blob: ab0181c3f480500211d39c3df59947c0ddffb88c [file] [log] [blame]
Davide Pesavento44deacc2014-02-19 10:48:07 +01001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Steve DiBenedettoef04f272014-06-04 14:28:31 -06003 * Copyright (c) 2014, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Steve DiBenedettoef04f272014-06-04 14:28:31 -060024 */
Davide Pesavento44deacc2014-02-19 10:48:07 +010025
Davide Pesavento7726ae52014-11-23 21:01:05 +010026#include "face/ethernet-face.hpp"
Alexander Afanasyev0eb70652014-02-27 18:35:07 -080027#include "face/ethernet-factory.hpp"
Davide Pesavento44deacc2014-02-19 10:48:07 +010028
Davide Pesavento7726ae52014-11-23 21:01:05 +010029#include "core/network-interface.hpp"
Davide Pesavento4c1a0782014-08-14 16:13:20 +020030#include "tests/test-common.hpp"
Davide Pesaventob60cc122014-03-19 19:26:02 +010031
Davide Pesavento7726ae52014-11-23 21:01:05 +010032#include <pcap/pcap.h>
33
Davide Pesavento44deacc2014-02-19 10:48:07 +010034namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070035namespace tests {
Davide Pesavento44deacc2014-02-19 10:48:07 +010036
Davide Pesaventob60cc122014-03-19 19:26:02 +010037class InterfacesFixture : protected BaseFixture
38{
39protected:
40 InterfacesFixture()
41 {
Alexander Afanasyevb56c5b92014-06-05 08:05:24 +030042 EthernetFactory factory;
43
Davide Pesaventob499a602014-11-18 22:36:56 +010044 for (const auto& netif : listNetworkInterfaces()) {
45 if (!netif.isLoopback() && netif.isUp()) {
46 try {
47 factory.createMulticastFace(netif, ethernet::getBroadcastAddress());
48 }
49 catch (Face::Error&) {
50 continue;
51 }
Davide Pesaventob60cc122014-03-19 19:26:02 +010052
Davide Pesaventob499a602014-11-18 22:36:56 +010053 m_interfaces.push_back(netif);
Davide Pesaventob60cc122014-03-19 19:26:02 +010054 }
Davide Pesaventob499a602014-11-18 22:36:56 +010055 }
Davide Pesaventob60cc122014-03-19 19:26:02 +010056 }
57
58protected:
Davide Pesaventob499a602014-11-18 22:36:56 +010059 std::vector<NetworkInterfaceInfo> m_interfaces;
Davide Pesaventob60cc122014-03-19 19:26:02 +010060};
61
Davide Pesavento7726ae52014-11-23 21:01:05 +010062BOOST_FIXTURE_TEST_SUITE(FaceEthernet, InterfacesFixture)
Davide Pesaventob60cc122014-03-19 19:26:02 +010063
Davide Pesavento7726ae52014-11-23 21:01:05 +010064BOOST_AUTO_TEST_CASE(GetChannels)
Davide Pesavento44deacc2014-02-19 10:48:07 +010065{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -080066 EthernetFactory factory;
Davide Pesavento44deacc2014-02-19 10:48:07 +010067
Davide Pesavento7726ae52014-11-23 21:01:05 +010068 auto channels = factory.getChannels();
69 BOOST_CHECK_EQUAL(channels.empty(), true);
70}
Davide Pesavento44deacc2014-02-19 10:48:07 +010071
Davide Pesavento7726ae52014-11-23 21:01:05 +010072BOOST_AUTO_TEST_CASE(MulticastFacesMap)
73{
74 if (m_interfaces.empty()) {
75 BOOST_WARN_MESSAGE(false, "No interfaces available for pcap, "
76 "cannot perform MulticastFacesMap test");
77 return;
78 }
79
80 EthernetFactory factory;
Alexander Afanasyevb56c5b92014-06-05 08:05:24 +030081 shared_ptr<EthernetFace> face1 = factory.createMulticastFace(m_interfaces.front(),
82 ethernet::getBroadcastAddress());
83 shared_ptr<EthernetFace> face1bis = factory.createMulticastFace(m_interfaces.front(),
84 ethernet::getBroadcastAddress());
Davide Pesaventob60cc122014-03-19 19:26:02 +010085 BOOST_CHECK_EQUAL(face1, face1bis);
86
Davide Pesaventob499a602014-11-18 22:36:56 +010087 if (m_interfaces.size() > 1) {
88 shared_ptr<EthernetFace> face2 = factory.createMulticastFace(m_interfaces.back(),
89 ethernet::getBroadcastAddress());
90 BOOST_CHECK_NE(face1, face2);
91 }
92 else {
Davide Pesavento7726ae52014-11-23 21:01:05 +010093 BOOST_WARN_MESSAGE(false, "Only one interface available for pcap, "
94 "cannot test second EthernetFace creation");
Davide Pesaventob499a602014-11-18 22:36:56 +010095 }
Davide Pesaventob60cc122014-03-19 19:26:02 +010096
Alexander Afanasyevb56c5b92014-06-05 08:05:24 +030097 shared_ptr<EthernetFace> face3 = factory.createMulticastFace(m_interfaces.front(),
98 ethernet::getDefaultMulticastAddress());
Davide Pesaventob60cc122014-03-19 19:26:02 +010099 BOOST_CHECK_NE(face1, face3);
100}
101
Davide Pesavento7726ae52014-11-23 21:01:05 +0100102BOOST_AUTO_TEST_CASE(SendPacket)
Davide Pesaventob60cc122014-03-19 19:26:02 +0100103{
Davide Pesavento7726ae52014-11-23 21:01:05 +0100104 if (m_interfaces.empty()) {
105 BOOST_WARN_MESSAGE(false, "No interfaces available for pcap, "
106 "cannot perform SendPacket test");
107 return;
108 }
109
Davide Pesaventob60cc122014-03-19 19:26:02 +0100110 EthernetFactory factory;
Davide Pesaventob60cc122014-03-19 19:26:02 +0100111 shared_ptr<EthernetFace> face = factory.createMulticastFace(m_interfaces.front(),
Alexander Afanasyevb56c5b92014-06-05 08:05:24 +0300112 ethernet::getDefaultMulticastAddress());
Alexander Afanasyev355c0662014-03-20 18:08:17 -0700113
Davide Pesavento7726ae52014-11-23 21:01:05 +0100114 BOOST_REQUIRE(static_cast<bool>(face));
Davide Pesavento44deacc2014-02-19 10:48:07 +0100115 BOOST_CHECK_EQUAL(face->isLocal(), false);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100116 BOOST_CHECK_EQUAL(face->isOnDemand(), false);
Junxiao Shi79494162014-04-02 18:25:11 -0700117 BOOST_CHECK_EQUAL(face->getRemoteUri().toString(),
Davide Pesaventob499a602014-11-18 22:36:56 +0100118 "ether://[" + ethernet::getDefaultMulticastAddress().toString() + "]");
Junxiao Shi79494162014-04-02 18:25:11 -0700119 BOOST_CHECK_EQUAL(face->getLocalUri().toString(),
Davide Pesaventob499a602014-11-18 22:36:56 +0100120 "dev://" + m_interfaces.front().name);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100121 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 0);
122 BOOST_CHECK_EQUAL(face->getCounters().getNOutBytes(), 0);
123
124 face->onFail += [] (const std::string& reason) { BOOST_FAIL(reason); };
Davide Pesavento44deacc2014-02-19 10:48:07 +0100125
Alexander Afanasyevb56c5b92014-06-05 08:05:24 +0300126 shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
127 shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
128 shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
129 shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
Davide Pesavento44deacc2014-02-19 10:48:07 +0100130
Davide Pesavento7726ae52014-11-23 21:01:05 +0100131 face->sendInterest(*interest1);
132 face->sendData (*data1 );
133 face->sendInterest(*interest2);
134 face->sendData (*data2 );
135
Matteo Sammarco66df9742014-11-21 18:31:26 +0100136 BOOST_CHECK_EQUAL(face->getCounters().getNOutBytes(),
137 14 * 4 + // 4 NDNLP headers
138 interest1->wireEncode().size() +
139 data1->wireEncode().size() +
140 interest2->wireEncode().size() +
141 data2->wireEncode().size());
Davide Pesavento44deacc2014-02-19 10:48:07 +0100142
143// m_ioRemaining = 4;
144// m_ioService.run();
145// m_ioService.reset();
146
147// BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
148// BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 1);
149// BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
150// BOOST_REQUIRE_EQUAL(m_face2_receivedDatas .size(), 1);
151
152// BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
153// BOOST_CHECK_EQUAL(m_face1_receivedDatas [0].getName(), data2.getName());
154// BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getName(), interest1.getName());
155// BOOST_CHECK_EQUAL(m_face2_receivedDatas [0].getName(), data1.getName());
156}
157
Davide Pesavento7726ae52014-11-23 21:01:05 +0100158BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
159{
160 if (m_interfaces.empty()) {
161 BOOST_WARN_MESSAGE(false, "No interfaces available for pcap, "
162 "cannot perform ProcessIncomingPacket test");
163 return;
164 }
165
166 EthernetFactory factory;
167 shared_ptr<EthernetFace> face = factory.createMulticastFace(m_interfaces.front(),
168 ethernet::getDefaultMulticastAddress());
169 BOOST_REQUIRE(static_cast<bool>(face));
170
171 std::vector<Interest> recInterests;
172 std::vector<Data> recDatas;
173
174 face->onFail += [] (const std::string& reason) { BOOST_FAIL(reason); };
175 face->onReceiveInterest += [&recInterests] (const Interest& i) { recInterests.push_back(i); };
176 face->onReceiveData += [&recDatas] (const Data& d) { recDatas.push_back(d); };
177
178 // check that packet data is not accessed if pcap didn't capture anything (caplen == 0)
179 static const pcap_pkthdr header1{};
180 face->processIncomingPacket(&header1, nullptr);
181 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 0);
182 BOOST_CHECK_EQUAL(recInterests.size(), 0);
183 BOOST_CHECK_EQUAL(recDatas.size(), 0);
184
185 // runt frame (too short)
186 static const pcap_pkthdr header2{{}, ethernet::HDR_LEN + 6};
187 static const uint8_t packet2[ethernet::HDR_LEN + 6]{};
188 face->processIncomingPacket(&header2, packet2);
189 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 0);
190 BOOST_CHECK_EQUAL(recInterests.size(), 0);
191 BOOST_CHECK_EQUAL(recDatas.size(), 0);
192
193 // valid frame, but TLV block has invalid length
194 static const pcap_pkthdr header3{{}, ethernet::HDR_LEN + ethernet::MIN_DATA_LEN};
195 static const uint8_t packet3[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
Matteo Sammarco66df9742014-11-21 18:31:26 +0100196 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
Davide Pesavento7726ae52014-11-23 21:01:05 +0100197 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
198 0x86, 0x24, // NDN ethertype
Matteo Sammarco66df9742014-11-21 18:31:26 +0100199 tlv::NdnlpData, // TLV type
200 0xfd, 0xff, 0xff // TLV length (invalid because greater than buffer size)
Davide Pesavento7726ae52014-11-23 21:01:05 +0100201 };
202 face->processIncomingPacket(&header3, packet3);
203 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 0);
204 BOOST_CHECK_EQUAL(recInterests.size(), 0);
205 BOOST_CHECK_EQUAL(recDatas.size(), 0);
206
207 // valid frame, but TLV block has invalid type
208 static const pcap_pkthdr header4{{}, ethernet::HDR_LEN + ethernet::MIN_DATA_LEN};
209 static const uint8_t packet4[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
Matteo Sammarco66df9742014-11-21 18:31:26 +0100210 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
Davide Pesavento7726ae52014-11-23 21:01:05 +0100211 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
212 0x86, 0x24, // NDN ethertype
213 0x00, // TLV type (invalid)
214 0x00 // TLV length
215 };
216 face->processIncomingPacket(&header4, packet4);
217 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 2);
218 BOOST_CHECK_EQUAL(recInterests.size(), 0);
219 BOOST_CHECK_EQUAL(recDatas.size(), 0);
220
Matteo Sammarco66df9742014-11-21 18:31:26 +0100221 // valid frame and valid NDNLP header, but invalid payload
Davide Pesavento7726ae52014-11-23 21:01:05 +0100222 static const pcap_pkthdr header5{{}, ethernet::HDR_LEN + ethernet::MIN_DATA_LEN};
223 static const uint8_t packet5[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
Matteo Sammarco66df9742014-11-21 18:31:26 +0100224 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
Davide Pesavento7726ae52014-11-23 21:01:05 +0100225 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
Matteo Sammarco66df9742014-11-21 18:31:26 +0100226 0x86, 0x24, // NDN ethertype
227 tlv::NdnlpData, 0x0e, // NDNLP header
228 tlv::NdnlpSequence, 0x08,
229 0, 0, 0, 0, 0, 0, 0, 0,
230 tlv::NdnlpPayload, 0x02,
231 0x00, // NDN TLV type (invalid)
232 0x00 // NDN TLV length
233 };
234 face->processIncomingPacket(&header5, packet5);
235 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 18);
236 BOOST_CHECK_EQUAL(recInterests.size(), 0);
237 BOOST_CHECK_EQUAL(recDatas.size(), 0);
238
239 // valid frame, valid NDNLP header, and valid NDN (interest) packet
240 static const pcap_pkthdr header6{{}, ethernet::HDR_LEN + ethernet::MIN_DATA_LEN};
241 static const uint8_t packet6[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
242 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
243 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
244 0x86, 0x24, // NDN ethertype
245 tlv::NdnlpData, 0x24, // NDNLP TLV type and length
246 0x51, 0x08, 0x00, 0x00, 0x00, 0x00, // rest of NDNLP header
247 0x00, 0x00, 0x00, 0x00, 0x54, 0x18,
248 tlv::Interest, 0x16, // NDN TLV type and length
Davide Pesavento7726ae52014-11-23 21:01:05 +0100249 0x07, 0x0e, 0x08, 0x07, 0x65, 0x78, // payload
250 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x08,
251 0x03, 0x66, 0x6f, 0x6f, 0x0a, 0x04,
252 0x03, 0xef, 0xe9, 0x7c
253 };
Matteo Sammarco66df9742014-11-21 18:31:26 +0100254 face->processIncomingPacket(&header6, packet6);
255 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 56);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100256 BOOST_CHECK_EQUAL(recInterests.size(), 1);
257 BOOST_CHECK_EQUAL(recDatas.size(), 0);
258}
259
Davide Pesavento44deacc2014-02-19 10:48:07 +0100260BOOST_AUTO_TEST_SUITE_END()
261
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700262} // namespace tests
Davide Pesavento44deacc2014-02-19 10:48:07 +0100263} // namespace nfd