Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 2304 → Rev 2305

/kernel/branches/net/gui/skincode.inc
43,43 → 43,43
ret
 
struct SKIN_HEADER
.ident dd ?
.version dd ?
.params dd ?
.buttons dd ?
.bitmaps dd ?
ident dd ?
version dd ?
params dd ?
buttons dd ?
bitmaps dd ?
ends
 
struct SKIN_PARAMS
.skin_height dd ?
.margin.right dw ?
.margin.left dw ?
.margin.bottom dw ?
.margin.top dw ?
.colors.inner dd ?
.colors.outer dd ?
.colors.frame dd ?
.colors_1.inner dd ?
.colors_1.outer dd ?
.colors_1.frame dd ?
.dtp.size dd ?
.dtp.data db 40 dup (?)
skin_height dd ?
margin.right dw ?
margin.left dw ?
margin.bottom dw ?
margin.top dw ?
colors.inner dd ?
colors.outer dd ?
colors.frame dd ?
colors_1.inner dd ?
colors_1.outer dd ?
colors_1.frame dd ?
dtp.size dd ?
dtp.data rb 40
ends
 
struct SKIN_BUTTONS
.type dd ?
.pos:
.left dw ?
.top dw ?
.size:
.width dw ?
.height dw ?
type dd ?
; pos:
left dw ?
top dw ?
; size:
width dw ?
height dw ?
ends
 
struct SKIN_BITMAPS
.kind dw ?
.type dw ?
.data dd ?
kind dw ?
type dw ?
data dd ?
ends
 
load_default_skin:
/kernel/branches/net/gui/skindata.inc
17,25 → 17,25
endg
 
struct SKIN_DATA
.colors.inner dd ?
.colors.outer dd ?
.colors.frame dd ?
.left.data dd ?
.left.left dd ?
.left.width dd ?
.oper.data dd ?
.oper.left dd ?
.oper.width dd ?
.base.data dd ?
.base.left dd ?
.base.width dd ?
colors.inner dd ?
colors.outer dd ?
colors.frame dd ?
left.data dd ?
left.left dd ?
left.width dd ?
oper.data dd ?
oper.left dd ?
oper.width dd ?
base.data dd ?
base.left dd ?
base.width dd ?
ends
 
struct SKIN_BUTTON
.left dd ?
.top dd ?
.width dd ?
.height dd ?
left dd ?
top dd ?
width dd ?
height dd ?
ends
 
uglobal
/kernel/branches/net/kernel.asm
56,6 → 56,7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
include 'macros.inc'
include 'struct.inc'
 
$Revision$
 
/kernel/branches/net/macros.inc
11,31 → 11,6
 
$Revision$
 
 
; structure definition helper
macro struct name, [arg]
{
common
name@struct equ name
struc name arg {
}
 
macro struct_helper name
{
match xname,name
\{
virtual at 0
xname xname
sizeof.#xname = $ - xname
name equ sizeof.#xname
end virtual
\}
}
 
ends fix } struct_helper name@struct
 
;// mike.dld, 2006-29-01 [
 
