Rev 5805 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5805 | Rev 5842 | ||
---|---|---|---|
Line 10... | Line 10... | ||
10 | ;; GNU GENERAL PUBLIC LICENSE ;; |
10 | ;; GNU GENERAL PUBLIC LICENSE ;; |
11 | ;; Version 2, June 1991 ;; |
11 | ;; Version 2, June 1991 ;; |
12 | ;; ;; |
12 | ;; ;; |
13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 14... | Line -... | ||
14 | - | ||
15 | ; TODO: ttl, user selectable size/number of packets |
- | |
16 | 14 | ||
Line 17... | Line 15... | ||
17 | format binary as "" |
15 | format binary as "" |
18 | 16 | ||
Line 26... | Line 24... | ||
26 | dd 1 ; header version |
24 | dd 1 ; header version |
27 | dd START ; entry point |
25 | dd START ; entry point |
28 | dd I_END ; initialized size |
26 | dd I_END ; initialized size |
29 | dd IM_END+0x1000 ; required memory |
27 | dd IM_END+0x1000 ; required memory |
30 | dd IM_END+0x1000 ; stack pointer |
28 | dd IM_END+0x1000 ; stack pointer |
31 | dd s ; parameters |
29 | dd params ; parameters |
32 | dd 0 ; path |
30 | dd 0 ; path |
Line 33... | Line 31... | ||
33 | 31 | ||
34 | include '../../proc32.inc' |
32 | include '../../proc32.inc' |
35 | include '../../macros.inc' |
33 | include '../../macros.inc' |
36 | purge mov,add,sub |
34 | purge mov,add,sub |
- | 35 | include '../../dll.inc' |
|
37 | include '../../dll.inc' |
36 | include '../../struct.inc' |
Line 38... | Line 37... | ||
38 | include '../../network.inc' |
37 | include '../../network.inc' |
- | 38 | ||
Line 39... | Line 39... | ||
39 | 39 | include 'icmp.inc' |
|
40 | include 'icmp.inc' |
40 | include 'ip.inc' |
41 | 41 | ||
Line 51... | Line 51... | ||
51 | jnz exit |
51 | jnz exit |
52 | ; initialize console |
52 | ; initialize console |
53 | push 1 |
53 | push 1 |
54 | call [con_start] |
54 | call [con_start] |
55 | push title |
55 | push title |
56 | push 25 |
56 | push 250 |
57 | push 80 |
57 | push 80 |
58 | push 25 |
58 | push 25 |
59 | push 80 |
59 | push 80 |
60 | call [con_init] |
60 | call [con_init] |
- | 61 | ; expand payload to 65504 bytes |
|
- | 62 | mov edi, icmp_packet.data+32 |
|
- | 63 | mov ecx, 65504/32-1 |
|
- | 64 | .expand_payload: |
|
- | 65 | mov esi, icmp_packet.data |
|
- | 66 | movsd |
|
- | 67 | movsd |
|
- | 68 | movsd |
|
- | 69 | movsd |
|
- | 70 | movsd |
|
- | 71 | movsd |
|
- | 72 | movsd |
|
- | 73 | movsd |
|
- | 74 | dec ecx |
|
- | 75 | jnz .expand_payload |
|
61 | ; main loop |
76 | ; main loop |
62 | cmp byte[s], 0 |
77 | cmp byte[params], 0 |
63 | jne parse_param |
78 | jne parse_param |
Line 64... | Line 79... | ||
64 | 79 | ||
65 | push str_welcome |
80 | push str_welcome |
66 | call [con_write_asciiz] |
81 | call [con_write_asciiz] |
67 | main: |
82 | main: |
68 | ; write prompt |
83 | ; write prompt |
69 | push str_prompt |
84 | push str_prompt |
70 | call [con_write_asciiz] |
85 | call [con_write_asciiz] |
71 | ; read string |
86 | ; read string |
72 | mov esi, s |
87 | mov esi, params |
73 | push 256 |
88 | push 1024 |
74 | push esi |
89 | push esi |
75 | call [con_gets] |
90 | call [con_gets] |
76 | ; check for exit |
91 | ; check for exit |
77 | test eax, eax |
92 | test eax, eax |
Line 91... | Line 106... | ||
91 | mov [stats.tx], 0 |
106 | mov [stats.tx], 0 |
92 | mov [stats.rx], 0 |
107 | mov [stats.rx], 0 |
93 | mov [stats.time], 0 |
108 | mov [stats.time], 0 |
Line 94... | Line 109... | ||
94 | 109 | ||
- | 110 | parse_param: |
|
95 | parse_param: |
111 | ; parameters defaults |
- | 112 | mov [count], 4 |
|
- | 113 | mov [size], 32 |
|
- | 114 | mov [ttl], 128 |
|
Line 96... | Line 115... | ||
96 | mov [count], 4 ; default number of pings to send |
115 | mov [timeout], 300 |
97 | 116 | ||
98 | ; Check if any additional parameters were given |
117 | ; Check if any additional parameters were given |
99 | mov esi, s |
118 | mov esi, params |
100 | mov ecx, 1024 |
119 | mov ecx, 1024 |
101 | .addrloop: |
120 | .addrloop: |
102 | lodsb |
121 | lodsb |
Line 121... | Line 140... | ||
121 | cmp al, 't' |
140 | cmp al, 't' |
122 | jne @f |
141 | jne @f |
123 | mov [count], -1 ; infinite |
142 | mov [count], -1 ; infinite |
124 | jmp .param_loop |
143 | jmp .param_loop |
125 | @@: |
144 | @@: |
- | 145 | cmp al, 'n' |
|
- | 146 | jne @f |
|
- | 147 | call ascii_to_dec |
|
- | 148 | test ebx, ebx |
|
- | 149 | jz .invalid |
|
- | 150 | mov [count], ebx |
|
- | 151 | jmp .param_loop |
|
- | 152 | @@: |
|
- | 153 | cmp al, 'l' |
|
- | 154 | jne @f |
|
- | 155 | call ascii_to_dec |
|
- | 156 | test ebx, ebx |
|
- | 157 | jz .invalid |
|
- | 158 | cmp ebx, 65500 |
|
- | 159 | ja .invalid |
|
- | 160 | mov [size], ebx |
|
- | 161 | jmp .param_loop |
|
- | 162 | @@: |
|
- | 163 | cmp al, 'i' |
|
- | 164 | jne @f |
|
- | 165 | call ascii_to_dec |
|
- | 166 | test ebx, ebx |
|
- | 167 | jz .invalid |
|
- | 168 | cmp ebx, 255 |
|
- | 169 | ja .invalid |
|
- | 170 | mov [ttl], ebx |
|
- | 171 | jmp .param_loop |
|
- | 172 | @@: |
|
- | 173 | cmp al, 'w' |
|
- | 174 | jne @f |
|
- | 175 | call ascii_to_dec |
|
- | 176 | test ebx, ebx |
|
- | 177 | jz .invalid |
|
- | 178 | mov [timeout], ebx |
|
- | 179 | jmp .param_loop |
|
- | 180 | @@: |
|
126 | ; implement more parameters here |
181 | ; implement more parameters here |
127 | .invalid: |
182 | .invalid: |
128 | push str13 |
183 | push str13 |
129 | call [con_write_asciiz] |
184 | call [con_write_asciiz] |
130 | jmp main |
185 | jmp main |
Line 133... | Line 188... | ||
133 | ; resolve name |
188 | ; resolve name |
134 | push esp ; reserve stack place |
189 | push esp ; reserve stack place |
135 | push esp ; fourth parameter |
190 | push esp ; fourth parameter |
136 | push 0 ; third parameter |
191 | push 0 ; third parameter |
137 | push 0 ; second parameter |
192 | push 0 ; second parameter |
138 | push s ; first parameter |
193 | push params ; first parameter |
139 | call [getaddrinfo] |
194 | call [getaddrinfo] |
140 | pop esi |
195 | pop esi |
141 | ; test for error |
196 | ; test for error |
142 | test eax, eax |
197 | test eax, eax |
143 | jnz fail |
198 | jnz fail |
Line 164... | Line 219... | ||
164 | cmp eax, -1 |
219 | cmp eax, -1 |
165 | jz fail2 |
220 | jz fail2 |
166 | mov [socketnum], eax |
221 | mov [socketnum], eax |
Line 167... | Line 222... | ||
167 | 222 | ||
- | 223 | mcall connect, [socketnum], sockaddr1, 18 |
|
- | 224 | cmp eax, -1 |
|
- | 225 | je fail2 |
|
- | 226 | ||
- | 227 | pushd [ttl] |
|
- | 228 | pushd 4 ; length of option |
|
- | 229 | pushd IP_TTL |
|
- | 230 | pushd IPPROTO_IP |
|
- | 231 | mcall setsockopt, [socketnum], esp |
|
- | 232 | add esp, 16 |
|
- | 233 | cmp eax, -1 |
|
Line 168... | Line 234... | ||
168 | mcall connect, [socketnum], sockaddr1, 18 |
234 | je fail2 |
169 | - | ||
Line 170... | Line 235... | ||
170 | mcall 40, EVM_STACK |
235 | |
171 | ; call [con_cls] |
236 | mcall 40, EVM_STACK |
Line 172... | Line 237... | ||
172 | 237 | ||
173 | push str3 |
238 | push str3 |
Line 174... | Line 239... | ||
174 | call [con_write_asciiz] |
239 | call [con_write_asciiz] |
175 | 240 | ||
176 | push [ip_ptr] |
241 | push [ip_ptr] |
- | 242 | call [con_write_asciiz] |
|
Line 177... | Line 243... | ||
177 | call [con_write_asciiz] |
243 | |
178 | 244 | push [size] |
|
179 | push (icmp_packet.length - ICMP_Packet.Data) |
245 | push str3b |
180 | push str3b |
246 | call [con_printf] |
Line 181... | Line 247... | ||
181 | call [con_printf] |
247 | add esp, 2*4 |
182 | 248 | ||
183 | mainloop: |
249 | mainloop: |
- | 250 | call [con_get_flags] |
|
- | 251 | test eax, 0x200 ; con window closed? |
|
- | 252 | jnz exit_now |
|
184 | call [con_get_flags] |
253 | |
- | 254 | inc [stats.tx] |
|
- | 255 | mcall 26, 10 ; Get high precision timer count |
|
Line 185... | Line 256... | ||
185 | test eax, 0x200 ; con window closed? |
256 | mov [time_reference], eax |
186 | jnz exit_now |
257 | mov esi, [size] |
187 | 258 | add esi, sizeof.ICMP_header |
|
188 | inc [stats.tx] |
259 | xor edi, edi |
189 | mcall 26, 10 ; Get high precision timer count |
260 | mcall send, [socketnum], icmp_packet |
190 | mov [time_reference], eax |
261 | cmp eax, -1 |
Line 201... | Line 272... | ||
201 | jb @f |
272 | jb @f |
202 | inc eax |
273 | inc eax |
203 | @@: |
274 | @@: |
204 | mov [time_reference], eax |
275 | mov [time_reference], eax |
Line -... | Line 276... | ||
- | 276 | ||
205 | 277 | ; Receive reply |
|
206 | mcall recv, [socketnum], buffer_ptr, BUFFERSIZE, MSG_DONTWAIT |
278 | mcall recv, [socketnum], buffer_ptr, BUFFERSIZE, MSG_DONTWAIT |
207 | cmp eax, -1 |
279 | cmp eax, -1 |
- | 280 | je .no_response |
|
- | 281 | test eax, eax |
|
Line -... | Line 282... | ||
- | 282 | jz fail2 |
|
- | 283 | ||
- | 284 | ; IP header length |
|
- | 285 | movzx esi, byte[buffer_ptr] |
|
- | 286 | and esi, 0xf |
|
- | 287 | shl esi, 2 |
|
- | 288 | ||
208 | je .no_response |
289 | ; Check packet length |
209 | 290 | sub eax, esi |
|
210 | sub eax, ICMP_Packet.Data |
291 | sub eax, sizeof.ICMP_header |
Line 211... | Line 292... | ||
211 | jb .invalid |
292 | jb .invalid |
212 | mov [recvd], eax |
293 | mov [recvd], eax |
Line 213... | Line 294... | ||
213 | 294 | ||
- | 295 | ; make esi point to ICMP packet header |
|
- | 296 | add esi, buffer_ptr |
|
- | 297 | ||
- | 298 | ; we have a response, print the sender IP |
|
- | 299 | push esi |
|
- | 300 | mov eax, [buffer_ptr + IPv4_header.SourceAddress] |
|
- | 301 | rol eax, 16 |
|
- | 302 | movzx ebx, ah |
|
- | 303 | push ebx |
|
- | 304 | movzx ebx, al |
|
- | 305 | push ebx |
|
- | 306 | shr eax, 16 |
|
214 | cmp word[buffer_ptr + ICMP_Packet.Identifier], IDENTIFIER |
307 | movzx ebx, ah |
215 | jne .invalid |
308 | push ebx |
216 | 309 | movzx ebx, al |
|
- | 310 | push ebx |
|
Line -... | Line 311... | ||
- | 311 | push str11 |
|
217 | ; OK, we have a response, update stats and let the user know |
312 | call [con_printf] |
218 | inc [stats.rx] |
313 | add esp, 5*4 |
- | 314 | pop esi |
|
- | 315 | ||
- | 316 | ; What kind of response is it? |
|
- | 317 | cmp [esi + ICMP_header.Type], ICMP_ECHOREPLY |
|
Line -... | Line 318... | ||
- | 318 | je .echo_reply |
|
- | 319 | cmp [esi + ICMP_header.Type], ICMP_TIMXCEED |
|
- | 320 | je .ttl_exceeded |
|
- | 321 | ||
- | 322 | jmp .invalid |
|
- | 323 | ||
219 | mov eax, [time_reference] |
324 | |
220 | add [stats.time], eax |
325 | .echo_reply: |
221 | 326 | ||
222 | push str11 ; TODO: print IP address of packet sender |
327 | cmp [esi + ICMP_header.Identifier], IDENTIFIER |
223 | call [con_write_asciiz] |
328 | jne .invalid |
224 | 329 | ||
Line -... | Line 330... | ||
- | 330 | ; Validate the packet |
|
225 | ; validate the packet |
331 | add esi, sizeof.ICMP_header |
- | 332 | mov ecx, [size] |
|
- | 333 | mov edi, icmp_packet.data |
|
- | 334 | repe cmpsb |
|
- | 335 | jne .miscomp |
|
- | 336 | ||
226 | lea esi, [buffer_ptr + ICMP_Packet.Data] |
337 | ; update stats |
227 | mov ecx, [recvd] |
338 | inc [stats.rx] |
228 | mov edi, icmp_packet.data |
339 | mov eax, [time_reference] |
229 | repe cmpsb |
340 | add [stats.time], eax |
230 | jne .miscomp |
341 | |
231 | 342 | movzx eax, [buffer_ptr + IPv4_header.TimeToLive] |
|
232 | ; All OK, print to the user! |
- | |
233 | mov eax, [time_reference] |
- | |
234 | xor edx, edx |
343 | push eax |
Line 235... | Line 344... | ||
235 | mov ebx, 10 |
344 | mov eax, [time_reference] |
236 | div ebx |
345 | xor edx, edx |
- | 346 | mov ebx, 10 |
|
- | 347 | div ebx |
|
- | 348 | push edx |
|
- | 349 | push eax |
|
- | 350 | push [recvd] |
|
- | 351 | ||
- | 352 | push str7 |
|
- | 353 | call [con_printf] |
|
Line 237... | Line 354... | ||
237 | push edx |
354 | add esp, 5*4 |
Line -... | Line 355... | ||
- | 355 | ||
238 | push eax |
356 | jmp .continue |
239 | ; movzx eax, word[buffer_ptr + ICMP_Packet.SequenceNumber] |
357 | |
240 | ; push eax |
358 | |
241 | push [recvd] |
359 | .ttl_exceeded: |
242 | 360 | push str14 |
|
243 | push str7 |
361 | call [con_write_asciiz] |
- | 362 | ||
244 | call [con_printf] |
363 | jmp .continue |
Line 245... | Line 364... | ||
245 | 364 | ||
246 | jmp .continue |
365 | |
247 | 366 | ; Error in packet, print it to user |
|
Line 269... | Line 388... | ||
269 | inc [icmp_packet.seq] |
388 | inc [icmp_packet.seq] |
Line 270... | Line 389... | ||
270 | 389 | ||
271 | cmp [count], -1 |
390 | cmp [count], -1 |
272 | je .forever |
391 | je .forever |
273 | dec [count] |
392 | dec [count] |
274 | jz done |
393 | jz .stats |
- | 394 | .forever: |
|
275 | .forever: |
395 | ; wait a second before sending next request |
276 | mcall 5, 100 ; wait a second |
- | |
277 | 396 | mcall 5, 100 |
|
Line 278... | Line 397... | ||
278 | jmp mainloop |
397 | jmp mainloop |
279 | 398 | ||
280 | ; Done.. |
399 | ; Print statistics |
281 | done: |
400 | .stats: |
282 | cmp [stats.rx], 0 |
401 | cmp [stats.rx], 0 |
283 | jne @f |
402 | jne @f |
284 | xor eax, eax |
403 | xor eax, eax |
Line 296... | Line 415... | ||
296 | push eax |
415 | push eax |
297 | push [stats.rx] |
416 | push [stats.rx] |
298 | push [stats.tx] |
417 | push [stats.tx] |
299 | push str12 |
418 | push str12 |
300 | call [con_printf] |
419 | call [con_printf] |
- | 420 | add esp, 5*4 |
|
301 | jmp main |
421 | jmp main |
Line 302... | Line 422... | ||
302 | 422 | ||
303 | ; DNS error |
423 | ; DNS error |
304 | fail: |
424 | fail: |
Line 318... | Line 438... | ||
318 | call [con_exit] |
438 | call [con_exit] |
319 | exit_now: |
439 | exit_now: |
320 | mcall -1 |
440 | mcall -1 |
Line -... | Line 441... | ||
- | 441 | ||
- | 442 | ||
- | 443 | ascii_to_dec: |
|
- | 444 | ||
- | 445 | lodsb |
|
- | 446 | cmp al, ' ' |
|
- | 447 | jne .fail |
|
- | 448 | ||
- | 449 | xor eax, eax |
|
- | 450 | xor ebx, ebx |
|
- | 451 | .loop: |
|
- | 452 | lodsb |
|
- | 453 | test al, al |
|
- | 454 | jz .done |
|
- | 455 | cmp al, ' ' |
|
- | 456 | je .done |
|
- | 457 | sub al, '0' |
|
- | 458 | jb .fail |
|
- | 459 | cmp al, 9 |
|
- | 460 | ja .fail |
|
- | 461 | lea ebx, [ebx*4+ebx] |
|
- | 462 | lea ebx, [ebx*2+eax] |
|
- | 463 | jmp .loop |
|
- | 464 | .fail: |
|
- | 465 | xor ebx, ebx |
|
- | 466 | .done: |
|
- | 467 | dec esi |
|
- | 468 | ret |
|
- | 469 | ||
- | 470 | ||
321 | 471 | ||
322 | 472 | ||
323 | ; data |
473 | ; data |
324 | title db 'ICMP echo (ping) client',0 |
474 | title db 'ICMP echo (ping) client',0 |
- | 475 | str_welcome db 'Please enter the hostname or IP-address of the host you want to ping,',10 |
|
- | 476 | db 'or just press enter to exit.',10,10 |
|
- | 477 | db 'Options:',10 |
|
- | 478 | db ' -t Send packets till users abort.',10 |
|
- | 479 | db ' -n number Number of requests to send.',10 |
|
- | 480 | db ' -i TTL Time to live.',10 |
|
325 | str_welcome db 'Please enter the hostname or IP-address of the host you want to ping,',10 |
481 | db ' -l size Size of echo request.',10 |
326 | db 'or just press enter to exit.',10,0 |
482 | db ' -w time-out Time-out in hundredths of a second.',10,0 |
327 | str_prompt db 10,'> ',0 |
483 | str_prompt db 10,'> ',0 |
Line 328... | Line 484... | ||
328 | str3 db 'Pinging to ',0 |
484 | str3 db 'Pinging to ',0 |
329 | str3b db ' with %u data bytes',10,0 |
485 | str3b db ' with %u data bytes',10,0 |
330 | 486 | ||
331 | str4 db 10,0 |
487 | str4 db 10,0 |
Line 332... | Line 488... | ||
332 | str5 db 'Name resolution failed.',10,0 |
488 | str5 db 'Name resolution failed.',10,0 |
333 | str6 db 'Could not open socket',10,0 |
489 | str6 db 'Socket error.',10,0 |
334 | str13 db 'Invalid parameter(s)',10,0 |
490 | str13 db 'Invalid parameter(s)',10,0 |
335 | 491 | ||
336 | str11 db 'Answer: ',0 |
492 | str11 db 'Answer from %u.%u.%u.%u: ',0 |
- | 493 | str7 db 'bytes=%u time=%u.%u ms TTL=%u',10,0 |
|
Line 337... | Line 494... | ||
337 | str7 db 'bytes=%u time=%u.%u ms',10,0 |
494 | str8 db 'Timeout',10,0 |
Line 338... | Line 495... | ||
338 | str8 db 'Timeout',10,0 |
495 | str9 db 'miscompare at offset %u.',10,0 |
339 | str9 db 'Miscompare at offset %u',10,0 |
496 | str10 db 'invalid reply.',10,0 |
Line 348... | Line 505... | ||
348 | rb 10 |
505 | rb 10 |
Line 349... | Line 506... | ||
349 | 506 | ||
350 | time_reference dd ? |
507 | time_reference dd ? |
351 | ip_ptr dd ? |
508 | ip_ptr dd ? |
- | 509 | count dd ? |
|
- | 510 | size dd ? |
|
- | 511 | ttl dd ? |
|
352 | count dd ? |
512 | timeout dd ? |
Line 353... | Line 513... | ||
353 | recvd dd ? ; received number of bytes in last packet |
513 | recvd dd ? ; received number of bytes in last packet |
354 | 514 | ||
355 | stats: |
515 | stats: |
Line 379... | Line 539... | ||
379 | con_set_cursor_pos, 'con_set_cursor_pos',\ |
539 | con_set_cursor_pos, 'con_set_cursor_pos',\ |
380 | con_get_flags, 'con_get_flags' |
540 | con_get_flags, 'con_get_flags' |
Line 381... | Line 541... | ||
381 | 541 | ||
Line 382... | Line 542... | ||
382 | socketnum dd ? |
542 | socketnum dd ? |
383 | 543 | ||
384 | icmp_packet db 8 ; type |
544 | icmp_packet db ICMP_ECHO ; type |
385 | db 0 ; code |
545 | db 0 ; code |
386 | dw 0 ; |
546 | dw 0 ; checksum |
387 | .id dw IDENTIFIER ; identifier |
547 | .id dw IDENTIFIER ; identifier |
388 | .seq dw 0x0000 ; sequence number |
- | |
Line 389... | Line 548... | ||
389 | .data db 'abcdefghijklmnopqrstuvwxyz012345' |
548 | .seq dw 0x0000 ; sequence number |
- | 549 | .data db 'abcdefghijklmnopqrstuvwxyz012345' |
|
Line 390... | Line -... | ||
390 | .length = $ - icmp_packet |
- | |
391 | 550 | ||
392 | I_END: |
551 | I_END: |
Line 393... | Line 552... | ||
393 | 552 | rb 65504-32 |