forked from KolibriOS/kolibrios
Updates in net branch coded 6 months ago.
Mostly concerning checksuming, and cleanups git-svn-id: svn://kolibrios.org@1473 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
9ca8f38b9e
commit
c59969f41c
@ -113,85 +113,110 @@ IPv4_init:
|
|||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
IPv4_handler: ; TODO: clean up this mess
|
IPv4_handler: ; TODO: implement handler for IP options
|
||||||
; for instance, there should be only one piece of code wich make the jump to an underlying protocol, and not two..
|
|
||||||
; TODO2: add code for IPv4 sockets (raw sockets)
|
; TODO2: add code for IPv4 sockets (raw sockets)
|
||||||
|
|
||||||
DEBUGF 1,"IP_Handler - start\n"
|
DEBUGF 1,"IP_Handler - start\n"
|
||||||
|
|
||||||
push edx ebx
|
|
||||||
|
|
||||||
; save checksum, and clear it in original packet
|
;-------------------------------------------
|
||||||
mov di , [edx + IPv4_Packet.HeaderChecksum]
|
; Check if the packet still has time to live
|
||||||
mov word [edx + IPv4_Packet.HeaderChecksum], 0
|
|
||||||
|
|
||||||
; Re-calculate checksum
|
|
||||||
movzx ecx, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
|
|
||||||
and ecx, 0x0000000F ;
|
|
||||||
shl cx , 2 ;
|
|
||||||
mov esi, edx
|
|
||||||
xor edx, edx
|
|
||||||
call checksum_1
|
|
||||||
call checksum_2
|
|
||||||
|
|
||||||
; now compare the two..
|
|
||||||
cmp dx, di
|
|
||||||
pop ebx edx
|
|
||||||
jne .dump ; if checksum isn't valid then dump packet
|
|
||||||
|
|
||||||
DEBUGF 1,"IPv4 Checksum is correct\n",di
|
|
||||||
|
|
||||||
mov eax, [edx + IPv4_Packet.DestinationAddress]
|
|
||||||
mov edi, BROADCAST
|
|
||||||
mov ecx, MAX_IP+1
|
|
||||||
repnz scasd
|
|
||||||
jz .ip_ok
|
|
||||||
|
|
||||||
not eax
|
|
||||||
test eax, 127 shl 24 ; 127.x.x.x
|
|
||||||
jz .ip_ok
|
|
||||||
|
|
||||||
; TODO: we need to check for broadcasts (other then 255.255.255.255)
|
|
||||||
|
|
||||||
jmp .dump
|
|
||||||
|
|
||||||
.ip_ok:
|
|
||||||
call ETH_struc2dev ; TODO: make this work on other protocols too!
|
|
||||||
inc [IP_PACKETS_RX+4*edi]
|
|
||||||
DEBUGF 1,"packet comes from %u.%u.%u.%u\n",\
|
|
||||||
[edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1
|
|
||||||
|
|
||||||
mov al , [edx + IPv4_Packet.VersionAndIHL]
|
|
||||||
and al , 0x0f ; get IHL(header length)
|
|
||||||
cmp al , 0x05 ; IHL!= 5*4(20 bytes)
|
|
||||||
jnz .dump ; TODO: dont dump packets wich have optional fiels !!! /!\
|
|
||||||
|
|
||||||
cmp byte [edx + IPv4_Packet.TimeToLive], 0
|
cmp byte [edx + IPv4_Packet.TimeToLive], 0
|
||||||
je .dump
|
je .dump
|
||||||
|
|
||||||
movzx eax, word [edx + IPv4_Packet.FlagsAndFragmentOffset]
|
;--------------------------------------
|
||||||
xchg al , ah
|
; First, check if IP packet has options
|
||||||
|
|
||||||
test ax , 1 shl 13 ; Is 'more fragments' flag set ?
|
movzx eax, [edx + IPv4_Packet.VersionAndIHL]
|
||||||
jnz .yes_fragments ; If so, we definately have a fragmented packet
|
and al , 0x0f ; get IHL(header length)
|
||||||
|
cmp al , 0x05 ; IHL!= 5*4(20 bytes)
|
||||||
|
jnz .has_options
|
||||||
|
|
||||||
test ax , 0x1fff ; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets
|
|
||||||
jnz .last_fragment
|
|
||||||
|
|
||||||
.handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed
|
;-------------------------------
|
||||||
|
; Now, re-calcualte the checksum
|
||||||
|
|
||||||
|
; Re-calculate checksum
|
||||||
|
push edx ebx
|
||||||
|
mov esi, edx
|
||||||
|
call checksum_ip_header
|
||||||
|
pop ebx edx
|
||||||
|
|
||||||
|
; now see if it was correct
|
||||||
|
cmp [edx + IPv4_Packet.HeaderChecksum], 0
|
||||||
|
jne .dump ; if checksum isn't valid then dump packet
|
||||||
|
|
||||||
|
DEBUGF 1,"IPv4 Checksum is correct\n"
|
||||||
|
|
||||||
|
;-------------------------------------------------------
|
||||||
|
; Time to find out what interface this packet belongs to
|
||||||
|
|
||||||
|
; Therefore we will scan the current list of IP's
|
||||||
|
|
||||||
|
mov eax, [edx + IPv4_Packet.DestinationAddress]
|
||||||
|
mov edi, BROADCAST
|
||||||
|
mov ecx, MAX_IP+1
|
||||||
|
|
||||||
|
.find_ip_loop:
|
||||||
|
cmp eax, dword [edi]
|
||||||
|
jz .ip_ok
|
||||||
|
add edi, 4
|
||||||
|
dec ecx
|
||||||
|
jnz .find_ip_loop
|
||||||
|
|
||||||
|
; it was not on the list, perhaps it's a loopback ?
|
||||||
|
not eax
|
||||||
|
test eax, 127 shl 24 ; 127.x.x.x
|
||||||
|
jz .ip_ok
|
||||||
|
|
||||||
|
; TODO: we need to check for broadcasts (other then 255.255.255.255)
|
||||||
|
|
||||||
|
DEBUGF 2,"Destination address does not match!\n"
|
||||||
|
|
||||||
|
jmp .dump
|
||||||
|
|
||||||
|
|
||||||
|
;---------------------------------------------------
|
||||||
|
; Now we can update stats and find the device number
|
||||||
|
|
||||||
|
.ip_ok:
|
||||||
|
call ETH_struc2dev ; TODO: make this work on other protocols too!
|
||||||
|
inc [IP_PACKETS_RX+4*edi]
|
||||||
|
DEBUGF 1,"Packet comes from %u.%u.%u.%u\n",\
|
||||||
|
[edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;----------------------------------
|
||||||
|
; Check if the packet is fragmented
|
||||||
|
|
||||||
|
test [edx + IPv4_Packet.FlagsAndFragmentOffset], 1 shl 5 ; Is 'more fragments' flag set ?
|
||||||
|
jnz .has_fragments ; If so, we definately have a fragmented packet
|
||||||
|
|
||||||
|
test [edx + IPv4_Packet.FlagsAndFragmentOffset], 0xff1f ; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets
|
||||||
|
jnz .is_last_fragment
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------
|
||||||
|
; No, it's just a regular IP packet, pass it to the higher protocols
|
||||||
|
|
||||||
|
.handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed
|
||||||
movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
|
movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
|
||||||
and eax, 0x0000000F ;
|
and eax, 0x0000000F ;
|
||||||
shl eax, 2 ;
|
shl eax, 2 ;
|
||||||
|
|
||||||
movzx ecx, word [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet
|
movzx ecx, word [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet
|
||||||
xchg cl , ch ;
|
xchg cl , ch ;
|
||||||
sub ecx, eax ;
|
sub ecx, eax ;
|
||||||
|
|
||||||
add eax, edx
|
add eax, edx
|
||||||
push eax
|
push eax
|
||||||
|
|
||||||
|
mov esi, [edx + IPv4_Packet.SourceAddress] ; These values might be of interest to the higher protocols
|
||||||
|
mov edi, [edx + IPv4_Packet.DestinationAddress] ;
|
||||||
mov al , [edx + IPv4_Packet.Protocol]
|
mov al , [edx + IPv4_Packet.Protocol]
|
||||||
mov esi, [edx + IPv4_Packet.SourceAddress]
|
|
||||||
mov edi, [edx + IPv4_Packet.DestinationAddress]
|
|
||||||
pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
|
pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
|
||||||
|
|
||||||
cmp al , IP_PROTO_TCP
|
cmp al , IP_PROTO_TCP
|
||||||
@ -203,35 +228,79 @@ IPv4_handler: ; TODO: clean up this mess
|
|||||||
cmp al , IP_PROTO_ICMP
|
cmp al , IP_PROTO_ICMP
|
||||||
je ICMP_handler
|
je ICMP_handler
|
||||||
|
|
||||||
DEBUGF 1,"unknown protocol: %u\n",al
|
DEBUGF 2,"unknown Internet protocol: %u\n", al
|
||||||
|
|
||||||
.dump:
|
.dump:
|
||||||
DEBUGF 1,"IP_Handler - done\n"
|
DEBUGF 2,"IP_Handler - dumping\n"
|
||||||
; inc [dumped_rx_count]
|
; inc [dumped_rx_count]
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 4 ; pop (balance stack)
|
add esp, 4 ; pop (balance stack)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
.yes_fragments:
|
;---------------------------
|
||||||
|
; Fragmented packet handler
|
||||||
|
|
||||||
|
|
||||||
|
.has_fragments:
|
||||||
|
movzx eax, [edx + IPv4_Packet.FlagsAndFragmentOffset]
|
||||||
|
xchg al , ah
|
||||||
shl ax , 3
|
shl ax , 3
|
||||||
|
|
||||||
DEBUGF 1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_Packet.Identification]:4
|
DEBUGF 1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_Packet.Identification]:4
|
||||||
|
|
||||||
test ax , ax ; Is this the first packet of the fragment?
|
test ax , ax ; Is this the first packet of the fragment?
|
||||||
jnz .not_first_fragment
|
jz .is_first_fragment
|
||||||
|
|
||||||
|
|
||||||
|
;-------------------------------------------------------
|
||||||
|
; We have a fragmented IP packet, but it's not the first
|
||||||
|
|
||||||
|
DEBUGF 1,"Middle fragmented packet received!\n"
|
||||||
|
|
||||||
|
call IPv4_find_fragment_slot
|
||||||
|
cmp esi, -1
|
||||||
|
je .dump
|
||||||
|
|
||||||
|
mov word [esi + FRAGMENT_slot.ttl], 15 ; Reset the ttl
|
||||||
|
mov esi, [esi + FRAGMENT_slot.ptr]
|
||||||
|
or edi, -1
|
||||||
|
.find_last_entry: ; The following routine will try to find the last entry
|
||||||
|
cmp edi, [esi + FRAGMENT_entry.PrevPtr]
|
||||||
|
jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
|
||||||
|
mov edi, esi
|
||||||
|
mov esi, [esi + FRAGMENT_entry.NextPtr]
|
||||||
|
cmp esi, -1
|
||||||
|
jne .find_last_entry
|
||||||
|
; 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
|
||||||
|
|
||||||
|
pop eax ; pointer to packet
|
||||||
|
mov [edi + FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry
|
||||||
|
mov [eax + FRAGMENT_entry.NextPtr], -1
|
||||||
|
mov [eax + FRAGMENT_entry.PrevPtr], edi
|
||||||
|
mov [eax + FRAGMENT_entry.Owner], ebx
|
||||||
|
|
||||||
|
add esp, 4
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;------------------------------------
|
||||||
|
; We have received the first fragment
|
||||||
|
|
||||||
|
.is_first_fragment:
|
||||||
DEBUGF 1,"First fragmented packet received!\n"
|
DEBUGF 1,"First fragmented packet received!\n"
|
||||||
; try to locate a free slot..
|
; try to locate a free slot..
|
||||||
mov ecx, MAX_FRAGMENTS
|
mov ecx, MAX_FRAGMENTS
|
||||||
mov esi, FRAGMENT_LIST
|
mov esi, FRAGMENT_LIST
|
||||||
.find_free_slot:
|
.find_free_slot:
|
||||||
cmp word [esi + FRAGMENT_slot.ttl], 0
|
cmp word [esi + FRAGMENT_slot.ttl], 0
|
||||||
je .found_free_slot
|
je .found_free_slot
|
||||||
add esi, FRAGMENT_slot.size
|
add esi, FRAGMENT_slot.size
|
||||||
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 word [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl
|
mov word [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl
|
||||||
mov ax , word [edx + IPv4_Packet.Identification]
|
mov ax , word [edx + IPv4_Packet.Identification]
|
||||||
mov word [esi + FRAGMENT_slot.id], ax
|
mov word [esi + FRAGMENT_slot.id], ax
|
||||||
@ -250,51 +319,24 @@ IPv4_handler: ; TODO: clean up this mess
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;-----------------------------------
|
||||||
|
; We have received the last fragment
|
||||||
|
|
||||||
.not_first_fragment:
|
.is_last_fragment:
|
||||||
DEBUGF 1,"Middle fragmented packet received!\n"
|
|
||||||
|
|
||||||
call .find_fragment_slot
|
|
||||||
cmp esi, -1
|
|
||||||
je .dump
|
|
||||||
|
|
||||||
mov word [esi + FRAGMENT_slot.ttl], 15 ; Reset the ttl
|
|
||||||
mov esi, [esi + FRAGMENT_slot.ptr]
|
|
||||||
or edi, -1
|
|
||||||
.find_last_entry: ; The following routine will try to find the last entry
|
|
||||||
cmp edi, [esi + FRAGMENT_entry.PrevPtr]
|
|
||||||
jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
|
|
||||||
mov edi, esi
|
|
||||||
mov esi, [esi + FRAGMENT_entry.NextPtr]
|
|
||||||
cmp esi, -1
|
|
||||||
jne .find_last_entry
|
|
||||||
; We found the last entry (pointer is noww in edi)
|
|
||||||
; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure
|
|
||||||
|
|
||||||
pop eax ; pointer to packet
|
|
||||||
mov [edi + FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry
|
|
||||||
mov [eax + FRAGMENT_entry.NextPtr], -1
|
|
||||||
mov [eax + FRAGMENT_entry.PrevPtr], edi
|
|
||||||
mov [eax + FRAGMENT_entry.Owner], ebx
|
|
||||||
|
|
||||||
add esp, 4
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.last_fragment:
|
|
||||||
DEBUGF 1,"Last fragmented packet received!\n"
|
DEBUGF 1,"Last fragmented packet received!\n"
|
||||||
call .find_fragment_slot
|
|
||||||
|
call IPv4_find_fragment_slot
|
||||||
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 + 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 + 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, word [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Add total length
|
mov cx, word [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Add total length
|
||||||
xchg cl, ch
|
xchg cl, ch
|
||||||
DEBUGF 1,"Packet size: %u\n", cx
|
DEBUGF 1,"Packet size: %u\n", cx
|
||||||
@ -339,9 +381,9 @@ IPv4_handler: ; TODO: clean up this mess
|
|||||||
je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot
|
je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot
|
||||||
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, word [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset] ; Calculate the fragment offset
|
movzx ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.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 1,"Fragment offset: %u\n", cx
|
DEBUGF 1,"Fragment offset: %u\n", cx
|
||||||
|
|
||||||
@ -358,7 +400,7 @@ IPv4_handler: ; TODO: clean up this mess
|
|||||||
je .first_fragment
|
je .first_fragment
|
||||||
sub cx, bx ; If not, dont copy the header
|
sub cx, bx ; If not, dont copy the header
|
||||||
add esi, ebx ;
|
add esi, ebx ;
|
||||||
.first_fragment:
|
.first_fragment:
|
||||||
|
|
||||||
push cx ; First copy dword-wise, then byte-wise
|
push cx ; First copy dword-wise, then byte-wise
|
||||||
shr cx, 2 ;
|
shr cx, 2 ;
|
||||||
@ -369,6 +411,7 @@ IPv4_handler: ; TODO: clean up this mess
|
|||||||
|
|
||||||
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 edx, [edx + FRAGMENT_entry.NextPtr] ; Set edx to the next pointer
|
mov edx, [edx + FRAGMENT_entry.NextPtr] ; Set edx to the next pointer
|
||||||
call kernel_free ; free the previous fragment buffer (this uses the value from stack)
|
call kernel_free ; free the previous fragment buffer (this uses the value from stack)
|
||||||
pop eax
|
pop eax
|
||||||
@ -381,46 +424,19 @@ IPv4_handler: ; TODO: clean up this mess
|
|||||||
mov word [edx + IPv4_Packet.TotalLength], cx
|
mov word [edx + IPv4_Packet.TotalLength], cx
|
||||||
add esp, 8
|
add esp, 8
|
||||||
|
|
||||||
xchg cl, ch ; This prints the IP packet to the debug board (usefull when using serial output debug..)
|
xchg cl, ch ;
|
||||||
push ecx ;;;;
|
|
||||||
push eax ;;;;
|
push ecx ;;;;
|
||||||
; mov esi, edx ;
|
push eax ;;;;
|
||||||
|
|
||||||
|
; mov esi, edx ; This prints the IP packet to the debug board (usefull when using serial output debug..)
|
||||||
; ;
|
; ;
|
||||||
; @@: ;
|
; @@: ;
|
||||||
; lodsb ;
|
; lodsb ;
|
||||||
; DEBUGF 1,"%x ", eax:2 ;
|
; DEBUGF 1,"%x ", eax:2 ;
|
||||||
; loop @r ;
|
; loop @r ;
|
||||||
|
|
||||||
movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
|
jmp .handle_it ; edx = buf ptr, ecx = size, [esp] buf ptr, [esp+4], total size, ebx=device ptr
|
||||||
and ax, 0x000F ;
|
|
||||||
shl ax, 2 ;
|
|
||||||
|
|
||||||
sub ecx, eax
|
|
||||||
|
|
||||||
|
|
||||||
add eax, edx
|
|
||||||
push eax
|
|
||||||
mov al , [edx + IPv4_Packet.Protocol]
|
|
||||||
mov esi, [edx + IPv4_Packet.SourceAddress]
|
|
||||||
mov edi, [edx + IPv4_Packet.DestinationAddress]
|
|
||||||
pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
|
|
||||||
|
|
||||||
cmp al , IP_PROTO_TCP
|
|
||||||
je TCP_handler
|
|
||||||
|
|
||||||
cmp al , IP_PROTO_UDP
|
|
||||||
je UDP_handler
|
|
||||||
|
|
||||||
cmp al , IP_PROTO_ICMP
|
|
||||||
je ICMP_handler_fragments
|
|
||||||
|
|
||||||
DEBUGF 1,"IP_Handler - unknown protocol:%u\n",al
|
|
||||||
|
|
||||||
call kernel_free
|
|
||||||
add esp, 8 ; pop (balance stack)
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
.destroy_slot_pop:
|
.destroy_slot_pop:
|
||||||
add esp, 4
|
add esp, 4
|
||||||
@ -431,6 +447,18 @@ IPv4_handler: ; TODO: clean up this mess
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;-----------------------------------
|
||||||
|
; The IP packet has some options
|
||||||
|
|
||||||
|
.has_options:
|
||||||
|
jmp .dump
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; find fragment slot
|
; find fragment slot
|
||||||
@ -439,8 +467,8 @@ IPv4_handler: ; TODO: clean up this mess
|
|||||||
; OUT: pointer to slot in edi, -1 on error
|
; OUT: pointer to slot in edi, -1 on error
|
||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
|
align 4
|
||||||
.find_fragment_slot:
|
IPv4_find_fragment_slot:
|
||||||
|
|
||||||
push eax ebx ecx edx
|
push eax ebx ecx edx
|
||||||
mov ax , word [edx + IPv4_Packet.Identification]
|
mov ax , word [edx + IPv4_Packet.Identification]
|
||||||
@ -458,7 +486,7 @@ IPv4_handler: ; TODO: clean up this mess
|
|||||||
.try_next:
|
.try_next:
|
||||||
add esi, FRAGMENT_slot.size
|
add esi, FRAGMENT_slot.size
|
||||||
loop .find_slot
|
loop .find_slot
|
||||||
; pop edx ebx
|
; pop edx ebx
|
||||||
or esi, -1
|
or esi, -1
|
||||||
; ret
|
; ret
|
||||||
|
|
||||||
@ -581,15 +609,10 @@ IPv4_create_packet:
|
|||||||
pop ecx
|
pop ecx
|
||||||
mov [edi + IPv4_Packet.DestinationAddress], ecx
|
mov [edi + IPv4_Packet.DestinationAddress], ecx
|
||||||
|
|
||||||
push eax ebx edx
|
push eax edx esi
|
||||||
; calculate checksum
|
|
||||||
xor edx, edx
|
|
||||||
mov esi, edi
|
mov esi, edi
|
||||||
mov ecx, IPv4_Packet.DataOrOptional
|
call checksum_ip_header
|
||||||
call checksum_1
|
pop esi edx eax ecx
|
||||||
call checksum_2
|
|
||||||
mov [edi + IPv4_Packet.HeaderChecksum], dx
|
|
||||||
pop edx ebx eax ecx
|
|
||||||
add edi, IPv4_Packet.DataOrOptional
|
add edi, IPv4_Packet.DataOrOptional
|
||||||
|
|
||||||
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx
|
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx
|
||||||
@ -644,7 +667,7 @@ IPv4_dest_to_dev:
|
|||||||
.found_it:
|
.found_it:
|
||||||
shr edi, 2
|
shr edi, 2
|
||||||
|
|
||||||
DEBUGF 1,"%u\n",edi
|
DEBUGF 1,"%u\n",edi
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -705,59 +728,59 @@ IPv4_API:
|
|||||||
dec bl
|
dec bl
|
||||||
jz .write_gateway ; 9
|
jz .write_gateway ; 9
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
mov eax, -1
|
mov eax, -1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.packets_tx:
|
.packets_tx:
|
||||||
add eax, IP_PACKETS_TX
|
add eax, IP_PACKETS_TX
|
||||||
mov eax, [eax]
|
mov eax, [eax]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.packets_rx:
|
.packets_rx:
|
||||||
add eax, IP_PACKETS_RX
|
add eax, IP_PACKETS_RX
|
||||||
mov eax, [eax]
|
mov eax, [eax]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.read_ip:
|
.read_ip:
|
||||||
add eax, IP_LIST
|
add eax, IP_LIST
|
||||||
mov eax, [eax]
|
mov eax, [eax]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.write_ip:
|
.write_ip:
|
||||||
add eax, IP_LIST
|
add eax, IP_LIST
|
||||||
mov [eax], ecx
|
mov [eax], ecx
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.read_dns:
|
.read_dns:
|
||||||
add eax, DNS_LIST
|
add eax, DNS_LIST
|
||||||
mov eax, [eax]
|
mov eax, [eax]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.write_dns:
|
.write_dns:
|
||||||
add eax, DNS_LIST
|
add eax, DNS_LIST
|
||||||
mov [eax], ecx
|
mov [eax], ecx
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.read_subnet:
|
.read_subnet:
|
||||||
add eax, SUBNET_LIST
|
add eax, SUBNET_LIST
|
||||||
mov eax, [eax]
|
mov eax, [eax]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.write_subnet:
|
.write_subnet:
|
||||||
add eax, SUBNET_LIST
|
add eax, SUBNET_LIST
|
||||||
mov [eax], ecx
|
mov [eax], ecx
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.read_gateway:
|
.read_gateway:
|
||||||
add eax, GATEWAY_LIST
|
add eax, GATEWAY_LIST
|
||||||
mov eax, [eax]
|
mov eax, [eax]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.write_gateway:
|
.write_gateway:
|
||||||
add eax, GATEWAY_LIST
|
add eax, GATEWAY_LIST
|
||||||
mov [eax], ecx
|
mov [eax], ecx
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
|
@ -153,7 +153,7 @@ end if
|
|||||||
|
|
||||||
.error:
|
.error:
|
||||||
or eax, -1
|
or eax, -1
|
||||||
DEBUGF 1,"- fail\n"
|
DEBUGF 2,"Adding ETH device failed\n"
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -219,50 +219,56 @@ end if
|
|||||||
align 4
|
align 4
|
||||||
ETH_receiver:
|
ETH_receiver:
|
||||||
|
|
||||||
DEBUGF 1,"ETH_Receiver: "
|
; DEBUGF 1,"ETH_Receiver: "
|
||||||
push ebx
|
; push ebx
|
||||||
mov esi, esp
|
; mov esi, esp
|
||||||
add_to_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .fail
|
; add_to_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .fail
|
||||||
DEBUGF 1,"Queued packet successfully\n"
|
; DEBUGF 1,"Queued packet successfully\n"
|
||||||
add esp, 4*3
|
; add esp, 4*3
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
.fail:
|
|
||||||
DEBUGF 1,"ETH_IN_QUEUE is full!\n"
|
|
||||||
add esp, 4
|
|
||||||
call kernel_free
|
|
||||||
add esp, 4
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
|
||||||
;
|
;
|
||||||
; ETH_Handler:
|
; ret
|
||||||
;
|
;
|
||||||
; Handles all queued eth packets (called from kernel's main_loop)
|
; .fail:
|
||||||
|
; DEBUGF 1,"ETH_IN_QUEUE is full!\n"
|
||||||
|
; add esp, 4
|
||||||
|
; call kernel_free
|
||||||
|
; add esp, 4
|
||||||
;
|
;
|
||||||
; IN: /
|
; ret
|
||||||
; OUT: /
|
|
||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;
|
||||||
align 4
|
;
|
||||||
ETH_handler:
|
;;-----------------------------------------------------------------
|
||||||
|
;;
|
||||||
|
;; ETH_Handler:
|
||||||
|
;;
|
||||||
|
;; Handles all queued eth packets (called from kernel's main_loop)
|
||||||
|
;;
|
||||||
|
;; IN: /
|
||||||
|
;; OUT: /
|
||||||
|
;;
|
||||||
|
;;-----------------------------------------------------------------
|
||||||
|
;align 4
|
||||||
|
;ETH_handler:
|
||||||
|
;
|
||||||
|
; get_from_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .gohome
|
||||||
|
;
|
||||||
|
; push ETH_handler
|
||||||
|
;
|
||||||
|
; lodsd
|
||||||
|
; mov ebx, eax
|
||||||
|
; lodsd
|
||||||
|
; mov ecx, eax
|
||||||
|
; lodsd
|
||||||
|
; xchg eax, ecx
|
||||||
|
; push ecx
|
||||||
|
; push eax
|
||||||
|
|
||||||
get_from_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .gohome
|
|
||||||
|
|
||||||
push ETH_handler
|
;-----------------------------
|
||||||
|
mov eax, [esp]
|
||||||
lodsd
|
mov ecx, [esp+4]
|
||||||
mov ebx, eax
|
;-----------------------------
|
||||||
lodsd
|
|
||||||
mov ecx, eax
|
|
||||||
lodsd
|
|
||||||
xchg eax, ecx
|
|
||||||
push ecx
|
|
||||||
push eax
|
|
||||||
|
|
||||||
DEBUGF 1,"ETH_Handler - size: %u\n", ecx
|
DEBUGF 1,"ETH_Handler - size: %u\n", ecx
|
||||||
cmp ecx, 60 ; check packet length
|
cmp ecx, 60 ; check packet length
|
||||||
@ -278,10 +284,10 @@ ETH_handler:
|
|||||||
cmp ax, ETHER_ARP
|
cmp ax, ETHER_ARP
|
||||||
je ARP_handler
|
je ARP_handler
|
||||||
|
|
||||||
DEBUGF 1,"Unknown ethernet packet type %x\n", ax
|
DEBUGF 2,"Unknown ethernet packet type %x\n", ax
|
||||||
|
|
||||||
.dump:
|
.dump:
|
||||||
DEBUGF 1,"Dumping packet\n"
|
DEBUGF 2,"ETH_Handler - dumping\n"
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 4
|
add esp, 4
|
||||||
|
|
||||||
@ -290,6 +296,12 @@ ETH_handler:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
align 4
|
||||||
|
ETH_handler:
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; ETH_sender:
|
; ETH_sender:
|
||||||
@ -366,24 +378,29 @@ end if
|
|||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
ETH_struc2dev:
|
ETH_struc2dev:
|
||||||
push eax ecx
|
push ecx
|
||||||
|
|
||||||
mov eax, ebx
|
|
||||||
mov ecx, MAX_ETH_DEVICES
|
mov ecx, MAX_ETH_DEVICES
|
||||||
mov edi, ETH_DRV_LIST
|
mov edi, ETH_DRV_LIST
|
||||||
|
|
||||||
repne scasd
|
|
||||||
jnz .error
|
|
||||||
|
|
||||||
sub edi, ETH_DRV_LIST+4
|
.loop:
|
||||||
|
cmp ebx, [edi]
|
||||||
|
jz .found
|
||||||
|
add edi, 4
|
||||||
|
dec ecx
|
||||||
|
jnz .loop
|
||||||
|
|
||||||
|
or edi, -1
|
||||||
|
|
||||||
|
pop ecx
|
||||||
|
ret
|
||||||
|
|
||||||
|
.found:
|
||||||
|
sub edi, ETH_DRV_LIST
|
||||||
shr edi, 2
|
shr edi, 2
|
||||||
|
|
||||||
pop ecx eax
|
pop ecx
|
||||||
ret
|
|
||||||
.error:
|
|
||||||
or edi, -1
|
|
||||||
pop ecx eax
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -408,7 +425,7 @@ ETH_struc2dev:
|
|||||||
align 4
|
align 4
|
||||||
ETH_create_packet:
|
ETH_create_packet:
|
||||||
|
|
||||||
DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx
|
DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx
|
||||||
|
|
||||||
cmp ecx, 1500
|
cmp ecx, 1500
|
||||||
jg .exit
|
jg .exit
|
||||||
@ -448,17 +465,17 @@ ETH_create_packet:
|
|||||||
mov edx, 46 + ETH_FRAME.Data
|
mov edx, 46 + ETH_FRAME.Data
|
||||||
.continue:
|
.continue:
|
||||||
|
|
||||||
DEBUGF 1,"done: %x size:%u device:%x\n", eax, edx, ebx
|
DEBUGF 1,"done: %x size:%u device:%x\n", eax, edx, ebx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.pop_exit:
|
.pop_exit:
|
||||||
DEBUGF 1,"Out of ram space!!\n"
|
DEBUGF 2,"Out of ram space!!\n"
|
||||||
add esp, 18
|
add esp, 18
|
||||||
or edi,-1
|
or edi,-1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.exit:
|
.exit:
|
||||||
DEBUGF 1,"Packet too large!\n"
|
DEBUGF 2,"Packet too large!\n"
|
||||||
or edi, -1
|
or edi, -1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -146,10 +146,14 @@ ICMP_init:
|
|||||||
align 4
|
align 4
|
||||||
ICMP_handler: ;TODO: works only on pure ethernet right now !
|
ICMP_handler: ;TODO: works only on pure ethernet right now !
|
||||||
|
|
||||||
DEBUGF 1,"ICMP_Handler - start\n"
|
DEBUGF 1,"ICMP_Handler - buf:%x size:%x dev:%x, size:%x, buf:%x\n", [esp], [esp+4], ebx, ecx, edx
|
||||||
cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request?
|
cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request?
|
||||||
jne .check_sockets
|
jne .check_sockets
|
||||||
|
|
||||||
|
;;; TODO: check checksum!
|
||||||
|
|
||||||
|
DEBUGF 1,"ICMP_Handler - is echo request, through device:%x\n", ebx
|
||||||
|
|
||||||
mov byte [edx + ICMP_Packet.Type], ICMP_ECHOREPLY ; Change Packet type to reply
|
mov byte [edx + ICMP_Packet.Type], ICMP_ECHOREPLY ; Change Packet type to reply
|
||||||
mov word [edx + ICMP_Packet.Checksum], 0 ; Set checksum to 0, needed to calculate new checksum
|
mov word [edx + ICMP_Packet.Checksum], 0 ; Set checksum to 0, needed to calculate new checksum
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
$Revision$
|
$Revision$
|
||||||
|
|
||||||
struct SOCKET_head
|
struct SOCKET_head
|
||||||
.PrevPtr dd ? ; pointer to previous socket in list
|
|
||||||
.NextPtr dd ? ; pointer to next socket in list
|
.NextPtr dd ? ; pointer to next socket in list
|
||||||
|
.PrevPtr dd ? ; pointer to previous socket in list
|
||||||
.Number dd ? ; socket number (unique within single process)
|
.Number dd ? ; socket number (unique within single process)
|
||||||
.PID dd ? ; application process id
|
.PID dd ? ; application process id
|
||||||
.Domain dd ? ; INET/UNIX/..
|
.Domain dd ? ; INET/UNIX/..
|
||||||
@ -935,7 +935,7 @@ socket_check_port:
|
|||||||
align 4
|
align 4
|
||||||
socket_internal_receiver:
|
socket_internal_receiver:
|
||||||
|
|
||||||
DEBUGF 1,"Internal socket receiver: buffer %x, offset: %x size=%u socket: %x\n", esi, edi, ecx, eax
|
DEBUGF 1,"Internal socket receiver: buffer %x, offset: %x size=%u socket: %x\n", esi, edi, ecx, eax
|
||||||
|
|
||||||
push edi ; offset
|
push edi ; offset
|
||||||
push ecx ; size
|
push ecx ; size
|
||||||
@ -969,7 +969,7 @@ notify_network_event:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
.full:
|
.full:
|
||||||
DEBUGF 1,"Socket %x is full!\n",eax
|
DEBUGF 2,"Socket %x is full!\n",eax
|
||||||
mov [eax + SOCKET_head.lock], 0
|
mov [eax + SOCKET_head.lock], 0
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 8
|
add esp, 8
|
||||||
|
@ -19,18 +19,21 @@
|
|||||||
|
|
||||||
$Revision$
|
$Revision$
|
||||||
|
|
||||||
|
__DEBUG_LEVEL_OLD__ equ __DEBUG_LEVEL__
|
||||||
|
__DEBUG_LEVEL__ equ 1 ; this sets the debug level for network part of kernel
|
||||||
|
|
||||||
uglobal
|
uglobal
|
||||||
last_1sTick db ?
|
last_1sTick db ?
|
||||||
last_1hsTick dd ?
|
last_1hsTick dd ?
|
||||||
endg
|
endg
|
||||||
|
|
||||||
MAX_NET_DEVICES equ 16
|
MAX_NET_DEVICES equ 16
|
||||||
QUEUE_BEFORE_SENDING equ 1 ; 1 or 0 (enable or disable) currently only affects ethernet
|
QUEUE_BEFORE_SENDING equ 0 ; 1 or 0 (enable or disable) currently only affects ethernet
|
||||||
|
|
||||||
MIN_EPHEMERAL_PORT equ 49152
|
MIN_EPHEMERAL_PORT equ 49152
|
||||||
MAX_EPHEMERAL_PORT equ 61000
|
MAX_EPHEMERAL_PORT equ 61000
|
||||||
|
|
||||||
ETHER equ 1337 ; TODO: find another value for this (how does it work in posix ?)
|
ETHER equ 1337 ; TODO: find another value for this (how does it work in posix ?)
|
||||||
ETHER_ARP equ 0x0608
|
ETHER_ARP equ 0x0608
|
||||||
|
|
||||||
AF_UNSPEC equ 0
|
AF_UNSPEC equ 0
|
||||||
@ -207,35 +210,230 @@ end if
|
|||||||
;
|
;
|
||||||
; This is the first of two functions needed to calculate the TCP checksum.
|
; This is the first of two functions needed to calculate the TCP checksum.
|
||||||
;
|
;
|
||||||
; IN: edx = start offeset for semi-checksum
|
; IN: edx = start offset for semi-checksum
|
||||||
; esi = pointer to data
|
; esi = pointer to data
|
||||||
; ecx = data size
|
; ecx = data size
|
||||||
; OUT: edx = semi-checksum
|
; OUT: edx = semi-checksum
|
||||||
;
|
;
|
||||||
|
;
|
||||||
|
; Code was optimized by diamond
|
||||||
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
checksum_1:
|
checksum_1:
|
||||||
|
|
||||||
xor eax, eax
|
|
||||||
shr ecx, 1
|
shr ecx, 1
|
||||||
pushf
|
pushf
|
||||||
.loop:
|
jz .no_2
|
||||||
lodsw
|
|
||||||
xchg al, ah
|
|
||||||
add edx, eax
|
|
||||||
loop .loop
|
|
||||||
|
|
||||||
|
shr ecx, 1
|
||||||
|
pushf
|
||||||
|
jz .no_4
|
||||||
|
|
||||||
|
shr ecx, 1
|
||||||
|
pushf
|
||||||
|
jz .no_8
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
add dl, [esi+1]
|
||||||
|
adc dh, [esi+0]
|
||||||
|
|
||||||
|
adc dl, [esi+3]
|
||||||
|
adc dh, [esi+2]
|
||||||
|
|
||||||
|
adc dl, [esi+5]
|
||||||
|
adc dh, [esi+4]
|
||||||
|
|
||||||
|
adc dl, [esi+7]
|
||||||
|
adc dh, [esi+6]
|
||||||
|
|
||||||
|
adc edx, 0
|
||||||
|
add esi, 8
|
||||||
|
|
||||||
|
dec ecx
|
||||||
|
jnz .loop
|
||||||
|
|
||||||
|
adc edx, 0
|
||||||
|
|
||||||
|
.no_8:
|
||||||
|
popf
|
||||||
|
jnc .no_4
|
||||||
|
|
||||||
|
add dl, [esi+1]
|
||||||
|
adc dh, [esi+0]
|
||||||
|
|
||||||
|
adc dl, [esi+3]
|
||||||
|
adc dh, [esi+2]
|
||||||
|
|
||||||
|
adc edx, 0
|
||||||
|
add esi, 4
|
||||||
|
|
||||||
|
.no_4:
|
||||||
|
popf
|
||||||
|
jnc .no_2
|
||||||
|
|
||||||
|
add dl, [esi+1]
|
||||||
|
adc dh, [esi+0]
|
||||||
|
|
||||||
|
adc edx, 0
|
||||||
|
|
||||||
|
inc ecx
|
||||||
|
inc ecx
|
||||||
|
|
||||||
|
.no_2:
|
||||||
popf
|
popf
|
||||||
jnc .end
|
jnc .end
|
||||||
|
|
||||||
add dh, [esi]
|
add dh, [esi+0]
|
||||||
|
adc edx, 0
|
||||||
|
.end:
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;IN: 12 bytes of pseudoheader pushed onto the stack
|
||||||
|
; edx = start offset
|
||||||
|
;
|
||||||
|
; OUT: pseudochecksum in edx
|
||||||
|
|
||||||
|
|
||||||
|
align 4
|
||||||
|
checksum_pseudoheader:
|
||||||
|
|
||||||
|
add dl, [esp+5]
|
||||||
|
adc dh, [esp+4]
|
||||||
|
|
||||||
|
adc dl, [esp+7]
|
||||||
|
adc dh, [esp+6]
|
||||||
|
|
||||||
|
adc dl, [esp+9]
|
||||||
|
adc dh, [esp+8]
|
||||||
|
|
||||||
|
adc dl, [esp+11]
|
||||||
|
adc dh, [esp+10]
|
||||||
|
|
||||||
|
adc dl, [esp+13]
|
||||||
|
adc dh, [esp+12]
|
||||||
|
|
||||||
|
adc dl, [esp+15]
|
||||||
|
adc dh, [esp+14]
|
||||||
|
|
||||||
|
adc edx,0
|
||||||
|
ret 12
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
align 4
|
||||||
|
checksum_ip_header:
|
||||||
|
|
||||||
|
; This is the fast procedure to create or check a IP header without options
|
||||||
|
;
|
||||||
|
; To create a new checksum, the checksum field must be set to 0 before computation
|
||||||
|
;
|
||||||
|
; To check an existing checksum, leave the checksum as is, and it will be 0 after this procedure, if it was correct
|
||||||
|
|
||||||
|
xor edx, edx
|
||||||
|
|
||||||
|
add dl, [esi+1]
|
||||||
|
adc dh, [esi+0]
|
||||||
|
|
||||||
|
adc dl, [esi+3]
|
||||||
|
adc dh, [esi+2]
|
||||||
|
|
||||||
|
adc dl, [esi+5]
|
||||||
|
adc dh, [esi+4]
|
||||||
|
|
||||||
|
adc dl, [esi+7]
|
||||||
|
adc dh, [esi+6]
|
||||||
|
|
||||||
|
adc dl, [esi+9]
|
||||||
|
adc dh, [esi+8]
|
||||||
|
|
||||||
|
; we skip 11th and 12th byte, they are the checksum bytes and should be 0 for re-calculation
|
||||||
|
|
||||||
|
adc dl, [esi+13]
|
||||||
|
adc dh, [esi+12]
|
||||||
|
|
||||||
|
adc dl, [esi+15]
|
||||||
|
adc dh, [esi+14]
|
||||||
|
|
||||||
|
adc dl, [esi+17]
|
||||||
|
adc dh, [esi+16]
|
||||||
|
|
||||||
|
adc dl, [esi+19]
|
||||||
|
adc dh, [esi+18]
|
||||||
|
|
||||||
adc edx, 0
|
adc edx, 0
|
||||||
|
|
||||||
.end:
|
call checksum_2
|
||||||
|
|
||||||
|
neg word [esi+10] ; zero will stay zero so we jsut get the checksum
|
||||||
|
add word [esi+10], dx ; , else we will get (new checksum - old checksum) in the end, wich should be 0 :)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
align 4
|
||||||
|
checksum_udp:
|
||||||
|
|
||||||
|
; This is the fast procedure to create or check a IP header without options
|
||||||
|
;
|
||||||
|
; To create a new checksum, the checksum field must be set to 0 before computation
|
||||||
|
;
|
||||||
|
; To check an existing checksum, leave the checksum as is, and it will be 0 after this procedure, if it was correct
|
||||||
|
|
||||||
|
xor edx, edx
|
||||||
|
|
||||||
|
add dl, [esi+1]
|
||||||
|
adc dh, [esi+0]
|
||||||
|
|
||||||
|
adc dl, [esi+3]
|
||||||
|
adc dh, [esi+2]
|
||||||
|
|
||||||
|
adc dl, [esi+5]
|
||||||
|
adc dh, [esi+4]
|
||||||
|
|
||||||
|
adc dl, [esi+7]
|
||||||
|
adc dh, [esi+6]
|
||||||
|
|
||||||
|
adc dl, [esi+9]
|
||||||
|
adc dh, [esi+8]
|
||||||
|
|
||||||
|
; we skip 11th and 12th byte, they are the checksum bytes and should be 0 for re-calculation
|
||||||
|
|
||||||
|
adc dl, [esi+13]
|
||||||
|
adc dh, [esi+12]
|
||||||
|
|
||||||
|
adc dl, [esi+15]
|
||||||
|
adc dh, [esi+14]
|
||||||
|
|
||||||
|
adc dl, [esi+17]
|
||||||
|
adc dh, [esi+16]
|
||||||
|
|
||||||
|
adc dl, [esi+19]
|
||||||
|
adc dh, [esi+18]
|
||||||
|
|
||||||
|
adc edx, 0
|
||||||
|
|
||||||
|
call checksum_2
|
||||||
|
|
||||||
|
neg word [esi+10] ; zero will stay zero so we jsut get the checksum
|
||||||
|
add word [esi+10], dx ; , else we will get (new checksum - old checksum) in the end, wich should be 0 :)
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; checksum_2
|
; checksum_2
|
||||||
@ -400,3 +598,6 @@ sys_protocols:
|
|||||||
.return:
|
.return:
|
||||||
mov [esp+28+4], eax
|
mov [esp+28+4], eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
__DEBUG_LEVEL__ equ __DEBUG_LEVEL_OLD__
|
@ -139,10 +139,8 @@ TCP_decrease_socket_ttls:
|
|||||||
; scan through all the sockets, decrementing active timers
|
; scan through all the sockets, decrementing active timers
|
||||||
|
|
||||||
mov ebx, net_sockets
|
mov ebx, net_sockets
|
||||||
|
|
||||||
cmp [ebx + SOCKET_head.NextPtr], 0
|
cmp [ebx + SOCKET_head.NextPtr], 0
|
||||||
je .exit
|
je .exit
|
||||||
|
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov ebx, [ebx + SOCKET_head.NextPtr]
|
mov ebx, [ebx + SOCKET_head.NextPtr]
|
||||||
or ebx, ebx
|
or ebx, ebx
|
||||||
|
@ -74,35 +74,37 @@ UDP_init:
|
|||||||
align 4
|
align 4
|
||||||
UDP_handler:
|
UDP_handler:
|
||||||
|
|
||||||
DEBUGF 1,"UDP_Handler\n"
|
DEBUGF 1,"UDP_Handler\n"
|
||||||
|
|
||||||
|
cmp [edx + UDP_Packet.Checksum], 0
|
||||||
|
jz .no_checksum
|
||||||
; First validate, checksum:
|
; First validate, checksum:
|
||||||
|
|
||||||
pusha
|
pusha
|
||||||
|
|
||||||
rol cx, 8
|
|
||||||
push cx
|
push cx
|
||||||
rol cx, 8
|
rol word [esp], 8
|
||||||
push word IP_PROTO_UDP shl 8
|
push word IP_PROTO_UDP shl 8
|
||||||
push edi
|
push edi
|
||||||
push esi
|
push esi
|
||||||
|
|
||||||
mov di, [edx + UDP_Packet.Checksum]
|
mov di, [edx + UDP_Packet.Checksum]
|
||||||
mov [edx + UDP_Packet.Checksum], 0
|
mov [edx + UDP_Packet.Checksum], 0
|
||||||
|
|
||||||
mov esi, edx
|
mov esi, edx
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
call checksum_1
|
call checksum_1
|
||||||
mov ecx, 12
|
call checksum_pseudoheader
|
||||||
mov esi, esp
|
|
||||||
call checksum_1
|
|
||||||
add esp, 12
|
|
||||||
call checksum_2
|
call checksum_2
|
||||||
|
|
||||||
cmp di, dx
|
cmp di, dx
|
||||||
popa
|
popa
|
||||||
jne .dump
|
jne .checksum_mismatch ;dump
|
||||||
|
|
||||||
DEBUGF 1,"UDP Checksum is correct\n"
|
|
||||||
|
.no_checksum:
|
||||||
|
|
||||||
|
DEBUGF 1,"UDP Checksum is correct\n"
|
||||||
|
|
||||||
; Look for a socket where
|
; Look for a socket where
|
||||||
; IP Packet UDP Destination Port = local Port
|
; IP Packet UDP Destination Port = local Port
|
||||||
@ -110,7 +112,7 @@ UDP_handler:
|
|||||||
|
|
||||||
mov eax, net_sockets
|
mov eax, net_sockets
|
||||||
.try_more:
|
.try_more:
|
||||||
mov bx , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header
|
mov si , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov eax, [eax + SOCKET_head.NextPtr]
|
mov eax, [eax + SOCKET_head.NextPtr]
|
||||||
or eax, eax
|
or eax, eax
|
||||||
@ -119,10 +121,10 @@ UDP_handler:
|
|||||||
jne .next_socket
|
jne .next_socket
|
||||||
cmp [eax + SOCKET_head.Type], IP_PROTO_UDP
|
cmp [eax + SOCKET_head.Type], IP_PROTO_UDP
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], si
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
|
|
||||||
DEBUGF 1,"found socket with matching domain, type and localport\n"
|
DEBUGF 1,"found socket with matching domain, type and localport\n"
|
||||||
|
|
||||||
; For dhcp, we must allow any remote server to respond.
|
; For dhcp, we must allow any remote server to respond.
|
||||||
; I will accept the first incoming response to be the one
|
; I will accept the first incoming response to be the one
|
||||||
@ -131,28 +133,30 @@ UDP_handler:
|
|||||||
cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0xffffffff
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0xffffffff
|
||||||
je .ok1
|
je .ok1
|
||||||
|
|
||||||
mov ebx, [esp]
|
mov esi, [esp]
|
||||||
mov ebx, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet FIXME
|
mov esi, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet FIXME
|
||||||
cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], esi
|
||||||
jne .try_more ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
|
jne .try_more ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
|
||||||
|
|
||||||
|
|
||||||
DEBUGF 1,"Remote Ip matches\n"
|
DEBUGF 1,"Remote Ip matches\n"
|
||||||
.ok1:
|
.ok1:
|
||||||
|
|
||||||
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket], 0
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket], 0
|
||||||
jz .updateport
|
jz .updateport
|
||||||
|
|
||||||
mov bx, [edx + UDP_Packet.SourcePort]
|
mov si, [edx + UDP_Packet.SourcePort]
|
||||||
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], si
|
||||||
jne .dump
|
jne .dump
|
||||||
|
|
||||||
|
push ebx
|
||||||
lea ebx, [eax + SOCKET_head.lock]
|
lea ebx, [eax + SOCKET_head.lock]
|
||||||
call wait_mutex
|
call wait_mutex
|
||||||
|
pop ebx
|
||||||
|
|
||||||
.ok2:
|
.ok2:
|
||||||
|
|
||||||
DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
|
DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
|
||||||
lea esi, [edx + UDP_Packet.Data]
|
lea esi, [edx + UDP_Packet.Data]
|
||||||
movzx ecx, [edx + UDP_Packet.Length]
|
movzx ecx, [edx + UDP_Packet.Length]
|
||||||
rol cx , 8
|
rol cx , 8
|
||||||
@ -170,20 +174,33 @@ UDP_handler:
|
|||||||
|
|
||||||
.updateport:
|
.updateport:
|
||||||
|
|
||||||
|
push ebx
|
||||||
lea ebx, [eax + SOCKET_head.lock]
|
lea ebx, [eax + SOCKET_head.lock]
|
||||||
call wait_mutex
|
call wait_mutex
|
||||||
|
pop ebx
|
||||||
|
|
||||||
mov bx, [edx + UDP_Packet.SourcePort]
|
mov si, [edx + UDP_Packet.SourcePort]
|
||||||
DEBUGF 1,"Changing remote port to: %x\n", bx
|
DEBUGF 1,"Changing remote port to: %x\n", si
|
||||||
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
|
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], si
|
||||||
inc [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket]
|
inc [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket]
|
||||||
|
|
||||||
jmp .ok2
|
jmp .ok2
|
||||||
|
|
||||||
|
.checksum_mismatch:
|
||||||
|
|
||||||
|
DEBUGF 2,"UDP_Handler - checksum mismatch\n"
|
||||||
|
|
||||||
|
mov esi, [esp]
|
||||||
|
mov ecx, [esp + 4]
|
||||||
|
@@: ;
|
||||||
|
lodsb ;
|
||||||
|
DEBUGF 2,"%x ", eax:2 ;
|
||||||
|
loop @r ;
|
||||||
|
|
||||||
.dump:
|
.dump:
|
||||||
DEBUGF 1,"Dumping UDP packet\n"
|
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 4 ; pop (balance stack)
|
add esp, 4 ; pop (balance stack)
|
||||||
|
DEBUGF 2,"UDP_Handler - dumping\n"
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -210,15 +227,12 @@ UDP_socket_send:
|
|||||||
mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
|
mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
|
||||||
mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
|
mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
|
||||||
|
|
||||||
DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
|
DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
|
||||||
|
|
||||||
mov di , IP_PROTO_UDP
|
mov di , IP_PROTO_UDP
|
||||||
|
|
||||||
sub esp, 8 ; reserve some place in stack for later
|
sub esp, 8 ; reserve some place in stack for later
|
||||||
|
; Create a part of the pseudoheader in stack,
|
||||||
; Create a part pseudoheader in stack,
|
|
||||||
push dword IP_PROTO_UDP shl 8
|
push dword IP_PROTO_UDP shl 8
|
||||||
|
|
||||||
add ecx, UDP_Packet.Data
|
add ecx, UDP_Packet.Data
|
||||||
|
|
||||||
; TODO: fill in: dx = fragment id
|
; TODO: fill in: dx = fragment id
|
||||||
@ -257,17 +271,14 @@ UDP_socket_send:
|
|||||||
; Checksum for pseudoheader
|
; Checksum for pseudoheader
|
||||||
pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options..
|
pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options..
|
||||||
pushd [edi-8] ; source address
|
pushd [edi-8] ; source address
|
||||||
mov ecx, 12
|
call checksum_pseudoheader
|
||||||
mov esi, esp
|
|
||||||
call checksum_1
|
|
||||||
add esp, 12 ; remove the pseudoheader from stack
|
|
||||||
; Now create the final checksum and store it in UDP header
|
; Now create the final checksum and store it in UDP header
|
||||||
call checksum_2
|
call checksum_2
|
||||||
mov [edi + UDP_Packet.Checksum], dx
|
mov [edi + UDP_Packet.Checksum], dx
|
||||||
|
|
||||||
inc [UDP_PACKETS_TX]
|
inc [UDP_PACKETS_TX]
|
||||||
|
|
||||||
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx ;
|
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx ;
|
||||||
jmp ETH_sender ;
|
jmp ETH_sender ;
|
||||||
|
|
||||||
.fail:
|
.fail:
|
||||||
|
Loading…
Reference in New Issue
Block a user