Subversion Repositories Kolibri OS

Rev

Rev 4435 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4435 Rev 4469
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2010-2013. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2010-2014. 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
; TODO: more precise timer, ttl, user selectable size/number of packets
15
; TODO: more precise timer, ttl, user selectable size/number of packets
16
 
16
 
17
format binary as ""
17
format binary as ""
18
 
18
 
19
BUFFERSIZE      = 1500
19
BUFFERSIZE      = 1500
20
IDENTIFIER      = 0x1337
20
IDENTIFIER      = 0x1337
21
 
21
 
22
use32
22
use32
23
        org     0x0
23
        org     0x0
24
 
24
 
25
        db      'MENUET01'      ; signature
25
        db      'MENUET01'      ; signature
26
        dd      1               ; header version
26
        dd      1               ; header version
27
        dd      start           ; entry point
27
        dd      start           ; entry point
28
        dd      I_END           ; initialized size
28
        dd      I_END           ; initialized size
29
        dd      mem             ; required memory
29
        dd      mem             ; required memory
30
        dd      mem             ; stack pointer
30
        dd      mem             ; stack pointer
31
        dd      s               ; parameters
31
        dd      s               ; parameters
32
        dd      0               ; path
32
        dd      0               ; path
33
 
33
 
34
 
34
 
35
; useful includes
35
; useful includes
36
include '../../macros.inc'
36
include '../../macros.inc'
37
purge mov,add,sub
37
purge mov,add,sub
38
include '../../proc32.inc'
38
include '../../proc32.inc'
39
include '../../dll.inc'
39
include '../../dll.inc'
40
include '../../network.inc'
40
include '../../network.inc'
41
 
41
 
42
include 'icmp.inc'
42
include 'icmp.inc'
43
 
43
 
44
 
44
 
45
start:
45
start:
46
; load libraries
46
; load libraries
47
        stdcall dll.Load, @IMPORT
47
        stdcall dll.Load, @IMPORT
48
        test    eax, eax
48
        test    eax, eax
49
        jnz     exit
49
        jnz     exit
50
; initialize console
50
; initialize console
51
        push    1
51
        push    1
52
        call    [con_start]
52
        call    [con_start]
53
        push    title
53
        push    title
54
        push    25
54
        push    25
55
        push    80
55
        push    80
56
        push    25
56
        push    25
57
        push    80
57
        push    80
58
        call    [con_init]
58
        call    [con_init]
59
; main loop
59
; main loop
60
        cmp     byte[s], 0
60
        cmp     byte[s], 0
61
        jne     resolve
61
        jne     resolve
62
 
62
 
63
        push    str_welcome
63
        push    str_welcome
64
        call    [con_write_asciiz]
64
        call    [con_write_asciiz]
65
main:
65
main:
66
; write prompt
66
; write prompt
67
        push    str_prompt
67
        push    str_prompt
68
        call    [con_write_asciiz]
68
        call    [con_write_asciiz]
69
; read string
69
; read string
70
        mov     esi, s
70
        mov     esi, s
71
        push    256
71
        push    256
72
        push    esi
72
        push    esi
73
        call    [con_gets]
73
        call    [con_gets]
74
; check for exit
74
; check for exit
75
        test    eax, eax
75
        test    eax, eax
76
        jz      exit
76
        jz      exit
77
        cmp     byte [esi], 10
77
        cmp     byte [esi], 10
78
        jz      exit
78
        jz      exit
79
; delete terminating '\n'
79
; delete terminating '\n'
80
        push    esi
80
        push    esi
81
@@:
81
@@:
82
        lodsb
82
        lodsb
83
        test    al, al
83
        test    al, al
84
        jnz     @b
84
        jnz     @b
85
        mov     byte [esi-2], al
85
        mov     byte [esi-2], al
86
        pop     esi
86
        pop     esi
87
 
87
 
88
; reset stats
88
; reset stats
89
        mov     [stats.tx], 0
