more tun stuff

pull/14/head
Jeff Becker 6 years ago
parent e8daf53600
commit 4aebbda640
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -185,7 +185,7 @@ endif(UNIX)
if(TUNTAP)
set(LIBTUNTAP_SRC_BASE
${TT_ROOT}/tuntap.c
${TT_ROOT}/tuntap.cpp
${TT_ROOT}/tuntap_log.cpp
${LIBTUNTAP_IMPL})
if (UNIX)

@ -16,6 +16,19 @@ namespace llarp
return buff;
}
/** initialize llarp_buffer_t from raw memory */
template < typename T >
llarp_buffer_t
InitBuffer(T buf, size_t sz)
{
byte_t* ptr = (byte_t*)buf;
llarp_buffer_t ret;
ret.cur = ptr;
ret.base = ptr;
ret.sz = sz;
return ret;
}
/** initialize llarp_buffer_t from container */
template < typename T >
llarp_buffer_t

@ -8,6 +8,7 @@
#endif
#include <llarp/time.h>
#include <llarp/logger.hpp>
#include <llarp/mem.hpp>
#include <llarp/threading.hpp>
#include <algorithm>
@ -69,14 +70,47 @@ namespace llarp
return m_Queue.size();
}
template < typename... Args >
bool
EmplaceIf(std::function< bool(T*) > pred, Args&&... args)
{
std::unique_ptr< T > ptr = std::make_unique< T >(args...);
if(!pred(ptr.get()))
return false;
PutTime()(ptr.get());
{
Lock_t lock(m_QueueMutex);
if(firstPut == 0)
firstPut = GetTime()(ptr.get());
m_Queue.push(std::move(ptr));
}
return true;
}
template < typename... Args >
void
Emplace(Args&&... args)
{
std::unique_ptr< T > ptr = std::make_unique< T >(args...);
PutTime()(ptr.get());
{
Lock_t lock(m_QueueMutex);
if(firstPut == 0)
firstPut = GetTime()(ptr.get());
m_Queue.push(std::move(ptr));
}
}
void
Put(std::unique_ptr< T >& ptr)
{
Lock_t lock(m_QueueMutex);
PutTime()(ptr.get());
if(firstPut == 0)
firstPut = GetTime()(ptr.get());
m_Queue.push(std::move(ptr));
{
Lock_t lock(m_QueueMutex);
if(firstPut == 0)
firstPut = GetTime()(ptr.get());
m_Queue.push(std::move(ptr));
}
}
template < typename Func >
@ -90,9 +124,9 @@ namespace llarp
auto start = firstPut;
while(m_Queue.size())
{
// llarp::LogInfo("CoDelQueue::Process - queue has ", m_Queue.size());
auto& item = m_Queue.top();
auto dlt = start - GetTime()(item.get());
llarp::LogDebug("CoDelQueue::Process - queue has ", m_Queue.size());
const auto& item = m_Queue.top();
auto dlt = start - GetTime()(item.get());
// llarp::LogInfo("CoDelQueue::Process - dlt ", dlt);
lowest = std::min(dlt, lowest);
if(m_Queue.size() == 1)

@ -74,14 +74,18 @@ namespace llarp
PacketQueue_t m_NetworkToUserPktQueue;
/// return true if we have a remote loki address for this ip address
bool
HasRemoteForIP(const uint32_t& ipv4)
{
return m_IPs.find(ipv4) != m_IPs.end();
}
HasRemoteForIP(const uint32_t& ipv4) const;
uint32_t
ObtainIPForAddr(const service::Address& addr);
private:
std::promise< bool > m_TunSetupResult;
std::unordered_map< uint32_t, service::Address > m_IPs;
std::unordered_map< uint32_t, service::Address > m_IPToAddr;
std::unordered_map< service::Address, uint32_t, service::Address::Hash >
m_AddrToIP;
uint32_t m_OurIP;
uint32_t m_NextIP;
};
} // namespace handlers
} // namespace llarp

