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 */ 8 9 10 #include "ipv4.h" 11 #include "ipv4_address.h" 12 #include "multicast.h" 13 14 #include <net_datalink.h> 15 #include <net_datalink_protocol.h> 16 #include <net_device.h> 17 #include <net_protocol.h> 18 #include <net_stack.h> 19 #include <NetBufferUtilities.h> 20 #include <ProtocolUtilities.h> 21 22 #include <KernelExport.h> 23 #include <util/AutoLock.h> 24 #include <util/list.h> 25 #include <util/DoublyLinkedList.h> 26 #include <util/MultiHashTable.h> 27 28 #include <netinet/in.h> 29 #include <netinet/ip.h> 30 #include <new> 31 #include <stdlib.h> 32 #include <stdio.h> 33 #include <string.h> 34 #include <utility> 35 36 37 //#define TRACE_IPV4 38 #ifdef TRACE_IPV4 39 # define TRACE(format, args...) \ 40 dprintf("IPv4 [%" B_PRIdBIGTIME "] " format "\n", system_time() , \ 41 ##args) 42 # define TRACE_SK(protocol, format, args...) \ 43 dprintf("IPv4 [%" B_PRIdBIGTIME "] %p " format "\n", system_time(), \ 44 protocol , ##args) 45 # define TRACE_ONLY(x) x 46 #else 47 # define TRACE(args...) ; 48 # define TRACE_SK(args...) ; 49 # define TRACE_ONLY(x) 50 #endif 51 52 53 #define MAX_HASH_FRAGMENTS 64 54 // slots in the fragment packet's hash 55 #define FRAGMENT_TIMEOUT 60000000LL 56 // discard fragment after 60 seconds 57 58 59 typedef DoublyLinkedList<struct net_buffer, 60 DoublyLinkedListCLink<struct net_buffer> > FragmentList; 61 62 typedef NetBufferField<uint16, offsetof(ipv4_header, checksum)> IPChecksumField; 63 64 struct ipv4_packet_key { 65 in_addr_t source; 66 in_addr_t destination; 67 uint16 id; 68 uint8 protocol; 69 }; 70 71 72 class FragmentPacket { 73 public: 74 FragmentPacket(const ipv4_packet_key& key); 75 ~FragmentPacket(); 76 77 status_t AddFragment(uint16 start, uint16 end, 78 net_buffer* buffer, bool lastFragment); 79 status_t Reassemble(net_buffer* to); 80 81 bool IsComplete() const 82 { return fReceivedLastFragment 83 && fBytesLeft == 0; } 84 85 const ipv4_packet_key& Key() const { return fKey; } 86 FragmentPacket*& HashTableLink() { return fNext; } 87 88 static void StaleTimer(struct net_timer* timer, void* data); 89 90 private: 91 FragmentPacket* fNext; 92 struct ipv4_packet_key fKey; 93 uint32 fIndex; 94 bool fReceivedLastFragment; 95 int32 fBytesLeft; 96 FragmentList fFragments; 97 net_timer fTimer; 98 }; 99 100 101 struct FragmentHashDefinition { 102 typedef ipv4_packet_key KeyType; 103 typedef FragmentPacket ValueType; 104 105 size_t HashKey(const KeyType& key) const 106 { 107 return (key.source ^ key.destination ^ key.protocol ^ key.id); 108 } 109 110 size_t Hash(ValueType* value) const 111 { 112 return HashKey(value->Key()); 113 } 114 115 bool Compare(const KeyType& key, ValueType* value) const 116 { 117 const ipv4_packet_key& packetKey = value->Key(); 118 119 return packetKey.id == key.id 120 && packetKey.source == key.source 121 && packetKey.destination == key.destination 122 && packetKey.protocol == key.protocol; 123 } 124 125 ValueType*& GetLink(ValueType* value) const 126 { 127 return value->HashTableLink(); 128 } 129 }; 130 131 typedef BOpenHashTable<FragmentHashDefinition, false, true> FragmentTable; 132 133 134 class RawSocket 135 : public DoublyLinkedListLinkImpl<RawSocket>, public DatagramSocket<> { 136 public: 137 RawSocket(net_socket* socket); 138 }; 139 140 typedef DoublyLinkedList<RawSocket> RawSocketList; 141 142 typedef MulticastGroupInterface<IPv4Multicast> IPv4GroupInterface; 143 typedef MulticastFilter<IPv4Multicast> IPv4MulticastFilter; 144 145 struct MulticastStateHash { 146 typedef std::pair<const in_addr* , uint32> KeyType; 147 typedef IPv4GroupInterface ValueType; 148 149 size_t HashKey(const KeyType &key) const 150 { return key.first->s_addr ^ key.second; } 151 size_t Hash(ValueType* value) const 152 { return HashKey(std::make_pair(&value->Address(), 153 value->Interface()->index)); } 154 bool Compare(const KeyType &key, ValueType* value) const 155 { return value->Interface()->index == key.second 156 && value->Address().s_addr == key.first->s_addr; } 157 bool CompareValues(ValueType* value1, ValueType* value2) const 158 { return value1->Interface()->index == value2->Interface()->index 159 && value1->Address().s_addr == value2->Address().s_addr; } 160 ValueType*& GetLink(ValueType* value) const { return value->MulticastGroupsHashLink(); } 161 }; 162 163 164 struct ipv4_protocol : net_protocol { 165 ipv4_protocol() 166 : 167 raw(NULL), 168 multicast_filter(this) 169 { 170 } 171 172 ~ipv4_protocol() 173 { 174 delete raw; 175 } 176 177 RawSocket* raw; 178 uint8 service_type; 179 uint8 time_to_live; 180 uint8 multicast_time_to_live; 181 bool multicast_loopback; 182 uint32 flags; 183 struct sockaddr* multicast_address; // for IP_MULTICAST_IF 184 185 IPv4MulticastFilter multicast_filter; 186 }; 187 188 // protocol flags 189 #define IP_FLAG_HEADER_INCLUDED 0x01 190 #define IP_FLAG_RECEIVE_DEST_ADDR 0x02 191 192 193 static const int kDefaultTTL = 254; 194 static const int kDefaultMulticastTTL = 1; 195 static const bool kDefaultMulticastLoopback = true; 196 197 198 extern net_protocol_module_info gIPv4Module; 199 // we need this in ipv4_std_ops() for registering the AF_INET domain 200 201 net_stack_module_info* gStackModule; 202 net_buffer_module_info* gBufferModule; 203 204 static struct net_domain* sDomain; 205 static net_datalink_module_info* sDatalinkModule; 206 static net_socket_module_info* sSocketModule; 207 static int32 sPacketID; 208 static RawSocketList sRawSockets; 209 static mutex sRawSocketsLock; 210 static mutex sFragmentLock; 211 static FragmentTable sFragmentHash; 212 static mutex sMulticastGroupsLock; 213 214 typedef MultiHashTable<MulticastStateHash> MulticastState; 215 static MulticastState* sMulticastState; 216 217 static net_protocol_module_info* sReceivingProtocol[256]; 218 static mutex sReceivingProtocolLock; 219 220 221 static const char* 222 print_address(const in_addr* address, char* buf, size_t bufLen) 223 { 224 unsigned int addr = ntohl(address->s_addr); 225 226 snprintf(buf, bufLen, "%u.%u.%u.%u", (addr >> 24) & 0xff, 227 (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); 228 229 return buf; 230 } 231 232 233 RawSocket::RawSocket(net_socket* socket) 234 : 235 DatagramSocket<>("ipv4 raw socket", socket) 236 { 237 } 238 239 240 // #pragma mark - 241 242 243 FragmentPacket::FragmentPacket(const ipv4_packet_key& key) 244 : 245 fKey(key), 246 fIndex(0), 247 fReceivedLastFragment(false), 248 fBytesLeft(IP_MAXPACKET) 249 { 250 gStackModule->init_timer(&fTimer, FragmentPacket::StaleTimer, this); 251 } 252 253 254 FragmentPacket::~FragmentPacket() 255 { 256 // cancel the kill timer 257 gStackModule->set_timer(&fTimer, -1); 258 259 // delete all fragments 260 net_buffer* buffer; 261 while ((buffer = fFragments.RemoveHead()) != NULL) { 262 gBufferModule->free(buffer); 263 } 264 } 265 266 267 status_t 268 FragmentPacket::AddFragment(uint16 start, uint16 end, net_buffer* buffer, 269 bool lastFragment) 270 { 271 // restart the timer 272 gStackModule->set_timer(&fTimer, FRAGMENT_TIMEOUT); 273 274 if (start >= end) { 275 // invalid fragment 276 return B_BAD_DATA; 277 } 278 279 // Search for a position in the list to insert the fragment 280 281 FragmentList::ReverseIterator iterator = fFragments.GetReverseIterator(); 282 net_buffer* previous = NULL; 283 net_buffer* next = NULL; 284 while ((previous = iterator.Next()) != NULL) { 285 if (previous->fragment.start <= start) { 286 // The new fragment can be inserted after this one 287 break; 288 } 289 290 next = previous; 291 } 292 293 // See if we already have the fragment's data 294 295 if (previous != NULL && previous->fragment.start <= start 296 && previous->fragment.end >= end) { 297 // we do, so we can just drop this fragment 298 gBufferModule->free(buffer); 299 return B_OK; 300 } 301 302 fIndex = buffer->index; 303 // adopt the buffer's device index 304 305 TRACE(" previous: %p, next: %p", previous, next); 306 307 // If we have parts of the data already, truncate as needed 308 309 if (previous != NULL && previous->fragment.end > start) { 310 TRACE(" remove header %d bytes", previous->fragment.end - start); 311 gBufferModule->remove_header(buffer, previous->fragment.end - start); 312 start = previous->fragment.end; 313 } 314 if (next != NULL && end > next->fragment.start) { 315 TRACE(" remove trailer %d bytes", end - next->fragment.start); 316 gBufferModule->remove_trailer(buffer, end - next->fragment.start); 317 end = next->fragment.start; 318 } 319 320 // Now try if we can already merge the fragments together 321 322 // We will always keep the last buffer received, so that we can still 323 // report an error (in which case we're not responsible for freeing it) 324 325 if (previous != NULL && previous->fragment.end == start) { 326 fFragments.Remove(previous); 327 328 buffer->fragment.start = previous->fragment.start; 329 buffer->fragment.end = end; 330 331 status_t status = gBufferModule->merge(buffer, previous, false); 332 TRACE(" merge previous: %s", strerror(status)); 333 if (status != B_OK) { 334 fFragments.Insert(next, previous); 335 return status; 336 } 337 338 fFragments.Insert(next, buffer); 339 340 // cut down existing hole 341 fBytesLeft -= end - start; 342 343 if (lastFragment && !fReceivedLastFragment) { 344 fReceivedLastFragment = true; 345 fBytesLeft -= IP_MAXPACKET - end; 346 } 347 348 TRACE(" hole length: %d", (int)fBytesLeft); 349 350 return B_OK; 351 } else if (next != NULL && next->fragment.start == end) { 352 net_buffer* afterNext = (net_buffer*)next->link.next; 353 fFragments.Remove(next); 354 355 buffer->fragment.start = start; 356 buffer->fragment.end = next->fragment.end; 357 358 status_t status = gBufferModule->merge(buffer, next, true); 359 TRACE(" merge next: %s", strerror(status)); 360 if (status != B_OK) { 361 // Insert "next" at its previous position 362 fFragments.Insert(afterNext, next); 363 return status; 364 } 365 366 fFragments.Insert(afterNext, buffer); 367 368 // cut down existing hole 369 fBytesLeft -= end - start; 370 371 if (lastFragment && !fReceivedLastFragment) { 372 fReceivedLastFragment = true; 373 fBytesLeft -= IP_MAXPACKET - end; 374 } 375 376 TRACE(" hole length: %d", (int)fBytesLeft); 377 378 return B_OK; 379 } 380 381 // We couldn't merge the fragments, so we need to add it as is 382 383 TRACE(" new fragment: %p, bytes %d-%d", buffer, start, end); 384 385 buffer->fragment.start = start; 386 buffer->fragment.end = end; 387 fFragments.Insert(next, buffer); 388 389 // update length of the hole, if any 390 fBytesLeft -= end - start; 391 392 if (lastFragment && !fReceivedLastFragment) { 393 fReceivedLastFragment = true; 394 fBytesLeft -= IP_MAXPACKET - end; 395 } 396 397 TRACE(" hole length: %d", (int)fBytesLeft); 398 399 return B_OK; 400 } 401 402 403 /*! Reassembles the fragments to the specified buffer \a to. 404 This buffer must have been added via AddFragment() before. 405 */ 406 status_t 407 FragmentPacket::Reassemble(net_buffer* to) 408 { 409 if (!IsComplete()) 410 return B_ERROR; 411 412 net_buffer* buffer = NULL; 413 414 net_buffer* fragment; 415 while ((fragment = fFragments.RemoveHead()) != NULL) { 416 if (buffer != NULL) { 417 status_t status; 418 if (to == fragment) { 419 status = gBufferModule->merge(fragment, buffer, false); 420 buffer = fragment; 421 } else 422 status = gBufferModule->merge(buffer, fragment, true); 423 if (status != B_OK) 424 return status; 425 } else 426 buffer = fragment; 427 } 428 429 if (buffer != to) 430 panic("ipv4 packet reassembly did not work correctly."); 431 432 to->index = fIndex; 433 // reset the buffer's device index 434 435 return B_OK; 436 } 437 438 439 /*static*/ void 440 FragmentPacket::StaleTimer(struct net_timer* timer, void* data) 441 { 442 FragmentPacket* packet = (FragmentPacket*)data; 443 TRACE("Assembling FragmentPacket %p timed out!", packet); 444 445 MutexLocker locker(&sFragmentLock); 446 sFragmentHash.Remove(packet); 447 locker.Unlock(); 448 449 if (!packet->fFragments.IsEmpty()) { 450 // Send error: fragment reassembly time exceeded 451 sDomain->module->error_reply(NULL, packet->fFragments.First(), 452 B_NET_ERROR_REASSEMBLY_TIME_EXCEEDED, NULL); 453 } 454 455 delete packet; 456 } 457 458 459 // #pragma mark - 460 461 462 #ifdef TRACE_IPV4 463 static void 464 dump_ipv4_header(ipv4_header &header) 465 { 466 struct pretty_ipv4 { 467 #if B_HOST_IS_LENDIAN == 1 468 uint8 a; 469 uint8 b; 470 uint8 c; 471 uint8 d; 472 #else 473 uint8 d; 474 uint8 c; 475 uint8 b; 476 uint8 a; 477 #endif 478 }; 479 struct pretty_ipv4* src = (struct pretty_ipv4*)&header.source; 480 struct pretty_ipv4* dst = (struct pretty_ipv4*)&header.destination; 481 dprintf(" version: %d\n", header.version); 482 dprintf(" header_length: 4 * %d\n", header.header_length); 483 dprintf(" service_type: %d\n", header.service_type); 484 dprintf(" total_length: %d\n", header.TotalLength()); 485 dprintf(" id: %d\n", ntohs(header.id)); 486 dprintf(" fragment_offset: %d (flags: %c%c%c)\n", 487 header.FragmentOffset() & IP_FRAGMENT_OFFSET_MASK, 488 (header.FragmentOffset() & IP_RESERVED_FLAG) ? 'r' : '-', 489 (header.FragmentOffset() & IP_DONT_FRAGMENT) ? 'd' : '-', 490 (header.FragmentOffset() & IP_MORE_FRAGMENTS) ? 'm' : '-'); 491 dprintf(" time_to_live: %d\n", header.time_to_live); 492 dprintf(" protocol: %d\n", header.protocol); 493 dprintf(" checksum: %d\n", ntohs(header.checksum)); 494 dprintf(" source: %d.%d.%d.%d\n", src->a, src->b, src->c, src->d); 495 dprintf(" destination: %d.%d.%d.%d\n", dst->a, dst->b, dst->c, dst->d); 496 } 497 #endif // TRACE_IPV4 498 499 500 static int 501 dump_ipv4_multicast(int argc, char** argv) 502 { 503 MulticastState::Iterator groupIterator = sMulticastState->GetIterator(); 504 505 while (groupIterator.HasNext()) { 506 IPv4GroupInterface* state = groupIterator.Next(); 507 508 char addressBuffer[64]; 509 510 kprintf("%p: group <%s, %s, %s {", state, state->Interface()->name, 511 print_address(&state->Address(), addressBuffer, 512 sizeof(addressBuffer)), 513 state->Mode() == IPv4GroupInterface::kExclude 514 ? "Exclude" : "Include"); 515 516 int count = 0; 517 IPv4GroupInterface::AddressSet::Iterator addressIterator 518 = state->Sources().GetIterator(); 519 while (addressIterator.HasNext()) { 520 kprintf("%s%s", count > 0 ? ", " : "", 521 print_address(&addressIterator.Next(), 522 addressBuffer, sizeof(addressBuffer))); 523 count++; 524 } 525 526 kprintf("}> sock %p\n", state->Parent()->Socket()); 527 } 528 529 return 0; 530 } 531 532 533 /*! Attempts to re-assemble fragmented packets. 534 \return B_OK if everything went well; if it could reassemble the packet, \a _buffer 535 will point to its buffer, otherwise, it will be \c NULL. 536 \return various error codes if something went wrong (mostly B_NO_MEMORY) 537 */ 538 static status_t 539 reassemble_fragments(const ipv4_header &header, net_buffer** _buffer) 540 { 541 net_buffer* buffer = *_buffer; 542 status_t status; 543 544 struct ipv4_packet_key key; 545 key.source = (in_addr_t)header.source; 546 key.destination = (in_addr_t)header.destination; 547 key.id = header.id; 548 key.protocol = header.protocol; 549 550 // TODO: Make locking finer grained. 551 MutexLocker locker(&sFragmentLock); 552 553 FragmentPacket* packet = sFragmentHash.Lookup(key); 554 if (packet == NULL) { 555 // New fragment packet 556 packet = new (std::nothrow) FragmentPacket(key); 557 if (packet == NULL) 558 return B_NO_MEMORY; 559 560 // add packet to hash 561 status = sFragmentHash.Insert(packet); 562 if (status != B_OK) { 563 delete packet; 564 return status; 565 } 566 } 567 568 uint16 fragmentOffset = header.FragmentOffset(); 569 uint16 start = (fragmentOffset & IP_FRAGMENT_OFFSET_MASK) << 3; 570 uint16 end = start + header.TotalLength() - header.HeaderLength(); 571 bool lastFragment = (fragmentOffset & IP_MORE_FRAGMENTS) == 0; 572 573 TRACE(" Received IPv4 %sfragment of size %d, offset %d.", 574 lastFragment ? "last ": "", end - start, start); 575 576 // Remove header unless this is the first fragment 577 if (start != 0) 578 gBufferModule->remove_header(buffer, header.HeaderLength()); 579 580 status = packet->AddFragment(start, end, buffer, lastFragment); 581 if (status != B_OK) 582 return status; 583 584 if (packet->IsComplete()) { 585 sFragmentHash.Remove(packet); 586 // no matter if reassembling succeeds, we won't need this packet 587 // anymore 588 589 status = packet->Reassemble(buffer); 590 delete packet; 591 592 // _buffer does not change 593 return status; 594 } 595 596 // This indicates that the packet is not yet complete 597 *_buffer = NULL; 598 return B_OK; 599 } 600 601 602 /*! Fragments the incoming buffer and send all fragments via the specified 603 \a route. 604 */ 605 static status_t 606 send_fragments(ipv4_protocol* protocol, struct net_route* route, 607 net_buffer* buffer, uint32 mtu) 608 { 609 TRACE_SK(protocol, "SendFragments(%" B_PRIu32 " bytes, mtu %" B_PRIu32 ")", 610 buffer->size, mtu); 611 612 NetBufferHeaderReader<ipv4_header> originalHeader(buffer); 613 if (originalHeader.Status() != B_OK) 614 return originalHeader.Status(); 615 616 uint16 headerLength = originalHeader->HeaderLength(); 617 uint32 bytesLeft = buffer->size - headerLength; 618 uint32 fragmentOffset = 0; 619 status_t status = B_OK; 620 621 net_buffer* headerBuffer = gBufferModule->split(buffer, headerLength); 622 if (headerBuffer == NULL) 623 return B_NO_MEMORY; 624 625 // TODO: we need to make sure ipv4_header is contiguous or 626 // use another construct. 627 NetBufferHeaderReader<ipv4_header> bufferHeader(headerBuffer); 628 ipv4_header* header = &bufferHeader.Data(); 629 630 // Adapt MTU to be a multiple of 8 (fragment offsets can only be specified 631 // this way) 632 mtu -= headerLength; 633 mtu &= ~7; 634 TRACE(" adjusted MTU to %" B_PRIu32 ", bytesLeft %" B_PRIu32, mtu, 635 bytesLeft); 636 637 while (bytesLeft > 0) { 638 uint32 fragmentLength = min_c(bytesLeft, mtu); 639 bytesLeft -= fragmentLength; 640 bool lastFragment = bytesLeft == 0; 641 642 header->total_length = htons(fragmentLength + headerLength); 643 header->fragment_offset = htons((lastFragment ? 0 : IP_MORE_FRAGMENTS) 644 | (fragmentOffset >> 3)); 645 header->checksum = 0; 646 header->checksum = gStackModule->checksum((uint8*)header, 647 headerLength); 648 // TODO: compute the checksum only for those parts that changed? 649 650 TRACE(" send fragment of %" B_PRIu32 " bytes (%" B_PRIu32 " bytes " 651 "left)", fragmentLength, bytesLeft); 652 653 net_buffer* fragmentBuffer; 654 if (!lastFragment) { 655 fragmentBuffer = gBufferModule->split(buffer, fragmentLength); 656 fragmentOffset += fragmentLength; 657 } else 658 fragmentBuffer = buffer; 659 660 if (fragmentBuffer == NULL) { 661 status = B_NO_MEMORY; 662 break; 663 } 664 665 // copy header to fragment 666 status = gBufferModule->prepend(fragmentBuffer, header, headerLength); 667 668 // send fragment 669 if (status == B_OK) 670 status = sDatalinkModule->send_routed_data(route, fragmentBuffer); 671 672 if (lastFragment) { 673 // we don't own the last buffer, so we don't have to free it 674 break; 675 } 676 677 if (status != B_OK) { 678 gBufferModule->free(fragmentBuffer); 679 break; 680 } 681 } 682 683 gBufferModule->free(headerBuffer); 684 return status; 685 } 686 687 688 /*! Delivers the provided \a buffer to all listeners of this multicast group. 689 Does not take over ownership of the buffer. 690 */ 691 static bool 692 deliver_multicast(net_protocol_module_info* module, net_buffer* buffer, 693 bool deliverToRaw) 694 { 695 if (module->deliver_data == NULL) 696 return false; 697 698 // TODO: fix multicast! 699 return false; 700 MutexLocker _(sMulticastGroupsLock); 701 702 sockaddr_in* multicastAddr = (sockaddr_in*)buffer->destination; 703 704 MulticastState::ValueIterator it = sMulticastState->Lookup(std::make_pair( 705 &multicastAddr->sin_addr, buffer->interface_address->interface->index)); 706 707 size_t count = 0; 708 709 while (it.HasNext()) { 710 IPv4GroupInterface* state = it.Next(); 711 712 ipv4_protocol* ipProtocol = state->Parent()->Socket(); 713 if (deliverToRaw && (ipProtocol->raw == NULL 714 || ipProtocol->socket->protocol != buffer->protocol)) 715 continue; 716 717 if (state->FilterAccepts(buffer)) { 718 net_protocol* protocol = ipProtocol; 719 if (protocol->module != module) { 720 // as multicast filters are installed with an IPv4 protocol 721 // reference, we need to go and find the appropriate instance 722 // related to the 'receiving protocol' with module 'module'. 723 net_protocol* protocol = ipProtocol->socket->first_protocol; 724 725 while (protocol != NULL && protocol->module != module) 726 protocol = protocol->next; 727 } 728 729 if (protocol != NULL) { 730 module->deliver_data(protocol, buffer); 731 count++; 732 } 733 } 734 } 735 736 return count > 0; 737 } 738 739 740 /*! Delivers the buffer to all listening raw sockets without taking ownership of 741 the provided \a buffer. 742 Returns \c true if there was any receiver, \c false if not. 743 */ 744 static bool 745 raw_receive_data(net_buffer* buffer) 746 { 747 MutexLocker locker(sRawSocketsLock); 748 749 if (sRawSockets.IsEmpty()) 750 return false; 751 752 TRACE("RawReceiveData(%i)", buffer->protocol); 753 754 if ((buffer->flags & MSG_MCAST) != 0) { 755 // we need to call deliver_multicast here separately as 756 // buffer still has the IP header, and it won't in the 757 // next call. This isn't very optimized but works for now. 758 // A better solution would be to hold separate hash tables 759 // and lists for RAW and non-RAW sockets. 760 return deliver_multicast(&gIPv4Module, buffer, true); 761 } 762 763 RawSocketList::Iterator iterator = sRawSockets.GetIterator(); 764 size_t count = 0; 765 766 while (iterator.HasNext()) { 767 RawSocket* raw = iterator.Next(); 768 769 if (raw->Socket()->protocol == buffer->protocol) { 770 raw->EnqueueClone(buffer); 771 count++; 772 } 773 } 774 775 return count > 0; 776 } 777 778 779 static inline sockaddr* 780 fill_sockaddr_in(sockaddr_in* target, in_addr_t address) 781 { 782 target->sin_family = AF_INET; 783 target->sin_len = sizeof(sockaddr_in); 784 target->sin_port = 0; 785 target->sin_addr.s_addr = address; 786 return (sockaddr*)target; 787 } 788 789 790 static status_t 791 get_int_option(void* target, size_t length, int value) 792 { 793 if (length != sizeof(int)) 794 return B_BAD_VALUE; 795 796 return user_memcpy(target, &value, sizeof(int)); 797 } 798 799 800 static status_t 801 get_char_int_option(void* target, size_t length, int value) 802 { 803 if (length == sizeof(int)) 804 return user_memcpy(target, &value, sizeof(int)); 805 if (length == sizeof(unsigned char)) { 806 unsigned char uvalue = value; 807 return user_memcpy(target, &uvalue, sizeof(uvalue)); 808 } 809 return B_BAD_VALUE; 810 } 811 812 813 template<typename Type> static status_t 814 set_int_option(Type &target, const void* _value, size_t length) 815 { 816 int value; 817 818 if (length != sizeof(int)) 819 return B_BAD_VALUE; 820 821 if (user_memcpy(&value, _value, sizeof(int)) != B_OK) 822 return B_BAD_ADDRESS; 823 824 target = value; 825 return B_OK; 826 } 827 828 829 template<typename Type> static status_t 830 set_char_int_option(Type &target, const void* _value, size_t length) 831 { 832 if (length == sizeof(int)) { 833 int value; 834 if (user_memcpy(&value, _value, sizeof(int)) != B_OK) 835 return B_BAD_ADDRESS; 836 if (value > 255) 837 return B_BAD_VALUE; 838 target = value; 839 return B_OK; 840 } 841 if (length == sizeof(unsigned char)) { 842 unsigned char value; 843 if (user_memcpy(&value, _value, sizeof(value)) != B_OK) 844 return B_BAD_ADDRESS; 845 846 target = value; 847 return B_OK; 848 } 849 return B_BAD_VALUE; 850 } 851 852 853 static net_protocol_module_info* 854 receiving_protocol(uint8 protocol) 855 { 856 net_protocol_module_info* module = sReceivingProtocol[protocol]; 857 if (module != NULL) 858 return module; 859 860 MutexLocker locker(sReceivingProtocolLock); 861 862 module = sReceivingProtocol[protocol]; 863 if (module != NULL) 864 return module; 865 866 if (gStackModule->get_domain_receiving_protocol(sDomain, protocol, 867 &module) == B_OK) 868 sReceivingProtocol[protocol] = module; 869 870 return module; 871 } 872 873 874 // #pragma mark - multicast 875 876 877 status_t 878 IPv4Multicast::JoinGroup(IPv4GroupInterface* state) 879 { 880 MutexLocker _(sMulticastGroupsLock); 881 882 sockaddr_in groupAddr; 883 status_t status = sDatalinkModule->join_multicast(state->Interface(), 884 sDomain, fill_sockaddr_in(&groupAddr, state->Address().s_addr)); 885 if (status != B_OK) 886 return status; 887 888 sMulticastState->Insert(state); 889 return B_OK; 890 } 891 892 893 status_t 894 IPv4Multicast::LeaveGroup(IPv4GroupInterface* state) 895 { 896 MutexLocker _(sMulticastGroupsLock); 897 898 sMulticastState->Remove(state); 899 900 sockaddr_in groupAddr; 901 return sDatalinkModule->leave_multicast(state->Interface(), sDomain, 902 fill_sockaddr_in(&groupAddr, state->Address().s_addr)); 903 } 904 905 906 static status_t 907 ipv4_delta_group(IPv4GroupInterface* group, int option, 908 net_interface* interface, const in_addr* sourceAddr) 909 { 910 switch (option) { 911 case IP_ADD_MEMBERSHIP: 912 return group->Add(); 913 case IP_DROP_MEMBERSHIP: 914 return group->Drop(); 915 case IP_BLOCK_SOURCE: 916 return group->BlockSource(*sourceAddr); 917 case IP_UNBLOCK_SOURCE: 918 return group->UnblockSource(*sourceAddr); 919 case IP_ADD_SOURCE_MEMBERSHIP: 920 return group->AddSSM(*sourceAddr); 921 case IP_DROP_SOURCE_MEMBERSHIP: 922 return group->DropSSM(*sourceAddr); 923 } 924 925 return B_ERROR; 926 } 927 928 929 static status_t 930 ipv4_delta_membership(ipv4_protocol* protocol, int option, 931 net_interface* interface, const in_addr* groupAddr, 932 const in_addr* sourceAddr) 933 { 934 IPv4MulticastFilter& filter = protocol->multicast_filter; 935 IPv4GroupInterface* state = NULL; 936 status_t status = B_OK; 937 938 switch (option) { 939 case IP_ADD_MEMBERSHIP: 940 case IP_ADD_SOURCE_MEMBERSHIP: 941 status = filter.GetState(*groupAddr, interface, state, true); 942 break; 943 944 case IP_DROP_MEMBERSHIP: 945 case IP_BLOCK_SOURCE: 946 case IP_UNBLOCK_SOURCE: 947 case IP_DROP_SOURCE_MEMBERSHIP: 948 filter.GetState(*groupAddr, interface, state, false); 949 if (state == NULL) { 950 if (option == IP_DROP_MEMBERSHIP 951 || option == IP_DROP_SOURCE_MEMBERSHIP) 952 return EADDRNOTAVAIL; 953 954 return B_BAD_VALUE; 955 } 956 break; 957 } 958 959 if (status != B_OK) 960 return status; 961 962 status = ipv4_delta_group(state, option, interface, sourceAddr); 963 filter.ReturnState(state); 964 return status; 965 } 966 967 968 static int 969 generic_to_ipv4(int option) 970 { 971 switch (option) { 972 case MCAST_JOIN_GROUP: 973 return IP_ADD_MEMBERSHIP; 974 case MCAST_JOIN_SOURCE_GROUP: 975 return IP_ADD_SOURCE_MEMBERSHIP; 976 case MCAST_LEAVE_GROUP: 977 return IP_DROP_MEMBERSHIP; 978 case MCAST_BLOCK_SOURCE: 979 return IP_BLOCK_SOURCE; 980 case MCAST_UNBLOCK_SOURCE: 981 return IP_UNBLOCK_SOURCE; 982 case MCAST_LEAVE_SOURCE_GROUP: 983 return IP_DROP_SOURCE_MEMBERSHIP; 984 } 985 986 return -1; 987 } 988 989 990 static net_interface* 991 get_multicast_interface(ipv4_protocol* protocol, const in_addr* address) 992 { 993 // TODO: this is broken and leaks references 994 sockaddr_in groupAddr; 995 net_route* route = sDatalinkModule->get_route(sDomain, 996 fill_sockaddr_in(&groupAddr, address ? address->s_addr : INADDR_ANY)); 997 if (route == NULL) 998 return NULL; 999 1000 return route->interface_address->interface; 1001 } 1002 1003 1004 static status_t 1005 ipv4_delta_membership(ipv4_protocol* protocol, int option, 1006 in_addr* interfaceAddr, in_addr* groupAddr, in_addr* sourceAddr) 1007 { 1008 net_interface* interface = NULL; 1009 1010 if (interfaceAddr->s_addr == INADDR_ANY) { 1011 interface = get_multicast_interface(protocol, groupAddr); 1012 } else { 1013 sockaddr_in address; 1014 interface = sDatalinkModule->get_interface_with_address( 1015 fill_sockaddr_in(&address, interfaceAddr->s_addr)); 1016 } 1017 1018 if (interface == NULL) 1019 return B_DEVICE_NOT_FOUND; 1020 1021 return ipv4_delta_membership(protocol, option, interface, 1022 groupAddr, sourceAddr); 1023 } 1024 1025 1026 static status_t 1027 ipv4_generic_delta_membership(ipv4_protocol* protocol, int option, 1028 uint32 index, const sockaddr_storage* _groupAddr, 1029 const sockaddr_storage* _sourceAddr) 1030 { 1031 if (_groupAddr->ss_family != AF_INET 1032 || (_sourceAddr != NULL && _sourceAddr->ss_family != AF_INET)) 1033 return B_BAD_VALUE; 1034 1035 const in_addr* groupAddr = &((const sockaddr_in*)_groupAddr)->sin_addr; 1036 1037 // TODO: this is broken and leaks references 1038 net_interface* interface; 1039 if (index == 0) 1040 interface = get_multicast_interface(protocol, groupAddr); 1041 else 1042 interface = sDatalinkModule->get_interface(sDomain, index); 1043 1044 if (interface == NULL) 1045 return B_DEVICE_NOT_FOUND; 1046 1047 const in_addr* sourceAddr = NULL; 1048 if (_sourceAddr != NULL) 1049 sourceAddr = &((const sockaddr_in*)_sourceAddr)->sin_addr; 1050 1051 return ipv4_delta_membership(protocol, generic_to_ipv4(option), interface, 1052 groupAddr, sourceAddr); 1053 } 1054 1055 1056 // #pragma mark - module interface 1057 1058 1059 net_protocol* 1060 ipv4_init_protocol(net_socket* socket) 1061 { 1062 ipv4_protocol* protocol = new (std::nothrow) ipv4_protocol(); 1063 if (protocol == NULL) 1064 return NULL; 1065 1066 protocol->raw = NULL; 1067 protocol->service_type = 0; 1068 protocol->time_to_live = kDefaultTTL; 1069 protocol->multicast_time_to_live = kDefaultMulticastTTL; 1070 protocol->multicast_loopback = kDefaultMulticastLoopback; 1071 protocol->flags = 0; 1072 protocol->multicast_address = NULL; 1073 return protocol; 1074 } 1075 1076 1077 status_t 1078 ipv4_uninit_protocol(net_protocol* _protocol) 1079 { 1080 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1081 1082 delete protocol; 1083 1084 return B_OK; 1085 } 1086 1087 1088 /*! Since open() is only called on the top level protocol, when we get here 1089 it means we are on a SOCK_RAW socket. 1090 */ 1091 status_t 1092 ipv4_open(net_protocol* _protocol) 1093 { 1094 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1095 1096 // Only root may open raw sockets 1097 if (geteuid() != 0) 1098 return B_NOT_ALLOWED; 1099 1100 RawSocket* raw = new (std::nothrow) RawSocket(protocol->socket); 1101 if (raw == NULL) 1102 return B_NO_MEMORY; 1103 1104 status_t status = raw->InitCheck(); 1105 if (status != B_OK) { 1106 delete raw; 1107 return status; 1108 } 1109 1110 TRACE_SK(protocol, "Open()"); 1111 1112 protocol->raw = raw; 1113 1114 MutexLocker locker(sRawSocketsLock); 1115 sRawSockets.Add(raw); 1116 return B_OK; 1117 } 1118 1119 1120 status_t 1121 ipv4_close(net_protocol* _protocol) 1122 { 1123 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1124 RawSocket* raw = protocol->raw; 1125 if (raw == NULL) 1126 return B_ERROR; 1127 1128 TRACE_SK(protocol, "Close()"); 1129 1130 MutexLocker locker(sRawSocketsLock); 1131 sRawSockets.Remove(raw); 1132 delete raw; 1133 protocol->raw = NULL; 1134 1135 return B_OK; 1136 } 1137 1138 1139 status_t 1140 ipv4_free(net_protocol* protocol) 1141 { 1142 return B_OK; 1143 } 1144 1145 1146 status_t 1147 ipv4_connect(net_protocol* protocol, const struct sockaddr* address) 1148 { 1149 return B_ERROR; 1150 } 1151 1152 1153 status_t 1154 ipv4_accept(net_protocol* protocol, struct net_socket** _acceptedSocket) 1155 { 1156 return B_NOT_SUPPORTED; 1157 } 1158 1159 1160 status_t 1161 ipv4_control(net_protocol* _protocol, int level, int option, void* value, 1162 size_t* _length) 1163 { 1164 if ((level & LEVEL_MASK) != IPPROTO_IP) 1165 return sDatalinkModule->control(sDomain, option, value, _length); 1166 1167 return B_BAD_VALUE; 1168 } 1169 1170 1171 status_t 1172 ipv4_getsockopt(net_protocol* _protocol, int level, int option, void* value, 1173 int* _length) 1174 { 1175 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1176 1177 if (level == IPPROTO_IP) { 1178 bool isDgramOrRaw = protocol->socket->type == SOCK_DGRAM 1179 || protocol->socket->type == SOCK_RAW; 1180 if (option == IP_HDRINCL) { 1181 return get_int_option(value, *_length, 1182 (protocol->flags & IP_FLAG_HEADER_INCLUDED) != 0); 1183 } 1184 if (option == IP_RECVDSTADDR) { 1185 return get_int_option(value, *_length, 1186 (protocol->flags & IP_FLAG_RECEIVE_DEST_ADDR) != 0); 1187 } 1188 if (option == IP_TTL) 1189 return get_int_option(value, *_length, protocol->time_to_live); 1190 if (option == IP_TOS) 1191 return get_int_option(value, *_length, protocol->service_type); 1192 if (option == IP_MULTICAST_IF) { 1193 if (*_length != sizeof(struct in_addr)) 1194 return B_BAD_VALUE; 1195 if (!isDgramOrRaw) 1196 return B_NOT_SUPPORTED; 1197 struct sockaddr_in defaultAddress; 1198 defaultAddress.sin_addr.s_addr = htonl(INADDR_ANY); 1199 struct sockaddr_in* address = 1200 (struct sockaddr_in*)protocol->multicast_address; 1201 if (address == NULL) 1202 address = &defaultAddress; 1203 if (user_memcpy(value, &address->sin_addr, sizeof(struct in_addr)) 1204 != B_OK) { 1205 return B_BAD_ADDRESS; 1206 } 1207 return B_OK; 1208 } 1209 if (option == IP_MULTICAST_TTL) { 1210 if (!isDgramOrRaw) 1211 return B_NOT_SUPPORTED; 1212 return get_char_int_option(value, *_length, 1213 protocol->multicast_time_to_live); 1214 } 1215 if (option == IP_MULTICAST_LOOP) { 1216 if (!isDgramOrRaw) 1217 return B_NOT_SUPPORTED; 1218 return get_char_int_option(value, *_length, 1219 protocol->multicast_loopback ? 1 : 0); 1220 } 1221 if (option == IP_ADD_MEMBERSHIP 1222 || option == IP_DROP_MEMBERSHIP 1223 || option == IP_BLOCK_SOURCE 1224 || option == IP_UNBLOCK_SOURCE 1225 || option == IP_ADD_SOURCE_MEMBERSHIP 1226 || option == IP_DROP_SOURCE_MEMBERSHIP 1227 || option == MCAST_JOIN_GROUP 1228 || option == MCAST_LEAVE_GROUP 1229 || option == MCAST_BLOCK_SOURCE 1230 || option == MCAST_UNBLOCK_SOURCE 1231 || option == MCAST_JOIN_SOURCE_GROUP 1232 || option == MCAST_LEAVE_SOURCE_GROUP) { 1233 // RFC 3678, Section 4.1: 1234 // ``An error of EOPNOTSUPP is returned if these options are 1235 // used with getsockopt().'' 1236 return B_NOT_SUPPORTED; 1237 } 1238 1239 dprintf("IPv4::getsockopt(): get unknown option: %d\n", option); 1240 return ENOPROTOOPT; 1241 } 1242 1243 return sSocketModule->get_option(protocol->socket, level, option, value, 1244 _length); 1245 } 1246 1247 1248 status_t 1249 ipv4_setsockopt(net_protocol* _protocol, int level, int option, 1250 const void* value, int length) 1251 { 1252 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1253 1254 if (level == IPPROTO_IP) { 1255 bool isDgramOrRaw = protocol->socket->type == SOCK_DGRAM 1256 || protocol->socket->type == SOCK_RAW; 1257 if (option == IP_HDRINCL) { 1258 int headerIncluded; 1259 if (length != sizeof(int)) 1260 return B_BAD_VALUE; 1261 if (user_memcpy(&headerIncluded, value, sizeof(headerIncluded)) 1262 != B_OK) 1263 return B_BAD_ADDRESS; 1264 1265 if (headerIncluded) 1266 protocol->flags |= IP_FLAG_HEADER_INCLUDED; 1267 else 1268 protocol->flags &= ~IP_FLAG_HEADER_INCLUDED; 1269 1270 return B_OK; 1271 } 1272 if (option == IP_RECVDSTADDR) { 1273 int getAddress; 1274 if (length != sizeof(int)) 1275 return B_BAD_VALUE; 1276 if (user_memcpy(&getAddress, value, sizeof(int)) != B_OK) 1277 return B_BAD_ADDRESS; 1278 1279 if (getAddress && (protocol->socket->type == SOCK_DGRAM 1280 || protocol->socket->type == SOCK_RAW)) 1281 protocol->flags |= IP_FLAG_RECEIVE_DEST_ADDR; 1282 else 1283 protocol->flags &= ~IP_FLAG_RECEIVE_DEST_ADDR; 1284 1285 return B_OK; 1286 } 1287 if (option == IP_TTL) 1288 return set_int_option(protocol->time_to_live, value, length); 1289 if (option == IP_TOS) 1290 return set_int_option(protocol->service_type, value, length); 1291 if (option == IP_MULTICAST_IF) { 1292 if (length != sizeof(struct in_addr)) 1293 return B_BAD_VALUE; 1294 if (!isDgramOrRaw) 1295 return B_NOT_SUPPORTED; 1296 1297 struct sockaddr_in* address = new (std::nothrow) sockaddr_in; 1298 if (address == NULL) 1299 return B_NO_MEMORY; 1300 1301 struct in_addr sin_addr; 1302 if (user_memcpy(&sin_addr, value, sizeof(struct in_addr)) 1303 != B_OK) { 1304 delete address; 1305 return B_BAD_ADDRESS; 1306 } 1307 fill_sockaddr_in(address, sin_addr.s_addr); 1308 1309 // Using INADDR_ANY to remove the previous setting. 1310 if (address->sin_addr.s_addr == htonl(INADDR_ANY)) { 1311 delete address; 1312 delete protocol->multicast_address; 1313 protocol->multicast_address = NULL; 1314 return B_OK; 1315 } 1316 1317 struct net_interface* interface 1318 = sDatalinkModule->get_interface_with_address( 1319 (sockaddr*)address); 1320 if (interface == NULL) { 1321 delete address; 1322 return EADDRNOTAVAIL; 1323 } 1324 1325 delete protocol->multicast_address; 1326 protocol->multicast_address = (struct sockaddr*)address; 1327 1328 sDatalinkModule->put_interface(interface); 1329 return B_OK; 1330 } 1331 if (option == IP_MULTICAST_TTL) { 1332 if (!isDgramOrRaw) 1333 return B_NOT_SUPPORTED; 1334 return set_char_int_option(protocol->multicast_time_to_live, value, 1335 length); 1336 } 1337 if (option == IP_MULTICAST_LOOP) { 1338 if (!isDgramOrRaw) 1339 return B_NOT_SUPPORTED; 1340 uint8 multicast_loopback; 1341 status_t status = set_char_int_option(multicast_loopback, value, 1342 length); 1343 if (status == B_OK) 1344 protocol->multicast_loopback = multicast_loopback != 0; 1345 return status; 1346 } 1347 if (option == IP_ADD_MEMBERSHIP || option == IP_DROP_MEMBERSHIP) { 1348 if (!isDgramOrRaw) 1349 return B_NOT_SUPPORTED; 1350 ip_mreq mreq; 1351 if (length != sizeof(ip_mreq)) 1352 return B_BAD_VALUE; 1353 if (user_memcpy(&mreq, value, sizeof(ip_mreq)) != B_OK) 1354 return B_BAD_ADDRESS; 1355 1356 return ipv4_delta_membership(protocol, option, &mreq.imr_interface, 1357 &mreq.imr_multiaddr, NULL); 1358 } 1359 if (option == IP_BLOCK_SOURCE 1360 || option == IP_UNBLOCK_SOURCE 1361 || option == IP_ADD_SOURCE_MEMBERSHIP 1362 || option == IP_DROP_SOURCE_MEMBERSHIP) { 1363 if (!isDgramOrRaw) 1364 return B_NOT_SUPPORTED; 1365 ip_mreq_source mreq; 1366 if (length != sizeof(ip_mreq_source)) 1367 return B_BAD_VALUE; 1368 if (user_memcpy(&mreq, value, sizeof(ip_mreq_source)) != B_OK) 1369 return B_BAD_ADDRESS; 1370 1371 return ipv4_delta_membership(protocol, option, &mreq.imr_interface, 1372 &mreq.imr_multiaddr, &mreq.imr_sourceaddr); 1373 } 1374 if (option == MCAST_LEAVE_GROUP || option == MCAST_JOIN_GROUP) { 1375 if (!isDgramOrRaw) 1376 return B_NOT_SUPPORTED; 1377 group_req greq; 1378 if (length != sizeof(group_req)) 1379 return B_BAD_VALUE; 1380 if (user_memcpy(&greq, value, sizeof(group_req)) != B_OK) 1381 return B_BAD_ADDRESS; 1382 1383 return ipv4_generic_delta_membership(protocol, option, 1384 greq.gr_interface, &greq.gr_group, NULL); 1385 } 1386 if (option == MCAST_BLOCK_SOURCE 1387 || option == MCAST_UNBLOCK_SOURCE 1388 || option == MCAST_JOIN_SOURCE_GROUP 1389 || option == MCAST_LEAVE_SOURCE_GROUP) { 1390 if (!isDgramOrRaw) 1391 return B_NOT_SUPPORTED; 1392 group_source_req greq; 1393 if (length != sizeof(group_source_req)) 1394 return B_BAD_VALUE; 1395 if (user_memcpy(&greq, value, sizeof(group_source_req)) != B_OK) 1396 return B_BAD_ADDRESS; 1397 1398 return ipv4_generic_delta_membership(protocol, option, 1399 greq.gsr_interface, &greq.gsr_group, &greq.gsr_source); 1400 } 1401 1402 dprintf("IPv4::setsockopt(): set unknown option: %d\n", option); 1403 return ENOPROTOOPT; 1404 } 1405 1406 return sSocketModule->set_option(protocol->socket, level, option, 1407 value, length); 1408 } 1409 1410 1411 status_t 1412 ipv4_bind(net_protocol* protocol, const struct sockaddr* address) 1413 { 1414 if (address->sa_family != AF_INET) 1415 return EAFNOSUPPORT; 1416 1417 // only INADDR_ANY and addresses of local interfaces are accepted: 1418 if (((sockaddr_in*)address)->sin_addr.s_addr == INADDR_ANY 1419 || IN_MULTICAST(ntohl(((sockaddr_in*)address)->sin_addr.s_addr)) 1420 || sDatalinkModule->is_local_address(sDomain, address, NULL, NULL)) { 1421 memcpy(&protocol->socket->address, address, sizeof(struct sockaddr_in)); 1422 protocol->socket->address.ss_len = sizeof(struct sockaddr_in); 1423 // explicitly set length, as our callers can't be trusted to 1424 // always provide the correct length! 1425 return B_OK; 1426 } 1427 1428 return B_ERROR; 1429 // address is unknown on this host 1430 } 1431 1432 1433 status_t 1434 ipv4_unbind(net_protocol* protocol, struct sockaddr* address) 1435 { 1436 // nothing to do here 1437 return B_OK; 1438 } 1439 1440 1441 status_t 1442 ipv4_listen(net_protocol* protocol, int count) 1443 { 1444 return B_NOT_SUPPORTED; 1445 } 1446 1447 1448 status_t 1449 ipv4_shutdown(net_protocol* protocol, int direction) 1450 { 1451 return B_NOT_SUPPORTED; 1452 } 1453 1454 1455 status_t 1456 ipv4_send_routed_data(net_protocol* _protocol, struct net_route* route, 1457 net_buffer* buffer) 1458 { 1459 if (route == NULL) 1460 return B_BAD_VALUE; 1461 1462 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1463 net_interface_address* interfaceAddress = route->interface_address; 1464 net_interface* interface = interfaceAddress->interface; 1465 1466 TRACE_SK(protocol, "SendRoutedData(%p, %p [%" B_PRIu32 " bytes])", route, 1467 buffer, buffer->size); 1468 1469 sockaddr_in& source = *(sockaddr_in*)buffer->source; 1470 sockaddr_in& destination = *(sockaddr_in*)buffer->destination; 1471 sockaddr_in* broadcastAddress = (sockaddr_in*)interfaceAddress->destination; 1472 1473 bool checksumNeeded = true; 1474 bool headerIncluded = false; 1475 if (protocol != NULL) 1476 headerIncluded = (protocol->flags & IP_FLAG_HEADER_INCLUDED) != 0; 1477 1478 buffer->flags &= ~(MSG_BCAST | MSG_MCAST); 1479 1480 if (destination.sin_addr.s_addr == INADDR_ANY) 1481 return EDESTADDRREQ; 1482 1483 if ((interface->device->flags & IFF_BROADCAST) != 0 1484 && (destination.sin_addr.s_addr == INADDR_BROADCAST 1485 || (broadcastAddress != NULL && destination.sin_addr.s_addr 1486 == broadcastAddress->sin_addr.s_addr))) { 1487 if (protocol && !(protocol->socket->options & SO_BROADCAST)) 1488 return B_BAD_VALUE; 1489 buffer->flags |= MSG_BCAST; 1490 } else if (IN_MULTICAST(ntohl(destination.sin_addr.s_addr))) 1491 buffer->flags |= MSG_MCAST; 1492 1493 // Add IP header (if needed) 1494 1495 if (!headerIncluded) { 1496 NetBufferPrepend<ipv4_header> header(buffer); 1497 if (header.Status() != B_OK) 1498 return header.Status(); 1499 1500 header->version = IPV4_VERSION; 1501 header->header_length = sizeof(ipv4_header) / 4; 1502 header->service_type = protocol ? protocol->service_type : 0; 1503 header->total_length = htons(buffer->size); 1504 header->id = htons(atomic_add(&sPacketID, 1)); 1505 header->fragment_offset = 0; 1506 if (protocol) { 1507 header->time_to_live = (buffer->flags & MSG_MCAST) != 0 1508 ? protocol->multicast_time_to_live : protocol->time_to_live; 1509 } else { 1510 header->time_to_live = (buffer->flags & MSG_MCAST) != 0 1511 ? kDefaultMulticastTTL : kDefaultTTL; 1512 } 1513 header->protocol = protocol 1514 ? protocol->socket->protocol : buffer->protocol; 1515 header->checksum = 0; 1516 1517 header->source = source.sin_addr.s_addr; 1518 header->destination = destination.sin_addr.s_addr; 1519 1520 TRACE_ONLY(dump_ipv4_header(*header)); 1521 } else { 1522 // if IP_HDRINCL, check if the source address is set 1523 NetBufferHeaderReader<ipv4_header> header(buffer); 1524 if (header.Status() != B_OK) 1525 return header.Status(); 1526 1527 if (header->source == 0) { 1528 header->source = source.sin_addr.s_addr; 1529 header->checksum = 0; 1530 header.Sync(); 1531 } else 1532 checksumNeeded = false; 1533 1534 TRACE(" Header was already supplied:"); 1535 TRACE_ONLY(dump_ipv4_header(*header)); 1536 } 1537 1538 if (buffer->size > 0xffff) 1539 return EMSGSIZE; 1540 1541 if (checksumNeeded) { 1542 *IPChecksumField(buffer) = gBufferModule->checksum(buffer, 0, 1543 sizeof(ipv4_header), true); 1544 } 1545 1546 TRACE_SK(protocol, " SendRoutedData(): header chksum: %" B_PRIu32 1547 ", buffer checksum: %" B_PRIu32, 1548 gBufferModule->checksum(buffer, 0, sizeof(ipv4_header), true), 1549 gBufferModule->checksum(buffer, 0, buffer->size, true)); 1550 1551 TRACE_SK(protocol, " SendRoutedData(): destination: %08x", 1552 ntohl(destination.sin_addr.s_addr)); 1553 1554 uint32 mtu = route->mtu ? route->mtu : interface->mtu; 1555 if (buffer->size > mtu) { 1556 // we need to fragment the packet 1557 return send_fragments(protocol, route, buffer, mtu); 1558 } 1559 1560 return sDatalinkModule->send_routed_data(route, buffer); 1561 } 1562 1563 1564 status_t 1565 ipv4_send_data(net_protocol* _protocol, net_buffer* buffer) 1566 { 1567 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1568 1569 TRACE_SK(protocol, "SendData(%p [%" B_PRIu32 " bytes])", buffer, 1570 buffer->size); 1571 1572 if (protocol != NULL && (protocol->flags & IP_FLAG_HEADER_INCLUDED)) { 1573 if (buffer->size < sizeof(ipv4_header)) 1574 return B_BAD_VALUE; 1575 1576 sockaddr_in* source = (sockaddr_in*)buffer->source; 1577 sockaddr_in* destination = (sockaddr_in*)buffer->destination; 1578 1579 fill_sockaddr_in(source, *NetBufferField<in_addr_t, 1580 offsetof(ipv4_header, source)>(buffer)); 1581 fill_sockaddr_in(destination, *NetBufferField<in_addr_t, 1582 offsetof(ipv4_header, destination)>(buffer)); 1583 } 1584 1585 // handle IP_MULTICAST_IF 1586 if (IN_MULTICAST(ntohl( 1587 ((sockaddr_in*)buffer->destination)->sin_addr.s_addr)) 1588 && protocol != NULL && protocol->multicast_address != NULL) { 1589 net_interface_address* address = sDatalinkModule->get_interface_address( 1590 protocol->multicast_address); 1591 if (address == NULL || (address->interface->flags & IFF_UP) == 0) { 1592 sDatalinkModule->put_interface_address(address); 1593 return EADDRNOTAVAIL; 1594 } 1595 1596 sDatalinkModule->put_interface_address(buffer->interface_address); 1597 buffer->interface_address = address; 1598 // the buffer takes over ownership of the address 1599 1600 net_route* route = sDatalinkModule->get_route(sDomain, address->local); 1601 if (route == NULL) 1602 return ENETUNREACH; 1603 1604 return sDatalinkModule->send_routed_data(route, buffer); 1605 } 1606 1607 return sDatalinkModule->send_data(protocol, sDomain, buffer); 1608 } 1609 1610 1611 ssize_t 1612 ipv4_send_avail(net_protocol* protocol) 1613 { 1614 return B_ERROR; 1615 } 1616 1617 1618 status_t 1619 ipv4_read_data(net_protocol* _protocol, size_t numBytes, uint32 flags, 1620 net_buffer** _buffer) 1621 { 1622 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1623 RawSocket* raw = protocol->raw; 1624 if (raw == NULL) 1625 return B_ERROR; 1626 1627 TRACE_SK(protocol, "ReadData(%lu, 0x%" B_PRIx32 ")", numBytes, flags); 1628 1629 return raw->Dequeue(flags, _buffer); 1630 } 1631 1632 1633 ssize_t 1634 ipv4_read_avail(net_protocol* _protocol) 1635 { 1636 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1637 RawSocket* raw = protocol->raw; 1638 if (raw == NULL) 1639 return B_ERROR; 1640 1641 return raw->AvailableData(); 1642 } 1643 1644 1645 struct net_domain* 1646 ipv4_get_domain(net_protocol* protocol) 1647 { 1648 return sDomain; 1649 } 1650 1651 1652 size_t 1653 ipv4_get_mtu(net_protocol* protocol, const struct sockaddr* address) 1654 { 1655 net_route* route = sDatalinkModule->get_route(sDomain, address); 1656 if (route == NULL) 1657 return 0; 1658 1659 size_t mtu; 1660 if (route->mtu != 0) 1661 mtu = route->mtu; 1662 else 1663 mtu = route->interface_address->interface->mtu; 1664 1665 sDatalinkModule->put_route(sDomain, route); 1666 return mtu - sizeof(ipv4_header); 1667 } 1668 1669 1670 status_t 1671 ipv4_receive_data(net_buffer* buffer) 1672 { 1673 TRACE("ipv4_receive_data(%p [%" B_PRIu32 " bytes])", buffer, buffer->size); 1674 1675 NetBufferHeaderReader<ipv4_header> bufferHeader(buffer); 1676 if (bufferHeader.Status() != B_OK) 1677 return bufferHeader.Status(); 1678 1679 ipv4_header& header = bufferHeader.Data(); 1680 TRACE_ONLY(dump_ipv4_header(header)); 1681 1682 if (header.version != IPV4_VERSION) 1683 return B_BAD_TYPE; 1684 1685 uint16 packetLength = header.TotalLength(); 1686 uint16 headerLength = header.HeaderLength(); 1687 if (packetLength > buffer->size 1688 || headerLength < sizeof(ipv4_header)) 1689 return B_BAD_DATA; 1690 1691 // TODO: would be nice to have a direct checksum function somewhere 1692 if (gBufferModule->checksum(buffer, 0, headerLength, true) != 0) 1693 return B_BAD_DATA; 1694 1695 // lower layers notion of broadcast or multicast have no relevance to us 1696 // other than deciding whether to send an ICMP error 1697 bool wasMulticast = (buffer->flags & (MSG_BCAST | MSG_MCAST)) != 0; 1698 bool notForUs = false; 1699 buffer->flags &= ~(MSG_BCAST | MSG_MCAST); 1700 1701 sockaddr_in destination; 1702 fill_sockaddr_in(&destination, header.destination); 1703 1704 if (header.destination == INADDR_BROADCAST) { 1705 buffer->flags |= MSG_BCAST; 1706 1707 // Find first interface with a matching family 1708 if (!sDatalinkModule->is_local_link_address(sDomain, true, 1709 buffer->destination, &buffer->interface_address)) 1710 notForUs = !wasMulticast; 1711 } else if (IN_MULTICAST(ntohl(header.destination))) { 1712 buffer->flags |= MSG_MCAST; 1713 } else { 1714 uint32 matchedAddressType = 0; 1715 1716 // test if the packet is really for us 1717 if (!sDatalinkModule->is_local_address(sDomain, (sockaddr*)&destination, 1718 &buffer->interface_address, &matchedAddressType) 1719 && !sDatalinkModule->is_local_link_address(sDomain, true, 1720 buffer->destination, &buffer->interface_address)) { 1721 // if the buffer was a link layer multicast, regard it as a 1722 // broadcast, and let the upper levels decide what to do with it 1723 if (wasMulticast) 1724 buffer->flags |= MSG_BCAST; 1725 else 1726 notForUs = true; 1727 } else { 1728 // copy over special address types (MSG_BCAST or MSG_MCAST): 1729 buffer->flags |= matchedAddressType; 1730 } 1731 } 1732 1733 // set net_buffer's source/destination address 1734 fill_sockaddr_in((struct sockaddr_in*)buffer->source, header.source); 1735 memcpy(buffer->destination, &destination, sizeof(sockaddr_in)); 1736 1737 buffer->protocol = header.protocol; 1738 1739 if (notForUs) { 1740 TRACE(" ipv4_receive_data(): packet was not for us %x -> %x", 1741 ntohl(header.source), ntohl(header.destination)); 1742 1743 if (!wasMulticast) { 1744 // Send ICMP error: Host unreachable 1745 sDomain->module->error_reply(NULL, buffer, B_NET_ERROR_UNREACH_HOST, 1746 NULL); 1747 } 1748 1749 return B_ERROR; 1750 } 1751 1752 // remove any trailing/padding data 1753 status_t status = gBufferModule->trim(buffer, packetLength); 1754 if (status != B_OK) 1755 return status; 1756 1757 // check for fragmentation 1758 uint16 fragmentOffset = header.FragmentOffset(); 1759 if ((fragmentOffset & IP_MORE_FRAGMENTS) != 0 1760 || (fragmentOffset & IP_FRAGMENT_OFFSET_MASK) != 0) { 1761 // this is a fragment 1762 TRACE(" ipv4_receive_data(): Found a Fragment!"); 1763 status = reassemble_fragments(header, &buffer); 1764 TRACE(" ipv4_receive_data(): -> %s", strerror(status)); 1765 if (status != B_OK) 1766 return status; 1767 1768 if (buffer == NULL) { 1769 // buffer was put into fragment packet 1770 TRACE(" ipv4_receive_data(): Not yet assembled."); 1771 return B_OK; 1772 } 1773 } 1774 1775 // Since the buffer might have been changed (reassembled fragment) 1776 // we must no longer access bufferHeader or header anymore after 1777 // this point 1778 1779 bool rawDelivered = raw_receive_data(buffer); 1780 1781 // Preserve the ipv4 header for ICMP processing 1782 gBufferModule->store_header(buffer); 1783 1784 bufferHeader.Remove(headerLength); 1785 // the header is of variable size and may include IP options 1786 // (TODO: that we ignore for now) 1787 1788 net_protocol_module_info* module = receiving_protocol(buffer->protocol); 1789 if (module == NULL) { 1790 // no handler for this packet 1791 if (!rawDelivered) { 1792 sDomain->module->error_reply(NULL, buffer, 1793 B_NET_ERROR_UNREACH_PROTOCOL, NULL); 1794 } 1795 return EAFNOSUPPORT; 1796 } 1797 1798 if ((buffer->flags & MSG_MCAST) != 0) { 1799 // Unfortunately historical reasons dictate that the IP multicast 1800 // model be a little different from the unicast one. We deliver 1801 // this frame directly to all sockets registered with interest 1802 // for this multicast group. 1803 deliver_multicast(module, buffer, false); 1804 gBufferModule->free(buffer); 1805 return B_OK; 1806 } 1807 1808 return module->receive_data(buffer); 1809 } 1810 1811 1812 status_t 1813 ipv4_deliver_data(net_protocol* _protocol, net_buffer* buffer) 1814 { 1815 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1816 1817 if (protocol->raw == NULL) 1818 return B_ERROR; 1819 1820 return protocol->raw->EnqueueClone(buffer); 1821 } 1822 1823 1824 status_t 1825 ipv4_error_received(net_error error, net_buffer* buffer) 1826 { 1827 TRACE(" ipv4_error_received(error %d, buffer %p [%" B_PRIu32 " bytes])", 1828 (int)error, buffer, buffer->size); 1829 1830 NetBufferHeaderReader<ipv4_header> bufferHeader(buffer); 1831 if (bufferHeader.Status() != B_OK) 1832 return bufferHeader.Status(); 1833 1834 ipv4_header& header = bufferHeader.Data(); 1835 TRACE_ONLY(dump_ipv4_header(header)); 1836 1837 // We do not check the packet length, as we usually only get a part of it 1838 uint16 headerLength = header.HeaderLength(); 1839 if (header.version != IPV4_VERSION 1840 || headerLength < sizeof(ipv4_header) 1841 || gBufferModule->checksum(buffer, 0, headerLength, true) != 0) 1842 return B_BAD_DATA; 1843 1844 // Restore addresses of the original buffer 1845 1846 // lower layers notion of broadcast or multicast have no relevance to us 1847 // TODO: they actually have when deciding whether to send an ICMP error 1848 buffer->flags &= ~(MSG_BCAST | MSG_MCAST); 1849 1850 fill_sockaddr_in((struct sockaddr_in*)buffer->source, header.source); 1851 fill_sockaddr_in((struct sockaddr_in*)buffer->destination, 1852 header.destination); 1853 1854 if (header.destination == INADDR_BROADCAST) 1855 buffer->flags |= MSG_BCAST; 1856 else if (IN_MULTICAST(ntohl(header.destination))) 1857 buffer->flags |= MSG_MCAST; 1858 1859 // test if the packet is really from us 1860 if (!sDatalinkModule->is_local_address(sDomain, buffer->source, NULL, 1861 NULL)) { 1862 TRACE(" ipv4_error_received(): packet was not for us %x -> %x", 1863 ntohl(header.source), ntohl(header.destination)); 1864 return B_ERROR; 1865 } 1866 1867 buffer->protocol = header.protocol; 1868 1869 bufferHeader.Remove(headerLength); 1870 1871 net_protocol_module_info* protocol = receiving_protocol(buffer->protocol); 1872 if (protocol == NULL) 1873 return B_ERROR; 1874 1875 // propagate error 1876 return protocol->error_received(error, buffer); 1877 } 1878 1879 1880 status_t 1881 ipv4_error_reply(net_protocol* protocol, net_buffer* cause, net_error error, 1882 net_error_data* errorData) 1883 { 1884 // Directly obtain the ICMP protocol module 1885 net_protocol_module_info* icmp = receiving_protocol(IPPROTO_ICMP); 1886 if (icmp == NULL) 1887 return B_ERROR; 1888 1889 return icmp->error_reply(protocol, cause, error, errorData); 1890 } 1891 1892 1893 ssize_t 1894 ipv4_process_ancillary_data_no_container(net_protocol* protocol, 1895 net_buffer* buffer, void* msgControl, size_t msgControlLen) 1896 { 1897 ssize_t bytesWritten = 0; 1898 1899 if ((((ipv4_protocol*)protocol)->flags & IP_FLAG_RECEIVE_DEST_ADDR) != 0) { 1900 if (msgControlLen < CMSG_SPACE(sizeof(struct in_addr))) 1901 return B_NO_MEMORY; 1902 1903 cmsghdr* messageHeader = (cmsghdr*)msgControl; 1904 messageHeader->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); 1905 messageHeader->cmsg_level = IPPROTO_IP; 1906 messageHeader->cmsg_type = IP_RECVDSTADDR; 1907 1908 memcpy(CMSG_DATA(messageHeader), 1909 &((struct sockaddr_in*)buffer->destination)->sin_addr, 1910 sizeof(struct in_addr)); 1911 1912 bytesWritten += CMSG_SPACE(sizeof(struct in_addr)); 1913 } 1914 1915 return bytesWritten; 1916 } 1917 1918 1919 // #pragma mark - 1920 1921 1922 status_t 1923 init_ipv4() 1924 { 1925 sPacketID = (int32)system_time(); 1926 1927 mutex_init(&sRawSocketsLock, "raw sockets"); 1928 mutex_init(&sFragmentLock, "IPv4 Fragments"); 1929 mutex_init(&sMulticastGroupsLock, "IPv4 multicast groups"); 1930 mutex_init(&sReceivingProtocolLock, "IPv4 receiving protocols"); 1931 1932 status_t status; 1933 1934 sMulticastState = new MulticastState(); 1935 if (sMulticastState == NULL) { 1936 status = B_NO_MEMORY; 1937 goto err4; 1938 } 1939 1940 status = sMulticastState->Init(); 1941 if (status != B_OK) 1942 goto err5; 1943 1944 new (&sFragmentHash) FragmentTable(); 1945 status = sFragmentHash.Init(256); 1946 if (status != B_OK) 1947 goto err5; 1948 1949 new (&sRawSockets) RawSocketList; 1950 // static initializers do not work in the kernel, 1951 // so we have to do it here, manually 1952 // TODO: for modules, this shouldn't be required 1953 1954 status = gStackModule->register_domain_protocols(AF_INET, SOCK_RAW, 0, 1955 "network/protocols/ipv4/v1", NULL); 1956 if (status != B_OK) 1957 goto err6; 1958 1959 status = gStackModule->register_domain(AF_INET, "internet", &gIPv4Module, 1960 &gIPv4AddressModule, &sDomain); 1961 if (status != B_OK) 1962 goto err6; 1963 1964 add_debugger_command("ipv4_multicast", dump_ipv4_multicast, 1965 "list all current IPv4 multicast states"); 1966 1967 return B_OK; 1968 1969 err6: 1970 sFragmentHash.~FragmentTable(); 1971 err5: 1972 delete sMulticastState; 1973 err4: 1974 mutex_destroy(&sReceivingProtocolLock); 1975 mutex_destroy(&sMulticastGroupsLock); 1976 mutex_destroy(&sFragmentLock); 1977 mutex_destroy(&sRawSocketsLock); 1978 return status; 1979 } 1980 1981 1982 status_t 1983 uninit_ipv4() 1984 { 1985 mutex_lock(&sReceivingProtocolLock); 1986 1987 remove_debugger_command("ipv4_multicast", dump_ipv4_multicast); 1988 1989 // put all the domain receiving protocols we gathered so far 1990 for (uint32 i = 0; i < 256; i++) { 1991 if (sReceivingProtocol[i] != NULL) 1992 gStackModule->put_domain_receiving_protocol(sDomain, i); 1993 } 1994 1995 gStackModule->unregister_domain(sDomain); 1996 mutex_unlock(&sReceivingProtocolLock); 1997 1998 delete sMulticastState; 1999 sFragmentHash.~FragmentTable(); 2000 2001 mutex_destroy(&sMulticastGroupsLock); 2002 mutex_destroy(&sFragmentLock); 2003 mutex_destroy(&sRawSocketsLock); 2004 mutex_destroy(&sReceivingProtocolLock); 2005 2006 return B_OK; 2007 } 2008 2009 2010 static status_t 2011 ipv4_std_ops(int32 op, ...) 2012 { 2013 switch (op) { 2014 case B_MODULE_INIT: 2015 return init_ipv4(); 2016 case B_MODULE_UNINIT: 2017 return uninit_ipv4(); 2018 2019 default: 2020 return B_ERROR; 2021 } 2022 } 2023 2024 2025 net_protocol_module_info gIPv4Module = { 2026 { 2027 "network/protocols/ipv4/v1", 2028 0, 2029 ipv4_std_ops 2030 }, 2031 NET_PROTOCOL_ATOMIC_MESSAGES, 2032 2033 ipv4_init_protocol, 2034 ipv4_uninit_protocol, 2035 ipv4_open, 2036 ipv4_close, 2037 ipv4_free, 2038 ipv4_connect, 2039 ipv4_accept, 2040 ipv4_control, 2041 ipv4_getsockopt, 2042 ipv4_setsockopt, 2043 ipv4_bind, 2044 ipv4_unbind, 2045 ipv4_listen, 2046 ipv4_shutdown, 2047 ipv4_send_data, 2048 ipv4_send_routed_data, 2049 ipv4_send_avail, 2050 ipv4_read_data, 2051 ipv4_read_avail, 2052 ipv4_get_domain, 2053 ipv4_get_mtu, 2054 ipv4_receive_data, 2055 ipv4_deliver_data, 2056 ipv4_error_received, 2057 ipv4_error_reply, 2058 NULL, // add_ancillary_data() 2059 NULL, // process_ancillary_data() 2060 ipv4_process_ancillary_data_no_container, 2061 NULL, // send_data_no_buffer() 2062 NULL // read_data_no_buffer() 2063 }; 2064 2065 module_dependency module_dependencies[] = { 2066 {NET_STACK_MODULE_NAME, (module_info**)&gStackModule}, 2067 {NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule}, 2068 {NET_DATALINK_MODULE_NAME, (module_info**)&sDatalinkModule}, 2069 {NET_SOCKET_MODULE_NAME, (module_info**)&sSocketModule}, 2070 {} 2071 }; 2072 2073 module_info* modules[] = { 2074 (module_info*)&gIPv4Module, 2075 NULL 2076 }; 2077