; macros definition
macro diff16 title,l1,l2
{
/kernel/branches/net/network/ARP.inc
25,6 → 25,7
 
ARP_REQUEST_TTL equ 31 ; 20 s
ARP_ENTRY_TTL equ 937 ; 600 s
ARP_STATIC_ENTRY equ -1
 
ARP_REQ_OPCODE equ 0x0100 ; request
ARP_REP_OPCODE equ 0x0200 ; reply
31,34 → 32,35
 
ARP_TABLE_SIZE equ 20 ; Size of table
 
struct ARP_ENTRY
.IP dd ?
.MAC dp ?
.Status dw ?
.TTL dw ?
.size:
struct ARP_entry
 
IP dd ?
MAC dp ?
Status dw ?
TTL dw ?
 
ends
 
struct ARP_Packet
.HardwareType dw ?
.ProtocolType dw ?
.HardwareSize db ?
.ProtocolSize db ?
.Opcode dw ?
.SenderMAC dp ?
.SenderIP dd ?
.TargetMAC dp ?
.TargetIP dd ?
.size:
struct ARP_header
 
HardwareType dw ?
ProtocolType dw ?
HardwareSize db ?
ProtocolSize db ?
Opcode dw ?
SenderMAC dp ?
SenderIP dd ?
TargetMAC dp ?
TargetIP dd ?
 
ends
 
 
align 4
uglobal
 
NumARP dd ?
 
ARP_table rb ARP_ENTRY.size * ARP_TABLE_SIZE
ARP_table rb ARP_TABLE_SIZE * sizeof.ARP_entry
 
ARP_PACKETS_TX rd MAX_NET_DEVICES
ARP_PACKETS_RX rd MAX_NET_DEVICES
114,21 → 116,21
 
mov esi, ARP_table
.loop:
cmp [esi + ARP_ENTRY.TTL], 0xffff ; 0xffff = static entry
cmp [esi + ARP_entry.TTL], ARP_STATIC_ENTRY
je .next
 
dec [esi + ARP_ENTRY.TTL]
dec [esi + ARP_entry.TTL]
jz .time_out
 
.next:
add esi, ARP_ENTRY.size
add esi, sizeof.ARP_entry
dec ecx
jnz .loop
jmp .exit
 
.time_out:
cmp [esi + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
jz .response_timeout
cmp [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE
je .response_timeout
 
push esi ecx
call ARP_del_entry
137,8 → 139,8
jmp .next
 
.response_timeout:
mov [esi + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT
mov [esi + ARP_ENTRY.TTL], 10
mov [esi + ARP_entry.Status], ARP_RESPONSE_TIMEOUT
mov [esi + ARP_entry.TTL], 10
 
jmp .next
 
161,29 → 163,29
ARP_input:
 
DEBUGF 1,"ARP_Handler - start\n"
cmp ecx, ARP_Packet.size
cmp ecx, sizeof.ARP_header
jb .exit
 
;---------------------
; Handle Reply packets
 
cmp word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE
cmp [edx + ARP_header.Opcode], ARP_REP_OPCODE
jne .maybe_request
 
DEBUGF 1,"ARP_Handler - it's a reply packet from %u.%u.%u.%u\n",\
[edx + ARP_Packet.SenderIP]:1,[edx + ARP_Packet.SenderIP+1]:1,[edx + ARP_Packet.SenderIP+2]:1,[edx + ARP_Packet.SenderIP+3]:1,
[edx + ARP_header.SenderIP]:1, [edx + ARP_header.SenderIP+1]:1, [edx + ARP_header.SenderIP+2]:1, [edx + ARP_header.SenderIP+3]:1
 
mov ecx, [NumARP]
test ecx, ecx
jz .exit
 
mov eax, [edx + ARP_Packet.SenderIP]
mov eax, [edx + ARP_header.SenderIP]
mov esi, ARP_table
 
.loop:
cmp [esi + ARP_ENTRY.IP], eax
cmp [esi + ARP_entry.IP], eax
je .gotit
add esi, ARP_ENTRY.size
add esi, sizeof.ARP_entry
dec ecx
jnz .loop
 
192,18 → 194,18
.gotit:
DEBUGF 1,"ARP_Handler - found matching entry\n"
 
cmp [esi+ARP_ENTRY.TTL], 0xffff ; if it is a static entry, dont touch it
cmp [esi + ARP_entry.TTL], ARP_STATIC_ENTRY ; if it is a static entry, dont touch it
je .exit
 
DEBUGF 1,"ARP_Handler - updating entry\n"
 
mov [esi+ARP_ENTRY.Status], ARP_VALID_MAPPING
mov [esi+ARP_ENTRY.TTL], ARP_ENTRY_TTL
mov [esi + ARP_entry.Status], ARP_VALID_MAPPING
mov [esi + ARP_entry.TTL], ARP_ENTRY_TTL
 
mov eax, dword [edx + ARP_Packet.SenderMAC]
mov dword [esi+ARP_ENTRY.MAC], eax
mov ax , word [edx + ARP_Packet.SenderMAC + 4]
mov word [esi+ARP_ENTRY.MAC+4], ax
mov eax, dword [edx + ARP_header.SenderMAC]
mov dword [esi+ARP_entry.MAC], eax
mov ax , word [edx + ARP_header.SenderMAC + 4]
mov word [esi+ARP_entry.MAC+4], ax
 
jmp .exit
 
212,7 → 214,7
; Handle Request packets
 
.maybe_request:
cmp word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE
cmp [edx + ARP_header.Opcode], ARP_REQ_OPCODE
jne .exit
 
call NET_ptr_to_num
222,7 → 224,7
inc [ARP_PACKETS_RX+4*edi]
 
mov eax, [IP_LIST+4*edi]
cmp eax, [edx + ARP_Packet.TargetIP] ; Is it looking for my IP address?
cmp eax, [edx + ARP_header.TargetIP] ; Is it looking for my IP address?
jne .exit ; TODO: instead of quitting, update local entrys with matching IP's ?
 
push eax
231,8 → 233,8
; OK, it is a request for one of our MAC addresses.
; Build the frame and send it. We can reuse the buffer. (faster then using ARP_create_packet)
 
lea esi, [edx + ARP_Packet.SenderMAC]
lea edi, [edx + ARP_Packet.TargetMAC]
lea esi, [edx + ARP_header.SenderMAC]
lea edi, [edx + ARP_header.TargetMAC]
movsd ; Move Sender Mac to Dest MAC
movsw ;
movsd ; Move sender IP to Dest IP
240,21 → 242,21
pop esi
mov esi, [NET_DRV_LIST + 4*esi]
lea esi, [esi + ETH_DEVICE.mac]
lea edi, [edx + ARP_Packet.SenderMAC]
lea edi, [edx + ARP_header.SenderMAC]
movsd ; Copy MAC address from in MAC_LIST
movsw ;
pop eax
stosd ; Write our IP
 
mov word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE
mov [edx + ARP_header.Opcode], ARP_REP_OPCODE
 
; Now, Fill in ETHERNET header
 
mov edi, [esp]
lea esi, [edx + ARP_Packet.TargetMAC]
lea esi, [edx + ARP_header.TargetMAC]
movsd
movsw
lea esi, [edx + ARP_Packet.SenderMAC]
lea esi, [edx + ARP_header.SenderMAC]
movsd
movsw
; mov ax , ETHER_ARP
294,7 → 296,7
 
lea eax, [ebx + ETH_DEVICE.mac] ; local device mac
mov edx, ETH_BROADCAST ; broadcast mac
mov ecx, ARP_Packet.size
mov ecx, sizeof.ARP_header
mov di, ETHER_ARP
call ETH_output
jz .exit
301,13 → 303,13
 
mov ecx, eax
 
mov [edi + ARP_Packet.HardwareType], 0x0100 ; Ethernet
mov [edi + ARP_Packet.ProtocolType], 0x0008 ; IP
mov [edi + ARP_Packet.HardwareSize], 6 ; MAC-addr length
mov [edi + ARP_Packet.ProtocolSize], 4 ; IP-addr length
mov [edi + ARP_Packet.Opcode], ARP_REQ_OPCODE ; Request
mov [edi + ARP_header.HardwareType], 0x0100 ; Ethernet
mov [edi + ARP_header.ProtocolType], 0x0008 ; IP
mov [edi + ARP_header.HardwareSize], 6 ; MAC-addr length
mov [edi + ARP_header.ProtocolSize], 4 ; IP-addr length
mov [edi + ARP_header.Opcode], ARP_REQ_OPCODE ; Request
 
add edi, ARP_Packet.SenderMAC
add edi, ARP_header.SenderMAC
 
lea esi, [ebx + ETH_DEVICE.mac] ; SenderMac
movsw ;
353,19 → 355,19
cmp ecx, ARP_TABLE_SIZE ; list full ?
jae .error
 
mov eax, dword[esi + ARP_ENTRY.MAC]
mov bx , word[esi + ARP_ENTRY.MAC + 4]
mov eax, dword [esi + ARP_entry.MAC]
mov bx , word [esi + ARP_entry.MAC + 4]
mov edi, ARP_table
 
.loop:
cmp dword [edi + ARP_ENTRY.MAC], eax ; Check for duplicate MAC's
cmp dword [edi + ARP_entry.MAC], eax ; Check for duplicate MAC's
jne .maybe_next ;
cmp word [edi + ARP_ENTRY.MAC + 4], bx ;
cmp word [edi + ARP_entry.MAC + 4], bx ;
jne .maybe_next ;
 
cmp dword[edi + ARP_ENTRY.TTL], 0xFFFF ; static entry
cmp [edi + ARP_entry.TTL], ARP_STATIC_ENTRY
jne .notstatic
cmp dword[esi + ARP_ENTRY.TTL], 0xFFFF
cmp [esi + ARP_entry.TTL], ARP_STATIC_ENTRY
jne .error
.notstatic:
 
374,18 → 376,18
jmp .add
 
.maybe_next:
add esi, ARP_ENTRY.size
add esi, sizeof.ARP_entry
loop .loop
 
mov ecx, [NumARP]
.add:
push ecx
imul ecx, ARP_ENTRY.size
imul ecx, sizeof.ARP_entry
lea edi, [ecx + ARP_table]
mov ecx, ARP_ENTRY.size/2
mov ecx, sizeof.ARP_entry/2
rep movsw
 
lea esi, [edi - ARP_ENTRY.size]
lea esi, [edi - sizeof.ARP_entry]
inc [NumARP]
pop eax
DEBUGF 1,"New entry created: %u\n", eax
413,12 → 415,12
 
DEBUGF 1,"ARP del entry %x, total entrys: %u\n", esi, [NumARP]
 
mov ecx, ARP_table + (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size
mov ecx, ARP_table + (ARP_TABLE_SIZE - 1) * sizeof.ARP_entry
sub ecx, esi
shr ecx, 1
 
mov edi, esi
lea esi, [edi + ARP_ENTRY.size]
lea esi, [edi + sizeof.ARP_entry]
rep movsw
 
dec [NumARP]
474,11 → 476,11
mov ecx, [NumARP]
test ecx, ecx
jz .not_in_list
mov esi, ARP_table + ARP_ENTRY.IP
mov esi, ARP_table + ARP_entry.IP
.scan_loop:
cmp [esi], eax
je .found_it
add esi, ARP_ENTRY.size
add esi, sizeof.ARP_entry
loop .scan_loop
 
.not_in_list:
496,7 → 498,7
pushd eax
mov esi, esp
call ARP_add_entry
add esp, ARP_ENTRY.size
add esp, sizeof.ARP_entry
 
cmp eax, -1
je .full
509,12 → 511,12
;; TODO: check if driver could transmit packet
 
pop esi
imul esi, ARP_ENTRY.size
imul esi, sizeof.ARP_entry
add esi, ARP_table
 
mov ecx, 25
.wait_loop:
cmp [esi + ARP_ENTRY.Status], 1
cmp [esi + ARP_entry.Status], 1
je .got_it
push esi
mov esi, 10
527,12 → 529,12
 
.found_it:
DEBUGF 1,"found IP in ARPTable\n"
cmp [esi + ARP_ENTRY.Status], 1
cmp [esi + ARP_entry.Status], 1
jne .invalid
 
.got_it:
movzx eax, word [esi+ARP_ENTRY.MAC]
mov ebx, dword[esi+ARP_ENTRY.MAC+2]
movzx eax, word [esi + ARP_entry.MAC]
mov ebx, dword[esi + ARP_entry.MAC+2]
ret
 
.invalid:
607,10 → 609,10
jae .error
; edi = pointer to buffer
; ecx = # entry
imul ecx, ARP_ENTRY.size
imul ecx, sizeof.ARP_entry
add ecx, ARP_table
mov esi, ecx
mov ecx, ARP_ENTRY.size/2
mov ecx, sizeof.ARP_entry/2
rep movsw
 
xor eax, eax
625,7 → 627,7
; ecx = # entry
cmp ecx, [NumARP]
jae .error
imul ecx, ARP_ENTRY.size
imul ecx, sizeof.ARP_entry
lea esi, [ARP_table + ecx]
call ARP_del_entry
ret
/kernel/branches/net/network/IPv4.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; IPv4.INC ;;
22,35 → 22,38
MAX_IP equ MAX_NET_DEVICES
IP_MAX_INTERFACES equ MAX_IP
 
struct IPv4_Packet
.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 ?
.DataOrOptional:
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 ?
 
ends
 
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
.size:
 
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
.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
 
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
.Data: ; Ip header begins here (we will need the IP header to re-construct the complete packet)
; Ip header begins here (we will need the IP header to re-construct the complete packet)
ends
 
 
65,7 → 68,7
IP_PACKETS_TX rd MAX_IP
IP_PACKETS_RX rd MAX_IP
 
FRAGMENT_LIST rb MAX_FRAGMENTS*FRAGMENT_slot.size
FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot
endg
 
 
84,7 → 87,7
rep stosd
 
mov edi, FRAGMENT_LIST
mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP
mov ecx, sizeof.FRAGMENT_slot*MAX_FRAGMENTS/4 + 2*MAX_IP
rep stosd
 
}
200,20 → 203,20
; TODO2: add code for raw sockets
 
DEBUGF 1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\
[edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1
[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_Packet.DestinationAddress]:1,[edx + IPv4_Packet.DestinationAddress + 1]:1,[edx + IPv4_Packet.DestinationAddress + 2]:1,[edx + IPv4_Packet.DestinationAddress + 3]:1
[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_Packet.TimeToLive], 0
cmp byte [edx + IPv4_header.TimeToLive], 0
je .dump
 
;--------------------------------------
; First, check if IP packet has options
 
movzx eax, [edx + IPv4_Packet.VersionAndIHL]
movzx eax, [edx + IPv4_header.VersionAndIHL]
and al , 0x0f ; get IHL(header length)
cmp al , 0x05 ; IHL!= 5*4(20 bytes)
jnz .has_options
235,7 → 238,7
; check if it matches local ip
 
mov eax, [IP_LIST+edi]
cmp [edx + IPv4_Packet.DestinationAddress], eax
cmp [edx + IPv4_header.DestinationAddress], eax
je .ip_ok
 
; check for broadcast
243,17 → 246,17
mov eax, [SUBNET_LIST+edi]
not eax
or eax, [IP_LIST+edi]
cmp [edx + IPv4_Packet.DestinationAddress], eax
cmp [edx + IPv4_header.DestinationAddress], eax
je .ip_ok
 
; or a special broadcast
 
cmp [edx + IPv4_Packet.DestinationAddress], -1
cmp [edx + IPv4_header.DestinationAddress], -1
je .ip_ok
 
; maybe it's a multicast then
 
mov eax, [edx + IPv4_Packet.DestinationAddress]
mov eax, [edx + IPv4_header.DestinationAddress]
and eax, 0xff000000
; cmp eax, 224 shl 24
; je .ip_ok
277,10 → 280,10
;----------------------------------
; Check if the packet is fragmented
 
test [edx + IPv4_Packet.FlagsAndFragmentOffset], 1 shl 5 ; Is 'more fragments' flag set ?
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_Packet.FlagsAndFragmentOffset], 0xff1f ; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets
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
 
;-------------------------------------------------------------------
287,10 → 290,10
; 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_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
movzx eax, [edx + IPv4_header.VersionAndIHL] ; Calculate Header length by using IHL field
and eax, 0x0000000f ;
shl eax, 2 ;
movzx ecx, [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet
movzx ecx, [edx + IPv4_header.TotalLength] ; Calculate length of encapsulated Packet
xchg cl , ch ;
sub ecx, eax ;
 
297,9 → 300,9
add eax, edx
push eax
 
mov esi, [edx + IPv4_Packet.SourceAddress] ; These values might be of interest to the higher protocols
mov edi, [edx + IPv4_Packet.DestinationAddress] ;
mov al , [edx + IPv4_Packet.Protocol]
mov esi, [edx + IPv4_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)
 
cmp al , IP_PROTO_TCP
326,11 → 329,11
 
 
.has_fragments:
movzx eax, [edx + IPv4_Packet.FlagsAndFragmentOffset]
movzx eax, [edx + IPv4_header.FlagsAndFragmentOffset]
xchg al , ah
shl ax , 3
 
DEBUGF 1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_Packet.Identification]:4
DEBUGF 1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_header.Identification]:4
 
test ax , ax ; Is this the first packet of the fragment?
jz .is_first_fragment
379,17 → 382,17
.find_free_slot:
cmp word [esi + FRAGMENT_slot.ttl], 0
je .found_free_slot
add esi, FRAGMENT_slot.size
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_Packet.Identification]
mov ax , [edx + IPv4_header.Identification]
mov [esi + FRAGMENT_slot.id], ax
mov eax,[edx + IPv4_Packet.SourceAddress]
mov eax,[edx + IPv4_header.SourceAddress]
mov [esi + FRAGMENT_slot.SrcIP], eax
mov eax, [edx + IPv4_Packet.DestinationAddress]
mov eax, [edx + IPv4_header.DestinationAddress]
mov [esi + FRAGMENT_slot.DstIP], eax
pop eax
mov [esi + FRAGMENT_slot.ptr], eax
420,11 → 423,11
.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 + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Add total length
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 + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Sub Header length
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
440,7 → 443,7
mov [esi + FRAGMENT_entry.PrevPtr], edi
mov [esi + FRAGMENT_entry.Owner], ebx
 
mov cx, [edx + IPv4_Packet.TotalLength] ; Note: This time we dont substract Header length
mov cx, [edx + IPv4_header.TotalLength] ; Note: This time we dont substract Header length
xchg cl , ch
DEBUGF 1,"Packet size: %u\n", cx
add ax , cx
447,7 → 450,7
DEBUGF 1,"Total Received data size: %u\n", eax
 
push eax
mov ax , [edx + IPv4_Packet.FlagsAndFragmentOffset]
mov ax , [edx + IPv4_header.FlagsAndFragmentOffset]
xchg al , ah
shl ax , 3
add cx , ax
465,18 → 468,18
mov edx, [esp+4] ; Get pointer to first fragment entry back in edx
 
.rebuild_packet_loop:
movzx ecx, [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset] ; Calculate the fragment offset
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 + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Find header size (in ebx) of 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 + FRAGMENT_entry.Data] ; Set esi to the correct begin of fragment
movzx ecx, [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Calculate total length of fragment
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 ?
504,7 → 507,7
pop ecx
xchg cl, ch
mov edx, eax
mov [edx + IPv4_Packet.TotalLength], cx
mov [edx + IPv4_header.TotalLength], cx
add esp, 8
 
xchg cl, ch ;
550,11 → 553,11
;;; TODO: the RFC says we should check protocol number too
 
push eax ebx ecx edx
mov ax , [edx + IPv4_Packet.Identification]
mov ax , [edx + IPv4_header.Identification]
mov ecx, MAX_FRAGMENTS
mov esi, FRAGMENT_LIST
mov ebx, [edx + IPv4_Packet.SourceAddress]
mov edx, [edx + IPv4_Packet.DestinationAddress]
mov ebx, [edx + IPv4_header.SourceAddress]
mov edx, [edx + IPv4_header.DestinationAddress]
.find_slot:
cmp [esi + FRAGMENT_slot.id], ax
jne .try_next
563,7 → 566,7
cmp [esi + FRAGMENT_slot.DstIP], edx
je .found_slot
.try_next:
add esi, FRAGMENT_slot.size
add esi, sizeof.FRAGMENT_slot
loop .find_slot
; pop edx ebx
or esi, -1
617,7 → 620,7
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 18]
add ecx, IPv4_Packet.DataOrOptional
add ecx, sizeof.IPv4_header
mov di , ETHER_IPv4
call ETH_output
jz .error
624,22 → 627,22
 
add esp, 6 ; pop the mac
 
mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header)
mov [edi + IPv4_Packet.TypeOfService], 0 ; nothing special, just plain ip packet
mov [edi + IPv4_Packet.TotalLength], cx
rol [edi + IPv4_Packet.TotalLength], 8 ; internet byte order
mov [edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000
mov [edi + IPv4_Packet.HeaderChecksum], 0
pop word [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol
; [edi + IPv4_Packet.Protocol]
popw [edi + IPv4_Packet.Identification] ; fragment id
popd [edi + IPv4_Packet.SourceAddress]
popd [edi + IPv4_Packet.DestinationAddress]
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]
 
pop ecx
 
IPv4_checksum edi
add edi, IPv4_Packet.DataOrOptional
add edi, sizeof.IPv4_header
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx
ret
 
694,7 → 697,7
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 6+4]
add ecx, IPv4_Packet.DataOrOptional
add ecx, sizeof.IPv4_header
mov di, ETHER_IPv4
call ETH_output
jz .error
711,22 → 714,22
rep movsb
pop ecx edi
 
