编程实现发送ICMP协议数据包剖析

上传人:我** 文档编号:116440722 上传时间:2019-11-16 格式:DOC 页数:8 大小:298KB
返回 下载 相关 举报
编程实现发送ICMP协议数据包剖析_第1页
第1页 / 共8页
编程实现发送ICMP协议数据包剖析_第2页
第2页 / 共8页
编程实现发送ICMP协议数据包剖析_第3页
第3页 / 共8页
编程实现发送ICMP协议数据包剖析_第4页
第4页 / 共8页
编程实现发送ICMP协议数据包剖析_第5页
第5页 / 共8页
点击查看更多>>
资源描述

《编程实现发送ICMP协议数据包剖析》由会员分享,可在线阅读,更多相关《编程实现发送ICMP协议数据包剖析(8页珍藏版)》请在金锄头文库上搜索。

1、ICMP 原理与代码及分析 专业: 班级: 学号: 姓名: 一、一、ICMP 协议简介协议简介 ICMP 全称 Internet Control Message Protocol,中文名为因特网控制报文协议。它工作在 OSI 的网络层, 向数据通讯中的源主机报告错误。ICMP 可以实现故障隔离和故障恢复。网络本身是不可靠的,在网络传 输过程中,可能会发生许多突发事件并导致数据传输失败。网络层的 IP 协议是一个无连接的协议,它不 会处理网络层传输中的故障,而位于网络层的 ICMP 协议却恰好弥补了 IP 的缺限,它使用 IP 协议进行信 息传递,向数据包中的源端节点提供发生在网络层的错误信息反

2、馈。ICMP 的报头长 8 字节,结构如图 1 所示。 比特 0 7 8 15 16 比特 31 类型(0 或 8)代码(0)检验和 首部其余部分(未使用) 数据 (图 1 ICMP 报头结构) 类型类型:标识生成的错误报文,它是 ICMP 报文中的第一个字段; 代码代码:进一步地限定生成 ICMP 报文。该字段用来查找产生错误的原因; 校验和校验和:存储了 ICMP 所使用的校验和值。 未使用未使用:保留字段,供将来使用,起值设为 0 数据数据:包含了所有接受到的数据报的 IP 报头。还包含 IP 数据报中前 8 个字节的数据; ICMP 协议提供的诊断报文类型如表 1 所示。 种类种类类型

3、类型描述描述 3目的端不可达 4源点抑制 11超时 12参数问题 差错报文 5改变路由 8 或 0回显请求或应答 13 或 14时间戳请求或应答 17 或 18地址掩码请求或应答 查询报文 10 或 9路由询问和通告 (表 1 ICMP 诊断报文类型) ICMP 提供多种类型的消息为源端节点提供网络层的故障信息反馈,它的报文类型可以归纳为以下 5 个大 类: 诊断报文(类型 8,代码 0;类型 0,代码 0) ; 目的不可达报文(类型 3,代码 0-15) ; 重定向报文(类型 5,代码 0-4) ; 超时报文(类型 11,代码 0-1) ; 信息报文(类型 12-18) 。 二、编程实现发送

4、二、编程实现发送 ICMP 协议数据包协议数据包 代码功能:实现发送 ICMP 协议数据包,从而实现 DOS 下 ping 命令功能。 1.代码简要分析代码简要分析 代码执行步骤: (1)创建协议类型为 IPPROTO_ICMP 的原始套接字,设置套接字的属性。 (2)创建并初始化 ICMP 封包。 (3)调用 sendto 函数向远程主机发送 ICMP 的请求。 (4)调用 recvfrom 函数接受 ICMP 响应。 初始化 ICMP 头时先初始化消息的类型和代码域,之后应该是回显请求头。程序首先定义了 ICMP 头 的数据结构 ICMP_HDR。 typedef struct icmp_

5、hdr unsigned char icmp_type;/ 消息类型 unsigned char icmp_code;/ 代码 unsigned short icmp_checksum;/ 校验和 / 下面是回显头 unsigned short icmp_id;/ 用来惟一标识此请求的 ID 号,通常设置为进程 ID unsigned short icmp_sequence;/ 序列号 unsigned long icmp_timestamp; / 时间戳 ICMP_HDR, *PICMP_HDR; 2.完整代码及解析完整代码及解析 #include “/common/initsock.h“

6、#include “/common/protoinfo.h“ #include “/common/comm.h“ #include CInitSock theSock; typedef struct icmp_hdr unsigned char icmp_type;/ 消息类型 unsigned char icmp_code;/ 代码 unsigned short icmp_checksum;/ 校验和 / 下面是回显头 unsigned short icmp_id;/ 用来惟一标识此请求的 ID 号,通常设置为进程 ID unsigned short icmp_sequence;/ 序列号

7、unsigned long icmp_timestamp; / 时间戳 ICMP_HDR, *PICMP_HDR; int main() / 目的 IP 地址,即要 Ping 的 IP 地址 char szDestIp = “192.168.1.104“; / 127.0.0.1 / 创建原始套节字 SOCKET sRaw = :socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); / 设置接收超时 SetTimeout(sRaw, 1000, TRUE); / 设置目的地址 SOCKADDR_IN dest; dest.sin_family = AF_INET;

