A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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: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 "...
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: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:201
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:340
#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
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:1489
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:278
void SetNextHopMtu(uint16_t mtu)
Set the next hop MTU.
Definition: icmpv4.cc:299
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:100
#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: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:319
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:827
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:257
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.