《编程实现发送ICMP协议详情大数据包》由会员分享,可在线阅读,更多相关《编程实现发送ICMP协议详情大数据包(8页珍藏版)》请在金锄头文库上搜索。
1、wordICMP原理与代码与分析专业: 班级:学号:某某: 一、 ICMP协议简介ICMP全称Internet Control Message Protocol,中文名为因特网控制报文协议。它工作在OSI的网络层,向数据通讯中的源主机报告错误。ICMP可以实现故障隔离和故障恢复。网络本身是不可靠的,在网络传输过程中,可能会发生许多突发事件并导致数据传输失败。网络层的IP协议是一个无连接的协议,它不会处理网络层传输中的故障,而位于网络层的ICMP协议却恰好弥补了IP的缺限,它使用IP协议进展信息传递,向数据包中的源端节点提供发生在网络层的错误信息反应。ICMP的报头长8字节,结构如图1所示。 比
2、特0 78 15 16 比特31类型0或8代码0检验和首部其余局部未使用数据图1ICMP报头结构l 类型:标识生成的错误报文,它是ICMP报文中的第一个字段;l 代码:进一步地限定生成ICMP报文。该字段用来查找产生错误的原因;l 校验和:存储了ICMP所使用的校验和值。l 未使用:保存字段,供将来使用,起值设为0l 数据:包含了所有承受到的数据报的IP报头。还包含IP数据报中前8个字节的数据;ICMP协议提供的诊断报文类型如表1所示。种类类型描述过失报文3目的端不可达4源点抑制11超时12参数问题5改变路由查询报文8或0回显请求或应答13或14时间戳请求或应答17或18地址掩码请求或应答10
3、或9路由询问和通告表1ICMP诊断报文类型ICMP提供多种类型的消息为源端节点提供网络层的故障信息反应,它的报文类型可以归纳为以下5个大类:l 诊断报文类型8,代码0;类型0,代码0;l 目的不可达报文类型3,代码0-15;l 重定向报文类型5,代码0-4;l 超时报文类型11,代码0-1;l 信息报文类型12-18。二、编程实现发送ICMP协议数据包代码功能:实现发送ICMP协议数据包,从而实现DOS下ping命令功能。1.代码简要分析代码执行步骤:(1) 创建协议类型为IPPROTO_ICMP的原始套接字,设置套接字的属性。(2) 创建并初始化ICMP封包。(3) 调用sendto函数向远
4、程主机发送ICMP的请求。(4) 调用recvfrom函数承受ICMP响应。初始化ICMP头时先初始化消息的类型和代码域,之后应该是回显请求头。程序首先定义了ICMP头的数据结构ICMP_HDR。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_sequen
5、ce;/ 序列号 unsigned long icmp_timestamp; / 时间戳 ICMP_HDR, *PICMP_HDR;2.完整代码与解析#include ./mon/initsock.h#include ./mon/protoinfo.h#include ./mon/m.h#include CInitSock theSock;typedef struct icmp_hdr unsigned char icmp_type;/ 消息类型 unsigned char icmp_code;/ 代码 unsigned short icmp_checksum;/ 校验和/ 下面是回显头 un
6、signed short icmp_id;/ 用来惟一标识此请求的ID号,通常设置为进程ID unsigned short icmp_sequence;/ 序列号 unsigned long icmp_timestamp; / 时间戳 ICMP_HDR, *PICMP_HDR;int main()/ 目的IP地址,即要Ping的IP地址char szDestIp = 192.168.1.104;/ 创建原始套节字SOCKET sRaw = :socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);/ 设置接收超时SetTimeout(sRaw, 1000, TRUE);
7、/ 设置目的地址SOCKADDR_IN dest;dest.sin_family = AF_INET;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):GetCurrentPr
8、ocessId();pIcmp-icmp_checksum = 0;pIcmp-icmp_sequence = 0;/ 填充数据局部,可以为任意memset(&buffsizeof(ICMP_HDR), E, 32);/ 开始发送和接收ICMP封包USHORTnSeq = 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_times
9、tamp = :GetTickCount();pIcmp-icmp_sequence = nSeq+;pIcmp-icmp_checksum = checksum(USHORT*)buff, sizeof(ICMP_HDR) + 32);nRet = :sendto(sRaw, buff, sizeof(ICMP_HDR) + 32, 0, (SOCKADDR *)&dest, sizeof(dest);if(nRet = SOCKET_ERROR)printf( sendto() failed: %d n, :WSAGetLastError();return -1;nRet = :recvf
10、rom(sRaw, recvBuf, 1024, 0, (sockaddr*)&from, &nLen);if(nRet = SOCKET_ERROR)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
11、recvd n, pRecvIcmp-icmp_type);return -1;if(pRecvIcmp-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(
12、n);:Sleep(1000);return 0;三、代码结果分析运行代码结果:源地址:192.168.1.101 目的地址: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作为源地址,加上一些其他的控制信息,构建一个IP数据包,并想方法得到192.168.1.104
13、的MAC地址物理地址,这是数据链路层协议构建数据链路层的传输单元帧所必需的,以便交给数据链路层构建一个数据帧。关键就在这里,IP层协议通过机器B的IP地址和自己的子网掩码,发现它跟自己属同一网络,就直接在本网络内查找这台机器的MAC,如果以前两机有过通信,在A机的ARP缓存表应该有B机IP与其MAC的映射关系,如果没有,就发一个ARP请求广播,得到B机的MAC,一并交给数据链路层。后者构建一个数据帧,目的地址是IP层传过来的物理地址,源地址如此是本机的物理地址,还要附加上一些控制信息,依据以太网的介质访问规如此,将它们传送出去。主机B收到这个数据帧后,先检查它的目的地址,并和本机的物理地址比照,如符合,如此接收;否如此丢弃。接收后检查该数据帧,将IP数据包从帧中提取出来,交给本机的IP层协议。同样,IP层检查