blob: fda16f0a5948fdbb26aa56bf5df4f2ff72241448 [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 Pesaventoecd44802018-07-23 23:48:10 -040085 m_pcap = pcap_open_live(interface.data(), 65535, 0, 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()) {
Junxiao Shi2222a612015-06-06 08:01:38 -0700120 if (isVerbose) {
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 Pesaventoecd44802018-07-23 23:48:10 -0400125 int res = pcap_compile(m_pcap, &program, pcapFilter.data(), 0, PCAP_NETMASK_UNKNOWN);
Junxiao Shic1c2b832016-07-24 20:45:36 +0000126 if (res < 0) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400127 BOOST_THROW_EXCEPTION(Error("Cannot parse pcap filter expression '" + pcapFilter + "': " +
128 pcap_geterr(m_pcap)));
Junxiao Shi2222a612015-06-06 08:01:38 -0700129 }
130
Junxiao Shic1c2b832016-07-24 20:45:36 +0000131 res = pcap_setfilter(m_pcap, &program);
Junxiao Shi2222a612015-06-06 08:01:38 -0700132 pcap_freecode(&program);
Junxiao Shic1c2b832016-07-24 20:45:36 +0000133 if (res < 0) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400134 BOOST_THROW_EXCEPTION(Error("Cannot set pcap filter: "s + pcap_geterr(m_pcap)));
Junxiao Shi2222a612015-06-06 08:01:38 -0700135 }
136 }
137
Davide Pesaventoecd44802018-07-23 23:48:10 -0400138 if (pcap_loop(m_pcap, -1, &pcapCallback, reinterpret_cast<uint8_t*>(this)) < 0) {
139 BOOST_THROW_EXCEPTION(Error("pcap_loop: "s + pcap_geterr(m_pcap)));
Junxiao Shic1c2b832016-07-24 20:45:36 +0000140 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700141}
142
Junxiao Shi2222a612015-06-06 08:01:38 -0700143void
Davide Pesaventoecd44802018-07-23 23:48:10 -0400144NdnDump::printPacket(const pcap_pkthdr* pkthdr, const uint8_t* payload) const
Junxiao Shi2222a612015-06-06 08:01:38 -0700145{
Davide Pesaventoecd44802018-07-23 23:48:10 -0400146 // sanity checks
147 if (pkthdr->caplen == 0) {
148 std::cout << "[Invalid header: caplen=0]" << std::endl;
149 return;
150 }
151 if (pkthdr->len == 0) {
152 std::cout << "[Invalid header: len=0]" << std::endl;
153 return;
154 }
155 else if (pkthdr->len < pkthdr->caplen) {
156 std::cout << "[Invalid header: len(" << pkthdr->len
157 << ") < caplen(" << pkthdr->caplen << ")]" << std::endl;
158 return;
159 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700160
Davide Pesaventoecd44802018-07-23 23:48:10 -0400161 std::ostringstream os;
162 printTimestamp(os, pkthdr->ts);
163
164 ssize_t payloadSize = pkthdr->len;
Junxiao Shi2222a612015-06-06 08:01:38 -0700165
166 int frameType = skipDataLinkHeaderAndGetFrameType(payload, payloadSize);
167 if (frameType < 0) {
Junxiao Shi2222a612015-06-06 08:01:38 -0700168 return;
169 }
170
Junxiao Shic1c2b832016-07-24 20:45:36 +0000171 int res = skipAndProcessFrameHeader(frameType, payload, payloadSize, os);
172 if (res < 0) {
Junxiao Shi2222a612015-06-06 08:01:38 -0700173 return;
174 }
175
176 bool isOk = false;
177 Block block;
178 std::tie(isOk, block) = Block::fromBuffer(payload, payloadSize);
179 if (!isOk) {
Vince Lehman277ecf02016-02-10 16:37:48 -0600180 // if packet is incomplete, we will not be able to process it
181 if (payloadSize > 0) {
182 std::cout << os.str() << ", " << "INCOMPLETE-PACKET" << ", size: " << payloadSize << std::endl;
183 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700184 return;
185 }
186
Vince Lehman277ecf02016-02-10 16:37:48 -0600187 lp::Packet lpPacket;
188 Block netPacket;
189
190 if (block.type() == lp::tlv::LpPacket) {
191 lpPacket = lp::Packet(block);
192
193 Buffer::const_iterator begin, end;
Vince Lehman277ecf02016-02-10 16:37:48 -0600194 if (lpPacket.has<lp::FragmentField>()) {
195 std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
196 }
197 else {
198 std::cout << os.str() << ", " << "NDNLPv2-IDLE" << std::endl;
199 return;
200 }
201
202 bool isOk = false;
203 std::tie(isOk, netPacket) = Block::fromBuffer(&*begin, std::distance(begin, end));
204 if (!isOk) {
205 // if network packet is fragmented, we will not be able to process it
206 std::cout << os.str() << ", " << "NDNLPv2-FRAGMENT" << std::endl;
207 return;
208 }
209 }
210 else {
211 netPacket = block;
212 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700213
214 try {
Vince Lehman277ecf02016-02-10 16:37:48 -0600215 if (netPacket.type() == tlv::Interest) {
216 Interest interest(netPacket);
Junxiao Shi2222a612015-06-06 08:01:38 -0700217 if (matchesFilter(interest.getName())) {
Vince Lehman277ecf02016-02-10 16:37:48 -0600218 if (lpPacket.has<lp::NackField>()) {
219 lp::Nack nack(interest);
220 nack.setHeader(lpPacket.get<lp::NackField>());
Vince Lehman277ecf02016-02-10 16:37:48 -0600221 std::cout << os.str() << ", " << "NACK: " << nack.getReason() << ", " << interest << std::endl;
222 }
223 else {
224 std::cout << os.str() << ", " << "INTEREST: " << interest << std::endl;
225 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700226 }
227 }
Vince Lehman277ecf02016-02-10 16:37:48 -0600228 else if (netPacket.type() == tlv::Data) {
229 Data data(netPacket);
Junxiao Shi2222a612015-06-06 08:01:38 -0700230 if (matchesFilter(data.getName())) {
231 std::cout << os.str() << ", " << "DATA: " << data.getName() << std::endl;
232 }
233 }
Vince Lehman277ecf02016-02-10 16:37:48 -0600234 else {
235 std::cout << os.str() << ", " << "UNKNOWN-NETWORK-PACKET" << std::endl;
236 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700237 }
Junxiao Shic1c2b832016-07-24 20:45:36 +0000238 catch (const tlv::Error& e) {
Junxiao Shi2222a612015-06-06 08:01:38 -0700239 std::cerr << e.what() << std::endl;
240 }
241}
242
243void
Davide Pesaventoecd44802018-07-23 23:48:10 -0400244NdnDump::printTimestamp(std::ostream& os, const timeval& tv) const
Junxiao Shi2222a612015-06-06 08:01:38 -0700245{
Davide Pesaventoecd44802018-07-23 23:48:10 -0400246 /// \todo Add more timestamp formats (time since previous packet, time since first packet, ...)
247 os << tv.tv_sec
Junxiao Shi2222a612015-06-06 08:01:38 -0700248 << "."
Davide Pesaventoecd44802018-07-23 23:48:10 -0400249 << std::setfill('0') << std::setw(6) << tv.tv_usec
250 << " ";
Junxiao Shi2222a612015-06-06 08:01:38 -0700251}
252
253int
Davide Pesaventoecd44802018-07-23 23:48:10 -0400254NdnDump::skipDataLinkHeaderAndGetFrameType(const uint8_t*& payload, ssize_t& payloadSize) const
Junxiao Shi2222a612015-06-06 08:01:38 -0700255{
Davide Pesaventoecd44802018-07-23 23:48:10 -0400256 int frameType = -1;
Junxiao Shi2222a612015-06-06 08:01:38 -0700257
258 switch (m_dataLinkType) {
Junxiao Shic1c2b832016-07-24 20:45:36 +0000259 case DLT_EN10MB: { // Ethernet frames can have Ethernet or 802.3 encapsulation
Davide Pesaventoecd44802018-07-23 23:48:10 -0400260 const ether_header* eh = reinterpret_cast<const ether_header*>(payload);
Junxiao Shi2222a612015-06-06 08:01:38 -0700261
Davide Pesaventoecd44802018-07-23 23:48:10 -0400262 if (payloadSize < ETHER_HDR_LEN) {
263 std::cerr << "Invalid Ethernet frame" << std::endl;
Junxiao Shi2222a612015-06-06 08:01:38 -0700264 return -1;
265 }
266
Davide Pesaventoecd44802018-07-23 23:48:10 -0400267 frameType = ntohs(eh->ether_type);
Davide Pesavento051db002018-07-22 18:56:16 -0400268 payloadSize -= ETHER_HDR_LEN;
269 payload += ETHER_HDR_LEN;
Junxiao Shi2222a612015-06-06 08:01:38 -0700270
271 break;
272 }
Junxiao Shic1c2b832016-07-24 20:45:36 +0000273 case DLT_PPP: {
Junxiao Shi2222a612015-06-06 08:01:38 -0700274 frameType = *payload;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000275 --payloadSize;
276 ++payload;
Junxiao Shi2222a612015-06-06 08:01:38 -0700277
278 if (!(frameType & 1)) {
279 frameType = (frameType << 8) | *payload;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000280 --payloadSize;
281 ++payload;
Junxiao Shi2222a612015-06-06 08:01:38 -0700282 }
283
Davide Pesaventoecd44802018-07-23 23:48:10 -0400284 if (payloadSize < 4) { // PPP_HDRLEN in linux/ppp_defs.h
Junxiao Shi2222a612015-06-06 08:01:38 -0700285 std::cerr << "Invalid PPP frame" << std::endl;
286 return -1;
287 }
288
289 break;
290 }
Junxiao Shi022bddf2016-11-24 23:15:20 +0000291 case DLT_LINUX_SLL: {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400292 const sll_header* sll = reinterpret_cast<const sll_header*>(payload);
Junxiao Shi022bddf2016-11-24 23:15:20 +0000293
294 if (payloadSize < SLL_HDR_LEN) {
295 std::cerr << "Invalid LINUX_SLL frame" << std::endl;
296 return -1;
297 }
298
Davide Pesaventoecd44802018-07-23 23:48:10 -0400299 frameType = ntohs(sll->sll_protocol);
Junxiao Shi022bddf2016-11-24 23:15:20 +0000300 payloadSize -= SLL_HDR_LEN;
301 payload += SLL_HDR_LEN;
302
303 break;
304 }
Davide Pesaventoecd44802018-07-23 23:48:10 -0400305 default:
306 std::cerr << "Unknown frame type" << std::endl;
307 break;
Junxiao Shi2222a612015-06-06 08:01:38 -0700308 }
309
310 return frameType;
311}
312
313int
Davide Pesaventoecd44802018-07-23 23:48:10 -0400314NdnDump::skipAndProcessFrameHeader(int frameType, const uint8_t*& payload, ssize_t& payloadSize,
Junxiao Shic1c2b832016-07-24 20:45:36 +0000315 std::ostream& os) const
Junxiao Shi2222a612015-06-06 08:01:38 -0700316{
Junxiao Shic1c2b832016-07-24 20:45:36 +0000317 switch (frameType) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400318 case ETHERTYPE_IP:
Junxiao Shic1c2b832016-07-24 20:45:36 +0000319 case DLT_EN10MB: { // pcap encapsulation
320 const ip* ipHeader = reinterpret_cast<const ip*>(payload);
Davide Pesavento051db002018-07-22 18:56:16 -0400321 size_t ipHeaderSize = ipHeader->ip_hl * 4;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000322 if (ipHeaderSize < 20) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400323 std::cerr << "Invalid IPv4 header len: " << ipHeaderSize << " bytes" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000324 return -1;
325 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700326
Junxiao Shic1c2b832016-07-24 20:45:36 +0000327 os << "From: " << inet_ntoa(ipHeader->ip_src) << ", ";
328 os << "To: " << inet_ntoa(ipHeader->ip_dst);
Junxiao Shi2222a612015-06-06 08:01:38 -0700329
Junxiao Shic1c2b832016-07-24 20:45:36 +0000330 payloadSize -= ipHeaderSize;
331 payload += ipHeaderSize;
Junxiao Shi2222a612015-06-06 08:01:38 -0700332
Junxiao Shic1c2b832016-07-24 20:45:36 +0000333 if (payloadSize < 0) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400334 std::cerr << "Invalid IPv4 packet" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000335 return -1;
336 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700337
Junxiao Shic1c2b832016-07-24 20:45:36 +0000338 switch (ipHeader->ip_p) {
339 case IPPROTO_UDP: {
Junxiao Shic1c2b832016-07-24 20:45:36 +0000340 payloadSize -= sizeof(udphdr);
341 payload += sizeof(udphdr);
Junxiao Shi2222a612015-06-06 08:01:38 -0700342
Junxiao Shic1c2b832016-07-24 20:45:36 +0000343 if (payloadSize < 0) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400344 std::cerr << "Invalid UDP/IP packet" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000345 return -1;
Junxiao Shi2222a612015-06-06 08:01:38 -0700346 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700347
Junxiao Shic1c2b832016-07-24 20:45:36 +0000348 os << ", Tunnel Type: UDP";
349 break;
350 }
351 case IPPROTO_TCP: {
Junxiao Shic1c2b832016-07-24 20:45:36 +0000352 const tcphdr* tcpHeader = reinterpret_cast<const tcphdr*>(payload);
Davide Pesavento051db002018-07-22 18:56:16 -0400353 size_t tcpHeaderSize = tcpHeader->th_off * 4;
Junxiao Shi2222a612015-06-06 08:01:38 -0700354
Junxiao Shic1c2b832016-07-24 20:45:36 +0000355 if (tcpHeaderSize < 20) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400356 std::cerr << "Invalid TCP header len: " << tcpHeaderSize << " bytes" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000357 return -1;
Junxiao Shi2222a612015-06-06 08:01:38 -0700358 }
Junxiao Shic1c2b832016-07-24 20:45:36 +0000359
360 payloadSize -= tcpHeaderSize;
361 payload += tcpHeaderSize;
362
363 if (payloadSize < 0) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400364 std::cerr << "Invalid TCP/IP packet" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000365 return -1;
366 }
367
368 os << ", Tunnel Type: TCP";
369 break;
370 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700371 default:
372 return -1;
Junxiao Shi2222a612015-06-06 08:01:38 -0700373 }
Junxiao Shic1c2b832016-07-24 20:45:36 +0000374 break;
375 }
Davide Pesaventoecd44802018-07-23 23:48:10 -0400376 case ethernet::ETHERTYPE_NDN:
377 case 0x7777: // NDN ethertype used in ndnSIM
Junxiao Shi2222a612015-06-06 08:01:38 -0700378 os << "Tunnel Type: EthernetFrame";
379 break;
Davide Pesaventoecd44802018-07-23 23:48:10 -0400380 case 0x0077: // protocol field in PPP header used in ndnSIM
Junxiao Shi2222a612015-06-06 08:01:38 -0700381 os << "Tunnel Type: PPP";
382 payloadSize -= 2;
383 payload += 2;
384 break;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000385 default: // do nothing if it is not a recognized type of a packet
Junxiao Shi2222a612015-06-06 08:01:38 -0700386 return -1;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000387 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700388
389 return 0;
390}
391
Junxiao Shic1c2b832016-07-24 20:45:36 +0000392bool
Davide Pesaventoecd44802018-07-23 23:48:10 -0400393NdnDump::matchesFilter(const Name& name) const
Junxiao Shic1c2b832016-07-24 20:45:36 +0000394{
Davide Pesavento78de7352018-07-22 00:35:45 -0400395 if (!nameFilter)
Junxiao Shic1c2b832016-07-24 20:45:36 +0000396 return true;
397
398 /// \todo Switch to NDN regular expressions
Davide Pesavento78de7352018-07-22 00:35:45 -0400399 return std::regex_match(name.toUri(), *nameFilter);
Junxiao Shic1c2b832016-07-24 20:45:36 +0000400}
401
Junxiao Shi3cd47df2015-06-07 20:58:14 -0700402} // namespace dump
Junxiao Shi2222a612015-06-06 08:01:38 -0700403} // namespace ndn