Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 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: 983 $
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
ETHER_ARP		equ  0x0608
30
 
31
ARP_REQ_OPCODE		equ  0x0100  ; request
32
ARP_REP_OPCODE		equ  0x0200  ; reply
33
 
34
ARP_TABLE_SIZE		equ  20      ; Size of table
35
 
36
struct ARP_ENTRY
37
       .IP		dd  ?
38
       .MAC		dp  ?
39
       .Status		dw  ?
40
       .TTL		dw  ?  ; in seconds
41
       .size:
42
ends
43
 
44
struct ARP_Packet
45
       .HardwareType	dw  ?
46
       .ProtocolType	dw  ?
47
       .HardwareSize	db  ?
48
       .ProtocolSize	db  ?
49
       .Opcode		dw  ?
50
       .SenderMAC	dp  ?
51
       .SenderIP	dd  ?
52
       .TargetMAC	dp  ?
53
       .TargetIP	dd  ?
54
ends
55
 
56
 
57
; The TTL field is decremented every second, and is deleted when it
58
; reaches 0. It is refreshed every time a packet is received
59
; If the TTL field is 0xFFFF it is a static entry and is never deleted
60
; The status field can be the following values:
61
; 0x0000  entry not used
62
; 0x0001  entry holds a valid mapping
63
; 0x0002  entry contains an IP address, awaiting ARP response
64
; 0x0003  No response received to ARP request.
65
; The last status value is provided to allow the network layer to delete
66
; a packet that is queued awaiting an ARP response
67
 
68
align 4
69
uglobal
70
 
71
	NumARP		dd ?
72
	ARPTable	rb ARP_ENTRY.size * ARP_TABLE_SIZE
73
 
74
	ARP_PACKETS_TX	rd  MAX_NET_DEVICES
75
	ARP_PACKETS_RX	rd  MAX_NET_DEVICES
76
 
77
 
78
endg
79
 
80
 
81
 
82
 
83
ARP_init:
84
 
85
	xor	eax, eax
86
 
87
	mov	[NumARP], eax
88
 
89
	mov	edi, ARP_PACKETS_TX
90
	mov	ecx, 2*MAX_NET_DEVICES
91
	rep	stosd
92
 
93
	ret
94
 
95
 
96
 
97
 
98
;***************************************************************************
99
;   Function
100
;      arp_table_manager  [by Johnny_B]
101
;
102
;   Description
103
;     Does a most required operations with ARP-table
104
;  IN:
105
;   Operation: see Opcode's constants below
106
;       Index: Index of entry in the ARP-table
107
;       Extra: Extra parameter for some Opcodes
108
;  OUT:
109
;   EAX = Returned value depends on opcodes, more detailed see below
110
;
111
;***************************************************************************
112
;Opcode's constants
113
ARP_TABLE_ADD		      equ  1
114
ARP_TABLE_IP_TO_MAC	      equ  5
115
 
116
;Index's constants
117
EXTRA_IS_ARP_PACKET_PTR  equ  0   ;if Extra contain pointer to ARP_Packet
118
EXTRA_IS_ARP_ENTRY_PTR	 equ  -1  ;if Extra contain pointer to ARP_ENTRY
119
 
120
align 4
121
proc arp_table_manager stdcall uses ebx esi edi ecx edx, Opcode:DWORD,Index:DWORD,Extra:DWORD
122
 
123
    mov     ebx, ARPTable  ;ARPTable base
124
    mov     ecx, dword[NumARP]	       ;ARP-entries counter
125
 
126
    mov     eax, dword[Opcode]
127
 
128
 
129
    DEBUGF 1,"ARP table manager opcode:%u numARP:%u\n",eax,ecx
130
 
131
    cmp     eax, ARP_TABLE_ADD
132
    je	    .add
1187 hidnplayr 133
 
1159 hidnplayr 134
    cmp     eax, ARP_TABLE_IP_TO_MAC
135
    je	    .ip_to_mac
1187 hidnplayr 136
 
1159 hidnplayr 137
    jmp     .exit     ;if unknown opcode
138
 
139
 
140
;;BEGIN ADD
141
;;Description: it adds an entry in the table. If ARP-table already
142
;;             contains same IP, it will be updated.
143
;;IN:   Operation: ARP_TABLE_ADD
144
;;      Index: specifies what contains Extra-parameter
145
;;      Extra: if Index==EXTRA_IS_ARP_Packet_PTR,
146
;;             then Extra contains pointer to ARP_Packet,
147
;;             otherwise Extra contains pointer to ARP_ENTRY
148
;;OUT:
149
;;  EAX=index of entry, that has been added
150
;;
151
.add:
152
 
153
    DEBUGF 1,"1"
154
 
155
    sub     esp, ARP_ENTRY.size   ;Allocate ARP_ENTRY_SIZE byte in stack
156
 
157
    mov     esi, [Extra]   ;pointer
158
    mov     edi, [Index]   ;opcode
159
 
160
    cmp     edi, EXTRA_IS_ARP_PACKET_PTR
161
    je	    .ARP_Packet_to_entry ;if Extra contain ptr to ARP_Packet and we have to form arp-entry
162
				 ;else it contain ptr to arp-entry
163
 
164
    DEBUGF 1,"2"
165
 
166
    cld
167
	  ; esi already has been loaded
168
    mov     edi, esp	  ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
169
    mov     ecx,ARP_ENTRY.size/2  ;ARP_ENTRY_SIZE must be even number!!!
170
    rep     movsw    ;copy
171
    jmp     .search
172
 
173
  .ARP_Packet_to_entry:
174
 
175
    DEBUGF 1,"3"
176
    mov     edx, dword[esi + ARP_Packet.SenderIP] ;esi=base of ARP_Packet
177
    mov     [esp + ARP_ENTRY.IP], edx
178
 
179
    cld
180
    lea     esi, [esi + ARP_Packet.SenderMAC]
181
    lea     edi, [esp + ARP_ENTRY.MAC]
182
    movsd
183
    movsw
184
    mov     word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING  ; specify the type - a valid entry
185
    mov     word[esp + ARP_ENTRY.TTL], 0x0E10	 ; = 1 hour
186
 
187
  .search:
188
 
189
    DEBUGF 1,"4"
190
    mov     edx, dword[esp + ARP_ENTRY.IP]  ;edx=IP-address, which we'll search
191
    mov     ecx, dword[NumARP]		    ;ecx=ARP-entries counter
192
    jecxz   .add_to_end 		    ;if ARP-entries number == 0
193
    imul    eax, ecx, ARP_ENTRY.size	    ;eax=current table size(in bytes)
194
  @@:
195
    sub     eax, ARP_ENTRY.size
196
    cmp     dword[ebx + eax + ARP_ENTRY.IP], edx
197
    loopnz  @b
198
;    jz      .replace       ; found, replace existing entry, ptr to it is in eax
199
 
1162 hidnplayr 200
  .add_to_end:
1159 hidnplayr 201
;
202
;    DEBUGF 1,"5\n"
203
;    ;else add to end
204
;    or      eax,-1    ;set eax=0xFFFFFFFF if adding is impossible
205
;    mov     ecx, dword[NumARP]
206
;    cmp     ecx, ARP_TABLE_SIZE
207
;    je      .add_exit   ;if arp-entries number is equal to arp-table maxsize
208
 
209
;    imul    eax, dword[NumARP], ARP_ENTRY.size ;eax=ptr to end of ARPTable
210
;    inc     dword [NumARP]    ;increase ARP-entries counter
211
 
212
;  .replace:
213
    DEBUGF 1,"Updating ARP entry: %x-%x-%x-%x-%x-%x = %u.%u.%u.%u to slot:%u\n",\
214
    [esp + ARP_ENTRY.MAC]:2,[esp + ARP_ENTRY.MAC+1]:2,[esp + ARP_ENTRY.MAC+2]:2,[esp + ARP_ENTRY.MAC+3]:2,[esp + ARP_ENTRY.MAC+4]:2,[esp + ARP_ENTRY.MAC+5]:2,\
215
    [esp + ARP_ENTRY.IP]:1,[esp + ARP_ENTRY.IP+1]:1,[esp + ARP_ENTRY.IP+2]:1,[esp + ARP_ENTRY.IP+3]:1,eax
216
 
217
    cld
218
    mov     esi, esp		  ;esp=base of ARP-entry, that will be added
219
    lea     edi, [ebx + eax]	  ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
220
    mov     ecx,ARP_ENTRY.size/2  ;ARP_ENTRY_SIZE must be even number!!!
