diff --git a/usr.sbin/faithd/faithd.8 b/usr.sbin/faithd/faithd.8 index 6cb06778c743..d5a32300c5b4 100644 --- a/usr.sbin/faithd/faithd.8 +++ b/usr.sbin/faithd/faithd.8 @@ -1,5 +1,5 @@ -.\" $NetBSD: faithd.8,v 1.9 2000/07/03 08:37:20 itojun Exp $ -.\" $KAME: faithd.8,v 1.11 2000/07/03 06:35:25 jinmei Exp $ +.\" $NetBSD: faithd.8,v 1.10 2000/07/04 13:28:13 itojun Exp $ +.\" $KAME: faithd.8,v 1.13 2000/07/04 13:18:54 itojun Exp $ .\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. @@ -38,34 +38,18 @@ .Nm .Op Fl dp .Op Ar service Op Ar serverpath Op Ar serverargs +.Nm "" .Sh DESCRIPTION .Nm -provides IPv6/v4 TCP relay for the specified -.Ar service . +provides IPv6-to-IPv4 TCP relay. +.Nm +must be used on an IPv4/v6 dual stack router. .Pp +When .Nm -must be invoked on IPv4/v6 dual stack router. -The router must be configured to capture all the TCP traffic -toward reserved -.Tn IPv6 -address prefix, by using -.Xr route 8 -and -.Xr sysctl 8 -commands. -.Nm -will daemonize itself on invocation. -.Pp -.Nm -will listen to +receives .Tn TCPv6 -port -.Ar service . -If -.Tn TCPv6 -traffic to port -.Ar service -is found, +traffic, .Nm will relay the .Tn TCPv6 @@ -87,20 +71,47 @@ destination address is the traffic will be relayed to IPv4 destination .Li 10.1.1.1 . .Pp +To use +.Nm +translation service, +an IPv6 address prefix must be reserved for mapping IPv4 addresses into. +Kernel must be properly configured to route all the TCP connection +toward the reserved IPv6 address prefix into the +.Xr faith 4 +pseudo interface, by using +.Xr route 8 +command. +Also, +.Xr sysctl 8 +should be used to configure +.Dv net.inet6.ip6.keepfaith +to +.Dv 1 . +.Pp +The router must be configured to capture all the TCP traffic +toward reserved +.Tn IPv6 +address prefix, by using +.Xr route 8 +and +.Xr sysctl 8 +commands. +.Ss Daemon mode +When +.Nm +is invoked as a standalone program, +.Nm +will daemonize itself. +.Nm +will listen to +.Tn TCPv6 +port +.Ar service . If +.Tn TCPv6 +traffic to port .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. +is found, it relays the connection. .Pp Since .Nm @@ -125,22 +136,20 @@ You can also specify .Ar serverargs for the arguments for the local daemon. .Pp -To use +If +.Ar service +is not given, +.Li telnet +is assumed, and .Nm -translation service, -an IPv6 address prefix must be reserved for mapping IPv4 addresses into. -Kernel must be properly configured to route all the TCP connection -toward the reserved IPv6 address prefix into the -.Dv faith -pseudo interface, by using -.Xr route 8 -command. -Also, -.Xr sysctl 8 -should be used to configure -.Dv net.inet6.ip6.keepfaith -to -.Dv 1 . +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 If .Fl d @@ -186,12 +195,50 @@ Inactive sessions will be disconnected in 30 minutes, to avoid stale sessions from chewing up resources. This may be inappropriate for some of the services .Pq should this be configurable? . +.Ss inetd mode +When +.Nm +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. +.Nm +will relay the connection. +Otherwise, +.Nm +will invoke service-specific daemon like +.Xr telnetd 8 , +by using the command argument passed from +.Xr inetd 8 . +.Pp +.Nm +determines operation mode by the local TCP port number, +and enables special protocol handling whenever necessary/possible. +For example, if +.Nm +is invoked via +.Xr inetd 8 +on FTP port, it will operate as a FTP relay. +.Pp +The operation mode requires special support for +.Nm +in +.Xr inetd 8 . .Sh EXAMPLES Before invoking .Nm Ns , .Xr faith 4 interface has to be configured properly. -.Pp +.Bd -literal -offset +# sysctl -w net.inet6.ip6.accept_rtadv=0 +# sysctl -w net.inet6.ip6.forwarding=1 +# sysctl -w net.inet6.ip6.keepfaith=1 +# ifconfig faith0 up +# route add -inet6 3ffe:501:4819:ffff:: -prefixlen 96 ::1 +# route change -inet6 3ffe:501:4819:ffff:: -prefixlen 96 -ifp faith0 +.Ed +.Ss Daemon mode samples To translate .Li telnet service, and provide no local telnet service, invoke @@ -206,7 +253,7 @@ If you would like to provide local telnet service via .Xr telnetd 8 on .Pa /usr/libexec/telnetd , -user the following command line: +use the following command line: .Bd -literal -offset # faithd telnet /usr/libexec/telnetd telnetd .Ed @@ -216,7 +263,10 @@ If you would like to pass extra arguments to the local daemon: # faithd ftpd /usr/libexec/ftpd ftpd -l .Ed .Pp -Here are some other examples: +Here are some other examples. +You may need +.Fl p +to translate rsh/rlogin services. .Bd -literal -offset # faithd sshd # faithd login /usr/libexec/rlogin rlogind @@ -227,6 +277,29 @@ However, you should be careful when translating rlogin or rsh connections. See .Sx SECURITY NOTICE for more details. +.Ss inetd mode samples +Add the following lines into +.Xr inetd.conf 5 . +.\"Syntax may vary depending upon your operating system. +.Bd -literal -offset +telnet stream faith/tcp6 nowait root faithd telnetd +ftp stream faith/tcp6 nowait root faithd ftpd -l +ssh stream faith/tcp6 nowait root faithd /usr/pkg/bin/sshd -i +.Ed +.Pp +.Xr inetd 8 +will open listening sockets with enabling kernel TCP relay support. +Whenever connection comes in, +.Nm +will be invoked by +.Xr inetd 8 . +If it the connection endpoint is in the reserved IPv6 address prefix. +.Nm +will relay the connection. +Otherwise, +.Nm +will invoke service-specific daemon like +.Xr telnetd 8 . .Sh RETURN VALUES .Nm exits with @@ -268,6 +341,8 @@ IPv6 source address needs to be filtered by using packet filters. Documents listed in .Sx SEE ALSO have more discussions on this topic. +Under inetd mode of operation, you can limit the connection source by using +.Xr hosts.allow 5 . .\" .Sh HISTORY The diff --git a/usr.sbin/faithd/faithd.c b/usr.sbin/faithd/faithd.c index 5cb1938cc6e2..6da60081143d 100644 --- a/usr.sbin/faithd/faithd.c +++ b/usr.sbin/faithd/faithd.c @@ -1,5 +1,5 @@ -/* $NetBSD: faithd.c,v 1.11 2000/06/29 01:24:11 itojun Exp $ */ -/* $KAME: faithd.c,v 1.19 2000/06/29 01:17:29 itojun Exp $ */ +/* $NetBSD: faithd.c,v 1.12 2000/07/04 13:28:13 itojun Exp $ */ +/* $KAME: faithd.c,v 1.21 2000/07/04 03:18:35 itojun Exp $ */ /* * Copyright (C) 1997 and 1998 WIDE Project. @@ -102,8 +102,11 @@ static int sockfd = 0; #endif int dflag = 0; static int pflag = 0; +static int inetd = 0; int main __P((int, char **)); +static int inetd_main __P((int, char **)); +static int daemon_main __P((int, char **)); static void play_service __P((int)); static void play_child __P((int, struct sockaddr *)); static int faith_prefix __P((struct sockaddr *)); @@ -123,15 +126,8 @@ static void update_myaddrs __P((void)); static void usage __P((void)); int -main(int argc, char *argv[]) +main(int argc, char **argv) { - struct addrinfo hints, *res; - int s_wld, error, i, serverargc, on = 1; - int family = AF_INET6; - int c; -#ifdef FAITH_NS - char *ns; -#endif /* FAITH_NS */ /* * Initializing stuff @@ -143,6 +139,87 @@ main(int argc, char *argv[]) else faithdname = argv[0]; + if (strcmp(faithdname, "faithd") != 0) { + inetd = 1; + return inetd_main(argc, argv); + } else + return daemon_main(argc, argv); +} + +static int +inetd_main(int argc, char **argv) +{ + char path[MAXPATHLEN]; + struct sockaddr_storage me; + struct sockaddr_storage from; + int melen, fromlen; + int i; + int error; + const int on = 1; + char sbuf[NI_MAXSERV], snum[NI_MAXSERV]; + + if (strrchr(argv[0], '/') == NULL) + snprintf(path, sizeof(path), "%s/%s", DEFAULT_DIR, argv[0]); + else + snprintf(path, sizeof(path), "%s", argv[0]); + +#ifdef USE_ROUTE + grab_myaddrs(); + + sockfd = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC); + if (sockfd < 0) { + exit_error("socket(PF_ROUTE): %s", ERRSTR); + /*NOTREACHED*/ + } +#endif + + melen = sizeof(me); + if (getsockname(STDIN_FILENO, (struct sockaddr *)&me, &melen) < 0) + exit_error("getsockname"); + fromlen = sizeof(from); + if (getpeername(STDIN_FILENO, (struct sockaddr *)&from, &fromlen) < 0) + exit_error("getpeername"); + if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0, + sbuf, sizeof(sbuf), NI_NUMERICHOST) == 0) + service = sbuf; + else + service = DEFAULT_PORT_NAME; + if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0, + snum, sizeof(snum), NI_NUMERICHOST) != 0) + snprintf(snum, sizeof(snum), "?"); + + snprintf(logname, sizeof(logname), "faithd %s", snum); + snprintf(procname, sizeof(procname), "accepting port %s", snum); + openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); + + if (argc >= MAXARGV) + exit_failure("too many augments"); + serverarg[0] = serverpath = path; + for (i = 1; i < argc; i++) + serverarg[i] = argv[i]; + serverarg[i] = NULL; + + error = setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &on, + sizeof(on)); + if (error < 0) + exit_error("setsockopt(SO_OOBINLINE): %s", ERRSTR); + + play_child(STDIN_FILENO, (struct sockaddr *)&from); + exit_failure("should not reach here"); + return 0; /*dummy!*/ +} + +static int +daemon_main(int argc, char **argv) +{ + struct addrinfo hints, *res; + int s_wld, error, i, serverargc, on = 1; + int family = AF_INET6; + int c; +#ifdef FAITH_NS + char *ns; +#endif /* FAITH_NS */ + while ((c = getopt(argc, argv, "dp46")) != -1) { switch (c) { case 'd': @@ -198,7 +275,7 @@ main(int argc, char *argv[]) break; default: serverargc = argc - NUMARG; - if (serverargc > MAXARGV) + if (serverargc >= MAXARGV) exit_error("too many augments"); serverpath = malloc(strlen(argv[NUMPRG]) + 1); @@ -388,10 +465,12 @@ play_child(int s_src, struct sockaddr *srcaddr) * Local service */ syslog(LOG_INFO, "executing local %s", serverpath); - dup2(s_src, 0); - close(s_src); - dup2(0, 1); - dup2(0, 2); + if (!inetd) { + dup2(s_src, 0); + close(s_src); + dup2(0, 1); + dup2(0, 2); + } execv(serverpath, serverarg); syslog(LOG_ERR, "execv %s: %s", serverpath, ERRSTR); _exit(EXIT_FAILURE); diff --git a/usr.sbin/faithd/faithd.h b/usr.sbin/faithd/faithd.h index c5a1dafaf70f..83e4f688d2ee 100644 --- a/usr.sbin/faithd/faithd.h +++ b/usr.sbin/faithd/faithd.h @@ -1,5 +1,5 @@ -/* $NetBSD: faithd.h,v 1.3 2000/05/31 03:18:02 itojun Exp $ */ -/* $KAME: faithd.h,v 1.2 2000/05/31 03:06:07 itojun Exp $ */ +/* $NetBSD: faithd.h,v 1.4 2000/07/04 13:28:13 itojun Exp $ */ +/* $KAME: faithd.h,v 1.3 2000/07/01 11:40:45 itojun Exp $ */ /* * Copyright (C) 1997 and 1998 WIDE Project. @@ -44,8 +44,9 @@ extern void exit_success __P((const char *fmt, ...)); extern void exit_failure __P((const char *fmt, ...)); #define DEFAULT_PORT_NAME "telnet" -#define DEFAULT_PATH "/usr/libexec/telnetd" +#define DEFAULT_DIR "/usr/libexec" #define DEFAULT_NAME "telnetd" +#define DEFAULT_PATH (DEFAULT_DIR "/" DEFAULT_NAME) #define FTP_PORT 21 #define RLOGIN_PORT 513