Subversion Repositories Kolibri OS

Rev

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

Rev 3908 Rev 4265
Line 16... Line 16...
16
;;                                                                 ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 18... Line 18...
18
 
18
 
Line 19... Line 19...
19
$Revision: 3515 $
19
$Revision: 3515 $
Line 20... Line 20...
20
 
20
 
Line 21... Line 21...
21
MAX_FRAGMENTS                   = 64
21
IPv4_MAX_FRAGMENTS              = 64
22
 
22
 
Line 33... Line 33...
33
        SourceAddress           dd ?
33
        SourceAddress           dd ?
34
        DestinationAddress      dd ?
34
        DestinationAddress      dd ?
Line 35... Line 35...
35
 
35
 
Line 36... Line 36...
36
ends
36
ends
Line 37... Line 37...
37
 
37
 
38
struct  FRAGMENT_slot
38
struct  IPv4_FRAGMENT_slot
39
 
39
 
40
        ttl                     dw ?    ; Time to live for this entry, 0 for empty slot's
40
        ttl                     dw ?    ; Time to live for this entry, 0 for empty slot's
41
        id                      dw ?    ; Identification field from IP header
41
        id                      dw ?    ; Identification field from IP header
Line 42... Line 42...
42
        SrcIP                   dd ?    ; .. from IP header
42
        SrcIP                   dd ?    ; .. from IP header
Line 43... Line 43...
43
        DstIP                   dd ?    ; .. from IP header
43
        DstIP                   dd ?    ; .. from IP header
Line 44... Line 44...
44
        ptr                     dd ?    ; Pointer to first packet
44
        ptr                     dd ?    ; Pointer to first packet
45
 
45
 
46
ends
46
ends
47
 
47
 
Line 62... Line 62...
62
        SUBNET_LIST             rd NET_DEVICES_MAX
62
        SUBNET_LIST             rd NET_DEVICES_MAX
63
        DNS_LIST                rd NET_DEVICES_MAX
63
        DNS_LIST                rd NET_DEVICES_MAX
64
        GATEWAY_LIST            rd NET_DEVICES_MAX
64
        GATEWAY_LIST            rd NET_DEVICES_MAX
65
        BROADCAST_LIST          rd NET_DEVICES_MAX
65
        BROADCAST_LIST          rd NET_DEVICES_MAX
Line 66... Line 66...
66
 
66
 
67
        IP_packets_tx           rd NET_DEVICES_MAX
67
        IPv4_packets_tx         rd NET_DEVICES_MAX
68
        IP_packets_rx           rd NET_DEVICES_MAX
68
        IPv4_packets_rx         rd NET_DEVICES_MAX
Line 69... Line 69...
69
        IP_packets_dumped       rd NET_DEVICES_MAX
69
        IPv4_packets_dumped     rd NET_DEVICES_MAX
Line 70... Line 70...
70
 
70
 
Line 71... Line 71...
71
        FRAGMENT_LIST           rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot
71
        IPv4_FRAGMENT_LIST      rb IPv4_MAX_FRAGMENTS * sizeof.IPv4_FRAGMENT_slot