@ -51,9 +51,12 @@ namespace llarp
struct IPv4Packet
{
static constexpr size_t MaxSize = 1500;
llarp_time_t timestamp;
size_t sz;
byte_t buf[MaxSize];
llarp_time_t timestamp = 0;
size_t sz = 0;
byte_t buf[MaxSize] = {0};
bool
Load(llarp_buffer_t buf);
struct GetTime
{
@ -95,44 +98,35 @@ namespace llarp
return (iphdr*)buf;
}
uint32_t&
uint32_t
src()
{
return Header()->saddr;
return ntohs(Header()->saddr);
}
uint32_t&
uint32_t
dst()
{
return Header()->daddr;
return ntohs(Header()->daddr);
}
const uint32_t&
src() const
void
src(uint32_t ip)
{
return Header()->saddr;
Header()->saddr = htons(ip);
}
const uint32_t&
dst() const
void
dst(uint32_t ip)
{
return Header()->daddr;
Header()->daddr = htons(ip);
}
/// put the payload of an ip packet
/// recalculate all fields
/// return true on success
/// return false if the payload doesn't fit
bool
PutPayload(llarp_buffer_t buf);
// update ip packet checksum
void
UpdateChecksum();
};
/// parse an ipv4 packet
/// returns nullptr if invalid data
/// copies buffer into return value
std::unique_ptr< IPv4Packet >
ParseIPv4Packet(const void* buf, size_t sz);
} // namespace net
} // namespace llarp

@ -4,6 +4,7 @@
#include <llarp/mem.h>
#include <cctype>
#include <cstdio>
#include <memory>
namespace llarp
{
@ -57,4 +58,15 @@ namespace llarp
} // namespace llarp
#if __cplusplus < 201402L
namespace std
{
template < typename T, typename... Args >
std::unique_ptr< T >
make_unique(Args &&... args)
{
return std::unique_ptr< T >(new T(std::forward< Args >(args)...));
}
} // namespace std
#endif
#endif

@ -252,7 +252,7 @@ namespace llarp
OnOutboundLookup(const IntroSet* i); /* */
static bool
SetupIsolatedNetwork(void* user, bool failed);
SetupIsolatedNetwork(void* user, bool success);
bool
DoNetworkIsolation(bool failed);

@ -37,8 +37,8 @@
#else
#include <net/if.h>
#endif
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in.h>
#endif
#include <stdint.h>
@ -154,8 +154,14 @@ extern "C"
};
/* User definable log callback */
typedef void (*t_tuntap_log)(int, const char *);
TUNTAP_EXPORT t_tuntap_log tuntap_log;
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 *
@ -214,7 +220,7 @@ extern "C"
TUNTAP_EXPORT void
tuntap_log_set_cb(t_tuntap_log cb);
void
tuntap_log_default(int, const char *);
tuntap_log_default(int, int, const char *, const char *);
void
tuntap_log_hexdump(void *, size_t);
void

@ -104,7 +104,10 @@ llarp_ev_udp_sendto(struct llarp_udp_io *udp, const sockaddr *to,
bool
llarp_ev_add_tun(struct llarp_ev_loop *loop, struct llarp_tun_io *tun)
{
return loop->create_tun(tun);
auto dev = loop->create_tun(tun);
if(dev)
return loop->add_ev(dev, false);
return false;
}
bool

@ -39,9 +39,7 @@ namespace llarp
bool
queue_write(const void* data, size_t sz)
{
std::unique_ptr< WriteBuffer > buf =
std::unique_ptr< WriteBuffer >(new WriteBuffer(data, sz));
m_writeq.Put(buf);
m_writeq.Emplace(data, sz);
return m_writeq.Size() <= MAX_WRITE_QUEUE_SIZE;
}
@ -143,7 +141,7 @@ struct llarp_ev_loop
udp_listen(llarp_udp_io* l, const sockaddr* src)
{
auto ev = create_udp(l, src);
return ev && add_ev(ev);
return ev && add_ev(ev, false);
}
virtual llarp::ev_io*
@ -158,7 +156,7 @@ struct llarp_ev_loop
create_tun(llarp_tun_io* tun) = 0;
virtual bool
add_ev(llarp::ev_io* ev, bool write = true) = 0;
add_ev(llarp::ev_io* ev, bool write = false) = 0;
virtual bool
running() const = 0;

@ -85,8 +85,8 @@ namespace llarp
if(t->before_write)
{
t->before_write(t);
ev_io::flush_write();
}
ev_io::flush_write();
}
int
@ -101,12 +101,16 @@ namespace llarp
bool
setup()
{
if(tuntap_start(tunif, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1)
llarp::LogDebug("set up tunif");
if(tuntap_start(tunif, TUNTAP_MODE_TUNNEL, 0) == -1)
return false;
llarp::LogDebug("set ifname to ", t->ifname);
if(tuntap_set_ifname(tunif, t->ifname) == -1)
return false;
if(tuntap_set_ip(tunif, t->ifaddr, t->netmask) == -1)
return false;
if(tuntap_up(tunif) == -1)
return false;
fd = tunif->tun_fd;
return fd != -1;
}
@ -185,10 +189,8 @@ struct llarp_epoll_loop : public llarp_ev_loop
if(events[idx].events & EPOLLIN)
{
ev->read(readbuf, sizeof(readbuf));
}
if(events[idx].events & EPOLLOUT)
{
ev->flush_write();
if(events[idx].events & EPOLLOUT)
ev->flush_write();
}
++idx;
}
@ -221,10 +223,8 @@ struct llarp_epoll_loop : public llarp_ev_loop
if(events[idx].events & EPOLLIN)
{
ev->read(readbuf, sizeof(readbuf));
}
if(events[idx].events & EPOLLOUT)
{
ev->flush_write();
if(events[idx].events & EPOLLOUT)
ev->flush_write();
}
++idx;
}

