@@ -414,6 +414,14 @@ impl<'a> Iterator for CmsgIterator<'a> {
414
414
Some ( ControlMessage :: ScmTimestamp (
415
415
& * ( cmsg_data. as_ptr ( ) as * const _ ) ) )
416
416
} ,
417
+ #[ cfg( any( target_os = "linux" , target_os = "android" , target_os = "macos" , target_os = "ios" ) ) ]
418
+ ( libc:: IPPROTO_IPV6 , libc:: IPV6_PKTINFO ) => unsafe {
419
+ Some ( ControlMessage :: Ipv6PacketInfo ( & * ( cmsg_data. as_ptr ( ) as * const _ ) ) )
420
+ } ,
421
+ #[ cfg( any( target_os = "linux" , target_os = "android" , target_os = "macos" , target_os = "ios" ) ) ]
422
+ ( libc:: IPPROTO_IP , libc:: IP_PKTINFO ) => unsafe {
423
+ Some ( ControlMessage :: Ipv4PacketInfo ( & * ( cmsg_data. as_ptr ( ) as * const _ ) ) )
424
+ } ,
417
425
( _, _) => unsafe {
418
426
Some ( ControlMessage :: Unknown ( UnknownCmsg (
419
427
cmsg,
@@ -504,6 +512,10 @@ pub enum ControlMessage<'a> {
504
512
/// nix::unistd::close(in_socket).unwrap();
505
513
/// ```
506
514
ScmTimestamp ( & ' a TimeVal ) ,
515
+ #[ cfg( any( target_os = "linux" , target_os = "android" , target_os = "macos" , target_os = "ios" ) ) ]
516
+ Ipv4PacketInfo ( & ' a libc:: in_pktinfo ) ,
517
+ #[ cfg( any( target_os = "linux" , target_os = "android" , target_os = "macos" , target_os = "ios" ) ) ]
518
+ Ipv6PacketInfo ( & ' a libc:: in6_pktinfo ) ,
507
519
#[ doc( hidden) ]
508
520
Unknown ( UnknownCmsg < ' a > ) ,
509
521
}
@@ -538,6 +550,14 @@ impl<'a> ControlMessage<'a> {
538
550
ControlMessage :: ScmTimestamp ( t) => {
539
551
mem:: size_of_val ( t)
540
552
} ,
553
+ #[ cfg( any( target_os = "linux" , target_os = "android" , target_os = "macos" , target_os = "ios" ) ) ]
554
+ ControlMessage :: Ipv4PacketInfo ( pktinfo) => {
555
+ mem:: size_of_val ( pktinfo)
556
+ } ,
557
+ #[ cfg( any( target_os = "linux" , target_os = "android" , target_os = "macos" , target_os = "ios" ) ) ]
558
+ ControlMessage :: Ipv6PacketInfo ( pktinfo) => {
559
+ mem:: size_of_val ( pktinfo)
560
+ } ,
541
561
ControlMessage :: Unknown ( UnknownCmsg ( _, bytes) ) => {
542
562
mem:: size_of_val ( bytes)
543
563
}
@@ -586,6 +606,46 @@ impl<'a> ControlMessage<'a> {
586
606
587
607
copy_bytes ( t, buf) ;
588
608
} ,
609
+ #[ cfg( any( target_os = "linux" , target_os = "android" , target_os = "macos" , target_os = "ios" ) ) ]
610
+ ControlMessage :: Ipv4PacketInfo ( pktinfo) => {
611
+ let cmsg = cmsghdr {
612
+ cmsg_len : self . len ( ) as _ ,
613
+ cmsg_level : libc:: IPPROTO_IP ,
614
+ cmsg_type : libc:: IP_PKTINFO ,
615
+ ..mem:: uninitialized ( )
616
+ } ;
617
+ copy_bytes ( & cmsg, buf) ;
618
+
619
+ let padlen = cmsg_align ( mem:: size_of_val ( & cmsg) ) -
620
+ mem:: size_of_val ( & cmsg) ;
621
+
622
+ let mut tmpbuf = & mut [ ] [ ..] ;
623
+ mem:: swap ( & mut tmpbuf, buf) ;
624
+ let ( _padding, mut remainder) = tmpbuf. split_at_mut ( padlen) ;
625
+ mem:: swap ( buf, & mut remainder) ;
626
+
627
+ copy_bytes ( pktinfo, buf) ;
628
+ } ,
629
+ #[ cfg( any( target_os = "linux" , target_os = "android" , target_os = "macos" , target_os = "ios" ) ) ]
630
+ ControlMessage :: Ipv6PacketInfo ( pktinfo) => {
631
+ let cmsg = cmsghdr {
632
+ cmsg_len : self . len ( ) as _ ,
633
+ cmsg_level : libc:: IPPROTO_IPV6 ,
634
+ cmsg_type : libc:: IPV6_PKTINFO ,
635
+ ..mem:: uninitialized ( )
636
+ } ;
637
+ copy_bytes ( & cmsg, buf) ;
638
+
639
+ let padlen = cmsg_align ( mem:: size_of_val ( & cmsg) ) -
640
+ mem:: size_of_val ( & cmsg) ;
641
+
642
+ let mut tmpbuf = & mut [ ] [ ..] ;
643
+ mem:: swap ( & mut tmpbuf, buf) ;
644
+ let ( _padding, mut remainder) = tmpbuf. split_at_mut ( padlen) ;
645
+ mem:: swap ( buf, & mut remainder) ;
646
+
647
+ copy_bytes ( pktinfo, buf) ;
648
+ } ,
589
649
ControlMessage :: Unknown ( UnknownCmsg ( orig_cmsg, bytes) ) => {
590
650
copy_bytes ( orig_cmsg, buf) ;
591
651
copy_bytes ( bytes, buf) ;
0 commit comments