pub fn link_loopback() -> Vec<u8> {
vec![
0x00, 0x00, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, b'l', b'o', 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x0d, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, ]
}
pub fn addr_loopback_v4() -> Vec<u8> {
vec![
0x02, 0x08, 0x80, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x01, 0x08, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x00, 0x01, 0x07, 0x00, 0x03, 0x00, b'l', b'o', 0x00, 0x00, ]
}
pub fn addr_loopback_v6() -> Vec<u8> {
vec![
0x0a, 0x80, 0x80, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, ]
}
pub fn route_default_v4() -> Vec<u8> {
vec![
0x02, 0x00, 0x00, 0x00, 0xfe, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00, 0xc0, 0xa8, 0x01, 0x01, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, ]
}
pub fn tc_qdisc_fq_codel() -> Vec<u8> {
vec![
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x01, 0x00, b'f', b'q', b'_', b'c', b'o', b'd', b'e', b'l', 0x00, 0x00, 0x00, 0x00, ]
}
pub fn neighbor_arp() -> Vec<u8> {
vec![
0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0xc0, 0xa8, 0x01, 0x01, 0x0a, 0x00, 0x02, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x00, ]
}
#[cfg(test)]
mod tests {
use super::*;
use crate::netlink::{
messages::{AddressMessage, LinkMessage, NeighborMessage, RouteMessage, TcMessage},
parse::FromNetlink,
};
#[test]
fn test_parse_link_loopback() {
let data = link_loopback();
let link = LinkMessage::from_bytes(&data).expect("failed to parse link message");
assert_eq!(link.ifindex(), 1);
assert_eq!(link.name.as_deref(), Some("lo"));
assert_eq!(link.mtu, Some(65536));
assert!(link.is_up());
assert!(link.is_loopback());
}
#[test]
fn test_parse_addr_loopback_v4() {
let data = addr_loopback_v4();
let addr = AddressMessage::from_bytes(&data).expect("failed to parse address message");
assert_eq!(addr.ifindex(), 1);
assert_eq!(addr.prefix_len(), 8);
assert_eq!(addr.family(), 2); assert!(addr.is_ipv4());
assert!(addr.is_permanent());
if let Some(local) = &addr.local {
assert_eq!(local.to_string(), "127.0.0.1");
} else {
panic!("expected local address");
}
}
#[test]
fn test_parse_addr_loopback_v6() {
let data = addr_loopback_v6();
let addr = AddressMessage::from_bytes(&data).expect("failed to parse address message");
assert_eq!(addr.ifindex(), 1);
assert_eq!(addr.prefix_len(), 128);
assert_eq!(addr.family(), 10); assert!(addr.is_ipv6());
assert!(addr.is_permanent());
if let Some(address) = &addr.address {
assert_eq!(address.to_string(), "::1");
} else {
panic!("expected address");
}
}
#[test]
fn test_parse_route_default_v4() {
let data = route_default_v4();
let route = RouteMessage::from_bytes(&data).expect("failed to parse route message");
assert_eq!(route.dst_len(), 0); assert_eq!(route.family(), 2); assert_eq!(route.table_id(), 254);
if let Some(ref gw) = route.gateway {
assert_eq!(gw.to_string(), "192.168.1.1");
} else {
panic!("expected gateway");
}
assert_eq!(route.oif, Some(2));
}
#[test]
fn test_parse_tc_qdisc_fq_codel() {
let data = tc_qdisc_fq_codel();
let tc = TcMessage::from_bytes(&data).expect("failed to parse tc message");
assert_eq!(tc.ifindex(), 2);
assert_eq!(tc.kind(), Some("fq_codel"));
assert_eq!(tc.parent(), crate::TcHandle::ROOT);
}
#[test]
fn test_parse_neighbor_arp() {
let data = neighbor_arp();
let neigh = NeighborMessage::from_bytes(&data).expect("failed to parse neighbor message");
assert_eq!(neigh.ifindex(), 2);
assert_eq!(neigh.family(), 2);
if let Some(dst) = &neigh.destination {
assert_eq!(dst.to_string(), "192.168.1.1");
} else {
panic!("expected destination");
}
assert!(neigh.lladdr.is_some());
}
}