微软ping程序源代码完整版
编写自己的一个ping程序,可以说是许多人迈出网络编程的第一步吧!!这个ping程序的源代码经过我的修改和调试,基本上可以取代windows中自带的ping程序. 各个模块后都有我的详细注释和修改日志,希望能够对大家的学习
1
/*
本程序的主要源代码来自MSDN网站, 笔者只是做了一些改进和注释! 另外需要注意的是在Build之前,必须加入ws2_32.lib库文件,
否则会提示"error LNK2001:"的错误! */
2
3 /* *****************************************************************************\
4 | Version 1.1 修改记录: |
5 | <1> 解决了socket阻塞的问题,从而能够正确地处理超时的请求! |
6 |------------------------------------------------------------------------------|
7 | Version 1.2 修改记录: |
8 | <1> 增加了由用户控制发送ICMP包的数目的功能(即命令的第二个参数). |
9 | <2> 增加了对ping结果的统计功能. |
10 \***************************************************************************** */
11
12 #pragma pack( 4 )
13
14 #include < WINSOCK2.H >
15 #include < STDIO.H >
16 #include < STDLIB.H >
17
18 #define ICMP_ECHO 8
19 #define ICMP_ECHOREPLY 0
20
21 #define ICMP_MIN 8 // minimum 8 byte icmp packet (just header)
22
23 /* The IP header */
24 typedef struct iphdr {
25 unsigned int h_len: 4 ; // length of the header
26 unsigned int version: 4 ; // Version of IP
27 unsigned char tos; // Type of service
28 unsigned short total_len; // total length of the packet
29 unsigned short ident; // unique identifier
30 unsigned short frag_and_flags; // flags
31 unsigned char ttl;
32 unsigned char proto; // protocol (TCP, UDP etc)
33 unsigned short checksum; // IP checksum
34
35 unsigned int sourceIP;
36 unsigned int destIP;
37
38 }IpHeader;
39
40 //
41 // ICMP header
42 //
43 typedef struct icmphdr {
44 BYTE i_type;
45 BYTE i_code; /* type sub code */
46 USHORT i_cksum;
47 USHORT i_id;
48 USHORT i_seq;
49 /* This is not the std header, but we reserve space for time */
50 ULONG timestamp;
51 }IcmpHeader;
52
53 #define STATUS_FAILED 0xFFFF
54 #define DEF_PACKET_SIZE 32
55 #define DEF_PACKET_NUMBER 4 /* 发送数据报的个数 */
56 #define MAX_PACKET 1024
57
58 #define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
59 #define xfree(p) HeapFree (GetProcessHeap(),0,(p))
60
61 void fill_icmp_data( char * , int );
62 USHORT checksum(USHORT * , int );
63 int decode_resp( char * , int , struct sockaddr_in * );
64
65 void Usage( char * progname){
66
67 fprintf(stderr, " Usage:\n " );
68 fprintf(stderr, " %s [number of packets] [data_size]\n " ,progname);
69 fprintf(stderr, " datasize can be up to 1Kb\n " );
70 ExitProcess(STATUS_FAILED);
71
72 }
73 int main( int argc, char ** argv){
74
75 WSADATA wsaData;
76 SOCKET sockRaw;
77 struct sockaddr_in dest,from;
78 struct hostent * hp;
79 int bread,datasize,times;
80 int fromlen = sizeof (from);
81 int timeout = 1000 ;
82 int statistic = 0 ; /* 用于统计结果 */
83 char * dest_ip;
84 char * icmp_data;
85 char * recvbuf;
86 unsigned int addr = 0 ;
87 USHORT seq_no = 0 ;
88
89 if (WSAStartup(MAKEWORD( 2 , 1 ), & wsaData) != 0 ){
90 fprintf(stderr, " WSAStartup failed: %d\n " ,GetLastError());
91 ExitProcess(STATUS_FAILED);
92 }
93
94 if (argc < 2 ) {
95 Usage(argv[ 0 ]);
96 }
97 sockRaw = WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL, 0 ,WSA_FLAG_OVERLAPPED);
98
99 //
100 // 注:为了使用发送接收超时设置(即设置SO_RCVTIMEO, SO_SNDTIMEO),
101 // 必须将标志位设为WSA_FLAG_OVERLAPPED !
102 //
103
104 if (sockRaw == INVALID_SOCKET) {
105 fprintf(stderr, " WSASocket() failed: %d\n " ,WSAGetLastError());
106 ExitProcess(STATUS_FAILED);
107 }
108 bread = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,( char * ) & timeout,
109 sizeof (timeout));
110 if (bread == SOCKET_ERROR) {
111 fprintf(stderr, " failed to set recv timeout: %d\n " ,WSAGetLastError());
112 ExitProcess(STATUS_FAILED);
113 }
114 timeout = 1000 ;
115 bread = setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,( char * ) & timeout,
116 sizeof (timeout));
117 if (bread == SOCKET_ERROR) {
118 fprintf(stderr, " failed to set send timeout: %d\n " ,WSAGetLastError());
119 ExitProcess(STATUS_FAILED);
120 }
121 memset( & dest, 0 , sizeof (dest));
122
123 hp = gethostbyname(argv[ 1 ]);
124
125 if ( ! hp){
126 addr = inet_addr(argv[ 1 ]);
127 }
128 if (( ! hp) && (addr == INADDR_NONE) ) {
129 fprintf(stderr, " Unable to resolve %s\n " ,argv[ 1 ]);
130 ExitProcess(STATUS_FAILED);
131 }
132
133 if (hp != NULL)
134 memcpy( & (dest.sin_addr),hp -> h_addr,hp -> h_length);
135 else
136 dest.sin_addr.s_addr = addr;
137
138 if (hp)
139 dest.sin_family = hp -> h_addrtype;
140 else
141 dest.sin_family = AF_INET;
142
143 dest_ip = inet_ntoa(dest.sin_addr);
144
145 //
146 // atoi函数原型是: int atoi( const char *string );
147 // The return value is 0 if the input cannot be converted to an integer !
148 //
149 if (argc > 2 )
150 {
151 times = atoi(argv[ 2 ]);
152 if (times == 0 )
153 times = DEF_PACKET_NUMBER;
154 }
155 else
156 times = DEF_PACKET_NUMBER;
157
158 if (argc > 3 )
159 {
160 datasize = atoi(argv[ 3 ]);
161 if (datasize == 0 )
162 datasize = DEF_PACKET_SIZE;
163 if (datasize > 1024 ) /* 用户给出的数据包大小太大 */
164 {
165 fprintf(stderr, " WARNING : data_size is too large !\n " );
166 datasize = DEF_PACKET_SIZE;
167 }
168 }
169 else
170 datasize = DEF_PACKET_SIZE;
171
172 datasize += sizeof (IcmpHeader);
173
174 icmp_data = ( char * )xmalloc(MAX_PACKET);
175 recvbuf = ( char * )xmalloc(MAX_PACKET);
176
177 if ( ! icmp_data) {
178 fprintf(stderr, " HeapAlloc failed %d\n " ,GetLastError());
179 ExitProcess(STATUS_FAILED);
180 }
181
182
183 memset(icmp_data, 0 ,MAX_PACKET);
184 fill_icmp_data(icmp_data,datasize);
185
186 //
187 // 显示提示信息
188 //
189 fprintf(stdout, " \nPinging %s .\n\n " ,dest_ip);
190
191
192 for ( int i = 0 ;i < times; ++ i){
193 int bwrote;
194
195 ((IcmpHeader * )icmp_data) -> i_cksum = 0 ;
196 ((IcmpHeader * )icmp_data) -> timestamp = GetTickCount();
197
198 ((IcmpHeader * )icmp_data) -> i_seq = seq_no ++ ;
199 ((IcmpHeader * )icmp_data) -> i_cksum = checksum((USHORT * )icmp_data,datasize);
200
201 bwrote = sendto(sockRaw,icmp_data,datasize, 0 ,( struct sockaddr * ) & dest, sizeof (dest));
202 if (bwrote == SOCKET_ERROR){
203 if (WSAGetLastError() == WSAETIMEDOUT) {
204 printf( " Request timed out.\n " );
205 continue ;
206 }
207 fprintf(stderr, " sendto failed: %d\n " ,WSAGetLastError());
208 ExitProcess(STATUS_FAILED);
209 }
210 if (bwrote < datasize ) {
211 fprintf(stdout, " Wrote %d bytes\n " ,bwrote);
212 }
213 bread = recvfrom(sockRaw,recvbuf,MAX_PACKET, 0 ,( struct sockaddr * ) & from, & fromlen);
214 if (bread == SOCKET_ERROR){
215 if (WSAGetLastError() == WSAETIMEDOUT) {
216 printf( " Request timed out.\n " );
217 continue ;
218 }
219 fprintf(stderr, " recvfrom failed: %d\n " ,WSAGetLastError());
220 ExitProcess(STATUS_FAILED);
221 }
222 if ( ! decode_resp(recvbuf,bread, & from))
223 statistic ++ ; /* 成功接收的数目++ */
224 Sleep( 1000 );
225
226 }
227
228 /*
229 Display the statistic result
230 */
231 fprintf(stdout, " \nPing statistics for %s \n " ,dest_ip);
232 fprintf(stdout, " Packets: Sent = %d,Received = %d, Lost = %d (%2.0f%% loss)\n " ,times,
233 statistic,(times - statistic),( float )(times - statistic) / times * 100 );
234
235
236 WSACleanup();
237 return 0 ;
238
239 }
240 /*
241 The response is an IP packet. We must decode the IP header to locate
242 the ICMP data
243 */
244 int decode_resp( char * buf, int bytes, struct sockaddr_in * from) {
245
246 IpHeader * iphdr;
247 IcmpHeader * icmphdr;
248 unsigned short iphdrlen;
249
250 iphdr = (IpHeader * )buf;
251
252 iphdrlen = (iphdr -> h_len) * 4 ; // number of 32-bit words *4 = bytes
253
254 if (bytes < iphdrlen + ICMP_MIN) {
255 printf( " Too few bytes from %s\n " ,inet_ntoa(from -> sin_addr));
256 }
257
258 icmphdr = (IcmpHeader * )(buf + iphdrlen);
259
260 if (icmphdr -> i_type != ICMP_ECHOREPLY) {
261 fprintf(stderr, " non-echo type %d recvd\n " ,icmphdr -> i_type);
262 return 1 ;
263 }
264 if (icmphdr -> i_id != (USHORT)GetCurrentProcessId()) {
265 fprintf(stderr, " someone else's packet!\n " );
266 return 1 ;
267 }
268 printf( " %d bytes from %s: " ,bytes, inet_ntoa(from -> sin_addr));
269 printf( " icmp_seq = %d. " ,icmphdr -> i_seq);
270 printf( " time: %d ms " ,GetTickCount() - icmphdr -> timestamp);
271 printf( " \n " );
272 return 0 ;
273
274 }
275
276
277 USHORT checksum(USHORT * buffer, int size) {
278
279 unsigned long cksum = 0 ;
280
281 while (size > 1 ) {
282 cksum +=* buffer ++ ;
283 size -= sizeof (USHORT);
284 }
285
286 if (size) {
287 cksum += * (UCHAR * )buffer;
288 }
289
290 cksum = (cksum >> 16 ) + (cksum & 0xffff );
291 cksum += (cksum >> 16 );
292 return (USHORT)( ~ cksum);
293 }
294 /*
295 Helper function to fill in various stuff in our ICMP request.
296 */
297 void fill_icmp_data( char * icmp_data, int datasize){
298
299 IcmpHeader * icmp_hdr;
300 char * datapart;
301
302 icmp_hdr = (IcmpHeader * )icmp_data;
303
304 icmp_hdr -> i_type = ICMP_ECHO;
305 icmp_hdr -> i_code = 0 ;
306 icmp_hdr -> i_id = (USHORT)GetCurrentProcessId();
307 icmp_hdr -> i_cksum = 0 ;
308 icmp_hdr -> i_seq = 0 ;
309
310 datapart = icmp_data + sizeof (IcmpHeader);
311 //
312 // Place some junk in the buffer.
313 //
314 memset(datapart, ' E ' , datasize - sizeof (IcmpHeader));
315
316 }
317
318 /* ****************** 附: ping命令执行时显示的画面 **************\
319 * C:\Documents and Settings\houzhijiang>ping 236.56.54.12 *
320 * *
321 * Pinging 236.56.54.12 with 32 bytes of data: *
322 * *
323 * Request timed out. *
324 * Request timed out. *
325 * Request timed out. *
326 * Request timed out. *
327 * *
328 * Ping statistics for 236.56.54.12: *
329 * Packets: Sent = 4, Received = 0, Lost = 4 (100% loss), *
330 * *
331 \************************************************************** */
332
333 /* **************************************************************\
334 * C:\Documents and Settings\houzhijiang>ping 127.0.0.1 *
335 * *
336 * Pinging 127.0.0.1 with 32 bytes of data: *
337 * *
338 * Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 *
339 * Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 *
340 * Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 *
341 * Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 *
342 * *
343 * Ping statistics for 127.0.0.1: *
344 * Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), *
345 * Approximate round trip times in milli-seconds: *
346 * Minimum = 0ms, Maximum = 0ms, Average = 0ms *
347 * *
348 \************************************************************** */
349
否则会提示"error LNK2001:"的错误! */
2
3 /* *****************************************************************************\
4 | Version 1.1 修改记录: |
5 | <1> 解决了socket阻塞的问题,从而能够正确地处理超时的请求! |
6 |------------------------------------------------------------------------------|
7 | Version 1.2 修改记录: |
8 | <1> 增加了由用户控制发送ICMP包的数目的功能(即命令的第二个参数). |
9 | <2> 增加了对ping结果的统计功能. |
10 \***************************************************************************** */
11
12 #pragma pack( 4 )
13
14 #include < WINSOCK2.H >
15 #include < STDIO.H >
16 #include < STDLIB.H >
17
18 #define ICMP_ECHO 8
19 #define ICMP_ECHOREPLY 0
20
21 #define ICMP_MIN 8 // minimum 8 byte icmp packet (just header)
22
23 /* The IP header */
24 typedef struct iphdr {
25 unsigned int h_len: 4 ; // length of the header
26 unsigned int version: 4 ; // Version of IP
27 unsigned char tos; // Type of service
28 unsigned short total_len; // total length of the packet
29 unsigned short ident; // unique identifier
30 unsigned short frag_and_flags; // flags
31 unsigned char ttl;
32 unsigned char proto; // protocol (TCP, UDP etc)
33 unsigned short checksum; // IP checksum
34
35 unsigned int sourceIP;
36 unsigned int destIP;
37
38 }IpHeader;
39
40 //
41 // ICMP header
42 //
43 typedef struct icmphdr {
44 BYTE i_type;
45 BYTE i_code; /* type sub code */
46 USHORT i_cksum;
47 USHORT i_id;
48 USHORT i_seq;
49 /* This is not the std header, but we reserve space for time */
50 ULONG timestamp;
51 }IcmpHeader;
52
53 #define STATUS_FAILED 0xFFFF
54 #define DEF_PACKET_SIZE 32
55 #define DEF_PACKET_NUMBER 4 /* 发送数据报的个数 */
56 #define MAX_PACKET 1024
57
58 #define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
59 #define xfree(p) HeapFree (GetProcessHeap(),0,(p))
60
61 void fill_icmp_data( char * , int );
62 USHORT checksum(USHORT * , int );
63 int decode_resp( char * , int , struct sockaddr_in * );
64
65 void Usage( char * progname){
66
67 fprintf(stderr, " Usage:\n " );
68 fprintf(stderr, " %s [number of packets] [data_size]\n " ,progname);
69 fprintf(stderr, " datasize can be up to 1Kb\n " );
70 ExitProcess(STATUS_FAILED);
71
72 }
73 int main( int argc, char ** argv){
74
75 WSADATA wsaData;
76 SOCKET sockRaw;
77 struct sockaddr_in dest,from;
78 struct hostent * hp;
79 int bread,datasize,times;
80 int fromlen = sizeof (from);
81 int timeout = 1000 ;
82 int statistic = 0 ; /* 用于统计结果 */
83 char * dest_ip;
84 char * icmp_data;
85 char * recvbuf;
86 unsigned int addr = 0 ;
87 USHORT seq_no = 0 ;
88
89 if (WSAStartup(MAKEWORD( 2 , 1 ), & wsaData) != 0 ){
90 fprintf(stderr, " WSAStartup failed: %d\n " ,GetLastError());
91 ExitProcess(STATUS_FAILED);
92 }
93
94 if (argc < 2 ) {
95 Usage(argv[ 0 ]);
96 }
97 sockRaw = WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL, 0 ,WSA_FLAG_OVERLAPPED);
98
99 //
100 // 注:为了使用发送接收超时设置(即设置SO_RCVTIMEO, SO_SNDTIMEO),
101 // 必须将标志位设为WSA_FLAG_OVERLAPPED !
102 //
103
104 if (sockRaw == INVALID_SOCKET) {
105 fprintf(stderr, " WSASocket() failed: %d\n " ,WSAGetLastError());
106 ExitProcess(STATUS_FAILED);
107 }
108 bread = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,( char * ) & timeout,
109 sizeof (timeout));
110 if (bread == SOCKET_ERROR) {
111 fprintf(stderr, " failed to set recv timeout: %d\n " ,WSAGetLastError());
112 ExitProcess(STATUS_FAILED);
113 }
114 timeout = 1000 ;
115 bread = setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,( char * ) & timeout,
116 sizeof (timeout));
117 if (bread == SOCKET_ERROR) {
118 fprintf(stderr, " failed to set send timeout: %d\n " ,WSAGetLastError());
119 ExitProcess(STATUS_FAILED);
120 }
121 memset( & dest, 0 , sizeof (dest));
122
123 hp = gethostbyname(argv[ 1 ]);
124
125 if ( ! hp){
126 addr = inet_addr(argv[ 1 ]);
127 }
128 if (( ! hp) && (addr == INADDR_NONE) ) {
129 fprintf(stderr, " Unable to resolve %s\n " ,argv[ 1 ]);
130 ExitProcess(STATUS_FAILED);
131 }
132
133 if (hp != NULL)
134 memcpy( & (dest.sin_addr),hp -> h_addr,hp -> h_length);
135 else
136 dest.sin_addr.s_addr = addr;
137
138 if (hp)
139 dest.sin_family = hp -> h_addrtype;
140 else
141 dest.sin_family = AF_INET;
142
143 dest_ip = inet_ntoa(dest.sin_addr);
144
145 //
146 // atoi函数原型是: int atoi( const char *string );
147 // The return value is 0 if the input cannot be converted to an integer !
148 //
149 if (argc > 2 )
150 {
151 times = atoi(argv[ 2 ]);
152 if (times == 0 )
153 times = DEF_PACKET_NUMBER;
154 }
155 else
156 times = DEF_PACKET_NUMBER;
157
158 if (argc > 3 )
159 {
160 datasize = atoi(argv[ 3 ]);
161 if (datasize == 0 )
162 datasize = DEF_PACKET_SIZE;
163 if (datasize > 1024 ) /* 用户给出的数据包大小太大 */
164 {
165 fprintf(stderr, " WARNING : data_size is too large !\n " );
166 datasize = DEF_PACKET_SIZE;
167 }
168 }
169 else
170 datasize = DEF_PACKET_SIZE;
171
172 datasize += sizeof (IcmpHeader);
173
174 icmp_data = ( char * )xmalloc(MAX_PACKET);
175 recvbuf = ( char * )xmalloc(MAX_PACKET);
176
177 if ( ! icmp_data) {
178 fprintf(stderr, " HeapAlloc failed %d\n " ,GetLastError());
179 ExitProcess(STATUS_FAILED);
180 }
181
182
183 memset(icmp_data, 0 ,MAX_PACKET);
184 fill_icmp_data(icmp_data,datasize);
185
186 //
187 // 显示提示信息
188 //
189 fprintf(stdout, " \nPinging %s .\n\n " ,dest_ip);
190
191
192 for ( int i = 0 ;i < times; ++ i){
193 int bwrote;
194
195 ((IcmpHeader * )icmp_data) -> i_cksum = 0 ;
196 ((IcmpHeader * )icmp_data) -> timestamp = GetTickCount();
197
198 ((IcmpHeader * )icmp_data) -> i_seq = seq_no ++ ;
199 ((IcmpHeader * )icmp_data) -> i_cksum = checksum((USHORT * )icmp_data,datasize);
200
201 bwrote = sendto(sockRaw,icmp_data,datasize, 0 ,( struct sockaddr * ) & dest, sizeof (dest));
202 if (bwrote == SOCKET_ERROR){
203 if (WSAGetLastError() == WSAETIMEDOUT) {
204 printf( " Request timed out.\n " );
205 continue ;
206 }
207 fprintf(stderr, " sendto failed: %d\n " ,WSAGetLastError());
208 ExitProcess(STATUS_FAILED);
209 }
210 if (bwrote < datasize ) {
211 fprintf(stdout, " Wrote %d bytes\n " ,bwrote);
212 }
213 bread = recvfrom(sockRaw,recvbuf,MAX_PACKET, 0 ,( struct sockaddr * ) & from, & fromlen);
214 if (bread == SOCKET_ERROR){
215 if (WSAGetLastError() == WSAETIMEDOUT) {
216 printf( " Request timed out.\n " );
217 continue ;
218 }
219 fprintf(stderr, " recvfrom failed: %d\n " ,WSAGetLastError());
220 ExitProcess(STATUS_FAILED);
221 }
222 if ( ! decode_resp(recvbuf,bread, & from))
223 statistic ++ ; /* 成功接收的数目++ */
224 Sleep( 1000 );
225
226 }
227
228 /*
229 Display the statistic result
230 */
231 fprintf(stdout, " \nPing statistics for %s \n " ,dest_ip);
232 fprintf(stdout, " Packets: Sent = %d,Received = %d, Lost = %d (%2.0f%% loss)\n " ,times,
233 statistic,(times - statistic),( float )(times - statistic) / times * 100 );
234
235
236 WSACleanup();
237 return 0 ;
238
239 }
240 /*
241 The response is an IP packet. We must decode the IP header to locate
242 the ICMP data
243 */
244 int decode_resp( char * buf, int bytes, struct sockaddr_in * from) {
245
246 IpHeader * iphdr;
247 IcmpHeader * icmphdr;
248 unsigned short iphdrlen;
249
250 iphdr = (IpHeader * )buf;
251
252 iphdrlen = (iphdr -> h_len) * 4 ; // number of 32-bit words *4 = bytes
253
254 if (bytes < iphdrlen + ICMP_MIN) {
255 printf( " Too few bytes from %s\n " ,inet_ntoa(from -> sin_addr));
256 }
257
258 icmphdr = (IcmpHeader * )(buf + iphdrlen);
259
260 if (icmphdr -> i_type != ICMP_ECHOREPLY) {
261 fprintf(stderr, " non-echo type %d recvd\n " ,icmphdr -> i_type);
262 return 1 ;
263 }
264 if (icmphdr -> i_id != (USHORT)GetCurrentProcessId()) {
265 fprintf(stderr, " someone else's packet!\n " );
266 return 1 ;
267 }
268 printf( " %d bytes from %s: " ,bytes, inet_ntoa(from -> sin_addr));
269 printf( " icmp_seq = %d. " ,icmphdr -> i_seq);
270 printf( " time: %d ms " ,GetTickCount() - icmphdr -> timestamp);
271 printf( " \n " );
272 return 0 ;
273
274 }
275
276
277 USHORT checksum(USHORT * buffer, int size) {
278
279 unsigned long cksum = 0 ;
280
281 while (size > 1 ) {
282 cksum +=* buffer ++ ;
283 size -= sizeof (USHORT);
284 }
285
286 if (size) {
287 cksum += * (UCHAR * )buffer;
288 }
289
290 cksum = (cksum >> 16 ) + (cksum & 0xffff );
291 cksum += (cksum >> 16 );
292 return (USHORT)( ~ cksum);
293 }
294 /*
295 Helper function to fill in various stuff in our ICMP request.
296 */
297 void fill_icmp_data( char * icmp_data, int datasize){
298
299 IcmpHeader * icmp_hdr;
300 char * datapart;
301
302 icmp_hdr = (IcmpHeader * )icmp_data;
303
304 icmp_hdr -> i_type = ICMP_ECHO;
305 icmp_hdr -> i_code = 0 ;
306 icmp_hdr -> i_id = (USHORT)GetCurrentProcessId();
307 icmp_hdr -> i_cksum = 0 ;
308 icmp_hdr -> i_seq = 0 ;
309
310 datapart = icmp_data + sizeof (IcmpHeader);
311 //
312 // Place some junk in the buffer.
313 //
314 memset(datapart, ' E ' , datasize - sizeof (IcmpHeader));
315
316 }
317
318 /* ****************** 附: ping命令执行时显示的画面 **************\
319 * C:\Documents and Settings\houzhijiang>ping 236.56.54.12 *
320 * *
321 * Pinging 236.56.54.12 with 32 bytes of data: *
322 * *
323 * Request timed out. *
324 * Request timed out. *
325 * Request timed out. *
326 * Request timed out. *
327 * *
328 * Ping statistics for 236.56.54.12: *
329 * Packets: Sent = 4, Received = 0, Lost = 4 (100% loss), *
330 * *
331 \************************************************************** */
332
333 /* **************************************************************\
334 * C:\Documents and Settings\houzhijiang>ping 127.0.0.1 *
335 * *
336 * Pinging 127.0.0.1 with 32 bytes of data: *
337 * *
338 * Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 *
339 * Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 *
340 * Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 *
341 * Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 *
342 * *
343 * Ping statistics for 127.0.0.1: *
344 * Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), *
345 * Approximate round trip times in milli-seconds: *
346 * Minimum = 0ms, Maximum = 0ms, Average = 0ms *
347 * *
348 \************************************************************** */
349