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 return B_ERROR; 1156 } 1157 1158 1159 status_t 1160 ipv4_accept(net_protocol* protocol, struct net_socket** _acceptedSocket) 1161 { 1162 return B_NOT_SUPPORTED; 1163 } 1164 1165 1166 status_t 1167 ipv4_control(net_protocol* _protocol, int level, int option, void* value, 1168 size_t* _length) 1169 { 1170 if ((level & LEVEL_MASK) != IPPROTO_IP) 1171 return sDatalinkModule->control(sDomain, option, value, _length); 1172 1173 return B_BAD_VALUE; 1174 } 1175 1176 1177 status_t 1178 ipv4_getsockopt(net_protocol* _protocol, int level, int option, void* value, 1179 int* _length) 1180 { 1181 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1182 1183 if (level == IPPROTO_IP) { 1184 bool isDgramOrRaw = protocol->socket->type == SOCK_DGRAM 1185 || protocol->socket->type == SOCK_RAW; 1186 if (option == IP_HDRINCL) { 1187 return get_int_option(value, *_length, 1188 (protocol->flags & IP_FLAG_HEADER_INCLUDED) != 0); 1189 } 1190 if (option == IP_RECVDSTADDR) { 1191 return get_int_option(value, *_length, 1192 (protocol->flags & IP_FLAG_RECEIVE_DEST_ADDR) != 0); 1193 } 1194 if (option == IP_TTL) 1195 return get_int_option(value, *_length, protocol->time_to_live); 1196 if (option == IP_TOS) 1197 return get_int_option(value, *_length, protocol->service_type); 1198 if (option == IP_MULTICAST_IF) { 1199 if (*_length != sizeof(struct in_addr)) 1200 return B_BAD_VALUE; 1201 if (!isDgramOrRaw) 1202 return B_NOT_SUPPORTED; 1203 struct sockaddr_in defaultAddress; 1204 defaultAddress.sin_addr.s_addr = htonl(INADDR_ANY); 1205 struct sockaddr_in* address = 1206 (struct sockaddr_in*)protocol->multicast_address; 1207 if (address == NULL) 1208 address = &defaultAddress; 1209 if (user_memcpy(value, &address->sin_addr, sizeof(struct in_addr)) 1210 != B_OK) { 1211 return B_BAD_ADDRESS; 1212 } 1213 return B_OK; 1214 } 1215 if (option == IP_MULTICAST_TTL) { 1216 if (!isDgramOrRaw) 1217 return B_NOT_SUPPORTED; 1218 return get_char_int_option(value, *_length, 1219 protocol->multicast_time_to_live); 1220 } 1221 if (option == IP_MULTICAST_LOOP) { 1222 if (!isDgramOrRaw) 1223 return B_NOT_SUPPORTED; 1224 return get_char_int_option(value, *_length, 1225 protocol->multicast_loopback ? 1 : 0); 1226 } 1227 if (option == IP_ADD_MEMBERSHIP 1228 || option == IP_DROP_MEMBERSHIP 1229 || option == IP_BLOCK_SOURCE 1230 || option == IP_UNBLOCK_SOURCE 1231 || option == IP_ADD_SOURCE_MEMBERSHIP 1232 || option == IP_DROP_SOURCE_MEMBERSHIP 1233 || option == MCAST_JOIN_GROUP 1234 || option == MCAST_LEAVE_GROUP 1235 || option == MCAST_BLOCK_SOURCE 1236 || option == MCAST_UNBLOCK_SOURCE 1237 || option == MCAST_JOIN_SOURCE_GROUP 1238 || option == MCAST_LEAVE_SOURCE_GROUP) { 1239 // RFC 3678, Section 4.1: 1240 // ``An error of EOPNOTSUPP is returned if these options are 1241 // used with getsockopt().'' 1242 return B_NOT_SUPPORTED; 1243 } 1244 1245 dprintf("IPv4::getsockopt(): get unknown option: %d\n", option); 1246 return ENOPROTOOPT; 1247 } 1248 1249 return sSocketModule->get_option(protocol->socket, level, option, value, 1250 _length); 1251 } 1252 1253 1254 status_t 1255 ipv4_setsockopt(net_protocol* _protocol, int level, int option, 1256 const void* value, int length) 1257 { 1258 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1259 1260 if (level == IPPROTO_IP) { 1261 bool isDgramOrRaw = protocol->socket->type == SOCK_DGRAM 1262 || protocol->socket->type == SOCK_RAW; 1263 if (option == IP_HDRINCL) { 1264 int headerIncluded; 1265 if (length != sizeof(int)) 1266 return B_BAD_VALUE; 1267 if (user_memcpy(&headerIncluded, value, sizeof(headerIncluded)) 1268 != B_OK) 1269 return B_BAD_ADDRESS; 1270 1271 if (headerIncluded) 1272 protocol->flags |= IP_FLAG_HEADER_INCLUDED; 1273 else 1274 protocol->flags &= ~IP_FLAG_HEADER_INCLUDED; 1275 1276 return B_OK; 1277 } 1278 if (option == IP_RECVDSTADDR) { 1279 int getAddress; 1280 if (length != sizeof(int)) 1281 return B_BAD_VALUE; 1282 if (user_memcpy(&getAddress, value, sizeof(int)) != B_OK) 1283 return B_BAD_ADDRESS; 1284 1285 if (getAddress && (protocol->socket->type == SOCK_DGRAM 1286 || protocol->socket->type == SOCK_RAW)) 1287 protocol->flags |= IP_FLAG_RECEIVE_DEST_ADDR; 1288 else 1289 protocol->flags &= ~IP_FLAG_RECEIVE_DEST_ADDR; 1290 1291 return B_OK; 1292 } 1293 if (option == IP_TTL) 1294 return set_int_option(protocol->time_to_live, value, length); 1295 if (option == IP_TOS) 1296 return set_int_option(protocol->service_type, value, length); 1297 if (option == IP_MULTICAST_IF) { 1298 if (length != sizeof(struct in_addr)) 1299 return B_BAD_VALUE; 1300 if (!isDgramOrRaw) 1301 return B_NOT_SUPPORTED; 1302 1303 struct sockaddr_in* address = new (std::nothrow) sockaddr_in; 1304 if (address == NULL) 1305 return B_NO_MEMORY; 1306 1307 struct in_addr sin_addr; 1308 if (user_memcpy(&sin_addr, value, sizeof(struct in_addr)) 1309 != B_OK) { 1310 delete address; 1311 return B_BAD_ADDRESS; 1312 } 1313 fill_sockaddr_in(address, sin_addr.s_addr); 1314 1315 // Using INADDR_ANY to remove the previous setting. 1316 if (address->sin_addr.s_addr == htonl(INADDR_ANY)) { 1317 delete address; 1318 delete protocol->multicast_address; 1319 protocol->multicast_address = NULL; 1320 return B_OK; 1321 } 1322 1323 struct net_interface* interface 1324 = sDatalinkModule->get_interface_with_address( 1325 (sockaddr*)address); 1326 if (interface == NULL) { 1327 delete address; 1328 return EADDRNOTAVAIL; 1329 } 1330 1331 delete protocol->multicast_address; 1332 protocol->multicast_address = (struct sockaddr*)address; 1333 1334 sDatalinkModule->put_interface(interface); 1335 return B_OK; 1336 } 1337 if (option == IP_MULTICAST_TTL) { 1338 if (!isDgramOrRaw) 1339 return B_NOT_SUPPORTED; 1340 return set_char_int_option(protocol->multicast_time_to_live, value, 1341 length); 1342 } 1343 if (option == IP_MULTICAST_LOOP) { 1344 if (!isDgramOrRaw) 1345 return B_NOT_SUPPORTED; 1346 uint8 multicast_loopback; 1347 status_t status = set_char_int_option(multicast_loopback, value, 1348 length); 1349 if (status == B_OK) 1350 protocol->multicast_loopback = multicast_loopback != 0; 1351 return status; 1352 } 1353 if (option == IP_ADD_MEMBERSHIP || option == IP_DROP_MEMBERSHIP) { 1354 if (!isDgramOrRaw) 1355 return B_NOT_SUPPORTED; 1356 ip_mreq mreq; 1357 if (length != sizeof(ip_mreq)) 1358 return B_BAD_VALUE; 1359 if (user_memcpy(&mreq, value, sizeof(ip_mreq)) != B_OK) 1360 return B_BAD_ADDRESS; 1361 1362 return ipv4_delta_membership(protocol, option, &mreq.imr_interface, 1363 &mreq.imr_multiaddr, NULL); 1364 } 1365 if (option == IP_BLOCK_SOURCE 1366 || option == IP_UNBLOCK_SOURCE 1367 || option == IP_ADD_SOURCE_MEMBERSHIP 1368 || option == IP_DROP_SOURCE_MEMBERSHIP) { 1369 if (!isDgramOrRaw) 1370 return B_NOT_SUPPORTED; 1371 ip_mreq_source mreq; 1372 if (length != sizeof(ip_mreq_source)) 1373 return B_BAD_VALUE; 1374 if (user_memcpy(&mreq, value, sizeof(ip_mreq_source)) != B_OK) 1375 return B_BAD_ADDRESS; 1376 1377 return ipv4_delta_membership(protocol, option, &mreq.imr_interface, 1378 &mreq.imr_multiaddr, &mreq.imr_sourceaddr); 1379 } 1380 if (option == MCAST_LEAVE_GROUP || option == MCAST_JOIN_GROUP) { 1381 if (!isDgramOrRaw) 1382 return B_NOT_SUPPORTED; 1383 group_req greq; 1384 if (length != sizeof(group_req)) 1385 return B_BAD_VALUE; 1386 if (user_memcpy(&greq, value, sizeof(group_req)) != B_OK) 1387 return B_BAD_ADDRESS; 1388 1389 return ipv4_generic_delta_membership(protocol, option, 1390 greq.gr_interface, &greq.gr_group, NULL); 1391 } 1392 if (option == MCAST_BLOCK_SOURCE 1393 || option == MCAST_UNBLOCK_SOURCE 1394 || option == MCAST_JOIN_SOURCE_GROUP 1395 || option == MCAST_LEAVE_SOURCE_GROUP) { 1396 if (!isDgramOrRaw) 1397 return B_NOT_SUPPORTED; 1398 group_source_req greq; 1399 if (length != sizeof(group_source_req)) 1400 return B_BAD_VALUE; 1401 if (user_memcpy(&greq, value, sizeof(group_source_req)) != B_OK) 1402 return B_BAD_ADDRESS; 1403 1404 return ipv4_generic_delta_membership(protocol, option, 1405 greq.gsr_interface, &greq.gsr_group, &greq.gsr_source); 1406 } 1407 1408 dprintf("IPv4::setsockopt(): set unknown option: %d\n", option); 1409 return ENOPROTOOPT; 1410 } 1411 1412 return sSocketModule->set_option(protocol->socket, level, option, 1413 value, length); 1414 } 1415 1416 1417 status_t 1418 ipv4_bind(net_protocol* protocol, const struct sockaddr* address) 1419 { 1420 if (address->sa_family != AF_INET) 1421 return EAFNOSUPPORT; 1422 1423 // only INADDR_ANY and addresses of local interfaces are accepted: 1424 if (((sockaddr_in*)address)->sin_addr.s_addr == INADDR_ANY 1425 || IN_MULTICAST(ntohl(((sockaddr_in*)address)->sin_addr.s_addr)) 1426 || sDatalinkModule->is_local_address(sDomain, address, NULL, NULL)) { 1427 memcpy(&protocol->socket->address, address, sizeof(struct sockaddr_in)); 1428 protocol->socket->address.ss_len = sizeof(struct sockaddr_in); 1429 // explicitly set length, as our callers can't be trusted to 1430 // always provide the correct length! 1431 return B_OK; 1432 } 1433 1434 return EADDRNOTAVAIL; 1435 // address is unknown on this host 1436 } 1437 1438 1439 status_t 1440 ipv4_unbind(net_protocol* protocol, struct sockaddr* address) 1441 { 1442 // nothing to do here 1443 return B_OK; 1444 } 1445 1446 1447 status_t 1448 ipv4_listen(net_protocol* protocol, int count) 1449 { 1450 return B_NOT_SUPPORTED; 1451 } 1452 1453 1454 status_t 1455 ipv4_shutdown(net_protocol* protocol, int direction) 1456 { 1457 return B_NOT_SUPPORTED; 1458 } 1459 1460 1461 status_t 1462 ipv4_send_routed_data(net_protocol* _protocol, struct net_route* route, 1463 net_buffer* buffer) 1464 { 1465 if (route == NULL) 1466 return B_BAD_VALUE; 1467 1468 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1469 net_interface_address* interfaceAddress = route->interface_address; 1470 net_interface* interface = interfaceAddress->interface; 1471 1472 TRACE_SK(protocol, "SendRoutedData(%p, %p [%" B_PRIu32 " bytes])", route, 1473 buffer, buffer->size); 1474 1475 sockaddr_in& source = *(sockaddr_in*)buffer->source; 1476 sockaddr_in& destination = *(sockaddr_in*)buffer->destination; 1477 sockaddr_in* broadcastAddress = (sockaddr_in*)interfaceAddress->destination; 1478 1479 bool checksumNeeded = true; 1480 bool headerIncluded = false; 1481 if (protocol != NULL) 1482 headerIncluded = (protocol->flags & IP_FLAG_HEADER_INCLUDED) != 0; 1483 1484 buffer->flags &= ~(MSG_BCAST | MSG_MCAST); 1485 1486 if (destination.sin_addr.s_addr == INADDR_ANY) 1487 return EDESTADDRREQ; 1488 1489 if ((interface->device->flags & IFF_BROADCAST) != 0 1490 && (destination.sin_addr.s_addr == INADDR_BROADCAST 1491 || (broadcastAddress != NULL && destination.sin_addr.s_addr 1492 == broadcastAddress->sin_addr.s_addr))) { 1493 if (protocol && !(protocol->socket->options & SO_BROADCAST)) 1494 return B_BAD_VALUE; 1495 buffer->flags |= MSG_BCAST; 1496 } else if (IN_MULTICAST(ntohl(destination.sin_addr.s_addr))) 1497 buffer->flags |= MSG_MCAST; 1498 1499 // Add IP header (if needed) 1500 1501 if (!headerIncluded) { 1502 NetBufferPrepend<ipv4_header> header(buffer); 1503 if (header.Status() != B_OK) 1504 return header.Status(); 1505 1506 header->version = IPV4_VERSION; 1507 header->header_length = sizeof(ipv4_header) / 4; 1508 header->service_type = protocol ? protocol->service_type : 0; 1509 header->total_length = htons(buffer->size); 1510 header->id = htons(atomic_add(&sPacketID, 1)); 1511 header->fragment_offset = 0; 1512 if (protocol) { 1513 header->time_to_live = (buffer->flags & MSG_MCAST) != 0 1514 ? protocol->multicast_time_to_live : protocol->time_to_live; 1515 } else { 1516 header->time_to_live = (buffer->flags & MSG_MCAST) != 0 1517 ? kDefaultMulticastTTL : kDefaultTTL; 1518 } 1519 header->protocol = protocol 1520 ? protocol->socket->protocol : buffer->protocol; 1521 header->checksum = 0; 1522 1523 header->source = source.sin_addr.s_addr; 1524 header->destination = destination.sin_addr.s_addr; 1525 1526 TRACE_ONLY(dump_ipv4_header(*header)); 1527 } else { 1528 // if IP_HDRINCL, check if the source address is set 1529 NetBufferHeaderReader<ipv4_header> header(buffer); 1530 if (header.Status() != B_OK) 1531 return header.Status(); 1532 1533 if (header->source == 0) { 1534 header->source = source.sin_addr.s_addr; 1535 header->checksum = 0; 1536 header.Sync(); 1537 } else 1538 checksumNeeded = false; 1539 1540 TRACE(" Header was already supplied:"); 1541 TRACE_ONLY(dump_ipv4_header(*header)); 1542 } 1543 1544 if (buffer->size > 0xffff) 1545 return EMSGSIZE; 1546 1547 if (checksumNeeded) { 1548 *IPChecksumField(buffer) = gBufferModule->checksum(buffer, 0, 1549 sizeof(ipv4_header), true); 1550 } 1551 1552 if ((buffer->flags & MSG_MCAST) != 0 1553 && (protocol != NULL && protocol->multicast_loopback)) { 1554 // copy an IP multicast packet to the input queue of the loopback 1555 // interface 1556 net_buffer *loopbackBuffer = gBufferModule->duplicate(buffer); 1557 if (loopbackBuffer == NULL) 1558 return B_NO_MEMORY; 1559 status_t status = B_ERROR; 1560 1561 // get the IPv4 loopback address 1562 struct sockaddr loopbackAddress; 1563 gIPv4AddressModule.get_loopback_address(&loopbackAddress); 1564 1565 // get the matching interface address if any 1566 net_interface_address* address = 1567 sDatalinkModule->get_interface_address(&loopbackAddress); 1568 if (address == NULL || (address->interface->flags & IFF_UP) == 0) { 1569 sDatalinkModule->put_interface_address(address); 1570 } else { 1571 sDatalinkModule->put_interface_address( 1572 loopbackBuffer->interface_address); 1573 loopbackBuffer->interface_address = address; 1574 status = ipv4_receive_data(loopbackBuffer); 1575 } 1576 1577 if (status != B_OK) 1578 gBufferModule->free(loopbackBuffer); 1579 } 1580 1581 TRACE_SK(protocol, " SendRoutedData(): header chksum: %" B_PRIu32 1582 ", buffer checksum: %" B_PRIu32, 1583 gBufferModule->checksum(buffer, 0, sizeof(ipv4_header), true), 1584 gBufferModule->checksum(buffer, 0, buffer->size, true)); 1585 1586 TRACE_SK(protocol, " SendRoutedData(): destination: %08x", 1587 ntohl(destination.sin_addr.s_addr)); 1588 1589 uint32 mtu = route->mtu ? route->mtu : interface->device->mtu; 1590 if (buffer->size > mtu) { 1591 // we need to fragment the packet 1592 return send_fragments(protocol, route, buffer, mtu); 1593 } 1594 1595 return sDatalinkModule->send_routed_data(route, buffer); 1596 } 1597 1598 1599 status_t 1600 ipv4_send_data(net_protocol* _protocol, net_buffer* buffer) 1601 { 1602 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1603 1604 TRACE_SK(protocol, "SendData(%p [%" B_PRIu32 " bytes])", buffer, 1605 buffer->size); 1606 1607 if (protocol != NULL && (protocol->flags & IP_FLAG_HEADER_INCLUDED)) { 1608 if (buffer->size < sizeof(ipv4_header)) 1609 return B_BAD_VALUE; 1610 1611 sockaddr_in* source = (sockaddr_in*)buffer->source; 1612 sockaddr_in* destination = (sockaddr_in*)buffer->destination; 1613 1614 fill_sockaddr_in(source, *NetBufferField<in_addr_t, 1615 offsetof(ipv4_header, source)>(buffer)); 1616 fill_sockaddr_in(destination, *NetBufferField<in_addr_t, 1617 offsetof(ipv4_header, destination)>(buffer)); 1618 } 1619 1620 // handle IP_MULTICAST_IF 1621 if (IN_MULTICAST(ntohl( 1622 ((sockaddr_in*)buffer->destination)->sin_addr.s_addr)) 1623 && protocol != NULL && protocol->multicast_address != NULL) { 1624 net_interface_address* address = sDatalinkModule->get_interface_address( 1625 protocol->multicast_address); 1626 if (address == NULL || (address->interface->flags & IFF_UP) == 0) { 1627 sDatalinkModule->put_interface_address(address); 1628 return EADDRNOTAVAIL; 1629 } 1630 1631 sDatalinkModule->put_interface_address(buffer->interface_address); 1632 buffer->interface_address = address; 1633 // the buffer takes over ownership of the address 1634 1635 net_route* route = sDatalinkModule->get_route(sDomain, address->local); 1636 if (route == NULL) 1637 return ENETUNREACH; 1638 1639 return sDatalinkModule->send_routed_data(route, buffer); 1640 } 1641 1642 return sDatalinkModule->send_data(protocol, sDomain, buffer); 1643 } 1644 1645 1646 ssize_t 1647 ipv4_send_avail(net_protocol* protocol) 1648 { 1649 return B_ERROR; 1650 } 1651 1652 1653 status_t 1654 ipv4_read_data(net_protocol* _protocol, size_t numBytes, uint32 flags, 1655 net_buffer** _buffer) 1656 { 1657 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1658 RawSocket* raw = protocol->raw; 1659 if (raw == NULL) 1660 return B_ERROR; 1661 1662 TRACE_SK(protocol, "ReadData(%lu, 0x%" B_PRIx32 ")", numBytes, flags); 1663 1664 return raw->Dequeue(flags, _buffer); 1665 } 1666 1667 1668 ssize_t 1669 ipv4_read_avail(net_protocol* _protocol) 1670 { 1671 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1672 RawSocket* raw = protocol->raw; 1673 if (raw == NULL) 1674 return B_ERROR; 1675 1676 return raw->AvailableData(); 1677 } 1678 1679 1680 struct net_domain* 1681 ipv4_get_domain(net_protocol* protocol) 1682 { 1683 return sDomain; 1684 } 1685 1686 1687 size_t 1688 ipv4_get_mtu(net_protocol* protocol, const struct sockaddr* address) 1689 { 1690 net_route* route = sDatalinkModule->get_route(sDomain, address); 1691 if (route == NULL) 1692 return 0; 1693 1694 size_t mtu; 1695 if (route->mtu != 0) 1696 mtu = route->mtu; 1697 else 1698 mtu = route->interface_address->interface->device->mtu; 1699 1700 sDatalinkModule->put_route(sDomain, route); 1701 return mtu - sizeof(ipv4_header); 1702 } 1703 1704 1705 status_t 1706 ipv4_receive_data(net_buffer* buffer) 1707 { 1708 TRACE("ipv4_receive_data(%p [%" B_PRIu32 " bytes])", buffer, buffer->size); 1709 1710 NetBufferHeaderReader<ipv4_header> bufferHeader(buffer); 1711 if (bufferHeader.Status() != B_OK) 1712 return bufferHeader.Status(); 1713 1714 ipv4_header& header = bufferHeader.Data(); 1715 TRACE_ONLY(dump_ipv4_header(header)); 1716 1717 if (header.version != IPV4_VERSION) 1718 return B_BAD_TYPE; 1719 1720 uint16 packetLength = header.TotalLength(); 1721 uint16 headerLength = header.HeaderLength(); 1722 if (packetLength > buffer->size 1723 || headerLength < sizeof(ipv4_header)) 1724 return B_BAD_DATA; 1725 1726 // TODO: would be nice to have a direct checksum function somewhere 1727 if (gBufferModule->checksum(buffer, 0, headerLength, true) != 0) 1728 return B_BAD_DATA; 1729 1730 // lower layers notion of broadcast or multicast have no relevance to us 1731 // other than deciding whether to send an ICMP error 1732 bool wasMulticast = (buffer->flags & (MSG_BCAST | MSG_MCAST)) != 0; 1733 bool notForUs = false; 1734 buffer->flags &= ~(MSG_BCAST | MSG_MCAST); 1735 1736 sockaddr_in destination; 1737 fill_sockaddr_in(&destination, header.destination); 1738 1739 if (header.destination == INADDR_BROADCAST) { 1740 buffer->flags |= MSG_BCAST; 1741 1742 // Find first interface with a matching family 1743 if (!sDatalinkModule->is_local_link_address(sDomain, true, 1744 buffer->destination, &buffer->interface_address)) 1745 notForUs = !wasMulticast; 1746 } else if (IN_MULTICAST(ntohl(header.destination))) { 1747 buffer->flags |= MSG_MCAST; 1748 } else { 1749 uint32 matchedAddressType = 0; 1750 1751 // test if the packet is really for us 1752 if (!sDatalinkModule->is_local_address(sDomain, (sockaddr*)&destination, 1753 &buffer->interface_address, &matchedAddressType) 1754 && !sDatalinkModule->is_local_link_address(sDomain, true, 1755 buffer->destination, &buffer->interface_address)) { 1756 // if the buffer was a link layer multicast, regard it as a 1757 // broadcast, and let the upper levels decide what to do with it 1758 if (wasMulticast) 1759 buffer->flags |= MSG_BCAST; 1760 else 1761 notForUs = true; 1762 } else { 1763 // copy over special address types (MSG_BCAST or MSG_MCAST): 1764 buffer->flags |= matchedAddressType; 1765 } 1766 } 1767 1768 // set net_buffer's source/destination address 1769 fill_sockaddr_in((struct sockaddr_in*)buffer->source, header.source); 1770 memcpy(buffer->destination, &destination, sizeof(sockaddr_in)); 1771 1772 buffer->protocol = header.protocol; 1773 1774 if (notForUs) { 1775 TRACE(" ipv4_receive_data(): packet was not for us %x -> %x", 1776 ntohl(header.source), ntohl(header.destination)); 1777 1778 if (!wasMulticast) { 1779 // Send ICMP error: Host unreachable 1780 sDomain->module->error_reply(NULL, buffer, B_NET_ERROR_UNREACH_HOST, 1781 NULL); 1782 } 1783 1784 return B_ERROR; 1785 } 1786 1787 // remove any trailing/padding data 1788 status_t status = gBufferModule->trim(buffer, packetLength); 1789 if (status != B_OK) 1790 return status; 1791 1792 // check for fragmentation 1793 uint16 fragmentOffset = header.FragmentOffset(); 1794 if ((fragmentOffset & IP_MORE_FRAGMENTS) != 0 1795 || (fragmentOffset & IP_FRAGMENT_OFFSET_MASK) != 0) { 1796 // this is a fragment 1797 TRACE(" ipv4_receive_data(): Found a Fragment!"); 1798 status = reassemble_fragments(header, &buffer); 1799 TRACE(" ipv4_receive_data(): -> %s", strerror(status)); 1800 if (status != B_OK) 1801 return status; 1802 1803 if (buffer == NULL) { 1804 // buffer was put into fragment packet 1805 TRACE(" ipv4_receive_data(): Not yet assembled."); 1806 return B_OK; 1807 } 1808 } 1809 1810 // Since the buffer might have been changed (reassembled fragment) 1811 // we must no longer access bufferHeader or header anymore after 1812 // this point 1813 1814 bool rawDelivered = raw_receive_data(buffer); 1815 1816 // Preserve the ipv4 header for ICMP processing 1817 gBufferModule->store_header(buffer); 1818 1819 bufferHeader.Remove(headerLength); 1820 // the header is of variable size and may include IP options 1821 // (TODO: that we ignore for now) 1822 1823 net_protocol_module_info* module = receiving_protocol(buffer->protocol); 1824 if (module == NULL) { 1825 // no handler for this packet 1826 if (!rawDelivered) { 1827 sDomain->module->error_reply(NULL, buffer, 1828 B_NET_ERROR_UNREACH_PROTOCOL, NULL); 1829 } 1830 return EAFNOSUPPORT; 1831 } 1832 1833 if ((buffer->flags & MSG_MCAST) != 0) { 1834 // Unfortunately historical reasons dictate that the IP multicast 1835 // model be a little different from the unicast one. We deliver 1836 // this frame directly to all sockets registered with interest 1837 // for this multicast group. 1838 deliver_multicast(module, buffer, false); 1839 gBufferModule->free(buffer); 1840 return B_OK; 1841 } 1842 1843 return module->receive_data(buffer); 1844 } 1845 1846 1847 status_t 1848 ipv4_deliver_data(net_protocol* _protocol, net_buffer* buffer) 1849 { 1850 ipv4_protocol* protocol = (ipv4_protocol*)_protocol; 1851 1852 if (protocol->raw == NULL) 1853 return B_ERROR; 1854 1855 return protocol->raw->EnqueueClone(buffer); 1856 } 1857 1858 1859 status_t 1860 ipv4_error_received(net_error error, net_buffer* buffer) 1861 { 1862 TRACE(" ipv4_error_received(error %d, buffer %p [%" B_PRIu32 " bytes])", 1863 (int)error, buffer, buffer->size); 1864 1865 NetBufferHeaderReader<ipv4_header> bufferHeader(buffer); 1866 if (bufferHeader.Status() != B_OK) 1867 return bufferHeader.Status(); 1868 1869 ipv4_header& header = bufferHeader.Data(); 1870 TRACE_ONLY(dump_ipv4_header(header)); 1871 1872 // We do not check the packet length, as we usually only get a part of it 1873 uint16 headerLength = header.HeaderLength(); 1874 if (header.version != IPV4_VERSION 1875 || headerLength < sizeof(ipv4_header) 1876 || gBufferModule->checksum(buffer, 0, headerLength, true) != 0) 1877 return B_BAD_DATA; 1878 1879 // Restore addresses of the original buffer 1880 1881 // lower layers notion of broadcast or multicast have no relevance to us 1882 // TODO: they actually have when deciding whether to send an ICMP error 1883 buffer->flags &= ~(MSG_BCAST | MSG_MCAST); 1884 1885 fill_sockaddr_in((struct sockaddr_in*)buffer->source, header.source); 1886 fill_sockaddr_in((struct sockaddr_in*)buffer->destination, 1887 header.destination); 1888 1889 if (header.destination == INADDR_BROADCAST) 1890 buffer->flags |= MSG_BCAST; 1891 else if (IN_MULTICAST(ntohl(header.destination))) 1892 buffer->flags |= MSG_MCAST; 1893 1894 // test if the packet is really from us 1895 if (!sDatalinkModule->is_local_address(sDomain, buffer->source, NULL, 1896 NULL)) { 1897 TRACE(" ipv4_error_received(): packet was not for us %x -> %x", 1898 ntohl(header.source), ntohl(header.destination)); 1899 return B_ERROR; 1900 } 1901 1902 buffer->protocol = header.protocol; 1903 1904 bufferHeader.Remove(headerLength); 1905 1906 net_protocol_module_info* protocol = receiving_protocol(buffer->protocol); 1907 if (protocol == NULL) 1908 return B_ERROR; 1909 1910 // propagate error 1911 return protocol->error_received(error, buffer); 1912 } 1913 1914 1915 status_t 1916 ipv4_error_reply(net_protocol* protocol, net_buffer* cause, net_error error, 1917 net_error_data* errorData) 1918 { 1919 // Directly obtain the ICMP protocol module 1920 net_protocol_module_info* icmp = receiving_protocol(IPPROTO_ICMP); 1921 if (icmp == NULL) 1922 return B_ERROR; 1923 1924 return icmp->error_reply(protocol, cause, error, errorData); 1925 } 1926 1927 1928 ssize_t 1929 ipv4_process_ancillary_data_no_container(net_protocol* protocol, 1930 net_buffer* buffer, void* msgControl, size_t msgControlLen) 1931 { 1932 ssize_t bytesWritten = 0; 1933 1934 if ((((ipv4_protocol*)protocol)->flags & IP_FLAG_RECEIVE_DEST_ADDR) != 0) { 1935 if (msgControlLen < CMSG_SPACE(sizeof(struct in_addr))) 1936 return B_NO_MEMORY; 1937 1938 cmsghdr* messageHeader = (cmsghdr*)msgControl; 1939 messageHeader->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); 1940 messageHeader->cmsg_level = IPPROTO_IP; 1941 messageHeader->cmsg_type = IP_RECVDSTADDR; 1942 1943 memcpy(CMSG_DATA(messageHeader), 1944 &((struct sockaddr_in*)buffer->destination)->sin_addr, 1945 sizeof(struct in_addr)); 1946 1947 bytesWritten += CMSG_SPACE(sizeof(struct in_addr)); 1948 } 1949 1950 return bytesWritten; 1951 } 1952 1953 1954 // #pragma mark - 1955 1956 1957 status_t 1958 init_ipv4() 1959 { 1960 sPacketID = (int32)system_time(); 1961 1962 mutex_init(&sRawSocketsLock, "raw sockets"); 1963 mutex_init(&sFragmentLock, "IPv4 Fragments"); 1964 mutex_init(&sMulticastGroupsLock, "IPv4 multicast groups"); 1965 mutex_init(&sReceivingProtocolLock, "IPv4 receiving protocols"); 1966 1967 status_t status; 1968 1969 sMulticastState = new MulticastState(); 1970 if (sMulticastState == NULL) { 1971 status = B_NO_MEMORY; 1972 goto err4; 1973 } 1974 1975 status = sMulticastState->Init(); 1976 if (status != B_OK) 1977 goto err5; 1978 1979 new (&sFragmentHash) FragmentTable(); 1980 status = sFragmentHash.Init(256); 1981 if (status != B_OK) 1982 goto err5; 1983 1984 new (&sRawSockets) RawSocketList; 1985 // static initializers do not work in the kernel, 1986 // so we have to do it here, manually 1987 // TODO: for modules, this shouldn't be required 1988 1989 status = gStackModule->register_domain_protocols(AF_INET, SOCK_RAW, 0, 1990 "network/protocols/ipv4/v1", NULL); 1991 if (status != B_OK) 1992 goto err6; 1993 1994 status = gStackModule->register_domain(AF_INET, "internet", &gIPv4Module, 1995 &gIPv4AddressModule, &sDomain); 1996 if (status != B_OK) 1997 goto err6; 1998 1999 add_debugger_command("ipv4_multicast", dump_ipv4_multicast, 2000 "list all current IPv4 multicast states"); 2001 2002 return B_OK; 2003 2004 err6: 2005 sFragmentHash.~FragmentTable(); 2006 err5: 2007 delete sMulticastState; 2008 err4: 2009 mutex_destroy(&sReceivingProtocolLock); 2010 mutex_destroy(&sMulticastGroupsLock); 2011 mutex_destroy(&sFragmentLock); 2012 mutex_destroy(&sRawSocketsLock); 2013 return status; 2014 } 2015 2016 2017 status_t 2018 uninit_ipv4() 2019 { 2020 mutex_lock(&sReceivingProtocolLock); 2021 2022 remove_debugger_command("ipv4_multicast", dump_ipv4_multicast); 2023 2024 // put all the domain receiving protocols we gathered so far 2025 for (uint32 i = 0; i < 256; i++) { 2026 if (sReceivingProtocol[i] != NULL) 2027 gStackModule->put_domain_receiving_protocol(sDomain, i); 2028 } 2029 2030 gStackModule->unregister_domain(sDomain); 2031 mutex_unlock(&sReceivingProtocolLock); 2032 2033 delete sMulticastState; 2034 sFragmentHash.~FragmentTable(); 2035 2036 mutex_destroy(&sMulticastGroupsLock); 2037 mutex_destroy(&sFragmentLock); 2038 mutex_destroy(&sRawSocketsLock); 2039 mutex_destroy(&sReceivingProtocolLock); 2040 2041 return B_OK; 2042 } 2043 2044 2045 static status_t 2046 ipv4_std_ops(int32 op, ...) 2047 { 2048 switch (op) { 2049 case B_MODULE_INIT: 2050 return init_ipv4(); 2051 case B_MODULE_UNINIT: 2052 return uninit_ipv4(); 2053 2054 default: 2055 return B_ERROR; 2056 } 2057 } 2058 2059 2060 net_protocol_module_info gIPv4Module = { 2061 { 2062 "network/protocols/ipv4/v1", 2063 0, 2064 ipv4_std_ops 2065 }, 2066 NET_PROTOCOL_ATOMIC_MESSAGES, 2067 2068 ipv4_init_protocol, 2069 ipv4_uninit_protocol, 2070 ipv4_open, 2071 ipv4_close, 2072 ipv4_free, 2073 ipv4_connect, 2074 ipv4_accept, 2075 ipv4_control, 2076 ipv4_getsockopt, 2077 ipv4_setsockopt, 2078 ipv4_bind, 2079 ipv4_unbind, 2080 ipv4_listen, 2081 ipv4_shutdown, 2082 ipv4_send_data, 2083 ipv4_send_routed_data, 2084 ipv4_send_avail, 2085 ipv4_read_data, 2086 ipv4_read_avail, 2087 ipv4_get_domain, 2088 ipv4_get_mtu, 2089 ipv4_receive_data, 2090 ipv4_deliver_data, 2091 ipv4_error_received, 2092 ipv4_error_reply, 2093 NULL, // add_ancillary_data() 2094 NULL, // process_ancillary_data() 2095 ipv4_process_ancillary_data_no_container, 2096 NULL, // send_data_no_buffer() 2097 NULL // read_data_no_buffer() 2098 }; 2099 2100 module_dependency module_dependencies[] = { 2101 {NET_STACK_MODULE_NAME, (module_info**)&gStackModule}, 2102 {NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule}, 2103 {NET_DATALINK_MODULE_NAME, (module_info**)&sDatalinkModule}, 2104 {NET_SOCKET_MODULE_NAME, (module_info**)&sSocketModule}, 2105 {} 2106 }; 2107 2108 module_info* modules[] = { 2109 (module_info*)&gIPv4Module, 2110 NULL 2111 }; 2112