Subversion Repositories Kolibri OS

Rev

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

Rev 3861 Rev 4052
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: 2924 $
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     [UDP_PACKETS_TX + edi]
233
        inc     [UDP_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
;-----------------------------------------------------------------
314
;-----------------------------------------------------------------
314
;
315
;
315
; ICMP_output
316
; ICMP_output
316
;
317
;
317
; IN:  eax = dest ip
318
; IN:  eax = dest ip
-
 
319
;      bh  = type
318
;      ebx = source ip
320
;      bl  = code
319
;      ecx = data length
321
;      ecx = data length
320
;      dh  = type
-
 
321
;      dl  = code
322
;      edx = source ip
322
;      esi = data offset
323
;      esi = data offset
323
;      edi = identifier shl 16 + sequence number
324
;      edi = identifier shl 16 + sequence number
324
;
325
;
325
;-----------------------------------------------------------------
326
;-----------------------------------------------------------------
326
align 4
327
align 4
327
ICMP_output:
328
ICMP_output:
328
 
329
 
329
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet\n"
330
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet\n"
330
 
331
 
331
        push    esi edi dx
-
 
332
 
-
 
333
        mov     edx, [eax + IP_SOCKET.LocalIP]
-
 
334
        mov     eax, [eax + IP_SOCKET.RemoteIP]
332
        push    esi edi bx
335
        add     ecx, sizeof.ICMP_header
333
        add     ecx, sizeof.ICMP_header
336
        mov     di, IP_PROTO_ICMP SHL 8 + 128           ; TTL
334
        mov     di, IP_PROTO_ICMP SHL 8 + 128           ; TTL
337
        call    IPv4_output
335
        call    IPv4_output
338
        jz      .exit
336
        jz      .exit
339
 
337
 
340
        DEBUGF  DEBUG_NETWORK_VERBOSE, "full icmp packet size: %u\n", edx
338
        DEBUGF  DEBUG_NETWORK_VERBOSE, "full icmp packet size: %u\n", edx
341
 
339
 
342
        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
343
        pop     dword [edi + ICMP_header.Identifier]    ; identifier and sequence number
341
        pop     dword [edi + ICMP_header.Identifier]    ; identifier and sequence number
344
        mov     [edi + ICMP_header.Checksum], 0
342
        mov     [edi + ICMP_header.Checksum], 0
345
 
343
 
346
        push    ebx ecx edx
344
        push    ebx ecx edx
347
        mov     esi, edi
345
        mov     esi, edi
348
        xor     edx, edx
346
        xor     edx, edx
349
        call    checksum_1
347
        call    checksum_1
350
        call    checksum_2
348
        call    checksum_2
351
        mov     [edi + ICMP_header.Checksum], dx
349
        mov     [edi + ICMP_header.Checksum], dx
352
        pop     edx ecx ebx esi
350
        pop     edx ecx ebx esi
353
 
351
 
354
        sub     ecx, sizeof.ICMP_header
352
        sub     ecx, sizeof.ICMP_header
355
        add     edi, sizeof.ICMP_header
353
        add     edi, sizeof.ICMP_header
356
        push    cx
354
        push    cx
357
        shr     cx, 2
355
        shr     cx, 2
358
        rep movsd
356
        rep movsd
359
        pop     cx
357
        pop     cx
360
        and     cx, 3
358
        and     cx, 3
361
        rep movsb
359
        rep movsb
362
 
360
 
363
        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
364
        push    edx edi
362
        push    edx edi
365
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
363
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
366
        call    [ebx + NET_DEVICE.transmit]
364
        call    [ebx + NET_DEVICE.transmit]
367
        test    eax, eax
365
        test    eax, eax
368
        jnz     @f
366
        jnz     @f
369
        call    NET_ptr_to_num4
367
        call    NET_ptr_to_num4
370
        inc     [ICMP_PACKETS_TX + edi]
368
        inc     [ICMP_PACKETS_TX + edi]
371
       @@:
369
       @@:
372
        ret
370
        ret
373
  .exit:
371
  .exit:
374
        DEBUGF  DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
372
        DEBUGF  DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
375
        add     esp, 2*4 + 2
373
        add     esp, 2*4 + 2
376
        ret
374
        ret
-
 
375
end if
377
 
376
 
378
 
377
 
379
 
378
 
380
 
379
 
381
;-----------------------------------------------------------------
380
;-----------------------------------------------------------------
382
;
381
;
383
; ICMP_output
382
; ICMP_output_raw
384
;
383
;
385
; IN:  eax = socket ptr
384
; IN:  eax = socket ptr
386
;      ecx = data length
385
;      ecx = data length
387
;      esi = data offset
386
;      esi = data offset
388
;
387
;
389
;-----------------------------------------------------------------
388
;-----------------------------------------------------------------
390
align 4
389
align 4
391
ICMP_output_raw:
390
ICMP_output_raw:
392
 
391
 
393
        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
394
 
393
 
395
        push    edx
394
        push    edx
396
 
395
 
397
        mov     di, IP_PROTO_ICMP SHL 8 + 128  ; TTL
396
        mov     di, IP_PROTO_ICMP SHL 8 + 128  ; TTL
398
        mov     edx, [eax + IP_SOCKET.LocalIP]
397
        mov     edx, [eax + IP_SOCKET.LocalIP]
399
        mov     eax, [eax + IP_SOCKET.RemoteIP]
398
        mov     eax, [eax + IP_SOCKET.RemoteIP]
400
        call    IPv4_output
399
        call    IPv4_output
401
        jz      .exit
400
        jz      .exit
402
 
401
 
403
        pop     esi
402
        pop     esi
404
        push    edx
403
        push    edx
405
        push    eax
404
        push    eax
406
 
405
 
407
        push    edi ecx
406
        push    edi ecx
408
        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
409
        rep movsb
408
        rep movsb
410
        pop     ecx edi
409
        pop     ecx edi
411
 
410
 
412
        mov     [edi + ICMP_header.Checksum], 0
411
        mov     [edi + ICMP_header.Checksum], 0
413
 
412
 
414
        mov     esi, edi
413
        mov     esi, edi
415
        xor     edx, edx
414
        xor     edx, edx
416
        call    checksum_1
415
        call    checksum_1
417
        call    checksum_2
416
        call    checksum_2
418
        mov     [edi + ICMP_header.Checksum], dx
417
        mov     [edi + ICMP_header.Checksum], dx
419
 
418
 
420
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
419
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
421
        call    [ebx + NET_DEVICE.transmit]
420
        call    [ebx + NET_DEVICE.transmit]
422
        test    eax, eax
421
        test    eax, eax
423
        jnz     @f
422
        jnz     @f
424
        call    NET_ptr_to_num4
423
        call    NET_ptr_to_num4
425
        inc     [ICMP_PACKETS_TX + edi]
424
        inc     [ICMP_PACKETS_TX + edi]
426
       @@:
425
       @@:
427
        ret
426
        ret
428
  .exit:
427
  .exit:
429
        DEBUGF  DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
428
        DEBUGF  DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
430
        add     esp, 4
429
        add     esp, 4
431
        ret
430
        ret
432
 
431
 
433
 
432
 
434
 
433
 
435
 
434
 
436
;-----------------------------------------------------------------
435
;-----------------------------------------------------------------
437
;
436
;
438
; ICMP_API
437
; ICMP_API
439
;
438
;
440
; This function is called by system function 75
439
; This function is called by system function 75
441
;
440
;
442
; IN:  subfunction number in bl
441
; IN:  subfunction number in bl
443
;      device number in bh
442
;      device number in bh
444
;      ecx, edx, .. depends on subfunction
443
;      ecx, edx, .. depends on subfunction
445
;
444
;
446
; OUT:
445
; OUT:
447
;
446
;
448
;-----------------------------------------------------------------
447
;-----------------------------------------------------------------
449
align 4
448
align 4
450
ICMP_api:
449
ICMP_api:
451
 
450
 
452
        movzx   eax, bh
451
        movzx   eax, bh
453
        shl     eax, 2
452
        shl     eax, 2
454
 
453
 
455
        test    bl, bl
454
        test    bl, bl
456
        jz      .packets_tx     ; 0
455
        jz      .packets_tx     ; 0
457
        dec     bl
456
        dec     bl
458
        jz      .packets_rx     ; 1
457
        jz      .packets_rx     ; 1
459
 
458
 
460
  .error:
459
  .error:
461
        mov     eax, -1
460
        mov     eax, -1
462
        ret
461
        ret
463
 
462
 
464
  .packets_tx:
463
  .packets_tx:
465
        mov     eax, [ICMP_PACKETS_TX + eax]
464
        mov     eax, [ICMP_PACKETS_TX + eax]
466
        ret
465
        ret
467
 
466
 
468
  .packets_rx:
467
  .packets_rx:
469
        mov     eax, [ICMP_PACKETS_RX + eax]
468
        mov     eax, [ICMP_PACKETS_RX + eax]
470
        ret
469
        ret