A Discrete-Event Network Simulator
API
ipv6-extension-header.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007-2009 Strasbourg University
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: David Gross <gdavid.devel@gmail.com>
19  */
20 
21 #include "ns3/assert.h"
22 #include "ns3/log.h"
23 #include "ns3/header.h"
24 #include "ipv6-extension-header.h"
25 
26 namespace ns3
27 {
28 
29 NS_LOG_COMPONENT_DEFINE ("Ipv6ExtensionHeader");
30 
31 NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionHeader);
32 
34 {
35  static TypeId tid = TypeId ("ns3::Ipv6ExtensionHeader")
37  .SetParent<Header> ()
38  .SetGroupName ("Internet")
39  ;
40  return tid;
41 }
42 
44 {
45  return GetTypeId ();
46 }
47 
49  : m_length (0),
50  m_nextHeader (0),
51  m_data (0)
52 {
53 }
54 
56 {
57 }
58 
59 void Ipv6ExtensionHeader::SetNextHeader (uint8_t nextHeader)
60 {
61  m_nextHeader = nextHeader;
62 }
63 
65 {
66  return m_nextHeader;
67 }
68 
69 void Ipv6ExtensionHeader::SetLength (uint16_t length)
70 {
71  NS_ASSERT_MSG (!(length & 0x7), "Invalid Ipv6ExtensionHeader Length, must be a multiple of 8 bytes.");
72  NS_ASSERT_MSG (length > 0, "Invalid Ipv6ExtensionHeader Length, must be greater than 0.");
73  NS_ASSERT_MSG (length < 2048, "Invalid Ipv6ExtensionHeader Length, must be a lower than 2048.");
74 
75  m_length = (length >> 3) - 1;
76 }
77 
79 {
80  return (m_length + 1) << 3;
81 }
82 
83 void Ipv6ExtensionHeader::Print (std::ostream &os) const
84 {
85  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength () << " )";
86 }
87 
89 {
90  return 2;
91 }
92 
94 {
96 
98  i.WriteU8 (m_length);
99  i.Write (m_data.PeekData (), m_data.GetSize ());
100 }
101 
103 {
105 
106  m_nextHeader = i.ReadU8 ();
107  m_length = i.ReadU8 ();
108 
109  uint32_t dataLength = GetLength () - 2;
110  uint8_t* data = new uint8_t[dataLength];
111  i.Read (data, dataLength);
112 
113  if (dataLength > m_data.GetSize ())
114  {
115  m_data.AddAtEnd (dataLength - m_data.GetSize ());
116  }
117  else
118  {
119  m_data.RemoveAtEnd (m_data.GetSize () - dataLength);
120  }
121 
122  i = m_data.Begin ();
123  i.Write (data, dataLength);
124 
125  delete[] data;
126  return GetSerializedSize ();
127 }
128 
129 OptionField::OptionField (uint32_t optionsOffset)
130  : m_optionData (0),
131  m_optionsOffset (optionsOffset)
132 {
133 }
134 
136 {
137 }
138 
140 {
142 }
143 
145 {
146  start.Write (m_optionData.Begin (), m_optionData.End ());
147  uint32_t fill = CalculatePad ((Ipv6OptionHeader::Alignment) { 8,0});
148  NS_LOG_LOGIC ("fill with " << fill << " bytes padding");
149  switch (fill)
150  {
151  case 0: return;
152  case 1: Ipv6OptionPad1Header ().Serialize (start);
153  return;
154  default: Ipv6OptionPadnHeader (fill).Serialize (start);
155  return;
156  }
157 }
158 
160 {
161  uint8_t* buf = new uint8_t[length];
162  start.Read (buf, length);
163  m_optionData = Buffer ();
164  m_optionData.AddAtEnd (length);
165  m_optionData.Begin ().Write (buf, length);
166  delete[] buf;
167  return length;
168 }
169 
171 {
172  NS_LOG_FUNCTION (option);
173 
174  uint32_t pad = CalculatePad (option.GetAlignment ());
175  NS_LOG_LOGIC ("need " << pad << " bytes padding");
176  switch (pad)
177  {
178  case 0: break; //no padding needed
179  case 1: AddOption (Ipv6OptionPad1Header ());
180  break;
181  default: AddOption (Ipv6OptionPadnHeader (pad));
182  break;
183  }
184 
187  it.Prev (option.GetSerializedSize ());
188  option.Serialize (it);
189 }
190 
192 {
193  return (alignment.offset - (m_optionData.GetSize () + m_optionsOffset)) % alignment.factor;
194 }
195 
197 {
198  return m_optionsOffset;
199 }
200 
202 {
203  return m_optionData;
204 }
205 
206 
208 
210 {
211  static TypeId tid = TypeId ("ns3::Ipv6ExtensionHopByHopHeader")
213  .SetParent<Ipv6ExtensionHeader> ()
214  .SetGroupName ("Internet")
215  ;
216  return tid;
217 }
218 
220 {
221  return GetTypeId ();
222 }
223 
225  : OptionField (2)
226 {
227 }
228 
230 {
231 }
232 
233 void Ipv6ExtensionHopByHopHeader::Print (std::ostream &os) const
234 {
235  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength () << " )";
236 }
237 
239 {
240  return 2 + OptionField::GetSerializedSize ();
241 }
242 
244 {
246 
247  i.WriteU8 (GetNextHeader ());
248  i.WriteU8 ((GetSerializedSize () >> 3) - 1);
250 }
251 
253 {
255 
256  SetNextHeader (i.ReadU8 ());
257  m_length = i.ReadU8 ();
259 
260  return GetSerializedSize ();
261 }
262 
264 
266 {
267  static TypeId tid = TypeId ("ns3::Ipv6ExtensionDestinationHeader")
269  .SetParent<Ipv6ExtensionHeader> ()
270  .SetGroupName ("Internet")
271  ;
272  return tid;
273 }
274 
276 {
277  return GetTypeId ();
278 }
279 
281  : OptionField (2)
282 {
283 }
284 
286 {
287 }
288 
289 void Ipv6ExtensionDestinationHeader::Print (std::ostream &os) const
290 {
291  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength () << " )";
292 }
293 
295 {
296  return 2 + OptionField::GetSerializedSize ();
297 }
298 
300 {
302 
303  i.WriteU8 (GetNextHeader ());
304  i.WriteU8 ((GetSerializedSize () >> 3) - 1);
306 }
307 
309 {
311 
312  SetNextHeader (i.ReadU8 ());
313  m_length = i.ReadU8 ();
315 
316  return GetSerializedSize ();
317 }
318 
320 
322 {
323  static TypeId tid = TypeId ("ns3::Ipv6ExtensionFragmentHeader")
325  .SetParent<Ipv6ExtensionHeader> ()
326  .SetGroupName ("Internet")
327  ;
328  return tid;
329 }
330 
332 {
333  return GetTypeId ();
334 }
335 
337  : m_offset (0),
338  m_identification (0)
339 {
340  m_length = 0;
341 }
342 
344 {
345 }
346 
348 {
349  // Clear the offset, and save the MF bit
350  m_offset &= 1;
351  m_offset |= offset & (~7);
352 }
353 
355 {
356  return m_offset & (~1);
357 }
358 
360 {
361  m_offset = moreFragment ? m_offset | 1 : m_offset & (~1);
362 }
363 
365 {
366  return m_offset & 1;
367 }
368 
370 {
371  m_identification = identification;
372 }
373 
375 {
376  return m_identification;
377 }
378 
379 void Ipv6ExtensionFragmentHeader::Print (std::ostream &os) const
380 {
381  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
382  << " offset = " << (uint32_t)GetOffset () << " MF = " << (uint32_t)GetMoreFragment () << " identification = " << (uint32_t)m_identification << " )";
383 }
384 
386 {
387  return 8;
388 }
389 
391 {
393 
394  i.WriteU8 (GetNextHeader ());
395  // Fragment header does not carry an extension length
396  i.WriteU8 (0);
399 }
400 
402 {
404 
405  SetNextHeader (i.ReadU8 ());
406  // Fragment header does not carry an extension length
407  i.ReadU8 ();
408  m_offset = i.ReadNtohU16 ();
410 
411  return GetSerializedSize ();
412 }
413 
415 
417 {
418  static TypeId tid = TypeId ("ns3::Ipv6ExtensionRoutingHeader")
420  .SetParent<Ipv6ExtensionHeader> ()
421  .SetGroupName ("Internet")
422  ;
423  return tid;
424 }
425 
427 {
428  return GetTypeId ();
429 }
430 
432  : m_typeRouting (0),
433  m_segmentsLeft (0)
434 {
435 }
436 
438 {
439 }
440 
442 {
443  m_typeRouting = typeRouting;
444 }
445 
447 {
448  return m_typeRouting;
449 }
450 
452 {
453  m_segmentsLeft = segmentsLeft;
454 }
455 
457 {
458  return m_segmentsLeft;
459 }
460 
461 void Ipv6ExtensionRoutingHeader::Print (std::ostream &os) const
462 {
463  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
464  << " typeRouting = " << (uint32_t)m_typeRouting << " segmentsLeft = " << (uint32_t)m_segmentsLeft << " )";
465 }
466 
468 {
469  return 4;
470 }
471 
473 {
475 
476  i.WriteU8 (GetNextHeader ());
477  i.WriteU8 (m_length);
480 }
481 
483 {
485 
486  SetNextHeader (i.ReadU8 ());
487  m_length = i.ReadU8 ();
488  m_typeRouting = i.ReadU8 ();
489  m_segmentsLeft = i.ReadU8 ();
490 
491  return GetSerializedSize ();
492 }
493 
495 
497 {
498  static TypeId tid = TypeId ("ns3::Ipv6ExtensionLooseRoutingHeader")
500  .SetParent<Ipv6ExtensionRoutingHeader> ()
501  .SetGroupName ("Internet")
502  ;
503  return tid;
504 }
505 
507 {
508  return GetTypeId ();
509 }
510 
512  : m_routersAddress (0)
513 {
514 }
515 
517 {
518 }
519 
521 {
522  m_routersAddress.clear ();
523  m_routersAddress.assign (n, Ipv6Address (""));
524 }
525 
526 void Ipv6ExtensionLooseRoutingHeader::SetRoutersAddress (std::vector<Ipv6Address> routersAddress)
527 {
528  m_routersAddress = routersAddress;
529 }
530 
531 std::vector<Ipv6Address> Ipv6ExtensionLooseRoutingHeader::GetRoutersAddress () const
532 {
533  return m_routersAddress;
534 }
535 
537 {
538  m_routersAddress.at (index) = addr;
539 }
540 
542 {
543  return m_routersAddress.at (index);
544 }
545 
546 void Ipv6ExtensionLooseRoutingHeader::Print (std::ostream &os) const
547 {
548  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
549  << " typeRouting = " << (uint32_t)GetTypeRouting () << " segmentsLeft = " << (uint32_t)GetSegmentsLeft () << " ";
550 
551  for (std::vector<Ipv6Address>::const_iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
552  {
553  os << *it << " ";
554  }
555 
556  os << " )";
557 }
558 
560 {
561  return 8 + m_routersAddress.size () * 16;
562 }
563 
565 {
567  uint8_t buff[16];
568 
569  uint8_t addressNum = m_routersAddress.size ();
570 
571  i.WriteU8 (GetNextHeader ());
572  i.WriteU8 (addressNum*2);
573  i.WriteU8 (GetTypeRouting ());
574  i.WriteU8 (GetSegmentsLeft ());
575  i.WriteU32 (0);
576 
577  for (VectorIpv6Address_t::const_iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
578  {
579  it->Serialize (buff);
580  i.Write (buff, 16);
581  }
582 }
583 
585 {
587  uint8_t buff[16];
588 
589  SetNextHeader (i.ReadU8 ());
590  m_length = i.ReadU8 ();
591  SetTypeRouting (i.ReadU8 ());
592  SetSegmentsLeft (i.ReadU8 ());
593  i.ReadU32 ();
594 
595  uint8_t addressNum = m_length / 2;
596  SetNumberAddress (addressNum);
597  for (uint8_t index = 0; index < addressNum; index++)
598  {
599  i.Read (buff, 16);
600  SetRouterAddress (index, Ipv6Address (buff));
601  }
602 
603  return GetSerializedSize ();
604 }
605 
607 
609 {
610  static TypeId tid = TypeId ("ns3::Ipv6ExtensionESPHeader")
612  .SetParent<Ipv6ExtensionHeader> ()
613  .SetGroupName ("Internet")
614  ;
615  return tid;
616 }
617 
619 {
620  return GetTypeId ();
621 }
622 
624 {
625 }
626 
628 {
629 }
630 
631 void Ipv6ExtensionESPHeader::Print (std::ostream &os) const
632 {
634 }
635 
637 {
639  return 0;
640 }
641 
643 {
645 }
646 
648 {
650  return 0;
651 }
652 
654 
656 {
657  static TypeId tid = TypeId ("ns3::Ipv6ExtensionAHHeader")
659  .SetParent<Ipv6ExtensionHeader> ()
660  .SetGroupName ("Internet")
661  ;
662  return tid;
663 }
664 
666 {
667  return GetTypeId ();
668 }
669 
671 {
672 }
673 
675 {
676 }
677 
678 void Ipv6ExtensionAHHeader::Print (std::ostream &os) const
679 {
681 }
682 
684 {
686  return 0;
687 }
688 
690 {
692 }
693 
695 {
697  return 0;
698 }
699 
700 } /* namespace ns3 */
701 
iterator in a Buffer instance
Definition: buffer.h:99
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:954
void WriteU32(uint32_t data)
Definition: buffer.cc:879
uint16_t ReadNtohU16(void)
Definition: buffer.h:946
void WriteU8(uint8_t data)
Definition: buffer.h:869
uint8_t ReadU8(void)
Definition: buffer.h:1021
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1124
void WriteHtonU16(uint16_t data)
Definition: buffer.h:905
void Prev(void)
go backward by one byte
Definition: buffer.h:851
void WriteHtonU32(uint32_t data)
Definition: buffer.h:924
uint32_t ReadU32(void)
Definition: buffer.cc:973
uint32_t ReadNtohU32(void)
Definition: buffer.h:970
automatically resized byte buffer
Definition: buffer.h:93
uint32_t GetSize(void) const
Definition: buffer.h:1063
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:488
void AddAtEnd(uint32_t end)
Definition: buffer.cc:354
Buffer::Iterator End(void) const
Definition: buffer.h:1075
uint8_t const * PeekData(void) const
Definition: buffer.cc:710
Buffer::Iterator Begin(void) const
Definition: buffer.h:1069
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Deserialize the object from a buffer iterator.
Describes an IPv6 address.
Definition: ipv6-address.h:50
Header of IPv6 Extension AH.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
virtual ~Ipv6ExtensionAHHeader()
Destructor.
virtual void Print(std::ostream &os) const
Print some information about the packet.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
static TypeId GetTypeId()
Get the type identificator.
Header of IPv6 Extension Destination.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
virtual ~Ipv6ExtensionDestinationHeader()
Destructor.
static TypeId GetTypeId()
Get the type identificator.
virtual void Print(std::ostream &os) const
Print some information about the packet.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
Header of IPv6 Extension ESP.
static TypeId GetTypeId()
Get the type identificator.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
virtual ~Ipv6ExtensionESPHeader()
Destructor.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual void Print(std::ostream &os) const
Print some information about the packet.
Header of IPv6 Extension Fragment.
virtual void Print(std::ostream &os) const
Print some information about the packet.
static TypeId GetTypeId()
Get the type identificator.
void SetIdentification(uint32_t identification)
Set the "Identification" field.
void SetOffset(uint16_t offset)
Set the "Offset" field.
uint32_t m_identification
Identifier of the packet.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
virtual ~Ipv6ExtensionFragmentHeader()
Destructor.
uint16_t m_offset
Offset of the fragment and More Fragment bit.
uint16_t GetOffset() const
Get the field "Offset".
bool GetMoreFragment() const
Get the status of "More Fragment" bit.
uint32_t GetIdentification() const
Get the field "Identification".
void SetMoreFragment(bool moreFragment)
Set the status of "More Fragment" bit.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
Header for IPv6 Extension.
uint8_t m_nextHeader
The "next header" field.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
uint16_t GetLength() const
Get the length of the extension.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
static TypeId GetTypeId()
Get the type identificator.
void SetLength(uint16_t length)
brief Set the length of the extension.
Buffer m_data
The data of the extension.
void SetNextHeader(uint8_t nextHeader)
Set the "Next header" field.
virtual ~Ipv6ExtensionHeader()
Destructor.
virtual void Print(std::ostream &os) const
Print some information about the packet.
uint8_t GetNextHeader() const
Get the next header.
uint8_t m_length
The "length" field.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
Header of IPv6 Extension "Hop by Hop".
virtual void Print(std::ostream &os) const
Print some information about the packet.
virtual ~Ipv6ExtensionHopByHopHeader()
Destructor.
static TypeId GetTypeId()
Get the type identificator.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
Header of IPv6 Extension Routing : Type 0 (Loose Routing)
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
static TypeId GetTypeId()
Get the type identificator.
std::vector< Ipv6Address > GetRoutersAddress() const
Get the vector of routers' address.
void SetRoutersAddress(std::vector< Ipv6Address > routersAddress)
Set the vector of routers' address.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
VectorIpv6Address_t m_routersAddress
The vector of Routers' IPv6 Address.
Ipv6Address GetRouterAddress(uint8_t index) const
Get a Router IPv6 Address.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
void SetRouterAddress(uint8_t index, Ipv6Address addr)
Set a Router IPv6 Address.
virtual void Print(std::ostream &os) const
Print some information about the packet.
void SetNumberAddress(uint8_t n)
Set the number of routers' address.
Header of IPv6 Extension Routing.
virtual ~Ipv6ExtensionRoutingHeader()
Destructor.
void SetTypeRouting(uint8_t typeRouting)
Set the "Type of Routing" field.
uint8_t m_typeRouting
Type of routing.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
uint8_t GetTypeRouting() const
Get the field "Type of Routing".
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
uint8_t GetSegmentsLeft() const
Get the field "Segments left".
static TypeId GetTypeId()
Get the type identificator.
virtual void Print(std::ostream &os) const
Print some information about the packet.
void SetSegmentsLeft(uint8_t segmentsLeft)
Set the "Segments left" field.
uint8_t m_segmentsLeft
Number of left segments.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
Header for IPv6 Option.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
virtual Alignment GetAlignment() const
Get the Alignment requirement of this option header.
Header of IPv6 Option Pad1.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
Header of IPv6 Option Padn.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
Option field for an IPv6ExtensionHeader.
uint32_t GetSerializedSize() const
Get the serialized size of the packet.
void AddOption(Ipv6OptionHeader const &option)
Serialize the option, prepending pad1 or padn option as necessary.
uint32_t CalculatePad(Ipv6OptionHeader::Alignment alignment) const
Calculate padding.
void Serialize(Buffer::Iterator start) const
Serialize all added options.
uint32_t Deserialize(Buffer::Iterator start, uint32_t length)
Deserialize the packet.
Buffer GetOptionBuffer()
Get the buffer.
uint32_t GetOptionsOffset()
Get the offset where the options begin, measured from the start of the extension header.
Buffer m_optionData
Data payload.
OptionField(uint32_t optionsOffset)
Constructor.
uint32_t m_optionsOffset
Offset.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId AddConstructor(void)
Record in this TypeId the fact that the default constructor is accessible.
Definition: type-id.h:638
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#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:45
Every class exported by the ns3 library is enclosed in the ns3 namespace.
def start()
Definition: core.py:1853
uint8_t data[writeSize]
represents the alignment requirements of an option header