1 /* 2 * Copyright 2006, 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), hardwareAddress, ETHER_ADDRESS_LENGTH)) { 223 dprintf("ARP host %08lx updated with different hardware address %02x:%02x:%02x:%02x:%02x:%02x.\n", 224 protocolAddress, hardwareAddress->sdl_data[0] & 0xff, hardwareAddress->sdl_data[1] & 0xff, 225 hardwareAddress->sdl_data[2] & 0xff, hardwareAddress->sdl_data[3] & 0xff, 226 hardwareAddress->sdl_data[4] & 0xff, hardwareAddress->sdl_data[5] & 0xff); 227 return B_ERROR; 228 } 229 230 entry->hardware_address = *hardwareAddress; 231 entry->timestamp = system_time(); 232 } else { 233 entry = arp_entry::Add(protocolAddress, hardwareAddress, flags); 234 if (entry == NULL) 235 return B_NO_MEMORY; 236 } 237 238 // if someone was waiting for this ARP request to be resolved 239 if (entry->resolved_sem >= B_OK) { 240 delete_sem(entry->resolved_sem); 241 entry->resolved_sem = -1; 242 } 243 244 if (entry->request_buffer != NULL) { 245 gBufferModule->free(entry->request_buffer); 246 entry->request_buffer = NULL; 247 } 248 249 if ((entry->flags & ARP_FLAG_PERMANENT) == 0) { 250 // (re)start the stale timer 251 entry->timer_state = ARP_STATE_STALE; 252 sStackModule->set_timer(&entry->timer, ARP_STALE_TIMEOUT); 253 } 254 255 if (_entry) 256 *_entry = entry; 257 258 return B_OK; 259 } 260 261 262 static status_t 263 arp_update_local(net_datalink_protocol *protocol) 264 { 265 net_interface *interface = protocol->interface; 266 in_addr_t inetAddress; 267 268 if (interface->address == NULL) { 269 // interface has not yet been set 270 inetAddress = INADDR_ANY; 271 } else 272 inetAddress = ((sockaddr_in *)interface->address)->sin_addr.s_addr; 273 274 sockaddr_dl address; 275 address.sdl_len = sizeof(sockaddr_dl); 276 address.sdl_family = AF_DLI; 277 address.sdl_type = IFT_ETHER; 278 address.sdl_e_type = ETHER_TYPE_IP; 279 address.sdl_nlen = 0; 280 address.sdl_slen = 0; 281 address.sdl_alen = interface->device->address.length; 282 memcpy(LLADDR(&address), interface->device->address.data, address.sdl_alen); 283 284 arp_entry *entry; 285 status_t status = arp_update_entry(inetAddress, &address, 286 ARP_FLAG_LOCAL | ARP_FLAG_PERMANENT, &entry); 287 if (status == B_OK) 288 entry->protocol = protocol; 289 290 return status; 291 } 292 293 294 static status_t 295 handle_arp_request(net_buffer *buffer, arp_header &header) 296 { 297 BenaphoreLocker locker(sCacheLock); 298 299 if (!sIgnoreReplies) { 300 arp_update_entry(header.protocol_sender, (sockaddr_dl *)&buffer->source, 0); 301 // remember the address of the sender as we might need it later 302 } 303 304 // check if this request is for us 305 306 arp_entry *entry = arp_entry::Lookup(header.protocol_target); 307 if (entry == NULL || (entry->flags & (ARP_FLAG_LOCAL | ARP_FLAG_PUBLISH)) == 0) { 308 // We're not the one to answer this request 309 // TODO: instead of letting the other's request time-out, can we reply 310 // failure somehow? 311 TRACE((" not for us\n")); 312 return B_ERROR; 313 } 314 315 // send a reply (by reusing the buffer we got) 316 317 TRACE((" send reply!\n")); 318 header.opcode = htons(ARP_OPCODE_REPLY); 319 320 memcpy(header.hardware_target, header.hardware_sender, ETHER_ADDRESS_LENGTH); 321 header.protocol_target = header.protocol_sender; 322 memcpy(header.hardware_sender, LLADDR(&entry->hardware_address), ETHER_ADDRESS_LENGTH); 323 header.protocol_sender = entry->protocol_address; 324 325 // exchange source and destination address 326 memcpy(LLADDR((sockaddr_dl *)&buffer->source), header.hardware_sender, 327 ETHER_ADDRESS_LENGTH); 328 memcpy(LLADDR((sockaddr_dl *)&buffer->destination), header.hardware_target, 329 ETHER_ADDRESS_LENGTH); 330 331 buffer->flags = 0; 332 // make sure this won't be a broadcast message 333 334 return entry->protocol->next->module->send_data(entry->protocol->next, buffer); 335 } 336 337 338 static void 339 handle_arp_reply(net_buffer *buffer, arp_header &header) 340 { 341 if (sIgnoreReplies) 342 return; 343 344 BenaphoreLocker locker(sCacheLock); 345 arp_update_entry(header.protocol_sender, (sockaddr_dl *)&buffer->source, 0); 346 } 347 348 349 static status_t 350 arp_receive(void *cookie, net_buffer *buffer) 351 { 352 TRACE(("ARP receive\n")); 353 354 NetBufferHeader<arp_header> bufferHeader(buffer); 355 if (bufferHeader.Status() < B_OK) 356 return bufferHeader.Status(); 357 358 arp_header &header = bufferHeader.Data(); 359 uint16 opcode = ntohs(header.opcode); 360 361 #ifdef TRACE_ARP 362 dprintf(" hw sender: %02x:%02x:%02x:%02x:%02x:%02x\n", 363 header.hardware_sender[0], header.hardware_sender[1], header.hardware_sender[2], 364 header.hardware_sender[3], header.hardware_sender[4], header.hardware_sender[5]); 365 dprintf(" proto sender: %ld.%ld.%ld.%ld\n", header.protocol_sender >> 24, (header.protocol_sender >> 16) & 0xff, 366 (header.protocol_sender >> 8) & 0xff, header.protocol_sender & 0xff); 367 dprintf(" hw target: %02x:%02x:%02x:%02x:%02x:%02x\n", 368 header.hardware_target[0], header.hardware_target[1], header.hardware_target[2], 369 header.hardware_target[3], header.hardware_target[4], header.hardware_target[5]); 370 dprintf(" proto target: %ld.%ld.%ld.%ld\n", header.protocol_target >> 24, (header.protocol_target >> 16) & 0xff, 371 (header.protocol_target >> 8) & 0xff, header.protocol_target & 0xff); 372 #endif 373 374 if (ntohs(header.protocol_type) != ETHER_TYPE_IP 375 || ntohs(header.hardware_type) != ARP_HARDWARE_TYPE_ETHER) 376 return B_BAD_TYPE; 377 378 // check if the packet is okay 379 380 if (header.hardware_length != ETHER_ADDRESS_LENGTH 381 || header.protocol_length != sizeof(in_addr_t)) 382 return B_BAD_DATA; 383 384 bufferHeader.Detach(); 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 if (status == B_OK) { 784 // We also register the domain as a handler for deframed packets; 785 // while the ethernet_frame module is not really connected to our 786 // domain, we are. 787 status = sStackModule->register_domain_device_handler(interface->device, 788 ETHER_FRAME_TYPE | ETHER_TYPE_IP, interface->domain); 789 } 790 791 if (status < B_OK) 792 return status; 793 794 arp_protocol *protocol = new (std::nothrow) arp_protocol; 795 if (protocol == NULL) 796 return B_NO_MEMORY; 797 798 *_protocol = protocol; 799 return B_OK; 800 } 801 802 803 status_t 804 arp_uninit_protocol(net_datalink_protocol *protocol) 805 { 806 sStackModule->unregister_device_handler(protocol->interface->device, 807 ETHER_FRAME_TYPE | ETHER_TYPE_ARP); 808 sStackModule->unregister_device_handler(protocol->interface->device, 809 ETHER_FRAME_TYPE | ETHER_TYPE_IP); 810 811 delete protocol; 812 return B_OK; 813 } 814 815 816 status_t 817 arp_send_data(net_datalink_protocol *protocol, 818 net_buffer *buffer) 819 { 820 { 821 BenaphoreLocker locker(sCacheLock); 822 823 // Lookup source (us) 824 // TODO: this could be cached - the lookup isn't really needed at all 825 826 arp_entry *entry = arp_entry::Lookup( 827 ((struct sockaddr_in *)&buffer->source)->sin_addr.s_addr); 828 if (entry == NULL) 829 return B_ERROR; 830 831 memcpy(&buffer->source, &entry->hardware_address, 832 entry->hardware_address.sdl_len); 833 834 if ((buffer->flags & MSG_BCAST) == 0) { 835 // Lookup destination (we may need to wait for this) 836 entry = arp_entry::Lookup( 837 ((struct sockaddr_in *)&buffer->destination)->sin_addr.s_addr); 838 if (entry == NULL) { 839 // The ARP entry does not yet exist, if we're allowed to wait, 840 // we'll send an ARP request and try to change that. 841 if ((buffer->flags & MSG_DONTWAIT) != 0) { 842 // TODO: implement delaying packet send after ARP response! 843 return B_ERROR; 844 } 845 846 status_t status = arp_resolve(protocol, 847 ((struct sockaddr_in *)&buffer->destination)->sin_addr.s_addr, &entry); 848 if (status < B_OK) 849 return status; 850 } else { 851 // The entry exists, but we have to check if it has already been 852 // resolved and is valid. 853 status_t status = arp_check_resolved(&entry, buffer->flags); 854 if (status < B_OK) 855 return status; 856 } 857 858 memcpy(&buffer->destination, &entry->hardware_address, 859 entry->hardware_address.sdl_len); 860 } 861 } 862 863 return protocol->next->module->send_data(protocol->next, buffer); 864 } 865 866 867 status_t 868 arp_up(net_datalink_protocol *_protocol) 869 { 870 arp_protocol *protocol = (arp_protocol *)_protocol; 871 status_t status = protocol->next->module->interface_up(protocol->next); 872 if (status < B_OK) 873 return status; 874 875 // cache this device's address for later use 876 877 status = arp_update_local(protocol); 878 if (status < B_OK) { 879 protocol->next->module->interface_down(protocol->next); 880 return status; 881 } 882 883 return B_OK; 884 } 885 886 887 void 888 arp_down(net_datalink_protocol *protocol) 889 { 890 // remove local ARP entry from the cache 891 892 if (protocol->interface->address != NULL) { 893 BenaphoreLocker locker(sCacheLock); 894 895 arp_entry *entry = arp_entry::Lookup( 896 ((sockaddr_in *)protocol->interface->address)->sin_addr.s_addr); 897 if (entry != NULL) { 898 hash_remove(sCache, entry); 899 delete entry; 900 } 901 } 902 903 protocol->next->module->interface_down(protocol->next); 904 } 905 906 907 status_t 908 arp_control(net_datalink_protocol *protocol, 909 int32 op, void *argument, size_t length) 910 { 911 if (op == SIOCSIFADDR && (protocol->interface->flags & IFF_UP) != 0) { 912 // The interface may get a new address, so we need to update our 913 // local entries. 914 bool hasOldAddress = false; 915 in_addr_t oldAddress = 0; 916 if (protocol->interface->address != NULL) { 917 oldAddress = ((sockaddr_in *)protocol->interface->address)->sin_addr.s_addr; 918 hasOldAddress = true; 919 } 920 921 status_t status = protocol->next->module->control(protocol->next, 922 SIOCSIFADDR, argument, length); 923 if (status < B_OK) 924 return status; 925 926 arp_update_local(protocol); 927 928 if (oldAddress == ((sockaddr_in *)protocol->interface->address)->sin_addr.s_addr 929 || !hasOldAddress) 930 return B_OK; 931 932 // remove previous address from cache 933 // TODO: we should be able to do this (add/remove) in one atomic operation! 934 935 BenaphoreLocker locker(sCacheLock); 936 937 arp_entry *entry = arp_entry::Lookup(oldAddress); 938 if (entry != NULL) { 939 hash_remove(sCache, entry); 940 delete entry; 941 } 942 943 return B_OK; 944 } 945 946 return protocol->next->module->control(protocol->next, 947 op, argument, length); 948 } 949 950 951 static status_t 952 arp_std_ops(int32 op, ...) 953 { 954 switch (op) { 955 case B_MODULE_INIT: 956 return arp_init(); 957 case B_MODULE_UNINIT: 958 return arp_uninit(); 959 960 default: 961 return B_ERROR; 962 } 963 } 964 965 966 static net_datalink_protocol_module_info sARPModule = { 967 { 968 "network/datalink_protocols/arp/v1", 969 0, 970 arp_std_ops 971 }, 972 arp_init_protocol, 973 arp_uninit_protocol, 974 arp_send_data, 975 arp_up, 976 arp_down, 977 arp_control, 978 }; 979 980 module_info *modules[] = { 981 (module_info *)&sARPModule, 982 NULL 983 }; 984