pub fn configure(&mut self, cfg: TunConfig) -> Result<(), TunError> {
        if let Some((ip, mask)) = cfg.ip {
            // ioctl SIOCAIFADDR
            match ip {
                IpAddr::V4(ip) => {
                    let ip: u32 = ip.into();

                    let mask: u32 = match mask {
                        32 => u32::MAX,
                        x if x < 32 => u32::MAX - (2_u32.pow((32 - x).into())) + 1,
                        x => return Err(TunError::Ipv4InvalidCidr { cidr: x }),
                    };

                    let broadcast = !mask | ip;

                    let req = IfAliasReq {
                        ifra_name: self.name.clone(),
                        ifra_addr: libc::sockaddr_in {
                            sin_len: mem::size_of::<libc::sockaddr_in>() as u8,
                            sin_family: libc::AF_INET as u8,
                            sin_port: 0,
                            sin_addr: libc::in_addr { s_addr: ip.to_be() },
                            sin_zero: [0; 8],
                        },
                        ifra_broadaddr: libc::sockaddr_in {
                            sin_len: mem::size_of::<libc::sockaddr_in>() as u8,
                            sin_family: libc::AF_INET as u8,
                            sin_port: 0,
                            sin_addr: libc::in_addr {
                                s_addr: broadcast.to_be(),
                            },
                            sin_zero: [0; 8],
                        },
                        ifra_mask: libc::sockaddr_in {
                            sin_len: mem::size_of::<libc::sockaddr_in>() as u8,
                            sin_family: libc::AF_INET as u8,
                            sin_port: 0,
                            sin_addr: libc::in_addr {
                                s_addr: mask.to_be(),
                            },
                            sin_zero: [0; 8],
                        },
                        ifra_vhid: 0,
                    };

                    tracing::trace!("ifreqalias: {:?}", req);

                    // SAFETY: ioctl has been verified using truss to be correct
                    let res = unsafe {
                        libc::ioctl(self.sock_fd, SIOCAIFADDR, &req as *const IfAliasReq)
                    };
                    if res == -1 {
                        tracing::error!("errno: {}", nix::errno::Errno::last());
                    }
                }

                IpAddr::V6(_) => {
                    unimplemented!()
                }
            }
        }

        if cfg.packet_info {
            // SAFETY:
            if unsafe { libc::ioctl(self.fd, TUNSIFHEAD, &1) } == -1 {
                tracing::warn!(
                    "failed to set multi-af mode (packet_info): {}",
                    nix::errno::Errno::last()
                );
            }
        }

        Ok(())
    }
/// Applies the tunnel config settings to this TUN device
///
/// # Arguments
/// * `cfg` - Tunnel Configuration Options
///
/// # Errors
/// * UDP config socket fails to open
/// * An invalid CIDR is passed with the IP
/// * Fails to set the IP address
Applies the tunnel config settings to this TUN device
Applies the tunnel config settings to this TUN device
pub fn configure(&mut self, cfg: TunConfig) -> Result<(), TunError> {
        if let Some((ip, mask)) = cfg.ip {
            // ioctl SIOCAIFADDR
            match ip {
                IpAddr::V4(ip) => {
                    let ip: u32 = ip.into();
                    let mask: u32 = match mask {
                        32 => u32::MAX,
                        x if x < 32 => u32::MAX - (2_u32.pow((32 - x).into())) + 1,
                        x => return Err(TunError::Ipv4InvalidCidr { cidr: x }),
                    };
                    let broadcast = !mask | ip;
                    let req = IfAliasReq {
                        ifra_name: self.name.clone(),
                        ifra_addr: libc::sockaddr_in {
                            sin_len: mem::size_of::<libc::sockaddr_in>() as u8,
                            sin_family: libc::AF_INET as u8,
                            sin_port: 0,
                            sin_addr: libc::in_addr { s_addr: ip.to_be() },
                            sin_zero: [0; 8],
                        },
                        ifra_broadaddr: libc::sockaddr_in {
                            sin_len: mem::size_of::<libc::sockaddr_in>() as u8,
                            sin_family: libc::AF_INET as u8,
                            sin_port: 0,
                            sin_addr: libc::in_addr {
                                s_addr: broadcast.to_be(),
                            },
                            sin_zero: [0; 8],
                        },
                        ifra_mask: libc::sockaddr_in {
                            sin_len: mem::size_of::<libc::sockaddr_in>() as u8,
                            sin_family: libc::AF_INET as u8,
                            sin_port: 0,
                            sin_addr: libc::in_addr {
                                s_addr: mask.to_be(),
                            },
                            sin_zero: [0; 8],
                        },
                        ifra_vhid: 0,
                    };
                    tracing::trace!("ifreqalias: {:?}", req);
                    // SAFETY: ioctl has been verified using truss to be correct
                    let res = unsafe {
                        libc::ioctl(self.sock_fd, SIOCAIFADDR, &req as *const IfAliasReq)
                    };
                    if res == -1 {
                        tracing::error!("errno: {}", nix::errno::Errno::last());
                    }
                }
                IpAddr::V6(_) => {
                    unimplemented!()
                }
            }
        }
        if cfg.packet_info {
            // SAFETY:
            if unsafe { libc::ioctl(self.fd, TUNSIFHEAD, &1) } == -1 {
                tracing::warn!(
                    "failed to set multi-af mode (packet_info): {}",
                    nix::errno::Errno::last()
                );
            }
        }
        Ok(())
    }
