Subversion Repositories Kolibri OS

Rev

Rev 1185 | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;  ARP.INC                                                     ;;
  7. ;;                                                              ;;
  8. ;;  Address Resolution Protocol                                 ;;
  9. ;;                                                              ;;
  10. ;;  This file contains the following:                           ;;
  11. ;;   arp_table_manager - Manages an ARPTable                    ;;
  12. ;;   arp_request - Sends an ARP request on the ethernet         ;;
  13. ;;   arp_handler - Called when an ARP packet is received        ;;
  14. ;;                                                              ;;
  15. ;;  Changes history:                                            ;;
  16. ;;   22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net          ;;
  17. ;;   11.11.2006 - [Johnny_B] and [smb]                          ;;
  18. ;;                                                              ;;
  19. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  20.  
  21. $Revision: 983 $
  22.  
  23.  
  24. ARP_NO_ENTRY            equ  0
  25. ARP_VALID_MAPPING       equ  1
  26. ARP_AWAITING_RESPONSE   equ  2
  27. ARP_RESPONSE_TIMEOUT    equ  3
  28.  
  29. ETHER_ARP               equ  0x0608
  30.  
  31. ARP_REQ_OPCODE          equ  0x0100  ; request
  32. ARP_REP_OPCODE          equ  0x0200  ; reply
  33.  
  34. ARP_TABLE_SIZE          equ  20      ; Size of table
  35.  
  36. struct ARP_ENTRY
  37.        .IP              dd  ?
  38.        .MAC             dp  ?
  39.        .Status          dw  ?
  40.        .TTL             dw  ?  ; in seconds
  41.        .size:
  42. ends
  43.  
  44. struct ARP_Packet
  45.        .HardwareType    dw  ?
  46.        .ProtocolType    dw  ?
  47.        .HardwareSize    db  ?
  48.        .ProtocolSize    db  ?
  49.        .Opcode          dw  ?
  50.        .SenderMAC       dp  ?
  51.        .SenderIP        dd  ?
  52.        .TargetMAC       dp  ?
  53.        .TargetIP        dd  ?
  54. ends
  55.  
  56.  
  57. ; The TTL field is decremented every second, and is deleted when it
  58. ; reaches 0. It is refreshed every time a packet is received
  59. ; If the TTL field is 0xFFFF it is a static entry and is never deleted
  60. ; The status field can be the following values:
  61. ; 0x0000  entry not used
  62. ; 0x0001  entry holds a valid mapping
  63. ; 0x0002  entry contains an IP address, awaiting ARP response
  64. ; 0x0003  No response received to ARP request.
  65. ; The last status value is provided to allow the network layer to delete
  66. ; a packet that is queued awaiting an ARP response
  67.  
  68. align 4
  69. uglobal
  70.  
  71.         NumARP          dd ?
  72.         ARPTable        rb ARP_ENTRY.size * ARP_TABLE_SIZE
  73.  
  74.         ARP_PACKETS_TX  rd  MAX_NET_DEVICES
  75.         ARP_PACKETS_RX  rd  MAX_NET_DEVICES
  76.  
  77.  
  78. endg
  79.  
  80.  
  81.  
  82.  
  83. ARP_init:
  84.  
  85.         xor     eax, eax
  86.  
  87.         mov     [NumARP], eax
  88.  
  89.         mov     edi, ARP_PACKETS_TX
  90.         mov     ecx, 2*MAX_NET_DEVICES
  91.         rep     stosd
  92.  
  93.         ret
  94.  
  95.  
  96.  
  97.  
  98. ;***************************************************************************
  99. ;   Function
  100. ;      arp_table_manager  [by Johnny_B]
  101. ;
  102. ;   Description
  103. ;     Does a most required operations with ARP-table
  104. ;  IN:
  105. ;   Operation: see Opcode's constants below
  106. ;       Index: Index of entry in the ARP-table
  107. ;       Extra: Extra parameter for some Opcodes
  108. ;  OUT:
  109. ;   EAX = Returned value depends on opcodes, more detailed see below
  110. ;
  111. ;***************************************************************************
  112. ;Opcode's constants
  113. ARP_TABLE_ADD                 equ  1
  114. ARP_TABLE_IP_TO_MAC           equ  5
  115.  
  116. ;Index's constants
  117. EXTRA_IS_ARP_PACKET_PTR  equ  0   ;if Extra contain pointer to ARP_Packet
  118. EXTRA_IS_ARP_ENTRY_PTR   equ  -1  ;if Extra contain pointer to ARP_ENTRY
  119.  
  120. align 4
  121. proc arp_table_manager stdcall uses ebx esi edi ecx edx, Opcode:DWORD,Index:DWORD,Extra:DWORD
  122.  
  123.     mov     ebx, ARPTable  ;ARPTable base
  124.     mov     ecx, dword[NumARP]         ;ARP-entries counter
  125.  
  126.     mov     eax, dword[Opcode]
  127.  
  128.  
  129.     DEBUGF 1,"ARP table manager opcode:%u numARP:%u\n",eax,ecx
  130.  
  131.     cmp     eax, ARP_TABLE_ADD
  132.     je      .add
  133.  
  134.     cmp     eax, ARP_TABLE_IP_TO_MAC
  135.     je      .ip_to_mac
  136.  
  137.     jmp     .exit     ;if unknown opcode
  138.  
  139.  
  140. ;;BEGIN ADD
  141. ;;Description: it adds an entry in the table. If ARP-table already
  142. ;;             contains same IP, it will be updated.
  143. ;;IN:   Operation: ARP_TABLE_ADD
  144. ;;      Index: specifies what contains Extra-parameter
  145. ;;      Extra: if Index==EXTRA_IS_ARP_Packet_PTR,
  146. ;;             then Extra contains pointer to ARP_Packet,
  147. ;;             otherwise Extra contains pointer to ARP_ENTRY
  148. ;;OUT:
  149. ;;  EAX=index of entry, that has been added
  150. ;;
  151. .add:
  152.  
  153.     DEBUGF 1,"1"
  154.  
  155.     sub     esp, ARP_ENTRY.size   ;Allocate ARP_ENTRY_SIZE byte in stack
  156.  
  157.     mov     esi, [Extra]   ;pointer
  158.     mov     edi, [Index]   ;opcode
  159.  
  160.     cmp     edi, EXTRA_IS_ARP_PACKET_PTR
  161.     je      .ARP_Packet_to_entry ;if Extra contain ptr to ARP_Packet and we have to form arp-entry
  162.                                  ;else it contain ptr to arp-entry
  163.  
  164.     DEBUGF 1,"2"
  165.  
  166.     cld
  167.           ; esi already has been loaded
  168.     mov     edi, esp      ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
  169.     mov     ecx,ARP_ENTRY.size/2  ;ARP_ENTRY_SIZE must be even number!!!
  170.     rep     movsw    ;copy
  171.     jmp     .search
  172.  
  173.   .ARP_Packet_to_entry:
  174.  
  175.     DEBUGF 1,"3"
  176.     mov     edx, dword[esi + ARP_Packet.SenderIP] ;esi=base of ARP_Packet
  177.     mov     [esp + ARP_ENTRY.IP], edx
  178.  
  179.     cld
  180.     lea     esi, [esi + ARP_Packet.SenderMAC]
  181.     lea     edi, [esp + ARP_ENTRY.MAC]
  182.     movsd
  183.     movsw
  184.     mov     word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING  ; specify the type - a valid entry
  185.     mov     word[esp + ARP_ENTRY.TTL], 0x0E10    ; = 1 hour
  186.  
  187.   .search:
  188.  
  189.     DEBUGF 1,"4"
  190.     mov     edx, dword[esp + ARP_ENTRY.IP]  ;edx=IP-address, which we'll search
  191.     mov     ecx, dword[NumARP]              ;ecx=ARP-entries counter
  192.     jecxz   .add_to_end                     ;if ARP-entries number == 0
  193.     imul    eax, ecx, ARP_ENTRY.size        ;eax=current table size(in bytes)
  194.   @@:
  195.     sub     eax, ARP_ENTRY.size
  196.     cmp     dword[ebx + eax + ARP_ENTRY.IP], edx
  197.     loopnz  @b
  198. ;    jz      .replace       ; found, replace existing entry, ptr to it is in eax
  199.  
  200.   .add_to_end:
  201. ;
  202. ;    DEBUGF 1,"5\n"
  203. ;    ;else add to end
  204. ;    or      eax,-1    ;set eax=0xFFFFFFFF if adding is impossible
  205. ;    mov     ecx, dword[NumARP]
  206. ;    cmp     ecx, ARP_TABLE_SIZE
  207. ;    je      .add_exit   ;if arp-entries number is equal to arp-table maxsize
  208.  
  209. ;    imul    eax, dword[NumARP], ARP_ENTRY.size ;eax=ptr to end of ARPTable
  210. ;    inc     dword [NumARP]    ;increase ARP-entries counter
  211.  
  212. ;  .replace:
  213.     DEBUGF 1,"Updating ARP entry: %x-%x-%x-%x-%x-%x = %u.%u.%u.%u to slot:%u\n",\
  214.     [esp + ARP_ENTRY.MAC]:2,[esp + ARP_ENTRY.MAC+1]:2,[esp + ARP_ENTRY.MAC+2]:2,[esp + ARP_ENTRY.MAC+3]:2,[esp + ARP_ENTRY.MAC+4]:2,[esp + ARP_ENTRY.MAC+5]:2,\
  215.     [esp + ARP_ENTRY.IP]:1,[esp + ARP_ENTRY.IP+1]:1,[esp + ARP_ENTRY.IP+2]:1,[esp + ARP_ENTRY.IP+3]:1,eax
  216.  
  217.     cld
  218.     mov     esi, esp              ;esp=base of ARP-entry, that will be added
  219.     lea     edi, [ebx + eax]      ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
  220.     mov     ecx,ARP_ENTRY.size/2  ;ARP_ENTRY_SIZE must be even number!!!
  221.     rep     movsw
  222.  
  223.     mov     ecx, ARP_ENTRY.size
  224.     xor     edx, edx  ;"div" takes operand from EDX:EAX
  225.     div     ecx       ;eax=index of entry, which has been added
  226.  
  227.  
  228.  
  229. .add_exit:
  230.  
  231.     add     esp, ARP_ENTRY.size   ;free stack
  232.     jmp     .exit
  233. ;;END ADD
  234.  
  235.  
  236.  
  237. ;;BEGIN IP_TO_MAC
  238. ;;Description: it gets an IP from Index, scans each entry in the table and writes
  239. ;;             MAC, that relates to specified IP, into buffer specified in Extra.
  240. ;;             And if it cannot find an IP-address in the table, it does an ARP-request of that.
  241. ;;IN:   Operation: ARP_TABLE_IP_TO_MAC
  242. ;;      Index: IP that should be transformed into MAC
  243. ;;      Extra: pointer to buffer where will be written the MAC-address.
  244. ;;OUT:
  245. ;;  EAX=ARP table entry status code.
  246. ;;      If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request.
  247. ;;      If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system.
  248. ;;      If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long.
  249. ;;      If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC.
  250. ;;
  251. ;;  If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet
  252. ;;  resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this
  253. ;;  function with 1sec delay. sure, only if it not return a valid MAC after a first call.
  254. ;;  
  255. .ip_to_mac:
  256.  
  257.     DEBUGF 1,"Trying to find MAC for %u.%u.%u.%u\n",[Index]:1,[Index+1]:1,[Index+2]:1,[Index+3]:1
  258.  
  259.     xor     eax, eax
  260.     mov     edi, dword[Extra]
  261.     cld
  262.     stosd
  263.     stosw
  264.  
  265.  
  266.     ; first, check destination IP to see if it is on 'this' network.
  267.     ; The test is:
  268.     ; if ( destIP & subnet_mask == stack_ip & subnet_mask )
  269.     ;   destination is local
  270.     ; else
  271.     ;  destination is remote, so pass to gateway
  272.  
  273.  
  274. ;;; TODO: get device number ! (in edx)
  275.     xor     edx, edx
  276.  
  277.     mov     eax, [Index]       ;eax=required IP
  278.     mov     esi, eax
  279.     and     esi, [SUBNET_LIST+edx]
  280.     mov     ecx, [IP_LIST+edx]
  281.     and     ecx, [SUBNET_LIST+edx]
  282.     cmp     esi, ecx
  283.     je      @f        ;if we and target IP are located in the same network
  284.     mov     eax, [GATEWAY_LIST+edx]
  285.     mov     [Index], eax
  286.     DEBUGF 1,"IP is not on subnet, using %u.%u.%u.%u instead\n",[Index]:1,[Index+1]:1,[Index+2]:1,[Index+3]:1
  287.   @@:
  288.  
  289.     cmp     dword[NumARP], 0
  290.     je      .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP.
  291.                                     ;EAX will be containing a zero, it's equal to ARP_NO_ENTRY
  292.  
  293.     mov     ecx, dword[NumARP]
  294.     imul    esi, ecx, ARP_ENTRY.size  ;esi=current ARP-table size
  295.  
  296.   @@:
  297.     sub     esi, ARP_ENTRY.size
  298.     cmp     [ebx + esi + ARP_ENTRY.IP], eax         ; ebx=ARPTable base
  299.     loopnz  @b                       ; Return back if non match
  300.     jnz     .ip_to_mac_send_request  ; and request IP->MAC if none found in the table
  301.  
  302.     ; Return the entry status in eax
  303.     movzx   eax, word[ebx + esi + ARP_ENTRY.Status]
  304.  
  305.     DEBUGF 1,"MAC found:  %x-%x-%x-%x-%x-%x status:%x in slot:%u\n",\
  306.     [ebx + esi + ARP_ENTRY.MAC]:2,[ebx + esi + ARP_ENTRY.MAC+1]:2,[ebx + esi + ARP_ENTRY.MAC+2]:2,[ebx + esi + ARP_ENTRY.MAC+3]:2,[ebx + esi + ARP_ENTRY.MAC+4]:2,[ebx + esi + ARP_ENTRY.MAC+5]:2, ax, esi
  307.  
  308.     ; esi holds index
  309.     cld
  310.     lea     esi, [ebx + esi + ARP_ENTRY.MAC]
  311.     mov     edi, [Extra]   ;edi=ptr to buffer for write MAC
  312.     movsd
  313.     movsw
  314.     jmp     .exit
  315.  
  316.   .ip_to_mac_send_request:
  317. ;;; TODO: get device number ! (in edx)
  318.     xor     edx, edx
  319.     mov     edx, [ETH_DRV_LIST + 4*edx]
  320.     lea     ecx, [edx + ETH_DEVICE.mac]
  321.  
  322.     stdcall arp_request,[Index],[IP_LIST+edx],ecx  ;TargetIP,SenderIP_ptr,SenderMAC_ptr
  323.     mov     eax, ARP_NO_ENTRY
  324.     jmp     .exit
  325.  
  326. ;;END IP_TO_MAC
  327.  
  328. .exit:
  329.     ret
  330. endp
  331.  
  332.  
  333. ;***************************************************************************
  334. ;   Function
  335. ;      arp_request  [by Johnny_B]
  336. ;
  337. ;   Description
  338. ;      Sends an ARP request on the ethernet
  339. ;   IN:
  340. ;     TargetIP      : requested IP address
  341. ;     SenderIP_ptr  : POINTER to sender's IP address(our system's address)
  342. ;     SenderMAC_ptr : POINTER to sender's MAC address(our system's address)
  343. ;   OUT:
  344. ;     EAX=0 (if all is ok), otherwise EAX is not defined
  345. ;
  346. ;      EBX,ESI,EDI will be saved
  347. ;
  348. ;***************************************************************************
  349. proc arp_request stdcall uses ebx esi edi,\
  350.     TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD
  351.  
  352.     DEBUGF 1,"Create ARP request\n"
  353.  
  354.  
  355.     stdcall kernel_alloc, 60  ; minimum eth packet size
  356.     test    eax, eax
  357.     jz      .exit
  358.  
  359.     mov     ebx, eax
  360.  
  361.     mov     word [ebx + ETH_FRAME.Data + ARP_Packet.HardwareType], 0x0100 ;Ethernet
  362.     mov     word [ebx + ETH_FRAME.Data + ARP_Packet.ProtocolType], 0x0008 ;IP
  363.     mov     byte [ebx + ETH_FRAME.Data + ARP_Packet.HardwareSize], 0x06   ;MAC-addr length
  364.     mov     byte [ebx + ETH_FRAME.Data + ARP_Packet.ProtocolSize], 0x04   ;IP-addr length
  365.     mov     word [ebx + ETH_FRAME.Data + ARP_Packet.Opcode], 0x0100       ;Request
  366.  
  367.     DEBUGF 1,"1"
  368.  
  369.     cld
  370.     mov     esi, [SenderMAC_ptr]
  371.     lea     edi, [ebx + ETH_FRAME.Data + ARP_Packet.SenderMAC]       ;Our MAC-addr
  372.     movsd
  373.     movsw
  374.  
  375.     DEBUGF 1,"2"
  376.  
  377.     mov     esi, [SenderIP_ptr]
  378.     mov     [ebx + ETH_FRAME.Data + ARP_Packet.SenderIP], esi        ;Our IP-addr
  379. ;    movsd
  380.  
  381.     DEBUGF 1,"3"
  382.  
  383.     lea     edi, [ebx + ETH_FRAME.Data + ARP_Packet.TargetMAC]       ; Required MAC-addr
  384.     xor     eax, eax
  385.     stosd
  386.     stosw
  387.  
  388.     DEBUGF 1,"4"
  389.  
  390.     lea     edi, [ebx + ETH_FRAME.DstMAC]
  391.     stosd
  392.     stosw
  393.  
  394.     DEBUGF 1,"5"
  395.  
  396.     mov     esi, [TargetIP]
  397.     mov     dword [ebx + ETH_FRAME.Data + ARP_Packet.TargetIP], esi   ;Required IP-addr(we get it as function parameter)
  398.  
  399.  
  400.     DEBUGF 1,"6"
  401.  
  402.     mov     esi, [SenderMAC_ptr]
  403.     lea     edi, [ebx + ETH_FRAME.SrcMAC]
  404.     movsd
  405.     movsw
  406.  
  407.     DEBUGF 1,"7"
  408.  
  409.     mov     ax , ETHER_ARP
  410.     stosw
  411.  
  412.     DEBUGF 1,"8"
  413.  
  414. ;;; TODO: get device number in edx !!
  415.     xor     edx, edx
  416.     shl     edx, 2
  417.  
  418.     inc     [ARP_PACKETS_TX+edx]
  419.  
  420.     push    dword .returnaddr
  421.     push    dword 60
  422.     push    ebx
  423.     mov     ebx, [ETH_DRV_LIST + edx]
  424.     jmp     [ebx + ETH_DEVICE.transmit]
  425. .returnaddr:
  426.  
  427.     ; Add an entry in the ARP table, awaiting response
  428.     sub     esp, ARP_ENTRY.size    ;allocate memory for ARP-entry
  429.  
  430.     mov     esi, dword[TargetIP]
  431.     mov     dword[esp + ARP_ENTRY.IP],esi
  432.  
  433.     lea     edi, [esp + ARP_ENTRY.MAC]
  434.     xor     eax, eax
  435.     stosd
  436.     stosw
  437.  
  438.     mov     word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
  439.     mov     word[esp + ARP_ENTRY.TTL], 10  ; 10 seconds
  440.  
  441.     stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp
  442.     add     esp, ARP_ENTRY.size ; free memory
  443.  
  444. .exit:
  445.  
  446.     DEBUGF 1,"ARP request - end\n"
  447.     ret
  448. endp
  449.  
  450.  
  451.  
  452.  
  453.  
  454. ;---------------------------------------------------------------------------
  455. ;
  456. ; ARP_decrease_entry_ttls
  457. ;
  458. ; IN: /
  459. ; OUT: /
  460. ;
  461. ;---------------------------------------------------------------------------
  462.  
  463. align 4
  464. ARP_decrease_entry_ttls:
  465.  
  466.         mov     ecx, [NumARP]
  467.         test    ecx, ecx
  468.         jz      .exit
  469.  
  470.         mov     ebx, ARPTable
  471.  
  472. .timer_loop:
  473.  
  474.         movsx   esi, word [ebx + ARP_ENTRY.TTL]
  475.         cmp     esi, 0xFFFFFFFF
  476.         je      .timer_loop_end  ;if TTL==0xFFFF then it's static entry
  477.  
  478.         test    esi, esi
  479.         jnz     .timer_loop_end_with_dec  ;if TTL!=0
  480.  
  481.         ; Ok, TTL is 0
  482.         ;if Status==AWAITING_RESPONSE and TTL==0
  483.         ;then we have to change it to ARP_RESPONSE_TIMEOUT
  484.         cmp     word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
  485.         jne     @f
  486.  
  487.         mov     word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT
  488.         mov     word [ebx + ARP_ENTRY.TTL], word 0x000A   ;10 sec
  489.         jmp     .timer_loop_end
  490.  
  491.   @@:
  492.         ;if TTL==0 and Status==VALID_MAPPING, we have to delete it
  493.         ;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too
  494.         mov     esi, dword[NumARP]
  495.         sub     esi, ecx          ;esi=index of entry, will be deleted
  496.  
  497.         call    ARP_del_entry
  498.  
  499.         jmp     .timer_loop_end
  500.  
  501.  
  502. .timer_loop_end_with_dec:
  503.  
  504.         dec     word [ebx + ARP_ENTRY.TTL]  ;decrease TTL
  505.  
  506. .timer_loop_end:
  507.  
  508.         add     ebx, ARP_ENTRY.size
  509.         loop    .timer_loop
  510.  
  511. .exit:
  512.  
  513.         ret
  514.  
  515.  
  516. ;---------------------------------------------------------------------------
  517. ;
  518. ; ARP_del_entry
  519. ;
  520. ; IN: entry # in esi
  521. ; OUT: /
  522. ;
  523. ;---------------------------------------------------------------------------
  524.  
  525. align 4
  526. ARP_del_entry:
  527.  
  528.         imul    esi, ARP_ENTRY.size
  529.  
  530.         mov     ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size
  531.         sub     ecx, esi
  532.  
  533.         lea     edi, [ebx + esi]            ;edi=ptr to entry that should be deleted
  534.         lea     esi, [edi + ARP_ENTRY.size] ;esi=ptr to next entry
  535.  
  536.         shr     ecx,1      ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER!
  537.         cld
  538.         rep     movsw
  539.  
  540.         dec     dword[NumARP] ;decrease arp-entries counter
  541.         ret
  542.  
  543.  
  544.  
  545.  
  546.  
  547. ;-----------------------------------------------------
  548. ;
  549. ; ARP_Handler:
  550. ;
  551. ;  This function handles ARP protocol over ethernet
  552. ;  (other protocols may follow in the future)
  553. ;
  554. ;  IN:  Pointer to buffer in [esp]
  555. ;       size of buffer in [esp+4]
  556. ;       packet size (without ethernet header) in ecx
  557. ;  OUT: /
  558. ;
  559. ;-----------------------------------------------------
  560. align 4
  561. ARP_Handler:
  562.  
  563.         DEBUGF  1,"ARP_Handler - start\n"
  564.         cmp     ecx, 28
  565.         jl      .exit
  566.  
  567. ; Is this a REQUEST?
  568. ; Is this a request for My Host IP
  569. ; Yes - So construct a response message.
  570. ; Send this message to the ethernet card for transmission
  571.  
  572. ;        push    ebx edx
  573.         stdcall arp_table_manager, ARP_TABLE_ADD, EXTRA_IS_ARP_PACKET_PTR, edx
  574. ;        pop     edx ebx
  575.  
  576.         cmp     word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE  ; Is this a request packet?
  577.         jne     .exit
  578.  
  579.         call    ETH_struc2dev
  580.         DEBUGF  1,"ARP Packet came from device: %u\n", edi
  581.         inc     [ARP_PACKETS_RX+4*edi]
  582.         cmp     edi, -1
  583.         jz      .exit
  584.  
  585.         mov     eax, edi
  586.         shl     eax, 2
  587.         add     eax, IP_LIST
  588.         mov     eax, [eax]
  589.         cmp     eax, [edx + ARP_Packet.TargetIP]                ; Is it looking for my IP address?
  590.         jnz     .exit
  591.         push    eax
  592.         push    edi
  593.  
  594. ;        DEBUGF  1,"ETH_ARP_Handler - request for %u.%u.%u.%u\n",[edi+0]:1,[edi+1]:1,[edi+2]:1,[edi+3]:1
  595.  
  596. ; OK, it is a request for one of our MAC addresses. Build the frame and send it
  597. ; We can reuse the buffer.
  598.  
  599.         cld
  600.         lea     esi, [edx + ARP_Packet.SenderMAC]
  601.         lea     edi, [edx + ARP_Packet.TargetMAC]
  602.         movsd                                                   ; Move Sender Mac to Dest MAC
  603.         movsw                                                   ;
  604.         movsd                                                   ; Move sender IP to Dest IP
  605.  
  606.         pop     esi
  607.         mov     esi, [ETH_DRV_LIST + 4*esi]
  608.         lea     esi, [esi + ETH_DEVICE.mac]
  609.         lea     edi, [edx + ARP_Packet.SenderMAC]
  610.         movsd                                                   ; Copy MAC address from in MAC_LIST
  611.         movsw                                                   ;
  612.         pop     eax
  613.         stosd                                                   ; Write our IP
  614.  
  615.         mov     word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE
  616.  
  617. ; Now, Fill in ETHERNET header
  618.  
  619.         mov     edi, [esp]
  620.         lea     esi, [edx + ARP_Packet.TargetMAC]
  621.         movsd
  622.         movsw
  623.         lea     esi, [edx + ARP_Packet.SenderMAC]
  624.         movsd
  625.         movsw
  626.         mov     ax , ETHER_ARP
  627.         stosw
  628.  
  629.         jmp     ETH_Sender                                      ; And send it!
  630.  
  631.        .exit:
  632.         call    kernel_free
  633.         add     esp, 4                                          ; pop (balance stack)
  634.  
  635.         DEBUGF 1,"ARP_Handler - fail\n"
  636.         ret
  637.  
  638.  
  639.  
  640.  
  641. ;---------------------------------------------------------------------------
  642. ;
  643. ; ARP_API
  644. ;
  645. ; This function is called by system function 75
  646. ;
  647. ; IN:  subfunction number in bl
  648. ;      device number in bh
  649. ;      ecx, edx, .. depends on subfunction
  650. ;
  651. ; OUT:
  652. ;
  653. ;---------------------------------------------------------------------------
  654.  
  655. align 4
  656. ARP_API:
  657.  
  658.         movzx   eax, bh
  659.         shl     eax, 2
  660.  
  661.         test    bl, bl
  662.         jz      .packets_tx     ; 0
  663.         dec     bl
  664.         jz      .packets_rx     ; 1
  665.         dec     bl
  666.         jz      .entries        ; 2
  667.         dec     bl
  668.         jz      .read           ; 3
  669.         dec     bl
  670.         jz      .write          ; 4
  671.         dec     bl
  672.         jz      .remove         ; 5
  673.         dec     bl
  674.  
  675.  
  676. .error:
  677.         mov     eax, -1
  678.         ret
  679.  
  680. .packets_tx:
  681.         add     eax, ARP_PACKETS_TX
  682.         mov     eax, [eax]
  683.         ret
  684.  
  685. .packets_rx:
  686.         add     eax, ARP_PACKETS_RX
  687.         mov     eax, [eax]
  688.         ret
  689.  
  690. .entries:
  691.         mov     eax, [NumARP]
  692.         ret
  693.  
  694. .read:
  695.         ; TODO: write code
  696.         ret
  697.  
  698. .write:
  699.         ; TODO: write code
  700.         ret
  701.  
  702. .remove:
  703.         ; TODO: write code
  704.         ret
  705.  
  706.