mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 12:33:44 +02:00
Commit of a draft of the pcap-based strategy for a Windows tap. This may, in the end, not work, since winpcap may not support immediate capture and also because some software flags winpcap as malware. Like I said, trying to do anything interesting with Windows is PAIN.
This commit is contained in:
parent
d19516b40a
commit
c8213a3f58
4 changed files with 228 additions and 17 deletions
|
@ -679,6 +679,8 @@ void EthernetTap::threadMain()
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
#include <WinSock2.h>
|
#include <WinSock2.h>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
|
@ -689,6 +691,165 @@ void EthernetTap::threadMain()
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
/* Background thread that handles I/O to/from all running
|
||||||
|
* EthernetTap instances using WinPcap -- this must be
|
||||||
|
* managed from a single thread because of the need to
|
||||||
|
* "reboot" npf every time a new interface is added. */
|
||||||
|
class _WinEthernetTapPcapIOThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
_WinEthernetTapPcapIOThread()
|
||||||
|
{
|
||||||
|
scManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
|
||||||
|
if (scManager == NULL)
|
||||||
|
fprintf(stderr,"ZeroTier One: WARNING: unable to OpenSCManager(), tap will have issues with new devices!\r\n");
|
||||||
|
updateSem = CreateSemaphore(NULL,0,1,NULL); // binary
|
||||||
|
run = true;
|
||||||
|
needReload = false;
|
||||||
|
thread = Thread::start(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~_WinEthernetTapPcapIOThread()
|
||||||
|
{
|
||||||
|
run = false;
|
||||||
|
needReload = false;
|
||||||
|
ReleaseSemaphore(updateSem,1,NULL);
|
||||||
|
Thread::join(thread);
|
||||||
|
CloseHandle(updateSem);
|
||||||
|
if (scManager != NULL)
|
||||||
|
CloseServiceHandle(scManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void threadMain()
|
||||||
|
throw()
|
||||||
|
{
|
||||||
|
HANDLE *objects = new HANDLE[1];
|
||||||
|
objects[0] = updateSem;
|
||||||
|
DWORD numObjects = 1;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
if (!run) {
|
||||||
|
delete [] objects;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("waiting on: %d\r\n",(int)numObjects);
|
||||||
|
WaitForMultipleObjects(numObjects,objects,FALSE,INFINITE);
|
||||||
|
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(taps_m);
|
||||||
|
|
||||||
|
for(std::list<EthernetTap *>::iterator tapptr(taps.begin());tapptr!=taps.end();++tapptr) {
|
||||||
|
EthernetTap *tap = *tapptr;
|
||||||
|
if (tap->_pcap) {
|
||||||
|
{
|
||||||
|
Mutex::Lock _l2(tap->_injectPending_m);
|
||||||
|
while (!tap->_injectPending.empty()) {
|
||||||
|
pcap_sendpacket(tap->_pcap,(const u_char *)(tap->_injectPending.front().first.data),tap->_injectPending.front().second);
|
||||||
|
tap->_injectPending.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("dispatch: %s\r\n",tap->_myDeviceInstanceId.c_str());
|
||||||
|
pcap_dispatch(tap->_pcap,-1,&EthernetTap::_pcapHandler,(u_char *)tap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needReload) {
|
||||||
|
// Close all taps and restart WinPcap driver to scan for possible new
|
||||||
|
// interfaces... yuck. This is done because WinPcap does not support
|
||||||
|
// hot plug, so if we've added a new loopback adapter it won't show
|
||||||
|
// up without this full system refresh.
|
||||||
|
needReload = false;
|
||||||
|
|
||||||
|
for(std::list<EthernetTap *>::iterator tapptr(taps.begin());tapptr!=taps.end();++tapptr) {
|
||||||
|
if ((*tapptr)->_pcap) {
|
||||||
|
pcap_close((*tapptr)->_pcap);
|
||||||
|
(*tapptr)->_pcap = (pcap_t *)0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scManager != NULL) {
|
||||||
|
Thread::sleep(250);
|
||||||
|
SC_HANDLE npfService = OpenServiceA(scManager,"npf",SERVICE_ALL_ACCESS);
|
||||||
|
if (npfService != NULL) {
|
||||||
|
SERVICE_STATUS sstatus;
|
||||||
|
memset(&sstatus,0,sizeof(SERVICE_STATUS));
|
||||||
|
ControlService(npfService,SERVICE_CONTROL_STOP,&sstatus);
|
||||||
|
printf("service restart\r\n");
|
||||||
|
CloseServiceHandle(npfService);
|
||||||
|
}
|
||||||
|
Thread::sleep(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] objects;
|
||||||
|
objects = new HANDLE[taps.size() + 1];
|
||||||
|
objects[0] = updateSem;
|
||||||
|
numObjects = 1;
|
||||||
|
|
||||||
|
pcap_if_t *alldevs;
|
||||||
|
char pcaperrbuf[PCAP_ERRBUF_SIZE+1];
|
||||||
|
if (pcap_findalldevs(&alldevs,pcaperrbuf) != -1) {
|
||||||
|
for(std::list<EthernetTap *>::iterator tapptr(taps.begin());tapptr!=taps.end();++tapptr) {
|
||||||
|
EthernetTap *tap = *tapptr;
|
||||||
|
pcap_if_t *mydev = (pcap_if_t *)0;
|
||||||
|
for(mydev=alldevs;(mydev);mydev=mydev->next) {
|
||||||
|
if (strstr(mydev->name,tap->_myDeviceInstanceId.c_str()))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (mydev) {
|
||||||
|
tap->_pcap = pcap_open_live(mydev->name,65535,1,0,pcaperrbuf);
|
||||||
|
pcap_setnonblock(tap->_pcap,1,pcaperrbuf);
|
||||||
|
if (tap->_pcap) {
|
||||||
|
printf("pcap opened: %s\r\n",mydev->name);
|
||||||
|
objects[numObjects++] = pcap_getevent(tap->_pcap);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tap->_pcap = (pcap_t *)0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pcap_freealldevs(alldevs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!run) {
|
||||||
|
delete [] objects;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void addTap(EthernetTap *t)
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(taps_m);
|
||||||
|
taps.push_back(t);
|
||||||
|
needReload = true;
|
||||||
|
ReleaseSemaphore(updateSem,1,NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void removeTap(EthernetTap *t)
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(taps_m);
|
||||||
|
for(std::list<EthernetTap *>::iterator tapptr(taps.begin());tapptr!=taps.end();++tapptr) {
|
||||||
|
if (*tapptr == t) {
|
||||||
|
taps.erase(tapptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
needReload = true;
|
||||||
|
ReleaseSemaphore(updateSem,1,NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<EthernetTap *> taps;
|
||||||
|
Mutex taps_m;
|
||||||
|
SC_HANDLE scManager;
|
||||||
|
HANDLE updateSem;
|
||||||
|
volatile bool run;
|
||||||
|
volatile bool needReload;
|
||||||
|
Thread thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
static _WinEthernetTapPcapIOThread _pcapIoThread;
|
||||||
static Mutex _systemTapInitLock;
|
static Mutex _systemTapInitLock;
|
||||||
|
|
||||||
EthernetTap::EthernetTap(
|
EthernetTap::EthernetTap(
|
||||||
|
@ -703,7 +864,8 @@ EthernetTap::EthernetTap(
|
||||||
_mtu(mtu),
|
_mtu(mtu),
|
||||||
_r(renv),
|
_r(renv),
|
||||||
_handler(handler),
|
_handler(handler),
|
||||||
_arg(arg)
|
_arg(arg),
|
||||||
|
_pcap((pcap_t *)0)
|
||||||
{
|
{
|
||||||
char subkeyName[1024];
|
char subkeyName[1024];
|
||||||
char subkeyClass[1024];
|
char subkeyClass[1024];
|
||||||
|
@ -715,7 +877,6 @@ EthernetTap::EthernetTap(
|
||||||
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS)
|
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS)
|
||||||
throw std::runtime_error("unable to open registry key for network adapter enumeration");
|
throw std::runtime_error("unable to open registry key for network adapter enumeration");
|
||||||
|
|
||||||
std::string myDeviceInstanceId;
|
|
||||||
std::set<std::string> existingDeviceInstances;
|
std::set<std::string> existingDeviceInstances;
|
||||||
|
|
||||||
// Enumerate all Microsoft Loopback Adapter instances and look for one
|
// Enumerate all Microsoft Loopback Adapter instances and look for one
|
||||||
|
@ -742,7 +903,7 @@ EthernetTap::EthernetTap(
|
||||||
existingDeviceInstances.insert(instanceId);
|
existingDeviceInstances.insert(instanceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((myDeviceInstanceId.length() == 0)&&(instanceId.length() != 0)) {
|
if ((_myDeviceInstanceId.length() == 0)&&(instanceId.length() != 0)) {
|
||||||
type = 0;
|
type = 0;
|
||||||
dataLen = sizeof(data);
|
dataLen = sizeof(data);
|
||||||
if (RegGetValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
|
if (RegGetValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
|
||||||
|
@ -751,7 +912,7 @@ EthernetTap::EthernetTap(
|
||||||
type = 0;
|
type = 0;
|
||||||
dataLen = sizeof(data);
|
dataLen = sizeof(data);
|
||||||
if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
|
if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
|
||||||
myDeviceInstanceId = instanceId;
|
_myDeviceInstanceId = instanceId;
|
||||||
subkeyIndex = -1; // break outer loop
|
subkeyIndex = -1; // break outer loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -764,13 +925,13 @@ EthernetTap::EthernetTap(
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is no device, try to create one
|
// If there is no device, try to create one
|
||||||
if (myDeviceInstanceId.length() == 0) {
|
if (_myDeviceInstanceId.length() == 0) {
|
||||||
// Execute devcon to install an instance of the Microsoft Loopback Adapter
|
// Execute devcon to install an instance of the Microsoft Loopback Adapter
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
std::string devcon(_r->homePath + "\\devcon64.exe");
|
const char *devcon = "\\devcon64.exe";
|
||||||
#else
|
#else
|
||||||
BOOL f64 = FALSE;
|
BOOL f64 = FALSE;
|
||||||
std::string devcon(_r->homePath + ((IsWow64Process(GetCurrentProcess(),&f64) == TRUE) ? "\\devcon64.exe" : "\\devcon32.exe"));
|
const char *devcon = ((IsWow64Process(GetCurrentProcess(),&f64) == TRUE) ? "\\devcon64.exe" : "\\devcon32.exe");
|
||||||
#endif
|
#endif
|
||||||
char windir[4096];
|
char windir[4096];
|
||||||
windir[0] = '\0';
|
windir[0] = '\0';
|
||||||
|
@ -780,7 +941,7 @@ EthernetTap::EthernetTap(
|
||||||
PROCESS_INFORMATION processInfo;
|
PROCESS_INFORMATION processInfo;
|
||||||
memset(&startupInfo,0,sizeof(STARTUPINFOA));
|
memset(&startupInfo,0,sizeof(STARTUPINFOA));
|
||||||
memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
|
memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
|
||||||
if (!CreateProcessA(NULL,(LPSTR)(devcon + " install " + windir + "\\inf\\netloop.inf *msloop").c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) {
|
if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" install " + windir + "\\inf\\netloop.inf *msloop").c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) {
|
||||||
RegCloseKey(nwAdapters);
|
RegCloseKey(nwAdapters);
|
||||||
throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon);
|
throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon);
|
||||||
}
|
}
|
||||||
|
@ -809,7 +970,7 @@ EthernetTap::EthernetTap(
|
||||||
if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
|
if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
|
||||||
if (existingDeviceInstances.count(std::string(data,dataLen)) == 0) {
|
if (existingDeviceInstances.count(std::string(data,dataLen)) == 0) {
|
||||||
RegSetKeyValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",REG_SZ,tag,strlen(tag)+1);
|
RegSetKeyValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",REG_SZ,tag,strlen(tag)+1);
|
||||||
myDeviceInstanceId.assign(data,dataLen);
|
_myDeviceInstanceId.assign(data,dataLen);
|
||||||
subkeyIndex = -1; // break outer loop
|
subkeyIndex = -1; // break outer loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -822,12 +983,18 @@ EthernetTap::EthernetTap(
|
||||||
|
|
||||||
RegCloseKey(nwAdapters);
|
RegCloseKey(nwAdapters);
|
||||||
|
|
||||||
if (myDeviceInstanceId.length() == 0)
|
if (_myDeviceInstanceId.length() == 0)
|
||||||
throw std::runtime_error("unable to create new loopback adapter for tap");
|
throw std::runtime_error("unable to create new loopback adapter for tap");
|
||||||
|
|
||||||
|
// pcap is opened and managed by the pcap I/O thread
|
||||||
|
_pcapIoThread.addTap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
EthernetTap::~EthernetTap()
|
EthernetTap::~EthernetTap()
|
||||||
{
|
{
|
||||||
|
_pcapIoThread.removeTap(this);
|
||||||
|
if (_pcap)
|
||||||
|
pcap_close(_pcap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EthernetTap::whack()
|
void EthernetTap::whack()
|
||||||
|
@ -846,21 +1013,38 @@ bool EthernetTap::removeIP(const InetAddress &ip)
|
||||||
|
|
||||||
void EthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
|
void EthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
|
||||||
{
|
{
|
||||||
|
if (len > (ZT_IF_MTU))
|
||||||
|
return;
|
||||||
|
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(_injectPending_m);
|
||||||
|
_injectPending.push( std::pair<Array<char,ZT_IF_MTU + 32>,unsigned int>(Array<char,ZT_IF_MTU + 32>(),len + 14) );
|
||||||
|
char *d = _injectPending.back().first.data;
|
||||||
|
memcpy(d,to.data,6);
|
||||||
|
memcpy(d + 6,from.data,6);
|
||||||
|
*((uint16_t *)(d + 12)) = Utils::hton(etherType);
|
||||||
|
memcpy(d + 14,data,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSemaphore(_pcapIoThread.updateSem,1,NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EthernetTap::deviceName() const
|
std::string EthernetTap::deviceName() const
|
||||||
{
|
{
|
||||||
return std::string();
|
return _myDeviceInstanceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
|
bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EthernetTap::threadMain()
|
void EthernetTap::_pcapHandler(u_char *user,const struct pcap_pkthdr *pkt_header,const u_char *pkt_data)
|
||||||
throw()
|
|
||||||
{
|
{
|
||||||
|
printf("got packet: %d\r\n",(int)pkt_header->len);
|
||||||
|
if (pkt_header->len > 14)
|
||||||
|
((EthernetTap *)user)->_handler(((EthernetTap *)user)->_arg,MAC(pkt_data + 6),MAC(pkt_data),Utils::ntoh(*((const uint16_t *)(pkt_data + 12))),Buffer<4096>(pkt_data + 14,pkt_header->len - 14));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
|
@ -30,12 +30,15 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <queue>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "Constants.hpp"
|
#include "Constants.hpp"
|
||||||
#include "InetAddress.hpp"
|
#include "InetAddress.hpp"
|
||||||
#include "MAC.hpp"
|
#include "MAC.hpp"
|
||||||
|
@ -43,16 +46,30 @@
|
||||||
#include "MulticastGroup.hpp"
|
#include "MulticastGroup.hpp"
|
||||||
#include "Thread.hpp"
|
#include "Thread.hpp"
|
||||||
#include "Buffer.hpp"
|
#include "Buffer.hpp"
|
||||||
|
#include "Array.hpp"
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
#include <pcap/pcap.h>
|
||||||
|
#include <pcap/bpf.h>
|
||||||
|
#include <Win32-Extensions.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
class RuntimeEnvironment;
|
class RuntimeEnvironment;
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
class _WinEthernetTapPcapIOThread;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* System ethernet tap device
|
* System ethernet tap device
|
||||||
*/
|
*/
|
||||||
class EthernetTap
|
class EthernetTap
|
||||||
{
|
{
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
friend class _WinEthernetTapPcapIOThread;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Construct a new TAP device
|
* Construct a new TAP device
|
||||||
|
@ -172,18 +189,19 @@ public:
|
||||||
*/
|
*/
|
||||||
bool updateMulticastGroups(std::set<MulticastGroup> &groups);
|
bool updateMulticastGroups(std::set<MulticastGroup> &groups);
|
||||||
|
|
||||||
|
#ifdef __UNIX_LIKE__
|
||||||
/**
|
/**
|
||||||
* Thread main method; do not call elsewhere
|
* Thread main method; do not call elsewhere
|
||||||
*/
|
*/
|
||||||
void threadMain()
|
void threadMain()
|
||||||
throw();
|
throw();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const MAC _mac;
|
const MAC _mac;
|
||||||
const unsigned int _mtu;
|
const unsigned int _mtu;
|
||||||
|
|
||||||
const RuntimeEnvironment *_r;
|
const RuntimeEnvironment *_r;
|
||||||
Thread _thread;
|
|
||||||
|
|
||||||
std::set<InetAddress> _ips;
|
std::set<InetAddress> _ips;
|
||||||
Mutex _ips_m;
|
Mutex _ips_m;
|
||||||
|
@ -192,10 +210,19 @@ private:
|
||||||
void *_arg;
|
void *_arg;
|
||||||
|
|
||||||
#ifdef __UNIX_LIKE__
|
#ifdef __UNIX_LIKE__
|
||||||
|
Thread _thread;
|
||||||
char _dev[16];
|
char _dev[16];
|
||||||
int _fd;
|
int _fd;
|
||||||
int _shutdownSignalPipe[2];
|
int _shutdownSignalPipe[2];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
pcap_t *_pcap;
|
||||||
|
std::string _myDeviceInstanceId;
|
||||||
|
std::queue< std::pair< Array<char,ZT_IF_MTU + 32>,unsigned int > > _injectPending;
|
||||||
|
Mutex _injectPending_m;
|
||||||
|
static void _pcapHandler(u_char *user,const struct pcap_pkthdr *pkt_header,const u_char *pkt_data);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
|
@ -412,7 +412,7 @@ int main(int argc,char **argv)
|
||||||
RuntimeEnvironment renv;
|
RuntimeEnvironment renv;
|
||||||
renv.homePath = "C:";
|
renv.homePath = "C:";
|
||||||
EthernetTap tap(&renv,"test12345",MAC(),2800,NULL,NULL);
|
EthernetTap tap(&renv,"test12345",MAC(),2800,NULL,NULL);
|
||||||
return 0;
|
Thread::sleep(100000000);
|
||||||
} catch (std::exception &exc) {
|
} catch (std::exception &exc) {
|
||||||
std::cout << exc.what() << std::endl;
|
std::cout << exc.what() << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -69,14 +69,14 @@
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>$(SolutionDir)\ext\bin\libcrypto\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(SolutionDir)\ext\bin\libcrypto\include;$(SolutionDir)\ext\bin\winpcap-devel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<AdditionalDependencies>wsock32.lib;ws2_32.lib;iphlpapi.lib;$(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>wsock32.lib;ws2_32.lib;iphlpapi.lib;$(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;$(SolutionDir)\ext\bin\winpcap-devel\lib\wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
|
Loading…
Add table
Reference in a new issue