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 {
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 
uint8_t m_length
The "length" field.
virtual void Print(std::ostream &os) const
Print some information about the packet.
static TypeId GetTypeId()
Get the type identificator.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
uint32_t Deserialize(Buffer::Iterator start, uint32_t length)
Deserialize the packet.
virtual void Print(std::ostream &os) const
Print some information about the packet.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
uint32_t ReadU32(void)
Definition: buffer.cc:972
TypeId AddConstructor(void)
Record in this TypeId the fact that the default constructor is accessible.
Definition: type-id.h:652
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:483
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
Header of IPv6 Extension ESP.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
Buffer GetOptionBuffer()
Get the buffer.
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
Header for IPv6 Option.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
Header of IPv6 Extension Routing.
void SetTypeRouting(uint8_t typeRouting)
Set the "Type of Routing" field.
uint16_t m_offset
Offset of the fragment and More Fragment bit.
Ipv6Address GetRouterAddress(uint8_t index) const
Get a Router IPv6 Address.
automatically resized byte buffer
Definition: buffer.h:92
def start()
Definition: core.py:1855
uint16_t GetOffset() const
Get the field "Offset".
virtual ~Ipv6ExtensionRoutingHeader()
Destructor.
static TypeId GetTypeId()
Get the type identificator.
uint8_t GetNextHeader() const
Get the next header.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
uint16_t GetLength() const
Get the length of the extension.
Header of IPv6 Option Pad1.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Buffer m_optionData
Data payload.
uint32_t GetIdentification() const
Get the field "Identification".
uint8_t const * PeekData(void) const
Definition: buffer.cc:705
void SetOffset(uint16_t offset)
Set the "Offset" field.
static TypeId GetTypeId()
Get the type identificator.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
uint32_t ReadNtohU32(void)
Definition: buffer.h:970
static TypeId GetTypeId()
Get the type identificator.
represents the alignment requirements of an option header
Header of IPv6 Extension "Hop by Hop".
iterator in a Buffer instance
Definition: buffer.h:98
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 ~Ipv6ExtensionDestinationHeader()
Destructor.
uint8_t m_nextHeader
The "next header" field.
Header of IPv6 Extension Routing : Type 0 (Loose Routing)
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
Option field for an IPv6ExtensionHeader.
static TypeId GetTypeId()
Get the type identificator.
void Prev(void)
go backward by one byte
Definition: buffer.h:851
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
Header of IPv6 Extension AH.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
uint8_t data[writeSize]
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual ~Ipv6ExtensionESPHeader()
Destructor.
void WriteHtonU16(uint16_t data)
Definition: buffer.h:905
uint32_t CalculatePad(Ipv6OptionHeader::Alignment alignment) const
Calculate padding.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
virtual void Print(std::ostream &os) const
Print some information about the packet.
virtual void Print(std::ostream &os) const
Print some information about the packet.
VectorIpv6Address_t m_routersAddress
The vector of Routers&#39; IPv6 Address.
uint8_t GetTypeRouting() const
Get the field "Type of Routing".
void SetMoreFragment(bool moreFragment)
Set the status of "More Fragment" bit.
virtual Alignment GetAlignment() const
Get the Alignment requirement of this option header.
void SetIdentification(uint32_t identification)
Set the "Identification" field.
std::vector< Ipv6Address > GetRoutersAddress() const
Get the vector of routers&#39; address.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
uint32_t m_optionsOffset
Offset.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
void AddAtEnd(uint32_t end)
Definition: buffer.cc:354
virtual ~Ipv6ExtensionFragmentHeader()
Destructor.
void SetNextHeader(uint8_t nextHeader)
Set the "Next header" field.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void Serialize(Buffer::Iterator start) const
Serialize all added options.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual ~Ipv6ExtensionAHHeader()
Destructor.
Buffer m_data
The data of the extension.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
void AddOption(Ipv6OptionHeader const &option)
Serialize the option, prepending pad1 or padn option as necessary.
virtual ~Ipv6ExtensionHeader()
Destructor.
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1123
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
void WriteHtonU32(uint32_t data)
Definition: buffer.h:924
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
Buffer::Iterator End(void) const
Definition: buffer.h:1075
uint32_t m_identification
Identifier of the packet.
Describes an IPv6 address.
Definition: ipv6-address.h:49
void SetRoutersAddress(std::vector< Ipv6Address > routersAddress)
Set the vector of routers&#39; address.
void WriteU8(uint8_t data)
Definition: buffer.h:869
bool GetMoreFragment() const
Get the status of "More Fragment" bit.
Header of IPv6 Extension Destination.
uint32_t GetOptionsOffset()
Get the offset where the options begin, measured from the start of the extension header.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
uint32_t GetSerializedSize() const
Get the serialized size of the packet.
Header for IPv6 Extension.
virtual void Print(std::ostream &os) const
Print some information about the packet.
uint8_t m_typeRouting
Type of routing.
uint32_t GetSize(void) const
Definition: buffer.h:1063
Header of IPv6 Extension Fragment.
uint8_t ReadU8(void)
Definition: buffer.h:1021
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:953
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
void SetLength(uint16_t length)
brief Set the length of the extension.
OptionField(uint32_t optionsOffset)
Constructor.
virtual ~Ipv6ExtensionHopByHopHeader()
Destructor.
static TypeId GetTypeId()
Get the type identificator.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
uint8_t m_segmentsLeft
Number of left segments.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
virtual void Print(std::ostream &os) const
Print some information about the packet.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
uint8_t GetSegmentsLeft() const
Get the field "Segments left".
virtual void Print(std::ostream &os) const
Print some information about the packet.
uint16_t ReadNtohU16(void)
Definition: buffer.h:946
void WriteU32(uint32_t data)
Definition: buffer.cc:878
void SetRouterAddress(uint8_t index, Ipv6Address addr)
Set a Router IPv6 Address.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
void SetNumberAddress(uint8_t n)
Set the number of routers&#39; address.
a unique identifier for an interface.
Definition: type-id.h:58
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
Buffer::Iterator Begin(void) const
Definition: buffer.h:1069
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
Header of IPv6 Option Padn.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual ~Ipv6ExtensionLooseRoutingHeader()
Destructor.
virtual void Print(std::ostream &os) const
Print some information about the packet.
static TypeId GetTypeId()
Get the type identificator.
void SetSegmentsLeft(uint8_t segmentsLeft)
Set the "Segments left" field.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.