Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2021. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;  STACK.INC                                                      ;;
  7. ;;                                                                 ;;
  8. ;;  TCP/IP stack for KolibriOS                                     ;;
  9. ;;                                                                 ;;
  10. ;;    Written by hidnplayr@kolibrios.org                           ;;
  11. ;;                                                                 ;;
  12. ;;     Some parts of code are based on the work of:                ;;
  13. ;;      Mike Hibbett (menuetos network stack)                      ;;
  14. ;;      Eugen Brasoveanu (solar os network stack and drivers)      ;;
  15. ;;      mike.dld (kolibrios socket code)                           ;;
  16. ;;                                                                 ;;
  17. ;;     TCP part is based on 4.4BSD                                 ;;
  18. ;;                                                                 ;;
  19. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  20. ;;             Version 2, June 1991                                ;;
  21. ;;                                                                 ;;
  22. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  23.  
  24. $Revision: 8986 $
  25.  
  26. uglobal
  27.         net_10ms        dd ?
  28.         net_tmr_count   dw ?
  29. endg
  30.  
  31. DEBUG_NETWORK_ERROR     = 1
  32. DEBUG_NETWORK_VERBOSE   = 0
  33.  
  34. NET_DEVICES_MAX         = 16
  35. NET_BUFFERS             = 512
  36. NET_BUFFER_SIZE         = 2048
  37. ARP_BLOCK               = 1             ; true or false
  38.  
  39. EPHEMERAL_PORT_MIN      = 49152
  40. EPHEMERAL_PORT_MAX      = 61000
  41. MIN_EPHEMERAL_PORT_N    = 0x00C0        ; same in Network byte order (FIXME)
  42. MAX_EPHEMERAL_PORT_N    = 0x48EE        ; same in Network byte order (FIXME)
  43.  
  44. ; Ethernet protocol numbers
  45. ETHER_PROTO_ARP                 = 0x0608
  46. ETHER_PROTO_IPv4                = 0x0008
  47. ETHER_PROTO_IPv6                = 0xDD86
  48. ETHER_PROTO_PPP_DISCOVERY       = 0x6388
  49. ETHER_PROTO_PPP_SESSION         = 0x6488
  50.  
  51. ; Internet protocol numbers
  52. IP_PROTO_IP             = 0
  53. IP_PROTO_ICMP           = 1
  54. IP_PROTO_TCP            = 6
  55. IP_PROTO_UDP            = 17
  56. IP_PROTO_RAW            = 255
  57.  
  58. ; IP options
  59. IP_TOS                  = 1
  60. IP_TTL                  = 2
  61. IP_HDRINCL              = 3
  62.  
  63. ; PPP protocol numbers
  64. PPP_PROTO_IPv4          = 0x2100
  65. PPP_PROTO_IPV6          = 0x5780
  66. PPP_PROTO_ETHERNET      = 666           ; FIXME
  67.  
  68. ;Protocol family
  69. AF_UNSPEC               = 0
  70. AF_LOCAL                = 1
  71. AF_INET4                = 2
  72. AF_INET6                = 10
  73. AF_PPP                  = 777           ; FIXME
  74.  
  75. ; Socket types
  76. SOCK_STREAM             = 1
  77. SOCK_DGRAM              = 2
  78. SOCK_RAW                = 3
  79.  
  80. ; Socket level
  81. SOL_SOCKET              = 0xffff
  82.  
  83. ; Socket options
  84. SO_ACCEPTCON            = 1 shl 0
  85. SO_BROADCAST            = 1 shl 1
  86. SO_DEBUG                = 1 shl 2
  87. SO_DONTROUTE            = 1 shl 3
  88. SO_KEEPALIVE            = 1 shl 4
  89. SO_OOBINLINE            = 1 shl 5
  90. SO_REUSEADDR            = 1 shl 6
  91. SO_REUSEPORT            = 1 shl 7
  92. SO_USELOOPBACK          = 1 shl 8
  93. SO_BINDTODEVICE         = 1 shl 9
  94. SO_LINGER               = 1 shl 10
  95.  
  96. SO_NONBLOCK             = 1 shl 31
  97.  
  98. ; Socket flags for user calls
  99. MSG_PEEK                = 0x02
  100. MSG_DONTWAIT            = 0x40
  101.  
  102. ; Socket States
  103. SS_NOFDREF              = 0x0001        ; no file table ref any more
  104. SS_ISCONNECTED          = 0x0002        ; socket connected to a peer
  105. SS_ISCONNECTING         = 0x0004        ; in process of connecting to peer
  106. SS_ISDISCONNECTING      = 0x0008        ; in process of disconnecting
  107. SS_CANTSENDMORE         = 0x0010        ; can't send more data to peer
  108. SS_CANTRCVMORE          = 0x0020        ; can't receive more data from peer
  109. SS_RCVATMARK            = 0x0040        ; at mark on input
  110. SS_ISABORTING           = 0x0080        ; aborting fd references - close()
  111. SS_RESTARTSYS           = 0x0100        ; restart blocked system calls
  112. SS_ISDISCONNECTED       = 0x0800        ; socket disconnected from peer
  113.  
  114. SS_ASYNC                = 0x1000        ; async i/o notify
  115. SS_ISCONFIRMING         = 0x2000        ; deciding to accept connection req
  116. SS_MORETOCOME           = 0x4000
  117.  
  118. SS_BLOCKED              = 0x8000
  119.  
  120.  
  121. SOCKET_BUFFER_SIZE      = 4096*8        ; must be 4096*(power of 2) where 'power of 2' is at least 8
  122. MAX_backlog             = 20            ; maximum backlog for stream sockets
  123.  
  124. ; Error Codes
  125. ENOBUFS                 = 1
  126. EINPROGRESS             = 2
  127. EOPNOTSUPP              = 4
  128. EWOULDBLOCK             = 6
  129. ENOTCONN                = 9
  130. EALREADY                = 10
  131. EINVAL                  = 11
  132. EMSGSIZE                = 12
  133. ENOMEM                  = 18
  134. EADDRINUSE              = 20
  135. EADDRNOTAVAIL           = 21
  136. ECONNRESET              = 52
  137. ECONNABORTED            = 53
  138. EISCONN                 = 56
  139. ETIMEDOUT               = 60
  140. ECONNREFUSED            = 61
  141.  
  142. ; Api protocol numbers
  143. API_ETH                 = 0
  144. API_IPv4                = 1
  145. API_ICMP                = 2
  146. API_UDP                 = 3
  147. API_TCP                 = 4
  148. API_ARP                 = 5
  149. API_PPPOE               = 6
  150. API_IPv6                = 7
  151.  
  152. ; Network device types
  153. NET_DEVICE_LOOPBACK     = 0
  154. NET_DEVICE_ETH          = 1
  155. NET_DEVICE_SLIP         = 2
  156.  
  157. ; Network link types (link protocols)
  158. NET_LINK_LOOPBACK       = 0
  159. NET_LINK_MAC            = 1     ; Media access control (ethernet, isdn, ...)
  160. NET_LINK_PPP            = 2     ; Point to Point Protocol (PPPoE, ...)
  161. NET_LINK_IEEE802.11     = 3     ; IEEE 802.11 (WiFi)
  162.  
  163. ; Hardware acceleration bits
  164. NET_HWACC_TCP_IPv4_IN   = 1 shl 0
  165. NET_HWACC_TCP_IPv4_OUT  = 1 shl 1
  166.  
  167. ; Network frame types
  168. NET_BUFF_LOOPBACK       = 0
  169. NET_BUFF_ETH            = 1
  170.  
  171. struct  NET_DEVICE
  172.  
  173.         device_type     dd ?    ; Type field
  174.         mtu             dd ?    ; Maximal Transmission Unit
  175.         name            dd ?    ; Ptr to 0 terminated string
  176.  
  177.         unload          dd ?    ; Ptrs to driver functions
  178.         reset           dd ?    ;
  179.         transmit        dd ?    ;
  180.  
  181.         link_state      dd ?    ; link state (0 = no link)
  182.         hwacc           dd ?    ; bitmask stating enabled HW accelerations (offload engines)
  183.  
  184.         bytes_tx        dq ?    ; Statistics, updated by the driver
  185.         bytes_rx        dq ?    ;
  186.  
  187.         packets_tx      dd ?    ;
  188.         packets_tx_err  dd ?    ; CRC errors, too long or too short frames
  189.         packets_tx_drop dd ?    ;
  190.         packets_tx_ovr  dd ?    ; FIFO overrun
  191.  
  192.         packets_rx      dd ?    ;
  193.         packets_rx_err  dd ?    ; CRC errors, too long or too short frames
  194.         packets_rx_drop dd ?    ;
  195.         packets_rx_ovr  dd ?    ; FIFO overrun
  196.  
  197. ends
  198.  
  199. struct  NET_BUFF
  200.  
  201.         NextPtr         dd ?    ; pointer to next frame in list
  202.         PrevPtr         dd ?    ; pointer to previous frame in list
  203.         device          dd ?    ; ptr to NET_DEVICE structure
  204.         type            dd ?    ; encapsulation type: e.g. Ethernet
  205.         length          dd ?    ; size of encapsulated data
  206.         offset          dd ?    ; offset to actual data (24 bytes for default frame)
  207.         data            rb 0
  208.  
  209. ends
  210.  
  211.  
  212. ; Exactly as it says..
  213. macro pseudo_random reg {
  214.         add     reg, [esp]
  215.         rol     reg, 5
  216.         xor     reg, [timer_ticks]
  217. ;        add     reg, [CPU_FREQ]
  218.         imul    reg, 214013
  219.         xor     reg, 0xdeadbeef
  220.         rol     reg, 9
  221. }
  222.  
  223. ; Network to Hardware byte order (dword)
  224. macro ntohd reg {
  225.  
  226.         rol     word reg, 8
  227.         rol     dword reg, 16
  228.         rol     word reg , 8
  229.  
  230. }
  231.  
  232. ; Network to Hardware byte order (word)
  233. macro ntohw reg {
  234.  
  235.         rol     word reg, 8
  236.  
  237. }
  238.  
  239.  
  240. include "queue.inc"
  241.  
  242. include "loopback.inc"
  243. include "ethernet.inc"
  244.  
  245. include "PPPoE.inc"
  246.  
  247. include "ARP.inc"
  248. include "IPv4.inc"
  249. include "IPv6.inc"
  250.  
  251. include "icmp.inc"
  252. include "udp.inc"
  253. include "tcp.inc"
  254.  
  255. include "socket.inc"
  256.  
  257.  
  258.  
  259. uglobal
  260. align 4
  261.  
  262.         net_device_count        dd ?
  263.         net_device_list         rd NET_DEVICES_MAX
  264.  
  265.         net_buffs_free          rd NET_BUFFERS
  266.         .current                dd ?
  267.  
  268. endg
  269.  
  270.  
  271. ;-----------------------------------------------------------------;
  272. ;                                                                 ;
  273. ; stack_init: Initialize all network variables                    ;
  274. ;                                                                 ;
  275. ;  IN:  /                                                         ;
  276. ;  OUT: /                                                         ;
  277. ;                                                                 ;
  278. ;-----------------------------------------------------------------;
  279. align 4
  280. stack_init:
  281.  
  282. ; allocate network buffers
  283.         stdcall kernel_alloc, NET_BUFFER_SIZE*NET_BUFFERS
  284.         test    eax, eax
  285.         jz      .fail
  286.  
  287.         mov     edi, net_buffs_free
  288.         mov     ecx, NET_BUFFERS
  289.         cld
  290.   .loop:
  291.         stosd
  292.         add     eax, NET_BUFFER_SIZE
  293.         dec     ecx
  294.         jnz     .loop
  295.  
  296.         mov     eax, net_buffs_free
  297.         stosd
  298.  
  299. ; Init the network drivers list
  300.         xor     eax, eax
  301.         mov     edi, net_device_count
  302.         mov     ecx, (NET_DEVICES_MAX + 1)
  303.         rep stosd
  304.  
  305.         eth_init
  306.  
  307.         pppoe_init
  308.  
  309.         ipv4_init
  310. ;        ipv6_init
  311.         icmp_init
  312.  
  313.         arp_init
  314.         udp_init
  315.         tcp_init
  316.  
  317.         socket_init
  318.  
  319.         loop_init
  320.  
  321.         mov     [net_tmr_count], 0
  322.         ret
  323.  
  324.   .fail:
  325.         DEBUGF  DEBUG_NETWORK_ERROR, "Stack init failed!\n"
  326.         ret
  327.  
  328.  
  329.  
  330. ; Wakeup every tick.
  331. proc stack_handler_has_work?
  332.  
  333.         mov     eax, [timer_ticks]
  334.         cmp     eax, [net_10ms]
  335.  
  336.         ret
  337. endp
  338.  
  339.  
  340. ;-----------------------------------------------------------------;
  341. ;                                                                 ;
  342. ; stack_handler: Network handlers called from os_loop.            ;
  343. ;                                                                 ;
  344. ;  IN:  /                                                         ;
  345. ;  OUT: /                                                         ;
  346. ;                                                                 ;
  347. ;-----------------------------------------------------------------;
  348. align 4
  349. stack_handler:
  350.  
  351.         ; Test for 10ms tick
  352.         mov     eax, [timer_ticks]
  353.         cmp     eax, [net_10ms]
  354.         je      .exit
  355.         mov     [net_10ms], eax
  356.  
  357.         cmp     [net_device_count], 0
  358.         je      .exit
  359.  
  360.         test    [net_10ms], 0x0f        ; 160ms
  361.         jnz     .exit
  362.  
  363.         tcp_timer_160ms
  364.  
  365.         test    [net_10ms], 0x3f        ; 640ms
  366.         jnz     .exit
  367.  
  368.         arp_decrease_entry_ttls
  369.         ipv4_decrease_fragment_ttls
  370.  
  371.         xor     edx, edx
  372.         mov     eax, [TCP_timer1_event]
  373.         mov     ebx, [eax + EVENT.id]
  374.         xor     esi, esi
  375.         call    raise_event
  376.  
  377.   .exit:
  378.         ret
  379.  
  380.  
  381. align 4
  382. proc net_buff_alloc stdcall, buffersize
  383.  
  384.         cmp     [buffersize], NET_BUFFER_SIZE
  385.         ja      .too_large
  386.  
  387.         spin_lock_irqsave
  388.  
  389.         mov     eax, [net_buffs_free.current]
  390.         cmp     eax, net_buffs_free+NET_BUFFERS*4
  391.         jae     .out_of_mem
  392.         mov     eax, [eax]
  393.         add     [net_buffs_free.current], 4
  394.  
  395.         spin_unlock_irqrestore
  396.  
  397.         DEBUGF  DEBUG_NETWORK_VERBOSE, "net_buff_alloc: 0x%x\n", eax
  398.         ret
  399.  
  400.   .out_of_mem:
  401.         spin_unlock_irqrestore
  402.  
  403.         xor     eax, eax
  404.         DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: out of mem!\n"
  405.         ret
  406.  
  407.   .too_large:
  408.         xor     eax, eax
  409.         DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: too large!\n"
  410.         ret
  411. endp
  412.  
  413.  
  414. align 4
  415. proc net_buff_free stdcall, buffer
  416.  
  417.         DEBUGF  DEBUG_NETWORK_VERBOSE, "net_buff_free: 0x%x\n", [buffer]
  418.  
  419.         spin_lock_irqsave
  420.  
  421.         sub     [net_buffs_free.current], 4             ; move pointer backwards
  422.         mov     eax, [net_buffs_free.current]           ; place free'd buffer pointer on the list
  423.         push    [buffer]
  424.         pop     dword[eax]
  425.  
  426.         spin_unlock_irqrestore
  427.  
  428.         ret
  429. endp
  430.  
  431.  
  432. align 4
  433. net_link_changed:
  434.  
  435.         DEBUGF  DEBUG_NETWORK_VERBOSE, "net_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state]
  436.  
  437. align 4
  438. net_send_event:
  439.  
  440.         DEBUGF  DEBUG_NETWORK_VERBOSE, "net_send_event\n"
  441.  
  442. ; Send event to all applications
  443.         push    edi ecx
  444.         mov     edi, SLOT_BASE
  445.         mov     ecx, [thread_count]
  446.   .loop:
  447.         add     edi, sizeof.APPDATA
  448.         or      [edi + APPDATA.occurred_events], EVENT_NETWORK2
  449.         loop    .loop
  450.         pop     ecx edi
  451.  
  452.         ret
  453.  
  454.  
  455.  
  456. ;-----------------------------------------------------------------;
  457. ;                                                                 ;
  458. ; net_add_device: Called by network driver to register interface. ;
  459. ;                                                                 ;
  460. ;  IN:  ebx = ptr to device structure                             ;
  461. ;                                                                 ;
  462. ;  OUT: eax = device num on success                               ;
  463. ;       eax = -1 on error                                         ;
  464. ;                                                                 ;
  465. ;-----------------------------------------------------------------;
  466. align 4
  467. net_add_device:
  468.  
  469.         DEBUGF  DEBUG_NETWORK_VERBOSE, "net_add_device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
  470.  
  471.         cmp     [net_device_count], NET_DEVICES_MAX
  472.         jae     .error
  473.  
  474. ;----------------------------------
  475. ; Check if device is already listed
  476.         mov     eax, ebx
  477.         mov     ecx, NET_DEVICES_MAX    ; We need to check whole list because a device may be removed without re-organizing list
  478.         mov     edi, net_device_list
  479.  
  480.         repne scasd                     ; See if device is already in the list
  481.         jz      .error
  482.  
  483. ;----------------------------
  484. ; Find empty slot in the list
  485.         xor     eax, eax
  486.         mov     ecx, NET_DEVICES_MAX
  487.         mov     edi, net_device_list
  488.  
  489.         repne scasd
  490.         jnz     .error
  491.  
  492.         sub     edi, 4
  493.  
  494. ;-----------------------------
  495. ; Add device to the found slot
  496.         mov     [edi], ebx              ; add device to list
  497.  
  498.         mov     eax, edi                ; Calculate device number in eax
  499.         sub     eax, net_device_list
  500.         shr     eax, 2
  501.  
  502.         inc     [net_device_count]      ; Indicate that one more network device is up and running
  503.  
  504.         call    net_send_event
  505.  
  506.         DEBUGF  DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax
  507.         ret
  508.  
  509.   .error:
  510.         or      eax, -1
  511.         DEBUGF  DEBUG_NETWORK_ERROR, "Adding network device failed\n"
  512.         ret
  513.  
  514.  
  515.  
  516. ;-----------------------------------------------------------------;
  517. ;                                                                 ;
  518. ; net_remove_device: Called by network driver to unregister dev.  ;
  519. ;                                                                 ;
  520. ;  IN:  ebx = ptr to device                                       ;
  521. ;                                                                 ;
  522. ;  OUT: eax: -1 on error                                          ;
  523. ;                                                                 ;
  524. ;-----------------------------------------------------------------;
  525. align 4
  526. net_remove_device:
  527.  
  528.         cmp     [net_device_count], 0
  529.         je      .error
  530.  
  531. ;----------------------------
  532. ; Find the driver in the list
  533.  
  534.         mov     eax, ebx
  535.         mov     ecx, NET_DEVICES_MAX
  536.         mov     edi, net_device_list
  537.  
  538.         repne scasd
  539.         jnz     .error
  540.  
  541. ;------------------------
  542. ; Remove it from the list
  543.  
  544.         xor     eax, eax
  545.         mov     dword [edi-4], eax
  546.         dec     [net_device_count]
  547.  
  548.         call    net_send_event
  549.  
  550.         xor     eax, eax
  551.         ret
  552.  
  553.   .error:
  554.         or      eax, -1
  555.         ret
  556.  
  557.  
  558.  
  559. ;-----------------------------------------------------------------;
  560. ;                                                                 ;
  561. ; net_ptr_to_num                                                  ;
  562. ;                                                                 ;
  563. ;  IN:  ebx = ptr to device struct                                ;
  564. ;                                                                 ;
  565. ;  OUT: edi = device number                                       ;
  566. ;       edi = -1 on error                                         ;
  567. ;                                                                 ;
  568. ;-----------------------------------------------------------------;
  569. align 4
  570. net_ptr_to_num:
  571.  
  572.         call    net_ptr_to_num4
  573.         ror     edi, 2          ; If -1, stay -1
  574.                                 ; valid device numbers have last two bits 0, so do just shr
  575.  
  576.         ret
  577.  
  578. align 4
  579. net_ptr_to_num4:                ; Todo, place number in device structure so we only need to verify?
  580.  
  581.         test    ebx, ebx
  582.         jz      .fail
  583.  
  584.         push    ecx
  585.         mov     ecx, NET_DEVICES_MAX
  586.         mov     edi, net_device_list
  587.   .loop:
  588.         cmp     ebx, [edi]
  589.         je      .found
  590.         add     edi, 4
  591.         dec     ecx
  592.         jnz     .loop
  593.  
  594.         pop     ecx
  595.   .fail:
  596.         or      edi, -1
  597.         ret
  598.  
  599.   .found:
  600.         sub     edi, net_device_list
  601.         pop     ecx
  602.         ret
  603.  
  604. ;-----------------------------------------------------------------;
  605. ;                                                                 ;
  606. ; checksum_1: Calculate semi-checksum for network packets.        ;
  607. ;                                                                 ;
  608. ;  IN:  edx = start offset for semi-checksum                      ;
  609. ;       esi = pointer to data                                     ;
  610. ;       ecx = data size                                           ;
  611. ;                                                                 ;
  612. ;  OUT: edx = semi-checksum                                       ;
  613. ;                                                                 ;
  614. ;-----------------------------------------------------------------;
  615. align 4
  616. checksum_1:
  617.  
  618.         shr     ecx, 1
  619.         pushf
  620.         jz      .no_2
  621.  
  622.         shr     ecx, 1
  623.         pushf
  624.         jz      .no_4
  625.  
  626.         shr     ecx, 1
  627.         pushf
  628.         jz      .no_8
  629.  
  630.   .loop:
  631.         add     dl, [esi+1]
  632.         adc     dh, [esi+0]
  633.  
  634.         adc     dl, [esi+3]
  635.         adc     dh, [esi+2]
  636.  
  637.         adc     dl, [esi+5]
  638.         adc     dh, [esi+4]
  639.  
  640.         adc     dl, [esi+7]
  641.         adc     dh, [esi+6]
  642.  
  643.         adc     edx, 0
  644.         add     esi, 8
  645.  
  646.         dec     ecx
  647.         jnz     .loop
  648.  
  649.         adc     edx, 0
  650.  
  651.   .no_8:
  652.         popf
  653.         jnc     .no_4
  654.  
  655.         add     dl, [esi+1]
  656.         adc     dh, [esi+0]
  657.  
  658.         adc     dl, [esi+3]
  659.         adc     dh, [esi+2]
  660.  
  661.         adc     edx, 0
  662.         add     esi, 4
  663.  
  664.   .no_4:
  665.         popf
  666.         jnc     .no_2
  667.  
  668.         add     dl, [esi+1]
  669.         adc     dh, [esi+0]
  670.  
  671.         adc     edx, 0
  672.         inc     esi
  673.         inc     esi
  674.  
  675.   .no_2:
  676.         popf
  677.         jnc     .end
  678.  
  679.         add     dh, [esi+0]
  680.         adc     edx, 0
  681.   .end:
  682.         ret
  683.  
  684. ;-----------------------------------------------------------------;
  685. ;                                                                 ;
  686. ; checksum_2: Calculate the final ip/tcp/udp checksum.            ;
  687. ;                                                                 ;
  688. ;   IN: edx = semi-checksum                                       ;
  689. ;                                                                 ;
  690. ;  OUT: dx = checksum (in INET byte order)                        ;
  691. ;                                                                 ;
  692. ;-----------------------------------------------------------------;
  693. align 4
  694. checksum_2:
  695.  
  696.         mov     ecx, edx
  697.         shr     ecx, 16
  698.         and     edx, 0xffff
  699.         add     edx, ecx
  700.  
  701.         mov     ecx, edx
  702.         shr     ecx, 16
  703.         add     dx, cx
  704.         test    dx, dx          ; it seems that ZF is not set when CF is set :(
  705.         not     dx
  706.         jnz     .not_zero
  707.         dec     dx
  708.   .not_zero:
  709.         xchg    dl, dh
  710.  
  711.         DEBUGF  DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx
  712.  
  713.         ret
  714.  
  715.  
  716.  
  717. ;-----------------------------------------------------------------;
  718. ;                                                                 ;
  719. ;  System function 74: Low level access to network devices.       ;
  720. ;                                                                 ;
  721. ;-----------------------------------------------------------------;
  722. align 4
  723. syscall_network:
  724.  
  725.         cmp     bl, 255
  726.         jne     @f
  727.  
  728.         mov     eax, [net_device_count]
  729.         mov     [esp+32], eax
  730.         ret
  731.  
  732.    @@:
  733.         cmp     bh, NET_DEVICES_MAX                     ; Check if device number exists
  734.         jae     .doesnt_exist
  735.  
  736.         mov     esi, ebx
  737.         and     esi, 0x0000ff00
  738.         shr     esi, 6
  739.  
  740.         cmp     dword[esi + net_device_list], 0         ; check if device is running
  741.         je      .doesnt_exist
  742.  
  743.         mov     eax, [esi + net_device_list]
  744.  
  745.         and     ebx, 0x000000ff
  746.         cmp     ebx, .number
  747.         ja      .doesnt_exist
  748.         jmp     dword [.table + 4*ebx]
  749.  
  750.   .table:
  751.         dd      .get_type               ; 0
  752.         dd      .get_dev_name           ; 1
  753.         dd      .reset                  ; 2
  754.         dd      .stop                   ; 3
  755.         dd      .get_ptr                ; 4
  756.         dd      .get_drv_name           ; 5
  757.  
  758.         dd      .packets_tx             ; 6
  759.         dd      .packets_rx             ; 7
  760.         dd      .bytes_tx               ; 8
  761.         dd      .bytes_rx               ; 9
  762.         dd      .state                  ; 10
  763.   .number = ($ - .table) / 4 - 1
  764.  
  765.   .get_type:
  766.         mov     eax, [eax + NET_DEVICE.device_type]
  767.         mov     [esp+32], eax
  768.         ret
  769.  
  770.   .get_dev_name:
  771. ; { Patch by Coldy, sanity check
  772.         mov     ebx, eax ; eax will used for is_region_userspace return
  773.         stdcall is_region_userspace, ecx, 64
  774.         jz      .bad_buffer      
  775.         mov     esi, [ebx + NET_DEVICE.name] ;mov     esi, [eax + NET_DEVICE.name]
  776. ; } End patch by Coldy, sanity check
  777.         mov     edi, ecx
  778.  
  779.         mov     ecx, 64/4 ; max length
  780.         rep movsd
  781.  
  782.         xor     eax, eax
  783.         mov     [esp+32], eax
  784.         ret
  785.  
  786.   .reset:
  787.         call    [eax + NET_DEVICE.reset]
  788.         mov     [esp+32], eax
  789.         ret
  790.  
  791.   .stop:
  792.         call    [eax + NET_DEVICE.unload]
  793.         mov     [esp+32], eax
  794.         ret
  795.  
  796.  
  797.   .get_ptr:
  798.         mov     [esp+32], eax
  799.         ret
  800.  
  801.  
  802.   .get_drv_name:
  803.         xor     eax, eax
  804.         mov     [esp+32], eax
  805.         ret
  806.  
  807.   .packets_tx:
  808.         mov     eax, [eax + NET_DEVICE.packets_tx]
  809.         mov     [esp+32], eax
  810.         ret
  811.  
  812.   .packets_rx:
  813.         mov     eax, [eax + NET_DEVICE.packets_rx]
  814.         mov     [esp+32], eax
  815.         ret
  816.  
  817.   .bytes_tx:
  818.         mov     ebx, dword[eax + NET_DEVICE.bytes_tx + 4]
  819.         mov     [esp+20], ebx
  820.         mov     eax, dword[eax + NET_DEVICE.bytes_tx]
  821.         mov     [esp+32], eax
  822.         ret
  823.  
  824.   .bytes_rx:
  825.         mov     ebx, dword[eax + NET_DEVICE.bytes_rx + 4]
  826.         mov     [esp+20], ebx
  827.         mov     eax, dword[eax + NET_DEVICE.bytes_rx]
  828.         mov     [esp+32], eax
  829.         ret
  830.  
  831.   .state:
  832.         mov     eax, [eax + NET_DEVICE.link_state]
  833.         mov     [esp+32], eax
  834.         ret
  835.  
  836.  
  837.   .doesnt_exist:
  838.   .bad_buffer: ; Sanity check failed, exit
  839.         mov     dword[esp+32], -1
  840.         ret
  841.  
  842.  
  843.  
  844. ;-----------------------------------------------------------------;
  845. ;                                                                 ;
  846. ;  System function 76: Low level access to protocol handlers.     ;
  847. ;                                                                 ;
  848. ;-----------------------------------------------------------------;
  849. align 4
  850. syscall_protocols:
  851.         cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
  852.         jae     .doesnt_exist
  853.  
  854.         mov     eax, ebx
  855.         and     eax, 0x0000ff00
  856.         shr     eax, 6                          ; now we have the device num * 4 in eax
  857.         cmp     [eax + net_device_list], 0      ; check if device is running
  858.         je      .doesnt_exist
  859.  
  860.         push    .return                         ; return address (we will be using jumps instead of calls)
  861.  
  862.         mov     eax, ebx                        ; set ax to protocol number
  863.         shr     eax, 16                         ;
  864.  
  865.         cmp     ax, API_ETH
  866.         je      eth_api
  867.  
  868.         cmp     ax, API_IPv4
  869.         je      ipv4_api
  870.  
  871.         cmp     ax, API_ICMP
  872.         je      icmp_api
  873.  
  874.         cmp     ax, API_UDP
  875.         je      udp_api
  876.  
  877.         cmp     ax, API_TCP
  878.         je      tcp_api
  879.  
  880.         cmp     ax, API_ARP
  881.         je      arp_api
  882.  
  883.         cmp     ax, API_PPPOE
  884.         je      pppoe_api
  885.  
  886.         cmp     ax, API_IPv6
  887.         je      ipv6_api
  888.  
  889.         add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
  890.  
  891.   .doesnt_exist:
  892.         mov     eax, -1
  893.  
  894.   .return:
  895.         mov     [esp+28+4], eax                 ; return eax value to the program
  896.         ret
  897.