📄 tcp.inc
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; TCP.INC ;;
;; ;;
;; TCP Processes for Menuet OS TCP/IP stack ;;
;; ;;
;; Version 0.3 29 August 2002 ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;*******************************************************************
; Interface
;
; tcp_tx_handler Handles the TCP transmit queue
; tcp_rx The protocol handler for received data
; buildTCPPacket fills in the packet headers and data
; tcpStateMachine Main state machine for received TCP packets
;
;*******************************************************************
;***************************************************************************
; Function
; tcp_tx_handler
;
; Description
; Handles queued TCP data
; This is a kernel function, called by stack_handler
;
;***************************************************************************
tcp_tx_handler:
ret
;***************************************************************************
; 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_rx:
; 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.
push eax
; Look for a socket where
; IP Packet TCP Destination Port = local Port
; IP Packet SA = Remote IP
; IP Packet TCP Source Port = remote Port
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
ss1:
sub eax, SOCKETBUFFSIZE
movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr
cmp [eax + sockets + 12], bx ; compare with socket's local port
jnz nxttst1 ; different - try next socket
movzx ebx, word [edx + 20] ; get the source port from the TCP hdr
cmp [eax + sockets + 20], bx ; compare with socket's remote port
jnz nxttst1 ; different - try next socket
mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr
cmp [eax + sockets + 16], ebx ; compare with socket's remote IP
jnz nxttst1 ; different - try next socket
; We have a complete match - use this socket
jmp tcprx_001
nxttst1:
loop ss1 ; Return back if no match
; If we got here, there was no match
; Look for a socket where
; IP Packet TCP Destination Port = local Port
; IP Packet SA = Remote IP
; socket remote Port = 0
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
ss2:
sub eax, SOCKETBUFFSIZE
movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr
cmp [eax + sockets + 12], bx ; compare with socket's local port
jnz nxttst2 ; different - try next socket
mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr
cmp [eax + sockets + 16], ebx ; compare with socket's remote IP
jnz nxttst2 ; different - try next socket
mov ebx, 0
cmp [eax + sockets + 20], bx ; only match a remote socket of 0
jnz nxttst2 ; different - try next socket
; We have a complete match - use this socket
jmp tcprx_001
nxttst2:
loop ss2 ; Return back if no match
; If we got here, there was no match
; Look for a socket where
; IP Packet TCP Destination Port = local Port
; socket Remote IP = 0
; socket remote Port = 0
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
ss3:
sub eax, SOCKETBUFFSIZE
movzx ebx, word [edx + 22] ; get destination port from the TCP hdr
cmp [eax + sockets + 12], bx ; compare with socket's local port
jnz nxttst3 ; different - try next socket
mov ebx, 0
cmp [eax + sockets + 20], bx ; only match a remote socket of 0
jnz nxttst3 ; different - try next socket
mov ebx, 0
cmp [eax + sockets + 16], ebx ; only match a socket remote IP of 0
jnz nxttst3 ; different - try next socket
; We have a complete match - use this socket
jmp tcprx_001
nxttst3:
loop ss3 ; Return back if no match
; If we got here, we need to reject the packet
inc dword [dumped_rx_count]
jmp tcprx_exit
tcprx_001:
; We have a valid socket/TCB, so call the TCB State Machine for that skt.
; socket is pointed to by [eax + sockets]
; IP packet is pointed to by [edx]
; IP buffer number is on stack ( it will be popped at the end)
call tcpStateMachine
tcprx_exit:
pop eax
call freeBuff
ret
;***************************************************************************
; Function
; buildTCPPacket
;
; Description
; builds an IP Packet with TCP data fully populated for transmission
; You may destroy any and all registers
; TCP control flags specified in bl
; This TCB is in [sktAddr]
; User data pointed to by esi
; Data length in ecx
; Transmit buffer number in eax
;
;***************************************************************************
buildTCPPacket:
push ecx ; Save data length
; convert buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
mov edx, eax
mov [edx + 33], bl ; TCP flags
mov ebx, [sktAddr]
; 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 + 8]
mov [edx + 12], eax ; source IP
mov eax, [ebx + 16]
mov [edx + 16], eax ; Destination IP
mov al, 0x45
mov [edx], al ; Version, IHL
xor al, al
mov [edx + 1], al ; Type of service
pop eax ; Get the TCP data length
push eax
add eax, 20 + 20 ; add IP header and TCP header lengths
mov [edx + 2], ah
mov [edx + 3], al
xor al, al
mov [edx + 4], al
mov [edx + 5], al
mov al, 0x40
mov [edx + 6], al
xor al, al
mov [edx + 7], al
mov al, 0x20
mov [edx + 8], al
mov al, 6 ; TCP protocol
mov [edx + 9], al
; Checksum left unfilled
xor ax, ax
mov [edx + 10], ax
; Fill in the TCP header ( some data is in the socket descriptor)
mov ax, [ebx + 12]
mov [edx + 20], ax ; Local Port
mov ax, [ebx + 20]
mov [edx + 20 + 2], ax ; desitination Port
; Checksum left unfilled
xor ax, ax
mov [edx + 20 + 16], ax
; sequence number
mov eax, [ebx + 48]
mov [edx + 20 + 4], eax
; ack number
mov eax, [ebx + 56]
mov [edx + 20 + 8], eax
; window ( 0x2000 )
mov ax, 0x0020
mov [edx + 20 + 14], ax
; Urgent pointer (0)
mov ax, 0
mov [edx + 20 + 18], ax
; data offset ( 0x50 )
mov al, 0x50
mov [edx + 20 + 12], al
pop ecx ; count of bytes to send
mov ebx, ecx ; need the length later
cmp ebx, 0
jz btp_001
mov edi, edx
add edi, 40
cld
rep movsb ; copy the data across
btp_001:
; we have edx as IPbuffer ptr.
; Fill in the TCP checksum
; First, fill in pseudoheader
mov eax, [edx + 12]
mov [pseudoHeader], eax
mov eax, [edx + 16]
mov [pseudoHeader+4], eax
mov ax, 0x0600 ; 0 + protocol
mov [pseudoHeader+8], ax
add ebx, 20
mov eax, ebx
mov [pseudoHeader+10], ah
mov [pseudoHeader+11], al
mov eax, pseudoHeader
mov [checkAdd1], eax
mov [checkSize1], word 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]
mov [edx + 20 + 16], ah
mov [edx + 20 + 17], al
; Fill in the IP header checksum
mov eax, edx
mov [checkAdd1], eax
mov [checkSize1], word 20
mov [checkAdd2], dword 0
mov [checkSize2], word 0
call checksum
mov ax, [checkResult]
mov [edx + 10], ah
mov [edx + 11], al
ret
; Increments the 32 bit value pointed to by esi in internet order
inc_inet_esi:
push eax
add esi, 3
mov al, byte[esi]
inc al
mov byte[esi], al
cmp al, 0
jnz iie_exit
dec esi
mov al, byte[esi]
inc al
mov byte[esi], al
cmp al, 0
jnz iie_exit
dec esi
mov al, byte[esi]
inc al
mov byte[esi], al
jnz iie_exit
dec esi
mov al, byte[esi]
inc al
mov byte[esi], al
iie_exit:
pop eax
ret
; Increments the 32 bit value pointed to by esi in internet order
; by the value in ecx
add_inet_esi:
push eax
mov al, [esi]
shl eax, 8
inc esi
mov al, [esi]
shl eax, 8
inc esi
mov al, [esi]
shl eax, 8
inc esi
mov al, [esi]
add eax, ecx
mov [esi], al
dec esi
shr eax, 8
mov [esi], al
dec esi
shr eax, 8
mov [esi], al
dec esi
shr eax, 8
mov [esi], al
pop eax
ret
TCBStateHandler:
dd stateTCB_LISTEN
dd stateTCB_SYN_SENT
dd stateTCB_SYN_RECEIVED
dd stateTCB_ESTABLISHED
dd stateTCB_FIN_WAIT_1
dd stateTCB_FIN_WAIT_2
dd stateTCB_CLOSE_WAIT
dd stateTCB_CLOSING
dd stateTCB_LAST_ACK
dd stateTCB_TIME_WAIT
dd stateTCB_CLOSED
;***************************************************************************
; Function
; tcpStateMachine
;
; Description
; TCP state machine
; This is a kernel function, called by tcp_rx
;
; IP buffer address given in [edx]
; Socket/TCB address in [eax + sockets]
;
; The IP buffer will be released by the caller
;***************************************************************************
tcpStateMachine:
mov ebx, sockets
add ebx, eax
mov [sktAddr], ebx
; Call handler for given TCB state
mov ebx, [eax + sockets+28]
cmp ebx, TCB_LISTEN
jb tsm_exit
cmp ebx, TCB_CLOSED
ja tsm_exit
dec ebx
call dword [TCBStateHandler+ebx*4]
tsm_exit:
ret
stateTCB_LISTEN:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -