summaryrefslogtreecommitdiffstats
path: root/usr.sbin/faithd
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2001-06-11 12:39:29 +0000
committerume <ume@FreeBSD.org>2001-06-11 12:39:29 +0000
commit832f8d224926758a9ae0b23a6b45353e44fbc87a (patch)
treea79fc7ad2b97862c4a404f352f0211ad93a7b5f1 /usr.sbin/faithd
parent2693854b01a52b0395a91322aa3edf926bddff38 (diff)
downloadFreeBSD-src-832f8d224926758a9ae0b23a6b45353e44fbc87a.zip
FreeBSD-src-832f8d224926758a9ae0b23a6b45353e44fbc87a.tar.gz
Sync with recent KAME.
This work was based on kame-20010528-freebsd43-snap.tgz and some critical problem after the snap was out were fixed. There are many many changes since last KAME merge. TODO: - The definitions of SADB_* in sys/net/pfkeyv2.h are still different from RFC2407/IANA assignment because of binary compatibility issue. It should be fixed under 5-CURRENT. - ip6po_m member of struct ip6_pktopts is no longer used. But, it is still there because of binary compatibility issue. It should be removed under 5-CURRENT. Reviewed by: itojun Obtained from: KAME MFC after: 3 weeks
Diffstat (limited to 'usr.sbin/faithd')
-rw-r--r--usr.sbin/faithd/Makefile2
-rw-r--r--usr.sbin/faithd/README50
-rw-r--r--usr.sbin/faithd/faithd.8151
-rw-r--r--usr.sbin/faithd/faithd.c191
-rw-r--r--usr.sbin/faithd/faithd.h11
-rw-r--r--usr.sbin/faithd/ftp.c5
-rw-r--r--usr.sbin/faithd/prefix.c360
-rw-r--r--usr.sbin/faithd/prefix.h52
-rw-r--r--usr.sbin/faithd/rsh.c2
-rw-r--r--usr.sbin/faithd/tcp.c9
10 files changed, 713 insertions, 120 deletions
diff --git a/usr.sbin/faithd/Makefile b/usr.sbin/faithd/Makefile
index c63b097..42da8df 100644
--- a/usr.sbin/faithd/Makefile
+++ b/usr.sbin/faithd/Makefile
@@ -14,7 +14,7 @@
# $FreeBSD$
PROG= faithd
-SRCS= faithd.c tcp.c ftp.c rsh.c
+SRCS= faithd.c tcp.c ftp.c rsh.c prefix.c
MAN= faithd.8
#CFLAGS+= -DFAITH4
CFLAGS+= -Wall
diff --git a/usr.sbin/faithd/README b/usr.sbin/faithd/README
index 4808b4a..2ad0592 100644
--- a/usr.sbin/faithd/README
+++ b/usr.sbin/faithd/README
@@ -1,7 +1,7 @@
Configuring FAITH IPv6-to-IPv4 TCP relay
Kazu Yamamoto and Jun-ichiro itojun Hagino
-$KAME: README,v 1.4 2000/05/31 03:16:14 itojun Exp $
+$KAME: README,v 1.7 2001/04/25 11:25:19 itojun Exp $
$FreeBSD$
Introduction
@@ -27,13 +27,13 @@ invoked per each TCP services (TCP port number).
clients IPv6 node "src" |
You will have to allocate an IPv6 address prefix to map IPv4 addresses into.
-The following description uses 3ffe:0501:1234:ffff:: as example.
+The following description uses 3ffe:0501:ffff:0000:: as example.
Please use a prefix which belongs to your site.
FAITH will make it possible to make a IPv6 TCP connection From IPv6 node
"src", toward IPv4 node "dest", by specifying FAITH-mapped address
-3ffe:0501:1234:ffff::123.4.5.6
-(which is, 3ffe:0501:1234:ffff:0000:0000:7b04:0506).
-The address mapping can be performed by hand:-), by speical nameserver on
+3ffe:0501:ffff:0000::123.4.5.6
+(which is, 3ffe:0501:ffff:0000:0000:0000:7b04:0506).
+The address mapping can be performed by hand:-), by special nameserver on
the network, or by special resolver on the source node.
@@ -41,7 +41,7 @@ Setup
=====
The following example assumes:
-- You have assigned 3ffe:0501:1234:ffff:: as FAITH adderss prefix.
+- You have assigned 3ffe:0501:ffff:0000:: as FAITH adderss prefix.
- You are willing to provide IPv6-to IPv4 TCP relay for telnet.
<<On the translating router on which faithd runs>>
@@ -57,12 +57,12 @@ The following example assumes:
(3) Route packets toward FAITH prefix into "faith0" interface.
# ifconfig faith0 up
- # route add -inet6 3ffe:0501:1234:ffff:: -prefixlen 64 \
- fe80::xxxx:yyyy:zzzz:wwww%faith0
+ # route add -inet6 3ffe:0501:ffff:0000:: -prefixlen 64 ::1
+ # route change -inet6 3ffe:0501:ffff:0000:: -prefixlen 64 -ifp faith0
(4) Execute "faithd" by root as follows:
- # faithd telnet /usr/local/v6/libexec/telnetd telnetd
+ # faithd telnet /usr/libexec/telnetd telnetd
1st argument is a service name you are willing to provide TCP relay.
(it can be specified either by number "23" or by string "telnet")
@@ -73,11 +73,14 @@ The following example assumes:
More examples:
- # faithd login /usr/local/v6/libexec/rlogin rlogind
- # faithd shell /usr/local/v6/libexec/rshd rshd
- # faithd ftpd /usr/local/v6/libexec/ftpd ftpd -l
+ # faithd login /usr/libexec/rlogin rlogind
+ # faithd shell /usr/libexec/rshd rshd
+ # faithd ftpd /usr/libexec/ftpd ftpd -l
# faithd sshd
+If inetd(8) on your platform have special support for faithd, it is possible
+to setup faithd services via inetd(8). Consult manpage for details.
+
<<Routing>>
@@ -95,7 +98,7 @@ There are two ways to translate IPv4 address to IPv6 address:
(5.b) Add an entry into /etc/hosts so that you can resolve hostname into
faked IPv6 addrss. For example, add the following line for www.netbsd.org:
- 3ffe:0501:1234:ffff::140.160.140.252 www.netbsd.org
+ 3ffe:0501:ffff:0000::140.160.140.252 www.netbsd.org
<<On the translating router on which faithd runs.>>
@@ -107,18 +110,31 @@ in "/var/log/daemon".
daemon.* /var/log/daemon
+Access control
+==============
+
+Since faithd implements TCP relaying service, it is critical to implement
+proper access control to cope with malicious use. Bad guy may try to
+use your relay router to circumvent access controls, or may try to
+abuse your network (like sending SPAMs from IPv4 address that belong to you).
+Install IPv6 packet filter directives that would reject traffic from
+unwanted source. If you are using inetd-based setup, you may be able to
+use access control mechanisms in inetd.
+
+
Advanced configuration
======================
If you would like to restrict IPv4 destination for translation, you may
want to do the following:
- # route add -inet6 3ffe:0501:1234:ffff::123.0.0.0 -prefixlen 104 \
- -interface faith0
+ # route add -inet6 3ffe:0501:ffff:0000::123.0.0.0 -prefixlen 104 ::1
+ # route change -inet6 3ffe:0501:ffff:0000::123.0.0.0 -prefixlen 104 \
+ -ifp faith0
By this way, you can restrict IPv4 destination to 123.0.0.0/8.
-You may also want to reject packets toward 3ffe:0501:1234:ffff::/64 which
-is not in 3ffe:0501:1234:ffff::123.0.0.0/104. This will be left as excerside
+You may also want to reject packets toward 3ffe:0501:ffff:0000::/64 which
+is not in 3ffe:0501:ffff:0000::123.0.0.0/104. This will be left as excerside
for the reader.
By doing this, you will be able to provide your IPv4 web server to outside
diff --git a/usr.sbin/faithd/faithd.8 b/usr.sbin/faithd/faithd.8
index 6d552eb..ff0fa65 100644
--- a/usr.sbin/faithd/faithd.8
+++ b/usr.sbin/faithd/faithd.8
@@ -1,4 +1,4 @@
-.\" $KAME: faithd.8,v 1.12 2000/07/04 13:15:01 itojun Exp $
+.\" $KAME: faithd.8,v 1.30 2001/05/24 20:47:56 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@@ -38,7 +38,9 @@
.Sh SYNOPSIS
.Nm
.Op Fl dp
-.Op Ar service Op Ar serverpath Op Ar serverargs
+.Op Fl f Ar configfile
+.Ar service
+.Op Ar serverpath Op Ar serverargs
.Sh DESCRIPTION
.Nm
provides IPv6-to-IPv4 TCP relay.
@@ -96,6 +98,24 @@ address prefix, by using
and
.Xr sysctl 8
commands.
+.Pp
+.Nm
+needs a special name-to-address translation logic, so that
+hostnames gets resolved into special
+.Tn IPv6
+address prefix.
+For small-scale installation, use
+.Xr hosts 5 .
+For large-scale installation, it is useful to have
+a DNS server with special address translation support.
+An implementation called
+.Nm totd
+is available
+at
+.Pa http://www.vermicelli.pasta.cs.uit.no/ipv6/software.html .
+Make sure you do not propagate translated DNS records to normal DNS cloud,
+it is highly harmful.
+.Pp
.Ss Daemon mode
When
.Nm
@@ -136,26 +156,14 @@ You can also specify
.Ar serverargs
for the arguments for the local daemon.
.Pp
-If
-.Ar service
-is not given,
-.Li telnet
-is assumed, and
-.Nm
-will relay TCP traffic on TCP port
-.Li telnet .
-With
-.Ar service ,
-.Nm
-will work as TCP relaying daemon for specified
-.Ar service
-as described above.
-.Pp
The following options are available:
.Bl -tag -width indent
.It Fl d
Debugging information will be generated using
.Xr syslog 3 .
+.It Fl f Ar configfile
+Specify a configuration file for access control.
+See below.
.It Fl p
Use privileged TCP port number as source port,
for IPv4 TCP connection toward final destination.
@@ -200,7 +208,7 @@ is invoked via
.Xr inetd 8 ,
.Nm
will handle connection passed from standard input.
-If it the connection endpoint is in the reserved IPv6 address prefix.
+If the connection endpoint is in the reserved IPv6 address prefix,
.Nm
will relay the connection.
Otherwise,
@@ -223,6 +231,52 @@ The operation mode requires special support for
.Nm
in
.Xr inetd 8 .
+.Ss Access control
+To prevent malicious accesses,
+.Nm
+implements a simple address-based access control.
+With
+.Pa /etc/faithd.conf
+.Po
+or
+.Ar configfile
+specified by
+.Fl f
+.Pc ,
+.Nm
+will avoid relaying unwanted traffic.
+The
+.Pa faithd.conf
+contains directives with the following format:
+.Bl -bullet
+.It
+.Xo
+.Ic Ar src/slen Li deny Ar dst/dlen
+.Xc
+.Pp
+If the source address of a query matches
+.Ar src/slen ,
+and the translated destination address matches
+.Ar dst/dlen ,
+deny the connection.
+.It
+.Xo
+.Ic Ar src/slen Li permit Ar dst/dlen
+.Xc
+.Pp
+If the source address of a query matches
+.Ar src/slen ,
+and the translated destination address matches
+.Ar dst/dlen ,
+permit the connection.
+.El
+.Pp
+The directives are evaluated in sequence,
+and the first matching entry will be effective.
+.Pp
+With inetd mode,
+traffic may be filtered by using access control functionality in
+.Xr inetd 8 .
.Sh EXAMPLES
Before invoking
.Nm ,
@@ -241,9 +295,8 @@ To translate
.Li telnet
service, and provide no local telnet service, invoke
.Nm
-as either of the following:
+as follows:
.Bd -literal -offset
-# faithd
# faithd telnet
.Ed
.Pp
@@ -258,7 +311,7 @@ use the following command line:
.Pp
If you would like to pass extra arguments to the local daemon:
.Bd -literal -offset
-# faithd ftpd /usr/local/v6/libexec/ftpd ftpd -l
+# faithd ftp /usr/local/v6/libexec/ftpd ftpd -l
.Ed
.Pp
Here are some other examples.
@@ -266,14 +319,15 @@ You may need
.Fl p
to translate rsh/rlogin services.
.Bd -literal -offset
-# faithd sshd
+# faithd ssh
# faithd login /usr/local/v6/libexec/rlogin rlogind
# faithd shell /usr/local/v6/libexec/rshd rshd
.Ed
.Pp
However, you should be careful when translating rlogin or rsh
-connections. See
-.Sx SECURITY NOTICE
+connections.
+See
+.Sx SECURITY CONSIDERATIONS
for more details.
.Ss inetd mode samples
Add the following lines into
@@ -282,7 +336,7 @@ Syntax may vary depending upon your operating system.
.Bd -literal -offset
telnet stream tcp6/faith nowait root /usr/sbin/faithd telnetd
ftp stream tcp6/faith nowait root /usr/sbin/faithd ftpd -l
-ssh stream tcp6/faith nowait root /usr/sbin/faithd /usr/pkg/bin/sshd -i
+ssh stream tcp6/faith nowait root /usr/sbin/faithd /usr/sbin/sshd -i
.Ed
.Pp
.Xr inetd 8
@@ -298,6 +352,20 @@ Otherwise,
.Nm
will invoke service-specific daemon like
.Xr telnetd 8 .
+.Ss Access control samples
+The following illustrates a simple
+.Pa faithd.conf
+setting.
+.Bd -literal -offset
+# permit anyone from 3ffe:501:ffff::/48 to use the translator,
+# to connect to the following IPv4 destinations:
+# - any location except 10.0.0.0/8 and 127.0.0.0/8.
+# Permit no other connections.
+#
+3ffe:501:ffff::/48 deny 10.0.0.0/8
+3ffe:501:ffff::/48 deny 127.0.0.0/8
+3ffe:501:ffff::/48 permit 0.0.0.0/0
+.Ed
.Sh RETURN VALUES
.Nm
exits with
@@ -316,20 +384,34 @@ on error.
.%A Kazu Yamamoto
.%T "An IPv6-to-IPv4 transport relay translator"
.%R internet draft
-.%N draft-ietf-ngtrans-tcpudp-relay-01.txt
+.%N draft-ietf-ngtrans-tcpudp-relay-04.txt
.%O work in progress material
.Re
-.Sh SECURITY NOTICE
+.\"
+.Sh HISTORY
+The
+.Nm
+command first appeared in WIDE Hydrangea IPv6 protocol stack kit.
+.\"
+.Pp
+IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack
+was initially integrated into
+.Fx 4.0
+.Sh SECURITY CONSIDERATIONS
It is very insecure to use
.Xr rhosts 5
and other IP-address based authentication, for connections relayed by
.Nm
.Pq and any other TCP relaying services .
.Pp
+Administrators are advised to limit accesses to
.Nm
-itself does not implement access controls, as
-it intends to implement transparent TCP relay services.
-Administrators are advised to filter packets based on IPv6 address.
+using
+.Pa faithd.conf ,
+or by using IPv6 packet filters.
+It is to protect
+.Nm
+service from malicious parties and avoid theft of service/bandwidth.
IPv6 destination address can be limited by
carefully configuring routing entries that points to
.Xr faith 4 ,
@@ -339,12 +421,3 @@ IPv6 source address needs to be filtered by using packet filters.
Documents listed in
.Sx SEE ALSO
have more discussions on this topic.
-.\"
-.Sh HISTORY
-The
-.Nm
-command first appeared in WIDE Hydrangea IPv6 protocol stack kit.
-.Pp
-IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack
-was initially integrated into
-.Fx 4.0
diff --git a/usr.sbin/faithd/faithd.c b/usr.sbin/faithd/faithd.c
index fddf402..2f02da1 100644
--- a/usr.sbin/faithd/faithd.c
+++ b/usr.sbin/faithd/faithd.c
@@ -1,4 +1,4 @@
-/* $KAME: faithd.c,v 1.20 2000/07/01 11:40:45 itojun Exp $ */
+/* $KAME: faithd.c,v 1.39 2001/04/25 11:20:42 itojun Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
@@ -47,6 +47,9 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/ioctl.h>
+#ifdef __FreeBSD__
+#include <libutil.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
@@ -83,6 +86,7 @@
#endif
#include "faithd.h"
+#include "prefix.h"
char *serverpath = NULL;
char *serverarg[MAXARGV + 1];
@@ -101,6 +105,7 @@ static int sockfd = 0;
int dflag = 0;
static int pflag = 0;
static int inetd = 0;
+static char *configfile = NULL;
int main __P((int, char **));
static int inetd_main __P((int, char **));
@@ -115,6 +120,8 @@ static int map4to6 __P((struct sockaddr_in *, struct sockaddr_in6 *));
static void sig_child __P((int));
static void sig_terminate __P((int));
static void start_daemon __P((void));
+static void exit_stderr __P((const char *, ...))
+ __attribute__((__format__(__printf__, 1, 2)));
#ifndef HAVE_GETIFADDRS
static unsigned int if_maxindex __P((void));
#endif
@@ -156,6 +163,11 @@ inetd_main(int argc, char **argv)
const int on = 1;
char sbuf[NI_MAXSERV], snum[NI_MAXSERV];
+ if (config_load(configfile) < 0 && configfile) {
+ exit_failure("could not load config file");
+ /*NOTREACHED*/
+ }
+
if (strrchr(argv[0], '/') == NULL)
snprintf(path, sizeof(path), "%s/%s", DEFAULT_DIR, argv[0]);
else
@@ -166,17 +178,21 @@ inetd_main(int argc, char **argv)
sockfd = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC);
if (sockfd < 0) {
- exit_error("socket(PF_ROUTE): %s", ERRSTR);
+ exit_failure("socket(PF_ROUTE): %s", ERRSTR);
/*NOTREACHED*/
}
#endif
melen = sizeof(me);
- if (getsockname(STDIN_FILENO, (struct sockaddr *)&me, &melen) < 0)
- exit_error("getsockname");
+ if (getsockname(STDIN_FILENO, (struct sockaddr *)&me, &melen) < 0) {
+ exit_failure("getsockname: %s", ERRSTR);
+ /*NOTREACHED*/
+ }
fromlen = sizeof(from);
- if (getpeername(STDIN_FILENO, (struct sockaddr *)&from, &fromlen) < 0)
- exit_error("getpeername");
+ if (getpeername(STDIN_FILENO, (struct sockaddr *)&from, &fromlen) < 0) {
+ exit_failure("getpeername: %s", ERRSTR);
+ /*NOTREACHED*/
+ }
if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0,
sbuf, sizeof(sbuf), NI_NUMERICHOST) == 0)
service = sbuf;
@@ -190,8 +206,10 @@ inetd_main(int argc, char **argv)
snprintf(procname, sizeof(procname), "accepting port %s", snum);
openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON);
- if (argc >= MAXARGV)
+ if (argc >= MAXARGV) {
exit_failure("too many arguments");
+ /*NOTREACHED*/
+ }
serverarg[0] = serverpath = path;
for (i = 1; i < argc; i++)
serverarg[i] = argv[i];
@@ -199,8 +217,10 @@ inetd_main(int argc, char **argv)
error = setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &on,
sizeof(on));
- if (error < 0)
- exit_error("setsockopt(SO_OOBINLINE): %s", ERRSTR);
+ if (error < 0) {
+ exit_failure("setsockopt(SO_OOBINLINE): %s", ERRSTR);
+ /*NOTREACHED*/
+ }
play_child(STDIN_FILENO, (struct sockaddr *)&from);
exit_failure("should not reach here");
@@ -218,11 +238,14 @@ daemon_main(int argc, char **argv)
char *ns;
#endif /* FAITH_NS */
- while ((c = getopt(argc, argv, "dp46")) != -1) {
+ while ((c = getopt(argc, argv, "df:p46")) != -1) {
switch (c) {
case 'd':
dflag++;
break;
+ case 'f':
+ configfile = optarg;
+ break;
case 'p':
pflag++;
break;
@@ -236,12 +259,17 @@ daemon_main(int argc, char **argv)
#endif
default:
usage();
- break;
+ /*NOTREACHED*/
}
}
argc -= optind;
argv += optind;
+ if (config_load(configfile) < 0 && configfile) {
+ exit_failure("could not load config file");
+ /*NOTREACHED*/
+ }
+
#ifdef FAITH_NS
if ((ns = getenv(FAITH_NS)) != NULL) {
struct sockaddr_storage ss;
@@ -266,15 +294,12 @@ daemon_main(int argc, char **argv)
switch (argc) {
case 0:
- serverpath = DEFAULT_PATH;
- serverarg[0] = DEFAULT_NAME;
- serverarg[1] = NULL;
- service = DEFAULT_PORT_NAME;
- break;
+ usage();
+ /*NOTREACHED*/
default:
serverargc = argc - NUMARG;
if (serverargc >= MAXARGV)
- exit_error("too many augments");
+ exit_stderr("too many arguments");
serverpath = malloc(strlen(argv[NUMPRG]) + 1);
strcpy(serverpath, argv[NUMPRG]);
@@ -300,17 +325,17 @@ daemon_main(int argc, char **argv)
hints.ai_protocol = 0;
error = getaddrinfo(NULL, service, &hints, &res);
if (error)
- exit_error("getaddrinfo: %s", gai_strerror(error));
+ exit_stderr("getaddrinfo: %s", gai_strerror(error));
s_wld = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s_wld == -1)
- exit_error("socket: %s", ERRSTR);
+ exit_stderr("socket: %s", ERRSTR);
#ifdef IPV6_FAITH
if (res->ai_family == AF_INET6) {
error = setsockopt(s_wld, IPPROTO_IPV6, IPV6_FAITH, &on, sizeof(on));
if (error == -1)
- exit_error("setsockopt(IPV6_FAITH): %s", ERRSTR);
+ exit_stderr("setsockopt(IPV6_FAITH): %s", ERRSTR);
}
#endif
#ifdef FAITH4
@@ -318,31 +343,31 @@ daemon_main(int argc, char **argv)
if (res->ai_family == AF_INET) {
error = setsockopt(s_wld, IPPROTO_IP, IP_FAITH, &on, sizeof(on));
if (error == -1)
- exit_error("setsockopt(IP_FAITH): %s", ERRSTR);
+ exit_stderr("setsockopt(IP_FAITH): %s", ERRSTR);
}
#endif
#endif /* FAITH4 */
error = setsockopt(s_wld, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if (error == -1)
- exit_error("setsockopt(SO_REUSEADDR): %s", ERRSTR);
+ exit_stderr("setsockopt(SO_REUSEADDR): %s", ERRSTR);
error = setsockopt(s_wld, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on));
if (error == -1)
- exit_error("setsockopt(SO_OOBINLINE): %s", ERRSTR);
+ exit_stderr("setsockopt(SO_OOBINLINE): %s", ERRSTR);
error = bind(s_wld, (struct sockaddr *)res->ai_addr, res->ai_addrlen);
if (error == -1)
- exit_error("bind: %s", ERRSTR);
+ exit_stderr("bind: %s", ERRSTR);
error = listen(s_wld, 5);
if (error == -1)
- exit_error("listen: %s", ERRSTR);
+ exit_stderr("listen: %s", ERRSTR);
#ifdef USE_ROUTE
sockfd = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC);
if (sockfd < 0) {
- exit_error("socket(PF_ROUTE): %s", ERRSTR);
+ exit_stderr("socket(PF_ROUTE): %s", ERRSTR);
/*NOTREACHED*/
}
#endif
@@ -359,7 +384,7 @@ daemon_main(int argc, char **argv)
syslog(LOG_INFO, "Staring faith daemon for %s port", service);
play_service(s_wld);
- /*NOTREACHED*/
+ /* NOTREACHED */
exit(1); /*pacify gcc*/
}
@@ -407,8 +432,10 @@ again:
len = sizeof(srcaddr);
s_src = accept(s_wld, (struct sockaddr *)&srcaddr,
&len);
- if (s_src == -1)
+ if (s_src == -1) {
exit_failure("socket: %s", ERRSTR);
+ /*NOTREACHED*/
+ }
child_pid = fork();
@@ -419,6 +446,7 @@ again:
openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON);
play_child(s_src, (struct sockaddr *)&srcaddr);
exit_failure("should never reach here");
+ /*NOTREACHED*/
} else {
/* parent process */
close(s_src);
@@ -441,6 +469,7 @@ play_child(int s_src, struct sockaddr *srcaddr)
int s_dst, error, hport, nresvport, on = 1;
struct timeval tv;
struct sockaddr *sa4;
+ const struct config *conf;
tv.tv_sec = 1;
tv.tv_usec = 0;
@@ -450,8 +479,10 @@ play_child(int s_src, struct sockaddr *srcaddr)
syslog(LOG_INFO, "accepted a client from %s", src);
error = getsockname(s_src, (struct sockaddr *)&dstaddr6, &len);
- if (error == -1)
+ if (error == -1) {
exit_failure("getsockname: %s", ERRSTR);
+ /*NOTREACHED*/
+ }
getnameinfo((struct sockaddr *)&dstaddr6, len,
dst6, sizeof(dst6), NULL, 0, NI_NUMERICHOST);
@@ -487,7 +518,8 @@ play_child(int s_src, struct sockaddr *srcaddr)
if (!map6to4((struct sockaddr_in6 *)&dstaddr6,
(struct sockaddr_in *)&dstaddr4)) {
close(s_src);
- exit_error("map6to4 failed");
+ exit_failure("map6to4 failed");
+ /*NOTREACHED*/
}
syslog(LOG_INFO, "translating from v6 to v4");
break;
@@ -496,20 +528,35 @@ play_child(int s_src, struct sockaddr *srcaddr)
if (!map4to6((struct sockaddr_in *)&dstaddr6,
(struct sockaddr_in6 *)&dstaddr4)) {
close(s_src);
- exit_error("map4to6 failed");
+ exit_failure("map4to6 failed");
+ /*NOTREACHED*/
}
syslog(LOG_INFO, "translating from v4 to v6");
break;
#endif
default:
close(s_src);
- exit_error("family not supported");
+ exit_failure("family not supported");
/*NOTREACHED*/
}
sa4 = (struct sockaddr *)&dstaddr4;
getnameinfo(sa4, sa4->sa_len,
dst4, sizeof(dst4), NULL, 0, NI_NUMERICHOST);
+
+ conf = config_match(srcaddr, sa4);
+ if (!conf || !conf->permit) {
+ close(s_src);
+ if (conf) {
+ exit_failure("translation to %s not permitted for %s",
+ dst4, prefix_string(&conf->match));
+ /*NOTREACHED*/
+ } else {
+ exit_failure("translation to %s not permitted", dst4);
+ /*NOTREACHED*/
+ }
+ }
+
syslog(LOG_INFO, "the translator is connecting to %s", dst4);
setproctitle("port %s, %s -> %s", service, src, dst4);
@@ -531,31 +578,55 @@ play_child(int s_src, struct sockaddr *srcaddr)
s_dst = socket(sa4->sa_family, SOCK_STREAM, 0);
break;
}
- if (s_dst == -1)
+ if (s_dst < 0) {
exit_failure("socket: %s", ERRSTR);
+ /*NOTREACHED*/
+ }
+
+ if (conf->src.a.ss_family) {
+ if (bind(s_dst, (struct sockaddr *)&conf->src.a,
+ conf->src.a.ss_len) < 0) {
+ exit_failure("bind: %s", ERRSTR);
+ /*NOTREACHED*/
+ }
+ }
error = setsockopt(s_dst, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on));
- if (error == -1)
- exit_error("setsockopt(SO_OOBINLINE): %s", ERRSTR);
+ if (error < 0) {
+ exit_failure("setsockopt(SO_OOBINLINE): %s", ERRSTR);
+ /*NOTREACHED*/
+ }
error = setsockopt(s_src, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
- if (error == -1)
- exit_error("setsockopt(SO_SNDTIMEO): %s", ERRSTR);
+ if (error < 0) {
+ exit_failure("setsockopt(SO_SNDTIMEO): %s", ERRSTR);
+ /*NOTREACHED*/
+ }
error = setsockopt(s_dst, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
- if (error == -1)
- exit_error("setsockopt(SO_SNDTIMEO): %s", ERRSTR);
+ if (error < 0) {
+ exit_failure("setsockopt(SO_SNDTIMEO): %s", ERRSTR);
+ /*NOTREACHED*/
+ }
error = connect(s_dst, sa4, sa4->sa_len);
- if (error == -1)
+ if (error < 0) {
exit_failure("connect: %s", ERRSTR);
+ /*NOTREACHED*/
+ }
switch (hport) {
case FTP_PORT:
ftp_relay(s_src, s_dst);
break;
case RSH_PORT:
+ syslog(LOG_WARNING,
+ "WARINNG: it is insecure to relay rsh port");
rsh_relay(s_src, s_dst);
break;
+ case RLOGIN_PORT:
+ syslog(LOG_WARNING,
+ "WARINNG: it is insecure to relay rlogin port");
+ /*FALLTHROUGH*/
default:
tcp_relay(s_src, s_dst, service);
break;
@@ -581,8 +652,10 @@ faith_prefix(struct sockaddr *dst)
mib[2] = IPPROTO_IPV6;
mib[3] = IPV6CTL_FAITH_PREFIX;
size = sizeof(struct in6_addr);
- if (sysctl(mib, 4, &faith_prefix, &size, NULL, 0) < 0)
- exit_error("sysctl: %s", ERRSTR);
+ if (sysctl(mib, 4, &faith_prefix, &size, NULL, 0) < 0) {
+ exit_failure("sysctl: %s", ERRSTR);
+ /*NOTREACHED*/
+ }
if (memcmp(dst, &faith_prefix,
sizeof(struct in6_addr) - sizeof(struct in_addr) == 0) {
@@ -649,7 +722,7 @@ map6to4(struct sockaddr_in6 *dst6, struct sockaddr_in *dst4)
if (dst4->sin_addr.s_addr == INADDR_ANY
|| dst4->sin_addr.s_addr == INADDR_BROADCAST
- || IN_MULTICAST(dst4->sin_addr.s_addr))
+ || IN_MULTICAST(ntohl(dst4->sin_addr.s_addr)))
return 0;
return 1;
@@ -695,7 +768,7 @@ sig_child(int sig)
pid_t pid;
pid = wait3(&status, WNOHANG, (struct rusage *)0);
- if (pid && status)
+ if (pid && WEXITSTATUS(status))
syslog(LOG_WARNING, "child %d exit status 0x%x", pid, status);
}
@@ -709,18 +782,34 @@ sig_terminate(int sig)
static void
start_daemon(void)
{
- if (daemon(0, 0) == -1)
- exit_error("daemon: %s", ERRSTR);
+#ifdef SA_NOCLDWAIT
+ struct sigaction sa;
+#endif
- if (signal(SIGCHLD, sig_child) == SIG_ERR)
+ if (daemon(0, 0) == -1)
+ exit_stderr("daemon: %s", ERRSTR);
+
+#ifdef SA_NOCLDWAIT
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = sig_child;
+ sa.sa_flags = SA_NOCLDWAIT;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGCHLD, &sa, (struct sigaction *)0);
+#else
+ if (signal(SIGCHLD, sig_child) == SIG_ERR) {
exit_failure("signal CHLD: %s", ERRSTR);
+ /*NOTREACHED*/
+ }
+#endif
- if (signal(SIGTERM, sig_terminate) == SIG_ERR)
+ if (signal(SIGTERM, sig_terminate) == SIG_ERR) {
exit_failure("signal TERM: %s", ERRSTR);
+ /*NOTREACHED*/
+ }
}
-void
-exit_error(const char *fmt, ...)
+static void
+exit_stderr(const char *fmt, ...)
{
va_list ap;
char buf[BUFSIZ];
@@ -977,7 +1066,7 @@ update_myaddrs()
static void
usage()
{
- fprintf(stderr, "usage: %s [-dp] [service [serverpath [serverargs]]]\n",
+ fprintf(stderr, "usage: %s [-dp] [-f conf] service [serverpath [serverargs]]\n",
faithdname);
exit(0);
}
diff --git a/usr.sbin/faithd/faithd.h b/usr.sbin/faithd/faithd.h
index b882aad..8a5021b 100644
--- a/usr.sbin/faithd/faithd.h
+++ b/usr.sbin/faithd/faithd.h
@@ -1,4 +1,4 @@
-/* $KAME: faithd.h,v 1.2 2000/05/31 03:06:07 itojun Exp $ */
+/* $KAME: faithd.h,v 1.6 2000/10/05 22:20:37 itojun Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
@@ -40,12 +40,13 @@ extern int ftp_active __P((int, int, int *, int *));
extern int ftp_passive __P((int, int, int *, int *));
extern void rsh_relay __P((int, int));
extern void rsh_dual_relay __P((int, int));
-extern void exit_error __P((const char *fmt, ...));
-extern void exit_success __P((const char *fmt, ...));
-extern void exit_failure __P((const char *fmt, ...));
+extern void exit_success __P((const char *, ...))
+ __attribute__((__format__(__printf__, 1, 2)));
+extern void exit_failure __P((const char *, ...))
+ __attribute__((__format__(__printf__, 1, 2)));
#define DEFAULT_PORT_NAME "telnet"
-#define DEFAULT_DIR "/usr/local/v6/libexec"
+#define DEFAULT_DIR "/usr/libexec"
#define DEFAULT_NAME "telnetd"
#define DEFAULT_PATH (DEFAULT_DIR "/" DEFAULT_NAME)
diff --git a/usr.sbin/faithd/ftp.c b/usr.sbin/faithd/ftp.c
index e4838eb..b0daa5a 100644
--- a/usr.sbin/faithd/ftp.c
+++ b/usr.sbin/faithd/ftp.c
@@ -1,4 +1,4 @@
-/* $KAME$ */
+/* $KAME: ftp.c,v 1.10 2000/09/14 00:23:39 itojun Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
@@ -514,7 +514,7 @@ passivefail:
error = setsockopt(wport6, IPPROTO_IPV6, IPV6_FAITH,
&on, sizeof(on));
if (error == -1)
- exit_error("setsockopt(IPV6_FAITH): %s", ERRSTR);
+ exit_failure("setsockopt(IPV6_FAITH): %s", ERRSTR);
}
#endif
error = bind(wport6, (struct sockaddr *)sin6, sin6->sin6_len);
@@ -924,6 +924,7 @@ eprtparamfail:
}
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(hostp, portp, &hints, &res);
if (error) {
n = snprintf(sbuf, sizeof(sbuf),
diff --git a/usr.sbin/faithd/prefix.c b/usr.sbin/faithd/prefix.c
new file mode 100644
index 0000000..739ae56
--- /dev/null
+++ b/usr.sbin/faithd/prefix.c
@@ -0,0 +1,360 @@
+/* $KAME: prefix.c,v 1.8 2000/11/24 06:16:56 itojun Exp $ */
+/* $FreeBSD$ */
+
+/*
+ * Copyright (C) 2000 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#ifndef offsetof
+#define offsetof(type, member) ((size_t)(u_long)(&((type *)0)->member))
+#endif
+
+#include "faithd.h"
+#include "prefix.h"
+
+static int prefix_set __P((const char *, struct prefix *, int));
+static struct config *config_load1 __P((const char *));
+#if 0
+static void config_show1 __P((const struct config *));
+static void config_show __P((void));
+#endif
+
+struct config *config_list = NULL;
+#ifdef NI_WITHSCOPEID
+const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
+#else
+const int niflags = NI_NUMERICHOST;
+#endif
+
+static int
+prefix_set(s, prefix, slash)
+ const char *s;
+ struct prefix *prefix;
+ int slash;
+{
+ char *p, *q, *r;
+ struct addrinfo hints, *res = NULL;
+ int max;
+ char *a;
+
+ p = strdup(s);
+ q = strchr(p, '/');
+ if (q) {
+ if (!slash)
+ goto fail;
+ *q++ = '\0';
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(p, "0", &hints, &res))
+ goto fail;
+ if (res->ai_next || res->ai_addrlen > sizeof(prefix->a))
+ goto fail;
+ memcpy(&prefix->a, res->ai_addr, res->ai_addrlen);
+
+ switch (prefix->a.ss_family) {
+ case AF_INET:
+ max = 32;
+ a = (char *)&((struct sockaddr_in *)&prefix->a)->sin_addr;
+ break;
+ case AF_INET6:
+ max = 128;
+ a = (char *)&((struct sockaddr_in6 *)&prefix->a)->sin6_addr;
+ break;
+ default:
+ a = NULL;
+ max = -1;
+ break;
+ }
+
+ if (q) {
+ r = NULL;
+ prefix->l = (int)strtoul(q, &r, 10);
+ if (!*q || *r)
+ goto fail;
+ if (prefix->l < 0 || prefix->l > max)
+ goto fail;
+ } else
+ prefix->l = max;
+
+ if (p)
+ free(p);
+ if (res)
+ freeaddrinfo(res);
+ return 0;
+
+fail:
+ if (p)
+ free(p);
+ if (res)
+ freeaddrinfo(res);
+ return -1;
+}
+
+const char *
+prefix_string(prefix)
+ const struct prefix *prefix;
+{
+ static char buf[NI_MAXHOST + 20];
+ char hbuf[NI_MAXHOST];
+
+ if (getnameinfo((struct sockaddr *)&prefix->a, prefix->a.ss_len, hbuf,
+ sizeof(hbuf), NULL, 0, niflags))
+ return NULL;
+ snprintf(buf, sizeof(buf), "%s/%d", hbuf, prefix->l);
+ return buf;
+}
+
+int
+prefix_match(prefix, sa)
+ const struct prefix *prefix;
+ const struct sockaddr *sa;
+{
+ struct sockaddr_storage a, b;
+ char *pa, *pb;
+ int off, l;
+
+ if (prefix->a.ss_family != sa->sa_family ||
+ prefix->a.ss_len != sa->sa_len)
+ return 0;
+
+ if (prefix->a.ss_len > sizeof(a) || sa->sa_len > sizeof(b))
+ return 0;
+
+ switch (prefix->a.ss_family) {
+ case AF_INET:
+ off = offsetof(struct sockaddr_in, sin_addr);
+ break;
+ case AF_INET6:
+ off = offsetof(struct sockaddr_in6, sin6_addr);
+ break;
+ default:
+ if (memcmp(&prefix->a, sa, prefix->a.ss_len) != 0)
+ return 0;
+ else
+ return 1;
+ }
+
+ memcpy(&a, &prefix->a, prefix->a.ss_len);
+ memcpy(&b, sa, sa->sa_len);
+ l = prefix->l / 8 + (prefix->l % 8 ? 1 : 0);
+
+ /* overrun check */
+ if (off + l > a.ss_len)
+ return 0;
+
+ pa = ((char *)&a) + off;
+ pb = ((char *)&b) + off;
+ if (prefix->l % 8) {
+ pa[prefix->l / 8] &= 0xff00 >> (prefix->l % 8);
+ pb[prefix->l / 8] &= 0xff00 >> (prefix->l % 8);
+ }
+ if (memcmp(pa, pb, l) != 0)
+ return 0;
+ else
+ return 1;
+}
+
+/*
+ * prefix/prefixlen permit/deny prefix/prefixlen [srcaddr]
+ * 3ffe::/16 permit 10.0.0.0/8 10.1.1.1
+ */
+static struct config *
+config_load1(line)
+ const char *line;
+{
+ struct config *conf;
+ char buf[BUFSIZ];
+ char *p;
+ char *token[4];
+ int i;
+
+ if (strlen(line) + 1 > sizeof(buf))
+ return NULL;
+ strlcpy(buf, line, sizeof(buf));
+
+ p = strchr(buf, '\n');
+ if (!p)
+ return NULL;
+ *p = '\0';
+ p = strchr(buf, '#');
+ if (p)
+ *p = '\0';
+ if (strlen(buf) == 0)
+ return NULL;
+
+ p = buf;
+ memset(token, 0, sizeof(token));
+ for (i = 0; i < sizeof(token) / sizeof(token[0]); i++) {
+ token[i] = strtok(p, "\t ");
+ p = NULL;
+ if (token[i] == NULL)
+ break;
+ }
+ /* extra tokens? */
+ if (strtok(p, "\t ") != NULL)
+ return NULL;
+ /* insufficient tokens */
+ switch (i) {
+ case 3:
+ case 4:
+ break;
+ default:
+ return NULL;
+ }
+
+ conf = (struct config *)malloc(sizeof(*conf));
+ if (conf == NULL)
+ return NULL;
+ memset(conf, 0, sizeof(*conf));
+
+ if (strcasecmp(token[1], "permit") == 0)
+ conf->permit = 1;
+ else if (strcasecmp(token[1], "deny") == 0)
+ conf->permit = 0;
+ else {
+ /* invalid keyword is considered as "deny" */
+ conf->permit = 0;
+ }
+
+ if (prefix_set(token[0], &conf->match, 1) < 0)
+ goto fail;
+ if (prefix_set(token[2], &conf->dest, 1) < 0)
+ goto fail;
+ if (token[3]) {
+ if (prefix_set(token[3], &conf->src, 0) < 0)
+ goto fail;
+ }
+
+ return conf;
+
+fail:
+ free(conf);
+ return NULL;
+}
+
+int
+config_load(configfile)
+ const char *configfile;
+{
+ FILE *fp;
+ char buf[BUFSIZ];
+ struct config *conf, *p;
+ struct config sentinel;
+
+ config_list = NULL;
+
+ if (!configfile)
+ configfile = _PATH_PREFIX_CONF;
+ fp = fopen(configfile, "r");
+ if (fp == NULL)
+ return -1;
+
+ p = &sentinel;
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ conf = config_load1(buf);
+ if (conf) {
+ p->next = conf;
+ p = p->next;
+ }
+ }
+ config_list = sentinel.next;
+
+ fclose(fp);
+ return 0;
+}
+
+#if 0
+static void
+config_show1(conf)
+ const struct config *conf;
+{
+ const char *p;
+
+ p = prefix_string(&conf->match);
+ printf("%s", p ? p : "?");
+
+ if (conf->permit)
+ printf(" permit");
+ else
+ printf(" deny");
+
+ p = prefix_string(&conf->dest);
+ printf(" %s", p ? p : "?");
+
+ printf("\n");
+}
+
+static void
+config_show()
+{
+ struct config *conf;
+
+ for (conf = config_list; conf; conf = conf->next)
+ config_show1(conf);
+}
+#endif
+
+const struct config *
+config_match(sa1, sa2)
+ struct sockaddr *sa1, *sa2;
+{
+ static struct config conf;
+ const struct config *p;
+
+ if (sa1->sa_len > sizeof(conf.match.a) ||
+ sa2->sa_len > sizeof(conf.dest.a))
+ return NULL;
+
+ memset(&conf, 0, sizeof(conf));
+ if (!config_list) {
+ conf.permit = 1;
+ memcpy(&conf.match.a, sa1, sa1->sa_len);
+ memcpy(&conf.dest.a, sa2, sa2->sa_len);
+ return &conf;
+ }
+
+ for (p = config_list; p; p = p->next)
+ if (prefix_match(&p->match, sa1) && prefix_match(&p->dest, sa2))
+ return p;
+
+ return NULL;
+}
diff --git a/usr.sbin/faithd/prefix.h b/usr.sbin/faithd/prefix.h
new file mode 100644
index 0000000..3ef56e3
--- /dev/null
+++ b/usr.sbin/faithd/prefix.h
@@ -0,0 +1,52 @@
+/* $KAME: prefix.h,v 1.3 2000/11/19 11:45:38 itojun Exp $ */
+/* $FreeBSD$ */
+
+/*
+ * Copyright (C) 2000 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+struct prefix {
+ struct sockaddr_storage a;
+ int l;
+};
+
+struct config {
+ struct config *next;
+
+ int permit;
+ struct prefix match;
+ struct prefix dest;
+ struct prefix src; /* src to use for outgoing connection */
+};
+
+#define _PATH_PREFIX_CONF "/etc/faithd.conf"
+
+extern const char *prefix_string __P((const struct prefix *));
+extern int prefix_match __P((const struct prefix *, const struct sockaddr *));
+extern int config_load __P((const char *));
+extern const struct config *config_match __P((struct sockaddr *, struct sockaddr *));
diff --git a/usr.sbin/faithd/rsh.c b/usr.sbin/faithd/rsh.c
index 6d81147..4e11d76 100644
--- a/usr.sbin/faithd/rsh.c
+++ b/usr.sbin/faithd/rsh.c
@@ -1,4 +1,4 @@
-/* $KAME$ */
+/* $KAME: rsh.c,v 1.5 2001/02/15 17:28:04 itojun Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
diff --git a/usr.sbin/faithd/tcp.c b/usr.sbin/faithd/tcp.c
index 004686f..c754dfc 100644
--- a/usr.sbin/faithd/tcp.c
+++ b/usr.sbin/faithd/tcp.c
@@ -1,4 +1,4 @@
-/* $KAME$ */
+/* $KAME: tcp.c,v 1.5 2000/09/29 03:48:31 sakane Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
@@ -93,9 +93,9 @@ sig_child(int sig)
pid_t pid;
pid = wait3(&status, WNOHANG, (struct rusage *)0);
- if (pid && status)
+ if (pid && WEXITSTATUS(status))
syslog(LOG_WARNING, "child %d exit status 0x%x", pid, status);
- exit_failure("terminate connection due to child termination");
+ exit_success("terminate connection due to child termination");
}
static void
@@ -195,7 +195,8 @@ relay(int s_rcv, int s_snd, const char *service, int direction)
FD_ZERO(&exceptfds);
fcntl(s_snd, F_SETFD, O_NONBLOCK);
oreadfds = readfds; owritefds = writefds; oexceptfds = exceptfds;
- FD_SET(s_rcv, &readfds); FD_SET(s_rcv, &exceptfds);
+ FD_SET(s_rcv, &readfds);
+ FD_SET(s_rcv, &exceptfds);
oob_exists = 0;
maxfd = (s_rcv > s_snd) ? s_rcv : s_snd;
OpenPOWER on IntegriCloud