Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2009-2012. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;; Clevermouse & hidnplayr                                      ;;
  7. ;;                                                              ;;
  8. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  9.  
  10.  
  11. struct  PPPoE_header
  12.  
  13.         VersionAndType  db ?
  14.         Code            db ?
  15.         SessionID       dw ?
  16.         Length          dw ?            ; Length of payload, does NOT include the length PPPoE header.
  17.  
  18. ends
  19.  
  20. struct  PPPoE_connection
  21.  
  22.         next            dd ?            ; pointer to next connection
  23.         prev            dd ?            ; pointer to previous connection
  24.  
  25.         pid             dd ?            ; identifier of base application
  26.  
  27.         datalen         dd ?            ; length of received data
  28.         recvbuf         rb 1500         ; buffer for received data
  29.         sendbuf         rb 1500         ; buffer for data to send
  30.  
  31. ends
  32.  
  33. iglobal
  34. align 4
  35.         PPPoE.head              dd PPPoE.head
  36.         PPPoE.tail              dd PPPoE.head
  37. endg
  38.  
  39. uglobal
  40.         PPPoE.cur_receiver      dd ?
  41.         PPPoE.cur_receiver_ptr  dd ?
  42.         PPPoE.cur_receiver_len  dd ?
  43. endg
  44.  
  45.  
  46. ; Allocates internal structure for future PPPoE actions.
  47. align 4
  48. PPPoE_alloc_connection:
  49.  
  50. ; 1. Allocate memory in the kernel area.
  51.         stdcall kernel_alloc, sizeof.PPPoE_connection
  52.  
  53. ; 1a. If memory allocation failed, return NULL.
  54.         test    eax, eax
  55.         jz      .nothing
  56.  
  57. ; 2. Copy PID of caller to the structure.
  58.         mov     edx, [CURRENT_TASK]
  59.         mov     [eax + PPPoE_connection.pid], edx
  60.  
  61. ; 3. Insert the structure to the list of all connections.
  62.         mov     [eax + PPPoE_connection.next], PPPoE.head
  63.         mov     edx, [PPPoE.tail]
  64.         mov     [eax + PPPoE_connection.prev], edx
  65.         mov     [edx + PPPoE_connection.next], eax
  66.         mov     [PPPoE.tail], eax
  67.  
  68.   .nothing:
  69.         ret
  70.  
  71.  
  72. align 4
  73. PPPoE_free_connection:
  74.  
  75. ; 1. Check that the caller is the owner of this connection.
  76.         mov     eax, [CURRENT_TASK]
  77.         cmp     [ebx+PPPoE_connection.pid], eax
  78.         jnz     .nothing
  79.  
  80. ; 2. Delete the structure from the list of all connections.
  81.         mov     eax, [ebx+PPPoE_connection.next]
  82.         mov     edx, [ebx+PPPoE_connection.prev]
  83.         mov     [eax+PPPoE_connection.prev], edx
  84.         mov     [edx+PPPoE_connection.next], eax
  85.  
  86. ; 3. Free the memory.
  87.         stdcall kernel_free, ebx
  88.  
  89.   .nothing:
  90.         ret
  91.  
  92.  
  93. ; Send PADI packet
  94.  
  95. ; ebx (ecx in app) = size of buffer for PPPoE offers, must be at least 1514
  96. ; ecx (edx in app) = size of tags, 0 means "use default"
  97. ; edx (esi in app) = pointer to buffer for PPPoE offers
  98. ; esi (edi in app) = pointer to tags, ignored if 'size of tags' == 0
  99. align 4
  100. PPPoE_send_init:
  101.  
  102. ; 1. Check length.
  103.         cmp     ebi, 1514
  104.         jb      .bad
  105.  
  106. ; RFC2516: An entire PADI packet (including the PPPoE header) MUST NOT
  107. ; exceed 1484 octets.
  108. ; PPPoE header is 6 bytes long, so maximum length of tags is 1478.
  109.         cmp     ecx, 1478
  110.         ja      .bad
  111.  
  112. ; 2. Check that no one listen for offers.
  113.         cmp     [PPPoE.cur_receiver], 0
  114.         jnz     .bad
  115.  
  116. ; 3. Remember PID and data pointer of current listener.
  117.         push    [CURRENT_TASK]
  118.         pop     [PPPoE.cur_receiver]
  119.         mov     [PPPoE.cur_receiver_ptr], edx
  120.         mov     [PPPoE.cur_receiver_len], ebx
  121.         and     dword [edx], 0 ; no offers yet
  122.  
  123. ; 4. Create packet.
  124.         test    ecx, ecx
  125.         jnz     @f
  126.         mov     esi, .default_payload
  127.         mov     ecx, .default_payload_length
  128.        @@:
  129.  
  130.         mov     edx, [NET_DRV_LIST]     ;;;; FIXME
  131.         lea     eax, [ebx + ETH_DEVICE.mac]     ; Source Address
  132.         mov     edx, ETH_BROADCAST              ; Destination Address
  133.         add     ecx, sizeof.PPPoE_header        ; Data size
  134.         mov     di, ETHER_PPP_DISCOVERY         ; Protocol
  135.         call    ETH_output
  136.         jz      .eth_error
  137.  
  138.         push    edx eax
  139.  
  140. ; 4b. Set ver=1, type=1 (=> first byte 0x11), code=9 (PADI packet), session=0
  141.         mov     dword [edi], (0x09 shl 8) + 0x11
  142.  
  143. ; 4c. Set payload length.
  144.         mov     [edi+4], ch
  145.         mov     [edi+5], cl
  146.  
  147. ; 4e. Copy given tags.
  148.         rep     movsb
  149.  
  150. ; 5. Send packet.
  151.         call    [ebx + NET_DEVICE.transmit]
  152. ; 6. Return.
  153.         xor     eax, eax
  154.         ret
  155.  
  156.   .bad:
  157.         or      eax, -1
  158.         ret
  159.  
  160.   .default_payload:
  161. ; Service-Name tag with zero length
  162.         dw      0x0101, 0x0000
  163.   .default_payload_length = $ - .default_payload
  164.  
  165.  
  166. ; Stop receiving PADO packets
  167. align 4
  168. PPPoE_stop_offers:
  169.  
  170. ; Only the listener can stop listen.    ;;; TODO: make sure this function is called when process gets terminated
  171.         mov     eax, [CURRENT_TASK]
  172.         cmp     [PPPoE.cur_receiver], eax
  173.         jnz     .bad
  174.         xor     eax, eax
  175.         mov     [PPPoE.cur_receiver_ptr], eax
  176.         mov     [PPPoE.cur_receiver], eax
  177.         ret
  178.  
  179.   .bad:
  180.         or      eax, -1
  181.         ret
  182.  
  183. ; Send PPPoE data in Discovery stage
  184. align 4
  185. PPPoE_send_discovery:
  186.         ret
  187.  
  188. ; Receive PPPoE data in Discovery stage
  189. align 4
  190. PPPoE_receive_discovery:
  191.         ret
  192.  
  193.  
  194.  
  195. ;-----------------------------------------------------------------
  196. ;
  197. ; PPPoE discovery input
  198. ;
  199. ; Handler of received Ethernet packet with type = Discovery
  200. ;
  201. ;
  202. ;  IN:  Pointer to buffer in [esp]
  203. ;       size of buffer in [esp+4]
  204. ;       pointer to device struct in ebx
  205. ;       pointer to PPP header in edx
  206. ;       size of PPP packet in ecx
  207. ;  OUT: /
  208. ;
  209. ;-----------------------------------------------------------------
  210. align 4
  211. PPPoE_discovery_input:
  212.  
  213. ; 1. Minimum 6 bytes for PPPoE header.
  214.         cmp     ecx, sizeof.PPPoE_header
  215.         jb      .bad
  216.  
  217. ; 1. Ignore packets with ver<>1 and/or type<>1.
  218.         cmp     [edx + PPPoE_header.VersionAndType], 0x11
  219.         jnz     .bad
  220.  
  221. ; 2. Code must be either 7 for Offer,
  222. ; or 0x65 for Session-Confirmation, or 0xa7 for Terminate.
  223. ; Because only Initiation/Offers are supported, we expect only value 7.
  224.         cmp     [edx + PPPoE_header.Code], 7
  225.         jnz     .bad
  226.  
  227. ; 3. Session ID must be zero for Offers.
  228.         cmp     [edx + PPPoE_header.SessionID], 0
  229.         jnz     .bad
  230.  
  231. ; 4. Payload length
  232.         rol     [edx + PPPoE_header.Length], 8          ; Convert INET byte order to intel
  233.  
  234. ; 5. Ignore packet if nobody is listening.
  235.         cmp     [PPPoE.cur_receiver], 0
  236.         jz      .bad
  237.  
  238. ; 6. Good, now copy the received packet to the buffer of listener.
  239.  
  240.         ;;; TODO
  241.  
  242.   .bad:
  243.         DEBUGF 1,'K : PPPoE - dumped\n'
  244.         call    kernel_free
  245.         add     esp, 4                                  ; pop (balance stack)
  246.         ret
  247.  
  248.  
  249.  
  250.  
  251. ;---------------------------------------------------------------------------
  252. ;
  253. ; PPPoE API
  254. ;
  255. ; This function is called by system function 75
  256. ;
  257. ; IN:  subfunction number in bl
  258. ;      device number in bh
  259. ;      ecx, edx, .. depends on subfunction
  260. ;
  261. ; OUT:
  262. ;
  263. ;---------------------------------------------------------------------------
  264. align 4
  265. PPPoE_api:
  266.  
  267.         movzx   eax, bh
  268.         shl     eax, 2
  269.  
  270.         and     ebx, 0xff
  271.         cmp     ebx, .number
  272.         ja      .error
  273.         jmp     dword [.table + 4*ebx]
  274.  
  275.   .table:
  276.         dd      PPPoE_send_init         ; 0
  277.         dd      PPPoE_stop_offers       ; 1
  278.         dd      PPPoE_alloc_connection  ; 3
  279.         dd      PPPoE_free_connection   ; 4
  280.         dd      PPPoE_send_discovery    ; 5
  281.         dd      PPPoE_receive_discovery ; 6
  282.   .number = ($ - .table) / 4 - 1
  283.  
  284.   .error:
  285.         mov     eax, -1
  286.         ret
  287.