Subject: libwrap change for IPv6
To: None <tech-net@netbsd.org>
From: None <itojun@iijlab.net>
List: tech-net
Date: 08/11/1999 23:48:28
------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <13412.934382891.1@coconut.itojun.org>
Content-Transfer-Encoding: 7bit
I've made a patch for IPv6 support in libwrap. This is based on
NetBSD 1.4 code (hence tcp_wrapper 7.4), and should be easily applied
to NetBSD-current code. This involves following changes:
- IPv6 addresses on getpeername() will be handled correctly.
This is done by changing sockaddr_in to sockaddr_storage or sockaddr
as necessary.
- you can wrap numeric addresses by square bracket, to avoid
colon issue (used as separator for /etc/hosts.{allow,deny}).
- now it depends on more recent API functions like inet_pton().
- API change: s/struct sockaddr_in */struct sockaddr */ in struct
host_info.
A line in /etc/hosts.allow will look like this:
telnetd: 127.0.0.1/255.255.255.255 [::1/128] [3ffe::/ffff::]
now prefixlen is allowed for IPv6 case, for obvious reasons.
There are other patch available on the net but they change separator
from colon to pipe sign, so it makes /etc/hosts.allow incompatible
with previous installations. I thought we should not impact
compatibility with other systems so I used square brackets.
The patch is attached below. Please comment before I commit it
into the repository.
Of course, I'll be submitting this to Wietse for the merge (for
latest tcp_wrapper), but due to the last two items I may need to
do more for portability (but I hate to reimplement inet_pton by
myself).
itojun
------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <13412.934382891.2@coconut.itojun.org>
Content-Transfer-Encoding: 7bit
? hosts_access.po
? options.po
? shell_cmd.po
? rfc931.po
? eval.po
? hosts_ctl.po
? refuse.po
? percent_x.po
? clean_exit.po
? fix_options.po
? socket.po
? workarounds.po
? update.po
? misc.po
? diag.po
? hosts_access.cat3
? hosts_access.cat5
? hosts_options.cat5
Index: Makefile
===================================================================
RCS file: /cvsroot/kame/kame/netbsd/lib/libwrap/Makefile,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** Makefile 1999/08/11 08:16:05 1.1.1.1
--- Makefile 1999/08/11 12:18:15 1.2
***************
*** 15,20 ****
--- 15,22 ----
INCS= tcpd.h
INCSDIR=/usr/include
+ MKPIC= no
+
.include "Makefile.cflags"
.include <bsd.lib.mk>
Index: Makefile.cflags
===================================================================
RCS file: /cvsroot/kame/kame/netbsd/lib/libwrap/Makefile.cflags,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** Makefile.cflags 1999/08/11 08:16:05 1.1.1.1
--- Makefile.cflags 1999/08/11 12:18:15 1.2
***************
*** 11,13 ****
--- 11,15 ----
# we don't want to use it in wrapper-related utilities (such as
# tcpdmatch) that include this file.
#CPPFLAGS+=-DPARANOID
+
+ CPPFLAGS+=-Dss_family=__ss_family -Dss_len=__ss_len -DINET6
Index: fix_options.c
===================================================================
RCS file: /cvsroot/kame/kame/netbsd/lib/libwrap/fix_options.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** fix_options.c 1999/08/11 08:16:05 1.1.1.1
--- fix_options.c 1999/08/11 14:15:07 1.2
***************
*** 40,45 ****
--- 40,56 ----
struct protoent *ip;
int fd = request->fd;
int len = sizeof lbuf;
+ struct sockaddr_storage ss;
+ int sslen;
+
+ /* check if this is AF_INET socket */
+ 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;
if ((ip = getprotobyname("ip")) != 0)
ipproto = ip->p_proto;
Index: hosts_access.c
===================================================================
RCS file: /cvsroot/kame/kame/netbsd/lib/libwrap/hosts_access.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -c -r1.1.1.1 -r1.3
*** hosts_access.c 1999/08/11 08:16:05 1.1.1.1
--- hosts_access.c 1999/08/11 14:34:41 1.3
***************
*** 46,51 ****
--- 46,54 ----
#include <netgroup.h>
#include <rpcsvc/ypclnt.h>
#endif
+ #ifdef INET6
+ #include <sys/socket.h>
+ #endif
extern int errno;
***************
*** 96,101 ****
--- 99,107 ----
static int rbl_match __P((char *, char *));
static int string_match __P((char *, char *));
static int masked_match __P((char *, char *, char *));
+ #ifdef INET6
+ static int masked_match6 __P((char *, char *, char *));
+ #endif
/* Size of logical line buffer. */
***************
*** 201,206 ****
--- 207,213 ----
int (*match_fn) __P((char *, struct request_info *));
{
char *tok;
+ int l;
/*
* Process tokens one at a time. We have exhausted all possible matches
***************
*** 212,217 ****
--- 219,229 ----
for (tok = strtok(list, sep); tok != 0; tok = strtok((char *) 0, sep)) {
if (STR_EQ(tok, "EXCEPT")) /* EXCEPT: give up */
return (NO);
+ l = strlen(tok);
+ if (*tok == '[' && tok[l - 1] == ']') {
+ tok[l - 1] = '\0';
+ tok++;
+ }
if (match_fn(tok, request)) { /* YES: look for exceptions */
while ((tok = strtok((char *) 0, sep)) && STR_NE(tok, "EXCEPT"))
/* VOID */ ;
***************
*** 289,295 ****
} else if (strncmp(tok, "{RBL}.", 6) == 0) { /* RBL lookup in domain */
return rbl_match(tok+6, eval_hostaddr(host));
} else if ((mask = split_at(tok, '/')) != 0) { /* net/mask */
! return (masked_match(tok, mask, eval_hostaddr(host)));
} else { /* anything else */
return (string_match(tok, eval_hostaddr(host))
|| (NOT_INADDR(tok) && string_match(tok, eval_hostname(host))));
--- 301,308 ----
} else if (strncmp(tok, "{RBL}.", 6) == 0) { /* RBL lookup in domain */
return rbl_match(tok+6, eval_hostaddr(host));
} else if ((mask = split_at(tok, '/')) != 0) { /* net/mask */
! return (masked_match(tok, mask, eval_hostaddr(host))
! || masked_match6(tok, mask, eval_hostaddr(host)));
} else { /* anything else */
return (string_match(tok, eval_hostaddr(host))
|| (NOT_INADDR(tok) && string_match(tok, eval_hostname(host))));
***************
*** 380,382 ****
--- 393,439 ----
}
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;
+ struct in6_addr mask;
+ struct in6_addr addr;
+ int masklen;
+ int fail;
+ int i;
+
+ if (inet_pton(AF_INET6, string, &addr) != 1)
+ return (NO);
+ fail = 0;
+ if (inet_pton(AF_INET6, net_tok, &net) != 1)
+ fail++;
+ if (strchr(mask_tok, ':') == NULL) {
+ masklen = atoi(mask_tok);
+ if (0 <= masklen && masklen <= 128) {
+ memset(&mask, 0, sizeof(mask));
+ memset(&mask, 0xff, masklen / 8);
+ if (masklen % 8) {
+ ((u_char *)&mask)[masklen / 8] =
+ (0xff00 >> (masklen % 8)) & 0xff;
+ }
+ } else
+ fail++;
+ } else {
+ if (inet_pton(AF_INET6, mask_tok, &mask) != 1)
+ fail++;
+ }
+ if (fail) {
+ tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok);
+ return (NO); /* not tcpd_jump() */
+ }
+
+ for (i = 0; i < sizeof(addr); i++)
+ addr.s6_addr[i] &= mask.s6_addr[i];
+ return (memcmp(&addr, &net, sizeof(addr)) == 0);
+ }
+ #endif
Index: misc.c
===================================================================
RCS file: /cvsroot/kame/kame/netbsd/lib/libwrap/misc.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** misc.c 1999/08/11 08:16:05 1.1.1.1
--- misc.c 1999/08/11 14:15:08 1.2
***************
*** 61,71 ****
--- 61,96 ----
char *string;
int delimiter;
{
+ #if 0
char *cp;
if ((cp = strchr(string, delimiter)) != 0)
*cp++ = 0;
return (cp);
+ #else
+ char *cp;
+ int bracket;
+
+ 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;
+ return cp;
+ #endif
}
/* dot_quad_addr - convert dotted quad to internal form */
Index: rfc931.c
===================================================================
RCS file: /cvsroot/kame/kame/netbsd/lib/libwrap/rfc931.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -c -r1.1.1.1 -r1.3
*** rfc931.c 1999/08/11 08:16:06 1.1.1.1
--- rfc931.c 1999/08/11 14:15:08 1.3
***************
*** 80,104 ****
/* rfc931 - return remote user name, given socket structures */
void rfc931(rmt_sin, our_sin, dest)
! struct sockaddr_in *rmt_sin;
! struct sockaddr_in *our_sin;
char *dest;
{
unsigned rmt_port;
unsigned our_port;
! struct sockaddr_in rmt_query_sin;
! struct sockaddr_in our_query_sin;
char user[256]; /* XXX */
char buffer[512]; /* XXX */
char *cp;
char *result = unknown;
FILE *fp;
#ifdef __GNUC__
(void)&result; /* Avoid longjmp clobbering */
(void)&fp; /* XXX gcc */
#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
--- 80,126 ----
/* rfc931 - return remote user name, given socket structures */
void rfc931(rmt_sin, our_sin, dest)
! struct sockaddr *rmt_sin;
! struct sockaddr *our_sin;
char *dest;
{
unsigned rmt_port;
unsigned our_port;
! struct sockaddr_storage rmt_query_sin;
! struct sockaddr_storage our_query_sin;
char user[256]; /* XXX */
char buffer[512]; /* XXX */
char *cp;
char *result = unknown;
FILE *fp;
+ int salen;
+ u_short *rmt_portp;
+ u_short *our_portp;
#ifdef __GNUC__
(void)&result; /* Avoid longjmp clobbering */
(void)&fp; /* XXX gcc */
#endif
+ /* address family must be the same */
+ if (rmt_sin->sa_family != our_sin->sa_family) {
+ STRN_CPY(dest, result, STRING_LENGTH);
+ return;
+ }
+ switch (rmt_sin->sa_family) {
+ case AF_INET:
+ salen = sizeof(struct sockaddr_in);
+ break;
+ #ifdef INET6
+ case AF_INET6:
+ salen = sizeof(struct sockaddr_in6);
+ break;
+ #endif
+ default:
+ STRN_CPY(dest, result, STRING_LENGTH);
+ return;
+ }
+
/*
* 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
***************
*** 109,115 ****
* sockets.
*/
! if ((fp = fsocket(AF_INET, SOCK_STREAM, 0)) != 0) {
setbuf(fp, (char *) 0);
/*
--- 131,137 ----
* sockets.
*/
! if ((fp = fsocket(rmt_sin->sa_family, SOCK_STREAM, 0)) != 0) {
setbuf(fp, (char *) 0);
/*
***************
*** 129,143 ****
* addresses from the query socket.
*/
! our_query_sin = *our_sin;
! our_query_sin.sin_port = htons(ANY_PORT);
! rmt_query_sin = *rmt_sin;
! rmt_query_sin.sin_port = htons(RFC931_PORT);
if (bind(fileno(fp), (struct sockaddr *) & our_query_sin,
! sizeof(our_query_sin)) >= 0 &&
connect(fileno(fp), (struct sockaddr *) & rmt_query_sin,
! sizeof(rmt_query_sin)) >= 0) {
/*
* Send query to server. Neglect the risk that a 13-byte
--- 151,185 ----
* addresses from the query socket.
*/
! memcpy(&our_query_sin, our_sin, salen);
! switch (our_query_sin.ss_family) {
! case AF_INET:
! our_portp = &((struct sockaddr_in *)&our_query_sin)->sin_port;
! break;
! #ifdef INET6
! case AF_INET6:
! our_portp = &((struct sockaddr_in6 *)&our_query_sin)->sin6_port;
! break;
! #endif
! }
! *rmt_portp = htons(ANY_PORT);
! memcpy(&rmt_query_sin, rmt_sin, salen);
! switch (rmt_query_sin.ss_family) {
! case AF_INET:
! rmt_portp = &((struct sockaddr_in *)&rmt_query_sin)->sin_port;
! break;
! #ifdef INET6
! case AF_INET6:
! rmt_portp = &((struct sockaddr_in6 *)&rmt_query_sin)->sin6_port;
! break;
! #endif
! }
! *rmt_portp = htons(RFC931_PORT);
if (bind(fileno(fp), (struct sockaddr *) & our_query_sin,
! salen) >= 0 &&
connect(fileno(fp), (struct sockaddr *) & rmt_query_sin,
! salen) >= 0) {
/*
* Send query to server. Neglect the risk that a 13-byte
***************
*** 146,153 ****
*/
fprintf(fp, "%u,%u\r\n",
! ntohs(rmt_sin->sin_port),
! ntohs(our_sin->sin_port));
fflush(fp);
/*
--- 188,195 ----
*/
fprintf(fp, "%u,%u\r\n",
! ntohs(*rmt_portp),
! ntohs(*our_portp));
fflush(fp);
/*
***************
*** 161,168 ****
&& ferror(fp) == 0 && feof(fp) == 0
&& sscanf(buffer, "%u , %u : USERID :%*[^:]:%255s",
&rmt_port, &our_port, user) == 3
! && ntohs(rmt_sin->sin_port) == rmt_port
! && ntohs(our_sin->sin_port) == our_port) {
/*
* Strip trailing carriage return. It is part of the
--- 203,210 ----
&& ferror(fp) == 0 && feof(fp) == 0
&& sscanf(buffer, "%u , %u : USERID :%*[^:]:%255s",
&rmt_port, &our_port, user) == 3
! && ntohs(*rmt_portp) == rmt_port
! && ntohs(*our_portp) == our_port) {
/*
* Strip trailing carriage return. It is part of the
Index: socket.c
===================================================================
RCS file: /cvsroot/kame/kame/netbsd/lib/libwrap/socket.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -c -r1.1.1.1 -r1.3
*** socket.c 1999/08/11 08:16:06 1.1.1.1
--- socket.c 1999/08/11 14:15:08 1.3
***************
*** 81,88 ****
void sock_host(request)
struct request_info *request;
{
! static struct sockaddr_in client;
! static struct sockaddr_in server;
int len;
char buf[BUFSIZ];
int fd = request->fd;
--- 81,88 ----
void sock_host(request)
struct request_info *request;
{
! static struct sockaddr_storage client;
! static struct sockaddr_storage server;
int len;
char buf[BUFSIZ];
int fd = request->fd;
***************
*** 96,101 ****
--- 96,103 ----
* really should verify that client.sin_family gets the value AF_INET,
* but this program has already caused too much grief on systems with
* broken library code.
+ *
+ * XXX the last sentence is untrue as we support AF_INET6 as well :-)
*/
len = sizeof(client);
***************
*** 111,117 ****
memset(buf, 0 sizeof(buf));
#endif
}
! request->client->sin = &client;
/*
* Determine the server binding. This is used for client username
--- 113,119 ----
memset(buf, 0 sizeof(buf));
#endif
}
! request->client->sin = (struct sockaddr *)&client;
/*
* Determine the server binding. This is used for client username
***************
*** 124,130 ****
tcpd_warn("getsockname: %m");
return;
}
! request->server->sin = &server;
}
/* sock_hostaddr - map endpoint address to printable form */
--- 126,132 ----
tcpd_warn("getsockname: %m");
return;
}
! request->server->sin = (struct sockaddr *)&server;
}
/* sock_hostaddr - map endpoint address to printable form */
***************
*** 132,141 ****
void sock_hostaddr(host)
struct host_info *host;
{
! struct sockaddr_in *sin = host->sin;
! if (sin != 0)
! STRN_CPY(host->addr, inet_ntoa(sin->sin_addr), sizeof(host->addr));
}
/* sock_hostname - map endpoint address to host name */
--- 134,159 ----
void sock_hostaddr(host)
struct host_info *host;
{
! struct sockaddr *sa = host->sin;
! int salen;
! if (!sa)
! return;
! switch (sa->sa_family) {
! case AF_INET:
! salen = sizeof(struct sockaddr_in);
! break;
! #ifdef INET6
! case AF_INET6:
! salen = sizeof(struct sockaddr_in6);
! break;
! #endif
! default:
! salen = sizeof(struct sockaddr);
! break;
! }
! getnameinfo(sa, salen, host->addr, sizeof(host->addr), NULL, 0,
! NI_NUMERICHOST);
}
/* sock_hostname - map endpoint address to host name */
***************
*** 143,151 ****
void sock_hostname(host)
struct host_info *host;
{
! struct sockaddr_in *sin = host->sin;
struct hostent *hp;
int i;
/*
* On some systems, for example Solaris 2.3, gethostbyaddr(0.0.0.0) does
--- 161,172 ----
void sock_hostname(host)
struct host_info *host;
{
! struct sockaddr *sin = host->sin;
struct hostent *hp;
int i;
+ int af, alen;
+ char *ap;
+ char hbuf[MAXHOSTNAMELEN];
/*
* On some systems, for example Solaris 2.3, gethostbyaddr(0.0.0.0) does
***************
*** 154,162 ****
* have to special-case 0.0.0.0, in order to avoid false alerts from the
* host name/address checking code below.
*/
! if (sin != 0 && sin->sin_addr.s_addr != 0
! && (hp = gethostbyaddr((char *) &(sin->sin_addr),
! sizeof(sin->sin_addr), AF_INET)) != 0) {
STRN_CPY(host->name, hp->h_name, sizeof(host->name));
--- 175,200 ----
* have to special-case 0.0.0.0, in order to avoid false alerts from the
* host name/address checking code below.
*/
! if (!sin)
! return;
! switch (af = sin->sa_family) {
! case AF_INET:
! if (((struct sockaddr_in *)sin)->sin_addr.s_addr == 0)
! return;
! ap = (char *)&((struct sockaddr_in *)sin)->sin_addr;
! alen = sizeof(struct in_addr);
! break;
! #ifdef INET6
! case AF_INET6:
! /* XXX more special cases? */
! ap = (char *)&((struct sockaddr_in6 *)sin)->sin6_addr;
! alen = sizeof(struct in6_addr);
! break;
! #endif
! defalut:
! return;
! }
! if ((hp = gethostbyaddr(ap, alen, af)) != 0) {
STRN_CPY(host->name, hp->h_name, sizeof(host->name));
***************
*** 173,179 ****
* we're in big trouble anyway.
*/
! if ((hp = gethostbyname(host->name)) == 0) {
/*
* Unable to verify that the host name matches the address. This
--- 211,217 ----
* we're in big trouble anyway.
*/
! if ((hp = gethostbyname2(host->name, af)) == 0) {
/*
* Unable to verify that the host name matches the address. This
***************
*** 205,213 ****
*/
for (i = 0; hp->h_addr_list[i]; i++) {
! if (memcmp(hp->h_addr_list[i],
! (char *) &sin->sin_addr,
! sizeof(sin->sin_addr)) == 0)
return; /* name is good, keep it */
}
--- 243,249 ----
*/
for (i = 0; hp->h_addr_list[i]; i++) {
! if (memcmp(hp->h_addr_list[i], (char *) ap, alen) == 0)
return; /* name is good, keep it */
}
***************
*** 218,224 ****
*/
tcpd_warn("host name/address mismatch: %s != %s",
! inet_ntoa(sin->sin_addr), hp->h_name);
}
/* name is bad, clobber it */
(void)strncpy(host->name, paranoid, sizeof(host->name) - 1);
--- 254,260 ----
*/
tcpd_warn("host name/address mismatch: %s != %s",
! inet_ntop(af, ap, hbuf, sizeof(hbuf)), hp->h_name);
}
/* name is bad, clobber it */
(void)strncpy(host->name, paranoid, sizeof(host->name) - 1);
***************
*** 231,237 ****
int fd;
{
char buf[BUFSIZ];
! struct sockaddr_in sin;
int size = sizeof(sin);
/*
--- 267,273 ----
int fd;
{
char buf[BUFSIZ];
! struct sockaddr_storage sin;
int size = sizeof(sin);
/*
Index: tcpd.h
===================================================================
RCS file: /cvsroot/kame/kame/netbsd/lib/libwrap/tcpd.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** tcpd.h 1999/08/11 08:16:06 1.1.1.1
--- tcpd.h 1999/08/11 12:18:16 1.2
***************
*** 12,18 ****
struct host_info {
char name[STRING_LENGTH]; /* access via eval_hostname(host) */
char addr[STRING_LENGTH]; /* access via eval_hostaddr(host) */
! struct sockaddr_in *sin; /* socket address or 0 */
struct t_unitdata *unit; /* TLI transport address or 0 */
struct request_info *request; /* for shared information */
};
--- 12,18 ----
struct host_info {
char name[STRING_LENGTH]; /* access via eval_hostname(host) */
char addr[STRING_LENGTH]; /* access via eval_hostaddr(host) */
! struct sockaddr *sin; /* socket address or 0 */
struct t_unitdata *unit; /* TLI transport address or 0 */
struct request_info *request; /* for shared information */
};
***************
*** 81,87 ****
extern char *percent_x /* do %<char> expansion */
__P((char *, int, char *, struct request_info *));
extern void rfc931 /* client name from RFC 931 daemon */
! __P((struct sockaddr_in *, struct sockaddr_in *, char *));
extern void clean_exit /* clean up and exit */
__P((struct request_info *));
extern void refuse /* clean up and exit */
--- 81,87 ----
extern char *percent_x /* do %<char> expansion */
__P((char *, int, char *, struct request_info *));
extern void rfc931 /* client name from RFC 931 daemon */
! __P((struct sockaddr *, struct sockaddr *, char *));
extern void clean_exit /* clean up and exit */
__P((struct request_info *));
extern void refuse /* clean up and exit */
Index: update.c
===================================================================
RCS file: /cvsroot/kame/kame/netbsd/lib/libwrap/update.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** update.c 1999/08/11 08:16:06 1.1.1.1
--- update.c 1999/08/11 12:18:17 1.2
***************
*** 56,65 ****
request->fd = va_arg(ap, int);
continue;
case RQ_CLIENT_SIN:
! request->client->sin = va_arg(ap, struct sockaddr_in *);
continue;
case RQ_SERVER_SIN:
! request->server->sin = va_arg(ap, struct sockaddr_in *);
continue;
/*
--- 56,65 ----
request->fd = va_arg(ap, int);
continue;
case RQ_CLIENT_SIN:
! request->client->sin = va_arg(ap, struct sockaddr *);
continue;
case RQ_SERVER_SIN:
! request->server->sin = va_arg(ap, struct sockaddr *);
continue;
/*
Index: workarounds.c
===================================================================
RCS file: /cvsroot/kame/kame/netbsd/lib/libwrap/workarounds.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** workarounds.c 1999/08/11 08:16:06 1.1.1.1
--- workarounds.c 1999/08/11 14:15:09 1.2
***************
*** 141,150 ****
if ((ret = recvfrom(sock, buf, buflen, flags, from, fromlen)) >= 0) {
if (from->sa_family == 0) {
! struct sockaddr my_addr;
int my_addr_len = sizeof(my_addr);
! if (getsockname(0, &my_addr, &my_addr_len)) {
tcpd_warn("getsockname: %m");
} else {
from->sa_family = my_addr.sa_family;
--- 141,150 ----
if ((ret = recvfrom(sock, buf, buflen, flags, from, fromlen)) >= 0) {
if (from->sa_family == 0) {
! struct sockaddr_storage my_addr;
int my_addr_len = sizeof(my_addr);
! if (getsockname(0, (struct sockaddr *)&my_addr, &my_addr_len)) {
tcpd_warn("getsockname: %m");
} else {
from->sa_family = my_addr.sa_family;
------- =_aaaaaaaaaa0--