Browse Source

Mac OSX Port - Lightly tested

Joseph Henry 9 years ago
parent
commit
95d28494f6
6 changed files with 101 additions and 19 deletions
  1. 13 1
      make-mac.mk
  2. 38 6
      netcon/Intercept.c
  3. 17 7
      netcon/Intercept.h
  4. 6 0
      netcon/LWIPStack.hpp
  5. 16 0
      netcon/README.md
  6. 11 5
      netcon/RPC.c

+ 13 - 1
make-mac.mk

@@ -79,6 +79,18 @@ one:	$(OBJS) service/OneService.o one.o
 	$(CODESIGN) -f -s $(CODESIGN_APP_CERT) zerotier-one
 	$(CODESIGN) -f -s $(CODESIGN_APP_CERT) zerotier-one
 	$(CODESIGN) -vvv zerotier-one
 	$(CODESIGN) -vvv zerotier-one
 
 
+netcon: $(OBJS)
+	rm -f *.o
+	# Need to selectively rebuild one.cpp and OneService.cpp with ZT_SERVICE_NETCON and ZT_ONE_NO_ROOT_CHECK defined, and also NetconEthernetTap
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) -DZT_SERVICE_NETCON -DZT_ONE_NO_ROOT_CHECK -Iext/lwip/src/include -Iext/lwip/src/include/ipv4 -Iext/lwip/src/include/ipv6 -o zerotier-netcon-service $(OBJS) service/OneService.cpp netcon/NetconEthernetTap.cpp one.cpp -x c netcon/RPC.c $(LDLIBS) -ldl
+	# Build netcon/liblwip.so which must be placed in ZT home for zerotier-netcon-service to work
+	cd netcon ; make -f make-liblwip.mk
+	# Use gcc not clang to build standalone intercept library since gcc is typically used for libc and we want to ensure maximal ABI compatibility
+	cd netcon ; gcc -O2 -Wall -std=c99 -fPIC -fno-common -dynamiclib -flat_namespace -DVERBOSE -D_GNU_SOURCE -DNETCON_INTERCEPT -I. -nostdlib -shared -o libzerotierintercept.so Intercept.c RPC.c -ldl
+	cp netcon/libzerotierintercept.so libzerotierintercept.so
+	ln -sf zerotier-netcon-service zerotier-cli
+	ln -sf zerotier-netcon-service zerotier-idtool
+
 selftest: $(OBJS) selftest.o
 selftest: $(OBJS) selftest.o
 	$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
 	$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
 	$(STRIP) zerotier-selftest
 	$(STRIP) zerotier-selftest
@@ -97,7 +109,7 @@ official: FORCE
 	make ZT_OFFICIAL_RELEASE=1 mac-dist-pkg
 	make ZT_OFFICIAL_RELEASE=1 mac-dist-pkg
 
 
 clean:
 clean:
-	rm -rf *.dSYM build-* *.pkg *.dmg *.o node/*.o controller/*.o service/*.o osdep/*.o ext/http-parser/*.o ext/lz4/*.o ext/json-parser/*.o $(OBJS) zerotier-one zerotier-idtool zerotier-selftest zerotier-cli ZeroTierOneInstaller-* mkworld
+	rm -rf netcon/*.so *.dSYM build-* *.pkg *.dmg *.o node/*.o controller/*.o service/*.o osdep/*.o ext/http-parser/*.o ext/lz4/*.o ext/json-parser/*.o $(OBJS) zerotier-one zerotier-idtool zerotier-selftest zerotier-cli ZeroTierOneInstaller-* mkworld
 
 
 # For those building from source -- installs signed binary tap driver in system ZT home
 # For those building from source -- installs signed binary tap driver in system ZT home
 install-mac-tap: FORCE
 install-mac-tap: FORCE

+ 38 - 6
netcon/Intercept.c

@@ -38,20 +38,25 @@
 #include <sys/time.h>
 #include <sys/time.h>
 #include <pwd.h>
 #include <pwd.h>
 #include <errno.h>
 #include <errno.h>
-#include <linux/errno.h>
 #include <stdarg.h>
 #include <stdarg.h>
 #include <netdb.h>
 #include <netdb.h>
 #include <string.h>
 #include <string.h>
-#include <sys/syscall.h>
 #include <sys/types.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/socket.h>
 #include <sys/poll.h>
 #include <sys/poll.h>
 #include <sys/un.h>
 #include <sys/un.h>
 #include <arpa/inet.h>
 #include <arpa/inet.h>
 #include <sys/resource.h>
 #include <sys/resource.h>
-#include <linux/net.h> /* for NPROTO */
 
 
-#define SOCK_MAX (SOCK_PACKET + 1)
+#if defined(__linux__)
+  #include <linux/errno.h>
+  #include <sys/syscall.h>
+  #include <linux/net.h> /* for NPROTO */
+#endif
+
+#if defined(__linux__)
+  #define SOCK_MAX (SOCK_PACKET + 1)
+#endif
 #define SOCK_TYPE_MASK 0xf
 #define SOCK_TYPE_MASK 0xf
 
 
 #include "Intercept.h"
 #include "Intercept.h"
