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