pub fn create(cfg: TunConfig) -> Result<Self, TunError> {
        let mut cfg = cfg;

        // ensure the device name is present (required on linux)
        let name = match cfg.name.take() {
            Some(name) => name,
            None => return Err(TunError::DeviceNameRequired),
        };

        // sanity check length of device name and check for interior nulls
        let name =
            CString::new(name.as_str()).map_err(|error| TunError::DeviceNameContainsNuls {
                pos: error.nul_position(),
            })?;

        let name_bytes = name.as_bytes();
        if name_bytes.len() > (libc::IFNAMSIZ - 1) {
            return Err(TunError::DeviceNameTooLong {
                len: name_bytes.len(),
                max: libc::IFNAMSIZ,
            });
        }

        // open clone device
        let fd: RawFd = match unsafe { libc::open(CLONE_DEVICE_PATH.as_ptr() as _, libc::O_RDWR) } {
            -1 => return Err(TunError::DeviceOpenFailed),
            x if x < -1 => unreachable!("unexcepted return value from open(): {}", x),
            fd => fd,
        };

        let mut flags = libc::IFF_TUN;
        if !cfg.packet_info {
            flags |= libc::IFF_NO_PI;
        }

        // construct request struct
        let mut req = IfReq {
            name: [0u8; libc::IFNAMSIZ],
            flags: flags as c_short,
            _pad: [0u8; 64],
        };

        // memcpy name into request structure
        req.name[..name_bytes.len()].copy_from_slice(name_bytes);

        // create TUN device
        if unsafe { libc::ioctl(fd, TUNSETIFF as _, &req) } < 0 {
            return Err(TunError::DeviceCreateFailed);
        }

        // fetch interface index
        let index = match unsafe { libc::if_nametoindex(name.as_ptr()) } {
            0 => return Err(TunError::DeviceNotFound),
            x if x >= (i32::MAX as u32) => {
                unreachable!("if_nametoindex returned negative value")
            }
            idx => idx as i32,
        };

        let mut tun = Self {
            fd,
            name,
            index,
            packet_info: cfg.packet_info,
        };
        tun.configure(cfg)?;
        Ok(tun)
    }
/// Creates a new TUN device
///
/// If a TUN device named `name` does not already exist, one will be created.
///
/// Creating a new TUN device requires root privileges or `CAP_NET_ADMIN` to be set on
/// the binary. To avoid requiring root privileges, a TUN device can be created using
/// the `iproute2` package.
///
/// To create a TUN device via `iproute` named `tun0` owned by user `fred`:
/// ```
/// sudo ip tuntap add dev tun0 mode tun user fred
/// ```
///
/// Any configuration (setting ips, etc.) will require root privileges or `CAP_NET_ADMIN`
/// set on the binary.
///
///
/// # Arguments
/// * `name` - Name of TUN device
/// * `cfg` - Tunnel device configuration
///
/// # Errors
/// * `name` contains interior null bytes (aka not a c string)
/// * `name` is too long (longer than `libc::IFNAMSIZ`)
/// * not run as root user or with CAP_NET_ADMIN capability set
/// * TUN device fails to create for other reasons
Creates a new TUN device
If a TUN device named `name` does not already exist, one will be created.

Creating a new TUN device requires root privileges or `CAP_NET_ADMIN` to be set on
the binary. To avoid requiring root privileges, a TUN device can be created using
the `iproute2` package.



