// 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 . 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::().unwrap(); let target_ip_num = u32::from(target_ip); let mut routes2 = routes.iter().collect::>(); 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 = 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::().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(()) } */