forked from KolibriOS/kolibrios
More TCP code updates for net branch, code is still very unstable
git-svn-id: svn://kolibrios.org@1318 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
ddfdcfa285
commit
0e0b5fb665
@ -29,10 +29,10 @@ start:
|
|||||||
push 1
|
push 1
|
||||||
call [con_start]
|
call [con_start]
|
||||||
push title
|
push title
|
||||||
push -1
|
push 25
|
||||||
push -1
|
push 80
|
||||||
push -1
|
push 25
|
||||||
push -1
|
push 80
|
||||||
call [con_init]
|
call [con_init]
|
||||||
; main loop
|
; main loop
|
||||||
push str1
|
push str1
|
||||||
@ -102,7 +102,11 @@ main:
|
|||||||
mcall 40, 1 shl 7 ; + 7
|
mcall 40, 1 shl 7 ; + 7
|
||||||
call [con_cls]
|
call [con_cls]
|
||||||
|
|
||||||
|
mcall 18, 7
|
||||||
|
push eax
|
||||||
mcall 51, 1, thread, mem - 2048
|
mcall 51, 1, thread, mem - 2048
|
||||||
|
pop ecx
|
||||||
|
mcall 18, 3
|
||||||
|
|
||||||
mainloop:
|
mainloop:
|
||||||
mcall 10
|
mcall 10
|
||||||
@ -115,13 +119,25 @@ mainloop:
|
|||||||
mov byte [esi + eax], 0
|
mov byte [esi + eax], 0
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
cmp byte [esi], 0xff ; 'IAC' = Interpret As Command
|
cmp byte [esi], 0xff ; Interpret As Command
|
||||||
jne @f
|
jne @f
|
||||||
; TODO: parse options, for now, we will reply with 'WONT' to everything
|
; TODO: parse options, for now, we will reply with 'WONT' to everything
|
||||||
mov byte [esi + 1], 252 ; WONT
|
mov byte [esi + 1], 252 ; WONT
|
||||||
add esi, 3 ; a command is always 3 bytes
|
add esi, 3 ; a command is always 3 bytes
|
||||||
jmp @r
|
jmp @r
|
||||||
|
|
||||||
|
|
||||||
|
@@:
|
||||||
|
cmp byte [esi], 0x1b ; escape character
|
||||||
|
jne @f
|
||||||
|
cmp word [esi+1], 0x485b ; move cursor to beginning
|
||||||
|
jne @f
|
||||||
|
push 0
|
||||||
|
push 0
|
||||||
|
call [con_set_cursor_pos]
|
||||||
|
add esi, 3
|
||||||
|
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
push esi
|
push esi
|
||||||
|
|
||||||
@ -160,14 +176,15 @@ exit:
|
|||||||
|
|
||||||
thread:
|
thread:
|
||||||
mcall 40, 0
|
mcall 40, 0
|
||||||
|
.loop:
|
||||||
call [con_getch2]
|
call [con_getch2]
|
||||||
mov byte [send_data], al
|
mov byte [send_data], al
|
||||||
mcall send, [socketnum], send_data, 1
|
mcall send, [socketnum], send_data, 1
|
||||||
jmp thread
|
jmp .loop
|
||||||
|
|
||||||
; data
|
; data
|
||||||
title db 'Telnet',0
|
title db 'Telnet',0
|
||||||
str1 db 'Telnet v0.1',10,' for KolibriOS # 1250 or later. ',10,10,0
|
str1 db 'Telnet v0.1',10,' for KolibriOS # 1281 or later. ',10,10,'If you dont know where to connect to, try towel.blinkenlights.nl',10,10,0
|
||||||
str2 db '> ',0
|
str2 db '> ',0
|
||||||
str3 db 'Connecting to: ',0
|
str3 db 'Connecting to: ',0
|
||||||
str4 db 10,0
|
str4 db 10,0
|
||||||
@ -199,7 +216,8 @@ import console, \
|
|||||||
con_exit, 'con_exit', \
|
con_exit, 'con_exit', \
|
||||||
con_gets, 'con_gets',\
|
con_gets, 'con_gets',\
|
||||||
con_cls, 'con_cls',\
|
con_cls, 'con_cls',\
|
||||||
con_getch2, 'con_getch2'
|
con_getch2, 'con_getch2',\
|
||||||
|
con_set_cursor_pos, 'con_set_cursor_pos'
|
||||||
i_end:
|
i_end:
|
||||||
|
|
||||||
socketnum dd ?
|
socketnum dd ?
|
||||||
|
@ -17,39 +17,39 @@ PID_KERNEL equ 1 ;os_idle thread
|
|||||||
align 4
|
align 4
|
||||||
proc attach_int_handler stdcall, irq:dword, handler:dword, access_rights:dword
|
proc attach_int_handler stdcall, irq:dword, handler:dword, access_rights:dword
|
||||||
|
|
||||||
push ebx
|
push ebx
|
||||||
|
|
||||||
mov ebx, [irq] ;irq num
|
mov ebx, [irq] ;irq num
|
||||||
test ebx, ebx
|
test ebx, ebx
|
||||||
jz .err
|
jz .err
|
||||||
cmp ebx, 15 ; hidnplayr says: we only have 16 IRQ's
|
cmp ebx, 15 ; hidnplayr says: we only have 16 IRQ's
|
||||||
ja .err
|
ja .err
|
||||||
mov eax, [handler]
|
mov eax, [handler]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err
|
jz .err
|
||||||
cmp [irq_owner + 4 * ebx], 0
|
cmp [irq_owner + 4 * ebx], 0
|
||||||
je @f
|
je @f
|
||||||
|
|
||||||
mov ecx, [irq_rights + 4 * ebx] ; Rights : 0 - full access, 1 - read only, 2 - forbidden
|
mov ecx, [irq_rights + 4 * ebx] ; Rights : 0 - full access, 1 - read only, 2 - forbidden
|
||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
jnz .err
|
jnz .err
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
mov [irq_tab+ebx*4], eax
|
mov [irq_tab+ebx*4], eax
|
||||||
|
|
||||||
mov eax, [access_rights]
|
mov eax, [access_rights]
|
||||||
mov [irq_rights + 4 * ebx], eax
|
mov [irq_rights + 4 * ebx], eax
|
||||||
|
|
||||||
mov [irq_owner + 4 * ebx], PID_KERNEL ; all handlers belong to a kernel
|
mov [irq_owner + 4 * ebx], PID_KERNEL ; all handlers belong to a kernel
|
||||||
|
|
||||||
stdcall enable_irq, [irq]
|
stdcall enable_irq, [irq]
|
||||||
pop ebx
|
pop ebx
|
||||||
mov eax, 1
|
mov eax, 1
|
||||||
ret
|
ret
|
||||||
.err:
|
.err:
|
||||||
pop ebx
|
pop ebx
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
uglobal
|
uglobal
|
||||||
@ -121,8 +121,8 @@ align 4
|
|||||||
jmp .main
|
jmp .main
|
||||||
; align 4
|
; align 4
|
||||||
; .irq_6:
|
; .irq_6:
|
||||||
; push 6
|
; push 6
|
||||||
; jmp .main
|
; jmp .main
|
||||||
align 4
|
align 4
|
||||||
.irq_7:
|
.irq_7:
|
||||||
push 7
|
push 7
|
||||||
@ -149,16 +149,16 @@ align 4
|
|||||||
jmp .main
|
jmp .main
|
||||||
; align 4
|
; align 4
|
||||||
; .irq_13:
|
; .irq_13:
|
||||||
; push 13
|
; push 13
|
||||||
; jmp .main
|
; jmp .main
|
||||||
; align 4
|
; align 4
|
||||||
; .irq_14:
|
; .irq_14:
|
||||||
; push 14
|
; push 14
|
||||||
; jmp .main
|
; jmp .main
|
||||||
; align 4
|
; align 4
|
||||||
; .irq_15:
|
; .irq_15:
|
||||||
; push 15
|
; push 15
|
||||||
; jmp .main
|
; jmp .main
|
||||||
|
|
||||||
align 16
|
align 16
|
||||||
.main:
|
.main:
|
||||||
@ -212,7 +212,7 @@ endp
|
|||||||
|
|
||||||
align 4
|
align 4
|
||||||
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
|
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
|
||||||
push ebx
|
push ebx edx
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
mov ah, byte [bus]
|
mov ah, byte [bus]
|
||||||
@ -220,13 +220,13 @@ proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
|
|||||||
mov bh, byte [devfn]
|
mov bh, byte [devfn]
|
||||||
mov bl, byte [reg]
|
mov bl, byte [reg]
|
||||||
call pci_read_reg
|
call pci_read_reg
|
||||||
pop ebx
|
pop edx ebx
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
|
proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
|
||||||
push ebx
|
push ebx edx
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
mov ah, byte [bus]
|
mov ah, byte [bus]
|
||||||
@ -234,13 +234,13 @@ proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
|
|||||||
mov bh, byte [devfn]
|
mov bh, byte [devfn]
|
||||||
mov bl, byte [reg]
|
mov bl, byte [reg]
|
||||||
call pci_read_reg
|
call pci_read_reg
|
||||||
pop ebx
|
pop edx ebx
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
|
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
|
||||||
push ebx
|
push ebx edx
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
mov ah, byte [bus]
|
mov ah, byte [bus]
|
||||||
@ -248,13 +248,13 @@ proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
|
|||||||
mov bh, byte [devfn]
|
mov bh, byte [devfn]
|
||||||
mov bl, byte [reg]
|
mov bl, byte [reg]
|
||||||
call pci_read_reg
|
call pci_read_reg
|
||||||
pop ebx
|
pop edx ebx
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
|
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
|
||||||
push ebx
|
push ebx edx
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
mov ah, byte [bus]
|
mov ah, byte [bus]
|
||||||
@ -263,13 +263,13 @@ proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
|
|||||||
mov bl, byte [reg]
|
mov bl, byte [reg]
|
||||||
mov ecx, [val]
|
mov ecx, [val]
|
||||||
call pci_write_reg
|
call pci_write_reg
|
||||||
pop ebx
|
pop edx ebx
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
|
proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
|
||||||
push ebx
|
push ebx edx
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
mov ah, byte [bus]
|
mov ah, byte [bus]
|
||||||
@ -278,13 +278,13 @@ proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
|
|||||||
mov bl, byte [reg]
|
mov bl, byte [reg]
|
||||||
mov ecx, [val]
|
mov ecx, [val]
|
||||||
call pci_write_reg
|
call pci_write_reg
|
||||||
pop ebx
|
pop edx ebx
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
|
proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
|
||||||
push ebx
|
push ebx edx
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
mov ah, byte [bus]
|
mov ah, byte [bus]
|
||||||
@ -293,7 +293,7 @@ proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
|
|||||||
mov bl, byte [reg]
|
mov bl, byte [reg]
|
||||||
mov ecx, [val]
|
mov ecx, [val]
|
||||||
call pci_write_reg
|
call pci_write_reg
|
||||||
pop ebx
|
pop edx ebx
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
@ -394,7 +394,7 @@ proc reg_service stdcall, name:dword, handler:dword
|
|||||||
|
|
||||||
push ebx
|
push ebx
|
||||||
|
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
|
|
||||||
cmp [name], eax
|
cmp [name], eax
|
||||||
je .fail
|
je .fail
|
||||||
@ -432,7 +432,7 @@ proc reg_service stdcall, name:dword, handler:dword
|
|||||||
ret
|
ret
|
||||||
.fail:
|
.fail:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
pop ebx
|
pop ebx
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
@ -811,7 +811,7 @@ proc load_driver stdcall, driver_name:dword
|
|||||||
mov byte [edx+12], '/'
|
mov byte [edx+12], '/'
|
||||||
mov esi, [driver_name]
|
mov esi, [driver_name]
|
||||||
.redo:
|
.redo:
|
||||||
lea edx, [file_name]
|
lea edx, [file_name]
|
||||||
lea edi, [edx+13]
|
lea edi, [edx+13]
|
||||||
mov ecx, 16
|
mov ecx, 16
|
||||||
@@:
|
@@:
|
||||||
@ -928,14 +928,14 @@ proc load_driver stdcall, driver_name:dword
|
|||||||
jnz .ok
|
jnz .ok
|
||||||
|
|
||||||
stdcall kernel_free, [img_base]
|
stdcall kernel_free, [img_base]
|
||||||
cmp dword [file_name+13], 'SOUN'
|
cmp dword [file_name+13], 'SOUN'
|
||||||
jnz @f
|
jnz @f
|
||||||
cmp dword [file_name+17], 'D.ob'
|
cmp dword [file_name+17], 'D.ob'
|
||||||
jnz @f
|
jnz @f
|
||||||
cmp word [file_name+21], 'j'
|
cmp word [file_name+21], 'j'
|
||||||
jnz @f
|
jnz @f
|
||||||
mov esi, aSis
|
mov esi, aSis
|
||||||
jmp .redo
|
jmp .redo
|
||||||
@@:
|
@@:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
@ -61,11 +61,11 @@ macro DEBUGS_N _sign,_num,[_str] {
|
|||||||
jmp ..label
|
jmp ..label
|
||||||
..str db _str,0
|
..str db _str,0
|
||||||
..label:
|
..label:
|
||||||
add esp,4*8+4
|
add esp,4*8+4
|
||||||
mov edx,..str
|
mov edx,..str
|
||||||
sub esp,4*8+4
|
sub esp,4*8+4
|
||||||
else
|
else
|
||||||
mov edx,_str
|
mov edx,_str
|
||||||
end if
|
end if
|
||||||
if ~_num eq
|
if ~_num eq
|
||||||
if _num eqtype eax
|
if _num eqtype eax
|
||||||
@ -235,74 +235,75 @@ macro DEBUGH_N _sign,_num,_hex {
|
|||||||
|
|
||||||
debug_func fdo_debug_outchar
|
debug_func fdo_debug_outchar
|
||||||
debug_beginf
|
debug_beginf
|
||||||
pushad
|
pushad
|
||||||
movzx ebx,al
|
movzx ebx,al
|
||||||
mov eax,1
|
mov eax,1
|
||||||
mov ecx,sys_msg_board
|
mov ecx,sys_msg_board
|
||||||
call ecx ; sys_msg_board
|
call ecx ; sys_msg_board
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
debug_endf
|
debug_endf
|
||||||
|
|
||||||
debug_func fdo_debug_outstr
|
debug_func fdo_debug_outstr
|
||||||
debug_beginf
|
debug_beginf
|
||||||
mov eax,1
|
mov eax,1
|
||||||
.l1: dec esi
|
.l1: dec esi
|
||||||
js .l2
|
js .l2
|
||||||
movzx ebx,byte[edx]
|
movzx ebx,byte[edx]
|
||||||
or bl,bl
|
or bl,bl
|
||||||
jz .l2
|
jz .l2
|
||||||
mov ecx,sys_msg_board
|
mov ecx,sys_msg_board
|
||||||
call ecx ; sys_msg_board
|
call ecx ; sys_msg_board
|
||||||
inc edx
|
inc edx
|
||||||
jmp .l1
|
jmp .l1
|
||||||
.l2: ret
|
.l2: ret
|
||||||
debug_endf
|
debug_endf
|
||||||
|
|
||||||
debug_func fdo_debug_outdec
|
debug_func fdo_debug_outdec
|
||||||
debug_beginf
|
debug_beginf
|
||||||
or cl,cl
|
or cl,cl
|
||||||
jz @f
|
jz @f
|
||||||
or eax,eax
|
or eax,eax
|
||||||
jns @f
|
jns @f
|
||||||
neg eax
|
neg eax
|
||||||
push eax
|
push eax
|
||||||
mov al,'-'
|
mov al,'-'
|
||||||
call fdo_debug_outchar
|
call fdo_debug_outchar
|
||||||
pop eax
|
pop eax
|
||||||
@@: push 10
|
@@: push 10
|
||||||
pop ecx
|
pop ecx
|
||||||
push -'0'
|
push -'0'
|
||||||
.l1: xor edx,edx
|
.l1: xor edx,edx
|
||||||
div ecx
|
div ecx
|
||||||
push edx
|
push edx
|
||||||
test eax,eax
|
test eax,eax
|
||||||
jnz .l1
|
jnz .l1
|
||||||
.l2: pop eax
|
.l2: pop eax
|
||||||
add al,'0'
|
add al,'0'
|
||||||
jz .l3
|
jz .l3
|
||||||
call fdo_debug_outchar
|
call fdo_debug_outchar
|
||||||
jmp .l2
|
jmp .l2
|
||||||
.l3: ret
|
.l3: ret
|
||||||
debug_endf
|
debug_endf
|
||||||
|
|
||||||
debug_func fdo_debug_outhex
|
|
||||||
__fdo_hexdigits db '0123456789ABCDEF'
|
__fdo_hexdigits db '0123456789ABCDEF'
|
||||||
|
debug_func fdo_debug_outhex
|
||||||
|
|
||||||
debug_beginf
|
debug_beginf
|
||||||
mov cl,dl
|
mov cl,dl
|
||||||
neg cl
|
neg cl
|
||||||
add cl,8
|
add cl,8
|
||||||
shl cl,2
|
shl cl,2
|
||||||
rol eax,cl
|
rol eax,cl
|
||||||
.l1: rol eax,4
|
.l1: rol eax,4
|
||||||
push eax
|
push eax
|
||||||
and eax,0x0000000F
|
and eax,0x0000000F
|
||||||
mov al,[__fdo_hexdigits+eax]
|
mov al,[__fdo_hexdigits+eax]
|
||||||
call fdo_debug_outchar
|
call fdo_debug_outchar
|
||||||
pop eax
|
pop eax
|
||||||
dec edx
|
dec edx
|
||||||
jnz .l1
|
jnz .l1
|
||||||
ret
|
ret
|
||||||
debug_endf
|
debug_endf
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
|
@ -24,6 +24,7 @@ struct SOCKET_head
|
|||||||
.Type dd ? ; RAW/UDP/TCP/...
|
.Type dd ? ; RAW/UDP/TCP/...
|
||||||
.Protocol dd ? ; ICMP/IPv4/ARP/
|
.Protocol dd ? ; ICMP/IPv4/ARP/
|
||||||
.lock dd ? ; lock mutex
|
.lock dd ? ; lock mutex
|
||||||
|
.errorcode dd ?
|
||||||
.end:
|
.end:
|
||||||
ends
|
ends
|
||||||
|
|
||||||
@ -55,6 +56,7 @@ struct TCP_SOCKET
|
|||||||
; Transmission control block
|
; Transmission control block
|
||||||
.state dd ? ; TCB state
|
.state dd ? ; TCB state
|
||||||
.timer dd ? ; TCB timer (seconds)
|
.timer dd ? ; TCB timer (seconds)
|
||||||
|
|
||||||
.ISS dd ? ; initial send sequence number
|
.ISS dd ? ; initial send sequence number
|
||||||
.IRS dd ? ; initial receive sequence number
|
.IRS dd ? ; initial receive sequence number
|
||||||
.SND_UNA dd ? ; sequence number of unack'ed sent Packets
|
.SND_UNA dd ? ; sequence number of unack'ed sent Packets
|
||||||
@ -191,11 +193,31 @@ socket_open:
|
|||||||
mov [eax + SOCKET_head.Type], edx
|
mov [eax + SOCKET_head.Type], edx
|
||||||
mov [eax + SOCKET_head.Protocol], esi
|
mov [eax + SOCKET_head.Protocol], esi
|
||||||
|
|
||||||
|
cmp ecx, AF_INET4
|
||||||
|
je .af_inet4
|
||||||
|
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
|
||||||
|
.af_inet4:
|
||||||
|
|
||||||
|
cmp edx, IP_PROTO_TCP
|
||||||
|
je .tcp
|
||||||
|
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
.tcp:
|
||||||
|
|
||||||
|
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSED
|
||||||
|
|
||||||
|
pseudo_random ebx
|
||||||
|
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS], ebx
|
||||||
|
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], ebx
|
||||||
|
|
||||||
|
.done:
|
||||||
stdcall net_socket_addr_to_num, eax
|
stdcall net_socket_addr_to_num, eax
|
||||||
DEBUGF 1,", socketnumber: %u\n", eax
|
DEBUGF 1,", socketnumber: %u\n", eax
|
||||||
|
|
||||||
; TODO: if it is a tcp socket, set state to TCB_CLOSED
|
|
||||||
|
|
||||||
mov [esp+32], eax
|
mov [esp+32], eax
|
||||||
|
|
||||||
ret
|
ret
|
||||||
@ -513,27 +535,42 @@ socket_close:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
.tcp:
|
.tcp:
|
||||||
|
mov dword [esp+32],0
|
||||||
|
|
||||||
; first, remove all resend entries for this socket
|
; first, remove all resend entries for this socket
|
||||||
|
|
||||||
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN
|
call TCP_remove_socket
|
||||||
je .destroy_tcb
|
|
||||||
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT
|
|
||||||
je .destroy_tcb
|
|
||||||
|
|
||||||
; Send a fin, then enter finwait2 state
|
; cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN
|
||||||
|
; je .destroy_tcb
|
||||||
|
; cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT
|
||||||
|
; je .destroy_tcb
|
||||||
|
; cmp [eac + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSED
|
||||||
|
; je .destroy_tcb
|
||||||
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED
|
||||||
|
je .fin_wait
|
||||||
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED
|
||||||
|
je .fin_wait
|
||||||
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT
|
||||||
|
je .last_ack
|
||||||
|
|
||||||
|
stdcall net_socket_free, ebx
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
.last_ack:
|
||||||
|
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LAST_ACK
|
||||||
|
jmp .send_fin
|
||||||
|
|
||||||
|
.fin_wait:
|
||||||
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_1
|
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_1
|
||||||
|
|
||||||
mov bl, TH_FIN
|
.send_fin:
|
||||||
|
mov bl, TH_FIN + TH_ACK
|
||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
; call TCP_send
|
call TCP_send
|
||||||
|
|
||||||
;;;;;
|
|
||||||
|
|
||||||
|
|
||||||
.destroy_tcb:
|
|
||||||
|
|
||||||
stdcall net_socket_free, eax
|
|
||||||
mov dword [esp+32],0
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,6 +97,23 @@ macro add_INET reg {
|
|||||||
rol ecx, 16
|
rol ecx, 16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
macro pseudo_random reg {
|
||||||
|
|
||||||
|
add reg, [esp]
|
||||||
|
rol reg, 5
|
||||||
|
xor reg, [timer_ticks]
|
||||||
|
imul reg, 214013
|
||||||
|
xor reg, 0xdeadbeef
|
||||||
|
rol reg, 9
|
||||||
|
|
||||||
|
pushd reg
|
||||||
|
mov word [esp], 0x8080 ; kernel heap start addr (os_stack)
|
||||||
|
xor reg, [esp]
|
||||||
|
add esp, 4
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
include "queue.inc"
|
include "queue.inc"
|
||||||
include "ARP.inc"
|
include "ARP.inc"
|
||||||
include "IPv4.inc"
|
include "IPv4.inc"
|
||||||
@ -152,7 +169,7 @@ stack_handler:
|
|||||||
cmp [ETH_RUNNING], 0
|
cmp [ETH_RUNNING], 0
|
||||||
je .exit
|
je .exit
|
||||||
|
|
||||||
; Test for 1/100 s (10ms) tick
|
; Test for 10ms tick
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
cmp eax, [last_1hsTick]
|
cmp eax, [last_1hsTick]
|
||||||
je .exit
|
je .exit
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
;; Part of the tcp/ip network stack for KolibriOS ;;
|
;; Part of the tcp/ip network stack for KolibriOS ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Written by hidnplayr@kolibrios.org ;;
|
;; Written by hidnplayr@kolibrios.org ;;
|
||||||
|
;; Inspired by the TCP code of Mike Hibbit for MenuetOS ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; GNU GENERAL PUBLIC LICENSE ;;
|
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||||
;; Version 2, June 1991 ;;
|
;; Version 2, June 1991 ;;
|
||||||
@ -22,6 +23,8 @@ TCP_PACKET_TTL equ 50 ; resend if not replied to in 1/100 s
|
|||||||
TCP_SOCKET_TTL equ 10 ; # of secs to wait before closing socket
|
TCP_SOCKET_TTL equ 10 ; # of secs to wait before closing socket
|
||||||
TCP_QUEUE_SIZE equ 16
|
TCP_QUEUE_SIZE equ 16
|
||||||
|
|
||||||
|
TCP_MAX_ACKS equ 16
|
||||||
|
|
||||||
|
|
||||||
struct TCP_Packet
|
struct TCP_Packet
|
||||||
.SourcePort dw ?
|
.SourcePort dw ?
|
||||||
@ -63,13 +66,16 @@ uglobal
|
|||||||
TCP_PACKETS_RX rd MAX_IP
|
TCP_PACKETS_RX rd MAX_IP
|
||||||
|
|
||||||
TCP_IN_QUEUE rd (tcp_in_queue_entry.size*TCP_QUEUE_SIZE+queue.data)/4
|
TCP_IN_QUEUE rd (tcp_in_queue_entry.size*TCP_QUEUE_SIZE+queue.data)/4
|
||||||
TCP_OUT_QUEUE dd ?
|
TCP_OUT_QUEUE dd ?, ?
|
||||||
rd (tcp_out_queue_entry.size*TCP_QUEUE_SIZE)/4
|
rd (tcp_out_queue_entry.size*TCP_QUEUE_SIZE)/4
|
||||||
|
|
||||||
|
TCP_ACKS dd ?
|
||||||
|
TCP_ACK_LIST rd 3*TCP_MAX_ACKS
|
||||||
endg
|
endg
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
iglobal
|
iglobal
|
||||||
stateHandler:
|
TCPstateHandler:
|
||||||
|
|
||||||
dd stateTCB_LISTEN
|
dd stateTCB_LISTEN
|
||||||
dd stateTCB_SYN_SENT
|
dd stateTCB_SYN_SENT
|
||||||
@ -114,7 +120,7 @@ TCP_init:
|
|||||||
|
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
mov esi, TCP_OUT_QUEUE
|
mov esi, TCP_OUT_QUEUE
|
||||||
mov ecx, TCP_QUEUE_SIZE*tcp_out_queue_entry/4+1
|
mov ecx, TCP_QUEUE_SIZE*tcp_out_queue_entry/4+2+2+3*TCP_MAX_ACKS
|
||||||
rep stosd
|
rep stosd
|
||||||
|
|
||||||
ret
|
ret
|
||||||
@ -193,9 +199,12 @@ TCP_send_queued:
|
|||||||
cmp [TCP_OUT_QUEUE], 0
|
cmp [TCP_OUT_QUEUE], 0
|
||||||
je .exit
|
je .exit
|
||||||
|
|
||||||
|
mov ebx, TCP_OUT_QUEUE+4
|
||||||
|
call wait_mutex
|
||||||
|
|
||||||
mov eax, TCP_QUEUE_SIZE
|
mov eax, TCP_QUEUE_SIZE
|
||||||
mov ecx, [TCP_OUT_QUEUE]
|
mov ecx, [TCP_OUT_QUEUE]
|
||||||
mov esi, TCP_OUT_QUEUE+4
|
mov esi, TCP_OUT_QUEUE+8
|
||||||
|
|
||||||
.loop:
|
.loop:
|
||||||
cmp [esi + tcp_out_queue_entry.data_ptr], 0
|
cmp [esi + tcp_out_queue_entry.data_ptr], 0
|
||||||
@ -203,30 +212,33 @@ TCP_send_queued:
|
|||||||
add esi, tcp_out_queue_entry.size
|
add esi, tcp_out_queue_entry.size
|
||||||
loop .loop
|
loop .loop
|
||||||
.exit:
|
.exit:
|
||||||
|
mov [TCP_OUT_QUEUE+4], 0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.found_one:
|
.found_one:
|
||||||
dec [esi + tcp_out_queue_entry.ttl]
|
dec [esi + tcp_out_queue_entry.ttl]
|
||||||
jz .send_it
|
jz .send_it
|
||||||
|
cmp [esi + tcp_out_queue_entry.data_ptr], -1
|
||||||
|
jz .is_ack
|
||||||
.find_next:
|
.find_next:
|
||||||
add esi, tcp_out_queue_entry.size
|
add esi, tcp_out_queue_entry.size
|
||||||
dec eax
|
dec eax
|
||||||
jz .exit
|
jz .exit
|
||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
jnz .loop
|
jnz .loop
|
||||||
|
mov [TCP_OUT_QUEUE+4], 0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.send_it:
|
.send_it:
|
||||||
push eax ecx esi
|
pusha
|
||||||
|
|
||||||
mov ebx, [esi + tcp_out_queue_entry.owner]
|
mov ebx, [esi + tcp_out_queue_entry.owner]
|
||||||
push [esi + tcp_out_queue_entry.data_size]
|
pushd [esi + tcp_out_queue_entry.data_size]
|
||||||
push [esi + tcp_out_queue_entry.data_ptr]
|
pushd [esi + tcp_out_queue_entry.data_ptr]
|
||||||
DEBUGF 1,"Now sending TCP packet %x, size: %u, owner: %x, sendproc %x\n", [esp], [esp+4], ebx, [esi + tcp_out_queue_entry.sendproc]
|
DEBUGF 1,"Now sending TCP packet %x, size: %u, owner: %x, sendproc %x\n", [esp], [esp+4], ebx, [esi + tcp_out_queue_entry.sendproc]
|
||||||
inc [TCP_PACKETS_TX]
|
inc [TCP_PACKETS_TX]
|
||||||
call [esi + tcp_out_queue_entry.sendproc]
|
call [esi + tcp_out_queue_entry.sendproc]
|
||||||
add esp, 8
|
add esp, 8
|
||||||
pop esi ecx eax
|
popa
|
||||||
|
|
||||||
dec [esi + tcp_out_queue_entry.retries]
|
dec [esi + tcp_out_queue_entry.retries]
|
||||||
jz .remove_it
|
jz .remove_it
|
||||||
@ -241,6 +253,17 @@ TCP_send_queued:
|
|||||||
dec [TCP_OUT_QUEUE]
|
dec [TCP_OUT_QUEUE]
|
||||||
jmp .find_next
|
jmp .find_next
|
||||||
|
|
||||||
|
.is_ack:
|
||||||
|
pusha
|
||||||
|
mov eax, [esi + tcp_out_queue_entry.socket]
|
||||||
|
mov ebx, [esi + tcp_out_queue_entry.owner]
|
||||||
|
mov ecx, [esi + tcp_out_queue_entry.size]
|
||||||
|
call TCP_send_ack
|
||||||
|
popa
|
||||||
|
mov [esi + tcp_out_queue_entry.data_ptr], 0
|
||||||
|
dec [TCP_OUT_QUEUE]
|
||||||
|
jmp .find_next
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
@ -266,9 +289,11 @@ TCP_handler :
|
|||||||
|
|
||||||
; TODO: validate checksum
|
; TODO: validate checksum
|
||||||
|
|
||||||
|
; Find a matching socket for received packet, all following expressions must be valid:
|
||||||
|
;
|
||||||
; IP Packet TCP Destination Port = local Port
|
; IP Packet TCP Destination Port = local Port
|
||||||
; IP Packet SA = Remote IP OR = 0
|
; (IP Packet SA = Remote IP) OR (Remote IP = 0)
|
||||||
; IP Packet TCP Source Port = remote Port OR = 0
|
; (IP Packet TCP Source Port = remote Port) OR (remote Port = 0)
|
||||||
|
|
||||||
mov ebx, net_sockets
|
mov ebx, net_sockets
|
||||||
|
|
||||||
@ -318,27 +343,30 @@ TCP_handler :
|
|||||||
; ecx is size of tcp data
|
; ecx is size of tcp data
|
||||||
|
|
||||||
; as a Packet has been received, update the TCB timer
|
; as a Packet has been received, update the TCB timer
|
||||||
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], TCP_SOCKET_TTL
|
|
||||||
|
|
||||||
; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges
|
; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges
|
||||||
test [edx + TCP_Packet.Flags], TH_ACK
|
test [edx + TCP_Packet.Flags], TH_ACK
|
||||||
jz .no_ack ; No ACK, so no data yet
|
jz .no_ack ; No ACK, so no data yet
|
||||||
|
|
||||||
; Calculate ACK number
|
; Calculate ACK number, in intel byte order
|
||||||
mov edi, [edx + TCP_Packet.AckNumber]
|
mov edi, [edx + TCP_Packet.AckNumber]
|
||||||
bswap edi
|
bswap edi
|
||||||
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number], edi
|
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number], edi
|
||||||
DEBUGF 1,"Setting last_ack_number to %u\n", edi
|
DEBUGF 1,"Setting last_ack_number to %u\n", edi
|
||||||
bswap edi
|
|
||||||
|
|
||||||
; Dequeue all acknowledged packets
|
; Dequeue all acknowledged packets
|
||||||
cmp [TCP_OUT_QUEUE], 0 ; first, check if any packets are queued at all
|
cmp [TCP_OUT_QUEUE], 0 ; first, check if any packets are queued at all
|
||||||
je .no_ack
|
je .no_ack
|
||||||
|
|
||||||
|
push ebx
|
||||||
|
mov ebx, TCP_OUT_QUEUE+4
|
||||||
|
call wait_mutex
|
||||||
|
pop ebx
|
||||||
|
|
||||||
push ecx
|
push ecx
|
||||||
DEBUGF 1,"Removing all queued packets with smaller ACK\n"
|
DEBUGF 1,"Removing all queued packets with smaller ACK\n"
|
||||||
mov ecx, TCP_QUEUE_SIZE
|
mov ecx, TCP_QUEUE_SIZE
|
||||||
mov esi, TCP_OUT_QUEUE+4
|
mov esi, TCP_OUT_QUEUE+8
|
||||||
.loop:
|
.loop:
|
||||||
cmp [esi + tcp_out_queue_entry.data_ptr], 0
|
cmp [esi + tcp_out_queue_entry.data_ptr], 0
|
||||||
je .maybe_next
|
je .maybe_next
|
||||||
@ -349,7 +377,7 @@ TCP_handler :
|
|||||||
cmp [esi + tcp_out_queue_entry.seq_num], edi
|
cmp [esi + tcp_out_queue_entry.seq_num], edi
|
||||||
jg .maybe_next
|
jg .maybe_next
|
||||||
|
|
||||||
DEBUGF 1,"Removing a queued packet\n"
|
DEBUGF 1,"Removing a queued packet\n"
|
||||||
|
|
||||||
push [esi + tcp_out_queue_entry.data_ptr]
|
push [esi + tcp_out_queue_entry.data_ptr]
|
||||||
mov [esi + tcp_out_queue_entry.data_ptr], 0
|
mov [esi + tcp_out_queue_entry.data_ptr], 0
|
||||||
@ -359,8 +387,9 @@ TCP_handler :
|
|||||||
.maybe_next:
|
.maybe_next:
|
||||||
add esi, tcp_out_queue_entry.size
|
add esi, tcp_out_queue_entry.size
|
||||||
loop .loop
|
loop .loop
|
||||||
pop ecx
|
|
||||||
|
|
||||||
|
mov [TCP_OUT_QUEUE+4], 0
|
||||||
|
pop ecx
|
||||||
|
|
||||||
; Now call the correct handler, depending on the socket state
|
; Now call the correct handler, depending on the socket state
|
||||||
.no_ack:
|
.no_ack:
|
||||||
@ -371,11 +400,7 @@ TCP_handler :
|
|||||||
cmp eax, TCB_CLOSED
|
cmp eax, TCB_CLOSED
|
||||||
ja .dump
|
ja .dump
|
||||||
|
|
||||||
dec eax
|
call dword [TCPstateHandler+eax*4-4]
|
||||||
shl eax, 2
|
|
||||||
add eax, stateHandler
|
|
||||||
|
|
||||||
call dword[eax]
|
|
||||||
|
|
||||||
.dump:
|
.dump:
|
||||||
DEBUGF 1,"Dumping TCP packet\n"
|
DEBUGF 1,"Dumping TCP packet\n"
|
||||||
@ -465,13 +490,11 @@ TCP_send:
|
|||||||
xchg cl, ch
|
xchg cl, ch
|
||||||
pushw cx
|
pushw cx
|
||||||
xchg cl, ch
|
xchg cl, ch
|
||||||
;; pushw TCP_Packet.Data shl 8
|
|
||||||
pushw IP_PROTO_TCP shl 8
|
pushw IP_PROTO_TCP shl 8
|
||||||
pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options..
|
pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options..
|
||||||
pushd [edi-8] ; source address
|
pushd [edi-8] ; source address
|
||||||
|
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
; mov ecx, TCP_Packet.Data
|
|
||||||
mov esi, edi
|
mov esi, edi
|
||||||
call checksum_1
|
call checksum_1
|
||||||
mov ecx, 12
|
mov ecx, 12
|
||||||
@ -496,14 +519,13 @@ TCP_send:
|
|||||||
and ecx, 0x0000ffff
|
and ecx, 0x0000ffff
|
||||||
xchg cl, ch
|
xchg cl, ch
|
||||||
sub cx, TCP_Packet.Data
|
sub cx, TCP_Packet.Data
|
||||||
add_INET (edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT)
|
|
||||||
|
|
||||||
|
add_INET (edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT) ; todo: this should only happen when packet was queued successful
|
||||||
mov ecx, TCP_RETRIES
|
mov ecx, TCP_RETRIES
|
||||||
|
|
||||||
jmp .go_for_it
|
jmp .go_for_it
|
||||||
|
|
||||||
.only_one:
|
.only_one:
|
||||||
; inc_INET (edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT)
|
|
||||||
mov ecx, 1
|
mov ecx, 1
|
||||||
.go_for_it:
|
.go_for_it:
|
||||||
|
|
||||||
@ -523,37 +545,37 @@ TCP_send:
|
|||||||
; IN: [esp] pointer to buffer
|
; IN: [esp] pointer to buffer
|
||||||
; [esp + 4] size of buffer
|
; [esp + 4] size of buffer
|
||||||
; ebx = driver struct
|
; ebx = driver struct
|
||||||
|
; edx = sequence number of this packet in intel byte order
|
||||||
; esi = sender proc
|
; esi = sender proc
|
||||||
; edx = sequence number of this packet in normal byte order
|
|
||||||
; edi = socket number
|
; edi = socket number
|
||||||
; ecx = retries
|
|
||||||
; OUT: /
|
; OUT: /
|
||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
TCP_queue:
|
TCP_queue:
|
||||||
|
|
||||||
bswap edx
|
|
||||||
DEBUGF 1,"Adding packet to TCP queue, buffer: %x, size: %u, driver: %x, acknum: %u\n", [esp], [esp+4], ebx, edx
|
DEBUGF 1,"Adding packet to TCP queue, buffer: %x, size: %u, driver: %x, acknum: %u\n", [esp], [esp+4], ebx, edx
|
||||||
bswap edx
|
|
||||||
|
|
||||||
cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE
|
cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE
|
||||||
jge .full
|
jge .full
|
||||||
|
|
||||||
push ecx
|
push ebx
|
||||||
mov ecx, TCP_QUEUE_SIZE
|
mov ebx, TCP_OUT_QUEUE+4
|
||||||
mov eax, TCP_OUT_QUEUE+4
|
call wait_mutex
|
||||||
|
pop ebx
|
||||||
|
|
||||||
|
mov ecx, TCP_QUEUE_SIZE
|
||||||
|
mov eax, TCP_OUT_QUEUE+8
|
||||||
.loop:
|
.loop:
|
||||||
cmp [eax + tcp_out_queue_entry.data_ptr], 0
|
cmp [eax + tcp_out_queue_entry.data_ptr], 0
|
||||||
je .found_it
|
je .found_it
|
||||||
add eax, tcp_out_queue_entry.size
|
add eax, tcp_out_queue_entry.size
|
||||||
loop .loop
|
loop .loop
|
||||||
|
|
||||||
|
add esp, 4
|
||||||
.full: ; silently discard the packet
|
.full: ; silently discard the packet
|
||||||
DEBUGF 1,"TCP queue is full!\n"
|
DEBUGF 1,"TCP queue is full!\n"
|
||||||
|
|
||||||
add esp, 4
|
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 4
|
add esp, 4
|
||||||
|
|
||||||
@ -561,7 +583,7 @@ TCP_queue:
|
|||||||
|
|
||||||
.found_it: ; eax points to empty queue entry
|
.found_it: ; eax points to empty queue entry
|
||||||
|
|
||||||
pop [eax + tcp_out_queue_entry.retries]
|
mov [eax + tcp_out_queue_entry.retries], TCP_RETRIES
|
||||||
pop [eax + tcp_out_queue_entry.data_ptr]
|
pop [eax + tcp_out_queue_entry.data_ptr]
|
||||||
pop [eax + tcp_out_queue_entry.data_size]
|
pop [eax + tcp_out_queue_entry.data_size]
|
||||||
mov [eax + tcp_out_queue_entry.ttl], 1 ; send immediately
|
mov [eax + tcp_out_queue_entry.ttl], 1 ; send immediately
|
||||||
@ -572,9 +594,179 @@ TCP_queue:
|
|||||||
|
|
||||||
inc [TCP_OUT_QUEUE]
|
inc [TCP_OUT_QUEUE]
|
||||||
|
|
||||||
sub eax, TCP_OUT_QUEUE+4
|
sub eax, TCP_OUT_QUEUE+8
|
||||||
DEBUGF 1,"Added to queue in pos %u\n", eax
|
shr eax, 5
|
||||||
|
DEBUGF 1,"Added to queue in pos %u, total queued packets: %u\n", eax, [TCP_OUT_QUEUE+8]
|
||||||
|
|
||||||
|
mov [TCP_OUT_QUEUE+4], 0
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; IN: ebx = socket
|
||||||
|
; ecx = ack number
|
||||||
|
;
|
||||||
|
; OUT: /
|
||||||
|
;
|
||||||
|
;-----------------------------------------------------------------
|
||||||
|
align 4
|
||||||
|
TCP_queue_ack:
|
||||||
|
|
||||||
|
DEBUGF 1,"Adding ACK to TCP queue, socket: %x, acknum: %u\n", ebx, ecx
|
||||||
|
|
||||||
|
cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE
|
||||||
|
jge .full
|
||||||
|
|
||||||
|
push ebx ecx
|
||||||
|
mov ebx, TCP_OUT_QUEUE+4
|
||||||
|
call wait_mutex
|
||||||
|
|
||||||
|
mov ecx, TCP_QUEUE_SIZE
|
||||||
|
mov eax, TCP_OUT_QUEUE+8
|
||||||
|
.loop:
|
||||||
|
cmp [eax + tcp_out_queue_entry.data_ptr], 0
|
||||||
|
je .found_it
|
||||||
|
add eax, tcp_out_queue_entry.size
|
||||||
|
loop .loop
|
||||||
|
|
||||||
|
add esp, 8
|
||||||
|
.full: ; silently discard the packet
|
||||||
|
DEBUGF 1,"TCP queue is full!\n"
|
||||||
|
ret
|
||||||
|
|
||||||
|
.found_it: ; eax points to empty queue entry
|
||||||
|
|
||||||
|
pop [eax + tcp_out_queue_entry.data_size] ; ACK number
|
||||||
|
mov [eax + tcp_out_queue_entry.data_ptr], -1 ; ACK packet
|
||||||
|
pop [eax + tcp_out_queue_entry.socket]
|
||||||
|
mov [eax + tcp_out_queue_entry.retries], 1
|
||||||
|
mov [eax + tcp_out_queue_entry.ttl], 20 ; 200 ms
|
||||||
|
|
||||||
|
inc [TCP_OUT_QUEUE]
|
||||||
|
|
||||||
|
sub eax, TCP_OUT_QUEUE+8
|
||||||
|
shr eax, 5
|
||||||
|
DEBUGF 1,"Added to queue in pos %u, total queued packets: %u\n", eax, [TCP_OUT_QUEUE+8]
|
||||||
|
|
||||||
|
mov [TCP_OUT_QUEUE+4], 0
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; IN: eax = socket pointer
|
||||||
|
; ebx = device structure
|
||||||
|
; ecx = ack number
|
||||||
|
|
||||||
|
align 4
|
||||||
|
TCP_send_ack:
|
||||||
|
|
||||||
|
DEBUGF 1,"Creating TCP ACK packet, socket: %x, acknum: %x\n", eax, ecx
|
||||||
|
|
||||||
|
push ecx eax
|
||||||
|
|
||||||
|
mov di , IP_PROTO_TCP
|
||||||
|
mov ecx, TCP_Packet.Data
|
||||||
|
; Create an IPv4 Packet of the correct size
|
||||||
|
mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
|
||||||
|
mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
|
||||||
|
|
||||||
|
call IPv4_create_packet
|
||||||
|
cmp edi, -1
|
||||||
|
je .fail
|
||||||
|
|
||||||
|
pop ecx
|
||||||
|
|
||||||
|
; fill in tcp sequence number
|
||||||
|
push [ecx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
|
||||||
|
pop [edi + TCP_Packet.SequenceNumber]
|
||||||
|
|
||||||
|
; Fill in local and remote ports
|
||||||
|
push dword [ecx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort]
|
||||||
|
pop dword [edi + TCP_Packet.SourcePort]
|
||||||
|
|
||||||
|
; Acknumber
|
||||||
|
pop [edi + TCP_Packet.AckNumber]
|
||||||
|
|
||||||
|
; Fill in other tcp options
|
||||||
|
mov [edi + TCP_Packet.Flags], TH_ACK
|
||||||
|
mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes
|
||||||
|
mov [edi + TCP_Packet.UrgentPointer], 0
|
||||||
|
mov [edi + TCP_Packet.DataOffset], 0x50
|
||||||
|
mov [edi + TCP_Packet.Checksum], 0
|
||||||
|
|
||||||
|
; Push pointer to and size of total packet (needed for send procedure)
|
||||||
|
push edx eax esi
|
||||||
|
|
||||||
|
; Now, calculate the checksum
|
||||||
|
pushw TCP_Packet.Data shl 8
|
||||||
|
pushw IP_PROTO_TCP shl 8
|
||||||
|
pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options..
|
||||||
|
pushd [edi-8] ; source address
|
||||||
|
|
||||||
|
xor edx, edx
|
||||||
|
mov ecx, 12
|
||||||
|
mov esi, esp
|
||||||
|
call checksum_1
|
||||||
|
call checksum_2
|
||||||
|
mov [edi + TCP_Packet.Checksum], dx
|
||||||
|
add esp, 12 ; remove the pseudoheader from stack
|
||||||
|
|
||||||
|
pop eax
|
||||||
|
call eax
|
||||||
|
call kernel_free
|
||||||
|
add esp, 4 ; pop (balance stack)
|
||||||
|
ret
|
||||||
|
|
||||||
|
.fail:
|
||||||
|
add esp, 8
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; Remove all queued TCP packets for a specified socket
|
||||||
|
;
|
||||||
|
; IN: eax = socket number
|
||||||
|
; OUT: /
|
||||||
|
;
|
||||||
|
; destoys esi and ecx
|
||||||
|
;
|
||||||
|
;-----------------------------------------------------------------
|
||||||
|
|
||||||
|
align 4
|
||||||
|
TCP_remove_socket:
|
||||||
|
|
||||||
|
cmp [TCP_OUT_QUEUE], 0
|
||||||
|
je .skip
|
||||||
|
|
||||||
|
mov ebx, TCP_OUT_QUEUE+4
|
||||||
|
call wait_mutex
|
||||||
|
|
||||||
|
mov eax, TCP_QUEUE_SIZE
|
||||||
|
mov ecx, [TCP_OUT_QUEUE]
|
||||||
|
mov esi, TCP_OUT_QUEUE+8
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
cmp [esi + tcp_out_queue_entry.data_ptr], 0
|
||||||
|
jz .maybenext
|
||||||
|
cmp [esi + tcp_out_queue_entry.socket], eax
|
||||||
|
jnz .maybenext
|
||||||
|
|
||||||
|
push [esi + tcp_out_queue_entry.data_ptr]
|
||||||
|
mov [esi + tcp_out_queue_entry.data_ptr], 0
|
||||||
|
dec [TCP_OUT_QUEUE]
|
||||||
|
call kernel_free
|
||||||
|
|
||||||
|
.maybenext:
|
||||||
|
add esi, tcp_out_queue_entry.size
|
||||||
|
loop .loop
|
||||||
|
|
||||||
|
mov [TCP_OUT_QUEUE+4], 0
|
||||||
|
.skip:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -737,6 +929,90 @@ stateTCB_SYN_RECEIVED:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
if 0
|
||||||
|
|
||||||
|
|
||||||
|
align 4
|
||||||
|
stateTCB_ESTABLISHED:
|
||||||
|
|
||||||
|
DEBUGF 1,"TCBStateHandler: Established\n"
|
||||||
|
|
||||||
|
mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
|
||||||
|
bswap eax
|
||||||
|
DEBUGF 1,"RCV_NXT is set to:%u\n", eax
|
||||||
|
bswap eax
|
||||||
|
cmp eax, [edx + TCP_Packet.SequenceNumber]
|
||||||
|
jne .exit ;;;;;;
|
||||||
|
|
||||||
|
; check if we received an ACK
|
||||||
|
test [edx + TCP_Packet.Flags], TH_ACK
|
||||||
|
jz .no_ack
|
||||||
|
|
||||||
|
mov ax, [edx + TCP_Packet.Window]
|
||||||
|
xchg al, ah
|
||||||
|
cmp ax, 1024
|
||||||
|
ja @f
|
||||||
|
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 1
|
||||||
|
@@:
|
||||||
|
.no_ack:
|
||||||
|
|
||||||
|
; Now, see if we received any data
|
||||||
|
test ecx, ecx
|
||||||
|
jz .nodata
|
||||||
|
|
||||||
|
; Calculate next sequencenumber
|
||||||
|
add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT)
|
||||||
|
|
||||||
|
push edx
|
||||||
|
DEBUGF 1,"Got %u bytes data!\n", ecx
|
||||||
|
; calculate header length
|
||||||
|
movzx eax, [edx + TCP_Packet.DataOffset]
|
||||||
|
and eax, 11110000b
|
||||||
|
shr eax, 2
|
||||||
|
DEBUGF 1,"TCP header size: %u\n", eax
|
||||||
|
add edx, eax ; now edx points to data
|
||||||
|
|
||||||
|
add esp, 4
|
||||||
|
pop esi ; pointer to buffer
|
||||||
|
add esp, 4
|
||||||
|
|
||||||
|
sub edx, esi
|
||||||
|
mov edi, edx ; offset
|
||||||
|
mov eax, ebx ; socket ptr
|
||||||
|
|
||||||
|
call socket_internal_receiver ; Place the data from packet into socket
|
||||||
|
|
||||||
|
; lea ebx, [eax + SOCKET_head.lock]
|
||||||
|
; call wait_mutex
|
||||||
|
mov ebx, eax
|
||||||
|
pop edx
|
||||||
|
|
||||||
|
test [edx + TCP_Packet.Flags], TH_FIN + TH_RST
|
||||||
|
jz .ack
|
||||||
|
|
||||||
|
.nodata:
|
||||||
|
test [edx + TCP_Packet.Flags], TH_FIN + TH_RST
|
||||||
|
jz .exit
|
||||||
|
|
||||||
|
; Send an ACK to that fin, and enter closewait state
|
||||||
|
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT
|
||||||
|
; Remove all resend entries from the queue
|
||||||
|
mov eax, ebx
|
||||||
|
call TCP_remove_socket
|
||||||
|
|
||||||
|
.ack:
|
||||||
|
push ebx
|
||||||
|
mov ecx, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
|
||||||
|
call TCP_queue_ack
|
||||||
|
pop ebx
|
||||||
|
|
||||||
|
.exit:
|
||||||
|
mov [ebx + SOCKET_head.lock], 0
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
end if
|
||||||
|
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
stateTCB_ESTABLISHED:
|
stateTCB_ESTABLISHED:
|
||||||
@ -751,13 +1027,9 @@ stateTCB_ESTABLISHED:
|
|||||||
jne .exit
|
jne .exit
|
||||||
|
|
||||||
; Calculate next sequencenumber
|
; Calculate next sequencenumber
|
||||||
;; test ecx, ecx
|
|
||||||
;; jnz @f
|
|
||||||
;; inc ecx
|
|
||||||
;; @@:
|
|
||||||
add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT)
|
add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT)
|
||||||
|
|
||||||
test [edx + TCP_Packet.Flags], TH_FIN + TH_RST ;;;
|
test [edx + TCP_Packet.Flags], TH_FIN + TH_RST
|
||||||
jnz .fin
|
jnz .fin
|
||||||
|
|
||||||
.check_ack:
|
.check_ack:
|
||||||
@ -799,9 +1071,9 @@ stateTCB_ESTABLISHED:
|
|||||||
|
|
||||||
call socket_internal_receiver ; Place the data from packet into socket
|
call socket_internal_receiver ; Place the data from packet into socket
|
||||||
|
|
||||||
lea ebx, [eax + SOCKET_head.lock] ;;;;;
|
lea ebx, [eax + SOCKET_head.lock]
|
||||||
call wait_mutex ;;;;;
|
call wait_mutex
|
||||||
mov ebx, eax ;;;;
|
mov ebx, eax
|
||||||
|
|
||||||
.ack:
|
.ack:
|
||||||
mov eax, ebx
|
mov eax, ebx
|
||||||
@ -814,7 +1086,7 @@ stateTCB_ESTABLISHED:
|
|||||||
mov [ebx + SOCKET_head.lock], 0
|
mov [ebx + SOCKET_head.lock], 0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.fin:
|
.fin: ; we received a FIN or RESET
|
||||||
; Remove all resend entries from the queue
|
; Remove all resend entries from the queue
|
||||||
mov ecx, TCP_QUEUE_SIZE
|
mov ecx, TCP_QUEUE_SIZE
|
||||||
mov esi, TCP_OUT_QUEUE+4
|
mov esi, TCP_OUT_QUEUE+4
|
||||||
@ -837,11 +1109,10 @@ stateTCB_ESTABLISHED:
|
|||||||
loop .removeloop
|
loop .removeloop
|
||||||
|
|
||||||
; Send an ACK to that fin, and enter closewait state
|
; Send an ACK to that fin, and enter closewait state
|
||||||
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT
|
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSING
|
||||||
jmp .check_ack
|
jmp .check_ack
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
stateTCB_FIN_WAIT_1:
|
stateTCB_FIN_WAIT_1:
|
||||||
|
|
||||||
@ -864,10 +1135,6 @@ stateTCB_FIN_WAIT_1:
|
|||||||
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
|
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
; lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
|
|
||||||
; inc_INET esi
|
|
||||||
|
|
||||||
; Send an ACK
|
; Send an ACK
|
||||||
mov eax, ebx
|
mov eax, ebx
|
||||||
mov bl, TH_ACK
|
mov bl, TH_ACK
|
||||||
@ -893,11 +1160,6 @@ stateTCB_FIN_WAIT_2:
|
|||||||
; Change state, as we have a fin
|
; Change state, as we have a fin
|
||||||
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
|
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
|
||||||
|
|
||||||
lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
|
|
||||||
inc_INET esi
|
|
||||||
|
|
||||||
mov [ebx + SOCKET_head.lock], 0
|
|
||||||
|
|
||||||
; Send an ACK
|
; Send an ACK
|
||||||
mov eax, ebx
|
mov eax, ebx
|
||||||
mov bl, TH_ACK
|
mov bl, TH_ACK
|
||||||
|
Loading…
Reference in New Issue
Block a user