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