Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1195 → Rev 1196

/kernel/branches/net/network/tcp.inc
1,21 → 1,20
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; TCP.INC ;;
;; ;;
;; TCP Processes for Menuet OS TCP/IP stack ;;
;; Part of the tcp/ip network stack for KolibriOS ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; See file COPYING for details ;;
;; v0.6 : Added reset handling in the established state ;;
;; Added a timer per socket to allow delays when ;;
;; rx window gets below 1KB ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
$Revision: 1019 $
 
 
44,6 → 43,8
TCP_RETRIES equ 5 ; Number of times to resend a Packet
TCP_TIMEOUT equ 10 ; resend if not replied to in x hs
 
TCP_QUEUE_SIZE equ 16
 
struct TCP_Packet
.SourcePort dw ?
.DestinationPort dw ?
59,17 → 60,59
.Data:
ends
 
align 4
uglobal
TCP_PACKETS_TX rd MAX_IP
TCP_PACKETS_RX rd MAX_IP
 
;***************************************************************************
; Function
TCP_IN_QUEUE rd 3*TCP_QUEUE_SIZE+3
TCP_OUT_QUEUE rd 3*TCP_QUEUE_SIZE+3
endg
 
 
 
 
 
;-----------------------------------------------------------------
;
; TCP_init
;
; This function resets all TCP variables
;
; IN: /
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
TCP_init:
 
xor eax, eax
mov edi, TCP_PACKETS_TX
mov ecx, 2*MAX_IP
rep stosd
 
mov dword [TCP_IN_QUEUE], TCP_QUEUE_SIZE
mov dword [TCP_IN_QUEUE+4], TCP_IN_QUEUE + queue.data
mov dword [TCP_IN_QUEUE+8], TCP_IN_QUEUE + queue.data
 
mov dword [TCP_OUT_QUEUE], TCP_QUEUE_SIZE
mov dword [TCP_OUT_QUEUE+4], TCP_OUT_QUEUE + queue.data
mov dword [TCP_OUT_QUEUE+8], TCP_OUT_QUEUE + queue.data
 
ret
 
 
;-----------------------------------------------------------------
;
; tcp_tcb_handler
;
; Description
; Handles sockets in the timewait state, closing them
; when the TCB timer expires
;
;***************************************************************************
;-----------------------------------------------------------------
 
align 4
tcp_tcb_handler:
; scan through all the sockets, decrementing active timers
 
84,7 → 127,7
or ebx, ebx
jz .exit
 
DEBUGF 1, "K : %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState]
; DEBUGF 1, "K : %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState]
 
cmp [ebx + SOCKET.TCBTimer], 0
jne .decrement_tcb
124,7 → 167,8
;
;***************************************************************************
 
proc tcp_tx_handler stdcall
align 4
tcp_tx_handler:
; decrement all resend buffers timers. If they
; expire, queue them for sending, and restart the timer.
; If the retries counter reach 0, delete the entry
133,7 → 177,7
mov ecx, 0
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
; cmp ecx, NUMRESENDENTRIES
je .exit ; None left
cmp dword[esi + 4], 0
jne @f ; found one
162,9 → 206,9
@@: ; resend Packet
pushad
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
jne .tth004z
 
; TODO - try again in 10ms.
179,21 → 223,21
 
.tth004z:
; we have a buffer # in ax
push eax ecx
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
; push eax ecx
; mov ecx, IPBUFFSIZE
; mul ecx
; add eax, IPbuffs
 
; we have the buffer address in eax
mov edi, eax
pop ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
mov esi, resendBuffer
@@: add esi, IPBUFFSIZE
; mov esi, resendBuffer
; @@: add esi, IPBUFFSIZE
loop @b
 
; we have resend buffer location in esi
mov ecx, IPBUFFSIZE
; mov ecx, IPBUFFSIZE
 
; copy data across
push edi
202,15 → 246,15
pop edi
 