@ -77,7 +77,17 @@ namespace llarp
bool
TunEndpoint::SetupTun()
{
return llarp_ev_add_tun(EndpointNetLoop(), &tunif);
if(!llarp_ev_add_tun(EndpointNetLoop(), &tunif))
{
llarp::LogError(Name(), " failed to set up tun interface");
return false;
}
m_OurIP = inet_addr(tunif.ifaddr);
m_NextIP = m_OurIP;
char buf[128] = {0};
llarp::LogInfo(Name(), " set ", tunif.ifname, " to have address ",
inet_ntop(AF_INET, &m_OurIP, buf, sizeof(buf)));
return true;
}
bool
@ -100,7 +110,48 @@ namespace llarp
void
TunEndpoint::HandleDataMessage(service::ProtocolMessage *msg)
{
// TODO: implement me
if(msg->proto != service::eProtocolTraffic)
{
llarp::LogWarn("dropping unwarrented message, not ip traffic, proto=",
msg->proto);
return;
}
uint32_t themIP = ObtainIPForAddr(msg->sender.Addr());
uint32_t usIP = m_OurIP;
auto buf = llarp::Buffer(msg->payload);
if(!m_NetworkToUserPktQueue.EmplaceIf(
[buf, themIP, usIP](net::IPv4Packet *pkt) -> bool {
// do packet info rewrite here
// TODO: don't truncate packet here
memcpy(pkt->buf, buf.base, std::min(buf.sz, sizeof(pkt->buf)));
pkt->src(themIP);
pkt->dst(usIP);
pkt->UpdateChecksum();
return true;
}))
{
llarp::LogWarn("failed to parse buffer for ip traffic");
llarp::DumpBuffer(buf);
}
}
uint32_t
TunEndpoint::ObtainIPForAddr(const service::Address &addr)
{
auto itr = m_AddrToIP.find(addr);
if(itr != m_AddrToIP.end())
return itr->second;
uint32_t nextIP = ++m_NextIP;
m_AddrToIP.insert(std::make_pair(addr, nextIP));
m_IPToAddr.insert(std::make_pair(nextIP, addr));
return nextIP;
}
bool
TunEndpoint::HasRemoteForIP(const uint32_t &ip) const
{
return m_IPToAddr.find(ip) != m_IPToAddr.end();
}
void
@ -121,6 +172,7 @@ namespace llarp
TunEndpoint::tunifBeforeWrite(llarp_tun_io *tun)
{
TunEndpoint *self = static_cast< TunEndpoint * >(tun->user);
llarp::LogDebug("tunifBeforeWrite");
self->m_NetworkToUserPktQueue.Process(
[tun](const std::unique_ptr< net::IPv4Packet > &pkt) {
if(!llarp_ev_tun_async_write(tun, pkt->buf, pkt->sz))
@ -133,10 +185,12 @@ namespace llarp
{
// called for every packet read from user in isolated network thread
TunEndpoint *self = static_cast< TunEndpoint * >(tun->user);
std::unique_ptr< net::IPv4Packet > pkt = net::ParseIPv4Packet(buf, sz);
if(pkt)
self->m_UserToNetworkPktQueue.Put(pkt);
llarp::LogDebug("got pkt ", sz, " bytes");
if(!self->m_UserToNetworkPktQueue.EmplaceIf(
[buf, sz](net::IPv4Packet *pkt) -> bool {
return pkt->Load(llarp::InitBuffer(buf, sz));
}))
llarp::LogError("Failed to parse ipv4 packet");
}
TunEndpoint::~TunEndpoint()

@ -5,14 +5,37 @@ namespace llarp
{
namespace net
{
std::unique_ptr< IPv4Packet >
ParseIPv4Packet(const void* buf, size_t sz)
bool
IPv4Packet::Load(llarp_buffer_t pkt)
{
if(sz < 16 || sz > IPv4Packet::MaxSize)
return nullptr;
IPv4Packet* pkt = new IPv4Packet();
memcpy(pkt->buf, buf, sz);
return std::unique_ptr< IPv4Packet >(pkt);
memcpy(buf, pkt.base, std::min(pkt.sz, sizeof(buf)));
return true;
}
void
IPv4Packet::UpdateChecksum()
{
auto hdr = Header();
hdr->check = 0;
size_t count = hdr->ihl;
uint32_t sum = 0;
byte_t *addr = buf;
while(count > 1)
{
sum += ntohs(*(uint16_t *)addr);
count -= sizeof(uint16_t);
addr += sizeof(uint16_t);
}
if(count > 0)
sum += *(byte_t *)addr;
while(sum >> 16)
sum = (sum & 0xffff) + (sum >> 16);
hdr->check = htons(~sum);
}
} // namespace net
} // namespace llarp

@ -95,7 +95,7 @@ namespace llarp
bool
Endpoint::SetupIsolatedNetwork(void* user, bool failed)
{
return static_cast< Endpoint* >(user)->DoNetworkIsolation(failed);
return static_cast< Endpoint* >(user)->DoNetworkIsolation(!failed);
}
bool

@ -1,251 +0,0 @@
/*
* Copyright (c) 2012 Tristan Le Guern <tleguern@bouledef.eu>
*
* 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
#include <winsock2.h>
#include <ws2tcpip.h>
#include <wspiapi.h>
#else
#include <arpa/inet.h>
#include <netinet/in.h>
#endif
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "tuntap.h"
struct device *
tuntap_init(void)
{
struct device *dev = NULL;
if((dev = (struct device *)malloc(sizeof(*dev))) == NULL)
return NULL;
(void)memset(dev->if_name, '\0', sizeof(dev->if_name));
(void)memset(dev->hwaddr, '\0', sizeof(dev->hwaddr));
dev->tun_fd = TUNFD_INVALID_VALUE;
dev->ctrl_sock = -1;
dev->flags = 0;
tuntap_log = tuntap_log_default;
return dev;
}
void
tuntap_destroy(struct device *dev)
{
tuntap_sys_destroy(dev);
tuntap_release(dev);
}
char *
tuntap_get_ifname(struct device *dev)
{
return dev->if_name;
}
int
tuntap_version(void)
{
return TUNTAP_VERSION;
}
#if !defined(FreeBSD)
int
tuntap_set_ip_old(struct device *dev, const char *addr, int netmask)
{
t_tun_in_addr baddr4;
t_tun_in6_addr baddr6;
uint32_t mask;
int errval;
/* Only accept started device */
if(dev->tun_fd == TUNFD_INVALID_VALUE)
{
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
if(addr == NULL)
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'addr'");
return -1;
}
if(netmask < 0 || netmask > 128)
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'netmask'");
return -1;
}
/* Netmask */
mask = ~0;
mask = ~(mask >> netmask);
mask = htonl(mask);
/*
* Destination address parsing: we try IPv4 first and fall back to
* IPv6 if inet_pton return 0
*/
(void)memset(&baddr4, '\0', sizeof(baddr4));
(void)memset(&baddr6, '\0', sizeof(baddr6));
errval = inet_pton(AF_INET, addr, &(baddr4));
if(errval == 1)
{
return tuntap_sys_set_ipv4(dev, &baddr4, mask);
}
else if(errval == 0)
{
if(inet_pton(AF_INET6, addr, &(baddr6)) == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameters");
return -1;
}
return tuntap_sys_set_ipv6(dev, &baddr6, mask);
}
else if(errval == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameters");
return -1;
}
/* NOTREACHED */
return -1;
}
#endif
int
tuntap_set_ip(struct device *dev, ...)
{
va_list vl;
char *saddr;
char *daddr;
int netmask;
t_tun_in_addr sbaddr4;
t_tun_in6_addr sbaddr6;
#if defined(FreeBSD)
t_tun_in_addr dbaddr4;
t_tun_in6_addr dbaddr6;
#endif
uint32_t mask;
int errval;
saddr = daddr = NULL;
netmask = -1;
va_start(vl, dev);
saddr = va_arg(vl, char *);
netmask = va_arg(vl, int);
#if defined(FreeBSD)
if(dev->mode == TUNTAP_MODE_TUNNEL)
daddr = va_arg(vl, char *);
#endif
va_end(vl);
/* Only accept started device */
if(dev->tun_fd == TUNFD_INVALID_VALUE)
{
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
if(saddr == NULL)
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'saddr'");
return -1;
}
if(netmask < 0 || netmask > 128)
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'netmask'");
return -1;
}
/* Netmask */
mask = ~0;
mask = ~(mask >> netmask);
mask = htonl(mask);
/*
* Destination address parsing: we try IPv4 first and fall back to
* IPv6 if inet_pton return 0
*/
(void)memset(&sbaddr4, 0, sizeof(sbaddr4));
(void)memset(&sbaddr6, 0, sizeof(sbaddr6));
errval = inet_pton(AF_INET, saddr, &(sbaddr4));
if(errval == 1)
{
#if defined(FreeBSD)
#define tuntap_sys_set_ipv4 tuntap_sys_set_ipv4_tap
if(dev->mode == TUNTAP_MODE_TUNNEL)
{
if(daddr == NULL)
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'daddr'");
return -1;
}
(void)memset(&dbaddr4, 0, sizeof(dbaddr4));
(void)inet_pton(AF_INET, daddr, &(dbaddr4));
return tuntap_sys_set_ipv4_tun(dev, &sbaddr4, &dbaddr4, mask);
}
else
#endif
{
return tuntap_sys_set_ipv4(dev, &sbaddr4, mask);
}
}
else if(errval == 0)
{
#if !defined(FreeBSD) /* No IPV6 tests YET */
if(inet_pton(AF_INET6, saddr, &(sbaddr6)) == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameters");
return -1;
}
return tuntap_sys_set_ipv6(dev, &sbaddr6, mask);
}
else if(errval == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameters");
return -1;
#endif
}
/* NOTREACHED */
return -1;
}

