blob: d4b839680afe473acf1b0a64e03a51e8b8a6734a [file] [log] [blame]
Vince Lehman277ecf02016-02-10 16:37:48 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2016, University of Memphis.
4 *
5 * This file is part of ndn-tools (Named Data Networking Essential Tools).
6 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
7 *
8 * ndn-tools is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "tools/dump/ndndump.hpp"
21
22#include "tests/test-common.hpp"
23
24#include <boost/test/output_test_stream.hpp>
25
26#include <ndn-cxx/lp/packet.hpp>
27#include <ndn-cxx/security/key-chain.hpp>
28#include <ndn-cxx/util/ethernet.hpp>
29
30namespace ndn {
31namespace dump {
32namespace tests {
33
34using namespace ndn::tests;
35
36class StdCoutRedirector
37{
38public:
39 StdCoutRedirector(std::ostream& os)
40 {
41 // Redirect std::cout to the specified output stream
42 originalBuffer = std::cout.rdbuf(os.rdbuf());
43 }
44
45 ~StdCoutRedirector()
46 {
47 // Revert state for std::cout
48 std::cout.rdbuf(originalBuffer);
49 }
50
51private:
52 std::streambuf* originalBuffer;
53};
54
55class NdnDumpFixture
56{
57protected:
58 NdnDumpFixture()
59 {
60 dump.m_dataLinkType = DLT_EN10MB;
61 }
62
63 template <typename Packet>
64 void
65 receive(const Packet& packet)
66 {
67 ndn::EncodingBuffer buffer(packet.wireEncode());
68 receive(buffer);
69 }
70
71 void
72 receive(ndn::EncodingBuffer& buffer)
73 {
74 ndn::util::ethernet::Address host;
75
76 // Ethernet header
77 uint16_t frameType = htons(ndn::util::ethernet::ETHERTYPE_NDN);
78 buffer.prependByteArray(reinterpret_cast<const uint8_t*>(&frameType),
79 ndn::util::ethernet::TYPE_LEN);
80 buffer.prependByteArray(host.data(), host.size());
81 buffer.prependByteArray(host.data(), host.size());
82
83 pcap_pkthdr header{};
84 header.len = buffer.size();
85
86 {
87 StdCoutRedirector redirect(output);
88 dump.onCapturedPacket(&header, buffer.buf());
89 }
90 }
91
92protected:
93 Ndndump dump;
94 boost::test_tools::output_test_stream output;
95};
96
97BOOST_FIXTURE_TEST_SUITE(NdnDump, NdnDumpFixture)
98
99BOOST_AUTO_TEST_CASE(CaptureInterest)
100{
101 ndn::Interest interest("/test");
102 interest.setNonce(0);
103
104 this->receive(interest);
105
106 const std::string expectedOutput =
107 "0.000000 Tunnel Type: EthernetFrame, INTEREST: /test?ndn.Nonce=0\n";
108
109 BOOST_CHECK(output.is_equal(expectedOutput));
110}
111
112BOOST_AUTO_TEST_CASE(CaptureData)
113{
114 ndn::security::KeyChain keyChain;
115
116 ndn::Data data("/test");
117 keyChain.sign(data);
118
119 this->receive(data);
120
121 const std::string expectedOutput = "0.000000 Tunnel Type: EthernetFrame, DATA: /test\n";
122
123 BOOST_CHECK(output.is_equal(expectedOutput));
124}
125
126BOOST_AUTO_TEST_CASE(CaptureNack)
127{
128 ndn::Interest interest("/test");
129 interest.setNonce(0);
130
131 ndn::lp::Nack nack(interest);
132 nack.setReason(ndn::lp::NackReason::DUPLICATE);
133
134 lp::Packet lpPacket(interest.wireEncode());
135 lpPacket.add<lp::NackField>(nack.getHeader());
136
137 this->receive(lpPacket);
138
139 const std::string expectedOutput =
140 "0.000000 Tunnel Type: EthernetFrame, NACK: Duplicate, /test?ndn.Nonce=0\n";
141
142 BOOST_CHECK(output.is_equal(expectedOutput));
143}
144
145BOOST_AUTO_TEST_CASE(CaptureLpFragment)
146{
147 const uint8_t data[10] = {
148 0x06, 0x08, // Data packet
149 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
150 };
151
152 ndn::Buffer buffer(data, 4);
153
154 lp::Packet lpPacket;
155 lpPacket.add<lp::FragmentField>(std::make_pair(buffer.begin(), buffer.end()));
156 lpPacket.add<lp::FragIndexField>(0);
157 lpPacket.add<lp::FragCountField>(2);
158 lpPacket.add<lp::SequenceField>(1000);
159
160 this->receive(lpPacket);
161
162 const std::string expectedOutput =
163 "0.000000 Tunnel Type: EthernetFrame, NDNLPv2-FRAGMENT\n";
164
165 BOOST_CHECK(output.is_equal(expectedOutput));
166}
167
168BOOST_AUTO_TEST_CASE(CaptureIdlePacket)
169{
170 lp::Packet lpPacket;
171
172 this->receive(lpPacket);
173
174 const std::string expectedOutput =
175 "0.000000 Tunnel Type: EthernetFrame, NDNLPv2-IDLE\n";
176
177 BOOST_CHECK(output.is_equal(expectedOutput));
178}
179
180BOOST_AUTO_TEST_CASE(CaptureIncompletePacket)
181{
182 const uint8_t interest[] = {
183 0x05, 0x0E, // Interest
184 0x07, 0x06, // Name
185 0x08, 0x04, // NameComponent
186 0x74, 0x65, 0x73, 0x74,
187 0x0a, 0x04, // Nonce
188 0x00, 0x00, 0x00, 0x01
189 };
190
191 EncodingBuffer buffer;
192 buffer.prependByteArray(interest, 4);
193
194 this->receive(buffer);
195
196 const std::string expectedOutput =
197 "0.000000 Tunnel Type: EthernetFrame, INCOMPLETE-PACKET, size: 4\n";
198
199 BOOST_CHECK(output.is_equal(expectedOutput));
200}
201
202BOOST_AUTO_TEST_CASE(CaptureUnknownNetworkPacket)
203{
204 EncodingBuffer buffer(ndn::encoding::makeEmptyBlock(tlv::Name));
205
206 this->receive(buffer);
207
208 const std::string expectedOutput =
209 "0.000000 Tunnel Type: EthernetFrame, UNKNOWN-NETWORK-PACKET\n";
210
211 BOOST_CHECK(output.is_equal(expectedOutput));
212}
213
214BOOST_AUTO_TEST_CASE(DumpPcapTrace)
215{
216 dump.inputFile = "tests/dump/nack.pcap";
217 dump.pcapProgram = "";
218
219 {
220 StdCoutRedirector redirect(output);
221 dump.run();
222 }
223
224 const std::string expectedOutput =
225 "1456768916.467099 From: 1.0.0.1, To: 1.0.0.2, Tunnel Type: UDP, INTEREST: /producer/nack/congestion?ndn.MustBeFresh=1&ndn.Nonce=2581361680\n"
226 "1456768916.567099 From: 1.0.0.1, To: 1.0.0.2, Tunnel Type: UDP, INTEREST: /producer/nack/duplicate?ndn.MustBeFresh=1&ndn.Nonce=4138343109\n"
227 "1456768916.667099 From: 1.0.0.1, To: 1.0.0.2, Tunnel Type: UDP, INTEREST: /producer/nack/no-reason?ndn.MustBeFresh=1&ndn.Nonce=4034910304\n"
228 "1456768916.767099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: UDP, NACK: Congestion, /producer/nack/congestion?ndn.MustBeFresh=1&ndn.Nonce=2581361680\n"
229 "1456768916.867099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: UDP, NACK: Duplicate, /producer/nack/duplicate?ndn.MustBeFresh=1&ndn.Nonce=4138343109\n"
230 "1456768916.967099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: UDP, NACK: None, /producer/nack/no-reason?ndn.MustBeFresh=1&ndn.Nonce=4034910304\n"
231 "1456768917.067099 From: 1.0.0.1, To: 1.0.0.2, Tunnel Type: TCP, INTEREST: /producer/nack/congestion?ndn.MustBeFresh=1&ndn.Nonce=3192497423\n"
232 "1456768917.267099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: TCP, NACK: Congestion, /producer/nack/congestion?ndn.MustBeFresh=1&ndn.Nonce=3192497423\n"
233 "1456768917.367099 From: 1.0.0.1, To: 1.0.0.2, Tunnel Type: TCP, INTEREST: /producer/nack/duplicate?ndn.MustBeFresh=1&ndn.Nonce=522390724\n"
234 "1456768917.567099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: TCP, NACK: Duplicate, /producer/nack/duplicate?ndn.MustBeFresh=1&ndn.Nonce=522390724\n"
235 "1456768917.767099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: TCP, NACK: None, /producer/nack/no-reason?ndn.MustBeFresh=1&ndn.Nonce=2002441365\n"
236 "1456768917.967099 From: 1.0.0.1, To: 1.0.0.2, Tunnel Type: TCP, INTEREST: /producer/nack/no-reason?ndn.MustBeFresh=1&ndn.Nonce=3776824408\n"
237 "1456768918.067099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: TCP, NACK: None, /producer/nack/no-reason?ndn.MustBeFresh=1&ndn.Nonce=3776824408\n";
238
239 BOOST_CHECK(output.is_equal(expectedOutput));
240}
241
242
243BOOST_AUTO_TEST_SUITE_END()
244
245} // namespace tests
246} // namespace dump
247} // namespace ndn