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/tcp-option-rfc793.h"
27
28using namespace ns3;
29
30#define GET_RANDOM_UINT32(RandomVariable) \
31 static_cast<uint32_t> (RandomVariable->GetInteger (0, UINT32_MAX))
32
33#define GET_RANDOM_UINT16(RandomVariable) \
34 static_cast<uint16_t> (RandomVariable->GetInteger (0, UINT16_MAX))
35
36#define GET_RANDOM_UINT8(RandomVariable) \
37 static_cast<uint8_t> (RandomVariable->GetInteger (0, UINT8_MAX))
38
39#define GET_RANDOM_UINT6(RandomVariable) \
40 static_cast<uint8_t> (RandomVariable->GetInteger (0, UINT8_MAX >> 2))
41
42
43
51{
52public:
57 TcpHeaderGetSetTestCase (std::string name);
58protected:
59private:
60 virtual void DoRun (void);
61 virtual void DoTeardown (void);
62
63};
64
66{
67}
68
70{
71 uint16_t sourcePort; // Source port
72 uint16_t destinationPort; // Destination port
73 SequenceNumber32 sequenceNumber; // Sequence number
74 SequenceNumber32 ackNumber; // ACK number
75 uint8_t flags; // Flags (really a uint6_t)
76 uint16_t windowSize; // Window size
77 uint16_t urgentPointer; // Urgent pointer
78 TcpHeader header;
79 Buffer buffer;
80
81 Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
82 for (uint32_t i = 0; i < 1000; ++i)
83 {
84 sourcePort = GET_RANDOM_UINT16 (x);
85 destinationPort = GET_RANDOM_UINT16 (x);
86 sequenceNumber = SequenceNumber32 (GET_RANDOM_UINT32 (x));
87 ackNumber = SequenceNumber32 (GET_RANDOM_UINT32 (x));
88 flags = GET_RANDOM_UINT6 (x);
89 windowSize = GET_RANDOM_UINT16 (x);
90 urgentPointer = GET_RANDOM_UINT16 (x);
91
92 header.SetSourcePort (sourcePort);
93 header.SetDestinationPort (destinationPort);
94 header.SetSequenceNumber (sequenceNumber);
95 header.SetAckNumber (ackNumber);
96 header.SetFlags (flags);
97 header.SetWindowSize (windowSize);
98 header.SetUrgentPointer (urgentPointer);
99
100 NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
101 " not 5 word");
102
103 buffer.AddAtStart (header.GetSerializedSize ());
104 header.Serialize (buffer.Begin ());
105
106 NS_TEST_ASSERT_MSG_EQ (sourcePort, header.GetSourcePort (),
107 "Different source port found");
108 NS_TEST_ASSERT_MSG_EQ (destinationPort, header.GetDestinationPort (),
109 "Different destination port found");
110 NS_TEST_ASSERT_MSG_EQ (sequenceNumber, header.GetSequenceNumber (),
111 "Different sequence number found");
112 NS_TEST_ASSERT_MSG_EQ (ackNumber, header.GetAckNumber (),
113 "Different ack number found");
114 NS_TEST_ASSERT_MSG_EQ (flags, header.GetFlags (),
115 "Different flags found");
116 NS_TEST_ASSERT_MSG_EQ (windowSize, header.GetWindowSize (),
117 "Different window size found");
118 NS_TEST_ASSERT_MSG_EQ (urgentPointer, header.GetUrgentPointer (),
119 "Different urgent pointer found");
120
121 NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
122 " not 5 word");
123
124 TcpHeader copyHeader;
125
126 copyHeader.Deserialize (buffer.Begin ());
127
128 NS_TEST_ASSERT_MSG_EQ (sourcePort, copyHeader.GetSourcePort (),
129 "Different source port found in deserialized header");
130 NS_TEST_ASSERT_MSG_EQ (destinationPort, copyHeader.GetDestinationPort (),
131 "Different destination port found in deserialized header");
132 NS_TEST_ASSERT_MSG_EQ (sequenceNumber, copyHeader.GetSequenceNumber (),
133 "Different sequence number found in deserialized header");
134 NS_TEST_ASSERT_MSG_EQ (ackNumber, copyHeader.GetAckNumber (),
135 "Different ack number found in deserialized header");
136 NS_TEST_ASSERT_MSG_EQ (flags, copyHeader.GetFlags (),
137 "Different flags found in deserialized header");
138 NS_TEST_ASSERT_MSG_EQ (windowSize, copyHeader.GetWindowSize (),
139 "Different window size found in deserialized header");
140 NS_TEST_ASSERT_MSG_EQ (urgentPointer, copyHeader.GetUrgentPointer (),
141 "Different urgent pointer found in deserialized header");
142 }
143}
144
146{
147}
148
156{
157public:
162 TcpHeaderWithRFC793OptionTestCase (std::string name);
163
164private:
165 virtual void DoRun (void);
166 virtual void DoTeardown (void);
167
171 void OneOptionAtTime ();
175 void CheckNoPadding ();
180};
181
182
184 : TestCase (name)
185{
186
187}
188
189void
191{
195}
196
197void
199{
200 TcpHeader source, destination;
201 TcpOptionNOP temp;
202 Buffer buffer;
203 buffer.AddAtStart (40);
204
205 Buffer::Iterator i = buffer.Begin ();
206 source.AppendOption (&temp);
207
208 source.Serialize (i);
209
210 i.ReadU8 ();
211 i.WriteU8 (59);
212
213 i = buffer.Begin ();
214 destination.Deserialize (i);
215
216 NS_TEST_ASSERT_MSG_EQ (destination.HasOption (59), false, "Kind 59 registered");
217}
218
219void
221{
222 {
223 TcpOptionNOP oNop1, oNop2, oNop3, oNop4;
224 TcpHeader header;
225 Buffer buffer;
226
227 NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
228 " not 5 word");
229 header.AppendOption (&oNop1);
230 header.AppendOption (&oNop2);
231 header.AppendOption (&oNop3);
232 header.AppendOption (&oNop4);
233
234 NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 6, "Four byte added as option "
235 "are not a word");
236 NS_TEST_ASSERT_MSG_EQ (header.GetSerializedSize (), 24, "Four byte added as option "
237 "are not a word");
238
239 buffer.AddAtStart (header.GetSerializedSize ());
240 header.Serialize (buffer.Begin ());
241
243 buffer.GetSize (), "Header not correctly serialized");
244
245 // Inserted 4 byte NOP, no padding should be present
246 Buffer::Iterator i = buffer.Begin ();
247 i.Next (20);
248
249 for (uint32_t j = 0; j < 4; ++j)
250 {
251 std::stringstream ss;
252 ss << j;
253 uint8_t value = i.ReadU8 ();
254 NS_TEST_ASSERT_MSG_EQ (value, TcpOption::NOP,
255 "NOP not present at position " + ss.str ());
256 }
257 }
258}
259
260void
262{
263 {
264 TcpOptionEnd oEnd;
265 TcpHeader header;
266 Buffer buffer;
267
268 NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
269 " not 5 word");
270 header.AppendOption (&oEnd);
271 NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "Length has changed also for"
272 " END option");
273 NS_TEST_ASSERT_MSG_EQ (header.GetSerializedSize (), 20, "Length has changed also for"
274 " END option");
275
276
277 buffer.AddAtStart (header.GetSerializedSize ());
278 header.Serialize (buffer.Begin ());
279
281 buffer.GetSize (), "Header not correctly serialized");
282 }
283
284 {
285 TcpOptionNOP oNop;
286 TcpHeader header;
287 Buffer buffer;
288
289 NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
290 " not 5 word");
291 header.AppendOption (&oNop);
292 NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 6, "NOP option not handled correctly");
293 NS_TEST_ASSERT_MSG_EQ (header.GetSerializedSize (), 24, "Different length found for"
294 "NOP option");
295
296 buffer.AddAtStart (header.GetSerializedSize ());
297 header.Serialize (buffer.Begin ());
298
300 buffer.GetSize (), "Header not correctly serialized");
301
302 // Inserted only 1 byte NOP, and so implementation should pad; so
303 // the other 3 bytes should be END, PAD, PAD (n.b. PAD is same as END)
304 Buffer::Iterator i = buffer.Begin ();
305 i.Next (20);
306
307 uint8_t value = i.ReadU8 ();
308 NS_TEST_ASSERT_MSG_EQ (value, TcpOption::NOP, "NOP not present at byte 1");
309 value = i.ReadU8 ();
310 NS_TEST_ASSERT_MSG_EQ (value, TcpOption::END, "END not present at byte 2");
311 value = i.ReadU8 ();
312 NS_TEST_ASSERT_MSG_EQ (value, TcpOption::END, "pad not present at byte 3");
313 value = i.ReadU8 ();
314 NS_TEST_ASSERT_MSG_EQ (value, TcpOption::END, "pad not present at byte 4");
315 }
316
317 {
318 TcpOptionMSS oMSS;
319 oMSS.SetMSS (50);
320 TcpHeader header, dest;
321 Buffer buffer;
322
323 NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 5, "TcpHeader without option is"
324 " not 5 word");
325 header.AppendOption (&oMSS);
326 NS_TEST_ASSERT_MSG_EQ (header.GetLength (), 6, "MSS option not handled correctly");
327 NS_TEST_ASSERT_MSG_EQ (header.GetSerializedSize (), 24, "Different length found for"
328 "MSS option");
329
330 buffer.AddAtStart (header.GetSerializedSize ());
331 header.Serialize (buffer.Begin ());
332
334 buffer.GetSize (), "Header not correctly serialized");
335
336 dest.Deserialize (buffer.Begin ());
337 NS_TEST_ASSERT_MSG_EQ (header.HasOption (TcpOption::MSS),
338 true, "MSS option not correctly serialized");
340 "MSS Option not counted in the total");
341 }
342}
343
344
345void
347{
348 uint32_t foo;
349 foo = UINT32_MAX;
350 foo--;
351
352}
353
361{
362public:
367 TcpHeaderFlagsToString (std::string name);
368
369private:
370 virtual void DoRun (void);
371};
372
374 : TestCase (name)
375{
376}
377
378void
380{
381 std::string str, target;
382 str = TcpHeader::FlagsToString (0x0);
383 target = "";
384 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
385 str = TcpHeader::FlagsToString (0x1);
386 target = "FIN";
387 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
388 str = TcpHeader::FlagsToString (0x2);
389 target = "SYN";
390 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
391 str = TcpHeader::FlagsToString (0x4);
392 target = "RST";
393 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
394 str = TcpHeader::FlagsToString (0x8);
395 target = "PSH";
396 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
397 str = TcpHeader::FlagsToString (0x10);
398 target = "ACK";
399 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
400 str = TcpHeader::FlagsToString (0x20);
401 target = "URG";
402 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
403 str = TcpHeader::FlagsToString (0x40);
404 target = "ECE";
405 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
406 str = TcpHeader::FlagsToString (0x80);
407 target = "CWR";
408 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
409 str = TcpHeader::FlagsToString (0x3);
410 target = "FIN|SYN";
411 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
412 str = TcpHeader::FlagsToString (0x5);
413 target = "FIN|RST";
414 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
415 str = TcpHeader::FlagsToString (0xff);
416 target = "FIN|SYN|RST|PSH|ACK|URG|ECE|CWR";
417 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
418 str = TcpHeader::FlagsToString (0xff, ":");
419 target = "FIN:SYN:RST:PSH:ACK:URG:ECE:CWR";
420 NS_TEST_ASSERT_MSG_EQ (str, target, "str " << str << " does not equal target " << target);
421}
422
423
431{
432public:
434 : TestSuite ("tcp-header", UNIT)
435 {
436 AddTestCase (new TcpHeaderGetSetTestCase ("GetSet test cases"), TestCase::QUICK);
437 AddTestCase (new TcpHeaderWithRFC793OptionTestCase ("Test for options in RFC 793"), TestCase::QUICK);
438 AddTestCase (new TcpHeaderFlagsToString ("Test flags to string function"), TestCase::QUICK);
439 }
440
441};
442
444
TCP header Flags to Striing test.
TcpHeaderFlagsToString(std::string name)
Constructor.
virtual void DoRun(void)
Implementation to actually run this TestCase.
TCP header Get/Set test.
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
TcpHeaderGetSetTestCase(std::string name)
Constructor.
virtual void DoRun(void)
Implementation to actually run this TestCase.
TCP header TestSuite.
TCP header with RFC793 Options test.
void OneOptionAtTime()
Check an header with only one kind of option.
TcpHeaderWithRFC793OptionTestCase(std::string name)
Constructor.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void CheckNoPadding()
Check an header for the correct padding.
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
void CheckCorrectDeserialize()
Check the correct header deserialization.
iterator in a Buffer instance
Definition: buffer.h:99
void WriteU8(uint8_t data)
Definition: buffer.h:869
void Next(void)
go forward by one byte
Definition: buffer.h:845
uint8_t ReadU8(void)
Definition: buffer.h:1021
automatically resized byte buffer
Definition: buffer.h:93
uint32_t GetSize(void) const
Definition: buffer.h:1063
void AddAtStart(uint32_t start)
Definition: buffer.cc:309
Buffer::Iterator Begin(void) const
Definition: buffer.h:1069
Header for the Transmission Control Protocol.
Definition: tcp-header.h:45
void SetUrgentPointer(uint16_t urgentPointer)
Set the urgent pointer.
Definition: tcp-header.cc:125
virtual void Serialize(Buffer::Iterator start) const
Definition: tcp-header.cc:315
void SetDestinationPort(uint16_t port)
Set the destination port.
Definition: tcp-header.cc:95
void SetSequenceNumber(SequenceNumber32 sequenceNumber)
Set the sequence Number.
Definition: tcp-header.cc:101
virtual uint32_t GetSerializedSize(void) const
Definition: tcp-header.cc:309
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:143
uint8_t GetLength() const
Get the length in words.
Definition: tcp-header.cc:155
uint16_t GetDestinationPort() const
Get the destination port.
Definition: tcp-header.cc:137
void SetFlags(uint8_t flags)
Set flags of the header.
Definition: tcp-header.cc:113
void SetWindowSize(uint16_t windowSize)
Set the window size.
Definition: tcp-header.cc:119
uint16_t GetWindowSize() const
Get the window size.
Definition: tcp-header.cc:179
uint8_t GetOptionLength() const
Get the total length of appended options.
Definition: tcp-header.cc:161
bool AppendOption(Ptr< const TcpOption > option)
Append an option to the TCP header.
Definition: tcp-header.cc:463
bool HasOption(uint8_t kind) const
Check if the header has the option specified.
Definition: tcp-header.cc:511
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: tcp-header.cc:360
uint16_t GetSourcePort() const
Get the source port.
Definition: tcp-header.cc:131
void SetSourcePort(uint16_t port)
Set the source port.
Definition: tcp-header.cc:89
void SetAckNumber(SequenceNumber32 ackNumber)
Set the ACK number.
Definition: tcp-header.cc:107
uint16_t GetUrgentPointer() const
Get the urgent pointer.
Definition: tcp-header.cc:185
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:173
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:149
Defines the TCP option of kind 0 (end of option list) as in RFC 793
Defines the TCP option of kind 2 (maximum segment size) as in RFC 793
void SetMSS(uint16_t mss)
Set the Maximum Segment Size stored in the Option.
virtual uint32_t GetSerializedSize(void) const
Returns number of bytes required for Option serialization.
Defines the TCP option of kind 1 (no operation) as in RFC 793
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1197
SequenceNumber< uint32_t, int32_t > SequenceNumber32
32 bit Sequence number.
#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:141
Every class exported by the ns3 library is enclosed in the ns3 namespace.
list x
Random number samples.
#define END
End of a line.
static TcpHeaderTestSuite g_TcpHeaderTestSuite
Static variable for test initialization.
#define GET_RANDOM_UINT32(RandomVariable)
#define GET_RANDOM_UINT6(RandomVariable)
#define GET_RANDOM_UINT16(RandomVariable)