A Discrete-Event Network Simulator
API
tcp-header-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014 Natale Patriciello <natale.patriciello@gmail.com>
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  */
19 
20 #define __STDC_LIMIT_MACROS
21 #include <stdint.h>
22 #include "ns3/test.h"
23 #include "ns3/core-module.h"
24 #include "ns3/tcp-header.h"
25 #include "ns3/buffer.h"
26 #include "ns3/private/tcp-option-rfc793.h"
27 
28 namespace ns3 {
29 
31 {
32 public:
33  TcpHeaderGetSetTestCase (uint16_t sourcePort, uint16_t destinationPort,
34  SequenceNumber32 sequenceNumber, SequenceNumber32 ackNumber,
35  uint8_t flags, uint16_t m_windowSize, uint16_t m_urgentPointer,
36  std::string name);
37 protected:
38  uint16_t m_sourcePort;
39  uint16_t m_destinationPort;
42  uint8_t m_flags;
43  uint16_t m_windowSize;
44  uint16_t m_urgentPointer;
45 
46 private:
47  virtual void DoRun (void);
48  virtual void DoTeardown (void);
49 
52 };
53 
55  uint16_t sourcePort, uint16_t destinationPort,
56  SequenceNumber32 sequenceNumber, SequenceNumber32 ackNumber,
57  uint8_t flags, uint16_t windowSize, uint16_t urgentPointer,
58  std::string name) : TestCase (name)
59 {
60  m_sourcePort = sourcePort;
61  m_destinationPort = destinationPort;
62  m_sequenceNumber = sequenceNumber;
63  m_ackNumber = ackNumber;
64  m_flags = flags;
65  m_windowSize = windowSize;
66  m_urgentPointer = urgentPointer;
67 
75 
76  NS_TEST_ASSERT_MSG_EQ (m_header.GetLength (), 5, "TcpHeader without option is"
77  " not 5 word");
78 
81 }
82 
84 {
86  "Different source port found");
88  "Different destination port found");
90  "Different sequence number found");
92  "Different ack number found");
94  "Different flags found");
96  "Different window size found");
98  "Different urgent pointer found");
99 
100  NS_TEST_ASSERT_MSG_EQ (m_header.GetLength (), 5, "TcpHeader without option is"
101  " not 5 word");
102 
103  TcpHeader copyHeader;
104 
105  copyHeader.Deserialize (m_buffer.Begin ());
106 
107  NS_TEST_ASSERT_MSG_EQ (m_sourcePort, copyHeader.GetSourcePort (),
108  "Different source port found in deserialized header");
109  NS_TEST_ASSERT_MSG_EQ (m_destinationPort, copyHeader.GetDestinationPort (),
110  "Different destination port found in deserialized header");
111  NS_TEST_ASSERT_MSG_EQ (m_sequenceNumber, copyHeader.GetSequenceNumber (),
112  "Different sequence number found in deserialized header");
113  NS_TEST_ASSERT_MSG_EQ (m_ackNumber, copyHeader.GetAckNumber (),
114  "Different ack number found in deserialized header");
115  NS_TEST_ASSERT_MSG_EQ (m_flags, copyHeader.GetFlags (),
116  "Different flags found in deserialized header");
117  NS_TEST_ASSERT_MSG_EQ (m_windowSize, copyHeader.GetWindowSize (),
118  "Different window size found in deserialized header");
119  NS_TEST_ASSERT_MSG_EQ (m_urgentPointer, copyHeader.GetUrgentPointer (),
120  "Different urgent pointer found in deserialized header");
121 }
122 
124 {
125 
126 }
127 
129 {
130 public:
131  TcpHeaderWithRFC793OptionTestCase (std::string name);
132 
133 private:
134  virtual void DoRun (void);
135  virtual void DoTeardown (void);
136 
141  void OneOptionAtTime ();
142  void CheckNoPadding ();
143  void CheckCorrectDeserialize ();
144 };
145 
146 
148  : TestCase (name)
149 {
150 
151 }
152 
153 void
155 {
156  OneOptionAtTime ();
157  CheckNoPadding ();
159 }
160 
161 void
163 {
164  TcpHeader source, destination;
165  TcpOptionNOP temp;
166  Buffer buffer;
167  buffer.AddAtStart (40);
168 
169  Buffer::Iterator i = buffer.Begin ();
170  source.AppendOption (&temp);
171 
172  source.Serialize (i);
173 
174  i.ReadU8 ();
175  i.WriteU8 (59);
176 
177  i = buffer.Begin ();
178  destination.Deserialize (i);
179 
180  NS_TEST_ASSERT_MSG_EQ (destination.HasOption (59), false, "Kind 59 registered");
181 }
182 
183 void
185 {
186  {
187  TcpOptionNOP oNop1, oNop2, oNop3, oNop4;
188  TcpHeader header;
189  Buffer buffer;
190 
191  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
192  " not 5 word");
193  header.AppendOption (&oNop1);
194  header.AppendOption (&oNop2);
195  header.AppendOption (&oNop3);
196  header.AppendOption (&oNop4);
197 
198  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 6, "Four byte added as option "
199  "are not a word");
200  NS_TEST_ASSERT_MSG_EQ (header.GetSerializedSize (), 24, "Four byte added as option "
201  "are not a word");
202 
203  buffer.AddAtStart (header.GetSerializedSize ());
204  header.Serialize (buffer.Begin ());
205 
207  buffer.GetSize (), "Header not correctly serialized");
208 
209  // Inserted 4 byte NOP, no padding should be present
210  Buffer::Iterator i = buffer.Begin ();
211  i.Next (20);
212 
213  for (uint32_t j = 0; j < 4; ++j)
214  {
215  std::stringstream ss;
216  ss << j;
217  uint8_t value = i.ReadU8 ();
219  "NOP not present at position " + ss.str ());
220  }
221  }
222 }
223 
224 void
226 {
227  {
228  TcpOptionEnd oEnd;
229  TcpHeader header;
230  Buffer buffer;
231 
232  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
233  " not 5 word");
234  header.AppendOption (&oEnd);
235  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "Length has changed also for"
236  " END option");
237  NS_TEST_ASSERT_MSG_EQ (header.GetSerializedSize (), 20, "Length has changed also for"
238  " END option");
239 
240 
241  buffer.AddAtStart (header.GetSerializedSize ());
242  header.Serialize (buffer.Begin ());
243 
245  buffer.GetSize (), "Header not correctly serialized");
246  }
247 
248  {
249  TcpOptionNOP oNop;
250  TcpHeader header;
251  Buffer buffer;
252 
253  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
254  " not 5 word");
255  header.AppendOption (&oNop);
256  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 6, "NOP option not handled correctly");
257  NS_TEST_ASSERT_MSG_EQ (header.GetSerializedSize (), 24, "Different length found for"
258  "NOP option");
259 
260  buffer.AddAtStart (header.GetSerializedSize ());
261  header.Serialize (buffer.Begin ());
262 
264  buffer.GetSize (), "Header not correctly serialized");
265 
266  // Inserted only 1 byte NOP, and so implementation should pad; so
267  // the other 3 bytes should be END, PAD, PAD (n.b. PAD is same as END)
268  Buffer::Iterator i = buffer.Begin ();
269  i.Next (20);
270 
271  uint8_t value = i.ReadU8 ();
272  NS_TEST_ASSERT_MSG_EQ (value, TcpOption::NOP, "NOP not present at byte 1");
273  value = i.ReadU8 ();
274  NS_TEST_ASSERT_MSG_EQ (value, TcpOption::END, "END not present at byte 2");
275  value = i.ReadU8 ();
276  NS_TEST_ASSERT_MSG_EQ (value, TcpOption::END, "pad not present at byte 3");
277  value = i.ReadU8 ();
278  NS_TEST_ASSERT_MSG_EQ (value, TcpOption::END, "pad not present at byte 4");
279  }
280 
281  {
282  TcpOptionMSS oMSS;
283  oMSS.SetMSS (50);
284  TcpHeader header, dest;
285  Buffer buffer;
286 
287  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
288  " not 5 word");
289  header.AppendOption (&oMSS);
290  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 6, "MSS option not handled correctly");
291  NS_TEST_ASSERT_MSG_EQ (header.GetSerializedSize (), 24, "Different length found for"
292  "MSS option");
293 
294  buffer.AddAtStart (header.GetSerializedSize ());
295  header.Serialize (buffer.Begin ());
296 
298  buffer.GetSize (), "Header not correctly serialized");
299 
300  dest.Deserialize (buffer.Begin ());
302  true, "MSS option not correctly serialized");
303  }
304 }
305 
306 
307 void
309 {
310  uint32_t foo;
311  foo = UINT32_MAX;
312  foo--;
313 
314 }
315 
316 #define GET_RANDOM_UINT32(RandomVariable) \
317  static_cast<uint32_t> (RandomVariable->GetInteger (0, UINT32_MAX))
318 
319 #define GET_RANDOM_UINT16(RandomVariable) \
320  static_cast<uint16_t> (RandomVariable->GetInteger (0, UINT16_MAX))
321 
322 #define GET_RANDOM_UINT8(RandomVariable) \
323  static_cast<uint8_t> (RandomVariable->GetInteger (0, UINT8_MAX))
324 
325 #define GET_RANDOM_UINT6(RandomVariable) \
326  static_cast<uint8_t> (RandomVariable->GetInteger (0, UINT8_MAX >> 2))
327 
328 static class TcpHeaderTestSuite : public TestSuite
329 {
330 public:
332  : TestSuite ("tcp-header", UNIT)
333  {
334  Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
335 
336  for (uint32_t i = 0; i < 1000; ++i)
337  {
338  std::stringstream ss;
339  ss << i;
340 
342  GET_RANDOM_UINT16 (x),
345  GET_RANDOM_UINT6 (x),
346  GET_RANDOM_UINT16 (x),
347  GET_RANDOM_UINT16 (x),
348  "Case number " + ss.str ()),
350  }
351 
352  AddTestCase (new TcpHeaderWithRFC793OptionTestCase ("Test for options in RFC 793"),
354  }
355 
357 
358 } // namespace ns3
uint16_t GetDestinationPort() const
Get the destination port.
Definition: tcp-header.cc:109
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:115
void SetMSS(uint16_t mss)
Set the Maximum Segment Size stored in the Option.
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:133
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
Defines the TCP option of kind 1 (no operation) as in RFC 793
Fast test.
Definition: test.h:1110
A suite of tests to run.
Definition: test.h:1270
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:121
automatically resized byte buffer
Definition: buffer.h:92
#define GET_RANDOM_UINT6(RandomVariable)
encapsulates test code
Definition: test.h:1102
This test suite implements a Unit Test.
Definition: test.h:1280
uint16_t m_destinationPort
Destination port.
iterator in a Buffer instance
Definition: buffer.h:98
bool AppendOption(Ptr< TcpOption > option)
Append an option to the TCP header.
Definition: tcp-header.cc:453
ns3::TcpHeaderTestSuite g_TcpHeaderTestSuite
uint16_t m_urgentPointer
Urgent pointer.
void SetSequenceNumber(SequenceNumber32 sequenceNumber)
Set the sequence Number.
Definition: tcp-header.cc:73
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:184
uint16_t GetWindowSize() const
Get the window size.
Definition: tcp-header.cc:139
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:152
virtual void DoRun(void)
Implementation to actually run this TestCase.
Defines the TCP option of kind 0 (end of option list) as in RFC 793
void Next(void)
go forward by one byte
Definition: buffer.h:852
Buffer::Iterator Begin(void) const
Definition: buffer.h:1076
void SetDestinationPort(uint16_t port)
Set the destination port.
Definition: tcp-header.cc:67
void SetFlags(uint8_t flags)
Set flags of the header.
Definition: tcp-header.cc:85
void OneOptionAtTime()
Check an header with only one kind of option.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:44
uint16_t m_windowSize
Window size.
void SetSourcePort(uint16_t port)
Set the source port.
Definition: tcp-header.cc:61
uint8_t m_flags
Flags (really a uint6_t)
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
void SetUrgentPointer(uint16_t urgentPointer)
Set the urgent pointer.
Definition: tcp-header.cc:97
TcpHeaderGetSetTestCase(uint16_t sourcePort, uint16_t destinationPort, SequenceNumber32 sequenceNumber, SequenceNumber32 ackNumber, uint8_t flags, uint16_t m_windowSize, uint16_t m_urgentPointer, std::string name)
uint32_t GetSize(void) const
Definition: buffer.h:1070
virtual uint32_t GetSerializedSize(void) const
Definition: tcp-header.cc:302
uint8_t GetLength() const
Get the length in words.
Definition: tcp-header.cc:127
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: tcp-header.cc:353
uint16_t m_sourcePort
Source port.
#define GET_RANDOM_UINT16(RandomVariable)
SequenceNumber32 m_ackNumber
ACK number.
void WriteU8(uint8_t data)
Definition: buffer.h:876
SequenceNumber32 m_sequenceNumber
Sequence number.
void SetAckNumber(SequenceNumber32 ackNumber)
Set the ACK number.
Definition: tcp-header.cc:79
#define GET_RANDOM_UINT32(RandomVariable)
Defines the TCP option of kind 2 (maximum segment size) as in RFC 793
uint8_t ReadU8(void)
Definition: buffer.h:1028
uint16_t GetSourcePort() const
Get the source port.
Definition: tcp-header.cc:103
bool AddAtStart(uint32_t start)
Definition: buffer.cc:309
bool HasOption(uint8_t kind) const
Check if the header has the option specified.
Definition: tcp-header.cc:495
void SetWindowSize(uint16_t windowSize)
Set the window size.
Definition: tcp-header.cc:91
virtual void DoRun(void)
Implementation to actually run this TestCase.
uint16_t GetUrgentPointer() const
Get the urgent pointer.
Definition: tcp-header.cc:145
virtual void Serialize(Buffer::Iterator start) const
Definition: tcp-header.cc:308