; queue Packet
mov eax, NET1OUT_QUEUE
mov edx, [IP_LIST]
cmp edx, [edi + IP_Packet.DestinationAddress]
jne .not_local
mov eax, IPIN_QUEUE
; mov eax, NET1OUT_QUEUE
; mov edx, [IP_LIST]
; cmp edx, [edi + IP_Packet.DestinationAddress]
; jne .not_local
; mov eax, IPIN_QUEUE
 
.not_local:
pop ebx
call queue
; call queue
 
.tth005:
popad
221,36 → 265,33
 
.exit:
ret
endp
 
 
;***************************************************************************
; Function
; tcp_rx
 
;-----------------------------------------------------------------
;
; Description
; TCP protocol handler
; This is a kernel function, called by ip_rx
; IP buffer address given in edx
; IP buffer number in eax
; Free up (or re-use) IP buffer when finished
; TCP_Handler:
;
;***************************************************************************
; Called by IPv4_handler,
; this procedure will inject the tcp data diagrams in the application sockets.
;
; IN: Pointer to buffer in [esp]
; size of buffer in [esp+4]
; pointer to device struct in ebx
; TCP Packet size in ecx
; pointer to TCP Packet data in edx
; SourceAddres in esi
; OUT: /
;
;-----------------------------------------------------------------
 
proc tcp_rx stdcall uses ebx
; The process is as follows.
; Look for a socket with matching remote IP, remote port, local port
; if not found, then
; look for remote IP + local port match ( where sockets remote port = 0)
; if not found, then
; look for a socket where local socket port == IP Packets remote port
; where sockets remote port, remote IP = 0
; discard if not found
; Call sockets tcbStateMachine, with pointer to Packet.
; the state machine will not delete the Packet, so do that here.
TCP_Handler :
 
push eax
 
DEBUGF 1,"TCP_Handler\n"
 
jmp .exit ;;;;
 
; Look for a socket where
; IP Packet TCP Destination Port = local Port
; IP Packet SA = Remote IP
265,19 → 306,19
 
; DEBUGF 1, "K : tcp_rx - 1.dport: %x - %x\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
 
mov ax, [edx + 20 + TCP_Packet.DestinationPort] ; get the dest. port from the TCP hdr
mov ax, [edx + TCP_Packet.DestinationPort] ; get the dest. port from the TCP hdr
cmp [ebx + SOCKET.LocalPort], ax ; get the dest. port from the TCP hdr
jne .next_socket.1 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 1.addr: %x - %x\n", [edx + IP_Packet.SourceAddress], [ebx + SOCKET.RemoteIP]
 
mov eax, [edx + IP_Packet.SourceAddress] ; get the source IP Addr from the IP hdr
mov eax, esi ;[edx + IP_Packet.SourceAddress] ; get the source IP Addr from the IP hdr
cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP
jne .next_socket.1 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 1.sport: %x - %x\n", [edx + 20 + TCP_Packet.SourcePort]:4, [ebx + SOCKET.RemotePort]:4
 
mov ax, [edx + 20 + TCP_Packet.SourcePort] ; get the source port from the TCP hdr
mov ax, [edx + TCP_Packet.SourcePort] ; get the source port from the TCP hdr
cmp [ebx + SOCKET.RemotePort], ax ; compare with socket's remote port
jne .next_socket.1 ; different - try next socket
 
301,14 → 342,14
 
; DEBUGF 1, "K : tcp_rx - 2.dport: %x - %x\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
 
mov ax, [edx + 20 + TCP_Packet.DestinationPort] ; get the dest. port from the TCP hdr
mov ax, [edx + TCP_Packet.DestinationPort] ; get the dest. port from the TCP hdr
cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port
jne .next_socket.2 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 2.addr: %x - %x\n", [edx + IP_Packet.SourceAddress], [ebx + SOCKET.RemoteIP]
 
mov eax, [edx + IP_Packet.SourceAddress] ; get the source IP Addr from the IP hdr
cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP
; mov eax, esi ;[edx + IP_Packet.SourceAddress] ; get the source IP Addr from the IP hdr
cmp [ebx + SOCKET.RemoteIP], esi ; compare with socket's remote IP
jne .next_socket.2 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 2.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4
336,7 → 377,7
 
