Some cleanup/refactoring of IPv4 code (preparing for routing)

git-svn-id: svn://kolibrios.org@4052 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2013-10-19 15:47:58 +00:00
parent 9550c01924
commit 931a90c02d
5 changed files with 125 additions and 117 deletions

View File

@ -35,7 +35,7 @@ struct IPv4_header
ends ends
struct FRAGMENT_slot struct IPv4_FRAGMENT_slot
ttl dw ? ; Time to live for this entry, 0 for empty slot's ttl dw ? ; Time to live for this entry, 0 for empty slot's
id dw ? ; Identification field from IP header id dw ? ; Identification field from IP header
@ -45,7 +45,7 @@ struct FRAGMENT_slot
ends ends
struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets struct IPv4_FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets
PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet) PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet)
NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet) NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet)
@ -64,11 +64,11 @@ align 4
GATEWAY_LIST rd NET_DEVICES_MAX GATEWAY_LIST rd NET_DEVICES_MAX
BROADCAST_LIST rd NET_DEVICES_MAX BROADCAST_LIST rd NET_DEVICES_MAX
IP_packets_tx rd NET_DEVICES_MAX IPv4_packets_tx rd NET_DEVICES_MAX
IP_packets_rx rd NET_DEVICES_MAX IPv4_packets_rx rd NET_DEVICES_MAX
IP_packets_dumped rd NET_DEVICES_MAX IPv4_packets_dumped rd NET_DEVICES_MAX
FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot IPv4_FRAGMENT_LIST rb IPv4_MAX_FRAGMENTS * sizeof.IPv4_FRAGMENT_slot
endg endg
@ -84,7 +84,7 @@ macro IPv4_init {
xor eax, eax xor eax, eax
mov edi, IP_LIST mov edi, IP_LIST
mov ecx, 7*NET_DEVICES_MAX + (sizeof.FRAGMENT_slot*MAX_FRAGMENTS)/4 mov ecx, 7*NET_DEVICES_MAX + (sizeof.IPv4_FRAGMENT_slot*IPv4_MAX_FRAGMENTS)/4
rep stosd rep stosd
} }
@ -99,15 +99,15 @@ macro IPv4_decrease_fragment_ttls {
local .loop, .next local .loop, .next
mov esi, FRAGMENT_LIST mov esi, IPv4_FRAGMENT_LIST
mov ecx, MAX_FRAGMENTS mov ecx, IPv4_MAX_FRAGMENTS
.loop: .loop:
cmp [esi + FRAGMENT_slot.ttl], 0 cmp [esi + IPv4_FRAGMENT_slot.ttl], 0
je .next je .next
dec [esi + FRAGMENT_slot.ttl] dec [esi + IPv4_FRAGMENT_slot.ttl]
jz .died jz .died
.next: .next:
add esi, sizeof.FRAGMENT_slot add esi, sizeof.IPv4_FRAGMENT_slot
dec ecx dec ecx
jnz .loop jnz .loop
jmp .done jmp .done
@ -263,7 +263,7 @@ IPv4_input: ; TODO: add IPv4
; Now we can update stats ; Now we can update stats
.ip_ok: .ip_ok:
inc [IP_packets_rx + edi] inc [IPv4_packets_rx + edi]
;---------------------------------- ;----------------------------------
; Check if the packet is fragmented ; Check if the packet is fragmented
@ -304,7 +304,7 @@ IPv4_input: ; TODO: add IPv4
.dump: .dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n"
inc [IP_packets_dumped] ; FIXME: use correct interface inc [IPv4_packets_dumped] ; FIXME: use correct interface
call NET_packet_free call NET_packet_free
add esp, 4 ; pop (balance stack) add esp, 4 ; pop (balance stack)
ret ret
@ -334,24 +334,24 @@ IPv4_input: ; TODO: add IPv4
cmp esi, -1 cmp esi, -1
je .dump je .dump
mov [esi + FRAGMENT_slot.ttl], 15 ; Reset the ttl mov [esi + IPv4_FRAGMENT_slot.ttl], 15 ; Reset the ttl
mov esi, [esi + FRAGMENT_slot.ptr] mov esi, [esi + IPv4_FRAGMENT_slot.ptr]
or edi, -1 or edi, -1
.find_last_entry: ; The following routine will try to find the last entry .find_last_entry: ; The following routine will try to find the last entry
cmp edi, [esi + FRAGMENT_entry.PrevPtr] cmp edi, [esi + IPv4_FRAGMENT_entry.PrevPtr]
jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
mov edi, esi mov edi, esi
mov esi, [esi + FRAGMENT_entry.NextPtr] mov esi, [esi + IPv4_FRAGMENT_entry.NextPtr]
cmp esi, -1 cmp esi, -1
jne .find_last_entry jne .find_last_entry
; We found the last entry (pointer is now in edi) ; We found the last entry (pointer is now in edi)
; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure ; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure
pop eax ; pointer to packet pop eax ; pointer to packet
mov [edi + FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry mov [edi + IPv4_FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry
mov [eax + FRAGMENT_entry.NextPtr], -1 mov [eax + IPv4_FRAGMENT_entry.NextPtr], -1
mov [eax + FRAGMENT_entry.PrevPtr], edi mov [eax + IPv4_FRAGMENT_entry.PrevPtr], edi
mov [eax + FRAGMENT_entry.Owner], ebx mov [eax + IPv4_FRAGMENT_entry.Owner], ebx
add esp, 4 add esp, 4
ret ret
@ -363,29 +363,29 @@ IPv4_input: ; TODO: add IPv4
.is_first_fragment: .is_first_fragment:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: First fragment packet received!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: First fragment packet received!\n"
; try to locate a free slot.. ; try to locate a free slot..
mov ecx, MAX_FRAGMENTS mov ecx, IPv4_MAX_FRAGMENTS
mov esi, FRAGMENT_LIST mov esi, IPv4_FRAGMENT_LIST
.find_free_slot: .find_free_slot:
cmp word [esi + FRAGMENT_slot.ttl], 0 cmp word [esi + IPv4_FRAGMENT_slot.ttl], 0
je .found_free_slot je .found_free_slot
add esi, sizeof.FRAGMENT_slot add esi, sizeof.IPv4_FRAGMENT_slot
loop .find_free_slot loop .find_free_slot
jmp .dump ; If no free slot was found, dump the packet jmp .dump ; If no free slot was found, dump the packet
.found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure .found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure
mov [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl mov [esi + IPv4_FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl
mov ax, [edx + IPv4_header.Identification] mov ax, [edx + IPv4_header.Identification]
mov [esi + FRAGMENT_slot.id], ax mov [esi + IPv4_FRAGMENT_slot.id], ax
mov eax, [edx + IPv4_header.SourceAddress] mov eax, [edx + IPv4_header.SourceAddress]
mov [esi + FRAGMENT_slot.SrcIP], eax mov [esi + IPv4_FRAGMENT_slot.SrcIP], eax
mov eax, [edx + IPv4_header.DestinationAddress] mov eax, [edx + IPv4_header.DestinationAddress]
mov [esi + FRAGMENT_slot.DstIP], eax mov [esi + IPv4_FRAGMENT_slot.DstIP], eax
pop eax pop eax
mov [esi + FRAGMENT_slot.ptr], eax mov [esi + IPv4_FRAGMENT_slot.ptr], eax
; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure
mov [eax + FRAGMENT_entry.NextPtr], -1 mov [eax + IPv4_FRAGMENT_entry.NextPtr], -1
mov [eax + FRAGMENT_entry.PrevPtr], -1 mov [eax + IPv4_FRAGMENT_entry.PrevPtr], -1
mov [eax + FRAGMENT_entry.Owner], ebx mov [eax + IPv4_FRAGMENT_entry.Owner], ebx
add esp, 4 ; balance stack and exit add esp, 4 ; balance stack and exit
ret ret
@ -401,35 +401,35 @@ IPv4_input: ; TODO: add IPv4
cmp esi, -1 cmp esi, -1
je .dump je .dump
mov esi, [esi + FRAGMENT_slot.ptr] ; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer mov esi, [esi + IPv4_FRAGMENT_slot.ptr] ; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer
push esi push esi
xor eax, eax xor eax, eax
or edi, -1 or edi, -1
.count_bytes: .count_bytes:
cmp [esi + FRAGMENT_entry.PrevPtr], edi cmp [esi + IPv4_FRAGMENT_entry.PrevPtr], edi
jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
mov cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length mov cx, [esi + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length
xchg cl, ch xchg cl, ch
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx
add ax, cx add ax, cx
movzx cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length movzx cx, [esi + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length
and cx, 0x000F and cx, 0x000F
shl cx, 2 shl cx, 2
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Header size=%u\n", cx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Header size=%u\n", cx
sub ax, cx sub ax, cx
mov edi, esi mov edi, esi
mov esi, [esi + FRAGMENT_entry.NextPtr] mov esi, [esi + IPv4_FRAGMENT_entry.NextPtr]
cmp esi, -1 cmp esi, -1
jne .count_bytes jne .count_bytes
mov esi, [esp+4] mov esi, [esp+4]
mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code mov [edi + IPv4_FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code
mov [esi + FRAGMENT_entry.NextPtr], -1 mov [esi + IPv4_FRAGMENT_entry.NextPtr], -1
mov [esi + FRAGMENT_entry.PrevPtr], edi mov [esi + IPv4_FRAGMENT_entry.PrevPtr], edi
mov [esi + FRAGMENT_entry.Owner], ebx mov [esi + IPv4_FRAGMENT_entry.Owner], ebx
mov cx, [edx + IPv4_header.TotalLength] ; Note: This time we dont substract Header length mov cx, [edx + IPv4_header.TotalLength] ; Note: This time we dont substract Header length
xchg cl, ch xchg cl, ch
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx
add ax, cx add ax, cx
@ -454,18 +454,18 @@ IPv4_input: ; TODO: add IPv4
mov edx, [esp+4] ; Get pointer to first fragment entry back in edx mov edx, [esp+4] ; Get pointer to first fragment entry back in edx
.rebuild_packet_loop: .rebuild_packet_loop:
movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset movzx ecx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset
xchg cl, ch ; intel byte order xchg cl, ch ; intel byte order
shl cx, 3 ; multiply by 8 and clear first 3 bits shl cx, 3 ; multiply by 8 and clear first 3 bits
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Fragment offset=%u\n", cx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Fragment offset=%u\n", cx
lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment
movzx ebx, [edx + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment movzx ebx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment
and bx, 0x000F ; and bx, 0x000F ;
shl bx, 2 ; shl bx, 2 ;
lea esi, [edx + sizeof.FRAGMENT_entry] ; Set esi to the correct begin of fragment lea esi, [edx + sizeof.IPv4_FRAGMENT_entry] ; Set esi to the correct begin of fragment
movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment movzx ecx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment
xchg cl, ch ; intel byte order xchg cl, ch ; intel byte order
cmp edi, eax ; Is this packet the first fragment ? cmp edi, eax ; Is this packet the first fragment ?
@ -483,8 +483,8 @@ IPv4_input: ; TODO: add IPv4
push eax push eax
push edx ; Push pointer to fragment onto stack push edx ; Push pointer to fragment onto stack
mov ebx, [edx + FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet mov ebx, [edx + IPv4_FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet
mov edx, [edx + FRAGMENT_entry.NextPtr] ; Set edx to the next pointer mov edx, [edx + IPv4_FRAGMENT_entry.NextPtr] ; Set edx to the next pointer
call NET_packet_free ; free the previous fragment buffer (this uses the value from stack) call NET_packet_free ; free the previous fragment buffer (this uses the value from stack)
pop eax pop eax
cmp edx, -1 ; Check if it is last fragment in chain cmp edx, -1 ; Check if it is last fragment in chain
@ -527,19 +527,19 @@ IPv4_find_fragment_slot:
push eax ebx ecx edx push eax ebx ecx edx
mov ax, [edx + IPv4_header.Identification] mov ax, [edx + IPv4_header.Identification]
mov ecx, MAX_FRAGMENTS mov ecx, IPv4_MAX_FRAGMENTS
mov esi, FRAGMENT_LIST mov esi, IPv4_FRAGMENT_LIST
mov ebx, [edx + IPv4_header.SourceAddress] mov ebx, [edx + IPv4_header.SourceAddress]
mov edx, [edx + IPv4_header.DestinationAddress] mov edx, [edx + IPv4_header.DestinationAddress]
.find_slot: .find_slot:
cmp [esi + FRAGMENT_slot.id], ax cmp [esi + IPv4_FRAGMENT_slot.id], ax
jne .try_next jne .try_next
cmp [esi + FRAGMENT_slot.SrcIP], ebx cmp [esi + IPv4_FRAGMENT_slot.SrcIP], ebx
jne .try_next jne .try_next
cmp [esi + FRAGMENT_slot.DstIP], edx cmp [esi + IPv4_FRAGMENT_slot.DstIP], edx
je .found_slot je .found_slot
.try_next: .try_next:
add esi, sizeof.FRAGMENT_slot add esi, sizeof.IPv4_FRAGMENT_slot
loop .find_slot loop .find_slot
or esi, -1 or esi, -1
@ -552,17 +552,16 @@ IPv4_find_fragment_slot:
; ;
; IPv4_output ; IPv4_output
; ;
; IN: eax = dest ip ; IN: eax = Destination IP
; ebx = output device ptr/0 for automatic choice ; ecx = data length
; ecx = data length ; edx = Source IP
; 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
; ebx = pointer to device struct (needed for sending procedure) ; ebx = pointer to device struct (needed for sending procedure)
; ecx = unchanged (packet size of embedded data) ; ecx = unchanged (packet size of embedded data)
; edx = size of complete buffer ; edx = size of complete buffer
; edi = pointer to start of data (0 on error) ; edi = pointer to start of data (0 on error)
; ;
;------------------------------------------------------------------ ;------------------------------------------------------------------
align 4 align 4
@ -573,9 +572,9 @@ 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 edx di push ecx di eax
call IPv4_route ; outputs device number in edi, dest ip in eax, source IP in edx
call IPv4_route ; outputs device number in edi, dest ip in eax push edx
test edi, edi test edi, edi
jz .loopback jz .loopback
@ -586,12 +585,12 @@ IPv4_output:
push ebx ; push the mac onto the stack push ebx ; push the mac onto the stack
push ax push ax
inc [IP_packets_tx + edi] ; update stats inc [IPv4_packets_tx + edi] ; update stats
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 + 10 + 6] mov ecx, [esp + 6 + 8 + 2]
add ecx, sizeof.IPv4_header add ecx, sizeof.IPv4_header
mov di, ETHER_PROTO_IPv4 mov di, ETHER_PROTO_IPv4
call ETH_output call ETH_output
@ -605,12 +604,14 @@ IPv4_output:
mov [edi + IPv4_header.TotalLength], cx mov [edi + IPv4_header.TotalLength], cx
mov [edi + IPv4_header.Identification], 0 ; fragment id: FIXME mov [edi + IPv4_header.Identification], 0 ; fragment id: FIXME
mov [edi + IPv4_header.FlagsAndFragmentOffset], 0 mov [edi + IPv4_header.FlagsAndFragmentOffset], 0
pop word [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol
; [edi + IPv4_header.Protocol]
mov [edi + IPv4_header.HeaderChecksum], 0 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]
pop word[edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol
; [edi + IPv4_header.Protocol]
pop ecx pop ecx
IPv4_checksum edi IPv4_checksum edi
@ -677,7 +678,7 @@ IPv4_output_raw:
push ebx ; push the mac push ebx ; push the mac
push ax push ax
inc [IP_packets_tx + 4*edi] inc [IPv4_packets_tx + 4*edi]
mov ebx, [NET_DRV_LIST + 4*edi] mov ebx, [NET_DRV_LIST + 4*edi]
lea eax, [ebx + ETH_DEVICE.mac] lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp mov edx, esp
@ -857,40 +858,44 @@ IPv4_fragment:
; IPv4_route ; IPv4_route
; ;
; IN: eax = Destination IP ; IN: eax = Destination IP
; OUT: edi = device number*4 ; edx = Source IP
; eax = ip of gateway if nescessary, unchanged otherwise ; OUT: eax = Destination IP (or gateway IP)
; edx = Source IP
; edi = device number*4
; DESTROYED:
; ecx
; ;
;--------------------------------------------------------------------------- ;---------------------------------------------------------------------------
align 4 align 4
IPv4_route: IPv4_route: ; TODO: return error if no valid route found
cmp eax, 0xffffffff cmp eax, 0xffffffff
je .broadcast je .broadcast
xor edi, edi xor edi, edi
mov ecx, NET_DEVICES_MAX
.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 ecx, eax
and edx, [SUBNET_LIST+edi] and ecx, [SUBNET_LIST + edi]
cmp ebx, ecx
cmp ebx, edx je .got_it
jne .next
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi
ret
.next: .next:
add edi, 4 add edi, 4
dec ecx cmp edi, 4*NET_DEVICES_MAX
jnz .loop jb .loop
.invalid: mov eax, [GATEWAY_LIST + 4] ; TODO: let user (or a user space daemon) configure default route
mov eax, [GATEWAY_LIST+4] ;;; FIXME
.broadcast: .broadcast:
mov edi, 4 ; if none found, use device 1 as default ;;;; FIXME mov edi, 4 ; TODO: same as above
.got_it:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi
test edx, edx
jnz @f
mov edx, [IP_LIST + edi]
@@:
ret ret
@ -991,11 +996,11 @@ IPv4_api:
ret ret
.packets_tx: .packets_tx:
mov eax, [IP_packets_tx + eax] mov eax, [IPv4_packets_tx + eax]
ret ret
.packets_rx: .packets_rx:
mov eax, [IP_packets_rx + eax] mov eax, [IPv4_packets_rx + eax]
ret ret
.read_ip: .read_ip:

View File

@ -310,15 +310,16 @@ ICMP_input:
ret ret
if 0
;----------------------------------------------------------------- ;-----------------------------------------------------------------
; ;
; ICMP_output ; ICMP_output
; ;
; IN: eax = dest ip ; IN: eax = dest ip
; ebx = source ip ; bh = type
; bl = code
; ecx = data length ; ecx = data length
; dh = type ; edx = source ip
; dl = code
; esi = data offset ; esi = data offset
; edi = identifier shl 16 + sequence number ; edi = identifier shl 16 + sequence number
; ;
@ -328,10 +329,7 @@ ICMP_output:
DEBUGF DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet\n" DEBUGF DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet\n"
push esi edi dx push esi edi bx
mov edx, [eax + IP_SOCKET.LocalIP]
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
call IPv4_output call IPv4_output
@ -374,13 +372,14 @@ ICMP_output:
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n" DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
add esp, 2*4 + 2 add esp, 2*4 + 2
ret ret
end if
;----------------------------------------------------------------- ;-----------------------------------------------------------------
; ;
; ICMP_output ; ICMP_output_raw
; ;
; IN: eax = socket ptr ; IN: eax = socket ptr
; ecx = data length ; ecx = data length

View File

@ -421,6 +421,9 @@ SOCKET_bind:
cmp esi, 2 cmp esi, 2
jb .invalid jb .invalid
cmp [eax + UDP_SOCKET.LocalPort], 0 ; Socket can only be bound once
jnz .invalid
cmp word [edx], AF_INET4 cmp word [edx], AF_INET4
je .af_inet4 je .af_inet4
@ -456,17 +459,21 @@ SOCKET_bind:
.tcp: .tcp:
.udp: .udp:
mov ebx, [edx + 4] ; First, fill in the IP
test ebx, ebx ; If IP is 0, use default
jnz @f
mov ebx, [IP_LIST + 4] ;;;;; FIXME !i!i!i
@@:
mov [eax + IP_SOCKET.LocalIP], ebx
mov bx, [edx + 2] ; Now fill in the local port if it's still available pushd [edx + 4] ; First, fill in the IP
call SOCKET_check_port popd [eax + IP_SOCKET.LocalIP]
jz .addrinuse ; ZF is set by socket_check_port, on error
mov bx, [edx + 2] ; Did caller specify a local port?
test bx, bx
jnz .just_check
call SOCKET_find_port ; Nope, find an ephemeral one
jmp .done
.just_check:
call SOCKET_check_port ; Yes, check if it's still available
jz .addrinuse ; ZF is set by socket_check_port on error
.done:
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: local ip=%u.%u.%u.%u\n",\ DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: local ip=%u.%u.%u.%u\n",\
[eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\ [eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
[eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1 [eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1

View File

@ -437,8 +437,6 @@ TCP_send:
; Create the IP packet ; Create the IP packet
mov ecx, esi mov ecx, esi
mov ebx, [eax + SOCKET.device]
mov edx, [eax + IP_SOCKET.LocalIP] ; source ip 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

View File

@ -260,7 +260,6 @@ UDP_output:
sub esp, 8 ; Data ptr and data size will be placed here sub esp, 8 ; Data ptr and data size will be placed here
push edx esi push edx esi
mov ebx, [eax + SOCKET.device]
mov edx, [eax + IP_SOCKET.LocalIP] mov edx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP] mov eax, [eax + IP_SOCKET.RemoteIP]
mov di, IP_PROTO_UDP shl 8 + 128 mov di, IP_PROTO_UDP shl 8 + 128