89
        mov     [stats.tx], 0
90
        mov     [stats.rx], 0
90
        mov     [stats.rx], 0
91
        mov     [stats.time], 0
91
        mov     [stats.time], 0
92
 
92
 
93
resolve:
93
resolve:
94
; resolve name
94
; resolve name
95
        push    esp     ; reserve stack place
95
        push    esp     ; reserve stack place
96
        push    esp     ; fourth parameter
96
        push    esp     ; fourth parameter
97
        push    0       ; third parameter
97
        push    0       ; third parameter
98
        push    0       ; second parameter
98
        push    0       ; second parameter
99
        push    s       ; first parameter
99
        push    s       ; first parameter
100
        call    [getaddrinfo]
100
        call    [getaddrinfo]
101
        pop     esi
101
        pop     esi
102
; test for error
102
; test for error
103
        test    eax, eax
103
        test    eax, eax
104
        jnz     fail
104
        jnz     fail
105
 
105
 
106
; convert IP address to decimal notation
106
; convert IP address to decimal notation
107
        mov     eax, [esi+addrinfo.ai_addr]
107
        mov     eax, [esi+addrinfo.ai_addr]
108
        mov     eax, [eax+sockaddr_in.sin_addr]
108
        mov     eax, [eax+sockaddr_in.sin_addr]
109
        mov     [sockaddr1.ip], eax
109
        mov     [sockaddr1.ip], eax
110
        push    eax
110
        push    eax
111
        call    [inet_ntoa]
111
        call    [inet_ntoa]
112
; write result
112
; write result
113
        mov     [ip_ptr], eax
113
        mov     [ip_ptr], eax
114
 
114
 
115
        push    eax
115
        push    eax
116
 
116
 
117
; free allocated memory
117
; free allocated memory
118
        push    esi
118
        push    esi
119
        call    [freeaddrinfo]
119
        call    [freeaddrinfo]
120
 
120
 
121
        push    str4
121
        push    str4
122
        call    [con_write_asciiz]
122
        call    [con_write_asciiz]
123
 
123
 
124
        mcall   socket, AF_INET4, SOCK_RAW, IPPROTO_ICMP
124
        mcall   socket, AF_INET4, SOCK_RAW, IPPROTO_ICMP
125
        cmp     eax, -1
125
        cmp     eax, -1
126
        jz      fail2
126
        jz      fail2
127
        mov     [socketnum], eax
127
        mov     [socketnum], eax
128
 
128
 
129
        mcall   connect, [socketnum], sockaddr1, 18
129
        mcall   connect, [socketnum], sockaddr1, 18
130
 
130
 
131
        mcall   40, 1 shl 7 ; + 7
131
        mcall   40, 1 shl 7 ; + 7
132
;        call    [con_cls]
132
;        call    [con_cls]
133
 
133
 
134
        mov     [count], 4
134
        mov     [count], 4
135
 
135
 
136
        push    str3
136
        push    str3
137
        call    [con_write_asciiz]
137
        call    [con_write_asciiz]
138
 
138
 
139
        push    [ip_ptr]
139
        push    [ip_ptr]
140
        call    [con_write_asciiz]
140
        call    [con_write_asciiz]
141
 
141
 
142
        push    (icmp_packet.length - ICMP_Packet.Data)
142
        push    (icmp_packet.length - ICMP_Packet.Data)
143
        push    str3b
143
        push    str3b
144
        call    [con_printf]
144
        call    [con_printf]
145
 
145
 
146
mainloop:
146
mainloop:
147
        inc     [stats.tx]
147
        inc     [stats.tx]
148
        mcall   26,9
148
        mcall   26,9
149
        mov     [time_reference], eax
149
        mov     [time_reference], eax
150
        mcall   send, [socketnum], icmp_packet, icmp_packet.length, 0
150
        mcall   send, [socketnum], icmp_packet, icmp_packet.length, 0