Line 82... Line 82...
82
;-----------------------------------------------------------------
82
;-----------------------------------------------------------------
83
macro   IPv4_init {
83
macro   IPv4_init {
Line 84... Line 84...
84
 
84
 
85
        xor     eax, eax
85
        xor     eax, eax
86
        mov     edi, IP_LIST
86
        mov     edi, IP_LIST
87
        mov     ecx, 7*NET_DEVICES_MAX + (sizeof.FRAGMENT_slot*MAX_FRAGMENTS)/4
87
        mov     ecx, 7*NET_DEVICES_MAX + (sizeof.IPv4_FRAGMENT_slot*IPv4_MAX_FRAGMENTS)/4
Line 88... Line 88...
88
        rep stosd
88
        rep stosd
Line 97... Line 97...
97
;-----------------------------------------------------------------
97
;-----------------------------------------------------------------
98
macro IPv4_decrease_fragment_ttls {
98
macro IPv4_decrease_fragment_ttls {
Line 99... Line 99...
99
 
99
 
Line 100... Line 100...
100
local   .loop, .next
100
local   .loop, .next
101
 
101
 
102
        mov     esi, FRAGMENT_LIST
102
        mov     esi, IPv4_FRAGMENT_LIST
103
        mov     ecx, MAX_FRAGMENTS
103
        mov     ecx, IPv4_MAX_FRAGMENTS
104
  .loop:
104
  .loop:
105
        cmp     [esi + FRAGMENT_slot.ttl], 0
105
        cmp     [esi + IPv4_FRAGMENT_slot.ttl], 0
106
        je      .next
106
        je      .next
107
        dec     [esi + FRAGMENT_slot.ttl]
107
        dec     [esi + IPv4_FRAGMENT_slot.ttl]
108
        jz      .died
108
        jz      .died
109
  .next:
109
  .next:
110
        add     esi, sizeof.FRAGMENT_slot
110
        add     esi, sizeof.IPv4_FRAGMENT_slot
111
        dec     ecx
111
        dec     ecx
Line 112... Line 112...
112
        jnz     .loop
112
        jnz     .loop
Line 261... Line 261...
261
 
261
 
262
;------------------------
262
;------------------------
Line 263... Line 263...
263
; Now we can update stats
263
; Now we can update stats
264
 
264
 
Line 265... Line 265...
265
  .ip_ok:
265
  .ip_ok:
266
        inc     [IP_packets_rx + edi]
266
        inc     [IPv4_packets_rx + edi]
Line 267... Line 267...
267
 
267
 
Line 302... Line 302...
302
 
302
 
Line 303... Line 303...
303
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: unknown protocol %u\n", al
303
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: unknown protocol %u\n", al
304
 
304
 
305
  .dump:
305
  .dump:
306
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n"
306
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n"
307
        inc     [IP_packets_dumped]                             ; FIXME: use correct interface
307
        inc     [IPv4_packets_dumped]                           ; FIXME: use correct interface
308
        call    NET_packet_free
308
        call    NET_packet_free
Line 317... Line 317...
317
  .has_fragments:
317
  .has_fragments:
318
        movzx   eax, [edx + IPv4_header.FlagsAndFragmentOffset]
318
        movzx   eax, [edx + IPv4_header.FlagsAndFragmentOffset]
319
        xchg    al, ah
319
        xchg    al, ah
320
        shl     ax, 3
320
        shl     ax, 3
Line 321... Line 321...
321
 
321
 
Line 322... Line 322...
322
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: fragmented packet offset=%u id=%x\n", ax, [edx + IPv4_header.Identification]:4
322
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: fragmented packet offset=%u id=%x ptr=0x%x\n", ax, [edx + IPv4_header.Identification]:4, edx
323
 
323
 
Line 332... Line 332...
332
 
332
 
333
        call    IPv4_find_fragment_slot
333
        call    IPv4_find_fragment_slot
334
        cmp     esi, -1
334
        cmp     esi, -1
Line 335... Line 335...
335
        je      .dump
335
        je      .dump
336
 
336
 
337
        mov     [esi + FRAGMENT_slot.ttl], 15                   ; Reset the ttl
337
        mov     [esi + IPv4_FRAGMENT_slot.ttl], 15              ; Reset the ttl
338
        mov     esi, [esi + FRAGMENT_slot.ptr]
338
        mov     esi, [esi + IPv4_FRAGMENT_slot.ptr]
339
        or      edi, -1
339
        or      edi, -1
340
  .find_last_entry:                                             ; The following routine will try to find the last entry
340
  .find_last_entry:                                             ; The following routine will try to find the last entry
341
        cmp     edi, [esi + FRAGMENT_entry.PrevPtr]
341
        cmp     edi, [esi + IPv4_FRAGMENT_entry.PrevPtr]
342
        jne     .destroy_slot                                   ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
342
        jne     .destroy_slot                                   ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
343
        mov     edi, esi
343
        mov     edi, esi
344
        mov     esi, [esi + FRAGMENT_entry.NextPtr]
344
        mov     esi, [esi + IPv4_FRAGMENT_entry.NextPtr]
345
        cmp     esi, -1
345
        cmp     esi, -1
346
        jne     .find_last_entry
346
        jne     .find_last_entry
Line 347... Line 347...
347
                                                                ; We found the last entry (pointer is now in edi)
347
                                                                ; We found the last entry (pointer is now in edi)
348
                                                                ; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure
348
                                                                ; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure
349
 
349
 
350
        pop     eax                                             ; pointer to packet
350
        pop     eax                                             ; pointer to packet
351
        mov     [edi + FRAGMENT_entry.NextPtr], eax             ; update pointer of previous entry to the new entry
351
        mov     [edi + IPv4_FRAGMENT_entry.NextPtr], eax        ; update pointer of previous entry to the new entry
Line 352... Line 352...
352
        mov     [eax + FRAGMENT_entry.NextPtr], -1
352
        mov     [eax + IPv4_FRAGMENT_entry.NextPtr], -1
353
        mov     [eax + FRAGMENT_entry.PrevPtr], edi
353
        mov     [eax + IPv4_FRAGMENT_entry.PrevPtr], edi
Line 361... Line 361...
361
; We have received the first fragment
361
; We have received the first fragment
Line 362... Line 362...
362
 
362
 
363
  .is_first_fragment:
363
  .is_first_fragment:
364
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: First fragment packet received!\n"
364
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: First fragment packet received!\n"
365
                                                                ; try to locate a free slot..
365
                                                                ; try to locate a free slot..
366
        mov     ecx, MAX_FRAGMENTS
366
        mov     ecx, IPv4_MAX_FRAGMENTS
367
        mov     esi, FRAGMENT_LIST
367
        mov     esi, IPv4_FRAGMENT_LIST
368
  .find_free_slot:
368
  .find_free_slot:
369
        cmp     word [esi + FRAGMENT_slot.ttl], 0
369
        cmp     word [esi + IPv4_FRAGMENT_slot.ttl], 0
370
        je      .found_free_slot
370
        je      .found_free_slot
371
        add     esi, sizeof.FRAGMENT_slot
371
        add     esi, sizeof.IPv4_FRAGMENT_slot
372
        loop    .find_free_slot
372
        loop    .find_free_slot
Line 373... Line 373...
373
        jmp     .dump                                           ; If no free slot was found, dump the packet
373
        jmp     .dump                                           ; If no free slot was found, dump the packet
374
 
374
 
375
  .found_free_slot:                                             ; We found a free slot, let's fill in the FRAGMENT_slot structure
375
  .found_free_slot:                                             ; We found a free slot, let's fill in the FRAGMENT_slot structure
376
        mov     [esi + FRAGMENT_slot.ttl], 15                   ; RFC recommends 15 secs as ttl
376
        mov     [esi + IPv4_FRAGMENT_slot.ttl], 15              ; RFC recommends 15 secs as ttl
377
        mov     ax, [edx + IPv4_header.Identification]
377
        mov     ax, [edx + IPv4_header.Identification]
378
        mov     [esi + FRAGMENT_slot.id], ax
378
        mov     [esi + IPv4_FRAGMENT_slot.id], ax
379
        mov     eax, [edx + IPv4_header.SourceAddress]
379
        mov     eax, [edx + IPv4_header.SourceAddress]
380
        mov     [esi + FRAGMENT_slot.SrcIP], eax
380
        mov     [esi + IPv4_FRAGMENT_slot.SrcIP], eax
381
        mov     eax, [edx + IPv4_header.DestinationAddress]
381
        mov     eax, [edx + IPv4_header.DestinationAddress]
382
        mov     [esi + FRAGMENT_slot.DstIP], eax
382
        mov     [esi + IPv4_FRAGMENT_slot.DstIP], eax
383
        pop     eax
383
        pop     eax
384
        mov     [esi + FRAGMENT_slot.ptr], eax
384
        mov     [esi + IPv4_FRAGMENT_slot.ptr], eax
385
                                                                ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure
385
                                                                ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure
386
        mov     [eax + FRAGMENT_entry.NextPtr], -1
386
        mov     [eax + IPv4_FRAGMENT_entry.NextPtr], -1
Line 387... Line 387...
387
        mov     [eax + FRAGMENT_entry.PrevPtr], -1
387
        mov     [eax + IPv4_FRAGMENT_entry.PrevPtr], -1
388
        mov     [eax + FRAGMENT_entry.Owner], ebx
388
        mov     [eax + IPv4_FRAGMENT_entry.Owner], ebx
Line 399... Line 399...
399
 
399
 
400
        call    IPv4_find_fragment_slot
400
        call    IPv4_find_fragment_slot
401
        cmp     esi, -1
401
        cmp     esi, -1
Line 402... Line 402...
402
        je      .dump
402
        je      .dump
403
 
403
 
404
        mov     esi, [esi + FRAGMENT_slot.ptr]                  ; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer
404
        mov     esi, [esi + IPv4_FRAGMENT_slot.ptr]                     ; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer
405
        push    esi
405
        push    esi
Line 406... Line 406...
406
        xor     eax, eax
406
        xor     eax, eax
407
        or      edi, -1
407
        or      edi, -1
408
 
408
 
409
  .count_bytes:
409
  .count_bytes:
410
        cmp     [esi + FRAGMENT_entry.PrevPtr], edi
410
        cmp     [esi + IPv4_FRAGMENT_entry.PrevPtr], edi
411
        jne     .destroy_slot_pop                                               ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
411
        jne     .destroy_slot_pop                                                       ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
412
        mov     cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.TotalLength]     ; Add total length
412
        mov     cx, [esi + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength]        ; Add total length
413
        xchg    cl, ch
413
        xchg    cl, ch
414
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx
414
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx
415
        add     ax, cx
415
        add     ax, cx
416
        movzx   cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL]   ; Sub Header length
416
        movzx   cx, [esi + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL]      ; Sub Header length
417
        and     cx, 0x000F
417
        and     cx, 0x000F
418
        shl     cx, 2
418
        shl     cx, 2
419
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: Header size=%u\n", cx
419
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: Header size=%u\n", cx
420
        sub     ax, cx
420
        sub     ax, cx
421
        mov     edi, esi
421
        mov     edi, esi
Line 422... Line 422...
422
        mov     esi, [esi + FRAGMENT_entry.NextPtr]
422
        mov     esi, [esi + IPv4_FRAGMENT_entry.NextPtr]
423
        cmp     esi, -1
423
        cmp     esi, -1
424
        jne     .count_bytes
424
        jne     .count_bytes
425
 
425
 
426
        mov     esi, [esp+4]
426
        mov     esi, [esp+4]
Line 427... Line 427...
427
        mov     [edi + FRAGMENT_entry.NextPtr], esi                             ; Add this packet to the chain, this simplifies the following code
427
        mov     [edi + IPv4_FRAGMENT_entry.NextPtr], esi                                ; Add this packet to the chain, this simplifies the following code
428
        mov     [esi + FRAGMENT_entry.NextPtr], -1
428
        mov     [esi + IPv4_FRAGMENT_entry.NextPtr], -1
429
        mov     [esi + FRAGMENT_entry.PrevPtr], edi
429
        mov     [esi + IPv4_FRAGMENT_entry.PrevPtr], edi
430
        mov     [esi + FRAGMENT_entry.Owner], ebx
430
        mov     [esi + IPv4_FRAGMENT_entry.Owner], ebx
Line 452... Line 452...
452
        test    eax, eax
452
        test    eax, eax
453
        je      .destroy_slot_pop                                                       ; If we dont have enough space to allocate the buffer, discard all packets in slot
453
        je      .destroy_slot_pop                                                       ; If we dont have enough space to allocate the buffer, discard all packets in slot
454
        mov     edx, [esp+4]                                                            ; Get pointer to first fragment entry back in edx
454
        mov     edx, [esp+4]                                                            ; Get pointer to first fragment entry back in edx
Line 455... Line 455...
455
 
455
 
456
  .rebuild_packet_loop:
456
  .rebuild_packet_loop:
457
        movzx   ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset
457
        movzx   ecx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset
458
        xchg    cl, ch                                                                  ;  intel byte order
458
        xchg    cl, ch                                                                  ;  intel byte order
459
        shl     cx, 3                                                                   ;   multiply by 8 and clear first 3 bits
459
        shl     cx, 3                                                                   ;   multiply by 8 and clear first 3 bits
Line 460... Line 460...
460
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: Fragment offset=%u\n", cx
460
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: Fragment offset=%u\n", cx
461
 
461
 
462
        lea     edi, [eax + ecx]                                                        ; Notice that edi will be equal to eax for first fragment
462
        lea     edi, [eax + ecx]                                                        ; Notice that edi will be equal to eax for first fragment
463
        movzx   ebx, [edx + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL]          ; Find header size (in ebx) of fragment
463
        movzx   ebx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL]     ; Find header size (in ebx) of fragment
Line 464... Line 464...
464
        and     bx, 0x000F                                                              ;
464
        and     bx, 0x000F                                                              ;
465
        shl     bx, 2                                                                   ;
465
        shl     bx, 2                                                                   ;
466
 
466
 
Line 467... Line 467...
467
        lea     esi, [edx + sizeof.FRAGMENT_entry]                                      ; Set esi to the correct begin of fragment
467
        lea     esi, [edx + sizeof.IPv4_FRAGMENT_entry]                                 ; Set esi to the correct begin of fragment
468
        movzx   ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.TotalLength]            ; Calculate total length of fragment
468
        movzx   ecx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength]       ; Calculate total length of fragment
469
        xchg    cl, ch                                                                  ;  intel byte order
469
        xchg    cl, ch                                                                  ;  intel byte order
470
 
470
 
471
        cmp     edi, eax                                                                ; Is this packet the first fragment ?
471
        cmp     edi, eax                                                                ; Is this packet the first fragment ?
Line -... Line 472...
-
 
472
        je      .first_fragment
-
 
473
        sub     cx, bx                                                                  ; If not, dont copy the header
472
        je      .first_fragment
474
        add     esi, ebx                                                                ;
473
        sub     cx, bx                                                                  ; If not, dont copy the header
475
  .first_fragment:
474
        add     esi, ebx                                                                ;
476
 
475
  .first_fragment:
477
 
476
 
478
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: Copying %u bytes from 0x%x to 0x%x\n", ecx, esi, edi
477
        push    cx                                                                      ; First copy dword-wise, then byte-wise
479
        push    cx                                                                      ; First copy dword-wise, then byte-wise
Line 478... Line 480...
478
        shr     cx, 2                                                                   ;
480
        shr     cx, 2                                                                   ;
-
 
481
        rep movsd                                                                       ;
-
 
482
        pop     cx                                                                      ;
479
        rep movsd                                                                       ;
