Subversion Repositories Kolibri OS

Rev

Rev 511 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. $Revision: 511 $
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;                                                              ;;
  4. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  5. ;; Distributed under terms of the GNU General Public License    ;;
  6. ;;                                                              ;;
  7. ;;  ARP.INC                                                     ;;
  8. ;;                                                              ;;
  9. ;;  Address Resolution Protocol                                 ;;
  10. ;;                                                              ;;
  11. ;;  Last revision: 10.11.2006                                   ;;
  12. ;;                                                              ;;
  13. ;;  This file contains the following:                           ;;
  14. ;;   arp_table_manager - Manages an ARPTable                    ;;
  15. ;;   arp_request - Sends an ARP request on the ethernet         ;;
  16. ;;   arp_handler - Called when an ARP packet is received        ;;
  17. ;;                                                              ;;
  18. ;;  Changes history:                                            ;;
  19. ;;   22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net          ;;
  20. ;;   11.11.2006 - [Johnny_B] and [smb]                          ;;
  21. ;;                                                              ;;
  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.     cmp     dword[NumARP], 0
  345.     je      .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP.
  346.                                     ;EAX will be containing a zero, it's equal to ARP_NO_ENTRY
  347.  
  348.     mov     eax, [Index]       ;eax=required IP
  349.     mov     ecx, dword[NumARP]
  350.     imul    esi, ecx, ARP_ENTRY_SIZE  ;esi=current ARP-table size
  351.  
  352.   @@:
  353.     sub     esi, ARP_ENTRY_SIZE
  354.     cmp     [ebx + esi], eax         ; ebx=ARPTable base
  355.     loopnz  @b                       ; Return back if non match
  356.     jnz     .ip_to_mac_send_request  ; and request IP->MAC if none found in the table
  357.  
  358.     ; Return the entry status in eax
  359.     movzx   eax, word[ebx + esi + ARP_ENTRY.Status]
  360.  
  361.     ; esi holds index
  362.     cld
  363.     lea     esi, [ebx + esi + ARP_ENTRY.MAC]
  364.     mov     edi, [Extra]   ;edi=ptr to buffer for write MAC
  365.     movsd
  366.     movsw
  367.     jmp     .exit
  368.  
  369.   .ip_to_mac_send_request:
  370.     stdcall arp_request,[Index],stack_ip,node_addr  ;TargetIP,SenderIP_ptr,SenderMAC_ptr
  371.     mov     eax, ARP_NO_ENTRY
  372.     jmp     .exit
  373.  
  374. ;;END IP_TO_MAC
  375.  
  376. ;;BEGIN GET_ENTRIES_NUMBER
  377. ;;Description: returns an ARP-entries number in the ARPTable
  378. ;;IN:   Operation: ARP_TABLE_GET_ENTRIES_NUMBER
  379. ;;      Index: must be zero
  380. ;;      Extra: must be zero
  381. ;;OUT:
  382. ;;  EAX=ARP-entries number in the ARPTable
  383.   .get_entries_number:
  384.     mov     eax, dword[NumARP]
  385.     jmp     .exit
  386. ;;END GET_ENTRIES_NUMBER
  387.  
  388. .exit:
  389.     ret
  390. endp
  391.  
  392.  
  393. ;***************************************************************************
  394. ;   Function
  395. ;      arp_handler
  396. ;
  397. ;   Description
  398. ;      Called when an ARP packet is received on the ethernet
  399. ;      Header + Data is in Ether_buffer[]
  400. ;       It looks to see if the packet is a request to resolve this Hosts
  401. ;       IP address. If it is, send the ARP reply packet.
  402. ;      This Hosts IP address is in dword [stack_ip]  ( in network format )
  403. ;       This Hosts MAC address is in node_addr[6]
  404. ;      All registers may be destroyed
  405. ;
  406. ;***************************************************************************
  407. arp_handler:
  408.     ; Is this a REQUEST?
  409.     ; Is this a request for My Host IP
  410.     ; Yes - So construct a response message.
  411.     ; Send this message to the ethernet card for transmission
  412.  
  413.     stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_PACKET_PTR,ETH_FRAME.Data + ARP_PACKET
  414.  
  415.     inc     dword[arp_rx_count] ;increase ARP-packets counter
  416.  
  417.     cmp     word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REQ_OPCODE  ; Is this a request packet?
  418.     jne     .exit            ; No - so exit
  419.  
  420.     mov     eax, [stack_ip]
  421.     cmp     eax, dword[ETH_FRAME.Data + ARP_PACKET.TargetIP]         ; Is it looking for my IP address?
  422.     jne     .exit            ; No - so quit now
  423.  
  424.     ; OK, it is a request for my MAC address. Build the frame and send it
  425.     ; We can reuse the packet.
  426.  
  427.     mov     word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REP_OPCODE
  428.  
  429.     cld
  430.     mov     esi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
  431.     mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC
  432.     movsd
  433.     movsw
  434.  
  435.     mov     esi, ETH_FRAME.Data + ARP_PACKET.SenderIP
  436.     mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetIP
  437.     movsd
  438.  
  439.     mov     esi, node_addr
  440.     mov     edi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
  441.     movsd
  442.     movsw
  443.  
  444.     mov     esi, stack_ip
  445.     mov     edi, ETH_FRAME.Data + ARP_PACKET.SenderIP
  446.     movsd
  447.  
  448.     ; Now, send it!
  449.     mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC   ;ptr to destination MAC address
  450.     mov     bx, ETHER_ARP               ;type of protocol
  451.     mov     ecx, 28                     ;data size
  452.     mov     esi, ETH_FRAME.Data + ARP_PACKET             ;ptr to data
  453.     call    dword [drvr_transmit]       ;transmit packet
  454.  
  455.   .exit:
  456.     ret
  457.  
  458.  
  459. ;***************************************************************************
  460. ;   Function
  461. ;      arp_request  [by Johnny_B]
  462. ;
  463. ;   Description
  464. ;      Sends an ARP request on the ethernet
  465. ;   IN:
  466. ;     TargetIP      : requested IP address
  467. ;     SenderIP_ptr  : POINTER to sender's IP address(our system's address)
  468. ;     SenderMAC_ptr : POINTER to sender's MAC address(our system's address)
  469. ;   OUT:
  470. ;     EAX=0 (if all is ok), otherwise EAX is not defined
  471. ;
  472. ;      EBX,ESI,EDI will be saved
  473. ;
  474. ;***************************************************************************
  475. proc arp_request stdcall uses ebx esi edi,\
  476.     TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD
  477.  
  478.     inc     dword[arp_tx_count]  ; increase counter
  479.  
  480.     sub     esp, 28  ; allocate memory for ARP_PACKET
  481.  
  482.     mov     word[esp + ARP_PACKET.HardwareType],0x0100 ;Ethernet
  483.     mov     word[esp + ARP_PACKET.ProtocolType],0x0008 ;IP
  484.     mov     byte[esp + ARP_PACKET.HardwareSize],0x06   ;MAC-addr length
  485.     mov     byte[esp + ARP_PACKET.ProtocolSize],0x04   ;IP-addr length
  486.     mov     word[esp + ARP_PACKET.Opcode],0x0100       ;Request
  487.  
  488.     cld
  489.     mov     esi,[SenderMAC_ptr]
  490.     lea     edi,[esp + ARP_PACKET.SenderMAC]       ;Our MAC-addr
  491.     movsd
  492.     movsw
  493.  
  494.     mov     esi,[SenderIP_ptr]
  495.     lea     edi,[esp + ARP_PACKET.SenderIP]        ;Our IP-addr
  496.     movsd
  497.  
  498.     xor     eax, eax
  499.     lea     edi, [esp + ARP_PACKET.TargetMAC]      ;Required MAC-addr(zeroed)
  500.     stosd
  501.     stosw
  502.  
  503.     mov     esi, dword[TargetIP]
  504.     mov     dword[esp + ARP_PACKET.TargetIP],esi   ;Required IP-addr(we get it as function parameter)
  505.  
  506.     ; Now, send it!
  507.     mov     edi, broadcast_add     ; Pointer to 48 bit destination address
  508.     mov     bx, ETHER_ARP          ; Type of packet
  509.     mov     ecx, 28                ; size of packet
  510.     lea     esi, [esp + ARP_PACKET]; pointer to packet data
  511.     call    dword [drvr_transmit]  ; Call the drivers transmit function
  512.  
  513.     add     esp, 28  ; free memory, allocated before for ARP_PACKET
  514.  
  515.     ; Add an entry in the ARP table, awaiting response
  516.     sub     esp, ARP_ENTRY_SIZE    ;allocate memory for ARP-entry
  517.  
  518.     mov     esi, dword[TargetIP]
  519.     mov     dword[esp + ARP_ENTRY.IP],esi
  520.  
  521.     lea     edi, [esp + ARP_ENTRY.MAC]
  522.     xor     eax, eax
  523.     stosd
  524.     stosw
  525.  
  526.     mov     word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
  527.     mov     word[esp + ARP_ENTRY.TTL], 0x000A  ; 10 seconds
  528.  
  529.     stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp
  530.     add     esp, ARP_ENTRY_SIZE  ; free memory
  531.  
  532. .exit:
  533.     ret
  534. endp
  535.