blob: 4232908f835d606f436dd62af12282d27381b0cb [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![deny(warnings)]
use {
byteorder::{NativeEndian, WriteBytesExt},
failure::Error,
fdio::{fdio_sys, ioctl, make_ioctl},
fidl::encoding::Encoder,
fidl_fuchsia_wlan_tap as wlantap, fuchsia_async as fasync,
fuchsia_zircon::{self as zx, AsHandleRef},
std::{
fs::{File, OpenOptions},
mem,
os::raw,
path::Path,
},
};
pub struct Wlantap {
file: File,
}
impl Wlantap {
pub fn open() -> Result<Wlantap, Error> {
Ok(Wlantap {
file: OpenOptions::new()
.read(true)
.write(true)
.open(Path::new("/dev/test/wlantapctl"))?,
})
}
pub fn create_phy(
&self,
mut config: wlantap::WlantapPhyConfig,
) -> Result<wlantap::WlantapPhyProxy, Error> {
let (encoded_config, handles) = (&mut vec![], &mut vec![]);
Encoder::encode(encoded_config, handles, &mut config)?;
let (local, remote) = zx::Channel::create()?;
let mut ioctl_in = vec![];
ioctl_in.write_u32::<NativeEndian>(remote.raw_handle())?;
ioctl_in.append(encoded_config);
// Safe because the length of the buffer is computed from the length of a vector,
// and ioctl() doesn't retain the buffer.
unsafe {
ioctl(
&self.file,
IOCTL_WLANTAP_CREATE_WLANPHY,
ioctl_in.as_ptr() as *const std::os::raw::c_void,
ioctl_in.len(),
std::ptr::null_mut(),
0,
)?;
}
// Release ownership of the remote handle
mem::forget(remote);
Ok(wlantap::WlantapPhyProxy::new(fasync::Channel::from_channel(local)?))
}
}
const IOCTL_WLANTAP_CREATE_WLANPHY: raw::c_int =
make_ioctl!(fdio_sys::IOCTL_KIND_SET_HANDLE, fdio_sys::IOCTL_FAMILY_WLANTAP, 0);