1 diff -Nur postfix-1.1.2.orig/makedefs postfix-1.1.2/makedefs
2 --- postfix-1.1.2.orig/makedefs Fri Jan 25 15:17:18 2002
3 +++ postfix-1.1.2/makedefs Mon Jan 28 12:40:04 2002
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
13 + if [ -f /usr/local/v6/lib/libinet6.a ]; then
20 +if [ -z "$INET6" -a -f /usr/include/netinet/ip6.h -a -f /usr/include/linux/icmpv6.h ]; then
25 dcosx*) SYSTEM=$VERSION;;
28 : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk}
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"
38 + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
41 + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family"
42 + if test -f /usr/include/libinet6/netinet/ip6.h -a \
43 + -f /usr/lib/libinet6.a; then
44 + CCARGS="$CCARGS -I/usr/include/libinet6 -DUSAGI_LIBINET6"
45 + SYSLIBS="$SYSLIBS -linet6"
50 export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
53 diff -Nur postfix-1.1.2.orig/src/global/Makefile.in postfix-1.1.2/src/global/Makefile.in
54 --- postfix-1.1.2.orig/src/global/Makefile.in Mon Jan 28 12:38:34 2002
55 +++ postfix-1.1.2/src/global/Makefile.in Mon Jan 28 12:40:04 2002
56 diff -Nur postfix-1.1.2.orig/src/global/mynetworks.c postfix-1.1.2/src/global/mynetworks.c
58 timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
59 tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
60 flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
61 - verp_sender.c match_parent_style.c mime_state.c header_token.c \
62 + verp_sender.c match_parent_style.c mime_state.c header_token.c wildcard_inet_addr.c\
63 strip_addr.c virtual8_maps.c hold_message.c dict_proxy.c mail_dict.c \
65 OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
67 timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
68 tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
69 flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
70 - verp_sender.o match_parent_style.o mime_state.o header_token.o \
71 + verp_sender.o match_parent_style.o mime_state.o header_token.o wildcard_inet_addr.o\
72 strip_addr.o virtual8_maps.o hold_message.o dict_proxy.o mail_dict.o \
74 HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
76 rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
77 sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
78 mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \
79 - match_parent_style.h quote_flags.h mime_state.h header_token.h \
80 + match_parent_style.h quote_flags.h mime_state.h header_token.h wildcard_inet_addr.h\
81 lex_822.h strip_addr.h virtual8_maps.h hold_message.h dict_proxy.h \
83 TESTSRC = rec2stream.c stream2rec.c recdump.c
84 --- postfix-1.1.2.orig/src/global/mynetworks.c Sun Feb 25 02:46:07 2001
85 +++ postfix-1.1.2/src/global/mynetworks.c Mon Jan 28 12:40:04 2002
88 #include <inet_addr_list.h>
89 #include <name_mask.h>
91 +#include <sys/socket.h>
92 +#include <netinet/in.h>
99 const char *mynetworks(void)
101 static VSTRING *result;
103 + char hbuf[NI_MAXHOST];
107 char *myname = "mynetworks";
113 + struct sockaddr *sa;
116 mask_style = name_mask("mynetworks mask style", mask_styles,
117 var_mynetworks_style);
119 my_mask_list = own_inet_mask_list();
121 for (i = 0; i < my_addr_list->used; i++) {
123 + sa = (struct sockaddr *)&my_addr_list->addrs[i];
124 + if (sa->sa_family != AF_INET) {
125 + if (sa->sa_family == AF_INET6)
126 + vstring_sprintf_append(result, "XAATODOmynetworks ");
129 + addr = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
130 + mask = ntohl(((struct sockaddr_in *)&my_mask_list->addrs[i])->sin_addr.s_addr);
132 addr = ntohl(my_addr_list->addrs[i].s_addr);
133 mask = ntohl(my_mask_list->addrs[i].s_addr);
136 switch (mask_style) {
139 mask = IN_CLASSD_NET;
140 shift = IN_CLASSD_NSHIFT;
143 + if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
145 + strncpy(hbuf, "???", sizeof(hbuf));
146 + msg_fatal("%s: bad address class: %s", myname, hbuf);
148 msg_fatal("%s: bad address class: %s",
149 myname, inet_ntoa(my_addr_list->addrs[i]));
154 diff -Nur postfix-1.1.2.orig/src/global/own_inet_addr.c postfix-1.1.2/src/global/own_inet_addr.c
155 --- postfix-1.1.2.orig/src/global/own_inet_addr.c Tue Jul 31 20:38:29 2001
156 +++ postfix-1.1.2/src/global/own_inet_addr.c Mon Jan 28 12:40:04 2002
158 #include <netinet/in.h>
159 #include <arpa/inet.h>
162 +#include <sys/socket.h>
166 #ifdef STRCASECMP_IN_STRINGS_H
168 @@ -101,10 +105,11 @@
171 bufp = hosts = mystrdup(var_inet_interfaces);
172 - while ((host = mystrtok(&bufp, sep)) != 0)
173 + while ((host = mystrtok(&bufp, sep)) != 0) {
174 if (inet_addr_host(addr_list, host) == 0)
175 msg_fatal("config variable %s: host not found: %s",
176 VAR_INET_INTERFACES, host);
181 @@ -121,15 +126,39 @@
182 msg_fatal("could not find any active network interfaces");
183 for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) {
184 for (nlocal = 0; /* see below */ ; nlocal++) {
185 - if (nlocal >= local_addrs.used)
186 + if (nlocal >= local_addrs.used) {
188 + char hbuf[NI_MAXHOST];
189 + if (getnameinfo((struct sockaddr *)&addr_list->addrs[nvirtual],
190 + SS_LEN(addr_list->addrs[nvirtual]), hbuf,
191 + sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
192 + strncpy(hbuf, "???", sizeof(hbuf));
193 + msg_fatal("parameter %s: no local interface found for %s",
194 + VAR_INET_INTERFACES, hbuf);
196 msg_fatal("parameter %s: no local interface found for %s",
198 inet_ntoa(addr_list->addrs[nvirtual]));
202 + if (addr_list->addrs[nvirtual].ss_family ==
203 + local_addrs.addrs[nlocal].ss_family &&
204 + SS_LEN(addr_list->addrs[nvirtual]) ==
205 + SS_LEN(local_addrs.addrs[nlocal]) &&
206 + memcmp(&addr_list->addrs[nvirtual],
207 + &local_addrs.addrs[nlocal],
208 + SS_LEN(local_addrs.addrs[nlocal])) == 0) {
209 + inet_addr_list_append(mask_list, (struct sockaddr *)&local_masks.addrs[nlocal]);
213 if (addr_list->addrs[nvirtual].s_addr
214 == local_addrs.addrs[nlocal].s_addr) {
215 inet_addr_list_append(mask_list, &local_masks.addrs[nlocal]);
221 inet_addr_list_free(&local_addrs);
224 /* own_inet_addr - is this my own internet address */
227 +int own_inet_addr(struct sockaddr * addr)
232 + struct sockaddr *sa;
234 + if (addr_list.used == 0)
235 + own_inet_addr_init(&addr_list, &mask_list);
237 + for (i = 0; i < addr_list.used; i++) {
238 + sa = (struct sockaddr *)&addr_list.addrs[i];
239 + if (addr->sa_family != sa->sa_family)
241 + switch (addr->sa_family) {
243 + p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
244 + q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
245 + l = sizeof(struct in_addr);
249 + p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
250 + q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
251 + l = sizeof(struct in6_addr);
256 + if (memcmp(p, q, l) == 0)
262 int own_inet_addr(struct in_addr * addr)
266 for (i = 0; i < addr_list.used; i++)
267 if (addr->s_addr == addr_list.addrs[i].s_addr)
273 /* own_inet_addr_list - return list of addresses */
277 /* proxy_inet_addr - is this my proxy internet address */
280 +int proxy_inet_addr(struct sockaddr * addr)
285 + struct sockaddr *sa;
287 + if (*var_proxy_interfaces == 0)
290 + if (proxy_list.used == 0)
291 + proxy_inet_addr_init(&proxy_list);
293 + for (i = 0; i < proxy_list.used; i++) {
294 + sa = (struct sockaddr *)&proxy_list.addrs[i];
295 + if (addr->sa_family != sa->sa_family)
297 + switch (addr->sa_family) {
299 + p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
300 + q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
301 + l = sizeof(struct in_addr);
305 + p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
306 + q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
307 + l = sizeof(struct in6_addr);
312 + if (memcmp(p, q, l) == 0)
318 int proxy_inet_addr(struct in_addr * addr)
327 /* proxy_inet_addr_list - return list of addresses */
329 diff -Nur postfix-1.1.2.orig/src/global/own_inet_addr.h postfix-1.1.2/src/global/own_inet_addr.h
330 --- postfix-1.1.2.orig/src/global/own_inet_addr.h Sat Feb 24 02:25:32 2001
331 +++ postfix-1.1.2/src/global/own_inet_addr.h Mon Jan 28 12:40:04 2002
335 #include <netinet/in.h>
337 +#include <sys/socket.h>
341 * External interface.
344 +extern int own_inet_addr(struct sockaddr *);
346 extern int own_inet_addr(struct in_addr *);
348 extern struct INET_ADDR_LIST *own_inet_addr_list(void);
349 extern struct INET_ADDR_LIST *own_inet_mask_list(void);
351 +extern int proxy_inet_addr(struct sockaddr *);
353 extern int proxy_inet_addr(struct in_addr *);
355 extern struct INET_ADDR_LIST *proxy_inet_addr_list(void);
358 diff -Nur postfix-1.1.2.orig/src/global/peer_name.c postfix-1.1.2/src/global/peer_name.c
359 --- postfix-1.1.2.orig/src/global/peer_name.c Sun Jan 28 16:23:02 2001
360 +++ postfix-1.1.2/src/global/peer_name.c Mon Jan 28 12:40:04 2002
362 PEER_NAME *peer_name(int sock)
364 static PEER_NAME peer;
365 - struct sockaddr_in sin;
366 - SOCKADDR_SIZE len = sizeof(sin);
373 + struct sockaddr peer_un;
374 + struct sockaddr_in peer_un4;
376 + struct sockaddr_in6 peer_un6;
379 +#define sun p_un.peer_un
380 +#define sin p_un.peer_un4
382 +#define sin6 p_un.peer_un6
383 + static char hbuf[NI_MAXHOST];
384 + static char abuf[NI_MAXHOST];
388 + SOCKADDR_SIZE len = sizeof(p_un);
390 - if (getpeername(sock, (struct sockaddr *) & sin, &len) == 0) {
391 - switch (sin.sin_family) {
392 + if (getpeername(sock, (struct sockaddr *)&p_un, &len) == 0) {
393 + switch (p_un.peer_un.sa_family) {
396 peer.type = PEER_TYPE_INET;
397 hp = gethostbyaddr((char *) &(sin.sin_addr),
399 hp->h_name : "unknown");
400 peer.addr = inet_ntoa(sin.sin_addr);
404 + peer.type = PEER_TYPE_INET;
405 + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
406 + peer.name = "unknown";
412 + peer.type = PEER_TYPE_INET6;
413 + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
414 + peer.name = "unknown";
422 peer.type = PEER_TYPE_LOCAL;
423 diff -Nur postfix-1.1.2.orig/src/global/peer_name.h postfix-1.1.2/src/global/peer_name.h
424 --- postfix-1.1.2.orig/src/global/peer_name.h Fri Dec 11 19:55:32 1998
425 +++ postfix-1.1.2/src/global/peer_name.h Mon Jan 28 12:40:04 2002
427 #define PEER_TYPE_UNKNOWN 0
428 #define PEER_TYPE_INET 1
429 #define PEER_TYPE_LOCAL 2
431 +#define PEER_TYPE_INET6 3
434 extern PEER_NAME *peer_name(int);
436 diff -Nur postfix-1.1.2.orig/src/global/resolve_local.c postfix-1.1.2/src/global/resolve_local.c
437 --- postfix-1.1.2.orig/src/global/resolve_local.c Fri Jan 18 15:06:51 2002
438 +++ postfix-1.1.2/src/global/resolve_local.c Mon Jan 28 12:40:04 2002
440 #include <netinet/in.h>
441 #include <arpa/inet.h>
446 #define INADDR_NONE 0xffffffff
449 char *saved_addr = mystrdup(addr);
452 + struct addrinfo hints, *res, *res0;
455 struct in_addr ipaddr;
459 #define RETURN(x) { myfree(saved_addr); return(x); }
461 if (*dest == '[' && dest[len - 1] == ']') {
465 + memset(&hints, 0, sizeof(hints));
466 + hints.ai_family = PF_UNSPEC;
467 + hints.ai_socktype = SOCK_DGRAM;
468 + error = getaddrinfo(dest, NULL, &hints, &res0);
470 + for (res = res0; res; res = res->ai_next) {
471 + if (own_inet_addr(res->ai_addr)) {
472 + freeaddrinfo(res0);
476 + freeaddrinfo(res0);
479 if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE
480 && (own_inet_addr(&ipaddr) || proxy_inet_addr(&ipaddr)))
486 diff -Nur postfix-1.1.2.orig/src/global/wildcard_inet_addr.c postfix-1.1.2/src/global/wildcard_inet_addr.c
487 --- postfix-1.1.2.orig/src/global/wildcard_inet_addr.c Thu Jan 1 01:00:00 1970
488 +++ postfix-1.1.2/src/global/wildcard_inet_addr.c Mon Jan 28 12:40:04 2002
490 +/* System library. */
492 +#include <sys_defs.h>
493 +#include <netinet/in.h>
494 +#include <arpa/inet.h>
497 +#include <sys/socket.h>
501 +#ifdef STRCASECMP_IN_STRINGS_H
502 +#include <strings.h>
505 +/* Utility library. */
508 +#include <mymalloc.h>
509 +#include <inet_addr_list.h>
510 +#include <inet_addr_local.h>
511 +#include <inet_addr_host.h>
512 +#include <stringops.h>
514 +/* Global library. */
516 +#include <mail_params.h>
517 +#include <wildcard_inet_addr.h>
519 +/* Application-specific. */
520 +static INET_ADDR_LIST addr_list;
522 +/* wildcard_inet_addr_init - initialize my own address list */
524 +static void wildcard_inet_addr_init(INET_ADDR_LIST *addr_list)
527 + struct addrinfo hints, *res, *res0;
528 + char hbuf[NI_MAXHOST];
530 +#ifdef NI_WITHSCOPEID
531 + const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
533 + const int niflags = NI_NUMERICHOST;
536 + inet_addr_list_init(addr_list);
538 + memset(&hints, 0, sizeof(hints));
539 + hints.ai_family = PF_UNSPEC;
540 + hints.ai_socktype = SOCK_STREAM;
541 + hints.ai_flags = AI_PASSIVE;
542 + error = getaddrinfo(NULL, "0", &hints, &res0);
544 + msg_fatal("could not get list of wildcard addresses");
545 + for (res = res0; res; res = res->ai_next) {
546 + if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
548 + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
549 + NULL, 0, niflags) != 0)
551 + if (inet_addr_host(addr_list, hbuf) == 0)
552 + continue; /* msg_fatal("config variable %s: host not found: %s",
553 + VAR_INET_INTERFACES, hbuf); */
555 + freeaddrinfo(res0);
557 + if (inet_addr_host(addr_list, "0.0.0.0") == 0)
558 + msg_fatal("config variable %s: host not found: %s",
559 + VAR_INET_INTERFACES, "0.0.0.0");
563 +/* wildcard_inet_addr_list - return list of addresses */
565 +INET_ADDR_LIST *wildcard_inet_addr_list(void)
567 + if (addr_list.used == 0)
568 + wildcard_inet_addr_init(&addr_list);
570 + return (&addr_list);
572 diff -Nur postfix-1.1.2.orig/src/global/wildcard_inet_addr.h postfix-1.1.2/src/global/wildcard_inet_addr.h
573 --- postfix-1.1.2.orig/src/global/wildcard_inet_addr.h Thu Jan 1 01:00:00 1970
574 +++ postfix-1.1.2/src/global/wildcard_inet_addr.h Mon Jan 28 12:40:04 2002
576 +#ifndef _WILDCARD_INET_ADDR_H_INCLUDED_
577 +#define _WILDCARD_INET_ADDR_H_INCLUDED_
581 +/* wildcard_inet_addr_list 3h
583 +/* grab the list of wildcard IP addresses.
585 +/* #include <own_inet_addr.h>
593 +#include <netinet/in.h>
595 +#include <sys/socket.h>
599 + * External interface.
601 +extern struct INET_ADDR_LIST *wildcard_inet_addr_list(void);
608 +/* Jun-ichiro itojun Hagino
612 diff -Nur postfix-1.1.2.orig/src/master/master_ent.c postfix-1.1.2/src/master/master_ent.c
613 --- postfix-1.1.2.orig/src/master/master_ent.c Sun Dec 23 20:08:58 2001
614 +++ postfix-1.1.2/src/master/master_ent.c Mon Jan 28 12:40:04 2002
616 inet_addr_host(MASTER_INET_ADDRLIST(serv), host);
617 serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
618 } else if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) {
620 + MASTER_INET_ADDRLIST(serv) = wildcard_inet_addr_list();
621 + serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
623 MASTER_INET_ADDRLIST(serv) = 0; /* wild-card */
624 serv->listen_fd_count = 1;
627 MASTER_INET_ADDRLIST(serv) = own_inet_addr_list(); /* virtual */
628 serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
629 diff -Nur postfix-1.1.2.orig/src/master/master_listen.c postfix-1.1.2/src/master/master_listen.c
630 --- postfix-1.1.2.orig/src/master/master_listen.c Tue May 1 00:47:57 2001
631 +++ postfix-1.1.2/src/master/master_listen.c Mon Jan 28 12:40:04 2002
641 /* master_listen_init - enable connection requests */
643 void master_listen_init(MASTER_SERV *serv)
645 char *myname = "master_listen_init";
650 + char hbuf[NI_MAXHOST];
651 + SOCKADDR_SIZE salen;
655 * Find out what transport we should use, then create one or more
656 @@ -111,18 +120,31 @@
658 inet_listen(MASTER_INET_PORT(serv),
659 serv->max_proc > var_proc_limit ?
660 - serv->max_proc : var_proc_limit, NON_BLOCKING);
661 + serv->max_proc : var_proc_limit, NON_BLOCKING, 1);
662 close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
663 } else { /* virtual or host:port */
664 - for (n = 0; n < serv->listen_fd_count; n++) {
665 + for (m = n = 0; n < serv->listen_fd_count; n++) {
667 + if (getnameinfo((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n],
668 + SA_LEN((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n]),
669 + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) {
670 + strncpy(hbuf, "?????", sizeof(hbuf));
672 + end_point = concatenate(hbuf, ":", MASTER_INET_PORT(serv), (char *) 0);
674 end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]),
675 ":", MASTER_INET_PORT(serv), (char *) 0);
679 = inet_listen(end_point, serv->max_proc > var_proc_limit ?
680 - serv->max_proc : var_proc_limit, NON_BLOCKING);
681 - close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC);
682 + serv->max_proc : var_proc_limit, NON_BLOCKING, 0);
684 + serv->listen_fd[m] = tmpfd;
685 + close_on_exec(serv->listen_fd[m++], CLOSE_ON_EXEC);
689 + serv->listen_fd_count=m;
693 diff -Nur postfix-1.1.2.orig/src/smtp/Makefile.in postfix-1.1.2/src/smtp/Makefile.in
694 --- postfix-1.1.2.orig/src/smtp/Makefile.in Mon Jan 28 12:38:34 2002
695 +++ postfix-1.1.2/src/smtp/Makefile.in Mon Jan 28 12:40:04 2002
697 smtp_connect.o: ../../include/mail_params.h
698 smtp_connect.o: ../../include/own_inet_addr.h
699 smtp_connect.o: ../../include/dns.h
700 +smtp_connect.o: ../../include/get_port.h
701 smtp_connect.o: smtp.h
702 smtp_connect.o: ../../include/argv.h
703 smtp_connect.o: ../../include/deliver_request.h
704 diff -Nur postfix-1.1.2.orig/src/smtp/smtp_addr.c postfix-1.1.2/src/smtp/smtp_addr.c
705 --- postfix-1.1.2.orig/src/smtp/smtp_addr.c Sun Jul 8 17:05:26 2001
706 +++ postfix-1.1.2/src/smtp/smtp_addr.c Mon Jan 28 12:40:04 2002
707 @@ -134,18 +134,68 @@
708 static void smtp_print_addr(char *what, DNS_RR *addr_list)
711 - struct in_addr in_addr;
713 + struct sockaddr_storage ss;
715 + struct sockaddr ss;
717 + struct sockaddr_in *sin;
719 + struct sockaddr_in6 *sin6;
720 + char hbuf[NI_MAXHOST];
722 + char hbuf[sizeof("255.255.255.255") + 1];
725 msg_info("begin %s address list", what);
726 for (addr = addr_list; addr; addr = addr->next) {
727 - if (addr->data_len > sizeof(addr)) {
728 - msg_warn("skipping address length %d", addr->data_len);
730 - memcpy((char *) &in_addr, addr->data, sizeof(in_addr));
731 - msg_info("pref %4d host %s/%s",
732 - addr->pref, addr->name,
733 - inet_ntoa(in_addr));
734 + if (addr->class != C_IN) {
735 + msg_warn("skipping unsupported address (class=%u)", addr->class);
738 + switch (addr->type) {
740 + if (addr->data_len != sizeof(sin->sin_addr)) {
741 + msg_warn("skipping invalid address (AAAA, len=%u)",
745 + sin = (struct sockaddr_in *)&ss;
746 + memset(sin, 0, sizeof(*sin));
747 + sin->sin_family = AF_INET;
749 + sin->sin_len = sizeof(*sin);
751 + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
755 + if (addr->data_len != sizeof(sin6->sin6_addr)) {
756 + msg_warn("skipping invalid address (AAAA, len=%u)",
760 + sin6 = (struct sockaddr_in6 *)&ss;
761 + memset(sin6, 0, sizeof(*sin6));
762 + sin6->sin6_family = AF_INET6;
764 + sin6->sin6_len = sizeof(*sin6);
766 + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
770 + msg_warn("skipping unsupported address (type=%u)", addr->type);
775 + (void)getnameinfo((struct sockaddr *)&ss, SS_LEN(ss),
776 + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
778 + (void)inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
780 + msg_info("pref %4d host %s/%s", addr->pref, addr->name, hbuf);
782 msg_info("end %s address list", what);
784 @@ -155,15 +205,23 @@
785 static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
787 char *myname = "smtp_addr_one";
789 struct in_addr inaddr;
795 + struct addrinfo hints, *res0, *res;
803 msg_info("%s: host %s", myname, host);
807 * Interpret a numerical name as an address.
810 smtp_errno = SMTP_FAIL;
814 + memset(&hints, 0, sizeof(hints));
815 + hints.ai_family = PF_UNSPEC;
816 + hints.ai_socktype = SOCK_STREAM;
817 + error = getaddrinfo(host, NULL, &hints, &res0);
821 + smtp_errno = SMTP_RETRY;
824 + vstring_sprintf(why, "[%s]: %s",host,gai_strerror(error));
825 + smtp_errno = SMTP_FAIL;
828 + return (addr_list);
830 + for (res = res0; res; res = res->ai_next) {
831 + memset((char *) &fixed, 0, sizeof(fixed));
832 + switch(res->ai_family) {
834 + /* XXX not scope friendly */
835 + fixed.type = T_AAAA;
836 + addr = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
837 + addrlen = sizeof(struct in6_addr);
841 + addr = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr;
842 + addrlen = sizeof(struct in_addr);
845 + msg_warn("%s: unknown address family %d for %s",
846 + myname, res->ai_family, host);
849 + addr_list = dns_rr_append(addr_list,
850 + dns_rr_create(host, &fixed, pref, addr, addrlen));
853 + freeaddrinfo(res0);
859 INET_ADDR_LIST *self;
863 + struct sockaddr *sa;
867 * Find the first address that lists any address that this mail system is
868 @@ -260,12 +363,36 @@
870 self = own_inet_addr_list();
871 for (addr = addr_list; addr; addr = addr->next) {
872 - for (i = 0; i < self->used; i++)
873 + for (i = 0; i < self->used; i++) {
875 + sa = (struct sockaddr *)&self->addrs[i];
876 + switch(addr->type) {
879 + if (sa->sa_family != AF_INET6)
881 + if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
882 + addr->data, sizeof(struct in6_addr)) == 0) {
887 + if (sa->sa_family != AF_INET)
889 + if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
890 + addr->data, sizeof(struct in_addr)) == 0) {
896 if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
898 msg_info("%s: found at pref %d", myname, addr->pref);
906 @@ -400,12 +400,36 @@
908 self = proxy_inet_addr_list();
909 for (addr = addr_list; addr; addr = addr->next) {
910 - for (i = 0; i < self->used; i++)
911 + for (i = 0; i < self->used; i++) {
913 + sa = (struct sockaddr *)&self->addrs[i];
914 + switch(addr->type) {
917 + if (sa->sa_family != AF_INET6)
919 + if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
920 + addr->data, sizeof(struct in6_addr)) == 0) {
925 + if (sa->sa_family != AF_INET)
927 + if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
928 + addr->data, sizeof(struct in_addr)) == 0) {
934 if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
936 msg_info("%s: found at pref %d", myname, addr->pref);
944 diff -Nur postfix-1.1.2.orig/src/smtp/smtp_connect.c postfix-1.1.2/src/smtp/smtp_connect.c
945 --- postfix-1.1.2.orig/src/smtp/smtp_connect.c Mon Jan 28 12:38:34 2002
946 +++ postfix-1.1.2/src/smtp/smtp_connect.c Mon Jan 28 12:40:04 2002
948 /* System library. */
950 #include <sys_defs.h>
952 #include <sys/socket.h>
953 #include <netinet/in.h>
954 #include <arpa/inet.h>
956 #include <inet_addr_list.h>
958 #include <timed_connect.h>
959 +#include <get_port.h>
960 #include <stringops.h>
961 #include <host_port.h>
963 @@ -134,19 +136,45 @@
966 char *myname = "smtp_connect_addr";
967 - struct sockaddr_in sin;
970 + struct sockaddr_storage ss;
972 + struct sockaddr ss;
974 + struct sockaddr *sa;
975 + struct sockaddr_in *sin;
977 + struct sockaddr_in6 *sin6;
979 + SOCKADDR_SIZE salen;
981 + char hbuf[NI_MAXHOST];
983 + char hbuf[sizeof("255.255.255.255") + 1];
986 INET_ADDR_LIST *addr_list;
991 - unsigned long inaddr;
993 + sa = (struct sockaddr *)&ss;
994 + sin = (struct sockaddr_in *)&ss;
996 + sin6 = (struct sockaddr_in6 *)&ss;
1002 - if (addr->data_len > sizeof(sin.sin_addr)) {
1004 + if (((addr->type==T_A) && (addr->data_len > sizeof(sin->sin_addr))) ||
1005 + ((addr->type==T_AAAA) && (addr->data_len > sizeof(sin6->sin6_addr))))
1007 + if (addr->data_len > sizeof(sin->sin_addr))
1010 msg_warn("%s: skip address with length %d", myname, addr->data_len);
1011 smtp_errno = SMTP_RETRY;
1013 @@ -155,17 +183,39 @@
1017 - memset((char *) &sin, 0, sizeof(sin));
1018 - sin.sin_family = AF_INET;
1020 - if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
1021 - msg_fatal("%s: socket: %m", myname);
1023 + switch (addr->type) {
1026 + memset(sin6, 0, sizeof(*sin6));
1027 + sin6->sin6_family = AF_INET6;
1028 + salen = sizeof(*sin6);
1031 + default: /* T_A: */
1032 + memset(sin, 0, sizeof(*sin));
1033 + sin->sin_family = AF_INET;
1034 + salen = sizeof(*sin);
1038 + sa->sa_len = salen;
1040 + if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
1041 + msg_warn("%s: socket: %m", myname);
1044 * Allow the sysadmin to specify the source address, for example, as "-o
1045 * smtp_bind_address=x.x.x.x" in the master.cf file.
1047 if (*var_smtp_bind_addr) {
1049 + struct sockaddr_in sin;
1051 + memset(&sin, 0, sizeof(sin));
1052 + sin.sin_family = AF_INET;
1054 + sin.sin_len = sizeof(sin);
1056 sin.sin_addr.s_addr = inet_addr(var_smtp_bind_addr);
1057 if (sin.sin_addr.s_addr == INADDR_NONE)
1058 msg_fatal("%s: bad %s parameter: %s",
1059 @@ -174,6 +224,25 @@
1060 msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr));
1062 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1064 + char hbufl[NI_MAXHOST];
1065 + struct addrinfo hints, *res;
1067 + memset(&hints, 0, sizeof(hints));
1068 + hints.ai_family = sa->sa_family;
1069 + hints.ai_socktype = SOCK_STREAM;
1070 + hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1071 + snprintf(hbufl, sizeof(hbufl)-1, "%s", var_smtp_bind_addr);
1072 + if (getaddrinfo(hbufl, NULL, &hints, &res) == 0) {
1073 + (void)getnameinfo(res->ai_addr, res->ai_addrlen, hbufl,
1074 + sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1075 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1076 + msg_warn("%s: bind %s: %m", myname, hbufl);
1077 + freeaddrinfo(res);
1079 + msg_info("%s: bind %s", myname, hbufl);
1085 @@ -181,8 +250,17 @@
1086 * the mail appears to come from the "right" machine address.
1088 else if ((addr_list = own_inet_addr_list())->used == 1) {
1090 + struct sockaddr_in sin;
1091 + unsigned long inaddr; /*XXX BAD!*/
1093 + memset(&sin, 0, sizeof(sin));
1094 + sin.sin_family = AF_INET;
1096 + sin.sin_len = sizeof(sin);
1098 memcpy((char *) &sin.sin_addr, addr_list->addrs, sizeof(sin.sin_addr));
1099 - inaddr = ntohl(sin.sin_addr.s_addr);
1100 + inaddr = (unsigned long)ntohl(sin.sin_addr.s_addr);
1101 if (!IN_CLASSA(inaddr)
1102 || !(((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)) {
1103 if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
1104 @@ -190,30 +268,85 @@
1106 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1109 + char hbufl[NI_MAXHOST];
1110 + struct addrinfo hints, *res = NULL, *loopback = NULL;
1112 + memset(&hints, 0, sizeof(hints));
1113 + hints.ai_family = sa->sa_family;
1114 + hints.ai_socktype = SOCK_STREAM;
1115 + if (getaddrinfo(NULL, "0", &hints, &loopback) != 0)
1119 + * getnameinfo -> getaddrinfo loop is here so that we can
1120 + * get rid of port.
1122 + (void)getnameinfo((struct sockaddr *)addr_list->addrs, SA_LEN((struct sockaddr *)addr_list->addrs),
1123 + hbufl, sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1124 + hbufl[sizeof(hbufl)-1] = 0;
1125 + memset(&hints, 0, sizeof(hints));
1126 + hints.ai_family = sa->sa_family;
1127 + hints.ai_socktype = SOCK_STREAM;
1128 + hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1129 + if (getaddrinfo(hbufl, NULL, &hints, &res) == 0 &&
1130 + !(res->ai_addrlen == loopback->ai_addrlen &&
1131 + memcmp(res->ai_addr, loopback->ai_addr, res->ai_addrlen) == 0)) {
1132 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1133 + msg_warn("%s: bind %s: %m", myname, hbufl);
1135 + msg_info("%s: bind %s", myname, hbufl);
1138 + freeaddrinfo(res);
1140 + freeaddrinfo(loopback);
1145 * Connect to the SMTP server.
1147 - sin.sin_port = port;
1148 - memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr));
1149 + switch (addr->type) {
1152 + /* XXX scope unfriendly */
1153 + memset(sin6, 0, sizeof(*sin6));
1154 + sin6->sin6_port = port;
1155 + sin6->sin6_family = AF_INET6;
1156 + salen = sizeof(*sin6);
1157 + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
1158 + inet_ntop(AF_INET6, &sin6->sin6_addr, hbuf, sizeof(hbuf));
1161 + default: /* T_A */
1162 + memset(sin, 0, sizeof(*sin));
1163 + sin->sin_port = port;
1164 + sin->sin_family = AF_INET;
1165 + salen = sizeof(*sin);
1166 + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
1167 + inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
1171 + sa->sa_len = salen;
1175 msg_info("%s: trying: %s[%s] port %d...",
1176 - myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port));
1177 + myname, addr->name, hbuf, ntohs(port));
1178 if (var_smtp_conn_tmout > 0) {
1179 non_blocking(sock, NON_BLOCKING);
1180 - conn_stat = timed_connect(sock, (struct sockaddr *) & sin,
1181 - sizeof(sin), var_smtp_conn_tmout);
1182 + conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout);
1183 saved_errno = errno;
1184 non_blocking(sock, BLOCKING);
1185 errno = saved_errno;
1187 - conn_stat = connect(sock, (struct sockaddr *) & sin, sizeof(sin));
1188 + conn_stat = connect(sock, sa, salen);
1190 if (conn_stat < 0) {
1191 vstring_sprintf(why, "connect to %s[%s]: %m",
1192 - addr->name, inet_ntoa(sin.sin_addr));
1193 + addr->name, hbuf);
1194 smtp_errno = SMTP_RETRY;
1198 * Skip this host if it takes no action within some time limit.
1200 if (read_wait(sock, var_smtp_helo_tmout) < 0) {
1201 - vstring_sprintf(why, "connect to %s[%s]: read timeout",
1202 - addr->name, inet_ntoa(sin.sin_addr));
1203 + vstring_sprintf(why, "connect to %s [%s]: read timeout",
1204 + addr->name, hbuf);
1205 smtp_errno = SMTP_RETRY;
1209 stream = vstream_fdopen(sock, O_RDWR);
1210 if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
1211 vstring_sprintf(why, "connect to %s[%s]: server dropped connection without sending the initial greeting",
1212 - addr->name, inet_ntoa(sin.sin_addr));
1213 + addr->name, hbuf);
1214 smtp_errno = SMTP_RETRY;
1215 vstream_fclose(stream);
1219 if (ch == '4' && var_smtp_skip_4xx_greeting) {
1220 vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1221 - addr->name, inet_ntoa(sin.sin_addr));
1222 + addr->name, hbuf);
1223 smtp_errno = SMTP_RETRY;
1224 vstream_fclose(stream);
1226 @@ -392,12 +392,12 @@
1228 if (ch == '5' && var_smtp_skip_5xx_greeting) {
1229 vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1230 - addr->name, inet_ntoa(sin.sin_addr));
1231 + addr->name, hbuf);
1232 smtp_errno = SMTP_RETRY;
1233 vstream_fclose(stream);
1236 - return (smtp_session_alloc(dest, stream, addr->name, inet_ntoa(sin.sin_addr)));
1237 + return (smtp_session_alloc(dest, stream, addr->name, hbuf));
1240 /* smtp_connect_host - direct connection to host */
1241 diff -Nur postfix-1.1.2.orig/src/smtp/smtp_unalias.c postfix-1.1.2/src/smtp/smtp_unalias.c
1242 --- postfix-1.1.2.orig/src/smtp/smtp_unalias.c Thu Sep 28 19:06:09 2000
1243 +++ postfix-1.1.2/src/smtp/smtp_unalias.c Mon Jan 28 12:40:04 2002
1245 if ((result = htable_find(cache, name)) == 0) {
1246 fqdn = vstring_alloc(10);
1247 if (dns_lookup_types(name, smtp_unalias_flags, (DNS_RR **) 0,
1248 - fqdn, (VSTRING *) 0, T_MX, T_A, 0) != DNS_OK)
1249 + fqdn, (VSTRING *) 0, T_MX, T_A,
1254 vstring_strcpy(fqdn, name);
1255 htable_enter(cache, name, result = vstring_export(fqdn));
1257 diff -Nur postfix-1.1.2.orig/src/smtpd/smtpd_check.c postfix-1.1.2/src/smtpd/smtpd_check.c
1258 --- postfix-1.1.2.orig/src/smtpd/smtpd_check.c Mon Jan 28 12:38:34 2002
1259 +++ postfix-1.1.2/src/smtpd/smtpd_check.c Mon Jan 28 12:40:04 2002
1260 @@ -1187,6 +1195,49 @@
1262 static int has_my_addr(const char *host)
1265 + char *myname = "has_my_addr";
1266 + struct addrinfo hints, *res, *res0;
1268 + char hbuf[NI_MAXHOST];
1271 + msg_info("%s: host %s", myname, host);
1274 + * If we can't lookup the host, play safe and assume it is OK.
1279 + memset(&hints, 0, sizeof(hints));
1280 + hints.ai_family = PF_UNSPEC;
1281 + hints.ai_socktype = SOCK_DGRAM;
1282 + error = getaddrinfo(host, NULL, &hints, &res0);
1285 + msg_info("%s: host %s: %s", myname, host, gai_strerror(error));
1288 + for (res = res0; res; res = res->ai_next) {
1289 + if (msg_verbose) {
1290 + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
1291 + NULL, 0, NI_NUMERICHOST)) {
1292 + strncpy(hbuf, "???", sizeof(hbuf));
1294 + msg_info("%s: addr %s", myname, hbuf);
1296 + if (own_inet_addr(res->ai_addr)) {
1297 + freeaddrinfo(res0);
1301 + freeaddrinfo(res0);
1303 + msg_info("%s: host %s: no match", myname, host);
1307 char *myname = "has_my_addr";
1308 struct in_addr addr;
1310 @@ -1222,6 +1273,7 @@
1311 msg_info("%s: host %s: no match", myname, host);
1317 /* i_am_mx - is this machine listed as MX relay */
1318 @@ -1647,11 +1699,28 @@
1319 #define CHK_ADDR_RETURN(x,y) { *found = y; return(x); }
1321 addr = STR(vstring_strcpy(error_text, address));
1324 + if (strncmp(addr, "::ffff:", 7) == 0 && msg_verbose)
1325 + msg_info("%s: %s v6 addr in v4 compat-mode, "
1326 + "converted to v4 for map checking compatibility (%s)", \
1327 + myname, addr, addr+7);
1330 if ((dict = dict_handle(table)) == 0)
1331 msg_panic("%s: dictionary not found: %s", myname, table);
1333 if (flags == 0 || (flags & dict->flags) != 0) {
1335 + if (strncmp(addr, "::ffff:", 7) == 0) {
1336 + /* try if ::ffff: formati is present in map, if not, try
1337 + traditional IPv4 format striping :ffff: part */
1338 + if ((value = dict_get(dict, addr)) != 0 || \
1339 + (value = dict_get(dict, addr+7)) != 0)
1340 + CHK_ADDR_RETURN(check_table_result(state, table, value, address,
1341 + reply_name, reply_class,
1345 if ((value = dict_get(dict, addr)) != 0)
1346 CHK_ADDR_RETURN(check_table_result(state, table, value, address,
1347 reply_name, reply_class,
1348 @@ -2402,16 +2463,32 @@
1351 SMTPD_RBL_STATE *rbl;
1355 + struct in6_addr a;
1359 msg_info("%s: %s %s", myname, reply_class, addr);
1362 - * IPv4 only for now
1366 + /* IPv4 only for now */
1367 if (inet_pton(AF_INET, addr, &a) != 1)
1368 return SMTPD_CHECK_DUNNO;
1369 + octets = argv_split(state->addr, ".");
1371 + /* IPv4 and IPv6-mapped IPv4 only for now */
1372 + if (inet_pton(AF_INET, state->addr, &a) == 1)
1373 + octets = argv_split(state->addr, ".");
1375 + struct in6_addr a6;
1376 + if (inet_pton(AF_INET6, state->addr, &a6) != 1)
1377 + return SMTPD_CHECK_DUNNO;
1378 + if (!IN6_IS_ADDR_V4MAPPED(&a6) || (strrchr(state->addr,':') == NULL))
1379 + return SMTPD_CHECK_DUNNO;
1380 + octets = argv_split(strrchr(state->addr,':')+1, ".");
1385 diff -Nur postfix-1.1.2.orig/src/smtpd/smtpd_peer.c postfix-1.1.2/src/smtpd/smtpd_peer.c
1386 --- postfix-1.1.2.orig/src/smtpd/smtpd_peer.c Thu Jul 5 22:09:47 2001
1387 +++ postfix-1.1.2/src/smtpd/smtpd_peer.c Mon Jan 28 12:40:04 2002
1392 +/* Utility library. */
1395 +#include <mymalloc.h>
1396 +#include <valid_hostname.h>
1397 +#include <stringops.h>
1399 +/* Global library. */
1402 * Older systems don't have h_errno. Even modern systems don't have
1408 -/* Utility library. */
1411 -#include <mymalloc.h>
1412 -#include <valid_hostname.h>
1413 -#include <stringops.h>
1415 -/* Global library. */
1419 +#define GAI_STRERROR(error) \
1420 + ((error = EAI_SYSTEM) ? gai_strerror(error) : strerror(errno))
1423 /* Application-specific. */
1426 @@ -102,21 +106,28 @@
1428 void smtpd_peer_init(SMTPD_STATE *state)
1430 - struct sockaddr_in sin;
1431 - SOCKADDR_SIZE len = sizeof(sin);
1433 + struct sockaddr_storage ss;
1435 + struct sockaddr ss;
1436 + struct in_addr *in;
1440 + struct sockaddr *sa;
1441 + SOCKADDR_SIZE len;
1443 + sa = (struct sockaddr *)&ss;
1447 * Avoid suprious complaints from Purify on Solaris.
1449 - memset((char *) &sin, 0, len);
1450 + memset((char *) &sa, 0, len);
1453 * Look up the peer address information.
1455 - if (getpeername(vstream_fileno(state->client),
1456 - (struct sockaddr *) & sin, &len) >= 0) {
1457 + if (getpeername(vstream_fileno(state->client), sa, &len) >= 0) {
1461 @@ -132,23 +143,56 @@
1463 * Look up and "verify" the client hostname.
1465 - else if (errno == 0 && sin.sin_family == AF_INET) {
1466 - state->addr = mystrdup(inet_ntoa(sin.sin_addr));
1467 - hp = gethostbyaddr((char *) &(sin.sin_addr),
1468 - sizeof(sin.sin_addr), AF_INET);
1470 + else if (errno == 0 && (sa->sa_family == AF_INET
1472 + || sa->sa_family == AF_INET6
1476 + char hbuf[NI_MAXHOST];
1477 + char abuf[NI_MAXHOST];
1478 + struct addrinfo hints, *rnull = NULL;
1480 + char abuf[sizeof("255.255.255.255") + 1];
1486 + (void)getnameinfo(sa, len, abuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
1488 + in = &((struct sockaddr_in *)sa)->sin_addr;
1489 + inet_ntop(AF_INET, in, abuf, sizeof(hbuf));
1491 + state->addr = mystrdup(abuf);
1493 + error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD);
1496 + hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET);
1499 + hbuf = mystrdup(hp->h_name);
1504 state->name = mystrdup("unknown");
1506 + state->peer_code = (error == EAI_AGAIN ? 4 : 5);
1508 state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
1509 - } else if (valid_hostaddr(hp->h_name, DONT_GRIPE)) {
1511 + } else if (valid_hostaddr(hbuf, DONT_GRIPE)) {
1512 msg_warn("numeric result %s in address->name lookup for %s",
1513 - hp->h_name, state->addr);
1514 + hbuf, state->addr);
1515 state->name = mystrdup("unknown");
1516 state->peer_code = 5;
1517 - } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
1518 + } else if (!valid_hostname(hbuf, DONT_GRIPE)) {
1519 state->name = mystrdup("unknown");
1520 state->peer_code = 5;
1522 - state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */
1523 + state->name = mystrdup(hbuf); /* hp->name is clobbered!! */
1524 state->peer_code = 2;
1527 @@ -150,16 +194,31 @@
1528 state->peer_code = code; \
1532 + memset(&hints, 0, sizeof(hints));
1533 + hints.ai_family = AF_UNSPEC;
1534 + hints.ai_socktype = SOCK_STREAM;
1535 + error = getaddrinfo(state->name, NULL, &hints, &rnull);
1537 + msg_warn("%s: hostname %s verification failed: %s",
1538 + state->addr, state->name, GAI_STRERROR(error));
1539 + REJECT_PEER_NAME(state, (error == EAI_AGAIN ? 4 : 5));
1541 + /* memcmp() isn't needed if we use getaddrinfo */
1543 + freeaddrinfo(rnull);
1545 hp = gethostbyname(state->name); /* clobbers hp->name!! */
1547 msg_warn("%s: hostname %s verification failed: %s",
1548 state->addr, state->name, HSTRERROR(h_errno));
1549 REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ? 4 : 5));
1550 - } else if (hp->h_length != sizeof(sin.sin_addr)) {
1551 + } else if (hp->h_length != sizeof(*in)) {
1552 msg_warn("%s: hostname %s verification failed: bad address size %d",
1553 state->addr, state->name, hp->h_length);
1554 REJECT_PEER_NAME(state, 5);
1557 for (i = 0; /* void */ ; i++) {
1558 if (hp->h_addr_list[i] == 0) {
1559 msg_warn("%s: address not listed for hostname %s",
1560 @@ -167,12 +226,11 @@
1561 REJECT_PEER_NAME(state, 5);
1564 - if (memcmp(hp->h_addr_list[i],
1565 - (char *) &sin.sin_addr,
1566 - sizeof(sin.sin_addr)) == 0)
1567 + if (memcmp(hp->h_addr_list[i], (char *)in, sizeof(*in)) == 0)
1568 break; /* keep peer name */
1575 diff -Nur postfix-1.1.2.orig/src/smtpstone/smtp-sink.c postfix-1.1.2/src/smtpstone/smtp-sink.c
1576 --- postfix-1.1.2.orig/src/smtpstone/smtp-sink.c Thu Nov 8 21:15:32 2001
1577 +++ postfix-1.1.2/src/smtpstone/smtp-sink.c Mon Jan 28 12:40:04 2002
1580 if (strncmp(argv[optind], "inet:", 5) == 0)
1582 - sock = inet_listen(argv[optind], backlog, BLOCKING);
1583 + sock = inet_listen(argv[optind], backlog, BLOCKING, 1);
1587 diff -Nur postfix-1.1.2.orig/src/util/Makefile.in postfix-1.1.2/src/util/Makefile.in
1588 --- postfix-1.1.2.orig/src/util/Makefile.in Mon Jan 28 12:38:34 2002
1589 +++ postfix-1.1.2/src/util/Makefile.in Mon Jan 28 12:41:17 2002
1591 dict_tcp.c dict_unix.c dir_forest.c doze.c duplex_pipe.c \
1592 environ.c events.c exec_command.c fifo_listen.c fifo_trigger.c \
1593 file_limit.c find_inet.c fsspace.c fullname.c get_domainname.c \
1594 - get_hostname.c hex_quote.c htable.c inet_addr_host.c \
1595 + get_hostname.c get_port.c hex_quote.c htable.c inet_addr_host.c \
1596 inet_addr_list.c inet_addr_local.c inet_connect.c inet_listen.c \
1597 inet_trigger.c inet_util.c intv.c line_wrap.c lowercase.c \
1598 lstat_as.c mac_expand.c mac_parse.c make_dirs.c match_list.c \
1600 dict_tcp.o dict_unix.o dir_forest.o doze.o duplex_pipe.o \
1601 environ.o events.o exec_command.o fifo_listen.o fifo_trigger.o \
1602 file_limit.o find_inet.o fsspace.o fullname.o get_domainname.o \
1603 - get_hostname.o hex_quote.o htable.o inet_addr_host.o \
1604 + get_hostname.o get_port.o hex_quote.o htable.o inet_addr_host.o \
1605 inet_addr_list.o inet_addr_local.o inet_connect.o inet_listen.o \
1606 inet_trigger.o inet_util.o intv.o line_wrap.o lowercase.o \
1607 lstat_as.o mac_expand.o mac_parse.o make_dirs.o match_list.o \
1609 dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
1610 dict_nisplus.h dict_pcre.h dict_regexp.h dict_static.h dict_tcp.h \
1611 dict_unix.h dir_forest.h events.h exec_command.h find_inet.h \
1612 - fsspace.h fullname.h get_domainname.h get_hostname.h hex_quote.h \
1613 + fsspace.h fullname.h get_domainname.h get_hostname.h get_port.h hex_quote.h \
1614 htable.h inet_addr_host.h inet_addr_list.h inet_addr_local.h \
1615 inet_util.h intv.h iostuff.h line_wrap.h listen.h lstat_as.h \
1616 mac_expand.h mac_parse.h make_dirs.h match_list.h match_ops.h \
1618 get_domainname.o: mymalloc.h
1619 get_domainname.o: get_hostname.h
1620 get_domainname.o: get_domainname.h
1621 +get_port.o: sys_defs.h
1622 get_hostname.o: get_hostname.c
1623 get_hostname.o: sys_defs.h
1624 get_hostname.o: mymalloc.h
1626 match_list.o: stringops.h
1627 match_list.o: argv.h
1628 match_list.o: dict.h
1629 +match_list.o: inet_util.h
1630 match_list.o: match_ops.h
1631 match_list.o: match_list.h
1632 match_ops.o: match_ops.c
1633 diff -Nur postfix-1.1.2.orig/src/util/get_port.c postfix-1.1.2/src/util/get_port.c
1634 --- postfix-1.1.2.orig/src/util/get_port.c Thu Jan 1 01:00:00 1970
1635 +++ postfix-1.1.2/src/util/get_port.c Mon Jan 28 12:40:04 2002
1641 +/* trivial host and port extracter
1643 +/* #include <get_port.h>
1645 +/* char *get_port(data)
1649 +/* get_port() extract host name or ip address from
1650 +/* strings such as [3ffe:902:12::10]:25, [::1]
1651 +/* or 192.168.0.1:25, and null-terminates the
1652 +/* \fIdata\fR at the first occurrence of port separator.
1654 +/* If port not found return null pointer.
1658 +/* BSD Style (or BSD like) license.
1660 +/* Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1664 +/* System libraries */
1666 +#include <sys_defs.h>
1667 +#include <string.h>
1669 +/* Utility library. */
1671 +#include "get_port.h"
1673 +/* get_port - extract port number from string */
1675 +char *get_port(char *data)
1677 + const char *escl=strchr(data,'[');
1678 + const char *sepl=strchr(data,':');
1679 + char *escr=strrchr(data,']');
1680 + char *sepr=strrchr(data,':');
1682 + /* extract from "[address]:port" or "[address]"*/
1685 + memmove(data, data + 1, strlen(data) - strlen(escr));
1686 + data[strlen(data) - strlen(escr) - 1] = 0;
1690 + return (*escr ? escr : NULL);
1692 + /* extract from "address:port" or "address" */
1693 + if ((sepl == sepr) && sepr && sepl)
1699 + /* return empty string */
1702 diff -Nur postfix-1.1.2.orig/src/util/get_port.h postfix-1.1.2/src/util/get_port.h
1703 --- postfix-1.1.2.orig/src/util/get_port.h Thu Jan 1 01:00:00 1970
1704 +++ postfix-1.1.2/src/util/get_port.h Mon Jan 28 12:40:04 2002
1706 +#ifndef _GET_PORT_H_INCLUDED_
1707 +#define _GET_PORT_H_INCLUDED_
1713 +/* trivial host and port extracter
1715 +/* #include <get_port.h>
1719 + /* External interface. */
1721 +extern char *get_port(char *);
1727 +/* BSD Style (or BSD like) license.
1729 +/* Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1734 diff -Nur postfix-1.1.2.orig/src/util/inet_addr_host.c postfix-1.1.2/src/util/inet_addr_host.c
1735 --- postfix-1.1.2.orig/src/util/inet_addr_host.c Fri Dec 11 19:55:35 1998
1736 +++ postfix-1.1.2/src/util/inet_addr_host.c Mon Jan 28 12:40:04 2002
1738 #include <sys_defs.h>
1739 #include <netinet/in.h>
1740 #include <arpa/inet.h>
1741 +#include <sys/socket.h>
1743 +#include <stdlib.h>
1744 +#include <string.h>
1747 #define INADDR_NONE 0xffffffff
1750 #include <inet_addr_list.h>
1751 #include <inet_addr_host.h>
1756 /* inet_addr_host - look up address list for host */
1758 int inet_addr_host(INET_ADDR_LIST *addr_list, const char *hostname)
1762 + struct addrinfo hints, *res0, *res;
1764 + char buforhosta[1024];
1769 struct in_addr addr;
1771 int initial_count = addr_list->used;
1774 + memset(&hints, 0, sizeof(hints));
1775 + hints.ai_family = PF_UNSPEC;
1776 + hints.ai_socktype = SOCK_DGRAM;
1777 + error = getaddrinfo(hostname, NULL, &hints, &res0);
1779 + for (res = res0; res; res = res->ai_next) {
1780 + if(res->ai_family != AF_INET && res->ai_family != AF_INET6)
1782 + /* filter out address families that are not supported */
1783 + s = socket(res->ai_family, SOCK_DGRAM, 0);
1788 + inet_addr_list_append(addr_list, res->ai_addr);
1790 + freeaddrinfo(res0);
1793 if ((addr.s_addr = inet_addr(hostname)) != INADDR_NONE) {
1794 inet_addr_list_append(addr_list, &addr);
1797 inet_addr_list_append(addr_list,
1798 (struct in_addr *) * hp->h_addr_list++);
1802 return (addr_list->used - initial_count);
1811 INET_ADDR_LIST addr_list;
1813 + struct sockaddr *sa;
1814 + char hbuf[NI_MAXHOST];
1816 msg_vstream_init(argv[0], VSTREAM_ERR);
1819 if (inet_addr_host(&addr_list, *argv) == 0)
1820 msg_fatal("not found: %s", *argv);
1822 - for (i = 0; i < addr_list.used; i++)
1823 - vstream_printf("%s\n", inet_ntoa(addr_list.addrs[i]));
1824 + for (i = 0; i < addr_list.used; i++) {
1825 + sa = (struct sockaddr *)&addr_list.addrs[i];
1826 + getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
1828 + vstream_printf("%s\n", hbuf);
1830 vstream_fflush(VSTREAM_OUT);
1832 inet_addr_list_free(&addr_list);
1833 diff -Nur postfix-1.1.2.orig/src/util/inet_addr_list.c postfix-1.1.2/src/util/inet_addr_list.c
1834 --- postfix-1.1.2.orig/src/util/inet_addr_list.c Tue Jul 31 20:13:41 2001
1835 +++ postfix-1.1.2/src/util/inet_addr_list.c Mon Jan 28 12:40:04 2002
1837 #include <arpa/inet.h>
1843 +#include <string.h>
1844 +#include <sys/socket.h>
1847 /* Utility library. */
1855 + list->addrs = (struct sockaddr_storage *)
1857 list->addrs = (struct in_addr *)
1859 mymalloc(sizeof(*list->addrs) * list->size);
1862 /* inet_addr_list_append - append address to internet address list */
1865 +void inet_addr_list_append(INET_ADDR_LIST *list,
1866 + struct sockaddr * addr)
1868 + char *myname = "inet_addr_list_append";
1869 + char hbuf[NI_MAXHOST];
1871 + if (msg_verbose > 1) {
1872 + if (getnameinfo(addr, SA_LEN(addr), hbuf, sizeof(hbuf), NULL, 0,
1873 + NI_NUMERICHOST)) {
1874 + strncpy(hbuf, "??????", sizeof(hbuf));
1876 + msg_info("%s: %s", myname, hbuf);
1879 + if (list->used >= list->size)
1881 + list->addrs = (struct sockaddr_storage *)
1882 + myrealloc((char *) list->addrs,
1883 + sizeof(*list->addrs) * list->size);
1884 + memcpy(&list->addrs[list->used++], addr, SA_LEN(addr));
1887 void inet_addr_list_append(INET_ADDR_LIST *list, struct in_addr * addr)
1889 char *myname = "inet_addr_list_append";
1890 @@ -83,15 +117,22 @@
1891 sizeof(*list->addrs) * list->size);
1892 list->addrs[list->used++] = *addr;
1896 /* inet_addr_list_comp - compare addresses */
1898 static int inet_addr_list_comp(const void *a, const void *b)
1901 + if(((struct sockaddr*)a)->sa_family != ((struct sockaddr*)b)->sa_family)
1902 + return ( ((struct sockaddr*)a)->sa_family - ((struct sockaddr*)b)->sa_family );
1903 + return memcmp(a,b,SA_LEN((struct sockaddr*)a));
1905 const struct in_addr *a_addr = (const struct in_addr *) a;
1906 const struct in_addr *b_addr = (const struct in_addr *) b;
1908 return (a_addr->s_addr - b_addr->s_addr);
1912 /* inet_addr_list_uniq - weed out duplicates */
1913 diff -Nur postfix-1.1.2.orig/src/util/inet_addr_list.h postfix-1.1.2/src/util/inet_addr_list.h
1914 --- postfix-1.1.2.orig/src/util/inet_addr_list.h Tue Jul 31 19:56:47 2001
1915 +++ postfix-1.1.2/src/util/inet_addr_list.h Mon Jan 28 12:40:04 2002
1918 #include <netinet/in.h>
1922 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1923 +#define SS_LEN(x) (((x).ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1925 +#define SA_LEN(x) ((x)->sa_len)
1926 +#define SS_LEN(x) ((x).ss_len)
1931 * External interface.
1933 typedef struct INET_ADDR_LIST {
1934 int used; /* nr of elements in use */
1935 int size; /* actual list size */
1937 + struct sockaddr_storage *addrs; /* payload */
1939 struct in_addr *addrs; /* payload */
1943 extern void inet_addr_list_init(INET_ADDR_LIST *);
1944 extern void inet_addr_list_free(INET_ADDR_LIST *);
1945 extern void inet_addr_list_uniq(INET_ADDR_LIST *);
1948 +extern void inet_addr_list_append(INET_ADDR_LIST *, struct sockaddr *);
1950 extern void inet_addr_list_append(INET_ADDR_LIST *, struct in_addr *);
1955 diff -Nur postfix-1.1.2.orig/src/util/inet_addr_local.c postfix-1.1.2/src/util/inet_addr_local.c
1956 --- postfix-1.1.2.orig/src/util/inet_addr_local.c Sun Feb 25 19:20:19 2001
1957 +++ postfix-1.1.2/src/util/inet_addr_local.c Mon Jan 28 12:40:04 2002
1962 +#if defined(INET6) && (defined (LINUX) || defined (LINUX2))
1966 +#ifdef HAVE_GETIFADDRS
1967 +#include <ifaddrs.h>
1970 /* Utility library. */
1972 @@ -78,18 +85,104 @@
1974 int inet_addr_local(INET_ADDR_LIST *addr_list, INET_ADDR_LIST *mask_list)
1976 +#ifdef HAVE_GETIFADDRS
1977 + char *myname = "inet_addr_local";
1978 + struct ifaddrs *ifap, *ifa;
1979 + int initial_count = addr_list->used;
1980 + struct sockaddr *sa, *sam;
1983 + struct sockaddr_in6 addr6;
1986 + void *addr,*addrm;
1989 + if (getifaddrs(&ifap) < 0)
1990 + msg_fatal("%s: getifaddrs: %m", myname);
1992 + for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1993 + if (! (ifa->ifa_flags & IFF_RUNNING) || ifa->ifa_addr==NULL)
1995 + sa = ifa->ifa_addr;
1996 + sam = ifa->ifa_netmask;
1997 + switch (ifa->ifa_addr->sa_family) {
2000 + addr = (void *)&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
2001 + addrm = (void *)&((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
2007 + memcpy(&addr6, ifa->ifa_addr, ifa->ifa_addr->sa_len);
2008 + /* decode scoped address notation */
2009 + if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
2010 + IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
2011 + addr6.sin6_scope_id == 0) {
2012 + addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
2013 + (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
2014 + addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
2015 + sa = (struct sockaddr *)&addr6;
2025 + inet_addr_list_append(addr_list, sa);
2026 + if (mask_list != NULL)
2027 + inet_addr_list_append(mask_list, sam);
2029 + inet_addr_list_append(addr_list, (struct in_addr *)addr);
2030 + if (mask_list != NULL)
2031 + inet_addr_list_append(mask_list, (struct in_addr *)addrm);
2035 + freeifaddrs(ifap);
2036 + return (addr_list->used - initial_count);
2038 char *myname = "inet_addr_local";
2041 struct ifreq *the_end;
2043 - VSTRING *buf = vstring_alloc(1024);
2045 int initial_count = addr_list->used;
2046 struct in_addr addr;
2047 struct ifreq *ifr_mask;
2050 +#if defined (LINUX) || defined (LINUX2)
2051 +#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
2053 + char addr6p[8][5], addr6res[40], devname[20];
2054 + int plen, scope, dad_status, if_idx, gaierror;
2055 + struct addrinfo hints, *res, *res0;
2057 + struct sockaddr_in6 addr6;
2059 - if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
2062 + buf = vstring_alloc(1024);
2064 + if ((sock = socket(af, SOCK_DGRAM, 0)) < 0) {
2066 + if (af == AF_INET6)
2069 + msg_warn("%s: socket: %m", myname);
2074 msg_fatal("%s: socket: %m", myname);
2078 * Get the network interface list. XXX The socket API appears to have no
2079 @@ -126,10 +213,15 @@
2081 the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2082 for (ifr = ifc.ifc_req; ifr < the_end;) {
2083 - if (ifr->ifr_addr.sa_family == AF_INET) { /* IP interface */
2084 + if ((ifr->ifr_addr.sa_family == AF_INET) &&
2085 + (ifr->ifr_addr.sa_family == af)) { /* IP interface */
2086 addr = ((struct sockaddr_in *) & ifr->ifr_addr)->sin_addr;
2087 if (addr.s_addr != INADDR_ANY) { /* has IP address */
2089 + inet_addr_list_append(addr_list, &ifr->ifr_addr);
2091 inet_addr_list_append(addr_list, &addr);
2094 ifr_mask = (struct ifreq *) mymalloc(IFREQ_SIZE(ifr));
2095 memcpy((char *) ifr_mask, (char *) ifr, IFREQ_SIZE(ifr));
2096 @@ -141,11 +233,61 @@
2101 + else if ((ifr->ifr_addr.sa_family == AF_INET6) &&
2102 + (ifr->ifr_addr.sa_family == af)) { /* IPv6 interface */
2103 + addr6 = *((struct sockaddr_in6 *) & ifr->ifr_addr);
2105 + /* decode scoped address notation */
2106 + if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
2107 + IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
2108 + addr6.sin6_scope_id == 0) {
2109 + addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
2110 + (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
2111 + addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
2114 + if (!(IN6_IS_ADDR_UNSPECIFIED(&addr6.sin6_addr)))
2115 + inet_addr_list_append(addr_list, (struct sockaddr *)&addr6);
2118 ifr = NEXT_INTERFACE(ifr);
2124 + if (af != AF_INET6) {
2126 + goto other_socket_type;
2128 +#if defined (LINUX) || defined (LINUX2)
2129 + if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
2130 + while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
2131 + addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4],
2132 + addr6p[5], addr6p[6], addr6p[7],
2133 + &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
2134 + sprintf(addr6res, "%s:%s:%s:%s:%s:%s:%s:%s",
2135 + addr6p[0], addr6p[1], addr6p[2], addr6p[3],
2136 + addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
2137 + addr6res[sizeof(addr6res) - 1] = 0;
2138 + memset(&hints, 0, sizeof(hints));
2139 + hints.ai_flags = AI_NUMERICHOST;
2140 + hints.ai_family = AF_UNSPEC;
2141 + hints.ai_socktype = SOCK_DGRAM;
2142 + gaierror = getaddrinfo(addr6res, NULL, &hints, &res0);
2144 + for (res = res0; res; res = res->ai_next) {
2145 + inet_addr_list_append(addr_list, res->ai_addr);
2147 + freeaddrinfo(res0);
2153 return (addr_list->used - initial_count);
2159 INET_ADDR_LIST addr_list;
2160 INET_ADDR_LIST mask_list;
2162 + char abuf[NI_MAXHOST], mbuf[NI_MAXHOST];
2163 + struct sockaddr *sa;
2165 msg_vstream_init(argv[0], VSTREAM_ERR);
2167 @@ -172,8 +316,17 @@
2168 msg_warn("found only one active network interface");
2170 for (i = 0; i < addr_list.used; i++) {
2171 - vstream_printf("%s/", inet_ntoa(addr_list.addrs[i]));
2172 - vstream_printf("%s\n", inet_ntoa(mask_list.addrs[i]));
2173 + sa = (struct sockaddr *)&addr_list.addrs[i];
2174 + if (getnameinfo(sa, SA_LEN(sa), abuf, sizeof(abuf), NULL, 0,
2175 + NI_NUMERICHOST)) {
2176 + strncpy(abuf, "???", sizeof(abuf));
2178 + sa = (struct sockaddr *)&mask_list.addrs[i];
2179 + if (getnameinfo(sa, SA_LEN(sa), mbuf, sizeof(mbuf), NULL, 0,
2180 + NI_NUMERICHOST)) {
2181 + strncpy(mbuf, "???", sizeof(mbuf));
2183 + vstream_printf("%s/%s\n", abuf, mbuf);
2185 vstream_fflush(VSTREAM_OUT);
2186 inet_addr_list_free(&addr_list);
2187 diff -Nur postfix-1.1.2.orig/src/util/inet_connect.c postfix-1.1.2/src/util/inet_connect.c
2188 --- postfix-1.1.2.orig/src/util/inet_connect.c Mon Nov 20 19:06:31 2000
2189 +++ postfix-1.1.2/src/util/inet_connect.c Mon Jan 28 12:40:04 2002
2198 /* Utility library. */
2205 + struct addrinfo hints, *res, *res0;
2208 struct sockaddr_in sin;
2216 buf = inet_parse(addr, &host, &port);
2220 + memset(&hints, 0, sizeof(hints));
2221 + hints.ai_family = PF_UNSPEC;
2222 + hints.ai_socktype = SOCK_STREAM;
2223 + hints.ai_flags = AI_NUMERICHOST; /* find_inet_addr is numeric only */
2224 + if (getaddrinfo(host, port, &hints, &res0))
2225 + msg_fatal("host not found: %s", host);
2229 memset((char *) &sin, 0, sizeof(sin));
2230 sin.sin_family = AF_INET;
2231 sin.sin_addr.s_addr = find_inet_addr(host);
2232 sin.sin_port = find_inet_port(port, "tcp");
2238 + for (res = res0; res; res = res->ai_next) {
2239 + if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2242 + sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
2245 + if (timeout > 0) {
2246 + non_blocking(sock, NON_BLOCKING);
2247 + if (timed_connect(sock, res->ai_addr, res->ai_addrlen, timeout) < 0) {
2252 + if (block_mode != NON_BLOCKING)
2253 + non_blocking(sock, block_mode);
2256 + non_blocking(sock, block_mode);
2257 + if (connect(sock, res->ai_addr, res->ai_addrlen) < 0
2258 + && errno != EINPROGRESS) {
2266 + freeaddrinfo(res0);
2270 * Create a client socket.
2278 diff -Nur postfix-1.1.2.orig/src/util/inet_listen.c postfix-1.1.2/src/util/inet_listen.c
2279 --- postfix-1.1.2.orig/src/util/inet_listen.c Mon Nov 20 19:06:32 2000
2280 +++ postfix-1.1.2/src/util/inet_listen.c Mon Jan 28 12:40:04 2002
2283 /* #include <listen.h>
2285 -/* int inet_listen(addr, backlog, block_mode)
2286 +/* int inet_listen(addr, backlog, block_mode, addinuse_fatal)
2287 /* const char *addr;
2291 #include <sys_defs.h>
2292 #include <sys/socket.h>
2293 #include <netinet/in.h>
2295 +#if (! __GLIBC__ >= 2 && __GLIBC_MINOR__ >=1 )
2296 +#include <netinet6/in6.h>
2299 #include <arpa/inet.h>
2301 #ifndef MAXHOSTNAMELEN
2302 #include <sys/param.h>
2308 @@ -77,35 +83,116 @@
2310 /* inet_listen - create inet-domain listener */
2312 -int inet_listen(const char *addr, int backlog, int block_mode)
2313 +int inet_listen(const char *addr, int backlog, int block_mode, int addrinuse_fatal)
2316 + struct addrinfo *res, *res0, hints;
2323 + struct sockaddr *ai_addr;
2324 + SOCKADDR_SIZE ai_addrlen;
2325 + struct ai *ai_next;
2326 + } *res, *res0, resbody;
2327 struct sockaddr_in sin;
2331 + int addrinuse = 0;
2336 + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
2338 + char hbuf[sizeof("255.255.255.255") + 1];
2339 + char pbuf[sizeof("255.255.255.255") + 1];
2341 + char *cause = "unknown";
2344 * Translate address information to internal form.
2346 buf = inet_parse(addr, &host, &port);
2347 - memset((char *) &sin, 0, sizeof(sin));
2349 + memset(&hints, 0, sizeof(hints));
2350 + hints.ai_flags = AI_PASSIVE;
2351 + hints.ai_family = AF_UNSPEC;
2352 + hints.ai_socktype = SOCK_STREAM;
2353 + error = getaddrinfo(*host ? host : NULL, *port ? port : "0", &hints, &res0);
2355 + msg_fatal("getaddrinfo: %s", gai_strerror(error));
2359 + memset(&sin, 0, sizeof(sin));
2360 sin.sin_family = AF_INET;
2362 + sin.sin_len = sizeof(sin);
2364 sin.sin_port = find_inet_port(port, "tcp");
2365 sin.sin_addr.s_addr = (*host ? find_inet_addr(host) : INADDR_ANY);
2369 - * Create a listener socket.
2371 - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
2372 - msg_fatal("socket: %m");
2373 - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0)
2374 - msg_fatal("setsockopt: %m");
2375 - if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
2376 - msg_fatal("bind %s port %d: %m", sin.sin_addr.s_addr == INADDR_ANY ?
2377 - "INADDR_ANY" : inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
2378 + memset(&resbody, 0, sizeof(resbody));
2379 + resbody.ai_socktype = SOCK_STREAM;
2380 + resbody.ai_family = AF_INET;
2381 + resbody.ai_addr = (struct sockaddr *)&sin;
2382 + resbody.ai_addrlen = sizeof(sin);
2388 + for (res = res0; res; res = res->ai_next) {
2389 + if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2393 + * Create a listener socket.
2395 + if ((sock = socket(res->ai_family, res->ai_socktype, 0)) < 0) {
2400 + if (res->ai_family == AF_INET6 &&
2401 + setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &t, sizeof(t)) < 0) {
2402 + /* if kernel/libc don't support this simple ignore it
2403 + cause = "setsockopt(IPV6_V6ONLY)";
2411 + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0) {
2412 + cause = "setsockopt(SO_REUSEADDR)";
2418 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
2420 + if (errno == EADDRINUSE)
2428 + if (sock < 0 && (addrinuse_fatal || !addrinuse))
2429 + msg_fatal("%s: %m", cause);
2431 + freeaddrinfo(res0);
2435 non_blocking(sock, block_mode);
2436 if (listen(sock, backlog) < 0)
2437 msg_fatal("listen: %m");
2438 diff -Nur postfix-1.1.2.orig/src/util/listen.h postfix-1.1.2/src/util/listen.h
2439 --- postfix-1.1.2.orig/src/util/listen.h Mon Mar 22 02:57:11 1999
2440 +++ postfix-1.1.2/src/util/listen.h Mon Jan 28 12:40:04 2002
2442 * Listener external interface.
2444 extern int unix_listen(const char *, int, int);
2445 -extern int inet_listen(const char *, int, int);
2446 +extern int inet_listen(const char *, int, int, int);
2447 extern int fifo_listen(const char *, int, int);
2448 extern int stream_listen(const char *, int, int);
2450 diff -Nur postfix-1.1.2.orig/src/util/match_list.c postfix-1.1.2/src/util/match_list.c
2451 --- postfix-1.1.2.orig/src/util/match_list.c Tue Nov 20 21:07:15 2001
2452 +++ postfix-1.1.2/src/util/match_list.c Mon Jan 28 12:40:04 2002
2454 list = match_list_parse(list, vstring_str(buf));
2455 if (vstream_fclose(fp))
2456 msg_fatal("%s: read file %s: %m", myname, pattern);
2457 - } else if (strchr(pattern, ':') != 0) { /* type:table */
2458 + } else if ((strchr(pattern, ']') == 0) && (strchr(pattern, ':') != 0)) { /* type:table */
2459 for (cp = pattern; *cp == '!'; cp++)
2461 if (dict_handle(pattern) == 0)
2462 diff -Nur postfix-1.1.2.orig/src/util/match_ops.c postfix-1.1.2/src/util/match_ops.c
2463 --- postfix-1.1.2.orig/src/util/match_ops.c Tue Nov 20 21:16:10 2001
2464 +++ postfix-1.1.2/src/util/match_ops.c Mon Jan 28 12:40:04 2002
2466 #include <match_ops.h>
2467 #include <stringops.h>
2473 + * This program is free software; you can redistribute it and/or
2474 + * modify it under the terms of the GNU General Public License
2475 + * as published by the Free Software Foundation; either version
2476 + * 2 of the License, or (at your option) any later version.
2478 + * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
2481 + * Artur Frysiak <wiget@pld.org.pl>
2482 + * Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
2486 +#include <stdlib.h>
2487 +#include <unistd.h>
2488 +#include <syslog.h>
2490 +#include <sys/socket.h>
2491 +#include <netinet/in.h>
2492 +#include <string.h>
2494 +#include <arpa/inet.h>
2495 +#include <resolv.h>
2498 +#define AF_DECnet 12
2502 +#define PF_PACKET 17
2507 + unsigned char family;
2508 + unsigned char bytelen;
2509 + signed short bitlen;
2510 + unsigned int data[4];
2514 +int masked_match(char *, char *, char *);
2515 +int get_integer(int *, char *, int);
2516 +int get_addr_1(inet_prefix *, char *, int);
2517 +int get_prefix_1(inet_prefix *, char *, int);
2518 +int get_addr(inet_prefix *, char *, int);
2519 +int get_prefix(inet_prefix *, char *, int);
2520 +unsigned int get_addr32(char *);
2521 +int matches(char *, char *);
2522 +int inet_addr_match(inet_prefix *, inet_prefix *, int);
2523 +int mask_match(char *, char *, char *);
2525 +int get_integer(int *val, char *arg, int base)
2530 + if (!arg || !*arg)
2532 + res = strtol(arg, &ptr, base);
2533 + if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN)
2539 +int get_addr_1(inet_prefix *addr, char *name, int family)
2542 + unsigned char *ap = (unsigned char*)addr->data;
2545 + memset(addr, 0, sizeof(*addr));
2547 + if (strcmp(name, "default") == 0 || strcmp(name, "any") == 0) {
2548 + if (family == AF_DECnet)
2550 + addr->family = family;
2551 + addr->bytelen = (family == AF_INET6 ? 16 : 4);
2552 + addr->bitlen = -1;
2556 + if (strchr(name, ':')) {
2557 + addr->family = AF_INET6;
2558 + if (family != AF_UNSPEC && family != AF_INET6)
2560 + if (inet_pton(AF_INET6, name, addr->data) <= 0)
2562 + addr->bytelen = 16;
2563 + addr->bitlen = -1;
2566 + addr->family = AF_INET;
2567 + if (family != AF_UNSPEC && family != AF_INET)
2569 + addr->bytelen = 4;
2570 + addr->bitlen = -1;
2571 + for (cp = name, i = 0; *cp; cp++) {
2572 + if (*cp <= '9' && *cp >= '0') {
2573 + ap[i] = 10*ap[i] + (*cp-'0');
2576 + if (*cp == '.' && ++i <= 3)
2583 +int get_prefix_1(inet_prefix *dst, char *arg, int family)
2589 + memset(dst, 0, sizeof(*dst));
2591 + if (strcmp(arg, "default") == 0 || strcmp(arg, "any") == 0) {
2592 + if (family == AF_DECnet)
2594 + dst->family = family;
2600 + slash = strchr(arg, '/');
2603 + err = get_addr_1(dst, arg, family);
2605 + switch(dst->family) {
2607 + dst->bitlen = 128;
2617 + if (get_integer(&plen, slash+1, 0) || plen > dst->bitlen) {
2621 + dst->bitlen = plen;
2630 +int get_addr(inet_prefix *dst, char *arg, int family)
2633 + if (family == AF_PACKET)
2636 + if (get_addr_1(dst, arg, family))
2641 +int get_prefix(inet_prefix *dst, char *arg, int family)
2644 + if (family == AF_PACKET)
2647 + if (get_prefix_1(dst, arg, family))
2652 +unsigned int get_addr32(char *name)
2655 + if (get_addr_1(&addr, name, AF_INET))
2657 + return addr.data[0];
2660 +int matches(char *cmd, char *pattern)
2662 + int len = strlen(cmd);
2663 + if (len > strlen(pattern))
2665 + return memcmp(pattern, cmd, len);
2668 +int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits)
2670 + unsigned int *a1 = a->data;
2671 + unsigned int *a2 = b->data;
2672 + int words = bits >> 0x05;
2677 + if (memcmp(a1, a2, words << 2))
2681 + unsigned int w1, w2;
2682 + unsigned int mask;
2687 + mask = htonl((0xffffffff) << (0x20 - bits));
2689 + if ((w1 ^ w2) & mask)
2696 +/* zero if matches */
2697 +int mask_match(char *network, char *cprefix, char *address)
2699 + inet_prefix *inetwork;
2700 + inet_prefix *iaddress;
2703 + if (!(network && address && cprefix))
2705 + prefix = strtol(cprefix, (char **)NULL, 10);
2706 + if ((prefix < 0) || (prefix > 128))
2708 + if ((strlen(network) == 0) || (strlen(address) == 0))
2711 + inetwork = malloc(sizeof(inet_prefix));
2712 + iaddress = malloc(sizeof(inet_prefix));
2714 + if ((get_addr(iaddress, address, AF_UNSPEC) >= 0)
2715 + && (get_addr(inetwork, network, AF_UNSPEC) >= 0))
2716 + ret = inet_addr_match(inetwork, iaddress, prefix);
2722 + /* 1 if matches */
2723 + /* return (!ret); */
2724 + /* 0 if matches */
2729 + * masked_match() - universal for IPv4 and IPv6 - 1 if matches
2731 +int masked_match(net_tok, mask_tok, string)
2737 + struct in6_addr in6[2];
2738 + char v4addr[2][INET_ADDRSTRLEN];
2743 + /* Check for NULL */
2744 + if (!(net_tok && mask_tok && string))
2745 + return 0; /* doesn't match!!! */
2747 + /* If IPv6 mapped convert to native-IPv4 */
2749 + if (inet_pton(AF_INET6, net_tok, &in6[0]) == 1 &&
2750 + inet_pton(AF_INET6, string, &in6[1]) == 1 &&
2751 + IN6_IS_ADDR_V4MAPPED(&in6[0]) && IN6_IS_ADDR_V4MAPPED(&in6[1])) {
2752 + plen = atoi(mask_tok);
2753 + if (32 < plen && plen < 129) {
2754 + sprintf(newmask, "%d", plen - 96);
2755 + mask_tok = newmask;
2758 + (void)inet_ntop(AF_INET, &in6[0].s6_addr[12], v4addr[0],
2759 + sizeof(v4addr[0]));
2760 + net_tok = v4addr[0];
2761 + (void)inet_ntop(AF_INET, &in6[1].s6_addr[12], v4addr[1],
2762 + sizeof(v4addr[1]));
2763 + string = v4addr[1];
2766 + return (!mask_match(net_tok, mask_tok, string));
2770 /* match_string - match a string literal */
2772 int match_string(int unused_flags, const char *string, const char *pattern)
2778 /* match_parse_mask - parse net/mask pattern */
2780 static int match_parse_mask(const char *pattern, unsigned long *net_bits,
2781 @@ -198,27 +500,55 @@
2787 /* match_hostaddr - match host by address */
2789 int match_hostaddr(int unused_flags, const char *addr, const char *pattern)
2791 char *myname = "match_hostaddr";
2793 + char *network, *mask, *escl, *escr, *patternx;
2794 + struct in6_addr in6;
2795 + char v4addr[INET_ADDRSTRLEN];
2798 unsigned long mask_bits;
2799 unsigned long net_bits;
2800 unsigned long addr_bits;
2804 msg_info("%s: %s ~? %s", myname, addr, pattern);
2807 + if (addr[strspn(addr, "01234567890./:abcdef")] != 0)
2809 if (addr[strspn(addr, "01234567890./:")] != 0)
2814 + patternx = mystrdup(pattern);
2815 + escl = strchr(patternx,'[');
2816 + escr = strrchr(patternx,']');
2817 + if (escl && escr) {
2819 + sprintf(patternx, "%s%s", escl + 1, escr + 1);
2820 + pattern = patternx;
2825 * Try dictionary lookup. This can be case insensitive. XXX Probably
2826 * should also try again after stripping least significant octets.
2828 - if (strchr(pattern, ':') != 0) {
2830 + if (!(escl && escr) && strchr(pattern, ':') != 0)
2832 + if (strchr(pattern, ':') != 0)
2835 if (dict_lookup(pattern, addr) != 0)
2837 if (dict_errno != 0)
2838 @@ -229,6 +559,12 @@
2840 * Try an exact match with the host address.
2843 + if (inet_pton(AF_INET6, addr, &in6) == 1 && IN6_IS_ADDR_V4MAPPED(&in6)) {
2844 + (void)inet_ntop(AF_INET, &in6.s6_addr[12], v4addr, sizeof(v4addr));
2848 if (strcasecmp(addr, pattern) == 0) {
2851 @@ -237,6 +573,20 @@
2852 * In a net/mask pattern, the mask is specified as the number of bits of
2856 + network = mystrdup(patternx);
2857 + mask = split_at(network, '/');
2859 + if (masked_match(network, mask, (char *)addr)) {
2869 if (match_parse_mask(pattern, &net_bits, &mask_shift)) {
2870 addr_bits = inet_addr(addr);
2871 if (addr_bits == INADDR_NONE)
2873 mask_bits = htonl((0xffffffff) << (BITS_PER_ADDR - mask_shift));
2874 return ((addr_bits & mask_bits) == (net_bits & mask_bits));
2879 diff -Nur postfix-1.1.2.orig/src/util/sys_defs.h postfix-1.1.2/src/util/sys_defs.h
2880 --- postfix-1.1.2.orig/src/util/sys_defs.h Mon Jan 28 12:38:34 2002
2881 +++ postfix-1.1.2/src/util/sys_defs.h Mon Jan 28 12:40:04 2002
2883 #define DEF_MAILBOX_LOCK "flock, dotlock"
2886 +#if ((defined(__NetBSD_Version__) && __NetBSD_Version__ >= 105000000) || defined(USAGI_LIBINET6))
2887 +#define HAVE_GETIFADDRS
2893 diff -Nur postfix-1.1.2.orig/src/util/valid_hostname.c postfix-1.1.2/src/util/valid_hostname.c
2894 --- postfix-1.1.2.orig/src/util/valid_hostname.c Sun Jan 28 15:10:18 2001
2895 +++ postfix-1.1.2/src/util/valid_hostname.c Mon Jan 28 12:40:04 2002
2901 +#include <netinet/in.h>
2902 +#include <sys/socket.h>
2903 +#include <arpa/inet.h>
2907 /* Utility library. */
2910 @@ -103,7 +110,23 @@
2911 msg_warn("%s: misplaced hyphen: %.100s", myname, name);
2917 + else if (ch == ':') {
2918 + struct addrinfo hints, *res;
2920 + memset(&hints, 0, sizeof(hints));
2921 + hints.ai_family = AF_INET6;
2922 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
2923 + hints.ai_flags = AI_NUMERICHOST;
2924 + if (getaddrinfo(name, "0", &hints, &res) == 0) {
2925 + freeaddrinfo(res);
2933 msg_warn("%s: invalid character %d(decimal): %.100s",
2940 + struct addrinfo hints, *res;
2943 #define BYTES_NEEDED 4
2945 @@ -147,6 +173,17 @@
2950 + memset(&hints, 0, sizeof(hints));
2951 + hints.ai_family = AF_INET6;
2952 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
2953 + hints.ai_flags = AI_NUMERICHOST;
2954 + if (getaddrinfo(addr, "0", &hints, &res) == 0) {
2955 + freeaddrinfo(res);
2961 * Scary code to avoid sscanf() overflow nasties.