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

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

View File

@ -13,273 +13,273 @@ include "skindata.inc"
;skin_data = 0x00778000 ;skin_data = 0x00778000
read_skin_file: read_skin_file:
stdcall load_file, ebx stdcall load_file, ebx
test eax, eax test eax, eax
jz .notfound jz .notfound
cmp dword [eax], 'SKIN' cmp dword [eax], 'SKIN'
jnz .noskin jnz .noskin
cmp ebx, 32*1024 cmp ebx, 32*1024
jb @f jb @f
mov ebx, 32*1024 mov ebx, 32*1024
@@: @@:
lea ecx, [ebx+3] lea ecx, [ebx+3]
shr ecx, 2 shr ecx, 2
mov esi, eax mov esi, eax
mov edi, skin_data mov edi, skin_data
rep movsd rep movsd
stdcall kernel_free, eax stdcall kernel_free, eax
call parse_skin_data call parse_skin_data
xor eax, eax xor eax, eax
ret ret
.notfound: .notfound:
xor eax, eax xor eax, eax
inc eax inc eax
ret ret
.noskin: .noskin:
stdcall kernel_free, eax stdcall kernel_free, eax
push 2 push 2
pop eax pop eax
ret ret
struct SKIN_HEADER struct SKIN_HEADER
.ident dd ? ident dd ?
.version dd ? version dd ?
.params dd ? params dd ?
.buttons dd ? buttons dd ?
.bitmaps dd ? bitmaps dd ?
ends ends
struct SKIN_PARAMS struct SKIN_PARAMS
.skin_height dd ? skin_height dd ?
.margin.right dw ? margin.right dw ?
.margin.left dw ? margin.left dw ?
.margin.bottom dw ? margin.bottom dw ?
.margin.top dw ? margin.top dw ?
.colors.inner dd ? colors.inner dd ?
.colors.outer dd ? colors.outer dd ?
.colors.frame dd ? colors.frame dd ?
.colors_1.inner dd ? colors_1.inner dd ?
.colors_1.outer dd ? colors_1.outer dd ?
.colors_1.frame dd ? colors_1.frame dd ?
.dtp.size dd ? dtp.size dd ?
.dtp.data db 40 dup (?) dtp.data rb 40
ends ends
struct SKIN_BUTTONS struct SKIN_BUTTONS
.type dd ? type dd ?
.pos: ; pos:
.left dw ? left dw ?
.top dw ? top dw ?
.size: ; size:
.width dw ? width dw ?
.height dw ? height dw ?
ends ends
struct SKIN_BITMAPS struct SKIN_BITMAPS
.kind dw ? kind dw ?
.type dw ? type dw ?
.data dd ? data dd ?
ends ends
load_default_skin: load_default_skin:
mov [_skinh],22 mov [_skinh],22
mov ebx,_skin_file_default mov ebx,_skin_file_default
call read_skin_file call read_skin_file
ret ret
parse_skin_data: parse_skin_data:
mov ebp,skin_data mov ebp,skin_data
cmp [ebp+SKIN_HEADER.ident],'SKIN' cmp [ebp+SKIN_HEADER.ident],'SKIN'
jne .exit jne .exit
mov edi,skin_udata mov edi,skin_udata
mov ecx,(skin_udata.end-skin_udata)/4 mov ecx,(skin_udata.end-skin_udata)/4
xor eax,eax xor eax,eax
cld cld
rep stosd rep stosd
mov ebx,[ebp+SKIN_HEADER.params] mov ebx,[ebp+SKIN_HEADER.params]
add ebx,skin_data add ebx,skin_data
mov eax,[ebx+SKIN_PARAMS.skin_height] mov eax,[ebx+SKIN_PARAMS.skin_height]
mov [_skinh],eax mov [_skinh],eax
mov eax,[ebx+SKIN_PARAMS.colors.inner] mov eax,[ebx+SKIN_PARAMS.colors.inner]
mov [skin_active.colors.inner],eax mov [skin_active.colors.inner],eax
mov eax,[ebx+SKIN_PARAMS.colors.outer] mov eax,[ebx+SKIN_PARAMS.colors.outer]
mov [skin_active.colors.outer],eax mov [skin_active.colors.outer],eax
mov eax,[ebx+SKIN_PARAMS.colors.frame] mov eax,[ebx+SKIN_PARAMS.colors.frame]
mov [skin_active.colors.frame],eax mov [skin_active.colors.frame],eax
mov eax,[ebx+SKIN_PARAMS.colors_1.inner] mov eax,[ebx+SKIN_PARAMS.colors_1.inner]
mov [skin_inactive.colors.inner],eax mov [skin_inactive.colors.inner],eax
mov eax,[ebx+SKIN_PARAMS.colors_1.outer] mov eax,[ebx+SKIN_PARAMS.colors_1.outer]
mov [skin_inactive.colors.outer],eax mov [skin_inactive.colors.outer],eax
mov eax,[ebx+SKIN_PARAMS.colors_1.frame] mov eax,[ebx+SKIN_PARAMS.colors_1.frame]
mov [skin_inactive.colors.frame],eax mov [skin_inactive.colors.frame],eax
lea esi,[ebx+SKIN_PARAMS.dtp.data] lea esi,[ebx+SKIN_PARAMS.dtp.data]
mov edi,common_colours mov edi,common_colours
mov ecx,[ebx+SKIN_PARAMS.dtp.size] mov ecx,[ebx+SKIN_PARAMS.dtp.size]
and ecx,127 and ecx,127
rep movsb rep movsb
mov eax,dword[ebx+SKIN_PARAMS.margin.right] mov eax,dword[ebx+SKIN_PARAMS.margin.right]
mov dword[_skinmargins+0],eax mov dword[_skinmargins+0],eax
mov eax,dword[ebx+SKIN_PARAMS.margin.bottom] mov eax,dword[ebx+SKIN_PARAMS.margin.bottom]
mov dword[_skinmargins+4],eax mov dword[_skinmargins+4],eax
mov ebx,[ebp+SKIN_HEADER.bitmaps] mov ebx,[ebp+SKIN_HEADER.bitmaps]
add ebx,skin_data add ebx,skin_data
.lp1: cmp dword[ebx],0 .lp1: cmp dword[ebx],0
je .end_bitmaps je .end_bitmaps
movzx eax,[ebx+SKIN_BITMAPS.kind] movzx eax,[ebx+SKIN_BITMAPS.kind]
movzx ecx,[ebx+SKIN_BITMAPS.type] movzx ecx,[ebx+SKIN_BITMAPS.type]
dec eax dec eax
jnz .not_left jnz .not_left
xor eax,eax xor eax,eax
mov edx,skin_active.left.data mov edx,skin_active.left.data
or ecx,ecx or ecx,ecx
jnz @f jnz @f
mov edx,skin_inactive.left.data mov edx,skin_inactive.left.data
@@: jmp .next_bitmap @@: jmp .next_bitmap
.not_left: .not_left:
dec eax dec eax
jnz .not_oper jnz .not_oper
mov esi,[ebx+SKIN_BITMAPS.data] mov esi,[ebx+SKIN_BITMAPS.data]
add esi,skin_data add esi,skin_data
mov eax,[esi+0] mov eax,[esi+0]
neg eax neg eax
mov edx,skin_active.oper.data mov edx,skin_active.oper.data
or ecx,ecx or ecx,ecx
jnz @f jnz @f
mov edx,skin_inactive.oper.data mov edx,skin_inactive.oper.data
@@: jmp .next_bitmap @@: jmp .next_bitmap
.not_oper: .not_oper:
dec eax dec eax
jnz .not_base jnz .not_base
mov eax,[skin_active.left.width] mov eax,[skin_active.left.width]
mov edx,skin_active.base.data mov edx,skin_active.base.data
or ecx,ecx or ecx,ecx
jnz @f jnz @f
mov eax,[skin_inactive.left.width] mov eax,[skin_inactive.left.width]
mov edx,skin_inactive.base.data mov edx,skin_inactive.base.data
@@: jmp .next_bitmap @@: jmp .next_bitmap
.not_base: .not_base:
add ebx,8 add ebx,8
jmp .lp1 jmp .lp1
.next_bitmap: .next_bitmap:
mov ecx,[ebx+SKIN_BITMAPS.data] mov ecx,[ebx+SKIN_BITMAPS.data]
add ecx,skin_data add ecx,skin_data
mov [edx+4],eax mov [edx+4],eax
mov eax,[ecx+0] mov eax,[ecx+0]
mov [edx+8],eax mov [edx+8],eax
add ecx,8 add ecx,8
mov [edx+0],ecx mov [edx+0],ecx
add ebx,8 add ebx,8
jmp .lp1 jmp .lp1
.end_bitmaps: .end_bitmaps:
mov ebx,[ebp+SKIN_HEADER.buttons] mov ebx,[ebp+SKIN_HEADER.buttons]
add ebx,skin_data add ebx,skin_data
.lp2: cmp dword[ebx],0 .lp2: cmp dword[ebx],0
je .end_buttons je .end_buttons
mov eax,[ebx+SKIN_BUTTONS.type] mov eax,[ebx+SKIN_BUTTONS.type]
dec eax dec eax
jnz .not_close jnz .not_close
mov edx,skin_btn_close mov edx,skin_btn_close
jmp .next_button jmp .next_button
.not_close: .not_close:
dec eax dec eax
jnz .not_minimize jnz .not_minimize
mov edx,skin_btn_minimize mov edx,skin_btn_minimize
jmp .next_button jmp .next_button
.not_minimize: .not_minimize:
add ebx,12 add ebx,12
jmp .lp2 jmp .lp2
.next_button: .next_button:
movsx eax,[ebx+SKIN_BUTTONS.left] movsx eax,[ebx+SKIN_BUTTONS.left]
mov [edx+SKIN_BUTTON.left],eax mov [edx+SKIN_BUTTON.left],eax
movsx eax,[ebx+SKIN_BUTTONS.top] movsx eax,[ebx+SKIN_BUTTONS.top]
mov [edx+SKIN_BUTTON.top],eax mov [edx+SKIN_BUTTON.top],eax
movsx eax,[ebx+SKIN_BUTTONS.width] movsx eax,[ebx+SKIN_BUTTONS.width]
mov [edx+SKIN_BUTTON.width],eax mov [edx+SKIN_BUTTON.width],eax
movsx eax,[ebx+SKIN_BUTTONS.height] movsx eax,[ebx+SKIN_BUTTONS.height]
mov [edx+SKIN_BUTTON.height],eax mov [edx+SKIN_BUTTON.height],eax
add ebx,12 add ebx,12
jmp .lp2 jmp .lp2
.end_buttons: .end_buttons:
.exit: .exit:
ret ret
sys_putimage_with_check: sys_putimage_with_check:
or ebx,ebx or ebx,ebx
jz @f jz @f
call sys_putimage.forced call sys_putimage.forced
@@: ret @@: ret
drawwindow_IV_caption: drawwindow_IV_caption:
mov ebp,skin_active mov ebp,skin_active
or al,al or al,al
jnz @f jnz @f
mov ebp,skin_inactive mov ebp,skin_inactive
@@: @@:
mov esi,[esp+4] mov esi,[esp+4]
mov eax,[esi+WDATA.box.width] ; window width mov eax,[esi+WDATA.box.width] ; window width
mov edx,[ebp+SKIN_DATA.left.left] mov edx,[ebp+SKIN_DATA.left.left]
shl edx,16 shl edx,16
mov ecx,[ebp+SKIN_DATA.left.width] mov ecx,[ebp+SKIN_DATA.left.width]
shl ecx,16 shl ecx,16
add ecx,[_skinh] add ecx,[_skinh]
mov ebx, [ebp+SKIN_DATA.left.data] mov ebx, [ebp+SKIN_DATA.left.data]
call sys_putimage_with_check call sys_putimage_with_check
mov esi,[esp+4] mov esi,[esp+4]
mov eax,[esi+WDATA.box.width] mov eax,[esi+WDATA.box.width]
sub eax,[ebp+SKIN_DATA.left.width] sub eax,[ebp+SKIN_DATA.left.width]
sub eax,[ebp+SKIN_DATA.oper.width] sub eax,[ebp+SKIN_DATA.oper.width]
cmp eax,[ebp+SKIN_DATA.base.left] cmp eax,[ebp+SKIN_DATA.base.left]
jng .non_base jng .non_base
xor edx,edx xor edx,edx
mov ecx,[ebp+SKIN_DATA.base.width] mov ecx,[ebp+SKIN_DATA.base.width]
jecxz .non_base jecxz .non_base
div ecx div ecx
inc eax inc eax
mov ebx,[ebp+SKIN_DATA.base.data] mov ebx,[ebp+SKIN_DATA.base.data]
mov ecx,[ebp+SKIN_DATA.base.width] mov ecx,[ebp+SKIN_DATA.base.width]
shl ecx,16 shl ecx,16
add ecx,[_skinh] add ecx,[_skinh]
mov edx,[ebp+SKIN_DATA.base.left] mov edx,[ebp+SKIN_DATA.base.left]
sub edx,[ebp+SKIN_DATA.base.width] sub edx,[ebp+SKIN_DATA.base.width]
shl edx,16 shl edx,16
.baseskinloop: .baseskinloop:
shr edx,16 shr edx,16
add edx,[ebp+SKIN_DATA.base.width] add edx,[ebp+SKIN_DATA.base.width]
shl edx,16 shl edx,16
push eax ebx ecx edx push eax ebx ecx edx
call sys_putimage_with_check call sys_putimage_with_check
pop edx ecx ebx eax pop edx ecx ebx eax
dec eax dec eax
jnz .baseskinloop jnz .baseskinloop
.non_base: .non_base:
mov esi,[esp+4] mov esi,[esp+4]
mov edx,[esi+WDATA.box.width] mov edx,[esi+WDATA.box.width]
sub edx,[ebp+SKIN_DATA.oper.width] sub edx,[ebp+SKIN_DATA.oper.width]
inc edx inc edx
shl edx,16 shl edx,16
mov ebx,[ebp+SKIN_DATA.oper.data] mov ebx,[ebp+SKIN_DATA.oper.data]
mov ecx,[ebp+SKIN_DATA.oper.width] mov ecx,[ebp+SKIN_DATA.oper.width]
shl ecx,16 shl ecx,16
add ecx,[_skinh] add ecx,[_skinh]
call sys_putimage_with_check call sys_putimage_with_check
ret ret
;//mike.dld, 2006-08-02 ] ;//mike.dld, 2006-08-02 ]
@ -287,174 +287,174 @@ drawwindow_IV_caption:
drawwindow_IV: drawwindow_IV:
;param1 - aw_yes ;param1 - aw_yes
pusha pusha
push edx push edx
mov edi,edx mov edi,edx
mov ebp,skin_active mov ebp,skin_active
cmp byte [esp+32+4+4],0 cmp byte [esp+32+4+4],0
jne @f jne @f
mov ebp,skin_inactive mov ebp,skin_inactive
@@: @@:
mov eax,[edi+WDATA.box.left] mov eax,[edi+WDATA.box.left]
shl eax,16 shl eax,16
mov ax,word [edi+WDATA.box.left] mov ax,word [edi+WDATA.box.left]
add ax,word [edi+WDATA.box.width] add ax,word [edi+WDATA.box.width]
mov ebx,[edi+WDATA.box.top] mov ebx,[edi+WDATA.box.top]
shl ebx,16 shl ebx,16
mov bx,word [edi+WDATA.box.top] mov bx,word [edi+WDATA.box.top]
add bx,word [edi+WDATA.box.height] add bx,word [edi+WDATA.box.height]
; mov esi,[edi+24] ; mov esi,[edi+24]
; shr esi,1 ; shr esi,1
; and esi,0x007f7f7f ; and esi,0x007f7f7f
mov esi,[ebp+SKIN_DATA.colors.outer] mov esi,[ebp+SKIN_DATA.colors.outer]
call draw_rectangle call draw_rectangle
mov ecx,3 mov ecx,3
_dw3l: _dw3l:
add eax,1*65536-1 add eax,1*65536-1
add ebx,1*65536-1 add ebx,1*65536-1
test ax,ax test ax,ax
js no_skin_add_button js no_skin_add_button
test bx,bx test bx,bx
js no_skin_add_button js no_skin_add_button
mov esi,[ebp+SKIN_DATA.colors.frame] ;[edi+24] mov esi,[ebp+SKIN_DATA.colors.frame] ;[edi+24]
call draw_rectangle call draw_rectangle
dec ecx dec ecx
jnz _dw3l jnz _dw3l
mov esi,[ebp+SKIN_DATA.colors.inner] mov esi,[ebp+SKIN_DATA.colors.inner]
add eax,1*65536-1 add eax,1*65536-1
add ebx,1*65536-1 add ebx,1*65536-1
test ax,ax test ax,ax
js no_skin_add_button js no_skin_add_button
test bx,bx test bx,bx
js no_skin_add_button js no_skin_add_button
call draw_rectangle call draw_rectangle
cmp dword[skin_data],'SKIN' cmp dword[skin_data],'SKIN'
je @f je @f
xor eax,eax xor eax,eax
xor ebx,ebx xor ebx,ebx
mov esi,[esp] mov esi,[esp]
mov ecx,[esi+WDATA.box.width] mov ecx,[esi+WDATA.box.width]
inc ecx inc ecx
mov edx,[_skinh] mov edx,[_skinh]
mov edi,[common_colours+4] ; standard grab color mov edi,[common_colours+4] ; standard grab color
call [drawbar] call [drawbar]
jmp draw_clientbar jmp draw_clientbar
@@: @@:
mov al,[esp+32+4+4] mov al,[esp+32+4+4]
call drawwindow_IV_caption call drawwindow_IV_caption
draw_clientbar: draw_clientbar:
mov esi,[esp] mov esi,[esp]
mov edx,[esi+WDATA.box.top] ; WORK AREA mov edx,[esi+WDATA.box.top] ; WORK AREA
add edx,21+5 add edx,21+5
mov ebx,[esi+WDATA.box.top] mov ebx,[esi+WDATA.box.top]
add ebx,[esi+WDATA.box.height] add ebx,[esi+WDATA.box.height]
cmp edx,ebx cmp edx,ebx
jg _noinside2 jg _noinside2
mov eax,5 mov eax,5
mov ebx,[_skinh] mov ebx,[_skinh]
mov ecx,[esi+WDATA.box.width] mov ecx,[esi+WDATA.box.width]
mov edx,[esi+WDATA.box.height] mov edx,[esi+WDATA.box.height]
sub ecx,4 sub ecx,4
sub edx,4 sub edx,4
mov edi,[esi+WDATA.cl_workarea] mov edi,[esi+WDATA.cl_workarea]
test edi,0x40000000 test edi,0x40000000
jnz _noinside2 jnz _noinside2
call [drawbar] call [drawbar]
_noinside2: _noinside2:
cmp dword[skin_data],'SKIN' cmp dword[skin_data],'SKIN'
jne no_skin_add_button jne no_skin_add_button
;* close button ;* close button
mov edi,[BTN_ADDR] mov edi,[BTN_ADDR]
movzx eax,word [edi] movzx eax,word [edi]
cmp eax,1000 cmp eax,1000
jge no_skin_add_button jge no_skin_add_button
inc eax inc eax
mov [edi],ax mov [edi],ax
shl eax,4 shl eax,4
add eax,edi add eax,edi
mov bx,[CURRENT_TASK] mov bx,[CURRENT_TASK]
mov [eax],bx mov [eax],bx
add eax,2 ; save button id number add eax,2 ; save button id number
mov bx,1 mov bx,1
mov [eax],bx mov [eax],bx
add eax,2 ; x start add eax,2 ; x start
xor ebx,ebx xor ebx,ebx
cmp [skin_btn_close.left],0 cmp [skin_btn_close.left],0
jge _bCx_at_right jge _bCx_at_right
mov ebx,[esp] mov ebx,[esp]
mov ebx,[ebx+WDATA.box.width] mov ebx,[ebx+WDATA.box.width]
inc ebx inc ebx
_bCx_at_right: _bCx_at_right:
add ebx,[skin_btn_close.left] add ebx,[skin_btn_close.left]
mov [eax],bx mov [eax],bx
add eax,2 ; x size add eax,2 ; x size
mov ebx,[skin_btn_close.width] mov ebx,[skin_btn_close.width]
dec ebx dec ebx
mov [eax],bx mov [eax],bx
add eax,2 ; y start add eax,2 ; y start
mov ebx,[skin_btn_close.top] mov ebx,[skin_btn_close.top]
mov [eax],bx mov [eax],bx
add eax,2 ; y size add eax,2 ; y size
mov ebx,[skin_btn_close.height] mov ebx,[skin_btn_close.height]
dec ebx dec ebx
mov [eax],bx mov [eax],bx
;* minimize button ;* minimize button
mov edi,[BTN_ADDR] mov edi,[BTN_ADDR]
movzx eax,word [edi] movzx eax,word [edi]
cmp eax,1000 cmp eax,1000
jge no_skin_add_button jge no_skin_add_button
inc eax inc eax
mov [edi],ax mov [edi],ax
shl eax,4 shl eax,4
add eax,edi add eax,edi
mov bx,[CURRENT_TASK] mov bx,[CURRENT_TASK]
mov [eax],bx mov [eax],bx
add eax,2 ; save button id number add eax,2 ; save button id number
mov bx,65535 ;999 mov bx,65535 ;999
mov [eax],bx mov [eax],bx
add eax,2 ; x start add eax,2 ; x start
xor ebx,ebx xor ebx,ebx
cmp [skin_btn_minimize.left],0 cmp [skin_btn_minimize.left],0
jge _bMx_at_right jge _bMx_at_right
mov ebx,[esp] mov ebx,[esp]
mov ebx,[ebx+WDATA.box.width] mov ebx,[ebx+WDATA.box.width]
inc ebx inc ebx
_bMx_at_right: _bMx_at_right:
add ebx,[skin_btn_minimize.left] add ebx,[skin_btn_minimize.left]
mov [eax],bx mov [eax],bx
add eax,2 ; x size add eax,2 ; x size
mov ebx,[skin_btn_minimize.width] mov ebx,[skin_btn_minimize.width]
dec ebx dec ebx
mov [eax],bx mov [eax],bx
add eax,2 ; y start add eax,2 ; y start
mov ebx,[skin_btn_minimize.top] mov ebx,[skin_btn_minimize.top]
mov [eax],bx mov [eax],bx
add eax,2 ; y size add eax,2 ; y size
mov ebx,[skin_btn_minimize.height] mov ebx,[skin_btn_minimize.height]
dec ebx dec ebx
mov [eax],bx mov [eax],bx
no_skin_add_button: no_skin_add_button:
pop edi pop edi
popa popa
ret 4 ret 4

