I want to call ioctl
from Rust. I know that I should use the nix crate, but how exactly? From the documentation it’s not clear.
I have this C:
int tun_open(char *devname) { struct ifreq ifr; int fd, err; if ( (fd = open("/dev/net/tun", O_RDWR)) == -1 ) { perror("open /dev/net/tun");exit(1); } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN; strncpy(ifr.ifr_name, devname, IFNAMSIZ); /* ioctl will use if_name as the name of TUN * interface to open: "tun0", etc. */ if ( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) == -1 ) { perror("ioctl TUNSETIFF");close(fd);exit(1); } //..........
How would I do that same thing using the nix crate? There are no TUN*
constants in the nix crate and it isn’t clear how to use the ioctl
macro.
Advertisement
Answer
There is some example usage in rust-spidev. I will try to apply that to your code.
TUNSETIFF
is defined as:
#define TUNSETIFF _IOW('T', 202, int)
That would be this in Rust using nix:
const TUN_IOC_MAGIC: u8 = 'T' as u8; const TUN_IOC_SET_IFF: u8 = 202; ioctl!(write tun_set_iff with TUN_IOC_MAGIC, TUN_IOC_SET_IFF; u32);
The above macro will define the function, which you can call like this:
let err = unsafe { tun_set_iff(fd, ifr) }; // assuming ifr is an u32