1 /* 2 * Copyright 2006-2010, 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 * Atis Elsts, the.kfx@gmail.com 8 */ 9 10 11 #include "ipv6_address.h" 12 #include "ipv6_utils.h" 13 #include "multicast.h" 14 #include "../../stack/domains.h" 15 16 #include <net_datalink.h> 17 #include <net_datalink_protocol.h> 18 #include <net_device.h> 19 #include <net_protocol.h> 20 #include <net_stack.h> 21 #include <NetBufferUtilities.h> 22 #include <ProtocolUtilities.h> 23 24 #include <ByteOrder.h> 25 #include <KernelExport.h> 26 #include <util/AutoLock.h> 27 #include <util/list.h> 28 #include <util/DoublyLinkedList.h> 29 #include <util/MultiHashTable.h> 30 31 #include <netinet6/in6.h> 32 #include <netinet/ip6.h> 33 #include <netinet/icmp6.h> 34 #include <new> 35 #include <stdlib.h> 36 #include <stdio.h> 37 #include <string.h> 38 #include <utility> 39 40 41 #define TRACE_IPV6 42 #ifdef TRACE_IPV6 43 # define TRACE(format, args...) \ 44 dprintf("IPv6 [%llu] " format "\n", system_time() , ##args) 45 # define TRACE_SK(protocol, format, args...) \ 46 dprintf("IPv6 [%llu] %p " format "\n", system_time(), \ 47 protocol , ##args) 48 #else 49 # define TRACE(args...) do { } while (0) 50 # define TRACE_SK(args...) do { } while (0) 51 #endif 52 53 54 struct IPv6Header { 55 struct ip6_hdr header; 56 57 uint8 ProtocolVersion() const { return header.ip6_vfc & IPV6_VERSION_MASK; } 58 uint8 ServiceType() const { return ntohl(header.ip6_flow) >> 20;} 59 uint16 PayloadLength() const { return ntohs(header.ip6_plen); } 60 const in6_addr& Dst() const { return header.ip6_dst; } 61 const in6_addr& Src() const { return header.ip6_src; } 62 uint16 GetTransportHeaderOffset(net_buffer* buffer) const; 63 }; 64 65 class RawSocket 66 : public DoublyLinkedListLinkImpl<RawSocket>, public DatagramSocket<> { 67 public: 68 RawSocket(net_socket* socket); 69 }; 70 71 typedef DoublyLinkedList<RawSocket> RawSocketList; 72 73 74 typedef MulticastGroupInterface<IPv6Multicast> IPv6GroupInterface; 75 typedef MulticastFilter<IPv6Multicast> IPv6MulticastFilter; 76 77 struct MulticastStateHash { 78 typedef std::pair<const in6_addr*, uint32> KeyType; 79 typedef IPv6GroupInterface ValueType; 80 81 size_t HashKey(const KeyType &key) const; 82 size_t Hash(ValueType* value) const 83 { return HashKey(std::make_pair(&value->Address(), 84 value->Interface()->index)); } 85 bool Compare(const KeyType &key, ValueType* value) const 86 { return value->Interface()->index == key.second 87 && value->Address() == *key.first; } 88 bool CompareValues(ValueType* value1, ValueType* value2) const 89 { return value1->Interface()->index == value2->Interface()->index 90 && value1->Address() == value2->Address(); } 91 ValueType*& GetLink(ValueType* value) const { return value->HashLink(); } 92 }; 93 94 95 struct ipv6_protocol : net_protocol { 96 ipv6_protocol() 97 : 98 multicast_filter(this) 99 { 100 } 101 102 RawSocket *raw; 103 uint8 service_type; 104 uint8 time_to_live; 105 uint8 multicast_time_to_live; 106 uint8 receive_hoplimit; 107 uint8 receive_pktinfo; 108 struct sockaddr* interface_address; // for IPV6_MULTICAST_IF 109 110 IPv6MulticastFilter multicast_filter; 111 }; 112 113 114 static const int kDefaultTTL = 254; 115 static const int kDefaultMulticastTTL = 1; 116 117 118 extern net_protocol_module_info gIPv6Module; 119 // we need this in ipv6_std_ops() for registering the AF_INET domain 120 121 net_stack_module_info* gStackModule; 122 net_buffer_module_info* gBufferModule; 123 124 static struct net_domain* sDomain; 125 static net_datalink_module_info* sDatalinkModule; 126 static net_socket_module_info* sSocketModule; 127 static RawSocketList sRawSockets; 128 static mutex sRawSocketsLock; 129 static mutex sMulticastGroupsLock; 130 131 typedef MultiHashTable<MulticastStateHash> MulticastState; 132 static MulticastState* sMulticastState; 133 134 static net_protocol_module_info* sReceivingProtocol[256]; 135 static mutex sReceivingProtocolLock; 136 137 138 uint16 139 IPv6Header::GetTransportHeaderOffset(net_buffer* buffer) const 140 { 141 uint16 offset = sizeof(struct ip6_hdr); 142 uint8 next = header.ip6_nxt; 143 144 // these are the extension headers that might be supported one day 145 while (next == IPPROTO_HOPOPTS 146 || next == IPPROTO_ROUTING 147 || next == IPPROTO_FRAGMENT 148 || next == IPPROTO_ESP 149 || next == IPPROTO_AH 150 || next == IPPROTO_DSTOPTS) { 151 struct ip6_ext extensionHeader; 152 status_t status = gBufferModule->read(buffer, offset, 153 &extensionHeader, sizeof(ip6_ext)); 154 if (status != B_OK) 155 break; 156 157 next = extensionHeader.ip6e_nxt; 158 offset += extensionHeader.ip6e_len; 159 } 160 161 buffer->protocol = next; 162 return offset; 163 } 164 165 166 RawSocket::RawSocket(net_socket* socket) 167 : 168 DatagramSocket<>("ipv6 raw socket", socket) 169 { 170 } 171 172 173 size_t 174 MulticastStateHash::HashKey(const KeyType &key) const 175 { 176 size_t result = 0; 177 result = jenkins_hashword((const uint32*)&key.first, 178 sizeof(in6_addr) / sizeof(uint32), result); 179 result = jenkins_hashword(&key.second, 1, result); 180 return result; 181 } 182 183 184 // #pragma mark - 185 186 187 static inline void 188 dump_ipv6_header(IPv6Header &header) 189 { 190 #ifdef TRACE_IPV6 191 char addrbuf[INET6_ADDRSTRLEN]; 192 dprintf(" version: %d\n", header.ProtocolVersion() >> 4); 193 dprintf(" service_type: %d\n", header.ServiceType()); 194 dprintf(" payload_length: %d\n", header.PayloadLength()); 195 dprintf(" next_header: %d\n", header.header.ip6_nxt); 196 dprintf(" hop_limit: %d\n", header.header.ip6_hops); 197 dprintf(" source: %s\n", ip6_sprintf(&header.header.ip6_src, addrbuf)); 198 dprintf(" destination: %s\n", 199 ip6_sprintf(&header.header.ip6_dst, addrbuf)); 200 #endif 201 } 202 203 204 static status_t 205 deliver_multicast(net_protocol_module_info* module, net_buffer* buffer, 206 bool deliverToRaw, net_interface *interface) 207 { 208 sockaddr_in6* multicastAddr = (sockaddr_in6*)buffer->destination; 209 210 MulticastState::ValueIterator it = sMulticastState->Lookup(std::make_pair( 211 &multicastAddr->sin6_addr, interface->index)); 212 213 while (it.HasNext()) { 214 IPv6GroupInterface* state = it.Next(); 215 ipv6_protocol* ipproto = state->Parent()->Socket(); 216 217 if (deliverToRaw && ipproto->raw == NULL) 218 continue; 219 220 if (state->FilterAccepts(buffer)) { 221 // TODO: do as in IPv4 code 222 module->deliver_data(ipproto, buffer); 223 } 224 } 225 226 return B_OK; 227 } 228 229 230 static status_t 231 deliver_multicast(net_protocol_module_info* module, net_buffer* buffer, 232 bool deliverToRaw) 233 { 234 if (module->deliver_data == NULL) 235 return B_OK; 236 237 MutexLocker _(sMulticastGroupsLock); 238 239 status_t status = B_OK; 240 if (buffer->interface) { 241 status = deliver_multicast(module, buffer, deliverToRaw, 242 buffer->interface); 243 } else { 244 // REVIEWME: does this look ok? 245 net_domain_private* domain = (net_domain_private*)sDomain; 246 RecursiveLocker locker(domain->lock); 247 248 net_interface* interface = NULL; 249 while (true) { 250 interface = (net_interface*)list_get_next_item( 251 &domain->interfaces, interface); 252 if (interface == NULL) 253 break; 254 255 status = deliver_multicast(module, buffer, deliverToRaw, interface); 256 if (status < B_OK) 257 break; 258 } 259 } 260 return status; 261 } 262 263 264 static void 265 raw_receive_data(net_buffer* buffer) 266 { 267 MutexLocker locker(sRawSocketsLock); 268 269 if (sRawSockets.IsEmpty()) 270 return; 271 272 TRACE("RawReceiveData(%i)", buffer->protocol); 273 274 if ((buffer->flags & MSG_MCAST) != 0) { 275 deliver_multicast(&gIPv6Module, buffer, true); 276 } else { 277 RawSocketList::Iterator iterator = sRawSockets.GetIterator(); 278 279 while (iterator.HasNext()) { 280 RawSocket* raw = iterator.Next(); 281 282 if (raw->Socket()->protocol == buffer->protocol) 283 raw->SocketEnqueue(buffer); 284 } 285 } 286 } 287 288 289 static inline sockaddr* 290 fill_sockaddr_in6(sockaddr_in6* target, const in6_addr &address) 291 { 292 target->sin6_family = AF_INET6; 293 target->sin6_len = sizeof(sockaddr_in6); 294 target->sin6_port = 0; 295 target->sin6_flowinfo = 0; 296 memcpy(target->sin6_addr.s6_addr, address.s6_addr, sizeof(in6_addr)); 297 target->sin6_scope_id = 0; 298 return (sockaddr*)target; 299 } 300 301 302 status_t 303 IPv6Multicast::JoinGroup(IPv6GroupInterface* state) 304 { 305 MutexLocker _(sMulticastGroupsLock); 306 307 sockaddr_in6 groupAddr; 308 net_interface* interface = state->Interface(); 309 310 status_t status = interface->first_info->join_multicast( 311 interface->first_protocol, 312 fill_sockaddr_in6(&groupAddr, state->Address())); 313 if (status != B_OK) 314 return status; 315 316 sMulticastState->Insert(state); 317 return B_OK; 318 } 319 320 321 status_t 322 IPv6Multicast::LeaveGroup(IPv6GroupInterface* state) 323 { 324 MutexLocker _(sMulticastGroupsLock); 325 326 sMulticastState->Remove(state); 327 328 sockaddr_in6 groupAddr; 329 net_interface* interface = state->Interface(); 330 331 return interface->first_protocol->module->join_multicast( 332 interface->first_protocol, 333 fill_sockaddr_in6(&groupAddr, state->Address())); 334 } 335 336 337 static net_protocol_module_info* 338 receiving_protocol(uint8 protocol) 339 { 340 net_protocol_module_info* module = sReceivingProtocol[protocol]; 341 if (module != NULL) 342 return module; 343 344 MutexLocker locker(sReceivingProtocolLock); 345 346 module = sReceivingProtocol[protocol]; 347 if (module != NULL) 348 return module; 349 350 if (gStackModule->get_domain_receiving_protocol(sDomain, protocol, 351 &module) == B_OK) 352 sReceivingProtocol[protocol] = module; 353 354 return module; 355 } 356 357 358 static status_t 359 ipv6_delta_group(IPv6GroupInterface* group, int option, 360 net_interface* interface, const in6_addr* sourceAddr) 361 { 362 switch (option) { 363 case IPV6_JOIN_GROUP: 364 return group->Add(); 365 case IPV6_LEAVE_GROUP: 366 return group->Drop(); 367 } 368 369 return B_ERROR; 370 } 371 372 373 static status_t 374 ipv6_delta_membership(ipv6_protocol* protocol, int option, 375 net_interface* interface, const in6_addr* groupAddr, 376 const in6_addr* sourceAddr) 377 { 378 IPv6MulticastFilter &filter = protocol->multicast_filter; 379 IPv6GroupInterface* state = NULL; 380 status_t status = B_OK; 381 382 switch (option) { 383 // TODO: support more options 384 case IPV6_JOIN_GROUP: 385 status = filter.GetState(*groupAddr, interface, state, true); 386 break; 387 388 case IPV6_LEAVE_GROUP: 389 filter.GetState(*groupAddr, interface, state, false); 390 if (state == NULL) 391 return EADDRNOTAVAIL; 392 break; 393 } 394 395 if (status != B_OK) 396 return status; 397 398 status = ipv6_delta_group(state, option, interface, sourceAddr); 399 filter.ReturnState(state); 400 return status; 401 } 402 403 404 static status_t 405 ipv6_delta_membership(ipv6_protocol* protocol, int option, 406 uint32 interfaceIndex, in6_addr* groupAddr, in6_addr* sourceAddr) 407 { 408 net_interface* interface; 409 410 // TODO: can the interface be unspecified? 411 interface = sDatalinkModule->get_interface(sDomain, interfaceIndex); 412 413 if (interface == NULL) 414 return B_DEVICE_NOT_FOUND; 415 416 return ipv6_delta_membership(protocol, option, interface, 417 groupAddr, sourceAddr); 418 } 419 420 421 static status_t 422 get_int_option(void* target, size_t length, int value) 423 { 424 if (length != sizeof(int)) 425 return B_BAD_VALUE; 426 427 return user_memcpy(target, &value, sizeof(int)); 428 } 429 430 431 template<typename Type> static status_t 432 set_int_option(Type &target, const void* _value, size_t length) 433 { 434 int value; 435 436 if (length != sizeof(int)) 437 return B_BAD_VALUE; 438 439 if (user_memcpy(&value, _value, sizeof(int)) != B_OK) 440 return B_BAD_ADDRESS; 441 442 target = value; 443 return B_OK; 444 } 445 446 447 // #pragma mark - 448 449 450 net_protocol* 451 ipv6_init_protocol(net_socket* socket) 452 { 453 ipv6_protocol* protocol = new (std::nothrow) ipv6_protocol(); 454 if (protocol == NULL) 455 return NULL; 456 457 protocol->raw = NULL; 458 protocol->service_type = 0; 459 protocol->time_to_live = kDefaultTTL; 460 protocol->multicast_time_to_live = kDefaultMulticastTTL; 461 protocol->receive_hoplimit = 0; 462 protocol->receive_pktinfo = 0; 463 protocol->interface_address = NULL; 464 return protocol; 465 } 466 467 468 status_t 469 ipv6_uninit_protocol(net_protocol* _protocol) 470 { 471 ipv6_protocol* protocol = (ipv6_protocol*)_protocol; 472 473 delete protocol->raw; 474 delete protocol->interface_address; 475 delete protocol; 476 return B_OK; 477 } 478 479 480 /*! Since open() is only called on the top level protocol, when we get here 481 it means we are on a SOCK_RAW socket. 482 */ 483 status_t 484 ipv6_open(net_protocol* _protocol) 485 { 486 ipv6_protocol* protocol = (ipv6_protocol*)_protocol; 487 488 RawSocket* raw = new (std::nothrow) RawSocket(protocol->socket); 489 if (raw == NULL) 490 return B_NO_MEMORY; 491 492 status_t status = raw->InitCheck(); 493 if (status != B_OK) { 494 delete raw; 495 return status; 496 } 497 498 TRACE_SK(protocol, "Open()"); 499 500 protocol->raw = raw; 501 502 MutexLocker locker(sRawSocketsLock); 503 sRawSockets.Add(raw); 504 return B_OK; 505 } 506 507 508 status_t 509 ipv6_close(net_protocol* _protocol) 510 { 511 ipv6_protocol* protocol = (ipv6_protocol*)_protocol; 512 RawSocket* raw = protocol->raw; 513 if (raw == NULL) 514 return B_ERROR; 515 516 TRACE_SK(protocol, "Close()"); 517 518 MutexLocker locker(sRawSocketsLock); 519 sRawSockets.Remove(raw); 520 delete raw; 521 protocol->raw = NULL; 522 523 return B_OK; 524 } 525 526 527 status_t 528 ipv6_free(net_protocol* protocol) 529 { 530 return B_OK; 531 } 532 533 534 status_t 535 ipv6_connect(net_protocol* protocol, const struct sockaddr* address) 536 { 537 return B_ERROR; 538 } 539 540 541 status_t 542 ipv6_accept(net_protocol* protocol, struct net_socket** _acceptedSocket) 543 { 544 return EOPNOTSUPP; 545 } 546 547 548 status_t 549 ipv6_control(net_protocol* _protocol, int level, int option, void* value, 550 size_t* _length) 551 { 552 if ((level & LEVEL_MASK) != IPPROTO_IPV6) 553 return sDatalinkModule->control(sDomain, option, value, _length); 554 555 return B_BAD_VALUE; 556 } 557 558 559 status_t 560 ipv6_getsockopt(net_protocol* _protocol, int level, int option, void* value, 561 int* _length) 562 { 563 ipv6_protocol* protocol = (ipv6_protocol*)_protocol; 564 565 if (level == IPPROTO_IPV6) { 566 // TODO: support more of these options 567 568 if (option == IPV6_MULTICAST_HOPS) { 569 return get_int_option(value, *_length, 570 protocol->multicast_time_to_live); 571 } 572 if (option == IPV6_MULTICAST_LOOP) 573 return EOPNOTSUPP; 574 if (option == IPV6_UNICAST_HOPS) 575 return get_int_option(value, *_length, protocol->time_to_live); 576 if (option == IPV6_V6ONLY) 577 return EOPNOTSUPP; 578 if (option == IPV6_RECVPKTINFO) 579 return get_int_option(value, *_length, protocol->receive_pktinfo); 580 if (option == IPV6_RECVHOPLIMIT) 581 return get_int_option(value, *_length, protocol->receive_hoplimit); 582 if (option == IPV6_JOIN_GROUP 583 || option == IPV6_LEAVE_GROUP) 584 return EOPNOTSUPP; 585 586 dprintf("IPv6::getsockopt(): get unknown option: %d\n", option); 587 return ENOPROTOOPT; 588 } 589 590 return sSocketModule->get_option(protocol->socket, level, option, value, 591 _length); 592 } 593 594 595 status_t 596 ipv6_setsockopt(net_protocol* _protocol, int level, int option, 597 const void* value, int length) 598 { 599 ipv6_protocol* protocol = (ipv6_protocol*)_protocol; 600 601 if (level == IPPROTO_IPV6) { 602 // TODO: support more of these options 603 604 if (option == IPV6_MULTICAST_IF) { 605 if (length != sizeof(struct in6_addr)) 606 return B_BAD_VALUE; 607 608 struct sockaddr_in6* address = new (std::nothrow) sockaddr_in6; 609 if (address == NULL) 610 return B_NO_MEMORY; 611 612 if (user_memcpy(&address->sin6_addr, value, sizeof(in6_addr)) 613 != B_OK) { 614 delete address; 615 return B_BAD_ADDRESS; 616 } 617 618 // Using the unspecifed address to remove the previous setting. 619 if (IN6_IS_ADDR_UNSPECIFIED(&address->sin6_addr)) { 620 delete address; 621 delete protocol->interface_address; 622 protocol->interface_address = NULL; 623 return B_OK; 624 } 625 626 struct net_interface* interface 627 = sDatalinkModule->get_interface_with_address(sDomain, 628 (struct sockaddr*)address); 629 if (interface == NULL) { 630 delete address; 631 return EADDRNOTAVAIL; 632 } 633 634 delete protocol->interface_address; 635 protocol->interface_address = (struct sockaddr*)address; 636 return B_OK; 637 } 638 if (option == IPV6_MULTICAST_HOPS) { 639 return set_int_option(protocol->multicast_time_to_live, 640 value, length); 641 } 642 if (option == IPV6_MULTICAST_LOOP) 643 return EOPNOTSUPP; 644 if (option == IPV6_UNICAST_HOPS) 645 return set_int_option(protocol->time_to_live, value, length); 646 if (option == IPV6_V6ONLY) 647 return EOPNOTSUPP; 648 if (option == IPV6_RECVPKTINFO) 649 return set_int_option(protocol->receive_pktinfo, value, length); 650 if (option == IPV6_RECVHOPLIMIT) 651 return set_int_option(protocol->receive_hoplimit, value, length); 652 if (option == IPV6_JOIN_GROUP || option == IPV6_LEAVE_GROUP) { 653 ipv6_mreq mreq; 654 if (length != sizeof(ipv6_mreq)) 655 return B_BAD_VALUE; 656 if (user_memcpy(&mreq, value, sizeof(ipv6_mreq)) != B_OK) 657 return B_BAD_ADDRESS; 658 659 return ipv6_delta_membership(protocol, option, mreq.ipv6mr_interface, 660 &mreq.ipv6mr_multiaddr, NULL); 661 } 662 663 dprintf("IPv6::setsockopt(): set unknown option: %d\n", option); 664 return ENOPROTOOPT; 665 } 666 667 return sSocketModule->set_option(protocol->socket, level, option, 668 value, length); 669 } 670 671 672 status_t 673 ipv6_bind(net_protocol* protocol, const sockaddr* _address) 674 { 675 if (_address->sa_family != AF_INET6) 676 return EAFNOSUPPORT; 677 678 const sockaddr_in6* address = (const sockaddr_in6*)_address; 679 680 // only INADDR_ANY and addresses of local interfaces are accepted: 681 if (IN6_IS_ADDR_UNSPECIFIED(&address->sin6_addr) 682 || IN6_IS_ADDR_MULTICAST(&address->sin6_addr) 683 || sDatalinkModule->is_local_address(sDomain, _address, NULL, NULL)) { 684 memcpy(&protocol->socket->address, address, sizeof(sockaddr_in6)); 685 protocol->socket->address.ss_len = sizeof(sockaddr_in6); 686 // explicitly set length, as our callers can't be trusted to 687 // always provide the correct length! 688 return B_OK; 689 } 690 691 return B_ERROR; 692 // address is unknown on this host 693 } 694 695 696 status_t 697 ipv6_unbind(net_protocol* protocol, struct sockaddr* address) 698 { 699 // nothing to do here 700 return B_OK; 701 } 702 703 704 status_t 705 ipv6_listen(net_protocol* protocol, int count) 706 { 707 return EOPNOTSUPP; 708 } 709 710 711 status_t 712 ipv6_shutdown(net_protocol* protocol, int direction) 713 { 714 return EOPNOTSUPP; 715 } 716 717 718 static uint8 719 ip6_select_hoplimit(net_protocol* _protocol, net_buffer* buffer) 720 { 721 // TODO: the precedence should be as follows: 722 // 1. Hoplimit value specified via ioctl. 723 // 2. (If the outgoing interface is detected) the current 724 // hop limit of the interface specified by router advertisement. 725 // 3. The system default hoplimit. 726 727 ipv6_protocol* protocol = (ipv6_protocol*)_protocol; 728 const bool isMulticast = buffer->flags & MSG_MCAST; 729 730 if (protocol) { 731 return isMulticast ? protocol->multicast_time_to_live 732 : protocol->time_to_live; 733 } 734 return isMulticast ? kDefaultMulticastTTL : kDefaultTTL; 735 } 736 737 738 status_t 739 ipv6_send_routed_data(net_protocol* _protocol, struct net_route* route, 740 net_buffer* buffer) 741 { 742 if (route == NULL) 743 return B_BAD_VALUE; 744 745 ipv6_protocol* protocol = (ipv6_protocol*)_protocol; 746 net_interface* interface = route->interface; 747 uint8 protocolNumber; 748 if (protocol != NULL && protocol->socket != NULL) 749 protocolNumber = protocol->socket->protocol; 750 else 751 protocolNumber = buffer->protocol; 752 753 TRACE_SK(protocol, "SendRoutedData(%p, %p [%ld bytes])", route, buffer, 754 buffer->size); 755 756 sockaddr_in6& source = *(sockaddr_in6*)buffer->source; 757 sockaddr_in6& destination = *(sockaddr_in6*)buffer->destination; 758 759 buffer->flags &= ~(MSG_BCAST | MSG_MCAST); 760 761 if (IN6_IS_ADDR_UNSPECIFIED(&destination.sin6_addr)) 762 return EDESTADDRREQ; 763 764 if (IN6_IS_ADDR_MULTICAST(&destination.sin6_addr)) 765 buffer->flags |= MSG_MCAST; 766 767 uint16 dataLength = buffer->size; 768 769 // Add IPv6 header 770 771 NetBufferPrepend<ip6_hdr> header(buffer); 772 if (header.Status() != B_OK) 773 return header.Status(); 774 775 if (buffer->size > 0xffff) 776 return EMSGSIZE; 777 778 uint32 flowinfo = 0; 779 // TODO: fill in the flow id from somewhere 780 if (protocol) { 781 // fill in traffic class 782 flowinfo |= htonl(protocol->service_type << 20); 783 } 784 // set lower 28 bits 785 header->ip6_flow = htonl(flowinfo) & IPV6_FLOWINFO_MASK; 786 // set upper 4 bits 787 header->ip6_vfc |= IPV6_VERSION; 788 header->ip6_plen = htons(dataLength); 789 header->ip6_nxt = protocolNumber; 790 header->ip6_hlim = ip6_select_hoplimit(protocol, buffer); 791 memcpy(&header->ip6_src, &source.sin6_addr, sizeof(in6_addr)); 792 memcpy(&header->ip6_dst, &destination.sin6_addr, sizeof(in6_addr)); 793 794 header.Sync(); 795 796 // write the checksum for ICMPv6 sockets 797 if (protocolNumber == IPPROTO_ICMPV6 798 && dataLength >= sizeof(struct icmp6_hdr)) { 799 NetBufferField<uint16, 800 sizeof(ip6_hdr) + offsetof(icmp6_hdr, icmp6_cksum)> 801 icmpChecksum(buffer); 802 // first make sure the existing checksum is zero 803 *icmpChecksum = 0; 804 icmpChecksum.Sync(); 805 806 uint16 checksum = gBufferModule->checksum(buffer, sizeof(ip6_hdr), 807 buffer->size - sizeof(ip6_hdr), false); 808 checksum = ipv6_checksum(&header->ip6_src, 809 &header->ip6_dst, dataLength, protocolNumber, 810 checksum); 811 *icmpChecksum = checksum; 812 } 813 814 char addrbuf[INET6_ADDRSTRLEN]; 815 TRACE_SK(protocol, " SendRoutedData(): destination: %s", 816 ip6_sprintf(&destination.sin6_addr, addrbuf)); 817 818 uint32 mtu = route->mtu ? route->mtu : interface->mtu; 819 if (buffer->size > mtu) { 820 // we need to fragment the packet 821 return EMSGSIZE; // TODO 822 //return send_fragments(protocol, route, buffer, mtu); 823 } 824 825 return sDatalinkModule->send_data(route, buffer); 826 } 827 828 829 status_t 830 ipv6_send_data(net_protocol* _protocol, net_buffer* buffer) 831 { 832 ipv6_protocol* protocol = (ipv6_protocol*)_protocol; 833 834 TRACE_SK(protocol, "SendData(%p [%ld bytes])", buffer, buffer->size); 835 836 sockaddr_in6* destination = (sockaddr_in6*)buffer->destination; 837 838 // handle IPV6_MULTICAST_IF 839 if (IN6_IS_ADDR_MULTICAST(&destination->sin6_addr) 840 && protocol->interface_address != NULL) { 841 net_interface* interface 842 = sDatalinkModule->get_interface_with_address(sDomain, 843 protocol->interface_address); 844 if (interface == NULL || (interface->flags & IFF_UP) == 0) 845 return EADDRNOTAVAIL; 846 847 buffer->interface = interface; 848 849 net_route* route = sDatalinkModule->get_route(sDomain, 850 interface->address); 851 if (route == NULL) 852 return ENETUNREACH; 853 854 return sDatalinkModule->send_data(route, buffer); 855 } 856 857 return sDatalinkModule->send_datagram(protocol, sDomain, buffer); 858 } 859 860 861 ssize_t 862 ipv6_send_avail(net_protocol* protocol) 863 { 864 return B_ERROR; 865 } 866 867 868 status_t 869 ipv6_read_data(net_protocol* _protocol, size_t numBytes, uint32 flags, 870 net_buffer** _buffer) 871 { 872 ipv6_protocol* protocol = (ipv6_protocol*)_protocol; 873 RawSocket* raw = protocol->raw; 874 if (raw == NULL) 875 return B_ERROR; 876 877 TRACE_SK(protocol, "ReadData(%lu, 0x%lx)", numBytes, flags); 878 879 return raw->SocketDequeue(flags, _buffer); 880 } 881 882 883 ssize_t 884 ipv6_read_avail(net_protocol* _protocol) 885 { 886 ipv6_protocol* protocol = (ipv6_protocol*)_protocol; 887 RawSocket* raw = protocol->raw; 888 if (raw == NULL) 889 return B_ERROR; 890 891 return raw->AvailableData(); 892 } 893 894 895 struct net_domain* 896 ipv6_get_domain(net_protocol* protocol) 897 { 898 return sDomain; 899 } 900 901 902 size_t 903 ipv6_get_mtu(net_protocol* protocol, const struct sockaddr* address) 904 { 905 net_route* route = sDatalinkModule->get_route(sDomain, address); 906 if (route == NULL) 907 return 0; 908 909 size_t mtu; 910 if (route->mtu != 0) 911 mtu = route->mtu; 912 else 913 mtu = route->interface->mtu; 914 915 sDatalinkModule->put_route(sDomain, route); 916 // TODO: what about extension headers? 917 // this function probably shoud be changed in calling places, not here 918 return mtu - sizeof(ip6_hdr); 919 } 920 921 922 status_t 923 ipv6_receive_data(net_buffer* buffer) 924 { 925 TRACE("ReceiveData(%p [%ld bytes])", buffer, buffer->size); 926 927 NetBufferHeaderReader<IPv6Header> bufferHeader(buffer); 928 if (bufferHeader.Status() != B_OK) 929 return bufferHeader.Status(); 930 931 IPv6Header &header = bufferHeader.Data(); 932 // dump_ipv6_header(header); 933 934 if (header.ProtocolVersion() != IPV6_VERSION) 935 return B_BAD_TYPE; 936 937 uint16 packetLength = header.PayloadLength() + sizeof(ip6_hdr); 938 if (packetLength > buffer->size) 939 return B_BAD_DATA; 940 941 // lower layers notion of Broadcast or Multicast have no relevance to us 942 buffer->flags &= ~(MSG_BCAST | MSG_MCAST); 943 944 sockaddr_in6 destination; 945 fill_sockaddr_in6(&destination, header.Dst()); 946 947 if (IN6_IS_ADDR_MULTICAST(&destination.sin6_addr)) { 948 buffer->flags |= MSG_MCAST; 949 } else { 950 // test if the packet is really for us 951 if (!sDatalinkModule->is_local_address(sDomain, (sockaddr*)&destination, 952 &buffer->interface, NULL) 953 && !sDatalinkModule->is_local_link_address(sDomain, true, 954 buffer->destination, &buffer->interface)) { 955 char srcbuf[INET6_ADDRSTRLEN]; 956 char dstbuf[INET6_ADDRSTRLEN]; 957 TRACE(" ReceiveData(): packet was not for us %s -> %s", 958 ip6_sprintf(&header.Src(), srcbuf), 959 ip6_sprintf(&header.Dst(), dstbuf)); 960 return B_ERROR; 961 } 962 } 963 964 // set net_buffer's source/destination address 965 fill_sockaddr_in6((struct sockaddr_in6*)buffer->source, header.Src()); 966 memcpy(buffer->destination, &destination, sizeof(sockaddr_in6)); 967 968 // get the transport protocol and transport header offset 969 uint16 transportHeaderOffset = header.GetTransportHeaderOffset(buffer); 970 uint8 protocol = buffer->protocol; 971 972 // remove any trailing/padding data 973 status_t status = gBufferModule->trim(buffer, packetLength); 974 if (status != B_OK) 975 return status; 976 977 // 978 // TODO: check for fragmentation 979 // 980 981 // tell the buffer to preserve removed ipv6 header - may need it later 982 gBufferModule->store_header(buffer); 983 984 TRACE("store_header for %p\n", buffer); 985 986 // remove ipv6 headers for now 987 gBufferModule->remove_header(buffer, transportHeaderOffset); 988 989 // deliver the data to raw sockets 990 raw_receive_data(buffer); 991 992 net_protocol_module_info* module = receiving_protocol(protocol); 993 if (module == NULL) { 994 // no handler for this packet 995 return EAFNOSUPPORT; 996 } 997 998 if ((buffer->flags & MSG_MCAST) != 0) { 999 // Unfortunely historical reasons dictate that the IP multicast 1000 // model be a little different from the unicast one. We deliver 1001 // this frame directly to all sockets registered with interest 1002 // for this multicast group. 1003 return deliver_multicast(module, buffer, false); 1004 } 1005 1006 return module->receive_data(buffer); 1007 } 1008 1009 1010 status_t 1011 ipv6_deliver_data(net_protocol* _protocol, net_buffer* buffer) 1012 { 1013 ipv6_protocol* protocol = (ipv6_protocol*)_protocol; 1014 1015 if (protocol->raw == NULL) 1016 return B_ERROR; 1017 1018 return protocol->raw->SocketEnqueue(buffer); 1019 } 1020 1021 1022 status_t 1023 ipv6_error_received(net_error error, net_buffer* data) 1024 { 1025 return B_ERROR; 1026 } 1027 1028 1029 status_t 1030 ipv6_error_reply(net_protocol* protocol, net_buffer* cause, net_error error, 1031 net_error_data* errorData) 1032 { 1033 return B_ERROR; 1034 } 1035 1036 1037 ssize_t 1038 ipv6_process_ancillary_data_no_container(net_protocol* _protocol, 1039 net_buffer* buffer, void* msgControl, size_t msgControlLen) 1040 { 1041 ipv6_protocol* protocol = (ipv6_protocol*)_protocol; 1042 ssize_t bytesWritten = 0; 1043 1044 if (protocol->receive_hoplimit != 0) { 1045 TRACE("receive_hoplimit"); 1046 1047 if (msgControlLen < CMSG_SPACE(sizeof(int))) 1048 return B_NO_MEMORY; 1049 1050 TRACE("restore_header for %p\n", buffer); 1051 1052 if (gBufferModule->stored_header_length(buffer) 1053 < (int)sizeof(ip6_hdr)) 1054 return B_ERROR; 1055 1056 IPv6Header header; 1057 if (gBufferModule->restore_header(buffer, 0, &header, sizeof(ip6_hdr)) 1058 != B_OK) 1059 return B_ERROR; 1060 1061 if (header.ProtocolVersion() != IPV6_VERSION) 1062 return B_ERROR; 1063 1064 cmsghdr* messageHeader = (cmsghdr*)((char*)msgControl + bytesWritten); 1065 messageHeader->cmsg_len = CMSG_LEN(sizeof(int)); 1066 messageHeader->cmsg_level = IPPROTO_IPV6; 1067 messageHeader->cmsg_type = IPV6_HOPLIMIT; 1068 1069 int hoplimit = header.header.ip6_hlim; 1070 memcpy(CMSG_DATA(messageHeader), &hoplimit, sizeof(int)); 1071 1072 bytesWritten += CMSG_SPACE(sizeof(int)); 1073 msgControlLen -= CMSG_SPACE(sizeof(int)); 1074 } 1075 1076 if (protocol->receive_pktinfo != 0) { 1077 TRACE("receive_pktinfo"); 1078 1079 if (msgControlLen < CMSG_SPACE(sizeof(struct in6_pktinfo))) 1080 return B_NO_MEMORY; 1081 1082 cmsghdr* messageHeader = (cmsghdr*)((char*)msgControl + bytesWritten); 1083 messageHeader->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); 1084 messageHeader->cmsg_level = IPPROTO_IPV6; 1085 messageHeader->cmsg_type = IPV6_PKTINFO; 1086 1087 struct in6_pktinfo pi; 1088 memcpy(&pi.ipi6_addr, 1089 &((struct sockaddr_in6*)buffer->destination)->sin6_addr, 1090 sizeof(struct in6_addr)); 1091 // REVIEWME: assume buffer->interface cannot be NULL 1092 pi.ipi6_ifindex = buffer->interface->index; 1093 memcpy(CMSG_DATA(messageHeader), &pi, sizeof(struct in6_pktinfo)); 1094 1095 bytesWritten += CMSG_SPACE(sizeof(struct in6_pktinfo)); 1096 msgControlLen -= CMSG_SPACE(sizeof(struct in6_pktinfo)); 1097 } 1098 1099 return bytesWritten; 1100 } 1101 1102 1103 // #pragma mark - 1104 1105 1106 status_t 1107 init_ipv6() 1108 { 1109 mutex_init(&sRawSocketsLock, "raw sockets"); 1110 mutex_init(&sMulticastGroupsLock, "IPv6 multicast groups"); 1111 mutex_init(&sReceivingProtocolLock, "IPv6 receiving protocols"); 1112 1113 status_t status; 1114 1115 sMulticastState = new MulticastState(); 1116 if (sMulticastState == NULL) { 1117 status = B_NO_MEMORY; 1118 goto err; 1119 } 1120 1121 status = sMulticastState->Init(); 1122 if (status != B_OK) 1123 goto err; 1124 1125 new (&sRawSockets) RawSocketList; 1126 // static initializers do not work in the kernel, 1127 // so we have to do it here, manually 1128 // TODO: for modules, this shouldn't be required 1129 1130 status = gStackModule->register_domain_protocols(AF_INET6, SOCK_RAW, 0, 1131 NET_IPV6_MODULE_NAME, NULL); 1132 if (status != B_OK) 1133 goto err; 1134 1135 status = gStackModule->register_domain(AF_INET6, "internet6", &gIPv6Module, 1136 &gIPv6AddressModule, &sDomain); 1137 if (status != B_OK) 1138 goto err; 1139 1140 TRACE("init_ipv6: OK\n"); 1141 return B_OK; 1142 1143 err: 1144 delete sMulticastState; 1145 mutex_destroy(&sReceivingProtocolLock); 1146 mutex_destroy(&sMulticastGroupsLock); 1147 mutex_destroy(&sRawSocketsLock); 1148 TRACE("init_ipv6: error, status=%u\n", status); 1149 return status; 1150 } 1151 1152 1153 status_t 1154 uninit_ipv6() 1155 { 1156 mutex_lock(&sReceivingProtocolLock); 1157 1158 // put all the domain receiving protocols we gathered so far 1159 for (uint32 i = 0; i < 256; i++) { 1160 if (sReceivingProtocol[i] != NULL) 1161 gStackModule->put_domain_receiving_protocol(sDomain, i); 1162 } 1163 1164 delete sMulticastState; 1165 1166 gStackModule->unregister_domain(sDomain); 1167 mutex_unlock(&sReceivingProtocolLock); 1168 1169 mutex_destroy(&sMulticastGroupsLock); 1170 mutex_destroy(&sRawSocketsLock); 1171 mutex_destroy(&sReceivingProtocolLock); 1172 1173 return B_OK; 1174 } 1175 1176 1177 static status_t 1178 ipv6_std_ops(int32 op, ...) 1179 { 1180 switch (op) { 1181 case B_MODULE_INIT: 1182 return init_ipv6(); 1183 case B_MODULE_UNINIT: 1184 return uninit_ipv6(); 1185 default: 1186 return B_ERROR; 1187 } 1188 } 1189 1190 1191 net_protocol_module_info gIPv6Module = { 1192 { 1193 NET_IPV6_MODULE_NAME, 1194 0, 1195 ipv6_std_ops 1196 }, 1197 NET_PROTOCOL_ATOMIC_MESSAGES, 1198 1199 ipv6_init_protocol, 1200 ipv6_uninit_protocol, 1201 ipv6_open, 1202 ipv6_close, 1203 ipv6_free, 1204 ipv6_connect, 1205 ipv6_accept, 1206 ipv6_control, 1207 ipv6_getsockopt, 1208 ipv6_setsockopt, 1209 ipv6_bind, 1210 ipv6_unbind, 1211 ipv6_listen, 1212 ipv6_shutdown, 1213 ipv6_send_data, 1214 ipv6_send_routed_data, 1215 ipv6_send_avail, 1216 ipv6_read_data, 1217 ipv6_read_avail, 1218 ipv6_get_domain, 1219 ipv6_get_mtu, 1220 ipv6_receive_data, 1221 ipv6_deliver_data, 1222 ipv6_error_received, 1223 ipv6_error_reply, 1224 NULL, // add_ancillary_data() 1225 NULL, // process_ancillary_data() 1226 ipv6_process_ancillary_data_no_container, 1227 NULL, // send_data_no_buffer() 1228 NULL // read_data_no_buffer() 1229 }; 1230 1231 module_dependency module_dependencies[] = { 1232 {NET_STACK_MODULE_NAME, (module_info**)&gStackModule}, 1233 {NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule}, 1234 {NET_DATALINK_MODULE_NAME, (module_info**)&sDatalinkModule}, 1235 {NET_SOCKET_MODULE_NAME, (module_info**)&sSocketModule}, 1236 {} 1237 }; 1238 1239 module_info* modules[] = { 1240 (module_info*)&gIPv6Module, 1241 NULL 1242 }; 1243