Subversion Repositories Kolibri OS

Rev

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

Rev 5565 Rev 5594
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2015. 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: 5565 $
19
$Revision: 5594 $
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
;       ebx = pointer to device struct
134
;       ebx = pointer to device struct
135
;       ecx = ICMP Packet size
135
;       ecx = ICMP Packet size
136
;       esi = ptr to ICMP Packet data
136
;       esi = ptr to ICMP Packet data
137
;       edi = ptr to ipv4 source and dest address
137
;       edi = ptr to ipv4 source and dest address
138
;
138
;
139
;  OUT: /
139
;  OUT: /
140
;
140
;
141
;-----------------------------------------------------------------
141
;-----------------------------------------------------------------
142
align 4
142
align 4
143
ICMP_input:
143
ICMP_input:
144
 
144
 
145
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP_input\n"
145
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP_input\n"
146
 
146
 
147
; Check the checksum
147
; Check the checksum
148
        push    esi ecx
148
        push    esi ecx
149
        push    [esi + ICMP_header.Checksum]
149
        push    [esi + ICMP_header.Checksum]
150
        mov     [esi + ICMP_header.Checksum], 0
150
        mov     [esi + ICMP_header.Checksum], 0
151
        xor     edx, edx
151
        xor     edx, edx
152
        call    checksum_1
152
        call    checksum_1
153
        call    checksum_2
153
        call    checksum_2
154
        pop     si
154
        pop     si
155
        cmp     dx, si
155
        cmp     dx, si
156
        pop     ecx esi
156
        pop     ecx esi
157
        jne     .checksum_mismatch
157
        jne     .checksum_mismatch
158
 
158
 
159
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP_input: Checksum OK\n"
159
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP_input: Checksum OK\n"
160
 
160
 
161
; Ualidate device ptr
161
; Ualidate device ptr
162
        mov     eax, edi
162
        mov     eax, edi
163
        call    NET_ptr_to_num4
163
        call    NET_ptr_to_num4
164
        cmp     edi, -1
164
        cmp     edi, -1
165
        je      .dump
165
        je      .dump
166
 
166
 
167
; Update stats
167
; Update stats
168
        inc     [ICMP_PACKETS_RX + edi]
168
        inc     [ICMP_PACKETS_RX + edi]
169
 
169
 
170
; Is this an echo request?
170
; Is this an echo request?
171
        cmp     [esi + ICMP_header.Type], ICMP_ECHO
171
        cmp     [esi + ICMP_header.Type], ICMP_ECHO
172
        je      .echo_request
172
        je      .echo_request
173
 
173
 
174
; Look for an open ICMP socket
174
; Look for an open ICMP socket
175
        pusha
175
        pusha
176
        mov     ecx, socket_mutex
176
        mov     ecx, socket_mutex
177
        call    mutex_lock
177
        call    mutex_lock
178
        popa
178
        popa
179
 
179
 
180
        mov     edx, [eax]              ; ipv4 source address
180
        mov     edx, [eax]              ; ipv4 source address
181
        mov     eax, net_sockets
181
        mov     eax, net_sockets
182
  .try_more:
182
  .try_more:
183
;        mov      , [esi + ICMP_header.Identifier]
183
;        mov      , [esi + ICMP_header.Identifier]
184
  .next_socket:
184
  .next_socket:
185
        mov     eax, [eax + SOCKET.NextPtr]
185
        mov     eax, [eax + SOCKET.NextPtr]
186
        or      eax, eax
186
        or      eax, eax
187
        jz      .dump_
187
        jz      .dump_
188
 
188
 
189
        cmp     [eax + SOCKET.Domain], AF_INET4
189
        cmp     [eax + SOCKET.Domain], AF_INET4
190
        jne     .next_socket
190
        jne     .next_socket
191
 
191
 
192
        cmp     [eax + SOCKET.Protocol], IP_PROTO_ICMP
192
        cmp     [eax + SOCKET.Protocol], IP_PROTO_ICMP
193
        jne     .next_socket
193
        jne     .next_socket
194
 
194
 
195
        cmp     [eax + IP_SOCKET.RemoteIP], edx
195
        cmp     [eax + IP_SOCKET.RemoteIP], edx
196
        jne     .next_socket
196
        jne     .next_socket
197
 
197
 
198
;        cmp     [eax + ICMP_SOCKET.Identifier],
198
;        cmp     [eax + ICMP_SOCKET.Identifier],
199
;        jne     .next_socket
199
;        jne     .next_socket
200
 
200
 
201
        pusha
201
        pusha
202
        mov     ecx, socket_mutex
202
        mov     ecx, socket_mutex
203
        call    mutex_unlock
203
        call    mutex_unlock
204
        popa
204
        popa
205
 
205
 
206
        DEBUGF  DEBUG_NETWORK_VERBOSE, "socket=%x\n", eax
206
        DEBUGF  DEBUG_NETWORK_VERBOSE, "socket=%x\n", eax
207
 
207
 
208
        pusha
208
        pusha
209
        lea     ecx, [eax + SOCKET.mutex]
209
        lea     ecx, [eax + SOCKET.mutex]
210
        call    mutex_lock
210
        call    mutex_lock
211
        popa
211
        popa
212
 
212
 
213
        jmp     SOCKET_input
213
        jmp     SOCKET_input
214
 
214
 
215
 
215
 
216
 
216
 
217
  .echo_request:
217
  .echo_request:
218
 
218
 
219
; We'll reuse the packet so we can create the response as fast as possible
219
; We'll reuse the packet so we can create the response as fast as possible
220
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP echo request\n"
220
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP echo request\n"
221
 
221
 
222
; Change Packet type to reply
222
; Change Packet type to reply
223
        mov     [esi + ICMP_header.Type], ICMP_ECHOREPLY
223
        mov     [esi + ICMP_header.Type], ICMP_ECHOREPLY
224
 
224
 
225
        mov     eax, [esp]
225
        mov     eax, [esp]
226
        lea     esi, [eax + NET_BUFF.data]
226
        lea     esi, [eax + NET_BUFF.data]
227
 
227
 
228
; Check frame type
228
; Check frame type
229
        cmp     [eax + NET_BUFF.type], NET_BUFF_ETH
229
        cmp     [eax + NET_BUFF.type], NET_BUFF_ETH
230
        jne     .not_ethernet
230
        jne     .not_ethernet
231
 
231
 
232
; exchange dest and source MAC in ETH header
232
; exchange dest and source MAC in ETH header
233
        push    dword [esi + ETH_header.DstMAC]
233
        push    dword [esi + ETH_header.DstMAC]
234
        push    dword [esi + ETH_header.SrcMAC]
234
        push    dword [esi + ETH_header.SrcMAC]
235
        pop     dword [esi + ETH_header.DstMAC]
235
        pop     dword [esi + ETH_header.DstMAC]
236
        pop     dword [esi + ETH_header.SrcMAC]
236
        pop     dword [esi + ETH_header.SrcMAC]
237
        push    word [esi + ETH_header.DstMAC + 4]
237
        push    word [esi + ETH_header.DstMAC + 4]
238
        push    word [esi + ETH_header.SrcMAC + 4]
238
        push    word [esi + ETH_header.SrcMAC + 4]
239
        pop     word [esi + ETH_header.DstMAC + 4]
239
        pop     word [esi + ETH_header.DstMAC + 4]
240
        pop     word [esi + ETH_header.SrcMAC + 4]
240
        pop     word [esi + ETH_header.SrcMAC + 4]
241
        add     esi, sizeof.ETH_header
241
        add     esi, sizeof.ETH_header
242
 
242
 
243
  .not_ethernet:
243
  .not_ethernet:
244
; Exchange dest and source address in IP header
244
; Exchange dest and source address in IP header
245
        push    [esi + IPv4_header.SourceAddress]
245
        push    [esi + IPv4_header.SourceAddress]
246
        push    [esi + IPv4_header.DestinationAddress]
246
        push    [esi + IPv4_header.DestinationAddress]
247
        pop     [esi + IPv4_header.SourceAddress]
247
        pop     [esi + IPv4_header.SourceAddress]
248
        pop     [esi + IPv4_header.DestinationAddress]
248
        pop     [esi + IPv4_header.DestinationAddress]
249
 
249
 
250
; Calculate IP header length
250
; Calculate IP header length
251
        movzx   ecx, [esi + IPv4_header.VersionAndIHL]
251
        movzx   ecx, [esi + IPv4_header.VersionAndIHL]
