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
31TypeId
33{
34 static TypeId tid = TypeId("ns3::Icmpv4L4Protocol")
36 .SetGroupName("Internet")
37 .AddConstructor<Icmpv4L4Protocol>();
38 return tid;
39}
40
42 : m_node(nullptr)
43{
44 NS_LOG_FUNCTION(this);
45}
46
52
53void
55{
56 NS_LOG_FUNCTION(this << node);
57 m_node = node;
58}
59
60/*
61 * This method is called by AggregateObject and completes the aggregation
62 * by setting the node in the ICMP stack and adding ICMP factory to
63 * IPv4 stack connected to the node
64 */
65void
67{
68 NS_LOG_FUNCTION(this);
69 if (!m_node)
70 {
71 Ptr<Node> node = this->GetObject<Node>();
72 if (node)
73 {
74 Ptr<Ipv4> ipv4 = this->GetObject<Ipv4>();
75 if (ipv4 && m_downTarget.IsNull())
76 {
77 this->SetNode(node);
78 ipv4->Insert(this);
80 ipv4->AggregateObject(rawFactory);
82 }
83 }
84 }
86}
87
88uint16_t
94
95int
101
102void
103Icmpv4L4Protocol::SendMessage(Ptr<Packet> packet, Ipv4Address dest, uint8_t type, uint8_t code)
104{
105 NS_LOG_FUNCTION(this << packet << dest << static_cast<uint32_t>(type)
106 << static_cast<uint32_t>(code));
107 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4>();
108 NS_ASSERT(ipv4 && ipv4->GetRoutingProtocol());
109 Ipv4Header header;
110 header.SetDestination(dest);
111 header.SetProtocol(PROT_NUMBER);
112 Socket::SocketErrno errno_;
113 Ptr<Ipv4Route> route;
114 Ptr<NetDevice> oif(nullptr); // specify non-zero if bound to a source address
115 route = ipv4->GetRoutingProtocol()->RouteOutput(packet, header, oif, errno_);
116 if (route)
117 {
118 NS_LOG_LOGIC("Route exists");
119 Ipv4Address source = route->GetSource();
120 SendMessage(packet, source, dest, type, code, route);
121 }
122 else
123 {
124 NS_LOG_WARN("drop icmp message");
125 }
126}
127
128void
130 Ipv4Address source,
131 Ipv4Address dest,
132 uint8_t type,
133 uint8_t code,
134 Ptr<Ipv4Route> route)
135{
136 NS_LOG_FUNCTION(this << packet << source << dest << static_cast<uint32_t>(type)
137 << static_cast<uint32_t>(code) << route);
138 Icmpv4Header icmp;
139 icmp.SetType(type);
140 icmp.SetCode(code);
142 {
143 icmp.EnableChecksum();
144 }
145 packet->AddHeader(icmp);
146
147 m_downTarget(packet, source, dest, PROT_NUMBER, route);
148}
149
150void
152 Ptr<const Packet> orgData,
153 uint16_t nextHopMtu)
154{
155 NS_LOG_FUNCTION(this << header << *orgData << nextHopMtu);
157}
158
159void
165
166void
168 Ptr<const Packet> orgData,
169 uint8_t code,
170 uint16_t nextHopMtu)
171{
172 NS_LOG_FUNCTION(this << header << *orgData << (uint32_t)code << nextHopMtu);
175 unreach.SetNextHopMtu(nextHopMtu);
176 unreach.SetHeader(header);
177 unreach.SetData(orgData);
178 p->AddHeader(unreach);
180}
181
182void
184{
185 NS_LOG_FUNCTION(this << header << *orgData);
188 time.SetHeader(header);
189 time.SetData(orgData);
190 p->AddHeader(time);
191 if (!isFragment)
192 {
193 SendMessage(p,
194 header.GetSource(),
197 }
198 else
199 {
200 SendMessage(p,
201 header.GetSource(),
204 }
205}
206
207void
209 Icmpv4Header header,
210 Ipv4Address source,
211 Ipv4Address destination,
212 uint8_t tos)
213{
214 NS_LOG_FUNCTION(this << p << header << source << destination << tos);
215
216 Ptr<Packet> reply = Create<Packet>();
217 Icmpv4Echo echo;
218 p->RemoveHeader(echo);
219 reply->AddHeader(echo);
220 SocketIpTosTag ipTosTag;
221 ipTosTag.SetTos(tos);
222 reply->ReplacePacketTag(ipTosTag);
223 SendMessage(reply, destination, source, Icmpv4Header::ICMPV4_ECHO_REPLY, 0, nullptr);
224}
225
226void
228 Icmpv4Header icmp,
229 uint32_t info,
230 Ipv4Header ipHeader,
231 const uint8_t payload[8])
232{
233 NS_LOG_FUNCTION(this << source << icmp << info << ipHeader << payload);
234
235 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4>();
236 Ptr<IpL4Protocol> l4 = ipv4->GetProtocol(ipHeader.GetProtocol());
237 if (l4)
238 {
239 l4->ReceiveIcmp(source,
240 ipHeader.GetTtl(),
241 icmp.GetType(),
242 icmp.GetCode(),
243 info,
244 ipHeader.GetSource(),
245 ipHeader.GetDestination(),
246 payload);
247 }
248}
249
250void
252 Icmpv4Header icmp,
253 Ipv4Address source,
254 Ipv4Address destination)
255{
256 NS_LOG_FUNCTION(this << p << icmp << source << destination);
257
259 p->PeekHeader(unreach);
260 uint8_t payload[8];
261 unreach.GetData(payload);
262 Ipv4Header ipHeader = unreach.GetHeader();
263 Forward(source, icmp, unreach.GetNextHopMtu(), ipHeader, payload);
264}
265
266void
268 Icmpv4Header icmp,
269 Ipv4Address source,
270 Ipv4Address destination)
271{
272 NS_LOG_FUNCTION(this << p << icmp << source << destination);
273
275 p->PeekHeader(time);
276 uint8_t payload[8];
277 time.GetData(payload);
278 Ipv4Header ipHeader = time.GetHeader();
279 // info field is zero for TimeExceeded on linux
280 Forward(source, icmp, 0, ipHeader, payload);
281}
282
285 const Ipv4Header& header,
286 Ptr<Ipv4Interface> incomingInterface)
287{
288 NS_LOG_FUNCTION(this << p << header << incomingInterface);
289
290 Icmpv4Header icmp;
291 p->RemoveHeader(icmp);
292 switch (icmp.GetType())
293 {
295 Ipv4Address dst = header.GetDestination();
296 // We could have received an Echo request to a broadcast-type address.
297 if (dst.IsBroadcast())
298 {
299 Ipv4Address src = header.GetSource();
300 for (uint32_t index = 0; index < incomingInterface->GetNAddresses(); index++)
301 {
302 Ipv4InterfaceAddress addr = incomingInterface->GetAddress(index);
303 if (addr.IsInSameSubnet(src))
304 {
305 dst = addr.GetAddress();
306 }
307 }
308 }
309 else
310 {
311 for (uint32_t index = 0; index < incomingInterface->GetNAddresses(); index++)
312 {
313 Ipv4InterfaceAddress addr = incomingInterface->GetAddress(index);
314 if (dst == addr.GetBroadcast())
315 {
316 dst = addr.GetAddress();
317 }
318 }
319 }
320 HandleEcho(p, icmp, header.GetSource(), dst, header.GetTos());
321 break;
322 }
324 HandleDestUnreach(p, icmp, header.GetSource(), header.GetDestination());
325 break;
327 HandleTimeExceeded(p, icmp, header.GetSource(), header.GetDestination());
328 break;
329 default:
330 NS_LOG_DEBUG(icmp << " " << *p);
331 break;
332 }
333 return IpL4Protocol::RX_OK;
334}
335
338 const Ipv6Header& header,
339 Ptr<Ipv6Interface> incomingInterface)
340{
341 NS_LOG_FUNCTION(this << p << header.GetSource() << header.GetDestination()
342 << incomingInterface);
344}
345
346void
354
355void
357{
358 NS_LOG_FUNCTION(this << &callback);
359 m_downTarget = callback;
360}
361
362void
367
370{
371 NS_LOG_FUNCTION(this);
372 return m_downTarget;
373}
374
381
382} // 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.
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.
static constexpr uint8_t PROT_NUMBER
ICMP protocol number (see RFC 792 )
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:49
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