Subversion Repositories Kolibri OS

Rev

Rev 5363 | Rev 5584 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5363 Rev 5522
Line 14... Line 14...
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 18... Line 18...
18
 
18
 
Line 19... Line 19...
19
$Revision: 5363 $
19
$Revision: 5522 $
Line 20... Line 20...
20
 
20
 
Line 129... Line 129...
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
;
Line 141... Line 140...
141
;
140
;
142
;-----------------------------------------------------------------
141
;-----------------------------------------------------------------
143
align 4
142
align 4
144
ICMP_input:
143
ICMP_input:
Line 145... Line 144...
145
 
144
 
146
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP_input:\n"
-
 
147
 
-
 
Line -... Line 145...
-
 
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
Line 158... Line -...
158
        pop     ecx edx
-
 
159
        jne     .checksum_mismatch
-
 
160
 
156
        pop     ecx esi
161
; Check packet type
-
 
Line 162... Line 157...
162
 
157
        jne     .checksum_mismatch
-
 
158
 
163
        cmp     [edx + ICMP_header.Type], ICMP_ECHO             ; Is this an echo request?
159
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP_input: Checksum OK\n"
164
        jne     .check_sockets
160
 
165
 
161
; Ualidate device ptr
166
; Update stats (and validate device ptr)
-
 
167
        call    NET_ptr_to_num4
-
 
168
        cmp     edi, -1
-
 
169
        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
-
 
Line -... Line 162...
-
 
162
        mov     eax, edi
-
 
163
        call    NET_ptr_to_num4
Line -... Line 164...
-
 
164
        cmp     edi, -1
-
 
165
        je      .dump
-
 
166
 
Line 233... Line -...
233
        inc     [ICMP_PACKETS_TX + edi]
-
 
234
       @@:
167
; Update stats
235
        ret
-
 
236
 
168
        inc     [ICMP_PACKETS_RX + edi]
237
 
169
 
238
 
170
; Is this an echo request?
239
 
171
        cmp     [esi + ICMP_header.Type], ICMP_ECHO
Line 240... Line 172...
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
 
Line 258... Line 190...
258
        jne     .next_socket
190
        jne     .next_socket
Line 259... Line 191...
259
 
191
 
260
        cmp     [eax + SOCKET.Protocol], IP_PROTO_ICMP
192
        cmp     [eax + SOCKET.Protocol], IP_PROTO_ICMP
Line 261... Line 193...
261
        jne     .next_socket
193
        jne     .next_socket
262
 
194
 
Line 263... Line 195...
263
        cmp     [eax + IP_SOCKET.RemoteIP], esi
195
        cmp     [eax + IP_SOCKET.RemoteIP], edx
264
        jne     .next_socket
196
        jne     .next_socket
Line 265... Line -...
265
 
-
 
266
;        cmp     [eax + ICMP_SOCKET.Identifier],
-
 
267
;        jne     .next_socket
-
 
268
 
-
 
269
; Update stats (and validate device ptr)
-
 
270
        call    NET_ptr_to_num4
-
 
271
        cmp     edi, -1
197
 
272
        je      .dump_
198
;        cmp     [eax + ICMP_SOCKET.Identifier],
273
        inc     [ICMP_PACKETS_RX + edi]
199
;        jne     .next_socket
274
 
200
 
Line 282... Line 208...
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
Line 286... Line -...
286
 
-
 
287
        mov     esi, edx
212
 
Line 288... Line -...
288
        jmp     SOCKET_input
-
 
Line -... Line 213...
-
 
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
Line 293... Line 290...
293
        mov     ecx, socket_mutex
290
        mov     ecx, socket_mutex
294
        call    mutex_unlock
291
        call    mutex_unlock
Line 295... Line -...
295
        popa
-
 
296
 
292
        popa
297
        DEBUGF  DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n"
293
 
Line 298... Line 294...
298
        jmp     .dump
294
        DEBUGF  DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n"
299
 
295
        jmp     .dump
300
 
-
 
301
  .checksum_mismatch:
296
 
302
        DEBUGF  DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n"
-
 
303
 
-
 
304
  .dump:
297
  .checksum_mismatch:
Line 305... Line 298...
305
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n"
298
        DEBUGF  DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n"
306
 
299
 
Line 398... Line 391...
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
Line 401... Line 394...
401
 
394
 
402
        pop     esi
-
 
403
        push    edx
395
        pop     esi
Line 404... Line 396...
404
        push    eax
396
        push    eax
405
 
397
 
406
        push    edi ecx
398
        push    edi ecx
Line 424... Line 416...
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