221
    rep     movsw
222
 
223
    mov     ecx, ARP_ENTRY.size
224
    xor     edx, edx  ;"div" takes operand from EDX:EAX
225
    div     ecx       ;eax=index of entry, which has been added
226
 
227
 
228
 
229
.add_exit:
230
 
231
    add     esp, ARP_ENTRY.size   ;free stack
232
    jmp     .exit
233
;;END ADD
234
 
235
 
236
 
237
;;BEGIN IP_TO_MAC
238
;;Description: it gets an IP from Index, scans each entry in the table and writes
239
;;             MAC, that relates to specified IP, into buffer specified in Extra.
240
;;             And if it cannot find an IP-address in the table, it does an ARP-request of that.
241
;;IN:   Operation: ARP_TABLE_IP_TO_MAC
242
;;      Index: IP that should be transformed into MAC
243
;;      Extra: pointer to buffer where will be written the MAC-address.
244
;;OUT:
245
;;  EAX=ARP table entry status code.
246
;;      If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request.
247
;;      If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system.
248
;;      If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long.
249
;;      If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC.
250
;;
251
;;  If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet
252
;;  resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this
253
;;  function with 1sec delay. sure, only if it not return a valid MAC after a first call.
254
;;
255
.ip_to_mac:
256
 
257
    DEBUGF 1,"Trying to find MAC for %u.%u.%u.%u\n",[Index]:1,[Index+1]:1,[Index+2]:1,[Index+3]:1
258
 
259
    xor     eax, eax
260
    mov     edi, dword[Extra]
261
    cld
262
    stosd
263
    stosw
264
 
265
 
266
    ; first, check destination IP to see if it is on 'this' network.
267
    ; The test is:
268
    ; if ( destIP & subnet_mask == stack_ip & subnet_mask )
269
    ;   destination is local
270
    ; else
271
    ;  destination is remote, so pass to gateway
272
 
273
 
274
;;; TODO: get device number ! (in edx)
275
    xor     edx, edx
276
 
277
    mov     eax, [Index]       ;eax=required IP
278
    mov     esi, eax
279
    and     esi, [SUBNET_LIST+edx]
280
    mov     ecx, [IP_LIST+edx]
281
    and     ecx, [SUBNET_LIST+edx]
282
    cmp     esi, ecx
283
    je	    @f	      ;if we and target IP are located in the same network
284
    mov     eax, [GATEWAY_LIST+edx]
285
    mov     [Index], eax
286
    DEBUGF 1,"IP is not on subnet, using %u.%u.%u.%u instead\n",[Index]:1,[Index+1]:1,[Index+2]:1,[Index+3]:1
287
  @@:
288
 
289
    cmp     dword[NumARP], 0
290
    je	    .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP.
291
				    ;EAX will be containing a zero, it's equal to ARP_NO_ENTRY
292
 
293
    mov     ecx, dword[NumARP]
294
    imul    esi, ecx, ARP_ENTRY.size  ;esi=current ARP-table size
295
 
296
  @@:
297
    sub     esi, ARP_ENTRY.size
298
    cmp     [ebx + esi + ARP_ENTRY.IP], eax	    ; ebx=ARPTable base
299
    loopnz  @b			     ; Return back if non match
300
    jnz     .ip_to_mac_send_request  ; and request IP->MAC if none found in the table
301
 
302
    ; Return the entry status in eax
303
    movzx   eax, word[ebx + esi + ARP_ENTRY.Status]
304
 
305
    DEBUGF 1,"MAC found:  %x-%x-%x-%x-%x-%x status:%x in slot:%u\n",\
306
    [ebx + esi + ARP_ENTRY.MAC]:2,[ebx + esi + ARP_ENTRY.MAC+1]:2,[ebx + esi + ARP_ENTRY.MAC+2]:2,[ebx + esi + ARP_ENTRY.MAC+3]:2,[ebx + esi + ARP_ENTRY.MAC+4]:2,[ebx + esi + ARP_ENTRY.MAC+5]:2, ax, esi
307
 
308
    ; esi holds index
309
    cld
310
    lea     esi, [ebx + esi + ARP_ENTRY.MAC]
311
    mov     edi, [Extra]   ;edi=ptr to buffer for write MAC
312
    movsd
313
    movsw
314
    jmp     .exit
315
 
316
  .ip_to_mac_send_request:
317
;;; TODO: get device number ! (in edx)
318
    xor     edx, edx
319
    mov     edx, [ETH_DRV_LIST + 4*edx]
320
    lea     ecx, [edx + ETH_DEVICE.mac]
321
 
322
    stdcall arp_request,[Index],[IP_LIST+edx],ecx  ;TargetIP,SenderIP_ptr,SenderMAC_ptr
323
    mov     eax, ARP_NO_ENTRY
324
    jmp     .exit
325
 
326
;;END IP_TO_MAC
327
 
328
.exit:
329
    ret
330
endp
331
 
332
 
333
;***************************************************************************
334
;   Function
335
;      arp_request  [by Johnny_B]
336
;
337
;   Description
338
;      Sends an ARP request on the ethernet
339
;   IN:
340
;     TargetIP      : requested IP address
341
;     SenderIP_ptr  : POINTER to sender's IP address(our system's address)
342
;     SenderMAC_ptr : POINTER to sender's MAC address(our system's address)
343
;   OUT:
344
;     EAX=0 (if all is ok), otherwise EAX is not defined
345
;
346
;      EBX,ESI,EDI will be saved
347
;
348
;***************************************************************************
349
proc arp_request stdcall uses ebx esi edi,\
350
    TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD
351
 
352
    DEBUGF 1,"Create ARP request\n"
353
 
354
 
355
    stdcall kernel_alloc, 60  ; minimum eth packet size
356
    test    eax, eax
357
    jz	    .exit
358
 
359
    mov     ebx, eax
360
 
361
    mov     word [ebx + ETH_FRAME.Data + ARP_Packet.HardwareType], 0x0100 ;Ethernet
362
    mov     word [ebx + ETH_FRAME.Data + ARP_Packet.ProtocolType], 0x0008 ;IP
363
    mov     byte [ebx + ETH_FRAME.Data + ARP_Packet.HardwareSize], 0x06   ;MAC-addr length
364
    mov     byte [ebx + ETH_FRAME.Data + ARP_Packet.ProtocolSize], 0x04   ;IP-addr length
365
    mov     word [ebx + ETH_FRAME.Data + ARP_Packet.Opcode], 0x0100	  ;Request
366
 
367
    DEBUGF 1,"1"
368
 
369
    cld
370
    mov     esi, [SenderMAC_ptr]
371
    lea     edi, [ebx + ETH_FRAME.Data + ARP_Packet.SenderMAC]	     ;Our MAC-addr
372
    movsd
373
    movsw
374
 
375
    DEBUGF 1,"2"
376
 
377
    mov     esi, [SenderIP_ptr]
378
    mov     [ebx + ETH_FRAME.Data + ARP_Packet.SenderIP], esi	     ;Our IP-addr
379
;    movsd
380
 
381
    DEBUGF 1,"3"
382
 
383
    lea     edi, [ebx + ETH_FRAME.Data + ARP_Packet.TargetMAC]	     ; Required MAC-addr
384
    xor     eax, eax
385
    stosd
386
    stosw
387
 
388
    DEBUGF 1,"4"
389
 
390
    lea     edi, [ebx + ETH_FRAME.DstMAC]
391
    stosd
392
    stosw
393
 
394
    DEBUGF 1,"5"
395
 
396
    mov     esi, [TargetIP]
397
    mov     dword [ebx + ETH_FRAME.Data + ARP_Packet.TargetIP], esi   ;Required IP-addr(we get it as function parameter)
398
 
399
 
400
    DEBUGF 1,"6"
401
 
402
    mov     esi, [SenderMAC_ptr]
403
    lea     edi, [ebx + ETH_FRAME.SrcMAC]
404
    movsd
405
    movsw
406
 
407
    DEBUGF 1,"7"
408
 
409
    mov     ax , ETHER_ARP
410
    stosw
411
 
412
    DEBUGF 1,"8"
413
 
414
;;; TODO: get device number in edx !!
415
    xor     edx, edx
416
    shl     edx, 2
417
 
1171 hidnplayr 418
    inc     [ARP_PACKETS_TX+edx]
419
 
1159 hidnplayr 420
    push    dword .returnaddr
421
    push    dword 60
422
    push    ebx
423
    mov     ebx, [ETH_DRV_LIST + edx]
