(internet): Refactor Ipv4L3Protocol::Send to fragment broadcast packets

This commit is contained in:
Jared Dulmage
2020-05-12 11:43:51 +02:00
committed by Tommaso Pecorella
parent e99ae43138
commit 1a4caf72b9
7 changed files with 199 additions and 134 deletions

View File

@@ -114,6 +114,11 @@ Ipv4L3Protocol::GetTypeId (void)
"and is being forwarded to another node",
MakeTraceSourceAccessor (&Ipv4L3Protocol::m_unicastForwardTrace),
"ns3::Ipv4L3Protocol::SentTracedCallback")
.AddTraceSource ("MulticastForward",
"A multicast IPv4 packet was received by this node "
"and is being forwarded to another node",
MakeTraceSourceAccessor (&Ipv4L3Protocol::m_multicastForwardTrace),
"ns3::Ipv4L3Protocol::SentTracedCallback")
.AddTraceSource ("LocalDeliver",
"An IPv4 packet was received by/for this node, "
"and it is being forward up the stack",
@@ -750,73 +755,100 @@ Ipv4L3Protocol::Send (Ptr<Packet> packet,
{
NS_LOG_FUNCTION (this << packet << source << destination << uint32_t (protocol) << route);
Ipv4Header ipHeader;
bool mayFragment = true;
// we need a copy of the packet with its tags in case we need to invoke recursion.
Ptr<Packet> pktCopyWithTags = packet->Copy ();
uint8_t ttl = m_defaultTtl;
SocketIpTtlTag tag;
bool found = packet->RemovePacketTag (tag);
if (found)
SocketIpTtlTag ipTtlTag;
bool ipTtlTagFound = packet->RemovePacketTag (ipTtlTag);
if (ipTtlTagFound)
{
ttl = tag.GetTtl ();
ttl = ipTtlTag.GetTtl ();
}
uint8_t tos = 0;
SocketIpTosTag ipTosTag;
found = packet->RemovePacketTag (ipTosTag);
if (found)
bool ipTosTagFound = packet->RemovePacketTag (ipTosTag);
if (ipTosTagFound)
{
tos = ipTosTag.GetTos ();
}
// Handle a few cases:
// 1) packet is destined to limited broadcast address
// 2) packet is destined to a subnet-directed broadcast address
// 3) packet is not broadcast, and is passed in with a route entry
// 4) packet is not broadcast, and is passed in with a route entry but route->GetGateway is not set (e.g., on-demand)
// 5) packet is not broadcast, and route is NULL (e.g., a raw socket call, or ICMP)
// can construct the header here
Ipv4Header ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
// 1) packet is destined to limited broadcast address or link-local multicast address
// Handle a few cases:
// 1) packet is passed in with a route entry
// 1a) packet is passed in with a route entry but route->GetGateway is not set (e.g., on-demand)
// 1b) packet is passed in with a route entry and valid gateway
// 2) packet is passed without a route and packet is destined to limited broadcast address
// 3) packet is passed without a route and packet is destined to a subnet-directed broadcast address
// 4) packet is passed without a route, packet is not broadcast (e.g., a raw socket call, or ICMP)
// 1) packet is passed in with route entry
if (route)
{
// 1a) route->GetGateway is not set (e.g., on-demand)
if (!route->GetGateway ().IsInitialized ())
{
// This could arise because the synchronous RouteOutput() call
// returned to the transport protocol with a source address but
// there was no next hop available yet (since a route may need
// to be queried).
NS_FATAL_ERROR ("Ipv4L3Protocol::Send case 1a: packet passed with a route but the Gateway address is uninitialized. This case not yet implemented.");
}
// 1b) with a valid gateway
NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 1b: passed in with route and valid gateway");
int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
m_sendOutgoingTrace (ipHeader, packet, interface);
SendRealOut (route, packet->Copy (), ipHeader);
return;
}
// 2) packet is destined to limited broadcast address or link-local multicast address
if (destination.IsBroadcast () || destination.IsLocalMulticast ())
{
NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 1: limited broadcast");
ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 2: limited broadcast - no route");
uint32_t ifaceIndex = 0;
for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
{
Ptr<Ipv4Interface> outInterface = *ifaceIter;
bool sendIt = false;
if (source == Ipv4Address::GetAny ())
{
sendIt = true;
}
for (uint32_t index = 0; index < outInterface->GetNAddresses (); index++)
// ANY source matches any interface
bool sendIt = source.IsAny ();
// check if some specific address on outInterface matches
for (uint32_t index = 0; !sendIt && index < outInterface->GetNAddresses (); index++)
{
if (outInterface->GetAddress (index).GetLocal () == source)
{
sendIt = true;
}
}
if (sendIt)
{
Ptr<Packet> packetCopy = packet->Copy ();
NS_ASSERT (packetCopy->GetSize () <= outInterface->GetDevice ()->GetMtu ());
m_sendOutgoingTrace (ipHeader, packetCopy, ifaceIndex);
CallTxTrace (ipHeader, packetCopy, m_node->GetObject<Ipv4> (), ifaceIndex);
outInterface->Send (packetCopy, ipHeader, destination);
// create a proxy route for this interface
Ptr<Ipv4Route> route = Create<Ipv4Route> ();
route->SetDestination (destination);
route->SetGateway (Ipv4Address::GetAny ());
route->SetSource (source);
route->SetOutputDevice (outInterface->GetDevice ());
DecreaseIdentification (source, destination, protocol);
Send (pktCopyWithTags, source, destination, protocol, route);
}
}
return;
}
// 2) check: packet is destined to a subnet-directed broadcast address
uint32_t ifaceIndex = 0;
// 3) check: packet is destined to a subnet-directed broadcast address
for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
ifaceIter != m_interfaces.end (); ifaceIter++)
{
Ptr<Ipv4Interface> outInterface = *ifaceIter;
uint32_t ifaceIndex = GetInterfaceForDevice (outInterface->GetDevice ());
for (uint32_t j = 0; j < GetNAddresses (ifaceIndex); j++)
{
Ipv4InterfaceAddress ifAddr = GetAddress (ifaceIndex, j);
@@ -824,42 +856,24 @@ Ipv4L3Protocol::Send (Ptr<Packet> packet,
if (destination.IsSubnetDirectedBroadcast (ifAddr.GetMask ()) &&
destination.CombineMask (ifAddr.GetMask ()) == ifAddr.GetLocal ().CombineMask (ifAddr.GetMask ()) )
{
NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 2: subnet directed bcast to " << ifAddr.GetLocal ());
ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
Ptr<Packet> packetCopy = packet->Copy ();
m_sendOutgoingTrace (ipHeader, packetCopy, ifaceIndex);
CallTxTrace (ipHeader, packetCopy, m_node->GetObject<Ipv4> (), ifaceIndex);
outInterface->Send (packetCopy, ipHeader, destination);
NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 3: subnet directed bcast to " << ifAddr.GetLocal () << " - no route");
// create a proxy route for this interface
Ptr<Ipv4Route> route = Create<Ipv4Route> ();
route->SetDestination (destination);
route->SetGateway (Ipv4Address::GetAny ());
route->SetSource (source);
route->SetOutputDevice (outInterface->GetDevice ());
DecreaseIdentification (source, destination, protocol);
Send (pktCopyWithTags, source, destination, protocol, route);
return;
}
}
}
// 3) packet is not broadcast, and is passed in with a route entry
// with a valid Ipv4Address as the gateway
if (route && route->GetGateway () != Ipv4Address ())
{
NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 3: passed in with route");
ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
m_sendOutgoingTrace (ipHeader, packet, interface);
SendRealOut (route, packet->Copy (), ipHeader);
return;
}
// 4) packet is not broadcast, and is passed in with a route entry but route->GetGateway is not set (e.g., on-demand)
if (route && route->GetGateway () == Ipv4Address ())
{
// This could arise because the synchronous RouteOutput() call
// returned to the transport protocol with a source address but
// there was no next hop available yet (since a route may need
// to be queried).
NS_FATAL_ERROR ("Ipv4L3Protocol::Send case 4: This case not yet implemented");
}
// 5) packet is not broadcast, and route is NULL (e.g., a raw socket call)
NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 5: passed in with no route " << destination);
// 4) packet is not broadcast, and route is NULL (e.g., a raw socket call)
NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 4: not broadcast and passed in with no route " << destination);
Socket::SocketErrno errno_;
Ptr<NetDevice> oif (0); // unused for now
ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
Ptr<Ipv4Route> newRoute;
if (m_routingProtocol != 0)
{
@@ -871,20 +885,29 @@ Ipv4L3Protocol::Send (Ptr<Packet> packet,
}
if (newRoute)
{
int32_t interface = GetInterfaceForDevice (newRoute->GetOutputDevice ());
m_sendOutgoingTrace (ipHeader, packet, interface);
SendRealOut (newRoute, packet->Copy (), ipHeader);
DecreaseIdentification (source, destination, protocol);
Send (pktCopyWithTags, source, destination, protocol, newRoute);
}
else
{
NS_LOG_WARN ("No route to host. Drop.");
m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, m_node->GetObject<Ipv4> (), 0);
DecreaseIdentification (source, destination, protocol);
}
}
// \todo when should we set ip_id? check whether we are incrementing
// m_identification on packets that may later be dropped in this stack
// and whether that deviates from Linux
void
Ipv4L3Protocol::DecreaseIdentification (Ipv4Address source,
Ipv4Address destination,
uint8_t protocol)
{
uint64_t src = source.Get ();
uint64_t dst = destination.Get ();
uint64_t srcDst = dst | (src << 32);
std::pair<uint64_t, uint8_t> key = std::make_pair (srcDst, protocol);
m_identification[key]--;
}
Ipv4Header
Ipv4L3Protocol::BuildHeader (
Ipv4Address source,
@@ -950,59 +973,37 @@ Ipv4L3Protocol::SendRealOut (Ptr<Ipv4Route> route,
Ptr<Ipv4Interface> outInterface = GetInterface (interface);
NS_LOG_LOGIC ("Send via NetDevice ifIndex " << outDev->GetIfIndex () << " ipv4InterfaceIndex " << interface);
if (route->GetGateway () != Ipv4Address ("0.0.0.0"))
Ipv4Address target;
std::string targetLabel;
if (route->GetGateway ().IsAny ())
{
if (outInterface->IsUp ())
target = ipHeader.GetDestination ();
targetLabel = "destination";
}
else
{
target = route->GetGateway ();
targetLabel = "gateway";
}
if (outInterface->IsUp ())
{
NS_LOG_LOGIC ("Send to " << targetLabel << " " << target);
if ( packet->GetSize () + ipHeader.GetSerializedSize () > outInterface->GetDevice ()->GetMtu () )
{
NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
if ( packet->GetSize () + ipHeader.GetSerializedSize () > outInterface->GetDevice ()->GetMtu () )
std::list<Ipv4PayloadHeaderPair> listFragments;
DoFragmentation (packet, ipHeader, outInterface->GetDevice ()->GetMtu (), listFragments);
for ( std::list<Ipv4PayloadHeaderPair>::iterator it = listFragments.begin (); it != listFragments.end (); it++ )
{
std::list<Ipv4PayloadHeaderPair> listFragments;
DoFragmentation (packet, ipHeader, outInterface->GetDevice ()->GetMtu (), listFragments);
for ( std::list<Ipv4PayloadHeaderPair>::iterator it = listFragments.begin (); it != listFragments.end (); it++ )
{
CallTxTrace (it->second, it->first, m_node->GetObject<Ipv4> (), interface);
outInterface->Send (it->first, it->second, route->GetGateway ());
}
}
else
{
CallTxTrace (ipHeader, packet, m_node->GetObject<Ipv4> (), interface);
outInterface->Send (packet, ipHeader, route->GetGateway ());
NS_LOG_LOGIC ("Sending fragment " << *(it->first) );
CallTxTrace (it->second, it->first, m_node->GetObject<Ipv4> (), interface);
outInterface->Send (it->first, it->second, target);
}
}
else
{
NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << route->GetGateway ());
m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv4> (), interface);
}
}
else
{
if (outInterface->IsUp ())
{
NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestination ());
if ( packet->GetSize () + ipHeader.GetSerializedSize () > outInterface->GetDevice ()->GetMtu () )
{
std::list<Ipv4PayloadHeaderPair> listFragments;
DoFragmentation (packet, ipHeader, outInterface->GetDevice ()->GetMtu (), listFragments);
for ( std::list<Ipv4PayloadHeaderPair>::iterator it = listFragments.begin (); it != listFragments.end (); it++ )
{
NS_LOG_LOGIC ("Sending fragment " << *(it->first) );
CallTxTrace (it->second, it->first, m_node->GetObject<Ipv4> (), interface);
outInterface->Send (it->first, it->second, ipHeader.GetDestination ());
}
}
else
{
CallTxTrace (ipHeader, packet, m_node->GetObject<Ipv4> (), interface);
outInterface->Send (packet, ipHeader, ipHeader.GetDestination ());
}
}
else
{
NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << ipHeader.GetDestination ());
m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv4> (), interface);
CallTxTrace (ipHeader, packet, m_node->GetObject<Ipv4> (), interface);
outInterface->Send (packet, ipHeader, target);
}
}
}
@@ -1019,25 +1020,27 @@ Ipv4L3Protocol::IpMulticastForward (Ptr<Ipv4MulticastRoute> mrtentry, Ptr<const
for (mapIter = ttlMap.begin (); mapIter != ttlMap.end (); mapIter++)
{
uint32_t interfaceId = mapIter->first;
uint32_t interface = mapIter->first;
//uint32_t outputTtl = mapIter->second; // Unused for now
Ptr<Packet> packet = p->Copy ();
Ipv4Header h = header;
h.SetTtl (header.GetTtl () - 1);
if (h.GetTtl () == 0)
Ipv4Header ipHeader = header;
ipHeader.SetTtl (header.GetTtl () - 1);
if (ipHeader.GetTtl () == 0)
{
NS_LOG_WARN ("TTL exceeded. Drop.");
m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv4> (), interfaceId);
m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv4> (), interface);
return;
}
NS_LOG_LOGIC ("Forward multicast via interface " << interfaceId);
NS_LOG_LOGIC ("Forward multicast via interface " << interface);
Ptr<Ipv4Route> rtentry = Create<Ipv4Route> ();
rtentry->SetSource (h.GetSource ());
rtentry->SetDestination (h.GetDestination ());
rtentry->SetSource (ipHeader.GetSource ());
rtentry->SetDestination (ipHeader.GetDestination ());
rtentry->SetGateway (Ipv4Address::GetAny ());
rtentry->SetOutputDevice (GetNetDevice (interfaceId));
SendRealOut (rtentry, packet, h);
rtentry->SetOutputDevice (GetNetDevice (interface));
m_multicastForwardTrace (ipHeader, packet, interface);
SendRealOut (rtentry, packet, ipHeader);
continue;
}
}