@@ -92,6 +97,11 @@ static int connected_to_service(int sockfd)
 static int set_up_intercept()
 static int set_up_intercept()
 {
 {
   if (!realconnect) {
   if (!realconnect) {
+
+#if defined(__linux__)
+    realaccept4 = dlsym(RTLD_NEXT, "accept4");
+    realsyscall = dlsym(RTLD_NEXT, "syscall");
+#endif
     realconnect = dlsym(RTLD_NEXT, "connect");
     realconnect = dlsym(RTLD_NEXT, "connect");
     realbind = dlsym(RTLD_NEXT, "bind");
     realbind = dlsym(RTLD_NEXT, "bind");
     realaccept = dlsym(RTLD_NEXT, "accept");
     realaccept = dlsym(RTLD_NEXT, "accept");
@@ -100,9 +110,7 @@ static int set_up_intercept()
     realbind = dlsym(RTLD_NEXT, "bind");
     realbind = dlsym(RTLD_NEXT, "bind");
     realsetsockopt = dlsym(RTLD_NEXT, "setsockopt");
     realsetsockopt = dlsym(RTLD_NEXT, "setsockopt");
     realgetsockopt = dlsym(RTLD_NEXT, "getsockopt");
     realgetsockopt = dlsym(RTLD_NEXT, "getsockopt");
-    realaccept4 = dlsym(RTLD_NEXT, "accept4");
     realclose = dlsym(RTLD_NEXT, "close");
     realclose = dlsym(RTLD_NEXT, "close");
-    realsyscall = dlsym(RTLD_NEXT, "syscall");
     realgetsockname = dlsym(RTLD_NEXT, "getsockname");
     realgetsockname = dlsym(RTLD_NEXT, "getsockname");
   }
   }
   if (!netpath) {
   if (!netpath) {
@@ -127,10 +135,12 @@ int setsockopt(SETSOCKOPT_SIG)
     return realsetsockopt(socket, level, option_name, option_value, option_len);
     return realsetsockopt(socket, level, option_name, option_value, option_len);
 
 
   dwr(MSG_DEBUG,"setsockopt(%d)\n", socket);
   dwr(MSG_DEBUG,"setsockopt(%d)\n", socket);
+#if defined(__linux__)
   if(level == SOL_IPV6 && option_name == IPV6_V6ONLY)
   if(level == SOL_IPV6 && option_name == IPV6_V6ONLY)
     return 0;
     return 0;
   if(level == SOL_IP && (option_name == IP_TTL || option_name == IP_TOS))
   if(level == SOL_IP && (option_name == IP_TTL || option_name == IP_TOS))
     return 0;
     return 0;
+#endif
   if(level == IPPROTO_TCP || (level == SOL_SOCKET && option_name == SO_KEEPALIVE))
   if(level == IPPROTO_TCP || (level == SOL_SOCKET && option_name == SO_KEEPALIVE))
     return 0;
     return 0;
   if(realsetsockopt(socket, level, option_name, option_value, option_len) < 0)
   if(realsetsockopt(socket, level, option_name, option_value, option_len) < 0)
@@ -169,13 +179,16 @@ int socket(SOCKET_SIG)
 
 
   dwr(MSG_DEBUG,"socket():\n");
   dwr(MSG_DEBUG,"socket():\n");
   /* Check that type makes sense */
   /* Check that type makes sense */
+#if defined(__linux__)
   int flags = socket_type & ~SOCK_TYPE_MASK;
   int flags = socket_type & ~SOCK_TYPE_MASK;
   if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) {
   if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) {
       errno = EINVAL;
       errno = EINVAL;
       return -1;
       return -1;
   }
   }
+#endif
   socket_type &= SOCK_TYPE_MASK;
   socket_type &= SOCK_TYPE_MASK;
   /* Check protocol is in range */
   /* Check protocol is in range */
+#if defined(__linux__)
   if (socket_family < 0 || socket_family >= NPROTO){
   if (socket_family < 0 || socket_family >= NPROTO){
     errno = EAFNOSUPPORT;
     errno = EAFNOSUPPORT;
     return -1;
     return -1;
@@ -184,9 +197,12 @@ int socket(SOCKET_SIG)
     errno = EINVAL;
     errno = EINVAL;
     return -1;
     return -1;
   }
   }
+#endif
   /* TODO: detect ENFILE condition */
   /* TODO: detect ENFILE condition */
   if(socket_family == AF_LOCAL
   if(socket_family == AF_LOCAL
+#if defined(__linux__)
     || socket_family == AF_NETLINK
     || socket_family == AF_NETLINK
+#endif
     || socket_family == AF_UNIX) {
     || socket_family == AF_UNIX) {
       int err = realsocket(socket_family, socket_type, protocol);
       int err = realsocket(socket_family, socket_type, protocol);
       dwr(MSG_DEBUG,"realsocket() = %d\n", err);
       dwr(MSG_DEBUG,"realsocket() = %d\n", err);
@@ -244,24 +260,30 @@ int connect(CONNECT_SIG)
     errno = ENOTSOCK;
     errno = ENOTSOCK;
     return -1;
     return -1;
   }
   }
+#if defined(__linux__)
   /* Check family */
   /* Check family */
   if (connaddr->sin_family < 0 || connaddr->sin_family >= NPROTO){
   if (connaddr->sin_family < 0 || connaddr->sin_family >= NPROTO){
     errno = EAFNOSUPPORT;
     errno = EAFNOSUPPORT;
     return -1;
     return -1;
   }
   }
+#endif
   /* make sure we don't touch any standard outputs */
   /* make sure we don't touch any standard outputs */
   if(__fd == STDIN_FILENO || __fd == STDOUT_FILENO || __fd == STDERR_FILENO)
   if(__fd == STDIN_FILENO || __fd == STDOUT_FILENO || __fd == STDERR_FILENO)
     return(realconnect(__fd, __addr, __len));
     return(realconnect(__fd, __addr, __len));
 
 
   if(__addr != NULL && (connaddr->sin_family == AF_LOCAL
   if(__addr != NULL && (connaddr->sin_family == AF_LOCAL
+#if defined(__linux__)
     || connaddr->sin_family == PF_NETLINK
     || connaddr->sin_family == PF_NETLINK
     || connaddr->sin_family == AF_NETLINK
     || connaddr->sin_family == AF_NETLINK
+#endif
     || connaddr->sin_family == AF_UNIX)) {
     || connaddr->sin_family == AF_UNIX)) {
     return realconnect(__fd, __addr, __len);
     return realconnect(__fd, __addr, __len);
   }
   }
   /* Assemble and send RPC */
   /* Assemble and send RPC */
   struct connect_st rpc_st;
   struct connect_st rpc_st;
+#if defined(__linux__)
   rpc_st.__tid = syscall(SYS_gettid);
   rpc_st.__tid = syscall(SYS_gettid);
+#endif
   rpc_st.__fd = __fd;
   rpc_st.__fd = __fd;
   memcpy(&rpc_st.__addr, __addr, sizeof(struct sockaddr_storage));
   memcpy(&rpc_st.__addr, __addr, sizeof(struct sockaddr_storage));
   memcpy(&rpc_st.__len, &__len, sizeof(socklen_t));
   memcpy(&rpc_st.__len, &__len, sizeof(socklen_t));
@@ -300,7 +322,9 @@ int bind(BIND_SIG)
   connaddr = (struct sockaddr_in *)addr;
   connaddr = (struct sockaddr_in *)addr;
 
 
   if(connaddr->sin_family == AF_LOCAL
   if(connaddr->sin_family == AF_LOCAL
+#if defined(__linux__)
     || connaddr->sin_family == AF_NETLINK
     || connaddr->sin_family == AF_NETLINK
+#endif
     || connaddr->sin_family == AF_UNIX) {
     || connaddr->sin_family == AF_UNIX) {
       int err = realbind(sockfd, addr, addrlen);
       int err = realbind(sockfd, addr, addrlen);
       dwr(MSG_DEBUG,"realbind, err = %d\n", err);
       dwr(MSG_DEBUG,"realbind, err = %d\n", err);
@@ -317,7 +341,9 @@ int bind(BIND_SIG)
   /* Assemble and send RPC */
   /* Assemble and send RPC */
   struct bind_st rpc_st;
   struct bind_st rpc_st;
   rpc_st.sockfd = sockfd;
   rpc_st.sockfd = sockfd;
+#if defined(__linux__)
   rpc_st.__tid = syscall(SYS_gettid);
   rpc_st.__tid = syscall(SYS_gettid);
+#endif
   memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr_storage));
   memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr_storage));
   memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t));
   memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t));
   return rpc_send_command(netpath, RPC_BIND, sockfd, &rpc_st, sizeof(struct bind_st));
   return rpc_send_command(netpath, RPC_BIND, sockfd, &rpc_st, sizeof(struct bind_st));