252
        and     ecx, 0x0f
252
        and     ecx, 0x0f
253
        shl     cx, 2
253
        shl     cx, 2
254
        mov     edi, ecx                        ; put it in edi for later
254
        mov     edi, ecx                        ; put it in edi for later
255
 
255
 
256
; Calculate IP checksum
256
; Calculate IP checksum
257
        mov     eax, esi
257
        mov     eax, esi
258
        mov     [eax + IPv4_header.HeaderChecksum], 0
258
        mov     [eax + IPv4_header.HeaderChecksum], 0
259
        xor     edx, edx
259
        xor     edx, edx
260
        call    checksum_1
260
        call    checksum_1
261
        call    checksum_2
261
        call    checksum_2
262
        mov     [eax + IPv4_header.HeaderChecksum], dx
262
        mov     [eax + IPv4_header.HeaderChecksum], dx
263
 
263
 
264
; Calculate ICMP packet length
264
; Calculate ICMP packet length
265
        movzx   ecx, [eax + IPv4_header.TotalLength]
265
        movzx   ecx, [eax + IPv4_header.TotalLength]
266
        xchg    ch, cl
266
        xchg    ch, cl
267
        sub     ecx, edi                        ; IP packet length - IP header length = ICMP packet length
267
        sub     ecx, edi                        ; IP packet length - IP header length = ICMP packet length
268
 
268
 
269
; Calculate ICMP checkSum
269
; Calculate ICMP checkSum
270
        mov     eax, esi
270
        mov     eax, esi
271
        mov     [esi + ICMP_header.Checksum], 0
271
        mov     [esi + ICMP_header.Checksum], 0
272
        xor     edx, edx
272
        xor     edx, edx
273
        call    checksum_1
273
        call    checksum_1
274
        call    checksum_2
274
        call    checksum_2
275
        mov     [eax + ICMP_header.Checksum], dx
275
        mov     [eax + ICMP_header.Checksum], dx
276
 
276
 
277
; Transmit the frame
277
; Transmit the frame
278
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP transmitting reply\n"
278
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP transmitting reply\n"
279
        call    [ebx + NET_DEVICE.transmit]
279
        call    [ebx + NET_DEVICE.transmit]
280
        test    eax, eax
280
        test    eax, eax
281
        jnz     @f
281
        jnz     @f
282
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP transmit failed\n"
282
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP transmit failed\n"
283
        call    NET_ptr_to_num4
283
        call    NET_ptr_to_num4
284
        inc     [ICMP_PACKETS_TX + edi]
284
        inc     [ICMP_PACKETS_TX + edi]
285
       @@:
285
       @@:
286
        ret
286
        ret
287
 
287
 
288
  .dump_:
288
  .dump_:
289
        pusha
289
        pusha
290
        mov     ecx, socket_mutex
290
        mov     ecx, socket_mutex
291
        call    mutex_unlock
291
        call    mutex_unlock
292
        popa
292
        popa
293
 
293
 
294
        DEBUGF  DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n"
294
        DEBUGF  DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n"
295
        jmp     .dump
295
        jmp     .dump
296
 
296
 
297
  .checksum_mismatch:
297
  .checksum_mismatch:
298
        DEBUGF  DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n"
298
        DEBUGF  DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n"
299
 
299
 
300
  .dump:
300
  .dump:
301
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n"
301
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n"
302
        call    NET_BUFF_free
302
        call    NET_BUFF_free
303
        ret
303
        ret
304
 
304
 
305
 
305
 
306
if 0
306
if 0
307
;-----------------------------------------------------------------
307
;-----------------------------------------------------------------
308
;
308
;
309
; ICMP_output
309
; ICMP_output
310
;
310
;
311
; IN:  eax = dest ip
311
; IN:  eax = dest ip
312
;      bh  = type
312
;      bh  = type
313
;      bl  = code
313
;      bl  = code
314
;      ecx = data length
314
;      ecx = data length
315
;      edx = source ip
315
;      edx = source ip
316
;      esi = data offset
316
;      esi = data offset
317
;      edi = identifier shl 16 + sequence number
317
;      edi = identifier shl 16 + sequence number
318
;
318
;
319
;-----------------------------------------------------------------
319
;-----------------------------------------------------------------
320
align 4
320
align 4
321
ICMP_output:
321
ICMP_output:
322
 
