blob: 00984362fa5b8f5a46d4dc6dc3735dfe7c640515 [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
Junxiao Shida93f1f2015-11-11 06:13:16 -070037BOOST_AUTO_TEST_SUITE(Face)
Davide Pesavento35120ea2015-11-17 21:13:18 +010038BOOST_FIXTURE_TEST_SUITE(TestEthernet, NetworkInterfaceFixture)
Junxiao Shida93f1f2015-11-11 06:13:16 -070039
40using nfd::Face;
41
Davide Pesavento7726ae52014-11-23 21:01:05 +010042BOOST_AUTO_TEST_CASE(GetChannels)
Davide Pesavento44deacc2014-02-19 10:48:07 +010043{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -080044 EthernetFactory factory;
Davide Pesavento44deacc2014-02-19 10:48:07 +010045
Davide Pesavento7726ae52014-11-23 21:01:05 +010046 auto channels = factory.getChannels();
47 BOOST_CHECK_EQUAL(channels.empty(), true);
48}
Davide Pesavento44deacc2014-02-19 10:48:07 +010049
Davide Pesavento7726ae52014-11-23 21:01:05 +010050BOOST_AUTO_TEST_CASE(MulticastFacesMap)
51{
Davide Pesavento35120ea2015-11-17 21:13:18 +010052 SKIP_IF_NETWORK_INTERFACE_COUNT_LT(1);
Davide Pesavento7726ae52014-11-23 21:01:05 +010053
54 EthernetFactory factory;
Davide Pesavento35120ea2015-11-17 21:13:18 +010055 auto face1 = factory.createMulticastFace(m_interfaces.front(), ethernet::getBroadcastAddress());
56 auto face1bis = factory.createMulticastFace(m_interfaces.front(), ethernet::getBroadcastAddress());
Davide Pesaventob60cc122014-03-19 19:26:02 +010057 BOOST_CHECK_EQUAL(face1, face1bis);
58
Davide Pesavento35120ea2015-11-17 21:13:18 +010059 auto face2 = factory.createMulticastFace(m_interfaces.front(), ethernet::getDefaultMulticastAddress());
60 BOOST_CHECK_NE(face1, face2);
Davide Pesaventob60cc122014-03-19 19:26:02 +010061
Davide Pesavento35120ea2015-11-17 21:13:18 +010062 SKIP_IF_NETWORK_INTERFACE_COUNT_LT(2);
63
64 auto face3 = factory.createMulticastFace(m_interfaces.back(), ethernet::getBroadcastAddress());
Davide Pesaventob60cc122014-03-19 19:26:02 +010065 BOOST_CHECK_NE(face1, face3);
66}
67
Yukai Tu7c90e6d2015-07-11 12:21:46 +080068BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
69{
70 EthernetFactory factory;
71
72 BOOST_CHECK_THROW(factory.createFace(FaceUri("ether://[08:00:27:01:01:01]"),
73 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
74 bind([]{}),
75 bind([]{})),
76 ProtocolFactory::Error);
77
78 BOOST_CHECK_THROW(factory.createFace(FaceUri("ether://[08:00:27:01:01:01]"),
79 ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
80 bind([]{}),
81 bind([]{})),
82 ProtocolFactory::Error);
83
84 BOOST_CHECK_THROW(factory.createFace(FaceUri("ether://[08:00:27:01:01:01]"),
85 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
86 bind([]{}),
87 bind([]{})),
88 ProtocolFactory::Error);
89}
90
Davide Pesavento7726ae52014-11-23 21:01:05 +010091BOOST_AUTO_TEST_CASE(SendPacket)
Davide Pesaventob60cc122014-03-19 19:26:02 +010092{
Davide Pesavento35120ea2015-11-17 21:13:18 +010093 SKIP_IF_NETWORK_INTERFACE_COUNT_LT(1);
Davide Pesavento7726ae52014-11-23 21:01:05 +010094
Davide Pesaventob60cc122014-03-19 19:26:02 +010095 EthernetFactory factory;
Davide Pesavento35120ea2015-11-17 21:13:18 +010096 auto face = factory.createMulticastFace(m_interfaces.front(), ethernet::getDefaultMulticastAddress());
Alexander Afanasyev355c0662014-03-20 18:08:17 -070097
Davide Pesavento7726ae52014-11-23 21:01:05 +010098 BOOST_REQUIRE(static_cast<bool>(face));
Davide Pesavento44deacc2014-02-19 10:48:07 +010099 BOOST_CHECK_EQUAL(face->isLocal(), false);
Davide Pesavento35120ea2015-11-17 21:13:18 +0100100 BOOST_CHECK_EQUAL(face->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERMANENT);
Davide Pesavento94279412015-02-27 01:29:32 +0100101 BOOST_CHECK_EQUAL(face->isMultiAccess(), true);
Junxiao Shi79494162014-04-02 18:25:11 -0700102 BOOST_CHECK_EQUAL(face->getRemoteUri().toString(),
Davide Pesaventob499a602014-11-18 22:36:56 +0100103 "ether://[" + ethernet::getDefaultMulticastAddress().toString() + "]");
Junxiao Shi79494162014-04-02 18:25:11 -0700104 BOOST_CHECK_EQUAL(face->getLocalUri().toString(),
Davide Pesaventob499a602014-11-18 22:36:56 +0100105 "dev://" + m_interfaces.front().name);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700106 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 0);
107 BOOST_CHECK_EQUAL(face->getCounters().nOutBytes, 0);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100108
Junxiao Shic099ddb2014-12-25 20:53:20 -0700109 face->onFail.connect([] (const std::string& reason) { BOOST_FAIL(reason); });
Davide Pesavento44deacc2014-02-19 10:48:07 +0100110
Alexander Afanasyevb56c5b92014-06-05 08:05:24 +0300111 shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
112 shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
113 shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
114 shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
Davide Pesavento44deacc2014-02-19 10:48:07 +0100115
Davide Pesavento7726ae52014-11-23 21:01:05 +0100116 face->sendInterest(*interest1);
117 face->sendData (*data1 );
118 face->sendInterest(*interest2);
119 face->sendData (*data2 );
120
Junxiao Shida93f1f2015-11-11 06:13:16 -0700121 BOOST_CHECK_EQUAL(face->getCounters().nOutBytes,
Matteo Sammarco66df9742014-11-21 18:31:26 +0100122 interest1->wireEncode().size() +
123 data1->wireEncode().size() +
124 interest2->wireEncode().size() +
125 data2->wireEncode().size());
Davide Pesavento44deacc2014-02-19 10:48:07 +0100126}
127
Davide Pesavento7726ae52014-11-23 21:01:05 +0100128BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
129{
Davide Pesavento35120ea2015-11-17 21:13:18 +0100130 SKIP_IF_NETWORK_INTERFACE_COUNT_LT(1);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100131
132 EthernetFactory factory;
Davide Pesavento35120ea2015-11-17 21:13:18 +0100133 auto face = factory.createMulticastFace(m_interfaces.front(), ethernet::getDefaultMulticastAddress());
Davide Pesavento7726ae52014-11-23 21:01:05 +0100134 BOOST_REQUIRE(static_cast<bool>(face));
135
Davide Pesavento35120ea2015-11-17 21:13:18 +0100136 auto transport = dynamic_cast<face::EthernetTransport*>(face->getLpFace()->getTransport());
137 BOOST_REQUIRE(transport != nullptr);
138
Davide Pesavento7726ae52014-11-23 21:01:05 +0100139 std::vector<Interest> recInterests;
140 std::vector<Data> recDatas;
141
Junxiao Shic099ddb2014-12-25 20:53:20 -0700142 face->onFail.connect([] (const std::string& reason) { BOOST_FAIL(reason); });
143 face->onReceiveInterest.connect(
144 [&recInterests] (const Interest& i) { recInterests.push_back(i); });
145 face->onReceiveData.connect([&recDatas] (const Data& d) { recDatas.push_back(d); });
Davide Pesavento7726ae52014-11-23 21:01:05 +0100146
147 // check that packet data is not accessed if pcap didn't capture anything (caplen == 0)
Davide Pesaventoed89ccc2015-11-01 20:35:04 +0100148 static const pcap_pkthdr zeroHeader{};
Davide Pesavento35120ea2015-11-17 21:13:18 +0100149 transport->processIncomingPacket(&zeroHeader, nullptr);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700150 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 0);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100151 BOOST_CHECK_EQUAL(recInterests.size(), 0);
152 BOOST_CHECK_EQUAL(recDatas.size(), 0);
153
154 // runt frame (too short)
Davide Pesaventoed89ccc2015-11-01 20:35:04 +0100155 pcap_pkthdr runtHeader{};
156 runtHeader.caplen = ethernet::HDR_LEN + 6;
Davide Pesavento7726ae52014-11-23 21:01:05 +0100157 static const uint8_t packet2[ethernet::HDR_LEN + 6]{};
Davide Pesavento35120ea2015-11-17 21:13:18 +0100158 transport->processIncomingPacket(&runtHeader, packet2);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700159 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 0);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100160 BOOST_CHECK_EQUAL(recInterests.size(), 0);
161 BOOST_CHECK_EQUAL(recDatas.size(), 0);
162
163 // valid frame, but TLV block has invalid length
Davide Pesaventoed89ccc2015-11-01 20:35:04 +0100164 pcap_pkthdr validHeader{};
165 validHeader.caplen = ethernet::HDR_LEN + ethernet::MIN_DATA_LEN;
Davide Pesavento7726ae52014-11-23 21:01:05 +0100166 static const uint8_t packet3[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
Matteo Sammarco66df9742014-11-21 18:31:26 +0100167 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
Davide Pesavento7726ae52014-11-23 21:01:05 +0100168 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
169 0x86, 0x24, // NDN ethertype
Davide Pesavento35120ea2015-11-17 21:13:18 +0100170 tlv::Interest, // TLV type
Matteo Sammarco66df9742014-11-21 18:31:26 +0100171 0xfd, 0xff, 0xff // TLV length (invalid because greater than buffer size)
Davide Pesavento7726ae52014-11-23 21:01:05 +0100172 };
Davide Pesavento35120ea2015-11-17 21:13:18 +0100173 transport->processIncomingPacket(&validHeader, packet3);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700174 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 0);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100175 BOOST_CHECK_EQUAL(recInterests.size(), 0);
176 BOOST_CHECK_EQUAL(recDatas.size(), 0);
177
178 // valid frame, but TLV block has invalid type
Davide Pesavento7726ae52014-11-23 21:01:05 +0100179 static const uint8_t packet4[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
Matteo Sammarco66df9742014-11-21 18:31:26 +0100180 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
Davide Pesavento7726ae52014-11-23 21:01:05 +0100181 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
182 0x86, 0x24, // NDN ethertype
183 0x00, // TLV type (invalid)
184 0x00 // TLV length
185 };
Davide Pesavento35120ea2015-11-17 21:13:18 +0100186 transport->processIncomingPacket(&validHeader, packet4);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700187 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 2);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100188 BOOST_CHECK_EQUAL(recInterests.size(), 0);
189 BOOST_CHECK_EQUAL(recDatas.size(), 0);
190
Davide Pesavento35120ea2015-11-17 21:13:18 +0100191 // valid frame and valid NDNLPv2 packet, but invalid network-layer packet
Davide Pesavento7726ae52014-11-23 21:01:05 +0100192 static const uint8_t packet5[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
Matteo Sammarco66df9742014-11-21 18:31:26 +0100193 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
Davide Pesavento7726ae52014-11-23 21:01:05 +0100194 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
Davide Pesavento35120ea2015-11-17 21:13:18 +0100195 0x86, 0x24, // NDN ethertype
196 lp::tlv::LpPacket, 0x04, // start of NDNLPv2 packet
197 lp::tlv::Fragment, 0x02, // single fragment
198 0x00, // TLV type (invalid)
199 0x00 // TLV length
Matteo Sammarco66df9742014-11-21 18:31:26 +0100200 };
Davide Pesavento35120ea2015-11-17 21:13:18 +0100201 transport->processIncomingPacket(&validHeader, packet5);
202 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 8);
Matteo Sammarco66df9742014-11-21 18:31:26 +0100203 BOOST_CHECK_EQUAL(recInterests.size(), 0);
204 BOOST_CHECK_EQUAL(recDatas.size(), 0);
205
Davide Pesavento35120ea2015-11-17 21:13:18 +0100206 // valid frame, valid NDNLPv2 packet, and valid NDN (interest) packet
Matteo Sammarco66df9742014-11-21 18:31:26 +0100207 static const uint8_t packet6[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
208 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
209 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
210 0x86, 0x24, // NDN ethertype
Davide Pesavento35120ea2015-11-17 21:13:18 +0100211 lp::tlv::LpPacket, 0x1a, // start of NDNLPv2 packet
212 lp::tlv::Fragment, 0x18, // single fragment
213 tlv::Interest, 0x16, // start of NDN packet
Davide Pesavento7726ae52014-11-23 21:01:05 +0100214 0x07, 0x0e, 0x08, 0x07, 0x65, 0x78, // payload
215 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x08,
216 0x03, 0x66, 0x6f, 0x6f, 0x0a, 0x04,
217 0x03, 0xef, 0xe9, 0x7c
218 };
Davide Pesavento35120ea2015-11-17 21:13:18 +0100219 transport->processIncomingPacket(&validHeader, packet6);
220 BOOST_CHECK_EQUAL(face->getCounters().nInBytes, 36);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100221 BOOST_CHECK_EQUAL(recInterests.size(), 1);
222 BOOST_CHECK_EQUAL(recDatas.size(), 0);
223}
224
Junxiao Shida93f1f2015-11-11 06:13:16 -0700225BOOST_AUTO_TEST_SUITE_END() // TestEthernet
226BOOST_AUTO_TEST_SUITE_END() // Face
Davide Pesavento44deacc2014-02-19 10:48:07 +0100227
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700228} // namespace tests
Davide Pesavento44deacc2014-02-19 10:48:07 +0100229} // namespace nfd