Getting ready for better IP routing

git-svn-id: svn://kolibrios.org@2877 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2012-07-17 21:36:34 +00:00
parent e63514ec4a
commit eda11ddd36
8 changed files with 97 additions and 91 deletions

View File

@ -282,6 +282,7 @@ ARP_input:
; ARP_output_request ; ARP_output_request
; ;
; IN: ip in eax ; IN: ip in eax
; device in edi
; OUT: / ; OUT: /
; ;
;--------------------------------------------------------------------------- ;---------------------------------------------------------------------------
@ -290,7 +291,6 @@ ARP_output_request:
DEBUGF 1,"Create ARP Packet\n" DEBUGF 1,"Create ARP Packet\n"
call IPv4_dest_to_dev
push eax ; DestIP push eax ; DestIP
pushd [IP_LIST+edi] ; SenderIP pushd [IP_LIST+edi] ; SenderIP
@ -441,9 +441,11 @@ ARP_del_entry:
; This function translates an IP address to a MAC address ; This function translates an IP address to a MAC address
; ;
; IN: eax = IPv4 address ; IN: eax = IPv4 address
; edi = device number
; OUT: eax = -1 on error, -2 means request send ; OUT: eax = -1 on error, -2 means request send
; else, ax = first two bytes of mac (high 16 bits of eax will be 0) ; else, ax = first two bytes of mac (high 16 bits of eax will be 0)
; ebx = last four bytes of mac ; ebx = last four bytes of mac
; edi = unchanged
; ;
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 align 4
@ -457,27 +459,9 @@ ARP_IP_to_MAC:
cmp eax, 0xffffffff cmp eax, 0xffffffff
je .broadcast je .broadcast
; if ((Remote IP & subnet_mask) == (local IP & subnet_mask ))
; destination is on same subnet
; else, destination is remote and must use a gateway
call IPv4_dest_to_dev
mov ebx, [IP_LIST + edi]
and ebx, [SUBNET_LIST + edi]
mov ecx, eax
and ecx, [SUBNET_LIST + edi]
cmp ecx, ebx
je .local
mov eax, [GATEWAY_LIST + edi]
DEBUGF 1,"requested IP is not on subnet, using default gateway\n"
;-------------------------------- ;--------------------------------
; Try to find the IP in ARP_table ; Try to find the IP in ARP_table
.local:
mov ecx, [NumARP] mov ecx, [NumARP]
test ecx, ecx test ecx, ecx
jz .not_in_list jz .not_in_list
@ -494,7 +478,7 @@ ARP_IP_to_MAC:
;-------------------- ;--------------------
; Send an ARP request ; Send an ARP request
push eax ; save IP for ARP_output_request push eax edi ; save IP for ARP_output_request
; Now create the ARP entry ; Now create the ARP entry
pushw ARP_REQUEST_TTL ; TTL pushw ARP_REQUEST_TTL ; TTL
@ -510,7 +494,7 @@ ARP_IP_to_MAC:
je .full je .full
; And send a request ; And send a request
pop eax pop edi eax
call ARP_output_request ; IP in eax call ARP_output_request ; IP in eax
;; TODO: check if driver could transmit packet ;; TODO: check if driver could transmit packet
@ -532,7 +516,7 @@ ARP_IP_to_MAC:
.full: .full:
DEBUGF 1,"ARP table is full!\n" DEBUGF 1,"ARP table is full!\n"
pop eax add esp, 8
mov eax, -1 mov eax, -1
ret ret

View File

