forked from KolibriOS/kolibrios
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:
parent
92f2253d7a
commit
255c2b5ab3
@ -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:
|
||||
|
@ -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
|
||||
|
@ -56,6 +56,7 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
include 'macros.inc'
|
||||
include 'struct.inc'
|
||||
|
||||
$Revision$
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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:
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user