@@ -328,6 +354,7 @@ int bind(BIND_SIG)
 ------------------------------------------------------------------------------*/
 ------------------------------------------------------------------------------*/
 
 
 /* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */
 /* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */
+#if defined(__linux__)
 int accept4(ACCEPT4_SIG)
 int accept4(ACCEPT4_SIG)
 {
 {
   dwr(MSG_DEBUG,"accept4(%d):\n", sockfd);
   dwr(MSG_DEBUG,"accept4(%d):\n", sockfd);
@@ -337,6 +364,7 @@ int accept4(ACCEPT4_SIG)
     fcntl(sockfd, F_SETFL, O_NONBLOCK);
     fcntl(sockfd, F_SETFL, O_NONBLOCK);
   return accept(sockfd, addr, addrlen);
   return accept(sockfd, addr, addrlen);
 }
 }
+#endif
 
 
 /*------------------------------------------------------------------------------
 /*------------------------------------------------------------------------------
 ----------------------------------- accept() -----------------------------------
 ----------------------------------- accept() -----------------------------------
@@ -442,7 +470,9 @@ int listen(LISTEN_SIG)
   struct listen_st rpc_st;
   struct listen_st rpc_st;
   rpc_st.sockfd = sockfd;
   rpc_st.sockfd = sockfd;
   rpc_st.backlog = backlog;
   rpc_st.backlog = backlog;
+#if defined(__linux__)
   rpc_st.__tid = syscall(SYS_gettid);
   rpc_st.__tid = syscall(SYS_gettid);
+#endif
   return rpc_send_command(netpath, RPC_LISTEN, sockfd, &rpc_st, sizeof(struct listen_st));
   return rpc_send_command(netpath, RPC_LISTEN, sockfd, &rpc_st, sizeof(struct listen_st));
 }
 }
 
 
@@ -502,6 +532,7 @@ int getsockname(GETSOCKNAME_SIG)
 ------------------------------------ syscall() ---------------------------------
 ------------------------------------ syscall() ---------------------------------
 ------------------------------------------------------------------------------*/
 ------------------------------------------------------------------------------*/
 
 
