Hello community,

here is the log from the commit of package tcpd for openSUSE:Factory checked in 
at 2015-08-21 07:35:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/tcpd (Old)
 and      /work/SRC/openSUSE:Factory/.tcpd.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "tcpd"

Changes:
--------
--- /work/SRC/openSUSE:Factory/tcpd/tcpd.changes        2014-12-01 
14:00:35.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.tcpd.new/tcpd.changes   2015-08-21 
07:35:28.000000000 +0200
@@ -1,0 +2,11 @@
+Mon Jul 20 14:08:16 UTC 2015 - o...@suse.com
+
+- Fix breakage of IPv6 address handling [bsc#914527, bsc#899185]
+  Added patches:
+  tcp_wrappers_7.6-ipv6-sockaddr-storage.patch
+  tcp_wrappers_7.6-ipv6-subnet.diff
+  tcp_wrappers_7.6-ipv6-host-match.patch
+  tcp_wrappers_7.6-ipv6-mapped-v4.patch
+- Re-added static library
+
+-------------------------------------------------------------------

New:
----
  tcp_wrappers_7.6-ipv6-host-match.patch
  tcp_wrappers_7.6-ipv6-mapped-v4.patch
  tcp_wrappers_7.6-ipv6-sockaddr-storage.patch
  tcp_wrappers_7.6-ipv6-subnet.diff

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ tcpd.spec ++++++
--- /var/tmp/diff_new_pack.FUPkBy/_old  2015-08-21 07:35:29.000000000 +0200
+++ /var/tmp/diff_new_pack.FUPkBy/_new  2015-08-21 07:35:29.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package tcpd
 #
-# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,6 +17,7 @@
 
 
 %define lname  libwrap0
+
 Name:           tcpd
 Version:        7.6
 Release:        0
@@ -56,8 +57,16 @@
 Patch27:        tcp_wrappers_%{version}-fedora-bug17847.diff
 Patch28:        tcp_wrappers_7.6-implicit-decl.patch
 Patch29:        tcpd-ocloexec.patch
+Patch30:        tcp_wrappers_%{version}-ipv6-sockaddr-storage.patch
+Patch31:        tcp_wrappers_%{version}-ipv6-subnet.diff
+Patch32:        tcp_wrappers_%{version}-ipv6-host-match.patch
+Patch33:        tcp_wrappers_%{version}-ipv6-mapped-v4.patch
 BuildRequires:  linux-kernel-headers
 Provides:       nkitb:%{_sbindir}/tcpd
+# bug437293
+%ifarch ppc64
+Obsoletes:      tcpd-64bit
+%endif
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
 %description
@@ -78,6 +87,11 @@
 Group:          Development/Languages/C and C++
 Requires:       %{lname} = %{version}
 Requires:       glibc-devel
+# bug437293
+%ifarch ppc64
+Obsoletes:      tcpd-devel-64bit
+%endif
+#
 
 %description devel
 This package contains the library and header files, which are necessary
@@ -115,9 +129,13 @@
 %patch27
 %patch28
 %patch29
+%patch30 -p1
+%patch31
+%patch32 -p1
+%patch33 -p1
 
 %build
-make %{?_smp_mflags} linux CC=cc
+make %{?_smp_mflags} linux CC="cc"
 
 %install
 install -d -m 755 %{buildroot}%{_includedir}
@@ -126,6 +144,7 @@
 install -d -m 755 %{buildroot}%{_mandir}/man{1,3,5,8}
 install -d -m 755 %{buildroot}/%{_lib}
 install -m 644 ip6utils.h tcpd.h %{buildroot}%{_includedir}
+install -m 644 libwrap.a %{buildroot}/%{_libdir}
 install -m 755 safe_finger tcpd tcpdchk tcpdmatch try-from 
%{buildroot}%{_sbindir}
 install -m 644 hosts_access.3 %{buildroot}%{_mandir}/man3
 install -m 644 hosts_access.5 hosts_options.5 %{buildroot}%{_mandir}/man5
@@ -141,7 +160,7 @@
 %postun -n %{lname} -p /sbin/ldconfig
 
 %files
-%defattr(-,root,root)
+%defattr(644,root,root,755)
 %doc BLURB CHANGES DISCLAIMER README README.ipv6 README.NIS
 %doc %{_mandir}/man?/*
 %attr(755,root,root) %{_sbindir}/*
@@ -152,9 +171,10 @@
 %attr(755,root,root) /%{_lib}/libwrap.so.0*
 
 %files devel
-%defattr(-,root,root)
+%defattr(644,root,root,755)
 %{_includedir}/tcpd.h
 %{_includedir}/ip6utils.h
+%{_libdir}/libwrap.a
 %{_libdir}/libwrap.so
 
 %changelog

++++++ tcp_wrappers_7.6-ipv6-host-match.patch ++++++
---
 hosts_access.c |  271 ++++++++++++++++++++++++++++++++++-----------------------
 misc.c         |   18 +++
 tcpd.h         |    2 
 3 files changed, 183 insertions(+), 108 deletions(-)

Index: tcp_wrappers_7.6/hosts_access.c
===================================================================
--- tcp_wrappers_7.6.orig/hosts_access.c
+++ tcp_wrappers_7.6/hosts_access.c
@@ -88,6 +88,10 @@ static int server_match();
 static int client_match();
 static int host_match();
 static int string_match();
+static int masked_match();
+#ifdef INET6
+static void ipv6_mask();
+#endif
 
 /* Size of logical line buffer. */
 
@@ -293,6 +297,74 @@ struct hosts_info *host;
     return (match);
 }
 
