r_extcap/interface.rs
1//! Module containg code to define the extcap interfaces. These are data used to
2//! popuplate the `Capture` or interface list in the main page of Wireshark.
3
4use crate::PrintSentence;
5use std::borrow::Cow;
6use typed_builder::TypedBuilder;
7
8/// Enum defining the data link types.
9pub use pcap_file::DataLink;
10
11/// Metadata for this extcap program. The version will be used for displaying
12/// the version information of the extcap interface in the about dialog of
13/// Wireshark.
14///
15/// A default implementation of `Metadata` is provided as `Metadata::default()`,
16/// which extracts these information from the `version`, `homepage`, and
17/// `description` attributes in the cargo manifest.
18pub struct Metadata {
19 /// The version of this extcap program, displayed in the about dialog of
20 /// Wireshark.
21 pub version: Cow<'static, str>,
22 /// A URL linking to more details about this extcap program. This is the URL
23 /// opened when the help button in the config dialog, or a
24 /// [`HelpButtonControl`][crate::controls::HelpButtonControl] is clicked.
25 pub help_url: Cow<'static, str>,
26 /// A user-friendly description of the extcap program.
27 pub display_description: Cow<'static, str>,
28}
29
30/// ## Example
31///
32/// ```
33/// # use r_extcap::ExtcapFormatter;
34/// use r_extcap::interface::Metadata;
35///
36/// let metadata = Metadata {
37/// version: "3.2.1-test".into(),
38/// help_url: "http://www.wireshark.org".into(),
39/// display_description: "Just for testing".into(),
40/// };
41/// assert_eq!(
42/// format!("{}", ExtcapFormatter(&metadata)),
43/// "extcap {version=3.2.1-test}{help=http://www.wireshark.org}{display=Just for testing}\n"
44/// )
45/// ```
46impl PrintSentence for Metadata {
47 fn format_sentence(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 writeln!(
49 f,
50 "extcap {{version={}}}{{help={}}}{{display={}}}",
51 self.version, self.help_url, self.display_description
52 )
53 }
54}
55
56/// Definition of an interface for this extcap program. An interface is an entry
57/// in the Wireshark homepage, similar to `Wi-Fi: en0`. Instances of this should
58/// be passed to
59/// [`InterfacesStep::list_interfaces`][crate::InterfacesStep::list_interfaces].
60#[derive(Debug, TypedBuilder)]
61pub struct Interface {
62 /// A unique identifier for this interface. This value will be passed back
63 /// from Wireshark in the `--extcap-interface` argument in subsequent calls
64 /// to indicate which interface the user is working with.
65 pub value: Cow<'static, str>,
66 /// A user-readable string describing this interface, which is shown in the
67 /// Wireshark UI.
68 pub display: Cow<'static, str>,
69 /// The DLT associated with this interface. The DLT is used by Wireshark to
70 /// determine how to dissect the packet data given by this extcap program.
71 ///
72 /// Note: While the extcap-example and documentation chapter 8.2 says this
73 /// is a list of DLTs, in reality only one DLT per interface is supported,
74 /// per [this
75 /// thread](https://www.wireshark.org/lists/wireshark-dev/201511/msg00143.html).
76 pub dlt: Dlt,
77}
78
79/// ```
80/// use r_extcap::config::ExtcapFormatter;
81/// use r_extcap::interface::{DataLink, Dlt, Interface};
82/// # let dlt = Dlt {
83/// # data_link_type: DataLink::ETHERNET,
84/// # name: "ETHERNET".into(),
85/// # display: "IEEE 802.3 Ethernet".into(),
86/// # };
87/// assert_eq!(
88/// ExtcapFormatter(&Interface{ value: "MyInterface".into(), display: "My interface".into(), dlt }).to_string(),
89/// "interface {value=MyInterface}{display=My interface}\n",
90/// );
91/// ```
92impl PrintSentence for Interface {
93 fn format_sentence(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 writeln!(
95 f,
96 "interface {{value={}}}{{display={}}}",
97 self.value, self.display,
98 )
99 }
100}
101
102/// Struct defining the DLT to be used for this extcap. Typically the DLT is
103/// defined together with the [`Interface`][crate::interface::Interface] and
104/// passed into
105/// [`InterfacesStep::list_interfaces`][crate::InterfacesStep::list_interfaces].
106/// But you can also use this class standalone and print out the resulting
107/// config using the [`print_sentence`][crate::PrintSentence::print_sentence]
108/// method.
109#[derive(Clone, Debug, TypedBuilder)]
110pub struct Dlt {
111 /// The data link type this packet should be analyzed as.
112 ///
113 /// See: <http://www.tcpdump.org/linktypes.html> for the list of DLTs.
114 pub data_link_type: DataLink,
115
116 /// The name of this DLT. Typically this is the same as the name in
117 /// <http://www.tcpdump.org/linktypes.html> without the `LINKTYPE_` prefix.
118 pub name: Cow<'static, str>,
119
120 /// A user-friendly string describing this DLT.
121 pub display: Cow<'static, str>,
122}
123
124/// Print the configuration line suitable for use with `--extcap-dlts`.
125///
126/// ## Example
127/// ```
128/// use r_extcap::config::ExtcapFormatter;
129/// use r_extcap::interface::{DataLink, Dlt};
130///
131/// let dlt = Dlt {
132/// data_link_type: DataLink::ETHERNET,
133/// name: "ETHERNET".into(),
134/// display: "IEEE 802.3 Ethernet".into(),
135/// };
136/// assert_eq!(
137/// ExtcapFormatter(&dlt).to_string(),
138/// "dlt {number=1}{name=ETHERNET}{display=IEEE 802.3 Ethernet}\n",
139/// );
140/// ```
141impl PrintSentence for Dlt {
142 fn format_sentence(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
143 writeln!(
144 f,
145 "dlt {{number={}}}{{name={}}}{{display={}}}",
146 <u32>::from(self.data_link_type),
147 self.name,
148 self.display
149 )
150 }
151}