@@ -2,7 +2,7 @@ use std::{
2
2
io,
3
3
io:: IoSliceMut ,
4
4
mem:: { self , MaybeUninit } ,
5
- net:: { IpAddr , SocketAddr } ,
5
+ net:: { IpAddr , Ipv4Addr , Ipv6Addr , SocketAddr , SocketAddrV4 , SocketAddrV6 } ,
6
6
os:: unix:: io:: AsRawFd ,
7
7
ptr,
8
8
sync:: atomic:: AtomicUsize ,
@@ -498,14 +498,16 @@ fn decode_recv(
498
498
ecn_bits = cmsg:: decode :: < libc:: c_int > ( cmsg) as u8 ;
499
499
}
500
500
} ,
501
- ( libc:: IPPROTO_IP , libc:: IP_PKTINFO ) => unsafe {
502
- let pktinfo = cmsg:: decode :: < libc:: in_pktinfo > ( cmsg) ;
503
- dst_ip = Some ( IpAddr :: V4 ( ptr:: read ( & pktinfo. ipi_addr as * const _ as _ ) ) ) ;
504
- } ,
505
- ( libc:: IPPROTO_IPV6 , libc:: IPV6_PKTINFO ) => unsafe {
506
- let pktinfo = cmsg:: decode :: < libc:: in6_pktinfo > ( cmsg) ;
507
- dst_ip = Some ( IpAddr :: V6 ( ptr:: read ( & pktinfo. ipi6_addr as * const _ as _ ) ) ) ;
508
- } ,
501
+ ( libc:: IPPROTO_IP , libc:: IP_PKTINFO ) => {
502
+ let pktinfo = unsafe { cmsg:: decode :: < libc:: in_pktinfo > ( cmsg) } ;
503
+ dst_ip = Some ( IpAddr :: V4 ( Ipv4Addr :: from (
504
+ pktinfo. ipi_addr . s_addr . to_ne_bytes ( ) ,
505
+ ) ) ) ;
506
+ }
507
+ ( libc:: IPPROTO_IPV6 , libc:: IPV6_PKTINFO ) => {
508
+ let pktinfo = unsafe { cmsg:: decode :: < libc:: in6_pktinfo > ( cmsg) } ;
509
+ dst_ip = Some ( IpAddr :: V6 ( Ipv6Addr :: from ( pktinfo. ipi6_addr . s6_addr ) ) ) ;
510
+ }
509
511
#[ cfg( target_os = "linux" ) ]
510
512
( libc:: SOL_UDP , libc:: UDP_GRO ) => unsafe {
511
513
stride = cmsg:: decode :: < libc:: c_int > ( cmsg) as usize ;
@@ -515,8 +517,26 @@ fn decode_recv(
515
517
}
516
518
517
519
let addr = match libc:: c_int:: from ( name. ss_family ) {
518
- libc:: AF_INET => unsafe { SocketAddr :: V4 ( ptr:: read ( & name as * const _ as _ ) ) } ,
519
- libc:: AF_INET6 => unsafe { SocketAddr :: V6 ( ptr:: read ( & name as * const _ as _ ) ) } ,
520
+ libc:: AF_INET => {
521
+ // Safety: if the ss_family field is AF_INET then storage must be a sockaddr_in.
522
+ let addr: & libc:: sockaddr_in =
523
+ unsafe { & * ( & name as * const _ as * const libc:: sockaddr_in ) } ;
524
+ SocketAddr :: V4 ( SocketAddrV4 :: new (
525
+ Ipv4Addr :: from ( addr. sin_addr . s_addr . to_ne_bytes ( ) ) ,
526
+ u16:: from_be ( addr. sin_port ) ,
527
+ ) )
528
+ }
529
+ libc:: AF_INET6 => {
530
+ // Safety: if the ss_family field is AF_INET6 then storage must be a sockaddr_in6.
531
+ let addr: & libc:: sockaddr_in6 =
532
+ unsafe { & * ( & name as * const _ as * const libc:: sockaddr_in6 ) } ;
533
+ SocketAddr :: V6 ( SocketAddrV6 :: new (
534
+ Ipv6Addr :: from ( addr. sin6_addr . s6_addr ) ,
535
+ u16:: from_be ( addr. sin6_port ) ,
536
+ addr. sin6_flowinfo ,
537
+ addr. sin6_scope_id ,
538
+ ) )
539
+ }
520
540
_ => unreachable ! ( ) ,
521
541
} ;
522
542
0 commit comments