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 
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
uint8_t m_length
The "length" field.
static TypeId GetTypeId()
Get the type identificator.
uint32_t Deserialize(Buffer::Iterator start, uint32_t length)
Deserialize the packet.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
uint32_t ReadU32(void)
Definition: buffer.cc:975
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:486
#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 TypeId GetInstanceTypeId() const
Get the instance type ID.
Buffer GetOptionBuffer()
Get the buffer.
Header for IPv6 Option.
virtual Alignment GetAlignment() const
Get the Alignment requirement of this option header.
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.
automatically resized byte buffer
Definition: buffer.h:92
def start()
Definition: core.py:1790
virtual ~Ipv6ExtensionRoutingHeader()
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 void Print(std::ostream &os) const
Print some informations about the packet.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
Header of IPv6 Option Pad1.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Buffer m_optionData
Data payload.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
void SetOffset(uint16_t offset)
Set the "Offset" field.
static TypeId GetTypeId()
Get the type identificator.
uint32_t ReadNtohU32(void)
Definition: buffer.h:970
static TypeId GetTypeId()
Get the type identificator.
virtual void Print(std::ostream &os) const
Print some informations about the packet.
represents the alignment requirements of an option header
Header of IPv6 Extension "Hop by Hop".
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
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 ~Ipv6ExtensionDestinationHeader()
Destructor.
uint8_t m_nextHeader
The "next header" field.
Header of IPv6 Extension Routing : Type 0 (Loose Routing)
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.
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
Buffer::Iterator End(void) const
Definition: buffer.h:1075
uint8_t const * PeekData(void) const
Definition: buffer.cc:708
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
VectorIpv6Address_t m_routersAddress
The vector of Routers' IPv6 Address.
void SetMoreFragment(bool moreFragment)
Set the status of "More Fragment" bit.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
void SetIdentification(uint32_t identification)
Set the "Identification" field.
Buffer::Iterator Begin(void) const
Definition: buffer.h:1069
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
uint32_t m_optionsOffset
Offset.
void AddAtEnd(uint32_t end)
Definition: buffer.cc:354
virtual ~Ipv6ExtensionFragmentHeader()
Destructor.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
virtual void Print(std::ostream &os) const
Print some informations about the packet.
void SetNextHeader(uint8_t nextHeader)
Set the "Next header" field.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual ~Ipv6ExtensionAHHeader()
Destructor.
Buffer m_data
The data of the extension.
void AddOption(Ipv6OptionHeader const &option)
Serialize the option, prepending pad1 or padn option as necessary.
virtual ~Ipv6ExtensionHeader()
Destructor.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1126
Ipv6Address GetRouterAddress(uint8_t index) const
Get a Router IPv6 Address.
uint8_t GetTypeRouting() const
Get the field "Type of Routing".
virtual void Print(std::ostream &os) const
Print some informations about the packet.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
void WriteHtonU32(uint32_t data)
Definition: buffer.h:924
uint32_t GetSize(void) const
Definition: buffer.h:1063
bool GetMoreFragment() const
Get the status of "More Fragment" bit.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
uint32_t m_identification
Identifier of the packet.
uint8_t GetSegmentsLeft() const
Get the field "Segments left".
#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:90
void Serialize(Buffer::Iterator start) const
Serialize all added options.
uint8_t GetNextHeader() const
Get the next header.
Describes an IPv6 address.
Definition: ipv6-address.h:48
void SetRoutersAddress(std::vector< Ipv6Address > routersAddress)
Set the vector of routers' address.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
uint32_t CalculatePad(Ipv6OptionHeader::Alignment alignment) const
Calculate padding.
virtual void Print(std::ostream &os) const
Print some informations about the packet.
void WriteU8(uint8_t data)
Definition: buffer.h:869
uint32_t GetIdentification() const
Get the field "Identification".
Header of IPv6 Extension Destination.
uint32_t GetOptionsOffset()
Get the offset where the options begin, measured from the start of the extension header.
Header for IPv6 Extension.
std::vector< Ipv6Address > GetRoutersAddress() const
Get the vector of routers' address.
uint8_t m_typeRouting
Type of routing.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
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:956
void SetLength(uint16_t length)
brief Set the length of the extension.
uint32_t GetSerializedSize() const
Get the serialized size of the packet.
OptionField(uint32_t optionsOffset)
Constructor.
virtual ~Ipv6ExtensionHopByHopHeader()
Destructor.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
static TypeId GetTypeId()
Get the type identificator.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
uint8_t m_segmentsLeft
Number of left segments.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
uint16_t GetOffset() const
Get the field "Offset".
uint16_t GetLength() const
Get the length of the extension.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
uint16_t ReadNtohU16(void)
Definition: buffer.h:946
virtual void Print(std::ostream &os) const
Print some informations about the packet.
void WriteU32(uint32_t data)
Definition: buffer.cc:881
void SetRouterAddress(uint8_t index, Ipv6Address addr)
Set a Router IPv6 Address.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
void SetNumberAddress(uint8_t n)
Set the number of routers' address.
a unique identifier for an interface.
Definition: type-id.h:58
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
virtual void Print(std::ostream &os) const
Print some informations about the packet.
Header of IPv6 Option Padn.
virtual ~Ipv6ExtensionLooseRoutingHeader()
Destructor.
virtual void Print(std::ostream &os) const
Print some informations about the packet.
static TypeId GetTypeId()
Get the type identificator.
void SetSegmentsLeft(uint8_t segmentsLeft)
Set the "Segments left" field.