Subversion Repositories Kolibri OS

Rev

Rev 2924 | 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: 3147 $
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
1529 hidnplayr 185
  .loop:
2311 hidnplayr 186
        cmp     [esi + ARP_entry.IP], eax
187
        je      .gotit
188
        add     esi, sizeof.ARP_entry
189
        dec     ecx
190
        jnz     .loop
1258 hidnplayr 191
 
3147 hidnplayr 192
        DEBUGF  1,"ARP_input: no matching entry found\n"
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
        cmp     ecx, ARP_TABLE_SIZE     ; list full ?
356
        jae     .error
1196 hidnplayr 357
 
2311 hidnplayr 358
        mov     eax, dword [esi + ARP_entry.MAC]
3147 hidnplayr 359
        mov     bx, word [esi + ARP_entry.MAC + 4]
360
 
361
        xor     ecx, ecx
2311 hidnplayr 362
        mov     edi, ARP_table
1529 hidnplayr 363
  .loop:
2311 hidnplayr 364
        cmp     dword [edi + ARP_entry.MAC], eax        ; Check for duplicate MAC's
365
        jne     .maybe_next                             ;
366
        cmp     word [edi + ARP_entry.MAC + 4], bx      ;
367
        jne     .maybe_next                             ;
1196 hidnplayr 368
 
2311 hidnplayr 369
        cmp     [edi + ARP_entry.TTL], ARP_STATIC_ENTRY
3147 hidnplayr 370
        jne     .add
2311 hidnplayr 371
        cmp     [esi + ARP_entry.TTL], ARP_STATIC_ENTRY
372
        jne     .error
1196 hidnplayr 373
 
1529 hidnplayr 374
  .maybe_next:
3147 hidnplayr 375
        add     edi, sizeof.ARP_entry
376
        inc     ecx
377
        cmp     ecx, ARP_TABLE_SIZE
378
        jae     .error
379
        jmp     .loop
1196 hidnplayr 380
 
1529 hidnplayr 381
  .add:
3147 hidnplayr 382
        mov     eax, ecx
383
 
2311 hidnplayr 384
        mov     ecx, sizeof.ARP_entry/2
385
        rep     movsw
386
        inc     [NumARP]
2891 hidnplayr 387
        DEBUGF  1,"entry=%u\n", eax
1529 hidnplayr 388
 
2311 hidnplayr 389
        ret
1196 hidnplayr 390
 
1529 hidnplayr 391
  .error:
2891 hidnplayr 392
        DEBUGF  1,"failed\n"
2311 hidnplayr 393
        mov     eax, -1
394
        ret
1196 hidnplayr 395
 
396
 
1257 hidnplayr 397
;-----------------------------------------------------------------
1185 hidnplayr 398
;
399
; ARP_del_entry
400
;
1529 hidnplayr 401
; IN:  esi = ptr to arp entry
1185 hidnplayr 402
; OUT: /
403
;
1257 hidnplayr 404
;-----------------------------------------------------------------
1185 hidnplayr 405
align 4
406
ARP_del_entry:
407
 
2891 hidnplayr 408
        DEBUGF 1,"ARP_del_entry: entry=%u entrys=%u\n", esi, [NumARP]
1206 hidnplayr 409
 
2311 hidnplayr 410
        mov     ecx, ARP_table + (ARP_TABLE_SIZE - 1) * sizeof.ARP_entry
411
        sub     ecx, esi
412
        shr     ecx, 1
1185 hidnplayr 413
 
2311 hidnplayr 414
        mov     edi, esi
415
        lea     esi, [edi + sizeof.ARP_entry]
416
        rep     movsw
1185 hidnplayr 417
 
2311 hidnplayr 418
        dec     [NumARP]
2891 hidnplayr 419
        DEBUGF 1,"ARP_del_entry: success\n"
1529 hidnplayr 420
 
2311 hidnplayr 421
        ret
1185 hidnplayr 422
 
423
 
424
 
425
 
1529 hidnplayr 426
 
1257 hidnplayr 427
;-----------------------------------------------------------------
1159 hidnplayr 428
;
1529 hidnplayr 429
; ARP_IP_to_MAC
1159 hidnplayr 430
;
1529 hidnplayr 431
;  This function translates an IP address to a MAC address
1159 hidnplayr 432
;
1529 hidnplayr 433
;  IN:  eax = IPv4 address
2877 hidnplayr 434
;       edi = device number
1529 hidnplayr 435
;  OUT: eax = -1 on error, -2 means request send
436
;      else, ax = first two bytes of mac (high 16 bits of eax will be 0)
437
;       ebx = last four bytes of mac
2877 hidnplayr 438
;       edi = unchanged
1159 hidnplayr 439
;
1257 hidnplayr 440
;-----------------------------------------------------------------
1159 hidnplayr 441
align 4
1529 hidnplayr 442
ARP_IP_to_MAC:
1159 hidnplayr 443
 
2555 hidnplayr 444
        DEBUGF 1,"ARP_IP_to_MAC: %u.%u", al, ah
445
        rol     eax, 16
446
        DEBUGF 1,".%u.%u\n", al, ah
447
        rol     eax, 16
1159 hidnplayr 448
 
2311 hidnplayr 449
        cmp     eax, 0xffffffff
450
        je      .broadcast
1159 hidnplayr 451
 
1529 hidnplayr 452
;--------------------------------
453
; Try to find the IP in ARP_table
1206 hidnplayr 454
 
2311 hidnplayr 455
        mov     ecx, [NumARP]
456
        test    ecx, ecx
457
        jz      .not_in_list
458
        mov     esi, ARP_table + ARP_entry.IP
1529 hidnplayr 459
  .scan_loop:
2311 hidnplayr 460
        cmp     [esi], eax
461
        je      .found_it
462
        add     esi, sizeof.ARP_entry
463
        loop    .scan_loop
1206 hidnplayr 464
 
1529 hidnplayr 465
  .not_in_list:
2888 hidnplayr 466
        DEBUGF 1,"ARP_IP_to_MAC: preparing for ARP request\n"
1196 hidnplayr 467
 
1529 hidnplayr 468
;--------------------
469
; Send an ARP request
1196 hidnplayr 470
 
2877 hidnplayr 471
        push    eax edi                    ; save IP for ARP_output_request
1159 hidnplayr 472
 
2629 hidnplayr 473
; Now create the ARP entry
474
        pushw   ARP_REQUEST_TTL         ; TTL
475
        pushw   ARP_AWAITING_RESPONSE   ; status
476
        pushd   0                       ; mac
2311 hidnplayr 477
        pushw   0
2629 hidnplayr 478
        pushd   eax                     ; ip
2311 hidnplayr 479
        mov     esi, esp
480
        call    ARP_add_entry
481
        add     esp, sizeof.ARP_entry
1159 hidnplayr 482
 
2311 hidnplayr 483
        cmp     eax, -1
484
        je      .full
1159 hidnplayr 485
 
2629 hidnplayr 486
; And send a request
2877 hidnplayr 487
        pop     edi eax
2629 hidnplayr 488
        call    ARP_output_request      ; IP in eax
1530 hidnplayr 489
;; TODO: check if driver could transmit packet
490
 
2629 hidnplayr 491
        mov     eax, -2                 ; request send
2311 hidnplayr 492
        ret
1159 hidnplayr 493
 
1529 hidnplayr 494
  .found_it:
2888 hidnplayr 495
        DEBUGF  1,"ARP_IP_to_MAC: found IP\n"
2629 hidnplayr 496
        cmp     [esi + ARP_entry.Status], ARP_VALID_MAPPING
2311 hidnplayr 497
        jne     .invalid
1159 hidnplayr 498
 
2311 hidnplayr 499
        movzx   eax, word [esi + ARP_entry.MAC]
2877 hidnplayr 500
        mov     ebx, dword[esi + ARP_entry.MAC + 2]
2311 hidnplayr 501
        ret
1206 hidnplayr 502
 
1529 hidnplayr 503
  .invalid:
2888 hidnplayr 504
        DEBUGF  1,"ARP_IP_to_MAC: entry has no valid mapping!\n"
2311 hidnplayr 505
        mov     eax, -1
506
        ret
1159 hidnplayr 507
 
1529 hidnplayr 508
  .full:
2888 hidnplayr 509
        DEBUGF  1,"ARP_IP_to_MAC: table is full!\n"
2877 hidnplayr 510
        add     esp, 8
2311 hidnplayr 511
        mov     eax, -1
512
        ret
1159 hidnplayr 513
 
1529 hidnplayr 514
  .broadcast:
2311 hidnplayr 515
        mov     eax, 0x0000ffff
516
        mov     ebx, 0xffffffff
517
        ret
1159 hidnplayr 518
 
519
 
1257 hidnplayr 520
;-----------------------------------------------------------------
1159 hidnplayr 521
;
522
; ARP_API
523
;
524
; This function is called by system function 75
525
;
526
; IN:  subfunction number in bl
527
;      device number in bh
528
;      ecx, edx, .. depends on subfunction
529
;
1257 hidnplayr 530
; OUT:  ?
1159 hidnplayr 531
;
1257 hidnplayr 532
;-----------------------------------------------------------------
1159 hidnplayr 533
align 4
2614 hidnplayr 534
ARP_api:
1159 hidnplayr 535
 
2311 hidnplayr 536
        movzx   eax, bh
537
        shl     eax, 2
1159 hidnplayr 538
 
2614 hidnplayr 539
        and     ebx, 0xff
540
        cmp     ebx, .number
541
        ja      .error
542
        jmp     dword [.table + 4*ebx]
1159 hidnplayr 543
 
2614 hidnplayr 544
  .table:
545
        dd      .packets_tx     ; 0
546
        dd      .packets_rx     ; 1
547
        dd      .entries        ; 2
548
        dd      .read           ; 3
549
        dd      .write          ; 4
550
        dd      .remove         ; 5
551
  .number = ($ - .table) / 4 - 1
552
 
553
  .error:
2311 hidnplayr 554
        mov     eax, -1
555
        ret
1159 hidnplayr 556
 
2614 hidnplayr 557
  .packets_tx:
558
        mov     eax, [ARP_PACKETS_TX + eax]
2311 hidnplayr 559
        ret
1159 hidnplayr 560
 
2614 hidnplayr 561
  .packets_rx:
562
        mov     eax, [ARP_PACKETS_RX + eax]
2311 hidnplayr 563
        ret
1159 hidnplayr 564
 
2614 hidnplayr 565
  .entries:
2311 hidnplayr 566
        mov     eax, [NumARP]
567
        ret
1159 hidnplayr 568
 
2614 hidnplayr 569
  .read:
2311 hidnplayr 570
        cmp     ecx, [NumARP]
571
        jae     .error
572
        ; edi = pointer to buffer
573
        ; ecx = # entry
574
        imul    ecx, sizeof.ARP_entry
575
        add     ecx, ARP_table
576
        mov     esi, ecx
577
        mov     ecx, sizeof.ARP_entry/2
578
        rep     movsw
1200 hidnplayr 579
 
2311 hidnplayr 580
        xor     eax, eax
581
        ret
1159 hidnplayr 582
 
2614 hidnplayr 583
  .write:
2311 hidnplayr 584
        ; esi = pointer to buffer
585
        call    ARP_add_entry        ;out: eax = entry number, -1 on error
586
        ret
1159 hidnplayr 587
 
2614 hidnplayr 588
  .remove:
2311 hidnplayr 589
        ; ecx = # entry
590
        cmp     ecx, [NumARP]
591
        jae     .error
592
        imul    ecx, sizeof.ARP_entry
593
        lea     esi, [ARP_table + ecx]
594
        call    ARP_del_entry
595
        ret
1159 hidnplayr 596