+#if defined(__linux__)
 long syscall(SYSCALL_SIG)
 long syscall(SYSCALL_SIG)
 {
 {
   va_list ap;
   va_list ap;
@@ -542,3 +573,4 @@ long syscall(SYSCALL_SIG)
 #endif
 #endif
   return realsyscall(number,a,b,c,d,e,f);
   return realsyscall(number,a,b,c,d,e,f);
 }
 }
+#endif

+ 17 - 7
netcon/Intercept.h

@@ -25,12 +25,17 @@
  * LLC. Start here: http://www.zerotier.com/
  * LLC. Start here: http://www.zerotier.com/
  */
  */
 
 
-
 #ifndef _INTERCEPT_H
 #ifndef _INTERCEPT_H
 #define _INTERCEPT_H	1
 #define _INTERCEPT_H	1
 
 
 #include <sys/socket.h>
 #include <sys/socket.h>
 
 
+
+#if defined(__linux__)
+	#define ACCEPT4_SIG int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags
+ 	#define SYSCALL_SIG	long number, ...
+#endif
+
 #define CLOSE_SIG int fd
 #define CLOSE_SIG int fd
 #define READ_SIG int __fd, void *__buf, size_t __nbytes
 #define READ_SIG int __fd, void *__buf, size_t __nbytes
 #define BIND_SIG int sockfd, const struct sockaddr *addr, socklen_t addrlen
 #define BIND_SIG int sockfd, const struct sockaddr *addr, socklen_t addrlen
