Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1196 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  ARP.INC                                                        ;;
7
;;                                                                 ;;
8
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
9
;;                                                                 ;;
10
;;  Based on the work of [Johnny_B] and [smb]                      ;;
11
;;                                                                 ;;
12
;;    Written by hidnplayr@kolibrios.org                           ;;
13
;;                                                                 ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1159 hidnplayr 18
 
1196 hidnplayr 19
 
1206 hidnplayr 20
$Revision: 1251 $
1159 hidnplayr 21
 
22
 
23
ARP_NO_ENTRY		equ  0
24
ARP_VALID_MAPPING	equ  1
25
ARP_AWAITING_RESPONSE	equ  2
26
ARP_RESPONSE_TIMEOUT	equ  3
27
 
1196 hidnplayr 28
ARP_REQUEST_TTL 	= 20 ; in seconds
1206 hidnplayr 29
ARP_ENTRY_TTL		= 600 ; in seconds
1196 hidnplayr 30
 
1159 hidnplayr 31
ETHER_ARP		equ  0x0608
32
 
33
ARP_REQ_OPCODE		equ  0x0100  ; request
34
ARP_REP_OPCODE		equ  0x0200  ; reply
35
 
36
ARP_TABLE_SIZE		equ  20      ; Size of table
37
 
38
struct ARP_ENTRY
39
       .IP		dd  ?
40
       .MAC		dp  ?
41
       .Status		dw  ?
42
       .TTL		dw  ?  ; in seconds
43
       .size:
44
ends
45
 
46
struct ARP_Packet
47
       .HardwareType	dw  ?
48
       .ProtocolType	dw  ?
49
       .HardwareSize	db  ?
50
       .ProtocolSize	db  ?
51
       .Opcode		dw  ?
52
       .SenderMAC	dp  ?
53
       .SenderIP	dd  ?
54
       .TargetMAC	dp  ?
55
       .TargetIP	dd  ?
56
ends
57
 
58
 
59
; The TTL field is decremented every second, and is deleted when it
60
; reaches 0. It is refreshed every time a packet is received
61
; If the TTL field is 0xFFFF it is a static entry and is never deleted
62
; The status field can be the following values:
63
; 0x0000  entry not used
64
; 0x0001  entry holds a valid mapping
65
; 0x0002  entry contains an IP address, awaiting ARP response
66
; 0x0003  No response received to ARP request.
67
; The last status value is provided to allow the network layer to delete
68
; a packet that is queued awaiting an ARP response
69
 
70
align 4
71
uglobal
72
 
73
	NumARP		dd ?
74
	ARPTable	rb ARP_ENTRY.size * ARP_TABLE_SIZE
75
 
76
	ARP_PACKETS_TX	rd  MAX_NET_DEVICES
77
	ARP_PACKETS_RX	rd  MAX_NET_DEVICES
78
 
79
 
80
endg
81
 
82
 
83
 
1196 hidnplayr 84
;-----------------------------------------------------------------
85
;
86
; ARP_init
87
;
88
;  This function resets all ARP variables
89
;
90
;  IN:  /
91
;  OUT: /
92
;
93
;-----------------------------------------------------------------
1159 hidnplayr 94
 
1196 hidnplayr 95
align 4
1159 hidnplayr 96
ARP_init:
97
 
98
	xor	eax, eax
99
 
100
	mov	[NumARP], eax
101
 
102
	mov	edi, ARP_PACKETS_TX
103
	mov	ecx, 2*MAX_NET_DEVICES
104
	rep	stosd
105
 
106
	ret
107
 
108
 
1196 hidnplayr 109
;-----------------------------------------------------------------
1159 hidnplayr 110
;
1196 hidnplayr 111
; ARP_IP_to_MAC
1159 hidnplayr 112
;
1196 hidnplayr 113
;  This function resets all ARP variables
114
;
115
;  IN: eax = IPv4 address
116
;  OUT: eax = -1 on error, else eax = first two bytes of mac
117
;                   ( high 16 bits are zero)
118
;       ebx = last four bytes of mac                                  ; TODO: special eax value for 'request send'
119
;
120
;-----------------------------------------------------------------
1159 hidnplayr 121
 
122
align 4
1196 hidnplayr 123
ARP_IP_to_MAC:
1159 hidnplayr 124
 