322
 
323
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet\n"
323
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet\n"
324
 
324
 
325
        push    esi edi bx
325
        push    esi edi bx
326
        add     ecx, sizeof.ICMP_header
326
        add     ecx, sizeof.ICMP_header
327
        mov     di, IP_PROTO_ICMP SHL 8 + 128           ; TTL
327
        mov     di, IP_PROTO_ICMP SHL 8 + 128           ; TTL
328
        call    IPv4_output
328
        call    IPv4_output
329
        jz      .exit
329
        jz      .exit
330
 
330
 
331
        DEBUGF  DEBUG_NETWORK_VERBOSE, "full icmp packet size: %u\n", edx
331
        DEBUGF  DEBUG_NETWORK_VERBOSE, "full icmp packet size: %u\n", edx
332
 
332
 
333
        pop     word [edi + ICMP_header.Type]           ; Write both type and code bytes at once
333
        pop     word [edi + ICMP_header.Type]           ; Write both type and code bytes at once
334
        pop     dword [edi + ICMP_header.Identifier]    ; identifier and sequence number
334
        pop     dword [edi + ICMP_header.Identifier]    ; identifier and sequence number
335
        mov     [edi + ICMP_header.Checksum], 0
335
        mov     [edi + ICMP_header.Checksum], 0
336
 
336
 
337
        push    ebx ecx edx
337
        push    ebx ecx edx
338
        mov     esi, edi
338
        mov     esi, edi
339
        xor     edx, edx
339
        xor     edx, edx
340
        call    checksum_1
340
        call    checksum_1
341
        call    checksum_2
341
        call    checksum_2
342
        mov     [edi + ICMP_header.Checksum], dx
342
        mov     [edi + ICMP_header.Checksum], dx
343
        pop     edx ecx ebx esi
343
        pop     edx ecx ebx esi
344
 
344
 
345
        sub     ecx, sizeof.ICMP_header
345
        sub     ecx, sizeof.ICMP_header
346
        add     edi, sizeof.ICMP_header
346
        add     edi, sizeof.ICMP_header
347
        push    cx
347
        push    cx
348
        shr     cx, 2
348
        shr     cx, 2
349
        rep movsd
349
        rep movsd
350
        pop     cx
350
        pop     cx
351
        and     cx, 3
351
        and     cx, 3
352
        rep movsb
352
        rep movsb
353
 
353
 
354
        sub     edi, edx                                ;;; TODO: find a better way to remember start of packet
354
        sub     edi, edx                                ;;; TODO: find a better way to remember start of packet
355
        push    edx edi
355
        push    edx edi
356
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
356
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
357
        call    [ebx + NET_DEVICE.transmit]
357
        call    [ebx + NET_DEVICE.transmit]
358
        test    eax, eax
358
        test    eax, eax
359
        jnz     @f
359
        jnz     @f
360
        call    NET_ptr_to_num4
360
        call    NET_ptr_to_num4
361
        inc     [ICMP_PACKETS_TX + edi]
361
        inc     [ICMP_PACKETS_TX + edi]
362
       @@:
362
       @@:
363
        ret
363
        ret
364
  .exit:
364
  .exit:
365
        DEBUGF  DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
365
        DEBUGF  DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
366
        add     esp, 2*4 + 2
366
        add     esp, 2*4 + 2
367
        ret
367
        ret
368
end if
368
end if
369
 
369
 
370
 
370
 
371
 
371
 
372
 
372
 
373
;-----------------------------------------------------------------
373
;-----------------------------------------------------------------
374
;
374
;
375
; ICMP_output_raw
375
; ICMP_output_raw
376
;
376
;
377
; IN:  eax = socket ptr
377
; IN:  eax = socket ptr
378
;      ecx = data length
378
;      ecx = data length
379
;      esi = data offset
379
;      esi = data offset
380
;
380
;
381
;-----------------------------------------------------------------
381
;-----------------------------------------------------------------
382
align 4
382
align 4
383
ICMP_output_raw:
383
ICMP_output_raw:
384
 
384
 
385
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx
385
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx
386
 
386
 
387
        push    edx
387
        push    edx
388
 
388
 
389
        mov     di, IP_PROTO_ICMP SHL 8 + 128  ; TTL
