Subversion Repositories Kolibri OS

Rev

Rev 871 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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