483
        and     cx, 3                                                                   ;
480
        pop     cx                                                                      ;
-
 
481
        and     cx, 3                                                                   ;
484
        rep movsb                                                                       ;
482
        rep movsb                                                                       ;
485
 
483
 
486
        push    eax
484
        push    eax
487
        push    [edx + IPv4_FRAGMENT_entry.Owner]                                       ; we need to remeber the owner, in case this is the last packet
485
        push    edx                                                                     ; Push pointer to fragment onto stack
488
        push    [edx + IPv4_FRAGMENT_entry.NextPtr]                                     ; Set edx to the next pointer
Line 486... Line 489...
486
        mov     ebx, [edx + FRAGMENT_entry.Owner]                                       ; we need to remeber the owner, in case this is the last packet
489
        push    edx                                                                     ; Push pointer to fragment onto stack
487
        mov     edx, [edx + FRAGMENT_entry.NextPtr]                                     ; Set edx to the next pointer
490
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: Next Fragment: 0x%x\n", edx
488
        call    NET_packet_free                                                         ; free the previous fragment buffer (this uses the value from stack)
491
        call    NET_packet_free                                                         ; free the previous fragment buffer (this uses the value from stack)
489
        pop     eax
492
        pop     edx ebx eax
490
        cmp     edx, -1                                                                 ; Check if it is last fragment in chain
