首页 新闻 搜索 专区 学院

编写PING程序..得到的不是自己的包

0
[已关闭问题] 关闭于 2012-08-26 13:26
  1 #include "winsock2.h"
  2 #include "stdio.h"
  3 
  4 #pragma comment( lib, "Ws2_32.lib" ) 
  5 
  6 int Init_WsaData (void)
  7 {
  8     WSADATA wsaData;
  9     //WSAStartup (WORD wVersionRequested, LPWSADATA lpWSAData)
 10     //The WSAStartup function initiates use of WS2_32.DLL by a process
 11     //Success Return 0
 12     if (WSAStartup (MAKEWORD (2, 2), &wsaData) == 0)
 13         return 0;
 14     else
 15         return WSAGetLastError ();
 16 
 17 }
 18 
 19 
 20 typedef struct _IPHeader        // 20×Ö½ÚµÄIPÍ·
 21 {
 22     UCHAR     iphVerLen;      // °æ±¾ºÅºÍÍ·³¤¶È£¨¸÷Õ¼4룩
 23     UCHAR     ipTOS;          // ·þÎñÀàÐÍ 
 24     USHORT    ipLength;       // ·â°ü×ܳ¤¶È£¬¼´Õû¸öIP±¨µÄ³¤¶È
 25     USHORT    ipID;              // ·â°ü±êʶ£¬Î©Ò»±êʶ·¢Ë͵Äÿһ¸öÊý¾Ý±¨
 26     USHORT    ipFlags;          // ±êÖ¾
 27     UCHAR     ipTTL;          // Éú´æʱ¼ä£¬¾ÍÊÇTTL
 28     UCHAR     ipProtocol;     // ЭÒ飬¿ÉÄÜÊÇTCP¡¢UDP¡¢ICMPµÈ
 29     USHORT    ipChecksum;     // УÑéºÍ
 30     ULONG     ipSource;       // Ô´IPµØÖ·
 31     ULONG     ipDestination;  // Ä¿±êIPµØÖ·
 32 } IPHeader, *PIPHeader; 
 33 
 34 
 35 typedef struct _ICMP_HDR
 36 {
 37     UCHAR  icmp_type;        //1byte
 38     USHORT icmp_check;        //2byte
 39     UCHAR  icmp_code;        //1byte
 40     //echo header
 41     USHORT icmp_id;            //2byte
 42     USHORT icmp_sequence;    //2byte
 43     ULONG  icmp_timestamp;    //8byte
 44 }ICMP_HDR, *PICMP_HDR;
 45 
 46 BOOL SetTimeout ( SOCKET s, int nTime, BOOL bRecv )
 47 {
 48     int ret = ::setsockopt(s, SOL_SOCKET, 
 49         bRecv ? SO_RCVTIMEO : SO_SNDTIMEO, (char*)&nTime, sizeof(nTime));
 50     return ret != SOCKET_ERROR;
 51 }
 52 
 53 USHORT CheckSum ( UCHAR *buff, int nLen )
 54 {
 55     UINT  nSum = 0;
 56     INT     i = 0; 
 57     
 58     while ( nLen > 1 )
 59     {
 60         nSum = nSum + ( ( buff[i] << 8 ) & 0xFF00 ) + ( buff[i + 1] & 0xFF );    
 61         nLen -= 2;
 62            i += 2;    
 63     }
 64     if ( nLen )
 65     {
 66         nSum = nSum + ( buff[i] | 0xFF00 );
 67     }
 68 
 69     nSum = ( nSum >> 16 ) + ( nSum & 0x00FF );
 70 
 71     return (USHORT)(~nSum);
 72 }
 73 
 74 int main ( void )
 75 {
 76     char szDestIp [10];
 77     printf ( " The Destination Ip: " );
 78     gets ( szDestIp );
 79     
 80     if ( Init_WsaData () != 0 )
 81         return 0;
 82     //Create SOCK_RAW
 83     SOCKET sRaw = ::socket ( AF_INET, SOCK_RAW, IPPROTO_ICMP );
 84 
 85     //ÉèÖýÓÊÕ³¬Ê±
 86     SetTimeout ( sRaw, 1000, TRUE );
 87 
 88 
 89     SOCKADDR_IN dest;
 90     dest.sin_family =  AF_INET;
 91     dest.sin_port   =  htons ( 4567 );
 92     dest.sin_addr.S_un.S_addr = inet_addr ( szDestIp );
 93 
 94     //´´½¨ICMP·â°ü ICMPÍ· + ÄÚÈÝ
 95     char buff [sizeof (ICMP_HDR) + 32];        //header 16bytes + 32bytes ÄÚÈÝ
 96 
 97     ICMP_HDR *pIcmp = (ICMP_HDR *)buff;
 98 
 99     pIcmp->icmp_type = 8;                //ÇëÇó»ØÏÔ
100     pIcmp->icmp_code = 0;        
101 
102     //»ØÏÔÍ·²¿
103     pIcmp->icmp_id = (USHORT)::GetCurrentProcessId ();
104     pIcmp->icmp_check = 0;
105     pIcmp->icmp_sequence = 0;
106     
107     //Ìî³äÊý¾Ý
108 //    dest 
109 //        Pointer to destination. 
110 //    c 
111 //        Character to set. 
112 //    count 
113 //        Number of characters. 
114     memset ( &buff[sizeof (ICMP_HDR)], 'E', 32 );
115 
116     USHORT nSeq = 0;
117     char recvBuf[1024];
118     SOCKADDR_IN from;
119     int nLen = sizeof (from);
120 
121 
122     while ( TRUE )
123     {
124         static int nCount = 0;
125         int nRet;
126         if ( nCount++ == 4 )
127             break;
128         pIcmp->icmp_check = 0;
129         pIcmp->icmp_timestamp = ::GetTickCount ();
130         pIcmp->icmp_sequence = nSeq++;
131         pIcmp->icmp_check = CheckSum ( (unsigned char *)buff, sizeof ( ICMP_HDR ) + 32 );
132         nRet = ::sendto ( sRaw, buff, sizeof ( ICMP_HDR ) + 32, 0, (SOCKADDR *)&dest, sizeof (dest) );
133         if ( nRet == SOCKET_ERROR )
134         {
135             printf ( " Error At sendto () : %d\n", WSAGetLastError () );
136             return -1;
137         }
138 
139         nRet = ::recvfrom ( sRaw, recvBuf, 1024, 0, (sockaddr*)&from, &nLen );
140         if ( nRet == SOCKET_ERROR )
141         {
142             if ( ::WSAGetLastError () == WSAETIMEDOUT )
143             {
144                 printf ( "timed out\n" );
145                 continue;
146             }
147             printf ( "Error At recvfrom (): %d\n", ::WSAGetLastError () );
148             return -1;
149         }
150 
151         int nTick = ::GetTickCount ();
152         if ( nRet < sizeof (IPHeader) + sizeof (ICMP_HDR) )
153 //        if ( nRet < sizeof (ICMP_HDR) )
154         {
155             printf ( "Too few bytes from %s\n", ::inet_ntoa (from.sin_addr) );
156         }
157         ICMP_HDR *pRecvIcmp = ( ICMP_HDR * )( recvBuf + sizeof ( IPHeader ) );
158         if ( pRecvIcmp->icmp_type != 0 )
159         {
160             printf ( "Echo Error %d\n", pRecvIcmp->icmp_type );
161             return -1;
162         }
163         if ( pRecvIcmp->icmp_id != ::GetCurrentProcessId () )
164         {
165             printf ( "someone else's packet!\n" );
166             return -1;
167         }
168 
169         printf ( "%d bytes from %s: ", nRet, inet_ntoa (from.sin_addr) );
170         printf ( "icmp_seq = %d.", pRecvIcmp->icmp_sequence );
171         printf ( "time: %d ms", nTick - pRecvIcmp->icmp_timestamp );
172         printf ( "\n" );
173         ::Sleep (1000);
174     }
175 
176     return 0;
177 }

 

我构建了ICMP封包,通过原始套接字,实现ping功能,我试着ping我所在的网关,但得到的信息不是我想要的,不知道是ICMP包头上的IP包头错误,还是什么..

Anger_Coder的主页 Anger_Coder | 初学一级 | 园豆:186
提问于:2012-05-26 11:21
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册