Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;;  STACK.INC                                                      ;;
  4. ;;                                                                 ;;
  5. ;;  TCP/IP stack for Menuet OS                                     ;;
  6. ;;                                                                 ;;
  7. ;;  Version 0.7  4th July 2004                                     ;;
  8. ;;                                                                 ;;
  9. ;;  Copyright 2002 Mike Hibbett, mikeh@oceanfree.net               ;;
  10. ;;                                                                 ;;
  11. ;;  See file COPYING for details                                   ;;
  12. ;;                                                                 ;;
  13. ;; Version 0.7                                                     ;;
  14. ;;         Added a timer per socket to allow delays when rx window ;;
  15. ;;         gets below 1KB                                          ;;
  16. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  17.  
  18.  
  19. ;*******************************************************************
  20. ;   Interface
  21. ;      The interfaces defined in ETHERNET.INC plus:
  22. ;      stack_init
  23. ;      stack_handler
  24. ;      app_stack_handler
  25. ;      app_socket_handler
  26. ;      checksum
  27. ;
  28. ;*******************************************************************
  29.  
  30.  
  31.  
  32. ;
  33. ;   IP Packet after reception - Normal IP packet format
  34. ;
  35. ;    0                   1                   2                   3
  36. ;    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
  37. ;
  38. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  39. ;0  |Version|  IHL  |Type of Service|       Total Length            |
  40. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  41. ;4  |         Identification        |Flags|      Fragment Offset    |
  42. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  43. ;8  |  Time to Live |    Protocol   |         Header Checksum       |
  44. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  45. ;12 |                       Source Address                          |
  46. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  47. ;16 |                    Destination Address                        |
  48. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  49. ;   |      Data                                                     |
  50. ;   +-+-+-..........                                               -+
  51.  
  52.  
  53. ;   TCP Payload ( Data field in IP datagram )
  54. ;
  55. ;    0                   1                   2                   3
  56. ;    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
  57. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  58. ;20 |          Source Port          |       Destination Port        |
  59. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  60. ;24 |                        Sequence Number                        |
  61. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  62. ;28 |                    Acknowledgment Number                      |
  63. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  64. ;32 |  Data |           |U|A|P|R|S|F|                               |
  65. ;   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
  66. ;   |       |           |G|K|H|T|N|N|                               |
  67. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  68. ;36 |           Checksum            |         Urgent Pointer        |
  69. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  70. ;40 |                    Options                    |    Padding    |
  71. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  72. ;   |                             data
  73.  
  74.  
  75. ;
  76. ;   UDP Payload ( Data field in IP datagram )
  77. ;
  78. ;    0                   1                   2                   3
  79. ;    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
  80. ;
  81. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  82. ;   |       Source Port             |      Destination Port         |
  83. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  84. ;   | Length ( UDP Header + Data )  |           Checksum            |
  85. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  86. ;   |       UDP Data                                                |
  87. ;   +-+-+-..........                                               -+
  88. ;
  89.  
  90.  
  91. ;
  92. ;  Socket Descriptor + Buffer
  93. ;
  94. ;    0                   1                   2                   3
  95. ;    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
  96. ;
  97. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  98. ;   |                    Status ( of this buffer )                  |
  99. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  100. ;   |  Application Process ID                                       |
  101. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  102. ;   |                  Local IP Address                             |
  103. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  104. ;   | Local IP Port                 | Unused ( set to 0 )           |
  105. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  106. ;   |                  Remote IP Address                            |
  107. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  108. ;   | Remote IP Port                | Unused ( set to 0 )           |
  109. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  110. ; 24|   Rx Data Count                                   INTEL format|
  111. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  112. ; 28|                 TCB STATE                         INTEL format|
  113. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  114. ; 32|   TCB Timer (seconds)                             INTEL format|
  115. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  116. ; 36| ISS (Inital Sequence # used by this connection )   INET format|
  117. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  118. ; 40| IRS ( Inital Receive Sequence # )                  INET format|
  119. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  120. ; 44| SND.UNA  Seq # of unack'ed sent packets            INET format|
  121. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  122. ; 48| SND.NXT  Next send seq # to use                    INET format|
  123. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  124. ; 52| SND.WND  Send window                               INET format|
  125. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  126. ; 56| RCV.NXT  Next expected receive sequence #          INET format|
  127. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  128. ; 60| RCV.WND  Receive window                            INET format|
  129. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  130. ; 64| SEG.LEN  Segment length                           INTEL format|
  131. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  132. ; 68| SEG.WND  Segment window                           INTEL format|
  133. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  134. ; 72| Retransmit queue # NOW WINDOW SIZE TIMER          INTEL format|
  135. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  136. ; 76|       RX Data                                                 |
  137. ;   +-+-+-..........                                               -+
  138.  
  139.  
  140.  
  141. ; IP protocol numbers
  142. PROTOCOL_ICMP     equ      1
  143. PROTOCOL_TCP      equ      6
  144. PROTOCOL_UDP      equ      17
  145.  
  146.  
  147. ; TIPBUFF status values
  148. BUFF_EMPTY         equ     0
  149. BUFF_RX_FULL       equ     1
  150. BUFF_ALLOCATED     equ     2
  151. BUFF_TX_FULL       equ     3
  152.  
  153. NUM_IPBUFFERS      equ     20    ; buffers allocated for TX/RX
  154.  
  155. SOCK_EMPTY         equ     0        ; socket not in use
  156. SOCK_OPEN          equ     1        ; open issued, but no data sent
  157.  
  158. ; TCP opening modes
  159. SOCKET_PASSIVE     equ     0
  160. SOCKET_ACTIVE      equ     1
  161.  
  162. ; TCP TCB states
  163. TCB_LISTEN         equ        1
  164. TCB_SYN_SENT       equ        2
  165. TCB_SYN_RECEIVED   equ        3
  166. TCB_ESTABLISHED    equ        4
  167. TCB_FIN_WAIT_1     equ        5
  168. TCB_FIN_WAIT_2     equ        6
  169. TCB_CLOSE_WAIT     equ        7
  170. TCB_CLOSING        equ        8
  171. TCB_LAST_ACK       equ        9
  172. TCB_TIME_WAIT      equ        10
  173. TCB_CLOSED         equ        11
  174.  
  175. TWOMSL              equ     10      ; # of secs to wait before closing socket
  176.  
  177. ; socket buffers
  178. SOCKETBUFFSIZE     equ        4096  ; state + config + buffer.
  179. SOCKETHEADERSIZE   equ        76    ; thus 4096 - SOCKETHEADERSIZE bytes data
  180.  
  181. NUM_SOCKETS        equ        16    ; Number of open sockets supported. Was 20
  182.  
  183.  
  184. NUMQUEUES          equ        4
  185. EMPTY_QUEUE        equ        0
  186. IPIN_QUEUE         equ        1
  187. IPOUT_QUEUE        equ        2
  188. NET1OUT_QUEUE      equ        3
  189.  
  190. NO_BUFFER          equ        0xFFFF
  191. IPBUFFSIZE         equ        1500                ; MTU of an ethernet packet
  192. NUMQUEUEENTRIES    equ        NUM_IPBUFFERS
  193. NUMRESENDENTRIES    equ         18              ; Buffers for TCP resend packets
  194. TCP_RETRIES         equ         5               ; Number of times to resend a packet
  195. TCP_TIMEOUT         equ         10              ; resend if not replied to in x hs
  196.  
  197. ; These are the 0x40 function codes for application access to the stack
  198. STACK_DRIVER_STATUS  equ   52
  199. SOCKET_INTERFACE     equ   53
  200.  
  201.  
  202. ; 128KB allocated for the stack and network driver buffers and other
  203. ; data requirements
  204. stack_data_start     equ   0x700000
  205. eth_data_start       equ   0x700000
  206. stack_data           equ   0x704000
  207. stack_data_end       equ   0x71ffff
  208.  
  209. ; 32 bit word
  210. stack_config         equ   stack_data
  211. ; 32 bit word - IP Address in network format
  212. stack_ip             equ   stack_data + 4
  213. ; 1 byte. 0 == inactive, 1 = active
  214. slip_active          equ   stack_data + 8       ; no longer used
  215. ; 1 byte. 0 == inactive, 1 = active
  216. ethernet_active      equ   stack_data + 9
  217. unused               equ   stack_data + 10
  218. ;  word. Buffer number, -1 if none
  219. rx_buff_ptr          equ   stack_data + 12
  220. ; dword. Buffer number, -1 if none
  221. tx_buff_ptr          equ   stack_data + 16
  222. ; byte.
  223. slip_rx_state        equ   stack_data + 20      ; no longer used
  224. ; byte
  225. slip_tx_state        equ   stack_data + 21      ; no longer used
  226. ; dword. Index into data
  227. rx_data_ptr          equ   stack_data + 22
  228. ; dword. Index into data
  229. tx_data_ptr          equ   stack_data + 26
  230. ; word. Count of bytes to send
  231. tx_msg_len           equ   stack_data + 30
  232. ; Address of selected socket
  233. sktAddr              equ   stack_data + 32
  234. ; Parameter to checksum routine - data ptr
  235. checkAdd1            equ   stack_data + 36
  236. ; Parameter to checksum routine - 2nd data ptr
  237. checkAdd2            equ   stack_data + 40
  238. ; Parameter to checksum routine - data size
  239. checkSize1           equ   stack_data + 44
  240. ; Parameter to checksum routine - 2nd data size
  241. checkSize2           equ   stack_data + 46
  242. ; result of checksum routine
  243. checkResult          equ   stack_data + 48
  244.  
  245. ; holds the TCP/UDP pseudo header. SA|DA|0|prot|UDP len|
  246. pseudoHeader         equ   stack_data + 50
  247.  
  248. ; receive and transmit IP buffer allocation
  249. sockets              equ   stack_data + 62
  250. Next_free2           equ   sockets + (SOCKETBUFFSIZE * NUM_SOCKETS)
  251. ; 1560 byte buffer for rx / tx ethernet packets
  252. Ether_buffer         equ   Next_free2
  253. Next_free3           equ   Ether_buffer + 1560
  254. last_1sTick          equ   Next_free3
  255. IPbuffs              equ   Next_free3 + 1
  256. queues               equ   IPbuffs + ( NUM_IPBUFFERS * IPBUFFSIZE )
  257. queueList            equ   queues + (2 * NUMQUEUES)
  258. last_1hsTick         equ   queueList + ( 2 * NUMQUEUEENTRIES )
  259.  
  260. ;resendQ              equ   queueList + ( 2 * NUMQUEUEENTRIES )
  261. ;resendBuffer         equ    resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP
  262. ;                    equ    resendBuffer + ( IPBUFFSIZE * NUMRESENDENTRIES )
  263.  
  264.  
  265.  
  266. resendQ             equ     0x770000
  267. resendBuffer        equ     resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP
  268.  
  269.  
  270. ;***************************************************************************
  271. ;   Function
  272. ;      stack_init
  273. ;
  274. ;   Description
  275. ;      Clear all allocated memory to zero. This ensures that
  276. ;       on startup, the stack is inactive, and consumes no resources
  277. ;       This is a kernel function, called prior to the OS main loop
  278. ;       in set_variables
  279. ;
  280. ;***************************************************************************
  281. stack_init:
  282.     xor     eax,eax
  283.     mov     edi,stack_data_start
  284.     mov     ecx,0x20000 / 4  ; Assume that we have 128KB of data
  285.     cld
  286.     rep     stosd
  287.  
  288.     ; Initialise TCP resend queue data structures
  289.     mov     eax, 0xFFFFFFFF
  290.     mov     edi, resendQ
  291.     mov     ecx, NUMRESENDENTRIES  ; 1 dword per entry
  292.     cld
  293.     rep     stosd
  294.  
  295.  
  296.     mov     eax, 0xFFFFFFFF
  297.     mov     [rx_buff_ptr], eax
  298.     mov     [tx_buff_ptr], eax
  299.  
  300.     ; Put in some defaults : slip, 0x3f8, 4, ip=192.168.1.22
  301.     ; Saves me entering them each boot up when debugging
  302.     mov     eax, 0x03f80401
  303.     mov     [stack_config], eax
  304.     mov     eax, 0xc801a8c0
  305.     mov     [stack_ip], eax
  306.  
  307.     call    queueInit
  308.  
  309.     ; The following block sets up the 1s timer
  310.     mov     al,0x0
  311.     out     0x70,al
  312.     in      al,0x71
  313.     mov     [last_1sTick], al
  314.  
  315.     ret
  316.  
  317.  
  318.  
  319. ;***************************************************************************
  320. ;   Function
  321. ;      stack_handler
  322. ;
  323. ;   Description
  324. ;       The kernel loop routine for the stack
  325. ;       This is a kernel function, called in the main loop
  326. ;
  327. ;***************************************************************************
  328. stack_handler:
  329.  
  330.     call    ethernet_driver
  331.     call    ip_rx
  332.  
  333.  
  334.     ; Test for 10ms tick, call tcp timer
  335.     mov     eax, [timer_ticks] ;[0xfdf0]
  336.     cmp     eax, [last_1hsTick]
  337.     je      sh_001
  338.  
  339.     mov     [last_1hsTick], eax
  340.     call    tcp_tx_handler
  341.  
  342. sh_001:
  343.  
  344.     ; Test for 1 second event, call 1s timer functions
  345.     mov     al,0x0   ;second
  346.     out     0x70,al
  347.     in      al,0x71
  348.     cmp     al, [last_1sTick]
  349.     je      sh_exit
  350.  
  351.     mov     [last_1sTick], al
  352.  
  353.     call    arp_timer
  354.     call    tcp_tcb_handler
  355.  
  356. sh_exit:
  357.     ret
  358.  
  359.  
  360.  
  361.  
  362. ;***************************************************************************
  363. ;   Function
  364. ;      is_localport_unused
  365. ;
  366. ;   Description
  367. ;         scans through all the active sockets , looking to see if the
  368. ;      port number specified in bx is in use as a localport number.
  369. ;      This is useful when you want a to generate a unique local port
  370. ;      number.
  371. ;          On return, eax = 1 for free, 0 for in use
  372. ;
  373. ;***************************************************************************
  374. is_localport_unused:
  375.     mov     al, bh
  376.     mov     ah, bl
  377.     mov     bx, ax
  378.  
  379.     mov     edx, SOCKETBUFFSIZE * NUM_SOCKETS
  380.     mov     ecx, NUM_SOCKETS
  381.     mov     eax, 0                    ; Assume the return value is 'in use'
  382.  
  383. ilu1:
  384.     sub     edx, SOCKETBUFFSIZE
  385.     cmp     [edx + sockets + 12], bx
  386.     loopnz  ilu1                  ; Return back if the socket is occupied
  387.  
  388.     jz      ilu_exit
  389.     inc     eax                         ; return port not in use
  390.  
  391. ilu_exit:
  392.     ret
  393.  
  394.  
  395.  
  396. ;***************************************************************************
  397. ;   Function
  398. ;      get_free_socket
  399. ;
  400. ;   Description
  401. ;
  402. ;***************************************************************************
  403. get_free_socket:
  404.     push    ecx
  405.     mov     eax, SOCKETBUFFSIZE * NUM_SOCKETS
  406.     mov     ecx, NUM_SOCKETS
  407.  
  408. gfs1:
  409.     sub     eax, SOCKETBUFFSIZE
  410.     cmp     [eax + sockets], dword SOCK_EMPTY
  411.     loopnz  gfs1                  ; Return back if the socket is occupied
  412.     mov     eax, ecx
  413.     pop     ecx
  414.     jz      gfs_exit
  415.     mov     eax, 0xFFFFFFFF
  416.  
  417. gfs_exit:
  418.     ret
  419.  
  420.  
  421.  
  422. ;***************************************************************************
  423. ;   Function
  424. ;      checksum
  425. ;
  426. ;   Description
  427. ;       checkAdd1,checkAdd2, checkSize1, checkSize2, checkResult
  428. ;       Dont break anything; Most registers are used by the caller
  429. ;       This code is derived from the 'C' source, cksum.c, in the book
  430. ;       Internetworking with TCP/IP Volume II by D.E. Comer
  431. ;
  432. ;***************************************************************************
  433. checksum:
  434.     pusha
  435.  
  436.     xor     edx, edx                  ; edx is the accumulative checksum
  437.     xor     ebx, ebx
  438.     mov     cx, [checkSize1]
  439.     shr     cx, 1
  440.     jz      cs1_1
  441.  
  442.     mov     eax, [checkAdd1]
  443.  
  444. cs1:
  445.     mov     bh, [eax]
  446.     mov     bl, [eax + 1]
  447.  
  448.     add     eax, 2
  449.     add     edx, ebx
  450.  
  451.     loopw   cs1
  452.  
  453. cs1_1:
  454.     and     word [checkSize1], 0x01
  455.     jz      cs_test2
  456.  
  457.     mov     bh, [eax]
  458.     xor     bl, bl
  459.  
  460.     add     edx, ebx
  461.  
  462. cs_test2:
  463.     mov     cx, [checkSize2]
  464.     cmp     cx, 0
  465.     jz      cs_exit                     ; Finished if no 2nd buffer
  466.  
  467.     shr     cx, 1
  468.     jz      cs2_1
  469.  
  470.     mov     eax, [checkAdd2]
  471.  
  472. cs2:
  473.     mov     bh, [eax]
  474.     mov     bl, [eax + 1]
  475.  
  476.     add     eax, 2
  477.     add     edx, ebx
  478.  
  479.     loopw   cs2
  480.  
  481. cs2_1:
  482.     and     word [checkSize2], 0x01
  483.     jz      cs_exit
  484.  
  485.     mov     bh, [eax]
  486.     xor     bl, bl
  487.  
  488.     add     edx, ebx
  489.  
  490. cs_exit:
  491.     mov     ebx, edx
  492.  
  493.     shr     ebx, 16
  494.     and     edx, 0xffff
  495.     add     edx, ebx
  496.     mov     eax, edx
  497.     shr     eax, 16
  498.     add     edx, eax
  499.     not     dx
  500.  
  501.     mov     [checkResult], dx
  502.     popa
  503.     ret
  504.  
  505.  
  506.  
  507.  
  508. ;***************************************************************************
  509. ;   Function
  510. ;      app_stack_handler
  511. ;
  512. ;   Description
  513. ;       This is an application service, called by int 0x40 fn 52
  514. ;       It provides application access to the network interface layer
  515. ;
  516. ;***************************************************************************
  517. app_stack_handler:
  518.     cmp     eax, 0
  519.     jnz     not0
  520.     ; Read the configuartion word
  521.     mov     eax, [stack_config]
  522.     ret
  523.  
  524. not0:
  525.     cmp     eax, 1
  526.     jnz     not1
  527.     ; read the IP address
  528.  
  529.     mov     eax, [stack_ip]
  530.     ret
  531.  
  532. not1:
  533.     cmp     eax, 2
  534.     jnz     not2
  535.  
  536.     ; write the configuration word
  537.     mov     [stack_config], ebx
  538.  
  539.     ; <Slip shouldn't be active anyway - thats an operational issue.>
  540.     ; If ethernet now enabled, probe for the card, reset it and empty
  541.     ; the packet buffer
  542.     ; If all successfull, enable the card.
  543.     ; If ethernet now disabled, set it as disabled. Should really
  544.     ; empty the tcpip data area too.
  545.  
  546.     ; ethernet interface is '3' in ls 7 bits
  547.     and     bl, 0x7f
  548.     cmp     bl, 3
  549.  
  550.     je       ash_eth_enable
  551.     ; Ethernet isn't enabled, so make sure that the card is disabled
  552.     mov     [ethernet_active], byte 0
  553.  
  554.     ret
  555.  
  556. ash_eth_enable:
  557.     ; Probe for the card. This will reset it and enable the interface
  558.     ; if found
  559.     call    eth_probe
  560.     cmp     eax, 0
  561.     je      ash_eth_done            ; Abort if no hardware found
  562.  
  563.     mov     [ethernet_active], byte 1
  564.  
  565. ash_eth_done:
  566.     ret
  567.  
  568. not2:
  569.     cmp     eax, 3
  570.     jnz     not3
  571.     ; write the IP Address
  572.     mov     [stack_ip], ebx
  573.     ret
  574.  
  575. not3:
  576.     cmp     eax, 4
  577.     jnz     not4
  578.     ; Enabled the slip driver on the comm port
  579.     ; slip removed
  580.     ret
  581.  
  582. not4:
  583.     cmp     eax, 5
  584.     jnz     not5
  585.     ; Disable the slip driver on the comm port
  586.     ; slip removed
  587.  
  588. not5:
  589.     cmp     eax, 6
  590.     jnz     not6
  591.  
  592.     ; Insert an IP packet into the stacks received packet queue
  593.     call    stack_insert_packet
  594.     ret
  595.  
  596. not6:
  597.     cmp     eax, 7
  598.     jnz     not7
  599.  
  600.     ; Test for any packets queued for transmission over the network
  601.  
  602. not7:
  603.     cmp     eax, 8
  604.     jnz     not8
  605.  
  606.     call    stack_get_packet
  607.     ; Extract a packet queued for transmission by the network
  608.     ret
  609.  
  610. not8:
  611.     cmp     eax, 9
  612.     jnz     not9
  613.  
  614.     ; read the gateway IP address
  615.  
  616.     mov     eax, [gateway_ip]
  617.     ret
  618.  
  619. not9:
  620.     cmp     eax, 10
  621.     jnz     not10
  622.  
  623.     ; read the subnet mask
  624.  
  625.     mov     eax, [subnet_mask]
  626.     ret
  627.  
  628. not10:
  629.     cmp     eax, 11
  630.     jnz     not11
  631.  
  632.     ; write the gateway IP Address
  633.     mov     [gateway_ip], ebx
  634.  
  635.     ret
  636.  
  637. not11:
  638.     cmp     eax, 12
  639.     jnz     not12
  640.  
  641.     ; write the subnet mask
  642.     mov     [subnet_mask], ebx
  643.  
  644.  
  645. not12:
  646.     cmp     eax, 13
  647.     jnz     not13
  648.  
  649.     ; read the dns
  650.  
  651.     mov     eax, [dns_ip]
  652.     ret
  653.  
  654. not13:
  655.     cmp     eax, 14
  656.     jnz     stack_driver_end
  657.  
  658.     ; write the dns IP Address
  659.     mov     [dns_ip], ebx
  660.  
  661.     ret
  662.  
  663. stack_driver_end:
  664.     ret
  665.  
  666.  
  667.  
  668. ;***************************************************************************
  669. ;   Function
  670. ;      app_socket_handler
  671. ;
  672. ;   Description
  673. ;       This is an application service, called by int 0x40
  674. ;       It provides application access to stack socket services
  675. ;       such as opening sockets
  676. ;
  677. ;***************************************************************************
  678. app_socket_handler:
  679.     cmp     eax, 0
  680.     jnz     nots0
  681.  
  682.     call    socket_open
  683.     ret
  684.  
  685. nots0:
  686.     cmp     eax, 1
  687.     jnz     nots1
  688.  
  689.     call    socket_close
  690.     ret
  691.  
  692. nots1:
  693.     cmp     eax, 2
  694.     jnz     nots2
  695.  
  696.     call    socket_poll
  697.     ret
  698.  
  699. nots2:
  700.     cmp     eax, 3
  701.     jnz     nots3
  702.  
  703.     call    socket_read
  704.     ret
  705.  
  706. nots3:
  707.     cmp     eax, 4
  708.     jnz     nots4
  709.  
  710.     call    socket_write
  711.     ret
  712.  
  713. nots4:
  714.     cmp     eax, 5
  715.     jnz     nots5
  716.  
  717.     call    socket_open_tcp
  718.     ret
  719.  
  720. nots5:
  721.     cmp     eax, 6
  722.     jnz     nots6
  723.  
  724.     call    socket_status
  725.     ret
  726.  
  727. nots6:
  728.     cmp     eax, 7
  729.     jnz     nots7
  730.  
  731.     call    socket_write_tcp
  732.     ret
  733.  
  734. nots7:
  735.     cmp     eax, 8
  736.     jnz     nots8
  737.  
  738.     call    socket_close_tcp
  739.     ret
  740.  
  741. nots8:
  742.     cmp     eax, 9
  743.     jnz     nots9
  744.  
  745.     call    is_localport_unused
  746.     ret
  747.  
  748. nots9:
  749.     cmp     eax, 254
  750.     jnz     notdump
  751.  
  752.     ret
  753.  
  754. notdump:
  755.     cmp     eax, 255
  756.     jnz     notsdebug
  757.  
  758.     ; This sub function allows access to debugging information on the stack
  759.     ; ebx holds the request:
  760.     ;  100 : return length of empty queue
  761.     ;  101 : return length of IPOUT QUEUE
  762.     ;  102 : return length of IPIN QUEUE
  763.     ;  103 : return length of NET1OUT QUEUE
  764.     ; 200 : return # of ARP entries
  765.     ; 201 : return size of ARP table ( max # entries )
  766.     ; 202 : select ARP table entry #
  767.     ; 203 : return IP of selected table entry
  768.     ; 204 : return High 4 bytes of MAC address of selected table entry
  769.     ; 205 : return low  2 bytes of MAC address of selected table entry
  770.     ; 206 : return status word of selected table entry
  771.     ; 207 : return Time to live of selected table entry
  772.  
  773.  
  774.     ;  2 : return number of IP packets received
  775.     ;  3 : return number of packets transmitted
  776.     ;  4 : return number of received packets dumped
  777.     ;  5 : return number of arp packets received
  778.     ;  6 : return status of packet driver
  779.     ;      ( 0 == not active, FFFFFFFF = successful )
  780.  
  781.     call    stack_internal_status
  782.     ret
  783.  
  784. notsdebug:
  785.     ; Invalid Option
  786.     ret
  787.  
  788.  
  789. uglobal
  790.   ARPTmp:
  791.   times 14 db 0
  792. endg
  793.  
  794. ;***************************************************************************
  795. ;   Function
  796. ;      stack_internal_status
  797. ;
  798. ;   Description
  799. ;       Returns information about the internal status of the stack
  800. ;       This is only useful for debugging
  801. ;       It works with the ethernet driver
  802. ;       sub function in ebx
  803. ;       return requested data in eax
  804. ;
  805. ;***************************************************************************
  806. stack_internal_status:
  807.     cmp     ebx, 100
  808.     jnz     notsis100
  809.  
  810.     ;  100 : return length of EMPTY QUEUE
  811.     mov     ebx, EMPTY_QUEUE
  812.     call    queueSize
  813.     ret
  814.  
  815. notsis100:
  816.     cmp     ebx, 101
  817.     jnz     notsis101
  818.  
  819.     ;  101 : return length of IPOUT QUEUE
  820.     mov     ebx, IPOUT_QUEUE
  821.     call    queueSize
  822.     ret
  823.  
  824. notsis101:
  825.     cmp     ebx, 102
  826.     jnz     notsis102
  827.  
  828.     ;  102 : return length of IPIN QUEUE
  829.     mov     ebx, IPIN_QUEUE
  830.     call    queueSize
  831.     ret
  832.  
  833. notsis102:
  834.     cmp     ebx, 103
  835.     jnz     notsis103
  836.  
  837.     ;  103 : return length of NET1OUT QUEUE
  838.     mov     ebx, NET1OUT_QUEUE
  839.     call    queueSize
  840.     ret
  841.  
  842. notsis103:
  843.     cmp     ebx, 200
  844.     jnz     notsis200
  845.  
  846.     ; 200 : return num entries in arp table
  847.     movzx   eax, byte [NumARP]
  848.     ret
  849.  
  850. notsis200:
  851.     cmp     ebx, 201
  852.     jnz     notsis201
  853.  
  854.     ; 201 : return arp table size
  855.     mov     eax, 20 ; ARP_TABLE_SIZE
  856.     ret
  857.  
  858. notsis201:
  859.     cmp     ebx, 202
  860.     jnz     notsis202
  861.  
  862.     ; 202 - read the requested table entry
  863.     ; into a temporary buffer
  864.     ; ecx holds the entry number
  865.  
  866.     mov     eax, ecx
  867.     mov     ecx, 14 ; ARP_ENTRY_SIZE
  868.     mul     ecx
  869.  
  870.     mov     ecx, [eax + ARPTable]
  871.     mov     [ARPTmp], ecx
  872.     mov     ecx, [eax + ARPTable+4]
  873.     mov     [ARPTmp+4], ecx
  874.     mov     ecx, [eax + ARPTable+8]
  875.     mov     [ARPTmp+8], ecx
  876.     mov     cx, [eax + ARPTable+12]
  877.     mov     [ARPTmp+12], cx
  878.     ret
  879.  
  880. notsis202:
  881.     cmp     ebx, 203
  882.     jnz     notsis203
  883.  
  884.     ; 203 - return IP address
  885.     mov     eax, [ARPTmp]
  886.     ret
  887.  
  888. notsis203:
  889.     cmp     ebx, 204
  890.     jnz     notsis204
  891.  
  892.     ; 204 - return MAC high dword
  893.     mov     eax, [ARPTmp+4]
  894.     ret
  895.  
  896. notsis204:
  897.     cmp     ebx, 205
  898.     jnz     notsis205
  899.  
  900.     ; 205 - return MAC ls word
  901.     movzx   eax, word [ARPTmp+8]
  902.     ret
  903.  
  904. notsis205:
  905.     cmp     ebx, 206
  906.     jnz     notsis206
  907.  
  908.     ; 206 - return status word
  909.     movzx   eax, word [ARPTmp+10]
  910.     ret
  911.  
  912. notsis206:
  913.     cmp     ebx, 207
  914.     jnz     notsis207
  915.  
  916.     ; 207 - return ttl word
  917.     movzx   eax, word [ARPTmp+12]
  918.     ret
  919.  
  920. notsis207:
  921.     cmp     ebx, 2
  922.     jnz     notsis2
  923.  
  924.     ;  2 : return number of IP packets received
  925.     mov     eax, [ip_rx_count]
  926.     ret
  927.  
  928. notsis2:
  929.     cmp     ebx, 3
  930.     jnz     notsis3
  931.  
  932.     ;  3 : return number of packets transmitted
  933.     mov     eax, [ip_tx_count]
  934.     ret
  935.  
  936. notsis3:
  937.     cmp     ebx, 4
  938.     jnz     notsis4
  939.  
  940.     ;  4 : return number of received packets dumped
  941.     mov     eax, [dumped_rx_count]
  942.     ret
  943.  
  944. notsis4:
  945.     cmp     ebx, 5
  946.     jnz     notsis5
  947.  
  948.     ;  5 : return number of arp packets received
  949.     mov     eax, [arp_rx_count]
  950.     ret
  951.  
  952. notsis5:
  953.     cmp     ebx, 6
  954.     jnz     notsis6
  955.  
  956.     ;  6 : return status of packet driver
  957.     ;  ( 0 == not active, FFFFFFFF = successful )
  958.     mov     eax, [eth_status]
  959.     ret
  960.  
  961. notsis6:
  962.     xor     eax, eax
  963.     ret
  964.  
  965.  
  966.  
  967. ;***************************************************************************
  968. ;   Function
  969. ;      stack_get_packet
  970. ;
  971. ;   Description
  972. ;       extracts an IP packet from the NET1 output queue
  973. ;       and sends the data to the calling process
  974. ;       pointer to data in edx
  975. ;       returns number of bytes read in eax
  976. ;
  977. ;***************************************************************************
  978. stack_get_packet:
  979.     ; Look for a buffer to tx
  980.     mov     eax, NET1OUT_QUEUE
  981.     call    dequeue
  982.     cmp     ax, NO_BUFFER
  983.     je      sgp_non_exit            ; Exit if no buffer available
  984.  
  985.     push    eax                     ; Save buffer number for freeing at end
  986.  
  987.     push    edx
  988.     ; convert buffer pointer eax to the absolute address
  989.     mov     ecx, IPBUFFSIZE
  990.     mul     ecx
  991.     add     eax, IPbuffs
  992.     pop     edx
  993.  
  994.     push    eax                     ; save address of IP data
  995.  
  996.     ; Get the address of the callers data
  997.     mov     edi,[0x3010]
  998.     add     edi,TASKDATA.mem_start
  999.     add     edx,[edi]
  1000.     mov     edi, edx
  1001.  
  1002.     pop     eax
  1003.  
  1004.     mov     ecx, 1500           ; should get the actual number of bytes to write
  1005.     mov     esi, eax
  1006.     cld
  1007.     rep     movsb               ; copy the data across
  1008.  
  1009.     ; And finally, return the buffer to the free queue
  1010.     pop     eax
  1011.     call    freeBuff
  1012.  
  1013.     mov     eax, 1500
  1014.     ret
  1015.  
  1016. sgp_non_exit:
  1017.     xor     eax, eax
  1018.     ret
  1019.  
  1020.  
  1021.  
  1022. ;***************************************************************************
  1023. ;   Function
  1024. ;      stack_insert_packet
  1025. ;
  1026. ;   Description
  1027. ;       writes an IP packet into the stacks receive queue
  1028. ;       # of bytes to write in ecx
  1029. ;       pointer to data in edx
  1030. ;       returns 0 in eax ok, -1 == failed
  1031. ;
  1032. ;***************************************************************************
  1033. stack_insert_packet:
  1034.  
  1035.     mov     eax, EMPTY_QUEUE
  1036.     call    dequeue
  1037.     cmp     ax, NO_BUFFER
  1038.     je      sip_err_exit
  1039.  
  1040.     push    eax
  1041.  
  1042.     ; save the pointers to the data buffer & size
  1043.     push    edx
  1044.     push    ecx
  1045.  
  1046.     ; convert buffer pointer eax to the absolute address
  1047.     mov     ecx, IPBUFFSIZE
  1048.     mul     ecx
  1049.     add     eax, IPbuffs
  1050.  
  1051.     mov     edx, eax
  1052.  
  1053.     ; So, edx holds the IPbuffer ptr
  1054.  
  1055.     pop     ecx                     ; count of bytes to send
  1056.     mov     ebx, ecx                ; need the length later
  1057.     pop     eax                     ; get callers ptr to data to send
  1058.  
  1059.     ; Get the address of the callers data
  1060.     mov     edi,[0x3010]
  1061.     add     edi,TASKDATA.mem_start
  1062.     add     eax,[edi]
  1063.     mov     esi, eax
  1064.  
  1065.     mov     edi, edx
  1066.     cld
  1067.     rep     movsb               ; copy the data across
  1068.  
  1069.     pop     ebx
  1070.  
  1071.     mov     eax, IPIN_QUEUE
  1072.     call    queue
  1073.  
  1074.     inc     dword [ip_rx_count]
  1075.  
  1076.     mov     eax, 0
  1077.     ret
  1078.  
  1079. sip_err_exit:
  1080.     mov     eax, 0xFFFFFFFF
  1081.     ret
  1082.  
  1083.  
  1084.  
  1085. ;***************************************************************************
  1086. ;   Function
  1087. ;      socket_open
  1088. ;
  1089. ;   Description
  1090. ;       find a free socket
  1091. ;       local port in ebx
  1092. ;       remote port in ecx
  1093. ;       remote ip in edx
  1094. ;       return socket # in eax, -1 if none available
  1095. ;
  1096. ;***************************************************************************
  1097. socket_open:
  1098.     call    get_free_socket
  1099.  
  1100.     cmp     eax, 0xFFFFFFFF
  1101.     jz      so_exit
  1102.  
  1103.     ; ax holds the socket number that is free. Get real address
  1104.     push    eax
  1105.     shl     eax, 12
  1106.     add     eax, sockets
  1107.  
  1108.     mov     [eax], dword SOCK_OPEN
  1109.  
  1110.     mov     [eax + 12], byte bh      ; Local port ( LS 16 bits )
  1111.     mov     [eax + 13], byte bl      ; Local port ( LS 16 bits )
  1112.     mov     ebx, [stack_ip]
  1113.     mov     [eax + 8], ebx         ; Local IP
  1114.     mov     [eax + 20], ch         ; Remote Port ( LS 16 bits )
  1115.     mov     [eax + 21], cl         ; Remote Port ( LS 16 bits )
  1116.     mov     [eax + 16], edx         ; Remote IP ( in Internet order )
  1117.     mov     [eax + 24], dword 0      ; recieved data count
  1118.  
  1119.     mov     esi, [0x3010]
  1120.     mov     ebx, [esi+TASKDATA.pid]
  1121.     mov     [eax + 4], ebx         ; save the process ID
  1122.     pop     eax      ; Get the socket number back, so we can return it
  1123.  
  1124. so_exit:
  1125.     ret
  1126.  
  1127.  
  1128.  
  1129. ;***************************************************************************
  1130. ;   Function
  1131. ;      socket_open_tcp
  1132. ;
  1133. ;   Description
  1134. ;       Opens a TCP socket in PASSIVE or ACTIVE mode
  1135. ;       find a free socket
  1136. ;       local port in ebx ( intel format )
  1137. ;       remote port in ecx ( intel format )
  1138. ;       remote ip in edx ( in Internet byte order )
  1139. ;       Socket open mode in esi  ( SOCKET_PASSIVE or SOCKET_ACTIVE )
  1140. ;       return socket # in eax, -1 if none available
  1141. ;
  1142. ;***************************************************************************
  1143. socket_open_tcp:
  1144.     call    get_free_socket
  1145.  
  1146.     cmp     eax, 0xFFFFFFFF
  1147.     jz      so_exit
  1148.  
  1149.     ; ax holds the socket number that is free. Get real address
  1150.     push    eax
  1151.     shl     eax, 12
  1152.     add     eax, sockets
  1153.  
  1154.     mov     [sktAddr], eax
  1155.     mov     [eax], dword SOCK_OPEN
  1156.  
  1157.     ; TODO - check this works!
  1158.     mov     [eax + 72], dword 0     ; Reset the window timer.
  1159.  
  1160.     mov     [eax + 12], byte bh      ; Local port ( LS 16 bits )
  1161.     mov     [eax + 13], byte bl      ; Local port ( LS 16 bits )
  1162.     mov     ebx, [stack_ip]
  1163.     mov     [eax + 8], ebx         ; Local IP
  1164.     mov     [eax + 20], ch         ; Remote Port ( LS 16 bits )
  1165.     mov     [eax + 21], cl         ; Remote Port ( LS 16 bits )
  1166.     mov     [eax + 16], edx         ; Remote IP ( in Internet order )
  1167.     mov     [eax + 24], dword 0      ; recieved data count
  1168.  
  1169.     ; Now fill in TCB state
  1170.     mov     ebx, TCB_LISTEN
  1171.     cmp     esi, SOCKET_PASSIVE
  1172.     jz      sot_001
  1173.     mov     ebx, TCB_SYN_SENT
  1174.  
  1175. sot_001:
  1176.     mov     [eax + 28], ebx            ; Indicate the state of the TCB
  1177.  
  1178.     mov     esi, [0x3010]
  1179.     mov     ecx, [esi+TASKDATA.pid]
  1180.     mov     [eax + 4], ecx         ; save the process ID
  1181.  
  1182.     cmp     ebx, TCB_LISTEN
  1183.     je      sot_done
  1184.  
  1185.     ; Now, if we are in active mode, then we have to send a SYN to the specified remote port
  1186.  
  1187.  
  1188.     mov     eax, EMPTY_QUEUE
  1189.     call    dequeue
  1190.     cmp     ax, NO_BUFFER
  1191.     je      sot_done
  1192.  
  1193.     push    eax
  1194.  
  1195.     mov     bl, 0x02        ; SYN
  1196.     mov     ecx, 0
  1197.  
  1198.     call    buildTCPPacket
  1199.  
  1200.     mov     eax, NET1OUT_QUEUE
  1201.  
  1202.     mov     edx, [stack_ip]
  1203.     mov     ecx, [ sktAddr ]
  1204.     mov     ecx, [ ecx + 16 ]
  1205.     cmp     edx, ecx
  1206.     jne     sot_notlocal
  1207.     mov     eax, IPIN_QUEUE
  1208.  
  1209. sot_notlocal:
  1210.        ; Send it.
  1211.     pop     ebx
  1212.     call    queue
  1213.  
  1214.     mov     esi, [sktAddr]
  1215.  
  1216.     ; increment SND.NXT in socket
  1217.     add     esi, 48
  1218.     call    inc_inet_esi
  1219.  
  1220. sot_done:
  1221.     pop     eax      ; Get the socket number back, so we can return it
  1222.  
  1223. sot_exit:
  1224.     ret
  1225.  
  1226.  
  1227.  
  1228. ;***************************************************************************
  1229. ;   Function
  1230. ;      socket_close
  1231. ;
  1232. ;   Description
  1233. ;       socket # in ebx
  1234. ;       returns 0 for ok, -1 for socket not open (fail)
  1235. ;
  1236. ;***************************************************************************
  1237. socket_close:
  1238.     shl     ebx, 12
  1239.     add     ebx, sockets
  1240.     mov     eax, 0xFFFFFFFF         ; assume this operation will fail..
  1241.     cmp     [ebx], dword SOCK_EMPTY
  1242.     jz      sc_exit
  1243.  
  1244.     ; Clear the socket varaibles
  1245.     xor     eax, eax
  1246.     mov     edi,ebx
  1247.     mov     ecx,SOCKETHEADERSIZE
  1248.     cld
  1249.     rep     stosb
  1250.  
  1251. sc_exit:
  1252.     ret
  1253.  
  1254.  
  1255.  
  1256. ;***************************************************************************
  1257. ;   Function
  1258. ;      socket_close_tcp
  1259. ;
  1260. ;   Description
  1261. ;       socket # in ebx
  1262. ;       returns 0 for ok, -1 for socket not open (fail)
  1263. ;
  1264. ;***************************************************************************
  1265. socket_close_tcp:
  1266.     ; first, remove any resend entries
  1267.     pusha
  1268.  
  1269.     mov     esi, resendQ
  1270.     mov     ecx, 0
  1271.  
  1272. sct001:
  1273.     cmp     ecx, NUMRESENDENTRIES
  1274.     je      sct003              ; None left
  1275.     cmp     [esi], bl
  1276.     je      sct002              ; found one
  1277.     inc     ecx
  1278.     add     esi, 4
  1279.     jmp     sct001
  1280.  
  1281. sct002:
  1282.     dec     dword [arp_rx_count] ; ************ TEST ONLY!
  1283.  
  1284.     mov     [esi], byte 0xFF
  1285.     jmp     sct001
  1286.  
  1287. sct003:
  1288.     popa
  1289.  
  1290.     shl     ebx, 12
  1291.     add     ebx, sockets
  1292.     mov     [sktAddr], ebx
  1293.     mov     eax, 0xFFFFFFFF         ; assume this operation will fail..
  1294.     cmp     [ebx], dword SOCK_EMPTY
  1295.     jz      sct_exit
  1296.  
  1297.     ; Now construct the response, and queue for sending by IP
  1298.     mov     eax, EMPTY_QUEUE
  1299.     call    dequeue
  1300.     cmp     ax, NO_BUFFER
  1301.     je      stl_exit
  1302.  
  1303.     push    eax
  1304.  
  1305.     mov     bl, 0x11        ; FIN + ACK
  1306.     mov     ecx, 0
  1307.     mov     esi, 0
  1308.  
  1309.     call    buildTCPPacket
  1310.  
  1311.     mov     ebx, [sktAddr]
  1312.  
  1313.     ; increament SND.NXT in socket
  1314.     mov     esi, 48
  1315.     add     esi, ebx
  1316.     call    inc_inet_esi
  1317.  
  1318.  
  1319.     ; Get the socket state
  1320.     mov     eax, [ebx + 28]
  1321.     cmp     eax, TCB_LISTEN
  1322.     je      destroyTCB
  1323.     cmp     eax, TCB_SYN_SENT
  1324.     je      destroyTCB
  1325.     cmp     eax, TCB_SYN_RECEIVED
  1326.     je      sct_finwait1
  1327.     cmp     eax, TCB_ESTABLISHED
  1328.     je      sct_finwait1
  1329.  
  1330.     ; assume CLOSE WAIT
  1331.     ; Send a fin, then enter last-ack state
  1332.     mov     eax, TCB_LAST_ACK
  1333.     mov     [ebx + 28], eax
  1334.     xor     eax, eax
  1335.     jmp     sct_send
  1336.  
  1337. sct_finwait1:
  1338.     ; Send a fin, then enter finwait2 state
  1339.     mov     eax, TCB_FIN_WAIT_1
  1340.     mov     [ebx + 28], eax
  1341.     xor     eax, eax
  1342.  
  1343. sct_send:
  1344.     mov     eax, NET1OUT_QUEUE
  1345.  
  1346.     mov     edx, [stack_ip]
  1347.     mov     ecx, [ sktAddr ]
  1348.     mov     ecx, [ ecx + 16 ]
  1349.     cmp     edx, ecx
  1350.     jne     sct_notlocal
  1351.     mov     eax, IPIN_QUEUE
  1352.  
  1353. sct_notlocal:
  1354.        ; Send it.
  1355.     pop     ebx
  1356.     call    queue
  1357.     jmp     sct_exit
  1358.  
  1359. destroyTCB:
  1360.     pop     eax
  1361.     ; Clear the socket varaibles
  1362.     xor     eax, eax
  1363.     mov     edi,ebx
  1364.     mov     ecx,SOCKETHEADERSIZE
  1365.     cld
  1366.     rep     stosb
  1367.  
  1368. sct_exit:
  1369.     ret
  1370.  
  1371.  
  1372.  
  1373. ;***************************************************************************
  1374. ;   Function
  1375. ;      socket_poll
  1376. ;
  1377. ;   Description
  1378. ;       socket # in ebx
  1379. ;       returns count in eax.
  1380. ;
  1381. ;***************************************************************************
  1382. socket_poll:
  1383.     shl     ebx, 12
  1384.     add     ebx, sockets
  1385.     mov     eax, [ebx + 24]
  1386.  
  1387.     ret
  1388.  
  1389.  
  1390.  
  1391. ;***************************************************************************
  1392. ;   Function
  1393. ;      socket_status
  1394. ;
  1395. ;   Description
  1396. ;       socket # in ebx
  1397. ;       returns TCB state in eax.
  1398. ;
  1399. ;***************************************************************************
  1400. socket_status:
  1401.     shl     ebx, 12
  1402.     add     ebx, sockets
  1403.     mov     eax, [ebx + 28]
  1404.  
  1405.     ret
  1406.  
  1407.  
  1408.  
  1409. ;***************************************************************************
  1410. ;   Function
  1411. ;      socket_read
  1412. ;
  1413. ;   Description
  1414. ;       socket # in ebx
  1415. ;       returns # of bytes remaining in eax, data in bl
  1416. ;
  1417. ;***************************************************************************
  1418. socket_read:
  1419.     shl     ebx, 12
  1420.     add     ebx, sockets
  1421.     mov     eax, [ebx + 24]         ; get count of bytes
  1422.     mov     ecx,1
  1423.     test    eax, eax
  1424.     jz      sr2
  1425.  
  1426.     dec     eax
  1427.     mov     esi, ebx            ; esi is address of socket
  1428.     mov     [ebx + 24], eax         ; store new count
  1429.     movzx   ebx, byte [ebx + SOCKETHEADERSIZE]  ; get the byte
  1430.     add     esi, SOCKETHEADERSIZE
  1431.     mov     edi, esi
  1432.     inc     esi
  1433.  
  1434.     mov     ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4
  1435.     cld
  1436.     rep     movsd
  1437.     xor     ecx, ecx
  1438.  
  1439. sr1:
  1440.     jmp     sor_exit
  1441.  
  1442. sr2:
  1443.     xor     bl, bl
  1444.  
  1445. sor_exit:
  1446.     ret
  1447.  
  1448.  
  1449.  
  1450. ;***************************************************************************
  1451. ;   Function
  1452. ;      socket_write
  1453. ;
  1454. ;   Description
  1455. ;       socket in ebx
  1456. ;       # of bytes to write in ecx
  1457. ;       pointer to data in edx
  1458. ;       returns 0 in eax ok, -1 == failed ( invalid socket, or
  1459. ;       could not queue IP packet )
  1460. ;
  1461. ;***************************************************************************
  1462. socket_write:
  1463.     ; First, find the address of the socket descriptor
  1464.     shl     ebx, 12
  1465.     add     ebx, sockets         ; ebx = address of actual socket
  1466.  
  1467.     mov     eax, 0xFFFFFFFF
  1468.     ; If the socket is invalid, return with an error code
  1469.     cmp     [ebx], dword SOCK_EMPTY
  1470.     je      sw_exit
  1471.  
  1472.  
  1473.     mov     eax, EMPTY_QUEUE
  1474.     call    dequeue
  1475.     cmp     ax, NO_BUFFER
  1476.     je      sw_exit
  1477.  
  1478.     ; Save the queue entry number
  1479.     push    eax
  1480.  
  1481.     ; save the pointers to the data buffer & size
  1482.     push    edx
  1483.     push    ecx
  1484.  
  1485.     ; convert buffer pointer eax to the absolute address
  1486.     mov     ecx, IPBUFFSIZE
  1487.     mul     ecx
  1488.     add     eax, IPbuffs
  1489.  
  1490.     mov     edx, eax
  1491.  
  1492.     ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
  1493.  
  1494.     ; Fill in the IP header ( some data is in the socket descriptor)
  1495.     mov     eax, [ebx + 8]
  1496.     mov     [edx + 12], eax      ; source IP
  1497.     mov     eax, [ebx + 16]
  1498.     mov     [edx + 16], eax      ; Destination IP
  1499.  
  1500.     mov     al, 0x45
  1501.     mov     [edx], al         ; Version, IHL
  1502.     xor     al, al
  1503.     mov     [edx + 1], al     ; Type of service
  1504.  
  1505.     pop     eax                   ; Get the UDP data length
  1506.     push    eax
  1507.  
  1508.     add     eax, 20 + 8           ; add IP header and UDP header lengths
  1509.     mov     [edx + 2], ah
  1510.     mov     [edx + 3], al
  1511.     xor     al, al
  1512.     mov     [edx + 4], al
  1513.     mov     [edx + 5], al
  1514.     mov     al, 0x40
  1515.     mov     [edx + 6], al
  1516.     xor     al, al
  1517.     mov     [edx + 7], al
  1518.     mov     al, 0x20
  1519.     mov     [edx + 8], al
  1520.     mov     al, 17
  1521.     mov     [edx + 9], al
  1522.  
  1523.     ; Checksum left unfilled
  1524.     xor     ax, ax
  1525.     mov     [edx + 10], ax
  1526.  
  1527.     ; Fill in the UDP header ( some data is in the socket descriptor)
  1528.     mov     ax, [ebx + 12]
  1529.     mov     [edx + 20], ax
  1530.  
  1531.     mov     ax, [ebx + 20]
  1532.     mov     [edx + 20 + 2], ax
  1533.  
  1534.     pop     eax
  1535.     push    eax
  1536.  
  1537.     add     eax, 8
  1538.     mov     [edx + 20 + 4], ah
  1539.     mov     [edx + 20 + 5], al
  1540.  
  1541.     ; Checksum left unfilled
  1542.     xor     ax, ax
  1543.     mov     [edx + 20 + 6], ax
  1544.  
  1545.     pop     ecx                  ; count of bytes to send
  1546.     mov     ebx, ecx            ; need the length later
  1547.     pop     eax                  ; get callers ptr to data to send
  1548.  
  1549.     ; Get the address of the callers data
  1550.     mov     edi,[0x3010]
  1551.     add     edi,TASKDATA.mem_start
  1552.     add     eax,[edi]
  1553.     mov     esi, eax
  1554.  
  1555.     mov     edi, edx
  1556.     add     edi, 28
  1557.     cld
  1558.     rep     movsb               ; copy the data across
  1559.  
  1560.     ; we have edx as IPbuffer ptr.
  1561.     ; Fill in the UDP checksum
  1562.     ; First, fill in pseudoheader
  1563.     mov     eax, [edx + 12]
  1564.     mov     [pseudoHeader], eax
  1565.     mov     eax, [edx + 16]
  1566.     mov     [pseudoHeader+4], eax
  1567.     mov     ax, 0x1100            ; 0 + protocol
  1568.     mov     [pseudoHeader+8], ax
  1569.     add     ebx, 8
  1570.     mov     eax, ebx
  1571.     mov     [pseudoHeader+10], ah
  1572.     mov     [pseudoHeader+11], al
  1573.  
  1574.     mov     eax, pseudoHeader
  1575.     mov     [checkAdd1], eax
  1576.     mov     [checkSize1], word 12
  1577.     mov     eax, edx
  1578.     add     eax, 20
  1579.     mov     [checkAdd2], eax
  1580.     mov     eax, ebx
  1581.     mov     [checkSize2], ax      ; was eax!! mjh 8/7/02
  1582.  
  1583.     call    checksum
  1584.  
  1585.     ; store it in the UDP checksum ( in the correct order! )
  1586.     mov     ax, [checkResult]
  1587.  
  1588.     ; If the UDP checksum computes to 0, we must make it 0xffff
  1589.     ; (0 is reserved for 'not used')
  1590.     cmp     ax, 0
  1591.     jne     sw_001
  1592.     mov     ax, 0xffff
  1593.  
  1594. sw_001:
  1595.     mov     [edx + 20 + 6], ah
  1596.     mov     [edx + 20 + 7], al
  1597.  
  1598.     ; Fill in the IP header checksum
  1599.     mov     eax, edx
  1600.     mov     [checkAdd1], eax
  1601.     mov     [checkSize1], word 20
  1602.     mov     [checkAdd2], dword 0
  1603.     mov     [checkSize2], word 0
  1604.  
  1605.     call    checksum
  1606.  
  1607.     mov     ax, [checkResult]
  1608.     mov     [edx + 10], ah
  1609.     mov     [edx + 11], al
  1610.  
  1611.     ; Check destination IP address.
  1612.     ; If it is the local host IP, route it back to IP_RX
  1613.  
  1614.     pop     ebx
  1615.     mov     eax, NET1OUT_QUEUE
  1616.  
  1617.     mov     ecx, [ edx + 16]
  1618.     mov     edx, [stack_ip]
  1619.     cmp     edx, ecx
  1620.     jne     sw_notlocal
  1621.     mov     eax, IPIN_QUEUE
  1622.  
  1623. sw_notlocal:
  1624.     ; Send it.
  1625.     call    queue
  1626.  
  1627.     xor     eax, eax
  1628.  
  1629. sw_exit:
  1630.     ret
  1631.  
  1632.  
  1633.  
  1634. ;***************************************************************************
  1635. ;   Function
  1636. ;      socket_write_tcp
  1637. ;
  1638. ;   Description
  1639. ;       socket in ebx
  1640. ;       # of bytes to write in ecx
  1641. ;       pointer to data in edx
  1642. ;       returns 0 in eax ok, -1 == failed ( invalid socket, or
  1643. ;       could not queue IP packet )
  1644. ;
  1645. ;***************************************************************************
  1646. socket_write_tcp:
  1647.     ; First, find the address of the socket descriptor
  1648.     shl     ebx, 12
  1649.     add     ebx, sockets         ; ebx = address of actual socket
  1650.  
  1651.     mov     [sktAddr], ebx
  1652.  
  1653.     mov     eax, 0xFFFFFFFF
  1654.     ; If the socket is invalid, return with an error code
  1655.     cmp     [ebx], dword SOCK_EMPTY
  1656.     je      swt_exit
  1657.  
  1658.     ; If the sockets window timer is nonzero, do not queue packet
  1659.     ; TODO - done
  1660.     cmp     [ebx + 72], dword 0
  1661.     jne     swt_exit
  1662.  
  1663.     mov     eax, EMPTY_QUEUE
  1664.     call    dequeue
  1665.     cmp     ax, NO_BUFFER
  1666.     je      swt_exit
  1667.  
  1668.     push    eax
  1669.  
  1670.     mov     bl, 0x10        ; ACK
  1671.  
  1672.     ; Get the address of the callers data
  1673.     mov     edi,[0x3010]
  1674.     add     edi,TASKDATA.mem_start
  1675.     add     edx,[edi]
  1676.     mov     esi, edx
  1677.  
  1678.     pop     eax
  1679.     push    eax
  1680.  
  1681.     push    ecx
  1682.     call    buildTCPPacket
  1683.     pop     ecx
  1684.  
  1685.     ; Check destination IP address.
  1686.     ; If it is the local host IP, route it back to IP_RX
  1687.  
  1688.     pop     ebx
  1689.     push    ecx
  1690.     mov     eax, NET1OUT_QUEUE
  1691.  
  1692.     mov     edx, [stack_ip]
  1693.     mov     ecx, [ sktAddr ]
  1694.     mov     ecx, [ ecx + 16 ]
  1695.     cmp     edx, ecx
  1696.     jne     swt_notlocal
  1697.     mov     eax, IPIN_QUEUE
  1698.  
  1699. swt_notlocal:
  1700.     pop     ecx
  1701.  
  1702.     push    ebx                 ; save ipbuffer number
  1703.  
  1704.     call    queue
  1705.  
  1706.     mov     esi, [sktAddr]
  1707.  
  1708.     ; increament SND.NXT in socket
  1709.     ; Amount to increment by is in ecx
  1710.     add     esi, 48
  1711.     call    add_inet_esi
  1712.  
  1713.     pop     ebx
  1714.  
  1715.     ; Copy the IP buffer to a resend queue
  1716.     ; If there isn't one, dont worry about it for now
  1717.     mov     esi, resendQ
  1718.     mov     ecx, 0
  1719.  
  1720. swt003:
  1721.     cmp     ecx, NUMRESENDENTRIES
  1722.     je      swt001              ; None found
  1723.     cmp     [esi], byte 0xFF
  1724.     je      swt002              ; found one
  1725.     inc     ecx
  1726.     add     esi, 4
  1727.     jmp     swt003
  1728.  
  1729. swt002:
  1730.     push    ebx
  1731.  
  1732.     ; OK, we have a buffer descriptor ptr in esi.
  1733.     ; resend entry # in ecx
  1734.     ;  Populate it
  1735.     ;  socket #
  1736.     ;  retries count
  1737.     ;  retry time
  1738.     ;  fill IP buffer associated with this descriptor
  1739.  
  1740.     mov     eax, [sktAddr]
  1741.     sub     eax, sockets
  1742.     shr     eax, 12             ; get skt #
  1743.     mov     [esi], al
  1744.     mov     [esi + 1], byte TCP_RETRIES
  1745.     mov     [esi + 2], word TCP_TIMEOUT
  1746.  
  1747.     inc     ecx
  1748.     ; Now get buffer location, and copy buffer across. argh! more copying,,
  1749.     mov     edi, resendBuffer - IPBUFFSIZE
  1750. swt002a:
  1751.     add     edi, IPBUFFSIZE
  1752.     loop    swt002a
  1753.  
  1754.     ; we have dest buffer location in edi
  1755.     pop     eax
  1756.     ; convert source buffer pointer eax to the absolute address
  1757.     mov     ecx, IPBUFFSIZE
  1758.     mul     ecx
  1759.     add     eax, IPbuffs
  1760.     mov     esi, eax
  1761.  
  1762.     ; do copy
  1763.     mov     ecx, IPBUFFSIZE
  1764.     cld
  1765.     rep     movsb
  1766.  
  1767.     inc     dword [arp_rx_count] ; ************ TEST ONLY!
  1768.  
  1769. swt001:
  1770.     xor     eax, eax
  1771.  
  1772. swt_exit:
  1773.     ret
  1774.  
  1775.  
  1776.  
  1777. ; Below, the main network layer source code is included
  1778. ;
  1779.  
  1780. include "queue.inc"
  1781. include "ip.inc"
  1782. include "tcp.inc"
  1783. include "udp.inc"
  1784. include "eth_drv/ethernet.inc"
  1785.