493
        cmp     edx, -1                                                                 ; Check if it is last fragment in chain
491
        jne     .rebuild_packet_loop
494
        jne     .rebuild_packet_loop
492
 
495
 
493
        pop     ecx
-
 
494
        xchg    cl, ch
-
 
495
        mov     edx, eax
496
        pop     ecx
Line 496... Line 497...
496
        mov     [edx + IPv4_header.TotalLength], cx
497
        xchg    cl, ch
497
        add     esp, 8
498
        mov     edx, eax
498
        xchg    cl, ch
499
        mov     [edx + IPv4_header.TotalLength], cx
Line 525... Line 526...
525
 
526
 
Line 526... Line 527...
526
;;; TODO: the RFC says we should check protocol number too
527
;;; TODO: the RFC says we should check protocol number too
527
 
528
 
528
        push    eax ebx ecx edx
529
        push    eax ebx ecx edx
529
        mov     ax, [edx + IPv4_header.Identification]
530
        mov     ax, [edx + IPv4_header.Identification]
530
        mov     ecx, MAX_FRAGMENTS
531
        mov     ecx, IPv4_MAX_FRAGMENTS
531
        mov     esi, FRAGMENT_LIST
532
        mov     esi, IPv4_FRAGMENT_LIST
532
        mov     ebx, [edx + IPv4_header.SourceAddress]
