A Discrete-Event Network Simulator
API
icmpv4-l4-protocol.cc
Go to the documentation of this file.
1 #include "icmpv4-l4-protocol.h"
3 #include "ipv4-interface.h"
4 #include "ipv4-l3-protocol.h"
5 #include "ns3/assert.h"
6 #include "ns3/log.h"
7 #include "ns3/node.h"
8 #include "ns3/packet.h"
9 #include "ns3/boolean.h"
10 #include "ns3/ipv4-route.h"
11 
12 namespace ns3 {
13 
14 NS_LOG_COMPONENT_DEFINE ("Icmpv4L4Protocol");
15 
16 NS_OBJECT_ENSURE_REGISTERED (Icmpv4L4Protocol);
17 
18 // see rfc 792
19 const uint8_t Icmpv4L4Protocol::PROT_NUMBER = 1;
20 
21 TypeId
23 {
24  static TypeId tid = TypeId ("ns3::Icmpv4L4Protocol")
26  .SetGroupName ("Internet")
27  .AddConstructor<Icmpv4L4Protocol> ()
28  ;
29  return tid;
30 }
31 
33  : m_node (0)
34 {
35  NS_LOG_FUNCTION (this);
36 }
38 {
39  NS_LOG_FUNCTION (this);
40  NS_ASSERT (m_node == 0);
41 }
42 
43 void
45 {
46  NS_LOG_FUNCTION (this << node);
47  m_node = node;
48 }
49 
50 /*
51  * This method is called by AddAgregate and completes the aggregation
52  * by setting the node in the ICMP stack and adding ICMP factory to
53  * IPv4 stack connected to the node
54  */
55 void
57 {
58  NS_LOG_FUNCTION (this);
59  if (m_node == 0)
60  {
61  Ptr<Node> node = this->GetObject<Node> ();
62  if (node != 0)
63  {
64  Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
65  if (ipv4 != 0 && m_downTarget.IsNull ())
66  {
67  this->SetNode (node);
68  ipv4->Insert (this);
69  Ptr<Ipv4RawSocketFactoryImpl> rawFactory = CreateObject<Ipv4RawSocketFactoryImpl> ();
70  ipv4->AggregateObject (rawFactory);
71  this->SetDownTarget (MakeCallback (&Ipv4::Send, ipv4));
72  }
73  }
74  }
76 }
77 
78 uint16_t
80 {
82  return PROT_NUMBER;
83 }
84 
85 int
87 {
88  NS_LOG_FUNCTION (this);
89  return PROT_NUMBER;
90 }
91 void
92 Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address dest, uint8_t type, uint8_t code)
93 {
94  NS_LOG_FUNCTION (this << packet << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code));
95  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
96  NS_ASSERT (ipv4 != 0 && ipv4->GetRoutingProtocol () != 0);
97  Ipv4Header header;
98  header.SetDestination (dest);
99  header.SetProtocol (PROT_NUMBER);
100  Socket::SocketErrno errno_;
101  Ptr<Ipv4Route> route;
102  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
103  route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
104  if (route != 0)
105  {
106  NS_LOG_LOGIC ("Route exists");
107  Ipv4Address source = route->GetSource ();
108  SendMessage (packet, source, dest, type, code, route);
109  }
110  else
111  {
112  NS_LOG_WARN ("drop icmp message");
113  }
114 }
115 
116 void
117 Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address source, Ipv4Address dest, uint8_t type, uint8_t code, Ptr<Ipv4Route> route)
118 {
119  NS_LOG_FUNCTION (this << packet << source << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code) << route);
120  Icmpv4Header icmp;
121  icmp.SetType (type);
122  icmp.SetCode (code);
123  if (Node::ChecksumEnabled ())
124  {
125  icmp.EnableChecksum ();
126  }
127  packet->AddHeader (icmp);
128 
129  m_downTarget (packet, source, dest, PROT_NUMBER, route);
130 }
131 void
133  Ptr<const Packet> orgData,
134  uint16_t nextHopMtu)
135 {
136  NS_LOG_FUNCTION (this << header << *orgData << nextHopMtu);
137  SendDestUnreach (header, orgData, Icmpv4DestinationUnreachable::FRAG_NEEDED, nextHopMtu);
138 }
139 void
141  Ptr<const Packet> orgData)
142 {
143  NS_LOG_FUNCTION (this << header << *orgData);
145 }
146 void
148  uint8_t code, uint16_t nextHopMtu)
149 {
150  NS_LOG_FUNCTION (this << header << *orgData << (uint32_t) code << nextHopMtu);
151  Ptr<Packet> p = Create<Packet> ();
153  unreach.SetNextHopMtu (nextHopMtu);
154  unreach.SetHeader (header);
155  unreach.SetData (orgData);
156  p->AddHeader (unreach);
157  SendMessage (p, header.GetSource (), Icmpv4Header::DEST_UNREACH, code);
158 }
159 
160 void
162 {
163  NS_LOG_FUNCTION (this << header << *orgData);
164  Ptr<Packet> p = Create<Packet> ();
165  Icmpv4TimeExceeded time;
166  time.SetHeader (header);
167  time.SetData (orgData);
168  p->AddHeader (time);
170 }
171 
172 void
174  Icmpv4Header header,
175  Ipv4Address source,
176  Ipv4Address destination)
177 {
178  NS_LOG_FUNCTION (this << p << header << source << destination);
179 
180  Ptr<Packet> reply = Create<Packet> ();
181  Icmpv4Echo echo;
182  p->RemoveHeader (echo);
183  reply->AddHeader (echo);
184  SendMessage (reply, destination, source, Icmpv4Header::ECHO_REPLY, 0, 0);
185 }
186 void
188  uint32_t info, Ipv4Header ipHeader,
189  const uint8_t payload[8])
190 {
191  NS_LOG_FUNCTION (this << source << icmp << info << ipHeader << payload);
192 
193  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
194  Ptr<IpL4Protocol> l4 = ipv4->GetProtocol (ipHeader.GetProtocol ());
195  if (l4 != 0)
196  {
197  l4->ReceiveIcmp (source, ipHeader.GetTtl (), icmp.GetType (), icmp.GetCode (),
198  info, ipHeader.GetSource (), ipHeader.GetDestination (), payload);
199  }
200 }
201 void
203  Icmpv4Header icmp,
204  Ipv4Address source,
205  Ipv4Address destination)
206 {
207  NS_LOG_FUNCTION (this << p << icmp << source << destination);
208 
210  p->PeekHeader (unreach);
211  uint8_t payload[8];
212  unreach.GetData (payload);
213  Ipv4Header ipHeader = unreach.GetHeader ();
214  Forward (source, icmp, unreach.GetNextHopMtu (), ipHeader, payload);
215 }
216 void
218  Icmpv4Header icmp,
219  Ipv4Address source,
220  Ipv4Address destination)
221 {
222  NS_LOG_FUNCTION (this << p << icmp << source << destination);
223 
224  Icmpv4TimeExceeded time;
225  p->PeekHeader (time);
226  uint8_t payload[8];
227  time.GetData (payload);
228  Ipv4Header ipHeader = time.GetHeader ();
229  // info field is zero for TimeExceeded on linux
230  Forward (source, icmp, 0, ipHeader, payload);
231 }
232 
235  Ipv4Header const &header,
236  Ptr<Ipv4Interface> incomingInterface)
237 {
238  NS_LOG_FUNCTION (this << p << header << incomingInterface);
239 
240  Icmpv4Header icmp;
241  p->RemoveHeader (icmp);
242  switch (icmp.GetType ()) {
243  case Icmpv4Header::ECHO:
244  HandleEcho (p, icmp, header.GetSource (), header.GetDestination ());
245  break;
247  HandleDestUnreach (p, icmp, header.GetSource (), header.GetDestination ());
248  break;
250  HandleTimeExceeded (p, icmp, header.GetSource (), header.GetDestination ());
251  break;
252  default:
253  NS_LOG_DEBUG (icmp << " " << *p);
254  break;
255  }
256  return IpL4Protocol::RX_OK;
257 }
260  Ipv6Header const &header,
261  Ptr<Ipv6Interface> incomingInterface)
262 {
263  NS_LOG_FUNCTION (this << p << header.GetSourceAddress () << header.GetDestinationAddress () << incomingInterface);
265 }
266 void
268 {
269  NS_LOG_FUNCTION (this);
270  m_node = 0;
273 }
274 
275 void
277 {
278  NS_LOG_FUNCTION (this << &callback);
279  m_downTarget = callback;
280 }
281 
282 void
284 {
285  NS_LOG_FUNCTION (this << &callback);
286 }
287 
290 {
291  NS_LOG_FUNCTION (this);
292  return m_downTarget;
293 }
294 
297 {
298  NS_LOG_FUNCTION (this);
300 }
301 
302 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
void SetType(uint8_t type)
Set ICMP type.
Definition: icmpv4.cc:109
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition: icmpv4.cc:324
Introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
uint8_t GetCode(void) const
Get ICMP code.
Definition: icmpv4.cc:127
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
Introspection did not find any typical Config paths.
Definition: icmpv4.h:217
static bool ChecksumEnabled(void)
Definition: node.cc:269
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1078
#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
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:339
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
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...
Ptr< Node > m_node
the node this protocol is associated with
Introspection did not find any typical Config paths.
Definition: icmpv4.h:33
void SetNode(Ptr< Node > node)
Set the node the protocol is associated with.
uint16_t GetNextHopMtu(void) const
Get the next hop MTU.
Definition: icmpv4.cc:305
void SetCode(uint8_t code)
Set ICMP code.
Definition: icmpv4.cc:115
void Forward(Ipv4Address source, Icmpv4Header icmp, uint32_t info, Ipv4Header ipHeader, const uint8_t payload[8])
Forward the message to an L4 protocol.
void SendDestUnreachFragNeeded(Ipv4Header header, Ptr< const Packet > orgData, uint16_t nextHopMtu)
Send a Destination Unreachable - Fragmentation needed ICMP error.
Packet header for IPv4.
Definition: ipv4-header.h:31
void SendTimeExceededTtl(Ipv4Header header, Ptr< const Packet > orgData)
Send a Time Exceeded ICMP error.
void EnableChecksum(void)
Enables ICMP Checksum calculation.
Definition: icmpv4.cc:57
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1296
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
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...
void SetHeader(Ipv4Header header)
Set the ICMP carried IPv4 header.
Definition: icmpv4.cc:430
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:318
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:277
void SetNextHopMtu(uint16_t mtu)
Set the next hop MTU.
Definition: icmpv4.cc:299
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual int GetProtocolNumber(void) const
Get the protocol number.
Introspection did not find any typical Config paths.
Definition: icmpv4.h:91
virtual void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)=0
L4 Protocol abstract base class.
static TypeId GetTypeId(void)
Get the type ID.
void SendDestUnreachPort(Ipv4Header header, Ptr< const Packet > orgData)
Send a Time Exceeded ICMP error.
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
IpL4Protocol::DownTargetCallback m_downTarget
callback to Ipv4::Send
virtual enum IpL4Protocol::RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)
Receive method.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
virtual void DoDispose(void)
Destructor implementation.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
static uint16_t GetStaticProtocolNumber(void)
Get the protocol number.
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition: icmpv4.cc:436
Introspection did not find any typical Config paths.
Definition: icmpv4.h:151
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:101
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
void SendDestUnreach(Ipv4Header header, Ptr< const Packet > orgData, uint8_t code, uint16_t nextHopMtu)
Send an ICMP Destination Unreachable packet.
uint8_t GetType(void) const
Get ICMP type.
Definition: icmpv4.cc:121
void Nullify(void)
Discard the implementation, set it to null.
Definition: callback.h:1082
RxStatus
Rx status codes.
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
Ipv4Header GetHeader(void) const
Get the ICMP carried IPv4 header.
Definition: icmpv4.cc:330
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:455
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...
void HandleTimeExceeded(Ptr< Packet > p, Icmpv4Header icmp, Ipv4Address source, Ipv4Address destination)
Handles an incoming ICMP Time Exceeded packet.
a unique identifier for an interface.
Definition: type-id.h:57
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...
Ipv4Header GetHeader(void) const
Get the ICMP carried IPv4 header.
Definition: icmpv4.cc:442
void SendMessage(Ptr< Packet > packet, Ipv4Address dest, uint8_t type, uint8_t code)
Send a generic ICMP packet.
TypeId SetParent(TypeId tid)
Definition: type-id.cc:638
void HandleEcho(Ptr< Packet > p, Icmpv4Header header, Ipv4Address source, Ipv4Address destination)
Handles an incoming ICMP Echo packet.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:111
static const uint8_t PROT_NUMBER
ICMP protocol number (0x1)
void HandleDestUnreach(Ptr< Packet > p, Icmpv4Header header, Ipv4Address source, Ipv4Address destination)
Handles an incoming ICMP Destination Unreachable packet.