8、dest.sin_port = htons(0); dest.sin_addr.S_un.S_addr = inet_addr(szDestIp); / 创建 ICMP 封包 char buffsizeof(ICMP_HDR) + 32; ICMP_HDR* pIcmp = (ICMP_HDR*)buff; / 填写 ICMP 封包数据 pIcmp-icmp_type = 8;/ 请求一个 ICMP 回显 pIcmp-icmp_code = 0; pIcmp-icmp_id = (USHORT):GetCurrentProcessId(); pIcmp-icmp_checksum = 0; p

9、Icmp-icmp_sequence = 0; / 填充数据部分,可以为任意 memset( / 开始发送和接收 ICMP 封包 USHORT nSeq = 0; char recvBuf1024; SOCKADDR_IN from; int nLen = sizeof(from); while(TRUE) static int nCount = 0; int nRet; if(nCount+ = 4) break; pIcmp-icmp_checksum = 0; pIcmp-icmp_timestamp = :GetTickCount(); pIcmp-icmp_sequence = nS

10、eq+; pIcmp-icmp_checksum = checksum(USHORT*)buff, sizeof(ICMP_HDR) + 32); nRet = :sendto(sRaw, buff, sizeof(ICMP_HDR) + 32, 0, (SOCKADDR *) if(nRet = SOCKET_ERROR) printf(“ sendto() failed: %d n“, :WSAGetLastError(); return -1; nRet = :recvfrom(sRaw, recvBuf, 1024, 0, (sockaddr*) if(nRet = SOCKET_ER

11、ROR) if(:WSAGetLastError() = WSAETIMEDOUT) printf(“ timed outn“); continue; printf(“ recvfrom() failed: %dn“, :WSAGetLastError(); return -1; / 下面开始解析接收到的 ICMP 封包 int nTick = :GetTickCount(); if(nRet icmp_type != 0)/ 回显 printf(“ nonecho type %d recvd n“, pRecvIcmp-icmp_type); return -1; if(pRecvIcmp-

12、icmp_id != :GetCurrentProcessId() printf(“ someone elses packet! n“); return -1; printf(“ %d bytes from %s:“, nRet, inet_ntoa(from.sin_addr); printf(“ icmp_seq = %d. “, pRecvIcmp-icmp_sequence); printf(“ time: %d ms“, nTick - pRecvIcmp-icmp_timestamp); printf(“ n“); :Sleep(1000); return 0; 三、代码结果分析三

13、、代码结果分析 运行代码结果:(源地址:192.168.1.101 目的地址:192.168.1.104) DOS 下使用 ping 命令 ping 192.168.1.104 结果:(源地址:192.168.1.101 目的地址: 192.168.1.104) 由图可以分析出代码实现功能与 ping 命令功能类似。即代码会构建一个固定格式的 ICMP 请求数据 包,然后由 ICMP 协议将这个数据包连同地址“192.168.1.104”一起交给 IP 层协议,IP 层协议将以地 址“192.168.1.104”作为目的地址,本机 IP 地址 192.168.1.101 作为源地址,加上一些其

14、他的控制信 息,构建一个 IP 数据包,并想办法得到 192.168.1.104 的 MAC 地址(物理地址,这是数据链路层协 议构建数据链路层的传输单元帧所必需的) ,以便交给数据链路层构建一个数据帧。关键就在这 里,IP 层协议通过机器 B 的 IP 地址和自己的子网掩码,发现它跟自己属同一网络,就直接在本网络 内查找这台机器的 MAC,如果以前两机有过通信,在 A 机的 ARP 缓存表应该有 B 机 IP 与其 MAC 的映 射关系,如果没有,就发一个 ARP 请求广播,得到 B 机的 MAC,一并交给数据链路层。后者构建一个 数据帧,目的地址是 IP 层传过来的物理地址,源地址则是本机

15、的物理地址,还要附加上一些控制信 息,依据以太网的介质访问规则,将它们传送出去。 主机 B 收到这个数据帧后,先检查它的目的地址,并和本机的物理地址对比,如符合,则接收;否则 丢弃。接收后检查该数据帧,将 IP 数据包从帧中提取出来,交给本机的 IP 层协议。同样,IP 层检查 后,将有用的信息提取后交给 ICMP 协议,后者处理后,马上构建一个 ICMP 应答包,发送给主机 A,其过程和主机 A 发送 ICMP 请求包到主机 B 一模一样。 由 wireshark 抓包,我们可以更清楚的看到两者的相似处。 Wireshark 抓到代码的数据包:(源地址:192.168.1.101 目的地址:192.168.1.104) Wireshark 抓到 ping 命令的数据包:(源地址:192.168.1.101 目的地址:192.168.1.104) 代码和 ping 命令都使用 ICMP 协议,并且都是源地址请求一次,目的地址回应一次。而且 wireshark 判断两者都实现 ping 功能。 如果是目的网络与主机网络不通 代码结果: Ping 命令结果:

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号