A Discrete-Event Network Simulator
API
ipv6-extension-header-test-suite.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License version 2 as
4  * published by the Free Software Foundation;
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * Author: Fabian Mauchle <fabian.mauchle@hsr.ch>
16  */
17 
18 #include "ns3/ipv6-extension-header.h"
19 #include "ns3/ipv6-option-header.h"
20 #include "ns3/test.h"
21 
22 using namespace ns3;
23 
24 // ===========================================================================
25 // An empty option field must be filled with pad1 or padN header so theshape
26 // extension header's size is a multiple of 8.
27 //
28 // 0 31
29 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30 // | Extension Destination Header | |
31 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ PadN Header +
32 // | |
33 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 // ===========================================================================
35 
42 {
43  public:
45  : TestCase("TestEmptyOptionField")
46  {
47  }
48 
49  void DoRun() override
50  {
53  0,
54  "length of extension header is not a multiple of 8");
55 
56  Buffer buf;
57  buf.AddAtStart(header.GetSerializedSize());
58  header.Serialize(buf.Begin());
59 
60  const uint8_t* data = buf.PeekData();
61  NS_TEST_EXPECT_MSG_EQ(*(data + 2), 1, "padding is missing"); // expecting a padN header
62  }
63 };
64 
65 // ===========================================================================
66 // An option without alignment requirement must not be padded
67 //
68 // 0 31
69 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70 // | Extension Destination Header | OptionWithoutAlignmentHeader..|
71 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72 // |..OptionWithoutAlignmentHeader | PadN Header |
73 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74 // ===========================================================================
75 
82 {
83  public:
84  static const uint8_t TYPE = 42;
85 
86  uint32_t GetSerializedSize() const override
87  {
88  return 4;
89  }
90 
91  void Serialize(Buffer::Iterator start) const override
92  {
93  start.WriteU8(TYPE);
94  start.WriteU8(GetSerializedSize() - 2);
95  start.WriteU16(0);
96  }
97 };
98 
105 {
106  public:
108  : TestCase("TestOptionWithoutAlignment")
109  {
110  }
111 
112  void DoRun() override
113  {
115  OptionWithoutAlignmentHeader optionHeader;
116  header.AddOption(optionHeader);
117 
119  0,
120  "length of extension header is not a multiple of 8");
121 
122  Buffer buf;
123  buf.AddAtStart(header.GetSerializedSize());
124  header.Serialize(buf.Begin());
125 
126  const uint8_t* data = buf.PeekData();
129  "option without alignment is not first in header field");
130  }
131 };
132 
133 // ===========================================================================
134 // An option with alignment requirement must be padded accordingly (padding to
135 // a total size multiple of 8 is allowed)
136 //
137 // 0 31
138 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
139 // | Extension Destination Header | PadN Header |
140 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
141 // | OptionWithAlignmentHeader |
142 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
143 // | PadN Header | |
144 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
145 // | Ipv6OptionJumbogramHeader |
146 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
147 // ===========================================================================
148 
155 {
156  public:
157  static const uint8_t TYPE = 73;
158 
159  uint32_t GetSerializedSize() const override
160  {
161  return 4;
162  }
163 
164  void Serialize(Buffer::Iterator start) const override
165  {
166  start.WriteU8(TYPE);
167  start.WriteU8(GetSerializedSize() - 2);
168  start.WriteU16(0);
169  }
170 
171  Alignment GetAlignment() const override
172  {
173  return (Alignment){4, 0};
174  }
175 };
176 
183 {
184  public:
186  : TestCase("TestOptionWithAlignment")
187  {
188  }
189 
190  void DoRun() override
191  {
193  OptionWithAlignmentHeader optionHeader;
194  header.AddOption(optionHeader);
195  Ipv6OptionJumbogramHeader jumboHeader; // has an alignment of 4n+2
196  header.AddOption(jumboHeader);
197 
199  0,
200  "length of extension header is not a multiple of 8");
201 
202  Buffer buf;
203  buf.AddAtStart(header.GetSerializedSize());
204  header.Serialize(buf.Begin());
205 
206  const uint8_t* data = buf.PeekData();
207  NS_TEST_EXPECT_MSG_EQ(*(data + 2), 1, "padding is missing"); // expecting a padN header
210  "option with alignment is not padded correctly");
211  NS_TEST_EXPECT_MSG_EQ(*(data + 8), 1, "padding is missing"); // expecting a padN header
212  NS_TEST_EXPECT_MSG_EQ(*(data + 10),
213  jumboHeader.GetType(),
214  "option with alignment is not padded correctly");
215  }
216 };
217 
218 // ===========================================================================
219 // An option with an alignment that exactly matches the gap must not be padded
220 // (padding to a total size multiple of 8 is allowed)
221 //
222 // 0 31
223 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
224 // | Extension Destination Header | |
225 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
226 // | Ipv6OptionJumbogramHeader |
227 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
228 // | OptionWithAlignmentHeader |
229 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
230 // | PadN Header |
231 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
232 // ===========================================================================
233 
240 {
241  public:
243  : TestCase("TestCorrectAlignment")
244  {
245  }
246 
247  void DoRun() override
248  {
250  Ipv6OptionJumbogramHeader jumboHeader; // has an alignment of 4n+2
251  header.AddOption(jumboHeader);
252  OptionWithAlignmentHeader optionHeader;
253  header.AddOption(optionHeader);
254 
256  0,
257  "length of extension header is not a multiple of 8");
258 
259  Buffer buf;
260  buf.AddAtStart(header.GetSerializedSize());
261  header.Serialize(buf.Begin());
262 
263  const uint8_t* data = buf.PeekData();
265  jumboHeader.GetType(),
266  "option with fulfilled alignment is padded anyway");
269  "option with fulfilled alignment is padded anyway");
270  }
271 };
272 
279 {
280  public:
282  : TestSuite("ipv6-extension-header", UNIT)
283  {
284  AddTestCase(new TestEmptyOptionField, TestCase::QUICK);
286  AddTestCase(new TestOptionWithAlignment, TestCase::QUICK);
287  AddTestCase(new TestFulfilledAlignment, TestCase::QUICK);
288  }
289 };
290 
IPv6 extensions Test: Option with alignment.
static const uint8_t TYPE
Option Type.
Alignment GetAlignment() const override
Get the Alignment requirement of this option header.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
IPv6 extensions Test: Option without alignment.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
static const uint8_t TYPE
Option type.
IPv6 extensions Test: Empty option field.
void DoRun() override
Implementation to actually run this TestCase.
IPv6 extensions Test: Test an option already aligned.
void DoRun() override
Implementation to actually run this TestCase.
IPv6 extensions Test: Test the option with alignment.
void DoRun() override
Implementation to actually run this TestCase.
IPv6 extensions Test: Test the option without alignment.
void DoRun() override
Implementation to actually run this TestCase.
iterator in a Buffer instance
Definition: buffer.h:100
automatically resized byte buffer
Definition: buffer.h:94
void AddAtStart(uint32_t start)
Definition: buffer.cc:314
Buffer::Iterator Begin() const
Definition: buffer.h:1074
const uint8_t * PeekData() const
Definition: buffer.cc:703
Header of IPv6 Extension Destination.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
Header for IPv6 Option.
uint8_t GetType() const
Get the type of the option.
Header of IPv6 Option Jumbogram.
void AddOption(const Ipv6OptionHeader &option)
Serialize the option, prepending pad1 or padn option as necessary.
encapsulates test code
Definition: test.h:1060
@ QUICK
Fast test.
Definition: test.h:1065
A suite of tests to run.
Definition: test.h:1256
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:251
static Ipv6ExtensionHeaderTestSuite ipv6ExtensionHeaderTestSuite
Static variable for test initialization.
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