Subversion Repositories Kolibri OS

Rev

Rev 2553 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1514 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.    ;;
1159 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  ICMP.INC                                                       ;;
7
;;                                                                 ;;
8
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
9
;;                                                                 ;;
10
;;  Based on the work of [Johnny_B] and [smb]                      ;;
11
;;                                                                 ;;
12
;;    Written by hidnplayr@kolibrios.org                           ;;
13
;;                                                                 ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
 
19
 
1206 hidnplayr 20
$Revision: 2614 $
1159 hidnplayr 21
 
22
; ICMP types & codes
23
 
2614 hidnplayr 24
ICMP_ECHOREPLY                  = 0               ; echo reply message
1159 hidnplayr 25
 
2614 hidnplayr 26
ICMP_UNREACH                    = 3
27
ICMP_UNREACH_NET                = 0               ; bad net
28
ICMP_UNREACH_HOST               = 1               ; bad host
29
ICMP_UNREACH_PROTOCOL           = 2               ; bad protocol
30
ICMP_UNREACH_PORT               = 3               ; bad port
31
ICMP_UNREACH_NEEDFRAG           = 4               ; IP_DF caused drop
32
ICMP_UNREACH_SRCFAIL            = 5               ; src route failed
33
ICMP_UNREACH_NET_UNKNOWN        = 6               ; unknown net
34
ICMP_UNREACH_HOST_UNKNOWN       = 7               ; unknown host
35
ICMP_UNREACH_ISOLATED           = 8               ; src host isolated
36
ICMP_UNREACH_NET_PROHIB         = 9               ; prohibited access
37
ICMP_UNREACH_HOST_PROHIB        = 10              ; ditto
38
ICMP_UNREACH_TOSNET             = 11              ; bad tos for net
39
ICMP_UNREACH_TOSHOST            = 12              ; bad tos for host
40
ICMP_UNREACH_FILTER_PROHIB      = 13              ; admin prohib
41
ICMP_UNREACH_HOST_PRECEDENCE    = 14             ; host prec vio.
42
ICMP_UNREACH_PRECEDENCE_CUTOFF  = 15           ; prec cutoff
1159 hidnplayr 43
 
2614 hidnplayr 44
ICMP_SOURCEQUENCH               = 4               ; Packet lost, slow down
1159 hidnplayr 45
 
2614 hidnplayr 46
ICMP_REDIRECT                   = 5               ; shorter route, codes:
47
ICMP_REDIRECT_NET               = 0               ; for network
48
ICMP_REDIRECT_HOST              = 1               ; for host
49
ICMP_REDIRECT_TOSNET            = 2               ; for tos and net
50
ICMP_REDIRECT_TOSHOST           = 3               ; for tos and host
1159 hidnplayr 51
 
2614 hidnplayr 52
ICMP_ALTHOSTADDR                = 6               ; alternate host address
53
ICMP_ECHO                       = 8               ; echo service
54
ICMP_ROUTERADVERT               = 9               ; router advertisement
55
ICMP_ROUTERADVERT_NORMAL        = 0                  ; normal advertisement
56
ICMP_ROUTERADVERT_NOROUTE_COMMON= 16         ; selective routing
1159 hidnplayr 57
 
2614 hidnplayr 58
ICMP_ROUTERSOLICIT              = 10              ; router solicitation
59
ICMP_TIMXCEED                   = 11              ; time exceeded, code:
60
ICMP_TIMXCEED_INTRANS           = 0               ; ttl==0 in transit
61
ICMP_TIMXCEED_REASS             = 1               ; ttl==0 in reass
1159 hidnplayr 62
 
2614 hidnplayr 63
ICMP_PARAMPROB                  = 12               ; ip header bad
64
ICMP_PARAMPROB_ERRATPTR         = 0            ; error at param ptr
65
ICMP_PARAMPROB_OPTABSENT        = 1            ; req. opt. absent
66
ICMP_PARAMPROB_LENGTH           = 2            ; bad length
1159 hidnplayr 67
 
