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