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