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 ;; |
;; ;; |
;; IPv4.INC ;; |
52,7 → 52,7 |
PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet) |
NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet) |
Owner dd ? ; Pointer to structure of driver |
rb 2 ; to match ethernet header size ; TODO: fix this hack |
rb 2 ; to match ethernet header size ;;; FIXME |
; Ip header begins here (we will need the IP header to re-construct the complete packet) |
ends |
|
64,6 → 64,7 |
SUBNET_LIST rd MAX_IP |
DNS_LIST rd MAX_IP |
GATEWAY_LIST rd MAX_IP |
BROADCAST_LIST rd MAX_IP |
|
IP_PACKETS_TX rd MAX_IP |
IP_PACKETS_RX rd MAX_IP |
83,13 → 84,9 |
|
xor eax, eax |
mov edi, IP_LIST |
mov ecx, 4*MAX_IP |
mov ecx, 7*MAX_IP + (sizeof.FRAGMENT_slot*MAX_FRAGMENTS)/4 |
rep stosd |
|
mov edi, FRAGMENT_LIST |
mov ecx, sizeof.FRAGMENT_slot*MAX_FRAGMENTS/4 + 2*MAX_IP |
rep stosd |
|
} |
|
|
100,20 → 97,27 |
;----------------------------------------------------------------- |
macro IPv4_decrease_fragment_ttls { |
|
local .loop |
local .loop, .next |
|
mov esi, FRAGMENT_LIST |
mov ecx, MAX_FRAGMENTS |
.loop: |
cmp [esi + FRAGMENT_slot.ttl], 0 |
je .try_next |
je .next |
dec [esi + FRAGMENT_slot.ttl] |
jnz .try_next |
jz .died |
.next: |
add esi, sizeof.FRAGMENT_slot |
dec ecx |
jnz .loop |
jmp .done |
|
.died: |
DEBUGF 1,"Fragment slot timed-out!\n" |
;;; TODO: clear all entry's of timed-out slot |
.try_next: |
add esi, 4 |
loop .loop |
jmp .next |
|
.done: |
} |
|
|
186,7 → 190,7 |
; |
; IPv4_input: |
; |
; Will check if IP Packet isnt damaged |
; Will check if IPv4 Packet isnt damaged |
; and call appropriate handler. (TCP/UDP/ICMP/..) |
; |
; It will also re-construct fragmented packets |
194,27 → 198,23 |
; IN: Pointer to buffer in [esp] |
; size of buffer in [esp+4] |
; pointer to device struct in ebx |
; pointer to IP header in edx |
; size of IP packet in ecx |
; pointer to IPv4 header in edx |
; size of IPv4 packet in ecx |
; OUT: / |
; |
;----------------------------------------------------------------- |
align 4 |
IPv4_input: ; TODO: add code for raw sockets |
IPv4_input: ; TODO: add IPv4 raw sockets support |
|
DEBUGF 1,"IPv4_input, packet from: %u.%u.%u.%u ",\ |
[edx + IPv4_header.SourceAddress]:1,[edx + IPv4_header.SourceAddress + 1]:1,[edx + IPv4_header.SourceAddress + 2]:1,[edx + IPv4_header.SourceAddress + 3]:1 |
[edx + IPv4_header.SourceAddress + 0]:1,[edx + IPv4_header.SourceAddress + 1]:1,\ |
[edx + IPv4_header.SourceAddress + 2]:1,[edx + IPv4_header.SourceAddress + 3]:1 |
DEBUGF 1,"to: %u.%u.%u.%u\n",\ |
[edx + IPv4_header.DestinationAddress]:1,[edx + IPv4_header.DestinationAddress + 1]:1,[edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1 |
[edx + IPv4_header.DestinationAddress + 0]:1,[edx + IPv4_header.DestinationAddress + 1]:1,\ |
[edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1 |
|
;------------------------------------------- |
; Check if the packet still has time to live |
|
cmp byte [edx + IPv4_header.TimeToLive], 0 |
je .dump |
|
;------------------------------- |
; Now, re-calculate the checksum |
; re-calculate the checksum |
|
IPv4_checksum edx |
jnz .dump ; if checksum isn't valid then dump packet |
229,38 → 229,35 |
|
; check if it matches local ip |
|
mov eax, [IP_LIST+edi] |
cmp [edx + IPv4_header.DestinationAddress], eax |
mov eax, [edx + IPv4_header.DestinationAddress] |
cmp eax, [IP_LIST+edi] |
je .ip_ok |
|
; check for broadcast |
; check for broadcast (IP or (not SUBNET)) |
|
mov eax, [SUBNET_LIST+edi] |
not eax |
or eax, [IP_LIST+edi] |
cmp [edx + IPv4_header.DestinationAddress], eax |
cmp eax, [BROADCAST_LIST+edi] |
je .ip_ok |
|
; or a special broadcast |
; or a special broadcast (255.255.255.255) |
|
cmp [edx + IPv4_header.DestinationAddress], -1 |
cmp eax, 0xffffffff |
je .ip_ok |
|
; maybe it's a multicast then |
; maybe it's a multicast (224.0.0.0/4) |
|
mov eax, [edx + IPv4_header.DestinationAddress] |
and eax, 0xff000000 |
; cmp eax, 224 shl 24 |
; je .ip_ok |
and eax, 0x0fffffff |
cmp eax, 224 |
je .ip_ok |
|
; or a loopback address |
; or a loopback address (127.0.0.0/8) |
|
cmp eax, 127 shl 24 |
and eax, 0x00ffffff |
cmp eax, 127 |
je .ip_ok |
|
; or it's not meant for us.. |
; or it's just not meant for us.. :( |
|
DEBUGF 2,"Destination address does not match!\n" |
DEBUGF 2,"IPv4_input - Destination address does not match!\n" |
jmp .dump |
|
;------------------------ |
304,10 → 301,10 |
cmp al, IP_PROTO_ICMP |
je ICMP_input |
|
DEBUGF 2,"unknown Internet protocol: %u\n", al |
DEBUGF 2,"IPv4_input - unknown protocol: %u\n", al |
|
.dump: |
DEBUGF 2,"IP_Handler - dumping\n" |
DEBUGF 2,"IPv4_input - dumping\n" |
; inc [dumped_rx_count] |
call kernel_free |
add esp, 4 ; pop (balance stack) |
499,16 → 496,10 |
mov edx, eax |
mov [edx + IPv4_header.TotalLength], cx |
add esp, 8 |
xchg cl, ch |
push ecx |
|
xchg cl, ch ; |
|
push ecx ;;;; |
push eax ;;;; |
|
; mov esi, edx ; This prints the IP packet to the debug board (usefull when using serial output debug..) |
; ; |
; packet_to_debug |
|
push eax |
jmp .handle_it ; edx = buf ptr, ecx = size, [esp] buf ptr, [esp+4], total size, ebx=device ptr |
|
.destroy_slot_pop: |
527,7 → 518,7 |
; find fragment slot |
; |
; IN: pointer to fragmented packet in edx |
; OUT: pointer to slot in edi, -1 on error |
; OUT: pointer to slot in esi, -1 on error |
; |
;----------------------------------------------------------------- |
align 4 |
885,7 → 876,8 |
je .found_it |
.next: |
add edi, 4 |
loop .loop |
dec ecx |
jnz .loop |
|
.invalid: |
xor edi, edi ; if none found, use device 0 as default device |
967,6 → 959,13 |
|
.write_ip: |
mov [IP_LIST + eax], ecx |
|
; pre-calculate the local broadcast address |
mov ebx, [SUBNET_LIST + eax] |
not ebx |
or ecx, ebx |
mov [BROADCAST_LIST + eax], ecx |
|
xor eax, eax |
ret |
|
985,6 → 984,13 |
|
.write_subnet: |
mov [SUBNET_LIST + eax], ecx |
|
; pre-calculate the local broadcast address |
mov ebx, [IP_LIST + eax] |
not ecx |
or ecx, ebx |
mov [BROADCAST_LIST + eax], ecx |
|
xor eax, eax |
ret |
|