Subversion Repositories Kolibri OS

Rev

Rev 1171 | 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_DEL		      equ  2
115
ARP_TABLE_GET		      equ  3
116
ARP_TABLE_GET_ENTRIES_NUMBER  equ  4
117
ARP_TABLE_IP_TO_MAC	      equ  5
118
ARP_TABLE_TIMER 	      equ  6
119
 
120
;Index's constants
121
EXTRA_IS_ARP_PACKET_PTR  equ  0   ;if Extra contain pointer to ARP_Packet
122
EXTRA_IS_ARP_ENTRY_PTR	 equ  -1  ;if Extra contain pointer to ARP_ENTRY
123
 
124
align 4
125
proc arp_table_manager stdcall uses ebx esi edi ecx edx, Opcode:DWORD,Index:DWORD,Extra:DWORD
126
 
127
    mov     ebx, ARPTable  ;ARPTable base
128
    mov     ecx, dword[NumARP]	       ;ARP-entries counter
129
 
130
    mov     eax, dword[Opcode]
131
 
132
    cmp     eax, ARP_TABLE_TIMER
133
    je	    .timer
134
 
135
    DEBUGF 1,"ARP table manager opcode:%u numARP:%u\n",eax,ecx
136
 
137
    cmp     eax, ARP_TABLE_ADD
138
    je	    .add
139
    cmp     eax, ARP_TABLE_DEL
140
    je	    .del
141
    cmp     eax, ARP_TABLE_GET
142
    je	    .get
143
    cmp     eax, ARP_TABLE_IP_TO_MAC
144
    je	    .ip_to_mac
145
    cmp     eax, ARP_TABLE_GET_ENTRIES_NUMBER
146
    je	    .get_entries_number
147
    jmp     .exit     ;if unknown opcode
148
 
149
 
150
;;BEGIN TIMER
151
;;Description: it must be callback every second. It is responsible for removing expired routes.
152
;;IN:   Operation: ARP_TABLE_TIMER
153
;;      Index: must be zero
154
;;      Extra: must be zero
155
;;OUT:
156
;;  EAX=not defined
157
;;
158
.timer:
159
    test    ecx, ecx
160
    jz	    .exit    ;if NumARP=0 nothing to do
161
;    sub     ecx, ARP_TABLE_ENTRIES  ;ecx=dynamic entries number
162
;    jz      .exit    ;if NumARP=number of static entries then exit
163
 
164
;    add     ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE  ;ebx=dynamic entries base
165
 
166
  .timer_loop:
167
    movsx   esi, word [ebx + ARP_ENTRY.TTL]
168
    cmp     esi, 0xFFFFFFFF
169
    je	    .timer_loop_end  ;if TTL==0xFFFF then it's static entry
170
 
171
    test    esi, esi
172
    jnz     .timer_loop_end_with_dec  ;if TTL!=0
173
 
174
    ; Ok, TTL is 0
175
    ;if Status==AWAITING_RESPONSE and TTL==0
176
    ;then we have to change it to ARP_RESPONSE_TIMEOUT
177
    cmp     word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
178
    jne     @f
179
 
180
    mov     word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT
181
    mov     word [ebx + ARP_ENTRY.TTL], word 0x000A   ;10 sec
182
    jmp     .timer_loop_end
183
 
184
  @@:
185
    ;if TTL==0 and Status==VALID_MAPPING, we have to delete it
186
    ;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too
187
    mov     esi, dword[NumARP]
188
    sub     esi, ecx	      ;esi=index of entry, will be deleted
189
    stdcall arp_table_manager,ARP_TABLE_DEL,esi,0 ;opcode,index,extra
190
    jmp     .timer_loop_end
191
 
192
 
193
  .timer_loop_end_with_dec:
194
    dec     word [ebx + ARP_ENTRY.TTL]	;decrease TTL
195
  .timer_loop_end:
196
    add     ebx, ARP_ENTRY.size
197
    loop    .timer_loop
198
 
199
    jmp     .exit
200
;;END TIMER
201
 
202
;;BEGIN ADD
203
;;Description: it adds an entry in the table. If ARP-table already
204
;;             contains same IP, it will be updated.
205
;;IN:   Operation: ARP_TABLE_ADD
206
;;      Index: specifies what contains Extra-parameter
207
;;      Extra: if Index==EXTRA_IS_ARP_Packet_PTR,
208
;;             then Extra contains pointer to ARP_Packet,
209
;;             otherwise Extra contains pointer to ARP_ENTRY
210
;;OUT:
211
;;  EAX=index of entry, that has been added
212
;;
213
.add:
214
 
