2023-05-06 22:50:34 -04:00

96 lines
3.0 KiB
Rust

// Copyright (C) 2023 Andrew Rioux
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pub mod error;
pub mod netlink;
pub mod nl_ffi;
pub mod route;
// from bridge.c
extern "C" {
pub(crate) fn netlink_route() -> libc::c_int;
}
/* fn main() -> error::Result<()> {
let sock = netlink::Socket::new(netlink::SocketType::Routing)?;
let lookup_sock = netlink::Socket::new(netlink::SocketType::Lookup)?;
let links = sock.get_links()?;
let routes = sock.get_routes()?;
let target_ip = "1.1.1.1".parse::<Ipv4Addr>().unwrap();
let target_ip_num = u32::from(target_ip);
let mut routes2 = routes.iter().collect::<Vec<_>>();
println!("Routes: {}", routes2.len());
routes2.sort_by(|r1, r2| {
r2.dst().map(|a| a.cidrlen())
.partial_cmp(&r1.dst().map(|a| a.cidrlen()))
.unwrap_or(std::cmp::Ordering::Equal)
});
let routes3 = routes2.iter().filter(|route| {
let Some(dst) = route.dst() else { return false };
let mask = if dst.cidrlen() != 0 {
(0xFFFFFFFFu32.overflowing_shr(32 - dst.cidrlen())).0.overflowing_shl(32 - dst.cidrlen()).0
} else {
0
};
let Ok(dst_addr): Result<Ipv4Addr, _> = dst.try_into() else { return false };
let dst_addr = u32::from(dst_addr);
(mask & dst_addr) == (mask & target_ip_num)
});
for route in routes3 {
let link = netlink::get_link_by_index(&links, route.ifindex());
println!(
"route: src: {:?}, dst: {:?}, link: {}, {:?}",
route.src().map(|s| (s.hw_address(), s.cidrlen())),
route.dst().map(|s| (s.hw_address(), s.cidrlen())),
route.ifindex(),
link.map(|l| l.name())
);
for hops in route.hop_iter() {
println!(
"\tgateway: {:?}, ifindex: {}",
hops.gateway().map(|g| g.hw_address()),
hops.ifindex()
);
}
}
let src_ip = route::Addr::from("172.17.0.1".parse::<Ipv4Addr>().unwrap());
let neighs = sock.get_neigh()?;
let target_neigh = route::get_neigh_for_addr(&neighs, &links, &src_ip);
if let Some((link, neigh)) = target_neigh {
println!(
"link: {}; src mac: {:?}; src ip: {:?}; dst mac: {:?}",
link.name(),
link.addr().hw_address(),
neigh.dst().hw_address(),
neigh.lladdr().hw_address()
);
}
Ok(())
} */