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.InsertBefore(next, previous); 335 return status; 336 } 337 338 fFragments.InsertBefore(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.InsertBefore(afterNext, next); 363 return status; 364 } 365 366 fFragments.InsertBefore(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.InsertBefore(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 status_t ipv4_receive_data(net_buffer* buffer); 689 690 691 /*! Delivers the provided \a buffer to all listeners of this multicast group. 692 Does not take over ownership of the buffer. 693 */ 694 static bool 695 deliver_multicast(net_protocol_module_info* module, net_buffer* buffer, 696 bool deliverToRaw) 697 { 698 TRACE("deliver_multicast(%p [%" B_PRIu32 " bytes])", buffer, buffer->size); 699 if (module->deliver_data == NULL) 700 return false; 701 702 MutexLocker _(sMulticastGroupsLock); 703 704 sockaddr_in* multicastAddr = (sockaddr_in*)buffer->destination; 705 706 uint32 index = buffer->index; 707 if (buffer->interface_address != NULL) 708 index = buffer->interface_address->interface->index; 709 710 MulticastState::ValueIterator it = sMulticastState->Lookup(std::make_pair( 711 &multicastAddr->sin_addr, index)); 712 713 size_t count = 0; 714 715 while (it.HasNext()) { 716 IPv4GroupInterface* state = it.Next(); 717 718 ipv4_protocol* ipProtocol = state->Parent()->Socket(); 719 if (deliverToRaw && (ipProtocol->raw == NULL 720 || ipProtocol->socket->protocol != buffer->protocol)) 721 continue; 722 723 if (state->FilterAccepts(buffer)) { 724 net_protocol* protocol = ipProtocol; 725 if (protocol->module != module) { 726 // as multicast filters are installed with an IPv4 protocol 727 // reference, we need to go and find the appropriate instance 728 // related to the 'receiving protocol' with module 'module'. 729 protocol = ipProtocol->socket->first_protocol; 730 731 while (protocol != NULL && protocol->module != module) 732 protocol = protocol->next; 733 } 734 735 if (protocol != NULL) { 736 module->deliver_data(protocol, buffer); 737 count++; 738 } 739 } 740 } 741 742 return count > 0; 743 } 744 745 746 /*! Delivers the buffer to all listening raw sockets without taking ownership of 747 the provided \a buffer. 748 Returns \c true if there was any receiver, \c false if not. 749 */ 750 static bool 751 raw_receive_data(net_buffer* buffer) 752 { 753 MutexLocker locker(sRawSocketsLock); 754 755 if (sRawSockets.IsEmpty()) 756 return false; 757 758 TRACE("RawReceiveData(%i)", buffer->protocol); 759 760 if ((buffer->flags & MSG_MCAST) != 0) { 761 // we need to call deliver_multicast here separately as 762 // buffer still has the IP header, and it won't in the 763 // next call. This isn't very optimized but works for now. 764 // A better solution would be to hold separate hash tables 765 // and lists for RAW and non-RAW sockets. 766 return deliver_multicast(&gIPv4Module, buffer, true); 767 } 768 769 RawSocketList::Iterator iterator = sRawSockets.GetIterator(); 770 size_t count = 0; 771 772 while (iterator.HasNext()) { 773 RawSocket* raw = iterator.Next(); 774 775 if (raw->Socket()->protocol == buffer->protocol) { 776 raw->EnqueueClone(buffer); 777 count++; 778 } 779 } 780 781 return count > 0; 782 } 783 784 785 static inline sockaddr* 786 fill_sockaddr_in(sockaddr_in* target, in_addr_t address) 787 { 788 target->sin_family = AF_INET; 789 target->sin_len = sizeof(sockaddr_in); 790 target->sin_port = 0; 791 target->sin_addr.s_addr = address; 792 return (sockaddr*)target; 793 } 794 795 796 static status_t 797 get_int_option(void* target, size_t length, int value) 798 { 799 if (length != sizeof(int)) 800 return B_BAD_VALUE; 801 802 return user_memcpy(target, &value, sizeof(int)); 803 } 804 805 806 static status_t 807 get_char_int_option(void* target, size_t length, int value) 808 { 809 if (length == sizeof(int)) 810 return user_memcpy(target, &value, sizeof(int)); 811 if (length == sizeof(unsigned char)) { 812 unsigned char uvalue = value; 813 return user_memcpy(target, &uvalue, sizeof(uvalue)); 814 } 815 return B_BAD_VALUE; 816 } 817 818 819 template<typename Type> static status_t 820 set_int_option(Type &target, const void* _value, size_t length) 821 { 822 int value; 823 824 if (length != sizeof(int)) 825 return B_BAD_VALUE; 826 827 if (user_memcpy(&value, _value, sizeof(int)) != B_OK) 828 return B_BAD_ADDRESS; 829 830 target = value; 831 return B_OK; 832 } 833 834 835 template<typename Type> static status_t 836 set_char_int_option(Type &target, const void* _value, size_t length) 837 { 838 if (length == sizeof(int)) { 839 int value; 840 if (user_memcpy(&value, _value, sizeof(int)) != B_OK) 841 return B_BAD_ADDRESS; 842 if (value > 255) 843 return B_BAD_VALUE; 844 target = value; 845 return B_OK; 846 } 847 if (length == sizeof(unsigned char)) { 848 unsigned char value; 849 if (user_memcpy(&value, _value, sizeof(value)) != B_OK) 850 return B_BAD_ADDRESS; 851 852 target = value; 853 return B_OK; 854 } 855 return B_BAD_VALUE; 856 } 857 858 859 static net_protocol_module_info* 860 receiving_protocol(uint8 protocol) 861 { 862 net_protocol_module_info* module = sReceivingProtocol[protocol]; 863 if (module != NULL) 864 return module; 865 866 MutexLocker locker(sReceivingProtocolLock); 867 868 module = sReceivingProtocol[protocol]; 869 if (module != NULL) 870 return module; 871 872 if (gStackModule->get_domain_receiving_protocol(sDomain, protocol, 873 &module) == B_OK) 874 sReceivingProtocol[protocol] = module; 875 876 return module; 877 } 878 879 880 // #pragma mark - multicast 881 882 883 status_t 884 IPv4Multicast::JoinGroup(IPv4GroupInterface* state) 885 { 886 MutexLocker _(sMulticastGroupsLock); 887 888 sockaddr_in groupAddr; 889 status_t status = sDatalinkModule->join_multicast(state->Interface(), 890 sDomain, fill_sockaddr_in(&groupAddr, state->Address().s_addr)); 891 if (status != B_OK) 892 return status; 893 894 sMulticastState->Insert(state); 895 return B_OK; 896 } 897 898 899 status_t 900 IPv4Multicast::LeaveGroup(IPv4GroupInterface* state) 901 { 902 MutexLocker _(sMulticastGroupsLock); 903 904 sMulticastState->Remove(state); 905 906 sockaddr_in groupAddr; 907 return sDatalinkModule->leave_multicast(state->Interface(), sDomain, 908 fill_sockaddr_in(&groupAddr, state->Address().s_addr)); 909 } 910 911 912 static status_t 913 ipv4_delta_group(IPv4GroupInterface* group, int option, 914 net_interface* interface, const in_addr* sourceAddr) 915 { 916 switch (option) { 917 case IP_ADD_MEMBERSHIP: 918 return group->Add(); 919 case IP_DROP_MEMBERSHIP: 920 return group->Drop(); 921 case IP_BLOCK_SOURCE: 922 return group->BlockSource(*sourceAddr); 923 case IP_UNBLOCK_SOURCE: 924 return group->UnblockSource(*sourceAddr); 925 case IP_ADD_SOURCE_MEMBERSHIP: 926 return group->AddSSM(*sourceAddr); 927 case IP_DROP_SOURCE_MEMBERSHIP: 928 return group->DropSSM(*sourceAddr); 929 } 930 931 return B_ERROR; 932 } 933 934 935 static status_t 936 ipv4_delta_membership(ipv4_protocol* protocol, int option, 937 net_interface* interface, const in_addr* groupAddr, 938 const in_addr* sourceAddr) 939 { 940 IPv4MulticastFilter& filter = protocol->multicast_filter; 941 IPv4GroupInterface* state = NULL; 942 status_t status = B_OK; 943 944 switch (option) { 945 case IP_ADD_MEMBERSHIP: 946 case IP_ADD_SOURCE_MEMBERSHIP: 947 status = filter.GetState(*groupAddr, interface, state, true); 948 break; 949 950 case IP_DROP_MEMBERSHIP: 951 case IP_BLOCK_SOURCE: 952 case IP_UNBLOCK_SOURCE: 953 case IP_DROP_SOURCE_MEMBERSHIP: 954 filter.GetState(*groupAddr, interface, state, false); 955 if (state == NULL) { 956 if (option == IP_DROP_MEMBERSHIP 957 || option == IP_DROP_SOURCE_MEMBERSHIP) 958 return EADDRNOTAVAIL; 959 960 return B_BAD_VALUE; 961 } 962 break; 963 } 964 965 if (status != B_OK) 966 return status; 967 968 status = ipv4_delta_group(state, option, interface, sourceAddr); 969 filter.ReturnState(state); 970 return status; 971 } 972 973 974 static int 975 generic_to_ipv4(int option) 976 { 977 switch (option) { 978 case MCAST_JOIN_GROUP: 979 return IP_ADD_MEMBERSHIP; 980 case MCAST_JOIN_SOURCE_GROUP: 981 return IP_ADD_SOURCE_MEMBERSHIP; 982 case MCAST_LEAVE_GROUP: 983 return IP_DROP_MEMBERSHIP; 984 case MCAST_BLOCK_SOURCE: 985 return IP_BLOCK_SOURCE; 986 case MCAST_UNBLOCK_SOURCE: 987 return IP_UNBLOCK_SOURCE; 988 case MCAST_LEAVE_SOURCE_GROUP: 989 return IP_DROP_SOURCE_MEMBERSHIP; 990 } 991 992 return -1; 993 } 994 995 996 static net_interface* 997 get_multicast_interface(ipv4_protocol* protocol, const in_addr* address) 998 { 999 // TODO: this is broken and leaks references 1000 sockaddr_in groupAddr; 1001 net_route* route = sDatalinkModule->get_route(sDomain, 1002 fill_sockaddr_in(&groupAddr, address ? address->s_addr : INADDR_ANY)); 1003 if (route == NULL) 1004 return NULL; 1005 1006 return route->interface_address->interface; 1007 } 1008 1009 1010 static status_t 1011 ipv4_delta_membership(ipv4_protocol* protocol, int option, 1012 in_addr* interfaceAddr, in_addr* groupAddr, in_addr* sourceAddr) 1013 { 1014 net_interface* interface = NULL; 1015 1016 if (interfaceAddr->s_addr == INADDR_ANY) { 1017 interface = get_multicast_interface(protocol, groupAddr); 1018 } else { 1019 sockaddr_in address; 1020 interface = sDatalinkModule->get_interface_with_address( 1021 fill_sockaddr_in(&address, interfaceAddr->s_addr)); 1022 } 1023 1024 if (interface == NULL) 1025 return B_DEVICE_NOT_FOUND; 1026 1027 return ipv4_delta_membership(protocol, option, interface, 1028 groupAddr, sourceAddr); 1029 } 1030 1031 1032 static status_t 1033 ipv4_generic_delta_membership(ipv4_protocol* protocol, int option, 1034 uint32 index, const sockaddr_storage* _groupAddr, 1035 const sockaddr_storage* _sourceAddr) 1036 { 1037 if (_groupAddr->ss_family != AF_INET 1038 || (_sourceAddr != NULL && _sourceAddr->ss_family != AF_INET)) 1039 return B_BAD_VALUE; 1040 1041 const in_addr* groupAddr = &((const sockaddr_in*)_groupAddr)->sin_addr; 1042 1043 // TODO: this is broken and leaks references 1044 net_interface* interface; 1045 if (index == 0) 1046 interface = get_multicast_interface(protocol, groupAddr); 1047 else 1048 interface = sDatalinkModule->get_interface(sDomain, index); 1049 1050 if (interface == NULL) 1051 return B_DEVICE_NOT_FOUND; 1052 1053 const in_addr* sourceAddr = NULL; 1054 if (_sourceAddr != NULL) 1055 sourceAddr = &((const sockaddr_in*)_sourceAddr)->sin_addr; 1056 1057 return ipv4_delta_membership(protocol, generic_to_ipv4(option), interface, 1058 groupAddr, sourceAddr); 1059 } 1060 1061 1062 // #pragma mark - module interface 1063 1064 1065 net_protocol* 1066 ipv4_init_protocol(net_socket* socket) 1067 { 1068 ipv4_protocol* protocol = new (std::nothrow) ipv4_protocol(); 1069 if (protocol == NULL) 1070 return NULL; 1071 1072 protocol->raw = NULL; 1073 protocol->service_type = 0; 1074 protocol->time_to_live = kDefaultTTL; 1075 protocol->multicast_time_to_live = kDefaultMulticastTTL; 1076 protocol->multicast_loopback = kDefaultMulticastLoopback; 1077 protocol->flags = 0; 1078 protocol->multicast_address = NULL; 1079 return protocol; 1080 } 1081 1082 1083 status_t 1084 ipv4_uninit_protocol(net_protocol* _protocol) 1085 { 1086 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1087 1088 delete protocol; 1089 1090 return B_OK; 1091 } 1092 1093 1094 /*! Since open() is only called on the top level protocol, when we get here 1095 it means we are on a SOCK_RAW socket. 1096 */ 1097 status_t 1098 ipv4_open(net_protocol* _protocol) 1099 { 1100 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1101 1102 // Only root may open raw sockets 1103 if (geteuid() != 0) 1104 return B_NOT_ALLOWED; 1105 1106 RawSocket* raw = new (std::nothrow) RawSocket(protocol->socket); 1107 if (raw == NULL) 1108 return B_NO_MEMORY; 1109 1110 status_t status = raw->InitCheck(); 1111 if (status != B_OK) { 1112 delete raw; 1113 return status; 1114 } 1115 1116 TRACE_SK(protocol, "Open()"); 1117 1118 protocol->raw = raw; 1119 1120 MutexLocker locker(sRawSocketsLock); 1121 sRawSockets.Add(raw); 1122 return B_OK; 1123 } 1124 1125 1126 status_t 1127 ipv4_close(net_protocol* _protocol) 1128 { 1129 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1130 RawSocket* raw = protocol->raw; 1131 if (raw == NULL) 1132 return B_ERROR; 1133 1134 TRACE_SK(protocol, "Close()"); 1135 1136 MutexLocker locker(sRawSocketsLock); 1137 sRawSockets.Remove(raw); 1138 delete raw; 1139 protocol->raw = NULL; 1140 1141 return B_OK; 1142 } 1143 1144 1145 status_t 1146 ipv4_free(net_protocol* protocol) 1147 { 1148 return B_OK; 1149 } 1150 1151 1152 status_t 1153 ipv4_connect(net_protocol* _protocol, const struct sockaddr* address) 1154 { 1155 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1156 RawSocket* raw = protocol->raw; 1157 if (raw == NULL) 1158 return B_ERROR; 1159 if (address->sa_len != sizeof(struct sockaddr_in)) 1160 return B_BAD_VALUE; 1161 if (address->sa_family != AF_INET) 1162 return EAFNOSUPPORT; 1163 1164 memcpy(&protocol->socket->peer, address, sizeof(struct sockaddr_in)); 1165 sSocketModule->set_connected(protocol->socket); 1166 1167 return B_OK; 1168 } 1169 1170 1171 status_t 1172 ipv4_accept(net_protocol* protocol, struct net_socket** _acceptedSocket) 1173 { 1174 return B_NOT_SUPPORTED; 1175 } 1176 1177 1178 status_t 1179 ipv4_control(net_protocol* _protocol, int level, int option, void* value, 1180 size_t* _length) 1181 { 1182 if ((level & LEVEL_MASK) != IPPROTO_IP) 1183 return sDatalinkModule->control(sDomain, option, value, _length); 1184 1185 return B_BAD_VALUE; 1186 } 1187 1188 1189 status_t 1190 ipv4_getsockopt(net_protocol* _protocol, int level, int option, void* value, 1191 int* _length) 1192 { 1193 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1194 1195 if (level == IPPROTO_IP) { 1196 bool isDgramOrRaw = protocol->socket->type == SOCK_DGRAM 1197 || protocol->socket->type == SOCK_RAW; 1198 if (option == IP_HDRINCL) { 1199 return get_int_option(value, *_length, 1200 (protocol->flags & IP_FLAG_HEADER_INCLUDED) != 0); 1201 } 1202 if (option == IP_RECVDSTADDR) { 1203 return get_int_option(value, *_length, 1204 (protocol->flags & IP_FLAG_RECEIVE_DEST_ADDR) != 0); 1205 } 1206 if (option == IP_TTL) 1207 return get_int_option(value, *_length, protocol->time_to_live); 1208 if (option == IP_TOS) 1209 return get_int_option(value, *_length, protocol->service_type); 1210 if (option == IP_MULTICAST_IF) { 1211 if (*_length != sizeof(struct in_addr)) 1212 return B_BAD_VALUE; 1213 if (!isDgramOrRaw) 1214 return B_NOT_SUPPORTED; 1215 struct sockaddr_in defaultAddress; 1216 defaultAddress.sin_addr.s_addr = htonl(INADDR_ANY); 1217 struct sockaddr_in* address = 1218 (struct sockaddr_in*)protocol->multicast_address; 1219 if (address == NULL) 1220 address = &defaultAddress; 1221 if (user_memcpy(value, &address->sin_addr, sizeof(struct in_addr)) 1222 != B_OK) { 1223 return B_BAD_ADDRESS; 1224 } 1225 return B_OK; 1226 } 1227 if (option == IP_MULTICAST_TTL) { 1228 if (!isDgramOrRaw) 1229 return B_NOT_SUPPORTED; 1230 return get_char_int_option(value, *_length, 1231 protocol->multicast_time_to_live); 1232 } 1233 if (option == IP_MULTICAST_LOOP) { 1234 if (!isDgramOrRaw) 1235 return B_NOT_SUPPORTED; 1236 return get_char_int_option(value, *_length, 1237 protocol->multicast_loopback ? 1 : 0); 1238 } 1239 if (option == IP_ADD_MEMBERSHIP 1240 || option == IP_DROP_MEMBERSHIP 1241 || option == IP_BLOCK_SOURCE 1242 || option == IP_UNBLOCK_SOURCE 1243 || option == IP_ADD_SOURCE_MEMBERSHIP 1244 || option == IP_DROP_SOURCE_MEMBERSHIP 1245 || option == MCAST_JOIN_GROUP 1246 || option == MCAST_LEAVE_GROUP 1247 || option == MCAST_BLOCK_SOURCE 1248 || option == MCAST_UNBLOCK_SOURCE 1249 || option == MCAST_JOIN_SOURCE_GROUP 1250 || option == MCAST_LEAVE_SOURCE_GROUP) { 1251 // RFC 3678, Section 4.1: 1252 // ``An error of EOPNOTSUPP is returned if these options are 1253 // used with getsockopt().'' 1254 return B_NOT_SUPPORTED; 1255 } 1256 1257 dprintf("IPv4::getsockopt(): get unknown option: %d\n", option); 1258 return ENOPROTOOPT; 1259 } 1260 1261 return sSocketModule->get_option(protocol->socket, level, option, value, 1262 _length); 1263 } 1264 1265 1266 status_t 1267 ipv4_setsockopt(net_protocol* _protocol, int level, int option, 1268 const void* value, int length) 1269 { 1270 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1271 1272 if (level == IPPROTO_IP) { 1273 bool isDgramOrRaw = protocol->socket->type == SOCK_DGRAM 1274 || protocol->socket->type == SOCK_RAW; 1275 if (option == IP_HDRINCL) { 1276 int headerIncluded; 1277 if (length != sizeof(int)) 1278 return B_BAD_VALUE; 1279 if (user_memcpy(&headerIncluded, value, sizeof(headerIncluded)) 1280 != B_OK) 1281 return B_BAD_ADDRESS; 1282 1283 if (headerIncluded) 1284 protocol->flags |= IP_FLAG_HEADER_INCLUDED; 1285 else 1286 protocol->flags &= ~IP_FLAG_HEADER_INCLUDED; 1287 1288 return B_OK; 1289 } 1290 if (option == IP_RECVDSTADDR) { 1291 int getAddress; 1292 if (length != sizeof(int)) 1293 return B_BAD_VALUE; 1294 if (user_memcpy(&getAddress, value, sizeof(int)) != B_OK) 1295 return B_BAD_ADDRESS; 1296 1297 if (getAddress && (protocol->socket->type == SOCK_DGRAM 1298 || protocol->socket->type == SOCK_RAW)) 1299 protocol->flags |= IP_FLAG_RECEIVE_DEST_ADDR; 1300 else 1301 protocol->flags &= ~IP_FLAG_RECEIVE_DEST_ADDR; 1302 1303 return B_OK; 1304 } 1305 if (option == IP_TTL) 1306 return set_int_option(protocol->time_to_live, value, length); 1307 if (option == IP_TOS) 1308 return set_int_option(protocol->service_type, value, length); 1309 if (option == IP_MULTICAST_IF) { 1310 if (length != sizeof(struct in_addr)) 1311 return B_BAD_VALUE; 1312 if (!isDgramOrRaw) 1313 return B_NOT_SUPPORTED; 1314 1315 struct sockaddr_in* address = new (std::nothrow) sockaddr_in; 1316 if (address == NULL) 1317 return B_NO_MEMORY; 1318 1319 struct in_addr sin_addr; 1320 if (user_memcpy(&sin_addr, value, sizeof(struct in_addr)) 1321 != B_OK) { 1322 delete address; 1323 return B_BAD_ADDRESS; 1324 } 1325 fill_sockaddr_in(address, sin_addr.s_addr); 1326 1327 // Using INADDR_ANY to remove the previous setting. 1328 if (address->sin_addr.s_addr == htonl(INADDR_ANY)) { 1329 delete address; 1330 delete protocol->multicast_address; 1331 protocol->multicast_address = NULL; 1332 return B_OK; 1333 } 1334 1335 struct net_interface* interface 1336 = sDatalinkModule->get_interface_with_address( 1337 (sockaddr*)address); 1338 if (interface == NULL) { 1339 delete address; 1340 return EADDRNOTAVAIL; 1341 } 1342 1343 delete protocol->multicast_address; 1344 protocol->multicast_address = (struct sockaddr*)address; 1345 1346 sDatalinkModule->put_interface(interface); 1347 return B_OK; 1348 } 1349 if (option == IP_MULTICAST_TTL) { 1350 if (!isDgramOrRaw) 1351 return B_NOT_SUPPORTED; 1352 return set_char_int_option(protocol->multicast_time_to_live, value, 1353 length); 1354 } 1355 if (option == IP_MULTICAST_LOOP) { 1356 if (!isDgramOrRaw) 1357 return B_NOT_SUPPORTED; 1358 uint8 multicast_loopback; 1359 status_t status = set_char_int_option(multicast_loopback, value, 1360 length); 1361 if (status == B_OK) 1362 protocol->multicast_loopback = multicast_loopback != 0; 1363 return status; 1364 } 1365 if (option == IP_ADD_MEMBERSHIP || option == IP_DROP_MEMBERSHIP) { 1366 if (!isDgramOrRaw) 1367 return B_NOT_SUPPORTED; 1368 ip_mreq mreq; 1369 if (length != sizeof(ip_mreq)) 1370 return B_BAD_VALUE; 1371 if (user_memcpy(&mreq, value, sizeof(ip_mreq)) != B_OK) 1372 return B_BAD_ADDRESS; 1373 1374 return ipv4_delta_membership(protocol, option, &mreq.imr_interface, 1375 &mreq.imr_multiaddr, NULL); 1376 } 1377 if (option == IP_BLOCK_SOURCE 1378 || option == IP_UNBLOCK_SOURCE 1379 || option == IP_ADD_SOURCE_MEMBERSHIP 1380 || option == IP_DROP_SOURCE_MEMBERSHIP) { 1381 if (!isDgramOrRaw) 1382 return B_NOT_SUPPORTED; 1383 ip_mreq_source mreq; 1384 if (length != sizeof(ip_mreq_source)) 1385 return B_BAD_VALUE; 1386 if (user_memcpy(&mreq, value, sizeof(ip_mreq_source)) != B_OK) 1387 return B_BAD_ADDRESS; 1388 1389 return ipv4_delta_membership(protocol, option, &mreq.imr_interface, 1390 &mreq.imr_multiaddr, &mreq.imr_sourceaddr); 1391 } 1392 if (option == MCAST_LEAVE_GROUP || option == MCAST_JOIN_GROUP) { 1393 if (!isDgramOrRaw) 1394 return B_NOT_SUPPORTED; 1395 group_req greq; 1396 if (length != sizeof(group_req)) 1397 return B_BAD_VALUE; 1398 if (user_memcpy(&greq, value, sizeof(group_req)) != B_OK) 1399 return B_BAD_ADDRESS; 1400 1401 return ipv4_generic_delta_membership(protocol, option, 1402 greq.gr_interface, &greq.gr_group, NULL); 1403 } 1404 if (option == MCAST_BLOCK_SOURCE 1405 || option == MCAST_UNBLOCK_SOURCE 1406 || option == MCAST_JOIN_SOURCE_GROUP 1407 || option == MCAST_LEAVE_SOURCE_GROUP) { 1408 if (!isDgramOrRaw) 1409 return B_NOT_SUPPORTED; 1410 group_source_req greq; 1411 if (length != sizeof(group_source_req)) 1412 return B_BAD_VALUE; 1413 if (user_memcpy(&greq, value, sizeof(group_source_req)) != B_OK) 1414 return B_BAD_ADDRESS; 1415 1416 return ipv4_generic_delta_membership(protocol, option, 1417 greq.gsr_interface, &greq.gsr_group, &greq.gsr_source); 1418 } 1419 1420 dprintf("IPv4::setsockopt(): set unknown option: %d\n", option); 1421 return ENOPROTOOPT; 1422 } 1423 1424 return sSocketModule->set_option(protocol->socket, level, option, 1425 value, length); 1426 } 1427 1428 1429 status_t 1430 ipv4_bind(net_protocol* protocol, const struct sockaddr* address) 1431 { 1432 if (address->sa_family != AF_INET) 1433 return EAFNOSUPPORT; 1434 1435 // only INADDR_ANY and addresses of local interfaces are accepted: 1436 if (((sockaddr_in*)address)->sin_addr.s_addr == INADDR_ANY 1437 || IN_MULTICAST(ntohl(((sockaddr_in*)address)->sin_addr.s_addr)) 1438 || sDatalinkModule->is_local_address(sDomain, address, NULL, NULL)) { 1439 memcpy(&protocol->socket->address, address, sizeof(struct sockaddr_in)); 1440 protocol->socket->address.ss_len = sizeof(struct sockaddr_in); 1441 // explicitly set length, as our callers can't be trusted to 1442 // always provide the correct length! 1443 return B_OK; 1444 } 1445 1446 return EADDRNOTAVAIL; 1447 // address is unknown on this host 1448 } 1449 1450 1451 status_t 1452 ipv4_unbind(net_protocol* protocol, struct sockaddr* address) 1453 { 1454 // nothing to do here 1455 return B_OK; 1456 } 1457 1458 1459 status_t 1460 ipv4_listen(net_protocol* protocol, int count) 1461 { 1462 return B_NOT_SUPPORTED; 1463 } 1464 1465 1466 status_t 1467 ipv4_shutdown(net_protocol* protocol, int direction) 1468 { 1469 return B_NOT_SUPPORTED; 1470 } 1471 1472 1473 status_t 1474 ipv4_send_routed_data(net_protocol* _protocol, struct net_route* route, 1475 net_buffer* buffer) 1476 { 1477 if (route == NULL) 1478 return B_BAD_VALUE; 1479 1480 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1481 net_interface_address* interfaceAddress = route->interface_address; 1482 net_interface* interface = interfaceAddress->interface; 1483 1484 TRACE_SK(protocol, "SendRoutedData(%p, %p [%" B_PRIu32 " bytes])", route, 1485 buffer, buffer->size); 1486 1487 sockaddr_in& source = *(sockaddr_in*)buffer->source; 1488 sockaddr_in& destination = *(sockaddr_in*)buffer->destination; 1489 sockaddr_in* broadcastAddress = (sockaddr_in*)interfaceAddress->destination; 1490 1491 bool checksumNeeded = true; 1492 bool headerIncluded = false; 1493 if (protocol != NULL) 1494 headerIncluded = (protocol->flags & IP_FLAG_HEADER_INCLUDED) != 0; 1495 1496 buffer->flags &= ~(MSG_BCAST | MSG_MCAST); 1497 1498 if (destination.sin_addr.s_addr == INADDR_ANY) 1499 return EDESTADDRREQ; 1500 1501 if ((interface->device->flags & IFF_BROADCAST) != 0 1502 && (destination.sin_addr.s_addr == INADDR_BROADCAST 1503 || (broadcastAddress != NULL && destination.sin_addr.s_addr 1504 == broadcastAddress->sin_addr.s_addr))) { 1505 if (protocol && !(protocol->socket->options & SO_BROADCAST)) 1506 return B_BAD_VALUE; 1507 buffer->flags |= MSG_BCAST; 1508 } else if (IN_MULTICAST(ntohl(destination.sin_addr.s_addr))) 1509 buffer->flags |= MSG_MCAST; 1510 1511 // Add IP header (if needed) 1512 1513 if (!headerIncluded) { 1514 NetBufferPrepend<ipv4_header> header(buffer); 1515 if (header.Status() != B_OK) 1516 return header.Status(); 1517 1518 header->version = IPV4_VERSION; 1519 header->header_length = sizeof(ipv4_header) / 4; 1520 header->service_type = protocol ? protocol->service_type : 0; 1521 header->total_length = htons(buffer->size); 1522 header->id = htons(atomic_add(&sPacketID, 1)); 1523 header->fragment_offset = 0; 1524 if (protocol) { 1525 header->time_to_live = (buffer->flags & MSG_MCAST) != 0 1526 ? protocol->multicast_time_to_live : protocol->time_to_live; 1527 } else { 1528 header->time_to_live = (buffer->flags & MSG_MCAST) != 0 1529 ? kDefaultMulticastTTL : kDefaultTTL; 1530 } 1531 header->protocol = protocol 1532 ? protocol->socket->protocol : buffer->protocol; 1533 header->checksum = 0; 1534 1535 header->source = source.sin_addr.s_addr; 1536 header->destination = destination.sin_addr.s_addr; 1537 1538 TRACE_ONLY(dump_ipv4_header(*header)); 1539 } else { 1540 // if IP_HDRINCL, check if the source address is set 1541 NetBufferHeaderReader<ipv4_header> header(buffer); 1542 if (header.Status() != B_OK) 1543 return header.Status(); 1544 1545 if (header->source == 0) { 1546 header->source = source.sin_addr.s_addr; 1547 header->checksum = 0; 1548 header.Sync(); 1549 } else 1550 checksumNeeded = false; 1551 1552 TRACE(" Header was already supplied:"); 1553 TRACE_ONLY(dump_ipv4_header(*header)); 1554 } 1555 1556 if (buffer->size > 0xffff) 1557 return EMSGSIZE; 1558 1559 if (checksumNeeded) { 1560 *IPChecksumField(buffer) = gBufferModule->checksum(buffer, 0, 1561 sizeof(ipv4_header), true); 1562 } 1563 1564 if ((buffer->flags & MSG_MCAST) != 0 1565 && (protocol != NULL && protocol->multicast_loopback)) { 1566 // copy an IP multicast packet to the input queue of the loopback 1567 // interface 1568 net_buffer *loopbackBuffer = gBufferModule->duplicate(buffer); 1569 if (loopbackBuffer == NULL) 1570 return B_NO_MEMORY; 1571 status_t status = B_ERROR; 1572 1573 // get the IPv4 loopback address 1574 struct sockaddr loopbackAddress; 1575 gIPv4AddressModule.get_loopback_address(&loopbackAddress); 1576 1577 // get the matching interface address if any 1578 net_interface_address* address = 1579 sDatalinkModule->get_interface_address(&loopbackAddress); 1580 if (address == NULL || (address->interface->flags & IFF_UP) == 0) { 1581 sDatalinkModule->put_interface_address(address); 1582 } else { 1583 sDatalinkModule->put_interface_address( 1584 loopbackBuffer->interface_address); 1585 loopbackBuffer->interface_address = address; 1586 status = ipv4_receive_data(loopbackBuffer); 1587 } 1588 1589 if (status != B_OK) 1590 gBufferModule->free(loopbackBuffer); 1591 } 1592 1593 TRACE_SK(protocol, " SendRoutedData(): header chksum: %" B_PRIu32 1594 ", buffer checksum: %" B_PRIu32, 1595 gBufferModule->checksum(buffer, 0, sizeof(ipv4_header), true), 1596 gBufferModule->checksum(buffer, 0, buffer->size, true)); 1597 1598 TRACE_SK(protocol, " SendRoutedData(): destination: %08x", 1599 ntohl(destination.sin_addr.s_addr)); 1600 1601 uint32 mtu = route->mtu ? route->mtu : interface->device->mtu; 1602 if (buffer->size > mtu) { 1603 // we need to fragment the packet 1604 return send_fragments(protocol, route, buffer, mtu); 1605 } 1606 1607 return sDatalinkModule->send_routed_data(route, buffer); 1608 } 1609 1610 1611 status_t 1612 ipv4_send_data(net_protocol* _protocol, net_buffer* buffer) 1613 { 1614 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1615 1616 TRACE_SK(protocol, "SendData(%p [%" B_PRIu32 " bytes])", buffer, 1617 buffer->size); 1618 1619 if (protocol != NULL && (protocol->flags & IP_FLAG_HEADER_INCLUDED)) { 1620 if (buffer->size < sizeof(ipv4_header)) 1621 return B_BAD_VALUE; 1622 1623 sockaddr_in* source = (sockaddr_in*)buffer->source; 1624 sockaddr_in* destination = (sockaddr_in*)buffer->destination; 1625 1626 fill_sockaddr_in(source, *NetBufferField<in_addr_t, 1627 offsetof(ipv4_header, source)>(buffer)); 1628 fill_sockaddr_in(destination, *NetBufferField<in_addr_t, 1629 offsetof(ipv4_header, destination)>(buffer)); 1630 } 1631 1632 // handle IP_MULTICAST_IF 1633 if (IN_MULTICAST(ntohl( 1634 ((sockaddr_in*)buffer->destination)->sin_addr.s_addr)) 1635 && protocol != NULL && protocol->multicast_address != NULL) { 1636 net_interface_address* address = sDatalinkModule->get_interface_address( 1637 protocol->multicast_address); 1638 if (address == NULL || (address->interface->flags & IFF_UP) == 0) { 1639 sDatalinkModule->put_interface_address(address); 1640 return EADDRNOTAVAIL; 1641 } 1642 1643 sDatalinkModule->put_interface_address(buffer->interface_address); 1644 buffer->interface_address = address; 1645 // the buffer takes over ownership of the address 1646 1647 net_route* route = sDatalinkModule->get_route(sDomain, address->local); 1648 if (route == NULL) 1649 return ENETUNREACH; 1650 1651 return sDatalinkModule->send_routed_data(route, buffer); 1652 } 1653 1654 return sDatalinkModule->send_data(protocol, sDomain, buffer); 1655 } 1656 1657 1658 ssize_t 1659 ipv4_send_avail(net_protocol* protocol) 1660 { 1661 return B_ERROR; 1662 } 1663 1664 1665 status_t 1666 ipv4_read_data(net_protocol* _protocol, size_t numBytes, uint32 flags, 1667 net_buffer** _buffer) 1668 { 1669 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1670 RawSocket* raw = protocol->raw; 1671 if (raw == NULL) 1672 return B_ERROR; 1673 1674 TRACE_SK(protocol, "ReadData(%lu, 0x%" B_PRIx32 ")", numBytes, flags); 1675 1676 return raw->Dequeue(flags, _buffer); 1677 } 1678 1679 1680 ssize_t 1681 ipv4_read_avail(net_protocol* _protocol) 1682 { 1683 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1684 RawSocket* raw = protocol->raw; 1685 if (raw == NULL) 1686 return B_ERROR; 1687 1688 return raw->AvailableData(); 1689 } 1690 1691 1692 struct net_domain* 1693 ipv4_get_domain(net_protocol* protocol) 1694 { 1695 return sDomain; 1696 } 1697 1698 1699 size_t 1700 ipv4_get_mtu(net_protocol* protocol, const struct sockaddr* address) 1701 { 1702 net_route* route = sDatalinkModule->get_route(sDomain, address); 1703 if (route == NULL) 1704 return 0; 1705 1706 size_t mtu; 1707 if (route->mtu != 0) 1708 mtu = route->mtu; 1709 else 1710 mtu = route->interface_address->interface->device->mtu; 1711 1712 sDatalinkModule->put_route(sDomain, route); 1713 1714 if (mtu > 0xffff) 1715 mtu = 0xffff; 1716 1717 return mtu - sizeof(ipv4_header); 1718 } 1719 1720 1721 status_t 1722 ipv4_receive_data(net_buffer* buffer) 1723 { 1724 TRACE("ipv4_receive_data(%p [%" B_PRIu32 " bytes])", buffer, buffer->size); 1725 1726 uint16 headerLength = 0; 1727 { 1728 NetBufferHeaderReader<ipv4_header> bufferHeader(buffer); 1729 if (bufferHeader.Status() != B_OK) 1730 return bufferHeader.Status(); 1731 1732 ipv4_header& header = bufferHeader.Data(); 1733 TRACE_ONLY(dump_ipv4_header(header)); 1734 1735 if (header.version != IPV4_VERSION) 1736 return B_BAD_TYPE; 1737 1738 uint16 packetLength = header.TotalLength(); 1739 headerLength = header.HeaderLength(); 1740 if (packetLength > buffer->size 1741 || headerLength < sizeof(ipv4_header)) 1742 return B_BAD_DATA; 1743 1744 // TODO: would be nice to have a direct checksum function somewhere 1745 if (gBufferModule->checksum(buffer, 0, headerLength, true) != 0) 1746 return B_BAD_DATA; 1747 1748 // lower layers notion of broadcast or multicast have no relevance to us 1749 // other than deciding whether to send an ICMP error 1750 bool wasMulticast = (buffer->flags & (MSG_BCAST | MSG_MCAST)) != 0; 1751 bool notForUs = false; 1752 buffer->flags &= ~(MSG_BCAST | MSG_MCAST); 1753 1754 sockaddr_in destination; 1755 fill_sockaddr_in(&destination, header.destination); 1756 1757 if (header.destination == INADDR_BROADCAST) { 1758 buffer->flags |= MSG_BCAST; 1759 1760 // Find first interface with a matching family 1761 if (!sDatalinkModule->is_local_link_address(sDomain, true, 1762 buffer->destination, &buffer->interface_address)) 1763 notForUs = !wasMulticast; 1764 } else if (IN_MULTICAST(ntohl(header.destination))) { 1765 buffer->flags |= MSG_MCAST; 1766 } else { 1767 uint32 matchedAddressType = 0; 1768 1769 // test if the packet is really for us 1770 if (!sDatalinkModule->is_local_address(sDomain, (sockaddr*)&destination, 1771 &buffer->interface_address, &matchedAddressType) 1772 && !sDatalinkModule->is_local_link_address(sDomain, true, 1773 buffer->destination, &buffer->interface_address)) { 1774 // if the buffer was a link layer multicast, regard it as a 1775 // broadcast, and let the upper levels decide what to do with it 1776 if (wasMulticast) 1777 buffer->flags |= MSG_BCAST; 1778 else 1779 notForUs = true; 1780 } else { 1781 // copy over special address types (MSG_BCAST or MSG_MCAST): 1782 buffer->flags |= matchedAddressType; 1783 } 1784 } 1785 1786 // set net_buffer's source/destination address 1787 fill_sockaddr_in((struct sockaddr_in*)buffer->source, header.source); 1788 memcpy(buffer->destination, &destination, sizeof(sockaddr_in)); 1789 1790 buffer->protocol = header.protocol; 1791 1792 if (notForUs) { 1793 TRACE(" ipv4_receive_data(): packet was not for us %x -> %x", 1794 ntohl(header.source), ntohl(header.destination)); 1795 1796 if (!wasMulticast) { 1797 // Send ICMP error: Host unreachable 1798 sDomain->module->error_reply(NULL, buffer, B_NET_ERROR_UNREACH_HOST, 1799 NULL); 1800 } 1801 1802 return B_ERROR; 1803 } 1804 1805 // remove any trailing/padding data 1806 status_t status = gBufferModule->trim(buffer, packetLength); 1807 if (status != B_OK) 1808 return status; 1809 1810 // check for fragmentation 1811 uint16 fragmentOffset = header.FragmentOffset(); 1812 if ((fragmentOffset & IP_MORE_FRAGMENTS) != 0 1813 || (fragmentOffset & IP_FRAGMENT_OFFSET_MASK) != 0) { 1814 // this is a fragment 1815 TRACE(" ipv4_receive_data(): Found a Fragment!"); 1816 status = reassemble_fragments(header, &buffer); 1817 TRACE(" ipv4_receive_data(): -> %s", strerror(status)); 1818 if (status != B_OK) 1819 return status; 1820 1821 if (buffer == NULL) { 1822 // buffer was put into fragment packet 1823 TRACE(" ipv4_receive_data(): Not yet assembled."); 1824 return B_OK; 1825 } 1826 } 1827 1828 // Since the buffer might have been changed (reassembled fragment) 1829 // we must no longer access bufferHeader or header anymore after 1830 // this point 1831 } 1832 1833 bool rawDelivered = raw_receive_data(buffer); 1834 1835 // Preserve the ipv4 header for ICMP processing 1836 gBufferModule->store_header(buffer); 1837 gBufferModule->remove_header(buffer, headerLength); 1838 // the header is of variable size and may include IP options 1839 // (TODO: that we ignore for now) 1840 1841 net_protocol_module_info* module = receiving_protocol(buffer->protocol); 1842 if (module == NULL) { 1843 // no handler for this packet 1844 if (!rawDelivered) { 1845 sDomain->module->error_reply(NULL, buffer, 1846 B_NET_ERROR_UNREACH_PROTOCOL, NULL); 1847 } 1848 return EAFNOSUPPORT; 1849 } 1850 1851 if ((buffer->flags & MSG_MCAST) != 0) { 1852 // Unfortunately historical reasons dictate that the IP multicast 1853 // model be a little different from the unicast one. We deliver 1854 // this frame directly to all sockets registered with interest 1855 // for this multicast group. 1856 deliver_multicast(module, buffer, false); 1857 gBufferModule->free(buffer); 1858 return B_OK; 1859 } 1860 1861 return module->receive_data(buffer); 1862 } 1863 1864 1865 status_t 1866 ipv4_deliver_data(net_protocol* _protocol, net_buffer* buffer) 1867 { 1868 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1869 1870 if (protocol->raw == NULL) 1871 return B_ERROR; 1872 1873 return protocol->raw->EnqueueClone(buffer); 1874 } 1875 1876 1877 status_t 1878 ipv4_error_received(net_error error, net_buffer* buffer) 1879 { 1880 TRACE(" ipv4_error_received(error %d, buffer %p [%" B_PRIu32 " bytes])", 1881 (int)error, buffer, buffer->size); 1882 1883 NetBufferHeaderReader<ipv4_header> bufferHeader(buffer); 1884 if (bufferHeader.Status() != B_OK) 1885 return bufferHeader.Status(); 1886 1887 ipv4_header& header = bufferHeader.Data(); 1888 TRACE_ONLY(dump_ipv4_header(header)); 1889 1890 // We do not check the packet length, as we usually only get a part of it 1891 uint16 headerLength = header.HeaderLength(); 1892 if (header.version != IPV4_VERSION 1893 || headerLength < sizeof(ipv4_header) 1894 || gBufferModule->checksum(buffer, 0, headerLength, true) != 0) 1895 return B_BAD_DATA; 1896 1897 // Restore addresses of the original buffer 1898 1899 // lower layers notion of broadcast or multicast have no relevance to us 1900 // TODO: they actually have when deciding whether to send an ICMP error 1901 buffer->flags &= ~(MSG_BCAST | MSG_MCAST); 1902 1903 fill_sockaddr_in((struct sockaddr_in*)buffer->source, header.source); 1904 fill_sockaddr_in((struct sockaddr_in*)buffer->destination, 1905 header.destination); 1906 1907 if (header.destination == INADDR_BROADCAST) 1908 buffer->flags |= MSG_BCAST; 1909 else if (IN_MULTICAST(ntohl(header.destination))) 1910 buffer->flags |= MSG_MCAST; 1911 1912 // test if the packet is really from us 1913 if (!sDatalinkModule->is_local_address(sDomain, buffer->source, NULL, 1914 NULL)) { 1915 TRACE(" ipv4_error_received(): packet was not for us %x -> %x", 1916 ntohl(header.source), ntohl(header.destination)); 1917 return B_ERROR; 1918 } 1919 1920 buffer->protocol = header.protocol; 1921 1922 bufferHeader.Remove(headerLength); 1923 1924 net_protocol_module_info* protocol = receiving_protocol(buffer->protocol); 1925 if (protocol == NULL) 1926 return B_ERROR; 1927 1928 // propagate error 1929 return protocol->error_received(error, buffer); 1930 } 1931 1932 1933 status_t 1934 ipv4_error_reply(net_protocol* protocol, net_buffer* cause, net_error error, 1935 net_error_data* errorData) 1936 { 1937 // Directly obtain the ICMP protocol module 1938 net_protocol_module_info* icmp = receiving_protocol(IPPROTO_ICMP); 1939 if (icmp == NULL) 1940 return B_ERROR; 1941 1942 return icmp->error_reply(protocol, cause, error, errorData); 1943 } 1944 1945 1946 ssize_t 1947 ipv4_process_ancillary_data_no_container(net_protocol* protocol, 1948 net_buffer* buffer, void* msgControl, size_t msgControlLen) 1949 { 1950 ssize_t bytesWritten = 0; 1951 1952 if ((((ipv4_protocol*)protocol)->flags & IP_FLAG_RECEIVE_DEST_ADDR) != 0) { 1953 if (msgControlLen < CMSG_SPACE(sizeof(struct in_addr))) 1954 return B_NO_MEMORY; 1955 1956 cmsghdr* messageHeader = (cmsghdr*)msgControl; 1957 messageHeader->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); 1958 messageHeader->cmsg_level = IPPROTO_IP; 1959 messageHeader->cmsg_type = IP_RECVDSTADDR; 1960 1961 memcpy(CMSG_DATA(messageHeader), 1962 &((struct sockaddr_in*)buffer->destination)->sin_addr, 1963 sizeof(struct in_addr)); 1964 1965 bytesWritten += CMSG_SPACE(sizeof(struct in_addr)); 1966 } 1967 1968 return bytesWritten; 1969 } 1970 1971 1972 // #pragma mark - 1973 1974 1975 status_t 1976 init_ipv4() 1977 { 1978 sPacketID = (int32)system_time(); 1979 1980 mutex_init(&sRawSocketsLock, "raw sockets"); 1981 mutex_init(&sFragmentLock, "IPv4 Fragments"); 1982 mutex_init(&sMulticastGroupsLock, "IPv4 multicast groups"); 1983 mutex_init(&sReceivingProtocolLock, "IPv4 receiving protocols"); 1984 1985 status_t status; 1986 1987 sMulticastState = new MulticastState(); 1988 if (sMulticastState == NULL) { 1989 status = B_NO_MEMORY; 1990 goto err4; 1991 } 1992 1993 status = sMulticastState->Init(); 1994 if (status != B_OK) 1995 goto err5; 1996 1997 new (&sFragmentHash) FragmentTable(); 1998 status = sFragmentHash.Init(256); 1999 if (status != B_OK) 2000 goto err5; 2001 2002 new (&sRawSockets) RawSocketList; 2003 // static initializers do not work in the kernel, 2004 // so we have to do it here, manually 2005 // TODO: for modules, this shouldn't be required 2006 2007 status = gStackModule->register_domain_protocols(AF_INET, SOCK_RAW, 0, 2008 "network/protocols/ipv4/v1", NULL); 2009 if (status != B_OK) 2010 goto err6; 2011 2012 status = gStackModule->register_domain(AF_INET, "internet", &gIPv4Module, 2013 &gIPv4AddressModule, &sDomain); 2014 if (status != B_OK) 2015 goto err6; 2016 2017 add_debugger_command("ipv4_multicast", dump_ipv4_multicast, 2018 "list all current IPv4 multicast states"); 2019 2020 return B_OK; 2021 2022 err6: 2023 sFragmentHash.~FragmentTable(); 2024 err5: 2025 delete sMulticastState; 2026 err4: 2027 mutex_destroy(&sReceivingProtocolLock); 2028 mutex_destroy(&sMulticastGroupsLock); 2029 mutex_destroy(&sFragmentLock); 2030 mutex_destroy(&sRawSocketsLock); 2031 return status; 2032 } 2033 2034 2035 status_t 2036 uninit_ipv4() 2037 { 2038 mutex_lock(&sReceivingProtocolLock); 2039 2040 remove_debugger_command("ipv4_multicast", dump_ipv4_multicast); 2041 2042 // put all the domain receiving protocols we gathered so far 2043 for (uint32 i = 0; i < 256; i++) { 2044 if (sReceivingProtocol[i] != NULL) 2045 gStackModule->put_domain_receiving_protocol(sDomain, i); 2046 } 2047 2048 gStackModule->unregister_domain(sDomain); 2049 mutex_unlock(&sReceivingProtocolLock); 2050 2051 delete sMulticastState; 2052 sFragmentHash.~FragmentTable(); 2053 2054 mutex_destroy(&sMulticastGroupsLock); 2055 mutex_destroy(&sFragmentLock); 2056 mutex_destroy(&sRawSocketsLock); 2057 mutex_destroy(&sReceivingProtocolLock); 2058 2059 return B_OK; 2060 } 2061 2062 2063 static status_t 2064 ipv4_std_ops(int32 op, ...) 2065 { 2066 switch (op) { 2067 case B_MODULE_INIT: 2068 return init_ipv4(); 2069 case B_MODULE_UNINIT: 2070 return uninit_ipv4(); 2071 2072 default: 2073 return B_ERROR; 2074 } 2075 } 2076 2077 2078 net_protocol_module_info gIPv4Module = { 2079 { 2080 "network/protocols/ipv4/v1", 2081 0, 2082 ipv4_std_ops 2083 }, 2084 NET_PROTOCOL_ATOMIC_MESSAGES, 2085 2086 ipv4_init_protocol, 2087 ipv4_uninit_protocol, 2088 ipv4_open, 2089 ipv4_close, 2090 ipv4_free, 2091 ipv4_connect, 2092 ipv4_accept, 2093 ipv4_control, 2094 ipv4_getsockopt, 2095 ipv4_setsockopt, 2096 ipv4_bind, 2097 ipv4_unbind, 2098 ipv4_listen, 2099 ipv4_shutdown, 2100 ipv4_send_data, 2101 ipv4_send_routed_data, 2102 ipv4_send_avail, 2103 ipv4_read_data, 2104 ipv4_read_avail, 2105 ipv4_get_domain, 2106 ipv4_get_mtu, 2107 ipv4_receive_data, 2108 ipv4_deliver_data, 2109 ipv4_error_received, 2110 ipv4_error_reply, 2111 NULL, // add_ancillary_data() 2112 NULL, // process_ancillary_data() 2113 ipv4_process_ancillary_data_no_container, 2114 NULL, // send_data_no_buffer() 2115 NULL // read_data_no_buffer() 2116 }; 2117 2118 module_dependency module_dependencies[] = { 2119 {NET_STACK_MODULE_NAME, (module_info**)&gStackModule}, 2120 {NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule}, 2121 {NET_DATALINK_MODULE_NAME, (module_info**)&sDatalinkModule}, 2122 {NET_SOCKET_MODULE_NAME, (module_info**)&sSocketModule}, 2123 {} 2124 }; 2125 2126 module_info* modules[] = { 2127 (module_info*)&gIPv4Module, 2128 NULL 2129 }; 2130