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_nextHeader (0),
50  m_length (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  m_length = (length >> 3) - 1;
72 }
73 
75 {
76  return (m_length + 1) << 3;
77 }
78 
79 void Ipv6ExtensionHeader::Print (std::ostream &os) const
80 {
81  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength () << " )";
82 }
83 
85 {
86  return 2;
87 }
88 
90 {
92 
94  i.WriteU8 (m_length);
95  i.Write (m_data.PeekData (), m_data.GetSize ());
96 }
97 
99 {
101 
102  m_nextHeader = i.ReadU8 ();
103  m_length = i.ReadU8 ();
104 
105  uint32_t dataLength = GetLength () - 2;
106  uint8_t* data = new uint8_t[dataLength];
107  i.Read (data, dataLength);
108 
109  if (dataLength > m_data.GetSize ())
110  {
111  m_data.AddAtEnd (dataLength - m_data.GetSize ());
112  }
113  else
114  {
115  m_data.RemoveAtEnd (m_data.GetSize () - dataLength);
116  }
117 
118  i = m_data.Begin ();
119  i.Write (data, dataLength);
120 
121  delete[] data;
122  return GetSerializedSize ();
123 }
124 
125 OptionField::OptionField (uint32_t optionsOffset)
126  : m_optionData (0),
127  m_optionsOffset (optionsOffset)
128 {
129 }
130 
132 {
133 }
134 
136 {
138 }
139 
141 {
142  start.Write (m_optionData.Begin (), m_optionData.End ());
143  uint32_t fill = CalculatePad ((Ipv6OptionHeader::Alignment) { 8,0});
144  NS_LOG_LOGIC ("fill with " << fill << " bytes padding");
145  switch (fill)
146  {
147  case 0: return;
148  case 1: Ipv6OptionPad1Header ().Serialize (start);
149  return;
150  default: Ipv6OptionPadnHeader (fill).Serialize (start);
151  return;
152  }
153 }
154 
156 {
157  uint8_t* buf = new uint8_t[length];
158  start.Read (buf, length);
159  m_optionData = Buffer ();
160  m_optionData.AddAtEnd (length);
161  m_optionData.Begin ().Write (buf, length);
162  delete[] buf;
163  return length;
164 }
165 
167 {
169 
170  uint32_t pad = CalculatePad (option.GetAlignment ());
171  NS_LOG_LOGIC ("need " << pad << " bytes padding");
172  switch (pad)
173  {
174  case 0: break; //no padding needed
175  case 1: AddOption (Ipv6OptionPad1Header ());
176  break;
177  default: AddOption (Ipv6OptionPadnHeader (pad));
178  break;
179  }
180 
183  it.Prev (option.GetSerializedSize ());
184  option.Serialize (it);
185 }
186 
188 {
189  return (alignment.offset - (m_optionData.GetSize () + m_optionsOffset)) % alignment.factor;
190 }
191 
193 {
194  return m_optionsOffset;
195 }
196 
198 {
199  return m_optionData;
200 }
201 
202 
204 
206 {
207  static TypeId tid = TypeId ("ns3::Ipv6ExtensionHopByHopHeader")
209  .SetParent<Ipv6ExtensionHeader> ()
210  .SetGroupName ("Internet")
211  ;
212  return tid;
213 }
214 
216 {
217  return GetTypeId ();
218 }
219 
221  : OptionField (2)
222 {
223 }
224 
226 {
227 }
228 
229 void Ipv6ExtensionHopByHopHeader::Print (std::ostream &os) const
230 {
231  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength () << " )";
232 }
233 
235 {
236  return 2 + OptionField::GetSerializedSize ();
237 }
238 
240 {
242 
243  i.WriteU8 (GetNextHeader ());
244  i.WriteU8 ((GetSerializedSize () >> 3) - 1);
246 }
247 
249 {
251 
252  SetNextHeader (i.ReadU8 ());
253  SetLength ((i.ReadU8 () + 1) << 3);
255 
256  return GetSerializedSize ();
257 }
258 
260 
262 {
263  static TypeId tid = TypeId ("ns3::Ipv6ExtensionDestinationHeader")
265  .SetParent<Ipv6ExtensionHeader> ()
266  .SetGroupName ("Internet")
267  ;
268  return tid;
269 }
270 
272 {
273  return GetTypeId ();
274 }
275 
277  : OptionField (2)
278 {
279 }
280 
282 {
283 }
284 
285 void Ipv6ExtensionDestinationHeader::Print (std::ostream &os) const
286 {
287  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength () << " )";
288 }
289 
291 {
292  return 2 + OptionField::GetSerializedSize ();
293 }
294 
296 {
298 
299  i.WriteU8 (GetNextHeader ());
300  i.WriteU8 ((GetSerializedSize () >> 3) - 1);
302 }
303 
305 {
307 
308  SetNextHeader (i.ReadU8 ());
309  SetLength ((i.ReadU8 () + 1) << 3);
311 
312  return GetSerializedSize ();
313 }
314 
316 
318 {
319  static TypeId tid = TypeId ("ns3::Ipv6ExtensionFragmentHeader")
321  .SetParent<Ipv6ExtensionHeader> ()
322  .SetGroupName ("Internet")
323  ;
324  return tid;
325 }
326 
328 {
329  return GetTypeId ();
330 }
331 
333  : m_offset (0),
334  m_identification (0)
335 {
336  SetLength (0);
337 }
338 
340 {
341 }
342 
344 {
345  // Clear the offset, and save the MF bit
346  m_offset &= 1;
347  m_offset |= offset & (~7);
348 }
349 
351 {
352  return m_offset & (~1);
353 }
354 
356 {
357  m_offset = moreFragment ? m_offset | 1 : m_offset & (~1);
358 }
359 
361 {
362  return m_offset & 1;
363 }
364 
366 {
367  m_identification = identification;
368 }
369 
371 {
372  return m_identification;
373 }
374 
375 void Ipv6ExtensionFragmentHeader::Print (std::ostream &os) const
376 {
377  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
378  << " offset = " << (uint32_t)GetOffset () << " MF = " << (uint32_t)GetMoreFragment () << " identification = " << (uint32_t)m_identification << " )";
379 }
380 
382 {
383  return 8;
384 }
385 
387 {
389 
390  i.WriteU8 (GetNextHeader ());
391  i.WriteU8 (0);
394 }
395 
397 {
399 
400  SetNextHeader (i.ReadU8 ());
401  i.ReadU8();
402  SetLength (0);
403  m_offset = i.ReadNtohU16 ();
405 
406  return GetSerializedSize ();
407 }
408 
410 
412 {
413  static TypeId tid = TypeId ("ns3::Ipv6ExtensionRoutingHeader")
415  .SetParent<Ipv6ExtensionHeader> ()
416  .SetGroupName ("Internet")
417  ;
418  return tid;
419 }
420 
422 {
423  return GetTypeId ();
424 }
425 
427  : m_typeRouting (0),
428  m_segmentsLeft (0)
429 {
430 }
431 
433 {
434 }
435 
437 {
438  m_typeRouting = typeRouting;
439 }
440 
442 {
443  return m_typeRouting;
444 }
445 
447 {
448  m_segmentsLeft = segmentsLeft;
449 }
450 
452 {
453  return m_segmentsLeft;
454 }
455 
456 void Ipv6ExtensionRoutingHeader::Print (std::ostream &os) const
457 {
458  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
459  << " typeRouting = " << (uint32_t)m_typeRouting << " segmentsLeft = " << (uint32_t)m_segmentsLeft << " )";
460 }
461 
463 {
464  return 4;
465 }
466 
468 {
470 
471  i.WriteU8 (GetNextHeader ());
472  i.WriteU8 ((GetLength () >> 3) - 1);
475 }
476 
478 {
480 
481  SetNextHeader (i.ReadU8 ());
482  SetLength ((i.ReadU8 () + 1) << 3);
483  m_typeRouting = i.ReadU8 ();
484  m_segmentsLeft = i.ReadU8 ();
485 
486  return GetSerializedSize ();
487 }
488 
490 
492 {
493  static TypeId tid = TypeId ("ns3::Ipv6ExtensionLooseRoutingHeader")
495  .SetParent<Ipv6ExtensionRoutingHeader> ()
496  .SetGroupName ("Internet")
497  ;
498  return tid;
499 }
500 
502 {
503  return GetTypeId ();
504 }
505 
507  : m_routersAddress (0)
508 {
509 }
510 
512 {
513 }
514 
516 {
517  m_routersAddress.clear ();
518  m_routersAddress.assign (n, Ipv6Address (""));
519 }
520 
521 void Ipv6ExtensionLooseRoutingHeader::SetRoutersAddress (std::vector<Ipv6Address> routersAddress)
522 {
523  m_routersAddress = routersAddress;
524 }
525 
526 std::vector<Ipv6Address> Ipv6ExtensionLooseRoutingHeader::GetRoutersAddress () const
527 {
528  return m_routersAddress;
529 }
530 
532 {
533  m_routersAddress.at (index) = addr;
534 }
535 
537 {
538  return m_routersAddress.at (index);
539 }
540 
541 void Ipv6ExtensionLooseRoutingHeader::Print (std::ostream &os) const
542 {
543  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
544  << " typeRouting = " << (uint32_t)GetTypeRouting () << " segmentsLeft = " << (uint32_t)GetSegmentsLeft () << " ";
545 
546  for (std::vector<Ipv6Address>::const_iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
547  {
548  os << *it << " ";
549  }
550 
551  os << " )";
552 }
553 
555 {
556  return 8 + m_routersAddress.size () * 16;
557 }
558 
560 {
562  uint8_t buff[16];
563 
564  i.WriteU8 (GetNextHeader ());
565  i.WriteU8 ((GetLength () >> 3) - 1);
566  i.WriteU8 (GetTypeRouting ());
567  i.WriteU8 (GetSegmentsLeft ());
568  i.WriteU32 (0);
569 
570  for (VectorIpv6Address_t::const_iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
571  {
572  it->Serialize (buff);
573  i.Write (buff, 16);
574  }
575 }
576 
578 {
580  uint8_t buff[16];
581 
582  SetNextHeader (i.ReadU8 ());
583  SetLength ((i.ReadU8 () + 1) << 3);
584  SetTypeRouting (i.ReadU8 ());
585  SetSegmentsLeft (i.ReadU8 ());
586  i.ReadU32 ();
587 
588  for (std::vector<Ipv6Address>::iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
589  {
590  i.Read (buff, 16);
591  it->Set (buff);
592  }
593 
594  return GetSerializedSize ();
595 }
596 
598 
600 {
601  static TypeId tid = TypeId ("ns3::Ipv6ExtensionESPHeader")
603  .SetParent<Ipv6ExtensionHeader> ()
604  .SetGroupName ("Internet")
605  ;
606  return tid;
607 }
608 
610 {
611  return GetTypeId ();
612 }
613 
615 {
616 }
617 
619 {
620 }
621 
622 void Ipv6ExtensionESPHeader::Print (std::ostream &os) const
623 {
625 }
626 
628 {
630  return 0;
631 }
632 
634 {
636 }
637 
639 {
641  return 0;
642 }
643 
645 
647 {
648  static TypeId tid = TypeId ("ns3::Ipv6ExtensionAHHeader")
650  .SetParent<Ipv6ExtensionHeader> ()
651  .SetGroupName ("Internet")
652  ;
653  return tid;
654 }
655 
657 {
658  return GetTypeId ();
659 }
660 
662 {
663 }
664 
666 {
667 }
668 
669 void Ipv6ExtensionAHHeader::Print (std::ostream &os) const
670 {
672 }
673 
675 {
677  return 0;
678 }
679 
681 {
683 }
684 
686 {
688  return 0;
689 }
690 
691 } /* namespace ns3 */
692 
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.
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:1001
TypeId AddConstructor(void)
Definition: type-id.h:460
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:501
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
Introspection did not find any typical Config paths.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
Introspection did not find any typical Config paths.
virtual Alignment GetAlignment() const
Get the Alignment requirement of this option header.
uint32_t CalculatePad(Ipv6OptionHeader::Alignment alignment) const
Calculate padding.
Introspection did not find any typical Config paths.
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:1482
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.
Introspection did not find any typical Config paths.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Buffer m_optionData
Data payload.
OptionField(uint32_t optionsOffset)
Constructor.
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:977
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
Introspection did not find any typical Config paths.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
iterator in a Buffer instance
Definition: buffer.h:98
uint32_t GetSerializedSize() const
Get the serialized size of the packet.
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.
Introspection did not find any typical Config paths.
Option field for an IPv6ExtensionHeader Enables adding options to an IPv6ExtensionHeader.
static TypeId GetTypeId()
Get the type identificator.
void Prev(void)
go backward by one byte
Definition: buffer.h:858
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
Introspection did not find any typical Config paths.
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:912
Buffer::Iterator End(void) const
Definition: buffer.h:1082
uint8_t const * PeekData(void) const
Definition: buffer.cc:733
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.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
Buffer::Iterator Begin(void) const
Definition: buffer.h:1076
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.
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.
uint32_t GetOptionsOffset()
Get the offset where the options begin, measured from the start of the extension header.
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:1152
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:931
uint32_t GetSize(void) const
Definition: buffer.h:1070
bool GetMoreFragment() const
Get the status of "More Fragment" bit.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
uint32_t m_identification
Identifier of the packet.
uint8_t GetSegmentsLeft() const
Get the field "Segments left".
bool AddAtEnd(uint32_t end)
Definition: buffer.cc:360
uint8_t GetNextHeader() const
Get the next header.
Describes an IPv6 address.
Definition: ipv6-address.h:47
void SetRoutersAddress(std::vector< Ipv6Address > routersAddress)
Set the vector of routers' address.
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
virtual void Print(std::ostream &os) const
Print some informations about the packet.
void WriteU8(uint8_t data)
Definition: buffer.h:876
void AddOption(Ipv6OptionHeader const &option)
Serialize the option, prepending pad1 or padn option as necessary.
uint32_t GetIdentification() const
Get the field "Identification".
Introspection did not find any typical Config paths.
uint32_t Deserialize(Buffer::Iterator start, uint32_t length)
Deserialize the packet.
Buffer GetOptionBuffer()
Get the buffer.
Introspection did not find any typical Config paths.
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.
Introspection did not find any typical Config paths.
uint8_t ReadU8(void)
Definition: buffer.h:1028
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:982
void SetLength(uint16_t length)
brief Set the length of the extension.
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.
void Serialize(Buffer::Iterator start) const
Serialize all added options.
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:953
virtual void Print(std::ostream &os) const
Print some informations about the packet.
void WriteU32(uint32_t data)
Definition: buffer.cc:907
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:57
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
virtual void Print(std::ostream &os) const
Print some informations about the packet.
Introspection did not find any typical Config paths.
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.