; DEBUGF 1, "K : tcp_rx - 3.dport: %x - %x\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
 
mov ax, [edx + 20 + TCP_Packet.DestinationPort] ; get destination port from the TCP hdr
mov ax, [edx + TCP_Packet.DestinationPort] ; get destination port from the TCP hdr
cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port
jne .next_socket.3 ; different - try next socket
 
358,9 → 399,9
; If we got here, we need to reject the Packet
 
DEBUGF 1, "K : tcp_rx - dumped\n"
DEBUGF 1, "K : --------: %x-%x-%x (flags: %x)\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [edx + IP_Packet.SourceAddress], [edx + 20 + TCP_Packet.SourcePort]:4, [edx + 20 + TCP_Packet.Flags]:2
; DEBUGF 1, "K : --------: %x-%x-%x (flags: %x)\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [edx + IP_Packet.SourceAddress], [edx + 20 + TCP_Packet.SourcePort]:4, [edx + 20 + TCP_Packet.Flags]:2
 
inc [dumped_rx_count]
; inc [dumped_rx_count]
jmp .exit
 
.change_state:
373,12 → 414,27
stdcall tcpStateMachine, ebx
 
.exit:
pop eax
call freeBuff
 
call kernel_free
add esp, 4 ; pop (balance stack)
 
ret
endp
 
 
 
;-----------------------------------------------------------------
;
; IN: eax = dest ip
; ebx = source ip
; ecx = data length
; edx = remote port shl 16 + local port
; esi = data offset
;
;-----------------------------------------------------------------
 
TCP_create_Packet:
 
DEBUGF 1,"Create TCP Packet\n"
;***************************************************************************
; Function
; buildTCPPacket
394,30 → 450,31
;
;***************************************************************************
 
proc build_tcp_Packet stdcall, sockAddr:DWORD
push ecx ; Save data length
 
; convert buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
add ecx, UDP_Packet.Data
mov di , IP_PROTO_UDP
 
mov edx, eax
; dx = fragment id
 
mov [edx + 20 + TCP_Packet.Flags], bl ; TCP flags
call IPv4_create_Packet ; TODO: figure out a way to choose between IPv4 and IPv6
cmp edi, -1
je .exit
 
mov ebx, [sockAddr]
mov [edi + TCP_Packet.Flags], bl ; TCP flags
 
; mov ebx, [sockAddr];---------------------------------------------------------- eof
 
; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
 
; Fill in the IP header ( some data is in the socket descriptor)
mov eax, [ebx + SOCKET.LocalIP]
mov [edx + IP_Packet.SourceAddress], eax
; mov [edx + IP_Packet.SourceAddress], eax
mov eax, [ebx + SOCKET.RemoteIP]
mov [edx + IP_Packet.DestinationAddress], eax
; mov [edx + IP_Packet.DestinationAddress], eax
 
mov [edx + IP_Packet.VersionAndIHL], 0x45
mov [edx + IP_Packet.TypeOfService], 0
; mov [edx + IP_Packet.VersionAndIHL], 0x45
; mov [edx + IP_Packet.TypeOfService], 0
 
pop eax ; Get the TCP data length
push eax
424,14 → 481,14
 
add eax, 20 + 20 ; add IP header and TCP header lengths
rol ax, 8
mov [edx + IP_Packet.TotalLength], ax
mov [edx + IP_Packet.Identification], 0
mov [edx + IP_Packet.FlagsAndFragmentOffset], 0x0040
mov [edx + IP_Packet.TimeToLive], 0x20
mov [edx + IP_Packet.Protocol], PROTOCOL_TCP
; mov [edx + IP_Packet.TotalLength], ax
; mov [edx + IP_Packet.Identification], 0
; mov [edx + IP_Packet.FlagsAndFragmentOffset], 0x0040
; mov [edx + IP_Packet.TimeToLive], 0x20
; mov [edx + IP_Packet.Protocol], PROTOCOL_TCP
 
; Checksum left unfilled
mov [edx + IP_Packet.HeaderChecksum], 0
; mov [edx + IP_Packet.HeaderChecksum], 0
 
