Skip to content

Commit

Permalink
add new_route example
Browse files Browse the repository at this point in the history
  • Loading branch information
liuxu623 committed Sep 19, 2023
1 parent 970f795 commit 6a1d3fb
Showing 1 changed file with 93 additions and 0 deletions.
93 changes: 93 additions & 0 deletions examples/new_route.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// SPDX-License-Identifier: MIT

use std::net::{Ipv4Addr};
use netlink_packet_core::{
NetlinkHeader, NetlinkMessage, NetlinkPayload, NLM_F_ACK, NLM_F_CREATE,
NLM_F_EXCL, NLM_F_REQUEST,
};
use netlink_packet_route::{
constants::{AF_INET}, route, RtnlMessage, RouteHeader, RouteMessage, RouteFlags,
RT_TABLE_MAIN, RTPROT_BOOT, RT_SCOPE_UNIVERSE, RTN_UNICAST,
};
use netlink_sys::{protocols::NETLINK_ROUTE, Socket, SocketAddr};

fn main() {
let mut socket = Socket::new(NETLINK_ROUTE).unwrap();
let _port_number = socket.bind_auto().unwrap().port_number();
socket.connect(&SocketAddr::new(0, 0)).unwrap();

let mut route_msg_hdr = RouteHeader::default();
route_msg_hdr.address_family = AF_INET as u8;
route_msg_hdr.table = RT_TABLE_MAIN;
route_msg_hdr.scope = RT_SCOPE_UNIVERSE;
route_msg_hdr.protocol = RTPROT_BOOT;
route_msg_hdr.kind = RTN_UNICAST;
route_msg_hdr.source_prefix_length = 0;
route_msg_hdr.destination_prefix_length = 32;
route_msg_hdr.flags = RouteFlags::RTNH_F_ONLINK;

let mut route_msg = RouteMessage::default();
route_msg.header = route_msg_hdr;
route_msg.nlas = vec![
// lo
route::Nla::Oif(1),
route::Nla::Gateway(
"169.254.1.1".parse::<Ipv4Addr>().unwrap().octets().to_vec()),
route::Nla::Destination(
"1.1.1.1".parse::<Ipv4Addr>().unwrap().octets().to_vec()),
];
let mut nl_hdr = NetlinkHeader::default();
nl_hdr.flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;

let mut msg = NetlinkMessage::new(
nl_hdr,
NetlinkPayload::from(RtnlMessage::NewRoute(route_msg)),
);

msg.finalize();
let mut buf = vec![0; msg.header.length as usize];

msg.serialize(&mut buf[..msg.buffer_len()]);

println!(">>> {msg:?}");

socket
.send(&buf, 0)
.expect("failed to send netlink message");

let mut receive_buffer = vec![0; 4096];
let mut offset = 0;

'outer: loop {
let size = socket.recv(&mut &mut receive_buffer[..], 0).unwrap();

loop {
let bytes = &receive_buffer[offset..];
// Parse the message
let rx_packet: NetlinkMessage<RtnlMessage> =
NetlinkMessage::deserialize(bytes).unwrap();

match rx_packet.payload {
NetlinkPayload::Error(err) => {
match err.code {
None => {
println!("Done!");
break 'outer;
}
Some(_) => {
eprintln!("Received a netlink error message: {err:?}");
return;
}
}
}
_ => {}
}

offset += rx_packet.header.length as usize;
if offset == size || rx_packet.header.length == 0 {
offset = 0;
break;
}
}
}
}

0 comments on commit 6a1d3fb

Please sign in to comment.