some tun interface code

pull/13/head
Jeff Becker 6 years ago
parent 54f70f370a
commit 04bf8d6116
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -182,14 +182,14 @@ else()
endif(UNIX)
if(TUNTAP)
set(LIBTUNTAP_SRC
set(LIBTUNTAP_SRC_BASE
${TT_ROOT}/tuntap.c
${TT_ROOT}/tuntap_log.cpp
${LIBTUNTAP_IMPL})
if (UNIX)
set(LIBTUNTAP_SRC
${TT_ROOT}/tuntap-unix.c
${LIBTUNTAP_SRC})
${LIBTUNTAP_SRC_BASE})
endif()
else()
set(LIBTUNTAP_SRC "")
@ -241,6 +241,8 @@ set(LIB_PLATFORM_SRC
llarp/threadpool.cpp
# for android shim
${ANDROID_PLATFORM_SRC}
# tun
${LIBTUNTAP_SRC}
# win32 inline procs
llarp/win32_inet.c
llarp/win32_intrnl.c
@ -356,7 +358,7 @@ set(LIB_SRC
llarp/service/protocol.cpp
llarp/service/tag.cpp
llarp/service/info.cpp
${LIBTUNTAP_SRC}
)
set(DNS_SRC

@ -8,13 +8,14 @@
#define ssize_t long
#endif
#else
#include <netinet/in.h>
#include <sys/socket.h>
#endif
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <tuntap.h>
/**
* ev.h
*
@ -74,4 +75,29 @@ llarp_ev_udp_sendto(struct llarp_udp_io *udp, const struct sockaddr *to,
int
llarp_ev_close_udp(struct llarp_udp_io *udp);
struct llarp_tun_io
{
// TODO: more info?
char ifaddr[128];
int netmask;
char ifname[IFNAMSIZ + 1];
void *user;
void *impl;
struct llarp_ev_loop *parent;
/// called every event loop tick after reads
void (*tick)(struct llarp_tun_io *);
void (*recvpkt)(struct llarp_tun_io *, const void *, ssize_t);
};
/// create tun interface with network interface name ifname
/// returns true on success otherwise returns false
bool
llarp_ev_add_tun(struct llarp_ev_loop *ev, struct llarp_tun_io *tun);
/// async write a packet on tun interface
/// returns true if queued, returns false on drop
bool
llarp_ev_tun_async_write(struct llarp_tun_io *tun, const void *pkt, size_t sz);
#endif

@ -13,6 +13,7 @@ namespace llarp
~TunEndpoint();
device* m_tunif;
std::string m_IfName;
};
} // namespace service
} // namespace llarp

@ -105,3 +105,15 @@ llarp_ev_udp_sendto(struct llarp_udp_io *udp, const sockaddr *to,
}
return ret;
}
bool
llarp_ev_add_tun(struct llarp_ev_loop *loop, struct llarp_tun_io *tun)
{
return loop->create_tun(tun);
}
bool
llarp_ev_tun_async_write(struct llarp_tun_io *tun, const void *pkt, size_t sz)
{
return static_cast< llarp::ev_io * >(tun->impl)->queue_write(pkt, sz);
}

@ -5,7 +5,13 @@
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <llarp/buffer.h>
#include <list>
#include <llarp/codel.hpp>
#include <vector>
#ifndef MAX_WRITE_QUEUE_SIZE
#define MAX_WRITE_QUEUE_SIZE 1024
#endif
namespace llarp
{
@ -13,10 +19,10 @@ namespace llarp
{
#ifndef _WIN32
int fd;
ev_io(int f) : fd(f){};
ev_io(int f) : fd(f), m_writeq("writequeue"){};
#else
SOCKET fd;
ev_io(SOCKET f) : fd(f){};
ev_io(SOCKET f) : fd(f), m_writeq("writequeue"){};
#endif
virtual int
read(void* buf, size_t sz) = 0;
@ -24,6 +30,79 @@ namespace llarp
virtual int
sendto(const sockaddr* dst, const void* data, size_t sz) = 0;
/// used for tun interface
bool
queue_write(const void* data, size_t sz)
{
m_writeq.Put(new WriteBuffer(data, sz));
return m_writeq.Size() <= MAX_WRITE_QUEUE_SIZE;
}
/// called in event loop when fd is ready for writing
/// drops all buffers that cannot be written in this pump
/// this assumes fd is set to non blocking
void
flush_write()
{
std::queue< WriteBuffer* > send;
m_writeq.Process(send);
while(send.size())
{
auto& buffer = send.front();
if(write(fd, buffer->payload.data(), buffer->payload.size()) == -1)
{
// failed to write
// TODO: should we requeue this buffer?
}
delete buffer;
}
/// reset errno
errno = 0;
}
struct WriteBuffer
{
llarp_time_t timestamp = 0;
std::vector< byte_t > payload;
WriteBuffer(const void* ptr, size_t sz) : payload(sz)
{
memcpy(payload.data(), ptr, sz);
}
struct GetTime
{
llarp_time_t
operator()(const WriteBuffer* w) const
{
return w->timestamp;
}
};
struct PutTime
{
void
operator()(WriteBuffer*& w) const
{
w->timestamp = llarp_time_now_ms();
}
};
struct Compare
{
bool
operator()(const WriteBuffer* left, const WriteBuffer* right) const
{
return left->timestamp < right->timestamp;
}
};
};
llarp::util::CoDelQueue< WriteBuffer*, WriteBuffer::GetTime,
WriteBuffer::PutTime, WriteBuffer::Compare,
llarp::util::NullMutex, llarp::util::NullLock >
m_writeq;
virtual ~ev_io()
{
#ifndef _WIN32
@ -33,6 +112,7 @@ namespace llarp
#endif
};
};
}; // namespace llarp
struct llarp_ev_loop
@ -49,18 +129,44 @@ struct llarp_ev_loop
stop() = 0;
virtual bool
udp_listen(llarp_udp_io* l, const sockaddr* src) = 0;
udp_listen(llarp_udp_io* l, const sockaddr* src)
{
auto ev = create_udp(l, src);
return ev && add_ev(ev);
}
virtual llarp::ev_io*
create_udp(llarp_udp_io* l, const sockaddr* src) = 0;
virtual bool
udp_close(llarp_udp_io* l) = 0;
virtual bool
close_ev(llarp::ev_io* ev) = 0;
virtual llarp::ev_io*
create_tun(llarp_tun_io* tun) = 0;
virtual bool
add_ev(llarp::ev_io* ev) = 0;
virtual bool
running() const = 0;
virtual ~llarp_ev_loop(){};
std::list< llarp_udp_io* > udp_listeners;
std::list< llarp_tun_io* > tun_listeners;
void
tick_listeners()
{
for(auto& l : udp_listeners)
if(l->tick)
l->tick(l);
for(auto& l : tun_listeners)
if(l->tick)
l->tick(l);
}
};
#endif

@ -4,6 +4,7 @@
#include <llarp/net.h>
#include <signal.h>
#include <sys/epoll.h>
#include <tuntap.h>
#include <unistd.h>
#include <cstdio>
#include "ev.hpp"
@ -58,6 +59,50 @@ namespace llarp
return sent;
}
};
struct tun : public ev_io
{
llarp_tun_io* t;
device* tunif;
tun(llarp_tun_io* tio)
: ev_io(-1)
, t(tio)
, tunif(tuntap_init())
{
};
int
sendto(const sockaddr* to, const void* data, size_t sz)
{
// TODO: implement me
return -1;
}
int
read(void* buf, size_t sz)
{
return tuntap_read(tunif, buf, sz);
}
bool
setup()
{
if(tuntap_start(tunif, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1)
return false;
if(tuntap_set_ifname(tunif, t->ifname) == -1)
return false;
if(tuntap_set_ip(tunif, t->ifaddr, t->netmask) == -1)
return false;
fd = tunif->tun_fd;
return false;
}
~tun()
{
}
};
}; // namespace llarp
struct llarp_epoll_loop : public llarp_ev_loop
@ -129,12 +174,14 @@ struct llarp_epoll_loop : public llarp_ev_loop
{
ev->read(readbuf, sizeof(readbuf));
}
if(events[idx].events & EPOLLOUT)
{
ev->flush_write();
}
++idx;
}
}
for(auto& l : udp_listeners)
if(l->tick)
l->tick(l);
tick_listeners();
return result;
}
@ -162,12 +209,14 @@ struct llarp_epoll_loop : public llarp_ev_loop
{
ev->read(readbuf, sizeof(readbuf));
}
if(events[idx].events & EPOLLOUT)
{
ev->flush_write();
}
++idx;
}
}
for(auto& l : udp_listeners)
if(l->tick)
l->tick(l);
tick_listeners();
} while(epollfd != -1);
return result;
}
@ -224,23 +273,39 @@ struct llarp_epoll_loop : public llarp_ev_loop
return epoll_ctl(epollfd, EPOLL_CTL_DEL, ev->fd, nullptr) != -1;
}
bool
udp_listen(llarp_udp_io* l, const sockaddr* src)
llarp::ev_io*
create_tun(llarp_tun_io* tun)
{
llarp::tun* t = new llarp::tun(tun);
if(t->setup())
return t;
delete t;
return nullptr;
}
llarp::ev_io*
create_udp(llarp_udp_io* l, const sockaddr* src)
{
int fd = udp_bind(src);
if(fd == -1)
return false;
return nullptr;
llarp::udp_listener* listener = new llarp::udp_listener(fd, l);
l->impl = listener;
udp_listeners.push_back(l);
return listener;
}
bool
add_ev(llarp::ev_io* e)
{
epoll_event ev;
ev.data.ptr = listener;
ev.events = EPOLLIN;
if(epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1)
ev.data.ptr = e;
ev.events = EPOLLIN | EPOLLOUT;
if(epoll_ctl(epollfd, EPOLL_CTL_ADD, e->fd, &ev) == -1)
{
delete listener;
delete e;
return false;
}
l->impl = listener;
udp_listeners.push_back(l);
return true;
}

@ -125,9 +125,7 @@ struct llarp_kqueue_loop : public llarp_ev_loop
++idx;
}
}
for(auto& l : udp_listeners)
if(l->tick)
l->tick(l);
tick_listeners();
return result;
}
@ -162,9 +160,7 @@ struct llarp_kqueue_loop : public llarp_ev_loop
++idx;
}
}
for(auto& l : udp_listeners)
if(l->tick)
l->tick(l);
tick_listeners();
} while(result != -1);
return result;
}

@ -0,0 +1,20 @@
#include <llarp/service/tun.hpp>
namespace llarp
{
namespace service
{
TunEndpoint::TunEndpoint(const std::string &ifname, llarp_router *r)
: Endpoint("tunif-" + ifname, r)
, m_tunif(tuntap_init())
, m_IfName(ifname)
{
}
TunEndpoint::~TunEndpoint()
{
tuntap_destroy(m_tunif);
}
} // namespace service
} // namespace llarp

@ -25,24 +25,24 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#if defined Linux
# include <netinet/ether.h>
# include <linux/if_tun.h>
#include <linux/if_tun.h>
#include <netinet/ether.h>
#else
# include <net/if.h>
# if defined DragonFly
# include <net/tun/if_tun.h>
# elif !defined Darwin
# include <net/if_tun.h>
# endif
# include <netinet/in.h>
# include <netinet/if_ether.h>
#include <net/if.h>
#if defined DragonFly
#include <net/tun/if_tun.h>
#elif !defined Darwin
#include <net/if_tun.h>
#endif
#include <netinet/if_ether.h>
#include <netinet/in.h>
#endif
#include <stdio.h>
@ -51,310 +51,358 @@
#include <time.h>
#include <unistd.h>
#include "tuntap.h"
#include <tuntap.h>
int
tuntap_start(struct device *dev, int mode, int tun) {
int sock;
int fd;
fd = sock = -1;
/* Don't re-initialise a previously started device */
if (dev->tun_fd != -1) {
tuntap_log(TUNTAP_LOG_ERR, "Device is already started");
return -1;
}
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1) {
goto clean;
}
dev->ctrl_sock = sock;
if (mode & TUNTAP_MODE_PERSIST && tun == TUNTAP_ID_ANY) {
goto clean; /* XXX: Explain why */
}
fd = tuntap_sys_start(dev, mode, tun);
if (fd == -1) {
goto clean;
}
dev->tun_fd = fd;
tuntap_set_debug(dev, 0);
return 0;
tuntap_start(struct device *dev, int mode, int tun)
{
int sock;
int fd;
fd = sock = -1;
/* Don't re-initialise a previously started device */
if(dev->tun_fd != -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Device is already started");
return -1;
}
sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock == -1)
{
goto clean;
}
dev->ctrl_sock = sock;
if(mode & TUNTAP_MODE_PERSIST && tun == TUNTAP_ID_ANY)
{
goto clean; /* XXX: Explain why */
}
fd = tuntap_sys_start(dev, mode, tun);
if(fd == -1)
{
goto clean;
}
dev->tun_fd = fd;
tuntap_set_debug(dev, 0);
return 0;
clean:
if (fd != -1) {
(void)close(fd);
}
if (sock != -1) {
(void)close(sock);
}
return -1;
if(fd != -1)
{
(void)close(fd);
}
if(sock != -1)
{
(void)close(sock);
}
return -1;
}
void
tuntap_release(struct device *dev) {
(void)close(dev->tun_fd);
(void)close(dev->ctrl_sock);
free(dev);
tuntap_release(struct device *dev)
{
(void)close(dev->tun_fd);
(void)close(dev->ctrl_sock);
free(dev);
}
int
tuntap_set_descr(struct device *dev, const char *descr) {
size_t len;
if (descr == NULL) {
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'descr'");
return -1;
}
len = strlen(descr);
if (len > IF_DESCRSIZE) {
/* The value will be troncated */
tuntap_log(TUNTAP_LOG_WARN, "Parameter 'descr' is too long");
}
if (tuntap_sys_set_descr(dev, descr, len) == -1) {
return -1;
}
return 0;
tuntap_set_descr(struct device *dev, const char *descr)
{
size_t len;
if(descr == NULL)
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'descr'");
return -1;
}
len = strlen(descr);
if(len > IF_DESCRSIZE)
{
/* The value will be troncated */
tuntap_log(TUNTAP_LOG_WARN, "Parameter 'descr' is too long");
}
if(tuntap_sys_set_descr(dev, descr, len) == -1)
{
return -1;
}
return 0;
}
int
tuntap_set_ifname(struct device *dev, const char *ifname) {
size_t len;
if (ifname == NULL) {
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'ifname'");
return -1;
}
len = strlen(ifname);
if (len > IF_NAMESIZE) {
tuntap_log(TUNTAP_LOG_ERR, "Parameter 'ifname' is too long");
return -1;
}
if (tuntap_sys_set_ifname(dev, ifname, len) == -1) {
return -1;
}
(void)memset(dev->if_name, 0, IF_NAMESIZE);
(void)strncpy(dev->if_name, ifname, len);
return 0;
tuntap_set_ifname(struct device *dev, const char *ifname)
{
size_t len;
if(ifname == NULL)
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'ifname'");
return -1;
}
len = strlen(ifname);
if(len > IF_NAMESIZE)
{
tuntap_log(TUNTAP_LOG_ERR, "Parameter 'ifname' is too long");
return -1;
}
if(tuntap_sys_set_ifname(dev, ifname, len) == -1)
{
return -1;
}
(void)memset(dev->if_name, 0, IF_NAMESIZE);
(void)strncpy(dev->if_name, ifname, len);
return 0;
}
char *
tuntap_get_hwaddr(struct device *dev) {
struct ether_addr eth_attr;
tuntap_get_hwaddr(struct device *dev)
{
struct ether_addr eth_attr;
(void)memcpy(&eth_attr, dev->hwaddr, sizeof dev->hwaddr);
return ether_ntoa(&eth_attr);
(void)memcpy(&eth_attr, dev->hwaddr, sizeof dev->hwaddr);
return ether_ntoa(&eth_attr);
}
int
tuntap_set_hwaddr(struct device *dev, const char *hwaddr) {
struct ether_addr *eth_addr, eth_rand;
if (strcmp(hwaddr, "random") == 0) {
unsigned int i;
unsigned char *ptr;
i = 0;
ptr = (unsigned char *)&eth_rand;
srandom((unsigned int)time(NULL));
for (; i < sizeof eth_rand; ++i) {
*ptr = (unsigned char)random();
ptr++;
}
ptr = (unsigned char *)&eth_rand;
*ptr &= 0xfc;
eth_addr = &eth_rand;
} else {
eth_addr = ether_aton(hwaddr);
if (eth_addr == NULL) {
return -1;
}
}
(void)memcpy(dev->hwaddr, eth_addr, ETHER_ADDR_LEN);
if (tuntap_sys_set_hwaddr(dev, eth_addr) == -1)
return -1;
return 0;
tuntap_set_hwaddr(struct device *dev, const char *hwaddr)
{
struct ether_addr *eth_addr, eth_rand;
if(strcmp(hwaddr, "random") == 0)
{
unsigned int i;
unsigned char *ptr;
i = 0;
ptr = (unsigned char *)&eth_rand;
srandom((unsigned int)time(NULL));
for(; i < sizeof eth_rand; ++i)
{
*ptr = (unsigned char)random();
ptr++;
}
ptr = (unsigned char *)&eth_rand;
*ptr &= 0xfc;
eth_addr = &eth_rand;
}
else
{
eth_addr = ether_aton(hwaddr);
if(eth_addr == NULL)
{
return -1;
}
}
(void)memcpy(dev->hwaddr, eth_addr, ETHER_ADDR_LEN);
if(tuntap_sys_set_hwaddr(dev, eth_addr) == -1)
return -1;
return 0;
}
int
tuntap_up(struct device *dev) {
struct ifreq ifr;
(void)memset(&ifr, '\0', sizeof ifr);
(void)memcpy(ifr.ifr_name, dev->if_name, sizeof dev->if_name);
ifr.ifr_flags = (short int)dev->flags;
ifr.ifr_flags |= IFF_UP;
if (ioctl(dev->ctrl_sock, SIOCSIFFLAGS, &ifr) == -1) {
return -1;
}
dev->flags = ifr.ifr_flags;
return 0;
tuntap_up(struct device *dev)
{
struct ifreq ifr;
(void)memset(&ifr, '\0', sizeof ifr);
(void)memcpy(ifr.ifr_name, dev->if_name, sizeof dev->if_name);
ifr.ifr_flags = (short int)dev->flags;
ifr.ifr_flags |= IFF_UP;
if(ioctl(dev->ctrl_sock, SIOCSIFFLAGS, &ifr) == -1)
{
return -1;
}
dev->flags = ifr.ifr_flags;
return 0;
}
int
tuntap_down(struct device *dev) {
struct ifreq ifr;
(void)memset(&ifr, '\0', sizeof ifr);
(void)memcpy(ifr.ifr_name, dev->if_name, sizeof dev->if_name);
ifr.ifr_flags = (short)dev->flags;
ifr.ifr_flags &= ~IFF_UP;
if (ioctl(dev->ctrl_sock, SIOCSIFFLAGS, &ifr) == -1) {
return -1;
}
dev->flags = ifr.ifr_flags;
return 0;
tuntap_down(struct device *dev)
{
struct ifreq ifr;
(void)memset(&ifr, '\0', sizeof ifr);
(void)memcpy(ifr.ifr_name, dev->if_name, sizeof dev->if_name);
ifr.ifr_flags = (short)dev->flags;
ifr.ifr_flags &= ~IFF_UP;
if(ioctl(dev->ctrl_sock, SIOCSIFFLAGS, &ifr) == -1)
{
return -1;
}
dev->flags = ifr.ifr_flags;
return 0;
}
int
tuntap_get_mtu(struct device *dev) {
struct ifreq ifr;
/* Only accept started device */
if (dev->tun_fd == -1) {
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
(void)memset(&ifr, '\0', sizeof ifr);
(void)memcpy(ifr.ifr_name, dev->if_name, sizeof dev->if_name);
if (ioctl(dev->ctrl_sock, SIOCGIFMTU, &ifr) == -1) {
tuntap_log(TUNTAP_LOG_ERR, "Can't get MTU");
return -1;
}
return ifr.ifr_mtu;
tuntap_get_mtu(struct device *dev)
{
struct ifreq ifr;
/* Only accept started device */
if(dev->tun_fd == -1)
{
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
(void)memset(&ifr, '\0', sizeof ifr);
(void)memcpy(ifr.ifr_name, dev->if_name, sizeof dev->if_name);
if(ioctl(dev->ctrl_sock, SIOCGIFMTU, &ifr) == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Can't get MTU");
return -1;
}
return ifr.ifr_mtu;
}
int
tuntap_set_mtu(struct device *dev, int mtu) {
struct ifreq ifr;
/* Only accept started device */
if (dev->tun_fd == -1) {
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
(void)memset(&ifr, '\0', sizeof ifr);
(void)memcpy(ifr.ifr_name, dev->if_name, sizeof dev->if_name);
ifr.ifr_mtu = mtu;
if (ioctl(dev->ctrl_sock, SIOCSIFMTU, &ifr) == -1) {
tuntap_log(TUNTAP_LOG_ERR, "Can't set MTU");
return -1;
}
return 0;
tuntap_set_mtu(struct device *dev, int mtu)
{
struct ifreq ifr;
/* Only accept started device */
if(dev->tun_fd == -1)
{
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
(void)memset(&ifr, '\0', sizeof ifr);
(void)memcpy(ifr.ifr_name, dev->if_name, sizeof dev->if_name);
ifr.ifr_mtu = mtu;
if(ioctl(dev->ctrl_sock, SIOCSIFMTU, &ifr) == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Can't set MTU");
return -1;
}
return 0;
}
int
tuntap_read(struct device *dev, void *buf, size_t size) {
int n;
/* Only accept started device */
if (dev->tun_fd == -1) {
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
n = read(dev->tun_fd, buf, size);
if (n == -1) {
tuntap_log(TUNTAP_LOG_WARN, "Can't to read from device");
return -1;
}
return n;
tuntap_read(struct device *dev, void *buf, size_t size)
{
int n;
/* Only accept started device */
if(dev->tun_fd == -1)
{
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
n = read(dev->tun_fd, buf, size);
if(n == -1)
{
tuntap_log(TUNTAP_LOG_WARN, "Can't to read from device");
return -1;
}
return n;
}
int
tuntap_write(struct device *dev, void *buf, size_t size) {
int n;
/* Only accept started device */
if (dev->tun_fd == -1) {
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
n = write(dev->tun_fd, buf, size);
if (n == -1) {
tuntap_log(TUNTAP_LOG_WARN, "Can't write to device");
return -1;
}
return n;
tuntap_write(struct device *dev, void *buf, size_t size)
{
int n;
/* Only accept started device */
if(dev->tun_fd == -1)
{
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
n = write(dev->tun_fd, buf, size);
if(n == -1)
{
tuntap_log(TUNTAP_LOG_WARN, "Can't write to device");
return -1;
}
return n;
}
int
tuntap_get_readable(struct device *dev) {
int n;
n = 0;
if (ioctl(dev->tun_fd, FIONREAD, &n) == -1) {
tuntap_log(TUNTAP_LOG_INFO, "Your system does not support"
" FIONREAD, fallback to MTU");
return tuntap_get_mtu(dev);
}
return n;
tuntap_get_readable(struct device *dev)
{
int n;
n = 0;
if(ioctl(dev->tun_fd, FIONREAD, &n) == -1)
{
tuntap_log(TUNTAP_LOG_INFO,
"Your system does not support"
" FIONREAD, fallback to MTU");
return tuntap_get_mtu(dev);
}
return n;
}
int
tuntap_set_nonblocking(struct device *dev, int set) {
if (ioctl(dev->tun_fd, FIONBIO, &set) == -1) {
switch(set) {
case 0:
tuntap_log(TUNTAP_LOG_ERR, "Can't unset nonblocking");
break;
case 1:
tuntap_log(TUNTAP_LOG_ERR, "Can't set nonblocking");
break;
default:
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'set'");
}
return -1;
}
return 0;
tuntap_set_nonblocking(struct device *dev, int set)
{
if(ioctl(dev->tun_fd, FIONBIO, &set) == -1)
{
switch(set)
{
case 0:
tuntap_log(TUNTAP_LOG_ERR, "Can't unset nonblocking");
break;
case 1:
tuntap_log(TUNTAP_LOG_ERR, "Can't set nonblocking");
break;
default:
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'set'");
}
return -1;
}
return 0;
}
int
tuntap_set_debug(struct device *dev, int set) {
/* Only accept started device */
if (dev->tun_fd == -1) {
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
tuntap_set_debug(struct device *dev, int set)
{
/* Only accept started device */
if(dev->tun_fd == -1)
{
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
#if !defined Darwin
if (ioctl(dev->tun_fd, TUNSDEBUG, &set) == -1) {
switch(set) {
case 0:
tuntap_log(TUNTAP_LOG_WARN, "Can't unset debug");
break;
case 1:
tuntap_log(TUNTAP_LOG_WARN, "Can't set debug");
break;
default:
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'set'");
}
return -1;
}
return 0;
if(ioctl(dev->tun_fd, TUNSDEBUG, &set) == -1)
{
switch(set)
{
case 0:
tuntap_log(TUNTAP_LOG_WARN, "Can't unset debug");
break;
case 1:
tuntap_log(TUNTAP_LOG_WARN, "Can't set debug");
break;
default:
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'set'");
}
return -1;
}
return 0;
#else
tuntap_log(TUNTAP_LOG_NOTICE,
"Your system does not support tuntap_set_debug()");
return -1;
tuntap_log(TUNTAP_LOG_NOTICE,
"Your system does not support tuntap_set_debug()");
return -1;
#endif
}

@ -28,6 +28,8 @@
extern "C"
{
t_tuntap_log tuntap_log = &tuntap_log_default;
void
tuntap_log_set_cb(t_tuntap_log cb)
{

Loading…
Cancel
Save