; [edi + IPv4_Packet.VersionAndIHL] ; IPv4, normal length (no Optional header)
; [edi + IPv4_Packet.TypeOfService] ; nothing special, just plain ip packet
; [edi + IPv4_Packet.TotalLength]
; [edi + IPv4_Packet.TotalLength] ; internet byte order
; [edi + IPv4_Packet.FlagsAndFragmentOffset]
; [edi + IPv4_header.VersionAndIHL] ; IPv4, normal length (no Optional header)
; [edi + IPv4_header.TypeOfService] ; nothing special, just plain ip packet
; [edi + IPv4_header.TotalLength]
; [edi + IPv4_header.TotalLength] ; internet byte order
; [edi + IPv4_header.FlagsAndFragmentOffset]
 
mov [edi + IPv4_Packet.HeaderChecksum], 0
mov [edi + IPv4_header.HeaderChecksum], 0
 
; [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol
; [edi + IPv4_Packet.Protocol]
; [edi + IPv4_Packet.Identification] ; fragment id
; [edi + IPv4_Packet.SourceAddress]
; [edi + IPv4_Packet.DestinationAddress]
; [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol
; [edi + IPv4_header.Protocol]
; [edi + IPv4_header.Identification] ; fragment id
; [edi + IPv4_header.SourceAddress]
; [edi + IPv4_header.DestinationAddress]
 
IPv4_checksum edi ;;;; todo: checksum for IP packet with options!
add edi, IPv4_Packet.DataOrOptional
add edi, sizeof.IPv4_header
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx
call [ebx + NET_DEVICE.transmit]
ret
760,11 → 763,11
 
and ecx, not 111b ; align 4
 
cmp ecx, IPv4_Packet.DataOrOptional + 8 ; must be able to put at least 8 bytes
cmp ecx, sizeof.IPv4_header + 8 ; must be able to put at least 8 bytes
jb .err2
 
push esi ecx
mov eax, [esi + IPv4_Packet.DestinationAddress]
mov eax, [esi + IPv4_header.DestinationAddress]
call ARP_IP_to_MAC
pop ecx esi
cmp eax, -1
779,7 → 782,7
 
 
push esi ; ptr to ip header
sub ecx, IPv4_Packet.DataOrOptional ; substract header size
sub ecx, sizeof.IPv4_header ; substract header size
push ecx ; max data size
push dword 0 ; offset
 
802,7 → 805,7
 
; copy data
mov esi, [esp + 2*4]
add esi, IPv4_Packet.DataOrOptional
add esi, sizeof.IPv4_header
add esi, [esp] ; offset
 
mov ecx, [esp + 1*4]
811,9 → 814,9
 
; now, correct header
mov ecx, [esp + 1*4]
add ecx, IPv4_Packet.DataOrOptional
add ecx, sizeof.IPv4_header
xchg cl, ch
mov [edi + IPv4_Packet.TotalLength], cx
mov [edi + IPv4_header.TotalLength], cx
 
mov ecx, [esp] ; offset
xchg cl, ch
822,9 → 825,9
; je .last_fragment
or cx, 1 shl 2 ; more fragments
; .last_fragment:
mov [edi + IPv4_Packet.FlagsAndFragmentOffset], cx
mov [edi + IPv4_header.FlagsAndFragmentOffset], cx
 
mov [edi + IPv4_Packet.HeaderChecksum], 0
mov [edi + IPv4_header.HeaderChecksum], 0
 
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< send the packet
mov ecx, [esp + 1*4]
/kernel/branches/net/network/ethernet.inc
16,30 → 16,29
 
$Revision$
 
struct ETH_FRAME
.DstMAC dp ? ; destination MAC-address
.SrcMAC dp ? ; source MAC-address
.Type dw ? ; type of the upper-layer protocol
.Data: ; data (46-1500 bytes for a normal packet)
struct ETH_header
 
DstMAC dp ? ; destination MAC-address
SrcMAC dp ? ; source MAC-address
Type dw ? ; type of the upper-layer protocol
 
ends
 
ETH_FRAME_MINIMUM equ 60
 
virtual at NET_DEVICE.end
struct ETH_DEVICE NET_DEVICE
 
ETH_DEVICE:
set_mode dd ?
get_mode dd ?
 
.set_mode dd ?
.get_mode dd ?
set_MAC dd ?
get_MAC dd ?
 
.set_MAC dd ?
.get_MAC dd ?
mode dd ?
mac dp ?
 
.mode dd ?
.mac dp ?
ends
 
end virtual
 
align 4
iglobal
 
67,10 → 66,10
DEBUGF 1,"ETH_input - size: %u\n", ecx
cmp ecx, ETH_FRAME_MINIMUM
jb .dump
sub ecx, ETH_FRAME.Data
sub ecx, sizeof.ETH_header
 
lea edx, [eax + ETH_FRAME.Data]
mov ax , [eax + ETH_FRAME.Type]
lea edx, [eax + sizeof.ETH_header]
mov ax , [eax + ETH_header.Type]
 
cmp ax, ETHER_IPv4
je IPv4_input
116,7 → 115,7
 
push ecx ; << 1
push di eax edx ; << 2
add ecx, ETH_FRAME.Data
add ecx, sizeof.ETH_header
 
push ecx ; << 3
 
137,7 → 136,7
pop ax ; >> 2
stosw
 
lea eax, [edi - ETH_FRAME.Data] ; Set eax to buffer start
lea eax, [edi - sizeof.ETH_header] ; Set eax to buffer start
mov edx, ecx ; Set edx to complete buffer size
 
pop ecx ; >> 1
210,12 → 209,12
ret
 
.packets_tx:
mov eax, dword [eax + NET_DEVICE.packets_tx]
mov eax, [eax + NET_DEVICE.packets_tx]
 
ret
 
.packets_rx:
mov eax, dword [eax + NET_DEVICE.packets_rx]
mov eax, [eax + NET_DEVICE.packets_rx]
ret
 
.bytes_tx:
/kernel/branches/net/network/icmp.inc
87,13 → 87,14
 
 
 
struct ICMP_Packet
.Type db ?
.Code db ?
.Checksum dw ?
.Identifier dw ?
.SequenceNumber dw ?
.Data:
struct ICMP_header
 
Type db ?
Code db ?
Checksum dw ?
Identifier dw ?
SequenceNumber dw ?
 
ends
 
 
146,8 → 147,8
; First, check the checksum (altough some implementations ignore it)
 
push edx esi ecx
push [edx + ICMP_Packet.Checksum]
mov [edx + ICMP_Packet.Checksum], 0
push [edx + ICMP_header.Checksum]
mov [edx + ICMP_header.Checksum], 0
mov esi, edx
xor edx, edx
call checksum_1
157,7 → 158,7
pop ecx esi edx
jne .checksum_mismatch
 
cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request?
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
164,7 → 165,7
; Notice: this only works on pure ethernet (however, IP packet options are not a problem this time :)
 
DEBUGF 1,"ICMP_input - echo request\n"
mov byte [edx + ICMP_Packet.Type], ICMP_ECHOREPLY ; Change Packet type to reply
mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply
 
; Update stats (and validate device ptr)
call NET_ptr_to_num
176,23 → 177,23
; 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_FRAME.DstMAC]
push dword [esi + ETH_FRAME.SrcMAC]
pop dword [esi + ETH_FRAME.DstMAC]
pop dword [esi + ETH_FRAME.SrcMAC]
push word [esi + ETH_FRAME.DstMAC + 4]
push word [esi + ETH_FRAME.SrcMAC + 4]
pop word [esi + ETH_FRAME.DstMAC + 4]
pop word [esi + ETH_FRAME.SrcMAC + 4]
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, ETH_FRAME.Data
push [esi + IPv4_Packet.SourceAddress]
push [esi + IPv4_Packet.DestinationAddress]
pop [esi + IPv4_Packet.SourceAddress]
pop [esi + IPv4_Packet.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_Packet.VersionAndIHL] ; Calculate IP Header length by using IHL field
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
203,10 → 204,10
call checksum_1 ;
call checksum_2 ;
pop esi ;
mov [esi + IPv4_Packet.HeaderChecksum], dx ;
mov [esi + IPv4_header.HeaderChecksum], dx ;
 
; Recalculate ICMP CheckSum
movzx ecx, [esi + IPv4_Packet.TotalLength] ; Find length of IP Packet
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
 
214,7 → 215,7
xor edx, edx ;
call checksum_1 ;
call checksum_2 ;
mov [eax + ICMP_Packet.Checksum], dx ;
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]
229,7 → 230,7
 