533
        mov     ebx, [edx + IPv4_header.SourceAddress]
533
        mov     edx, [edx + IPv4_header.DestinationAddress]
534
        mov     edx, [edx + IPv4_header.DestinationAddress]
534
  .find_slot:
535
  .find_slot:
535
        cmp     [esi + FRAGMENT_slot.id], ax
536
        cmp     [esi + IPv4_FRAGMENT_slot.id], ax
536
        jne     .try_next
537
        jne     .try_next
537
        cmp     [esi + FRAGMENT_slot.SrcIP], ebx
538
        cmp     [esi + IPv4_FRAGMENT_slot.SrcIP], ebx
538
        jne     .try_next
539
        jne     .try_next
539
        cmp     [esi + FRAGMENT_slot.DstIP], edx
540
        cmp     [esi + IPv4_FRAGMENT_slot.DstIP], edx
540
        je      .found_slot
541
        je      .found_slot
541
  .try_next:
542
  .try_next:
Line 542... Line 543...
542
        add     esi, sizeof.FRAGMENT_slot
543
        add     esi, sizeof.IPv4_FRAGMENT_slot
543
        loop    .find_slot
544
        loop    .find_slot
544
 
545
 
Line 550... Line 551...
550
 
551
 
551
;------------------------------------------------------------------
552
;------------------------------------------------------------------
552
;
553
;
553
; IPv4_output
554
; IPv4_output
554
;
555
;
555
; IN: eax = dest ip
-
 
556
;     ebx = output device ptr/0 for automatic choice
556
; IN:   eax = Destination IP
557
;     ecx = data length
557
;       ecx = data length
558
;     edx = source ip
558
;       edx = Source IP
559
;     di  = TTL shl 8 + protocol
559
;       di  = TTL shl 8 + protocol
560
;
560
;
561
; OUT: eax = pointer to buffer start
561
; OUT:  eax = pointer to buffer start
562
;      ebx = pointer to device struct (needed for sending procedure)
562
;       ebx = pointer to device struct (needed for sending procedure)
Line 571... Line 571...
571
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_output: size=%u ip=0x%x\n", ecx, eax
571
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_output: size=%u ip=0x%x\n", ecx, eax
Line 572... Line 572...
572
 
572
 
573
        cmp     ecx, 65500              ; Max IPv4 packet size
573
        cmp     ecx, 65500              ; Max IPv4 packet size
Line 574... Line 574...
574
        ja      .too_large
574
        ja      .too_large
575
 
-
 
576
        push    ecx eax edx di
575
 
-
 
576
        push    ecx di eax
Line 577... Line 577...
577
 
577
        call    IPv4_route              ; outputs device number in edi, dest ip in eax, source IP in edx
578
        call    IPv4_route              ; outputs device number in edi, dest ip in eax
578
        push    edx
Line 579... Line 579...
579
 
579
 
580
        test    edi, edi
580
        test    edi, edi
581
        jz      .loopback
581
        jz      .loopback
582
 
582
 
583
        call    ARP_IP_to_MAC
583
        call    ARP_IP_to_MAC
Line 584... Line 584...
584
        test    eax, 0xffff0000         ; error bits
584
        test    eax, 0xffff0000         ; error bits
Line 585... Line 585...
585
        jnz     .arp_error
585
        jnz     .arp_error
586
        push    ebx                     ; push the mac onto the stack
586
        push    ebx                     ; push the mac onto the stack
587
        push    ax
587
        push    ax
588
 
588
 
589
        inc     [IP_packets_tx + edi]   ; update stats
589
        inc     [IPv4_packets_tx + edi]   ; update stats
590
 
590
 
591
        mov     ebx, [NET_DRV_LIST + edi]
