diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2019-03-21 16:42:52 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2019-03-21 16:42:52 -0700 |
commit | e37eb0aa542ef8aee8532c5bfdde7f09ed343a28 (patch) | |
tree | c2900b4814847fb3249b41e7dcfe5ab6dbac9215 /ext/tap-mac/tuntap | |
parent | 130fa35bb1707ea232015c1a3672f0585632dea1 (diff) | |
download | infinitytier-e37eb0aa542ef8aee8532c5bfdde7f09ed343a28.tar.gz infinitytier-e37eb0aa542ef8aee8532c5bfdde7f09ed343a28.zip |
More cleanup of old stuff no longer used.
Diffstat (limited to 'ext/tap-mac/tuntap')
-rw-r--r-- | ext/tap-mac/tuntap/Makefile | 95 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/lock.cc | 206 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/lock.h | 160 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/mem.cc | 76 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/mem.h | 48 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/tap/Info.plist | 36 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/tap/Makefile | 60 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/tap/kmod.cc | 93 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/tap/tap.cc | 533 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/tap/tap.h | 111 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/tuntap.cc | 963 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/tuntap.h | 301 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/tuntap_mgr.cc | 372 | ||||
-rw-r--r-- | ext/tap-mac/tuntap/src/util.h | 46 |
14 files changed, 0 insertions, 3100 deletions
diff --git a/ext/tap-mac/tuntap/Makefile b/ext/tap-mac/tuntap/Makefile deleted file mode 100644 index 53ab1a9d..00000000 --- a/ext/tap-mac/tuntap/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -# Lets have a version, at last! -TUNTAP_VERSION = 20150118 - -# BASE install directory -BASE= - -all: tap.kext - -keysetup: - -security delete-keychain net.sf.tuntaposx.tmp - security create-keychain -p $$(head -c 32 /dev/urandom | hexdump -e '"%02x"') \ - net.sf.tuntaposx.tmp - security set-keychain-settings -lut 60 net.sf.tuntaposx.tmp - security import identity.p12 -k net.sf.tuntaposx.tmp -f pkcs12 \ - -P $$(read -sp 'identity passphrase: ' pw && echo "$$pw") -A - security find-identity -v net.sf.tuntaposx.tmp | \ - awk -F \" '$$2 ~ /^Developer ID Application:/ { print $$2 }' > .signing_identity - security find-identity -v net.sf.tuntaposx.tmp | \ - awk -F \" '$$2 ~ /^Developer ID Installer:/ { print $$2 }' > .installer_identity - -pkgbuild/%.pkg: %.kext - mkdir -p pkgbuild/$*_root/Library/Extensions - cp -pR $*.kext pkgbuild/$*_root/Library/Extensions - mkdir -p pkgbuild/$*_root/Library/LaunchDaemons - cp pkg/launchd/net.sf.tuntaposx.$*.plist pkgbuild/$*_root/Library/LaunchDaemons - pkgbuild --root pkgbuild/$*_root \ - --component-plist pkg/components/$*.plist \ - --scripts pkg/scripts/$* pkgbuild/$*.pkg - -tuntap_$(TUNTAP_VERSION).pkg: pkgbuild/tap.pkg pkgbuild/tun.pkg - productbuild --distribution pkg/distribution.xml --package-path pkgbuild \ - --resources pkg/res.dummy \ - tuntap_$(TUNTAP_VERSION).pkg ; \ - pkgutil --expand tuntap_$(TUNTAP_VERSION).pkg pkgbuild/tuntap_pkg.d - cp -pR pkg/res/ pkgbuild/tuntap_pkg.d/Resources - pkgutil --flatten pkgbuild/tuntap_pkg.d tuntap_$(TUNTAP_VERSION).pkg - if test -s ".installer_identity"; then \ - productsign --sign "$$(cat .installer_identity)" --keychain net.sf.tuntaposx.tmp \ - tuntap_$(TUNTAP_VERSION).pkg tuntap_$(TUNTAP_VERSION).pkg.signed ; \ - mv tuntap_$(TUNTAP_VERSION).pkg.signed tuntap_$(TUNTAP_VERSION).pkg ; \ - fi - -pkg: tuntap_$(TUNTAP_VERSION).pkg - tar czf tuntap_$(TUNTAP_VERSION).tar.gz \ - README.installer README tuntap_$(TUNTAP_VERSION).pkg - -# Install targets -# They are provided for the gentoo ebuild, but should work just fine for other people as well. -install_%_kext: %.kext - mkdir -p $(BASE)/Library/Extensions - cp -pR $*.kext $(BASE)/Library/Extensions/ - chown -R root:wheel $(BASE)/Library/Extensions/$*.kext - mkdir -p $(BASE)/Library/LaunchDaemons - cp pkg/launchd/net.sf.tuntaposx.$*.plist $(BASE)/Library/LaunchDaemons - chown -R root:wheel $(BASE)/Library/LaunchDaemons/net.sf.tuntaposx.$*.plist - -install: install_tap_kext install_tun_kext - -tarball: clean - touch tuntap_$(TUNTAP_VERSION)_src.tar.gz - tar czf tuntap_$(TUNTAP_VERSION)_src.tar.gz \ - -C .. \ - --exclude "tuntap/identity.p12" \ - --exclude "tuntap/tuntap_$(TUNTAP_VERSION)_src.tar.gz" \ - --exclude "tuntap/tuntap_$(TUNTAP_VERSION).tar.gz" \ - --exclude "tuntap/tuntap_$(TUNTAP_VERSION).pkg" \ - --exclude "*/.*" \ - tuntap - -clean: - cd src/tap && make -f Makefile clean - cd src/tun && make -f Makefile clean - -rm -rf pkgbuild - -rm -rf tuntap_$(TUNTAP_VERSION).pkg - -rm -f tuntap_$(TUNTAP_VERSION).tar.gz - -rm -f tuntap_$(TUNTAP_VERSION)_src.tar.gz - -%.kext: - cd src/$* && make TUNTAP_VERSION=$(TUNTAP_VERSION) -f Makefile all - if test -s ".signing_identity"; then \ - codesign -fv --keychain net.sf.tuntaposx.tmp -s "$$(cat .signing_identity)" \ - $*.kext ; \ - fi - -test: - # configd messes with interface flags, issuing SIOCSIFFLAGS ioctls upon receiving kernel - # events indicating protocols have been attached and detached. Unfortunately, configd does - # this asynchronously, making the SIOCSIFFLAGS changes totally unpredictable when we bring - # our interfaces up and down in rapid succession during our tests. I haven't found a good - # way to suppress or handle this mess other than disabling configd temporarily. - killall -STOP configd - -PYTHONPATH=test python test/tuntap/tuntap_tests.py --tests='$(TESTS)' - killall -CONT configd - -.PHONY: test diff --git a/ext/tap-mac/tuntap/src/lock.cc b/ext/tap-mac/tuntap/src/lock.cc deleted file mode 100644 index 9c78783a..00000000 --- a/ext/tap-mac/tuntap/src/lock.cc +++ /dev/null @@ -1,206 +0,0 @@ -/* - * ip tunnel/ethertap device for MacOSX. - * - * Locking implementation. - */ -/* - * Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de> - * - * 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. - * 3. The name of the author may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "lock.h" - -extern "C" { - -#include <kern/clock.h> - -#include <sys/syslog.h> -#include <sys/proc.h> - -} - -#if 0 -#define dprintf(...) log(LOG_INFO, __VA_ARGS__) -#else -#define dprintf(...) -#endif - -/* class tt_lock */ -lck_grp_t *tt_lock::tt_lck_grp = NULL; - -bool -tt_lock::initialize() -{ - /* init if necessary */ - if (tt_lck_grp == NULL) { - dprintf("initing lock group\n"); - tt_lck_grp = lck_grp_alloc_init("tuntap locks", LCK_GRP_ATTR_NULL); - - if (tt_lck_grp == NULL) { - /* if something fails, the lock won't work */ - log(LOG_ERR, "tuntap: could not allocate locking group\n"); - return false; - } - } - - return true; -} - -void -tt_lock::shutdown() -{ - /* free the locking group */ - if (tt_lck_grp != NULL) { - dprintf("freeing lock group\n"); - lck_grp_free(tt_lck_grp); - tt_lck_grp = NULL; - } -} - -/* tt_mutex */ -tt_mutex::tt_mutex() -{ - /* fail if locking group not initialized */ - if (tt_lck_grp == NULL) - return; - - /* allocate the lock */ - lck = lck_rw_alloc_init(tt_lck_grp, NULL); - - if (lck == NULL) - log(LOG_ERR, "tuntap: could not allocate mutex\n"); -} - -tt_mutex::~tt_mutex() -{ - /* if the lock doesn't exist, this will be a no-op */ - if (lck == NULL) - return; - - /* free the lock */ - lck_rw_free(lck, tt_lck_grp); -} - -void -tt_mutex::lock() -{ - if (lck != NULL) - lck_rw_lock_exclusive(lck); -} - -void -tt_mutex::unlock() -{ - if (lck != NULL) - lck_rw_unlock_exclusive(lck); -} - -void -tt_mutex::sleep(void *cond) -{ - if (lck != NULL) - lck_rw_sleep(lck, LCK_SLEEP_DEFAULT, cond, THREAD_INTERRUPTIBLE); -} - -void -tt_mutex::sleep(void *cond, uint64_t nanoseconds) -{ - if (lck != NULL) { - uint64_t abstime; - nanoseconds_to_absolutetime(nanoseconds, &abstime); - lck_rw_sleep_deadline(lck, LCK_SLEEP_DEFAULT, cond, THREAD_INTERRUPTIBLE, abstime); - } -} - -void -tt_mutex::wakeup(void *cond) -{ - if (lck != NULL) - ::wakeup(cond); -} - -/* tt_gate */ -tt_gate::tt_gate() - : ticket_number(0), - population(0) -{ -} - -void -tt_gate::enter() -{ - /* just try to grab the lock, increase the ticket number and the population */ - auto_lock l(&slock); - ticket_number++; - population++; -} - -void -tt_gate::exit() -{ - auto_lock l(&slock); - ticket_number--; - population--; -} - -bool -tt_gate::is_anyone_in() -{ - return population != 0; -} - -unsigned int -tt_gate::get_ticket_number() -{ - return ticket_number; -} - -void -tt_gate::lock() -{ - slock.lock(); -} - -void -tt_gate::unlock() -{ - slock.unlock(); -} - -void -tt_gate::sleep(void* cond) -{ - slock.sleep(cond); -} - -void -tt_gate::sleep(void* cond, uint64_t nanoseconds) -{ - slock.sleep(cond, nanoseconds); -} - -void -tt_gate::wakeup(void* cond) -{ - slock.wakeup(cond); -} - diff --git a/ext/tap-mac/tuntap/src/lock.h b/ext/tap-mac/tuntap/src/lock.h deleted file mode 100644 index 51d3299a..00000000 --- a/ext/tap-mac/tuntap/src/lock.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * ip tunnel/ethertap device for MacOSX. - * - * Locking is not as straightforward for Tiger. So declare our own locking class. - */ -/* - * Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de> - * - * 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. - * 3. The name of the author may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __LOCK_H__ -#define __LOCK_H__ - -extern "C" { - -#include <kern/locks.h> -#include <sys/param.h> - -} - -/* our own locking class. declares the common interface of the locking primitives. */ -class tt_lock { - - protected: - /* locking group */ - static lck_grp_t *tt_lck_grp; - - public: - /* be virtual */ - virtual ~tt_lock() { }; - - /* static intialization (inits the locking group) */ - static bool initialize(); - static void shutdown(); - - /* locking */ - virtual void lock() = 0; - virtual void unlock() = 0; - - /* monitor primitives */ - virtual void sleep(void* cond) = 0; - virtual void sleep(void* cond, uint64_t) = 0; - virtual void wakeup(void* cond) = 0; -}; - -/* simple mutex */ -class tt_mutex : public tt_lock { - - private: - /* underlying darwin lock */ - lck_rw_t *lck; - - public: - tt_mutex(); - virtual ~tt_mutex(); - - void lock(); - void unlock(); - - /* monitor primitives */ - void sleep(void* cond); - void sleep(void* cond, uint64_t); - void wakeup(void* cond); -}; - -/* A very special locking class that we use to track threads that enter and leave the character - * device service functions. They call enter() before entering the actual service routinge and - * exit() when done. enter() only permits them to pass when the gate isn't locked. Furthermore, the - * gate assigns ticket numbers to everyone that passes the gate, so you can check whether more - * threads came through. See tuntap_mgr::shutdown() for how we use that stuff. - */ -class tt_gate : public tt_lock { - - private: - /* synchronization lock */ - tt_mutex slock; - /* ticket number */ - unsigned int ticket_number; - /* count of threads that are in */ - unsigned int population; - - public: - /* construct a new gate */ - tt_gate(); - - /* enter - pass the gate */ - void enter(); - /* exit - pass the gate */ - void exit(); - - /* check whether anyone is in */ - bool is_anyone_in(); - /* gets the next ticket number */ - unsigned int get_ticket_number(); - - /* lock the gate */ - void lock(); - /* unlock the gate */ - void unlock(); - - /* monitor primitives */ - void sleep(void* cond); - void sleep(void* cond, uint64_t); - void wakeup(void* cond); -}; - -/* auto_lock and auto_rwlock serve as automatic lock managers: Create an object, passing the - * tt_[rw]lock you want to lock to have it grab the lock. When the object goes out of scope, the - * destructor of the class will release the lock. - */ -class auto_lock { - - protected: - /* the lock we hold */ - tt_lock *l; - - public: - auto_lock(tt_lock *m) - : l(m) - { - lock(); - } - - ~auto_lock() - { - unlock(); - } - - void lock() - { - l->lock(); - } - - void unlock() - { - l->unlock(); - } -}; - -#endif /* __LOCK_H__ */ - diff --git a/ext/tap-mac/tuntap/src/mem.cc b/ext/tap-mac/tuntap/src/mem.cc deleted file mode 100644 index cd3264fa..00000000 --- a/ext/tap-mac/tuntap/src/mem.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* - * ip tunnel/ethertap device for MacOSX. Common functionality of tap_interface and tun_interface. - * - * Memory management implementation. - */ -/* - * Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de> - * - * 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. - * 3. The name of the author may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "mem.h" - -extern "C" { - -#include <libkern/OSMalloc.h> - -} - -#if 0 -#define dprintf(...) log(LOG_INFO, __VA_ARGS__) -#else -#define dprintf(...) -#endif - -static int inited = 0; -static OSMallocTag tag; - -void -mem_initialize(const char* name) { - - if (!inited) { - tag = OSMalloc_Tagalloc(name, OSMT_DEFAULT); - inited = 1; - } -} - -void -mem_shutdown() { - - if (inited) { - OSMalloc_Tagfree(tag); - inited = 0; - } -} - -void * -mem_alloc(uint32_t size) { - - return OSMalloc(size, tag); -} - -void -mem_free(void *addr, uint32_t size) { - - OSFree(addr, size, tag); -} - diff --git a/ext/tap-mac/tuntap/src/mem.h b/ext/tap-mac/tuntap/src/mem.h deleted file mode 100644 index 4d06fd8c..00000000 --- a/ext/tap-mac/tuntap/src/mem.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ip tunnel/ethertap device for MacOSX. Common functionality of tap_interface and tun_interface. - * - * Memory management. - */ -/* - * Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de> - * - * 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. - * 3. The name of the author may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __MEM_H__ -#define __MEM_H__ - -extern "C" { - -#include <stdint.h> - -} - -/* Memory manager initalization and shutdown */ -void mem_initialize(const char *name); -void mem_shutdown(); - -/* Memory allocation functions */ -void *mem_alloc(uint32_t size); -void mem_free(void *addr, uint32_t size); - -#endif /* __MEM_H__ */ - diff --git a/ext/tap-mac/tuntap/src/tap/Info.plist b/ext/tap-mac/tuntap/src/tap/Info.plist deleted file mode 100644 index bb9b03fd..00000000 --- a/ext/tap-mac/tuntap/src/tap/Info.plist +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>@@CFBUNDLEDEVELOPMENTREGION@@</string> - <key>CFBundleExecutable</key> - <string>@@CFBUNDLEEXECUTABLE@@</string> - <key>CFBundleIdentifier</key> - <string>@@CFBUNDLEIDENTIFIER@@</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>@@CFBUNDLEEXECUTABLE@@</string> - <key>CFBundlePackageType</key> - <string>@@CFBUNDLEPACKAGETYPE@@</string> - <key>CFBundleShortVersionString</key> - <string>@@CFBUNDLEVERSION@@</string> - <key>CFBundleSignature</key> - <string>@@CFBUNDLESIGNATURE@@</string> - <key>CFBundleVersion</key> - <string>1.0</string> - <key>OSBundleLibraries</key> - <dict> - <key>com.apple.kpi.mach</key> - <string>8.0</string> - <key>com.apple.kpi.bsd</key> - <string>8.0</string> - <key>com.apple.kpi.libkern</key> - <string>8.0</string> - <key>com.apple.kpi.unsupported</key> - <string>8.0</string> - </dict> -</dict> -</plist> - diff --git a/ext/tap-mac/tuntap/src/tap/Makefile b/ext/tap-mac/tuntap/src/tap/Makefile deleted file mode 100644 index 306a86d7..00000000 --- a/ext/tap-mac/tuntap/src/tap/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# ethertap driver for MacOSX -# -# Makefile -# -# (c) 2004, 2005, 2006, 2007, 2008 Mattias Nissler -# - -OBJS = ../tuntap.o ../tuntap_mgr.o ../lock.o ../mem.o kmod.o tap.o -KMOD_BIN = tap -BUNDLE_DIR = ../.. -BUNDLE_NAME = tap.kext - -TAP_KEXT_VERSION = $(TUNTAP_VERSION) - -BUNDLE_REGION = English -BUNDLE_IDENTIFIER = com.zerotier.tap -BUNDLE_SIGNATURE = ???? -BUNDLE_PACKAGETYPE = KEXT -BUNDLE_VERSION = $(TAP_KEXT_VERSION) - -INCLUDE = -I.. -I/System/Library/Frameworks/Kernel.framework/Headers -CFLAGS = -Wall -Werror -mkernel -force_cpusubtype_ALL \ - -nostdinc -fno-builtin -fno-stack-protector -msoft-float -fno-common \ - -arch x86_64 \ - -DKERNEL -DAPPLE -DKERNEL_PRIVATE -DTUNTAP_VERSION=\"$(TUNTAP_VERSION)\" \ - -DTAP_KEXT_VERSION=\"$(TAP_KEXT_VERSION)\" -CCFLAGS = $(CFLAGS) -LDFLAGS = -Wall -Werror -arch x86_64 -Xlinker -kext -nostdlib -lkmodc++ -lkmod -lcc_kext - -CCP = clang -x c++ -CC = clang -x c -LD = clang - -all: $(KMOD_BIN) bundle - -.c.o: - $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ -.cc.o: - $(CCP) $(CCFLAGS) $(INCLUDE) -c $< -o $@ - -$(KMOD_BIN): $(OBJS) - $(LD) $(LDFLAGS) -o $(KMOD_BIN) $(OBJS) - -bundle: $(KMOD_BIN) - rm -rf $(BUNDLE_DIR)/$(BUNDLE_NAME) - mkdir -p $(BUNDLE_DIR)/$(BUNDLE_NAME)/Contents/MacOS - cp $(KMOD_BIN) $(BUNDLE_DIR)/$(BUNDLE_NAME)/Contents/MacOS - sed -e "s/@@CFBUNDLEEXECUTABLE@@/$(KMOD_BIN)/" \ - -e "s/@@CFBUNDLEDEVELOPMENTREGION@@/$(BUNDLE_REGION)/" \ - -e "s/@@CFBUNDLEIDENTIFIER@@/$(BUNDLE_IDENTIFIER)/" \ - -e "s/@@CFBUNDLESIGNATURE@@/$(BUNDLE_SIGNATURE)/" \ - -e "s/@@CFBUNDLEPACKAGETYPE@@/$(BUNDLE_PACKAGETYPE)/" \ - -e "s/@@CFBUNDLEVERSION@@/$(BUNDLE_VERSION)/" \ - Info.plist > $(BUNDLE_DIR)/$(BUNDLE_NAME)/Contents/Info.plist - -clean: - -rm -f $(OBJS) $(KMOD_BIN) - -rm -rf $(BUNDLE_DIR)/$(BUNDLE_NAME) - diff --git a/ext/tap-mac/tuntap/src/tap/kmod.cc b/ext/tap-mac/tuntap/src/tap/kmod.cc deleted file mode 100644 index f9c4a40e..00000000 --- a/ext/tap-mac/tuntap/src/tap/kmod.cc +++ /dev/null @@ -1,93 +0,0 @@ -/* - * ethertap device for MacOSX. - * - * Kext definition (it is a mach kmod really...) - */ -/* - * Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de> - * - * 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. - * 3. The name of the author may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "tap.h" -#include "mem.h" - -extern "C" { - -#include <sys/param.h> - -#include <mach/kmod.h> - -static tap_manager *mgr; - -/* - * start function. called when the kext gets loaded. - */ -static kern_return_t tap_module_start(struct kmod_info *ki, void *data) -{ - mem_initialize(TAP_FAMILY_NAME); - - /* initialize locking */ - if (!tt_lock::initialize()) - return KMOD_RETURN_FAILURE; - - /* create a tap manager that will handle the rest */ - mgr = new tap_manager(); - - if (mgr != NULL) { - if (mgr->initialize(TAP_IF_COUNT, (char *) TAP_FAMILY_NAME)) - return KMOD_RETURN_SUCCESS; - - delete mgr; - mgr = NULL; - /* clean up locking */ - tt_lock::shutdown(); - } - - return KMOD_RETURN_FAILURE; -} - -/* - * stop function. called when the kext should be unloaded. unloading can be prevented by - * returning failure - */ -static kern_return_t tap_module_stop(struct kmod_info *ki, void *data) -{ - if (mgr != NULL) { - if (!mgr->shutdown()) - return KMOD_RETURN_FAILURE; - - delete mgr; - mgr = NULL; - } - - /* clean up locking */ - tt_lock::shutdown(); - - mem_shutdown(); - - return KMOD_RETURN_SUCCESS; -} - -KMOD_DECL(tap, TAP_KEXT_VERSION) - -} - diff --git a/ext/tap-mac/tuntap/src/tap/tap.cc b/ext/tap-mac/tuntap/src/tap/tap.cc deleted file mode 100644 index b348a85e..00000000 --- a/ext/tap-mac/tuntap/src/tap/tap.cc +++ /dev/null @@ -1,533 +0,0 @@ -/* - * ethertap device for macosx. - * - * tap_interface class definition - */ -/* - * Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de> - * - * 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. - * 3. The name of the author may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "tap.h" - -extern "C" { - -#include <sys/systm.h> -#include <sys/syslog.h> -#include <sys/param.h> -#include <sys/sockio.h> -#include <sys/random.h> -#include <sys/kern_event.h> - -#include <mach/thread_policy.h> - -#include <net/if_types.h> -#include <net/if_arp.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/dlil.h> -#include <net/ethernet.h> - -} - -#if 0 -#define dprintf(...) log(LOG_INFO, __VA_ARGS__) -#else -#define dprintf(...) -#endif - -// These declarations are missing in the Kernel.framework headers, put present in userspace :-/ -#pragma pack(4) -struct ifmediareq { - char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - int ifm_current; /* current media options */ - int ifm_mask; /* don't care mask */ - int ifm_status; /* media status */ - int ifm_active; /* active options */ - int ifm_count; /* # entries in ifm_ulist array */ - int *ifm_ulist; /* media words */ -}; - -struct ifmediareq64 { - char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - int ifm_current; /* current media options */ - int ifm_mask; /* don't care mask */ - int ifm_status; /* media status */ - int ifm_active; /* active options */ - int ifm_count; /* # entries in ifm_ulist array */ - user64_addr_t ifmu_ulist __attribute__((aligned(8))); -}; - -struct ifmediareq32 { - char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - int ifm_current; /* current media options */ - int ifm_mask; /* don't care mask */ - int ifm_status; /* media status */ - int ifm_active; /* active options */ - int ifm_count; /* # entries in ifm_ulist array */ - user32_addr_t ifmu_ulist; /* 32-bit pointer */ -}; -#pragma pack() - -#define SIOCGIFMEDIA32 _IOWR('i', 56, struct ifmediareq32) /* get net media */ -#define SIOCGIFMEDIA64 _IOWR('i', 56, struct ifmediareq64) /* get net media (64-bit) */ - -/* thread_policy_set is exported in Mach.kext, but commented in mach/thread_policy.h in the - * Kernel.Framework headers (why?). Add a local declaration to work around that. - */ -extern "C" { -kern_return_t thread_policy_set( - thread_t thread, - thread_policy_flavor_t flavor, - thread_policy_t policy_info, - mach_msg_type_number_t count); -} - -static unsigned char ETHER_BROADCAST_ADDR[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - -/* members */ -tap_interface::tap_interface() { - bzero(attached_protos, sizeof(attached_protos)); - input_thread = THREAD_NULL; -} - -bool -tap_interface::initialize(unsigned short major, unsigned short unit) -{ - this->unit = unit; - this->family_name = TAP_FAMILY_NAME; - this->family = IFNET_FAMILY_ETHERNET; - this->type = IFT_ETHER; - bzero(unique_id, UIDLEN); - snprintf(unique_id, UIDLEN, "%s%d", family_name, unit); - - dprintf("tap: starting interface %s%d\n", TAP_FAMILY_NAME, unit); - - /* register character device */ - if (!tuntap_interface::register_chardev(major)) - return false; - - return true; -} - -void -tap_interface::shutdown() -{ - dprintf("tap: shutting down tap interface %s%d\n", TAP_FAMILY_NAME, unit); - - unregister_chardev(); -} - -int -tap_interface::initialize_interface() -{ - struct sockaddr_dl lladdr; - lladdr.sdl_len = sizeof(lladdr); - lladdr.sdl_family = AF_LINK; - lladdr.sdl_alen = ETHER_ADDR_LEN; - lladdr.sdl_nlen = lladdr.sdl_slen = 0; - - /* generate a random MAC address */ - read_random(LLADDR(&lladdr), ETHER_ADDR_LEN); - - /* clear multicast bit and set local assignment bit (see IEEE 802) */ - (LLADDR(&lladdr))[0] &= 0xfe; - (LLADDR(&lladdr))[0] |= 0x02; - - dprintf("tap: random tap address: %02x:%02x:%02x:%02x:%02x:%02x\n", - (LLADDR(&lladdr))[0] & 0xff, - (LLADDR(&lladdr))[1] & 0xff, - (LLADDR(&lladdr))[2] & 0xff, - (LLADDR(&lladdr))[3] & 0xff, - (LLADDR(&lladdr))[4] & 0xff, - (LLADDR(&lladdr))[5] & 0xff); - - /* register interface */ - if (!tuntap_interface::register_interface(&lladdr, ETHER_BROADCAST_ADDR, ETHER_ADDR_LEN)) - return EIO; - - /* Set link level address. Yes, we need to do that again. Darwin sucks. */ - errno_t err = ifnet_set_lladdr(ifp, LLADDR(&lladdr), ETHER_ADDR_LEN); - if (err) - dprintf("tap: failed to set lladdr on %s%d: %d\n", family_name, unit, err); - - /* set mtu */ - ifnet_set_mtu(ifp, TAP_MTU); - /* set header length */ - ifnet_set_hdrlen(ifp, sizeof(struct ether_header)); - /* add the broadcast flag */ - ifnet_set_flags(ifp, IFF_BROADCAST, IFF_BROADCAST); - - /* we must call bpfattach(). Otherwise we deadlock BPF while unloading. Seems to be a bug in - * the kernel, see bpfdetach() in net/bpf.c, it will return without releasing the lock if - * the interface wasn't attached. I wonder what they were smoking while writing it ;-) - */ - bpfattach(ifp, DLT_EN10MB, ifnet_hdrlen(ifp)); - - /* Inject an empty packet to trigger the input thread calling demux(), which will unblock - * thread_sync_lock. This is part of a hack to avoid a kernel crash on re-attaching - * interfaces, see comment in shutdown_interface for more information. - */ - mbuf_t empty_mbuf; - mbuf_gethdr(MBUF_WAITOK, MBUF_TYPE_DATA, &empty_mbuf); - if (empty_mbuf != NULL) { - mbuf_pkthdr_setrcvif(empty_mbuf, ifp); - mbuf_pkthdr_setlen(empty_mbuf, 0); - mbuf_pkthdr_setheader(empty_mbuf, mbuf_data(empty_mbuf)); - mbuf_set_csum_performed(empty_mbuf, 0, 0); - if (ifnet_input(ifp, empty_mbuf, NULL) == 0) { - auto_lock l(&thread_sync_lock); - for (int i = 0; i < 100 && input_thread == THREAD_NULL; ++i) { - dprintf("input thread not found, waiting...\n"); - thread_sync_lock.sleep(&input_thread, 10000000); - } - } else { - mbuf_freem(empty_mbuf); - } - } - if (input_thread == THREAD_NULL) - dprintf("Failed to determine input thread!\n"); - - return 0; -} - -void -tap_interface::shutdown_interface() -{ - dprintf("tap: shutting down network interface of device %s%d\n", TAP_FAMILY_NAME, unit); - - /* detach all protocols */ - for (unsigned int i = 0; i < MAX_ATTACHED_PROTOS; i++) { - if (attached_protos[i].used) { - errno_t err = ifnet_detach_protocol(ifp, attached_protos[i].proto); - if (err) - log(LOG_WARNING, "tap: could not detach protocol %d from %s%d\n", - attached_protos[i].proto, TAP_FAMILY_NAME, unit); - } - } - - cleanup_interface(); - unregister_interface(); - - /* There's a race condition in the kernel that may cause crashes when quickly re-attaching - * interfaces. The crash happens when the interface gets re-attached before the input thread - * for the interface managed to terminate, in which case an assert on the input_waiting flag - * to be clear triggers in ifnet_attach. The bug is really that there's no synchronization - * for terminating the input thread. To work around this, the following code does add the - * missing synchronization to wait for the input thread to terminate. Of course, threading - * primitives available to kexts are few, and I'm not aware of a way to wait for a thread to - * terminate. Hence, the code calls thread_policy_set (passing bogus parameters) in a loop, - * until it returns KERN_TERMINATED. Since this is all rather fragile, there's an upper - * limit on the loop iteratations we're willing to make, so this terminates eventually even - * if things change on the kernel side eventually. - */ - if (input_thread != THREAD_NULL) { - dprintf("Waiting for input thread...\n"); - kern_return_t result = 0; - for (int i = 0; i < 100; ++i) { - result = thread_policy_set(input_thread, -1, NULL, 0); - dprintf("thread_policy_set result: %d\n", result); - if (result == KERN_TERMINATED) { - dprintf("Input thread terminated.\n"); - thread_deallocate(input_thread); - input_thread = THREAD_NULL; - break; - } - - auto_lock l(&thread_sync_lock); - thread_sync_lock.sleep(&input_thread, 10000000); - } - } -} - -errno_t -tap_interface::if_ioctl(u_int32_t cmd, void *arg) -{ - dprintf("tap: if_ioctl cmd: %d (%x)\n", cmd & 0xff, cmd); - - switch (cmd) { - case SIOCSIFLLADDR: - { - /* set ethernet address */ - struct sockaddr *ea = &(((struct ifreq *) arg)->ifr_addr); - - dprintf("tap: SIOCSIFLLADDR family %d len %d\n", - ea->sa_family, ea->sa_len); - - /* check if it is really an ethernet address */ - if (ea->sa_family != AF_LINK || ea->sa_len != ETHER_ADDR_LEN) - return EINVAL; - - /* ok, copy */ - errno_t err = ifnet_set_lladdr(ifp, ea->sa_data, ETHER_ADDR_LEN); - if (err) { - dprintf("tap: failed to set lladdr on %s%d: %d\n", - family_name, unit, err); - return err; - } - - /* Generate a LINK_ON event. This necessary for configd to re-read - * the interface data and refresh the MAC address. Not doing so - * would result in the DHCP client using a stale MAC address... - */ - generate_link_event(KEV_DL_LINK_ON); - - return 0; - } - - case SIOCGIFMEDIA32: - case SIOCGIFMEDIA64: - { - struct ifmediareq *ifmr = (struct ifmediareq*) arg; - user_addr_t list = USER_ADDR_NULL; - - ifmr->ifm_current = IFM_ETHER; - ifmr->ifm_mask = 0; - ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE; - ifmr->ifm_active = IFM_ETHER; - ifmr->ifm_count = 1; - - if (cmd == SIOCGIFMEDIA64) - list = ((struct ifmediareq64*) ifmr)->ifmu_ulist; - else - list = CAST_USER_ADDR_T( - ((struct ifmediareq32*) ifmr)->ifmu_ulist); - - if (list != USER_ADDR_NULL) - return copyout(&ifmr->ifm_current, list, sizeof(int)); - - return 0; - } - - default: - /* let our superclass handle it */ - return tuntap_interface::if_ioctl(cmd, arg); - } - - return EOPNOTSUPP; -} - -errno_t -tap_interface::if_demux(mbuf_t m, char *header, protocol_family_t *proto) -{ - struct ether_header *eh = (struct ether_header *) header; - unsigned char lladdr[ETHER_ADDR_LEN]; - - dprintf("tap: if_demux\n"); - - /* Make note of what input thread this interface is running on. This is part of a hack to - * avoid a crash on re-attaching interfaces, see comment in shutdown_interface for details. - */ - if (input_thread == THREAD_NULL) { - auto_lock l(&thread_sync_lock); - input_thread = current_thread(); - thread_reference(input_thread); - thread_sync_lock.wakeup(&input_thread); - } - - /* size check */ - if (mbuf_len(m) < sizeof(struct ether_header)) - return ENOENT; - - /* catch broadcast and multicast (stolen from bsd/net/ether_if_module.c) */ - if (eh->ether_dhost[0] & 1) { - if (memcmp(ETHER_BROADCAST_ADDR, eh->ether_dhost, ETHER_ADDR_LEN) == 0) { - /* broadcast */ - dprintf("tap: broadcast packet.\n"); - mbuf_setflags_mask(m, MBUF_BCAST, MBUF_BCAST); - } else { - /* multicast */ - dprintf("tap: multicast packet.\n"); - mbuf_setflags_mask(m, MBUF_MCAST, MBUF_MCAST); - } - } else { - /* check wether the packet has our address */ - ifnet_lladdr_copy_bytes(ifp, lladdr, ETHER_ADDR_LEN); - if (memcmp(lladdr, eh->ether_dhost, ETHER_ADDR_LEN) != 0) - mbuf_setflags_mask(m, MBUF_PROMISC, MBUF_PROMISC); - } - - /* find the protocol */ - for (unsigned int i = 0; i < MAX_ATTACHED_PROTOS; i++) { - if (attached_protos[i].used && attached_protos[i].type == eh->ether_type) { - *proto = attached_protos[i].proto; - return 0; - } - } - - dprintf("tap: if_demux() failed to find proto.\n"); - - /* no matching proto found */ - return ENOENT; -} - -errno_t -tap_interface::if_framer(mbuf_t *m, const struct sockaddr *dest, const char *dest_linkaddr, - const char *frame_type) -{ - struct ether_header *eh; - mbuf_t nm = *m; - errno_t err; - - dprintf("tap: if_framer\n"); - - /* prepend the ethernet header */ - err = mbuf_prepend(&nm, sizeof (struct ether_header), MBUF_WAITOK); - if (err) { - dprintf("tap: could not prepend data to mbuf: %d\n", err); - return err; - } - *m = nm; - - /* fill the header */ - eh = (struct ether_header *) mbuf_data(*m); - memcpy(eh->ether_dhost, dest_linkaddr, ETHER_ADDR_LEN); - ifnet_lladdr_copy_bytes(ifp, eh->ether_shost, ETHER_ADDR_LEN); - eh->ether_type = *((u_int16_t *) frame_type); - - return 0; -} - -errno_t -tap_interface::if_add_proto(protocol_family_t proto, const struct ifnet_demux_desc *desc, - u_int32_t ndesc) -{ - errno_t err; - - dprintf("tap: if_add_proto proto %d\n", proto); - - for (unsigned int i = 0; i < ndesc; i++) { - /* try to add the protocol */ - err = add_one_proto(proto, desc[i]); - if (err != 0) { - /* if that fails, remove everything stored so far */ - if_del_proto(proto); - return err; - } - } - - return 0; -} - -errno_t -tap_interface::if_del_proto(protocol_family_t proto) -{ - dprintf("tap: if_del_proto proto %d\n", proto); - - /* delete all matching entries in attached_protos */ - for (unsigned int i = 0; i < MAX_ATTACHED_PROTOS; i++) { - if (attached_protos[i].proto == proto) - attached_protos[i].used = false; - } - - return 0; -} - -errno_t -tap_interface::if_check_multi(const struct sockaddr *maddr) -{ - dprintf("tap: if_check_multi family %d\n", maddr->sa_family); - - /* see whether it is a ethernet address with the multicast bit set */ - if (maddr->sa_family == AF_LINK) { - struct sockaddr_dl *dlmaddr = (struct sockaddr_dl *) maddr; - if (LLADDR(dlmaddr)[0] & 0x01) - return 0; - else - return EADDRNOTAVAIL; - } - - return EOPNOTSUPP; -} - -errno_t -tap_interface::add_one_proto(protocol_family_t proto, const struct ifnet_demux_desc &dd) -{ - int free = -1; - u_int16_t dt; - - /* we only support DLIL_DESC_ETYPE2 */ - if (dd.type != DLIL_DESC_ETYPE2 || dd.datalen != 2) { - log(LOG_WARNING, "tap: tap only supports DLIL_DESC_ETYPE2 protocols.\n"); - return EINVAL; - } - - dt = *((u_int16_t *) (dd.data)); - - /* see if the protocol is already registered */ - for (unsigned int i = 0; i < MAX_ATTACHED_PROTOS; i++) { - if (attached_protos[i].used) { - if (dt == attached_protos[i].type) { - /* already registered */ - if (attached_protos[i].proto == proto) { - /* matches the old entry */ - return 0; - } else - return EEXIST; - } - } else if (free == -1) - free = i; - } - - /* did we find a free entry? */ - if (free == -1) - /* is ENOBUFS correct? */ - return ENOBUFS; - - /* ok, save information */ - attached_protos[free].used = true; - attached_protos[free].type = dt; - attached_protos[free].proto = proto; - - return 0; -} - -/* This code is shamelessly stolen from if_bond.c */ -void -tap_interface::generate_link_event(u_int32_t code) -{ - struct { - struct kern_event_msg header; - u_int32_t unit; - char if_name[IFNAMSIZ]; - } event; - - bzero(&event, sizeof(event)); - event.header.total_size = sizeof(event); - event.header.vendor_code = KEV_VENDOR_APPLE; - event.header.kev_class = KEV_NETWORK_CLASS; - event.header.kev_subclass = KEV_DL_SUBCLASS; - event.header.event_code = code; - event.header.event_data[0] = family; - event.unit = (u_int32_t) unit; - strncpy(event.if_name, ifnet_name(ifp), IFNAMSIZ); - - ifnet_event(ifp, &event.header); -} - -/* tap_manager members */ -tuntap_interface * -tap_manager::create_interface() -{ - return new tap_interface(); -} - diff --git a/ext/tap-mac/tuntap/src/tap/tap.h b/ext/tap-mac/tuntap/src/tap/tap.h deleted file mode 100644 index a5164d4a..00000000 --- a/ext/tap-mac/tuntap/src/tap/tap.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * ethertap device for MacOSX. - */ -/* - * Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de> - * - * 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. - * 3. The name of the author may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __TAP_H__ -#define __TAP_H__ - -#include "tuntap.h" - -extern "C" { - -#include <kern/thread.h> - -} - -#define TAP_FAMILY_NAME ((char *) "zt") -#define TAP_IF_COUNT 32 /* max number of tap interfaces */ -#define TAP_MTU 2800 -#define TAP_LLADDR tap_lladdr - -/* the mac address of our interfaces. note that the last byte will be replaced by the unit number */ -extern u_char tap_lladdr[]; - -/* tap manager */ -class tap_manager : public tuntap_manager { - - protected: - /* just define the interface creation method */ - virtual tuntap_interface *create_interface(); - -}; - -/* the tap network interface */ -class tap_interface : public tuntap_interface { - public: - tap_interface(); - - protected: - /* maximum number of protocols that can be attached */ - static const unsigned int MAX_ATTACHED_PROTOS = 8; - - /* information about attached protocols for demuxing is stored here */ - struct { - /* whether this entry is used */ - bool used; - /* type in the ethernet header */ - u_int16_t type; - /* protocol passed to add_proto */ - protocol_family_t proto; - } attached_protos[MAX_ATTACHED_PROTOS]; - - /* The input thread for the network interface. */ - thread_t input_thread; - - /* initializes the interface */ - virtual bool initialize(unsigned short major, unsigned short unit); - - /* shuts the interface down */ - virtual void shutdown(); - - /* called when the character device is opened in order to intialize the network - * interface. - */ - virtual int initialize_interface(); - /* called when the character device is closed to shutdown the network interface */ - virtual void shutdown_interface(); - - /* override interface routines */ - virtual errno_t if_ioctl(u_int32_t cmd, void *arg); - virtual errno_t if_demux(mbuf_t m, char *header, protocol_family_t *proto); - virtual errno_t if_framer(mbuf_t *m, const struct sockaddr *dest, - const char *dest_linkaddr, const char *frame_type); - virtual errno_t if_add_proto(protocol_family_t proto, - const struct ifnet_demux_desc *ddesc, u_int32_t ndesc); - virtual errno_t if_del_proto(protocol_family_t proto); - virtual errno_t if_check_multi(const struct sockaddr *maddr); - - /* if_add_proto helper */ - errno_t add_one_proto(protocol_family_t proto, const struct ifnet_demux_desc &dd); - - /* generates a kernel event */ - void generate_link_event(u_int32_t code); - - friend class tap_manager; -}; - -#endif /* __TAP_H__ */ - diff --git a/ext/tap-mac/tuntap/src/tuntap.cc b/ext/tap-mac/tuntap/src/tuntap.cc deleted file mode 100644 index d0f89018..00000000 --- a/ext/tap-mac/tuntap/src/tuntap.cc +++ /dev/null @@ -1,963 +0,0 @@ -/* - * ip tunnel/ethertap device for MacOSX. Common functionality of tap_interface and tun_interface. - * - * tuntap_interface class definition - */ -/* - * Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de> - * - * 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. - * 3. The name of the author may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "tuntap.h" - -#if 0 -#define dprintf(...) log(LOG_INFO, __VA_ARGS__) -#else -#define dprintf(...) -#endif - -extern "C" { - -#include <sys/conf.h> -#include <sys/syslog.h> -#include <sys/param.h> -#include <sys/filio.h> -#include <sys/sockio.h> -#include <sys/fcntl.h> -#include <sys/kpi_socket.h> - -#include <vm/vm_kern.h> - -#include <net/if_types.h> -#include <net/if_var.h> -#include <net/if_dl.h> -#include <net/if_arp.h> - -#include <miscfs/devfs/devfs.h> - -} - -extern "C" { - -/* interface service functions that delegate to the appropriate tuntap_interface instance */ -errno_t -tuntap_if_output(ifnet_t ifp, mbuf_t m) -{ - if (ifp != NULL) { - tuntap_interface *ttif = (tuntap_interface *) ifnet_softc(ifp); - if (ttif != NULL) - return ttif->if_output(m); - } - - if (m != NULL) - mbuf_freem_list(m); - - return ENODEV; -} - -errno_t -tuntap_if_ioctl(ifnet_t ifp, long unsigned int cmd, void *arg) -{ - if (ifp != NULL) { - tuntap_interface *ttif = (tuntap_interface *) ifnet_softc(ifp); - if (ttif != NULL) - return ttif->if_ioctl(cmd, arg); - } - - return ENODEV; -} - -errno_t -tuntap_if_set_bpf_tap(ifnet_t ifp, bpf_tap_mode mode, int (*cb)(ifnet_t, mbuf_t)) -{ - if (ifp != NULL) { - tuntap_interface *ttif = (tuntap_interface *) ifnet_softc(ifp); - if (ttif != NULL) - return ttif->if_set_bpf_tap(mode, cb); - } - - return ENODEV; -} - -errno_t -tuntap_if_demux(ifnet_t ifp, mbuf_t m, char *header, protocol_family_t *proto) -{ - if (ifp != NULL) { - tuntap_interface *ttif = (tuntap_interface *) ifnet_softc(ifp); - if (ttif != NULL) - return ttif->if_demux(m, header, proto); - } - - return ENODEV; -} - -errno_t -tuntap_if_framer(ifnet_t ifp, mbuf_t *m, const struct sockaddr *dest, const char *dest_linkaddr, - const char *frame_type) -{ - if (ifp != NULL) { - tuntap_interface *ttif = (tuntap_interface *) ifnet_softc(ifp); - if (ttif != NULL) - return ttif->if_framer(m, dest, dest_linkaddr, frame_type); - } - - return ENODEV; -} - -errno_t -tuntap_if_add_proto(ifnet_t ifp, protocol_family_t proto, const struct ifnet_demux_desc *ddesc, - u_int32_t ndesc) -{ - if (ifp != NULL) { - tuntap_interface *ttif = (tuntap_interface *) ifnet_softc(ifp); - if (ttif != NULL) - return ttif->if_add_proto(proto, ddesc, ndesc); - } - - return ENODEV; -} - -errno_t -tuntap_if_del_proto(ifnet_t ifp, protocol_family_t proto) -{ - if (ifp != NULL) { - tuntap_interface *ttif = (tuntap_interface *) ifnet_softc(ifp); - if (ttif != NULL) - return ttif->if_del_proto(proto); - } - - return ENODEV; -} - -errno_t -tuntap_if_check_multi(ifnet_t ifp, const struct sockaddr* maddr) -{ - if (ifp != NULL) - { - tuntap_interface *ttif = (tuntap_interface *) ifnet_softc(ifp); - if (ttif != NULL) - return ttif->if_check_multi(maddr); - } - - return ENODEV; -} - -void -tuntap_if_detached(ifnet_t ifp) -{ - if (ifp != NULL) { - tuntap_interface *ttif = (tuntap_interface *) ifnet_softc(ifp); - if (ttif != NULL) - ttif->if_detached(); - } -} - -errno_t -tuntap_if_noop_output(ifnet_t, mbuf_t) -{ - return ENODEV; -} - -errno_t -tuntap_if_noop_demux(ifnet_t, mbuf_t, char*, protocol_family_t*) -{ - return ENODEV; -} - -errno_t -tuntap_if_noop_add_proto(ifnet_t, protocol_family_t, const struct ifnet_demux_desc*, u_int32_t) -{ - return ENODEV; -} - -errno_t -tuntap_if_noop_del_proto(ifnet_t, protocol_family_t) -{ - return ENODEV; -} - -} /* extern "C" */ - -/* tuntap_mbuf_queue */ -tuntap_mbuf_queue::tuntap_mbuf_queue() -{ - head = tail = NULL; - size = 0; -} - -tuntap_mbuf_queue::~tuntap_mbuf_queue() -{ - clear(); -} - -bool -tuntap_mbuf_queue::enqueue(mbuf_t mb) -{ - if (size == QUEUE_SIZE) - return false; - - mbuf_setnextpkt(mb, NULL); - - if (head == NULL) - head = tail = mb; - else { - mbuf_setnextpkt(tail, mb); - tail = mb; - } - size++; - - return true; -} - -mbuf_t -tuntap_mbuf_queue::dequeue() -{ - mbuf_t ret; - - /* check wether there is a packet in the queue */ - if (head == NULL) - return NULL; - - /* fetch it */ - ret = head; - head = mbuf_nextpkt(head); - mbuf_setnextpkt(ret, NULL); - size--; - - return ret; -} - -void -tuntap_mbuf_queue::clear() -{ - /* free mbufs that are in the queue */ - if (head != NULL) - mbuf_freem_list(head); - - head = NULL; - tail = NULL; - size = 0; -} - -/* tuntap_interface members */ -tuntap_interface::tuntap_interface() -{ - /* initialize the members */ - ifp = NULL; - open = false; - block_io = true; - dev_handle = NULL; - pid = 0; - selthreadclear(&rsel); - bpf_mode = BPF_MODE_DISABLED; - bpf_callback = NULL; - bzero(unique_id, UIDLEN); - in_ioctl = false; -} - -tuntap_interface::~tuntap_interface() -{ -} - -bool -tuntap_interface::register_chardev(unsigned short major) -{ - /* register character device */ - dev_handle = devfs_make_node(makedev(major, unit), DEVFS_CHAR, 0, 0, 0660, "%s%d", - family_name, (int) unit); - - if (dev_handle == NULL) { - log(LOG_ERR, "tuntap: could not make /dev/%s%d\n", family_name, (int) unit); - return false; - } - - return true; -} - -void -tuntap_interface::unregister_chardev() -{ - dprintf("unregistering character device\n"); - - /* unregister character device */ - if (dev_handle != NULL) - devfs_remove(dev_handle); - dev_handle = NULL; -} - -bool -tuntap_interface::register_interface(const struct sockaddr_dl* lladdr, void *bcaddr, - u_int32_t bcaddrlen) -{ - struct ifnet_init_params ip; - errno_t err; - - dprintf("register_interface\n"); - - /* initialize an initialization info struct */ - ip.uniqueid_len = UIDLEN; - ip.uniqueid = unique_id; - ip.name = family_name; - ip.unit = unit; - ip.family = family; - ip.type = type; - ip.output = tuntap_if_output; - ip.demux = tuntap_if_demux; - ip.add_proto = tuntap_if_add_proto; - ip.del_proto = tuntap_if_del_proto; - ip.check_multi = tuntap_if_check_multi; - ip.framer = tuntap_if_framer; - ip.softc = this; - ip.ioctl = tuntap_if_ioctl; - ip.set_bpf_tap = tuntap_if_set_bpf_tap; - ip.detach = tuntap_if_detached; - ip.event = NULL; - ip.broadcast_addr = bcaddr; - ip.broadcast_len = bcaddrlen; - - dprintf("tuntap: tuntap_if_check_multi is at 0x%08x\n", (void*) tuntap_if_check_multi); - - /* allocate the interface */ - err = ifnet_allocate(&ip, &ifp); - if (err) { - log(LOG_ERR, "tuntap: could not allocate interface for %s%d: %d\n", family_name, - (int) unit, err); - ifp = NULL; - return false; - } - - /* activate the interface */ - err = ifnet_attach(ifp, lladdr); - if (err) { - log(LOG_ERR, "tuntap: could not attach interface %s%d: %d\n", family_name, - (int) unit, err); - ifnet_release(ifp); - ifp = NULL; - return false; - } - - dprintf("setting interface flags\n"); - - /* set interface flags */ - ifnet_set_flags(ifp, IFF_RUNNING | IFF_MULTICAST | IFF_SIMPLEX, (u_int16_t) ~0UL); - - dprintf("flags: %x\n", ifnet_flags(ifp)); - - return true; -} - -void -tuntap_interface::unregister_interface() -{ - errno_t err; - - dprintf("unregistering network interface\n"); - - if (ifp != NULL) { - interface_detached = false; - - /* detach interface */ - err = ifnet_detach(ifp); - if (err) - log(LOG_ERR, "tuntap: error detaching interface %s%d: %d\n", - family_name, unit, err); - - dprintf("interface detaching\n"); - - /* Wait until the interface has completely been detached. */ - thread_sync_lock.lock(); - while (!interface_detached) - thread_sync_lock.sleep(&interface_detached); - thread_sync_lock.unlock(); - - dprintf("interface detached\n"); - - /* release the interface */ - ifnet_release(ifp); - - ifp = NULL; - } - - dprintf("network interface unregistered\n"); -} - -void -tuntap_interface::cleanup_interface() -{ - errno_t err; - ifaddr_t *addrs; - ifaddr_t *a; - struct ifreq ifr; - - /* mark the interface down */ - ifnet_set_flags(ifp, 0, IFF_UP | IFF_RUNNING); - - /* Unregister all interface addresses. This works around a deficiency in the Darwin kernel. - * If we don't remove all IP addresses that are attached to the interface it can happen that - * the IP code fails to clean them up itself. When the interface is recycled, the IP code - * might then think some addresses are still attached to the interface... - */ - - err = ifnet_get_address_list(ifp, &addrs); - if (!err) { - - /* Execute a SIOCDIFADDR ioctl for each address. For technical reasons, we can only - * do that with a socket of the appropriate family. So try to create a dummy socket. - * I know this is a little expensive, but better than crashing... - * - * This really sucks. - */ - for (a = addrs; *a != NULL; a++) { - /* initialize the request parameters */ - snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", - ifnet_name(ifp), ifnet_unit(ifp)); - ifaddr_address(*a, &(ifr.ifr_addr), sizeof(ifr.ifr_addr)); - if (ifr.ifr_addr.sa_family != AF_INET) - continue; - - dprintf("trying to delete address of family %d\n", ifr.ifr_addr.sa_family); - - do_sock_ioctl(ifr.ifr_addr.sa_family, SIOCDIFADDR, &ifr); - } - - /* release the address list */ - ifnet_free_address_list(addrs); - } -} - -bool -tuntap_interface::idle() -{ - return !(open); -} - -void -tuntap_interface::notify_bpf(mbuf_t mb, bool out) -{ - auto_lock l(&bpf_lock); - - if ((out && bpf_mode == BPF_MODE_OUTPUT) - || (!out && bpf_mode == BPF_MODE_INPUT) - || (bpf_mode == BPF_MODE_INPUT_OUTPUT)) - (*bpf_callback)(ifp, mb); -} - -void -tuntap_interface::do_sock_ioctl(sa_family_t af, unsigned long cmd, void* arg) { - if (in_ioctl) { - log(LOG_ERR, "tuntap: ioctl recursion detected, aborting.\n"); - return; - } - - socket_t sock; - errno_t err = sock_socket(af, SOCK_RAW, 0, NULL, NULL, &sock); - if (err) { - log(LOG_ERR, "tuntap: failed to create socket: %d\n", err); - return; - } - - in_ioctl = true; - - /* issue the ioctl */ - err = sock_ioctl(sock, cmd, arg); - if (err) - log(LOG_ERR, "tuntap: socket ioctl %d failed: %d\n", cmd, err); - - in_ioctl = false; - - /* get rid of the socket */ - sock_close(sock); -} - -/* character device service methods */ -int -tuntap_interface::cdev_open(int flags, int devtype, proc_t p) -{ - dprintf("tuntap: cdev_open()\n"); - - /* grab the lock so that there can only be one thread inside */ - auto_lock l(&lock); - - /* check wether it is already open */ - if (open) - return EBUSY; - - /* bring the network interface up */ - int error = initialize_interface(); - if (error) - return error; - - open = true; - pid = proc_pid(p); - - return 0; -} - -int -tuntap_interface::cdev_close(int flags, int devtype, proc_t p) -{ - dprintf("tuntap: cdev_close()\n"); - - auto_lock l(&lock); - - if (open) { - open = false; - - /* shut down the network interface */ - shutdown_interface(); - - /* clear the queue */ - send_queue.clear(); - - /* wakeup the cdev thread and notify selects */ - wakeup(this); - selwakeup(&rsel); - - return 0; - } - - return EBADF; -} - -int -tuntap_interface::cdev_read(uio_t uio, int ioflag) -{ - auto_lock l(&lock); - - unsigned int nb = 0; - int error; - - dprintf("tuntap: cdev read\n"); - - if (!open || ifp == NULL || !(ifnet_flags(ifp) & IFF_UP)) - return EIO; - - /* fetch a new mbuf from the queue if necessary */ - mbuf_t cur_mbuf = NULL; - while (cur_mbuf == NULL) { - dprintf("tuntap: fetching new mbuf\n"); - - cur_mbuf = send_queue.dequeue(); - if (cur_mbuf == NULL) { - /* nothing in queue, block or return */ - if (!block_io) { - dprintf("tuntap: aborting (nbio)\n"); - return EWOULDBLOCK; - } else { - /* block */ - dprintf("tuntap: waiting\n"); - /* release the lock while waiting */ - l.unlock(); - error = msleep(this, NULL, PZERO | PCATCH, "tuntap", NULL); - - l.lock(); - - if (error) - return error; - - /* see whether the device was closed in the meantime */ - if (!open || ifp == NULL || !(ifnet_flags(ifp) & IFF_UP)) - return EIO; - - } - } - } - - /* notify bpf */ - notify_bpf(cur_mbuf, true); - - /* output what we have */ - do { - dprintf("tuntap: got new mbuf: %p uio_resid: %d\n", cur_mbuf, uio_resid(uio)); - - /* now we have an mbuf */ - int chunk_len = min(mbuf_len(cur_mbuf), uio_resid(uio)); - error = uiomove((char *) mbuf_data(cur_mbuf), chunk_len, uio); - if (error) { - mbuf_freem(cur_mbuf); - return error; - } - nb += chunk_len; - - dprintf("tuntap: moved %d bytes to userspace uio_resid: %d\n", chunk_len, - uio_resid(uio)); - - /* update cur_mbuf */ - cur_mbuf = mbuf_free(cur_mbuf); - - } while (uio_resid(uio) > 0 && cur_mbuf != NULL); - - /* update statistics */ - ifnet_stat_increment_out(ifp, 1, nb, 0); - - /* still data left? forget about that ;-) */ - if (cur_mbuf != NULL) - mbuf_freem(cur_mbuf); - - dprintf("tuntap: read done\n"); - - return 0; -} - -int -tuntap_interface::cdev_write(uio_t uio, int ioflag) -{ - auto_lock l(&lock); - - if (!open || ifp == NULL || !(ifnet_flags(ifp) & IFF_UP)) - return EIO; - - dprintf("tuntap: cdev write. uio_resid: %d\n", uio_resid(uio)); - - /* pack the data into an mbuf chain */ - mbuf_t first, mb; - - /* first we need an mbuf having a header */ - mbuf_gethdr(MBUF_WAITOK, MBUF_TYPE_DATA, &first); - if (first == NULL) { - log(LOG_ERR, "tuntap: could not get mbuf.\n"); - return ENOMEM; - } - mbuf_setlen(first, 0); - - unsigned int mlen = mbuf_maxlen(first); - unsigned int chunk_len; - unsigned int copied = 0; - unsigned int max_data_len = ifnet_mtu(ifp) + ifnet_hdrlen(ifp); - int error; - - /* stuff the data into the mbuf(s) */ - mb = first; - while (uio_resid(uio) > 0) { - /* copy a chunk. enforce mtu (don't know if this is correct behaviour) */ - chunk_len = min(max_data_len - copied, min(uio_resid(uio), mlen)); - error = uiomove((caddr_t) mbuf_data(mb), chunk_len, uio); - if (error) { - log(LOG_ERR, "tuntap: could not copy data from userspace: %d\n", error); - mbuf_freem(first); - return error; - } - - dprintf("tuntap: copied %d bytes, uio_resid %d\n", chunk_len, - uio_resid(uio)); - - mlen -= chunk_len; - mbuf_setlen(mb, mbuf_len(mb) + chunk_len); - copied += chunk_len; - - /* if done, break the loop */ - if (uio_resid(uio) <= 0 || copied >= max_data_len) - break; - - /* allocate a new mbuf if the current is filled */ - if (mlen == 0) { - mbuf_t next; - mbuf_get(MBUF_WAITOK, MBUF_TYPE_DATA, &next); - if (next == NULL) { - log(LOG_ERR, "tuntap: could not get mbuf.\n"); - mbuf_freem(first); - return ENOMEM; - } - mbuf_setnext(mb, next); - mb = next; - mbuf_setlen(mb, 0); - mlen = mbuf_maxlen(mb); - } - } - - /* fill in header info */ - mbuf_pkthdr_setrcvif(first, ifp); - mbuf_pkthdr_setlen(first, copied); - mbuf_pkthdr_setheader(first, mbuf_data(first)); - mbuf_set_csum_performed(first, 0, 0); - - /* update statistics */ - ifnet_stat_increment_in(ifp, 1, copied, 0); - - dprintf("tuntap: mbuf chain constructed. first: %p mb: %p len: %d data: %p\n", - first, mb, mbuf_len(first), mbuf_data(first)); - - /* notify bpf */ - notify_bpf(first, false); - - /* need to adjust the data pointer to point directly behind the linklevel header. The header - * itself is later accessed via m_pkthdr.header. Well, if something is ugly, here is it. - */ - mbuf_adj(first, ifnet_hdrlen(ifp)); - - /* pass the packet over to the network stack */ - error = ifnet_input(ifp, first, NULL); - - if (error) { - log(LOG_ERR, "tuntap: could not input packet into network stack.\n"); - mbuf_freem(first); - return error; - } - - return 0; -} - -int -tuntap_interface::cdev_ioctl(u_long cmd, caddr_t data, int fflag, proc_t p) -{ - auto_lock l(&lock); - - dprintf("tuntap: cdev ioctl: %d\n", (int) (cmd & 0xff)); - - switch (cmd) { - case FIONBIO: - /* set i/o mode */ - block_io = *((int *) data) ? false : true; - return 0; - case FIOASYNC: - /* don't allow switching it on */ - if (*((int *) data)) - return ENOTTY; - return 0; - } - - return ENOTTY; -} - -int -tuntap_interface::cdev_select(int which, void *wql, proc_t p) -{ - auto_lock l(&lock); - - int ret = 0; - - dprintf("tuntap: select. which: %d\n", which); - - switch (which) { - case FREAD: - /* check wether data is available */ - { - if (!send_queue.empty()) - ret = 1; - else { - dprintf("tuntap: select: waiting\n"); - selrecord(p, &rsel, wql); - } - } - break; - case FWRITE: - /* we are always writeable */ - ret = 1; - } - - return ret; -} - -/* interface service methods */ -errno_t -tuntap_interface::if_output(mbuf_t m) -{ - mbuf_t pkt; - - dprintf("tuntap: if output\n"); - - /* just to be sure */ - if (m == NULL) - return 0; - - if (!open || ifp == NULL || !(ifnet_flags(ifp) & IFF_UP)) { - mbuf_freem_list(m); - return EHOSTDOWN; - } - - /* check whether packet has a header */ - if ((mbuf_flags(m) & MBUF_PKTHDR) == 0) { - log(LOG_ERR, "tuntap: packet to be output has no mbuf header.\n"); - mbuf_freem_list(m); - return EINVAL; - } - - /* put the packet(s) into the output queue */ - while (m != NULL) { - /* keep pointer, iterate */ - pkt = m; - m = mbuf_nextpkt(m); - mbuf_setnextpkt(pkt, NULL); - - auto_lock l(&lock); - - if (!send_queue.enqueue(pkt)) { - mbuf_freem(pkt); - mbuf_freem_list(m); - return ENOBUFS; - } - } - - /* protect the wakeup calls with the lock, not sure they are safe. */ - { - auto_lock l(&lock); - - /* wakeup the cdev thread and notify selects */ - wakeup(this); - selwakeup(&rsel); - } - - return 0; -} - -errno_t -tuntap_interface::if_ioctl(u_int32_t cmd, void *arg) -{ - dprintf("tuntap: if ioctl: %d\n", (int) (cmd & 0xff)); - - switch (cmd) { - case SIOCSIFADDR: - { - dprintf("tuntap: if_ioctl: SIOCSIFADDR\n"); - - /* Unfortunately, ifconfig sets the address family field of an INET - * netmask to zero, which makes early mDNSresponder versions ignore - * the interface. Fix that here. This one is of the category "ugly - * workaround". Dumb Darwin... - * - * Meanwhile, Apple has fixed mDNSResponder, and recent versions of - * Leopard don't need this hack anymore. However, Tiger still has a - * broken version so we leave the hack in for now. - * - * TODO: Revisit when dropping Tiger support. - * - * Btw. If you configure other network interfaces using ifconfig, - * you run into the same problem. I still don't know how to make the - * tap devices show up in the network configuration panel... - */ - ifaddr_t ifa = (ifaddr_t) arg; - if (ifa == NULL) - return 0; - - sa_family_t af = ifaddr_address_family(ifa); - if (af != AF_INET) - return 0; - - struct ifaliasreq ifra; - int sa_size = sizeof(struct sockaddr); - if (ifaddr_address(ifa, &ifra.ifra_addr, sa_size) - || ifaddr_dstaddress(ifa, &ifra.ifra_broadaddr, sa_size) - || ifaddr_netmask(ifa, &ifra.ifra_mask, sa_size)) { - log(LOG_WARNING, - "tuntap: failed to parse interface address.\n"); - return 0; - } - - // Check that the address family fields match. If not, issue another - // SIOCAIFADDR to fix the entry. - if (ifra.ifra_addr.sa_family != af - || ifra.ifra_broadaddr.sa_family != af - || ifra.ifra_mask.sa_family != af) { - log(LOG_INFO, "tuntap: Fixing address family for %s%d\n", - family_name, unit); - - snprintf(ifra.ifra_name, sizeof(ifra.ifra_name), "%s%d", - family_name, unit); - ifra.ifra_addr.sa_family = af; - ifra.ifra_broadaddr.sa_family = af; - ifra.ifra_mask.sa_family = af; - - do_sock_ioctl(af, SIOCAIFADDR, &ifra); - } - - return 0; - } - - case SIOCSIFFLAGS: - return 0; - - case SIOCGIFSTATUS: - { - struct ifstat *stat = (struct ifstat *) arg; - int len; - char *p; - - if (stat == NULL) - return EINVAL; - - /* print status */ - len = strlen(stat->ascii); - p = stat->ascii + len; - if (open) { - snprintf(p, IFSTATMAX - len, "\topen (pid %u)\n", pid); - } else { - snprintf(p, IFSTATMAX - len, "\tclosed\n"); - } - - return 0; - } - - case SIOCSIFMTU: - { - struct ifreq *ifr = (struct ifreq *) arg; - - if (ifr == NULL) - return EINVAL; - - ifnet_set_mtu(ifp, ifr->ifr_mtu); - - return 0; - } - - case SIOCDIFADDR: - return 0; - - } - - return EOPNOTSUPP; -} - -errno_t -tuntap_interface::if_set_bpf_tap(bpf_tap_mode mode, int (*cb)(ifnet_t, mbuf_t)) -{ - dprintf("tuntap: mode %d\n", mode); - - auto_lock l(&bpf_lock); - - bpf_callback = cb; - bpf_mode = mode; - - return 0; -} - -errno_t -tuntap_interface::if_check_multi(const struct sockaddr *maddr) -{ - dprintf("tuntap: if_check_multi\n"); - - return EOPNOTSUPP; -} - -void -tuntap_interface::if_detached() -{ - dprintf("tuntap: if_detached\n"); - - /* wake unregister_interface() */ - thread_sync_lock.lock(); - interface_detached = true; - thread_sync_lock.wakeup(&interface_detached); - thread_sync_lock.unlock(); - - dprintf("if_detached done\n"); -} - diff --git a/ext/tap-mac/tuntap/src/tuntap.h b/ext/tap-mac/tuntap/src/tuntap.h deleted file mode 100644 index d5f398d0..00000000 --- a/ext/tap-mac/tuntap/src/tuntap.h +++ /dev/null @@ -1,301 +0,0 @@ -/* - * ip tunnel/ethertap device for MacOSX. - * - * The class tuntaptap_interface contains the common functionality of tuntap_interface and - * tap_interface. - */ -/* - * Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de> - * - * 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. - * 3. The name of the author may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __TUNTAP_H__ -#define __TUNTAP_H__ - -#include "util.h" -#include "lock.h" - -extern "C" { - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/systm.h> -#include <sys/kpi_mbuf.h> - -#include <kern/locks.h> - -#include <net/if.h> -#include <net/bpf.h> -#include <net/kpi_interface.h> - -} - -extern "C" { - -errno_t tuntap_if_output(ifnet_t ifp, mbuf_t m); -errno_t tuntap_if_ioctl(ifnet_t ifp, long unsigned int cmd, void *arg); -errno_t tuntap_if_set_bpf_tap(ifnet_t ifp, bpf_tap_mode mode, int (*cb)(ifnet_t, mbuf_t)); -errno_t tuntap_if_demux(ifnet_t ifp, mbuf_t m, char *header, protocol_family_t *proto); -errno_t tuntap_if_framer(ifnet_t ifp, mbuf_t *m, const struct sockaddr *dest, - const char *dest_linkaddr, const char *frame_type); -errno_t tuntap_if_add_proto(ifnet_t ifp, protocol_family_t proto, - const struct ifnet_demux_desc *ddesc, u_int32_t ndesc); -errno_t tuntap_if_del_proto(ifnet_t ifp, protocol_family_t proto); -errno_t tuntap_if_check_multi(ifnet_t ifp, const struct sockaddr *maddr); -void tuntap_if_detached(ifnet_t ifp); - -} - -/* forward declaration */ -class tuntap_interface; - -/* both interface families have their manager object that will create, initialize, shutdown and - * delete interfaces. This is (mostly) generic so it can be used both for tun and tap. The only - * exception is the interface creation, therefore this class is abstract. tun and tap have their own - * versions that simply fill in create_interface(). - */ -class tuntap_manager { - - protected: - /* manager cdev gate */ - tt_gate cdev_gate; - /* interface count */ - unsigned int count; - /* an array holding all the interface instances */ - tuntap_interface **tuntaps; - /* the major device number */ - int dev_major; - /* family name */ - char *family; - - /* wether static members are initialized */ - static bool statics_initialized; - - /* major-to-manager-map */ - static const int MAX_CDEV = 256; - static tuntap_manager *mgr_map[MAX_CDEV]; - - /* initializes static members */ - void initialize_statics(); - - public: - /* sets major device number, allocates the interface table. */ - bool initialize(unsigned int count, char *family); - - /* tries to shutdown the family. returns true if successful. the manager object may - * not be deleted if this wasn't called successfully. - */ - bool shutdown(); - - /* the destructor deletes allocated memory and unregisters the character device - * switch */ - virtual ~tuntap_manager(); - - /* here are the cdev routines for the class. They will figure out the manager object - * and call the service methods declared below. - */ - static int cdev_open(dev_t dev, int flags, int devtype, proc_t p); - static int cdev_close(dev_t dev, int flags, int devtype, proc_t p); - static int cdev_read(dev_t dev, uio_t uio, int ioflag); - static int cdev_write(dev_t dev, uio_t uio, int ioflag); - static int cdev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, - proc_t p); - static int cdev_select(dev_t dev, int which, void *wql, proc_t p); - - protected: - /* Here are the actual service routines that will do the required things (creating - * interfaces and such) and forward to the interface's implementation. - */ - int do_cdev_open(dev_t dev, int flags, int devtype, proc_t p); - int do_cdev_close(dev_t dev, int flags, int devtype, proc_t p); - int do_cdev_read(dev_t dev, uio_t uio, int ioflag); - int do_cdev_write(dev_t dev, uio_t uio, int ioflag); - int do_cdev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, proc_t p); - int do_cdev_select(dev_t dev, int which, void *wql, proc_t p); - - /* abstract method that will create an interface. Implemented by tun and tap */ - virtual tuntap_interface *create_interface() = 0; - - /* makes sure there is one idle interface available (if nothing fails */ - void ensure_idle_device(); - -}; - -/* a class implementing a mbuf packet queue. On Darwin 7 we had struct ifqueue, but that is now - * internal to the kernel for Darwin 8. So lets have our own. - */ -class tuntap_mbuf_queue { - - private: - /* output end of the queue. dequeueing takes mbufs from here */ - mbuf_t head; - /* input end. new mbufs are appended here. */ - mbuf_t tail; - - /* size */ - unsigned int size; - - /* maximum queue size */ - static const unsigned int QUEUE_SIZE = 128; - - public: - /* initialize new empty queue */ - tuntap_mbuf_queue(); - ~tuntap_mbuf_queue(); - - /* is the queue full? */ - bool full() { return size == QUEUE_SIZE; } - /* is it emtpy? */ - bool empty() { return size == 0; } - - /* enqueue an mbuf. returns true if there was space left, so the mbuf could be - * queued, false otherwise */ - bool enqueue(mbuf_t mb); - - /* tries to dequeue the next mbuf. If the queue is empty, NULL is returned */ - mbuf_t dequeue(); - - /* makes the queue empty, discarding any queue packets */ - void clear(); -}; - -class tuntap_interface { - - protected: - /* interface number */ - unsigned int unit; - /* family name */ - char *family_name; - /* family identifier */ - ifnet_family_t family; - /* interface type */ - u_int32_t type; - /* id string */ - static const unsigned int UIDLEN = 20; - char unique_id[UIDLEN]; - - /* synchronization */ - tt_mutex lock; - tt_mutex bpf_lock; - tt_mutex thread_sync_lock; - - /* the interface structure registered */ - ifnet_t ifp; - /* whether the device has been opened */ - bool open; - /* whether we are doing blocking i/o */ - bool block_io; - /* whether the interface has properly been detached */ - bool interface_detached; - /* handle to the devfs node for the character device */ - void *dev_handle; - /* the pid of the process that opened the cdev, if any */ - pid_t pid; - /* read select info */ - struct selinfo rsel; - /* bpf mode, wether filtering is on or off */ - bpf_tap_mode bpf_mode; - /* bpf callback. called when packet arrives/leaves */ - int (*bpf_callback)(ifnet_t, mbuf_t); - /* pending packets queue (for output), must be accessed with the lock held */ - tuntap_mbuf_queue send_queue; - /* whether an ioctl that we issued is currently being processed */ - bool in_ioctl; - - /* protected constructor. initializes most of the members */ - tuntap_interface(); - virtual ~tuntap_interface(); - - /* initialize the device */ - virtual bool initialize(unsigned short major, unsigned short unit) = 0; - - /* character device management */ - virtual bool register_chardev(unsigned short major); - virtual void unregister_chardev(); - - /* network interface management */ - virtual bool register_interface(const struct sockaddr_dl *lladdr, - void *bcaddr, u_int32_t bcaddrlen); - virtual void unregister_interface(); - virtual void cleanup_interface(); - - /* called when the character device is opened in order to intialize the network - * interface. - */ - virtual int initialize_interface() = 0; - /* called when the character device is closed to shutdown the network interface */ - virtual void shutdown_interface() = 0; - - /* check wether the interface is idle (so it can be brought down) */ - virtual bool idle(); - - /* shut it down */ - virtual void shutdown() = 0; - - /* notifies BPF of a packet coming through */ - virtual void notify_bpf(mbuf_t mb, bool out); - - /* executes a socket ioctl through a temporary socket */ - virtual void do_sock_ioctl(sa_family_t af, unsigned long cmd, void* arg); - - /* character device service methods. Called by the manager */ - virtual int cdev_open(int flags, int devtype, proc_t p); - virtual int cdev_close(int flags, int devtype, proc_t p); - virtual int cdev_read(uio_t uio, int ioflag); - virtual int cdev_write(uio_t uio, int ioflag); - virtual int cdev_ioctl(u_long cmd, caddr_t data, int fflag, proc_t p); - virtual int cdev_select(int which, void *wql, proc_t p); - - /* interface functions. friends and implementation methods */ - friend errno_t tuntap_if_output(ifnet_t ifp, mbuf_t m); - friend errno_t tuntap_if_ioctl(ifnet_t ifp, long unsigned int cmd, void *arg); - friend errno_t tuntap_if_set_bpf_tap(ifnet_t ifp, bpf_tap_mode mode, - int (*cb)(ifnet_t, mbuf_t)); - friend errno_t tuntap_if_demux(ifnet_t ifp, mbuf_t m, char *header, - protocol_family_t *proto); - friend errno_t tuntap_if_framer(ifnet_t ifp, mbuf_t *m, const struct sockaddr *dest, - const char *dest_linkaddr, const char *frame_type); - friend errno_t tuntap_if_add_proto(ifnet_t ifp, protocol_family_t proto, - const struct ifnet_demux_desc *ddesc, u_int32_t ndesc); - friend errno_t tuntap_if_del_proto(ifnet_t ifp, protocol_family_t proto); - friend errno_t tuntap_if_check_multi(ifnet_t ifp, const struct sockaddr *maddr); - friend void tuntap_if_detached(ifnet_t ifp); - - virtual errno_t if_output(mbuf_t m); - virtual errno_t if_ioctl(u_int32_t cmd, void *arg); - virtual errno_t if_set_bpf_tap(bpf_tap_mode mode, int (*cb)(ifnet_t, mbuf_t)); - virtual errno_t if_demux(mbuf_t m, char *header, protocol_family_t *proto) = 0; - virtual errno_t if_framer(mbuf_t *m, const struct sockaddr *dest, - const char *dest_linkaddr, const char *frame_type) = 0; - virtual errno_t if_add_proto(protocol_family_t proto, - const struct ifnet_demux_desc *ddesc, u_int32_t ndesc) = 0; - virtual errno_t if_del_proto(protocol_family_t proto) = 0; - virtual errno_t if_check_multi(const struct sockaddr *maddr); - virtual void if_detached(); - - /* tuntap_manager feeds us with cdev input, so it is our friend */ - friend class tuntap_manager; -}; - -#endif /* __TUNTAP_H__ */ - diff --git a/ext/tap-mac/tuntap/src/tuntap_mgr.cc b/ext/tap-mac/tuntap/src/tuntap_mgr.cc deleted file mode 100644 index f41394e9..00000000 --- a/ext/tap-mac/tuntap/src/tuntap_mgr.cc +++ /dev/null @@ -1,372 +0,0 @@ -/* - * ip tunnel/ethertap device for MacOSX. - * - * tuntap_manager definition. - */ -/* - * Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de> - * - * 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. - * 3. The name of the author may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "tuntap.h" -#include "mem.h" - -extern "C" { - -#include <sys/conf.h> -#include <sys/param.h> -#include <sys/syslog.h> -#include <sys/systm.h> - -#include <vm/vm_kern.h> - -#include <miscfs/devfs/devfs.h> - -} - -#if 0 -#define dprintf(...) log(LOG_INFO, __VA_ARGS__) -#else -#define dprintf(...) -#endif - -/* cdevsw for tuntap_manager */ -static struct cdevsw mgr_cdevsw = -{ - tuntap_manager::cdev_open, - tuntap_manager::cdev_close, - tuntap_manager::cdev_read, - tuntap_manager::cdev_write, - tuntap_manager::cdev_ioctl, - eno_stop, - eno_reset, - NULL, - tuntap_manager::cdev_select, - eno_mmap, - eno_strat, - eno_getc, - eno_putc, - 0 -}; - -/* tuntap_manager members */ -tuntap_manager *tuntap_manager::mgr_map[MAX_CDEV]; - -bool tuntap_manager::statics_initialized = false; - -/* static initializer */ -void -tuntap_manager::initialize_statics() -{ - dprintf("initializing mgr_map\n"); - - /* initialize the major-to-manager map */ - for (int i = 0; i < MAX_CDEV; i++) - mgr_map[i] = NULL; - - statics_initialized = true; -} - -bool -tuntap_manager::initialize(unsigned int count, char *family) -{ - this->count = count; - this->family = family; - this->tuntaps = NULL; - - if (!statics_initialized) - initialize_statics(); - - /* make sure noone can access the character devices until we are done */ - auto_lock l(&cdev_gate); - - /* register the switch for the tap character devices */ - dev_major = cdevsw_add(-1, &mgr_cdevsw); - if (dev_major == -1) { - log(LOG_ERR, "%s: could not register character device switch.\n", family); - return false; - } - - /* allocate memory for the interface instance table */ - tuntaps = (tuntap_interface **) mem_alloc(count * sizeof(tuntap_interface *)); - if (tuntaps == NULL) - { - log(LOG_ERR, "%s: no memory!\n", family); - return false; - } - - bzero(tuntaps, count * sizeof(tuntap_interface *)); - - /* Create the interfaces. This will only add the character devices. The network devices will - * be created upon open()ing the corresponding character devices. - */ - for (int i = 0; i < (int) count; i++) - { - tuntaps[i] = create_interface(); - - if (tuntaps[i] != NULL) - { - if (tuntaps[i]->initialize(dev_major, i)) - { - continue; - } - - /* error here. current interface needs to be shut down */ - i++; - } - - /* something went wrong. clean up. */ - while (--i >= 0) - { - tuntaps[i]->shutdown(); - delete tuntaps[i]; - } - - return false; - } - - /* register the new family in the mgr switch */ - mgr_map[dev_major] = this; - - log(LOG_INFO, "%s kernel extension version %s <mattias.nissler@gmx.de>\n", - family, TUNTAP_VERSION); - - return true; -} - -bool -tuntap_manager::shutdown() -{ - bool ok = true; - - /* we halt the whole thing while we check whether we can shutdown */ - auto_lock l(&cdev_gate); - - /* anyone in? */ - if (cdev_gate.is_anyone_in()) { - dprintf("tuntap_mgr: won't shutdown, threads still behind the gate."); - ok = false; - } else { - /* query the interfaces to see if shutting down is ok */ - if (tuntaps != NULL) { - for (unsigned int i = 0; i < count; i++) { - if (tuntaps[i] != NULL) - ok &= tuntaps[i]->idle(); - } - - /* if yes, do it now */ - if (ok) { - for (unsigned int i = 0; i < count; i++) { - if (tuntaps[i] != NULL) { - tuntaps[i]->shutdown(); - delete tuntaps[i]; - tuntaps[i] = NULL; - } - } - } - } - } - - /* unregister the character device switch */ - if (ok) { - if (dev_major != -1 && cdevsw_remove(dev_major, &mgr_cdevsw) == -1) { - log(LOG_WARNING, - "%s: character device switch got lost. strange.\n", family); - } - mgr_map[dev_major] = NULL; - dev_major = -1; - - /* at this point there is still a chance that some thread hangs at the cdev_gate in - * one of the cdev service functions. I can't imagine any way that would aviod this. - * So lets unblock the gate such that they fail. - */ - unsigned int old_number; - do { - old_number = cdev_gate.get_ticket_number(); - - dprintf("tuntap_manager: waiting for other threads to give up.\n"); - - /* wait one second */ - cdev_gate.sleep(&cdev_gate, 1000000); - - } while (cdev_gate.get_ticket_number() != old_number); - - /* I hope it is safe to unload now. */ - - } else { - log(LOG_WARNING, "%s: won't unload, at least one interface is busy.\n", family); - } - - dprintf("tuntap manager: shutdown %s\n", ok ? "ok" : "failed"); - - return ok; -} - -tuntap_manager::~tuntap_manager() -{ - dprintf("freeing interface table\n"); - - /* free memory */ - if (tuntaps != NULL) - mem_free(tuntaps, count * sizeof(tuntap_interface *)); -} - -/* service method dispatchers */ -int -tuntap_manager::cdev_open(dev_t dev, int flags, int devtype, proc_t p) -{ - return (mgr_map[major(dev)] == NULL ? ENOENT - : mgr_map[major(dev)]->do_cdev_open(dev, flags, devtype, p)); -} - -int -tuntap_manager::cdev_close(dev_t dev, int flags, int devtype, proc_t p) -{ - return (mgr_map[major(dev)] == NULL ? EBADF - : mgr_map[major(dev)]->do_cdev_close(dev, flags, devtype, p)); -} - -int -tuntap_manager::cdev_read(dev_t dev, uio_t uio, int ioflag) -{ - return (mgr_map[major(dev)] == NULL ? EBADF - : mgr_map[major(dev)]->do_cdev_read(dev, uio, ioflag)); -} - -int -tuntap_manager::cdev_write(dev_t dev, uio_t uio, int ioflag) -{ - return (mgr_map[major(dev)] == NULL ? EBADF - : mgr_map[major(dev)]->do_cdev_write(dev, uio, ioflag)); -} - -int -tuntap_manager::cdev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, proc_t p) -{ - return (mgr_map[major(dev)] == NULL ? EBADF - : mgr_map[major(dev)]->do_cdev_ioctl(dev, cmd, data, fflag, p)); -} - -int -tuntap_manager::cdev_select(dev_t dev, int which, void *wql, proc_t p) -{ - return (mgr_map[major(dev)] == NULL ? EBADF - : mgr_map[major(dev)]->do_cdev_select(dev, which, wql, p)); -} - -/* character device service methods */ -int -tuntap_manager::do_cdev_open(dev_t dev, int flags, int devtype, proc_t p) -{ - int dmin = minor(dev); - int error = ENOENT; - - cdev_gate.enter(); - - if (dmin < (int) count && dmin >= 0 && tuntaps[dmin] != NULL) - error = tuntaps[dmin]->cdev_open(flags, devtype, p); - - cdev_gate.exit(); - - return error; -} - -int -tuntap_manager::do_cdev_close(dev_t dev, int flags, int devtype, proc_t p) -{ - int dmin = minor(dev); - int error = EBADF; - - cdev_gate.enter(); - - if (dmin < (int) count && dmin >= 0 && tuntaps[dmin] != NULL) - error = tuntaps[dmin]->cdev_close(flags, devtype, p); - - cdev_gate.exit(); - - return error; -} - -int -tuntap_manager::do_cdev_read(dev_t dev, uio_t uio, int ioflag) -{ - int dmin = minor(dev); - int error = EBADF; - - cdev_gate.enter(); - - if (dmin < (int) count && dmin >= 0 && tuntaps[dmin] != NULL) - error = tuntaps[dmin]->cdev_read(uio, ioflag); - - cdev_gate.exit(); - - return error; -} - -int -tuntap_manager::do_cdev_write(dev_t dev, uio_t uio, int ioflag) -{ - int dmin = minor(dev); - int error = EBADF; - - cdev_gate.enter(); - - if (dmin < (int) count && dmin >= 0 && tuntaps[dmin] != NULL) - error = tuntaps[dmin]->cdev_write(uio, ioflag); - - cdev_gate.exit(); - - return error; -} - -int -tuntap_manager::do_cdev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, proc_t p) -{ - int dmin = minor(dev); - int error = EBADF; - - cdev_gate.enter(); - - if (dmin < (int) count && dmin >= 0 && tuntaps[dmin] != NULL) - error = tuntaps[dmin]->cdev_ioctl(cmd, data, fflag, p); - - cdev_gate.exit(); - - return error; -} - -int -tuntap_manager::do_cdev_select(dev_t dev, int which, void *wql, proc_t p) -{ - int dmin = minor(dev); - int error = EBADF; - - cdev_gate.enter(); - - if (dmin < (int) count && dmin >= 0 && tuntaps[dmin] != NULL) - error = tuntaps[dmin]->cdev_select(which, wql, p); - - cdev_gate.exit(); - - return error; -} - diff --git a/ext/tap-mac/tuntap/src/util.h b/ext/tap-mac/tuntap/src/util.h deleted file mode 100644 index 0f6955e8..00000000 --- a/ext/tap-mac/tuntap/src/util.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ip tunnel/ethertap device for MacOSX. - * - * Some utilities and misc stuff. - */ -/* - * Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de> - * - * 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. - * 3. The name of the author may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __UTIL_H__ -#define __UTIL_H__ - -extern "C" { - -/* In Darwin 8 (OS X Tiger) there is a problem with struct selinfo. It was made `private' to the - * kernel, so its definition is not available from the headers in Kernel.framework. However, we need - * to declare something :-( - */ -struct selinfo { - char data[128]; /* should be enough... */ -}; - -} /* extern "C" */ - -#endif /* __UTIL_H__ */ - |