Subversion Repositories Kolibri OS

Rev

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