Skip to content

Commit 9eccfc2

Browse files
Alexander Polakovkamalmarhubi
Alexander Polakov
authored andcommitted
Netlink bits
1 parent f167e8f commit 9eccfc2

File tree

3 files changed

+97
-1
lines changed

3 files changed

+97
-1
lines changed

src/sys/socket/addr.rs

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use std::{fmt, hash, mem, net, ptr};
55
use std::ffi::OsStr;
66
use std::path::Path;
77
use std::os::unix::ffi::OsStrExt;
8+
#[cfg(any(target_os = "linux", target_os = "android"))]
9+
use ::sys::socket::addr::netlink::NetlinkAddr;
810

911
// TODO: uncomment out IpAddr functions: rust-lang/rfcs#988
1012

@@ -14,12 +16,24 @@ use std::os::unix::ffi::OsStrExt;
1416
*
1517
*/
1618

19+
#[cfg(any(target_os = "linux", target_os = "android"))]
20+
#[derive(Debug,Copy,Clone)]
21+
#[repr(C)]
22+
pub struct sockaddr_nl {
23+
pub nl_family: sa_family_t,
24+
nl_pad: libc::c_ushort,
25+
pub nl_pid: u32,
26+
pub nl_groups: u32
27+
}
28+
1729
#[repr(i32)]
1830
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
1931
pub enum AddressFamily {
2032
Unix = consts::AF_UNIX,
2133
Inet = consts::AF_INET,
2234
Inet6 = consts::AF_INET6,
35+
#[cfg(any(target_os = "linux", target_os = "android"))]
36+
Netlink = consts::AF_NETLINK,
2337
}
2438

2539
#[derive(Copy)]
@@ -449,7 +463,9 @@ impl fmt::Display for UnixAddr {
449463
#[derive(Copy)]
450464
pub enum SockAddr {
451465
Inet(InetAddr),
452-
Unix(UnixAddr)
466+
Unix(UnixAddr),
467+
#[cfg(any(target_os = "linux", target_os = "android"))]
468+
Netlink(NetlinkAddr)
453469
}
454470

455471
impl SockAddr {
@@ -461,11 +477,18 @@ impl SockAddr {
461477
Ok(SockAddr::Unix(try!(UnixAddr::new(path))))
462478
}
463479

480+
#[cfg(any(target_os = "linux", target_os = "android"))]
481+
pub fn new_netlink(pid: u32, groups: u32) -> SockAddr {
482+
SockAddr::Netlink(NetlinkAddr::new(pid, groups))
483+
}
484+
464485
pub fn family(&self) -> AddressFamily {
465486
match *self {
466487
SockAddr::Inet(InetAddr::V4(..)) => AddressFamily::Inet,
467488
SockAddr::Inet(InetAddr::V6(..)) => AddressFamily::Inet6,
468489
SockAddr::Unix(..) => AddressFamily::Unix,
490+
#[cfg(any(target_os = "linux", target_os = "android"))]
491+
SockAddr::Netlink(..) => AddressFamily::Netlink,
469492
}
470493
}
471494

@@ -478,6 +501,8 @@ impl SockAddr {
478501
SockAddr::Inet(InetAddr::V4(ref addr)) => (mem::transmute(addr), mem::size_of::<libc::sockaddr_in>() as libc::socklen_t),
479502
SockAddr::Inet(InetAddr::V6(ref addr)) => (mem::transmute(addr), mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t),
480503
SockAddr::Unix(UnixAddr(ref addr, len)) => (mem::transmute(addr), (len + mem::size_of::<libc::sa_family_t>()) as libc::socklen_t),
504+
#[cfg(any(target_os = "linux", target_os = "android"))]
505+
SockAddr::Netlink(NetlinkAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<sockaddr_nl>() as libc::socklen_t),
481506
}
482507
}
483508
}
@@ -491,6 +516,10 @@ impl PartialEq for SockAddr {
491516
(SockAddr::Unix(ref a), SockAddr::Unix(ref b)) => {
492517
a == b
493518
}
519+
#[cfg(any(target_os = "linux", target_os = "android"))]
520+
(SockAddr::Netlink(ref a), SockAddr::Netlink(ref b)) => {
521+
a == b
522+
}
494523
_ => false,
495524
}
496525
}
@@ -504,6 +533,8 @@ impl hash::Hash for SockAddr {
504533
match *self {
505534
SockAddr::Inet(ref a) => a.hash(s),
506535
SockAddr::Unix(ref a) => a.hash(s),
536+
#[cfg(any(target_os = "linux", target_os = "android"))]
537+
SockAddr::Netlink(ref a) => a.hash(s),
507538
}
508539
}
509540
}
@@ -519,6 +550,64 @@ impl fmt::Display for SockAddr {
519550
match *self {
520551
SockAddr::Inet(ref inet) => inet.fmt(f),
521552
SockAddr::Unix(ref unix) => unix.fmt(f),
553+
#[cfg(any(target_os = "linux", target_os = "android"))]
554+
SockAddr::Netlink(ref nl) => nl.fmt(f),
555+
}
556+
}
557+
}
558+
559+
#[cfg(any(target_os = "linux", target_os = "android"))]
560+
pub mod netlink {
561+
use ::sys::socket::addr::{AddressFamily,sockaddr_nl};
562+
use libc::sa_family_t;
563+
use std::{fmt, hash};
564+
565+
#[derive(Copy)]
566+
pub struct NetlinkAddr(pub sockaddr_nl);
567+
568+
impl NetlinkAddr {
569+
pub fn new(pid: u32, groups: u32) -> NetlinkAddr {
570+
NetlinkAddr(sockaddr_nl {
571+
nl_family: AddressFamily::Netlink as sa_family_t,
572+
nl_pad: 0,
573+
nl_pid: pid,
574+
nl_groups: groups,
575+
})
576+
}
577+
578+
pub fn pid(&self) -> u32 {
579+
self.0.nl_pid
580+
}
581+
582+
pub fn groups(&self) -> u32 {
583+
self.0.nl_groups
584+
}
585+
}
586+
587+
impl PartialEq for NetlinkAddr {
588+
fn eq(&self, other: &NetlinkAddr) -> bool {
589+
self.0.nl_pid == other.0.nl_pid && self.0.nl_groups == self.0.nl_groups
590+
}
591+
}
592+
593+
impl Eq for NetlinkAddr {
594+
}
595+
596+
impl hash::Hash for NetlinkAddr {
597+
fn hash<H: hash::Hasher>(&self, s: &mut H) {
598+
( self.0.nl_family, self.0.nl_pid, self.0.nl_groups).hash(s)
599+
}
600+
}
601+
602+
impl Clone for NetlinkAddr {
603+
fn clone(&self) -> NetlinkAddr {
604+
*self
605+
}
606+
}
607+
608+
impl fmt::Display for NetlinkAddr {
609+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
610+
write!(f, "pid: {} groups: {}", self.pid(), self.groups())
522611
}
523612
}
524613
}