pub fn configure ( & mut self , cfg : TunConfig ) -> Result < ( ) , TunError > { if let Some ( ( ip , mask ) ) = cfg . ip { // ioctl SIOCAIFADDR match ip { IpAddr :: V4 ( ip ) => { let ip : u32 = ip . into ( ) ; let mask : u32 = match mask { 32 => u32 :: MAX , x if x < 32 => u32 :: MAX - ( 2_u32 . pow ( ( 32 - x ) . into ( ) ) ) + 1 , x => return Err ( TunError :: Ipv4InvalidCidr { cidr : x } ) , } ; let broadcast = ! mask | ip ; let req = IfAliasReq { ifra_name : self . name . clone ( ) , ifra_addr : libc :: sockaddr_in { sin_len : mem :: size_of :: < libc :: sockaddr_in > ( ) as u8 , sin_family : libc :: AF_INET as u8 , sin_port : 0 , sin_addr : libc :: in_addr { s_addr : ip . to_be ( ) } , sin_zero : [ 0 ; 8 ] , } , ifra_broadaddr : libc :: sockaddr_in { sin_len : mem :: size_of :: < libc :: sockaddr_in > ( ) as u8 , sin_family : libc :: AF_INET as u8 , sin_port : 0 , sin_addr : libc :: in_addr { s_addr : broadcast . to_be ( ) , } , sin_zero : [ 0 ; 8 ] , } , ifra_mask : libc :: sockaddr_in { sin_len : mem :: size_of :: < libc :: sockaddr_in > ( ) as u8 , sin_family : libc :: AF_INET as u8 , sin_port : 0 , sin_addr : libc :: in_addr { s_addr : mask . to_be ( ) , } , sin_zero : [ 0 ; 8 ] , } , ifra_vhid : 0 , } ; tracing :: trace ! ( " " req ) ; // SAFETY: ioctl has been verified using truss to be correct let res = unsafe { libc :: ioctl ( self . sock_fd , SIOCAIFADDR , & req as * const IfAliasReq ) } ; if res == - 1 { tracing :: error ! ( " " nix errno Errno last ( ) ) ; } } IpAddr :: V6 ( _ ) => { unimplemented ! ( ) } } } if cfg . packet_info { // SAFETY: if unsafe { libc :: ioctl ( self . fd , TUNSIFHEAD , & 1 ) } == - 1 { tracing :: warn ! ( " " nix errno Errno last ( ) ) ; } } Ok ( ( ) ) }
Applies the tunnel config settings to this TUN device
Applies the tunnel config settings to this TUN device
&mut self
cfg
TunConfig
&mut self
cfg
TunConfig
errors
UDP config socket fails to open
An invalid CIDR is passed with the IP
Fails to set the IP address
UDP config socket fails to open An invalid CIDR is passed with the IP Fails to set the IP address