424
    jmp     [ebx + ETH_DEVICE.transmit]
425
.returnaddr:
426
 
427
    ; Add an entry in the ARP table, awaiting response
428
    sub     esp, ARP_ENTRY.size    ;allocate memory for ARP-entry
429
 
430
    mov     esi, dword[TargetIP]
431
    mov     dword[esp + ARP_ENTRY.IP],esi
432
 
433
    lea     edi, [esp + ARP_ENTRY.MAC]
434
    xor     eax, eax
435
    stosd
436
    stosw
437
 
438
    mov     word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
439
    mov     word[esp + ARP_ENTRY.TTL], 10  ; 10 seconds
440
 
441
    stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp
442
    add     esp, ARP_ENTRY.size ; free memory
443
 
444
.exit:
445
 
446
    DEBUGF 1,"ARP request - end\n"
447
    ret
448
endp
449
 
450
 
451
 
452
 
453
 
1185 hidnplayr 454
;---------------------------------------------------------------------------
455
;
456
; ARP_decrease_entry_ttls
457
;
458
; IN: /
459
; OUT: /
460
;
461
;---------------------------------------------------------------------------
462
 
463
align 4
464
ARP_decrease_entry_ttls:
465
 
466
	mov	ecx, [NumARP]
467
	test	ecx, ecx
468
	jz	.exit
469
 
470
	mov	ebx, ARPTable
471
 
472
.timer_loop:
473
 
474
	movsx	esi, word [ebx + ARP_ENTRY.TTL]
475
	cmp	esi, 0xFFFFFFFF
476
	je	.timer_loop_end  ;if TTL==0xFFFF then it's static entry
477
 
478
	test	esi, esi
479
	jnz	.timer_loop_end_with_dec  ;if TTL!=0
480
 
481
	; Ok, TTL is 0
482
	;if Status==AWAITING_RESPONSE and TTL==0
483
	;then we have to change it to ARP_RESPONSE_TIMEOUT
484
	cmp	word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
485
	jne	@f
486
 
487
	mov	word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT
488
	mov	word [ebx + ARP_ENTRY.TTL], word 0x000A   ;10 sec
489
	jmp	.timer_loop_end
490
 
491
  @@:
492
	;if TTL==0 and Status==VALID_MAPPING, we have to delete it
493
	;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too
494
	mov	esi, dword[NumARP]
495
	sub	esi, ecx	  ;esi=index of entry, will be deleted
496
 
497
	call	ARP_del_entry
498
 
499
	jmp	.timer_loop_end
500
 
501
 
502
.timer_loop_end_with_dec:
503
 
504
	dec	word [ebx + ARP_ENTRY.TTL]  ;decrease TTL
505
 
506
.timer_loop_end:
507
 
508
	add	ebx, ARP_ENTRY.size
509
	loop	.timer_loop
510
 
511
.exit:
512
 
513
	ret
514
 
515
 
516
;---------------------------------------------------------------------------
517
;
518
; ARP_del_entry
519
;
520
; IN: entry # in esi
521
; OUT: /
522
;
523
;---------------------------------------------------------------------------
524
 
525
align 4
526
ARP_del_entry:
527
 
528
	imul	esi, ARP_ENTRY.size
529
 
530
	mov	ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size
531
	sub	ecx, esi
532
 
533
	lea	edi, [ebx + esi]	    ;edi=ptr to entry that should be deleted
534
	lea	esi, [edi + ARP_ENTRY.size] ;esi=ptr to next entry
535
 
536
	shr	ecx,1	   ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER!
537
	cld
538
	rep	movsw
539
 
540
	dec	dword[NumARP] ;decrease arp-entries counter
541
	ret
542
 
543
 
544
 
545
 
546
 
1159 hidnplayr 547
;-----------------------------------------------------
548
;
549
; ARP_Handler:
550
;
551
;  This function handles ARP protocol over ethernet
552
;  (other protocols may follow in the future)
553
;
554
;  IN:  Pointer to buffer in [esp]
555
;       size of buffer in [esp+4]
556
;       packet size (without ethernet header) in ecx
557
;  OUT: /
558
;
559
;-----------------------------------------------------
560
align 4
561
ARP_Handler:
562
 
563
	DEBUGF	1,"ARP_Handler - start\n"
564
	cmp	ecx, 28
565
	jl	.exit
566
 
