]> git.sesse.net Git - greproxy/commitdiff
Move TUNProtocol into its own file.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 7 Feb 2015 00:15:19 +0000 (01:15 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 7 Feb 2015 00:15:19 +0000 (01:15 +0100)
tunprotocol.cpp [new file with mode: 0644]
tunprotocol.h [new file with mode: 0644]

diff --git a/tunprotocol.cpp b/tunprotocol.cpp
new file mode 100644 (file)
index 0000000..b8b63a3
--- /dev/null
@@ -0,0 +1,93 @@
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+
+#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 (file)
index 0000000..cfe3b46
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef _TUNPROTOCOL_H
+#define _TUNPROTOCOL_H 1
+
+#include "protocol.h"
+
+#include <stdint.h>
+#include <string>
+
+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)