Skip to content

Commit 895604f

Browse files
authored
Merge pull request #292 from fox0/talk
talk: impl From<&SocketAddrV4> for Osockaddr
2 parents 6f1ee84 + a4be304 commit 895604f

File tree

1 file changed

+36
-28
lines changed

1 file changed

+36
-28
lines changed

users/talk.rs

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ use std::{
2626
io::{self, Cursor, Error, IsTerminal, Write},
2727
mem::{size_of, zeroed},
2828
net::{
29-
self, AddrParseError, Ipv4Addr, SocketAddr, SocketAddrV4, TcpListener, TcpStream, UdpSocket,
29+
self, AddrParseError, Ipv4Addr, SocketAddr, SocketAddrV4, SocketAddrV6, TcpListener,
30+
TcpStream, UdpSocket,
3031
},
3132
os::fd::AsRawFd,
3233
process, ptr,
@@ -196,6 +197,7 @@ type SaFamily = u16;
196197
#[cfg(target_os = "linux")]
197198
type SaFamily = sa_family_t;
198199

200+
#[derive(PartialEq)]
199201
#[binrw]
200202
/// Socket address structure representing a network address.
201203
pub struct Osockaddr {
@@ -205,6 +207,15 @@ pub struct Osockaddr {
205207
pub sa_data: [u8; 14],
206208
}
207209

210+
impl Default for Osockaddr {
211+
fn default() -> Self {
212+
Osockaddr {
213+
sa_family: 0, // TODO use enum libc::AF_UNSPEC as u16
214+
sa_data: [0; 14],
215+
}
216+
}
217+
}
218+
208219
impl From<&Osockaddr> for SocketAddrV4 {
209220
fn from(value: &Osockaddr) -> Self {
210221
// Extract the port
@@ -226,45 +237,29 @@ impl From<&SocketAddr> for Osockaddr {
226237
fn from(value: &SocketAddr) -> Self {
227238
match value {
228239
SocketAddr::V4(v) => Self::from(v),
229-
SocketAddr::V6(_) => unimplemented!(),
240+
SocketAddr::V6(v) => Self::from(v),
230241
}
231242
}
232243
}
233244

234245
impl From<&SocketAddrV4> for Osockaddr {
235246
fn from(value: &SocketAddrV4) -> Self {
236-
let ip = value.ip().to_string();
237-
let port = value.port();
238-
// TODO use as.bytes()
247+
let port: [u8; 2] = value.port().to_be_bytes();
248+
let octets: [u8; 4] = value.ip().octets();
239249

240-
let mut sa_data: [u8; 14] = [0; 14];
250+
let mut result = Self::default();
241251

242-
let ip_segments: Result<Vec<u8>, _> = ip.split('.').map(|s| s.parse::<u8>()).collect();
252+
result.sa_data[0..2].copy_from_slice(&port);
253+
result.sa_data[2..6].copy_from_slice(&octets);
254+
result.sa_data[12..14].copy_from_slice(&[0, 2]);
243255

244-
match ip_segments {
245-
Ok(ip_bytes) if ip_bytes.len() == 4 => {
246-
sa_data[0..2].copy_from_slice(&port.to_be_bytes());
247-
sa_data[2..6].copy_from_slice(&ip_bytes);
248-
sa_data[12..14].copy_from_slice(&[0, 2]);
249-
}
250-
_ => {
251-
eprint!("Invalid IP address format: {}", ip);
252-
}
253-
}
254-
255-
Self {
256-
sa_family: 0, // TODO use enum
257-
sa_data,
258-
}
256+
result
259257
}
260258
}
261259

262-
impl Default for Osockaddr {
263-
fn default() -> Self {
264-
Osockaddr {
265-
sa_family: 0,
266-
sa_data: [0; 14],
267-
}
260+
impl From<&SocketAddrV6> for Osockaddr {
261+
fn from(_value: &SocketAddrV6) -> Self {
262+
unimplemented!()
268263
}
269264
}
270265

@@ -1758,3 +1753,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
17581753

17591754
process::exit(exit_code)
17601755
}
1756+
1757+
#[cfg(test)]
1758+
mod tests {
1759+
use super::*;
1760+
1761+
#[test]
1762+
fn test_osock_addr_from_socket_addr_v4() {
1763+
let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 600);
1764+
let value = Osockaddr::from(&socket);
1765+
assert_eq!(value.sa_family, libc::AF_UNSPEC as u16);
1766+
assert_eq!(value.sa_data, [2, 88, 127, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2]);
1767+
}
1768+
}

0 commit comments

Comments
 (0)