1#![warn(clippy::all)]
50#![warn(clippy::pedantic)]
51#![allow(clippy::module_name_repetitions)]
52
53pub mod error;
54pub mod flow;
55pub mod layer;
56pub mod packet;
57pub mod pcap;
58pub mod utils;
59
60pub use error::{PacketError, Result};
62pub use layer::arp::{ARP_FIXED_HEADER_LEN, ARP_HEADER_LEN, ArpRoute, HardwareAddr, ProtocolAddr};
63pub use layer::bindings::{
64 BindingRegistry, apply_binding, expected_upper_layers, find_binding, find_bindings_from,
65 find_bindings_to, infer_upper_layer,
66};
67pub use layer::ethernet::{
68 DOT3_MAX_LENGTH, ETHERNET_HEADER_LEN, EthernetFrameType, dispatch_hook, is_dot3, is_ethernet_ii,
69};
70pub use layer::neighbor::{
71 ArpCache, CacheEntry, NdpCache, ipv4_multicast_mac, ipv6_multicast_mac, is_ipv4_multicast,
72 is_ipv6_multicast, solicited_node_multicast,
73};
74pub use layer::quic::builder::QuicBuilder;
75pub use layer::{
76 ArpBuilder,
78 ArpLayer,
80 BytesField,
82 DnsLayer,
83 Dot3Builder,
84 Dot3Layer,
85 EthernetBuilder,
86 EthernetLayer,
87 Field,
88 FieldDesc,
89 FieldError,
90 FieldType,
91 FieldValue,
92 Http2Builder,
93 Http2FrameBuilder,
94 HttpRequestBuilder,
95 HttpResponseBuilder,
96 ICMPV6_MIN_HEADER_LEN,
97 IPV6_HEADER_LEN,
98 IcmpBuilder,
99 IcmpLayer,
100 Icmpv6Builder,
101 Icmpv6Layer,
102 IntoLayerStackEntry,
104 Ipv4Builder,
105 Ipv4Flags,
106 Ipv4Layer,
107 Ipv6Builder,
108 Ipv6Layer,
109 L2TP_FIELD_NAMES,
110 L2TP_MIN_HEADER_LEN,
111 L2TP_PORT,
112 L2tpBuilder,
113 L2tpLayer,
114 LAYER_BINDINGS,
115 Layer,
117 LayerBinding,
119 LayerEnum,
120 LayerIndex,
121 LayerKind,
122 LayerStack,
123 LayerStackEntry,
124 MacAddress,
125 NeighborCache,
127 NeighborResolver,
128 RAW_FIELDS,
129 RawBuilder,
130 RawLayer,
131 SSH_BINARY_HEADER_LEN,
132 SSH_PORT,
133 SshBuilder,
134 SshLayer,
135 TcpBuilder,
136 TcpFlags,
137 TcpLayer,
138 TlsRecordBuilder,
139 UdpBuilder,
140 UdpLayer,
141 icmpv6_checksum,
142 verify_icmpv6_checksum,
143};
144pub use packet::Packet;
145pub use pcap::{
146 CapturedPacket, LinkType, PcapIterator, PcapMetadata, rdpcap, wrpcap, wrpcap_packets,
147};
148
149pub use flow::{
151 CanonicalKey, ConversationState, ConversationStatus, ConversationTable, DirectionStats,
152 FlowConfig, FlowDirection, FlowError, ProtocolState, TransportProtocol, extract_flows,
153 extract_flows_with_config,
154};
155
156pub use utils::{
158 align_to, ethernet_min_frame, extract_bits, hexdump, hexstr, hexstr_sep, internet_checksum,
159 pad_to, parse_hex, set_bits, transport_checksum, verify_checksum,
160};
161
162pub mod ethertype {
164 pub use crate::layer::ethertype::*;
165}
166
167pub mod ip_protocol {
169 pub use crate::layer::ip_protocol::*;
170}
171
172pub mod arp_opcode {
174 pub use crate::layer::arp::opcode::*;
175}
176
177pub mod arp_hardware {
179 pub use crate::layer::arp::hardware_type::*;
180}
181
182pub mod arp_protocol {
184 pub use crate::layer::arp::protocol_type::*;
185}
186
187pub mod prelude {
189 pub use crate::arp_hardware;
190 pub use crate::arp_opcode;
191 pub use crate::ethertype;
192 pub use crate::{
193 ARP_HEADER_LEN,
194 ArpBuilder,
195 ArpCache,
196 ArpLayer,
198 BindingRegistry,
199 BytesField,
200 Dot3Builder,
201 Dot3Layer,
202 ETHERNET_HEADER_LEN,
203 EthernetBuilder,
204 EthernetLayer,
206 Field,
207 FieldDesc,
208 FieldError,
209 FieldType,
210 FieldValue,
211 HardwareAddr,
212 IntoLayerStackEntry,
214 Ipv4Builder,
215 Ipv4Flags,
216 Layer,
217 LayerBinding,
219 LayerEnum,
220 LayerIndex,
221 LayerKind,
222 LayerStack,
223 LayerStackEntry,
224 MacAddress,
226 NdpCache,
227 NeighborCache,
229 Packet,
231 PacketError,
232 ProtocolAddr,
233 RawBuilder,
235 RawLayer,
236 Result,
237 TcpBuilder,
238 TcpFlags,
239 apply_binding,
240 find_binding,
241 ipv4_multicast_mac,
242 ipv6_multicast_mac,
243 is_dot3,
244 is_ethernet_ii,
245 };
246 pub use std::net::{Ipv4Addr, Ipv6Addr};
247}
248
249pub const VERSION: &str = env!("CARGO_PKG_VERSION");
251
252pub fn version() -> &'static str {
254 VERSION
255}
256
257#[cfg(test)]
258mod tests {
259 use super::prelude::*;
260
261 #[test]
262 fn test_basic_packet_creation() {
263 let eth = EthernetBuilder::new()
265 .dst(MacAddress::BROADCAST)
266 .src(MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]))
267 .build_with_payload(LayerKind::Arp);
268
269 let arp = ArpBuilder::who_has(Ipv4Addr::new(192, 168, 1, 100))
271 .hwsrc(MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]))
272 .psrc(Ipv4Addr::new(192, 168, 1, 1))
273 .build();
274
275 let mut packet_data = eth;
277 packet_data.extend_from_slice(&arp);
278
279 let mut packet = Packet::from_bytes(packet_data);
281 packet.parse().unwrap();
282
283 assert_eq!(packet.layer_count(), 2);
284
285 let eth_layer = packet.ethernet().unwrap();
286 assert_eq!(
287 eth_layer.ethertype(packet.as_bytes()).unwrap(),
288 ethertype::ARP
289 );
290
291 let arp_layer = packet.arp().unwrap();
292 assert!(arp_layer.is_request(packet.as_bytes()));
293 }
294
295 #[test]
296 fn test_layer_bindings() {
297 let binding = find_binding(LayerKind::Ethernet, LayerKind::Arp);
299 assert!(binding.is_some());
300 assert_eq!(binding.unwrap().field_value, 0x0806);
301
302 let (field, value) = apply_binding(LayerKind::Ethernet, LayerKind::Ipv4).unwrap();
304 assert_eq!(field, "type");
305 assert_eq!(value, 0x0800);
306 }
307
308 #[test]
309 fn test_neighbor_resolution() {
310 let _cache = NeighborCache::new();
311
312 let mcast_ip = Ipv4Addr::new(224, 0, 0, 1);
314 let mcast_mac = ipv4_multicast_mac(mcast_ip);
315 assert!(mcast_mac.is_multicast());
316 assert!(mcast_mac.is_ipv4_multicast());
317 }
318
319 #[test]
320 fn test_frame_type_dispatch() {
321 let eth2 = vec![
323 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x08,
324 0x00, ];
326 assert!(!is_dot3(ð2, 0));
327 assert!(is_ethernet_ii(ð2, 0));
328
329 let dot3 = vec![
331 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x00,
332 0x64, ];
334 assert!(is_dot3(&dot3, 0));
335 assert!(!is_ethernet_ii(&dot3, 0));
336 }
337}