215
    DEBUGF 1,"1"
216
 
217
    sub     esp, ARP_ENTRY.size   ;Allocate ARP_ENTRY_SIZE byte in stack
218
 
219
    mov     esi, [Extra]   ;pointer
220
    mov     edi, [Index]   ;opcode
221
 
222
    cmp     edi, EXTRA_IS_ARP_PACKET_PTR
223
    je	    .ARP_Packet_to_entry ;if Extra contain ptr to ARP_Packet and we have to form arp-entry
224
				 ;else it contain ptr to arp-entry
225
 
226
    DEBUGF 1,"2"
227
 
228
    cld
229
	  ; esi already has been loaded
230
    mov     edi, esp	  ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
231
    mov     ecx,ARP_ENTRY.size/2  ;ARP_ENTRY_SIZE must be even number!!!
232
    rep     movsw    ;copy
233
    jmp     .search
234
 
235
  .ARP_Packet_to_entry:
236
 
237
    DEBUGF 1,"3"
238
    mov     edx, dword[esi + ARP_Packet.SenderIP] ;esi=base of ARP_Packet
239
    mov     [esp + ARP_ENTRY.IP], edx
240
 
241
    cld
242
    lea     esi, [esi + ARP_Packet.SenderMAC]
243
    lea     edi, [esp + ARP_ENTRY.MAC]
244
    movsd
245
    movsw
246
    mov     word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING  ; specify the type - a valid entry
247
    mov     word[esp + ARP_ENTRY.TTL], 0x0E10	 ; = 1 hour
248
 
249
  .search:
250
 
251
    DEBUGF 1,"4"
252
    mov     edx, dword[esp + ARP_ENTRY.IP]  ;edx=IP-address, which we'll search
253
    mov     ecx, dword[NumARP]		    ;ecx=ARP-entries counter
254
    jecxz   .add_to_end 		    ;if ARP-entries number == 0
255
    imul    eax, ecx, ARP_ENTRY.size	    ;eax=current table size(in bytes)
256
  @@:
257
    sub     eax, ARP_ENTRY.size
258
    cmp     dword[ebx + eax + ARP_ENTRY.IP], edx
259
    loopnz  @b
260
;    jz      .replace       ; found, replace existing entry, ptr to it is in eax
261
 
1162 hidnplayr 262
  .add_to_end:
1159 hidnplayr 263
;
264
;    DEBUGF 1,"5\n"
265
;    ;else add to end
266
;    or      eax,-1    ;set eax=0xFFFFFFFF if adding is impossible
267
;    mov     ecx, dword[NumARP]
268
;    cmp     ecx, ARP_TABLE_SIZE
269
;    je      .add_exit   ;if arp-entries number is equal to arp-table maxsize
270
 
271
;    imul    eax, dword[NumARP], ARP_ENTRY.size ;eax=ptr to end of ARPTable
272
;    inc     dword [NumARP]    ;increase ARP-entries counter
273
 
274
;  .replace:
275
    DEBUGF 1,"Updating ARP entry: %x-%x-%x-%x-%x-%x = %u.%u.%u.%u to slot:%u\n",\
276
    [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,\
277
    [esp + ARP_ENTRY.IP]:1,[esp + ARP_ENTRY.IP+1]:1,[esp + ARP_ENTRY.IP+2]:1,[esp + ARP_ENTRY.IP+3]:1,eax
278
 
279
    cld
280
    mov     esi, esp		  ;esp=base of ARP-entry, that will be added
281
    lea     edi, [ebx + eax]	  ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
282
    mov     ecx,ARP_ENTRY.size/2  ;ARP_ENTRY_SIZE must be even number!!!
283
    rep     movsw
284
 
285
    mov     ecx, ARP_ENTRY.size
286
    xor     edx, edx  ;"div" takes operand from EDX:EAX
287
    div     ecx       ;eax=index of entry, which has been added
288
 
289
 
290
 
291
.add_exit:
292
 
293
    add     esp, ARP_ENTRY.size   ;free stack
294
    jmp     .exit
295
;;END ADD
296
 
297
;;BEGIN DEL
298
;;Description: it deletes an entry in the table.
299
;;IN:   Operation: ARP_TABLE_DEL
300
;;      Index: index of entry, that should be deleted
301
;;      Extra: must be zero
302
;;OUT:
303
;;  EAX=not defined
304
;;
305
.del:
306
    mov     esi, [Index]
307
    imul    esi, ARP_ENTRY.size
308
 
309
    mov     ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size
310
    sub     ecx, esi
311
 
312
    lea     edi, [ebx + esi]		;edi=ptr to entry that should be deleted
313
    lea     esi, [edi + ARP_ENTRY.size] ;esi=ptr to next entry
314
 
315
    shr     ecx,1      ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER!
316
    cld
317
    rep     movsw
318
 
319
    dec     dword[NumARP] ;decrease arp-entries counter
320
    jmp     .exit
321
;;END DEL
322
 
323
;;BEGIN GET
324
;;Description: it reads an entry of table into buffer.
325
;;IN:   Operation: ARP_TABLE_GET
326
;;      Index: index of entry, that should be read
327
;;      Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE)
328
;;OUT:
329
;;  EAX=not defined
330
;;
331
.get:
332
    mov     esi, [Index]
333
    imul    esi, ARP_ENTRY.size  ;esi=ptr to required ARP_ENTRY
334
    mov     edi, [Extra]	  ;edi=buffer for reading
335
    mov     ecx, ARP_ENTRY.size/2 ; must be even number!!!
336
    cld
337
    rep     movsw
338
    jmp     .exit
339
;;END GET
340
 
341
;;BEGIN IP_TO_MAC
342
;;Description: it gets an IP from Index, scans each entry in the table and writes
343
;;             MAC, that relates to specified IP, into buffer specified in Extra.
344
;;             And if it cannot find an IP-address in the table, it does an ARP-request of that.
345
;;IN:   Operation: ARP_TABLE_IP_TO_MAC
346
;;      Index: IP that should be transformed into MAC
347
;;      Extra: pointer to buffer where will be written the MAC-address.
348
;;OUT:
349
;;  EAX=ARP table entry status code.
350
;;      If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request.
351
;;      If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system.
352
;;      If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long.
353
;;      If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC.
354
;;
355
;;  If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet
356
;;  resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this
357
;;  function with 1sec delay. sure, only if it not return a valid MAC after a first call.
358
;;
359
.ip_to_mac:
360
 
361
    DEBUGF 1,"Trying to find MAC for %u.%u.%u.%u\n",[Index]:1,[Index+1]:1,[Index+2]:1,[Index+3]:1
362
 
363
    xor     eax, eax
364
    mov     edi, dword[Extra]
365
    cld
366
    stosd
367
    stosw
368
 
369
 
370
    ; first, check destination IP to see if it is on 'this' network.
371
    ; The test is:
372
    ; if ( destIP & subnet_mask == stack_ip & subnet_mask )
373
    ;   destination is local
374
    ; else
375
    ;  destination is remote, so pass to gateway
376
 
377
 
378
;;; TODO: get device number ! (in edx)
379
    xor     edx, edx
380
 
381
    mov     eax, [Index]       ;eax=required IP
382
    mov     esi, eax
383
    and     esi, [SUBNET_LIST+edx]
384
    mov     ecx, [IP_LIST+edx]
385
    and     ecx, [SUBNET_LIST+edx]
386
    cmp     esi, ecx
387
    je	    @f	      ;if we and target IP are located in the same network
388
    mov     eax, [GATEWAY_LIST+edx]
389
    mov     [Index], eax
390
    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
391
  @@:
392
 
393
    cmp     dword[NumARP], 0
394
    je	    .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP.
395
				    ;EAX will be containing a zero, it's equal to ARP_NO_ENTRY
396
 
397
    mov     ecx, dword[NumARP]
398
    imul    esi, ecx, ARP_ENTRY.size  ;esi=current ARP-table size
399
 
400
  @@:
401
    sub     esi, ARP_ENTRY.size
402
    cmp     [ebx + esi + ARP_ENTRY.IP], eax	    ; ebx=ARPTable base
403
    loopnz  @b			     ; Return back if non match
404
    jnz     .ip_to_mac_send_request  ; and request IP->MAC if none found in the table
405
 
406
    ; Return the entry status in eax
407
    movzx   eax, word[ebx + esi + ARP_ENTRY.Status]
408
 
409
    DEBUGF 1,"MAC found:  %x-%x-%x-%x-%x-%x status:%x in slot:%u\n",\
