@@ -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,12 @@ impl<'a> ControlMessage<'a> {
538
550
ControlMessage :: ScmTimestamp ( t) => {
539
551
mem:: size_of_val ( t)
540
552
} ,
553
+ ControlMessage :: Ipv4PacketInfo ( pktinfo) => {
554
+ mem:: size_of_val ( pktinfo)
555
+ } ,
556
+ ControlMessage :: Ipv6PacketInfo ( pktinfo) => {
557
+ mem:: size_of_val ( pktinfo)
558
+ } ,
541
559
ControlMessage :: Unknown ( UnknownCmsg ( _, bytes) ) => {
542
560
mem:: size_of_val ( bytes)
543
561
}
@@ -586,6 +604,46 @@ impl<'a> ControlMessage<'a> {
586
604
587
605
copy_bytes ( t, buf) ;
588
606
} ,
607
+ #[ cfg( any( target_os = "linux" , target_os = "android" , target_os = "macos" , target_os = "ios" ) ) ]
608
+ ControlMessage :: Ipv4PacketInfo ( pktinfo) => {
609
+ let cmsg = cmsghdr {
610
+ cmsg_len : self . len ( ) as _ ,
611
+ cmsg_level : libc:: IPPROTO_IP ,
612
+ cmsg_type : libc:: IP_PKTINFO ,
613
+ ..mem:: uninitialized ( )
614
+ } ;
615
+ copy_bytes ( & cmsg, buf) ;
616
+
617
+ let padlen = cmsg_align ( mem:: size_of_val ( & cmsg) ) -
618
+ mem:: size_of_val ( & cmsg) ;
619
+
620
+ let mut tmpbuf = & mut [ ] [ ..] ;
621
+ mem:: swap ( & mut tmpbuf, buf) ;
622
+ let ( _padding, mut remainder) = tmpbuf. split_at_mut ( padlen) ;
623
+ mem:: swap ( buf, & mut remainder) ;
624
+
625
+ copy_bytes ( pktinfo, buf) ;
626
+ } ,
627
+ #[ cfg( any( target_os = "linux" , target_os = "android" , target_os = "macos" , target_os = "ios" ) ) ]
628
+ ControlMessage :: Ipv6PacketInfo ( pktinfo) => {
629
+ let cmsg = cmsghdr {
630
+ cmsg_len : self . len ( ) as _ ,
631
+ cmsg_level : libc:: IPPROTO_IPV6 ,
632
+ cmsg_type : libc:: IPV6_PKTINFO ,
633
+ ..mem:: uninitialized ( )
634
+ } ;
635
+ copy_bytes ( & cmsg, buf) ;
636
+
637
+ let padlen = cmsg_align ( mem:: size_of_val ( & cmsg) ) -
638
+ mem:: size_of_val ( & cmsg) ;
639
+
640
+ let mut tmpbuf = & mut [ ] [ ..] ;
641
+ mem:: swap ( & mut tmpbuf, buf) ;
642
+ let ( _padding, mut remainder) = tmpbuf. split_at_mut ( padlen) ;
643
+ mem:: swap ( buf, & mut remainder) ;
644
+
645
+ copy_bytes ( pktinfo, buf) ;
646
+ } ,
589
647
ControlMessage :: Unknown ( UnknownCmsg ( orig_cmsg, bytes) ) => {
590
648
copy_bytes ( orig_cmsg, buf) ;
591
649
copy_bytes ( bytes, buf) ;
0 commit comments