Rev 7891 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7891 | Rev 9128 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2010-2020. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2010-2021. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;; ping.asm - ICMP echo client for KolibriOS ;; |
6 | ;; ping.asm - ICMP echo client for KolibriOS ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Written by hidnplayr@kolibrios.org ;; |
8 | ;; Written by hidnplayr@kolibrios.org ;; |
9 | ;; ;; |
9 | ;; ;; |
10 | ;; GNU GENERAL PUBLIC LICENSE ;; |
10 | ;; GNU GENERAL PUBLIC LICENSE ;; |
11 | ;; Version 2, June 1991 ;; |
11 | ;; Version 2, June 1991 ;; |
12 | ;; ;; |
12 | ;; ;; |
13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
14 | 14 | ||
15 | format binary as "" |
15 | format binary as "" |
16 | 16 | ||
17 | BUFFERSIZE = 65536 |
17 | BUFFERSIZE = 65536 |
18 | 18 | ||
19 | use32 |
19 | use32 |
20 | org 0x0 |
20 | org 0x0 |
21 | 21 | ||
22 | db 'MENUET01' ; signature |
22 | db 'MENUET01' ; signature |
23 | dd 1 ; header version |
23 | dd 1 ; header version |
24 | dd START ; entry point |
24 | dd START ; entry point |
25 | dd I_END ; initialized size |
25 | dd I_END ; initialized size |
26 | dd IM_END+0x1000 ; required memory |
26 | dd IM_END+0x1000 ; required memory |
27 | dd IM_END+0x1000 ; stack pointer |
27 | dd IM_END+0x1000 ; stack pointer |
28 | dd params ; parameters |
28 | dd params ; parameters |
29 | dd 0 ; path |
29 | dd 0 ; path |
30 | 30 | ||
31 | include '../../proc32.inc' |
31 | include '../../proc32.inc' |
32 | include '../../macros.inc' |
32 | include '../../macros.inc' |
33 | purge mov,add,sub |
33 | purge mov,add,sub |
34 | include '../../dll.inc' |
34 | include '../../dll.inc' |
35 | include '../../struct.inc' |
35 | include '../../struct.inc' |
36 | include '../../network.inc' |
36 | include '../../network.inc' |
37 | 37 | ||
38 | include '../icmp.inc' |
38 | include '../icmp.inc' |
39 | include '../ip.inc' |
39 | include '../ip.inc' |
40 | 40 | ||
41 | 41 | ||
42 | START: |
42 | START: |
43 | ; init heap |
43 | ; init heap |
44 | mcall 68, 11 |
44 | mcall 68, 11 |
45 | test eax, eax |
45 | test eax, eax |
46 | jz exit |
46 | jz exit |
47 | ; load libraries |
47 | ; load libraries |
48 | stdcall dll.Load, @IMPORT |
48 | stdcall dll.Load, @IMPORT |
49 | test eax, eax |
49 | test eax, eax |
50 | jnz exit |
50 | jnz exit |
51 | ; initialize console |
51 | ; initialize console |
52 | push 1 |
- | |
53 | call [con_start] |
52 | invoke con_start, 1 |
54 | push title |
- | |
55 | push 250 |
- | |
56 | push 80 |
- | |
57 | push 25 |
- | |
58 | push 80 |
- | |
59 | call [con_init] |
53 | invoke con_init, 80, 25, 80, 250, title |
60 | ; Init identifier with our PID number |
54 | ; Init identifier with our PID number |
61 | mcall 9, thread_info, -1 |
55 | mcall 9, thread_info, -1 |
62 | mov eax, [thread_info.PID] |
56 | mov eax, [thread_info.PID] |
63 | mov [icmp_packet.id], ax |
57 | mov [icmp_packet.id], ax |
64 | ; expand payload to 65504 bytes |
58 | ; expand payload to 65504 bytes |
65 | mov edi, icmp_packet.data+32 |
59 | mov edi, icmp_packet.data+32 |
66 | mov ecx, 65504/32-1 |
60 | mov ecx, 65504/32-1 |
67 | .expand_payload: |
61 | .expand_payload: |
68 | mov esi, icmp_packet.data |
62 | mov esi, icmp_packet.data |
69 | movsd |
63 | movsd |
70 | movsd |
64 | movsd |
71 | movsd |
65 | movsd |
72 | movsd |
66 | movsd |
73 | movsd |
67 | movsd |
74 | movsd |
68 | movsd |
75 | movsd |
69 | movsd |
76 | movsd |
70 | movsd |
77 | dec ecx |
71 | dec ecx |
78 | jnz .expand_payload |
72 | jnz .expand_payload |
79 | ; main loop |
73 | ; main loop |
80 | cmp byte[params], 0 |
74 | cmp byte[params], 0 |
81 | jne parse_param |
75 | jne parse_param |
82 | - | ||
83 | push str_welcome |
76 | |
84 | call [con_write_asciiz] |
77 | invoke con_write_asciiz, str_welcome |
85 | main: |
78 | main: |
86 | ; write prompt |
- | |
87 | push str_prompt |
79 | ; write prompt |
88 | call [con_write_asciiz] |
80 | invoke con_write_asciiz, str_prompt |
89 | ; read string |
81 | ; read string |
90 | mov esi, params |
- | |
91 | push 1024 |
- | |
92 | push esi |
82 | mov esi, params |
93 | call [con_gets] |
83 | invoke con_gets, esi, 1024 |
94 | ; check for exit |
84 | ; check for exit |
95 | test eax, eax |
85 | test eax, eax |
96 | jz exit |
86 | jz exit |
97 | cmp byte [esi], 10 |
87 | cmp byte [esi], 10 |
98 | jz exit |
88 | jz exit |
99 | ; delete terminating '\n' |
89 | ; delete terminating '\n' |
100 | push esi |
90 | push esi |
101 | @@: |
91 | @@: |
102 | lodsb |
92 | lodsb |
103 | test al, al |
93 | test al, al |
104 | jnz @b |
94 | jnz @b |
105 | mov [esi-2], al |
95 | mov [esi-2], al |
106 | pop esi |
96 | pop esi |
107 | 97 | ||
108 | ; reset stats |
98 | ; reset stats |
109 | mov [stats.tx], 0 |
99 | mov [stats.tx], 0 |
110 | mov [stats.rx], 0 |
100 | mov [stats.rx], 0 |
111 | mov [stats.time], 0 |
101 | mov [stats.time], 0 |
112 | 102 | ||
113 | parse_param: |
103 | parse_param: |
114 | ; parameters defaults |
104 | ; parameters defaults |
115 | mov [count], 4 |
105 | mov [count], 4 |
116 | mov [size], 32 |
106 | mov [size], 32 |
117 | mov [ttl], 128 |
107 | mov [ttl], 128 |
118 | mov [timeout], 300 |
108 | mov [timeout], 300 |
119 | 109 | ||
120 | ; Check if any additional parameters were given |
110 | ; Check if any additional parameters were given |
121 | mov esi, params |
111 | mov esi, params |
122 | mov ecx, 1024 |
112 | mov ecx, 1024 |
123 | .addrloop: |
113 | .addrloop: |
124 | lodsb |
114 | lodsb |
125 | test al, al |
115 | test al, al |
126 | jz .resolve |
116 | jz .resolve |
127 | cmp al, ' ' |
117 | cmp al, ' ' |
128 | jne .addrloop |
118 | jne .addrloop |
129 | mov byte[esi-1], 0 |
119 | mov byte[esi-1], 0 |
130 | jmp .param |
120 | jmp .param |
131 | 121 | ||
132 | .param_loop: |
122 | .param_loop: |
133 | lodsb |
123 | lodsb |
134 | test al, al |
124 | test al, al |
135 | jz .resolve |
125 | jz .resolve |
136 | cmp al, ' ' |
126 | cmp al, ' ' |
137 | jne .invalid |
127 | jne .invalid |
138 | .param: |
128 | .param: |
139 | lodsb |
129 | lodsb |
140 | cmp al, '-' |
130 | cmp al, '-' |
141 | jne .invalid |
131 | jne .invalid |
142 | lodsb |
132 | lodsb |
143 | cmp al, 't' |
133 | cmp al, 't' |
144 | jne @f |
134 | jne @f |
145 | mov [count], -1 ; infinite |
135 | mov [count], -1 ; infinite |
146 | jmp .param_loop |
136 | jmp .param_loop |
147 | @@: |
137 | @@: |
148 | cmp al, 'n' |
138 | cmp al, 'n' |
149 | jne @f |
139 | jne @f |
150 | call ascii_to_dec |
140 | call ascii_to_dec |
151 | test ebx, ebx |
141 | test ebx, ebx |
152 | jz .invalid |
142 | jz .invalid |
153 | mov [count], ebx |
143 | mov [count], ebx |
154 | jmp .param_loop |
144 | jmp .param_loop |
155 | @@: |
145 | @@: |
156 | cmp al, 'l' |
146 | cmp al, 'l' |
157 | jne @f |
147 | jne @f |
158 | call ascii_to_dec |
148 | call ascii_to_dec |
159 | test ebx, ebx |
149 | test ebx, ebx |
160 | jz .invalid |
150 | jz .invalid |
161 | cmp ebx, 65500 |
151 | cmp ebx, 65500 |
162 | ja .invalid |
152 | ja .invalid |
163 | mov [size], ebx |
153 | mov [size], ebx |
164 | jmp .param_loop |
154 | jmp .param_loop |
165 | @@: |
155 | @@: |
166 | cmp al, 'i' |
156 | cmp al, 'i' |
167 | jne @f |
157 | jne @f |
168 | call ascii_to_dec |
158 | call ascii_to_dec |
169 | test ebx, ebx |
159 | test ebx, ebx |
170 | jz .invalid |
160 | jz .invalid |
171 | cmp ebx, 255 |
161 | cmp ebx, 255 |
172 | ja .invalid |
162 | ja .invalid |
173 | mov [ttl], ebx |
163 | mov [ttl], ebx |
174 | jmp .param_loop |
164 | jmp .param_loop |
175 | @@: |
165 | @@: |
176 | cmp al, 'w' |
166 | cmp al, 'w' |
177 | jne @f |
167 | jne @f |
178 | call ascii_to_dec |
168 | call ascii_to_dec |
179 | test ebx, ebx |
169 | test ebx, ebx |
180 | jz .invalid |
170 | jz .invalid |
181 | mov [timeout], ebx |
171 | mov [timeout], ebx |
182 | jmp .param_loop |
172 | jmp .param_loop |
183 | @@: |
173 | @@: |
184 | ; implement more parameters here |
174 | ; implement more parameters here |
185 | .invalid: |
175 | .invalid: |
186 | push str13 |
- | |
187 | call [con_write_asciiz] |
176 | invoke con_write_asciiz, str13 |
188 | jmp main |
177 | jmp main |
189 | 178 | ||
190 | .resolve: |
179 | .resolve: |
191 | ; resolve name |
180 | ; resolve name |
192 | push esp ; reserve stack place |
181 | push esp ; reserve stack place |
193 | push esp ; fourth parameter |
- | |
194 | push 0 ; third parameter |
- | |
195 | push 0 ; second parameter |
- | |
196 | push params ; first parameter |
- | |
197 | call [getaddrinfo] |
182 | invoke getaddrinfo, params, 0, 0, esp |
198 | pop esi |
183 | pop esi |
199 | ; test for error |
184 | ; test for error |
200 | test eax, eax |
185 | test eax, eax |
201 | jnz fail |
186 | jnz fail |
202 | 187 | ||
203 | ; convert IP address to decimal notation |
188 | ; convert IP address to decimal notation |
204 | mov eax, [esi+addrinfo.ai_addr] |
189 | mov eax, [esi+addrinfo.ai_addr] |
205 | mov eax, [eax+sockaddr_in.sin_addr] |
190 | mov eax, [eax+sockaddr_in.sin_addr] |
206 | mov [sockaddr1.ip], eax |
191 | mov [sockaddr1.ip], eax |
207 | push eax |
- | |
208 | call [inet_ntoa] |
192 | invoke inet_ntoa, eax |
209 | ; write result |
193 | ; write result |
210 | mov [ip_ptr], eax |
194 | mov [ip_ptr], eax |
211 | 195 | ||
212 | push eax |
196 | push eax |
213 | 197 | ||
214 | ; free allocated memory |
198 | ; free allocated memory |
215 | push esi |
- | |
216 | call [freeaddrinfo] |
199 | invoke freeaddrinfo, esi |
217 | - | ||
218 | push str4 |
200 | |
219 | call [con_write_asciiz] |
201 | invoke con_write_asciiz, str4 |
220 | 202 | ||
221 | mcall socket, AF_INET4, SOCK_RAW, IPPROTO_ICMP |
203 | mcall socket, AF_INET4, SOCK_RAW, IPPROTO_ICMP |
222 | cmp eax, -1 |
204 | cmp eax, -1 |
223 | jz fail2 |
205 | jz fail2 |
224 | mov [socketnum], eax |
206 | mov [socketnum], eax |
225 | 207 | ||
226 | mcall connect, [socketnum], sockaddr1, 18 |
208 | mcall connect, [socketnum], sockaddr1, 18 |
227 | cmp eax, -1 |
209 | cmp eax, -1 |
228 | je fail2 |
210 | je fail2 |
229 | 211 | ||
230 | pushd [ttl] |
212 | pushd [ttl] |
231 | pushd 4 ; length of option |
213 | pushd 4 ; length of option |
232 | pushd IP_TTL |
214 | pushd IP_TTL |
233 | pushd IPPROTO_IP |
215 | pushd IPPROTO_IP |
234 | mcall setsockopt, [socketnum], esp |
216 | mcall setsockopt, [socketnum], esp |
235 | add esp, 16 |
217 | add esp, 16 |
236 | cmp eax, -1 |
218 | cmp eax, -1 |
237 | je fail2 |
219 | je fail2 |
238 | 220 | ||
239 | mcall 40, EVM_STACK |
221 | mcall 40, EVM_STACK |
240 | - | ||
241 | push str3 |
222 | |
242 | call [con_write_asciiz] |
- | |
243 | - | ||
244 | push [ip_ptr] |
223 | invoke con_write_asciiz, str3 |
245 | call [con_write_asciiz] |
- | |
246 | - | ||
247 | push [size] |
- | |
248 | push str3b |
224 | invoke con_write_asciiz, [ip_ptr] |
249 | call [con_printf] |
225 | invoke con_printf, str3b, [size] |
250 | add esp, 2*4 |
226 | add esp, 2*4 |
251 | 227 | ||
252 | mainloop: |
228 | mainloop: |
253 | call [con_get_flags] |
229 | invoke con_get_flags |
254 | test eax, 0x200 ; con window closed? |
230 | test eax, 0x200 ; con window closed? |
255 | jnz exit_now |
231 | jnz exit_now |
256 | 232 | ||
257 | inc [stats.tx] |
233 | inc [stats.tx] |
258 | mcall 26, 10 ; Get high precision timer count |
234 | mcall 26, 10 ; Get high precision timer count |
259 | mov [time_reference], eax |
235 | mov [time_reference], eax |
260 | mov esi, [size] |
236 | mov esi, [size] |
261 | add esi, sizeof.ICMP_header |
237 | add esi, sizeof.ICMP_header |
262 | xor edi, edi |
238 | xor edi, edi |
263 | mcall send, [socketnum], icmp_packet |
239 | mcall send, [socketnum], icmp_packet |
264 | cmp eax, -1 |
240 | cmp eax, -1 |
265 | je fail2 |
241 | je fail2 |
266 | 242 | ||
267 | mov [time_exceeded], 0 |
243 | mov [time_exceeded], 0 |
268 | .receiveloop: |
244 | .receiveloop: |
269 | mov ebx, [timeout] |
245 | mov ebx, [timeout] |
270 | sub ebx, [time_exceeded] |
246 | sub ebx, [time_exceeded] |
271 | jb .no_response |
247 | jb .no_response |
272 | mcall 23 ; Wait for network event with timeout |
248 | mcall 23 ; Wait for network event with timeout |
273 | 249 | ||
274 | mcall 26, 10 ; Get high precision timer count |
250 | mcall 26, 10 ; Get high precision timer count |
275 | sub eax, [time_reference] |
251 | sub eax, [time_reference] |
276 | jz @f |
252 | jz @f |
277 | xor edx, edx |
253 | xor edx, edx |
278 | mov ebx, 100000 |
254 | mov ebx, 100000 |
279 | div ebx |
255 | div ebx |
280 | cmp edx, 50000 |
256 | cmp edx, 50000 |
281 | jb @f |
257 | jb @f |
282 | inc eax |
258 | inc eax |
283 | @@: |
259 | @@: |
284 | mov [time_exceeded], eax ; Exceeded time in 1/100 s |
260 | mov [time_exceeded], eax ; Exceeded time in 1/100 s |
285 | 261 | ||
286 | ; Receive reply |
262 | ; Receive reply |
287 | mcall recv, [socketnum], buffer_ptr, BUFFERSIZE, MSG_DONTWAIT |
263 | mcall recv, [socketnum], buffer_ptr, BUFFERSIZE, MSG_DONTWAIT |
288 | cmp eax, -1 |
264 | cmp eax, -1 |
289 | je .no_response |
265 | je .no_response |
290 | test eax, eax |
266 | test eax, eax |
291 | jz fail2 |
267 | jz fail2 |
292 | 268 | ||
293 | ; IP header length |
269 | ; IP header length |
294 | movzx esi, byte[buffer_ptr] |
270 | movzx esi, byte[buffer_ptr] |
295 | and esi, 0xf |
271 | and esi, 0xf |
296 | shl esi, 2 |
272 | shl esi, 2 |
297 | 273 | ||
298 | ; Check packet length |
274 | ; Check packet length |
299 | sub eax, esi |
275 | sub eax, esi |
300 | sub eax, sizeof.ICMP_header |
276 | sub eax, sizeof.ICMP_header |
301 | jb .invalid |
277 | jb .invalid |
302 | mov [recvd], eax |
278 | mov [recvd], eax |
303 | 279 | ||
304 | ; make esi point to ICMP packet header |
280 | ; make esi point to ICMP packet header |
305 | add esi, buffer_ptr |
281 | add esi, buffer_ptr |
306 | 282 | ||
307 | ; Check identifier |
283 | ; Check identifier |
308 | mov ax, [icmp_packet.id] |
284 | mov ax, [icmp_packet.id] |
309 | cmp [esi + ICMP_header.Identifier], ax |
285 | cmp [esi + ICMP_header.Identifier], ax |
310 | jne .receiveloop |
286 | jne .receiveloop |
311 | 287 | ||
312 | ; we have a response, print the sender IP |
288 | ; we have a response, print the sender IP |
313 | push esi |
289 | push esi |
314 | mov eax, [buffer_ptr + IPv4_header.SourceAddress] |
290 | mov eax, [buffer_ptr + IPv4_header.SourceAddress] |
315 | rol eax, 16 |
291 | rol eax, 16 |
316 | movzx ebx, ah |
292 | movzx ebx, ah |
317 | push ebx |
293 | push ebx |
318 | movzx ebx, al |
294 | movzx ebx, al |
319 | push ebx |
295 | push ebx |
320 | shr eax, 16 |
296 | shr eax, 16 |
321 | movzx ebx, ah |
297 | movzx ebx, ah |
322 | push ebx |
298 | push ebx |
323 | movzx ebx, al |
299 | movzx ebx, al |
324 | push ebx |
300 | push ebx |
325 | push str11 |
301 | push str11 |
326 | call [con_printf] |
302 | call [con_printf] |
327 | add esp, 5*4 |
303 | add esp, 5*4 |
328 | pop esi |
304 | pop esi |
329 | 305 | ||
330 | ; What kind of response is it? |
306 | ; What kind of response is it? |
331 | cmp [esi + ICMP_header.Type], ICMP_ECHOREPLY |
307 | cmp [esi + ICMP_header.Type], ICMP_ECHOREPLY |
332 | je .echo_reply |
308 | je .echo_reply |
333 | cmp [esi + ICMP_header.Type], ICMP_TIMXCEED |
309 | cmp [esi + ICMP_header.Type], ICMP_TIMXCEED |
334 | je .ttl_exceeded |
310 | je .ttl_exceeded |
335 | 311 | ||
336 | jmp .invalid |
312 | jmp .invalid |
337 | 313 | ||
338 | 314 | ||
339 | .echo_reply: |
315 | .echo_reply: |
340 | 316 | ||
341 | ; Validate the payload |
317 | ; Validate the payload |
342 | add esi, sizeof.ICMP_header |
318 | add esi, sizeof.ICMP_header |
343 | mov ecx, [size] |
319 | mov ecx, [size] |
344 | mov edi, icmp_packet.data |
320 | mov edi, icmp_packet.data |
345 | repe cmpsb |
321 | repe cmpsb |
346 | jne .miscomp |
322 | jne .miscomp |
347 | 323 | ||
348 | ; update stats |
324 | ; update stats |
349 | inc [stats.rx] |
325 | inc [stats.rx] |
350 | mov eax, [time_exceeded] |
326 | mov eax, [time_exceeded] |
351 | add [stats.time], eax |
327 | add [stats.time], eax |
352 | 328 | ||
353 | ; Print time exceeded |
329 | ; Print time exceeded |
354 | movzx eax, [buffer_ptr + IPv4_header.TimeToLive] |
330 | movzx eax, [buffer_ptr + IPv4_header.TimeToLive] |
355 | push eax |
331 | push eax |
356 | mov eax, [time_exceeded] |
332 | mov eax, [time_exceeded] |
357 | xor edx, edx |
333 | xor edx, edx |
358 | mov ebx, 10 |
334 | mov ebx, 10 |
359 | div ebx |
335 | div ebx |
360 | push edx |
336 | push edx |
361 | push eax |
337 | push eax |
362 | push [recvd] |
338 | push [recvd] |
363 | - | ||
364 | push str7 |
339 | |
365 | call [con_printf] |
340 | invoke con_printf, str7 |
366 | add esp, 5*4 |
341 | add esp, 5*4 |
367 | 342 | ||
368 | jmp .continue |
343 | jmp .continue |
369 | 344 | ||
370 | 345 | ||
371 | .ttl_exceeded: |
346 | .ttl_exceeded: |
372 | push str14 |
- | |
373 | call [con_write_asciiz] |
347 | invoke con_write_asciiz, str14 |
374 | - | ||
375 | jmp .continue |
348 | jmp .continue |
376 | 349 | ||
377 | 350 | ||
378 | ; Error in packet, print it to user |
351 | ; Error in packet, print it to user |
379 | .miscomp: |
352 | .miscomp: |
380 | sub edi, icmp_packet.data+1 |
353 | sub edi, icmp_packet.data+1 |
381 | push edi |
354 | push edi |
382 | push str9 |
- | |
383 | call [con_printf] |
355 | invoke con_printf, str9 |
384 | add esp, 2*4 |
356 | add esp, 2*4 |
385 | jmp .continue |
357 | jmp .continue |
386 | 358 | ||
387 | ; Invalid reply |
359 | ; Invalid reply |
388 | .invalid: |
360 | .invalid: |
389 | push str10 |
- | |
390 | call [con_write_asciiz] |
361 | invoke con_write_asciiz, str13 |
391 | jmp .continue |
362 | jmp .continue |
392 | 363 | ||
393 | ; Timeout! |
364 | ; Timeout! |
394 | .no_response: |
365 | .no_response: |
395 | push str8 |
- | |
396 | call [con_write_asciiz] |
366 | invoke con_write_asciiz, str8 |
397 | 367 | ||
398 | ; Send more ICMP packets ? |
368 | ; Send more ICMP packets ? |
399 | .continue: |
369 | .continue: |
400 | inc [icmp_packet.seq] |
370 | inc [icmp_packet.seq] |
- | 371 | ||
- | 372 | invoke con_kbhit |
|
- | 373 | test eax, eax |
|
- | 374 | jz .nokey |
|
- | 375 | invoke con_getch2 |
|
- | 376 | cmp ax, 0x1E03 ; Ctrl+C |
|
- | 377 | je .stats |
|
- | 378 | .nokey: |
|
401 | 379 | ||
402 | cmp [count], -1 |
380 | cmp [count], -1 |
403 | je .forever |
381 | je .forever |
404 | dec [count] |
382 | dec [count] |
405 | jz .stats |
383 | jz .stats |
406 | .forever: |
384 | .forever: |
407 | ; wait a second before sending next request |
385 | ; wait a second before sending next request |
408 | mcall 5, 100 |
386 | mcall 5, 100 |
409 | jmp mainloop |
387 | jmp mainloop |
410 | 388 | ||
411 | ; Print statistics |
389 | ; Print statistics |
412 | .stats: |
390 | .stats: |
413 | cmp [stats.rx], 0 |
391 | cmp [stats.rx], 0 |
414 | jne @f |
392 | jne @f |
415 | xor eax, eax |
393 | xor eax, eax |
416 | xor edx, edx |
394 | xor edx, edx |
417 | jmp .zero |
395 | jmp .zero |
418 | @@: |
396 | @@: |
419 | xor edx, edx |
397 | xor edx, edx |
420 | mov eax, [stats.time] |
398 | mov eax, [stats.time] |
421 | div [stats.rx] |
399 | div [stats.rx] |
422 | xor edx, edx |
400 | xor edx, edx |
423 | mov ebx, 10 |
401 | mov ebx, 10 |
424 | div ebx |
402 | div ebx |
425 | .zero: |
403 | .zero: |
426 | push edx |
404 | push edx |
427 | push eax |
405 | push eax |
428 | push [stats.rx] |
406 | push [stats.rx] |
429 | push [stats.tx] |
407 | push [stats.tx] |
430 | push str12 |
- | |
431 | call [con_printf] |
408 | invoke con_printf, str12 |
432 | add esp, 5*4 |
409 | add esp, 5*4 |
433 | jmp main |
410 | jmp main |
434 | 411 | ||
435 | ; DNS error |
412 | ; DNS error |
436 | fail: |
413 | fail: |
437 | push str5 |
- | |
438 | call [con_write_asciiz] |
414 | invoke con_write_asciiz, str5 |
439 | jmp main |
415 | jmp main |
440 | 416 | ||
441 | ; Socket error |
417 | ; Socket error |
442 | fail2: |
418 | fail2: |
443 | push str6 |
- | |
444 | call [con_write_asciiz] |
419 | invoke con_write_asciiz, str6 |
445 | jmp main |
420 | jmp main |
446 | 421 | ||
447 | ; Finally.. exit! |
422 | ; Finally.. exit! |
448 | exit: |
423 | exit: |
449 | push 1 |
- | |
450 | call [con_exit] |
424 | invoke con_exit, 1 |
451 | exit_now: |
425 | exit_now: |
452 | mcall -1 |
426 | mcall -1 |
453 | 427 | ||
454 | 428 | ||
455 | ascii_to_dec: |
429 | ascii_to_dec: |
456 | 430 | ||
457 | lodsb |
431 | lodsb |
458 | cmp al, ' ' |
432 | cmp al, ' ' |
459 | jne .fail |
433 | jne .fail |
460 | 434 | ||
461 | xor eax, eax |
435 | xor eax, eax |
462 | xor ebx, ebx |
436 | xor ebx, ebx |
463 | .loop: |
437 | .loop: |
464 | lodsb |
438 | lodsb |
465 | test al, al |
439 | test al, al |
466 | jz .done |
440 | jz .done |
467 | cmp al, ' ' |
441 | cmp al, ' ' |
468 | je .done |
442 | je .done |
469 | sub al, '0' |
443 | sub al, '0' |
470 | jb .fail |
444 | jb .fail |
471 | cmp al, 9 |
445 | cmp al, 9 |
472 | ja .fail |
446 | ja .fail |
473 | lea ebx, [ebx*4+ebx] |
447 | lea ebx, [ebx*4+ebx] |
474 | lea ebx, [ebx*2+eax] |
448 | lea ebx, [ebx*2+eax] |
475 | jmp .loop |
449 | jmp .loop |
476 | .fail: |
450 | .fail: |
477 | xor ebx, ebx |
451 | xor ebx, ebx |
478 | .done: |
452 | .done: |
479 | dec esi |
453 | dec esi |
480 | ret |
454 | ret |
481 | 455 | ||
482 | 456 | ||
483 | 457 | ||
484 | 458 | ||
485 | ; data |
459 | ; data |
486 | title db 'ICMP echo (ping) client',0 |
460 | title db 'ICMP echo (ping) client',0 |
487 | str_welcome db 'Please enter the hostname or IP-address of the host you want to ping,',10 |
461 | str_welcome db 'Please enter the hostname or IP-address of the host you want to ping,',10 |
488 | db 'or just press enter to exit.',10,10 |
462 | db 'or just press enter to exit.',10,10 |
489 | db 'Options:',10 |
463 | db 'Options:',10 |
490 | db ' -t Send packets till users abort.',10 |
464 | db ' -t Send packets till users abort. (Ctrl+C))',10 |
491 | db ' -n number Number of requests to send.',10 |
465 | db ' -n number Number of requests to send.',10 |
492 | db ' -i TTL Time to live.',10 |
466 | db ' -i TTL Time to live.',10 |
493 | db ' -l size Size of echo request.',10 |
467 | db ' -l size Size of echo request.',10 |
494 | db ' -w time-out Time-out in hundredths of a second.',10,0 |
468 | db ' -w time-out Time-out in hundredths of a second.',10,0 |
495 | str_prompt db 10,'> ',0 |
469 | str_prompt db 10,'> ',0 |
496 | str3 db 'Pinging to ',0 |
470 | str3 db 'Pinging to ',0 |
497 | str3b db ' with %u data bytes',10,0 |
471 | str3b db ' with %u data bytes',10,0 |
498 | 472 | ||
499 | str4 db 10,0 |
473 | str4 db 10,0 |
500 | str5 db 'Name resolution failed.',10,0 |
474 | str5 db 'Name resolution failed.',10,0 |
501 | str6 db 'Socket error.',10,0 |
475 | str6 db 'Socket error.',10,0 |
502 | str13 db 'Invalid parameter(s)',10,0 |
476 | str13 db 'Invalid parameter(s)',10,0 |
503 | 477 | ||
504 | str11 db 'Answer from %u.%u.%u.%u: ',0 |
478 | str11 db 'Answer from %u.%u.%u.%u: ',0 |
505 | str7 db 'bytes=%u time=%u.%u ms TTL=%u',10,0 |
479 | str7 db 'bytes=%u time=%u.%u ms TTL=%u',10,0 |
506 | str8 db 'Timeout',10,0 |
480 | str8 db 'Timeout',10,0 |
507 | str9 db 'miscompare at offset %u.',10,0 |
481 | str9 db 'miscompare at offset %u.',10,0 |
508 | str10 db 'invalid reply.',10,0 |
482 | str10 db 'invalid reply.',10,0 |
509 | str14 db 'TTL expired.',10,0 |
483 | str14 db 'TTL expired.',10,0 |
510 | 484 | ||
511 | str12 db 10,'Statistics:',10,'%u packets sent, %u packets received',10,'average response time=%u.%u ms',10,0 |
485 | str12 db 10,'Statistics:',10,'%u packets sent, %u packets received',10,'average response time=%u.%u ms',10,0 |
512 | 486 | ||
513 | sockaddr1: |
487 | sockaddr1: |
514 | dw AF_INET4 |
488 | dw AF_INET4 |
515 | .port dw 0 |
489 | .port dw 0 |
516 | .ip dd 0 |
490 | .ip dd 0 |
517 | rb 10 |
491 | rb 10 |
518 | 492 | ||
519 | time_reference dd ? ; start time of sent packet |
493 | time_reference dd ? ; start time of sent packet |
520 | time_exceeded dd ? ; time exceeded between send and receive |
494 | time_exceeded dd ? ; time exceeded between send and receive |
521 | ip_ptr dd ? |
495 | ip_ptr dd ? |
522 | count dd ? |
496 | count dd ? |
523 | size dd ? |
497 | size dd ? |
524 | ttl dd ? |
498 | ttl dd ? |
525 | timeout dd ? |
499 | timeout dd ? |
526 | recvd dd ? ; received number of bytes in last packet |
500 | recvd dd ? ; received number of bytes in last packet |
527 | 501 | ||
528 | stats: |
502 | stats: |
529 | .tx dd ? |
503 | .tx dd ? |
530 | .rx dd ? |
504 | .rx dd ? |
531 | .time dd ? |
505 | .time dd ? |
532 | 506 | ||
533 | ; import |
507 | ; import |
534 | align 4 |
508 | align 4 |
535 | @IMPORT: |
509 | @IMPORT: |
536 | 510 | ||
537 | library network, 'network.obj', console, 'console.obj' |
511 | library network, 'network.obj', console, 'console.obj' |
538 | import network, \ |
512 | import network, \ |
539 | getaddrinfo, 'getaddrinfo', \ |
513 | getaddrinfo, 'getaddrinfo', \ |
540 | freeaddrinfo, 'freeaddrinfo', \ |
514 | freeaddrinfo, 'freeaddrinfo', \ |
541 | inet_ntoa, 'inet_ntoa' |
515 | inet_ntoa, 'inet_ntoa' |
542 | 516 | ||
543 | import console, \ |
517 | import console, \ |
544 | con_start, 'START', \ |
518 | con_start, 'START', \ |
545 | con_init, 'con_init', \ |
519 | con_init, 'con_init', \ |
546 | con_write_asciiz, 'con_write_asciiz', \ |
520 | con_write_asciiz, 'con_write_asciiz', \ |
547 | con_printf, 'con_printf', \ |
521 | con_printf, 'con_printf', \ |
548 | con_exit, 'con_exit', \ |
522 | con_exit, 'con_exit', \ |
549 | con_gets, 'con_gets',\ |
523 | con_gets, 'con_gets',\ |
550 | con_cls, 'con_cls',\ |
524 | con_cls, 'con_cls',\ |
551 | con_getch2, 'con_getch2',\ |
525 | con_getch2, 'con_getch2',\ |
552 | con_set_cursor_pos, 'con_set_cursor_pos',\ |
526 | con_set_cursor_pos, 'con_set_cursor_pos',\ |
553 | con_get_flags, 'con_get_flags' |
527 | con_get_flags, 'con_get_flags',\ |
- | 528 | con_kbhit, 'con_kbhit' |
|
554 | 529 | ||
555 | socketnum dd ? |
530 | socketnum dd ? |
556 | 531 | ||
557 | icmp_packet db ICMP_ECHO ; type |
532 | icmp_packet db ICMP_ECHO ; type |
558 | db 0 ; code |
533 | db 0 ; code |
559 | dw 0 ; checksum |
534 | dw 0 ; checksum |
560 | .id dw 0 ; identifier |
535 | .id dw 0 ; identifier |
561 | .seq dw 0x0000 ; sequence number |
536 | .seq dw 0x0000 ; sequence number |
562 | .data db 'abcdefghijklmnopqrstuvwxyz012345' |
537 | .data db 'abcdefghijklmnopqrstuvwxyz012345' |
563 | 538 | ||
564 | I_END: |
539 | I_END: |
565 | rb 65504-32 |
540 | rb 65504-32 |
566 | 541 | ||
567 | thread_info process_information |
542 | thread_info process_information |
568 | 543 | ||
569 | params rb 1024 |
544 | params rb 1024 |
570 | buffer_ptr: rb BUFFERSIZE |
545 | buffer_ptr: rb BUFFERSIZE |
571 | 546 | ||
572 | IM_END: |
547 | IM_END: |