2017-07-25 23:40:24 -07:00
|
|
|
/*
|
|
|
|
|
* ZeroTier SDK - Network Virtualization Everywhere
|
2019-01-14 12:01:29 -08:00
|
|
|
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
|
2017-07-25 23:40:24 -07:00
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2019-01-14 12:01:29 -08:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2017-07-25 23:40:24 -07:00
|
|
|
*
|
|
|
|
|
* --
|
|
|
|
|
*
|
|
|
|
|
* You can be released from the requirements of the license by purchasing
|
|
|
|
|
* a commercial license. Buying such a license is mandatory as soon as you
|
|
|
|
|
* develop commercial closed-source software that incorporates or links
|
|
|
|
|
* directly against ZeroTier software without disclosing the source code
|
|
|
|
|
* of your own application.
|
|
|
|
|
*/
|
|
|
|
|
|
2017-09-27 02:29:04 -07:00
|
|
|
/**
|
|
|
|
|
* @file
|
|
|
|
|
*
|
2019-01-14 12:01:29 -08:00
|
|
|
* lwIP network stack driver
|
2017-09-27 02:29:04 -07:00
|
|
|
*/
|
2017-09-08 16:13:56 -07:00
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
#include <vector>
|
2019-01-25 12:42:53 -08:00
|
|
|
#include <queue>
|
2017-11-06 13:50:20 -08:00
|
|
|
|
2017-09-27 02:29:04 -07:00
|
|
|
#include "MAC.hpp"
|
2017-08-08 11:16:01 -07:00
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
#include "Mutex.hpp"
|
|
|
|
|
#include "Constants.hpp"
|
|
|
|
|
#include "VirtualTap.hpp"
|
2017-07-26 02:12:28 -07:00
|
|
|
|
2017-07-25 23:40:24 -07:00
|
|
|
#include "netif/ethernet.h"
|
2017-09-27 02:29:04 -07:00
|
|
|
#include "lwip/netif.h"
|
2017-07-25 23:40:24 -07:00
|
|
|
#include "lwip/etharp.h"
|
2017-09-27 02:29:04 -07:00
|
|
|
#include "lwip/tcpip.h"
|
|
|
|
|
#include "lwip/mem.h"
|
|
|
|
|
#include "lwip/memp.h"
|
|
|
|
|
#include "lwip/sys.h"
|
|
|
|
|
#include "lwip/tcp.h"
|
|
|
|
|
#include "lwip/timeouts.h"
|
|
|
|
|
#include "lwip/stats.h"
|
2017-10-16 12:23:10 -07:00
|
|
|
#include "lwip/ethip6.h"
|
2017-11-06 13:50:20 -08:00
|
|
|
#include "lwip/ip_addr.h"
|
|
|
|
|
#include "lwip/nd6.h"
|
|
|
|
|
#include "lwip/dns.h"
|
|
|
|
|
#include "lwip/netifapi.h"
|
2017-07-25 23:40:24 -07:00
|
|
|
|
2017-11-06 13:50:20 -08:00
|
|
|
#include "lwIP.h"
|
2017-09-08 16:13:56 -07:00
|
|
|
|
2018-02-07 18:03:04 -08:00
|
|
|
#if defined(_WIN32)
|
|
|
|
|
#include <time.h>
|
|
|
|
|
void ms_sleep(unsigned long ms)
|
|
|
|
|
{
|
|
|
|
|
Sleep(ms);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-01-25 12:42:53 -08:00
|
|
|
std::queue<struct pbuf *> rx_queue;
|
|
|
|
|
|
2018-02-07 11:35:51 -08:00
|
|
|
ZeroTier::Mutex _rx_input_lock_m;
|
|
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
bool main_loop_exited = false;
|
2017-09-29 15:37:50 -07:00
|
|
|
bool lwip_driver_initialized = false;
|
2019-01-14 12:01:29 -08:00
|
|
|
bool has_already_been_initialized = false;
|
|
|
|
|
int hibernationDelayMultiplier = 1;
|
|
|
|
|
|
2017-09-29 15:37:50 -07:00
|
|
|
ZeroTier::Mutex driver_m;
|
2017-08-14 11:25:44 -07:00
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
std::vector<struct netif *> lwip_netifs;
|
|
|
|
|
|
|
|
|
|
void lwip_hibernate_driver()
|
2017-07-25 23:40:24 -07:00
|
|
|
{
|
2019-01-14 12:01:29 -08:00
|
|
|
hibernationDelayMultiplier = ZTS_HIBERNATION_MULTIPLIER;
|
2017-07-25 23:40:24 -07:00
|
|
|
}
|
|
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
void lwip_wake_driver()
|
2017-09-27 02:29:04 -07:00
|
|
|
{
|
2019-01-14 12:01:29 -08:00
|
|
|
hibernationDelayMultiplier = 1;
|
2017-09-27 02:29:04 -07:00
|
|
|
}
|
|
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
// Callback for when the TCPIP thread has been successfully started
|
2017-09-27 02:29:04 -07:00
|
|
|
static void tcpip_init_done(void *arg)
|
|
|
|
|
{
|
|
|
|
|
sys_sem_t *sem;
|
|
|
|
|
sem = (sys_sem_t *)arg;
|
2017-09-29 15:37:50 -07:00
|
|
|
lwip_driver_initialized = true;
|
|
|
|
|
driver_m.unlock();
|
2017-09-27 02:29:04 -07:00
|
|
|
sys_sem_signal(sem);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-07 11:35:51 -08:00
|
|
|
void my_tcpip_callback(void *arg)
|
|
|
|
|
{
|
2019-01-14 12:01:29 -08:00
|
|
|
if (main_loop_exited) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-01-25 12:42:53 -08:00
|
|
|
err_t err = ERR_OK;
|
2018-02-07 14:23:07 -08:00
|
|
|
int loop_score = LWIP_FRAMES_HANDLED_PER_CORE_CALL; // max num of packets to read per polling call
|
2018-02-07 11:35:51 -08:00
|
|
|
// TODO: Optimize (use Ringbuffer)
|
2019-01-25 12:42:53 -08:00
|
|
|
while (loop_score > 0) {
|
|
|
|
|
// TODO: Swap this block out for a thread-safe container
|
|
|
|
|
_rx_input_lock_m.lock();
|
|
|
|
|
if (rx_queue.size() == 0) {
|
|
|
|
|
_rx_input_lock_m.unlock();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
struct pbuf *p = rx_queue.front();
|
|
|
|
|
rx_queue.pop();
|
|
|
|
|
_rx_input_lock_m.unlock();
|
2018-02-07 11:35:51 -08:00
|
|
|
// Packet routing logic. Inputs packet into correct lwip netif interface depending on protocol type
|
|
|
|
|
struct ip_hdr *iphdr;
|
|
|
|
|
switch (((struct eth_hdr *)p->payload)->type)
|
2019-01-14 12:01:29 -08:00
|
|
|
{
|
2018-02-07 11:35:51 -08:00
|
|
|
case PP_HTONS(ETHTYPE_IPV6): {
|
|
|
|
|
iphdr = (struct ip_hdr *)((char *)p->payload + SIZEOF_ETH_HDR);
|
2019-01-14 12:01:29 -08:00
|
|
|
for (size_t i=0; i<lwip_netifs.size(); i++) {
|
|
|
|
|
if (lwip_netifs[i]->output_ip6 &&
|
|
|
|
|
lwip_netifs[i]->output_ip6 == ethip6_output) {
|
2019-01-25 12:42:53 -08:00
|
|
|
if ((err = lwip_netifs[i]->input(p, lwip_netifs[i])) != ERR_OK) {
|
|
|
|
|
DEBUG_ERROR("packet input error (ipv6, p=%p, netif=%p)=%d", p, &lwip_netifs[i], err);
|
2018-02-07 11:35:51 -08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case PP_HTONS(ETHTYPE_IP): {
|
|
|
|
|
iphdr = (struct ip_hdr *)((char *)p->payload + SIZEOF_ETH_HDR);
|
2019-01-14 12:01:29 -08:00
|
|
|
for (size_t i=0; i<lwip_netifs.size(); i++) {
|
|
|
|
|
if (lwip_netifs[i]->output &&
|
|
|
|
|
lwip_netifs[i]->output == etharp_output) {
|
|
|
|
|
if (lwip_netifs[i]->ip_addr.u_addr.ip4.addr == iphdr->dest.addr ||
|
|
|
|
|
ip4_addr_isbroadcast_u32(iphdr->dest.addr, lwip_netifs[i])) {
|
2019-01-25 12:42:53 -08:00
|
|
|
if ((err = lwip_netifs[i]->input(p, lwip_netifs[i])) != ERR_OK) {
|
|
|
|
|
DEBUG_ERROR("packet input error (ipv4, p=%p, netif=%p)=%d", p, &lwip_netifs[i], err);
|
2018-02-07 11:35:51 -08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case PP_HTONS(ETHTYPE_ARP): {
|
2019-01-14 12:01:29 -08:00
|
|
|
for (size_t i=0; i<lwip_netifs.size(); i++) {
|
|
|
|
|
if (lwip_netifs[i]->state) {
|
2018-02-07 11:35:51 -08:00
|
|
|
pbuf_ref(p);
|
2019-01-25 12:42:53 -08:00
|
|
|
if ((err = lwip_netifs[i]->input(p, lwip_netifs[i])) != ERR_OK) {
|
|
|
|
|
DEBUG_ERROR("packet input error (arp, p=%p, netif=%p)=%d", p, &lwip_netifs[i], err);
|
2018-02-07 11:35:51 -08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
} break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
loop_score--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-27 02:29:04 -07:00
|
|
|
// main thread which starts the initialization process
|
2019-01-14 12:01:29 -08:00
|
|
|
static void main_lwip_driver_loop(void *arg)
|
2017-09-27 02:29:04 -07:00
|
|
|
{
|
2019-01-25 12:42:53 -08:00
|
|
|
#if defined(__linux__)
|
|
|
|
|
pthread_setname_np(pthread_self(), "lwip_driver_loop");
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(__APPLE__)
|
|
|
|
|
pthread_setname_np("lwip_driver_loop");
|
|
|
|
|
#endif
|
2017-09-27 02:29:04 -07:00
|
|
|
sys_sem_t sem;
|
|
|
|
|
LWIP_UNUSED_ARG(arg);
|
|
|
|
|
if (sys_sem_new(&sem, 0) != ERR_OK) {
|
2018-01-31 17:05:23 -08:00
|
|
|
DEBUG_ERROR("failed to create semaphore");
|
2017-09-27 02:29:04 -07:00
|
|
|
}
|
|
|
|
|
tcpip_init(tcpip_init_done, &sem);
|
2019-01-14 12:01:29 -08:00
|
|
|
has_already_been_initialized = true;
|
2017-09-27 02:29:04 -07:00
|
|
|
sys_sem_wait(&sem);
|
2019-01-14 12:01:29 -08:00
|
|
|
while(lwip_driver_initialized) {
|
2018-02-07 18:03:04 -08:00
|
|
|
#if defined(_WIN32)
|
2019-01-14 12:01:29 -08:00
|
|
|
ms_sleep(LWIP_GUARDED_BUF_CHECK_INTERVAL*hibernationDelayMultiplier);
|
2018-02-07 18:03:04 -08:00
|
|
|
#else
|
2019-01-14 12:01:29 -08:00
|
|
|
usleep(LWIP_GUARDED_BUF_CHECK_INTERVAL*1000*hibernationDelayMultiplier);
|
2018-02-07 18:03:04 -08:00
|
|
|
#endif
|
2018-02-07 11:35:51 -08:00
|
|
|
// Handle incoming packets from the core's thread context.
|
|
|
|
|
// If you feed frames into the core directly you will violate the core's thread model
|
|
|
|
|
tcpip_callback_with_block(my_tcpip_callback, NULL, 1);
|
|
|
|
|
}
|
2019-01-14 12:01:29 -08:00
|
|
|
main_loop_exited = true;
|
2017-09-27 02:29:04 -07:00
|
|
|
}
|
|
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
// Initialize the lwIP stack
|
2017-09-27 02:29:04 -07:00
|
|
|
void lwip_driver_init()
|
|
|
|
|
{
|
2019-01-14 12:01:29 -08:00
|
|
|
driver_m.lock(); // Unlocked from callback indicating completion of driver init
|
|
|
|
|
if (has_already_been_initialized || lwip_driver_initialized) {
|
|
|
|
|
// Already initialized, skip
|
|
|
|
|
driver_m.unlock();
|
|
|
|
|
return;
|
|
|
|
|
} if (main_loop_exited) {
|
|
|
|
|
DEBUG_ERROR("stack has previously been shutdown an cannot be restarted.");
|
|
|
|
|
driver_m.unlock();
|
2017-09-27 02:29:04 -07:00
|
|
|
return;
|
|
|
|
|
}
|
2017-12-19 16:23:52 -08:00
|
|
|
#if defined(_WIN32)
|
2019-01-14 12:01:29 -08:00
|
|
|
sys_init(); // Required for win32 init of critical sections
|
2017-10-09 17:56:40 -07:00
|
|
|
#endif
|
2019-01-14 12:01:29 -08:00
|
|
|
void *st = sys_thread_new("main_thread", main_lwip_driver_loop,
|
2017-09-27 02:29:04 -07:00
|
|
|
NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
void lwip_driver_shutdown()
|
|
|
|
|
{
|
|
|
|
|
if (main_loop_exited) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
lwip_driver_initialized = false;
|
|
|
|
|
// Give the stack time to call the frame feed callback one last time before shutting everything down
|
|
|
|
|
int callbackInterval = LWIP_GUARDED_BUF_CHECK_INTERVAL*hibernationDelayMultiplier*1000;
|
|
|
|
|
usleep(callbackInterval*3);
|
|
|
|
|
while(!main_loop_exited) {
|
|
|
|
|
usleep(LWIP_GUARDED_BUF_CHECK_INTERVAL*1000);
|
|
|
|
|
}
|
|
|
|
|
if (tcpip_shutdown() == ERR_OK) {
|
|
|
|
|
sys_timeouts_free();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void lwip_driver_set_all_interfaces_down()
|
|
|
|
|
{
|
|
|
|
|
for (size_t i=0; i<lwip_netifs.size(); i++) {
|
|
|
|
|
if (lwip_netifs[i]) {
|
|
|
|
|
netif_remove(lwip_netifs[i]);
|
|
|
|
|
netif_set_down(lwip_netifs[i]);
|
|
|
|
|
netif_set_link_down(lwip_netifs[i]);
|
|
|
|
|
delete lwip_netifs[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
lwip_netifs.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void lwip_driver_set_tap_interfaces_down(void *tapref)
|
|
|
|
|
{
|
|
|
|
|
int sz_i = lwip_netifs.size();
|
|
|
|
|
std::vector<struct netif*>::iterator iter;
|
|
|
|
|
for (iter = lwip_netifs.begin(); iter != lwip_netifs.end(); ) {
|
|
|
|
|
struct netif *lp = *(iter);
|
|
|
|
|
if (lp->state == tapref) {
|
|
|
|
|
netif_remove(lp);
|
|
|
|
|
netif_set_down(lp);
|
|
|
|
|
netif_set_link_down(lp);
|
|
|
|
|
iter = lwip_netifs.erase(iter);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
++iter;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-17 14:37:01 -07:00
|
|
|
err_t lwip_eth_tx(struct netif *netif, struct pbuf *p)
|
2017-07-25 23:40:24 -07:00
|
|
|
{
|
2017-08-02 14:54:29 -07:00
|
|
|
struct pbuf *q;
|
|
|
|
|
char buf[ZT_MAX_MTU+32];
|
|
|
|
|
char *bufptr;
|
|
|
|
|
int totalLength = 0;
|
2017-07-25 23:40:24 -07:00
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
ZeroTier::VirtualTap *tap = (ZeroTier::VirtualTap*)netif->state;
|
2017-08-02 14:54:29 -07:00
|
|
|
bufptr = buf;
|
2017-09-18 11:58:41 -07:00
|
|
|
for (q = p; q != NULL; q = q->next) {
|
2017-08-02 14:54:29 -07:00
|
|
|
memcpy(bufptr, q->payload, q->len);
|
|
|
|
|
bufptr += q->len;
|
|
|
|
|
totalLength += q->len;
|
|
|
|
|
}
|
|
|
|
|
struct eth_hdr *ethhdr;
|
|
|
|
|
ethhdr = (struct eth_hdr *)buf;
|
2017-07-25 23:40:24 -07:00
|
|
|
|
2017-08-02 14:54:29 -07:00
|
|
|
ZeroTier::MAC src_mac;
|
|
|
|
|
ZeroTier::MAC dest_mac;
|
|
|
|
|
src_mac.setTo(ethhdr->src.addr, 6);
|
|
|
|
|
dest_mac.setTo(ethhdr->dest.addr, 6);
|
2017-07-25 23:40:24 -07:00
|
|
|
|
2017-09-13 22:34:25 -07:00
|
|
|
char *data = buf + sizeof(struct eth_hdr);
|
|
|
|
|
int len = totalLength - sizeof(struct eth_hdr);
|
|
|
|
|
int proto = ZeroTier::Utils::ntoh((uint16_t)ethhdr->type);
|
|
|
|
|
tap->_handler(tap->_arg, NULL, tap->_nwid, src_mac, dest_mac, proto, 0, data, len);
|
2017-09-05 16:51:07 -07:00
|
|
|
|
2017-09-15 19:45:49 -07:00
|
|
|
if (ZT_MSG_TRANSFER == true) {
|
2017-09-05 16:51:07 -07:00
|
|
|
char flagbuf[32];
|
|
|
|
|
memset(&flagbuf, 0, 32);
|
2019-01-14 12:01:29 -08:00
|
|
|
char macBuf[ZTS_MAC_ADDRSTRLEN], nodeBuf[ZTS_ID_LEN];
|
|
|
|
|
snprintf(macBuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
|
|
ethhdr->dest.addr[0], ethhdr->dest.addr[1], ethhdr->dest.addr[2],
|
|
|
|
|
ethhdr->dest.addr[3], ethhdr->dest.addr[4], ethhdr->dest.addr[5]);
|
2017-09-05 16:51:07 -07:00
|
|
|
ZeroTier::MAC mac;
|
|
|
|
|
mac.setTo(ethhdr->dest.addr, 6);
|
|
|
|
|
mac.toAddress(tap->_nwid).toString(nodeBuf);
|
2019-01-14 12:01:29 -08:00
|
|
|
DEBUG_TRANS("len=%5d dst=%s [%s TX <-- %s] proto=0x%04x %s", totalLength, macBuf, nodeBuf, tap->nodeId().c_str(),
|
|
|
|
|
ZeroTier::Utils::ntoh(ethhdr->type), flagbuf);
|
2017-09-05 16:51:07 -07:00
|
|
|
}
|
2019-01-25 12:42:53 -08:00
|
|
|
|
|
|
|
|
|
2017-08-02 14:54:29 -07:00
|
|
|
return ERR_OK;
|
2017-07-25 23:40:24 -07:00
|
|
|
}
|
|
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
void lwip_eth_rx(ZeroTier::VirtualTap *tap, const ZeroTier::MAC &from, const ZeroTier::MAC &to, unsigned int etherType,
|
2017-09-27 02:29:04 -07:00
|
|
|
const void *data, unsigned int len)
|
|
|
|
|
{
|
2019-01-25 12:42:53 -08:00
|
|
|
if (!lwip_netifs.size()) {
|
|
|
|
|
DEBUG_ERROR("there are no netifs set up to handle this packet. ignoring.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-27 02:29:04 -07:00
|
|
|
struct pbuf *p,*q;
|
|
|
|
|
struct eth_hdr ethhdr;
|
|
|
|
|
from.copyTo(ethhdr.src.addr, 6);
|
|
|
|
|
to.copyTo(ethhdr.dest.addr, 6);
|
|
|
|
|
ethhdr.type = ZeroTier::Utils::hton((uint16_t)etherType);
|
|
|
|
|
|
2017-11-13 15:27:56 -08:00
|
|
|
if (ZT_MSG_TRANSFER == true) {
|
|
|
|
|
char flagbuf[32];
|
|
|
|
|
memset(&flagbuf, 0, 32);
|
2019-01-14 12:01:29 -08:00
|
|
|
char macBuf[ZTS_MAC_ADDRSTRLEN], nodeBuf[ZTS_ID_LEN];
|
|
|
|
|
snprintf(macBuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
|
|
ethhdr.dest.addr[0], ethhdr.dest.addr[1], ethhdr.dest.addr[2],
|
|
|
|
|
ethhdr.dest.addr[3], ethhdr.dest.addr[4], ethhdr.dest.addr[5]);
|
2017-11-13 15:27:56 -08:00
|
|
|
ZeroTier::MAC mac;
|
|
|
|
|
mac.setTo(ethhdr.src.addr, 6);
|
|
|
|
|
mac.toAddress(tap->_nwid).toString(nodeBuf);
|
2019-01-14 12:01:29 -08:00
|
|
|
DEBUG_TRANS("len=%5d dst=%s [%s RX --> %s] proto=0x%04x %s", len, macBuf, nodeBuf, tap->nodeId().c_str(),
|
|
|
|
|
ZeroTier::Utils::ntoh(ethhdr.type), flagbuf);
|
2017-11-13 15:27:56 -08:00
|
|
|
}
|
2019-01-25 12:42:53 -08:00
|
|
|
|
|
|
|
|
p = pbuf_alloc(PBUF_RAW, len+sizeof(struct eth_hdr), PBUF_RAM);
|
|
|
|
|
if (!p) {
|
|
|
|
|
DEBUG_ERROR("dropped packet: unable to allocate memory for pbuf");
|
2017-09-27 02:29:04 -07:00
|
|
|
return;
|
2017-08-02 14:54:29 -07:00
|
|
|
}
|
2019-01-25 12:42:53 -08:00
|
|
|
// First pbuf gets ethernet header at start
|
|
|
|
|
q = p;
|
|
|
|
|
if (q->len < sizeof(ethhdr)) {
|
|
|
|
|
DEBUG_ERROR("dropped packet: first pbuf smaller than ethernet header");
|
2017-11-13 15:27:56 -08:00
|
|
|
return;
|
2017-08-02 14:54:29 -07:00
|
|
|
}
|
2019-01-25 12:42:53 -08:00
|
|
|
const char *dataptr = reinterpret_cast<const char *>(data);
|
|
|
|
|
memcpy(q->payload,ðhdr,sizeof(ethhdr));
|
|
|
|
|
int remainingPayloadSpace = q->len - sizeof(ethhdr);
|
|
|
|
|
memcpy((char*)q->payload + sizeof(ethhdr),dataptr,remainingPayloadSpace);
|
|
|
|
|
dataptr += remainingPayloadSpace;
|
|
|
|
|
// Remaining pbufs (if any) get rest of data
|
|
|
|
|
while ((q = q->next)) {
|
|
|
|
|
memcpy(q->payload,dataptr,q->len);
|
|
|
|
|
dataptr += q->len;
|
|
|
|
|
}
|
|
|
|
|
_rx_input_lock_m.lock();
|
|
|
|
|
if (rx_queue.size() >= LWIP_MAX_GUARDED_RX_BUF_SZ) {
|
|
|
|
|
DEBUG_INFO("dropped packet: rx_queue is full (>= %d)", LWIP_MAX_GUARDED_RX_BUF_SZ);
|
2018-10-11 15:54:24 -07:00
|
|
|
return;
|
2017-11-06 13:50:20 -08:00
|
|
|
}
|
2019-01-25 12:42:53 -08:00
|
|
|
rx_queue.push(p);
|
|
|
|
|
_rx_input_lock_m.unlock();
|
2017-11-06 13:50:20 -08:00
|
|
|
}
|
|
|
|
|
|
2017-12-07 16:45:02 -08:00
|
|
|
/*
|
2017-11-21 15:53:31 -08:00
|
|
|
void lwip_dns_init()
|
|
|
|
|
{
|
|
|
|
|
dns_init();
|
|
|
|
|
}
|
2017-12-07 16:45:02 -08:00
|
|
|
*/
|
2017-11-21 15:53:31 -08:00
|
|
|
|
|
|
|
|
void lwip_start_dhcp(void *netif)
|
|
|
|
|
{
|
|
|
|
|
#if defined(LIBZT_IPV4)
|
2018-07-19 17:19:06 -07:00
|
|
|
//netifapi_dhcp_start((struct netif *)netif);
|
2017-11-21 15:53:31 -08:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-25 12:42:53 -08:00
|
|
|
/*
|
2018-07-25 14:01:12 -07:00
|
|
|
static void netif_status_callback(struct netif *netif)
|
|
|
|
|
{
|
|
|
|
|
DEBUG_INFO("n=%p, %c%c, %d, o=%p, o6=%p, mc=%x:%x:%x:%x:%x:%x, hwln=%d, st=%p, flgs=%d\n",
|
|
|
|
|
netif,
|
|
|
|
|
netif->name[0],
|
|
|
|
|
netif->name[1],
|
|
|
|
|
netif->mtu,
|
|
|
|
|
netif->output,
|
|
|
|
|
netif->output_ip6,
|
|
|
|
|
netif->hwaddr[0],
|
|
|
|
|
netif->hwaddr[1],
|
|
|
|
|
netif->hwaddr[2],
|
|
|
|
|
netif->hwaddr[3],
|
|
|
|
|
netif->hwaddr[4],
|
|
|
|
|
netif->hwaddr[5],
|
|
|
|
|
netif->hwaddr_len,
|
|
|
|
|
netif->state,
|
|
|
|
|
netif->flags
|
|
|
|
|
);
|
|
|
|
|
}
|
2019-01-25 12:42:53 -08:00
|
|
|
*/
|
2018-07-25 14:01:12 -07:00
|
|
|
|
|
|
|
|
ZeroTier::MAC _mac;
|
|
|
|
|
|
|
|
|
|
static err_t netif_init_4(struct netif *netif)
|
|
|
|
|
{
|
|
|
|
|
netif->hwaddr_len = 6;
|
|
|
|
|
netif->name[0] = 'e';
|
2019-01-14 12:01:29 -08:00
|
|
|
netif->name[1] = '0'+lwip_netifs.size();
|
2018-07-25 14:01:12 -07:00
|
|
|
netif->linkoutput = lwip_eth_tx;
|
|
|
|
|
netif->output = etharp_output;
|
|
|
|
|
netif->mtu = ZT_MAX_MTU;
|
|
|
|
|
netif->flags = NETIF_FLAG_BROADCAST
|
|
|
|
|
| NETIF_FLAG_ETHARP
|
|
|
|
|
| NETIF_FLAG_ETHERNET
|
|
|
|
|
| NETIF_FLAG_IGMP
|
|
|
|
|
| NETIF_FLAG_LINK_UP
|
|
|
|
|
| NETIF_FLAG_UP;
|
|
|
|
|
_mac.copyTo(netif->hwaddr, netif->hwaddr_len);
|
|
|
|
|
netif->hwaddr_len = sizeof(netif->hwaddr);
|
|
|
|
|
return ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static err_t netif_init_6(struct netif *netif)
|
|
|
|
|
{
|
|
|
|
|
netif->hwaddr_len = 6;
|
|
|
|
|
netif->name[0] = 'e';
|
2019-01-14 12:01:29 -08:00
|
|
|
netif->name[1] = '0'+(char)lwip_netifs.size();
|
2018-07-25 14:01:12 -07:00
|
|
|
netif->linkoutput = lwip_eth_tx;
|
|
|
|
|
netif->output = etharp_output;
|
|
|
|
|
netif->output_ip6 = ethip6_output;
|
|
|
|
|
netif->mtu = ZT_MAX_MTU;
|
|
|
|
|
netif->flags = NETIF_FLAG_BROADCAST
|
|
|
|
|
| NETIF_FLAG_ETHARP
|
|
|
|
|
| NETIF_FLAG_ETHERNET
|
|
|
|
|
| NETIF_FLAG_IGMP
|
|
|
|
|
| NETIF_FLAG_MLD6;
|
|
|
|
|
_mac.copyTo(netif->hwaddr, netif->hwaddr_len);
|
|
|
|
|
netif->hwaddr_len = sizeof(netif->hwaddr);
|
|
|
|
|
return ERR_OK;
|
|
|
|
|
}
|
2018-07-19 17:19:06 -07:00
|
|
|
|
2017-11-21 15:53:31 -08:00
|
|
|
void lwip_init_interface(void *tapref, const ZeroTier::MAC &mac, const ZeroTier::InetAddress &ip)
|
|
|
|
|
{
|
2019-01-14 12:01:29 -08:00
|
|
|
char ipbuf[INET6_ADDRSTRLEN];
|
|
|
|
|
char macbuf[ZTS_MAC_ADDRSTRLEN];
|
|
|
|
|
struct netif *lwipdev = new struct netif;
|
|
|
|
|
lwip_netifs.push_back(lwipdev);
|
|
|
|
|
|
2018-07-25 14:01:12 -07:00
|
|
|
_mac = mac;
|
2017-11-21 15:53:31 -08:00
|
|
|
|
|
|
|
|
if (ip.isV4()) {
|
2019-01-14 12:01:29 -08:00
|
|
|
char nmbuf[INET6_ADDRSTRLEN];
|
2017-11-21 15:53:31 -08:00
|
|
|
static ip4_addr_t ipaddr, netmask, gw;
|
|
|
|
|
IP4_ADDR(&gw,127,0,0,1);
|
|
|
|
|
ipaddr.addr = *((u32_t *)ip.rawIpData());
|
|
|
|
|
netmask.addr = *((u32_t *)ip.netmask().rawIpData());
|
2019-01-25 12:42:53 -08:00
|
|
|
//netif_set_status_callback(lwipdev, netif_status_callback);
|
2018-07-25 14:01:12 -07:00
|
|
|
netif_add(lwipdev, &ipaddr, &netmask, &gw, NULL, netif_init_4, tcpip_input);
|
2017-11-21 15:53:31 -08:00
|
|
|
lwipdev->state = tapref;
|
2019-01-14 12:01:29 -08:00
|
|
|
snprintf(macbuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
|
|
lwipdev->hwaddr[0], lwipdev->hwaddr[1], lwipdev->hwaddr[2],
|
|
|
|
|
lwipdev->hwaddr[3], lwipdev->hwaddr[4], lwipdev->hwaddr[5]);
|
|
|
|
|
DEBUG_INFO("initialized netif as [mac=%s, addr=%s, nm=%s]",
|
|
|
|
|
macbuf, ip.toString(ipbuf), ip.netmask().toString(nmbuf));
|
2017-11-21 15:53:31 -08:00
|
|
|
}
|
2018-07-25 14:01:12 -07:00
|
|
|
if (ip.isV6())
|
|
|
|
|
{
|
2017-11-21 15:53:31 -08:00
|
|
|
static ip6_addr_t ipaddr;
|
|
|
|
|
memcpy(&(ipaddr.addr), ip.rawIpData(), sizeof(ipaddr.addr));
|
2018-09-20 17:51:44 -07:00
|
|
|
lwipdev->ip6_autoconfig_enabled = 1;
|
2018-07-25 14:01:12 -07:00
|
|
|
netif_add(lwipdev, NULL, NULL, NULL, NULL, netif_init_6, tcpip_input);
|
2018-09-20 17:51:44 -07:00
|
|
|
netif_ip6_addr_set(lwipdev, 1, &ipaddr);
|
2017-11-21 15:53:31 -08:00
|
|
|
lwipdev->state = tapref;
|
2018-09-20 17:51:44 -07:00
|
|
|
netif_create_ip6_linklocal_address(lwipdev, 1);
|
|
|
|
|
netif_ip6_addr_set_state(lwipdev, 0, IP6_ADDR_TENTATIVE);
|
2018-07-25 14:01:12 -07:00
|
|
|
netif_ip6_addr_set_state(lwipdev, 1, IP6_ADDR_TENTATIVE);
|
2019-01-25 12:42:53 -08:00
|
|
|
//netif_set_status_callback(lwipdev, netif_status_callback);
|
2017-11-21 15:53:31 -08:00
|
|
|
netif_set_default(lwipdev);
|
|
|
|
|
netif_set_up(lwipdev);
|
|
|
|
|
netif_set_link_up(lwipdev);
|
2019-01-14 12:01:29 -08:00
|
|
|
snprintf(macbuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
|
|
lwipdev->hwaddr[0], lwipdev->hwaddr[1], lwipdev->hwaddr[2],
|
|
|
|
|
lwipdev->hwaddr[3], lwipdev->hwaddr[4], lwipdev->hwaddr[5]);
|
|
|
|
|
DEBUG_INFO("initialized netif as [mac=%s, addr=%s]",
|
|
|
|
|
macbuf, ip.toString(ipbuf));
|
2017-11-21 15:53:31 -08:00
|
|
|
}
|
|
|
|
|
}
|