Any configuration (setting ips, etc.) will require root privileges or `CAP_NET_ADMIN`
set on the binary.
Creates a new TUN device If a TUN device named ` name ` does not already exist one will be created . Creating a new TUN device requires root privileges or ` CAP_NET_ADMIN ` to be set on the binary . To avoid requiring root privileges a TUN device can be created using the ` iproute2 ` package . Any configuration ( setting ips etc . ) will require root privileges or ` CAP_NET_ADMIN ` set on the binary .
pub fn create(cfg: TunConfig) -> Result<Self, TunError> {
        let mut cfg = cfg;
        // ensure the device name is present (required on linux)
        let name = match cfg.name.take() {
            Some(name) => name,
            None => return Err(TunError::DeviceNameRequired),
        };
        // sanity check length of device name and check for interior nulls
        let name =
            CString::new(name.as_str()).map_err(|error| TunError::DeviceNameContainsNuls {
                pos: error.nul_position(),
            })?;
        let name_bytes = name.as_bytes();
        if name_bytes.len() > (libc::IFNAMSIZ - 1) {
            return Err(TunError::DeviceNameTooLong {
                len: name_bytes.len(),
                max: libc::IFNAMSIZ,
            });
        }
        // open clone device
        let fd: RawFd = match unsafe { libc::open(CLONE_DEVICE_PATH.as_ptr() as _, libc::O_RDWR) } {
            -1 => return Err(TunError::DeviceOpenFailed),
            x if x < -1 => unreachable!("unexcepted return value from open(): {}", x),
            fd => fd,
        };
        let mut flags = libc::IFF_TUN;
        if !cfg.packet_info {
            flags |= libc::IFF_NO_PI;
        }
        // construct request struct
        let mut req = IfReq {
            name: [0u8; libc::IFNAMSIZ],
            flags: flags as c_short,
            _pad: [0u8; 64],
        };
        // memcpy name into request structure
        req.name[..name_bytes.len()].copy_from_slice(name_bytes);
        // create TUN device
        if unsafe { libc::ioctl(fd, TUNSETIFF as _, &req) } < 0 {
            return Err(TunError::DeviceCreateFailed);
        }
        // fetch interface index
        let index = match unsafe { libc::if_nametoindex(name.as_ptr()) } {
            0 => return Err(TunError::DeviceNotFound),
            x if x >= (i32::MAX as u32) => {
                unreachable!("if_nametoindex returned negative value")
            }
            idx => idx as i32,
        };
        let mut tun = Self {
            fd,
            name,
            index,
            packet_info: cfg.packet_info,
        };
        tun.configure(cfg)?;
        Ok(tun)
    }
pub fn create ( cfg : TunConfig ) -> Result < Self , TunError > { let mut cfg = cfg ; // ensure the device name is present (required on linux) let name = match cfg . name . take ( ) { Some ( name ) => name , None => return Err ( TunError :: DeviceNameRequired ) , } ; // sanity check length of device name and check for interior nulls let name = CString :: new ( name . as_str ( ) ) . map_err ( | error | TunError :: DeviceNameContainsNuls { pos : error . nul_position ( ) , } ) ? ; let name_bytes = name . as_bytes ( ) ; if name_bytes . len ( ) > ( libc :: IFNAMSIZ - 1 ) { return Err ( TunError :: DeviceNameTooLong { len : name_bytes . len ( ) , max : libc :: IFNAMSIZ , } ) ; } // open clone device let fd : RawFd = match unsafe { libc :: open ( CLONE_DEVICE_PATH . as_ptr ( ) as _ , libc :: O_RDWR ) } { - 1 => return Err ( TunError :: DeviceOpenFailed ) , x if x < - 1 => unreachable ! ( " " x ) , fd => fd , } ; let mut flags = libc :: IFF_TUN ; if ! cfg . packet_info { flags |= libc :: IFF_NO_PI ; } // construct request struct let mut req = IfReq { name : [ 0u8 ; libc :: IFNAMSIZ ] , flags : flags as c_short , _pad : [ 0u8 ; 64 ] , } ; // memcpy name into request structure req . name [ .. name_bytes . len ( ) ] . copy_from_slice ( name_bytes ) ; // create TUN device if unsafe { libc :: ioctl ( fd , TUNSETIFF as _ , & req ) } < 0 { return Err ( TunError :: DeviceCreateFailed ) ; } // fetch interface index let index = match unsafe { libc :: if_nametoindex ( name . as_ptr ( ) ) } { 0 => return Err ( TunError :: DeviceNotFound ) , x if x >= ( i32 :: MAX as u32 ) => { unreachable ! ( " " ) } idx => idx as i32 , } ; let mut tun = Self { fd , name , index , packet_info : cfg . packet_info , } ; tun . configure ( cfg ) ? ; Ok ( tun ) }
Creates a new TUN device
If a TUN device named `name` does not already exist, one will be created.
Creates a new TUN device If a TUN device named ` name ` does not already exist one will be created .
cfg
TunConfig
cfg
TunConfig
errors
`name` contains interior null bytes (aka not a c string)
`name` is too long (longer than `libc::IFNAMSIZ`)
not run as root user or with CAP_NET_ADMIN capability set
TUN device fails to create for other reasons
` name ` contains interior null bytes ( aka not a c string ) ` name ` is too long ( longer than ` libc :: IFNAMSIZ ` ) not run as root user or with CAP_NET_ADMIN capability set TUN device fails to create for other reasons