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
|
||||
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