Subversion Repositories Kolibri OS

Rev

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