; Fill in the TCP header (some data is in the socket descriptor)
mov ax, [ebx + SOCKET.LocalPort]
475,54 → 532,64
@@: ; we have edx as IPbuffer ptr.
; Fill in the TCP checksum
; First, fill in pseudoheader
mov eax, [edx + IP_Packet.SourceAddress]
mov [pseudoHeader], eax
mov eax, [edx + IP_Packet.DestinationAddress]
mov [pseudoHeader + 4], eax
mov word[pseudoHeader + 8], PROTOCOL_TCP shl 8 + 0
add ebx, 20
mov [pseudoHeader + 10], bh
mov [pseudoHeader + 11], bl
; mov eax, [edx + IP_Packet.SourceAddress]
; mov [pseudoHeader], eax
; mov eax, [edx + IP_Packet.DestinationAddress]
; mov [pseudoHeader + 4], eax
; mov word[pseudoHeader + 8], PROTOCOL_TCP shl 8 + 0
; add ebx, 20
; mov [pseudoHeader + 10], bh
; mov [pseudoHeader + 11], bl
;
; mov eax, pseudoHeader
; mov [checkAdd1], eax
; mov word[checkSize1], 12
; mov eax, edx
; add eax, 20
; mov [checkAdd2], eax
; mov eax, ebx
; mov [checkSize2], ax
;
; call checksum
 
mov eax, pseudoHeader
mov [checkAdd1], eax
mov word[checkSize1], 12
mov eax, edx
add eax, 20
mov [checkAdd2], eax
mov eax, ebx
mov [checkSize2], ax
 
call checksum
 
; store it in the TCP checksum ( in the correct order! )
mov ax, [checkResult]
rol ax, 8
mov [edx + 20 + TCP_Packet.Checksum], ax
; mov ax, [checkResult]
; rol ax, 8
; mov [edx + 20 + TCP_Packet.Checksum], ax
 