@ -556,9 +556,9 @@ IPv4_find_fragment_slot:
; IPv4_output ; IPv4_output
; ;
; IN: eax = dest ip ; IN: eax = dest ip
; ebx = source ip ; ebx = output device ptr/0 for automatic choice
; ecx = data length ; ecx = data length
; dx = fragment id ; edx = source ip
; di = TTL shl 8 + protocol ; di = TTL shl 8 + protocol
; ;
; OUT: eax = pointer to buffer start ; OUT: eax = pointer to buffer start
@ -576,38 +576,36 @@ IPv4_output:
cmp ecx, 65500 ; Max IPv4 packet size cmp ecx, 65500 ; Max IPv4 packet size
ja .too_large ja .too_large
push ecx eax ebx dx di push ecx eax edx di
call IPv4_dest_to_dev ; outputs device number in edi, dest ip in eax
call ARP_IP_to_MAC call ARP_IP_to_MAC
test eax, 0xffff0000 ; error bits test eax, 0xffff0000 ; error bits
jnz .arp_error jnz .arp_error
push ebx ; push the mac onto the stack
push ebx ; push the mac
push ax push ax
call IPv4_dest_to_dev inc [IP_PACKETS_TX + edi] ; update stats
inc [IP_PACKETS_TX+edi]
mov ebx, [NET_DRV_LIST + edi] mov ebx, [NET_DRV_LIST + edi]
lea eax, [ebx + ETH_DEVICE.mac] lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp mov edx, esp
mov ecx, [esp + 18] mov ecx, [esp + 10 + 6]
add ecx, sizeof.IPv4_header add ecx, sizeof.IPv4_header
mov di, ETHER_IPv4 mov di, ETHER_IPv4
call ETH_output call ETH_output
jz .eth_error jz .eth_error
add esp, 6 ; pop the mac out of the stack
add esp, 6 ; pop the mac xchg cl, ch ; internet byte order
mov [edi + IPv4_header.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) mov [edi + IPv4_header.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header)
mov [edi + IPv4_header.TypeOfService], 0 ; nothing special, just plain ip packet mov [edi + IPv4_header.TypeOfService], 0 ; nothing special, just plain ip packet
mov [edi + IPv4_header.TotalLength], cx mov [edi + IPv4_header.TotalLength], cx
rol [edi + IPv4_header.TotalLength], 8 ; internet byte order mov [edi + IPv4_header.Identification], 0 ; fragment id: FIXME
mov [edi + IPv4_header.FlagsAndFragmentOffset], 0x0000 mov [edi + IPv4_header.FlagsAndFragmentOffset], 0
mov [edi + IPv4_header.HeaderChecksum], 0
pop word [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol pop word [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol
; [edi + IPv4_header.Protocol] ; [edi + IPv4_header.Protocol]
popw [edi + IPv4_header.Identification] ; fragment id mov [edi + IPv4_header.HeaderChecksum], 0
popd [edi + IPv4_header.SourceAddress] popd [edi + IPv4_header.SourceAddress]
popd [edi + IPv4_header.DestinationAddress] popd [edi + IPv4_header.DestinationAddress]
@ -620,19 +618,19 @@ IPv4_output:
.eth_error: .eth_error:
DEBUGF 1,"IPv4_output: ethernet error\n" DEBUGF 1,"IPv4_output: ethernet error\n"
add esp, 3*4+2*2+6 add esp, 3*4+2+6
sub edi, edi xor edi, edi
ret ret
.arp_error: .arp_error:
DEBUGF 1,"IPv4_output: ARP error (0x%x)\n", eax DEBUGF 1,"IPv4_output: ARP error (0x%x)\n", eax
add esp, 4+4+4+2+2 add esp, 3*4+2
sub edi, edi xor edi, edi
ret ret
.too_large: .too_large:
DEBUGF 1,"IPv4_output: error: Packet too large!\n" DEBUGF 1,"IPv4_output: error: Packet too large!\n"
sub edi, edi xor edi, edi
ret ret
@ -661,17 +659,15 @@ IPv4_output_raw:
sub esp, 8 sub esp, 8
push esi eax push esi eax
call IPv4_dest_to_dev
call ARP_IP_to_MAC call ARP_IP_to_MAC
test eax, 0xffff0000 ; error bits test eax, 0xffff0000 ; error bits
jnz .arp_error jnz .arp_error
.continue:
push ebx ; push the mac push ebx ; push the mac
push ax push ax
call IPv4_dest_to_dev
inc [IP_PACKETS_TX + edi] inc [IP_PACKETS_TX + edi]
mov ebx, [NET_DRV_LIST + edi] mov ebx, [NET_DRV_LIST + edi]
lea eax, [ebx + ETH_DEVICE.mac] lea eax, [ebx + ETH_DEVICE.mac]
@ -853,22 +849,21 @@ IPv4_fragment:
; ;
; IN: eax = Destination IP ; IN: eax = Destination IP
; OUT: edi = device id * 4 ; OUT: edi = device id * 4
; eax = ip of gateway if nescessary, unchanged otherwise
; ;
;--------------------------------------------------------------------------- ;---------------------------------------------------------------------------
align 4 align 4
IPv4_dest_to_dev: IPv4_dest_to_dev:
cmp eax, 0xffffffff cmp eax, 0xffffffff
je .invalid je .broadcast
xor edi, edi xor edi, edi
mov ecx, MAX_IP mov ecx, MAX_IP
.loop: .loop:
mov ebx, [IP_LIST+edi] mov ebx, [IP_LIST+edi]
and ebx, [SUBNET_LIST+edi] and ebx, [SUBNET_LIST+edi]
jz .next jz .next
mov edx, eax mov edx, eax
and edx, [SUBNET_LIST+edi] and edx, [SUBNET_LIST+edi]
@ -880,11 +875,15 @@ IPv4_dest_to_dev:
jnz .loop jnz .loop
.invalid: .invalid:
xor edi, edi ; if none found, use device 0 as default device xor edi, edi ; if none found, use device 0 as default
mov eax, [GATEWAY_LIST]
.found_it: .found_it:
DEBUGF 1,"IPv4_dest_to_dev: %u\n", edi DEBUGF 1,"IPv4_dest_to_dev: %u\n", edi
ret
.broadcast:
xor edi, edi
ret ret

View File

@ -284,7 +284,6 @@ ICMP_input:
; ecx = data length ; ecx = data length
; dh = type ; dh = type
; dl = code ; dl = code
; high 16 bits of edx = fragment id (for IP header)
; esi = data offset ; esi = data offset
; edi = identifier shl 16 + sequence number ; edi = identifier shl 16 + sequence number
; ;
@ -294,34 +293,28 @@ ICMP_output:
DEBUGF 1,"Creating ICMP Packet\n" DEBUGF 1,"Creating ICMP Packet\n"
push esi edi edx push esi edi dx
mov ebx, [eax + IP_SOCKET.LocalIP] mov edx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP] mov eax, [eax + IP_SOCKET.RemoteIP]
add ecx, sizeof.ICMP_header add ecx, sizeof.ICMP_header
mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL
shr edx, 16
call IPv4_output call IPv4_output
jz .exit jz .exit
DEBUGF 1,"full icmp packet size: %u\n", edx DEBUGF 1,"full icmp packet size: %u\n", edx
pop eax pop word [edi + ICMP_header.Type] ; Write both type and code bytes at once
mov word [edi + ICMP_header.Type], ax ; Write both type and code bytes at once pop dword [edi + ICMP_header.Identifier] ; identifier and sequence number
pop eax
mov [edi + ICMP_header.SequenceNumber], ax
shr eax, 16
mov [edi + ICMP_header.Identifier], ax
mov [edi + ICMP_header.Checksum], 0 mov [edi + ICMP_header.Checksum], 0
push eax ebx ecx edx push ebx ecx edx
mov esi, edi mov esi, edi
xor edx, edx xor edx, edx
call checksum_1 call checksum_1
call checksum_2 call checksum_2
mov [edi + ICMP_header.Checksum], dx mov [edi + ICMP_header.Checksum], dx
pop edx ecx ebx eax esi pop edx ecx ebx esi
sub ecx, sizeof.ICMP_header sub ecx, sizeof.ICMP_header
add edi, sizeof.ICMP_header add edi, sizeof.ICMP_header
@ -339,7 +332,7 @@ ICMP_output:
ret ret
.exit: .exit:
DEBUGF 1,"Creating ICMP Packet failed\n" DEBUGF 1,"Creating ICMP Packet failed\n"
add esp, 3*4 add esp,2*4+2
ret ret
@ -362,8 +355,7 @@ ICMP_output_raw:
push edx push edx
mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL
shr edx, 16 mov edx, [eax + IP_SOCKET.LocalIP]
mov ebx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP] mov eax, [eax + IP_SOCKET.RemoteIP]
call IPv4_output call IPv4_output
jz .exit jz .exit

