1 /* 2 * Copyright 2006, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 */ 8 9 //! Ethernet Address Resolution Protocol, see RFC 826. 10 11 12 #include <arp_control.h> 13 #include <net_datalink_protocol.h> 14 #include <net_device.h> 15 #include <net_datalink.h> 16 #include <net_stack.h> 17 #include <NetBufferUtilities.h> 18 19 #include <generic_syscall.h> 20 #include <util/AutoLock.h> 21 #include <util/khash.h> 22 23 #include <ByteOrder.h> 24 #include <KernelExport.h> 25 26 #include <net/if.h> 27 #include <net/if_dl.h> 28 #include <net/if_types.h> 29 #include <new> 30 #include <stdio.h> 31 #include <string.h> 32 #include <sys/sockio.h> 33 34 35 #define TRACE_ARP 36 #ifdef TRACE_ARP 37 # define TRACE(x) dprintf x 38 #else 39 # define TRACE(x) ; 40 #endif 41 42 43 struct arp_header { 44 uint16 hardware_type; 45 uint16 protocol_type; 46 uint8 hardware_length; 47 uint8 protocol_length; 48 uint16 opcode; 49 50 // TODO: this should be a variable length header, but for our current 51 // usage (Ethernet/IPv4), this should work fine. 52 uint8 hardware_sender[6]; 53 in_addr_t protocol_sender; 54 uint8 hardware_target[6]; 55 in_addr_t protocol_target; 56 } _PACKED; 57 58 #define ARP_OPCODE_REQUEST 1 59 #define ARP_OPCODE_REPLY 2 60 61 #define ARP_HARDWARE_TYPE_ETHER 1 62 63 struct arp_entry { 64 arp_entry *next; 65 in_addr_t protocol_address; 66 sockaddr_dl hardware_address; 67 uint32 flags; 68 sem_id resolved_sem; 69 net_buffer *request_buffer; 70 net_timer timer; 71 uint32 timer_state; 72 bigtime_t timestamp; 73 net_datalink_protocol *protocol; 74 75 static int Compare(void *_entry, const void *_key); 76 static uint32 Hash(void *_entry, const void *_key, uint32 range); 77 static arp_entry *Lookup(in_addr_t protocolAddress); 78 static arp_entry *Add(in_addr_t protocolAddress, sockaddr_dl *hardwareAddress, 79 uint32 flags); 80 }; 81 82 // see arp_control.h for flags 83 84 #define ARP_NO_STATE 0 85 #define ARP_STATE_REQUEST 1 86 #define ARP_STATE_LAST_REQUEST 5 87 #define ARP_STATE_REQUEST_FAILED 6 88 #define ARP_STATE_REMOVE_FAILED 7 89 #define ARP_STATE_STALE 8 90 91 #define ARP_STALE_TIMEOUT 30 * 60000000LL // 30 minutes 92 #define ARP_REJECT_TIMEOUT 20000000LL // 20 seconds 93 #define ARP_REQUEST_TIMEOUT 1000000LL // 1 second 94 95 struct arp_protocol : net_datalink_protocol { 96 }; 97 98 99 static void arp_timer(struct net_timer *timer, void *data); 100 101 struct net_buffer_module_info *gBufferModule; 102 static net_stack_module_info *sStackModule; 103 static hash_table *sCache; 104 static benaphore sCacheLock; 105 static bool sIgnoreReplies; 106 107 108 /*static*/ int 109 arp_entry::Compare(void *_entry, const void *_key) 110 { 111 arp_entry *entry = (arp_entry *)_entry; 112 in_addr_t key = (in_addr_t)_key; 113 114 if (entry->protocol_address == key) 115 return 0; 116 117 return 1; 118 } 119 120 121 /*static*/ uint32 122 arp_entry::Hash(void *_entry, const void *_key, uint32 range) 123 { 124 arp_entry *entry = (arp_entry *)_entry; 125 in_addr_t key = (in_addr_t)_key; 126 127 // TODO: check if this makes a good hash... 128 #define HASH(o) (((o >> 24) ^ (o >> 16) ^ (o >> 8) ^ o) % range) 129 130 #ifdef TRACE_ARP 131 in_addr_t a = entry ? entry->protocol_address : key; 132 dprintf("%ld.%ld.%ld.%ld: Hash: %lu\n", a >> 24, (a >> 16) & 0xff, 133 (a >> 8) & 0xff, a & 0xff, HASH(a)); 134 #endif 135 136 if (entry != NULL) 137 return HASH(entry->protocol_address); 138 139 return HASH(key); 140 #undef HASH 141 } 142 143 144 /*static*/ arp_entry * 145 arp_entry::Lookup(in_addr_t address) 146 { 147 return (arp_entry *)hash_lookup(sCache, (void *)address); 148 } 149 150 151 /*static*/ arp_entry * 152 arp_entry::Add(in_addr_t protocolAddress, sockaddr_dl *hardwareAddress, 153 uint32 flags) 154 { 155 arp_entry *entry = new (std::nothrow) arp_entry; 156 if (entry == NULL) 157 return NULL; 158 159 entry->protocol_address = protocolAddress; 160 entry->flags = flags; 161 entry->timestamp = system_time(); 162 entry->protocol = NULL; 163 entry->request_buffer = NULL; 164 entry->timer_state = ARP_NO_STATE; 165 sStackModule->init_timer(&entry->timer, arp_timer, entry); 166 167 if (hardwareAddress != NULL) { 168 // this entry is already resolved 169 entry->hardware_address = *hardwareAddress; 170 entry->hardware_address.sdl_e_type = ETHER_TYPE_IP; 171 entry->resolved_sem = -1; 172 } else { 173 // this entry still needs to be resolved 174 entry->hardware_address.sdl_alen = 0; 175 176 char name[32]; 177 snprintf(name, sizeof(name), "arp %08lx", protocolAddress); 178 entry->resolved_sem = create_sem(0, name); 179 if (entry->resolved_sem < B_OK) { 180 delete entry; 181 return NULL; 182 } 183 } 184 if (entry->hardware_address.sdl_len != sizeof(sockaddr_dl)) { 185 // explicitly set correct length in case our caller hasn't... 186 entry->hardware_address.sdl_len = sizeof(sockaddr_dl); 187 } 188 189 if (hash_insert(sCache, entry) != B_OK) { 190 delete entry; 191 return NULL; 192 } 193 194 return entry; 195 } 196 197 198 // #pragma mark - 199 200 201 /*! 202 Updates the entry determined by \a protocolAddress with the specified 203 \a hardwareAddress. 204 If such an entry does not exist yet, a new entry is added. If you try 205 to update a local existing entry but didn't ask for it (by setting 206 \a flags to ARP_FLAG_LOCAL), an error is returned. 207 208 This function does not lock the cache - you have to do it yourself 209 before calling it. 210 */ 211 status_t 212 arp_update_entry(in_addr_t protocolAddress, sockaddr_dl *hardwareAddress, 213 uint32 flags, arp_entry **_entry = NULL) 214 { 215 arp_entry *entry = arp_entry::Lookup(protocolAddress); 216 if (entry != NULL) { 217 // We disallow updating of entries that had been resolved before, 218 // but to a different address. 219 // Right now, you have to manually purge the ARP entries (or wait some 220 // time) to let us switch to the new address. 221 if (entry->hardware_address.sdl_alen != 0 222 && memcmp(LLADDR(&entry->hardware_address), hardwareAddress, ETHER_ADDRESS_LENGTH)) { 223 dprintf("ARP host %08lx updated with different hardware address %02x:%02x:%02x:%02x:%02x:%02x.\n", 224 protocolAddress, hardwareAddress->sdl_data[0] & 0xff, hardwareAddress->sdl_data[1] & 0xff, 225 hardwareAddress->sdl_data[2] & 0xff, hardwareAddress->sdl_data[3] & 0xff, 226 hardwareAddress->sdl_data[4] & 0xff, hardwareAddress->sdl_data[5] & 0xff); 227 return B_ERROR; 228 } 229 230 entry->hardware_address = *hardwareAddress; 231 entry->timestamp = system_time(); 232 } else { 233 entry = arp_entry::Add(protocolAddress, hardwareAddress, flags); 234 if (entry == NULL) 235 return B_NO_MEMORY; 236 } 237 238 // if someone was waiting for this ARP request to be resolved 239 if (entry->resolved_sem >= B_OK) { 240 delete_sem(entry->resolved_sem); 241 entry->resolved_sem = -1; 242 } 243 244 if (entry->request_buffer != NULL) { 245 gBufferModule->free(entry->request_buffer); 246 entry->request_buffer = NULL; 247 } 248 249 if ((entry->flags & ARP_FLAG_PERMANENT) == 0) { 250 // (re)start the stale timer 251 entry->timer_state = ARP_STATE_STALE; 252 sStackModule->set_timer(&entry->timer, ARP_STALE_TIMEOUT); 253 } 254 255 if (_entry) 256 *_entry = entry; 257 258 return B_OK; 259 } 260 261 262 static status_t 263 arp_update_local(net_datalink_protocol *protocol) 264 { 265 net_interface *interface = protocol->interface; 266 267 if (interface->address == NULL) { 268 // interface has not yet been set 269 return B_OK; 270 } 271 272 sockaddr_dl address; 273 address.sdl_len = sizeof(sockaddr_dl); 274 address.sdl_family = AF_DLI; 275 address.sdl_type = IFT_ETHER; 276 address.sdl_e_type = ETHER_TYPE_IP; 277 address.sdl_nlen = 0; 278 address.sdl_slen = 0; 279 address.sdl_alen = interface->device->address.length; 280 memcpy(LLADDR(&address), interface->device->address.data, address.sdl_alen); 281 282 arp_entry *entry; 283 status_t status = arp_update_entry(((sockaddr_in *)interface->address)->sin_addr.s_addr, 284 &address, ARP_FLAG_LOCAL | ARP_FLAG_PERMANENT, &entry); 285 if (status == B_OK) 286 entry->protocol = protocol; 287 288 return status; 289 } 290 291 292 static status_t 293 handle_arp_request(net_buffer *buffer, arp_header &header) 294 { 295 BenaphoreLocker locker(sCacheLock); 296 297 if (!sIgnoreReplies) { 298 arp_update_entry(header.protocol_sender, (sockaddr_dl *)&buffer->source, 0); 299 // remember the address of the sender as we might need it later 300 } 301 302 // check if this request is for us 303 304 arp_entry *entry = arp_entry::Lookup(header.protocol_target); 305 if (entry == NULL || (entry->flags & (ARP_FLAG_LOCAL | ARP_FLAG_PUBLISH)) == 0) { 306 // We're not the one to answer this request 307 // TODO: instead of letting the other's request time-out, can we reply 308 // failure somehow? 309 TRACE((" not for us\n")); 310 return B_ERROR; 311 } 312 313 // send a reply (by reusing the buffer we got) 314 315 TRACE((" send reply!\n")); 316 header.opcode = htons(ARP_OPCODE_REPLY); 317 318 memcpy(header.hardware_target, header.hardware_sender, ETHER_ADDRESS_LENGTH); 319 header.protocol_target = header.protocol_sender; 320 memcpy(header.hardware_sender, LLADDR(&entry->hardware_address), ETHER_ADDRESS_LENGTH); 321 header.protocol_sender = entry->protocol_address; 322 323 // exchange source and destination address 324 memcpy(LLADDR((sockaddr_dl *)&buffer->source), header.hardware_sender, 325 ETHER_ADDRESS_LENGTH); 326 memcpy(LLADDR((sockaddr_dl *)&buffer->destination), header.hardware_target, 327 ETHER_ADDRESS_LENGTH); 328 329 buffer->flags = 0; 330 // make sure this won't be a broadcast message 331 332 return entry->protocol->next->module->send_data(entry->protocol->next, buffer); 333 } 334 335 336 static void 337 handle_arp_reply(net_buffer *buffer, arp_header &header) 338 { 339 if (sIgnoreReplies) 340 return; 341 342 BenaphoreLocker locker(sCacheLock); 343 arp_update_entry(header.protocol_sender, (sockaddr_dl *)&buffer->source, 0); 344 } 345 346 347 static status_t 348 arp_receive(void *cookie, net_buffer *buffer) 349 { 350 TRACE(("ARP receive\n")); 351 352 NetBufferHeader<arp_header> bufferHeader(buffer); 353 if (bufferHeader.Status() < B_OK) 354 return bufferHeader.Status(); 355 356 arp_header &header = bufferHeader.Data(); 357 uint16 opcode = ntohs(header.opcode); 358 359 #ifdef TRACE_ARP 360 dprintf(" hw sender: %02x:%02x:%02x:%02x:%02x:%02x\n", 361 header.hardware_sender[0], header.hardware_sender[1], header.hardware_sender[2], 362 header.hardware_sender[3], header.hardware_sender[4], header.hardware_sender[5]); 363 dprintf(" proto sender: %ld.%ld.%ld.%ld\n", header.protocol_sender >> 24, (header.protocol_sender >> 16) & 0xff, 364 (header.protocol_sender >> 8) & 0xff, header.protocol_sender & 0xff); 365 dprintf(" hw target: %02x:%02x:%02x:%02x:%02x:%02x\n", 366 header.hardware_target[0], header.hardware_target[1], header.hardware_target[2], 367 header.hardware_target[3], header.hardware_target[4], header.hardware_target[5]); 368 dprintf(" proto target: %ld.%ld.%ld.%ld\n", header.protocol_target >> 24, (header.protocol_target >> 16) & 0xff, 369 (header.protocol_target >> 8) & 0xff, header.protocol_target & 0xff); 370 #endif 371 372 if (ntohs(header.protocol_type) != ETHER_TYPE_IP 373 || ntohs(header.hardware_type) != ARP_HARDWARE_TYPE_ETHER) 374 return B_BAD_TYPE; 375 376 // check if the packet is okay 377 378 if (header.hardware_length != ETHER_ADDRESS_LENGTH 379 || header.protocol_length != sizeof(in_addr_t)) 380 return B_BAD_DATA; 381 382 bufferHeader.Detach(); 383 384 // handle packet 385 386 switch (opcode) { 387 case ARP_OPCODE_REQUEST: 388 TRACE((" got ARP request\n")); 389 if (handle_arp_request(buffer, header) == B_OK) { 390 // the function will take care of the buffer if everything went well 391 return B_OK; 392 } 393 break; 394 case ARP_OPCODE_REPLY: 395 TRACE((" got ARP reply\n")); 396 handle_arp_reply(buffer, header); 397 break; 398 399 default: 400 dprintf("unknown ARP opcode %d\n", opcode); 401 return B_ERROR; 402 } 403 404 gBufferModule->free(buffer); 405 return B_OK; 406 } 407 408 409 static void 410 arp_timer(struct net_timer *timer, void *data) 411 { 412 arp_entry *entry = (arp_entry *)data; 413 TRACE(("ARP timer %ld, entry %p!\n", entry->timer_state, entry)); 414 415 switch (entry->timer_state) { 416 case ARP_NO_STATE: 417 // who are you kidding? 418 break; 419 420 case ARP_STATE_REQUEST_FAILED: 421 // requesting the ARP entry failed, we keep it around for a while, though, 422 // so that we won't try to request the same address again too soon. 423 TRACE((" requesting ARP entry %p failed!\n", entry)); 424 entry->timer_state = ARP_STATE_REMOVE_FAILED; 425 entry->flags |= ARP_FLAG_REJECT; 426 sStackModule->set_timer(&entry->timer, ARP_REJECT_TIMEOUT); 427 break; 428 429 case ARP_STATE_REMOVE_FAILED: 430 case ARP_STATE_STALE: 431 // the entry has aged so much that we're going to remove it 432 TRACE((" remove ARP entry %p!\n", entry)); 433 434 benaphore_lock(&sCacheLock); 435 hash_remove(sCache, entry); 436 benaphore_unlock(&sCacheLock); 437 438 delete entry; 439 440 break; 441 default: 442 if (entry->timer_state > ARP_STATE_LAST_REQUEST) 443 break; 444 445 TRACE((" send request for ARP entry %p!\n", entry)); 446 net_buffer *request = entry->request_buffer; 447 if (entry->timer_state < ARP_STATE_LAST_REQUEST) { 448 // we'll still need our buffer, so in order to prevent it being 449 // freed by a successful send, we need to clone it 450 request = gBufferModule->clone(request, true); 451 if (request == NULL) { 452 // cloning failed - that means we won't be able to send as 453 // many requests as originally planned 454 request = entry->request_buffer; 455 entry->timer_state = ARP_STATE_LAST_REQUEST; 456 } 457 } 458 459 // we're trying to resolve the address, so keep sending requests 460 status_t status = entry->protocol->next->module->send_data( 461 entry->protocol->next, request); 462 if (status < B_OK) 463 gBufferModule->free(request); 464 465 if (entry->timer_state == ARP_STATE_LAST_REQUEST) { 466 // buffer has been freed on send 467 entry->request_buffer = NULL; 468 } 469 470 entry->timer_state++; 471 sStackModule->set_timer(&entry->timer, ARP_REQUEST_TIMEOUT); 472 } 473 } 474 475 476 /*! 477 Checks if the ARP \a entry has already been resolved. If it wasn't yet, 478 and MSG_DONTWAIT is not set in \a flags, it will wait for the entry to 479 become resolved. 480 You need to have the sCacheLock held when calling this function - but 481 note that the lock may be interrupted (in which case entry is updated). 482 */ 483 static status_t 484 arp_check_resolved(arp_entry **_entry, uint32 flags) 485 { 486 arp_entry *entry = *_entry; 487 488 if ((entry->flags & ARP_FLAG_REJECT) != 0) 489 return EHOSTUNREACH; 490 491 if (entry->resolved_sem < B_OK) 492 return B_OK; 493 494 // we need to wait for this entry to become resolved 495 496 if ((flags & MSG_DONTWAIT) != 0) 497 return B_ERROR; 498 499 // store information we cannot access anymore after having unlocked the cache 500 sem_id waitSem = entry->resolved_sem; 501 in_addr_t address = entry->protocol_address; 502 503 benaphore_unlock(&sCacheLock); 504 505 status_t status = acquire_sem_etc(waitSem, 1, B_RELATIVE_TIMEOUT, 5 * 1000000); 506 507 benaphore_lock(&sCacheLock); 508 509 if (status == B_TIMED_OUT) 510 return EHOSTUNREACH; 511 512 // retrieve the entry again, as we reacquired the cache lock 513 entry = arp_entry::Lookup(address); 514 if (entry == NULL) 515 return B_ERROR; 516 517 *_entry = entry; 518 return B_OK; 519 } 520 521 522 /*! 523 Address resolver function: prepares and sends the ARP request necessary 524 to retrieve the hardware address for \a address. 525 You need to have the sCacheLock held when calling this function - but 526 note that the lock will be interrupted here if everything goes well. 527 */ 528 static status_t 529 arp_resolve(net_datalink_protocol *protocol, in_addr_t address, arp_entry **_entry) 530 { 531 // create an unresolved ARP entry as a placeholder 532 arp_entry *entry = arp_entry::Add(address, NULL, 0); 533 if (entry == NULL) 534 return B_NO_MEMORY; 535 536 // prepare ARP request 537 538 entry->request_buffer = gBufferModule->create(256); 539 if (entry->request_buffer == NULL) { 540 // TODO: do something with the entry 541 return B_NO_MEMORY; 542 } 543 544 NetBufferPrepend<arp_header> bufferHeader(entry->request_buffer); 545 status_t status = bufferHeader.Status(); 546 if (status < B_OK) { 547 // TODO: do something with the entry 548 return status; 549 } 550 551 // prepare ARP header 552 553 net_device *device = protocol->interface->device; 554 arp_header &header = bufferHeader.Data(); 555 556 header.hardware_type = htons(ARP_HARDWARE_TYPE_ETHER); 557 header.protocol_type = htons(ETHER_TYPE_IP); 558 header.hardware_length = ETHER_ADDRESS_LENGTH; 559 header.protocol_length = sizeof(in_addr_t); 560 header.opcode = htons(ARP_OPCODE_REQUEST); 561 562 memcpy(header.hardware_sender, device->address.data, ETHER_ADDRESS_LENGTH); 563 header.protocol_sender = ((sockaddr_in *)protocol->interface->address)->sin_addr.s_addr; 564 memset(header.hardware_target, 0, ETHER_ADDRESS_LENGTH); 565 header.protocol_target = address; 566 567 // prepare source and target addresses 568 569 struct sockaddr_dl &source = *(struct sockaddr_dl *)&entry->request_buffer->source; 570 source.sdl_len = sizeof(sockaddr_dl); 571 source.sdl_family = AF_DLI; 572 source.sdl_index = device->index; 573 source.sdl_type = IFT_ETHER; 574 source.sdl_e_type = ETHER_TYPE_ARP; 575 source.sdl_nlen = source.sdl_slen = 0; 576 source.sdl_alen = ETHER_ADDRESS_LENGTH; 577 memcpy(source.sdl_data, device->address.data, ETHER_ADDRESS_LENGTH); 578 579 entry->request_buffer->flags = MSG_BCAST; 580 // this is a broadcast packet, we don't need to fill in the destination 581 582 entry->protocol = protocol; 583 entry->timer_state = ARP_STATE_REQUEST; 584 sStackModule->set_timer(&entry->timer, 0); 585 // start request timer 586 587 sem_id waitSem = entry->resolved_sem; 588 benaphore_unlock(&sCacheLock); 589 590 // TODO: resend the request periodically via timer 591 // (and abort it that way, too) 592 593 status = acquire_sem_etc(waitSem, 1, B_RELATIVE_TIMEOUT, 5 * 1000000); 594 // wait for the entry to become resolved 595 596 benaphore_lock(&sCacheLock); 597 598 // retrieve the entry again, as we reacquired the cache lock 599 entry = arp_entry::Lookup(address); 600 if (entry == NULL) 601 return B_ERROR; 602 603 if (status == B_TIMED_OUT) { 604 // we didn't get a response, mark ARP entry as non-existant 605 entry->flags = ARP_FLAG_REJECT; 606 // TODO: remove the ARP entry after some time 607 return EHOSTUNREACH; 608 } 609 610 *_entry = entry; 611 return B_OK; 612 } 613 614 615 static status_t 616 arp_control(const char *subsystem, uint32 function, 617 void *buffer, size_t bufferSize) 618 { 619 struct arp_control control; 620 if (bufferSize != sizeof(struct arp_control)) 621 return B_BAD_VALUE; 622 if (user_memcpy(&control, buffer, sizeof(struct arp_control)) < B_OK) 623 return B_BAD_ADDRESS; 624 625 BenaphoreLocker locker(sCacheLock); 626 627 switch (function) { 628 case ARP_SET_ENTRY: 629 sockaddr_dl hardwareAddress; 630 631 hardwareAddress.sdl_len = sizeof(sockaddr_dl); 632 hardwareAddress.sdl_family = AF_DLI; 633 hardwareAddress.sdl_index = 0; 634 hardwareAddress.sdl_type = IFT_ETHER; 635 hardwareAddress.sdl_e_type = ETHER_TYPE_IP; 636 hardwareAddress.sdl_nlen = hardwareAddress.sdl_slen = 0; 637 hardwareAddress.sdl_alen = ETHER_ADDRESS_LENGTH; 638 memcpy(hardwareAddress.sdl_data, control.ethernet_address, ETHER_ADDRESS_LENGTH); 639 640 return arp_update_entry(control.address, &hardwareAddress, 641 control.flags & (ARP_FLAG_PUBLISH | ARP_FLAG_PERMANENT | ARP_FLAG_REJECT)); 642 643 case ARP_GET_ENTRY: 644 { 645 arp_entry *entry = arp_entry::Lookup(control.address); 646 if (entry == NULL || entry->resolved_sem < B_OK) 647 return B_ENTRY_NOT_FOUND; 648 649 memcpy(control.ethernet_address, entry->hardware_address.sdl_data, 650 ETHER_ADDRESS_LENGTH); 651 control.flags = entry->flags; 652 return user_memcpy(buffer, &control, sizeof(struct arp_control)); 653 } 654 655 case ARP_GET_ENTRIES: 656 { 657 hash_iterator iterator; 658 hash_open(sCache, &iterator); 659 660 arp_entry *entry; 661 uint32 i = 0; 662 while ((entry = (arp_entry *)hash_next(sCache, &iterator)) != NULL 663 && i < control.cookie) { 664 i++; 665 } 666 hash_close(sCache, &iterator, false); 667 668 if (entry == NULL) 669 return B_ENTRY_NOT_FOUND; 670 671 control.cookie++; 672 control.address = entry->protocol_address; 673 memcpy(control.ethernet_address, entry->hardware_address.sdl_data, 674 ETHER_ADDRESS_LENGTH); 675 control.flags = entry->flags; 676 677 return user_memcpy(buffer, &control, sizeof(struct arp_control)); 678 } 679 680 case ARP_DELETE_ENTRY: 681 { 682 arp_entry *entry = arp_entry::Lookup(control.address); 683 if (entry == NULL || entry->resolved_sem < B_OK) 684 return B_ENTRY_NOT_FOUND; 685 if ((entry->flags & ARP_FLAG_LOCAL) != 0) 686 return B_BAD_VALUE; 687 688 // schedule a timer to remove this entry 689 entry->timer_state = ARP_STATE_REMOVE_FAILED; 690 sStackModule->set_timer(&entry->timer, 0); 691 return B_OK; 692 } 693 694 case ARP_FLUSH_ENTRIES: 695 { 696 hash_iterator iterator; 697 hash_open(sCache, &iterator); 698 699 arp_entry *entry; 700 while ((entry = (arp_entry *)hash_next(sCache, &iterator)) != NULL) { 701 // we never flush local ARP entries 702 if ((entry->flags & ARP_FLAG_LOCAL) != 0) 703 continue; 704 705 // schedule a timer to remove this entry 706 entry->timer_state = ARP_STATE_REMOVE_FAILED; 707 sStackModule->set_timer(&entry->timer, 0); 708 } 709 hash_close(sCache, &iterator, false); 710 return B_OK; 711 } 712 713 case ARP_IGNORE_REPLIES: 714 sIgnoreReplies = control.flags != 0; 715 return B_OK; 716 } 717 718 return B_BAD_VALUE; 719 } 720 721 722 static status_t 723 arp_init() 724 { 725 status_t status = get_module(NET_STACK_MODULE_NAME, (module_info **)&sStackModule); 726 if (status < B_OK) 727 return status; 728 status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule); 729 if (status < B_OK) 730 goto err1; 731 732 status = benaphore_init(&sCacheLock, "arp cache"); 733 if (status < B_OK) 734 goto err2; 735 736 sCache = hash_init(64, offsetof(struct arp_entry, next), 737 &arp_entry::Compare, &arp_entry::Hash); 738 if (sCache == NULL) { 739 status = B_NO_MEMORY; 740 goto err3; 741 } 742 743 register_generic_syscall(ARP_SYSCALLS, arp_control, 1, 0); 744 return B_OK; 745 746 err3: 747 benaphore_destroy(&sCacheLock); 748 err2: 749 put_module(NET_BUFFER_MODULE_NAME); 750 err1: 751 put_module(NET_STACK_MODULE_NAME); 752 return status; 753 } 754 755 756 static status_t 757 arp_uninit() 758 { 759 unregister_generic_syscall(ARP_SYSCALLS, 1); 760 761 put_module(NET_BUFFER_MODULE_NAME); 762 put_module(NET_STACK_MODULE_NAME); 763 return B_OK; 764 } 765 766 767 // #pragma mark - 768 769 770 status_t 771 arp_init_protocol(struct net_interface *interface, net_datalink_protocol **_protocol) 772 { 773 // We currently only support a single family and type! 774 if (interface->domain->family != AF_INET 775 || interface->device->type != IFT_ETHER) 776 return B_BAD_TYPE; 777 778 status_t status = sStackModule->register_device_handler(interface->device, 779 ETHER_FRAME_TYPE | ETHER_TYPE_ARP, &arp_receive, NULL); 780 if (status == B_OK) { 781 // We also register the domain as a handler for deframed packets; 782 // while the ethernet_frame module is not really connected to our 783 // domain, we are. 784 status = sStackModule->register_domain_device_handler(interface->device, 785 ETHER_FRAME_TYPE | ETHER_TYPE_IP, interface->domain); 786 } 787 788 if (status < B_OK) 789 return status; 790 791 arp_protocol *protocol = new (std::nothrow) arp_protocol; 792 if (protocol == NULL) 793 return B_NO_MEMORY; 794 795 *_protocol = protocol; 796 return B_OK; 797 } 798 799 800 status_t 801 arp_uninit_protocol(net_datalink_protocol *protocol) 802 { 803 sStackModule->unregister_device_handler(protocol->interface->device, 804 ETHER_FRAME_TYPE | ETHER_TYPE_ARP); 805 sStackModule->unregister_device_handler(protocol->interface->device, 806 ETHER_FRAME_TYPE | ETHER_TYPE_IP); 807 808 delete protocol; 809 return B_OK; 810 } 811 812 813 status_t 814 arp_send_data(net_datalink_protocol *protocol, 815 net_buffer *buffer) 816 { 817 { 818 BenaphoreLocker locker(sCacheLock); 819 820 // Lookup source (us) 821 822 arp_entry *entry = arp_entry::Lookup( 823 ((struct sockaddr_in *)&buffer->source)->sin_addr.s_addr); 824 if (entry == NULL) 825 return B_ERROR; 826 827 memcpy(&buffer->source, &entry->hardware_address, 828 entry->hardware_address.sdl_len); 829 830 // Lookup destination (we may need to wait for this) 831 entry = arp_entry::Lookup( 832 ((struct sockaddr_in *)&buffer->destination)->sin_addr.s_addr); 833 if (entry == NULL) { 834 // The ARP entry does not yet exist, if we're allowed to wait, 835 // we'll send an ARP request and try to change that. 836 if ((buffer->flags & MSG_DONTWAIT) != 0) { 837 // TODO: implement delaying packet send after ARP response! 838 return B_ERROR; 839 } 840 841 status_t status = arp_resolve(protocol, 842 ((struct sockaddr_in *)&buffer->destination)->sin_addr.s_addr, &entry); 843 if (status < B_OK) 844 return status; 845 } else { 846 // The entry exists, but we have to check if it has already been 847 // resolved and is valid. 848 status_t status = arp_check_resolved(&entry, buffer->flags); 849 if (status < B_OK) 850 return status; 851 } 852 853 memcpy(&buffer->destination, &entry->hardware_address, 854 entry->hardware_address.sdl_len); 855 } 856 857 return protocol->next->module->send_data(protocol->next, buffer); 858 } 859 860 861 status_t 862 arp_up(net_datalink_protocol *_protocol) 863 { 864 arp_protocol *protocol = (arp_protocol *)_protocol; 865 status_t status = protocol->next->module->interface_up(protocol->next); 866 if (status < B_OK) 867 return status; 868 869 // cache this device's address for later use 870 871 status = arp_update_local(protocol); 872 if (status < B_OK) { 873 protocol->next->module->interface_down(protocol->next); 874 return status; 875 } 876 877 return B_OK; 878 } 879 880 881 void 882 arp_down(net_datalink_protocol *protocol) 883 { 884 // remove local ARP entry from the cache 885 886 if (protocol->interface->address != NULL) { 887 BenaphoreLocker locker(sCacheLock); 888 889 arp_entry *entry = arp_entry::Lookup( 890 ((sockaddr_in *)protocol->interface->address)->sin_addr.s_addr); 891 if (entry != NULL) { 892 hash_remove(sCache, entry); 893 delete entry; 894 } 895 } 896 897 protocol->next->module->interface_down(protocol->next); 898 } 899 900 901 status_t 902 arp_control(net_datalink_protocol *protocol, 903 int32 op, void *argument, size_t length) 904 { 905 if (op == SIOCSIFADDR && (protocol->interface->flags & IFF_UP) != 0) { 906 // The interface may get a new address, so we need to update our 907 // local entries. 908 in_addr_t oldAddress = 0; 909 if (protocol->interface->address != NULL) 910 oldAddress = ((sockaddr_in *)protocol->interface->address)->sin_addr.s_addr; 911 912 status_t status = protocol->next->module->control(protocol->next, 913 SIOCSIFADDR, argument, length); 914 if (status < B_OK) 915 return status; 916 917 arp_update_local(protocol); 918 919 if (oldAddress == ((sockaddr_in *)protocol->interface->address)->sin_addr.s_addr 920 || oldAddress == 0) 921 return B_OK; 922 923 // remove previous address from cache 924 // TODO: we should be able to do this (add/remove) in one atomic operation! 925 926 BenaphoreLocker locker(sCacheLock); 927 928 arp_entry *entry = arp_entry::Lookup(oldAddress); 929 if (entry != NULL) { 930 hash_remove(sCache, entry); 931 delete entry; 932 } 933 934 return B_OK; 935 } 936 937 return protocol->next->module->control(protocol->next, 938 op, argument, length); 939 } 940 941 942 static status_t 943 arp_std_ops(int32 op, ...) 944 { 945 switch (op) { 946 case B_MODULE_INIT: 947 return arp_init(); 948 case B_MODULE_UNINIT: 949 return arp_uninit(); 950 951 default: 952 return B_ERROR; 953 } 954 } 955 956 957 static net_datalink_protocol_module_info sARPModule = { 958 { 959 "network/datalink_protocols/arp/v1", 960 0, 961 arp_std_ops 962 }, 963 arp_init_protocol, 964 arp_uninit_protocol, 965 arp_send_data, 966 arp_up, 967 arp_down, 968 arp_control, 969 }; 970 971 module_info *modules[] = { 972 (module_info *)&sARPModule, 973 NULL 974 }; 975