Subversion Repositories Kolibri OS

Rev

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

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