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