Subversion Repositories Kolibri OS

Rev

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

  1. $Revision: 431 $
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;                                                              ;;
  4. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  5. ;; Distributed under terms of the GNU General Public License    ;;
  6. ;;                                                              ;;
  7. ;;  SOCKET.INC                                                  ;;
  8. ;;                                                              ;;
  9. ;;  Sockets constants, structures and functions                 ;;
  10. ;;                                                              ;;
  11. ;;  Last revision: 11.11.2006                                   ;;
  12. ;;                                                              ;;
  13. ;;  This file contains the following:                           ;;
  14. ;;    is_localport_unused                                       ;;
  15. ;;    get_free_socket                                           ;;
  16. ;;    socket_open                                               ;;
  17. ;;    socket_open_tcp                                           ;;
  18. ;;    socket_close                                              ;;
  19. ;;    socket_close_tcp                                          ;;
  20. ;;    socket_poll                                               ;;
  21. ;;    socket_status                                             ;;
  22. ;;    socket_read                                               ;;
  23. ;;    socket_write                                              ;;
  24. ;;    socket_write_tcp                                          ;;
  25. ;;                                                              ;;
  26. ;;                                                              ;;
  27. ;;  Changes history:                                            ;;
  28. ;;   22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net          ;;
  29. ;;   11.11.2006 - [Johnny_B] and [smb]                          ;;
  30. ;;                                                              ;;
  31. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  32.  
  33. ;
  34. ;  Socket Descriptor + Buffer
  35. ;
  36. ;    0                   1                   2                   3
  37. ;    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
  38. ;
  39. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  40. ;  0|                    Status ( of this buffer )                  |
  41. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  42. ;  4|  Application Process ID                                       |
  43. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  44. ;  8|                  Local IP Address                             |
  45. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  46. ; 12| Local IP Port                 | Unused ( set to 0 )           |
  47. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  48. ; 16|                  Remote IP Address                            |
  49. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  50. ; 20| Remote IP Port                | Unused ( set to 0 )           |
  51. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  52. ; 24|   Rx Data Count                                   INTEL format|
  53. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  54. ; 28|                 TCB STATE                         INTEL format|
  55. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  56. ; 32|   TCB Timer (seconds)                             INTEL format|
  57. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  58. ; 36| ISS (Inital Sequence # used by this connection )   INET format|
  59. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  60. ; 40| IRS ( Inital Receive Sequence # )                  INET format|
  61. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  62. ; 44| SND.UNA  Seq # of unack'ed sent packets            INET format|
  63. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  64. ; 48| SND.NXT  Next send seq # to use                    INET format|
  65. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  66. ; 52| SND.WND  Send window                               INET format|
  67. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  68. ; 56| RCV.NXT  Next expected receive sequence #          INET format|
  69. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  70. ; 60| RCV.WND  Receive window                            INET format|
  71. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  72. ; 64| SEG.LEN  Segment length                           INTEL format|
  73. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  74. ; 68| SEG.WND  Segment window                           INTEL format|
  75. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  76. ; 72| Retransmit queue # NOW WINDOW SIZE TIMER          INTEL format|
  77. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  78. ; 76|      RX offset from
  79. ; 76|       RX Data                                                 |
  80. ;   +-+-+-..........                                               -+
  81.  
  82.  
  83. ; so, define struct
  84. struc SOCKET
  85. {  .Status                  dd   ?  ;+00 - Status ( of this buffer )
  86.    .PID                     dd   ?  ;+04 - Application Process ID
  87.    .LocalIP                 dd   ?  ;+08 -  Local IP Address
  88.    .LocalPort               dw   ?  ;+12 - Local Port
  89.    .UnusedL                 dw   ?  ;+14 - may be removed in future
  90.    .RemoteIP                dd   ?  ;+16 - Remote IP Address
  91.    .RemotePort              dw   ?  ;+20 - Remote Port
  92.    .UnusedR                 dw   ?  ;+22 - may be removed in future
  93.    .rxDataCount             dd   ?  ;+24 - Rx Data Count
  94.    .TCBState                dd   ?  ;+28 - TCB STATE
  95.    .TCBTimer                dd   ?  ;+32 - TCB Timer (seconds)
  96.    .ISS                     dd   ?  ;+36 - Initial Send Sequence
  97.    .IRS                     dd   ?  ;+40 - Initial Receive Sequence
  98.    .SND_UNA                 dd   ?  ;+44 - Sequence number of unack'ed sent packets
  99.    .SND_NXT                 dd   ?  ;+48 - Next send sequence number to use
  100.    .SND_WND                 dd   ?  ;+52 - Send window
  101.    .RCV_NXT                 dd   ?  ;+56 - Next receive sequence number to use
  102.    .RCV_WND                 dd   ?  ;+60 - Receive window
  103.    .SEG_LEN                 dd   ?  ;+64 - Segment length
  104.    .SEG_WND                 dd   ?  ;+68 - Segment window
  105.    .wndsizeTimer            dd   ?  ;+72 - Retransmit queue # NOW WINDOW SIZE TIMER
  106.    .rxData                  dd   ?  ;+76 - receive data buffer here
  107. }
  108.  
  109. virtual at 0
  110.   SOCKET SOCKET
  111. end virtual
  112.  
  113. ; simple macro calcing real memory address of SOCKET struct by socket's
  114. macro   Index2RealAddr reg
  115. {
  116.         shl     reg, 12
  117.     add     reg, sockets
  118. }
  119.  
  120. ;Constants
  121. ; current socket statuses
  122. SOCK_EMPTY         equ     0        ; socket not in use
  123. SOCK_OPEN          equ     1        ; open issued, but no data sent
  124.  
  125. ; TCP opening modes
  126. SOCKET_PASSIVE     equ     0
  127. SOCKET_ACTIVE      equ     1
  128.  
  129. ;***************************************************************************
  130. ;   Function
  131. ;      is_localport_unused
  132. ;
  133. ;   Description
  134. ;         scans through all the active sockets , looking to see if the
  135. ;      port number specified in bx is in use as a localport number.
  136. ;      This is useful when you want a to generate a unique local port
  137. ;      number.
  138. ;          On return, eax = 1 for free, 0 for in use
  139. ;
  140. ;***************************************************************************
  141. is_localport_unused:
  142.     mov     al, bh
  143.     mov     ah, bl
  144.     mov     bx, ax
  145.  
  146.     mov     edx, SOCKETBUFFSIZE * NUM_SOCKETS
  147.     mov     ecx, NUM_SOCKETS
  148.     mov     eax, 0                    ; Assume the return value is 'in use'
  149.  
  150. ilu1:
  151.     sub     edx, SOCKETBUFFSIZE
  152.     cmp     [edx + sockets + SOCKET.LocalPort], bx
  153.     loopnz  ilu1                  ; Return back if the socket is occupied
  154.  
  155.     jz      ilu_exit
  156.     inc     eax                         ; return port not in use
  157.  
  158. ilu_exit:
  159.     ret
  160.  
  161.  
  162.  
  163. ;***************************************************************************
  164. ;   Function
  165. ;      get_free_socket
  166. ;
  167. ;   Description
  168. ;
  169. ;***************************************************************************
  170. get_free_socket:
  171.     push    ecx
  172.     mov     eax, SOCKETBUFFSIZE * NUM_SOCKETS
  173.     mov     ecx, NUM_SOCKETS
  174.  
  175. gfs1:
  176.     sub     eax, SOCKETBUFFSIZE
  177.     cmp     [eax + sockets + SOCKET.Status], dword SOCK_EMPTY
  178.     loopnz  gfs1                  ; Return back if the socket is occupied
  179.     mov     eax, ecx
  180.     pop     ecx
  181.     jz      gfs_exit
  182.     mov     eax, 0xFFFFFFFF
  183.  
  184. gfs_exit:
  185.     ret
  186.  
  187.  
  188. ;***************************************************************************
  189. ;   Function
  190. ;      socket_open
  191. ;
  192. ;   Description
  193. ;       find a free socket
  194. ;       local port in ebx
  195. ;       remote port in ecx
  196. ;       remote ip in edx
  197. ;       return socket # in eax, -1 if none available
  198. ;
  199. ;***************************************************************************
  200. socket_open:
  201.     call    get_free_socket
  202.  
  203.     cmp     eax, 0xFFFFFFFF
  204.     jz      so_exit
  205.  
  206.     ; ax holds the socket number that is free. Get real address
  207.     push    eax
  208.     Index2RealAddr eax
  209.  
  210.     mov     [eax + SOCKET.Status], dword SOCK_OPEN
  211.  
  212.     xchg    bh, bl
  213.     mov     [eax + SOCKET.LocalPort], bx
  214.     xchg    ch, cl
  215.     mov     [eax + SOCKET.RemotePort], cx
  216.  
  217.     mov     ebx, [stack_ip]
  218.     mov     [eax + SOCKET.LocalIP], ebx
  219.     mov     [eax + SOCKET.RemoteIP], edx
  220.     mov     [eax + SOCKET.rxDataCount], dword 0      ; recieved data count
  221.  
  222.     mov     esi, [TASK_BASE]
  223.     mov     ebx, [esi+TASKDATA.pid]
  224.     mov     [eax + SOCKET.PID], ebx         ; save the process ID
  225.     pop     eax      ; Get the socket number back, so we can return it
  226.  
  227. so_exit:
  228.     ret
  229.  
  230.  
  231.  
  232. ;***************************************************************************
  233. ;   Function
  234. ;      socket_open_tcp
  235. ;
  236. ;   Description
  237. ;       Opens a TCP socket in PASSIVE or ACTIVE mode
  238. ;       find a free socket
  239. ;       local port in ebx ( intel format )
  240. ;       remote port in ecx ( intel format )
  241. ;       remote ip in edx ( in Internet byte order )
  242. ;       Socket open mode in esi  ( SOCKET_PASSIVE or SOCKET_ACTIVE )
  243. ;       return socket # in eax, -1 if none available
  244. ;
  245. ;***************************************************************************
  246. socket_open_tcp:
  247.     call    get_free_socket
  248.  
  249.     cmp     eax, 0xFFFFFFFF
  250.     jz      so_exit
  251.  
  252.     ; ax holds the socket number that is free. Get real address
  253.     push eax
  254.     Index2RealAddr eax
  255.  
  256.     mov     [sktAddr], eax
  257.     mov     [eax], dword SOCK_OPEN
  258.  
  259.     ; TODO - check this works!
  260.     mov     [eax + SOCKET.wndsizeTimer], dword 0     ; Reset the window timer.
  261.  
  262.         xchg    bh, bl
  263.         mov     [eax + SOCKET.LocalPort], bx
  264. ;    mov     [eax + 12], byte bh      ; Local port ( LS 16 bits )
  265. ;    mov     [eax + 13], byte bl      ; Local port ( LS 16 bits )
  266.  
  267.         xchg    ch, cl
  268.         mov     [eax + SOCKET.RemotePort], cx
  269. ;    mov     [eax + 20], ch         ; Remote Port ( LS 16 bits )
  270. ;    mov     [eax + 21], cl         ; Remote Port ( LS 16 bits )
  271.  
  272.     mov     ebx, [stack_ip]
  273.     mov     [eax + SOCKET.LocalIP], ebx
  274.     mov     [eax + SOCKET.RemoteIP], edx
  275.     mov     [eax + SOCKET.rxDataCount], dword 0
  276.  
  277.     ; Now fill in TCB state
  278.     mov     ebx, TCB_LISTEN
  279.     cmp     esi, SOCKET_PASSIVE
  280.     jz      sot_001
  281.     mov     ebx, TCB_SYN_SENT
  282.  
  283. sot_001:
  284.     mov     [eax + SOCKET.TCBState], ebx            ; Indicate the state of the TCB
  285.  
  286.     mov     esi, [TASK_BASE]
  287.     mov     ecx, [esi+TASKDATA.pid]
  288.     mov     [eax + SOCKET.PID], ecx         ; save the process ID
  289.  
  290.     cmp     ebx, TCB_LISTEN
  291.     je      sot_done
  292.  
  293.     ; Now, if we are in active mode, then we have to send a SYN to the specified remote port
  294.     mov     eax, EMPTY_QUEUE
  295.     call    dequeue
  296.     cmp     ax, NO_BUFFER
  297.     je      sot_done
  298.  
  299.     push    eax
  300.  
  301.     mov     bl, 0x02        ; SYN
  302.     mov     ecx, 0
  303.  
  304.     call    buildTCPPacket
  305.  
  306.     mov     eax, NET1OUT_QUEUE
  307.  
  308.     mov     edx, [stack_ip]
  309.     mov     ecx, [sktAddr ]
  310.     mov     ecx, [ecx + 16]
  311.     cmp     edx, ecx
  312.     jne     sot_notlocal
  313.     mov     eax, IPIN_QUEUE
  314.  
  315. sot_notlocal:
  316.        ; Send it.
  317.     pop     ebx
  318.     call    queue
  319.  
  320.     mov     esi, [sktAddr]
  321.  
  322.     ; increment SND.NXT in socket
  323.     add     esi, 48
  324.     call    inc_inet_esi
  325.  
  326. sot_done:
  327.     pop     eax      ; Get the socket number back, so we can return it
  328.  
  329. sot_exit:
  330.     ret
  331.  
  332.  
  333.  
  334. ;***************************************************************************
  335. ;   Function
  336. ;      socket_close
  337. ;
  338. ;   Description
  339. ;       socket # in ebx
  340. ;       returns 0 for ok, -1 for socket not open (fail)
  341. ;
  342. ;***************************************************************************
  343. socket_close:
  344.     Index2RealAddr ebx
  345.     mov     eax, 0xFFFFFFFF         ; assume this operation will fail..
  346.     cmp     [ebx + SOCKET.Status], dword SOCK_EMPTY
  347.     jz      sc_exit
  348.  
  349.     ; Clear the socket varaibles
  350.     xor     eax, eax
  351.     mov     edi, ebx
  352.     mov     ecx, SOCKETHEADERSIZE
  353.     cld
  354.     rep     stosb
  355.  
  356. sc_exit:
  357.     ret
  358.  
  359.  
  360.  
  361. ;***************************************************************************
  362. ;   Function
  363. ;      socket_close_tcp
  364. ;
  365. ;   Description
  366. ;       socket # in ebx
  367. ;       returns 0 for ok, -1 for socket not open (fail)
  368. ;
  369. ;***************************************************************************
  370. socket_close_tcp:
  371.     ; first, remove any resend entries
  372.     pusha
  373.  
  374.     mov     esi, resendQ
  375.     mov     ecx, 0
  376.  
  377. sct001:
  378.     cmp     ecx, NUMRESENDENTRIES
  379.     je      sct003              ; None left
  380.     cmp     [esi], bl
  381.     je      sct002              ; found one
  382.     inc     ecx
  383.     add     esi, 4
  384.     jmp     sct001
  385.  
  386. sct002:
  387.  
  388.     mov     [esi], byte 0xFF
  389.     jmp     sct001
  390.  
  391. sct003:
  392.     popa
  393.  
  394.     Index2RealAddr ebx
  395.     mov     [sktAddr], ebx
  396.     mov     eax, 0xFFFFFFFF         ; assume this operation will fail..
  397.     cmp     [ebx + SOCKET.Status], dword SOCK_EMPTY
  398.     jz      sct_exit
  399.  
  400.     ; Now construct the response, and queue for sending by IP
  401.     mov     eax, EMPTY_QUEUE
  402.     call    dequeue
  403.     cmp     ax, NO_BUFFER
  404.     je      stl_exit
  405.  
  406.     push    eax
  407.  
  408.     mov     bl, 0x11        ; FIN + ACK
  409.     mov     ecx, 0
  410.     mov     esi, 0
  411.  
  412.     call    buildTCPPacket
  413.  
  414.     mov     ebx, [sktAddr]
  415.  
  416.     ; increament SND.NXT in socket
  417.     mov     esi, 48
  418.     add     esi, ebx
  419.     call    inc_inet_esi
  420.  
  421.  
  422.     ; Get the socket state
  423.     mov     eax, [ebx + SOCKET.TCBState]
  424.     cmp     eax, TCB_LISTEN
  425.     je      destroyTCB
  426.     cmp     eax, TCB_SYN_SENT
  427.     je      destroyTCB
  428.     cmp     eax, TCB_SYN_RECEIVED
  429.     je      sct_finwait1
  430.     cmp     eax, TCB_ESTABLISHED
  431.     je      sct_finwait1
  432.  
  433.     ; assume CLOSE WAIT
  434.     ; Send a fin, then enter last-ack state
  435.     mov     eax, TCB_LAST_ACK
  436.     mov     [ebx + SOCKET.TCBState], eax
  437.     xor     eax, eax
  438.     jmp     sct_send
  439.  
  440. sct_finwait1:
  441.     ; Send a fin, then enter finwait2 state
  442.     mov     eax, TCB_FIN_WAIT_1
  443.     mov     [ebx + SOCKET.TCBState], eax
  444.     xor     eax, eax
  445.  
  446. sct_send:
  447.     mov     eax, NET1OUT_QUEUE
  448.  
  449.     mov     edx, [stack_ip]
  450.     mov     ecx, [sktAddr ]
  451.     mov     ecx, [ecx + 16]
  452.     cmp     edx, ecx
  453.     jne     sct_notlocal
  454.     mov     eax, IPIN_QUEUE
  455.  
  456. sct_notlocal:
  457.        ; Send it.
  458.     pop     ebx
  459.     call    queue
  460.     jmp     sct_exit
  461.  
  462. destroyTCB:
  463.     pop     eax
  464.     ; Clear the socket varaibles
  465.     xor     eax, eax
  466.     mov     edi, ebx
  467.     mov     ecx, SOCKETHEADERSIZE
  468.     cld
  469.     rep     stosb
  470.  
  471. sct_exit:
  472.     ret
  473.  
  474.  
  475.  
  476. ;***************************************************************************
  477. ;   Function
  478. ;      socket_poll
  479. ;
  480. ;   Description
  481. ;       socket # in ebx
  482. ;       returns count in eax.
  483. ;
  484. ;***************************************************************************
  485. socket_poll:
  486.     Index2RealAddr ebx
  487.     mov     eax, [ebx + SOCKET.rxDataCount]
  488.  
  489.     ret
  490.  
  491.  
  492.  
  493. ;***************************************************************************
  494. ;   Function
  495. ;      socket_status
  496. ;
  497. ;   Description
  498. ;       socket # in ebx
  499. ;       returns TCB state in eax.
  500. ;
  501. ;***************************************************************************
  502. socket_status:
  503.     Index2RealAddr ebx
  504.     mov     eax, [ebx + SOCKET.TCBState]
  505.  
  506.     ret
  507.  
  508.  
  509.  
  510. ;***************************************************************************
  511. ;   Function
  512. ;      socket_read
  513. ;
  514. ;   Description
  515. ;       socket # in ebx
  516. ;       returns # of bytes remaining in eax, data in bl
  517. ;
  518. ;***************************************************************************
  519. socket_read:
  520.     Index2RealAddr ebx
  521.     mov     eax, [ebx + SOCKET.rxDataCount]         ; get count of bytes
  522.     mov     ecx, 1
  523.     test    eax, eax
  524.     jz      sr2
  525.  
  526.     dec     eax
  527.     mov     esi, ebx            ; esi is address of socket
  528.     mov     [ebx + SOCKET.rxDataCount], eax         ; store new count
  529.     ;movzx   ebx, byte [ebx + SOCKET.rxData]  ; get the byte
  530.     movzx   ebx, byte [ebx + SOCKETHEADERSIZE]  ; get the byte
  531.     add     esi, SOCKETHEADERSIZE
  532.     mov     edi, esi
  533.     inc     esi
  534.  
  535.     mov     ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4
  536.     cld
  537.     rep     movsd
  538.     xor     ecx, ecx
  539.  
  540. sr1:
  541.     jmp     sor_exit
  542.  
  543. sr2:
  544.     xor     bl, bl
  545.  
  546. sor_exit:
  547.     ret
  548.  
  549.  
  550. ;***************************************************************************
  551. ;   Function
  552. ;      socket_read_packet
  553. ;
  554. ;   Description
  555. ;       socket # in ebx
  556. ;       datapointer # in ecx
  557. ;       buffer size in edx
  558. ;       returns # of bytes copied in eax
  559. ;
  560. ;***************************************************************************
  561. socket_read_packet:
  562.     Index2RealAddr ebx                                     ; get real socket address
  563.     mov     eax, [ebx + SOCKET.rxDataCount]                ; get count of bytes
  564.     test    eax, eax                                       ; if count of bytes is zero..
  565.     jz      .exit                                          ; exit function (eax will be zero)
  566.  
  567.     test    edx, edx                                       ; if buffer size is zero, copy all data
  568.     jz      .copyallbytes
  569.     cmp     edx, eax                                       ; if buffer size is larger then the bytes of data, copy all data
  570.     jge     .copyallbytes
  571.  
  572.     sub     eax, edx                                       ; store new count (data bytes in buffer - bytes we're about to copy)
  573.     mov     [ebx + SOCKET.rxDataCount], eax                ;
  574.     push    eax
  575.     mov     eax, edx                                       ; number of bytes we want to copy must be in eax
  576.     call    .startcopy                                     ; copy to the application
  577.  
  578.     mov     esi, ebx                                       ; now we're going to copy the remaining bytes to the beginning
  579.     add     esi, SOCKETHEADERSIZE                          ; we dont need to copy the header
  580.     mov     edi, esi                                       ; edi is where we're going to copy to
  581.     add     esi, edx                                       ; esi is from where we copy
  582.     pop     ecx                                            ; count of bytes we have left
  583.     push    ecx                                            ; push it again so we can re-use it later
  584.     shr     ecx, 2                                         ; divide eax by 4
  585.     cld
  586.     rep     movsd                                          ; copy all full dwords
  587.     pop     ecx
  588.     and     ecx, 3
  589.     rep     movsb                                          ; copy remaining bytes
  590.  
  591.     ret                                                    ; at last, exit
  592.  
  593. .copyallbytes:
  594.     xor     esi, esi
  595.     mov     [ebx + SOCKET.rxDataCount], esi                ; store new count (zero)
  596.  
  597. .startcopy:
  598.     mov     edi, ecx                                       ;
  599.  ;   add     edi, std_application_base_address              ; get data pointer to buffer in application
  600.  
  601.     mov     esi, ebx                                       ;
  602.     add     esi, SOCKETHEADERSIZE                          ; we dont need to copy the header
  603.     mov     ecx, eax                                       ; eax is count of bytes
  604.     push    ecx
  605.     shr     ecx, 2                                         ; divide eax by 4
  606.     cld                                                    ; copy all full dwords
  607.     rep     movsd                                          ;
  608.     pop     ecx
  609.     and     ecx, 3
  610.     rep     movsb                                          ; copy the rest bytes
  611.  
  612. .exit:
  613.     ret                                                    ; exit, or go back to shift remaining bytes if any
  614.  
  615.  
  616.  
  617.  
  618. ;***************************************************************************
  619. ;   Function
  620. ;      socket_write
  621. ;
  622. ;   Description
  623. ;       socket in ebx
  624. ;       # of bytes to write in ecx
  625. ;       pointer to data in edx
  626. ;       returns 0 in eax ok, -1 == failed ( invalid socket, or
  627. ;       could not queue IP packet )
  628. ;
  629. ;***************************************************************************
  630. socket_write:
  631.     Index2RealAddr ebx
  632.  
  633.     mov     eax, 0xFFFFFFFF
  634.     ; If the socket is invalid, return with an error code
  635.     cmp     [ebx], dword SOCK_EMPTY
  636.     je      sw_exit
  637.  
  638.  
  639.     mov     eax, EMPTY_QUEUE
  640.     call    dequeue
  641.     cmp     ax, NO_BUFFER
  642.     je      sw_exit
  643.  
  644.     ; Save the queue entry number
  645.     push    eax
  646.  
  647.     ; save the pointers to the data buffer & size
  648.     push    edx
  649.     push    ecx
  650.  
  651.     ; convert buffer pointer eax to the absolute address
  652.     mov     ecx, IPBUFFSIZE
  653.     mul     ecx
  654.     add     eax, IPbuffs
  655.  
  656.     mov     edx, eax
  657.  
  658.     ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
  659.  
  660.     ; Fill in the IP header ( some data is in the socket descriptor)
  661.     mov     eax, [ebx + 8]
  662.     mov     [edx + 12], eax      ; source IP
  663.     mov     eax, [ebx + 16]
  664.     mov     [edx + 16], eax      ; Destination IP
  665.  
  666.     mov     al, 0x45
  667.     mov     [edx], al         ; Version, IHL
  668.     xor     al, al
  669.     mov     [edx + 1], al     ; Type of service
  670.  
  671.     pop     eax                   ; Get the UDP data length
  672.     push    eax
  673.  
  674.     add     eax, 20 + 8           ; add IP header and UDP header lengths
  675.     mov     [edx + 2], ah
  676.     mov     [edx + 3], al
  677.     xor     al, al
  678.     mov     [edx + 4], al
  679.     mov     [edx + 5], al
  680.     mov     al, 0x40
  681.     mov     [edx + 6], al
  682.     xor     al, al
  683.     mov     [edx + 7], al
  684.     mov     al, 0x20
  685.     mov     [edx + 8], al
  686.     mov     al, 17
  687.     mov     [edx + 9], al
  688.  
  689.     ; Checksum left unfilled
  690.     xor     ax, ax
  691.     mov     [edx + 10], ax
  692.  
  693.     ; Fill in the UDP header ( some data is in the socket descriptor)
  694.     mov     ax, [ebx + 12]
  695.     mov     [edx + 20], ax
  696.  
  697.     mov     ax, [ebx + 20]
  698.     mov     [edx + 20 + 2], ax
  699.  
  700.     pop     eax
  701.     push    eax
  702.  
  703.     add     eax, 8
  704.     mov     [edx + 20 + 4], ah
  705.     mov     [edx + 20 + 5], al
  706.  
  707.     ; Checksum left unfilled
  708.     xor     ax, ax
  709.     mov     [edx + 20 + 6], ax
  710.  
  711.     pop     ecx                  ; count of bytes to send
  712.     mov     ebx, ecx            ; need the length later
  713.     pop     eax                  ; get callers ptr to data to send
  714.  
  715.     ; Get the address of the callers data
  716.     mov     edi, [TASK_BASE]
  717.     add     edi, TASKDATA.mem_start
  718.     add     eax, [edi]
  719.     mov     esi, eax
  720.  
  721.     mov     edi, edx
  722.     add     edi, 28
  723.     cld
  724.     rep     movsb               ; copy the data across
  725.  
  726.     ; we have edx as IPbuffer ptr.
  727.     ; Fill in the UDP checksum
  728.     ; First, fill in pseudoheader
  729.     mov     eax, [edx + 12]
  730.     mov     [pseudoHeader], eax
  731.     mov     eax, [edx + 16]
  732.     mov     [pseudoHeader+4], eax
  733.     mov     ax, 0x1100            ; 0 + protocol
  734.     mov     [pseudoHeader+8], ax
  735.     add     ebx, 8
  736.     mov     eax, ebx
  737.     mov     [pseudoHeader+10], ah
  738.     mov     [pseudoHeader+11], al
  739.  
  740.     mov     eax, pseudoHeader
  741.     mov     [checkAdd1], eax
  742.     mov     [checkSize1], word 12
  743.     mov     eax, edx
  744.     add     eax, 20
  745.     mov     [checkAdd2], eax
  746.     mov     eax, ebx
  747.     mov     [checkSize2], ax      ; was eax!! mjh 8/7/02
  748.  
  749.     call    checksum
  750.  
  751.     ; store it in the UDP checksum ( in the correct order! )
  752.     mov     ax, [checkResult]
  753.  
  754.     ; If the UDP checksum computes to 0, we must make it 0xffff
  755.     ; (0 is reserved for 'not used')
  756.     cmp     ax, 0
  757.     jne     sw_001
  758.     mov     ax, 0xffff
  759.  
  760. sw_001:
  761.     mov     [edx + 20 + 6], ah
  762.     mov     [edx + 20 + 7], al
  763.  
  764.     ; Fill in the IP header checksum
  765.     GET_IHL ecx,edx              ; get IP-Header length
  766.     stdcall checksum_jb,edx,ecx  ; buf_ptr, buf_size
  767.  
  768.     mov     [edx + 10], ah
  769.     mov     [edx + 11], al
  770.  
  771.     ; Check destination IP address.
  772.     ; If it is the local host IP, route it back to IP_RX
  773.  
  774.     pop     ebx
  775.     mov     eax, NET1OUT_QUEUE
  776.  
  777.     mov     ecx, [ edx + 16]
  778.     mov     edx, [stack_ip]
  779.     cmp     edx, ecx
  780.     jne     sw_notlocal
  781.     mov     eax, IPIN_QUEUE
  782.  
  783. sw_notlocal:
  784.     ; Send it.
  785.     call    queue
  786.  
  787.     xor     eax, eax
  788.  
  789. sw_exit:
  790.     ret
  791.  
  792.  
  793.  
  794. ;***************************************************************************
  795. ;   Function
  796. ;      socket_write_tcp
  797. ;
  798. ;   Description
  799. ;       socket in ebx
  800. ;       # of bytes to write in ecx
  801. ;       pointer to data in edx
  802. ;       returns 0 in eax ok, -1 == failed ( invalid socket, or
  803. ;       could not queue IP packet )
  804. ;
  805. ;***************************************************************************
  806. socket_write_tcp:
  807.         Index2RealAddr ebx
  808.  
  809.     mov     [sktAddr], ebx
  810.  
  811.     mov     eax, 0xFFFFFFFF
  812.     ; If the socket is invalid, return with an error code
  813.     cmp     [ebx], dword SOCK_EMPTY
  814.     je      swt_exit
  815.  
  816.     ; If the sockets window timer is nonzero, do not queue packet
  817.     ; TODO - done
  818.     cmp     [ebx + SOCKET.wndsizeTimer], dword 0
  819.     jne     swt_exit
  820.  
  821.     mov     eax, EMPTY_QUEUE
  822.     call    dequeue
  823.     cmp     ax, NO_BUFFER
  824.     je      swt_exit
  825.  
  826.     push    eax
  827.  
  828.     mov     bl, 0x10        ; ACK
  829.  
  830.     ; Get the address of the callers data
  831.     mov     edi, [TASK_BASE]
  832.     add     edi, TASKDATA.mem_start
  833.     add     edx, [edi]
  834.     mov     esi, edx
  835.  
  836.     pop     eax
  837.     push    eax
  838.  
  839.     push    ecx
  840.     call    buildTCPPacket
  841.     pop     ecx
  842.  
  843.     ; Check destination IP address.
  844.     ; If it is the local host IP, route it back to IP_RX
  845.  
  846.     pop     ebx
  847.     push    ecx
  848.     mov     eax, NET1OUT_QUEUE
  849.  
  850.     mov     edx, [stack_ip]
  851.     mov     ecx, [sktAddr ]
  852.     mov     ecx, [ecx + 16]
  853.     cmp     edx, ecx
  854.     jne     swt_notlocal
  855.     mov     eax, IPIN_QUEUE
  856.  
  857. swt_notlocal:
  858.     pop     ecx
  859.  
  860.     push    ebx                 ; save ipbuffer number
  861.  
  862.     call    queue
  863.  
  864.     mov     esi, [sktAddr]
  865.  
  866.     ; increament SND.NXT in socket
  867.     ; Amount to increment by is in ecx
  868.     add     esi, 48
  869.     call    add_inet_esi
  870.  
  871.     pop     ebx
  872.  
  873.     ; Copy the IP buffer to a resend queue
  874.     ; If there isn't one, dont worry about it for now
  875.     mov     esi, resendQ
  876.     mov     ecx, 0
  877.  
  878. swt003:
  879.     cmp     ecx, NUMRESENDENTRIES
  880.     je      swt001              ; None found
  881.     cmp     [esi], byte 0xFF
  882.     je      swt002              ; found one
  883.     inc     ecx
  884.     add     esi, 4
  885.     jmp     swt003
  886.  
  887. swt002:
  888.     push    ebx
  889.  
  890.     ; OK, we have a buffer descriptor ptr in esi.
  891.     ; resend entry # in ecx
  892.     ;  Populate it
  893.     ;  socket #
  894.     ;  retries count
  895.     ;  retry time
  896.     ;  fill IP buffer associated with this descriptor
  897.  
  898.     mov     eax, [sktAddr]
  899.     sub     eax, sockets
  900.     shr     eax, 12             ; get skt #
  901.     mov     [esi], al
  902.     mov     [esi + 1], byte TCP_RETRIES
  903.     mov     [esi + 2], word TCP_TIMEOUT
  904.  
  905.     inc     ecx
  906.     ; Now get buffer location, and copy buffer across. argh! more copying,,
  907.     mov     edi, resendBuffer - IPBUFFSIZE
  908. swt002a:
  909.     add     edi, IPBUFFSIZE
  910.     loop    swt002a
  911.  
  912.     ; we have dest buffer location in edi
  913.     pop     eax
  914.     ; convert source buffer pointer eax to the absolute address
  915.     mov     ecx, IPBUFFSIZE
  916.     mul     ecx
  917.     add     eax, IPbuffs
  918.     mov     esi, eax
  919.  
  920.     ; do copy
  921.     mov     ecx, IPBUFFSIZE
  922.     cld
  923.     rep     movsb
  924.  
  925. swt001:
  926.     xor     eax, eax
  927.  
  928. swt_exit:
  929.     ret
  930.  
  931.