NET branch: re-organised all structs to use struct.inc from fasm

git-svn-id: svn://kolibrios.org@2305 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2011-11-08 23:06:26 +00:00
parent 92f2253d7a
commit 255c2b5ab3
16 changed files with 876 additions and 908 deletions

View File

@ -43,43 +43,43 @@ read_skin_file:
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:

View File

@ -17,25 +17,25 @@ iglobal
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

View File

@ -56,6 +56,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include 'macros.inc'
include 'struct.inc'
$Revision$

View File

@ -11,31 +11,6 @@ macro $Revision a {
$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
{

View File

@ -25,40 +25,42 @@ ARP_RESPONSE_TIMEOUT equ 3
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
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:
ends
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 @@ local .exit
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 @@ local .exit
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 @@ align 4
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 @@ ARP_input:
.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 @@ ARP_input:
; 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 @@ ARP_input:
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 @@ ARP_input:
; 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 @@ ARP_input:
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,20 +296,20 @@ ARP_output_request:
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
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 @@ ARP_add_entry:
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 @@ ARP_add_entry:
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 @@ ARP_del_entry:
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 @@ ARP_IP_to_MAC:
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 @@ ARP_IP_to_MAC:
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 @@ ARP_IP_to_MAC:
;; 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 @@ ARP_IP_to_MAC:
.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 @@ ARP_API:
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 @@ ARP_API:
; 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

View File

@ -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_FRAGMENTS equ 64
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 @@ uglobal
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 @@ macro IPv4_init {
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 @@ 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_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 @@ IPv4_input: ; TODO: implement handler for IP options
; 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 @@ IPv4_input: ; TODO: implement handler for IP options
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,29 +280,29 @@ IPv4_input: ; TODO: implement handler for IP options
;----------------------------------
; 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
;-------------------------------------------------------------------
; 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 ;
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 @@ IPv4_input: ; TODO: implement handler for IP options
.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 @@ IPv4_input: ; TODO: implement handler for IP options
.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 @@ IPv4_input: ; TODO: implement handler for IP options
.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,14 +443,14 @@ IPv4_input: ; TODO: implement handler for IP options
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
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 @@ IPv4_input: ; TODO: implement handler for IP options
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 @@ IPv4_input: ; TODO: implement handler for IP options
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 @@ IPv4_find_fragment_slot:
;;; 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 @@ IPv4_find_fragment_slot:
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,29 +620,29 @@ IPv4_output:
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
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 @@ IPv4_output_raw:
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 @@ IPv4_output_raw:
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 @@ IPv4_fragment:
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 @@ IPv4_fragment:
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 @@ IPv4_fragment:
; 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 @@ IPv4_fragment:
; 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 @@ IPv4_fragment:
; 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]

View File

@ -16,29 +16,28 @@
$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 ?
end virtual
ends
align 4
iglobal
@ -67,10 +66,10 @@ ETH_input:
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 @@ ETH_output:
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 @@ ETH_output:
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 @@ ETH_API:
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:

View File

@ -87,13 +87,14 @@ ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed
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 @@ ICMP_input:
; 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,14 +158,14 @@ ICMP_input:
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
; 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 @@ ICMP_input:
; 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 @@ ICMP_input:
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 @@ ICMP_input:
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 @@ ICMP_input:
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 @@ ICMP_output:
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,23 +308,23 @@ ICMP_output:
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
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 @@ ICMP_output_raw:
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]

View File

@ -24,10 +24,11 @@ $Revision$
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 @@ macro add_to_queue ptr, size, entry_size, failaddr {
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 @@ macro get_from_queue ptr, size, entry_size, failaddr {
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 get_from_queue ptr, size, entry_size, failaddr {
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
}

View File

@ -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
virtual at TCP_SOCKET.end
STREAM_SOCKET:
.rcv rd RING_BUFFER.end/4
.snd rd RING_BUFFER.end/4
.end:
end virtual
ends
struct socket_queue_entry
.data_ptr dd ?
.buf_ptr dd ?
.data_size dd ?
.size:
data_ptr dd ?
buf_ptr dd ?
data_size dd ?
ends
@ -191,7 +172,7 @@ SOCKETBUFFSIZE equ 4096 ; in bytes
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 @@ SOCKET_receive_dgram:
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 @@ SOCKET_input:
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

View File

@ -105,28 +105,24 @@ ECONNABORTED equ 53
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)
.end:
end virtual
ends
; Exactly as it says..
@ -684,7 +680,7 @@ sys_protocols:
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)

View File

@ -77,23 +77,24 @@ TCP_max_win equ 65535
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 @@ endg
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 @@ TCP_API:
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

View File

@ -39,21 +39,21 @@ 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_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
;-------------------------------
; 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 @@ TCP_input:
;-----------------------------------------------------------------------------------------
; 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 @@ TCP_input:
;-------------------------------------------
; 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 @@ TCP_input:
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 @@ TCP_input:
@@:
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 @@ TCP_input:
;---------------------------------------
; 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 @@ TCP_input:
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 @@ TCP_input:
;--------------------
; 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 @@ TCP_input:
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 @@ TCP_input:
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 @@ TCP_input:
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 @@ TCP_input:
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 @@ TCP_input:
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 @@ TCP_input:
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 @@ 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_segment.AckNumber]
mov eax, [edx + TCP_header.AckNumber]
cmp eax, [ebx + TCP_SOCKET.SND_UNA]
jne .not_uni_xfer
@ -441,7 +441,15 @@ TCP_input:
; 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 @@ align 4
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 @@ align 4
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 @@ align 4
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 @@ align 4
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 @@ align 4
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 @@ align 4
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 @@ align 4
.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 @@ align 4
; 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 @@ align 4
; 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 @@ align 4
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 @@ align 4
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 @@ align 4
;-----------------------------------------------
; 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 @@ align 4
;----------------------------------------
; 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 @@ align 4
;------------------
; 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 @@ align 4
;--------------------------------------
; 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 @@ align 4
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 @@ align 4
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 @@ align 4
;;; 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,14 +937,14 @@ align 4
; 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
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 @@ align 4
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 @@ align 4
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 @@ align 4
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 @@ align 4
@@:
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 @@ align 4
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 @@ align 4
; 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 @@ align 4
;----------------------------------------------
; 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 @@ align 4
; 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,17 +1272,17 @@ align 4
;
; @@:
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
@@:
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 @@ align 4
;-----------------
; 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 @@ align 4
;;; 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 @@ align 4
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 @@ align 4
;; 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 @@ align 4
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 @@ align 4
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

View File

@ -260,7 +260,7 @@ TCP_output:
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 @@ TCP_output:
;----------------------------------
; 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 @@ TCP_output:
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

View File

@ -245,7 +245,7 @@ TCP_respond_socket:
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 @@ TCP_respond_socket:
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 @@ TCP_respond_socket:
; 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 @@ TCP_respond_segment:
; 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 @@ TCP_respond_segment:
;---------------------------------------------------
; 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 @@ TCP_respond_segment:
; 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

View File

@ -18,11 +18,11 @@ $Revision$
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 @@ macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size, des
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 @@ UDP_input:
.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 @@ UDP_output:
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 @@ UDP_output:
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]