591
        mov     ebx, [NET_DRV_LIST + edi]
592
        lea     eax, [ebx + ETH_DEVICE.mac]
592
        lea     eax, [ebx + ETH_DEVICE.mac]
593
        mov     edx, esp
593
        mov     edx, esp
Line 603... Line 603...
603
        mov     [edi + IPv4_header.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header)
603
        mov     [edi + IPv4_header.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header)
604
        mov     [edi + IPv4_header.TypeOfService], 0    ; nothing special, just plain ip packet
604
        mov     [edi + IPv4_header.TypeOfService], 0    ; nothing special, just plain ip packet
605
        mov     [edi + IPv4_header.TotalLength], cx
605
        mov     [edi + IPv4_header.TotalLength], cx
606
        mov     [edi + IPv4_header.Identification], 0   ; fragment id: FIXME
606
        mov     [edi + IPv4_header.Identification], 0   ; fragment id: FIXME
607
        mov     [edi + IPv4_header.FlagsAndFragmentOffset], 0
607
        mov     [edi + IPv4_header.FlagsAndFragmentOffset], 0
608
        pop     word [edi + IPv4_header.TimeToLive]     ; ttl shl 8 + protocol
-
 
609
;               [edi + IPv4_header.Protocol]
-
 
-
 
608
 
610
        mov     [edi + IPv4_header.HeaderChecksum], 0
609
        mov     [edi + IPv4_header.HeaderChecksum], 0
611
        popd    [edi + IPv4_header.SourceAddress]
610
        popd    [edi + IPv4_header.SourceAddress]
612
        popd    [edi + IPv4_header.DestinationAddress]
611
        popd    [edi + IPv4_header.DestinationAddress]
Line -... Line 612...
-
 
612
 
-
 
613
        pop     word[edi + IPv4_header.TimeToLive]      ; ttl shl 8 + protocol
-
 
614
;               [edi + IPv4_header.Protocol]
613
 
615
 
Line 614... Line 616...
614
        pop     ecx
616
        pop     ecx
615
 
617
 
616
        IPv4_checksum edi
618
        IPv4_checksum edi
Line 675... Line 677...
675
        jnz     .arp_error
677
        jnz     .arp_error
Line 676... Line 678...
676
 
678
 
677
        push    ebx                     ; push the mac
679
        push    ebx                     ; push the mac
Line 678... Line 680...
678
        push    ax
680
        push    ax
679
 
681
 
680
        inc     [IP_packets_tx + 4*edi]
682
        inc     [IPv4_packets_tx + 4*edi]
681
        mov     ebx, [NET_DRV_LIST + 4*edi]
683
        mov     ebx, [NET_DRV_LIST + 4*edi]
682
        lea     eax, [ebx + ETH_DEVICE.mac]
684
        lea     eax, [ebx + ETH_DEVICE.mac]
683
        mov     edx, esp
685
        mov     edx, esp
Line 855... Line 857...
855
;---------------------------------------------------------------------------
857
;---------------------------------------------------------------------------
856
;
858
;
857
; IPv4_route
859
; IPv4_route
858
;
860
;
859
; IN:   eax = Destination IP
861
; IN:   eax = Destination IP
860
; OUT:  edi = device number*4
862
;       edx = Source IP
861
;       eax = ip of gateway if nescessary, unchanged otherwise
863
; OUT:  eax = Destination IP (or gateway IP)
-
 
864
;       edx = Source IP
-
 
865
;       edi = device number*4
-
 
866
; DESTROYED:
-
 
867
;       ecx
862
;
868
;
863
;---------------------------------------------------------------------------
869
;---------------------------------------------------------------------------
864
align 4
870
align 4
865
IPv4_route:
871
IPv4_route:     ; TODO: return error if no valid route found
Line 866... Line 872...
866
 
872
 
867
        cmp     eax, 0xffffffff
873
        cmp     eax, 0xffffffff
Line 868... Line 874...
868
        je      .broadcast
874
        je      .broadcast
869
 
-
 
870
        xor     edi, edi
875
 
871
        mov     ecx, NET_DEVICES_MAX
876
        xor     edi, edi
872
  .loop:
877
  .loop:
873
        mov     ebx, [IP_LIST+edi]