mov ebx, net_sockets
.try_more:
; mov ax , [edx + ICMP_Packet.Identifier]
; mov ax , [edx + ICMP_header.Identifier]
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
297,7 → 298,7
 
mov ebx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP]
add ecx, ICMP_Packet.Data
add ecx, sizeof.ICMP_header
mov di , IP_PROTO_ICMP SHL 8 + 128 ; TTL
shr edx, 16
 
307,12 → 308,12
DEBUGF 1,"full icmp packet size: %u\n", edx
 
pop eax
mov word [edi + ICMP_Packet.Type], ax ; Write both type and code bytes at once
mov word [edi + ICMP_header.Type], ax ; Write both type and code bytes at once
pop eax
mov [edi + ICMP_Packet.SequenceNumber], ax
mov [edi + ICMP_header.SequenceNumber], ax
shr eax, 16
mov [edi + ICMP_Packet.Identifier], ax
mov [edi + ICMP_Packet.Checksum], 0
mov [edi + ICMP_header.Identifier], ax
mov [edi + ICMP_header.Checksum], 0
 
push eax ebx ecx edx
mov esi, edi
319,11 → 320,11
xor edx, edx
call checksum_1
call checksum_2
mov [edi + ICMP_Packet.Checksum], dx
mov [edi + ICMP_header.Checksum], dx
pop edx ecx ebx eax esi
 
sub ecx, ICMP_Packet.Data
add edi, ICMP_Packet.Data
sub ecx, sizeof.ICMP_header
add edi, sizeof.ICMP_header
push cx
shr cx , 2
rep movsd
376,13 → 377,13
rep movsb
pop ecx edi
 
mov [edi + ICMP_Packet.Checksum], 0
mov [edi + ICMP_header.Checksum], 0
 
mov esi, edi
xor edx, edx
call checksum_1
call checksum_2
mov [edi + ICMP_Packet.Checksum], dx
mov [edi + ICMP_header.Checksum], dx
 
DEBUGF 1,"Sending ICMP Packet\n"
call [ebx + NET_DEVICE.transmit]
/kernel/branches/net/network/queue.inc
24,10 → 24,11
 
 
struct queue
.size dd ? ; number of queued packets in this queue
.w_ptr dd ? ; current writing pointer in queue
.r_ptr dd ? ; current reading pointer
.data:
 
size dd ? ; number of queued packets in this queue
w_ptr dd ? ; current writing pointer in queue
r_ptr dd ? ; current reading pointer
 
ends
 
; The following macros share these inputs:
52,7 → 53,7
mov ecx, entry_size/4 ; Write the queue entry
rep movsd ;
 
lea ecx, [size*entry_size+ptr+queue.data]
lea ecx, [size*entry_size+ptr+sizeof.queue]
cmp edi, ecx ; entry size
jb .no_wrap
 
77,7 → 78,7
 
add esi, entry_size
 
lea ecx, [size*entry_size+ptr+queue.data]
lea ecx, [size*entry_size+ptr+sizeof.queue]
cmp esi, ecx ; entry size
jb .no_wrap
 
93,7 → 94,7
macro init_queue ptr {
 
mov [ptr + queue.size] , 0
lea edi, [ptr + queue.data]
lea edi, [ptr + sizeof.queue]
mov [ptr + queue.w_ptr], edi
mov [ptr + queue.r_ptr], edi
}
/kernel/branches/net/network/socket.inc
16,174 → 16,155
$Revision$
 
 
virtual at 0
struct SOCKET
 
SOCKET:
.NextPtr dd ? ; pointer to next socket in list
.PrevPtr dd ? ; pointer to previous socket in list
.Number dd ? ; socket number
NextPtr dd ? ; pointer to next socket in list
PrevPtr dd ? ; pointer to previous socket in list
Number dd ? ; socket number
 
.lock dd ? ; lock mutex
lock dd ? ; lock mutex
 
.PID dd ? ; application process id
.Domain dd ? ; INET/UNIX/..
.Type dd ? ; RAW/STREAM/DGRAP
.Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP
.errorcode dd ?
PID dd ? ; application process id
Domain dd ? ; INET/UNIX/..
Type dd ? ; RAW/STREAM/DGRAP
Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP
errorcode dd ?
 
