blob: 77743a859cf9af796aa17731656ee0bb490a3261 [file] [log] [blame]
Junxiao Shi2222a612015-06-06 08:01:38 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento60f8cc12018-05-10 22:05:21 -04002/*
3 * Copyright (c) 2014-2018, Regents of the University of California.
Junxiao Shi3cd47df2015-06-07 20:58:14 -07004 *
5 * This file is part of ndn-tools (Named Data Networking Essential Tools).
6 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
7 *
8 * ndn-tools is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
Davide Pesavento60f8cc12018-05-10 22:05:21 -040019/*
Junxiao Shi2222a612015-06-06 08:01:38 -070020 * Copyright (c) 2011-2014, Regents of the University of California,
21 *
22 * This file is part of ndndump, the packet capture and analysis tool for Named Data
23 * Networking (NDN).
24 *
25 * ndndump is free software: you can redistribute it and/or modify it under the terms
26 * of the GNU General Public License as published by the Free Software Foundation,
27 * either version 3 of the License, or (at your option) any later version.
28 *
29 * ndndump is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
30 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
31 * PURPOSE. See the GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License along with
34 * ndndump, e.g., in COPYING file. If not, see <http://www.gnu.org/licenses/>.
35 **/
36
37#include "ndndump.hpp"
38
Davide Pesavento051db002018-07-22 18:56:16 -040039#include <net/ethernet.h>
40#include <netinet/ip.h>
41#include <netinet/tcp.h>
42#include <netinet/udp.h>
Junxiao Shi2222a612015-06-06 08:01:38 -070043
Junxiao Shi022bddf2016-11-24 23:15:20 +000044#include <pcap/sll.h>
45
Junxiao Shi2222a612015-06-06 08:01:38 -070046#include <iomanip>
Davide Pesaventoc0702702017-08-24 22:04:00 -040047#include <sstream>
Junxiao Shi2222a612015-06-06 08:01:38 -070048
Vince Lehman277ecf02016-02-10 16:37:48 -060049#include <ndn-cxx/lp/nack.hpp>
50#include <ndn-cxx/lp/packet.hpp>
Davide Pesaventoecd44802018-07-23 23:48:10 -040051#include <ndn-cxx/net/ethernet.hpp>
Junxiao Shi2222a612015-06-06 08:01:38 -070052
53namespace ndn {
Junxiao Shi3cd47df2015-06-07 20:58:14 -070054namespace dump {
Junxiao Shi2222a612015-06-06 08:01:38 -070055
Davide Pesaventoecd44802018-07-23 23:48:10 -040056NdnDump::~NdnDump()
Junxiao Shic1c2b832016-07-24 20:45:36 +000057{
Davide Pesaventoecd44802018-07-23 23:48:10 -040058 if (m_pcap)
59 pcap_close(m_pcap);
60}
61
62static void
63pcapCallback(uint8_t* user, const pcap_pkthdr* pkthdr, const uint8_t* payload)
64{
65 reinterpret_cast<const NdnDump*>(user)->printPacket(pkthdr, payload);
Junxiao Shic1c2b832016-07-24 20:45:36 +000066}
67
Junxiao Shi2222a612015-06-06 08:01:38 -070068void
Davide Pesaventoecd44802018-07-23 23:48:10 -040069NdnDump::run()
Junxiao Shi2222a612015-06-06 08:01:38 -070070{
Davide Pesaventoecd44802018-07-23 23:48:10 -040071 char errbuf[PCAP_ERRBUF_SIZE];
Junxiao Shi2222a612015-06-06 08:01:38 -070072
Davide Pesaventoecd44802018-07-23 23:48:10 -040073 if (inputFile.empty() && interface.empty()) {
74 const char* defaultDevice = pcap_lookupdev(errbuf);
75
76 if (defaultDevice == nullptr) {
Junxiao Shic7599632016-07-24 20:46:24 +000077 BOOST_THROW_EXCEPTION(Error(errbuf));
Junxiao Shi2222a612015-06-06 08:01:38 -070078 }
79
Davide Pesaventoecd44802018-07-23 23:48:10 -040080 interface = defaultDevice;
Junxiao Shi2222a612015-06-06 08:01:38 -070081 }
82
Davide Pesaventoecd44802018-07-23 23:48:10 -040083 std::string action;
Junxiao Shi2222a612015-06-06 08:01:38 -070084 if (!interface.empty()) {
Davide Pesavento24c08612018-07-26 13:33:24 -040085 m_pcap = pcap_open_live(interface.data(), 65535, wantPromisc, 1000, errbuf);
Junxiao Shic1c2b832016-07-24 20:45:36 +000086 if (m_pcap == nullptr) {
Davide Pesaventoecd44802018-07-23 23:48:10 -040087 BOOST_THROW_EXCEPTION(Error("Cannot open interface " + interface + ": " + errbuf));
Junxiao Shi2222a612015-06-06 08:01:38 -070088 }
Davide Pesaventoecd44802018-07-23 23:48:10 -040089 action = "listening on " + interface;
Junxiao Shi2222a612015-06-06 08:01:38 -070090 }
91 else {
Davide Pesavento78de7352018-07-22 00:35:45 -040092 m_pcap = pcap_open_offline(inputFile.data(), errbuf);
Junxiao Shic1c2b832016-07-24 20:45:36 +000093 if (m_pcap == nullptr) {
Davide Pesaventoecd44802018-07-23 23:48:10 -040094 BOOST_THROW_EXCEPTION(Error("Cannot open file '" + inputFile + "' for reading: " + errbuf));
Junxiao Shi2222a612015-06-06 08:01:38 -070095 }
Davide Pesaventoecd44802018-07-23 23:48:10 -040096 action = "reading from file " + inputFile;
Junxiao Shi2222a612015-06-06 08:01:38 -070097 }
98
Davide Pesaventoecd44802018-07-23 23:48:10 -040099 m_dataLinkType = pcap_datalink(m_pcap);
100 const char* dltName = pcap_datalink_val_to_name(m_dataLinkType);
101 const char* dltDesc = pcap_datalink_val_to_description(m_dataLinkType);
102 std::string formattedDlt = dltName ? dltName : to_string(m_dataLinkType);
103 if (dltDesc) {
104 formattedDlt += " ("s + dltDesc + ")";
105 }
106
107 std::cerr << "ndndump: " << action << ", link-type " << formattedDlt << std::endl;
108
109 switch (m_dataLinkType) {
110 case DLT_EN10MB:
111 case DLT_LINUX_SLL:
112 case DLT_PPP:
113 // we know how to handle these
114 break;
115 default:
116 BOOST_THROW_EXCEPTION(Error("Unsupported link-layer header type " + formattedDlt));
117 }
118
119 if (!pcapFilter.empty()) {
Davide Pesavento24c08612018-07-26 13:33:24 -0400120 if (wantVerbose) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400121 std::cerr << "ndndump: using pcap filter: " << pcapFilter << std::endl;
Junxiao Shi2222a612015-06-06 08:01:38 -0700122 }
123
124 bpf_program program;
Davide Pesaventofb42a3d2018-07-26 12:33:14 -0400125 int res = pcap_compile(m_pcap, &program, pcapFilter.data(), 1, PCAP_NETMASK_UNKNOWN);
Junxiao Shic1c2b832016-07-24 20:45:36 +0000126 if (res < 0) {
Davide Pesaventofb42a3d2018-07-26 12:33:14 -0400127 BOOST_THROW_EXCEPTION(Error("Cannot compile pcap filter '" + pcapFilter + "': " + pcap_geterr(m_pcap)));
Junxiao Shi2222a612015-06-06 08:01:38 -0700128 }
129
Junxiao Shic1c2b832016-07-24 20:45:36 +0000130 res = pcap_setfilter(m_pcap, &program);
Junxiao Shi2222a612015-06-06 08:01:38 -0700131 pcap_freecode(&program);
Junxiao Shic1c2b832016-07-24 20:45:36 +0000132 if (res < 0) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400133 BOOST_THROW_EXCEPTION(Error("Cannot set pcap filter: "s + pcap_geterr(m_pcap)));
Junxiao Shi2222a612015-06-06 08:01:38 -0700134 }
135 }
136
Davide Pesaventoecd44802018-07-23 23:48:10 -0400137 if (pcap_loop(m_pcap, -1, &pcapCallback, reinterpret_cast<uint8_t*>(this)) < 0) {
138 BOOST_THROW_EXCEPTION(Error("pcap_loop: "s + pcap_geterr(m_pcap)));
Junxiao Shic1c2b832016-07-24 20:45:36 +0000139 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700140}
141
Junxiao Shi2222a612015-06-06 08:01:38 -0700142void
Davide Pesaventoecd44802018-07-23 23:48:10 -0400143NdnDump::printPacket(const pcap_pkthdr* pkthdr, const uint8_t* payload) const
Junxiao Shi2222a612015-06-06 08:01:38 -0700144{
Davide Pesaventoecd44802018-07-23 23:48:10 -0400145 // sanity checks
146 if (pkthdr->caplen == 0) {
147 std::cout << "[Invalid header: caplen=0]" << std::endl;
148 return;
149 }
150 if (pkthdr->len == 0) {
151 std::cout << "[Invalid header: len=0]" << std::endl;
152 return;
153 }
154 else if (pkthdr->len < pkthdr->caplen) {
155 std::cout << "[Invalid header: len(" << pkthdr->len
156 << ") < caplen(" << pkthdr->caplen << ")]" << std::endl;
157 return;
158 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700159
Davide Pesaventoecd44802018-07-23 23:48:10 -0400160 std::ostringstream os;
Davide Pesaventob5b8f952018-07-26 14:19:16 -0400161 if (wantTimestamp) {
162 printTimestamp(os, pkthdr->ts);
163 }
Davide Pesaventoecd44802018-07-23 23:48:10 -0400164
165 ssize_t payloadSize = pkthdr->len;
Junxiao Shi2222a612015-06-06 08:01:38 -0700166
167 int frameType = skipDataLinkHeaderAndGetFrameType(payload, payloadSize);
168 if (frameType < 0) {
Junxiao Shi2222a612015-06-06 08:01:38 -0700169 return;
170 }
171
Junxiao Shic1c2b832016-07-24 20:45:36 +0000172 int res = skipAndProcessFrameHeader(frameType, payload, payloadSize, os);
173 if (res < 0) {
Junxiao Shi2222a612015-06-06 08:01:38 -0700174 return;
175 }
176
177 bool isOk = false;
178 Block block;
179 std::tie(isOk, block) = Block::fromBuffer(payload, payloadSize);
180 if (!isOk) {
Vince Lehman277ecf02016-02-10 16:37:48 -0600181 // if packet is incomplete, we will not be able to process it
182 if (payloadSize > 0) {
183 std::cout << os.str() << ", " << "INCOMPLETE-PACKET" << ", size: " << payloadSize << std::endl;
184 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700185 return;
186 }
187
Vince Lehman277ecf02016-02-10 16:37:48 -0600188 lp::Packet lpPacket;
189 Block netPacket;
190
191 if (block.type() == lp::tlv::LpPacket) {
192 lpPacket = lp::Packet(block);
193
194 Buffer::const_iterator begin, end;
Vince Lehman277ecf02016-02-10 16:37:48 -0600195 if (lpPacket.has<lp::FragmentField>()) {
196 std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
197 }
198 else {
199 std::cout << os.str() << ", " << "NDNLPv2-IDLE" << std::endl;
200 return;
201 }
202
203 bool isOk = false;
204 std::tie(isOk, netPacket) = Block::fromBuffer(&*begin, std::distance(begin, end));
205 if (!isOk) {
206 // if network packet is fragmented, we will not be able to process it
207 std::cout << os.str() << ", " << "NDNLPv2-FRAGMENT" << std::endl;
208 return;
209 }
210 }
211 else {
212 netPacket = block;
213 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700214
215 try {
Vince Lehman277ecf02016-02-10 16:37:48 -0600216 if (netPacket.type() == tlv::Interest) {
217 Interest interest(netPacket);
Junxiao Shi2222a612015-06-06 08:01:38 -0700218 if (matchesFilter(interest.getName())) {
Vince Lehman277ecf02016-02-10 16:37:48 -0600219 if (lpPacket.has<lp::NackField>()) {
220 lp::Nack nack(interest);
221 nack.setHeader(lpPacket.get<lp::NackField>());
Vince Lehman277ecf02016-02-10 16:37:48 -0600222 std::cout << os.str() << ", " << "NACK: " << nack.getReason() << ", " << interest << std::endl;
223 }
224 else {
225 std::cout << os.str() << ", " << "INTEREST: " << interest << std::endl;
226 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700227 }
228 }
Vince Lehman277ecf02016-02-10 16:37:48 -0600229 else if (netPacket.type() == tlv::Data) {
230 Data data(netPacket);
Junxiao Shi2222a612015-06-06 08:01:38 -0700231 if (matchesFilter(data.getName())) {
232 std::cout << os.str() << ", " << "DATA: " << data.getName() << std::endl;
233 }
234 }
Vince Lehman277ecf02016-02-10 16:37:48 -0600235 else {
236 std::cout << os.str() << ", " << "UNKNOWN-NETWORK-PACKET" << std::endl;
237 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700238 }
Junxiao Shic1c2b832016-07-24 20:45:36 +0000239 catch (const tlv::Error& e) {
Junxiao Shi2222a612015-06-06 08:01:38 -0700240 std::cerr << e.what() << std::endl;
241 }
242}
243
244void
Davide Pesaventoecd44802018-07-23 23:48:10 -0400245NdnDump::printTimestamp(std::ostream& os, const timeval& tv) const
Junxiao Shi2222a612015-06-06 08:01:38 -0700246{
Davide Pesaventoecd44802018-07-23 23:48:10 -0400247 /// \todo Add more timestamp formats (time since previous packet, time since first packet, ...)
248 os << tv.tv_sec
Junxiao Shi2222a612015-06-06 08:01:38 -0700249 << "."
Davide Pesaventoecd44802018-07-23 23:48:10 -0400250 << std::setfill('0') << std::setw(6) << tv.tv_usec
251 << " ";
Junxiao Shi2222a612015-06-06 08:01:38 -0700252}
253
254int
Davide Pesaventoecd44802018-07-23 23:48:10 -0400255NdnDump::skipDataLinkHeaderAndGetFrameType(const uint8_t*& payload, ssize_t& payloadSize) const
Junxiao Shi2222a612015-06-06 08:01:38 -0700256{
Davide Pesaventoecd44802018-07-23 23:48:10 -0400257 int frameType = -1;
Junxiao Shi2222a612015-06-06 08:01:38 -0700258
259 switch (m_dataLinkType) {
Junxiao Shic1c2b832016-07-24 20:45:36 +0000260 case DLT_EN10MB: { // Ethernet frames can have Ethernet or 802.3 encapsulation
Davide Pesaventoecd44802018-07-23 23:48:10 -0400261 const ether_header* eh = reinterpret_cast<const ether_header*>(payload);
Junxiao Shi2222a612015-06-06 08:01:38 -0700262
Davide Pesaventoecd44802018-07-23 23:48:10 -0400263 if (payloadSize < ETHER_HDR_LEN) {
264 std::cerr << "Invalid Ethernet frame" << std::endl;
Junxiao Shi2222a612015-06-06 08:01:38 -0700265 return -1;
266 }
267
Davide Pesaventoecd44802018-07-23 23:48:10 -0400268 frameType = ntohs(eh->ether_type);
Davide Pesavento051db002018-07-22 18:56:16 -0400269 payloadSize -= ETHER_HDR_LEN;
270 payload += ETHER_HDR_LEN;
Junxiao Shi2222a612015-06-06 08:01:38 -0700271
272 break;
273 }
Junxiao Shic1c2b832016-07-24 20:45:36 +0000274 case DLT_PPP: {
Junxiao Shi2222a612015-06-06 08:01:38 -0700275 frameType = *payload;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000276 --payloadSize;
277 ++payload;
Junxiao Shi2222a612015-06-06 08:01:38 -0700278
279 if (!(frameType & 1)) {
280 frameType = (frameType << 8) | *payload;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000281 --payloadSize;
282 ++payload;
Junxiao Shi2222a612015-06-06 08:01:38 -0700283 }
284
Davide Pesaventoecd44802018-07-23 23:48:10 -0400285 if (payloadSize < 4) { // PPP_HDRLEN in linux/ppp_defs.h
Junxiao Shi2222a612015-06-06 08:01:38 -0700286 std::cerr << "Invalid PPP frame" << std::endl;
287 return -1;
288 }
289
290 break;
291 }
Junxiao Shi022bddf2016-11-24 23:15:20 +0000292 case DLT_LINUX_SLL: {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400293 const sll_header* sll = reinterpret_cast<const sll_header*>(payload);
Junxiao Shi022bddf2016-11-24 23:15:20 +0000294
295 if (payloadSize < SLL_HDR_LEN) {
296 std::cerr << "Invalid LINUX_SLL frame" << std::endl;
297 return -1;
298 }
299
Davide Pesaventoecd44802018-07-23 23:48:10 -0400300 frameType = ntohs(sll->sll_protocol);
Junxiao Shi022bddf2016-11-24 23:15:20 +0000301 payloadSize -= SLL_HDR_LEN;
302 payload += SLL_HDR_LEN;
303
304 break;
305 }
Davide Pesaventoecd44802018-07-23 23:48:10 -0400306 default:
307 std::cerr << "Unknown frame type" << std::endl;
308 break;
Junxiao Shi2222a612015-06-06 08:01:38 -0700309 }
310
311 return frameType;
312}
313
314int
Davide Pesaventoecd44802018-07-23 23:48:10 -0400315NdnDump::skipAndProcessFrameHeader(int frameType, const uint8_t*& payload, ssize_t& payloadSize,
Junxiao Shic1c2b832016-07-24 20:45:36 +0000316 std::ostream& os) const
Junxiao Shi2222a612015-06-06 08:01:38 -0700317{
Junxiao Shic1c2b832016-07-24 20:45:36 +0000318 switch (frameType) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400319 case ETHERTYPE_IP:
Junxiao Shic1c2b832016-07-24 20:45:36 +0000320 case DLT_EN10MB: { // pcap encapsulation
321 const ip* ipHeader = reinterpret_cast<const ip*>(payload);
Davide Pesavento051db002018-07-22 18:56:16 -0400322 size_t ipHeaderSize = ipHeader->ip_hl * 4;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000323 if (ipHeaderSize < 20) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400324 std::cerr << "Invalid IPv4 header len: " << ipHeaderSize << " bytes" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000325 return -1;
326 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700327
Junxiao Shic1c2b832016-07-24 20:45:36 +0000328 os << "From: " << inet_ntoa(ipHeader->ip_src) << ", ";
329 os << "To: " << inet_ntoa(ipHeader->ip_dst);
Junxiao Shi2222a612015-06-06 08:01:38 -0700330
Junxiao Shic1c2b832016-07-24 20:45:36 +0000331 payloadSize -= ipHeaderSize;
332 payload += ipHeaderSize;
Junxiao Shi2222a612015-06-06 08:01:38 -0700333
Junxiao Shic1c2b832016-07-24 20:45:36 +0000334 if (payloadSize < 0) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400335 std::cerr << "Invalid IPv4 packet" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000336 return -1;
337 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700338
Junxiao Shic1c2b832016-07-24 20:45:36 +0000339 switch (ipHeader->ip_p) {
340 case IPPROTO_UDP: {
Junxiao Shic1c2b832016-07-24 20:45:36 +0000341 payloadSize -= sizeof(udphdr);
342 payload += sizeof(udphdr);
Junxiao Shi2222a612015-06-06 08:01:38 -0700343
Junxiao Shic1c2b832016-07-24 20:45:36 +0000344 if (payloadSize < 0) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400345 std::cerr << "Invalid UDP/IP packet" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000346 return -1;
Junxiao Shi2222a612015-06-06 08:01:38 -0700347 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700348
Junxiao Shic1c2b832016-07-24 20:45:36 +0000349 os << ", Tunnel Type: UDP";
350 break;
351 }
352 case IPPROTO_TCP: {
Junxiao Shic1c2b832016-07-24 20:45:36 +0000353 const tcphdr* tcpHeader = reinterpret_cast<const tcphdr*>(payload);
Davide Pesavento051db002018-07-22 18:56:16 -0400354 size_t tcpHeaderSize = tcpHeader->th_off * 4;
Junxiao Shi2222a612015-06-06 08:01:38 -0700355
Junxiao Shic1c2b832016-07-24 20:45:36 +0000356 if (tcpHeaderSize < 20) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400357 std::cerr << "Invalid TCP header len: " << tcpHeaderSize << " bytes" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000358 return -1;
Junxiao Shi2222a612015-06-06 08:01:38 -0700359 }
Junxiao Shic1c2b832016-07-24 20:45:36 +0000360
361 payloadSize -= tcpHeaderSize;
362 payload += tcpHeaderSize;
363
364 if (payloadSize < 0) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400365 std::cerr << "Invalid TCP/IP packet" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000366 return -1;
367 }
368
369 os << ", Tunnel Type: TCP";
370 break;
371 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700372 default:
373 return -1;
Junxiao Shi2222a612015-06-06 08:01:38 -0700374 }
Junxiao Shic1c2b832016-07-24 20:45:36 +0000375 break;
376 }
Davide Pesaventoecd44802018-07-23 23:48:10 -0400377 case ethernet::ETHERTYPE_NDN:
378 case 0x7777: // NDN ethertype used in ndnSIM
Junxiao Shi2222a612015-06-06 08:01:38 -0700379 os << "Tunnel Type: EthernetFrame";
380 break;
Davide Pesaventoecd44802018-07-23 23:48:10 -0400381 case 0x0077: // protocol field in PPP header used in ndnSIM
Junxiao Shi2222a612015-06-06 08:01:38 -0700382 os << "Tunnel Type: PPP";
383 payloadSize -= 2;
384 payload += 2;
385 break;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000386 default: // do nothing if it is not a recognized type of a packet
Junxiao Shi2222a612015-06-06 08:01:38 -0700387 return -1;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000388 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700389
390 return 0;
391}
392
Junxiao Shic1c2b832016-07-24 20:45:36 +0000393bool
Davide Pesaventoecd44802018-07-23 23:48:10 -0400394NdnDump::matchesFilter(const Name& name) const
Junxiao Shic1c2b832016-07-24 20:45:36 +0000395{
Davide Pesavento78de7352018-07-22 00:35:45 -0400396 if (!nameFilter)
Junxiao Shic1c2b832016-07-24 20:45:36 +0000397 return true;
398
399 /// \todo Switch to NDN regular expressions
Davide Pesavento78de7352018-07-22 00:35:45 -0400400 return std::regex_match(name.toUri(), *nameFilter);
Junxiao Shic1c2b832016-07-24 20:45:36 +0000401}
402
Junxiao Shi3cd47df2015-06-07 20:58:14 -0700403} // namespace dump
Junxiao Shi2222a612015-06-06 08:01:38 -0700404} // namespace ndn