summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
authorAlan Somers <asomers@gmail.com>2022-03-13 16:16:25 -0600
committerAlan Somers <asomers@gmail.com>2022-03-13 16:34:23 -0600
commitf0f67954fe4a0d279c5a9483c6636020863de75a (patch)
tree5238f98418d369e70132720ae1f52147728e4161 /src/sys
parentbf59a6ca1006801be18266c5f16d077720f1b8c0 (diff)
downloadnix-f0f67954fe4a0d279c5a9483c6636020863de75a.zip
Fix a panic in Linkaddr::addr
The function assumed something about the values of the sockaddr_dl's fields. But because the inner type is public, we musn't do that. The only solution is to change the function's signature to return an Option.
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/socket/addr.rs71
1 files changed, 50 insertions, 21 deletions
diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs
index 51999a3d..9fd9e30a 100644
--- a/src/sys/socket/addr.rs
+++ b/src/sys/socket/addr.rs
@@ -1446,33 +1446,38 @@ mod datalink {
}
/// Physical-layer address (MAC)
- pub fn addr(&self) -> [u8; 6] {
+ pub fn addr(&self) -> Option<[u8; 6]> {
let nlen = self.nlen();
let data = self.0.sdl_data;
- assert!(!self.is_empty());
-
- [
- data[nlen] as u8,
- data[nlen + 1] as u8,
- data[nlen + 2] as u8,
- data[nlen + 3] as u8,
- data[nlen + 4] as u8,
- data[nlen + 5] as u8,
- ]
+ if self.is_empty() {
+ None
+ } else {
+ Some([
+ data[nlen] as u8,
+ data[nlen + 1] as u8,
+ data[nlen + 2] as u8,
+ data[nlen + 3] as u8,
+ data[nlen + 4] as u8,
+ data[nlen + 5] as u8,
+ ])
+ }
}
}
impl fmt::Display for LinkAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let addr = self.addr();
- write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
- addr[0],
- addr[1],
- addr[2],
- addr[3],
- addr[4],
- addr[5])
+ if let Some(addr) = self.addr() {
+ write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
+ addr[0],
+ addr[1],
+ addr[2],
+ addr[3],
+ addr[4],
+ addr[5])
+ } else {
+ Ok(())
+ }
}
}
}
@@ -1558,6 +1563,28 @@ mod tests {
target_os = "openbsd"))]
use super::*;
+ /// Don't panic when trying to display an empty datalink address
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ #[test]
+ fn test_datalink_display() {
+ let la = LinkAddr(libc::sockaddr_dl{
+ sdl_len: 56,
+ sdl_family: 18,
+ sdl_index: 5,
+ sdl_type: 24,
+ sdl_nlen: 3,
+ sdl_alen: 0,
+ sdl_slen: 0,
+ .. unsafe{mem::zeroed()}
+ });
+ format!("{}", la);
+ }
+
#[cfg(any(target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
@@ -1593,7 +1620,8 @@ mod tests {
match sock_addr {
SockAddr::Link(ether_addr) => {
- assert_eq!(ether_addr.addr(), [24u8, 101, 144, 221, 76, 176]);
+ assert_eq!(ether_addr.addr(),
+ Some([24u8, 101, 144, 221, 76, 176]));
},
_ => { unreachable!() }
};
@@ -1615,7 +1643,8 @@ mod tests {
match sock_addr {
SockAddr::Link(ether_addr) => {
- assert_eq!(ether_addr.addr(), [24u8, 101, 144, 221, 76, 176]);
+ assert_eq!(ether_addr.addr(),
+ Some([24u8, 101, 144, 221, 76, 176]));
},
_ => { unreachable!() }
};