A Discrete-Event Network Simulator
API
icmpv4.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 
20 #include "icmpv4.h"
21 
22 #include "ns3/log.h"
23 #include "ns3/packet.h"
24 
25 namespace ns3
26 {
27 
28 NS_LOG_COMPONENT_DEFINE("Icmpv4Header");
29 
30 /********************************************************
31  * Icmpv4Header
32  ********************************************************/
33 
34 NS_OBJECT_ENSURE_REGISTERED(Icmpv4Header);
35 
36 TypeId
38 {
39  static TypeId tid = TypeId("ns3::Icmpv4Header")
40  .SetParent<Header>()
41  .SetGroupName("Internet")
42  .AddConstructor<Icmpv4Header>();
43  return tid;
44 }
45 
47  : m_type(0),
48  m_code(0),
49  m_calcChecksum(false)
50 {
51  NS_LOG_FUNCTION(this);
52 }
53 
55 {
56  NS_LOG_FUNCTION(this);
57 }
58 
59 void
61 {
62  NS_LOG_FUNCTION(this);
63  m_calcChecksum = true;
64 }
65 
66 TypeId
68 {
69  NS_LOG_FUNCTION(this);
70  return GetTypeId();
71 }
72 
73 uint32_t
75 {
76  NS_LOG_FUNCTION(this);
77  return 4;
78 }
79 
80 void
82 {
83  NS_LOG_FUNCTION(this << &start);
85  i.WriteU8(m_type);
86  i.WriteU8(m_code);
87  i.WriteHtonU16(0);
88  if (m_calcChecksum)
89  {
90  i = start;
91  uint16_t checksum = i.CalculateIpChecksum(i.GetSize());
92  i = start;
93  i.Next(2);
94  i.WriteU16(checksum);
95  }
96 }
97 
98 uint32_t
100 {
101  NS_LOG_FUNCTION(this << &start);
102  m_type = start.ReadU8();
103  m_code = start.ReadU8();
104  start.Next(2); // uint16_t checksum = start.ReadNtohU16 ();
105  return 4;
106 }
107 
108 void
109 Icmpv4Header::Print(std::ostream& os) const
110 {
111  NS_LOG_FUNCTION(this << &os);
112  os << "type=" << (uint32_t)m_type << ", code=" << (uint32_t)m_code;
113 }
114 
115 void
117 {
118  NS_LOG_FUNCTION(this << static_cast<uint32_t>(type));
119  m_type = type;
120 }
121 
122 void
124 {
125  NS_LOG_FUNCTION(this << static_cast<uint32_t>(code));
126  m_code = code;
127 }
128 
129 uint8_t
131 {
132  NS_LOG_FUNCTION(this);
133  return m_type;
134 }
135 
136 uint8_t
138 {
139  NS_LOG_FUNCTION(this);
140  return m_code;
141 }
142 
143 /********************************************************
144  * Icmpv4Echo
145  ********************************************************/
146 
148 
149 void
151 {
152  NS_LOG_FUNCTION(this << id);
153  m_identifier = id;
154 }
155 
156 void
158 {
159  NS_LOG_FUNCTION(this << seq);
160  m_sequence = seq;
161 }
162 
163 void
165 {
166  NS_LOG_FUNCTION(this << *data);
167 
168  uint32_t size = data->GetSize();
169  //
170  // All kinds of optimizations are possible, but let's not get carried away
171  // since this is probably a very uncommon thing in the big picture.
172  //
173  // N.B. Zero is a legal size for the alloc below even though a hardcoded zero
174  // would result in warning.
175  //
176  if (size != m_dataSize)
177  {
178  delete[] m_data;
179  m_data = new uint8_t[size];
180  m_dataSize = size;
181  }
182  data->CopyData(m_data, size);
183 }
184 
185 uint16_t
187 {
188  NS_LOG_FUNCTION(this);
189  return m_identifier;
190 }
191 
192 uint16_t
194 {
195  NS_LOG_FUNCTION(this);
196  return m_sequence;
197 }
198 
199 uint32_t
201 {
202  NS_LOG_FUNCTION(this);
203  return m_dataSize;
204 }
205 
206 uint32_t
207 Icmpv4Echo::GetData(uint8_t payload[]) const
208 {
209  NS_LOG_FUNCTION(this << payload);
210  memcpy(payload, m_data, m_dataSize);
211  return m_dataSize;
212 }
213 
214 TypeId
216 {
217  static TypeId tid = TypeId("ns3::Icmpv4Echo")
218  .SetParent<Header>()
219  .SetGroupName("Internet")
220  .AddConstructor<Icmpv4Echo>();
221  return tid;
222 }
223 
225  : m_identifier(0),
226  m_sequence(0),
227  m_dataSize(0)
228 {
229  NS_LOG_FUNCTION(this);
230  //
231  // After construction, m_data is always valid until destruction. This is true
232  // even if m_dataSize is zero.
233  //
234  m_data = new uint8_t[m_dataSize];
235 }
236 
238 {
239  NS_LOG_FUNCTION(this);
240  delete[] m_data;
241  m_data = nullptr;
242  m_dataSize = 0;
243 }
244 
245 TypeId
247 {
248  NS_LOG_FUNCTION(this);
249  return GetTypeId();
250 }
251 
252 uint32_t
254 {
255  NS_LOG_FUNCTION(this);
256  return 4 + m_dataSize;
257 }
258 
259 void
261 {
262  NS_LOG_FUNCTION(this << &start);
263  start.WriteHtonU16(m_identifier);
264  start.WriteHtonU16(m_sequence);
265  start.Write(m_data, m_dataSize);
266 }
267 
268 uint32_t
270 {
271  NS_LOG_FUNCTION(this << &start);
272 
273  uint32_t optionalPayloadSize = start.GetRemainingSize() - 4;
274  NS_ASSERT(start.GetRemainingSize() >= 4);
275 
276  m_identifier = start.ReadNtohU16();
277  m_sequence = start.ReadNtohU16();
278  if (optionalPayloadSize != m_dataSize)
279  {
280  delete[] m_data;
281  m_dataSize = optionalPayloadSize;
282  m_data = new uint8_t[m_dataSize];
283  }
284  start.Read(m_data, m_dataSize);
285  return m_dataSize + 4;
286 }
287 
288 void
289 Icmpv4Echo::Print(std::ostream& os) const
290 {
291  NS_LOG_FUNCTION(this << &os);
292  os << "identifier=" << m_identifier << ", sequence=" << m_sequence
293  << ", data size=" << m_dataSize;
294 }
295 
296 /********************************************************
297  * Icmpv4DestinationUnreachable
298  ********************************************************/
299 
301 
302 TypeId
304 {
305  static TypeId tid = TypeId("ns3::Icmpv4DestinationUnreachable")
306  .SetParent<Header>()
307  .SetGroupName("Internet")
308  .AddConstructor<Icmpv4DestinationUnreachable>();
309  return tid;
310 }
311 
313 {
314  NS_LOG_FUNCTION(this);
315  // make sure that thing is initialized to get initialized bytes
316  // when the ip payload's size is smaller than 8 bytes.
317  for (uint8_t j = 0; j < 8; j++)
318  {
319  m_data[j] = 0;
320  }
321 }
322 
323 void
325 {
326  NS_LOG_FUNCTION(this << mtu);
327  m_nextHopMtu = mtu;
328 }
329 
330 uint16_t
332 {
333  NS_LOG_FUNCTION(this);
334  return m_nextHopMtu;
335 }
336 
337 void
339 {
340  NS_LOG_FUNCTION(this << *data);
341  data->CopyData(m_data, 8);
342 }
343 
344 void
346 {
347  NS_LOG_FUNCTION(this << header);
348  m_header = header;
349 }
350 
351 void
352 Icmpv4DestinationUnreachable::GetData(uint8_t payload[8]) const
353 {
354  NS_LOG_FUNCTION(this << payload);
355  memcpy(payload, m_data, 8);
356 }
357 
360 {
361  NS_LOG_FUNCTION(this);
362  return m_header;
363 }
364 
366 {
367 }
368 
369 TypeId
371 {
372  NS_LOG_FUNCTION(this);
373  return GetTypeId();
374 }
375 
376 uint32_t
378 {
379  NS_LOG_FUNCTION(this);
380  return 4 + m_header.GetSerializedSize() + 8;
381 }
382 
383 void
385 {
386  NS_LOG_FUNCTION(this << &start);
387  start.WriteU16(0);
388  start.WriteHtonU16(m_nextHopMtu);
389  uint32_t size = m_header.GetSerializedSize();
391  start.Next(size);
392  start.Write(m_data, 8);
393 }
394 
395 uint32_t
397 {
398  NS_LOG_FUNCTION(this << &start);
400  i.Next(2);
402  uint32_t read = m_header.Deserialize(i);
403  i.Next(read);
404  for (uint8_t j = 0; j < 8; j++)
405  {
406  m_data[j] = i.ReadU8();
407  }
408  return i.GetDistanceFrom(start);
409 }
410 
411 void
412 Icmpv4DestinationUnreachable::Print(std::ostream& os) const
413 {
414  NS_LOG_FUNCTION(this << &os);
415  m_header.Print(os);
416  os << " org data=";
417  for (uint8_t i = 0; i < 8; i++)
418  {
419  os << (uint32_t)m_data[i];
420  if (i != 8)
421  {
422  os << " ";
423  }
424  }
425 }
426 
427 /********************************************************
428  * Icmpv4TimeExceeded
429  ********************************************************/
430 
432 
433 TypeId
435 {
436  static TypeId tid = TypeId("ns3::Icmpv4TimeExceeded")
437  .SetParent<Header>()
438  .SetGroupName("Internet")
439  .AddConstructor<Icmpv4TimeExceeded>();
440  return tid;
441 }
442 
444 {
445  NS_LOG_FUNCTION(this);
446  // make sure that thing is initialized to get initialized bytes
447  // when the ip payload's size is smaller than 8 bytes.
448  for (uint8_t j = 0; j < 8; j++)
449  {
450  m_data[j] = 0;
451  }
452 }
453 
454 void
456 {
457  NS_LOG_FUNCTION(this << *data);
458  data->CopyData(m_data, 8);
459 }
460 
461 void
463 {
464  NS_LOG_FUNCTION(this << header);
465  m_header = header;
466 }
467 
468 void
469 Icmpv4TimeExceeded::GetData(uint8_t payload[8]) const
470 {
471  NS_LOG_FUNCTION(this << payload);
472  memcpy(payload, m_data, 8);
473 }
474 
477 {
478  NS_LOG_FUNCTION(this);
479  return m_header;
480 }
481 
483 {
484  NS_LOG_FUNCTION(this);
485 }
486 
487 TypeId
489 {
490  NS_LOG_FUNCTION(this);
491  return GetTypeId();
492 }
493 
494 uint32_t
496 {
497  NS_LOG_FUNCTION(this);
498  return 4 + m_header.GetSerializedSize() + 8;
499 }
500 
501 void
503 {
504  NS_LOG_FUNCTION(this << &start);
505  start.WriteU32(0);
506  uint32_t size = m_header.GetSerializedSize();
508  start.Next(size);
509  start.Write(m_data, 8);
510 }
511 
512 uint32_t
514 {
515  NS_LOG_FUNCTION(this << &start);
517  i.Next(4);
518  uint32_t read = m_header.Deserialize(i);
519  i.Next(read);
520  for (uint8_t j = 0; j < 8; j++)
521  {
522  m_data[j] = i.ReadU8();
523  }
524  return i.GetDistanceFrom(start);
525 }
526 
527 void
528 Icmpv4TimeExceeded::Print(std::ostream& os) const
529 {
530  NS_LOG_FUNCTION(this << &os);
531  m_header.Print(os);
532  os << " org data=";
533  for (uint8_t i = 0; i < 8; i++)
534  {
535  os << (uint32_t)m_data[i];
536  if (i != 8)
537  {
538  os << " ";
539  }
540  }
541 }
542 
543 } // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
uint8_t ReadU8()
Definition: buffer.h:1027
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1135
void WriteU8(uint8_t data)
Definition: buffer.h:881
void WriteU16(uint16_t data)
Definition: buffer.cc:859
void WriteHtonU16(uint16_t data)
Definition: buffer.h:915
uint16_t ReadNtohU16()
Definition: buffer.h:954
uint32_t GetDistanceFrom(const Iterator &o) const
Definition: buffer.cc:780
uint32_t GetSize() const
Definition: buffer.cc:1166
void Next()
go forward by one byte
Definition: buffer.h:853
Protocol header serialization and deserialization.
Definition: header.h:44
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Deserialize the object from a buffer iterator.
ICMP Destination Unreachable header.
Definition: icmpv4.h:175
Ipv4Header m_header
carried IPv4 header
Definition: icmpv4.h:240
uint16_t GetNextHopMtu() const
Get the next hop MTU.
Definition: icmpv4.cc:331
uint16_t m_nextHopMtu
next hop MTU
Definition: icmpv4.h:239
Ipv4Header GetHeader() const
Get the ICMP carried IPv4 header.
Definition: icmpv4.cc:359
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition: icmpv4.cc:352
void SetNextHopMtu(uint16_t mtu)
Set the next hop MTU.
Definition: icmpv4.cc:324
void Serialize(Buffer::Iterator start) const override
Definition: icmpv4.cc:384
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition: icmpv4.cc:370
uint32_t GetSerializedSize() const override
Definition: icmpv4.cc:377
void SetHeader(Ipv4Header header)
Set the ICMP carried IPv4 header.
Definition: icmpv4.cc:345
void SetData(Ptr< const Packet > data)
Set the ICMP carried data.
Definition: icmpv4.cc:338
~Icmpv4DestinationUnreachable() override
Definition: icmpv4.cc:365
static TypeId GetTypeId()
Get ICMP type.
Definition: icmpv4.cc:303
uint8_t m_data[8]
carried data
Definition: icmpv4.h:241
void Print(std::ostream &os) const override
Definition: icmpv4.cc:412
ICMP Echo header.
Definition: icmpv4.h:110
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition: icmpv4.cc:246
void Print(std::ostream &os) const override
Definition: icmpv4.cc:289
uint16_t m_identifier
identifier
Definition: icmpv4.h:163
uint16_t m_sequence
sequence number
Definition: icmpv4.h:164
uint32_t GetData(uint8_t payload[]) const
Get the Echo data.
Definition: icmpv4.cc:207
void SetIdentifier(uint16_t id)
Set the Echo identifier.
Definition: icmpv4.cc:150
void SetData(Ptr< const Packet > data)
Set the Echo data.
Definition: icmpv4.cc:164
uint32_t GetSerializedSize() const override
Definition: icmpv4.cc:253
uint16_t GetIdentifier() const
Get the Echo identifier.
Definition: icmpv4.cc:186
void Serialize(Buffer::Iterator start) const override
Definition: icmpv4.cc:260
~Icmpv4Echo() override
Definition: icmpv4.cc:237
static TypeId GetTypeId()
Get ICMP type.
Definition: icmpv4.cc:215
uint8_t * m_data
data
Definition: icmpv4.h:165
void SetSequenceNumber(uint16_t seq)
Set the Echo sequence number.
Definition: icmpv4.cc:157
uint32_t GetDataSize() const
Get the Echo data size.
Definition: icmpv4.cc:200
uint32_t m_dataSize
data size
Definition: icmpv4.h:166
uint16_t GetSequenceNumber() const
Get the Echo sequence number.
Definition: icmpv4.cc:193
Base class for all the ICMP packet headers.
Definition: icmpv4.h:43
void SetCode(uint8_t code)
Set ICMP code.
Definition: icmpv4.cc:123
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition: icmpv4.cc:67
bool m_calcChecksum
true if checksum is calculated
Definition: icmpv4.h:101
void SetType(uint8_t type)
Set ICMP type.
Definition: icmpv4.cc:116
uint8_t m_code
ICMP code.
Definition: icmpv4.h:100
void EnableChecksum()
Enables ICMP Checksum calculation.
Definition: icmpv4.cc:60
void Print(std::ostream &os) const override
Definition: icmpv4.cc:109
uint8_t m_type
ICMP type.
Definition: icmpv4.h:99
static TypeId GetTypeId()
Get the type ID.
Definition: icmpv4.cc:37
uint8_t GetCode() const
Get ICMP code.
Definition: icmpv4.cc:137
uint8_t GetType() const
Get ICMP type.
Definition: icmpv4.cc:130
uint32_t GetSerializedSize() const override
Definition: icmpv4.cc:74
~Icmpv4Header() override
Definition: icmpv4.cc:54
void Serialize(Buffer::Iterator start) const override
Definition: icmpv4.cc:81
ICMP Time Exceeded header.
Definition: icmpv4.h:250
Ipv4Header m_header
carried IPv4 header
Definition: icmpv4.h:297
Ipv4Header GetHeader() const
Get the ICMP carried IPv4 header.
Definition: icmpv4.cc:476
void SetHeader(Ipv4Header header)
Set the ICMP carried IPv4 header.
Definition: icmpv4.cc:462
uint32_t GetSerializedSize() const override
Definition: icmpv4.cc:495
void GetData(uint8_t payload[8]) const
Get the ICMP carried data.
Definition: icmpv4.cc:469
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition: icmpv4.cc:488
void Serialize(Buffer::Iterator start) const override
Definition: icmpv4.cc:502
uint8_t m_data[8]
carried data
Definition: icmpv4.h:298
static TypeId GetTypeId()
Get ICMP type.
Definition: icmpv4.cc:434
void SetData(Ptr< const Packet > data)
Get the ICMP carried data.
Definition: icmpv4.cc:455
~Icmpv4TimeExceeded() override
Definition: icmpv4.cc:482
void Print(std::ostream &os) const override
Definition: icmpv4.cc:528
Packet header for IPv4.
Definition: ipv4-header.h:34
void Print(std::ostream &os) const override
Definition: ipv4-header.cc:347
void Serialize(Buffer::Iterator start) const override
Definition: ipv4-header.cc:392
uint32_t GetSerializedSize() const override
Definition: ipv4-header.cc:384
uint32_t Deserialize(Buffer::Iterator start) override
Definition: ipv4-header.cc:433
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint8_t data[writeSize]