blob: 41bf066b322a699b88377fa553a6d4689f54d99d [file] [log] [blame]
Davide Pesaventofe0580c2017-05-12 02:02:10 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento264af772021-02-09 21:48:24 -05002/*
Davide Pesaventoa599d2a2022-02-16 18:52:43 -05003 * Copyright (c) 2014-2022, Regents of the University of California,
Davide Pesaventofe0580c2017-05-12 02:02:10 -04004 * 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.
10 *
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/>.
24 */
25
26#ifndef NFD_DAEMON_FACE_PCAP_HELPER_HPP
27#define NFD_DAEMON_FACE_PCAP_HELPER_HPP
28
29#include "core/common.hpp"
30
Davide Pesavento264af772021-02-09 21:48:24 -050031#ifndef NFD_HAVE_LIBPCAP
Davide Pesaventofe0580c2017-05-12 02:02:10 -040032#error "Cannot include this file when libpcap is not available"
33#endif
34
35// forward declarations
36struct pcap;
37typedef pcap pcap_t;
38
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040039namespace nfd::face {
Davide Pesaventofe0580c2017-05-12 02:02:10 -040040
41/**
42 * @brief Helper class for dealing with libpcap handles.
43 */
44class PcapHelper : noncopyable
45{
46public:
47 class Error : public std::runtime_error
48 {
49 public:
50 explicit
51 Error(const std::string& what)
52 : std::runtime_error(what)
53 {
54 }
55 };
56
57 /**
58 * @brief Create a libpcap context for live packet capture on a network interface.
59 * @throw Error on any error
60 * @sa pcap_create(3pcap)
61 */
62 explicit
63 PcapHelper(const std::string& interfaceName);
64
65 ~PcapHelper();
66
67 /**
68 * @brief Start capturing packets.
69 * @param dlt The link-layer header type to be used.
70 * @throw Error on any error
71 * @sa pcap_activate(3pcap), pcap_set_datalink(3pcap)
72 */
73 void
74 activate(int dlt);
75
76 /**
77 * @brief Stop capturing and close the handle.
78 * @sa pcap_close(3pcap)
79 */
80 void
Davide Pesaventoa599d2a2022-02-16 18:52:43 -050081 close() noexcept;
Davide Pesaventofe0580c2017-05-12 02:02:10 -040082
83 /**
84 * @brief Obtain a file descriptor that can be used in calls such as select(2) and poll(2).
85 * @pre activate() has been called.
86 * @return A selectable file descriptor. It is the caller's responsibility to close the fd.
87 * @throw Error on any error
88 * @sa pcap_get_selectable_fd(3pcap)
89 */
90 int
91 getFd() const;
92
93 /**
94 * @brief Get last error message.
95 * @return Human-readable explanation of the last libpcap error.
96 * @warning The behavior is undefined if no error occurred.
97 * @sa pcap_geterr(3pcap)
98 */
99 std::string
Davide Pesaventoa599d2a2022-02-16 18:52:43 -0500100 getLastError() const noexcept;
Davide Pesaventofe0580c2017-05-12 02:02:10 -0400101
102 /**
103 * @brief Get the number of packets dropped by the kernel, as reported by libpcap.
104 * @throw Error on any error
105 * @sa pcap_stats(3pcap)
106 */
107 size_t
108 getNDropped() const;
109
110 /**
111 * @brief Install a BPF filter on the receiving socket.
112 * @param filter Null-terminated string containing the BPF program source.
113 * @pre activate() has been called.
114 * @throw Error on any error
115 * @sa pcap_setfilter(3pcap), pcap-filter(7)
116 */
117 void
118 setPacketFilter(const char* filter) const;
119
120 /**
121 * @brief Read the next packet captured on the interface.
Davide Pesaventoa599d2a2022-02-16 18:52:43 -0500122 * @return If successful, returns a tuple containing a read-only view of the received
123 * packet bytes (including the link-layer header) and a second element that
124 * must be ignored. On failure, returns a tuple containing an empty span and
125 * the reason for the failure.
126 * @warning The returned span is valid only until the next call to this function.
Davide Pesaventofe0580c2017-05-12 02:02:10 -0400127 * @sa pcap_next_ex(3pcap)
128 */
Davide Pesaventoa599d2a2022-02-16 18:52:43 -0500129 std::tuple<span<const uint8_t>, std::string>
130 readNextPacket() const noexcept;
Davide Pesaventofe0580c2017-05-12 02:02:10 -0400131
Davide Pesaventoa599d2a2022-02-16 18:52:43 -0500132 operator pcap_t*() const noexcept
Davide Pesaventofe0580c2017-05-12 02:02:10 -0400133 {
134 return m_pcap;
135 }
136
137private:
138 pcap_t* m_pcap;
139};
140
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400141} // namespace nfd::face
Davide Pesaventofe0580c2017-05-12 02:02:10 -0400142
143#endif // NFD_DAEMON_FACE_PCAP_HELPER_HPP