From fcc952a18c054821480964bc1b0f7b32e7728e62 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Mon, 23 Feb 2015 22:58:18 -0800 Subject: in_addr conversions + IP_DROP_MEMBERSHIP support --- src/nix.rs | 8 ++++- src/sys/socket/addr.rs | 87 ++++++++++++++++++++++++++++++++++++++++++----- src/sys/socket/mod.rs | 9 +++-- src/sys/socket/sockopt.rs | 1 + 4 files changed, 93 insertions(+), 12 deletions(-) diff --git a/src/nix.rs b/src/nix.rs index e59ceaed..3cc5beff 100644 --- a/src/nix.rs +++ b/src/nix.rs @@ -1,7 +1,7 @@ use libc; use std; -use errno::Errno; +use errno::{Errno, EINVAL}; pub type NixResult = Result; @@ -11,6 +11,12 @@ pub enum NixError { InvalidPath } +impl NixError { + pub fn invalid_argument() -> NixError { + NixError::Sys(EINVAL) + } +} + pub trait NixPath { fn with_nix_path(&self, f: F) -> Result where F: FnOnce(*const libc::c_char) -> T; diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs index 7a814d15..835979cf 100644 --- a/src/sys/socket/addr.rs +++ b/src/sys/socket/addr.rs @@ -1,10 +1,17 @@ use {NixResult, NixError}; use super::{sa_family_t, in_addr, sockaddr_in, sockaddr_in6, sockaddr_un, AF_UNIX, AF_INET}; use errno::Errno; +use libc; use std::{mem, net, path, ptr}; use std::ffi::{AsOsStr, CStr, OsStr}; use std::os::unix::OsStrExt; +/* + * + * ===== Sock addr ===== + * + */ + /// Represents a socket address #[derive(Copy)] pub enum SockAddr { @@ -66,21 +73,16 @@ impl ToSockAddr for path::Path { impl ToSockAddr for net::SocketAddr { fn to_sock_addr(&self) -> NixResult { use std::net::IpAddr; - use std::num::Int; match self.ip() { IpAddr::V4(ip) => { - let addr = ip.octets(); + let addr = ip.to_in_addr() + .expect("in_addr conversion expected to be successful"); + Ok(SockAddr::IpV4(sockaddr_in { sin_family: AF_INET as sa_family_t, sin_port: self.port(), - sin_addr: in_addr { - s_addr: Int::from_be( - ((addr[0] as u32) << 24) | - ((addr[1] as u32) << 16) | - ((addr[2] as u32) << 8) | - ((addr[3] as u32) << 0)) - }, + sin_addr: addr, .. unsafe { mem::zeroed() } })) } @@ -129,3 +131,70 @@ impl FromSockAddr for path::PathBuf { None } } + +/* + * + * ===== InAddr ===== + * + */ + +pub trait ToInAddr { + fn to_in_addr(self) -> Option; +} + +impl ToInAddr for SockAddr { + fn to_in_addr(self) -> Option { + match self { + SockAddr::IpV4(sock) => Some(sock.sin_addr), + _ => None, + } + } +} + +impl<'a> ToInAddr for &'a SockAddr { + fn to_in_addr(self) -> Option { + match *self { + SockAddr::IpV4(ref sock) => Some(sock.sin_addr), + _ => None, + } + } +} + +impl ToInAddr for net::IpAddr { + fn to_in_addr(self) -> Option { + match self { + net::IpAddr::V4(addr) => addr.to_in_addr(), + _ => None, + } + } +} + +impl<'a> ToInAddr for &'a net::IpAddr { + fn to_in_addr(self) -> Option { + match *self { + net::IpAddr::V4(addr) => addr.to_in_addr(), + _ => None, + } + } +} + +impl ToInAddr for net::Ipv4Addr { + fn to_in_addr(self) -> Option { + use std::num::Int; + + let addr = self.octets(); + Some(in_addr { + s_addr: Int::from_be( + ((addr[0] as u32) << 24) | + ((addr[1] as u32) << 16) | + ((addr[2] as u32) << 8) | + ((addr[3] as u32) << 0)) + }) + } +} + +impl<'a> ToInAddr for &'a net::Ipv4Addr { + fn to_in_addr(self) -> Option { + (*self).to_in_addr() + } +} diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 046df007..da29ae88 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -10,6 +10,7 @@ use std::os::unix::prelude::*; mod addr; mod consts; mod ffi; +mod multicast; pub mod sockopt; /* @@ -21,7 +22,8 @@ pub mod sockopt; pub use self::addr::{ SockAddr, ToSockAddr, - FromSockAddr + FromSockAddr, + ToInAddr, }; pub use libc::{ in_addr, @@ -31,7 +33,10 @@ pub use libc::{ sockaddr_in6, sockaddr_un, sa_family_t, - ip_mreq +}; + +pub use self::multicast::{ + ip_mreq, }; pub use self::consts::*; diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 79c1800e..a8063a56 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -72,6 +72,7 @@ sockopt_impl!(ReusePort, consts::SO_REUSEPORT, bool); sockopt_impl!(TcpNoDelay, consts::TCP_NODELAY, bool); sockopt_impl!(Linger, consts::SO_LINGER, super::linger); sockopt_impl!(IpAddMembership, consts::IP_ADD_MEMBERSHIP, super::ip_mreq); +sockopt_impl!(IpDropMembership, consts::IP_DROP_MEMBERSHIP, super::ip_mreq); sockopt_impl!(IpMulticastTtl, consts::IP_MULTICAST_TTL, u8); /* -- cgit v1.2.3