Subversion Repositories Kolibri OS

Rev

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