IPv6.inc
mxlgv_KolibriDev/src/kernel/network/IPv6.inc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                 ;;
;; Copyright (C) KolibriOS team 2012-2015. All rights reserved.    ;;
;; Distributed under terms of the GNU General Public License       ;;
;;                                                                 ;;
;;  IPv6.INC                                                       ;;
;;                                                                 ;;
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
;;                                                                 ;;
;;    Written by hidnplayr@kolibrios.org                           ;;
;;                                                                 ;;
;;          GNU GENERAL PUBLIC LICENSE                             ;;
;;             Version 2, June 1991                                ;;
;;                                                                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

$Revision: 6011 $


struct  IPv6_header

        VersionTrafficFlow      dd ?    ; Version[0-3], Traffic class[4-11], Flow Label [12-31]
        PayloadLength           dw ?    ; 16 bits, unsigned length of payload (extension headers are part of this)
        NextHeader              db ?    ; Values are same as in IPv4 'Protocol' field
        HopLimit                db ?    ; Decremented by every node, packet is discarded when it reaches 0
        SourceAddress           rd 4    ; 128-bit addresses
        DestinationAddress      rd 4    ;
        Payload                 rb 0

ends


uglobal
align 4

        IPv6:
        .addresses      rd 4*NET_DEVICES_MAX
        .subnet         rd 4*NET_DEVICES_MAX
        .dns            rd 4*NET_DEVICES_MAX
        .gateway        rd 4*NET_DEVICES_MAX

        .packets_tx     rd NET_DEVICES_MAX
        .packets_rx     rd NET_DEVICES_MAX

endg


;-----------------------------------------------------------------;
;                                                                 ;
; ipv6_init: Resets all IPv6 variables                            ;
;                                                                 ;
;-----------------------------------------------------------------;
macro   ipv6_init {

        xor     eax, eax
        mov     edi, IPv6
        mov     ecx, (4*4*4+2*4)MAX_IP
        rep stosd

}



;-----------------------------------------------------------------;
;                                                                 ;
; ipv6_input: Check if IPv6 Packet isnt damaged and call          ;
; appropriate handler. (TCP/UDP/ICMP/..)                          ;
; We will also re-construct fragmented packets                    ;
;                                                                 ;
;   IN: [esp] = ptr to buffer                                     ;
;       [esp+4] = size of buffer                                  ;
;       ebx = ptr to device struct                                ;
;       edx = ptr to IPv6 header                                  ;
;       ecx = size of IPv6 packet                                 ;
;                                                                 ;
;  OUT: /                                                         ;
;                                                                 ;
;-----------------------------------------------------------------;
align 4
ipv6_input:

        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv6_input from: %x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x\n",\
        [edx + IPv6_header.SourceAddress + 0]:2,[edx + IPv6_header.SourceAddress + 1]:2,\
        [edx + IPv6_header.SourceAddress + 2]:2,[edx + IPv6_header.SourceAddress + 3]:2,\
        [edx + IPv6_header.SourceAddress + 4]:2,[edx + IPv6_header.SourceAddress + 5]:2,\
        [edx + IPv6_header.SourceAddress + 6]:2,[edx + IPv6_header.SourceAddress + 7]:2,\
        [edx + IPv6_header.SourceAddress + 8]:2,[edx + IPv6_header.SourceAddress + 9]:2,\
        [edx + IPv6_header.SourceAddress + 10]:2,[edx + IPv6_header.SourceAddress + 11]:2,\
        [edx + IPv6_header.SourceAddress + 12]:2,[edx + IPv6_header.SourceAddress + 13]:2,\
        [edx + IPv6_header.SourceAddress + 14]:2,[edx + IPv6_header.SourceAddress + 15]:2

        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv6_input to: %x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x\n",\
        [edx + IPv6_header.DestinationAddress + 0]:2,[edx + IPv6_header.DestinationAddress + 1]:2,\
        [edx + IPv6_header.DestinationAddress + 2]:2,[edx + IPv6_header.DestinationAddress + 3]:2,\
        [edx + IPv6_header.DestinationAddress + 4]:2,[edx + IPv6_header.DestinationAddress + 5]:2,\
        [edx + IPv6_header.DestinationAddress + 6]:2,[edx + IPv6_header.DestinationAddress + 7]:2,\
        [edx + IPv6_header.DestinationAddress + 8]:2,[edx + IPv6_header.DestinationAddress + 9]:2,\
        [edx + IPv6_header.DestinationAddress + 10]:2,[edx + IPv6_header.DestinationAddress + 11]:2,\
        [edx + IPv6_header.DestinationAddress + 12]:2,[edx + IPv6_header.DestinationAddress + 13]:2,\
        [edx + IPv6_header.DestinationAddress + 14]:2,[edx + IPv6_header.DestinationAddress + 15]:2

        sub     ecx, sizeof.IPv6_header
        jb      .dump

        cmp     cx, [edx + IPv6_header.PayloadLength]
        jb      .dump

