📄 tcp.inc
字号:
; 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 is default ).I could accept 4KB, fa0, ( skt buffer size)
; 768 bytes seems better
mov ax, 0x0003
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
cmp al, 0
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
; as a packet has been received, update the TCB timer
mov ecx, TWOMSL
mov [ebx + 32], ecx
; If the received packet has an ACK bit set,
; remove any packets in the resend queue that this
; received packet acknowledges
pusha
mov cl, [edx + 33]
and cl, 0x10
cmp cl, 0x10
jne tsm001 ; No ACK, so no data yet
; get skt number in al
shr eax, 12
; The ack number is in [edx + 28], inet format
; skt in al
mov esi, resendQ
mov ecx, 0
t001:
cmp ecx, NUMRESENDENTRIES
je t003 ; None left
cmp [esi], al
je t002 ; found one
inc ecx
add esi, 4
jmp t001
t002: ; Can we delete this buffer?
; If yes, goto t004. No, goto t001
; Get packet data address
push ecx
inc ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
mov edi, resendBuffer - IPBUFFSIZE
t002a:
add edi, IPBUFFSIZE
loop t002a
; we have dest buffer location in edi. incoming packet in edx.
; Get this packets sequence number
; preserve al, ecx, esi, edx
mov cl, [edi + 24]
shl ecx, 8
mov cl, [edi + 25]
shl ecx, 8
mov cl, [edi + 26]
shl ecx, 8
mov cl, [edi + 27]
movzx ebx, byte [edi + 3]
mov bh, [edi + 2]
sub ebx, 40
add ecx, ebx ; ecx is now seq# of last byte +1, intel format
; get recievd ack #, in intel format
mov bl, [edx + 28]
shl ebx, 8
mov bl, [edx + 29]
shl ebx, 8
mov bl, [edx + 30]
shl ebx, 8
mov bl, [edx + 31]
cmp ebx, ecx ; Finally. ecx = rx'ed ack. ebx = last byte in que
; DANGER! need to handle case that we have just
; passed the 2**32, and wrapped round!
pop ecx
jae t004 ; if rx > old, delete old
inc ecx
add esi, 4
jmp t001
t004:
dec dword [arp_rx_count] ; ************ TEST ONLY!
mov [esi], byte 0xFF
inc ecx
add esi, 4
jmp t001
t003:
tsm001:
popa
; 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:
; In this case, we are expecting a SYN packet
; For now, if the packet is a SYN, process it, and send a response
; If not, ignore it
; Look at control flags
mov bl, [edx + 33]
and bl, 0x02
cmp bl, 0x02
jnz stl_exit
; We have a SYN. update the socket with this IP packets details,
; And send a response
mov ebx, [edx + 12] ; IP source address
mov [eax + sockets + 16], ebx
mov bx, [edx + 20] ; IP source port
mov [eax + sockets + 20], bx
mov ebx, [edx + 24] ; IRS
mov [eax + sockets + 40], ebx
mov [eax + sockets + 56], ebx
mov esi, sockets
add esi, eax
add esi, 56
call inc_inet_esi ; RCV.NXT
mov ebx, [eax + sockets + 36] ; ISS
mov [eax + sockets + 48], ebx ; SND.NXT
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je stl_exit
push eax
mov bl, 0x12 ; SYN + ACK
mov ecx, 0
mov esi, 0
call buildTCPPacket
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne stl_notlocal
mov eax, IPIN_QUEUE
stl_notlocal:
; Send it.
pop ebx
call queue
mov ebx, TCB_SYN_RECEIVED
mov esi, [sktAddr]
mov [esi + 28], ebx
; increament SND.NXT in socket
add esi, 48
call inc_inet_esi
stl_exit:
ret
stateTCB_SYN_SENT:
; We are awaiting an ACK to our SYN, with a SYM
; Look at control flags - expecting an ACK
mov bl, [edx + 33]
and bl, 0x12
cmp bl, 0x12
jnz stss_exit
mov ebx, TCB_ESTABLISHED
mov esi, [sktAddr]
mov [esi + 28], ebx
; Store the recv.nxt field
mov eax, [edx + 24]
; Update our recv.nxt field
mov esi, [sktAddr]
add esi, 56
mov [esi], eax
call inc_inet_esi
; Send an ACK
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je stss_exit
push eax
mov bl, 0x10 ; ACK
mov ecx, 0
mov esi, 0
call buildTCPPacket
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne stss_notlocal
mov eax, IPIN_QUEUE
stss_notlocal:
; Send it.
pop ebx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -