A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
icmpv4-l4-protocol.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@cutebugs.net>
7 */
8
10
11#include "ipv4-interface.h"
13#include "ipv4-route.h"
15#include "ipv4.h"
16#include "ipv6-interface.h"
17
18#include "ns3/assert.h"
19#include "ns3/boolean.h"
20#include "ns3/log.h"
21#include "ns3/node.h"
22#include "ns3/packet.h"
23
24namespace ns3
25{
26
27NS_LOG_COMPONENT_DEFINE("Icmpv4L4Protocol");
28
29NS_OBJECT_ENSURE_REGISTERED(Icmpv4L4Protocol);
30
31// see rfc 792
32const uint8_t Icmpv4L4Protocol::PROT_NUMBER = 1;
33
34TypeId
36{
37 static TypeId tid = TypeId("ns3::Icmpv4L4Protocol")
39 .SetGroupName("Internet")
40 .AddConstructor<Icmpv4L4Protocol>();
41 return tid;
42}
43
45 : m_node(nullptr)
46{
47 NS_LOG_FUNCTION(this);
48}
49
55
56void
58{
59 NS_LOG_FUNCTION(this << node);
60 m_node = node;
61}
62
63/*
64 * This method is called by AggregateObject and completes the aggregation
65 * by setting the node in the ICMP stack and adding ICMP factory to
66 * IPv4 stack connected to the node
67 */
68void
70{
71 NS_LOG_FUNCTION(this);
72 if (!m_node)
73 {
74 Ptr<Node> node = this->GetObject<Node>();
75 if (node)
76 {
77 Ptr<Ipv4> ipv4 = this->GetObject<Ipv4>();
78 if (ipv4 && m_downTarget.IsNull())
79 {
80 this->SetNode(node);
81 ipv4->Insert(this);
83 ipv4->AggregateObject(rawFactory);
85 }
86 }
87 }
89}
90
91uint16_t
97
98int
100{
101 NS_LOG_FUNCTION(this);
102 return PROT_NUMBER;
103}
104
105void
106Icmpv4L4Protocol::SendMessage(Ptr<Packet> packet, Ipv4Address dest, uint8_t type, uint8_t code)
107{
108 NS_LOG_FUNCTION(this << packet << dest << static_cast<uint32_t>(type)
109 << static_cast<uint32_t>(code));
110 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4>();
111 NS_ASSERT(ipv4 && ipv4->GetRoutingProtocol());
112 Ipv4Header header;
113 header.SetDestination(dest);
114 header.SetProtocol(PROT_NUMBER);
115 Socket::SocketErrno errno_;
116 Ptr<Ipv4Route> route;
117 Ptr<NetDevice> oif(nullptr); // specify non-zero if bound to a source address
118 route = ipv4->GetRoutingProtocol()->RouteOutput(packet, header, oif, errno_);
119 if (route)
120 {
121 NS_LOG_LOGIC("Route exists");
122 Ipv4Address source = route->GetSource();
123 SendMessage(packet, source, dest, type, code, route);
124 }
125 else
126 {
127 NS_LOG_WARN("drop icmp message");
128 }
129}
130
131void
133 Ipv4Address source,
134 Ipv4Address dest,
135 uint8_t type,
136 uint8_t code,
137 Ptr<Ipv4Route> route)
138{
139 NS_LOG_FUNCTION(this << packet << source << dest << static_cast<uint32_t>(type)
140 << static_cast<uint32_t>(code) << route);
141 Icmpv4Header icmp;
142 icmp.SetType(type);
143 icmp.SetCode(code);
145 {
146 icmp.EnableChecksum();
147 }
148 packet->AddHeader(icmp);
149
150 m_downTarget(packet, source, dest, PROT_NUMBER, route);
151}
152
153void
155 Ptr<const Packet> orgData,
156 uint16_t nextHopMtu)
157{
158 NS_LOG_FUNCTION(this << header << *orgData << nextHopMtu);
160}
161
162void
168
169void
171 Ptr<const Packet> orgData,
172 uint8_t code,
173 uint16_t nextHopMtu)
174{
175 NS_LOG_FUNCTION(this << header << *orgData << (uint32_t)code << nextHopMtu);
178 unreach.SetNextHopMtu(nextHopMtu);
179 unreach.SetHeader(header);
180 unreach.SetData(orgData);
181 p->AddHeader(unreach);
183}
184
185void
187{
188 NS_LOG_FUNCTION(this << header << *orgData);
191 time.SetHeader(header);
192 time.SetData(orgData);
193 p->AddHeader(time);
194 if (!isFragment)
195 {
196 SendMessage(p,
197 header.GetSource(),
200 }
201 else
202 {
203 SendMessage(p,
204 header.GetSource(),
207 }
208}
209
210void
212 Icmpv4Header header,
213 Ipv4Address source,
214 Ipv4Address destination,
215 uint8_t tos)
216{
217 NS_LOG_FUNCTION(this << p << header << source << destination << tos);
218
219 Ptr<Packet> reply = Create<Packet>();
220 Icmpv4Echo echo;
221 p->RemoveHeader(echo);
222 reply->AddHeader(echo);
223 SocketIpTosTag ipTosTag;
224 ipTosTag.SetTos(tos);
225 reply->ReplacePacketTag(ipTosTag);
226 SendMessage(reply, destination, source, Icmpv4Header::ICMPV4_ECHO_REPLY, 0, nullptr);
227}
228
229void
231 Icmpv4Header icmp,
232 uint32_t info,
233 Ipv4Header ipHeader,
234 const uint8_t payload[8])
235{
236 NS_LOG_FUNCTION(this << source << icmp << info << ipHeader << payload);
237
238 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4>();
239 Ptr<IpL4Protocol> l4 = ipv4->GetProtocol(ipHeader.GetProtocol());
240 if (l4)
241 {
242 l4->ReceiveIcmp(source,
243 ipHeader.GetTtl(),
244 icmp.GetType(),
245 icmp.GetCode(),
246 info,
247 ipHeader.GetSource(),
248 ipHeader.GetDestination(),
249 payload);
250 }
251}
252
253void
255 Icmpv4Header icmp,
256 Ipv4Address source,
257 Ipv4Address destination)
258{
259 NS_LOG_FUNCTION(this << p << icmp << source << destination);
260
262 p->PeekHeader(unreach);
263 uint8_t payload[8];
264 unreach.GetData(payload);
265 Ipv4Header ipHeader = unreach.GetHeader();
266 Forward(source, icmp, unreach.GetNextHopMtu(), ipHeader, payload);
267}
268
269void
271 Icmpv4Header icmp,
272 Ipv4Address source,
273 Ipv4Address destination)
274{
275 NS_LOG_FUNCTION(this << p << icmp << source << destination);
276
278 p->PeekHeader(time);
279 uint8_t payload[8];
280 time.GetData(payload);
281 Ipv4Header ipHeader = time.GetHeader();
282 // info field is zero for TimeExceeded on linux
283 Forward(source, icmp, 0, ipHeader, payload);
284}
285
288 const Ipv4Header& header,
289 Ptr<Ipv4Interface> incomingInterface)
290{
291 NS_LOG_FUNCTION(this << p << header << incomingInterface);
292
293 Icmpv4Header icmp;
294 p->RemoveHeader(icmp);
295 switch (icmp.GetType())
296 {
298 Ipv4Address dst = header.GetDestination();
299 // We could have received an Echo request to a broadcast-type address.
300 if (dst.IsBroadcast())
301 {
302 Ipv4Address src = header.GetSource();
303 for (uint32_t index = 0; index < incomingInterface->GetNAddresses(); index++)
304 {
305 Ipv4InterfaceAddress addr = incomingInterface->GetAddress(index);
306 if (addr.IsInSameSubnet(src))
307 {
308 dst = addr.GetAddress();
309 }
310 }
311 }
312 else
313 {
314 for (uint32_t index = 0; index < incomingInterface->GetNAddresses(); index++)
315 {
316 Ipv4InterfaceAddress addr = incomingInterface->GetAddress(index);
317 if (dst == addr.GetBroadcast())
318 {
319 dst = addr.GetAddress();
320 }
321 }
322 }
323 HandleEcho(p, icmp, header.GetSource(), dst, header.GetTos());
324 break;
325 }
327 HandleDestUnreach(p, icmp, header.GetSource(), header.GetDestination());
328 break;
330 HandleTimeExceeded(p, icmp, header.GetSource(), header.GetDestination());
331 break;
332 default:
333 NS_LOG_DEBUG(icmp << " " << *p);
334 break;
335 }
336 return IpL4Protocol::RX_OK;
337}
338
341 const Ipv6Header& header,
342 Ptr<Ipv6Interface> incomingInterface)
343{
344 NS_LOG_FUNCTION(this << p << header.GetSource() << header.GetDestination()
345 << incomingInterface);
347}
348
349void
357
358void
360{
361 NS_LOG_FUNCTION(this << &callback);
362 m_downTarget = callback;
363}
364
365void
370
373{
374 NS_LOG_FUNCTION(this);
375 return m_downTarget;
376}
377
384
385} // namespace ns3
void Nullify()
Discard the implementation, set it to null.
Definition callback.h:561
bool IsNull() const
Check for null implementation.
Definition callback.h:555
ICMP Destination Unreachable header.
Definition icmpv4.h:164
uint16_t GetNextHopMtu() const
Get the next hop MTU.
Definition icmpv4.cc:320
Ipv4Header GetHeader() const
Get the ICMP carried IPv4 header.
Definition icmpv4.cc:348
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition icmpv4.cc:341
void SetNextHopMtu(uint16_t mtu)
Set the next hop MTU.
Definition icmpv4.cc:313
void SetHeader(Ipv4Header header)
Set the ICMP carried IPv4 header.
Definition icmpv4.cc:334
void SetData(Ptr< const Packet > data)
Set the ICMP carried data.
Definition icmpv4.cc:327
ICMP Echo header.
Definition icmpv4.h:99
Base class for all the ICMP packet headers.
Definition icmpv4.h:32
void SetCode(uint8_t code)
Set ICMP code.
Definition icmpv4.cc:112
void SetType(uint8_t type)
Set ICMP type.
Definition icmpv4.cc:105
void EnableChecksum()
Enables ICMP Checksum calculation.
Definition icmpv4.cc:49
uint8_t GetCode() const
Get ICMP code.
Definition icmpv4.cc:126
uint8_t GetType() const
Get ICMP type.
Definition icmpv4.cc:119
This is the implementation of the ICMP protocol as described in RFC 792 .
void SetDownTarget6(IpL4Protocol::DownTargetCallback6 cb) override
This method allows a caller to set the current down target callback set for this L4 protocol (IPv6 ca...
Ptr< Node > m_node
the node this protocol is associated with
void SendTimeExceededTtl(Ipv4Header header, Ptr< const Packet > orgData, bool isFragment)
Send a Time Exceeded ICMP error.
static const uint8_t PROT_NUMBER
ICMP protocol number (0x1)
void SetDownTarget(IpL4Protocol::DownTargetCallback cb) override
This method allows a caller to set the current down target callback set for this L4 protocol (IPv4 ca...
void HandleEcho(Ptr< Packet > p, Icmpv4Header header, Ipv4Address source, Ipv4Address destination, uint8_t tos)
Handles an incoming ICMP Echo packet.
void SendDestUnreach(Ipv4Header header, Ptr< const Packet > orgData, uint8_t code, uint16_t nextHopMtu)
Send an ICMP Destination Unreachable packet.
void DoDispose() override
Destructor implementation.
IpL4Protocol::DownTargetCallback6 GetDownTarget6() const override
This method allows a caller to get the current down target callback set for this L4 protocol (IPv6 ca...
static TypeId GetTypeId()
Get the type ID.
void SetNode(Ptr< Node > node)
Set the node the protocol is associated with.
void SendDestUnreachPort(Ipv4Header header, Ptr< const Packet > orgData)
Send a Time Exceeded ICMP error.
static uint16_t GetStaticProtocolNumber()
Get the protocol number.
IpL4Protocol::RxStatus Receive(Ptr< Packet > p, const Ipv4Header &header, Ptr< Ipv4Interface > incomingInterface) override
Receive method.
IpL4Protocol::DownTargetCallback GetDownTarget() const override
This method allows a caller to get the current down target callback set for this L4 protocol (IPv4 ca...
void NotifyNewAggregate() override
Notify all Objects aggregated to this one of a new Object being aggregated.
void HandleTimeExceeded(Ptr< Packet > p, Icmpv4Header icmp, Ipv4Address source, Ipv4Address destination)
Handles an incoming ICMP Time Exceeded packet.
IpL4Protocol::DownTargetCallback m_downTarget
callback to Ipv4::Send
void SendDestUnreachFragNeeded(Ipv4Header header, Ptr< const Packet > orgData, uint16_t nextHopMtu)
Send a Destination Unreachable - Fragmentation needed ICMP error.
void SendMessage(Ptr< Packet > packet, Ipv4Address dest, uint8_t type, uint8_t code)
Send a generic ICMP packet.
void HandleDestUnreach(Ptr< Packet > p, Icmpv4Header header, Ipv4Address source, Ipv4Address destination)
Handles an incoming ICMP Destination Unreachable packet.
int GetProtocolNumber() const override
Get the protocol number.
void Forward(Ipv4Address source, Icmpv4Header icmp, uint32_t info, Ipv4Header ipHeader, const uint8_t payload[8])
Forward the message to an L4 protocol.
ICMP Time Exceeded header.
Definition icmpv4.h:239
Ipv4Header GetHeader() const
Get the ICMP carried IPv4 header.
Definition icmpv4.cc:465
void SetHeader(Ipv4Header header)
Set the ICMP carried IPv4 header.
Definition icmpv4.cc:451
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition icmpv4.cc:458
void SetData(Ptr< const Packet > data)
Get the ICMP carried data.
Definition icmpv4.cc:444
L4 Protocol abstract base class.
Callback< void, Ptr< Packet >, Ipv6Address, Ipv6Address, uint8_t, Ptr< Ipv6Route > > DownTargetCallback6
callback to send packets over IPv6
RxStatus
Rx status codes.
Ipv4 addresses are stored in host order in this class.
bool IsBroadcast() const
Packet header for IPv4.
Definition ipv4-header.h:23
void SetDestination(Ipv4Address destination)
Ipv4Address GetSource() const
uint8_t GetTos() const
uint8_t GetProtocol() const
Ipv4Address GetDestination() const
void SetProtocol(uint8_t num)
uint8_t GetTtl() const
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition ipv4.h:69
virtual void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)=0
a class to store IPv4 address information on an interface
bool IsInSameSubnet(const Ipv4Address b) const
Checks if the address is in the same subnet.
Ipv4Address GetAddress() const
Get the local address.
Ipv4Address GetBroadcast() const
Get the broadcast address.
Packet header for IPv6.
Definition ipv6-header.h:24
Ipv6Address GetDestination() const
Get the "Destination address" field.
Ipv6Address GetSource() const
Get the "Source address" field.
static bool ChecksumEnabled()
Definition node.cc:267
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition object.cc:412
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
Smart pointer class similar to boost::intrusive_ptr.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition socket.h:73
indicates whether the socket has IP_TOS set.
Definition socket.h:1260
void SetTos(uint8_t tos)
Set the tag's TOS.
Definition socket.cc:787
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#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.
Definition log.h:250
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
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...
Definition callback.h:684