Subversion Repositories Kolibri OS

Rev

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: