Skip to content

Commit 0240b7a

Browse files
author
luozijun
committed
Update src/sys/socket/addr.rs
1 parent 614b6ef commit 0240b7a

File tree

1 file changed

+83
-53
lines changed

1 file changed

+83
-53
lines changed

src/sys/socket/addr.rs

Lines changed: 83 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ impl AddressFamily {
206206
/// Create a new `AddressFamily` from an integer value retrieved from `libc`, usually from
207207
/// the `sa_family` field of a `sockaddr`.
208208
///
209-
/// Currently only supports these address families: Unix, Inet (v4 & v6), Netlink
209+
/// Currently only supports these address families: Unix, Inet (v4 & v6), Netlink, Link
210210
/// and System. Returns None for unsupported or unknown address families.
211211
pub fn from_i32(family: i32) -> Option<AddressFamily> {
212212
match family {
@@ -798,52 +798,22 @@ impl SockAddr {
798798
#[cfg(any(target_os = "ios", target_os = "macos"))]
799799
Some(AddressFamily::System) => Some(SockAddr::SysControl(
800800
SysControlAddr(*(addr as *const sys_control::sockaddr_ctl)))),
801-
// FIXME: android is same ?
802-
// #[cfg(any(target_os = "android", target_os = "linux"))]
803-
#[cfg(target_os = "linux")]
804-
Some(AddressFamily::Packet) => {
805-
let sll: *const libc::sockaddr_ll = mem::transmute(addr);
806-
let mac = EtherAddr((*sll).sll_addr[0],
807-
(*sll).sll_addr[1],
808-
(*sll).sll_addr[2],
809-
(*sll).sll_addr[3],
810-
(*sll).sll_addr[4],
811-
(*sll).sll_addr[5]);
812-
Some(SockAddr::Ether(mac))
801+
#[cfg(any(target_os = "android", target_os = "linux"))]
802+
Some(AddressFamily::Packet) => match EtherAddr::from_libc_sockaddr_ll(
803+
addr as *const libc::sockaddr_ll) {
804+
Some(mac_addr) => Some(SockAddr::Ether(mac_addr)),
805+
None => None
813806
},
814807
#[cfg(any(target_os = "dragonfly",
815-
target_os = "freebsd",
816-
target_os = "ios",
817-
target_os = "macos",
818-
target_os = "netbsd",
819-
target_os = "openbsd"))]
820-
Some(AddressFamily::Link) => {
821-
let sdl: *const libc::sockaddr_dl = mem::transmute(addr);
822-
let nlen = (*sdl).sdl_nlen as usize;
823-
let max_nlen: usize = if cfg!(target_os = "macos") {
824-
12
825-
} else if cfg!(target_os = "freebsd") {
826-
46
827-
} else if cfg!(target_os = "dragonfly") {
828-
12
829-
} else if cfg!(target_os = "netbsd") {
830-
12
831-
} else if cfg!(target_os = "openbsd") {
832-
24
833-
} else {
834-
return None;
835-
};
836-
if nlen + 5 >= max_nlen {
837-
return None;
838-
}
839-
let mac = EtherAddr((*sdl).sdl_data[nlen] as u8,
840-
(*sdl).sdl_data[nlen + 1] as u8,
841-
(*sdl).sdl_data[nlen + 2] as u8,
842-
(*sdl).sdl_data[nlen + 3] as u8,
843-
(*sdl).sdl_data[nlen + 4] as u8,
844-
(*sdl).sdl_data[nlen + 5] as u8);
845-
846-
Some(SockAddr::Ether(mac))
808+
target_os = "freebsd",
809+
target_os = "ios",
810+
target_os = "macos",
811+
target_os = "netbsd",
812+
target_os = "openbsd"))]
813+
Some(AddressFamily::Link) => match EtherAddr::from_libc_sockaddr_dl(
814+
addr as *const libc::sockaddr_dl) {
815+
Some(mac_addr) => Some(SockAddr::Ether(mac_addr)),
816+
None => None
847817
},
848818
// Other address families are currently not supported and simply yield a None
849819
// entry instead of a proper conversion to a `SockAddr`.
@@ -1091,23 +1061,83 @@ pub mod sys_control {
10911061
}
10921062

10931063
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
1094-
pub struct EtherAddr(pub u8, pub u8, pub u8, pub u8, pub u8, pub u8);
1064+
pub struct EtherAddr {
1065+
pub a: u8,
1066+
pub b: u8,
1067+
pub c: u8,
1068+
pub d: u8,
1069+
pub e: u8,
1070+
pub f: u8,
1071+
}
10951072

10961073
impl EtherAddr {
10971074
pub fn new(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8) -> EtherAddr {
1098-
EtherAddr(a, b, c, d, e, f)
1075+
EtherAddr {
1076+
a: a,
1077+
b: b,
1078+
c: c,
1079+
d: d,
1080+
e: e,
1081+
f: f,
1082+
}
1083+
}
1084+
1085+
#[cfg(any(target_os = "android", target_os = "linux"))]
1086+
pub unsafe fn from_libc_sockaddr_ll(sll: *const libc::sockaddr_ll) -> Option<EtherAddr> {
1087+
let mac = EtherAddr::new(
1088+
(*sll).sll_addr[0],
1089+
(*sll).sll_addr[1],
1090+
(*sll).sll_addr[2],
1091+
(*sll).sll_addr[3],
1092+
(*sll).sll_addr[4],
1093+
(*sll).sll_addr[5]);
1094+
Some(mac)
1095+
}
1096+
1097+
#[cfg(any(target_os = "dragonfly",
1098+
target_os = "freebsd",
1099+
target_os = "ios",
1100+
target_os = "macos",
1101+
target_os = "netbsd",
1102+
target_os = "openbsd"))]
1103+
pub unsafe fn from_libc_sockaddr_dl(sdl: *const libc::sockaddr_dl) -> Option<EtherAddr> {
1104+
let nlen = (*sdl).sdl_nlen as usize;
1105+
let max_nlen: usize = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
1106+
12
1107+
} else if cfg!(target_os = "freebsd") {
1108+
46
1109+
} else if cfg!(target_os = "dragonfly") {
1110+
12
1111+
} else if cfg!(target_os = "netbsd") {
1112+
12
1113+
} else if cfg!(target_os = "openbsd") {
1114+
24
1115+
} else {
1116+
unreachable!();
1117+
};
1118+
if nlen + 5 >= max_nlen {
1119+
return None;
1120+
}
1121+
let mac = EtherAddr::new(
1122+
(*sdl).sdl_data[nlen ] as u8,
1123+
(*sdl).sdl_data[nlen + 1] as u8,
1124+
(*sdl).sdl_data[nlen + 2] as u8,
1125+
(*sdl).sdl_data[nlen + 3] as u8,
1126+
(*sdl).sdl_data[nlen + 4] as u8,
1127+
(*sdl).sdl_data[nlen + 5] as u8);
1128+
Some(mac)
10991129
}
11001130
}
11011131

11021132
impl fmt::Display for EtherAddr {
11031133
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11041134
write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
1105-
self.0,
1106-
self.1,
1107-
self.2,
1108-
self.3,
1109-
self.4,
1110-
self.5)
1135+
self.a,
1136+
self.b,
1137+
self.c,
1138+
self.d,
1139+
self.e,
1140+
self.f)
11111141
}
11121142
}
11131143

0 commit comments

Comments
 (0)