Subversion Repositories Kolibri OS

Rev

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

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