2614 hidnplayr 68
ICMP_TSTAMP                     = 13              ; timestamp request
69
ICMP_TSTAMPREPLY                = 14              ; timestamp reply
70
ICMP_IREQ                       = 15              ; information request
71
ICMP_IREQREPLY                  = 16              ; information reply
72
ICMP_MASKREQ                    = 17              ; address mask request
73
ICMP_MASKREPLY                  = 18              ; address mask reply
74
ICMP_TRACEROUTE                 = 30              ; traceroute
75
ICMP_DATACONVERR                = 31              ; data conversion error
76
ICMP_MOBILE_REDIRECT            = 32              ; mobile host redirect
77
ICMP_IPV6_WHEREAREYOU           = 33              ; IPv6 where-are-you
78
ICMP_IPV6_IAMHERE               = 34              ; IPv6 i-am-here
79
ICMP_MOBILE_REGREQUEST          = 35              ; mobile registration req
80
ICMP_MOBILE_REGREPLY            = 36              ; mobile registreation reply
81
ICMP_SKIP                       = 39              ; SKIP
1159 hidnplayr 82
 
2614 hidnplayr 83
ICMP_PHOTURIS                   = 40              ; Photuris
84
ICMP_PHOTURIS_UNKNOWN_INDEX     = 1                ; unknown sec index
85
ICMP_PHOTURIS_AUTH_FAILED       = 2                ; auth failed
86
ICMP_PHOTURIS_DECRYPT_FAILED    = 3                ; decrypt failed
1159 hidnplayr 87
 
88
 
89
 
2308 hidnplayr 90
struct  ICMP_header
2305 hidnplayr 91
 
2311 hidnplayr 92
        Type                    db ?
93
        Code                    db ?
94
        Checksum                dw ?
95
        Identifier              dw ?
96
        SequenceNumber          dw ?
2305 hidnplayr 97
 
1159 hidnplayr 98
ends
99
 
100
 
101
align 4
102
uglobal
2311 hidnplayr 103
        ICMP_PACKETS_TX         rd MAX_IP
104
        ICMP_PACKETS_RX         rd MAX_IP
1159 hidnplayr 105
endg
106
 
1185 hidnplayr 107
 
108
 
1159 hidnplayr 109
;-----------------------------------------------------------------
110
;
111
; ICMP_init
112
;
113
;-----------------------------------------------------------------
114
 
1529 hidnplayr 115
macro ICMP_init {
116
 
2308 hidnplayr 117
        xor     eax, eax
118
        mov     edi, ICMP_PACKETS_TX
119
        mov     ecx, 2*MAX_IP
120
        rep     stosd
1159 hidnplayr 121
 
1529 hidnplayr 122
}
1171 hidnplayr 123
 
124
 
1257 hidnplayr 125
;-----------------------------------------------------------------
1159 hidnplayr 126
;
1514 hidnplayr 127
; ICMP_input:
1159 hidnplayr 128
;
1514 hidnplayr 129
;  This procedure will send reply's to ICMP echo's
130
;   and insert packets into sockets when needed
1159 hidnplayr 131
;
132
;  IN:  Pointer to buffer in [esp]
133
;       size of buffer in [esp+4]
1541 hidnplayr 134
;       ebx = pointer to device struct
135
;       ecx = ICMP Packet size
2310 hidnplayr 136
;       esi = ptr to ICMP Packet data
2308 hidnplayr 137
;       edi = ptr to ipv4 source and dest address
138
;
1159 hidnplayr 139
;  OUT: /
140
;
1257 hidnplayr 141
;-----------------------------------------------------------------
1159 hidnplayr 142
align 4
1514 hidnplayr 143
ICMP_input:
1159 hidnplayr 144
 
2308 hidnplayr 145
        DEBUGF  1,"ICMP_input - start\n"
1514 hidnplayr 146
 
1544 hidnplayr 147
; First, check the checksum (altough some implementations ignore it)
148
 
2310 hidnplayr 149
        push    esi ecx
2386 hidnplayr 150
        push    [esi + ICMP_header.Checksum]
151
        mov     [esi + ICMP_header.Checksum], 0
2308 hidnplayr 152
        xor     edx, edx
153
        call    checksum_1
154
        call    checksum_2
155
        pop     si
156
        cmp     dx, si
157
        pop     ecx edx
158
        jne     .checksum_mismatch
1544 hidnplayr 159
 
2308 hidnplayr 160
        cmp     [edx + ICMP_header.Type], ICMP_ECHO             ; Is this an echo request?
161
        jne     .check_sockets
1159 hidnplayr 162
 