567
; Is this a REQUEST?
568
; Is this a request for My Host IP
569
; Yes - So construct a response message.
570
; Send this message to the ethernet card for transmission
571
 
572
;        push    ebx edx
573
	stdcall arp_table_manager, ARP_TABLE_ADD, EXTRA_IS_ARP_PACKET_PTR, edx
574
;        pop     edx ebx
575
 
576
	cmp	word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE	; Is this a request packet?
577
	jne	.exit
578
 
579
	call	ETH_struc2dev
1171 hidnplayr 580
	DEBUGF	1,"ARP Packet came from device: %u\n", edi
581
	inc	[ARP_PACKETS_RX+4*edi]
1159 hidnplayr 582
	cmp	edi, -1
583
	jz	.exit
584
 
585
	mov	eax, edi
586
	shl	eax, 2
587
	add	eax, IP_LIST
588
	mov	eax, [eax]
589
	cmp	eax, [edx + ARP_Packet.TargetIP]		; Is it looking for my IP address?
590
	jnz	.exit
591
	push	eax
592
	push	edi
593
 
594
;        DEBUGF  1,"ETH_ARP_Handler - request for %u.%u.%u.%u\n",[edi+0]:1,[edi+1]:1,[edi+2]:1,[edi+3]:1
595
 
596
; OK, it is a request for one of our MAC addresses. Build the frame and send it
597
; We can reuse the buffer.
598
 
599
	cld
600
	lea	esi, [edx + ARP_Packet.SenderMAC]
601
	lea	edi, [edx + ARP_Packet.TargetMAC]
602
	movsd							; Move Sender Mac to Dest MAC
603
	movsw							;
604
	movsd							; Move sender IP to Dest IP
605
 
606
	pop	esi
607
	mov	esi, [ETH_DRV_LIST + 4*esi]
608
	lea	esi, [esi + ETH_DEVICE.mac]
609
	lea	edi, [edx + ARP_Packet.SenderMAC]
610
	movsd							; Copy MAC address from in MAC_LIST
611
	movsw							;
612
	pop	eax
613
	stosd							; Write our IP
614
 
615
	mov	word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE
616
 
617
; Now, Fill in ETHERNET header
618
 
619
	mov	edi, [esp]
620
	lea	esi, [edx + ARP_Packet.TargetMAC]
621
	movsd
622
	movsw
623
	lea	esi, [edx + ARP_Packet.SenderMAC]
624
	movsd
625
	movsw
626
	mov	ax , ETHER_ARP
627
	stosw
628
 
629
	jmp	ETH_Sender					; And send it!
630
 
631
       .exit:
632
	call	kernel_free
633
	add	esp, 4						; pop (balance stack)
634
 
635
	DEBUGF 1,"ARP_Handler - fail\n"
636
	ret
637
 
638
 
639
 
640
 
641
;---------------------------------------------------------------------------
642
;
643
; ARP_API
644
;
645
; This function is called by system function 75
646
;
647
; IN:  subfunction number in bl
648
;      device number in bh
649
;      ecx, edx, .. depends on subfunction
650
;
651
; OUT:
652
;
653
;---------------------------------------------------------------------------
654
 
655
align 4
656
ARP_API:
657
 
658
	movzx	eax, bh
659
	shl	eax, 2
660
 
661
	test	bl, bl
662
	jz	.packets_tx	; 0
663
	dec	bl
664
	jz	.packets_rx	; 1
665
	dec	bl
666
	jz	.entries	; 2
667
	dec	bl
668
	jz	.read		; 3
669
	dec	bl
670
	jz	.write		; 4
671
	dec	bl
672
	jz	.remove 	; 5
673
	dec	bl
674
 
675
 
676
.error:
677
	mov	eax, -1
678
	ret
679
 
680
.packets_tx:
681
	add	eax, ARP_PACKETS_TX
682
	mov	eax, [eax]
683
	ret
684
 
685
.packets_rx:
686
	add	eax, ARP_PACKETS_RX
687
	mov	eax, [eax]
688
	ret
689
 
690
.entries:
691
	mov	eax, [NumARP]
692
	ret
693
 
694
.read:
695
	; TODO: write code
696
	ret
697
 
698
.write:
699
	; TODO: write code
700
	ret
701
 
702
.remove:
703
	; TODO: write code
704
	ret
705