forked from KolibriOS/kolibrios
Getting ready for better IP routing
git-svn-id: svn://kolibrios.org@2877 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
e63514ec4a
commit
eda11ddd36
@ -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
|
||||
|
||||
@ -523,7 +507,7 @@ ARP_IP_to_MAC:
|
||||
jne .invalid
|
||||
|
||||
movzx eax, word [esi + ARP_entry.MAC]
|
||||
mov ebx, dword[esi + ARP_entry.MAC+2]
|
||||
mov ebx, dword[esi + ARP_entry.MAC + 2]
|
||||
ret
|
||||
|
||||
.invalid:
|
||||
@ -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
|
||||
|
||||
|
@ -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]
|
||||
mov ebx, [NET_DRV_LIST+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
|
||||
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,22 +659,20 @@ 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]
|
||||
inc [IP_PACKETS_TX + edi]
|
||||
mov ebx, [NET_DRV_LIST + edi]
|
||||
lea eax, [ebx + ETH_DEVICE.mac]
|
||||
mov edx, esp
|
||||
mov ecx, [esp + 6+4]
|
||||
mov ecx, [esp + 6 + 4]
|
||||
add ecx, sizeof.IPv4_header
|
||||
mov di, ETHER_IPv4
|
||||
call ETH_output
|
||||
@ -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
|
||||
|
||||
|
||||
|
@ -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,42 +293,36 @@ 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
|
||||
|
||||
mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL
|
||||
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
|
||||
push cx
|
||||
shr cx , 2
|
||||
shr cx, 2
|
||||
rep movsd
|
||||
pop cx
|
||||
and cx , 3
|
||||
and cx, 3
|
||||
rep movsb
|
||||
|
||||
sub edi, edx ;;; TODO: find a better way to remember start of packet
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -330,9 +330,9 @@ 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
|
||||
mov di, IP_PROTO_TCP shl 8 + 128
|
||||
call IPv4_output
|
||||
test edi, edi
|
||||
jz .error
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user