151
 
151
 
152
        mcall   23, 300 ; 3 seconds time-out
152
        mcall   23, 300 ; 3 seconds time-out
153
        mcall   26,9
153
        mcall   26,9
154
        sub     eax, [time_reference]
154
        sub     eax, [time_reference]
155
        xor     edx, edx
155
        xor     edx, edx
156
        mov     cx, 10
156
        mov     cx, 10
157
        mul     cx
157
        mul     cx
158
        mov     [time_reference], eax
158
        mov     [time_reference], eax
159
 
159
 
160
        mcall   recv, [socketnum], buffer_ptr, BUFFERSIZE, MSG_DONTWAIT
160
        mcall   recv, [socketnum], buffer_ptr, BUFFERSIZE, MSG_DONTWAIT
161
        cmp     eax, -1
161
        cmp     eax, -1
162
        je      .no_response
162
        je      .no_response
163
 
163
 
164
        sub     eax, ICMP_Packet.Data
164
        sub     eax, ICMP_Packet.Data
165
        jb      .no_response            ; FIXME: use other error message?
165
        jb      .invalid
166
        mov     [recvd], eax
166
        mov     [recvd], eax
167
 
167
 
168
        cmp     word[buffer_ptr + ICMP_Packet.Identifier], IDENTIFIER
168
        cmp     word[buffer_ptr + ICMP_Packet.Identifier], IDENTIFIER
169
        jne     .no_response            ; FIXME: use other error message?
169
        jne     .invalid
170
 
170
 
171
; OK, we have a response, update stats and let the user know
171
; OK, we have a response, update stats and let the user know
172
        inc     [stats.rx]
172
        inc     [stats.rx]
173
        mov     eax, [time_reference]
173
        mov     eax, [time_reference]
174
        add     [stats.time], eax
174
        add     [stats.time], eax
175
 
175
 
176
        push    str11                   ; TODO: print IP address of packet sender
176
        push    str11                   ; TODO: print IP address of packet sender
177
        call    [con_write_asciiz]
177
        call    [con_write_asciiz]
178
 
178
 
179
; validate the packet
179
; validate the packet
180
        lea     esi, [buffer_ptr + ICMP_Packet.Data]
180
        lea     esi, [buffer_ptr + ICMP_Packet.Data]
181
        mov     ecx, [recvd]
181
        mov     ecx, [recvd]
182
        mov     edi, icmp_packet.data
182
        mov     edi, icmp_packet.data
183
        repe    cmpsb
183
        repe    cmpsb
184
        jne     .miscomp
184
        jne     .miscomp
185
 
185
 
186
; All OK, print to the user!
186
; All OK, print to the user!
187
        push    [time_reference]
187
        push    [time_reference]
188
        movzx   eax, word[buffer_ptr + ICMP_Packet.SequenceNumber]
188
        movzx   eax, word[buffer_ptr + ICMP_Packet.SequenceNumber]
189
        push    eax
189
        push    eax
190
        push    [recvd]
190
        push    [recvd]
191
 
191
 
192
        push    str7
192
        push    str7
193
        call    [con_printf]
193
        call    [con_printf]
194
 
194
 
195
        jmp     continue
195
        jmp     .continue
196
 
196
 
197
; Error in packet, print it to user
197
; Error in packet, print it to user
198
  .miscomp:
198
  .miscomp:
199
        sub     edi, icmp_packet.data
199
        sub     edi, icmp_packet.data
200
        push    edi
200
        push    edi
201
        push    str9
201
        push    str9
202
        call    [con_printf]
202
        call    [con_printf]
203
        jmp     continue
203
        jmp     .continue
-
 
204
 
-
 
205
; Invalid reply
-
 
206
  .invalid:
-
 
207
        push    str10
-
 
208
        call    [con_write_asciiz]
-
 
209
        jmp     .continue
204
 
210
 
