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 
32 namespace ns3 {
33 
34 NS_LOG_COMPONENT_DEFINE ("Icmpv4L4Protocol");
35 
36 NS_OBJECT_ENSURE_REGISTERED (Icmpv4L4Protocol);
37 
38 // see rfc 792
39 const uint8_t Icmpv4L4Protocol::PROT_NUMBER = 1;
40 
41 TypeId
43 {
44  static TypeId tid = TypeId ("ns3::Icmpv4L4Protocol")
46  .SetGroupName ("Internet")
47  .AddConstructor<Icmpv4L4Protocol> ()
48  ;
49  return tid;
50 }
51 
53  : m_node (0)
54 {
55  NS_LOG_FUNCTION (this);
56 }
58 {
59  NS_LOG_FUNCTION (this);
60  NS_ASSERT (m_node == 0);
61 }
62 
63 void
65 {
66  NS_LOG_FUNCTION (this << node);
67  m_node = node;
68 }
69 
70 /*
71  * This method is called by AddAgregate and completes the aggregation
72  * by setting the node in the ICMP stack and adding ICMP factory to
73  * IPv4 stack connected to the node
74  */
75 void
77 {
78  NS_LOG_FUNCTION (this);
79  if (m_node == 0)
80  {
81  Ptr<Node> node = this->GetObject<Node> ();
82  if (node != 0)
83  {
84  Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
85  if (ipv4 != 0 && m_downTarget.IsNull ())
86  {
87  this->SetNode (node);
88  ipv4->Insert (this);
89  Ptr<Ipv4RawSocketFactoryImpl> rawFactory = CreateObject<Ipv4RawSocketFactoryImpl> ();
90  ipv4->AggregateObject (rawFactory);
91  this->SetDownTarget (MakeCallback (&Ipv4::Send, ipv4));
92  }
93  }
94  }
96 }
97 
98 uint16_t
100 {
102  return PROT_NUMBER;
103 }
104 
105 int
107 {
108  NS_LOG_FUNCTION (this);
109  return PROT_NUMBER;
110 }
111 void
112 Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address dest, uint8_t type, uint8_t code)
113 {
114  NS_LOG_FUNCTION (this << packet << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code));
115  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
116  NS_ASSERT (ipv4 != 0 && ipv4->GetRoutingProtocol () != 0);
117  Ipv4Header header;
118  header.SetDestination (dest);
119  header.SetProtocol (PROT_NUMBER);
120  Socket::SocketErrno errno_;
121  Ptr<Ipv4Route> route;
122  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
123  route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
124  if (route != 0)
125  {
126  NS_LOG_LOGIC ("Route exists");
127  Ipv4Address source = route->GetSource ();
128  SendMessage (packet, source, dest, type, code, route);
129  }
130  else
131  {
132  NS_LOG_WARN ("drop icmp message");
133  }
134 }
135 
136 void
137 Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address source, Ipv4Address dest, uint8_t type, uint8_t code, Ptr<Ipv4Route> route)
138 {
139  NS_LOG_FUNCTION (this << packet << source << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code) << route);
140  Icmpv4Header icmp;
141  icmp.SetType (type);
142  icmp.SetCode (code);
143  if (Node::ChecksumEnabled ())
144  {
145  icmp.EnableChecksum ();
146  }
147  packet->AddHeader (icmp);
148 
149  m_downTarget (packet, source, dest, PROT_NUMBER, route);
150 }
151 void
153  Ptr<const Packet> orgData,
154  uint16_t nextHopMtu)
155 {
156  NS_LOG_FUNCTION (this << header << *orgData << nextHopMtu);
157  SendDestUnreach (header, orgData, Icmpv4DestinationUnreachable::FRAG_NEEDED, nextHopMtu);
158 }
159 void
161  Ptr<const Packet> orgData)
162 {
163  NS_LOG_FUNCTION (this << header << *orgData);
165 }
166 void
168  uint8_t code, uint16_t nextHopMtu)
169 {
170  NS_LOG_FUNCTION (this << header << *orgData << (uint32_t) code << nextHopMtu);
171  Ptr<Packet> p = Create<Packet> ();
173  unreach.SetNextHopMtu (nextHopMtu);
174  unreach.SetHeader (header);
175  unreach.SetData (orgData);
176  p->AddHeader (unreach);
177  SendMessage (p, header.GetSource (), Icmpv4Header::DEST_UNREACH, code);
178 }
179 
180 void
182 {
183  NS_LOG_FUNCTION (this << header << *orgData);
184  Ptr<Packet> p = Create<Packet> ();
185  Icmpv4TimeExceeded time;
186  time.SetHeader (header);
187  time.SetData (orgData);
188  p->AddHeader (time);
190 }
191 
192 void
194  Icmpv4Header header,
195  Ipv4Address source,
196  Ipv4Address destination)
197 {
198  NS_LOG_FUNCTION (this << p << header << source << destination);
199 
200  Ptr<Packet> reply = Create<Packet> ();
201  Icmpv4Echo echo;
202  p->RemoveHeader (echo);
203  reply->AddHeader (echo);
204  SendMessage (reply, destination, source, Icmpv4Header::ECHO_REPLY, 0, 0);
205 }
206 void
208  uint32_t info, Ipv4Header ipHeader,
209  const uint8_t payload[8])
210 {
211  NS_LOG_FUNCTION (this << source << icmp << info << ipHeader << payload);
212 
213  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
214  Ptr<IpL4Protocol> l4 = ipv4->GetProtocol (ipHeader.GetProtocol ());
215  if (l4 != 0)
216  {
217  l4->ReceiveIcmp (source, ipHeader.GetTtl (), icmp.GetType (), icmp.GetCode (),
218  info, ipHeader.GetSource (), ipHeader.GetDestination (), payload);
219  }
220 }
221 void
223  Icmpv4Header icmp,
224  Ipv4Address source,
225  Ipv4Address destination)
226 {
227  NS_LOG_FUNCTION (this << p << icmp << source << destination);
228 
230  p->PeekHeader (unreach);
231  uint8_t payload[8];
232  unreach.GetData (payload);
233  Ipv4Header ipHeader = unreach.GetHeader ();
234  Forward (source, icmp, unreach.GetNextHopMtu (), ipHeader, payload);
235 }
236 void
238  Icmpv4Header icmp,
239  Ipv4Address source,
240  Ipv4Address destination)
241 {
242  NS_LOG_FUNCTION (this << p << icmp << source << destination);
243 
244  Icmpv4TimeExceeded time;
245  p->PeekHeader (time);
246  uint8_t payload[8];
247  time.GetData (payload);
248  Ipv4Header ipHeader = time.GetHeader ();
249  // info field is zero for TimeExceeded on linux
250  Forward (source, icmp, 0, ipHeader, payload);
251 }
252 
255  Ipv4Header const &header,
256  Ptr<Ipv4Interface> incomingInterface)
257 {
258  NS_LOG_FUNCTION (this << p << header << incomingInterface);
259 
260  Icmpv4Header icmp;
261  p->RemoveHeader (icmp);
262  switch (icmp.GetType ()) {
263  case Icmpv4Header::ECHO:
264  HandleEcho (p, icmp, header.GetSource (), header.GetDestination ());
265  break;
267  HandleDestUnreach (p, icmp, header.GetSource (), header.GetDestination ());
268  break;
270  HandleTimeExceeded (p, icmp, header.GetSource (), header.GetDestination ());
271  break;
272  default:
273  NS_LOG_DEBUG (icmp << " " << *p);
274  break;
275  }
276  return IpL4Protocol::RX_OK;
277 }
280  Ipv6Header const &header,
281  Ptr<Ipv6Interface> incomingInterface)
282 {
283  NS_LOG_FUNCTION (this << p << header.GetSourceAddress () << header.GetDestinationAddress () << incomingInterface);
285 }
286 void
288 {
289  NS_LOG_FUNCTION (this);
290  m_node = 0;
293 }
294 
295 void
297 {
298  NS_LOG_FUNCTION (this << &callback);
299  m_downTarget = callback;
300 }
301 
302 void
304 {
305  NS_LOG_FUNCTION (this << &callback);
306 }
307 
310 {
311  NS_LOG_FUNCTION (this);
312  return m_downTarget;
313 }
314 
317 {
318  NS_LOG_FUNCTION (this);
320 }
321 
322 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:266
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
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:455
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:1258
#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
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:339
#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:1480
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
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:276
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:1262
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:318
Ipv4Header GetHeader(void) const
Get the ICMP carried IPv4 header.
Definition: icmpv4.cc:330
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:442
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:826
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:255
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.