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 
36 TypeId
38 {
39  static TypeId tid = TypeId ("ns3::Icmpv4Header")
40  .SetParent<Header> ()
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 
140 void
142 {
143  NS_LOG_FUNCTION (this << id);
144  m_identifier = id;
145 }
146 void
148 {
149  NS_LOG_FUNCTION (this << seq);
150  m_sequence = seq;
151 }
152 void
154 {
155  NS_LOG_FUNCTION (this << *data);
156 
157  uint32_t size = data->GetSize ();
158  //
159  // All kinds of optimizations are possible, but let's not get carried away
160  // since this is probably a very uncommon thing in the big picture.
161  //
162  // N.B. Zero is a legal size for the alloc below even though a hardcoded zero
163  // would result in warning.
164  //
165  if (size != m_dataSize)
166  {
167  delete [] m_data;
168  m_data = new uint8_t[size];
169  m_dataSize = size;
170  }
171  data->CopyData (m_data, size);
172 }
173 uint16_t
175 {
176  NS_LOG_FUNCTION (this);
177  return m_identifier;
178 }
179 uint16_t
181 {
182  NS_LOG_FUNCTION (this);
183  return m_sequence;
184 }
185 uint32_t
187 {
188  NS_LOG_FUNCTION (this);
189  return m_dataSize;
190 }
191 uint32_t
192 Icmpv4Echo::GetData (uint8_t payload[]) const
193 {
194  NS_LOG_FUNCTION (this << payload);
195  memcpy (payload, m_data, m_dataSize);
196  return m_dataSize;
197 }
198 TypeId
200 {
201  static TypeId tid = TypeId ("ns3::Icmpv4Echo")
202  .SetParent<Header> ()
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  m_identifier = start.ReadNtohU16 ();
251  m_sequence = start.ReadNtohU16 ();
252  NS_ASSERT (start.GetSize () >= 4);
253  uint32_t size = start.GetSize () - 4;
254  if (size != m_dataSize)
255  {
256  delete [] m_data;
257  m_data = new uint8_t[size];
258  m_dataSize = size;
259  }
260  start.Read (m_data, m_dataSize);
261  return m_dataSize;
262 }
263 void
264 Icmpv4Echo::Print (std::ostream &os) const
265 {
266  NS_LOG_FUNCTION (this << &os);
267  os << "identifier=" << m_identifier << ", sequence=" << m_sequence;
268 }
269 
270 
271 /********************************************************
272  * Icmpv4DestinationUnreachable
273  ********************************************************/
274 
276  ;
277 
278 TypeId
280 {
281  static TypeId tid = TypeId ("ns3::Icmpv4DestinationUnreachable")
282  .SetParent<Header> ()
283  .AddConstructor<Icmpv4DestinationUnreachable> ()
284  ;
285  return tid;
286 }
288 {
289  NS_LOG_FUNCTION (this);
290  // make sure that thing is initialized to get initialized bytes
291  // when the ip payload's size is smaller than 8 bytes.
292  for (uint8_t j = 0; j < 8; j++)
293  {
294  m_data[j] = 0;
295  }
296 }
297 
298 void
300 {
301  NS_LOG_FUNCTION (this << mtu);
302  m_nextHopMtu = mtu;
303 }
304 uint16_t
306 {
307  NS_LOG_FUNCTION (this);
308  return m_nextHopMtu;
309 }
310 
311 void
313 {
314  NS_LOG_FUNCTION (this << *data);
315  data->CopyData (m_data, 8);
316 }
317 void
319 {
320  NS_LOG_FUNCTION (this << header);
321  m_header = header;
322 }
323 void
324 Icmpv4DestinationUnreachable::GetData (uint8_t payload[8]) const
325 {
326  NS_LOG_FUNCTION (this << payload);
327  memcpy (payload, m_data, 8);
328 }
329 Ipv4Header
331 {
332  NS_LOG_FUNCTION (this);
333  return m_header;
334 }
335 
336 
338 {
339 }
340 TypeId
342 {
343  NS_LOG_FUNCTION (this);
344  return GetTypeId ();
345 }
346 uint32_t
348 {
349  NS_LOG_FUNCTION (this);
350  return 4 + m_header.GetSerializedSize () + 8;
351 }
352 void
354 {
355  NS_LOG_FUNCTION (this << &start);
356  start.WriteU16 (0);
357  start.WriteHtonU16 (m_nextHopMtu);
358  uint32_t size = m_header.GetSerializedSize ();
359  m_header.Serialize (start);
360  start.Next (size);
361  start.Write (m_data, 8);
362 }
363 
364 uint32_t
366 {
367  NS_LOG_FUNCTION (this << &start);
369  i.Next (2);
370  m_nextHopMtu = i.ReadNtohU16 ();
371  uint32_t read = m_header.Deserialize (i);
372  i.Next (read);
373  for (uint8_t j = 0; j < 8; j++)
374  {
375  m_data[j] = i.ReadU8 ();
376  }
377  return i.GetDistanceFrom (start);
378 }
379 void
380 Icmpv4DestinationUnreachable::Print (std::ostream &os) const
381 {
382  NS_LOG_FUNCTION (this << &os);
383  m_header.Print (os);
384  os << " org data=";
385  for (uint8_t i = 0; i < 8; i++)
386  {
387  os << (uint32_t) m_data[i];
388  if (i != 8)
389  {
390  os << " ";
391  }
392  }
393 }
394 
395 /********************************************************
396  * Icmpv4TimeExceeded
397  ********************************************************/
398 
400  ;
401 
402 TypeId
404 {
405  static TypeId tid = TypeId ("ns3::Icmpv4TimeExceeded")
406  .SetParent<Header> ()
407  .AddConstructor<Icmpv4TimeExceeded> ()
408  ;
409  return tid;
410 }
412 {
413  NS_LOG_FUNCTION (this);
414  // make sure that thing is initialized to get initialized bytes
415  // when the ip payload's size is smaller than 8 bytes.
416  for (uint8_t j = 0; j < 8; j++)
417  {
418  m_data[j] = 0;
419  }
420 }
421 
422 
423 void
425 {
426  NS_LOG_FUNCTION (this << *data);
427  data->CopyData (m_data, 8);
428 }
429 void
431 {
432  NS_LOG_FUNCTION (this << header);
433  m_header = header;
434 }
435 void
436 Icmpv4TimeExceeded::GetData (uint8_t payload[8]) const
437 {
438  NS_LOG_FUNCTION (this << payload);
439  memcpy (payload, m_data, 8);
440 }
441 Ipv4Header
443 {
444  NS_LOG_FUNCTION (this);
445  return m_header;
446 }
447 
448 
450 {
451  NS_LOG_FUNCTION (this);
452 }
453 TypeId
455 {
456  NS_LOG_FUNCTION (this);
457  return GetTypeId ();
458 }
459 uint32_t
461 {
462  NS_LOG_FUNCTION (this);
463  return 4 + m_header.GetSerializedSize () + 8;
464 }
465 void
467 {
468  NS_LOG_FUNCTION (this << &start);
469  start.WriteU32 (0);
470  uint32_t size = m_header.GetSerializedSize ();
471  m_header.Serialize (start);
472  start.Next (size);
473  start.Write (m_data, 8);
474 }
475 
476 uint32_t
478 {
479  NS_LOG_FUNCTION (this << &start);
481  i.Next (4);
482  uint32_t read = m_header.Deserialize (i);
483  i.Next (read);
484  for (uint8_t j = 0; j < 8; j++)
485  {
486  m_data[j] = i.ReadU8 ();
487  }
488  return i.GetDistanceFrom (start);
489 }
490 void
491 Icmpv4TimeExceeded::Print (std::ostream &os) const
492 {
493  NS_LOG_FUNCTION (this << &os);
494  m_header.Print (os);
495  os << " org data=";
496  for (uint8_t i = 0; i < 8; i++)
497  {
498  os << (uint32_t) m_data[i];
499  if (i != 8)
500  {
501  os << " ";
502  }
503  }
504 }
505 
506 } // namespace ns3
Protocol header serialization and deserialization.
Definition: header.h:42
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1158
virtual void Print(std::ostream &os) const
Definition: icmpv4.cc:264
virtual TypeId GetInstanceTypeId(void) const
Definition: icmpv4.cc:341
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
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
uint8_t GetCode(void) const
Get ICMP code.
Definition: icmpv4.cc:127
virtual TypeId GetInstanceTypeId(void) const
Definition: icmpv4.cc:227
void SetHeader(Ipv4Header header)
Set the ICMP carried IPv4 header.
Definition: icmpv4.cc:318
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:312
virtual uint32_t GetSerializedSize(void) const
Definition: icmpv4.cc:460
uint32_t GetDataSize(void) const
Get the Echo data size.
Definition: icmpv4.cc:186
static TypeId GetTypeId(void)
Get ICMP type.
Definition: icmpv4.cc:199
#define NS_ASSERT(condition)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: icmpv4.cc:477
uint8_t m_code
ICMP code.
Definition: icmpv4.h:87
static TypeId GetTypeId(void)
Get the type ID.
Definition: icmpv4.cc:37
uint32_t GetSize(void) const
Definition: packet.h:650
virtual void Print(std::ostream &os) const
Definition: icmpv4.cc:491
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: icmpv4.cc:93
virtual void Serialize(Buffer::Iterator start) const
Definition: icmpv4.cc:466
virtual ~Icmpv4Header()
Definition: icmpv4.cc:52
uint16_t GetIdentifier(void) const
Get the Echo identifier.
Definition: icmpv4.cc:174
virtual void Print(std::ostream &os) const
Definition: icmpv4.cc:102
uint32_t GetDistanceFrom(Iterator const &o) const
Definition: buffer.cc:807
iterator in a Buffer instance
Definition: buffer.h:98
uint16_t GetNextHopMtu(void) const
Get the next hop MTU.
Definition: icmpv4.cc:305
virtual void Serialize(Buffer::Iterator start) const
Definition: icmpv4.cc:239
void SetCode(uint8_t code)
Set ICMP code.
Definition: icmpv4.cc:115
virtual uint32_t GetSerializedSize(void) const
Definition: icmpv4.cc:69
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
NS_LOG_COMPONENT_DEFINE("Icmpv4Header")
void EnableChecksum(void)
Enables ICMP Checksum calculation.
Definition: icmpv4.cc:57
static TypeId GetTypeId(void)
Get ICMP type.
Definition: icmpv4.cc:279
uint8_t data[writeSize]
void WriteU16(uint16_t data)
Definition: buffer.cc:895
Ipv4Header m_header
carried IPv4 header
Definition: icmpv4.h:261
void WriteHtonU16(uint16_t data)
Definition: buffer.h:726
virtual uint32_t GetSerializedSize(void) const
Definition: icmpv4.cc:233
void Next(void)
go forward by one byte
Definition: buffer.h:666
uint8_t m_data[8]
carried data
Definition: icmpv4.h:262
void SetHeader(Ipv4Header header)
Set the ICMP carried IPv4 header.
Definition: icmpv4.cc:430
void SetData(Ptr< const Packet > data)
Get the ICMP carried data.
Definition: icmpv4.cc:424
void SetNextHopMtu(uint16_t mtu)
Set the next hop MTU.
Definition: icmpv4.cc:299
virtual TypeId GetInstanceTypeId(void) const
Definition: icmpv4.cc:63
Ipv4Header m_header
carried IPv4 header
Definition: icmpv4.h:212
virtual ~Icmpv4Echo()
Definition: icmpv4.cc:219
Doxygen introspection did not find any typical Config paths.
Definition: icmpv4.h:91
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1148
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:192
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: icmpv4.cc:365
void SetData(Ptr< const Packet > data)
Set the Echo data.
Definition: icmpv4.cc:153
virtual ~Icmpv4TimeExceeded()
Definition: icmpv4.cc:449
virtual uint32_t GetSerializedSize(void) const
Definition: icmpv4.cc:347
void WriteU8(uint8_t data)
Definition: buffer.h:690
uint16_t m_identifier
identifier
Definition: icmpv4.h:145
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
void SetSequenceNumber(uint16_t seq)
Set the Echo sequence number.
Definition: icmpv4.cc:147
uint8_t GetType(void) const
Get ICMP type.
Definition: icmpv4.cc:121
virtual TypeId GetInstanceTypeId(void) const
Definition: icmpv4.cc:454
uint8_t ReadU8(void)
Definition: buffer.h:819
virtual void Serialize(Buffer::Iterator start) const
Definition: ipv4-header.cc:382
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:978
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: icmpv4.cc:247
uint16_t GetSequenceNumber(void) const
Get the Echo sequence number.
Definition: icmpv4.cc:180
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:330
static TypeId GetTypeId(void)
Get ICMP type.
Definition: icmpv4.cc:403
uint16_t ReadNtohU16(void)
Definition: buffer.h:767
uint8_t m_data[8]
carried data
Definition: icmpv4.h:213
void WriteU32(uint32_t data)
Definition: buffer.cc:903
virtual void Serialize(Buffer::Iterator start) const
Definition: icmpv4.cc:75
virtual void Print(std::ostream &os) const
Definition: icmpv4.cc:380
virtual uint32_t GetSerializedSize(void) const
Definition: ipv4-header.cc:374
uint32_t GetSize(void) const
Definition: buffer.cc:1183
a unique identifier for an interface.
Definition: type-id.h:49
Ipv4Header GetHeader(void) const
Get the ICMP carried IPv4 header.
Definition: icmpv4.cc:442
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
void SetIdentifier(uint16_t id)
Set the Echo identifier.
Definition: icmpv4.cc:141
bool m_calcChecksum
true if checksum is calculated
Definition: icmpv4.h:88
virtual void Serialize(Buffer::Iterator start) const
Definition: icmpv4.cc:353
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