Skip to content

Instantly share code, notes, and snippets.

@bave
Created February 25, 2019 13:42
Show Gist options
  • Save bave/8a9e3f50864338c3cb802d0fca110de2 to your computer and use it in GitHub Desktop.
Save bave/8a9e3f50864338c3cb802d0fca110de2 to your computer and use it in GitHub Desktop.
tapのサンプル
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <net/if.h>
/*
unsigned int if_nametoindex(const char *ifname);
char *if_indextoname(unsigned int ifindex, char *ifname);
*/
#include <linux/if.h>
#include <linux/if_tun.h>
#include <linux/if_arp.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sstream>
static int _tap_num = 0;
class tap
{
public:
tap()
{
_init();
};
virtual ~tap()
{
//close(_tap_fd);
};
void set_mac(uint8_t *mac)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifname.c_str(), ifname.size());
ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
memcpy(ifr.ifr_hwaddr.sa_data, mac, ETH_ALEN);
int ret;
ret = ioctl(_tap_fd, SIOCSIFHWADDR, (void*)&ifr);
if(ret == -1) {
perror("ioctl(SIOCSIFHWADDR)");
exit(EXIT_FAILURE);
}
return;
}
void set_mtu(uint32_t size)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifr.ifr_name, ifname.c_str(), ifname.size());
ifr.ifr_mtu = size;
int ret;
ret = ioctl(_tap_fd, SIOCSIFMTU, (void *)&ifr);
if(ret == -1) {
perror("ioctl(SIOCSIFHWADDR)");
exit(EXIT_FAILURE);
}
return;
}
void set_up()
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifr.ifr_name, ifname.c_str(), ifname.size());
ifr.ifr_flags = IFF_UP;
int ret;
ret = ioctl(_tap_fd, SIOCSIFFLAGS, (void*)&ifr);
if(ret == -1) {
perror("ioctl(SIOCSIFFLAGS)");
exit(EXIT_FAILURE);
}
return;
}
void set_down()
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifr.ifr_name, ifname.c_str(), ifname.size());
ifr.ifr_flags = 0;
int ret;
ret = ioctl(_tap_fd, SIOCSIFFLAGS, (void*)&ifr);
if(ret == -1) {
perror("ioctl(SIOCSIFFLAGS)");
exit(EXIT_FAILURE);
}
return;
}
private:
int _tap_fd;
std::string ifname;
const std::string base_name = "ethnic";
void _init()
{
ifname = base_name + str(_tap_num);
_tap_num++;
_tap_fd = open("/dev/net/tun", O_RDWR);
if (_tap_fd == -1) {
perror("open(/dev/net/tun)");
exit(EXIT_FAILURE);
}
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifname.c_str(), ifname.size());
ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
int ret;
ret = ioctl(_tap_fd, TUNSETIFF, (void*)&ifr);
if (ret == -1) {
close(_tap_fd);
perror("ioctl(TUNSETIFF)");
exit(EXIT_FAILURE);
}
return;
}
template <typename T> std::string str(const T& t) {
std::ostringstream os;
os << t;
return os.str();
}
};
int main()
{
class tap t;
for (;;) {
sleep(1);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment