blob: 54cca5d51d241f878ab528e61a3ad6ca4e1147b5 [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
136 BOOST_CHECK_EQUAL(face->getCounters().getNOutBytes(), interest1->wireEncode().size() +
137 data1->wireEncode().size() +
138 interest2->wireEncode().size() +
139 data2->wireEncode().size());
Davide Pesavento44deacc2014-02-19 10:48:07 +0100140
141// m_ioRemaining = 4;
142// m_ioService.run();
143// m_ioService.reset();
144
145// BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
146// BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 1);
147// BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
148// BOOST_REQUIRE_EQUAL(m_face2_receivedDatas .size(), 1);
149
150// BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
151// BOOST_CHECK_EQUAL(m_face1_receivedDatas [0].getName(), data2.getName());
152// BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getName(), interest1.getName());
153// BOOST_CHECK_EQUAL(m_face2_receivedDatas [0].getName(), data1.getName());
154}
155
Davide Pesavento7726ae52014-11-23 21:01:05 +0100156BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
157{
158 if (m_interfaces.empty()) {
159 BOOST_WARN_MESSAGE(false, "No interfaces available for pcap, "
160 "cannot perform ProcessIncomingPacket test");
161 return;
162 }
163
164 EthernetFactory factory;
165 shared_ptr<EthernetFace> face = factory.createMulticastFace(m_interfaces.front(),
166 ethernet::getDefaultMulticastAddress());
167 BOOST_REQUIRE(static_cast<bool>(face));
168
169 std::vector<Interest> recInterests;
170 std::vector<Data> recDatas;
171
172 face->onFail += [] (const std::string& reason) { BOOST_FAIL(reason); };
173 face->onReceiveInterest += [&recInterests] (const Interest& i) { recInterests.push_back(i); };
174 face->onReceiveData += [&recDatas] (const Data& d) { recDatas.push_back(d); };
175
176 // check that packet data is not accessed if pcap didn't capture anything (caplen == 0)
177 static const pcap_pkthdr header1{};
178 face->processIncomingPacket(&header1, nullptr);
179 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 0);
180 BOOST_CHECK_EQUAL(recInterests.size(), 0);
181 BOOST_CHECK_EQUAL(recDatas.size(), 0);
182
183 // runt frame (too short)
184 static const pcap_pkthdr header2{{}, ethernet::HDR_LEN + 6};
185 static const uint8_t packet2[ethernet::HDR_LEN + 6]{};
186 face->processIncomingPacket(&header2, packet2);
187 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 0);
188 BOOST_CHECK_EQUAL(recInterests.size(), 0);
189 BOOST_CHECK_EQUAL(recDatas.size(), 0);
190
191 // valid frame, but TLV block has invalid length
192 static const pcap_pkthdr header3{{}, ethernet::HDR_LEN + ethernet::MIN_DATA_LEN};
193 static const uint8_t packet3[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
194 0x01, 0x00, 0x5E, 0x00, 0x17, 0xAA, // destination address
195 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
196 0x86, 0x24, // NDN ethertype
197 tlv::Data, // TLV type
198 0xFD, 0xFF, 0xFF // TLV length (invalid because greater than packet size)
199 };
200 face->processIncomingPacket(&header3, packet3);
201 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 0);
202 BOOST_CHECK_EQUAL(recInterests.size(), 0);
203 BOOST_CHECK_EQUAL(recDatas.size(), 0);
204
205 // valid frame, but TLV block has invalid type
206 static const pcap_pkthdr header4{{}, ethernet::HDR_LEN + ethernet::MIN_DATA_LEN};
207 static const uint8_t packet4[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
211 0x00, // TLV type (invalid)
212 0x00 // TLV length
213 };
214 face->processIncomingPacket(&header4, packet4);
215 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 2);
216 BOOST_CHECK_EQUAL(recInterests.size(), 0);
217 BOOST_CHECK_EQUAL(recDatas.size(), 0);
218
219 // valid frame and valid TLV block
220 static const pcap_pkthdr header5{{}, ethernet::HDR_LEN + ethernet::MIN_DATA_LEN};
221 static const uint8_t packet5[ethernet::HDR_LEN + ethernet::MIN_DATA_LEN]{
222 0x01, 0x00, 0x5E, 0x00, 0x17, 0xAA, // destination address
223 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, // source address
224 0x86, 0x24, // NDN ethertype
225 tlv::Interest, // TLV type
226 0x16, // TLV length
227 0x07, 0x0e, 0x08, 0x07, 0x65, 0x78, // payload
228 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x08,
229 0x03, 0x66, 0x6f, 0x6f, 0x0a, 0x04,
230 0x03, 0xef, 0xe9, 0x7c
231 };
232 face->processIncomingPacket(&header5, packet5);
233 BOOST_CHECK_EQUAL(face->getCounters().getNInBytes(), 26);
234 BOOST_CHECK_EQUAL(recInterests.size(), 1);
235 BOOST_CHECK_EQUAL(recDatas.size(), 0);
236}
237
Davide Pesavento44deacc2014-02-19 10:48:07 +0100238BOOST_AUTO_TEST_SUITE_END()
239
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700240} // namespace tests
Davide Pesavento44deacc2014-02-19 10:48:07 +0100241} // namespace nfd