Subversion Repositories Kolibri OS

Rev

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

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