Subversion Repositories Kolibri OS

Rev

Rev 425 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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