1 use super::{consts, sa_family_t}
;
2 use {Errno, Error, Result, NixPath}
;
4 use std
::{fmt, hash, mem, net, ptr}
;
7 use std
::os
::unix
::ffi
::OsStrExt
;
8 #[cfg(any(target_os = "linux", target_os = "android"))]
9 use ::sys
::socket
::addr
::netlink
::NetlinkAddr
;
10 #[cfg(any(target_os = "macos", target_os = "ios"))]
11 use std
::os
::unix
::io
::RawFd
;
12 #[cfg(any(target_os = "macos", target_os = "ios"))]
13 use ::sys
::socket
::addr
::sys_control
::SysControlAddr
;
15 // TODO: uncomment out IpAddr functions: rust-lang/rfcs#988
19 * ===== AddressFamily =====
24 #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
25 pub enum AddressFamily
{
26 Unix
= consts
::AF_UNIX
,
27 Inet
= consts
::AF_INET
,
28 Inet6
= consts
::AF_INET6
,
29 #[cfg(any(target_os = "linux", target_os = "android"))]
30 Netlink
= consts
::AF_NETLINK
,
31 #[cfg(any(target_os = "linux", target_os = "android"))]
32 Packet
= consts
::AF_PACKET
,
33 #[cfg(any(target_os = "macos", target_os = "ios"))]
34 System
= consts
::AF_SYSTEM
,
39 V4(libc
::sockaddr_in
),
40 V6(libc
::sockaddr_in6
),
44 pub fn from_std(std
: &net
::SocketAddr
) -> InetAddr
{
46 net
::SocketAddr
::V4(ref addr
) => {
47 InetAddr
::V4(libc
::sockaddr_in
{
48 sin_family
: AddressFamily
::Inet
as sa_family_t
,
49 sin_port
: addr
.port().to_be(), // network byte order
50 sin_addr
: Ipv4Addr
::from_std(addr
.ip()).0,
51 .. unsafe { mem::zeroed() }
54 net
::SocketAddr
::V6(ref addr
) => {
55 InetAddr
::V6(libc
::sockaddr_in6
{
56 sin6_family
: AddressFamily
::Inet6
as sa_family_t
,
57 sin6_port
: addr
.port().to_be(), // network byte order
58 sin6_addr
: Ipv6Addr
::from_std(addr
.ip()).0,
59 sin6_flowinfo
: addr
.flowinfo(), // host byte order
60 sin6_scope_id
: addr
.scope_id(), // host byte order
61 .. unsafe { mem::zeroed() }
67 pub fn new(ip
: IpAddr
, port
: u16) -> InetAddr
{
69 IpAddr
::V4(ref ip
) => {
70 InetAddr
::V4(libc
::sockaddr_in
{
71 sin_family
: AddressFamily
::Inet
as sa_family_t
,
72 sin_port
: port
.to_be(),
74 .. unsafe { mem::zeroed() }
77 IpAddr
::V6(ref ip
) => {
78 InetAddr
::V6(libc
::sockaddr_in6
{
79 sin6_family
: AddressFamily
::Inet6
as sa_family_t
,
80 sin6_port
: port
.to_be(),
82 .. unsafe { mem::zeroed() }
87 /// Gets the IP address associated with this socket address.
88 pub fn ip(&self) -> IpAddr
{
90 InetAddr
::V4(ref sa
) => IpAddr
::V4(Ipv4Addr(sa
.sin_addr
)),
91 InetAddr
::V6(ref sa
) => IpAddr
::V6(Ipv6Addr(sa
.sin6_addr
)),
95 /// Gets the port number associated with this socket address
96 pub fn port(&self) -> u16 {
98 InetAddr
::V6(ref sa
) => u16::from_be(sa
.sin6_port
),
99 InetAddr
::V4(ref sa
) => u16::from_be(sa
.sin_port
),
103 pub fn to_std(&self) -> net
::SocketAddr
{
105 InetAddr
::V4(ref sa
) => net
::SocketAddr
::V4(
106 net
::SocketAddrV4
::new(
107 Ipv4Addr(sa
.sin_addr
).to_std(),
109 InetAddr
::V6(ref sa
) => net
::SocketAddr
::V6(
110 net
::SocketAddrV6
::new(
111 Ipv6Addr(sa
.sin6_addr
).to_std(),
118 pub fn to_str(&self) -> String
{
123 impl PartialEq
for InetAddr
{
124 fn eq(&self, other
: &InetAddr
) -> bool
{
125 match (*self, *other
) {
126 (InetAddr
::V4(ref a
), InetAddr
::V4(ref b
)) => {
127 a
.sin_port
== b
.sin_port
&&
128 a
.sin_addr
.s_addr
== b
.sin_addr
.s_addr
130 (InetAddr
::V6(ref a
), InetAddr
::V6(ref b
)) => {
131 a
.sin6_port
== b
.sin6_port
&&
132 a
.sin6_addr
.s6_addr
== b
.sin6_addr
.s6_addr
&&
133 a
.sin6_flowinfo
== b
.sin6_flowinfo
&&
134 a
.sin6_scope_id
== b
.sin6_scope_id
141 impl Eq
for InetAddr
{
144 impl hash
::Hash
for InetAddr
{
145 fn hash
<H
: hash
::Hasher
>(&self, s
: &mut H
) {
147 InetAddr
::V4(ref a
) => {
150 a
.sin_addr
.s_addr
).hash(s
)
152 InetAddr
::V6(ref a
) => {
155 &a
.sin6_addr
.s6_addr
,
157 a
.sin6_scope_id
).hash(s
)
163 impl Clone
for InetAddr
{
164 fn clone(&self) -> InetAddr
{
169 impl fmt
::Display
for InetAddr
{
170 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
172 InetAddr
::V4(_
) => write
!(f
, "{}:{}", self.ip(), self.port()),
173 InetAddr
::V6(_
) => write
!(f
, "[{}]:{}", self.ip(), self.port()),
190 /// Create a new IpAddr that contains an IPv4 address.
192 /// The result will represent the IP address a.b.c.d
193 pub fn new_v4(a
: u8, b
: u8, c
: u8, d
: u8) -> IpAddr
{
194 IpAddr
::V4(Ipv4Addr
::new(a
, b
, c
, d
))
197 /// Create a new IpAddr that contains an IPv6 address.
199 /// The result will represent the IP address a:b:c:d:e:f
200 pub fn new_v6(a
: u16, b
: u16, c
: u16, d
: u16, e
: u16, f
: u16, g
: u16, h
: u16) -> IpAddr
{
201 IpAddr
::V6(Ipv6Addr
::new(a
, b
, c
, d
, e
, f
, g
, h
))
205 pub fn from_std(std: &net::IpAddr) -> IpAddr {
207 net::IpAddr::V4(ref std) => IpAddr::V4(Ipv4Addr::from_std(std)),
208 net::IpAddr::V6(ref std) => IpAddr::V6(Ipv6Addr::from_std(std)),
212 pub fn to_std(&self) -> net::IpAddr {
214 IpAddr::V4(ref ip) => net::IpAddr::V4(ip.to_std()),
215 IpAddr::V6(ref ip) => net::IpAddr::V6(ip.to_std()),
221 impl fmt
::Display
for IpAddr
{
222 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
224 IpAddr
::V4(ref v4
) => v4
.fmt(f
),
225 IpAddr
::V6(ref v6
) => v6
.fmt(f
)
232 * ===== Ipv4Addr =====
237 pub struct Ipv4Addr(pub libc
::in_addr
);
240 pub fn new(a
: u8, b
: u8, c
: u8, d
: u8) -> Ipv4Addr
{
241 let ip
= (((a
as u32) << 24) |
244 ((d
as u32) << 0)).to_be();
246 Ipv4Addr(libc
::in_addr { s_addr: ip }
)
249 pub fn from_std(std
: &net
::Ipv4Addr
) -> Ipv4Addr
{
250 let bits
= std
.octets();
251 Ipv4Addr
::new(bits
[0], bits
[1], bits
[2], bits
[3])
254 pub fn any() -> Ipv4Addr
{
255 Ipv4Addr(libc
::in_addr { s_addr: consts::INADDR_ANY }
)
258 pub fn octets(&self) -> [u8; 4] {
259 let bits
= u32::from_be(self.0.s_addr
);
260 [(bits
>> 24) as u8, (bits
>> 16) as u8, (bits
>> 8) as u8, bits
as u8]
263 pub fn to_std(&self) -> net
::Ipv4Addr
{
264 let bits
= self.octets();
265 net
::Ipv4Addr
::new(bits
[0], bits
[1], bits
[2], bits
[3])
269 impl PartialEq
for Ipv4Addr
{
270 fn eq(&self, other
: &Ipv4Addr
) -> bool
{
271 self.0.s_addr
== other
.0.s_addr
275 impl Eq
for Ipv4Addr
{
278 impl hash
::Hash
for Ipv4Addr
{
279 fn hash
<H
: hash
::Hasher
>(&self, s
: &mut H
) {
280 self.0.s_addr
.hash(s
)
284 impl Clone
for Ipv4Addr
{
285 fn clone(&self) -> Ipv4Addr
{
290 impl fmt
::Display
for Ipv4Addr
{
291 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
292 let octets
= self.octets();
293 write
!(fmt
, "{}.{}.{}.{}", octets
[0], octets
[1], octets
[2], octets
[3])
299 * ===== Ipv6Addr =====
303 #[derive(Clone, Copy)]
304 pub struct Ipv6Addr(pub libc
::in6_addr
);
306 // Note that IPv6 addresses are stored in big endian order on all architectures.
307 // See https://tools.ietf.org/html/rfc1700 or consult your favorite search
310 macro_rules
! to_u8_array
{
311 ($
($num
:ident
),*) => {
312 [ $
(($num
>>8) as u8, ($num
&0xff) as u8,)* ]
316 macro_rules
! to_u16_array
{
317 ($slf
:ident
, $
($first
:expr
, $second
:expr
),*) => {
318 [$
( (($slf
.0.s6_addr
[$first
] as u16) << 8) + $slf
.0.s6_addr
[$second
] as u16,)*]
323 pub fn new(a
: u16, b
: u16, c
: u16, d
: u16, e
: u16, f
: u16, g
: u16, h
: u16) -> Ipv6Addr
{
324 let mut in6_addr_var
: libc
::in6_addr
= unsafe{mem::uninitialized()}
;
325 in6_addr_var
.s6_addr
= to_u8_array
!(a
,b
,c
,d
,e
,f
,g
,h
);
326 Ipv6Addr(in6_addr_var
)
329 pub fn from_std(std
: &net
::Ipv6Addr
) -> Ipv6Addr
{
330 let s
= std
.segments();
331 Ipv6Addr
::new(s
[0], s
[1], s
[2], s
[3], s
[4], s
[5], s
[6], s
[7])
334 /// Return the eight 16-bit segments that make up this address
335 pub fn segments(&self) -> [u16; 8] {
336 to_u16_array
!(self, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
339 pub fn to_std(&self) -> net
::Ipv6Addr
{
340 let s
= self.segments();
341 net
::Ipv6Addr
::new(s
[0], s
[1], s
[2], s
[3], s
[4], s
[5], s
[6], s
[7])
345 impl fmt
::Display
for Ipv6Addr
{
346 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
347 self.to_std().fmt(fmt
)
353 * ===== UnixAddr =====
357 /// A wrapper around `sockaddr_un`. We track the length of `sun_path` (excluding
358 /// a terminating null), because it may not be null-terminated. For example,
359 /// unconnected and Linux abstract sockets are never null-terminated, and POSIX
360 /// does not require that `sun_len` include the terminating null even for normal
361 /// sockets. Note that the actual sockaddr length is greater by
362 /// `offset_of!(libc::sockaddr_un, sun_path)`
364 pub struct UnixAddr(pub libc
::sockaddr_un
, pub usize);
367 /// Create a new sockaddr_un representing a filesystem path.
368 pub fn new
<P
: ?Sized
+ NixPath
>(path
: &P
) -> Result
<UnixAddr
> {
369 try
!(path
.with_nix_path(|cstr
| {
371 let mut ret
= libc
::sockaddr_un
{
372 sun_family
: AddressFamily
::Unix
as sa_family_t
,
376 let bytes
= cstr
.to_bytes();
378 if bytes
.len() > ret
.sun_path
.len() {
379 return Err(Error
::Sys(Errno
::ENAMETOOLONG
));
382 ptr
::copy_nonoverlapping(bytes
.as_ptr(),
383 ret
.sun_path
.as_mut_ptr() as *mut u8,
386 Ok(UnixAddr(ret
, bytes
.len()))
391 /// Create a new sockaddr_un representing an address in the
392 /// "abstract namespace". This is a Linux-specific extension,
393 /// primarily used to allow chrooted processes to communicate with
394 /// specific daemons.
395 pub fn new_abstract(path
: &[u8]) -> Result
<UnixAddr
> {
397 let mut ret
= libc
::sockaddr_un
{
398 sun_family
: AddressFamily
::Unix
as sa_family_t
,
402 if path
.len() + 1 > ret
.sun_path
.len() {
403 return Err(Error
::Sys(Errno
::ENAMETOOLONG
));
406 // Abstract addresses are represented by sun_path[0] ==
407 // b'\0', so copy starting one byte in.
408 ptr
::copy_nonoverlapping(path
.as_ptr(),
409 ret
.sun_path
.as_mut_ptr().offset(1) as *mut u8,
412 Ok(UnixAddr(ret
, path
.len() + 1))
416 fn sun_path(&self) -> &[u8] {
417 unsafe { mem::transmute(&self.0.sun_path[..self.1]) }
420 /// If this address represents a filesystem path, return that path.
421 pub fn path(&self) -> Option
<&Path
> {
422 if self.1 == 0 || self.0.sun_path
[0] == 0 {
423 // unbound or abstract
426 let p
= self.sun_path();
427 // POSIX only requires that `sun_len` be at least long enough to
428 // contain the pathname, and it need not be null-terminated. So we
429 // need to create a string that is the shorter of the
430 // null-terminated length or the full length.
431 let ptr
= &self.0.sun_path
as *const libc
::c_char
;
432 let reallen
= unsafe { libc::strnlen(ptr, p.len()) }
;
433 Some(Path
::new(<OsStr
as OsStrExt
>::from_bytes(&p
[..reallen
])))
438 impl PartialEq
for UnixAddr
{
439 fn eq(&self, other
: &UnixAddr
) -> bool
{
440 self.sun_path() == other
.sun_path()
444 impl Eq
for UnixAddr
{
447 impl hash
::Hash
for UnixAddr
{
448 fn hash
<H
: hash
::Hasher
>(&self, s
: &mut H
) {
449 ( self.0.sun_family
, self.sun_path() ).hash(s
)
453 impl Clone
for UnixAddr
{
454 fn clone(&self) -> UnixAddr
{
459 impl fmt
::Display
for UnixAddr
{
460 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
462 f
.write_str("<unbound UNIX socket>")
463 } else if let Some(path
) = self.path() {
464 path
.display().fmt(f
)
466 let display
= String
::from_utf8_lossy(&self.sun_path()[1..]);
467 write
!(f
, "@{}", display
)
474 * ===== Sock addr =====
478 /// Represents a socket address
483 #[cfg(any(target_os = "linux", target_os = "android"))]
484 Netlink(NetlinkAddr
),
485 #[cfg(any(target_os = "macos", target_os = "ios"))]
486 SysControl(SysControlAddr
),
490 pub fn new_inet(addr
: InetAddr
) -> SockAddr
{
494 pub fn new_unix
<P
: ?Sized
+ NixPath
>(path
: &P
) -> Result
<SockAddr
> {
495 Ok(SockAddr
::Unix(try
!(UnixAddr
::new(path
))))
498 #[cfg(any(target_os = "linux", target_os = "android"))]
499 pub fn new_netlink(pid
: u32, groups
: u32) -> SockAddr
{
500 SockAddr
::Netlink(NetlinkAddr
::new(pid
, groups
))
503 #[cfg(any(target_os = "macos", target_os = "ios"))]
504 pub fn new_sys_control(sockfd
: RawFd
, name
: &str, unit
: u32) -> Result
<SockAddr
> {
505 SysControlAddr
::from_name(sockfd
, name
, unit
).map(|a
| SockAddr
::SysControl(a
))
508 pub fn family(&self) -> AddressFamily
{
510 SockAddr
::Inet(InetAddr
::V4(..)) => AddressFamily
::Inet
,
511 SockAddr
::Inet(InetAddr
::V6(..)) => AddressFamily
::Inet6
,
512 SockAddr
::Unix(..) => AddressFamily
::Unix
,
513 #[cfg(any(target_os = "linux", target_os = "android"))]
514 SockAddr
::Netlink(..) => AddressFamily
::Netlink
,
515 #[cfg(any(target_os = "macos", target_os = "ios"))]
516 SockAddr
::SysControl(..) => AddressFamily
::System
,
520 pub fn to_str(&self) -> String
{
524 pub unsafe fn as_ffi_pair(&self) -> (&libc
::sockaddr
, libc
::socklen_t
) {
526 SockAddr
::Inet(InetAddr
::V4(ref addr
)) => (mem
::transmute(addr
), mem
::size_of
::<libc
::sockaddr_in
>() as libc
::socklen_t
),
527 SockAddr
::Inet(InetAddr
::V6(ref addr
)) => (mem
::transmute(addr
), mem
::size_of
::<libc
::sockaddr_in6
>() as libc
::socklen_t
),
528 SockAddr
::Unix(UnixAddr(ref addr
, len
)) => (mem
::transmute(addr
), (len
+ offset_of
!(libc
::sockaddr_un
, sun_path
)) as libc
::socklen_t
),
529 #[cfg(any(target_os = "linux", target_os = "android"))]
530 SockAddr
::Netlink(NetlinkAddr(ref sa
)) => (mem
::transmute(sa
), mem
::size_of
::<libc
::sockaddr_nl
>() as libc
::socklen_t
),
531 #[cfg(any(target_os = "macos", target_os = "ios"))]
532 SockAddr
::SysControl(SysControlAddr(ref sa
)) => (mem
::transmute(sa
), mem
::size_of
::<sys_control
::sockaddr_ctl
>() as libc
::socklen_t
),
537 impl PartialEq
for SockAddr
{
538 fn eq(&self, other
: &SockAddr
) -> bool
{
539 match (*self, *other
) {
540 (SockAddr
::Inet(ref a
), SockAddr
::Inet(ref b
)) => {
543 (SockAddr
::Unix(ref a
), SockAddr
::Unix(ref b
)) => {
546 #[cfg(any(target_os = "linux", target_os = "android"))]
547 (SockAddr
::Netlink(ref a
), SockAddr
::Netlink(ref b
)) => {
555 impl Eq
for SockAddr
{
558 impl hash
::Hash
for SockAddr
{
559 fn hash
<H
: hash
::Hasher
>(&self, s
: &mut H
) {
561 SockAddr
::Inet(ref a
) => a
.hash(s
),
562 SockAddr
::Unix(ref a
) => a
.hash(s
),
563 #[cfg(any(target_os = "linux", target_os = "android"))]
564 SockAddr
::Netlink(ref a
) => a
.hash(s
),
565 #[cfg(any(target_os = "macos", target_os = "ios"))]
566 SockAddr
::SysControl(ref a
) => a
.hash(s
),
571 impl Clone
for SockAddr
{
572 fn clone(&self) -> SockAddr
{
577 impl fmt
::Display
for SockAddr
{
578 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
580 SockAddr
::Inet(ref inet
) => inet
.fmt(f
),
581 SockAddr
::Unix(ref unix
) => unix
.fmt(f
),
582 #[cfg(any(target_os = "linux", target_os = "android"))]
583 SockAddr
::Netlink(ref nl
) => nl
.fmt(f
),
584 #[cfg(any(target_os = "macos", target_os = "ios"))]
585 SockAddr
::SysControl(ref sc
) => sc
.fmt(f
),
590 #[cfg(any(target_os = "linux", target_os = "android"))]
592 use ::sys
::socket
::addr
::{AddressFamily}
;
593 use libc
::{sa_family_t, sockaddr_nl}
;
595 use std
::hash
::{Hash, Hasher}
;
597 #[derive(Copy, Clone)]
598 pub struct NetlinkAddr(pub sockaddr_nl
);
600 // , PartialEq, Eq, Debug, Hash
601 impl PartialEq
for NetlinkAddr
{
602 fn eq(&self, other
: &Self) -> bool
{
603 let (inner
, other
) = (self.0, other
.0);
604 (inner
.nl_family
, inner
.nl_pid
, inner
.nl_groups
) ==
605 (other
.nl_family
, other
.nl_pid
, other
.nl_groups
)
609 impl Eq
for NetlinkAddr {}
611 impl Hash
for NetlinkAddr
{
612 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
614 (inner
.nl_family
, inner
.nl_pid
, inner
.nl_groups
).hash(s
);
620 pub fn new(pid
: u32, groups
: u32) -> NetlinkAddr
{
621 let mut addr
: sockaddr_nl
= unsafe { mem::zeroed() }
;
622 addr
.nl_family
= AddressFamily
::Netlink
as sa_family_t
;
624 addr
.nl_groups
= groups
;
629 pub fn pid(&self) -> u32 {
633 pub fn groups(&self) -> u32 {
638 impl fmt
::Display
for NetlinkAddr
{
639 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
640 write
!(f
, "pid: {} groups: {}", self.pid(), self.groups())
645 #[cfg(any(target_os = "macos", target_os = "ios"))]
646 pub mod sys_control
{
647 use ::sys
::socket
::consts
;
648 use ::sys
::socket
::addr
::{AddressFamily}
;
649 use libc
::{c_uchar, uint16_t, uint32_t}
;
651 use std
::hash
::{Hash, Hasher}
;
652 use std
::os
::unix
::io
::RawFd
;
653 use {Errno, Error, Result}
;
656 pub struct ctl_ioc_info
{
657 pub ctl_id
: uint32_t
,
658 pub ctl_name
: [c_uchar
; MAX_KCTL_NAME
],
661 const CTL_IOC_MAGIC
: u8 = 'N'
as u8;
662 const CTL_IOC_INFO
: u8 = 3;
663 const MAX_KCTL_NAME
: usize = 96;
665 ioctl
!(readwrite ctl_info with CTL_IOC_MAGIC
, CTL_IOC_INFO
; ctl_ioc_info
);
668 #[derive(Copy, Clone)]
669 pub struct sockaddr_ctl
{
671 pub sc_family
: c_uchar
,
672 pub ss_sysaddr
: uint16_t
,
674 pub sc_unit
: uint32_t
,
675 pub sc_reserved
: [uint32_t
; 5],
678 #[derive(Copy, Clone)]
679 pub struct SysControlAddr(pub sockaddr_ctl
);
681 // , PartialEq, Eq, Debug, Hash
682 impl PartialEq
for SysControlAddr
{
683 fn eq(&self, other
: &Self) -> bool
{
684 let (inner
, other
) = (self.0, other
.0);
685 (inner
.sc_id
, inner
.sc_unit
) ==
686 (other
.sc_id
, other
.sc_unit
)
690 impl Eq
for SysControlAddr {}
692 impl Hash
for SysControlAddr
{
693 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
695 (inner
.sc_id
, inner
.sc_unit
).hash(s
);
700 impl SysControlAddr
{
701 pub fn new(id
: u32, unit
: u32) -> SysControlAddr
{
702 let addr
= sockaddr_ctl
{
703 sc_len
: mem
::size_of
::<sockaddr_ctl
>() as c_uchar
,
704 sc_family
: AddressFamily
::System
as c_uchar
,
705 ss_sysaddr
: consts
::AF_SYS_CONTROL
as uint16_t
,
714 pub fn from_name(sockfd
: RawFd
, name
: &str, unit
: u32) -> Result
<SysControlAddr
> {
715 if name
.len() > MAX_KCTL_NAME
{
716 return Err(Error
::Sys(Errno
::ENAMETOOLONG
));
719 let mut ctl_name
= [0; MAX_KCTL_NAME
];
720 ctl_name
[..name
.len()].clone_from_slice(name
.as_bytes());
721 let mut info
= ctl_ioc_info { ctl_id: 0, ctl_name: ctl_name }
;
723 unsafe { try!(ctl_info(sockfd, &mut info)); }
725 Ok(SysControlAddr
::new(info
.ctl_id
, unit
))
728 pub fn id(&self) -> u32 {
732 pub fn unit(&self) -> u32 {
737 impl fmt
::Display
for SysControlAddr
{
738 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
739 write
!(f
, "id: {} unit: {}", self.id(), self.unit())