23 #include "ns3/uinteger.h"
24 #include "ns3/vector.h"
25 #include "ns3/boolean.h"
26 #include "ns3/callback.h"
27 #include "ns3/trace-source-accessor.h"
28 #include "ns3/object-vector.h"
29 #include "ns3/ipv6-routing-protocol.h"
30 #include "ns3/ipv6-route.h"
32 #include "loopback-net-device.h"
33 #include "ipv6-l3-protocol.h"
34 #include "ipv6-interface.h"
35 #include "ipv6-raw-socket-impl.h"
36 #include "ipv6-autoconfigured-prefix.h"
37 #include "ipv6-extension-demux.h"
38 #include "ipv6-extension.h"
39 #include "ipv6-extension-header.h"
40 #include "ipv6-option-demux.h"
41 #include "ipv6-option.h"
42 #include "icmpv6-l4-protocol.h"
43 #include "ndisc-cache.h"
47 NS_OBJECT_ENSURE_REGISTERED (Ipv6L3Protocol);
57 .AddConstructor<Ipv6L3Protocol> ()
58 .AddAttribute (
"DefaultTtl",
"The TTL value set by default on all outgoing packets generated on this node.",
61 MakeUintegerChecker<uint8_t> ())
62 .AddAttribute (
"DefaultTclass",
"The TCLASS value set by default on all outgoing packets generated on this node.",
65 MakeUintegerChecker<uint8_t> ())
66 .AddAttribute (
"InterfaceList",
"The set of IPv6 interfaces associated to this IPv6 stack.",
69 MakeObjectVectorChecker<Ipv6Interface> ())
70 .AddAttribute (
"SendIcmpv6Redirect",
"Send the ICMPv6 Redirect when appropriate.",
74 MakeBooleanChecker ())
75 .AddTraceSource (
"Tx",
"Send IPv6 packet to outgoing interface.",
77 .AddTraceSource (
"Rx",
"Receive IPv6 packet from incoming interface.",
79 .AddTraceSource (
"Drop",
"Drop IPv6 packet",
124 (*it)->StopValidTimer ();
125 (*it)->StopPreferredTimer ();
155 interface->SetNode (
m_node);
156 interface->SetDevice (device);
201 uint32_t max = (*it)->GetNAddresses ();
203 for (j = 0; j < max; j++)
205 if ((*it)->GetAddress (j).GetAddress () == address)
223 for (j = 0; j < (*it)->GetNAddresses (); j++)
225 if ((*it)->GetAddress (j).GetAddress ().CombinePrefix (mask) == address.
CombinePrefix (mask))
248 if ((*it)->GetDevice () == device)
259 NS_LOG_FUNCTION (
this << interface << network << mask << (uint32_t)flags << validTime << preferredTime);
264 if (flags & (1 << 6))
273 NS_FATAL_ERROR (
"Unknown method to make autoconfigured address for this kind of device.");
280 if ((*it)->GetInterface () ==
interface && (*it)->GetPrefix () == network && (*it)->GetMask () == mask)
282 (*it)->StopPreferredTimer ();
283 (*it)->StopValidTimer ();
284 (*it)->StartPreferredTimer ();
314 for (i = 0; i < max; i++)
326 if ((*it)->GetInterface () ==
interface && (*it)->GetPrefix () == network && (*it)->GetMask () == mask)
399 return interface->
GetDevice ()->GetMtu ();
406 return interface->
IsUp ();
453 device = CreateObject<LoopbackNetDevice> ();
457 interface->SetDevice (device);
458 interface->SetNode (
m_node);
460 interface->AddAddress (ifaceAddr);
477 NS_LOG_LOGIC (
"Forwarding state: " << interface->IsForwarding ());
478 return interface->IsForwarding ();
495 (*it)->SetForwarding (forward);
523 Ptr<Node> node = this->GetObject<Node> ();
560 if ((*i)->GetProtocolNumber () == protocolNumber)
620 NS_LOG_FUNCTION (
this << packet << source << destination << (uint32_t)protocol << route);
628 ttl = tag.GetHopLimit ();
637 tclass = tclassTag.GetTclass ();
649 NS_LOG_LOGIC (
"Ipv6L3Protocol::Send case 1: passed in with a route");
658 NS_LOG_LOGIC (
"Ipv6L3Protocol::Send case 1: probably sent to machine on same IPv6 network");
666 NS_LOG_LOGIC (
"Ipv6L3Protocol::Send case 3: passed in with no route " << destination);
667 Socket::SocketErrno err;
701 NS_LOG_FUNCTION (
this << device << p << protocol << from << to << packetType);
703 uint32_t
interface = 0;
711 if (ipv6Interface->
GetDevice () == device)
713 if (ipv6Interface->
IsUp ())
720 NS_LOG_LOGIC (
"Dropping received packet-- interface is down");
722 packet->RemoveHeader (hdr);
731 packet->RemoveHeader (hdr);
749 bool isDropped =
false;
751 if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
753 ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
772 NS_LOG_WARN (
"No route found for forwarding packet. Drop.");
788 int32_t
interface = GetInterfaceForDevice (dev);
792 NS_LOG_LOGIC (
"Send via NetDevice ifIndex " << dev->GetIfIndex () <<
" Ipv6InterfaceIndex " << interface);
795 std::list<Ptr<Packet> > fragments;
797 if (packet->
GetSize () > (size_t)(dev->GetMtu () + 40))
806 icmpv6->SendErrorTooBig (packet, ipHeader.
GetSourceAddress (), dev->GetMtu ());
817 ipv6Fragment->
GetFragments (packet, outInterface->GetDevice ()->GetMtu (), fragments);
822 if (outInterface->IsUp ())
824 NS_LOG_LOGIC (
"Send to gateway " << route->GetGateway ());
826 if (fragments.size () != 0)
828 std::ostringstream oss;
831 for (std::list<
Ptr<Packet> >::const_iterator it = fragments.begin (); it != fragments.end (); it++)
834 outInterface->Send (*it, route->GetGateway ());
841 outInterface->Send (packet, route->GetGateway ());
846 NS_LOG_LOGIC (
"Dropping-- outgoing interface is down: " << route->GetGateway ());
852 if (outInterface->IsUp ())
856 if (fragments.size () != 0)
858 std::ostringstream oss;
861 for (std::list<
Ptr<Packet> >::const_iterator it = fragments.begin (); it != fragments.end (); it++)
890 ipHeader.SetHopLimit (ipHeader.GetHopLimit () - 1);
892 if (ipHeader.GetSourceAddress ().IsLinkLocal ())
898 if (ipHeader.GetHopLimit () == 0)
904 && ipHeader.GetDestinationAddress ().IsMulticast () ==
false)
907 GetIcmpv6 ()->SendErrorTimeExceeded (packet, ipHeader.GetSourceAddress (), Icmpv6Header::ICMPV6_HOPLIMIT);
938 if (icmpv6->Lookup (target, rtentry->GetOutputDevice (), 0, &hardwareTarget))
940 icmpv6->SendRedirection (copy, src, target, dst, hardwareTarget);
944 icmpv6->SendRedirection (copy, src, target, dst,
Address ());
956 std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap ();
957 std::map<uint32_t, uint32_t>::iterator mapIter;
959 for (mapIter = ttlMap.begin (); mapIter != ttlMap.end (); mapIter++)
961 uint32_t interfaceId = mapIter->first;
972 NS_LOG_LOGIC (
"Forward multicast via interface " << interfaceId);
993 uint8_t nextHeaderPosition = 0;
994 bool isDropped =
false;
998 if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1002 if (buf == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1004 NS_LOG_WARN(
"Double Ipv6Header::IPV6_EXT_HOP_BY_HOP in packet, dropping packet");
1013 ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
1017 uint8_t nextHeaderStep = 0;
1018 uint8_t curHeader = nextHeader;
1019 nextHeaderStep = ipv6Extension->Process (p, nextHeaderPosition, ip, dst, &nextHeader, isDropped);
1020 nextHeaderPosition += nextHeaderStep;
1026 NS_ASSERT_MSG (nextHeaderStep != 0 || curHeader == Ipv6Header::IPV6_EXT_FRAGMENTATION,
1027 "Zero-size IPv6 Option Header, aborting" << *packet );
1040 if (nextHeaderPosition == 0)
1042 GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, 40);
1046 GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, ip.
GetSerializedSize () + nextHeaderPosition);
1062 case IpL4Protocol::RX_OK:
1064 case IpL4Protocol::RX_CSUM_FAILED:
1066 case IpL4Protocol::RX_ENDPOINT_CLOSED:
1068 case IpL4Protocol::RX_ENDPOINT_UNREACH:
1081 while (ipv6Extension);
1087 NS_LOG_LOGIC (
"Route input failure-- dropping packet to " << ipHeader <<
" with errno " << sockErrno);
1093 NS_LOG_FUNCTION (
this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize << (uint32_t)ttl << (uint32_t)tclass);
1108 ipv6ExtensionDemux->SetNode (
m_node);
1111 hopbyhopExtension->SetNode (
m_node);
1113 destinationExtension->SetNode (
m_node);
1115 fragmentExtension->SetNode (
m_node);
1121 ipv6ExtensionDemux->Insert (hopbyhopExtension);
1122 ipv6ExtensionDemux->Insert (destinationExtension);
1123 ipv6ExtensionDemux->Insert (fragmentExtension);
1124 ipv6ExtensionDemux->Insert (routingExtension);
1129 routingExtensionDemux->SetNode (
m_node);
1131 looseRoutingExtension->SetNode (
m_node);
1132 routingExtensionDemux->Insert (looseRoutingExtension);
1141 ipv6OptionDemux->SetNode (
m_node);
1144 pad1Option->SetNode (
m_node);
1146 padnOption->SetNode (
m_node);
1148 jumbogramOption->SetNode (
m_node);
1150 routerAlertOption->SetNode (
m_node);
1152 ipv6OptionDemux->Insert (pad1Option);
1153 ipv6OptionDemux->Insert (padnOption);
1154 ipv6OptionDemux->Insert (jumbogramOption);
1155 ipv6OptionDemux->Insert (routerAlertOption);
void SetNode(Ptr< Node > node)
Set the node.
bool IsAny() const
If the IPv6 address is the "Any" address.
void GetFragments(Ptr< Packet > packet, uint32_t fragmentSize, std::list< Ptr< Packet > > &listFragments)
Fragment a packet.
static bool IsMatchingType(const Address &address)
static Ipv6Address GetLoopback()
Get the loopback address.
Ipv6Header BuildHeader(Ipv6Address src, Ipv6Address dst, uint8_t protocol, uint16_t payloadSize, uint8_t hopLimit, uint8_t tclass)
Construct an IPv6 header.
static Ipv6Address MakeAutoconfiguredAddress(Mac48Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address with Mac48Address.
void SetForwarding(uint32_t i, bool val)
Enable or disable forwarding on interface.
bool AddAddress(Ipv6InterfaceAddress iface)
Add an IPv6 address.
smart pointer class similar to boost::intrusive_ptr
#define NS_LOG_FUNCTION(parameters)
virtual ~Ipv6L3Protocol()
Destructor.
void SetUp()
Enable this interface.
Ipv6L3Protocol()
Constructor.
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer...
Ptr< NetDevice > GetNetDevice(uint32_t i)
Get device by index.
bool AddAddress(uint32_t i, Ipv6InterfaceAddress address)
Add an address on interface.
Ptr< Ipv6RoutingProtocol > m_routingProtocol
Routing protocol.
Access to the IPv6 forwarding table, interfaces, and configuration.
void IpForward(Ptr< Ipv6Route > rtentry, Ptr< const Packet > p, const Ipv6Header &header)
Forward a packet.
Ptr< Ipv6RoutingProtocol > GetRoutingProtocol() const
Get current routing protocol used.
uint32_t AddIpv6Interface(Ptr< Ipv6Interface > interface)
Add an IPv6 interface to the stack.
void Send(Ptr< Packet > packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr< Ipv6Route > route)
Higher-level layers call this method to send a packet down the stack to the MAC and PHY layers...
Demultiplexes IPv6 extensions.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
bool IsAllRoutersMulticast() const
If the IPv6 address is "all routers multicast" (ff02::2/8).
void SetNode(Ptr< Node > node)
Set the node.
#define NS_ASSERT(condition)
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
Ipv6InterfaceAddress GetAddress(uint32_t index) const
Get an address from IPv6 interface.
#define NS_LOG_COMPONENT_DEFINE(name)
IPv6 address associated with an interface.
static const uint8_t PROT_NUMBER
ICMPv6 protocol number (58).
uint32_t GetNAddresses(uint32_t interface) const
Get number of address for an interface.
uint32_t GetSize(void) const
void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Receive method when a packet arrive in the stack. This method removes IPv6 header and forward up to L...
virtual void DoDispose(void)
bool IsAllHostsMulticast() const
If the IPv6 address is "all hosts multicast" (ff02::3/8).
#define NS_LOG_FUNCTION_NOARGS()
virtual bool GetSendIcmpv6Redirect() const
Get the ICMPv6 Redirect sending state.
bool IsAllNodesMulticast() const
If the IPv6 address is "all nodes multicast" (ff02::1/8).
virtual void DoDispose()
Dispose object.
void SetMetric(uint32_t i, uint16_t metric)
Set metric for an interface.
bool ForwardUp(Ptr< const Packet > p, Ipv6Header hdr, Ptr< NetDevice > device)
Forward up to receive method.
uint32_t AddInterface(Ptr< NetDevice > device)
Add IPv6 interface for a device.
Ptr< Node > m_node
Node attached to stack.
bool IsUp() const
Is the interface UP ?
#define NS_FATAL_ERROR(msg)
fatal error handling
a polymophic address class
virtual void SetIpForward(bool forward)
Set IPv6 forwarding state.
virtual void NotifyNewAggregate()
Notify other components connected to the node that a new stack member is now connected.
bool IsUp(uint32_t i) const
Is specified interface up ?
uint32_t m_nInterfaces
Number of IPv6 interfaces managed by the stack.
void SetDefaultTclass(uint8_t tclass)
Set the default TCLASS.
Ipv6Address GetAddress() const
Get the IPv6 address.
uint32_t GetNAddresses(void) const
Get number of addresses on this IPv6 interface.
void SetMetric(uint16_t metric)
Set the metric.
void RemoveAtStart(uint32_t size)
int32_t GetInterfaceForPrefix(Ipv6Address addr, Ipv6Prefix mask) const
Get interface index which match specified address/prefix.
Ptr< Socket > CreateRawSocket()
Create raw IPv6 socket.
Hold an unsigned integer type.
L4List_t m_protocols
List of transport protocol.
void IpMulticastForward(Ptr< Ipv6MulticastRoute > mrtentry, Ptr< const Packet > p, const Ipv6Header &header)
Forward a packet in multicast.
void SetDefaultTtl(uint8_t ttl)
Set the default TTL.
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
Ptr< NetDevice > GetDevice(uint32_t index) const
void SetUp(uint32_t i)
Set an interface up.
An implementation of the ICMPv6 protocol.
virtual enum RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)=0
virtual Ptr< NetDevice > GetDevice() const
Get the NetDevice.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
static TypeId GetTypeId()
Get the type ID of this class.
Ipv6InterfaceList m_interfaces
List of IPv6 interfaces.
void AggregateObject(Ptr< Object > other)
#define NS_LOG_LOGIC(msg)
bool m_ipForward
Forwarding packets (i.e. router mode) state.
uint32_t GetNInterfaces() const
Get current number of interface on this stack.
static Mac48Address ConvertFrom(const Address &address)
uint16_t GetMetric(uint32_t i) const
Get metric for an interface.
virtual void NotifyNewAggregate(void)
uint32_t GetNDevices(void) const
void SetForwarding(bool forward)
Set forwarding enabled or not.
Ptr< Packet > Copy(void) const
Ipv6AutoconfiguredPrefixList m_prefixes
List of IPv6 prefix received from RA.
void LocalDeliver(Ptr< const Packet > p, Ipv6Header const &ip, uint32_t iif)
Deliver a packet.
void DeleteRawSocket(Ptr< Socket > socket)
Remove raw IPv6 socket.
virtual bool GetIpForward() const
Get IPv6 forwarding state.
static uint16_t GetStaticProtocolNumber()
Get ICMPv6 protocol number.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Ipv6InterfaceAddress GetAddress(uint32_t interfaceIndex, uint32_t addressIndex) const
Get an address.
uint8_t m_defaultTtl
Default TTL for outgoing packets.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, DropReason, Ptr< Ipv6 >, uint32_t > m_dropTrace
Callback to trace drop packets.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_rxTrace
Callback to trace RX (reception) packets.
int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const
Get interface index which is on a specified net device.
void SetNode(Ptr< Node > node)
Set node for this stack.
bool IsForwarding(uint32_t i) const
Is interface allows forwarding ?
void RemoveAutoconfiguredAddress(uint32_t interface, Ipv6Address network, Ipv6Prefix mask, Ipv6Address defaultRouter)
Remove an autoconfigured address.
void SendRealOut(Ptr< Ipv6Route > route, Ptr< Packet > packet, Ipv6Header const &ipHeader)
Send packet with route.
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
void SetupLoopback()
Setup loopback interface.
#define NS_ASSERT_MSG(condition, message)
virtual void RegisterExtensions()
Register the IPv6 Extensions.
Describes an IPv6 address.
uint16_t GetMetric() const
Get the metric.
void SetRoutingProtocol(Ptr< Ipv6RoutingProtocol > routingProtocol)
Set routing protocol for this stack.
bool IsSolicitedMulticast() const
If the IPv6 address is a Solicited multicast address.
uint32_t AddDevice(Ptr< NetDevice > device)
Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const
Get L4 protocol by protocol number.
uint32_t GetId(void) const
Ptr< Icmpv6L4Protocol > GetIcmpv6() const
Get ICMPv6 protocol.
bool RemovePacketTag(Tag &tag)
void Insert(Ptr< IpL4Protocol > protocol)
Add an L4 protocol.
uint16_t GetMtu(uint32_t i) const
Get MTU for an interface.
bool m_sendIcmpv6Redirect
Allow ICMPv6 Redirect sending state.
virtual void RegisterOptions()
Register the IPv6 Options.
Describes an IPv6 prefix. It is just a bitmask like Ipv4Mask.
void SetDown(uint32_t i)
set an interface down.
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
int32_t GetInterfaceForAddress(Ipv6Address addr) const
Get interface index which has specified IPv6 address.
bool RemoveAddress(uint32_t interfaceIndex, uint32_t addressIndex)
Remove an address from an interface.
contain a set of ns3::Object pointers.
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_txTrace
Callback to trace TX (transmission) packets.
Ipv6Address CombinePrefix(Ipv6Prefix const &prefix)
Combine this address with a prefix.
uint8_t m_defaultTclass
Default TCLASS for outgoing packets.
Ptr< T > GetObject(void) const
void SetDown()
Disable this interface.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
SocketList m_sockets
List of IPv6 raw sockets.
static const uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
Ptr< Ipv6Interface > GetInterface(uint32_t i) const
Get an interface.
void AddHeader(const Header &header)
void Remove(Ptr< IpL4Protocol > protocol)
Remove an L4 protocol.
void AddAutoconfiguredAddress(uint32_t interface, Ipv6Address network, Ipv6Prefix mask, uint8_t flags, uint32_t validTime, uint32_t preferredTime, Ipv6Address defaultRouter=Ipv6Address::GetZero())
Add an autoconfigured address with RA information.
virtual void SetSendIcmpv6Redirect(bool sendIcmpv6Redirect)
Set the ICMPv6 Redirect sending state.
void RouteInputError(Ptr< const Packet > p, const Ipv6Header &ipHeader, Socket::SocketErrno sockErrno)
Fallback when no route is found.