A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
21
22#include "ns3/assert.h"
23#include "ns3/header.h"
24#include "ns3/log.h"
25
26namespace ns3
27{
28
29NS_LOG_COMPONENT_DEFINE("Ipv6ExtensionHeader");
30
31NS_OBJECT_ENSURE_REGISTERED(Ipv6ExtensionHeader);
32
33TypeId
35{
36 static TypeId tid = TypeId("ns3::Ipv6ExtensionHeader")
38 .SetParent<Header>()
39 .SetGroupName("Internet");
40 return tid;
41}
42
45{
46 return GetTypeId();
47}
48
50 : m_length(0),
51 m_nextHeader(0),
52 m_data(0)
53{
54}
55
57{
58}
59
60void
62{
63 m_nextHeader = nextHeader;
64}
65
66uint8_t
68{
69 return m_nextHeader;
70}
71
72void
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
83uint16_t
85{
86 return (m_length + 1) << 3;
87}
88
89void
90Ipv6ExtensionHeader::Print(std::ostream& os) const
91{
92 os << "( nextHeader = " << (uint32_t)GetNextHeader() << " length = " << (uint32_t)GetLength()
93 << " )";
94}
95
98{
99 return 2;
100}
101
102void
104{
105 Buffer::Iterator i = start;
106
108 i.WriteU8(m_length);
110}
111
114{
115 Buffer::Iterator i = start;
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
141 : m_optionData(0),
142 m_optionsOffset(optionsOffset)
143{
144}
145
147{
148}
149
152{
154}
155
156void
158{
159 start.Write(m_optionData.Begin(), m_optionData.End());
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:
170 Ipv6OptionPadnHeader(fill).Serialize(start);
171 return;
172 }
173}
174
177{
178 auto buf = new uint8_t[length];
179 start.Read(buf, length);
181 m_optionData.AddAtEnd(length);
182 m_optionData.Begin().Write(buf, length);
183 delete[] buf;
184 return length;
185}
186
187void
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
214{
215 return (alignment.offset - (m_optionData.GetSize() + m_optionsOffset)) % alignment.factor;
216}
217
220{
221 return m_optionsOffset;
222}
223
224Buffer
226{
227 return m_optionData;
228}
229
231
232TypeId
234{
235 static TypeId tid = TypeId("ns3::Ipv6ExtensionHopByHopHeader")
237 .SetParent<Ipv6ExtensionHeader>()
238 .SetGroupName("Internet");
239 return tid;
240}
241
242TypeId
244{
245 return GetTypeId();
246}
247
249 : OptionField(2)
250{
251}
252
254{
255}
256
257void
259{
260 os << "( nextHeader = " << (uint32_t)GetNextHeader() << " length = " << (uint32_t)GetLength()
261 << " )";
262}
263
266{
268}
269
270void
272{
273 Buffer::Iterator i = start;
274
276 i.WriteU8((GetSerializedSize() >> 3) - 1);
278}
279
282{
283 Buffer::Iterator i = start;
284
286 m_length = i.ReadU8();
288
289 return GetSerializedSize();
290}
291
293
294TypeId
296{
297 static TypeId tid = TypeId("ns3::Ipv6ExtensionDestinationHeader")
299 .SetParent<Ipv6ExtensionHeader>()
300 .SetGroupName("Internet");
301 return tid;
302}
303
304TypeId
306{
307 return GetTypeId();
308}
309
311 : OptionField(2)
312{
313}
314
316{
317}
318
319void
321{
322 os << "( nextHeader = " << (uint32_t)GetNextHeader() << " length = " << (uint32_t)GetLength()
323 << " )";
324}
325
328{
330}
331
332void
334{
335 Buffer::Iterator i = start;
336
338 i.WriteU8((GetSerializedSize() >> 3) - 1);
340}
341
344{
345 Buffer::Iterator i = start;
346
348 m_length = i.ReadU8();
350
351 return GetSerializedSize();
352}
353
355
356TypeId
358{
359 static TypeId tid = TypeId("ns3::Ipv6ExtensionFragmentHeader")
361 .SetParent<Ipv6ExtensionHeader>()
362 .SetGroupName("Internet");
363 return tid;
364}
365
366TypeId
368{
369 return GetTypeId();
370}
371
373 : m_offset(0),
374 m_identification(0)
375{
376 m_length = 0;
377}
378
380{
381}
382
383void
385{
386 // Clear the offset, and save the MF bit
387 m_offset &= 1;
388 m_offset |= offset & (~7);
389}
390
391uint16_t
393{
394 return m_offset & (~1);
395}
396
397void
399{
400 m_offset = moreFragment ? m_offset | 1 : m_offset & (~1);
401}
402
403bool
405{
406 return m_offset & 1;
407}
408
409void
411{
412 m_identification = identification;
413}
414
417{
418 return m_identification;
419}
420
421void
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
431{
432 return 8;
433}
434
435void
437{
438 Buffer::Iterator i = start;
439
441 // Fragment header does not carry an extension length
442 i.WriteU8(0);
445}
446
449{
450 Buffer::Iterator i = start;
451
453 // Fragment header does not carry an extension length
454 i.ReadU8();
455 m_offset = i.ReadNtohU16();
457
458 return GetSerializedSize();
459}
460
462
463TypeId
465{
466 static TypeId tid = TypeId("ns3::Ipv6ExtensionRoutingHeader")
468 .SetParent<Ipv6ExtensionHeader>()
469 .SetGroupName("Internet");
470 return tid;
471}
472
473TypeId
475{
476 return GetTypeId();
477}
478
480 : m_typeRouting(0),
481 m_segmentsLeft(0)
482{
483}
484
486{
487}
488
489void
491{
492 m_typeRouting = typeRouting;
493}
494
495uint8_t
497{
498 return m_typeRouting;
499}
500
501void
503{
504 m_segmentsLeft = segmentsLeft;
505}
506
507uint8_t
509{
510 return m_segmentsLeft;
511}
512
513void
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
523{
524 return 4;
525}
526
527void
529{
530 Buffer::Iterator i = start;
531
533 i.WriteU8(m_length);
536}
537
540{
541 Buffer::Iterator i = start;
542
544 m_length = i.ReadU8();
545 m_typeRouting = i.ReadU8();
547
548 return GetSerializedSize();
549}
550
552
553TypeId
555{
556 static TypeId tid = TypeId("ns3::Ipv6ExtensionLooseRoutingHeader")
558 .SetParent<Ipv6ExtensionRoutingHeader>()
559 .SetGroupName("Internet");
560 return tid;
561}
562
563TypeId
565{
566 return GetTypeId();
567}
568
570 : m_routersAddress(0)
571{
572}
573
575{
576}
577
578void
580{
581 m_routersAddress.clear();
582 m_routersAddress.assign(n, Ipv6Address(""));
583}
584
585void
586Ipv6ExtensionLooseRoutingHeader::SetRoutersAddress(std::vector<Ipv6Address> routersAddress)
587{
588 m_routersAddress = routersAddress;
589}
590
591std::vector<Ipv6Address>
593{
594 return m_routersAddress;
595}
596
597void
599{
600 m_routersAddress.at(index) = addr;
601}
602
605{
606 return m_routersAddress.at(index);
607}
608
609void
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
626{
627 return 8 + m_routersAddress.size() * 16;
628}
629
630void
632{
633 Buffer::Iterator i = start;
634 uint8_t buff[16];
635
636 uint8_t addressNum = m_routersAddress.size();
637
639 i.WriteU8(addressNum * 2);
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
653{
654 Buffer::Iterator i = start;
655 uint8_t buff[16];
656
658 m_length = 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
676TypeId
678{
679 static TypeId tid = TypeId("ns3::Ipv6ExtensionESPHeader")
681 .SetParent<Ipv6ExtensionHeader>()
682 .SetGroupName("Internet");
683 return tid;
684}
685
686TypeId
688{
689 return GetTypeId();
690}
691
693{
694}
695
697{
698}
699
700void
701Ipv6ExtensionESPHeader::Print(std::ostream& os) const
702{
703 /** \todo */
704}
705
708{
709 /** \todo */
710 return 0;
711}
712
713void
715{
716 /** \todo */
717}
718
721{
722 /** \todo */
723 return 0;
724}
725
727
728TypeId
730{
731 static TypeId tid = TypeId("ns3::Ipv6ExtensionAHHeader")
733 .SetParent<Ipv6ExtensionHeader>()
734 .SetGroupName("Internet");
735 return tid;
736}
737
738TypeId
740{
741 return GetTypeId();
742}
743
745{
746}
747
749{
750}
751
752void
753Ipv6ExtensionAHHeader::Print(std::ostream& os) const
754{
755 /** \todo */
756}
757
760{
761 /** \todo */
762 return 0;
763}
764
765void
767{
768 /** \todo */
769}
770
773{
774 /** \todo */
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
Describes an IPv6 address.
Definition: ipv6-address.h:49
Header of IPv6 Extension AH.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize the packet.
~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.
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize the packet.
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.
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize 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.
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize the packet.
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.
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize the packet.
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".
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize 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.
~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.
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize the packet.
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.
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize the packet.
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