1use enum_dispatch::enum_dispatch;
7
8pub mod arp;
9pub mod bindings;
10pub mod dhcp;
11pub mod dns;
12pub mod dot11;
13pub mod dot15d4;
14pub mod ethernet;
15pub mod field;
16pub mod field_ext;
17pub mod ftp;
18pub mod generic;
19pub mod http;
20pub mod http2;
21pub mod icmp;
22pub mod icmpv6;
23pub mod imap;
24pub mod ipv4;
25pub mod ipv6;
26pub mod l2tp;
27pub mod modbus;
28pub mod mqtt;
29pub mod mqttsn;
30pub mod neighbor;
31pub mod pop3;
32pub mod quic;
33pub mod raw;
34pub mod smtp;
35pub mod ssh;
36pub mod stack;
37pub mod tcp;
38pub mod tftp;
39pub mod tls;
40pub mod udp;
41pub mod zwave;
42
43use std::ops::Range;
44
45pub use arp::{ArpBuilder, ArpLayer};
47pub use bindings::{LAYER_BINDINGS, LayerBinding};
48pub use ethernet::{Dot3Builder, Dot3Layer, EthernetBuilder, EthernetLayer};
49pub use field::{BytesField, Field, FieldDesc, FieldError, FieldType, FieldValue, MacAddress};
50pub use ftp::{
51 FTP_CONTROL_PORT, FTP_DATA_PORT, FTP_FIELD_NAMES, FTP_MIN_HEADER_LEN, FtpBuilder, FtpLayer,
52 is_ftp_payload,
53};
54pub use http::{HTTP_FIELD_NAMES, HttpLayer, HttpRequestBuilder, HttpResponseBuilder};
55pub use http2::{HTTP2_FIELD_NAMES, Http2Builder, Http2FrameBuilder, Http2Layer};
56pub use icmp::{ICMP_MIN_HEADER_LEN, IcmpBuilder, IcmpLayer, icmp_checksum, verify_icmp_checksum};
57pub use icmpv6::{
58 ICMPV6_MIN_HEADER_LEN, Icmpv6Builder, Icmpv6Layer, icmpv6_checksum, verify_icmpv6_checksum,
59};
60pub use imap::{
61 IMAP_FIELD_NAMES, IMAP_MIN_HEADER_LEN, IMAP_PORT, ImapBuilder, ImapLayer, is_imap_payload,
62};
63pub use ipv4::{Ipv4Builder, Ipv4Flags, Ipv4Layer, Ipv4Options, Ipv4Route};
64pub use ipv6::{IPV6_HEADER_LEN, Ipv6Builder, Ipv6Layer};
65pub use l2tp::{L2TP_FIELD_NAMES, L2TP_MIN_HEADER_LEN, L2TP_PORT, L2tpBuilder, L2tpLayer};
66pub use modbus::{
67 MODBUS_FIELD_NAMES, MODBUS_MIN_HEADER_LEN, MODBUS_TCP_PORT, ModbusBuilder, ModbusLayer,
68 is_modbus_tcp_payload,
69};
70pub use mqtt::{
71 MQTT_FIELD_NAMES, MQTT_MIN_HEADER_LEN, MQTT_PORT, MqttBuilder, MqttLayer, is_mqtt_payload,
72};
73pub use mqttsn::{
74 MQTTSN_FIELD_NAMES, MQTTSN_MIN_HEADER_LEN, MQTTSN_PORT, MqttSnBuilder, MqttSnLayer,
75 is_mqttsn_payload,
76};
77pub use neighbor::{NeighborCache, NeighborResolver};
78pub use pop3::{
79 POP3_FIELD_NAMES, POP3_MIN_HEADER_LEN, POP3_PORT, Pop3Builder, Pop3Layer, is_pop3_payload,
80};
81pub use raw::{RAW_FIELDS, RawBuilder, RawLayer};
82pub use smtp::{
83 SMTP_FIELD_NAMES, SMTP_MIN_HEADER_LEN, SMTP_PORT, SmtpBuilder, SmtpLayer, is_smtp_payload,
84};
85pub use ssh::{SSH_BINARY_HEADER_LEN, SSH_PORT, SshBuilder, SshLayer};
86pub use stack::{IntoLayerStackEntry, LayerStack, LayerStackEntry};
87pub use tcp::{
88 TCP_FIELDS, TCP_MAX_HEADER_LEN, TCP_MIN_HEADER_LEN, TCP_SERVICES, TcpAoValue, TcpBuilder,
89 TcpFlags, TcpLayer, TcpOption, TcpOptionKind, TcpOptions, TcpOptionsBuilder, TcpSackBlock,
90 TcpTimestamp, service_name, service_port, tcp_checksum, tcp_checksum_ipv4, verify_tcp_checksum,
91};
92pub use tftp::{TFTP_MIN_HEADER_LEN, TFTP_PORT, TftpBuilder, TftpLayer, is_tftp_payload};
93pub use tls::{
94 TLS_FIELDS, TLS_PORT, TLS_RECORD_HEADER_LEN, TlsAlertBuilder, TlsCcsBuilder, TlsContentType,
95 TlsLayer, TlsRecordBuilder, TlsVersion,
96};
97pub use udp::{
98 UDP_HEADER_LEN, UdpBuilder, UdpLayer, udp_checksum_ipv4, udp_checksum_ipv6,
99 verify_udp_checksum_ipv4, verify_udp_checksum_ipv6,
100};
101pub use zwave::{
102 ZWAVE_FIELD_NAMES, ZWAVE_HEADER_LEN, ZWAVE_MIN_HEADER_LEN, ZWaveBuilder, ZWaveLayer,
103};
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
107#[repr(u8)]
108pub enum LayerKind {
109 Ethernet = 0,
110 Dot3 = 1,
111 Arp = 2,
112 Ipv4 = 3,
113 Ipv6 = 4,
114 Icmp = 5,
115 Icmpv6 = 6,
116 Tcp = 7,
117 Udp = 8,
118 Dns = 9,
119 Dot1Q = 10,
120 Dot1AD = 11,
121 Dot1AH = 12,
122 LLC = 13,
123 SNAP = 14,
124 Ssh = 15,
125 Tls = 16,
126 Dot15d4 = 17,
127 Dot15d4Fcs = 18,
128 Dot11 = 19,
129 Http = 20,
130 Quic = 21,
131 Generic = 22,
132 Http2 = 23,
133 L2tp = 24,
134 Mqtt = 25,
135 MqttSn = 26,
136 Modbus = 27,
137 ZWave = 28,
138 Ftp = 29,
139 Tftp = 30,
140 Smtp = 31,
141 Pop3 = 32,
142 Imap = 33,
143 Dhcp = 34,
144 Raw = 255,
145}
146
147impl LayerKind {
148 #[inline]
149 #[must_use]
150 pub const fn name(&self) -> &'static str {
151 match self {
152 Self::Ethernet => "Ethernet",
153 Self::Dot3 => "802.3",
154 Self::Arp => "ARP",
155 Self::Ipv4 => "IPv4",
156 Self::Ipv6 => "IPv6",
157 Self::Icmp => "ICMP",
158 Self::Icmpv6 => "ICMPv6",
159 Self::Tcp => "TCP",
160 Self::Udp => "UDP",
161 Self::Dns => "DNS",
162 Self::Dot1Q => "802.1Q",
163 Self::Dot1AD => "802.1AD",
164 Self::Dot1AH => "802.1AH",
165 Self::LLC => "LLC",
166 Self::SNAP => "SNAP",
167 Self::Ssh => "SSH",
168 Self::Tls => "TLS",
169 Self::Dot15d4 => "802.15.4",
170 Self::Dot15d4Fcs => "802.15.4 FCS",
171 Self::Dot11 => "802.11",
172 Self::Http => "HTTP",
173 Self::Quic => "QUIC",
174 Self::Generic => "Generic",
175 Self::Http2 => "HTTP/2",
176 Self::L2tp => "L2TP",
177 Self::Mqtt => "MQTT",
178 Self::MqttSn => "MQTT-SN",
179 Self::Modbus => "Modbus",
180 Self::ZWave => "Z-Wave",
181 Self::Ftp => "FTP",
182 Self::Tftp => "TFTP",
183 Self::Smtp => "SMTP",
184 Self::Pop3 => "POP3",
185 Self::Imap => "IMAP",
186 Self::Dhcp => "DHCP",
187 Self::Raw => "Raw",
188 }
189 }
190
191 #[inline]
192 #[must_use]
193 pub const fn min_header_size(&self) -> usize {
194 match self {
195 Self::Ethernet | Self::Dot3 => ethernet::ETHERNET_HEADER_LEN,
196 Self::Arp => arp::ARP_HEADER_LEN,
197 Self::Ipv4 => ipv4::IPV4_MIN_HEADER_LEN,
198 Self::Ipv6 => 40,
199 Self::Icmp | Self::Icmpv6 => 8,
200 Self::Tcp => tcp::TCP_MIN_HEADER_LEN,
201 Self::Udp => 8,
202 Self::Dns => 12,
203 Self::Dot1Q => 4,
204 Self::Dot1AD => 4,
205 Self::Dot1AH => 6,
206 Self::LLC => 3,
207 Self::SNAP => 5,
208 Self::Ssh => ssh::SSH_BINARY_HEADER_LEN,
209 Self::Tls => tls::TLS_RECORD_HEADER_LEN,
210 Self::Dot15d4 => 3, Self::Dot15d4Fcs => 5, Self::Dot11 => dot11::DOT11_MIN_HEADER_LEN,
213 Self::Http => 14, Self::Quic => quic::QUIC_MIN_HEADER_LEN,
215 Self::Generic => 0,
216 Self::Http2 => 9, Self::L2tp => l2tp::L2TP_MIN_HEADER_LEN,
218 Self::Mqtt => mqtt::MQTT_MIN_HEADER_LEN,
219 Self::MqttSn => mqttsn::MQTTSN_MIN_HEADER_LEN,
220 Self::Modbus => modbus::MODBUS_MIN_HEADER_LEN,
221 Self::ZWave => zwave::ZWAVE_MIN_HEADER_LEN,
222 Self::Ftp => ftp::FTP_MIN_HEADER_LEN,
223 Self::Tftp => tftp::TFTP_MIN_HEADER_LEN,
224 Self::Smtp => smtp::SMTP_MIN_HEADER_LEN,
225 Self::Pop3 => pop3::POP3_MIN_HEADER_LEN,
226 Self::Imap => imap::IMAP_MIN_HEADER_LEN,
227 Self::Dhcp => dhcp::DHCP_MIN_HEADER_LEN,
228 Self::Raw => 0,
229 }
230 }
231
232 #[inline]
234 #[must_use]
235 pub const fn is_link_layer(&self) -> bool {
236 matches!(
237 self,
238 Self::Ethernet | Self::Dot3 | Self::Dot1Q | Self::Dot1AD | Self::Dot1AH
239 )
240 }
241
242 #[inline]
244 #[must_use]
245 pub const fn is_network_layer(&self) -> bool {
246 matches!(self, Self::Ipv4 | Self::Ipv6 | Self::Arp)
247 }
248
249 #[inline]
251 #[must_use]
252 pub const fn is_transport_layer(&self) -> bool {
253 matches!(self, Self::Tcp | Self::Udp | Self::Icmp | Self::Icmpv6)
254 }
255}
256
257impl std::fmt::Display for LayerKind {
258 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
259 write!(f, "{}", self.name())
260 }
261}
262
263#[derive(Debug, Clone, Copy, PartialEq, Eq)]
265pub struct LayerIndex {
266 pub kind: LayerKind,
267 pub start: usize,
268 pub end: usize,
269}
270
271impl LayerIndex {
272 #[inline]
273 #[must_use]
274 pub const fn new(kind: LayerKind, start: usize, end: usize) -> Self {
275 Self { kind, start, end }
276 }
277
278 #[inline]
279 #[must_use]
280 pub const fn range(&self) -> Range<usize> {
281 self.start..self.end
282 }
283
284 #[inline]
285 #[must_use]
286 pub const fn len(&self) -> usize {
287 self.end - self.start
288 }
289
290 #[inline]
291 #[must_use]
292 pub const fn is_empty(&self) -> bool {
293 self.start == self.end
294 }
295
296 #[inline]
298 #[must_use]
299 pub fn slice<'a>(&self, buf: &'a [u8]) -> &'a [u8] {
300 &buf[self.start..self.end.min(buf.len())]
301 }
302
303 #[inline]
305 pub fn slice_mut<'a>(&self, buf: &'a mut [u8]) -> &'a mut [u8] {
306 let end = self.end.min(buf.len());
307 &mut buf[self.start..end]
308 }
309
310 #[inline]
312 #[must_use]
313 pub fn payload<'a>(&self, buf: &'a [u8]) -> &'a [u8] {
314 &buf[self.end.min(buf.len())..]
315 }
316}
317
318#[enum_dispatch]
323pub trait LayerDispatch {
324 fn dispatch_kind(&self) -> LayerKind;
326 fn dispatch_index(&self) -> &LayerIndex;
328 fn dispatch_summary(&self, buf: &[u8]) -> String;
330 fn dispatch_header_len(&self, buf: &[u8]) -> usize;
332 fn dispatch_hashret(&self, _buf: &[u8]) -> Vec<u8> {
334 vec![]
335 }
336 fn dispatch_field_names(&self) -> &'static [&'static str];
338 fn dispatch_get_field(&self, buf: &[u8], name: &str) -> Option<Result<FieldValue, FieldError>>;
340 fn dispatch_set_field(
342 &self,
343 buf: &mut [u8],
344 name: &str,
345 value: FieldValue,
346 ) -> Option<Result<(), FieldError>>;
347 fn dispatch_show_fields(&self, buf: &[u8]) -> Vec<(&'static str, String)>;
349}
350
351macro_rules! impl_layer_dispatch {
358 ($ty:ty, show = $show_fn:expr) => {
360 impl LayerDispatch for $ty {
361 #[inline]
362 fn dispatch_kind(&self) -> LayerKind {
363 Layer::kind(self)
364 }
365 #[inline]
366 fn dispatch_index(&self) -> &LayerIndex {
367 &self.index
368 }
369 #[inline]
370 fn dispatch_summary(&self, buf: &[u8]) -> String {
371 Layer::summary(self, buf)
372 }
373 #[inline]
374 fn dispatch_header_len(&self, buf: &[u8]) -> usize {
375 Layer::header_len(self, buf)
376 }
377 #[inline]
378 fn dispatch_hashret(&self, buf: &[u8]) -> Vec<u8> {
379 Layer::hashret(self, buf)
380 }
381 #[inline]
382 fn dispatch_field_names(&self) -> &'static [&'static str] {
383 Layer::field_names(self)
384 }
385 #[inline]
386 fn dispatch_get_field(
387 &self,
388 buf: &[u8],
389 name: &str,
390 ) -> Option<Result<FieldValue, FieldError>> {
391 self.get_field(buf, name)
392 }
393 #[inline]
394 fn dispatch_set_field(
395 &self,
396 buf: &mut [u8],
397 name: &str,
398 value: FieldValue,
399 ) -> Option<Result<(), FieldError>> {
400 self.set_field(buf, name, value)
401 }
402 #[inline]
403 fn dispatch_show_fields(&self, buf: &[u8]) -> Vec<(&'static str, String)> {
404 $show_fn(self, buf)
405 }
406 }
407 };
408 ($ty:ty, show = $show_fn:expr, readonly) => {
410 impl LayerDispatch for $ty {
411 #[inline]
412 fn dispatch_kind(&self) -> LayerKind {
413 Layer::kind(self)
414 }
415 #[inline]
416 fn dispatch_index(&self) -> &LayerIndex {
417 &self.index
418 }
419 #[inline]
420 fn dispatch_summary(&self, buf: &[u8]) -> String {
421 Layer::summary(self, buf)
422 }
423 #[inline]
424 fn dispatch_header_len(&self, buf: &[u8]) -> usize {
425 Layer::header_len(self, buf)
426 }
427 #[inline]
428 fn dispatch_hashret(&self, buf: &[u8]) -> Vec<u8> {
429 Layer::hashret(self, buf)
430 }
431 #[inline]
432 fn dispatch_field_names(&self) -> &'static [&'static str] {
433 Layer::field_names(self)
434 }
435 #[inline]
436 fn dispatch_get_field(
437 &self,
438 buf: &[u8],
439 name: &str,
440 ) -> Option<Result<FieldValue, FieldError>> {
441 self.get_field(buf, name)
442 }
443 #[inline]
444 fn dispatch_set_field(
445 &self,
446 _buf: &mut [u8],
447 _name: &str,
448 _value: FieldValue,
449 ) -> Option<Result<(), FieldError>> {
450 None
451 }
452 #[inline]
453 fn dispatch_show_fields(&self, buf: &[u8]) -> Vec<(&'static str, String)> {
454 $show_fn(self, buf)
455 }
456 }
457 };
458 ($ty:ty, show = $show_fn:expr, inherent, kind = $kind:expr, header_len = $hdr:expr) => {
460 impl LayerDispatch for $ty {
461 #[inline]
462 fn dispatch_kind(&self) -> LayerKind {
463 $kind
464 }
465 #[inline]
466 fn dispatch_index(&self) -> &LayerIndex {
467 &self.index
468 }
469 #[inline]
470 fn dispatch_summary(&self, buf: &[u8]) -> String {
471 self.summary(buf)
472 }
473 #[inline]
474 fn dispatch_header_len(&self, _buf: &[u8]) -> usize {
475 $hdr
476 }
477 #[inline]
478 fn dispatch_hashret(&self, buf: &[u8]) -> Vec<u8> {
479 self.hashret(buf)
480 }
481 #[inline]
482 fn dispatch_field_names(&self) -> &'static [&'static str] {
483 <$ty>::field_names()
484 }
485 #[inline]
486 fn dispatch_get_field(
487 &self,
488 buf: &[u8],
489 name: &str,
490 ) -> Option<Result<FieldValue, FieldError>> {
491 self.get_field(buf, name)
492 }
493 #[inline]
494 fn dispatch_set_field(
495 &self,
496 buf: &mut [u8],
497 name: &str,
498 value: FieldValue,
499 ) -> Option<Result<(), FieldError>> {
500 self.set_field(buf, name, value)
501 }
502 #[inline]
503 fn dispatch_show_fields(&self, buf: &[u8]) -> Vec<(&'static str, String)> {
504 $show_fn(self, buf)
505 }
506 }
507 };
508}
509
510pub trait Layer {
516 fn kind(&self) -> LayerKind;
518
519 fn summary(&self, data: &[u8]) -> String;
521
522 fn header_len(&self, data: &[u8]) -> usize;
524
525 fn hashret(&self, _data: &[u8]) -> Vec<u8> {
527 vec![]
528 }
529
530 fn answers(&self, _data: &[u8], _other: &Self, _other_data: &[u8]) -> bool {
532 false
533 }
534
535 fn extract_padding<'a>(&self, data: &'a [u8]) -> (&'a [u8], &'a [u8]) {
537 let header_len = self.header_len(data);
538 (&data[header_len..], &[])
539 }
540
541 fn field_names(&self) -> &'static [&'static str] {
543 &[]
544 }
545}
546
547#[derive(Debug, Clone)]
552#[enum_dispatch(LayerDispatch)]
553pub enum LayerEnum {
554 Ethernet(EthernetLayer),
555 Dot3(Dot3Layer),
556 Arp(ArpLayer),
557 Ipv4(Ipv4Layer),
558 Ipv6(Ipv6Layer),
559 Icmp(IcmpLayer),
560 Icmpv6(Icmpv6Layer),
561 Tcp(TcpLayer),
562 Udp(UdpLayer),
563 Dns(DnsLayer),
564 Ssh(SshLayer),
565 Tls(TlsLayer),
566 Dot15d4(dot15d4::Dot15d4Layer),
567 Dot15d4Fcs(dot15d4::Dot15d4FcsLayer),
568 Dot11(dot11::Dot11Layer),
569 Http(http::HttpLayer),
570 Http2(http2::Http2Layer),
571 Quic(quic::QuicLayer),
572 L2tp(l2tp::L2tpLayer),
573 Mqtt(mqtt::MqttLayer),
574 MqttSn(mqttsn::MqttSnLayer),
575 Modbus(modbus::ModbusLayer),
576 ZWave(zwave::ZWaveLayer),
577 Ftp(ftp::FtpLayer),
578 Tftp(tftp::TftpLayer),
579 Smtp(smtp::SmtpLayer),
580 Pop3(pop3::Pop3Layer),
581 Imap(imap::ImapLayer),
582 Dhcp(dhcp::DhcpLayer),
583 Raw(RawLayer),
584}
585
586impl LayerEnum {
587 #[inline]
589 #[must_use]
590 pub fn kind(&self) -> LayerKind {
591 self.dispatch_kind()
592 }
593
594 #[inline]
596 #[must_use]
597 pub fn index(&self) -> &LayerIndex {
598 self.dispatch_index()
599 }
600
601 #[must_use]
603 pub fn summary(&self, buf: &[u8]) -> String {
604 self.dispatch_summary(buf)
605 }
606
607 #[must_use]
609 pub fn hashret(&self, buf: &[u8]) -> Vec<u8> {
610 self.dispatch_hashret(buf)
611 }
612
613 #[must_use]
615 pub fn header_len(&self, buf: &[u8]) -> usize {
616 self.dispatch_header_len(buf)
617 }
618
619 #[must_use]
621 pub fn show_fields(&self, buf: &[u8]) -> Vec<(&'static str, String)> {
622 self.dispatch_show_fields(buf)
623 }
624
625 #[must_use]
627 pub fn get_field(&self, buf: &[u8], name: &str) -> Option<Result<FieldValue, FieldError>> {
628 self.dispatch_get_field(buf, name)
629 }
630
631 pub fn set_field(
633 &self,
634 buf: &mut [u8],
635 name: &str,
636 value: FieldValue,
637 ) -> Option<Result<(), FieldError>> {
638 self.dispatch_set_field(buf, name, value)
639 }
640
641 #[must_use]
643 pub fn field_names(&self) -> &'static [&'static str] {
644 self.dispatch_field_names()
645 }
646}
647
648fn ethernet_show_fields(l: &EthernetLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
653 let mut fields = Vec::new();
654 fields.push((
655 "dst",
656 l.dst(buf).map_or_else(|_| "?".into(), |m| m.to_string()),
657 ));
658 fields.push((
659 "src",
660 l.src(buf).map_or_else(|_| "?".into(), |m| m.to_string()),
661 ));
662 let etype = l.ethertype(buf).unwrap_or(0);
663 fields.push((
664 "type",
665 format!("{:#06x} ({})", etype, ethertype::name(etype)),
666 ));
667 fields
668}
669
670fn dot3_show_fields(l: &Dot3Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
671 let mut fields = Vec::new();
672 fields.push((
673 "dst",
674 l.dst(buf).map_or_else(|_| "?".into(), |m| m.to_string()),
675 ));
676 fields.push((
677 "src",
678 l.src(buf).map_or_else(|_| "?".into(), |m| m.to_string()),
679 ));
680 fields.push((
681 "len",
682 l.len_field(buf)
683 .map_or_else(|_| "?".into(), |v| v.to_string()),
684 ));
685 fields
686}
687
688fn arp_show_fields(l: &ArpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
689 let mut fields = Vec::new();
690 let hwtype = l.hwtype(buf).unwrap_or(0);
691 fields.push((
692 "hwtype",
693 format!("{:#06x} ({})", hwtype, arp::hardware_type::name(hwtype)),
694 ));
695 let ptype = l.ptype(buf).unwrap_or(0);
696 fields.push(("ptype", format!("{ptype:#06x}")));
697 fields.push((
698 "hwlen",
699 l.hwlen(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
700 ));
701 fields.push((
702 "plen",
703 l.plen(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
704 ));
705 let op = l.op(buf).unwrap_or(0);
706 fields.push(("op", format!("{} ({})", op, arp::opcode::name(op))));
707 fields.push((
708 "hwsrc",
709 l.hwsrc_raw(buf)
710 .map_or_else(|_| "?".into(), |a| a.to_string()),
711 ));
712 fields.push((
713 "psrc",
714 l.psrc_raw(buf)
715 .map_or_else(|_| "?".into(), |a| a.to_string()),
716 ));
717 fields.push((
718 "hwdst",
719 l.hwdst_raw(buf)
720 .map_or_else(|_| "?".into(), |a| a.to_string()),
721 ));
722 fields.push((
723 "pdst",
724 l.pdst_raw(buf)
725 .map_or_else(|_| "?".into(), |a| a.to_string()),
726 ));
727 fields
728}
729
730fn ipv4_show_fields(l: &Ipv4Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
731 let mut fields = Vec::new();
732 fields.push((
733 "version",
734 l.version(buf)
735 .map_or_else(|_| "?".into(), |v| v.to_string()),
736 ));
737 fields.push((
738 "ihl",
739 l.ihl(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
740 ));
741 fields.push((
742 "tos",
743 l.tos(buf)
744 .map_or_else(|_| "?".into(), |v| format!("{v:#04x}")),
745 ));
746 fields.push((
747 "len",
748 l.total_len(buf)
749 .map_or_else(|_| "?".into(), |v| v.to_string()),
750 ));
751 fields.push((
752 "id",
753 l.id(buf)
754 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
755 ));
756 fields.push((
757 "flags",
758 l.flags(buf).map_or_else(|_| "?".into(), |f| f.to_string()),
759 ));
760 fields.push((
761 "frag",
762 l.frag_offset(buf)
763 .map_or_else(|_| "?".into(), |v| v.to_string()),
764 ));
765 fields.push((
766 "ttl",
767 l.ttl(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
768 ));
769 let proto = l.protocol(buf).unwrap_or(0);
770 fields.push(("proto", format!("{} ({})", proto, l.protocol_name(buf))));
771 fields.push((
772 "chksum",
773 l.checksum(buf)
774 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
775 ));
776 fields.push((
777 "src",
778 l.src(buf).map_or_else(|_| "?".into(), |ip| ip.to_string()),
779 ));
780 fields.push((
781 "dst",
782 l.dst(buf).map_or_else(|_| "?".into(), |ip| ip.to_string()),
783 ));
784 let opts_len = l.options_len(buf);
786 if opts_len > 0 {
787 fields.push(("options", format!("[{opts_len} bytes]")));
788 }
789 fields
790}
791
792fn ipv6_show_fields(l: &Ipv6Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
793 let mut fields = Vec::new();
794 fields.push((
795 "version",
796 l.version(buf)
797 .map_or_else(|_| "?".into(), |v| v.to_string()),
798 ));
799 fields.push((
800 "tc",
801 l.traffic_class(buf)
802 .map_or_else(|_| "?".into(), |v| format!("{v:#04x}")),
803 ));
804 fields.push((
805 "fl",
806 l.flow_label(buf)
807 .map_or_else(|_| "?".into(), |v| format!("{v:#07x}")),
808 ));
809 fields.push((
810 "plen",
811 l.payload_len(buf)
812 .map_or_else(|_| "?".into(), |v| v.to_string()),
813 ));
814 let nh = l.next_header(buf).unwrap_or(0);
815 fields.push(("nh", format!("{} ({})", nh, ipv4::protocol::to_name(nh))));
816 fields.push((
817 "hlim",
818 l.hop_limit(buf)
819 .map_or_else(|_| "?".into(), |v| v.to_string()),
820 ));
821 fields.push((
822 "src",
823 l.src(buf).map_or_else(|_| "?".into(), |a| a.to_string()),
824 ));
825 fields.push((
826 "dst",
827 l.dst(buf).map_or_else(|_| "?".into(), |a| a.to_string()),
828 ));
829 fields
830}
831
832fn icmp_show_fields(l: &IcmpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
833 let mut fields = Vec::new();
834
835 fields.push((
837 "type",
838 l.icmp_type(buf).map_or_else(
839 |_| "?".into(),
840 |t: u8| format!("{} ({})", t, icmp::type_name(t)),
841 ),
842 ));
843
844 fields.push((
846 "code",
847 l.code(buf)
848 .map_or_else(|_| "?".into(), |c: u8| c.to_string()),
849 ));
850
851 fields.push((
853 "chksum",
854 l.checksum(buf)
855 .map_or_else(|_| "?".into(), |v: u16| format!("{v:#06x}")),
856 ));
857
858 if let Ok(Some(id)) = l.id(buf) {
860 fields.push(("id", format!("{id:#06x}")));
861 }
862
863 if let Ok(Some(seq)) = l.seq(buf) {
865 fields.push(("seq", seq.to_string()));
866 }
867
868 if let Ok(Some(gateway)) = l.gateway(buf) {
870 fields.push(("gw", gateway.to_string()));
871 }
872
873 if let Ok(Some(ptr)) = l.ptr(buf) {
875 fields.push(("ptr", ptr.to_string()));
876 }
877
878 if let Ok(Some(mtu)) = l.next_hop_mtu(buf) {
880 fields.push(("mtu", mtu.to_string()));
881 }
882
883 if let Ok(Some(ts_ori)) = l.ts_ori(buf) {
885 fields.push(("ts_ori", ts_ori.to_string()));
886 }
887 if let Ok(Some(ts_rx)) = l.ts_rx(buf) {
888 fields.push(("ts_rx", ts_rx.to_string()));
889 }
890 if let Ok(Some(ts_tx)) = l.ts_tx(buf) {
891 fields.push(("ts_tx", ts_tx.to_string()));
892 }
893
894 if let Ok(Some(addr_mask)) = l.addr_mask(buf) {
896 fields.push(("addr_mask", addr_mask.to_string()));
897 }
898
899 fields
900}
901
902fn icmpv6_show_fields(l: &Icmpv6Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
903 let mut fields = Vec::new();
904 let icmpv6_type = l.icmpv6_type(buf).unwrap_or(0);
905 let type_name = icmpv6::types::name(icmpv6_type);
906 fields.push(("type", format!("{icmpv6_type} ({type_name})")));
907 fields.push((
908 "code",
909 l.code(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
910 ));
911 fields.push((
912 "chksum",
913 l.checksum(buf)
914 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
915 ));
916 if let Ok(Some(id)) = l.id(buf) {
917 fields.push(("id", format!("{id:#06x}")));
918 }
919 if let Ok(Some(seq)) = l.seq(buf) {
920 fields.push(("seq", seq.to_string()));
921 }
922 if let Ok(Some(target)) = l.target_addr(buf) {
923 fields.push(("tgt", target.to_string()));
924 }
925 if let Ok(Some(mtu)) = l.mtu(buf) {
926 fields.push(("mtu", mtu.to_string()));
927 }
928 fields
929}
930
931fn tcp_show_fields(l: &TcpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
932 let mut fields = Vec::new();
933 fields.push((
934 "sport",
935 l.src_port(buf)
936 .map_or_else(|_| "?".into(), |v| v.to_string()),
937 ));
938 fields.push((
939 "dport",
940 l.dst_port(buf)
941 .map_or_else(|_| "?".into(), |v| v.to_string()),
942 ));
943 fields.push((
944 "seq",
945 l.seq(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
946 ));
947 fields.push((
948 "ack",
949 l.ack(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
950 ));
951 fields.push((
952 "dataofs",
953 l.data_offset(buf)
954 .map_or_else(|_| "?".into(), |v| v.to_string()),
955 ));
956 fields.push((
957 "reserved",
958 l.reserved(buf)
959 .map_or_else(|_| "?".into(), |v| v.to_string()),
960 ));
961 fields.push((
962 "flags",
963 l.flags(buf).map_or_else(|_| "?".into(), |f| f.to_string()),
964 ));
965 fields.push((
966 "window",
967 l.window(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
968 ));
969 fields.push((
970 "chksum",
971 l.checksum(buf)
972 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
973 ));
974 fields.push((
975 "urgptr",
976 l.urgent_ptr(buf)
977 .map_or_else(|_| "?".into(), |v| v.to_string()),
978 ));
979 let opts_len = l.options_len(buf);
981 if opts_len > 0 {
982 fields.push(("options", format!("[{opts_len} bytes]")));
983 }
984 fields
985}
986
987fn udp_show_fields(l: &UdpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
988 let mut fields = Vec::new();
989 fields.push((
990 "sport",
991 l.src_port(buf)
992 .map_or_else(|_| "?".into(), |v: u16| v.to_string()),
993 ));
994 fields.push((
995 "dport",
996 l.dst_port(buf)
997 .map_or_else(|_| "?".into(), |v: u16| v.to_string()),
998 ));
999 fields.push((
1000 "len",
1001 l.length(buf)
1002 .map_or_else(|_| "?".into(), |v: u16| v.to_string()),
1003 ));
1004 fields.push((
1005 "chksum",
1006 l.checksum(buf)
1007 .map_or_else(|_| "?".into(), |v: u16| format!("{v:#06x}")),
1008 ));
1009 fields
1010}
1011
1012fn dns_show_fields(l: &DnsLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1013 let mut fields = Vec::new();
1014 fields.push((
1015 "id",
1016 l.id(buf)
1017 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
1018 ));
1019 let qr = l.qr(buf).unwrap_or(false);
1020 fields.push(("qr", if qr { "response" } else { "query" }.to_string()));
1021 fields.push((
1022 "opcode",
1023 l.opcode(buf).map_or_else(
1024 |_| "?".into(),
1025 |v| format!("{} ({})", v, dns::types::opcode_name(v)),
1026 ),
1027 ));
1028 fields.push((
1029 "aa",
1030 l.aa(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1031 ));
1032 fields.push((
1033 "tc",
1034 l.tc(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1035 ));
1036 fields.push((
1037 "rd",
1038 l.rd(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1039 ));
1040 fields.push((
1041 "ra",
1042 l.ra(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1043 ));
1044 fields.push(("z", l.z(buf).map_or_else(|_| "?".into(), |v| v.to_string())));
1045 fields.push((
1046 "ad",
1047 l.ad(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1048 ));
1049 fields.push((
1050 "cd",
1051 l.cd(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1052 ));
1053 fields.push((
1054 "rcode",
1055 l.rcode(buf).map_or_else(
1056 |_| "?".into(),
1057 |v| format!("{} ({})", v, dns::types::rcode_name(v)),
1058 ),
1059 ));
1060 fields.push((
1061 "qdcount",
1062 l.qdcount(buf)
1063 .map_or_else(|_| "?".into(), |v| v.to_string()),
1064 ));
1065 fields.push((
1066 "ancount",
1067 l.ancount(buf)
1068 .map_or_else(|_| "?".into(), |v| v.to_string()),
1069 ));
1070 fields.push((
1071 "nscount",
1072 l.nscount(buf)
1073 .map_or_else(|_| "?".into(), |v| v.to_string()),
1074 ));
1075 fields.push((
1076 "arcount",
1077 l.arcount(buf)
1078 .map_or_else(|_| "?".into(), |v| v.to_string()),
1079 ));
1080 if let Ok(questions) = l.questions(buf) {
1082 for (i, q) in questions.iter().enumerate() {
1083 fields.push(("qd", format!("[{}] {}", i, q.summary())));
1084 }
1085 }
1086 fields
1087}
1088
1089fn ssh_show_fields(l: &SshLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1090 let mut fields = Vec::new();
1091 if l.is_version_exchange(buf) {
1092 if let Some(vs) = l.version_string(buf) {
1093 fields.push(("version_string", vs.to_string()));
1094 }
1095 } else {
1096 fields.push((
1097 "packet_length",
1098 l.packet_length(buf)
1099 .map_or_else(|_| "?".into(), |v| v.to_string()),
1100 ));
1101 fields.push((
1102 "padding_length",
1103 l.padding_length(buf)
1104 .map_or_else(|_| "?".into(), |v| v.to_string()),
1105 ));
1106 match l.message_type(buf) {
1107 Ok(Some(t)) => {
1108 fields.push((
1109 "message_type",
1110 format!("{} ({})", t, ssh::msg_types::name(t)),
1111 ));
1112 },
1113 Ok(None) => {},
1114 Err(_) => {
1115 fields.push(("message_type", "?".into()));
1116 },
1117 }
1118 }
1119 fields
1120}
1121
1122fn tls_show_fields(l: &TlsLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1123 let mut fields = Vec::new();
1124 fields.push((
1125 "type",
1126 l.content_type(buf).map_or_else(
1127 |_| "?".into(),
1128 |ct| format!("{} ({})", ct.as_u8(), ct.name()),
1129 ),
1130 ));
1131 fields.push((
1132 "version",
1133 l.version(buf)
1134 .map(|v| {
1135 let ver = TlsVersion(v);
1136 format!("{:#06x} ({})", v, ver.name())
1137 })
1138 .unwrap_or_else(|_| "?".into()),
1139 ));
1140 fields.push((
1141 "len",
1142 l.length(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1143 ));
1144 let frag = l.fragment(buf);
1145 if !frag.is_empty() {
1146 if frag.len() <= 16 {
1147 fields.push(("fragment", format!("[{} bytes] {:02x?}", frag.len(), frag)));
1148 } else {
1149 fields.push(("fragment", format!("[{} bytes]", frag.len())));
1150 }
1151 }
1152 fields
1153}
1154
1155fn dot11_show_fields(l: &dot11::Dot11Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
1156 let mut fields = Vec::new();
1157 fields.push((
1158 "type",
1159 l.frame_type(buf).map_or_else(
1160 |_| "?".into(),
1161 |v| format!("{} ({})", v, dot11::types::frame_type::name(v)),
1162 ),
1163 ));
1164 fields.push((
1165 "subtype",
1166 l.subtype(buf)
1167 .map(|v| {
1168 let ft = l.frame_type(buf).unwrap_or(0);
1169 format!("{} ({})", v, dot11::types::subtype_name(ft, v))
1170 })
1171 .unwrap_or_else(|_| "?".into()),
1172 ));
1173 fields.push((
1174 "proto",
1175 l.protocol_version(buf)
1176 .map_or_else(|_| "?".into(), |v| v.to_string()),
1177 ));
1178 fields.push((
1179 "FCfield",
1180 l.flags(buf)
1181 .map_or_else(|_| "?".into(), |v| format!("{v:#04x}")),
1182 ));
1183 fields.push((
1184 "ID",
1185 l.duration(buf)
1186 .map_or_else(|_| "?".into(), |v| v.to_string()),
1187 ));
1188 fields.push((
1189 "addr1",
1190 l.addr1(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1191 ));
1192 fields.push((
1193 "addr2",
1194 l.addr2(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1195 ));
1196 fields.push((
1197 "addr3",
1198 l.addr3(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1199 ));
1200 fields.push((
1201 "SC",
1202 l.seq_ctrl_raw(buf)
1203 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
1204 ));
1205 if l.has_addr4(buf) {
1206 fields.push((
1207 "addr4",
1208 l.addr4(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1209 ));
1210 }
1211 fields
1212}
1213
1214fn dot15d4_show_fields(l: &dot15d4::Dot15d4Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
1215 let mut fields = Vec::new();
1216 let ft = l.fcf_frametype(buf).unwrap_or(0);
1218 fields.push((
1219 "fcf_frametype",
1220 format!("{} ({})", ft, dot15d4::types::frame_type_name(ft)),
1221 ));
1222 fields.push((
1224 "fcf_security",
1225 l.fcf_security(buf)
1226 .map_or_else(|_| "?".into(), |v| v.to_string()),
1227 ));
1228 fields.push((
1229 "fcf_pending",
1230 l.fcf_pending(buf)
1231 .map_or_else(|_| "?".into(), |v| v.to_string()),
1232 ));
1233 fields.push((
1234 "fcf_ackreq",
1235 l.fcf_ackreq(buf)
1236 .map_or_else(|_| "?".into(), |v| v.to_string()),
1237 ));
1238 fields.push((
1239 "fcf_panidcompress",
1240 l.fcf_panidcompress(buf)
1241 .map_or_else(|_| "?".into(), |v| v.to_string()),
1242 ));
1243 let dam = l.fcf_destaddrmode(buf).unwrap_or(0);
1245 fields.push((
1246 "fcf_destaddrmode",
1247 format!("{} ({})", dam, dot15d4::types::addr_mode_name(dam)),
1248 ));
1249 fields.push((
1250 "fcf_framever",
1251 l.fcf_framever(buf)
1252 .map_or_else(|_| "?".into(), |v| v.to_string()),
1253 ));
1254 let sam = l.fcf_srcaddrmode(buf).unwrap_or(0);
1255 fields.push((
1256 "fcf_srcaddrmode",
1257 format!("{} ({})", sam, dot15d4::types::addr_mode_name(sam)),
1258 ));
1259 fields.push((
1261 "seqnum",
1262 l.seqnum(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1263 ));
1264 if let Ok(Some(panid)) = l.dest_panid(buf) {
1266 fields.push(("dest_panid", format!("{panid:#06x}")));
1267 }
1268 if let Ok(Some(addr)) = l.dest_addr_short(buf) {
1269 fields.push(("dest_addr", format!("{addr:#06x}")));
1270 }
1271 if let Ok(Some(addr)) = l.dest_addr_long(buf) {
1272 fields.push(("dest_addr", format!("{addr:#018x}")));
1273 }
1274 if let Ok(Some(panid)) = l.src_panid(buf) {
1275 fields.push(("src_panid", format!("{panid:#06x}")));
1276 }
1277 if let Ok(Some(addr)) = l.src_addr_short(buf) {
1278 fields.push(("src_addr", format!("{addr:#06x}")));
1279 }
1280 if let Ok(Some(addr)) = l.src_addr_long(buf) {
1281 fields.push(("src_addr", format!("{addr:#018x}")));
1282 }
1283 fields
1284}
1285
1286fn dot15d4_fcs_show_fields(
1287 l: &dot15d4::Dot15d4FcsLayer,
1288 buf: &[u8],
1289) -> Vec<(&'static str, String)> {
1290 let inner = dot15d4::Dot15d4Layer::new(l.index.start, l.index.end.saturating_sub(2));
1291 let mut fields = dot15d4_show_fields(&inner, buf);
1292 let slice = l.index.slice(buf);
1294 if slice.len() >= 2 {
1295 let fcs_bytes = &slice[slice.len() - 2..];
1296 let fcs = u16::from_le_bytes([fcs_bytes[0], fcs_bytes[1]]);
1297 let verified = l.verify_fcs(buf).unwrap_or(false);
1298 let status = if verified { "ok" } else { "INVALID" };
1299 fields.push(("fcs", format!("{fcs:#06x} ({status})")));
1300 }
1301 fields
1302}
1303
1304fn http_show_fields(l: &http::HttpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1305 let mut fields = Vec::new();
1306 if l.is_request(buf) {
1307 fields.push(("method", l.method(buf).unwrap_or("?").to_string()));
1308 fields.push(("uri", l.uri(buf).unwrap_or("?").to_string()));
1309 fields.push(("version", l.http_version(buf).unwrap_or("?").to_string()));
1310 } else if l.is_response(buf) {
1311 fields.push(("version", l.http_version(buf).unwrap_or("?").to_string()));
1312 fields.push((
1313 "status_code",
1314 l.status_code(buf)
1315 .map_or_else(|| "?".into(), |c| c.to_string()),
1316 ));
1317 fields.push(("reason", l.reason(buf).unwrap_or("?").to_string()));
1318 }
1319 fields
1320}
1321
1322fn http2_show_fields(l: &http2::Http2Layer, buf: &[u8]) -> Vec<(&'static str, String)> {
1323 let mut fields = Vec::new();
1324 if l.has_preface {
1325 fields.push(("preface", "true".to_string()));
1326 }
1327 if let Some(frame) = l.first_frame(buf) {
1328 fields.push((
1329 "frame_type",
1330 format!("{} ({})", frame.frame_type.as_u8(), frame.frame_type.name()),
1331 ));
1332 fields.push(("flags", format!("{:#04x}", frame.flags)));
1333 fields.push(("stream_id", frame.stream_id.to_string()));
1334 fields.push(("length", frame.length.to_string()));
1335 }
1336 fields
1337}
1338
1339fn quic_show_fields(l: &quic::QuicLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1340 let mut fields = Vec::new();
1341 fields.push((
1342 "header_form",
1343 if l.is_long_header(buf) {
1344 "long".to_string()
1345 } else {
1346 "short".to_string()
1347 },
1348 ));
1349 if let Some(pt) = l.packet_type(buf) {
1350 fields.push(("packet_type", pt.name().to_string()));
1351 }
1352 if let Some(ver) = l.version(buf) {
1353 fields.push(("version", format!("{ver:#010x}")));
1354 }
1355 fields
1356}
1357
1358fn l2tp_show_fields(l: &l2tp::L2tpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1359 let mut fields = Vec::new();
1360 fields.push((
1361 "flags",
1362 l.flags_word(buf)
1363 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
1364 ));
1365 fields.push((
1366 "version",
1367 l.version(buf)
1368 .map_or_else(|_| "?".into(), |v| v.to_string()),
1369 ));
1370 fields.push((
1371 "msg_type",
1372 l.msg_type(buf)
1373 .map(|v| {
1374 if v == 0 {
1375 "data".to_string()
1376 } else {
1377 "control".to_string()
1378 }
1379 })
1380 .unwrap_or_else(|_| "?".into()),
1381 ));
1382 if let Ok(Some(length)) = l.length(buf) {
1383 fields.push(("length", length.to_string()));
1384 }
1385 fields.push((
1386 "tunnel_id",
1387 l.tunnel_id(buf)
1388 .map_or_else(|_| "?".into(), |v| v.to_string()),
1389 ));
1390 fields.push((
1391 "session_id",
1392 l.session_id(buf)
1393 .map_or_else(|_| "?".into(), |v| v.to_string()),
1394 ));
1395 if let Ok(Some(ns)) = l.ns(buf) {
1396 fields.push(("ns", ns.to_string()));
1397 }
1398 if let Ok(Some(nr)) = l.nr(buf) {
1399 fields.push(("nr", nr.to_string()));
1400 }
1401 fields
1402}
1403
1404fn mqtt_show_fields(l: &mqtt::MqttLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1405 let mut fields = Vec::new();
1406 fields.push((
1407 "msg_type",
1408 l.msg_type(buf).map_or_else(
1409 |_| "?".into(),
1410 |v| format!("{} ({})", v, mqtt::message_type_name(v)),
1411 ),
1412 ));
1413 fields.push((
1414 "dup",
1415 l.dup(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1416 ));
1417 fields.push((
1418 "qos",
1419 l.qos(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1420 ));
1421 fields.push((
1422 "retain",
1423 l.retain(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1424 ));
1425 fields.push((
1426 "remaining_length",
1427 l.remaining_length(buf)
1428 .map_or_else(|_| "?".into(), |v| v.to_string()),
1429 ));
1430 if let Ok(mt) = l.msg_type(buf) {
1431 if mt == mqtt::PUBLISH {
1432 if let Ok(topic) = l.topic(buf) {
1433 fields.push(("topic", topic));
1434 }
1435 } else if mt == mqtt::CONNECT {
1436 if let Ok(name) = l.proto_name(buf) {
1437 fields.push(("proto_name", name));
1438 }
1439 if let Ok(level) = l.proto_level(buf) {
1440 fields.push(("proto_level", level.to_string()));
1441 }
1442 if let Ok(klive) = l.klive(buf) {
1443 fields.push(("klive", klive.to_string()));
1444 }
1445 if let Ok(cid) = l.client_id(buf) {
1446 fields.push(("client_id", cid));
1447 }
1448 } else if mt == mqtt::CONNACK
1449 && let Ok(rc) = l.retcode(buf)
1450 {
1451 fields.push(("retcode", rc.to_string()));
1452 }
1453 }
1454 fields
1455}
1456
1457fn mqttsn_show_fields(l: &mqttsn::MqttSnLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1458 let mut fields = Vec::new();
1459 fields.push((
1460 "length",
1461 l.packet_length(buf)
1462 .map_or_else(|_| "?".into(), |v| v.to_string()),
1463 ));
1464 let mt = l.msg_type(buf).unwrap_or(0xFF);
1465 fields.push((
1466 "type",
1467 format!("{} ({})", mt, mqttsn::message_type_name(mt)),
1468 ));
1469 if let Ok(v) = l.gw_id(buf) {
1470 fields.push(("gw_id", format!("{v:#04x}")));
1471 }
1472 if let Ok(v) = l.duration(buf) {
1473 fields.push(("duration", v.to_string()));
1474 }
1475 if let Ok(v) = l.return_code(buf) {
1476 fields.push(("return_code", v.to_string()));
1477 }
1478 if let Ok(v) = l.tid(buf) {
1479 fields.push(("tid", format!("{v:#06x}")));
1480 }
1481 if let Ok(v) = l.mid(buf) {
1482 fields.push(("mid", format!("{v:#06x}")));
1483 }
1484 fields
1485}
1486
1487fn modbus_show_fields(l: &modbus::ModbusLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1488 let mut fields = Vec::new();
1489 fields.push((
1490 "trans_id",
1491 l.trans_id(buf)
1492 .map_or_else(|_| "?".into(), |v| v.to_string()),
1493 ));
1494 fields.push((
1495 "proto_id",
1496 l.proto_id(buf)
1497 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
1498 ));
1499 fields.push((
1500 "length",
1501 l.length(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1502 ));
1503 fields.push((
1504 "unit_id",
1505 l.unit_id(buf)
1506 .map_or_else(|_| "?".into(), |v| format!("{v:#04x}")),
1507 ));
1508 let fc = l.func_code(buf).unwrap_or(0);
1509 fields.push((
1510 "func_code",
1511 format!("{:#04x} ({})", fc, modbus::func_code_name(fc)),
1512 ));
1513 if l.is_error(buf) {
1514 fields.push((
1515 "except_code",
1516 l.except_code(buf).map_or_else(
1517 |_| "?".into(),
1518 |v| format!("{} ({})", v, modbus::except_code_name(v)),
1519 ),
1520 ));
1521 }
1522 fields
1523}
1524
1525fn zwave_show_fields(l: &zwave::ZWaveLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1526 let mut fields = Vec::new();
1527 fields.push((
1528 "home_id",
1529 l.home_id(buf)
1530 .map_or_else(|_| "?".into(), |v| format!("{v:#010x}")),
1531 ));
1532 fields.push((
1533 "src",
1534 l.src(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1535 ));
1536 fields.push((
1537 "dst",
1538 l.dst(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1539 ));
1540 fields.push((
1541 "routed",
1542 l.routed(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1543 ));
1544 fields.push((
1545 "ackreq",
1546 l.ackreq(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1547 ));
1548 fields.push((
1549 "lowpower",
1550 l.lowpower(buf)
1551 .map_or_else(|_| "?".into(), |v| v.to_string()),
1552 ));
1553 fields.push((
1554 "speedmodified",
1555 l.speedmodified(buf)
1556 .map_or_else(|_| "?".into(), |v| v.to_string()),
1557 ));
1558 fields.push((
1559 "headertype",
1560 l.headertype(buf)
1561 .map_or_else(|_| "?".into(), |v| format!("{v:#04x}")),
1562 ));
1563 fields.push((
1564 "beam_control",
1565 l.beam_control(buf)
1566 .map_or_else(|_| "?".into(), |v| v.to_string()),
1567 ));
1568 fields.push((
1569 "seqn",
1570 l.seqn(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1571 ));
1572 fields.push((
1573 "length",
1574 l.length(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1575 ));
1576 if !l.is_ack(buf) {
1577 fields.push((
1578 "cmd_class",
1579 l.cmd_class(buf).map_or_else(
1580 |_| "?".into(),
1581 |v| format!("{:#04x} ({})", v, zwave::cmd_class_name(v)),
1582 ),
1583 ));
1584 if let Ok(cmd) = l.cmd(buf) {
1585 fields.push(("cmd", format!("{cmd:#04x}")));
1586 }
1587 }
1588 fields.push((
1589 "crc",
1590 l.crc(buf)
1591 .map_or_else(|_| "?".into(), |v| format!("{v:#04x}")),
1592 ));
1593 fields
1594}
1595
1596fn dhcp_show_fields(l: &dhcp::DhcpLayer, buf: &[u8]) -> Vec<(&'static str, String)> {
1597 let mut fields = Vec::new();
1598 fields.push((
1599 "op",
1600 l.op(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1601 ));
1602 fields.push((
1603 "htype",
1604 l.htype(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1605 ));
1606 fields.push((
1607 "hlen",
1608 l.hlen(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1609 ));
1610 fields.push((
1611 "hops",
1612 l.hops(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1613 ));
1614 fields.push((
1615 "xid",
1616 l.xid(buf)
1617 .map_or_else(|_| "?".into(), |v| format!("{v:#010x}")),
1618 ));
1619 fields.push((
1620 "secs",
1621 l.secs(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1622 ));
1623 fields.push((
1624 "flags",
1625 l.flags(buf)
1626 .map_or_else(|_| "?".into(), |v| format!("{v:#06x}")),
1627 ));
1628 fields.push((
1629 "ciaddr",
1630 l.ciaddr(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1631 ));
1632 fields.push((
1633 "yiaddr",
1634 l.yiaddr(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1635 ));
1636 fields.push((
1637 "siaddr",
1638 l.siaddr(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1639 ));
1640 fields.push((
1641 "giaddr",
1642 l.giaddr(buf).map_or_else(|_| "?".into(), |v| v.to_string()),
1643 ));
1644 fields.push((
1645 "chaddr",
1646 l.chaddr(buf).map_or_else(
1647 |_| "?".into(),
1648 |mac| {
1649 format!(
1650 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
1651 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
1652 )
1653 },
1654 ),
1655 ));
1656 if let Some(mt) = l.msg_type(buf) {
1657 let name = match mt {
1658 1 => "Discover",
1659 2 => "Offer",
1660 3 => "Request",
1661 4 => "Decline",
1662 5 => "ACK",
1663 6 => "NAK",
1664 7 => "Release",
1665 8 => "Inform",
1666 _ => "Unknown",
1667 };
1668 fields.push(("msg_type", format!("{mt} ({name})")));
1669 }
1670 if let Some(sid) = l.server_id(buf) {
1671 fields.push(("server_id", sid.to_string()));
1672 }
1673 if let Some(rip) = l.requested_ip(buf) {
1674 fields.push(("requested_ip", rip.to_string()));
1675 }
1676 if let Some(lt) = l.lease_time(buf) {
1677 fields.push(("lease_time", lt.to_string()));
1678 }
1679 if let Some(sm) = l.subnet_mask(buf) {
1680 fields.push(("subnet_mask", sm.to_string()));
1681 }
1682 if let Some(r) = l.router(buf) {
1683 fields.push(("router", r.to_string()));
1684 }
1685 let dns_servers = l.dns(buf);
1686 if !dns_servers.is_empty() {
1687 let s = dns_servers
1688 .iter()
1689 .map(|ip| ip.to_string())
1690 .collect::<Vec<_>>()
1691 .join(", ");
1692 fields.push(("dns", s));
1693 }
1694 fields
1695}
1696
1697pub use dns::DnsLayer;
1698
1699impl_layer_dispatch!(EthernetLayer, show = ethernet_show_fields);
1704impl_layer_dispatch!(
1705 Dot3Layer,
1706 show = dot3_show_fields,
1707 inherent,
1708 kind = LayerKind::Dot3,
1709 header_len = ethernet::ETHERNET_HEADER_LEN
1710);
1711impl_layer_dispatch!(ArpLayer, show = arp_show_fields);
1712impl_layer_dispatch!(Ipv4Layer, show = ipv4_show_fields);
1713impl_layer_dispatch!(Ipv6Layer, show = ipv6_show_fields);
1714impl_layer_dispatch!(IcmpLayer, show = icmp_show_fields);
1715impl_layer_dispatch!(Icmpv6Layer, show = icmpv6_show_fields);
1716impl_layer_dispatch!(TcpLayer, show = tcp_show_fields);
1717impl_layer_dispatch!(UdpLayer, show = udp_show_fields);
1718impl_layer_dispatch!(DnsLayer, show = dns_show_fields);
1719impl_layer_dispatch!(SshLayer, show = ssh_show_fields);
1720impl_layer_dispatch!(TlsLayer, show = tls_show_fields);
1721impl_layer_dispatch!(dot15d4::Dot15d4Layer, show = dot15d4_show_fields);
1722impl_layer_dispatch!(dot15d4::Dot15d4FcsLayer, show = dot15d4_fcs_show_fields);
1723impl_layer_dispatch!(dot11::Dot11Layer, show = dot11_show_fields);
1724impl_layer_dispatch!(HttpLayer, show = http_show_fields, readonly);
1725impl_layer_dispatch!(Http2Layer, show = http2_show_fields, readonly);
1726impl_layer_dispatch!(quic::QuicLayer, show = quic_show_fields);
1727impl_layer_dispatch!(l2tp::L2tpLayer, show = l2tp_show_fields);
1728impl_layer_dispatch!(mqtt::MqttLayer, show = mqtt_show_fields);
1729impl_layer_dispatch!(mqttsn::MqttSnLayer, show = mqttsn_show_fields);
1730impl_layer_dispatch!(modbus::ModbusLayer, show = modbus_show_fields);
1731impl_layer_dispatch!(zwave::ZWaveLayer, show = zwave_show_fields);
1732impl_layer_dispatch!(ftp::FtpLayer, show = ftp::ftp_show_fields, readonly);
1733impl_layer_dispatch!(tftp::TftpLayer, show = tftp::tftp_show_fields, readonly);
1734impl_layer_dispatch!(smtp::SmtpLayer, show = smtp::smtp_show_fields, readonly);
1735impl_layer_dispatch!(pop3::Pop3Layer, show = pop3::pop3_show_fields, readonly);
1736impl_layer_dispatch!(imap::ImapLayer, show = imap::imap_show_fields, readonly);
1737impl_layer_dispatch!(dhcp::DhcpLayer, show = dhcp_show_fields);
1738impl LayerDispatch for RawLayer {
1740 #[inline]
1741 fn dispatch_kind(&self) -> LayerKind {
1742 LayerKind::Raw
1743 }
1744 #[inline]
1745 fn dispatch_index(&self) -> &LayerIndex {
1746 &self.index
1747 }
1748 #[inline]
1749 fn dispatch_summary(&self, buf: &[u8]) -> String {
1750 self.summary(buf)
1751 }
1752 #[inline]
1753 fn dispatch_header_len(&self, buf: &[u8]) -> usize {
1754 self.header_len(buf)
1755 }
1756 #[inline]
1757 fn dispatch_hashret(&self, buf: &[u8]) -> Vec<u8> {
1758 self.hashret(buf)
1759 }
1760 #[inline]
1761 fn dispatch_field_names(&self) -> &'static [&'static str] {
1762 RawLayer::field_names()
1763 }
1764 #[inline]
1765 fn dispatch_get_field(&self, buf: &[u8], name: &str) -> Option<Result<FieldValue, FieldError>> {
1766 self.get_field(buf, name)
1767 }
1768 #[inline]
1769 fn dispatch_set_field(
1770 &self,
1771 buf: &mut [u8],
1772 name: &str,
1773 value: FieldValue,
1774 ) -> Option<Result<(), FieldError>> {
1775 self.set_field(buf, name, value)
1776 }
1777 #[inline]
1778 fn dispatch_show_fields(&self, buf: &[u8]) -> Vec<(&'static str, String)> {
1779 raw::raw_show_fields(self, buf)
1780 }
1781}
1782
1783pub mod ethertype {
1785 use crate::LayerKind;
1786
1787 pub const IPV4: u16 = 0x0800;
1788 pub const ARP: u16 = 0x0806;
1789 pub const IPV6: u16 = 0x86DD;
1790 pub const VLAN: u16 = 0x8100;
1791 pub const DOT1AD: u16 = 0x88A8;
1792 pub const DOT1AH: u16 = 0x88E7;
1793 pub const MACSEC: u16 = 0x88E5;
1794 pub const LOOPBACK: u16 = 0x9000;
1795
1796 #[must_use]
1797 pub fn name(t: u16) -> &'static str {
1798 match t {
1799 IPV4 => "IPv4",
1800 ARP => "ARP",
1801 IPV6 => "IPv6",
1802 VLAN => "802.1Q",
1803 DOT1AD => "802.1AD",
1804 DOT1AH => "802.1AH",
1805 MACSEC => "MACsec",
1806 LOOPBACK => "Loopback",
1807 _ => "Unknown",
1808 }
1809 }
1810
1811 #[must_use]
1812 pub fn to_layer_kind(t: u16) -> Option<LayerKind> {
1813 match t {
1814 IPV4 => Some(LayerKind::Ipv4),
1815 ARP => Some(LayerKind::Arp),
1816 IPV6 => Some(LayerKind::Ipv6),
1817 VLAN => Some(LayerKind::Dot1Q),
1818 DOT1AD => Some(LayerKind::Dot1AD),
1819 DOT1AH => Some(LayerKind::Dot1AH),
1820 _ => None,
1821 }
1822 }
1823
1824 #[must_use]
1825 pub fn from_layer_kind(kind: LayerKind) -> Option<u16> {
1826 match kind {
1827 LayerKind::Ipv4 => Some(IPV4),
1828 LayerKind::Arp => Some(ARP),
1829 LayerKind::Ipv6 => Some(IPV6),
1830 LayerKind::Dot1Q => Some(VLAN),
1831 LayerKind::Dot1AD => Some(DOT1AD),
1832 LayerKind::Dot1AH => Some(DOT1AH),
1833 _ => None,
1834 }
1835 }
1836}
1837
1838pub mod ip_protocol {
1840 pub use crate::layer::ipv4::protocol::*;
1841}
1842
1843#[cfg(test)]
1844mod tests {
1845 use super::*;
1846
1847 #[test]
1848 fn test_layer_kind() {
1849 assert_eq!(LayerKind::Ethernet.name(), "Ethernet");
1850 assert_eq!(LayerKind::Arp.min_header_size(), 28);
1851 assert!(LayerKind::Ethernet.is_link_layer());
1852 assert!(LayerKind::Ipv4.is_network_layer());
1853 assert!(LayerKind::Tcp.is_transport_layer());
1854 }
1855
1856 #[test]
1857 fn test_layer_index() {
1858 let idx = LayerIndex::new(LayerKind::Ethernet, 0, 14);
1859 assert_eq!(idx.len(), 14);
1860 assert_eq!(idx.range(), 0..14);
1861
1862 let buf = vec![0u8; 100];
1863 assert_eq!(idx.slice(&buf).len(), 14);
1864 assert_eq!(idx.payload(&buf).len(), 86);
1865 }
1866
1867 #[test]
1868 fn test_ethertype_conversions() {
1869 assert_eq!(ethertype::to_layer_kind(0x0800), Some(LayerKind::Ipv4));
1870 assert_eq!(ethertype::from_layer_kind(LayerKind::Arp), Some(0x0806));
1871 }
1872}