Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2465 Serge 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
431 serge 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
261 hidnplayr 20
 
593 mikedld 21
$Revision: 2465 $
22
 
23
 
261 hidnplayr 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
2434 Serge 70
  NumARP:
71
                 dd    ARP_TABLE_ENTRIES
261 hidnplayr 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
 
2434 Serge 126
        mov     ebx, dword[ARPTable_ptr];ARPTable base
127
        mov     ecx, dword[NumARP]     ;ARP-entries counter
261 hidnplayr 128
 
2434 Serge 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
261 hidnplayr 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:
2434 Serge 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
261 hidnplayr 158
 
2434 Serge 159
        add     ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE;ebx=dynamic entries base
261 hidnplayr 160
 
161
  .timer_loop:
2434 Serge 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
431 serge 165
 
2434 Serge 166
        test    esi, esi
167
        jnz     .timer_loop_end_with_dec;if TTL!=0
261 hidnplayr 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
2434 Serge 172
        cmp     word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
173
        jne     @f
261 hidnplayr 174
 
2434 Serge 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
261 hidnplayr 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
2434 Serge 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
261 hidnplayr 186
 
187
 
188
  .timer_loop_end_with_dec:
2434 Serge 189
        dec     word [ebx + ARP_ENTRY.TTL];decrease TTL
261 hidnplayr 190
  .timer_loop_end:
2434 Serge 191
        add     ebx, ARP_ENTRY_SIZE
192
        loop    .timer_loop
261 hidnplayr 193
 
2434 Serge 194
        jmp     .exit
261 hidnplayr 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
 
2434 Serge 210
        sub     esp, ARP_ENTRY_SIZE;Allocate ARP_ENTRY_SIZE byte in stack
261 hidnplayr 211
 
2434 Serge 212
        mov     esi, [Extra];pointer
213
        mov     edi, [Index];opcode
261 hidnplayr 214
 
2434 Serge 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
261 hidnplayr 217
                                 ;else it contain ptr to arp-entry
218
 
2434 Serge 219
        cld
261 hidnplayr 220
          ; esi already has been loaded
2434 Serge 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
261 hidnplayr 225
 
226
  .arp_packet_to_entry:
2434 Serge 227
        mov     edx, dword[esi + ARP_PACKET.SenderIP];esi=base of ARP_PACKET
228
        mov     [esp + ARP_ENTRY.IP], edx
261 hidnplayr 229
 
2434 Serge 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
261 hidnplayr 237
 
238
  .search:
2434 Serge 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)
261 hidnplayr 243
  @@:
2434 Serge 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
261 hidnplayr 248
 
249
  .add_to_end:
250
    ;else add to end
2434 Serge 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
261 hidnplayr 255
 
2434 Serge 256
        imul    eax, dword[NumARP], ARP_ENTRY_SIZE;eax=ptr to end of ARPTable
257
        inc     dword [NumARP];increase ARP-entries counter
261 hidnplayr 258
 
259
  .replace:
2434 Serge 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
261 hidnplayr 265
 
2434 Serge 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
261 hidnplayr 269
 
270
.add_exit:
2434 Serge 271
        add     esp, ARP_ENTRY_SIZE;free stack
272
        jmp     .exit
261 hidnplayr 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:
2434 Serge 284
        mov     esi, [Index]
285
        imul    esi, ARP_ENTRY_SIZE
261 hidnplayr 286
 
2434 Serge 287
        mov     ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE
288
        sub     ecx, esi
261 hidnplayr 289
 
2434 Serge 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
261 hidnplayr 292
 
2434 Serge 293
        shr     ecx, 1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER!
294
        cld
295
        rep movsw
261 hidnplayr 296
 
2434 Serge 297
        dec     dword[NumARP];decrease arp-entries counter
298
        jmp     .exit
261 hidnplayr 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:
2434 Serge 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
261 hidnplayr 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
 
2434 Serge 339
        xor     eax, eax
340
        mov     edi, dword[Extra]
341
        cld
342
        stosd
343
        stosw
261 hidnplayr 344
 
739 heavyiron 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
 
2434 Serge 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
739 heavyiron 362
  @@:
363
 
2434 Serge 364
        cmp     dword[NumARP], 0
365
        je      .ip_to_mac_send_request;if ARP-table not contain an entries, we have to request IP.
261 hidnplayr 366
                                    ;EAX will be containing a zero, it's equal to ARP_NO_ENTRY
367
 
2434 Serge 368
        mov     ecx, dword[NumARP]
369
        imul    esi, ecx, ARP_ENTRY_SIZE;esi=current ARP-table size
261 hidnplayr 370
 
371
  @@:
2434 Serge 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
261 hidnplayr 376
 
377
    ; Return the entry status in eax
2434 Serge 378
        movzx   eax, word[ebx + esi + ARP_ENTRY.Status]