;-------------------------------------------------------------------
; No, it's just a regular IP packet, pass it to the higher protocols

  .handle_it:
        movzx   ecx, [edx + IPv6_header.PayloadLength]
        lea     edi, [edx + IPv6_header.SourceAddress]          ; make edi ptr to source and dest IPv6 address
        lea     esi, [edx + IPv6_header.Payload]                ; make esi ptr to data
        mov     al, [edx + IPv6_header.NextHeader]

  .scan:
        cmp     al, 59  ; no next
        je      .dump

        cmp     al, 0
        je      .hop_by_hop

        cmp     al, 43
        je      .routing

        cmp     al, 44
        je      .fragment

        cmp     al, 60
        je      .dest_opts

;        cmp     al, IP_PROTO_TCP
;        je      TCP_input

;        cmp     al, IP_PROTO_UDP
;        je      UDP_input

;        cmp     al, 58
;        je      ICMP6_input

        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv6_input - unknown protocol: %u\n", al

  .dump:
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv6_input - dumping\n"
        call    net_buff_free
        ret

  .dump_options:
        add     esp, 2+4+4
        jmp     .dump

  .nextheader:
        pop     esi
        pop     ecx
        pop     ax
        jmp     .scan

;-------------------------
; Hop-by-Hop

  .hop_by_hop:
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv6_input - hop by hop\n"
        pushw   [esi]                   ; 8 bit identifier for option type
        movzx   eax, byte[esi + 1]      ; Hdr Ext Len
        inc     eax                     ; first 8 octets not counted
        shl     eax, 3                  ; * 8
        sub     ecx, eax
        push    ecx
        add     eax, esi
        push    eax
        inc     esi
        inc     esi

        mov     al, [esi]

        cmp     al, 0
        je      .pad_1

        cmp     al, 1
        je      .pad_n

        ; TODO: check with other known options

; unknown option.. discard packet or not?
; check highest two bits
        test    al, 0xc0        ; discard packet
        jnz     .dump_options

  .pad_n:
        movzx   eax, byte[esi + 1]
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv6_input - pad %u\n", eax
        inc     esi
        inc     esi
        add     esi, eax
        sub     ecx, eax
        jmp     .hop_by_hop

  .pad_1:
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv6_input - pad 1\n"
        inc     esi
        dec     ecx
        jmp     .hop_by_hop



  .dest_opts:
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv6_input - dest opts\n"
        jmp     .nextheader

  .routing:
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv6_input - routing\n"
        pushw   [esi]                   ; 8 bit identifier for option type
        movzx   eax, byte[esi + 1]      ; Hdr Ext Len
        inc     eax                     ; first 8 octets not counted
        shl     eax, 3                  ; * 8
        sub     ecx, eax
        push    ecx
        add     eax, esi
        push    eax
        inc     esi
        inc     esi

        cmp     al, 0
        je      .pad_1

        cmp     al, 1
        je      .pad_n

        mov     al, [esi]       ; routing type

        jmp     .nextheader

  .fragment:
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv6_input - fragment\n"

        jmp     .nextheader






;-----------------------------------------------------------------;
;                                                                 ;
; ipv6_api: Part of system function 76                            ;
;                                                                 ;
;  IN:  bl = subfunction number                                   ;
;       bh = device number                                        ;
;       ecx, edx, .. depends on subfunction                       ;
;                                                                 ;
; OUT:  depends on subfunction                                    ;
;                                                                 ;
;-----------------------------------------------------------------;
align 4
ipv6_api:

        movzx   eax, bh
        shl     eax, 2

        and     ebx, 0x000000ff
        cmp     ebx, .number
        ja      .error
        jmp     dword [.table + 4*ebx]

  .table:
        dd      .packets_tx     ; 0
        dd      .packets_rx     ; 1
;        dd      .read_ip        ; 2
;        dd      .write_ip       ; 3
;        dd      .read_dns       ; 4
;        dd      .write_dns      ; 5
;        dd      .read_subnet    ; 6
;        dd      .write_subnet   ; 7
;        dd      .read_gateway   ; 8
;        dd      .write_gateway  ; 9
  .number = ($ - .table) / 4 - 1

  .error:
        mov     eax, -1
        ret

  .packets_tx:
        mov     eax, [IPv6.packets_tx + eax]
        ret

  .packets_rx:
        mov     eax, [IPv6.packets_rx + eax]
        ret

