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"
25
26namespace ns3
27{
28
29NS_LOG_COMPONENT_DEFINE ("Ipv6ExtensionHeader");
30
31NS_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
59void Ipv6ExtensionHeader::SetNextHeader (uint8_t nextHeader)
60{
61 m_nextHeader = nextHeader;
62}
63
65{
66 return m_nextHeader;
67}
68
69void 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
83void 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);
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
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 ());
148 NS_LOG_LOGIC ("fill with " << fill << " bytes padding");
149 switch (fill)
150 {
151 case 0: return;
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
233void 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
289void 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
379void 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
461void 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
526void Ipv6ExtensionLooseRoutingHeader::SetRoutersAddress (std::vector<Ipv6Address> routersAddress)
527{
528 m_routersAddress = routersAddress;
529}
530
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
546void 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 ());
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
631void 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
678void 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
Describes an IPv6 address.
Definition: ipv6-address.h:50
Header of IPv6 Extension AH.
virtual TypeId GetInstanceTypeId() const
Get the instance type ID.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
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.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize 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.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize 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 uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
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.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize 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 uint32_t Deserialize(Buffer::Iterator start)
Deserialize 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.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize 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 uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
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