1196 hidnplayr 125
	DEBUGF 1,"ARP_IP_to_MAC\n"
1159 hidnplayr 126
 
127
    ; first, check destination IP to see if it is on 'this' network.
128
    ; The test is:
129
    ; if ( destIP & subnet_mask == stack_ip & subnet_mask )
130
    ;   destination is local
131
    ; else
132
    ;  destination is remote, so pass to gateway
133
 
1196 hidnplayr 134
	xor	edx, edx ; TODO: find device num in edx
1159 hidnplayr 135
 
1196 hidnplayr 136
	mov	ebx, [IP_LIST+edx]
137
	and	ebx, [SUBNET_LIST+edx]
1206 hidnplayr 138
 
1196 hidnplayr 139
	mov	ecx, eax
140
	and	ecx, [SUBNET_LIST+edx]
1206 hidnplayr 141
 
1196 hidnplayr 142
	cmp	ecx, ebx
143
	je	.local
1159 hidnplayr 144
 
1196 hidnplayr 145
	mov	eax, [GATEWAY_LIST+edx]
146
	DEBUGF 1,"requested IP is not on subnet, using gateway\n"
1159 hidnplayr 147
 
1196 hidnplayr 148
  .local:
149
   ; try to find it on the list
150
	mov	ecx, [NumARP]
1206 hidnplayr 151
	test	ecx, ecx
1196 hidnplayr 152
	jz	.not_in_list
153
	mov	esi, ARPTable + ARP_ENTRY.IP
154
  .scan_loop:
1206 hidnplayr 155
	cmp	[esi], eax
156
	je	.found_it
157
	add	esi, ARP_ENTRY.size
1196 hidnplayr 158
	loop	.scan_loop
159
  .not_in_list:
1159 hidnplayr 160
 
1196 hidnplayr 161
	DEBUGF 1,"IP not found on list, preparing for ARP request\n"
1159 hidnplayr 162
 
1196 hidnplayr 163
   ; if not, reserve an entry in list and send an ARP request packet
1159 hidnplayr 164
 
1196 hidnplayr 165
	push	eax
1159 hidnplayr 166
 
1196 hidnplayr 167
	push	word ARP_REQUEST_TTL
168
	push	word ARP_AWAITING_RESPONSE
169
	push	dword 0
170
	push	word 0
171
	push	eax
172
	call	ARP_add_entry
1159 hidnplayr 173
 
1196 hidnplayr 174
	cmp	eax, -1
175
	je	.full
1159 hidnplayr 176
 
1196 hidnplayr 177
	pop	eax
178
	call	ARP_create_request
1159 hidnplayr 179
 
1196 hidnplayr 180
	ret
1159 hidnplayr 181
 
1196 hidnplayr 182
  .found_it:
1206 hidnplayr 183
	add    esi, ARP_ENTRY.MAC