389
        mov     di, IP_PROTO_ICMP SHL 8 + 128  ; TTL
390
        mov     edx, [eax + IP_SOCKET.LocalIP]
390
        mov     edx, [eax + IP_SOCKET.LocalIP]
-
 
391
        mov     ebx, [eax + IP_SOCKET.device]
391
        mov     eax, [eax + IP_SOCKET.RemoteIP]
392
        mov     eax, [eax + IP_SOCKET.RemoteIP]
392
        call    IPv4_output
393
        call    IPv4_output
393
        jz      .exit
394
        jz      .exit
394
 
395
 
395
        pop     esi
396
        pop     esi
396
        push    eax
397
        push    eax
397
 
398
 
398
        push    edi ecx
399
        push    edi ecx
399
        DEBUGF  DEBUG_NETWORK_VERBOSE, "copying %u bytes from %x to %x\n", ecx, esi, edi
400
        DEBUGF  DEBUG_NETWORK_VERBOSE, "copying %u bytes from %x to %x\n", ecx, esi, edi
400
        rep movsb
401
        rep movsb
401
        pop     ecx edi
402
        pop     ecx edi
402
 
403
 
403
        mov     [edi + ICMP_header.Checksum], 0
404
        mov     [edi + ICMP_header.Checksum], 0
404
 
405
 
405
        mov     esi, edi
406
        mov     esi, edi
406
        xor     edx, edx
407
        xor     edx, edx
407
        call    checksum_1
408
        call    checksum_1
408
        call    checksum_2
409
        call    checksum_2
409
        mov     [edi + ICMP_header.Checksum], dx
410
        mov     [edi + ICMP_header.Checksum], dx
410
 
411
 
411
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
412
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
412
        call    [ebx + NET_DEVICE.transmit]
413
        call    [ebx + NET_DEVICE.transmit]
413
        test    eax, eax
414
        test    eax, eax
414
        jnz     @f
415
        jnz     @f
415
        call    NET_ptr_to_num4
416
        call    NET_ptr_to_num4
416
        inc     [ICMP_PACKETS_TX + edi]
417
        inc     [ICMP_PACKETS_TX + edi]
417
       @@:
418
       @@:
418
        ret
419
        ret
419
  .exit:
420
  .exit:
420
        DEBUGF  DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
421
        DEBUGF  DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
421
        ret
422
        ret
422
 
423
 
423
 
424
 
424
 
425
 
425
 
426
 
426
;-----------------------------------------------------------------
427
;-----------------------------------------------------------------
427
;
428
;
428
; ICMP_API
429
; ICMP_API
429
;
430
;
430
; This function is called by system function 75
431
; This function is called by system function 75
431
;
432
;
432
; IN:  subfunction number in bl
433
; IN:  subfunction number in bl
433
;      device number in bh
434
;      device number in bh
434
;      ecx, edx, .. depends on subfunction
435
;      ecx, edx, .. depends on subfunction
435
;
436
;
436
; OUT:
437
; OUT:
437
;
438
;
438
;-----------------------------------------------------------------
439
;-----------------------------------------------------------------
439
align 4
440
align 4
440
ICMP_api:
441
ICMP_api:
441
 
442
 
442
        movzx   eax, bh
443
        movzx   eax, bh
443
        shl     eax, 2
444
        shl     eax, 2
444
 
445
 
445
        test    bl, bl
446
        test    bl, bl
446
        jz      .packets_tx     ; 0
447
        jz      .packets_tx     ; 0
447
        dec     bl
448
        dec     bl
448
        jz      .packets_rx     ; 1
449
        jz      .packets_rx     ; 1
449
 
450
 
450
  .error:
451
  .error:
451
        mov     eax, -1
452
        mov     eax, -1
452
        ret
453
        ret
453
 
454
 
454
  .packets_tx:
455
  .packets_tx:
455
        mov     eax, [ICMP_PACKETS_TX + eax]
456
        mov     eax, [ICMP_PACKETS_TX + eax]
456
        ret
457
        ret
457
 
458
 
458
  .packets_rx:
459
  .packets_rx:
459
        mov     eax, [ICMP_PACKETS_RX + eax]
460
        mov     eax, [ICMP_PACKETS_RX + eax]
460
        ret
461
        ret