diff --git a/kernel/branches/net/network/IPv4.inc b/kernel/branches/net/network/IPv4.inc index ff2e2ea8de..4b750a062d 100644 --- a/kernel/branches/net/network/IPv4.inc +++ b/kernel/branches/net/network/IPv4.inc @@ -18,57 +18,57 @@ $Revision$ -MAX_FRAGMENTS equ 64 -MAX_IP equ MAX_NET_DEVICES +MAX_FRAGMENTS equ 64 +MAX_IP equ MAX_NET_DEVICES IP_MAX_INTERFACES equ MAX_IP -struct IPv4_header +struct IPv4_header - VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] - TypeOfService db ? ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0] - TotalLength dw ? - Identification dw ? - FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] - TimeToLive db ? ; - Protocol db ? - HeaderChecksum dw ? - SourceAddress dd ? - DestinationAddress dd ? + VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] + TypeOfService db ? ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0] + TotalLength dw ? + Identification dw ? + FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] + TimeToLive db ? ; + Protocol db ? + HeaderChecksum dw ? + SourceAddress dd ? + DestinationAddress dd ? ends -struct FRAGMENT_slot +struct FRAGMENT_slot - ttl dw ? ; Time to live for this entry, 0 for empty slot's - id dw ? ; Identification field from IP header - SrcIP dd ? ; .. from IP header - DstIP dd ? ; .. from IP header - ptr dd ? ; Pointer to first packet + ttl dw ? ; Time to live for this entry, 0 for empty slot's + id dw ? ; Identification field from IP header + SrcIP dd ? ; .. from IP header + DstIP dd ? ; .. from IP header + ptr dd ? ; Pointer to first packet ends -struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets +struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets - 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 - ; Ip header begins here (we will need the IP header to re-construct the complete packet) + 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 + ; Ip header begins here (we will need the IP header to re-construct the complete packet) ends align 4 uglobal - IP_LIST rd MAX_IP - SUBNET_LIST rd MAX_IP - DNS_LIST rd MAX_IP - GATEWAY_LIST rd MAX_IP + IP_LIST rd MAX_IP + SUBNET_LIST rd MAX_IP + DNS_LIST rd MAX_IP + GATEWAY_LIST rd MAX_IP - IP_PACKETS_TX rd MAX_IP - IP_PACKETS_RX rd MAX_IP + IP_PACKETS_TX rd MAX_IP + IP_PACKETS_RX rd MAX_IP - FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot + FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot endg @@ -79,16 +79,16 @@ endg ; This function resets all IP variables ; ;----------------------------------------------------------------- -macro IPv4_init { +macro IPv4_init { - xor eax, eax - mov edi, IP_LIST - mov ecx, 4*MAX_IP - rep stosd + xor eax, eax + mov edi, IP_LIST + mov ecx, 4*MAX_IP + rep stosd - mov edi, FRAGMENT_LIST - mov ecx, sizeof.FRAGMENT_slot*MAX_FRAGMENTS/4 + 2*MAX_IP - rep stosd + mov edi, FRAGMENT_LIST + mov ecx, sizeof.FRAGMENT_slot*MAX_FRAGMENTS/4 + 2*MAX_IP + rep stosd } @@ -100,20 +100,20 @@ macro IPv4_init { ;----------------------------------------------------------------- macro IPv4_decrease_fragment_ttls { -local .loop +local .loop - mov esi, FRAGMENT_LIST - mov ecx, MAX_FRAGMENTS + mov esi, FRAGMENT_LIST + mov ecx, MAX_FRAGMENTS .loop: - cmp [esi + FRAGMENT_slot.ttl], 0 - je .try_next - dec [esi + FRAGMENT_slot.ttl] - jnz .try_next - DEBUGF 1,"Fragment slot timed-out!\n" + cmp [esi + FRAGMENT_slot.ttl], 0 + je .try_next + dec [esi + FRAGMENT_slot.ttl] + jnz .try_next + DEBUGF 1,"Fragment slot timed-out!\n" ;;; TODO: clear all entry's of timed-out slot .try_next: - add esi, 4 - loop .loop + add esi, 4 + loop .loop } @@ -124,59 +124,59 @@ macro IPv4_checksum ptr { ; 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 - push ebx - xor ebx, ebx - add bl, [ptr+1] - adc bh, [ptr+0] + push ebx + xor ebx, ebx + add bl, [ptr+1] + adc bh, [ptr+0] - adc bl, [ptr+3] - adc bh, [ptr+2] + adc bl, [ptr+3] + adc bh, [ptr+2] - adc bl, [ptr+5] - adc bh, [ptr+4] + adc bl, [ptr+5] + adc bh, [ptr+4] - adc bl, [ptr+7] - adc bh, [ptr+6] + adc bl, [ptr+7] + adc bh, [ptr+6] - adc bl, [ptr+9] - adc bh, [ptr+8] + adc bl, [ptr+9] + adc bh, [ptr+8] ; we skip 11th and 12th byte, they are the checksum bytes and should be 0 for re-calculation - adc bl, [ptr+13] - adc bh, [ptr+12] + adc bl, [ptr+13] + adc bh, [ptr+12] - adc bl, [ptr+15] - adc bh, [ptr+14] + adc bl, [ptr+15] + adc bh, [ptr+14] - adc bl, [ptr+17] - adc bh, [ptr+16] + adc bl, [ptr+17] + adc bh, [ptr+16] - adc bl, [ptr+19] - adc bh, [ptr+18] + adc bl, [ptr+19] + adc bh, [ptr+18] - adc ebx, 0 + adc ebx, 0 - push ecx - mov ecx, ebx - shr ecx, 16 - and ebx, 0xffff - add ebx, ecx + push ecx + mov ecx, ebx + shr ecx, 16 + and ebx, 0xffff + add ebx, ecx - mov ecx, ebx - shr ecx, 16 - add ebx, ecx + mov ecx, ebx + shr ecx, 16 + add ebx, ecx - not bx - jnz .not_zero - dec bx + not bx + jnz .not_zero + dec bx .not_zero: - xchg bl, bh - pop ecx + xchg bl, bh + pop ecx - neg word [ptr+10] ; zero will stay zero so we just get the checksum - add word [ptr+10], bx ; , else we will get (new checksum - old checksum) in the end, wich should be 0 :) - pop ebx + neg word [ptr+10] ; zero will stay zero so we just get the checksum + add word [ptr+10], bx ; , else we will get (new checksum - old checksum) in the end, wich should be 0 :) + pop ebx } @@ -199,129 +199,127 @@ macro IPv4_checksum ptr { ; ;----------------------------------------------------------------- align 4 -IPv4_input: ; TODO: implement handler for IP options - ; TODO2: add code for raw sockets +IPv4_input: ; TODO: implement handler for IP options + ; TODO2: add code for raw sockets - DEBUGF 1,"IPv4_Handler, 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 - 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 + DEBUGF 1,"IPv4_Handler, 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 + 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 ;------------------------------------------- ; Check if the packet still has time to live - cmp byte [edx + IPv4_header.TimeToLive], 0 - je .dump + cmp byte [edx + IPv4_header.TimeToLive], 0 + je .dump ;-------------------------------------- ; First, check if IP packet has options - movzx eax, [edx + IPv4_header.VersionAndIHL] - and al , 0x0f ; get IHL(header length) - cmp al , 0x05 ; IHL!= 5*4(20 bytes) - jnz .has_options + movzx eax, [edx + IPv4_header.VersionAndIHL] + and al , 0x0f ; get IHL(header length) + cmp al , 0x05 ; IHL!= 5*4(20 bytes) + jnz .has_options ;------------------------------- ; Now, re-calculate the checksum - IPv4_checksum edx - jnz .dump ; if checksum isn't valid then dump packet + IPv4_checksum edx + jnz .dump ; if checksum isn't valid then dump packet - DEBUGF 1,"IPv4 Checksum is correct\n" + DEBUGF 1,"IPv4 Checksum is correct\n" ;----------------------------------- ; Check if destination IP is correct - call NET_ptr_to_num - shl edi, 2 + call NET_ptr_to_num + shl edi, 2 - ; check if it matches local ip + ; check if it matches local ip - mov eax, [IP_LIST+edi] - cmp [edx + IPv4_header.DestinationAddress], eax - je .ip_ok + mov eax, [IP_LIST+edi] + cmp [edx + IPv4_header.DestinationAddress], eax + je .ip_ok - ; check for broadcast + ; check for broadcast - mov eax, [SUBNET_LIST+edi] - not eax - or eax, [IP_LIST+edi] - cmp [edx + IPv4_header.DestinationAddress], eax - je .ip_ok + mov eax, [SUBNET_LIST+edi] + not eax + or eax, [IP_LIST+edi] + cmp [edx + IPv4_header.DestinationAddress], eax + je .ip_ok - ; or a special broadcast + ; or a special broadcast - cmp [edx + IPv4_header.DestinationAddress], -1 - je .ip_ok + cmp [edx + IPv4_header.DestinationAddress], -1 + je .ip_ok - ; maybe it's a multicast then + ; maybe it's a multicast then - mov eax, [edx + IPv4_header.DestinationAddress] - and eax, 0xff000000 + mov eax, [edx + IPv4_header.DestinationAddress] + and eax, 0xff000000 ; cmp eax, 224 shl 24 ; je .ip_ok - ; or a loopback address + ; or a loopback address - cmp eax, 127 shl 24 - je .ip_ok + cmp eax, 127 shl 24 + je .ip_ok - ; or it's not meant for us.. + ; or it's not meant for us.. - DEBUGF 2,"Destination address does not match!\n" - jmp .dump + DEBUGF 2,"Destination address does not match!\n" + jmp .dump ;------------------------ ; Now we can update stats .ip_ok: - inc [IP_PACKETS_RX+edi] + inc [IP_PACKETS_RX+edi] ;---------------------------------- ; Check if the packet is fragmented - test [edx + IPv4_header.FlagsAndFragmentOffset], 1 shl 5 ; Is 'more fragments' flag set ? - jnz .has_fragments ; If so, we definately have a fragmented packet + test [edx + IPv4_header.FlagsAndFragmentOffset], 1 shl 5 ; Is 'more fragments' flag set ? + jnz .has_fragments ; If so, we definately have a fragmented packet - test [edx + IPv4_header.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 + test [edx + IPv4_header.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, [edx + IPv4_header.VersionAndIHL] ; Calculate Header length by using IHL field - and eax, 0x0000000f ; - shl eax, 2 ; - movzx ecx, [edx + IPv4_header.TotalLength] ; Calculate length of encapsulated Packet - xchg cl , ch ; - sub ecx, eax ; + .handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed - add eax, edx - push eax + movzx esi, [edx + IPv4_header.VersionAndIHL] ; Calculate Header length by using IHL field + and esi, 0x0000000f ; + shl esi, 2 ; - mov esi, [edx + IPv4_header.SourceAddress] ; These values might be of interest to the higher protocols - mov edi, [edx + IPv4_header.DestinationAddress] ; - mov al , [edx + IPv4_header.Protocol] - pop edx ; Offset to data (tcp/udp/icmp/.. Packet) + movzx ecx, [edx + IPv4_header.TotalLength] ; Calculate length of encapsulated Packet + xchg cl , ch ; + sub ecx, esi ; - cmp al , IP_PROTO_TCP - je TCP_input + lea edi, [edx + IPv4_header.SourceAddress] ; make edi ptr to source and dest IPv4 address + mov al , [edx + IPv4_header.Protocol] + add edx, esi ; make edi ptr to data - cmp al , IP_PROTO_UDP - je UDP_input + cmp al , IP_PROTO_TCP + je TCP_input - cmp al , IP_PROTO_ICMP - je ICMP_input + cmp al , IP_PROTO_UDP + je UDP_input - DEBUGF 2,"unknown Internet protocol: %u\n", al + cmp al , IP_PROTO_ICMP + je ICMP_input + + DEBUGF 2,"unknown Internet protocol: %u\n", al .dump: - DEBUGF 2,"IP_Handler - dumping\n" + DEBUGF 2,"IP_Handler - dumping\n" ; inc [dumped_rx_count] - call kernel_free - add esp, 4 ; pop (balance stack) - ret + call kernel_free + add esp, 4 ; pop (balance stack) + ret ;--------------------------- @@ -329,204 +327,204 @@ IPv4_input: ; TODO: implement handler for IP options .has_fragments: - movzx eax, [edx + IPv4_header.FlagsAndFragmentOffset] - xchg al , ah - shl ax , 3 + movzx eax, [edx + IPv4_header.FlagsAndFragmentOffset] + xchg al , ah + shl ax , 3 - DEBUGF 1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_header.Identification]:4 + DEBUGF 1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_header.Identification]:4 - test ax , ax ; Is this the first packet of the fragment? - jz .is_first_fragment + test ax , ax ; Is this the first packet of the fragment? + jz .is_first_fragment ;------------------------------------------------------- ; We have a fragmented IP packet, but it's not the first - DEBUGF 1,"Middle fragmented packet received!\n" + DEBUGF 1,"Middle fragmented packet received!\n" - call IPv4_find_fragment_slot - cmp esi, -1 - je .dump + call IPv4_find_fragment_slot + cmp esi, -1 + je .dump - mov [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 + mov [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 + 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 + 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 - mov esi, FRAGMENT_LIST + DEBUGF 1,"First fragmented packet received!\n" + ; try to locate a free slot.. + mov ecx, MAX_FRAGMENTS + mov esi, FRAGMENT_LIST .find_free_slot: - cmp word [esi + FRAGMENT_slot.ttl], 0 - je .found_free_slot - add esi, sizeof.FRAGMENT_slot - loop .find_free_slot - jmp .dump ; If no free slot was found, dump the packet + cmp word [esi + FRAGMENT_slot.ttl], 0 + je .found_free_slot + add esi, sizeof.FRAGMENT_slot + loop .find_free_slot + 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 - mov [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl - mov ax , [edx + IPv4_header.Identification] - mov [esi + FRAGMENT_slot.id], ax - mov eax,[edx + IPv4_header.SourceAddress] - mov [esi + FRAGMENT_slot.SrcIP], eax - mov eax, [edx + IPv4_header.DestinationAddress] - mov [esi + FRAGMENT_slot.DstIP], eax - pop eax - mov [esi + FRAGMENT_slot.ptr], eax - ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure - mov [eax + FRAGMENT_entry.NextPtr], -1 - mov [eax + FRAGMENT_entry.PrevPtr], -1 - mov [eax + FRAGMENT_entry.Owner], ebx + .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 ax , [edx + IPv4_header.Identification] + mov [esi + FRAGMENT_slot.id], ax + mov eax,[edx + IPv4_header.SourceAddress] + mov [esi + FRAGMENT_slot.SrcIP], eax + mov eax, [edx + IPv4_header.DestinationAddress] + mov [esi + FRAGMENT_slot.DstIP], eax + pop eax + mov [esi + FRAGMENT_slot.ptr], eax + ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure + mov [eax + FRAGMENT_entry.NextPtr], -1 + mov [eax + FRAGMENT_entry.PrevPtr], -1 + mov [eax + FRAGMENT_entry.Owner], ebx - add esp, 4 ; balance stack and exit - ret + add esp, 4 ; balance stack and exit + ret ;----------------------------------- ; We have received the last fragment .is_last_fragment: - DEBUGF 1,"Last fragmented packet received!\n" + DEBUGF 1,"Last fragmented packet received!\n" - call IPv4_find_fragment_slot - cmp esi, -1 - je .dump + call IPv4_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 - or edi, -1 + 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 + 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!) - mov cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length - xchg cl, ch - DEBUGF 1,"Packet size: %u\n", cx - add ax, cx - movzx cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length - and cx, 0x000F - shl cx, 2 - DEBUGF 1,"Header size: %u\n", cx - sub ax, cx - mov edi, esi - mov esi, [esi + FRAGMENT_entry.NextPtr] - cmp esi, -1 - jne .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!) + mov cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length + xchg cl, ch + DEBUGF 1,"Packet size: %u\n", cx + add ax, cx + movzx cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length + and cx, 0x000F + shl cx, 2 + DEBUGF 1,"Header size: %u\n", cx + sub ax, cx + mov edi, esi + mov esi, [esi + FRAGMENT_entry.NextPtr] + cmp esi, -1 + jne .count_bytes - mov esi, [esp+4] - mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code - mov [esi + FRAGMENT_entry.NextPtr], -1 - mov [esi + FRAGMENT_entry.PrevPtr], edi - mov [esi + FRAGMENT_entry.Owner], ebx + mov esi, [esp+4] + mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code + mov [esi + FRAGMENT_entry.NextPtr], -1 + mov [esi + FRAGMENT_entry.PrevPtr], edi + mov [esi + FRAGMENT_entry.Owner], ebx - mov cx, [edx + IPv4_header.TotalLength] ; Note: This time we dont substract Header length - xchg cl , ch - DEBUGF 1,"Packet size: %u\n", cx - add ax , cx - DEBUGF 1,"Total Received data size: %u\n", eax + mov cx, [edx + IPv4_header.TotalLength] ; Note: This time we dont substract Header length + xchg cl , ch + DEBUGF 1,"Packet size: %u\n", cx + add ax , cx + DEBUGF 1,"Total Received data size: %u\n", eax - push eax - mov ax , [edx + IPv4_header.FlagsAndFragmentOffset] - xchg al , ah - shl ax , 3 - add cx , ax - pop eax - DEBUGF 1,"Total Fragment size: %u\n", ecx + push eax + mov ax , [edx + IPv4_header.FlagsAndFragmentOffset] + xchg al , ah + shl ax , 3 + add cx , ax + pop eax + DEBUGF 1,"Total Fragment size: %u\n", ecx - cmp ax, cx - jne .destroy_slot_pop + cmp ax, cx + jne .destroy_slot_pop - push eax - push eax - call kernel_alloc - test eax, eax - 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 + push eax + push eax + call kernel_alloc + test eax, eax + 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 .rebuild_packet_loop: - movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset - xchg cl , ch ; intel byte order - shl cx , 3 ; multiply by 8 and clear first 3 bits - DEBUGF 1,"Fragment offset: %u\n", cx + movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset + xchg cl , ch ; intel byte order + shl cx , 3 ; multiply by 8 and clear first 3 bits + DEBUGF 1,"Fragment offset: %u\n", cx - 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 - and bx , 0x000F ; - shl bx , 2 ; + 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 + and bx , 0x000F ; + shl bx , 2 ; - lea esi, [edx + sizeof.FRAGMENT_entry] ; Set esi to the correct begin of fragment - movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment - xchg cl, ch ; intel byte order + lea esi, [edx + sizeof.FRAGMENT_entry] ; Set esi to the correct begin of fragment + movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment + xchg cl, ch ; intel byte order - cmp edi, eax ; Is this packet the first fragment ? - je .first_fragment - sub cx, bx ; If not, dont copy the header - add esi, ebx ; + cmp edi, eax ; Is this packet the first fragment ? + je .first_fragment + sub cx, bx ; If not, dont copy the header + add esi, ebx ; .first_fragment: - push cx ; First copy dword-wise, then byte-wise - shr cx, 2 ; - rep movsd ; - pop cx ; - and cx, 3 ; - rep movsb ; + push cx ; First copy dword-wise, then byte-wise + shr cx, 2 ; + rep movsd ; + pop cx ; + and cx, 3 ; + rep movsb ; - 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 - cmp edx, -1 ; Check if it is last fragment in chain - jne .rebuild_packet_loop + 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 + cmp edx, -1 ; Check if it is last fragment in chain + jne .rebuild_packet_loop - pop ecx - xchg cl, ch - mov edx, eax - mov [edx + IPv4_header.TotalLength], cx - add esp, 8 + pop ecx + xchg cl, ch + mov edx, eax + mov [edx + IPv4_header.TotalLength], cx + add esp, 8 - xchg cl, ch ; + xchg cl, ch ; - push ecx ;;;; - push eax ;;;; + 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 - jmp .handle_it ; edx = buf ptr, ecx = size, [esp] buf ptr, [esp+4], total size, ebx=device ptr + jmp .handle_it ; edx = buf ptr, ecx = size, [esp] buf ptr, [esp+4], total size, ebx=device ptr .destroy_slot_pop: - add esp, 4 + add esp, 4 .destroy_slot: - DEBUGF 1,"Destroy fragment slot!\n" - ; TODO! - jmp .dump + DEBUGF 1,"Destroy fragment slot!\n" + ; TODO! + jmp .dump @@ -535,7 +533,7 @@ IPv4_input: ; TODO: implement handler for IP options ; The IP packet has some options .has_options: - jmp .dump + jmp .dump @@ -552,29 +550,29 @@ IPv4_find_fragment_slot: ;;; TODO: the RFC says we should check protocol number too - push eax ebx ecx edx - mov ax , [edx + IPv4_header.Identification] - mov ecx, MAX_FRAGMENTS - mov esi, FRAGMENT_LIST - mov ebx, [edx + IPv4_header.SourceAddress] - mov edx, [edx + IPv4_header.DestinationAddress] + push eax ebx ecx edx + mov ax , [edx + IPv4_header.Identification] + mov ecx, MAX_FRAGMENTS + mov esi, FRAGMENT_LIST + mov ebx, [edx + IPv4_header.SourceAddress] + mov edx, [edx + IPv4_header.DestinationAddress] .find_slot: - cmp [esi + FRAGMENT_slot.id], ax - jne .try_next - cmp [esi + FRAGMENT_slot.SrcIP], ebx - jne .try_next - cmp [esi + FRAGMENT_slot.DstIP], edx - je .found_slot + cmp [esi + FRAGMENT_slot.id], ax + jne .try_next + cmp [esi + FRAGMENT_slot.SrcIP], ebx + jne .try_next + cmp [esi + FRAGMENT_slot.DstIP], edx + je .found_slot .try_next: - add esi, sizeof.FRAGMENT_slot - loop .find_slot + add esi, sizeof.FRAGMENT_slot + loop .find_slot ; pop edx ebx - or esi, -1 + or esi, -1 ; ret .found_slot: - pop edx ecx ebx eax - ret + pop edx ecx ebx eax + ret ;------------------------------------------------------------------ @@ -597,63 +595,63 @@ IPv4_find_fragment_slot: align 4 IPv4_output: - DEBUGF 1,"IPv4_create_packet: size=%u\n", ecx + DEBUGF 1,"IPv4_create_packet: size=%u\n", ecx - cmp ecx, 65500 ; Max IPv4 packet size - ja .too_large + cmp ecx, 65500 ; Max IPv4 packet size + ja .too_large - push ecx eax ebx dx di + push ecx eax ebx dx di - call ARP_IP_to_MAC + call ARP_IP_to_MAC - test eax, 0xffff0000 ; error bits - jnz .arp_error + test eax, 0xffff0000 ; error bits + jnz .arp_error .continue: - push ebx ; push the mac - push ax + push ebx ; push the mac + push ax - call IPv4_dest_to_dev - inc [IP_PACKETS_TX+edi] - mov ebx, [NET_DRV_LIST+edi] - lea eax, [ebx + ETH_DEVICE.mac] - mov edx, esp - mov ecx, [esp + 18] - add ecx, sizeof.IPv4_header - mov di , ETHER_IPv4 - call ETH_output - jz .error + call IPv4_dest_to_dev + inc [IP_PACKETS_TX+edi] + mov ebx, [NET_DRV_LIST+edi] + lea eax, [ebx + ETH_DEVICE.mac] + mov edx, esp + mov ecx, [esp + 18] + add ecx, sizeof.IPv4_header + mov di , ETHER_IPv4 + call ETH_output + jz .error - add esp, 6 ; pop the mac + add esp, 6 ; pop the mac - mov [edi + IPv4_header.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) - mov [edi + IPv4_header.TypeOfService], 0 ; nothing special, just plain ip packet - mov [edi + IPv4_header.TotalLength], cx - rol [edi + IPv4_header.TotalLength], 8 ; internet byte order - mov [edi + IPv4_header.FlagsAndFragmentOffset], 0x0000 - mov [edi + IPv4_header.HeaderChecksum], 0 - pop word [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol + mov [edi + IPv4_header.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) + mov [edi + IPv4_header.TypeOfService], 0 ; nothing special, just plain ip packet + mov [edi + IPv4_header.TotalLength], cx + rol [edi + IPv4_header.TotalLength], 8 ; internet byte order + mov [edi + IPv4_header.FlagsAndFragmentOffset], 0x0000 + mov [edi + IPv4_header.HeaderChecksum], 0 + pop word [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol ; [edi + IPv4_header.Protocol] - popw [edi + IPv4_header.Identification] ; fragment id - popd [edi + IPv4_header.SourceAddress] - popd [edi + IPv4_header.DestinationAddress] + popw [edi + IPv4_header.Identification] ; fragment id + popd [edi + IPv4_header.SourceAddress] + popd [edi + IPv4_header.DestinationAddress] - pop ecx + pop ecx - IPv4_checksum edi - add edi, sizeof.IPv4_header - DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx - ret + IPv4_checksum edi + add edi, sizeof.IPv4_header + DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx + ret .error: - add esp, 6 + add esp, 6 .arp_error: - add esp, 4+4+4+2+2 + add esp, 4+4+4+2+2 .too_large: - DEBUGF 1,"IPv4_create_packet: Failed\n" - sub edi, edi - ret + DEBUGF 1,"IPv4_create_packet: Failed\n" + sub edi, edi + ret @@ -673,46 +671,46 @@ IPv4_output: align 4 IPv4_output_raw: - DEBUGF 1,"IPv4_output_raw: size=%u ptr=%x socket=%x\n", ecx, esi, eax + DEBUGF 1,"IPv4_output_raw: size=%u ptr=%x socket=%x\n", ecx, esi, eax - cmp ecx, 1480 ;;;;; FIXME - ja .too_large + cmp ecx, 1480 ;;;;; FIXME + ja .too_large - sub esp, 8 - push esi eax + sub esp, 8 + push esi eax - call ARP_IP_to_MAC + call ARP_IP_to_MAC - test eax, 0xffff0000 ; error bits - jnz .arp_error + test eax, 0xffff0000 ; error bits + jnz .arp_error .continue: - push ebx ; push the mac - push ax + push ebx ; push the mac + push ax - call IPv4_dest_to_dev - inc [IP_PACKETS_TX+edi] - mov ebx, [NET_DRV_LIST+edi] - lea eax, [ebx + ETH_DEVICE.mac] - mov edx, esp - mov ecx, [esp + 6+4] - add ecx, sizeof.IPv4_header - mov di, ETHER_IPv4 - call ETH_output - jz .error + call IPv4_dest_to_dev + inc [IP_PACKETS_TX+edi] + mov ebx, [NET_DRV_LIST+edi] + lea eax, [ebx + ETH_DEVICE.mac] + mov edx, esp + mov ecx, [esp + 6+4] + add ecx, sizeof.IPv4_header + mov di, ETHER_IPv4 + call ETH_output + jz .error - add esp, 6 ; pop the mac + add esp, 6 ; pop the mac - mov dword[esp+4+4], edx - mov dword[esp+4+4+4], eax + mov dword[esp+4+4], edx + mov dword[esp+4+4+4], eax - pop eax esi + pop eax esi ;; todo: check socket options if we should add header, or just compute checksum - push edi ecx - rep movsb - pop ecx edi + push edi ecx + rep movsb + pop ecx edi ; [edi + IPv4_header.VersionAndIHL] ; IPv4, normal length (no Optional header) ; [edi + IPv4_header.TypeOfService] ; nothing special, just plain ip packet @@ -720,7 +718,7 @@ IPv4_output_raw: ; [edi + IPv4_header.TotalLength] ; internet byte order ; [edi + IPv4_header.FlagsAndFragmentOffset] - mov [edi + IPv4_header.HeaderChecksum], 0 + mov [edi + IPv4_header.HeaderChecksum], 0 ; [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol ; [edi + IPv4_header.Protocol] @@ -728,20 +726,20 @@ IPv4_output_raw: ; [edi + IPv4_header.SourceAddress] ; [edi + IPv4_header.DestinationAddress] - IPv4_checksum edi ;;;; todo: checksum for IP packet with options! - add edi, sizeof.IPv4_header - DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx - call [ebx + NET_DEVICE.transmit] - ret + IPv4_checksum edi ;;;; todo: checksum for IP packet with options! + add edi, sizeof.IPv4_header + DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx + call [ebx + NET_DEVICE.transmit] + ret .error: - add esp, 6 + add esp, 6 .arp_error: - add esp, 8+4+4 + add esp, 8+4+4 .too_large: - DEBUGF 1,"IPv4_output_raw: Failed\n" - sub edi, edi - ret + DEBUGF 1,"IPv4_output_raw: Failed\n" + sub edi, edi + ret ;-------------------------------------------------------- @@ -759,111 +757,111 @@ IPv4_output_raw: align 4 IPv4_fragment: - DEBUGF 1,"IPv4_fragment\n" + DEBUGF 1,"IPv4_fragment\n" - and ecx, not 111b ; align 4 + and ecx, not 111b ; align 4 - cmp ecx, sizeof.IPv4_header + 8 ; must be able to put at least 8 bytes - jb .err2 + cmp ecx, sizeof.IPv4_header + 8 ; must be able to put at least 8 bytes + jb .err2 - push esi ecx - mov eax, [esi + IPv4_header.DestinationAddress] - call ARP_IP_to_MAC - pop ecx esi - cmp eax, -1 - jz .err2 + push esi ecx + mov eax, [esi + IPv4_header.DestinationAddress] + call ARP_IP_to_MAC + pop ecx esi + cmp eax, -1 + jz .err2 - push ebx - push ax + push ebx + push ax - mov ebx, [NET_DRV_LIST] - lea eax, [ebx + ETH_DEVICE.mac] - push eax + mov ebx, [NET_DRV_LIST] + lea eax, [ebx + ETH_DEVICE.mac] + push eax - push esi ; ptr to ip header - sub ecx, sizeof.IPv4_header ; substract header size - push ecx ; max data size - push dword 0 ; offset + push esi ; ptr to ip header + sub ecx, sizeof.IPv4_header ; substract header size + push ecx ; max data size + push dword 0 ; offset .new_fragment: - DEBUGF 1,"Ipv4_fragment - new_fragmentn" + DEBUGF 1,"Ipv4_fragment - new_fragmentn" - mov eax, [esp + 3*4] - lea ebx, [esp + 4*4] - mov di , ETHER_IPv4 - call ETH_output + mov eax, [esp + 3*4] + lea ebx, [esp + 4*4] + mov di , ETHER_IPv4 + call ETH_output - cmp edi, -1 - jz .err + cmp edi, -1 + jz .err ; copy header - mov esi, [esp + 2*4] - mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header! - rep movsd + mov esi, [esp + 2*4] + mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header! + rep movsd ; copy data - mov esi, [esp + 2*4] - add esi, sizeof.IPv4_header - add esi, [esp] ; offset + mov esi, [esp + 2*4] + add esi, sizeof.IPv4_header + add esi, [esp] ; offset - mov ecx, [esp + 1*4] - DEBUGF 1,"IPv4_fragment - copying data (%u bytes)\n", ecx - rep movsb + mov ecx, [esp + 1*4] + DEBUGF 1,"IPv4_fragment - copying data (%u bytes)\n", ecx + rep movsb ; now, correct header - mov ecx, [esp + 1*4] - add ecx, sizeof.IPv4_header - xchg cl, ch - mov [edi + IPv4_header.TotalLength], cx + mov ecx, [esp + 1*4] + add ecx, sizeof.IPv4_header + xchg cl, ch + mov [edi + IPv4_header.TotalLength], cx - mov ecx, [esp] ; offset - xchg cl, ch + mov ecx, [esp] ; offset + xchg cl, ch ; cmp dword[esp + 4*4], 0 ; last fragment?;<<<<<< ; je .last_fragment - or cx, 1 shl 2 ; more fragments + or cx, 1 shl 2 ; more fragments ; .last_fragment: - mov [edi + IPv4_header.FlagsAndFragmentOffset], cx + mov [edi + IPv4_header.FlagsAndFragmentOffset], cx - mov [edi + IPv4_header.HeaderChecksum], 0 + mov [edi + IPv4_header.HeaderChecksum], 0 - ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< send the packet - mov ecx, [esp + 1*4] + ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< send the packet + mov ecx, [esp + 1*4] - push edx eax - IPv4_checksum edi + push edx eax + IPv4_checksum edi - call [ebx + NET_DEVICE.transmit] - ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + call [ebx + NET_DEVICE.transmit] + ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - mov ecx, [esp+4] - add [esp], ecx + mov ecx, [esp+4] + add [esp], ecx - mov ecx, [esp+3*4+6+4] ; ptr to begin of buff - add ecx, [esp+3*4+6+4+4] ; buff size - sub ecx, [esp+2*4] ; ptr to ip header - add ecx, [esp] ; offset + mov ecx, [esp+3*4+6+4] ; ptr to begin of buff + add ecx, [esp+3*4+6+4+4] ; buff size + sub ecx, [esp+2*4] ; ptr to ip header + add ecx, [esp] ; offset - DEBUGF 1,"Ipv4_fragment - bytes remaining: %u\n", ecx + DEBUGF 1,"Ipv4_fragment - bytes remaining: %u\n", ecx - cmp ecx, [esp+1*4] - jae .new_fragment + cmp ecx, [esp+1*4] + jae .new_fragment - mov [esp+4], ecx ; set fragment size to remaining packet size - jmp .new_fragment + mov [esp+4], ecx ; set fragment size to remaining packet size + jmp .new_fragment .err: - DEBUGF 1,"Ipv4_fragment - failed\n" + DEBUGF 1,"Ipv4_fragment - failed\n" .done: - add esp, 12 + 4 + 6 + add esp, 12 + 4 + 6 .err2: - DEBUGF 1,"Ipv4_fragment - dumping\n" - call kernel_free - add esp, 4 + DEBUGF 1,"Ipv4_fragment - dumping\n" + call kernel_free + add esp, 4 - ret + ret @@ -878,33 +876,33 @@ IPv4_fragment: align 4 IPv4_dest_to_dev: - cmp eax, 0xffffffff - je .invalid + cmp eax, 0xffffffff + je .invalid - xor edi, edi - mov ecx, MAX_IP + xor edi, edi + mov ecx, MAX_IP .loop: - mov ebx, [IP_LIST+edi] - and ebx, [SUBNET_LIST+edi] - jz .next + mov ebx, [IP_LIST+edi] + and ebx, [SUBNET_LIST+edi] + jz .next - mov edx, eax - and edx, [SUBNET_LIST+edi] + mov edx, eax + and edx, [SUBNET_LIST+edi] - cmp ebx, edx - je .found_it + cmp ebx, edx + je .found_it .next: - add edi, 4 - loop .loop + add edi, 4 + loop .loop .invalid: - xor edi, edi ; if none found, use device 0 as default device + xor edi, edi ; if none found, use device 0 as default device .found_it: - DEBUGF 1,"IPv4_dest_to_dev: %u\n", edi + DEBUGF 1,"IPv4_dest_to_dev: %u\n", edi - ret + ret @@ -918,9 +916,9 @@ IPv4_dest_to_dev: ;--------------------------------------------------------------------------- align 4 IPv4_get_frgmnt_num: - xor ax, ax ;;; TODO: replace this with real code + xor ax, ax ;;; TODO: replace this with real code - ret + ret ;--------------------------------------------------------------------------- @@ -939,84 +937,84 @@ IPv4_get_frgmnt_num: align 4 IPv4_API: - movzx eax, bh - shl eax, 2 + movzx eax, bh + shl eax, 2 - test bl, bl - jz .packets_tx ; 0 - dec bl - jz .packets_rx ; 1 - dec bl - jz .read_ip ; 2 - dec bl - jz .write_ip ; 3 - dec bl - jz .read_dns ; 4 - dec bl - jz .write_dns ; 5 - dec bl - jz .read_subnet ; 6 - dec bl - jz .write_subnet ; 7 - dec bl - jz .read_gateway ; 8 - dec bl - jz .write_gateway ; 9 + test bl, bl + jz .packets_tx ; 0 + dec bl + jz .packets_rx ; 1 + dec bl + jz .read_ip ; 2 + dec bl + jz .write_ip ; 3 + dec bl + jz .read_dns ; 4 + dec bl + jz .write_dns ; 5 + dec bl + jz .read_subnet ; 6 + dec bl + jz .write_subnet ; 7 + dec bl + jz .read_gateway ; 8 + dec bl + jz .write_gateway ; 9 .error: - mov eax, -1 - ret + mov eax, -1 + ret .packets_tx: - add eax, IP_PACKETS_TX - mov eax, [eax] - ret + add eax, IP_PACKETS_TX + mov eax, [eax] + ret .packets_rx: - add eax, IP_PACKETS_RX - mov eax, [eax] - ret + add eax, IP_PACKETS_RX + mov eax, [eax] + ret .read_ip: - add eax, IP_LIST - mov eax, [eax] - ret + add eax, IP_LIST + mov eax, [eax] + ret .write_ip: - add eax, IP_LIST - mov [eax], ecx - xor eax, eax - ret + add eax, IP_LIST + mov [eax], ecx + xor eax, eax + ret .read_dns: - add eax, DNS_LIST - mov eax, [eax] - ret + add eax, DNS_LIST + mov eax, [eax] + ret .write_dns: - add eax, DNS_LIST - mov [eax], ecx - xor eax, eax - ret + add eax, DNS_LIST + mov [eax], ecx + xor eax, eax + ret .read_subnet: - add eax, SUBNET_LIST - mov eax, [eax] - ret + add eax, SUBNET_LIST + mov eax, [eax] + ret .write_subnet: - add eax, SUBNET_LIST - mov [eax], ecx - xor eax, eax - ret + add eax, SUBNET_LIST + mov [eax], ecx + xor eax, eax + ret .read_gateway: - add eax, GATEWAY_LIST - mov eax, [eax] - ret + add eax, GATEWAY_LIST + mov eax, [eax] + ret .write_gateway: - add eax, GATEWAY_LIST - mov [eax], ecx - xor eax, eax - ret \ No newline at end of file + add eax, GATEWAY_LIST + mov [eax], ecx + xor eax, eax + ret \ No newline at end of file diff --git a/kernel/branches/net/network/icmp.inc b/kernel/branches/net/network/icmp.inc index 30596fbfb2..dedd02c5ee 100644 --- a/kernel/branches/net/network/icmp.inc +++ b/kernel/branches/net/network/icmp.inc @@ -21,87 +21,87 @@ $Revision$ ; ICMP types & codes -ICMP_ECHOREPLY equ 0 ; echo reply message +ICMP_ECHOREPLY equ 0 ; echo reply message -ICMP_UNREACH equ 3 -ICMP_UNREACH_NET equ 0 ; bad net -ICMP_UNREACH_HOST equ 1 ; bad host -ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol -ICMP_UNREACH_PORT equ 3 ; bad port -ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop -ICMP_UNREACH_SRCFAIL equ 5 ; src route failed -ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net -ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host -ICMP_UNREACH_ISOLATED equ 8 ; src host isolated -ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access -ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto -ICMP_UNREACH_TOSNET equ 11 ; bad tos for net -ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host -ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib -ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio. -ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff +ICMP_UNREACH equ 3 +ICMP_UNREACH_NET equ 0 ; bad net +ICMP_UNREACH_HOST equ 1 ; bad host +ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol +ICMP_UNREACH_PORT equ 3 ; bad port +ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop +ICMP_UNREACH_SRCFAIL equ 5 ; src route failed +ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net +ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host +ICMP_UNREACH_ISOLATED equ 8 ; src host isolated +ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access +ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto +ICMP_UNREACH_TOSNET equ 11 ; bad tos for net +ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host +ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib +ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio. +ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff -ICMP_SOURCEQUENCH equ 4 ; Packet lost, slow down +ICMP_SOURCEQUENCH equ 4 ; Packet lost, slow down -ICMP_REDIRECT equ 5 ; shorter route, codes: -ICMP_REDIRECT_NET equ 0 ; for network -ICMP_REDIRECT_HOST equ 1 ; for host -ICMP_REDIRECT_TOSNET equ 2 ; for tos and net -ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host +ICMP_REDIRECT equ 5 ; shorter route, codes: +ICMP_REDIRECT_NET equ 0 ; for network +ICMP_REDIRECT_HOST equ 1 ; for host +ICMP_REDIRECT_TOSNET equ 2 ; for tos and net +ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host -ICMP_ALTHOSTADDR equ 6 ; alternate host address -ICMP_ECHO equ 8 ; echo service -ICMP_ROUTERADVERT equ 9 ; router advertisement -ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement -ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing +ICMP_ALTHOSTADDR equ 6 ; alternate host address +ICMP_ECHO equ 8 ; echo service +ICMP_ROUTERADVERT equ 9 ; router advertisement +ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement +ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing -ICMP_ROUTERSOLICIT equ 10 ; router solicitation -ICMP_TIMXCEED equ 11 ; time exceeded, code: -ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit -ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass +ICMP_ROUTERSOLICIT equ 10 ; router solicitation +ICMP_TIMXCEED equ 11 ; time exceeded, code: +ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit +ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass -ICMP_PARAMPROB equ 12 ; ip header bad -ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr -ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent -ICMP_PARAMPROB_LENGTH equ 2 ; bad length +ICMP_PARAMPROB equ 12 ; ip header bad +ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr +ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent +ICMP_PARAMPROB_LENGTH equ 2 ; bad length -ICMP_TSTAMP equ 13 ; timestamp request -ICMP_TSTAMPREPLY equ 14 ; timestamp reply -ICMP_IREQ equ 15 ; information request -ICMP_IREQREPLY equ 16 ; information reply -ICMP_MASKREQ equ 17 ; address mask request -ICMP_MASKREPLY equ 18 ; address mask reply -ICMP_TRACEROUTE equ 30 ; traceroute -ICMP_DATACONVERR equ 31 ; data conversion error -ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect -ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you -ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here -ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req -ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply -ICMP_SKIP equ 39 ; SKIP +ICMP_TSTAMP equ 13 ; timestamp request +ICMP_TSTAMPREPLY equ 14 ; timestamp reply +ICMP_IREQ equ 15 ; information request +ICMP_IREQREPLY equ 16 ; information reply +ICMP_MASKREQ equ 17 ; address mask request +ICMP_MASKREPLY equ 18 ; address mask reply +ICMP_TRACEROUTE equ 30 ; traceroute +ICMP_DATACONVERR equ 31 ; data conversion error +ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect +ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you +ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here +ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req +ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply +ICMP_SKIP equ 39 ; SKIP -ICMP_PHOTURIS equ 40 ; Photuris -ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index -ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed -ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed +ICMP_PHOTURIS equ 40 ; Photuris +ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index +ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed +ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed -struct ICMP_header +struct ICMP_header - Type db ? - Code db ? - Checksum dw ? - Identifier dw ? - SequenceNumber dw ? + Type db ? + Code db ? + Checksum dw ? + Identifier dw ? + SequenceNumber dw ? ends align 4 uglobal - ICMP_PACKETS_TX rd MAX_IP - ICMP_PACKETS_RX rd MAX_IP + ICMP_PACKETS_TX rd MAX_IP + ICMP_PACKETS_RX rd MAX_IP endg @@ -114,10 +114,10 @@ endg macro ICMP_init { - xor eax, eax - mov edi, ICMP_PACKETS_TX - mov ecx, 2*MAX_IP - rep stosd + xor eax, eax + mov edi, ICMP_PACKETS_TX + mov ecx, 2*MAX_IP + rep stosd } @@ -134,116 +134,116 @@ macro ICMP_init { ; ebx = pointer to device struct ; ecx = ICMP Packet size ; edx = ptr to ICMP Packet data -; esi = ipv4 source address -; edi = ipv4 dest address +; edi = ptr to ipv4 source and dest address +; ; OUT: / ; ;----------------------------------------------------------------- align 4 ICMP_input: - DEBUGF 1,"ICMP_input - start\n" + DEBUGF 1,"ICMP_input - start\n" ; First, check the checksum (altough some implementations ignore it) - push edx esi ecx - push [edx + ICMP_header.Checksum] - mov [edx + ICMP_header.Checksum], 0 - mov esi, edx - xor edx, edx - call checksum_1 - call checksum_2 - pop si - cmp dx, si - pop ecx esi edx - jne .checksum_mismatch + push edx ecx + push [edx + ICMP_header.Checksum] + mov [edx + ICMP_header.Checksum], 0 + mov esi, edx + xor edx, edx + call checksum_1 + call checksum_2 + pop si + cmp dx, si + pop ecx edx + jne .checksum_mismatch - cmp [edx + ICMP_header.Type], ICMP_ECHO ; Is this an echo request? - jne .check_sockets + cmp [edx + ICMP_header.Type], ICMP_ECHO ; Is this an echo request? + jne .check_sockets -; We well re-use the packet sow e can create the response as fast as possible -; Notice: this only works on pure ethernet (however, IP packet options are not a problem this time :) +; We well re-use the packet so we can create the response as fast as possible +; Notice: this only works on pure ethernet - DEBUGF 1,"ICMP_input - echo request\n" - mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply + DEBUGF 1,"ICMP_input - echo request\n" + mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply ; Update stats (and validate device ptr) - call NET_ptr_to_num - cmp edi,-1 - je .dump - inc [ICMP_PACKETS_RX+4*edi] - inc [ICMP_PACKETS_TX+4*edi] + call NET_ptr_to_num + cmp edi,-1 + je .dump + inc [ICMP_PACKETS_RX+4*edi] + inc [ICMP_PACKETS_TX+4*edi] ; exchange dest and source address in IP header ; exchange dest and source MAC in ETH header - mov esi, [esp] ; Start of buffer - push dword [esi + ETH_header.DstMAC] - push dword [esi + ETH_header.SrcMAC] - pop dword [esi + ETH_header.DstMAC] - pop dword [esi + ETH_header.SrcMAC] - push word [esi + ETH_header.DstMAC + 4] - push word [esi + ETH_header.SrcMAC + 4] - pop word [esi + ETH_header.DstMAC + 4] - pop word [esi + ETH_header.SrcMAC + 4] + mov esi, [esp] ; Start of buffer + push dword [esi + ETH_header.DstMAC] + push dword [esi + ETH_header.SrcMAC] + pop dword [esi + ETH_header.DstMAC] + pop dword [esi + ETH_header.SrcMAC] + push word [esi + ETH_header.DstMAC + 4] + push word [esi + ETH_header.SrcMAC + 4] + pop word [esi + ETH_header.DstMAC + 4] + pop word [esi + ETH_header.SrcMAC + 4] - add esi, sizeof.ETH_header - push [esi + IPv4_header.SourceAddress] - push [esi + IPv4_header.DestinationAddress] - pop [esi + IPv4_header.SourceAddress] - pop [esi + IPv4_header.DestinationAddress] + add esi, sizeof.ETH_header + push [esi + IPv4_header.SourceAddress] + push [esi + IPv4_header.DestinationAddress] + pop [esi + IPv4_header.SourceAddress] + pop [esi + IPv4_header.DestinationAddress] ; Recalculate ip header checksum - movzx ecx, [esi + IPv4_header.VersionAndIHL] ; Calculate IP Header length by using IHL field - and ecx, 0x0f - shl cx, 2 - mov edi, ecx ; IP header length - mov eax, edx ; ICMP packet start addr + movzx ecx, [esi + IPv4_header.VersionAndIHL] ; Calculate IP Header length by using IHL field + and ecx, 0x0f + shl cx, 2 + mov edi, ecx ; IP header length + mov eax, edx ; ICMP packet start addr - push esi ; Calculate the IP checksum - xor edx, edx ; - call checksum_1 ; - call checksum_2 ; - pop esi ; - mov [esi + IPv4_header.HeaderChecksum], dx ; + push esi ; Calculate the IP checksum + xor edx, edx ; + call checksum_1 ; + call checksum_2 ; + pop esi ; + mov [esi + IPv4_header.HeaderChecksum], dx ; ; Recalculate ICMP CheckSum - movzx ecx, [esi + IPv4_header.TotalLength] ; Find length of IP Packet - xchg ch, cl ; - sub ecx, edi ; IP packet length - IP header length = ICMP packet length + movzx ecx, [esi + IPv4_header.TotalLength] ; Find length of IP Packet + xchg ch, cl ; + sub ecx, edi ; IP packet length - IP header length = ICMP packet length - mov esi, eax ; Calculate ICMP checksum - xor edx, edx ; - call checksum_1 ; - call checksum_2 ; - mov [eax + ICMP_header.Checksum], dx ; + mov esi, eax ; Calculate ICMP checksum + xor edx, edx ; + call checksum_1 ; + call checksum_2 ; + mov [eax + ICMP_header.Checksum], dx ; ; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!) - call [ebx + NET_DEVICE.transmit] - ret + call [ebx + NET_DEVICE.transmit] + ret .check_sockets: - ; Look for an open ICMP socket - ; esi = sender ip + ; Look for an open ICMP socket - mov ebx, net_sockets + mov esi, [edi] ; ipv4 source address + mov ebx, net_sockets .try_more: ; mov ax , [edx + ICMP_header.Identifier] .next_socket: - mov ebx, [ebx + SOCKET.NextPtr] - or ebx, ebx - jz .dump + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .dump - cmp [ebx + SOCKET.Domain], AF_INET4 - jne .next_socket + cmp [ebx + SOCKET.Domain], AF_INET4 + jne .next_socket - cmp [ebx + SOCKET.Protocol], IP_PROTO_ICMP - jne .next_socket + cmp [ebx + SOCKET.Protocol], IP_PROTO_ICMP + jne .next_socket - cmp [ebx + IP_SOCKET.RemoteIP], esi - jne .next_socket + cmp [ebx + IP_SOCKET.RemoteIP], esi + jne .next_socket ; cmp [esi + ICMP_SOCKET.Identifier], ax ; jne .next_socket @@ -253,26 +253,26 @@ ICMP_input: ; je .dump ; inc [ICMP_PACKETS_RX+edi] - DEBUGF 1,"Found valid ICMP packet for socket %x\n", ebx + DEBUGF 1,"Found valid ICMP packet for socket %x\n", ebx - mov eax, ebx - add ebx, SOCKET.lock - call wait_mutex + mov eax, ebx + add ebx, SOCKET.lock + call wait_mutex - mov esi, edx - jmp SOCKET_input + mov esi, edx + jmp SOCKET_input .checksum_mismatch: - DEBUGF 1,"ICMP_Handler - checksum mismatch\n" + DEBUGF 1,"ICMP_Handler - checksum mismatch\n" .dump: - DEBUGF 1,"ICMP_Handler - dumping\n" + DEBUGF 1,"ICMP_Handler - dumping\n" - call kernel_free - add esp, 4 ; pop (balance stack) + call kernel_free + add esp, 4 ; pop (balance stack) - ret + ret ;----------------------------------------------------------------- @@ -292,55 +292,55 @@ ICMP_input: align 4 ICMP_output: - DEBUGF 1,"Creating ICMP Packet\n" + DEBUGF 1,"Creating ICMP Packet\n" - push esi edi edx + push esi edi edx - mov ebx, [eax + IP_SOCKET.LocalIP] - mov eax, [eax + IP_SOCKET.RemoteIP] - add ecx, sizeof.ICMP_header - mov di , IP_PROTO_ICMP SHL 8 + 128 ; TTL - shr edx, 16 + mov ebx, [eax + IP_SOCKET.LocalIP] + mov eax, [eax + IP_SOCKET.RemoteIP] + add ecx, sizeof.ICMP_header + mov di , IP_PROTO_ICMP SHL 8 + 128 ; TTL + shr edx, 16 - call IPv4_output - jz .exit + call IPv4_output + jz .exit - DEBUGF 1,"full icmp packet size: %u\n", edx + DEBUGF 1,"full icmp packet size: %u\n", edx - pop eax - mov word [edi + ICMP_header.Type], ax ; Write both type and code bytes at once - pop eax - mov [edi + ICMP_header.SequenceNumber], ax - shr eax, 16 - mov [edi + ICMP_header.Identifier], ax - mov [edi + ICMP_header.Checksum], 0 + pop eax + mov word [edi + ICMP_header.Type], ax ; Write both type and code bytes at once + pop eax + mov [edi + ICMP_header.SequenceNumber], ax + shr eax, 16 + mov [edi + ICMP_header.Identifier], ax + mov [edi + ICMP_header.Checksum], 0 - push eax ebx ecx edx - mov esi, edi - xor edx, edx - call checksum_1 - call checksum_2 - mov [edi + ICMP_header.Checksum], dx - pop edx ecx ebx eax esi + push eax ebx ecx edx + mov esi, edi + xor edx, edx + call checksum_1 + call checksum_2 + mov [edi + ICMP_header.Checksum], dx + pop edx ecx ebx eax esi - sub ecx, sizeof.ICMP_header - add edi, sizeof.ICMP_header - push cx - shr cx , 2 - rep movsd - pop cx - and cx , 3 - rep movsb + sub ecx, sizeof.ICMP_header + add edi, sizeof.ICMP_header + push cx + shr cx , 2 + rep movsd + pop cx + and cx , 3 + rep movsb - sub edi, edx ;;; TODO: find a better way to remember start of packet - push edx edi - DEBUGF 1,"Sending ICMP Packet\n" - call [ebx + NET_DEVICE.transmit] - ret + sub edi, edx ;;; TODO: find a better way to remember start of packet + push edx edi + DEBUGF 1,"Sending ICMP Packet\n" + call [ebx + NET_DEVICE.transmit] + ret .exit: - DEBUGF 1,"Creating ICMP Packet failed\n" - add esp, 3*4 - ret + DEBUGF 1,"Creating ICMP Packet failed\n" + add esp, 3*4 + ret @@ -357,41 +357,41 @@ ICMP_output: align 4 ICMP_output_raw: - DEBUGF 1,"Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx + DEBUGF 1,"Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx - push edx + push edx - mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL - shr edx, 16 - mov ebx, [eax + IP_SOCKET.LocalIP] - mov eax, [eax + IP_SOCKET.RemoteIP] - call IPv4_output - jz .exit + mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL + shr edx, 16 + mov ebx, [eax + IP_SOCKET.LocalIP] + mov eax, [eax + IP_SOCKET.RemoteIP] + call IPv4_output + jz .exit - pop esi - push edx - push eax + pop esi + push edx + push eax - push edi ecx - DEBUGF 1,"copying %u bytes from %x to %x\n", ecx, esi, edi - rep movsb - pop ecx edi + push edi ecx + DEBUGF 1,"copying %u bytes from %x to %x\n", ecx, esi, edi + rep movsb + pop ecx edi - mov [edi + ICMP_header.Checksum], 0 + mov [edi + ICMP_header.Checksum], 0 - mov esi, edi - xor edx, edx - call checksum_1 - call checksum_2 - mov [edi + ICMP_header.Checksum], dx + mov esi, edi + xor edx, edx + call checksum_1 + call checksum_2 + mov [edi + ICMP_header.Checksum], dx - DEBUGF 1,"Sending ICMP Packet\n" - call [ebx + NET_DEVICE.transmit] - ret + DEBUGF 1,"Sending ICMP Packet\n" + call [ebx + NET_DEVICE.transmit] + ret .exit: - DEBUGF 1,"Creating ICMP Packet failed\n" - add esp, 4 - ret + DEBUGF 1,"Creating ICMP Packet failed\n" + add esp, 4 + ret @@ -412,24 +412,24 @@ ICMP_output_raw: align 4 ICMP_API: - movzx eax, bh - shl eax, 2 + movzx eax, bh + shl eax, 2 - test bl, bl - jz .packets_tx ; 0 - dec bl - jz .packets_rx ; 1 + test bl, bl + jz .packets_tx ; 0 + dec bl + jz .packets_rx ; 1 .error: - mov eax, -1 - ret + mov eax, -1 + ret .packets_tx: - add eax, ICMP_PACKETS_TX - mov eax, [eax] - ret + add eax, ICMP_PACKETS_TX + mov eax, [eax] + ret .packets_rx: - add eax, ICMP_PACKETS_RX - mov eax, [eax] - ret + add eax, ICMP_PACKETS_RX + mov eax, [eax] + ret diff --git a/kernel/branches/net/network/tcp_input.inc b/kernel/branches/net/network/tcp_input.inc index 9fa92058d7..eca405d0c1 100644 --- a/kernel/branches/net/network/tcp_input.inc +++ b/kernel/branches/net/network/tcp_input.inc @@ -25,9 +25,7 @@ $Revision$ ; ebx = ptr to device struct ; ecx = segment size ; edx = ptr to TCP segment -; -; esi = ipv4 source address -; edi = ipv4 dest address +; edi = ptr to ipv4 source address, followed by ipv4 dest address ; ; OUT: / ; @@ -39,70 +37,68 @@ TCP_input: DEBUGF 1,"TCP_input size=%u ", ecx ; Offset must be greater than or equal to the size of the standard TCP header (20) and less than or equal to the TCP length. - movzx eax, [edx + TCP_header.DataOffset] - and eax, 0xf0 - shr al, 2 + movzx eax, [edx + TCP_header.DataOffset] + and eax, 0xf0 + shr al, 2 - DEBUGF 1,"headersize=%u\n", eax + DEBUGF 1,"headersize=%u\n", eax - cmp eax, TCP_header.DataOffset - jb .drop_not_locked + cmp eax, TCP_header.DataOffset + jb .drop_not_locked ;------------------------------- ; Now, re-calculate the checksum - push eax ecx edx - pushw [edx + TCP_header.Checksum] - mov [edx + TCP_header.Checksum], 0 - push esi edi - mov esi, edx - TCP_checksum (esp), (esp+4) - pop esi edi ; yes, swap them (we dont need dest addr) - pop cx ; previous checksum - cmp cx, dx - pop edx ecx esi - jnz .drop_not_locked + push eax ecx edx + pushw [edx + TCP_header.Checksum] + mov [edx + TCP_header.Checksum], 0 + mov esi, edx + TCP_checksum (edi), (edi+4) + pop cx ; previous checksum + cmp cx, dx + pop edx ecx esi + jnz .drop_not_locked - DEBUGF 1,"Checksum is correct\n" + DEBUGF 1,"Checksum is correct\n" - sub ecx, esi ; update packet size - jb .drop_not_locked - DEBUGF 1,"we got %u bytes of data\n", ecx + sub ecx, esi ; substract TCP header size from total segment size + jb .drop_not_locked + DEBUGF 1,"we got %u bytes of data\n", ecx ;----------------------------------------------------------------------------------------- ; Check if this packet has a timestamp option (We do it here so we can process it quickly) - cmp esi, TCP_header.DataOffset + 12 ; Timestamp option is 12 bytes - jb .no_timestamp - je .is_ok + cmp esi, TCP_header.DataOffset + 12 ; Timestamp option is 12 bytes + jb .no_timestamp + je .is_ok - cmp byte [edx + sizeof.TCP_header + 12], TCP_OPT_EOL ; end of option list - jne .no_timestamp + cmp byte [edx + sizeof.TCP_header + 12], TCP_OPT_EOL ; end of option list + jne .no_timestamp .is_ok: - test [edx + TCP_header.Flags], TH_SYN ; SYN flag must not be set - jnz .no_timestamp + test [edx + TCP_header.Flags], TH_SYN ; SYN flag must not be set + jnz .no_timestamp - cmp dword [edx + sizeof.TCP_header], 0x0101080a ; Timestamp header - jne .no_timestamp + cmp dword [edx + sizeof.TCP_header], 0x0101080a ; Timestamp header + jne .no_timestamp - DEBUGF 1,"timestamp ok\n" + DEBUGF 1,"timestamp ok\n" - ; TODO: Parse the option - ; TODO: Set a Bit in the TCP to tell all options are parsed + ; TODO: Parse the option + ; TODO: Set a Bit in the TCP to tell all options are parsed .no_timestamp: ;------------------------------------------- ; Convert Big-endian values to little endian - ntohd [edx + TCP_header.SequenceNumber] - ntohd [edx + TCP_header.AckNumber] + ntohd [edx + TCP_header.SequenceNumber] + ntohd [edx + TCP_header.AckNumber] - ntohw [edx + TCP_header.Window] - ntohw [edx + TCP_header.UrgentPointer] - ntohw [edx + TCP_header.SourcePort] - ntohw [edx + TCP_header.DestinationPort] + ntohw [edx + TCP_header.Window] + ntohw [edx + TCP_header.UrgentPointer] + ntohw [edx + TCP_header.SourcePort] + ntohw [edx + TCP_header.DestinationPort] ;------------------------------------------------------------ ; Next thing to do is find the TCPS (thus, the socket pointer) @@ -111,187 +107,187 @@ TCP_input: ; (IP Packet SenderAddress = Remote IP) OR (Remote IP = 0) ; (IP Packet TCP Source Port = remote Port) OR (remote Port = 0) - mov ebx, net_sockets + mov ebx, net_sockets .socket_loop: - mov ebx, [ebx + SOCKET.NextPtr] - or ebx, ebx - jz .drop_with_reset_not_locked + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .drop_with_reset_not_locked - cmp [ebx + SOCKET.Domain], AF_INET4 - jne .socket_loop + cmp [ebx + SOCKET.Domain], AF_INET4 + jne .socket_loop - cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP - jne .socket_loop + cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP + jne .socket_loop - mov ax, [edx + TCP_header.DestinationPort] - cmp [ebx + TCP_SOCKET.LocalPort], ax - jne .socket_loop + mov ax, [edx + TCP_header.DestinationPort] + cmp [ebx + TCP_SOCKET.LocalPort], ax + jne .socket_loop - mov eax, [ebx + IP_SOCKET.RemoteIP] - cmp eax, edi ; edi is source ip from packet - je @f - test eax, eax - jnz .socket_loop + mov eax, [ebx + IP_SOCKET.RemoteIP] + cmp eax, [edi] ; Ipv4 source addres + je @f + test eax, eax + jnz .socket_loop @@: - mov ax, [ebx + TCP_SOCKET.RemotePort] - cmp [edx + TCP_header.SourcePort] , ax - je .found_socket - test ax, ax - jnz .socket_loop + mov ax, [ebx + TCP_SOCKET.RemotePort] + cmp [edx + TCP_header.SourcePort] , ax + je .found_socket + test ax, ax + jnz .socket_loop .found_socket: - DEBUGF 1,"Socket ptr: %x\n", ebx + DEBUGF 1,"Socket ptr: %x\n", ebx ; ebx now contains the pointer to the socket ;---------------------------- ; Check if socket isnt closed - cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSED - je .drop_not_locked + cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSED + je .drop_not_locked ;---------------- ; Lock the socket - cmp [ebx + SOCKET.lock], 0 - jne .drop_not_locked ;;; HACK ! HACK ! dirty fucking HACK ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + cmp [ebx + SOCKET.lock], 0 + jne .drop_not_locked ;;; HACK ! HACK ! dirty fucking HACK ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - add ebx, SOCKET.lock - DEBUGF 1,"lock: %x\n", [ebx] - call wait_mutex - sub ebx, SOCKET.lock + add ebx, SOCKET.lock + DEBUGF 1,"lock: %x\n", [ebx] + call wait_mutex + sub ebx, SOCKET.lock - DEBUGF 1,"Socket locked\n" + DEBUGF 1,"Socket locked\n" ;--------------------------------------- ; unscale the window into a 32 bit value - movzx eax, [edx + TCP_header.Window] - push ecx - mov cl, [ebx + TCP_SOCKET.SND_SCALE] - shl eax, cl - mov dword [edx + TCP_header.Window], eax ; word after window is checksum, we dont need checksum anymore - pop ecx + movzx eax, [edx + TCP_header.Window] + push ecx + mov cl, [ebx + TCP_SOCKET.SND_SCALE] + shl eax, cl + mov dword [edx + TCP_header.Window], eax ; word after window is checksum, we dont need checksum anymore + pop ecx ;----------------------------------- ; Is this socket a listening socket? - test [ebx + SOCKET.options], SO_ACCEPTCON - jz .no_listening_socket + test [ebx + SOCKET.options], SO_ACCEPTCON + jz .no_listening_socket - DEBUGF 1,"Accepting new connection\n" + DEBUGF 1,"Accepting new connection\n" - mov [ebx + SOCKET.lock], 0 - call SOCKET_fork + mov [ebx + SOCKET.lock], 0 + call SOCKET_fork - test eax, eax - jz .drop + test eax, eax + jz .drop - push [edx - sizeof.IPv4_header + IPv4_header.DestinationAddress] ;;; FIXME - pop [eax + IP_SOCKET.LocalIP] + push dword [edi + 4] ; Ipv4 destination addres + pop [eax + IP_SOCKET.LocalIP] - push [edx + TCP_header.DestinationPort] - pop [eax + TCP_SOCKET.LocalPort] + push [edx + TCP_header.DestinationPort] + pop [eax + TCP_SOCKET.LocalPort] - mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN + mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN ; mov [ebx + SOCKET.lock], 0 - mov ebx, eax + mov ebx, eax - jmp .LISTEN + jmp .LISTEN .no_listening_socket: ;------------------------------------- ; Reset idle timer and keepalive timer - mov [ebx + TCP_SOCKET.t_idle], 0 - mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval + mov [ebx + TCP_SOCKET.t_idle], 0 + mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;-------------------- ; Process TCP options - cmp esi, TCP_header.DataOffset ; esi is headersize - je .no_options + cmp esi, TCP_header.DataOffset ; Does header contain any options? + je .no_options - DEBUGF 1,"Segment has options\n" + DEBUGF 1,"Segment has options\n" - cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state - jz .not_uni_xfer ; also no header prediction + cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state + jz .not_uni_xfer ; also no header prediction - lea edi, [edx + sizeof.TCP_header] - lea eax, [edx + esi] + lea eax, [edx + esi] + lea esi, [edx + sizeof.TCP_header] .opt_loop: - cmp edi, eax - jae .no_options + cmp esi, eax ; are we scanning outside of header? + jae .no_options - cmp byte [edi], TCP_OPT_EOL ; end of option list? - jz .no_options + cmp byte [esi], TCP_OPT_EOL ; end of option list? + jz .no_options - cmp byte [edi], TCP_OPT_NOP ; nop ? - jz .opt_nop + cmp byte [esi], TCP_OPT_NOP ; nop ? + jz .opt_nop - cmp byte [edi], TCP_OPT_MAXSEG - je .opt_maxseg + cmp byte [esi], TCP_OPT_MAXSEG + je .opt_maxseg - cmp byte [edi], TCP_OPT_WINDOW - je .opt_window + cmp byte [esi], TCP_OPT_WINDOW + je .opt_window - cmp byte [edi], TCP_OPT_TIMESTAMP - je .opt_timestamp + cmp byte [esi], TCP_OPT_TIMESTAMP + je .opt_timestamp - jmp .no_options ; If we reach here, some unknown options were received, skip them all! + jmp .no_options ; If we reach here, some unknown options were received, skip them all! .opt_nop: - inc edi - jmp .opt_loop + inc edi + jmp .opt_loop .opt_maxseg: - cmp byte [edi+1], 4 - jne .no_options ; error occured, ignore all options! + cmp byte [esi+1], 4 + jne .no_options ; error occured, ignore all options! - test [edx + TCP_header.Flags], TH_SYN - jz @f + test [edx + TCP_header.Flags], TH_SYN + jz @f - movzx eax, word[edi+2] - rol ax, 8 - DEBUGF 1,"Maxseg: %u\n", ax + movzx eax, word[esi+2] + rol ax, 8 + DEBUGF 1,"Maxseg: %u\n", ax - mov [ebx + TCP_SOCKET.t_maxseg], eax + mov [ebx + TCP_SOCKET.t_maxseg], eax @@: - add edi, 4 - jmp .opt_loop + add edi, 4 + jmp .opt_loop .opt_window: - cmp byte [edi+1], 3 - jne .no_options + cmp byte [esi+1], 3 + jne .no_options - test [edx + TCP_header.Flags], TH_SYN - jz @f + test [edx + TCP_header.Flags], TH_SYN + jz @f - DEBUGF 1,"Got window option\n" + DEBUGF 1,"Got window option\n" - ;;;;; + ;;;;; @@: - add edi, 3 - jmp .opt_loop + add edi, 3 + jmp .opt_loop .opt_timestamp: - cmp byte [edi+1], 10 - jne .no_options + cmp byte [esi+1], 10 + jne .no_options - DEBUGF 1,"Got timestamp option\n" + DEBUGF 1,"Got timestamp option\n" - ;;;;; + ;;;;; - add edi, 10 - jmp .opt_loop + add esi, 10 + jmp .opt_loop .no_options: @@ -315,26 +311,26 @@ TCP_input: ; - If the length is not 0 and the ACK didn't move, we're the receiver side of the transfer. ; If the packets are in order (data queue is empty), add the data to the socket buffer and request a delayed ACK - cmp [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED - jnz .not_uni_xfer + cmp [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED + jnz .not_uni_xfer - test [edx + TCP_header.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG - jnz .not_uni_xfer + test [edx + TCP_header.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG + jnz .not_uni_xfer - test [edx + TCP_header.Flags], TH_ACK - jz .not_uni_xfer + test [edx + TCP_header.Flags], TH_ACK + jz .not_uni_xfer - mov eax, [edx + TCP_header.SequenceNumber] - cmp eax, [ebx + TCP_SOCKET.RCV_NXT] - jne .not_uni_xfer + mov eax, [edx + TCP_header.SequenceNumber] + cmp eax, [ebx + TCP_SOCKET.RCV_NXT] + jne .not_uni_xfer - mov eax, dword [edx + TCP_header.Window] - cmp eax, [ebx + TCP_SOCKET.SND_WND] - jne .not_uni_xfer + mov eax, dword [edx + TCP_header.Window] + cmp eax, [ebx + TCP_SOCKET.SND_WND] + jne .not_uni_xfer - mov eax, [ebx + TCP_SOCKET.SND_NXT] - cmp eax, [ebx + TCP_SOCKET.SND_MAX] - jne .not_uni_xfer + mov eax, [ebx + TCP_SOCKET.SND_NXT] + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + jne .not_uni_xfer ;--------------------------------------- ; check if we are sender in the uni-xfer @@ -342,25 +338,25 @@ TCP_input: ; If the following 4 conditions are all true, this segment is a pure ACK. ; ; - The segment contains no data. - test ecx, ecx - jnz .not_sender + test ecx, ecx + jnz .not_sender ; - The congestion window is greater than or equal to the current send window. ; This test is true only if the window is fully open, that is, the connection is not in the middle of slow start or congestion avoidance. - mov eax, [ebx + TCP_SOCKET.SND_CWND] - cmp eax, [ebx + TCP_SOCKET.SND_WND] - jb .not_uni_xfer + mov eax, [ebx + TCP_SOCKET.SND_CWND] + cmp eax, [ebx + TCP_SOCKET.SND_WND] + jb .not_uni_xfer ; - The acknowledgment field in the segment is less than or equal to the maximum sequence number sent. - mov eax, [edx + TCP_header.AckNumber] - cmp eax, [ebx + TCP_SOCKET.SND_MAX] - ja .not_uni_xfer + mov eax, [edx + TCP_header.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + ja .not_uni_xfer ; - The acknowledgment field in the segment is greater than the largest unacknowledged sequence number. - sub eax, [ebx + TCP_SOCKET.SND_UNA] - jbe .not_uni_xfer + sub eax, [ebx + TCP_SOCKET.SND_UNA] + jbe .not_uni_xfer - DEBUGF 1,"Header prediction: we are sender\n" + DEBUGF 1,"Header prediction: we are sender\n" ;--------------------------------- ; Packet is a pure ACK, process it @@ -370,28 +366,28 @@ TCP_input: ;;; TODO ; Delete acknowledged bytes from send buffer - pusha - mov ecx, eax - lea eax, [ebx + STREAM_SOCKET.snd] - call SOCKET_ring_free - popa + pusha + mov ecx, eax + lea eax, [ebx + STREAM_SOCKET.snd] + call SOCKET_ring_free + popa ; update window pointers - mov eax, [edx + TCP_header.AckNumber] - mov [ebx + TCP_SOCKET.SND_UNA], eax + mov eax, [edx + TCP_header.AckNumber] + mov [ebx + TCP_SOCKET.SND_UNA], eax ; Stop retransmit timer - mov [ebx + TCP_SOCKET.timer_retransmission], 0 + mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; Awaken waiting processes - mov [ebx + SOCKET.lock], 0 - mov eax, ebx - call SOCKET_notify_owner + mov [ebx + SOCKET.lock], 0 + mov eax, ebx + call SOCKET_notify_owner ; Generate more output - call TCP_output + call TCP_output - jmp .drop_not_locked + jmp .drop_not_locked ;------------------------------------------------- ; maybe we are the receiver in the uni-xfer then.. @@ -400,32 +396,35 @@ TCP_input: ; - The amount of data in the segment is greater than 0 (data count is in ecx) ; - The acknowledgment field equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment. - mov eax, [edx + TCP_header.AckNumber] - cmp eax, [ebx + TCP_SOCKET.SND_UNA] - jne .not_uni_xfer + mov eax, [edx + TCP_header.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_UNA] + jne .not_uni_xfer ; - The reassembly list of out-of-order segments for the connection is empty (seg_next equals tp). ;;; TODO - jnz .not_uni_xfer + jnz .not_uni_xfer ; Complete processing of received data - DEBUGF 1,"header prediction: we are receiver\nreceiving %u bytes of data\n", ecx + DEBUGF 1,"header prediction: we are receiver\nreceiving %u bytes of data\n", ecx - add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied + add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied - add esi, edx - lea eax, [ebx + STREAM_SOCKET.rcv] - call SOCKET_ring_write ; Add the data to the socket buffer + movzx esi, [edx + TCP_header.DataOffset] + and esi, 0xf0 + shr esi, 2 + add esi, edx + lea eax, [ebx + STREAM_SOCKET.rcv] + call SOCKET_ring_write ; Add the data to the socket buffer - mov eax, ebx - call SOCKET_notify_owner + mov eax, ebx + call SOCKET_notify_owner - or [ebx + TCP_SOCKET.t_flags], TF_DELACK ; Set delayed ack flag + or [ebx + TCP_SOCKET.t_flags], TF_DELACK ; Set delayed ack flag - jmp .drop + jmp .drop @@ -437,7 +436,7 @@ TCP_input: .not_uni_xfer: - DEBUGF 1,"Header prediction failed\n" + DEBUGF 1,"Header prediction failed\n" ; Calculate receive window size @@ -451,13 +450,13 @@ TCP_input: ; mov eax, edx ; @@: - cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN - je .LISTEN + cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN + je .LISTEN - cmp [ebx + TCP_SOCKET.t_state], TCPS_SYN_SENT - je .SYN_SENT + cmp [ebx + TCP_SOCKET.t_state], TCPS_SYN_SENT + je .SYN_SENT - jmp .NOT_LISTEN_OR_SYN_SENT + jmp .NOT_LISTEN_OR_SYN_SENT @@ -467,52 +466,52 @@ TCP_input: align 4 .LISTEN: - DEBUGF 1,"TCP state: listen\n" + DEBUGF 1,"TCP state: listen\n" - test [edx + TCP_header.Flags], TH_RST ;;; TODO: kill new socket on error - jnz .drop + test [edx + TCP_header.Flags], TH_RST ;;; TODO: kill new socket on error + jnz .drop - test [edx + TCP_header.Flags], TH_ACK - jnz .drop_with_reset + test [edx + TCP_header.Flags], TH_ACK + jnz .drop_with_reset - test [edx + TCP_header.Flags], TH_SYN - jz .drop + test [edx + TCP_header.Flags], TH_SYN + jz .drop ;;; TODO: check if it's a broadcast or multicast, and drop if so - push [edx - sizeof.IPv4_header + IPv4_header.SourceAddress] ;;; FIXME - pop [ebx + IP_SOCKET.RemoteIP] + push dword [edi + 4] ; Ipv4 destination addres + pop [ebx + IP_SOCKET.RemoteIP] - push [edx + TCP_header.SourcePort] - pop [ebx + TCP_SOCKET.RemotePort] + push [edx + TCP_header.SourcePort] + pop [ebx + TCP_SOCKET.RemotePort] - push [edx + TCP_header.SequenceNumber] - pop [ebx + TCP_SOCKET.IRS] + push [edx + TCP_header.SequenceNumber] + pop [ebx + TCP_SOCKET.IRS] - push [TCP_sequence_num] ;;;;; - add [TCP_sequence_num], 64000 / 2 - pop [ebx + TCP_SOCKET.ISS] + push [TCP_sequence_num] ;;;;; + add [TCP_sequence_num], 64000 / 2 + pop [ebx + TCP_SOCKET.ISS] - push [ebx + TCP_SOCKET.ISS] - pop [ebx + TCP_SOCKET.SND_NXT] + push [ebx + TCP_SOCKET.ISS] + pop [ebx + TCP_SOCKET.SND_NXT] - TCP_sendseqinit ebx - TCP_rcvseqinit ebx + TCP_sendseqinit ebx + TCP_rcvseqinit ebx - mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED - mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;;;; macro + mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED + mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;;;; macro - lea eax, [ebx + STREAM_SOCKET.snd] - call SOCKET_ring_create + lea eax, [ebx + STREAM_SOCKET.snd] + call SOCKET_ring_create - lea eax, [ebx + STREAM_SOCKET.rcv] - call SOCKET_ring_create + lea eax, [ebx + STREAM_SOCKET.rcv] + call SOCKET_ring_create ;;; call SOCKET_notify_owner - jmp .trim_then_step6 - + jmp .trim_then_step6 + @@ -528,87 +527,87 @@ align 4 align 4 .SYN_SENT: - DEBUGF 1,"TCP state: syn_sent\n" + DEBUGF 1,"TCP state: syn_sent\n" - test [edx + TCP_header.Flags], TH_ACK - jz @f + test [edx + TCP_header.Flags], TH_ACK + jz @f - mov eax, [edx + TCP_header.AckNumber] - cmp eax, [ebx + TCP_SOCKET.ISS] - jbe .drop_with_reset + mov eax, [edx + TCP_header.AckNumber] + cmp eax, [ebx + TCP_SOCKET.ISS] + jbe .drop_with_reset - cmp eax, [ebx + TCP_SOCKET.SND_MAX] - ja .drop_with_reset + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + ja .drop_with_reset @@: - test [edx + TCP_header.Flags], TH_RST - jz @f + test [edx + TCP_header.Flags], TH_RST + jz @f - test [edx + TCP_header.Flags], TH_ACK - jz .drop + test [edx + TCP_header.Flags], TH_ACK + jz .drop - mov eax, ebx - mov ebx, ECONNREFUSED - call TCP_drop + mov eax, ebx + mov ebx, ECONNREFUSED + call TCP_drop - jmp .drop + jmp .drop @@: - test [edx + TCP_header.Flags], TH_SYN - jz .drop + test [edx + TCP_header.Flags], TH_SYN + jz .drop ; at this point, segment seems to be valid - test [edx + TCP_header.Flags], TH_ACK - jz .no_syn_ack + test [edx + TCP_header.Flags], TH_ACK + jz .no_syn_ack ; now, process received SYN in response to an active open - mov eax, [edx + TCP_header.AckNumber] - mov [ebx + TCP_SOCKET.SND_UNA], eax - cmp eax, [ebx + TCP_SOCKET.SND_NXT] - jbe @f - mov [ebx + TCP_SOCKET.SND_NXT], eax + mov eax, [edx + TCP_header.AckNumber] + mov [ebx + TCP_SOCKET.SND_UNA], eax + cmp eax, [ebx + TCP_SOCKET.SND_NXT] + jbe @f + mov [ebx + TCP_SOCKET.SND_NXT], eax @@: .no_syn_ack: - mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; disable retransmission + mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; disable retransmission - push [edx + TCP_header.SequenceNumber] - pop [ebx + TCP_SOCKET.IRS] + push [edx + TCP_header.SequenceNumber] + pop [ebx + TCP_SOCKET.IRS] - TCP_rcvseqinit ebx + TCP_rcvseqinit ebx - or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - mov eax, [ebx + TCP_SOCKET.SND_UNA] - cmp eax, [ebx + TCP_SOCKET.ISS] - jbe .simultaneous_open + mov eax, [ebx + TCP_SOCKET.SND_UNA] + cmp eax, [ebx + TCP_SOCKET.ISS] + jbe .simultaneous_open - test [edx + TCP_header.Flags], TH_ACK - jz .simultaneous_open + test [edx + TCP_header.Flags], TH_ACK + jz .simultaneous_open - DEBUGF 1,"TCP: active open\n" + DEBUGF 1,"TCP: active open\n" ;;; TODO: update stats ; set socket state to connected - mov [ebx + SOCKET.state],1 ;;;; FIXME + mov [ebx + SOCKET.state],1 ;;;; FIXME - mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED + mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED ;;; TODO: check if we should scale the connection (567-572) ;;; TODO: update RTT estimators - jmp .trim_then_step6 + jmp .trim_then_step6 .simultaneous_open: - DEBUGF 1,"TCP: simultaneous open\n" + DEBUGF 1,"TCP: simultaneous open\n" ; We have received a syn but no ACK, so we are having a simultaneous open.. - mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED + mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED @@ -621,16 +620,16 @@ align 4 .trim_then_step6: - inc [edx + TCP_header.SequenceNumber] + inc [edx + TCP_header.SequenceNumber] ;;; TODO: Drop any received data that follows receive window (590) - mov eax, [edx + TCP_header.SequenceNumber] - mov [ebx + TCP_SOCKET.RCV_UP], eax - dec eax - mov [ebx + TCP_SOCKET.SND_WL1], eax + mov eax, [edx + TCP_header.SequenceNumber] + mov [ebx + TCP_SOCKET.RCV_UP], eax + dec eax + mov [ebx + TCP_SOCKET.SND_WL1], eax - jmp .ack_processed + jmp .ack_processed @@ -641,7 +640,7 @@ align 4 .NOT_LISTEN_OR_SYN_SENT: - DEBUGF 1,"Slow TCP input: not listen or syn_sent state\n" + DEBUGF 1,"Slow TCP input: not listen or syn_sent state\n" ;-------------------------------------------- ; Protection Against Wrapped Sequence Numbers @@ -666,54 +665,54 @@ align 4 ; check for duplicate data at beginning of segment - mov eax, [ebx + TCP_SOCKET.RCV_NXT] - sub eax, [edx + TCP_header.SequenceNumber] - jbe .no_duplicate + mov eax, [ebx + TCP_SOCKET.RCV_NXT] + sub eax, [edx + TCP_header.SequenceNumber] + jbe .no_duplicate - DEBUGF 1,"Uh oh.. %u bytes of duplicate data!\n", eax + DEBUGF 1,"Uh oh.. %u bytes of duplicate data!\n", eax - test [edx + TCP_header.Flags], TH_SYN - jz .no_dup_syn + test [edx + TCP_header.Flags], TH_SYN + jz .no_dup_syn ; remove duplicate syn - and [edx + TCP_header.Flags], not (TH_SYN) - inc [edx + TCP_header.SequenceNumber] + and [edx + TCP_header.Flags], not (TH_SYN) + inc [edx + TCP_header.SequenceNumber] - cmp [edx + TCP_header.UrgentPointer], 1 - jbe @f - dec [edx + TCP_header.UrgentPointer] - jmp .dup_syn + cmp [edx + TCP_header.UrgentPointer], 1 + jbe @f + dec [edx + TCP_header.UrgentPointer] + jmp .dup_syn @@: - and [edx + TCP_header.Flags], not (TH_URG) + and [edx + TCP_header.Flags], not (TH_URG) .dup_syn: - dec eax + dec eax .no_dup_syn: ; eax holds number of bytes to drop ; Check for entire duplicate packet - cmp eax, ecx - jae .duplicate + cmp eax, ecx + jae .duplicate - DEBUGF 1,"Going to drop %u out of %u bytes\n", eax, ecx + DEBUGF 1,"Going to drop %u out of %u bytes\n", eax, ecx ;;; TODO: apply figure 28.30 ; Check for duplicate FIN - test [edx + TCP_header.Flags], TH_FIN - jz @f - inc ecx - cmp eax, ecx - dec ecx - jne @f + test [edx + TCP_header.Flags], TH_FIN + jz @f + inc ecx + cmp eax, ecx + dec ecx + jne @f - mov eax, ecx - and [edx + TCP_header.Flags], not TH_FIN - or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - jmp .no_duplicate + mov eax, ecx + and [edx + TCP_header.Flags], not TH_FIN + or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + jmp .no_duplicate @@: ; Handle the case when a bound socket connects to itself @@ -724,73 +723,73 @@ align 4 ; This code also handles simultaneous half-open or self-connects - test eax, eax - jnz .drop_after_ack + test eax, eax + jnz .drop_after_ack - cmp [edx + TCP_header.Flags], TH_ACK - jz .drop_after_ack + cmp [edx + TCP_header.Flags], TH_ACK + jz .drop_after_ack .duplicate: - DEBUGF 1,"Duplicate received\n" + DEBUGF 1,"Duplicate received\n" ;---------------------------------------- ; Update statistics for duplicate packets ;;; TODO - jmp .drop_after_ack + jmp .drop_after_ack .no_duplicate: ;----------------------------------------------- ; Remove duplicate data and update urgent offset - add [edx + TCP_header.SequenceNumber], eax + add [edx + TCP_header.SequenceNumber], eax ;;; TODO - sub [edx + TCP_header.UrgentPointer], ax - ja @f + sub [edx + TCP_header.UrgentPointer], ax + ja @f - and [edx + TCP_header.Flags], not (TH_URG) - mov [edx + TCP_header.UrgentPointer], 0 + and [edx + TCP_header.Flags], not (TH_URG) + mov [edx + TCP_header.UrgentPointer], 0 @@: ;-------------------------------------------------- ; Handle data that arrives after process terminates - cmp [ebx + SOCKET.PID], 0 - ja @f + cmp [ebx + SOCKET.PID], 0 + ja @f - cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT - jbe @f + cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT + jbe @f - test ecx, ecx - jz @f + test ecx, ecx + jz @f ;;; Close the socket ;;; update stats - jmp .drop_with_reset + jmp .drop_with_reset @@: ;---------------------------------------- ; Remove data beyond right edge of window - mov eax, [edx + TCP_header.SequenceNumber] - add eax, ecx - sub eax, [ebx + TCP_SOCKET.RCV_NXT] - sub ax, [ebx + TCP_SOCKET.RCV_WND] + mov eax, [edx + TCP_header.SequenceNumber] + add eax, ecx + sub eax, [ebx + TCP_SOCKET.RCV_NXT] + sub ax, [ebx + TCP_SOCKET.RCV_WND] ; eax now holds the number of bytes to drop - jbe .no_excess_data + jbe .no_excess_data ;;; TODO: update stats - cmp eax, ecx - jb .dont_drop_all + cmp eax, ecx + jb .dont_drop_all ;;; TODO 700-736 @@ -817,54 +816,54 @@ align 4 ;------------------ ; Process RST flags - test [edx + TCP_header.Flags], TH_RST - jz .rst_skip + test [edx + TCP_header.Flags], TH_RST + jz .rst_skip - DEBUGF 1,"Got an RST flag" + DEBUGF 1,"Got an RST flag" - mov eax, [ebx + TCP_SOCKET.t_state] - shl eax, 2 - jmp dword [eax + .rst_sw_list] + mov eax, [ebx + TCP_SOCKET.t_state] + shl eax, 2 + jmp dword [eax + .rst_sw_list] .rst_sw_list: - dd .rst_skip ;TCPS_CLOSED - dd .rst_skip ;TCPS_LISTEN - dd .rst_skip ;TCPS_SYN_SENT - dd .econnrefused ;TCPS_SYN_RECEIVED - dd .econnreset ;TCPS_ESTABLISHED - dd .econnreset ;TCPS_CLOSE_WAIT - dd .econnreset ;TCPS_FIN_WAIT_1 - dd .rst_close ;TCPS_CLOSING - dd .rst_close ;TCPS_LAST_ACK - dd .econnreset ;TCPS_FIN_WAIT_2 - dd .rst_close ;TCPS_TIMED_WAIT + dd .rst_skip ;TCPS_CLOSED + dd .rst_skip ;TCPS_LISTEN + dd .rst_skip ;TCPS_SYN_SENT + dd .econnrefused ;TCPS_SYN_RECEIVED + dd .econnreset ;TCPS_ESTABLISHED + dd .econnreset ;TCPS_CLOSE_WAIT + dd .econnreset ;TCPS_FIN_WAIT_1 + dd .rst_close ;TCPS_CLOSING + dd .rst_close ;TCPS_LAST_ACK + dd .econnreset ;TCPS_FIN_WAIT_2 + dd .rst_close ;TCPS_TIMED_WAIT .econnrefused: - DEBUGF 1,"Connection refused" + DEBUGF 1,"Connection refused" - mov [ebx + SOCKET.errorcode], ECONNREFUSED - jmp .close + mov [ebx + SOCKET.errorcode], ECONNREFUSED + jmp .close .econnreset: - DEBUGF 1,"Connection reset" + DEBUGF 1,"Connection reset" - mov [ebx + SOCKET.errorcode], ECONNRESET + mov [ebx + SOCKET.errorcode], ECONNRESET .close: - DEBUGF 1,"Closing connection" + DEBUGF 1,"Closing connection" - mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSED - ;;; TODO: update stats - mov eax, ebx - call TCP_close - jmp .drop + mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSED + ;;; TODO: update stats + mov eax, ebx + call TCP_close + jmp .drop .rst_close: - DEBUGF 1,"Closing with reset\n" + DEBUGF 1,"Closing with reset\n" - mov eax, ebx - call TCP_close - jmp .drop + mov eax, ebx + call TCP_close + jmp .drop @@ -878,16 +877,16 @@ align 4 ;-------------------------------------- ; handle SYN-full and ACK-less segments - test [edx + TCP_header.Flags], TH_SYN - jz @f + test [edx + TCP_header.Flags], TH_SYN + jz @f - mov eax, ebx - mov ebx, ECONNRESET - call TCP_drop - jmp .drop_with_reset + mov eax, ebx + mov ebx, ECONNRESET + call TCP_drop + jmp .drop_with_reset - test [edx + TCP_header.Flags], TH_ACK - jz .drop + test [edx + TCP_header.Flags], TH_ACK + jz .drop @@: @@ -899,129 +898,129 @@ align 4 ;--------------- ; ACK processing - cmp [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED - jnz .no_syn_rcv + cmp [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED + jnz .no_syn_rcv - DEBUGF 1,"TCP state = syn received\n" + DEBUGF 1,"TCP state = syn received\n" - mov eax, [edx + TCP_header.AckNumber] - cmp [ebx + TCP_SOCKET.SND_UNA], eax - ja .drop_with_reset - cmp eax, [ebx + TCP_SOCKET.SND_MAX] - ja .drop_with_reset + mov eax, [edx + TCP_header.AckNumber] + cmp [ebx + TCP_SOCKET.SND_UNA], eax + ja .drop_with_reset + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + ja .drop_with_reset - ;;; update stats - mov eax, ebx - call SOCKET_is_connected - mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED + ;;; update stats + mov eax, ebx + call SOCKET_is_connected + mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED ; Do window scaling? - test [ebx + TCP_SOCKET.t_flags], TF_RCVD_SCALE - jz @f - test [ebx + TCP_SOCKET.t_flags], TF_REQ_SCALE - jz @f + test [ebx + TCP_SOCKET.t_flags], TF_RCVD_SCALE + jz @f + test [ebx + TCP_SOCKET.t_flags], TF_REQ_SCALE + jz @f - ;;; 810-811 + ;;; 810-811 @@: - ;;; 813 ? + ;;; 813 ? - mov eax, [edx + TCP_header.SequenceNumber] - dec eax - mov [ebx + TCP_SOCKET.SND_WL1], eax - jmp .not_dup_ack + mov eax, [edx + TCP_header.SequenceNumber] + dec eax + mov [ebx + TCP_SOCKET.SND_WL1], eax + jmp .not_dup_ack .no_syn_rcv: ; check for duplicate ACK - mov eax, [edx + TCP_header.AckNumber] - cmp eax, [ebx + TCP_SOCKET.SND_UNA] - ja .not_dup_ack + mov eax, [edx + TCP_header.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_UNA] + ja .not_dup_ack - test ecx, ecx - jnz .reset_dupacks + test ecx, ecx + jnz .reset_dupacks - mov eax, dword [edx + TCP_header.Window] - cmp eax, [ebx + TCP_SOCKET.SND_WND] - jne .reset_dupacks + mov eax, dword [edx + TCP_header.Window] + cmp eax, [ebx + TCP_SOCKET.SND_WND] + jne .reset_dupacks - DEBUGF 1,"Processing a duplicate ACK..\n" + DEBUGF 1,"Processing a duplicate ACK..\n" - cmp [ebx + TCP_SOCKET.timer_retransmission], 10000 ;;;; - ja @f + cmp [ebx + TCP_SOCKET.timer_retransmission], 10000 ;;;; + ja @f - mov eax, [edx + TCP_header.AckNumber] - cmp eax, [ebx + TCP_SOCKET.SND_UNA] - je .dup_ack + mov eax, [edx + TCP_header.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_UNA] + je .dup_ack @@: - mov [ebx + TCP_SOCKET.t_dupacks], 0 - jmp .not_dup_ack + mov [ebx + TCP_SOCKET.t_dupacks], 0 + jmp .not_dup_ack .dup_ack: - inc [ebx + TCP_SOCKET.t_dupacks] - cmp [ebx + TCP_SOCKET.t_dupacks], TCP_re_xmit_thresh - jne .no_re_xmit + inc [ebx + TCP_SOCKET.t_dupacks] + cmp [ebx + TCP_SOCKET.t_dupacks], TCP_re_xmit_thresh + jne .no_re_xmit - push [ebx + TCP_SOCKET.SND_NXT] ; >>>> + push [ebx + TCP_SOCKET.SND_NXT] ; >>>> - mov eax, [ebx + TCP_SOCKET.SND_WND] - cmp eax, [ebx + TCP_SOCKET.SND_CWND] - cmovg eax, [ebx + TCP_SOCKET.SND_CWND] - shr eax, 1 - push edx - xor edx, edx - div [ebx + TCP_SOCKET.t_maxseg] - cmp eax, 2 - jae @f - mov ax, 2 + mov eax, [ebx + TCP_SOCKET.SND_WND] + cmp eax, [ebx + TCP_SOCKET.SND_CWND] + cmovg eax, [ebx + TCP_SOCKET.SND_CWND] + shr eax, 1 + push edx + xor edx, edx + div [ebx + TCP_SOCKET.t_maxseg] + cmp eax, 2 + jae @f + mov ax, 2 @@: - mul [ebx + TCP_SOCKET.t_maxseg] - pop edx - mov [ebx + TCP_SOCKET.SND_SSTHRESH], eax + mul [ebx + TCP_SOCKET.t_maxseg] + pop edx + mov [ebx + TCP_SOCKET.SND_SSTHRESH], eax - mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; turn off retransmission timer - mov [ebx + TCP_SOCKET.t_rtt], 0 - mov eax, [edx + TCP_header.AckNumber] - mov [ebx + TCP_SOCKET.SND_NXT], eax - mov eax, [ebx + TCP_SOCKET.t_maxseg] - mov [ebx + TCP_SOCKET.SND_CWND], eax + mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; turn off retransmission timer + mov [ebx + TCP_SOCKET.t_rtt], 0 + mov eax, [edx + TCP_header.AckNumber] + mov [ebx + TCP_SOCKET.SND_NXT], eax + mov eax, [ebx + TCP_SOCKET.t_maxseg] + mov [ebx + TCP_SOCKET.SND_CWND], eax - mov eax, ebx - call TCP_output ; retransmit missing segment + mov eax, ebx + call TCP_output ; retransmit missing segment - push edx - xor edx, edx - mov eax, [ebx + TCP_SOCKET.t_maxseg] - mul [ebx + TCP_SOCKET.t_dupacks] - pop edx - add eax, [ebx + TCP_SOCKET.SND_SSTHRESH] - mov [ebx + TCP_SOCKET.SND_CWND], eax + push edx + xor edx, edx + mov eax, [ebx + TCP_SOCKET.t_maxseg] + mul [ebx + TCP_SOCKET.t_dupacks] + pop edx + add eax, [ebx + TCP_SOCKET.SND_SSTHRESH] + mov [ebx + TCP_SOCKET.SND_CWND], eax - pop eax ; <<<< - cmp eax, [ebx + TCP_SOCKET.SND_NXT] - jb @f - mov [ebx + TCP_SOCKET.SND_NXT], eax + pop eax ; <<<< + cmp eax, [ebx + TCP_SOCKET.SND_NXT] + jb @f + mov [ebx + TCP_SOCKET.SND_NXT], eax @@: - jmp .drop + jmp .drop .no_re_xmit: - jbe .not_dup_ack + jbe .not_dup_ack - DEBUGF 1,"Increasing congestion window\n" + DEBUGF 1,"Increasing congestion window\n" - mov eax, [ebx + TCP_SOCKET.t_maxseg] - add [ebx + TCP_SOCKET.SND_CWND], eax + mov eax, [ebx + TCP_SOCKET.t_maxseg] + add [ebx + TCP_SOCKET.SND_CWND], eax - mov eax, ebx - call TCP_output + mov eax, ebx + call TCP_output - jmp .drop + jmp .drop @@ -1034,32 +1033,32 @@ align 4 ; If the congestion window was inflated to account ; for the other side's cached packets, retract it - mov eax, [ebx + TCP_SOCKET.SND_SSTHRESH] - cmp eax, [ebx + TCP_SOCKET.SND_CWND] - ja @f - cmp [ebx + TCP_SOCKET.t_dupacks], TCP_re_xmit_thresh - jbe @f - mov [ebx + TCP_SOCKET.SND_CWND], eax + mov eax, [ebx + TCP_SOCKET.SND_SSTHRESH] + cmp eax, [ebx + TCP_SOCKET.SND_CWND] + ja @f + cmp [ebx + TCP_SOCKET.t_dupacks], TCP_re_xmit_thresh + jbe @f + mov [ebx + TCP_SOCKET.SND_CWND], eax @@: - mov [ebx + TCP_SOCKET.t_dupacks], 0 + mov [ebx + TCP_SOCKET.t_dupacks], 0 - mov eax, [edx + TCP_header.AckNumber] - cmp eax, [ebx + TCP_SOCKET.SND_MAX] - jbe @f + mov eax, [edx + TCP_header.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + jbe @f - ;;; TODO: update stats - jmp .drop_after_ack + ;;; TODO: update stats + jmp .drop_after_ack @@: - mov edi, [edx + TCP_header.AckNumber] - sub edi, [ebx + TCP_SOCKET.SND_UNA] ; now we got the number of acked bytes in esi + mov edi, [edx + TCP_header.AckNumber] + sub edi, [ebx + TCP_SOCKET.SND_UNA] ; now we got the number of acked bytes in edi - ;;; TODO: update stats + ;;; TODO: update stats - DEBUGF 1,"We have an acceptable ACK of %x bytes\n", esi + DEBUGF 1,"We have an acceptable ACK of %x bytes\n", esi @@ -1069,14 +1068,14 @@ align 4 ;------------------------------------------ ; RTT measurements and retransmission timer - ;;;;; 912 - 926 + ;;;;; 912 - 926 - mov [ebx + TCP_SOCKET.timer_retransmission], 0 + mov [ebx + TCP_SOCKET.timer_retransmission], 0 - mov eax, [ebx + TCP_SOCKET.SND_MAX] - cmp eax, [edx + TCP_header.AckNumber] - je .all_outstanding - mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value (use a macro for it) + mov eax, [ebx + TCP_SOCKET.SND_MAX] + cmp eax, [edx + TCP_header.AckNumber] + je .all_outstanding + mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value (use a macro for it) .all_outstanding: @@ -1088,32 +1087,32 @@ align 4 ;------------------------------------------- ; Open congestion window in response to ACKs - mov esi, [ebx + TCP_SOCKET.SND_CWND] - mov eax, [ebx + TCP_SOCKET.t_maxseg] + mov esi, [ebx + TCP_SOCKET.SND_CWND] + mov eax, [ebx + TCP_SOCKET.t_maxseg] - cmp esi, [ebx + TCP_SOCKET.SND_SSTHRESH] - jbe @f - push edx - push eax - mul eax - div esi - pop edx - shr edx, 3 - add eax, edx - pop edx + cmp esi, [ebx + TCP_SOCKET.SND_SSTHRESH] + jbe @f + push edx + push eax + mul eax + div esi + pop edx + shr edx, 3 + add eax, edx + pop edx @@: - add esi, eax + add esi, eax - push ecx - mov cl, [ebx + TCP_SOCKET.SND_SCALE] - mov eax, TCP_max_win - shl eax, cl - pop ecx + push ecx + mov cl, [ebx + TCP_SOCKET.SND_SCALE] + mov eax, TCP_max_win + shl eax, cl + pop ecx - cmp esi, eax - cmovg esi, eax - mov [ebx + TCP_SOCKET.SND_CWND], esi + cmp esi, eax + cmovg esi, eax + mov [ebx + TCP_SOCKET.SND_CWND], esi @@ -1124,31 +1123,31 @@ align 4 ;------------------------------------------ ; Remove acknowledged data from send buffer - push ecx edx ebx - mov ecx, edi - lea eax, [ebx + STREAM_SOCKET.snd] - call SOCKET_ring_free - pop ebx - sub [ebx + TCP_SOCKET.SND_WND], ecx - pop edx ecx + push ecx edx ebx + mov ecx, edi + lea eax, [ebx + STREAM_SOCKET.snd] + call SOCKET_ring_free + pop ebx + sub [ebx + TCP_SOCKET.SND_WND], ecx + pop edx ecx ; Wake up process waiting on send buffer - mov eax, ebx - call SOCKET_notify_owner + mov eax, ebx + call SOCKET_notify_owner ; Update TCPS - mov eax, [edx + TCP_header.AckNumber] - mov [ebx + TCP_SOCKET.SND_UNA], eax + mov eax, [edx + TCP_header.AckNumber] + mov [ebx + TCP_SOCKET.SND_UNA], eax - cmp eax, [ebx + TCP_SOCKET.SND_NXT] - jb @f - mov [ebx + TCP_SOCKET.SND_NXT], eax + cmp eax, [ebx + TCP_SOCKET.SND_NXT] + jb @f + mov [ebx + TCP_SOCKET.SND_NXT], eax @@: - ;; TODO: use zero flag as 'ourfinisacked' + ;; TODO: use zero flag as 'ourfinisacked' @@ -1156,61 +1155,61 @@ align 4 ; General ACK handling complete ; Now do the state-specific ones - mov eax, [ebx + TCP_SOCKET.t_state] - jmp dword [eax*4 + .ACK_sw_list] + mov eax, [ebx + TCP_SOCKET.t_state] + jmp dword [eax*4 + .ACK_sw_list] .ACK_sw_list: - dd .ack_processed ;TCPS_CLOSED - dd .ack_processed ;TCPS_LISTEN - dd .ack_processed ;TCPS_SYN_SENT - dd .ack_processed ;TCPS_SYN_RECEIVED - dd .ack_processed ;TCPS_ESTABLISHED - dd .ack_processed ;TCPS_CLOSE_WAIT - dd .ack_fw1 ;TCPS_FIN_WAIT_1 - dd .ack_c ;TCPS_CLOSING - dd .ack_la ;TCPS_LAST_ACK - dd .ack_processed ;TCPS_FIN_WAIT_2 - dd .ack_tw ;TCPS_TIMED_WAIT + dd .ack_processed ;TCPS_CLOSED + dd .ack_processed ;TCPS_LISTEN + dd .ack_processed ;TCPS_SYN_SENT + dd .ack_processed ;TCPS_SYN_RECEIVED + dd .ack_processed ;TCPS_ESTABLISHED + dd .ack_processed ;TCPS_CLOSE_WAIT + dd .ack_fw1 ;TCPS_FIN_WAIT_1 + dd .ack_c ;TCPS_CLOSING + dd .ack_la ;TCPS_LAST_ACK + dd .ack_processed ;TCPS_FIN_WAIT_2 + dd .ack_tw ;TCPS_TIMED_WAIT .ack_fw1: - jz .ack_processed + jz .ack_processed - test [ebx + SOCKET.state], SS_CANTRCVMORE - jnz @f - mov eax, ebx - call SOCKET_is_disconnected + test [ebx + SOCKET.state], SS_CANTRCVMORE + jnz @f + mov eax, ebx + call SOCKET_is_disconnected ;;; mov [ebx + TCP_SOCKET.timer_timed_wait], TCP_time_max_idle @@: - mov [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_2 - jmp .ack_processed + mov [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_2 + jmp .ack_processed .ack_c: - jz .ack_processed + jz .ack_processed - mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT - mov eax, ebx - call TCP_cancel_timers - mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL - mov eax, ebx - call SOCKET_is_disconnected - jmp .ack_processed + mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT + mov eax, ebx + call TCP_cancel_timers + mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL + mov eax, ebx + call SOCKET_is_disconnected + jmp .ack_processed .ack_la: - jz .ack_processed + jz .ack_processed - mov eax, ebx - call TCP_close - jmp .drop + mov eax, ebx + call TCP_close + jmp .drop .ack_tw: - mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL - jmp .drop_after_ack + mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL + jmp .drop_after_ack @@ -1218,42 +1217,42 @@ align 4 - .reset_dupacks: ; We got a new ACK, reset duplicate ACK counter + .reset_dupacks: ; We got a new ACK, reset duplicate ACK counter - mov [ebx + TCP_SOCKET.t_dupacks], 0 + mov [ebx + TCP_SOCKET.t_dupacks], 0 - .ack_processed: ; (step 6) + .ack_processed: ; (step 6) - DEBUGF 1,"ACK processed\n" + DEBUGF 1,"ACK processed\n" ;---------------------------------------------- ; check if we need to update window information - test [edx + TCP_header.Flags], TH_ACK - jz .no_window_update + test [edx + TCP_header.Flags], TH_ACK + jz .no_window_update - mov eax, [ebx + TCP_SOCKET.SND_WL1] - cmp eax, [edx + TCP_header.SequenceNumber] - jb .update_window - ja @f + mov eax, [ebx + TCP_SOCKET.SND_WL1] + cmp eax, [edx + TCP_header.SequenceNumber] + jb .update_window + ja @f - mov eax, [ebx + TCP_SOCKET.SND_WL2] - cmp eax, [edx + TCP_header.AckNumber] - jb .update_window - ja .no_window_update + mov eax, [ebx + TCP_SOCKET.SND_WL2] + cmp eax, [edx + TCP_header.AckNumber] + jb .update_window + ja .no_window_update @@: - mov eax, [ebx + TCP_SOCKET.SND_WL2] - cmp eax, [edx + TCP_header.AckNumber] - jne .no_window_update + mov eax, [ebx + TCP_SOCKET.SND_WL2] + cmp eax, [edx + TCP_header.AckNumber] + jne .no_window_update - movzx eax, [edx + TCP_header.Window] - cmp eax, [ebx + TCP_SOCKET.SND_WND] - jbe .no_window_update + movzx eax, [edx + TCP_header.Window] + cmp eax, [ebx + TCP_SOCKET.SND_WND] + jbe .no_window_update .update_window: - DEBUGF 1,"Updating window\n" + DEBUGF 1,"Updating window\n" ; Keep track of pure window updates @@ -1272,20 +1271,20 @@ align 4 ; ; @@: - mov eax, dword [edx + TCP_header.Window] - cmp eax, [ebx + TCP_SOCKET.max_sndwnd] - jbe @f - mov [ebx + TCP_SOCKET.max_sndwnd], eax + mov eax, dword [edx + TCP_header.Window] + cmp eax, [ebx + TCP_SOCKET.max_sndwnd] + jbe @f + mov [ebx + TCP_SOCKET.max_sndwnd], eax @@: - mov [ebx + TCP_SOCKET.SND_WND], eax + mov [ebx + TCP_SOCKET.SND_WND], eax - push [edx + TCP_header.SequenceNumber] - pop [ebx + TCP_SOCKET.SND_WL1] + push [edx + TCP_header.SequenceNumber] + pop [ebx + TCP_SOCKET.SND_WL1] - push [edx + TCP_header.AckNumber] - pop [ebx + TCP_SOCKET.SND_WL2] + push [edx + TCP_header.AckNumber] + pop [ebx + TCP_SOCKET.SND_WL2] - ;;; needoutput = 1 + ;;; needoutput = 1 .no_window_update: @@ -1298,33 +1297,33 @@ align 4 ;----------------- ; process URG flag - test [edx + TCP_header.Flags], TH_URG - jz .not_urgent + test [edx + TCP_header.Flags], TH_URG + jz .not_urgent - cmp [edx + TCP_header.UrgentPointer], 0 - jz .not_urgent + cmp [edx + TCP_header.UrgentPointer], 0 + jz .not_urgent - cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT - je .not_urgent + cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT + je .not_urgent ; Ignore bogus urgent offsets - ;;; 1040-1050 + ;;; 1040-1050 - movzx eax, [edx + TCP_header.UrgentPointer] - add eax, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.size] - cmp eax, SOCKET_MAXDATA - jbe .not_urgent + movzx eax, [edx + TCP_header.UrgentPointer] + add eax, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.size] + cmp eax, SOCKET_MAXDATA + jbe .not_urgent - mov [edx + TCP_header.UrgentPointer], 0 - and [edx + TCP_header.Flags], not (TH_URG) - jmp .do_data + mov [edx + TCP_header.UrgentPointer], 0 + and [edx + TCP_header.Flags], not (TH_URG) + jmp .do_data .not_urgent: ; processing of received urgent pointer - ;;; TODO (1051-1093) + ;;; TODO (1051-1093) @@ -1338,37 +1337,36 @@ align 4 .do_data: - DEBUGF 1,"TCP: do data (%u)\n", ecx + DEBUGF 1,"TCP: do data (%u)\n", ecx - test [edx + TCP_header.Flags], TH_FIN - jnz .process_fin + test [edx + TCP_header.Flags], TH_FIN + jnz .process_fin - cmp [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_1 - jae .dont_do_data + cmp [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_1 + jae .dont_do_data - test ecx, ecx - jz .final_processing + test ecx, ecx + jz .final_processing - DEBUGF 1,"Processing data in segment\n" + DEBUGF 1,"Processing data in segment\n" ;; TODO: check if data is in sequence ! - movzx eax, [edx + TCP_header.DataOffset] ;;; todo: remember this in.. edi ? - and eax, 0xf0 - shr al, 2 + movzx esi, [edx + TCP_header.DataOffset] + and esi, 0xf0 + shr esi, 2 + add esi, edx - lea esi, [edx + eax] + or [ebx + TCP_SOCKET.t_flags], TF_DELACK + add [ebx + TCP_SOCKET.RCV_NXT], ecx - or [ebx + TCP_SOCKET.t_flags], TF_DELACK - add [ebx + TCP_SOCKET.RCV_NXT], ecx + lea eax, [ebx + STREAM_SOCKET.rcv] + call SOCKET_ring_write - lea eax, [ebx + STREAM_SOCKET.rcv] - call SOCKET_ring_write + mov eax, ebx + call SOCKET_notify_owner - mov eax, ebx - call SOCKET_notify_owner - - jmp .final_processing + jmp .final_processing .dont_do_data: @@ -1384,63 +1382,63 @@ align 4 .process_fin: - DEBUGF 1,"Processing FIN\n" + DEBUGF 1,"Processing FIN\n" - cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT - je .not_first_fin - cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSING - je .not_first_fin - cmp [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_2 - je .not_first_fin + cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT + je .not_first_fin + cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSING + je .not_first_fin + cmp [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_2 + je .not_first_fin - DEBUGF 1,"First FIN for this connection\n" + DEBUGF 1,"First FIN for this connection\n" - mov eax, ebx - call SOCKET_cant_recv_more + mov eax, ebx + call SOCKET_cant_recv_more - mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - inc [ebx + TCP_SOCKET.RCV_NXT] + mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + inc [ebx + TCP_SOCKET.RCV_NXT] .not_first_fin: - mov eax, [ebx + TCP_SOCKET.t_state] - shl eax, 2 - jmp dword [eax + .FIN_sw_list] + mov eax, [ebx + TCP_SOCKET.t_state] + shl eax, 2 + jmp dword [eax + .FIN_sw_list] .FIN_sw_list: - dd .no_fin ;TCPS_CLOSED - dd .no_fin ;TCPS_LISTEN - dd .no_fin ;TCPS_SYN_SENT - dd .fin_syn_est ;TCPS_SYN_RECEIVED - dd .fin_syn_est ;TCPS_ESTABLISHED - dd .no_fin ;TCPS_CLOSE_WAIT - dd .fin_wait1 ;TCPS_FIN_WAIT_1 - dd .no_fin ;TCPS_CLOSING - dd .no_fin ;TCPS_LAST_ACK - dd .fin_wait2 ;TCPS_FIN_WAIT_2 - dd .fin_timed ;TCPS_TIMED_WAIT + dd .no_fin ;TCPS_CLOSED + dd .no_fin ;TCPS_LISTEN + dd .no_fin ;TCPS_SYN_SENT + dd .fin_syn_est ;TCPS_SYN_RECEIVED + dd .fin_syn_est ;TCPS_ESTABLISHED + dd .no_fin ;TCPS_CLOSE_WAIT + dd .fin_wait1 ;TCPS_FIN_WAIT_1 + dd .no_fin ;TCPS_CLOSING + dd .no_fin ;TCPS_LAST_ACK + dd .fin_wait2 ;TCPS_FIN_WAIT_2 + dd .fin_timed ;TCPS_TIMED_WAIT .fin_syn_est: - mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT - jmp .no_fin + mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT + jmp .no_fin .fin_wait1: - mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSING - jmp .no_fin + mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSING + jmp .no_fin .fin_wait2: - mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT - mov eax, ebx - call TCP_cancel_timers - mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL - call SOCKET_is_disconnected - jmp .no_fin + mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT + mov eax, ebx + call TCP_cancel_timers + mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL + call SOCKET_is_disconnected + jmp .no_fin .fin_timed: - mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL - jmp .no_fin + mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL + jmp .no_fin .no_fin: @@ -1456,30 +1454,30 @@ align 4 .final_processing: - DEBUGF 1,"Final processing\n" + DEBUGF 1,"Final processing\n" - ;;; if debug enabled, output packet + ;;; if debug enabled, output packet - ;test needoutput, needoutput - ;jz .dumpit + ;test needoutput, needoutput + ;jz .dumpit - test [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - jz .dumpit + test [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + jz .dumpit - DEBUGF 1,"ACK now!\n" + DEBUGF 1,"ACK now!\n" - push ebx - mov eax, ebx - call TCP_output - pop ebx + push ebx + mov eax, ebx + call TCP_output + pop ebx .dumpit: - mov [ebx + SOCKET.lock], 0 + mov [ebx + SOCKET.lock], 0 - call kernel_free - add esp, 4 - ret + call kernel_free + add esp, 4 + ret @@ -1493,25 +1491,25 @@ align 4 align 4 .drop_after_ack: - DEBUGF 1,"Drop after ACK\n" + DEBUGF 1,"Drop after ACK\n" - test [edx + TCP_header.Flags], TH_RST - jnz .drop + test [edx + TCP_header.Flags], TH_RST + jnz .drop - and [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + and [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - mov [ebx + SOCKET.lock], 0 + mov [ebx + SOCKET.lock], 0 - push ebx + push ebx ; mov cl, TH_ACK ; call TCP_respond_socket - mov eax, ebx - call TCP_output - pop ebx + mov eax, ebx + call TCP_output + pop ebx - call kernel_free - add esp, 4 - ret + call kernel_free + add esp, 4 + ret @@ -1526,45 +1524,45 @@ align 4 align 4 .drop_with_reset: - mov [ebx + SOCKET.lock], 0 + mov [ebx + SOCKET.lock], 0 .drop_with_reset_not_locked: - DEBUGF 1,"Drop with reset\n" + DEBUGF 1,"Drop with reset\n" - test [edx + TCP_header.Flags], TH_RST - jnz .drop + test [edx + TCP_header.Flags], TH_RST + jnz .drop - ;;; if its a multicast/broadcast, also drop + ;;; if its a multicast/broadcast, also drop - test [edx + TCP_header.Flags], TH_ACK - jnz .respond_ack + test [edx + TCP_header.Flags], TH_ACK + jnz .respond_ack - test [edx + TCP_header.Flags], TH_SYN - jnz .respond_syn + test [edx + TCP_header.Flags], TH_SYN + jnz .respond_syn - call kernel_free - add esp, 4 - ret + call kernel_free + add esp, 4 + ret .respond_ack: - push ebx - mov cl, TH_RST - call TCP_respond_socket - pop ebx + push ebx + mov cl, TH_RST + call TCP_respond_socket + pop ebx - jmp .destroy_new_socket + jmp .destroy_new_socket .respond_syn: - push ebx - mov cl, TH_RST + TH_ACK - call TCP_respond_socket - pop ebx + push ebx + mov cl, TH_RST + TH_ACK + call TCP_respond_socket + pop ebx - jmp .destroy_new_socket + jmp .destroy_new_socket @@ -1578,18 +1576,18 @@ align 4 align 4 .drop: - mov [ebx + SOCKET.lock], 0 + mov [ebx + SOCKET.lock], 0 .drop_not_locked: - DEBUGF 1,"Dropping packet\n" + DEBUGF 1,"Dropping packet\n" - ;;;; If debugging options are enabled, output the packet somwhere + ;;;; If debugging options are enabled, output the packet somwhere .destroy_new_socket: - ;;;; kill the newly created socket + ;;;; kill the newly created socket - call kernel_free - add esp, 4 - ret \ No newline at end of file + call kernel_free + add esp, 4 + ret \ No newline at end of file diff --git a/kernel/branches/net/network/tcp_subr.inc b/kernel/branches/net/network/tcp_subr.inc index cdca25efc0..6327f509cd 100644 --- a/kernel/branches/net/network/tcp_subr.inc +++ b/kernel/branches/net/network/tcp_subr.inc @@ -16,65 +16,65 @@ $Revision$ -macro TCP_checksum IP1, IP2 { +macro TCP_checksum IP1, IP2 { ;------------- ; Pseudoheader - ; protocol type - mov edx, IP_PROTO_TCP + ; protocol type + mov edx, IP_PROTO_TCP - ; source address - add dl, byte [IP1+1] - adc dh, byte [IP1+0] - adc dl, byte [IP1+3] - adc dh, byte [IP1+2] + ; source address + add dl, byte [IP1+1] + adc dh, byte [IP1+0] + adc dl, byte [IP1+3] + adc dh, byte [IP1+2] - ; destination address - adc dl, byte [IP2+1] - adc dh, byte [IP2+0] - adc dl, byte [IP2+3] - adc dh, byte [IP2+2] + ; destination address + adc dl, byte [IP2+1] + adc dh, byte [IP2+0] + adc dl, byte [IP2+3] + adc dh, byte [IP2+2] - ; size - adc dl, cl - adc dh, ch + ; size + adc dl, cl + adc dh, ch ;--------------------- ; Real header and data - push esi - call checksum_1 - call checksum_2 - pop esi + push esi + call checksum_1 + call checksum_2 + pop esi -} ; returns in dx only +} ; returns in dx only -macro TCP_sendseqinit ptr { +macro TCP_sendseqinit ptr { - push edi ;;;; i dont like this static use of edi - mov edi, [ptr + TCP_SOCKET.ISS] - mov [ptr + TCP_SOCKET.SND_UP], edi - mov [ptr + TCP_SOCKET.SND_MAX], edi - mov [ptr + TCP_SOCKET.SND_NXT], edi - mov [ptr + TCP_SOCKET.SND_UNA], edi - pop edi + push edi ;;;; i dont like this static use of edi + mov edi, [ptr + TCP_SOCKET.ISS] + mov [ptr + TCP_SOCKET.SND_UP], edi + mov [ptr + TCP_SOCKET.SND_MAX], edi + mov [ptr + TCP_SOCKET.SND_NXT], edi + mov [ptr + TCP_SOCKET.SND_UNA], edi + pop edi } -macro TCP_rcvseqinit ptr { +macro TCP_rcvseqinit ptr { - push edi - mov edi, [ptr + TCP_SOCKET.IRS] - inc edi - mov [ptr + TCP_SOCKET.RCV_NXT], edi - mov [ptr + TCP_SOCKET.RCV_ADV], edi - pop edi + push edi + mov edi, [ptr + TCP_SOCKET.IRS] + inc edi + mov [ptr + TCP_SOCKET.RCV_NXT], edi + mov [ptr + TCP_SOCKET.RCV_ADV], edi + pop edi } @@ -102,11 +102,11 @@ macro TCP_rcvseqinit ptr { align 4 TCP_pull_out_of_band: - DEBUGF 1,"TCP_pull_out_of_band\n" + DEBUGF 1,"TCP_pull_out_of_band\n" - ;;;; 1282-1305 + ;;;; 1282-1305 - ret + ret @@ -128,18 +128,18 @@ TCP_pull_out_of_band: align 4 TCP_drop: - DEBUGF 1,"TCP_drop\n" + DEBUGF 1,"TCP_drop\n" - cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED - jb .no_syn_received + cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED + jb .no_syn_received - mov [eax + TCP_SOCKET.t_state], TCPS_CLOSED + mov [eax + TCP_SOCKET.t_state], TCPS_CLOSED - call TCP_output + call TCP_output ;;; TODO: update stats - jmp TCP_close + jmp TCP_close .no_syn_received: @@ -147,7 +147,7 @@ TCP_drop: ;;; TODO: check if error code is "Connection timed out' and handle accordingly - mov [eax + SOCKET.errorcode], ebx + mov [eax + SOCKET.errorcode], ebx @@ -167,15 +167,15 @@ TCP_drop: align 4 TCP_close: - DEBUGF 1,"TCP_close\n" + DEBUGF 1,"TCP_close\n" ;;; TODO: update RTT and mean deviation ;;; TODO: update slow start threshold ;;; TODO: release connection resources - call SOCKET_is_disconnected + call SOCKET_is_disconnected - ret + ret @@ -198,26 +198,26 @@ TCP_close: align 4 TCP_outflags: - mov edx, [eax + TCP_SOCKET.t_state] - movzx edx, byte [edx + .flaglist] + mov edx, [eax + TCP_SOCKET.t_state] + movzx edx, byte [edx + .flaglist] - DEBUGF 1,"TCP_outflags, socket: %x, flags: %x\n", eax, dl + DEBUGF 1,"TCP_outflags, socket: %x, flags: %x\n", eax, dl - ret + ret .flaglist: - db TH_RST + TH_ACK ; TCPS_CLOSED - db 0 ; TCPS_LISTEN - db TH_SYN ; TCPS_SYN_SENT - db TH_SYN + TH_ACK ; TCPS_SYN_RECEIVED - db TH_ACK ; TCPS_ESTABLISHED - db TH_ACK ; TCPS_CLOSE_WAIT - db TH_SYN + TH_ACK ; TCPS_FIN_WAIT_1 - db TH_SYN + TH_ACK ; TCPS_CLOSING - db TH_SYN + TH_ACK ; TCPS_LAST_ACK - db TH_ACK ; TCPS_FIN_WAIT_2 - db TH_ACK ; TCPS_TIMED_WAIT + db TH_RST + TH_ACK ; TCPS_CLOSED + db 0 ; TCPS_LISTEN + db TH_SYN ; TCPS_SYN_SENT + db TH_SYN + TH_ACK ; TCPS_SYN_RECEIVED + db TH_ACK ; TCPS_ESTABLISHED + db TH_ACK ; TCPS_CLOSE_WAIT + db TH_SYN + TH_ACK ; TCPS_FIN_WAIT_1 + db TH_SYN + TH_ACK ; TCPS_CLOSING + db TH_SYN + TH_ACK ; TCPS_LAST_ACK + db TH_ACK ; TCPS_FIN_WAIT_2 + db TH_ACK ; TCPS_TIMED_WAIT @@ -237,69 +237,69 @@ TCP_outflags: align 4 TCP_respond_socket: - DEBUGF 1,"TCP_respond_socket\n" + DEBUGF 1,"TCP_respond_socket\n" ;--------------------- ; Create the IP packet - push cx ebx - mov eax, [ebx + IP_SOCKET.RemoteIP] - mov ebx, [ebx + IP_SOCKET.LocalIP] - mov ecx, sizeof.TCP_header - mov di , IP_PROTO_TCP shl 8 + 128 - call IPv4_output - test edi, edi - jz .error - pop esi cx - push edx eax + push cx ebx + mov eax, [ebx + IP_SOCKET.RemoteIP] + mov ebx, [ebx + IP_SOCKET.LocalIP] + mov ecx, sizeof.TCP_header + mov di , IP_PROTO_TCP shl 8 + 128 + call IPv4_output + test edi, edi + jz .error + pop esi cx + push edx eax ;----------------------------------------------- ; Fill in the TCP header by using the socket ptr - mov ax, [esi + TCP_SOCKET.LocalPort] - rol ax, 8 - stosw - mov ax, [esi + TCP_SOCKET.RemotePort] - rol ax, 8 - stosw - mov eax, [esi + TCP_SOCKET.SND_NXT] - bswap eax - stosd - mov eax, [esi + TCP_SOCKET.RCV_NXT] - bswap eax - stosd - mov al, 0x50 ; Dataoffset: 20 bytes (TCP_header.DataOffset) - stosb - mov al, cl - stosb + mov ax, [esi + TCP_SOCKET.LocalPort] + rol ax, 8 + stosw + mov ax, [esi + TCP_SOCKET.RemotePort] + rol ax, 8 + stosw + mov eax, [esi + TCP_SOCKET.SND_NXT] + bswap eax + stosd + mov eax, [esi + TCP_SOCKET.RCV_NXT] + bswap eax + stosd + mov al, 0x50 ; Dataoffset: 20 bytes (TCP_header.DataOffset) + stosb + mov al, cl + stosb ; mov ax, [esi + TCP_SOCKET.RCV_WND] ; rol ax, 8 - mov ax, 0x00a0 ;;;;;;; FIXME - stosw ; window - xor eax, eax - stosd ; checksum + urgentpointer + mov ax, 0x00a0 ;;;;;;; FIXME + stosw ; window + xor eax, eax + stosd ; checksum + urgentpointer ;--------------------- ; Fill in the checksum .checksum: - sub edi, sizeof.TCP_header - mov ecx, sizeof.TCP_header - xchg esi, edi - TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP) - mov [esi+TCP_header.Checksum], dx + sub edi, sizeof.TCP_header + mov ecx, sizeof.TCP_header + xchg esi, edi + TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP) + mov [esi+TCP_header.Checksum], dx ;-------------------- ; And send the segment - call [ebx + NET_DEVICE.transmit] - ret + call [ebx + NET_DEVICE.transmit] + ret .error: - DEBUGF 1,"TCP_respond failed\n" - add esp, 2+4 + DEBUGF 1,"TCP_respond failed\n" + add esp, 2+4 - ret + ret @@ -311,70 +311,72 @@ TCP_respond_socket: ;------------------------- ; TCP_respond.segment: ; -; IN: edx = segment ptr (a previously received segment) +; IN: ebx = ptr to driver +; edx = segment ptr (a previously received segment) +; edi = ptr to dest and src IPv4 addresses ; cl = flags align 4 TCP_respond_segment: - DEBUGF 1,"TCP_respond_segment\n" + DEBUGF 1,"TCP_respond_segment\n" ;--------------------- ; Create the IP packet - push cx edx - mov ebx, [edx - sizeof.IPv4_header + IPv4_header.SourceAddress] ;;;; FIXME: and what if ip packet had options?! - mov eax, [edx - sizeof.IPv4_header + IPv4_header.DestinationAddress] ;;; - mov ecx, sizeof.TCP_header - mov di , IP_PROTO_TCP shl 8 + 128 - call IPv4_output - jz .error - pop esi cx + push cx edx ebx + mov ebx, [edi + 4] + mov eax, [edi] + mov ecx, sizeof.TCP_header + mov di , IP_PROTO_TCP shl 8 + 128 + call IPv4_output + jz .error + pop ebx esi cx - push edx eax + push edx eax ;--------------------------------------------------- ; Fill in the TCP header by using a received segment - mov ax, [esi + TCP_header.DestinationPort] - rol ax, 8 - stosw - mov ax, [esi + TCP_header.SourcePort] - rol ax, 8 - stosw - mov eax, [esi + TCP_header.AckNumber] - bswap eax - stosd - xor eax, eax - stosd - mov al, 0x50 ; Dataoffset: 20 bytes (sizeof.TCP_header) - stosb - mov al, cl - stosb - mov ax, 1280 - rol ax, 8 - stosw ; window - xor eax, eax - stosd ; checksum + urgentpointer + mov ax, [esi + TCP_header.DestinationPort] + rol ax, 8 + stosw + mov ax, [esi + TCP_header.SourcePort] + rol ax, 8 + stosw + mov eax, [esi + TCP_header.AckNumber] + bswap eax + stosd + xor eax, eax + stosd + mov al, 0x50 ; Dataoffset: 20 bytes (sizeof.TCP_header) + stosb + mov al, cl + stosb + mov ax, 1280 + rol ax, 8 + stosw ; window + xor eax, eax + stosd ; checksum + urgentpointer ;--------------------- ; Fill in the checksum .checksum: - lea esi, [edi - sizeof.TCP_header] - mov ecx, sizeof.TCP_header - TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\ ; FIXME - (esi - sizeof.IPv4_header + IPv4_header.SourceAddress) - mov [esi+TCP_header.Checksum], dx + lea esi, [edi - sizeof.TCP_header] + mov ecx, sizeof.TCP_header + TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\ ; FIXME + (esi - sizeof.IPv4_header + IPv4_header.SourceAddress) + mov [esi+TCP_header.Checksum], dx ;-------------------- ; And send the segment - call [ebx + NET_DEVICE.transmit] - ret + call [ebx + NET_DEVICE.transmit] + ret .error: - DEBUGF 1,"TCP_respond failed\n" - add esp, 2+4 + DEBUGF 1,"TCP_respond failed\n" + add esp, 2+4 - ret \ No newline at end of file + ret \ No newline at end of file diff --git a/kernel/branches/net/network/udp.inc b/kernel/branches/net/network/udp.inc index 919c7cc040..d9c38f0dda 100644 --- a/kernel/branches/net/network/udp.inc +++ b/kernel/branches/net/network/udp.inc @@ -17,20 +17,20 @@ $Revision$ -struct UDP_Packet +struct UDP_Packet - SourcePort dw ? - DestinationPort dw ? - Length dw ? ; Length of (UDP Header + Data) - Checksum dw ? + SourcePort dw ? + DestinationPort dw ? + Length dw ? ; Length of (UDP Header + Data) + Checksum dw ? ends align 4 uglobal - UDP_PACKETS_TX rd MAX_IP - UDP_PACKETS_RX rd MAX_IP + UDP_PACKETS_TX rd MAX_IP + UDP_PACKETS_RX rd MAX_IP endg @@ -41,57 +41,57 @@ endg ; This function resets all UDP variables ; ;----------------------------------------------------------------- -macro UDP_init { +macro UDP_init { - xor eax, eax - mov edi, UDP_PACKETS_TX - mov ecx, 2*MAX_IP - rep stosd + xor eax, eax + mov edi, UDP_PACKETS_TX + mov ecx, 2*MAX_IP + rep stosd } -macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size, destroys: ecx, edx +macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size, destroys: ecx, edx ; Pseudoheader - mov edx, IP_PROTO_UDP + mov edx, IP_PROTO_UDP - add dl, [IP1+1] - adc dh, [IP1+0] - adc dl, [IP1+3] - adc dh, [IP1+2] + add dl, [IP1+1] + adc dh, [IP1+0] + adc dl, [IP1+3] + adc dh, [IP1+2] - adc dl, [IP2+1] - adc dh, [IP2+0] - adc dl, [IP2+3] - adc dh, [IP2+2] + adc dl, [IP2+1] + adc dh, [IP2+0] + adc dl, [IP2+3] + adc dh, [IP2+2] - adc dl, cl ; byte[esi+UDP_Packet.Length+1] - adc dh, ch ; byte[esi+UDP_Packet.Length+0] + adc dl, cl ; byte[esi+UDP_Packet.Length+1] + adc dh, ch ; byte[esi+UDP_Packet.Length+0] ; Done with pseudoheader, now do real header - adc dl, byte[esi+UDP_Packet.SourcePort+1] - adc dh, byte[esi+UDP_Packet.SourcePort+0] + adc dl, byte[esi+UDP_Packet.SourcePort+1] + adc dh, byte[esi+UDP_Packet.SourcePort+0] - adc dl, byte[esi+UDP_Packet.DestinationPort+1] - adc dh, byte[esi+UDP_Packet.DestinationPort+0] + adc dl, byte[esi+UDP_Packet.DestinationPort+1] + adc dh, byte[esi+UDP_Packet.DestinationPort+0] - adc dl, byte[esi+UDP_Packet.Length+1] - adc dh, byte[esi+UDP_Packet.Length+0] + adc dl, byte[esi+UDP_Packet.Length+1] + adc dh, byte[esi+UDP_Packet.Length+0] - adc edx, 0 + adc edx, 0 ; Done with header, now do data - push esi - movzx ecx, [esi+UDP_Packet.Length] - rol cx , 8 - sub cx , sizeof.UDP_Packet - add esi, sizeof.UDP_Packet + push esi + movzx ecx, [esi+UDP_Packet.Length] + rol cx , 8 + sub cx , sizeof.UDP_Packet + add esi, sizeof.UDP_Packet - call checksum_1 - call checksum_2 - pop esi + call checksum_1 + call checksum_2 + pop esi - add [esi+UDP_Packet.Checksum], dx ; this final instruction will set or clear ZF :) + add [esi+UDP_Packet.Checksum], dx ; this final instruction will set or clear ZF :) } @@ -108,9 +108,7 @@ macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size, des ; ebx = ptr to device struct ; ecx = UDP Packet size ; edx = ptr to UDP header -; -; esi = ipv4 source address -; edi = ipv4 dest address +; edi = ptr to ipv4 source and dest address ; ; OUT: / ; @@ -118,103 +116,104 @@ macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size, des align 4 UDP_input: - DEBUGF 1,"UDP_input, size:%u\n", ecx + DEBUGF 1,"UDP_input, size:%u\n", ecx ; First validate, checksum: - neg [edx+UDP_Packet.Checksum] ; substract chechksum from 0 - jz .no_checksum ; if checksum is zero, it is considered valid and we continue processing - ; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct + neg [edx+UDP_Packet.Checksum] ; substract chechksum from 0 + jz .no_checksum ; if checksum is zero, it is considered valid and we continue processing + ; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct - push edx - push edi - push esi - mov esi, edx - UDP_checksum (esp), (esp+4) - pop edi - pop esi ; we dont need it, but it is smaller then add esp, 4 - pop edx - jnz .checksum_mismatch + push edx + push edi + push esi + mov esi, edx + UDP_checksum (edi), (edi+4) + pop edi + pop esi ; we dont need it, but it is smaller then add esp, 4 + pop edx + jnz .checksum_mismatch .no_checksum: - DEBUGF 1,"UDP Checksum is correct\n" + DEBUGF 1,"UDP Checksum is correct\n" - ; Look for a socket where - ; IP Packet UDP Destination Port = local Port - ; IP Packet SA = Remote IP + ; Look for a socket where + ; IP Packet UDP Destination Port = local Port + ; IP Packet SA = Remote IP - mov eax, net_sockets + mov eax, net_sockets .try_more: - mov si , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header - rol si , 8 + mov si , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header + rol si , 8 .next_socket: - mov eax, [eax + SOCKET.NextPtr] - or eax, eax - jz .dump - cmp [eax + SOCKET.Domain], AF_INET4 - jne .next_socket - cmp [eax + SOCKET.Protocol], IP_PROTO_UDP - jne .next_socket - cmp [eax + UDP_SOCKET.LocalPort], si - jne .next_socket + mov eax, [eax + SOCKET.NextPtr] + or eax, eax + jz .dump + cmp [eax + SOCKET.Domain], AF_INET4 + jne .next_socket + cmp [eax + SOCKET.Protocol], IP_PROTO_UDP + jne .next_socket + cmp [eax + UDP_SOCKET.LocalPort], si + jne .next_socket - DEBUGF 1,"using socket: %x\n", eax + DEBUGF 1,"using socket: %x\n", eax - ;;; TODO: when packet is processed, check more sockets! + ;;; TODO: when packet is processed, check more sockets! - cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff - je @f - cmp [eax + IP_SOCKET.RemoteIP], edi ; edi is the packets source address - jne .try_more + cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff + je @f + mov edi, [edi + 4] ; ipv4 source address + cmp [eax + IP_SOCKET.RemoteIP], edi + jne .try_more @@: - cmp [eax + UDP_SOCKET.firstpacket], 0 - jz .updateport + cmp [eax + UDP_SOCKET.firstpacket], 0 + jz .updateport - mov si, [edx + UDP_Packet.SourcePort] - rol si, 8 - cmp [eax + UDP_SOCKET.RemotePort], si - jne .dump + mov si, [edx + UDP_Packet.SourcePort] + rol si, 8 + cmp [eax + UDP_SOCKET.RemotePort], si + jne .dump - push ebx - lea ebx, [eax + SOCKET.lock] - call wait_mutex - pop ebx + push ebx + lea ebx, [eax + SOCKET.lock] + call wait_mutex + pop ebx .updatesock: - inc [UDP_PACKETS_RX] - DEBUGF 1,"Found valid UDP packet for socket %x\n", eax - lea esi, [edx + sizeof.UDP_Packet] - movzx ecx, [edx + UDP_Packet.Length] - rol cx , 8 - sub cx , sizeof.UDP_Packet + inc [UDP_PACKETS_RX] + DEBUGF 1,"Found valid UDP packet for socket %x\n", eax + lea esi, [edx + sizeof.UDP_Packet] + movzx ecx, [edx + UDP_Packet.Length] + rol cx , 8 + sub cx , sizeof.UDP_Packet - jmp SOCKET_input + jmp SOCKET_input .updateport: - push ebx - lea ebx, [eax + SOCKET.lock] - call wait_mutex - pop ebx + push ebx + lea ebx, [eax + SOCKET.lock] + call wait_mutex + pop ebx - mov si, [edx + UDP_Packet.SourcePort] - rol si, 8 - DEBUGF 1,"Changing remote port to: %u\n", si - mov [eax + UDP_SOCKET.RemotePort], si - inc [eax + UDP_SOCKET.firstpacket] + mov si, [edx + UDP_Packet.SourcePort] + rol si, 8 + DEBUGF 1,"Changing remote port to: %u\n", si + mov [eax + UDP_SOCKET.RemotePort], si + inc [eax + UDP_SOCKET.firstpacket] - jmp .updatesock + jmp .updatesock .checksum_mismatch: - DEBUGF 2,"UDP_Handler - checksum mismatch\n" + DEBUGF 2,"UDP_Handler - checksum mismatch\n" .dump: - call kernel_free - add esp, 4 ; pop (balance stack) - DEBUGF 2,"UDP_Handler - dumping\n" + call kernel_free + add esp, 4 ; pop (balance stack) + DEBUGF 2,"UDP_Handler - dumping\n" - ret + ret @@ -232,64 +231,64 @@ UDP_input: align 4 UDP_output: - DEBUGF 1,"UDP_output: socket:%x, bytes: %u, data ptr: %x\n", eax, ecx, esi + DEBUGF 1,"UDP_output: socket:%x, bytes: %u, data ptr: %x\n", eax, ecx, esi - mov dx, [eax + UDP_SOCKET.RemotePort] - DEBUGF 1,"remote port: %u\n", dx - rol dx, 8 - rol edx, 16 - mov dx, [eax + UDP_SOCKET.LocalPort] - DEBUGF 1,"local port: %u\n", dx - rol dx, 8 + mov dx, [eax + UDP_SOCKET.RemotePort] + DEBUGF 1,"remote port: %u\n", dx + rol dx, 8 + rol edx, 16 + mov dx, [eax + UDP_SOCKET.LocalPort] + DEBUGF 1,"local port: %u\n", dx + rol dx, 8 - mov ebx, [eax + IP_SOCKET.LocalIP] - mov eax, [eax + IP_SOCKET.RemoteIP] + mov ebx, [eax + IP_SOCKET.LocalIP] + mov eax, [eax + IP_SOCKET.RemoteIP] - mov di, IP_PROTO_UDP shl 8 + 128 - sub esp, 8 ; Data ptr and data size will be placed here - add ecx, sizeof.UDP_Packet + mov di, IP_PROTO_UDP shl 8 + 128 + sub esp, 8 ; Data ptr and data size will be placed here + add ecx, sizeof.UDP_Packet ;;; TODO: fragment id - push edx esi - call IPv4_output - jz .fail + push edx esi + call IPv4_output + jz .fail - mov [esp + 8], eax ; pointer to buffer start - mov [esp + 8 + 4], edx ; buffer size + mov [esp + 8], eax ; pointer to buffer start + mov [esp + 8 + 4], edx ; buffer size - mov [edi + UDP_Packet.Length], cx - rol [edi + UDP_Packet.Length], 8 + mov [edi + UDP_Packet.Length], cx + rol [edi + UDP_Packet.Length], 8 - pop esi - push edi ecx - sub ecx, sizeof.UDP_Packet - add edi, sizeof.UDP_Packet - shr ecx, 2 - rep movsd - mov ecx, [esp] - and ecx, 3 - rep movsb - pop ecx edi + pop esi + push edi ecx + sub ecx, sizeof.UDP_Packet + add edi, sizeof.UDP_Packet + shr ecx, 2 + rep movsd + mov ecx, [esp] + and ecx, 3 + rep movsb + pop ecx edi - pop dword [edi + UDP_Packet.SourcePort] + pop dword [edi + UDP_Packet.SourcePort] ; Checksum - mov esi, edi - mov [edi + UDP_Packet.Checksum], 0 - UDP_checksum (edi-4), (edi-8) ; TODO: fix this, IPv4 packet could have options.. + mov esi, edi + mov [edi + UDP_Packet.Checksum], 0 + UDP_checksum (edi-4), (edi-8) ; TODO: fix this, IPv4 packet could have options.. - 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 - call [ebx + NET_DEVICE.transmit] - ret + call [ebx + NET_DEVICE.transmit] + ret .fail: - DEBUGF 1,"UDP_output: failed\n" - add esp, 4+4+8 - xor eax, eax - ret + DEBUGF 1,"UDP_output: failed\n" + add esp, 4+4+8 + xor eax, eax + ret @@ -310,24 +309,24 @@ UDP_output: align 4 UDP_API: - movzx eax, bh - shl eax, 2 + movzx eax, bh + shl eax, 2 - test bl, bl - jz .packets_tx ; 0 - dec bl - jz .packets_rx ; 1 + test bl, bl + jz .packets_tx ; 0 + dec bl + jz .packets_rx ; 1 .error: - mov eax, -1 - ret + mov eax, -1 + ret .packets_tx: - add eax, UDP_PACKETS_TX - mov eax, [eax] - ret + add eax, UDP_PACKETS_TX + mov eax, [eax] + ret .packets_rx: - add eax, UDP_PACKETS_RX - mov eax, [eax] - ret + add eax, UDP_PACKETS_RX + mov eax, [eax] + ret