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 
33 namespace ns3 {
34 
35 NS_LOG_COMPONENT_DEFINE ("Icmpv4L4Protocol");
36 
37 NS_OBJECT_ENSURE_REGISTERED (Icmpv4L4Protocol);
38 
39 // see rfc 792
40 const uint8_t Icmpv4L4Protocol::PROT_NUMBER = 1;
41 
42 TypeId
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 
64 void
66 {
67  NS_LOG_FUNCTION (this << node);
68  m_node = node;
69 }
70 
71 /*
72  * This method is called by AddAgregate 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  */
76 void
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 
99 uint16_t
101 {
103  return PROT_NUMBER;
104 }
105 
106 int
108 {
109  NS_LOG_FUNCTION (this);
110  return PROT_NUMBER;
111 }
112 void
113 Icmpv4L4Protocol::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 
137 void
138 Icmpv4L4Protocol::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);
144  if (Node::ChecksumEnabled ())
145  {
146  icmp.EnableChecksum ();
147  }
148  packet->AddHeader (icmp);
149 
150  m_downTarget (packet, source, dest, PROT_NUMBER, route);
151 }
152 void
154  Ptr<const Packet> orgData,
155  uint16_t nextHopMtu)
156 {
157  NS_LOG_FUNCTION (this << header << *orgData << nextHopMtu);
159 }
160 void
162  Ptr<const Packet> orgData)
163 {
164  NS_LOG_FUNCTION (this << header << *orgData);
166 }
167 void
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 
181 void
183 {
184  NS_LOG_FUNCTION (this << header << *orgData);
185  Ptr<Packet> p = Create<Packet> ();
186  Icmpv4TimeExceeded time;
187  time.SetHeader (header);
188  time.SetData (orgData);
189  p->AddHeader (time);
190  if (!isFragment)
191  {
193  }
194  else
195  {
197  }
198 }
199 
200 void
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 }
214 void
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 }
229 void
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 }
244 void
246  Icmpv4Header icmp,
247  Ipv4Address source,
248  Ipv4Address destination)
249 {
250  NS_LOG_FUNCTION (this << p << icmp << source << destination);
251 
252  Icmpv4TimeExceeded time;
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.GetSourceAddress () << header.GetDestinationAddress () << incomingInterface);
293 }
294 void
296 {
297  NS_LOG_FUNCTION (this);
298  m_node = 0;
301 }
302 
303 void
305 {
306  NS_LOG_FUNCTION (this << &callback);
307  m_downTarget = callback;
308 }
309 
310 void
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
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
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:326
Packet header for IPv6.
Definition: ipv6-header.h:34
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 "...
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:45
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
ICMP Time Exceeded header.
Definition: icmpv4.h:245
static bool ChecksumEnabled(void)
Definition: node.cc:276
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
#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:202
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
#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
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
Base class for all the ICMP packet headers.
Definition: icmpv4.h:40
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:307
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:33
void EnableChecksum(void)
Enables ICMP Checksum calculation.
Definition: icmpv4.cc:57
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
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:432
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:290
void SetNextHopMtu(uint16_t mtu)
Set the next hop MTU.
Definition: icmpv4.cc:301
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual int GetProtocolNumber(void) const
Get the protocol number.
ICMP Echo header.
Definition: icmpv4.h:107
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.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
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.
void SendTimeExceededTtl(Ipv4Header header, Ptr< const Packet > orgData, bool isFragment)
Send a Time Exceeded ICMP error.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:262
static uint16_t GetStaticProtocolNumber(void)
Get the protocol number.
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition: icmpv4.cc:438
ICMP Destination Unreachable header.
Definition: icmpv4.h:172
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:100
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:270
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:1274
RxStatus
Rx status codes.
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:325
Ipv4Header GetHeader(void) const
Get the ICMP carried IPv4 header.
Definition: icmpv4.cc:332
This is the implementation of the ICMP protocol as described in RFC 792.
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:58
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:444
void SendMessage(Ptr< Packet > packet, Ipv4Address dest, uint8_t type, uint8_t code)
Send a generic ICMP packet.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
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:256
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:110
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.