From 5b611332f020c9fc94b5992188dd0701fdf4f327 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sat, 7 Feb 2015 01:15:19 +0100 Subject: [PATCH] Move TUNProtocol into its own file. --- tunprotocol.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ tunprotocol.h | 20 +++++++++++ 2 files changed, 113 insertions(+) create mode 100644 tunprotocol.cpp create mode 100644 tunprotocol.h diff --git a/tunprotocol.cpp b/tunprotocol.cpp new file mode 100644 index 0000000..b8b63a3 --- /dev/null +++ b/tunprotocol.cpp @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tunprotocol.h" + +using namespace std; + +namespace { + +int tun_open(const char *name) { + struct ifreq ifr; + + int fd = open("/dev/net/tun", O_RDWR); + if (fd == -1) { + perror("/dev/net/tun"); + exit(1); + } + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TUN; + strncpy(ifr.ifr_name, name, IFNAMSIZ); + + int err = ioctl(fd, TUNSETIFF, &ifr); + if (err == -1) { + perror("ioctl(TUNSETIFF)"); + exit(-1); + } + + return fd; +} + +} // namespace + +TUNProtocol::TUNProtocol(const char *devname) + : tunfd(tun_open(devname)) { +} + +void TUNProtocol::send_packet(uint16_t proto, const string &data) +{ + char buf[4096]; + + char *ptr = buf; + uint16_t flags = 0; + memcpy(ptr, &flags, sizeof(flags)); + ptr += sizeof(flags); + + proto = htons(proto); + memcpy(ptr, &proto, sizeof(proto)); + ptr += sizeof(proto); + + memcpy(ptr, data.data(), data.size()); + + int len = sizeof(flags) + sizeof(proto) + data.size(); + if (write(tunfd, buf, len) != len) { + perror("write"); + return; + } +} + +int TUNProtocol::fd() const +{ + return tunfd; +} + +void TUNProtocol::read_packet(Protocol *sender) +{ + char buf[4096]; + int ret = read(tunfd, buf, sizeof(buf)); + if (ret == -1) { + perror("read"); + exit(1); + } + if (ret == 0) { + fprintf(stderr, "tunfd EOF\n"); + exit(1); + } + + char *ptr = buf; + uint16_t flags = *(uint16_t *)ptr; + ptr += 2; + uint16_t proto = ntohs(*(uint16_t *)ptr); + ptr += 2; + //fprintf(stderr, "tun packet: flags=%x proto=%x len=%d\n", + // flags, proto, ret - 4); + sender->send_packet(proto, string(ptr, buf + ret)); +} + diff --git a/tunprotocol.h b/tunprotocol.h new file mode 100644 index 0000000..cfe3b46 --- /dev/null +++ b/tunprotocol.h @@ -0,0 +1,20 @@ +#ifndef _TUNPROTOCOL_H +#define _TUNPROTOCOL_H 1 + +#include "protocol.h" + +#include +#include + +class TUNProtocol : public Protocol { +public: + TUNProtocol(const char *devname); + virtual void send_packet(uint16_t proto, const std::string &data); + virtual int fd() const; + void read_packet(Protocol* sender); + +private: + int tunfd; +}; + +#endif // !defined(_TUNPROTOCOL_H) -- 2.39.2