@@ -38,7 +43,6 @@
 #define WRITE_SIG int __fd, const void *__buf, size_t __n
 #define WRITE_SIG int __fd, const void *__buf, size_t __n
 #define LISTEN_SIG int sockfd, int backlog
 #define LISTEN_SIG int sockfd, int backlog
 #define SOCKET_SIG int socket_family, int socket_type, int protocol
 #define SOCKET_SIG int socket_family, int socket_type, int protocol
-#define ACCEPT4_SIG int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags
 #define ACCEPT_SIG int sockfd, struct sockaddr *addr, socklen_t *addrlen
 #define ACCEPT_SIG int sockfd, struct sockaddr *addr, socklen_t *addrlen
 #define SHUTDOWN_SIG int socket, int how
 #define SHUTDOWN_SIG int socket, int how
 #define CONNECT_SOCKARG struct sockaddr *
 #define CONNECT_SOCKARG struct sockaddr *
@@ -47,12 +51,17 @@
 #define DAEMON_SIG int nochdir, int noclose
 #define DAEMON_SIG int nochdir, int noclose
 #define SETSOCKOPT_SIG int socket, int level, int option_name, const void *option_value, socklen_t option_len
 #define SETSOCKOPT_SIG int socket, int level, int option_name, const void *option_value, socklen_t option_len
 #define GETSOCKOPT_SIG int sockfd, int level, int optname, void *optval, socklen_t *optlen
 #define GETSOCKOPT_SIG int sockfd, int level, int optname, void *optval, socklen_t *optlen
-#define SYSCALL_SIG	long number, ...
 #define CLONE_SIG int (*fn)(void *), void *child_stack, int flags, void *arg, ...
 #define CLONE_SIG int (*fn)(void *), void *child_stack, int flags, void *arg, ...
 #define GETSOCKNAME_SIG int sockfd, struct sockaddr *addr, socklen_t *addrlen
 #define GETSOCKNAME_SIG int sockfd, struct sockaddr *addr, socklen_t *addrlen
 #define DUP2_SIG int oldfd, int newfd
 #define DUP2_SIG int oldfd, int newfd
 #define DUP3_SIG int oldfd, int newfd, int flags
 #define DUP3_SIG int oldfd, int newfd, int flags
 
 
+
+#if defined(__linux__)
+	int accept4(ACCEPT4_SIG);
+	long syscall(SYSCALL_SIG);
+#endif
+
 void my_init(void);
 void my_init(void);
 int connect(CONNECT_SIG);
 int connect(CONNECT_SIG);
 int bind(BIND_SIG);
 int bind(BIND_SIG);
@@ -61,14 +70,17 @@ int listen(LISTEN_SIG);
 int socket(SOCKET_SIG);
 int socket(SOCKET_SIG);
 int setsockopt(SETSOCKOPT_SIG);
 int setsockopt(SETSOCKOPT_SIG);
 int getsockopt(GETSOCKOPT_SIG);
 int getsockopt(GETSOCKOPT_SIG);