View File

@ -29,6 +29,7 @@ struct SOCKET
Type dd ? ; RAW/STREAM/DGRAP Type dd ? ; RAW/STREAM/DGRAP
Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP
errorcode dd ? errorcode dd ?
device dd ?
options dd ? options dd ?
state dd ? state dd ?
@ -925,7 +926,7 @@ SOCKET_get_opt:
; ;
; IN: ecx = socket number ; IN: ecx = socket number
; edx = pointer to the options: ; edx = pointer to the options:
; dd level, optname, optval, optlen ; dd level, optname, optlen, optval
; OUT: -1 on error ; OUT: -1 on error
; ;
;----------------------------------------------------------------- ;-----------------------------------------------------------------
@ -937,8 +938,36 @@ SOCKET_set_opt:
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
cmp dword [edx], SOL_SOCKET
jne s_error
cmp dword [edx+4], SO_BINDTODEVICE
je .bind
jmp s_error
.bind:
cmp dword [edx+8], 0
je .unbind
movzx edx, byte [edx + 9]
cmp edx, MAX_NET_DEVICES
ja s_error
mov edx, [NET_DRV_LIST + 4*edx]
test edx, edx
jz s_error
mov [eax + SOCKET.device], edx
DEBUGF 1,"Bound socket %x to device %x\n",eax, edx
mov dword [esp+32], 0 ; success!
ret
.unbind:
mov [eax + SOCKET.device], 0
mov dword [esp+32], 0 ; success!
ret ret

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; STACK.INC ;; ;; STACK.INC ;;
@ -70,6 +70,10 @@ SO_OOBINLINE = 1 shl 5
SO_REUSEADDR = 1 shl 6 SO_REUSEADDR = 1 shl 6
SO_REUSEPORT = 1 shl 7 SO_REUSEPORT = 1 shl 7
SO_USELOOPBACK = 1 shl 8 SO_USELOOPBACK = 1 shl 8
SO_BINDTODEVICE = 1 shl 9
; Socket level
SOL_SOCKET = 0
; Socket States ; Socket States

