From 2f455315a745db910e924b35966d5a6b576171f4 Mon Sep 17 00:00:00 2001 From: garden Date: Sun, 13 Nov 2005 21:38:07 +0000 Subject: [PATCH] - added support for Mac OSX (10.3 Panther and 10.4 Tiger). For tuntap support it requires the tuntap driver by Mattias Nissler: http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ There are still some problems because of the differences in socket semantics between Linux and BSD. It should work but in some cases (heavy traffic) there will probably be severe packet loss if the sender is a OSX machine. - added poll emulation for Tiger (poll() is broken for devices) git-svn-id: https://vde.svn.sourceforge.net/svnroot/vde/trunk@60 d37a7db1-d92d-0410-89df-f68f52f87b57 --- vde-2/Makefile.am | 48 +++++++++------ vde-2/bitarray.h | 30 +++++----- vde-2/configure.ac | 70 +++++++++++++++++++--- vde-2/consmgmt.c | 7 ++- vde-2/datasock.c | 45 +++++++++----- vde-2/fstp.c | 1 + vde-2/poll2select.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++ vde-2/poll2select.h | 33 +++++++++++ vde-2/port.c | 1 + vde-2/qemu/vdeq.c | 3 +- vde-2/slirpvde/if.c | 12 ++-- vde-2/slirpvde/slirpvde.c | 14 ++++- vde-2/slirpvde/socket.c | 5 +- vde-2/slirpvde/tcp_subr.c | 4 +- vde-2/slirpvde/udp.c | 4 +- vde-2/sockutils.c | 2 +- vde-2/tuntap.c | 46 ++++++++++++++- vde-2/unixterm.c | 10 ++-- vde-2/vde.h | 10 ++++ vde-2/vde_plug.c | 16 ++++- vde-2/vde_switch.c | 23 ++++++-- vde-2/vdetaplib/vdetap.c | 3 +- vde-2/wirefilter.c | 17 ++++-- 23 files changed, 458 insertions(+), 92 deletions(-) create mode 100644 vde-2/poll2select.c create mode 100644 vde-2/poll2select.h diff --git a/vde-2/Makefile.am b/vde-2/Makefile.am index 8f0bbc4..c2c0c11 100644 --- a/vde-2/Makefile.am +++ b/vde-2/Makefile.am @@ -1,4 +1,10 @@ -SUBDIRS = qemu slirpvde vdetaplib bochs uml doc +SUBDIRS = qemu slirpvde bochs uml doc + +if WANT_TUNTAP +if CAN_MAKE_LIBVDETAP + SUBDIRS += vdetaplib +endif +endif AUTOMAKE_OPTIONS = foreign @@ -6,24 +12,24 @@ EXTRA_DIST = LICENSE VERSION ChangeLog bin_PROGRAMS = vde_switch dpipe vde_plug unixterm wirefilter vde_switch_SOURCES = \ - hash.c \ - hash.h \ - port.c \ - port.h \ - vde_switch.c \ - switch.h \ - vde.h \ - sockutils.c \ - sockutils.h \ - qtimer.c \ - qtimer.h \ - datasock.c \ - datasock.h \ - consmgmt.c \ - consmgmt.h \ - fstp.c \ - fstp.h \ - bitarray.h + hash.c \ + hash.h \ + port.c \ + port.h \ + vde_switch.c \ + switch.h \ + vde.h \ + sockutils.c \ + sockutils.h \ + qtimer.c \ + qtimer.h \ + datasock.c \ + datasock.h \ + consmgmt.c \ + consmgmt.h \ + fstp.c \ + fstp.h \ + bitarray.h dpipe_SOURCES = dpipe.c vde_plug_SOURCES = vde_plug.c vde.h unixterm_SOURCES = unixterm.c @@ -32,6 +38,10 @@ if WANT_TUNTAP vde_switch_SOURCES += tuntap.c tuntap.h endif +if HAVE_BROKEN_POLL + vde_switch_SOURCES += poll2select.c poll2select.h +endif + AM_CFLAGS = -Wall AM_CXXFLAGS = -Wall diff --git a/vde-2/bitarray.h b/vde-2/bitarray.h index bcaad8c..a77f528 100644 --- a/vde-2/bitarray.h +++ b/vde-2/bitarray.h @@ -1,5 +1,6 @@ /* BITARRAY (C) 2005 Renzo Davoli * Licensed under the GPLv2 + * Modified by Ludovico Gardenghi 2005 * * A bitarray is (a pointer to) an array of memory words, can be used as a set. * +--------------------------------+--------------------------------+---- @@ -62,19 +63,22 @@ #ifndef _BITARRAY_H #define _BITARRAY_H #include -#include +#include -#if __WORDSIZE == 32 /* 32 bits */ + +#if __LONG_MAX__ == 2147483647L /* 32 bits */ +# define __VDEWORDSIZE 32 # define __LOG_WORDSIZE (5) # define __WORDSIZEMASK 0x1f -#elif __WORDSIZE == 64 /* 64 bits */ +#elif __LONG_MAX__ == 9223372036854775807L /* 64 bits */ +# define __VDEWORDSIZE 64 # define __LOG_WORDSIZE (6) # define __WORDSIZEMASK 0x3f #else # error sorry this program has been tested only on 32 or 64 bit machines #endif -#define __WORDSIZE_1 (__WORDSIZE-1) +#define __WORDSIZE_1 (__VDEWORDSIZE-1) #define __WORDSIZEROUND(VX) ((VX + __WORDSIZE_1) >> __LOG_WORDSIZE) typedef unsigned long bitarrayelem; @@ -110,8 +114,8 @@ typedef bitarrayelem *bitarray; register bitarrayelem __v; \ int max=__WORDSIZEROUND(N); \ for (__i=0; __i< max; __i++) \ - for (__v=(X)[__i],__j=0; __j < __WORDSIZE; __v >>=1, __j++) \ - if (__v & 1) (F)(__i*__WORDSIZE+__j,(ARG)); \ + for (__v=(X)[__i],__j=0; __j < __VDEWORDSIZE; __v >>=1, __j++) \ + if (__v & 1) (F)(__i*__VDEWORDSIZE+__j,(ARG)); \ 0; }) #define BA_FORALL(X,N,EXPR,K) \ @@ -119,8 +123,8 @@ typedef bitarrayelem *bitarray; register bitarrayelem __v; \ int max=__WORDSIZEROUND(N); \ for (__i=0; __i< max; __i++) \ - for (__v=(X)[__i],__j=0; __j < __WORDSIZE; __v >>=1, __j++) \ - if (__v & 1) {(K)=__i*__WORDSIZE+__j;(EXPR);} \ + for (__v=(X)[__i],__j=0; __j < __VDEWORDSIZE; __v >>=1, __j++) \ + if (__v & 1) {(K)=__i*__VDEWORDSIZE+__j;(EXPR);} \ 0; }) #define BA_CARD(X,N) \ @@ -128,7 +132,7 @@ typedef bitarrayelem *bitarray; register bitarrayelem __v; \ int max=__WORDSIZEROUND(N); \ for (__i=0; __i< max; __i++) \ - for (__v=(X)[__i],__j=0; __j < __WORDSIZE; __v >>=1, __j++) \ + for (__v=(X)[__i],__j=0; __j < __VDEWORDSIZE; __v >>=1, __j++) \ if (__v & 1) __n++; \ __n; }) @@ -211,8 +215,8 @@ typedef bitarrayelem *bitarray; register bitarrayelem __v; \ register int __n=(X)[__WORDSIZEROUND(N)]; \ for (__i=0; __n > 0; __i++) \ - for (__v=(X)[__i],__j=0; __j < __WORDSIZE; __v >>=1, __j++) \ - if (__v & 1) (F)(__i*__WORDSIZE+__j,(ARG)),__n--; \ + for (__v=(X)[__i],__j=0; __j < __VDEWORDSIZE; __v >>=1, __j++) \ + if (__v & 1) (F)(__i*__VDEWORDSIZE+__j,(ARG)),__n--; \ 0; }) #define BAC_FORALL(X,N,EXPR,K) \ @@ -220,8 +224,8 @@ typedef bitarrayelem *bitarray; register bitarrayelem __v; \ register int __n=(X)[__WORDSIZEROUND(N)]; \ for (__i=0; __n > 0; __i++) \ - for (__v=(X)[__i],__j=0; __j < __WORDSIZE; __v >>=1, __j++) \ - if (__v & 1) (K)=__i*__WORDSIZE+__j,(EXPR),__n--; \ + for (__v=(X)[__i],__j=0; __j < __VDEWORDSIZE; __v >>=1, __j++) \ + if (__v & 1) (K)=__i*__VDEWORDSIZE+__j,(EXPR),__n--; \ 0; }) #define BAC_CARD(X,N) ((X)[__WORDSIZEROUND(N)]) diff --git a/vde-2/configure.ac b/vde-2/configure.ac index 67b6cd7..6e9816b 100644 --- a/vde-2/configure.ac +++ b/vde-2/configure.ac @@ -42,7 +42,7 @@ AC_FUNC_REALLOC AC_FUNC_SELECT_ARGTYPES AC_TYPE_SIGNAL AC_FUNC_VPRINTF -AC_CHECK_FUNCS([atexit dup2 gethostbyname gethostname gettimeofday inet_ntoa memmove memset putenv select setenv socket strchr strdup strerror strstr uname inet_aton sprintf readv random srandom index bcmp drand48 memmove gethostid revoke fchmod]) +AC_CHECK_FUNCS([atexit dup2 gethostbyname gethostname gettimeofday inet_ntoa memmove memset putenv select setenv socket strchr strdup strerror strstr uname inet_aton sprintf readv random srandom index bcmp drand48 memmove gethostid revoke fchmod getopt_long_only]) # All other nice checks I have to make for recostructing missing parts of # slirp's config.h file @@ -51,6 +51,20 @@ AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(char *) +# Define VDE_LINUX or VDE_DARWIN +case "$build_os" in + linux*) + AC_DEFINE([VDE_LINUX], 1, [If defined, this is a Linux system]) + ;; + darwin*) + AC_DEFINE([VDE_DARWIN], 1, [If defined, this is a Darwin system]) + ;; + *) + AC_MSG_ERROR([Unsupported architecture: $build_os. At the moment, only +Linux and Darwin are supported. Contributions are appreciated! :-)]) + ;; +esac + # Check of tuntap device AC_ARG_ENABLE([tuntap], AS_HELP_STRING([--disable-tuntap], @@ -58,17 +72,55 @@ AC_ARG_ENABLE([tuntap], [if test $enableval != "no" ; then add_tuntap_support=yes ; else add_tuntap_support=no ; fi], [add_tuntap_support=yes]) -AM_CONDITIONAL(WANT_TUNTAP, test "$add_tuntap_support" = yes) +# Check for tuntap support for Linux and OSX if test "$add_tuntap_support" = yes ; then - AC_CHECK_HEADER([linux/if_tun.h], - [AC_DEFINE([TUNTAP], 1, [If defined, tuntap support is compiled in])], - [AC_MSG_ERROR([Tuntap support seem to be not enabled on your kernel])]) + case "$build_os" in + linux*) + AC_CHECK_HEADER([linux/if_tun.h], + [AC_DEFINE([TUNTAP], 1, [If defined, tuntap support is compiled in])], + [AC_MSG_ERROR([Tuntap support seem to be not enabled on your kernel])]) + can_make_libvdetap=yes + ;; + darwin*) + # I don't use AC_CHECK_FILES because I need test -e and not test -r + for i in /dev/tap0 /Library/Extensions/tap.kext /System/Library/Extensions/tap.kext ; do + AC_MSG_CHECKING([for $i]) + if test -e "$i" ; then + AC_MSG_RESULT([yes]) + definename="`echo "$i" | tr "a-z*" "A-ZP" | tr -c "0-9A-Z" "_"`" + AC_DEFINE_UNQUOTED([HAVE_$definename]) + eval HAVE_$definename=yes + else + AC_MSG_RESULT([no]) + fi + done + + if test "$HAVE__DEV_TAP0_" ; then + AC_DEFINE([TUNTAP], 1, [If defined, tuntap support is compiled in]) + if ! test "$HAVE__LIBRARY_EXTENSIONS_TAP_KEXT_" -o "$HAVE__SYSTEM_LIBRARY_EXTENSIONS_TAP_KEXT_" ; then + AC_MSG_WARN([/dev/tap0 exists, but the kext cannot be found. Let's hope your +configuration does work...]) + fi + AC_MSG_CHECKING([for broken poll() support in Tiger]) + if expr "$build_os" : "darwin8\..*" > /dev/null; then + AC_MSG_RESULT([yes, emulating with select()]) + AC_DEFINE([HAVE_BROKEN_POLL], 1, [If defined, use poll2select]) + have_broken_poll=yes + else + AC_MSG_RESULT([no]) + fi + else + AC_MSG_ERROR([You do not have tuntap support. You can get it here: +http://www-user.rhrk.uni-kl.de/~nissler/tuntap/]) + fi + ;; + esac fi -#AC_CONFIG_FILES([doc/Makefile -# qemu/Makefile -# slirpvde/Makefile -# vdetaplib/Makefile]) +AM_CONDITIONAL(WANT_TUNTAP, test "$add_tuntap_support" = yes) +AM_CONDITIONAL(CAN_MAKE_LIBVDETAP, test "$can_make_libvdetap" = yes) +AM_CONDITIONAL(HAVE_BROKEN_POLL, test "$have_broken_poll" = yes) + AC_CONFIG_FILES([Makefile] [doc/Makefile] [qemu/Makefile] diff --git a/vde-2/consmgmt.c b/vde-2/consmgmt.c index c6e373c..ae133d8 100644 --- a/vde-2/consmgmt.c +++ b/vde-2/consmgmt.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #define _GNU_SOURCE @@ -210,7 +210,8 @@ static void handle_input(unsigned char type,int fd,int revents,int *unused) } } else {/* mgmt ctl */ struct sockaddr addr; - int len, new; + int new; + socklen_t len; len = sizeof(addr); new = accept(fd, &addr, &len); @@ -374,7 +375,7 @@ static void init(void) return; } sun.sun_family = PF_UNIX; - snprintf(sun.sun_path,UNIX_PATH_MAX,"%s",mgmt_socket); + snprintf(sun.sun_path,sizeof(sun.sun_path),"%s",mgmt_socket); if(bind(mgmtconnfd, (struct sockaddr *) &sun, sizeof(sun)) < 0){ if((errno == EADDRINUSE) && still_used(&sun)) return; else if(bind(mgmtconnfd, (struct sockaddr *) &sun, sizeof(sun)) < 0){ diff --git a/vde-2/datasock.c b/vde-2/datasock.c index d12b0f2..152eb03 100644 --- a/vde-2/datasock.c +++ b/vde-2/datasock.c @@ -1,6 +1,7 @@ /* Copyright 2005 Renzo Davoli - VDE-2 * --pidfile/-p and cleanup management by Mattia Belletti (C) 2004. * Licensed under the GPLv2 + * Modified by Ludovico Gardenghi 2005 */ #include @@ -18,13 +19,13 @@ #include #include #include -#include +#include #include #include #define _GNU_SOURCE #include -#include +//#include #include #include @@ -32,7 +33,6 @@ #include #include - static struct swmodule swmi; static struct mod_support modfun; static unsigned int ctl_type; @@ -44,6 +44,7 @@ static char *ctl_socket; #define MODULENAME "unix prog" +#define DATA_BUF_SIZE 131072 #define SWITCH_MAGIC 0xfeedface #define REQBUFLEN 256 @@ -77,7 +78,6 @@ union request { static void send_datasock(int fd, int ctl_fd, void *packet, int len, void *data, int port) { int n; - struct sockaddr *dst=(struct sockaddr *)data; n = sendto(fd, packet, len, 0, dst, sizeof(struct sockaddr_un)); @@ -96,6 +96,11 @@ static int newport(int fd, int portno) { int data_fd; struct sockaddr_un sun; +#ifdef VDE_DARWIN + int sockbufsize = DATA_BUF_SIZE; + int optsize = sizeof(sockbufsize); +#endif + if((data_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0){ printlog(LOG_ERR,"socket: %s",strerror(errno)); return -1; @@ -104,8 +109,18 @@ static int newport(int fd, int portno) printlog(LOG_ERR,"Setting O_NONBLOCK on data fd %s",strerror(errno)); return -1; } + +#ifdef VDE_DARWIN + if(setsockopt(data_fd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, optsize) < 0) + printlog(LOG_WARNING, "Warning: setting send buffer size on data fd %d to %d failed, expect packet loss: %s", + data_fd, sockbufsize, strerror(errno)); + if(setsockopt(data_fd, SOL_SOCKET, SO_RCVBUF, &sockbufsize, optsize) < 0) + printlog(LOG_WARNING, "Warning: setting send buffer size on data fd %d to %d failed, expect packet loss: %s", + data_fd, sockbufsize, strerror(errno)); +#endif + sun.sun_family = AF_UNIX; - snprintf(sun.sun_path,UNIX_PATH_MAX,"%s/%03d",ctl_socket,portno); + snprintf(sun.sun_path,sizeof(sun.sun_path),"%s/%03d",ctl_socket,portno); if ((unlink(sun.sun_path) < 0 && errno != ENOENT) || bind(data_fd, (struct sockaddr *) &sun, sizeof(sun)) < 0){ printlog(LOG_ERR,"Binding to data socket %s",strerror(errno)); @@ -169,7 +184,7 @@ static int new_port_v1_v3(int fd, int type_port, return -1; } sun_in.sun_family = AF_UNIX; - snprintf(sun_in.sun_path,UNIX_PATH_MAX,"%s/%03d",ctl_socket,port); + snprintf(sun_in.sun_path,sizeof(sun_in.sun_path),"%s/%03d",ctl_socket,port); if (sun_out->sun_path[0] != 0) { //not for unnamed sockets if ((cluid=checksockperm(sun_out->sun_path,sun_in.sun_path)) < 0) { printlog(LOG_WARNING,"Data_out socket permission: %s",strerror(errno)); @@ -203,7 +218,8 @@ static void handle_input(unsigned char type,int fd,int revents,int *arg) if (type == data_type) { struct bipacket packet; struct sockaddr sock; - int len, socklen = sizeof(sock); + int len; + socklen_t socklen = sizeof(sock); len=recvfrom(fd, &(packet.p), sizeof(struct packet),0, &sock, &socklen); if(len < 0){ @@ -256,7 +272,8 @@ static void handle_input(unsigned char type,int fd,int revents,int *arg) } else /*if (type == ctl_type)*/ { struct sockaddr addr; - int len, new; + socklen_t len; + int new; len = sizeof(addr); new = accept(fd, &addr, &len); @@ -276,17 +293,17 @@ static void handle_input(unsigned char type,int fd,int revents,int *arg) static void cleanup(unsigned char type,int fd,int arg) { - char path[UNIX_PATH_MAX]; + struct sockaddr_un clun; if (fd < 0) { - snprintf(path,UNIX_PATH_MAX,"%s/ctl",ctl_socket); - if(unlink(path) < 0) + snprintf(clun.sun_path,sizeof(clun.sun_path),"%s/ctl",ctl_socket); + if(unlink(clun.sun_path) < 0) printlog(LOG_WARNING,"Couldn't remove ctl socket '%s' : %s", ctl_socket, strerror(errno)); else if(rmdir(ctl_socket) < 0) printlog(LOG_WARNING,"Couldn't remove ctl dir '%s' : %s", ctl_socket, strerror(errno)); } else { if (type == data_type && arg>=0) { - snprintf(path,UNIX_PATH_MAX,"%s/%03d",ctl_socket,arg); - unlink(path); + snprintf(clun.sun_path,sizeof(clun.sun_path),"%s/%03d",ctl_socket,arg); + unlink(clun.sun_path); } close(fd); } @@ -352,7 +369,7 @@ static void init(void) return; } sun.sun_family = AF_UNIX; - snprintf(sun.sun_path,UNIX_PATH_MAX,"%s/ctl",ctl_socket); + snprintf(sun.sun_path,sizeof(sun.sun_path),"%s/ctl",ctl_socket); if(bind(connect_fd, (struct sockaddr *) &sun, sizeof(sun)) < 0){ if((errno == EADDRINUSE) && still_used(&sun)) return; else if(bind(connect_fd, (struct sockaddr *) &sun, sizeof(sun)) < 0){ diff --git a/vde-2/fstp.c b/vde-2/fstp.c index 6944826..941dbed 100644 --- a/vde-2/fstp.c +++ b/vde-2/fstp.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/vde-2/poll2select.c b/vde-2/poll2select.c new file mode 100644 index 0000000..fcf84b7 --- /dev/null +++ b/vde-2/poll2select.c @@ -0,0 +1,146 @@ +/* + * poll2select - convert poll() calls to select() calls + * Copyright 2005 Ludovico Gardenghi + * Licensed under the GPLv2 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "poll2select.h" + +#ifndef MAX +#define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +static int prepare_select(struct pollfd *ufds, nfds_t nfds, int timeout, + struct timeval **pstimeout, int *maxfdp1, fd_set *rfds, fd_set *wfds, fd_set *efds) +{ + register int i; + struct pollfd *currfd; + struct timeval *stimeout = *pstimeout; + + /* + * Conversion of information about file descriptors + */ + + *maxfdp1 = 0; + + if ((nfds > 0) && (ufds == NULL)) + { + errno = EFAULT; + return 0; + } + + for (i = 0; i < nfds; i++) + { + currfd = &ufds[i]; + + if (currfd->fd < 0) + { + errno = EBADF; + return 0; + } + + if (currfd->events & POLLIN) + FD_SET(currfd->fd, rfds); + if (currfd->events & POLLOUT) + FD_SET(currfd->fd, wfds); + if (currfd->events & POLLPRI) + FD_SET(currfd->fd, efds); + + *maxfdp1 = MAX(*maxfdp1, currfd->fd); + } + + (*maxfdp1)++; + + /* + * Conversion of information about timeout + */ + + if (timeout == 0) + { + if (stimeout == NULL) + { + errno = EINVAL; + return 0; + } + stimeout->tv_sec = 0; + stimeout->tv_usec = 0; + } + else if (timeout > 0) + { + if (stimeout == NULL) + { + errno = EINVAL; + return 0; + } + stimeout->tv_sec = timeout / 1000; + stimeout->tv_usec = (timeout % 1000) * 1000; + } + else // if (timeout < 0) + *pstimeout = NULL; + + return 1; +} + +static int convert_results(struct pollfd *ufds, int nfds, + fd_set *rfds, fd_set *wfds, fd_set *efds) +{ + register int i; + struct pollfd *currfd; + int retval = 0; + + for (i = 0; i < nfds; i++) + { + currfd = &ufds[i]; + + currfd->revents = 0; + + if (FD_ISSET(currfd->fd, rfds)) + currfd->revents |= POLLIN; + if (FD_ISSET(currfd->fd, wfds)) + currfd->revents |= POLLOUT; + if (FD_ISSET(currfd->fd, efds)) + currfd->revents |= POLLPRI; + + if (currfd->revents != 0) + retval++; + } + + return retval; +} + +int poll2select(struct pollfd *ufds, nfds_t nfds, int timeout) +{ + fd_set rfds, wfds, efds; + struct timeval stimeout; + struct timeval *pstimeout = &stimeout; + int maxfdp1; + int pretval, sretval, tretval; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + + tretval = prepare_select(ufds, nfds, timeout, &pstimeout, &maxfdp1, &rfds, &wfds, &efds); + if (!tretval) + return -1; + + sretval = select(maxfdp1, &rfds, &wfds, &efds, pstimeout); + if (sretval <= 0) + return sretval; + + pretval = convert_results(ufds, nfds, &rfds, &wfds, &efds); + + return pretval; +} + diff --git a/vde-2/poll2select.h b/vde-2/poll2select.h new file mode 100644 index 0000000..e0aeca6 --- /dev/null +++ b/vde-2/poll2select.h @@ -0,0 +1,33 @@ +/* + * poll2select - convert poll() calls to select() calls + * Copyright 2005 Ludovico Gardenghi + * Licensed under the GPLv2 + */ + +#ifndef POLL2SELECT_H_ +#define POLL2SELECT_H_ + +/* + * poll.h already has these definitions, so we must not repeat them in case + * someone included that header + */ +#ifndef _SYS_POLL_H_ + +#define POLLIN 0x0001 +#define POLLPRI 0x0002 +#define POLLOUT 0x0004 + +struct pollfd +{ + int fd; + short events; + short revents; +}; + +typedef unsigned int nfds_t; + +#endif + +int poll2select(struct pollfd *, nfds_t, int); + +#endif diff --git a/vde-2/port.c b/vde-2/port.c index 1336516..6dfe7eb 100644 --- a/vde-2/port.c +++ b/vde-2/port.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/vde-2/qemu/vdeq.c b/vde-2/qemu/vdeq.c index dc33afa..5b2e333 100644 --- a/vde-2/qemu/vdeq.c +++ b/vde-2/qemu/vdeq.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -156,7 +157,7 @@ int main(int argc, char **argv) int *fddata; char *argsock,**sockname; struct sockaddr_un *dataout,datain; - int datainsize; + socklen_t datainsize; int result; int *connected_fd; register ssize_t nx; diff --git a/vde-2/slirpvde/if.c b/vde-2/slirpvde/if.c index 36a5ee0..d2250af 100644 --- a/vde-2/slirpvde/if.c +++ b/vde-2/slirpvde/if.c @@ -272,12 +272,12 @@ if_start(void) DEBUG_CALL("if_start"); if (if_queued == 0) - return; /* Nothing to do */ - - again: - /* check if we can really output */ - if (!slirp_can_output()) - return; + return; /* Nothing to do */ + +again: + /* check if we can really output */ + if (!slirp_can_output()) + return; /* * See which queue to get next packet from diff --git a/vde-2/slirpvde/slirpvde.c b/vde-2/slirpvde/slirpvde.c index 64e53b9..58755d2 100644 --- a/vde-2/slirpvde/slirpvde.c +++ b/vde-2/slirpvde/slirpvde.c @@ -1,11 +1,13 @@ /* Copyright 2003 Renzo Davoli * Licensed under the GPL + * Modified by Ludovico Gardenghi 2005 */ #include #include #include #include +#include #include #include #include @@ -161,13 +163,19 @@ static void setsighandlers() { SIGTERM, "SIGTERM", 0 }, { SIGUSR1, "SIGUSR1", 1 }, { SIGUSR2, "SIGUSR2", 1 }, - { SIGPOLL, "SIGPOLL", 1 }, { SIGPROF, "SIGPROF", 1 }, { SIGVTALRM, "SIGVTALRM", 1 }, +#ifdef VDE_LINUX + { SIGPOLL, "SIGPOLL", 1 }, { SIGSTKFLT, "SIGSTKFLT", 1 }, { SIGIO, "SIGIO", 1 }, { SIGPWR, "SIGPWR", 1 }, { SIGUNUSED, "SIGUNUSED", 1 }, +#endif +#ifdef VDE_DARWIN + { SIGXCPU, "SIGXCPU", 1 }, + { SIGXFSZ, "SIGXFSZ", 1 }, +#endif { 0, NULL, 0 } }; @@ -245,7 +253,7 @@ int main(int argc, char **argv) { char *sockname=NULL; struct sockaddr_un datain; - int datainsize; + socklen_t datainsize; int result,nfds; int port=0; int connected_fd; @@ -259,7 +267,7 @@ int main(int argc, char **argv) filename=basename(argv[0]); - while ((opt=getopt_long_only(argc,argv,"s:n:p:g:m:d",slirpvdeopts,&longindx)) > 0) { + while ((opt=GETOPT_LONG(argc,argv,"s:n:p:g:m:d",slirpvdeopts,&longindx)) > 0) { switch (opt) { case 's' : sockname=optarg; break; diff --git a/vde-2/slirpvde/socket.c b/vde-2/slirpvde/socket.c index 084a0c3..aa5d2ac 100644 --- a/vde-2/slirpvde/socket.c +++ b/vde-2/slirpvde/socket.c @@ -378,7 +378,7 @@ sorecvfrom(so) struct socket *so; { struct sockaddr_in addr; - int addrlen = sizeof(struct sockaddr_in); + socklen_t addrlen = sizeof(struct sockaddr_in); DEBUG_CALL("sorecvfrom"); DEBUG_ARG("so = %lx", (long)so); @@ -531,7 +531,8 @@ solisten(port, laddr, lport, flags) { struct sockaddr_in addr; struct socket *so; - int s, addrlen = sizeof(addr), opt = 1; + int s; + socklen_t addrlen = sizeof(addr), opt = 1; DEBUG_CALL("solisten"); DEBUG_ARG("port = %d", port); diff --git a/vde-2/slirpvde/tcp_subr.c b/vde-2/slirpvde/tcp_subr.c index 516eb45..7195d16 100644 --- a/vde-2/slirpvde/tcp_subr.c +++ b/vde-2/slirpvde/tcp_subr.c @@ -461,7 +461,7 @@ tcp_connect(inso) { struct socket *so; struct sockaddr_in addr; - int addrlen = sizeof(struct sockaddr_in); + socklen_t addrlen = sizeof(struct sockaddr_in); struct tcpcb *tp; int s, opt; @@ -656,7 +656,7 @@ tcp_emu(so, m) { struct socket *tmpso; struct sockaddr_in addr; - int addrlen = sizeof(struct sockaddr_in); + socklen_t addrlen = sizeof(struct sockaddr_in); struct sbuf *so_rcv = &so->so_rcv; memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); diff --git a/vde-2/slirpvde/udp.c b/vde-2/slirpvde/udp.c index 7154cec..4a54886 100644 --- a/vde-2/slirpvde/udp.c +++ b/vde-2/slirpvde/udp.c @@ -398,7 +398,7 @@ udp_emu(so, m) struct mbuf *m; { struct sockaddr_in addr; - int addrlen = sizeof(addr); + socklen_t addrlen = sizeof(addr); #ifdef EMULATE_TALK CTL_MSG_OLD *omsg; CTL_MSG *nmsg; @@ -623,7 +623,7 @@ udp_listen(port, laddr, lport, flags) { struct sockaddr_in addr; struct socket *so; - int addrlen = sizeof(struct sockaddr_in), opt = 1; + socklen_t addrlen = sizeof(struct sockaddr_in), opt = 1; if ((so = socreate()) == NULL) { free(so); diff --git a/vde-2/sockutils.c b/vde-2/sockutils.c index d8e41c6..063c618 100644 --- a/vde-2/sockutils.c +++ b/vde-2/sockutils.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/vde-2/tuntap.c b/vde-2/tuntap.c index af76f24..8467bca 100644 --- a/vde-2/tuntap.c +++ b/vde-2/tuntap.c @@ -1,6 +1,7 @@ /* Copyright 2005 Renzo Davoli - VDE-2 * --pidfile/-p and cleanup management by Mattia Belletti (C) 2004. * Licensed under the GPLv2 + * Modified by Ludovico Gardenghi 2005 (OSX tuntap support) */ #include @@ -15,12 +16,18 @@ #include #include #include -#include #include #define _GNU_SOURCE #include +#ifdef VDE_LINUX +#include #include +#endif + +#ifdef VDE_DARWIN +#define TAP_PREFIX "/dev/" +#endif #include #include @@ -89,6 +96,11 @@ static void usage(void) printf( "(opts from tuntap module)\n" " -t, --tap TAP Enable routing through TAP tap interface\n" +#ifdef VDE_DARWIN + " TAP can be an absolute file name or a relative\n" + " one (and will be prefixed with %s). The TAP\n" + " device must already exist.\n", TAP_PREFIX +#endif ); } @@ -129,6 +141,7 @@ static int parseopt(int c, char *optarg) return outc; } +#ifdef VDE_LINUX int open_tap(char *dev) { struct ifreq ifr; @@ -149,6 +162,37 @@ int open_tap(char *dev) } return(fd); } +#endif + +#ifdef VDE_DARWIN +int open_tap(char *dev) +{ + int fd; + int prefixlen = strlen(TAP_PREFIX); + char *path = NULL; + if (*dev == '/') + fd=open(dev, O_RDWR); + else + { + path = malloc(strlen(dev) + prefixlen + 1); + if (path != NULL) + { + snprintf(path, strlen(dev) + prefixlen + 1, "%s%s", TAP_PREFIX, dev); + fd=open(path, O_RDWR); + free(path); + } + else + fd = -1; + } + + if (fd < 0) + { + printlog(LOG_ERR,"Failed to open tap device %s: %s", (*dev == '/') ? dev : path, strerror(errno)); + return(-1); + } + return fd; +} +#endif static int newport(int fd, int portno) { diff --git a/vde-2/unixterm.c b/vde-2/unixterm.c index ea15d61..970cd27 100644 --- a/vde-2/unixterm.c +++ b/vde-2/unixterm.c @@ -8,9 +8,11 @@ #include #include #include -#include -#include -#include +#include +#include +#include + +#include #define BUFSIZE 1024 char buf[BUFSIZE]; @@ -25,7 +27,7 @@ int main(int argc,char *argv[]) {STDIN_FILENO,POLLIN | POLLHUP,0}}; static int fileout[]={STDOUT_FILENO,STDOUT_FILENO}; sun.sun_family=PF_UNIX; - snprintf(sun.sun_path,UNIX_PATH_MAX,"%s",argv[1]); + snprintf(sun.sun_path,sizeof(sun.sun_path),"%s",argv[1]); fd=socket(PF_UNIX,SOCK_STREAM,0); rv=connect(fd,(struct sockaddr *)(&sun),sizeof(sun)); pfd[1].fd=fileout[0]=fd; diff --git a/vde-2/vde.h b/vde-2/vde.h index b4bccc9..8cdf415 100644 --- a/vde-2/vde.h +++ b/vde-2/vde.h @@ -1,3 +1,12 @@ +#ifndef VDE_H_ +#define VDE_H_ + +#ifdef HAVE_GETOPT_LONG_ONLY +#define GETOPT_LONG getopt_long_only +#else +#define GETOPT_LONG getopt_long +#endif + #ifndef VDESTDSOCK #define VDESTDSOCK "/var/run/vde.ctl" #define VDETMPSOCK "/tmp/vde.ctl" @@ -6,3 +15,4 @@ #define DO_SYSLOG #define VDE_IP_LOG +#endif diff --git a/vde-2/vde_plug.c b/vde-2/vde_plug.c index 12d17dc..29beb2b 100644 --- a/vde-2/vde_plug.c +++ b/vde-2/vde_plug.c @@ -1,5 +1,6 @@ /* Copyright 2002 Renzo Davoli * Licensed under the GPL + * Modified by Ludovico Gardenghi 2005 */ #include @@ -13,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -31,7 +32,10 @@ #include #endif +#ifndef MIN #define MIN(X,Y) (((X)<(Y))?(X):(Y)) +#endif + #define SWITCH_MAGIC 0xfeedface #define BUFSIZE 2048 #define MAXDESCR 128 @@ -361,13 +365,19 @@ static void setsighandlers() { SIGTERM, "SIGTERM", 0 }, { SIGUSR1, "SIGUSR1", 1 }, { SIGUSR2, "SIGUSR2", 1 }, - { SIGPOLL, "SIGPOLL", 1 }, { SIGPROF, "SIGPROF", 1 }, { SIGVTALRM, "SIGVTALRM", 1 }, +#ifdef VDE_LINUX + { SIGPOLL, "SIGPOLL", 1 }, { SIGSTKFLT, "SIGSTKFLT", 1 }, { SIGIO, "SIGIO", 1 }, { SIGPWR, "SIGPWR", 1 }, { SIGUNUSED, "SIGUNUSED", 1 }, +#endif +#ifdef VDE_DARWIN + { SIGXCPU, "SIGXCPU", 1 }, + { SIGXFSZ, "SIGXFSZ", 1 }, +#endif { 0, NULL, 0 } }; @@ -430,7 +440,7 @@ int main(int argc, char **argv) {"group",1,0,'g'}, {0, 0, 0, 0} }; - c = getopt_long_only (argc, argv, "hc:p:s:m:g:l", + c = GETOPT_LONG (argc, argv, "hc:p:s:m:g:l", long_options, &option_index); if (c == -1) break; diff --git a/vde-2/vde_switch.c b/vde-2/vde_switch.c index b6c6579..f31130f 100644 --- a/vde-2/vde_switch.c +++ b/vde-2/vde_switch.c @@ -2,6 +2,7 @@ * Licensed under the GPL * --pidfile/-p and cleanup management by Mattia Belletti. * some code remains from uml_switch Copyright 2001, 2002 Jeff Dike and others + * Modified by Ludovico Gardenghi 2005 */ #include @@ -13,8 +14,9 @@ #include #include #include +#ifndef HAVE_BROKEN_POLL #include - +#endif #include #include #include @@ -27,6 +29,13 @@ #include #include +#include + +#ifdef HAVE_BROKEN_POLL +#include "poll2select.h" +#define poll poll2select +#endif + static struct swmodule *swmh; char *prog; @@ -259,7 +268,7 @@ static void Usage(void) { p->usage(); printf( "\n" - "Report bugs to PACKAGE_BUGREPORT\n" + "Report bugs to "PACKAGE_BUGREPORT "\n" ); exit(1); } @@ -394,7 +403,7 @@ static void parse_args(int argc, char **argv) int option_index = 0; int c; while (1) { - c = getopt_long_only (argc, argv, optstring, + c = GETOPT_LONG (argc, argv, optstring, long_options, &option_index); if (c == -1) break; @@ -453,13 +462,19 @@ static void setsighandlers() { SIGTERM, "SIGTERM", 0 }, { SIGUSR1, "SIGUSR1", 1 }, { SIGUSR2, "SIGUSR2", 1 }, - { SIGPOLL, "SIGPOLL", 1 }, { SIGPROF, "SIGPROF", 1 }, { SIGVTALRM, "SIGVTALRM", 1 }, +#ifdef VDE_LINUX + { SIGPOLL, "SIGPOLL", 1 }, { SIGSTKFLT, "SIGSTKFLT", 1 }, { SIGIO, "SIGIO", 1 }, { SIGPWR, "SIGPWR", 1 }, { SIGUNUSED, "SIGUNUSED", 1 }, +#endif +#ifdef VDE_DARWIN + { SIGXCPU, "SIGXCPU", 1 }, + { SIGXFSZ, "SIGXFSZ", 1 }, +#endif { 0, NULL, 0 } }; diff --git a/vde-2/vdetaplib/vdetap.c b/vde-2/vdetaplib/vdetap.c index 128e73d..d539c19 100644 --- a/vde-2/vdetaplib/vdetap.c +++ b/vde-2/vdetaplib/vdetap.c @@ -118,7 +118,8 @@ main(int argc,char *argv[]) { int fd,fddata; struct sockaddr_un dataout,datain; - int datainsize,result,nx; + socklen_t datainsize; + int result,nx; register int i; /*printf("argc = %d\n",argc); for (i=0;i #include #include -#include +#include #include +#include + #define NPIPES 2 #define MAXCONN 3 #define STDIN_ALTFILENO 3 @@ -335,13 +338,19 @@ static void setsighandlers() { SIGTERM, "SIGTERM", 0 }, { SIGUSR1, "SIGUSR1", 1 }, { SIGUSR2, "SIGUSR2", 1 }, - { SIGPOLL, "SIGPOLL", 1 }, { SIGPROF, "SIGPROF", 1 }, { SIGVTALRM, "SIGVTALRM", 1 }, +#ifdef VDE_LINUX + { SIGPOLL, "SIGPOLL", 1 }, { SIGSTKFLT, "SIGSTKFLT", 1 }, { SIGIO, "SIGIO", 1 }, { SIGPWR, "SIGPWR", 1 }, { SIGUNUSED, "SIGUNUSED", 1 }, +#endif +#ifdef VDE_DARWIN + { SIGXCPU, "SIGXCPU", 1 }, + { SIGXFSZ, "SIGXFSZ", 1 }, +#endif { 0, NULL, 0 } }; @@ -373,7 +382,7 @@ static int openmgmt(char *mgmt) exit(1); } sun.sun_family = PF_UNIX; - snprintf(sun.sun_path,UNIX_PATH_MAX,"%s",mgmt); + snprintf(sun.sun_path,sizeof(sun.sun_path),"%s",mgmt); if(bind(mgmtconnfd, (struct sockaddr *) &sun, sizeof(sun)) < 0){ fprintf(stderr,"%s: mgmt bind %s",progname,strerror(errno)); exit(1); @@ -574,7 +583,7 @@ int main(int argc,char *argv[]) while(1) { int c; - c = getopt_long_only (argc, argv, "hnl:d:M:", + c = GETOPT_LONG (argc, argv, "hnl:d:M:", long_options, &option_index); if (c<0) break; -- 2.11.4.GIT