blob: 2b1d2de4fc2cc775cfbf4d8e1b4a2474acae91e2 [file] [log] [blame]
Davide Pesavento44deacc2014-02-19 10:48:07 +01001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev319f2c82015-01-07 14:56:53 -08003 * Copyright (c) 2014-2015, 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
Alexander Afanasyev0eb70652014-02-27 18:35:07 -080026#include "face/ethernet-factory.hpp"
Davide Pesavento35120ea2015-11-17 21:13:18 +010027#include "face/ethernet-transport.hpp"
Davide Pesavento44deacc2014-02-19 10:48:07 +010028
Davide Pesavento35120ea2015-11-17 21:13:18 +010029#include "face/lp-face-wrapper.hpp"
30#include "network-interface-fixture.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
Eric Newberry8717e872015-11-23 12:41:50 -070037using nfd::face::tests::NetworkInterfaceFixture;
38
Junxiao Shida93f1f2015-11-11 06:13:16 -070039BOOST_AUTO_TEST_SUITE(Face)
Davide Pesavento35120ea2015-11-17 21:13:18 +010040BOOST_FIXTURE_TEST_SUITE(TestEthernet, NetworkInterfaceFixture)
Junxiao Shida93f1f2015-11-11 06:13:16 -070041
42using nfd::Face;
43
Davide Pesavento7726ae52014-11-23 21:01:05 +010044BOOST_AUTO_TEST_CASE(GetChannels)
Davide Pesavento44deacc2014-02-19 10:48:07 +010045{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -080046 EthernetFactory factory;
Davide Pesavento44deacc2014-02-19 10:48:07 +010047
Davide Pesavento7726ae52014-11-23 21:01:05 +010048 auto channels = factory.getChannels();
49 BOOST_CHECK_EQUAL(channels.empty(), true);
50}
Davide Pesavento44deacc2014-02-19 10:48:07 +010051
Davide Pesavento7726ae52014-11-23 21:01:05 +010052BOOST_AUTO_TEST_CASE(MulticastFacesMap)
53{
Davide Pesavento35120ea2015-11-17 21:13:18 +010054 SKIP_IF_NETWORK_INTERFACE_COUNT_LT(1);
Davide Pesavento7726ae52014-11-23 21:01:05 +010055
56 EthernetFactory factory;
Davide Pesavento35120ea2015-11-17 21:13:18 +010057 auto face1 = factory.createMulticastFace(m_interfaces.front(), ethernet::getBroadcastAddress());
58 auto face1bis = factory.createMulticastFace(m_interfaces.front(), ethernet::getBroadcastAddress());
Davide Pesaventob60cc122014-03-19 19:26:02 +010059 BOOST_CHECK_EQUAL(face1, face1bis);
60
Davide Pesavento35120ea2015-11-17 21:13:18 +010061 auto face2 = factory.createMulticastFace(m_interfaces.front(), ethernet::getDefaultMulticastAddress());
62 BOOST_CHECK_NE(face1, face2);
Davide Pesaventob60cc122014-03-19 19:26:02 +010063
Davide Pesavento35120ea2015-11-17 21:13:18 +010064 SKIP_IF_NETWORK_INTERFACE_COUNT_LT(2);
65
66 auto face3 = factory.createMulticastFace(m_interfaces.back(), ethernet::getBroadcastAddress());
Davide Pesaventob60cc122014-03-19 19:26:02 +010067 BOOST_CHECK_NE(face1, face3);
68}
69
Yukai Tu7c90e6d2015-07-11 12:21:46 +080070BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
71{
72 EthernetFactory factory;
73
74 BOOST_CHECK_THROW(factory.createFace(FaceUri("ether://[08:00:27:01:01:01]"),
75 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
76 bind([]{}),
77 bind([]{})),
78 ProtocolFactory::Error);
79
80 BOOST_CHECK_THROW(factory.createFace(FaceUri("ether://[08:00:27:01:01:01]"),
81 ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
82 bind([]{}),
83 bind([]{})),
84 ProtocolFactory::Error);
85
86 BOOST_CHECK_THROW(factory.createFace(FaceUri("ether://[08:00:27:01:01:01]"),
87 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
88 bind([]{}),
89 bind([]{})),
90 ProtocolFactory::Error);
91}
92
Davide Pesavento7726ae52014-11-23 21:01:05 +010093BOOST_AUTO_TEST_CASE(SendPacket)
Davide Pesaventob60cc122014-03-19 19:26:02 +010094{
Davide Pesavento35120ea2015-11-17 21:13:18 +010095 SKIP_IF_NETWORK_INTERFACE_COUNT_LT(1);
Davide Pesavento7726ae52014-11-23 21:01:05 +010096
Davide Pesaventob60cc122014-03-19 19:26:02 +010097 EthernetFactory factory;
Davide Pesavento35120ea2015-11-17 21:13:18 +010098 auto face = factory.createMulticastFace(m_interfaces.front(), ethernet::getDefaultMulticastAddress());
Alexander Afanasyev355c0662014-03-20 18:08:17 -070099
Davide Pesavento7726ae52014-11-23 21:01:05 +0100100 BOOST_REQUIRE(static_cast<bool>(face));
Davide Pesavento44deacc2014-02-19 10:48:07 +0100101 BOOST_CHECK_EQUAL(face->isLocal(), false);
Davide Pesavento35120ea2015-11-17 21:13:18 +0100102 BOOST_CHECK_EQUAL(face->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERMANENT);
Davide Pesavento94279412015-02-27 01:29:32 +0100103 BOOST_CHECK_EQUAL(face->isMultiAccess(), true);
Junxiao Shi79494162014-04-02 18:25:11 -0700104 BOOST_CHECK_EQUAL(face->getRemoteUri().toString(),
Davide Pesaventob499a602014-11-18 22:36:56 +0100105 "ether://[" + ethernet::getDefaultMulticastAddress().toString() + "]");
Junxiao Shi79494162014-04-02 18:25:11 -0700106 BOOST_CHECK_EQUAL(face->getLocalUri().toString(),
Davide Pesaventob499a602014-11-18 22:36:56 +0100107 "dev://" + m_interfaces.front().name);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700108 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 0);
109 BOOST_CHECK_EQUAL(face->getCounters().nOutBytes, 0);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100110
Junxiao Shic099ddb2014-12-25 20:53:20 -0700111 face->onFail.connect([] (const std::string& reason) { BOOST_FAIL(reason); });
Davide Pesavento44deacc2014-02-19 10:48:07 +0100112
Alexander Afanasyevb56c5b92014-06-05 08:05:24 +0300113 shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
114 shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
115 shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
116 shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
Davide Pesavento44deacc2014-02-19 10:48:07 +0100117
Davide Pesavento7726ae52014-11-23 21:01:05 +0100118 face->sendInterest(*interest1);
119 face->sendData (*data1 );
120 face->sendInterest(*interest2);
121 face->sendData (*data2 );
122
Junxiao Shida93f1f2015-11-11 06:13:16 -0700123 BOOST_CHECK_EQUAL(face->getCounters().nOutBytes,
Matteo Sammarco66df9742014-11-21 18:31:26 +0100124 interest1->wireEncode().size() +
125 data1->wireEncode().size() +
126 interest2->wireEncode().size() +
127 data2->wireEncode().size());
Davide Pesavento44deacc2014-02-19 10:48:07 +0100128}
129
Davide Pesavento7726ae52014-11-23 21:01:05 +0100130BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
131{
Davide Pesavento35120ea2015-11-17 21:13:18 +0100132 SKIP_IF_NETWORK_INTERFACE_COUNT_LT(1);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100133
134 EthernetFactory factory;
Davide Pesavento35120ea2015-11-17 21:13:18 +0100135 auto face = factory.createMulticastFace(m_interfaces.front(), ethernet::getDefaultMulticastAddress());
Davide Pesavento7726ae52014-11-23 21:01:05 +0100136 BOOST_REQUIRE(static_cast<bool>(face));
137
Davide Pesavento35120ea2015-11-17 21:13:18 +0100138 auto transport = dynamic_cast<face::EthernetTransport*>(face->getLpFace()->getTransport());
139 BOOST_REQUIRE(transport != nullptr);
140
Davide Pesavento7726ae52014-11-23 21:01:05 +0100141 std::vector<Interest> recInterests;
142 std::vector<Data> recDatas;
143
Junxiao Shic099ddb2014-12-25 20:53:20 -0700144 face->onFail.connect([] (const std::string& reason) { BOOST_FAIL(reason); });
145 face->onReceiveInterest.connect(
146 [&recInterests] (const Interest& i) { recInterests.push_back(i); });
147 face->onReceiveData.connect([&recDatas] (const Data& d) { recDatas.push_back(d); });
Davide Pesavento7726ae52014-11-23 21:01:05 +0100148
149 // check that packet data is not accessed if pcap didn't capture anything (caplen == 0)
Davide Pesaventoed89ccc2015-11-01 20:35:04 +0100150 static const pcap_pkthdr zeroHeader{};
Davide Pesavento35120ea2015-11-17 21:13:18 +0100151 transport->processIncomingPacket(&zeroHeader, nullptr);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700152 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 0);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100153 BOOST_CHECK_EQUAL(recInterests.size(), 0);
154 BOOST_CHECK_EQUAL(recDatas.size(), 0);
155
156 // runt frame (too short)
Davide Pesaventoed89ccc2015-11-01 20:35:04 +0100157 pcap_pkthdr runtHeader{};
158 runtHeader.caplen = ethernet::HDR_LEN + 6;
Davide Pesavento7726ae52014-11-23 21:01:05 +0100159 static const uint8_t packet2[ethernet::HDR_LEN + 6]{};
Davide Pesavento35120ea2015-11-17 21:13:18 +0100160 transport->processIncomingPacket(&runtHeader, packet2);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700161 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 0);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100162 BOOST_CHECK_EQUAL(recInterests.size(), 0);
163 BOOST_CHECK_EQUAL(recDatas.size(), 0);
164
165 // valid frame, but TLV block has invalid length
Davide Pesaventoed89ccc2015-11-01 20:35:04 +0100166 pcap_pkthdr validHeader{};
167 validHeader.caplen = ethernet::HDR_LEN + ethernet::MIN_DATA_LEN;
Davide Pesavento7726ae52014-11-23 21:01:05 +0100168 static const uint8_t packet3[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
Matteo Sammarco66df9742014-11-21 18:31:26 +0100169 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
Davide Pesavento7726ae52014-11-23 21:01:05 +0100170 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
171 0x86, 0x24, // NDN ethertype
Davide Pesavento35120ea2015-11-17 21:13:18 +0100172 tlv::Interest, // TLV type
Matteo Sammarco66df9742014-11-21 18:31:26 +0100173 0xfd, 0xff, 0xff // TLV length (invalid because greater than buffer size)
Davide Pesavento7726ae52014-11-23 21:01:05 +0100174 };
Davide Pesavento35120ea2015-11-17 21:13:18 +0100175 transport->processIncomingPacket(&validHeader, packet3);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700176 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 0);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100177 BOOST_CHECK_EQUAL(recInterests.size(), 0);
178 BOOST_CHECK_EQUAL(recDatas.size(), 0);
179
180 // valid frame, but TLV block has invalid type
Davide Pesavento7726ae52014-11-23 21:01:05 +0100181 static const uint8_t packet4[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
Matteo Sammarco66df9742014-11-21 18:31:26 +0100182 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
Davide Pesavento7726ae52014-11-23 21:01:05 +0100183 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
184 0x86, 0x24, // NDN ethertype
185 0x00, // TLV type (invalid)
186 0x00 // TLV length
187 };
Davide Pesavento35120ea2015-11-17 21:13:18 +0100188 transport->processIncomingPacket(&validHeader, packet4);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700189 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 2);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100190 BOOST_CHECK_EQUAL(recInterests.size(), 0);
191 BOOST_CHECK_EQUAL(recDatas.size(), 0);
192
Davide Pesavento35120ea2015-11-17 21:13:18 +0100193 // valid frame and valid NDNLPv2 packet, but invalid network-layer packet
Davide Pesavento7726ae52014-11-23 21:01:05 +0100194 static const uint8_t packet5[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
Matteo Sammarco66df9742014-11-21 18:31:26 +0100195 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
Davide Pesavento7726ae52014-11-23 21:01:05 +0100196 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
Davide Pesavento35120ea2015-11-17 21:13:18 +0100197 0x86, 0x24, // NDN ethertype
198 lp::tlv::LpPacket, 0x04, // start of NDNLPv2 packet
199 lp::tlv::Fragment, 0x02, // single fragment
200 0x00, // TLV type (invalid)
201 0x00 // TLV length
Matteo Sammarco66df9742014-11-21 18:31:26 +0100202 };
Davide Pesavento35120ea2015-11-17 21:13:18 +0100203 transport->processIncomingPacket(&validHeader, packet5);
204 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 8);
Matteo Sammarco66df9742014-11-21 18:31:26 +0100205 BOOST_CHECK_EQUAL(recInterests.size(), 0);
206 BOOST_CHECK_EQUAL(recDatas.size(), 0);
207
Davide Pesavento35120ea2015-11-17 21:13:18 +0100208 // valid frame, valid NDNLPv2 packet, and valid NDN (interest) packet
Matteo Sammarco66df9742014-11-21 18:31:26 +0100209 static const uint8_t packet6[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
210 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
211 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
212 0x86, 0x24, // NDN ethertype
Davide Pesavento35120ea2015-11-17 21:13:18 +0100213 lp::tlv::LpPacket, 0x1a, // start of NDNLPv2 packet
214 lp::tlv::Fragment, 0x18, // single fragment
215 tlv::Interest, 0x16, // start of NDN packet
Davide Pesavento7726ae52014-11-23 21:01:05 +0100216 0x07, 0x0e, 0x08, 0x07, 0x65, 0x78, // payload
217 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x08,
218 0x03, 0x66, 0x6f, 0x6f, 0x0a, 0x04,
219 0x03, 0xef, 0xe9, 0x7c
220 };
Davide Pesavento35120ea2015-11-17 21:13:18 +0100221 transport->processIncomingPacket(&validHeader, packet6);
222 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 36);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100223 BOOST_CHECK_EQUAL(recInterests.size(), 1);
224 BOOST_CHECK_EQUAL(recDatas.size(), 0);
225}
226
Junxiao Shida93f1f2015-11-11 06:13:16 -0700227BOOST_AUTO_TEST_SUITE_END() // TestEthernet
228BOOST_AUTO_TEST_SUITE_END() // Face
Davide Pesavento44deacc2014-02-19 10:48:07 +0100229
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700230} // namespace tests
Davide Pesavento44deacc2014-02-19 10:48:07 +0100231} // namespace nfd