93-接收 ICMP 报文

如果你练习过前面的接收 IP 数据报的程序,相信写出这个不会很难。

1. 程序路径

本文使用的程序托管在 gitos 上:http://git.oschina.net/ivan_allen/unp

如果你已经 clone 过这个代码了,请使用 git pull 更新一下。本节程序所使用的程序路径是 unp/program/icmp/basic.

2. 程序编写思路

因为这一次我们只想要 ICMP 协议,因此可以只接收 IP 数据报中协议字段为 1 的 IP 数据报。具体就是创建下面这样的原始套接字:

// IPPROTO_ICMP 的宏定义值就是 1 sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

通过编写获取 IP 数据报的实验我们已经掌握了拿到了 IP 数据报的方法,接下来,就是从 IP 数据报中拿出它的数据部分。

// 假设我们拿到的 ip 数据报保存在指针 struct ip *ip 中,长度为 len.   // 计算 ip 首部长度 iphlen = ip->ip_hl << 2;  // 计算 ip 数据报中数据起始地址,ip 首部地址 + ip 首部长度: char *buf = (char*)ip + iphlen;  // buf 的地址就是 ICMP 报文的首地址,强制转换到 struct icmp* 类型中 struct icmp *icmp = (struct icmp*)buf;  // 这样一来我们就拿到了 icmp 报文了,后面该打印的就打印去吧。

3. 实验

为了能产生 ICMP 报文,我在 flower 主机上使用 ping 命令发送了两个报文。


这里写图片描述
图1 运行结果

ping 命令发送的每一个 ICMP 报文大小都是 64 字节,这 64 字节表示 ICMP 首部长度 + ICMP 数据部分的长度。从图 1 中可以看到,数据部分是 60 字节(每行 16 字节),加上 type+code+checksum 一共 4 字节,刚好 64 字节。

实际上,ping 命令发送的报文是请求回显 ICMP 报文,细心的同学可以观察到图 1 中的 type 字段的值是 8,code 字段的值是 0,根据 ICMP 协议文档描述,这是一个请求回显报文。

下一篇文章会详细讨论请求回显报文是干嘛的。

4. 总结

  • 掌握解析 ICMP 报文的方法

说明:本文转自blog.csdn.net,用于学习交流分享,仅代表原文作者观点。如有疑问,请联系我们删除~