Z5NTS功能之icmp

2008-03-23 10:35:42  作者
Author:zfive5(zhaozidong) Email :zfive5@yahoo.com.cn 连续两天,终于完成了Z5NTS imcp部分-可以发送所有imcp类型数据,对icmp协议也有了近一步的熟悉,IMCP类型说明如下(主要是参见stevens的TCP/IP三卷,这几本读三遍也不为过) Z5NTS功能之icmp(图一)
点击查看大图
类型 代码 描述 0 0 回显应答 3 目的不可达 0 网络不可达
1 主机不可达 2 协议不可达 3 端口不可达 4 需要进行分片但设置了不分片比特 5 源站选路失败 6 目的网络不熟悉 7 目的主机不熟悉 8 源主机被隔离(作废不用) 9 目的网络被强制禁止
10 目的主机被强制禁止 11 由于服务类型TOS网络不可达 12 由于服务类型TOS主机不可达 13 由于过滤,通信被强制禁止 14 主机越权 15 优先权中止生效 4 0 源端被关闭 5 重定向
0 对网络重定向 1 对主机重定向 2 对服务类型和网络重定向 3 对服务类型和主机重定向 8 0 请求回显(Ping请求) 9 0 路由器通告 10 0 路由器请求 11 超时 0 传输期间生存时间为0
1 在数据报组装期间生存时间为0 12 参数问题 0 坏的IP首部(包括各种差错) 1 缺少必需的选项 13 0 时间戳请求 14 0 时间戳应答 15 0 信息请求(作废不用) 16 0 信息应答(作废不用) 17 0 地址掩码请求
18 0 地址掩码应答 功能界面如下 Z5NTS功能之icmp(图二) 功能介绍 根据所选类型生成对应的格式图样,然后用户在参照对应的格式图样形成对应的协议数据,例如回送请求类型的十六进制数据如下 类 型08 代 码00 校验和00,00,(这里需要使用CheckSum函数来计算) 标识符01,02 序 号02,01 数 据00,00,00,00
核心代码如下: typedef strUCt ICMPHeader { UCHAR icmp_type; // icmp type UCHAR icmp_code; // icmp code USHORT icmp_checksum; // icmp checksum unsigned char szBUF[1]; } ICMPHDR; int Open() { hSock=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); if(hSock==INVALID_SOCKET) { return -1; }
int iTimeOut=15000; setsockopt(hSock,SOL_SOCKET,SO_RCVTIMEO,(char *)%26amp;iTimeOut,sizeof(iTimeOut)); return 0; } int Close() { if(hSock!=INVALID_SOCKET) closesocket(hSock); hSock=NULL; return 0; } int IcmpSend(char *szAddr,char *szInBUF,int iInLen,int iType) { struct hostent *phs; struct sockaddr_in in;
in.sin_family =AF_INET; in.sin_port=htons(0); in.sin_addr.S_un.S_addr =inet_addr(szAddr); if(in.sin_addr.S_un.S_addr==INADDR_NONE) { phs=gethostbyname(szAddr); in.sin_addr.s_addr=*((u_long *)%26amp;(phs-%26gt;h_addr_list[0])); } if(iType==0) { ICMPHDR *pICMPHDR=(ICMPHDR *)(szInBUF); pICMPHDR-%26gt;icmp_checksum=0; pICMPHDR-%26gt;icmp_checksum=CheckSum((unsigned short *)szInBUF,iInLen); }
int iRet; iRet=sendto(hSock,szInBUF,iInLen,0,(struct sockaddr *)%26amp;in,sizeof(struct sockaddr_in)); if(iRet==SOCKET_ERROR) { return -1; } if(iRet!=iInLen) { return -2; } return 0; } unsigned short CheckSum(unsigned short *szBUF,int iSize) { unsigned long ckSum=0; for(;iSize%26gt;1;iSize-=sizeof(unsigned short))
{ ckSum+=*szBUF++; } if(iSize==1) { ckSum+=*(unsigned char *)szBUF; } ckSum=(ckSum%26gt;%26gt;16)+(ckSum%26amp;0xffff); ckSum+=(ckSum%26gt;%26gt;16); return(unsigned short )(~ckSum); }