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