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