A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
icmpv4.cc
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
36 Icmpv4Header::GetTypeId (void)
37 {
38  static TypeId tid = TypeId ("ns3::Icmpv4Header")
39  .SetParent<Header> ()
40  .AddConstructor<Icmpv4Header> ()
41  ;
42  return tid;
43 }
44 Icmpv4Header::Icmpv4Header ()
45  : m_type (0),
46  m_code (0),
47  m_calcChecksum (false)
48 {
49  NS_LOG_FUNCTION (this);
50 }
51 Icmpv4Header::~Icmpv4Header ()
52 {
53  NS_LOG_FUNCTION (this);
54 }
55 void
56 Icmpv4Header::EnableChecksum (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);
77  Buffer::Iterator i = 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
120 Icmpv4Header::GetType (void) const
121 {
122  NS_LOG_FUNCTION (this);
123  return m_type;
124 }
125 uint8_t
126 Icmpv4Header::GetCode (void) const
127 {
128  NS_LOG_FUNCTION (this);
129  return m_code;
130 }
131 
132 /********************************************************
133  * Icmpv4Echo
134  ********************************************************/
135 
136 NS_OBJECT_ENSURE_REGISTERED (Icmpv4Echo);
137 
138 void
139 Icmpv4Echo::SetIdentifier (uint16_t id)
140 {
141  NS_LOG_FUNCTION (this << id);
142  m_identifier = id;
143 }
144 void
145 Icmpv4Echo::SetSequenceNumber (uint16_t seq)
146 {
147  NS_LOG_FUNCTION (this << seq);
148  m_sequence = seq;
149 }
150 void
151 Icmpv4Echo::SetData (Ptr<const Packet> data)
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
172 Icmpv4Echo::GetIdentifier (void) const
173 {
174  NS_LOG_FUNCTION (this);
175  return m_identifier;
176 }
177 uint16_t
178 Icmpv4Echo::GetSequenceNumber (void) const
179 {
180  NS_LOG_FUNCTION (this);
181  return m_sequence;
182 }
183 uint32_t
184 Icmpv4Echo::GetDataSize (void) const
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
197 Icmpv4Echo::GetTypeId (void)
198 {
199  static TypeId tid = TypeId ("ns3::Icmpv4Echo")
200  .SetParent<Header> ()
201  .AddConstructor<Icmpv4Echo> ()
202  ;
203  return tid;
204 }
205 Icmpv4Echo::Icmpv4Echo ()
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 }
217 Icmpv4Echo::~Icmpv4Echo ()
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 
273 NS_OBJECT_ENSURE_REGISTERED (Icmpv4DestinationUnreachable);
274 
275 TypeId
276 Icmpv4DestinationUnreachable::GetTypeId (void)
277 {
278  static TypeId tid = TypeId ("ns3::Icmpv4DestinationUnreachable")
279  .SetParent<Header> ()
280  .AddConstructor<Icmpv4DestinationUnreachable> ()
281  ;
282  return tid;
283 }
284 Icmpv4DestinationUnreachable::Icmpv4DestinationUnreachable ()
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
296 Icmpv4DestinationUnreachable::SetNextHopMtu (uint16_t mtu)
297 {
298  NS_LOG_FUNCTION (this << mtu);
299  m_nextHopMtu = mtu;
300 }
301 uint16_t
302 Icmpv4DestinationUnreachable::GetNextHopMtu (void) const
303 {
304  NS_LOG_FUNCTION (this);
305  return m_nextHopMtu;
306 }
307 
308 void
309 Icmpv4DestinationUnreachable::SetData (Ptr<const Packet> data)
310 {
311  NS_LOG_FUNCTION (this << *data);
312  data->CopyData (m_data, 8);
313 }
314 void
315 Icmpv4DestinationUnreachable::SetHeader (Ipv4Header header)
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
327 Icmpv4DestinationUnreachable::GetHeader (void) const
328 {
329  NS_LOG_FUNCTION (this);
330  return m_header;
331 }
332 
333 
334 Icmpv4DestinationUnreachable::~Icmpv4DestinationUnreachable ()
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);
365  Buffer::Iterator i = 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 
396 NS_OBJECT_ENSURE_REGISTERED (Icmpv4TimeExceeded);
397 
398 TypeId
399 Icmpv4TimeExceeded::GetTypeId (void)
400 {
401  static TypeId tid = TypeId ("ns3::Icmpv4TimeExceeded")
402  .SetParent<Header> ()
403  .AddConstructor<Icmpv4TimeExceeded> ()
404  ;
405  return tid;
406 }
407 Icmpv4TimeExceeded::Icmpv4TimeExceeded ()
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
420 Icmpv4TimeExceeded::SetData (Ptr<const Packet> data)
421 {
422  NS_LOG_FUNCTION (this << *data);
423  data->CopyData (m_data, 8);
424 }
425 void
426 Icmpv4TimeExceeded::SetHeader (Ipv4Header header)
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
438 Icmpv4TimeExceeded::GetHeader (void) const
439 {
440  NS_LOG_FUNCTION (this);
441  return m_header;
442 }
443 
444 
445 Icmpv4TimeExceeded::~Icmpv4TimeExceeded ()
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);
476  Buffer::Iterator i = 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:1158
virtual void Print(std::ostream &os) const
Definition: icmpv4.cc:262
virtual TypeId GetInstanceTypeId(void) const
Definition: icmpv4.cc:338
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
virtual TypeId GetInstanceTypeId(void) const
Definition: icmpv4.cc:225
virtual uint32_t GetSerializedSize(void) const
Definition: icmpv4.cc:456
#define NS_ASSERT(condition)
Definition: assert.h:64
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: icmpv4.cc:473
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
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 void Print(std::ostream &os) const
Definition: icmpv4.cc:101
uint32_t GetDistanceFrom(Iterator const &o) const
Definition: buffer.cc:807
iterator in a Buffer instance
Definition: buffer.h:98
virtual void Serialize(Buffer::Iterator start) const
Definition: icmpv4.cc:237
virtual uint32_t GetSerializedSize(void) const
Definition: icmpv4.cc:68
void WriteU16(uint16_t data)
Definition: buffer.cc:895
void WriteHtonU16(uint16_t data)
Definition: buffer.h:726
virtual uint32_t GetSerializedSize(void) const
Definition: icmpv4.cc:231
void Next(void)
Definition: buffer.h:666
virtual TypeId GetInstanceTypeId(void) const
Definition: icmpv4.cc:62
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1148
virtual void Print(std::ostream &os) const
Definition: ipv4-header.cc:333
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: icmpv4.cc:362
virtual uint32_t GetSerializedSize(void) const
Definition: icmpv4.cc:344
void WriteU8(uint8_t data)
Definition: buffer.h:690
virtual TypeId GetInstanceTypeId(void) const
Definition: icmpv4.cc:450
uint8_t ReadU8(void)
Definition: buffer.h:819
virtual void Serialize(Buffer::Iterator start) const
Definition: ipv4-header.cc:381
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:978
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: icmpv4.cc:245
uint16_t ReadNtohU16(void)
Definition: buffer.h:767
void WriteU32(uint32_t data)
Definition: buffer.cc:903
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:373
uint32_t GetSize(void) const
Definition: buffer.cc:1183
a unique identifier for an interface.
Definition: type-id.h:44
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
virtual void Serialize(Buffer::Iterator start) const
Definition: icmpv4.cc:350
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: ipv4-header.cc:421