.options dd ?
.state dd ?
.backlog dw ? ; how many incomming connections that can be queued
options dd ?
state dd ?
backlog dw ? ; how many incomming connections that can be queued
 
.snd_proc dd ?
.rcv_proc dd ?
snd_proc dd ?
rcv_proc dd ?
 
.end:
end virtual
ends
 
virtual at SOCKET.end
struct IP_SOCKET SOCKET
 
IP_SOCKET:
.LocalIP rd 4
.RemoteIP rd 4
LocalIP rd 4
RemoteIP rd 4
 
.end:
end virtual
ends
 
virtual at IP_SOCKET.end
struct TCP_SOCKET IP_SOCKET
 
TCP_SOCKET:
LocalPort dw ?
RemotePort dw ?
 
.LocalPort dw ?
.RemotePort dw ?
t_state dd ? ; TCB state
t_rxtshift dd ?
t_rxtcur dd ?
t_dupacks dd ?
t_maxseg dd ?
t_force dd ?
t_flags dd ?
 
.t_state dd ? ; TCB state
.t_rxtshift dd ?
.t_rxtcur dd ?
.t_dupacks dd ?
.t_maxseg dd ?
.t_force dd ?
.t_flags dd ?
 
;---------------
; RFC783 page 21
 
; send sequence
.SND_UNA dd ? ; sequence number of unack'ed sent Packets
.SND_NXT dd ? ; next send sequence number to use
.SND_UP dd ?
.SND_WL1 dd ? ; window minus one
.SND_WL2 dd ? ;
.ISS dd ? ; initial send sequence number
.SND_WND dd ? ; send window
SND_UNA dd ? ; sequence number of unack'ed sent Packets
SND_NXT dd ? ; next send sequence number to use
SND_UP dd ?
SND_WL1 dd ? ; window minus one
SND_WL2 dd ? ;
ISS dd ? ; initial send sequence number
SND_WND dd ? ; send window
 
; receive sequence
.RCV_WND dw ? ; receive window
.RCV_NXT dd ? ; next receive sequence number to use
.RCV_UP dd ?
.IRS dd ? ; initial receive sequence number
RCV_WND dw ? ; receive window
RCV_NXT dd ? ; next receive sequence number to use
RCV_UP dd ?
IRS dd ? ; initial receive sequence number
 
;---------------------
; Additional variables
 
; receive variables
.RCV_ADV dd ?
RCV_ADV dd ?
 
; retransmit variables
.SND_MAX dd ?
SND_MAX dd ?
 
; congestion control
.SND_CWND dd ?
.SND_SSTHRESH dd ?
SND_CWND dd ?
SND_SSTHRESH dd ?
 
;----------------------
; Transmit timing stuff
.t_idle dd ?
.t_rtt dd ?
.t_rtseq dd ?
.t_srtt dd ?
.t_rttvar dd ?
.t_rttmin dd ?
.max_sndwnd dd ?
t_idle dd ?
t_rtt dd ?
t_rtseq dd ?
t_srtt dd ?
t_rttvar dd ?
t_rttmin dd ?
max_sndwnd dd ?
 
;-----------------
; Out-of-band data
.t_oobflags dd ?
.t_iobc dd ?
.t_softerror dd ?
t_oobflags dd ?
t_iobc dd ?
t_softerror dd ?
 
 
;---------
; RFC 1323
.SND_SCALE db ? ; Scale factor
.RCV_SCALE db ?
.request_r_scale db ?
.requested_s_scale dd ?
SND_SCALE db ? ; Scale factor
RCV_SCALE db ?
request_r_scale db ?
requested_s_scale dd ?
 
.ts_recent dd ?
.ts_recent_age dd ?
.last_ack_sent dd ?
ts_recent dd ?
ts_recent_age dd ?
last_ack_sent dd ?
 
 
;-------
; Timers
.timer_retransmission dw ? ; rexmt
.timer_persist dw ?
.timer_keepalive dw ? ; keepalive/syn timeout
.timer_timed_wait dw ? ; also used as 2msl timer
timer_retransmission dw ? ; rexmt
timer_persist dw ?
timer_keepalive dw ? ; keepalive/syn timeout
timer_timed_wait dw ? ; also used as 2msl timer
 
.end:
end virtual
ends
 
virtual at IP_SOCKET.end
struct UDP_SOCKET IP_SOCKET
 
UDP_SOCKET:
LocalPort dw ?
RemotePort dw ?
firstpacket db ?
 
.LocalPort dw ?
.RemotePort dw ?
.firstpacket db ?
ends
 
.end:
end virtual
 
virtual at IP_SOCKET.end
struct ICMP_SOCKET
 
ICMP_SOCKET:
Identifier dw ?
 
.Identifier dw ?
ends
 
.end:
end virtual
 
struc RING_BUFFER {
.start_ptr dd ? ; Pointer to start of buffer
.end_ptr dd ? ; pointer to end of buffer
.read_ptr dd ? ; Read pointer
.write_ptr dd ? ; Write pointer
.size dd ? ; Number of bytes buffered
.end:
}
struct RING_BUFFER
start_ptr dd ? ; Pointer to start of buffer
end_ptr dd ? ; pointer to end of buffer
read_ptr dd ? ; Read pointer
write_ptr dd ? ; Write pointer
size dd ? ; Number of bytes buffered
ends
 
virtual at 0
struct STREAM_SOCKET TCP_SOCKET
 
RING_BUFFER RING_BUFFER
rcv rd sizeof.RING_BUFFER/4
snd rd sizeof.RING_BUFFER/4
 
end virtual
ends
 
virtual at TCP_SOCKET.end
struct socket_queue_entry
 
STREAM_SOCKET:
.rcv rd RING_BUFFER.end/4
.snd rd RING_BUFFER.end/4
.end:
data_ptr dd ?
buf_ptr dd ?
data_size dd ?
 
end virtual
 
struct socket_queue_entry
.data_ptr dd ?
.buf_ptr dd ?
.data_size dd ?
.size:
ends
 
 
191,7 → 172,7
 
SOCKET_QUEUE_SIZE equ 10 ; maximum number ofincoming packets queued for 1 socket
; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start
SOCKET_QUEUE_LOCATION equ (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*socket_queue_entry.size - queue.data)
SOCKET_QUEUE_LOCATION equ (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*sizeof.socket_queue_entry - sizeof.queue)
 
uglobal
net_sockets rd 4
714,7 → 695,7
mov ebx, esi
mov edi, edx ; addr to buffer
 
get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, s_error ; destroys esi and ecx
get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, s_error ; destroys esi and ecx
 
mov ecx, [esi + socket_queue_entry.data_size]
DEBUGF 1,"Got %u bytes of data\n", ecx
1062,10 → 1043,10
push esi
mov esi, esp
 
add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, SOCKET_input.full
add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full
 
DEBUGF 1,"SOCKET_input: queued packet successfully\n"
add esp, socket_queue_entry.size
add esp, sizeof.socket_queue_entry
mov [eax + SOCKET.lock], 0
jmp SOCKET_notify_owner
 
/kernel/branches/net/network/stack.inc
105,30 → 105,26
 
 
 
virtual at 0
struct NET_DEVICE
 
NET_DEVICE:
type dd ? ; Type field
mtu dd ? ; Maximal Transmission Unit
name dd ? ; Ptr to 0 terminated string
 
.type dd ? ; Type field
.mtu dd ? ; Maximal Transmission Unit
.name dd ? ; Ptr to 0 terminated string
unload dd ? ; Ptrs to driver functions
reset dd ? ;
transmit dd ? ;
 
.unload dd ? ; Ptrs to driver functions
.reset dd ? ;
.transmit dd ? ;
bytes_tx dq ? ; Statistics, updated by the driver
bytes_rx dq ? ;
packets_tx dd ? ;
packets_rx dd ? ;
 
.bytes_tx dq ? ; Statistics, updated by the driver
.bytes_rx dq ? ;
.packets_tx dd ? ;
.packets_rx dd ? ;
; hwacc dd ? ; bitmask stating available hardware accelerations (offload engines)
 
; .hwacc dd ? ; bitmask stating available hardware accelerations (offload engines)
ends
 
.end:
 
