A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
25namespace ns3
26{
27
28NS_LOG_COMPONENT_DEFINE("Icmpv4Header");
29
30/********************************************************
31 * Icmpv4Header
32 ********************************************************/
33
34NS_OBJECT_ENSURE_REGISTERED(Icmpv4Header);
35
36TypeId
38{
39 static TypeId tid = TypeId("ns3::Icmpv4Header")
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
59void
61{
62 NS_LOG_FUNCTION(this);
63 m_calcChecksum = true;
64}
65
68{
69 NS_LOG_FUNCTION(this);
70 return GetTypeId();
71}
72
75{
76 NS_LOG_FUNCTION(this);
77 return 4;
78}
79
80void
82{
83 NS_LOG_FUNCTION(this << &start);
84 Buffer::Iterator i = start;
85 i.WriteU8(m_type);
86 i.WriteU8(m_code);
87 i.WriteHtonU16(0);
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
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
108void
109Icmpv4Header::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
115void
117{
118 NS_LOG_FUNCTION(this << static_cast<uint32_t>(type));
119 m_type = type;
120}
121
122void
124{
125 NS_LOG_FUNCTION(this << static_cast<uint32_t>(code));
126 m_code = code;
127}
128
129uint8_t
131{
132 NS_LOG_FUNCTION(this);
133 return m_type;
134}
135
136uint8_t
138{
139 NS_LOG_FUNCTION(this);
140 return m_code;
141}
142
143/********************************************************
144 * Icmpv4Echo
145 ********************************************************/
146
148
149void
151{
152 NS_LOG_FUNCTION(this << id);
153 m_identifier = id;
154}
155
156void
158{
159 NS_LOG_FUNCTION(this << seq);
160 m_sequence = seq;
161}
162
163void
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
185uint16_t
187{
188 NS_LOG_FUNCTION(this);
189 return m_identifier;
190}
191
192uint16_t
194{
195 NS_LOG_FUNCTION(this);
196 return m_sequence;
197}
198
201{
202 NS_LOG_FUNCTION(this);
203 return m_dataSize;
204}
205
207Icmpv4Echo::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
214TypeId
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
245TypeId
247{
248 NS_LOG_FUNCTION(this);
249 return GetTypeId();
250}
251
254{
255 NS_LOG_FUNCTION(this);
256 return 4 + m_dataSize;
257}
258
259void
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
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
288void
289Icmpv4Echo::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
302TypeId
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
323void
325{
326 NS_LOG_FUNCTION(this << mtu);
327 m_nextHopMtu = mtu;
328}
329
330uint16_t
332{
333 NS_LOG_FUNCTION(this);
334 return m_nextHopMtu;
335}
336
337void
339{
340 NS_LOG_FUNCTION(this << *data);
341 data->CopyData(m_data, 8);
342}
343
344void
346{
347 NS_LOG_FUNCTION(this << header);
348 m_header = header;
349}
350
351void
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
369TypeId
371{
372 NS_LOG_FUNCTION(this);
373 return GetTypeId();
374}
375
378{
379 NS_LOG_FUNCTION(this);
380 return 4 + m_header.GetSerializedSize() + 8;
381}
382
383void
385{
386 NS_LOG_FUNCTION(this << &start);
387 start.WriteU16(0);
388 start.WriteHtonU16(m_nextHopMtu);
390 m_header.Serialize(start);
391 start.Next(size);
392 start.Write(m_data, 8);
393}
394
397{
398 NS_LOG_FUNCTION(this << &start);
399 Buffer::Iterator i = 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
411void
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
433TypeId
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
454void
456{
457 NS_LOG_FUNCTION(this << *data);
458 data->CopyData(m_data, 8);
459}
460
461void
463{
464 NS_LOG_FUNCTION(this << header);
465 m_header = header;
466}
467
468void
469Icmpv4TimeExceeded::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
487TypeId
489{
490 NS_LOG_FUNCTION(this);
491 return GetTypeId();
492}
493
496{
497 NS_LOG_FUNCTION(this);
498 return 4 + m_header.GetSerializedSize() + 8;
499}
500
501void
503{
504 NS_LOG_FUNCTION(this << &start);
505 start.WriteU32(0);
507 m_header.Serialize(start);
508 start.Next(size);
509 start.Write(m_data, 8);
510}
511
514{
515 NS_LOG_FUNCTION(this << &start);
516 Buffer::Iterator i = 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
527void
528Icmpv4TimeExceeded::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
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
uint32_t Deserialize(Buffer::Iterator start) override
Definition: icmpv4.cc:396
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
uint32_t Deserialize(Buffer::Iterator start) override
Definition: icmpv4.cc:269
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
uint32_t Deserialize(Buffer::Iterator start) override
Definition: icmpv4.cc:99
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
uint32_t Deserialize(Buffer::Iterator start) override
Definition: icmpv4.cc:513
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
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
#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]