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