View File

@@ -297,6 +297,16 @@ private:
virtual void SetWeakEsModel (bool model);
virtual bool GetWeakEsModel (void) const;
/**
* \brief Decrease the identification value for a dropped or recursed packet
* \param source source IPv4 address
* \param destination destination IPv4 address
* \param protocol L4 protocol
*/
void DecreaseIdentification (Ipv4Address source,
Ipv4Address destination,
uint8_t protocol);
/**
* \brief Construct an IPv4 header.
* \param source source IPv4 address
@@ -463,6 +473,8 @@ private:
TracedCallback<const Ipv4Header &, Ptr<const Packet>, uint32_t> m_sendOutgoingTrace;
/// Trace of unicast forwarded packets
TracedCallback<const Ipv4Header &, Ptr<const Packet>, uint32_t> m_unicastForwardTrace;
/// Trace of multicast forwarded packets
TracedCallback<const Ipv4Header &, Ptr<const Packet>, uint32_t> m_multicastForwardTrace;
/// Trace of locally delivered packets
TracedCallback<const Ipv4Header &, Ptr<const Packet>, uint32_t> m_localDeliverTrace;

View File

@@ -109,10 +109,11 @@ class Ipv4FragmentationTest: public TestCase
uint8_t *m_data; //!< Data.
uint32_t m_size; //!< packet size.
uint8_t m_icmpType; //!< ICMP type.
bool m_broadcast; //!< broadcast packets
public:
virtual void DoRun (void);
Ipv4FragmentationTest ();
Ipv4FragmentationTest (bool broadcast);
~Ipv4FragmentationTest ();
// server part
@@ -167,14 +168,16 @@ public:
};
Ipv4FragmentationTest::Ipv4FragmentationTest ()
: TestCase ("Verify the IPv4 layer 3 protocol fragmentation and reassembly")
Ipv4FragmentationTest::Ipv4FragmentationTest (bool broadcast)
: TestCase (std::string ("Verify the IPv4 layer 3 protocol fragmentation and reassembly: ") +
(broadcast? "broadcast": "unicast"))
{
m_socketServer = 0;
m_data = 0;
m_dataSize = 0;
m_size = 0;
m_icmpType = 0;
m_broadcast = broadcast;
}
Ipv4FragmentationTest::~Ipv4FragmentationTest ()
@@ -235,6 +238,7 @@ Ipv4FragmentationTest::StartClient (Ptr<Node> ClientNode)
m_socketClient->Connect (InetSocketAddress (Ipv4Address ("10.0.0.1"), 9));
CallbackValue cbValue = MakeCallback(&Ipv4FragmentationTest::HandleReadIcmpClient, this);
m_socketClient->SetAttribute ("IcmpCallback", cbValue);
m_socketClient->SetAllowBroadcast (m_broadcast);
}
m_socketClient->SetRecvCallback(MakeCallback(&Ipv4FragmentationTest::HandleReadClient, this));
@@ -306,7 +310,18 @@ Ptr<Packet> Ipv4FragmentationTest::SendClient (void)
p->AddPacketTag (tag);
p->AddByteTag (tag);
m_socketClient->Send (p);
if (m_broadcast)
{
Address address;
m_socketClient->GetPeerName (address);
InetSocketAddress saddress = InetSocketAddress::ConvertFrom (address);
saddress.SetIpv4 (Ipv4Address::GetBroadcast ());
m_socketClient->SendTo (p, 0, saddress);
}
else
{
m_socketClient->Send (p);
}
return p;
}
@@ -527,7 +542,8 @@ public:
Ipv4FragmentationTestSuite::Ipv4FragmentationTestSuite ()
: TestSuite ("ipv4-fragmentation", UNIT)
{
AddTestCase (new Ipv4FragmentationTest, TestCase::QUICK);
AddTestCase (new Ipv4FragmentationTest(false), TestCase::QUICK);
AddTestCase (new Ipv4FragmentationTest(true), TestCase::QUICK);
}
static Ipv4FragmentationTestSuite g_ipv4fragmentationTestSuite; //!< Static variable for test initialization

View File

@@ -197,9 +197,10 @@ Ipv4Mask::GetPrefixLength (void) const
return tmp;
}
static constexpr uint32_t UNINITIALIZED = 0x66666666U;
Ipv4Address::Ipv4Address ()
: m_address (0x66666666)
: m_address (UNINITIALIZED), m_initialized (false)
{
NS_LOG_FUNCTION (this);
}
@@ -207,11 +208,13 @@ Ipv4Address::Ipv4Address (uint32_t address)
{
NS_LOG_FUNCTION (this << address);
m_address = address;
m_initialized = true;
}
Ipv4Address::Ipv4Address (char const *address)
{
NS_LOG_FUNCTION (this << address);
m_address = AsciiToIpv4Host (address);
m_initialized = true;
}
uint32_t
@@ -225,12 +228,14 @@ Ipv4Address::Set (uint32_t address)
{
NS_LOG_FUNCTION (this << address);
m_address = address;
m_initialized = true;
}
void
Ipv4Address::Set (char const *address)
{
NS_LOG_FUNCTION (this << address);
m_address = AsciiToIpv4Host (address);
m_initialized = true;
}
Ipv4Address
@@ -264,6 +269,13 @@ Ipv4Address::IsSubnetDirectedBroadcast (Ipv4Mask const &mask) const
return ( (Get () | mask.GetInverse ()) == Get () );
}
bool
Ipv4Address::IsInitialized (void) const
{
NS_LOG_FUNCTION (this);
return (m_initialized);
}
bool
Ipv4Address::IsAny (void) const
{
@@ -326,6 +338,8 @@ Ipv4Address::Deserialize (const uint8_t buf[4])
ipv4.m_address |= buf[2];
ipv4.m_address <<= 8;
ipv4.m_address |= buf[3];
ipv4.m_initialized = true;
return ipv4;
}

View File

@@ -110,6 +110,11 @@ public:
* \param os The output stream to which this Ipv4Address is printed
*/
void Print (std::ostream &os) const;
/**
* \return true if address is initialized (i.e., set to something), false otherwise
*/
bool IsInitialized (void) const;
/**
* \return true if address is 0.0.0.0; false otherwise
*/
@@ -220,6 +225,7 @@ private:
*/
static uint8_t GetType (void);
uint32_t m_address; //!< IPv4 address
bool m_initialized; //!< IPv4 address has been explicitly initialized to a valid value.
/**
* \brief Equal to operator.

View File

@@ -282,24 +282,28 @@ Ipv6Address::Ipv6Address ()
{
NS_LOG_FUNCTION (this);
memset (m_address, 0x00, 16);
m_initialized = false;
}
Ipv6Address::Ipv6Address (Ipv6Address const& addr)
{
// Do not add function logging here, to avoid stack overflow
memcpy (m_address, addr.m_address, 16);
m_initialized = true;
}
Ipv6Address::Ipv6Address (Ipv6Address const* addr)
{
// Do not add function logging here, to avoid stack overflow
memcpy (m_address, addr->m_address, 16);
m_initialized = true;
}
Ipv6Address::Ipv6Address (char const* address)
{
NS_LOG_FUNCTION (this << address);
AsciiToIpv6Host (address, m_address);
m_initialized = true;
}
Ipv6Address::Ipv6Address (uint8_t address[16])
@@ -307,6 +311,7 @@ Ipv6Address::Ipv6Address (uint8_t address[16])
NS_LOG_FUNCTION (this << &address);
/* 128 bit => 16 bytes */
memcpy (m_address, address, 16);
m_initialized = true;
}
Ipv6Address::~Ipv6Address ()
@@ -319,6 +324,7 @@ void Ipv6Address::Set (char const* address)
{
NS_LOG_FUNCTION (this << address);
AsciiToIpv6Host (address, m_address);
m_initialized = true;
}
void Ipv6Address::Set (uint8_t address[16])
@@ -326,6 +332,7 @@ void Ipv6Address::Set (uint8_t address[16])
/* 128 bit => 16 bytes */
NS_LOG_FUNCTION (this << &address);
memcpy (m_address, address, 16);
m_initialized = true;
}
void Ipv6Address::Serialize (uint8_t buf[16]) const
@@ -338,6 +345,7 @@ Ipv6Address Ipv6Address::Deserialize (const uint8_t buf[16])
{
NS_LOG_FUNCTION (&buf);
Ipv6Address ipv6 ((uint8_t*)buf);
ipv6.m_initialized = true;
return ipv6;
}
@@ -353,12 +361,12 @@ Ipv6Address Ipv6Address::MakeIpv4MappedAddress(Ipv4Address addr)
Ipv4Address Ipv6Address::GetIpv4MappedAddress() const
{
NS_LOG_FUNCTION (this);
uint8_t buf[16];
Ipv4Address v4Addr;
uint8_t buf[16];
Ipv4Address v4Addr;
Serialize (buf);
v4Addr = Ipv4Address::Deserialize (&buf[12]);
return (v4Addr);
Serialize (buf);
v4Addr = Ipv4Address::Deserialize (&buf[12]);
return (v4Addr);
}
Ipv6Address Ipv6Address::MakeAutoconfiguredAddress (Address addr, Ipv6Address prefix)

View File

@@ -344,6 +344,11 @@ public:
*/
static Ipv6Address ConvertFrom (const Address& address);
/**
* \return true if address is initialized (i.e., set to something), false otherwise
*/
bool IsInitialized (void) const;
/**
* \brief Get the 0 (::) Ipv6Address.
* \return the :: Ipv6Address representation
@@ -410,6 +415,7 @@ private:
* \brief The address representation on 128 bits (16 bytes).
*/
uint8_t m_address[16];
bool m_initialized; //!< IPv6 address has been explicitly initialized to a valid value.
/**
* \brief Equal to operator.