View File

@ -421,7 +421,8 @@ TCP_output:
mov ecx, esi mov ecx, esi
mov ebx, [eax + IP_SOCKET.LocalIP] ; source ip mov ebx, [eax + SOCKET.device]
mov edx, [eax + IP_SOCKET.LocalIP] ; source ip
mov eax, [eax + IP_SOCKET.RemoteIP] ; dest ip mov eax, [eax + IP_SOCKET.RemoteIP] ; dest ip
mov di, IP_PROTO_TCP shl 8 + 128 mov di, IP_PROTO_TCP shl 8 + 128
call IPv4_output call IPv4_output

View File

@ -330,7 +330,7 @@ TCP_respond_socket:
push cx ebx push cx ebx
mov eax, [ebx + IP_SOCKET.RemoteIP] mov eax, [ebx + IP_SOCKET.RemoteIP]
mov ebx, [ebx + IP_SOCKET.LocalIP] mov edx, [ebx + IP_SOCKET.LocalIP]
mov ecx, sizeof.TCP_header mov ecx, sizeof.TCP_header
mov di, IP_PROTO_TCP shl 8 + 128 mov di, IP_PROTO_TCP shl 8 + 128
call IPv4_output call IPv4_output

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; UDP.INC ;; ;; UDP.INC ;;
@ -242,18 +242,15 @@ UDP_output:
DEBUGF 1,"local port: %u\n", dx DEBUGF 1,"local port: %u\n", dx
rol dx, 8 rol dx, 8
mov ebx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP]
mov di, IP_PROTO_UDP shl 8 + 128
sub esp, 8 ; Data ptr and data size will be placed here sub esp, 8 ; Data ptr and data size will be placed here
add ecx, sizeof.UDP_header
;;; TODO: fragment id
push edx esi push edx esi
mov ebx, [eax + SOCKET.device]
mov edx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP]
mov di, IP_PROTO_UDP shl 8 + 128
add ecx, sizeof.UDP_header
call IPv4_output call IPv4_output
jz .fail jz .fail
mov [esp + 8], eax ; pointer to buffer start mov [esp + 8], eax ; pointer to buffer start
mov [esp + 8 + 4], edx ; buffer size mov [esp + 8 + 4], edx ; buffer size