1use std::ffi::CString;
2
3use crate::{cstr_to_string, raw, Error};
4
5#[derive(Debug, PartialEq, Eq, Clone, Copy)]
16pub struct Linktype(pub i32);
17
18impl Linktype {
19 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 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 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}