View File

@ -17,25 +17,25 @@ iglobal
endg endg
struct SKIN_DATA struct SKIN_DATA
.colors.inner dd ? colors.inner dd ?
.colors.outer dd ? colors.outer dd ?
.colors.frame dd ? colors.frame dd ?
.left.data dd ? left.data dd ?
.left.left dd ? left.left dd ?
.left.width dd ? left.width dd ?
.oper.data dd ? oper.data dd ?
.oper.left dd ? oper.left dd ?
.oper.width dd ? oper.width dd ?
.base.data dd ? base.data dd ?
.base.left dd ? base.left dd ?
.base.width dd ? base.width dd ?
ends ends
struct SKIN_BUTTON struct SKIN_BUTTON
.left dd ? left dd ?
.top dd ? top dd ?
.width dd ? width dd ?
.height dd ? height dd ?
ends ends
uglobal uglobal
@ -43,18 +43,18 @@ uglobal
align 4 align 4
skin_udata: skin_udata:
_skinh dd ? _skinh dd ?
_skinmargins: ; rw 4 _skinmargins: ; rw 4
.right dw ? .right dw ?
.left dw ? .left dw ?
.bottom dw ? .bottom dw ?
.top dw ? .top dw ?
skin_btn_close SKIN_BUTTON skin_btn_close SKIN_BUTTON
skin_btn_minimize SKIN_BUTTON skin_btn_minimize SKIN_BUTTON
skin_active SKIN_DATA skin_active SKIN_DATA
skin_inactive SKIN_DATA skin_inactive SKIN_DATA
align 4 align 4

View File

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

View File

