--- ip6utils.h | 2 + rfc931.c | 101 +++++++++++++++++++++++++++++++++++++++---------------------- scaffold.c | 9 +---- socket.c | 14 +------- tcpd.h | 8 +--- update.c | 4 +- 6 files changed, 76 insertions(+), 62 deletions(-) Index: tcp_wrappers_7.6/ip6utils.h =================================================================== --- tcp_wrappers_7.6.orig/ip6utils.h +++ tcp_wrappers_7.6/ip6utils.h @@ -1,6 +1,8 @@ #ifndef IP6UTILS_H #define IP6UTILS_H +#include + /* inet_pton_mapped() - works like inet_pton(3) but always returns IPv6 address in dst - either "real" or v4mapped (::ffff:1.2.3.4) in Index: tcp_wrappers_7.6/rfc931.c =================================================================== --- tcp_wrappers_7.6.orig/rfc931.c +++ tcp_wrappers_7.6/rfc931.c @@ -65,28 +65,69 @@ int sig; siglongjmp(timebuf, sig); } +static inline unsigned int +sockaddr_len(const struct sockaddr_storage *ap) +{ + switch (ap->ss_family) { + case AF_INET: + return sizeof(struct sockaddr_in); + + case AF_INET6: + return sizeof(struct sockaddr_in6); + + } + + return 0; +} + +static inline unsigned short +sockaddr_port(const struct sockaddr_storage *ap) +{ + unsigned short num; + + switch (ap->ss_family) { + case AF_INET: + num = ((const struct sockaddr_in *) ap)->sin_port; + break; + case AF_INET6: + num = ((const struct sockaddr_in6 *) ap)->sin6_port; + break; + default: + num = 0; + break; + } + + return ntohs(num); +} + +static inline void +sockaddr_set_port(struct sockaddr_storage *ap, unsigned short port) +{ + unsigned short num = htons(port); + + switch (ap->ss_family) { + case AF_INET: + ((struct sockaddr_in *) ap)->sin_port = num; + break; + case AF_INET6: + ((struct sockaddr_in6 *) ap)->sin6_port = num; + break; + } +} + + /* 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 +struct sockaddr_storage *rmt_sin; +struct sockaddr_storage *our_sin; 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; @@ -97,18 +138,13 @@ char *dest; #ifdef INET6 /* address family must be the same */ - if (rmt_sin->sa_family != our_sin->sa_family) { + if (rmt_sin->ss_family != our_sin->ss_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: + + alen = sockaddr_len(our_sin); + if (alen == 0) { STRN_CPY(dest, result, STRING_LENGTH); return; } @@ -125,7 +161,7 @@ char *dest; */ #ifdef INET6 - if ((fp = fsocket(our_sin->sa_family, SOCK_STREAM, 0)) != 0) { + if ((fp = fsocket(our_sin->ss_family, SOCK_STREAM, 0)) != 0) { #else if ((fp = fsocket(AF_INET, SOCK_STREAM, 0)) != 0) { #endif @@ -154,18 +190,11 @@ char *dest; */ #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; - } + our_query_sin = *our_sin; + sockaddr_set_port(&our_query_sin, ANY_PORT); + + rmt_query_sin = *rmt_sin; + sockaddr_set_port(&rmt_query_sin, RFC931_PORT); if (bind(fileno(fp), (struct sockaddr *) & our_query_sin, alen) >= 0 && @@ -191,8 +220,8 @@ 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)); + sockaddr_port(rmt_sin), + sockaddr_port(our_sin)); #else ntohs(rmt_sin->sin_port), ntohs(our_sin->sin_port)); Index: tcp_wrappers_7.6/scaffold.c =================================================================== --- tcp_wrappers_7.6.orig/scaffold.c +++ tcp_wrappers_7.6/scaffold.c @@ -336,13 +336,8 @@ struct request_info *request; /* ARGSUSED */ void rfc931(rmt_sin, our_sin, dest) -#ifndef INET6 -struct sockaddr_in *rmt_sin; -struct sockaddr_in *our_sin; -#else -struct sockaddr *rmt_sin; -struct sockaddr *our_sin; -#endif +struct sockaddr_storage *rmt_sin; +struct sockaddr_storage *our_sin; char *dest; { strcpy(dest, unknown); Index: tcp_wrappers_7.6/tcpd.h =================================================================== --- tcp_wrappers_7.6.orig/tcpd.h +++ tcp_wrappers_7.6/tcpd.h @@ -19,11 +19,7 @@ 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 sockaddr_storage *sin; /* socket address or 0 */ struct t_unitdata *unit; /* TLI transport address or 0 */ struct request_info *request; /* for shared information */ }; @@ -86,7 +82,7 @@ extern void fromhost(); /* get/validat extern int hosts_access(struct request_info *); extern void shell_cmd(char *); extern char *percent_x(char *, int, char *, struct request_info *); -extern void rfc931(struct sockaddr *, struct sockaddr *, char *); +extern void rfc931(struct sockaddr_storage *, struct sockaddr_storage *, char *); extern void clean_exit(struct request_info *); extern void refuse(struct request_info *); extern char *xgets(char *, int, FILE *); Index: tcp_wrappers_7.6/socket.c =================================================================== --- tcp_wrappers_7.6.orig/socket.c +++ tcp_wrappers_7.6/socket.c @@ -116,11 +116,7 @@ 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 @@ -133,11 +129,7 @@ struct request_info *request; tcpd_warn("getsockname: %m"); return; } -#ifdef INET6 - request->server->sin = (struct sockaddr *)&server; -#else request->server->sin = &server; -#endif } @@ -180,7 +172,7 @@ struct request_info *request; sock_methods(request); memcpy(&client, res->ai_addr, res->ai_addrlen); - request->client->sin = (struct sockaddr *)&client; + request->client->sin = &client; freeaddrinfo(res); request->client->name[0] = 0; @@ -193,7 +185,7 @@ void sock_hostaddr(host) struct host_info *host; { #ifdef INET6 - struct sockaddr *sin = host->sin; + struct sockaddr *sin = (struct sockaddr *) host->sin; char *ap; int alen; @@ -227,7 +219,7 @@ void sock_hostname(struct host_info *host) { struct addrinfo hints, *res, *resbase; - struct sockaddr *sa = host->sin; + struct sockaddr *sa = (struct sockaddr *) host->sin; struct sockaddr_in6 *sin6, sin6buf; int errcode; Index: tcp_wrappers_7.6/update.c =================================================================== --- tcp_wrappers_7.6.orig/update.c +++ tcp_wrappers_7.6/update.c @@ -48,14 +48,14 @@ va_list ap; continue; case RQ_CLIENT_SIN: #ifdef INET6 - request->client->sin = va_arg(ap, struct sockaddr *); + request->client->sin = va_arg(ap, struct sockaddr_storage *); #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 *); + request->server->sin = va_arg(ap, struct sockaddr_storage *); #else request->server->sin = va_arg(ap, struct sockaddr_in *); #endif