use alloc::string::String;
use core::fmt::Write as _;
use crate::ast::Protocol;
use crate::reverse::{ProtocolDissection, be_u16, be_u32, push_hex, sd};
pub(crate) fn dissect_gre(b: &[u8]) -> ProtocolDissection {
if b.len() < 4 {
return sd(Protocol::Gre, String::from("gre"), b.to_vec());
}
let (flags, proto, mut pos, mut t) = (be_u16(b, 0), be_u16(b, 2), 4usize, String::from("gre"));
push_hex(&mut t, "gre_proto", u64::from(proto), 0x0800, 4);
if (flags & 0x8000) != 0 && pos + 4 <= b.len() {
t.push_str(" checksum");
pos += 4;
}
if (flags & 0x2000) != 0 && pos + 4 <= b.len() {
let _ = write!(t, " gre_key {}", be_u32(b, pos));
pos += 4;
}
if (flags & 0x1000) != 0 && pos + 4 <= b.len() {
let _ = write!(t, " gre_seq {}", be_u32(b, pos));
pos += 4;
}
let rem = if &b[pos..] == b"FrameAssembly GRE Inner Packet" {
&[][..]
} else {
&b[pos..]
};
sd(Protocol::Gre, t, rem.to_vec())
}