+static inline int
+host_info_ipv6addr(const struct host_info *host, struct in6_addr *addrbuf)
+{
+  /*
+   * In some cases we don't get the sockaddr, only the addr.
+   * We use inet_pton to convert it to its binary representation
+   * and match against that.
+   */
+  if (host->sin == NULL) {
+    if (host->addr == NULL || inet_pton(AF_INET6, host->addr, addrbuf) != 1)
+      return 0;
+
+    return 1;
+  } else
+  if (host->sin->ss_family == AF_INET6) {
+    *addrbuf = ((struct sockaddr_in6 *) host->sin)->sin6_addr;
+    return 1;
+  }
+  return 0;
+}
+
+static inline int
+token_ipv6addr_and_mask(char *tok, struct in6_addr *addrbuf, unsigned int 
*maskbits)
+{
+  char *cbr;
+  char *slash;
+
+  if (*tok != '[')
+    return 0;
+
+  *maskbits = 128;
+
+  ++tok; /* now points to the beginning of the IPv6 addr string */
+  if ((cbr = strchr(tok, ']')) == NULL) {
+    tcpd_warn("bad IP6 address specification");
+    return 0;
+  }
+  *cbr++ = '\0';
+
+  /*
+   * A /nnn prefix specifies how many bits of the address we
+   * need to check. 
+   * Note, we support both [x::y/64] and [x::y]/64
+   */
+  if ((slash = strchr(tok, '/')) == NULL && *cbr == '/')
+    slash = cbr;
+
+  if (slash != NULL) {
+    int mask;
+
+    *slash++ = '\0';
+    mask = atoi(slash);
+    if (mask < 0 || mask > 128) {
+      tcpd_warn("bad IP6 prefix specification");
+      return 0;
+    }
+
+    *maskbits = mask;
+  }
+
+  if (inet_pton(AF_INET6, tok, addrbuf) != 1) {
+    tcpd_warn("bad IP6 address specification");
+    return 0;
+  }
+
+  return 1;
+}
+
 /* host_match - match host name and/or address against pattern */
 
 static int host_match(tok, host)
@@ -328,12 +400,68 @@ struct host_info *host;
     } else if (STR_EQ(tok, "LOCAL")) {         /* local: no dots in name */
        char   *name = eval_hostname(host);
        return (strchr(name, '.') == 0 && HOSTNAME_KNOWN(name));
+    } else if (tok[0] == '[') {                        /* IPv6 address */
+#ifdef INET6
+      struct in6_addr match_addr, host_addr;
+      unsigned int mask = 128;
+
+      if (!host_info_ipv6addr(host, &host_addr))
+        return (NO);
+
+      if (!token_ipv6addr_and_mask(tok, &match_addr, &mask))
+        return (NO);
+
+      /*
+       * Zero the bits we're not interested in in both addresses
+       * then compare.  Note that we take a copy of the host info
+       * in that case.
+       */
+      if (mask != 128) {
+       ipv6_mask(&match_addr, mask);
+       ipv6_mask(&host_addr, mask);
+      }
+      if (memcmp(&match_addr, &host_addr, sizeof(struct in6_addr)) == 0)
+       return (YES);
+#endif
+      return (NO);
+    } 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))));
+      return (string_match(tok, eval_hostaddr(host))
+           || (NOT_INADDR(tok) && string_match(tok, eval_hostname(host))));
     }
 }
 