184
	DEBUGF 1,"Found MAC! (%x-%x-%x-%x-%x-%x)\n",[esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2
1196 hidnplayr 185
	movzx  eax, word [esi]
186
	mov    ebx, [esi+2]
1159 hidnplayr 187
 
1196 hidnplayr 188
	ret
1159 hidnplayr 189
 
1196 hidnplayr 190
  .full:
191
	add	esp, 4
192
	mov	eax, -1
193
	ret
1159 hidnplayr 194
 
1196 hidnplayr 195
 
196
;---------------------------------------------------------------------------
1159 hidnplayr 197
;
1196 hidnplayr 198
; ARP_create_packet
1159 hidnplayr 199
;
1196 hidnplayr 200
; IN:  ip in eax
1159 hidnplayr 201
;
1196 hidnplayr 202
; OUT: /
203
;
204
;---------------------------------------------------------------------------
1159 hidnplayr 205
 
206
 
1196 hidnplayr 207
align 4
208
ARP_create_request:
1159 hidnplayr 209
 
1196 hidnplayr 210
	DEBUGF 1,"Create ARP Packet\n"
1159 hidnplayr 211
 
1196 hidnplayr 212
	call	IPv4_dest_to_dev
1159 hidnplayr 213
 
1196 hidnplayr 214
	push	eax						; DestIP
215
	mov	eax, [IP_LIST+4*edi]				; senderIP
216
	push	eax
1159 hidnplayr 217
 
1196 hidnplayr 218
	mov	edi, [ETH_DRV_LIST + 4*edi]
219
	lea	eax, [edi + ETH_DEVICE.mac]
220
	mov	ebx, ETH_BROADCAST
221
	mov	ecx, 60 ; minimum packet size
222
	mov	edx, edi ;;;
223
	mov	di , ETHER_ARP
1249 hidnplayr 224
	call	ETH_create_packet
1196 hidnplayr 225
	cmp	edi, -1
226
	je	.exit
1159 hidnplayr 227
 
1206 hidnplayr 228
	mov	ecx, eax
1159 hidnplayr 229
 
1206 hidnplayr 230
	mov	[edi + ARP_Packet.HardwareType], 0x0100 ;Ethernet
231
	mov	[edi + ARP_Packet.ProtocolType], 0x0008 ;IP
232
	mov	[edi + ARP_Packet.HardwareSize], 6   ;MAC-addr length
233
	mov	[edi + ARP_Packet.ProtocolSize], 4   ;IP-addr length
234
	mov	[edi + ARP_Packet.Opcode], ARP_REQ_OPCODE      ;Request
235
 
1196 hidnplayr 236
	add	edi, ARP_Packet.SenderMAC			; sendermac
1206 hidnplayr 237
	lea	esi, [ebx + ETH_DEVICE.mac]			;
1196 hidnplayr 238
	movsw							;
239
	movsd							;
1206 hidnplayr 240
	pop	eax						;
241
	stosd							;
242
	mov	eax, -1 					; destmac
243
	stosd							;
244
	stosw							;
1196 hidnplayr 245
	pop	eax
246
	stosd							;
1159 hidnplayr 247
 
1206 hidnplayr 248
	DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx
1159 hidnplayr 249
 
1206 hidnplayr 250
	push	edx ecx
1249 hidnplayr 251
	jmp	ETH_sender
1159 hidnplayr 252
 
1196 hidnplayr 253
  .exit:
254
	add	esp, 8
255
	DEBUGF 1,"Create ARP Packet - failed\n"
256
	mov	eax, -1
257
	ret
1159 hidnplayr 258
 
259
 
260
 
1185 hidnplayr 261
;---------------------------------------------------------------------------
262
;
263
; ARP_decrease_entry_ttls
264
;
265
; IN: /
266
; OUT: /
267
;
268
;---------------------------------------------------------------------------
269
 
270
align 4
271
ARP_decrease_entry_ttls:
272
 
273
	mov	ecx, [NumARP]
274
	test	ecx, ecx
275
	jz	.exit
276
 
277
	mov	ebx, ARPTable
278
 
279
.timer_loop:
280
 
1206 hidnplayr 281
	cmp	[ebx + ARP_ENTRY.TTL], 0xFFFF
1185 hidnplayr 282
	je	.timer_loop_end  ;if TTL==0xFFFF then it's static entry
283
 
1206 hidnplayr 284
	cmp	[ebx + ARP_ENTRY.TTL], 0
1185 hidnplayr 285
	jnz	.timer_loop_end_with_dec  ;if TTL!=0
286
 
287
	; Ok, TTL is 0
288
	;if Status==AWAITING_RESPONSE and TTL==0
289
	;then we have to change it to ARP_RESPONSE_TIMEOUT
1206 hidnplayr 290
	cmp	[ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
1185 hidnplayr 291
	jne	@f
292
 
1206 hidnplayr 293
	mov	[ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT
294
	mov	[ebx + ARP_ENTRY.TTL], word 0x000A   ;10 sec
1185 hidnplayr 295
	jmp	.timer_loop_end
296
 
297
  @@:
298
	;if TTL==0 and Status==VALID_MAPPING, we have to delete it
299
	;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too
1206 hidnplayr 300
	mov	esi, [NumARP]
1185 hidnplayr 301
	sub	esi, ecx	  ;esi=index of entry, will be deleted
302
 
1206 hidnplayr 303
	push	ebx ecx
1185 hidnplayr 304
	call	ARP_del_entry
1206 hidnplayr 305
	pop	ecx ebx
1185 hidnplayr 306
 
307
	jmp	.timer_loop_end
308
 
309
 
310
.timer_loop_end_with_dec:
311
 
1206 hidnplayr 312
	dec	[ebx + ARP_ENTRY.TTL]  ;decrease TTL
1185 hidnplayr 313
 
314
.timer_loop_end:
315
 
316
	add	ebx, ARP_ENTRY.size
317
	loop	.timer_loop
318
 
319
.exit:
320
 
321
	ret
322
 
1196 hidnplayr 323
;---------------------------------------------------------------------------
324
;
325
; ARP_add_entry (or update)
326
;
327
; IN: arp entry in stack: esp     .IP
328
;                         esp+4   .MAC
329
;                         esp+10  .Status
330
;                         esp+12  .TTL
331
;                         esp+14
332
;
333
; OUT: eax = entry #, -1 on error
334
;
335
;---------------------------------------------------------------------------
1185 hidnplayr 336
 
1196 hidnplayr 337
; TODO: use a mutex
338
 
339
align 4
340
ARP_add_entry:
341
 
1206 hidnplayr 342
	DEBUGF 1,"ARP add entry: "
343
 
1196 hidnplayr 344
	mov	ecx, [NumARP]
345
	test	ecx, ecx
346
	jz	.add
347
 
1251 clevermous 348
	mov	eax, dword[esp + 4 + ARP_ENTRY.MAC]
349
	mov	bx , word[esp + 4 + ARP_ENTRY.MAC + 4]
1196 hidnplayr 350
	mov	esi, ARPTable
351
 
352
.loop:
353
	cmp	dword [esi + ARP_ENTRY.MAC], eax
354
	jne	.maybe_next
355
	cmp	word [esi + ARP_ENTRY.MAC + 4], bx
356
	jne	.maybe_next
357
 
358
	cmp	dword[esi + ARP_ENTRY.TTL], 0xFFFF ; static entry
359
	jne	.notstatic
1251 clevermous 360
	cmp	dword[esp + 4 + ARP_ENTRY.TTL], 0xFFFF
1206 hidnplayr 361
	jne	.error
1196 hidnplayr 362
.notstatic:
363
 
364
	mov	ebx, [NumARP]
365
	xchg	ebx, ecx
366
	sub	ecx, ebx
367
	jmp	.add
368
 
369
.maybe_next:
370
	add	esi, ARP_ENTRY.size
371
	loop	.loop
372
 
373
	mov	ecx, [NumARP]
374
	cmp	ecx, ARP_TABLE_SIZE
1206 hidnplayr 375
	jge	.error
1196 hidnplayr 376
 
377
.add:
378
	push	ecx
379
	imul	ecx, ARP_ENTRY.size
380
	lea	edi, [ecx + ARPTable]
1206 hidnplayr 381
	lea	esi, [esp + 8]
1196 hidnplayr 382
	mov	ecx, ARP_ENTRY.size/2
383
	repz	movsw
384
 
385
	inc	[NumARP]
386
	pop	eax
387
 
388
.exit:
1206 hidnplayr 389
	DEBUGF 1,"Exiting\n"
1251 clevermous 390
	ret	ARP_ENTRY.size
1196 hidnplayr 391
 
1206 hidnplayr 392
.error:
1196 hidnplayr 393
 
1206 hidnplayr 394
	DEBUGF 1,"error! \n"
1196 hidnplayr 395
 
396
	mov	eax, -1
397
	jmp	.exit
398
 
399
 
1185 hidnplayr 400
;---------------------------------------------------------------------------
401
;
402
; ARP_del_entry
403
;
404
; IN: entry # in esi
405
; OUT: /
406
;
407
;---------------------------------------------------------------------------
408
 
409
align 4
410
ARP_del_entry:
411
 
1206 hidnplayr 412
	DEBUGF 1,"ARP del entry %u, total entrys: %u\n", esi, [NumARP]
413
 
414
	cmp	esi, [NumARP]
415
	jge	.error
416
 
417
	DEBUGF 1,"deleting the entry..\n"
418
 
1185 hidnplayr 419
	imul	esi, ARP_ENTRY.size
420
 
421
	mov	ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size
422
	sub	ecx, esi
423
 
424
	lea	edi, [ebx + esi]	    ;edi=ptr to entry that should be deleted
425
	lea	esi, [edi + ARP_ENTRY.size] ;esi=ptr to next entry
426
 
427
	shr	ecx,1	   ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER!
428
	rep	movsw
429
 
1196 hidnplayr 430
	dec	[NumARP] ;decrease arp-entries counter
1206 hidnplayr 431
.error:
1185 hidnplayr 432
	ret
433
 
434
 
435
 
436
 
1159 hidnplayr 437
;-----------------------------------------------------
438
;
439
; ARP_Handler:
440
;
441
;  This function handles ARP protocol over ethernet
442
;  (other protocols may follow in the future)
443
;
444
;  IN:  Pointer to buffer in [esp]
445
;       size of buffer in [esp+4]
446
;       packet size (without ethernet header) in ecx
447
;  OUT: /
448
;
449
;-----------------------------------------------------
1196 hidnplayr 450
 
1159 hidnplayr 451
align 4
1196 hidnplayr 452
ARP_handler:
1159 hidnplayr 453
 
454
	DEBUGF	1,"ARP_Handler - start\n"
455
	cmp	ecx, 28
456
	jl	.exit
457
 
1196 hidnplayr 458
	cmp	word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE	; Is this a reply packet?
459
	jne	.maybe_request
1159 hidnplayr 460
 
1206 hidnplayr 461
	DEBUGF	1,"ARP_Handler - it's a reply packet from %u.%u.%u.%u\n",\
462
	[edx + ARP_Packet.SenderIP]:1,[edx + ARP_Packet.SenderIP+1]:1,[edx + ARP_Packet.SenderIP+2]:1,[edx + ARP_Packet.SenderIP+3]:1,
463
 
1196 hidnplayr 464
	mov	ecx, [NumARP]
465
	test	ecx, ecx
466
	jz	.exit
1159 hidnplayr 467
 
1206 hidnplayr 468
	mov	eax, [edx + ARP_Packet.SenderIP]
1196 hidnplayr 469
	mov	esi, ARPTable+ARP_ENTRY.IP
470
 
471
  .loop:
1206 hidnplayr 472
	cmp	[esi], eax
473
	je	.gotit
474
	add	esi, ARP_ENTRY.size
1196 hidnplayr 475
	loop	.loop
476
 
477
	jmp	.exit
478
 
479
  .gotit:
1206 hidnplayr 480
 
481
	DEBUGF	1,"ARP_Handler - found matching entry\n"
482
 
483
	cmp	[esi+ARP_ENTRY.Status], 0x0300	 ;if it is a static entry, dont touch it
1196 hidnplayr 484
	je	.exit
485
 
1206 hidnplayr 486
	DEBUGF	1,"ARP_Handler - updating entry\n"
1196 hidnplayr 487
 
1206 hidnplayr 488
	mov	[esi+ARP_ENTRY.Status], ARP_VALID_MAPPING
489
	mov	[esi+ARP_ENTRY.TTL], ARP_ENTRY_TTL
1196 hidnplayr 490
 
1206 hidnplayr 491
	mov	eax, dword [edx + ARP_Packet.SenderMAC]
492
	mov	dword [esi+ARP_ENTRY.MAC], eax
493
	mov	ax , word [edx + ARP_Packet.SenderMAC + 4]
494
	mov	word [esi+ARP_ENTRY.MAC+4], ax
495
 
1196 hidnplayr 496
	jmp	.exit
497
 
498
 
499
;------
500
 
501
 
502
  .maybe_request:
1159 hidnplayr 503
	cmp	word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE	; Is this a request packet?
504
	jne	.exit
505
 
506
	call	ETH_struc2dev
1206 hidnplayr 507
	DEBUGF	1,"ARP Request packet through device: %u\n", edi
1171 hidnplayr 508
	inc	[ARP_PACKETS_RX+4*edi]
1159 hidnplayr 509
	cmp	edi, -1
510
	jz	.exit
511
 
512
	mov	eax, edi
513
	shl	eax, 2
514
	add	eax, IP_LIST
515
	mov	eax, [eax]
516
	cmp	eax, [edx + ARP_Packet.TargetIP]		; Is it looking for my IP address?
517
	jnz	.exit
518
	push	eax
519
	push	edi
520
 
521
; OK, it is a request for one of our MAC addresses. Build the frame and send it
1196 hidnplayr 522
; We can reuse the buffer.  (faster then using ARP_create_packet)
1159 hidnplayr 523
 
524
	cld
525
	lea	esi, [edx + ARP_Packet.SenderMAC]
526
	lea	edi, [edx + ARP_Packet.TargetMAC]
527
	movsd							; Move Sender Mac to Dest MAC
528
	movsw							;
529
	movsd							; Move sender IP to Dest IP
530
 
531
	pop	esi
532
	mov	esi, [ETH_DRV_LIST + 4*esi]
533
	lea	esi, [esi + ETH_DEVICE.mac]
534
	lea	edi, [edx + ARP_Packet.SenderMAC]
535
	movsd							; Copy MAC address from in MAC_LIST
536
	movsw							;
537
	pop	eax
538
	stosd							; Write our IP
539
 
540
	mov	word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE
541
 
542
; Now, Fill in ETHERNET header
543
 
544
	mov	edi, [esp]
545
	lea	esi, [edx + ARP_Packet.TargetMAC]
546
	movsd
547
	movsw
548
	lea	esi, [edx + ARP_Packet.SenderMAC]
549
	movsd
550
	movsw
1196 hidnplayr 551
;        mov     ax , ETHER_ARP
552
;        stosw
1159 hidnplayr 553
 
1206 hidnplayr 554
	DEBUGF	1,"ARP_Handler - Sending reply \n"
555
 
1249 hidnplayr 556
	jmp	ETH_sender					; And send it!
1159 hidnplayr 557
 
1196 hidnplayr 558
     .exit:
1159 hidnplayr 559
	call	kernel_free
560
	add	esp, 4						; pop (balance stack)
561
 
1206 hidnplayr 562
	DEBUGF 1,"ARP_Handler - exiting\n"
1159 hidnplayr 563
	ret
564
 
565
 
566
 
567
 
568
;---------------------------------------------------------------------------
569
;
570
; ARP_API
571
;
572
; This function is called by system function 75
573
;
574
; IN:  subfunction number in bl
575
;      device number in bh
576
;      ecx, edx, .. depends on subfunction
577
;
578
; OUT:
579
;
580
;---------------------------------------------------------------------------
581
 
582
align 4
583
ARP_API:
584
 
585
	movzx	eax, bh
586
	shl	eax, 2
587
 
588
	test	bl, bl
589
	jz	.packets_tx	; 0
590
	dec	bl
591
	jz	.packets_rx	; 1
592
	dec	bl
593
	jz	.entries	; 2
594
	dec	bl
595
	jz	.read		; 3
596
	dec	bl
597
	jz	.write		; 4
598
	dec	bl
599
	jz	.remove 	; 5
600
	dec	bl
601
 
602
.error:
603
	mov	eax, -1
604
	ret
605
 
606
.packets_tx:
607
	add	eax, ARP_PACKETS_TX
608
	mov	eax, [eax]
609
	ret
610
 
611
.packets_rx:
612
	add	eax, ARP_PACKETS_RX
613
	mov	eax, [eax]
614
	ret
615
 
616
.entries:
617
	mov	eax, [NumARP]
618
	ret
619
 
620
.read:
1200 hidnplayr 621
	cmp	ecx, [NumARP]
622
	jge	.error
623
	; edi = pointer to buffer
624
	; ecx = # entry
625
	imul	ecx, ARP_ENTRY.size
626
	add	ecx, ARPTable
627
	mov	esi, ecx
628
	mov	ecx, ARP_ENTRY.size/2
629
	rep	movsw
630
 
631
	xor	eax, eax
1159 hidnplayr 632
	ret
633
 
634
.write:
1200 hidnplayr 635
	; esi = pointer to buffer
636
	sub	esp, ARP_ENTRY.size
637
	mov	edi, esp
638
	mov	ecx, ARP_ENTRY.size/2
639
	rep	movsw
1251 clevermous 640
	call	ARP_add_entry	     ;out: eax = entry number, -1 on error
641
	ret
1159 hidnplayr 642
 
643
.remove:
1200 hidnplayr 644
	; ecx = # entry
645
	mov	esi, ecx
1196 hidnplayr 646
	call	ARP_del_entry
1159 hidnplayr 647
	ret
648