410
    [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
411
 
412
    ; esi holds index
413
    cld
414
    lea     esi, [ebx + esi + ARP_ENTRY.MAC]
415
    mov     edi, [Extra]   ;edi=ptr to buffer for write MAC
416
    movsd
417
    movsw
418
    jmp     .exit
419
 
420
  .ip_to_mac_send_request:
421
;;; TODO: get device number ! (in edx)
422
    xor     edx, edx
423
    mov     edx, [ETH_DRV_LIST + 4*edx]
424
    lea     ecx, [edx + ETH_DEVICE.mac]
425
 
426
    stdcall arp_request,[Index],[IP_LIST+edx],ecx  ;TargetIP,SenderIP_ptr,SenderMAC_ptr
427
    mov     eax, ARP_NO_ENTRY
428
    jmp     .exit
429
 
430
;;END IP_TO_MAC
431
 
432
;;BEGIN GET_ENTRIES_NUMBER
433
;;Description: returns an ARP-entries number in the ARPTable
434
;;IN:   Operation: ARP_TABLE_GET_ENTRIES_NUMBER
435
;;      Index: must be zero
436
;;      Extra: must be zero
437
;;OUT:
438
;;  EAX=ARP-entries number in the ARPTable
439
  .get_entries_number:
440
    mov     eax, dword[NumARP]
441
    jmp     .exit
442
;;END GET_ENTRIES_NUMBER
443
 
444
.exit:
445
    ret
446
endp
447
 
448
 
449
;***************************************************************************
450
;   Function
451
;      arp_request  [by Johnny_B]
452
;
453
;   Description
454
;      Sends an ARP request on the ethernet
455
;   IN:
456
;     TargetIP      : requested IP address
457
;     SenderIP_ptr  : POINTER to sender's IP address(our system's address)
458
;     SenderMAC_ptr : POINTER to sender's MAC address(our system's address)
459
;   OUT:
460
;     EAX=0 (if all is ok), otherwise EAX is not defined
461
;
462
;      EBX,ESI,EDI will be saved
463
;
464
;***************************************************************************
465
proc arp_request stdcall uses ebx esi edi,\
466
    TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD
467
 
468
    DEBUGF 1,"Create ARP request\n"
469
 
470
 
471
    stdcall kernel_alloc, 60  ; minimum eth packet size
472
    test    eax, eax
473
    jz	    .exit
474
 
475
    mov     ebx, eax
476
 
477
    mov     word [ebx + ETH_FRAME.Data + ARP_Packet.HardwareType], 0x0100 ;Ethernet
478
    mov     word [ebx + ETH_FRAME.Data + ARP_Packet.ProtocolType], 0x0008 ;IP
479
    mov     byte [ebx + ETH_FRAME.Data + ARP_Packet.HardwareSize], 0x06   ;MAC-addr length
480
    mov     byte [ebx + ETH_FRAME.Data + ARP_Packet.ProtocolSize], 0x04   ;IP-addr length
481
    mov     word [ebx + ETH_FRAME.Data + ARP_Packet.Opcode], 0x0100	  ;Request
482
 
483
    DEBUGF 1,"1"
484
 
485
    cld
486
    mov     esi, [SenderMAC_ptr]
487
    lea     edi, [ebx + ETH_FRAME.Data + ARP_Packet.SenderMAC]	     ;Our MAC-addr
488
    movsd
489
    movsw
490
 
491
    DEBUGF 1,"2"
492
 
493
    mov     esi, [SenderIP_ptr]
494
    mov     [ebx + ETH_FRAME.Data + ARP_Packet.SenderIP], esi	     ;Our IP-addr
495
;    movsd
496
 
497
    DEBUGF 1,"3"
498
 
499
    lea     edi, [ebx + ETH_FRAME.Data + ARP_Packet.TargetMAC]	     ; Required MAC-addr
500
    xor     eax, eax
501
    stosd
502
    stosw
503
 
504
    DEBUGF 1,"4"
505
 
506
    lea     edi, [ebx + ETH_FRAME.DstMAC]
507
    stosd
508
    stosw
509
 
510
    DEBUGF 1,"5"
511
 
512
    mov     esi, [TargetIP]
513
    mov     dword [ebx + ETH_FRAME.Data + ARP_Packet.TargetIP], esi   ;Required IP-addr(we get it as function parameter)
514
 
515
 
516
    DEBUGF 1,"6"
517
 
518
    mov     esi, [SenderMAC_ptr]
519
    lea     edi, [ebx + ETH_FRAME.SrcMAC]
520
    movsd
521
    movsw
522
 
523
    DEBUGF 1,"7"
524
 
525
    mov     ax , ETHER_ARP
526
    stosw
527
 
528
    DEBUGF 1,"8"
529
 
530
;;; TODO: get device number in edx !!
531
    xor     edx, edx
532
    shl     edx, 2
533
 
1171 hidnplayr 534
    inc     [ARP_PACKETS_TX+edx]
535
 
1159 hidnplayr 536
    push    dword .returnaddr
537
    push    dword 60
538
    push    ebx
539
    mov     ebx, [ETH_DRV_LIST + edx]
540
    jmp     [ebx + ETH_DEVICE.transmit]
541
.returnaddr:
542
 
543
    ; Add an entry in the ARP table, awaiting response
544
    sub     esp, ARP_ENTRY.size    ;allocate memory for ARP-entry
545
 
546
    mov     esi, dword[TargetIP]
547
    mov     dword[esp + ARP_ENTRY.IP],esi
548
 
549
    lea     edi, [esp + ARP_ENTRY.MAC]
550
    xor     eax, eax
551
    stosd
552
    stosw
553
 
554
    mov     word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
555
    mov     word[esp + ARP_ENTRY.TTL], 10  ; 10 seconds
556
 
557
    stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp
558
    add     esp, ARP_ENTRY.size ; free memory
559
 
560
.exit:
561
 
562
    DEBUGF 1,"ARP request - end\n"
563
    ret
564
endp
565
 
566
 
567
 
568
 
569
 
1185 hidnplayr 570
;---------------------------------------------------------------------------
571
;
572
; ARP_decrease_entry_ttls
573
;
574
; IN: /
575
; OUT: /
576
;
577
;---------------------------------------------------------------------------
578
 
579
align 4
580
ARP_decrease_entry_ttls:
581
 
582
	mov	ecx, [NumARP]
583
	test	ecx, ecx
584
	jz	.exit
585
 
586
	mov	ebx, ARPTable
587
 
588
.timer_loop:
589
 
590
	movsx	esi, word [ebx + ARP_ENTRY.TTL]
591
	cmp	esi, 0xFFFFFFFF
592
	je	.timer_loop_end  ;if TTL==0xFFFF then it's static entry
593
 
594
	test	esi, esi
595
	jnz	.timer_loop_end_with_dec  ;if TTL!=0
596
 
597
	; Ok, TTL is 0
598
	;if Status==AWAITING_RESPONSE and TTL==0
599
	;then we have to change it to ARP_RESPONSE_TIMEOUT
600
	cmp	word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
601
	jne	@f
602
 
603
	mov	word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT
604
	mov	word [ebx + ARP_ENTRY.TTL], word 0x000A   ;10 sec
605
	jmp	.timer_loop_end
606
 
607
  @@:
608
	;if TTL==0 and Status==VALID_MAPPING, we have to delete it
609
	;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too
610
	mov	esi, dword[NumARP]
611
	sub	esi, ecx	  ;esi=index of entry, will be deleted
612
 
613
	call	ARP_del_entry
614
 
615
	jmp	.timer_loop_end
616
 
617
 
618
.timer_loop_end_with_dec:
619
 
620
	dec	word [ebx + ARP_ENTRY.TTL]  ;decrease TTL
621
 
622
.timer_loop_end:
623
 
624
	add	ebx, ARP_ENTRY.size
625
	loop	.timer_loop
626
 
627
.exit:
628
 
629
	ret
630
 
631
 
632
;---------------------------------------------------------------------------
633
;
634
; ARP_del_entry
635
;
636
; IN: entry # in esi
637
; OUT: /
638
;
639
;---------------------------------------------------------------------------
640
 
641
align 4
642
ARP_del_entry:
643
 
644
	imul	esi, ARP_ENTRY.size
645
 
646
	mov	ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size
647
	sub	ecx, esi
648
 
649
	lea	edi, [ebx + esi]	    ;edi=ptr to entry that should be deleted
650
	lea	esi, [edi + ARP_ENTRY.size] ;esi=ptr to next entry
651
 
652
	shr	ecx,1	   ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER!
653
	cld
654
	rep	movsw
655
 
656
	dec	dword[NumARP] ;decrease arp-entries counter
657
	ret
658
 
659
 
660
 
661
 
662
 
1159 hidnplayr 663
;-----------------------------------------------------
664
;
665
; ARP_Handler:
666
;
667
;  This function handles ARP protocol over ethernet
668
;  (other protocols may follow in the future)
669
;
670
;  IN:  Pointer to buffer in [esp]
671
;       size of buffer in [esp+4]
672
;       packet size (without ethernet header) in ecx
673
;  OUT: /
674
;
675
;-----------------------------------------------------
676
align 4
677
ARP_Handler:
678
 
