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 #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  .AddConstructor<Icmpv4L4Protocol> ()
27  ;
28  return tid;
29 }
30 
32  : m_node (0)
33 {
34  NS_LOG_FUNCTION (this);
35 }
37 {
38  NS_LOG_FUNCTION (this);
39  NS_ASSERT (m_node == 0);
40 }
41 
42 void
44 {
45  NS_LOG_FUNCTION (this << node);
46  m_node = node;
47 }
48 
49 /*
50  * This method is called by AddAgregate and completes the aggregation
51  * by setting the node in the ICMP stack and adding ICMP factory to
52  * IPv4 stack connected to the node
53  */
54 void
56 {
57  NS_LOG_FUNCTION (this);
58  if (m_node == 0)
59  {
60  Ptr<Node> node = this->GetObject<Node> ();
61  if (node != 0)
62  {
63  Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
64  if (ipv4 != 0 && m_downTarget.IsNull ())
65  {
66  this->SetNode (node);
67  ipv4->Insert (this);
68  Ptr<Ipv4RawSocketFactoryImpl> rawFactory = CreateObject<Ipv4RawSocketFactoryImpl> ();
69  ipv4->AggregateObject (rawFactory);
70  this->SetDownTarget (MakeCallback (&Ipv4::Send, ipv4));
71  }
72  }
73  }
75 }
76 
77 uint16_t
79 {
81  return PROT_NUMBER;
82 }
83 
84 int
86 {
87  NS_LOG_FUNCTION (this);
88  return PROT_NUMBER;
89 }
90 void
91 Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address dest, uint8_t type, uint8_t code)
92 {
93  NS_LOG_FUNCTION (this << packet << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code));
94  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
95  NS_ASSERT (ipv4 != 0 && ipv4->GetRoutingProtocol () != 0);
96  Ipv4Header header;
97  header.SetDestination (dest);
98  header.SetProtocol (PROT_NUMBER);
99  Socket::SocketErrno errno_;
100  Ptr<Ipv4Route> route;
101  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
102  route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
103  if (route != 0)
104  {
105  NS_LOG_LOGIC ("Route exists");
106  Ipv4Address source = route->GetSource ();
107  SendMessage (packet, source, dest, type, code, route);
108  }
109  else
110  {
111  NS_LOG_WARN ("drop icmp message");
112  }
113 }
114 
115 void
116 Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address source, Ipv4Address dest, uint8_t type, uint8_t code, Ptr<Ipv4Route> route)
117 {
118  NS_LOG_FUNCTION (this << packet << source << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code) << route);
119  Icmpv4Header icmp;
120  icmp.SetType (type);
121  icmp.SetCode (code);
122  if (Node::ChecksumEnabled ())
123  {
124  icmp.EnableChecksum ();
125  }
126  packet->AddHeader (icmp);
127 
128  m_downTarget (packet, source, dest, PROT_NUMBER, route);
129 }
130 void
132  Ptr<const Packet> orgData,
133  uint16_t nextHopMtu)
134 {
135  NS_LOG_FUNCTION (this << header << *orgData << nextHopMtu);
136  SendDestUnreach (header, orgData, Icmpv4DestinationUnreachable::FRAG_NEEDED, nextHopMtu);
137 }
138 void
140  Ptr<const Packet> orgData)
141 {
142  NS_LOG_FUNCTION (this << header << *orgData);
144 }
145 void
147  uint8_t code, uint16_t nextHopMtu)
148 {
149  NS_LOG_FUNCTION (this << header << *orgData << (uint32_t) code << nextHopMtu);
150  Ptr<Packet> p = Create<Packet> ();
152  unreach.SetNextHopMtu (nextHopMtu);
153  unreach.SetHeader (header);
154  unreach.SetData (orgData);
155  p->AddHeader (unreach);
156  SendMessage (p, header.GetSource (), Icmpv4Header::DEST_UNREACH, code);
157 }
158 
159 void
161 {
162  NS_LOG_FUNCTION (this << header << *orgData);
163  Ptr<Packet> p = Create<Packet> ();
164  Icmpv4TimeExceeded time;
165  time.SetHeader (header);
166  time.SetData (orgData);
167  p->AddHeader (time);
169 }
170 
171 void
173  Icmpv4Header header,
174  Ipv4Address source,
175  Ipv4Address destination)
176 {
177  NS_LOG_FUNCTION (this << p << header << source << destination);
178 
179  Ptr<Packet> reply = Create<Packet> ();
180  Icmpv4Echo echo;
181  p->RemoveHeader (echo);
182  reply->AddHeader (echo);
183  SendMessage (reply, destination, source, Icmpv4Header::ECHO_REPLY, 0, 0);
184 }
185 void
187  uint32_t info, Ipv4Header ipHeader,
188  const uint8_t payload[8])
189 {
190  NS_LOG_FUNCTION (this << source << icmp << info << ipHeader << payload);
191 
192  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
193  Ptr<IpL4Protocol> l4 = ipv4->GetProtocol (ipHeader.GetProtocol ());
194  if (l4 != 0)
195  {
196  l4->ReceiveIcmp (source, ipHeader.GetTtl (), icmp.GetType (), icmp.GetCode (),
197  info, ipHeader.GetSource (), ipHeader.GetDestination (), payload);
198  }
199 }
200 void
202  Icmpv4Header icmp,
203  Ipv4Address source,
204  Ipv4Address destination)
205 {
206  NS_LOG_FUNCTION (this << p << icmp << source << destination);
207 
209  p->PeekHeader (unreach);
210  uint8_t payload[8];
211  unreach.GetData (payload);
212  Ipv4Header ipHeader = unreach.GetHeader ();
213  Forward (source, icmp, unreach.GetNextHopMtu (), ipHeader, payload);
214 }
215 void
217  Icmpv4Header icmp,
218  Ipv4Address source,
219  Ipv4Address destination)
220 {
221  NS_LOG_FUNCTION (this << p << icmp << source << destination);
222 
223  Icmpv4TimeExceeded time;
224  p->PeekHeader (time);
225  uint8_t payload[8];
226  time.GetData (payload);
227  Ipv4Header ipHeader = time.GetHeader ();
228  // info field is zero for TimeExceeded on linux
229  Forward (source, icmp, 0, ipHeader, payload);
230 }
231 
234  Ipv4Header const &header,
235  Ptr<Ipv4Interface> incomingInterface)
236 {
237  NS_LOG_FUNCTION (this << p << header << incomingInterface);
238 
239  Icmpv4Header icmp;
240  p->RemoveHeader (icmp);
241  switch (icmp.GetType ()) {
242  case Icmpv4Header::ECHO:
243  HandleEcho (p, icmp, header.GetSource (), header.GetDestination ());
244  break;
246  HandleDestUnreach (p, icmp, header.GetSource (), header.GetDestination ());
247  break;
249  HandleTimeExceeded (p, icmp, header.GetSource (), header.GetDestination ());
250  break;
251  default:
252  NS_LOG_DEBUG (icmp << " " << *p);
253  break;
254  }
255  return IpL4Protocol::RX_OK;
256 }
259  Ipv6Header const &header,
260  Ptr<Ipv6Interface> incomingInterface)
261 {
262  NS_LOG_FUNCTION (this << p << header.GetSourceAddress () << header.GetDestinationAddress () << incomingInterface);
264 }
265 void
267 {
268  NS_LOG_FUNCTION (this);
269  m_node = 0;
272 }
273 
274 void
276 {
277  NS_LOG_FUNCTION (this << &callback);
278  m_downTarget = callback;
279 }
280 
281 void
283 {
284  NS_LOG_FUNCTION (this << &callback);
285 }
286 
289 {
290  NS_LOG_FUNCTION (this);
291  return m_downTarget;
292 }
293 
296 {
297  NS_LOG_FUNCTION (this);
299 }
300 
301 } // 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:108
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition: icmpv4.cc:321
Doxygen 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:126
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
Doxygen introspection did not find any typical Config paths.
Definition: icmpv4.h:217
static bool ChecksumEnabled(void)
Definition: node.cc:268
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1018
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
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:170
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:335
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
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
Doxygen 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:302
void SetCode(uint8_t code)
Set ICMP code.
Definition: icmpv4.cc:114
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:56
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1242
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:233
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:426
virtual void NotifyNewAggregate(void)
This method is invoked whenever two sets of objects are aggregated together.
Definition: object.cc:314
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:296
virtual int GetProtocolNumber(void) const
Get the protocol number.
Doxygen 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()
This method is invoked whenever two sets of objects are aggregated together.
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:38
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:203
static uint16_t GetStaticProtocolNumber(void)
Get the protocol number.
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition: icmpv4.cc:432
Doxygen 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:213
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:120
void Nullify(void)
Discard the implementation, set it to null.
Definition: callback.h:1022
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:327
Ptr< T > GetObject(void) const
Definition: object.h:362
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:49
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:438
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:610
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.