+static int masked_match(net_tok, mask_tok, string)
+char   *net_tok;
+char   *mask_tok;
+char   *string;
+{
+    unsigned long net;
+    unsigned long mask;
+    unsigned long addr;
+ 
+    /*
+     * Disallow forms other than dotted quad: the treatment that inet_addr()
+     * gives to forms with less than four components is inconsistent with the
+     * access control language. John P. Rouillard <rou...@cs.umb.edu>.
+     */
+ 
+    if ((addr = dot_quad_addr(string)) == INADDR_NONE)
+       return (NO);
+    if ((net = dot_quad_addr(net_tok)) == INADDR_NONE
+       || ((mask = dot_quad_addr(mask_tok)) == INADDR_NONE
+           && strcmp(mask_tok, "255.255.255.255")
+           && (mask = prefix_to_netmask(mask_tok)) == INADDR_NONE
+           && strcmp(mask_tok, "32"))) {
+       /* 255.255.255.255 == INADDR_NONE, separate check needed. TJ. */
+       /* 32 == INADDR_NONE, separate check needed. philipp */
+       tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok);
+       return (NO);                            /* not tcpd_jump() */
+     }
+    return ((addr & mask) == net);
+}
+ 
 /* string_match - match string against pattern 
  * 
  * tok = data read from /etc/hosts.*
@@ -359,113 +487,14 @@ char   *string;
        return (YES);
     } else if (STR_EQ(tok, "KNOWN")) {         /* not unknown */
        return (STR_NE(string, unknown));
-    } else if (STR_EQ(tok, string))            /* exact match */
-       return (YES);
-#ifdef INET6
-    else       /* IP addresses match - not needed for IPv4 */
-    {
-       /* For simplicity we convert everything to IPv6 (or v4 mapped) */
-       struct in6_addr pat, addr;
-       int len, ret, prefixlen=128, nof_periods = 0;
-       char ch, token[INET6_ADDRSTRLEN+1], *mask, *addition;
-
-       /* If prefix was given, handle it */
-       if ((mask = split_at(tok, '/')) != 0)
-       {
-               if (strchr(mask, '.') != NULL) /* We have something
-                                                  like 255.255.0.0  */
-                {
-                  int b1, b2, b3, b4;
-                  uint32_t netmask;
-
-                  if (sscanf(mask, "%d.%d.%d.%d", &b1, &b2, &b3, &b4) != 4)
-                  {
-                       tcpd_warn ("Wrong netmask in %s", tok);
-                       return (NO);
-                  }
-                  netmask = (((((b1 * 256) + b2) * 256) + b3) * 256) + b4;
-                  prefixlen = 0;
-                  while (netmask > 0)
-                  {
-                       ++prefixlen;
-                       netmask  <<= 1;
-                   }
-                }
-               else if (sscanf(mask, "%d", &prefixlen) != 1 || prefixlen < 0)
-               {
-                       tcpd_warn ("Wrong prefix length in %s", tok);
-                       return (NO);
-               }
-               
-               if (is_v4_string (tok))
-                       prefixlen += 96;        /* extend to v4mapped */
-
-               if (prefixlen > 128)
-               {
-                       tcpd_warn ("Prefix too long in %s", tok);
-                       return (NO);
-               }
-       }
-
-       len = strlen(tok);
-       if (tok[len - 1] == '.') {      /* prefix */
-         char *ptok = tok;
-
-         while ((ptok = strchr(ptok, '.')) != NULL){
-           nof_periods++;
-           ptok++;
-         }
-         switch(nof_periods){
-         case 1:
-           addition = "0.0.0";
-           prefixlen = 8;
-           break;
-         case 2:
-           addition = "0.0";
-           prefixlen = 16;
-           break;
-         case 3:
-           addition = "0";
-           prefixlen = 24;
-           break;
-         default: 
-           tcpd_warn ("Wrong prefix %s", tok);
-           return (NO);
-         }
-         snprintf(token, sizeof(token), "%s%s", tok, addition);
-         prefixlen += 96;      /* extend to v4mapped */
-       }       
-       else if (*tok == '[' && tok[len - 1] == ']') 
-       {
-               ch = tok[len - 1];
-                       tok[len - 1] = '\0';
-                       snprintf(token, sizeof(token), "%s", tok+1);
-                       tok[len - 1] = ch;
-       }
-       else
-               snprintf(token, sizeof(token), "%s", tok);
-       
-       memset (&pat, 0, sizeof(pat));
-       memset (&addr, 0, sizeof(addr));
-
-       if (inet_pton_mapped(AF_INET6, token, &pat) != 1)
-               return (NO);
-
-       if (inet_pton_mapped(AF_INET6, string, &addr) != 1)
-       {
-               tcpd_warn("Unable to handle client address: %s", string);
-               return (NO);
-       }
-
-       if (prefixlen < 128)
-       {
-               apply_v6_prefix (&pat, prefixlen);
-               apply_v6_prefix (&addr, prefixlen);
-       }
-
-       return (!memcmp(&pat, &addr, sizeof(struct in6_addr)));
+    } else if (tok[(n = strlen(tok)) - 1] == '.') {    /* prefix */
+       return (STRN_EQ(tok, string, n));
+    } else if ((STR_EQ(tok, "localhost") || STR_EQ(tok, 
"localhost.localdomain"))
+           && (STR_EQ(string, "localhost") || STR_EQ(string, 
"localhost.localdomain"))) {
+       return (YES); /* these localhosts are equivalent */
+    } else {                                   /* exact match */
+       return (STR_EQ(tok, string));
     }
