Subversion Repositories Kolibri OS

Rev

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

Rev 5584 Rev 5842
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: 5584 $
19
$Revision: 5842 $
20
 
20
 
Line 21... Line 21...
21
IPv4_MAX_FRAGMENTS              = 64
21
IPv4_MAX_FRAGMENTS              = 64
Line 213... Line 213...
213
;  and call appropriate handler. (TCP/UDP/ICMP/..)
213
;  and call appropriate handler. (TCP/UDP/ICMP/..)
214
;
214
;
215
;  It will also re-construct fragmented packets
215
;  It will also re-construct fragmented packets
216
;
216
;
217
;  IN:  Pointer to buffer in [esp]
217
;  IN:  Pointer to buffer in [esp]
218
;       size of buffer in [esp+4]
-
 
219
;       pointer to device struct in ebx
218
;       pointer to device struct in ebx
220
;       pointer to IPv4 header in edx
219
;       pointer to IPv4 header in edx
221
;       size of IPv4 packet in ecx
220
;       size of IPv4 packet in ecx
222
;  OUT: /
221
;  OUT: /
223
;
222
;
224
;-----------------------------------------------------------------
223
;-----------------------------------------------------------------
225
align 4
224
align 4
226
IPv4_input:                                                     ; TODO: add IPv4 raw sockets support
225
IPv4_input:
Line 227... Line 226...
227
 
226
 
228
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: packet from %u.%u.%u.%u ",\
227
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: packet from %u.%u.%u.%u ",\
229
        [edx + IPv4_header.SourceAddress + 0]:1,[edx + IPv4_header.SourceAddress + 1]:1,\
228
        [edx + IPv4_header.SourceAddress + 0]:1,[edx + IPv4_header.SourceAddress + 1]:1,\
230
        [edx + IPv4_header.SourceAddress + 2]:1,[edx + IPv4_header.SourceAddress + 3]:1
229
        [edx + IPv4_header.SourceAddress + 2]:1,[edx + IPv4_header.SourceAddress + 3]:1
231
        DEBUGF  DEBUG_NETWORK_VERBOSE, "to %u.%u.%u.%u\n",\
230
        DEBUGF  DEBUG_NETWORK_VERBOSE, "to %u.%u.%u.%u\n",\
232
        [edx + IPv4_header.DestinationAddress + 0]:1,[edx + IPv4_header.DestinationAddress + 1]:1,\
231
        [edx + IPv4_header.DestinationAddress + 0]:1,[edx + IPv4_header.DestinationAddress + 1]:1,\
Line -... Line 232...
-
 
