Subversion Repositories Kolibri OS

Rev

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

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