use crate::ast::*;
use crate::builders::WireContext;
use alloc::vec::Vec;
use core::net::IpAddr;
pub fn build_bgp_payload(ctx: &WireContext, spec: &BgpSpec, payload: &[u8]) -> (Vec<u8>, u16) {
let bgp_type = spec.bgp_type.unwrap_or(BgpType::Keepalive);
let mut bgp = Vec::new();
match bgp_type {
BgpType::Keepalive => {
bgp.reserve(19);
bgp.extend_from_slice(&[0xFF; 16]); bgp.extend_from_slice(&19_u16.to_be_bytes()); bgp.push(4); }
BgpType::Open => {
bgp.reserve(29);
bgp.extend_from_slice(&[0xFF; 16]);
bgp.extend_from_slice(&29_u16.to_be_bytes()); bgp.push(1); bgp.push(4); let asn = (spec.asn.unwrap_or(65001) & 0xFFFF) as u16;
bgp.extend_from_slice(&asn.to_be_bytes());
bgp.extend_from_slice(&spec.holdtime.unwrap_or(180).to_be_bytes());
let bgpid = match spec.bgpid {
Some(IpAddr::V4(b)) => b.octets(),
_ => match ctx.src_ip {
IpAddr::V4(s) => s.octets(),
_ => [192, 0, 2, 1],
},
};
bgp.extend_from_slice(&bgpid);
bgp.push(0); }
BgpType::Update => {
let total_len = (23 + payload.len()) as u16;
bgp.reserve(total_len as usize);
bgp.extend_from_slice(&[0xFF; 16]);
bgp.extend_from_slice(&total_len.to_be_bytes());
bgp.push(2); bgp.extend_from_slice(&0_u16.to_be_bytes()); bgp.extend_from_slice(&0_u16.to_be_bytes()); bgp.extend_from_slice(payload);
}
BgpType::Notification => {
let total_len = (21 + payload.len()) as u16;
bgp.reserve(total_len as usize);
bgp.extend_from_slice(&[0xFF; 16]);
bgp.extend_from_slice(&total_len.to_be_bytes());
bgp.push(3); bgp.push(6); bgp.push(0);
bgp.extend_from_slice(payload);
}
}
(bgp, 179)
}