use std::{
marker::PhantomData,
net::{Ipv4Addr, Ipv6Addr},
};
use netlink_packet_route::{
address::{AddressAttribute, AddressMessage},
AddressFamily,
};
#[derive(Debug)]
pub struct AddressMessageBuilder<T> {
message: AddressMessage,
_phantom: PhantomData<T>,
}
impl<T> AddressMessageBuilder<T> {
fn new_no_address_family() -> Self {
AddressMessageBuilder {
message: AddressMessage::default(),
_phantom: PhantomData,
}
}
pub fn index(mut self, index: u32) -> Self {
self.message.header.index = index;
self
}
pub fn build(self) -> AddressMessage {
self.message
}
}
impl Default for AddressMessageBuilder<Ipv4Addr> {
fn default() -> Self {
Self::new()
}
}
impl AddressMessageBuilder<Ipv4Addr> {
pub fn new() -> Self {
let mut builder = Self::new_no_address_family();
builder.message.header.family = AddressFamily::Inet;
builder
}
pub fn address(mut self, address: Ipv4Addr, prefix_len: u8) -> Self {
self.message.header.prefix_len = prefix_len;
if !address.is_multicast() {
self.message
.attributes
.push(AddressAttribute::Address(address.into()));
self.message
.attributes
.push(AddressAttribute::Local(address.into()));
if prefix_len < 31 {
let ip_addr = u32::from(address);
let brd = Ipv4Addr::from(
(0xffff_ffff_u32) >> u32::from(prefix_len) | ip_addr,
);
self.message
.attributes
.push(AddressAttribute::Broadcast(brd));
};
}
self
}
}
impl Default for AddressMessageBuilder<Ipv6Addr> {
fn default() -> Self {
Self::new()
}
}
impl AddressMessageBuilder<Ipv6Addr> {
pub fn new() -> Self {
let mut builder = Self::new_no_address_family();
builder.message.header.family = AddressFamily::Inet6;
builder
}
pub fn address(mut self, address: Ipv6Addr, prefix_len: u8) -> Self {
self.message.header.prefix_len = prefix_len;
if address.is_multicast() {
self.message
.attributes
.push(AddressAttribute::Multicast(address));
} else {
self.message
.attributes
.push(AddressAttribute::Address(address.into()));
self.message
.attributes
.push(AddressAttribute::Local(address.into()));
}
self
}
}