Subversion Repositories Kolibri OS

Rev

Rev 837 | Blame | Compare with Previous | 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: 2971 $
  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. struc ARP_ENTRY     ;=14 bytes
  30. {  .IP       dd  ?  ;+00
  31.    .MAC      dp  ?  ;+04
  32.    .Status   dw  ?  ;+10
  33.    .TTL      dw  ?  ;+12 : ( in seconds )
  34. }
  35.  
  36. virtual at 0
  37.   ARP_ENTRY ARP_ENTRY
  38. end virtual
  39.  
  40. ; The TTL field is decremented every second, and is deleted when it
  41. ; reaches 0. It is refreshed every time a packet is received
  42. ; If the TTL field is 0xFFFF it is a static entry and is never deleted
  43. ; The status field can be the following values:
  44. ; 0x0000  entry not used
  45. ; 0x0001  entry holds a valid mapping
  46. ; 0x0002  entry contains an IP address, awaiting ARP response
  47. ; 0x0003  No response received to ARP request.
  48. ; The last status value is provided to allow the network layer to delete
  49. ; a packet that is queued awaiting an ARP response
  50.  
  51.  
  52. ; The follow is the ARP Table.
  53. ; This table must be manually updated and the kernel recompilied if
  54. ; changes are made to it.
  55. ; Empty entries are filled with zeros
  56.  
  57. ARP_ENTRY_SIZE              equ     14          ; Number of bytes per entry
  58. ARP_TABLE_SIZE              equ     20          ; Size of table
  59. ARP_TABLE_ENTRIES           equ     0           ; Number of static entries in the table
  60.  
  61. ;TO ADD A STATIC ENTRY, DONT FORGET, PUT "ARPTable" from "uglobal" to "iglobal"!!!
  62. ;AND ALSO - IP and MAC have net byte-order, BUT STATUS AND TTL HAVE A MIRROR BYTE-ORDER!!!
  63. uglobal
  64.   ARPTable:
  65. ;example, static entry ->  db  11,22,33,44, 0x11,0x22,0x33,0x44,0x55,0x66, 0x01,0x00, 0xFF,0xFF
  66.   times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE  db 0
  67. endg
  68.  
  69. iglobal
  70.   NumARP:        dd    ARP_TABLE_ENTRIES
  71.   ARPTable_ptr   dd    ARPTable   ;pointer to ARPTable
  72. endg
  73.  
  74. ARP_REQ_OPCODE              equ     0x0100  ;request
  75. ARP_REP_OPCODE              equ     0x0200  ;reply
  76.  
  77. struc ARP_PACKET
  78. {  .HardwareType dw   ?  ;+00
  79.    .ProtocolType dw   ?  ;+02
  80.    .HardwareSize db   ?  ;+04
  81.    .ProtocolSize db   ?  ;+05
  82.    .Opcode       dw   ?  ;+06
  83.    .SenderMAC    dp   ?  ;+08
  84.    .SenderIP     dd   ?  ;+14
  85.    .TargetMAC    dp   ?  ;+18
  86.    .TargetIP     dd   ?  ;+24
  87. }
  88.  
  89. virtual at 0
  90.   ARP_PACKET ARP_PACKET
  91. end virtual
  92.  
  93.  
  94.  
  95. ;***************************************************************************
  96. ;   Function
  97. ;      arp_table_manager  [by Johnny_B]
  98. ;
  99. ;   Description
  100. ;     Does a most required operations with ARP-table
  101. ;  IN:
  102. ;   Operation: see Opcode's constants below
  103. ;       Index: Index of entry in the ARP-table
  104. ;       Extra: Extra parameter for some Opcodes
  105. ;  OUT:
  106. ;   EAX = Returned value depends on opcodes, more detailed see below
  107. ;
  108. ;***************************************************************************
  109. ;Opcode's constants
  110. ARP_TABLE_ADD                 equ  1
  111. ARP_TABLE_DEL                 equ  2
  112. ARP_TABLE_GET                 equ  3
  113. ARP_TABLE_GET_ENTRIES_NUMBER  equ  4
  114. ARP_TABLE_IP_TO_MAC           equ  5
  115. ARP_TABLE_TIMER               equ  6
  116.  
  117. ;Index's constants
  118. EXTRA_IS_ARP_PACKET_PTR  equ  0   ;if Extra contain pointer to ARP_PACKET
  119. EXTRA_IS_ARP_ENTRY_PTR   equ  -1  ;if Extra contain pointer to ARP_ENTRY
  120.  
  121. align 4
  122. proc arp_table_manager stdcall uses ebx esi edi ecx edx,\
  123.     Opcode:DWORD,Index:DWORD,Extra:DWORD
  124.  
  125.     mov     ebx, dword[ARPTable_ptr]   ;ARPTable base
  126.     mov     ecx, dword[NumARP]         ;ARP-entries counter
  127.  
  128.     mov     eax, dword[Opcode]
  129.     cmp     eax, ARP_TABLE_TIMER
  130.     je      .timer
  131.     cmp     eax, ARP_TABLE_ADD
  132.     je      .add
  133.     cmp     eax, ARP_TABLE_DEL
  134.     je      .del
  135.     cmp     eax, ARP_TABLE_GET
  136.     je      .get
  137.     cmp     eax, ARP_TABLE_IP_TO_MAC
  138.     je      .ip_to_mac
  139.     cmp     eax, ARP_TABLE_GET_ENTRIES_NUMBER
  140.     je      .get_entries_number
  141.     jmp     .exit     ;if unknown opcode
  142.  
  143.  
  144. ;;BEGIN TIMER
  145. ;;Description: it must be callback every second. It is responsible for removing expired routes.
  146. ;;IN:   Operation: ARP_TABLE_TIMER
  147. ;;      Index: must be zero
  148. ;;      Extra: must be zero
  149. ;;OUT:
  150. ;;  EAX=not defined
  151. ;;
  152. .timer:
  153.     test    ecx, ecx
  154.     jz      .exit    ;if NumARP=0 nothing to do
  155.     sub     ecx, ARP_TABLE_ENTRIES  ;ecx=dynamic entries number
  156.     jz      .exit    ;if NumARP=number of static entries then exit
  157.  
  158.     add     ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE  ;ebx=dynamic entries base
  159.  
  160.   .timer_loop:
  161.     movsx   esi, word [ebx + ARP_ENTRY.TTL]
  162.     cmp     esi, 0xFFFFFFFF
  163.     je      .timer_loop_end  ;if TTL==0xFFFF then it's static entry
  164.  
  165.     test    esi, esi
  166.     jnz     .timer_loop_end_with_dec  ;if TTL!=0
  167.  
  168.     ; Ok, TTL is 0
  169.     ;if Status==AWAITING_RESPONSE and TTL==0
  170.     ;then we have to change it to ARP_RESPONSE_TIMEOUT
  171.     cmp     word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
  172.     jne     @f
  173.  
  174.     mov     word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT
  175.     mov     word [ebx + ARP_ENTRY.TTL], word 0x000A   ;10 sec
  176.     jmp     .timer_loop_end
  177.  
  178.   @@:
  179.     ;if TTL==0 and Status==VALID_MAPPING, we have to delete it
  180.     ;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too
  181.     mov     esi, dword[NumARP]
  182.     sub     esi, ecx          ;esi=index of entry, will be deleted
  183.     stdcall arp_table_manager,ARP_TABLE_DEL,esi,0 ;opcode,index,extra
  184.     jmp     .timer_loop_end
  185.  
  186.  
  187.   .timer_loop_end_with_dec:
  188.     dec     word [ebx + ARP_ENTRY.TTL]  ;decrease TTL
  189.   .timer_loop_end:
  190.     add     ebx, ARP_ENTRY_SIZE
  191.     loop    .timer_loop
  192.  
  193.     jmp     .exit
  194. ;;END TIMER
  195.  
  196. ;;BEGIN ADD
  197. ;;Description: it adds an entry in the table. If ARP-table already
  198. ;;             contains same IP, it will be updated.
  199. ;;IN:   Operation: ARP_TABLE_ADD
  200. ;;      Index: specifies what contains Extra-parameter
  201. ;;      Extra: if Index==EXTRA_IS_ARP_PACKET_PTR,
  202. ;;             then Extra contains pointer to ARP_PACKET,
  203. ;;             otherwise Extra contains pointer to ARP_ENTRY
  204. ;;OUT:
  205. ;;  EAX=index of entry, that has been added
  206. ;;
  207. .add:
  208.  
  209.     sub     esp, ARP_ENTRY_SIZE   ;Allocate ARP_ENTRY_SIZE byte in stack
  210.  
  211.     mov     esi, [Extra]   ;pointer
  212.     mov     edi, [Index]   ;opcode
  213.  
  214.     cmp     edi, EXTRA_IS_ARP_PACKET_PTR
  215.     je      .arp_packet_to_entry ;if Extra contain ptr to ARP_PACKET and we have to form arp-entry
  216.                                  ;else it contain ptr to arp-entry
  217.  
  218.     cld
  219.           ; esi already has been loaded
  220.     mov     edi, esp      ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
  221.     mov     ecx,ARP_ENTRY_SIZE/2  ;ARP_ENTRY_SIZE must be even number!!!
  222.     rep     movsw    ;copy
  223.     jmp     .search
  224.  
  225.   .arp_packet_to_entry:
  226.     mov     edx, dword[esi + ARP_PACKET.SenderIP] ;esi=base of ARP_PACKET
  227.     mov     [esp + ARP_ENTRY.IP], edx
  228.  
  229.     cld
  230.     lea     esi, [esi + ARP_PACKET.SenderMAC]
  231.     lea     edi, [esp + ARP_ENTRY.MAC]
  232.     movsd
  233.     movsw
  234.     mov     word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING  ; specify the type - a valid entry
  235.     mov     word[esp + ARP_ENTRY.TTL], 0x0E10    ; = 1 hour
  236.  
  237.   .search:
  238.     mov     edx, dword[esp + ARP_ENTRY.IP]  ;edx=IP-address, which we'll search
  239.     mov     ecx, dword[NumARP]              ;ecx=ARP-entries counter
  240.     jecxz   .add_to_end                     ;if ARP-entries number == 0
  241.     imul    eax, ecx, ARP_ENTRY_SIZE        ;eax=current table size(in bytes)
  242.   @@:
  243.     sub     eax, ARP_ENTRY_SIZE
  244.     cmp     dword[ebx + eax + ARP_ENTRY.IP], edx
  245.     loopnz  @b
  246.     jz      .replace       ; found, replace existing entry, ptr to it is in eax
  247.  
  248.   .add_to_end:
  249.     ;else add to end
  250.     or      eax,-1    ;set eax=0xFFFFFFFF if adding is impossible
  251.     mov     ecx, dword[NumARP]
  252.     cmp     ecx, ARP_TABLE_SIZE
  253.     je      .add_exit   ;if arp-entries number is equal to arp-table maxsize
  254.  
  255.     imul    eax, dword[NumARP], ARP_ENTRY_SIZE ;eax=ptr to end of ARPTable
  256.     inc     dword [NumARP]    ;increase ARP-entries counter
  257.  
  258.   .replace:
  259.     cld
  260.     mov     esi, esp              ;esp=base of ARP-entry, that will be added
  261.     lea     edi, [ebx + eax]      ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
  262.     mov     ecx,ARP_ENTRY_SIZE/2  ;ARP_ENTRY_SIZE must be even number!!!
  263.     rep     movsw
  264.  
  265.     mov     ecx, ARP_ENTRY_SIZE
  266.     xor     edx, edx  ;"div" takes operand from EDX:EAX
  267.     div     ecx       ;eax=index of entry, which has been added
  268.  
  269. .add_exit:
  270.     add     esp, ARP_ENTRY_SIZE   ;free stack
  271.     jmp     .exit
  272. ;;END ADD
  273.  
  274. ;;BEGIN DEL
  275. ;;Description: it deletes an entry in the table.
  276. ;;IN:   Operation: ARP_TABLE_DEL
  277. ;;      Index: index of entry, that should be deleted
  278. ;;      Extra: must be zero
  279. ;;OUT:
  280. ;;  EAX=not defined
  281. ;;
  282. .del:
  283.     mov     esi, [Index]
  284.     imul    esi, ARP_ENTRY_SIZE
  285.  
  286.     mov     ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE
  287.     sub     ecx, esi
  288.  
  289.     lea     edi, [ebx + esi]            ;edi=ptr to entry that should be deleted
  290.     lea     esi, [edi + ARP_ENTRY_SIZE] ;esi=ptr to next entry
  291.  
  292.     shr     ecx,1      ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER!
  293.     cld
  294.     rep     movsw
  295.  
  296.     dec     dword[NumARP] ;decrease arp-entries counter
  297.     jmp     .exit
  298. ;;END DEL
  299.  
  300. ;;BEGIN GET
  301. ;;Description: it reads an entry of table into buffer.
  302. ;;IN:   Operation: ARP_TABLE_GET
  303. ;;      Index: index of entry, that should be read
  304. ;;      Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE)
  305. ;;OUT:
  306. ;;  EAX=not defined
  307. ;;
  308. .get:
  309.     mov     esi, [Index]
  310.     imul    esi, ARP_ENTRY_SIZE   ;esi=ptr to required ARP_ENTRY
  311.     mov     edi, [Extra]          ;edi=buffer for reading
  312.     mov     ecx, ARP_ENTRY_SIZE/2 ; must be even number!!!
  313.     cld
  314.     rep     movsw
  315.     jmp     .exit
  316. ;;END GET
  317.  
  318. ;;BEGIN IP_TO_MAC
  319. ;;Description: it gets an IP from Index, scans each entry in the table and writes
  320. ;;             MAC, that relates to specified IP, into buffer specified in Extra.
  321. ;;             And if it cannot find an IP-address in the table, it does an ARP-request of that.
  322. ;;IN:   Operation: ARP_TABLE_IP_TO_MAC
  323. ;;      Index: IP that should be transformed into MAC
  324. ;;      Extra: pointer to buffer where will be written the MAC-address.
  325. ;;OUT:
  326. ;;  EAX=ARP table entry status code.
  327. ;;      If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request.
  328. ;;      If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system.
  329. ;;      If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long.
  330. ;;      If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC.
  331. ;;
  332. ;;  If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet
  333. ;;  resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this
  334. ;;  function with 1sec delay. sure, only if it not return a valid MAC after a first call.
  335. ;;  
  336. .ip_to_mac:
  337.  
  338.     xor     eax, eax
  339.     mov     edi, dword[Extra]
  340.     cld
  341.     stosd
  342.     stosw
  343.  
  344.  
  345.     ; first, check destination IP to see if it is on 'this' network.
  346.     ; The test is:
  347.     ; if ( destIP & subnet_mask == stack_ip & subnet_mask )
  348.     ;   destination is local
  349.     ; else
  350.     ;  destination is remote, so pass to gateway
  351.  
  352.     mov     eax, [Index]       ;eax=required IP
  353.     mov     esi, eax
  354.     and     esi, [subnet_mask]
  355.     mov     ecx, [stack_ip]
  356.     and     ecx, [subnet_mask]
  357.     cmp     esi, ecx
  358.     je      @f        ;if we and target IP are located in the same network
  359.     mov     eax, [gateway_ip]
  360.     mov     [Index], eax
  361.   @@:
  362.  
  363.     cmp     dword[NumARP], 0
  364.     je      .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP.
  365.                                     ;EAX will be containing a zero, it's equal to ARP_NO_ENTRY
  366.  
  367.     mov     ecx, dword[NumARP]
  368.     imul    esi, ecx, ARP_ENTRY_SIZE  ;esi=current ARP-table size
  369.  
  370.   @@:
  371.     sub     esi, ARP_ENTRY_SIZE
  372.     cmp     [ebx + esi], eax         ; ebx=ARPTable base
  373.     loopnz  @b                       ; Return back if non match
  374.     jnz     .ip_to_mac_send_request  ; and request IP->MAC if none found in the table
  375.  
  376.     ; Return the entry status in eax
  377.     movzx   eax, word[ebx + esi + ARP_ENTRY.Status]
  378.  
  379.     ; esi holds index
  380.     cld
  381.     lea     esi, [ebx + esi + ARP_ENTRY.MAC]
  382.     mov     edi, [Extra]   ;edi=ptr to buffer for write MAC
  383.     movsd
  384.     movsw
  385.     jmp     .exit
  386.  
  387.   .ip_to_mac_send_request:
  388.     stdcall arp_request,[Index],stack_ip,node_addr  ;TargetIP,SenderIP_ptr,SenderMAC_ptr
  389.     mov     eax, ARP_NO_ENTRY
  390.     jmp     .exit
  391.  
  392. ;;END IP_TO_MAC
  393.  
  394. ;;BEGIN GET_ENTRIES_NUMBER
  395. ;;Description: returns an ARP-entries number in the ARPTable
  396. ;;IN:   Operation: ARP_TABLE_GET_ENTRIES_NUMBER
  397. ;;      Index: must be zero
  398. ;;      Extra: must be zero
  399. ;;OUT:
  400. ;;  EAX=ARP-entries number in the ARPTable
  401.   .get_entries_number:
  402.     mov     eax, dword[NumARP]
  403.     jmp     .exit
  404. ;;END GET_ENTRIES_NUMBER
  405.  
  406. .exit:
  407.     ret
  408. endp
  409.  
  410.  
  411. ;***************************************************************************
  412. ;   Function
  413. ;      arp_handler
  414. ;
  415. ;   Description
  416. ;      Called when an ARP packet is received on the ethernet
  417. ;      Header + Data is in Ether_buffer[]
  418. ;       It looks to see if the packet is a request to resolve this Hosts
  419. ;       IP address. If it is, send the ARP reply packet.
  420. ;      This Hosts IP address is in dword [stack_ip]  ( in network format )
  421. ;       This Hosts MAC address is in node_addr[6]
  422. ;      All registers may be destroyed
  423. ;
  424. ;***************************************************************************
  425. arp_handler:
  426.     ; Is this a REQUEST?
  427.     ; Is this a request for My Host IP
  428.     ; Yes - So construct a response message.
  429.     ; Send this message to the ethernet card for transmission
  430.  
  431.     stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_PACKET_PTR,ETH_FRAME.Data + ARP_PACKET
  432.  
  433.     inc     dword[arp_rx_count] ;increase ARP-packets counter
  434.  
  435.     cmp     word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REQ_OPCODE  ; Is this a request packet?
  436.     jne     .exit            ; No - so exit
  437.  
  438.     mov     eax, [stack_ip]
  439.     cmp     eax, dword[ETH_FRAME.Data + ARP_PACKET.TargetIP]         ; Is it looking for my IP address?
  440.     jne     .exit            ; No - so quit now
  441.  
  442.     ; OK, it is a request for my MAC address. Build the frame and send it
  443.     ; We can reuse the packet.
  444.  
  445.     mov     word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REP_OPCODE
  446.  
  447.     cld
  448.     mov     esi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
  449.     mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC
  450.     movsd
  451.     movsw
  452.  
  453.     mov     esi, ETH_FRAME.Data + ARP_PACKET.SenderIP
  454.     mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetIP
  455.     movsd
  456.  
  457.     mov     esi, node_addr
  458.     mov     edi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
  459.     movsd
  460.     movsw
  461.  
  462.     mov     esi, stack_ip
  463.     mov     edi, ETH_FRAME.Data + ARP_PACKET.SenderIP
  464.     movsd
  465.  
  466.     ; Now, send it!
  467.     mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC   ;ptr to destination MAC address
  468.     mov     bx, ETHER_ARP               ;type of protocol
  469.     mov     ecx, 28                     ;data size
  470.     mov     esi, ETH_FRAME.Data + ARP_PACKET             ;ptr to data
  471.     push    ebp
  472.     call    dword [drvr_transmit]       ;transmit packet
  473.     pop     ebp
  474.  
  475.   .exit:
  476.     ret
  477.  
  478.  
  479. ;***************************************************************************
  480. ;   Function
  481. ;      arp_request  [by Johnny_B]
  482. ;
  483. ;   Description
  484. ;      Sends an ARP request on the ethernet
  485. ;   IN:
  486. ;     TargetIP      : requested IP address
  487. ;     SenderIP_ptr  : POINTER to sender's IP address(our system's address)
  488. ;     SenderMAC_ptr : POINTER to sender's MAC address(our system's address)
  489. ;   OUT:
  490. ;     EAX=0 (if all is ok), otherwise EAX is not defined
  491. ;
  492. ;      EBX,ESI,EDI will be saved
  493. ;
  494. ;***************************************************************************
  495. proc arp_request stdcall uses ebx esi edi,\
  496.     TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD
  497.  
  498.     inc     dword[arp_tx_count]  ; increase counter
  499.  
  500.     sub     esp, 28  ; allocate memory for ARP_PACKET
  501.  
  502.     mov     word[esp + ARP_PACKET.HardwareType],0x0100 ;Ethernet
  503.     mov     word[esp + ARP_PACKET.ProtocolType],0x0008 ;IP
  504.     mov     byte[esp + ARP_PACKET.HardwareSize],0x06   ;MAC-addr length
  505.     mov     byte[esp + ARP_PACKET.ProtocolSize],0x04   ;IP-addr length
  506.     mov     word[esp + ARP_PACKET.Opcode],0x0100       ;Request
  507.  
  508.     cld
  509.     mov     esi,[SenderMAC_ptr]
  510.     lea     edi,[esp + ARP_PACKET.SenderMAC]       ;Our MAC-addr
  511.     movsd
  512.     movsw
  513.  
  514.     mov     esi,[SenderIP_ptr]
  515.     lea     edi,[esp + ARP_PACKET.SenderIP]        ;Our IP-addr
  516.     movsd
  517.  
  518.     xor     eax, eax
  519.     lea     edi, [esp + ARP_PACKET.TargetMAC]      ;Required MAC-addr(zeroed)
  520.     stosd
  521.     stosw
  522.  
  523.     mov     esi, dword[TargetIP]
  524.     mov     dword[esp + ARP_PACKET.TargetIP],esi   ;Required IP-addr(we get it as function parameter)
  525.  
  526.     ; Now, send it!
  527.     mov     edi, broadcast_add     ; Pointer to 48 bit destination address
  528.     mov     bx, ETHER_ARP          ; Type of packet
  529.     mov     ecx, 28                ; size of packet
  530.     lea     esi, [esp + ARP_PACKET]; pointer to packet data
  531.     push    ebp
  532.     call    dword [drvr_transmit]  ; Call the drivers transmit function
  533.     pop     ebp
  534.  
  535.     add     esp, 28  ; free memory, allocated before for ARP_PACKET
  536.  
  537.     ; Add an entry in the ARP table, awaiting response
  538.     sub     esp, ARP_ENTRY_SIZE    ;allocate memory for ARP-entry
  539.  
  540.     mov     esi, dword[TargetIP]
  541.     mov     dword[esp + ARP_ENTRY.IP],esi
  542.  
  543.     lea     edi, [esp + ARP_ENTRY.MAC]
  544.     xor     eax, eax
  545.     stosd
  546.     stosw
  547.  
  548.     mov     word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
  549.     mov     word[esp + ARP_ENTRY.TTL], 0x000A  ; 10 seconds
  550.  
  551.     stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp
  552.     add     esp, ARP_ENTRY_SIZE  ; free memory
  553.  
  554. .exit:
  555.     ret
  556. endp
  557.