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