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