Subversion Repositories Kolibri OS

Rev

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

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