22 #include "ns3/icmpv6-header.h"
23 #include "ns3/inet6-socket-address.h"
24 #include "ns3/ipv6-extension-header.h"
25 #include "ns3/ipv6-header.h"
26 #include "ns3/ipv6-raw-socket-factory.h"
28 #include "ns3/nstime.h"
29 #include "ns3/packet.h"
30 #include "ns3/simulator.h"
31 #include "ns3/socket-factory.h"
32 #include "ns3/socket.h"
33 #include "ns3/uinteger.h"
47 .SetParent<Application>()
48 .SetGroupName(
"Internet-Apps")
49 .AddConstructor<
Ping6>()
52 "The maximum number of packets the application will send (zero means infinite)",
55 MakeUintegerChecker<uint32_t>())
56 .AddAttribute(
"Interval",
57 "The time to wait between packets",
61 .AddAttribute(
"RemoteIpv6",
62 "The Ipv6Address of the outbound packets",
64 MakeIpv6AddressAccessor(&Ping6::m_peerAddress),
65 MakeIpv6AddressChecker())
66 .AddAttribute(
"LocalIpv6",
67 "Local Ipv6Address of the sender",
69 MakeIpv6AddressAccessor(&Ping6::m_localAddress),
70 MakeIpv6AddressChecker())
71 .AddAttribute(
"PacketSize",
72 "Size of packets generated",
75 MakeUintegerChecker<uint32_t>());
85 m_ipInterfaceIndex = 0;
87 m_sendEvent = EventId();
104 Ping6::StartApplication()
115 m_socket->Bind(Inet6SocketAddress(m_localAddress, 0));
117 m_socket->SetRecvCallback(
MakeCallback(&Ping6::HandleRead,
this));
118 m_ipv6Protocol = m_node->GetObject<Ipv6L3Protocol>();
120 if (!m_localAddress.IsAny())
122 m_ipInterfaceIndex = m_ipv6Protocol->GetInterfaceForAddress(m_localAddress);
130 Ping6::SetLocal(Ipv6Address ipv6)
133 m_localAddress = ipv6;
137 Ping6::SetRemote(Ipv6Address ipv6)
140 m_peerAddress = ipv6;
144 Ping6::StopApplication()
157 Ping6::SetIfIndex(uint32_t ifIndex)
163 Ping6::ScheduleTransmit(
Time dt)
170 Ping6::SetRouters(std::vector<Ipv6Address> routers)
182 Ptr<Ipv6> ipv6 = GetNode()->GetObject<Ipv6>();
189 for (uint32_t i = 0; i < GetNode()->GetObject<Ipv6>()->GetNAddresses(m_ifIndex); i++)
191 Ipv6InterfaceAddress srcIa;
192 srcIa = GetNode()->GetObject<Ipv6>()->GetAddress(m_ifIndex, i);
194 if (srcIa.IsInSameSubnet(m_peerAddress))
196 src = srcIa.GetAddress();
203 src = m_localAddress;
206 uint32_t size = m_size;
209 NS_LOG_WARN(
"ICMPv6 echo request payload size must be >= 4");
213 uint8_t*
data =
new uint8_t[size];
214 memset(
data, 0, size);
220 Ptr<Packet> p = Create<Packet>(
data, size);
232 m_socket->Bind(Inet6SocketAddress(src, 0));
235 if (!m_routers.empty())
237 Ipv6ExtensionLooseRoutingHeader routingHeader;
239 routingHeader.SetTypeRouting(0);
240 routingHeader.SetSegmentsLeft(m_routers.size());
241 routingHeader.SetRoutersAddress(m_routers);
242 p->AddHeader(routingHeader);
246 m_socket->SendTo(p, 0, Inet6SocketAddress(m_peerAddress, 0));
249 NS_LOG_INFO(
"Sent " << p->GetSize() <<
" bytes to " << m_peerAddress);
251 if (m_sent < m_count || m_count == 0)
253 ScheduleTransmit(m_interval);
260 Ping6::HandleRead(Ptr<Socket> socket)
264 Ptr<Packet> packet =
nullptr;
266 while ((packet = socket->RecvFrom(from)))
272 Icmpv6DestinationUnreachable destUnreach;
273 Icmpv6TimeExceeded timeExceeded;
276 packet->RemoveHeader(hdr);
279 packet->CopyData(&
type,
sizeof(
type));
284 packet->RemoveHeader(reply);
287 << std::dec << packet->GetSize() <<
" bytes from " <<
address.GetIpv6()
288 <<
" id = " << (uint16_t)reply.GetId()
289 <<
" seq = " << (uint16_t)reply.GetSeq()
290 <<
" Hop Count = " << (uint16_t)(64 - hdr.GetHopLimit()));
294 m_ipv6Protocol->ReachabilityHint(m_ifIndex,
address.GetIpv6());
298 m_ipv6Protocol->ReachabilityHint(m_ipInterfaceIndex,
address.GetIpv6());
303 packet->RemoveHeader(destUnreach);
308 packet->RemoveHeader(timeExceeded);
void DoDispose() override
Destructor implementation.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
static bool IsMatchingType(const Address &addr)
If the address match.
AttributeValue implementation for Ipv6Address.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
static TypeId LookupByName(std::string name)
Get a TypeId by name.
static void Send(Ptr< NetDevice > dev, int level, std::string emuMode)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
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 AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Callback< R, Args... > MakeNullCallback()
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Time Seconds(double value)
Construct a Time in the indicated unit.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.