-#endif
 }
 
 #ifndef DISABLE_WILDCARD_MATCHING
@@ -535,3 +564,29 @@ int match_pattern_ylo(const char *s, con
   /*NOTREACHED*/
 }
 #endif /* DISABLE_WILDCARD_MATCHING */
+
+#ifdef INET6
+/*
+ * Function that zeros all but the first "maskbits" bits of the IPV6 address
+ * This function can be made generic by specifying an address length as
+ * extra parameter. (So Wietse can implement 1.2.3.4/16)
+ */
+static void ipv6_mask(in6p, maskbits)
+struct in6_addr *in6p;
+int maskbits;
+{
+    unsigned char *p = (unsigned char*) in6p;
+
+    if (maskbits < 0 || maskbits >= 128)
+       return;
+
+    p += maskbits / 8;
+    maskbits %= 8;
+
+    if (maskbits != 0)
+       *p++ &= 0xff << (8 - maskbits);
+
+    while (p < (((unsigned char*) in6p)) + sizeof(*in6p))
+       *p++ = 0;
+}
+#endif
Index: tcp_wrappers_7.6/misc.c
===================================================================
--- tcp_wrappers_7.6.orig/misc.c
+++ tcp_wrappers_7.6/misc.c
@@ -107,3 +107,21 @@ char   *str;
     }
     return (runs == 4 ? inet_addr(str) : INADDR_NONE);
 }
+
+/* prefix_to_netmask - convert prefix (0-32) to netmask */
+
+unsigned long prefix_to_netmask(str)
+char   *str;
+{
+    unsigned long prefix;
+    char *endptr;
+
+    if (!isdigit(str[0]))
+       return INADDR_NONE;
+
+    prefix = strtoul(str, &endptr, 10);
+    if ((endptr == str) || (*endptr != '\0') || (prefix > 32))
+       return INADDR_NONE;
+
+    return htonl(~0UL << (32 - prefix));
+}
Index: tcp_wrappers_7.6/tcpd.h
===================================================================
--- tcp_wrappers_7.6.orig/tcpd.h
+++ tcp_wrappers_7.6/tcpd.h
@@ -88,6 +88,7 @@ extern void refuse(struct request_info *
 extern char *xgets(char *, int, FILE *);
 extern char *split_at(char *, int);
 extern unsigned long dot_quad_addr(char *);
+extern char *skip_ipv6_addrs(char *);
 #else
 extern int hosts_access();             /* access control */
 extern void shell_cmd();               /* execute shell command */
@@ -98,6 +99,7 @@ extern void refuse();                 /* clean up and
 extern char *xgets();                  /* fgets() on steroids */
 extern char *split_at();               /* strchr() and split */
 extern unsigned long dot_quad_addr();  /* restricted inet_addr() */
+extern char *skip_ipv6_addrs();
 #endif
 
 /* Global variables. */
++++++ tcp_wrappers_7.6-ipv6-mapped-v4.patch ++++++
---
 hosts_access.c |    2 +-
 socket.c       |   14 +++++++++-----
 2 files changed, 10 insertions(+), 6 deletions(-)

Index: tcp_wrappers_7.6/hosts_access.c
===================================================================
--- tcp_wrappers_7.6.orig/hosts_access.c
+++ tcp_wrappers_7.6/hosts_access.c
@@ -461,7 +461,7 @@ char   *string;
      }
     return ((addr & mask) == net);
 }
