]> git.pld-linux.org Git - packages/postfix.git/blob - postfix-ipv6.patch
- one more fix: inet_interfaces=all should work with v6 enabled
[packages/postfix.git] / postfix-ipv6.patch
1 diff -Nur snapshot-20010525.nov6/IPV6_README snapshot-20010525/IPV6_README
2 --- snapshot-20010525.nov6/IPV6_README  Thu Jan  1 01:00:00 1970
3 +++ snapshot-20010525/IPV6_README       Wed Oct 17 11:38:17 2001
4 @@ -0,0 +1,33 @@
5 +$Id$
6 +
7 +                   ALPHA IPv6 patch for Postfix.
8 +
9 +       You can use IPv6 addresses in configuration file but
10 +you must enclose them with [] for example: [3ffe:902:12::10].
11 +
12 +Probably not all things work properly, yet.
13 +
14 + INFO:
15 +  - all previous versions of this patch (dated before 15 January
16 +  2000) was against postfix-19991231-pl02 with pfixtls patch
17 +  applied (see ftp://ftp.aet.tu-cottbus.de/pub/pfixtls/ for more).
18 +  All newer patches are created against clean postfix version.
19 +
20 + BUGS && PROBLEMS:
21 + - getaddrinfo call in smtp_addr_one() function doesn't always
22 +   return proper ai_addr structure (fixed).
23 + - lmtp code isn't IPv6 ready (not fixed).
24 +
25 +Please send all comments and patches to:
26 +           Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>, PLD GNU/Linux
27 +           Artur Frysiak <wiget@pld.org.pl>, PLD GNU/Linux
28 +
29 +Newest version of this patch can be found at:
30 +           http://www.misiek.eu.org/ipv6/
31 +
32 +Thanks to:
33 +- Mark Huizer <xaa@timewasters.nl>
34 +       author of first IPv6 patch for postfix
35 +- KAME Team <core@kame.net>
36 +       fixes to Mark's patch
37 +diff -ruN --exclude *.orig --exclude *~ snapshot-20010329.noipv6/makedefs snapshot-20010329/makedefs
38 diff -Nur snapshot-20010525.nov6/makedefs snapshot-20010525/makedefs
39 --- snapshot-20010525.nov6/makedefs     Tue May  1 01:16:07 2001
40 +++ snapshot-20010525/makedefs  Wed Oct 17 11:38:17 2001
41 @@ -52,6 +52,21 @@
42  SYSTEM=`(uname -s) 2>/dev/null`
43  RELEASE=`(uname -r) 2>/dev/null`
44  VERSION=`(uname -v) 2>/dev/null`
45 +if test -f /usr/include/netinet6/in6.h; then
46 +       grep __KAME__ /usr/include/netinet6/in6.h 2>&1 >/dev/null
47 +       if [ $?  = 1 ]; then
48 +               INET6=
49 +       else
50 +               if [ -f /usr/local/v6/lib/libinet6.a ]; then
51 +                       INET6=kame
52 +               else
53 +                       INET6=kame-merged
54 +               fi
55 +       fi
56 +fi
57 +if [ -z "$INET6" -a -f /usr/include/netinet/ip6.h -a -f /usr/include/linux/icmpv6.h ]; then
58 +       INET6=linux
59 +fi
60  
61  case "$VERSION" in
62   dcosx*) SYSTEM=$VERSION;;
63 @@ -276,6 +291,26 @@
64  
65  : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk}
66  
67 +case "$INET6" in
68 +kame)
69 +       CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
70 +       if test -f /usr/local/v6/lib/libinet6.a; then
71 +               SYSLIBS="$SYSLIBS -L/usr/local/v6/lib -linet6"
72 +       fi
73 +       ;;
74 +kame-merged)
75 +       CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
76 +       ;;
77 +linux)
78 +       CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family"
79 +       if test -f /usr/include/libinet6/netinet/ip6.h -a \
80 +               -f /usr/lib/libinet6.a; then 
81 +               CCARGS="$CCARGS -I/usr/include/libinet6 -DUSAGI_LIBINET6"
82 +               SYSLIBS="$SYSLIBS -linet6"
83 +       fi
84 +       ;;
85 +esac
86 +
87  export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
88  
89  sed 's/  / /g' <<EOF
90 diff -Nur snapshot-20010525.nov6/src/dns/dns_lookup.c snapshot-20010525/src/dns/dns_lookup.c
91 --- snapshot-20010525.nov6/src/dns/dns_lookup.c Sun Feb  4 19:16:20 2001
92 +++ snapshot-20010525/src/dns/dns_lookup.c      Wed Oct 17 11:38:17 2001
93 @@ -132,6 +132,9 @@
94  } DNS_REPLY;
95  
96  #define INET_ADDR_LEN  4               /* XXX */
97 +#ifdef INET6
98 +#define INET6_ADDR_LEN 16
99 +#endif
100  
101  /* dns_query - query name server and pre-parse the reply */
102  
103 @@ -337,6 +340,19 @@
104         memcpy(temp, pos, fixed->length);
105         data_len = fixed->length;
106         break;
107 +#ifdef INET6
108 +    case T_AAAA:
109 +       if (fixed->length != INET6_ADDR_LEN) {
110 +           msg_warn("extract_answer: bad IPv6 address length: %d", fixed->length);
111 +           return (0);
112 +       }
113 +       if (fixed->length > sizeof(temp))
114 +           msg_panic("dns_get_rr: length %d > DNS_NAME_LEN",
115 +                     fixed->length);
116 +       memcpy(temp, pos, fixed->length);
117 +       data_len = fixed->length;
118 +       break;
119 +#endif
120      case T_TXT:
121         data_len = MIN2(pos[0] + 1, MIN2(fixed->length + 1, sizeof(temp)));
122         for (src = pos + 1, dst = (unsigned char *) (temp);
123 diff -Nur snapshot-20010525.nov6/src/global/Makefile.in snapshot-20010525/src/global/Makefile.in
124 --- snapshot-20010525.nov6/src/global/Makefile.in       Tue Oct 16 13:15:43 2001
125 +++ snapshot-20010525/src/global/Makefile.in    Wed Oct 17 11:38:17 2001
126 @@ -19,7 +19,7 @@
127         timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
128         tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
129         flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
130 -       pfixtls.c
131 +       pfixtls.c wildcard_inet_addr.c
132  OBJS   = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
133         debug_peer.o debug_process.o defer.o deliver_completed.o \
134         deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \
135 @@ -40,7 +40,7 @@
136         timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
137         tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
138         flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
139 -       pfixtls.o
140 +       pfixtls.o wildcard_inet_addr.o
141  HDRS   = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
142         config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
143         deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \
144 @@ -56,7 +56,7 @@
145         recipient_list.h record.h resolve_clnt.h resolve_local.h \
146         rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
147         sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
148 -       mbox_conf.h mbox_open.h abounce.h pfixtls.h
149 +       mbox_conf.h mbox_open.h abounce.h pfixtls.h wildcard_inet_addr.h
150  TESTSRC        = rec2stream.c stream2rec.c recdump.c
151  WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
152         -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
153 diff -Nur snapshot-20010525.nov6/src/global/mynetworks.c snapshot-20010525/src/global/mynetworks.c
154 --- snapshot-20010525.nov6/src/global/mynetworks.c      Sun Feb 25 02:46:07 2001
155 +++ snapshot-20010525/src/global/mynetworks.c   Wed Oct 17 11:38:17 2001
156 @@ -50,6 +50,11 @@
157  #include <vstring.h>
158  #include <inet_addr_list.h>
159  #include <name_mask.h>
160 +#ifdef INET6
161 +#include <sys/socket.h>
162 +#include <netinet/in.h>
163 +#include <netdb.h>
164 +#endif
165  
166  /* Global library. */
167  
168 @@ -75,6 +80,9 @@
169  const char *mynetworks(void)
170  {
171      static VSTRING *result;
172 +#ifdef INET6
173 +    char hbuf[NI_MAXHOST];
174 +#endif
175  
176      if (result == 0) {
177         char   *myname = "mynetworks";
178 @@ -87,6 +95,9 @@
179         int     junk;
180         int     i;
181         int     mask_style;
182 +#ifdef INET6
183 +       struct sockaddr *sa;
184 +#endif
185  
186         mask_style = name_mask("mynetworks mask style", mask_styles,
187                                var_mynetworks_style);
188 @@ -96,8 +107,18 @@
189         my_mask_list = own_inet_mask_list();
190  
191         for (i = 0; i < my_addr_list->used; i++) {
192 +#ifdef INET6
193 +           sa = (struct sockaddr *)&my_addr_list->addrs[i];
194 +           if (sa->sa_family != AF_INET) {
195 +               vstring_sprintf_append(result, "XAATODOmynetworks ");
196 +               continue;
197 +           }
198 +           addr = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
199 +           mask = ntohl(((struct sockaddr_in *)&my_mask_list->addrs[i])->sin_addr.s_addr);
200 +#else
201             addr = ntohl(my_addr_list->addrs[i].s_addr);
202             mask = ntohl(my_mask_list->addrs[i].s_addr);
203 +#endif
204  
205             switch (mask_style) {
206  
207 @@ -119,8 +140,15 @@
208                     mask = IN_CLASSD_NET;
209                     shift = IN_CLASSD_NSHIFT;
210                 } else {
211 +#ifdef INET6
212 +                   if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
213 +                           NI_NUMERICHOST))
214 +                       strncpy(hbuf, "???", sizeof(hbuf));
215 +                   msg_fatal("%s: bad address class: %s", myname, hbuf);
216 +#else
217                     msg_fatal("%s: bad address class: %s",
218                               myname, inet_ntoa(my_addr_list->addrs[i]));
219 +#endif
220                 }
221                 break;
222  
223 diff -Nur snapshot-20010525.nov6/src/global/own_inet_addr.c snapshot-20010525/src/global/own_inet_addr.c
224 --- snapshot-20010525.nov6/src/global/own_inet_addr.c   Sun Feb 25 02:51:39 2001
225 +++ snapshot-20010525/src/global/own_inet_addr.c        Wed Oct 17 11:38:17 2001
226 @@ -39,6 +39,10 @@
227  #include <netinet/in.h>
228  #include <arpa/inet.h>
229  #include <string.h>
230 +#ifdef INET6
231 +#include <sys/socket.h>
232 +#include <netdb.h>
233 +#endif
234  
235  #ifdef STRCASECMP_IN_STRINGS_H
236  #include <strings.h>
237 @@ -101,10 +105,11 @@
238       */
239      else {
240         bufp = hosts = mystrdup(var_inet_interfaces);
241 -       while ((host = mystrtok(&bufp, sep)) != 0)
242 +       while ((host = mystrtok(&bufp, sep)) != 0) {
243             if (inet_addr_host(addr_list, host) == 0)
244                 msg_fatal("config variable %s: host not found: %s",
245                           VAR_INET_INTERFACES, host);
246 +       }
247         myfree(hosts);
248  
249         inet_addr_list_init(&local_addrs);
250 @@ -113,15 +118,39 @@
251             msg_fatal("could not find any active network interfaces");
252         for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) {
253             for (nlocal = 0; /* see below */ ; nlocal++) {
254 -               if (nlocal >= local_addrs.used)
255 +               if (nlocal >= local_addrs.used) {
256 +#ifdef INET6
257 +                   char hbuf[NI_MAXHOST];
258 +                   if (getnameinfo((struct sockaddr *)&addr_list->addrs[nvirtual],
259 +                       SS_LEN(addr_list->addrs[nvirtual]), hbuf,
260 +                       sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
261 +                       strncpy(hbuf, "???", sizeof(hbuf));
262 +                   msg_fatal("parameter %s: no local interface found for %s",
263 +                             VAR_INET_INTERFACES, hbuf);
264 +#else
265                     msg_fatal("parameter %s: no local interface found for %s",
266                               VAR_INET_INTERFACES,
267                               inet_ntoa(addr_list->addrs[nvirtual]));
268 +#endif
269 +               }
270 +#ifdef INET6
271 +               if (addr_list->addrs[nvirtual].ss_family == 
272 +                   local_addrs.addrs[nlocal].ss_family &&
273 +                   SS_LEN(addr_list->addrs[nvirtual]) == 
274 +                   SS_LEN(local_addrs.addrs[nlocal]) &&
275 +                   memcmp(&addr_list->addrs[nvirtual],
276 +                   &local_addrs.addrs[nlocal],
277 +                   SS_LEN(local_addrs.addrs[nlocal])) == 0) {
278 +                   inet_addr_list_append(mask_list, (struct sockaddr *)&local_masks.addrs[nlocal]);
279 +                   break;
280 +               }
281 +#else
282                 if (addr_list->addrs[nvirtual].s_addr
283                     == local_addrs.addrs[nlocal].s_addr) {
284                     inet_addr_list_append(mask_list, &local_masks.addrs[nlocal]);
285                     break;
286                 }
287 +#endif
288             }
289         }
290         inet_addr_list_free(&local_addrs);
291 @@ -131,6 +160,42 @@
292  
293  /* own_inet_addr - is this my own internet address */
294  
295 +#ifdef INET6
296 +int     own_inet_addr(struct sockaddr * addr)
297 +{
298 +    int     i;
299 +    char *p, *q;
300 +    int l;
301 +    struct sockaddr *sa;
302 +
303 +    if (addr_list.used == 0)
304 +       own_inet_addr_init(&addr_list, &mask_list);
305 +
306 +    for (i = 0; i < addr_list.used; i++) {
307 +       sa = (struct sockaddr *)&addr_list.addrs[i];
308 +       if (addr->sa_family != sa->sa_family)
309 +           continue;
310 +       switch (addr->sa_family) {
311 +       case AF_INET:
312 +           p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
313 +           q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
314 +           l = sizeof(struct in_addr);
315 +           break;
316 +       case AF_INET6:
317 +           /* XXX scope */
318 +           p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
319 +           q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
320 +           l = sizeof(struct in6_addr);
321 +           break;
322 +       default:
323 +           continue;
324 +       }
325 +       if (memcmp(p, q, l) == 0)
326 +           return (1);
327 +    }
328 +    return (0);
329 +}
330 +#else
331  int     own_inet_addr(struct in_addr * addr)
332  {
333      int     i;
334 @@ -141,8 +206,8 @@
335      for (i = 0; i < addr_list.used; i++)
336         if (addr->s_addr == addr_list.addrs[i].s_addr)
337             return (1);
338 -    return (0);
339  }
340 +#endif
341  
342  /* own_inet_addr_list - return list of addresses */
343  
344 diff -Nur snapshot-20010525.nov6/src/global/own_inet_addr.h snapshot-20010525/src/global/own_inet_addr.h
345 --- snapshot-20010525.nov6/src/global/own_inet_addr.h   Sat Feb 24 02:25:32 2001
346 +++ snapshot-20010525/src/global/own_inet_addr.h        Wed Oct 17 11:38:17 2001
347 @@ -15,11 +15,18 @@
348    * System library.
349    */
350  #include <netinet/in.h>
351 +#ifdef INET6
352 +#include <sys/socket.h>
353 +#endif
354  
355   /*
356    * External interface.
357    */
358 +#ifdef INET6
359 +extern int own_inet_addr(struct sockaddr *);
360 +#else
361  extern int own_inet_addr(struct in_addr *);
362 +#endif
363  extern struct INET_ADDR_LIST *own_inet_addr_list(void);
364  extern struct INET_ADDR_LIST *own_inet_mask_list(void);
365  
366 diff -Nur snapshot-20010525.nov6/src/global/peer_name.c snapshot-20010525/src/global/peer_name.c
367 --- snapshot-20010525.nov6/src/global/peer_name.c       Sun Jan 28 16:23:02 2001
368 +++ snapshot-20010525/src/global/peer_name.c    Wed Oct 17 11:38:17 2001
369 @@ -69,12 +69,32 @@
370  PEER_NAME *peer_name(int sock)
371  {
372      static PEER_NAME peer;
373 -    struct sockaddr_in sin;
374 -    SOCKADDR_SIZE len = sizeof(sin);
375 +    union sockunion {
376 +       struct {
377 +           u_char si_len;
378 +           u_char si_family;
379 +           u_short si_port;
380 +       } su_si;
381 +       struct sockaddr peer_un;
382 +       struct sockaddr_in peer_un4;
383 +#ifdef INET6
384 +       struct sockaddr_in6 peer_un6;
385 +#endif
386 +    } p_un;
387 +#define sun p_un.peer_un
388 +#define sin p_un.peer_un4
389 +#ifdef INET6
390 +#define sin6 p_un.peer_un6
391 +    static char hbuf[NI_MAXHOST];
392 +    static char abuf[NI_MAXHOST];
393 +#else
394      struct hostent *hp;
395 +#endif
396 +    SOCKADDR_SIZE len = sizeof(p_un);
397  
398 -    if (getpeername(sock, (struct sockaddr *) & sin, &len) == 0) {
399 -       switch (sin.sin_family) {
400 +    if (getpeername(sock, (struct sockaddr *)&p_un, &len) == 0) {
401 +       switch (p_un.peer_un.sa_family) {
402 +#ifndef INET6
403         case AF_INET:
404             peer.type = PEER_TYPE_INET;
405             hp = gethostbyaddr((char *) &(sin.sin_addr),
406 @@ -83,6 +103,24 @@
407                          hp->h_name : "unknown");
408             peer.addr = inet_ntoa(sin.sin_addr);
409             return (&peer);
410 +#else
411 +       case AF_INET:
412 +           peer.type = PEER_TYPE_INET;
413 +           if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
414 +               peer.name = "unknown";
415 +           else
416 +               peer.name = hbuf;
417 +           peer.addr = abuf;
418 +           return (&peer);
419 +       case AF_INET6:
420 +           peer.type = PEER_TYPE_INET6;
421 +           if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
422 +               peer.name = "unknown";
423 +           else
424 +               peer.name = hbuf;
425 +           peer.addr = abuf;
426 +           return (&peer);
427 +#endif
428         case AF_UNSPEC:
429         case AF_UNIX:
430             peer.type = PEER_TYPE_LOCAL;
431 diff -Nur snapshot-20010525.nov6/src/global/peer_name.h snapshot-20010525/src/global/peer_name.h
432 --- snapshot-20010525.nov6/src/global/peer_name.h       Fri Dec 11 19:55:32 1998
433 +++ snapshot-20010525/src/global/peer_name.h    Wed Oct 17 11:38:17 2001
434 @@ -22,6 +22,9 @@
435  #define PEER_TYPE_UNKNOWN      0
436  #define PEER_TYPE_INET         1
437  #define PEER_TYPE_LOCAL                2
438 +#ifdef INET6
439 +#define PEER_TYPE_INET6                3
440 +#endif
441  
442  extern PEER_NAME *peer_name(int);
443  
444 diff -Nur snapshot-20010525.nov6/src/global/resolve_local.c snapshot-20010525/src/global/resolve_local.c
445 --- snapshot-20010525.nov6/src/global/resolve_local.c   Mon Apr 26 00:05:42 1999
446 +++ snapshot-20010525/src/global/resolve_local.c        Wed Oct 17 11:38:17 2001
447 @@ -42,6 +42,7 @@
448  #include <netinet/in.h>
449  #include <arpa/inet.h>
450  #include <string.h>
451 +#include <netdb.h>
452  
453  #ifndef INADDR_NONE
454  #define INADDR_NONE 0xffffffff
455 @@ -78,7 +79,12 @@
456  {
457      char   *saved_addr = mystrdup(addr);
458      char   *dest;
459 +#ifdef INET6
460 +    struct addrinfo hints, *res, *res0;
461 +    int error;
462 +#else
463      struct in_addr ipaddr;
464 +#endif
465      int     len;
466  
467  #define RETURN(x) { myfree(saved_addr); return(x); }
468 @@ -108,9 +114,25 @@
469      if (*dest == '[' && dest[len - 1] == ']') {
470         dest++;
471         dest[len -= 2] = 0;
472 +#ifdef INET6
473 +       memset(&hints, 0, sizeof(hints));
474 +       hints.ai_family = PF_UNSPEC;
475 +       hints.ai_socktype = SOCK_DGRAM;
476 +       error = getaddrinfo(dest, NULL, &hints, &res0);
477 +       if (!error) {
478 +           for (res = res0; res; res = res->ai_next) {
479 +               if (own_inet_addr(res->ai_addr)) {
480 +                   freeaddrinfo(res0);
481 +                   RETURN(1);
482 +               }
483 +           }
484 +           freeaddrinfo(res0);
485 +       }
486 +#else
487         if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE
488             && own_inet_addr(&ipaddr))
489             RETURN(1);
490 +#endif
491      }
492  
493      /*
494 diff -Nur snapshot-20010525.nov6/src/global/wildcard_inet_addr.c snapshot-20010525/src/global/wildcard_inet_addr.c
495 --- snapshot-20010525.nov6/src/global/wildcard_inet_addr.c      Thu Jan  1 01:00:00 1970
496 +++ snapshot-20010525/src/global/wildcard_inet_addr.c   Wed Oct 17 11:38:17 2001
497 @@ -0,0 +1,82 @@
498 +/* System library. */
499 +
500 +#include <sys_defs.h>
501 +#include <netinet/in.h>
502 +#include <arpa/inet.h>
503 +#include <string.h>
504 +#ifdef INET6
505 +#include <sys/socket.h>
506 +#endif
507 +#include <netdb.h>
508 +
509 +#ifdef STRCASECMP_IN_STRINGS_H
510 +#include <strings.h>
511 +#endif
512 +
513 +/* Utility library. */
514 +
515 +#include <msg.h>
516 +#include <mymalloc.h>
517 +#include <inet_addr_list.h>
518 +#include <inet_addr_local.h>
519 +#include <inet_addr_host.h>
520 +#include <stringops.h>
521 +
522 +/* Global library. */
523 +
524 +#include <mail_params.h>
525 +#include <wildcard_inet_addr.h>
526 +
527 +/* Application-specific. */
528 +static INET_ADDR_LIST addr_list;
529 +
530 +/* wildcard_inet_addr_init - initialize my own address list */
531 +
532 +static void wildcard_inet_addr_init(INET_ADDR_LIST *addr_list)
533 +{
534 +#ifdef INET6
535 +    struct addrinfo hints, *res, *res0;
536 +    char hbuf[NI_MAXHOST];
537 +    int error;
538 +#ifdef NI_WITHSCOPEID
539 +    const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
540 +#else
541 +    const int niflags = NI_NUMERICHOST;
542 +#endif
543 +
544 +    inet_addr_list_init(addr_list);
545 +
546 +    memset(&hints, 0, sizeof(hints));
547 +    hints.ai_family = PF_UNSPEC;
548 +    hints.ai_socktype = SOCK_STREAM;
549 +    hints.ai_flags = AI_PASSIVE;
550 +    error = getaddrinfo(NULL, "0", &hints, &res0);
551 +    if (error)
552 +       msg_fatal("could not get list of wildcard addresses");
553 +    for (res = res0; res; res = res->ai_next) {
554 +       if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
555 +           continue;
556 +       if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
557 +           NULL, 0, niflags) != 0)
558 +           continue;
559 +       if (inet_addr_host(addr_list, hbuf) == 0)
560 +           continue; /* msg_fatal("config variable %s: host not found: %s",
561 +                     VAR_INET_INTERFACES, hbuf); */
562 +    }
563 +    freeaddrinfo(res0);
564 +#else
565 +    if (inet_addr_host(addr_list, "0.0.0.0") == 0)
566 +       msg_fatal("config variable %s: host not found: %s",
567 +                 VAR_INET_INTERFACES, "0.0.0.0");
568 +#endif
569 +}
570 +
571 +/* wildcard_inet_addr_list - return list of addresses */
572 +
573 +INET_ADDR_LIST *wildcard_inet_addr_list(void)
574 +{
575 +    if (addr_list.used == 0)
576 +       wildcard_inet_addr_init(&addr_list);
577 +
578 +    return (&addr_list);
579 +}
580 diff -Nur snapshot-20010525.nov6/src/global/wildcard_inet_addr.h snapshot-20010525/src/global/wildcard_inet_addr.h
581 --- snapshot-20010525.nov6/src/global/wildcard_inet_addr.h      Thu Jan  1 01:00:00 1970
582 +++ snapshot-20010525/src/global/wildcard_inet_addr.h   Wed Oct 17 11:38:17 2001
583 @@ -0,0 +1,36 @@
584 +#ifndef _WILDCARD_INET_ADDR_H_INCLUDED_
585 +#define _WILDCARD_INET_ADDR_H_INCLUDED_
586 +
587 +/*++
588 +/* NAME
589 +/*     wildcard_inet_addr_list 3h
590 +/* SUMMARY
591 +/*     grab the list of wildcard IP addresses.
592 +/* SYNOPSIS
593 +/*     #include <own_inet_addr.h>
594 +/* DESCRIPTION
595 +/* .nf
596 +/*--*/
597 +
598 + /*
599 +  * System library.
600 +  */
601 +#include <netinet/in.h>
602 +#ifdef INET6
603 +#include <sys/socket.h>
604 +#endif
605 +
606 + /*
607 +  * External interface.
608 +  */
609 +extern struct INET_ADDR_LIST *wildcard_inet_addr_list(void);
610 +
611 +/* LICENSE
612 +/* .ad
613 +/* .fi
614 +/*     foo
615 +/* AUTHOR(S)
616 +/*     Jun-ichiro itojun Hagino
617 +/*--*/
618 +
619 +#endif
620 diff -Nur snapshot-20010525.nov6/src/master/master_ent.c snapshot-20010525/src/master/master_ent.c
621 --- snapshot-20010525.nov6/src/master/master_ent.c      Tue May  1 00:45:54 2001
622 +++ snapshot-20010525/src/master/master_ent.c   Wed Oct 17 11:38:17 2001
623 @@ -284,8 +284,13 @@
624             inet_addr_host(MASTER_INET_ADDRLIST(serv), host);
625             serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
626         } else if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) {
627 +#ifdef INET6
628 +               MASTER_INET_ADDRLIST(serv) = wildcard_inet_addr_list();
629 +               serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
630 +#else
631             MASTER_INET_ADDRLIST(serv) = 0;     /* wild-card */
632             serv->listen_fd_count = 1;
633 +#endif
634         } else {
635             MASTER_INET_ADDRLIST(serv) = own_inet_addr_list();  /* virtual */
636             serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
637 diff -Nur snapshot-20010525.nov6/src/master/master_listen.c snapshot-20010525/src/master/master_listen.c
638 --- snapshot-20010525.nov6/src/master/master_listen.c   Tue May  1 00:47:57 2001
639 +++ snapshot-20010525/src/master/master_listen.c        Wed Oct 17 11:43:52 2001
640 @@ -64,13 +64,22 @@
641  
642  #include "master.h"
643  
644 +#ifdef INET6
645 +#include <netdb.h>
646 +#include <stdio.h>
647 +#endif 
648 +
649  /* master_listen_init - enable connection requests */
650  
651  void    master_listen_init(MASTER_SERV *serv)
652  {
653      char   *myname = "master_listen_init";
654      char   *end_point;
655 -    int     n;
656 +    int     n,m,tmpfd;
657 +#ifdef INET6
658 +    char hbuf[NI_MAXHOST];
659 +    SOCKADDR_SIZE salen;
660 +#endif
661  
662      /*
663       * Find out what transport we should use, then create one or more
664 @@ -111,18 +120,31 @@
665             serv->listen_fd[0] =
666                 inet_listen(MASTER_INET_PORT(serv),
667                             serv->max_proc > var_proc_limit ?
668 -                           serv->max_proc : var_proc_limit, NON_BLOCKING);
669 +                           serv->max_proc : var_proc_limit, NON_BLOCKING, 1);
670             close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
671         } else {                                /* virtual or host:port */
672 -           for (n = 0; n < serv->listen_fd_count; n++) {
673 +           for (m = n = 0; n < serv->listen_fd_count; n++) {
674 +#ifdef INET6
675 +               if (getnameinfo((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n],
676 +                       SA_LEN((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n]), 
677 +                       hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) {
678 +                   strncpy(hbuf, "?????", sizeof(hbuf));
679 +               }
680 +               end_point = concatenate(hbuf, ":", MASTER_INET_PORT(serv), (char *) 0);
681 +#else
682                 end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]),
683                                    ":", MASTER_INET_PORT(serv), (char *) 0);
684 -               serv->listen_fd[n]
685 +#endif
686 +               tmpfd
687                     = inet_listen(end_point, serv->max_proc > var_proc_limit ?
688 -                            serv->max_proc : var_proc_limit, NON_BLOCKING);
689 -               close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC);
690 +                            serv->max_proc : var_proc_limit, NON_BLOCKING, 0);
691 +               if (tmpfd >= 0) {
692 +                   serv->listen_fd[m] = tmpfd;
693 +                   close_on_exec(serv->listen_fd[m++], CLOSE_ON_EXEC);
694 +               }
695                 myfree(end_point);
696             }
697 +           serv->listen_fd_count=m;
698         }
699         break;
700      default:
701 diff -Nur snapshot-20010525.nov6/src/qmgr/qmgr_message.c snapshot-20010525/src/qmgr/qmgr_message.c
702 --- snapshot-20010525.nov6/src/qmgr/qmgr_message.c      Tue Feb 27 00:49:31 2001
703 +++ snapshot-20010525/src/qmgr/qmgr_message.c   Wed Oct 17 11:38:17 2001
704 @@ -460,7 +460,11 @@
705          * every front-ent program.
706          */
707         if ((at = strrchr(recipient->address, '@')) != 0
708 +#ifdef INET6
709 +           && (at + 1)[strspn(at + 1, "[]0123456789.:abcdef")] != 0
710 +#else
711             && (at + 1)[strspn(at + 1, "[]0123456789.")] != 0
712 +#endif
713             && valid_hostname(at + 1, DONT_GRIPE) == 0) {
714             qmgr_bounce_recipient(message, recipient,
715                                   "bad host/domain syntax: \"%s\"", at + 1);
716 diff -Nur snapshot-20010525.nov6/src/smtp/Makefile.in snapshot-20010525/src/smtp/Makefile.in
717 --- snapshot-20010525.nov6/src/smtp/Makefile.in Tue Oct 16 13:15:43 2001
718 +++ snapshot-20010525/src/smtp/Makefile.in      Wed Oct 17 11:38:17 2001
719 @@ -139,6 +139,7 @@
720  smtp_connect.o: ../../include/mail_params.h
721  smtp_connect.o: ../../include/own_inet_addr.h
722  smtp_connect.o: ../../include/dns.h
723 +smtp_connect.o: ../../include/get_port.h
724  smtp_connect.o: smtp.h
725  smtp_connect.o: ../../include/argv.h
726  smtp_connect.o: ../../include/deliver_request.h
727 diff -Nur snapshot-20010525.nov6/src/smtp/smtp_addr.c snapshot-20010525/src/smtp/smtp_addr.c
728 --- snapshot-20010525.nov6/src/smtp/smtp_addr.c Sat May  5 14:55:36 2001
729 +++ snapshot-20010525/src/smtp/smtp_addr.c      Wed Oct 17 11:38:17 2001
730 @@ -112,18 +112,68 @@
731  static void smtp_print_addr(char *what, DNS_RR *addr_list)
732  {
733      DNS_RR *addr;
734 -    struct in_addr in_addr;
735 +#ifdef INET6
736 +    struct sockaddr_storage ss;
737 +#else
738 +    struct sockaddr ss;
739 +#endif
740 +    struct sockaddr_in *sin;
741 +#ifdef INET6
742 +    struct sockaddr_in6 *sin6;
743 +    char   hbuf[NI_MAXHOST];
744 +#else
745 +    char   hbuf[sizeof("255.255.255.255") + 1];
746 +#endif
747  
748      msg_info("begin %s address list", what);
749      for (addr = addr_list; addr; addr = addr->next) {
750 -       if (addr->data_len > sizeof(addr)) {
751 -           msg_warn("skipping address length %d", addr->data_len);
752 -       } else {
753 -           memcpy((char *) &in_addr, addr->data, sizeof(in_addr));
754 -           msg_info("pref %4d host %s/%s",
755 -                    addr->pref, addr->name,
756 -                    inet_ntoa(in_addr));
757 +       if (addr->class != C_IN) {
758 +           msg_warn("skipping unsupported address (class=%u)", addr->class);
759 +           continue;
760         }
761 +       switch (addr->type) {
762 +       case T_A:
763 +           if (addr->data_len != sizeof(sin->sin_addr)) {
764 +               msg_warn("skipping invalid address (AAAA, len=%u)",
765 +                   addr->data_len);
766 +               continue;
767 +           }
768 +           sin = (struct sockaddr_in *)&ss;
769 +           memset(sin, 0, sizeof(*sin));
770 +           sin->sin_family = AF_INET;
771 +#ifdef HAS_SA_LEN
772 +           sin->sin_len = sizeof(*sin);
773 +#endif
774 +           memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
775 +           break;
776 +#ifdef INET6
777 +       case T_AAAA:
778 +           if (addr->data_len != sizeof(sin6->sin6_addr)) {
779 +               msg_warn("skipping invalid address (AAAA, len=%u)",
780 +                   addr->data_len);
781 +               continue;
782 +           }
783 +           sin6 = (struct sockaddr_in6 *)&ss;
784 +           memset(sin6, 0, sizeof(*sin6));
785 +           sin6->sin6_family = AF_INET6;
786 +#ifdef HAS_SA_LEN
787 +           sin6->sin6_len = sizeof(*sin6);
788 +#endif
789 +           memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
790 +           break;
791 +#endif
792 +       default:
793 +           msg_warn("skipping unsupported address (type=%u)", addr->type);
794 +           continue;
795 +       }
796 +
797 +#ifdef INET6
798 +       (void)getnameinfo((struct sockaddr *)&ss, SS_LEN(ss),
799 +           hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
800 +#else
801 +       (void)inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
802 +#endif
803 +       msg_info("pref %4d host %s/%s", addr->pref, addr->name, hbuf);
804      }
805      msg_info("end %s address list", what);
806  }
807 @@ -133,15 +183,23 @@
808  static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
809  {
810      char   *myname = "smtp_addr_one";
811 +#ifndef INET6
812      struct in_addr inaddr;
813 -    DNS_FIXED fixed;
814      DNS_RR *addr = 0;
815      DNS_RR *rr;
816      struct hostent *hp;
817 +#else
818 +    struct addrinfo hints, *res0, *res;
819 +    int error = -1;
820 +    char *addr;
821 +    size_t addrlen;
822 +#endif
823 +    DNS_FIXED fixed;
824  
825      if (msg_verbose)
826         msg_info("%s: host %s", myname, host);
827  
828 +#ifndef INET6
829      /*
830       * Interpret a numerical name as an address.
831       */
832 @@ -194,6 +252,48 @@
833         smtp_errno = SMTP_FAIL;
834         break;
835      }
836 +#else
837 +    memset(&hints, 0, sizeof(hints));
838 +    hints.ai_family = PF_UNSPEC;
839 +    hints.ai_socktype = SOCK_STREAM;
840 +    error = getaddrinfo(host, NULL, &hints, &res0);
841 +    if (error) {
842 +       switch (error) {
843 +       case EAI_AGAIN:
844 +           smtp_errno = SMTP_RETRY;
845 +           break;
846 +       default:
847 +           vstring_sprintf(why, "[%s]: %s",host,gai_strerror(error));
848 +           smtp_errno = SMTP_FAIL;
849 +           break;
850 +       }
851 +       return (addr_list);
852 +    }
853 +    for (res = res0; res; res = res->ai_next) {
854 +       memset((char *) &fixed, 0, sizeof(fixed));
855 +       switch(res->ai_family) {
856 +       case AF_INET6:
857 +           /* XXX not scope friendly */
858 +           fixed.type = T_AAAA;
859 +           addr = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
860 +           addrlen = sizeof(struct in6_addr);
861 +           break;
862 +       case AF_INET:
863 +           fixed.type = T_A;
864 +           addr = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr;
865 +           addrlen = sizeof(struct in_addr);
866 +           break;
867 +       default:
868 +           msg_warn("%s: unknown address family %d for %s",
869 +               myname, res->ai_family, host);
870 +           continue;
871 +       }
872 +       addr_list = dns_rr_append(addr_list,
873 +           dns_rr_create(host, &fixed, pref, addr, addrlen));
874 +    }
875 +    if (res0)
876 +       freeaddrinfo(res0);
877 +#endif
878      return (addr_list);
879  }
880  
881 @@ -229,6 +329,9 @@
882      INET_ADDR_LIST *self;
883      DNS_RR *addr;
884      int     i;
885 +#ifdef INET6
886 +    struct sockaddr *sa;
887 +#endif
888  
889      /*
890       * Find the first address that lists any address that this mail system is
891 @@ -238,12 +341,36 @@
892  
893      self = own_inet_addr_list();
894      for (addr = addr_list; addr; addr = addr->next) {
895 -       for (i = 0; i < self->used; i++)
896 +       for (i = 0; i < self->used; i++) {
897 +#ifdef INET6
898 +           sa = (struct sockaddr *)&self->addrs[i];
899 +           switch(addr->type) {
900 +           case T_AAAA:
901 +               /* XXX scope */
902 +               if (sa->sa_family != AF_INET6)
903 +                   break;
904 +               if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
905 +                       addr->data, sizeof(struct in6_addr)) == 0) {
906 +                   return(addr);
907 +               }
908 +               break;
909 +           case T_A:
910 +               if (sa->sa_family != AF_INET)
911 +                   break;
912 +               if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
913 +                       addr->data, sizeof(struct in_addr)) == 0) {
914 +                   return(addr);
915 +               }
916 +               break;
917 +           }
918 +#else
919             if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
920                 if (msg_verbose)
921                     msg_info("%s: found at pref %d", myname, addr->pref);
922                 return (addr);
923             }
924 +#endif
925 +       }
926      }
927  
928      /*
929 diff -Nur snapshot-20010525.nov6/src/smtp/smtp_connect.c snapshot-20010525/src/smtp/smtp_connect.c
930 --- snapshot-20010525.nov6/src/smtp/smtp_connect.c      Tue Oct 16 13:15:43 2001
931 +++ snapshot-20010525/src/smtp/smtp_connect.c   Wed Oct 17 11:38:17 2001
932 @@ -81,6 +81,7 @@
933  /* System library. */
934  
935  #include <sys_defs.h>
936 +#include <stdlib.h>
937  #include <sys/socket.h>
938  #include <netinet/in.h>
939  #include <arpa/inet.h>
940 @@ -110,6 +111,7 @@
941  #include <inet_addr_list.h>
942  #include <iostuff.h>
943  #include <timed_connect.h>
944 +#include <get_port.h>
945  #include <stringops.h>
946  
947  /* Global library. */
948 @@ -133,19 +135,45 @@
949                                                VSTRING *why)
950  {
951      char   *myname = "smtp_connect_addr";
952 -    struct sockaddr_in sin;
953 -    int     sock;
954 +#ifdef INET6
955 +    struct sockaddr_storage ss;
956 +#else
957 +    struct sockaddr ss;
958 +#endif
959 +    struct sockaddr *sa;
960 +    struct sockaddr_in *sin;
961 +#ifdef INET6
962 +    struct sockaddr_in6 *sin6;
963 +#endif
964 +    SOCKADDR_SIZE salen;
965 +#ifdef INET6
966 +    char hbuf[NI_MAXHOST];
967 +#else
968 +    char hbuf[sizeof("255.255.255.255") + 1];
969 +#endif
970 +    int     sock = -1;
971      INET_ADDR_LIST *addr_list;
972      int     conn_stat;
973      int     saved_errno;
974      VSTREAM *stream;
975      int     ch;
976 -    unsigned long inaddr;
977 +
978 +    sa = (struct sockaddr *)&ss;
979 +    sin = (struct sockaddr_in *)&ss;
980 +#ifdef INET6
981 +    sin6 = (struct sockaddr_in6 *)&ss;
982 +#endif
983  
984      /*
985       * Sanity checks.
986       */
987 -    if (addr->data_len > sizeof(sin.sin_addr)) {
988 +#ifdef INET6
989 +    if (((addr->type==T_A) && (addr->data_len > sizeof(sin->sin_addr))) ||
990 +       ((addr->type==T_AAAA) && (addr->data_len > sizeof(sin6->sin6_addr))))
991 +#else
992 +    if (addr->data_len > sizeof(sin->sin_addr))
993 +#endif
994 +    {
995         msg_warn("%s: skip address with length %d", myname, addr->data_len);
996         smtp_errno = SMTP_RETRY;
997         return (0);
998 @@ -154,17 +182,39 @@
999      /*
1000       * Initialize.
1001       */
1002 -    memset((char *) &sin, 0, sizeof(sin));
1003 -    sin.sin_family = AF_INET;
1004 -
1005 -    if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
1006 -       msg_fatal("%s: socket: %m", myname);
1007 -
1008 +    switch (addr->type) {
1009 +#ifdef INET6
1010 +    case T_AAAA:
1011 +       memset(sin6, 0, sizeof(*sin6));
1012 +       sin6->sin6_family = AF_INET6;
1013 +       salen = sizeof(*sin6);
1014 +       break;
1015 +#endif
1016 +    default: /* T_A: */
1017 +       memset(sin, 0, sizeof(*sin));
1018 +       sin->sin_family = AF_INET;
1019 +       salen = sizeof(*sin);
1020 +       break;
1021 +    }
1022 +#ifdef HAS_SA_LEN
1023 +    sa->sa_len = salen;
1024 +#endif
1025 +    if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
1026 +       msg_warn("%s: socket: %m", myname);
1027 +                   
1028      /*
1029       * Allow the sysadmin to specify the source address, for example, as "-o
1030       * smtp_bind_address=x.x.x.x" in the master.cf file.
1031       */
1032      if (*var_smtp_bind_addr) {
1033 +#ifndef INET6
1034 +       struct sockaddr_in sin;
1035 +
1036 +       memset(&sin, 0, sizeof(sin));
1037 +       sin.sin_family = AF_INET;
1038 +#ifdef HAS_SA_LEN
1039 +       sin.sin_len = sizeof(sin);
1040 +#endif
1041         sin.sin_addr.s_addr = inet_addr(var_smtp_bind_addr);
1042         if (sin.sin_addr.s_addr == INADDR_NONE)
1043             msg_fatal("%s: bad %s parameter: %s",
1044 @@ -173,6 +223,25 @@
1045             msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr));
1046         if (msg_verbose)
1047             msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1048 +#else
1049 +       char hbufl[NI_MAXHOST];
1050 +       struct addrinfo hints, *res;
1051 +
1052 +       memset(&hints, 0, sizeof(hints));
1053 +       hints.ai_family = sa->sa_family;
1054 +       hints.ai_socktype = SOCK_STREAM;
1055 +       hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1056 +       snprintf(hbufl, sizeof(hbufl)-1, "%s", var_smtp_bind_addr);
1057 +       if (getaddrinfo(hbufl, NULL, &hints, &res) == 0) {
1058 +           (void)getnameinfo(res->ai_addr, res->ai_addrlen, hbufl,
1059 +               sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1060 +           if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1061 +               msg_warn("%s: bind %s: %m", myname, hbufl);
1062 +           freeaddrinfo(res);
1063 +           if (msg_verbose)
1064 +               msg_info("%s: bind %s", myname, hbufl);
1065 +       }
1066 +#endif
1067      }
1068  
1069      /*
1070 @@ -180,8 +249,17 @@
1071       * the mail appears to come from the "right" machine address.
1072       */
1073      else if ((addr_list = own_inet_addr_list())->used == 1) {
1074 +#ifndef INET6
1075 +       struct sockaddr_in sin;
1076 +       unsigned long inaddr;   /*XXX BAD!*/
1077 +
1078 +       memset(&sin, 0, sizeof(sin));
1079 +       sin.sin_family = AF_INET;
1080 +#ifdef HAS_SA_LEN
1081 +       sin.sin_len = sizeof(sin);
1082 +#endif
1083         memcpy((char *) &sin.sin_addr, addr_list->addrs, sizeof(sin.sin_addr));
1084 -       inaddr = ntohl(sin.sin_addr.s_addr);
1085 +       inaddr = (unsigned long)ntohl(sin.sin_addr.s_addr);
1086         if (!IN_CLASSA(inaddr)
1087             || !(((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)) {
1088             if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
1089 @@ -189,30 +267,85 @@
1090             if (msg_verbose)
1091                 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1092         }
1093 +#else
1094 +       char hbufl[NI_MAXHOST];
1095 +       struct addrinfo hints, *res = NULL, *loopback = NULL;
1096 +
1097 +       memset(&hints, 0, sizeof(hints));
1098 +       hints.ai_family = sa->sa_family;
1099 +       hints.ai_socktype = SOCK_STREAM;
1100 +       if (getaddrinfo(NULL, "0", &hints, &loopback) != 0)
1101 +           loopback = NULL;
1102 +
1103 +       /*
1104 +        * getnameinfo -> getaddrinfo loop is here so that we can
1105 +        * get rid of port.
1106 +        */
1107 +       (void)getnameinfo((struct sockaddr *)addr_list->addrs, SA_LEN((struct sockaddr *)addr_list->addrs),
1108 +           hbufl, sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1109 +       hbufl[sizeof(hbufl)-1] = 0;
1110 +       memset(&hints, 0, sizeof(hints));
1111 +       hints.ai_family = sa->sa_family;
1112 +       hints.ai_socktype = SOCK_STREAM;
1113 +       hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1114 +       if (getaddrinfo(hbufl, NULL, &hints, &res) == 0 &&
1115 +           !(res->ai_addrlen == loopback->ai_addrlen &&
1116 +             memcmp(res->ai_addr, loopback->ai_addr, res->ai_addrlen) == 0)) {
1117 +           if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1118 +               msg_warn("%s: bind %s: %m", myname, hbufl);
1119 +           if (msg_verbose)
1120 +               msg_info("%s: bind %s", myname, hbufl);
1121 +       }
1122 +       if (res)
1123 +           freeaddrinfo(res);
1124 +       if (loopback)
1125 +           freeaddrinfo(loopback);
1126 +#endif
1127      }
1128  
1129      /*
1130       * Connect to the SMTP server.
1131       */
1132 -    sin.sin_port = port;
1133 -    memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr));
1134 +    switch (addr->type) {
1135 +#ifdef INET6
1136 +    case T_AAAA:
1137 +       /* XXX scope unfriendly */
1138 +       memset(sin6, 0, sizeof(*sin6));
1139 +       sin6->sin6_port = port;
1140 +       sin6->sin6_family = AF_INET6;
1141 +       salen = sizeof(*sin6);
1142 +       memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
1143 +       inet_ntop(AF_INET6, &sin6->sin6_addr, hbuf, sizeof(hbuf));
1144 +       break;
1145 +#endif
1146 +    default: /* T_A */
1147 +       memset(sin, 0, sizeof(*sin));
1148 +       sin->sin_port = port;
1149 +       sin->sin_family = AF_INET;
1150 +       salen = sizeof(*sin);
1151 +       memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
1152 +       inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
1153 +       break;
1154 +    }
1155 +#ifdef HAS_SA_LEN
1156 +    sa->sa_len = salen;
1157 +#endif
1158  
1159      if (msg_verbose)
1160         msg_info("%s: trying: %s[%s] port %d...",
1161 -                myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port));
1162 +                myname, addr->name, hbuf, ntohs(port));
1163      if (var_smtp_conn_tmout > 0) {
1164         non_blocking(sock, NON_BLOCKING);
1165 -       conn_stat = timed_connect(sock, (struct sockaddr *) & sin,
1166 -                                 sizeof(sin), var_smtp_conn_tmout);
1167 +       conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout);
1168         saved_errno = errno;
1169         non_blocking(sock, BLOCKING);
1170         errno = saved_errno;
1171      } else {
1172 -       conn_stat = connect(sock, (struct sockaddr *) & sin, sizeof(sin));
1173 +       conn_stat = connect(sock, sa, salen);
1174      }
1175      if (conn_stat < 0) {
1176         vstring_sprintf(why, "connect to %s[%s]: %m",
1177 -                       addr->name, inet_ntoa(sin.sin_addr));
1178 +                       addr->name, hbuf);
1179         smtp_errno = SMTP_RETRY;
1180         close(sock);
1181         return (0);
1182 @@ -222,8 +355,8 @@
1183       * Skip this host if it takes no action within some time limit.
1184       */
1185      if (read_wait(sock, var_smtp_helo_tmout) < 0) {
1186 -       vstring_sprintf(why, "connect to %s[%s]: read timeout",
1187 -                       addr->name, inet_ntoa(sin.sin_addr));
1188 +       vstring_sprintf(why, "connect to %s [%s]: read timeout",
1189 +                       addr->name, hbuf);
1190         smtp_errno = SMTP_RETRY;
1191         close(sock);
1192         return (0);
1193 @@ -234,8 +367,8 @@
1194       */
1195      stream = vstream_fdopen(sock, O_RDWR);
1196      if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
1197 -       vstring_sprintf(why, "connect to %s[%s]: server dropped connection",
1198 -                       addr->name, inet_ntoa(sin.sin_addr));
1199 +       vstring_sprintf(why, "connect to %s [%s]: server dropped connection",
1200 +                       addr->name, hbuf);
1201         smtp_errno = SMTP_RETRY;
1202         vstream_fclose(stream);
1203         return (0);
1204 @@ -247,7 +380,7 @@
1205       */
1206      if (ch == '4' && var_smtp_skip_4xx_greeting) {
1207         vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1208 -                       addr->name, inet_ntoa(sin.sin_addr));
1209 +                       addr->name, hbuf);
1210         smtp_errno = SMTP_RETRY;
1211         vstream_fclose(stream);
1212         return (0);
1213 @@ -258,12 +391,12 @@
1214       */
1215      if (ch == '5' && var_smtp_skip_5xx_greeting) {
1216         vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1217 -                       addr->name, inet_ntoa(sin.sin_addr));
1218 +                       addr->name, hbuf);
1219         smtp_errno = SMTP_RETRY;
1220         vstream_fclose(stream);
1221         return (0);
1222      }
1223 -    return (smtp_session_alloc(dest, stream, addr->name, inet_ntoa(sin.sin_addr)));
1224 +    return (smtp_session_alloc(dest, stream, addr->name, hbuf));
1225  }
1226  
1227  /* smtp_connect_host - direct connection to host */
1228 @@ -273,7 +406,7 @@
1229      SMTP_SESSION *session = 0;
1230      DNS_RR *addr_list;
1231      DNS_RR *addr;
1232 -
1233 +    
1234      /*
1235       * Try each address in the specified order until we find one that works.
1236       * The addresses belong to the same A record, so we have no information
1237 @@ -380,6 +513,7 @@
1238             msg_fatal("unknown service: %s/%s", service, protocol);
1239         *portp = sp->s_port;
1240      }
1241 +
1242      return (buf);
1243  }
1244  
1245 diff -Nur snapshot-20010525.nov6/src/smtp/smtp_unalias.c snapshot-20010525/src/smtp/smtp_unalias.c
1246 --- snapshot-20010525.nov6/src/smtp/smtp_unalias.c      Thu Sep 28 19:06:09 2000
1247 +++ snapshot-20010525/src/smtp/smtp_unalias.c   Wed Oct 17 11:38:17 2001
1248 @@ -86,7 +86,11 @@
1249      if ((result = htable_find(cache, name)) == 0) {
1250         fqdn = vstring_alloc(10);
1251         if (dns_lookup_types(name, smtp_unalias_flags, (DNS_RR **) 0,
1252 -                            fqdn, (VSTRING *) 0, T_MX, T_A, 0) != DNS_OK)
1253 +                            fqdn, (VSTRING *) 0, T_MX, T_A,
1254 +#ifdef INET6
1255 +                            T_AAAA,
1256 +#endif
1257 +                            0) != DNS_OK)
1258             vstring_strcpy(fqdn, name);
1259         htable_enter(cache, name, result = vstring_export(fqdn));
1260      }
1261 diff -Nur snapshot-20010525.nov6/src/smtpd/smtpd_check.c snapshot-20010525/src/smtpd/smtpd_check.c
1262 --- snapshot-20010525.nov6/src/smtpd/smtpd_check.c      Tue Oct 16 13:15:43 2001
1263 +++ snapshot-20010525/src/smtpd/smtpd_check.c   Wed Oct 17 11:38:17 2001
1264 @@ -812,7 +812,11 @@
1265         msg_info("%s: %s", myname, name);
1266  
1267      dns_status = dns_lookup_types(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
1268 -                                 (VSTRING *) 0, T_A, T_MX, 0);
1269 +                                 (VSTRING *) 0, T_A, T_MX,
1270 +#ifdef INET6
1271 +                                 T_AAAA,
1272 +#endif
1273 +                                 0);
1274      if (dns_status != DNS_OK)
1275         return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
1276                                    "%d <%s>: %s odrzucony/rejected: Host not found",
1277 @@ -834,7 +838,11 @@
1278         msg_info("%s: %s", myname, name);
1279  
1280      dns_status = dns_lookup_types(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
1281 -                                 (VSTRING *) 0, T_A, T_MX, 0);
1282 +                                 (VSTRING *) 0, T_A, T_MX,
1283 +#ifdef INET6
1284 +                                 T_AAAA,
1285 +#endif
1286 +                                 0);
1287      if (dns_status != DNS_OK)
1288         return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
1289                                    "%d <%s>: %s odrzucony/rejected: Domain not found",
1290 @@ -1007,6 +1015,49 @@
1291  
1292  static int has_my_addr(char *host)
1293  {
1294 +#ifdef INET6
1295 +    char   *myname = "has_my_addr";
1296 +    struct addrinfo hints, *res, *res0;
1297 +    int error;
1298 +    char hbuf[NI_MAXHOST];
1299 +
1300 +    if (msg_verbose)
1301 +       msg_info("%s: host %s", myname, host);
1302 +
1303 +    /*
1304 +     * If we can't lookup the host, play safe and assume it is OK.
1305 +     */
1306 +#define YUP    1
1307 +#define NOPE   0
1308 +
1309 +    memset(&hints, 0, sizeof(hints));
1310 +    hints.ai_family = PF_UNSPEC;
1311 +    hints.ai_socktype = SOCK_DGRAM;
1312 +    error = getaddrinfo(host, NULL, &hints, &res0);
1313 +    if (error) {
1314 +       if (msg_verbose)
1315 +           msg_info("%s: host %s: %s", myname, host, gai_strerror(error));
1316 +       return (YUP);
1317 +    }
1318 +    for (res = res0; res; res = res->ai_next) {
1319 +       if (msg_verbose) {
1320 +           if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
1321 +                   NULL, 0, NI_NUMERICHOST)) {
1322 +               strncpy(hbuf, "???", sizeof(hbuf));
1323 +           }
1324 +           msg_info("%s: addr %s", myname, hbuf);
1325 +       }
1326 +       if (own_inet_addr(res->ai_addr)) {
1327 +           freeaddrinfo(res0);
1328 +           return (YUP);
1329 +       }
1330 +    }
1331 +    freeaddrinfo(res0);
1332 +    if (msg_verbose)
1333 +       msg_info("%s: host %s: no match", myname, host);
1334 +
1335 +    return (NOPE);
1336 +#else
1337      char   *myname = "has_my_addr";
1338      struct in_addr addr;
1339      char  **cpp;
1340 @@ -1042,6 +1093,7 @@
1341         msg_info("%s: host %s: no match", myname, host);
1342  
1343      return (NOPE);
1344 +#endif
1345  }
1346  
1347  /* permit_mx_backup - permit use of me as MX backup for recipient domain */
1348 @@ -1548,10 +1600,15 @@
1349      int     dns_status = DNS_FAIL;
1350      int     i;
1351      int     result;
1352 +    struct in_addr a;
1353  
1354      if (msg_verbose)
1355         msg_info("%s: %s", myname, state->addr);
1356  
1357 +    /* IPv4 only for now */
1358 +    if (inet_pton(AF_INET, state->addr, &a) != 1)
1359 +       return SMTPD_CHECK_DUNNO;
1360 +
1361      /*
1362       * IPv4 only for now
1363       */
1364 diff -Nur snapshot-20010525.nov6/src/smtpd/smtpd_peer.c snapshot-20010525/src/smtpd/smtpd_peer.c
1365 --- snapshot-20010525.nov6/src/smtpd/smtpd_peer.c       Sun Jan 28 16:24:56 2001
1366 +++ snapshot-20010525/src/smtpd/smtpd_peer.c    Wed Oct 17 11:38:17 2001
1367 @@ -63,6 +63,15 @@
1368  #include <netdb.h>
1369  #include <string.h>
1370  
1371 +/* Utility library. */
1372 +
1373 +#include <msg.h>
1374 +#include <mymalloc.h>
1375 +#include <valid_hostname.h>
1376 +#include <stringops.h>
1377 +
1378 +/* Global library. */
1379 +
1380   /*
1381    * Older systems don't have h_errno. Even modern systems don't have
1382    * hstrerror().
1383 @@ -84,16 +93,11 @@
1384      )
1385  #endif
1386  
1387 -/* Utility library. */
1388 -
1389 -#include <msg.h>
1390 -#include <mymalloc.h>
1391 -#include <valid_hostname.h>
1392 -#include <stringops.h>
1393 -
1394 -/* Global library. */
1395 -
1396 -
1397 +#ifdef INET6
1398 +#define GAI_STRERROR(error) \
1399 +       ((error = EAI_SYSTEM) ? gai_strerror(error) : strerror(errno))
1400 +#endif
1401 +       
1402  /* Application-specific. */
1403  
1404  #include "smtpd.h"
1405 @@ -102,16 +106,23 @@
1406  
1407  void    smtpd_peer_init(SMTPD_STATE *state)
1408  {
1409 -    struct sockaddr_in sin;
1410 -    SOCKADDR_SIZE len = sizeof(sin);
1411 +#ifdef INET6
1412 +    struct sockaddr_storage ss;
1413 +#else
1414 +    struct sockaddr ss;
1415 +    struct in_addr *in;
1416      struct hostent *hp;
1417 -    int     i;
1418 +#endif
1419 +    struct sockaddr *sa;
1420 +    SOCKADDR_SIZE len;
1421 +
1422 +    sa = (struct sockaddr *)&ss;
1423 +    len = sizeof(ss);
1424  
1425      /*
1426       * Look up the peer address information.
1427       */
1428 -    if (getpeername(vstream_fileno(state->client),
1429 -                   (struct sockaddr *) & sin, &len) >= 0) {
1430 +    if (getpeername(vstream_fileno(state->client), sa, &len) >= 0) {
1431         errno = 0;
1432      }
1433  
1434 @@ -128,18 +139,51 @@
1435      /*
1436       * Look up and "verify" the client hostname.
1437       */
1438 -    else if (errno == 0 && sin.sin_family == AF_INET) {
1439 -       state->addr = mystrdup(inet_ntoa(sin.sin_addr));
1440 -       hp = gethostbyaddr((char *) &(sin.sin_addr),
1441 -                          sizeof(sin.sin_addr), AF_INET);
1442 -       if (hp == 0) {
1443 +    else if (errno == 0 && (sa->sa_family == AF_INET
1444 +#ifdef INET6
1445 +                           || sa->sa_family == AF_INET6
1446 +#endif
1447 +                   )) {
1448 +#ifdef INET6
1449 +       char hbuf[NI_MAXHOST];
1450 +       char abuf[NI_MAXHOST];
1451 +       struct addrinfo hints, *rnull = NULL;
1452 +#else
1453 +       char abuf[sizeof("255.255.255.255") + 1];
1454 +       char *hbuf;
1455 +#endif
1456 +       int error = -1;
1457 +
1458 +#ifdef INET6
1459 +       (void)getnameinfo(sa, len, abuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
1460 +#else
1461 +       in = &((struct sockaddr_in *)sa)->sin_addr;
1462 +       inet_ntop(AF_INET, in, abuf, sizeof(hbuf));
1463 +#endif
1464 +       state->addr = mystrdup(abuf);
1465 +#ifdef INET6
1466 +       error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD);
1467 +#else
1468 +       hbuf = NULL;
1469 +       hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET);
1470 +       if (hp) {
1471 +           error = 0;
1472 +               hbuf = mystrdup(hp->h_name);
1473 +       } else
1474 +           error = 1;
1475 +#endif
1476 +       if (error) {
1477             state->name = mystrdup("unknown");
1478 +#ifdef INET6
1479 +               state->peer_code = (error == EAI_AGAIN ? 4 : 5);
1480 +#else
1481             state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
1482 -       } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
1483 +#endif
1484 +       } else if (!valid_hostname(hbuf, DONT_GRIPE)) {
1485             state->name = mystrdup("unknown");
1486             state->peer_code = 5;
1487         } else {
1488 -           state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */
1489 +           state->name = mystrdup(hbuf);       /* hp->name is clobbered!! */
1490             state->peer_code = 2;
1491  
1492             /*
1493 @@ -151,16 +195,31 @@
1494         state->peer_code = code; \
1495      }
1496  
1497 +#ifdef INET6
1498 +           memset(&hints, 0, sizeof(hints));
1499 +           hints.ai_family = AF_UNSPEC;
1500 +           hints.ai_socktype = SOCK_STREAM;
1501 +           error = getaddrinfo(state->name, NULL, &hints, &rnull);
1502 +           if (error) {
1503 +               msg_warn("%s: hostname %s verification failed: %s",
1504 +                        state->addr, state->name, GAI_STRERROR(error));
1505 +               REJECT_PEER_NAME(state, (error == EAI_AGAIN ? 4 : 5));
1506 +           }
1507 +           /* memcmp() isn't needed if we use getaddrinfo */
1508 +           if (rnull)
1509 +               freeaddrinfo(rnull);
1510 +#else
1511             hp = gethostbyname(state->name);    /* clobbers hp->name!! */
1512             if (hp == 0) {
1513                 msg_warn("%s: hostname %s verification failed: %s",
1514                          state->addr, state->name, HSTRERROR(h_errno));
1515                 REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ? 4 : 5));
1516 -           } else if (hp->h_length != sizeof(sin.sin_addr)) {
1517 +           } else if (hp->h_length != sizeof(*in)) {
1518                 msg_warn("%s: hostname %s verification failed: bad address size %d",
1519                          state->addr, state->name, hp->h_length);
1520                 REJECT_PEER_NAME(state, 5);
1521             } else {
1522 +               int i;
1523                 for (i = 0; /* void */ ; i++) {
1524                     if (hp->h_addr_list[i] == 0) {
1525                         msg_warn("%s: address not listed for hostname %s",
1526 @@ -168,12 +227,11 @@
1527                         REJECT_PEER_NAME(state, 5);
1528                         break;
1529                     }
1530 -                   if (memcmp(hp->h_addr_list[i],
1531 -                              (char *) &sin.sin_addr,
1532 -                              sizeof(sin.sin_addr)) == 0)
1533 +                   if (memcmp(hp->h_addr_list[i], (char *)in, sizeof(*in)) == 0)
1534                         break;                  /* keep peer name */
1535                 }
1536             }
1537 +#endif
1538         }
1539      }
1540  
1541 diff -Nur snapshot-20010525.nov6/src/smtpstone/smtp-sink.c snapshot-20010525/src/smtpstone/smtp-sink.c
1542 --- snapshot-20010525.nov6/src/smtpstone/smtp-sink.c    Thu Jan 25 01:26:07 2001
1543 +++ snapshot-20010525/src/smtpstone/smtp-sink.c Wed Oct 17 11:38:17 2001
1544 @@ -416,7 +416,7 @@
1545      } else {
1546         if (strncmp(argv[optind], "inet:", 5) == 0)
1547             argv[optind] += 5;
1548 -       sock = inet_listen(argv[optind], backlog, BLOCKING);
1549 +       sock = inet_listen(argv[optind], backlog, BLOCKING, 1);
1550      }
1551  
1552      /*
1553 diff -Nur snapshot-20010525.nov6/src/util/Makefile.in snapshot-20010525/src/util/Makefile.in
1554 --- snapshot-20010525.nov6/src/util/Makefile.in Tue Oct 16 13:15:43 2001
1555 +++ snapshot-20010525/src/util/Makefile.in      Wed Oct 17 11:38:17 2001
1556 @@ -5,6 +5,7 @@
1557         dict_nisplus.c dict_open.c dir_forest.c doze.c environ.c \
1558         events.c exec_command.c fifo_listen.c fifo_trigger.c file_limit.c \
1559         find_inet.c fsspace.c fullname.c get_domainname.c get_hostname.c \
1560 +       get_port.c \
1561         htable.c inet_addr_host.c inet_addr_list.c inet_addr_local.c \
1562         inet_connect.c inet_listen.c inet_trigger.c inet_util.c \
1563         line_wrap.c lowercase.c lstat_as.c mac_parse.c make_dirs.c \
1564 @@ -30,6 +31,7 @@
1565         dict_nisplus.o dict_open.o dir_forest.o doze.o environ.o \
1566         events.o exec_command.o fifo_listen.o fifo_trigger.o file_limit.o \
1567         find_inet.o fsspace.o fullname.o get_domainname.o get_hostname.o \
1568 +       get_port.o \
1569         htable.o inet_addr_host.o inet_addr_list.o inet_addr_local.o \
1570         inet_connect.o inet_listen.o inet_trigger.o inet_util.o \
1571         line_wrap.o lowercase.o lstat_as.o mac_parse.o make_dirs.o \
1572 @@ -53,6 +55,7 @@
1573         dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
1574         dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
1575         exec_command.h find_inet.h fsspace.h fullname.h get_domainname.h \
1576 +       get_port.h \
1577         get_hostname.h htable.h inet_addr_host.h inet_addr_list.h \
1578         inet_addr_local.h inet_util.h iostuff.h line_wrap.h listen.h lstat_as.h \
1579         mac_parse.h make_dirs.h match_list.h match_ops.h msg.h msg_output.h \
1580 @@ -590,6 +593,7 @@
1581  get_domainname.o: mymalloc.h
1582  get_domainname.o: get_hostname.h
1583  get_domainname.o: get_domainname.h
1584 +get_port.o: sys_defs.h
1585  get_hostname.o: get_hostname.c
1586  get_hostname.o: sys_defs.h
1587  get_hostname.o: mymalloc.h
1588 @@ -701,6 +705,7 @@
1589  match_list.o: stringops.h
1590  match_list.o: argv.h
1591  match_list.o: dict.h
1592 +match_list.o: inet_util.h
1593  match_list.o: match_list.h
1594  match_ops.o: match_ops.c
1595  match_ops.o: sys_defs.h
1596 diff -Nur snapshot-20010525.nov6/src/util/get_port.c snapshot-20010525/src/util/get_port.c
1597 --- snapshot-20010525.nov6/src/util/get_port.c  Thu Jan  1 01:00:00 1970
1598 +++ snapshot-20010525/src/util/get_port.c       Wed Oct 17 11:38:17 2001
1599 @@ -0,0 +1,65 @@
1600 +/*++
1601 +/* NAME
1602 +/*     get_port 3
1603 +/* SUMMARY
1604 +/*     trivial host and port extracter
1605 +/* SYNOPSIS
1606 +/*     #include <get_port.h>
1607 +/*
1608 +/*     char    *get_port(data)
1609 +/*     char    *data;
1610 +/*
1611 +/* DESCRIPTION
1612 +/*     get_port() extract host name or ip address from
1613 +/*     strings such as [3ffe:902:12::10]:25, [::1]
1614 +/*     or 192.168.0.1:25, and null-terminates the
1615 +/*     \fIdata\fR at the first occurrence of port separator.
1616 +/* DIAGNOSTICS
1617 +/*     If port not found return null pointer.
1618 +/* LICENSE
1619 +/* .ad
1620 +/* .fi
1621 +/*     BSD Style (or BSD like) license.
1622 +/* AUTHOR(S)
1623 +/*     Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1624 +/*     Wroclaw, POLAND
1625 +/*--*/
1626 +
1627 +/* System libraries */
1628 +
1629 +#include <sys_defs.h>
1630 +#include <string.h>
1631 +
1632 +/* Utility library. */
1633 +
1634 +#include "get_port.h"
1635 +
1636 +/* get_port - extract port number from string */
1637 +
1638 +char *get_port(char *data)
1639 +{
1640 +       const char *escl=strchr(data,'[');
1641 +       const char *sepl=strchr(data,':');
1642 +       char *escr=strrchr(data,']');
1643 +       char *sepr=strrchr(data,':');
1644 +
1645 +       /* extract from "[address]:port" or "[address]"*/
1646 +       if (escl && escr)
1647 +       {
1648 +               memmove(data, data + 1, strlen(data) - strlen(escr));
1649 +               data[strlen(data) - strlen(escr) - 1] = 0;
1650 +               *escr++ = 0;
1651 +               if (*escr == ':')
1652 +                       escr++;
1653 +               return (*escr ? escr : NULL);
1654 +       }
1655 +       /* extract from "address:port" or "address" */
1656 +       if ((sepl == sepr) && sepr && sepl)
1657 +       {
1658 +               *sepr++ = 0;
1659 +               return sepr;
1660 +       }
1661 +
1662 +       /* return empty string */
1663 +       return NULL;
1664 +}
1665 diff -Nur snapshot-20010525.nov6/src/util/get_port.h snapshot-20010525/src/util/get_port.h
1666 --- snapshot-20010525.nov6/src/util/get_port.h  Thu Jan  1 01:00:00 1970
1667 +++ snapshot-20010525/src/util/get_port.h       Wed Oct 17 11:38:17 2001
1668 @@ -0,0 +1,28 @@
1669 +#ifndef _GET_PORT_H_INCLUDED_
1670 +#define _GET_PORT_H_INCLUDED_
1671 +
1672 +/*++
1673 +/* NAME
1674 +/*     get_port 3h
1675 +/* SUMMARY
1676 +/*     trivial host and port extracter
1677 +/* SYNOPSIS
1678 +/*     #include <get_port.h>
1679 +/* DESCRIPTION
1680 +/* .nf
1681 +
1682 + /* External interface. */
1683 +
1684 +extern char *get_port(char *);
1685 +
1686 +
1687 +/* LICENSE
1688 +/* .ad
1689 +/* .fi
1690 +/*     BSD Style (or BSD like) license.
1691 +/* AUTHOR(S)
1692 +/*     Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1693 +/*     Wroclaw, POLAND
1694 +/*--*/
1695 +
1696 +#endif
1697 diff -Nur snapshot-20010525.nov6/src/util/inet_addr_host.c snapshot-20010525/src/util/inet_addr_host.c
1698 --- snapshot-20010525.nov6/src/util/inet_addr_host.c    Fri Dec 11 19:55:35 1998
1699 +++ snapshot-20010525/src/util/inet_addr_host.c Wed Oct 17 11:38:17 2001
1700 @@ -38,7 +38,10 @@
1701  #include <sys_defs.h>
1702  #include <netinet/in.h>
1703  #include <arpa/inet.h>
1704 +#include <sys/socket.h>
1705  #include <netdb.h>
1706 +#include <stdlib.h>
1707 +#include <string.h>
1708  
1709  #ifndef INADDR_NONE
1710  #define INADDR_NONE 0xffffffff
1711 @@ -48,15 +51,47 @@
1712  
1713  #include <inet_addr_list.h>
1714  #include <inet_addr_host.h>
1715 +#ifdef TEST
1716 +#include <msg.h>
1717 +#endif
1718  
1719  /* inet_addr_host - look up address list for host */
1720  
1721  int     inet_addr_host(INET_ADDR_LIST *addr_list, const char *hostname)
1722  {
1723 +#ifdef INET6
1724 +    int s;
1725 +    struct addrinfo hints, *res0, *res;
1726 +#ifdef TEST    
1727 +       char buforhosta[1024];
1728 +#endif 
1729 +    int error;
1730 +#else
1731      struct hostent *hp;
1732      struct in_addr addr;
1733 +#endif
1734      int     initial_count = addr_list->used;
1735  
1736 +#ifdef INET6
1737 +    memset(&hints, 0, sizeof(hints));
1738 +    hints.ai_family = PF_UNSPEC;
1739 +    hints.ai_socktype = SOCK_DGRAM;
1740 +    error = getaddrinfo(hostname, NULL, &hints, &res0);
1741 +    if (error == 0) {
1742 +       for (res = res0; res; res = res->ai_next) {
1743 +           if(res->ai_family != AF_INET && res->ai_family != AF_INET6)
1744 +               continue;
1745 +           /* filter out address families that are not supported */
1746 +           s = socket(res->ai_family, SOCK_DGRAM, 0);
1747 +           if (s < 0)
1748 +               continue;
1749 +           close(s);
1750 +
1751 +           inet_addr_list_append(addr_list, res->ai_addr);
1752 +       }
1753 +       freeaddrinfo(res0);
1754 +    }
1755 +#else
1756      if ((addr.s_addr = inet_addr(hostname)) != INADDR_NONE) {
1757         inet_addr_list_append(addr_list, &addr);
1758      } else {
1759 @@ -65,9 +100,12 @@
1760                 inet_addr_list_append(addr_list,
1761                                     (struct in_addr *) * hp->h_addr_list++);
1762      }
1763 +#endif
1764 +
1765      return (addr_list->used - initial_count);
1766  }
1767  
1768 +
1769  #ifdef TEST
1770  
1771  #include <msg.h>
1772 @@ -78,6 +116,8 @@
1773  {
1774      INET_ADDR_LIST addr_list;
1775      int     i;
1776 +    struct sockaddr *sa;
1777 +    char hbuf[NI_MAXHOST];
1778  
1779      msg_vstream_init(argv[0], VSTREAM_ERR);
1780  
1781 @@ -89,8 +129,12 @@
1782         if (inet_addr_host(&addr_list, *argv) == 0)
1783             msg_fatal("not found: %s", *argv);
1784  
1785 -       for (i = 0; i < addr_list.used; i++)
1786 -           vstream_printf("%s\n", inet_ntoa(addr_list.addrs[i]));
1787 +       for (i = 0; i < addr_list.used; i++) {
1788 +           sa = (struct sockaddr *)&addr_list.addrs[i];
1789 +           getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
1790 +                   NI_NUMERICHOST);
1791 +           vstream_printf("%s\n", hbuf);
1792 +       }
1793         vstream_fflush(VSTREAM_OUT);
1794      }
1795      inet_addr_list_free(&addr_list);
1796 diff -Nur snapshot-20010525.nov6/src/util/inet_addr_list.c snapshot-20010525/src/util/inet_addr_list.c
1797 --- snapshot-20010525.nov6/src/util/inet_addr_list.c    Mon Nov 20 19:06:30 2000
1798 +++ snapshot-20010525/src/util/inet_addr_list.c Wed Oct 17 11:38:17 2001
1799 @@ -44,6 +44,13 @@
1800  #include <netinet/in.h>
1801  #include <arpa/inet.h>
1802  
1803 +#include <netdb.h>
1804 +
1805 +#ifdef INET6
1806 +#include <string.h>
1807 +#include <sys/socket.h>
1808 +#endif
1809 +
1810  /* Utility library. */
1811  
1812  #include <msg.h>
1813 @@ -56,12 +63,39 @@
1814  {
1815      list->used = 0;
1816      list->size = 2;
1817 +#ifdef INET6
1818 +    list->addrs = (struct sockaddr_storage *)
1819 +#else
1820      list->addrs = (struct in_addr *)
1821 +#endif
1822         mymalloc(sizeof(*list->addrs) * list->size);
1823  }
1824  
1825  /* inet_addr_list_append - append address to internet address list */
1826  
1827 +#ifdef INET6
1828 +void    inet_addr_list_append(INET_ADDR_LIST *list, 
1829 +                              struct sockaddr * addr)
1830 +{
1831 +    char   *myname = "inet_addr_list_append";
1832 +    char hbuf[NI_MAXHOST];
1833 +
1834 +    if (msg_verbose > 1) {
1835 +       if (getnameinfo(addr, SA_LEN(addr), hbuf, sizeof(hbuf), NULL, 0,
1836 +           NI_NUMERICHOST)) {
1837 +           strncpy(hbuf, "??????", sizeof(hbuf));
1838 +       }
1839 +       msg_info("%s: %s", myname, hbuf);
1840 +    }
1841 +
1842 +    if (list->used >= list->size)
1843 +       list->size *= 2;
1844 +    list->addrs = (struct sockaddr_storage *)
1845 +       myrealloc((char *) list->addrs,
1846 +                 sizeof(*list->addrs) * list->size);
1847 +    memcpy(&list->addrs[list->used++], addr, SA_LEN(addr));
1848 +}
1849 +#else
1850  void    inet_addr_list_append(INET_ADDR_LIST *list, struct in_addr * addr)
1851  {
1852      char   *myname = "inet_addr_list_append";
1853 @@ -76,6 +110,7 @@
1854                   sizeof(*list->addrs) * list->size);
1855      list->addrs[list->used++] = *addr;
1856  }
1857 +#endif
1858  
1859  /* inet_addr_list_free - destroy internet address list */
1860  
1861 diff -Nur snapshot-20010525.nov6/src/util/inet_addr_list.h snapshot-20010525/src/util/inet_addr_list.h
1862 --- snapshot-20010525.nov6/src/util/inet_addr_list.h    Fri Dec 11 19:55:35 1998
1863 +++ snapshot-20010525/src/util/inet_addr_list.h Wed Oct 17 11:38:17 2001
1864 @@ -16,18 +16,37 @@
1865    */
1866  #include <netinet/in.h>
1867  
1868 +#ifndef SA_LEN
1869 +#ifndef HAS_SA_LEN
1870 +#define SA_LEN(x)       (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1871 +#define SS_LEN(x)       (((x).ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1872 +#else
1873 +#define SA_LEN(x)       ((x)->sa_len)
1874 +#define SS_LEN(x)       ((x).ss_len)
1875 +#endif
1876 +#endif
1877 +
1878   /*
1879    * External interface.
1880    */
1881  typedef struct INET_ADDR_LIST {
1882      int     used;                      /* nr of elements in use */
1883      int     size;                      /* actual list size */
1884 +#ifdef INET6
1885 +    struct sockaddr_storage *addrs;    /* payload */
1886 +#else
1887      struct in_addr *addrs;             /* payload */
1888 +#endif
1889  } INET_ADDR_LIST;
1890  
1891  extern void inet_addr_list_init(INET_ADDR_LIST *);
1892  extern void inet_addr_list_free(INET_ADDR_LIST *);
1893 +#ifdef INET6
1894 +struct sockaddr;
1895 +extern void inet_addr_list_append(INET_ADDR_LIST *, struct sockaddr *);
1896 +#else
1897  extern void inet_addr_list_append(INET_ADDR_LIST *, struct in_addr *);
1898 +#endif
1899  
1900  /* LICENSE
1901  /* .ad
1902 diff -Nur snapshot-20010525.nov6/src/util/inet_addr_local.c snapshot-20010525/src/util/inet_addr_local.c
1903 --- snapshot-20010525.nov6/src/util/inet_addr_local.c   Sun Feb 25 19:20:19 2001
1904 +++ snapshot-20010525/src/util/inet_addr_local.c        Wed Oct 17 11:38:17 2001
1905 @@ -47,6 +47,13 @@
1906  #endif
1907  #include <errno.h>
1908  #include <string.h>
1909 +#if defined(INET6) && (defined (LINUX) || defined (LINUX2))
1910 +#include <netdb.h>
1911 +#include <stdio.h>
1912 +#endif
1913 +#ifdef HAVE_GETIFADDRS
1914 +#include <ifaddrs.h>
1915 +#endif
1916  
1917  /* Utility library. */
1918  
1919 @@ -78,18 +85,98 @@
1920  
1921  int     inet_addr_local(INET_ADDR_LIST *addr_list, INET_ADDR_LIST *mask_list)
1922  {
1923 +#ifdef HAVE_GETIFADDRS
1924 +    char *myname = "inet_addr_local";
1925 +    struct ifaddrs *ifap, *ifa;
1926 +    int initial_count = addr_list->used;
1927 +    struct sockaddr *sa;
1928 +#ifdef INET6
1929 +#ifdef __KAME__
1930 +    struct sockaddr_in6 addr6;
1931 +#endif
1932 +#else
1933 +    void *addr;
1934 +#endif
1935 +
1936 +    if (getifaddrs(&ifap) < 0)
1937 +       msg_fatal("%s: getifaddrs: %m", myname);
1938 +
1939 +    for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1940 +               if (! (ifa->ifa_flags & IFF_RUNNING)) 
1941 +                       continue;
1942 +       sa = ifa->ifa_addr;
1943 +       switch (ifa->ifa_addr->sa_family) {
1944 +       case AF_INET:
1945 +#ifndef INET6
1946 +           addr = (void *)&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
1947 +#endif
1948 +           break;
1949 +#ifdef INET6
1950 +       case AF_INET6:
1951 +#ifdef __KAME__
1952 +           memcpy(&addr6, ifa->ifa_addr, ifa->ifa_addr->sa_len);
1953 +           /* decode scoped address notation */
1954 +           if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
1955 +                IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
1956 +               addr6.sin6_scope_id == 0) {
1957 +               addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
1958 +                   (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
1959 +               addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
1960 +               sa = (struct sockaddr *)&addr6;
1961 +           }
1962 +#endif
1963 +           break;
1964 +#endif
1965 +       default:
1966 +           continue;
1967 +       }
1968 +
1969 +#ifdef INET6
1970 +       inet_addr_list_append(addr_list, sa);
1971 +#else
1972 +       inet_addr_list_append(addr_list, (struct in_addr *)addr);
1973 +#endif
1974 +    }
1975 +
1976 +    freeifaddrs(ifap);
1977 +    return (addr_list->used - initial_count);
1978 +#else
1979      char   *myname = "inet_addr_local";
1980      struct ifconf ifc;
1981      struct ifreq *ifr;
1982      struct ifreq *the_end;
1983      int     sock;
1984 -    VSTRING *buf = vstring_alloc(1024);
1985 +    VSTRING *buf;
1986      int     initial_count = addr_list->used;
1987      struct in_addr addr;
1988      struct ifreq *ifr_mask;
1989 +    int af = AF_INET;
1990 +#ifdef INET6
1991 +#if defined (LINUX) || defined (LINUX2)
1992 +#define _PATH_PROCNET_IFINET6   "/proc/net/if_inet6"
1993 +    FILE *f;
1994 +    char addr6p[8][5], addr6res[40], devname[20];
1995 +    int plen, scope, dad_status, if_idx, gaierror;
1996 +    struct addrinfo hints, *res, *res0;
1997 +#endif
1998 +    struct sockaddr_in6 addr6;
1999  
2000 -    if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
2001 +other_socket_type:
2002 +#endif
2003 +    buf = vstring_alloc(1024);
2004 +
2005 +    if ((sock = socket(af, SOCK_DGRAM, 0)) < 0) {
2006 +#ifdef INET6
2007 +       if (af == AF_INET6)
2008 +       {
2009 +           if (msg_verbose)
2010 +                   msg_warn("%s: socket: %m", myname);
2011 +           goto end;
2012 +       }
2013 +       else
2014 +#endif
2015         msg_fatal("%s: socket: %m", myname);
2016 +    }
2017  
2018      /*
2019       * Get the network interface list. XXX The socket API appears to have no
2020 @@ -126,10 +213,15 @@
2021       */
2022      the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2023      for (ifr = ifc.ifc_req; ifr < the_end;) {
2024 -       if (ifr->ifr_addr.sa_family == AF_INET) {       /* IP interface */
2025 +       if ((ifr->ifr_addr.sa_family == AF_INET) &&
2026 +                       (ifr->ifr_addr.sa_family == af)) { /* IP interface */
2027             addr = ((struct sockaddr_in *) & ifr->ifr_addr)->sin_addr;
2028             if (addr.s_addr != INADDR_ANY) {    /* has IP address */
2029 +#ifdef INET6
2030 +               inet_addr_list_append(addr_list, &ifr->ifr_addr);
2031 +#else
2032                 inet_addr_list_append(addr_list, &addr);
2033 +#endif
2034                 if (mask_list) {
2035                     ifr_mask = (struct ifreq *) mymalloc(IFREQ_SIZE(ifr));
2036                     memcpy((char *) ifr_mask, (char *) ifr, IFREQ_SIZE(ifr));
2037 @@ -141,11 +233,61 @@
2038                 }
2039             }
2040         }
2041 +#ifdef INET6
2042 +       else if ((ifr->ifr_addr.sa_family == AF_INET6) &&
2043 +                       (ifr->ifr_addr.sa_family == af)) {  /* IPv6 interface */
2044 +           addr6 = *((struct sockaddr_in6 *) & ifr->ifr_addr);
2045 +#ifdef __KAME__
2046 +           /* decode scoped address notation */
2047 +           if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
2048 +                IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
2049 +               addr6.sin6_scope_id == 0) {
2050 +               addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
2051 +                   (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
2052 +               addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
2053 +           }
2054 +#endif
2055 +           if (!(IN6_IS_ADDR_UNSPECIFIED(&addr6.sin6_addr)))
2056 +               inet_addr_list_append(addr_list, (struct sockaddr *)&addr6);
2057 +       }
2058 +#endif
2059         ifr = NEXT_INTERFACE(ifr);
2060      }
2061      vstring_free(buf);
2062      (void) close(sock);
2063 +#ifdef INET6
2064 +end:
2065 +    if (af != AF_INET6) {
2066 +           af = AF_INET6;
2067 +           goto other_socket_type;
2068 +    }
2069 +#if defined (LINUX) || defined (LINUX2)
2070 +    if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
2071 +         while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
2072 +              addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4],
2073 +              addr6p[5], addr6p[6], addr6p[7],
2074 +              &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
2075 +                sprintf(addr6res, "%s:%s:%s:%s:%s:%s:%s:%s",
2076 +                                addr6p[0], addr6p[1], addr6p[2], addr6p[3],
2077 +                                addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
2078 +                addr6res[sizeof(addr6res) - 1] = 0;
2079 +                memset(&hints, 0, sizeof(hints));
2080 +                hints.ai_flags = AI_NUMERICHOST;
2081 +                hints.ai_family = AF_UNSPEC;
2082 +                hints.ai_socktype = SOCK_DGRAM;
2083 +                gaierror = getaddrinfo(addr6res, NULL, &hints, &res0);
2084 +                if (!gaierror) {
2085 +                        for (res = res0; res; res = res->ai_next) {
2086 +                              inet_addr_list_append(addr_list, res->ai_addr);
2087 +                        }
2088 +                        freeaddrinfo(res0);
2089 +                }
2090 +        }
2091 +    }
2092 +#endif /* linux */
2093 +#endif
2094      return (addr_list->used - initial_count);
2095 +#endif
2096  }
2097  
2098  #ifdef TEST
2099 @@ -158,6 +300,8 @@
2100      INET_ADDR_LIST addr_list;
2101      INET_ADDR_LIST mask_list;
2102      int     i;
2103 +    char abuf[NI_MAXHOST], mbuf[NI_MAXHOST];
2104 +    struct sockaddr *sa;
2105  
2106      msg_vstream_init(argv[0], VSTREAM_ERR);
2107  
2108 @@ -172,8 +316,17 @@
2109         msg_warn("found only one active network interface");
2110  
2111      for (i = 0; i < addr_list.used; i++) {
2112 -       vstream_printf("%s/", inet_ntoa(addr_list.addrs[i]));
2113 -       vstream_printf("%s\n", inet_ntoa(mask_list.addrs[i]));
2114 +       sa = (struct sockaddr *)&addr_list.addrs[i];
2115 +       if (getnameinfo(sa, SA_LEN(sa), abuf, sizeof(abuf), NULL, 0,
2116 +               NI_NUMERICHOST)) {
2117 +           strncpy(abuf, "???", sizeof(abuf));
2118 +       }
2119 +       sa = (struct sockaddr *)&mask_list.addrs[i];
2120 +       if (getnameinfo(sa, SA_LEN(sa), mbuf, sizeof(mbuf), NULL, 0,
2121 +               NI_NUMERICHOST)) {
2122 +           strncpy(mbuf, "???", sizeof(mbuf));
2123 +       }
2124 +       vstream_printf("%s/%s\n", abuf, mbuf);
2125      }
2126      vstream_fflush(VSTREAM_OUT);
2127      inet_addr_list_free(&addr_list);
2128 diff -Nur snapshot-20010525.nov6/src/util/inet_connect.c snapshot-20010525/src/util/inet_connect.c
2129 --- snapshot-20010525.nov6/src/util/inet_connect.c      Mon Nov 20 19:06:31 2000
2130 +++ snapshot-20010525/src/util/inet_connect.c   Wed Oct 17 11:38:17 2001
2131 @@ -55,6 +55,9 @@
2132  #include <string.h>
2133  #include <unistd.h>
2134  #include <errno.h>
2135 +#ifdef INET6
2136 +#include <netdb.h>
2137 +#endif
2138  
2139  /* Utility library. */
2140  
2141 @@ -73,7 +76,12 @@
2142      char   *buf;
2143      char   *host;
2144      char   *port;
2145 +#ifdef INET6
2146 +    struct addrinfo hints, *res, *res0;
2147 +    int    error;
2148 +#else
2149      struct sockaddr_in sin;
2150 +#endif
2151      int     sock;
2152  
2153      /*
2154 @@ -81,14 +89,58 @@
2155       * the local host.
2156       */
2157      buf = inet_parse(addr, &host, &port);
2158 +#ifdef INET6
2159 +    if (*host == 0)
2160 +       host = NULL;
2161 +    memset(&hints, 0, sizeof(hints));
2162 +    hints.ai_family = PF_UNSPEC;
2163 +    hints.ai_socktype = SOCK_STREAM;
2164 +    hints.ai_flags = AI_NUMERICHOST;   /* find_inet_addr is numeric only */
2165 +    if (getaddrinfo(host, port, &hints, &res0))
2166 +       msg_fatal("host not found: %s", host);
2167 +#else
2168      if (*host == 0)
2169         host = "localhost";
2170      memset((char *) &sin, 0, sizeof(sin));
2171      sin.sin_family = AF_INET;
2172      sin.sin_addr.s_addr = find_inet_addr(host);
2173      sin.sin_port = find_inet_port(port, "tcp");
2174 +#endif
2175      myfree(buf);
2176  
2177 +#ifdef INET6
2178 +    sock = -1;
2179 +    for (res = res0; res; res = res->ai_next) {
2180 +       if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2181 +           continue;
2182 +
2183 +       sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
2184 +       if (sock < 0)
2185 +           continue;
2186 +       if (timeout > 0) {
2187 +           non_blocking(sock, NON_BLOCKING);
2188 +           if (timed_connect(sock, res->ai_addr, res->ai_addrlen, timeout) < 0) {
2189 +               close(sock);
2190 +               sock = -1;
2191 +               continue;
2192 +           }
2193 +           if (block_mode != NON_BLOCKING)
2194 +               non_blocking(sock, block_mode);
2195 +           break;
2196 +       } else {
2197 +           non_blocking(sock, block_mode);
2198 +           if (connect(sock, res->ai_addr, res->ai_addrlen) < 0
2199 +               && errno != EINPROGRESS) {
2200 +               close(sock);
2201 +               sock = -1;
2202 +               continue;
2203 +           }
2204 +           break;
2205 +       }
2206 +    }
2207 +    freeaddrinfo(res0);
2208 +    return sock;
2209 +#else
2210      /*
2211       * Create a client socket.
2212       */
2213 @@ -121,4 +173,5 @@
2214         }
2215         return (sock);
2216      }
2217 +#endif
2218  }
2219 diff -Nur snapshot-20010525.nov6/src/util/inet_listen.c snapshot-20010525/src/util/inet_listen.c
2220 --- snapshot-20010525.nov6/src/util/inet_listen.c       Mon Nov 20 19:06:32 2000
2221 +++ snapshot-20010525/src/util/inet_listen.c    Wed Oct 17 11:38:17 2001
2222 @@ -6,7 +6,7 @@
2223  /* SYNOPSIS
2224  /*     #include <listen.h>
2225  /*
2226 -/*     int     inet_listen(addr, backlog, block_mode)
2227 +/*     int     inet_listen(addr, backlog, block_mode, addinuse_fatal)
2228  /*     const char *addr;
2229  /*     int     backlog;
2230  /*     int     block_mode;
2231 @@ -51,11 +51,17 @@
2232  #include <sys_defs.h>
2233  #include <sys/socket.h>
2234  #include <netinet/in.h>
2235 +#ifdef INET6
2236 +#if (! __GLIBC__ >= 2 && __GLIBC_MINOR__ >=1 )
2237 +#include <netinet6/in6.h>
2238 +#endif
2239 +#endif
2240  #include <arpa/inet.h>
2241  #include <netdb.h>
2242  #ifndef MAXHOSTNAMELEN
2243  #include <sys/param.h>
2244  #endif
2245 +#include <errno.h>
2246  #include <string.h>
2247  #include <unistd.h>
2248  
2249 @@ -77,35 +83,116 @@
2250  
2251  /* inet_listen - create inet-domain listener */
2252  
2253 -int     inet_listen(const char *addr, int backlog, int block_mode)
2254 +int     inet_listen(const char *addr, int backlog, int block_mode, int addrinuse_fatal)
2255  {
2256 +#ifdef INET6
2257 +    struct addrinfo *res, *res0, hints;
2258 +    int error;
2259 +#else
2260 +    struct ai {
2261 +       int ai_family;
2262 +       int ai_socktype;
2263 +       int ai_protocol;
2264 +       struct sockaddr *ai_addr;
2265 +       SOCKADDR_SIZE ai_addrlen;
2266 +       struct ai *ai_next;
2267 +    } *res, *res0, resbody;
2268      struct sockaddr_in sin;
2269 +#endif
2270      int     sock;
2271      int     t = 1;
2272 +    int     addrinuse = 0;
2273      char   *buf;
2274      char   *host;
2275      char   *port;
2276 +#ifdef INET6
2277 +    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
2278 +#else
2279 +    char hbuf[sizeof("255.255.255.255") + 1];
2280 +    char pbuf[sizeof("255.255.255.255") + 1];
2281 +#endif
2282 +    char *cause = "unknown";
2283  
2284      /*
2285       * Translate address information to internal form.
2286       */
2287      buf = inet_parse(addr, &host, &port);
2288 -    memset((char *) &sin, 0, sizeof(sin));
2289 +#ifdef INET6
2290 +    memset(&hints, 0, sizeof(hints));
2291 +    hints.ai_flags = AI_PASSIVE;
2292 +    hints.ai_family = AF_UNSPEC;
2293 +    hints.ai_socktype = SOCK_STREAM;
2294 +    error = getaddrinfo(*host ? host : NULL, *port ? port : "0", &hints, &res0);
2295 +    if (error) {
2296 +       msg_fatal("getaddrinfo: %s", gai_strerror(error));
2297 +    }
2298 +    myfree(buf);
2299 +#else
2300 +    memset(&sin, 0, sizeof(sin));
2301      sin.sin_family = AF_INET;
2302 +#ifdef HAS_SA_LEN
2303 +    sin.sin_len = sizeof(sin);
2304 +#endif
2305      sin.sin_port = find_inet_port(port, "tcp");
2306      sin.sin_addr.s_addr = (*host ? find_inet_addr(host) : INADDR_ANY);
2307 -    myfree(buf);
2308  
2309 -    /*
2310 -     * Create a listener socket.
2311 -     */
2312 -    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
2313 -       msg_fatal("socket: %m");
2314 -    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0)
2315 -       msg_fatal("setsockopt: %m");
2316 -    if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
2317 -       msg_fatal("bind %s port %d: %m", sin.sin_addr.s_addr == INADDR_ANY ?
2318 -              "INADDR_ANY" : inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
2319 +    memset(&resbody, 0, sizeof(resbody)); 
2320 +    resbody.ai_socktype = SOCK_STREAM;
2321 +    resbody.ai_family = AF_INET;
2322 +    resbody.ai_addr = (struct sockaddr *)&sin;
2323 +    resbody.ai_addrlen = sizeof(sin);
2324 +
2325 +    res0 = &resbody;
2326 +#endif
2327 +
2328 +    sock = -1;
2329 +    for (res = res0; res; res = res->ai_next) {
2330 +       if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2331 +           continue;
2332 +
2333 +       /*
2334 +        * Create a listener socket.
2335 +        */
2336 +       if ((sock = socket(res->ai_family, res->ai_socktype, 0)) < 0) {
2337 +           cause = "socket";
2338 +           continue;
2339 +       }
2340 +#ifdef IPV6_V6ONLY
2341 +       if (res->ai_family == AF_INET6 &&
2342 +           setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &t, sizeof(t)) < 0) {
2343 +               /* if kernel/libc don't support this simple ignore it
2344 +           cause = "setsockopt(IPV6_V6ONLY)";
2345 +           close(sock);
2346 +           sock = -1;
2347 +           continue;
2348 +               */
2349 +               ;
2350 +       }
2351 +#endif
2352 +       if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0) {
2353 +           cause = "setsockopt(SO_REUSEADDR)";
2354 +           close(sock);
2355 +           sock = -1;
2356 +           continue;
2357 +       }
2358 +
2359 +       if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
2360 +           cause = "bind";
2361 +           if (errno == EADDRINUSE)
2362 +               addrinuse = 1;
2363 +           close(sock);
2364 +           sock = -1;
2365 +           continue;
2366 +       }
2367 +       break;
2368 +    }
2369 +    if (sock < 0 && (addrinuse_fatal || !addrinuse))
2370 +       msg_fatal("%s: %m", cause);
2371 +#ifdef INET6
2372 +    freeaddrinfo(res0);
2373 +#endif
2374 +    if (sock < 0)
2375 +       return -1;
2376      non_blocking(sock, block_mode);
2377      if (listen(sock, backlog) < 0)
2378         msg_fatal("listen: %m");
2379 diff -Nur snapshot-20010525.nov6/src/util/listen.h snapshot-20010525/src/util/listen.h
2380 --- snapshot-20010525.nov6/src/util/listen.h    Mon Mar 22 02:57:11 1999
2381 +++ snapshot-20010525/src/util/listen.h Wed Oct 17 11:38:17 2001
2382 @@ -20,7 +20,7 @@
2383    * Listener external interface.
2384    */
2385  extern int unix_listen(const char *, int, int);
2386 -extern int inet_listen(const char *, int, int);
2387 +extern int inet_listen(const char *, int, int, int);
2388  extern int fifo_listen(const char *, int, int);
2389  extern int stream_listen(const char *, int, int);
2390  
2391 diff -Nur snapshot-20010525.nov6/src/util/match_list.c snapshot-20010525/src/util/match_list.c
2392 --- snapshot-20010525.nov6/src/util/match_list.c        Mon Nov 20 19:06:32 2000
2393 +++ snapshot-20010525/src/util/match_list.c     Wed Oct 17 11:38:17 2001
2394 @@ -107,7 +107,7 @@
2395                     list = match_list_parse(list, vstring_str(buf));
2396             if (vstream_fclose(fp))
2397                 msg_fatal("%s: read file %s: %m", myname, pattern);
2398 -       } else if (strchr(pattern, ':') != 0) { /* type:table */
2399 +       } else if ((strchr(pattern, ']') == 0) && (strchr(pattern, ':') != 0)) {        /* type:table */
2400             for (cp = pattern; *cp == '!'; cp++)
2401                  /* void */ ;
2402             if (dict_handle(pattern) == 0)
2403 diff -Nur snapshot-20010525.nov6/src/util/match_ops.c snapshot-20010525/src/util/match_ops.c
2404 --- snapshot-20010525.nov6/src/util/match_ops.c Mon Sep  6 03:02:14 1999
2405 +++ snapshot-20010525/src/util/match_ops.c      Wed Oct 17 11:38:17 2001
2406 @@ -70,6 +70,307 @@
2407  #include <match_ops.h>
2408  #include <stringops.h>
2409  
2410 +#ifdef INET6
2411 +/*
2412 + *             $Id$
2413 + *
2414 + *             This program is free software; you can redistribute it and/or
2415 + *             modify it under the terms of the GNU General Public License
2416 + *             as published by the Free Software Foundation; either version
2417 + *             2 of the License, or (at your option) any later version.
2418 + *
2419 + * Authors:    Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
2420 + * 
2421 + * Modifications:
2422 + *             Artur Frysiak <wiget@pld.org.pl>
2423 + *             Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
2424 + */
2425 +
2426 +#include <stdio.h>
2427 +#include <stdlib.h>
2428 +#include <unistd.h>
2429 +#include <syslog.h>
2430 +#include <fcntl.h>
2431 +#include <sys/socket.h>
2432 +#include <netinet/in.h>
2433 +#include <string.h>
2434 +#include <netdb.h>
2435 +#include <arpa/inet.h>
2436 +#include <resolv.h>
2437 +
2438 +#ifndef        AF_DECnet
2439 +#define        AF_DECnet       12
2440 +#endif
2441 +
2442 +#ifndef        PF_PACKET
2443 +#define        PF_PACKET       17
2444 +#endif
2445 +
2446 +typedef struct
2447 +{
2448 +       unsigned char family;
2449 +       unsigned char bytelen;
2450 +       signed short  bitlen;
2451 +       unsigned int data[4];
2452 +} inet_prefix;
2453 +
2454 +/* prototypes */
2455 +int masked_match(char *, char *, char *);
2456 +int get_integer(int *, char *, int);
2457 +int get_addr_1(inet_prefix *, char *, int);
2458 +int get_prefix_1(inet_prefix *, char *, int);
2459 +int get_addr(inet_prefix *, char *, int);
2460 +int get_prefix(inet_prefix *, char *, int);
2461 +unsigned int get_addr32(char *);
2462 +int matches(char *, char *);
2463 +int inet_addr_match(inet_prefix *, inet_prefix *, int);
2464 +int mask_match(char *, char *, char *);
2465 +       
2466 +int get_integer(int *val, char *arg, int base)
2467 +{
2468 +       long res;
2469 +       char *ptr;
2470 +
2471 +       if (!arg || !*arg)
2472 +               return -1;
2473 +       res = strtol(arg, &ptr, base);
2474 +       if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN)
2475 +               return -1;
2476 +       *val = res;
2477 +       return 0;
2478 +}
2479 +
2480 +int get_addr_1(inet_prefix *addr, char *name, int family)
2481 +{
2482 +       char *cp;
2483 +       unsigned char *ap = (unsigned char*)addr->data;
2484 +       int i;
2485 +
2486 +       memset(addr, 0, sizeof(*addr));
2487 +
2488 +       if (strcmp(name, "default") == 0 || strcmp(name, "any") == 0) {
2489 +               if (family == AF_DECnet)
2490 +                       return -1;
2491 +               addr->family = family;
2492 +               addr->bytelen = (family == AF_INET6 ? 16 : 4);
2493 +               addr->bitlen = -1;
2494 +               return 0;
2495 +       }
2496 +
2497 +       if (strchr(name, ':')) {
2498 +               addr->family = AF_INET6;
2499 +               if (family != AF_UNSPEC && family != AF_INET6)
2500 +                       return -1;
2501 +               if (inet_pton(AF_INET6, name, addr->data) <= 0)
2502 +                       return -1;
2503 +               addr->bytelen = 16;
2504 +               addr->bitlen = -1;
2505 +               return 0;
2506 +       }
2507 +       addr->family = AF_INET;
2508 +       if (family != AF_UNSPEC && family != AF_INET)
2509 +               return -1;
2510 +       addr->bytelen = 4;
2511 +       addr->bitlen = -1;
2512 +       for (cp = name, i = 0; *cp; cp++) {
2513 +               if (*cp <= '9' && *cp >= '0') {
2514 +                       ap[i] = 10*ap[i] + (*cp-'0');
2515 +                       continue;
2516 +               }
2517 +               if (*cp == '.' && ++i <= 3)
2518 +                       continue;
2519 +               return -1;
2520 +       }
2521 +       return 0;
2522 +}
2523 +
2524 +int get_prefix_1(inet_prefix *dst, char *arg, int family)
2525 +{
2526 +       int err;
2527 +       unsigned plen;
2528 +       char *slash;
2529 +
2530 +       memset(dst, 0, sizeof(*dst));
2531 +
2532 +       if (strcmp(arg, "default") == 0 || strcmp(arg, "any") == 0) {
2533 +               if (family == AF_DECnet)
2534 +                       return -1;
2535 +               dst->family = family;
2536 +               dst->bytelen = 0;
2537 +               dst->bitlen = 0;
2538 +               return 0;
2539 +       }
2540 +
2541 +       slash = strchr(arg, '/');
2542 +       if (slash)
2543 +               *slash = 0;
2544 +       err = get_addr_1(dst, arg, family);
2545 +       if (err == 0) {
2546 +               switch(dst->family) {
2547 +                       case AF_INET6:
2548 +                               dst->bitlen = 128;
2549 +                               break;
2550 +                       case AF_DECnet:
2551 +                               dst->bitlen = 16;
2552 +                               break;
2553 +                       default:
2554 +                       case AF_INET:
2555 +                               dst->bitlen = 32;
2556 +               }
2557 +               if (slash) {
2558 +                       if (get_integer(&plen, slash+1, 0) || plen > dst->bitlen) {
2559 +                               err = -1;
2560 +                               goto done;
2561 +                       }
2562 +                       dst->bitlen = plen;
2563 +               }
2564 +       }
2565 +done:
2566 +       if (slash)
2567 +               *slash = '/';
2568 +       return err;
2569 +}
2570 +
2571 +int get_addr(inet_prefix *dst, char *arg, int family)
2572 +{
2573 +#ifdef AF_PACKET
2574 +       if (family == AF_PACKET)
2575 +               return -1;
2576 +#endif
2577 +       if (get_addr_1(dst, arg, family))
2578 +               return -1;
2579 +       return 0;
2580 +}
2581 +
2582 +int get_prefix(inet_prefix *dst, char *arg, int family)
2583 +{
2584 +#ifdef AF_PACKET
2585 +       if (family == AF_PACKET)
2586 +               return -1;
2587 +#endif
2588 +       if (get_prefix_1(dst, arg, family))
2589 +               return -1;
2590 +       return 0;
2591 +}
2592 +
2593 +unsigned int get_addr32(char *name)
2594 +{
2595 +       inet_prefix addr;
2596 +       if (get_addr_1(&addr, name, AF_INET))
2597 +               return -1;
2598 +       return addr.data[0];
2599 +}
2600 +
2601 +int matches(char *cmd, char *pattern)
2602 +{
2603 +       int len = strlen(cmd);
2604 +       if (len > strlen(pattern))
2605 +               return -1;
2606 +       return memcmp(pattern, cmd, len);
2607 +}
2608 +
2609 +int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits)
2610 +{
2611 +       unsigned int *a1 = a->data;
2612 +       unsigned int *a2 = b->data;
2613 +       int words = bits >> 0x05;
2614 +
2615 +       bits &= 0x1f;
2616 +
2617 +       if (words)
2618 +               if (memcmp(a1, a2, words << 2))
2619 +                       return -1;
2620 +
2621 +       if (bits) {
2622 +               unsigned int w1, w2;
2623 +               unsigned int mask;
2624 +
2625 +               w1 = a1[words];
2626 +               w2 = a2[words];
2627 +
2628 +               mask = htonl((0xffffffff) << (0x20 - bits));
2629 +
2630 +               if ((w1 ^ w2) & mask)
2631 +                       return 1;
2632 +       }
2633 +
2634 +       return 0;
2635 +}
2636 +
2637 +/* zero if matches */
2638 +int mask_match(char *network, char *cprefix, char *address)
2639 +{
2640 +       inet_prefix *inetwork;
2641 +       inet_prefix *iaddress;
2642 +       int ret, prefix;
2643 +
2644 +       if (!(network && address && cprefix))
2645 +               return -1;
2646 +       prefix = strtol(cprefix, (char **)NULL, 10);
2647 +       if ((prefix < 0) || (prefix > 128))
2648 +               return -1;
2649 +       if ((strlen(network) == 0) || (strlen(address) == 0))
2650 +               return -1;
2651 +
2652 +       inetwork = malloc(sizeof(inet_prefix));
2653 +       iaddress = malloc(sizeof(inet_prefix));
2654 +
2655 +       if ((get_addr(iaddress, address, AF_UNSPEC) >= 0)
2656 +                       && (get_addr(inetwork, network, AF_UNSPEC) >= 0))
2657 +               ret = inet_addr_match(inetwork, iaddress, prefix);
2658 +       else
2659 +               ret = -1;
2660 +       free(inetwork);
2661 +       free(iaddress);
2662 +
2663 +       /* 1 if matches */
2664 +       /* return (!ret); */
2665 +       /* 0 if matches */
2666 +       return ret;
2667 +}
2668 +
2669 +/*
2670 + * masked_match() - universal for IPv4 and IPv6
2671 + */
2672 +int masked_match(net_tok, mask_tok, string)
2673 +char   *net_tok;
2674 +char   *mask_tok;
2675 +char   *string;
2676 +{
2677 +#ifdef INET6
2678 +       struct in6_addr in6[2];
2679 +       char v4addr[2][INET_ADDRSTRLEN];
2680 +       char newmask[6];
2681 +       int plen;
2682 +#endif
2683 +
2684 +       /* Check for NULL */
2685 +       if (!(net_tok && mask_tok && string))
2686 +               return 1;
2687 +
2688 +       /* If IPv6 mapped convert to native-IPv4 */
2689 +#ifdef INET6
2690 +       if (inet_pton(AF_INET6, net_tok, &in6[0]) == 1 &&
2691 +           inet_pton(AF_INET6, string, &in6[1]) == 1 &&
2692 +           IN6_IS_ADDR_V4MAPPED(&in6[0]) && IN6_IS_ADDR_V4MAPPED(&in6[1])) {
2693 +               plen = atoi(mask_tok);
2694 +               if (32 < plen && plen < 129) {
2695 +                       sprintf(newmask, "%d", plen - 96);
2696 +                       mask_tok = newmask;
2697 +               }
2698 +
2699 +               (void)inet_ntop(AF_INET, &in6[0].s6_addr[12], v4addr[0],
2700 +                   sizeof(v4addr[0]));
2701 +               net_tok = v4addr[0];
2702 +               (void)inet_ntop(AF_INET, &in6[1].s6_addr[12], v4addr[1],
2703 +                   sizeof(v4addr[1]));
2704 +               string = v4addr[1];
2705 +       }
2706 +#endif
2707 +       return (!mask_match(net_tok, mask_tok, string));
2708 +}
2709 +#endif
2710 +
2711  /* match_string - match a string literal */
2712  
2713  int     match_string(const char *string, const char *pattern)
2714 @@ -158,6 +459,7 @@
2715      return (0);
2716  }
2717  
2718 +#ifndef INET6
2719  /* match_parse_mask - parse net/mask pattern */
2720  
2721  static int match_parse_mask(const char *pattern, unsigned long *net_bits,
2722 @@ -178,28 +480,55 @@
2723      myfree(saved_pattern);
2724      return (mask != 0);
2725  }
2726 +#endif
2727  
2728  /* match_hostaddr - match host by address */
2729  
2730  int     match_hostaddr(const char *addr, const char *pattern)
2731  {
2732      char   *myname = "match_hostaddr";
2733 +#ifdef INET6
2734 +    char *network, *mask, *escl, *escr, *patternx;
2735 +    struct in6_addr in6;
2736 +    char v4addr[INET_ADDRSTRLEN];
2737 +#else
2738      int     mask_shift;
2739      unsigned long mask_bits;
2740      unsigned long net_bits;
2741      unsigned long addr_bits;
2742 +#endif
2743  
2744      if (msg_verbose)
2745         msg_info("%s: %s ~? %s", myname, addr, pattern);
2746  
2747 +#ifdef INET6
2748 +    if (addr[strspn(addr, "01234567890./:abcdef")] != 0)
2749 +#else
2750      if (addr[strspn(addr, "01234567890./:")] != 0)
2751 +#endif
2752         return (0);
2753  
2754 +#ifdef INET6
2755 +    patternx = mystrdup(pattern);
2756 +    escl = strchr(patternx,'[');
2757 +    escr = strrchr(patternx,']');
2758 +    if (escl && escr) {
2759 +       *escr = 0;
2760 +       sprintf(patternx, "%s%s", escl + 1, escr + 1);
2761 +       pattern = patternx;
2762 +    }
2763 +#endif
2764 +    
2765      /*
2766       * Try dictionary lookup. This can be case insensitive. XXX Probably
2767       * should also try again after stripping least significant octets.
2768       */
2769 -    if (strchr(pattern, ':') != 0) {
2770 +#ifdef INET6
2771 +    if (!(escl && escr) && strchr(pattern, ':') != 0)
2772 +#else
2773 +    if (strchr(pattern, ':') != 0)
2774 +#endif
2775 +    {
2776         if (dict_lookup(pattern, addr) != 0)
2777             return (1);
2778         if (dict_errno != 0)
2779 @@ -210,6 +539,12 @@
2780      /*
2781       * Try an exact match with the host address.
2782       */
2783 +#ifdef INET6
2784 +    if (inet_pton(AF_INET6, addr, &in6) == 1 && IN6_IS_ADDR_V4MAPPED(&in6)) {
2785 +       (void)inet_ntop(AF_INET, &in6.s6_addr[12], v4addr, sizeof(v4addr));
2786 +       addr = v4addr;
2787 +    }
2788 +#endif
2789      if (strcasecmp(addr, pattern) == 0) {
2790         return (1);
2791      }
2792 @@ -218,6 +553,20 @@
2793       * In a net/mask pattern, the mask is specified as the number of bits of
2794       * the network part.
2795       */
2796 +#ifdef INET6
2797 +    network = mystrdup(patternx);
2798 +    mask = split_at(network, '/');
2799 +
2800 +    if (masked_match(network, mask, (char *)addr)) {
2801 +       myfree(network);
2802 +       myfree(patternx);
2803 +       return (1);
2804 +    } else {
2805 +       myfree(network);
2806 +       myfree(patternx);
2807 +    }
2808 +#else
2809 +           
2810      if (match_parse_mask(pattern, &net_bits, &mask_shift)) {
2811         addr_bits = inet_addr(addr);
2812         if (addr_bits == INADDR_NONE)
2813 @@ -225,5 +574,6 @@
2814         mask_bits = htonl((0xffffffff) << (BITS_PER_ADDR - mask_shift));
2815         return ((addr_bits & mask_bits) == (net_bits & mask_bits));
2816      }
2817 +#endif
2818      return (0);
2819  }
2820 diff -Nur snapshot-20010525.nov6/src/util/sys_defs.h snapshot-20010525/src/util/sys_defs.h
2821 --- snapshot-20010525.nov6/src/util/sys_defs.h  Tue Oct 16 13:15:43 2001
2822 +++ snapshot-20010525/src/util/sys_defs.h       Wed Oct 17 11:38:17 2001
2823 @@ -67,6 +67,10 @@
2824  #define DEF_MAILBOX_LOCK "flock, dotlock"
2825  #endif
2826  
2827 +#if ((defined(__NetBSD_Version__) && __NetBSD_Version__ >= 105000000) || defined(USAGI_LIBINET6))
2828 +#define HAVE_GETIFADDRS
2829 +#endif
2830 +
2831   /*
2832    * UNIX on MAC.
2833    */
2834 diff -Nur snapshot-20010525.nov6/src/util/valid_hostname.c snapshot-20010525/src/util/valid_hostname.c
2835 --- snapshot-20010525.nov6/src/util/valid_hostname.c    Sun Jan 28 15:10:18 2001
2836 +++ snapshot-20010525/src/util/valid_hostname.c Wed Oct 17 11:38:17 2001
2837 @@ -47,6 +47,13 @@
2838  #include <string.h>
2839  #include <ctype.h>
2840  
2841 +#ifdef INET6
2842 +#include <netinet/in.h>
2843 +#include <sys/socket.h>
2844 +#include <arpa/inet.h>
2845 +#include <netdb.h>
2846 +#endif
2847 +
2848  /* Utility library. */
2849  
2850  #include "msg.h"
2851 @@ -103,7 +110,23 @@
2852                     msg_warn("%s: misplaced hyphen: %.100s", myname, name);
2853                 return (0);
2854             }
2855 -       } else {
2856 +       }
2857 +#ifdef INET6
2858 +       else if (ch == ':') {
2859 +           struct addrinfo hints, *res;
2860 +
2861 +           memset(&hints, 0, sizeof(hints));
2862 +           hints.ai_family = AF_INET6;
2863 +           hints.ai_socktype = SOCK_STREAM;    /*dummy*/
2864 +           hints.ai_flags = AI_NUMERICHOST;
2865 +           if (getaddrinfo(name, "0", &hints, &res) == 0) {
2866 +               freeaddrinfo(res);
2867 +               return 1;
2868 +           } else
2869 +               return 0;
2870 +       }
2871 +#endif
2872 +       else {
2873             if (gripe)
2874                 msg_warn("%s: invalid character %d(decimal): %.100s",
2875                          myname, ch, name);
2876 @@ -135,6 +158,9 @@
2877      int     byte_count = 0;
2878      int     byte_val = 0;
2879      int     ch;
2880 +#ifdef INET6
2881 +    struct addrinfo hints, *res;
2882 +#endif
2883  
2884  #define BYTES_NEEDED   4
2885  
2886 @@ -147,6 +173,17 @@
2887         return (0);
2888      }
2889  
2890 +#ifdef INET6
2891 +    memset(&hints, 0, sizeof(hints));
2892 +    hints.ai_family = AF_INET6;
2893 +    hints.ai_socktype = SOCK_STREAM;   /*dummy*/
2894 +    hints.ai_flags = AI_NUMERICHOST;
2895 +    if (getaddrinfo(addr, "0", &hints, &res) == 0) {
2896 +       freeaddrinfo(res);
2897 +       return 1;
2898 +    }
2899 +#endif
2900 +
2901      /*
2902       * Scary code to avoid sscanf() overflow nasties.
2903       */
This page took 0.33741 seconds and 4 git commands to generate.