Subversion Repositories Kolibri OS

Rev

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

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