2308 hidnplayr 163
; We well re-use the packet so we can create the response as fast as possible
164
; Notice: this only works on pure ethernet
1544 hidnplayr 165
 
2308 hidnplayr 166
        DEBUGF  1,"ICMP_input - echo request\n"
167
        mov     [edx + ICMP_header.Type], ICMP_ECHOREPLY        ; Change Packet type to reply
1159 hidnplayr 168
 
1544 hidnplayr 169
; Update stats (and validate device ptr)
2308 hidnplayr 170
        call    NET_ptr_to_num
171
        cmp     edi,-1
172
        je      .dump
173
        inc     [ICMP_PACKETS_RX+4*edi]
174
        inc     [ICMP_PACKETS_TX+4*edi]
1171 hidnplayr 175
 
1159 hidnplayr 176
; exchange dest and source address in IP header
177
; exchange dest and source MAC in ETH header
2308 hidnplayr 178
        mov     esi, [esp]                                      ; Start of buffer
179
        push    dword [esi + ETH_header.DstMAC]
180
        push    dword [esi + ETH_header.SrcMAC]
181
        pop     dword [esi + ETH_header.DstMAC]
182
        pop     dword [esi + ETH_header.SrcMAC]
183
        push    word [esi + ETH_header.DstMAC + 4]
184
        push    word [esi + ETH_header.SrcMAC + 4]
185
        pop     word [esi + ETH_header.DstMAC + 4]
186
        pop     word [esi + ETH_header.SrcMAC + 4]
1159 hidnplayr 187
 
2308 hidnplayr 188
        add     esi, sizeof.ETH_header
189
        push    [esi + IPv4_header.SourceAddress]
190
        push    [esi + IPv4_header.DestinationAddress]
191
        pop     [esi + IPv4_header.SourceAddress]
192
        pop     [esi + IPv4_header.DestinationAddress]
1159 hidnplayr 193
 
194
; Recalculate ip header checksum
2308 hidnplayr 195
        movzx   ecx, [esi + IPv4_header.VersionAndIHL]          ; Calculate IP Header length by using IHL field
196
        and     ecx, 0x0f
197
        shl     cx, 2
198
        mov     edi, ecx                                        ; IP header length
199
        mov     eax, edx                                        ; ICMP packet start addr
1159 hidnplayr 200
 
2308 hidnplayr 201
        push    esi                                             ; Calculate the IP checksum
202
        xor     edx, edx                                        ;
203
        call    checksum_1                                      ;
204
        call    checksum_2                                      ;
205
        pop     esi                                             ;
206
        mov     [esi + IPv4_header.HeaderChecksum], dx          ;
1544 hidnplayr 207
 
1159 hidnplayr 208
; Recalculate ICMP CheckSum
2308 hidnplayr 209
        movzx   ecx, [esi + IPv4_header.TotalLength]            ; Find length of IP Packet
210
        xchg    ch, cl                                          ;
211
        sub     ecx, edi                                        ; IP packet length - IP header length = ICMP packet length
1159 hidnplayr 212
 
2308 hidnplayr 213
        mov     esi, eax                                        ; Calculate ICMP checksum
214
        xor     edx, edx                                        ;
215
        call    checksum_1                                      ;
216
        call    checksum_2                                      ;
217
        mov     [eax + ICMP_header.Checksum], dx                ;
1544 hidnplayr 218
 
219
; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!)
2308 hidnplayr 220
        call    [ebx + NET_DEVICE.transmit]
221
        ret
1159 hidnplayr 222
 
1171 hidnplayr 223
 
224
 
225
 
1159 hidnplayr 226
       .check_sockets:
2308 hidnplayr 227
        ; Look for an open ICMP socket
1159 hidnplayr 228
 
2308 hidnplayr 229
        mov     esi, [edi]              ; ipv4 source address
2553 hidnplayr 230
        mov     eax, net_sockets
1159 hidnplayr 231
  .try_more:
2553 hidnplayr 232
;        mov      , [edx + ICMP_header.Identifier]
1159 hidnplayr 233
  .next_socket:
2553 hidnplayr 234
        mov     eax, [eax + SOCKET.NextPtr]
235
        or      eax, eax
2308 hidnplayr 236
        jz      .dump
1541 hidnplayr 237
 
