pcap/
linktype.rs

1use std::ffi::CString;
2
3use crate::{cstr_to_string, raw, Error};
4
5/// This is a datalink link type.
6///
7/// As an example, `Linktype(1)` is ethernet. A full list of linktypes is available
8/// [here](http://www.tcpdump.org/linktypes.html). The const bellow are not exhaustive.
9/// ```rust
10/// use pcap::Linktype;
11///
12/// let lt = Linktype(1);
13/// assert_eq!(Linktype::ETHERNET, lt);
14/// ```
15#[derive(Debug, PartialEq, Eq, Clone, Copy)]
16pub struct Linktype(pub i32);
17
18impl Linktype {
19    /// Gets the name of the link type, such as EN10MB
20    pub fn get_name(&self) -> Result<String, Error> {
21        unsafe { cstr_to_string(raw::pcap_datalink_val_to_name(self.0)) }?
22            .ok_or(Error::InvalidLinktype)
23    }
24
25    /// Gets the description of a link type.
26    pub fn get_description(&self) -> Result<String, Error> {
27        unsafe { cstr_to_string(raw::pcap_datalink_val_to_description(self.0)) }?
28            .ok_or(Error::InvalidLinktype)
29    }
30
31    /// Gets the linktype from a name string
32    pub fn from_name(name: &str) -> Result<Linktype, Error> {
33        let name = CString::new(name)?;
34        let val = unsafe { raw::pcap_datalink_name_to_val(name.as_ptr()) };
35        if val == -1 {
36            return Err(Error::InvalidLinktype);
37        }
38
39        Ok(Linktype(val))
40    }
41
42    pub const NULL: Self = Self(0);
43    pub const ETHERNET: Self = Self(1);
44    pub const AX25: Self = Self(3);
45    pub const IEEE802_5: Self = Self(6);
46    pub const ARCNET_BSD: Self = Self(7);
47    pub const SLIP: Self = Self(8);
48    pub const PPP: Self = Self(9);
49    pub const FDDI: Self = Self(10);
50    pub const PPP_HDLC: Self = Self(50);
51    pub const PPP_ETHER: Self = Self(51);
52    pub const ATM_RFC1483: Self = Self(100);
53    pub const RAW: Self = Self(101);
54    pub const C_HDLC: Self = Self(104);
55    pub const IEEE802_11: Self = Self(105);
56    pub const FRELAY: Self = Self(107);
57    pub const LOOP: Self = Self(108);
58    pub const LINUX_SLL: Self = Self(113);
59    pub const LTALK: Self = Self(114);
60    pub const PFLOG: Self = Self(117);
61    pub const IEEE802_11_PRISM: Self = Self(119);
62    pub const IP_OVER_FC: Self = Self(122);
63    pub const SUNATM: Self = Self(123);
64    pub const IEEE802_11_RADIOTAP: Self = Self(127);
65    pub const ARCNET_LINUX: Self = Self(129);
66    pub const APPLE_IP_OVER_IEEE1394: Self = Self(138);
67    pub const MTP2_WITH_PHDR: Self = Self(139);
68    pub const MTP2: Self = Self(140);
69    pub const MTP3: Self = Self(141);
70    pub const SCCP: Self = Self(142);
71    pub const DOCSIS: Self = Self(143);
72    pub const LINUX_IRDA: Self = Self(144);
73    pub const USER0: Self = Self(147);
74    pub const USER1: Self = Self(148);
75    pub const USER2: Self = Self(149);
76    pub const USER3: Self = Self(150);
77    pub const USER4: Self = Self(151);
78    pub const USER5: Self = Self(152);
79    pub const USER6: Self = Self(153);
80    pub const USER7: Self = Self(154);
81    pub const USER8: Self = Self(155);
82    pub const USER9: Self = Self(156);
83    pub const USER10: Self = Self(157);
84    pub const USER11: Self = Self(158);
85    pub const USER12: Self = Self(159);
86    pub const USER13: Self = Self(160);
87    pub const USER14: Self = Self(161);
88    pub const USER15: Self = Self(162);
89    pub const IEEE802_11_AVS: Self = Self(163);
90    pub const BACNET_MS_TP: Self = Self(165);
91    pub const PPP_PPPD: Self = Self(166);
92    pub const GPRS_LLC: Self = Self(169);
93    pub const GPF_T: Self = Self(170);
94    pub const GPF_F: Self = Self(171);
95    pub const LINUX_LAPD: Self = Self(177);
96    pub const MFR: Self = Self(182);
97    pub const BLUETOOTH_HCI_H4: Self = Self(187);
98    pub const USB_LINUX: Self = Self(189);
99    pub const PPI: Self = Self(192);
100    pub const IEEE802_15_4_WITHFCS: Self = Self(195);
101    pub const SITA: Self = Self(196);
102    pub const ERF: Self = Self(197);
103    pub const BLUETOOTH_HCI_H4_WITH_PHDR: Self = Self(201);
104    pub const AX25_KISS: Self = Self(202);
105    pub const LAPD: Self = Self(203);
106    pub const PPP_WITH_DIR: Self = Self(204);
107    pub const C_HDLC_WITH_DIR: Self = Self(205);
108    pub const FRELAY_WITH_DIR: Self = Self(206);
109    pub const LAPB_WITH_DIR: Self = Self(207);
110    pub const IPMB_LINUX: Self = Self(209);
111    pub const IEEE802_15_4_NONASK_PHY: Self = Self(215);
112    pub const USB_LINUX_MMAPPED: Self = Self(220);
113    pub const FC_2: Self = Self(224);
114    pub const FC_2_WITH_FRAME_DELIMS: Self = Self(225);
115    pub const IPNET: Self = Self(226);
116    pub const CAN_SOCKETCAN: Self = Self(227);
117    pub const IPV4: Self = Self(228);
118    pub const IPV6: Self = Self(229);
119    pub const IEEE802_15_4_NOFCS: Self = Self(230);
120    pub const DBUS: Self = Self(231);
121    pub const DVB_CI: Self = Self(235);
122    pub const MUX27010: Self = Self(236);
123    pub const STANAG_5066_D_PDU: Self = Self(237);
124    pub const NFLOG: Self = Self(239);
125    pub const NETANALYZER: Self = Self(240);
126    pub const NETANALYZER_TRANSPARENT: Self = Self(241);
127    pub const IPOIB: Self = Self(242);
128    pub const MPEG_2_TS: Self = Self(243);
129    pub const NG40: Self = Self(244);
130    pub const NFC_LLCP: Self = Self(245);
131    pub const INFINIBAND: Self = Self(247);
132    pub const SCTP: Self = Self(248);
133    pub const USBPCAP: Self = Self(249);
134    pub const RTAC_SERIAL: Self = Self(250);
135    pub const BLUETOOTH_LE_LL: Self = Self(251);
136    pub const NETLINK: Self = Self(253);
137    pub const BLUETOOTH_LINUX_MONITOR: Self = Self(254);
138    pub const BLUETOOTH_BREDR_BB: Self = Self(255);
139    pub const BLUETOOTH_LE_LL_WITH_PHDR: Self = Self(256);
140    pub const PROFIBUS_DL: Self = Self(257);
141    pub const PKTAP: Self = Self(258);
142    pub const EPON: Self = Self(259);
143    pub const IPMI_HPM_2: Self = Self(260);
144    pub const ZWAVE_R1_R2: Self = Self(261);
145    pub const ZWAVE_R3: Self = Self(262);
146    pub const WATTSTOPPER_DLM: Self = Self(263);
147    pub const ISO_14443: Self = Self(264);
148    pub const RDS: Self = Self(265);
149    pub const USB_DARWIN: Self = Self(266);
150    pub const SDLC: Self = Self(268);
151    pub const LORATAP: Self = Self(270);
152    pub const VSOCK: Self = Self(271);
153    pub const NORDIC_BLE: Self = Self(272);
154    pub const DOCSIS31_XRA31: Self = Self(273);
155    pub const ETHERNET_MPACKET: Self = Self(274);
156    pub const DISPLAYPORT_AUX: Self = Self(275);
157    pub const LINUX_SLL2: Self = Self(276);
158    pub const OPENVIZSLA: Self = Self(278);
159    pub const EBHSCR: Self = Self(279);
160    pub const VPP_DISPATCH: Self = Self(280);
161    pub const DSA_TAG_BRCM: Self = Self(281);
162    pub const DSA_TAG_BRCM_PREPEND: Self = Self(282);
163    pub const IEEE802_15_4_TAP: Self = Self(283);
164    pub const DSA_TAG_DSA: Self = Self(284);
165    pub const DSA_TAG_EDSA: Self = Self(285);
166    pub const ELEE: Self = Self(286);
167    pub const Z_WAVE_SERIAL: Self = Self(287);
168    pub const USB_2_0: Self = Self(288);
169    pub const ATSC_ALP: Self = Self(289);
170}
171
172#[cfg(test)]
173mod tests {
174    use crate::raw::testmod::RAWMTX;
175
176    use super::*;
177
178    #[test]
179    fn test_get_name() {
180        let _m = RAWMTX.lock();
181        let name = "datalink name";
182
183        let cstr = CString::new(name).unwrap();
184        let ctx = raw::pcap_datalink_val_to_name_context();
185        ctx.expect().return_once(|_| cstr.into_raw());
186
187        let linktype_name = Linktype::ARCNET_LINUX.get_name().unwrap();
188        assert_eq!(&linktype_name, name);
189    }
190
191    #[test]
192    fn test_get_description() {
193        let _m = RAWMTX.lock();
194        let desc = "datalink description";
195
196        let cstr = CString::new(desc).unwrap();
197        let ctx = raw::pcap_datalink_val_to_description_context();
198        ctx.expect().return_once(|_| cstr.into_raw());
199
200        let linktype_name = Linktype::ARCNET_LINUX.get_description().unwrap();
201        assert_eq!(&linktype_name, desc);
202    }
203
204    #[test]
205    fn test_from_name() {
206        let _m = RAWMTX.lock();
207
208        let ctx = raw::pcap_datalink_name_to_val_context();
209        ctx.expect().return_once(|_| 7);
210
211        let linktype = Linktype::from_name("git rekt scrub").unwrap();
212        assert_eq!(linktype, Linktype::ARCNET_BSD);
213
214        let ctx = raw::pcap_datalink_name_to_val_context();
215        ctx.checkpoint();
216        ctx.expect().return_once(|_| -1);
217
218        let err = Linktype::from_name("git rekt scrub").unwrap_err();
219        assert_eq!(err, Error::InvalidLinktype);
220    }
221}