A Discrete-Event Network Simulator
API
icmpv4.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@sophia.inria.fr>
19  */
20 
21 #include "icmpv4.h"
22 #include "ns3/packet.h"
23 #include "ns3/log.h"
24 
25 namespace ns3 {
26 
27 NS_LOG_COMPONENT_DEFINE ("Icmpv4Header");
28 
29 /********************************************************
30  * Icmpv4Header
31  ********************************************************/
32 
33 NS_OBJECT_ENSURE_REGISTERED (Icmpv4Header);
34 
35 TypeId
37 {
38  static TypeId tid = TypeId ("ns3::Icmpv4Header")
39  .SetParent<Header> ()
40  .SetGroupName ("Internet")
41  .AddConstructor<Icmpv4Header> ()
42  ;
43  return tid;
44 }
46  : m_type (0),
47  m_code (0),
48  m_calcChecksum (false)
49 {
50  NS_LOG_FUNCTION (this);
51 }
53 {
54  NS_LOG_FUNCTION (this);
55 }
56 void
58 {
59  NS_LOG_FUNCTION (this);
60  m_calcChecksum = true;
61 }
62 TypeId
64 {
65  NS_LOG_FUNCTION (this);
66  return GetTypeId ();
67 }
68 uint32_t
70 {
71  NS_LOG_FUNCTION (this);
72  return 4;
73 }
74 void
76 {
77  NS_LOG_FUNCTION (this << &start);
79  i.WriteU8 (m_type);
80  i.WriteU8 (m_code);
81  i.WriteHtonU16 (0);
82  if (m_calcChecksum)
83  {
84  i = start;
85  uint16_t checksum = i.CalculateIpChecksum (i.GetSize ());
86  i = start;
87  i.Next (2);
88  i.WriteU16 (checksum);
89  }
90 
91 }
92 uint32_t
94 {
95  NS_LOG_FUNCTION (this << &start);
96  m_type = start.ReadU8 ();
97  m_code = start.ReadU8 ();
98  start.Next (2); // uint16_t checksum = start.ReadNtohU16 ();
99  return 4;
100 }
101 void
102 Icmpv4Header::Print (std::ostream &os) const
103 {
104  NS_LOG_FUNCTION (this << &os);
105  os << "type=" << (uint32_t)m_type << ", code=" << (uint32_t)m_code;
106 }
107 
108 void
109 Icmpv4Header::SetType (uint8_t type)
110 {
111  NS_LOG_FUNCTION (this << static_cast<uint32_t> (type));
112  m_type = type;
113 }
114 void
115 Icmpv4Header::SetCode (uint8_t code)
116 {
117  NS_LOG_FUNCTION (this << static_cast<uint32_t> (code));
118  m_code = code;
119 }
120 uint8_t
122 {
123  NS_LOG_FUNCTION (this);
124  return m_type;
125 }
126 uint8_t
128 {
129  NS_LOG_FUNCTION (this);
130  return m_code;
131 }
132 
133 /********************************************************
134  * Icmpv4Echo
135  ********************************************************/
136 
138 
139 void
141 {
142  NS_LOG_FUNCTION (this << id);
143  m_identifier = id;
144 }
145 void
147 {
148  NS_LOG_FUNCTION (this << seq);
149  m_sequence = seq;
150 }
151 void
153 {
154  NS_LOG_FUNCTION (this << *data);
155 
156  uint32_t size = data->GetSize ();
157  //
158  // All kinds of optimizations are possible, but let's not get carried away
159  // since this is probably a very uncommon thing in the big picture.
160  //
161  // N.B. Zero is a legal size for the alloc below even though a hardcoded zero
162  // would result in warning.
163  //
164  if (size != m_dataSize)
165  {
166  delete [] m_data;
167  m_data = new uint8_t[size];
168  m_dataSize = size;
169  }
170  data->CopyData (m_data, size);
171 }
172 uint16_t
174 {
175  NS_LOG_FUNCTION (this);
176  return m_identifier;
177 }
178 uint16_t
180 {
181  NS_LOG_FUNCTION (this);
182  return m_sequence;
183 }
184 uint32_t
186 {
187  NS_LOG_FUNCTION (this);
188  return m_dataSize;
189 }
190 uint32_t
191 Icmpv4Echo::GetData (uint8_t payload[]) const
192 {
193  NS_LOG_FUNCTION (this << payload);
194  memcpy (payload, m_data, m_dataSize);
195  return m_dataSize;
196 }
197 TypeId
199 {
200  static TypeId tid = TypeId ("ns3::Icmpv4Echo")
201  .SetParent<Header> ()
202  .SetGroupName ("Internet")
203  .AddConstructor<Icmpv4Echo> ()
204  ;
205  return tid;
206 }
208  : m_identifier (0),
209  m_sequence (0),
210  m_dataSize (0)
211 {
212  NS_LOG_FUNCTION (this);
213  //
214  // After construction, m_data is always valid until destruction. This is true
215  // even if m_dataSize is zero.
216  //
217  m_data = new uint8_t[m_dataSize];
218 }
220 {
221  NS_LOG_FUNCTION (this);
222  delete [] m_data;
223  m_data = 0;
224  m_dataSize = 0;
225 }
226 TypeId
228 {
229  NS_LOG_FUNCTION (this);
230  return GetTypeId ();
231 }
232 uint32_t
234 {
235  NS_LOG_FUNCTION (this);
236  return 4 + m_dataSize;
237 }
238 void
240 {
241  NS_LOG_FUNCTION (this << &start);
242  start.WriteHtonU16 (m_identifier);
243  start.WriteHtonU16 (m_sequence);
244  start.Write (m_data, m_dataSize);
245 }
246 uint32_t
248 {
249  NS_LOG_FUNCTION (this << &start);
250 
251  uint32_t optionalPayloadSize = start.GetRemainingSize () -4;
252  NS_ASSERT (start.GetRemainingSize () >= 4);
253 
254  m_identifier = start.ReadNtohU16 ();
255  m_sequence = start.ReadNtohU16 ();
256  if (optionalPayloadSize != m_dataSize)
257  {
258  delete [] m_data;
259  m_dataSize = optionalPayloadSize;
260  m_data = new uint8_t[m_dataSize];
261  }
262  start.Read (m_data, m_dataSize);
263  return m_dataSize+4;
264 }
265 void
266 Icmpv4Echo::Print (std::ostream &os) const
267 {
268  NS_LOG_FUNCTION (this << &os);
269  os << "identifier=" << m_identifier << ", sequence=" << m_sequence << ", data size=" << m_dataSize;
270 }
271 
272 
273 /********************************************************
274  * Icmpv4DestinationUnreachable
275  ********************************************************/
276 
278 
279 TypeId
281 {
282  static TypeId tid = TypeId ("ns3::Icmpv4DestinationUnreachable")
283  .SetParent<Header> ()
284  .SetGroupName ("Internet")
285  .AddConstructor<Icmpv4DestinationUnreachable> ()
286  ;
287  return tid;
288 }
290 {
291  NS_LOG_FUNCTION (this);
292  // make sure that thing is initialized to get initialized bytes
293  // when the ip payload's size is smaller than 8 bytes.
294  for (uint8_t j = 0; j < 8; j++)
295  {
296  m_data[j] = 0;
297  }
298 }
299 
300 void
302 {
303  NS_LOG_FUNCTION (this << mtu);
304  m_nextHopMtu = mtu;
305 }
306 uint16_t
308 {
309  NS_LOG_FUNCTION (this);
310  return m_nextHopMtu;
311 }
312 
313 void
315 {
316  NS_LOG_FUNCTION (this << *data);
317  data->CopyData (m_data, 8);
318 }
319 void
321 {
322  NS_LOG_FUNCTION (this << header);
323  m_header = header;
324 }
325 void
326 Icmpv4DestinationUnreachable::GetData (uint8_t payload[8]) const
327 {
328  NS_LOG_FUNCTION (this << payload);
329  memcpy (payload, m_data, 8);
330 }
331 Ipv4Header
333 {
334  NS_LOG_FUNCTION (this);
335  return m_header;
336 }
337 
338 
340 {
341 }
342 TypeId
344 {
345  NS_LOG_FUNCTION (this);
346  return GetTypeId ();
347 }
348 uint32_t
350 {
351  NS_LOG_FUNCTION (this);
352  return 4 + m_header.GetSerializedSize () + 8;
353 }
354 void
356 {
357  NS_LOG_FUNCTION (this << &start);
358  start.WriteU16 (0);
359  start.WriteHtonU16 (m_nextHopMtu);
360  uint32_t size = m_header.GetSerializedSize ();
362  start.Next (size);
363  start.Write (m_data, 8);
364 }
365 
366 uint32_t
368 {
369  NS_LOG_FUNCTION (this << &start);
371  i.Next (2);
372  m_nextHopMtu = i.ReadNtohU16 ();
373  uint32_t read = m_header.Deserialize (i);
374  i.Next (read);
375  for (uint8_t j = 0; j < 8; j++)
376  {
377  m_data[j] = i.ReadU8 ();
378  }
379  return i.GetDistanceFrom (start);
380 }
381 void
382 Icmpv4DestinationUnreachable::Print (std::ostream &os) const
383 {
384  NS_LOG_FUNCTION (this << &os);
385  m_header.Print (os);
386  os << " org data=";
387  for (uint8_t i = 0; i < 8; i++)
388  {
389  os << (uint32_t) m_data[i];
390  if (i != 8)
391  {
392  os << " ";
393  }
394  }
395 }
396 
397 /********************************************************
398  * Icmpv4TimeExceeded
399  ********************************************************/
400 
402 
403 TypeId
405 {
406  static TypeId tid = TypeId ("ns3::Icmpv4TimeExceeded")
407  .SetParent<Header> ()
408  .SetGroupName ("Internet")
409  .AddConstructor<Icmpv4TimeExceeded> ()
410  ;
411  return tid;
412 }
414 {
415  NS_LOG_FUNCTION (this);
416  // make sure that thing is initialized to get initialized bytes
417  // when the ip payload's size is smaller than 8 bytes.
418  for (uint8_t j = 0; j < 8; j++)
419  {
420  m_data[j] = 0;
421  }
422 }
423 
424 
425 void
427 {
428  NS_LOG_FUNCTION (this << *data);
429  data->CopyData (m_data, 8);
430 }
431 void
433 {
434  NS_LOG_FUNCTION (this << header);
435  m_header = header;
436 }
437 void
438 Icmpv4TimeExceeded::GetData (uint8_t payload[8]) const
439 {
440  NS_LOG_FUNCTION (this << payload);
441  memcpy (payload, m_data, 8);
442 }
443 Ipv4Header
445 {
446  NS_LOG_FUNCTION (this);
447  return m_header;
448 }
449 
450 
452 {
453  NS_LOG_FUNCTION (this);
454 }
455 TypeId
457 {
458  NS_LOG_FUNCTION (this);
459  return GetTypeId ();
460 }
461 uint32_t
463 {
464  NS_LOG_FUNCTION (this);
465  return 4 + m_header.GetSerializedSize () + 8;
466 }
467 void
469 {
470  NS_LOG_FUNCTION (this << &start);
471  start.WriteU32 (0);
472  uint32_t size = m_header.GetSerializedSize ();
474  start.Next (size);
475  start.Write (m_data, 8);
476 }
477 
478 uint32_t
480 {
481  NS_LOG_FUNCTION (this << &start);
483  i.Next (4);
484  uint32_t read = m_header.Deserialize (i);
485  i.Next (read);
486  for (uint8_t j = 0; j < 8; j++)
487  {
488  m_data[j] = i.ReadU8 ();
489  }
490  return i.GetDistanceFrom (start);
491 }
492 void
493 Icmpv4TimeExceeded::Print (std::ostream &os) const
494 {
495  NS_LOG_FUNCTION (this << &os);
496  m_header.Print (os);
497  os << " org data=";
498  for (uint8_t i = 0; i < 8; i++)
499  {
500  os << (uint32_t) m_data[i];
501  if (i != 8)
502  {
503  os << " ";
504  }
505  }
506 }
507 
508 } // namespace ns3
Protocol header serialization and deserialization.
Definition: header.h:42
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1133
virtual void Print(std::ostream &os) const
Definition: icmpv4.cc:102
void SetType(uint8_t type)
Set ICMP type.
Definition: icmpv4.cc:109
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Ipv4Header GetHeader(void) const
Get the ICMP carried IPv4 header.
Definition: icmpv4.cc:332
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
void SetHeader(Ipv4Header header)
Set the ICMP carried IPv4 header.
Definition: icmpv4.cc:320
uint16_t m_sequence
sequence number
Definition: icmpv4.h:162
uint32_t GetData(uint8_t payload[]) const
Get the Echo data.
Definition: icmpv4.cc:191
uint32_t GetDataSize(void) const
Get the Echo data size.
Definition: icmpv4.cc:185
ICMP Time Exceeded header.
Definition: icmpv4.h:246
void SetData(Ptr< const Packet > data)
Set the ICMP carried data.
Definition: icmpv4.cc:314
def start()
Definition: core.py:1855
static TypeId GetTypeId(void)
Get ICMP type.
Definition: icmpv4.cc:198
virtual void Print(std::ostream &os) const
Definition: icmpv4.cc:493
virtual void Serialize(Buffer::Iterator start) const
Definition: ipv4-header.cc:383
#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
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: icmpv4.cc:479
uint8_t m_code
ICMP code.
Definition: icmpv4.h:98
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
static TypeId GetTypeId(void)
Get the type ID.
Definition: icmpv4.cc:36
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition: icmpv4.cc:326
virtual void Serialize(Buffer::Iterator start) const
Definition: icmpv4.cc:468
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: icmpv4.cc:93
virtual void Print(std::ostream &os) const
Definition: icmpv4.cc:382
virtual ~Icmpv4Header()
Definition: icmpv4.cc:52
Base class for all the ICMP packet headers.
Definition: icmpv4.h:40
iterator in a Buffer instance
Definition: buffer.h:98
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: icmpv4.cc:227
void SetCode(uint8_t code)
Set ICMP code.
Definition: icmpv4.cc:115
uint32_t GetDistanceFrom(Iterator const &o) const
Definition: buffer.cc:783
Packet header for IPv4.
Definition: ipv4-header.h:33
virtual void Print(std::ostream &os) const
Definition: icmpv4.cc:266
uint16_t m_nextHopMtu
next hop MTU
Definition: icmpv4.h:235
virtual uint32_t GetSerializedSize(void) const
Definition: icmpv4.cc:462
uint32_t m_dataSize
data size
Definition: icmpv4.h:164
void EnableChecksum(void)
Enables ICMP Checksum calculation.
Definition: icmpv4.cc:57
virtual uint32_t GetSerializedSize(void) const
Definition: icmpv4.cc:349
virtual void Serialize(Buffer::Iterator start) const
Definition: icmpv4.cc:239
static TypeId GetTypeId(void)
Get ICMP type.
Definition: icmpv4.cc:280
uint8_t data[writeSize]
void WriteU16(uint16_t data)
Definition: buffer.cc:870
uint8_t GetType(void) const
Get ICMP type.
Definition: icmpv4.cc:121
Ipv4Header m_header
carried IPv4 header
Definition: icmpv4.h:294
void WriteHtonU16(uint16_t data)
Definition: buffer.h:905
virtual uint32_t GetSerializedSize(void) const
Definition: ipv4-header.cc:375
void Next(void)
go forward by one byte
Definition: buffer.h:845
uint32_t GetSize(void) const
Definition: buffer.cc:1158
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: icmpv4.cc:343
uint8_t m_data[8]
carried data
Definition: icmpv4.h:295
void SetHeader(Ipv4Header header)
Set the ICMP carried IPv4 header.
Definition: icmpv4.cc:432
virtual uint32_t GetSerializedSize(void) const
Definition: icmpv4.cc:233
void SetData(Ptr< const Packet > data)
Get the ICMP carried data.
Definition: icmpv4.cc:426
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.
Ipv4Header m_header
carried IPv4 header
Definition: icmpv4.h:236
Ipv4Header GetHeader(void) const
Get the ICMP carried IPv4 header.
Definition: icmpv4.cc:444
virtual ~Icmpv4Echo()
Definition: icmpv4.cc:219
virtual void Serialize(Buffer::Iterator start) const
Definition: icmpv4.cc:355
ICMP Echo header.
Definition: icmpv4.h:107
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: icmpv4.cc:456
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: icmpv4.cc:367
virtual uint32_t GetSerializedSize(void) const
Definition: icmpv4.cc:69
void SetData(Ptr< const Packet > data)
Set the Echo data.
Definition: icmpv4.cc:152
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: icmpv4.cc:63
uint16_t GetSequenceNumber(void) const
Get the Echo sequence number.
Definition: icmpv4.cc:179
uint16_t GetNextHopMtu(void) const
Get the next hop MTU.
Definition: icmpv4.cc:307
virtual ~Icmpv4TimeExceeded()
Definition: icmpv4.cc:451
void WriteU8(uint8_t data)
Definition: buffer.h:869
uint16_t m_identifier
identifier
Definition: icmpv4.h:161
virtual void Serialize(Buffer::Iterator start) const
Definition: icmpv4.cc:75
uint16_t GetIdentifier(void) const
Get the Echo identifier.
Definition: icmpv4.cc:173
ICMP Destination Unreachable header.
Definition: icmpv4.h:172
void SetSequenceNumber(uint16_t seq)
Set the Echo sequence number.
Definition: icmpv4.cc:146
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition: icmpv4.cc:438
uint8_t ReadU8(void)
Definition: buffer.h:1021
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: icmpv4.cc:247
static TypeId GetTypeId(void)
Get ICMP type.
Definition: icmpv4.cc:404
uint16_t ReadNtohU16(void)
Definition: buffer.h:946
uint8_t m_data[8]
carried data
Definition: icmpv4.h:237
uint8_t GetCode(void) const
Get ICMP code.
Definition: icmpv4.cc:127
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
void SetIdentifier(uint16_t id)
Set the Echo identifier.
Definition: icmpv4.cc:140
bool m_calcChecksum
true if checksum is calculated
Definition: icmpv4.h:99
uint8_t * m_data
data
Definition: icmpv4.h:163
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: ipv4-header.cc:423
virtual void Print(std::ostream &os) const
Definition: ipv4-header.cc:335
uint8_t m_type
ICMP type.
Definition: icmpv4.h:97