@ -11,31 +11,6 @@ macro $Revision a {
$Revision$ $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 ; macros definition
macro diff16 title,l1,l2 macro diff16 title,l1,l2
{ {

View File

@ -25,40 +25,42 @@ ARP_RESPONSE_TIMEOUT equ 3
ARP_REQUEST_TTL equ 31 ; 20 s ARP_REQUEST_TTL equ 31 ; 20 s
ARP_ENTRY_TTL equ 937 ; 600 s ARP_ENTRY_TTL equ 937 ; 600 s
ARP_STATIC_ENTRY equ -1
ARP_REQ_OPCODE equ 0x0100 ; request ARP_REQ_OPCODE equ 0x0100 ; request
ARP_REP_OPCODE equ 0x0200 ; reply ARP_REP_OPCODE equ 0x0200 ; reply
ARP_TABLE_SIZE equ 20 ; Size of table ARP_TABLE_SIZE equ 20 ; Size of table
struct ARP_ENTRY struct ARP_entry
.IP dd ?
.MAC dp ? IP dd ?
.Status dw ? MAC dp ?
.TTL dw ? Status dw ?
.size: TTL dw ?
ends ends
struct ARP_Packet struct ARP_header
.HardwareType dw ?
.ProtocolType dw ?
.HardwareSize db ?
.ProtocolSize db ?
.Opcode dw ?
.SenderMAC dp ?
.SenderIP dd ?
.TargetMAC dp ?
.TargetIP dd ?
.size:
ends
HardwareType dw ?
ProtocolType dw ?
HardwareSize db ?
ProtocolSize db ?
Opcode dw ?
SenderMAC dp ?
SenderIP dd ?
TargetMAC dp ?
TargetIP dd ?
ends
align 4 align 4
uglobal uglobal
NumARP dd ? 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_TX rd MAX_NET_DEVICES
ARP_PACKETS_RX rd MAX_NET_DEVICES ARP_PACKETS_RX rd MAX_NET_DEVICES
@ -114,21 +116,21 @@ local .exit
mov esi, ARP_table mov esi, ARP_table
.loop: .loop:
cmp [esi + ARP_ENTRY.TTL], 0xffff ; 0xffff = static entry cmp [esi + ARP_entry.TTL], ARP_STATIC_ENTRY
je .next je .next
dec [esi + ARP_ENTRY.TTL] dec [esi + ARP_entry.TTL]
jz .time_out jz .time_out
.next: .next:
add esi, ARP_ENTRY.size add esi, sizeof.ARP_entry
dec ecx dec ecx
jnz .loop jnz .loop
jmp .exit jmp .exit
.time_out: .time_out:
cmp [esi + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE cmp [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE
jz .response_timeout je .response_timeout
push esi ecx push esi ecx
call ARP_del_entry call ARP_del_entry
@ -137,8 +139,8 @@ local .exit
jmp .next jmp .next
.response_timeout: .response_timeout:
mov [esi + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT mov [esi + ARP_entry.Status], ARP_RESPONSE_TIMEOUT
mov [esi + ARP_ENTRY.TTL], 10 mov [esi + ARP_entry.TTL], 10
jmp .next jmp .next
@ -161,29 +163,29 @@ align 4
ARP_input: ARP_input:
DEBUGF 1,"ARP_Handler - start\n" DEBUGF 1,"ARP_Handler - start\n"
cmp ecx, ARP_Packet.size cmp ecx, sizeof.ARP_header
jb .exit jb .exit
;--------------------- ;---------------------
; Handle Reply packets ; Handle Reply packets
cmp word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE cmp [edx + ARP_header.Opcode], ARP_REP_OPCODE
jne .maybe_request jne .maybe_request
DEBUGF 1,"ARP_Handler - it's a reply packet from %u.%u.%u.%u\n",\ 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] mov ecx, [NumARP]
test ecx, ecx test ecx, ecx
jz .exit jz .exit
mov eax, [edx + ARP_Packet.SenderIP] mov eax, [edx + ARP_header.SenderIP]
mov esi, ARP_table mov esi, ARP_table
.loop: .loop:
cmp [esi + ARP_ENTRY.IP], eax cmp [esi + ARP_entry.IP], eax
je .gotit je .gotit
add esi, ARP_ENTRY.size add esi, sizeof.ARP_entry
dec ecx dec ecx
jnz .loop jnz .loop
@ -192,18 +194,18 @@ ARP_input:
.gotit: .gotit:
DEBUGF 1,"ARP_Handler - found matching entry\n" 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 je .exit
DEBUGF 1,"ARP_Handler - updating entry\n" DEBUGF 1,"ARP_Handler - updating entry\n"
mov [esi+ARP_ENTRY.Status], ARP_VALID_MAPPING mov [esi + ARP_entry.Status], ARP_VALID_MAPPING
mov [esi+ARP_ENTRY.TTL], ARP_ENTRY_TTL mov [esi + ARP_entry.TTL], ARP_ENTRY_TTL
mov eax, dword [edx + ARP_Packet.SenderMAC] mov eax, dword [edx + ARP_header.SenderMAC]
mov dword [esi+ARP_ENTRY.MAC], eax mov dword [esi+ARP_entry.MAC], eax
mov ax , word [edx + ARP_Packet.SenderMAC + 4] mov ax , word [edx + ARP_header.SenderMAC + 4]
mov word [esi+ARP_ENTRY.MAC+4], ax mov word [esi+ARP_entry.MAC+4], ax
jmp .exit jmp .exit
@ -212,7 +214,7 @@ ARP_input:
; Handle Request packets ; Handle Request packets
.maybe_request: .maybe_request:
cmp word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE cmp [edx + ARP_header.Opcode], ARP_REQ_OPCODE
jne .exit jne .exit
call NET_ptr_to_num call NET_ptr_to_num
@ -222,7 +224,7 @@ ARP_input:
inc [ARP_PACKETS_RX+4*edi] inc [ARP_PACKETS_RX+4*edi]
mov eax, [IP_LIST+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 ? jne .exit ; TODO: instead of quitting, update local entrys with matching IP's ?
push eax push eax
@ -231,8 +233,8 @@ ARP_input:
; OK, it is a request for one of our MAC addresses. ; 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) ; Build the frame and send it. We can reuse the buffer. (faster then using ARP_create_packet)
lea esi, [edx + ARP_Packet.SenderMAC] lea esi, [edx + ARP_header.SenderMAC]
lea edi, [edx + ARP_Packet.TargetMAC] lea edi, [edx + ARP_header.TargetMAC]
movsd ; Move Sender Mac to Dest MAC movsd ; Move Sender Mac to Dest MAC
movsw ; movsw ;
movsd ; Move sender IP to Dest IP movsd ; Move sender IP to Dest IP
@ -240,21 +242,21 @@ ARP_input:
pop esi pop esi
mov esi, [NET_DRV_LIST + 4*esi] mov esi, [NET_DRV_LIST + 4*esi]
lea esi, [esi + ETH_DEVICE.mac] 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 movsd ; Copy MAC address from in MAC_LIST
movsw ; movsw ;
pop eax pop eax
stosd ; Write our IP 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 ; Now, Fill in ETHERNET header
mov edi, [esp] mov edi, [esp]
lea esi, [edx + ARP_Packet.TargetMAC] lea esi, [edx + ARP_header.TargetMAC]
movsd movsd
movsw movsw
lea esi, [edx + ARP_Packet.SenderMAC] lea esi, [edx + ARP_header.SenderMAC]
movsd movsd
movsw movsw
; mov ax , ETHER_ARP ; mov ax , ETHER_ARP
@ -294,20 +296,20 @@ ARP_output_request:
lea eax, [ebx + ETH_DEVICE.mac] ; local device mac lea eax, [ebx + ETH_DEVICE.mac] ; local device mac
mov edx, ETH_BROADCAST ; broadcast mac mov edx, ETH_BROADCAST ; broadcast mac
mov ecx, ARP_Packet.size mov ecx, sizeof.ARP_header
mov di, ETHER_ARP mov di, ETHER_ARP
call ETH_output call ETH_output
jz .exit jz .exit
mov ecx, eax mov ecx, eax
mov [edi + ARP_Packet.HardwareType], 0x0100 ; Ethernet mov [edi + ARP_header.HardwareType], 0x0100 ; Ethernet
mov [edi + ARP_Packet.ProtocolType], 0x0008 ; IP mov [edi + ARP_header.ProtocolType], 0x0008 ; IP
mov [edi + ARP_Packet.HardwareSize], 6 ; MAC-addr length mov [edi + ARP_header.HardwareSize], 6 ; MAC-addr length
mov [edi + ARP_Packet.ProtocolSize], 4 ; IP-addr length mov [edi + ARP_header.ProtocolSize], 4 ; IP-addr length
mov [edi + ARP_Packet.Opcode], ARP_REQ_OPCODE ; Request 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 lea esi, [ebx + ETH_DEVICE.mac] ; SenderMac
movsw ; movsw ;
@ -353,19 +355,19 @@ ARP_add_entry:
cmp ecx, ARP_TABLE_SIZE ; list full ? cmp ecx, ARP_TABLE_SIZE ; list full ?
jae .error jae .error
mov eax, dword[esi + ARP_ENTRY.MAC] mov eax, dword [esi + ARP_entry.MAC]
mov bx , word[esi + ARP_ENTRY.MAC + 4] mov bx , word [esi + ARP_entry.MAC + 4]
mov edi, ARP_table mov edi, ARP_table
.loop: .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 ; jne .maybe_next ;
cmp word [edi + ARP_ENTRY.MAC + 4], bx ; cmp word [edi + ARP_entry.MAC + 4], bx ;
jne .maybe_next ; jne .maybe_next ;
cmp dword[edi + ARP_ENTRY.TTL], 0xFFFF ; static entry cmp [edi + ARP_entry.TTL], ARP_STATIC_ENTRY
jne .notstatic jne .notstatic
cmp dword[esi + ARP_ENTRY.TTL], 0xFFFF cmp [esi + ARP_entry.TTL], ARP_STATIC_ENTRY
jne .error jne .error
.notstatic: .notstatic:
@ -374,18 +376,18 @@ ARP_add_entry:
jmp .add jmp .add
.maybe_next: .maybe_next:
add esi, ARP_ENTRY.size add esi, sizeof.ARP_entry
loop .loop loop .loop
mov ecx, [NumARP] mov ecx, [NumARP]
.add: .add:
push ecx push ecx
imul ecx, ARP_ENTRY.size imul ecx, sizeof.ARP_entry
lea edi, [ecx + ARP_table] lea edi, [ecx + ARP_table]
mov ecx, ARP_ENTRY.size/2 mov ecx, sizeof.ARP_entry/2
rep movsw rep movsw
lea esi, [edi - ARP_ENTRY.size] lea esi, [edi - sizeof.ARP_entry]
inc [NumARP] inc [NumARP]
pop eax pop eax
DEBUGF 1,"New entry created: %u\n", 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] 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 sub ecx, esi
shr ecx, 1 shr ecx, 1
mov edi, esi mov edi, esi
lea esi, [edi + ARP_ENTRY.size] lea esi, [edi + sizeof.ARP_entry]
rep movsw rep movsw
dec [NumARP] dec [NumARP]
@ -474,11 +476,11 @@ ARP_IP_to_MAC:
mov ecx, [NumARP] mov ecx, [NumARP]
test ecx, ecx test ecx, ecx
jz .not_in_list jz .not_in_list
mov esi, ARP_table + ARP_ENTRY.IP mov esi, ARP_table + ARP_entry.IP
.scan_loop: .scan_loop:
cmp [esi], eax cmp [esi], eax
je .found_it je .found_it
add esi, ARP_ENTRY.size add esi, sizeof.ARP_entry
loop .scan_loop loop .scan_loop
.not_in_list: .not_in_list:
@ -496,7 +498,7 @@ ARP_IP_to_MAC:
pushd eax pushd eax
mov esi, esp mov esi, esp
call ARP_add_entry call ARP_add_entry
add esp, ARP_ENTRY.size add esp, sizeof.ARP_entry
cmp eax, -1 cmp eax, -1
je .full je .full
@ -509,12 +511,12 @@ ARP_IP_to_MAC:
;; TODO: check if driver could transmit packet ;; TODO: check if driver could transmit packet
pop esi pop esi
imul esi, ARP_ENTRY.size imul esi, sizeof.ARP_entry
add esi, ARP_table add esi, ARP_table
mov ecx, 25 mov ecx, 25
.wait_loop: .wait_loop:
cmp [esi + ARP_ENTRY.Status], 1 cmp [esi + ARP_entry.Status], 1
je .got_it je .got_it
push esi push esi
mov esi, 10 mov esi, 10
@ -527,12 +529,12 @@ ARP_IP_to_MAC:
.found_it: .found_it:
DEBUGF 1,"found IP in ARPTable\n" DEBUGF 1,"found IP in ARPTable\n"
cmp [esi + ARP_ENTRY.Status], 1 cmp [esi + ARP_entry.Status], 1
jne .invalid jne .invalid
.got_it: .got_it:
movzx eax, word [esi+ARP_ENTRY.MAC] movzx eax, word [esi + ARP_entry.MAC]
mov ebx, dword[esi+ARP_ENTRY.MAC+2] mov ebx, dword[esi + ARP_entry.MAC+2]
ret ret
.invalid: .invalid:
@ -607,10 +609,10 @@ ARP_API:
jae .error jae .error
; edi = pointer to buffer ; edi = pointer to buffer
; ecx = # entry ; ecx = # entry
imul ecx, ARP_ENTRY.size imul ecx, sizeof.ARP_entry
add ecx, ARP_table add ecx, ARP_table
mov esi, ecx mov esi, ecx
mov ecx, ARP_ENTRY.size/2 mov ecx, sizeof.ARP_entry/2
rep movsw rep movsw
xor eax, eax xor eax, eax
@ -625,7 +627,7 @@ ARP_API:
; ecx = # entry ; ecx = # entry
cmp ecx, [NumARP] cmp ecx, [NumARP]
jae .error jae .error
imul ecx, ARP_ENTRY.size imul ecx, sizeof.ARP_entry
lea esi, [ARP_table + ecx] lea esi, [ARP_table + ecx]
call ARP_del_entry call ARP_del_entry
ret ret

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; IPv4.INC ;; ;; IPv4.INC ;;
@ -22,35 +22,38 @@ MAX_FRAGMENTS equ 64
MAX_IP equ MAX_NET_DEVICES MAX_IP equ MAX_NET_DEVICES
IP_MAX_INTERFACES equ MAX_IP IP_MAX_INTERFACES equ MAX_IP
struct IPv4_Packet 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] VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits]
.TotalLength dw ? TypeOfService db ? ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0]
.Identification dw ? TotalLength dw ?
.FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] Identification dw ?
.TimeToLive db ? ; FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15]
.Protocol db ? TimeToLive db ? ;
.HeaderChecksum dw ? Protocol db ?
.SourceAddress dd ? HeaderChecksum dw ?
.DestinationAddress dd ? SourceAddress dd ?
.DataOrOptional: DestinationAddress dd ?
ends ends
struct FRAGMENT_slot struct FRAGMENT_slot
.ttl dw ? ; Time to live for this entry, 0 for empty slot's
.id dw ? ; Identification field from IP header ttl dw ? ; Time to live for this entry, 0 for empty slot's
.SrcIP dd ? ; .. from IP header id dw ? ; Identification field from IP header
.DstIP dd ? ; .. from IP header SrcIP dd ? ; .. from IP header
.ptr dd ? ; Pointer to first packet DstIP dd ? ; .. from IP header
.size: ptr dd ? ; Pointer to first packet
ends ends
struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets
.PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet)
.NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet) PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet)
.Owner dd ? ; Pointer to structure of driver NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet)
rb 2 ; to match ethernet header size ; TODO: fix this hack Owner dd ? ; Pointer to structure of driver
.Data: ; Ip header begins here (we will need the IP header to re-construct the complete packet) rb 2 ; to match ethernet header size ; TODO: fix this hack
; Ip header begins here (we will need the IP header to re-construct the complete packet)
ends ends
@ -65,7 +68,7 @@ uglobal
IP_PACKETS_TX rd MAX_IP IP_PACKETS_TX rd MAX_IP
IP_PACKETS_RX 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 endg
@ -84,7 +87,7 @@ macro IPv4_init {
rep stosd rep stosd
mov edi, FRAGMENT_LIST 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 rep stosd
} }
@ -200,20 +203,20 @@ IPv4_input: ; TODO: implement handler for IP options
; TODO2: add code for raw sockets ; TODO2: add code for raw sockets
DEBUGF 1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\ 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",\ 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 ; 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 je .dump
;-------------------------------------- ;--------------------------------------
; First, check if IP packet has options ; 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) and al , 0x0f ; get IHL(header length)
cmp al , 0x05 ; IHL!= 5*4(20 bytes) cmp al , 0x05 ; IHL!= 5*4(20 bytes)
jnz .has_options jnz .has_options
@ -235,7 +238,7 @@ IPv4_input: ; TODO: implement handler for IP options
; check if it matches local ip ; check if it matches local ip
mov eax, [IP_LIST+edi] mov eax, [IP_LIST+edi]
cmp [edx + IPv4_Packet.DestinationAddress], eax cmp [edx + IPv4_header.DestinationAddress], eax
je .ip_ok je .ip_ok
; check for broadcast ; check for broadcast
@ -243,17 +246,17 @@ IPv4_input: ; TODO: implement handler for IP options
mov eax, [SUBNET_LIST+edi] mov eax, [SUBNET_LIST+edi]
not eax not eax
or eax, [IP_LIST+edi] or eax, [IP_LIST+edi]
cmp [edx + IPv4_Packet.DestinationAddress], eax cmp [edx + IPv4_header.DestinationAddress], eax
je .ip_ok je .ip_ok
; or a special broadcast ; or a special broadcast
cmp [edx + IPv4_Packet.DestinationAddress], -1 cmp [edx + IPv4_header.DestinationAddress], -1
je .ip_ok je .ip_ok
; maybe it's a multicast then ; maybe it's a multicast then
mov eax, [edx + IPv4_Packet.DestinationAddress] mov eax, [edx + IPv4_header.DestinationAddress]
and eax, 0xff000000 and eax, 0xff000000
; cmp eax, 224 shl 24 ; cmp eax, 224 shl 24
; je .ip_ok ; je .ip_ok
@ -277,29 +280,29 @@ IPv4_input: ; TODO: implement handler for IP options
;---------------------------------- ;----------------------------------
; Check if the packet is fragmented ; 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 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 jnz .is_last_fragment
;------------------------------------------------------------------- ;-------------------------------------------------------------------
; No, it's just a regular IP packet, pass it to the higher protocols ; 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 .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 ; and eax, 0x0000000f ;
shl eax, 2 ; 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 ; xchg cl , ch ;
sub ecx, eax ; sub ecx, eax ;
add eax, edx add eax, edx
push eax push eax
mov esi, [edx + IPv4_Packet.SourceAddress] ; These values might be of interest to the higher protocols mov esi, [edx + IPv4_header.SourceAddress] ; These values might be of interest to the higher protocols
mov edi, [edx + IPv4_Packet.DestinationAddress] ; mov edi, [edx + IPv4_header.DestinationAddress] ;
mov al , [edx + IPv4_Packet.Protocol] mov al , [edx + IPv4_header.Protocol]
pop edx ; Offset to data (tcp/udp/icmp/.. Packet) pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
cmp al , IP_PROTO_TCP cmp al , IP_PROTO_TCP
@ -326,11 +329,11 @@ IPv4_input: ; TODO: implement handler for IP options
.has_fragments: .has_fragments:
movzx eax, [edx + IPv4_Packet.FlagsAndFragmentOffset] movzx eax, [edx + IPv4_header.FlagsAndFragmentOffset]
xchg al , ah xchg al , ah
shl ax , 3 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? test ax , ax ; Is this the first packet of the fragment?
jz .is_first_fragment jz .is_first_fragment
@ -379,17 +382,17 @@ IPv4_input: ; TODO: implement handler for IP options
.find_free_slot: .find_free_slot:
cmp word [esi + FRAGMENT_slot.ttl], 0 cmp word [esi + FRAGMENT_slot.ttl], 0
je .found_free_slot je .found_free_slot
add esi, FRAGMENT_slot.size add esi, sizeof.FRAGMENT_slot
loop .find_free_slot loop .find_free_slot
jmp .dump ; If no free slot was found, dump the packet 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 .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 [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 [esi + FRAGMENT_slot.id], ax
mov eax,[edx + IPv4_Packet.SourceAddress] mov eax,[edx + IPv4_header.SourceAddress]
mov [esi + FRAGMENT_slot.SrcIP], eax mov [esi + FRAGMENT_slot.SrcIP], eax
mov eax, [edx + IPv4_Packet.DestinationAddress] mov eax, [edx + IPv4_header.DestinationAddress]
mov [esi + FRAGMENT_slot.DstIP], eax mov [esi + FRAGMENT_slot.DstIP], eax
pop eax pop eax
mov [esi + FRAGMENT_slot.ptr], eax mov [esi + FRAGMENT_slot.ptr], eax
@ -420,11 +423,11 @@ IPv4_input: ; TODO: implement handler for IP options
.count_bytes: .count_bytes:
cmp [esi + FRAGMENT_entry.PrevPtr], edi cmp [esi + FRAGMENT_entry.PrevPtr], edi
jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) 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 xchg cl, ch
DEBUGF 1,"Packet size: %u\n", cx DEBUGF 1,"Packet size: %u\n", cx
add ax, 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 and cx, 0x000F
shl cx, 2 shl cx, 2
DEBUGF 1,"Header size: %u\n", cx 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.PrevPtr], edi
mov [esi + FRAGMENT_entry.Owner], ebx 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 xchg cl , ch
DEBUGF 1,"Packet size: %u\n", cx DEBUGF 1,"Packet size: %u\n", cx
add ax , cx add ax , cx
DEBUGF 1,"Total Received data size: %u\n", eax DEBUGF 1,"Total Received data size: %u\n", eax
push eax push eax
mov ax , [edx + IPv4_Packet.FlagsAndFragmentOffset] mov ax , [edx + IPv4_header.FlagsAndFragmentOffset]
xchg al , ah xchg al , ah
shl ax , 3 shl ax , 3
add cx , ax 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 mov edx, [esp+4] ; Get pointer to first fragment entry back in edx
.rebuild_packet_loop: .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 xchg cl , ch ; intel byte order
shl cx , 3 ; multiply by 8 and clear first 3 bits shl cx , 3 ; multiply by 8 and clear first 3 bits
DEBUGF 1,"Fragment offset: %u\n", cx DEBUGF 1,"Fragment offset: %u\n", cx
lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment 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 ; and bx , 0x000F ;
shl bx , 2 ; shl bx , 2 ;
lea esi, [edx + FRAGMENT_entry.Data] ; Set esi to the correct begin of fragment lea esi, [edx + sizeof.FRAGMENT_entry] ; Set esi to the correct begin of fragment
movzx ecx, [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Calculate total length of fragment movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment
xchg cl, ch ; intel byte order xchg cl, ch ; intel byte order
cmp edi, eax ; Is this packet the first fragment ? cmp edi, eax ; Is this packet the first fragment ?
@ -504,7 +507,7 @@ IPv4_input: ; TODO: implement handler for IP options
pop ecx pop ecx
xchg cl, ch xchg cl, ch
mov edx, eax mov edx, eax
mov [edx + IPv4_Packet.TotalLength], cx mov [edx + IPv4_header.TotalLength], cx
add esp, 8 add esp, 8
xchg cl, ch ; xchg cl, ch ;
@ -550,11 +553,11 @@ IPv4_find_fragment_slot:
;;; TODO: the RFC says we should check protocol number too ;;; TODO: the RFC says we should check protocol number too
push eax ebx ecx edx push eax ebx ecx edx
mov ax , [edx + IPv4_Packet.Identification] mov ax , [edx + IPv4_header.Identification]
mov ecx, MAX_FRAGMENTS mov ecx, MAX_FRAGMENTS
mov esi, FRAGMENT_LIST mov esi, FRAGMENT_LIST
mov ebx, [edx + IPv4_Packet.SourceAddress] mov ebx, [edx + IPv4_header.SourceAddress]
mov edx, [edx + IPv4_Packet.DestinationAddress] mov edx, [edx + IPv4_header.DestinationAddress]
.find_slot: .find_slot:
cmp [esi + FRAGMENT_slot.id], ax cmp [esi + FRAGMENT_slot.id], ax
jne .try_next jne .try_next
@ -563,7 +566,7 @@ IPv4_find_fragment_slot:
cmp [esi + FRAGMENT_slot.DstIP], edx cmp [esi + FRAGMENT_slot.DstIP], edx
je .found_slot je .found_slot
.try_next: .try_next:
add esi, FRAGMENT_slot.size add esi, sizeof.FRAGMENT_slot
loop .find_slot loop .find_slot
; pop edx ebx ; pop edx ebx
or esi, -1 or esi, -1
@ -617,29 +620,29 @@ IPv4_output:
lea eax, [ebx + ETH_DEVICE.mac] lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp mov edx, esp
mov ecx, [esp + 18] mov ecx, [esp + 18]
add ecx, IPv4_Packet.DataOrOptional add ecx, sizeof.IPv4_header
mov di , ETHER_IPv4 mov di , ETHER_IPv4
call ETH_output call ETH_output
jz .error jz .error
add esp, 6 ; pop the mac add esp, 6 ; pop the mac
mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) mov [edi + IPv4_header.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header)
mov [edi + IPv4_Packet.TypeOfService], 0 ; nothing special, just plain ip packet mov [edi + IPv4_header.TypeOfService], 0 ; nothing special, just plain ip packet
mov [edi + IPv4_Packet.TotalLength], cx mov [edi + IPv4_header.TotalLength], cx
rol [edi + IPv4_Packet.TotalLength], 8 ; internet byte order rol [edi + IPv4_header.TotalLength], 8 ; internet byte order
mov [edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000 mov [edi + IPv4_header.FlagsAndFragmentOffset], 0x0000
mov [edi + IPv4_Packet.HeaderChecksum], 0 mov [edi + IPv4_header.HeaderChecksum], 0
pop word [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol pop word [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol
; [edi + IPv4_Packet.Protocol] ; [edi + IPv4_header.Protocol]
popw [edi + IPv4_Packet.Identification] ; fragment id popw [edi + IPv4_header.Identification] ; fragment id
popd [edi + IPv4_Packet.SourceAddress] popd [edi + IPv4_header.SourceAddress]
popd [edi + IPv4_Packet.DestinationAddress] popd [edi + IPv4_header.DestinationAddress]
pop ecx pop ecx
IPv4_checksum edi IPv4_checksum edi
add edi, IPv4_Packet.DataOrOptional add edi, sizeof.IPv4_header
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx
ret ret
@ -694,7 +697,7 @@ IPv4_output_raw:
lea eax, [ebx + ETH_DEVICE.mac] lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp mov edx, esp
mov ecx, [esp + 6+4] mov ecx, [esp + 6+4]
add ecx, IPv4_Packet.DataOrOptional add ecx, sizeof.IPv4_header
mov di, ETHER_IPv4 mov di, ETHER_IPv4
call ETH_output call ETH_output
jz .error jz .error
@ -711,22 +714,22 @@ IPv4_output_raw:
rep movsb rep movsb
pop ecx edi pop ecx edi
; [edi + IPv4_Packet.VersionAndIHL] ; IPv4, normal length (no Optional header) ; [edi + IPv4_header.VersionAndIHL] ; IPv4, normal length (no Optional header)
; [edi + IPv4_Packet.TypeOfService] ; nothing special, just plain ip packet ; [edi + IPv4_header.TypeOfService] ; nothing special, just plain ip packet
; [edi + IPv4_Packet.TotalLength] ; [edi + IPv4_header.TotalLength]
; [edi + IPv4_Packet.TotalLength] ; internet byte order ; [edi + IPv4_header.TotalLength] ; internet byte order
; [edi + IPv4_Packet.FlagsAndFragmentOffset] ; [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_header.TimeToLive] ; ttl shl 8 + protocol
; [edi + IPv4_Packet.Protocol] ; [edi + IPv4_header.Protocol]
; [edi + IPv4_Packet.Identification] ; fragment id ; [edi + IPv4_header.Identification] ; fragment id
; [edi + IPv4_Packet.SourceAddress] ; [edi + IPv4_header.SourceAddress]
; [edi + IPv4_Packet.DestinationAddress] ; [edi + IPv4_header.DestinationAddress]
IPv4_checksum edi ;;;; todo: checksum for IP packet with options! 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 DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
ret ret
@ -760,11 +763,11 @@ IPv4_fragment:
and ecx, not 111b ; align 4 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 jb .err2
push esi ecx push esi ecx
mov eax, [esi + IPv4_Packet.DestinationAddress] mov eax, [esi + IPv4_header.DestinationAddress]
call ARP_IP_to_MAC call ARP_IP_to_MAC
pop ecx esi pop ecx esi
cmp eax, -1 cmp eax, -1
@ -779,7 +782,7 @@ IPv4_fragment:
push esi ; ptr to ip header 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 ecx ; max data size
push dword 0 ; offset push dword 0 ; offset
@ -802,7 +805,7 @@ IPv4_fragment:
; copy data ; copy data
mov esi, [esp + 2*4] mov esi, [esp + 2*4]
add esi, IPv4_Packet.DataOrOptional add esi, sizeof.IPv4_header
add esi, [esp] ; offset add esi, [esp] ; offset
mov ecx, [esp + 1*4] mov ecx, [esp + 1*4]
@ -811,9 +814,9 @@ IPv4_fragment:
; now, correct header ; now, correct header
mov ecx, [esp + 1*4] mov ecx, [esp + 1*4]
add ecx, IPv4_Packet.DataOrOptional add ecx, sizeof.IPv4_header
xchg cl, ch xchg cl, ch
mov [edi + IPv4_Packet.TotalLength], cx mov [edi + IPv4_header.TotalLength], cx
mov ecx, [esp] ; offset mov ecx, [esp] ; offset
xchg cl, ch xchg cl, ch
@ -822,9 +825,9 @@ IPv4_fragment:
; je .last_fragment ; je .last_fragment
or cx, 1 shl 2 ; more fragments or cx, 1 shl 2 ; more fragments
; .last_fragment: ; .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 ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< send the packet
mov ecx, [esp + 1*4] mov ecx, [esp + 1*4]

View File

@ -16,29 +16,28 @@
$Revision$ $Revision$
struct ETH_FRAME struct ETH_header
.DstMAC dp ? ; destination MAC-address
.SrcMAC dp ? ; source MAC-address DstMAC dp ? ; destination MAC-address
.Type dw ? ; type of the upper-layer protocol SrcMAC dp ? ; source MAC-address
.Data: ; data (46-1500 bytes for a normal packet) Type dw ? ; type of the upper-layer protocol
ends ends
ETH_FRAME_MINIMUM equ 60 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 ? set_MAC dd ?
.get_mode dd ? get_MAC dd ?
.set_MAC dd ? mode dd ?
.get_MAC dd ? mac dp ?
.mode dd ? ends
.mac dp ?
end virtual
align 4 align 4
iglobal iglobal
@ -67,10 +66,10 @@ ETH_input:
DEBUGF 1,"ETH_input - size: %u\n", ecx DEBUGF 1,"ETH_input - size: %u\n", ecx
cmp ecx, ETH_FRAME_MINIMUM cmp ecx, ETH_FRAME_MINIMUM
jb .dump jb .dump
sub ecx, ETH_FRAME.Data sub ecx, sizeof.ETH_header
lea edx, [eax + ETH_FRAME.Data] lea edx, [eax + sizeof.ETH_header]
mov ax , [eax + ETH_FRAME.Type] mov ax , [eax + ETH_header.Type]
cmp ax, ETHER_IPv4 cmp ax, ETHER_IPv4
je IPv4_input je IPv4_input
@ -116,7 +115,7 @@ ETH_output:
push ecx ; << 1 push ecx ; << 1
push di eax edx ; << 2 push di eax edx ; << 2
add ecx, ETH_FRAME.Data add ecx, sizeof.ETH_header
push ecx ; << 3 push ecx ; << 3
@ -137,8 +136,8 @@ ETH_output:
pop ax ; >> 2 pop ax ; >> 2
stosw 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 mov edx, ecx ; Set edx to complete buffer size
pop ecx ; >> 1 pop ecx ; >> 1
@ -210,12 +209,12 @@ ETH_API:
ret ret
.packets_tx: .packets_tx:
mov eax, dword [eax + NET_DEVICE.packets_tx] mov eax, [eax + NET_DEVICE.packets_tx]
ret ret
.packets_rx: .packets_rx:
mov eax, dword [eax + NET_DEVICE.packets_rx] mov eax, [eax + NET_DEVICE.packets_rx]
ret ret
.bytes_tx: .bytes_tx:

View File

@ -87,13 +87,14 @@ ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed
struct ICMP_Packet struct ICMP_header
.Type db ?
.Code db ? Type db ?
.Checksum dw ? Code db ?
.Identifier dw ? Checksum dw ?
.SequenceNumber dw ? Identifier dw ?
.Data: SequenceNumber dw ?
ends ends
@ -146,8 +147,8 @@ ICMP_input:
; First, check the checksum (altough some implementations ignore it) ; First, check the checksum (altough some implementations ignore it)
push edx esi ecx push edx esi ecx
push [edx + ICMP_Packet.Checksum] push [edx + ICMP_header.Checksum]
mov [edx + ICMP_Packet.Checksum], 0 mov [edx + ICMP_header.Checksum], 0
mov esi, edx mov esi, edx
xor edx, edx xor edx, edx
call checksum_1 call checksum_1
@ -157,14 +158,14 @@ ICMP_input:
pop ecx esi edx pop ecx esi edx
jne .checksum_mismatch 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 jne .check_sockets
; We well re-use the packet sow e can create the response as fast as possible ; 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 :) ; Notice: this only works on pure ethernet (however, IP packet options are not a problem this time :)
DEBUGF 1,"ICMP_input - echo request\n" 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) ; Update stats (and validate device ptr)
call NET_ptr_to_num call NET_ptr_to_num
@ -175,24 +176,24 @@ ICMP_input:
; exchange dest and source address in IP header ; exchange dest and source address in IP header
; exchange dest and source MAC in ETH header ; exchange dest and source MAC in ETH header
mov esi, [esp] ; Start of buffer mov esi, [esp] ; Start of buffer
push dword [esi + ETH_FRAME.DstMAC] push dword [esi + ETH_header.DstMAC]
push dword [esi + ETH_FRAME.SrcMAC] push dword [esi + ETH_header.SrcMAC]
pop dword [esi + ETH_FRAME.DstMAC] pop dword [esi + ETH_header.DstMAC]
pop dword [esi + ETH_FRAME.SrcMAC] pop dword [esi + ETH_header.SrcMAC]
push word [esi + ETH_FRAME.DstMAC + 4] push word [esi + ETH_header.DstMAC + 4]
push word [esi + ETH_FRAME.SrcMAC + 4] push word [esi + ETH_header.SrcMAC + 4]
pop word [esi + ETH_FRAME.DstMAC + 4] pop word [esi + ETH_header.DstMAC + 4]
pop word [esi + ETH_FRAME.SrcMAC + 4] pop word [esi + ETH_header.SrcMAC + 4]
add esi, ETH_FRAME.Data add esi, sizeof.ETH_header
push [esi + IPv4_Packet.SourceAddress] push [esi + IPv4_header.SourceAddress]
push [esi + IPv4_Packet.DestinationAddress] push [esi + IPv4_header.DestinationAddress]
pop [esi + IPv4_Packet.SourceAddress] pop [esi + IPv4_header.SourceAddress]
pop [esi + IPv4_Packet.DestinationAddress] pop [esi + IPv4_header.DestinationAddress]
; Recalculate ip header checksum ; 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 and ecx, 0x0f
shl cx, 2 shl cx, 2
mov edi, ecx ; IP header length mov edi, ecx ; IP header length
@ -203,10 +204,10 @@ ICMP_input:
call checksum_1 ; call checksum_1 ;
call checksum_2 ; call checksum_2 ;
pop esi ; pop esi ;
mov [esi + IPv4_Packet.HeaderChecksum], dx ; mov [esi + IPv4_header.HeaderChecksum], dx ;
; Recalculate ICMP CheckSum ; 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 ; xchg ch, cl ;
sub ecx, edi ; IP packet length - IP header length = ICMP packet length sub ecx, edi ; IP packet length - IP header length = ICMP packet length
@ -214,7 +215,7 @@ ICMP_input:
xor edx, edx ; xor edx, edx ;
call checksum_1 ; call checksum_1 ;
call checksum_2 ; 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!) ; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!)
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
@ -229,7 +230,7 @@ ICMP_input:
mov ebx, net_sockets mov ebx, net_sockets
.try_more: .try_more:
; mov ax , [edx + ICMP_Packet.Identifier] ; mov ax , [edx + ICMP_header.Identifier]
.next_socket: .next_socket:
mov ebx, [ebx + SOCKET.NextPtr] mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx or ebx, ebx
@ -297,7 +298,7 @@ ICMP_output:
mov ebx, [eax + IP_SOCKET.LocalIP] mov ebx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP] 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 mov di , IP_PROTO_ICMP SHL 8 + 128 ; TTL
shr edx, 16 shr edx, 16
@ -307,23 +308,23 @@ ICMP_output:
DEBUGF 1,"full icmp packet size: %u\n", edx DEBUGF 1,"full icmp packet size: %u\n", edx
pop eax 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 pop eax
mov [edi + ICMP_Packet.SequenceNumber], ax mov [edi + ICMP_header.SequenceNumber], ax
shr eax, 16 shr eax, 16
mov [edi + ICMP_Packet.Identifier], ax mov [edi + ICMP_header.Identifier], ax
mov [edi + ICMP_Packet.Checksum], 0 mov [edi + ICMP_header.Checksum], 0
push eax ebx ecx edx push eax ebx ecx edx
mov esi, edi mov esi, edi
xor edx, edx xor edx, edx
call checksum_1 call checksum_1
call checksum_2 call checksum_2
mov [edi + ICMP_Packet.Checksum], dx mov [edi + ICMP_header.Checksum], dx
pop edx ecx ebx eax esi pop edx ecx ebx eax esi
sub ecx, ICMP_Packet.Data sub ecx, sizeof.ICMP_header
add edi, ICMP_Packet.Data add edi, sizeof.ICMP_header
push cx push cx
shr cx , 2 shr cx , 2
rep movsd rep movsd
@ -376,13 +377,13 @@ ICMP_output_raw:
rep movsb rep movsb
pop ecx edi pop ecx edi
mov [edi + ICMP_Packet.Checksum], 0 mov [edi + ICMP_header.Checksum], 0
mov esi, edi mov esi, edi
xor edx, edx xor edx, edx
call checksum_1 call checksum_1
call checksum_2 call checksum_2
mov [edi + ICMP_Packet.Checksum], dx mov [edi + ICMP_header.Checksum], dx
DEBUGF 1,"Sending ICMP Packet\n" DEBUGF 1,"Sending ICMP Packet\n"
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]

