summaryrefslogtreecommitdiffstats
path: root/contrib/tcp_wrappers
diff options
context:
space:
mode:
authorshin <shin@FreeBSD.org>2000-02-03 10:27:03 +0000
committershin <shin@FreeBSD.org>2000-02-03 10:27:03 +0000
commit225d233deb08e4006d8cabd0a6572f76d729f90d (patch)
tree5e244ba219acd7cbeb17a0c5dc92b62227ab2828 /contrib/tcp_wrappers
parent22aa8f5f0343020efcf93d4ebc043c5f558995d5 (diff)
downloadFreeBSD-src-225d233deb08e4006d8cabd0a6572f76d729f90d.zip
FreeBSD-src-225d233deb08e4006d8cabd0a6572f76d729f90d.tar.gz
Missing tcp_wrapper IPv6 support seemed to be a bug, so commit it.
Now when tcp_wrapper is enabled by inetd -wW, several accesses which should be permitted are refused only for IPv6, if hostname is used to decide the host to be allowed. IPv6 users will be just upset. About security related concern. -All extensions are wrapped by #ifdef INET6, so people can completely disable the extension by recompile libwrap without INET6 option. -Access via IPv6 is not enabled by default. People need to enable IPv6 access by changing /etc/inetd.conf at first, by adding tcp6 and/or tcp46 entries. -The base of patches are from KAME package and are actually daily used for more than a year in several Japanese IPv6 environments. -Patches are reviewed by markm. Approved by: jkh Submitted by: Hajimu UMEMOTO <ume@mahoroba.org> Reviewed by: markm Obtained from: KAME project
Diffstat (limited to 'contrib/tcp_wrappers')
-rw-r--r--contrib/tcp_wrappers/Makefile41
-rw-r--r--contrib/tcp_wrappers/fix_options.c21
-rw-r--r--contrib/tcp_wrappers/hosts_access.57
-rw-r--r--contrib/tcp_wrappers/hosts_access.c105
-rw-r--r--contrib/tcp_wrappers/misc.c24
-rw-r--r--contrib/tcp_wrappers/refuse.c7
-rw-r--r--contrib/tcp_wrappers/rfc931.c66
-rw-r--r--contrib/tcp_wrappers/scaffold.c155
-rw-r--r--contrib/tcp_wrappers/socket.c149
-rw-r--r--contrib/tcp_wrappers/tcpd.c7
-rw-r--r--contrib/tcp_wrappers/tcpd.h6
-rw-r--r--contrib/tcp_wrappers/tcpdchk.c36
-rw-r--r--contrib/tcp_wrappers/tcpdmatch.c55
-rw-r--r--contrib/tcp_wrappers/tli.c37
-rw-r--r--contrib/tcp_wrappers/update.c10
-rw-r--r--contrib/tcp_wrappers/workarounds.c13
16 files changed, 727 insertions, 12 deletions
diff --git a/contrib/tcp_wrappers/Makefile b/contrib/tcp_wrappers/Makefile
index 2906c52..10ede81 100644
--- a/contrib/tcp_wrappers/Makefile
+++ b/contrib/tcp_wrappers/Makefile
@@ -1,4 +1,5 @@
# @(#) Makefile 1.23 97/03/21 19:27:20
+# $FreeBSD$
what:
@echo
@@ -21,7 +22,7 @@ what:
@echo " dynix epix esix freebsd hpux irix4 irix5 irix6 isc iunix"
@echo " linux machten mips(untested) ncrsvr4 netbsd next osf power_unix_211"
@echo " ptx-2.x ptx-generic pyramid sco sco-nis sco-od2 sco-os5 sinix sunos4"
- @echo " sunos40 sunos5 sysv4 tandem ultrix unicos7 unicos8 unixware1 unixware2"
+ @echo " sunos40 sunos5 solaris8 sysv4 tandem ultrix unicos7 unicos8 unixware1 unixware2"
@echo " uts215 uxp"
@echo
@echo "If none of these match your environment, edit the system"
@@ -131,20 +132,34 @@ epix:
NETGROUP=-DNETGROUP TLI= SYSTYPE="-systype bsd43" all
# Freebsd and linux by default have no NIS.
-386bsd netbsd bsdos:
+386bsd bsdos:
@make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \
LIBS= RANLIB=ranlib ARFLAGS=rv AUX_OBJ= NETGROUP= TLI= \
EXTRA_CFLAGS=-DSYS_ERRLIST_DEFINED VSYSLOG= all
freebsd:
@make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \
+ RANLIB=ranlib ARFLAGS=rv AUX_OBJ= NETGROUP=-DNETGROUP TLI= \
+ EXTRA_CFLAGS="-DSYS_ERRLIST_DEFINED -DINET6 -DUSE_GETIPNODEBY" \
+ VSYSLOG= all
+
+netbsd:
+ @make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \
LIBS= RANLIB=ranlib ARFLAGS=rv AUX_OBJ= NETGROUP= TLI= \
- EXTRA_CFLAGS=-DSYS_ERRLIST_DEFINED VSYSLOG= all
+ EXTRA_CFLAGS="-DSYS_ERRLIST_DEFINED -DINET6 \
+ -Dss_family=__ss_family -Dss_len=__ss_len" VSYSLOG= all
linux:
@make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \
- LIBS= RANLIB=ranlib ARFLAGS=rv AUX_OBJ=setenv.o \
- NETGROUP= TLI= EXTRA_CFLAGS="-DBROKEN_SO_LINGER" all
+ LIBS= RANLIB=ranlib ARFLAGS=rv AUX_OBJ=setenv.o NETGROUP= TLI= \
+ EXTRA_CFLAGS="-DSYS_ERRLIST_DEFINED -DBROKEN_SO_LINGER -DINET6=1 \
+ -Dss_family=__ss_family -Dss_len=__ss_len" all
+
+linux-old:
+ @make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \
+ LIBS="/usr/inet6/lib/libinet6.a -lresolv" \
+ RANLIB=ranlib ARFLAGS=rv AUX_OBJ=setenv.o NETGROUP= TLI= \
+ EXTRA_CFLAGS="-DSYS_ERRLIST_DEFINED -DBROKEN_SO_LINGER -DINET6=1 -Dss_family=sin6_family -Dsockaddr_storage=sockaddr_in6 -I/usr/inet6/include" all
# This is good for many SYSV+BSD hybrids with NIS, probably also for HP-UX 7.x.
hpux hpux8 hpux9 hpux10:
@@ -196,6 +211,14 @@ sunos5:
NETGROUP=-DNETGROUP AUX_OBJ=setenv.o TLI=-DTLI \
BUGS="$(BUGS) -DSOLARIS_24_GETHOSTBYNAME_BUG" all
+# SunOS 5.8 is another SYSV4 variant, but has IPv6 support
+solaris8:
+ @make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \
+ LIBS="-lsocket -lnsl" RANLIB=echo ARFLAGS=rv VSYSLOG= \
+ NETGROUP=-DNETGROUP AUX_OBJ=setenv.o TLI=-DTLI \
+ EXTRA_CFLAGS="-DINET6 -DUSE_GETIPNODEBY -DNO_CLONE_DEVICE \
+ -DINT32_T" all
+
# Generic SYSV40
esix sysv4:
@make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \
@@ -229,7 +252,7 @@ tandem:
# Amdahl UTS 2.1.5 (Richard.Richmond@bridge.bst.bls.com)
uts215:
- @make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \
+ @make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \
LIBS="-lsocket" RANLIB=echo \
ARFLAGS=rv AUX_OBJ=setenv.o NETGROUP=-DNO_NETGROUP TLI= all
@@ -391,7 +414,7 @@ AR = ar
# the ones provided with this source distribution. The environ.c module
# implements setenv(), getenv(), and putenv().
-AUX_OBJ= setenv.o
+#AUX_OBJ= setenv.o
#AUX_OBJ= environ.o
#AUX_OBJ= environ.o strcasecmp.o
@@ -454,7 +477,7 @@ AUX_OBJ= setenv.o
# host name aliases. Compile with -DSOLARIS_24_GETHOSTBYNAME_BUG to work
# around this. The workaround does no harm on other Solaris versions.
-BUGS = -DGETPEERNAME_BUG -DBROKEN_FGETS -DLIBC_CALLS_STRTOK
+#BUGS = -DGETPEERNAME_BUG -DBROKEN_FGETS -DLIBC_CALLS_STRTOK
#BUGS = -DGETPEERNAME_BUG -DBROKEN_FGETS -DINET_ADDR_BUG
#BUGS = -DGETPEERNAME_BUG -DBROKEN_FGETS -DSOLARIS_24_GETHOSTBYNAME_BUG
@@ -472,7 +495,7 @@ BUGS = -DGETPEERNAME_BUG -DBROKEN_FGETS -DLIBC_CALLS_STRTOK
# If your system supports vsyslog(), comment out the following definition.
# If in doubt leave it in, it won't harm.
-VSYSLOG = -Dvsyslog=myvsyslog
+#VSYSLOG = -Dvsyslog=myvsyslog
# End of the system dependencies.
#################################
diff --git a/contrib/tcp_wrappers/fix_options.c b/contrib/tcp_wrappers/fix_options.c
index b5e81b8..4983a55 100644
--- a/contrib/tcp_wrappers/fix_options.c
+++ b/contrib/tcp_wrappers/fix_options.c
@@ -3,6 +3,8 @@
* rlogind and kernel source, but all mistakes in it are my fault.
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -11,6 +13,9 @@ static char sccsid[] = "@(#) fix_options.c 1.6 97/04/08 02:29:19";
#include <sys/types.h>
#include <sys/param.h>
+#ifdef INET6
+#include <sys/socket.h>
+#endif
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
@@ -41,6 +46,22 @@ struct request_info *request;
unsigned int opt;
int optlen;
struct in_addr dummy;
+#ifdef INET6
+ struct sockaddr_storage ss;
+ int sslen;
+
+ /*
+ * check if this is AF_INET socket
+ * XXX IPv6 support?
+ */
+ sslen = sizeof(ss);
+ if (getsockname(fd, (struct sockaddr *)&ss, &sslen) < 0) {
+ syslog(LOG_ERR, "getpeername: %m");
+ clean_exit(request);
+ }
+ if (ss.ss_family != AF_INET)
+ return;
+#endif
if ((ip = getprotobyname("ip")) != 0)
ipproto = ip->p_proto;
diff --git a/contrib/tcp_wrappers/hosts_access.5 b/contrib/tcp_wrappers/hosts_access.5
index 49a6bf7..27ab2ae 100644
--- a/contrib/tcp_wrappers/hosts_access.5
+++ b/contrib/tcp_wrappers/hosts_access.5
@@ -90,6 +90,13 @@ bitwise AND of the address and the `mask\'. For example, the net/mask
pattern `131.155.72.0/255.255.254.0\' matches every address in the
range `131.155.72.0\' through `131.155.73.255\'.
.IP \(bu
+An expression of the form `[n:n:n:n:n:n:n:n]/m\' is interpreted as a
+`[net]/prefixlen\' pair. A IPv6 host address is matched if
+`prefixlen\' bits of `net\' is equal to the `prefixlen\' bits of the
+address. For example, the [net]/prefixlen pattern
+`[3ffe:505:2:1::]/64\' matches every address in the range
+`3ffe:505:2:1::\' through `3ffe:505:2:1:ffff:ffff:ffff:ffff\'.
+.IP \(bu
A string that begins with a `/\' character is treated as a file
name. A host name or address is matched if it matches any host name
or address pattern listed in the named file. The file format is
diff --git a/contrib/tcp_wrappers/hosts_access.c b/contrib/tcp_wrappers/hosts_access.c
index 27dd81d..2b4dcee 100644
--- a/contrib/tcp_wrappers/hosts_access.c
+++ b/contrib/tcp_wrappers/hosts_access.c
@@ -26,7 +26,13 @@ static char sccsid[] = "@(#) hosts_access.c 1.21 97/02/12 02:13:22";
/* System libraries. */
#include <sys/types.h>
+#ifdef INT32_T
+ typedef uint32_t u_int32_t;
+#endif
#include <sys/param.h>
+#ifdef INET6
+#include <sys/socket.h>
+#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
@@ -84,6 +90,10 @@ static int client_match();
static int host_match();
static int string_match();
static int masked_match();
+#ifdef INET6
+static int masked_match4();
+static int masked_match6();
+#endif
/* Size of logical line buffer. */
@@ -313,6 +323,13 @@ char *string;
{
int n;
+#ifdef INET6
+ /* convert IPv4 mapped IPv6 address to IPv4 address */
+ if (STRN_EQ(string, "::ffff:", 7)
+ && dot_quad_addr(string + 7) != INADDR_NONE) {
+ string += 7;
+ }
+#endif
if (tok[0] == '.') { /* suffix */
n = strlen(string) - strlen(tok);
return (n > 0 && STR_EQ(tok, string + n));
@@ -323,20 +340,55 @@ char *string;
} else if (tok[(n = strlen(tok)) - 1] == '.') { /* prefix */
return (STRN_EQ(tok, string, n));
} else { /* exact match */
+#ifdef INET6
+ struct in6_addr pat, addr;
+ int len, ret;
+ char ch;
+
+ len = strlen(tok);
+ if (*tok == '[' && tok[len - 1] == ']') {
+ ch = tok[len - 1];
+ tok[len - 1] = '\0';
+ ret = inet_pton(AF_INET6, tok + 1, pat.s6_addr);
+ tok[len - 1] = ch;
+ if (ret != 1 || inet_pton(AF_INET6, string, addr.s6_addr) != 1)
+ return NO;
+ return (!memcmp(&pat, &addr, sizeof(struct in6_addr)));
+ }
+#endif
return (STR_EQ(tok, string));
}
}
/* masked_match - match address against netnumber/netmask */
+#ifdef INET6
static int masked_match(net_tok, mask_tok, string)
char *net_tok;
char *mask_tok;
char *string;
{
+ return (masked_match4(net_tok, mask_tok, string) ||
+ masked_match6(net_tok, mask_tok, string));
+}
+
+static int masked_match4(net_tok, mask_tok, string)
+#else
+static int masked_match(net_tok, mask_tok, string)
+#endif
+char *net_tok;
+char *mask_tok;
+char *string;
+{
+#ifdef INET6
+ u_int32_t net;
+ u_int32_t mask;
+ u_int32_t addr;
+#else
unsigned long net;
unsigned long mask;
unsigned long addr;
+#endif
/*
* Disallow forms other than dotted quad: the treatment that inet_addr()
@@ -348,8 +400,61 @@ char *string;
return (NO);
if ((net = dot_quad_addr(net_tok)) == INADDR_NONE
|| (mask = dot_quad_addr(mask_tok)) == INADDR_NONE) {
+#ifndef INET6
tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok);
+#endif
return (NO); /* not tcpd_jump() */
}
return ((addr & mask) == net);
}
+
+#ifdef INET6
+static int masked_match6(net_tok, mask_tok, string)
+char *net_tok;
+char *mask_tok;
+char *string;
+{
+ struct in6_addr net, addr;
+ u_int32_t mask;
+ int len, mask_len, i = 0;
+ char ch;
+
+ if (inet_pton(AF_INET6, string, addr.s6_addr) != 1)
+ return NO;
+
+ if (IN6_IS_ADDR_V4MAPPED(&addr)) {
+ if ((*(u_int32_t *)&net.s6_addr[12] = dot_quad_addr(net_tok)) == INADDR_NONE
+ || (mask = dot_quad_addr(mask_tok)) == INADDR_NONE)
+ return (NO);
+ return ((*(u_int32_t *)&addr.s6_addr[12] & mask) == *(u_int32_t *)&net.s6_addr[12]);
+ }
+
+ /* match IPv6 address against netnumber/prefixlen */
+ len = strlen(net_tok);
+ if (*net_tok != '[' || net_tok[len - 1] != ']')
+ return NO;
+ ch = net_tok[len - 1];
+ net_tok[len - 1] = '\0';
+ if (inet_pton(AF_INET6, net_tok + 1, net.s6_addr) != 1) {
+ net_tok[len - 1] = ch;
+ return NO;
+ }
+ net_tok[len - 1] = ch;
+ if ((mask_len = atoi(mask_tok)) < 0 || mask_len > 128)
+ return NO;
+
+ while (mask_len > 0) {
+ if (mask_len < 32) {
+ mask = htonl(~(0xffffffff >> mask_len));
+ if ((*(u_int32_t *)&addr.s6_addr[i] & mask) != (*(u_int32_t *)&net.s6_addr[i] & mask))
+ return NO;
+ break;
+ }
+ if (*(u_int32_t *)&addr.s6_addr[i] != *(u_int32_t *)&net.s6_addr[i])
+ return NO;
+ i += 4;
+ mask_len -= 32;
+ }
+ return YES;
+}
+#endif /* INET6 */
diff --git a/contrib/tcp_wrappers/misc.c b/contrib/tcp_wrappers/misc.c
index 87a7653..8f04f87 100644
--- a/contrib/tcp_wrappers/misc.c
+++ b/contrib/tcp_wrappers/misc.c
@@ -2,6 +2,8 @@
* Misc routines that are used by tcpd and by tcpdchk.
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -58,9 +60,31 @@ int delimiter;
{
char *cp;
+#ifdef INET6
+ int bracket = 0;
+
+ for (cp = string; cp && *cp; cp++) {
+ switch (*cp) {
+ case '[':
+ bracket++;
+ break;
+ case ']':
+ bracket--;
+ break;
+ default:
+ if (bracket == 0 && *cp == delimiter) {
+ *cp++ = 0;
+ return cp;
+ }
+ break;
+ }
+ }
+ return (NULL);
+#else
if ((cp = strchr(string, delimiter)) != 0)
*cp++ = 0;
return (cp);
+#endif
}
/* dot_quad_addr - convert dotted quad to internal form */
diff --git a/contrib/tcp_wrappers/refuse.c b/contrib/tcp_wrappers/refuse.c
index ccf8030..fd04e08 100644
--- a/contrib/tcp_wrappers/refuse.c
+++ b/contrib/tcp_wrappers/refuse.c
@@ -5,6 +5,8 @@
* the program is terminated.
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -25,7 +27,12 @@ static char sccsid[] = "@(#) refuse.c 1.5 94/12/28 17:42:39";
void refuse(request)
struct request_info *request;
{
+#ifdef INET6
+ syslog(deny_severity, "refused connect from %s (%s)",
+ eval_client(request), eval_hostaddr(request->client));
+#else
syslog(deny_severity, "refused connect from %s", eval_client(request));
+#endif
clean_exit(request);
/* NOTREACHED */
}
diff --git a/contrib/tcp_wrappers/rfc931.c b/contrib/tcp_wrappers/rfc931.c
index 8176417..c666f58 100644
--- a/contrib/tcp_wrappers/rfc931.c
+++ b/contrib/tcp_wrappers/rfc931.c
@@ -7,6 +7,8 @@
* Diagnostics are reported through syslog(3).
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -68,20 +70,50 @@ int sig;
/* rfc931 - return remote user name, given socket structures */
void rfc931(rmt_sin, our_sin, dest)
+#ifdef INET6
+struct sockaddr *rmt_sin;
+struct sockaddr *our_sin;
+#else
struct sockaddr_in *rmt_sin;
struct sockaddr_in *our_sin;
+#endif
char *dest;
{
unsigned rmt_port;
unsigned our_port;
+#ifdef INET6
+ struct sockaddr_storage rmt_query_sin;
+ struct sockaddr_storage our_query_sin;
+ int alen;
+#else
struct sockaddr_in rmt_query_sin;
struct sockaddr_in our_query_sin;
+#endif
char user[256]; /* XXX */
char buffer[512]; /* XXX */
char *cp;
char *result = unknown;
FILE *fp;
+#ifdef INET6
+ /* address family must be the same */
+ if (rmt_sin->sa_family != our_sin->sa_family) {
+ STRN_CPY(dest, result, STRING_LENGTH);
+ return;
+ }
+ switch (our_sin->sa_family) {
+ case AF_INET:
+ alen = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ alen = sizeof(struct sockaddr_in6);
+ break;
+ default:
+ STRN_CPY(dest, result, STRING_LENGTH);
+ return;
+ }
+#endif
+
/*
* Use one unbuffered stdio stream for writing to and for reading from
* the RFC931 etc. server. This is done because of a bug in the SunOS
@@ -92,7 +124,11 @@ char *dest;
* sockets.
*/
+#ifdef INET6
+ if ((fp = fsocket(our_sin->sa_family, SOCK_STREAM, 0)) != 0) {
+#else
if ((fp = fsocket(AF_INET, SOCK_STREAM, 0)) != 0) {
+#endif
setbuf(fp, (char *) 0);
/*
@@ -112,6 +148,25 @@ char *dest;
* addresses from the query socket.
*/
+#ifdef INET6
+ memcpy(&our_query_sin, our_sin, alen);
+ memcpy(&rmt_query_sin, rmt_sin, alen);
+ switch (our_sin->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)&our_query_sin)->sin_port = htons(ANY_PORT);
+ ((struct sockaddr_in *)&rmt_query_sin)->sin_port = htons(RFC931_PORT);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)&our_query_sin)->sin6_port = htons(ANY_PORT);
+ ((struct sockaddr_in6 *)&rmt_query_sin)->sin6_port = htons(RFC931_PORT);
+ break;
+ }
+
+ if (bind(fileno(fp), (struct sockaddr *) & our_query_sin,
+ alen) >= 0 &&
+ connect(fileno(fp), (struct sockaddr *) & rmt_query_sin,
+ alen) >= 0) {
+#else
our_query_sin = *our_sin;
our_query_sin.sin_port = htons(ANY_PORT);
rmt_query_sin = *rmt_sin;
@@ -121,6 +176,7 @@ char *dest;
sizeof(our_query_sin)) >= 0 &&
connect(fileno(fp), (struct sockaddr *) & rmt_query_sin,
sizeof(rmt_query_sin)) >= 0) {
+#endif
/*
* Send query to server. Neglect the risk that a 13-byte
@@ -129,8 +185,13 @@ char *dest;
*/
fprintf(fp, "%u,%u\r\n",
+#ifdef INET6
+ ntohs(((struct sockaddr_in *)rmt_sin)->sin_port),
+ ntohs(((struct sockaddr_in *)our_sin)->sin_port));
+#else
ntohs(rmt_sin->sin_port),
ntohs(our_sin->sin_port));
+#endif
fflush(fp);
/*
@@ -144,8 +205,13 @@ char *dest;
&& ferror(fp) == 0 && feof(fp) == 0
&& sscanf(buffer, "%u , %u : USERID :%*[^:]:%255s",
&rmt_port, &our_port, user) == 3
+#ifdef INET6
+ && ntohs(((struct sockaddr_in *)rmt_sin)->sin_port) == rmt_port
+ && ntohs(((struct sockaddr_in *)our_sin)->sin_port) == our_port) {
+#else
&& ntohs(rmt_sin->sin_port) == rmt_port
&& ntohs(our_sin->sin_port) == our_port) {
+#endif
/*
* Strip trailing carriage return. It is part of the
diff --git a/contrib/tcp_wrappers/scaffold.c b/contrib/tcp_wrappers/scaffold.c
index afce15a..ea87c5c 100644
--- a/contrib/tcp_wrappers/scaffold.c
+++ b/contrib/tcp_wrappers/scaffold.c
@@ -2,6 +2,8 @@
* Routines for testing only. Not really industrial strength.
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -20,6 +22,7 @@ static char sccs_id[] = "@(#) scaffold.c 1.6 97/03/21 19:27:24";
#include <syslog.h>
#include <setjmp.h>
#include <string.h>
+#include <resolv.h>
#ifndef INADDR_NONE
#define INADDR_NONE (-1) /* XXX should be 0xffffffff */
@@ -57,6 +60,9 @@ struct hostent *hp;
/* void */ ;
if ((hb = (struct hostent_block *) malloc(sizeof(struct hostent_block)
+#ifdef INET6
+ + strlen(hp->h_name) + 1
+#endif
+ (hp->h_length + sizeof(char *)) * count)) == 0) {
fprintf(stderr, "Sorry, out of memory\n");
exit(1);
@@ -66,6 +72,11 @@ struct hostent *hp;
hb->host.h_addr_list = hb->addr_list;
hb->host.h_addr_list[count] = 0;
data = (char *) (hb->host.h_addr_list + count + 1);
+#ifdef INET6
+ hb->host.h_name = data + hp->h_length * count;
+ strcpy(hb->host.h_name, hp->h_name);
+ hb->host.h_addrtype = hp->h_addrtype;
+#endif
for (count = 0; (addr = hp->h_addr_list[count]) != 0; count++) {
hb->host.h_addr_list[count] = data + hp->h_length * count;
@@ -74,6 +85,104 @@ struct hostent *hp;
return (&hb->host);
}
+#if defined(INET6) && !defined(USE_GETIPNODEBY)
+/* merge_hostent - merge hostent in one memory block */
+
+static struct hostent *merge_hostent(hp1, hp2)
+struct hostent *hp1, *hp2;
+{
+ struct hostent_block {
+ struct hostent host;
+ char *addr_list[1];
+ };
+ struct hostent_block *hb;
+ int count, count2;
+ char *data;
+ char *addr;
+
+ for (count = 0; hp1->h_addr_list[count] != 0; count++)
+ /* void */ ;
+ for (count2 = 0; hp2->h_addr_list[count2] != 0; count2++)
+ /* void */ ;
+ count += count2;
+
+ if ((hb = (struct hostent_block *) malloc(sizeof(struct hostent_block)
+ + strlen(hp1->h_name) + 1
+ + (hp1->h_length + sizeof(char *)) * count)) == 0) {
+ fprintf(stderr, "Sorry, out of memory\n");
+ exit(1);
+ }
+ memset((char *) &hb->host, 0, sizeof(hb->host));
+ hb->host.h_length = hp1->h_length;
+ hb->host.h_addr_list = hb->addr_list;
+ hb->host.h_addr_list[count] = 0;
+ data = (char *) (hb->host.h_addr_list + count + 1);
+ hb->host.h_name = data + hp1->h_length * count;
+ strcpy(hb->host.h_name, hp1->h_name);
+ hb->host.h_addrtype = hp1->h_addrtype;
+
+ for (count = 0; (addr = hp1->h_addr_list[count]) != 0; count++) {
+ hb->host.h_addr_list[count] = data + hp1->h_length * count;
+ memcpy(hb->host.h_addr_list[count], addr, hp1->h_length);
+ }
+ for (count2 = 0; (addr = hp2->h_addr_list[count2]) != 0; count2++) {
+ hb->host.h_addr_list[count] = data + hp1->h_length * count;
+ memcpy(hb->host.h_addr_list[count], addr, hp1->h_length);
+ ++count;
+ }
+ return (&hb->host);
+}
+#endif
+
+static struct hostent *gethostbyname64(host)
+char *host;
+{
+ struct hostent *hp = NULL, *hp2 = NULL;
+#ifdef USE_GETIPNODEBY
+ int h_error;
+
+ if ((hp = getipnodebyname(host, AF_INET6,
+ AI_V4MAPPED | AI_ADDRCONFIG | AI_ALL,
+ &h_error)) != 0) {
+ hp2 = dup_hostent(hp);
+ freehostent(hp);
+ return (hp2);
+ }
+#else
+ struct hostent *hp1;
+ u_long res_options;
+
+ if ((_res.options & RES_INIT) == 0) {
+ if (res_init() < 0) {
+ tcpd_warn("%s: res_init() failed", host);
+ return (NULL);
+ }
+ }
+ res_options = _res.options;
+#ifdef INET6
+ _res.options |= RES_USE_INET6;
+ if ((hp1 = gethostbyname2(host, AF_INET6)) != NULL)
+ hp1 = dup_hostent(hp1);
+#endif
+ if ((hp2 = gethostbyname2(host, AF_INET)) != NULL)
+ hp2 = dup_hostent(hp2);
+ _res.options = res_options;
+#ifdef INET6
+ if (hp1 && hp2) {
+ hp = merge_hostent(hp1, hp2);
+ free((char *) hp1);
+ free((char *) hp2);
+ return (hp);
+ }
+ if (hp1)
+ return (hp1);
+#endif
+ if (hp2)
+ return (hp2);
+#endif
+ return (NULL);
+}
+
/* find_inet_addr - find all addresses for this host, result to free() */
struct hostent *find_inet_addr(host)
@@ -83,6 +192,7 @@ char *host;
struct hostent *hp;
static struct hostent h;
static char *addr_list[2];
+ static char hnamebuf[BUFSIZ];
/*
* Host address: translate it to internal form.
@@ -91,6 +201,11 @@ char *host;
h.h_addr_list = addr_list;
h.h_addr_list[0] = (char *) &addr;
h.h_length = sizeof(addr);
+#ifdef INET6
+ h.h_addrtype = AF_INET;
+ h.h_name = hnamebuf;
+ strcpy(h.h_name, host);
+#endif
return (dup_hostent(&h));
}
@@ -104,19 +219,33 @@ char *host;
tcpd_warn("%s: not an internet address", host);
return (0);
}
+#ifdef INET6
+ if ((hp = gethostbyname64(host)) == 0) {
+#else
if ((hp = gethostbyname(host)) == 0) {
+#endif
tcpd_warn("%s: host not found", host);
return (0);
}
+#ifdef INET6
+ if (hp->h_addrtype != AF_INET6) {
+ tcpd_warn("%d: not an internet host", hp->h_addrtype);
+ free((char *) hp);
+#else
if (hp->h_addrtype != AF_INET) {
tcpd_warn("%d: not an internet host", hp->h_addrtype);
+#endif
return (0);
}
if (STR_NE(host, hp->h_name)) {
tcpd_warn("%s: hostname alias", host);
tcpd_warn("(official name: %.*s)", STRING_LENGTH, hp->h_name);
}
+#ifdef INET6
+ return (hp);
+#else
return (dup_hostent(hp));
+#endif
}
/* check_dns - give each address thorough workout, return address count */
@@ -125,7 +254,13 @@ int check_dns(host)
char *host;
{
struct request_info request;
+#ifdef INET6
+ struct sockaddr_storage sin;
+ char *ap;
+ int alen;
+#else
struct sockaddr_in sin;
+#endif
struct hostent *hp;
int count;
char *addr;
@@ -135,10 +270,30 @@ char *host;
request_init(&request, RQ_CLIENT_SIN, &sin, 0);
sock_methods(&request);
memset((char *) &sin, 0, sizeof(sin));
+#ifdef INET6
+ sin.ss_family = hp->h_addrtype;
+ switch (hp->h_addrtype) {
+ case AF_INET:
+ ap = (char *)&((struct sockaddr_in *)&sin)->sin_addr;
+ alen = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ ap = (char *)&((struct sockaddr_in6 *)&sin)->sin6_addr;
+ alen = sizeof(struct sockaddr_in6);
+ break;
+ default:
+ return (0);
+ }
+#else
sin.sin_family = AF_INET;
+#endif
for (count = 0; (addr = hp->h_addr_list[count]) != 0; count++) {
+#ifdef INET6
+ memcpy(ap, addr, alen);
+#else
memcpy((char *) &sin.sin_addr, addr, sizeof(sin.sin_addr));
+#endif
/*
* Force host name and address conversions. Use the request structure
diff --git a/contrib/tcp_wrappers/socket.c b/contrib/tcp_wrappers/socket.c
index c659b16..d2370e0 100644
--- a/contrib/tcp_wrappers/socket.c
+++ b/contrib/tcp_wrappers/socket.c
@@ -13,6 +13,8 @@
* Diagnostics are reported through syslog(3).
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -30,6 +32,12 @@ static char sccsid[] = "@(#) socket.c 1.15 97/03/21 19:27:24";
#include <syslog.h>
#include <string.h>
+#ifdef INET6
+#ifndef USE_GETIPNODEBY
+#include <resolv.h>
+#endif
+#endif
+
extern char *inet_ntoa();
/* Local stuff. */
@@ -74,8 +82,13 @@ char *name;
void sock_host(request)
struct request_info *request;
{
+#ifdef INET6
+ static struct sockaddr_storage client;
+ static struct sockaddr_storage server;
+#else
static struct sockaddr_in client;
static struct sockaddr_in server;
+#endif
int len;
char buf[BUFSIZ];
int fd = request->fd;
@@ -104,7 +117,11 @@ struct request_info *request;
memset(buf, 0 sizeof(buf));
#endif
}
+#ifdef INET6
+ request->client->sin = (struct sockaddr *)&client;
+#else
request->client->sin = &client;
+#endif
/*
* Determine the server binding. This is used for client username
@@ -117,7 +134,11 @@ struct request_info *request;
tcpd_warn("getsockname: %m");
return;
}
+#ifdef INET6
+ request->server->sin = (struct sockaddr *)&server;
+#else
request->server->sin = &server;
+#endif
}
/* sock_hostaddr - map endpoint address to printable form */
@@ -125,10 +146,33 @@ struct request_info *request;
void sock_hostaddr(host)
struct host_info *host;
{
+#ifdef INET6
+ struct sockaddr *sin = host->sin;
+ char *ap;
+ int alen;
+
+ if (!sin)
+ return;
+ switch (sin->sa_family) {
+ case AF_INET:
+ ap = (char *)&((struct sockaddr_in *)sin)->sin_addr;
+ alen = sizeof(struct in_addr);
+ break;
+ case AF_INET6:
+ ap = (char *)&((struct sockaddr_in6 *)sin)->sin6_addr;
+ alen = sizeof(struct in6_addr);
+ break;
+ default:
+ return;
+ }
+ host->addr[0] = '\0';
+ inet_ntop(sin->sa_family, ap, host->addr, sizeof(host->addr));
+#else
struct sockaddr_in *sin = host->sin;
if (sin != 0)
STRN_CPY(host->addr, inet_ntoa(sin->sin_addr), sizeof(host->addr));
+#endif
}
/* sock_hostname - map endpoint address to host name */
@@ -136,8 +180,21 @@ struct host_info *host;
void sock_hostname(host)
struct host_info *host;
{
+#ifdef INET6
+ struct sockaddr *sin = host->sin;
+ char addr[128];
+#ifdef USE_GETIPNODEBY
+ int h_error;
+#else
+ u_long res_options;
+#endif
+ struct hostent *hp = NULL;
+ char *ap;
+ int alen;
+#else
struct sockaddr_in *sin = host->sin;
struct hostent *hp;
+#endif
int i;
/*
@@ -147,11 +204,42 @@ struct host_info *host;
* have to special-case 0.0.0.0, in order to avoid false alerts from the
* host name/address checking code below.
*/
+#ifdef INET6
+ if (sin != NULL) {
+ switch (sin->sa_family) {
+ case AF_INET:
+ if (((struct sockaddr_in *)sin)->sin_addr.s_addr == 0) {
+ strcpy(host->name, paranoid); /* name is bad, clobber it */
+ return;
+ }
+ ap = (char *) &((struct sockaddr_in *)sin)->sin_addr;
+ alen = sizeof(struct in_addr);
+ break;
+ case AF_INET6:
+ ap = (char *) &((struct sockaddr_in6 *)sin)->sin6_addr;
+ alen = sizeof(struct in6_addr);
+ break;
+ defalut:
+ strcpy(host->name, paranoid); /* name is bad, clobber it */
+ return;
+ }
+#ifdef USE_GETIPNODEBY
+ hp = getipnodebyaddr(ap, alen, sin->sa_family, &h_error);
+#else
+ hp = gethostbyaddr(ap, alen, sin->sa_family);
+#endif
+ }
+ if (hp) {
+#else
if (sin != 0 && sin->sin_addr.s_addr != 0
&& (hp = gethostbyaddr((char *) &(sin->sin_addr),
sizeof(sin->sin_addr), AF_INET)) != 0) {
+#endif
STRN_CPY(host->name, hp->h_name, sizeof(host->name));
+#if defined(INET6) && defined(USE_GETIPNODEBY)
+ freehostent(hp);
+#endif
/*
* Verify that the address is a member of the address list returned
@@ -166,15 +254,53 @@ struct host_info *host;
* we're in big trouble anyway.
*/
+#ifdef INET6
+#ifdef USE_GETIPNODEBY
+ hp = getipnodebyname(host->name, sin->sa_family,
+ AI_V4MAPPED | AI_ADDRCONFIG | AI_ALL, &h_error);
+#else
+ if ((_res.options & RES_INIT) == 0) {
+ if (res_init() < 0) {
+ inet_ntop(sin->sa_family, ap, addr, sizeof(addr));
+ tcpd_warn("can't verify hostname: res_init() for %s failed",
+ addr);
+ strcpy(host->name, paranoid); /* name is bad, clobber it */
+ return;
+ }
+ }
+ res_options = _res.options;
+ if (sin->sa_family == AF_INET6)
+ _res.options |= RES_USE_INET6;
+ else
+ _res.options &= ~RES_USE_INET6;
+ hp = gethostbyname2(host->name,
+ (sin->sa_family == AF_INET6 &&
+ IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sin)->sin6_addr)) ?
+ AF_INET : sin->sa_family);
+ _res.options = res_options;
+#endif
+ if (!hp) {
+#else
if ((hp = gethostbyname(host->name)) == 0) {
+#endif
/*
* Unable to verify that the host name matches the address. This
* may be a transient problem or a botched name server setup.
*/
+#ifdef INET6
+#ifdef USE_GETIPNODEBY
+ tcpd_warn("can't verify hostname: getipnodebyname(%s, %s) failed",
+#else
+ tcpd_warn("can't verify hostname: gethostbyname2(%s, %s) failed",
+#endif
+ host->name,
+ (sin->sa_family == AF_INET) ? "AF_INET" : "AF_INET6");
+#else
tcpd_warn("can't verify hostname: gethostbyname(%s) failed",
host->name);
+#endif
} else if (STR_NE(host->name, hp->h_name)
&& STR_NE(host->name, "localhost")) {
@@ -198,10 +324,19 @@ struct host_info *host;
*/
for (i = 0; hp->h_addr_list[i]; i++) {
+#ifdef INET6
+ if (memcmp(hp->h_addr_list[i], ap, alen) == 0) {
+#ifdef USE_GETIPNODEBY
+ freehostent(hp);
+#endif
+ return; /* name is good, keep it */
+ }
+#else
if (memcmp(hp->h_addr_list[i],
(char *) &sin->sin_addr,
sizeof(sin->sin_addr)) == 0)
return; /* name is good, keep it */
+#endif
}
/*
@@ -210,10 +345,20 @@ struct host_info *host;
* server.
*/
+#ifdef INET6
+ inet_ntop(sin->sa_family, ap, addr, sizeof(addr));
+ tcpd_warn("host name/address mismatch: %s != %.*s",
+ addr, STRING_LENGTH, hp->h_name);
+#else
tcpd_warn("host name/address mismatch: %s != %.*s",
inet_ntoa(sin->sin_addr), STRING_LENGTH, hp->h_name);
+#endif
}
strcpy(host->name, paranoid); /* name is bad, clobber it */
+#if defined(INET6) && defined(USE_GETIPNODEBY)
+ if (hp)
+ freehostent(hp);
+#endif
}
}
@@ -223,7 +368,11 @@ static void sock_sink(fd)
int fd;
{
char buf[BUFSIZ];
+#ifdef INET6
+ struct sockaddr_storage sin;
+#else
struct sockaddr_in sin;
+#endif
int size = sizeof(sin);
/*
diff --git a/contrib/tcp_wrappers/tcpd.c b/contrib/tcp_wrappers/tcpd.c
index d865b9c..55c6853 100644
--- a/contrib/tcp_wrappers/tcpd.c
+++ b/contrib/tcp_wrappers/tcpd.c
@@ -8,6 +8,8 @@
* are logged through syslog(3).
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -120,7 +122,12 @@ char **argv;
/* Report request and invoke the real daemon program. */
+#ifdef INET6
+ syslog(allow_severity, "connect from %s (%s)",
+ eval_client(&request), eval_hostaddr(request.client));
+#else
syslog(allow_severity, "connect from %s", eval_client(&request));
+#endif
closelog();
(void) execv(path, argv);
syslog(LOG_ERR, "error: cannot execute %s: %m", path);
diff --git a/contrib/tcp_wrappers/tcpd.h b/contrib/tcp_wrappers/tcpd.h
index 3eecc91..fec20a2 100644
--- a/contrib/tcp_wrappers/tcpd.h
+++ b/contrib/tcp_wrappers/tcpd.h
@@ -2,6 +2,8 @@
* @(#) tcpd.h 1.5 96/03/19 16:22:24
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * $FreeBSD$
*/
/* Structure to describe one communications endpoint. */
@@ -11,7 +13,11 @@
struct host_info {
char name[STRING_LENGTH]; /* access via eval_hostname(host) */
char addr[STRING_LENGTH]; /* access via eval_hostaddr(host) */
+#ifdef INET6
+ struct sockaddr *sin; /* socket address or 0 */
+#else
struct sockaddr_in *sin; /* socket address or 0 */
+#endif
struct t_unitdata *unit; /* TLI transport address or 0 */
struct request_info *request; /* for shared information */
};
diff --git a/contrib/tcp_wrappers/tcpdchk.c b/contrib/tcp_wrappers/tcpdchk.c
index 6a317d9..a2804a2 100644
--- a/contrib/tcp_wrappers/tcpdchk.c
+++ b/contrib/tcp_wrappers/tcpdchk.c
@@ -24,6 +24,9 @@ static char sccsid[] = "@(#) tcpdchk.c 1.8 97/02/12 02:13:25";
#include <sys/types.h>
#include <sys/stat.h>
+#ifdef INET6
+#include <sys/socket.h>
+#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
@@ -403,6 +406,26 @@ char *pat;
}
}
+#ifdef INET6
+static int is_inet6_addr(pat)
+ char *pat;
+{
+ struct in6_addr addr;
+ int len, ret;
+ char ch;
+
+ if (*pat != '[')
+ return (0);
+ len = strlen(pat);
+ if ((ch = pat[len - 1]) != ']')
+ return (0);
+ pat[len - 1] = '\0';
+ ret = inet_pton(AF_INET6, pat + 1, &addr);
+ pat[len - 1] = ch;
+ return (ret == 1);
+}
+#endif
+
/* check_host - criticize host pattern */
static int check_host(pat)
@@ -449,14 +472,27 @@ char *pat;
tcpd_warn("open %s: %m", pat);
}
} else if (mask = split_at(pat, '/')) { /* network/netmask */
+#ifdef INET6
+ int mask_len;
+
+ if ((dot_quad_addr(pat) == INADDR_NONE
+ || dot_quad_addr(mask) == INADDR_NONE)
+ && (!is_inet6_addr(pat)
+ || ((mask_len = atoi(mask)) < 0 || mask_len > 128)))
+#else
if (dot_quad_addr(pat) == INADDR_NONE
|| dot_quad_addr(mask) == INADDR_NONE)
+#endif
tcpd_warn("%s/%s: bad net/mask pattern", pat, mask);
} else if (STR_EQ(pat, "FAIL")) { /* obsolete */
tcpd_warn("FAIL is no longer recognized");
tcpd_warn("(use EXCEPT or DENY instead)");
} else if (reserved_name(pat)) { /* other reserved */
/* void */ ;
+#ifdef INET6
+ } else if (is_inet6_addr(pat)) { /* IPv6 address */
+ addr_count = 1;
+#endif
} else if (NOT_INADDR(pat)) { /* internet name */
if (pat[strlen(pat) - 1] == '.') {
tcpd_warn("%s: domain or host name ends in dot", pat);
diff --git a/contrib/tcp_wrappers/tcpdmatch.c b/contrib/tcp_wrappers/tcpdmatch.c
index b1cf75f2..f8c8dc1 100644
--- a/contrib/tcp_wrappers/tcpdmatch.c
+++ b/contrib/tcp_wrappers/tcpdmatch.c
@@ -11,6 +11,8 @@
* that would normally be reported via the syslog daemon.
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -68,8 +70,15 @@ char **argv;
int ch;
char *inetcf = 0;
int count;
+#ifdef INET6
+ struct sockaddr_storage server_sin;
+ struct sockaddr_storage client_sin;
+ char *ap;
+ int alen;
+#else
struct sockaddr_in server_sin;
struct sockaddr_in client_sin;
+#endif
struct stat st;
/*
@@ -173,12 +182,35 @@ char **argv;
if ((hp = find_inet_addr(server)) == 0)
exit(1);
memset((char *) &server_sin, 0, sizeof(server_sin));
+#ifdef INET6
+ server_sin.ss_family = hp->h_addrtype;
+ switch (hp->h_addrtype) {
+ case AF_INET:
+ ap = (char *)&((struct sockaddr_in *)&server_sin)->sin_addr;
+ alen = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ ap = (char *)&((struct sockaddr_in6 *)&server_sin)->sin6_addr;
+ alen = sizeof(struct sockaddr_in6);
+ break;
+ default:
+ exit(1);
+ }
+#ifdef SIN6_LEN
+ server_sin.ss_len = alen;
+#endif
+#else
server_sin.sin_family = AF_INET;
+#endif
request_set(&request, RQ_SERVER_SIN, &server_sin, 0);
for (count = 0; (addr = hp->h_addr_list[count]) != 0; count++) {
+#ifdef INET6
+ memcpy(ap, addr, alen);
+#else
memcpy((char *) &server_sin.sin_addr, addr,
sizeof(server_sin.sin_addr));
+#endif
/*
* Force evaluation of server host name and address. Host name
@@ -230,12 +262,35 @@ char **argv;
if ((hp = find_inet_addr(client)) == 0)
exit(1);
memset((char *) &client_sin, 0, sizeof(client_sin));
+#ifdef INET6
+ client_sin.ss_family = hp->h_addrtype;
+ switch (hp->h_addrtype) {
+ case AF_INET:
+ ap = (char *)&((struct sockaddr_in *)&client_sin)->sin_addr;
+ alen = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ ap = (char *)&((struct sockaddr_in6 *)&client_sin)->sin6_addr;
+ alen = sizeof(struct sockaddr_in6);
+ break;
+ default:
+ exit(1);
+ }
+#ifdef SIN6_LEN
+ client_sin.ss_len = alen;
+#endif
+#else
client_sin.sin_family = AF_INET;
+#endif
request_set(&request, RQ_CLIENT_SIN, &client_sin, 0);
for (count = 0; (addr = hp->h_addr_list[count]) != 0; count++) {
+#ifdef INET6
+ memcpy(ap, addr, alen);
+#else
memcpy((char *) &client_sin.sin_addr, addr,
sizeof(client_sin.sin_addr));
+#endif
/*
* Force evaluation of client host name and address. Host name
diff --git a/contrib/tcp_wrappers/tli.c b/contrib/tcp_wrappers/tli.c
index 14579d1..36d6f7e 100644
--- a/contrib/tcp_wrappers/tli.c
+++ b/contrib/tcp_wrappers/tli.c
@@ -12,6 +12,8 @@
* Diagnostics are reported through syslog(3).
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -65,8 +67,13 @@ static void tli_sink();
void tli_host(request)
struct request_info *request;
{
+#ifdef INET6
+ static struct sockaddr_storage client;
+ static struct sockaddr_storage server;
+#else
static struct sockaddr_in client;
static struct sockaddr_in server;
+#endif
/*
* If we discover that we are using an IP transport, pretend we never
@@ -75,15 +82,31 @@ struct request_info *request;
*/
tli_endpoints(request);
+#ifdef INET6
+ if ((request->config = tli_transport(request->fd)) != 0
+ && (STR_EQ(request->config->nc_protofmly, "inet") ||
+ STR_EQ(request->config->nc_protofmly, "inet6"))) {
+#else
if ((request->config = tli_transport(request->fd)) != 0
- && STR_EQ(request->config->nc_protofmly, "inet")) {
+ && STR_EQ(request->config->nc_protofmly, "inet")) {
+#endif
if (request->client->unit != 0) {
+#ifdef INET6
+ client = *(struct sockaddr_storage *) request->client->unit->addr.buf;
+ request->client->sin = (struct sockaddr *) &client;
+#else
client = *(struct sockaddr_in *) request->client->unit->addr.buf;
request->client->sin = &client;
+#endif
}
if (request->server->unit != 0) {
- server = *(struct sockaddr_in *) request->server->unit->addr.buf;
- request->server->sin = &server;
+#ifdef INET6
+ server = *(struct sockaddr_storage *) request->server->unit->addr.buf;
+ request->server->sin = (struct sockaddr *) &server;
+#else
+ server = *(struct sockaddr_in *) request->server->unit->addr.buf;
+ request->server->sin = &server;
+#endif
}
tli_cleanup(request);
sock_methods(request);
@@ -187,7 +210,15 @@ int fd;
}
while (config = getnetconfig(handlep)) {
if (stat(config->nc_device, &from_config) == 0) {
+#ifdef NO_CLONE_DEVICE
+ /*
+ * If the network devices are not cloned (as is the case for
+ * Solaris 8 Beta), we must compare the major device numbers.
+ */
+ if (major(from_config.st_rdev) == major(from_client.st_rdev))
+#else
if (minor(from_config.st_rdev) == major(from_client.st_rdev))
+#endif
break;
}
}
diff --git a/contrib/tcp_wrappers/update.c b/contrib/tcp_wrappers/update.c
index a76cf2b..b612d5e 100644
--- a/contrib/tcp_wrappers/update.c
+++ b/contrib/tcp_wrappers/update.c
@@ -11,6 +11,8 @@
* Diagnostics are reported through syslog(3).
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -46,10 +48,18 @@ va_list ap;
request->fd = va_arg(ap, int);
continue;
case RQ_CLIENT_SIN:
+#ifdef INET6
+ request->client->sin = va_arg(ap, struct sockaddr *);
+#else
request->client->sin = va_arg(ap, struct sockaddr_in *);
+#endif
continue;
case RQ_SERVER_SIN:
+#ifdef INET6
+ request->server->sin = va_arg(ap, struct sockaddr *);
+#else
request->server->sin = va_arg(ap, struct sockaddr_in *);
+#endif
continue;
/*
diff --git a/contrib/tcp_wrappers/workarounds.c b/contrib/tcp_wrappers/workarounds.c
index 9ffa247..1ad2c64 100644
--- a/contrib/tcp_wrappers/workarounds.c
+++ b/contrib/tcp_wrappers/workarounds.c
@@ -5,6 +5,8 @@
* systems.
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -166,11 +168,22 @@ struct sockaddr *sa;
int *len;
{
int ret;
+#ifdef INET6
+ struct sockaddr *sin = sa;
+#else
struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+#endif
if ((ret = getpeername(sock, sa, len)) >= 0
+#ifdef INET6
+ && ((sin->su_si.si_family == AF_INET6
+ && IN6_IS_ADDR_UNSPECIFIED(&sin->su_sin6.sin6_addr))
+ || (sin->su_si.si_family == AF_INET
+ && sin->su_sin.sin_addr.s_addr == 0))) {
+#else
&& sa->sa_family == AF_INET
&& sin->sin_addr.s_addr == 0) {
+#endif
errno = ENOTCONN;
return (-1);
} else {
OpenPOWER on IntegriCloud