/kernel/branches/net/network/IPv4.inc |
---|
113,40 → 113,59 |
; |
;----------------------------------------------------------------- |
align 4 |
IPv4_handler: ; TODO: clean up this mess |
; for instance, there should be only one piece of code wich make the jump to an underlying protocol, and not two.. |
IPv4_handler: ; TODO: implement handler for IP options |
; TODO2: add code for IPv4 sockets (raw sockets) |
DEBUGF 1,"IP_Handler - start\n" |
push edx ebx |
; save checksum, and clear it in original packet |
mov di , [edx + IPv4_Packet.HeaderChecksum] |
mov word [edx + IPv4_Packet.HeaderChecksum], 0 |
;------------------------------------------- |
; Check if the packet still has time to live |
cmp byte [edx + IPv4_Packet.TimeToLive], 0 |
je .dump |
;-------------------------------------- |
; First, check if IP packet has options |
movzx eax, [edx + IPv4_Packet.VersionAndIHL] |
and al , 0x0f ; get IHL(header length) |
cmp al , 0x05 ; IHL!= 5*4(20 bytes) |
jnz .has_options |
;------------------------------- |
; Now, re-calcualte the checksum |
; Re-calculate checksum |
movzx ecx, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
and ecx, 0x0000000F ; |
shl cx , 2 ; |
push edx ebx |
mov esi, edx |
xor edx, edx |
call checksum_1 |
call checksum_2 |
call checksum_ip_header |
pop ebx edx |
; now compare the two.. |
cmp dx, di |
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",di |
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 |
repnz scasd |
.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 |
153,36 → 172,41 |
; 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",\ |
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 |
je .dump |
movzx eax, word [edx + IPv4_Packet.FlagsAndFragmentOffset] |
xchg al , ah |
test ax , 1 shl 13 ; Is 'more fragments' flag set ? |
jnz .yes_fragments ; If so, we definately have a fragmented packet |
;---------------------------------- |
; Check if the packet is fragmented |
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 |
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 |
and eax, 0x0000000F ; |
shl eax, 2 ; |
movzx ecx, word [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet |
xchg cl , ch ; |
sub ecx, eax ; |
189,9 → 213,10 |
add eax, edx |
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 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 |
203,10 → 228,10 |
cmp al , IP_PROTO_ICMP |
je ICMP_handler |
DEBUGF 1,"unknown protocol: %u\n",al |
DEBUGF 2,"unknown Internet protocol: %u\n", al |
.dump: |
DEBUGF 1,"IP_Handler - done\n" |
DEBUGF 2,"IP_Handler - dumping\n" |
; inc [dumped_rx_count] |
call kernel_free |
add esp, 4 ; pop (balance stack) |
213,13 → 238,57 |
ret |
.yes_fragments: |
;--------------------------- |
; Fragmented packet handler |
.has_fragments: |
movzx eax, [edx + IPv4_Packet.FlagsAndFragmentOffset] |
xchg al , ah |
shl ax , 3 |
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? |
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" |
; try to locate a free slot.. |
mov ecx, MAX_FRAGMENTS |
250,48 → 319,21 |
ret |
;----------------------------------- |
; We have received the last fragment |
.not_first_fragment: |
DEBUGF 1,"Middle fragmented packet received!\n" |
.is_last_fragment: |
DEBUGF 1,"Last fragmented packet received!\n" |
call .find_fragment_slot |
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 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" |
call .find_fragment_slot |
cmp esi, -1 |
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 |
push esi |
xor eax, eax ; |
xor eax, eax |
or edi, -1 |
.count_bytes: |
cmp [esi + FRAGMENT_entry.PrevPtr], edi |
jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
369,6 → 411,7 |
push eax |
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 |
call kernel_free ; free the previous fragment buffer (this uses the value from stack) |
pop eax |
381,10 → 424,12 |
mov word [edx + IPv4_Packet.TotalLength], cx |
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 ;;;; |
; mov esi, edx ; |
; mov esi, edx ; This prints the IP packet to the debug board (usefull when using serial output debug..) |
; ; |
; @@: ; |
; lodsb ; |
391,46 → 436,29 |
; DEBUGF 1,"%x ", eax:2 ; |
; loop @r ; |
movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
and ax, 0x000F ; |
shl ax, 2 ; |
jmp .handle_it ; edx = buf ptr, ecx = size, [esp] buf ptr, [esp+4], total size, ebx=device ptr |
sub ecx, eax |
.destroy_slot_pop: |
add esp, 4 |
.destroy_slot: |
DEBUGF 1,"Destroy fragment slot!\n" |
; TODO! |
jmp .dump |
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 |
;----------------------------------- |
; The IP packet has some options |
cmp al , IP_PROTO_ICMP |
je ICMP_handler_fragments |
.has_options: |
jmp .dump |
DEBUGF 1,"IP_Handler - unknown protocol:%u\n",al |
call kernel_free |
add esp, 8 ; pop (balance stack) |
ret |
.destroy_slot_pop: |
add esp, 4 |
.destroy_slot: |
DEBUGF 1,"Destroy fragment slot!\n" |
; TODO! |
jmp .dump |
;----------------------------------------------------------------- |
; |
; find fragment slot |
439,9 → 467,9 |
; OUT: pointer to slot in edi, -1 on error |
; |
;----------------------------------------------------------------- |
align 4 |
IPv4_find_fragment_slot: |
.find_fragment_slot: |
push eax ebx ecx edx |
mov ax , word [edx + IPv4_Packet.Identification] |
mov ecx, MAX_FRAGMENTS |
581,15 → 609,10 |
pop ecx |
mov [edi + IPv4_Packet.DestinationAddress], ecx |
push eax ebx edx |
; calculate checksum |
xor edx, edx |
push eax edx esi |
mov esi, edi |
mov ecx, IPv4_Packet.DataOrOptional |
call checksum_1 |
call checksum_2 |
mov [edi + IPv4_Packet.HeaderChecksum], dx |
pop edx ebx eax ecx |
call checksum_ip_header |
pop esi edx eax ecx |
add edi, IPv4_Packet.DataOrOptional |
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx |
/kernel/branches/net/network/ethernet.inc |
---|
153,7 → 153,7 |
.error: |
or eax, -1 |
DEBUGF 1,"- fail\n" |
DEBUGF 2,"Adding ETH device failed\n" |
ret |
219,51 → 219,57 |
align 4 |
ETH_receiver: |
DEBUGF 1,"ETH_Receiver: " |
push ebx |
mov esi, esp |
add_to_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .fail |
DEBUGF 1,"Queued packet successfully\n" |
add esp, 4*3 |
ret |
.fail: |
DEBUGF 1,"ETH_IN_QUEUE is full!\n" |
add esp, 4 |
call kernel_free |
add esp, 4 |
ret |
;----------------------------------------------------------------- |
; DEBUGF 1,"ETH_Receiver: " |
; push ebx |
; mov esi, esp |
; add_to_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .fail |
; DEBUGF 1,"Queued packet successfully\n" |
; add esp, 4*3 |
; |
; 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: / |
; OUT: / |
; ret |
; |
;----------------------------------------------------------------- |
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] |
mov ecx, [esp+4] |
;----------------------------- |
lodsd |
mov ebx, eax |
lodsd |
mov ecx, eax |
lodsd |
xchg eax, ecx |
push ecx |
push eax |
DEBUGF 1,"ETH_Handler - size: %u\n", ecx |
cmp ecx, 60 ; check packet length |
jl .dump |
278,10 → 284,10 |
cmp ax, ETHER_ARP |
je ARP_handler |
DEBUGF 1,"Unknown ethernet packet type %x\n", ax |
DEBUGF 2,"Unknown ethernet packet type %x\n", ax |
.dump: |
DEBUGF 1,"Dumping packet\n" |
DEBUGF 2,"ETH_Handler - dumping\n" |
call kernel_free |
add esp, 4 |
290,6 → 296,12 |
align 4 |
ETH_handler: |
ret |
;----------------------------------------------------------------- |
; |
; ETH_sender: |
366,27 → 378,32 |
;----------------------------------------------------------------- |
align 4 |
ETH_struc2dev: |
push eax ecx |
push ecx |
mov eax, ebx |
mov ecx, MAX_ETH_DEVICES |
mov edi, ETH_DRV_LIST |
repne scasd |
jnz .error |
sub edi, ETH_DRV_LIST+4 |
shr edi, 2 |
.loop: |
cmp ebx, [edi] |
jz .found |
add edi, 4 |
dec ecx |
jnz .loop |
pop ecx eax |
ret |
.error: |
or edi, -1 |
pop ecx eax |
pop ecx |
ret |
.found: |
sub edi, ETH_DRV_LIST |
shr edi, 2 |
pop ecx |
ret |
;----------------------------------------------------------------- |
; |
; ETH_create_packet |
452,13 → 469,13 |
ret |
.pop_exit: |
DEBUGF 1,"Out of ram space!!\n" |
DEBUGF 2,"Out of ram space!!\n" |
add esp, 18 |
or edi,-1 |
ret |
.exit: |
DEBUGF 1,"Packet too large!\n" |
DEBUGF 2,"Packet too large!\n" |
or edi, -1 |
ret |
/kernel/branches/net/network/icmp.inc |
---|
146,10 → 146,14 |
align 4 |
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? |
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 word [edx + ICMP_Packet.Checksum], 0 ; Set checksum to 0, needed to calculate new checksum |
/kernel/branches/net/network/socket.inc |
---|
16,8 → 16,8 |
$Revision$ |
struct SOCKET_head |
.NextPtr dd ? ; pointer to next socket in list |
.PrevPtr dd ? ; pointer to previous socket in list |
.NextPtr dd ? ; pointer to next socket in list |
.Number dd ? ; socket number (unique within single process) |
.PID dd ? ; application process id |
.Domain dd ? ; INET/UNIX/.. |
969,7 → 969,7 |
ret |
.full: |
DEBUGF 1,"Socket %x is full!\n",eax |
DEBUGF 2,"Socket %x is full!\n",eax |
mov [eax + SOCKET_head.lock], 0 |
call kernel_free |
add esp, 8 |
/kernel/branches/net/network/stack.inc |
---|
19,6 → 19,9 |
$Revision$ |
__DEBUG_LEVEL_OLD__ equ __DEBUG_LEVEL__ |
__DEBUG_LEVEL__ equ 1 ; this sets the debug level for network part of kernel |
uglobal |
last_1sTick db ? |
last_1hsTick dd ? |
25,7 → 28,7 |
endg |
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 |
MAX_EPHEMERAL_PORT equ 61000 |
207,35 → 210,230 |
; |
; 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 |
; ecx = data size |
; OUT: edx = semi-checksum |
; |
; |
; Code was optimized by diamond |
; |
;----------------------------------------------------------------- |
align 4 |
checksum_1: |
xor eax, eax |
shr ecx, 1 |
pushf |
jz .no_2 |
shr ecx, 1 |
pushf |
jz .no_4 |
shr ecx, 1 |
pushf |
jz .no_8 |
.loop: |
lodsw |
xchg al, ah |
add edx, eax |
loop .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 |
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 |
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 |
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 |
400,3 → 598,6 |
.return: |
mov [esp+28+4], eax |
ret |
__DEBUG_LEVEL__ equ __DEBUG_LEVEL_OLD__ |
/kernel/branches/net/network/tcp.inc |
---|
139,10 → 139,8 |
; scan through all the sockets, decrementing active timers |
mov ebx, net_sockets |
cmp [ebx + SOCKET_head.NextPtr], 0 |
je .exit |
.next_socket: |
mov ebx, [ebx + SOCKET_head.NextPtr] |
or ebx, ebx |
/kernel/branches/net/network/udp.inc |
---|
75,13 → 75,15 |
UDP_handler: |
DEBUGF 1,"UDP_Handler\n" |
cmp [edx + UDP_Packet.Checksum], 0 |
jz .no_checksum |
; First validate, checksum: |
pusha |
rol cx, 8 |
push cx |
rol cx, 8 |
rol word [esp], 8 |
push word IP_PROTO_UDP shl 8 |
push edi |
push esi |
92,16 → 94,16 |
mov esi, edx |
xor edx, edx |
call checksum_1 |
mov ecx, 12 |
mov esi, esp |
call checksum_1 |
add esp, 12 |
call checksum_pseudoheader |
call checksum_2 |
cmp di, dx |
popa |
jne .dump |
jne .checksum_mismatch ;dump |
.no_checksum: |
DEBUGF 1,"UDP Checksum is correct\n" |
; Look for a socket where |
110,7 → 112,7 |
mov eax, net_sockets |
.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: |
mov eax, [eax + SOCKET_head.NextPtr] |
or eax, eax |
119,7 → 121,7 |
jne .next_socket |
cmp [eax + SOCKET_head.Type], IP_PROTO_UDP |
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 |
DEBUGF 1,"found socket with matching domain, type and localport\n" |
131,9 → 133,9 |
cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0xffffffff |
je .ok1 |
mov ebx, [esp] |
mov ebx, [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 |
mov esi, [esp] |
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], esi |
jne .try_more ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination |
143,12 → 145,14 |
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket], 0 |
jz .updateport |
mov bx, [edx + UDP_Packet.SourcePort] |
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx |
mov si, [edx + UDP_Packet.SourcePort] |
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], si |
jne .dump |
push ebx |
lea ebx, [eax + SOCKET_head.lock] |
call wait_mutex |
pop ebx |
.ok2: |
170,20 → 174,33 |
.updateport: |
push ebx |
lea ebx, [eax + SOCKET_head.lock] |
call wait_mutex |
pop ebx |
mov bx, [edx + UDP_Packet.SourcePort] |
DEBUGF 1,"Changing remote port to: %x\n", bx |
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx |
mov si, [edx + UDP_Packet.SourcePort] |
DEBUGF 1,"Changing remote port to: %x\n", si |
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], si |
inc [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket] |
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: |
DEBUGF 1,"Dumping UDP packet\n" |
call kernel_free |
add esp, 4 ; pop (balance stack) |
DEBUGF 2,"UDP_Handler - dumping\n" |
ret |
213,12 → 230,9 |
DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx |
mov di , IP_PROTO_UDP |
sub esp, 8 ; reserve some place in stack for later |
; Create a part pseudoheader in stack, |
; Create a part of the pseudoheader in stack, |
push dword IP_PROTO_UDP shl 8 |
add ecx, UDP_Packet.Data |
; TODO: fill in: dx = fragment id |
257,10 → 271,7 |
; Checksum for pseudoheader |
pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. |
pushd [edi-8] ; source address |
mov ecx, 12 |
mov esi, esp |
call checksum_1 |
add esp, 12 ; remove the pseudoheader from stack |
call checksum_pseudoheader |
; Now create the final checksum and store it in UDP header |
call checksum_2 |
mov [edi + UDP_Packet.Checksum], dx |