end virtual
 
 
; Exactly as it says..
macro pseudo_random reg {
add reg, [esp]
684,7 → 680,7
mov esi, ebx
and esi, 0x0000ff00
shr esi, 6 ; now we have the device num * 4 in esi
cmp dword [esi + NET_DRV_LIST], 0 ; check if driver is running
cmp [esi + NET_DRV_LIST], 0 ; check if driver is running
je .doesnt_exist
 
push .return ; return address (we will be using jumps instead of calls)
/kernel/branches/net/network/tcp.inc
77,23 → 77,24
 
TCP_re_xmit_thresh equ 3
 
struct TCP_segment
.SourcePort dw ?
.DestinationPort dw ?
.SequenceNumber dd ?
.AckNumber dd ?
.DataOffset db ? ; DataOffset[0-3 bits] and Reserved[4-7]
.Flags db ? ; Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN
.Window dw ?
.Checksum dw ?
.UrgentPointer dw ?
.Data: ; ..or options
struct TCP_header
 
SourcePort dw ?
DestinationPort dw ?
SequenceNumber dd ?
AckNumber dd ?
DataOffset db ? ; DataOffset[0-3 bits] and Reserved[4-7]
Flags db ? ; Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN
Window dw ?
Checksum dw ?
UrgentPointer dw ?
 
ends
 
align 4
uglobal
TCP_segments_tx rd IP_MAX_INTERFACES
TCP_segments_rx rd IP_MAX_INTERFACES
TCP_headers_tx rd IP_MAX_INTERFACES
TCP_headers_rx rd IP_MAX_INTERFACES
TCP_bytes_rx rq IP_MAX_INTERFACES
TCP_bytes_tx rq IP_MAX_INTERFACES
TCP_sequence_num dd ?
110,7 → 111,7
macro TCP_init {
 
xor eax, eax
mov edi, TCP_segments_tx
mov edi, TCP_headers_tx
mov ecx, (6*IP_MAX_INTERFACES)
rep stosd
 
155,11 → 156,11
ret
 
.packets_tx:
add eax, TCP_segments_tx
add eax, TCP_headers_tx
mov eax, [eax]
ret
 
.packets_rx:
add eax, TCP_segments_rx
add eax, TCP_headers_rx
mov eax, [eax]
ret
/kernel/branches/net/network/tcp_input.inc
39,13 → 39,13
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_segment.DataOffset]
movzx eax, [edx + TCP_header.DataOffset]
and eax, 0xf0
shr al, 2
 
DEBUGF 1,"headersize=%u\n", eax
 
cmp eax, TCP_segment.DataOffset
cmp eax, TCP_header.DataOffset
jb .drop_not_locked
 
;-------------------------------
52,8 → 52,8
; Now, re-calculate the checksum
 
push eax ecx edx
pushw [edx + TCP_segment.Checksum]
mov [edx + TCP_segment.Checksum], 0
pushw [edx + TCP_header.Checksum]
mov [edx + TCP_header.Checksum], 0
push esi edi
mov esi, edx
TCP_checksum (esp), (esp+4)
72,18 → 72,18
;-----------------------------------------------------------------------------------------
; Check if this packet has a timestamp option (We do it here so we can process it quickly)
 
cmp esi, TCP_segment.DataOffset + 12 ; Timestamp option is 12 bytes
cmp esi, TCP_header.DataOffset + 12 ; Timestamp option is 12 bytes
jb .no_timestamp
je .is_ok
 
cmp byte [edx + TCP_segment.Data + 12], TCP_OPT_EOL ; end of option list
cmp byte [edx + sizeof.TCP_header + 12], TCP_OPT_EOL ; end of option list
jne .no_timestamp
 
.is_ok:
test [edx + TCP_segment.Flags], TH_SYN ; SYN flag must not be set
test [edx + TCP_header.Flags], TH_SYN ; SYN flag must not be set
jnz .no_timestamp
 
cmp dword [edx + TCP_segment.Data], 0x0101080a ; Timestamp header
cmp dword [edx + sizeof.TCP_header], 0x0101080a ; Timestamp header
jne .no_timestamp
 
DEBUGF 1,"timestamp ok\n"
96,13 → 96,13
;-------------------------------------------
; Convert Big-endian values to little endian
 
ntohd [edx + TCP_segment.SequenceNumber]
ntohd [edx + TCP_segment.AckNumber]
ntohd [edx + TCP_header.SequenceNumber]
ntohd [edx + TCP_header.AckNumber]
 
ntohw [edx + TCP_segment.Window]
ntohw [edx + TCP_segment.UrgentPointer]
ntohw [edx + TCP_segment.SourcePort]
ntohw [edx + TCP_segment.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)
124,7 → 124,7
cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP
jne .socket_loop
 
mov ax, [edx + TCP_segment.DestinationPort]
mov ax, [edx + TCP_header.DestinationPort]
cmp [ebx + TCP_SOCKET.LocalPort], ax
jne .socket_loop
 
136,7 → 136,7
@@:
 
mov ax, [ebx + TCP_SOCKET.RemotePort]
cmp [edx + TCP_segment.SourcePort] , ax
cmp [edx + TCP_header.SourcePort] , ax
je .found_socket
test ax, ax
jnz .socket_loop
168,11 → 168,11
;---------------------------------------
; unscale the window into a 32 bit value
 
movzx eax, [edx + TCP_segment.Window]
movzx eax, [edx + TCP_header.Window]
push ecx
mov cl, [ebx + TCP_SOCKET.SND_SCALE]
shl eax, cl
mov dword [edx + TCP_segment.Window], eax ; word after window is checksum, we dont need checksum anymore
mov dword [edx + TCP_header.Window], eax ; word after window is checksum, we dont need checksum anymore
pop ecx
 
;-----------------------------------
189,10 → 189,10
test eax, eax
jz .drop
 
push [edx - IPv4_Packet.DataOrOptional + IPv4_Packet.DestinationAddress] ;;; FIXME
push [edx - sizeof.IPv4_header + IPv4_header.DestinationAddress] ;;; FIXME
pop [eax + IP_SOCKET.LocalIP]
 
push [edx + TCP_segment.DestinationPort]
push [edx + TCP_header.DestinationPort]
pop [eax + TCP_SOCKET.LocalPort]
 
mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN
213,7 → 213,7
;--------------------
; Process TCP options
 
cmp esi, TCP_segment.DataOffset ; esi is headersize
cmp esi, TCP_header.DataOffset ; esi is headersize
je .no_options
 
DEBUGF 1,"Segment has options\n"
221,7 → 221,7
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 + TCP_segment.Data]
lea edi, [edx + sizeof.TCP_header]
lea eax, [edx + esi]
 
.opt_loop:
253,7 → 253,7
cmp byte [edi+1], 4
jne .no_options ; error occured, ignore all options!
 
test [edx + TCP_segment.Flags], TH_SYN
test [edx + TCP_header.Flags], TH_SYN
jz @f
 
movzx eax, word[edi+2]
271,7 → 271,7
cmp byte [edi+1], 3
jne .no_options
 
test [edx + TCP_segment.Flags], TH_SYN
test [edx + TCP_header.Flags], TH_SYN
jz @f
 
DEBUGF 1,"Got window option\n"
318,17 → 318,17
cmp [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED
jnz .not_uni_xfer
 
test [edx + TCP_segment.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG
test [edx + TCP_header.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG
jnz .not_uni_xfer
 
test [edx + TCP_segment.Flags], TH_ACK
test [edx + TCP_header.Flags], TH_ACK
jz .not_uni_xfer
 
mov eax, [edx + TCP_segment.SequenceNumber]
mov eax, [edx + TCP_header.SequenceNumber]
cmp eax, [ebx + TCP_SOCKET.RCV_NXT]
jne .not_uni_xfer
 
mov eax, dword [edx + TCP_segment.Window]
mov eax, dword [edx + TCP_header.Window]
cmp eax, [ebx + TCP_SOCKET.SND_WND]
jne .not_uni_xfer
 
352,7 → 352,7
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_segment.AckNumber]
mov eax, [edx + TCP_header.AckNumber]
cmp eax, [ebx + TCP_SOCKET.SND_MAX]
ja .not_uni_xfer
 
377,7 → 377,7
popa
 
; update window pointers
mov eax, [edx + TCP_segment.AckNumber]
mov eax, [edx + TCP_header.AckNumber]
mov [ebx + TCP_SOCKET.SND_UNA], eax
 
; Stop retransmit timer
400,7 → 400,7
; - 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_segment.AckNumber]
mov eax, [edx + TCP_header.AckNumber]
cmp eax, [ebx + TCP_SOCKET.SND_UNA]
jne .not_uni_xfer
 
441,7 → 441,15
 
; Calculate receive window size
 
;;;; TODO: 444
; mov eax, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.size]
; neg eax
; add eax, SOCKETBUFFSIZE
; mov edx, [ebx + TCP_SOCKET.RCV_ADV]
; sub edx, [ebx + TCP_SOCKET.RCV_NXT]
; cmp eax, edx
; jae @f
; mov eax, edx
; @@:
 
cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN
je .LISTEN
461,24 → 469,24
 
DEBUGF 1,"TCP state: listen\n"
 
test [edx + TCP_segment.Flags], TH_RST ;;; TODO: kill new socket on error
test [edx + TCP_header.Flags], TH_RST ;;; TODO: kill new socket on error
jnz .drop
 
test [edx + TCP_segment.Flags], TH_ACK
test [edx + TCP_header.Flags], TH_ACK
jnz .drop_with_reset
 
test [edx + TCP_segment.Flags], TH_SYN
test [edx + TCP_header.Flags], TH_SYN
jz .drop
 
;;; TODO: check if it's a broadcast or multicast, and drop if so
 
push [edx - IPv4_Packet.DataOrOptional + IPv4_Packet.SourceAddress] ;;; FIXME
push [edx - sizeof.IPv4_header + IPv4_header.SourceAddress] ;;; FIXME
pop [ebx + IP_SOCKET.RemoteIP]
 
push [edx + TCP_segment.SourcePort]
push [edx + TCP_header.SourcePort]
pop [ebx + TCP_SOCKET.RemotePort]
 
push [edx + TCP_segment.SequenceNumber]
push [edx + TCP_header.SequenceNumber]
pop [ebx + TCP_SOCKET.IRS]
 
push [TCP_sequence_num] ;;;;;
522,10 → 530,10
 
DEBUGF 1,"TCP state: syn_sent\n"
 