-int accept4(ACCEPT4_SIG);
-long syscall(SYSCALL_SIG);
 int close(CLOSE_SIG);
 int close(CLOSE_SIG);
 int clone(CLONE_SIG);
 int clone(CLONE_SIG);
 int dup2(DUP2_SIG);
 int dup2(DUP2_SIG);
 int dup3(DUP3_SIG);
 int dup3(DUP3_SIG);
 int getsockname(GETSOCKNAME_SIG);
 int getsockname(GETSOCKNAME_SIG);
 
 
+#if defined(__linux__)
+	static int (*realaccept4)(ACCEPT4_SIG) = 0;
+	static long (*realsyscall)(SYSCALL_SIG) = 0;
+#endif
+
 static int (*realconnect)(CONNECT_SIG) = 0;
 static int (*realconnect)(CONNECT_SIG) = 0;
 static int (*realbind)(BIND_SIG) = 0;
 static int (*realbind)(BIND_SIG) = 0;
 static int (*realaccept)(ACCEPT_SIG) = 0;
 static int (*realaccept)(ACCEPT_SIG) = 0;
@@ -76,8 +88,6 @@ static int (*reallisten)(LISTEN_SIG) = 0;
 static int (*realsocket)(SOCKET_SIG) = 0;
 static int (*realsocket)(SOCKET_SIG) = 0;
 static int (*realsetsockopt)(SETSOCKOPT_SIG) = 0;
 static int (*realsetsockopt)(SETSOCKOPT_SIG) = 0;
 static int (*realgetsockopt)(GETSOCKOPT_SIG) = 0;
 static int (*realgetsockopt)(GETSOCKOPT_SIG) = 0;
-static int (*realaccept4)(ACCEPT4_SIG) = 0;
-static long (*realsyscall)(SYSCALL_SIG) = 0;
 static int (*realclose)(CLOSE_SIG) = 0;
 static int (*realclose)(CLOSE_SIG) = 0;
 static int (*realgetsockname)(GETSOCKNAME_SIG) = 0;
 static int (*realgetsockname)(GETSOCKNAME_SIG) = 0;
 
 

+ 6 - 0
netcon/LWIPStack.hpp

