From 42504a97694173e4686aab210e77cbd4a758ab13 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sat, 7 Feb 2015 00:57:52 +0100 Subject: [PATCH] Move more stuff into the classes. Not fully orthogonal yet. --- tungre.cpp | 105 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 43 deletions(-) diff --git a/tungre.cpp b/tungre.cpp index 82bfa34..9b93e85 100644 --- a/tungre.cpp +++ b/tungre.cpp @@ -69,15 +69,21 @@ struct GREPacket { } }; -class Sender { +class Protocol { public: virtual void send_packet(uint16_t proto, const string &data) = 0; + virtual int fd() const = 0; }; -class GRESender : public Sender { +class Reorderer; +class Protocol; + +class GREProtocol : public Protocol { public: - GRESender(int sock, const in6_addr &dst); + GREProtocol(const in6_addr &myaddr, const in6_addr &dst); virtual void send_packet(uint16_t proto, const string &data); + virtual int fd() const; + void read_packet(Reorderer* sender); private: int seq; @@ -85,10 +91,12 @@ private: sockaddr_in6 dstaddr; }; -class TUNSender : public Sender { +class TUNProtocol : public Protocol { public: - TUNSender(int tunfd); + TUNProtocol(const char *devname); virtual void send_packet(uint16_t proto, const string &data); + virtual int fd() const; + void read_packet(Protocol* sender); private: int tunfd; @@ -96,28 +104,43 @@ private: class Reorderer { public: - Reorderer(Sender* sender); + Reorderer(Protocol* sender); void handle_packet(uint16_t proto, const string& data, int seq); private: void send_packet(uint16_t proto, const string &data, bool silence); - Sender* sender; + Protocol* sender; int last_seq; priority_queue, greater> packet_buffer; map ccs; }; -GRESender::GRESender(int sock, const in6_addr &dst) - : sock(sock), seq(0) +GREProtocol::GREProtocol(const in6_addr &src, const in6_addr &dst) + : seq(0) { memset(&dstaddr, 0, sizeof(dstaddr)); dstaddr.sin6_family = AF_INET6; dstaddr.sin6_addr = dst; + + sock = socket(AF_INET6, SOCK_RAW, IPPROTO_GRE); + if (sock == -1) { + perror("socket"); + exit(1); + } + + sockaddr_in6 my_addr; + memset(&my_addr, 0, sizeof(my_addr)); + my_addr.sin6_family = AF_INET6; + my_addr.sin6_addr = src; + if (bind(sock, (sockaddr *)&my_addr, sizeof(my_addr)) == -1) { + perror("bind"); + exit(1); + } } -void GRESender::send_packet(uint16_t proto, const string &data) +void GREProtocol::send_packet(uint16_t proto, const string &data) { char buf[4096]; gre_header *gre = (gre_header *)buf; @@ -139,11 +162,17 @@ void GRESender::send_packet(uint16_t proto, const string &data) return; } } + +int GREProtocol::fd() const +{ + return sock; +} -TUNSender::TUNSender(int tunfd) - : tunfd(tunfd) {} +TUNProtocol::TUNProtocol(const char *devname) + : tunfd(tun_open(devname)) { +} -void TUNSender::send_packet(uint16_t proto, const string &data) +void TUNProtocol::send_packet(uint16_t proto, const string &data) { char buf[4096]; @@ -165,7 +194,12 @@ void TUNSender::send_packet(uint16_t proto, const string &data) } } -Reorderer::Reorderer(Sender* sender) +int TUNProtocol::fd() const +{ + return tunfd; +} + +Reorderer::Reorderer(Protocol* sender) : sender(sender), last_seq(-1) { } @@ -237,12 +271,12 @@ void Reorderer::send_packet(uint16_t proto, const string &data, bool silence) sender->send_packet(proto, data); } -void read_gre_packet(int gresock, const in6_addr &remoteaddr, Reorderer *sender) +void GREProtocol::read_packet(Reorderer *sender) { struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); char buf[4096]; - int ret = recvfrom(gresock, buf, sizeof(buf), 0, (struct sockaddr *)&addr, &addrlen); + int ret = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&addr, &addrlen); if (ret == -1) { perror("recvfrom"); exit(1); @@ -251,7 +285,7 @@ void read_gre_packet(int gresock, const in6_addr &remoteaddr, Reorderer *sender) return; } struct in6_addr *addr6 = &((struct sockaddr_in6 *)&addr)->sin6_addr; - if (memcmp(addr6, &remoteaddr, sizeof(*addr6)) != 0) { + if (memcmp(addr6, &dstaddr.sin6_addr, sizeof(*addr6)) != 0) { // ignore return; } @@ -275,7 +309,7 @@ void read_gre_packet(int gresock, const in6_addr &remoteaddr, Reorderer *sender) sender->handle_packet(ntohs(gre->protocol_type), string(ptr, buf + ret), seq); } -void read_tun_packet(int tunfd, Sender *sender) +void TUNProtocol::read_packet(Protocol *sender) { char buf[4096]; int ret = read(tunfd, buf, sizeof(buf)); @@ -300,44 +334,29 @@ void read_tun_packet(int tunfd, Sender *sender) int main(int argc, char **argv) { - int tunfd = tun_open("tungre"); - int gresock = socket(AF_INET6, SOCK_RAW, IPPROTO_GRE); - if (gresock == -1) { - perror("socket"); - exit(1); - } - - sockaddr_in6 my_addr; - memset(&my_addr, 0, sizeof(my_addr)); - my_addr.sin6_family = AF_INET6; - my_addr.sin6_addr = get_addr(argv[1]); - if (bind(gresock, (sockaddr *)&my_addr, sizeof(my_addr)) == -1) { - perror("bind"); - exit(1); - } - + in6_addr myaddr = get_addr(argv[1]); in6_addr remoteaddr = get_addr(argv[2]); - GRESender gre_sender(gresock, remoteaddr); - TUNSender tun_sender(tunfd); + GREProtocol gre(myaddr, remoteaddr); + TUNProtocol tun("tungre"); - Reorderer tun_reorderer(&tun_sender); + Reorderer tun_reorderer(&tun); fd_set fds; FD_ZERO(&fds); for ( ;; ) { - FD_SET(gresock, &fds); - FD_SET(tunfd, &fds); + FD_SET(gre.fd(), &fds); + FD_SET(tun.fd(), &fds); int ret = select(1024, &fds, NULL, NULL, NULL); if (ret == -1) { perror("select"); continue; } - if (FD_ISSET(gresock, &fds)) { - read_gre_packet(gresock, remoteaddr, &tun_reorderer); + if (FD_ISSET(gre.fd(), &fds)) { + gre.read_packet(&tun_reorderer); } - if (FD_ISSET(tunfd, &fds)) { - read_tun_packet(tunfd, &gre_sender); + if (FD_ISSET(tun.fd(), &fds)) { + tun.read_packet(&gre); } } } -- 2.39.2