|   计算校验和(Checksum)的函数为: //功能:计算ICMP包的校验和unsigned short ip_checksum(unsigned short *buffer, int size)
 {
 unsigned long cksum = 0;
 
 // 将所有的16数相加
 while (size > 1)
 {
 cksum += *buffer++;
 size -= sizeof(unsigned short);
 }
 if (size) //加上最后一个BYTE
 {
 cksum += *(unsigned char*)buffer;
 }
  //和的前16位和后16位相加cksum = (cksum >> 16) + (cksum &0xffff);
 cksum += (cksum >> 16);
  return (unsigned short)(~cksum);}
   在真正发送Ping报文前,需要先初始化Raw Socket: // 功能:初始化RAW Socket, 设置ttl, 初始化目标地址// 返回值:<0 失败
 int setup_for_ping(char *host, int ttl, SOCKET &sd, sockaddr_in &dest)
 {
 // 创建原始套接字
 sd = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, 0, 0, 0);
 if (sd == INVALID_SOCKET)
 {
 cerr << "Failed to create raw socket: " << WSAGetLastError() << endl;
 return - 1;
 }
 
 if (setsockopt(sd, IPPROTO_IP, IP_TTL, (const char*) &ttl, sizeof(ttl)) ==SOCKET_ERROR)
 {
 cerr << "TTL setsockopt failed: " << WSAGetLastError() << endl;
 return - 1;
 }
  // 初始化目标主机信息块memset(&dest, 0, sizeof(dest));
  // 将第1个参数转换为目标IP地址unsigned int addr = inet_addr(host);
 if (addr != INADDR_NONE)
 {
 // 为IP地址
 dest.sin_addr.s_addr = addr;
 dest.sin_family = AF_INET;
 }
 else
 {
 // 非IP地址,进行主机名和IP地址的转换
 hostent *hp = gethostbyname(host);
 if (hp != 0)
 {
 // 查找主机名对应的IP地址
 memcpy(&(dest.sin_addr), hp->h_addr, hp->h_length);
 dest.sin_family = hp->h_addrtype;
 }
 else
 {
 // 不能识别的主机名
 cerr << "Failed to resolve " << host << endl;
 return - 1;
 }
 }
 return 0;
 }
 
		      
		      
		      
		      
		      
		      
                        共9页: 上一页 [1] [2] [3] 4 [5] [6] [7] [8] [9] 下一页 |