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