261 hidnplayr 379
 
380
    ; esi holds index
2434 Serge 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
261 hidnplayr 387
 
388
  .ip_to_mac_send_request:
2434 Serge 389
        stdcall arp_request, [Index], stack_ip, node_addr;TargetIP,SenderIP_ptr,SenderMAC_ptr
390
        mov     eax, ARP_NO_ENTRY
391
        jmp     .exit
261 hidnplayr 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:
2434 Serge 403
        mov     eax, dword[NumARP]
404
        jmp     .exit
261 hidnplayr 405
;;END GET_ENTRIES_NUMBER
406
 
407
.exit:
2434 Serge 408
        ret
261 hidnplayr 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
 
2434 Serge 432
        stdcall arp_table_manager, ARP_TABLE_ADD, EXTRA_IS_ARP_PACKET_PTR, ETH_FRAME.Data + ARP_PACKET
261 hidnplayr 433
 
2434 Serge 434
        inc     dword[arp_rx_count];increase ARP-packets counter
261 hidnplayr 435
 
2434 Serge 436
        cmp     word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REQ_OPCODE; Is this a request packet?
437
        jne     .exit        ; No - so exit
261 hidnplayr 438
 
2434 Serge 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
261 hidnplayr 442
 
443
    ; OK, it is a request for my MAC address. Build the frame and send it
444
    ; We can reuse the packet.
445
 
2434 Serge 446
        mov     word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REP_OPCODE
261 hidnplayr 447
 
2434 Serge 448
        cld
449
        mov     esi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
450
        mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC
451
        movsd
452
        movsw
261 hidnplayr 453
 
2434 Serge 454
        mov     esi, ETH_FRAME.Data + ARP_PACKET.SenderIP
455
        mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetIP
456
        movsd
261 hidnplayr 457
 
2434 Serge 458
        mov     esi, node_addr
459
        mov     edi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
460
        movsd
461
        movsw
261 hidnplayr 462
 
2434 Serge 463
        mov     esi, stack_ip
464
        mov     edi, ETH_FRAME.Data + ARP_PACKET.SenderIP
465
        movsd
261 hidnplayr 466
 
467
    ; Now, send it!
2434 Serge 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
261 hidnplayr 475
 
476
  .exit:
2434 Serge 477
        ret
261 hidnplayr 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
 
2434 Serge 499
        inc     dword[arp_tx_count]; increase counter
261 hidnplayr 500
 
2434 Serge 501
        sub     esp, 28; allocate memory for ARP_PACKET
261 hidnplayr 502
 
2434 Serge 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
261 hidnplayr 508
 
2434 Serge 509
        cld
510
        mov     esi, [SenderMAC_ptr]
511
        lea     edi, [esp + ARP_PACKET.SenderMAC]  ;Our MAC-addr
512
        movsd
513
        movsw
261 hidnplayr 514
 
2434 Serge 515
        mov     esi, [SenderIP_ptr]
516
        lea     edi, [esp + ARP_PACKET.SenderIP]   ;Our IP-addr
517
        movsd
261 hidnplayr 518
 
2434 Serge 519
        xor     eax, eax
520
        lea     edi, [esp + ARP_PACKET.TargetMAC]  ;Required MAC-addr(zeroed)
521
        stosd
522
        stosw
261 hidnplayr 523
 
2434 Serge 524
        mov     esi, dword[TargetIP]
525
        mov     dword[esp + ARP_PACKET.TargetIP], esi;Required IP-addr(we get it as function parameter)
261 hidnplayr 526
 
527
    ; Now, send it!
2434 Serge 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
261 hidnplayr 535
 
2434 Serge 536
        add     esp, 28; free memory, allocated before for ARP_PACKET
261 hidnplayr 537
 
538
    ; Add an entry in the ARP table, awaiting response
2434 Serge 539
        sub     esp, ARP_ENTRY_SIZE;allocate memory for ARP-entry
261 hidnplayr 540
 
2434 Serge 541
        mov     esi, dword[TargetIP]
542
        mov     dword[esp + ARP_ENTRY.IP], esi
261 hidnplayr 543
 
2434 Serge 544
        lea     edi, [esp + ARP_ENTRY.MAC]
545
        xor     eax, eax
546
        stosd
547
        stosw
261 hidnplayr 548
 
2434 Serge 549
        mov     word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
550
        mov     word[esp + ARP_ENTRY.TTL], 0x000A; 10 seconds
261 hidnplayr 551
 
2434 Serge 552
        stdcall arp_table_manager, ARP_TABLE_ADD, EXTRA_IS_ARP_ENTRY_PTR, esp
553
        add     esp, ARP_ENTRY_SIZE; free memory
261 hidnplayr 554
 
555
.exit:
2434 Serge 556
        ret
261 hidnplayr 557
endp