A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
27 #include "../src/internet/model/tcp-option-rfc793.h"
28 
29 namespace ns3 {
30 
32 {
33 public:
34  TcpHeaderGetSetTestCase (uint16_t sourcePort, uint16_t destinationPort,
35  SequenceNumber32 sequenceNumber, SequenceNumber32 ackNumber,
36  uint8_t flags, uint16_t m_windowSize, uint16_t m_urgentPointer,
37  std::string name);
38 protected:
39  uint16_t m_sourcePort;
40  uint16_t m_destinationPort;
43  uint8_t m_flags;
44  uint16_t m_windowSize;
45  uint16_t m_urgentPointer;
46 
47 private:
48  virtual void DoRun (void);
49  virtual void DoTeardown (void);
50 
53 };
54 
56  uint16_t sourcePort, uint16_t destinationPort,
57  SequenceNumber32 sequenceNumber, SequenceNumber32 ackNumber,
58  uint8_t flags, uint16_t windowSize, uint16_t urgentPointer,
59  std::string name) : TestCase (name)
60 {
61  m_sourcePort = sourcePort;
62  m_destinationPort = destinationPort;
63  m_sequenceNumber = sequenceNumber;
64  m_ackNumber = ackNumber;
65  m_flags = flags;
66  m_windowSize = windowSize;
67  m_urgentPointer = urgentPointer;
68 
76 
77  NS_TEST_ASSERT_MSG_EQ (m_header.GetLength (), 5, "TcpHeader without option is"
78  " not 5 word");
79 
82 }
83 
85 {
87  "Different source port found");
89  "Different destination port found");
91  "Different sequence number found");
93  "Different ack number found");
95  "Different flags found");
97  "Different window size found");
99  "Different urgent pointer found");
100 
101  NS_TEST_ASSERT_MSG_EQ (m_header.GetLength (), 5, "TcpHeader without option is"
102  " not 5 word");
103 
104  TcpHeader copyHeader;
105 
106  copyHeader.Deserialize (m_buffer.Begin ());
107 
108  NS_TEST_ASSERT_MSG_EQ (m_sourcePort, copyHeader.GetSourcePort (),
109  "Different source port found in deserialized header");
110  NS_TEST_ASSERT_MSG_EQ (m_destinationPort, copyHeader.GetDestinationPort (),
111  "Different destination port found in deserialized header");
112  NS_TEST_ASSERT_MSG_EQ (m_sequenceNumber, copyHeader.GetSequenceNumber (),
113  "Different sequence number found in deserialized header");
114  NS_TEST_ASSERT_MSG_EQ (m_ackNumber, copyHeader.GetAckNumber (),
115  "Different ack number found in deserialized header");
116  NS_TEST_ASSERT_MSG_EQ (m_flags, copyHeader.GetFlags (),
117  "Different flags found in deserialized header");
118  NS_TEST_ASSERT_MSG_EQ (m_windowSize, copyHeader.GetWindowSize (),
119  "Different window size found in deserialized header");
120  NS_TEST_ASSERT_MSG_EQ (m_urgentPointer, copyHeader.GetUrgentPointer (),
121  "Different urgent pointer found in deserialized header");
122 }
123 
125 {
126 
127 }
128 
130 {
131 public:
132  TcpHeaderWithRFC793OptionTestCase (std::string name);
133 
134 private:
135  virtual void DoRun (void);
136  virtual void DoTeardown (void);
137 
142  void OneOptionAtTime ();
143  void CheckNoPadding ();
144  void CheckCorrectDeserialize ();
145 };
146 
147 
149  : TestCase (name)
150 {
151 
152 }
153 
154 void
156 {
157  OneOptionAtTime ();
158  CheckNoPadding ();
160 }
161 
162 void
164 {
165  TcpHeader source, destination;
166  TcpOptionNOP temp;
167  Buffer buffer;
168  buffer.AddAtStart (40);
169 
170  Buffer::Iterator i = buffer.Begin ();
171  source.AppendOption (&temp);
172 
173  source.Serialize (i);
174 
175  i.ReadU8 ();
176  i.WriteU8 (59);
177 
178  i = buffer.Begin ();
179  destination.Deserialize (i);
180 
181  NS_TEST_ASSERT_MSG_EQ (destination.HasOption (59), false, "Kind 59 registered");
182 }
183 
184 void
186 {
187  {
188  TcpOptionNOP oNop1, oNop2, oNop3, oNop4;
189  TcpHeader header;
190  Buffer buffer;
191 
192  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
193  " not 5 word");
194  header.AppendOption (&oNop1);
195  header.AppendOption (&oNop2);
196  header.AppendOption (&oNop3);
197  header.AppendOption (&oNop4);
198 
199  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 6, "Four byte added as option "
200  "are not a word");
201  NS_TEST_ASSERT_MSG_EQ (header.GetSerializedSize (), 24, "Four byte added as option "
202  "are not a word");
203 
204  buffer.AddAtStart (header.GetSerializedSize ());
205  header.Serialize (buffer.Begin ());
206 
208  buffer.GetSize (), "Header not correctly serialized");
209 
210  // Inserted 4 byte NOP, no padding should be present
211  Buffer::Iterator i = buffer.Begin ();
212  i.Next (20);
213 
214  for (uint32_t j = 0; j < 4; ++j)
215  {
216  std::stringstream ss;
217  ss << j;
218  uint8_t value = i.ReadU8 ();
220  "NOP not present at position " + ss.str ());
221  }
222  }
223 }
224 
225 void
227 {
228  {
229  TcpOptionEnd oEnd;
230  TcpHeader header;
231  Buffer buffer;
232 
233  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
234  " not 5 word");
235  header.AppendOption (&oEnd);
236  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "Length has changed also for"
237  " END option");
238  NS_TEST_ASSERT_MSG_EQ (header.GetSerializedSize (), 20, "Length has changed also for"
239  " END option");
240 
241 
242  buffer.AddAtStart (header.GetSerializedSize ());
243  header.Serialize (buffer.Begin ());
244 
246  buffer.GetSize (), "Header not correctly serialized");
247  }
248 
249  {
250  TcpOptionNOP oNop;
251  TcpHeader header;
252  Buffer buffer;
253 
254  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
255  " not 5 word");
256  header.AppendOption (&oNop);
257  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 6, "NOP option not handled correctly");
258  NS_TEST_ASSERT_MSG_EQ (header.GetSerializedSize (), 24, "Different length found for"
259  "NOP option");
260 
261  buffer.AddAtStart (header.GetSerializedSize ());
262  header.Serialize (buffer.Begin ());
263 
265  buffer.GetSize (), "Header not correctly serialized");
266 
267  // Inserted only 1 byte NOP, and so implementation should pad; so
268  // the other 3 bytes should be END, PAD, PAD (n.b. PAD is same as END)
269  Buffer::Iterator i = buffer.Begin ();
270  i.Next (20);
271 
272  uint8_t value = i.ReadU8 ();
273  NS_TEST_ASSERT_MSG_EQ (value, TcpOption::NOP, "NOP not present at byte 1");
274  value = i.ReadU8 ();
275  NS_TEST_ASSERT_MSG_EQ (value, TcpOption::END, "END not present at byte 2");
276  value = i.ReadU8 ();
277  NS_TEST_ASSERT_MSG_EQ (value, TcpOption::END, "pad not present at byte 3");
278  value = i.ReadU8 ();
279  NS_TEST_ASSERT_MSG_EQ (value, TcpOption::END, "pad not present at byte 4");
280  }
281 
282  {
283  TcpOptionMSS oMSS;
284  oMSS.SetMSS (50);
285  TcpHeader header, dest;
286  Buffer buffer;
287 
288  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
289  " not 5 word");
290  header.AppendOption (&oMSS);
291  NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 6, "MSS option not handled correctly");
292  NS_TEST_ASSERT_MSG_EQ (header.GetSerializedSize (), 24, "Different length found for"
293  "MSS option");
294 
295  buffer.AddAtStart (header.GetSerializedSize ());
296  header.Serialize (buffer.Begin ());
297 
299  buffer.GetSize (), "Header not correctly serialized");
300 
301  dest.Deserialize (buffer.Begin ());
303  true, "MSS option not correctly serialized");
304  }
305 }
306 
307 
308 void
310 {
311  uint32_t foo;
312  foo = UINT32_MAX;
313  foo--;
314 
315 }
316 
317 #define GET_RANDOM_UINT32(RandomVariable) \
318  static_cast<uint32_t> (RandomVariable->GetInteger (0, UINT32_MAX))
319 
320 #define GET_RANDOM_UINT16(RandomVariable) \
321  static_cast<uint16_t> (RandomVariable->GetInteger (0, UINT16_MAX))
322 
323 #define GET_RANDOM_UINT8(RandomVariable) \
324  static_cast<uint8_t> (RandomVariable->GetInteger (0, UINT8_MAX))
325 
326 #define GET_RANDOM_UINT6(RandomVariable) \
327  static_cast<uint8_t> (RandomVariable->GetInteger (0, UINT8_MAX >> 2))
328 
329 static class TcpHeaderTestSuite : public TestSuite
330 {
331 public:
333  : TestSuite ("tcp-header", UNIT)
334  {
335  Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
336 
337  for (uint32_t i = 0; i < 1000; ++i)
338  {
339  std::stringstream ss;
340  ss << i;
341 
343  GET_RANDOM_UINT16 (x),
346  GET_RANDOM_UINT6 (x),
347  GET_RANDOM_UINT16 (x),
348  GET_RANDOM_UINT16 (x),
349  "Case number " + ss.str ()),
351  }
352 
353  AddTestCase (new TcpHeaderWithRFC793OptionTestCase ("Test for options in RFC 793"),
355  }
356 
358 
359 } // 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
A suite of tests to run.
Definition: test.h:1289
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:1113
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
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:148
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.
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)
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual child TestCase case to this TestCase.
Definition: test.cc:184
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
Fast test.
Definition: test.h:1121
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
This test suite implements a Unit Test.
Definition: test.h:1299
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