205
; Timeout!
211
; Timeout!
206
  .no_response:
212
  .no_response:
207
        push    str8
213
        push    str8
208
        call    [con_write_asciiz]
214
        call    [con_write_asciiz]
209
 
215
 
210
; Send more ICMP packets ?
216
; Send more ICMP packets ?
211
   continue:
217
  .continue:
212
        inc     [icmp_packet.seq]
218
        inc     [icmp_packet.seq]
213
 
219
 
214
        dec     [count]
220
        dec     [count]
215
        jz      done
221
        jz      done
216
 
222
 
217
        mcall   5, 100  ; wait a second
223
        mcall   5, 100  ; wait a second
218
 
224
 
219
        jmp     mainloop
225
        jmp     mainloop
220
 
226
 
221
; Done..
227
; Done..
222
done:
228
done:
223
        cmp     [stats.rx], 0
229
        cmp     [stats.rx], 0
224
        jne     @f
230
        jne     @f
225
        xor     eax, eax
231
        xor     eax, eax
226
        jmp     .zero
232
        jmp     .zero
227
  @@:
233
  @@:
228
        xor     edx, edx
234
        xor     edx, edx
229
        mov     eax, [stats.time]
235
        mov     eax, [stats.time]
230
        div     [stats.rx]
236
        div     [stats.rx]
231
  .zero:
237
  .zero:
232
        push    eax
238
        push    eax
233
        push    [stats.rx]
239
        push    [stats.rx]
234
        push    [stats.tx]
240
        push    [stats.tx]
235
        push    str12
241
        push    str12
236
        call    [con_printf]
242
        call    [con_printf]
237
        jmp     main
243
        jmp     main
238
 
244
 
239
; DNS error
245
; DNS error
240
fail:
246
fail:
241
        push    str5
247
        push    str5
242
        call    [con_write_asciiz]
248
        call    [con_write_asciiz]
243
        jmp     main
249
        jmp     main
244
 
250
 
245
; Socket error
251
; Socket error
246
fail2:
252
fail2:
247
        push    str6
253
        push    str6
248
        call    [con_write_asciiz]
254
        call    [con_write_asciiz]
249
        jmp     main
255
        jmp     main
250
 
256
 
251
; Finally.. exit!
257
; Finally.. exit!
252
exit:
258
exit:
253
        push    1
259
        push    1
254
        call    [con_exit]
260
        call    [con_exit]
255
 
261
 
256
        mcall   -1
262
        mcall   -1
257
 
263
 
258
 
264
 
259
; data
265
; data
260
title   db      'ICMP echo (ping) client',0
266
title   db      'ICMP echo (ping) client',0
261
str_welcome db  'Please enter the hostname or IP-address of the host you want to ping,',10
267
str_welcome db  'Please enter the hostname or IP-address of the host you want to ping,',10
262
            db  'or just press enter to exit.',10,0
268
            db  'or just press enter to exit.',10,0
263
str_prompt  db  10,'> ',0
269
str_prompt  db  10,'> ',0
264
str3    db      'Pinging to ',0
270
str3    db      'Pinging to ',0
265
str3b   db      ' with %u data bytes',10,0
271
str3b   db      ' with %u data bytes',10,0
266
 
272
 
267
str4    db      10,0
273
str4    db      10,0
268
str5    db      'Name resolution failed.',10,0
274
str5    db      'Name resolution failed.',10,0
269
str6    db      'Could not open socket',10,0
275
str6    db      'Could not open socket',10,0
270
 
276
 
271
str11   db      'Answer: ',0
277
str11   db      'Answer: ',0
272
str7    db      'bytes=%u seq=%u time=%u ms',10,0
278
str7    db      'bytes=%u seq=%u time=%u ms',10,0
273
str8    db      'timeout!',10,0
279
str8    db      'timeout!',10,0
274
str9    db      'miscompare at offset %u',10,0
280
str9    db      'miscompare at offset %u',10,0
-
 