679
	DEBUGF	1,"ARP_Handler - start\n"
680
	cmp	ecx, 28
681
	jl	.exit
682
 
683
; Is this a REQUEST?
684
; Is this a request for My Host IP
685
; Yes - So construct a response message.
686
; Send this message to the ethernet card for transmission
687
 
688
;        push    ebx edx
689
	stdcall arp_table_manager, ARP_TABLE_ADD, EXTRA_IS_ARP_PACKET_PTR, edx
690
;        pop     edx ebx
691
 
692
	cmp	word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE	; Is this a request packet?
693
	jne	.exit
694
 
695
	call	ETH_struc2dev
1171 hidnplayr 696
	DEBUGF	1,"ARP Packet came from device: %u\n", edi
697
	inc	[ARP_PACKETS_RX+4*edi]
1159 hidnplayr 698
	cmp	edi, -1
699
	jz	.exit
700
 
701
	mov	eax, edi
702
	shl	eax, 2
703
	add	eax, IP_LIST
704
	mov	eax, [eax]
705
	cmp	eax, [edx + ARP_Packet.TargetIP]		; Is it looking for my IP address?
706
	jnz	.exit
707
	push	eax
708
	push	edi
709
 
710
;        DEBUGF  1,"ETH_ARP_Handler - request for %u.%u.%u.%u\n",[edi+0]:1,[edi+1]:1,[edi+2]:1,[edi+3]:1
711
 
712
; OK, it is a request for one of our MAC addresses. Build the frame and send it
713
; We can reuse the buffer.
714
 
715
	cld
716
	lea	esi, [edx + ARP_Packet.SenderMAC]
717
	lea	edi, [edx + ARP_Packet.TargetMAC]
718
	movsd							; Move Sender Mac to Dest MAC
719
	movsw							;
720
	movsd							; Move sender IP to Dest IP
721
 
722
	pop	esi
723
	mov	esi, [ETH_DRV_LIST + 4*esi]
724
	lea	esi, [esi + ETH_DEVICE.mac]
725
	lea	edi, [edx + ARP_Packet.SenderMAC]
726
	movsd							; Copy MAC address from in MAC_LIST
727
	movsw							;
728
	pop	eax
729
	stosd							; Write our IP
730
 
731
	mov	word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE
732
 
733
; Now, Fill in ETHERNET header
734
 
735
	mov	edi, [esp]
736
	lea	esi, [edx + ARP_Packet.TargetMAC]
737
	movsd
738
	movsw
739
	lea	esi, [edx + ARP_Packet.SenderMAC]
740
	movsd
741
	movsw
742
	mov	ax , ETHER_ARP
743
	stosw
744
 
745
	jmp	ETH_Sender					; And send it!
746
 
747
       .exit:
748
	call	kernel_free
749
	add	esp, 4						; pop (balance stack)
750
 
751
	DEBUGF 1,"ARP_Handler - fail\n"
752
	ret
753
 
754
 
755
 
756
 
757
;---------------------------------------------------------------------------
758
;
759
; ARP_API
760
;
761
; This function is called by system function 75
762
;
763
; IN:  subfunction number in bl
764
;      device number in bh
765
;      ecx, edx, .. depends on subfunction
766
;
767
; OUT:
768
;
769
;---------------------------------------------------------------------------
770
 
771
align 4
772
ARP_API:
773
 
774
	movzx	eax, bh
775
	shl	eax, 2
776
 
777
	test	bl, bl
778
	jz	.packets_tx	; 0
779
	dec	bl
780
	jz	.packets_rx	; 1
781
	dec	bl
782
	jz	.entries	; 2
783
	dec	bl
784
	jz	.read		; 3
785
	dec	bl
786
	jz	.write		; 4
787
	dec	bl
788
	jz	.remove 	; 5
789
	dec	bl
790
 
791
 
792
.error:
793
	mov	eax, -1
794
	ret
795
 
796
.packets_tx:
797
	add	eax, ARP_PACKETS_TX
798
	mov	eax, [eax]
799
	ret
800
 
801
.packets_rx:
802
	add	eax, ARP_PACKETS_RX
803
	mov	eax, [eax]
804
	ret
805
 
806
.entries:
807
	mov	eax, [NumARP]
808
	ret
809
 
810
.read:
811
	; TODO: write code
812
	ret
813
 
814
.write:
815
	; TODO: write code
816
	ret
817
 
818
.remove:
819
	; TODO: write code
820
	ret
821