Rustem Gimadutdinov (rgimad)
73864ff1d7
git-svn-id: svn://kolibrios.org@9019 a494cfbc-eb01-0410-851d-a64ba20cac60
291 lines
9.9 KiB
PHP
291 lines
9.9 KiB
PHP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; 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$
|
|
|
|
|
|
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
|
|
|