2025-05-12 10:37:16 +08:00

65 lines
1.6 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Since the rust ioctl bindings don't have all the structures and constants,
* it's easier to just write the thing in C and link it in.
*/
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <sys/socket.h>
#ifdef __linux__
#include <linux/if.h>
#include <linux/if_tun.h>
#else
#include <net/if.h>
#define IFF_TUN 0x0001
#define IFF_TAP 0x0002
#define IFF_NO_PI 0x1000
#define TUNSETIFF _IOW('T', 202, int)
#endif
#include <sys/ioctl.h>
/**
* fd the fd to turn into TUN or TAP.
* name the name to use. If empty, kernel will assign something by itself.
* Must be buffer with capacity at least 33.
* mode 1 = TUN, 2 = TAP.
* packet_info if packet info should be provided, if the given value is 0 it will not prepend packet info.
*/
int tuntap_setup(int fd, unsigned char *name, int mode, int packet_info)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof ifr);
switch (mode)
{
case 1:
ifr.ifr_flags = IFF_TUN;
break;
case 2:
ifr.ifr_flags = IFF_TAP;
break;
default:
assert(0);
}
// If no packet info needs to be provided add corresponding flag
if (!packet_info)
{
ifr.ifr_flags |= IFF_NO_PI;
}
// Leave one for terminating '\0'. No idea if it is needed, didn't find
// it in the docs, but assuming the worst.
strncpy(ifr.ifr_name, (char *)name, IFNAMSIZ - 1);
int ioresult = ioctl(fd, TUNSETIFF, &ifr);
if (ioresult < 0)
{
return ioresult;
}
strncpy((char *)name, ifr.ifr_name, IFNAMSIZ < 32 ? IFNAMSIZ : 32);
name[32] = '\0';
return 0;
}