View File

@ -24,10 +24,11 @@ $Revision$
struct queue struct queue
.size dd ? ; number of queued packets in this queue
.w_ptr dd ? ; current writing pointer in queue size dd ? ; number of queued packets in this queue
.r_ptr dd ? ; current reading pointer w_ptr dd ? ; current writing pointer in queue
.data: r_ptr dd ? ; current reading pointer
ends ends
; The following macros share these inputs: ; 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 mov ecx, entry_size/4 ; Write the queue entry
rep movsd ; rep movsd ;
lea ecx, [size*entry_size+ptr+queue.data] lea ecx, [size*entry_size+ptr+sizeof.queue]
cmp edi, ecx ; entry size cmp edi, ecx ; entry size
jb .no_wrap jb .no_wrap
@ -77,7 +78,7 @@ macro get_from_queue ptr, size, entry_size, failaddr {
add esi, entry_size 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 cmp esi, ecx ; entry size
jb .no_wrap jb .no_wrap
@ -93,7 +94,7 @@ macro get_from_queue ptr, size, entry_size, failaddr {
macro init_queue ptr { macro init_queue ptr {
mov [ptr + queue.size] , 0 mov [ptr + queue.size] , 0
lea edi, [ptr + queue.data] lea edi, [ptr + sizeof.queue]
mov [ptr + queue.w_ptr], edi mov [ptr + queue.w_ptr], edi
mov [ptr + queue.r_ptr], edi mov [ptr + queue.r_ptr], edi
} }

View File

@ -16,174 +16,155 @@
$Revision$ $Revision$
virtual at 0 struct SOCKET
SOCKET: NextPtr dd ? ; pointer to next socket in list
.NextPtr dd ? ; pointer to next socket in list PrevPtr dd ? ; pointer to previous socket in list
.PrevPtr dd ? ; pointer to previous socket in list Number dd ? ; socket number
.Number dd ? ; socket number
.lock dd ? ; lock mutex lock dd ? ; lock mutex
.PID dd ? ; application process id PID dd ? ; application process id
.Domain dd ? ; INET/UNIX/.. Domain dd ? ; INET/UNIX/..
.Type dd ? ; RAW/STREAM/DGRAP Type dd ? ; RAW/STREAM/DGRAP
.Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP
.errorcode dd ? errorcode dd ?
.options dd ? options dd ?
.state dd ? state dd ?
.backlog dw ? ; how many incomming connections that can be queued backlog dw ? ; how many incomming connections that can be queued
.snd_proc dd ? snd_proc dd ?
.rcv_proc dd ? rcv_proc dd ?
.end: ends
end virtual
virtual at SOCKET.end struct IP_SOCKET SOCKET
IP_SOCKET: LocalIP rd 4
.LocalIP rd 4 RemoteIP rd 4
.RemoteIP rd 4
.end: ends
end virtual
virtual at IP_SOCKET.end struct TCP_SOCKET IP_SOCKET
TCP_SOCKET: LocalPort dw ?
RemotePort dw ?
.LocalPort dw ? t_state dd ? ; TCB state
.RemotePort dw ? t_rxtshift dd ?
t_rxtcur dd ?
.t_state dd ? ; TCB state t_dupacks dd ?
.t_rxtshift dd ? t_maxseg dd ?
.t_rxtcur dd ? t_force dd ?
.t_dupacks dd ? t_flags dd ?
.t_maxseg dd ?
.t_force dd ?
.t_flags dd ?
;--------------- ;---------------
; RFC783 page 21 ; RFC783 page 21
; send sequence ; send sequence
.SND_UNA dd ? ; sequence number of unack'ed sent Packets SND_UNA dd ? ; sequence number of unack'ed sent Packets
.SND_NXT dd ? ; next send sequence number to use SND_NXT dd ? ; next send sequence number to use
.SND_UP dd ? SND_UP dd ?
.SND_WL1 dd ? ; window minus one SND_WL1 dd ? ; window minus one
.SND_WL2 dd ? ; SND_WL2 dd ? ;
.ISS dd ? ; initial send sequence number ISS dd ? ; initial send sequence number
.SND_WND dd ? ; send window SND_WND dd ? ; send window
; receive sequence ; receive sequence
.RCV_WND dw ? ; receive window RCV_WND dw ? ; receive window
.RCV_NXT dd ? ; next receive sequence number to use RCV_NXT dd ? ; next receive sequence number to use
.RCV_UP dd ? RCV_UP dd ?
.IRS dd ? ; initial receive sequence number IRS dd ? ; initial receive sequence number
;--------------------- ;---------------------
; Additional variables ; Additional variables
; receive variables ; receive variables
.RCV_ADV dd ? RCV_ADV dd ?
; retransmit variables ; retransmit variables
.SND_MAX dd ? SND_MAX dd ?
; congestion control ; congestion control
.SND_CWND dd ? SND_CWND dd ?
.SND_SSTHRESH dd ? SND_SSTHRESH dd ?
;---------------------- ;----------------------
; Transmit timing stuff ; Transmit timing stuff
.t_idle dd ? t_idle dd ?
.t_rtt dd ? t_rtt dd ?
.t_rtseq dd ? t_rtseq dd ?
.t_srtt dd ? t_srtt dd ?
.t_rttvar dd ? t_rttvar dd ?
.t_rttmin dd ? t_rttmin dd ?
.max_sndwnd dd ? max_sndwnd dd ?
;----------------- ;-----------------
; Out-of-band data ; Out-of-band data
.t_oobflags dd ? t_oobflags dd ?
.t_iobc dd ? t_iobc dd ?
.t_softerror dd ? t_softerror dd ?
;--------- ;---------
; RFC 1323 ; RFC 1323
.SND_SCALE db ? ; Scale factor SND_SCALE db ? ; Scale factor
.RCV_SCALE db ? RCV_SCALE db ?
.request_r_scale db ? request_r_scale db ?
.requested_s_scale dd ? requested_s_scale dd ?
.ts_recent dd ? ts_recent dd ?
.ts_recent_age dd ? ts_recent_age dd ?
.last_ack_sent dd ? last_ack_sent dd ?
;------- ;-------
; Timers ; Timers
.timer_retransmission dw ? ; rexmt timer_retransmission dw ? ; rexmt
.timer_persist dw ? timer_persist dw ?
.timer_keepalive dw ? ; keepalive/syn timeout timer_keepalive dw ? ; keepalive/syn timeout
.timer_timed_wait dw ? ; also used as 2msl timer timer_timed_wait dw ? ; also used as 2msl timer
.end: ends
end virtual
virtual at IP_SOCKET.end struct UDP_SOCKET IP_SOCKET
UDP_SOCKET: LocalPort dw ?
RemotePort dw ?
firstpacket db ?
.LocalPort dw ? ends
.RemotePort dw ?
.firstpacket db ?
.end:
end virtual
virtual at IP_SOCKET.end struct ICMP_SOCKET
ICMP_SOCKET: Identifier dw ?
.Identifier dw ? ends
.end:
end virtual
struc RING_BUFFER { struct RING_BUFFER
.start_ptr dd ? ; Pointer to start of buffer start_ptr dd ? ; Pointer to start of buffer
.end_ptr dd ? ; pointer to end of buffer end_ptr dd ? ; pointer to end of buffer
.read_ptr dd ? ; Read pointer read_ptr dd ? ; Read pointer
.write_ptr dd ? ; Write pointer write_ptr dd ? ; Write pointer
.size dd ? ; Number of bytes buffered size dd ? ; Number of bytes buffered
.end: 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
STREAM_SOCKET:
.rcv rd RING_BUFFER.end/4
.snd rd RING_BUFFER.end/4
.end:
end virtual
struct socket_queue_entry struct socket_queue_entry
.data_ptr dd ?
.buf_ptr dd ? data_ptr dd ?
.data_size dd ? buf_ptr dd ?
.size: data_size dd ?
ends ends
@ -191,7 +172,7 @@ SOCKETBUFFSIZE equ 4096 ; in bytes
SOCKET_QUEUE_SIZE equ 10 ; maximum number ofincoming packets queued for 1 socket 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 ; 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 uglobal
net_sockets rd 4 net_sockets rd 4
@ -714,7 +695,7 @@ SOCKET_receive_dgram:
mov ebx, esi mov ebx, esi
mov edi, edx ; addr to buffer 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] mov ecx, [esi + socket_queue_entry.data_size]
DEBUGF 1,"Got %u bytes of data\n", ecx DEBUGF 1,"Got %u bytes of data\n", ecx
@ -1062,10 +1043,10 @@ SOCKET_input:
push esi push esi
mov esi, esp 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" 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 mov [eax + SOCKET.lock], 0
jmp SOCKET_notify_owner jmp SOCKET_notify_owner

View File

@ -105,28 +105,24 @@ ECONNABORTED equ 53
virtual at 0 struct NET_DEVICE
NET_DEVICE: type dd ? ; Type field
mtu dd ? ; Maximal Transmission Unit
name dd ? ; Ptr to 0 terminated string
.type dd ? ; Type field unload dd ? ; Ptrs to driver functions
.mtu dd ? ; Maximal Transmission Unit reset dd ? ;
.name dd ? ; Ptr to 0 terminated string transmit dd ? ;
.unload dd ? ; Ptrs to driver functions bytes_tx dq ? ; Statistics, updated by the driver
.reset dd ? ; bytes_rx dq ? ;
.transmit dd ? ; packets_tx dd ? ;
packets_rx dd ? ;
.bytes_tx dq ? ; Statistics, updated by the driver ; hwacc dd ? ; bitmask stating available hardware accelerations (offload engines)
.bytes_rx dq ? ;
.packets_tx dd ? ;
.packets_rx dd ? ;
; .hwacc dd ? ; bitmask stating available hardware accelerations (offload engines) ends
.end:
end virtual
; Exactly as it says.. ; Exactly as it says..
@ -684,7 +680,7 @@ sys_protocols:
mov esi, ebx mov esi, ebx
and esi, 0x0000ff00 and esi, 0x0000ff00
shr esi, 6 ; now we have the device num * 4 in esi 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 je .doesnt_exist
push .return ; return address (we will be using jumps instead of calls) push .return ; return address (we will be using jumps instead of calls)

View File

@ -77,23 +77,24 @@ TCP_max_win equ 65535
TCP_re_xmit_thresh equ 3 TCP_re_xmit_thresh equ 3
struct TCP_segment struct TCP_header
.SourcePort dw ?
.DestinationPort dw ? SourcePort dw ?
.SequenceNumber dd ? DestinationPort dw ?
.AckNumber dd ? SequenceNumber dd ?
.DataOffset db ? ; DataOffset[0-3 bits] and Reserved[4-7] AckNumber dd ?
.Flags db ? ; Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN DataOffset db ? ; DataOffset[0-3 bits] and Reserved[4-7]
.Window dw ? Flags db ? ; Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN
.Checksum dw ? Window dw ?
.UrgentPointer dw ? Checksum dw ?
.Data: ; ..or options UrgentPointer dw ?
ends ends
align 4 align 4
uglobal uglobal
TCP_segments_tx rd IP_MAX_INTERFACES TCP_headers_tx rd IP_MAX_INTERFACES
TCP_segments_rx rd IP_MAX_INTERFACES TCP_headers_rx rd IP_MAX_INTERFACES
TCP_bytes_rx rq IP_MAX_INTERFACES TCP_bytes_rx rq IP_MAX_INTERFACES
TCP_bytes_tx rq IP_MAX_INTERFACES TCP_bytes_tx rq IP_MAX_INTERFACES
TCP_sequence_num dd ? TCP_sequence_num dd ?
@ -110,7 +111,7 @@ endg
macro TCP_init { macro TCP_init {
xor eax, eax xor eax, eax
mov edi, TCP_segments_tx mov edi, TCP_headers_tx
mov ecx, (6*IP_MAX_INTERFACES) mov ecx, (6*IP_MAX_INTERFACES)
rep stosd rep stosd
@ -155,11 +156,11 @@ TCP_API:
ret ret
.packets_tx: .packets_tx:
add eax, TCP_segments_tx add eax, TCP_headers_tx
mov eax, [eax] mov eax, [eax]
ret ret
.packets_rx: .packets_rx:
add eax, TCP_segments_rx add eax, TCP_headers_rx
mov eax, [eax] mov eax, [eax]
ret ret

View File

@ -39,21 +39,21 @@ TCP_input:
DEBUGF 1,"TCP_input size=%u ", ecx 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. ; 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 and eax, 0xf0
shr al, 2 shr al, 2
DEBUGF 1,"headersize=%u\n", eax DEBUGF 1,"headersize=%u\n", eax
cmp eax, TCP_segment.DataOffset cmp eax, TCP_header.DataOffset
jb .drop_not_locked jb .drop_not_locked
;------------------------------- ;-------------------------------
; Now, re-calculate the checksum ; Now, re-calculate the checksum
push eax ecx edx push eax ecx edx
pushw [edx + TCP_segment.Checksum] pushw [edx + TCP_header.Checksum]
mov [edx + TCP_segment.Checksum], 0 mov [edx + TCP_header.Checksum], 0
push esi edi push esi edi
mov esi, edx mov esi, edx
TCP_checksum (esp), (esp+4) 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) ; 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 jb .no_timestamp
je .is_ok 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 jne .no_timestamp
.is_ok: .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 jnz .no_timestamp
cmp dword [edx + TCP_segment.Data], 0x0101080a ; Timestamp header cmp dword [edx + sizeof.TCP_header], 0x0101080a ; Timestamp header
jne .no_timestamp jne .no_timestamp
DEBUGF 1,"timestamp ok\n" DEBUGF 1,"timestamp ok\n"
@ -96,13 +96,13 @@ TCP_input:
;------------------------------------------- ;-------------------------------------------
; Convert Big-endian values to little endian ; Convert Big-endian values to little endian
ntohd [edx + TCP_segment.SequenceNumber] ntohd [edx + TCP_header.SequenceNumber]
ntohd [edx + TCP_segment.AckNumber] ntohd [edx + TCP_header.AckNumber]
ntohw [edx + TCP_segment.Window] ntohw [edx + TCP_header.Window]
ntohw [edx + TCP_segment.UrgentPointer] ntohw [edx + TCP_header.UrgentPointer]
ntohw [edx + TCP_segment.SourcePort] ntohw [edx + TCP_header.SourcePort]
ntohw [edx + TCP_segment.DestinationPort] ntohw [edx + TCP_header.DestinationPort]
;------------------------------------------------------------ ;------------------------------------------------------------
; Next thing to do is find the TCPS (thus, the socket pointer) ; 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 cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP
jne .socket_loop jne .socket_loop
mov ax, [edx + TCP_segment.DestinationPort] mov ax, [edx + TCP_header.DestinationPort]
cmp [ebx + TCP_SOCKET.LocalPort], ax cmp [ebx + TCP_SOCKET.LocalPort], ax
jne .socket_loop jne .socket_loop
@ -136,7 +136,7 @@ TCP_input:
@@: @@:
mov ax, [ebx + TCP_SOCKET.RemotePort] mov ax, [ebx + TCP_SOCKET.RemotePort]
cmp [edx + TCP_segment.SourcePort] , ax cmp [edx + TCP_header.SourcePort] , ax
je .found_socket je .found_socket
test ax, ax test ax, ax
jnz .socket_loop jnz .socket_loop
@ -168,11 +168,11 @@ TCP_input:
;--------------------------------------- ;---------------------------------------
; unscale the window into a 32 bit value ; unscale the window into a 32 bit value
movzx eax, [edx + TCP_segment.Window] movzx eax, [edx + TCP_header.Window]
push ecx push ecx
mov cl, [ebx + TCP_SOCKET.SND_SCALE] mov cl, [ebx + TCP_SOCKET.SND_SCALE]
shl eax, cl 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 pop ecx
;----------------------------------- ;-----------------------------------
@ -189,10 +189,10 @@ TCP_input:
test eax, eax test eax, eax
jz .drop 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] pop [eax + IP_SOCKET.LocalIP]
push [edx + TCP_segment.DestinationPort] push [edx + TCP_header.DestinationPort]
pop [eax + TCP_SOCKET.LocalPort] pop [eax + TCP_SOCKET.LocalPort]
mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN
@ -213,7 +213,7 @@ TCP_input:
;-------------------- ;--------------------
; Process TCP options ; Process TCP options
cmp esi, TCP_segment.DataOffset ; esi is headersize cmp esi, TCP_header.DataOffset ; esi is headersize
je .no_options je .no_options
DEBUGF 1,"Segment has options\n" 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 cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state
jz .not_uni_xfer ; also no header prediction jz .not_uni_xfer ; also no header prediction
lea edi, [edx + TCP_segment.Data] lea edi, [edx + sizeof.TCP_header]
lea eax, [edx + esi] lea eax, [edx + esi]
.opt_loop: .opt_loop:
@ -253,7 +253,7 @@ TCP_input:
cmp byte [edi+1], 4 cmp byte [edi+1], 4
jne .no_options ; error occured, ignore all options! jne .no_options ; error occured, ignore all options!
test [edx + TCP_segment.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jz @f jz @f
movzx eax, word[edi+2] movzx eax, word[edi+2]
@ -271,7 +271,7 @@ TCP_input:
cmp byte [edi+1], 3 cmp byte [edi+1], 3
jne .no_options jne .no_options
test [edx + TCP_segment.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jz @f jz @f
DEBUGF 1,"Got window option\n" DEBUGF 1,"Got window option\n"
@ -318,17 +318,17 @@ TCP_input:
cmp [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED cmp [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED
jnz .not_uni_xfer 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 jnz .not_uni_xfer
test [edx + TCP_segment.Flags], TH_ACK test [edx + TCP_header.Flags], TH_ACK
jz .not_uni_xfer jz .not_uni_xfer
mov eax, [edx + TCP_segment.SequenceNumber] mov eax, [edx + TCP_header.SequenceNumber]
cmp eax, [ebx + TCP_SOCKET.RCV_NXT] cmp eax, [ebx + TCP_SOCKET.RCV_NXT]
jne .not_uni_xfer 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] cmp eax, [ebx + TCP_SOCKET.SND_WND]
jne .not_uni_xfer jne .not_uni_xfer
@ -352,7 +352,7 @@ TCP_input:
jb .not_uni_xfer jb .not_uni_xfer
; - The acknowledgment field in the segment is less than or equal to the maximum sequence number sent. ; - 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] cmp eax, [ebx + TCP_SOCKET.SND_MAX]
ja .not_uni_xfer ja .not_uni_xfer
@ -377,7 +377,7 @@ TCP_input:
popa popa
; update window pointers ; update window pointers
mov eax, [edx + TCP_segment.AckNumber] mov eax, [edx + TCP_header.AckNumber]
mov [ebx + TCP_SOCKET.SND_UNA], eax mov [ebx + TCP_SOCKET.SND_UNA], eax
; Stop retransmit timer ; 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 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. ; - 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] cmp eax, [ebx + TCP_SOCKET.SND_UNA]
jne .not_uni_xfer jne .not_uni_xfer
@ -441,7 +441,15 @@ TCP_input:
; Calculate receive window size ; 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 cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN
je .LISTEN je .LISTEN
@ -461,24 +469,24 @@ align 4
DEBUGF 1,"TCP state: listen\n" 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 jnz .drop
test [edx + TCP_segment.Flags], TH_ACK test [edx + TCP_header.Flags], TH_ACK
jnz .drop_with_reset jnz .drop_with_reset
test [edx + TCP_segment.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jz .drop jz .drop
;;; TODO: check if it's a broadcast or multicast, and drop if so ;;; 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] pop [ebx + IP_SOCKET.RemoteIP]
push [edx + TCP_segment.SourcePort] push [edx + TCP_header.SourcePort]
pop [ebx + TCP_SOCKET.RemotePort] pop [ebx + TCP_SOCKET.RemotePort]
push [edx + TCP_segment.SequenceNumber] push [edx + TCP_header.SequenceNumber]
pop [ebx + TCP_SOCKET.IRS] pop [ebx + TCP_SOCKET.IRS]
push [TCP_sequence_num] ;;;;; push [TCP_sequence_num] ;;;;;
@ -522,10 +530,10 @@ align 4
DEBUGF 1,"TCP state: syn_sent\n" DEBUGF 1,"TCP state: syn_sent\n"
test [edx + TCP_segment.Flags], TH_ACK test [edx + TCP_header.Flags], TH_ACK
jz @f jz @f
mov eax, [edx + TCP_segment.AckNumber] mov eax, [edx + TCP_header.AckNumber]
cmp eax, [ebx + TCP_SOCKET.ISS] cmp eax, [ebx + TCP_SOCKET.ISS]
jbe .drop_with_reset jbe .drop_with_reset
@ -533,10 +541,10 @@ align 4
ja .drop_with_reset ja .drop_with_reset
@@: @@:
test [edx + TCP_segment.Flags], TH_RST test [edx + TCP_header.Flags], TH_RST
jz @f jz @f
test [edx + TCP_segment.Flags], TH_ACK test [edx + TCP_header.Flags], TH_ACK
jz .drop jz .drop
mov eax, ebx mov eax, ebx
@ -546,17 +554,17 @@ align 4
jmp .drop jmp .drop
@@: @@:
test [edx + TCP_segment.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jz .drop jz .drop
; at this point, segment seems to be valid ; 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 jz .no_syn_ack
; now, process received SYN in response to an active open ; 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 mov [ebx + TCP_SOCKET.SND_UNA], eax
cmp eax, [ebx + TCP_SOCKET.SND_NXT] cmp eax, [ebx + TCP_SOCKET.SND_NXT]
jbe @f jbe @f
@ -567,7 +575,7 @@ align 4
mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; disable retransmission mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; disable retransmission
push [edx + TCP_segment.SequenceNumber] push [edx + TCP_header.SequenceNumber]
pop [ebx + TCP_SOCKET.IRS] pop [ebx + TCP_SOCKET.IRS]
TCP_rcvseqinit ebx TCP_rcvseqinit ebx
@ -578,7 +586,7 @@ align 4
cmp eax, [ebx + TCP_SOCKET.ISS] cmp eax, [ebx + TCP_SOCKET.ISS]
jbe .simultaneous_open jbe .simultaneous_open
test [edx + TCP_segment.Flags], TH_ACK test [edx + TCP_header.Flags], TH_ACK
jz .simultaneous_open jz .simultaneous_open
DEBUGF 1,"TCP: active open\n" DEBUGF 1,"TCP: active open\n"
@ -613,11 +621,11 @@ align 4
.trim_then_step6: .trim_then_step6:
inc [edx + TCP_segment.SequenceNumber] inc [edx + TCP_header.SequenceNumber]
;;; TODO: Drop any received data that follows receive window (590) ;;; 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 mov [ebx + TCP_SOCKET.RCV_UP], eax
dec eax dec eax
mov [ebx + TCP_SOCKET.SND_WL1], eax mov [ebx + TCP_SOCKET.SND_WL1], eax
@ -659,25 +667,25 @@ align 4
; check for duplicate data at beginning of segment ; check for duplicate data at beginning of segment
mov eax, [ebx + TCP_SOCKET.RCV_NXT] mov eax, [ebx + TCP_SOCKET.RCV_NXT]
sub eax, [edx + TCP_segment.SequenceNumber] sub eax, [edx + TCP_header.SequenceNumber]
jbe .no_duplicate jbe .no_duplicate
DEBUGF 1,"Uh oh.. %u bytes of duplicate data!\n", eax DEBUGF 1,"Uh oh.. %u bytes of duplicate data!\n", eax
test [edx + TCP_segment.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jz .no_dup_syn jz .no_dup_syn
; remove duplicate syn ; remove duplicate syn
and [edx + TCP_segment.Flags], not (TH_SYN) and [edx + TCP_header.Flags], not (TH_SYN)
inc [edx + TCP_segment.SequenceNumber] inc [edx + TCP_header.SequenceNumber]
cmp [edx + TCP_segment.UrgentPointer], 1 cmp [edx + TCP_header.UrgentPointer], 1
jbe @f jbe @f
dec [edx + TCP_segment.UrgentPointer] dec [edx + TCP_header.UrgentPointer]
jmp .dup_syn jmp .dup_syn
@@: @@:
and [edx + TCP_segment.Flags], not (TH_URG) and [edx + TCP_header.Flags], not (TH_URG)
.dup_syn: .dup_syn:
dec eax dec eax
.no_dup_syn: .no_dup_syn:
@ -695,7 +703,7 @@ align 4
; Check for duplicate FIN ; Check for duplicate FIN
test [edx + TCP_segment.Flags], TH_FIN test [edx + TCP_header.Flags], TH_FIN
jz @f jz @f
inc ecx inc ecx
cmp eax, ecx cmp eax, ecx
@ -703,7 +711,7 @@ align 4
jne @f jne @f
mov eax, ecx 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 or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
jmp .no_duplicate jmp .no_duplicate
@@: @@:
@ -719,7 +727,7 @@ align 4
test eax, eax test eax, eax
jnz .drop_after_ack jnz .drop_after_ack
cmp [edx + TCP_segment.Flags], TH_ACK cmp [edx + TCP_header.Flags], TH_ACK
jz .drop_after_ack jz .drop_after_ack
.duplicate: .duplicate:
@ -738,15 +746,15 @@ align 4
;----------------------------------------------- ;-----------------------------------------------
; Remove duplicate data and update urgent offset ; Remove duplicate data and update urgent offset
add [edx + TCP_segment.SequenceNumber], eax add [edx + TCP_header.SequenceNumber], eax
;;; TODO ;;; TODO
sub [edx + TCP_segment.UrgentPointer], ax sub [edx + TCP_header.UrgentPointer], ax
ja @f ja @f
and [edx + TCP_segment.Flags], not (TH_URG) and [edx + TCP_header.Flags], not (TH_URG)
mov [edx + TCP_segment.UrgentPointer], 0 mov [edx + TCP_header.UrgentPointer], 0
@@: @@:
;-------------------------------------------------- ;--------------------------------------------------
@ -770,7 +778,7 @@ align 4
;---------------------------------------- ;----------------------------------------
; Remove data beyond right edge of window ; Remove data beyond right edge of window
mov eax, [edx + TCP_segment.SequenceNumber] mov eax, [edx + TCP_header.SequenceNumber]
add eax, ecx add eax, ecx
sub eax, [ebx + TCP_SOCKET.RCV_NXT] sub eax, [ebx + TCP_SOCKET.RCV_NXT]
sub ax, [ebx + TCP_SOCKET.RCV_WND] sub ax, [ebx + TCP_SOCKET.RCV_WND]
@ -809,7 +817,7 @@ align 4
;------------------ ;------------------
; Process RST flags ; Process RST flags
test [edx + TCP_segment.Flags], TH_RST test [edx + TCP_header.Flags], TH_RST
jz .rst_skip jz .rst_skip
DEBUGF 1,"Got an RST flag" DEBUGF 1,"Got an RST flag"
@ -870,7 +878,7 @@ align 4
;-------------------------------------- ;--------------------------------------
; handle SYN-full and ACK-less segments ; handle SYN-full and ACK-less segments
test [edx + TCP_segment.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jz @f jz @f
mov eax, ebx mov eax, ebx
@ -878,7 +886,7 @@ align 4
call TCP_drop call TCP_drop
jmp .drop_with_reset jmp .drop_with_reset
test [edx + TCP_segment.Flags], TH_ACK test [edx + TCP_header.Flags], TH_ACK
jz .drop jz .drop
@@: @@:
@ -896,7 +904,7 @@ align 4
DEBUGF 1,"TCP state = syn received\n" 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 cmp [ebx + TCP_SOCKET.SND_UNA], eax
ja .drop_with_reset ja .drop_with_reset
cmp eax, [ebx + TCP_SOCKET.SND_MAX] cmp eax, [ebx + TCP_SOCKET.SND_MAX]
@ -920,7 +928,7 @@ align 4
;;; 813 ? ;;; 813 ?
mov eax, [edx + TCP_segment.SequenceNumber] mov eax, [edx + TCP_header.SequenceNumber]
dec eax dec eax
mov [ebx + TCP_SOCKET.SND_WL1], eax mov [ebx + TCP_SOCKET.SND_WL1], eax
jmp .not_dup_ack jmp .not_dup_ack
@ -929,14 +937,14 @@ align 4
; check for duplicate ACK ; check for duplicate ACK
mov eax, [edx + TCP_segment.AckNumber] mov eax, [edx + TCP_header.AckNumber]
cmp eax, [ebx + TCP_SOCKET.SND_UNA] cmp eax, [ebx + TCP_SOCKET.SND_UNA]
ja .not_dup_ack ja .not_dup_ack
test ecx, ecx test ecx, ecx
jnz .reset_dupacks jnz .reset_dupacks
mov eax, dword [edx + TCP_segment.Window] mov eax, dword [edx + TCP_header.Window]
cmp eax, [ebx + TCP_SOCKET.SND_WND] cmp eax, [ebx + TCP_SOCKET.SND_WND]
jne .reset_dupacks jne .reset_dupacks
@ -945,7 +953,7 @@ align 4
cmp [ebx + TCP_SOCKET.timer_retransmission], 10000 ;;;; cmp [ebx + TCP_SOCKET.timer_retransmission], 10000 ;;;;
ja @f ja @f
mov eax, [edx + TCP_segment.AckNumber] mov eax, [edx + TCP_header.AckNumber]
cmp eax, [ebx + TCP_SOCKET.SND_UNA] cmp eax, [ebx + TCP_SOCKET.SND_UNA]
je .dup_ack je .dup_ack
@ -977,7 +985,7 @@ align 4
mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; turn off retransmission timer mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; turn off retransmission timer
mov [ebx + TCP_SOCKET.t_rtt], 0 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 [ebx + TCP_SOCKET.SND_NXT], eax
mov eax, [ebx + TCP_SOCKET.t_maxseg] mov eax, [ebx + TCP_SOCKET.t_maxseg]
mov [ebx + TCP_SOCKET.SND_CWND], eax mov [ebx + TCP_SOCKET.SND_CWND], eax
@ -1036,7 +1044,7 @@ align 4
mov [ebx + TCP_SOCKET.t_dupacks], 0 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] cmp eax, [ebx + TCP_SOCKET.SND_MAX]
jbe @f 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 sub edi, [ebx + TCP_SOCKET.SND_UNA] ; now we got the number of acked bytes in esi
;;; TODO: update stats ;;; TODO: update stats
@ -1066,7 +1074,7 @@ align 4
mov [ebx + TCP_SOCKET.timer_retransmission], 0 mov [ebx + TCP_SOCKET.timer_retransmission], 0
mov eax, [ebx + TCP_SOCKET.SND_MAX] mov eax, [ebx + TCP_SOCKET.SND_MAX]
cmp eax, [edx + TCP_segment.AckNumber] cmp eax, [edx + TCP_header.AckNumber]
je .all_outstanding je .all_outstanding
mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value (use a macro for it) mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value (use a macro for it)
.all_outstanding: .all_outstanding:
@ -1131,7 +1139,7 @@ align 4
; Update TCPS ; Update TCPS
mov eax, [edx + TCP_segment.AckNumber] mov eax, [edx + TCP_header.AckNumber]
mov [ebx + TCP_SOCKET.SND_UNA], eax mov [ebx + TCP_SOCKET.SND_UNA], eax
cmp eax, [ebx + TCP_SOCKET.SND_NXT] cmp eax, [ebx + TCP_SOCKET.SND_NXT]
@ -1221,25 +1229,25 @@ align 4
;---------------------------------------------- ;----------------------------------------------
; check if we need to update window information ; 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 jz .no_window_update
mov eax, [ebx + TCP_SOCKET.SND_WL1] mov eax, [ebx + TCP_SOCKET.SND_WL1]
cmp eax, [edx + TCP_segment.SequenceNumber] cmp eax, [edx + TCP_header.SequenceNumber]
jb .update_window jb .update_window
ja @f ja @f
mov eax, [ebx + TCP_SOCKET.SND_WL2] mov eax, [ebx + TCP_SOCKET.SND_WL2]
cmp eax, [edx + TCP_segment.AckNumber] cmp eax, [edx + TCP_header.AckNumber]
jb .update_window jb .update_window
ja .no_window_update ja .no_window_update
@@: @@:
mov eax, [ebx + TCP_SOCKET.SND_WL2] mov eax, [ebx + TCP_SOCKET.SND_WL2]
cmp eax, [edx + TCP_segment.AckNumber] cmp eax, [edx + TCP_header.AckNumber]
jne .no_window_update jne .no_window_update
movzx eax, [edx + TCP_segment.Window] movzx eax, [edx + TCP_header.Window]
cmp eax, [ebx + TCP_SOCKET.SND_WND] cmp eax, [ebx + TCP_SOCKET.SND_WND]
jbe .no_window_update jbe .no_window_update
@ -1253,7 +1261,7 @@ align 4
; jz @f ; jz @f
; ;
; mov eax, [ebx + TCP_SOCKET.SND_WL2] ; mov eax, [ebx + TCP_SOCKET.SND_WL2]
; cmp eax, [edx + TCP_segment.AckNumber] ; cmp eax, [edx + TCP_header.AckNumber]
; jne @f ; jne @f
; ;
; ;; mov eax, tiwin ; ;; 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] cmp eax, [ebx + TCP_SOCKET.max_sndwnd]
jbe @f jbe @f
mov [ebx + TCP_SOCKET.max_sndwnd], eax mov [ebx + TCP_SOCKET.max_sndwnd], eax
@@: @@:
mov [ebx + TCP_SOCKET.SND_WND], eax mov [ebx + TCP_SOCKET.SND_WND], eax
push [edx + TCP_segment.SequenceNumber] push [edx + TCP_header.SequenceNumber]
pop [ebx + TCP_SOCKET.SND_WL1] pop [ebx + TCP_SOCKET.SND_WL1]
push [edx + TCP_segment.AckNumber] push [edx + TCP_header.AckNumber]
pop [ebx + TCP_SOCKET.SND_WL2] pop [ebx + TCP_SOCKET.SND_WL2]
;;; needoutput = 1 ;;; needoutput = 1
@ -1290,10 +1298,10 @@ align 4
;----------------- ;-----------------
; process URG flag ; process URG flag
test [edx + TCP_segment.Flags], TH_URG test [edx + TCP_header.Flags], TH_URG
jz .not_urgent jz .not_urgent
cmp [edx + TCP_segment.UrgentPointer], 0 cmp [edx + TCP_header.UrgentPointer], 0
jz .not_urgent jz .not_urgent
cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
@ -1303,13 +1311,13 @@ align 4
;;; 1040-1050 ;;; 1040-1050
movzx eax, [edx + TCP_segment.UrgentPointer] movzx eax, [edx + TCP_header.UrgentPointer]
add eax, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.size] add eax, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.size]
cmp eax, SOCKET_MAXDATA cmp eax, SOCKET_MAXDATA
jbe .not_urgent jbe .not_urgent
mov [edx + TCP_segment.UrgentPointer], 0 mov [edx + TCP_header.UrgentPointer], 0
and [edx + TCP_segment.Flags], not (TH_URG) and [edx + TCP_header.Flags], not (TH_URG)
jmp .do_data jmp .do_data
.not_urgent: .not_urgent:
@ -1332,7 +1340,7 @@ align 4
DEBUGF 1,"TCP: do data (%u)\n", ecx 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 jnz .process_fin
cmp [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_1 cmp [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_1
@ -1345,7 +1353,7 @@ align 4
;; TODO: check if data is in sequence ! ;; 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 and eax, 0xf0
shr al, 2 shr al, 2
@ -1487,7 +1495,7 @@ align 4
DEBUGF 1,"Drop after ACK\n" DEBUGF 1,"Drop after ACK\n"
test [edx + TCP_segment.Flags], TH_RST test [edx + TCP_header.Flags], TH_RST
jnz .drop jnz .drop
and [ebx + TCP_SOCKET.t_flags], TF_ACKNOW and [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
@ -1524,15 +1532,15 @@ align 4
DEBUGF 1,"Drop with reset\n" DEBUGF 1,"Drop with reset\n"
test [edx + TCP_segment.Flags], TH_RST test [edx + TCP_header.Flags], TH_RST
jnz .drop jnz .drop
;;; if its a multicast/broadcast, also 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 jnz .respond_ack
test [edx + TCP_segment.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jnz .respond_syn jnz .respond_syn
call kernel_free call kernel_free

View File

@ -260,7 +260,7 @@ TCP_output:
DEBUGF 1,"Preparing to send a segment\n" 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 sub esp, 8 ; create some space on stack
push eax ; save socket pointer push eax ; save socket pointer
@ -435,10 +435,10 @@ TCP_output:
;---------------------------------- ;----------------------------------
; update sequence number and timers (400) ; 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 jz @f
inc [eax + TCP_SOCKET.SND_NXT] ; syn and fin take a sequence number 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 jz @f
or [eax + TCP_SOCKET.t_flags], TF_SENTFIN ; if we sent a fin, set the sentfin flag 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 DEBUGF 1,"checksum: ptr=%x size=%u\n", esi, ecx
TCP_checksum (eax + IP_SOCKET.LocalIP), (eax + IP_SOCKET.RemoteIP) TCP_checksum (eax + IP_SOCKET.LocalIP), (eax + IP_SOCKET.RemoteIP)
mov [esi+TCP_segment.Checksum], dx mov [esi + TCP_header.Checksum], dx
; unlock socket ; unlock socket

View File

@ -245,7 +245,7 @@ TCP_respond_socket:
push cx ebx push cx ebx
mov eax, [ebx + IP_SOCKET.RemoteIP] mov eax, [ebx + IP_SOCKET.RemoteIP]
mov ebx, [ebx + IP_SOCKET.LocalIP] mov ebx, [ebx + IP_SOCKET.LocalIP]
mov ecx, TCP_segment.Data mov ecx, sizeof.TCP_header
mov di , IP_PROTO_TCP shl 8 + 128 mov di , IP_PROTO_TCP shl 8 + 128
call IPv4_output call IPv4_output
test edi, edi test edi, edi
@ -268,7 +268,7 @@ TCP_respond_socket:
mov eax, [esi + TCP_SOCKET.RCV_NXT] mov eax, [esi + TCP_SOCKET.RCV_NXT]
bswap eax bswap eax
stosd stosd
mov al, 0x50 ; Dataoffset: 20 bytes (TCP_segment.DataOffset) mov al, 0x50 ; Dataoffset: 20 bytes (TCP_header.DataOffset)
stosb stosb
mov al, cl mov al, cl
stosb stosb
@ -283,11 +283,11 @@ TCP_respond_socket:
; Fill in the checksum ; Fill in the checksum
.checksum: .checksum:
sub edi, TCP_segment.Data sub edi, sizeof.TCP_header
mov ecx, TCP_segment.Data mov ecx, sizeof.TCP_header
xchg esi, edi xchg esi, edi
TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP) 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 ; And send the segment
@ -323,9 +323,9 @@ TCP_respond_segment:
; Create the IP packet ; Create the IP packet
push cx edx push cx edx
mov ebx, [edx - IPv4_Packet.DataOrOptional + IPv4_Packet.SourceAddress] ;;;; FIXME: and what if ip packet had options?! mov ebx, [edx - sizeof.IPv4_header + IPv4_header.SourceAddress] ;;;; FIXME: and what if ip packet had options?!
mov eax, [edx - IPv4_Packet.DataOrOptional + IPv4_Packet.DestinationAddress] ;;; mov eax, [edx - sizeof.IPv4_header + IPv4_header.DestinationAddress] ;;;
mov ecx, TCP_segment.Data mov ecx, sizeof.TCP_header
mov di , IP_PROTO_TCP shl 8 + 128 mov di , IP_PROTO_TCP shl 8 + 128
call IPv4_output call IPv4_output
jz .error jz .error
@ -336,18 +336,18 @@ TCP_respond_segment:
;--------------------------------------------------- ;---------------------------------------------------
; Fill in the TCP header by using a received 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 rol ax, 8
stosw stosw
mov ax, [esi + TCP_segment.SourcePort] mov ax, [esi + TCP_header.SourcePort]
rol ax, 8 rol ax, 8
stosw stosw
mov eax, [esi + TCP_segment.AckNumber] mov eax, [esi + TCP_header.AckNumber]
bswap eax bswap eax
stosd stosd
xor eax, eax xor eax, eax
stosd stosd
mov al, 0x50 ; Dataoffset: 20 bytes (TCP_segment.Data) mov al, 0x50 ; Dataoffset: 20 bytes (sizeof.TCP_header)
stosb stosb
mov al, cl mov al, cl
stosb stosb
@ -361,11 +361,11 @@ TCP_respond_segment:
; Fill in the checksum ; Fill in the checksum
.checksum: .checksum:
lea esi, [edi - TCP_segment.Data] lea esi, [edi - sizeof.TCP_header]
mov ecx, TCP_segment.Data mov ecx, sizeof.TCP_header
TCP_checksum (esi - IPv4_Packet.DataOrOptional + IPv4_Packet.DestinationAddress),\ ; FIXME TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\ ; FIXME
(esi - IPv4_Packet.DataOrOptional + IPv4_Packet.SourceAddress) (esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
mov [esi+TCP_segment.Checksum], dx mov [esi+TCP_header.Checksum], dx
;-------------------- ;--------------------
; And send the segment ; And send the segment

View File

@ -18,11 +18,11 @@ $Revision$
struct UDP_Packet struct UDP_Packet
.SourcePort dw ?
.DestinationPort dw ? SourcePort dw ?
.Length dw ? ; Length of (UDP Header + Data) DestinationPort dw ?
.Checksum dw ? Length dw ? ; Length of (UDP Header + Data)
.Data: Checksum dw ?
ends ends
@ -84,8 +84,8 @@ macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size, des
push esi push esi
movzx ecx, [esi+UDP_Packet.Length] movzx ecx, [esi+UDP_Packet.Length]
rol cx , 8 rol cx , 8
sub cx , UDP_Packet.Data sub cx , sizeof.UDP_Packet
add esi, UDP_Packet.Data add esi, sizeof.UDP_Packet
call checksum_1 call checksum_1
call checksum_2 call checksum_2
@ -183,10 +183,10 @@ UDP_input:
.updatesock: .updatesock:
inc [UDP_PACKETS_RX] inc [UDP_PACKETS_RX]
DEBUGF 1,"Found valid UDP packet for socket %x\n", eax 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] movzx ecx, [edx + UDP_Packet.Length]
rol cx , 8 rol cx , 8
sub cx , UDP_Packet.Data sub cx , sizeof.UDP_Packet
jmp SOCKET_input jmp SOCKET_input
@ -247,7 +247,7 @@ UDP_output:
mov di, IP_PROTO_UDP shl 8 + 128 mov di, IP_PROTO_UDP shl 8 + 128
sub esp, 8 ; Data ptr and data size will be placed here 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 ;;; TODO: fragment id
push edx esi push edx esi
@ -262,8 +262,8 @@ UDP_output:
pop esi pop esi
push edi ecx push edi ecx
sub ecx, UDP_Packet.Data sub ecx, sizeof.UDP_Packet
add edi, UDP_Packet.Data add edi, sizeof.UDP_Packet
shr ecx, 2 shr ecx, 2
rep movsd rep movsd
mov ecx, [esp] mov ecx, [esp]