Setup tun device
This commit is contained in:
parent
5c4b52acc6
commit
1f96a34a37
7 changed files with 138 additions and 0 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -88,3 +88,5 @@ docs/_build/
|
||||||
# PyBuilder
|
# PyBuilder
|
||||||
target/
|
target/
|
||||||
|
|
||||||
|
# ---> Local ignores
|
||||||
|
congestvpn
|
||||||
|
|
19
Makefile
Normal file
19
Makefile
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
CXX=g++
|
||||||
|
CXXFLAGS=-O2 -g -Wall -Wextra -std=c++17
|
||||||
|
CXXLIBS=
|
||||||
|
|
||||||
|
OBJS=TunDevice.o util.o main.o
|
||||||
|
TARGET=congestvpn
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(CXX) $(CXXFLAGS) $(CXXLIBS) -o $@ $^
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJS) $(TARGET)
|
||||||
|
|
||||||
|
.PHONY: all clean
|
46
TunDevice.cpp
Normal file
46
TunDevice.cpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#include <linux/if.h>
|
||||||
|
#include <linux/if_tun.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "TunDevice.hpp"
|
||||||
|
|
||||||
|
TunDevice::TunDevice(const std::string& dev)
|
||||||
|
{
|
||||||
|
struct ifreq ifr;
|
||||||
|
int fd, err;
|
||||||
|
|
||||||
|
if( (fd = open("/dev/net/tun", O_RDWR)) < 0 )
|
||||||
|
throw TunDevice::InitializationError("Cannot open /dev/net/tun", fd);
|
||||||
|
|
||||||
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
|
||||||
|
/* Flags: IFF_TUN - TUN device (no Ethernet headers)
|
||||||
|
* IFF_TAP - TAP device
|
||||||
|
*
|
||||||
|
* IFF_NO_PI - Do not provide packet information
|
||||||
|
*/
|
||||||
|
ifr.ifr_flags = IFF_TUN;
|
||||||
|
if(!dev.empty()) {
|
||||||
|
if(dev.size() >= IFNAMSIZ - 2)
|
||||||
|
throw TunDevice::InitializationError("Device name is too long.");
|
||||||
|
strncpy(ifr.ifr_name, dev.c_str(), IFNAMSIZ-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
|
||||||
|
close(fd);
|
||||||
|
throw TunDevice::InitializationError(
|
||||||
|
"Tunnel interface failed [TUNSETIFF]", err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_dev_name = ifr.ifr_name;
|
||||||
|
_fd = fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
TunDevice::~TunDevice() {
|
||||||
|
close(_fd);
|
||||||
|
}
|
22
TunDevice.hpp
Normal file
22
TunDevice.hpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "util.hpp"
|
||||||
|
|
||||||
|
class TunDevice {
|
||||||
|
public:
|
||||||
|
class InitializationError : public MsgException {
|
||||||
|
public:
|
||||||
|
InitializationError(const std::string& msg, int code=0)
|
||||||
|
: MsgException(msg, code) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
TunDevice(const std::string& dev);
|
||||||
|
~TunDevice();
|
||||||
|
|
||||||
|
const std::string& get_dev_name() const { return _dev_name; }
|
||||||
|
int get_fd() const { return _fd; }
|
||||||
|
private:
|
||||||
|
int _fd;
|
||||||
|
std::string _dev_name;
|
||||||
|
};
|
17
main.cpp
Normal file
17
main.cpp
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#include <cstdio>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "TunDevice.hpp"
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
try {
|
||||||
|
TunDevice tun_dev("cvpn%d");
|
||||||
|
printf("Tunnel device opened: <%s>, fd <%d>.\nSleeping 10 seconds.\n",
|
||||||
|
tun_dev.get_dev_name().c_str(), tun_dev.get_fd());
|
||||||
|
sleep(10);
|
||||||
|
printf("Shutting down.\n");
|
||||||
|
} catch(const TunDevice::InitializationError& exn) {
|
||||||
|
fprintf(stderr, "ERROR: %s\n", exn.what());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
15
util.cpp
Normal file
15
util.cpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include "util.hpp"
|
||||||
|
|
||||||
|
MsgException::MsgException(const std::string& msg, int code)
|
||||||
|
: _msg(msg), _code(code)
|
||||||
|
{
|
||||||
|
_what = _msg;
|
||||||
|
|
||||||
|
if(_code != 0) {
|
||||||
|
char remainder[20];
|
||||||
|
sprintf(remainder, " (code %d)", _code);
|
||||||
|
_what += remainder;
|
||||||
|
}
|
||||||
|
}
|
17
util.hpp
Normal file
17
util.hpp
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// MsgException -- an exception bearing a passed explanation message
|
||||||
|
class MsgException : public std::exception {
|
||||||
|
public:
|
||||||
|
MsgException(const std::string& msg, int code=0);
|
||||||
|
int errcode() const noexcept { return _code; }
|
||||||
|
const char* what() const noexcept { return _what.c_str(); };
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string _msg;
|
||||||
|
int _code;
|
||||||
|
std::string _what;
|
||||||
|
};
|
Loading…
Reference in a new issue