summaryrefslogtreecommitdiff
path: root/usr.sbin/faithd/faithd.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/faithd/faithd.c')
-rw-r--r--usr.sbin/faithd/faithd.c179
1 files changed, 132 insertions, 47 deletions
diff --git a/usr.sbin/faithd/faithd.c b/usr.sbin/faithd/faithd.c
index 640b6534f60..b5673d3e8e3 100644
--- a/usr.sbin/faithd/faithd.c
+++ b/usr.sbin/faithd/faithd.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: faithd.c,v 1.7 2000/07/05 17:23:13 deraadt Exp $ */
-/* $KAME: faithd.c,v 1.18 2000/05/31 03:06:07 itojun Exp $ */
+/* $OpenBSD: faithd.c,v 1.8 2000/09/16 10:33:45 itojun Exp $ */
+/* $KAME: faithd.c,v 1.29 2000/09/12 05:20:35 itojun Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
@@ -34,7 +34,7 @@
* User level translator from IPv6 to IPv4.
*
* Usage: faithd [<port> <progpath> <arg1(progname)> <arg2> ...]
- * e.g. faithd telnet /usr/local/v6/sbin/telnetd telnetd
+ * e.g. faithd telnet /usr/libexec/telnetd telnetd
*/
#define HAVE_GETIFADDRS
@@ -102,8 +102,13 @@ static int sockfd = 0;
#endif
int dflag = 0;
static int pflag = 0;
+static int inetd = 0;
int main __P((int, char **));
+#if 0
+static int inetd_main __P((int, char **));
+#endif
+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 *));
@@ -114,6 +119,7 @@ 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 *, ...));
#ifndef HAVE_GETIFADDRS
static unsigned int if_maxindex __P((void));
#endif
@@ -123,15 +129,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 +142,93 @@ main(int argc, char *argv[])
else
faithdname = argv[0];
+#if 0
+ if (strcmp(faithdname, "faithd") != 0) {
+ inetd = 1;
+ return inetd_main(argc, argv);
+ } else
+ return daemon_main(argc, argv);
+#else
+ return daemon_main(argc, argv);
+#endif
+}
+
+#if 0
+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_failure("socket(PF_ROUTE): %s", ERRSTR);
+ /*NOTREACHED*/
+ }
+#endif
+
+ melen = sizeof(me);
+ if (getsockname(STDIN_FILENO, (struct sockaddr *)&me, &melen) < 0)
+ exit_failure("getsockname");
+ fromlen = sizeof(from);
+ if (getpeername(STDIN_FILENO, (struct sockaddr *)&from, &fromlen) < 0)
+ exit_failure("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 arguments");
+ 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_failure("setsockopt(SO_OOBINLINE): %s", ERRSTR);
+
+ play_child(STDIN_FILENO, (struct sockaddr *)&from);
+ exit_failure("should not reach here");
+ return 0; /*dummy!*/
+}
+#endif
+
+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':
@@ -161,7 +247,7 @@ main(int argc, char *argv[])
#endif
default:
usage();
- break;
+ /*NOTREACHED*/
}
}
argc -= optind;
@@ -191,15 +277,12 @@ 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");
+ if (serverargc >= MAXARGV)
+ exit_stderr("too many arguments");
serverpath = malloc(strlen(argv[NUMPRG]) + 1);
strcpy(serverpath, argv[NUMPRG]);
@@ -225,17 +308,17 @@ 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
@@ -243,31 +326,31 @@ 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
@@ -284,7 +367,7 @@ main(int argc, char *argv[])
syslog(LOG_INFO, "Staring faith daemon for %s port", service);
play_service(s_wld);
- /*NOTRECHED*/
+ /* NOTREACHED */
exit(1); /*pacify gcc*/
}
@@ -388,10 +471,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);
@@ -410,7 +495,7 @@ 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");
}
syslog(LOG_INFO, "translating from v6 to v4");
break;
@@ -419,14 +504,14 @@ 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");
}
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*/
}
@@ -459,14 +544,14 @@ play_child(int s_src, struct sockaddr *srcaddr)
error = setsockopt(s_dst, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on));
if (error == -1)
- exit_error("setsockopt(SO_OOBINLINE): %s", ERRSTR);
+ exit_failure("setsockopt(SO_OOBINLINE): %s", ERRSTR);
error = setsockopt(s_src, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
if (error == -1)
- exit_error("setsockopt(SO_SNDTIMEO): %s", ERRSTR);
+ exit_failure("setsockopt(SO_SNDTIMEO): %s", ERRSTR);
error = setsockopt(s_dst, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
if (error == -1)
- exit_error("setsockopt(SO_SNDTIMEO): %s", ERRSTR);
+ exit_failure("setsockopt(SO_SNDTIMEO): %s", ERRSTR);
error = connect(s_dst, sa4, sa4->sa_len);
if (error == -1)
@@ -505,7 +590,7 @@ faith_prefix(struct sockaddr *dst)
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);
+ exit_failure("sysctl: %s", ERRSTR);
if (memcmp(dst, &faith_prefix,
sizeof(struct in6_addr) - sizeof(struct in_addr) == 0) {
@@ -572,7 +657,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;
@@ -618,7 +703,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);
}
@@ -633,7 +718,7 @@ static void
start_daemon(void)
{
if (daemon(0, 0) == -1)
- exit_error("daemon: %s", ERRSTR);
+ exit_stderr("daemon: %s", ERRSTR);
if (signal(SIGCHLD, sig_child) == SIG_ERR)
exit_failure("signal CHLD: %s", ERRSTR);
@@ -642,8 +727,8 @@ start_daemon(void)
exit_failure("signal TERM: %s", ERRSTR);
}
-void
-exit_error(const char *fmt, ...)
+static void
+exit_stderr(const char *fmt, ...)
{
va_list ap;
char buf[BUFSIZ];
@@ -651,7 +736,7 @@ exit_error(const char *fmt, ...)
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- fprintf(stderr, "%s\n", buf);
+ fprintf(stderr, "%s", buf);
exit(EXIT_FAILURE);
}
@@ -900,7 +985,7 @@ update_myaddrs()
static void
usage()
{
- fprintf(stderr, "usage: %s [-dp] [service [serverpath [serverargs]]]\n",
+ fprintf(stderr, "usage: %s [-dp] service [serverpath [serverargs]]\n",
faithdname);
exit(0);
}