878
        mov     ebx, [IP_LIST + edi]
874
        and     ebx, [SUBNET_LIST+edi]
879
        and     ebx, [SUBNET_LIST + edi]
875
        jz      .next
880
        jz      .next
876
        mov     edx, eax
-
 
877
        and     edx, [SUBNET_LIST+edi]
881
        mov     ecx, eax
878
 
882
        and     ecx, [SUBNET_LIST + edi]
879
        cmp     ebx, edx
-
 
880
        jne     .next
-
 
881
 
-
 
882
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi
-
 
883
        ret
883
        cmp     ebx, ecx
884
 
884
        je      .got_it
885
  .next:
885
  .next:
886
        add     edi, 4
886
        add     edi, 4
Line 887... Line -...
887
        dec     ecx
-
 
888
        jnz     .loop
887
        cmp     edi, 4*NET_DEVICES_MAX
889
 
888
        jb      .loop
890
  .invalid:
889
 
-
 
890
        mov     eax, [GATEWAY_LIST + 4]         ; TODO: let user (or a user space daemon) configure default route
-
 
891
  .broadcast:
-
 
892
        mov     edi, 4                          ; TODO: same as above
-
 
893
  .got_it:
-
 
894
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi
-
 
895
        test    edx, edx
-
 
896
        jnz     @f
891
        mov     eax, [GATEWAY_LIST+4]       ;;; FIXME
897
        mov     edx, [IP_LIST + edi]
Line 892... Line 898...
892
  .broadcast:
898
  @@:
Line 908... Line 914...
908
        xor     ax, ax  ;;; TODO: replace this with real code
914
        xor     ax, ax  ;;; TODO: replace this with real code
Line 909... Line 915...
909
 
915
 
Line -... Line 916...
-
 
916
        ret
-
 
917
 
-
 
918
 
-
 
919
;-----------------------------------------------------------------
-
 
920
;
-
 
921
; IPv4_connect
-
 
922
;
-
 
923
;   IN: eax = socket pointer
-
 
924
;  OUT: eax = 0 ok / -1 error
-
 
925
;       ebx = error code
-
 
926
;
-
 
927
;-------------------------
-
 
928
align 4
-
 
929
IPv4_connect:
-
 
930
 
-
 
931
        push    eax edx
-
 
932
        lea     ecx, [eax + SOCKET.mutex]
-
 
933
        call    mutex_lock
-
 
934
        pop     edx eax
-
 
935
 
-
 
936
; Fill in local IP
-
 
937
        cmp     [eax + IP_SOCKET.LocalIP], 0
-
 
938
        jne     @f
-
 
939
        push    [IP_LIST + 4]                                   ; FIXME: use correct local IP
-
 
940
        pop     [eax + IP_SOCKET.LocalIP]
-
 
941
 
-
 
942
; Fill in remote IP
-
 
943
        pushd   [edx + 4]
-
 
944
        pop     [eax + IP_SOCKET.RemoteIP]
-
 
945
 
-
 
946
; Set up data receiving queue
-
 
947
        push    eax
-
 
948
        init_queue (eax + SOCKET_QUEUE_LOCATION)
-
 
949
        pop     eax
-
 
950
 
-
 
951
        lea     ecx, [eax + SOCKET.mutex]
-
 
952
        call    mutex_unlock
-
 
953
 
-
 
954
        xor     eax, eax
910
        ret
955
        ret
911
 
956
 
912
 
957
 
913
;---------------------------------------------------------------------------
958
;---------------------------------------------------------------------------
914
;
959
;
Line 950... Line 995...
950
  .error:
995
  .error:
951
        mov     eax, -1
996
        mov     eax, -1
952
        ret
997
        ret
Line 953... Line 998...
953
 
998
 
954
  .packets_tx:
999
  .packets_tx:
955
        mov     eax, [IP_packets_tx + eax]
1000
        mov     eax, [IPv4_packets_tx + eax]
Line 956... Line 1001...
956
        ret
1001
        ret
957
 
1002
 
958
  .packets_rx:
1003
  .packets_rx:
Line 959... Line 1004...
959
        mov     eax, [IP_packets_rx + eax]
1004
        mov     eax, [IPv4_packets_rx + eax]
960
        ret
1005
        ret
961
 
1006