Subversion Repositories Kolibri OS

Rev

Rev 380 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. $Revision: 425 $
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;                                                                 ;;
  4. ;;  TCP.INC                                                        ;;
  5. ;;                                                                 ;;
  6. ;;  TCP Processes for Menuet OS  TCP/IP stack                      ;;
  7. ;;                                                                 ;;
  8. ;;  Version 0.6  4th July 2004                                       ;;
  9. ;;                                                                 ;;
  10. ;;  Copyright 2002 Mike Hibbett, mikeh@oceanfree.net               ;;
  11. ;;                                                                 ;;
  12. ;;  See file COPYING for details                                   ;;
  13. ;;  v0.6 : Added reset handling in the established state           ;;
  14. ;;         Added a timer per socket to allow delays when rx window ;;
  15. ;;         gets below 1KB                                          ;;
  16. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  17.  
  18. ; TCP TCB states
  19. TCB_LISTEN         equ        1
  20. TCB_SYN_SENT       equ        2
  21. TCB_SYN_RECEIVED   equ        3
  22. TCB_ESTABLISHED    equ        4
  23. TCB_FIN_WAIT_1     equ        5
  24. TCB_FIN_WAIT_2     equ        6
  25. TCB_CLOSE_WAIT     equ        7
  26. TCB_CLOSING        equ        8
  27. TCB_LAST_ACK       equ        9
  28. TCB_TIME_WAIT      equ        10
  29. TCB_CLOSED         equ        11
  30.  
  31. TWOMSL              equ     10      ; # of secs to wait before closing socket
  32.  
  33. TCP_RETRIES         equ         5               ; Number of times to resend a packet
  34. TCP_TIMEOUT         equ         10              ; resend if not replied to in x hs
  35.  
  36. ;*******************************************************************
  37. ;   Interface
  38. ;
  39. ;       tcp_tx_handler      Handles the TCP transmit queue
  40. ;       tcp_rx              The protocol handler for received data
  41. ;       buildTCPPacket      fills in the packet headers and data
  42. ;       tcpStateMachine     Main state machine for received TCP packets
  43. ;       tcp_tcb_handler     1s timer, to erase tcb's in TIME_WAIT state
  44. ;
  45. ;*******************************************************************
  46.  
  47.  
  48. ;   TCP Payload ( Data field in IP datagram )
  49. ;
  50. ;    0                   1                   2                   3
  51. ;    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  52. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  53. ;20 |          Source Port          |       Destination Port        |
  54. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  55. ;24 |                        Sequence Number                        |
  56. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  57. ;28 |                    Acknowledgment Number                      |
  58. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  59. ;32 |  Data |           |U|A|P|R|S|F|                               |
  60. ;   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
  61. ;   |       |           |G|K|H|T|N|N|                               |
  62. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  63. ;36 |           Checksum            |         Urgent Pointer        |
  64. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  65. ;40 |                    Options                    |    Padding    |
  66. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  67. ;   |                             data
  68.  
  69.  
  70. struc TCP_PACKET
  71. {  .SourcePort       dw  ?  ;+00
  72.    .DestinationPort  dw  ?  ;+02
  73.    .SequenceNumber   dd  ?  ;+04
  74.    .AckNumber        dd  ?  ;+08
  75.    .DataOffset       db  ?  ;+12 - DataOffset[0-3 bits] and Reserved[4-7]
  76.    .Flags            db  ?  ;+13 - Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN
  77.    .Window           dw  ?  ;+14
  78.    .Checksum         dw  ?  ;+16
  79.    .UrgentPointer    dw  ?  ;+18
  80.    .Options          rb  3  ;+20
  81.    .Padding          db  ?  ;+23
  82.    .Data             db  ?  ;+24
  83. }
  84.  
  85. virtual at 0
  86.   TCP_PACKET TCP_PACKET
  87. end virtual
  88.  
  89.  
  90.  
  91. ;***************************************************************************
  92. ;   Function
  93. ;      tcp_tcb_handler
  94. ;
  95. ;   Description
  96. ;       Handles sockets in the timewait state, closing them
  97. ;       when the TCB timer expires
  98. ;
  99. ;***************************************************************************
  100. tcp_tcb_handler:
  101.     ; scan through all the sockets, decrementing active timers
  102.  
  103.     mov     eax, SOCKETBUFFSIZE * NUM_SOCKETS
  104.     mov     ecx, NUM_SOCKETS
  105.  
  106. tth1:
  107.     sub     eax, SOCKETBUFFSIZE
  108.     cmp     [eax + sockets + 32], dword 0
  109.     jne     tth2
  110.  
  111. tth1a:
  112.     cmp     [eax + sockets + 72], dword 0
  113.     jne     tth4
  114.  
  115.     loop    tth1
  116.     ret
  117.  
  118. tth2:
  119.     ; decrement it, delete socket if TCB timer = 0 & socket in timewait state
  120.     pusha
  121.     dec     dword [eax + sockets + 32]
  122.     cmp     [eax + sockets + 32], dword 0
  123.     jne     tth3
  124.  
  125.     cmp     [eax + sockets + 28], dword TCB_TIME_WAIT
  126.     jne     tth3
  127.  
  128.     ; OK, delete socket
  129.     mov     edi, eax
  130.     add     edi, sockets
  131.  
  132.     xor     eax, eax
  133.     mov     ecx, SOCKETHEADERSIZE
  134.     cld
  135.     rep     stosb
  136.  
  137. tth3:
  138.     popa
  139.  
  140.     jmp     tth1a
  141.  
  142.     loop    tth1
  143.     ret
  144.  
  145.     ; TODO - prove it works!
  146. tth4:
  147.     dec     dword [eax + sockets + 72]
  148.     loop    tth1
  149.     ret
  150.  
  151.  
  152.  
  153.  
  154. tth_exit:
  155.     ret
  156.  
  157.  
  158. ;***************************************************************************
  159. ;   Function
  160. ;      tcp_tx_handler
  161. ;
  162. ;   Description
  163. ;       Handles queued TCP data
  164. ;       This is a kernel function, called by stack_handler
  165. ;
  166. ;***************************************************************************
  167. tcp_tx_handler:
  168.     ; decrement all resend buffers timers. If they
  169.     ; expire, queue them for sending, and restart the timer.
  170.     ; If the retries counter reach 0, delete the entry
  171.  
  172.     mov     esi, resendQ
  173.     mov     ecx, 0
  174.  
  175. tth001:
  176.     cmp     ecx, NUMRESENDENTRIES
  177.     je      tth003              ; None left
  178.     cmp     [esi], byte 0xFF
  179.     jne     tth002              ; found one
  180.     inc     ecx
  181.     add     esi, 4
  182.     jmp     tth001
  183.  
  184. tth002:
  185.     ; we have one. decrement it's timer by 1
  186.     dec     word [esi+2]
  187.     mov     ax, [esi+2]
  188.     cmp     ax, 0
  189.     je      tth002a
  190.     inc     ecx
  191.     add     esi, 4
  192.     jmp     tth001              ; Timer not zero, so move on
  193.  
  194. tth002a:
  195.     mov     bl, 0xff
  196.     ; restart timer, and decrement retries
  197.     ; After the first resend, back of on next, by a factor of 5
  198.     mov     [esi+2], word TCP_TIMEOUT * 5
  199.     dec     byte [esi+1]
  200.     mov     al, [esi+1]
  201.     cmp     al, 0
  202.     jne     tth004
  203.  
  204.     ; retries now 0, so delete from queue
  205.     xchg     [esi], bl
  206. tth004:
  207.  
  208.     ; resend packet
  209.     pusha
  210.  
  211.     mov     eax, EMPTY_QUEUE
  212.     call    dequeue
  213.     cmp     ax, NO_BUFFER
  214.     jne      tth004z
  215.  
  216.     ; TODO - try again in 10ms.
  217.     cmp     bl, 0xff
  218.     jne     tth004za
  219.     mov     [esi], bl
  220.  
  221. tth004za:
  222.     ; Mark it to expire in 10ms - 1 tick
  223.     mov     [esi+1], byte 1
  224.     mov     [esi+2], word 1
  225.     jmp     tth005
  226.  
  227. tth004z:
  228.     ; we have a buffer # in ax
  229.  
  230.     push    eax
  231.     push    ecx
  232.     mov     ecx, IPBUFFSIZE
  233.     mul     ecx
  234.     add     eax, IPbuffs
  235.  
  236.     ; we have the buffer address in eax
  237.     mov     edi, eax
  238.     pop     ecx
  239.     ; get resend data address
  240.     inc     ecx
  241.     ; Now get buffer location, and copy buffer across. argh! more copying,,
  242.     mov     esi, resendBuffer - IPBUFFSIZE
  243. tth004a:
  244.     add     esi, IPBUFFSIZE
  245.     loop    tth004a
  246.  
  247.     ; we have resend buffer location in esi
  248.     mov     ecx, IPBUFFSIZE
  249.  
  250.     ; copy data across
  251.     cld
  252.     rep     movsb
  253.  
  254.     ; queue packet
  255.  
  256.  
  257.  
  258.     mov     eax, NET1OUT_QUEUE
  259.  
  260.     mov     edx, [stack_ip]
  261.     mov     ecx, [ edi + 16 ]
  262.     cmp     edx, ecx
  263.     jne     tth004b
  264.     mov     eax, IPIN_QUEUE
  265.  
  266. tth004b:
  267.     pop     ebx
  268.  
  269.     call    queue
  270.  
  271.  
  272. tth005:
  273.     popa
  274.  
  275.     inc     ecx
  276.     add     esi, 4
  277.     jmp     tth001
  278.  
  279. tth003:
  280.     ret
  281.  
  282.  
  283.  
  284.  
  285. ;***************************************************************************
  286. ;   Function
  287. ;      tcp_rx
  288. ;
  289. ;   Description
  290. ;       TCP protocol handler
  291. ;       This is a kernel function, called by ip_rx
  292. ;       IP buffer address given in edx
  293. ;          IP buffer number in eax
  294. ;          Free up (or re-use) IP buffer when finished
  295. ;
  296. ;***************************************************************************
  297. tcp_rx:
  298.     ; The process is as follows.
  299.     ; Look for a socket with matching remote IP, remote port, local port
  300.     ; if not found, then
  301.     ; look for remote IP + local port match ( where sockets remote port = 0)
  302.     ; if not found, then
  303.     ; look for a socket where local socket port == IP packets remote port
  304.     ; where sockets remote port, remote IP = 0
  305.     ; discard if not found
  306.     ; Call sockets tcbStateMachine, with pointer to packet.
  307.     ; the state machine will not delete the packet, so do that here.
  308.  
  309.     push        eax
  310.  
  311.     ; Look for a socket where
  312.     ; IP Packet TCP Destination Port = local Port
  313.     ; IP Packet SA = Remote IP
  314.     ; IP Packet TCP Source Port = remote Port
  315.  
  316.     mov     eax, SOCKETBUFFSIZE * NUM_SOCKETS
  317.     mov     ecx, NUM_SOCKETS
  318. ss1:
  319.     sub     eax, SOCKETBUFFSIZE
  320.     movzx   ebx, word [edx + 22]     ; get the dest. port from the TCP hdr
  321.     cmp     [eax + sockets + 12], bx ; compare with socket's local port
  322.     jnz     nxttst1                        ; different - try next socket
  323.  
  324.     movzx   ebx, word [edx + 20]       ; get the source port from the TCP hdr
  325.     cmp     [eax + sockets + 20], bx ; compare with socket's remote port
  326.     jnz     nxttst1                        ; different - try next socket
  327.  
  328.  
  329.     mov     ebx, [edx + 12]           ; get the source IP Addr from the IP hdr
  330.     cmp     [eax + sockets + 16], ebx ; compare with socket's remote IP
  331.     jnz     nxttst1                        ; different - try next socket
  332.  
  333.     ; We have a complete match - use this socket
  334.     jmp     tcprx_001
  335.  
  336. nxttst1:
  337.     loop    ss1                     ; Return back if no match
  338.  
  339.     ; If we got here, there was no match
  340.     ; Look for a socket where
  341.     ; IP Packet TCP Destination Port = local Port
  342.     ; IP Packet SA = Remote IP
  343.     ; socket remote Port = 0
  344.  
  345.     mov     eax, SOCKETBUFFSIZE * NUM_SOCKETS
  346.     mov     ecx, NUM_SOCKETS
  347.  
  348. ss2:
  349.     sub     eax, SOCKETBUFFSIZE
  350.  
  351.     movzx   ebx, word [edx + 22]     ; get the dest. port from the TCP hdr
  352.     cmp     [eax + sockets + 12], bx ; compare with socket's local port
  353.     jnz     nxttst2                        ; different - try next socket
  354.  
  355.     mov     ebx, [edx + 12]          ; get the source IP Addr from the IP hdr
  356.     cmp     [eax + sockets + 16], ebx ; compare with socket's remote IP
  357.     jnz     nxttst2                        ; different - try next socket
  358.  
  359.     mov     ebx, 0
  360.     cmp     [eax + sockets + 20], bx ; only match a remote socket of 0
  361.     jnz     nxttst2                        ; different - try next socket
  362.  
  363.     ; We have a complete match - use this socket
  364.     jmp     tcprx_001
  365.  
  366. nxttst2:
  367.     loop    ss2                     ; Return back if no match
  368.  
  369.     ; If we got here, there was no match
  370.     ; Look for a socket where
  371.     ; IP Packet TCP Destination Port = local Port
  372.     ; socket Remote IP = 0
  373.     ; socket remote Port = 0
  374.  
  375.     mov     eax, SOCKETBUFFSIZE * NUM_SOCKETS
  376.     mov     ecx, NUM_SOCKETS
  377.  
  378. ss3:
  379.     sub     eax, SOCKETBUFFSIZE
  380.  
  381.     movzx   ebx, word [edx + 22]     ; get destination port from the TCP hdr
  382.     cmp     [eax + sockets + 12], bx ; compare with socket's local port
  383.     jnz     nxttst3                        ; different - try next socket
  384.  
  385.     mov     ebx, 0
  386.     cmp     [eax + sockets + 20], bx ; only match a remote socket of 0
  387.     jnz     nxttst3                        ; different - try next socket
  388.  
  389.     mov     ebx, 0
  390.     cmp     [eax + sockets + 16], ebx ; only match a socket remote IP of 0
  391.     jnz     nxttst3                        ; different - try next socket
  392.  
  393.     ; We have a complete match - use this socket
  394.     jmp     tcprx_001
  395.  
  396. nxttst3:
  397.     loop    ss3                     ; Return back if no match
  398.  
  399.     ; If we got here, we need to reject the packet
  400.     inc     dword [dumped_rx_count]
  401.     jmp     tcprx_exit
  402.  
  403. tcprx_001:
  404.     ; We have a valid socket/TCB, so call the TCB State Machine for that skt.
  405.     ; socket is pointed to by [eax + sockets]
  406.     ; IP packet is pointed to by [edx]
  407.     ; IP buffer number is on stack ( it will be popped at the end)
  408.     call    tcpStateMachine
  409.  
  410. tcprx_exit:
  411.     pop     eax
  412.     call    freeBuff
  413.  
  414.     ret
  415.  
  416.  
  417.  
  418. ;***************************************************************************
  419. ;   Function
  420. ;      buildTCPPacket
  421. ;
  422. ;   Description
  423. ;       builds an IP Packet with TCP data fully populated for transmission
  424. ;       You may destroy any and all registers
  425. ;          TCP control flags specified in bl
  426. ;          This TCB is in [sktAddr]
  427. ;          User data pointed to by esi
  428. ;       Data length in ecx
  429. ;          Transmit buffer number in eax
  430. ;
  431. ;***************************************************************************
  432. buildTCPPacket:
  433.     push    ecx                        ; Save data length
  434.  
  435.     ; convert buffer pointer eax to the absolute address
  436.     mov     ecx, IPBUFFSIZE
  437.     mul     ecx
  438.     add     eax, IPbuffs
  439.  
  440.     mov     edx, eax
  441.  
  442.     mov     [edx + 33], bl            ; TCP flags
  443.  
  444.     mov     ebx, [sktAddr]
  445.  
  446.     ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
  447.  
  448.     ; Fill in the IP header ( some data is in the socket descriptor)
  449.     mov     eax, [ebx + 8]
  450.     mov     [edx + 12], eax      ; source IP
  451.     mov     eax, [ebx + 16]
  452.     mov     [edx + 16], eax      ; Destination IP
  453.  
  454.     mov     al, 0x45
  455.     mov     [edx], al         ; Version, IHL
  456.     xor     al, al
  457.     mov     [edx + 1], al     ; Type of service
  458.  
  459.     pop     eax                   ; Get the TCP data length
  460.     push    eax
  461.  
  462.     add     eax, 20 + 20           ; add IP header and TCP header lengths
  463.     mov     [edx + 2], ah
  464.     mov     [edx + 3], al
  465.     xor     al, al
  466.     mov     [edx + 4], al
  467.     mov     [edx + 5], al
  468.     mov     al, 0x40
  469.     mov     [edx + 6], al
  470.     xor     al, al
  471.     mov     [edx + 7], al
  472.     mov     al, 0x20
  473.     mov     [edx + 8], al
  474.     mov     al, 6                         ; TCP protocol
  475.     mov     [edx + 9], al
  476.  
  477.     ; Checksum left unfilled
  478.     xor     ax, ax
  479.     mov     [edx + 10], ax
  480.  
  481.     ; Fill in the TCP header ( some data is in the socket descriptor)
  482.     mov     ax, [ebx + 12]
  483.     mov     [edx + 20], ax        ; Local Port
  484.  
  485.     mov     ax, [ebx + 20]
  486.     mov     [edx + 20 + 2], ax    ; desitination Port
  487.  
  488.     ; Checksum left unfilled
  489.     xor     ax, ax
  490.     mov     [edx + 20 + 16], ax
  491.  
  492.     ; sequence number
  493.     mov     eax, [ebx + 48]
  494.     mov     [edx + 20 + 4], eax
  495.  
  496.     ; ack number
  497.     mov     eax, [ebx + 56]
  498.     mov     [edx + 20 + 8], eax
  499.  
  500.     ; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size)
  501.     ; 768 bytes seems better
  502.     mov     ax, 0x0003
  503.     mov     [edx + 20 + 14], ax
  504.  
  505.     ; Urgent pointer (0)
  506.     mov     ax, 0
  507.     mov     [edx + 20 + 18], ax
  508.  
  509.     ; data offset ( 0x50 )
  510.     mov     al, 0x50
  511.     mov     [edx + 20 + 12], al
  512.  
  513.     pop     ecx                  ; count of bytes to send
  514.     mov     ebx, ecx            ; need the length later
  515.  
  516.     cmp     ebx, 0
  517.     jz      btp_001
  518.  
  519.     mov     edi, edx
  520.     add     edi, 40
  521.     cld
  522.     rep     movsb               ; copy the data across
  523.  
  524. btp_001:
  525.     ; we have edx as IPbuffer ptr.
  526.     ; Fill in the TCP checksum
  527.     ; First, fill in pseudoheader
  528.     mov     eax, [edx + 12]
  529.     mov     [pseudoHeader], eax
  530.     mov     eax, [edx + 16]
  531.     mov     [pseudoHeader+4], eax
  532.     mov     ax, 0x0600            ; 0 + protocol
  533.     mov     [pseudoHeader+8], ax
  534.     add     ebx, 20
  535.     mov     eax, ebx
  536.     mov     [pseudoHeader+10], ah
  537.     mov     [pseudoHeader+11], al
  538.  
  539.     mov     eax, pseudoHeader
  540.     mov     [checkAdd1], eax
  541.     mov     [checkSize1], word 12
  542.     mov     eax, edx
  543.     add     eax, 20
  544.     mov     [checkAdd2], eax
  545.     mov     eax, ebx
  546.     mov     [checkSize2], ax
  547.  
  548.     call    checksum
  549.  
  550.     ; store it in the TCP checksum ( in the correct order! )
  551.     mov     ax, [checkResult]
  552.  
  553.     mov     [edx + 20 + 16], ah
  554.     mov     [edx + 20 + 17], al
  555.  
  556.     ; Fill in the IP header checksum
  557.     GET_IHL eax,edx              ; get IP-Header length
  558.     stdcall checksum_jb,edx,eax  ; buf_ptr, buf_size
  559.  
  560.     mov     [edx + 10], ah
  561.     mov     [edx + 11], al
  562.  
  563.     ret
  564.  
  565.  
  566. ; Increments the 32 bit value pointed to by esi in internet order
  567. inc_inet_esi:
  568.     push    eax
  569.     add     esi, 3
  570.     mov     al, byte[esi]
  571.     inc     al
  572.     mov     byte[esi], al
  573.     cmp     al, 0
  574.     jnz     iie_exit
  575.     dec     esi
  576.     mov     al, byte[esi]
  577.     inc     al
  578.     mov     byte[esi], al
  579.     cmp     al, 0
  580.     jnz     iie_exit
  581.     dec     esi
  582.     mov     al, byte[esi]
  583.     inc     al
  584.     mov     byte[esi], al
  585.     cmp     al, 0
  586.     jnz     iie_exit
  587.     dec     esi
  588.     mov     al, byte[esi]
  589.     inc     al
  590.     mov     byte[esi], al
  591.  
  592. iie_exit:
  593.     pop     eax
  594.     ret
  595.  
  596.  
  597. ; Increments the 32 bit value pointed to by esi in internet order
  598. ; by the value in ecx
  599. add_inet_esi:
  600.     push    eax
  601.  
  602.     mov     al, [esi]
  603.     shl     eax, 8
  604.     inc     esi
  605.     mov     al, [esi]
  606.     shl     eax, 8
  607.     inc     esi
  608.     mov     al, [esi]
  609.     shl     eax, 8
  610.     inc     esi
  611.     mov     al, [esi]
  612.     add     eax, ecx
  613.     mov     [esi], al
  614.     dec     esi
  615.     shr     eax, 8
  616.     mov     [esi], al
  617.     dec     esi
  618.     shr     eax, 8
  619.     mov     [esi], al
  620.     dec     esi
  621.     shr     eax, 8
  622.     mov     [esi], al
  623.     pop     eax
  624.     ret
  625.  
  626.  
  627. iglobal
  628.   TCBStateHandler:
  629.     dd      stateTCB_LISTEN
  630.     dd      stateTCB_SYN_SENT
  631.     dd      stateTCB_SYN_RECEIVED
  632.     dd      stateTCB_ESTABLISHED
  633.     dd      stateTCB_FIN_WAIT_1
  634.     dd      stateTCB_FIN_WAIT_2
  635.     dd      stateTCB_CLOSE_WAIT
  636.     dd      stateTCB_CLOSING
  637.     dd      stateTCB_LAST_ACK
  638.     dd      stateTCB_TIME_WAIT
  639.     dd      stateTCB_CLOSED
  640. endg
  641.  
  642. ;***************************************************************************
  643. ;   Function
  644. ;      tcpStateMachine
  645. ;
  646. ;   Description
  647. ;       TCP state machine
  648. ;       This is a kernel function, called by tcp_rx
  649. ;
  650. ;       IP buffer address given in edx
  651. ;          Socket/TCB address in [eax + sockets]
  652. ;
  653. ;       The IP buffer will be released by the caller
  654. ;***************************************************************************
  655. tcpStateMachine:
  656.     mov     ebx, sockets
  657.     add     ebx, eax
  658.     mov     [sktAddr], ebx
  659.  
  660.     ; as a packet has been received, update the TCB timer
  661.     mov     ecx, TWOMSL
  662.     mov     [ebx + 32], ecx
  663.  
  664.     ; If the received packet has an ACK bit set,
  665.     ; remove any packets in the resend queue that this
  666.     ; received packet acknowledges
  667.     pusha
  668.     mov     cl, [edx + 33]
  669.     and     cl, 0x10
  670.     cmp     cl, 0x10
  671.     jne     tsm001                      ; No ACK, so no data yet
  672.  
  673.  
  674.     ; get skt number in al
  675.     shr     eax, 12
  676.  
  677.     ; The ack number is in [edx + 28], inet format
  678.     ; skt in al
  679.  
  680.     mov     esi, resendQ
  681.     mov     ecx, 0
  682.  
  683. t001:
  684.     cmp     ecx, NUMRESENDENTRIES
  685.     je      t003              ; None left
  686.     cmp     [esi], al
  687.     je      t002              ; found one
  688.     inc     ecx
  689.     add     esi, 4
  690.     jmp     t001
  691.  
  692. t002:                   ; Can we delete this buffer?
  693.  
  694.                         ; If yes, goto t004. No, goto t001
  695.     ; Get packet data address
  696.  
  697.     push    ecx
  698.     inc     ecx
  699.     ; Now get buffer location, and copy buffer across. argh! more copying,,
  700.     mov     edi, resendBuffer - IPBUFFSIZE
  701. t002a:
  702.     add     edi, IPBUFFSIZE
  703.     loop    t002a
  704.  
  705.     ; we have dest buffer location in edi. incoming packet in edx.
  706.     ; Get this packets sequence number
  707.     ; preserve al, ecx, esi, edx
  708.  
  709.     mov     cl, [edi + 24]
  710.     shl     ecx, 8
  711.     mov     cl, [edi + 25]
  712.     shl     ecx, 8
  713.     mov     cl, [edi + 26]
  714.     shl     ecx, 8
  715.     mov     cl, [edi + 27]
  716.     movzx   ebx, byte [edi + 3]
  717.     mov     bh, [edi + 2]
  718.     sub     ebx, 40
  719.     add     ecx, ebx          ; ecx is now seq# of last byte +1, intel format
  720.  
  721.     ; get recievd ack #, in intel format
  722.     mov     bl, [edx + 28]
  723.     shl     ebx, 8
  724.     mov     bl, [edx + 29]
  725.     shl     ebx, 8
  726.     mov     bl, [edx + 30]
  727.     shl     ebx, 8
  728.     mov     bl, [edx + 31]
  729.  
  730.     cmp     ebx, ecx        ; Finally. ecx = rx'ed ack. ebx = last byte in que
  731.                             ; DANGER! need to handle case that we have just
  732.                             ; passed the 2**32, and wrapped round!
  733.     pop     ecx
  734.  
  735.     jae     t004             ; if rx > old, delete old
  736.     inc     ecx
  737.     add     esi, 4
  738.     jmp     t001
  739.  
  740.  
  741. t004:
  742.     dec     dword [arp_rx_count] ; ************ TEST ONLY!
  743.  
  744.     mov     [esi], byte 0xFF
  745.     inc     ecx
  746.     add     esi, 4
  747.     jmp     t001
  748.  
  749. t003:
  750.  
  751. tsm001:
  752.     popa
  753.  
  754.     ; Call handler for given TCB state
  755.     mov     ebx, [eax + sockets+28]
  756.     cmp     ebx, TCB_LISTEN
  757.     jb      tsm_exit
  758.     cmp     ebx, TCB_CLOSED
  759.     ja      tsm_exit
  760.  
  761.     dec     ebx
  762.     call    dword [TCBStateHandler+ebx*4]
  763.  
  764. tsm_exit:
  765.     ret
  766.  
  767.  
  768.  
  769. stateTCB_LISTEN:
  770.     ; In this case, we are expecting a SYN packet
  771.     ; For now, if the packet is a SYN, process it, and send a response
  772.     ; If not, ignore it
  773.  
  774.     ; Look at control flags
  775.     mov     bl, [edx + 33]
  776.     and     bl, 0x02
  777.     cmp     bl, 0x02
  778.     jnz     stl_exit
  779.  
  780.     ; We have a SYN. update the socket with this IP packets details,
  781.     ; And send a response
  782.  
  783.     mov     ebx, [edx + 12] ; IP source address
  784.     mov     [eax + sockets + 16], ebx
  785.     mov     bx, [edx + 20] ; IP source port
  786.     mov     [eax + sockets + 20], bx
  787.     mov     ebx, [edx + 24] ; IRS
  788.     mov     [eax + sockets + 40], ebx
  789.     mov     [eax + sockets + 56], ebx
  790.     mov     esi, sockets
  791.     add     esi, eax
  792.     add     esi, 56
  793.     call    inc_inet_esi ; RCV.NXT
  794.     mov     ebx, [eax + sockets + 36]    ; ISS
  795.     mov     [eax + sockets + 48], ebx    ; SND.NXT
  796.  
  797.     ; Now construct the response, and queue for sending by IP
  798.     mov     eax, EMPTY_QUEUE
  799.     call    dequeue
  800.     cmp     ax, NO_BUFFER
  801.     je      stl_exit
  802.  
  803.     push    eax
  804.     mov     bl, 0x12        ; SYN + ACK
  805.     mov     ecx, 0
  806.     mov     esi, 0
  807.  
  808.     call    buildTCPPacket
  809.  
  810.     mov     eax, NET1OUT_QUEUE
  811.     mov     edx, [stack_ip]
  812.     mov     ecx, [ sktAddr ]
  813.     mov     ecx, [ ecx + 16 ]
  814.     cmp     edx, ecx
  815.     jne     stl_notlocal
  816.     mov     eax, IPIN_QUEUE
  817.  
  818. stl_notlocal:
  819.        ; Send it.
  820.     pop     ebx
  821.     call    queue
  822.  
  823.  
  824.     mov     ebx, TCB_SYN_RECEIVED
  825.     mov     esi, [sktAddr]
  826.     mov     [esi + 28], ebx
  827.  
  828.     ; increament SND.NXT in socket
  829.     add     esi, 48
  830.     call    inc_inet_esi
  831.  
  832. stl_exit:
  833.     ret
  834.  
  835.  
  836.  
  837. stateTCB_SYN_SENT:
  838.     ; We are awaiting an ACK to our SYN, with a SYM
  839.     ; Look at control flags - expecting an ACK
  840.     mov     bl, [edx + 33]
  841.     and     bl, 0x12
  842.     cmp     bl, 0x12
  843.     jnz     stss_exit
  844.  
  845.     mov     ebx, TCB_ESTABLISHED
  846.     mov     esi, [sktAddr]
  847.     mov     [esi + 28], ebx
  848.  
  849.     ; Store the recv.nxt field
  850.     mov     eax, [edx + 24]
  851.  
  852.     ; Update our recv.nxt field
  853.     mov     esi, [sktAddr]
  854.     add     esi, 56
  855.     mov     [esi], eax
  856.     call    inc_inet_esi
  857.  
  858.     ; Send an ACK
  859.     ; Now construct the response, and queue for sending by IP
  860.     mov     eax, EMPTY_QUEUE
  861.     call    dequeue
  862.     cmp     ax, NO_BUFFER
  863.     je      stss_exit
  864.  
  865.     push    eax
  866.  
  867.     mov     bl, 0x10        ; ACK
  868.     mov     ecx, 0
  869.     mov     esi, 0
  870.  
  871.     call    buildTCPPacket
  872.  
  873.     mov     eax, NET1OUT_QUEUE
  874.  
  875.     mov     edx, [stack_ip]
  876.     mov     ecx, [ sktAddr ]
  877.     mov     ecx, [ ecx + 16 ]
  878.     cmp     edx, ecx
  879.     jne     stss_notlocal
  880.     mov     eax, IPIN_QUEUE
  881.  
  882. stss_notlocal:
  883.        ; Send it.
  884.     pop     ebx
  885.     call    queue
  886.  
  887. stss_exit:
  888.     ret
  889.  
  890.  
  891.  
  892. stateTCB_SYN_RECEIVED:
  893.     ; In this case, we are expecting an ACK packet
  894.     ; For now, if the packet is an ACK, process it,
  895.     ; If not, ignore it
  896.  
  897.     ; Look at control flags - expecting an ACK
  898.     mov     bl, [edx + 33]
  899.     and     bl, 0x10
  900.     cmp     bl, 0x10
  901.     jnz     stsr_exit
  902.  
  903.     mov     ebx, TCB_ESTABLISHED
  904.     mov     esi, [sktAddr]
  905.     mov     [esi + 28], ebx
  906.  
  907. stsr_exit:
  908.     ret
  909.  
  910.  
  911.  
  912. stateTCB_ESTABLISHED:
  913.     ; Here we are expecting data, or a request to close
  914.     ; OR both...
  915.  
  916.     ; Did we receive a FIN or RST?
  917.     mov     bl, [edx + 33]
  918.     and     bl, 0x05
  919.     cmp     bl, 0
  920.     je      ste_chkack
  921.  
  922.     ; It was a fin or reset.
  923.  
  924.     ; Remove resend entries from the queue  - I dont want to send any more data
  925.     pusha
  926.  
  927.     mov     ebx, [sktAddr]
  928.     sub     ebx, sockets
  929.     shr     ebx, 12             ; get skt #
  930.  
  931.     mov     esi, resendQ
  932.     mov     ecx, 0
  933.  
  934. ste001:
  935.     cmp     ecx, NUMRESENDENTRIES
  936.     je      ste003              ; None left
  937.     cmp     [esi], bl
  938.     je      ste002              ; found one
  939.     inc     ecx
  940.     add     esi, 4
  941.     jmp     ste001
  942.  
  943. ste002:
  944.     dec     dword [arp_rx_count] ; ************ TEST ONLY!
  945.  
  946.     mov     [esi], byte 0xFF
  947.     jmp     ste001
  948.  
  949. ste003:
  950.     popa
  951.  
  952.     ; was it a reset?
  953.     mov     bl, [edx + 33]
  954.     and     bl, 0x04
  955.     cmp     bl, 0x04
  956.     jne     ste003a
  957.  
  958.     mov     esi, [sktAddr]
  959.     mov     ebx, TCB_CLOSED
  960.     mov     [esi + 28], ebx
  961.     jmp     ste_exit
  962.  
  963. ste003a:
  964.     ; Send an ACK to that fin, and enter closewait state
  965.  
  966.     mov     esi, [sktAddr]
  967.     mov     ebx, TCB_CLOSE_WAIT
  968.     mov     [esi + 28], ebx
  969.     add     esi, 56
  970.     mov     eax, [esi]              ; save original
  971.     call    inc_inet_esi
  972.     ;; jmp    ste_ack - NO, there may be data
  973.  
  974. ste_chkack:
  975.     ; Check that we received an ACK
  976.     mov     bl, [edx + 33]
  977.     and     bl, 0x10
  978.     cmp     bl, 0x10
  979.     jnz     ste_exit
  980.  
  981.  
  982.     ; TODO - done, I think!
  983.     ; First, look at the incoming window. If this is less than or equal to 1024,
  984.     ; Set the socket window timer to 1. This will stop an additional packets being
  985.     ; queued.
  986.     ; ** I may need to tweak this value, since I do not know how many packets are already queued
  987.     mov     ch, [edx + 34]
  988.     mov     cl, [edx + 35]
  989.     cmp     cx, 1024
  990.     ja      ste004
  991.  
  992.     mov     ecx, [sktAddr]
  993.     mov     [ecx+72], dword 1
  994.  
  995. ste004:
  996.  
  997.     ; OK, here is the deal
  998.     ; My recv.nct field holds the seq of the expected next rec byte
  999.     ; if the recevied sequence number is not equal to this, do not
  1000.     ; increment the recv.nxt field, do not copy data - just send a
  1001.     ; repeat ack.
  1002.  
  1003.     ; recv.nxt is in dword [edx+24], in inext format
  1004.     ; recv seq is in [sktAddr]+56, in inet format
  1005.     ; just do a comparision
  1006.     mov     ecx, [sktAddr]
  1007.     add     ecx, 56
  1008.  
  1009.     cmp     [ecx - 56 + 28], dword TCB_CLOSE_WAIT
  1010.     mov     ecx, [ecx]
  1011.     jne     stenofin
  1012.     mov     ecx, eax
  1013.  
  1014. stenofin:
  1015.     cmp     ecx, [edx+24]
  1016.     jne     ste_ack
  1017.  
  1018.  
  1019.     ; Read the data bytes, store in socket buffer
  1020.     xor     ecx, ecx
  1021.     mov     ch, [edx + 2]
  1022.     mov     cl, [edx + 3]
  1023.     sub     ecx, 40                    ; Discard 40 bytes of header
  1024.  
  1025.     cmp     ecx, 0
  1026.     jnz     ste_data                ; Read data, if any
  1027.  
  1028.     ; If we had received a fin, we need to ACK it.
  1029.     mov     esi, [sktAddr]
  1030.     mov     ebx, [esi + 28]
  1031.     cmp     ebx, TCB_CLOSE_WAIT
  1032.     jz      ste_ack
  1033.     jnz     ste_exit
  1034.  
  1035. ste_data:
  1036.     push    ecx
  1037.     mov     esi, [sktAddr]
  1038.  
  1039.     add     [esi + 24], ecx      ; increment the count of bytes in buffer
  1040.  
  1041.     mov     eax, [esi + 4]       ; get socket owner PID
  1042.     push    eax
  1043.  
  1044.     mov     eax, [esi + 24]      ; get # of bytes already in buffer
  1045.  
  1046.     ; point to the location to store the data
  1047.     add     esi, eax
  1048.     sub     esi, ecx
  1049.     add     esi, SOCKETHEADERSIZE
  1050.  
  1051.     add     edx, 40        ; edx now points to the data
  1052.     mov     edi, esi
  1053.     mov     esi, edx
  1054.  
  1055.     cld
  1056.     rep     movsb          ; copy the data across
  1057.  
  1058.     ; flag an event to the application
  1059.     pop     eax
  1060.     mov     ecx,1
  1061.     mov     esi,TASK_DATA+TASKDATA.pid
  1062.  
  1063. news:
  1064.     cmp     [esi],eax
  1065.     je      foundPID1
  1066.     inc     ecx
  1067.     add     esi,0x20
  1068.     cmp     ecx,[TASK_COUNT]
  1069.     jbe     news
  1070.  
  1071. foundPID1:
  1072.     shl     ecx,8
  1073.     or      dword [ecx+SLOT_BASE+APPDATA.event_mask],dword 10000000b ; stack event
  1074.  
  1075.     pop     ecx
  1076.  
  1077.     ; Update our recv.nxt field
  1078.     mov     esi, [sktAddr]
  1079.     add     esi, 56
  1080.     call    add_inet_esi
  1081.  
  1082. ste_ack:
  1083.     ; Send an ACK
  1084.     ; Now construct the response, and queue for sending by IP
  1085.     mov     eax, EMPTY_QUEUE
  1086.     call    dequeue
  1087.     cmp     ax, NO_BUFFER
  1088.     je      ste_exit
  1089.  
  1090.     push    eax
  1091.  
  1092.     mov     bl, 0x10        ; ACK
  1093.     mov     ecx, 0
  1094.     mov     esi, 0
  1095.  
  1096.     call    buildTCPPacket
  1097.  
  1098.     mov     eax, NET1OUT_QUEUE
  1099.  
  1100.     mov     edx, [stack_ip]
  1101.     mov     ecx, [ sktAddr ]
  1102.     mov     ecx, [ ecx + 16 ]
  1103.     cmp     edx, ecx
  1104.     jne     ste_notlocal
  1105.     mov     eax, IPIN_QUEUE
  1106. ste_notlocal:
  1107.  
  1108.        ; Send it.
  1109.     pop     ebx
  1110.     call    queue
  1111.  
  1112. ste_exit:
  1113.     ret
  1114.  
  1115.  
  1116.  
  1117. stateTCB_FIN_WAIT_1:
  1118.     ; We can either receive an ACK of a fin, or a fin
  1119.     mov     bl, [edx + 33]
  1120.     and     bl, 0x10
  1121.     cmp     bl, 0x10
  1122.     jnz     stfw1_001
  1123.  
  1124.     ; It was an ACK
  1125.     mov     esi, [sktAddr]
  1126.     mov     ebx, TCB_FIN_WAIT_2
  1127.     mov     [esi + 28], ebx
  1128.     jmp     stfw1_exit
  1129.  
  1130. stfw1_001:
  1131.     ; It must be a fin then
  1132.     mov     esi, [sktAddr]
  1133.     mov     ebx, TCB_CLOSING
  1134.     mov     [esi + 28], ebx
  1135.     add     esi, 56
  1136.     call    inc_inet_esi
  1137.  
  1138.     ; Send an ACK
  1139.     mov     eax, EMPTY_QUEUE
  1140.     call    dequeue
  1141.     cmp     ax, NO_BUFFER
  1142.     je      stfw1_exit
  1143.  
  1144.     push    eax
  1145.  
  1146.     mov     bl, 0x10        ; ACK
  1147.     mov     ecx, 0
  1148.     mov     esi, 0
  1149.  
  1150.     call    buildTCPPacket
  1151.     mov     eax, NET1OUT_QUEUE
  1152.  
  1153.     mov     edx, [stack_ip]
  1154.     mov     ecx, [ sktAddr ]
  1155.     mov     ecx, [ ecx + 16 ]
  1156.     cmp     edx, ecx
  1157.     jne     stfw1_notlocal
  1158.     mov     eax, IPIN_QUEUE
  1159.  
  1160. stfw1_notlocal:
  1161.     ; Send it.
  1162.     pop     ebx
  1163.     call    queue
  1164.  
  1165. stfw1_exit:
  1166.     ret
  1167.  
  1168.  
  1169.  
  1170. stateTCB_FIN_WAIT_2:
  1171.     mov     esi, [sktAddr]
  1172.  
  1173.     ; Get data length
  1174.     xor     ecx, ecx
  1175.     mov     ch, [edx+2]
  1176.     mov     cl, [edx+3]
  1177.     sub     ecx, 40
  1178.  
  1179.     mov     bl, [edx + 33]
  1180.     and     bl, 0x01
  1181.     cmp     bl, 0x01
  1182.     jne     stfw2001
  1183.  
  1184.     ; Change state, as we have a fin
  1185.     mov     ebx, TCB_TIME_WAIT
  1186.     mov     [esi + 28], ebx
  1187.  
  1188.     inc     ecx                     ; FIN is part of the sequence space
  1189.  
  1190. stfw2001:
  1191.     add     esi, 56
  1192.     call    add_inet_esi
  1193.  
  1194.     ; Send an ACK
  1195.     mov     eax, EMPTY_QUEUE
  1196.     call    dequeue
  1197.     cmp     ax, NO_BUFFER
  1198.     je      stfw2_exit
  1199.  
  1200.     push    eax
  1201.  
  1202.     mov     bl, 0x10        ; ACK
  1203.     mov     ecx, 0
  1204.     mov     esi, 0
  1205.  
  1206.     call    buildTCPPacket
  1207.  
  1208.     mov     eax, NET1OUT_QUEUE
  1209.  
  1210.     mov     edx, [stack_ip]
  1211.     mov     ecx, [ sktAddr ]
  1212.     mov     ecx, [ ecx + 16 ]
  1213.     cmp     edx, ecx
  1214.     jne     stfw2_notlocal
  1215.     mov     eax, IPIN_QUEUE
  1216.  
  1217. stfw2_notlocal:
  1218.        ; Send it.
  1219.     pop     ebx
  1220.     call    queue
  1221.  
  1222.     ; Only delete the socket if we received the FIN
  1223.  
  1224.     mov     bl, [edx + 33]
  1225.     and     bl, 0x01
  1226.     cmp     bl, 0x01
  1227.     jne     stfw2_exit
  1228.  
  1229. ;    mov     edi, [sktAddr]
  1230.  
  1231.     ; delete the socket. Should really wait for 2MSL
  1232. ;    xor     eax, eax
  1233. ;    mov     ecx,SOCKETHEADERSIZE
  1234. ;    cld
  1235. ;    rep     stosb
  1236.  
  1237. stfw2_exit:
  1238.     ret
  1239.  
  1240.  
  1241.  
  1242. stateTCB_CLOSE_WAIT:
  1243.     ; Intentionally left empty
  1244.     ; socket_close_tcp handles this
  1245.     ret
  1246.  
  1247.  
  1248.  
  1249. stateTCB_CLOSING:
  1250.     ; We can either receive an ACK of a fin, or a fin
  1251.     mov     bl, [edx + 33]
  1252.     and     bl, 0x10
  1253.     cmp     bl, 0x10
  1254.     jnz     stc_exit
  1255.  
  1256.     ; It was an ACK
  1257.  
  1258.     mov     edi, [sktAddr]
  1259.  
  1260.     ; delete the socket
  1261.     xor     eax, eax
  1262.     mov     ecx,SOCKETHEADERSIZE
  1263.     cld
  1264.     rep     stosb
  1265.  
  1266. stc_exit:
  1267.     ret
  1268.  
  1269.  
  1270.  
  1271. stateTCB_LAST_ACK:
  1272.     ; Look at control flags - expecting an ACK
  1273.     mov     bl, [edx + 33]
  1274.     and     bl, 0x10
  1275.     cmp     bl, 0x10
  1276.     jnz     stla_exit
  1277.  
  1278.     mov     edi, [sktAddr]
  1279.  
  1280.     ; delete the socket
  1281.     xor     eax, eax
  1282.     mov     ecx,SOCKETHEADERSIZE
  1283.     cld
  1284.     rep     stosb
  1285.  
  1286. stla_exit:
  1287.     ret
  1288.  
  1289.  
  1290.  
  1291. stateTCB_TIME_WAIT:
  1292.     ret
  1293.  
  1294.  
  1295.  
  1296. stateTCB_CLOSED:
  1297.     ret
  1298.