1 /* 2 * Copyright 2006-2010, 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 * Hugo Santos, hugosantos@gmail.com 8 */ 9 10 11 //! Ethernet Address Resolution Protocol, see RFC 826. 12 13 14 #include <arp_control.h> 15 #include <net_datalink_protocol.h> 16 #include <net_device.h> 17 #include <net_datalink.h> 18 #include <net_stack.h> 19 #include <NetBufferUtilities.h> 20 21 #include <generic_syscall.h> 22 #include <util/atomic.h> 23 #include <util/AutoLock.h> 24 #include <util/DoublyLinkedList.h> 25 #include <util/khash.h> 26 27 #include <ByteOrder.h> 28 #include <KernelExport.h> 29 30 #include <net/if.h> 31 #include <net/if_dl.h> 32 #include <net/if_types.h> 33 #include <new> 34 #include <stdio.h> 35 #include <string.h> 36 #include <sys/sockio.h> 37 38 39 //#define TRACE_ARP 40 #ifdef TRACE_ARP 41 # define TRACE(x) dprintf x 42 #else 43 # define TRACE(x) ; 44 #endif 45 46 47 struct arp_header { 48 uint16 hardware_type; 49 uint16 protocol_type; 50 uint8 hardware_length; 51 uint8 protocol_length; 52 uint16 opcode; 53 54 // TODO: this should be a variable length header, but for our current 55 // usage (Ethernet/IPv4), this should work fine. 56 uint8 hardware_sender[6]; 57 in_addr_t protocol_sender; 58 uint8 hardware_target[6]; 59 in_addr_t protocol_target; 60 } _PACKED; 61 62 #define ARP_OPCODE_REQUEST 1 63 #define ARP_OPCODE_REPLY 2 64 65 #define ARP_HARDWARE_TYPE_ETHER 1 66 67 struct arp_entry { 68 arp_entry *next; 69 in_addr_t protocol_address; 70 sockaddr_dl hardware_address; 71 uint32 flags; 72 net_buffer *request_buffer; 73 net_timer timer; 74 uint32 timer_state; 75 bigtime_t timestamp; 76 net_datalink_protocol *protocol; 77 78 typedef DoublyLinkedListCLink<net_buffer> NetBufferLink; 79 typedef DoublyLinkedList<net_buffer, NetBufferLink> BufferList; 80 81 BufferList queue; 82 83 static int Compare(void *_entry, const void *_key); 84 static uint32 Hash(void *_entry, const void *_key, uint32 range); 85 static arp_entry *Lookup(in_addr_t protocolAddress); 86 static arp_entry *Add(in_addr_t protocolAddress, 87 sockaddr_dl *hardwareAddress, uint32 flags); 88 89 ~arp_entry(); 90 91 void ClearQueue(); 92 void MarkFailed(); 93 void MarkValid(); 94 void ScheduleRemoval(); 95 }; 96 97 // see arp_control.h for more flags 98 #define ARP_FLAG_REMOVED 0x00010000 99 #define ARP_PUBLIC_FLAG_MASK 0x0000ffff 100 101 #define ARP_NO_STATE 0 102 #define ARP_STATE_REQUEST 1 103 #define ARP_STATE_LAST_REQUEST 5 104 #define ARP_STATE_REQUEST_FAILED 6 105 #define ARP_STATE_REMOVE_FAILED 7 106 #define ARP_STATE_STALE 8 107 108 #define ARP_STALE_TIMEOUT 30 * 60000000LL // 30 minutes 109 #define ARP_REJECT_TIMEOUT 20000000LL // 20 seconds 110 #define ARP_REQUEST_TIMEOUT 1000000LL // 1 second 111 112 struct arp_protocol : net_datalink_protocol { 113 sockaddr_dl hardware_address; 114 in_addr_t local_address; 115 }; 116 117 118 static const net_buffer* kDeletedBuffer = (net_buffer*)~0; 119 120 static void arp_timer(struct net_timer *timer, void *data); 121 122 net_buffer_module_info* gBufferModule; 123 static net_stack_module_info* sStackModule; 124 static net_datalink_module_info* sDatalinkModule; 125 static hash_table* sCache; 126 static mutex sCacheLock; 127 static bool sIgnoreReplies; 128 129 130 #ifdef TRACE_ARP 131 132 133 const char* 134 mac_to_string(uint8* address) 135 { 136 static char buffer[20]; 137 snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x", 138 address[0], address[1], address[2], address[3], address[4], address[5]); 139 return buffer; 140 } 141 142 143 const char* 144 inet_to_string(in_addr_t address) 145 { 146 static char buffer[20]; 147 148 unsigned int hostAddress = ntohl(address); 149 snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d", 150 hostAddress >> 24, (hostAddress >> 16) & 0xff, 151 (hostAddress >> 8) & 0xff, hostAddress & 0xff); 152 return buffer; 153 } 154 155 156 #endif // TRACE_ARP 157 158 159 static net_buffer* 160 get_request_buffer(arp_entry* entry) 161 { 162 net_buffer* buffer = entry->request_buffer; 163 if (buffer == NULL || buffer == kDeletedBuffer) 164 return NULL; 165 166 buffer = atomic_pointer_test_and_set(&entry->request_buffer, 167 (net_buffer*)NULL, buffer); 168 if (buffer == kDeletedBuffer) 169 return NULL; 170 171 return buffer; 172 } 173 174 175 static void 176 put_request_buffer(arp_entry* entry, net_buffer* buffer) 177 { 178 net_buffer* requestBuffer = atomic_pointer_test_and_set( 179 &entry->request_buffer, buffer, (net_buffer*)NULL); 180 if (requestBuffer != NULL) { 181 // someone else took over ownership of the request buffer 182 gBufferModule->free(buffer); 183 } 184 } 185 186 187 static void 188 delete_request_buffer(arp_entry* entry) 189 { 190 net_buffer* buffer = atomic_pointer_set(&entry->request_buffer, 191 kDeletedBuffer); 192 if (buffer != NULL && buffer != kDeletedBuffer) 193 gBufferModule->free(buffer); 194 } 195 196 197 static void 198 ipv4_to_ether_multicast(sockaddr_dl *destination, const sockaddr_in *source) 199 { 200 // RFC 1112 - Host extensions for IP multicasting 201 // 202 // ``An IP host group address is mapped to an Ethernet multicast 203 // address by placing the low-order 23-bits of the IP address into 204 // the low-order 23 bits of the Ethernet multicast address 205 // 01-00-5E-00-00-00 (hex).'' 206 207 destination->sdl_len = sizeof(sockaddr_dl); 208 destination->sdl_family = AF_LINK; 209 destination->sdl_index = 0; 210 destination->sdl_type = IFT_ETHER; 211 destination->sdl_e_type = htons(ETHER_TYPE_IP); 212 destination->sdl_nlen = destination->sdl_slen = 0; 213 destination->sdl_alen = ETHER_ADDRESS_LENGTH; 214 215 memcpy(LLADDR(destination) + 2, &source->sin_addr, sizeof(in_addr)); 216 uint32 *data = (uint32 *)LLADDR(destination); 217 data[0] = (data[0] & htonl(0x7f)) | htonl(0x01005e00); 218 } 219 220 221 // #pragma mark - 222 223 224 /*static*/ int 225 arp_entry::Compare(void *_entry, const void *_key) 226 { 227 arp_entry *entry = (arp_entry *)_entry; 228 in_addr_t *key = (in_addr_t *)_key; 229 230 if (entry->protocol_address == *key) 231 return 0; 232 233 return 1; 234 } 235 236 237 /*static*/ uint32 238 arp_entry::Hash(void *_entry, const void *_key, uint32 range) 239 { 240 arp_entry *entry = (arp_entry *)_entry; 241 const in_addr_t *key = (const in_addr_t *)_key; 242 243 // TODO: check if this makes a good hash... 244 #define HASH(o) ((((o) >> 24) ^ ((o) >> 16) ^ ((o) >> 8) ^ (o)) % range) 245 246 #if 0 247 in_addr_t a = entry ? entry->protocol_address : *key; 248 dprintf("%ld.%ld.%ld.%ld: Hash: %lu\n", a >> 24, (a >> 16) & 0xff, 249 (a >> 8) & 0xff, a & 0xff, HASH(a)); 250 #endif 251 252 if (entry != NULL) 253 return HASH(entry->protocol_address); 254 255 return HASH(*key); 256 #undef HASH 257 } 258 259 260 /*static*/ arp_entry * 261 arp_entry::Lookup(in_addr_t address) 262 { 263 return (arp_entry *)hash_lookup(sCache, &address); 264 } 265 266 267 /*static*/ arp_entry * 268 arp_entry::Add(in_addr_t protocolAddress, sockaddr_dl *hardwareAddress, 269 uint32 flags) 270 { 271 ASSERT_LOCKED_MUTEX(&sCacheLock); 272 273 arp_entry *entry = new (std::nothrow) arp_entry; 274 if (entry == NULL) 275 return NULL; 276 277 entry->protocol_address = protocolAddress; 278 entry->flags = flags; 279 entry->timestamp = system_time(); 280 entry->protocol = NULL; 281 entry->request_buffer = NULL; 282 entry->timer_state = ARP_NO_STATE; 283 sStackModule->init_timer(&entry->timer, arp_timer, entry); 284 285 if (hardwareAddress != NULL) { 286 // this entry is already resolved 287 entry->hardware_address = *hardwareAddress; 288 entry->hardware_address.sdl_e_type = htons(ETHER_TYPE_IP); 289 } else { 290 // this entry still needs to be resolved 291 entry->hardware_address.sdl_alen = 0; 292 } 293 if (entry->hardware_address.sdl_len != sizeof(sockaddr_dl)) { 294 // explicitly set correct length in case our caller hasn't... 295 entry->hardware_address.sdl_len = sizeof(sockaddr_dl); 296 } 297 298 if (hash_insert(sCache, entry) != B_OK) { 299 // We can delete the entry here with the sCacheLock held, since it's 300 // guaranteed there are no timers pending. 301 delete entry; 302 return NULL; 303 } 304 305 return entry; 306 } 307 308 309 arp_entry::~arp_entry() 310 { 311 // make sure there is no active timer left for us 312 sStackModule->cancel_timer(&timer); 313 sStackModule->wait_for_timer(&timer); 314 315 ClearQueue(); 316 } 317 318 319 void 320 arp_entry::ClearQueue() 321 { 322 BufferList::Iterator iterator = queue.GetIterator(); 323 while (iterator.HasNext()) { 324 net_buffer *buffer = iterator.Next(); 325 iterator.Remove(); 326 gBufferModule->free(buffer); 327 } 328 } 329 330 331 void 332 arp_entry::MarkFailed() 333 { 334 TRACE(("ARP entry %p Marked as FAILED\n", this)); 335 336 flags = (flags & ~ARP_FLAG_VALID) | ARP_FLAG_REJECT; 337 ClearQueue(); 338 } 339 340 341 void 342 arp_entry::MarkValid() 343 { 344 TRACE(("ARP entry %p Marked as VALID, have %li packets queued.\n", this, 345 queue.Count())); 346 347 flags = (flags & ~ARP_FLAG_REJECT) | ARP_FLAG_VALID; 348 349 BufferList::Iterator iterator = queue.GetIterator(); 350 while (iterator.HasNext()) { 351 net_buffer *buffer = iterator.Next(); 352 iterator.Remove(); 353 354 TRACE((" ARP Dequeing packet %p...\n", buffer)); 355 356 memcpy(buffer->destination, &hardware_address, 357 hardware_address.sdl_len); 358 protocol->next->module->send_data(protocol->next, buffer); 359 } 360 } 361 362 363 void 364 arp_entry::ScheduleRemoval() 365 { 366 // schedule a timer to remove this entry 367 timer_state = ARP_STATE_REMOVE_FAILED; 368 sStackModule->set_timer(&timer, 0); 369 } 370 371 372 // #pragma mark - 373 374 375 /*! Updates the entry determined by \a protocolAddress with the specified 376 \a hardwareAddress. 377 If such an entry does not exist yet, a new entry is added. If you try 378 to update a local existing entry but didn't ask for it (by setting 379 \a flags to ARP_FLAG_LOCAL), an error is returned. 380 381 This function does not lock the cache - you have to do it yourself 382 before calling it. 383 */ 384 static status_t 385 arp_update_entry(in_addr_t protocolAddress, sockaddr_dl *hardwareAddress, 386 uint32 flags, arp_entry **_entry = NULL) 387 { 388 ASSERT_LOCKED_MUTEX(&sCacheLock); 389 TRACE(("%s(%s, %s, flags 0x%" B_PRIx32 ")\n", __FUNCTION__, 390 inet_to_string(protocolAddress), mac_to_string(LLADDR(hardwareAddress)), 391 flags)); 392 393 arp_entry *entry = arp_entry::Lookup(protocolAddress); 394 if (entry != NULL) { 395 // We disallow updating of entries that had been resolved before, 396 // but to a different address (only for those that belong to a 397 // specific address - redefining INADDR_ANY is always allowed). 398 // Right now, you have to manually purge the ARP entries (or wait some 399 // time) to let us switch to the new address. 400 if (protocolAddress != INADDR_ANY 401 && entry->hardware_address.sdl_alen != 0 402 && memcmp(LLADDR(&entry->hardware_address), 403 LLADDR(hardwareAddress), ETHER_ADDRESS_LENGTH)) { 404 uint8* data = LLADDR(hardwareAddress); 405 dprintf("ARP host %08x updated with different hardware address " 406 "%02x:%02x:%02x:%02x:%02x:%02x.\n", protocolAddress, 407 data[0], data[1], data[2], data[3], data[4], data[5]); 408 return B_ERROR; 409 } 410 411 entry->hardware_address = *hardwareAddress; 412 entry->timestamp = system_time(); 413 } else { 414 entry = arp_entry::Add(protocolAddress, hardwareAddress, flags); 415 if (entry == NULL) 416 return B_NO_MEMORY; 417 } 418 419 delete_request_buffer(entry); 420 421 if ((entry->flags & ARP_FLAG_PERMANENT) == 0) { 422 // (re)start the stale timer 423 entry->timer_state = ARP_STATE_STALE; 424 sStackModule->set_timer(&entry->timer, ARP_STALE_TIMEOUT); 425 } 426 427 if ((entry->flags & ARP_FLAG_REJECT) != 0) 428 entry->MarkFailed(); 429 else 430 entry->MarkValid(); 431 432 if (_entry) 433 *_entry = entry; 434 435 return B_OK; 436 } 437 438 439 static status_t 440 arp_set_local_entry(arp_protocol* protocol, const sockaddr* local) 441 { 442 MutexLocker locker(sCacheLock); 443 444 net_interface* interface = protocol->interface; 445 in_addr_t inetAddress; 446 447 if (local == NULL) { 448 // interface has not yet been set 449 inetAddress = INADDR_ANY; 450 } else 451 inetAddress = ((sockaddr_in*)local)->sin_addr.s_addr; 452 453 TRACE(("%s(): address %s\n", __FUNCTION__, inet_to_string(inetAddress))); 454 455 if (protocol->local_address == 0) 456 protocol->local_address = inetAddress; 457 458 sockaddr_dl address; 459 address.sdl_len = sizeof(sockaddr_dl); 460 address.sdl_family = AF_LINK; 461 address.sdl_type = IFT_ETHER; 462 address.sdl_e_type = htons(ETHER_TYPE_IP); 463 address.sdl_nlen = 0; 464 address.sdl_slen = 0; 465 address.sdl_alen = interface->device->address.length; 466 memcpy(LLADDR(&address), interface->device->address.data, address.sdl_alen); 467 468 memcpy(&protocol->hardware_address, &address, sizeof(sockaddr_dl)); 469 // cache the address in our protocol 470 471 arp_entry* entry; 472 status_t status = arp_update_entry(inetAddress, &address, 473 ARP_FLAG_LOCAL | ARP_FLAG_PERMANENT, &entry); 474 if (status == B_OK) 475 entry->protocol = protocol; 476 477 return status; 478 } 479 480 481 static void 482 arp_remove_local_entry(arp_protocol* protocol, const sockaddr* local, 483 net_interface_address* updateLocalAddress = NULL) 484 { 485 in_addr_t inetAddress; 486 487 if (local == NULL) { 488 // interface has not yet been set 489 inetAddress = INADDR_ANY; 490 } else 491 inetAddress = ((sockaddr_in*)local)->sin_addr.s_addr; 492 493 TRACE(("%s(): address %s\n", __FUNCTION__, inet_to_string(inetAddress))); 494 495 MutexLocker locker(sCacheLock); 496 497 arp_entry* entry = arp_entry::Lookup(inetAddress); 498 if (entry != NULL) { 499 hash_remove(sCache, entry); 500 entry->flags |= ARP_FLAG_REMOVED; 501 } 502 503 if (updateLocalAddress != NULL && protocol->local_address == inetAddress) { 504 // find new local sender address 505 protocol->local_address = 0; 506 507 net_interface_address* address = NULL; 508 while (sDatalinkModule->get_next_interface_address(protocol->interface, 509 &address)) { 510 if (address == updateLocalAddress || address->local == NULL 511 || address->local->sa_family != AF_INET) 512 continue; 513 514 protocol->local_address 515 = ((sockaddr_in*)address->local)->sin_addr.s_addr; 516 } 517 } 518 519 locker.Unlock(); 520 delete entry; 521 522 if (protocol->local_address == 0 && updateLocalAddress) { 523 // Try to keep the interface operational 524 arp_set_local_entry(protocol, NULL); 525 } 526 } 527 528 529 /*! Removes all entries belonging to the local interface of the \a procotol 530 given. 531 */ 532 static void 533 arp_remove_local(arp_protocol* protocol) 534 { 535 net_interface_address* address = NULL; 536 while (sDatalinkModule->get_next_interface_address(protocol->interface, 537 &address)) { 538 if (address->local == NULL || address->local->sa_family != AF_INET) 539 continue; 540 541 arp_remove_local_entry(protocol, address->local); 542 } 543 } 544 545 546 /*! Creates permanent local entries for all addresses of the interface belonging 547 to this protocol. 548 Returns an error if no entry could be added. 549 */ 550 static status_t 551 arp_update_local(arp_protocol* protocol) 552 { 553 protocol->local_address = 0; 554 // TODO: test if this actually works - maybe we should use 555 // INADDR_BROADCAST instead 556 557 ssize_t count = 0; 558 559 net_interface_address* address = NULL; 560 while (sDatalinkModule->get_next_interface_address(protocol->interface, 561 &address)) { 562 if (address->local == NULL || address->local->sa_family != AF_INET) 563 continue; 564 565 if (arp_set_local_entry(protocol, address->local) == B_OK) { 566 count++; 567 } 568 } 569 570 if (count == 0) 571 return arp_set_local_entry(protocol, NULL); 572 573 return B_OK; 574 } 575 576 577 static status_t 578 handle_arp_request(net_buffer *buffer, arp_header &header) 579 { 580 MutexLocker locker(sCacheLock); 581 582 if (!sIgnoreReplies) { 583 arp_update_entry(header.protocol_sender, 584 (sockaddr_dl *)buffer->source, 0); 585 // remember the address of the sender as we might need it later 586 } 587 588 // check if this request is for us 589 590 arp_entry *entry = arp_entry::Lookup(header.protocol_target); 591 if (entry == NULL || entry->protocol == NULL 592 || (entry->flags & (ARP_FLAG_LOCAL | ARP_FLAG_PUBLISH)) == 0) { 593 // We're not the one to answer this request 594 // TODO: instead of letting the other's request time-out, can we reply 595 // failure somehow? 596 TRACE((" not for us\n")); 597 return B_ERROR; 598 } 599 600 // send a reply (by reusing the buffer we got) 601 602 TRACE((" send reply!\n")); 603 header.opcode = htons(ARP_OPCODE_REPLY); 604 605 memcpy(header.hardware_target, header.hardware_sender, ETHER_ADDRESS_LENGTH); 606 header.protocol_target = header.protocol_sender; 607 memcpy(header.hardware_sender, LLADDR(&entry->hardware_address), 608 ETHER_ADDRESS_LENGTH); 609 header.protocol_sender = entry->protocol_address; 610 611 // exchange source and destination address 612 memcpy(LLADDR((sockaddr_dl *)buffer->source), header.hardware_sender, 613 ETHER_ADDRESS_LENGTH); 614 memcpy(LLADDR((sockaddr_dl *)buffer->destination), header.hardware_target, 615 ETHER_ADDRESS_LENGTH); 616 617 buffer->flags = 0; 618 // make sure this won't be a broadcast message 619 620 return entry->protocol->next->module->send_data(entry->protocol->next, 621 buffer); 622 } 623 624 625 static void 626 handle_arp_reply(net_buffer *buffer, arp_header &header) 627 { 628 if (sIgnoreReplies) 629 return; 630 631 MutexLocker locker(sCacheLock); 632 arp_update_entry(header.protocol_sender, (sockaddr_dl *)buffer->source, 0); 633 } 634 635 636 static status_t 637 arp_receive(void *cookie, net_device *device, net_buffer *buffer) 638 { 639 TRACE(("ARP receive\n")); 640 641 NetBufferHeaderReader<arp_header> bufferHeader(buffer); 642 if (bufferHeader.Status() < B_OK) 643 return bufferHeader.Status(); 644 645 arp_header &header = bufferHeader.Data(); 646 uint16 opcode = ntohs(header.opcode); 647 648 #ifdef TRACE_ARP 649 dprintf(" hw sender: %s\n", mac_to_string(header.hardware_sender)); 650 dprintf(" proto sender: %s\n", inet_to_string(header.protocol_sender)); 651 dprintf(" hw target: %s\n", mac_to_string(header.hardware_target));; 652 dprintf(" proto target: %s\n", inet_to_string(header.protocol_target)); 653 #endif // TRACE_ARP 654 655 if (ntohs(header.protocol_type) != ETHER_TYPE_IP 656 || ntohs(header.hardware_type) != ARP_HARDWARE_TYPE_ETHER) 657 return B_BAD_TYPE; 658 659 // check if the packet is okay 660 661 if (header.hardware_length != ETHER_ADDRESS_LENGTH 662 || header.protocol_length != sizeof(in_addr_t)) 663 return B_BAD_DATA; 664 665 // handle packet 666 667 switch (opcode) { 668 case ARP_OPCODE_REQUEST: 669 TRACE((" got ARP request\n")); 670 if (handle_arp_request(buffer, header) == B_OK) { 671 // the function will take care of the buffer if everything 672 // went well 673 return B_OK; 674 } 675 break; 676 case ARP_OPCODE_REPLY: 677 TRACE((" got ARP reply\n")); 678 handle_arp_reply(buffer, header); 679 break; 680 681 default: 682 dprintf("unknown ARP opcode %d\n", opcode); 683 return B_ERROR; 684 } 685 686 gBufferModule->free(buffer); 687 return B_OK; 688 } 689 690 691 static void 692 arp_timer(struct net_timer *timer, void *data) 693 { 694 arp_entry *entry = (arp_entry *)data; 695 TRACE(("ARP timer %ld, entry %p!\n", entry->timer_state, entry)); 696 697 switch (entry->timer_state) { 698 case ARP_NO_STATE: 699 // who are you kidding? 700 break; 701 702 case ARP_STATE_REQUEST_FAILED: 703 // Requesting the ARP entry failed, we keep it around for a while, 704 // though, so that we won't try to request the same address again 705 // too soon. 706 TRACE((" requesting ARP entry %p failed!\n", entry)); 707 entry->timer_state = ARP_STATE_REMOVE_FAILED; 708 entry->MarkFailed(); 709 sStackModule->set_timer(&entry->timer, ARP_REJECT_TIMEOUT); 710 break; 711 712 case ARP_STATE_REMOVE_FAILED: 713 case ARP_STATE_STALE: 714 { 715 // the entry has aged so much that we're going to remove it 716 TRACE((" remove ARP entry %p!\n", entry)); 717 718 MutexLocker locker(sCacheLock); 719 if ((entry->flags & ARP_FLAG_REMOVED) != 0) { 720 // The entry has already been removed, and is about to be 721 // deleted 722 break; 723 } 724 725 hash_remove(sCache, entry); 726 locker.Unlock(); 727 728 delete entry; 729 break; 730 } 731 732 default: 733 { 734 if (entry->timer_state > ARP_STATE_LAST_REQUEST 735 || entry->protocol == NULL) 736 break; 737 738 TRACE((" send request for ARP entry %p!\n", entry)); 739 740 net_buffer *request = get_request_buffer(entry); 741 if (request == NULL) 742 break; 743 744 if (entry->timer_state < ARP_STATE_LAST_REQUEST) { 745 // we'll still need our buffer, so in order to prevent it being 746 // freed by a successful send, we need to clone it 747 net_buffer* clone = gBufferModule->clone(request, true); 748 if (clone == NULL) { 749 // cloning failed - that means we won't be able to send as 750 // many requests as originally planned 751 entry->timer_state = ARP_STATE_LAST_REQUEST; 752 } else { 753 put_request_buffer(entry, request); 754 request = clone; 755 } 756 } 757 758 // we're trying to resolve the address, so keep sending requests 759 status_t status = entry->protocol->next->module->send_data( 760 entry->protocol->next, request); 761 if (status < B_OK) 762 gBufferModule->free(request); 763 764 entry->timer_state++; 765 sStackModule->set_timer(&entry->timer, ARP_REQUEST_TIMEOUT); 766 break; 767 } 768 } 769 } 770 771 772 /*! Address resolver function: prepares and triggers the ARP request necessary 773 to retrieve the hardware address for \a address. 774 775 You need to have the sCacheLock held when calling this function. 776 */ 777 static status_t 778 arp_start_resolve(arp_protocol* protocol, in_addr_t address, arp_entry** _entry) 779 { 780 ASSERT_LOCKED_MUTEX(&sCacheLock); 781 782 // create an unresolved ARP entry as a placeholder 783 arp_entry *entry = arp_entry::Add(address, NULL, 0); 784 if (entry == NULL) 785 return B_NO_MEMORY; 786 787 // prepare ARP request 788 789 entry->request_buffer = gBufferModule->create(256); 790 if (entry->request_buffer == NULL) { 791 entry->ScheduleRemoval(); 792 return B_NO_MEMORY; 793 } 794 795 NetBufferPrepend<arp_header> bufferHeader(entry->request_buffer); 796 status_t status = bufferHeader.Status(); 797 if (status < B_OK) { 798 entry->ScheduleRemoval(); 799 return status; 800 } 801 802 // prepare ARP header 803 804 net_device *device = protocol->interface->device; 805 arp_header &header = bufferHeader.Data(); 806 807 header.hardware_type = htons(ARP_HARDWARE_TYPE_ETHER); 808 header.protocol_type = htons(ETHER_TYPE_IP); 809 header.hardware_length = ETHER_ADDRESS_LENGTH; 810 header.protocol_length = sizeof(in_addr_t); 811 header.opcode = htons(ARP_OPCODE_REQUEST); 812 813 memcpy(header.hardware_sender, device->address.data, ETHER_ADDRESS_LENGTH); 814 memset(header.hardware_target, 0, ETHER_ADDRESS_LENGTH); 815 header.protocol_sender = protocol->local_address; 816 header.protocol_target = address; 817 818 // prepare source and target addresses 819 820 struct sockaddr_dl &source = *(struct sockaddr_dl *) 821 entry->request_buffer->source; 822 source.sdl_len = sizeof(sockaddr_dl); 823 source.sdl_family = AF_LINK; 824 source.sdl_index = device->index; 825 source.sdl_type = IFT_ETHER; 826 source.sdl_e_type = htons(ETHER_TYPE_ARP); 827 source.sdl_nlen = source.sdl_slen = 0; 828 source.sdl_alen = ETHER_ADDRESS_LENGTH; 829 memcpy(source.sdl_data, device->address.data, ETHER_ADDRESS_LENGTH); 830 831 entry->request_buffer->flags = MSG_BCAST; 832 // this is a broadcast packet, we don't need to fill in the destination 833 834 entry->protocol = protocol; 835 entry->timer_state = ARP_STATE_REQUEST; 836 sStackModule->set_timer(&entry->timer, 0); 837 // start request timer 838 839 *_entry = entry; 840 return B_OK; 841 } 842 843 844 static status_t 845 arp_control(const char *subsystem, uint32 function, void *buffer, 846 size_t bufferSize) 847 { 848 struct arp_control control; 849 if (bufferSize != sizeof(struct arp_control)) 850 return B_BAD_VALUE; 851 if (user_memcpy(&control, buffer, sizeof(struct arp_control)) < B_OK) 852 return B_BAD_ADDRESS; 853 854 MutexLocker locker(sCacheLock); 855 856 switch (function) { 857 case ARP_SET_ENTRY: 858 { 859 sockaddr_dl hardwareAddress; 860 861 hardwareAddress.sdl_len = sizeof(sockaddr_dl); 862 hardwareAddress.sdl_family = AF_LINK; 863 hardwareAddress.sdl_index = 0; 864 hardwareAddress.sdl_type = IFT_ETHER; 865 hardwareAddress.sdl_e_type = htons(ETHER_TYPE_IP); 866 hardwareAddress.sdl_nlen = hardwareAddress.sdl_slen = 0; 867 hardwareAddress.sdl_alen = ETHER_ADDRESS_LENGTH; 868 memcpy(hardwareAddress.sdl_data, control.ethernet_address, 869 ETHER_ADDRESS_LENGTH); 870 871 return arp_update_entry(control.address, &hardwareAddress, 872 control.flags & (ARP_FLAG_PUBLISH | ARP_FLAG_PERMANENT 873 | ARP_FLAG_REJECT)); 874 } 875 876 case ARP_GET_ENTRY: 877 { 878 arp_entry *entry = arp_entry::Lookup(control.address); 879 if (entry == NULL || !(entry->flags & ARP_FLAG_VALID)) 880 return B_ENTRY_NOT_FOUND; 881 882 if (entry->hardware_address.sdl_alen == ETHER_ADDRESS_LENGTH) { 883 memcpy(control.ethernet_address, 884 entry->hardware_address.sdl_data, ETHER_ADDRESS_LENGTH); 885 } else 886 memset(control.ethernet_address, 0, ETHER_ADDRESS_LENGTH); 887 888 control.flags = entry->flags & ARP_PUBLIC_FLAG_MASK; 889 return user_memcpy(buffer, &control, sizeof(struct arp_control)); 890 } 891 892 case ARP_GET_ENTRIES: 893 { 894 hash_iterator iterator; 895 hash_open(sCache, &iterator); 896 897 arp_entry *entry; 898 uint32 i = 0; 899 while ((entry = (arp_entry *)hash_next(sCache, &iterator)) != NULL 900 && i < control.cookie) { 901 i++; 902 } 903 hash_close(sCache, &iterator, false); 904 905 if (entry == NULL) 906 return B_ENTRY_NOT_FOUND; 907 908 control.cookie++; 909 control.address = entry->protocol_address; 910 if (entry->hardware_address.sdl_alen == ETHER_ADDRESS_LENGTH) { 911 memcpy(control.ethernet_address, 912 entry->hardware_address.sdl_data, ETHER_ADDRESS_LENGTH); 913 } else 914 memset(control.ethernet_address, 0, ETHER_ADDRESS_LENGTH); 915 control.flags = entry->flags & ARP_PUBLIC_FLAG_MASK; 916 917 return user_memcpy(buffer, &control, sizeof(struct arp_control)); 918 } 919 920 case ARP_DELETE_ENTRY: 921 { 922 arp_entry *entry = arp_entry::Lookup(control.address); 923 if (entry == NULL) 924 return B_ENTRY_NOT_FOUND; 925 if ((entry->flags & ARP_FLAG_LOCAL) != 0) 926 return B_BAD_VALUE; 927 928 entry->ScheduleRemoval(); 929 return B_OK; 930 } 931 932 case ARP_FLUSH_ENTRIES: 933 { 934 hash_iterator iterator; 935 hash_open(sCache, &iterator); 936 937 arp_entry *entry; 938 while ((entry = (arp_entry *)hash_next(sCache, &iterator)) != NULL) { 939 // we never flush local ARP entries 940 if ((entry->flags & ARP_FLAG_LOCAL) != 0) 941 continue; 942 943 entry->ScheduleRemoval(); 944 } 945 hash_close(sCache, &iterator, false); 946 return B_OK; 947 } 948 949 case ARP_IGNORE_REPLIES: 950 sIgnoreReplies = control.flags != 0; 951 return B_OK; 952 } 953 954 return B_BAD_VALUE; 955 } 956 957 958 static status_t 959 arp_init() 960 { 961 mutex_init(&sCacheLock, "arp cache"); 962 963 sCache = hash_init(64, offsetof(struct arp_entry, next), 964 &arp_entry::Compare, &arp_entry::Hash); 965 if (sCache == NULL) { 966 mutex_destroy(&sCacheLock); 967 return B_NO_MEMORY; 968 } 969 970 register_generic_syscall(ARP_SYSCALLS, arp_control, 1, 0); 971 return B_OK; 972 } 973 974 975 static status_t 976 arp_uninit() 977 { 978 unregister_generic_syscall(ARP_SYSCALLS, 1); 979 return B_OK; 980 } 981 982 983 // #pragma mark - net_datalink_protocol 984 985 986 status_t 987 arp_init_protocol(net_interface* interface, net_domain* domain, 988 net_datalink_protocol** _protocol) 989 { 990 // We currently only support a single family and type! 991 if (interface->device->type != IFT_ETHER 992 || domain->family != AF_INET) 993 return B_BAD_TYPE; 994 995 status_t status = sStackModule->register_device_handler(interface->device, 996 B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_ARP), &arp_receive, NULL); 997 if (status != B_OK) 998 return status; 999 1000 status = sStackModule->register_domain_device_handler( 1001 interface->device, B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_IP), domain); 1002 if (status != B_OK) 1003 return status; 1004 1005 arp_protocol* protocol = new(std::nothrow) arp_protocol; 1006 if (protocol == NULL) 1007 return B_NO_MEMORY; 1008 1009 memset(&protocol->hardware_address, 0, sizeof(sockaddr_dl)); 1010 protocol->local_address = 0; 1011 1012 *_protocol = protocol; 1013 return B_OK; 1014 } 1015 1016 1017 status_t 1018 arp_uninit_protocol(net_datalink_protocol *protocol) 1019 { 1020 sStackModule->unregister_device_handler(protocol->interface->device, 1021 B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_ARP)); 1022 sStackModule->unregister_device_handler(protocol->interface->device, 1023 B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_IP)); 1024 1025 delete protocol; 1026 return B_OK; 1027 } 1028 1029 1030 status_t 1031 arp_send_data(net_datalink_protocol *_protocol, net_buffer *buffer) 1032 { 1033 arp_protocol *protocol = (arp_protocol *)_protocol; 1034 { 1035 MutexLocker locker(sCacheLock); 1036 1037 // Set buffer target and destination address 1038 1039 memcpy(buffer->source, &protocol->hardware_address, 1040 protocol->hardware_address.sdl_len); 1041 1042 if ((buffer->flags & MSG_MCAST) != 0) { 1043 sockaddr_dl multicastDestination; 1044 ipv4_to_ether_multicast(&multicastDestination, 1045 (sockaddr_in *)buffer->destination); 1046 memcpy(buffer->destination, &multicastDestination, 1047 sizeof(multicastDestination)); 1048 } else if ((buffer->flags & MSG_BCAST) == 0) { 1049 // Lookup destination (we may need to wait for this) 1050 arp_entry *entry = arp_entry::Lookup( 1051 ((struct sockaddr_in *)buffer->destination)->sin_addr.s_addr); 1052 if (entry == NULL) { 1053 status_t status = arp_start_resolve(protocol, 1054 ((struct sockaddr_in*)buffer->destination)->sin_addr.s_addr, 1055 &entry); 1056 if (status != B_OK) 1057 return status; 1058 } 1059 1060 if ((entry->flags & ARP_FLAG_REJECT) != 0) 1061 return EHOSTUNREACH; 1062 1063 if ((entry->flags & ARP_FLAG_VALID) == 0) { 1064 // entry is still being resolved. 1065 TRACE(("ARP Queuing packet %p, entry still being resolved.\n", 1066 buffer)); 1067 entry->queue.Add(buffer); 1068 return B_OK; 1069 } 1070 1071 memcpy(buffer->destination, &entry->hardware_address, 1072 entry->hardware_address.sdl_len); 1073 } 1074 // the broadcast address is set in the ethernet frame module 1075 } 1076 TRACE(("%s(%p): from %s\n", __FUNCTION__, buffer, 1077 mac_to_string(LLADDR((sockaddr_dl*)buffer->source)))); 1078 TRACE((" to %s\n", 1079 mac_to_string(LLADDR((sockaddr_dl*)buffer->destination)))); 1080 1081 return protocol->next->module->send_data(protocol->next, buffer); 1082 } 1083 1084 1085 status_t 1086 arp_up(net_datalink_protocol* _protocol) 1087 { 1088 arp_protocol* protocol = (arp_protocol*)_protocol; 1089 status_t status = protocol->next->module->interface_up(protocol->next); 1090 if (status != B_OK) 1091 return status; 1092 1093 // cache this device's address for later use 1094 1095 status = arp_update_local(protocol); 1096 if (status != B_OK) { 1097 protocol->next->module->interface_down(protocol->next); 1098 return status; 1099 } 1100 1101 return B_OK; 1102 } 1103 1104 1105 void 1106 arp_down(net_datalink_protocol *protocol) 1107 { 1108 // remove local ARP entries from the cache 1109 arp_remove_local((arp_protocol*)protocol); 1110 1111 protocol->next->module->interface_down(protocol->next); 1112 } 1113 1114 1115 status_t 1116 arp_change_address(net_datalink_protocol* _protocol, 1117 net_interface_address* address, int32 option, 1118 const struct sockaddr* oldAddress, const struct sockaddr* newAddress) 1119 { 1120 arp_protocol* protocol = (arp_protocol*)_protocol; 1121 TRACE(("%s(option %" B_PRId32 ")\n", __FUNCTION__, option)); 1122 1123 switch (option) { 1124 case SIOCSIFADDR: 1125 case SIOCAIFADDR: 1126 case SIOCDIFADDR: 1127 // Those are the options we handle 1128 if ((protocol->interface->flags & IFF_UP) != 0) { 1129 // Update ARP entry for the local address 1130 1131 if (newAddress != NULL && newAddress->sa_family == AF_INET) { 1132 status_t status = arp_set_local_entry(protocol, newAddress); 1133 if (status != B_OK) 1134 return status; 1135 } 1136 1137 if (option != SIOCAIFADDR 1138 && (oldAddress == NULL || oldAddress->sa_family == AF_INET)) 1139 arp_remove_local_entry(protocol, oldAddress, address); 1140 } 1141 break; 1142 1143 default: 1144 break; 1145 } 1146 1147 return protocol->next->module->change_address(protocol->next, address, 1148 option, oldAddress, newAddress); 1149 } 1150 1151 1152 status_t 1153 arp_control(net_datalink_protocol *_protocol, int32 op, void *argument, 1154 size_t length) 1155 { 1156 arp_protocol* protocol = (arp_protocol*)_protocol; 1157 return protocol->next->module->control(protocol->next, op, argument, 1158 length); 1159 } 1160 1161 1162 static status_t 1163 arp_join_multicast(net_datalink_protocol *protocol, const sockaddr *address) 1164 { 1165 if (address->sa_family != AF_INET) 1166 return EINVAL; 1167 1168 sockaddr_dl multicastAddress; 1169 ipv4_to_ether_multicast(&multicastAddress, (const sockaddr_in *)address); 1170 1171 return protocol->next->module->join_multicast(protocol->next, 1172 (sockaddr *)&multicastAddress); 1173 } 1174 1175 1176 static status_t 1177 arp_leave_multicast(net_datalink_protocol *protocol, const sockaddr *address) 1178 { 1179 if (address->sa_family != AF_INET) 1180 return EINVAL; 1181 1182 sockaddr_dl multicastAddress; 1183 ipv4_to_ether_multicast(&multicastAddress, (const sockaddr_in *)address); 1184 1185 return protocol->next->module->leave_multicast(protocol->next, 1186 (sockaddr *)&multicastAddress); 1187 } 1188 1189 1190 static status_t 1191 arp_std_ops(int32 op, ...) 1192 { 1193 switch (op) { 1194 case B_MODULE_INIT: 1195 return arp_init(); 1196 case B_MODULE_UNINIT: 1197 return arp_uninit(); 1198 1199 default: 1200 return B_ERROR; 1201 } 1202 } 1203 1204 1205 static net_datalink_protocol_module_info sARPModule = { 1206 { 1207 "network/datalink_protocols/arp/v1", 1208 0, 1209 arp_std_ops 1210 }, 1211 arp_init_protocol, 1212 arp_uninit_protocol, 1213 arp_send_data, 1214 arp_up, 1215 arp_down, 1216 arp_change_address, 1217 arp_control, 1218 arp_join_multicast, 1219 arp_leave_multicast, 1220 }; 1221 1222 1223 module_dependency module_dependencies[] = { 1224 {NET_STACK_MODULE_NAME, (module_info**)&sStackModule}, 1225 {NET_DATALINK_MODULE_NAME, (module_info**)&sDatalinkModule}, 1226 {NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule}, 1227 {} 1228 }; 1229 1230 module_info* modules[] = { 1231 (module_info*)&sARPModule, 1232 NULL 1233 }; 1234