20#include "ns3/assert.h" 
   21#include "ns3/ipv6-address.h" 
   23#include "ns3/object-vector.h" 
   24#include "ns3/trace-source-accessor.h" 
   25#include "ns3/uinteger.h" 
   42                            .SetGroupName(
"Internet")
 
   43                            .AddAttribute(
"ExtensionNumber",
 
   44                                          "The IPv6 extension number.",
 
 
   85    NS_LOG_FUNCTION(
this << packet << offset << length << ipv6Header << dst << nextHeader
 
   90    malformedPacket->AddHeader(ipv6Header);
 
   94    p->RemoveAtStart(offset);
 
   99    uint8_t processedSize = 0;
 
  101    auto data = 
new uint8_t[size];
 
  102    p->CopyData(
data, size);
 
  104    uint8_t optionType = 0;
 
  105    uint8_t optionLength = 0;
 
  107    while (length > processedSize && !isDropped)
 
  109        optionType = *(
data + processedSize);
 
  110        ipv6Option = ipv6OptionDemux->GetOption(optionType);
 
  118                optionLength = *(
data + processedSize + 1) + 2;
 
  125                stopProcessing = 
true;
 
  131                icmpv6->SendErrorParameterError(malformedPacket,
 
  134                                                offset + processedSize);
 
  137                stopProcessing = 
true;
 
  146                    icmpv6->SendErrorParameterError(malformedPacket,
 
  149                                                    offset + processedSize);
 
  153                stopProcessing = 
true;
 
  164                ipv6Option->Process(packet, offset + processedSize, ipv6Header, isDropped);
 
  167        processedSize += optionLength;
 
  168        p->RemoveAtStart(optionLength);
 
  173    return processedSize;
 
 
  180    m_uvar->SetStream(stream);
 
 
  189    static TypeId tid = 
TypeId(
"ns3::Ipv6ExtensionHopByHop")
 
  191                            .SetGroupName(
"Internet")
 
 
  216                               bool& stopProcessing,
 
  220    NS_LOG_FUNCTION(
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
 
  223    p->RemoveAtStart(offset);
 
  226    p->RemoveHeader(hopbyhopHeader);
 
  233    offset += processedSize;
 
  246    return processedSize;
 
 
  254    static TypeId tid = 
TypeId(
"ns3::Ipv6ExtensionDestination")
 
  256                            .SetGroupName(
"Internet")
 
 
  281                                  bool& stopProcessing,
 
  285    NS_LOG_FUNCTION(
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
 
  288    p->RemoveAtStart(offset);
 
  291    p->RemoveHeader(destinationHeader);
 
  298    offset += processedSize;
 
  311    return processedSize;
 
 
  320        TypeId(
"ns3::Ipv6ExtensionFragment")
 
  322            .SetGroupName(
"Internet")
 
  324            .AddAttribute(
"FragmentExpirationTimeout",
 
  325                          "When this timeout expires, the fragments " 
  326                          "will be cleared from the buffer.",
 
 
  348        it->second = 
nullptr;
 
 
  372                               bool& stopProcessing,
 
  376    NS_LOG_FUNCTION(
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
 
  379    p->RemoveAtStart(offset);
 
  382    p->RemoveHeader(fragmentHeader);
 
  390    uint16_t fragmentOffset = fragmentHeader.
GetOffset();
 
  404        m_fragments.insert(std::make_pair(fragmentKey, fragments));
 
  406                     << src << 
" IP hdr id " << identification << 
" m_fragments.size() " 
  407                     << 
m_fragments.size() << 
" offset " << fragmentOffset);
 
  408        auto iter = 
SetTimeout(fragmentKey, ipHeader);
 
  409        fragments->SetTimeoutIter(iter);
 
  413        fragments = it->second;
 
  416    if (fragmentOffset == 0)
 
  419        unfragmentablePart->RemoveAtEnd(packet->GetSize() - offset);
 
  420        fragments->SetUnfragmentablePart(unfragmentablePart);
 
  423    NS_LOG_DEBUG(
"Add fragment with IP hdr id " << identification << 
" offset " << fragmentOffset);
 
  424    fragments->AddFragment(p, fragmentOffset, moreFragment);
 
  426    if (fragments->IsEntire())
 
  428        packet = fragments->GetPacket();
 
  432                     << fragmentKey.second
 
  433                     << 
" erase timeout, m_fragments.size(): " << 
m_fragments.size());
 
  434        stopProcessing = 
false;
 
  438        stopProcessing = 
true;
 
 
  448                                    std::list<Ipv6PayloadHeaderPair>& listFragments)
 
  457    p->CopyData(&type, 
sizeof(type));
 
  459    bool moreHeader = 
true;
 
  468    std::list<std::pair<Ipv6ExtensionHeader*, uint8_t>> unfragmentablePart;
 
  469    uint32_t unfragmentablePartSize = 0;
 
  473    uint8_t extensionHeaderLength;
 
  480            p->RemoveHeader(*hopbyhopHeader);
 
  482            nextHeader = hopbyhopHeader->GetNextHeader();
 
  483            extensionHeaderLength = hopbyhopHeader->GetLength();
 
  486            p->CopyData(&type, 
sizeof(type));
 
  498            unfragmentablePartSize += extensionHeaderLength;
 
  506            p->CopyData(buf, 
sizeof(buf));
 
  507            uint8_t routingType = buf[2];
 
  510                ipv6ExtensionRoutingDemux->GetExtensionRoutingHeaderPtr(routingType);
 
  512            p->RemoveHeader(*routingHeader);
 
  515            extensionHeaderLength = routingHeader->
GetLength();
 
  518            p->CopyData(&type, 
sizeof(type));
 
  529            unfragmentablePartSize += extensionHeaderLength;
 
  534            p->RemoveHeader(*destinationHeader);
 
  536            nextHeader = destinationHeader->GetNextHeader();
 
  537            extensionHeaderLength = destinationHeader->GetLength();
 
  540            p->CopyData(&type, 
sizeof(type));
 
  551            unfragmentablePartSize += extensionHeaderLength;
 
  559        maxFragmentSize - ipv6HeaderSize - unfragmentablePartSize - fragmentHeaderSize;
 
  560    uint32_t currentFragmentablePartSize = 0;
 
  562    bool moreFragment = 
true;
 
  568        if (p->GetSize() > offset + maxFragmentablePartSize)
 
  571            currentFragmentablePartSize = maxFragmentablePartSize;
 
  572            currentFragmentablePartSize -= currentFragmentablePartSize % 8;
 
  576            moreFragment = 
false;
 
  577            currentFragmentablePartSize = p->GetSize() - offset;
 
  585        Ptr<Packet> fragment = p->CreateFragment(offset, currentFragmentablePartSize);
 
  586        offset += currentFragmentablePartSize;
 
  588        fragment->AddHeader(fragmentHeader);
 
  590        for (
auto it = unfragmentablePart.begin(); it != unfragmentablePart.end(); it++)
 
  596                fragment->AddHeader(*p);
 
  602                fragment->AddHeader(*p);
 
  608                fragment->AddHeader(*p);
 
  614        std::ostringstream oss;
 
  616        fragment->Print(oss);
 
  618        listFragments.emplace_back(fragment, ipv6Header);
 
  619    } 
while (moreFragment);
 
  621    for (
auto it = unfragmentablePart.begin(); it != unfragmentablePart.end(); it++)
 
  626    unfragmentablePart.clear();
 
 
  632    NS_LOG_FUNCTION(
this << fragmentKey.first << fragmentKey.second << ipHeader);
 
  637                  "IPv6 Fragment timeout reached for non-existent fragment");
 
  638    fragments = it->second;
 
  640    Ptr<Packet> packet = fragments->GetPartialPacket();
 
  643    if (packet && packet->GetSize() > 8)
 
  646        p->AddHeader(ipHeader);
 
 
  665                     << key.second << 
" at time " 
 
  691        NS_LOG_DEBUG(
"Handle time " << std::get<0>(element).GetSeconds() << 
" IP hdr id " 
  692                                    << std::get<1>(element).
second);
 
  707    NS_LOG_DEBUG(
"Scheduling later HandleTimeout at " << (now + difference).GetSeconds());
 
 
  712    : m_moreFragment(false)
 
 
  722                                              uint16_t fragmentOffset,
 
  726    std::list<std::pair<Ptr<Packet>, uint16_t>>::iterator it;
 
  728    for (it = m_packetFragments.begin(); it != m_packetFragments.end(); it++)
 
  730        if (it->second > fragmentOffset)
 
  736    if (it == m_packetFragments.end())
 
  738        m_moreFragment = moreFragment;
 
  741    m_packetFragments.insert(it, std::pair<
Ptr<Packet>, uint16_t>(fragment, fragmentOffset));
 
 
  748    m_unfragmentable = unfragmentablePart;
 
 
  754    bool ret = !m_moreFragment && !m_packetFragments.empty();
 
  758        uint16_t lastEndOffset = 0;
 
  760        for (
auto it = m_packetFragments.begin(); it != m_packetFragments.end(); it++)
 
  762            if (lastEndOffset != it->second)
 
  768            lastEndOffset += it->first->GetSize();
 
 
  780    for (
auto it = m_packetFragments.begin(); it != m_packetFragments.end(); it++)
 
  782        p->AddAtEnd(it->first);
 
 
  793    if (m_unfragmentable)
 
  795        p = m_unfragmentable->Copy();
 
  802    uint16_t lastEndOffset = 0;
 
  804    for (
auto it = m_packetFragments.begin(); it != m_packetFragments.end(); it++)
 
  806        if (lastEndOffset != it->second)
 
  810        p->AddAtEnd(it->first);
 
  811        lastEndOffset += it->first->GetSize();
 
 
  821    m_timeoutIter = iter;
 
 
  827    return m_timeoutIter;
 
 
  837                            .SetGroupName(
"Internet")
 
 
  874                              bool& stopProcessing,
 
  878    NS_LOG_FUNCTION(
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
 
  882    malformedPacket->AddHeader(ipv6Header);
 
  885    p->RemoveAtStart(offset);
 
  888    packet->CopyData(buf, 
sizeof(buf));
 
  890    uint8_t routingNextHeader = buf[0];
 
  891    uint8_t routingLength = buf[1];
 
  892    uint8_t routingTypeRouting = buf[2];
 
  893    uint8_t routingSegmentsLeft = buf[3];
 
  897        *nextHeader = routingNextHeader;
 
  905        ipv6ExtensionRoutingDemux->GetExtensionRouting(routingTypeRouting);
 
  907    if (!ipv6ExtensionRouting)
 
  909        if (routingSegmentsLeft == 0)
 
  917            icmpv6->SendErrorParameterError(malformedPacket,
 
  923            stopProcessing = 
true;
 
  926        return routingLength;
 
  929    return ipv6ExtensionRouting->Process(packet,
 
 
  945        TypeId(
"ns3::Ipv6ExtensionRoutingDemux")
 
  947            .SetGroupName(
"Internet")
 
  948            .AddAttribute(
"RoutingExtensions",
 
  949                          "The set of IPv6 Routing extensions registered with this demux.",
 
 
  968    for (
auto it = m_extensionsRouting.begin(); it != m_extensionsRouting.end(); it++)
 
  973    m_extensionsRouting.clear();
 
 
  989    m_extensionsRouting.push_back(extensionRouting);
 
 
  995    for (
const auto& extRouting : m_extensionsRouting)
 
  997        if (extRouting->GetTypeRouting() == typeRouting)
 
 
 1011    for (
const auto& extRouting : m_extensionsRouting)
 
 1013        if (extRouting->GetTypeRouting() == typeRouting)
 
 1015            return extRouting->GetExtensionRoutingHeaderPtr();
 
 
 1026    m_extensionsRouting.remove(extensionRouting);
 
 
 1034    static TypeId tid = 
TypeId(
"ns3::Ipv6ExtensionLooseRouting")
 
 1036                            .SetGroupName(
"Internet")
 
 
 1052    return TYPE_ROUTING;
 
 
 1066                                   uint8_t* nextHeader,
 
 1067                                   bool& stopProcessing,
 
 1071    NS_LOG_FUNCTION(
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
 
 1075    malformedPacket->AddHeader(ipv6Header);
 
 1078    p->RemoveAtStart(offset);
 
 1090    p->CopyData(buf, 
sizeof(buf));
 
 1092    p->RemoveHeader(routingHeader);
 
 1105    uint8_t length = (routingHeader.
GetLength() >> 3) - 1;
 
 1106    uint8_t nbAddress = length / 2;
 
 1107    uint8_t nextAddressIndex;
 
 1110    if (segmentsLeft == 0)
 
 1116    if (length % 2 != 0)
 
 1119        icmpv6->SendErrorParameterError(malformedPacket,
 
 1125        stopProcessing = 
true;
 
 1129    if (segmentsLeft > nbAddress)
 
 1132        icmpv6->SendErrorParameterError(malformedPacket,
 
 1138        stopProcessing = 
true;
 
 1143    nextAddressIndex = nbAddress - segmentsLeft;
 
 1150        stopProcessing = 
true;
 
 1163        stopProcessing = 
true;
 
 1168    p->AddHeader(routingHeader);
 
 1182    Ptr<Ipv6Route> rtentry = ipv6rp->RouteOutput(p, ipv6header, 
nullptr, err);
 
 1187        ipv6->SendRealOut(rtentry, p, ipv6header);
 
 
 1207                            .SetGroupName(
"Internet")
 
 
 1231                          uint8_t* nextHeader,
 
 1232                          bool& stopProcessing,
 
 1236    NS_LOG_FUNCTION(
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
 
 
 1250                            .SetGroupName(
"Internet")
 
 
 1274                         uint8_t* nextHeader,
 
 1275                         bool& stopProcessing,
 
 1279    NS_LOG_FUNCTION(
this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
 
 
iterator in a Buffer instance
automatically resized byte buffer
void AddAtStart(uint32_t start)
Buffer::Iterator Begin() const
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
bool IsPending() const
This method is syntactic sugar for !IsExpired().
An implementation of the ICMPv6 protocol.
Describes an IPv6 address.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
IPv6 Extension AH (Authentication Header)
~Ipv6ExtensionAH() override
Destructor.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
static TypeId GetTypeId()
Get the type identificator.
uint8_t GetExtensionNumber() const override
Get the extension number.
Ipv6ExtensionAH()
Constructor.
Demultiplexes IPv6 extensions.
IPv6 Extension Destination.
Ipv6ExtensionDestination()
Constructor.
uint8_t GetExtensionNumber() const override
Get the extension number.
static const uint8_t EXT_NUMBER
Destination extension number.
static TypeId GetTypeId()
Get the type identificator.
~Ipv6ExtensionDestination() override
Destructor.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
IPv6 Extension ESP (Encapsulating Security Payload)
~Ipv6ExtensionESP() override
Destructor.
Ipv6ExtensionESP()
Constructor.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
uint8_t GetExtensionNumber() const override
Get the extension number.
static TypeId GetTypeId()
Get the type identificator.
Ptr< Packet > GetPartialPacket() const
Get the packet parts so far received.
Ptr< Packet > GetPacket() const
Get the entire packet.
void AddFragment(Ptr< Packet > fragment, uint16_t fragmentOffset, bool moreFragment)
Add a fragment.
void SetTimeoutIter(FragmentsTimeoutsListI_t iter)
Set the Timeout iterator.
void SetUnfragmentablePart(Ptr< Packet > unfragmentablePart)
Set the unfragmentable part of the packet.
bool IsEntire() const
If all fragments have been added.
FragmentsTimeoutsListI_t GetTimeoutIter()
Get the Timeout iterator.
Time m_fragmentExpirationTimeout
Expiration timeout.
void HandleTimeout()
Handles a fragmented packet timeout.
Ipv6ExtensionFragment()
Constructor.
static TypeId GetTypeId()
Get the type identificator.
void GetFragments(Ptr< Packet > packet, Ipv6Header ipv6Header, uint32_t fragmentSize, std::list< Ipv6PayloadHeaderPair > &listFragments)
Fragment a packet.
std::pair< Ipv6Address, uint32_t > FragmentKey_t
Key identifying a fragmented packet.
EventId m_timeoutEvent
Event for the next scheduled timeout.
MapFragments_t m_fragments
The hash of fragmented packets.
void DoDispose() override
Dispose this object.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
std::list< std::tuple< Time, FragmentKey_t, Ipv6Header > >::iterator FragmentsTimeoutsListI_t
Container Iterator for fragment timeouts.
~Ipv6ExtensionFragment() override
Destructor.
FragmentsTimeoutsList_t m_timeoutEventList
Timeout "events" container.
void HandleFragmentsTimeout(FragmentKey_t key, Ipv6Header ipHeader)
Process the timeout for packet fragments.
FragmentsTimeoutsListI_t SetTimeout(FragmentKey_t key, Ipv6Header ipHeader)
Set a new timeout "event" for a fragmented packet.
uint8_t GetExtensionNumber() const override
Get the extension number.
static const uint8_t EXT_NUMBER
Fragmentation extension number.
IPv6 Extension "Hop By Hop".
static TypeId GetTypeId()
Get the type identificator.
~Ipv6ExtensionHopByHop() override
Destructor.
Ipv6ExtensionHopByHop()
Constructor.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
static const uint8_t EXT_NUMBER
Hop-by-hop extension number.
uint8_t GetExtensionNumber() const override
Get the extension number.
IPv6 Extension base If you want to implement a new IPv6 extension, all you have to do is implement a ...
Ptr< Node > GetNode() const
Get the node.
virtual uint8_t ProcessOptions(Ptr< Packet > &packet, uint8_t offset, uint8_t length, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason)
Process options Called by implementing classes to process the options.
virtual uint8_t GetExtensionNumber() const =0
Get the extension number.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Ptr< Node > m_node
The node.
void SetNode(Ptr< Node > node)
Set the node.
Ptr< UniformRandomVariable > m_uvar
Provides uniform random variables.
~Ipv6Extension() override
Destructor.
Ipv6Extension()
Constructor.
static TypeId GetTypeId()
Get the type identificator.
IPv6 Extension Loose Routing.
static TypeId GetTypeId()
Get the type identificator.
~Ipv6ExtensionLooseRouting() override
Destructor.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
uint8_t GetTypeRouting() const override
Get the type of routing.
Ipv6ExtensionLooseRouting()
Constructor.
Ipv6ExtensionRoutingHeader * GetExtensionRoutingHeaderPtr() override
Get a pointer to a new routing extension header.
IPv6 Extension Routing Demux.
Ipv6ExtensionRoutingDemux()
Constructor.
void DoDispose() override
Dispose this object.
void Insert(Ptr< Ipv6ExtensionRouting > extensionRouting)
Insert a new IPv6 Routing Extension.
static TypeId GetTypeId()
The interface ID.
void SetNode(Ptr< Node > node)
Set the node.
Ptr< Ipv6ExtensionRouting > GetExtensionRouting(uint8_t typeRouting)
Get the routing extension corresponding to typeRouting.
void Remove(Ptr< Ipv6ExtensionRouting > extensionRouting)
Remove a routing extension from this demux.
Ipv6ExtensionRoutingList_t m_extensionsRouting
List of IPv6 Routing Extensions supported.
Ipv6ExtensionRoutingHeader * GetExtensionRoutingHeaderPtr(uint8_t typeRouting)
Get a pointer to a new routing extension header corresponding to typeRouting.
~Ipv6ExtensionRoutingDemux() override
Destructor.
uint8_t GetExtensionNumber() const override
Get the extension number.
Ipv6ExtensionRouting()
Constructor.
~Ipv6ExtensionRouting() override
Destructor.
virtual Ipv6ExtensionRoutingHeader * GetExtensionRoutingHeaderPtr()
Get a pointer to a new routing extension header.
static TypeId GetTypeId()
Get the type identificator.
virtual uint8_t GetTypeRouting() const
Get the type of routing.
uint8_t Process(Ptr< Packet > &packet, uint8_t offset, const Ipv6Header &ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool &stopProcessing, bool &isDropped, Ipv6L3Protocol::DropReason &dropReason) override
Process method Called from Ipv6L3Protocol::Receive.
IPv6 layer implementation.
DropReason
Reason why a packet has been dropped.
@ DROP_FRAGMENT_TIMEOUT
Fragment timeout.
@ DROP_UNKNOWN_OPTION
Unknown option.
@ DROP_MALFORMED_HEADER
Malformed header.
A base class which provides memory management and object aggregation.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
virtual void DoDispose()
Destructor implementation.
uint32_t GetOptionsOffset() const
Get the offset where the options begin, measured from the start of the extension header.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time Now()
Return the current simulation virtual time.
SocketErrno
Enumeration of the possible errors returned by a socket.
Simulation virtual time values and global simulation resolution.
AttributeValue implementation for Time.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeChecker > MakeObjectVectorChecker()
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Ptr< const AttributeChecker > MakeUintegerChecker()
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Time Seconds(double value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.