A Discrete-Event Network Simulator
API
ipv6-extension-header.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007-2009 Strasbourg University
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: David Gross <gdavid.devel@gmail.com>
18  */
19 
20 #include "ipv6-extension-header.h"
21 
22 #include "ns3/assert.h"
23 #include "ns3/header.h"
24 #include "ns3/log.h"
25 
26 namespace ns3
27 {
28 
29 NS_LOG_COMPONENT_DEFINE("Ipv6ExtensionHeader");
30 
31 NS_OBJECT_ENSURE_REGISTERED(Ipv6ExtensionHeader);
32 
33 TypeId
35 {
36  static TypeId tid = TypeId("ns3::Ipv6ExtensionHeader")
38  .SetParent<Header>()
39  .SetGroupName("Internet");
40  return tid;
41 }
42 
43 TypeId
45 {
46  return GetTypeId();
47 }
48 
50  : m_length(0),
51  m_nextHeader(0),
52  m_data(0)
53 {
54 }
55 
57 {
58 }
59 
60 void
62 {
63  m_nextHeader = nextHeader;
64 }
65 
66 uint8_t
68 {
69  return m_nextHeader;
70 }
71 
72 void
74 {
75  NS_ASSERT_MSG(!(length & 0x7),
76  "Invalid Ipv6ExtensionHeader Length, must be a multiple of 8 bytes.");
77  NS_ASSERT_MSG(length > 0, "Invalid Ipv6ExtensionHeader Length, must be greater than 0.");
78  NS_ASSERT_MSG(length < 2048, "Invalid Ipv6ExtensionHeader Length, must be a lower than 2048.");
79 
80  m_length = (length >> 3) - 1;
81 }
82 
83 uint16_t
85 {
86  return (m_length + 1) << 3;
87 }
88 
89 void
90 Ipv6ExtensionHeader::Print(std::ostream& os) const
91 {
92  os << "( nextHeader = " << (uint32_t)GetNextHeader() << " length = " << (uint32_t)GetLength()
93  << " )";
94 }
95 
96 uint32_t
98 {
99  return 2;
100 }
101 
102 void
104 {
106 
108  i.WriteU8(m_length);
110 }
111 
112 uint32_t
114 {
116 
117  m_nextHeader = i.ReadU8();
118  m_length = i.ReadU8();
119 
120  uint32_t dataLength = GetLength() - 2;
121  auto data = new uint8_t[dataLength];
122  i.Read(data, dataLength);
123 
124  if (dataLength > m_data.GetSize())
125  {
126  m_data.AddAtEnd(dataLength - m_data.GetSize());
127  }
128  else
129  {
130  m_data.RemoveAtEnd(m_data.GetSize() - dataLength);
131  }
132 
133  i = m_data.Begin();
134  i.Write(data, dataLength);
135 
136  delete[] data;
137  return GetSerializedSize();
138 }
139 
140 OptionField::OptionField(uint32_t optionsOffset)
141  : m_optionData(0),
142  m_optionsOffset(optionsOffset)
143 {
144 }
145 
147 {
148 }
149 
150 uint32_t
152 {
154 }
155 
156 void
158 {
160  uint32_t fill = CalculatePad((Ipv6OptionHeader::Alignment){8, 0});
161  NS_LOG_LOGIC("fill with " << fill << " bytes padding");
162  switch (fill)
163  {
164  case 0:
165  return;
166  case 1:
168  return;
169  default:
171  return;
172  }
173 }
174 
175 uint32_t
177 {
178  auto buf = new uint8_t[length];
179  start.Read(buf, length);
180  m_optionData = Buffer();
181  m_optionData.AddAtEnd(length);
182  m_optionData.Begin().Write(buf, length);
183  delete[] buf;
184  return length;
185 }
186 
187 void
189 {
190  NS_LOG_FUNCTION(option);
191 
192  uint32_t pad = CalculatePad(option.GetAlignment());
193  NS_LOG_LOGIC("need " << pad << " bytes padding");
194  switch (pad)
195  {
196  case 0:
197  break; // no padding needed
198  case 1:
200  break;
201  default:
203  break;
204  }
205 
208  it.Prev(option.GetSerializedSize());
209  option.Serialize(it);
210 }
211 
212 uint32_t
214 {
215  return (alignment.offset - (m_optionData.GetSize() + m_optionsOffset)) % alignment.factor;
216 }
217 
218 uint32_t
220 {
221  return m_optionsOffset;
222 }
223 
224 Buffer
226 {
227  return m_optionData;
228 }
229 
231 
232 TypeId
234 {
235  static TypeId tid = TypeId("ns3::Ipv6ExtensionHopByHopHeader")
237  .SetParent<Ipv6ExtensionHeader>()
238  .SetGroupName("Internet");
239  return tid;
240 }
241 
242 TypeId
244 {
245  return GetTypeId();
246 }
247 
249  : OptionField(2)
250 {
251 }
252 
254 {
255 }
256 
257 void
258 Ipv6ExtensionHopByHopHeader::Print(std::ostream& os) const
259 {
260  os << "( nextHeader = " << (uint32_t)GetNextHeader() << " length = " << (uint32_t)GetLength()
261  << " )";
262 }
263 
264 uint32_t
266 {
267  return 2 + OptionField::GetSerializedSize();
268 }
269 
270 void
272 {
274 
275  i.WriteU8(GetNextHeader());
276  i.WriteU8((GetSerializedSize() >> 3) - 1);
278 }
279 
280 uint32_t
282 {
284 
285  SetNextHeader(i.ReadU8());
286  m_length = i.ReadU8();
288 
289  return GetSerializedSize();
290 }
291 
293 
294 TypeId
296 {
297  static TypeId tid = TypeId("ns3::Ipv6ExtensionDestinationHeader")
299  .SetParent<Ipv6ExtensionHeader>()
300  .SetGroupName("Internet");
301  return tid;
302 }
303 
304 TypeId
306 {
307  return GetTypeId();
308 }
309 
311  : OptionField(2)
312 {
313 }
314 
316 {
317 }
318 
319 void
321 {
322  os << "( nextHeader = " << (uint32_t)GetNextHeader() << " length = " << (uint32_t)GetLength()
323  << " )";
324 }
325 
326 uint32_t
328 {
329  return 2 + OptionField::GetSerializedSize();
330 }
331 
332 void
334 {
336 
337  i.WriteU8(GetNextHeader());
338  i.WriteU8((GetSerializedSize() >> 3) - 1);
340 }
341 
342 uint32_t
344 {
346 
347  SetNextHeader(i.ReadU8());
348  m_length = i.ReadU8();
350 
351  return GetSerializedSize();
352 }
353 
355 
356 TypeId
358 {
359  static TypeId tid = TypeId("ns3::Ipv6ExtensionFragmentHeader")
361  .SetParent<Ipv6ExtensionHeader>()
362  .SetGroupName("Internet");
363  return tid;
364 }
365 
366 TypeId
368 {
369  return GetTypeId();
370 }
371 
373  : m_offset(0),
374  m_identification(0)
375 {
376  m_length = 0;
377 }
378 
380 {
381 }
382 
383 void
385 {
386  // Clear the offset, and save the MF bit
387  m_offset &= 1;
388  m_offset |= offset & (~7);
389 }
390 
391 uint16_t
393 {
394  return m_offset & (~1);
395 }
396 
397 void
399 {
400  m_offset = moreFragment ? m_offset | 1 : m_offset & (~1);
401 }
402 
403 bool
405 {
406  return m_offset & 1;
407 }
408 
409 void
411 {
412  m_identification = identification;
413 }
414 
415 uint32_t
417 {
418  return m_identification;
419 }
420 
421 void
422 Ipv6ExtensionFragmentHeader::Print(std::ostream& os) const
423 {
424  os << "( nextHeader = " << (uint32_t)GetNextHeader() << " length = " << (uint32_t)GetLength()
425  << " offset = " << (uint32_t)GetOffset() << " MF = " << (uint32_t)GetMoreFragment()
426  << " identification = " << (uint32_t)m_identification << " )";
427 }
428 
429 uint32_t
431 {
432  return 8;
433 }
434 
435 void
437 {
439 
440  i.WriteU8(GetNextHeader());
441  // Fragment header does not carry an extension length
442  i.WriteU8(0);
445 }
446 
447 uint32_t
449 {
451 
452  SetNextHeader(i.ReadU8());
453  // Fragment header does not carry an extension length
454  i.ReadU8();
455  m_offset = i.ReadNtohU16();
457 
458  return GetSerializedSize();
459 }
460 
462 
463 TypeId
465 {
466  static TypeId tid = TypeId("ns3::Ipv6ExtensionRoutingHeader")
468  .SetParent<Ipv6ExtensionHeader>()
469  .SetGroupName("Internet");
470  return tid;
471 }
472 
473 TypeId
475 {
476  return GetTypeId();
477 }
478 
480  : m_typeRouting(0),
481  m_segmentsLeft(0)
482 {
483 }
484 
486 {
487 }
488 
489 void
491 {
492  m_typeRouting = typeRouting;
493 }
494 
495 uint8_t
497 {
498  return m_typeRouting;
499 }
500 
501 void
503 {
504  m_segmentsLeft = segmentsLeft;
505 }
506 
507 uint8_t
509 {
510  return m_segmentsLeft;
511 }
512 
513 void
514 Ipv6ExtensionRoutingHeader::Print(std::ostream& os) const
515 {
516  os << "( nextHeader = " << (uint32_t)GetNextHeader() << " length = " << (uint32_t)GetLength()
517  << " typeRouting = " << (uint32_t)m_typeRouting
518  << " segmentsLeft = " << (uint32_t)m_segmentsLeft << " )";
519 }
520 
521 uint32_t
523 {
524  return 4;
525 }
526 
527 void
529 {
531 
532  i.WriteU8(GetNextHeader());
533  i.WriteU8(m_length);
536 }
537 
538 uint32_t
540 {
542 
543  SetNextHeader(i.ReadU8());
544  m_length = i.ReadU8();
545  m_typeRouting = i.ReadU8();
546  m_segmentsLeft = i.ReadU8();
547 
548  return GetSerializedSize();
549 }
550 
552 
553 TypeId
555 {
556  static TypeId tid = TypeId("ns3::Ipv6ExtensionLooseRoutingHeader")
558  .SetParent<Ipv6ExtensionRoutingHeader>()
559  .SetGroupName("Internet");
560  return tid;
561 }
562 
563 TypeId
565 {
566  return GetTypeId();
567 }
568 
570  : m_routersAddress(0)
571 {
572 }
573 
575 {
576 }
577 
578 void
580 {
581  m_routersAddress.clear();
582  m_routersAddress.assign(n, Ipv6Address(""));
583 }
584 
585 void
586 Ipv6ExtensionLooseRoutingHeader::SetRoutersAddress(std::vector<Ipv6Address> routersAddress)
587 {
588  m_routersAddress = routersAddress;
589 }
590 
591 std::vector<Ipv6Address>
593 {
594  return m_routersAddress;
595 }
596 
597 void
599 {
600  m_routersAddress.at(index) = addr;
601 }
602 
605 {
606  return m_routersAddress.at(index);
607 }
608 
609 void
611 {
612  os << "( nextHeader = " << (uint32_t)GetNextHeader() << " length = " << (uint32_t)GetLength()
613  << " typeRouting = " << (uint32_t)GetTypeRouting()
614  << " segmentsLeft = " << (uint32_t)GetSegmentsLeft() << " ";
615 
616  for (auto it = m_routersAddress.begin(); it != m_routersAddress.end(); it++)
617  {
618  os << *it << " ";
619  }
620 
621  os << " )";
622 }
623 
624 uint32_t
626 {
627  return 8 + m_routersAddress.size() * 16;
628 }
629 
630 void
632 {
634  uint8_t buff[16];
635 
636  uint8_t addressNum = m_routersAddress.size();
637 
638  i.WriteU8(GetNextHeader());
639  i.WriteU8(addressNum * 2);
640  i.WriteU8(GetTypeRouting());
642  i.WriteU32(0);
643 
644  for (auto it = m_routersAddress.begin(); it != m_routersAddress.end(); it++)
645  {
646  it->Serialize(buff);
647  i.Write(buff, 16);
648  }
649 }
650 
651 uint32_t
653 {
655  uint8_t buff[16];
656 
657  SetNextHeader(i.ReadU8());
658  m_length = i.ReadU8();
659  SetTypeRouting(i.ReadU8());
660  SetSegmentsLeft(i.ReadU8());
661  i.ReadU32();
662 
663  uint8_t addressNum = m_length / 2;
664  SetNumberAddress(addressNum);
665  for (uint8_t index = 0; index < addressNum; index++)
666  {
667  i.Read(buff, 16);
668  SetRouterAddress(index, Ipv6Address(buff));
669  }
670 
671  return GetSerializedSize();
672 }
673 
675 
676 TypeId
678 {
679  static TypeId tid = TypeId("ns3::Ipv6ExtensionESPHeader")
681  .SetParent<Ipv6ExtensionHeader>()
682  .SetGroupName("Internet");
683  return tid;
684 }
685 
686 TypeId
688 {
689  return GetTypeId();
690 }
691 
693 {
694 }
695 
697 {
698 }
699 
700 void
701 Ipv6ExtensionESPHeader::Print(std::ostream& os) const
702 {
704 }
705 
706 uint32_t
708 {
710  return 0;
711 }
712 
713 void
715 {
717 }
718 
719 uint32_t
721 {
723  return 0;
724 }
725 
727 
728 TypeId
730 {
731  static TypeId tid = TypeId("ns3::Ipv6ExtensionAHHeader")
733  .SetParent<Ipv6ExtensionHeader>()
734  .SetGroupName("Internet");
735  return tid;
736 }
737 
738 TypeId
740 {
741  return GetTypeId();
742 }
743 
745 {
746 }
747 
749 {
750 }
751 
752 void
753 Ipv6ExtensionAHHeader::Print(std::ostream& os) const
754 {
756 }
757 
758 uint32_t
760 {
762  return 0;
763 }
764 
765 void
767 {
769 }
770 
771 uint32_t
773 {
775  return 0;
776 }
777 
778 } /* namespace ns3 */
iterator in a Buffer instance
Definition: buffer.h:100
void WriteU32(uint32_t data)
Definition: buffer.cc:868
uint8_t ReadU8()
Definition: buffer.h:1027
void WriteU8(uint8_t data)
Definition: buffer.h:881
void Write(const uint8_t *buffer, uint32_t size)
Definition: buffer.cc:948
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1125
void WriteHtonU16(uint16_t data)
Definition: buffer.h:915
uint32_t ReadNtohU32()
Definition: buffer.h:978
uint32_t ReadU32()
Definition: buffer.cc:966
void WriteHtonU32(uint32_t data)
Definition: buffer.h:933
uint16_t ReadNtohU16()
Definition: buffer.h:954
void Prev()
go backward by one byte
Definition: buffer.h:860
automatically resized byte buffer
Definition: buffer.h:94
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:493
uint32_t GetSize() const
Definition: buffer.h:1068
Buffer::Iterator Begin() const
Definition: buffer.h:1074
void AddAtEnd(uint32_t end)
Definition: buffer.cc:360
Buffer::Iterator End() const
Definition: buffer.h:1081
const uint8_t * PeekData() const
Definition: buffer.cc:703
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Deserialize the object from a buffer iterator.
Describes an IPv6 address.
Definition: ipv6-address.h:49
Header of IPv6 Extension AH.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
~Ipv6ExtensionAHHeader() override
Destructor.
static TypeId GetTypeId()
Get the type identificator.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
void Print(std::ostream &os) const override
Print some information about the packet.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
Header of IPv6 Extension Destination.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
~Ipv6ExtensionDestinationHeader() override
Destructor.
void Print(std::ostream &os) const override
Print some information about the packet.
static TypeId GetTypeId()
Get the type identificator.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
Header of IPv6 Extension ESP.
static TypeId GetTypeId()
Get the type identificator.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
void Print(std::ostream &os) const override
Print some information about the packet.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
~Ipv6ExtensionESPHeader() override
Destructor.
Header of IPv6 Extension Fragment.
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 GetSerializedSize() const override
Get the serialized size of the packet.
uint32_t m_identification
Identifier of the packet.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
void Print(std::ostream &os) const override
Print some information about the packet.
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".
~Ipv6ExtensionFragmentHeader() override
Destructor.
void SetMoreFragment(bool moreFragment)
Set the status of "More Fragment" bit.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
Header for IPv6 Extension.
void Print(std::ostream &os) const override
Print some information about the packet.
uint8_t m_nextHeader
The "next header" field.
uint16_t GetLength() const
Get the length of the extension.
uint32_t GetSerializedSize() const override
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.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
~Ipv6ExtensionHeader() override
Destructor.
void SetNextHeader(uint8_t nextHeader)
Set the "Next header" field.
uint8_t GetNextHeader() const
Get the next header.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
uint8_t m_length
The "length" field.
Header of IPv6 Extension "Hop by Hop".
static TypeId GetTypeId()
Get the type identificator.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
~Ipv6ExtensionHopByHopHeader() override
Destructor.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
void Print(std::ostream &os) const override
Print some information about the packet.
Header of IPv6 Extension Routing : Type 0 (Loose Routing)
void Print(std::ostream &os) const override
Print some information about the packet.
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.
VectorIpv6Address_t m_routersAddress
The vector of Routers' IPv6 Address.
Ipv6Address GetRouterAddress(uint8_t index) const
Get a Router IPv6 Address.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
~Ipv6ExtensionLooseRoutingHeader() override
Destructor.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
void SetRouterAddress(uint8_t index, Ipv6Address addr)
Set a Router IPv6 Address.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
void SetNumberAddress(uint8_t n)
Set the number of routers' address.
Header of IPv6 Extension Routing.
void SetTypeRouting(uint8_t typeRouting)
Set the "Type of Routing" field.
uint8_t m_typeRouting
Type of routing.
uint8_t GetTypeRouting() const
Get the field "Type of Routing".
uint8_t GetSegmentsLeft() const
Get the field "Segments left".
static TypeId GetTypeId()
Get the type identificator.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
void SetSegmentsLeft(uint8_t segmentsLeft)
Set the "Segments left" field.
uint8_t m_segmentsLeft
Number of left segments.
void Print(std::ostream &os) const override
Print some information about the packet.
~Ipv6ExtensionRoutingHeader() override
Destructor.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Header for IPv6 Option.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
virtual Alignment GetAlignment() const
Get the Alignment requirement of this option header.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Header of IPv6 Option Pad1.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
Header of IPv6 Option Padn.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
Option field for an IPv6ExtensionHeader.
uint32_t GetSerializedSize() const
Get the serialized size of the packet.
uint32_t CalculatePad(Ipv6OptionHeader::Alignment alignment) const
Calculate padding.
void Serialize(Buffer::Iterator start) const
Serialize all added options.
uint32_t GetOptionsOffset() const
Get the offset where the options begin, measured from the start of the extension header.
uint32_t Deserialize(Buffer::Iterator start, uint32_t length)
Deserialize the packet.
Buffer GetOptionBuffer()
Get the buffer.
Buffer m_optionData
Data payload.
OptionField(uint32_t optionsOffset)
Constructor.
uint32_t m_optionsOffset
Offset.
void AddOption(const Ipv6OptionHeader &option)
Serialize the option, prepending pad1 or padn option as necessary.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId AddConstructor()
Record in this TypeId the fact that the default constructor is accessible.
Definition: type-id.h:651
#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:86
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:46
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint8_t data[writeSize]
represents the alignment requirements of an option header