@@ -132,7 +132,13 @@ public:
   LWIPStack(const char* path) :
   LWIPStack(const char* path) :
     _libref(NULL)
     _libref(NULL)
   {
   {
+    
+#if defined(__linux__)
     _libref = dlmopen(LM_ID_NEWLM, path, RTLD_NOW);
     _libref = dlmopen(LM_ID_NEWLM, path, RTLD_NOW);
+#elif defined(__APPLE__)
+    _libref = dlopen(path, RTLD_NOW);
+#endif
+
     if(_libref == NULL)
     if(_libref == NULL)
       printf("dlerror(): %s\n", dlerror());
       printf("dlerror(): %s\n", dlerror());
 
 

+ 16 - 0
netcon/README.md

@@ -70,6 +70,22 @@ The intercept library does nothing unless the *ZT\_NC\_NETWORK* environment vari
 
 
 Unlike *zerotier-one*, *zerotier-netcon-service* does not need to be run with root privileges and will not modify the host's network configuration in any way. It can be run alongside *zerotier-one* on the same host with no ill effect, though this can be confusing since you'll have to remember the difference between "real" host interfaces (tun/tap) and network containerized endpoints. The latter are completely unknown to the kernel and will not show up in *ifconfig*.
 Unlike *zerotier-one*, *zerotier-netcon-service* does not need to be run with root privileges and will not modify the host's network configuration in any way. It can be run alongside *zerotier-one* on the same host with no ill effect, though this can be confusing since you'll have to remember the difference between "real" host interfaces (tun/tap) and network containerized endpoints. The latter are completely unknown to the kernel and will not show up in *ifconfig*.
 
 
+# Linking into an application on Mac OSX
+
+Example:
+
+    gcc myapp.c -o myapp libzerotierintercept.so
+    export ZT_NC_NETWORK=/tmp/netcon-test-home/nc_8056c2e21c000001
+
+Start service
+
+    ./zerotier-netcon-service -d -p8000 /tmp/netcon-test-home
+
+Run application
+
+    ./myapp
+
+
 # Starting the Network Containers Service
 # Starting the Network Containers Service
 
 
 You don't need Docker or any other container engine to try Network Containers. A simple test can be performed in user space (no root) in your own home directory.
 You don't need Docker or any other container engine to try Network Containers. A simple test can be performed in user space (no root) in your own home directory.

+ 11 - 5
netcon/RPC.c

@@ -3,7 +3,10 @@
 #include <sys/un.h>
 #include <sys/un.h>
 #include <pthread.h>
 #include <pthread.h>
 #include <errno.h>
 #include <errno.h>
+
+#if defined(__linux__)
 #include <sys/syscall.h>
 #include <sys/syscall.h>
+#endif
 
 
 #include <fcntl.h>
 #include <fcntl.h>
 #include <dlfcn.h>
 #include <dlfcn.h>
@@ -70,12 +73,12 @@ int get_retval(int rpc_sock)
 
 
 int load_symbols_rpc()
 int load_symbols_rpc()
 {
 {
-  #ifdef NETCON_INTERCEPT
+#ifdef NETCON_INTERCEPT
   realsocket = dlsym(RTLD_NEXT, "socket");
   realsocket = dlsym(RTLD_NEXT, "socket");
   realconnect = dlsym(RTLD_NEXT, "connect");
   realconnect = dlsym(RTLD_NEXT, "connect");
   if(!realconnect || !realsocket)
   if(!realconnect || !realsocket)
     return -1;
     return -1;
-  #endif
+#endif
   return 1;
   return 1;
 }
 }
 
 
@@ -131,19 +134,22 @@ int rpc_send_command(char *path, int cmd, int forfd, void *data, int len)
   memcpy(&cmdbuf[CANARY_IDX], &canary_num, CANARY_SZ);
   memcpy(&cmdbuf[CANARY_IDX], &canary_num, CANARY_SZ);
   memcpy(&cmdbuf[STRUCT_IDX], data, len);
   memcpy(&cmdbuf[STRUCT_IDX], data, len);
 
 
-#ifdef VERBOSE
+#if defined(VERBOSE)
+  rpc_count++;
   memset(metabuf, 0, BUF_SZ);
   memset(metabuf, 0, BUF_SZ);
+#if defined(__linux__)
   pid_t pid = syscall(SYS_getpid);
   pid_t pid = syscall(SYS_getpid);
   pid_t tid = syscall(SYS_gettid);
   pid_t tid = syscall(SYS_gettid);
-  rpc_count++;
+#endif
   char timestring[20];
   char timestring[20];
   time_t timestamp;
   time_t timestamp;
   timestamp = time(NULL);
   timestamp = time(NULL);
   strftime(timestring, sizeof(timestring), "%H:%M:%S", localtime(&timestamp));
   strftime(timestring, sizeof(timestring), "%H:%M:%S", localtime(&timestamp));
   memcpy(metabuf, RPC_PHRASE, RPC_PHRASE_SZ); // Write signal phrase
   memcpy(metabuf, RPC_PHRASE, RPC_PHRASE_SZ); // Write signal phrase
-  
+#if defined(__linux__)
   memcpy(&metabuf[IDX_PID],     &pid,         sizeof(pid_t)      ); /* pid       */
   memcpy(&metabuf[IDX_PID],     &pid,         sizeof(pid_t)      ); /* pid       */
   memcpy(&metabuf[IDX_TID],     &tid,         sizeof(pid_t)      ); /* tid       */
   memcpy(&metabuf[IDX_TID],     &tid,         sizeof(pid_t)      ); /* tid       */
+#endif
   memcpy(&metabuf[IDX_COUNT],   &rpc_count,   sizeof(rpc_count)  ); /* rpc_count */
   memcpy(&metabuf[IDX_COUNT],   &rpc_count,   sizeof(rpc_count)  ); /* rpc_count */
   memcpy(&metabuf[IDX_TIME],    &timestring,   20                ); /* timestamp */
   memcpy(&metabuf[IDX_TIME],    &timestring,   20                ); /* timestamp */
 #endif
 #endif