diff options
author | SUZUKI, Shinsuke <suz@kame.net> | 2007-02-27 14:21:41 +0000 |
---|---|---|
committer | Bjørn Mork <bjorn@mork.no> | 2010-08-06 15:37:36 +0200 |
commit | fe2c74572f875332b461ba2a17a594a7ee4eb2d3 (patch) | |
tree | 84ca26e3f0168158823d7c741479e37ba069a862 | |
parent | fcdc0798bb2be5fa00427240afda6bdfd3d0a392 (diff) |
supported compilation on Solaris (contributed by James Carlson)
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | Makefile.in | 13 | ||||
-rw-r--r-- | auth.h | 8 | ||||
-rw-r--r-- | common.c | 190 | ||||
-rwxr-xr-x | configure | 338 | ||||
-rw-r--r-- | configure.in | 23 | ||||
-rw-r--r-- | control.h | 11 | ||||
-rw-r--r-- | dhcp6.h | 22 | ||||
-rw-r--r-- | dhcp6c.c | 2 | ||||
-rw-r--r-- | dhcp6relay.c | 4 | ||||
-rw-r--r-- | dhcp6s.c | 4 | ||||
-rw-r--r-- | missing/arc4random.h | 5 | ||||
-rw-r--r-- | missing/daemon.c | 50 | ||||
-rw-r--r-- | missing/err.h | 34 | ||||
-rw-r--r-- | missing/getifaddrs.c | 217 | ||||
-rw-r--r-- | missing/ifaddrs.h | 44 | ||||
-rw-r--r-- | missing/sys/queue.h | 137 | ||||
-rw-r--r-- | missing/warnx.c | 59 |
18 files changed, 1130 insertions, 37 deletions
@@ -1,3 +1,9 @@ +2007-02-27 SUZUKI, Shinsuke <suz@kame.net> + * Makefile.in, configure.in, configure, auth.h, common.c, control.h, dhcp6.h, + dhcp6s.c, missing/{arc4random.h, daemon.c, err.h, getifaddrs.c, ifaddrs.h, + sys/queue.h, warnx.c} + supported compilation on Solaris (contributed by James Carlson) + 2007-02-12 SUZUKI, Shinsuke <suz@kame.net> * cftoken.l: accepts interface names, such as eth0.100(Linux VLAN interface) or foobar (named by "ifconfig name" command). (Bug-ID 1644637) diff --git a/Makefile.in b/Makefile.in index 4398b31..3e6f606 100644 --- a/Makefile.in +++ b/Makefile.in @@ -25,7 +25,7 @@ # SUCH DAMAGE. # -# $Id: Makefile.in,v 1.14 2007-02-12 08:32:36 suzsuz Exp $ +# $Id: Makefile.in,v 1.15 2007-02-27 14:21:40 suzsuz Exp $ # $KAME: Makefile.in,v 1.45 2005/10/16 16:25:38 suz Exp $ # @@ -90,6 +90,12 @@ strlcat.o: $(srcdir)/missing/strlcat.c strlcpy.o: $(srcdir)/missing/strlcpy.c $(CC) -c $(srcdir)/missing/$*.c arc4random.o: $(srcdir)/missing/arc4random.c + $(CC) $(CFLAGS) -c $(srcdir)/missing/$*.c +getifaddrs.o: $(srcdir)/missing/getifaddrs.c + $(CC) -c $(srcdir)/missing/$*.c +daemon.o: $(srcdir)/missing/daemon.c + $(CC) -c $(srcdir)/missing/$*.c +warnx.o: $(srcdir)/missing/warnx.c $(CC) -c $(srcdir)/missing/$*.c $(srcdir)/ianaopts.h: gentab.pl bootp-dhcp-parameters @@ -122,4 +128,7 @@ package: $(srcdir)/configure $(srcdir)/configure.in \ $(srcdir)/install-sh $(srcdir)/*.sample \ $(srcdir)/missing/arc4random.? $(srcdir)/missing/strlcat.c \ - $(srcdir)/missing/strlcpy.c + $(srcdir)/missing/strlcpy.c $(srcdir)/missing/daemon.c \ + $(srcdir)/missing/err.h $(srcdir)/missing/warnx.c \ + $(srcdir)/missing/ifaddrs.h $(srcdir)/missing/getifaddrs.c \ + $(srcdir)/missing/sys/queue.h @@ -29,6 +29,14 @@ * SUCH DAMAGE. */ +#ifdef __sun__ +#define __P(x) x +#ifndef U_INT32_T_DEFINED +#define U_INT32_T_DEFINED +typedef uint32_t u_int32_t; +#endif +#endif + #define MD5_DIGESTLENGTH 16 /* secret key information for delayed authentication */ @@ -55,6 +55,13 @@ #include <linux/if_packet.h> #endif #include <net/if_arp.h> +#ifdef __sun__ +#include <sys/sockio.h> +#include <sys/dlpi.h> +#include <stropts.h> +#include <fcntl.h> +#include <libdevinfo.h> +#endif #ifdef __KAME__ #include <netinet6/in6_var.h> @@ -71,13 +78,7 @@ #include <string.h> #include <err.h> #include <netdb.h> - -#ifdef HAVE_GETIFADDRS -# ifdef HAVE_IFADDRS_H -# define USE_GETIFADDRS -# include <ifaddrs.h> -# endif -#endif +#include <ifaddrs.h> #include <dhcp6.h> #include <config.h> @@ -1081,6 +1082,137 @@ get_duid(idfile, duid) return (-1); } +#ifdef __sun__ +struct hwparms { + char *buf; + u_int16_t *hwtypep; + ssize_t retval; +}; + +static ssize_t +getifhwaddr(const char *ifname, char *buf, u_int16_t *hwtypep, int ppa) +{ + int fd, flags; + char fname[MAXPATHLEN], *cp; + struct strbuf putctl; + struct strbuf getctl; + long getbuf[1024]; + dl_info_req_t dlir; + dl_phys_addr_req_t dlpar; + dl_phys_addr_ack_t *dlpaa; + + dprintf(LOG_DEBUG, FNAME, "trying %s ppa %d", ifname, ppa); + + if (ifname[0] == '\0') + return (-1); + if (ppa >= 0 && !isdigit(ifname[strlen(ifname) - 1])) + (void) snprintf(fname, sizeof (fname), "/dev/%s%d", ifname, + ppa); + else + (void) snprintf(fname, sizeof (fname), "/dev/%s", ifname); + getctl.maxlen = sizeof (getbuf); + getctl.buf = (char *)getbuf; + if ((fd = open(fname, O_RDWR)) == -1) { + dl_attach_req_t dlar; + + cp = fname + strlen(fname) - 1; + if (!isdigit(*cp)) + return (-1); + while (cp > fname) { + if (!isdigit(*cp)) + break; + cp--; + } + if (cp == fname) + return (-1); + cp++; + dlar.dl_ppa = atoi(cp); + *cp = '\0'; + if ((fd = open(fname, O_RDWR)) == -1) + return (-1); + dlar.dl_primitive = DL_ATTACH_REQ; + putctl.len = sizeof (dlar); + putctl.buf = (char *)&dlar; + if (putmsg(fd, &putctl, NULL, 0) == -1) { + (void) close(fd); + return (-1); + } + flags = 0; + if (getmsg(fd, &getctl, NULL, &flags) == -1) { + (void) close(fd); + return (-1); + } + if (getbuf[0] != DL_OK_ACK) { + (void) close(fd); + return (-1); + } + } + dlir.dl_primitive = DL_INFO_REQ; + putctl.len = sizeof (dlir); + putctl.buf = (char *)&dlir; + if (putmsg(fd, &putctl, NULL, 0) == -1) { + (void) close(fd); + return (-1); + } + flags = 0; + if (getmsg(fd, &getctl, NULL, &flags) == -1) { + (void) close(fd); + return (-1); + } + if (getbuf[0] != DL_INFO_ACK) { + (void) close(fd); + return (-1); + } + switch (((dl_info_ack_t *)getbuf)->dl_mac_type) { + case DL_CSMACD: + case DL_ETHER: + case DL_100VG: + case DL_ETH_CSMA: + case DL_100BT: + *hwtypep = ARPHRD_ETHER; + break; + default: + (void) close(fd); + return (-1); + } + dlpar.dl_primitive = DL_PHYS_ADDR_REQ; + dlpar.dl_addr_type = DL_CURR_PHYS_ADDR; + putctl.len = sizeof (dlpar); + putctl.buf = (char *)&dlpar; + if (putmsg(fd, &putctl, NULL, 0) == -1) { + (void) close(fd); + return (-1); + } + flags = 0; + if (getmsg(fd, &getctl, NULL, &flags) == -1) { + (void) close(fd); + return (-1); + } + if (getbuf[0] != DL_PHYS_ADDR_ACK) { + (void) close(fd); + return (-1); + } + dlpaa = (dl_phys_addr_ack_t *)getbuf; + if (dlpaa->dl_addr_length != 6) { + (void) close(fd); + return (-1); + } + (void) memcpy(buf, (char *)getbuf + dlpaa->dl_addr_offset, + dlpaa->dl_addr_length); + return (dlpaa->dl_addr_length); +} + +static int +devfs_handler(di_node_t node, di_minor_t minor, void *arg) +{ + struct hwparms *parms = arg; + + parms->retval = getifhwaddr(di_minor_name(minor), parms->buf, + parms->hwtypep, di_instance(node)); + return (parms->retval == -1 ? DI_WALK_CONTINUE : DI_WALK_TERMINATE); +} +#endif + static ssize_t gethwid(buf, len, ifname, hwtypep) char *buf; @@ -1097,6 +1229,28 @@ gethwid(buf, len, ifname, hwtypep) #endif ssize_t l; +#ifdef __sun__ + if (ifname == NULL) { + di_node_t root; + struct hwparms parms; + + if ((root = di_init("/", DINFOSUBTREE | DINFOMINOR | + DINFOPROP)) == DI_NODE_NIL) { + dprintf(LOG_INFO, FNAME, "di_init failed"); + return (-1); + } + parms.buf = buf; + parms.hwtypep = hwtypep; + parms.retval = -1; + (void) di_walk_minor(root, DDI_NT_NET, DI_CHECK_ALIAS, &parms, + devfs_handler); + di_fini(root); + return (parms.retval); + } else { + return (getifhwaddr(ifname, buf, hwtypep, -1)); + } +#endif + if (getifaddrs(&ifap) < 0) return (-1); @@ -3094,6 +3248,9 @@ ifaddrconf(cmd, ifname, addr, plen, pltime, vltime) struct in6_ifreq req; struct ifreq ifr; #endif +#ifdef __sun__ + struct lifreq req; +#endif unsigned long ioctl_cmd; char *cmdstr; int s; /* XXX overhead */ @@ -3107,6 +3264,9 @@ ifaddrconf(cmd, ifname, addr, plen, pltime, vltime) #ifdef __linux__ ioctl_cmd = SIOCSIFADDR; #endif +#ifdef __sun__ + ioctl_cmd = SIOCLIFADDIF; +#endif break; case IFADDRCONF_REMOVE: cmdstr = "remove"; @@ -3116,6 +3276,9 @@ ifaddrconf(cmd, ifname, addr, plen, pltime, vltime) #ifdef __linux__ ioctl_cmd = SIOCDIFADDR; #endif +#ifdef __sun__ + ioctl_cmd = SIOCLIFREMOVEIF; +#endif break; default: return (-1); @@ -3149,6 +3312,9 @@ ifaddrconf(cmd, ifname, addr, plen, pltime, vltime) req.ifr6_prefixlen = plen; req.ifr6_ifindex = ifr.ifr_ifindex; #endif +#ifdef __sun__ + strncpy(req.lifr_name, ifname, sizeof (req.lifr_name)); +#endif if (ioctl(s, ioctl_cmd, &req)) { dprintf(LOG_NOTICE, FNAME, "failed to %s an address on %s: %s", @@ -3157,6 +3323,16 @@ ifaddrconf(cmd, ifname, addr, plen, pltime, vltime) return (-1); } +#ifdef __sun__ + memcpy(&req.lifr_addr, addr, sizeof (*addr)); + if (ioctl(s, SIOCSLIFADDR, &req) == -1) { + dprintf(LOG_NOTICE, FNAME, "failed to %s new address on %s: %s", + cmdstr, ifname, strerror(errno)); + close(s); + return (-1); + } +#endif + dprintf(LOG_DEBUG, FNAME, "%s an address %s/%d on %s", cmdstr, addr2str((struct sockaddr *)addr), plen, ifname); @@ -2915,8 +2915,62 @@ fi CFLAGS="$CFLAGS -I\$(srcdir)" -echo "$as_me:$LINENO: checking for getaddrinfo/getnameinfo library" >&5 -echo $ECHO_N "checking for getaddrinfo/getnameinfo library... $ECHO_C" >&6 +if test -x /usr/bin/sun && /usr/bin/sun; then + CFLAGS="$CFLAGS -D_XOPEN_SOURCE=500 -D__EXTENSIONS__" + LDFLAGS="-lxnet -ldevinfo -lnsl -lsocket -lrt" +fi + +echo "$as_me:$LINENO: checking for sys/queue.h" >&5 +echo $ECHO_N "checking for sys/queue.h... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/queue.h> +int +main () +{ +TAILQ_HEAD(test, none); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + CFLAGS="$CFLAGS -I\$(srcdir)/missing" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 @@ -2947,9 +3001,13 @@ _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then result=kame +else + result=regular fi rm -f conftest* +echo "$as_me:$LINENO: checking for getaddrinfo/getnameinfo library" >&5 +echo $ECHO_N "checking for getaddrinfo/getnameinfo library... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $result" >&5 echo "${ECHO_T}$result" >&6 case $result in @@ -3263,9 +3321,13 @@ fi done -echo "$as_me:$LINENO: checking for getifaddrs" >&5 -echo $ECHO_N "checking for getifaddrs... $ECHO_C" >&6 -if test "${ac_cv_func_getifaddrs+set}" = set; then + +for ac_func in getifaddrs +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF @@ -3274,12 +3336,12 @@ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -/* Define getifaddrs to an innocuous variant, in case <limits.h> declares getifaddrs. +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define getifaddrs innocuous_getifaddrs +#define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, - which can conflict with char getifaddrs (); below. + which can conflict with char $ac_func (); below. Prefer <limits.h> to <assert.h> if __STDC__ is defined, since <limits.h> exists even on freestanding compilers. */ @@ -3289,7 +3351,7 @@ cat >>conftest.$ac_ext <<_ACEOF # include <assert.h> #endif -#undef getifaddrs +#undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus @@ -3298,14 +3360,14 @@ extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char getifaddrs (); +char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_getifaddrs) || defined (__stub___getifaddrs) +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else -char (*f) () = getifaddrs; +char (*f) () = $ac_func; #endif #ifdef __cplusplus } @@ -3314,7 +3376,7 @@ char (*f) () = getifaddrs; int main () { -return f != getifaddrs; +return f != $ac_func; ; return 0; } @@ -3341,27 +3403,35 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then - ac_cv_func_getifaddrs=yes + eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_func_getifaddrs=no +eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_func_getifaddrs" >&5 -echo "${ECHO_T}$ac_cv_func_getifaddrs" >&6 -if test $ac_cv_func_getifaddrs = yes; then - cat >>confdefs.h <<\_ACEOF -#define HAVE_GETIFADDRS 1 +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else - echo FATAL: getifaddrs is required - exit 1 + case $LIBOBJS in + "$ac_func.$ac_objext" | \ + *" $ac_func.$ac_objext" | \ + "$ac_func.$ac_objext "* | \ + *" $ac_func.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;; +esac + fi +done + for ac_func in if_nametoindex @@ -3579,6 +3649,230 @@ done +for ac_func in daemon +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + case $LIBOBJS in + "$ac_func.$ac_objext" | \ + *" $ac_func.$ac_objext" | \ + "$ac_func.$ac_objext "* | \ + *" $ac_func.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;; +esac + +fi +done + + + +for ac_func in warnx +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + case $LIBOBJS in + "$ac_func.$ac_objext" | \ + *" $ac_func.$ac_objext" | \ + "$ac_func.$ac_objext "* | \ + *" $ac_func.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;; +esac + +fi +done + + + echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then diff --git a/configure.in b/configure.in index 825dade..461949a 100644 --- a/configure.in +++ b/configure.in @@ -50,12 +50,25 @@ dnl exit 1]) CFLAGS="$CFLAGS -I\$(srcdir)" -AC_MSG_CHECKING(for getaddrinfo/getnameinfo library) +dnl On Sun systems, we need to use the standards-compliant 3XNET functions +if test -x /usr/bin/sun && /usr/bin/sun; then + CFLAGS="$CFLAGS -D_XOPEN_SOURCE=500 -D__EXTENSIONS__" + LDFLAGS="-lxnet -ldevinfo -lnsl -lsocket -lrt" +fi + +AC_MSG_CHECKING(for sys/queue.h) +AC_TRY_COMPILE([#include <sys/queue.h>], + [TAILQ_HEAD(test, none);], + [AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no) + CFLAGS="$CFLAGS -I\$(srcdir)/missing"]) + AC_EGREP_CPP(yes, [#include <netinet/in.h> #ifdef __KAME__ yes -#endif], [result=kame]) +#endif], [result=kame], [result=regular]) +AC_MSG_CHECKING(for getaddrinfo/getnameinfo library) AC_MSG_RESULT($result) case $result in kame) AC_DEFINE(INET6) @@ -68,11 +81,11 @@ esac AC_REPLACE_FUNCS(getaddrinfo) AC_REPLACE_FUNCS(getnameinfo) -AC_CHECK_FUNC(getifaddrs, AC_DEFINE(HAVE_GETIFADDRS), [dnl - echo FATAL: getifaddrs is required - exit 1]) +AC_REPLACE_FUNCS(getifaddrs) AC_CHECK_FUNCS(if_nametoindex) AC_REPLACE_FUNCS(strlcpy strlcat) +AC_REPLACE_FUNCS(daemon) +AC_REPLACE_FUNCS(warnx) dnl Checks for header files. AC_HEADER_STDC @@ -29,6 +29,17 @@ * SUCH DAMAGE. */ +#ifdef __sun__ +#ifndef U_INT16_T_DEFINED +#define U_INT16_T_DEFINED +typedef uint16_t u_int16_t; +#endif +#ifndef U_INT32_T_DEFINED +#define U_INT32_T_DEFINED +typedef uint32_t u_int32_t; +#endif +#endif + #define DEFAULT_SERVER_CONTROL_ADDR "::1" /* default IPv6 address for server * control socket */ #define DEFAULT_SERVER_CONTROL_PORT "5547" /* default TCP port for server @@ -31,6 +31,28 @@ #ifndef __DHCP6_H_DEFINED #define __DHCP6_H_DEFINED +#ifdef __sun__ +#define __P(x) x +typedef uint8_t u_int8_t; +#ifndef U_INT16_T_DEFINED +#define U_INT16_T_DEFINED +typedef uint16_t u_int16_t; +#endif +#ifndef U_INT32_T_DEFINED +#define U_INT32_T_DEFINED +typedef uint32_t u_int32_t; +#endif +typedef uint64_t u_int64_t; +#ifndef CMSG_SPACE +#define CMSG_SPACE(l) \ + ((unsigned int)_CMSG_HDR_ALIGN(sizeof (struct cmsghdr) + (l))) +#endif +#ifndef CMSG_LEN +#define CMSG_LEN(l) \ + ((unsigned int)_CMSG_DATA_ALIGN(sizeof (struct cmsghdr)) + (l)) +#endif +#endif + /* Error Values */ #define DH6ERR_FAILURE 16 #define DH6ERR_AUTHFAIL 17 @@ -317,12 +317,14 @@ client6_init() strerror(errno)); exit(1); } +#ifdef IPV6_V6ONLY if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { dprintf(LOG_ERR, FNAME, "setsockopt(IPV6_V6ONLY): %s", strerror(errno)); exit(1); } +#endif /* * According RFC3315 2.2, only the incoming port should be bound to UDP diff --git a/dhcp6relay.c b/dhcp6relay.c index e05a47c..78d18df 100644 --- a/dhcp6relay.c +++ b/dhcp6relay.c @@ -360,12 +360,14 @@ relay6_init(int ifnum, char *iflist[]) strerror(errno)); goto failexit; } +#ifdef IPV6_V6ONLY if (setsockopt(csock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) < 0) { dprintf(LOG_ERR, FNAME, "setsockopt(csock, IPV6_V6ONLY): %s", strerror(errno)); goto failexit; } +#endif if (bind(csock, res->ai_addr, res->ai_addrlen) < 0) { dprintf(LOG_ERR, FNAME, "bind(csock): %s", strerror(errno)); goto failexit; @@ -470,12 +472,14 @@ relay6_init(int ifnum, char *iflist[]) goto failexit; } on = 1; +#ifdef IPV6_V6ONLY if (setsockopt(ssock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) < 0) { dprintf(LOG_ERR, FNAME, "setsockopt(ssock, IPV6_V6ONLY): %s", strerror(errno)); goto failexit; } +#endif if (bind(ssock, res->ai_addr, res->ai_addrlen) < 0) { dprintf(LOG_ERR, FNAME, "bind(ssock): %s", strerror(errno)); goto failexit; @@ -441,12 +441,14 @@ server6_init() exit(1); } #endif +#ifdef IPV6_V6ONLY if (setsockopt(insock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { dprintf(LOG_ERR, FNAME, "setsockopt(inbound, IPV6_V6ONLY): %s", strerror(errno)); exit(1); } +#endif if (bind(insock, res->ai_addr, res->ai_addrlen) < 0) { dprintf(LOG_ERR, FNAME, "bind(insock): %s", strerror(errno)); exit(1); @@ -517,7 +519,7 @@ server6_init() strerror(errno)); exit(1); } -#ifndef __linux__ +#if !defined(__linux__) && !defined(__sun__) /* make the socket write-only */ if (shutdown(outsock, 0)) { dprintf(LOG_ERR, FNAME, "shutdown(outbound, 0): %s", diff --git a/missing/arc4random.h b/missing/arc4random.h index 7487efa..074c100 100644 --- a/missing/arc4random.h +++ b/missing/arc4random.h @@ -29,4 +29,9 @@ * SUCH DAMAGE. */ +#ifdef __sun__ +#define __P(x) x +typedef uint32_t u_int32_t; +#endif + extern u_int32_t arc4random __P((void)); diff --git a/missing/daemon.c b/missing/daemon.c new file mode 100644 index 0000000..9bf6416 --- /dev/null +++ b/missing/daemon.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2006 WIDE Project. All rights reserved. + * + * 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. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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 <sys/types.h> +#include <unistd.h> +#include <fcntl.h> + +int +daemon(int nochdir, int noclose) +{ + if (fork() != 0) + _exit(0); + if (nochdir == 0) + (void) chdir("/"); + if (noclose == 0) { + (void) close(0); + (void) open("/dev/null", O_RDWR); + (void) dup2(0, 1); + (void) dup2(0, 2); + } + (void) setsid(); + if (fork() != 0) + _exit(0); + return (0); +} diff --git a/missing/err.h b/missing/err.h new file mode 100644 index 0000000..dfc41d5 --- /dev/null +++ b/missing/err.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2006 WIDE Project. All rights reserved. + * + * 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. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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. + */ + +extern void err(int, const char *); +/* PRINTFLIKE2 */ +extern void errx(int, const char *, ...); +/* PRINTFLIKE1 */ +extern void warnx(const char *, ...); +#define warn warnx diff --git a/missing/getifaddrs.c b/missing/getifaddrs.c new file mode 100644 index 0000000..4320c43 --- /dev/null +++ b/missing/getifaddrs.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2006 WIDE Project. All rights reserved. + * + * 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. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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 <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <sys/sockio.h> +#include <sys/socket.h> +#include <net/if.h> + +#include "ifaddrs.h" + +static int +get_lifreq(int fd, struct lifreq **ifr_ret) +{ + struct lifnum lifn; + struct lifconf lifc; + struct lifreq *lifrp; + + lifn.lifn_family = AF_UNSPEC; + lifn.lifn_flags = 0; + if (ioctl(fd, SIOCGLIFNUM, &lifn) == -1) + lifn.lifn_count = 16; + else + lifn.lifn_count += 16; + + for (;;) { + lifc.lifc_len = lifn.lifn_count * sizeof (*lifrp); + lifrp = malloc(lifc.lifc_len); + if (lifrp == NULL) + return (-1); + + lifc.lifc_family = AF_UNSPEC; + lifc.lifc_flags = 0; + lifc.lifc_buf = (char *)lifrp; + if (ioctl(fd, SIOCGLIFCONF, &lifc) == -1) { + free(lifrp); + if (errno == EINVAL) { + lifn.lifn_count <<= 1; + continue; + } + (void) close(fd); + return (-1); + } + if (lifc.lifc_len < (lifn.lifn_count - 1) * sizeof (*lifrp)) + break; + free(lifrp); + lifn.lifn_count <<= 1; + } + (void) close(fd); + + *ifr_ret = lifrp; + + return (lifc.lifc_len / sizeof (*lifrp)); +} + +static size_t +nbytes(const struct lifreq *lifrp, int nlif, size_t socklen) +{ + size_t len = 0; + size_t slen; + + while (nlif > 0) { + slen = strlen(lifrp->lifr_name) + 1; + len += sizeof (struct ifaddrs) + ((slen + 3) & ~3); + len += 3 * socklen; + lifrp++; + nlif--; + } + return (len); +} + +static struct sockaddr * +addrcpy(struct sockaddr_storage *addr, char **bufp) +{ + char *buf = *bufp; + size_t len; + + len = addr->ss_family == AF_INET ? sizeof (struct sockaddr_in) : + sizeof (struct sockaddr_in6); + (void) memcpy(buf, addr, len); + *bufp = buf + len; + return ((struct sockaddr *)buf); +} + +static int +populate(struct ifaddrs *ifa, int fd, struct lifreq *lifrp, int nlif, int af, + char **bufp) +{ + char *buf = *bufp; + size_t slen; + + while (nlif > 0) { + ifa->ifa_next = (nlif > 1) ? ifa + 1 : NULL; + (void) strcpy(ifa->ifa_name = buf, lifrp->lifr_name); + slen = strlen(lifrp->lifr_name) + 1; + buf += (slen + 3) & ~3; + if (ioctl(fd, SIOCGLIFFLAGS, lifrp) == -1) + ifa->ifa_flags = 0; + else + ifa->ifa_flags = lifrp->lifr_flags; + if (ioctl(fd, SIOCGLIFADDR, lifrp) == -1) + ifa->ifa_addr = NULL; + else + ifa->ifa_addr = addrcpy(&lifrp->lifr_addr, &buf); + if (ioctl(fd, SIOCGLIFNETMASK, lifrp) == -1) + ifa->ifa_netmask = NULL; + else + ifa->ifa_netmask = addrcpy(&lifrp->lifr_addr, &buf); + if (ifa->ifa_flags & IFF_POINTOPOINT) { + if (ioctl(fd, SIOCGLIFDSTADDR, lifrp) == -1) + ifa->ifa_dstaddr = NULL; + else + ifa->ifa_dstaddr = + addrcpy(&lifrp->lifr_dstaddr, &buf); + } else if (ifa->ifa_flags & IFF_BROADCAST) { + if (ioctl(fd, SIOCGLIFBRDADDR, lifrp) == -1) + ifa->ifa_broadaddr = NULL; + else + ifa->ifa_broadaddr = + addrcpy(&lifrp->lifr_broadaddr, &buf); + } else { + ifa->ifa_dstaddr = NULL; + } + + ifa++; + nlif--; + lifrp++; + } + *bufp = buf; + return (0); +} + +int +getifaddrs(struct ifaddrs **ifap) +{ + int fd4, fd6; + int nif4, nif6 = 0; + struct lifreq *ifr4 = NULL; + struct lifreq *ifr6 = NULL; + struct ifaddrs *ifa = NULL; + char *buf; + + if ((fd4 = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + return (-1); + if ((fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) == -1 && + errno != EAFNOSUPPORT) { + (void) close(fd4); + return (-1); + } + + if ((nif4 = get_lifreq(fd4, &ifr4)) == -1 || + (fd6 != -1 && (nif6 = get_lifreq(fd6, &ifr6)) == -1)) + goto failure; + + if (nif4 == 0 && nif6 == 0) { + *ifap = NULL; + return (0); + } + + ifa = malloc(nbytes(ifr4, nif4, sizeof (struct sockaddr_in)) + + nbytes(ifr6, nif6, sizeof (struct sockaddr_in6))); + if (ifa == NULL) + goto failure; + + buf = (char *)(ifa + nif4 + nif6); + + if (populate(ifa, fd4, ifr4, nif4, AF_INET, &buf) == -1) + goto failure; + if (nif4 > 0 && nif6 > 0) + ifa[nif4 - 1].ifa_next = ifa + nif4; + if (populate(ifa + nif4, fd6, ifr6, nif6, AF_INET6, &buf) == -1) + goto failure; + + return (0); + +failure: + free(ifa); + (void) close(fd4); + if (fd6 != -1) + (void) close(fd6); + free(ifr4); + free(ifr6); + return (-1); +} + +void +freeifaddrs(struct ifaddrs *ifa) +{ + free(ifa); +} diff --git a/missing/ifaddrs.h b/missing/ifaddrs.h new file mode 100644 index 0000000..0bf5f92 --- /dev/null +++ b/missing/ifaddrs.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2006 WIDE Project. All rights reserved. + * + * 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. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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 <sys/types.h> + +#undef ifa_broadaddr +#undef ifa_dstaddr +struct ifaddrs { + struct ifaddrs *ifa_next; /* Pointer to next struct */ + char *ifa_name; /* Interface name */ + uint64_t ifa_flags; /* Interface flags */ + struct sockaddr *ifa_addr; /* Interface address */ + struct sockaddr *ifa_netmask; /* Interface netmask */ + struct sockaddr *ifa_dstaddr; /* P2P interface destination */ +}; +#define ifa_broadaddr ifa_dstaddr + +extern int getifaddrs(struct ifaddrs **); +extern void freeifaddrs(struct ifaddrs *); diff --git a/missing/sys/queue.h b/missing/sys/queue.h new file mode 100644 index 0000000..027f495 --- /dev/null +++ b/missing/sys/queue.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * + * Adapted from FreeBSD sys/queue.h by James Carlson <james.d.carlson@sun.com> + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.6 2001/12/18 10:09:02 ru Exp $ + */ + +/* + * Tail queue declarations. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * Tail queue functions. + */ +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_INIT(head) do { \ + TAILQ_FIRST((head)) = NULL; \ + (head)->tqh_last = &TAILQ_FIRST((head)); \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ + TAILQ_FIRST((head))->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + TAILQ_FIRST((head)) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + TAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ +} while (0) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field)) != NULL) \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ +} while (0) + +/* + * List declarations. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_INIT(head) do { \ + LIST_FIRST((head)) = NULL; \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ + LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &LIST_FIRST((head)); \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL) \ + LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ +} while (0) diff --git a/missing/warnx.c b/missing/warnx.c new file mode 100644 index 0000000..75e1a96 --- /dev/null +++ b/missing/warnx.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2006 WIDE Project. All rights reserved. + * + * 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. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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 <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +void +err(int retv, const char *str) +{ + (void) fprintf(stderr, "%s\n", str); + exit(retv); +} + +void +errx(int retv, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + (void) vfprintf(stderr, fmt, args); + va_end(args); + exit(retv); +} + +void +warnx(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + (void) vfprintf(stderr, fmt, args); + va_end(args); +} |