Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1196 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2888 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2012. 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: 2924 $
1159 hidnplayr 20
 
2614 hidnplayr 21
ARP_NO_ENTRY            = 0
22
ARP_VALID_MAPPING       = 1
23
ARP_AWAITING_RESPONSE   = 2
24
ARP_RESPONSE_TIMEOUT    = 3
1159 hidnplayr 25
 
2614 hidnplayr 26
ARP_REQUEST_TTL         = 31          ; 20 s
27
ARP_ENTRY_TTL           = 937         ; 600 s
28
ARP_STATIC_ENTRY        = -1
1159 hidnplayr 29
 
2614 hidnplayr 30
ARP_REQ_OPCODE          = 0x0100      ; request
31
ARP_REP_OPCODE          = 0x0200      ; reply
1196 hidnplayr 32
 
2614 hidnplayr 33
ARP_TABLE_SIZE          = 20          ; Size of table
1159 hidnplayr 34
 
2305 hidnplayr 35
struct ARP_entry
36
 
2311 hidnplayr 37
       IP               dd ?
38
       MAC              dp ?
39
       Status           dw ?
40
       TTL              dw ?
2305 hidnplayr 41
 
1159 hidnplayr 42
ends
43
 
2305 hidnplayr 44
struct ARP_header
45
 
2311 hidnplayr 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 ?
2305 hidnplayr 55
 
1159 hidnplayr 56
ends
57
 
58
align 4
59
uglobal
60
 
2311 hidnplayr 61
        NumARP          dd ?
1258 hidnplayr 62
 
2924 hidnplayr 63
        ARP_table       rb ARP_TABLE_SIZE * sizeof.ARP_entry    ; TODO: separate ARP table and stats per interface
1159 hidnplayr 64
 
2311 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
 
2311 hidnplayr 82
        xor     eax, eax
83
        mov     [NumARP], eax
1159 hidnplayr 84
 
2311 hidnplayr 85
        mov     edi, ARP_PACKETS_TX
86
        mov     ecx, 2*MAX_NET_DEVICES
87
        rep     stosd
1159 hidnplayr 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
 
2311 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
 
2311 hidnplayr 113
        mov     ecx, [NumARP]
114
        test    ecx, ecx
115
        jz      .exit
1206 hidnplayr 116
 
2311 hidnplayr 117
        mov     esi, ARP_table
1529 hidnplayr 118
  .loop:
2311 hidnplayr 119
        cmp     [esi + ARP_entry.TTL], ARP_STATIC_ENTRY
120
        je      .next
1206 hidnplayr 121
 
2311 hidnplayr 122
        dec     [esi + ARP_entry.TTL]
123
        jz      .time_out
1159 hidnplayr 124
 
1529 hidnplayr 125
  .next:
2311 hidnplayr 126
        add     esi, sizeof.ARP_entry
127
        dec     ecx
128
        jnz     .loop
129
        jmp     .exit
1159 hidnplayr 130
 
1529 hidnplayr 131
  .time_out:
2311 hidnplayr 132
        cmp     [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE
133
        je      .response_timeout
1159 hidnplayr 134
 
2311 hidnplayr 135
        push    esi ecx
136
        call    ARP_del_entry
137
        pop     ecx esi
1159 hidnplayr 138
 
2311 hidnplayr 139
        jmp     .next
1159 hidnplayr 140
 
1529 hidnplayr 141
  .response_timeout:
2311 hidnplayr 142
        mov     [esi + ARP_entry.Status], ARP_RESPONSE_TIMEOUT
143
        mov     [esi + ARP_entry.TTL], 10
1159 hidnplayr 144
 
2311 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
2629 hidnplayr 159
;       packet ptr in edx
1529 hidnplayr 160
;  OUT: /
161
;
162
;-----------------------------------------------------------------
163
align 4
164
ARP_input:
1258 hidnplayr 165
 
2311 hidnplayr 166
        cmp     ecx, sizeof.ARP_header
167
        jb      .exit
1258 hidnplayr 168
 
1529 hidnplayr 169
;---------------------
170
; Handle Reply packets
1258 hidnplayr 171
 
2311 hidnplayr 172
        cmp     [edx + ARP_header.Opcode], ARP_REP_OPCODE
173
        jne     .maybe_request
1159 hidnplayr 174
 
2891 hidnplayr 175
        DEBUGF  1,"ARP_input: got reply packet from %u.%u.%u.%u\n",\
176
        [edx + ARP_header.SenderIP]:1, [edx + ARP_header.SenderIP + 1]:1,\
177
        [edx + ARP_header.SenderIP + 2]:1, [edx + ARP_header.SenderIP + 3]:1
1159 hidnplayr 178
 
2311 hidnplayr 179
        mov     ecx, [NumARP]
180
        test    ecx, ecx
181
        jz      .exit
1159 hidnplayr 182
 
2311 hidnplayr 183
        mov     eax, [edx + ARP_header.SenderIP]
184
        mov     esi, ARP_table
1196 hidnplayr 185
 
1529 hidnplayr 186
  .loop:
2311 hidnplayr 187
        cmp     [esi + ARP_entry.IP], eax
188
        je      .gotit
189
        add     esi, sizeof.ARP_entry
190
        dec     ecx
191
        jnz     .loop
1258 hidnplayr 192
 
2311 hidnplayr 193
        jmp     .exit
1159 hidnplayr 194
 
1529 hidnplayr 195
  .gotit:
2891 hidnplayr 196
        DEBUGF  1,"ARP_input: found matching entry\n"
1159 hidnplayr 197
 
2311 hidnplayr 198
        cmp     [esi + ARP_entry.TTL], ARP_STATIC_ENTRY         ; if it is a static entry, dont touch it
199
        je      .exit
1159 hidnplayr 200
 
2891 hidnplayr 201
        DEBUGF  1,"ARP_input: updating entry\n"
1159 hidnplayr 202
 
2311 hidnplayr 203
        mov     [esi + ARP_entry.Status], ARP_VALID_MAPPING
204
        mov     [esi + ARP_entry.TTL], ARP_ENTRY_TTL
1529 hidnplayr 205
 
2311 hidnplayr 206
        mov     eax, dword [edx + ARP_header.SenderMAC]
2891 hidnplayr 207
        mov     dword [esi + ARP_entry.MAC], eax
2629 hidnplayr 208
        mov     cx, word [edx + ARP_header.SenderMAC + 4]
2891 hidnplayr 209
        mov     word [esi + ARP_entry.MAC + 4], cx
1529 hidnplayr 210
 
2311 hidnplayr 211
        jmp     .exit
1529 hidnplayr 212
 
213
 
214
;-----------------------
215
; Handle Request packets
216
 
217
  .maybe_request:
2311 hidnplayr 218
        cmp     [edx + ARP_header.Opcode], ARP_REQ_OPCODE
219
        jne     .exit
1529 hidnplayr 220
 
2311 hidnplayr 221
        call    NET_ptr_to_num
222
        cmp     edi, -1
223
        jz      .exit
2891 hidnplayr 224
        DEBUGF  1,"ARP_input: got request packet through device: %u\n", edi
225
        inc     [ARP_PACKETS_RX + 4*edi]
1159 hidnplayr 226
 
2891 hidnplayr 227
        mov     eax, [IP_LIST + 4*edi]
2311 hidnplayr 228
        cmp     eax, [edx + ARP_header.TargetIP]                ; Is it looking for my IP address?
2629 hidnplayr 229
        jne     .exit
1159 hidnplayr 230
 
2311 hidnplayr 231
        push    eax
232
        push    edi
1206 hidnplayr 233
 
1529 hidnplayr 234
; OK, it is a request for one of our MAC addresses.
235
; Build the frame and send it. We can reuse the buffer.  (faster then using ARP_create_packet)
236
 
2311 hidnplayr 237
        lea     esi, [edx + ARP_header.SenderMAC]
238
        lea     edi, [edx + ARP_header.TargetMAC]
239
        movsd                                                   ; Move Sender Mac to Dest MAC
240
        movsw                                                   ;
241
        movsd                                                   ; Move sender IP to Dest IP
1529 hidnplayr 242
 
2311 hidnplayr 243
        pop     esi
244
        mov     esi, [NET_DRV_LIST + 4*esi]
245
        lea     esi, [esi + ETH_DEVICE.mac]
246
        lea     edi, [edx + ARP_header.SenderMAC]
247
        movsd                                                   ; Copy MAC address from in MAC_LIST
248
        movsw                                                   ;
249
        pop     eax
250
        stosd                                                   ; Write our IP
1159 hidnplayr 251
 
2311 hidnplayr 252
        mov     [edx + ARP_header.Opcode], ARP_REP_OPCODE
1159 hidnplayr 253
 
1529 hidnplayr 254
; Now, Fill in ETHERNET header
255
 
2311 hidnplayr 256
        mov     edi, [esp]
257
        lea     esi, [edx + ARP_header.TargetMAC]
258
        movsd
259
        movsw
260
        lea     esi, [edx + ARP_header.SenderMAC]
261
        movsd
262
        movsw
2629 hidnplayr 263
;        mov     ax , ETHER_ARP                                 ; It's already there, I'm sure of it!
1529 hidnplayr 264
;        stosw
265
 
2891 hidnplayr 266
        DEBUGF  1,"ARP_input: Sending reply\n"
1529 hidnplayr 267
 
2311 hidnplayr 268
        call    [ebx + NET_DEVICE.transmit]
269
        ret
1159 hidnplayr 270
 
2629 hidnplayr 271
  .exit:
2311 hidnplayr 272
        call    kernel_free
273
        add     esp, 4                                          ; pop (balance stack)
1529 hidnplayr 274
 
2891 hidnplayr 275
        DEBUGF  1,"ARP_input: exiting\n"
2311 hidnplayr 276
        ret
1159 hidnplayr 277
 
278
 
1185 hidnplayr 279
;---------------------------------------------------------------------------
280
;
1529 hidnplayr 281
; ARP_output_request
1185 hidnplayr 282
;
1529 hidnplayr 283
; IN:  ip in eax
2877 hidnplayr 284
;      device in edi
1185 hidnplayr 285
; OUT: /
286
;
287
;---------------------------------------------------------------------------
288
align 4
1529 hidnplayr 289
ARP_output_request:
1185 hidnplayr 290
 
2311 hidnplayr 291
        push    eax                             ; DestIP
2891 hidnplayr 292
        pushd   [IP_LIST + edi]                 ; SenderIP
1185 hidnplayr 293
 
2891 hidnplayr 294
        DEBUGF  1,"ARP_output_request: ip=%u.%u.%u.%u\n",\
295
        [esp]:1, [esp + 1]:1, [esp + 2]:1, [esp + 3]:1
1185 hidnplayr 296
 
2891 hidnplayr 297
        mov     ebx, [NET_DRV_LIST + edi]       ; device ptr
298
 
2311 hidnplayr 299
        lea     eax, [ebx + ETH_DEVICE.mac]     ; local device mac
300
        mov     edx, ETH_BROADCAST              ; broadcast mac
301
        mov     ecx, sizeof.ARP_header
302
        mov     di, ETHER_ARP
303
        call    ETH_output
304
        jz      .exit
1185 hidnplayr 305
 
2311 hidnplayr 306
        mov     ecx, eax
1185 hidnplayr 307
 
2311 hidnplayr 308
        mov     [edi + ARP_header.HardwareType], 0x0100         ; Ethernet
309
        mov     [edi + ARP_header.ProtocolType], 0x0008         ; IP
310
        mov     [edi + ARP_header.HardwareSize], 6              ; MAC-addr length
311
        mov     [edi + ARP_header.ProtocolSize], 4              ; IP-addr length
312
        mov     [edi + ARP_header.Opcode], ARP_REQ_OPCODE       ; Request
1185 hidnplayr 313
 
2311 hidnplayr 314
        add     edi, ARP_header.SenderMAC
1185 hidnplayr 315
 
2311 hidnplayr 316
        lea     esi, [ebx + ETH_DEVICE.mac]     ; SenderMac
317
        movsw                                   ;
318
        movsd                                   ;
319
        pop     eax                             ; SenderIP
320
        stosd                                   ;
1185 hidnplayr 321
 
2311 hidnplayr 322
        mov     eax, -1                         ; DestMac
323
        stosd                                   ;
324
        stosw                                   ;
325
        pop     eax                             ; DestIP
326
        stosd                                   ;
1185 hidnplayr 327
 
2891 hidnplayr 328
        DEBUGF  1,"ARP_output_request: device=%x\n", ebx
1185 hidnplayr 329
 
2311 hidnplayr 330
        push    edx ecx
331
        call    [ebx + NET_DEVICE.transmit]
332
        ret
1185 hidnplayr 333
 
1529 hidnplayr 334
  .exit:
2891 hidnplayr 335
        add     esp, 4 + 4
336
        DEBUGF  1,"ARP_output_request: failed\n"
2311 hidnplayr 337
        sub     eax, eax
338
        ret
1185 hidnplayr 339
 
340
 
1257 hidnplayr 341
;-----------------------------------------------------------------
1196 hidnplayr 342
;
343
; ARP_add_entry (or update)
344
;
1529 hidnplayr 345
; IN:  esi = ptr to entry (can easily be made on the stack)
1196 hidnplayr 346
; OUT: eax = entry #, -1 on error
347
;
1257 hidnplayr 348
;-----------------------------------------------------------------   ; TODO: use a mutex
1196 hidnplayr 349
align 4
350
ARP_add_entry:
351
 
2891 hidnplayr 352
        DEBUGF  1,"ARP_add_entry: "
1206 hidnplayr 353
 
2311 hidnplayr 354
        mov     ecx, [NumARP]
355
        test    ecx, ecx                ; first entry?
356
        jz      .add
357
        cmp     ecx, ARP_TABLE_SIZE     ; list full ?
358
        jae     .error
1196 hidnplayr 359
 
2311 hidnplayr 360
        mov     eax, dword [esi + ARP_entry.MAC]
361
        mov     bx , word [esi + ARP_entry.MAC + 4]
362
        mov     edi, ARP_table
1196 hidnplayr 363
 
1529 hidnplayr 364
  .loop:
2311 hidnplayr 365
        cmp     dword [edi + ARP_entry.MAC], eax        ; Check for duplicate MAC's
366
        jne     .maybe_next                             ;
367
        cmp     word [edi + ARP_entry.MAC + 4], bx      ;
368
        jne     .maybe_next                             ;
1196 hidnplayr 369
 
2311 hidnplayr 370
        cmp     [edi + ARP_entry.TTL], ARP_STATIC_ENTRY
371
        jne     .notstatic
372
        cmp     [esi + ARP_entry.TTL], ARP_STATIC_ENTRY
373
        jne     .error
1529 hidnplayr 374
  .notstatic:
1196 hidnplayr 375
 
2311 hidnplayr 376
        neg     ecx
377
        add     ecx, [NumARP]
378
        jmp     .add
1196 hidnplayr 379
 
1529 hidnplayr 380
  .maybe_next:
2311 hidnplayr 381
        add     esi, sizeof.ARP_entry
382
        loop    .loop
1196 hidnplayr 383
 
2311 hidnplayr 384
        mov     ecx, [NumARP]
1529 hidnplayr 385
  .add:
2311 hidnplayr 386
        push    ecx
387
        imul    ecx, sizeof.ARP_entry
388
        lea     edi, [ecx + ARP_table]
389
        mov     ecx, sizeof.ARP_entry/2
390
        rep     movsw
1196 hidnplayr 391
 
2311 hidnplayr 392
        lea     esi, [edi - sizeof.ARP_entry]
393
        inc     [NumARP]
394
        pop     eax
2891 hidnplayr 395
        DEBUGF  1,"entry=%u\n", eax
1529 hidnplayr 396
 
2311 hidnplayr 397
        ret
1196 hidnplayr 398
 
1529 hidnplayr 399
  .error:
2891 hidnplayr 400
        DEBUGF  1,"failed\n"
2311 hidnplayr 401
        mov     eax, -1
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
 
2891 hidnplayr 416
        DEBUGF 1,"ARP_del_entry: entry=%u entrys=%u\n", esi, [NumARP]
1206 hidnplayr 417
 
2311 hidnplayr 418
        mov     ecx, ARP_table + (ARP_TABLE_SIZE - 1) * sizeof.ARP_entry
419
        sub     ecx, esi
420
        shr     ecx, 1
1185 hidnplayr 421
 
2311 hidnplayr 422
        mov     edi, esi
423
        lea     esi, [edi + sizeof.ARP_entry]
424
        rep     movsw
1185 hidnplayr 425
 
2311 hidnplayr 426
        dec     [NumARP]
2891 hidnplayr 427
        DEBUGF 1,"ARP_del_entry: success\n"
1529 hidnplayr 428
 
2311 hidnplayr 429
        ret
1185 hidnplayr 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
2877 hidnplayr 442
;       edi = device number
1529 hidnplayr 443
;  OUT: eax = -1 on error, -2 means request send
444
;      else, ax = first two bytes of mac (high 16 bits of eax will be 0)
445
;       ebx = last four bytes of mac
2877 hidnplayr 446
;       edi = unchanged
1159 hidnplayr 447
;
1257 hidnplayr 448
;-----------------------------------------------------------------
1159 hidnplayr 449
align 4
1529 hidnplayr 450
ARP_IP_to_MAC:
1159 hidnplayr 451
 
2555 hidnplayr 452
        DEBUGF 1,"ARP_IP_to_MAC: %u.%u", al, ah
453
        rol     eax, 16
454
        DEBUGF 1,".%u.%u\n", al, ah
455
        rol     eax, 16
1159 hidnplayr 456
 
2311 hidnplayr 457
        cmp     eax, 0xffffffff
458
        je      .broadcast
1159 hidnplayr 459
 
1529 hidnplayr 460
;--------------------------------
461
; Try to find the IP in ARP_table
1206 hidnplayr 462
 
2311 hidnplayr 463
        mov     ecx, [NumARP]
464
        test    ecx, ecx
465
        jz      .not_in_list
466
        mov     esi, ARP_table + ARP_entry.IP
1529 hidnplayr 467
  .scan_loop:
2311 hidnplayr 468
        cmp     [esi], eax
469
        je      .found_it
470
        add     esi, sizeof.ARP_entry
471
        loop    .scan_loop
1206 hidnplayr 472
 
1529 hidnplayr 473
  .not_in_list:
2888 hidnplayr 474
        DEBUGF 1,"ARP_IP_to_MAC: preparing for ARP request\n"
1196 hidnplayr 475
 
1529 hidnplayr 476
;--------------------
477
; Send an ARP request
1196 hidnplayr 478
 
2877 hidnplayr 479
        push    eax edi                    ; save IP for ARP_output_request
1159 hidnplayr 480
 
2629 hidnplayr 481
; Now create the ARP entry
482
        pushw   ARP_REQUEST_TTL         ; TTL
483
        pushw   ARP_AWAITING_RESPONSE   ; status
484
        pushd   0                       ; mac
2311 hidnplayr 485
        pushw   0
2629 hidnplayr 486
        pushd   eax                     ; ip
2311 hidnplayr 487
        mov     esi, esp
488
        call    ARP_add_entry
489
        add     esp, sizeof.ARP_entry
1159 hidnplayr 490
 
2311 hidnplayr 491
        cmp     eax, -1
492
        je      .full
1159 hidnplayr 493
 
2629 hidnplayr 494
; And send a request
2877 hidnplayr 495
        pop     edi eax
2629 hidnplayr 496
        call    ARP_output_request      ; IP in eax
1530 hidnplayr 497
;; TODO: check if driver could transmit packet
498
 
2629 hidnplayr 499
        mov     eax, -2                 ; request send
2311 hidnplayr 500
        ret
1159 hidnplayr 501
 
1529 hidnplayr 502
  .found_it:
2888 hidnplayr 503
        DEBUGF  1,"ARP_IP_to_MAC: found IP\n"
2629 hidnplayr 504
        cmp     [esi + ARP_entry.Status], ARP_VALID_MAPPING
2311 hidnplayr 505
        jne     .invalid
1159 hidnplayr 506
 
2311 hidnplayr 507
        movzx   eax, word [esi + ARP_entry.MAC]
2877 hidnplayr 508
        mov     ebx, dword[esi + ARP_entry.MAC + 2]
2311 hidnplayr 509
        ret
1206 hidnplayr 510
 
1529 hidnplayr 511
  .invalid:
2888 hidnplayr 512
        DEBUGF  1,"ARP_IP_to_MAC: entry has no valid mapping!\n"
2311 hidnplayr 513
        mov     eax, -1
514
        ret
1159 hidnplayr 515
 
1529 hidnplayr 516
  .full:
2888 hidnplayr 517
        DEBUGF  1,"ARP_IP_to_MAC: table is full!\n"
2877 hidnplayr 518
        add     esp, 8
2311 hidnplayr 519
        mov     eax, -1
520
        ret
1159 hidnplayr 521
 
1529 hidnplayr 522
  .broadcast:
2311 hidnplayr 523
        mov     eax, 0x0000ffff
524
        mov     ebx, 0xffffffff
525
        ret
1159 hidnplayr 526
 
527
 
1257 hidnplayr 528
;-----------------------------------------------------------------
1159 hidnplayr 529
;
530
; ARP_API
531
;
532
; This function is called by system function 75
533
;
534
; IN:  subfunction number in bl
535
;      device number in bh
536
;      ecx, edx, .. depends on subfunction
537
;
1257 hidnplayr 538
; OUT:  ?
1159 hidnplayr 539
;
1257 hidnplayr 540
;-----------------------------------------------------------------
1159 hidnplayr 541
align 4
2614 hidnplayr 542
ARP_api:
1159 hidnplayr 543
 
2311 hidnplayr 544
        movzx   eax, bh
545
        shl     eax, 2
1159 hidnplayr 546
 
2614 hidnplayr 547
        and     ebx, 0xff
548
        cmp     ebx, .number
549
        ja      .error
550
        jmp     dword [.table + 4*ebx]
1159 hidnplayr 551
 
2614 hidnplayr 552
  .table:
553
        dd      .packets_tx     ; 0
554
        dd      .packets_rx     ; 1
555
        dd      .entries        ; 2
556
        dd      .read           ; 3
557
        dd      .write          ; 4
558
        dd      .remove         ; 5
559
  .number = ($ - .table) / 4 - 1
560
 
561
  .error:
2311 hidnplayr 562
        mov     eax, -1
563
        ret
1159 hidnplayr 564
 
2614 hidnplayr 565
  .packets_tx:
566
        mov     eax, [ARP_PACKETS_TX + eax]
2311 hidnplayr 567
        ret
1159 hidnplayr 568
 
2614 hidnplayr 569
  .packets_rx:
570
        mov     eax, [ARP_PACKETS_RX + eax]
2311 hidnplayr 571
        ret
1159 hidnplayr 572
 
2614 hidnplayr 573
  .entries:
2311 hidnplayr 574
        mov     eax, [NumARP]
575
        ret
1159 hidnplayr 576
 
2614 hidnplayr 577
  .read:
2311 hidnplayr 578
        cmp     ecx, [NumARP]
579
        jae     .error
580
        ; edi = pointer to buffer
581
        ; ecx = # entry
582
        imul    ecx, sizeof.ARP_entry
583
        add     ecx, ARP_table
584
        mov     esi, ecx
585
        mov     ecx, sizeof.ARP_entry/2
586
        rep     movsw
1200 hidnplayr 587
 
2311 hidnplayr 588
        xor     eax, eax
589
        ret
1159 hidnplayr 590
 
2614 hidnplayr 591
  .write:
2311 hidnplayr 592
        ; esi = pointer to buffer
593
        call    ARP_add_entry        ;out: eax = entry number, -1 on error
594
        ret
1159 hidnplayr 595
 
2614 hidnplayr 596
  .remove:
2311 hidnplayr 597
        ; ecx = # entry
598
        cmp     ecx, [NumARP]
599
        jae     .error
600
        imul    ecx, sizeof.ARP_entry
601
        lea     esi, [ARP_table + ecx]
602
        call    ARP_del_entry
603
        ret
1159 hidnplayr 604