Newly broken out OSX tap driver builds now.

This commit is contained in:
Adam Ierymenko 2014-07-31 15:13:48 -07:00
parent 98d426e1d5
commit 526435859f
4 changed files with 28 additions and 21 deletions

View File

@ -42,8 +42,7 @@ CXXFLAGS=$(CFLAGS) -fno-rtti
include objects.mk include objects.mk
OBJS+=osnet/BSDRoutingTable.o OBJS+=osnet/BSDRoutingTable.o osnet/OSXEthernetTap.o osnet/OSXEthernetTapFactory.o
#osnet/OSXEthernetTap.o osnet/OSXEthernetTapFactory.o
all: one all: one

View File

@ -56,16 +56,17 @@
#include <netinet6/in6_var.h> #include <netinet6/in6_var.h>
#include <netinet/in_var.h> #include <netinet/in_var.h>
#include <netinet/icmp6.h> #include <netinet/icmp6.h>
#include <netinet6/nd6.h>
#include <ifaddrs.h>
// OSX compile fix... in6_var defines this in a struct which namespaces it for C++ // OSX compile fix... in6_var defines this in a struct which namespaces it for C++ ... why?!?
struct prf_ra { struct prf_ra {
u_char onlink : 1; u_char onlink : 1;
u_char autonomous : 1; u_char autonomous : 1;
u_char reserved : 6; u_char reserved : 6;
} prf_ra; } prf_ra;
#include <netinet6/nd6.h>
#include <ifaddrs.h>
// These are KERNEL_PRIVATE... why? // These are KERNEL_PRIVATE... why?
#ifndef SIOCAUTOCONF_START #ifndef SIOCAUTOCONF_START
#define SIOCAUTOCONF_START _IOWR('i', 132, struct in6_ifreq) /* accept rtadvd on this interface */ #define SIOCAUTOCONF_START _IOWR('i', 132, struct in6_ifreq) /* accept rtadvd on this interface */
@ -309,40 +310,44 @@ static inline bool _setIpv6Stuff(const char *ifname,bool performNUD,bool acceptR
namespace ZeroTier { namespace ZeroTier {
// Only permit one tap to be opened concurrently across the entire process
static Mutex __tapCreateLock;
OSXEthernetTap::OSXEthernetTap( OSXEthernetTap::OSXEthernetTap(
const char *tryToGetDevice,
const MAC &mac, const MAC &mac,
unsigned int mtu, unsigned int mtu,
unsigned int metric,
uint64_t nwid,
const char *desiredDevice,
const char *friendlyName,
void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &),
void *arg) void *arg) :
throw(std::runtime_error) :
EthernetTap("OSXEthernetTap",mac,mtu,metric), EthernetTap("OSXEthernetTap",mac,mtu,metric),
_r(renv),
_handler(handler), _handler(handler),
_arg(arg), _arg(arg),
_mtu(mtu),
_metric(metric),
_fd(0), _fd(0),
_enabled(true) _enabled(true)
{ {
static Mutex globalTapCreateLock;
char devpath[64],ethaddr[64],mtustr[32],metstr[32]; char devpath[64],ethaddr[64],mtustr[32],metstr[32];
struct stat stattmp; struct stat stattmp;
Mutex::Lock _l(__tapCreateLock); // create only one tap at a time, globally
Mutex::Lock _gl(globalTapCreateLock);
if (mtu > 2800) if (mtu > 2800)
throw std::runtime_error("max tap MTU is 2800"); throw std::runtime_error("max tap MTU is 2800");
if (stat("/dev/zt0",&stattmp)) if (stat("/dev/zt0",&stattmp))
throw std::runtime_error("/dev/zt# tap devices do not exist and unable to load kernel extension"); throw std::runtime_error("/dev/zt# tap devices do not exist");
// Try to reopen the last device we had, if we had one and it's still unused. // Try to reopen the last device we had, if we had one and it's still unused.
bool recalledDevice = false; bool recalledDevice = false;
if ((tryToGetDevice)&&(tryToGetDevice[0])) { if ((desiredDevice)&&(desiredDevice[0] == 'z')&&(desiredDevice[1] == 't')) {
Utils::snprintf(devpath,sizeof(devpath),"/dev/%s",tryToGetDevice); if ((strchr(desiredDevice,'/'))||(strchr(desiredDevice,'.'))) // security sanity check
throw std::runtime_error("invalid desiredDevice parameter");
Utils::snprintf(devpath,sizeof(devpath),"/dev/%s",desiredDevice);
if (stat(devpath,&stattmp) == 0) { if (stat(devpath,&stattmp) == 0) {
_fd = ::open(devpath,O_RDWR); _fd = ::open(devpath,O_RDWR);
if (_fd > 0) { if (_fd > 0) {
_dev = tryToGetDevice; _dev = desiredDevice;
recalledDevice = true; recalledDevice = true;
} }
} }
@ -350,7 +355,7 @@ OSXEthernetTap::OSXEthernetTap(
// Open the first unused tap device if we didn't recall a previous one. // Open the first unused tap device if we didn't recall a previous one.
if (!recalledDevice) { if (!recalledDevice) {
for(int i=0;i<256;++i) { for(int i=0;i<64;++i) {
Utils::snprintf(devpath,sizeof(devpath),"/dev/zt%d",i); Utils::snprintf(devpath,sizeof(devpath),"/dev/zt%d",i);
if (stat(devpath,&stattmp)) if (stat(devpath,&stattmp))
throw std::runtime_error("no more TAP devices available"); throw std::runtime_error("no more TAP devices available");
@ -375,7 +380,7 @@ OSXEthernetTap::OSXEthernetTap(
// Configure MAC address and MTU, bring interface up // Configure MAC address and MTU, bring interface up
Utils::snprintf(ethaddr,sizeof(ethaddr),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)mac[0],(int)mac[1],(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]); Utils::snprintf(ethaddr,sizeof(ethaddr),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)mac[0],(int)mac[1],(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]);
Utils::snprintf(mtustr,sizeof(mtustr),"%u",_mtu); Utils::snprintf(mtustr,sizeof(mtustr),"%u",_mtu);
Utils::snprintf(metstr,sizeof(metstr),"%u",_metric) Utils::snprintf(metstr,sizeof(metstr),"%u",_metric);
long cpid = (long)vfork(); long cpid = (long)vfork();
if (cpid == 0) { if (cpid == 0) {
::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"lladdr",ethaddr,"mtu",mtustr,"metric",metstr,"up",(const char *)0); ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"lladdr",ethaddr,"mtu",mtustr,"metric",metstr,"up",(const char *)0);
@ -425,7 +430,7 @@ static bool ___removeIp(const std::string &_dev,const InetAddress &ip)
if (cpid == 0) { if (cpid == 0) {
execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"inet",ip.toIpString().c_str(),"-alias",(const char *)0); execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"inet",ip.toIpString().c_str(),"-alias",(const char *)0);
_exit(-1); _exit(-1);
} else (cpid > 0) { } else if (cpid > 0) {
int exitcode = -1; int exitcode = -1;
waitpid(cpid,&exitcode,0); waitpid(cpid,&exitcode,0);
return (exitcode == 0); return (exitcode == 0);

View File

@ -78,6 +78,8 @@ private:
void *_arg; void *_arg;
Thread _thread; Thread _thread;
std::string _dev; std::string _dev;
unsigned int _mtu;
unsigned int _metric;
int _fd; int _fd;
int _shutdownSignalPipe[2]; int _shutdownSignalPipe[2];
volatile bool _enabled; volatile bool _enabled;

View File

@ -29,13 +29,14 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h>
#include "OSXEthernetTapFactory.hpp" #include "OSXEthernetTapFactory.hpp"
#include "OSXEthernetTap.hpp" #include "OSXEthernetTap.hpp"
namespace ZeroTier { namespace ZeroTier {
OSXEthernetTapFactory::OSXEthernetTapFactory(const char *pathToTapKext,const char *tapKextName) OSXEthernetTapFactory::OSXEthernetTapFactory(const char *pathToTapKext,const char *tapKextName) :
_pathToTapKext((pathToTapKext) ? pathToTapKext : ""), _pathToTapKext((pathToTapKext) ? pathToTapKext : ""),
_tapKextName((tapKextName) ? tapKextName : "") _tapKextName((tapKextName) ? tapKextName : "")
{ {