use crate::ast::*;
use alloc::vec::Vec;
pub fn build_geneve_payload(spec: &GeneveSpec, payload: &[u8]) -> (Vec<u8>, u16) {
let vni = spec.vni.unwrap_or(4096) & 0x00FF_FFFF;
let proto = spec.protocol_type.unwrap_or(0x6558);
let opt_len = if spec.opt_class.is_some() { 1_u8 } else { 0_u8 };
let mut geneve = Vec::with_capacity(12 + payload.len());
geneve.push(opt_len & 0x3F);
geneve.push(0); geneve.extend_from_slice(&proto.to_be_bytes());
geneve.push((vni >> 16) as u8);
geneve.push((vni >> 8) as u8);
geneve.push(vni as u8);
geneve.push(0);
if let Some(opt_class) = spec.opt_class {
geneve.extend_from_slice(&opt_class.to_be_bytes());
geneve.push(spec.opt_type.unwrap_or(0));
geneve.push(0); }
if payload.is_empty() {
if proto == 0x6558 {
let mut inner_ip = [
0x45, 0x00, 0x00, 28, 0x00, 0x01, 0x00, 0x00, 64, 17, 0x00, 0x00, 10, 0, 0, 1,
10, 0, 0, 2,
];
let ip_cksum = crate::packet::internet_checksum(&[&inner_ip]);
inner_ip[10..12].copy_from_slice(&ip_cksum.to_be_bytes());
geneve.extend_from_slice(&[0x00, 0x00, 0x5e, 0x00, 0x53, 0x02]); geneve.extend_from_slice(&[0x00, 0x00, 0x5e, 0x00, 0x53, 0x01]); geneve.extend_from_slice(&0x0800_u16.to_be_bytes()); geneve.extend_from_slice(&inner_ip);
geneve.extend_from_slice(&[0x30, 0x39, 0x00, 0x50, 0x00, 0x08, 0x00, 0x00]); } else {
geneve.extend_from_slice(b"FrameAssembly GENEVE Inner Data");
}
} else {
geneve.extend_from_slice(payload);
}
(geneve, 6081)
}