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
;
; IN: ip in eax
; device in edi
; OUT: /
;
;---------------------------------------------------------------------------
@ -290,7 +291,6 @@ ARP_output_request:
DEBUGF 1,"Create ARP Packet\n"
call IPv4_dest_to_dev
push eax ; DestIP
pushd [IP_LIST+edi] ; SenderIP
@ -441,9 +441,11 @@ ARP_del_entry:
; This function translates an IP address to a MAC address
;
; IN: eax = IPv4 address
; edi = device number
; OUT: eax = -1 on error, -2 means request send
; else, ax = first two bytes of mac (high 16 bits of eax will be 0)
; ebx = last four bytes of mac
; edi = unchanged
;
;-----------------------------------------------------------------
align 4
@ -457,27 +459,9 @@ ARP_IP_to_MAC:
cmp eax, 0xffffffff
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
.local:
mov ecx, [NumARP]
test ecx, ecx
jz .not_in_list
@ -494,7 +478,7 @@ ARP_IP_to_MAC:
;--------------------
; 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
pushw ARP_REQUEST_TTL ; TTL
@ -510,7 +494,7 @@ ARP_IP_to_MAC:
je .full
; And send a request
pop eax
pop edi eax
call ARP_output_request ; IP in eax
;; TODO: check if driver could transmit packet
@ -532,7 +516,7 @@ ARP_IP_to_MAC:
.full:
DEBUGF 1,"ARP table is full!\n"
pop eax
add esp, 8
mov eax, -1
ret

View File

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

View File

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

View File

@ -29,6 +29,7 @@ struct SOCKET
Type dd ? ; RAW/STREAM/DGRAP
Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP
errorcode dd ?
device dd ?
options dd ?
state dd ?
@ -925,7 +926,7 @@ SOCKET_get_opt:
;
; IN: ecx = socket number
; edx = pointer to the options:
; dd level, optname, optval, optlen
; dd level, optname, optlen, optval
; OUT: -1 on error
;
;-----------------------------------------------------------------
@ -937,8 +938,36 @@ SOCKET_set_opt:
call SOCKET_num_to_ptr
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

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 ;;
;; ;;
;; STACK.INC ;;
@ -70,6 +70,10 @@ SO_OOBINLINE = 1 shl 5
SO_REUSEADDR = 1 shl 6
SO_REUSEPORT = 1 shl 7
SO_USELOOPBACK = 1 shl 8
SO_BINDTODEVICE = 1 shl 9
; Socket level
SOL_SOCKET = 0
; Socket States

View File

@ -421,7 +421,8 @@ TCP_output:
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 di, IP_PROTO_TCP shl 8 + 128
call IPv4_output

View File

@ -330,7 +330,7 @@ TCP_respond_socket:
push cx ebx
mov eax, [ebx + IP_SOCKET.RemoteIP]
mov ebx, [ebx + IP_SOCKET.LocalIP]
mov edx, [ebx + IP_SOCKET.LocalIP]
mov ecx, sizeof.TCP_header
mov di, IP_PROTO_TCP shl 8 + 128
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 ;;
;; ;;
;; UDP.INC ;;
@ -242,18 +242,15 @@ UDP_output:
DEBUGF 1,"local port: %u\n", dx
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
add ecx, sizeof.UDP_header
;;; TODO: fragment id
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
jz .fail
mov [esp + 8], eax ; pointer to buffer start
mov [esp + 8 + 4], edx ; buffer size