; Fill in the IP header checksum
movzx eax, byte [edx + IP_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
and eax, 0x0000000F ;
shl eax, 2 ;
 
; movzx eax, byte [edx + IP_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
; and eax, 0x0000000F ;
; shl eax, 2 ;
;
stdcall checksum_jb, edx, eax ; buf_ptr, buf_size
rol ax, 8
mov [edx + IP_Packet.HeaderChecksum], ax
; mov [edx + IP_Packet.HeaderChecksum], ax
 
 
.exit:
 
call kernel_free
add esp, 4 ; pop (balance stack)
 
ret
endp
;endp
 
 
; Increments the 32 bit value pointed to by esi in internet order
proc inc_inet_esi stdcall
push eax
mov eax, [esi]
bswap eax
inc eax
bswap eax
mov [esi], eax
pop eax
ret
; push eax
; mov eax, [esi]
; bswap eax
; inc eax
; bswap eax
; mov [esi], eax
; pop eax
; ret
inc byte[esi+0]
adc byte[esi+1],0
adc byte[esi+2],0
adc byte[esi+3],0
endp
 
 
591,7 → 658,7
xor ecx, ecx
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
; cmp ecx, NUMRESENDENTRIES
je .call_handler ; None left
cmp [esi + 4], eax
je @f ; found one
606,8 → 673,8
 
push ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
imul edi, ecx, IPBUFFSIZE
add edi, resendBuffer
; imul edi, ecx, IPBUFFSIZE
; add edi, resendBuffer
 
; we have dest buffer location in edi. incoming Packet in edx.
; Get this Packets sequence number
668,41 → 735,41
; We have a SYN. update the socket with this IP Packets details,
; And send a response
 
mov eax, [edx + IP_Packet.SourceAddress]
mov [ebx + SOCKET.RemoteIP], eax
mov ax, [edx + 20 + TCP_Packet.SourcePort]
mov [ebx + SOCKET.RemotePort], ax
mov eax, [edx + 20 + TCP_Packet.SequenceNumber]
mov [ebx + SOCKET.IRS], eax
mov [ebx + SOCKET.RCV_NXT], eax
lea esi, [ebx + SOCKET.RCV_NXT]
call inc_inet_esi ; RCV.NXT
mov eax, [ebx + SOCKET.ISS]
mov [ebx + SOCKET.SND_NXT], eax
 
; mov eax, [edx + IP_Packet.SourceAddress]
; mov [ebx + SOCKET.RemoteIP], eax
; mov ax, [edx + 20 + TCP_Packet.SourcePort]
; mov [ebx + SOCKET.RemotePort], ax
; mov eax, [edx + 20 + TCP_Packet.SequenceNumber]
; mov [ebx + SOCKET.IRS], eax
; mov [ebx + SOCKET.RCV_NXT], eax
; lea esi, [ebx + SOCKET.RCV_NXT]
; call inc_inet_esi ; RCV.NXT
; mov eax, [ebx + SOCKET.ISS]
; mov [ebx + SOCKET.SND_NXT], eax
;
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
; je .exit
 
push eax
mov bl, TH_SYN + TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_Packet, [sockAddr]
; stdcall build_tcp_Packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
; mov eax, NET1OUT_QUEUE
;;; mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
; mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
;;; call queue
 
mov esi, [sockAddr]
mov [esi + SOCKET.TCBState], TCB_SYN_RECEIVED
747,9 → 814,9
 
; Send an ACK
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
pop ebx
je .exit
 
757,19 → 824,19
 
xor ecx, ecx
xor esi, esi
stdcall build_tcp_Packet, [sockAddr]
; stdcall build_tcp_Packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
; mov eax, NET1OUT_QUEUE
;;; mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
; mov ecx, [sockAddr]
; cmp edx, [ecx + SOCKET.RemoteIP]
; jne .not_local
; mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
;;; call queue
 
.exit:
ret
822,13 → 889,13
mov ecx, 0
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
je .last_resendq ; None left
cmp [esi + 4], eax
je @f ; found one
inc ecx
add esi, 8
jmp .next_resendq
; cmp ecx, NUMRESENDENTRIES
; je .last_resendq ; None left
; cmp [esi + 4], eax
; je @f ; found one
; inc ecx
; add esi, 8
; jmp .next_resendq
 
@@: mov dword[esi + 4], 0
inc ecx
881,7 → 948,7
 
 
; Read the data bytes, store in socket buffer
movzx ecx, [edx + IP_Packet.TotalLength]
; movzx ecx, [edx + IP_Packet.TotalLength]
xchg cl, ch
sub ecx, 40 ; Discard 40 bytes of header
ja .data ; Read data, if any
943,9 → 1010,9
.ack:
; Send an ACK
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
je .exit
 
push eax
953,20 → 1020,20
mov bl, TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_Packet, [sockAddr]
; stdcall build_tcp_Packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
; mov eax, NET1OUT_QUEUE
 
;;; mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
; mov ecx, [sockAddr]
; cmp edx, [ecx + SOCKET.RemoteIP]
; jne .not_local
; mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
;;; call queue
 
.exit:
ret
1000,9 → 1067,9
call inc_inet_esi
 
; Send an ACK
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
je .exit
 
push eax
1010,19 → 1077,19
mov bl, TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_Packet, [sockAddr]
; stdcall build_tcp_Packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
; mov eax, NET1OUT_QUEUE
;;; mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
; mov ecx, [sockAddr]
; cmp edx, [ecx + SOCKET.RemoteIP]
; jne .not_local
; mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
;;; call queue
 
.exit:
ret
1040,10 → 1107,10
call inc_inet_esi
 
; Send an ACK
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
; mov eax, EMPTY_QUEUE
; call dequeue
;; cmp ax, NO_BUFFER
; je .exit
 
push eax
 
1050,19 → 1117,19
mov bl, TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_Packet, [sockAddr]
; stdcall build_tcp_Packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
; mov eax, NET1OUT_QUEUE
;;; mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
; mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
;;; call queue
 
.exit:
ret
1119,8 → 1186,8
; @param EDX is pointer to application data buffer
; @return 0 (sent successfully) or -1 (error) in EAX
;;
proc socket_write_tcp stdcall
local sockAddr dd ?
;proc socket_write_tcp stdcall
;local sockAddr dd ?
 
; DEBUGF 1, "socket_write_tcp(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx
1128,16 → 1195,16
jz .error
 
mov ebx, eax
mov [sockAddr], ebx
; mov [sockAddr], ebx
 
; If the sockets window timer is nonzero, do not queue Packet
cmp [ebx + SOCKET.wndsizeTimer], 0
jne .error
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .error
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
; je .error
 
push eax
 
1152,7 → 1219,7
 
push ecx
mov bl, TH_ACK
stdcall build_tcp_Packet, [sockAddr]
; stdcall build_tcp_Packet, [sockAddr]
pop ecx
 
; Check destination IP address.
1161,24 → 1228,24
pop ebx
push ecx
 
mov eax, NET1OUT_QUEUE
; mov eax, NET1OUT_QUEUE
;;; TODO: get device id in edx
xor edx, edx
 
shl edx, 2
mov edx, [IP_LIST+edx]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
; mov ecx, [sockAddr]
; cmp edx, [ecx + SOCKET.RemoteIP]
; jne .not_local
; mov eax, IPIN_QUEUE
 
.not_local:
pop ecx
push ebx ; save ipbuffer number
 
call queue
;;;; call queue
 
mov esi, [sockAddr]
; mov esi, [sockAddr]
 
; increament SND.NXT in socket
; Amount to increment by is in ecx
1193,7 → 1260,7
mov ecx, 0
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
; cmp ecx, NUMRESENDENTRIES
je .exit ; None found
cmp dword[esi + 4], 0
je @f ; found one
1211,7 → 1278,7
; retry time
; fill IP buffer associated with this descriptor
 
stdcall net_socket_addr_to_num, [sockAddr]
; stdcall net_socket_addr_to_num, [sockAddr]
mov [esi + 4], eax
mov byte[esi + 1], TCP_RETRIES
mov word[esi + 2], TCP_TIMEOUT
1218,21 → 1285,21
 
inc ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
mov edi, resendBuffer - IPBUFFSIZE
; mov edi, resendBuffer - IPBUFFSIZE
 
@@: add edi, IPBUFFSIZE
; @@: add edi, IPBUFFSIZE
loop @b
 
; we have dest buffer location in edi
pop eax
; convert source buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
mov esi, eax
; mov ecx, IPBUFFSIZE
; mul ecx
; add eax, IPbuffs
; mov esi, eax
 
; do copy
mov ecx, IPBUFFSIZE
; mov ecx, IPBUFFSIZE
; cld
rep movsb
 
1243,7 → 1310,7
.error:
or eax, -1
ret
endp
;endp
 
 
 
1262,10 → 1329,10
 
checksum:
pusha
mov eax, [checkAdd1]
; mov eax, [checkAdd1]
xor edx, edx ; edx is the accumulative checksum
xor ebx, ebx
mov cx, [checkSize1]
; mov cx, [checkSize1]
shr cx, 1
jz cs1_1
 
1279,7 → 1346,7
loopw cs1
 
cs1_1:
and word [checkSize1], 0x01
; and word [checkSize1], 0x01
jz cs_test2
 
mov bh, [eax]
1288,11 → 1355,11
add edx, ebx
 
cs_test2:
mov cx, [checkSize2]
; mov cx, [checkSize2]
cmp cx, 0
jz cs_exit ; Finished if no 2nd buffer
 
mov eax, [checkAdd2]
; mov eax, [checkAdd2]
 
shr cx, 1
jz cs2_1
1307,7 → 1374,7
loopw cs2
 
cs2_1:
and word [checkSize2], 0x01
; and word [checkSize2], 0x01
jz cs_exit
 
mov bh, [eax]
1326,21 → 1393,7
add edx, eax
not dx
 
mov [checkResult], dx
; mov [checkResult], dx
popa
ret
 
 
 
 
 
TCP_HANDLER:
;;; TODO: write code here
 
call kernel_free
add esp, 4 ; pop (balance stack)
 
ret