1 --- postfix-2.0.16.orig/makedefs 2003-01-23 14:45:02.000000000 +0100
2 +++ postfix-2.0.16/makedefs 2003-11-08 20:22:55.000000000 +0100
4 SYSTEM=`(uname -s) 2>/dev/null`
5 RELEASE=`(uname -r) 2>/dev/null`
6 VERSION=`(uname -v) 2>/dev/null`
7 +if test -f /usr/include/netinet6/in6.h; then
8 + grep __KAME__ /usr/include/netinet6/in6.h 2>&1 >/dev/null
12 + if [ -f /usr/local/v6/lib/libinet6.a ]; then
19 +if [ -z "$INET6" -a -f /usr/include/netinet/ip6.h -a -f /usr/include/linux/icmpv6.h ]; then
24 dcosx*) SYSTEM=$VERSION;;
27 : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk}
31 + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
32 + if test -f /usr/local/v6/lib/libinet6.a; then
33 + SYSLIBS="$SYSLIBS -L/usr/local/v6/lib -linet6"
37 + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
40 + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family"
41 + if test -f /usr/include/libinet6/netinet/ip6.h
43 + CCARGS="$CCARGS -I/usr/include/libinet6 -DUSAGI_LIBINET6"
44 + SYSLIBS="$SYSLIBS -linet6"
49 export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
52 --- postfix-2.0.16.orig/src/global/Makefile.in 2003-11-08 20:17:08.000000000 +0100
53 +++ postfix-2.0.16/src/global/Makefile.in 2003-11-08 20:22:55.000000000 +0100
55 timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
56 tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
57 flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
58 - verp_sender.c match_parent_style.c mime_state.c header_token.c \
59 + verp_sender.c match_parent_style.c mime_state.c header_token.c wildcard_inet_addr.c\
60 strip_addr.c virtual8_maps.c hold_message.c dict_proxy.c mail_dict.c \
62 OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
64 timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
65 tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
66 flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
67 - verp_sender.o match_parent_style.o mime_state.o header_token.o \
68 + verp_sender.o match_parent_style.o mime_state.o header_token.o wildcard_inet_addr.o\
69 strip_addr.o virtual8_maps.o hold_message.o dict_proxy.o mail_dict.o \
71 HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
73 rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
74 sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
75 mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \
76 - match_parent_style.h quote_flags.h mime_state.h header_token.h \
77 + match_parent_style.h quote_flags.h mime_state.h header_token.h wildcard_inet_addr.h\
78 lex_822.h strip_addr.h virtual8_maps.h hold_message.h dict_proxy.h \
80 TESTSRC = rec2stream.c stream2rec.c recdump.c
81 --- postfix-2.0.16.orig/src/global/mynetworks.c 2001-02-25 02:46:07.000000000 +0100
82 +++ postfix-2.0.16/src/global/mynetworks.c 2003-11-08 20:22:55.000000000 +0100
85 #include <inet_addr_list.h>
86 #include <name_mask.h>
88 +#include <sys/socket.h>
89 +#include <netinet/in.h>
96 const char *mynetworks(void)
98 static VSTRING *result;
100 + char hbuf[NI_MAXHOST];
104 char *myname = "mynetworks";
110 + struct sockaddr *sa;
111 + struct sockaddr_in6 *addr6;
112 + struct sockaddr_in6 *mask6;
113 + struct in6_addr net6;
117 mask_style = name_mask("mynetworks mask style", mask_styles,
118 var_mynetworks_style);
120 my_mask_list = own_inet_mask_list();
122 for (i = 0; i < my_addr_list->used; i++) {
124 + sa = (struct sockaddr *)&my_addr_list->addrs[i];
125 + if (sa->sa_family == AF_INET6) {
126 + addr6 = (struct sockaddr_in6 *)sa;
127 + mask6 = (struct sockaddr_in6 *)&my_mask_list->addrs[i];
129 + switch (mask_style) {
130 + case MASK_STYLE_CLASS:
131 + /* treat as subnet for IPv6 */
132 + case MASK_STYLE_SUBNET:
133 + for (j=0; j<16; j++)
134 + net6.s6_addr[j] = addr6->sin6_addr.s6_addr[j] & mask6->sin6_addr.s6_addr[j];
135 + for(shift=128; shift>0; shift--)
136 + if ((mask6->sin6_addr.s6_addr[(shift-1) / 8]) & (0x80 >> ((shift-1) % 8)))
139 + case MASK_STYLE_HOST:
140 + memcpy (&net6, &(addr6->sin6_addr), sizeof(net6));
144 + msg_panic("unknown mynetworks mask style: %s",
145 + var_mynetworks_style);
147 + inet_ntop(AF_INET6, &net6, hbuf, sizeof(hbuf));
149 + msg_warn("%s: skipped network with zero mask: [%s/0]", myname, hbuf);
151 + vstring_sprintf_append(result, "[%s/%d] ", hbuf, shift);
153 + } else if (sa->sa_family != AF_INET) {
156 + addr = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
157 + mask = ntohl(((struct sockaddr_in *)&my_mask_list->addrs[i])->sin_addr.s_addr);
159 addr = ntohl(my_addr_list->addrs[i].s_addr);
160 mask = ntohl(my_mask_list->addrs[i].s_addr);
163 switch (mask_style) {
166 mask = IN_CLASSD_NET;
167 shift = IN_CLASSD_NSHIFT;
170 + if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
172 + strncpy(hbuf, "???", sizeof(hbuf));
173 + msg_fatal("%s: bad address class: %s", myname, hbuf);
175 msg_fatal("%s: bad address class: %s",
176 myname, inet_ntoa(my_addr_list->addrs[i]));
182 var_mynetworks_style);
184 net.s_addr = htonl(addr & mask);
185 + if (shift == BITS_PER_ADDR) {
187 + if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
189 + strncpy(hbuf, "???", sizeof(hbuf));
190 + msg_warn("%s: skipped network with zero mask: %s/0", myname, hbuf);
192 + msg_warn("%s: skipped network with zero mask: %s/0",
193 + myname, inet_ntoa(my_addr_list->addrs[i]));
197 vstring_sprintf_append(result, "%s/%d ",
198 inet_ntoa(net), BITS_PER_ADDR - shift);
200 --- postfix-2.0.16.orig/src/global/own_inet_addr.c 2002-10-25 01:19:19.000000000 +0200
201 +++ postfix-2.0.16/src/global/own_inet_addr.c 2003-11-08 20:22:55.000000000 +0100
203 #include <netinet/in.h>
204 #include <arpa/inet.h>
207 +#include <sys/socket.h>
211 #ifdef STRCASECMP_IN_STRINGS_H
213 @@ -113,10 +117,11 @@
216 bufp = hosts = mystrdup(var_inet_interfaces);
217 - while ((host = mystrtok(&bufp, sep)) != 0)
218 + while ((host = mystrtok(&bufp, sep)) != 0) {
219 if (inet_addr_host(addr_list, host) == 0)
220 msg_fatal("config variable %s: host not found: %s",
221 VAR_INET_INTERFACES, host);
226 @@ -133,15 +138,39 @@
227 msg_fatal("could not find any active network interfaces");
228 for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) {
229 for (nlocal = 0; /* see below */ ; nlocal++) {
230 - if (nlocal >= local_addrs.used)
231 + if (nlocal >= local_addrs.used) {
233 + char hbuf[NI_MAXHOST];
234 + if (getnameinfo((struct sockaddr *)&addr_list->addrs[nvirtual],
235 + SS_LEN(addr_list->addrs[nvirtual]), hbuf,
236 + sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
237 + strncpy(hbuf, "???", sizeof(hbuf));
238 + msg_fatal("parameter %s: no local interface found for %s",
239 + VAR_INET_INTERFACES, hbuf);
241 msg_fatal("parameter %s: no local interface found for %s",
243 inet_ntoa(addr_list->addrs[nvirtual]));
247 + if (addr_list->addrs[nvirtual].ss_family ==
248 + local_addrs.addrs[nlocal].ss_family &&
249 + SS_LEN(addr_list->addrs[nvirtual]) ==
250 + SS_LEN(local_addrs.addrs[nlocal]) &&
251 + memcmp(&addr_list->addrs[nvirtual],
252 + &local_addrs.addrs[nlocal],
253 + SS_LEN(local_addrs.addrs[nlocal])) == 0) {
254 + inet_addr_list_append(mask_list, (struct sockaddr *)&local_masks.addrs[nlocal]);
258 if (addr_list->addrs[nvirtual].s_addr
259 == local_addrs.addrs[nlocal].s_addr) {
260 inet_addr_list_append(mask_list, &local_masks.addrs[nlocal]);
266 inet_addr_list_free(&local_addrs);
269 /* own_inet_addr - is this my own internet address */
272 +int own_inet_addr(struct sockaddr * addr)
277 + struct sockaddr *sa;
279 + if (addr_list.used == 0)
280 + own_inet_addr_init(&addr_list, &mask_list);
282 + for (i = 0; i < addr_list.used; i++) {
283 + sa = (struct sockaddr *)&addr_list.addrs[i];
284 + if (addr->sa_family != sa->sa_family)
286 + switch (addr->sa_family) {
288 + p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
289 + q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
290 + l = sizeof(struct in_addr);
294 + p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
295 + q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
296 + l = sizeof(struct in6_addr);
301 + if (memcmp(p, q, l) == 0)
307 int own_inet_addr(struct in_addr * addr)
311 for (i = 0; i < addr_list.used; i++)
312 if (addr->s_addr == addr_list.addrs[i].s_addr)
318 /* own_inet_addr_list - return list of addresses */
322 /* proxy_inet_addr - is this my proxy internet address */
325 +int proxy_inet_addr(struct sockaddr * addr)
330 + struct sockaddr *sa;
332 + if (*var_proxy_interfaces == 0)
335 + if (proxy_list.used == 0)
336 + proxy_inet_addr_init(&proxy_list);
338 + for (i = 0; i < proxy_list.used; i++) {
339 + sa = (struct sockaddr *)&proxy_list.addrs[i];
340 + if (addr->sa_family != sa->sa_family)
342 + switch (addr->sa_family) {
344 + p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
345 + q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
346 + l = sizeof(struct in_addr);
350 + p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
351 + q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
352 + l = sizeof(struct in6_addr);
357 + if (memcmp(p, q, l) == 0)
363 int proxy_inet_addr(struct in_addr * addr)
372 /* proxy_inet_addr_list - return list of addresses */
374 --- postfix-2.0.16.orig/src/global/own_inet_addr.h 2002-10-25 01:07:05.000000000 +0200
375 +++ postfix-2.0.16/src/global/own_inet_addr.h 2003-11-08 20:22:55.000000000 +0100
379 #include <netinet/in.h>
381 +#include <sys/socket.h>
385 * External interface.
388 +extern int own_inet_addr(struct sockaddr *);
390 extern int own_inet_addr(struct in_addr *);
392 extern struct INET_ADDR_LIST *own_inet_addr_list(void);
393 extern struct INET_ADDR_LIST *own_inet_mask_list(void);
395 +extern int proxy_inet_addr(struct sockaddr *);
397 extern int proxy_inet_addr(struct in_addr *);
399 extern struct INET_ADDR_LIST *proxy_inet_addr_list(void);
402 --- postfix-2.0.16.orig/src/global/peer_name.c 2001-01-28 16:23:02.000000000 +0100
403 +++ postfix-2.0.16/src/global/peer_name.c 2003-11-08 20:22:55.000000000 +0100
405 PEER_NAME *peer_name(int sock)
407 static PEER_NAME peer;
408 - struct sockaddr_in sin;
409 - SOCKADDR_SIZE len = sizeof(sin);
416 + struct sockaddr peer_un;
417 + struct sockaddr_in peer_un4;
419 + struct sockaddr_in6 peer_un6;
422 +#define sun p_un.peer_un
423 +#define sin p_un.peer_un4
425 +#define sin6 p_un.peer_un6
426 + static char hbuf[NI_MAXHOST];
427 + static char abuf[NI_MAXHOST];
431 + SOCKADDR_SIZE len = sizeof(p_un);
433 - if (getpeername(sock, (struct sockaddr *) & sin, &len) == 0) {
434 - switch (sin.sin_family) {
435 + if (getpeername(sock, (struct sockaddr *)&p_un, &len) == 0) {
436 + switch (p_un.peer_un.sa_family) {
439 peer.type = PEER_TYPE_INET;
440 hp = gethostbyaddr((char *) &(sin.sin_addr),
442 hp->h_name : "unknown");
443 peer.addr = inet_ntoa(sin.sin_addr);
447 + peer.type = PEER_TYPE_INET;
448 + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
449 + peer.name = "unknown";
455 + peer.type = PEER_TYPE_INET6;
456 + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
457 + peer.name = "unknown";
465 peer.type = PEER_TYPE_LOCAL;
466 --- postfix-2.0.16.orig/src/global/peer_name.h 1998-12-11 19:55:32.000000000 +0100
467 +++ postfix-2.0.16/src/global/peer_name.h 2003-11-08 20:22:55.000000000 +0100
469 #define PEER_TYPE_UNKNOWN 0
470 #define PEER_TYPE_INET 1
471 #define PEER_TYPE_LOCAL 2
473 +#define PEER_TYPE_INET6 3
476 extern PEER_NAME *peer_name(int);
478 --- postfix-2.0.16.orig/src/global/resolve_local.c 2002-10-25 01:21:20.000000000 +0200
479 +++ postfix-2.0.16/src/global/resolve_local.c 2003-11-08 20:22:55.000000000 +0100
481 #include <netinet/in.h>
482 #include <arpa/inet.h>
487 #define INADDR_NONE 0xffffffff
490 char *saved_addr = mystrdup(addr);
493 + struct addrinfo hints, *res, *res0;
496 struct in_addr ipaddr;
500 #define RETURN(x) { myfree(saved_addr); return(x); }
502 if (*dest == '[' && dest[len - 1] == ']') {
506 + memset(&hints, 0, sizeof(hints));
507 + hints.ai_family = PF_UNSPEC;
508 + hints.ai_socktype = SOCK_DGRAM;
509 + error = getaddrinfo(dest, NULL, &hints, &res0);
511 + for (res = res0; res; res = res->ai_next) {
512 + if (own_inet_addr(res->ai_addr)) {
513 + freeaddrinfo(res0);
517 + freeaddrinfo(res0);
520 if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE
521 && (own_inet_addr(&ipaddr) || proxy_inet_addr(&ipaddr)))
527 --- postfix-2.0.16.orig/src/global/wildcard_inet_addr.c 1970-01-01 01:00:00.000000000 +0100
528 +++ postfix-2.0.16/src/global/wildcard_inet_addr.c 2003-11-08 20:22:55.000000000 +0100
530 +/* System library. */
532 +#include <sys_defs.h>
533 +#include <netinet/in.h>
534 +#include <arpa/inet.h>
537 +#include <sys/socket.h>
541 +#ifdef STRCASECMP_IN_STRINGS_H
542 +#include <strings.h>
545 +/* Utility library. */
548 +#include <mymalloc.h>
549 +#include <inet_addr_list.h>
550 +#include <inet_addr_local.h>
551 +#include <inet_addr_host.h>
552 +#include <stringops.h>
554 +/* Global library. */
556 +#include <mail_params.h>
557 +#include <wildcard_inet_addr.h>
559 +/* Application-specific. */
560 +static INET_ADDR_LIST addr_list;
562 +/* wildcard_inet_addr_init - initialize my own address list */
564 +static void wildcard_inet_addr_init(INET_ADDR_LIST *addr_list)
567 + struct addrinfo hints, *res, *res0;
568 + char hbuf[NI_MAXHOST];
570 +#ifdef NI_WITHSCOPEID
571 + const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
573 + const int niflags = NI_NUMERICHOST;
576 + inet_addr_list_init(addr_list);
578 + memset(&hints, 0, sizeof(hints));
579 + hints.ai_family = PF_UNSPEC;
580 + hints.ai_socktype = SOCK_STREAM;
581 + hints.ai_flags = AI_PASSIVE;
582 + error = getaddrinfo(NULL, "0", &hints, &res0);
584 + msg_fatal("could not get list of wildcard addresses");
585 + for (res = res0; res; res = res->ai_next) {
586 + if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
588 + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
589 + NULL, 0, niflags) != 0)
591 + if (inet_addr_host(addr_list, hbuf) == 0)
592 + continue; /* msg_fatal("config variable %s: host not found: %s",
593 + VAR_INET_INTERFACES, hbuf); */
595 + freeaddrinfo(res0);
597 + if (inet_addr_host(addr_list, "0.0.0.0") == 0)
598 + msg_fatal("config variable %s: host not found: %s",
599 + VAR_INET_INTERFACES, "0.0.0.0");
603 +/* wildcard_inet_addr_list - return list of addresses */
605 +INET_ADDR_LIST *wildcard_inet_addr_list(void)
607 + if (addr_list.used == 0)
608 + wildcard_inet_addr_init(&addr_list);
610 + return (&addr_list);
612 --- postfix-2.0.16.orig/src/global/wildcard_inet_addr.h 1970-01-01 01:00:00.000000000 +0100
613 +++ postfix-2.0.16/src/global/wildcard_inet_addr.h 2003-11-08 20:22:55.000000000 +0100
615 +#ifndef _WILDCARD_INET_ADDR_H_INCLUDED_
616 +#define _WILDCARD_INET_ADDR_H_INCLUDED_
620 +/* wildcard_inet_addr_list 3h
622 +/* grab the list of wildcard IP addresses.
624 +/* #include <own_inet_addr.h>
632 +#include <netinet/in.h>
634 +#include <sys/socket.h>
638 + * External interface.
640 +extern struct INET_ADDR_LIST *wildcard_inet_addr_list(void);
647 +/* Jun-ichiro itojun Hagino
651 --- postfix-2.0.16.orig/src/master/master_ent.c 2003-06-18 21:19:46.000000000 +0200
652 +++ postfix-2.0.16/src/master/master_ent.c 2003-11-08 20:22:55.000000000 +0100
654 inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
655 serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
656 } else if (strcasecmp(saved_interfaces, DEF_INET_INTERFACES) == 0) {
658 + MASTER_INET_ADDRLIST(serv) = wildcard_inet_addr_list();
659 + serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
661 MASTER_INET_ADDRLIST(serv) = 0; /* wild-card */
662 serv->listen_fd_count = 1;
665 MASTER_INET_ADDRLIST(serv) = own_inet_addr_list(); /* virtual */
666 inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
667 --- postfix-2.0.16.orig/src/master/master_listen.c 2001-05-01 00:47:57.000000000 +0200
668 +++ postfix-2.0.16/src/master/master_listen.c 2003-11-08 20:22:55.000000000 +0100
678 /* master_listen_init - enable connection requests */
680 void master_listen_init(MASTER_SERV *serv)
682 char *myname = "master_listen_init";
687 + char hbuf[NI_MAXHOST];
688 + SOCKADDR_SIZE salen;
692 * Find out what transport we should use, then create one or more
693 @@ -111,18 +120,31 @@
695 inet_listen(MASTER_INET_PORT(serv),
696 serv->max_proc > var_proc_limit ?
697 - serv->max_proc : var_proc_limit, NON_BLOCKING);
698 + serv->max_proc : var_proc_limit, NON_BLOCKING, 1);
699 close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
700 } else { /* virtual or host:port */
701 - for (n = 0; n < serv->listen_fd_count; n++) {
702 + for (m = n = 0; n < serv->listen_fd_count; n++) {
704 + if (getnameinfo((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n],
705 + SA_LEN((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n]),
706 + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) {
707 + strncpy(hbuf, "?????", sizeof(hbuf));
709 + end_point = concatenate(hbuf, ":", MASTER_INET_PORT(serv), (char *) 0);
711 end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]),
712 ":", MASTER_INET_PORT(serv), (char *) 0);
716 = inet_listen(end_point, serv->max_proc > var_proc_limit ?
717 - serv->max_proc : var_proc_limit, NON_BLOCKING);
718 - close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC);
719 + serv->max_proc : var_proc_limit, NON_BLOCKING, 0);
721 + serv->listen_fd[m] = tmpfd;
722 + close_on_exec(serv->listen_fd[m++], CLOSE_ON_EXEC);
726 + serv->listen_fd_count=m;
730 --- postfix-2.0.16.orig/src/smtp/Makefile.in 2003-11-08 20:17:08.000000000 +0100
731 +++ postfix-2.0.16/src/smtp/Makefile.in 2003-11-08 20:22:55.000000000 +0100
733 smtp_connect.o: ../../include/mail_params.h
734 smtp_connect.o: ../../include/own_inet_addr.h
735 smtp_connect.o: ../../include/dns.h
736 +smtp_connect.o: ../../include/get_port.h
737 smtp_connect.o: smtp.h
738 smtp_connect.o: ../../include/argv.h
739 smtp_connect.o: ../../include/deliver_request.h
740 --- postfix-2.0.16.orig/src/smtp/smtp_addr.c 2002-10-25 01:03:11.000000000 +0200
741 +++ postfix-2.0.16/src/smtp/smtp_addr.c 2003-11-08 20:22:55.000000000 +0100
742 @@ -134,18 +134,68 @@
743 static void smtp_print_addr(char *what, DNS_RR *addr_list)
746 - struct in_addr in_addr;
748 + struct sockaddr_storage ss;
750 + struct sockaddr ss;
752 + struct sockaddr_in *sin;
754 + struct sockaddr_in6 *sin6;
755 + char hbuf[NI_MAXHOST];
757 + char hbuf[sizeof("255.255.255.255") + 1];
760 msg_info("begin %s address list", what);
761 for (addr = addr_list; addr; addr = addr->next) {
762 - if (addr->data_len > sizeof(addr)) {
763 - msg_warn("skipping address length %d", addr->data_len);
765 - memcpy((char *) &in_addr, addr->data, sizeof(in_addr));
766 - msg_info("pref %4d host %s/%s",
767 - addr->pref, addr->name,
768 - inet_ntoa(in_addr));
769 + if (addr->class != C_IN) {
770 + msg_warn("skipping unsupported address (class=%u)", addr->class);
773 + switch (addr->type) {
775 + if (addr->data_len != sizeof(sin->sin_addr)) {
776 + msg_warn("skipping invalid address (AAAA, len=%u)",
780 + sin = (struct sockaddr_in *)&ss;
781 + memset(sin, 0, sizeof(*sin));
782 + sin->sin_family = AF_INET;
784 + sin->sin_len = sizeof(*sin);
786 + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
790 + if (addr->data_len != sizeof(sin6->sin6_addr)) {
791 + msg_warn("skipping invalid address (AAAA, len=%u)",
795 + sin6 = (struct sockaddr_in6 *)&ss;
796 + memset(sin6, 0, sizeof(*sin6));
797 + sin6->sin6_family = AF_INET6;
799 + sin6->sin6_len = sizeof(*sin6);
801 + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
805 + msg_warn("skipping unsupported address (type=%u)", addr->type);
810 + (void)getnameinfo((struct sockaddr *)&ss, SS_LEN(ss),
811 + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
813 + (void)inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
815 + msg_info("pref %4d host %s/%s", addr->pref, addr->name, hbuf);
817 msg_info("end %s address list", what);
819 @@ -155,15 +205,23 @@
820 static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
822 char *myname = "smtp_addr_one";
824 struct in_addr inaddr;
830 + struct addrinfo hints, *res0, *res;
838 msg_info("%s: host %s", myname, host);
842 * Interpret a numerical name as an address.
845 smtp_errno = SMTP_FAIL;
849 + memset(&hints, 0, sizeof(hints));
850 + hints.ai_family = PF_UNSPEC;
851 + hints.ai_socktype = SOCK_STREAM;
852 + error = getaddrinfo(host, NULL, &hints, &res0);
856 + smtp_errno = SMTP_RETRY;
859 + vstring_sprintf(why, "[%s]: %s",host,gai_strerror(error));
860 + smtp_errno = SMTP_FAIL;
863 + return (addr_list);
865 + for (res = res0; res; res = res->ai_next) {
866 + memset((char *) &fixed, 0, sizeof(fixed));
867 + switch(res->ai_family) {
869 + /* XXX not scope friendly */
870 + fixed.type = T_AAAA;
871 + addr = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
872 + addrlen = sizeof(struct in6_addr);
876 + addr = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr;
877 + addrlen = sizeof(struct in_addr);
880 + msg_warn("%s: unknown address family %d for %s",
881 + myname, res->ai_family, host);
884 + addr_list = dns_rr_append(addr_list,
885 + dns_rr_create(host, &fixed, pref, addr, addrlen));
888 + freeaddrinfo(res0);
894 INET_ADDR_LIST *self;
898 + struct sockaddr *sa;
902 * Find the first address that lists any address that this mail system is
903 @@ -260,12 +363,36 @@
905 self = own_inet_addr_list();
906 for (addr = addr_list; addr; addr = addr->next) {
907 - for (i = 0; i < self->used; i++)
908 + for (i = 0; i < self->used; i++) {
910 + sa = (struct sockaddr *)&self->addrs[i];
911 + switch(addr->type) {
914 + if (sa->sa_family != AF_INET6)
916 + if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
917 + addr->data, sizeof(struct in6_addr)) == 0) {
922 + if (sa->sa_family != AF_INET)
924 + if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
925 + addr->data, sizeof(struct in_addr)) == 0) {
931 if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
933 msg_info("%s: found at pref %d", myname, addr->pref);
941 @@ -273,12 +400,36 @@
943 self = proxy_inet_addr_list();
944 for (addr = addr_list; addr; addr = addr->next) {
945 - for (i = 0; i < self->used; i++)
946 + for (i = 0; i < self->used; i++) {
948 + sa = (struct sockaddr *)&self->addrs[i];
949 + switch(addr->type) {
952 + if (sa->sa_family != AF_INET6)
954 + if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
955 + addr->data, sizeof(struct in6_addr)) == 0) {
960 + if (sa->sa_family != AF_INET)
962 + if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
963 + addr->data, sizeof(struct in_addr)) == 0) {
969 if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
971 msg_info("%s: found at pref %d", myname, addr->pref);
979 --- postfix-2.0.16.orig/src/smtp/smtp_connect.c 2003-11-08 20:17:08.000000000 +0100
980 +++ postfix-2.0.16/src/smtp/smtp_connect.c 2003-11-08 20:32:33.000000000 +0100
982 /* System library. */
984 #include <sys_defs.h>
986 #include <sys/socket.h>
987 #include <netinet/in.h>
988 #include <arpa/inet.h>
990 #include <inet_addr_list.h>
992 #include <timed_connect.h>
993 +#include <get_port.h>
994 #include <stringops.h>
995 #include <host_port.h>
996 #include <sane_connect.h>
997 @@ -135,19 +137,45 @@
1000 char *myname = "smtp_connect_addr";
1001 - struct sockaddr_in sin;
1004 + struct sockaddr_storage ss;
1006 + struct sockaddr ss;
1008 + struct sockaddr *sa;
1009 + struct sockaddr_in *sin;
1011 + struct sockaddr_in6 *sin6;
1013 + SOCKADDR_SIZE salen;
1015 + char hbuf[NI_MAXHOST];
1017 + char hbuf[sizeof("255.255.255.255") + 1];
1020 INET_ADDR_LIST *addr_list;
1025 - unsigned long inaddr;
1027 + sa = (struct sockaddr *)&ss;
1028 + sin = (struct sockaddr_in *)&ss;
1030 + sin6 = (struct sockaddr_in6 *)&ss;
1036 - if (addr->data_len > sizeof(sin.sin_addr)) {
1038 + if (((addr->type==T_A) && (addr->data_len > sizeof(sin->sin_addr))) ||
1039 + ((addr->type==T_AAAA) && (addr->data_len > sizeof(sin6->sin6_addr))))
1041 + if (addr->data_len > sizeof(sin->sin_addr))
1044 msg_warn("%s: skip address with length %d", myname, addr->data_len);
1045 smtp_errno = SMTP_RETRY;
1047 @@ -156,17 +184,39 @@
1051 - memset((char *) &sin, 0, sizeof(sin));
1052 - sin.sin_family = AF_INET;
1054 - if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
1055 - msg_fatal("%s: socket: %m", myname);
1057 + switch (addr->type) {
1060 + memset(sin6, 0, sizeof(*sin6));
1061 + sin6->sin6_family = AF_INET6;
1062 + salen = sizeof(*sin6);
1065 + default: /* T_A: */
1066 + memset(sin, 0, sizeof(*sin));
1067 + sin->sin_family = AF_INET;
1068 + salen = sizeof(*sin);
1072 + sa->sa_len = salen;
1074 + if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
1075 + msg_warn("%s: socket: %m", myname);
1078 * Allow the sysadmin to specify the source address, for example, as "-o
1079 * smtp_bind_address=x.x.x.x" in the master.cf file.
1081 if (*var_smtp_bind_addr) {
1083 + struct sockaddr_in sin;
1085 + memset(&sin, 0, sizeof(sin));
1086 + sin.sin_family = AF_INET;
1088 + sin.sin_len = sizeof(sin);
1090 sin.sin_addr.s_addr = inet_addr(var_smtp_bind_addr);
1091 if (sin.sin_addr.s_addr == INADDR_NONE)
1092 msg_fatal("%s: bad %s parameter: %s",
1093 @@ -175,6 +225,25 @@
1094 msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr));
1096 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1098 + char hbufl[NI_MAXHOST];
1099 + struct addrinfo hints, *res;
1101 + memset(&hints, 0, sizeof(hints));
1102 + hints.ai_family = sa->sa_family;
1103 + hints.ai_socktype = SOCK_STREAM;
1104 + hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1105 + snprintf(hbufl, sizeof(hbufl)-1, "%s", var_smtp_bind_addr);
1106 + if (getaddrinfo(hbufl, NULL, &hints, &res) == 0) {
1107 + (void)getnameinfo(res->ai_addr, res->ai_addrlen, hbufl,
1108 + sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1109 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1110 + msg_warn("%s: bind %s: %m", myname, hbufl);
1111 + freeaddrinfo(res);
1113 + msg_info("%s: bind %s", myname, hbufl);
1119 @@ -182,8 +251,17 @@
1120 * the mail appears to come from the "right" machine address.
1122 else if ((addr_list = own_inet_addr_list())->used == 1) {
1124 + struct sockaddr_in sin;
1125 + unsigned long inaddr; /*XXX BAD!*/
1127 + memset(&sin, 0, sizeof(sin));
1128 + sin.sin_family = AF_INET;
1130 + sin.sin_len = sizeof(sin);
1132 memcpy((char *) &sin.sin_addr, addr_list->addrs, sizeof(sin.sin_addr));
1133 - inaddr = ntohl(sin.sin_addr.s_addr);
1134 + inaddr = (unsigned long)ntohl(sin.sin_addr.s_addr);
1135 if (!IN_CLASSA(inaddr)
1136 || !(((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)) {
1137 if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
1138 @@ -191,30 +269,85 @@
1140 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1143 + char hbufl[NI_MAXHOST];
1144 + struct addrinfo hints, *res = NULL, *loopback = NULL;
1146 + memset(&hints, 0, sizeof(hints));
1147 + hints.ai_family = sa->sa_family;
1148 + hints.ai_socktype = SOCK_STREAM;
1149 + if (getaddrinfo(NULL, "0", &hints, &loopback) != 0)
1153 + * getnameinfo -> getaddrinfo loop is here so that we can
1154 + * get rid of port.
1156 + (void)getnameinfo((struct sockaddr *)addr_list->addrs, SA_LEN((struct sockaddr *)addr_list->addrs),
1157 + hbufl, sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1158 + hbufl[sizeof(hbufl)-1] = 0;
1159 + memset(&hints, 0, sizeof(hints));
1160 + hints.ai_family = sa->sa_family;
1161 + hints.ai_socktype = SOCK_STREAM;
1162 + hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1163 + if (getaddrinfo(hbufl, NULL, &hints, &res) == 0 &&
1164 + !(res->ai_addrlen == loopback->ai_addrlen &&
1165 + memcmp(res->ai_addr, loopback->ai_addr, res->ai_addrlen) == 0)) {
1166 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1167 + msg_warn("%s: bind %s: %m", myname, hbufl);
1169 + msg_info("%s: bind %s", myname, hbufl);
1172 + freeaddrinfo(res);
1174 + freeaddrinfo(loopback);
1179 * Connect to the SMTP server.
1181 - sin.sin_port = port;
1182 - memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr));
1183 + switch (addr->type) {
1186 + /* XXX scope unfriendly */
1187 + memset(sin6, 0, sizeof(*sin6));
1188 + sin6->sin6_port = port;
1189 + sin6->sin6_family = AF_INET6;
1190 + salen = sizeof(*sin6);
1191 + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
1192 + inet_ntop(AF_INET6, &sin6->sin6_addr, hbuf, sizeof(hbuf));
1195 + default: /* T_A */
1196 + memset(sin, 0, sizeof(*sin));
1197 + sin->sin_port = port;
1198 + sin->sin_family = AF_INET;
1199 + salen = sizeof(*sin);
1200 + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
1201 + inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
1205 + sa->sa_len = salen;
1209 msg_info("%s: trying: %s[%s] port %d...",
1210 - myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port));
1211 + myname, addr->name, hbuf, ntohs(port));
1212 if (var_smtp_conn_tmout > 0) {
1213 non_blocking(sock, NON_BLOCKING);
1214 - conn_stat = timed_connect(sock, (struct sockaddr *) & sin,
1215 - sizeof(sin), var_smtp_conn_tmout);
1216 + conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout);
1217 saved_errno = errno;
1218 non_blocking(sock, BLOCKING);
1219 errno = saved_errno;
1221 - conn_stat = sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin));
1222 + conn_stat = connect(sock, sa, salen);
1224 if (conn_stat < 0) {
1225 vstring_sprintf(why, "connect to %s[%s]: %m",
1226 - addr->name, inet_ntoa(sin.sin_addr));
1227 + addr->name, hbuf);
1228 smtp_errno = SMTP_RETRY;
1232 * Skip this host if it takes no action within some time limit.
1234 if (read_wait(sock, var_smtp_helo_tmout) < 0) {
1235 - vstring_sprintf(why, "connect to %s[%s]: read timeout",
1236 - addr->name, inet_ntoa(sin.sin_addr));
1237 + vstring_sprintf(why, "connect to %s [%s]: read timeout",
1238 + addr->name, hbuf);
1239 smtp_errno = SMTP_RETRY;
1243 stream = vstream_fdopen(sock, O_RDWR);
1244 if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
1245 vstring_sprintf(why, "connect to %s[%s]: server dropped connection without sending the initial greeting",
1246 - addr->name, inet_ntoa(sin.sin_addr));
1247 + addr->name, hbuf);
1248 smtp_errno = SMTP_RETRY;
1249 vstream_fclose(stream);
1253 if (ch == '4' && var_smtp_skip_4xx_greeting) {
1254 vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1255 - addr->name, inet_ntoa(sin.sin_addr));
1256 + addr->name, hbuf);
1257 smtp_errno = SMTP_RETRY;
1258 vstream_fclose(stream);
1260 @@ -260,12 +393,12 @@
1262 if (ch == '5' && var_smtp_skip_5xx_greeting) {
1263 vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1264 - addr->name, inet_ntoa(sin.sin_addr));
1265 + addr->name, hbuf);
1266 smtp_errno = SMTP_RETRY;
1267 vstream_fclose(stream);
1270 - return (smtp_session_alloc(dest, stream, addr->name, inet_ntoa(sin.sin_addr)));
1271 + return (smtp_session_alloc(dest, stream, addr->name, hbuf));
1274 /* smtp_connect_host - direct connection to host */
1275 --- postfix-2.0.16.orig/src/smtp/smtp_unalias.c 2000-09-28 19:06:09.000000000 +0200
1276 +++ postfix-2.0.16/src/smtp/smtp_unalias.c 2003-11-08 20:22:55.000000000 +0100
1278 if ((result = htable_find(cache, name)) == 0) {
1279 fqdn = vstring_alloc(10);
1280 if (dns_lookup_types(name, smtp_unalias_flags, (DNS_RR **) 0,
1281 - fqdn, (VSTRING *) 0, T_MX, T_A, 0) != DNS_OK)
1282 + fqdn, (VSTRING *) 0, T_MX, T_A,
1287 vstring_strcpy(fqdn, name);
1288 htable_enter(cache, name, result = vstring_export(fqdn));
1290 --- postfix-2.0.16.orig/src/smtpd/smtpd_check.c 2003-11-08 20:17:08.000000000 +0100
1291 +++ postfix-2.0.16/src/smtpd/smtpd_check.c 2003-11-08 20:22:55.000000000 +0100
1292 @@ -1369,6 +1369,49 @@
1293 static int has_my_addr(SMTPD_STATE *state, const char *host,
1294 const char *reply_name, const char *reply_class)
1297 + char *myname = "has_my_addr";
1298 + struct addrinfo hints, *res, *res0;
1300 + char hbuf[NI_MAXHOST];
1303 + msg_info("%s: host %s", myname, host);
1306 + * If we can't lookup the host, play safe and assume it is OK.
1311 + memset(&hints, 0, sizeof(hints));
1312 + hints.ai_family = PF_UNSPEC;
1313 + hints.ai_socktype = SOCK_DGRAM;
1314 + error = getaddrinfo(host, NULL, &hints, &res0);
1317 + msg_info("%s: host %s: %s", myname, host, gai_strerror(error));
1320 + for (res = res0; res; res = res->ai_next) {
1321 + if (msg_verbose) {
1322 + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
1323 + NULL, 0, NI_NUMERICHOST)) {
1324 + strncpy(hbuf, "???", sizeof(hbuf));
1326 + msg_info("%s: addr %s", myname, hbuf);
1328 + if (own_inet_addr(res->ai_addr)) {
1329 + freeaddrinfo(res0);
1333 + freeaddrinfo(res0);
1335 + msg_info("%s: host %s: no match", myname, host);
1339 char *myname = "has_my_addr";
1340 struct in_addr addr;
1342 @@ -1407,6 +1450,7 @@
1343 msg_info("%s: host %s: no match", myname, host);
1349 /* i_am_mx - is this machine listed as MX relay */
1350 @@ -1991,11 +2035,28 @@
1351 #define CHK_ADDR_RETURN(x,y) { *found = y; return(x); }
1353 addr = STR(vstring_strcpy(error_text, address));
1356 + if (strncmp(addr, "::ffff:", 7) == 0 && msg_verbose)
1357 + msg_info("%s: %s v6 addr in v4 compat-mode, "
1358 + "converted to v4 for map checking compatibility (%s)", \
1359 + myname, addr, addr+7);
1362 if ((dict = dict_handle(table)) == 0)
1363 msg_panic("%s: dictionary not found: %s", myname, table);
1365 if (flags == 0 || (flags & dict->flags) != 0) {
1367 + if (strncmp(addr, "::ffff:", 7) == 0) {
1368 + /* try if ::ffff: formati is present in map, if not, try
1369 + traditional IPv4 format striping :ffff: part */
1370 + if ((value = dict_get(dict, addr)) != 0 || \
1371 + (value = dict_get(dict, addr+7)) != 0)
1372 + CHK_ADDR_RETURN(check_table_result(state, table, value, address,
1373 + reply_name, reply_class,
1377 if ((value = dict_get(dict, addr)) != 0)
1378 CHK_ADDR_RETURN(check_table_result(state, table, value, address,
1379 reply_name, reply_class,
1380 @@ -2438,16 +2499,32 @@
1383 SMTPD_RBL_STATE *rbl;
1387 + struct in6_addr a;
1391 msg_info("%s: %s %s", myname, reply_class, addr);
1394 - * IPv4 only for now
1398 + /* IPv4 only for now */
1399 if (inet_pton(AF_INET, addr, &a) != 1)
1400 return SMTPD_CHECK_DUNNO;
1401 + octets = argv_split(state->addr, ".");
1403 + /* IPv4 and IPv6-mapped IPv4 only for now */
1404 + if (inet_pton(AF_INET, state->addr, &a) == 1)
1405 + octets = argv_split(state->addr, ".");
1407 + struct in6_addr a6;
1408 + if (inet_pton(AF_INET6, state->addr, &a6) != 1)
1409 + return SMTPD_CHECK_DUNNO;
1410 + if (!IN6_IS_ADDR_V4MAPPED(&a6) || (strrchr(state->addr,':') == NULL))
1411 + return SMTPD_CHECK_DUNNO;
1412 + octets = argv_split(strrchr(state->addr,':')+1, ".");
1417 --- postfix-2.0.16.orig/src/smtpd/smtpd_peer.c 2002-08-22 19:50:51.000000000 +0200
1418 +++ postfix-2.0.16/src/smtpd/smtpd_peer.c 2003-11-08 20:22:55.000000000 +0100
1423 +/* Utility library. */
1426 +#include <mymalloc.h>
1427 +#include <valid_hostname.h>
1428 +#include <stringops.h>
1430 +/* Global library. */
1433 * Older systems don't have h_errno. Even modern systems don't have
1439 -/* Utility library. */
1442 -#include <mymalloc.h>
1443 -#include <valid_hostname.h>
1444 -#include <stringops.h>
1446 -/* Global library. */
1450 +#define GAI_STRERROR(error) \
1451 + ((error = EAI_SYSTEM) ? gai_strerror(error) : strerror(errno))
1454 /* Application-specific. */
1457 @@ -102,21 +106,28 @@
1459 void smtpd_peer_init(SMTPD_STATE *state)
1461 - struct sockaddr_in sin;
1462 - SOCKADDR_SIZE len = sizeof(sin);
1464 + struct sockaddr_storage ss;
1466 + struct sockaddr ss;
1467 + struct in_addr *in;
1471 + struct sockaddr *sa;
1472 + SOCKADDR_SIZE len;
1474 + sa = (struct sockaddr *)&ss;
1478 * Avoid suprious complaints from Purify on Solaris.
1480 - memset((char *) &sin, 0, len);
1481 + memset((char *) sa, 0, len);
1484 * Look up the peer address information.
1486 - if (getpeername(vstream_fileno(state->client),
1487 - (struct sockaddr *) & sin, &len) >= 0) {
1488 + if (getpeername(vstream_fileno(state->client), sa, &len) >= 0) {
1492 @@ -132,23 +143,56 @@
1494 * Look up and "verify" the client hostname.
1496 - else if (errno == 0 && sin.sin_family == AF_INET) {
1497 - state->addr = mystrdup(inet_ntoa(sin.sin_addr));
1498 - hp = gethostbyaddr((char *) &(sin.sin_addr),
1499 - sizeof(sin.sin_addr), AF_INET);
1501 + else if (errno == 0 && (sa->sa_family == AF_INET
1503 + || sa->sa_family == AF_INET6
1507 + char hbuf[NI_MAXHOST];
1508 + char abuf[NI_MAXHOST];
1509 + struct addrinfo hints, *rnull = NULL;
1511 + char abuf[sizeof("255.255.255.255") + 1];
1517 + (void)getnameinfo(sa, len, abuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
1519 + in = &((struct sockaddr_in *)sa)->sin_addr;
1520 + inet_ntop(AF_INET, in, abuf, sizeof(hbuf));
1522 + state->addr = mystrdup(abuf);
1524 + error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD);
1527 + hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET);
1530 + hbuf = mystrdup(hp->h_name);
1535 state->name = mystrdup("unknown");
1537 + state->peer_code = (error == EAI_AGAIN ? 4 : 5);
1539 state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
1540 - } else if (valid_hostaddr(hp->h_name, DONT_GRIPE)) {
1542 + } else if (valid_hostaddr(hbuf, DONT_GRIPE)) {
1543 msg_warn("numeric result %s in address->name lookup for %s",
1544 - hp->h_name, state->addr);
1545 + hbuf, state->addr);
1546 state->name = mystrdup("unknown");
1547 state->peer_code = 5;
1548 - } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
1549 + } else if (!valid_hostname(hbuf, DONT_GRIPE)) {
1550 state->name = mystrdup("unknown");
1551 state->peer_code = 5;
1553 - state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */
1554 + state->name = mystrdup(hbuf); /* hp->name is clobbered!! */
1555 state->peer_code = 2;
1558 @@ -160,16 +204,31 @@
1559 state->peer_code = code; \
1563 + memset(&hints, 0, sizeof(hints));
1564 + hints.ai_family = AF_UNSPEC;
1565 + hints.ai_socktype = SOCK_STREAM;
1566 + error = getaddrinfo(state->name, NULL, &hints, &rnull);
1568 + msg_warn("%s: hostname %s verification failed: %s",
1569 + state->addr, state->name, GAI_STRERROR(error));
1570 + REJECT_PEER_NAME(state, (error == EAI_AGAIN ? 4 : 5));
1572 + /* memcmp() isn't needed if we use getaddrinfo */
1574 + freeaddrinfo(rnull);
1576 hp = gethostbyname(state->name); /* clobbers hp->name!! */
1578 msg_warn("%s: hostname %s verification failed: %s",
1579 state->addr, state->name, HSTRERROR(h_errno));
1580 REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ? 4 : 5));
1581 - } else if (hp->h_length != sizeof(sin.sin_addr)) {
1582 + } else if (hp->h_length != sizeof(*in)) {
1583 msg_warn("%s: hostname %s verification failed: bad address size %d",
1584 state->addr, state->name, hp->h_length);
1585 REJECT_PEER_NAME(state, 5);
1588 for (i = 0; /* void */ ; i++) {
1589 if (hp->h_addr_list[i] == 0) {
1590 msg_warn("%s: address not listed for hostname %s",
1591 @@ -177,12 +236,11 @@
1592 REJECT_PEER_NAME(state, 5);
1595 - if (memcmp(hp->h_addr_list[i],
1596 - (char *) &sin.sin_addr,
1597 - sizeof(sin.sin_addr)) == 0)
1598 + if (memcmp(hp->h_addr_list[i], (char *)in, sizeof(*in)) == 0)
1599 break; /* keep peer name */
1606 --- postfix-2.0.16.orig/src/smtpstone/smtp-sink.c 2003-09-13 02:46:56.000000000 +0200
1607 +++ postfix-2.0.16/src/smtpstone/smtp-sink.c 2003-11-08 20:22:55.000000000 +0100
1610 if (strncmp(argv[optind], "inet:", 5) == 0)
1612 - sock = inet_listen(argv[optind], backlog, BLOCKING);
1613 + sock = inet_listen(argv[optind], backlog, BLOCKING, 1);
1617 --- postfix-2.0.16.orig/src/util/get_port.c 1970-01-01 01:00:00.000000000 +0100
1618 +++ postfix-2.0.16/src/util/get_port.c 2003-11-08 20:22:55.000000000 +0100
1624 +/* trivial host and port extracter
1626 +/* #include <get_port.h>
1628 +/* char *get_port(data)
1632 +/* get_port() extract host name or ip address from
1633 +/* strings such as [3ffe:902:12::10]:25, [::1]
1634 +/* or 192.168.0.1:25, and null-terminates the
1635 +/* \fIdata\fR at the first occurrence of port separator.
1637 +/* If port not found return null pointer.
1641 +/* BSD Style (or BSD like) license.
1643 +/* Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1647 +/* System libraries */
1649 +#include <sys_defs.h>
1650 +#include <string.h>
1652 +/* Utility library. */
1654 +#include "get_port.h"
1656 +/* get_port - extract port number from string */
1658 +char *get_port(char *data)
1660 + const char *escl=strchr(data,'[');
1661 + const char *sepl=strchr(data,':');
1662 + char *escr=strrchr(data,']');
1663 + char *sepr=strrchr(data,':');
1665 + /* extract from "[address]:port" or "[address]"*/
1668 + memmove(data, data + 1, strlen(data) - strlen(escr));
1669 + data[strlen(data) - strlen(escr) - 1] = 0;
1673 + return (*escr ? escr : NULL);
1675 + /* extract from "address:port" or "address" */
1676 + if ((sepl == sepr) && sepr && sepl)
1682 + /* return empty string */
1685 --- postfix-2.0.16.orig/src/util/get_port.h 1970-01-01 01:00:00.000000000 +0100
1686 +++ postfix-2.0.16/src/util/get_port.h 2003-11-08 20:22:55.000000000 +0100
1688 +#ifndef _GET_PORT_H_INCLUDED_
1689 +#define _GET_PORT_H_INCLUDED_
1695 +/* trivial host and port extracter
1697 +/* #include <get_port.h>
1701 + /* External interface. */
1703 +extern char *get_port(char *);
1709 +/* BSD Style (or BSD like) license.
1711 +/* Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1716 --- postfix-2.0.16.orig/src/util/inet_addr_host.c 1998-12-11 19:55:35.000000000 +0100
1717 +++ postfix-2.0.16/src/util/inet_addr_host.c 2003-11-08 20:22:55.000000000 +0100
1719 #include <sys_defs.h>
1720 #include <netinet/in.h>
1721 #include <arpa/inet.h>
1722 +#include <sys/socket.h>
1724 +#include <stdlib.h>
1725 +#include <string.h>
1728 #define INADDR_NONE 0xffffffff
1731 #include <inet_addr_list.h>
1732 #include <inet_addr_host.h>
1737 /* inet_addr_host - look up address list for host */
1739 int inet_addr_host(INET_ADDR_LIST *addr_list, const char *hostname)
1743 + struct addrinfo hints, *res0, *res;
1745 + char buforhosta[1024];
1750 struct in_addr addr;
1752 int initial_count = addr_list->used;
1755 + memset(&hints, 0, sizeof(hints));
1756 + hints.ai_family = PF_UNSPEC;
1757 + hints.ai_socktype = SOCK_DGRAM;
1758 + error = getaddrinfo(hostname, NULL, &hints, &res0);
1760 + for (res = res0; res; res = res->ai_next) {
1761 + if(res->ai_family != AF_INET && res->ai_family != AF_INET6)
1763 + /* filter out address families that are not supported */
1764 + s = socket(res->ai_family, SOCK_DGRAM, 0);
1769 + inet_addr_list_append(addr_list, res->ai_addr);
1771 + freeaddrinfo(res0);
1774 if ((addr.s_addr = inet_addr(hostname)) != INADDR_NONE) {
1775 inet_addr_list_append(addr_list, &addr);
1778 inet_addr_list_append(addr_list,
1779 (struct in_addr *) * hp->h_addr_list++);
1783 return (addr_list->used - initial_count);
1792 INET_ADDR_LIST addr_list;
1794 + struct sockaddr *sa;
1795 + char hbuf[NI_MAXHOST];
1797 msg_vstream_init(argv[0], VSTREAM_ERR);
1800 if (inet_addr_host(&addr_list, *argv) == 0)
1801 msg_fatal("not found: %s", *argv);
1803 - for (i = 0; i < addr_list.used; i++)
1804 - vstream_printf("%s\n", inet_ntoa(addr_list.addrs[i]));
1805 + for (i = 0; i < addr_list.used; i++) {
1806 + sa = (struct sockaddr *)&addr_list.addrs[i];
1807 + getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
1809 + vstream_printf("%s\n", hbuf);
1811 vstream_fflush(VSTREAM_OUT);
1813 inet_addr_list_free(&addr_list);
1814 --- postfix-2.0.16.orig/src/util/inet_addr_list.c 2001-07-31 20:13:41.000000000 +0200
1815 +++ postfix-2.0.16/src/util/inet_addr_list.c 2003-11-08 20:22:55.000000000 +0100
1817 #include <arpa/inet.h>
1823 +#include <string.h>
1824 +#include <sys/socket.h>
1827 /* Utility library. */
1835 + list->addrs = (struct sockaddr_storage *)
1837 list->addrs = (struct in_addr *)
1839 mymalloc(sizeof(*list->addrs) * list->size);
1842 /* inet_addr_list_append - append address to internet address list */
1845 +void inet_addr_list_append(INET_ADDR_LIST *list,
1846 + struct sockaddr * addr)
1848 + char *myname = "inet_addr_list_append";
1849 + char hbuf[NI_MAXHOST];
1851 + if (msg_verbose > 1) {
1852 + if (getnameinfo(addr, SA_LEN(addr), hbuf, sizeof(hbuf), NULL, 0,
1853 + NI_NUMERICHOST)) {
1854 + strncpy(hbuf, "??????", sizeof(hbuf));
1856 + msg_info("%s: %s", myname, hbuf);
1859 + if (list->used >= list->size)
1861 + list->addrs = (struct sockaddr_storage *)
1862 + myrealloc((char *) list->addrs,
1863 + sizeof(*list->addrs) * list->size);
1864 + memcpy(&list->addrs[list->used++], addr, SA_LEN(addr));
1867 void inet_addr_list_append(INET_ADDR_LIST *list, struct in_addr * addr)
1869 char *myname = "inet_addr_list_append";
1870 @@ -83,15 +117,22 @@
1871 sizeof(*list->addrs) * list->size);
1872 list->addrs[list->used++] = *addr;
1876 /* inet_addr_list_comp - compare addresses */
1878 static int inet_addr_list_comp(const void *a, const void *b)
1881 + if(((struct sockaddr*)a)->sa_family != ((struct sockaddr*)b)->sa_family)
1882 + return ( ((struct sockaddr*)a)->sa_family - ((struct sockaddr*)b)->sa_family );
1883 + return memcmp(a,b,SA_LEN((struct sockaddr*)a));
1885 const struct in_addr *a_addr = (const struct in_addr *) a;
1886 const struct in_addr *b_addr = (const struct in_addr *) b;
1888 return (a_addr->s_addr - b_addr->s_addr);
1892 /* inet_addr_list_uniq - weed out duplicates */
1893 --- postfix-2.0.16.orig/src/util/inet_addr_list.h 2001-07-31 19:56:47.000000000 +0200
1894 +++ postfix-2.0.16/src/util/inet_addr_list.h 2003-11-08 20:22:55.000000000 +0100
1897 #include <netinet/in.h>
1901 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1902 +#define SS_LEN(x) (((x).ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1904 +#define SA_LEN(x) ((x)->sa_len)
1905 +#define SS_LEN(x) ((x).ss_len)
1910 * External interface.
1912 typedef struct INET_ADDR_LIST {
1913 int used; /* nr of elements in use */
1914 int size; /* actual list size */
1916 + struct sockaddr_storage *addrs; /* payload */
1918 struct in_addr *addrs; /* payload */
1922 extern void inet_addr_list_init(INET_ADDR_LIST *);
1923 extern void inet_addr_list_free(INET_ADDR_LIST *);
1924 extern void inet_addr_list_uniq(INET_ADDR_LIST *);
1927 +extern void inet_addr_list_append(INET_ADDR_LIST *, struct sockaddr *);
1929 extern void inet_addr_list_append(INET_ADDR_LIST *, struct in_addr *);
1934 --- postfix-2.0.16.orig/src/util/inet_addr_local.c 2001-02-25 19:20:19.000000000 +0100
1935 +++ postfix-2.0.16/src/util/inet_addr_local.c 2003-11-08 20:22:55.000000000 +0100
1940 +#if defined(INET6) && (defined (LINUX) || defined (LINUX2))
1944 +#ifdef HAVE_GETIFADDRS
1945 +#include <ifaddrs.h>
1948 /* Utility library. */
1950 @@ -78,18 +85,104 @@
1952 int inet_addr_local(INET_ADDR_LIST *addr_list, INET_ADDR_LIST *mask_list)
1954 +#ifdef HAVE_GETIFADDRS
1955 + char *myname = "inet_addr_local";
1956 + struct ifaddrs *ifap, *ifa;
1957 + int initial_count = addr_list->used;
1958 + struct sockaddr *sa, *sam;
1961 + struct sockaddr_in6 addr6;
1964 + void *addr,*addrm;
1967 + if (getifaddrs(&ifap) < 0)
1968 + msg_fatal("%s: getifaddrs: %m", myname);
1970 + for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1971 + if ((!(ifa->ifa_flags & IFF_RUNNING)) || (ifa->ifa_addr == NULL) || (ifa->ifa_netmask == NULL))
1973 + sa = ifa->ifa_addr;
1974 + sam = ifa->ifa_netmask;
1975 + switch (ifa->ifa_addr->sa_family) {
1978 + addr = (void *)&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
1979 + addrm = (void *)&((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
1985 + memcpy(&addr6, ifa->ifa_addr, ifa->ifa_addr->sa_len);
1986 + /* decode scoped address notation */
1987 + if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
1988 + IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
1989 + addr6.sin6_scope_id == 0) {
1990 + addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
1991 + (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
1992 + addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
1993 + sa = (struct sockaddr *)&addr6;
2003 + inet_addr_list_append(addr_list, sa);
2004 + if (mask_list != NULL)
2005 + inet_addr_list_append(mask_list, sam);
2007 + inet_addr_list_append(addr_list, (struct in_addr *)addr);
2008 + if (mask_list != NULL)
2009 + inet_addr_list_append(mask_list, (struct in_addr *)addrm);
2013 + freeifaddrs(ifap);
2014 + return (addr_list->used - initial_count);
2016 char *myname = "inet_addr_local";
2019 struct ifreq *the_end;
2021 - VSTRING *buf = vstring_alloc(1024);
2023 int initial_count = addr_list->used;
2024 struct in_addr addr;
2025 struct ifreq *ifr_mask;
2028 +#if defined (LINUX) || defined (LINUX2)
2029 +#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
2031 + char addr6p[8][5], addr6res[40], devname[20];
2032 + int plen, scope, dad_status, if_idx, gaierror;
2033 + struct addrinfo hints, *res, *res0;
2035 + struct sockaddr_in6 addr6;
2039 + buf = vstring_alloc(1024);
2041 - if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
2042 + if ((sock = socket(af, SOCK_DGRAM, 0)) < 0) {
2044 + if (af == AF_INET6)
2047 + msg_warn("%s: socket: %m", myname);
2052 msg_fatal("%s: socket: %m", myname);
2056 * Get the network interface list. XXX The socket API appears to have no
2057 @@ -126,10 +219,15 @@
2059 the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2060 for (ifr = ifc.ifc_req; ifr < the_end;) {
2061 - if (ifr->ifr_addr.sa_family == AF_INET) { /* IP interface */
2062 + if ((ifr->ifr_addr.sa_family == AF_INET) &&
2063 + (ifr->ifr_addr.sa_family == af)) { /* IP interface */
2064 addr = ((struct sockaddr_in *) & ifr->ifr_addr)->sin_addr;
2065 if (addr.s_addr != INADDR_ANY) { /* has IP address */
2067 + inet_addr_list_append(addr_list, &ifr->ifr_addr);
2069 inet_addr_list_append(addr_list, &addr);
2072 ifr_mask = (struct ifreq *) mymalloc(IFREQ_SIZE(ifr));
2073 memcpy((char *) ifr_mask, (char *) ifr, IFREQ_SIZE(ifr));
2074 @@ -141,11 +239,70 @@
2079 + else if ((ifr->ifr_addr.sa_family == AF_INET6) &&
2080 + (ifr->ifr_addr.sa_family == af)) { /* IPv6 interface */
2081 + addr6 = *((struct sockaddr_in6 *) & ifr->ifr_addr);
2083 + /* decode scoped address notation */
2084 + if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
2085 + IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
2086 + addr6.sin6_scope_id == 0) {
2087 + addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
2088 + (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
2089 + addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
2092 + if (!(IN6_IS_ADDR_UNSPECIFIED(&addr6.sin6_addr))) {
2093 + inet_addr_list_append(addr_list, (struct sockaddr *)&addr6);
2095 +#error "mask_list for IPv6 without libinet6 not done yet (error to avoid open-relay)"
2096 + /* TODO: how to get netmask here? */
2101 ifr = NEXT_INTERFACE(ifr);
2107 + if (af != AF_INET6) {
2109 + goto other_socket_type;
2111 +#if defined (LINUX) || defined (LINUX2)
2112 + if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
2113 + while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
2114 + addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4],
2115 + addr6p[5], addr6p[6], addr6p[7],
2116 + &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
2117 + sprintf(addr6res, "%s:%s:%s:%s:%s:%s:%s:%s",
2118 + addr6p[0], addr6p[1], addr6p[2], addr6p[3],
2119 + addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
2120 + addr6res[sizeof(addr6res) - 1] = 0;
2121 + memset(&hints, 0, sizeof(hints));
2122 + hints.ai_flags = AI_NUMERICHOST;
2123 + hints.ai_family = AF_UNSPEC;
2124 + hints.ai_socktype = SOCK_DGRAM;
2125 + gaierror = getaddrinfo(addr6res, NULL, &hints, &res0);
2127 + for (res = res0; res; res = res->ai_next) {
2128 + inet_addr_list_append(addr_list, res->ai_addr);
2130 +#error "mask_list for IPv6 without libinet6 not done yet (error to avoid open-relay)"
2131 + /* TODO: calculate netmask basing on plen */
2134 + freeaddrinfo(res0);
2140 return (addr_list->used - initial_count);
2146 INET_ADDR_LIST addr_list;
2147 INET_ADDR_LIST mask_list;
2149 + char abuf[NI_MAXHOST], mbuf[NI_MAXHOST];
2150 + struct sockaddr *sa;
2152 msg_vstream_init(argv[0], VSTREAM_ERR);
2154 @@ -172,8 +331,17 @@
2155 msg_warn("found only one active network interface");
2157 for (i = 0; i < addr_list.used; i++) {
2158 - vstream_printf("%s/", inet_ntoa(addr_list.addrs[i]));
2159 - vstream_printf("%s\n", inet_ntoa(mask_list.addrs[i]));
2160 + sa = (struct sockaddr *)&addr_list.addrs[i];
2161 + if (getnameinfo(sa, SA_LEN(sa), abuf, sizeof(abuf), NULL, 0,
2162 + NI_NUMERICHOST)) {
2163 + strncpy(abuf, "???", sizeof(abuf));
2165 + sa = (struct sockaddr *)&mask_list.addrs[i];
2166 + if (getnameinfo(sa, SA_LEN(sa), mbuf, sizeof(mbuf), NULL, 0,
2167 + NI_NUMERICHOST)) {
2168 + strncpy(mbuf, "???", sizeof(mbuf));
2170 + vstream_printf("%s/%s\n", abuf, mbuf);
2172 vstream_fflush(VSTREAM_OUT);
2173 inet_addr_list_free(&addr_list);
2174 --- postfix-2.0.16.orig/src/util/inet_connect.c 2003-09-13 03:04:12.000000000 +0200
2175 +++ postfix-2.0.16/src/util/inet_connect.c 2003-11-08 20:22:55.000000000 +0100
2184 /* Utility library. */
2191 + struct addrinfo hints, *res, *res0;
2194 struct sockaddr_in sin;
2202 buf = inet_parse(addr, &host, &port);
2206 + memset(&hints, 0, sizeof(hints));
2207 + hints.ai_family = PF_UNSPEC;
2208 + hints.ai_socktype = SOCK_STREAM;
2209 + hints.ai_flags = AI_NUMERICHOST; /* find_inet_addr is numeric only */
2210 + if (getaddrinfo(host, port, &hints, &res0))
2211 + msg_fatal("host not found: %s", host);
2215 memset((char *) &sin, 0, sizeof(sin));
2216 sin.sin_family = AF_INET;
2217 sin.sin_addr.s_addr = find_inet_addr(host);
2218 sin.sin_port = find_inet_port(port, "tcp");
2224 + for (res = res0; res; res = res->ai_next) {
2225 + if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2228 + sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
2231 + if (timeout > 0) {
2232 + non_blocking(sock, NON_BLOCKING);
2233 + if (timed_connect(sock, res->ai_addr, res->ai_addrlen, timeout) < 0) {
2238 + if (block_mode != NON_BLOCKING)
2239 + non_blocking(sock, block_mode);
2242 + non_blocking(sock, block_mode);
2243 + if (connect(sock, res->ai_addr, res->ai_addrlen) < 0
2244 + && errno != EINPROGRESS) {
2252 + freeaddrinfo(res0);
2256 * Create a client socket.
2264 --- postfix-2.0.16.orig/src/util/inet_listen.c 2003-09-13 01:50:50.000000000 +0200
2265 +++ postfix-2.0.16/src/util/inet_listen.c 2003-11-08 20:22:55.000000000 +0100
2268 /* #include <listen.h>
2270 -/* int inet_listen(addr, backlog, block_mode)
2271 +/* int inet_listen(addr, backlog, block_mode, addinuse_fatal)
2272 /* const char *addr;
2276 #include <sys_defs.h>
2277 #include <sys/socket.h>
2278 #include <netinet/in.h>
2280 +#if (! __GLIBC__ >= 2 && __GLIBC_MINOR__ >=1 )
2281 +#include <netinet6/in6.h>
2284 #include <arpa/inet.h>
2286 #ifndef MAXHOSTNAMELEN
2287 #include <sys/param.h>
2293 @@ -77,35 +83,116 @@
2295 /* inet_listen - create inet-domain listener */
2297 -int inet_listen(const char *addr, int backlog, int block_mode)
2298 +int inet_listen(const char *addr, int backlog, int block_mode, int addrinuse_fatal)
2301 + struct addrinfo *res, *res0, hints;
2308 + struct sockaddr *ai_addr;
2309 + SOCKADDR_SIZE ai_addrlen;
2310 + struct ai *ai_next;
2311 + } *res, *res0, resbody;
2312 struct sockaddr_in sin;
2316 + int addrinuse = 0;
2321 + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
2323 + char hbuf[sizeof("255.255.255.255") + 1];
2324 + char pbuf[sizeof("255.255.255.255") + 1];
2326 + char *cause = "unknown";
2329 * Translate address information to internal form.
2331 buf = inet_parse(addr, &host, &port);
2332 - memset((char *) &sin, 0, sizeof(sin));
2334 + memset(&hints, 0, sizeof(hints));
2335 + hints.ai_flags = AI_PASSIVE;
2336 + hints.ai_family = AF_UNSPEC;
2337 + hints.ai_socktype = SOCK_STREAM;
2338 + error = getaddrinfo(*host ? host : NULL, *port ? port : "0", &hints, &res0);
2340 + msg_fatal("getaddrinfo: %s", gai_strerror(error));
2344 + memset(&sin, 0, sizeof(sin));
2345 sin.sin_family = AF_INET;
2347 + sin.sin_len = sizeof(sin);
2349 sin.sin_port = find_inet_port(port, "tcp");
2350 sin.sin_addr.s_addr = (*host ? find_inet_addr(host) : INADDR_ANY);
2354 - * Create a listener socket.
2356 - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
2357 - msg_fatal("socket: %m");
2358 - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0)
2359 - msg_fatal("setsockopt: %m");
2360 - if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
2361 - msg_fatal("bind %s port %d: %m", sin.sin_addr.s_addr == INADDR_ANY ?
2362 - "INADDR_ANY" : inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
2363 + memset(&resbody, 0, sizeof(resbody));
2364 + resbody.ai_socktype = SOCK_STREAM;
2365 + resbody.ai_family = AF_INET;
2366 + resbody.ai_addr = (struct sockaddr *)&sin;
2367 + resbody.ai_addrlen = sizeof(sin);
2373 + for (res = res0; res; res = res->ai_next) {
2374 + if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2378 + * Create a listener socket.
2380 + if ((sock = socket(res->ai_family, res->ai_socktype, 0)) < 0) {
2385 + if (res->ai_family == AF_INET6 &&
2386 + setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &t, sizeof(t)) < 0) {
2387 + /* if kernel/libc don't support this simple ignore it
2388 + cause = "setsockopt(IPV6_V6ONLY)";
2396 + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0) {
2397 + cause = "setsockopt(SO_REUSEADDR)";
2403 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
2405 + if (errno == EADDRINUSE)
2413 + if (sock < 0 && (addrinuse_fatal || !addrinuse))
2414 + msg_fatal("%s: %m", cause);
2416 + freeaddrinfo(res0);
2420 non_blocking(sock, block_mode);
2421 if (listen(sock, backlog) < 0)
2422 msg_fatal("listen: %m");
2423 --- postfix-2.0.16.orig/src/util/listen.h 1999-03-22 02:57:11.000000000 +0100
2424 +++ postfix-2.0.16/src/util/listen.h 2003-11-08 20:22:55.000000000 +0100
2426 * Listener external interface.
2428 extern int unix_listen(const char *, int, int);
2429 -extern int inet_listen(const char *, int, int);
2430 +extern int inet_listen(const char *, int, int, int);
2431 extern int fifo_listen(const char *, int, int);
2432 extern int stream_listen(const char *, int, int);
2434 --- postfix-2.0.16.orig/src/util/Makefile.in 2003-11-08 20:17:08.000000000 +0100
2435 +++ postfix-2.0.16/src/util/Makefile.in 2003-11-08 20:22:55.000000000 +0100
2437 dict_tcp.c dict_unix.c dir_forest.c doze.c duplex_pipe.c \
2438 environ.c events.c exec_command.c fifo_listen.c fifo_trigger.c \
2439 file_limit.c find_inet.c fsspace.c fullname.c get_domainname.c \
2440 - get_hostname.c hex_quote.c htable.c inet_addr_host.c \
2441 + get_hostname.c get_port.c hex_quote.c htable.c inet_addr_host.c \
2442 inet_addr_list.c inet_addr_local.c inet_connect.c inet_listen.c \
2443 inet_trigger.c inet_util.c intv.c line_wrap.c lowercase.c \
2444 lstat_as.c mac_expand.c mac_parse.c make_dirs.c match_list.c \
2446 dict_tcp.o dict_unix.o dir_forest.o doze.o duplex_pipe.o \
2447 environ.o events.o exec_command.o fifo_listen.o fifo_trigger.o \
2448 file_limit.o find_inet.o fsspace.o fullname.o get_domainname.o \
2449 - get_hostname.o hex_quote.o htable.o inet_addr_host.o \
2450 + get_hostname.o get_port.o hex_quote.o htable.o inet_addr_host.o \
2451 inet_addr_list.o inet_addr_local.o inet_connect.o inet_listen.o \
2452 inet_trigger.o inet_util.o intv.o line_wrap.o lowercase.o \
2453 lstat_as.o mac_expand.o mac_parse.o make_dirs.o match_list.o \
2455 dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
2456 dict_nisplus.h dict_pcre.h dict_pgsql.h dict_regexp.h dict_static.h dict_tcp.h \
2457 dict_unix.h dir_forest.h events.h exec_command.h find_inet.h \
2458 - fsspace.h fullname.h get_domainname.h get_hostname.h hex_quote.h \
2459 + fsspace.h fullname.h get_domainname.h get_hostname.h get_port.h hex_quote.h \
2460 htable.h inet_addr_host.h inet_addr_list.h inet_addr_local.h \
2461 inet_util.h intv.h iostuff.h line_wrap.h listen.h lstat_as.h \
2462 mac_expand.h mac_parse.h make_dirs.h match_list.h match_ops.h \
2464 get_domainname.o: mymalloc.h
2465 get_domainname.o: get_hostname.h
2466 get_domainname.o: get_domainname.h
2467 +get_port.o: sys_defs.h
2468 get_hostname.o: get_hostname.c
2469 get_hostname.o: sys_defs.h
2470 get_hostname.o: mymalloc.h
2472 match_list.o: stringops.h
2473 match_list.o: argv.h
2474 match_list.o: dict.h
2475 +match_list.o: inet_util.h
2476 match_list.o: match_ops.h
2477 match_list.o: match_list.h
2478 match_ops.o: match_ops.c
2479 --- postfix-2.0.16.orig/src/util/match_list.c 2001-11-20 21:07:15.000000000 +0100
2480 +++ postfix-2.0.16/src/util/match_list.c 2003-11-08 20:22:55.000000000 +0100
2482 list = match_list_parse(list, vstring_str(buf));
2483 if (vstream_fclose(fp))
2484 msg_fatal("%s: read file %s: %m", myname, pattern);
2485 - } else if (strchr(pattern, ':') != 0) { /* type:table */
2486 + } else if ((strchr(pattern, ']') == 0) && (strchr(pattern, ':') != 0)) { /* type:table */
2487 for (cp = pattern; *cp == '!'; cp++)
2489 if (dict_handle(pattern) == 0)
2490 --- postfix-2.0.16.orig/src/util/match_ops.c 2003-04-14 16:44:19.000000000 +0200
2491 +++ postfix-2.0.16/src/util/match_ops.c 2003-11-08 20:22:55.000000000 +0100
2493 #include <match_ops.h>
2494 #include <stringops.h>
2500 + * This program is free software; you can redistribute it and/or
2501 + * modify it under the terms of the GNU General Public License
2502 + * as published by the Free Software Foundation; either version
2503 + * 2 of the License, or (at your option) any later version.
2505 + * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
2508 + * Artur Frysiak <wiget@pld.org.pl>
2509 + * Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
2513 +#include <stdlib.h>
2514 +#include <unistd.h>
2515 +#include <syslog.h>
2517 +#include <sys/socket.h>
2518 +#include <netinet/in.h>
2519 +#include <string.h>
2521 +#include <arpa/inet.h>
2522 +#include <resolv.h>
2525 +#define AF_DECnet 12
2529 +#define PF_PACKET 17
2534 + unsigned char family;
2535 + unsigned char bytelen;
2536 + signed short bitlen;
2537 + unsigned int data[4];
2541 +int masked_match(char *, char *, char *);
2542 +int get_integer(int *, char *, int);
2543 +int get_addr_1(inet_prefix *, char *, int);
2544 +int get_prefix_1(inet_prefix *, char *, int);
2545 +int get_addr(inet_prefix *, char *, int);
2546 +int get_prefix(inet_prefix *, char *, int);
2547 +unsigned int get_addr32(char *);
2548 +int matches(char *, char *);
2549 +int inet_addr_match(inet_prefix *, inet_prefix *, int);
2550 +int mask_match(char *, char *, char *);
2552 +int get_integer(int *val, char *arg, int base)
2557 + if (!arg || !*arg)
2559 + res = strtol(arg, &ptr, base);
2560 + if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN)
2566 +int get_addr_1(inet_prefix *addr, char *name, int family)
2569 + unsigned char *ap = (unsigned char*)addr->data;
2572 + memset(addr, 0, sizeof(*addr));
2574 + if (strcmp(name, "default") == 0 || strcmp(name, "any") == 0) {
2575 + if (family == AF_DECnet)
2577 + addr->family = family;
2578 + addr->bytelen = (family == AF_INET6 ? 16 : 4);
2579 + addr->bitlen = -1;
2583 + if (strchr(name, ':')) {
2584 + addr->family = AF_INET6;
2585 + if (family != AF_UNSPEC && family != AF_INET6)
2587 + if (inet_pton(AF_INET6, name, addr->data) <= 0)
2589 + addr->bytelen = 16;
2590 + addr->bitlen = -1;
2593 + addr->family = AF_INET;
2594 + if (family != AF_UNSPEC && family != AF_INET)
2596 + addr->bytelen = 4;
2597 + addr->bitlen = -1;
2598 + for (cp = name, i = 0; *cp; cp++) {
2599 + if (*cp <= '9' && *cp >= '0') {
2600 + ap[i] = 10*ap[i] + (*cp-'0');
2603 + if (*cp == '.' && ++i <= 3)
2610 +int get_prefix_1(inet_prefix *dst, char *arg, int family)
2616 + memset(dst, 0, sizeof(*dst));
2618 + if (strcmp(arg, "default") == 0 || strcmp(arg, "any") == 0) {
2619 + if (family == AF_DECnet)
2621 + dst->family = family;
2627 + slash = strchr(arg, '/');
2630 + err = get_addr_1(dst, arg, family);
2632 + switch(dst->family) {
2634 + dst->bitlen = 128;
2644 + if (get_integer(&plen, slash+1, 0) || plen > dst->bitlen) {
2648 + dst->bitlen = plen;
2657 +int get_addr(inet_prefix *dst, char *arg, int family)
2660 + if (family == AF_PACKET)
2663 + if (get_addr_1(dst, arg, family))
2668 +int get_prefix(inet_prefix *dst, char *arg, int family)
2671 + if (family == AF_PACKET)
2674 + if (get_prefix_1(dst, arg, family))
2679 +unsigned int get_addr32(char *name)
2682 + if (get_addr_1(&addr, name, AF_INET))
2684 + return addr.data[0];
2687 +int matches(char *cmd, char *pattern)
2689 + int len = strlen(cmd);
2690 + if (len > strlen(pattern))
2692 + return memcmp(pattern, cmd, len);
2695 +int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits)
2697 + unsigned int *a1 = a->data;
2698 + unsigned int *a2 = b->data;
2699 + int words = bits >> 0x05;
2704 + if (memcmp(a1, a2, words << 2))
2708 + unsigned int w1, w2;
2709 + unsigned int mask;
2714 + mask = htonl((0xffffffff) << (0x20 - bits));
2716 + if ((w1 ^ w2) & mask)
2723 +/* zero if matches */
2724 +int mask_match(char *network, char *cprefix, char *address)
2726 + inet_prefix *inetwork;
2727 + inet_prefix *iaddress;
2730 + if (!(network && address && cprefix))
2732 + prefix = strtol(cprefix, (char **)NULL, 10);
2733 + if ((prefix < 0) || (prefix > 128))
2735 + if ((strlen(network) == 0) || (strlen(address) == 0))
2738 + inetwork = malloc(sizeof(inet_prefix));
2739 + iaddress = malloc(sizeof(inet_prefix));
2741 + if ((get_addr(iaddress, address, AF_UNSPEC) >= 0)
2742 + && (get_addr(inetwork, network, AF_UNSPEC) >= 0))
2743 + ret = inet_addr_match(inetwork, iaddress, prefix);
2749 + /* 1 if matches */
2750 + /* return (!ret); */
2751 + /* 0 if matches */
2756 + * masked_match() - universal for IPv4 and IPv6 - 1 if matches
2758 +int masked_match(net_tok, mask_tok, string)
2764 + struct in6_addr in6[2];
2765 + char v4addr[2][INET_ADDRSTRLEN];
2770 + /* Check for NULL */
2771 + if (!(net_tok && mask_tok && string))
2772 + return 0; /* doesn't match!!! */
2774 + /* If IPv6 mapped convert to native-IPv4 */
2776 + if (inet_pton(AF_INET6, net_tok, &in6[0]) == 1 &&
2777 + inet_pton(AF_INET6, string, &in6[1]) == 1 &&
2778 + IN6_IS_ADDR_V4MAPPED(&in6[0]) && IN6_IS_ADDR_V4MAPPED(&in6[1])) {
2779 + plen = atoi(mask_tok);
2780 + if (32 < plen && plen < 129) {
2781 + sprintf(newmask, "%d", plen - 96);
2782 + mask_tok = newmask;
2785 + (void)inet_ntop(AF_INET, &in6[0].s6_addr[12], v4addr[0],
2786 + sizeof(v4addr[0]));
2787 + net_tok = v4addr[0];
2788 + (void)inet_ntop(AF_INET, &in6[1].s6_addr[12], v4addr[1],
2789 + sizeof(v4addr[1]));
2790 + string = v4addr[1];
2793 + return (!mask_match(net_tok, mask_tok, string));
2798 /* match_string - match a string literal */
2800 int match_string(int unused_flags, const char *string, const char *pattern)
2806 /* match_parse_mask - parse net/mask pattern */
2808 static int match_parse_mask(const char *pattern, unsigned long *net_bits,
2809 @@ -198,28 +501,55 @@
2814 /* match_hostaddr - match host by address */
2816 int match_hostaddr(int unused_flags, const char *addr, const char *pattern)
2818 char *myname = "match_hostaddr";
2820 + char *network, *mask, *escl, *escr, *patternx;
2821 + struct in6_addr in6;
2822 + char v4addr[INET_ADDRSTRLEN];
2825 unsigned long mask_bits;
2826 unsigned long net_bits;
2827 unsigned long addr_bits;
2828 struct in_addr net_addr;
2832 msg_info("%s: %s ~? %s", myname, addr, pattern);
2835 + if (addr[strspn(addr, "01234567890./:abcdef")] != 0)
2837 if (addr[strspn(addr, "01234567890./:")] != 0)
2842 + patternx = mystrdup(pattern);
2843 + escl = strchr(patternx,'[');
2844 + escr = strrchr(patternx,']');
2845 + if (escl && escr) {
2847 + sprintf(patternx, "%s%s", escl + 1, escr + 1);
2848 + pattern = patternx;
2853 * Try dictionary lookup. This can be case insensitive. XXX Probably
2854 * should also try again after stripping least significant octets.
2856 - if (strchr(pattern, ':') != 0) {
2858 + if (!(escl && escr) && strchr(pattern, ':') != 0)
2860 + if (strchr(pattern, ':') != 0)
2863 if (dict_lookup(pattern, addr) != 0)
2865 if (dict_errno != 0)
2866 @@ -230,6 +560,12 @@
2868 * Try an exact match with the host address.
2871 + if (inet_pton(AF_INET6, addr, &in6) == 1 && IN6_IS_ADDR_V4MAPPED(&in6)) {
2872 + (void)inet_ntop(AF_INET, &in6.s6_addr[12], v4addr, sizeof(v4addr));
2876 if (strcasecmp(addr, pattern) == 0) {
2879 @@ -238,6 +574,20 @@
2880 * In a net/mask pattern, the mask is specified as the number of bits of
2884 + network = mystrdup(patternx);
2885 + mask = split_at(network, '/');
2887 + if (masked_match(network, mask, (char *)addr)) {
2897 if (match_parse_mask(pattern, &net_bits, &mask_shift)) {
2898 addr_bits = inet_addr(addr);
2899 if (addr_bits == INADDR_NONE)
2901 pattern, inet_ntoa(net_addr), mask_shift);
2907 --- postfix-2.0.16.orig/src/util/sys_defs.h 2003-11-08 20:17:08.000000000 +0100
2908 +++ postfix-2.0.16/src/util/sys_defs.h 2003-11-08 20:22:55.000000000 +0100
2910 #define DEF_MAILBOX_LOCK "flock, dotlock"
2913 +#if ((defined(__NetBSD_Version__) && __NetBSD_Version__ >= 105000000) || defined(USAGI_LIBINET6))
2914 +#define HAVE_GETIFADDRS
2920 --- postfix-2.0.16.orig/src/util/valid_hostname.c 2002-12-20 02:33:41.000000000 +0100
2921 +++ postfix-2.0.16/src/util/valid_hostname.c 2003-11-08 20:22:55.000000000 +0100
2927 +#include <netinet/in.h>
2928 +#include <sys/socket.h>
2929 +#include <arpa/inet.h>
2933 /* Utility library. */
2936 @@ -109,7 +116,23 @@
2937 msg_warn("%s: misplaced hyphen: %.100s", myname, name);
2943 + else if (ch == ':') {
2944 + struct addrinfo hints, *res;
2946 + memset(&hints, 0, sizeof(hints));
2947 + hints.ai_family = AF_INET6;
2948 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
2949 + hints.ai_flags = AI_NUMERICHOST;
2950 + if (getaddrinfo(name, "0", &hints, &res) == 0) {
2951 + freeaddrinfo(res);
2959 msg_warn("%s: invalid character %d(decimal): %.100s",
2966 + struct addrinfo hints, *res;
2969 #define BYTES_NEEDED 4
2971 @@ -166,6 +192,17 @@
2976 + memset(&hints, 0, sizeof(hints));
2977 + hints.ai_family = AF_INET6;
2978 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
2979 + hints.ai_flags = AI_NUMERICHOST;
2980 + if (getaddrinfo(addr, "0", &hints, &res) == 0) {
2981 + freeaddrinfo(res);
2987 * Scary code to avoid sscanf() overflow nasties.