blob: 6b7a0bb391c8c93d7cd4722636372acf6df415a9 [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
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);
Davide Pesavento94279412015-02-27 01:29:32 +0100117 BOOST_CHECK_EQUAL(face->isMultiAccess(), true);
Junxiao Shi79494162014-04-02 18:25:11 -0700118 BOOST_CHECK_EQUAL(face->getRemoteUri().toString(),
Davide Pesaventob499a602014-11-18 22:36:56 +0100119 "ether://[" + ethernet::getDefaultMulticastAddress().toString() + "]");
Junxiao Shi79494162014-04-02 18:25:11 -0700120 BOOST_CHECK_EQUAL(face->getLocalUri().toString(),
Davide Pesaventob499a602014-11-18 22:36:56 +0100121 "dev://" + m_interfaces.front().name);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100122 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 0);
123 BOOST_CHECK_EQUAL(face->getCounters().getNOutBytes(), 0);
124
Junxiao Shic099ddb2014-12-25 20:53:20 -0700125 face->onFail.connect([] (const std::string& reason) { BOOST_FAIL(reason); });
Davide Pesavento44deacc2014-02-19 10:48:07 +0100126
Alexander Afanasyevb56c5b92014-06-05 08:05:24 +0300127 shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
128 shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
129 shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
130 shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
Davide Pesavento44deacc2014-02-19 10:48:07 +0100131
Davide Pesavento7726ae52014-11-23 21:01:05 +0100132 face->sendInterest(*interest1);
133 face->sendData (*data1 );
134 face->sendInterest(*interest2);
135 face->sendData (*data2 );
136
Matteo Sammarco66df9742014-11-21 18:31:26 +0100137 BOOST_CHECK_EQUAL(face->getCounters().getNOutBytes(),
138 14 * 4 + // 4 NDNLP headers
139 interest1->wireEncode().size() +
140 data1->wireEncode().size() +
141 interest2->wireEncode().size() +
142 data2->wireEncode().size());
Davide Pesavento44deacc2014-02-19 10:48:07 +0100143
144// m_ioRemaining = 4;
145// m_ioService.run();
146// m_ioService.reset();
147
148// BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
149// BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 1);
150// BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
151// BOOST_REQUIRE_EQUAL(m_face2_receivedDatas .size(), 1);
152
153// BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
154// BOOST_CHECK_EQUAL(m_face1_receivedDatas [0].getName(), data2.getName());
155// BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getName(), interest1.getName());
156// BOOST_CHECK_EQUAL(m_face2_receivedDatas [0].getName(), data1.getName());
157}
158
Davide Pesavento7726ae52014-11-23 21:01:05 +0100159BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
160{
161 if (m_interfaces.empty()) {
162 BOOST_WARN_MESSAGE(false, "No interfaces available for pcap, "
163 "cannot perform ProcessIncomingPacket test");
164 return;
165 }
166
167 EthernetFactory factory;
168 shared_ptr<EthernetFace> face = factory.createMulticastFace(m_interfaces.front(),
169 ethernet::getDefaultMulticastAddress());
170 BOOST_REQUIRE(static_cast<bool>(face));
171
172 std::vector<Interest> recInterests;
173 std::vector<Data> recDatas;
174
Junxiao Shic099ddb2014-12-25 20:53:20 -0700175 face->onFail.connect([] (const std::string& reason) { BOOST_FAIL(reason); });
176 face->onReceiveInterest.connect(
177 [&recInterests] (const Interest& i) { recInterests.push_back(i); });
178 face->onReceiveData.connect([&recDatas] (const Data& d) { recDatas.push_back(d); });
Davide Pesavento7726ae52014-11-23 21:01:05 +0100179
180 // check that packet data is not accessed if pcap didn't capture anything (caplen == 0)
181 static const pcap_pkthdr header1{};
182 face->processIncomingPacket(&header1, nullptr);
183 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 0);
184 BOOST_CHECK_EQUAL(recInterests.size(), 0);
185 BOOST_CHECK_EQUAL(recDatas.size(), 0);
186
187 // runt frame (too short)
188 static const pcap_pkthdr header2{{}, ethernet::HDR_LEN + 6};
189 static const uint8_t packet2[ethernet::HDR_LEN + 6]{};
190 face->processIncomingPacket(&header2, packet2);
191 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 0);
192 BOOST_CHECK_EQUAL(recInterests.size(), 0);
193 BOOST_CHECK_EQUAL(recDatas.size(), 0);
194
195 // valid frame, but TLV block has invalid length
196 static const pcap_pkthdr header3{{}, ethernet::HDR_LEN + ethernet::MIN_DATA_LEN};
197 static const uint8_t packet3[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
Matteo Sammarco66df9742014-11-21 18:31:26 +0100198 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
Davide Pesavento7726ae52014-11-23 21:01:05 +0100199 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
200 0x86, 0x24, // NDN ethertype
Matteo Sammarco66df9742014-11-21 18:31:26 +0100201 tlv::NdnlpData, // TLV type
202 0xfd, 0xff, 0xff // TLV length (invalid because greater than buffer size)
Davide Pesavento7726ae52014-11-23 21:01:05 +0100203 };
204 face->processIncomingPacket(&header3, packet3);
205 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 0);
206 BOOST_CHECK_EQUAL(recInterests.size(), 0);
207 BOOST_CHECK_EQUAL(recDatas.size(), 0);
208
209 // valid frame, but TLV block has invalid type
210 static const pcap_pkthdr header4{{}, ethernet::HDR_LEN + ethernet::MIN_DATA_LEN};
211 static const uint8_t packet4[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
Matteo Sammarco66df9742014-11-21 18:31:26 +0100212 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
Davide Pesavento7726ae52014-11-23 21:01:05 +0100213 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
214 0x86, 0x24, // NDN ethertype
215 0x00, // TLV type (invalid)
216 0x00 // TLV length
217 };
218 face->processIncomingPacket(&header4, packet4);
219 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 2);
220 BOOST_CHECK_EQUAL(recInterests.size(), 0);
221 BOOST_CHECK_EQUAL(recDatas.size(), 0);
222
Matteo Sammarco66df9742014-11-21 18:31:26 +0100223 // valid frame and valid NDNLP header, but invalid payload
Davide Pesavento7726ae52014-11-23 21:01:05 +0100224 static const pcap_pkthdr header5{{}, ethernet::HDR_LEN + ethernet::MIN_DATA_LEN};
225 static const uint8_t packet5[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
Matteo Sammarco66df9742014-11-21 18:31:26 +0100226 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
Davide Pesavento7726ae52014-11-23 21:01:05 +0100227 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
Matteo Sammarco66df9742014-11-21 18:31:26 +0100228 0x86, 0x24, // NDN ethertype
229 tlv::NdnlpData, 0x0e, // NDNLP header
230 tlv::NdnlpSequence, 0x08,
231 0, 0, 0, 0, 0, 0, 0, 0,
232 tlv::NdnlpPayload, 0x02,
233 0x00, // NDN TLV type (invalid)
234 0x00 // NDN TLV length
235 };
236 face->processIncomingPacket(&header5, packet5);
237 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 18);
238 BOOST_CHECK_EQUAL(recInterests.size(), 0);
239 BOOST_CHECK_EQUAL(recDatas.size(), 0);
240
241 // valid frame, valid NDNLP header, and valid NDN (interest) packet
242 static const pcap_pkthdr header6{{}, ethernet::HDR_LEN + ethernet::MIN_DATA_LEN};
243 static const uint8_t packet6[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
244 0x01, 0x00, 0x5e, 0x00, 0x17, 0xaa, // destination address
245 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
246 0x86, 0x24, // NDN ethertype
247 tlv::NdnlpData, 0x24, // NDNLP TLV type and length
248 0x51, 0x08, 0x00, 0x00, 0x00, 0x00, // rest of NDNLP header
249 0x00, 0x00, 0x00, 0x00, 0x54, 0x18,
250 tlv::Interest, 0x16, // NDN TLV type and length
Davide Pesavento7726ae52014-11-23 21:01:05 +0100251 0x07, 0x0e, 0x08, 0x07, 0x65, 0x78, // payload
252 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x08,
253 0x03, 0x66, 0x6f, 0x6f, 0x0a, 0x04,
254 0x03, 0xef, 0xe9, 0x7c
255 };
Matteo Sammarco66df9742014-11-21 18:31:26 +0100256 face->processIncomingPacket(&header6, packet6);
257 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 56);
Davide Pesavento7726ae52014-11-23 21:01:05 +0100258 BOOST_CHECK_EQUAL(recInterests.size(), 1);
259 BOOST_CHECK_EQUAL(recDatas.size(), 0);
260}
261
Davide Pesavento44deacc2014-02-19 10:48:07 +0100262BOOST_AUTO_TEST_SUITE_END()
263
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700264} // namespace tests
Davide Pesavento44deacc2014-02-19 10:48:07 +0100265} // namespace nfd