⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp.inc

📁 MenuetOS是一个用汇编开发的32/64位PC操作系统
💻 INC
📖 第 1 页 / 共 3 页
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                 ;;
;;  TCP.INC                                                        ;;
;;                                                                 ;;
;;  TCP Processes for Menuet OS  TCP/IP stack                      ;;
;;                                                                 ;;
;;  Version 0.6  4th July 2004                                       ;;
;;                                                                 ;;
;;  Copyright 2002 Mike Hibbett, mikeh@oceanfree.net               ;;
;;                                                                 ;;
;;  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                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   
   
;*******************************************************************
;   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
;       tcp_tcb_handler     1s timer, to erase tcb's in TIME_WAIT state
;
;*******************************************************************
   


;***************************************************************************
;   Function
;      tcp_tcb_handler
;
;   Description
;       Handles sockets in the timewait state, closing them
;       when the TCB timer expires
;
;***************************************************************************
tcp_tcb_handler:
    ; scan through all the sockets, decrementing active timers
    
    mov     eax, SOCKETBUFFSIZE * NUM_SOCKETS
    mov     ecx, NUM_SOCKETS
   
tth1:
    sub     eax, SOCKETBUFFSIZE
    cmp     [eax + sockets + 32], dword 0
    jne     tth2

tth1a:
    cmp     [eax + sockets + 72], dword 0
    jne     tth4
        
    loop    tth1
    ret

tth2: 
    ; decrement it, delete socket if TCB timer = 0 & socket in timewait state
    pusha
    dec     dword [eax + sockets + 32]
    cmp     [eax + sockets + 32], dword 0
    jne     tth3
    
    cmp     [eax + sockets + 28], dword TCB_TIME_WAIT
    jne     tth3
    
    ; OK, delete socket
    mov     edi, eax
    add     edi, sockets
    
    xor     eax, eax
    mov     ecx, SOCKETHEADERSIZE
    cld
    rep     stosb
    
tth3:
    popa
    
    jmp     tth1a
    
    loop    tth1
    ret
    
    ; TODO - prove it works!
tth4:
    dec     dword [eax + sockets + 72]    
    loop    tth1
    ret
    
    
    

tth_exit:
    ret
    

;***************************************************************************
;   Function
;      tcp_tx_handler
;
;   Description
;       Handles queued TCP data
;       This is a kernel function, called by stack_handler
;
;***************************************************************************
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

    mov     esi, resendQ
    mov     ecx, 0
    
tth001:
    cmp     ecx, NUMRESENDENTRIES
    je      tth003              ; None left
    cmp     [esi], byte 0xFF
    jne      tth002             ; found one
    inc     ecx
    add     esi, 4
    jmp     tth001

tth002:    
    ; we have one. decrement it's timer by 1
    dec     word [esi+2]
    mov     ax, [esi+2]
    cmp     ax, 0
    je     tth002a
    inc     ecx
    add     esi, 4
    jmp     tth001              ; Timer not zero, so move on

tth002a:   
    mov     bl, 0xff 
    ; restart timer, and decrement retries
    ; After the first resend, back of on next, by a factor of 5
    mov     [esi+2], word TCP_TIMEOUT * 5
    dec     byte [esi+1]
    mov     al, [esi+1]
    cmp     al, 0
    jne     tth004
    
    ; retries now 0, so delete from queue
    xchg     [esi], bl
tth004:

    ; resend packet
    pusha   

    mov     eax, EMPTY_QUEUE
    call    dequeue
    cmp     ax, NO_BUFFER
    jne      tth004z              
    
    ; TODO - try again in 10ms.
    cmp     bl, 0xff
    jne     tth004za
    mov     [esi], bl
    
tth004za:    
    ; Mark it to expire in 10ms - 1 tick
    mov     [esi+1], byte 1
    mov     [esi+2], word 1
    jmp     tth005

tth004z:    
    ; we have a buffer # in ax
    
    push    eax
    push    ecx
    mov     ecx, IPBUFFSIZE
    mul     ecx
    add     eax, IPbuffs

    ; we have the buffer address in eax
    mov     edi, eax
    pop     ecx
    ; get resend data address
    inc     ecx
    ; Now get buffer location, and copy buffer across. argh! more copying,,
    mov     esi, resendBuffer - IPBUFFSIZE
tth004a:
    add     esi, IPBUFFSIZE
    loop    tth004a
   
    ; we have resend buffer location in esi
    mov     ecx, IPBUFFSIZE
    
    ; copy data across
    cld
    rep     movsb
    
    ; queue packet
    
    
    
    mov     eax, NET1OUT_QUEUE

    mov     edx, [stack_ip]
    mov     ecx, [ edi + 16 ]
    cmp     edx, ecx
    jne     tth004b
    mov     eax, IPIN_QUEUE
    
tth004b:
    pop     ebx
    
    call    queue
       

tth005:    
    popa    
    
    inc     ecx
    add     esi, 4
    jmp     tth001

tth003:    
    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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -