Libraryize test.cc

This commit is contained in:
Ian Gulliver
2016-09-25 17:37:37 -07:00
parent c067cbd71e
commit f31ccaad16
10 changed files with 100 additions and 102 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
bazel-*
*.swp

6
BUILD
View File

@@ -1,6 +0,0 @@
cc_binary(
name = "test",
srcs = [
"test.cc",
],
)

View File

@@ -55,6 +55,7 @@ toolchain {
compiler_flag: "-fPIE"
linker_flag: "-Wl,-z,relro,-z,now"
linker_flag: "-pie"
linker_flag: "-lstdc++"
compilation_mode_flags {
mode: OPT

5
format.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/sh
exec find $(dirname $0) \
-name '*.cc' -o -name '*.h' \
-exec clang-format-3.8 -i --style=google '{}' ';'

View File

@@ -1,3 +1,5 @@
package(default_visibility = ["//visibility:public"])
cc_library(
name = "tun_tap_device_lib",
hdrs = [

View File

@@ -1 +1,41 @@
#include "lib/tun_tap_device.h"
#include <sys/socket.h>
#include <linux/if.h>
#include <glog/logging.h>
#include <sys/ioctl.h>
#include <unistd.h>
namespace funstraw {
namespace {
const std::string kCloneDevice = "/dev/net/tun";
}
TunTapDevice::TunTapDevice(const std::string& name, uint64_t if_flags, uint64_t fd_flags) {
auto fd_ = open(kCloneDevice.c_str(), fd_flags);
CHECK_NE(fd_, -1) << strerror(errno);
struct ifreq ifr = {0};
ifr.ifr_flags = if_flags;
if (!name.empty()) {
CHECK_LT(name.length(), IFNAMSIZ);
strcpy(ifr.ifr_name, name.c_str());
}
CHECK_EQ(ioctl(fd_, TUNSETIFF, &ifr), 0) << strerror(errno);
name_ = ifr.ifr_name;
}
TunTapDevice::~TunTapDevice() {
CHECK_EQ(close(fd_), 0);
}
size_t TunTapDevice::Read(char* buf) {
auto bytes = read(fd_, buf, 2048);
CHECK_NE(bytes, -1) << strerror(errno);
return bytes;
}
} // namespace funstraw

View File

@@ -1,21 +1,33 @@
#include <string>
#include <fcntl.h>
#include <linux/if_tun.h>
#include <sys/stat.h>
#include <sys/types.h>
class TapTunDevice {
namespace funstraw {
class TunTapDevice {
public:
static const auto kTunFormat = IFF_TUN;
static const auto kTapFormat = IFF_TAP;
static const auto kNoPacketInfo = IFF_NO_PI;
static const auto kIfFormatTun = IFF_TUN;
static const auto kIfFormatTap = IFF_TAP;
static const auto kIfNoPacketInfo = IFF_NO_PI;
TapTunDevice(const std::string& name, uint64_t flags);
TapTunDevice(uint64_t flags);
static const auto kFdReadOnly = O_RDONLY;
static const auto kFdWriteOnly = O_WRONLY;
static const auto kFdReadWrite = O_RDWR;
const std::string& Name() {
return name_;
}
TunTapDevice(const std::string& name, uint64_t if_flags, uint64_t fd_flags);
~TunTapDevice();
const std::string& Name() { return name_; }
// TODO: real buffer object
size_t Read(char* buf);
private:
int fd_;
std::string name_;
};
} // namespace funstraw

87
test.cc
View File

@@ -1,87 +0,0 @@
#include <sys/socket.h>
#include <fcntl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int tun_alloc(char *dev, int flags) {
struct ifreq ifr;
int fd, err;
const char *clonedev = "/dev/net/tun";
/* Arguments taken by the function:
*
* char *dev: the name of an interface (or '\0'). MUST have enough
* space to hold the interface name if '\0' is passed
* int flags: interface flags (eg, IFF_TUN etc.)
*/
/* open the clone device */
if( (fd = open(clonedev, O_RDWR)) < 0 ) {
return fd;
}
/* preparation of the struct ifr, of type "struct ifreq" */
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = flags; /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */
if (*dev) {
/* if a device name was specified, put it in the structure; otherwise,
* the kernel will try to allocate the "next" device of the
* specified type */
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
}
/* try to create the device */
if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
close(fd);
return err;
}
/* if the operation was successful, write back the name of the
* interface to the variable "dev", so the caller can know
* it. Note that the caller MUST reserve space in *dev (see calling
* code below) */
strcpy(dev, ifr.ifr_name);
/* this is the special file descriptor that the caller will use to talk
* with the virtual interface */
return fd;
}
int main(int argc, char *argv[]) {
char tun_name[IFNAMSIZ];
/* Connect to the device */
strcpy(tun_name, "tun77");
int tun_fd = tun_alloc(tun_name, IFF_TUN); /* tun interface */
if(tun_fd < 0){
perror("Allocating interface");
exit(1);
}
char buffer[2048];
/* Now read data coming from the kernel */
while(1) {
/* Note that "buffer" should be at least the MTU size of the interface, eg 1500 bytes */
int nread = read(tun_fd,buffer,sizeof(buffer));
if(nread < 0) {
perror("Reading from interface");
close(tun_fd);
exit(1);
}
/* Do whatever with the data */
printf("Read %d bytes from device %s\n", nread, tun_name);
}
return 0;
}

12
tools/BUILD Normal file
View File

@@ -0,0 +1,12 @@
cc_binary(
name = "dump_tun",
srcs = [
"dump_tun.cc",
],
deps = [
"//lib:tun_tap_device_lib",
],
linkopts = [
"-lglog",
],
)

18
tools/dump_tun.cc Normal file
View File

@@ -0,0 +1,18 @@
#include "lib/tun_tap_device.h"
#include "glog/logging.h"
using funstraw::TunTapDevice;
int main(int argc, char* argv[]) {
google::InitGoogleLogging(argv[0]);
TunTapDevice dev("", TunTapDevice::kIfFormatTun | TunTapDevice::kIfNoPacketInfo, TunTapDevice::kFdReadOnly);
LOG(INFO) << "Device: " << dev.Name();
while (true) {
char buf[2048];
auto bytes = dev.Read(buf);
LOG(INFO) << bytes << " byte packet";
}
}