src/sys/socket/consts.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod os {
88
pub const AF_LOCAL: c_int = AF_UNIX;
99
pub const AF_INET: c_int = 2;
1010
pub const AF_INET6: c_int = 10;
11+
pub const AF_NETLINK: c_int = 16;
1112

1213
pub const SOCK_STREAM: c_int = 1;
1314
pub const SOCK_DGRAM: c_int = 2;
@@ -20,6 +21,7 @@ mod os {
2021
pub const SOL_TCP: c_int = 6;
2122
pub const SOL_UDP: c_int = 17;
2223
pub const SOL_IPV6: c_int = 41;
24+
pub const SOL_NETLINK: c_int = 270;
2325
pub const IPPROTO_IP: c_int = SOL_IP;
2426
pub const IPPROTO_IPV6: c_int = SOL_IPV6;
2527
pub const IPPROTO_TCP: c_int = SOL_TCP;

src/sys/socket/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ pub use self::addr::{
3131
Ipv4Addr,
3232
Ipv6Addr,
3333
};
34+
#[cfg(any(target_os = "linux", target_os = "android"))]
35+
pub use ::sys::socket::addr::netlink::NetlinkAddr;
36+
3437
pub use libc::{
3538
in_addr,
3639
in6_addr,
@@ -538,6 +541,8 @@ pub enum SockLevel {
538541
Ip = IPPROTO_IP,
539542
Ipv6 = IPPROTO_IPV6,
540543
Udp = IPPROTO_UDP,
544+
#[cfg(any(target_os = "linux", target_os = "android"))]
545+
Netlink = SOL_NETLINK,
541546
}
542547

543548
/// Represents a socket option that can be accessed or set. Used as an argument

0 commit comments

Comments
 (0)