mirror of https://github.com/oxen-io/lokinet
tun code refactor (#1495)
* partial tun code refactor * take out the trash * move vpn platform code into llarp/vpn/platform.cpp * fix hive build * fix win32 * fix memory leak on win32 * reduce cpu use * make macos compile * win32 patches: * use wepoll for zmq * use all cores on windows iocp read loop * fix zmq patch for windows * clean up cmake for win32 * add uninstall before reinstall option to win32 installer * more ipv6 stuff * make it compile * fix up route poker * remove an unneeded code block in macos wtf * always use call to system * fix route poker behavior on macos * disable ipv6 on windows for now * cpu perf improvement: * colease calls to Router::PumpLL to 1 per event loop wakeup * set up THEN add addresses * emulate proactor event loop on win32 * remove excessively verbose error message * fix issue #1499 * exclude uv_poll from win32 so that it can start up * update logtag to include directory * create minidump on windows if there was a crash * make windows happy * use dmp suffix on minidump files * typo fix * address feedback from jason * use PROJECT_SOURCE_DIR instead of CMAKE_SOURCE_DIR * quote $@ in apply-patches in case path has spaces in it * address feedback from tom * remove llarp/ev/pipe * add comments for clairification * make event loop queue size constant namedpull/1509/head
parent
029b6db364
commit
49b9ad7197
@ -1,6 +1,8 @@
|
||||
function(add_log_tag target)
|
||||
get_target_property(TARGET_SRCS ${target} SOURCES)
|
||||
foreach(F ${TARGET_SRCS})
|
||||
set_property(SOURCE ${F} APPEND PROPERTY COMPILE_DEFINITIONS LOG_TAG=\"${F}\")
|
||||
get_filename_component(fpath "${F}" ABSOLUTE)
|
||||
string(REPLACE "${PROJECT_SOURCE_DIR}/" "" logtag "${fpath}")
|
||||
set_property(SOURCE ${F} APPEND PROPERTY COMPILE_DEFINITIONS LOG_TAG=\"${logtag}\")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
for f in "$@" ; do
|
||||
patch -p1 -i "$f"
|
||||
done
|
@ -0,0 +1,16 @@
|
||||
diff --git a/external/wepoll/wepoll.c b/external/wepoll/wepoll.c
|
||||
--- a/external/wepoll/wepoll.c
|
||||
+++ b/external/wepoll/wepoll.c
|
||||
@@ -140,9 +140,9 @@
|
||||
#pragma warning(push, 1)
|
||||
#endif
|
||||
|
||||
-#include <WS2tcpip.h>
|
||||
-#include <WinSock2.h>
|
||||
-#include <Windows.h>
|
||||
+#include <ws2tcpip.h>
|
||||
+#include <winsock2.h>
|
||||
+#include <windows.h>
|
||||
|
||||
#ifndef __GNUC__
|
||||
#pragma warning(pop)
|
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
mkdir -p build-windows
|
||||
cd build-windows
|
||||
cmake -G Ninja -DCMAKE_CROSSCOMPILE=ON -DCMAKE_EXE_LINKER_FLAGS=-fstack-protector -DLIBUV_ROOT=$PWD/../external/libuv -DCMAKE_CXX_FLAGS=-fdiagnostics-color=always -DCMAKE_TOOLCHAIN_FILE=../contrib/cross/mingw64.cmake -DBUILD_STATIC_DEPS=ON -DBUILD_PACKAGE=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=OFF -DWITH_TESTS=OFF -DNATIVE_BUILD=OFF -DSTATIC_LINK=ON -DWITH_SYSTEMD=OFF -DFORCE_LOKIMQ_SUBMODULE=ON -DSUBMODULE_CHECK=OFF -DWITH_LTO=OFF ..
|
||||
cmake -G Ninja -DCMAKE_CROSSCOMPILE=ON -DCMAKE_EXE_LINKER_FLAGS=-fstack-protector -DLIBUV_ROOT=$PWD/../external/libuv -DCMAKE_CXX_FLAGS=-fdiagnostics-color=always -DCMAKE_TOOLCHAIN_FILE=../contrib/cross/mingw64.cmake -DBUILD_STATIC_DEPS=ON -DBUILD_PACKAGE=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=OFF -DWITH_TESTS=OFF -DNATIVE_BUILD=OFF -DSTATIC_LINK=ON -DWITH_SYSTEMD=OFF -DFORCE_LOKIMQ_SUBMODULE=ON -DSUBMODULE_CHECK=OFF -DWITH_LTO=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_CROSSCOMPLING=ON ..
|
||||
ninja package
|
||||
|
@ -1,267 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Tristan Le Guern <leguern AT medu DOT se>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* Copyright (c) 2016 Mahdi Mokhtari <mokhi64@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined Windows
|
||||
#else /* Unix */
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#if !defined Windows /* Unix :) */
|
||||
#if !defined Linux
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#if defined(Linux)
|
||||
// Once we drop xenial support we can just include net/if.h on linux
|
||||
#include <linux/if.h>
|
||||
#else
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
#if defined Linux
|
||||
#include <netinet/in.h>
|
||||
#elif defined(iOS)
|
||||
#include <net/ethernet.h>
|
||||
#else
|
||||
#include <netinet/if_ether.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef LIBTUNTAP_H_
|
||||
#define LIBTUNTAP_H_
|
||||
|
||||
#if defined IFNAMSIZ && !defined IF_NAMESIZE
|
||||
#define IF_NAMESIZE IFNAMSIZ /* Historical BSD name */
|
||||
#elif !defined IF_NAMESIZE
|
||||
#define IF_NAMESIZE 16
|
||||
#endif
|
||||
|
||||
#define IF_DESCRSIZE 50 /* XXX: Tests needed on NetBSD and OpenBSD */
|
||||
|
||||
#if defined TUNSETDEBUG
|
||||
#define TUNSDEBUG TUNSETDEBUG
|
||||
#endif
|
||||
|
||||
#if defined Windows
|
||||
#define TUNFD_INVALID_VALUE INVALID_HANDLE_VALUE
|
||||
#else /* Unix */
|
||||
#define TUNFD_INVALID_VALUE -1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Uniformize types
|
||||
* - t_tun: tun device file descriptor
|
||||
* - t_tun_in_addr: struct in_addr/IN_ADDR
|
||||
* - t_tun_in6_addr: struct in6_addr/IN6_ADDR
|
||||
*/
|
||||
#if defined Windows
|
||||
#include <windows.h>
|
||||
#include <in6addr.h>
|
||||
#include <winsock2.h>
|
||||
typedef HANDLE t_tun;
|
||||
typedef IN_ADDR t_tun_in_addr;
|
||||
typedef IN6_ADDR t_tun_in6_addr;
|
||||
#else /* Unix */
|
||||
typedef int t_tun;
|
||||
typedef struct in_addr t_tun_in_addr;
|
||||
typedef struct in6_addr t_tun_in6_addr;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Windows helpers
|
||||
*/
|
||||
#if defined Windows
|
||||
//#define strncat(x, y, z) strncat_s((x), _countof(x), (y), (z));
|
||||
#define strdup(x) _strdup(x)
|
||||
#endif
|
||||
|
||||
#define TUNTAP_ID_MAX 256
|
||||
#define TUNTAP_ID_ANY 257
|
||||
|
||||
#define TUNTAP_MODE_ETHERNET 0x0001
|
||||
#define TUNTAP_MODE_TUNNEL 0x0002
|
||||
#define TUNTAP_MODE_PERSIST 0x0004
|
||||
|
||||
#define TUNTAP_LOG_NONE 0x0000
|
||||
#define TUNTAP_LOG_DEBUG 0x0001
|
||||
#define TUNTAP_LOG_INFO 0x0002
|
||||
#define TUNTAP_LOG_NOTICE 0x0004
|
||||
#define TUNTAP_LOG_WARN 0x0008
|
||||
#define TUNTAP_LOG_ERR 0x0016
|
||||
|
||||
/* Versioning: 0xMMmm, with 'M' for major and 'm' for minor */
|
||||
#define TUNTAP_VERSION_MAJOR 0
|
||||
#define TUNTAP_VERSION_MINOR 3
|
||||
#define TUNTAP_VERSION ((TUNTAP_VERSION_MAJOR << 8) | TUNTAP_VERSION_MINOR)
|
||||
|
||||
#define TUNTAP_GET_FD(x) (x)->tun_fd
|
||||
|
||||
/* Handle Windows symbols export */
|
||||
#if defined Windows
|
||||
#if defined(tuntap_EXPORTS) && defined(_USRDLL) /* CMake generated goo */
|
||||
#define TUNTAP_EXPORT __declspec(dllexport)
|
||||
#elif defined(tuntap_EXPORTS)
|
||||
#define TUNTAP_EXPORT __declspec(dllimport)
|
||||
#else
|
||||
#define TUNTAP_EXPORT extern
|
||||
#endif
|
||||
#else /* Unix */
|
||||
#define TUNTAP_EXPORT extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct device
|
||||
{
|
||||
/** set me on ios and android to block on a promise for the fd */
|
||||
int (*obtain_fd)(struct device*);
|
||||
/** user data */
|
||||
void* user;
|
||||
t_tun tun_fd;
|
||||
int ctrl_sock;
|
||||
int flags; /* ifr.ifr_flags on Unix */
|
||||
char if_name[IF_NAMESIZE];
|
||||
#if defined(Windows)
|
||||
int idx; /* needed to set ipv6 address */
|
||||
DWORD bindaddr; /* set DNS client address */
|
||||
#endif
|
||||
#if defined(FreeBSD)
|
||||
int mode;
|
||||
#endif
|
||||
#if defined(__sun)
|
||||
int ip_fd;
|
||||
int reserved;
|
||||
char internal_name[IF_NAMESIZE];
|
||||
#endif
|
||||
};
|
||||
|
||||
/* User definable log callback */
|
||||
typedef void (*t_tuntap_log)(int, int, const char*, const char*);
|
||||
TUNTAP_EXPORT t_tuntap_log __tuntap_log;
|
||||
|
||||
#ifndef LOG_TAG
|
||||
#define LOG_TAG "tuntap"
|
||||
#endif
|
||||
|
||||
#define tuntap_log(lvl, msg) __tuntap_log(lvl, __LINE__, LOG_TAG, msg)
|
||||
|
||||
/* Portable "public" functions */
|
||||
TUNTAP_EXPORT struct device*
|
||||
tuntap_init(void);
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_version(void);
|
||||
TUNTAP_EXPORT void
|
||||
tuntap_destroy(struct device*);
|
||||
TUNTAP_EXPORT void
|
||||
tuntap_release(struct device*);
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_start(struct device*, int, int);
|
||||
TUNTAP_EXPORT char*
|
||||
tuntap_get_ifname(struct device*);
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_set_ifname(struct device*, const char*);
|
||||
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_set_descr(struct device*, const char*);
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_up(struct device*);
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_down(struct device*);
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_get_mtu(struct device*);
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_set_mtu(struct device*, int);
|
||||
|
||||
/** set ip address and netmask
|
||||
|
||||
*/
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_set_ip(struct device*, const char* srcaddr, const char* dstaddr, int netmask);
|
||||
// TUNTAP_EXPORT int tuntap_set_ip_old(struct device *, const char
|
||||
// *, int);
|
||||
/*TUNTAP_EXPORT int tuntap_set_ip_old(struct device *, const char
|
||||
* *, int);*/
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_read(struct device*, void*, size_t);
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_write(struct device*, void*, size_t);
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_get_readable(struct device*);
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_set_nonblocking(struct device* dev, int);
|
||||
TUNTAP_EXPORT int
|
||||
tuntap_set_debug(struct device* dev, int);
|
||||
|
||||
/* Logging functions */
|
||||
TUNTAP_EXPORT void
|
||||
tuntap_log_set_cb(t_tuntap_log cb);
|
||||
void
|
||||
tuntap_log_default(int, int, const char*, const char*);
|
||||
void
|
||||
tuntap_log_hexdump(void*, size_t);
|
||||
void
|
||||
tuntap_log_chksum(void*, int);
|
||||
|
||||
/* OS specific functions */
|
||||
int
|
||||
tuntap_sys_start(struct device*, int, int);
|
||||
void
|
||||
tuntap_sys_destroy(struct device*);
|
||||
int
|
||||
tuntap_sys_set_ipv4(struct device*, t_tun_in_addr*, uint32_t);
|
||||
|
||||
#if defined(Windows)
|
||||
int
|
||||
tuntap_sys_set_dns(struct device* dev, t_tun_in_addr* s, uint32_t mask);
|
||||
#endif
|
||||
|
||||
#if defined(FreeBSD)
|
||||
int
|
||||
tuntap_sys_set_ipv4_tap(struct device*, t_tun_in_addr*, uint32_t);
|
||||
int
|
||||
tuntap_sys_set_ipv4_tun(
|
||||
struct device* dev, t_tun_in_addr* s4, t_tun_in_addr* s4dest, uint32_t bits, int netmask);
|
||||
#endif
|
||||
|
||||
int
|
||||
tuntap_sys_set_ipv6(struct device*, t_tun_in6_addr*, uint32_t);
|
||||
int
|
||||
tuntap_sys_set_ifname(struct device*, const char*, size_t);
|
||||
int
|
||||
tuntap_sys_set_descr(struct device*, const char*, size_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,226 +0,0 @@
|
||||
#include <ev/ev_win32.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <util/logging/logger.hpp>
|
||||
#include <atomic>
|
||||
|
||||
// a single event queue for the TUN interface
|
||||
static HANDLE tun_event_queue = INVALID_HANDLE_VALUE;
|
||||
|
||||
// we hand the kernel our thread handles to process completion events
|
||||
static HANDLE* kThreadPool;
|
||||
static int poolSize;
|
||||
|
||||
// list of TUN listeners (useful for exits or other nodes with multiple TUNs)
|
||||
std::list<win32_tun_io*> tun_listeners;
|
||||
|
||||
void
|
||||
begin_tun_loop(int nThreads, llarp_ev_loop* loop)
|
||||
{
|
||||
kThreadPool = new HANDLE[nThreads];
|
||||
for (int i = 0; i < nThreads; ++i)
|
||||
{
|
||||
kThreadPool[i] = CreateThread(nullptr, 0, &tun_ev_loop, loop, 0, nullptr);
|
||||
}
|
||||
llarp::LogInfo("created ", nThreads, " threads for TUN event queue");
|
||||
poolSize = nThreads;
|
||||
}
|
||||
|
||||
// this one is called from the TUN handler
|
||||
bool
|
||||
win32_tun_io::queue_write(const byte_t* buf, size_t sz)
|
||||
{
|
||||
return do_write((void*)buf, sz);
|
||||
}
|
||||
|
||||
bool
|
||||
win32_tun_io::setup()
|
||||
{
|
||||
if (tuntap_start(tunif, TUNTAP_MODE_TUNNEL, 0) == -1)
|
||||
{
|
||||
llarp::LogWarn("failed to start interface");
|
||||
return false;
|
||||
}
|
||||
if (tuntap_up(tunif) == -1)
|
||||
{
|
||||
char ebuf[1024];
|
||||
int err = GetLastError();
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL, ebuf, 1024, nullptr);
|
||||
llarp::LogWarn("failed to put interface up: ", ebuf);
|
||||
return false;
|
||||
}
|
||||
tunif->bindaddr = t->dnsaddr;
|
||||
|
||||
if (tuntap_set_ip(tunif, t->ifaddr, t->ifaddr, t->netmask) == -1)
|
||||
{
|
||||
llarp::LogWarn("failed to set ip");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tunif->tun_fd == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// first TUN device gets to set up the event port
|
||||
bool
|
||||
win32_tun_io::add_ev(llarp_ev_loop* loop)
|
||||
{
|
||||
if (tun_event_queue == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SYSTEM_INFO sys_info;
|
||||
GetSystemInfo(&sys_info);
|
||||
unsigned long numCPU = sys_info.dwNumberOfProcessors;
|
||||
// let the system handle 2x the number of CPUs or hardware
|
||||
// threads
|
||||
tun_event_queue = CreateIoCompletionPort(tunif->tun_fd, nullptr, (ULONG_PTR)this, numCPU * 2);
|
||||
begin_tun_loop(numCPU * 2, loop);
|
||||
}
|
||||
else
|
||||
CreateIoCompletionPort(tunif->tun_fd, tun_event_queue, (ULONG_PTR)this, 0);
|
||||
|
||||
// we're already non-blocking
|
||||
// add to list
|
||||
tun_listeners.push_back(this);
|
||||
byte_t* readbuf = (byte_t*)malloc(1500);
|
||||
read(readbuf, 1500);
|
||||
return true;
|
||||
}
|
||||
|
||||
// places data in event queue for kernel to process
|
||||
bool
|
||||
win32_tun_io::do_write(void* data, size_t sz)
|
||||
{
|
||||
DWORD code;
|
||||
asio_evt_pkt* pkt = new asio_evt_pkt;
|
||||
pkt->buf = data;
|
||||
pkt->sz = sz;
|
||||
pkt->write = true;
|
||||
memset(&pkt->pkt, '\0', sizeof(pkt->pkt));
|
||||
WriteFile(tunif->tun_fd, data, sz, nullptr, &pkt->pkt);
|
||||
code = GetLastError();
|
||||
// llarp::LogInfo("wrote data, error ", code);
|
||||
return (code == 0 || code == 997);
|
||||
}
|
||||
|
||||
// while this one is called from the event loop
|
||||
// eventually comes back and calls queue_write()
|
||||
void
|
||||
win32_tun_io::flush_write()
|
||||
{
|
||||
if (t->before_write)
|
||||
t->before_write(t);
|
||||
}
|
||||
|
||||
void
|
||||
win32_tun_io::read(byte_t* buf, size_t sz)
|
||||
{
|
||||
asio_evt_pkt* pkt = new asio_evt_pkt;
|
||||
pkt->buf = buf;
|
||||
memset(&pkt->pkt, '\0', sizeof(OVERLAPPED));
|
||||
pkt->sz = sz;
|
||||
pkt->write = false;
|
||||
ReadFile(tunif->tun_fd, buf, sz, nullptr, &pkt->pkt);
|
||||
}
|
||||
|
||||
// and now the event loop itself
|
||||
extern "C" DWORD FAR PASCAL
|
||||
tun_ev_loop(void* u)
|
||||
{
|
||||
llarp_ev_loop* logic = static_cast<llarp_ev_loop*>(u);
|
||||
|
||||
DWORD size = 0;
|
||||
OVERLAPPED* ovl = nullptr;
|
||||
ULONG_PTR listener = 0;
|
||||
asio_evt_pkt* pkt = nullptr;
|
||||
BOOL alert;
|
||||
|
||||
std::atomic_flag tick_queued;
|
||||
while (true)
|
||||
{
|
||||
alert = GetQueuedCompletionStatus(tun_event_queue, &size, &listener, &ovl, EV_TICK_INTERVAL);
|
||||
|
||||
if (!alert)
|
||||
{
|
||||
// tick listeners on io timeout, this is required to be done every tick
|
||||
// cycle regardless of any io being done, this manages the internal state
|
||||
// of the tun logic
|
||||
|
||||
if (tick_queued.test_and_set())
|
||||
continue; // if tick queued, don't queue another
|
||||
|
||||
logic->call_soon([&]() {
|
||||
for (const auto& tun : tun_listeners)
|
||||
{
|
||||
tun->flush_write();
|
||||
if (tun->t->tick)
|
||||
tun->t->tick(tun->t);
|
||||
}
|
||||
tick_queued.clear();
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
if (listener == (ULONG_PTR)~0)
|
||||
break;
|
||||
// if we're here, then we got something interesting :>
|
||||
pkt = (asio_evt_pkt*)ovl;
|
||||
win32_tun_io* ev = reinterpret_cast<win32_tun_io*>(listener);
|
||||
if (!pkt->write)
|
||||
{
|
||||
// llarp::LogInfo("read tun ", size, " bytes, pass to handler");
|
||||
logic->call_soon([pkt, size, ev]() {
|
||||
if (ev->t->recvpkt)
|
||||
ev->t->recvpkt(ev->t, llarp_buffer_t(pkt->buf, size));
|
||||
free(pkt->buf);
|
||||
delete pkt;
|
||||
});
|
||||
byte_t* readbuf = (byte_t*)malloc(1500);
|
||||
ev->read(readbuf, 1500);
|
||||
}
|
||||
|
||||
logic->call_soon([ev]() {
|
||||
ev->flush_write();
|
||||
if (ev->t->tick)
|
||||
ev->t->tick(ev->t);
|
||||
});
|
||||
}
|
||||
llarp::LogDebug("exit TUN event loop thread from system managed thread pool");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
exit_tun_loop()
|
||||
{
|
||||
if (kThreadPool)
|
||||
{
|
||||
// kill the kernel's thread pool
|
||||
// int i = (&kThreadPool)[1] - kThreadPool; // get the size of our thread
|
||||
// pool
|
||||
llarp::LogInfo("closing ", poolSize, " threads");
|
||||
// if we get all-ones in the queue, thread exits, and we clean up
|
||||
for (int j = 0; j < poolSize; ++j)
|
||||
PostQueuedCompletionStatus(tun_event_queue, 0, ~0, nullptr);
|
||||
WaitForMultipleObjects(poolSize, kThreadPool, TRUE, INFINITE);
|
||||
for (int j = 0; j < poolSize; ++j)
|
||||
CloseHandle(kThreadPool[j]);
|
||||
delete[] kThreadPool;
|
||||
kThreadPool = nullptr;
|
||||
|
||||
// the IOCP refcount is decreased each time an associated fd
|
||||
// is closed
|
||||
// the fds are closed in their destructors
|
||||
// once we get to zero, we can safely close the event port
|
||||
auto itr = tun_listeners.begin();
|
||||
while (itr != tun_listeners.end())
|
||||
{
|
||||
delete (*itr);
|
||||
itr = tun_listeners.erase(itr);
|
||||
}
|
||||
CloseHandle(tun_event_queue);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,97 +0,0 @@
|
||||
#ifndef EV_WIN32_H
|
||||
#define EV_WIN32_H
|
||||
#ifdef _WIN32
|
||||
#include <ev/ev.hpp>
|
||||
#include <net/net.h>
|
||||
#include <net/net.hpp>
|
||||
#include <util/buffer.hpp>
|
||||
#include <util/thread/logic.hpp>
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
// io packet for TUN read/write
|
||||
struct asio_evt_pkt
|
||||
{
|
||||
OVERLAPPED pkt = {0, 0, 0, 0, nullptr}; // must be first, since this is part of the IO call
|
||||
bool write = false; // true, or false if read pkt
|
||||
size_t sz; // should match the queued data size, if not try again?
|
||||
void* buf; // must remain valid until we get notification; this is _supposed_
|
||||
// to be zero-copy
|
||||
};
|
||||
|
||||
extern "C" DWORD FAR PASCAL
|
||||
tun_ev_loop(void* unused);
|
||||
|
||||
void
|
||||
exit_tun_loop();
|
||||
|
||||
void
|
||||
begin_tun_loop(int nThreads);
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct udp_listener : public ev_io
|
||||
{
|
||||
llarp_udp_io* udp;
|
||||
|
||||
udp_listener(int fd, llarp_udp_io* u) : ev_io(fd), udp(u){};
|
||||
|
||||
~udp_listener()
|
||||
{}
|
||||
|
||||
bool
|
||||
tick();
|
||||
|
||||
int
|
||||
read(byte_t* buf, size_t sz);
|
||||
|
||||
int
|
||||
sendto(const sockaddr* to, const void* data, size_t sz);
|
||||
};
|
||||
} // namespace llarp
|
||||
|
||||
// A different kind of event loop,
|
||||
// more suited for the native Windows NT
|
||||
// event model
|
||||
struct win32_tun_io
|
||||
{
|
||||
llarp_tun_io* t;
|
||||
device* tunif;
|
||||
|
||||
win32_tun_io(llarp_tun_io* tio) : t(tio), tunif(tuntap_init()){};
|
||||
|
||||
bool
|
||||
queue_write(const byte_t* buf, size_t sz);
|
||||
|
||||
bool
|
||||
setup();
|
||||
|
||||
// first TUN device gets to set up the event port
|
||||
bool
|
||||
add_ev(llarp_ev_loop* l);
|
||||
|
||||
// places data in event queue for kernel to process
|
||||
bool
|
||||
do_write(void* data, size_t sz);
|
||||
|
||||
// we call this one when we get a packet in the event port
|
||||
// which then kicks off another write
|
||||
void
|
||||
flush_write();
|
||||
|
||||
void
|
||||
read(byte_t* buf, size_t sz);
|
||||
|
||||
~win32_tun_io()
|
||||
{
|
||||
CancelIo(tunif->tun_fd);
|
||||
if (tunif->tun_fd)
|
||||
tuntap_destroy(tunif);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
@ -1,66 +0,0 @@
|
||||
#include <ev/pipe.hpp>
|
||||
#include <utility>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
llarp_ev_pkt_pipe::llarp_ev_pkt_pipe(llarp_ev_loop_ptr loop)
|
||||
: llarp::ev_io(-1, new LosslessWriteQueue_t()), m_Loop(std::move(loop))
|
||||
{}
|
||||
|
||||
bool
|
||||
llarp_ev_pkt_pipe::StartPipe()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
llarp::LogError("llarp_ev_pkt_pipe not supported on win32");
|
||||
return false;
|
||||
#else
|
||||
int _fds[2];
|
||||
if (pipe(_fds) == -1 && fcntl(_fds[0], F_SETFL, fcntl(_fds[0], F_GETFL) | O_NONBLOCK))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
fd = _fds[0];
|
||||
writefd = _fds[1];
|
||||
return m_Loop->add_pipe(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
llarp_ev_pkt_pipe::read(byte_t* pkt, size_t sz)
|
||||
{
|
||||
auto res = ::read(fd, pkt, sz);
|
||||
if (res <= 0)
|
||||
return res;
|
||||
llarp::LogDebug("read ", res, " on pipe");
|
||||
llarp_buffer_t buf(pkt, res);
|
||||
OnRead(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
llarp_ev_pkt_pipe::do_write(void* buf, size_t sz)
|
||||
{
|
||||
return ::write(writefd, buf, sz);
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_ev_pkt_pipe::Write(const llarp_buffer_t& pkt)
|
||||
{
|
||||
const ssize_t sz = pkt.sz;
|
||||
if (do_write(pkt.base, pkt.sz) != sz)
|
||||
{
|
||||
llarp::LogDebug("queue write ", pkt.sz);
|
||||
return queue_write(pkt.base, pkt.sz);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_ev_pkt_pipe::tick()
|
||||
{
|
||||
llarp::ev_io::flush_write();
|
||||
return true;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
#ifndef LLARP_EV_PIPE_HPP
|
||||
#define LLARP_EV_PIPE_HPP
|
||||
|
||||
#include <ev/ev.hpp>
|
||||
|
||||
/// a unidirectional packet pipe
|
||||
struct llarp_ev_pkt_pipe : public llarp::ev_io
|
||||
{
|
||||
llarp_ev_pkt_pipe(llarp_ev_loop_ptr loop);
|
||||
|
||||
/// start the pipe, initialize fds
|
||||
bool
|
||||
StartPipe();
|
||||
|
||||
/// write to the pipe from outside the event loop
|
||||
/// returns true on success
|
||||
/// returns false on failure
|
||||
bool
|
||||
Write(const llarp_buffer_t& buf);
|
||||
|
||||
/// override me to handle a packet from the other side in the owned event loop
|
||||
virtual void
|
||||
OnRead(const llarp_buffer_t& buf) = 0;
|
||||
|
||||
ssize_t
|
||||
do_write(void* buf, size_t sz) override;
|
||||
|
||||
bool
|
||||
tick() override;
|
||||
|
||||
int
|
||||
read(byte_t* buf, size_t sz) override;
|
||||
|
||||
private:
|
||||
llarp_ev_loop_ptr m_Loop;
|
||||
int writefd;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include <net/ip_range.hpp>
|
||||
#include <net/ip_packet.hpp>
|
||||
#include <set>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct Context;
|
||||
}
|
||||
|
||||
namespace llarp::vpn
|
||||
{
|
||||
struct InterfaceAddress
|
||||
{
|
||||
constexpr InterfaceAddress(IPRange r, int f = AF_INET) : range{std::move(r)}, fam{f}
|
||||
{}
|
||||
IPRange range;
|
||||
int fam;
|
||||
bool
|
||||
operator<(const InterfaceAddress& other) const
|
||||
{
|
||||
return range < other.range or fam < other.fam;
|
||||
}
|
||||
};
|
||||
|
||||
struct InterfaceInfo
|
||||
{
|
||||
std::string ifname;
|
||||
huint32_t dnsaddr;
|
||||
std::set<InterfaceAddress> addrs;
|
||||
};
|
||||
|
||||
/// a vpn network interface
|
||||
class NetworkInterface
|
||||
{
|
||||
public:
|
||||
NetworkInterface() = default;
|
||||
NetworkInterface(const NetworkInterface&) = delete;
|
||||
NetworkInterface(NetworkInterface&&) = delete;
|
||||
|
||||
virtual ~NetworkInterface() = default;
|
||||
|
||||
/// get pollable fd for reading
|
||||
virtual int
|
||||
PollFD() const = 0;
|
||||
|
||||
/// the interface's name
|
||||
virtual std::string
|
||||
IfName() const = 0;
|
||||
|
||||
/// read next ip packet
|
||||
/// blocks until ready
|
||||
virtual net::IPPacket
|
||||
ReadNextPacket() = 0;
|
||||
|
||||
/// return true if we have another packet to read
|
||||
virtual bool
|
||||
HasNextPacket() = 0;
|
||||
|
||||
/// write a packet to the interface
|
||||
/// returns false if we dropped it
|
||||
virtual bool
|
||||
WritePacket(net::IPPacket pkt) = 0;
|
||||
};
|
||||
|
||||
/// a vpn platform
|
||||
/// responsible for obtaining vpn interfaces
|
||||
class Platform
|
||||
{
|
||||
public:
|
||||
Platform() = default;
|
||||
Platform(const Platform&) = delete;
|
||||
Platform(Platform&&) = delete;
|
||||
virtual ~Platform() = default;
|
||||
|
||||
/// get a new network interface fully configured given the interface info
|
||||
/// blocks until ready, throws on error
|
||||
virtual std::shared_ptr<NetworkInterface>
|
||||
ObtainInterface(InterfaceInfo info) = 0;
|
||||
};
|
||||
|
||||
/// create native vpn platform
|
||||
std::unique_ptr<Platform>
|
||||
MakeNativePlatform(llarp::Context* ctx);
|
||||
|
||||
} // namespace llarp::vpn
|
@ -0,0 +1,176 @@
|
||||
#pragma once
|
||||
|
||||
#include <ev/vpn.hpp>
|
||||
#include <vpn/common.hpp>
|
||||
|
||||
#include <sys/kern_control.h>
|
||||
#include <sys/sys_domain.h>
|
||||
#include <sys/kern_event.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
namespace llarp::vpn
|
||||
{
|
||||
class AppleInterface : public NetworkInterface
|
||||
{
|
||||
const int m_FD;
|
||||
const InterfaceInfo m_Info;
|
||||
std::string m_IfName;
|
||||
|
||||
static void
|
||||
Exec(std::string cmd)
|
||||
{
|
||||
LogDebug(cmd);
|
||||
system(cmd.c_str());
|
||||
}
|
||||
|
||||
public:
|
||||
AppleInterface(InterfaceInfo info)
|
||||
: m_FD{::socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL)}, m_Info{std::move(info)}
|
||||
{
|
||||
if (m_FD == -1)
|
||||
throw std::invalid_argument{"cannot open control socket: " + std::string{strerror(errno)}};
|
||||
|
||||
ctl_info cinfo{};
|
||||
const std::string apple_utun = "com.apple.net.utun_control";
|
||||
std::copy_n(apple_utun.c_str(), apple_utun.size(), cinfo.ctl_name);
|
||||
if (::ioctl(m_FD, CTLIOCGINFO, &cinfo) < 0)
|
||||
{
|
||||
::close(m_FD);
|
||||
throw std::runtime_error{"ioctl CTLIOCGINFO call failed: " + std::string{strerror(errno)}};
|
||||
}
|
||||
sockaddr_ctl addr{};
|
||||
addr.sc_id = cinfo.ctl_id;
|
||||
|
||||
addr.sc_len = sizeof(addr);
|
||||
addr.sc_family = AF_SYSTEM;
|
||||
addr.ss_sysaddr = AF_SYS_CONTROL;
|
||||
addr.sc_unit = 0;
|
||||
|
||||
if (connect(m_FD, (sockaddr*)&addr, sizeof(addr)) < 0)
|
||||
{
|
||||
::close(m_FD);
|
||||
throw std::runtime_error{"cannot connect to control socket address: "
|
||||
+ std::string{strerror(errno)}};
|
||||
}
|
||||
uint32_t namesz = IFNAMSIZ;
|
||||
char name[IFNAMSIZ + 1]{};
|
||||
if (getsockopt(m_FD, SYSPROTO_CONTROL, 2, name, &namesz) < 0)
|
||||
{
|
||||
::close(m_FD);
|
||||
throw std::runtime_error{"cannot query for interface name: "
|
||||
+ std::string{strerror(errno)}};
|
||||
}
|
||||
m_IfName = name;
|
||||
for (const auto& ifaddr : m_Info.addrs)
|
||||
{
|
||||
if (ifaddr.fam == AF_INET)
|
||||
{
|
||||
const huint32_t addr = net::TruncateV6(ifaddr.range.addr);
|
||||
const huint32_t netmask = net::TruncateV6(ifaddr.range.netmask_bits);
|
||||
const huint32_t daddr = addr & netmask;
|
||||
Exec(
|
||||
"/sbin/ifconfig " + m_IfName + " " + addr.ToString() + " " + daddr.ToString()
|
||||
+ " mtu 1500 netmask 255.255.255.255 up");
|
||||
Exec(
|
||||
"/sbin/route add " + daddr.ToString() + " -netmask " + netmask.ToString()
|
||||
+ " -interface " + m_IfName);
|
||||
Exec("/sbin/route add " + addr.ToString() + " -interface lo0");
|
||||
}
|
||||
else if (ifaddr.fam == AF_INET6)
|
||||
{
|
||||
Exec("/sbin/ifconfig " + m_IfName + " inet6 " + ifaddr.range.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~AppleInterface()
|
||||
{
|
||||
::close(m_FD);
|
||||
}
|
||||
|
||||
std::string
|
||||
IfName() const override
|
||||
{
|
||||
return m_IfName;
|
||||
}
|
||||
|
||||
int
|
||||
PollFD() const override
|
||||
{
|
||||
return m_FD;
|
||||
}
|
||||
|
||||
bool
|
||||
HasNextPacket() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
net::IPPacket
|
||||
ReadNextPacket() override
|
||||
{
|
||||
net::IPPacket pkt{};
|
||||
unsigned int pktinfo = 0;
|
||||
const struct iovec vecs[2] = {{.iov_base = &pktinfo, .iov_len = sizeof(unsigned int)},
|
||||
{.iov_base = pkt.buf, .iov_len = sizeof(pkt.buf)}};
|
||||
int n = readv(m_FD, vecs, 2);
|
||||
if (n >= (int)(sizeof(unsigned int)))
|
||||
{
|
||||
n -= sizeof(unsigned int);
|
||||
pkt.sz = n;
|
||||
}
|
||||
return pkt;
|
||||
}
|
||||
|
||||
bool
|
||||
WritePacket(net::IPPacket pkt) override
|
||||
{
|
||||
static unsigned int af4 = htonl(AF_INET);
|
||||
static unsigned int af6 = htonl(AF_INET6);
|
||||
|
||||
const struct iovec vecs[2] = {
|
||||
{.iov_base = pkt.IsV6() ? &af6 : &af4, .iov_len = sizeof(unsigned int)},
|
||||
{.iov_base = pkt.buf, .iov_len = pkt.sz}};
|
||||
|
||||
ssize_t n = writev(m_FD, vecs, 2);
|
||||
if (n >= (int)sizeof(unsigned int))
|
||||
{
|
||||
n -= sizeof(unsigned int);
|
||||
return static_cast<size_t>(n) == pkt.sz;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class ApplePlatform : public Platform
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<NetworkInterface>
|
||||
ObtainInterface(InterfaceInfo info) override
|
||||
{
|
||||
return std::make_shared<AppleInterface>(std::move(info));
|
||||
}
|
||||
};
|
||||
} // namespace llarp::vpn
|
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
namespace llarp::vpn
|
||||
{
|
||||
struct IOCTL
|
||||
{
|
||||
const int _fd;
|
||||
|
||||
explicit IOCTL(int af) : _fd{::socket(af, SOCK_DGRAM, IPPROTO_IP)}
|
||||
{
|
||||
if (_fd == -1)
|
||||
throw std::invalid_argument{strerror(errno)};
|
||||
};
|
||||
|
||||
~IOCTL()
|
||||
{
|
||||
::close(_fd);
|
||||
}
|
||||
|
||||
template <typename Command, typename... Args>
|
||||
void
|
||||
ioctl(Command cmd, Args&&... args)
|
||||
{
|
||||
if (::ioctl(_fd, cmd, std::forward<Args>(args)...) == -1)
|
||||
throw std::runtime_error("ioctl failed: " + std::string{strerror(errno)});
|
||||
}
|
||||
};
|
||||
} // namespace llarp::vpn
|
@ -0,0 +1,129 @@
|
||||
#pragma once
|
||||
|
||||
#include <ev/vpn.hpp>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <vpn/common.hpp>
|
||||
#include <linux/if_tun.h>
|
||||
|
||||
namespace llarp::vpn
|
||||
{
|
||||
struct in6_ifreq
|
||||
{
|
||||
in6_addr addr;
|
||||
uint32_t prefixlen;
|
||||
unsigned int ifindex;
|
||||
};
|
||||
|
||||
class LinuxInterface : public NetworkInterface
|
||||
{
|
||||
const int m_fd;
|
||||
const InterfaceInfo m_Info;
|
||||
|
||||
public:
|
||||
LinuxInterface(InterfaceInfo info)
|
||||
: NetworkInterface{}, m_fd{::open("/dev/net/tun", O_RDWR)}, m_Info{std::move(info)}
|
||||
|
||||
{
|
||||
if (m_fd == -1)
|
||||
throw std::runtime_error("cannot open /dev/net/tun " + std::string{strerror(errno)});
|
||||
|
||||
ifreq ifr{};
|
||||
in6_ifreq ifr6{};
|
||||
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
|
||||
std::copy_n(
|
||||
m_Info.ifname.c_str(),
|
||||
std::min(m_Info.ifname.size(), sizeof(ifr.ifr_name)),
|
||||
ifr.ifr_name);
|
||||
if (::ioctl(m_fd, TUNSETIFF, &ifr) == -1)
|
||||
throw std::runtime_error("cannot set interface name: " + std::string{strerror(errno)});
|
||||
IOCTL control{AF_INET};
|
||||
|
||||
control.ioctl(SIOCGIFFLAGS, &ifr);
|
||||
const int flags = ifr.ifr_flags;
|
||||
control.ioctl(SIOCGIFINDEX, &ifr);
|
||||
const int ifindex = ifr.ifr_ifindex;
|
||||
|
||||
IOCTL control6{AF_INET6};
|
||||
for (const auto& ifaddr : m_Info.addrs)
|
||||
{
|
||||
if (ifaddr.fam == AF_INET)
|
||||
{
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
const nuint32_t addr = ToNet(net::TruncateV6(ifaddr.range.addr));
|
||||
((sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr = addr.n;
|
||||
control.ioctl(SIOCSIFADDR, &ifr);
|
||||
|
||||
const nuint32_t mask = ToNet(net::TruncateV6(ifaddr.range.netmask_bits));
|
||||
((sockaddr_in*)&ifr.ifr_netmask)->sin_addr.s_addr = mask.n;
|
||||
control.ioctl(SIOCSIFNETMASK, &ifr);
|
||||
}
|
||||
if (ifaddr.fam == AF_INET6)
|
||||
{
|
||||
ifr6.addr = net::HUIntToIn6(ifaddr.range.addr);
|
||||
ifr6.prefixlen = llarp::bits::count_bits(ifaddr.range.netmask_bits);
|
||||
ifr6.ifindex = ifindex;
|
||||
control6.ioctl(SIOCSIFADDR, &ifr6);
|
||||
}
|
||||
}
|
||||
ifr.ifr_flags = flags | IFF_UP | IFF_NO_PI;
|
||||
control.ioctl(SIOCSIFFLAGS, &ifr);
|
||||
}
|
||||
|
||||
virtual ~LinuxInterface()
|
||||
{
|
||||
if (m_fd != -1)
|
||||
::close(m_fd);
|
||||
}
|
||||
|
||||
int
|
||||
PollFD() const override
|
||||
{
|
||||
return m_fd;
|
||||
}
|
||||
|
||||
net::IPPacket
|
||||
ReadNextPacket() override
|
||||
{
|
||||
net::IPPacket pkt;
|
||||
const auto sz = read(m_fd, pkt.buf, sizeof(pkt.buf));
|
||||
if (sz >= 0)
|
||||
pkt.sz = std::min(sz, ssize_t{sizeof(pkt.buf)});
|
||||
return pkt;
|
||||
}
|
||||
|
||||
bool
|
||||
WritePacket(net::IPPacket pkt) override
|
||||
{
|
||||
const auto sz = write(m_fd, pkt.buf, pkt.sz);
|
||||
if (sz <= 0)
|
||||
return false;
|
||||
return sz == static_cast<ssize_t>(pkt.sz);
|
||||
}
|
||||
|
||||
bool
|
||||
HasNextPacket() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string
|
||||
IfName() const override
|
||||
{
|
||||
return m_Info.ifname;
|
||||
}
|
||||
};
|
||||
|
||||
class LinuxPlatform : public Platform
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<NetworkInterface>
|
||||
ObtainInterface(InterfaceInfo info) override
|
||||
{
|
||||
return std::make_shared<LinuxInterface>(std::move(info));
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace llarp::vpn
|
@ -0,0 +1,38 @@
|
||||
#ifdef _WIN32
|
||||
#include <vpn/win32.hpp>
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
#ifdef ANDROID
|
||||
#include <vpn/android.hpp>
|
||||
#else
|
||||
#include <vpn/linux.hpp>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#include <vpn/apple.hpp>
|
||||
#endif
|
||||
|
||||
namespace llarp::vpn
|
||||
{
|
||||
std::unique_ptr<Platform>
|
||||
MakeNativePlatform(llarp::Context* ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
std::unique_ptr<Platform> plat;
|
||||
#ifdef _WIN32
|
||||
plat = std::make_unique<vpn::Win32Platform>();
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
#ifdef ANDROID
|
||||
plat = std::make_unique<vpn::AndroidPlatform>();
|
||||
#else
|
||||
plat = std::make_unique<vpn::LinuxPlatform>();
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
plat = std::make_unique<vpn::ApplePlatform>();
|
||||
#endif
|
||||
return plat;
|
||||
}
|
||||
|
||||
} // namespace llarp::vpn
|
@ -0,0 +1,446 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <util/thread/queue.hpp>
|
||||
#include <ev/vpn.hpp>
|
||||
|
||||
// DDK macros
|
||||
#define CTL_CODE(DeviceType, Function, Method, Access) \
|
||||
(((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
|
||||
#define FILE_DEVICE_UNKNOWN 0x00000022
|
||||
#define FILE_ANY_ACCESS 0x00000000
|
||||
#define METHOD_BUFFERED 0
|
||||
|
||||
/* From OpenVPN tap driver, common.h */
|
||||
#define TAP_CONTROL_CODE(request, method) \
|
||||
CTL_CODE(FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
|
||||
#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE(1, METHOD_BUFFERED)
|
||||
#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE(2, METHOD_BUFFERED)
|
||||
#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE(3, METHOD_BUFFERED)
|
||||
#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE(4, METHOD_BUFFERED)
|
||||
#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE(5, METHOD_BUFFERED)
|
||||
#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE(6, METHOD_BUFFERED)
|
||||
#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE(7, METHOD_BUFFERED)
|
||||
#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE(8, METHOD_BUFFERED)
|
||||
#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE(9, METHOD_BUFFERED)
|
||||
#define TAP_IOCTL_CONFIG_TUN TAP_CONTROL_CODE(10, METHOD_BUFFERED)
|
||||
|
||||
/* Windows registry crap */
|
||||
#define MAX_KEY_LENGTH 255
|
||||
#define MAX_VALUE_NAME 16383
|
||||
#define NETWORK_ADAPTERS \
|
||||
"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-" \
|
||||
"08002BE10318}"
|
||||
|
||||
typedef unsigned long IPADDR;
|
||||
|
||||
namespace llarp::vpn
|
||||
{
|
||||
static char*
|
||||
reg_query(char* key_name)
|
||||
{
|
||||
HKEY adapters, adapter;
|
||||
DWORD i, ret, len;
|
||||
char* deviceid = nullptr;
|
||||
DWORD sub_keys = 0;
|
||||
|
||||
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(key_name), 0, KEY_READ, &adapters);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ret = RegQueryInfoKey(
|
||||
adapters, NULL, NULL, NULL, &sub_keys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (sub_keys <= 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Walk througt all adapters */
|
||||
for (i = 0; i < sub_keys; i++)
|
||||
{
|
||||
char new_key[MAX_KEY_LENGTH];
|
||||
char data[256];
|
||||
TCHAR key[MAX_KEY_LENGTH];
|
||||
DWORD keylen = MAX_KEY_LENGTH;
|
||||
|
||||
/* Get the adapter key name */
|
||||
ret = RegEnumKeyEx(adapters, i, key, &keylen, NULL, NULL, NULL, NULL);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Append it to NETWORK_ADAPTERS and open it */
|
||||
snprintf(new_key, sizeof new_key, "%s\\%s", key_name, key);
|
||||
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(new_key), 0, KEY_READ, &adapter);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check its values */
|
||||
len = sizeof data;
|
||||
ret = RegQueryValueEx(adapter, "ComponentId", NULL, NULL, (LPBYTE)data, &len);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
{
|
||||
/* This value doesn't exist in this adaptater tree */
|
||||
goto clean;
|
||||
}
|
||||
/* If its a tap adapter, its all good */
|
||||
if (strncmp(data, "tap0901", 7) == 0)
|
||||
{
|
||||
DWORD type;
|
||||
|
||||
len = sizeof data;
|
||||
ret = RegQueryValueEx(adapter, "NetCfgInstanceId", NULL, &type, (LPBYTE)data, &len);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
{
|
||||
goto clean;
|
||||
}
|
||||
deviceid = strdup(data);
|
||||
break;
|
||||
}
|
||||
clean:
|
||||
RegCloseKey(adapter);
|
||||
}
|
||||
RegCloseKey(adapters);
|
||||
return deviceid;
|
||||
}
|
||||
|
||||
class Win32Interface : public NetworkInterface
|
||||
{
|
||||
std::atomic<bool> m_Run;
|
||||
HANDLE m_Device, m_IOCP;
|
||||
std::vector<HANDLE> m_Threads;
|
||||
thread::Queue<net::IPPacket> m_ReadQueue;
|
||||
|
||||
const InterfaceInfo m_Info;
|
||||
|
||||
static std::wstring
|
||||
get_win_sys_path()
|
||||
{
|
||||
wchar_t win_sys_path[MAX_PATH] = {0};
|
||||
const wchar_t* default_sys_path = L"C:\\Windows\\system32";
|
||||
|
||||
if (!GetSystemDirectoryW(win_sys_path, _countof(win_sys_path)))
|
||||
{
|
||||
wcsncpy(win_sys_path, default_sys_path, _countof(win_sys_path));
|
||||
win_sys_path[_countof(win_sys_path) - 1] = L'\0';
|
||||
}
|
||||
return win_sys_path;
|
||||
}
|
||||
|
||||
static std::string
|
||||
NetSHCommand()
|
||||
{
|
||||
std::wstring wcmd = get_win_sys_path() + L"\\netsh.exe";
|
||||
|
||||
using convert_type = std::codecvt_utf8<wchar_t>;
|
||||
std::wstring_convert<convert_type, wchar_t> converter;
|
||||
return converter.to_bytes(wcmd);
|
||||
}
|
||||
|
||||
static void
|
||||
NetSH(std::string commands)
|
||||
{
|
||||
commands = NetSHCommand() + " " + commands;
|
||||
::system(commands.c_str());
|
||||
}
|
||||
|
||||
public:
|
||||
Win32Interface(InterfaceInfo info) : m_ReadQueue{1024}, m_Info{std::move(info)}
|
||||
{
|
||||
DWORD len;
|
||||
|
||||
const auto device_id = reg_query(NETWORK_ADAPTERS);
|
||||
if (device_id == nullptr)
|
||||
{
|
||||
LogError("cannot query registry");
|
||||
throw std::invalid_argument{"cannot query registery"};
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss << "\\\\.\\Global\\" << device_id << ".tap";
|
||||
const auto fname = ss.str();
|
||||
m_Device = CreateFile(
|
||||
fname.c_str(),
|
||||
GENERIC_WRITE | GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
0,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
|
||||
0);
|
||||
if (m_Device == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
LogError("failed to open device");
|
||||
throw std::invalid_argument{"cannot open " + fname};
|
||||
}
|
||||
|
||||
LogInfo("putting interface up...");
|
||||
ULONG flag = 1;
|
||||
// put the interface up
|
||||
if (not DeviceIoControl(
|
||||
m_Device,
|
||||
TAP_IOCTL_SET_MEDIA_STATUS,
|
||||
&flag,
|
||||
sizeof(flag),
|
||||
&flag,
|
||||
sizeof(flag),
|
||||
&len,
|
||||
nullptr))
|
||||
{
|
||||
LogError("cannot up interface up");
|
||||
throw std::invalid_argument{"cannot put interface up"};
|
||||
}
|
||||
|
||||
LogInfo("setting addresses");
|
||||
// set ipv4 addresses
|
||||
for (const auto& ifaddr : m_Info.addrs)
|
||||
{
|
||||
if (ifaddr.fam == AF_INET)
|
||||
{
|
||||
IPADDR sock[3]{};
|
||||
const nuint32_t addr = xhtonl(net::TruncateV6(ifaddr.range.addr));
|
||||
const nuint32_t mask = xhtonl(net::TruncateV6(ifaddr.range.netmask_bits));
|
||||
LogInfo("address ", addr, " netmask ", mask);
|
||||
sock[0] = addr.n;
|
||||
sock[1] = addr.n & mask.n;
|
||||
sock[2] = mask.n;
|
||||
|
||||
if (not DeviceIoControl(
|
||||
m_Device,
|
||||
TAP_IOCTL_CONFIG_TUN,
|
||||
&sock,
|
||||
sizeof(sock),
|
||||
&sock,
|
||||
sizeof(sock),
|
||||
&len,
|
||||
nullptr))
|
||||
{
|
||||
LogError("cannot set address");
|
||||
throw std::invalid_argument{"cannot configure tun interface address"};
|
||||
}
|
||||
|
||||
IPADDR ep[4]{};
|
||||
|
||||
ep[0] = addr.n;
|
||||
ep[1] = mask.n;
|
||||
ep[2] = (addr.n | ~mask.n) - htonl(1);
|
||||
ep[3] = 31536000;
|
||||
|
||||
if (not DeviceIoControl(
|
||||
m_Device,
|
||||
TAP_IOCTL_CONFIG_DHCP_MASQ,
|
||||
ep,
|
||||
sizeof(ep),
|
||||
ep,
|
||||
sizeof(ep),
|
||||
&len,
|
||||
nullptr))
|
||||
{
|
||||
LogError("cannot set dhcp masq");
|
||||
throw std::invalid_argument{"Cannot configure tun interface dhcp"};
|
||||
}
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct opt
|
||||
{
|
||||
uint8_t dhcp_opt;
|
||||
uint8_t length;
|
||||
uint32_t value;
|
||||
} dns, gateway;
|
||||
#pragma pack(pop)
|
||||
|
||||
const nuint32_t dnsaddr{xhtonl(m_Info.dnsaddr)};
|
||||
dns.dhcp_opt = 6;
|
||||
dns.length = 4;
|
||||
dns.value = dnsaddr.n;
|
||||
|
||||
gateway.dhcp_opt = 3;
|
||||
gateway.length = 4;
|
||||
gateway.value = addr.n + htonl(1);
|
||||
|
||||
if (not DeviceIoControl(
|
||||
m_Device,
|
||||
TAP_IOCTL_CONFIG_DHCP_SET_OPT,
|
||||
&gateway,
|
||||
sizeof(gateway),
|
||||
&gateway,
|
||||
sizeof(gateway),
|
||||
&len,
|
||||
nullptr))
|
||||
{
|
||||
LogError("cannot set gateway");
|
||||
throw std::invalid_argument{"cannot set tun gateway"};
|
||||
}
|
||||
|
||||
if (not DeviceIoControl(
|
||||
m_Device,
|
||||
TAP_IOCTL_CONFIG_DHCP_SET_OPT,
|
||||
&dns,
|
||||
sizeof(dns),
|
||||
&dns,
|
||||
sizeof(dns),
|
||||
&len,
|
||||
nullptr))
|
||||
{
|
||||
LogError("cannot set dns");
|
||||
throw std::invalid_argument{"cannot set tun dns"};
|
||||
}
|
||||
}
|
||||
}
|
||||
// set ipv6 addresses
|
||||
/*
|
||||
for (const auto& ifaddr : m_Info.addrs)
|
||||
{
|
||||
if (ifaddr.fam == AF_INET6)
|
||||
{
|
||||
IPRange range = ifaddr.range;
|
||||
range.netmask_bits = netmask_ipv6_bits(128);
|
||||
NetSH(
|
||||
"interface ipv6 set address " + std::to_string(ifindex) + " " + range.ToString()
|
||||
+ " store=active");
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
~Win32Interface()
|
||||
{
|
||||
ULONG flag = 0;
|
||||
DWORD len;
|
||||
// put the interface down
|
||||
DeviceIoControl(
|
||||
m_Device,
|
||||
TAP_IOCTL_SET_MEDIA_STATUS,
|
||||
&flag,
|
||||
sizeof(flag),
|
||||
&flag,
|
||||
sizeof(flag),
|
||||
&len,
|
||||
nullptr);
|
||||
m_Run = false;
|
||||
CloseHandle(m_IOCP);
|
||||
// close the handle
|
||||
CloseHandle(m_Device);
|
||||
// close the reader threads
|
||||
for (auto& thread : m_Threads)
|
||||
CloseHandle(thread);
|
||||
}
|
||||
|
||||
int
|
||||
PollFD() const override
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool
|
||||
HasNextPacket() override
|
||||
{
|
||||
return not m_ReadQueue.empty();
|
||||
}
|
||||
|
||||
std::string
|
||||
IfName() const override
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
static DWORD FAR PASCAL
|
||||
Loop(void* u)
|
||||
{
|
||||
static_cast<Win32Interface*>(u)->ReadLoop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Start()
|
||||
{
|
||||
m_Run = true;
|
||||
const auto numThreads = std::thread::hardware_concurrency();
|
||||
m_IOCP = CreateIoCompletionPort(m_Device, nullptr, (ULONG_PTR)this, 1 + numThreads);
|
||||
for (size_t idx = 0; idx < numThreads; ++idx)
|
||||
m_Threads.push_back(CreateThread(nullptr, 0, &Loop, this, 0, nullptr));
|
||||
}
|
||||
|
||||
net::IPPacket
|
||||
ReadNextPacket()
|
||||
{
|
||||
return m_ReadQueue.popFront();
|
||||
}
|
||||
|
||||
struct asio_evt_pkt
|
||||
{
|
||||
explicit asio_evt_pkt(bool _read) : read{_read}
|
||||
{}
|
||||
|
||||
OVERLAPPED hdr = {0, 0, 0, 0, nullptr}; // must be first, since this is part of the IO call
|
||||
bool read;
|
||||
net::IPPacket pkt;
|
||||
|
||||
void
|
||||
Read(HANDLE dev)
|
||||
{
|
||||
ReadFile(dev, pkt.buf, sizeof(pkt.buf), nullptr, &hdr);
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
WritePacket(net::IPPacket pkt)
|
||||
{
|
||||
LogDebug("write packet ", pkt.sz);
|
||||
asio_evt_pkt* ev = new asio_evt_pkt{false};
|
||||
std::copy_n(pkt.buf, pkt.sz, ev->pkt.buf);
|
||||
ev->pkt.sz = pkt.sz;
|
||||
WriteFile(m_Device, ev->pkt.buf, ev->pkt.sz, nullptr, &ev->hdr);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ReadLoop()
|
||||
{
|
||||
std::unique_ptr<asio_evt_pkt> ev = std::make_unique<asio_evt_pkt>(true);
|
||||
ev->Read(m_Device);
|
||||
while (m_Run)
|
||||
{
|
||||
DWORD size;
|
||||
ULONG_PTR user;
|
||||
OVERLAPPED* ovl = nullptr;
|
||||
if (not GetQueuedCompletionStatus(m_IOCP, &size, &user, &ovl, 1000))
|
||||
continue;
|
||||
asio_evt_pkt* pkt = (asio_evt_pkt*)ovl;
|
||||
LogDebug("got iocp event size=", size, " read=", pkt->read);
|
||||
if (pkt->read)
|
||||
{
|
||||
pkt->pkt.sz = size;
|
||||
m_ReadQueue.pushBack(pkt->pkt);
|
||||
pkt->Read(m_Device);
|
||||
}
|
||||
else
|
||||
delete pkt;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Win32Platform : public Platform
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<NetworkInterface>
|
||||
ObtainInterface(InterfaceInfo info) override
|
||||
{
|
||||
auto netif = std::make_shared<Win32Interface>(std::move(info));
|
||||
netif->Start();
|
||||
return netif;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace llarp::vpn
|
@ -1,28 +0,0 @@
|
||||
add_library(tuntap OBJECT
|
||||
libtuntap-master/tuntap.cpp
|
||||
libtuntap-master/tuntap_log.cpp)
|
||||
|
||||
get_target_property(nlohmann_inc nlohmann_json::nlohmann_json INTERFACE_INCLUDE_DIRECTORIES)
|
||||
target_include_directories(tuntap PRIVATE ../llarp ../include ${nlohmann_inc})
|
||||
|
||||
if(WIN32)
|
||||
target_sources(tuntap PRIVATE libtuntap-master/tuntap-windows.c)
|
||||
else()
|
||||
target_sources(tuntap PRIVATE libtuntap-master/tuntap-unix.c)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
|
||||
target_sources(tuntap PRIVATE libtuntap-master/tuntap-unix-linux.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
|
||||
target_sources(tuntap PRIVATE libtuntap-master/tuntap-unix-openbsd.c libtuntap-master/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD")
|
||||
target_sources(tuntap PRIVATE libtuntap-master/tuntap-unix-netbsd.c libtuntap-master/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD|DragonFly")
|
||||
target_sources(tuntap PRIVATE libtuntap-master/tuntap-unix-freebsd.c libtuntap-master/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin|iOS")
|
||||
target_sources(tuntap PRIVATE libtuntap-master/tuntap-unix-darwin.c libtuntap-master/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
||||
target_sources(tuntap PRIVATE libtuntap-master/tuntap-unix-sunos.c)
|
||||
else()
|
||||
message(FATAL_ERROR "Your operating system - ${CMAKE_SYSTEM_NAME} is not supported yet for libtuntap")
|
||||
endif()
|
||||
endif()
|
@ -1,137 +0,0 @@
|
||||
# libtuntap CMakeLists.txt
|
||||
# ========================
|
||||
|
||||
project(libtuntap)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
# CMake global options
|
||||
# --------------------
|
||||
option(ENABLE_REGRESS "Enable the regression tests" OFF)
|
||||
option(ENABLE_CXX "Enable the C++ wrapper library" OFF)
|
||||
option(ENABLE_PYTHON "Enable the Python wrapper library" OFF)
|
||||
|
||||
if(ENABLE_PYTHON AND NOT ENABLE_CXX)
|
||||
set(ENABLE_CXX ON)
|
||||
message(WARNING "ENABLE_CXX also set to ON")
|
||||
endif()
|
||||
|
||||
# CMake Configuration
|
||||
# -------------------
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
set(CMAKE_INSTALL_PREFIX "/usr/local/")
|
||||
set(${CMAKE_SYSTEM_NAME} True)
|
||||
|
||||
# Global CPP definitions
|
||||
# ----------------------
|
||||
add_definitions(-D${CMAKE_SYSTEM_NAME})
|
||||
|
||||
# Portable source files
|
||||
# ---------------------
|
||||
set(SOURCES_LIST
|
||||
tuntap.c
|
||||
tuntap_log.c
|
||||
)
|
||||
|
||||
# OS families specific things
|
||||
# ---------------------------
|
||||
if(UNIX)
|
||||
# Unix specific include directories
|
||||
# ---------------------------------
|
||||
include_directories(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
/usr/include/
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
# Unix specific definitions
|
||||
# -------------------------
|
||||
add_definitions(-DUnix)
|
||||
|
||||
# Unix specific source files
|
||||
# --------------------------
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-unix.c )
|
||||
endif(UNIX)
|
||||
|
||||
if(Windows)
|
||||
# Windows specific definitions
|
||||
# ----------------------------
|
||||
add_definitions(-DWindows)
|
||||
|
||||
# Windows specific source files
|
||||
# -----------------------------
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-windows.c )
|
||||
endif(Windows)
|
||||
|
||||
# OS specific things
|
||||
# ------------------
|
||||
if(UNIX)
|
||||
if(Linux)
|
||||
set(CMAKE_INSTALL_PREFIX "/usr/")
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-unix-linux.c)
|
||||
elseif (OpenBSD)
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-unix-openbsd.c)
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-unix-bsd.c)
|
||||
elseif (NetBSD)
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-unix-netbsd.c)
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-unix-bsd.c)
|
||||
elseif (FreeBSD)
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-unix-freebsd.c)
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-unix-bsd.c)
|
||||
elseif (Darwin)
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-unix-darwin.c)
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-unix-bsd.c)
|
||||
elseif (DragonFly)
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-unix-freebsd.c)
|
||||
set(SOURCES_LIST ${SOURCES_LIST} tuntap-unix-bsd.c)
|
||||
else()
|
||||
message(FATAL_ERROR "Your operating system is not supported yet")
|
||||
endif()
|
||||
endif(UNIX)
|
||||
|
||||
# Library definition
|
||||
# ------------------
|
||||
add_library(tuntap SHARED ${SOURCES_LIST} tuntap.h)
|
||||
set_target_properties(tuntap PROPERTIES VERSION 2.1)
|
||||
|
||||
add_library(tuntap-static STATIC ${SOURCES_LIST})
|
||||
set_target_properties(tuntap-static PROPERTIES OUTPUT_NAME "tuntap")
|
||||
if(UNIX)
|
||||
set_target_properties(tuntap-static PROPERTIES PREFIX "lib")
|
||||
endif(UNIX)
|
||||
|
||||
if(Windows)
|
||||
target_link_libraries(tuntap Ws2_32.lib)
|
||||
target_link_libraries(tuntap-static Ws2_32.lib)
|
||||
endif(Windows)
|
||||
|
||||
# C++ Binding definition
|
||||
# ----------------------
|
||||
if(ENABLE_CXX)
|
||||
include(bindings/cpp/CMakeLists.txt)
|
||||
endif(ENABLE_CXX)
|
||||
|
||||
# Python Binding definition
|
||||
# -------------------------
|
||||
if(ENABLE_PYTHON)
|
||||
include(bindings/python/CMakeLists.txt)
|
||||
endif (ENABLE_PYTHON)
|
||||
|
||||
# Install rules
|
||||
# -------------
|
||||
if(UNIX)
|
||||
install(TARGETS tuntap DESTINATION lib)
|
||||
install(TARGETS tuntap-static DESTINATION lib)
|
||||
install(FILES tuntap.h DESTINATION include)
|
||||
target_include_directories(tuntap INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif(UNIX)
|
||||
|
||||
include(CMakeLists.txt.local OPTIONAL)
|
||||
|
||||
# Tests rules
|
||||
# -----------
|
||||
if (ENABLE_REGRESS)
|
||||
include(regress/CMakeLists.txt)
|
||||
endif (ENABLE_REGRESS)
|
||||
|
@ -1,377 +0,0 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Generated by "Unix Makefiles" Generator, CMake Version 3.9
|
||||
|
||||
# Default target executed when no arguments are given to make.
|
||||
default_target: all
|
||||
|
||||
.PHONY : default_target
|
||||
|
||||
# Allow only one "make -f Makefile2" at a time, but pass parallelism.
|
||||
.NOTPARALLEL:
|
||||
|
||||
|
||||
#=============================================================================
|
||||
# Special targets provided by cmake.
|
||||
|
||||
# Disable implicit rules so canonical targets will work.
|
||||
.SUFFIXES:
|
||||
|
||||
|
||||
# Remove some rules from gmake that .SUFFIXES does not remove.
|
||||
SUFFIXES =
|
||||
|
||||
.SUFFIXES: .hpux_make_needs_suffix_list
|
||||
|
||||
|
||||
# Suppress display of executed commands.
|
||||
$(VERBOSE).SILENT:
|
||||
|
||||
|
||||
# A target that is always out of date.
|
||||
cmake_force:
|
||||
|
||||
.PHONY : cmake_force
|
||||
|
||||
#=============================================================================
|
||||
# Set environment variables for the build.
|
||||
|
||||
# The shell in which to execute make rules.
|
||||
SHELL = /bin/sh
|
||||
|
||||
# The CMake executable.
|
||||
CMAKE_COMMAND = /usr/local/bin/cmake
|
||||
|
||||
# The command to remove a file.
|
||||
RM = /usr/local/bin/cmake -E remove -f
|
||||
|
||||
# Escaping for special characters.
|
||||
EQUALS = =
|
||||
|
||||
# The top-level source directory on which CMake was run.
|
||||
CMAKE_SOURCE_DIR = /Users/rtharp/Sites/llarp/vendor/libtuntap-master
|
||||
|
||||
# The top-level build directory on which CMake was run.
|
||||
CMAKE_BINARY_DIR = /Users/rtharp/Sites/llarp/vendor/libtuntap-master
|
||||
|
||||
#=============================================================================
|
||||
# Targets provided globally by CMake.
|
||||
|
||||
# Special rule for the target install/local
|
||||
install/local: preinstall
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
|
||||
/usr/local/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
|
||||
.PHONY : install/local
|
||||
|
||||
# Special rule for the target install/local
|
||||
install/local/fast: preinstall/fast
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
|
||||
/usr/local/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
|
||||
.PHONY : install/local/fast
|
||||
|
||||
# Special rule for the target install/strip
|
||||
install/strip: preinstall
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
|
||||
/usr/local/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
|
||||
.PHONY : install/strip
|
||||
|
||||
# Special rule for the target install/strip
|
||||
install/strip/fast: preinstall/fast
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
|
||||
/usr/local/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
|
||||
.PHONY : install/strip/fast
|
||||
|
||||
# Special rule for the target install
|
||||
install: preinstall
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
|
||||
/usr/local/bin/cmake -P cmake_install.cmake
|
||||
.PHONY : install
|
||||
|
||||
# Special rule for the target install
|
||||
install/fast: preinstall/fast
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
|
||||
/usr/local/bin/cmake -P cmake_install.cmake
|
||||
.PHONY : install/fast
|
||||
|
||||
# Special rule for the target list_install_components
|
||||
list_install_components:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\""
|
||||
.PHONY : list_install_components
|
||||
|
||||
# Special rule for the target list_install_components
|
||||
list_install_components/fast: list_install_components
|
||||
|
||||
.PHONY : list_install_components/fast
|
||||
|
||||
# Special rule for the target rebuild_cache
|
||||
rebuild_cache:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
|
||||
/usr/local/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
|
||||
.PHONY : rebuild_cache
|
||||
|
||||
# Special rule for the target rebuild_cache
|
||||
rebuild_cache/fast: rebuild_cache
|
||||
|
||||
.PHONY : rebuild_cache/fast
|
||||
|
||||
# Special rule for the target edit_cache
|
||||
edit_cache:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
|
||||
/usr/local/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
|
||||
.PHONY : edit_cache
|
||||
|
||||
# Special rule for the target edit_cache
|
||||
edit_cache/fast: edit_cache
|
||||
|
||||
.PHONY : edit_cache/fast
|
||||
|
||||
# The main all target
|
||||
all: cmake_check_build_system
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/rtharp/Sites/llarp/vendor/libtuntap-master/CMakeFiles /Users/rtharp/Sites/llarp/vendor/libtuntap-master/CMakeFiles/progress.marks
|
||||
$(MAKE) -f CMakeFiles/Makefile2 all
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/rtharp/Sites/llarp/vendor/libtuntap-master/CMakeFiles 0
|
||||
.PHONY : all
|
||||
|
||||
# The main clean target
|
||||
clean:
|
||||
$(MAKE) -f CMakeFiles/Makefile2 clean
|
||||
.PHONY : clean
|
||||
|
||||
# The main clean target
|
||||
clean/fast: clean
|
||||
|
||||
.PHONY : clean/fast
|
||||
|
||||
# Prepare targets for installation.
|
||||
preinstall: all
|
||||
$(MAKE) -f CMakeFiles/Makefile2 preinstall
|
||||
.PHONY : preinstall
|
||||
|
||||
# Prepare targets for installation.
|
||||
preinstall/fast:
|
||||
$(MAKE) -f CMakeFiles/Makefile2 preinstall
|
||||
.PHONY : preinstall/fast
|
||||
|
||||
# clear depends
|
||||
depend:
|
||||
$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
|
||||
.PHONY : depend
|
||||
|
||||
#=============================================================================
|
||||
# Target rules for targets named tuntap-static
|
||||
|
||||
# Build rule for target.
|
||||
tuntap-static: cmake_check_build_system
|
||||
$(MAKE) -f CMakeFiles/Makefile2 tuntap-static
|
||||
.PHONY : tuntap-static
|
||||
|
||||
# fast build rule for target.
|
||||
tuntap-static/fast:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/build
|
||||
.PHONY : tuntap-static/fast
|
||||
|
||||
#=============================================================================
|
||||
# Target rules for targets named tuntap
|
||||
|
||||
# Build rule for target.
|
||||
tuntap: cmake_check_build_system
|
||||
$(MAKE) -f CMakeFiles/Makefile2 tuntap
|
||||
.PHONY : tuntap
|
||||
|
||||
# fast build rule for target.
|
||||
tuntap/fast:
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/build
|
||||
.PHONY : tuntap/fast
|
||||
|
||||
tuntap-unix-bsd.o: tuntap-unix-bsd.c.o
|
||||
|
||||
.PHONY : tuntap-unix-bsd.o
|
||||
|
||||
# target to build an object file
|
||||
tuntap-unix-bsd.c.o:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap-unix-bsd.c.o
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap-unix-bsd.c.o
|
||||
.PHONY : tuntap-unix-bsd.c.o
|
||||
|
||||
tuntap-unix-bsd.i: tuntap-unix-bsd.c.i
|
||||
|
||||
.PHONY : tuntap-unix-bsd.i
|
||||
|
||||
# target to preprocess a source file
|
||||
tuntap-unix-bsd.c.i:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap-unix-bsd.c.i
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap-unix-bsd.c.i
|
||||
.PHONY : tuntap-unix-bsd.c.i
|
||||
|
||||
tuntap-unix-bsd.s: tuntap-unix-bsd.c.s
|
||||
|
||||
.PHONY : tuntap-unix-bsd.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
tuntap-unix-bsd.c.s:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap-unix-bsd.c.s
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap-unix-bsd.c.s
|
||||
.PHONY : tuntap-unix-bsd.c.s
|
||||
|
||||
tuntap-unix-darwin.o: tuntap-unix-darwin.c.o
|
||||
|
||||
.PHONY : tuntap-unix-darwin.o
|
||||
|
||||
# target to build an object file
|
||||
tuntap-unix-darwin.c.o:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap-unix-darwin.c.o
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap-unix-darwin.c.o
|
||||
.PHONY : tuntap-unix-darwin.c.o
|
||||
|
||||
tuntap-unix-darwin.i: tuntap-unix-darwin.c.i
|
||||
|
||||
.PHONY : tuntap-unix-darwin.i
|
||||
|
||||
# target to preprocess a source file
|
||||
tuntap-unix-darwin.c.i:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap-unix-darwin.c.i
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap-unix-darwin.c.i
|
||||
.PHONY : tuntap-unix-darwin.c.i
|
||||
|
||||
tuntap-unix-darwin.s: tuntap-unix-darwin.c.s
|
||||
|
||||
.PHONY : tuntap-unix-darwin.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
tuntap-unix-darwin.c.s:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap-unix-darwin.c.s
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap-unix-darwin.c.s
|
||||
.PHONY : tuntap-unix-darwin.c.s
|
||||
|
||||
tuntap-unix.o: tuntap-unix.c.o
|
||||
|
||||
.PHONY : tuntap-unix.o
|
||||
|
||||
# target to build an object file
|
||||
tuntap-unix.c.o:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap-unix.c.o
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap-unix.c.o
|
||||
.PHONY : tuntap-unix.c.o
|
||||
|
||||
tuntap-unix.i: tuntap-unix.c.i
|
||||
|
||||
.PHONY : tuntap-unix.i
|
||||
|
||||
# target to preprocess a source file
|
||||
tuntap-unix.c.i:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap-unix.c.i
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap-unix.c.i
|
||||
.PHONY : tuntap-unix.c.i
|
||||
|
||||
tuntap-unix.s: tuntap-unix.c.s
|
||||
|
||||
.PHONY : tuntap-unix.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
tuntap-unix.c.s:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap-unix.c.s
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap-unix.c.s
|
||||
.PHONY : tuntap-unix.c.s
|
||||
|
||||
tuntap.o: tuntap.c.o
|
||||
|
||||
.PHONY : tuntap.o
|
||||
|
||||
# target to build an object file
|
||||
tuntap.c.o:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap.c.o
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap.c.o
|
||||
.PHONY : tuntap.c.o
|
||||
|
||||
tuntap.i: tuntap.c.i
|
||||
|
||||
.PHONY : tuntap.i
|
||||
|
||||
# target to preprocess a source file
|
||||
tuntap.c.i:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap.c.i
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap.c.i
|
||||
.PHONY : tuntap.c.i
|
||||
|
||||
tuntap.s: tuntap.c.s
|
||||
|
||||
.PHONY : tuntap.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
tuntap.c.s:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap.c.s
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap.c.s
|
||||
.PHONY : tuntap.c.s
|
||||
|
||||
tuntap_log.o: tuntap_log.c.o
|
||||
|
||||
.PHONY : tuntap_log.o
|
||||
|
||||
# target to build an object file
|
||||
tuntap_log.c.o:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap_log.c.o
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap_log.c.o
|
||||
.PHONY : tuntap_log.c.o
|
||||
|
||||
tuntap_log.i: tuntap_log.c.i
|
||||
|
||||
.PHONY : tuntap_log.i
|
||||
|
||||
# target to preprocess a source file
|
||||
tuntap_log.c.i:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap_log.c.i
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap_log.c.i
|
||||
.PHONY : tuntap_log.c.i
|
||||
|
||||
tuntap_log.s: tuntap_log.c.s
|
||||
|
||||
.PHONY : tuntap_log.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
tuntap_log.c.s:
|
||||
$(MAKE) -f CMakeFiles/tuntap-static.dir/build.make CMakeFiles/tuntap-static.dir/tuntap_log.c.s
|
||||
$(MAKE) -f CMakeFiles/tuntap.dir/build.make CMakeFiles/tuntap.dir/tuntap_log.c.s
|
||||
.PHONY : tuntap_log.c.s
|
||||
|
||||
# Help Target
|
||||
help:
|
||||
@echo "The following are some of the valid targets for this Makefile:"
|
||||
@echo "... all (the default if no target is provided)"
|
||||
@echo "... clean"
|
||||
@echo "... depend"
|
||||
@echo "... install/local"
|
||||
@echo "... install/strip"
|
||||
@echo "... install"
|
||||
@echo "... list_install_components"
|
||||
@echo "... tuntap-static"
|
||||
@echo "... rebuild_cache"
|
||||
@echo "... edit_cache"
|
||||
@echo "... tuntap"
|
||||
@echo "... tuntap-unix-bsd.o"
|
||||
@echo "... tuntap-unix-bsd.i"
|
||||
@echo "... tuntap-unix-bsd.s"
|
||||
@echo "... tuntap-unix-darwin.o"
|
||||
@echo "... tuntap-unix-darwin.i"
|
||||
@echo "... tuntap-unix-darwin.s"
|
||||
@echo "... tuntap-unix.o"
|
||||
@echo "... tuntap-unix.i"
|
||||
@echo "... tuntap-unix.s"
|
||||
@echo "... tuntap.o"
|
||||
@echo "... tuntap.i"
|
||||
@echo "... tuntap.s"
|
||||
@echo "... tuntap_log.o"
|
||||
@echo "... tuntap_log.i"
|
||||
@echo "... tuntap_log.s"
|
||||
.PHONY : help
|
||||
|
||||
|
||||
|
||||
#=============================================================================
|
||||
# Special targets to cleanup operation of make.
|
||||
|
||||
# Special rule to run CMake to check the build system integrity.
|
||||
# No rule that depends on this can have commands that come from listfiles
|
||||
# because they might be regenerated.
|
||||
cmake_check_build_system:
|
||||
$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
|
||||
.PHONY : cmake_check_build_system
|
||||
|
@ -1,53 +0,0 @@
|
||||
libtuntap
|
||||
=========
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
libtuntap is a library for configuring TUN or TAP devices in a portable manner.
|
||||
|
||||
TUN and TAP are virtual networking devices which allow userland applications
|
||||
to receive packets sent to it. The userland applications can also send their
|
||||
own packets to the devices and they will be forwarded to the kernel.
|
||||
|
||||
This is useful for developping tunnels, private networks or virtualisation
|
||||
systems.
|
||||
|
||||
Supported Features
|
||||
------------------
|
||||
|
||||
* Creation of TUN _and_ TAP devices;
|
||||
* Autodetection of available TUN or TAP devices;
|
||||
* Setting and getting the MAC address of the device;
|
||||
* Setting and getting the MTU of the device;
|
||||
* Setting the status of the device (up/down);
|
||||
* Setting the IPv4 address and netmask of the device;
|
||||
* Setting the persistence mode of the device;
|
||||
* Setting the name of the device (Linux only);
|
||||
* Setting the description of the device (OpenBSD and FreeBSD only).
|
||||
|
||||
Supported Systems
|
||||
-----------------
|
||||
|
||||
* OpenBSD;
|
||||
* Linux;
|
||||
* NetBSD;
|
||||
* Darwin.
|
||||
|
||||
Current Porting Efforts
|
||||
-----------------------
|
||||
|
||||
* Windows;
|
||||
* FreeBSD.
|
||||
|
||||
In the future
|
||||
-------------
|
||||
|
||||
* AIX;
|
||||
* Solaris.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
All the code is licensed under the ISC License.
|
||||
It's free, not GPLed !
|
@ -1,17 +0,0 @@
|
||||
# TODO
|
||||
|
||||
- [ ] Create a system of automatic testing with VMs
|
||||
- [X] OpenBSD vm
|
||||
- [X] Debian vm
|
||||
- [ ] Import some patches from dev branch in master
|
||||
- [ ] tuntap_get_descr() is not implemented in master
|
||||
- [X] Test on OpenBSD (not working)
|
||||
- [ ] Fix tuntap-unix-openbsd.c
|
||||
- [ ] Test on NetBSD
|
||||
- [ ] Test on FreeBSD
|
||||
- [ ] Test on Darwin
|
||||
- [X] Test on Debian (working)
|
||||
- [ ] Fix shell scripts based tests test35 and test36
|
||||
- [ ] Test on FreeBSD
|
||||
- [ ] Test on Windows
|
||||
- [ ] Move away from cmake?
|
@ -1,7 +0,0 @@
|
||||
libtuntap bindings
|
||||
==================
|
||||
|
||||
libtuntap supports bindings in C++ and Python, thanks to Fabien Pichot
|
||||
(@drepdash on Github). This is a work in progress.
|
||||
|
||||
Support for more languages is planned.
|
@ -1,24 +0,0 @@
|
||||
# libtuntap C++ binding CMakeLists.txt
|
||||
# ====================================
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bindings/cpp
|
||||
)
|
||||
|
||||
add_library(tuntap++ SHARED
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bindings/cpp/tuntap++.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bindings/cpp/tuntap++.hh
|
||||
)
|
||||
set_target_properties(tuntap++ PROPERTIES VERSION 2.1)
|
||||
|
||||
add_library(tuntap++-static STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bindings/cpp/tuntap++.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bindings/cpp/tuntap++.hh
|
||||
)
|
||||
set_target_properties(tuntap++-static PROPERTIES OUTPUT_NAME "tuntap++")
|
||||
|
||||
target_link_libraries(tuntap++ tuntap)
|
||||
|
||||
target_link_libraries(tuntap++-static tuntap)
|
||||
|
||||
target_include_directories(tuntap++ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bindings/cpp)
|
@ -1,176 +0,0 @@
|
||||
#include "tuntap++.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
namespace tuntap {
|
||||
|
||||
tun::tun()
|
||||
: _dev{tuntap_init()}
|
||||
{
|
||||
tuntap_start(_dev, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY);
|
||||
}
|
||||
|
||||
tun::~tun()
|
||||
{
|
||||
tuntap_destroy(_dev);
|
||||
}
|
||||
|
||||
tun::tun(tun &&t)
|
||||
: _dev(nullptr)
|
||||
{
|
||||
std::swap(t._dev, this->_dev);
|
||||
}
|
||||
|
||||
void
|
||||
tun::release()
|
||||
{
|
||||
tuntap_release(_dev);
|
||||
}
|
||||
|
||||
std::string
|
||||
tun::name() const
|
||||
{
|
||||
return tuntap_get_ifname(_dev);
|
||||
}
|
||||
|
||||
void
|
||||
tun::name(std::string const &s)
|
||||
{
|
||||
tuntap_set_ifname(_dev, s.c_str());
|
||||
}
|
||||
|
||||
t_tun
|
||||
tun::native_handle() const
|
||||
{
|
||||
return TUNTAP_GET_FD(this->_dev);
|
||||
}
|
||||
|
||||
void
|
||||
tun::up()
|
||||
{
|
||||
tuntap_up(_dev);
|
||||
}
|
||||
|
||||
void
|
||||
tun::down()
|
||||
{
|
||||
tuntap_down(_dev);
|
||||
}
|
||||
|
||||
int
|
||||
tun::mtu() const
|
||||
{
|
||||
return tuntap_get_mtu(_dev);
|
||||
}
|
||||
|
||||
void
|
||||
tun::mtu(int m)
|
||||
{
|
||||
tuntap_set_mtu(_dev, m);
|
||||
}
|
||||
|
||||
void
|
||||
tun::ip(std::string const &s, int netmask)
|
||||
{
|
||||
tuntap_set_ip(_dev, s.c_str(), netmask);
|
||||
}
|
||||
|
||||
void
|
||||
tun::nonblocking(bool b)
|
||||
{
|
||||
tuntap_set_nonblocking(_dev, int(b));
|
||||
}
|
||||
|
||||
tap::tap()
|
||||
: _dev{tuntap_init()}
|
||||
{
|
||||
tuntap_start(_dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY);
|
||||
}
|
||||
|
||||
tap::~tap()
|
||||
{
|
||||
tuntap_destroy(_dev);
|
||||
}
|
||||
|
||||
tap::tap(tap &&t)
|
||||
: _dev(nullptr)
|
||||
{
|
||||
std::swap(t._dev, this->_dev);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tap::release()
|
||||
{
|
||||
tuntap_release(_dev);
|
||||
}
|
||||
|
||||
std::string
|
||||
tap::name() const
|
||||
{
|
||||
return tuntap_get_ifname(_dev);
|
||||
}
|
||||
|
||||
void
|
||||
tap::name(std::string const &s)
|
||||
{
|
||||
tuntap_set_ifname(_dev, s.c_str());
|
||||
}
|
||||
|
||||
std::string
|
||||
tap::hwaddr() const
|
||||
{
|
||||
return tuntap_get_hwaddr(_dev);
|
||||
}
|
||||
|
||||
void
|
||||
tap::hwaddr(std::string const &s)
|
||||
{
|
||||
tuntap_set_hwaddr(_dev, s.c_str());
|
||||
}
|
||||
|
||||
t_tun
|
||||
tap::native_handle() const
|
||||
{
|
||||
return TUNTAP_GET_FD(this->_dev);
|
||||
}
|
||||
|
||||
void
|
||||
tap::up()
|
||||
{
|
||||
tuntap_up(_dev);
|
||||
}
|
||||
|
||||
void
|
||||
tap::down()
|
||||
{
|
||||
tuntap_down(_dev);
|
||||
}
|
||||
|
||||
int
|
||||
tap::mtu() const
|
||||
{
|
||||
return tuntap_get_mtu(_dev);
|
||||
}
|
||||
|
||||
void
|
||||
tap::mtu(int m)
|
||||
{
|
||||
tuntap_set_mtu(_dev, m);
|
||||
}
|
||||
|
||||
void
|
||||
tap::ip(std::string const &s, int netmask)
|
||||
{
|
||||
tuntap_set_ip(_dev, s.c_str(), netmask);
|
||||
}
|
||||
|
||||
void
|
||||
tap::nonblocking(bool b)
|
||||
{
|
||||
tuntap_set_nonblocking(_dev, int(b));
|
||||
}
|
||||
|
||||
} /* tuntap */
|
@ -1,72 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef LIBTUNTAP_ALY0MA60
|
||||
#define LIBTUNTAP_ALY0MA60
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <tuntap.h>
|
||||
|
||||
namespace tuntap {
|
||||
|
||||
class tun
|
||||
{
|
||||
public:
|
||||
tun();
|
||||
~tun();
|
||||
tun(tun const &) = delete;
|
||||
tun & operator = (tun const &) = delete;
|
||||
tun(tun &&);
|
||||
|
||||
// Properties
|
||||
std::string name() const;
|
||||
void name(std::string const &);
|
||||
int mtu() const ;
|
||||
void mtu(int);
|
||||
t_tun native_handle() const;
|
||||
|
||||
// Network
|
||||
void up();
|
||||
void down();
|
||||
void ip(std::string const &presentation, int netmask);
|
||||
|
||||
// System
|
||||
void release();
|
||||
void nonblocking(bool);
|
||||
private:
|
||||
struct device* _dev;
|
||||
};
|
||||
|
||||
class tap
|
||||
{
|
||||
public:
|
||||
tap();
|
||||
~tap();
|
||||
tap(tap const &) = delete;
|
||||
tap & operator = (tap const &) = delete;
|
||||
tap(tap &&);
|
||||
|
||||
// Properties
|
||||
std::string name() const;
|
||||
void name(std::string const &);
|
||||
std::string hwaddr() const;
|
||||
void hwaddr(std::string const &);
|
||||
int mtu() const;
|
||||
void mtu(int);
|
||||
t_tun native_handle() const;
|
||||
|
||||
// Network
|
||||
void up();
|
||||
void down();
|
||||
void ip(std::string const &presentation, int netmask);
|
||||
|
||||
// System
|
||||
void release();
|
||||
void nonblocking(bool);
|
||||
private:
|
||||
struct device* _dev;
|
||||
};
|
||||
|
||||
} /* tuntap */
|
||||
|
||||
|
||||
#endif /* end of include guard: LIBTUNTAP_ALY0MA60 */
|
@ -1,32 +0,0 @@
|
||||
# libtuntap python binding CMakeLists.txt
|
||||
# =======================================
|
||||
|
||||
find_package(PythonLibs)
|
||||
find_package(Boost COMPONENTS system thread python)
|
||||
|
||||
if(${PYTHONLIBS_FOUND} AND ${Boost_FOUND})
|
||||
include_directories(${PYTHON_INCLUDE_PATH})
|
||||
include_directories(${Boost_INCLUDE_PATH})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/bindings/cpp)
|
||||
|
||||
add_library(python-tuntap SHARED
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bindings/python/pytuntap.cc
|
||||
)
|
||||
target_link_libraries(python-tuntap
|
||||
${PYTHON_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
tuntap++
|
||||
)
|
||||
add_custom_command(TARGET python-tuntap POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${PROJECT_SOURCE_DIR}/bindings/python/__init__.py"
|
||||
"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/bindings/python/pytuntap"
|
||||
)
|
||||
set_target_properties(python-tuntap PROPERTIES OUTPUT_NAME "_pytuntap")
|
||||
set_target_properties(python-tuntap PROPERTIES PREFIX "")
|
||||
set_target_properties(python-tuntap
|
||||
PROPERTIES LIBRARY_OUTPUT_DIRECTORY
|
||||
${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/bindings/python/pytuntap
|
||||
)
|
||||
endif()
|
||||
|
@ -1,24 +0,0 @@
|
||||
from _pytuntap import *
|
||||
import io
|
||||
|
||||
class TunTapFileIO(io.FileIO):
|
||||
def __init__(self, tuntap):
|
||||
super(TunTapFileIO, self).__init__(tuntap.native_handle, 'rb+')
|
||||
|
||||
def read(self, size):
|
||||
return memoryview(bytearray(super(TunTapFileIO, self).read(size)))
|
||||
|
||||
def readinto():
|
||||
raise NotImplementedError
|
||||
|
||||
def readall():
|
||||
raise NotImplementedError
|
||||
|
||||
def writelines():
|
||||
raise NotImplementedError
|
||||
|
||||
def _file(self):
|
||||
return TunTapFileIO(self)
|
||||
|
||||
Tap.file = _file
|
||||
Tun.file = _file
|
@ -1,44 +0,0 @@
|
||||
#include "tuntap++.hh"
|
||||
#include <boost/python.hpp>
|
||||
|
||||
BOOST_PYTHON_MODULE(_pytuntap)
|
||||
{
|
||||
using namespace tuntap;
|
||||
using namespace boost::python;
|
||||
|
||||
std::string (tap::*tap_get_name)() const = &tap::name;
|
||||
void (tap::*tap_set_name)(std::string const &) = &tap::name;
|
||||
std::string (tap::*tap_get_hwaddr)() const = &tap::hwaddr;
|
||||
void (tap::*tap_set_hwaddr)(std::string const &) = &tap::hwaddr;
|
||||
int (tap::*tap_get_mtu)() const = &tap::mtu;
|
||||
void (tap::*tap_set_mtu)(int) = &tap::mtu;
|
||||
|
||||
std::string (tun::*tun_get_name)() const = &tun::name;
|
||||
void (tun::*tun_set_name)(std::string const &) = &tun::name;
|
||||
int (tun::*tun_get_mtu)() const = &tun::mtu;
|
||||
void (tun::*tun_set_mtu)(int) = &tun::mtu;
|
||||
|
||||
def("tuntap_version", tuntap_version);
|
||||
|
||||
class_<tun, boost::noncopyable>("Tun", init<>())
|
||||
.def("release", &tun::release)
|
||||
.def("up", &tun::up)
|
||||
.def("down", &tun::down)
|
||||
.def("ip", &tun::ip)
|
||||
.def("nonblocking", &tun::nonblocking)
|
||||
.add_property("name", tun_get_name, tun_set_name)
|
||||
.add_property("mtu", tun_get_mtu, tun_set_mtu)
|
||||
.add_property("native_handle", &tun::native_handle)
|
||||
;
|
||||
class_<tap, boost::noncopyable>("Tap", init<>())
|
||||
.def("release", &tap::release)
|
||||
.def("up", &tap::up)
|
||||
.def("down", &tap::down)
|
||||
.def("ip", &tap::ip)
|
||||
.def("nonblocking", &tap::nonblocking)
|
||||
.add_property("name", tap_get_name, tap_set_name)
|
||||
.add_property("hwaddr", tap_set_hwaddr, tap_set_hwaddr)
|
||||
.add_property("mtu", tap_set_mtu, tap_set_mtu)
|
||||
.add_property("native_handle", &tap::native_handle)
|
||||
;
|
||||
}
|
@ -1,327 +0,0 @@
|
||||
API
|
||||
===
|
||||
|
||||
Types
|
||||
=====
|
||||
|
||||
struct device
|
||||
-------------
|
||||
|
||||
The `struct device` is an opaque structure containing internal parameter, like the device name, device flags, device file descriptor, etc. You should not access them.
|
||||
|
||||
The structure size may vary from an operating system to an other, you should not rely on it.
|
||||
|
||||
t_tuntap_log
|
||||
------------
|
||||
|
||||
typedef void (*t_tuntap_log)(int level, const char *msg);
|
||||
|
||||
This type is a pointer to a log function. It allows to override the default behaviour, which is printing every messages on the error output prefixed with its error level.
|
||||
|
||||
Error levels are described later, they are macros in the form `TUNTAP_LOG_*`.
|
||||
|
||||
t_tun
|
||||
-----
|
||||
|
||||
The `t_tun` type map the file descriptor type of a given operating system.
|
||||
|
||||
Typically it's an `int` on UNIXes and a `HANDLE` on Windows.
|
||||
|
||||
Macros
|
||||
======
|
||||
|
||||
There is two type of macros, the libtuntap ones, and the "portable" ones. The laters are here to help portable parts of the code to rely on meaningful names, not hard-coded magic values.
|
||||
|
||||
libtuntap macros
|
||||
----------------
|
||||
|
||||
TUNTAP_ID_MAX
|
||||
-------------
|
||||
|
||||
`TUNTAP_ID_MAX` is the maximal device unit giveable as the third parameter of `tuntap_start()`.
|
||||
|
||||
TUNTAP_ID_ANY
|
||||
-------------
|
||||
|
||||
`TUNTAP_ID_ANY` is the wild-card device unit giveable as the third parameter of `tuntap_start()`.
|
||||
|
||||
TUNTAP_MODE_ETHERNET
|
||||
--------------------
|
||||
|
||||
`TUNTAP_MODE_ETHERNET` is the tap-mode giveable as the second parameter of `tuntap_start()`.
|
||||
|
||||
TUNTAP_MODE_TUNNEL
|
||||
------------------
|
||||
|
||||
`TUNTAP_MODE_TUNNEL` is the tun-mode giveable as the second parameter of `tuntap_start()`.
|
||||
|
||||
TUNTAP_MODE_PERSIST
|
||||
-------------------
|
||||
|
||||
`TUNTAP_MODE_PERSIST` is the persistence flag giveable OR'ed with the second parameter of `tuntap_start()`.
|
||||
|
||||
This flag is optional and should be used with either `TUNTAP_MODE_TUNNEL` or `TUNTAP_MODE_ETHERNET`.
|
||||
|
||||
TUNTAP_LOG_ERR
|
||||
--------------
|
||||
|
||||
`TUNTAP_LOG_ERR` describes an error message.
|
||||
|
||||
TUNTAP_LOG_WARN
|
||||
---------------
|
||||
|
||||
`TUNTAP_LOG_WARN` describes a warning message.
|
||||
|
||||
TUNTAP_LOG_INFO
|
||||
---------------
|
||||
|
||||
`TUNTAP_LOG_INFO` describes an informational message.
|
||||
|
||||
TUNTAP_LOG_NOTICE
|
||||
-----------------
|
||||
|
||||
`TUNTAP_LOG_NOTICE` describes a message which is not really an error nor a warning. It is mostly used to warn about unimplemented or unavailable part of the libtuntap.
|
||||
|
||||
TUNTAP_LOG_DEBUG
|
||||
----------------
|
||||
|
||||
`TUNTAP_LOG_DEBUG` describes a debug messages. You should see one only if your are using the git HEAD.
|
||||
|
||||
TUNTAP_LOG_NONE
|
||||
---------------
|
||||
|
||||
`TUNTAP_LOG_NONE` describes other things. It is only used by `tuntap_log_hexdump()` and `tuntap_log_chksum()`.
|
||||
|
||||
Portable macros
|
||||
---------------
|
||||
|
||||
ETHER_ADDR_LEN
|
||||
--------------
|
||||
|
||||
`ETHER_ADDR_LEN` is a value dictated by [[http://www.ieee802.org/3/|IEEE 802.3]] standard.
|
||||
On Linux systems its value is mapped on `ETH_ALEN` one.
|
||||
|
||||
IF_NAMESIZE
|
||||
-----------
|
||||
|
||||
`IF_NAMESIZE` gives the maximal length of an interface name.
|
||||
On BSD systems its value is mapped on `IFNAMSIZ` one.
|
||||
|
||||
IF_DESCRSIZE
|
||||
------------
|
||||
|
||||
`IF_DESCSIZE` gives the maximal length of an interface description.
|
||||
|
||||
TUNFD_INVALID_VALUE
|
||||
-------------------
|
||||
|
||||
`TUNFD_INVALID_VALUE` is the invalid value of the t_tun type.
|
||||
On UNIXes systems its value is `-1`.
|
||||
On Windows systems its value is `INVALID_HANDLE_VALUE`.
|
||||
|
||||
Functions
|
||||
=========
|
||||
|
||||
tuntap_init
|
||||
-----------
|
||||
|
||||
struct device *tuntap_init(void);
|
||||
|
||||
This function will allocate and initialise a `struct device`.
|
||||
|
||||
tuntap_version
|
||||
--------------
|
||||
|
||||
int tuntap_version(void);
|
||||
|
||||
This function returns the version number of libtuntap.
|
||||
You can extract the major and the minor like this:
|
||||
|
||||
int version = tuntap_version();
|
||||
int major = version >> 8;
|
||||
int minor = version & major;
|
||||
|
||||
Note that this version number is not the same as the shared library version.
|
||||
|
||||
tuntap_destroy
|
||||
--------------
|
||||
|
||||
void tuntap_destroy(struct device *dev);
|
||||
|
||||
This function will free allocated memory, close file descriptors and destroy the interface.
|
||||
|
||||
=== tuntap_release
|
||||
|
||||
void tuntap_release(struct device *dev);
|
||||
|
||||
This function will free allocated memory and close file descriptors. leaving the interface.
|
||||
|
||||
=== tuntap_start
|
||||
|
||||
int tuntap_start(struct device dev*, int mode, int unit);
|
||||
|
||||
This function will configure the device with the mode `mode` and the optional device unit `unit`.
|
||||
|
||||
The `mode` parameter should be either `TUNTAP_MODE_ETHERNET` or `TUNTAP_MODE_TUNNEL` eventually ORed with `TUNTAP_MODE_PERSIST`.
|
||||
|
||||
The `unit` parameter should always be less than `TUNTAP_ID_MAX` and greater than 0. If you don't need a particular value, you should use `TUNTAP_ID_ANY`, which is a sort of wild-card device unit. With this parameter, the kernel will pick the next available device.
|
||||
The term "device unit" is also known as PPA, for Physical Point of Attachment, in Solaris documentation.
|
||||
|
||||
Examples:
|
||||
|
||||
tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY)
|
||||
|
||||
tuntap_start(dev, TUNTAP_MODE_TUNNEL, 2)
|
||||
|
||||
tuntap_start(dev, TUNTAP_MODE_TUNNEL | TUNTAP_MODE_PERSIST, TUNTAP_ID_ANY)
|
||||
|
||||
tuntap_get_ifname
|
||||
-----------------
|
||||
|
||||
char *tuntap_get_ifname(struct device *dev);
|
||||
|
||||
This function fetch and return the name of the interface described by `dev`.
|
||||
|
||||
tuntap_set_ifname
|
||||
-----------------
|
||||
|
||||
int tuntap_set_ifname(struct device *dev, const char *ifname);
|
||||
|
||||
This function replaces the name of the interface described by `dev` with the given name `ifname`.
|
||||
|
||||
It returns -1 on error.
|
||||
|
||||
Compatibility: Linux.
|
||||
|
||||
tuntap_get_hwaddr
|
||||
-----------------
|
||||
|
||||
char *tuntap_get_hwaddr(struct device *dev);
|
||||
|
||||
This function fetch and returns the link-layer address (MAC) of the interface described by `dev`.
|
||||
|
||||
The returned string come from a statically allocated buffer, ans thus should be saved if needed for later use.
|
||||
|
||||
tuntap_set_hwaddr
|
||||
-----------------
|
||||
|
||||
int tuntap_set_hwaddr(struct device *dev, const char *mac_addr);
|
||||
|
||||
This function replaces the link-layer address of the interface described by `dev` with the given address `mac_addr`.
|
||||
|
||||
It returns -1 on error.
|
||||
|
||||
tuntap_set_descr
|
||||
----------------
|
||||
|
||||
int tuntap_set_descr(struct device *dev, const char *desc);
|
||||
|
||||
This function replaces the description of the interface described by `dev` with the given string `desc`.
|
||||
|
||||
Compatibility: OpenBSD, FreeBSD.
|
||||
|
||||
tuntap_up
|
||||
---------
|
||||
|
||||
int tuntap_up(struct device *dev);
|
||||
|
||||
This function set interface to the UP state, just like `ifconfig eth0 up` would do.
|
||||
|
||||
tuntap_down
|
||||
-----------
|
||||
|
||||
int tuntap_down(struct device *dev);
|
||||
|
||||
This function set interface to the DOWN state, just like `ifconfig eth0 down` would do.
|
||||
|
||||
tuntap_get_mtu
|
||||
--------------
|
||||
|
||||
int tuntap_get_mtu(struct device *dev);
|
||||
|
||||
This function fetch and returns the Maximum Transfer Unit (MTU) of the interface described by `dev`.
|
||||
|
||||
tuntap_set_mtu
|
||||
--------------
|
||||
|
||||
int tuntap_set_mtu(struct device *dev, int mtu);
|
||||
|
||||
This function replaces the MTU of the interface described by `dev` with the given value `mtu`.
|
||||
|
||||
tuntap_set_ip
|
||||
-------------
|
||||
|
||||
int tuntap_set_ip(struct device *dev, const char *, int ip_addr);
|
||||
|
||||
This function replaces the IP address of the interface described by `dev` with the given address `ip_addr`.
|
||||
|
||||
tuntap_read
|
||||
-----------
|
||||
|
||||
int tuntap_read(struct device *dev, void *buf, size_t buf_len);
|
||||
|
||||
This function will read one packet from the interface descibed by `dev` and will store it in the buffer `buf` of size `buf_len`. This value can be retrieved with a call to `tuntap_get_readable()`.
|
||||
|
||||
tuntap_write
|
||||
------------
|
||||
|
||||
int tuntap_write(struct device *dev, void *buf, size_t buf_len);
|
||||
|
||||
This function will write the packet stored in the buffer `buf` of size `buf_len` to the interface descibed by `dev`.
|
||||
|
||||
tuntap_get_readable
|
||||
-------------------
|
||||
|
||||
int tuntap_get_readable(struct device *dev);
|
||||
|
||||
This function will return the size of the next packet waiting in the buffer queue of the interface described by `dev`.
|
||||
On Linux this function is the same as `tuntap_get_mtu()`, because the ioctl call `FIONREAD` is not supported on caracter devices.
|
||||
|
||||
tuntap_set_nonblocking
|
||||
----------------------
|
||||
|
||||
int tuntap_set_nonblocking(struct device *dev, int set);
|
||||
|
||||
This function will set the socket of the interface described by `dev` to a non-blocking state.
|
||||
|
||||
tuntap_set_debug
|
||||
----------------
|
||||
|
||||
int tuntap_set_debug(struct device *dev, int set);
|
||||
|
||||
This function will enable or disable the debug mode of the interface described by `dev`, depending of the value of `set`.
|
||||
|
||||
If `set` is 0, it will disable debug, and if it is 1 it will enable it.
|
||||
|
||||
The debug mode will add more output regarding the interface on the console.
|
||||
|
||||
This functionality depend on your operating system. It is enable by default on FreeBSD and NetBSD, but you might have to recompile your tun and tap drivers on Linux and OpenBSD to enable it.
|
||||
|
||||
tuntap_log_set_cb
|
||||
-----------------
|
||||
|
||||
void tuntap_log_set_cb(t_tuntap_log cb);
|
||||
|
||||
This function allow to set an external printing function, in order to erase the default behaviour.
|
||||
|
||||
tuntap_log_hexdump
|
||||
------------------
|
||||
|
||||
void tuntap_log_hexdump(void *, size_t);
|
||||
|
||||
This function is actualy not documented.
|
||||
|
||||
tuntap_log_chksum
|
||||
-----------------
|
||||
|
||||
void tuntap_log_chksum(void *, int);
|
||||
|
||||
This function is actualy not documented.
|
||||
|
||||
TUNTAP_GET_FD
|
||||
-------------
|
||||
|
||||
int TUNTAP_GET_FD(struct device *dev)
|
||||
|
||||
This macro will return the socket of the interface described by `dev`.
|
||||
|
@ -1,100 +0,0 @@
|
||||
# libtuntap regression tests CMakeLists.txt
|
||||
# =========================================
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
enable_testing()
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
||||
|
||||
# C based tests
|
||||
# -------------
|
||||
file(GLOB ALL_C_TESTS regress/test*.c)
|
||||
foreach(SOURCE_FILE ${ALL_C_TESTS})
|
||||
string(REPLACE ".c" "" PATH_WO_SUFFIX ${SOURCE_FILE})
|
||||
string(REPLACE ${CMAKE_CURRENT_SOURCE_DIR}/ ""
|
||||
TEST_SRC_PATH ${SOURCE_FILE})
|
||||
string(REPLACE ${CMAKE_CURRENT_SOURCE_DIR}/regress/ ""
|
||||
TEST_NAME ${PATH_WO_SUFFIX})
|
||||
|
||||
add_executable(${TEST_NAME} ${TEST_SRC_PATH})
|
||||
target_link_libraries(${TEST_NAME} tuntap)
|
||||
add_test(${TEST_NAME} ${EXECUTABLE_OUTPUT_PATH}/${TEST_NAME})
|
||||
endforeach(SOURCE_FILE)
|
||||
|
||||
# Shell based tests
|
||||
# -----------------
|
||||
file(GLOB ALL_SH_TESTS regress/test*.sh)
|
||||
foreach(SOURCE_FILE ${ALL_SH_TESTS})
|
||||
string(REPLACE ".sh" "" PATH_WO_SUFFIX ${SOURCE_FILE})
|
||||
string(REPLACE ${CMAKE_CURRENT_SOURCE_DIR}/ ""
|
||||
TEST_SRC_PATH ${SOURCE_FILE})
|
||||
string(REPLACE ${CMAKE_CURRENT_SOURCE_DIR}/regress/ ""
|
||||
TEST_NAME ${PATH_WO_SUFFIX})
|
||||
|
||||
string(REPLACE ".sh" ".c" HELPER_SRC_PATH ${TEST_SRC_PATH})
|
||||
string(REPLACE "test" "helper" HELPER_SRC_PATH ${HELPER_SRC_PATH})
|
||||
string(REPLACE "test" "helper" HELPER_NAME ${TEST_NAME})
|
||||
|
||||
# XXX: Do it conditionaly
|
||||
add_executable(${HELPER_NAME} ${HELPER_SRC_PATH})
|
||||
target_link_libraries(${HELPER_NAME} tuntap)
|
||||
|
||||
# XXX: This is cancerous
|
||||
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME})
|
||||
file(COPY ${TEST_SRC_PATH}
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_EXECUTE
|
||||
)
|
||||
file(RENAME ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}.sh
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME})
|
||||
|
||||
add_test(${TEST_NAME} ${EXECUTABLE_OUTPUT_PATH}/${TEST_NAME})
|
||||
endforeach(SOURCE_FILE)
|
||||
|
||||
# "Will fail" tests
|
||||
# -----------------
|
||||
|
||||
# Only NetBSD, FreeBSD and DragonFlyBSD have the debug mode compiled by default
|
||||
if(NOT NetBSD AND NOT FreeBSD AND NOT DragonFly)
|
||||
set_tests_properties(test39 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test40 PROPERTIES WILL_FAIL true)
|
||||
endif()
|
||||
|
||||
# Only Linux has a tuntap_set_ifname() implemented
|
||||
if(NOT Linux)
|
||||
set_tests_properties(test41 PROPERTIES WILL_FAIL true)
|
||||
endif()
|
||||
|
||||
# Only FreeBSD and OpenBSD have a tuntap_set_descr() implemented
|
||||
if(NOT FreeBSD AND NOT OpenBSD)
|
||||
set_tests_properties(test44 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test46 PROPERTIES WILL_FAIL true)
|
||||
endif()
|
||||
|
||||
# Windows work-in-progress (tap)
|
||||
if (Windows)
|
||||
set_tests_properties(test05 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test07 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test09 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test39 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test41 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test44 PROPERTIES WILL_FAIL true)
|
||||
endif()
|
||||
|
||||
# Windows work-in-progress (tun)
|
||||
if (Windows)
|
||||
set_tests_properties(test02 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test04 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test06 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test08 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test10 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test12 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test14 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test18 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test22 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test24 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test26 PROPERTIES WILL_FAIL true)
|
||||
set_tests_properties(test40 PROPERTIES WILL_FAIL true)
|
||||
endif()
|
||||
|
@ -1,50 +0,0 @@
|
||||
Regression Testing
|
||||
==================
|
||||
|
||||
test01: Create a tapN device
|
||||
test02: Create a tunN device
|
||||
test03: Create a tap0 device
|
||||
test04: Create a tun0 device
|
||||
test05: Create a tapN device and set its mtu to 1400
|
||||
test06: Create a tunN device and set its mtu to 1400
|
||||
test07: Create a tapN device and set its MAC address to 54:1a:13:ef:b6:b5
|
||||
test08: Create a tunN device and set its MAC address to 54:1a:13:ef:b6:b5
|
||||
test09: Create a tapN device and set its MAC address to random
|
||||
test10: Create a tunN device and set its MAC address to random
|
||||
test11: Create a tapN device and turn it up
|
||||
test12: Create a tunN device and turn it up
|
||||
test13: Create a tapN device, turn it up and set its IPv4 address
|
||||
test14: Create a tunN device, turn it up and set its IPv4 address
|
||||
#test15: Create a tapN device, turn it up and set its IPv6 address
|
||||
#test16: Create a tunN device, turn it up and set its IPv6 address
|
||||
test17: Create a tapN device, set its IPv4 address and turn it up
|
||||
test18: Create a tunN device, set its IPv4 address and turn it up
|
||||
#test19: Create a tapN device, set its IPv6 address and turn it up
|
||||
#test20: Create a tunN device, set its IPv6 address and turn it up
|
||||
test21: Create a tapN device and set its IP address to NULL
|
||||
test22: Create a tunN device and set its IP address to NULL
|
||||
test23: Create a tapN device and set its netmask to a negative value
|
||||
test24: Create a tunN device and set its netmask to a negative value
|
||||
test25: Create a tapN device and set its IP address to a dumb value
|
||||
test26: Create a tunN device and set its IP address to a dumb value
|
||||
#test27: Create a tapN device and set its netmask to a dumb value
|
||||
#test28: Create a tunN device and set its netmask to a dumb value
|
||||
test29: Double create a tapN device
|
||||
test30: Create a device with a wrong type
|
||||
test31: Create a device with a wrong number
|
||||
test32: Create a tapN device and check its pre-existing MAC address
|
||||
test33: Create a tap0 persistent device and destroy it
|
||||
test34: Create a tun0 persistent device and destroy it
|
||||
test35: Create a tap0 persistent device and release it
|
||||
test36: Create a tun1 persistent device and release it
|
||||
test37: Set a log callback and generate an error
|
||||
test38: Set a log callback and generate all possible error levels
|
||||
test39: Enable debug for a tap device
|
||||
test40: Enable debug for a tun device
|
||||
test41: Set a new name to an interface
|
||||
test42: Set a NULL name to an interface
|
||||
test43: Set a name of more than IF_NAMESIZE to an interface
|
||||
test44: Set a description to an interface
|
||||
test45: Set a NULL description to an interface
|
||||
test46: Set a description to an interface and check it
|
||||
|
@ -1,26 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET|TUNTAP_MODE_PERSIST
|
||||
, 0) == -1)
|
||||
ret = 1;
|
||||
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL|TUNTAP_MODE_PERSIST, 0)
|
||||
== -1)
|
||||
ret = 1;
|
||||
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET|TUNTAP_MODE_PERSIST
|
||||
, 0) == -1)
|
||||
ret = 1;
|
||||
|
||||
tuntap_release(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL|TUNTAP_MODE_PERSIST, 1) == -1)
|
||||
ret = 1;
|
||||
|
||||
tuntap_release(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY) == -1)
|
||||
ret = 1;
|
||||
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1)
|
||||
ret = 1;
|
||||
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, 0) == -1)
|
||||
ret = 1;
|
||||
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL, 0) == -1)
|
||||
ret = 1;
|
||||
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
int mtu;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY)
|
||||
== -1) {
|
||||
ret = 1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
if (tuntap_set_mtu(dev, 1400) == -1) {
|
||||
ret = 1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
mtu = tuntap_get_mtu(dev);
|
||||
if (mtu != 1400)
|
||||
ret = 1;
|
||||
|
||||
clean:
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
int mtu;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1) {
|
||||
ret = 1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
if (tuntap_set_mtu(dev, 1400) == -1) {
|
||||
ret = 1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
mtu = tuntap_get_mtu(dev);
|
||||
if (mtu != 1400) {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
clean:
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
# define strcasecmp(x, y) _stricmp((x), (y))
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
char *hwaddr;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY)
|
||||
== -1) {
|
||||
ret = 1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
if (tuntap_set_hwaddr(dev, "54:1a:13:ef:b6:b5") == -1) {
|
||||
ret = 1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
hwaddr = tuntap_get_hwaddr(dev);
|
||||
if (strcasecmp(hwaddr, "54:1a:13:ef:b6:b5") != 0)
|
||||
ret = 1;
|
||||
|
||||
clean:
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
/* This test SHOULD fail, it's normal */
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 1;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1)
|
||||
goto clean;
|
||||
|
||||
if (tuntap_set_hwaddr(dev, "54:1a:13:ef:b6:b5") == -1)
|
||||
ret = 0;
|
||||
|
||||
clean:
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY)
|
||||
== -1) {
|
||||
ret = 1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
if (tuntap_set_hwaddr(dev, "random") == -1) {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
clean:
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
/* This test SHOULD fail, it's normal */
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 1;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1) {
|
||||
goto clean;
|
||||
}
|
||||
|
||||
if (tuntap_set_hwaddr(dev, "random") == -1) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
clean:
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY)
|
||||
== -1) {
|
||||
ret = 1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
if (tuntap_up(dev) == -1)
|
||||
ret = 1;
|
||||
|
||||
clean:
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1) {
|
||||
ret = 1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
if (tuntap_up(dev) == -1)
|
||||
ret = 1;
|
||||
|
||||
clean:
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
/*
|
||||
* This test seems to pass on Windows, but it's not true.
|
||||
* tuntap_up() should be call _after_ tuntap_set_ip(), as in test17.c
|
||||
*
|
||||
* Fuck.
|
||||
*/
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
|
||||
ret = 0;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY) == -1) {
|
||||
ret = 1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
if (tuntap_up(dev) == -1) {
|
||||
ret = 1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
if (tuntap_set_ip(dev, "1.2.3.4", 24) == -1) {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
clean:
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_up(dev) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_set_ip(dev, "1.2.3.4", 24) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
tuntap_destroy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_set_ip(dev, "1.2.3.4", 24) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_up(dev) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
tuntap_destroy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_set_ip(dev, "1.2.3.4", 24) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_up(dev) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
tuntap_destroy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_set_ip(dev, NULL, 24) == -1) {
|
||||
tuntap_destroy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_set_ip(dev, NULL, 24) == -1) {
|
||||
tuntap_destroy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_set_ip(dev, "1.2.3.4", -2) == -1) {
|
||||
tuntap_destroy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_set_ip(dev, "1.2.3.4", -2) == -1) {
|
||||
tuntap_destroy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_set_ip(dev, "Chipot", 24) == -1) {
|
||||
tuntap_destroy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_set_ip(dev, "Chipot", 24) == -1) {
|
||||
tuntap_destroy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY) == -1) {
|
||||
tuntap_destroy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, 42, TUNTAP_ID_ANY) == -1) {
|
||||
tuntap_destroy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_TUNNEL, -1) == -1) {
|
||||
tuntap_destroy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
/* Public domain - Tristan Le Guern <tleguern@bouledef.eu> */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#if defined Windows
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "tuntap.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
char *hwaddr;
|
||||
|
||||
ret = 1;
|
||||
dev = tuntap_init();
|
||||
if (tuntap_start(dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY) == -1) {
|
||||
goto clean;
|
||||
}
|
||||
|
||||
hwaddr = tuntap_get_hwaddr(dev);
|
||||
(void)fprintf(stderr, "%s\n", hwaddr);
|
||||
if (strcmp(hwaddr, "0:0:0:0:0:0") == 0)
|
||||
goto clean;
|
||||
if (strcmp(hwaddr, "00:00:00:00:00:00") == 0)
|
||||
goto clean;
|
||||
|
||||
ret = 0;
|
||||
clean:
|
||||
tuntap_destroy(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,40 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# test33: Create a tap0 persistent device and destroy it
|
||||
|
||||
TEST="`pwd`/helper33"
|
||||
SYSTEM=`uname`
|
||||
|
||||
# There is no tap driver on OpenBSD
|
||||
if [ "$SYSTEM" = "OpenBSD" ]; then
|
||||
TARGET='tun0'
|
||||
TYPE='tap'
|
||||
else
|
||||
TARGET='tap0'
|
||||
TYPE='tap'
|
||||
fi
|
||||
|
||||
if [ "$SYSTEM" = "Linux" ]; then
|
||||
IFDEL="ip tuntap del $TARGET mode $TYPE"
|
||||
else
|
||||
IFDEL="ifconfig $TARGET destroy"
|
||||
fi
|
||||
|
||||
OK=0
|
||||
$TEST && OK=1
|
||||
|
||||
# If the $TEST was a success, check if the interface still exist
|
||||
if [ $OK -eq 1 ]; then
|
||||
ifconfig $TARGET > /dev/null && OK=2
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The $TARGET still exists, clean it and return failure
|
||||
if [ $OK -eq 2 ]; then
|
||||
$IFDEL
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Everything went fine
|
||||
exit 0
|
@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# test34: Create a tun0 persistent device and destroy it
|
||||
|
||||
TEST="`pwd`/helper34"
|
||||
SYSTEM=`uname`
|
||||
TARGET='tun0'
|
||||
TYPE='tun'
|
||||
|
||||
if [ "$SYSTEM" = "Linux" ]; then
|
||||
IFDEL="ip tuntap del $TARGET mode $TYPE"
|
||||
else
|
||||
IFDEL="ifconfig $TARGET destroy"
|
||||
fi
|
||||
|
||||
OK=0
|
||||
$TEST && OK=1
|
||||
|
||||
# The $TEST is successful
|
||||
if [ $OK -eq 1 ]; then
|
||||
ifconfig $TARGET && OK=2
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The $TARGET still exists
|
||||
if [ $OK -eq 2 ]; then
|
||||
$IFDEL
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue