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