Subversion Repositories Kolibri OS

Rev

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

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