summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Lerche <me@carllerche.com>2015-02-23 22:58:18 -0800
committerCarl Lerche <me@carllerche.com>2015-02-23 22:58:18 -0800
commitfcc952a18c054821480964bc1b0f7b32e7728e62 (patch)
treeb922a4d92c6a7e23fe5181d911a6f7200755b4e2
parent979faf097691dc35bb12b91dcde0d804a3d32b79 (diff)
downloadnix-fcc952a18c054821480964bc1b0f7b32e7728e62.zip
in_addr conversions + IP_DROP_MEMBERSHIP support
-rw-r--r--src/nix.rs8
-rw-r--r--src/sys/socket/addr.rs87
-rw-r--r--src/sys/socket/mod.rs9
-rw-r--r--src/sys/socket/sockopt.rs1
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<T> = Result<T, NixError>;
@@ -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<T, F>(&self, f: F) -> Result<T, NixError>
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<SockAddr> {
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<libc::in_addr>;
+}
+
+impl ToInAddr for SockAddr {
+ fn to_in_addr(self) -> Option<libc::in_addr> {
+ match self {
+ SockAddr::IpV4(sock) => Some(sock.sin_addr),
+ _ => None,
+ }
+ }
+}
+
+impl<'a> ToInAddr for &'a SockAddr {
+ fn to_in_addr(self) -> Option<libc::in_addr> {
+ match *self {
+ SockAddr::IpV4(ref sock) => Some(sock.sin_addr),
+ _ => None,
+ }
+ }
+}
+
+impl ToInAddr for net::IpAddr {
+ fn to_in_addr(self) -> Option<libc::in_addr> {
+ match self {
+ net::IpAddr::V4(addr) => addr.to_in_addr(),
+ _ => None,
+ }
+ }
+}
+
+impl<'a> ToInAddr for &'a net::IpAddr {
+ fn to_in_addr(self) -> Option<libc::in_addr> {
+ match *self {
+ net::IpAddr::V4(addr) => addr.to_in_addr(),
+ _ => None,
+ }
+ }
+}
+
+impl ToInAddr for net::Ipv4Addr {
+ fn to_in_addr(self) -> Option<libc::in_addr> {
+ 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<libc::in_addr> {
+ (*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);
/*