@ -0,0 +1,256 @@
/*
* Copyright (c) 2012 Tristan Le Guern <tleguern@bouledef.eu>
*
* 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
#include <winsock2.h>
#include <ws2tcpip.h>
#include <wspiapi.h>
#else
#include <arpa/inet.h>
#include <netinet/in.h>
#endif
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <llarp/logger.hpp>
#include "tuntap.h"
extern "C"
{
struct device *
tuntap_init(void)
{
struct device *dev = NULL;
if((dev = (struct device *)malloc(sizeof(*dev))) == NULL)
return NULL;
(void)memset(dev->if_name, '\0', sizeof(dev->if_name));
(void)memset(dev->hwaddr, '\0', sizeof(dev->hwaddr));
dev->tun_fd = TUNFD_INVALID_VALUE;
dev->ctrl_sock = -1;
dev->flags = 0;
__tuntap_log = &tuntap_log_default;
return dev;
}
void
tuntap_destroy(struct device *dev)
{
tuntap_sys_destroy(dev);
tuntap_release(dev);
}
char *
tuntap_get_ifname(struct device *dev)
{
return dev->if_name;
}
int
tuntap_version(void)
{
return TUNTAP_VERSION;
}
#if !defined(FreeBSD)
int
tuntap_set_ip_old(struct device *dev, const char *addr, int netmask)
{
t_tun_in_addr baddr4;
t_tun_in6_addr baddr6;
uint32_t mask;
int errval;
/* Only accept started device */
if(dev->tun_fd == TUNFD_INVALID_VALUE)
{
llarp::LogInfo("device not started");
return 0;
}
if(addr == NULL)
{
llarp::LogError("Invalid address");
return -1;
}
if(netmask < 0 || netmask > 128)
{
llarp::LogError("Invalid netmask");
return -1;
}
/* Netmask */
mask = ~0;
mask = ~(mask >> netmask);
mask = htonl(mask);
/*
* Destination address parsing: we try IPv4 first and fall back to
* IPv6 if inet_pton return 0
*/
(void)memset(&baddr4, '\0', sizeof(baddr4));
(void)memset(&baddr6, '\0', sizeof(baddr6));
errval = inet_pton(AF_INET, addr, &(baddr4));
if(errval == 1)
{
return tuntap_sys_set_ipv4(dev, &baddr4, mask);
}
else if(errval == 0)
{
if(inet_pton(AF_INET6, addr, &(baddr6)) == -1)
{
llarp::LogError("invalid ipv6 address: ", addr);
return -1;
}
return tuntap_sys_set_ipv6(dev, &baddr6, mask);
}
else if(errval == -1)
{
llarp::LogError("invalid address: ", addr);
return -1;
}
/* NOTREACHED */
return -1;
}
#endif
int
tuntap_set_ip(struct device *dev, ...)
{
va_list vl;
char *saddr;
char *daddr;
int netmask;
t_tun_in_addr sbaddr4;
t_tun_in6_addr sbaddr6;
#if defined(FreeBSD)
t_tun_in_addr dbaddr4;
t_tun_in6_addr dbaddr6;
#endif
uint32_t mask;
int errval;
saddr = daddr = NULL;
netmask = -1;
va_start(vl, dev);
saddr = va_arg(vl, char *);
netmask = va_arg(vl, int);
#if defined(FreeBSD)
if(dev->mode == TUNTAP_MODE_TUNNEL)
daddr = va_arg(vl, char *);
#endif
va_end(vl);
/* Only accept started device */
if(dev->tun_fd == TUNFD_INVALID_VALUE)
{
llarp::LogWarn("device not started");
return 0;
}
if(saddr == NULL)
{
llarp::LogWarn("invalid source addr");
return -1;
}
if(netmask < 0 || netmask > 128)
{
llarp::LogWarn("invalid netmask");
return -1;
}
/* Netmask */
mask = ~0;
mask = ~(mask >> netmask);
mask = htonl(mask);
/*
* Destination address parsing: we try IPv4 first and fall back to
* IPv6 if inet_pton return 0
*/
(void)memset(&sbaddr4, 0, sizeof(sbaddr4));
(void)memset(&sbaddr6, 0, sizeof(sbaddr6));
errval = inet_pton(AF_INET, saddr, &(sbaddr4));
if(errval == 1)
{
#if defined(FreeBSD)
#define tuntap_sys_set_ipv4 tuntap_sys_set_ipv4_tap
if(dev->mode == TUNTAP_MODE_TUNNEL)
{
if(daddr == NULL)
{
llarp::LogWarn("invalid destination address");
return -1;
}
(void)memset(&dbaddr4, 0, sizeof(dbaddr4));
(void)inet_pton(AF_INET, daddr, &(dbaddr4));
return tuntap_sys_set_ipv4_tun(dev, &sbaddr4, &dbaddr4, mask);
}
else
#endif
{
return tuntap_sys_set_ipv4(dev, &sbaddr4, mask);
}
}
else if(errval == 0)
{
#if !defined(FreeBSD) /* No IPV6 tests YET */
if(inet_pton(AF_INET6, saddr, &(sbaddr6)) == -1)
{
llarp::LogWarn("invalid ip6 source address: ", saddr);
return -1;
}
return tuntap_sys_set_ipv6(dev, &sbaddr6, mask);
}
else if(errval == -1)
{
llarp::LogWarn("invalid ip6 source address: ", saddr);
return -1;
#endif
}
/* NOTREACHED */
return -1;
}
}