test [edx + TCP_segment.Flags], TH_ACK
test [edx + TCP_header.Flags], TH_ACK
jz @f
 
mov eax, [edx + TCP_segment.AckNumber]
mov eax, [edx + TCP_header.AckNumber]
cmp eax, [ebx + TCP_SOCKET.ISS]
jbe .drop_with_reset
 
533,10 → 541,10
ja .drop_with_reset
@@:
 
test [edx + TCP_segment.Flags], TH_RST
test [edx + TCP_header.Flags], TH_RST
jz @f
 
test [edx + TCP_segment.Flags], TH_ACK
test [edx + TCP_header.Flags], TH_ACK
jz .drop
 
mov eax, ebx
546,17 → 554,17
jmp .drop
@@:
 
test [edx + TCP_segment.Flags], TH_SYN
test [edx + TCP_header.Flags], TH_SYN
jz .drop
 
; at this point, segment seems to be valid
 
test [edx + TCP_segment.Flags], TH_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_segment.AckNumber]
mov eax, [edx + TCP_header.AckNumber]
mov [ebx + TCP_SOCKET.SND_UNA], eax
cmp eax, [ebx + TCP_SOCKET.SND_NXT]
jbe @f
567,7 → 575,7
 
mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; disable retransmission
 
push [edx + TCP_segment.SequenceNumber]
push [edx + TCP_header.SequenceNumber]
pop [ebx + TCP_SOCKET.IRS]
 
TCP_rcvseqinit ebx
578,7 → 586,7
cmp eax, [ebx + TCP_SOCKET.ISS]
jbe .simultaneous_open
 
test [edx + TCP_segment.Flags], TH_ACK
test [edx + TCP_header.Flags], TH_ACK
jz .simultaneous_open
 
DEBUGF 1,"TCP: active open\n"
613,11 → 621,11
 
.trim_then_step6:
 
inc [edx + TCP_segment.SequenceNumber]
inc [edx + TCP_header.SequenceNumber]
 
;;; TODO: Drop any received data that follows receive window (590)
 
mov eax, [edx + TCP_segment.SequenceNumber]
mov eax, [edx + TCP_header.SequenceNumber]
mov [ebx + TCP_SOCKET.RCV_UP], eax
dec eax
mov [ebx + TCP_SOCKET.SND_WL1], eax
659,25 → 667,25
; check for duplicate data at beginning of segment
 
mov eax, [ebx + TCP_SOCKET.RCV_NXT]
sub eax, [edx + TCP_segment.SequenceNumber]
sub eax, [edx + TCP_header.SequenceNumber]
jbe .no_duplicate
 
DEBUGF 1,"Uh oh.. %u bytes of duplicate data!\n", eax
 
test [edx + TCP_segment.Flags], TH_SYN
test [edx + TCP_header.Flags], TH_SYN
jz .no_dup_syn
 
; remove duplicate syn
 
and [edx + TCP_segment.Flags], not (TH_SYN)
inc [edx + TCP_segment.SequenceNumber]
and [edx + TCP_header.Flags], not (TH_SYN)
inc [edx + TCP_header.SequenceNumber]
 
cmp [edx + TCP_segment.UrgentPointer], 1
cmp [edx + TCP_header.UrgentPointer], 1
jbe @f
dec [edx + TCP_segment.UrgentPointer]
dec [edx + TCP_header.UrgentPointer]
jmp .dup_syn
@@:
and [edx + TCP_segment.Flags], not (TH_URG)
and [edx + TCP_header.Flags], not (TH_URG)
.dup_syn:
dec eax
.no_dup_syn:
695,7 → 703,7
 
; Check for duplicate FIN
 
test [edx + TCP_segment.Flags], TH_FIN
test [edx + TCP_header.Flags], TH_FIN
jz @f
inc ecx
cmp eax, ecx
703,7 → 711,7
jne @f
 
mov eax, ecx
and [edx + TCP_segment.Flags], not TH_FIN
and [edx + TCP_header.Flags], not TH_FIN
or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
jmp .no_duplicate
@@:
719,7 → 727,7
test eax, eax
jnz .drop_after_ack
 
cmp [edx + TCP_segment.Flags], TH_ACK
cmp [edx + TCP_header.Flags], TH_ACK
jz .drop_after_ack
 
.duplicate:
738,15 → 746,15
;-----------------------------------------------
; Remove duplicate data and update urgent offset
 
add [edx + TCP_segment.SequenceNumber], eax
add [edx + TCP_header.SequenceNumber], eax
 
;;; TODO
 
sub [edx + TCP_segment.UrgentPointer], ax
sub [edx + TCP_header.UrgentPointer], ax
ja @f
 
and [edx + TCP_segment.Flags], not (TH_URG)
mov [edx + TCP_segment.UrgentPointer], 0
and [edx + TCP_header.Flags], not (TH_URG)
mov [edx + TCP_header.UrgentPointer], 0
@@:
 
;--------------------------------------------------
770,7 → 778,7
;----------------------------------------
; Remove data beyond right edge of window
 
mov eax, [edx + TCP_segment.SequenceNumber]
mov eax, [edx + TCP_header.SequenceNumber]
add eax, ecx
sub eax, [ebx + TCP_SOCKET.RCV_NXT]
sub ax, [ebx + TCP_SOCKET.RCV_WND]
809,7 → 817,7
;------------------
; Process RST flags
 
test [edx + TCP_segment.Flags], TH_RST
test [edx + TCP_header.Flags], TH_RST
jz .rst_skip
 
DEBUGF 1,"Got an RST flag"
870,7 → 878,7
;--------------------------------------
; handle SYN-full and ACK-less segments
 
test [edx + TCP_segment.Flags], TH_SYN
test [edx + TCP_header.Flags], TH_SYN
jz @f
 
mov eax, ebx
878,7 → 886,7
call TCP_drop
jmp .drop_with_reset
 
test [edx + TCP_segment.Flags], TH_ACK
test [edx + TCP_header.Flags], TH_ACK
jz .drop
@@:
 
896,7 → 904,7
 
DEBUGF 1,"TCP state = syn received\n"
 
mov eax, [edx + TCP_segment.AckNumber]
mov eax, [edx + TCP_header.AckNumber]
cmp [ebx + TCP_SOCKET.SND_UNA], eax
ja .drop_with_reset
cmp eax, [ebx + TCP_SOCKET.SND_MAX]
920,7 → 928,7
 
;;; 813 ?
 
mov eax, [edx + TCP_segment.SequenceNumber]
mov eax, [edx + TCP_header.SequenceNumber]
dec eax
mov [ebx + TCP_SOCKET.SND_WL1], eax
jmp .not_dup_ack
929,7 → 937,7
 
; check for duplicate ACK
 
mov eax, [edx + TCP_segment.AckNumber]
mov eax, [edx + TCP_header.AckNumber]
cmp eax, [ebx + TCP_SOCKET.SND_UNA]
ja .not_dup_ack
 
936,7 → 944,7
test ecx, ecx
jnz .reset_dupacks
 
mov eax, dword [edx + TCP_segment.Window]
mov eax, dword [edx + TCP_header.Window]
cmp eax, [ebx + TCP_SOCKET.SND_WND]
jne .reset_dupacks
 
945,7 → 953,7
cmp [ebx + TCP_SOCKET.timer_retransmission], 10000 ;;;;
ja @f
 
mov eax, [edx + TCP_segment.AckNumber]
mov eax, [edx + TCP_header.AckNumber]
cmp eax, [ebx + TCP_SOCKET.SND_UNA]
je .dup_ack
 
977,7 → 985,7
 
mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; turn off retransmission timer
mov [ebx + TCP_SOCKET.t_rtt], 0
mov eax, [edx + TCP_segment.AckNumber]
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
1036,7 → 1044,7
 
mov [ebx + TCP_SOCKET.t_dupacks], 0
 
mov eax, [edx + TCP_segment.AckNumber]
mov eax, [edx + TCP_header.AckNumber]
cmp eax, [ebx + TCP_SOCKET.SND_MAX]
jbe @f
 
1045,7 → 1053,7
 
@@:
 
mov edi, [edx + TCP_segment.AckNumber]
mov edi, [edx + TCP_header.AckNumber]
sub edi, [ebx + TCP_SOCKET.SND_UNA] ; now we got the number of acked bytes in esi
 
;;; TODO: update stats
1066,7 → 1074,7
mov [ebx + TCP_SOCKET.timer_retransmission], 0
 
mov eax, [ebx + TCP_SOCKET.SND_MAX]
cmp eax, [edx + TCP_segment.AckNumber]
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:
1131,7 → 1139,7
 
; Update TCPS
 
mov eax, [edx + TCP_segment.AckNumber]
mov eax, [edx + TCP_header.AckNumber]
mov [ebx + TCP_SOCKET.SND_UNA], eax
 
cmp eax, [ebx + TCP_SOCKET.SND_NXT]
1221,25 → 1229,25
;----------------------------------------------
; check if we need to update window information
 
test [edx + TCP_segment.Flags], TH_ACK
test [edx + TCP_header.Flags], TH_ACK
jz .no_window_update
 
mov eax, [ebx + TCP_SOCKET.SND_WL1]
cmp eax, [edx + TCP_segment.SequenceNumber]
cmp eax, [edx + TCP_header.SequenceNumber]
jb .update_window
ja @f
 
mov eax, [ebx + TCP_SOCKET.SND_WL2]
cmp eax, [edx + TCP_segment.AckNumber]
cmp eax, [edx + TCP_header.AckNumber]
jb .update_window
ja .no_window_update
@@:
 
mov eax, [ebx + TCP_SOCKET.SND_WL2]
cmp eax, [edx + TCP_segment.AckNumber]
cmp eax, [edx + TCP_header.AckNumber]
jne .no_window_update
 
movzx eax, [edx + TCP_segment.Window]
movzx eax, [edx + TCP_header.Window]
cmp eax, [ebx + TCP_SOCKET.SND_WND]
jbe .no_window_update
 
1253,7 → 1261,7
; jz @f
;
; mov eax, [ebx + TCP_SOCKET.SND_WL2]
; cmp eax, [edx + TCP_segment.AckNumber]
; cmp eax, [edx + TCP_header.AckNumber]
; jne @f
;
; ;; mov eax, tiwin
1264,7 → 1272,7
;
; @@:
 
mov eax, dword [edx + TCP_segment.Window]
mov eax, dword [edx + TCP_header.Window]
cmp eax, [ebx + TCP_SOCKET.max_sndwnd]
jbe @f
mov [ebx + TCP_SOCKET.max_sndwnd], eax
1271,10 → 1279,10
@@:
mov [ebx + TCP_SOCKET.SND_WND], eax
 
push [edx + TCP_segment.SequenceNumber]
push [edx + TCP_header.SequenceNumber]
pop [ebx + TCP_SOCKET.SND_WL1]
 
push [edx + TCP_segment.AckNumber]
push [edx + TCP_header.AckNumber]
pop [ebx + TCP_SOCKET.SND_WL2]
 
;;; needoutput = 1
1290,10 → 1298,10
;-----------------
; process URG flag
 
test [edx + TCP_segment.Flags], TH_URG
test [edx + TCP_header.Flags], TH_URG
jz .not_urgent
 
cmp [edx + TCP_segment.UrgentPointer], 0
cmp [edx + TCP_header.UrgentPointer], 0
jz .not_urgent
 
cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
1303,13 → 1311,13
 
;;; 1040-1050
 
movzx eax, [edx + TCP_segment.UrgentPointer]
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_segment.UrgentPointer], 0
and [edx + TCP_segment.Flags], not (TH_URG)
mov [edx + TCP_header.UrgentPointer], 0
and [edx + TCP_header.Flags], not (TH_URG)
jmp .do_data
 
.not_urgent:
1332,7 → 1340,7
 
DEBUGF 1,"TCP: do data (%u)\n", ecx
 
test [edx + TCP_segment.Flags], TH_FIN
test [edx + TCP_header.Flags], TH_FIN
jnz .process_fin
 
cmp [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_1
1345,7 → 1353,7
 
;; TODO: check if data is in sequence !
 
movzx eax, [edx + TCP_segment.DataOffset] ;;; todo: remember this in.. edi ?
movzx eax, [edx + TCP_header.DataOffset] ;;; todo: remember this in.. edi ?
and eax, 0xf0
shr al, 2
 
1487,7 → 1495,7
 
DEBUGF 1,"Drop after ACK\n"
 
test [edx + TCP_segment.Flags], TH_RST
test [edx + TCP_header.Flags], TH_RST
jnz .drop
 
and [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
1524,15 → 1532,15
 
DEBUGF 1,"Drop with reset\n"
 
test [edx + TCP_segment.Flags], TH_RST
test [edx + TCP_header.Flags], TH_RST
jnz .drop
 
;;; if its a multicast/broadcast, also drop
 
test [edx + TCP_segment.Flags], TH_ACK
test [edx + TCP_header.Flags], TH_ACK
jnz .respond_ack
 
test [edx + TCP_segment.Flags], TH_SYN
test [edx + TCP_header.Flags], TH_SYN
jnz .respond_syn
 
call kernel_free
/kernel/branches/net/network/tcp_output.inc
260,7 → 260,7
 
DEBUGF 1,"Preparing to send a segment\n"
 
mov edi, TCP_segment.Data ; edi will contain headersize
mov edi, sizeof.TCP_header ; edi will contain headersize
 
sub esp, 8 ; create some space on stack
push eax ; save socket pointer
435,10 → 435,10
;----------------------------------
; update sequence number and timers (400)
 
test [esi + TCP_segment.Flags], TH_SYN + TH_FIN
test [esi + TCP_header.Flags], TH_SYN + TH_FIN
jz @f
inc [eax + TCP_SOCKET.SND_NXT] ; syn and fin take a sequence number
test [esi + TCP_segment.Flags], TH_FIN
test [esi + TCP_header.Flags], TH_FIN
jz @f
or [eax + TCP_SOCKET.t_flags], TF_SENTFIN ; if we sent a fin, set the sentfin flag
@@:
475,7 → 475,7
DEBUGF 1,"checksum: ptr=%x size=%u\n", esi, ecx
 
TCP_checksum (eax + IP_SOCKET.LocalIP), (eax + IP_SOCKET.RemoteIP)
mov [esi+TCP_segment.Checksum], dx
mov [esi + TCP_header.Checksum], dx
 
; unlock socket
 
/kernel/branches/net/network/tcp_subr.inc
245,7 → 245,7
push cx ebx
mov eax, [ebx + IP_SOCKET.RemoteIP]
mov ebx, [ebx + IP_SOCKET.LocalIP]
mov ecx, TCP_segment.Data
mov ecx, sizeof.TCP_header
mov di , IP_PROTO_TCP shl 8 + 128
call IPv4_output
test edi, edi
268,7 → 268,7
mov eax, [esi + TCP_SOCKET.RCV_NXT]
bswap eax
stosd
mov al, 0x50 ; Dataoffset: 20 bytes (TCP_segment.DataOffset)
mov al, 0x50 ; Dataoffset: 20 bytes (TCP_header.DataOffset)
stosb
mov al, cl
stosb
283,11 → 283,11
; Fill in the checksum
 
.checksum:
sub edi, TCP_segment.Data
mov ecx, TCP_segment.Data
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_segment.Checksum], dx
mov [esi+TCP_header.Checksum], dx
 
;--------------------
; And send the segment
323,9 → 323,9
; Create the IP packet
 
push cx edx
mov ebx, [edx - IPv4_Packet.DataOrOptional + IPv4_Packet.SourceAddress] ;;;; FIXME: and what if ip packet had options?!
mov eax, [edx - IPv4_Packet.DataOrOptional + IPv4_Packet.DestinationAddress] ;;;
mov ecx, TCP_segment.Data
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
336,18 → 336,18
;---------------------------------------------------
; Fill in the TCP header by using a received segment
 
mov ax, [esi + TCP_segment.DestinationPort]
mov ax, [esi + TCP_header.DestinationPort]
rol ax, 8
stosw
mov ax, [esi + TCP_segment.SourcePort]
mov ax, [esi + TCP_header.SourcePort]
rol ax, 8
stosw
mov eax, [esi + TCP_segment.AckNumber]
mov eax, [esi + TCP_header.AckNumber]
bswap eax
stosd
xor eax, eax
stosd
mov al, 0x50 ; Dataoffset: 20 bytes (TCP_segment.Data)
mov al, 0x50 ; Dataoffset: 20 bytes (sizeof.TCP_header)
stosb
mov al, cl
stosb
361,11 → 361,11
; Fill in the checksum
 
.checksum:
lea esi, [edi - TCP_segment.Data]
mov ecx, TCP_segment.Data
TCP_checksum (esi - IPv4_Packet.DataOrOptional + IPv4_Packet.DestinationAddress),\ ; FIXME
(esi - IPv4_Packet.DataOrOptional + IPv4_Packet.SourceAddress)
mov [esi+TCP_segment.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
/kernel/branches/net/network/udp.inc
18,12 → 18,12
 
 
struct UDP_Packet
.SourcePort dw ?
.DestinationPort dw ?
.Length dw ? ; Length of (UDP Header + Data)
.Checksum dw ?
.Data:
 
SourcePort dw ?
DestinationPort dw ?
Length dw ? ; Length of (UDP Header + Data)
Checksum dw ?
 
ends
 
 
84,8 → 84,8
push esi
movzx ecx, [esi+UDP_Packet.Length]
rol cx , 8
sub cx , UDP_Packet.Data
add esi, UDP_Packet.Data
sub cx , sizeof.UDP_Packet
add esi, sizeof.UDP_Packet
 
call checksum_1
call checksum_2
183,10 → 183,10
.updatesock:
inc [UDP_PACKETS_RX]
DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
lea esi, [edx + UDP_Packet.Data]
lea esi, [edx + sizeof.UDP_Packet]
movzx ecx, [edx + UDP_Packet.Length]
rol cx , 8
sub cx , UDP_Packet.Data
sub cx , sizeof.UDP_Packet
 
jmp SOCKET_input
 
247,7 → 247,7
 
mov di, IP_PROTO_UDP shl 8 + 128
sub esp, 8 ; Data ptr and data size will be placed here
add ecx, UDP_Packet.Data
add ecx, sizeof.UDP_Packet
 
;;; TODO: fragment id
push edx esi
262,8 → 262,8
 
pop esi
push edi ecx
sub ecx, UDP_Packet.Data
add edi, UDP_Packet.Data
sub ecx, sizeof.UDP_Packet
add edi, sizeof.UDP_Packet
shr ecx, 2
rep movsd
mov ecx, [esp]