2553 hidnplayr 238
        cmp     [eax + SOCKET.Domain], AF_INET4
2308 hidnplayr 239
        jne     .next_socket
1541 hidnplayr 240
 
2553 hidnplayr 241
        cmp     [eax + SOCKET.Protocol], IP_PROTO_ICMP
2308 hidnplayr 242
        jne     .next_socket
1171 hidnplayr 243
 
2553 hidnplayr 244
        cmp     [eax + IP_SOCKET.RemoteIP], esi
2308 hidnplayr 245
        jne     .next_socket
1159 hidnplayr 246
 
2553 hidnplayr 247
;        cmp     [eax + ICMP_SOCKET.Identifier],
1541 hidnplayr 248
;        jne     .next_socket
249
 
250
;        call    IPv4_dest_to_dev
251
;        cmp     edi,-1
252
;        je      .dump
253
;        inc     [ICMP_PACKETS_RX+edi]
254
 
2553 hidnplayr 255
        DEBUGF 1,"Found valid ICMP packet for socket %x\n", eax
1541 hidnplayr 256
 
2402 hidnplayr 257
        pusha
258
        lea     ecx, [eax + SOCKET.mutex]
259
        call    mutex_lock
260
        popa
1159 hidnplayr 261
 
2308 hidnplayr 262
        mov     esi, edx
263
        jmp     SOCKET_input
1159 hidnplayr 264
 
1541 hidnplayr 265
 
1544 hidnplayr 266
  .checksum_mismatch:
2308 hidnplayr 267
        DEBUGF  1,"ICMP_Handler - checksum mismatch\n"
1544 hidnplayr 268
 
269
  .dump:
2308 hidnplayr 270
        DEBUGF  1,"ICMP_Handler - dumping\n"
1159 hidnplayr 271
 
2308 hidnplayr 272
        call    kernel_free
273
        add     esp, 4 ; pop (balance stack)
1159 hidnplayr 274
 
2308 hidnplayr 275
        ret
1159 hidnplayr 276
 
277
 
1257 hidnplayr 278
;-----------------------------------------------------------------
1159 hidnplayr 279
;
1519 hidnplayr 280
; ICMP_output
1159 hidnplayr 281
;
1519 hidnplayr 282
; IN:  eax = dest ip
283
;      ebx = source ip
284
;      ecx = data length
285
;      dh  = type
286
;      dl  = code
287
;      high 16 bits of edx = fragment id (for IP header)
288
;      esi = data offset
289
;      edi = identifier shl 16 + sequence number
1159 hidnplayr 290
;
291
;-----------------------------------------------------------------
292
align 4
1514 hidnplayr 293
ICMP_output:
1159 hidnplayr 294
 
2308 hidnplayr 295
        DEBUGF  1,"Creating ICMP Packet\n"
1159 hidnplayr 296
 
2308 hidnplayr 297
        push    esi edi edx
1159 hidnplayr 298
 
2308 hidnplayr 299
        mov     ebx, [eax + IP_SOCKET.LocalIP]
300
        mov     eax, [eax + IP_SOCKET.RemoteIP]
301
        add     ecx, sizeof.ICMP_header
302
        mov     di , IP_PROTO_ICMP SHL 8 + 128  ; TTL
303
        shr     edx, 16
1159 hidnplayr 304
 
2308 hidnplayr 305
        call    IPv4_output
306
        jz      .exit
1159 hidnplayr 307
 
2308 hidnplayr 308
        DEBUGF  1,"full icmp packet size: %u\n", edx
1165 hidnplayr 309
 
2308 hidnplayr 310
        pop     eax
311
        mov     word [edi + ICMP_header.Type], ax       ; Write both type and code bytes at once
312
        pop     eax
313
        mov     [edi + ICMP_header.SequenceNumber], ax
314
        shr     eax, 16
315
        mov     [edi + ICMP_header.Identifier], ax
316
        mov     [edi + ICMP_header.Checksum], 0
1159 hidnplayr 317
 
2308 hidnplayr 318
        push    eax ebx ecx edx
319
        mov     esi, edi
320
        xor     edx, edx
321
        call    checksum_1
322
        call    checksum_2
323
        mov     [edi + ICMP_header.Checksum], dx
324
        pop     edx ecx ebx eax esi
1159 hidnplayr 325
 