281
str10   db      'reply invalid',10,0
275
 
282
 
276
str12   db      10,'Ping stats:',10,'%u packets sent, %u packets received',10,'average response time=%u ms',10,0
283
str12   db      10,'Ping stats:',10,'%u packets sent, %u packets received',10,'average response time=%u ms',10,0
277
 
284
 
278
sockaddr1:
285
sockaddr1:
279
        dw AF_INET4
286
        dw AF_INET4
280
.port   dw 0
287
.port   dw 0
281
.ip     dd 0
288
.ip     dd 0
282
        rb 10
289
        rb 10
283
 
290
 
284
time_reference  dd ?
291
time_reference  dd ?
285
ip_ptr          dd ?
292
ip_ptr          dd ?
286
count           dd ?
293
count           dd ?
287
recvd           dd ?    ; received number of bytes in last packet
294
recvd           dd ?    ; received number of bytes in last packet
288
 
295
 
289
stats:
296
stats:
290
        .tx     dd ?
297
        .tx     dd ?
291
        .rx     dd ?
298
        .rx     dd ?
292
        .time   dd ?
299
        .time   dd ?
293
 
300
 
294
; import
301
; import
295
align 4
302
align 4
296
@IMPORT:
303
@IMPORT:
297
 
304
 
298
library network, 'network.obj', console, 'console.obj'
305
library network, 'network.obj', console, 'console.obj'
299
import  network,        \
306
import  network,        \
300
        getaddrinfo,    'getaddrinfo',  \
307
        getaddrinfo,    'getaddrinfo',  \
301
        freeaddrinfo,   'freeaddrinfo', \
308
        freeaddrinfo,   'freeaddrinfo', \
302
        inet_ntoa,      'inet_ntoa'
309
        inet_ntoa,      'inet_ntoa'
303
 
310
 
304
import  console,        \
311
import  console,        \
305
        con_start,      'START',        \
312
        con_start,      'START',        \
306
        con_init,       'con_init',     \
313
        con_init,       'con_init',     \
307
        con_write_asciiz,       'con_write_asciiz',     \
314
        con_write_asciiz,       'con_write_asciiz',     \
308
        con_printf,       'con_printf',     \
315
        con_printf,       'con_printf',     \
309
        con_exit,       'con_exit',     \
316
        con_exit,       'con_exit',     \
310
        con_gets,       'con_gets',\
317
        con_gets,       'con_gets',\
311
        con_cls,        'con_cls',\
318
        con_cls,        'con_cls',\
312
        con_getch2,     'con_getch2',\
319
        con_getch2,     'con_getch2',\
313
        con_set_cursor_pos, 'con_set_cursor_pos'
320
        con_set_cursor_pos, 'con_set_cursor_pos'
314
 
321
 
315
socketnum       dd ?
322
socketnum       dd ?
316
 
323
 
317
icmp_packet:    db 8            ; type
324
icmp_packet:    db 8            ; type
318
                db 0            ; code
325
                db 0            ; code
319
                dw 0            ;
326
                dw 0            ;
320
 .id            dw IDENTIFIER   ; identifier
327
 .id            dw IDENTIFIER   ; identifier
321
 .seq           dw 0x0000       ; sequence number
328
 .seq           dw 0x0000       ; sequence number
322
 .data          db 'abcdefghijklmnopqrstuvwxyz012345'
329
 .data          db 'abcdefghijklmnopqrstuvwxyz012345'
323
 .length = $ - icmp_packet
330
 .length = $ - icmp_packet
324
 
331
 
325
I_END:
332
I_END:
326
 
333
 
327
buffer_ptr      rb BUFFERSIZE
334
buffer_ptr      rb BUFFERSIZE
328
 
335
 
329
s               rb 1024
336
s               rb 1024
330
                rb 4096    ; stack
337
                rb 4096    ; stack
331
mem:
338
mem: