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 
17 NS_OBJECT_ENSURE_REGISTERED (Icmpv4L4Protocol)
18  ;
19 
20 // see rfc 792
21 const uint8_t Icmpv4L4Protocol::PROT_NUMBER = 1;
22 
23 TypeId
25 {
26  static TypeId tid = TypeId ("ns3::Icmpv4L4Protocol")
28  .AddConstructor<Icmpv4L4Protocol> ()
29  ;
30  return tid;
31 }
32 
34  : m_node (0)
35 {
36  NS_LOG_FUNCTION (this);
37 }
39 {
40  NS_LOG_FUNCTION (this);
41  NS_ASSERT (m_node == 0);
42 }
43 
44 void
46 {
47  NS_LOG_FUNCTION (this << node);
48  m_node = node;
49 }
50 
51 /*
52  * This method is called by AddAgregate and completes the aggregation
53  * by setting the node in the ICMP stack and adding ICMP factory to
54  * IPv4 stack connected to the node
55  */
56 void
58 {
59  NS_LOG_FUNCTION (this);
60  if (m_node == 0)
61  {
62  Ptr<Node> node = this->GetObject<Node> ();
63  if (node != 0)
64  {
65  Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
66  if (ipv4 != 0 && m_downTarget.IsNull ())
67  {
68  this->SetNode (node);
69  ipv4->Insert (this);
70  Ptr<Ipv4RawSocketFactoryImpl> rawFactory = CreateObject<Ipv4RawSocketFactoryImpl> ();
71  ipv4->AggregateObject (rawFactory);
72  this->SetDownTarget (MakeCallback (&Ipv4::Send, ipv4));
73  }
74  }
75  }
77 }
78 
79 uint16_t
81 {
83  return PROT_NUMBER;
84 }
85 
86 int
88 {
89  NS_LOG_FUNCTION (this);
90  return PROT_NUMBER;
91 }
92 void
93 Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address dest, uint8_t type, uint8_t code)
94 {
95  NS_LOG_FUNCTION (this << packet << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code));
96  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
97  NS_ASSERT (ipv4 != 0 && ipv4->GetRoutingProtocol () != 0);
98  Ipv4Header header;
99  header.SetDestination (dest);
100  header.SetProtocol (PROT_NUMBER);
101  Socket::SocketErrno errno_;
102  Ptr<Ipv4Route> route;
103  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
104  route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
105  if (route != 0)
106  {
107  NS_LOG_LOGIC ("Route exists");
108  Ipv4Address source = route->GetSource ();
109  SendMessage (packet, source, dest, type, code, route);
110  }
111  else
112  {
113  NS_LOG_WARN ("drop icmp message");
114  }
115 }
116 
117 void
118 Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address source, Ipv4Address dest, uint8_t type, uint8_t code, Ptr<Ipv4Route> route)
119 {
120  NS_LOG_FUNCTION (this << packet << source << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code) << route);
121  Icmpv4Header icmp;
122  icmp.SetType (type);
123  icmp.SetCode (code);
124  if (Node::ChecksumEnabled ())
125  {
126  icmp.EnableChecksum ();
127  }
128  packet->AddHeader (icmp);
129 
130  m_downTarget (packet, source, dest, PROT_NUMBER, route);
131 }
132 void
134  Ptr<const Packet> orgData,
135  uint16_t nextHopMtu)
136 {
137  NS_LOG_FUNCTION (this << header << *orgData << nextHopMtu);
138  SendDestUnreach (header, orgData, Icmpv4DestinationUnreachable::FRAG_NEEDED, nextHopMtu);
139 }
140 void
142  Ptr<const Packet> orgData)
143 {
144  NS_LOG_FUNCTION (this << header << *orgData);
146 }
147 void
149  uint8_t code, uint16_t nextHopMtu)
150 {
151  NS_LOG_FUNCTION (this << header << *orgData << (uint32_t) code << nextHopMtu);
152  Ptr<Packet> p = Create<Packet> ();
154  unreach.SetNextHopMtu (nextHopMtu);
155  unreach.SetHeader (header);
156  unreach.SetData (orgData);
157  p->AddHeader (unreach);
158  SendMessage (p, header.GetSource (), Icmpv4Header::DEST_UNREACH, code);
159 }
160 
161 void
163 {
164  NS_LOG_FUNCTION (this << header << *orgData);
165  Ptr<Packet> p = Create<Packet> ();
166  Icmpv4TimeExceeded time;
167  time.SetHeader (header);
168  time.SetData (orgData);
169  p->AddHeader (time);
171 }
172 
173 void
175  Icmpv4Header header,
176  Ipv4Address source,
177  Ipv4Address destination)
178 {
179  NS_LOG_FUNCTION (this << p << header << source << destination);
180 
181  Ptr<Packet> reply = Create<Packet> ();
182  Icmpv4Echo echo;
183  p->RemoveHeader (echo);
184  reply->AddHeader (echo);
185  SendMessage (reply, destination, source, Icmpv4Header::ECHO_REPLY, 0, 0);
186 }
187 void
189  uint32_t info, Ipv4Header ipHeader,
190  const uint8_t payload[8])
191 {
192  NS_LOG_FUNCTION (this << source << icmp << info << ipHeader << payload);
193 
194  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
195  Ptr<IpL4Protocol> l4 = ipv4->GetProtocol (ipHeader.GetProtocol ());
196  if (l4 != 0)
197  {
198  l4->ReceiveIcmp (source, ipHeader.GetTtl (), icmp.GetType (), icmp.GetCode (),
199  info, ipHeader.GetSource (), ipHeader.GetDestination (), payload);
200  }
201 }
202 void
204  Icmpv4Header icmp,
205  Ipv4Address source,
206  Ipv4Address destination)
207 {
208  NS_LOG_FUNCTION (this << p << icmp << source << destination);
209 
211  p->PeekHeader (unreach);
212  uint8_t payload[8];
213  unreach.GetData (payload);
214  Ipv4Header ipHeader = unreach.GetHeader ();
215  Forward (source, icmp, unreach.GetNextHopMtu (), ipHeader, payload);
216 }
217 void
219  Icmpv4Header icmp,
220  Ipv4Address source,
221  Ipv4Address destination)
222 {
223  NS_LOG_FUNCTION (this << p << icmp << source << destination);
224 
225  Icmpv4TimeExceeded time;
226  p->PeekHeader (time);
227  uint8_t payload[8];
228  time.GetData (payload);
229  Ipv4Header ipHeader = time.GetHeader ();
230  // info field is zero for TimeExceeded on linux
231  Forward (source, icmp, 0, ipHeader, payload);
232 }
233 
236  Ipv4Header const &header,
237  Ptr<Ipv4Interface> incomingInterface)
238 {
239  NS_LOG_FUNCTION (this << p << header << incomingInterface);
240 
241  Icmpv4Header icmp;
242  p->RemoveHeader (icmp);
243  switch (icmp.GetType ()) {
244  case Icmpv4Header::ECHO:
245  HandleEcho (p, icmp, header.GetSource (), header.GetDestination ());
246  break;
248  HandleDestUnreach (p, icmp, header.GetSource (), header.GetDestination ());
249  break;
251  HandleTimeExceeded (p, icmp, header.GetSource (), header.GetDestination ());
252  break;
253  default:
254  NS_LOG_DEBUG (icmp << " " << *p);
255  break;
256  }
257  return IpL4Protocol::RX_OK;
258 }
261  Ipv6Header const &header,
262  Ptr<Ipv6Interface> incomingInterface)
263 {
264  NS_LOG_FUNCTION (this << p << header.GetSourceAddress () << header.GetDestinationAddress () << incomingInterface);
266 }
267 void
269 {
270  NS_LOG_FUNCTION (this);
271  m_node = 0;
274 }
275 
276 void
278 {
279  NS_LOG_FUNCTION (this << &callback);
280  m_downTarget = callback;
281 }
282 
283 void
285 {
286  NS_LOG_FUNCTION (this << &callback);
287 }
288 
291 {
292  NS_LOG_FUNCTION (this);
293  return m_downTarget;
294 }
295 
298 {
299  NS_LOG_FUNCTION (this);
301 }
302 
303 } // 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
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)
Definition: log.h:345
uint8_t GetCode(void) const
Get ICMP code.
Definition: icmpv4.cc:127
NS_LOG_COMPONENT_DEFINE("GrantedTimeWindowMpiInterface")
Doxygen introspection did not find any typical Config paths.
Definition: icmpv4.h:217
static bool ChecksumEnabled(void)
Definition: node.cc:266
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1014
#define NS_ASSERT(condition)
Definition: assert.h:64
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
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: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:1238
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
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)
This method is invoked whenever two sets of objects are aggregated together.
Definition: object.cc:315
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
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
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)
Definition: log.h:280
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
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:102
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
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:1018
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
Definition: object.h:361
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: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:611
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:112
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.