2308 hidnplayr 326
        sub     ecx, sizeof.ICMP_header
327
        add     edi, sizeof.ICMP_header
328
        push    cx
329
        shr     cx , 2
330
        rep     movsd
331
        pop     cx
332
        and     cx , 3
333
        rep     movsb
1159 hidnplayr 334
 
2308 hidnplayr 335
        sub     edi, edx                                ;;; TODO: find a better way to remember start of packet
336
        push    edx edi
337
        DEBUGF  1,"Sending ICMP Packet\n"
338
        call    [ebx + NET_DEVICE.transmit]
339
        ret
1159 hidnplayr 340
  .exit:
2308 hidnplayr 341
        DEBUGF  1,"Creating ICMP Packet failed\n"
342
        add     esp, 3*4
343
        ret
1159 hidnplayr 344
 
345
 
346
 
347
 
1257 hidnplayr 348
;-----------------------------------------------------------------
1159 hidnplayr 349
;
1541 hidnplayr 350
; ICMP_output
351
;
352
; IN:  eax = socket ptr
353
;      ecx = data length
354
;      esi = data offset
355
;
356
;-----------------------------------------------------------------
357
align 4
358
ICMP_output_raw:
359
 
2308 hidnplayr 360
        DEBUGF  1,"Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx
1541 hidnplayr 361
 
2308 hidnplayr 362
        push    edx
1541 hidnplayr 363
 
2308 hidnplayr 364
        mov     di, IP_PROTO_ICMP SHL 8 + 128  ; TTL
365
        shr     edx, 16
366
        mov     ebx, [eax + IP_SOCKET.LocalIP]
367
        mov     eax, [eax + IP_SOCKET.RemoteIP]
368
        call    IPv4_output
369
        jz      .exit
1541 hidnplayr 370
 
2308 hidnplayr 371
        pop     esi
372
        push    edx
373
        push    eax
1541 hidnplayr 374
 
2308 hidnplayr 375
        push    edi ecx
376
        DEBUGF  1,"copying %u bytes from %x to %x\n", ecx, esi, edi
377
        rep     movsb
378
        pop     ecx edi
1541 hidnplayr 379
 
2308 hidnplayr 380
        mov     [edi + ICMP_header.Checksum], 0
1541 hidnplayr 381
 
2308 hidnplayr 382
        mov     esi, edi
383
        xor     edx, edx
384
        call    checksum_1
385
        call    checksum_2
386
        mov     [edi + ICMP_header.Checksum], dx
1541 hidnplayr 387
 
2308 hidnplayr 388
        DEBUGF  1,"Sending ICMP Packet\n"
389
        call    [ebx + NET_DEVICE.transmit]
390
        ret
1541 hidnplayr 391
  .exit:
2308 hidnplayr 392
        DEBUGF  1,"Creating ICMP Packet failed\n"
393
        add     esp, 4
394
        ret
1541 hidnplayr 395
 
396
 
397
 
398
 
399
;-----------------------------------------------------------------
400
;
1159 hidnplayr 401
; ICMP_API
402
;
403
; This function is called by system function 75
404
;
405
; IN:  subfunction number in bl
406
;      device number in bh
407
;      ecx, edx, .. depends on subfunction
408
;
409
; OUT:
410
;
1257 hidnplayr 411
;-----------------------------------------------------------------
1159 hidnplayr 412
align 4
2614 hidnplayr 413
ICMP_api:
1159 hidnplayr 414
 
2308 hidnplayr 415
        movzx   eax, bh
416
        shl     eax, 2
1159 hidnplayr 417
 
2308 hidnplayr 418
        test    bl, bl
419
        jz      .packets_tx     ; 0
420
        dec     bl
421
        jz      .packets_rx     ; 1
1159 hidnplayr 422
 
2614 hidnplayr 423
  .error:
2308 hidnplayr 424
        mov     eax, -1
425
        ret
1159 hidnplayr 426
 
2614 hidnplayr 427
  .packets_tx:
428
        mov     eax, [ICMP_PACKETS_TX + eax]
2308 hidnplayr 429
        ret
1159 hidnplayr 430
 
2614 hidnplayr 431
  .packets_rx:
432
        mov     eax, [ICMP_PACKETS_RX + eax]
2308 hidnplayr 433
        ret