@ -28,37 +28,37 @@
extern "C"
{
t_tuntap_log tuntap_log = &tuntap_log_default;
t_tuntap_log __tuntap_log = &tuntap_log_default;
void
tuntap_log_set_cb(t_tuntap_log cb)
{
if(cb == NULL)
{
tuntap_log = tuntap_log_default;
__tuntap_log = tuntap_log_default;
}
tuntap_log = cb;
__tuntap_log = cb;
}
void
tuntap_log_default(int level, const char *errmsg)
tuntap_log_default(int level, int line, const char *tag, const char *errmsg)
{
switch(level)
{
case TUNTAP_LOG_DEBUG:
llarp::LogDebug(errmsg);
llarp::_Log(llarp::eLogDebug, tag, line, errmsg);
break;
case TUNTAP_LOG_INFO:
llarp::LogInfo(errmsg);
llarp::_Log(llarp::eLogInfo, tag, line, errmsg);
break;
case TUNTAP_LOG_NOTICE:
llarp::LogInfo(errmsg);
llarp::_Log(llarp::eLogInfo, tag, line, errmsg);
break;
case TUNTAP_LOG_WARN:
llarp::LogWarn(errmsg);
llarp::_Log(llarp::eLogWarn, tag, line, errmsg);
break;
case TUNTAP_LOG_ERR:
llarp::LogError(errmsg);
llarp::_Log(llarp::eLogError, tag, line, errmsg);
break;
case TUNTAP_LOG_NONE:
default:

Loading…
Cancel
Save