- 
+
 /* string_match - match string against pattern 
  * 
  * tok = data read from /etc/hosts.*
Index: tcp_wrappers_7.6/socket.c
===================================================================
--- tcp_wrappers_7.6.orig/socket.c
+++ tcp_wrappers_7.6/socket.c
@@ -187,24 +187,28 @@ struct host_info *host;
 #ifdef INET6
     struct sockaddr *sin = (struct sockaddr *) host->sin;
     char *ap;
-    int alen;
+    int af;
 
     if (!sin)
         return;
-    switch (sin->sa_family) {
+
+    af = sin->sa_family;
+    switch (af) {
         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);
+           if (IN6_IS_ADDR_V4MAPPED(ap)) {
+               ap = &((struct in6_addr *) ap)->s6_addr32[3];
+               af = AF_INET;
+           }
             break;
         default:
             return;
     }
     host->addr[0] = '\0';
-    inet_ntop(sin->sa_family, ap, host->addr, sizeof(host->addr));
+    inet_ntop(af, ap, host->addr, sizeof(host->addr));
 #else
     struct sockaddr_in *sin = host->sin;
 
++++++ tcp_wrappers_7.6-ipv6-sockaddr-storage.patch ++++++
---
 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 <netinet/in.h>
+
 /* 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
++++++ tcp_wrappers_7.6-ipv6-subnet.diff ++++++
--- hosts_access.c      2014/10/11 17:16:13     1.57
+++ hosts_access.c      2014/10/12 16:11:45
@@ -367,41 +367,10 @@
        /* For simplicity we convert everything to IPv6 (or v4 mapped) */
        struct in6_addr pat, addr;
        int len, ret, prefixlen=128, nof_periods = 0;
-       char ch, token[INET6_ADDRSTRLEN+1], *mask, *ptok = tok, *addition;
-       len = strlen(tok);
-       if (tok[(n = strlen(tok)) - 1] == '.') {        /* prefix */
-         while ((ptok = strchr(ptok, '.')) != NULL){
-           nof_periods++;
-           ptok++;
-         }
-         switch(nof_periods){
-         case 1:
-           addition = "0.0.0/8";
-           break;
-         case 2:
-           addition = "0.0/16";
-           break;
-         case 3:
-           addition = "0/24";
-           break;
-         default: 
-           tcpd_warn ("Wrong prefix %s", tok);
-           return (NO);
-         }
-         snprintf(token, sizeof(token), "%s%s", tok, addition);
-       }       
-       else if (*tok == '[' && tok[len - 1] == ']') 
-       {
-               ch = tok[len - 1];
-                       tok[len - 1] = '\0';
-                       snprintf(token, sizeof(token), "%s", tok+1);
-                       tok[len - 1] = ch;
-       }
-       else
-               snprintf(token, sizeof(token), "%s", tok);
-       
+       char ch, token[INET6_ADDRSTRLEN+1], *mask, *addition;
+
        /* If prefix was given, handle it */
-       if ((mask = split_at(token, '/')) != 0)
+       if ((mask = split_at(tok, '/')) != 0)
        {
                if (strchr(mask, '.') != NULL) /* We have something
                                                   like 255.255.0.0  */
@@ -428,7 +397,7 @@
                        return (NO);
                }
                
-               if (is_v4_string (token))
+               if (is_v4_string (tok))
                        prefixlen += 96;        /* extend to v4mapped */
 
                if (prefixlen > 128)
@@ -437,6 +406,44 @@
                        return (NO);
                }
        }
+
+       len = strlen(tok);
+       if (tok[len - 1] == '.') {      /* prefix */
+         char *ptok = tok;
+
+         while ((ptok = strchr(ptok, '.')) != NULL){
+           nof_periods++;
+           ptok++;
+         }
+         switch(nof_periods){
+         case 1:
+           addition = "0.0.0";
+           prefixlen = 8;
+           break;
+         case 2:
+           addition = "0.0";
+           prefixlen = 16;
+           break;
+         case 3:
+           addition = "0";
+           prefixlen = 24;
+           break;
+         default: 
+           tcpd_warn ("Wrong prefix %s", tok);
+           return (NO);
+         }
+         snprintf(token, sizeof(token), "%s%s", tok, addition);
+         prefixlen += 96;      /* extend to v4mapped */
+       }       
+       else if (*tok == '[' && tok[len - 1] == ']') 
+       {
+               ch = tok[len - 1];
+                       tok[len - 1] = '\0';
+                       snprintf(token, sizeof(token), "%s", tok+1);
+                       tok[len - 1] = ch;
+       }
+       else
+               snprintf(token, sizeof(token), "%s", tok);
        
        memset (&pat, 0, sizeof(pat));
        memset (&addr, 0, sizeof(addr));

Reply via email to