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