use bytemuck::{Pod, Zeroable};
pub mod version {
pub const GRE: u8 = 0;
pub const ENHANCED: u8 = 1;
}
pub mod flags {
pub const C: u16 = 0x8000;
pub const R: u16 = 0x4000;
pub const K: u16 = 0x2000;
pub const S: u16 = 0x1000;
pub const SR: u16 = 0x0800;
pub const RECUR: u16 = 0x0700;
pub const A: u16 = 0x0080;
pub const FLAGS: u16 = 0x0078;
pub const V: u16 = 0x0007;
}
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
pub struct GreFlags {
c: bool,
r: bool,
k: bool,
s: bool,
sr: bool,
a: bool,
recur: u8,
flags: u8,
v: u8,
}
impl GreFlags {
pub fn csum(mut self, c: bool) -> Self {
self.c = c;
self
}
pub fn routing(mut self, r: bool) -> Self {
self.r = r;
self
}
pub fn key(mut self, k: bool) -> Self {
self.k = k;
self
}
pub fn seq(mut self, s: bool) -> Self {
self.s = s;
self
}
pub fn source_routing(mut self, sr: bool) -> Self {
self.sr = sr;
self
}
pub fn recursion(mut self, recur: u8) -> Self {
self.recur = recur;
self
}
pub fn ack(mut self, a: bool) -> Self {
self.a = a;
self
}
pub fn flags(mut self, flags: u8) -> Self {
self.flags = flags;
self
}
pub fn ver(mut self, v: u8) -> Self {
self.v = v;
self
}
}
impl From<GreFlags> for u16 {
fn from(s: GreFlags) -> Self {
((s.v as u16) & flags::V)
| (((s.recur as u16) & 0x7) << 8)
| (((s.recur as u16) & 0xf) << 3)
| (if s.c { flags::C } else { 0 })
| (if s.r { flags::R } else { 0 })
| (if s.k { flags::K } else { 0 })
| (if s.s { flags::S } else { 0 })
| (if s.sr { flags::SR } else { 0 })
| (if s.a { flags::A } else { 0 })
}
}
#[repr(C, packed(1))]
#[derive(Pod, Zeroable, Default, Debug, Copy, Clone)]
pub struct gre_hdr {
pub flags: u16,
pub proto: u16,
}
impl gre_hdr {
pub fn new(flags: GreFlags, proto: u16) -> Self {
let f: u16 = flags.into();
Self {
flags: f.to_be(),
proto: proto.to_be(),
}
}
pub fn init(&mut self) -> &mut Self {
*self = Self::default();
self
}
pub fn flags<T>(&mut self, flags: T) -> &mut Self
where
u16: From<T>,
{
let f: u16 = flags.into();
self.flags = f.to_be();
self
}
pub fn proto(&mut self, proto: u16) -> &mut Self {
self.proto = proto.to_be();
self
}
pub fn get_flags(&self) -> u16 {
u16::from_be(self.flags)
}
pub fn get_csum(&self) -> bool {
(self.get_flags() & flags::C) != 0
}
pub fn get_key(&self) -> bool {
(self.get_flags() & flags::K) != 0
}
pub fn get_seq(&self) -> bool {
(self.get_flags() & flags::S) != 0
}
pub fn get_ver(&self) -> u8 {
(self.get_flags() & flags::V) as u8
}
}
#[repr(C, packed(1))]
#[derive(Pod, Zeroable, Debug, Copy, Clone)]
pub struct gre_hdr_sum {
pub csum: u16,
pub rsvd: u16,
}
impl gre_hdr_sum {
pub fn csum(mut self, csum: u16) -> Self {
self.csum = csum.to_be();
self
}
pub fn rsvd(mut self, rsvd: u16) -> Self {
self.rsvd = rsvd.to_be();
self
}
}
#[repr(C, packed(1))]
#[derive(Pod, Zeroable, Debug, Copy, Clone)]
pub struct gre_hdr_key {
pub key: u32,
}
impl gre_hdr_key {
pub fn key(mut self, key: u32) -> Self {
self.key = key.to_be();
self
}
}
#[repr(C, packed(1))]
#[derive(Pod, Zeroable, Debug, Copy, Clone)]
pub struct gre_hdr_seq {
pub seq: u32,
}
impl gre_hdr_seq {
pub fn seq(mut self, seq: u32) -> Self {
self.seq = seq.to_be();
self
}
}