A Discrete-Event Network Simulator
API
icmpv4-l4-protocol.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2008 INRIA
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Mathieu Lacage <mathieu.lacage@cutebugs.net>
19 */
20
21#include "icmpv4-l4-protocol.h"
23#include "ipv4-interface.h"
24#include "ipv4-l3-protocol.h"
25#include "ns3/assert.h"
26#include "ns3/log.h"
27#include "ns3/node.h"
28#include "ns3/packet.h"
29#include "ns3/boolean.h"
30#include "ns3/ipv4-route.h"
31#include "ns3/ipv6-interface.h"
32
33namespace ns3 {
34
35NS_LOG_COMPONENT_DEFINE ("Icmpv4L4Protocol");
36
37NS_OBJECT_ENSURE_REGISTERED (Icmpv4L4Protocol);
38
39// see rfc 792
40const uint8_t Icmpv4L4Protocol::PROT_NUMBER = 1;
41
42TypeId
44{
45 static TypeId tid = TypeId ("ns3::Icmpv4L4Protocol")
47 .SetGroupName ("Internet")
48 .AddConstructor<Icmpv4L4Protocol> ()
49 ;
50 return tid;
51}
52
54 : m_node (0)
55{
56 NS_LOG_FUNCTION (this);
57}
59{
60 NS_LOG_FUNCTION (this);
61 NS_ASSERT (m_node == 0);
62}
63
64void
66{
67 NS_LOG_FUNCTION (this << node);
68 m_node = node;
69}
70
71/*
72 * This method is called by AggregateObject and completes the aggregation
73 * by setting the node in the ICMP stack and adding ICMP factory to
74 * IPv4 stack connected to the node
75 */
76void
78{
79 NS_LOG_FUNCTION (this);
80 if (m_node == 0)
81 {
82 Ptr<Node> node = this->GetObject<Node> ();
83 if (node != 0)
84 {
85 Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
86 if (ipv4 != 0 && m_downTarget.IsNull ())
87 {
88 this->SetNode (node);
89 ipv4->Insert (this);
90 Ptr<Ipv4RawSocketFactoryImpl> rawFactory = CreateObject<Ipv4RawSocketFactoryImpl> ();
91 ipv4->AggregateObject (rawFactory);
92 this->SetDownTarget (MakeCallback (&Ipv4::Send, ipv4));
93 }
94 }
95 }
97}
98
99uint16_t
101{
103 return PROT_NUMBER;
104}
105
106int
108{
109 NS_LOG_FUNCTION (this);
110 return PROT_NUMBER;
111}
112void
113Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address dest, uint8_t type, uint8_t code)
114{
115 NS_LOG_FUNCTION (this << packet << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code));
116 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
117 NS_ASSERT (ipv4 != 0 && ipv4->GetRoutingProtocol () != 0);
118 Ipv4Header header;
119 header.SetDestination (dest);
120 header.SetProtocol (PROT_NUMBER);
121 Socket::SocketErrno errno_;
122 Ptr<Ipv4Route> route;
123 Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
124 route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
125 if (route != 0)
126 {
127 NS_LOG_LOGIC ("Route exists");
128 Ipv4Address source = route->GetSource ();
129 SendMessage (packet, source, dest, type, code, route);
130 }
131 else
132 {
133 NS_LOG_WARN ("drop icmp message");
134 }
135}
136
137void
138Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address source, Ipv4Address dest, uint8_t type, uint8_t code, Ptr<Ipv4Route> route)
139{
140 NS_LOG_FUNCTION (this << packet << source << dest << static_cast<uint32_t> (type) << 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}
152void
154 Ptr<const Packet> orgData,
155 uint16_t nextHopMtu)
156{
157 NS_LOG_FUNCTION (this << header << *orgData << nextHopMtu);
159}
160void
162 Ptr<const Packet> orgData)
163{
164 NS_LOG_FUNCTION (this << header << *orgData);
166}
167void
169 uint8_t code, uint16_t nextHopMtu)
170{
171 NS_LOG_FUNCTION (this << header << *orgData << (uint32_t) code << nextHopMtu);
172 Ptr<Packet> p = Create<Packet> ();
174 unreach.SetNextHopMtu (nextHopMtu);
175 unreach.SetHeader (header);
176 unreach.SetData (orgData);
177 p->AddHeader (unreach);
179}
180
181void
183{
184 NS_LOG_FUNCTION (this << header << *orgData);
185 Ptr<Packet> p = Create<Packet> ();
187 time.SetHeader (header);
188 time.SetData (orgData);
189 p->AddHeader (time);
190 if (!isFragment)
191 {
193 }
194 else
195 {
197 }
198}
199
200void
202 Icmpv4Header header,
203 Ipv4Address source,
204 Ipv4Address destination)
205{
206 NS_LOG_FUNCTION (this << p << header << source << destination);
207
208 Ptr<Packet> reply = Create<Packet> ();
209 Icmpv4Echo echo;
210 p->RemoveHeader (echo);
211 reply->AddHeader (echo);
212 SendMessage (reply, destination, source, Icmpv4Header::ICMPV4_ECHO_REPLY, 0, 0);
213}
214void
216 uint32_t info, Ipv4Header ipHeader,
217 const uint8_t payload[8])
218{
219 NS_LOG_FUNCTION (this << source << icmp << info << ipHeader << payload);
220
221 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
222 Ptr<IpL4Protocol> l4 = ipv4->GetProtocol (ipHeader.GetProtocol ());
223 if (l4 != 0)
224 {
225 l4->ReceiveIcmp (source, ipHeader.GetTtl (), icmp.GetType (), icmp.GetCode (),
226 info, ipHeader.GetSource (), ipHeader.GetDestination (), payload);
227 }
228}
229void
231 Icmpv4Header icmp,
232 Ipv4Address source,
233 Ipv4Address destination)
234{
235 NS_LOG_FUNCTION (this << p << icmp << source << destination);
236
238 p->PeekHeader (unreach);
239 uint8_t payload[8];
240 unreach.GetData (payload);
241 Ipv4Header ipHeader = unreach.GetHeader ();
242 Forward (source, icmp, unreach.GetNextHopMtu (), ipHeader, payload);
243}
244void
246 Icmpv4Header icmp,
247 Ipv4Address source,
248 Ipv4Address destination)
249{
250 NS_LOG_FUNCTION (this << p << icmp << source << destination);
251
253 p->PeekHeader (time);
254 uint8_t payload[8];
255 time.GetData (payload);
256 Ipv4Header ipHeader = time.GetHeader ();
257 // info field is zero for TimeExceeded on linux
258 Forward (source, icmp, 0, ipHeader, payload);
259}
260
263 Ipv4Header const &header,
264 Ptr<Ipv4Interface> incomingInterface)
265{
266 NS_LOG_FUNCTION (this << p << header << incomingInterface);
267
268 Icmpv4Header icmp;
269 p->RemoveHeader (icmp);
270 switch (icmp.GetType ()) {
272 HandleEcho (p, icmp, header.GetSource (), header.GetDestination ());
273 break;
275 HandleDestUnreach (p, icmp, header.GetSource (), header.GetDestination ());
276 break;
278 HandleTimeExceeded (p, icmp, header.GetSource (), header.GetDestination ());
279 break;
280 default:
281 NS_LOG_DEBUG (icmp << " " << *p);
282 break;
283 }
284 return IpL4Protocol::RX_OK;
285}
288 Ipv6Header const &header,
289 Ptr<Ipv6Interface> incomingInterface)
290{
291 NS_LOG_FUNCTION (this << p << header.GetSource () << header.GetDestination () << incomingInterface);
293}
294void
296{
297 NS_LOG_FUNCTION (this);
298 m_node = 0;
301}
302
303void
305{
306 NS_LOG_FUNCTION (this << &callback);
307 m_downTarget = callback;
308}
309
310void
312{
313 NS_LOG_FUNCTION (this << &callback);
314}
315
318{
319 NS_LOG_FUNCTION (this);
320 return m_downTarget;
321}
322
325{
326 NS_LOG_FUNCTION (this);
328}
329
330} // namespace ns3
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
void Nullify(void)
Discard the implementation, set it to null.
Definition: callback.h:1391
ICMP Destination Unreachable header.
Definition: icmpv4.h:173
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition: icmpv4.cc:326
Ipv4Header GetHeader(void) const
Get the ICMP carried IPv4 header.
Definition: icmpv4.cc:332
void SetNextHopMtu(uint16_t mtu)
Set the next hop MTU.
Definition: icmpv4.cc:301
uint16_t GetNextHopMtu(void) const
Get the next hop MTU.
Definition: icmpv4.cc:307
void SetHeader(Ipv4Header header)
Set the ICMP carried IPv4 header.
Definition: icmpv4.cc:320
void SetData(Ptr< const Packet > data)
Set the ICMP carried data.
Definition: icmpv4.cc:314
ICMP Echo header.
Definition: icmpv4.h:108
Base class for all the ICMP packet headers.
Definition: icmpv4.h:41
@ ICMPV4_TIME_EXCEEDED
Definition: icmpv4.h:51
@ ICMPV4_DEST_UNREACH
Definition: icmpv4.h:49
void SetCode(uint8_t code)
Set ICMP code.
Definition: icmpv4.cc:115
void SetType(uint8_t type)
Set ICMP type.
Definition: icmpv4.cc:109
uint8_t GetType(void) const
Get ICMP type.
Definition: icmpv4.cc:121
void EnableChecksum(void)
Enables ICMP Checksum calculation.
Definition: icmpv4.cc:57
uint8_t GetCode(void) const
Get ICMP code.
Definition: icmpv4.cc:127
This is the implementation of the ICMP protocol as described in RFC 792.
virtual IpL4Protocol::DownTargetCallback GetDownTarget(void) const
This method allows a caller to get the current down target callback set for this L4 protocol (IPv4 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.
virtual enum IpL4Protocol::RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)
Receive method.
virtual void SetDownTarget6(IpL4Protocol::DownTargetCallback6 cb)
This method allows a caller to set the current down target callback set for this L4 protocol (IPv6 ca...
static const uint8_t PROT_NUMBER
ICMP protocol number (0x1)
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
virtual int GetProtocolNumber(void) const
Get the protocol number.
void SendDestUnreach(Ipv4Header header, Ptr< const Packet > orgData, uint8_t code, uint16_t nextHopMtu)
Send an ICMP Destination Unreachable packet.
void SetNode(Ptr< Node > node)
Set the node the protocol is associated with.
static uint16_t GetStaticProtocolNumber(void)
Get the protocol number.
void SendDestUnreachPort(Ipv4Header header, Ptr< const Packet > orgData)
Send a Time Exceeded ICMP error.
void HandleEcho(Ptr< Packet > p, Icmpv4Header header, Ipv4Address source, Ipv4Address destination)
Handles an incoming ICMP Echo packet.
virtual IpL4Protocol::DownTargetCallback6 GetDownTarget6(void) const
This method allows a caller to get the current down target callback set for this L4 protocol (IPv6 ca...
static TypeId GetTypeId(void)
Get the type ID.
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
virtual void SetDownTarget(IpL4Protocol::DownTargetCallback cb)
This method allows a caller to set the current down target callback set for this L4 protocol (IPv4 ca...
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.
virtual void DoDispose(void)
Destructor implementation.
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:247
Ipv4Header GetHeader(void) const
Get the ICMP carried IPv4 header.
Definition: icmpv4.cc:444
void SetHeader(Ipv4Header header)
Set the ICMP carried IPv4 header.
Definition: icmpv4.cc:432
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition: icmpv4.cc:438
void SetData(Ptr< const Packet > data)
Get the ICMP carried data.
Definition: icmpv4.cc:426
L4 Protocol abstract base class.
RxStatus
Rx status codes.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
Packet header for IPv4.
Definition: ipv4-header.h:34
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:77
virtual void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)=0
Packet header for IPv6.
Definition: ipv6-header.h:36
Ipv6Address GetSource(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:105
Ipv6Address GetDestination(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:125
static bool ChecksumEnabled(void)
Definition: node.cc:278
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:325
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#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:265
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648