Subversion Repositories Kolibri OS

Rev

Rev 3600 | Rev 3602 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3600 Rev 3601
Line 56... Line 56...
56
ends
56
ends
Line 57... Line 57...
57
 
57
 
58
align 4
58
align 4
Line 59... Line -...
59
uglobal
-
 
Line 60... Line 59...
60
 
59
uglobal
Line -... Line 60...
-
 
60
 
61
        NumARP          dd ?
61
 
62
 
62
        ARP_table       rb NET_DEVICES_MAX*(ARP_TABLE_SIZE * sizeof.ARP_entry)
63
        ARP_table       rb ARP_TABLE_SIZE * sizeof.ARP_entry    ; TODO: separate ARP table and stats per interface
63
 
Line 79... Line 79...
79
;
79
;
80
;-----------------------------------------------------------------
80
;-----------------------------------------------------------------
81
macro ARP_init {
81
macro ARP_init {
Line 82... Line 82...
82
 
82
 
83
        xor     eax, eax
-
 
84
        mov     [NumARP], eax
-
 
85
 
83
        xor     eax, eax
86
        mov     edi, ARP_PACKETS_TX
84
        mov     edi, ARP_entries_num
87
        mov     ecx, 3*NET_DEVICES_MAX
85
        mov     ecx, 4*NET_DEVICES_MAX
Line 88... Line 86...
88
        rep     stosd
86
        rep     stosd
Line 89... Line 87...
89
 
87
 
Line 109... Line 107...
109
; 0x0002  entry contains an IP address, awaiting ARP response
107
; 0x0002  entry contains an IP address, awaiting ARP response
110
; 0x0003  No response received to ARP request.
108
; 0x0003  No response received to ARP request.
111
; The last status value is provided to allow the network layer to delete
109
; The last status value is provided to allow the network layer to delete
112
; a packet that is queued awaiting an ARP response
110
; a packet that is queued awaiting an ARP response
Line 113... Line 111...
113
 
111
 
-
 
112
        xor     edi, edi
-
 
113
  .loop_outer:
114
        mov     ecx, [NumARP]
114
        mov     ecx, [ARP_entries_num + 4*edi]
115
        test    ecx, ecx
115
        test    ecx, ecx
Line -... Line 116...
-
 
116
        jz      .exit
-
 
117
 
116
        jz      .exit
118
        mov     esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)
117
 
119
        imul    esi, edi
118
        mov     esi, ARP_table
120
        add     esi, ARP_table
119
  .loop:
121
  .loop:
Line 120... Line 122...
120
        cmp     [esi + ARP_entry.TTL], ARP_STATIC_ENTRY
122
        cmp     [esi + ARP_entry.TTL], ARP_STATIC_ENTRY
Line 131... Line 133...
131
 
133
 
132
  .time_out:
134
  .time_out:
133
        cmp     [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE
135
        cmp     [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE
Line 134... Line 136...
134
        je      .response_timeout
136
        je      .response_timeout
135
 
137
 
136
        push    esi ecx
138
        push    esi edi ecx
Line 137... Line 139...
137
        call    ARP_del_entry
139
        call    ARP_del_entry
Line 138... Line 140...
138
        pop     ecx esi
140
        pop     ecx edi esi
139
 
141
 
140
        jmp     .next
142
        jmp     .next
Line 141... Line 143...
141
 
143
 
Line 142... Line 144...
142
  .response_timeout:
144
  .response_timeout:
-
 
145
        mov     [esi + ARP_entry.Status], ARP_RESPONSE_TIMEOUT
-
 
146
        mov     [esi + ARP_entry.TTL], 10
-
 
147
 
Line 143... Line 148...
143
        mov     [esi + ARP_entry.Status], ARP_RESPONSE_TIMEOUT
148
        jmp     .next
Line 144... Line 149...
144
        mov     [esi + ARP_entry.TTL], 10
149
 
Line 194... Line 199...
194
        cmp     [edx + ARP_header.Opcode], ARP_REP_OPCODE
199
        cmp     [edx + ARP_header.Opcode], ARP_REP_OPCODE
195
        jne     .maybe_request
200
        jne     .maybe_request
Line 196... Line 201...
196
 
201
 
Line 197... Line 202...
197
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: It's a reply\n"
202
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: It's a reply\n"
198
 
203
 
199
        mov     ecx, [NumARP]
204
        mov     ecx, [ARP_entries_num + 4*edi]
Line -... Line 205...
-
 
205
        test    ecx, ecx
-
 
206
        jz      .exit
200
        test    ecx, ecx
207
 
201
        jz      .exit
208
        mov     esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)
202
 
209
        imul    esi, edi
203
        mov     esi, ARP_table
210
        add     esi, ARP_table
204
  .loop:
211
  .loop:
205
        cmp     [esi + ARP_entry.IP], eax
212
        cmp     [esi + ARP_entry.IP], eax
Line 296... Line 303...
296
 
303
 
297
;---------------------------------------------------------------------------
304
;---------------------------------------------------------------------------
298
;
305
;
299
; ARP_output_request
306
; ARP_output_request
300
;
307
;
301
; IN:  ip in eax
308
; IN:   ebx = device ptr
302
;      device in edi
309
;       eax = IP
-
 
310
; OUT: /
303
; OUT: /
311
;       scratched: probably everything
304
;
312
;
305
;---------------------------------------------------------------------------
313
;---------------------------------------------------------------------------
306
align 4
314
align 4
Line 307... Line 315...
307
ARP_output_request:
315
ARP_output_request:
308
 
-
 
309
        push    eax                             ; DestIP
-
 
310
        pushd   [IP_LIST + edi]                 ; SenderIP
-
 
311
        inc     [ARP_PACKETS_TX + edi]          ; assume we will succeed
-
 
312
 
-
 
Line -... Line 316...
-
 
316
 
313
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_output_request: ip=%u.%u.%u.%u\n",\
317
        push    eax
Line 314... Line 318...
314
        [esp + 4]:1, [esp + 5]:1, [esp + 6]:1, [esp + 7]:1
318
 
315
 
319
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_output_request: ip=%u.%u.%u.%u device=0x%x\n",\
316
        mov     ebx, [NET_DRV_LIST + edi]       ; device ptr
320
        [esp]:1, [esp + 1]:1, [esp + 2]:1, [esp + 3]:1, ebx
317
 
321
 
318
        lea     eax, [ebx + ETH_DEVICE.mac]     ; local device mac
322
        lea     eax, [ebx + ETH_DEVICE.mac]     ; local device mac
319
        mov     edx, ETH_BROADCAST              ; broadcast mac
323
        mov     edx, ETH_BROADCAST              ; broadcast mac
Line 320... Line -...
320
        mov     ecx, sizeof.ARP_header
-
 
321
        mov     di, ETHER_PROTO_ARP
-
 
322
        call    ETH_output
324
        mov     ecx, sizeof.ARP_header
323
        jz      .exit
325
        mov     di, ETHER_PROTO_ARP
324
 
326
        call    ETH_output
325
        mov     ecx, eax
327
        jz      .exit
326
 
328
 
Line 327... Line 329...
327
        mov     [edi + ARP_header.HardwareType], 0x0100         ; Ethernet
329
        mov     [edi + ARP_header.HardwareType], 0x0100         ; Ethernet
328
        mov     [edi + ARP_header.ProtocolType], 0x0008         ; IP
-
 
329
        mov     [edi + ARP_header.HardwareSize], 6              ; MAC-addr length
330
        mov     [edi + ARP_header.ProtocolType], 0x0008         ; IP
330
        mov     [edi + ARP_header.ProtocolSize], 4              ; IP-addr length
331
        mov     [edi + ARP_header.HardwareSize], 6              ; MAC-addr length
331
        mov     [edi + ARP_header.Opcode], ARP_REQ_OPCODE       ; Request
332
        mov     [edi + ARP_header.ProtocolSize], 4              ; IP-addr length
332
 
-
 
333
        add     edi, ARP_header.SenderMAC
-
 
Line 334... Line 333...
334
 
333
        mov     [edi + ARP_header.Opcode], ARP_REQ_OPCODE       ; Request
335
        lea     esi, [ebx + ETH_DEVICE.mac]     ; SenderMac
334
 
336
        movsw                                   ;
335
        add     edi, ARP_header.SenderMAC
337
        movsd                                   ;
336
        lea     esi, [ebx + ETH_DEVICE.mac]     ; SenderMac
338
        pop     eax                             ; SenderIP
337
        movsw                                   ;
-
 
338
        movsd                                   ;
Line 339... Line 339...
339
        stosd                                   ;
339
 
-
 
340
;        mov     esi, [ebx + NET_DEVICE.number]
-
 
341
        xor     esi, esi        ;;;; FIXME
-
 
342
        inc     esi ;;;;;;;;;
Line 340... Line 343...
340
 
343
        inc     [ARP_PACKETS_TX + 4*esi]        ; assume we will succeed
341
        mov     eax, -1                         ; DestMac
344
        lea     esi, [IP_LIST + 4*esi]          ; SenderIP
342
        stosd                                   ;
345
        movsd
Line 343... Line 346...
343
        stosw                                   ;
346
 
344
        pop     eax                             ; DestIP
347
        mov     esi, ETH_BROADCAST              ; DestMac
345
        stosd                                   ;
348
        movsw                                   ;
346
 
-
 
347
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_output_request: device=%x\n", ebx
349
        movsd                                   ;
Line 348... Line 350...
348
 
350
        popd    [edi]                           ; DestIP
349
        push    edx ecx
351
 
350
        call    [ebx + NET_DEVICE.transmit]
352
        push    edx eax
351
        ret
353
        call    [ebx + NET_DEVICE.transmit]
352
 
354
        ret
-
 
355
 
353
  .exit:
356
  .exit:
354
        add     esp, 4 + 4
357
        add     esp, 4
355
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_output_request: failed\n"
358
        DEBUGF  DEBUG_NETWORK_ERROR, "ARP_output_request: send failed\n"
356
        sub     eax, eax
359
        ret
357
        ret
360
 
358
 
361
 
Line 359... Line 362...
359
 
362
;-----------------------------------------------------------------
Line 360... Line 363...
360
;-----------------------------------------------------------------
363
;
361
;
364
; ARP_add_entry (or update)
362
; ARP_add_entry (or update)
365
;
Line -... Line 366...
-
 
366
; IN:  esi = ptr to entry (can easily be made on the stack)
-
 
367
;      edi = device num
-
 
368
; OUT: eax = entry #, -1 on error
-
 
369
;      esi = ptr to newly created entry
-
 
370
;
-
 
371
;-----------------------------------------------------------------      ; TODO: use a mutex
363
;
372
align 4
-
 
373
ARP_add_entry:
364
; IN:  esi = ptr to entry (can easily be made on the stack)
374
 
365
; OUT: eax = entry #, -1 on error
375
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_add_entry: device=%u\n", edi
366
;      edi = ptr to newly created entry
376
 
367
;
377
        mov     ecx, [ARP_entries_num + 4*edi]
368
;-----------------------------------------------------------------      ; TODO: use a mutex
378
        cmp     ecx, ARP_TABLE_SIZE                                     ; list full ?
Line 369... Line 379...
369
align 4
379
        jae     .full
370
ARP_add_entry:
380
 
Line 371... Line 381...
371
 
381
 
372
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_add_entry: "
382
; From this point on, we can only fail if IP has a static entry, or if table is corrupt.
Line -... Line 383...
-
 
383
 
-
 
384
        inc     [ARP_entries_num + 4*edi]                               ; assume we will succeed
-
 
385
 
373
 
386
        push    edi
374
        mov     ecx, [NumARP]
387
        xor     ecx, ecx
375
        cmp     ecx, ARP_TABLE_SIZE                                     ; list full ?
388
        imul    edi, ARP_TABLE_SIZE*sizeof.ARP_entry
376
        jae     .error
389
        add     edi, ARP_table
377
 
-
 
378
        xor     eax, eax
390
        mov     eax, [edi + ARP_entry.IP]
Line 379... Line 391...
379
        mov     edi, ARP_table
391
  .loop:
-
 
392
        cmp     [edi + ARP_entry.Status], ARP_NO_ENTRY                  ; is this slot empty?
380
        mov     ecx, [esi + ARP_entry.IP]
393
        je      .add
381
  .loop:
394
 
382
        cmp     [edi + ARP_entry.Status], ARP_NO_ENTRY                  ; is this slot empty?
395
        cmp     [edi + ARP_entry.IP], eax                               ; if not, check if it doesnt collide
383
        je      .add
396
        jne     .maybe_next
-
 
397
 
384
 
398
        cmp     [edi + ARP_entry.TTL], ARP_STATIC_ENTRY                 ; ok, its the same IP, update it if not static
Line 385... Line 399...
385
        cmp     [edi + ARP_entry.IP], ecx                               ; if not, check if it doesnt collide
399
        jne     .add
Line 386... Line 400...
386
        jne     .maybe_next
400
 
-
 
401
        DEBUGF  DEBUG_NETWORK_ERROR, "ARP_add_entry: failed, IP already has a static entry\n"
-
 
402
        jmp     .error
387
 
403
 
-
 
404
  .maybe_next:                                                          ; try the next slot
388
        cmp     [edi + ARP_entry.TTL], ARP_STATIC_ENTRY                 ; ok, its the same IP, update it if not static
405
        add     edi, sizeof.ARP_entry
389
        jne     .add
406
        inc     ecx
Line 390... Line 407...
390
 
407
        cmp     ecx, ARP_TABLE_SIZE
391
  .maybe_next:                                                          ; try the next slot
408
        jb      .loop
392
        add     edi, sizeof.ARP_entry
409
 
393
        inc     eax
410
  .add:
394
        cmp     eax, ARP_TABLE_SIZE
411
        push    ecx
-
 
412
        mov     ecx, sizeof.ARP_entry/2
395
        jae     .error
413
        rep     movsw
396
        jmp     .loop
414
        pop     ecx
397
 
415
        lea     esi, [edi - sizeof.ARP_entry]
398
  .add:
416
        pop     edi
399
        mov     ecx, sizeof.ARP_entry/2
417
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_add_entry: entry=%u\n", ecx
Line 400... Line 418...
400
        rep     movsw
418
 
401
        inc     [NumARP]
419
        ret
402
        sub     edi, sizeof.ARP_entry
420
 
Line -... Line 421...
-
 
421
  .error:
-
 
422
        pop     edi
403
        DEBUGF  DEBUG_NETWORK_VERBOSE, "entry=%u\n", eax
423
        dec     [ARP_entries_num + 4*edi]
404
 
424
        DEBUGF  DEBUG_NETWORK_ERROR, "ARP_add_entry_failed\n"
405
        ret
425
  .full:
Line -... Line 426...
-
 
426
        mov     eax, -1
406
 
427
        ret
407
  .error:
428
 
408
        DEBUGF  DEBUG_NETWORK_VERBOSE, "failed\n"
429
 
Line -... Line 430...
-
 
430
;-----------------------------------------------------------------
409
        mov     eax, -1
431
;
410
        ret
432
; ARP_del_entry
411
 
433
;
Line 412... Line 434...
412
 
434
; IN:   esi = ptr to arp entry
-
 
435
;       edi = device number
413
;-----------------------------------------------------------------
436
; OUT:  /
Line 414... Line 437...
414
;
437
;
Line 463... Line 486...
463
align 4
486
align 4
464
ARP_IP_to_MAC:
487
ARP_IP_to_MAC:
Line 465... Line 488...
465
 
488
 
466
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: %u.%u", al, ah
489
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: %u.%u", al, ah
467
        rol     eax, 16
490
        rol     eax, 16
468
        DEBUGF  DEBUG_NETWORK_VERBOSE, ".%u.%u\n", al, ah
491
        DEBUGF  DEBUG_NETWORK_VERBOSE, ".%u.%u device: %u\n", al, ah, edi
Line 469... Line 492...
469
        rol     eax, 16
492
        rol     eax, 16
470
 
493
 
Line 471... Line 494...
471
        cmp     eax, 0xffffffff
494
        cmp     eax, 0xffffffff
472
        je      .broadcast
495
        je      .broadcast
Line 473... Line 496...
473
 
496
 
474
;--------------------------------
497
;--------------------------------
475
; Try to find the IP in ARP_table
498
; Try to find the IP in ARP_table
476
 
499
 
477
        mov     ecx, [NumARP]
500
        mov     ecx, [ARP_entries_num + 4*edi]
478
        test    ecx, ecx
501
        test    ecx, ecx
479
        jz      .not_in_list
502
        jz      .not_in_list
480
        mov     esi, ARP_table + ARP_entry.IP
503
        mov     esi, ARP_table + ARP_entry.IP
-
 
504
  .scan_loop:
481
  .scan_loop:
505
        cmp     [esi], eax
Line 482... Line 506...
482
        cmp     [esi], eax
506
        je      .found_it
483
        je      .found_it
507
        add     esi, sizeof.ARP_entry
Line 484... Line -...
484
        add     esi, sizeof.ARP_entry
-
 
485
        loop    .scan_loop
-
 
486
 
-
 
487
  .not_in_list:
508
        dec     ecx
488
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: preparing for ARP request\n"
-
 
489
 
509
        jnz     .scan_loop
490
;--------------------
510
 
491
; Send an ARP request
511
  .not_in_list:
492
 
512
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: preparing for ARP request\n"
493
        push    eax edi                 ; save IP for ARP_output_request
513
 
494
 
514
        push    eax edi                 ; save IP for ARP_output_request
495
; Now create the ARP entry
515
; Now craft the ARP entry on the stack
-
 
516
        pushw   ARP_REQUEST_TTL         ; TTL
-
 
517
        pushw   ARP_AWAITING_RESPONSE   ; status
496
        pushw   ARP_REQUEST_TTL         ; TTL
518
        pushd   0                       ; mac
-
 
519
        pushw   0
-
 
520
        pushd   eax                     ; ip
497
        pushw   ARP_AWAITING_RESPONSE   ; status
521
        mov     esi, esp
Line -... Line 522...
-
 
522
 
498
        pushd   0                       ; mac
523
; Add it to the list
499
        pushw   0
524
        call    ARP_add_entry
Line -... Line 525...
-
 
525
 
500
        pushd   eax                     ; ip
526
; Delete the temporary entry
-
 
527
        add     esp, sizeof.ARP_entry   ; clear the entry from stack
-
 
528
 
501
        mov     esi, esp
529
; If we could not add it to the list, give up
Line 502... Line 530...
502
        call    ARP_add_entry
530
        cmp     eax, -1                 ; did ARP_add_entry fail?
-
 
531
        je      .full
503
        add     esp, sizeof.ARP_entry   ; clear the entry from stack
532
 
504
 
533
;-----------------------------------------------
505
        cmp     eax, -1                 ; did ARP_add_entry fail?
-
 
506
        je      .full
-
 
507
 
-
 
508
        mov     esi, edi
534
; At this point, we got an ARP entry in the list
509
        pop     edi eax                 ; IP in eax, device number in edi, for ARP_output_request
535
 
510
 
536
; Now send a request packet on the network
Line 511... Line 537...
511
        push    esi edi
537
        pop     edi eax                 ; IP in eax, device number in ebx, for ARP_output_request
Line 512... Line 538...
512
        call    ARP_output_request      ; And send a request
538
 
513
        pop     edi esi
539
        push    esi edi
514
 
540
        mov     ebx, [NET_DRV_LIST + 4*edi]
515
;-----------------------------------------------
541
        call    ARP_output_request
516
; At this point, we got an ARP entry in the list
542
        pop     edi esi
517
  .found_it:
543
  .found_it:
518
        cmp     [esi + ARP_entry.Status], ARP_VALID_MAPPING             ; Does it have a MAC assigned?
544
        cmp     [esi + ARP_entry.Status], ARP_VALID_MAPPING             ; Does it have a MAC assigned?
Line 519... Line 545...
519
        je      .valid
545
        je      .valid
Line 520... Line 546...
520
 
546
 
Line 521... Line 547...
521
if ARP_BLOCK
547
if ARP_BLOCK
Line 522... Line 548...
522
 
548
 
523
        cmp     [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE         ; Are we waiting for reply from remote end?
549
        cmp     [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE         ; Are we waiting for reply from remote end?
524
        jne     .give_up
550
        jne     .give_up
525
        push    esi
551
        push    esi edi
526
        mov     esi, 10                 ; wait 10 ms
552
        mov     esi, 10                 ; wait 10 ms
Line 527... Line 553...
527
        call    delay_ms
553
        call    delay_ms
528
        pop     esi
554
        pop     edi esi
529
        jmp     .found_it               ; now check again
555
        jmp     .found_it               ; now check again
Line 604... Line 630...
604
  .conflicts:
630
  .conflicts:
605
        mov     eax, [ARP_CONFLICTS + eax]
631
        mov     eax, [ARP_CONFLICTS + eax]
606
        ret
632
        ret
Line 607... Line 633...
607
 
633
 
608
  .entries:
634
  .entries:
609
        mov     eax, [NumARP]
635
        mov     eax, [ARP_entries_num + eax]
Line 610... Line 636...
610
        ret
636
        ret
611
 
637
 
612
  .read:
638
  .read:
-
 
639
        cmp     ecx, [ARP_entries_num + eax]
-
 
640
        jae     .error
-
 
641
        shr     eax, 2
613
        cmp     ecx, [NumARP]
642
        imul    eax, sizeof.ARP_entry*ARP_TABLE_SIZE
614
        jae     .error
643
        add     eax, ARP_table
615
        ; edi = pointer to buffer
644
        ; edi = pointer to buffer
616
        ; ecx = # entry
-
 
617
        imul    ecx, sizeof.ARP_entry
645
        ; ecx = # entry
618
        add     ecx, ARP_table
646
        imul    ecx, sizeof.ARP_entry
619
        mov     esi, ecx
647
        lea     esi, [eax + ecx]
Line 620... Line 648...
620
        mov     ecx, sizeof.ARP_entry/2
648
        mov     ecx, sizeof.ARP_entry/2
621
        rep     movsw
649
        rep     movsw
Line 622... Line 650...
622
 
650
 
623
        xor     eax, eax
651
        xor     eax, eax
-
 
652
        ret
-
 
653
 
624
        ret
654
  .write:
625
 
655
        ; esi = pointer to buffer
Line 626... Line 656...
626
  .write:
656
        mov     edi, eax
627
        ; esi = pointer to buffer
657
        shr     edi, 2
628
        call    ARP_add_entry           ; out: eax = entry number, -1 on error
658
        call    ARP_add_entry           ; out: eax = entry number, -1 on error
629
        ret
659
        ret
630
 
660
 
631
  .remove:
661
  .remove:
-
 
662
        ; ecx = # entry
-
 
663
        cmp     ecx, [ARP_entries_num + eax]
632
        ; ecx = # entry
664
        jae     .error
633
        cmp     ecx, [NumARP]
665
        imul    ecx, sizeof.ARP_entry
Line 634... Line 666...
634
        jae     .error
666
        lea     esi, [ARP_table + ecx]
635
        imul    ecx, sizeof.ARP_entry
667
        mov     edi, eax
636
        lea     esi, [ARP_table + ecx]
668
        shr     edi, 2
637
        call    ARP_del_entry
669
        call    ARP_del_entry
638
        ret
670
        ret