From 27b8836f74cb1c20f880b6fcae0c1b1dcd84f669 Mon Sep 17 00:00:00 2001 From: Xnoe Date: Sun, 30 Oct 2022 14:50:59 +0000 Subject: [PATCH] Implemented BroadcastAddress option, RenewalTime option and RebindingTime option. Ran cargo fmt --- src/main.rs | 327 +++++++++++++++++++++++++++++++---------------- src/rawsocket.rs | 45 +++++-- src/rtnetlink.rs | 22 ++-- 3 files changed, 263 insertions(+), 131 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2dfbf41..3302cb0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ -pub mod rtnetlink; pub mod rawsocket; +pub mod rtnetlink; use eui48::MacAddress; use rand::prelude::*; @@ -58,34 +58,32 @@ enum DHCPTransactionState { WaitingAfterDiscover, Request, WaitAfterRequest, - Renew + Renew, } fn pick_weighted(list: &Vec) -> Option<&T> { let len = list.len(); let mut rng = rand::thread_rng(); let mut prob = rng.gen_range(0f64..=1f64); - - println!("start prob={}", prob); + for (idx, elem) in list.iter().enumerate() { let weight = 1f64 / (2 as usize).pow(idx as u32 + (len != idx + 1) as u32) as f64; - + prob -= weight; - - println!("len={} idx={}: weight={}, prob={}", len, idx, weight, prob); - + if prob <= 0.0 { return Some(elem); } - } - + // fallback in case of float rounding errors i suppose list.choose(&mut rng) } fn dhcp_client(name: String, index: i32, mac: [u8; 6]) { - unsafe { libc::sleep(5); } + unsafe { + libc::sleep(5); + } let mut name = name; let mut socket_nl = rtnetlink::create_netlink_socket(false).unwrap(); let mut rng = rand::thread_rng(); @@ -120,65 +118,78 @@ fn dhcp_client(name: String, index: i32, mac: [u8; 6]) { DHCPOption::End, ], ) - .as_bytes() + .as_bytes(), ) { Ok(_) => break, - Err(libc::ENETDOWN) => { - unsafe { - { - #[repr(packed)] - struct Request {a: libc::nlmsghdr, b: rtnetlink::ifinfomsg} - let mut request = std::mem::zeroed::(); - - request.a.nlmsg_len = std::mem::size_of::() as u32; - request.a.nlmsg_type = libc::RTM_NEWLINK; - request.a.nlmsg_flags = (libc::NLM_F_REQUEST) as u16; - request.b.ifi_index = index; - request.b.ifi_flags = libc::IFF_UP as u32; - request.b.ifi_change = 1; - - socket_nl.send(rtnetlink::to_slice(&request)).unwrap(); + Err(libc::ENETDOWN) => unsafe { + { + #[repr(packed)] + struct Request { + a: libc::nlmsghdr, + b: rtnetlink::ifinfomsg, } + let mut request = std::mem::zeroed::(); - { - #[repr(packed)] - struct Request {a: libc::nlmsghdr, b: rtnetlink::ifinfomsg} - let mut request = std::mem::zeroed::(); - - request.a.nlmsg_len = std::mem::size_of::() as u32; - request.a.nlmsg_type = libc::RTM_GETLINK; - request.a.nlmsg_flags = (libc::NLM_F_REQUEST) as u16; - request.b.ifi_index = index; - - socket_nl.send(rtnetlink::to_slice(&request)).unwrap(); + request.a.nlmsg_len = std::mem::size_of::() as u32; + request.a.nlmsg_type = libc::RTM_NEWLINK; + request.a.nlmsg_flags = (libc::NLM_F_REQUEST) as u16; + request.b.ifi_index = index; + request.b.ifi_flags = libc::IFF_UP as u32; + request.b.ifi_change = 1; - let mut buffer = [0; 4096]; - socket_nl.recv(&mut buffer).unwrap(); - - let nlmsghdr = &buffer as *const _ as *const libc::nlmsghdr; - if (*nlmsghdr).nlmsg_type != libc::RTM_NEWLINK { - panic!("Wrong message!"); - } - - let mut n = (*nlmsghdr).nlmsg_len - std::mem::size_of::() as u32 - std::mem::size_of::() as u32; - let mut rtattr = (&buffer as *const _ as *const u8).offset(std::mem::size_of::() as isize + std::mem::size_of::() as isize) as *const rtnetlink::rtattr; - - while rtnetlink::rta_ok(rtattr, &mut n) { - match (*rtattr).rta_type { - libc::IFLA_IFNAME => { - name = zascii(&std::ptr::read(rtnetlink::rta_data(rtattr) as *const _ as *const [libc::c_char; libc::IFNAMSIZ])); - } - _ => () - } - - rtattr = rtnetlink::rta_next(rtattr, &mut n); - } - } - - libc::sleep(10); + socket_nl.send(rtnetlink::to_slice(&request)).unwrap(); } - } - Err(_) => panic!("Failed to send on {}", name) + + { + #[repr(packed)] + struct Request { + a: libc::nlmsghdr, + b: rtnetlink::ifinfomsg, + } + let mut request = std::mem::zeroed::(); + + request.a.nlmsg_len = std::mem::size_of::() as u32; + request.a.nlmsg_type = libc::RTM_GETLINK; + request.a.nlmsg_flags = (libc::NLM_F_REQUEST) as u16; + request.b.ifi_index = index; + + socket_nl.send(rtnetlink::to_slice(&request)).unwrap(); + + let mut buffer = [0; 4096]; + socket_nl.recv(&mut buffer).unwrap(); + + let nlmsghdr = &buffer as *const _ as *const libc::nlmsghdr; + if (*nlmsghdr).nlmsg_type != libc::RTM_NEWLINK { + panic!("Wrong message!"); + } + + let mut n = (*nlmsghdr).nlmsg_len + - std::mem::size_of::() as u32 + - std::mem::size_of::() as u32; + let mut rtattr = (&buffer as *const _ as *const u8).offset( + std::mem::size_of::() as isize + + std::mem::size_of::() as isize, + ) + as *const rtnetlink::rtattr; + + while rtnetlink::rta_ok(rtattr, &mut n) { + match (*rtattr).rta_type { + libc::IFLA_IFNAME => { + name = zascii(&std::ptr::read( + rtnetlink::rta_data(rtattr) as *const _ + as *const [libc::c_char; libc::IFNAMSIZ], + )); + } + _ => (), + } + + rtattr = rtnetlink::rta_next(rtattr, &mut n); + } + } + + libc::sleep(10); + }, + Err(_) => panic!("Failed to send on {}", name), } } dhcp_state = DHCPTransactionState::WaitingAfterDiscover; @@ -246,22 +257,24 @@ fn dhcp_client(name: String, index: i32, mac: [u8; 6]) { DHCPTransactionState::Request => { println!("Sent DHCPRequest on {}", name); - socket.send( - create_dhcp_packet( - xid, - client_mac, - None, - None, - vec![ - DHCPOption::DHCPMessageType(DHCPMessageType::DHCPRequest), - DHCPOption::RequestIPAddress(client_addr.unwrap()), - DHCPOption::ServerIdentifier(server_addr.unwrap()), - DHCPOption::ParameterRequest(vec![1, 3, 6, 28, 121]), - DHCPOption::End, - ], + socket + .send( + create_dhcp_packet( + xid, + client_mac, + None, + None, + vec![ + DHCPOption::DHCPMessageType(DHCPMessageType::DHCPRequest), + DHCPOption::RequestIPAddress(client_addr.unwrap()), + DHCPOption::ServerIdentifier(server_addr.unwrap()), + DHCPOption::ParameterRequest(vec![1, 3, 6, 28, 121]), + DHCPOption::End, + ], + ) + .as_bytes(), ) - .as_bytes() - ).unwrap(); + .unwrap(); dhcp_state = DHCPTransactionState::WaitAfterRequest; } @@ -308,10 +321,14 @@ fn dhcp_client(name: String, index: i32, mac: [u8; 6]) { } let mut sleep_time = 0; - let mut subnet_mask = Ipv4Addr::new(0,0,0,0); + let mut subnet_mask = Ipv4Addr::new(0, 0, 0, 0); let mut router = Vec::new(); let mut dns = Vec::new(); let mut classless_static_routes = Vec::new(); + let mut broadcast = None; + + let mut renew_time = None; + let mut rebind_time = None; for option in options { println!("Received: {:?}", option); @@ -323,6 +340,10 @@ fn dhcp_client(name: String, index: i32, mac: [u8; 6]) { DHCPOption::DomainNameServer(v) => dns = v, DHCPOption::ClasslessStaticRoute(v) => classless_static_routes = v, + DHCPOption::RenewalTime(t) => renew_time = Some(t), + DHCPOption::RebindingTime(t) => rebind_time = Some(t), + DHCPOption::BroadcastAddress(a) => broadcast = Some(a), + _ => (), } } @@ -330,38 +351,73 @@ fn dhcp_client(name: String, index: i32, mac: [u8; 6]) { unsafe { { #[repr(packed)] - struct Request {a: libc::nlmsghdr, b: rtnetlink::ifaddrmsg, c: rtnetlink::rtattr, d: [u8; 4], e: rtnetlink::rtattr, f: [u8; 4], g: rtnetlink::rtattr, h: rtnetlink::ifa_cacheinfo} + struct Request { + a: libc::nlmsghdr, + b: rtnetlink::ifaddrmsg, + c: rtnetlink::rtattr, + d: [u8; 4], + e: rtnetlink::rtattr, + f: [u8; 4], + g: rtnetlink::rtattr, + h: rtnetlink::ifa_cacheinfo, + } let mut request = std::mem::zeroed::(); request.a.nlmsg_len = std::mem::size_of::() as u32; request.a.nlmsg_type = libc::RTM_NEWADDR; - request.a.nlmsg_flags = (libc::NLM_F_REQUEST | libc::NLM_F_CREATE | libc::NLM_F_REPLACE) as u16; + request.a.nlmsg_flags = + (libc::NLM_F_REQUEST | libc::NLM_F_CREATE | libc::NLM_F_REPLACE) + as u16; request.b.ifa_family = libc::AF_INET as u8; request.b.ifa_index = index; request.b.ifa_prefixlen = u32::from(subnet_mask).leading_ones() as u8; request.c.rta_type = libc::IFA_LOCAL; - request.c.rta_len = std::mem::size_of::<(rtnetlink::rtattr, [u8; 4])>() as u16; + request.c.rta_len = + std::mem::size_of::<(rtnetlink::rtattr, [u8; 4])>() as u16; request.d = client_addr.unwrap().octets(); request.e.rta_type = libc::IFA_BROADCAST; - request.e.rta_len = std::mem::size_of::<(rtnetlink::rtattr, [u8; 4])>() as u16; - request.f = ((u32::from(client_addr.unwrap()) & u32::from(subnet_mask)) | (!u32::from(subnet_mask))).to_be_bytes(); + request.e.rta_len = + std::mem::size_of::<(rtnetlink::rtattr, [u8; 4])>() as u16; + if let Some(broadcast) = broadcast { + request.f = broadcast.octets(); + } else { + request.f = ((u32::from(client_addr.unwrap()) + & u32::from(subnet_mask)) + | (!u32::from(subnet_mask))) + .to_be_bytes(); + } request.g.rta_type = libc::IFA_CACHEINFO; - request.g.rta_len = std::mem::size_of::<(rtnetlink::rtattr, rtnetlink::ifa_cacheinfo)>() as u16; - request.h.ifa_preferred = (sleep_time as f32 * 0.5) as u32; - request.h.ifa_valid = (sleep_time as f32 * 0.875) as u32; + request.g.rta_len = std::mem::size_of::<( + rtnetlink::rtattr, + rtnetlink::ifa_cacheinfo, + )>() as u16; + request.h.ifa_preferred = + renew_time.unwrap_or((sleep_time as f32 * 0.5) as u32); + request.h.ifa_valid = + rebind_time.unwrap_or((sleep_time as f32 * 0.875) as u32); socket_nl.send(rtnetlink::to_slice(&request)).unwrap(); } { #[repr(packed)] - struct Request {a: libc::nlmsghdr, b: rtnetlink::rtmsg, c: rtnetlink::rtattr, d: [u8; 4], e: rtnetlink::rtattr, f: libc::c_int, g: rtnetlink::rtattr, h: rtnetlink::rta_cacheinfo} + struct Request { + a: libc::nlmsghdr, + b: rtnetlink::rtmsg, + c: rtnetlink::rtattr, + d: [u8; 4], + e: rtnetlink::rtattr, + f: libc::c_int, + g: rtnetlink::rtattr, + h: rtnetlink::rta_cacheinfo, + } let mut request = std::mem::zeroed::(); request.a.nlmsg_len = std::mem::size_of::() as u32; request.a.nlmsg_type = libc::RTM_NEWROUTE; - request.a.nlmsg_flags = (libc::NLM_F_REQUEST | libc::NLM_F_CREATE) as u16; + request.a.nlmsg_flags = + (libc::NLM_F_REQUEST | libc::NLM_F_CREATE) as u16; request.b.rtm_family = libc::AF_INET as u8; request.b.rtm_table = libc::RT_TABLE_MAIN; request.b.rtm_type = libc::RTN_UNICAST; @@ -369,27 +425,43 @@ fn dhcp_client(name: String, index: i32, mac: [u8; 6]) { request.b.rtm_scope = libc::RT_SCOPE_LINK; request.b.rtm_dst_len = u32::from(subnet_mask).leading_ones() as u8; request.c.rta_type = libc::RTA_DST; - request.c.rta_len = std::mem::size_of::<(rtnetlink::rtattr, [u8; 4])>() as u16; + request.c.rta_len = + std::mem::size_of::<(rtnetlink::rtattr, [u8; 4])>() as u16; request.d = client_addr.unwrap().octets(); request.e.rta_type = libc::RTA_OIF; - request.e.rta_len = std::mem::size_of::<(rtnetlink::rtattr, libc::c_int)>() as u16; + request.e.rta_len = + std::mem::size_of::<(rtnetlink::rtattr, libc::c_int)>() as u16; request.f = index; request.g.rta_type = libc::RTA_CACHEINFO; - request.g.rta_len = std::mem::size_of::<(rtnetlink::rtattr, rtnetlink::rta_cacheinfo)>() as u16; - request.h.rta_expires = (sleep_time as f32 * 0.875) as u32; + request.g.rta_len = std::mem::size_of::<( + rtnetlink::rtattr, + rtnetlink::rta_cacheinfo, + )>() as u16; + request.h.rta_expires = + rebind_time.unwrap_or((sleep_time as f32 * 0.875) as u32); socket_nl.send(rtnetlink::to_slice(&request)).unwrap(); } { #[repr(packed)] - struct Request {a: libc::nlmsghdr, b: rtnetlink::rtmsg, c: rtnetlink::rtattr, d: [u8; 4], e: rtnetlink::rtattr, f: libc::c_int, g: rtnetlink::rtattr, h: rtnetlink::rta_cacheinfo} + struct Request { + a: libc::nlmsghdr, + b: rtnetlink::rtmsg, + c: rtnetlink::rtattr, + d: [u8; 4], + e: rtnetlink::rtattr, + f: libc::c_int, + g: rtnetlink::rtattr, + h: rtnetlink::rta_cacheinfo, + } let mut request = std::mem::zeroed::(); request.a.nlmsg_len = std::mem::size_of::() as u32; request.a.nlmsg_type = libc::RTM_NEWROUTE; - request.a.nlmsg_flags = (libc::NLM_F_REQUEST | libc::NLM_F_CREATE) as u16; + request.a.nlmsg_flags = + (libc::NLM_F_REQUEST | libc::NLM_F_CREATE) as u16; request.b.rtm_family = libc::AF_INET as u8; request.b.rtm_table = libc::RT_TABLE_MAIN; request.b.rtm_type = libc::RTN_UNICAST; @@ -397,28 +469,44 @@ fn dhcp_client(name: String, index: i32, mac: [u8; 6]) { request.b.rtm_scope = libc::RT_SCOPE_UNIVERSE; request.b.rtm_dst_len = 0; request.c.rta_type = libc::RTA_GATEWAY; - request.c.rta_len = std::mem::size_of::<(rtnetlink::rtattr, [u8; 4])>() as u16; + request.c.rta_len = + std::mem::size_of::<(rtnetlink::rtattr, [u8; 4])>() as u16; request.d = pick_weighted(&router).unwrap().octets(); request.e.rta_type = libc::RTA_OIF; - request.e.rta_len = std::mem::size_of::<(rtnetlink::rtattr, libc::c_int)>() as u16; + request.e.rta_len = + std::mem::size_of::<(rtnetlink::rtattr, libc::c_int)>() as u16; request.f = index; request.g.rta_type = libc::RTA_CACHEINFO; - request.g.rta_len = std::mem::size_of::<(rtnetlink::rtattr, rtnetlink::rta_cacheinfo)>() as u16; - request.h.rta_expires = (sleep_time as f32 * 0.875) as u32; + request.g.rta_len = std::mem::size_of::<( + rtnetlink::rtattr, + rtnetlink::rta_cacheinfo, + )>() as u16; + request.h.rta_expires = + rebind_time.unwrap_or((sleep_time as f32 * 0.875) as u32); socket_nl.send(rtnetlink::to_slice(&request)).unwrap(); } { #[repr(packed)] - struct Request {a: libc::nlmsghdr, b: rtnetlink::rtmsg, c: rtnetlink::rtattr, d: [u8; 4], e: rtnetlink::rtattr, f: [u8; 4], g: rtnetlink::rtattr, h: libc::c_int} + struct Request { + a: libc::nlmsghdr, + b: rtnetlink::rtmsg, + c: rtnetlink::rtattr, + d: [u8; 4], + e: rtnetlink::rtattr, + f: [u8; 4], + g: rtnetlink::rtattr, + h: libc::c_int, + } for (prefix, prefix_len, router) in classless_static_routes { let mut request = std::mem::zeroed::(); request.a.nlmsg_len = std::mem::size_of::() as u32; request.a.nlmsg_type = libc::RTM_NEWROUTE; - request.a.nlmsg_flags = (libc::NLM_F_REQUEST | libc::NLM_F_CREATE) as u16; + request.a.nlmsg_flags = + (libc::NLM_F_REQUEST | libc::NLM_F_CREATE) as u16; request.b.rtm_family = libc::AF_INET as u8; request.b.rtm_table = libc::RT_TABLE_MAIN; request.b.rtm_type = libc::RTN_UNICAST; @@ -426,29 +514,44 @@ fn dhcp_client(name: String, index: i32, mac: [u8; 6]) { request.b.rtm_scope = libc::RT_SCOPE_UNIVERSE; request.b.rtm_dst_len = prefix_len; request.c.rta_type = libc::RTA_DST; - request.c.rta_len = std::mem::size_of::<(rtnetlink::rtattr, [u8; 4])>() as u16; + request.c.rta_len = + std::mem::size_of::<(rtnetlink::rtattr, [u8; 4])>() as u16; request.d = prefix.octets(); request.e.rta_type = libc::RTA_GATEWAY; - request.e.rta_len = std::mem::size_of::<(rtnetlink::rtattr, [u8; 4])>() as u16; + request.e.rta_len = + std::mem::size_of::<(rtnetlink::rtattr, [u8; 4])>() as u16; request.f = router.octets(); request.g.rta_type = libc::RTA_OIF; - request.g.rta_len = std::mem::size_of::<(rtnetlink::rtattr, libc::c_int)>() as u16; + request.g.rta_len = + std::mem::size_of::<(rtnetlink::rtattr, libc::c_int)>() as u16; request.h = index; - socket_nl.send(rtnetlink::to_slice(&request)).unwrap(); } } - let mut f = std::fs::OpenOptions::new().write(true).truncate(true).open("/etc/resolv.conf").unwrap(); + let mut f = std::fs::OpenOptions::new() + .write(true) + .truncate(true) + .open("/etc/resolv.conf") + .unwrap(); for server in dns { - f.write_all(("nameserver ".to_string() + &server.to_string() + "\n").as_bytes()).unwrap(); + f.write_all( + ("nameserver ".to_string() + &server.to_string() + "\n").as_bytes(), + ) + .unwrap(); } f.flush().unwrap(); } - println!("Sleeping for {} for lease time to elapse.", (sleep_time as f32 * 0.5) as u32); - std::thread::sleep(core::time::Duration::new((sleep_time as f32 * 0.5) as u64, 0)); + println!( + "Sleeping for {} for lease time to elapse.", + renew_time.unwrap_or((sleep_time as f32 * 0.5) as u32) + ); + std::thread::sleep(core::time::Duration::new( + renew_time.unwrap_or((sleep_time as f32 * 0.5) as u32) as u64, + 0, + )); dhcp_state = DHCPTransactionState::Renew } @@ -466,7 +569,7 @@ fn dhcp_client(name: String, index: i32, mac: [u8; 6]) { DHCPOption::End, ], ) - .as_bytes() + .as_bytes(), ); dhcp_state = DHCPTransactionState::WaitAfterRequest; } @@ -540,4 +643,4 @@ fn main() { ); println!("Index: {}", interface.index); } -} \ No newline at end of file +} diff --git a/src/rawsocket.rs b/src/rawsocket.rs index 70744de..1c3152f 100644 --- a/src/rawsocket.rs +++ b/src/rawsocket.rs @@ -8,7 +8,7 @@ pub struct RawSocket { socket: libc::c_int, src_addr: libc::sockaddr_ll, dest_addr: libc::sockaddr_ll, - if_index: i32 + if_index: i32, } pub fn create_raw_socket(index: i32, mac: [u8; 6]) -> Result { @@ -42,15 +42,34 @@ pub fn create_raw_socket(index: i32, mac: [u8; 6]) -> Result(); timeval.tv_sec = 30; - if libc::setsockopt(socket, libc::SOL_SOCKET, libc::SO_RCVTIMEO, &timeval as *const _ as *const libc::c_void, std::mem::size_of::() as u32) == -1 { + if libc::setsockopt( + socket, + libc::SOL_SOCKET, + libc::SO_RCVTIMEO, + &timeval as *const _ as *const libc::c_void, + std::mem::size_of::() as u32, + ) == -1 + { return Err("Failed to set SO_RCVTIMEO"); } - if libc::setsockopt(socket, libc::SOL_SOCKET, libc::SO_BROADCAST, &(1 as u32) as *const _ as *const libc::c_void, std::mem::size_of::() as u32) == -1 { - return Err("Failed to set SO_BROADCAST") + if libc::setsockopt( + socket, + libc::SOL_SOCKET, + libc::SO_BROADCAST, + &(1 as u32) as *const _ as *const libc::c_void, + std::mem::size_of::() as u32, + ) == -1 + { + return Err("Failed to set SO_BROADCAST"); } - if libc::bind(socket, &src_addr as *const _ as *const libc::sockaddr, std::mem::size_of::() as u32) == -1 { + if libc::bind( + socket, + &src_addr as *const _ as *const libc::sockaddr, + std::mem::size_of::() as u32, + ) == -1 + { return Err("Failed to bind to socket"); } } @@ -59,7 +78,7 @@ pub fn create_raw_socket(index: i32, mac: [u8; 6]) -> Result() }; msg.msg_name = &mut self.dest_addr as *mut _ as *mut libc::c_void; msg.msg_namelen = std::mem::size_of::() as u32; @@ -100,10 +119,16 @@ impl RawSocket { if n < 0 { match unsafe { *libc::__errno_location() } { libc::EAGAIN => return Ok((0, [0, 0, 0, 0, 0, 0])), - err => return Err(err) + err => return Err(err), } } else { - return Ok((n, unsafe { std::ptr::read(msg.msg_name as *mut _ as *mut libc::sockaddr_ll) }.sll_addr[..6].try_into().unwrap())); + return Ok(( + n, + unsafe { std::ptr::read(msg.msg_name as *mut _ as *mut libc::sockaddr_ll) } + .sll_addr[..6] + .try_into() + .unwrap(), + )); } } @@ -130,4 +155,4 @@ impl RawSocket { sll_protocol: 0x0008, }; } -} \ No newline at end of file +} diff --git a/src/rtnetlink.rs b/src/rtnetlink.rs index 482da5d..0e7b2f3 100644 --- a/src/rtnetlink.rs +++ b/src/rtnetlink.rs @@ -155,7 +155,7 @@ unsafe fn ifla_rta(r: *const ifinfomsg) -> *const rtattr { pub struct Socket { socket: libc::c_int, src_addr: libc::sockaddr_nl, - dest_addr: libc::sockaddr_nl + dest_addr: libc::sockaddr_nl, } pub fn create_netlink_socket(subscribed: bool) -> Result { @@ -177,7 +177,12 @@ pub fn create_netlink_socket(subscribed: bool) -> Result { return Err("Failed to create socket"); } - if libc::bind(socket, &src_addr as *const _ as *const libc::sockaddr, std::mem::size_of::() as u32) == -1 { + if libc::bind( + socket, + &src_addr as *const _ as *const libc::sockaddr, + std::mem::size_of::() as u32, + ) == -1 + { return Err("Failed to bind to socket"); } } @@ -185,7 +190,7 @@ pub fn create_netlink_socket(subscribed: bool) -> Result { Ok(Socket { socket: socket, src_addr: src_addr, - dest_addr: dest_addr + dest_addr: dest_addr, }) } @@ -195,7 +200,7 @@ impl Socket { iov_base: msg as *const _ as *mut libc::c_void, iov_len: msg.len() as usize, }; - + let mut msg = unsafe { std::mem::zeroed::() }; msg.msg_name = &mut self.dest_addr as *mut _ as *mut libc::c_void; msg.msg_namelen = std::mem::size_of::() as u32; @@ -239,10 +244,7 @@ pub struct InterfaceIterator { } pub unsafe fn to_slice(p: &T) -> &[u8] { - std::slice::from_raw_parts( - (p as *const T) as *const u8, - std::mem::size_of::(), - ) + std::slice::from_raw_parts((p as *const T) as *const u8, std::mem::size_of::()) } pub fn new_interface_iterator() -> Result { @@ -254,7 +256,9 @@ pub fn new_interface_iterator() -> Result { request.0.nlmsg_flags = (libc::NLM_F_REQUEST | libc::NLM_F_DUMP) as u16; request.1.ifi_family = libc::AF_NETLINK as u8; - socket.send(unsafe {to_slice(&request)}).expect("Failed to send interface request!"); + socket + .send(unsafe { to_slice(&request) }) + .expect("Failed to send interface request!"); Ok(InterfaceIterator { socket: socket,