232
        [edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1
-
 
233
 
-
 
234
        call    NET_ptr_to_num4
-
 
235
        cmp     edi, -1
233
        [edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1
236
        je      .invalid_device
234
 
237
 
Line 235... Line 238...
235
;-------------------------------
238
;-------------------------------
236
; re-calculate the checksum
239
; re-calculate the checksum
Line 237... Line 240...
237
 
240
 
Line 238... Line 241...
238
        IPv4_checksum edx
241
        IPv4_checksum edx
239
        jnz     .dump                                           ; if checksum isn't valid then dump packet
242
        jnz     .dump                                           ; if checksum isn't valid then dump packet
240
 
-
 
241
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: Checksum ok\n"
-
 
242
 
-
 
243
;-----------------------------------
-
 
Line -... Line 243...
-
 
243
 
244
; Check if destination IP is correct
244
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: Checksum ok\n"
245
 
245
 
246
        call    NET_ptr_to_num4
246
;--------------------------------
Line 247... Line 247...
247
 
247
; Check if destination IP matches
248
        ; check if it matches local ip (Using RFC1122 strong end system model)
-
 
249
 
248
 
250
        mov     eax, [edx + IPv4_header.DestinationAddress]
249
; local ip (Using RFC1122 strong end system model)
Line 251... Line 250...
251
        cmp     eax, [IP_LIST + edi]
250
        mov     eax, [edx + IPv4_header.DestinationAddress]
252
        je      .ip_ok
-
 
253
 
251
        cmp     eax, [IP_LIST + edi]
254
        ; check for broadcast (IP or (not SUBNET))
252
        je      .ip_ok
Line 255... Line 253...
255
 
253
 
256
        cmp     eax, [BROADCAST_LIST + edi]
-
 
257
        je      .ip_ok
254
; network layer broadcast
258
 
255
        cmp     eax, [BROADCAST_LIST + edi]
259
        ; or a special broadcast (255.255.255.255)
256
        je      .ip_ok
Line 260... Line 257...
260
 
257
 
261
        cmp     eax, 0xffffffff
-
 
262
        je      .ip_ok
258
; physical layer broadcast (255.255.255.255)
263
 
259
        cmp     eax, 0xffffffff
Line 264... Line 260...
264
        ; maybe it's a multicast (224.0.0.0/4)
260
        je      .ip_ok
265
 
-
 
266
        and     eax, 0x0fffffff
261
 
267
        cmp     eax, 224
262
; multicast (224.0.0.0/4 = 224.0.0.0 to 239.255.255.255)
Line 268... Line 263...
268
        je      .ip_ok
263
        and     eax, 0x0fffffff
269
 
264
        cmp     eax, 224
Line 303... Line 298...
303
 
298
 
304
        movzx   ecx, [edx + IPv4_header.TotalLength]            ; Calculate length of encapsulated Packet
299
        movzx   ecx, [edx + IPv4_header.TotalLength]            ; Calculate length of encapsulated Packet
305
        xchg    cl, ch                                          ;
300
        xchg    cl, ch                                          ;
Line 306... Line -...
306
        sub     ecx, esi                                        ;
-
 
307
 
301
        sub     ecx, esi                                        ;
308
        lea     edi, [edx + IPv4_header.SourceAddress]          ; make edi ptr to source and dest IPv4 address
302
 
Line 309... Line 303...
309
        mov     al, [edx + IPv4_header.Protocol]
303
        mov     al, [edx + IPv4_header.Protocol]
310
        add     esi, edx                                        ; make esi ptr to data
304
        add     esi, edx                                        ; make esi ptr to data
Line 316... Line 310...
316
        je      UDP_input
310
        je      UDP_input
Line 317... Line 311...
317
 
311
 
318
        cmp     al, IP_PROTO_ICMP
312
        cmp     al, IP_PROTO_ICMP
Line -... Line 313...
-
 
313
        je      ICMP_input
-
 
314
 
-
 
315
;-------------------------------
-
 
316
; Look for a matching RAW socket
-
 
317
        pusha
-
 
318
        mov     ecx, socket_mutex
-
 
319
        call    mutex_lock
-
 
320
        popa
-
 
321
 
-
 
322
        add     ecx, esi
-
 
323
        sub     ecx, edx
-
 
324
        mov     esi, edx
-
 
325
        movzx   edx, al
-
 
326
        mov     eax, net_sockets
-
 
327
  .next_socket:
-
 
328
        mov     eax, [eax + SOCKET.NextPtr]
-
 
329
        or      eax, eax
-
 
330
        jz      .dump_unlock
-
 
331
 
-
 
332
        cmp     [eax + SOCKET.Domain], AF_INET4
-
 
333
        jne     .next_socket
-
 
334
 
-
 
335
        cmp     [eax + SOCKET.Protocol], edx
-
 
336
        jne     .next_socket
-
 
337
 
-
 
338
        pusha
-
 
339
        mov     ecx, socket_mutex
-
 
340
        call    mutex_unlock
-
 
341
        popa
-
 
342
 
-
 
343
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: found matching RAW socket: 0x%x\n", eax
-
 
344
 
-
 
345
        pusha
-
 
346
        lea     ecx, [eax + SOCKET.mutex]
-
 
347
        call    mutex_lock
-
 
348
        popa
-
 
349
 
-
 
350
        jmp     SOCKET_input
-
 
351
 
-
 
352
  .dump_unlock:
-
 
353
 
-
 
354
        pusha
-
 
355
        mov     ecx, socket_mutex
-
 
356
        call    mutex_unlock
319
        je      ICMP_input
357
        popa
Line 320... Line 358...
320
 
358
 
321
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: unknown protocol %u\n", al
359
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: unknown protocol %u\n", al
322
 
360
 
-
 
361
  .dump:
-
 
362
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n"
-
 
363
        inc     [IPv4_packets_dumped + edi]
-
 
364
        call    NET_BUFF_free
-
 
365
        ret
323
  .dump:
366
 
324
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n"
367
  .invalid_device:
Line 325... Line 368...
325
        inc     [IPv4_packets_dumped]                           ; FIXME: use correct interface
368
        DEBUGF  DEBUG_NETWORK_ERROR, "IPv4_input: packet originated from invalid device\n"
Line 566... Line 609...
566
 
609
 
567
;------------------------------------------------------------------
610
;------------------------------------------------------------------
568
;
611
;
569
; IPv4_output
612
; IPv4_output
570
;
613
;
-
 
614
; IN:    al = protocol
571
; IN:   eax = Destination IP
615
;        ah = TTL
572
;       ebx = device ptr (or 0 to let IP layer decide)
616
;       ebx = device ptr (or 0 to let IP layer decide)
573
;       ecx = data length
617
;       ecx = data length
574
;       edx = Source IP
618
;       edx = Source IP
575
;        di = TTL shl 8 + protocol
619
;       edi = Destination IP
576
;
620
;
577
; OUT:  eax = pointer to buffer start / 0 on error
621
; OUT:  eax = pointer to buffer start / 0 on error
578
;       ebx = device ptr (send packet through this device)
622
;       ebx = device ptr (send packet through this device)
579
;       ecx = data length
623
;       ecx = data length
Line 587... Line 631...
587
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_output: size=%u ip=0x%x\n", ecx, eax
631
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_output: size=%u ip=0x%x\n", ecx, eax
Line 588... Line 632...
588
 
632
 
589
        cmp     ecx, 65500              ; Max IPv4 packet size
633
        cmp     ecx, 65500              ; Max IPv4 packet size
Line 590... Line 634...
590
        ja      .too_large
634
        ja      .too_large
-
 
635
 
591
 
636
        push    ecx ax edi
592
        push    ecx di eax
637
        mov     eax, edi
593
        call    IPv4_route              ; outputs device number in edi, dest ip in eax, source IP in edx
638
        call    IPv4_route              ; outputs device number in edi, dest ip in eax, source IP in edx
594
        push    edx
639
        push    edx
Line 640... Line 685...
640
        xor     eax, eax
685
        xor     eax, eax
641
        ret
686
        ret
Line 642... Line 687...
642
 
687
 
643
  .arp_error:
688
  .arp_error:
-
 
689
        DEBUGF  DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax
-
 
690
        add     esp, 4
-
 
691
        pop     eax
644
        DEBUGF  DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax
692
        DEBUGF  DEBUG_NETWORK_ERROR, "IPv4_output: ip=0x%x\n", eax
645
        add     esp, 3*4+2
693
        add     esp, 4+2
646
        xor     eax, eax
694
        xor     eax, eax
Line 647... Line 695...
647
        ret
695
        ret
648
 
696
 
Line 676... Line 724...
676
align 4
724
align 4
677
IPv4_output_raw:
725
IPv4_output_raw:
Line 678... Line 726...
678
 
726
 
Line 679... Line -...
679
        DEBUGF 1,"IPv4_output_raw: size=%u ptr=%x socket=%x\n", ecx, esi, eax
-
 
680
 
-
 
681
        cmp     ecx, 1480               ;;;;; FIXME
-
 
682
        ja      .too_large
727
        DEBUGF 1,"IPv4_output_raw: size=%u ptr=%x socket=%x\n", ecx, esi, eax
683
 
728
 
Line 684... Line 729...
684
        sub     esp, 8
729
        sub     esp, 8
685
        push    esi eax
730
        push    esi eax
Line 705... Line 750...
705
 
750
 
706
        mov     dword[esp+4+4], edx
751
        mov     dword[esp+4+4], edx
Line 707... Line 752...
707
        mov     dword[esp+4+4+4], eax
752
        mov     dword[esp+4+4+4], eax
708
 
753
 
Line 709... Line 754...
709
        pop     eax esi
754
        pop     eax esi
710
;; todo: check socket options if we should add header, or just compute checksum
755
;; TODO: check socket options if we should add header, or just compute checksum
711
 
756
 
Line 732... Line 777...
732
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_output_raw: device=%x\n", ebx
777
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_output_raw: device=%x\n", ebx
733
        call    [ebx + NET_DEVICE.transmit]
778
        call    [ebx + NET_DEVICE.transmit]
734
        ret
779
        ret
Line 735... Line 780...
735
 
780
 
736
  .error:
781
  .error:
-
 
782
        add     esp, 6+8+4+4
-
 
783
        mov     ebx, ENOBUFS            ; FIXME: NOBUFS or MSGSIZE error
-
 
784
        or      eax, -1
-
 
785
        ret
737
        add     esp, 6
786
 
738
  .arp_error:
787
  .arp_error:
739
        add     esp, 8+4+4
-
 
740
  .too_large:
788
        add     esp, 8+4+4
741
        DEBUGF  DEBUG_NETWORK_ERROR, "IPv4_output_raw: Failed\n"
789
        mov     ebx, ENOTCONN
742
        or      eax, -1
790
        or      eax, -1
Line 743... Line 791...
743
        ret
791
        ret
744
 
792
 
745
 
793
 
746
;--------------------------------------------------------
794
;--------------------------------------------------------
747
;
795
;
748
;
796
;
749
; IN: dword [esp] = pointer to buffer containing ipv4 packet to be fragmented
797
; IN: [esp] = pointer to buffer containing ipv4 packet to be fragmented
750
;     esi = pointer to ip header in that buffer
798
;     edi = pointer to ip header in that buffer
751
;     ecx = max size of fragments
799
;     ebx = device ptr
752
;
800
;
-
 
801
; OUT: /
Line 753... Line 802...
753
; OUT: /
802
;
-
 
803
;--------------------------------------------------------
-
 
804
proc IPv4_fragment stdcall buffer
-
 
805
 
-
 
806
locals
-
 
807
        offset          dd ?
754
;
808
        headerlength    dd ?
-
 
809
        headerptr       dd ?
Line 755... Line 810...
755
;--------------------------------------------------------
810
        dataptr         dd ?
Line 756... Line 811...
756
 
811
        remaining       dd ?
757
align 4
-
 
758
IPv4_fragment:
812
        segmentsize     dd ?
759
 
813
endl
760
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_fragment\n"
-
 
761
 
814
 
762
        and     ecx, not 111b   ; align 4
-
 
763
 
815
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_fragment\n"
764
        cmp     ecx, sizeof.IPv4_header + 8     ; must be able to put at least 8 bytes
816
 
765
        jb      .err2
817
; We must be able to put at least 8 bytes per segment
766
 
818
        movzx   eax, byte[edi]          ; IHL
767
        push    esi ecx
-
 
768
        mov     eax, [esi + IPv4_header.DestinationAddress]
819
        and     eax, 0xf
769
        call    ARP_IP_to_MAC
820
        shl     eax, 2
Line 770... Line -...
770
        pop     ecx esi
-
 
771
        cmp     eax, -1
821
        mov     [headerlength], eax
772
        jz      .err2
-
 
Line -... Line 822...
-
 
822
        add     eax, 8
-
 
823
        mov     ecx, [ebx + NET_DEVICE.mtu]
-
 
824
        and     ecx, not 11b
-
 
825
        cmp     ecx, eax
-
 
826
        jb      .fail
-
 
827
 
-
 
828
        mov     [edi + IPv4_header.HeaderChecksum], 0
Line 773... Line -...
773
 
-
 
774
        push    ebx
829
 
775
        push    ax
-
 
776
 
830
        mov     [segmentsize], ecx
Line 777... Line 831...
777
        mov     ebx, [NET_DRV_LIST]
831
        mov     [headerptr], edi
778
        lea     eax, [ebx + ETH_DEVICE.mac]
832
        movzx   ecx, [edi + IPv4_header.TotalLength]
Line -... Line 833...
-
 
833
        xchg    cl, ch
-
 
834
        sub     ecx, [headerlength]
-
 
835
        mov     [remaining], ecx
-
 
836
        mov     [offset], 0
-
 
837
 
-
 
838
        add     edi, [headerlength]
779
        push    eax
839
        mov     [dataptr], edi
780
 
840
 
-
 
841
  .loop:
-
 
842
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment"
781
 
843
 
782
        push    esi                             ; ptr to ip header
844
        mov     ecx, [segmentsize]
-
 
845
        cmp     ecx, [remaining]
-
 
846
        jbe     @f
-
 
847
        mov     ecx, [remaining]
Line 783... Line 848...
783
        sub     ecx, sizeof.IPv4_header         ; substract header size
848
  @@:
784
        push    ecx                             ; max data size
849
 
785
        push    dword 0                         ; offset
850
        mov     ax, ETHER_PROTO_IPv4
-
 
851
        mov     edx, [esp]
786
 
852
        add     edx, [edx + NET_BUFF.offset]
Line 787... Line 853...
787
  .new_fragment:
853
;        add     edx, ETH_header.DstMAC         ; = 0
788
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment"
854
        call    ETH_output
789
 
855
        jz      .fail
790
        mov     ax, ETHER_PROTO_IPv4
856
 
791
        lea     ebx, [esp + 4*4]
-
 
792
        call    ETH_output
857
        push    edi
793
        jz      .err
858
        mov     edx, ecx
794
 
859
 
-
 
860
; copy header
Line 795... Line 861...
795
; copy header
861
        mov     esi, [headerptr]
796
        mov     esi, [esp + 2*4]
862
        mov     ecx, [headerlength]
797
        mov     ecx, 5  ; 5 dwords: TODO: use IHL field of the header!
-
 
798
        rep movsd
863
        shr     ecx, 2
799
 
-
 
800
; copy data
-
 
801
        mov     esi, [esp + 2*4]
-
 
802
        add     esi, sizeof.IPv4_header
864
        rep movsd
803
        add     esi, [esp]      ; offset
-
 
804
 
-
 
805
        mov     ecx, [esp + 1*4]
-
 
806
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_fragment: copying %u bytes\n", ecx
-
 
807
        rep movsb
-
 
808
 
865
 
Line -... Line 866...
-
 
866
; copy data
809
; now, correct header
867
        mov     esi, [dataptr]
-
 
868
        add     esi, [offset]
Line -... Line 869...
-
 
869
        mov     ecx, edx
-
 
870
        sub     ecx, [headerlength]
-
 
871
        shr     ecx, 2
-
 
872
        rep movsd
810
        mov     ecx, [esp + 1*4]
873
        pop     edi
811
        add     ecx, sizeof.IPv4_header
874
 
-
 
875
; now, correct header
-
 
876
; packet length
Line 812... Line 877...
812
        xchg    cl, ch
877
        mov     ax, dx
813
        mov     [edi + IPv4_header.TotalLength], cx
878
        xchg    al, ah
814
 
-
 
815
        mov     ecx, [esp]              ; offset
879
        mov     [edi + IPv4_header.TotalLength], ax
816
        xchg    cl, ch
-
 
817
 
-
 
818
;        cmp     dword[esp + 4*4], 0     ; last fragment?;<<<<<<
-
 
819
;        je      .last_fragment
-
 
Line 820... Line -...
820
        or      cx, 1 shl 2             ; more fragments
-
 
821
;  .last_fragment:
880
 
822
        mov     [edi + IPv4_header.FlagsAndFragmentOffset], cx
-
 
823
 
881
; offset
Line 824... Line -...
824
        mov     [edi + IPv4_header.HeaderChecksum], 0
-
 
825
 
-
 
826
        ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< send the packet
-
 
827
        mov     ecx, [esp + 1*4]
882
        mov     eax, [offset]
828
 
-
 
829
        push    edx eax
-
 
830
        IPv4_checksum edi
883
        xchg    al, ah
Line 831... Line 884...
831
 
884
 
832
        call    [ebx + NET_DEVICE.transmit]
885
        sub     edx, [headerlength]
833
        ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-
 
834
 
-
 
835
        mov     ecx, [esp+4]
-
 
836
        add     [esp], ecx
-
 
837
 
886
        sub     [remaining], edx
838
        mov     ecx, [esp+3*4+6+4]      ; ptr to begin of buff
887
        je      @f
Line -... Line 888...
-
 
888
        jb      .fail
-
 
889
        or      ah, 1 shl 2             ; more fragments
Line 839... Line 890...
839
        add     ecx, [esp+3*4+6+4+4]    ; buff size
890
        add     [offset], edx
840
        sub     ecx, [esp+2*4]          ; ptr to ip header
891
  @@:
841
        add     ecx, [esp]              ; offset
892
        mov     [edi + IPv4_header.FlagsAndFragmentOffset], ax
Line 971... Line 1022...
971
 
1022
 
972
; Fill in remote IP
1023
; Fill in remote IP
973
        pushd   [edx + 4]
1024
        pushd   [edx + 4]
Line 974... Line -...
974
        pop     [eax + IP_SOCKET.RemoteIP]
-
 
975
 
-
 
976
; Set up data receiving queue
-
 
977
        push    eax
-
 
978
        init_queue (eax + SOCKET_QUEUE_LOCATION)
-
 
979
        pop     eax
1025
        pop     [eax + IP_SOCKET.RemoteIP]
980
 
1026
 
Line 981... Line 1027...
981
        lea     ecx, [eax + SOCKET.mutex]
1027
        lea     ecx, [eax + SOCKET.mutex]
982
        call    mutex_unlock
1028
        call    mutex_unlock