You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Rust的rtnetlink库获取指定IP的网关(替代ip route get)

用Rust的rtnetlink实现ip route get <IP>的功能

你遇到的问题核心是:当前代码发起了路由列表的dump请求(对应ip route show),而非针对特定IP的精准路由查询。要实现ip route get的效果,需要构造带目标IP筛选条件的单条查询请求,而非dump所有路由。

解决方案代码

首先确保Cargo.toml中添加依赖:

[dependencies]
rtnetlink = "0.10"
tokio = { version = "1.0", features = ["full"] }
ipnet = "2.0"

然后编写实现代码:

use ipnet::IpNet;
use rtnetlink::{new_connection, packet::route::RouteMessage};
use std::net::IpAddr;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 要查询的目标IP
    let target_ip: IpAddr = "10.244.1.2".parse()?;

    // 初始化rtnetlink连接
    let (connection, handle, _) = new_connection()?;
    tokio::spawn(connection);

    // 构造精准路由查询请求
    let mut route_msg = RouteMessage::new();
    // 设置地址族(IPv4/IPv6)
    route_msg.set_family(match target_ip {
        IpAddr::V4(_) => rtnetlink::packet::route::RouteFamily::Inet,
        IpAddr::V6(_) => rtnetlink::packet::route::RouteFamily::Inet6,
    });
    // 指定请求类型为GETROUTE,仅发送单条查询(不使用NLM_F_DUMP)
    route_msg.message.header.set_type(rtnetlink::packet::RtNetlinkMessageType::GetRoute);
    route_msg.message.header.flags = rtnetlink::packet::NlmFlags::REQUEST;

    // 添加目标IP属性(RTA_DST),用32位前缀表示主机路由
    let ip_net = IpNet::new(target_ip, 32)?;
    route_msg.add_attr_dst(ip_net.network());

    // 发送请求并获取结果
    let routes = handle.route().get(route_msg).execute().await?;

    // 解析结果,提取网关(via)等信息
    for route in routes {
        println!("匹配的路由信息:");
        if let Some(gateway) = route.gateway() {
            println!("via: {}", gateway);
        }
        if let Some(src) = route.src() {
            println!("src: {}", src);
        }
        if let Some(if_idx) = route.output_interface() {
            println!("dev: {}", if_idx);
        }
    }

    Ok(())
}

关键要点

  • 避免使用dump()方法:handle.route().get().dump()会触发内核返回所有路由条目,对应ip route show的行为。
  • 精准设置查询条件:手动构造RouteMessage,添加RTA_DST属性指定目标IP,同时不设置NLM_F_DUMP标志,内核会返回匹配该IP的最优路由。
  • 提取网关:通过route.gateway()方法可以直接获取ip route get输出中的via字段内容。

如果需要支持更复杂的场景(比如指定源IP、策略路由),可以额外添加RTA_SRC属性或调整请求的flags,基础场景下上述代码即可满足需求。

内容的提问来源于stack exchange,提问作者Jeff Hutchins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 08:50:25