1 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/IPV6_README snapshot-20010525/IPV6_README
2 --- snapshot-20010525.noipv6/IPV6_README Thu Jan 1 01:00:00 1970
3 +++ snapshot-20010525/IPV6_README Tue May 29 18:23:16 2001
7 + ALPHA IPv6 patch for Postfix.
9 + You can use IPv6 addresses in configuration file but
10 +you must enclose them with [] for example: [3ffe:902:12::10].
12 +Probably not all things work properly, yet.
15 + - all previous versions of this patch (dated before 15 January
16 + 2000) was against postfix-19991231-pl02 with pfixtls patch
17 + applied (see ftp://ftp.aet.tu-cottbus.de/pub/pfixtls/ for more).
18 + All newer patches are created against clean postfix version.
21 + - getaddrinfo call in smtp_addr_one() function doesn't always
22 + return proper ai_addr structure (fixed).
23 + - lmtp code isn't IPv6 ready (not fixed).
25 +Please send all comments and patches to:
26 + Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>, PLD GNU/Linux
27 + Artur Frysiak <wiget@pld.org.pl>, PLD GNU/Linux
29 +Newest version of this patch can be found at:
30 + http://www.misiek.eu.org/ipv6/
33 +- Mark Huizer <xaa@timewasters.nl>
34 + author of first IPv6 patch for postfix
35 +- KAME Team <core@kame.net>
36 + fixes to Mark's patch
37 +diff -ruN --exclude *.orig --exclude *~ snapshot-20010329.noipv6/makedefs snapshot-20010329/makedefs
38 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/makedefs snapshot-20010525/makedefs
39 --- snapshot-20010525.noipv6/makedefs Tue May 1 01:16:07 2001
40 +++ snapshot-20010525/makedefs Tue May 29 18:23:16 2001
42 SYSTEM=`(uname -s) 2>/dev/null`
43 RELEASE=`(uname -r) 2>/dev/null`
44 VERSION=`(uname -v) 2>/dev/null`
45 +if test -f /usr/include/netinet6/in6.h; then
46 + grep __KAME__ /usr/include/netinet6/in6.h 2>&1 >/dev/null
50 + if [ -f /usr/local/v6/lib/libinet6.a ]; then
57 +if [ -z "$INET6" -a -f /usr/include/netinet/ip6.h -a -f /usr/include/linux/icmpv6.h ]; then
62 dcosx*) SYSTEM=$VERSION;;
66 : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk}
70 + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
71 + if test -f /usr/local/v6/lib/libinet6.a; then
72 + SYSLIBS="$SYSLIBS -L/usr/local/v6/lib -linet6"
76 + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
79 + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family"
80 + if test -f /usr/include/libinet6/netinet/ip6.h -a \
81 + -f /usr/lib/libinet6.a; then
82 + CCARGS="$CCARGS -I/usr/include/libinet6 -DUSAGI_LIBINET6"
83 + SYSLIBS="$SYSLIBS -linet6"
88 export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
90 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/dns/dns_lookup.c snapshot-20010525/src/dns/dns_lookup.c
91 --- snapshot-20010525.noipv6/src/dns/dns_lookup.c Sun Feb 4 19:16:20 2001
92 +++ snapshot-20010525/src/dns/dns_lookup.c Tue May 29 18:23:16 2001
96 #define INET_ADDR_LEN 4 /* XXX */
98 +#define INET6_ADDR_LEN 16
101 /* dns_query - query name server and pre-parse the reply */
104 memcpy(temp, pos, fixed->length);
105 data_len = fixed->length;
109 + if (fixed->length != INET6_ADDR_LEN) {
110 + msg_warn("extract_answer: bad IPv6 address length: %d", fixed->length);
113 + if (fixed->length > sizeof(temp))
114 + msg_panic("dns_get_rr: length %d > DNS_NAME_LEN",
116 + memcpy(temp, pos, fixed->length);
117 + data_len = fixed->length;
121 data_len = MIN2(pos[0] + 1, MIN2(fixed->length + 1, sizeof(temp)));
122 for (src = pos + 1, dst = (unsigned char *) (temp);
123 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/global/Makefile.in snapshot-20010525/src/global/Makefile.in
124 --- snapshot-20010525.noipv6/src/global/Makefile.in Tue May 29 16:03:38 2001
125 +++ snapshot-20010525/src/global/Makefile.in Tue May 29 18:23:16 2001
127 timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
128 tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
129 flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
131 + pfixtls.c wildcard_inet_addr.c
132 OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
133 debug_peer.o debug_process.o defer.o deliver_completed.o \
134 deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \
136 timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
137 tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
138 flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
140 + pfixtls.o wildcard_inet_addr.o
141 HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
142 config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
143 deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \
145 recipient_list.h record.h resolve_clnt.h resolve_local.h \
146 rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
147 sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
148 - mbox_conf.h mbox_open.h abounce.h pfixtls.h
149 + mbox_conf.h mbox_open.h abounce.h pfixtls.h wildcard_inet_addr.h
150 TESTSRC = rec2stream.c stream2rec.c recdump.c
151 WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
152 -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
153 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/global/mynetworks.c snapshot-20010525/src/global/mynetworks.c
154 --- snapshot-20010525.noipv6/src/global/mynetworks.c Sun Feb 25 02:46:07 2001
155 +++ snapshot-20010525/src/global/mynetworks.c Tue May 29 18:23:16 2001
158 #include <inet_addr_list.h>
159 #include <name_mask.h>
161 +#include <sys/socket.h>
162 +#include <netinet/in.h>
166 /* Global library. */
169 const char *mynetworks(void)
171 static VSTRING *result;
173 + char hbuf[NI_MAXHOST];
177 char *myname = "mynetworks";
183 + struct sockaddr *sa;
186 mask_style = name_mask("mynetworks mask style", mask_styles,
187 var_mynetworks_style);
189 my_mask_list = own_inet_mask_list();
191 for (i = 0; i < my_addr_list->used; i++) {
193 + sa = (struct sockaddr *)&my_addr_list->addrs[i];
194 + if (sa->sa_family != AF_INET) {
195 + vstring_sprintf_append(result, "XAATODOmynetworks ");
198 + addr = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
199 + mask = ntohl(((struct sockaddr_in *)&my_mask_list->addrs[i])->sin_addr.s_addr);
201 addr = ntohl(my_addr_list->addrs[i].s_addr);
202 mask = ntohl(my_mask_list->addrs[i].s_addr);
205 switch (mask_style) {
208 mask = IN_CLASSD_NET;
209 shift = IN_CLASSD_NSHIFT;
212 + if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
214 + strncpy(hbuf, "???", sizeof(hbuf));
215 + msg_fatal("%s: bad address class: %s", myname, hbuf);
217 msg_fatal("%s: bad address class: %s",
218 myname, inet_ntoa(my_addr_list->addrs[i]));
223 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/global/own_inet_addr.c snapshot-20010525/src/global/own_inet_addr.c
224 --- snapshot-20010525.noipv6/src/global/own_inet_addr.c Sun Feb 25 02:51:39 2001
225 +++ snapshot-20010525/src/global/own_inet_addr.c Tue May 29 18:23:16 2001
227 #include <netinet/in.h>
228 #include <arpa/inet.h>
231 +#include <sys/socket.h>
235 #ifdef STRCASECMP_IN_STRINGS_H
237 @@ -101,10 +105,11 @@
240 bufp = hosts = mystrdup(var_inet_interfaces);
241 - while ((host = mystrtok(&bufp, sep)) != 0)
242 + while ((host = mystrtok(&bufp, sep)) != 0) {
243 if (inet_addr_host(addr_list, host) == 0)
244 msg_fatal("config variable %s: host not found: %s",
245 VAR_INET_INTERFACES, host);
249 inet_addr_list_init(&local_addrs);
250 @@ -113,15 +118,39 @@
251 msg_fatal("could not find any active network interfaces");
252 for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) {
253 for (nlocal = 0; /* see below */ ; nlocal++) {
254 - if (nlocal >= local_addrs.used)
255 + if (nlocal >= local_addrs.used) {
257 + char hbuf[NI_MAXHOST];
258 + if (getnameinfo((struct sockaddr *)&addr_list->addrs[nvirtual],
259 + SS_LEN(addr_list->addrs[nvirtual]), hbuf,
260 + sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
261 + strncpy(hbuf, "???", sizeof(hbuf));
262 + msg_fatal("parameter %s: no local interface found for %s",
263 + VAR_INET_INTERFACES, hbuf);
265 msg_fatal("parameter %s: no local interface found for %s",
267 inet_ntoa(addr_list->addrs[nvirtual]));
271 + if (addr_list->addrs[nvirtual].ss_family ==
272 + local_addrs.addrs[nlocal].ss_family &&
273 + SS_LEN(addr_list->addrs[nvirtual]) ==
274 + SS_LEN(local_addrs.addrs[nlocal]) &&
275 + memcmp(&addr_list->addrs[nvirtual],
276 + &local_addrs.addrs[nlocal],
277 + SS_LEN(local_addrs.addrs[nlocal])) == 0) {
278 + inet_addr_list_append(mask_list, (struct sockaddr *)&local_masks.addrs[nlocal]);
282 if (addr_list->addrs[nvirtual].s_addr
283 == local_addrs.addrs[nlocal].s_addr) {
284 inet_addr_list_append(mask_list, &local_masks.addrs[nlocal]);
290 inet_addr_list_free(&local_addrs);
293 /* own_inet_addr - is this my own internet address */
296 +int own_inet_addr(struct sockaddr * addr)
301 + struct sockaddr *sa;
303 + if (addr_list.used == 0)
304 + own_inet_addr_init(&addr_list, &mask_list);
306 + for (i = 0; i < addr_list.used; i++) {
307 + sa = (struct sockaddr *)&addr_list.addrs[i];
308 + if (addr->sa_family != sa->sa_family)
310 + switch (addr->sa_family) {
312 + p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
313 + q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
314 + l = sizeof(struct in_addr);
318 + p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
319 + q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
320 + l = sizeof(struct in6_addr);
325 + if (memcmp(p, q, l) == 0)
331 int own_inet_addr(struct in_addr * addr)
335 for (i = 0; i < addr_list.used; i++)
336 if (addr->s_addr == addr_list.addrs[i].s_addr)
342 /* own_inet_addr_list - return list of addresses */
344 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/global/own_inet_addr.h snapshot-20010525/src/global/own_inet_addr.h
345 --- snapshot-20010525.noipv6/src/global/own_inet_addr.h Sat Feb 24 02:25:32 2001
346 +++ snapshot-20010525/src/global/own_inet_addr.h Tue May 29 18:23:16 2001
350 #include <netinet/in.h>
352 +#include <sys/socket.h>
356 * External interface.
359 +extern int own_inet_addr(struct sockaddr *);
361 extern int own_inet_addr(struct in_addr *);
363 extern struct INET_ADDR_LIST *own_inet_addr_list(void);
364 extern struct INET_ADDR_LIST *own_inet_mask_list(void);
366 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/global/peer_name.c snapshot-20010525/src/global/peer_name.c
367 --- snapshot-20010525.noipv6/src/global/peer_name.c Sun Jan 28 16:23:02 2001
368 +++ snapshot-20010525/src/global/peer_name.c Tue May 29 18:23:16 2001
370 PEER_NAME *peer_name(int sock)
372 static PEER_NAME peer;
373 - struct sockaddr_in sin;
374 - SOCKADDR_SIZE len = sizeof(sin);
381 + struct sockaddr peer_un;
382 + struct sockaddr_in peer_un4;
384 + struct sockaddr_in6 peer_un6;
387 +#define sun p_un.peer_un
388 +#define sin p_un.peer_un4
390 +#define sin6 p_un.peer_un6
391 + static char hbuf[NI_MAXHOST];
392 + static char abuf[NI_MAXHOST];
396 + SOCKADDR_SIZE len = sizeof(p_un);
398 - if (getpeername(sock, (struct sockaddr *) & sin, &len) == 0) {
399 - switch (sin.sin_family) {
400 + if (getpeername(sock, (struct sockaddr *)&p_un, &len) == 0) {
401 + switch (p_un.peer_un.sa_family) {
404 peer.type = PEER_TYPE_INET;
405 hp = gethostbyaddr((char *) &(sin.sin_addr),
407 hp->h_name : "unknown");
408 peer.addr = inet_ntoa(sin.sin_addr);
412 + peer.type = PEER_TYPE_INET;
413 + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
414 + peer.name = "unknown";
420 + peer.type = PEER_TYPE_INET6;
421 + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
422 + peer.name = "unknown";
430 peer.type = PEER_TYPE_LOCAL;
431 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/global/peer_name.h snapshot-20010525/src/global/peer_name.h
432 --- snapshot-20010525.noipv6/src/global/peer_name.h Fri Dec 11 19:55:32 1998
433 +++ snapshot-20010525/src/global/peer_name.h Tue May 29 18:23:16 2001
435 #define PEER_TYPE_UNKNOWN 0
436 #define PEER_TYPE_INET 1
437 #define PEER_TYPE_LOCAL 2
439 +#define PEER_TYPE_INET6 3
442 extern PEER_NAME *peer_name(int);
444 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/global/resolve_local.c snapshot-20010525/src/global/resolve_local.c
445 --- snapshot-20010525.noipv6/src/global/resolve_local.c Mon Apr 26 00:05:42 1999
446 +++ snapshot-20010525/src/global/resolve_local.c Tue May 29 18:23:16 2001
448 #include <netinet/in.h>
449 #include <arpa/inet.h>
454 #define INADDR_NONE 0xffffffff
457 char *saved_addr = mystrdup(addr);
460 + struct addrinfo hints, *res, *res0;
463 struct in_addr ipaddr;
467 #define RETURN(x) { myfree(saved_addr); return(x); }
469 if (*dest == '[' && dest[len - 1] == ']') {
473 + memset(&hints, 0, sizeof(hints));
474 + hints.ai_family = PF_UNSPEC;
475 + hints.ai_socktype = SOCK_DGRAM;
476 + error = getaddrinfo(dest, NULL, &hints, &res0);
478 + for (res = res0; res; res = res->ai_next) {
479 + if (own_inet_addr(res->ai_addr)) {
480 + freeaddrinfo(res0);
484 + freeaddrinfo(res0);
487 if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE
488 && own_inet_addr(&ipaddr))
494 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/global/wildcard_inet_addr.c snapshot-20010525/src/global/wildcard_inet_addr.c
495 --- snapshot-20010525.noipv6/src/global/wildcard_inet_addr.c Thu Jan 1 01:00:00 1970
496 +++ snapshot-20010525/src/global/wildcard_inet_addr.c Tue May 29 18:23:16 2001
498 +/* System library. */
500 +#include <sys_defs.h>
501 +#include <netinet/in.h>
502 +#include <arpa/inet.h>
505 +#include <sys/socket.h>
509 +#ifdef STRCASECMP_IN_STRINGS_H
510 +#include <strings.h>
513 +/* Utility library. */
516 +#include <mymalloc.h>
517 +#include <inet_addr_list.h>
518 +#include <inet_addr_local.h>
519 +#include <inet_addr_host.h>
520 +#include <stringops.h>
522 +/* Global library. */
524 +#include <mail_params.h>
525 +#include <wildcard_inet_addr.h>
527 +/* Application-specific. */
528 +static INET_ADDR_LIST addr_list;
530 +/* wildcard_inet_addr_init - initialize my own address list */
532 +static void wildcard_inet_addr_init(INET_ADDR_LIST *addr_list)
535 + struct addrinfo hints, *res, *res0;
536 + char hbuf[NI_MAXHOST];
538 +#ifdef NI_WITHSCOPEID
539 + const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
541 + const int niflags = NI_NUMERICHOST;
544 + inet_addr_list_init(addr_list);
546 + memset(&hints, 0, sizeof(hints));
547 + hints.ai_family = PF_UNSPEC;
548 + hints.ai_socktype = SOCK_STREAM;
549 + hints.ai_flags = AI_PASSIVE;
550 + error = getaddrinfo(NULL, "0", &hints, &res0);
552 + msg_fatal("could not get list of wildcard addresses");
553 + for (res = res0; res; res = res->ai_next) {
554 + if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
556 + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
557 + NULL, 0, niflags) != 0)
559 + if (inet_addr_host(addr_list, hbuf) == 0)
560 + continue; /* msg_fatal("config variable %s: host not found: %s",
561 + VAR_INET_INTERFACES, hbuf); */
563 + freeaddrinfo(res0);
565 + if (inet_addr_host(addr_list, "0.0.0.0") == 0)
566 + msg_fatal("config variable %s: host not found: %s",
567 + VAR_INET_INTERFACES, "0.0.0.0");
571 +/* wildcard_inet_addr_list - return list of addresses */
573 +INET_ADDR_LIST *wildcard_inet_addr_list(void)
575 + if (addr_list.used == 0)
576 + wildcard_inet_addr_init(&addr_list);
578 + return (&addr_list);
580 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/global/wildcard_inet_addr.h snapshot-20010525/src/global/wildcard_inet_addr.h
581 --- snapshot-20010525.noipv6/src/global/wildcard_inet_addr.h Thu Jan 1 01:00:00 1970
582 +++ snapshot-20010525/src/global/wildcard_inet_addr.h Tue May 29 18:23:16 2001
584 +#ifndef _WILDCARD_INET_ADDR_H_INCLUDED_
585 +#define _WILDCARD_INET_ADDR_H_INCLUDED_
589 +/* wildcard_inet_addr_list 3h
591 +/* grab the list of wildcard IP addresses.
593 +/* #include <own_inet_addr.h>
601 +#include <netinet/in.h>
603 +#include <sys/socket.h>
607 + * External interface.
609 +extern struct INET_ADDR_LIST *wildcard_inet_addr_list(void);
616 +/* Jun-ichiro itojun Hagino
620 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/master/master_ent.c snapshot-20010525/src/master/master_ent.c
621 --- snapshot-20010525.noipv6/src/master/master_ent.c Tue May 1 00:45:54 2001
622 +++ snapshot-20010525/src/master/master_ent.c Tue May 29 18:30:51 2001
624 inet_addr_host(MASTER_INET_ADDRLIST(serv), host);
625 serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
626 } else if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) {
628 + MASTER_INET_ADDRLIST(serv) = wildcard_inet_addr_list();
629 + serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
631 MASTER_INET_ADDRLIST(serv) = 0; /* wild-card */
632 serv->listen_fd_count = 1;
635 MASTER_INET_ADDRLIST(serv) = own_inet_addr_list(); /* virtual */
636 serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
637 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/master/master_listen.c snapshot-20010525/src/master/master_listen.c
638 --- snapshot-20010525.noipv6/src/master/master_listen.c Tue May 1 00:47:57 2001
639 +++ snapshot-20010525/src/master/master_listen.c Tue May 29 18:24:18 2001
649 /* master_listen_init - enable connection requests */
651 void master_listen_init(MASTER_SERV *serv)
653 char *myname = "master_listen_init";
657 + char hbuf[NI_MAXHOST];
658 + SOCKADDR_SIZE salen;
662 * Find out what transport we should use, then create one or more
664 close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
665 } else { /* virtual or host:port */
666 for (n = 0; n < serv->listen_fd_count; n++) {
668 + if (getnameinfo((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n],
669 + SA_LEN((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n]),
670 + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) {
671 + strncpy(hbuf, "?????", sizeof(hbuf));
673 + end_point = concatenate(hbuf, ":", MASTER_INET_PORT(serv), (char *) 0);
675 end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]),
676 ":", 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 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/qmgr/qmgr_message.c snapshot-20010525/src/qmgr/qmgr_message.c
682 --- snapshot-20010525.noipv6/src/qmgr/qmgr_message.c Tue Feb 27 00:49:31 2001
683 +++ snapshot-20010525/src/qmgr/qmgr_message.c Tue May 29 18:23:16 2001
685 * every front-ent program.
687 if ((at = strrchr(recipient->address, '@')) != 0
689 + && (at + 1)[strspn(at + 1, "[]0123456789.:abcdef")] != 0
691 && (at + 1)[strspn(at + 1, "[]0123456789.")] != 0
693 && valid_hostname(at + 1, DONT_GRIPE) == 0) {
694 qmgr_bounce_recipient(message, recipient,
695 "bad host/domain syntax: \"%s\"", at + 1);
696 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/smtp/Makefile.in snapshot-20010525/src/smtp/Makefile.in
697 --- snapshot-20010525.noipv6/src/smtp/Makefile.in Tue May 29 16:03:38 2001
698 +++ snapshot-20010525/src/smtp/Makefile.in Tue May 29 18:23:16 2001
700 smtp_connect.o: ../../include/mail_params.h
701 smtp_connect.o: ../../include/own_inet_addr.h
702 smtp_connect.o: ../../include/dns.h
703 +smtp_connect.o: ../../include/get_port.h
704 smtp_connect.o: smtp.h
705 smtp_connect.o: ../../include/argv.h
706 smtp_connect.o: ../../include/deliver_request.h
707 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/smtp/smtp_addr.c snapshot-20010525/src/smtp/smtp_addr.c
708 --- snapshot-20010525.noipv6/src/smtp/smtp_addr.c Sat May 5 14:55:36 2001
709 +++ snapshot-20010525/src/smtp/smtp_addr.c Tue May 29 18:23:16 2001
710 @@ -112,18 +112,68 @@
711 static void smtp_print_addr(char *what, DNS_RR *addr_list)
714 - struct in_addr in_addr;
716 + struct sockaddr_storage ss;
718 + struct sockaddr ss;
720 + struct sockaddr_in *sin;
722 + struct sockaddr_in6 *sin6;
723 + char hbuf[NI_MAXHOST];
725 + char hbuf[sizeof("255.255.255.255") + 1];
728 msg_info("begin %s address list", what);
729 for (addr = addr_list; addr; addr = addr->next) {
730 - if (addr->data_len > sizeof(addr)) {
731 - msg_warn("skipping address length %d", addr->data_len);
733 - memcpy((char *) &in_addr, addr->data, sizeof(in_addr));
734 - msg_info("pref %4d host %s/%s",
735 - addr->pref, addr->name,
736 - inet_ntoa(in_addr));
737 + if (addr->class != C_IN) {
738 + msg_warn("skipping unsupported address (class=%u)", addr->class);
741 + switch (addr->type) {
743 + if (addr->data_len != sizeof(sin->sin_addr)) {
744 + msg_warn("skipping invalid address (AAAA, len=%u)",
748 + sin = (struct sockaddr_in *)&ss;
749 + memset(sin, 0, sizeof(*sin));
750 + sin->sin_family = AF_INET;
752 + sin->sin_len = sizeof(*sin);
754 + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
758 + if (addr->data_len != sizeof(sin6->sin6_addr)) {
759 + msg_warn("skipping invalid address (AAAA, len=%u)",
763 + sin6 = (struct sockaddr_in6 *)&ss;
764 + memset(sin6, 0, sizeof(*sin6));
765 + sin6->sin6_family = AF_INET6;
767 + sin6->sin6_len = sizeof(*sin6);
769 + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
773 + msg_warn("skipping unsupported address (type=%u)", addr->type);
778 + (void)getnameinfo((struct sockaddr *)&ss, SS_LEN(ss),
779 + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
781 + (void)inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
783 + msg_info("pref %4d host %s/%s", addr->pref, addr->name, hbuf);
785 msg_info("end %s address list", what);
787 @@ -133,15 +183,23 @@
788 static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
790 char *myname = "smtp_addr_one";
792 struct in_addr inaddr;
798 + struct addrinfo hints, *res0, *res;
806 msg_info("%s: host %s", myname, host);
810 * Interpret a numerical name as an address.
813 smtp_errno = SMTP_FAIL;
817 + memset(&hints, 0, sizeof(hints));
818 + hints.ai_family = PF_UNSPEC;
819 + hints.ai_socktype = SOCK_STREAM;
820 + error = getaddrinfo(host, NULL, &hints, &res0);
824 + smtp_errno = SMTP_RETRY;
827 + vstring_sprintf(why, "[%s]: %s",host,gai_strerror(error));
828 + smtp_errno = SMTP_FAIL;
831 + return (addr_list);
833 + for (res = res0; res; res = res->ai_next) {
834 + memset((char *) &fixed, 0, sizeof(fixed));
835 + switch(res->ai_family) {
837 + /* XXX not scope friendly */
838 + fixed.type = T_AAAA;
839 + addr = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
840 + addrlen = sizeof(struct in6_addr);
844 + addr = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr;
845 + addrlen = sizeof(struct in_addr);
848 + msg_warn("%s: unknown address family %d for %s",
849 + myname, res->ai_family, host);
852 + addr_list = dns_rr_append(addr_list,
853 + dns_rr_create(host, &fixed, pref, addr, addrlen));
856 + freeaddrinfo(res0);
862 INET_ADDR_LIST *self;
866 + struct sockaddr *sa;
870 * Find the first address that lists any address that this mail system is
871 @@ -238,12 +341,36 @@
873 self = own_inet_addr_list();
874 for (addr = addr_list; addr; addr = addr->next) {
875 - for (i = 0; i < self->used; i++)
876 + for (i = 0; i < self->used; i++) {
878 + sa = (struct sockaddr *)&self->addrs[i];
879 + switch(addr->type) {
882 + if (sa->sa_family != AF_INET6)
884 + if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
885 + addr->data, sizeof(struct in6_addr)) == 0) {
890 + if (sa->sa_family != AF_INET)
892 + if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
893 + addr->data, sizeof(struct in_addr)) == 0) {
899 if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
901 msg_info("%s: found at pref %d", myname, addr->pref);
909 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/smtp/smtp_connect.c snapshot-20010525/src/smtp/smtp_connect.c
910 --- snapshot-20010525.noipv6/src/smtp/smtp_connect.c Tue May 29 16:03:38 2001
911 +++ snapshot-20010525/src/smtp/smtp_connect.c Tue May 29 18:23:16 2001
913 /* System library. */
915 #include <sys_defs.h>
917 #include <sys/socket.h>
918 #include <netinet/in.h>
919 #include <arpa/inet.h>
921 #include <inet_addr_list.h>
923 #include <timed_connect.h>
924 +#include <get_port.h>
925 #include <stringops.h>
927 /* Global library. */
928 @@ -133,19 +135,45 @@
931 char *myname = "smtp_connect_addr";
932 - struct sockaddr_in sin;
935 + struct sockaddr_storage ss;
937 + struct sockaddr ss;
939 + struct sockaddr *sa;
940 + struct sockaddr_in *sin;
942 + struct sockaddr_in6 *sin6;
944 + SOCKADDR_SIZE salen;
946 + char hbuf[NI_MAXHOST];
948 + char hbuf[sizeof("255.255.255.255") + 1];
951 INET_ADDR_LIST *addr_list;
956 - unsigned long inaddr;
958 + sa = (struct sockaddr *)&ss;
959 + sin = (struct sockaddr_in *)&ss;
961 + sin6 = (struct sockaddr_in6 *)&ss;
967 - if (addr->data_len > sizeof(sin.sin_addr)) {
969 + if (((addr->type==T_A) && (addr->data_len > sizeof(sin->sin_addr))) ||
970 + ((addr->type==T_AAAA) && (addr->data_len > sizeof(sin6->sin6_addr))))
972 + if (addr->data_len > sizeof(sin->sin_addr))
975 msg_warn("%s: skip address with length %d", myname, addr->data_len);
976 smtp_errno = SMTP_RETRY;
978 @@ -154,17 +182,39 @@
982 - memset((char *) &sin, 0, sizeof(sin));
983 - sin.sin_family = AF_INET;
985 - if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
986 - msg_fatal("%s: socket: %m", myname);
988 + switch (addr->type) {
991 + memset(sin6, 0, sizeof(*sin6));
992 + sin6->sin6_family = AF_INET6;
993 + salen = sizeof(*sin6);
996 + default: /* T_A: */
997 + memset(sin, 0, sizeof(*sin));
998 + sin->sin_family = AF_INET;
999 + salen = sizeof(*sin);
1003 + sa->sa_len = salen;
1005 + if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
1006 + msg_warn("%s: socket: %m", myname);
1009 * Allow the sysadmin to specify the source address, for example, as "-o
1010 * smtp_bind_address=x.x.x.x" in the master.cf file.
1012 if (*var_smtp_bind_addr) {
1014 + struct sockaddr_in sin;
1016 + memset(&sin, 0, sizeof(sin));
1017 + sin.sin_family = AF_INET;
1019 + sin.sin_len = sizeof(sin);
1021 sin.sin_addr.s_addr = inet_addr(var_smtp_bind_addr);
1022 if (sin.sin_addr.s_addr == INADDR_NONE)
1023 msg_fatal("%s: bad %s parameter: %s",
1024 @@ -173,6 +223,25 @@
1025 msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr));
1027 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1029 + char hbufl[NI_MAXHOST];
1030 + struct addrinfo hints, *res;
1032 + memset(&hints, 0, sizeof(hints));
1033 + hints.ai_family = sa->sa_family;
1034 + hints.ai_socktype = SOCK_STREAM;
1035 + hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1036 + snprintf(hbufl, sizeof(hbufl)-1, "%s", var_smtp_bind_addr);
1037 + if (getaddrinfo(hbufl, NULL, &hints, &res) == 0) {
1038 + (void)getnameinfo(res->ai_addr, res->ai_addrlen, hbufl,
1039 + sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1040 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1041 + msg_warn("%s: bind %s: %m", myname, hbufl);
1042 + freeaddrinfo(res);
1044 + msg_info("%s: bind %s", myname, hbufl);
1050 @@ -180,8 +249,17 @@
1051 * the mail appears to come from the "right" machine address.
1053 else if ((addr_list = own_inet_addr_list())->used == 1) {
1055 + struct sockaddr_in sin;
1056 + unsigned long inaddr; /*XXX BAD!*/
1058 + memset(&sin, 0, sizeof(sin));
1059 + sin.sin_family = AF_INET;
1061 + sin.sin_len = sizeof(sin);
1063 memcpy((char *) &sin.sin_addr, addr_list->addrs, sizeof(sin.sin_addr));
1064 - inaddr = ntohl(sin.sin_addr.s_addr);
1065 + inaddr = (unsigned long)ntohl(sin.sin_addr.s_addr);
1066 if (!IN_CLASSA(inaddr)
1067 || !(((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)) {
1068 if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
1069 @@ -189,30 +267,85 @@
1071 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1074 + char hbufl[NI_MAXHOST];
1075 + struct addrinfo hints, *res = NULL, *loopback = NULL;
1077 + memset(&hints, 0, sizeof(hints));
1078 + hints.ai_family = sa->sa_family;
1079 + hints.ai_socktype = SOCK_STREAM;
1080 + if (getaddrinfo(NULL, "0", &hints, &loopback) != 0)
1084 + * getnameinfo -> getaddrinfo loop is here so that we can
1085 + * get rid of port.
1087 + (void)getnameinfo((struct sockaddr *)addr_list->addrs, SA_LEN((struct sockaddr *)addr_list->addrs),
1088 + hbufl, sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1089 + hbufl[sizeof(hbufl)-1] = 0;
1090 + memset(&hints, 0, sizeof(hints));
1091 + hints.ai_family = sa->sa_family;
1092 + hints.ai_socktype = SOCK_STREAM;
1093 + hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1094 + if (getaddrinfo(hbufl, NULL, &hints, &res) == 0 &&
1095 + !(res->ai_addrlen == loopback->ai_addrlen &&
1096 + memcmp(res->ai_addr, loopback->ai_addr, res->ai_addrlen) == 0)) {
1097 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1098 + msg_warn("%s: bind %s: %m", myname, hbufl);
1100 + msg_info("%s: bind %s", myname, hbufl);
1103 + freeaddrinfo(res);
1105 + freeaddrinfo(loopback);
1110 * Connect to the SMTP server.
1112 - sin.sin_port = port;
1113 - memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr));
1114 + switch (addr->type) {
1117 + /* XXX scope unfriendly */
1118 + memset(sin6, 0, sizeof(*sin6));
1119 + sin6->sin6_port = port;
1120 + sin6->sin6_family = AF_INET6;
1121 + salen = sizeof(*sin6);
1122 + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
1123 + inet_ntop(AF_INET6, &sin6->sin6_addr, hbuf, sizeof(hbuf));
1126 + default: /* T_A */
1127 + memset(sin, 0, sizeof(*sin));
1128 + sin->sin_port = port;
1129 + sin->sin_family = AF_INET;
1130 + salen = sizeof(*sin);
1131 + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
1132 + inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
1136 + sa->sa_len = salen;
1140 msg_info("%s: trying: %s[%s] port %d...",
1141 - myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port));
1142 + myname, addr->name, hbuf, ntohs(port));
1143 if (var_smtp_conn_tmout > 0) {
1144 non_blocking(sock, NON_BLOCKING);
1145 - conn_stat = timed_connect(sock, (struct sockaddr *) & sin,
1146 - sizeof(sin), var_smtp_conn_tmout);
1147 + conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout);
1148 saved_errno = errno;
1149 non_blocking(sock, BLOCKING);
1150 errno = saved_errno;
1152 - conn_stat = connect(sock, (struct sockaddr *) & sin, sizeof(sin));
1153 + conn_stat = connect(sock, sa, salen);
1155 if (conn_stat < 0) {
1156 vstring_sprintf(why, "connect to %s[%s]: %m",
1157 - addr->name, inet_ntoa(sin.sin_addr));
1158 + addr->name, hbuf);
1159 smtp_errno = SMTP_RETRY;
1163 * Skip this host if it takes no action within some time limit.
1165 if (read_wait(sock, var_smtp_helo_tmout) < 0) {
1166 - vstring_sprintf(why, "connect to %s[%s]: read timeout",
1167 - addr->name, inet_ntoa(sin.sin_addr));
1168 + vstring_sprintf(why, "connect to %s [%s]: read timeout",
1169 + addr->name, hbuf);
1170 smtp_errno = SMTP_RETRY;
1175 stream = vstream_fdopen(sock, O_RDWR);
1176 if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
1177 - vstring_sprintf(why, "connect to %s[%s]: server dropped connection",
1178 - addr->name, inet_ntoa(sin.sin_addr));
1179 + vstring_sprintf(why, "connect to %s [%s]: server dropped connection",
1180 + addr->name, hbuf);
1181 smtp_errno = SMTP_RETRY;
1182 vstream_fclose(stream);
1186 if (ch == '4' && var_smtp_skip_4xx_greeting) {
1187 vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1188 - addr->name, inet_ntoa(sin.sin_addr));
1189 + addr->name, hbuf);
1190 smtp_errno = SMTP_RETRY;
1191 vstream_fclose(stream);
1193 @@ -258,12 +391,12 @@
1195 if (ch == '5' && var_smtp_skip_5xx_greeting) {
1196 vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1197 - addr->name, inet_ntoa(sin.sin_addr));
1198 + addr->name, hbuf);
1199 smtp_errno = SMTP_RETRY;
1200 vstream_fclose(stream);
1203 - return (smtp_session_alloc(dest, stream, addr->name, inet_ntoa(sin.sin_addr)));
1204 + return (smtp_session_alloc(dest, stream, addr->name, hbuf));
1207 /* smtp_connect_host - direct connection to host */
1209 SMTP_SESSION *session = 0;
1215 * Try each address in the specified order until we find one that works.
1216 * The addresses belong to the same A record, so we have no information
1218 msg_fatal("unknown service: %s/%s", service, protocol);
1219 *portp = sp->s_port;
1225 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/smtp/smtp_unalias.c snapshot-20010525/src/smtp/smtp_unalias.c
1226 --- snapshot-20010525.noipv6/src/smtp/smtp_unalias.c Thu Sep 28 19:06:09 2000
1227 +++ snapshot-20010525/src/smtp/smtp_unalias.c Tue May 29 18:23:16 2001
1229 if ((result = htable_find(cache, name)) == 0) {
1230 fqdn = vstring_alloc(10);
1231 if (dns_lookup_types(name, smtp_unalias_flags, (DNS_RR **) 0,
1232 - fqdn, (VSTRING *) 0, T_MX, T_A, 0) != DNS_OK)
1233 + fqdn, (VSTRING *) 0, T_MX, T_A,
1238 vstring_strcpy(fqdn, name);
1239 htable_enter(cache, name, result = vstring_export(fqdn));
1241 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/smtpd/smtpd_check.c snapshot-20010525/src/smtpd/smtpd_check.c
1242 --- snapshot-20010525.noipv6/src/smtpd/smtpd_check.c Tue May 29 16:03:38 2001
1243 +++ snapshot-20010525/src/smtpd/smtpd_check.c Tue May 29 18:23:16 2001
1244 @@ -812,7 +812,11 @@
1245 msg_info("%s: %s", myname, name);
1247 dns_status = dns_lookup_types(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
1248 - (VSTRING *) 0, T_A, T_MX, 0);
1249 + (VSTRING *) 0, T_A, T_MX,
1254 if (dns_status != DNS_OK)
1255 return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
1256 "%d <%s>: %s odrzucony/rejected: Host not found",
1257 @@ -834,7 +838,11 @@
1258 msg_info("%s: %s", myname, name);
1260 dns_status = dns_lookup_types(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
1261 - (VSTRING *) 0, T_A, T_MX, 0);
1262 + (VSTRING *) 0, T_A, T_MX,
1267 if (dns_status != DNS_OK)
1268 return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
1269 "%d <%s>: %s odrzucony/rejected: Domain not found",
1270 @@ -1003,6 +1011,49 @@
1272 static int has_my_addr(char *host)
1275 + char *myname = "has_my_addr";
1276 + struct addrinfo hints, *res, *res0;
1278 + char hbuf[NI_MAXHOST];
1281 + msg_info("%s: host %s", myname, host);
1284 + * If we can't lookup the host, play safe and assume it is OK.
1289 + memset(&hints, 0, sizeof(hints));
1290 + hints.ai_family = PF_UNSPEC;
1291 + hints.ai_socktype = SOCK_DGRAM;
1292 + error = getaddrinfo(host, NULL, &hints, &res0);
1295 + msg_info("%s: host %s: %s", myname, host, gai_strerror(error));
1298 + for (res = res0; res; res = res->ai_next) {
1299 + if (msg_verbose) {
1300 + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
1301 + NULL, 0, NI_NUMERICHOST)) {
1302 + strncpy(hbuf, "???", sizeof(hbuf));
1304 + msg_info("%s: addr %s", myname, hbuf);
1306 + if (own_inet_addr(res->ai_addr)) {
1307 + freeaddrinfo(res0);
1311 + freeaddrinfo(res0);
1313 + msg_info("%s: host %s: no match", myname, host);
1317 char *myname = "has_my_addr";
1318 struct in_addr addr;
1320 @@ -1038,6 +1089,7 @@
1321 msg_info("%s: host %s: no match", myname, host);
1327 /* permit_mx_backup - permit use of me as MX backup for recipient domain */
1328 @@ -1544,9 +1596,14 @@
1329 int dns_status = DNS_FAIL;
1335 msg_info("%s: %s", myname, state->addr);
1337 + /* IPv4 only for now */
1338 + if (inet_pton(AF_INET, state->addr, &a) != 1)
1339 + return SMTPD_CHECK_DUNNO;
1343 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/smtpd/smtpd_peer.c snapshot-20010525/src/smtpd/smtpd_peer.c
1344 --- snapshot-20010525.noipv6/src/smtpd/smtpd_peer.c Sun Jan 28 16:24:56 2001
1345 +++ snapshot-20010525/src/smtpd/smtpd_peer.c Tue May 29 18:40:28 2001
1350 +/* Utility library. */
1353 +#include <mymalloc.h>
1354 +#include <valid_hostname.h>
1355 +#include <stringops.h>
1357 +/* Global library. */
1360 * Older systems don't have h_errno. Even modern systems don't have
1366 -/* Utility library. */
1369 -#include <mymalloc.h>
1370 -#include <valid_hostname.h>
1371 -#include <stringops.h>
1373 -/* Global library. */
1377 +#define GAI_STRERROR(error) \
1378 + ((error = EAI_SYSTEM) ? gai_strerror(error) : strerror(errno))
1381 /* Application-specific. */
1384 @@ -102,16 +106,23 @@
1386 void smtpd_peer_init(SMTPD_STATE *state)
1388 - struct sockaddr_in sin;
1389 - SOCKADDR_SIZE len = sizeof(sin);
1391 + struct sockaddr_storage ss;
1393 + struct sockaddr ss;
1394 + struct in_addr *in;
1398 + struct sockaddr *sa;
1399 + SOCKADDR_SIZE len;
1401 + sa = (struct sockaddr *)&ss;
1405 * Look up the peer address information.
1407 - if (getpeername(vstream_fileno(state->client),
1408 - (struct sockaddr *) & sin, &len) >= 0) {
1409 + if (getpeername(vstream_fileno(state->client), sa, &len) >= 0) {
1413 @@ -128,18 +139,51 @@
1415 * Look up and "verify" the client hostname.
1417 - else if (errno == 0 && sin.sin_family == AF_INET) {
1418 - state->addr = mystrdup(inet_ntoa(sin.sin_addr));
1419 - hp = gethostbyaddr((char *) &(sin.sin_addr),
1420 - sizeof(sin.sin_addr), AF_INET);
1422 + else if (errno == 0 && (sa->sa_family == AF_INET
1424 + || sa->sa_family == AF_INET6
1428 + char hbuf[NI_MAXHOST];
1429 + char abuf[NI_MAXHOST];
1430 + struct addrinfo hints, *rnull = NULL;
1432 + char abuf[sizeof("255.255.255.255") + 1];
1438 + (void)getnameinfo(sa, len, abuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
1440 + in = &((struct sockaddr_in *)sa)->sin_addr;
1441 + inet_ntop(AF_INET, in, abuf, sizeof(hbuf));
1443 + state->addr = mystrdup(abuf);
1445 + error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD);
1448 + hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET);
1451 + hbuf = mystrdup(hp->h_name);
1456 state->name = mystrdup("unknown");
1458 + state->peer_code = (error == EAI_AGAIN ? 4 : 5);
1460 state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
1461 - } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
1463 + } else if (!valid_hostname(hbuf, DONT_GRIPE)) {
1464 state->name = mystrdup("unknown");
1465 state->peer_code = 5;
1467 - state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */
1468 + state->name = mystrdup(hbuf); /* hp->name is clobbered!! */
1469 state->peer_code = 2;
1472 @@ -151,16 +195,31 @@
1473 state->peer_code = code; \
1477 + memset(&hints, 0, sizeof(hints));
1478 + hints.ai_family = AF_UNSPEC;
1479 + hints.ai_socktype = SOCK_STREAM;
1480 + error = getaddrinfo(state->name, NULL, &hints, &rnull);
1482 + msg_warn("%s: hostname %s verification failed: %s",
1483 + state->addr, state->name, GAI_STRERROR(error));
1484 + REJECT_PEER_NAME(state, (error == EAI_AGAIN ? 4 : 5));
1486 + /* memcmp() isn't needed if we use getaddrinfo */
1488 + freeaddrinfo(rnull);
1490 hp = gethostbyname(state->name); /* clobbers hp->name!! */
1492 msg_warn("%s: hostname %s verification failed: %s",
1493 state->addr, state->name, HSTRERROR(h_errno));
1494 REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ? 4 : 5));
1495 - } else if (hp->h_length != sizeof(sin.sin_addr)) {
1496 + } else if (hp->h_length != sizeof(*in)) {
1497 msg_warn("%s: hostname %s verification failed: bad address size %d",
1498 state->addr, state->name, hp->h_length);
1499 REJECT_PEER_NAME(state, 5);
1502 for (i = 0; /* void */ ; i++) {
1503 if (hp->h_addr_list[i] == 0) {
1504 msg_warn("%s: address not listed for hostname %s",
1505 @@ -168,13 +227,12 @@
1506 REJECT_PEER_NAME(state, 5);
1509 - if (memcmp(hp->h_addr_list[i],
1510 - (char *) &sin.sin_addr,
1511 - sizeof(sin.sin_addr)) == 0)
1512 + if (memcmp(hp->h_addr_list[i], (char *)in, sizeof(*in)) == 0)
1513 break; /* keep peer name */
1521 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/Makefile.in snapshot-20010525/src/util/Makefile.in
1522 --- snapshot-20010525.noipv6/src/util/Makefile.in Tue May 29 16:03:38 2001
1523 +++ snapshot-20010525/src/util/Makefile.in Tue May 29 18:23:16 2001
1525 dict_nisplus.c dict_open.c dir_forest.c doze.c environ.c \
1526 events.c exec_command.c fifo_listen.c fifo_trigger.c file_limit.c \
1527 find_inet.c fsspace.c fullname.c get_domainname.c get_hostname.c \
1529 htable.c inet_addr_host.c inet_addr_list.c inet_addr_local.c \
1530 inet_connect.c inet_listen.c inet_trigger.c inet_util.c \
1531 line_wrap.c lowercase.c lstat_as.c mac_parse.c make_dirs.c \
1533 dict_nisplus.o dict_open.o dir_forest.o doze.o environ.o \
1534 events.o exec_command.o fifo_listen.o fifo_trigger.o file_limit.o \
1535 find_inet.o fsspace.o fullname.o get_domainname.o get_hostname.o \
1537 htable.o inet_addr_host.o inet_addr_list.o inet_addr_local.o \
1538 inet_connect.o inet_listen.o inet_trigger.o inet_util.o \
1539 line_wrap.o lowercase.o lstat_as.o mac_parse.o make_dirs.o \
1541 dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
1542 dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
1543 exec_command.h find_inet.h fsspace.h fullname.h get_domainname.h \
1545 get_hostname.h htable.h inet_addr_host.h inet_addr_list.h \
1546 inet_addr_local.h inet_util.h iostuff.h line_wrap.h listen.h lstat_as.h \
1547 mac_parse.h make_dirs.h match_list.h match_ops.h msg.h msg_output.h \
1549 get_domainname.o: mymalloc.h
1550 get_domainname.o: get_hostname.h
1551 get_domainname.o: get_domainname.h
1552 +get_port.o: sys_defs.h
1553 get_hostname.o: get_hostname.c
1554 get_hostname.o: sys_defs.h
1555 get_hostname.o: mymalloc.h
1557 match_list.o: stringops.h
1558 match_list.o: argv.h
1559 match_list.o: dict.h
1560 +match_list.o: inet_util.h
1561 match_list.o: match_list.h
1562 match_ops.o: match_ops.c
1563 match_ops.o: sys_defs.h
1564 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/get_port.c snapshot-20010525/src/util/get_port.c
1565 --- snapshot-20010525.noipv6/src/util/get_port.c Thu Jan 1 01:00:00 1970
1566 +++ snapshot-20010525/src/util/get_port.c Tue May 29 18:23:16 2001
1572 +/* trivial host and port extracter
1574 +/* #include <get_port.h>
1576 +/* char *get_port(data)
1580 +/* get_port() extract host name or ip address from
1581 +/* strings such as [3ffe:902:12::10]:25, [::1]
1582 +/* or 192.168.0.1:25, and null-terminates the
1583 +/* \fIdata\fR at the first occurrence of port separator.
1585 +/* If port not found return null pointer.
1589 +/* BSD Style (or BSD like) license.
1591 +/* Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1595 +/* System libraries */
1597 +#include <sys_defs.h>
1598 +#include <string.h>
1600 +/* Utility library. */
1602 +#include "get_port.h"
1604 +/* get_port - extract port number from string */
1606 +char *get_port(char *data)
1608 + const char *escl=strchr(data,'[');
1609 + const char *sepl=strchr(data,':');
1610 + char *escr=strrchr(data,']');
1611 + char *sepr=strrchr(data,':');
1613 + /* extract from "[address]:port" or "[address]"*/
1616 + memmove(data, data + 1, strlen(data) - strlen(escr));
1617 + data[strlen(data) - strlen(escr) - 1] = 0;
1621 + return (*escr ? escr : NULL);
1623 + /* extract from "address:port" or "address" */
1624 + if ((sepl == sepr) && sepr && sepl)
1630 + /* return empty string */
1633 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/get_port.h snapshot-20010525/src/util/get_port.h
1634 --- snapshot-20010525.noipv6/src/util/get_port.h Thu Jan 1 01:00:00 1970
1635 +++ snapshot-20010525/src/util/get_port.h Tue May 29 18:23:16 2001
1637 +#ifndef _GET_PORT_H_INCLUDED_
1638 +#define _GET_PORT_H_INCLUDED_
1644 +/* trivial host and port extracter
1646 +/* #include <get_port.h>
1650 + /* External interface. */
1652 +extern char *get_port(char *);
1658 +/* BSD Style (or BSD like) license.
1660 +/* Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1665 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/inet_addr_host.c snapshot-20010525/src/util/inet_addr_host.c
1666 --- snapshot-20010525.noipv6/src/util/inet_addr_host.c Fri Dec 11 19:55:35 1998
1667 +++ snapshot-20010525/src/util/inet_addr_host.c Tue May 29 18:23:16 2001
1669 #include <sys_defs.h>
1670 #include <netinet/in.h>
1671 #include <arpa/inet.h>
1672 +#include <sys/socket.h>
1674 +#include <stdlib.h>
1675 +#include <string.h>
1678 #define INADDR_NONE 0xffffffff
1681 #include <inet_addr_list.h>
1682 #include <inet_addr_host.h>
1687 /* inet_addr_host - look up address list for host */
1689 int inet_addr_host(INET_ADDR_LIST *addr_list, const char *hostname)
1693 + struct addrinfo hints, *res0, *res;
1695 + char buforhosta[1024];
1700 struct in_addr addr;
1702 int initial_count = addr_list->used;
1705 + memset(&hints, 0, sizeof(hints));
1706 + hints.ai_family = PF_UNSPEC;
1707 + hints.ai_socktype = SOCK_DGRAM;
1708 + error = getaddrinfo(hostname, NULL, &hints, &res0);
1710 + for (res = res0; res; res = res->ai_next) {
1711 + /* filter out address families that are not supported */
1712 + s = socket(res->ai_family, SOCK_DGRAM, 0);
1717 + inet_addr_list_append(addr_list, res->ai_addr);
1719 + freeaddrinfo(res0);
1722 if ((addr.s_addr = inet_addr(hostname)) != INADDR_NONE) {
1723 inet_addr_list_append(addr_list, &addr);
1726 inet_addr_list_append(addr_list,
1727 (struct in_addr *) * hp->h_addr_list++);
1731 return (addr_list->used - initial_count);
1740 INET_ADDR_LIST addr_list;
1742 + struct sockaddr *sa;
1743 + char hbuf[NI_MAXHOST];
1745 msg_vstream_init(argv[0], VSTREAM_ERR);
1748 if (inet_addr_host(&addr_list, *argv) == 0)
1749 msg_fatal("not found: %s", *argv);
1751 - for (i = 0; i < addr_list.used; i++)
1752 - vstream_printf("%s\n", inet_ntoa(addr_list.addrs[i]));
1753 + for (i = 0; i < addr_list.used; i++) {
1754 + sa = (struct sockaddr *)&addr_list.addrs[i];
1755 + getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
1757 + vstream_printf("%s\n", hbuf);
1759 vstream_fflush(VSTREAM_OUT);
1761 inet_addr_list_free(&addr_list);
1762 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/inet_addr_list.c snapshot-20010525/src/util/inet_addr_list.c
1763 --- snapshot-20010525.noipv6/src/util/inet_addr_list.c Mon Nov 20 19:06:30 2000
1764 +++ snapshot-20010525/src/util/inet_addr_list.c Tue May 29 18:23:16 2001
1766 #include <netinet/in.h>
1767 #include <arpa/inet.h>
1772 +#include <string.h>
1773 +#include <sys/socket.h>
1776 /* Utility library. */
1784 + list->addrs = (struct sockaddr_storage *)
1786 list->addrs = (struct in_addr *)
1788 mymalloc(sizeof(*list->addrs) * list->size);
1791 /* inet_addr_list_append - append address to internet address list */
1794 +void inet_addr_list_append(INET_ADDR_LIST *list,
1795 + struct sockaddr * addr)
1797 + char *myname = "inet_addr_list_append";
1798 + char hbuf[NI_MAXHOST];
1800 + if (msg_verbose > 1) {
1801 + if (getnameinfo(addr, SA_LEN(addr), hbuf, sizeof(hbuf), NULL, 0,
1802 + NI_NUMERICHOST)) {
1803 + strncpy(hbuf, "??????", sizeof(hbuf));
1805 + msg_info("%s: %s", myname, hbuf);
1808 + if (list->used >= list->size)
1810 + list->addrs = (struct sockaddr_storage *)
1811 + myrealloc((char *) list->addrs,
1812 + sizeof(*list->addrs) * list->size);
1813 + memcpy(&list->addrs[list->used++], addr, SA_LEN(addr));
1816 void inet_addr_list_append(INET_ADDR_LIST *list, struct in_addr * addr)
1818 char *myname = "inet_addr_list_append";
1820 sizeof(*list->addrs) * list->size);
1821 list->addrs[list->used++] = *addr;
1825 /* inet_addr_list_free - destroy internet address list */
1827 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/inet_addr_list.h snapshot-20010525/src/util/inet_addr_list.h
1828 --- snapshot-20010525.noipv6/src/util/inet_addr_list.h Fri Dec 11 19:55:35 1998
1829 +++ snapshot-20010525/src/util/inet_addr_list.h Tue May 29 18:23:16 2001
1832 #include <netinet/in.h>
1836 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1837 +#define SS_LEN(x) (((x).ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1839 +#define SA_LEN(x) ((x)->sa_len)
1840 +#define SS_LEN(x) ((x).ss_len)
1845 * External interface.
1847 typedef struct INET_ADDR_LIST {
1848 int used; /* nr of elements in use */
1849 int size; /* actual list size */
1851 + struct sockaddr_storage *addrs; /* payload */
1853 struct in_addr *addrs; /* payload */
1857 extern void inet_addr_list_init(INET_ADDR_LIST *);
1858 extern void inet_addr_list_free(INET_ADDR_LIST *);
1861 +extern void inet_addr_list_append(INET_ADDR_LIST *, struct sockaddr *);
1863 extern void inet_addr_list_append(INET_ADDR_LIST *, struct in_addr *);
1868 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/inet_addr_local.c snapshot-20010525/src/util/inet_addr_local.c
1869 --- snapshot-20010525.noipv6/src/util/inet_addr_local.c Sun Feb 25 19:20:19 2001
1870 +++ snapshot-20010525/src/util/inet_addr_local.c Tue May 29 18:47:06 2001
1875 +#if defined(INET6) && (defined (LINUX) || defined (LINUX2))
1879 +#ifdef HAVE_GETIFADDRS
1880 +#include <ifaddrs.h>
1883 /* Utility library. */
1887 int inet_addr_local(INET_ADDR_LIST *addr_list, INET_ADDR_LIST *mask_list)
1889 +#ifdef HAVE_GETIFADDRS
1890 + char *myname = "inet_addr_local";
1891 + struct ifaddrs *ifap, *ifa;
1892 + int initial_count = addr_list->used;
1893 + struct sockaddr *sa;
1896 + struct sockaddr_in6 addr6;
1902 + if (getifaddrs(&ifap) < 0)
1903 + msg_fatal("%s: getifaddrs: %m", myname);
1905 + for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1906 + if (! (ifa->ifa_flags & IFF_RUNNING))
1908 + sa = ifa->ifa_addr;
1909 + switch (ifa->ifa_addr->sa_family) {
1912 + addr = (void *)&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
1918 + memcpy(&addr6, ifa->ifa_addr, ifa->ifa_addr->sa_len);
1919 + /* decode scoped address notation */
1920 + if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
1921 + IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
1922 + addr6.sin6_scope_id == 0) {
1923 + addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
1924 + (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
1925 + addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
1926 + sa = (struct sockaddr *)&addr6;
1936 + inet_addr_list_append(addr_list, sa);
1938 + inet_addr_list_append(addr_list, (struct in_addr *)addr);
1942 + freeifaddrs(ifap);
1943 + return (addr_list->used - initial_count);
1945 char *myname = "inet_addr_local";
1948 struct ifreq *the_end;
1950 - VSTRING *buf = vstring_alloc(1024);
1952 int initial_count = addr_list->used;
1953 struct in_addr addr;
1954 struct ifreq *ifr_mask;
1957 +#if defined (LINUX) || defined (LINUX2)
1958 +#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
1960 + char addr6p[8][5], addr6res[40], devname[20];
1961 + int plen, scope, dad_status, if_idx, gaierror;
1962 + struct addrinfo hints, *res, *res0;
1964 + struct sockaddr_in6 addr6;
1966 - if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
1969 + buf = vstring_alloc(1024);
1971 + if ((sock = socket(af, SOCK_DGRAM, 0)) < 0) {
1973 + if (af == AF_INET6)
1976 + msg_warn("%s: socket: %m", myname);
1981 msg_fatal("%s: socket: %m", myname);
1985 * Get the network interface list. XXX The socket API appears to have no
1986 @@ -126,10 +213,15 @@
1988 the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1989 for (ifr = ifc.ifc_req; ifr < the_end;) {
1990 - if (ifr->ifr_addr.sa_family == AF_INET) { /* IP interface */
1991 + if ((ifr->ifr_addr.sa_family == AF_INET) &&
1992 + (ifr->ifr_addr.sa_family == af)) { /* IP interface */
1993 addr = ((struct sockaddr_in *) & ifr->ifr_addr)->sin_addr;
1994 if (addr.s_addr != INADDR_ANY) { /* has IP address */
1996 + inet_addr_list_append(addr_list, &ifr->ifr_addr);
1998 inet_addr_list_append(addr_list, &addr);
2001 ifr_mask = (struct ifreq *) mymalloc(IFREQ_SIZE(ifr));
2002 memcpy((char *) ifr_mask, (char *) ifr, IFREQ_SIZE(ifr));
2003 @@ -141,11 +233,61 @@
2008 + else if ((ifr->ifr_addr.sa_family == AF_INET6) &&
2009 + (ifr->ifr_addr.sa_family == af)) { /* IPv6 interface */
2010 + addr6 = *((struct sockaddr_in6 *) & ifr->ifr_addr);
2012 + /* decode scoped address notation */
2013 + if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
2014 + IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
2015 + addr6.sin6_scope_id == 0) {
2016 + addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
2017 + (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
2018 + addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
2021 + if (!(IN6_IS_ADDR_UNSPECIFIED(&addr6.sin6_addr)))
2022 + inet_addr_list_append(addr_list, (struct sockaddr *)&addr6);
2025 ifr = NEXT_INTERFACE(ifr);
2031 + if (af != AF_INET6) {
2033 + goto other_socket_type;
2035 +#if defined (LINUX) || defined (LINUX2)
2036 + if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
2037 + while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
2038 + addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4],
2039 + addr6p[5], addr6p[6], addr6p[7],
2040 + &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
2041 + sprintf(addr6res, "%s:%s:%s:%s:%s:%s:%s:%s",
2042 + addr6p[0], addr6p[1], addr6p[2], addr6p[3],
2043 + addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
2044 + addr6res[sizeof(addr6res) - 1] = 0;
2045 + memset(&hints, 0, sizeof(hints));
2046 + hints.ai_flags = AI_NUMERICHOST;
2047 + hints.ai_family = AF_UNSPEC;
2048 + hints.ai_socktype = SOCK_DGRAM;
2049 + gaierror = getaddrinfo(addr6res, NULL, &hints, &res0);
2051 + for (res = res0; res; res = res->ai_next) {
2052 + inet_addr_list_append(addr_list, res->ai_addr);
2054 + freeaddrinfo(res0);
2060 return (addr_list->used - initial_count);
2066 INET_ADDR_LIST addr_list;
2067 INET_ADDR_LIST mask_list;
2069 + char abuf[NI_MAXHOST], mbuf[NI_MAXHOST];
2070 + struct sockaddr *sa;
2072 msg_vstream_init(argv[0], VSTREAM_ERR);
2074 @@ -172,8 +316,17 @@
2075 msg_warn("found only one active network interface");
2077 for (i = 0; i < addr_list.used; i++) {
2078 - vstream_printf("%s/", inet_ntoa(addr_list.addrs[i]));
2079 - vstream_printf("%s\n", inet_ntoa(mask_list.addrs[i]));
2080 + sa = (struct sockaddr *)&addr_list.addrs[i];
2081 + if (getnameinfo(sa, SA_LEN(sa), abuf, sizeof(abuf), NULL, 0,
2082 + NI_NUMERICHOST)) {
2083 + strncpy(abuf, "???", sizeof(abuf));
2085 + sa = (struct sockaddr *)&mask_list.addrs[i];
2086 + if (getnameinfo(sa, SA_LEN(sa), mbuf, sizeof(mbuf), NULL, 0,
2087 + NI_NUMERICHOST)) {
2088 + strncpy(mbuf, "???", sizeof(mbuf));
2090 + vstream_printf("%s/%s\n", abuf, mbuf);
2092 vstream_fflush(VSTREAM_OUT);
2093 inet_addr_list_free(&addr_list);
2094 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/inet_connect.c snapshot-20010525/src/util/inet_connect.c
2095 --- snapshot-20010525.noipv6/src/util/inet_connect.c Mon Nov 20 19:06:31 2000
2096 +++ snapshot-20010525/src/util/inet_connect.c Tue May 29 18:23:16 2001
2105 /* Utility library. */
2112 + struct addrinfo hints, *res, *res0;
2115 struct sockaddr_in sin;
2123 buf = inet_parse(addr, &host, &port);
2127 + memset(&hints, 0, sizeof(hints));
2128 + hints.ai_family = PF_UNSPEC;
2129 + hints.ai_socktype = SOCK_STREAM;
2130 + hints.ai_flags = AI_NUMERICHOST; /* find_inet_addr is numeric only */
2131 + if (getaddrinfo(host, port, &hints, &res0))
2132 + msg_fatal("host not found: %s", host);
2136 memset((char *) &sin, 0, sizeof(sin));
2137 sin.sin_family = AF_INET;
2138 sin.sin_addr.s_addr = find_inet_addr(host);
2139 sin.sin_port = find_inet_port(port, "tcp");
2145 + for (res = res0; res; res = res->ai_next) {
2146 + if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2149 + sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
2152 + if (timeout > 0) {
2153 + non_blocking(sock, NON_BLOCKING);
2154 + if (timed_connect(sock, res->ai_addr, res->ai_addrlen, timeout) < 0) {
2159 + if (block_mode != NON_BLOCKING)
2160 + non_blocking(sock, block_mode);
2163 + non_blocking(sock, block_mode);
2164 + if (connect(sock, res->ai_addr, res->ai_addrlen) < 0
2165 + && errno != EINPROGRESS) {
2173 + freeaddrinfo(res0);
2177 * Create a client socket.
2185 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/inet_listen.c snapshot-20010525/src/util/inet_listen.c
2186 --- snapshot-20010525.noipv6/src/util/inet_listen.c Mon Nov 20 19:06:32 2000
2187 +++ snapshot-20010525/src/util/inet_listen.c Tue May 29 18:23:16 2001
2189 #include <sys_defs.h>
2190 #include <sys/socket.h>
2191 #include <netinet/in.h>
2193 +#if (! __GLIBC__ >= 2 && __GLIBC_MINOR__ >=1 )
2194 +#include <netinet6/in6.h>
2197 #include <arpa/inet.h>
2199 #ifndef MAXHOSTNAMELEN
2200 @@ -79,33 +84,109 @@
2202 int inet_listen(const char *addr, int backlog, int block_mode)
2205 + struct addrinfo *res, *res0, hints;
2212 + struct sockaddr *ai_addr;
2213 + SOCKADDR_SIZE ai_addrlen;
2214 + struct ai *ai_next;
2215 + } *res, *res0, resbody;
2216 struct sockaddr_in sin;
2224 + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
2226 + char hbuf[sizeof("255.255.255.255") + 1];
2227 + char pbuf[sizeof("255.255.255.255") + 1];
2229 + char *cause = "unknown";
2232 * Translate address information to internal form.
2234 buf = inet_parse(addr, &host, &port);
2235 - memset((char *) &sin, 0, sizeof(sin));
2237 + memset(&hints, 0, sizeof(hints));
2238 + hints.ai_flags = AI_PASSIVE;
2239 + hints.ai_family = AF_UNSPEC;
2240 + hints.ai_socktype = SOCK_STREAM;
2241 + error = getaddrinfo(*host ? host : NULL, *port ? port : "0", &hints, &res0);
2243 + msg_fatal("getaddrinfo: %s", gai_strerror(error));
2247 + memset(&sin, 0, sizeof(sin));
2248 sin.sin_family = AF_INET;
2250 + sin.sin_len = sizeof(sin);
2252 sin.sin_port = find_inet_port(port, "tcp");
2253 sin.sin_addr.s_addr = (*host ? find_inet_addr(host) : INADDR_ANY);
2257 - * Create a listener socket.
2259 - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
2260 - msg_fatal("socket: %m");
2261 - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0)
2262 - msg_fatal("setsockopt: %m");
2263 - if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
2264 - msg_fatal("bind %s port %d: %m", sin.sin_addr.s_addr == INADDR_ANY ?
2265 - "INADDR_ANY" : inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
2266 + memset(&resbody, 0, sizeof(resbody));
2267 + resbody.ai_socktype = SOCK_STREAM;
2268 + resbody.ai_family = AF_INET;
2269 + resbody.ai_addr = (struct sockaddr *)&sin;
2270 + resbody.ai_addrlen = sizeof(sin);
2276 + for (res = res0; res; res = res->ai_next) {
2277 + if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2281 + * Create a listener socket.
2283 + if ((sock = socket(res->ai_family, res->ai_socktype, 0)) < 0) {
2288 + if (res->ai_family == AF_INET6 &&
2289 + setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &t, sizeof(t)) < 0) {
2290 + /* if kernel/libc don't support this simple ignore it
2291 + cause = "setsockopt(IPV6_V6ONLY)";
2299 + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0) {
2300 + cause = "setsockopt(SO_REUSEADDR)";
2306 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
2315 + msg_fatal("%s: %m", cause);
2317 + freeaddrinfo(res0);
2319 non_blocking(sock, block_mode);
2320 if (listen(sock, backlog) < 0)
2321 msg_fatal("listen: %m");
2322 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/match_list.c snapshot-20010525/src/util/match_list.c
2323 --- snapshot-20010525.noipv6/src/util/match_list.c Mon Nov 20 19:06:32 2000
2324 +++ snapshot-20010525/src/util/match_list.c Tue May 29 18:23:16 2001
2326 list = match_list_parse(list, vstring_str(buf));
2327 if (vstream_fclose(fp))
2328 msg_fatal("%s: read file %s: %m", myname, pattern);
2329 - } else if (strchr(pattern, ':') != 0) { /* type:table */
2330 + } else if ((strchr(pattern, ']') == 0) && (strchr(pattern, ':') != 0)) { /* type:table */
2331 for (cp = pattern; *cp == '!'; cp++)
2333 if (dict_handle(pattern) == 0)
2334 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/match_ops.c snapshot-20010525/src/util/match_ops.c
2335 --- snapshot-20010525.noipv6/src/util/match_ops.c Mon Sep 6 03:02:14 1999
2336 +++ snapshot-20010525/src/util/match_ops.c Tue May 29 18:23:16 2001
2338 #include <match_ops.h>
2339 #include <stringops.h>
2345 + * This program is free software; you can redistribute it and/or
2346 + * modify it under the terms of the GNU General Public License
2347 + * as published by the Free Software Foundation; either version
2348 + * 2 of the License, or (at your option) any later version.
2350 + * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
2353 + * Artur Frysiak <wiget@pld.org.pl>
2354 + * Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
2358 +#include <stdlib.h>
2359 +#include <unistd.h>
2360 +#include <syslog.h>
2362 +#include <sys/socket.h>
2363 +#include <netinet/in.h>
2364 +#include <string.h>
2366 +#include <arpa/inet.h>
2367 +#include <resolv.h>
2370 +#define AF_DECnet 12
2374 +#define PF_PACKET 17
2379 + unsigned char family;
2380 + unsigned char bytelen;
2381 + signed short bitlen;
2382 + unsigned int data[4];
2386 +int masked_match(char *, char *, char *);
2387 +int get_integer(int *, char *, int);
2388 +int get_addr_1(inet_prefix *, char *, int);
2389 +int get_prefix_1(inet_prefix *, char *, int);
2390 +int get_addr(inet_prefix *, char *, int);
2391 +int get_prefix(inet_prefix *, char *, int);
2392 +unsigned int get_addr32(char *);
2393 +int matches(char *, char *);
2394 +int inet_addr_match(inet_prefix *, inet_prefix *, int);
2395 +int mask_match(char *, char *, char *);
2397 +int get_integer(int *val, char *arg, int base)
2402 + if (!arg || !*arg)
2404 + res = strtol(arg, &ptr, base);
2405 + if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN)
2411 +int get_addr_1(inet_prefix *addr, char *name, int family)
2414 + unsigned char *ap = (unsigned char*)addr->data;
2417 + memset(addr, 0, sizeof(*addr));
2419 + if (strcmp(name, "default") == 0 || strcmp(name, "any") == 0) {
2420 + if (family == AF_DECnet)
2422 + addr->family = family;
2423 + addr->bytelen = (family == AF_INET6 ? 16 : 4);
2424 + addr->bitlen = -1;
2428 + if (strchr(name, ':')) {
2429 + addr->family = AF_INET6;
2430 + if (family != AF_UNSPEC && family != AF_INET6)
2432 + if (inet_pton(AF_INET6, name, addr->data) <= 0)
2434 + addr->bytelen = 16;
2435 + addr->bitlen = -1;
2438 + addr->family = AF_INET;
2439 + if (family != AF_UNSPEC && family != AF_INET)
2441 + addr->bytelen = 4;
2442 + addr->bitlen = -1;
2443 + for (cp = name, i = 0; *cp; cp++) {
2444 + if (*cp <= '9' && *cp >= '0') {
2445 + ap[i] = 10*ap[i] + (*cp-'0');
2448 + if (*cp == '.' && ++i <= 3)
2455 +int get_prefix_1(inet_prefix *dst, char *arg, int family)
2461 + memset(dst, 0, sizeof(*dst));
2463 + if (strcmp(arg, "default") == 0 || strcmp(arg, "any") == 0) {
2464 + if (family == AF_DECnet)
2466 + dst->family = family;
2472 + slash = strchr(arg, '/');
2475 + err = get_addr_1(dst, arg, family);
2477 + switch(dst->family) {
2479 + dst->bitlen = 128;
2489 + if (get_integer(&plen, slash+1, 0) || plen > dst->bitlen) {
2493 + dst->bitlen = plen;
2502 +int get_addr(inet_prefix *dst, char *arg, int family)
2505 + if (family == AF_PACKET)
2508 + if (get_addr_1(dst, arg, family))
2513 +int get_prefix(inet_prefix *dst, char *arg, int family)
2516 + if (family == AF_PACKET)
2519 + if (get_prefix_1(dst, arg, family))
2524 +unsigned int get_addr32(char *name)
2527 + if (get_addr_1(&addr, name, AF_INET))
2529 + return addr.data[0];
2532 +int matches(char *cmd, char *pattern)
2534 + int len = strlen(cmd);
2535 + if (len > strlen(pattern))
2537 + return memcmp(pattern, cmd, len);
2540 +int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits)
2542 + unsigned int *a1 = a->data;
2543 + unsigned int *a2 = b->data;
2544 + int words = bits >> 0x05;
2549 + if (memcmp(a1, a2, words << 2))
2553 + unsigned int w1, w2;
2554 + unsigned int mask;
2559 + mask = htonl((0xffffffff) << (0x20 - bits));
2561 + if ((w1 ^ w2) & mask)
2568 +/* zero if matches */
2569 +int mask_match(char *network, char *cprefix, char *address)
2571 + inet_prefix *inetwork;
2572 + inet_prefix *iaddress;
2575 + if (!(network && address && cprefix))
2577 + prefix = strtol(cprefix, (char **)NULL, 10);
2578 + if ((prefix < 0) || (prefix > 128))
2580 + if ((strlen(network) == 0) || (strlen(address) == 0))
2583 + inetwork = malloc(sizeof(inet_prefix));
2584 + iaddress = malloc(sizeof(inet_prefix));
2586 + if ((get_addr(iaddress, address, AF_UNSPEC) >= 0)
2587 + && (get_addr(inetwork, network, AF_UNSPEC) >= 0))
2588 + ret = inet_addr_match(inetwork, iaddress, prefix);
2594 + /* 1 if matches */
2595 + /* return (!ret); */
2596 + /* 0 if matches */
2601 + * masked_match() - universal for IPv4 and IPv6
2603 +int masked_match(net_tok, mask_tok, string)
2609 + struct in6_addr in6[2];
2610 + char v4addr[2][INET_ADDRSTRLEN];
2615 + /* Check for NULL */
2616 + if (!(net_tok && mask_tok && string))
2619 + /* If IPv6 mapped convert to native-IPv4 */
2621 + if (inet_pton(AF_INET6, net_tok, &in6[0]) == 1 &&
2622 + inet_pton(AF_INET6, string, &in6[1]) == 1 &&
2623 + IN6_IS_ADDR_V4MAPPED(&in6[0]) && IN6_IS_ADDR_V4MAPPED(&in6[1])) {
2624 + plen = atoi(mask_tok);
2625 + if (32 < plen && plen < 129) {
2626 + sprintf(newmask, "%d", plen - 96);
2627 + mask_tok = newmask;
2630 + (void)inet_ntop(AF_INET, &in6[0].s6_addr[12], v4addr[0],
2631 + sizeof(v4addr[0]));
2632 + net_tok = v4addr[0];
2633 + (void)inet_ntop(AF_INET, &in6[1].s6_addr[12], v4addr[1],
2634 + sizeof(v4addr[1]));
2635 + string = v4addr[1];
2638 + return (!mask_match(net_tok, mask_tok, string));
2642 /* match_string - match a string literal */
2644 int match_string(const char *string, const char *pattern)
2650 /* match_parse_mask - parse net/mask pattern */
2652 static int match_parse_mask(const char *pattern, unsigned long *net_bits,
2653 @@ -178,28 +480,55 @@
2654 myfree(saved_pattern);
2659 /* match_hostaddr - match host by address */
2661 int match_hostaddr(const char *addr, const char *pattern)
2663 char *myname = "match_hostaddr";
2665 + char *network, *mask, *escl, *escr, *patternx;
2666 + struct in6_addr in6;
2667 + char v4addr[INET_ADDRSTRLEN];
2670 unsigned long mask_bits;
2671 unsigned long net_bits;
2672 unsigned long addr_bits;
2676 msg_info("%s: %s ~? %s", myname, addr, pattern);
2679 + if (addr[strspn(addr, "01234567890./:abcdef")] != 0)
2681 if (addr[strspn(addr, "01234567890./:")] != 0)
2686 + patternx = mystrdup(pattern);
2687 + escl = strchr(patternx,'[');
2688 + escr = strrchr(patternx,']');
2689 + if (escl && escr) {
2691 + sprintf(patternx, "%s%s", escl + 1, escr + 1);
2692 + pattern = patternx;
2697 * Try dictionary lookup. This can be case insensitive. XXX Probably
2698 * should also try again after stripping least significant octets.
2700 - if (strchr(pattern, ':') != 0) {
2702 + if (!(escl && escr) && strchr(pattern, ':') != 0)
2704 + if (strchr(pattern, ':') != 0)
2707 if (dict_lookup(pattern, addr) != 0)
2709 if (dict_errno != 0)
2710 @@ -210,6 +539,12 @@
2712 * Try an exact match with the host address.
2715 + if (inet_pton(AF_INET6, addr, &in6) == 1 && IN6_IS_ADDR_V4MAPPED(&in6)) {
2716 + (void)inet_ntop(AF_INET, &in6.s6_addr[12], v4addr, sizeof(v4addr));
2720 if (strcasecmp(addr, pattern) == 0) {
2723 @@ -218,6 +553,20 @@
2724 * In a net/mask pattern, the mask is specified as the number of bits of
2728 + network = mystrdup(patternx);
2729 + mask = split_at(network, '/');
2731 + if (masked_match(network, mask, (char *)addr)) {
2741 if (match_parse_mask(pattern, &net_bits, &mask_shift)) {
2742 addr_bits = inet_addr(addr);
2743 if (addr_bits == INADDR_NONE)
2745 mask_bits = htonl((0xffffffff) << (BITS_PER_ADDR - mask_shift));
2746 return ((addr_bits & mask_bits) == (net_bits & mask_bits));
2751 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/sys_defs.h snapshot-20010525/src/util/sys_defs.h
2752 --- snapshot-20010525.noipv6/src/util/sys_defs.h Tue May 29 16:03:38 2001
2753 +++ snapshot-20010525/src/util/sys_defs.h Tue May 29 18:23:16 2001
2755 #define DEF_MAILBOX_LOCK "flock, dotlock"
2758 +#if ((defined(__NetBSD_Version__) && __NetBSD_Version__ >= 105000000) || defined(USAGI_LIBINET6))
2759 +#define HAVE_GETIFADDRS
2765 diff -ruN --exclude *.wiget --exclude *.rej snapshot-20010525.noipv6/src/util/valid_hostname.c snapshot-20010525/src/util/valid_hostname.c
2766 --- snapshot-20010525.noipv6/src/util/valid_hostname.c Sun Jan 28 15:10:18 2001
2767 +++ snapshot-20010525/src/util/valid_hostname.c Tue May 29 18:23:16 2001
2773 +#include <netinet/in.h>
2774 +#include <sys/socket.h>
2775 +#include <arpa/inet.h>
2779 /* Utility library. */
2782 @@ -103,7 +110,23 @@
2783 msg_warn("%s: misplaced hyphen: %.100s", myname, name);
2789 + else if (ch == ':') {
2790 + struct addrinfo hints, *res;
2792 + memset(&hints, 0, sizeof(hints));
2793 + hints.ai_family = AF_INET6;
2794 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
2795 + hints.ai_flags = AI_NUMERICHOST;
2796 + if (getaddrinfo(name, "0", &hints, &res) == 0) {
2797 + freeaddrinfo(res);
2805 msg_warn("%s: invalid character %d(decimal): %.100s",
2812 + struct addrinfo hints, *res;
2815 #define BYTES_NEEDED 4
2817 @@ -146,6 +172,17 @@
2818 msg_warn("%s: empty address", myname);
2823 + memset(&hints, 0, sizeof(hints));
2824 + hints.ai_family = AF_INET6;
2825 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
2826 + hints.ai_flags = AI_NUMERICHOST;
2827 + if (getaddrinfo(addr, "0", &hints, &res) == 0) {
2828 + freeaddrinfo(res);
2834 * Scary code to avoid sscanf() overflow nasties.