blob: 4c4382672ef43134db75919894e9e72754109c4c [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;
161 printTimestamp(os, pkthdr->ts);
162
163 ssize_t payloadSize = pkthdr->len;
Junxiao Shi2222a612015-06-06 08:01:38 -0700164
165 int frameType = skipDataLinkHeaderAndGetFrameType(payload, payloadSize);
166 if (frameType < 0) {
Junxiao Shi2222a612015-06-06 08:01:38 -0700167 return;
168 }
169
Junxiao Shic1c2b832016-07-24 20:45:36 +0000170 int res = skipAndProcessFrameHeader(frameType, payload, payloadSize, os);
171 if (res < 0) {
Junxiao Shi2222a612015-06-06 08:01:38 -0700172 return;
173 }
174
175 bool isOk = false;
176 Block block;
177 std::tie(isOk, block) = Block::fromBuffer(payload, payloadSize);
178 if (!isOk) {
Vince Lehman277ecf02016-02-10 16:37:48 -0600179 // if packet is incomplete, we will not be able to process it
180 if (payloadSize > 0) {
181 std::cout << os.str() << ", " << "INCOMPLETE-PACKET" << ", size: " << payloadSize << std::endl;
182 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700183 return;
184 }
185
Vince Lehman277ecf02016-02-10 16:37:48 -0600186 lp::Packet lpPacket;
187 Block netPacket;
188
189 if (block.type() == lp::tlv::LpPacket) {
190 lpPacket = lp::Packet(block);
191
192 Buffer::const_iterator begin, end;
Vince Lehman277ecf02016-02-10 16:37:48 -0600193 if (lpPacket.has<lp::FragmentField>()) {
194 std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
195 }
196 else {
197 std::cout << os.str() << ", " << "NDNLPv2-IDLE" << std::endl;
198 return;
199 }
200
201 bool isOk = false;
202 std::tie(isOk, netPacket) = Block::fromBuffer(&*begin, std::distance(begin, end));
203 if (!isOk) {
204 // if network packet is fragmented, we will not be able to process it
205 std::cout << os.str() << ", " << "NDNLPv2-FRAGMENT" << std::endl;
206 return;
207 }
208 }
209 else {
210 netPacket = block;
211 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700212
213 try {
Vince Lehman277ecf02016-02-10 16:37:48 -0600214 if (netPacket.type() == tlv::Interest) {
215 Interest interest(netPacket);
Junxiao Shi2222a612015-06-06 08:01:38 -0700216 if (matchesFilter(interest.getName())) {
Vince Lehman277ecf02016-02-10 16:37:48 -0600217 if (lpPacket.has<lp::NackField>()) {
218 lp::Nack nack(interest);
219 nack.setHeader(lpPacket.get<lp::NackField>());
Vince Lehman277ecf02016-02-10 16:37:48 -0600220 std::cout << os.str() << ", " << "NACK: " << nack.getReason() << ", " << interest << std::endl;
221 }
222 else {
223 std::cout << os.str() << ", " << "INTEREST: " << interest << std::endl;
224 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700225 }
226 }
Vince Lehman277ecf02016-02-10 16:37:48 -0600227 else if (netPacket.type() == tlv::Data) {
228 Data data(netPacket);
Junxiao Shi2222a612015-06-06 08:01:38 -0700229 if (matchesFilter(data.getName())) {
230 std::cout << os.str() << ", " << "DATA: " << data.getName() << std::endl;
231 }
232 }
Vince Lehman277ecf02016-02-10 16:37:48 -0600233 else {
234 std::cout << os.str() << ", " << "UNKNOWN-NETWORK-PACKET" << std::endl;
235 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700236 }
Junxiao Shic1c2b832016-07-24 20:45:36 +0000237 catch (const tlv::Error& e) {
Junxiao Shi2222a612015-06-06 08:01:38 -0700238 std::cerr << e.what() << std::endl;
239 }
240}
241
242void
Davide Pesaventoecd44802018-07-23 23:48:10 -0400243NdnDump::printTimestamp(std::ostream& os, const timeval& tv) const
Junxiao Shi2222a612015-06-06 08:01:38 -0700244{
Davide Pesaventoecd44802018-07-23 23:48:10 -0400245 /// \todo Add more timestamp formats (time since previous packet, time since first packet, ...)
246 os << tv.tv_sec
Junxiao Shi2222a612015-06-06 08:01:38 -0700247 << "."
Davide Pesaventoecd44802018-07-23 23:48:10 -0400248 << std::setfill('0') << std::setw(6) << tv.tv_usec
249 << " ";
Junxiao Shi2222a612015-06-06 08:01:38 -0700250}
251
252int
Davide Pesaventoecd44802018-07-23 23:48:10 -0400253NdnDump::skipDataLinkHeaderAndGetFrameType(const uint8_t*& payload, ssize_t& payloadSize) const
Junxiao Shi2222a612015-06-06 08:01:38 -0700254{
Davide Pesaventoecd44802018-07-23 23:48:10 -0400255 int frameType = -1;
Junxiao Shi2222a612015-06-06 08:01:38 -0700256
257 switch (m_dataLinkType) {
Junxiao Shic1c2b832016-07-24 20:45:36 +0000258 case DLT_EN10MB: { // Ethernet frames can have Ethernet or 802.3 encapsulation
Davide Pesaventoecd44802018-07-23 23:48:10 -0400259 const ether_header* eh = reinterpret_cast<const ether_header*>(payload);
Junxiao Shi2222a612015-06-06 08:01:38 -0700260
Davide Pesaventoecd44802018-07-23 23:48:10 -0400261 if (payloadSize < ETHER_HDR_LEN) {
262 std::cerr << "Invalid Ethernet frame" << std::endl;
Junxiao Shi2222a612015-06-06 08:01:38 -0700263 return -1;
264 }
265
Davide Pesaventoecd44802018-07-23 23:48:10 -0400266 frameType = ntohs(eh->ether_type);
Davide Pesavento051db002018-07-22 18:56:16 -0400267 payloadSize -= ETHER_HDR_LEN;
268 payload += ETHER_HDR_LEN;
Junxiao Shi2222a612015-06-06 08:01:38 -0700269
270 break;
271 }
Junxiao Shic1c2b832016-07-24 20:45:36 +0000272 case DLT_PPP: {
Junxiao Shi2222a612015-06-06 08:01:38 -0700273 frameType = *payload;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000274 --payloadSize;
275 ++payload;
Junxiao Shi2222a612015-06-06 08:01:38 -0700276
277 if (!(frameType & 1)) {
278 frameType = (frameType << 8) | *payload;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000279 --payloadSize;
280 ++payload;
Junxiao Shi2222a612015-06-06 08:01:38 -0700281 }
282
Davide Pesaventoecd44802018-07-23 23:48:10 -0400283 if (payloadSize < 4) { // PPP_HDRLEN in linux/ppp_defs.h
Junxiao Shi2222a612015-06-06 08:01:38 -0700284 std::cerr << "Invalid PPP frame" << std::endl;
285 return -1;
286 }
287
288 break;
289 }
Junxiao Shi022bddf2016-11-24 23:15:20 +0000290 case DLT_LINUX_SLL: {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400291 const sll_header* sll = reinterpret_cast<const sll_header*>(payload);
Junxiao Shi022bddf2016-11-24 23:15:20 +0000292
293 if (payloadSize < SLL_HDR_LEN) {
294 std::cerr << "Invalid LINUX_SLL frame" << std::endl;
295 return -1;
296 }
297
Davide Pesaventoecd44802018-07-23 23:48:10 -0400298 frameType = ntohs(sll->sll_protocol);
Junxiao Shi022bddf2016-11-24 23:15:20 +0000299 payloadSize -= SLL_HDR_LEN;
300 payload += SLL_HDR_LEN;
301
302 break;
303 }
Davide Pesaventoecd44802018-07-23 23:48:10 -0400304 default:
305 std::cerr << "Unknown frame type" << std::endl;
306 break;
Junxiao Shi2222a612015-06-06 08:01:38 -0700307 }
308
309 return frameType;
310}
311
312int
Davide Pesaventoecd44802018-07-23 23:48:10 -0400313NdnDump::skipAndProcessFrameHeader(int frameType, const uint8_t*& payload, ssize_t& payloadSize,
Junxiao Shic1c2b832016-07-24 20:45:36 +0000314 std::ostream& os) const
Junxiao Shi2222a612015-06-06 08:01:38 -0700315{
Junxiao Shic1c2b832016-07-24 20:45:36 +0000316 switch (frameType) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400317 case ETHERTYPE_IP:
Junxiao Shic1c2b832016-07-24 20:45:36 +0000318 case DLT_EN10MB: { // pcap encapsulation
319 const ip* ipHeader = reinterpret_cast<const ip*>(payload);
Davide Pesavento051db002018-07-22 18:56:16 -0400320 size_t ipHeaderSize = ipHeader->ip_hl * 4;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000321 if (ipHeaderSize < 20) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400322 std::cerr << "Invalid IPv4 header len: " << ipHeaderSize << " bytes" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000323 return -1;
324 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700325
Junxiao Shic1c2b832016-07-24 20:45:36 +0000326 os << "From: " << inet_ntoa(ipHeader->ip_src) << ", ";
327 os << "To: " << inet_ntoa(ipHeader->ip_dst);
Junxiao Shi2222a612015-06-06 08:01:38 -0700328
Junxiao Shic1c2b832016-07-24 20:45:36 +0000329 payloadSize -= ipHeaderSize;
330 payload += ipHeaderSize;
Junxiao Shi2222a612015-06-06 08:01:38 -0700331
Junxiao Shic1c2b832016-07-24 20:45:36 +0000332 if (payloadSize < 0) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400333 std::cerr << "Invalid IPv4 packet" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000334 return -1;
335 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700336
Junxiao Shic1c2b832016-07-24 20:45:36 +0000337 switch (ipHeader->ip_p) {
338 case IPPROTO_UDP: {
Junxiao Shic1c2b832016-07-24 20:45:36 +0000339 payloadSize -= sizeof(udphdr);
340 payload += sizeof(udphdr);
Junxiao Shi2222a612015-06-06 08:01:38 -0700341
Junxiao Shic1c2b832016-07-24 20:45:36 +0000342 if (payloadSize < 0) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400343 std::cerr << "Invalid UDP/IP packet" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000344 return -1;
Junxiao Shi2222a612015-06-06 08:01:38 -0700345 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700346
Junxiao Shic1c2b832016-07-24 20:45:36 +0000347 os << ", Tunnel Type: UDP";
348 break;
349 }
350 case IPPROTO_TCP: {
Junxiao Shic1c2b832016-07-24 20:45:36 +0000351 const tcphdr* tcpHeader = reinterpret_cast<const tcphdr*>(payload);
Davide Pesavento051db002018-07-22 18:56:16 -0400352 size_t tcpHeaderSize = tcpHeader->th_off * 4;
Junxiao Shi2222a612015-06-06 08:01:38 -0700353
Junxiao Shic1c2b832016-07-24 20:45:36 +0000354 if (tcpHeaderSize < 20) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400355 std::cerr << "Invalid TCP header len: " << tcpHeaderSize << " bytes" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000356 return -1;
Junxiao Shi2222a612015-06-06 08:01:38 -0700357 }
Junxiao Shic1c2b832016-07-24 20:45:36 +0000358
359 payloadSize -= tcpHeaderSize;
360 payload += tcpHeaderSize;
361
362 if (payloadSize < 0) {
Davide Pesaventoecd44802018-07-23 23:48:10 -0400363 std::cerr << "Invalid TCP/IP packet" << std::endl;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000364 return -1;
365 }
366
367 os << ", Tunnel Type: TCP";
368 break;
369 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700370 default:
371 return -1;
Junxiao Shi2222a612015-06-06 08:01:38 -0700372 }
Junxiao Shic1c2b832016-07-24 20:45:36 +0000373 break;
374 }
Davide Pesaventoecd44802018-07-23 23:48:10 -0400375 case ethernet::ETHERTYPE_NDN:
376 case 0x7777: // NDN ethertype used in ndnSIM
Junxiao Shi2222a612015-06-06 08:01:38 -0700377 os << "Tunnel Type: EthernetFrame";
378 break;
Davide Pesaventoecd44802018-07-23 23:48:10 -0400379 case 0x0077: // protocol field in PPP header used in ndnSIM
Junxiao Shi2222a612015-06-06 08:01:38 -0700380 os << "Tunnel Type: PPP";
381 payloadSize -= 2;
382 payload += 2;
383 break;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000384 default: // do nothing if it is not a recognized type of a packet
Junxiao Shi2222a612015-06-06 08:01:38 -0700385 return -1;
Junxiao Shic1c2b832016-07-24 20:45:36 +0000386 }
Junxiao Shi2222a612015-06-06 08:01:38 -0700387
388 return 0;
389}
390
Junxiao Shic1c2b832016-07-24 20:45:36 +0000391bool
Davide Pesaventoecd44802018-07-23 23:48:10 -0400392NdnDump::matchesFilter(const Name& name) const
Junxiao Shic1c2b832016-07-24 20:45:36 +0000393{
Davide Pesavento78de7352018-07-22 00:35:45 -0400394 if (!nameFilter)
Junxiao Shic1c2b832016-07-24 20:45:36 +0000395 return true;
396
397 /// \todo Switch to NDN regular expressions
Davide Pesavento78de7352018-07-22 00:35:45 -0400398 return std::regex_match(name.toUri(), *nameFilter);
Junxiao Shic1c2b832016-07-24 20:45:36 +0000399}
400
Junxiao Shi3cd47df2015-06-07 20:58:14 -0700401} // namespace dump
Junxiao Shi2222a612015-06-06 08:01:38 -0700402} // namespace ndn