mirror of https://github.com/oxen-io/lokinet
more tun stuff
This commit is contained in:
parent
e8daf53600
commit
4aebbda640
|
@ -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()
|
||||
|
|
37
llarp/ip.cpp
37
llarp/ip.cpp
|
@ -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…
Reference in New Issue