@@ -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" ) ]
197198type SaFamily = sa_family_t ;
198199
200+ #[ derive( PartialEq ) ]
199201#[ binrw]
200202/// Socket address structure representing a network address.
201203pub 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+
208219impl 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
234245impl 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