A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ipv6-extension-header-test-suite.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  * Author: Fabian Mauchle <fabian.mauchle@hsr.ch>
17  */
18 
19 #include "ns3/test.h"
20 #include "ns3/ipv6-extension-header.h"
21 #include "ns3/ipv6-option-header.h"
22 
23 using namespace ns3;
24 
25 // ===========================================================================
26 // An empty option field must be filled with pad1 or padN header so theshape
27 // extension header's size is a multiple of 8.
28 //
29 // 0 31
30 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31 // | Extension Destination Header | |
32 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ PadN Header +
33 // | |
34 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35 // ===========================================================================
37 {
38 public:
39  TestEmptyOptionField () : TestCase ("TestEmptyOptionField") {}
40 
41  virtual void DoRun ()
42  {
44  NS_TEST_EXPECT_MSG_EQ (header.GetSerializedSize () % 8, 0, "length of extension header is not a multiple of 8");
45 
46  Buffer buf;
47  buf.AddAtStart (header.GetSerializedSize ());
48  header.Serialize (buf.Begin ());
49 
50  const uint8_t* data = buf.PeekData ();
51  NS_TEST_EXPECT_MSG_EQ (*(data+2), 1, "padding is missing"); //expecting a padN header
52  }
53 };
54 
55 // ===========================================================================
56 // An option without alignment requirement must not be padded
57 //
58 // 0 31
59 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60 // | Extension Destination Header | OptionWithoutAlignmentHeader..|
61 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62 // |..OptionWithoutAlignmentHeader | PadN Header |
63 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64 // ===========================================================================
66 {
67 public:
68  static const uint8_t TYPE = 42;
69  virtual uint32_t GetSerializedSize () const
70  {
71  return 4;
72  }
73 
74  virtual void Serialize (Buffer::Iterator start) const
75  {
76  start.WriteU8 (TYPE);
77  start.WriteU8 (GetSerializedSize ()-2);
78  start.WriteU16 (0);
79  }
80 };
81 
82 
84 {
85 public:
86  TestOptionWithoutAlignment () : TestCase ("TestOptionWithoutAlignment") {}
87 
88  virtual void DoRun ()
89  {
91  OptionWithoutAlignmentHeader optionHeader;
92  header.AddOption (optionHeader);
93 
94 
95  NS_TEST_EXPECT_MSG_EQ (header.GetSerializedSize () % 8, 0, "length of extension header is not a multiple of 8");
96 
97  Buffer buf;
98  buf.AddAtStart (header.GetSerializedSize ());
99  header.Serialize (buf.Begin ());
100 
101  const uint8_t* data = buf.PeekData ();
102  NS_TEST_EXPECT_MSG_EQ (*(data+2), OptionWithoutAlignmentHeader::TYPE, "option without alignment is not first in header field");
103  }
104 };
105 
106 // ===========================================================================
107 // An option with alignment requirement must be padded accordingly (padding to
108 // a total size multiple of 8 is allowed)
109 //
110 // 0 31
111 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
112 // | Extension Destination Header | PadN Header |
113 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
114 // | OptionWithAlignmentHeader |
115 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
116 // | PadN Header | |
117 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
118 // | Ipv6OptionJumbogramHeader |
119 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
120 // ===========================================================================
122 {
123 public:
124  static const uint8_t TYPE = 73;
125  virtual uint32_t GetSerializedSize () const
126  {
127  return 4;
128  }
129 
130  virtual void Serialize (Buffer::Iterator start) const
131  {
132  start.WriteU8 (TYPE);
133  start.WriteU8 (GetSerializedSize ()-2);
134  start.WriteU16 (0);
135  }
136 
137  virtual Alignment GetAlignment () const
138  {
139  return (Alignment){ 4,0};
140  }
141 };
142 
143 
145 {
146 public:
147  TestOptionWithAlignment () : TestCase ("TestOptionWithAlignment") {}
148 
149  virtual void DoRun ()
150  {
152  OptionWithAlignmentHeader optionHeader;
153  header.AddOption (optionHeader);
154  Ipv6OptionJumbogramHeader jumboHeader; //has an alignment of 4n+2
155  header.AddOption (jumboHeader);
156 
157  NS_TEST_EXPECT_MSG_EQ (header.GetSerializedSize () % 8, 0, "length of extension header is not a multiple of 8");
158 
159  Buffer buf;
160  buf.AddAtStart (header.GetSerializedSize ());
161  header.Serialize (buf.Begin ());
162 
163  const uint8_t* data = buf.PeekData ();
164  NS_TEST_EXPECT_MSG_EQ (*(data+2), 1, "padding is missing"); //expecting a padN header
165  NS_TEST_EXPECT_MSG_EQ (*(data+4), OptionWithAlignmentHeader::TYPE, "option with alignment is not padded correctly");
166  NS_TEST_EXPECT_MSG_EQ (*(data+8), 1, "padding is missing"); //expecting a padN header
167  NS_TEST_EXPECT_MSG_EQ (*(data+10), jumboHeader.GetType (), "option with alignment is not padded correctly");
168  }
169 };
170 
171 // ===========================================================================
172 // An option with an alignment that exactly matches the gap must not be padded
173 // (padding to a total size multiple of 8 is allowed)
174 //
175 // 0 31
176 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
177 // | Extension Destination Header | |
178 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
179 // | Ipv6OptionJumbogramHeader |
180 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
181 // | OptionWithAlignmentHeader |
182 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
183 // | PadN Header |
184 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
185 // ===========================================================================
186 
188 {
189 public:
190  TestFulfilledAlignment () : TestCase ("TestCorrectAlignment") {}
191 
192  virtual void DoRun ()
193  {
195  Ipv6OptionJumbogramHeader jumboHeader; //has an alignment of 4n+2
196  header.AddOption (jumboHeader);
197  OptionWithAlignmentHeader optionHeader;
198  header.AddOption (optionHeader);
199 
200  NS_TEST_EXPECT_MSG_EQ (header.GetSerializedSize () % 8, 0, "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), jumboHeader.GetType (), "option with fulfilled alignment is padded anyway");
208  NS_TEST_EXPECT_MSG_EQ (*(data+8), OptionWithAlignmentHeader::TYPE, "option with fulfilled alignment is padded anyway");
209  }
210 };
211 
213 {
214 public:
216  : TestSuite ("ipv6-extension-header", UNIT)
217  {
218  AddTestCase (new TestEmptyOptionField, TestCase::QUICK);
219  AddTestCase (new TestOptionWithoutAlignment, TestCase::QUICK);
220  AddTestCase (new TestOptionWithAlignment, TestCase::QUICK);
221  AddTestCase (new TestFulfilledAlignment, TestCase::QUICK);
222 
223  }
224 };
225 
226 static Ipv6ExtensionHeaderTestSuite ipv6ExtensionHeaderTestSuite;
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
Header for IPv6 Option.
A suite of tests to run.
Definition: test.h:962
automatically resized byte buffer
Definition: buffer.h:92
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
encapsulates test code
Definition: test.h:834
uint8_t GetType() const
Get the type of the option.
represents the alignment requirements of an option header
iterator in a Buffer instance
Definition: buffer.h:98
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
void WriteU16(uint16_t data)
Definition: buffer.cc:895
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual void DoRun()
Implementation to actually run this test case.
Header of IPv6 Option Jumbogram.
virtual void DoRun()
Implementation to actually run this test case.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual void DoRun()
Implementation to actually run this test case.
virtual Alignment GetAlignment() const
Get the Alignment requirement of this option header.
void WriteU8(uint8_t data)
Definition: buffer.h:690
void AddOption(Ipv6OptionHeader const &option)
Serialize the option, prepending pad1 or padn option as necessary.
Header of IPv6 Extension Destination.
bool AddAtStart(uint32_t start)
Definition: buffer.cc:305
virtual void DoRun()
Implementation to actually run this test case.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.