@@ -508,7 +508,7 @@ impl PfCtl {
508508 ) -> Result < ( ) > {
509509 let mut iface = unsafe { mem:: zeroed :: < ffi:: pfvar:: pfioc_iface > ( ) } ;
510510 interface. try_copy_to ( & mut iface. pfiio_name ) ?;
511- iface. pfiio_flags = flags as i32 ;
511+ iface. pfiio_flags = flags. bits ( ) ;
512512 ioctl_guard ! ( ffi:: pf_set_iface_flag( self . fd( ) , & mut iface) ) ?;
513513 Ok ( ( ) )
514514 }
@@ -523,11 +523,51 @@ impl PfCtl {
523523 ) -> Result < ( ) > {
524524 let mut iface = unsafe { mem:: zeroed :: < ffi:: pfvar:: pfioc_iface > ( ) } ;
525525 interface. try_copy_to ( & mut iface. pfiio_name ) ?;
526- iface. pfiio_flags = flags as i32 ;
526+ iface. pfiio_flags = flags. bits ( ) ;
527527 ioctl_guard ! ( ffi:: pf_clear_iface_flag( self . fd( ) , & mut iface) ) ?;
528528 Ok ( ( ) )
529529 }
530530
531+ /// Get interfaces with corresponding flags.
532+ ///
533+ /// https://man.freebsd.org/cgi/man.cgi?pf(4)
534+ pub fn get_interface_flags (
535+ & mut self ,
536+ interface : Interface ,
537+ ) -> Result < Vec < InterfaceDescription > > {
538+ // This should be sufficient capacity on average machine to avoid reallocation
539+ const INITIAL_CAPACITY : usize = 30 ;
540+
541+ let mut buf: Vec < ffi:: pfvar:: pfi_kif > = Vec :: with_capacity ( INITIAL_CAPACITY ) ;
542+ let mut iface = unsafe { mem:: zeroed :: < ffi:: pfvar:: pfioc_iface > ( ) } ;
543+ interface. try_copy_to ( & mut iface. pfiio_name ) ?;
544+ iface. pfiio_esize = mem:: size_of :: < ffi:: pfvar:: pfi_kif > ( ) as i32 ;
545+
546+ let mut num_system_interfaces = 0 ;
547+ for _ in 0 ..2 {
548+ iface. pfiio_buffer = buf. as_mut_ptr ( ) as _ ;
549+ iface. pfiio_size = buf. capacity ( ) as _ ;
550+
551+ ioctl_guard ! ( ffi:: pf_get_ifaces( self . fd( ) , & mut iface) ) ?;
552+ num_system_interfaces = usize:: try_from ( iface. pfiio_size ) . unwrap_or_default ( ) ;
553+
554+ // Reserve additional space and retry if number of system interfaces exceeds capacity
555+ if num_system_interfaces > buf. capacity ( ) {
556+ buf. reserve ( num_system_interfaces) ;
557+ } else {
558+ break ;
559+ }
560+ }
561+
562+ let new_len = std:: cmp:: min ( num_system_interfaces, buf. capacity ( ) ) ;
563+ // SAFETY: safe since new_len is capped at capacity
564+ unsafe { buf. set_len ( new_len) } ;
565+
566+ buf. into_iter ( )
567+ . map ( InterfaceDescription :: try_from)
568+ . collect ( )
569+ }
570+
531571 /// Get all states created by stateful rules
532572 fn get_states_inner ( & mut self ) -> Result < Vec < ffi:: pfvar:: pfsync_state > > {
533573 let num_states = self . get_num_states ( ) ?;
0 commit comments