X-Git-Url: https://git.distorted.org.uk/~mdw/tripe/blobdiff_plain/067aa5f013dd6108e81c1df0c2ed19491802bc69..4a3882945f605704ede113a9fe98cd19a92363a7:/server/tripe.c diff --git a/server/tripe.c b/server/tripe.c index d50757bc..b8438857 100644 --- a/server/tripe.c +++ b/server/tripe.c @@ -91,6 +91,8 @@ Options:\n\ -u, --usage Display pointless usage message.\n\ --tunnels Display IP tunnel drivers and exit.\n\ \n\ +-4, --ipv4 Transport over IPv4 only.\n\ +-6, --ipv6 Transport over IPv6 only.\n\ -D, --daemon Run in the background.\n\ -F, --foreground Quit when stdin reports end-of-file.\n\ -d, --directory=DIR Switch to directory DIR [default " CONFIGDIR "].\n\ @@ -119,11 +121,11 @@ int main(int argc, char *argv[]) int csockmode = 0600; const char *dir = CONFIGDIR; const char *p; - unsigned port = TRIPE_PORT; - struct in_addr baddr = { INADDR_ANY }; + const char *bindhost = 0, *bindsvc = STR(TRIPE_PORT); + struct addrinfo aihint = { 0 }, *ailist; unsigned f = 0; int i; - int selerr = 0; + int err, selerr = 0; unsigned af; struct timeval tv; uid_t u = -1; @@ -141,6 +143,7 @@ int main(int argc, char *argv[]) if ((p = getenv("TRIPESOCK")) != 0) csock = p; tun_default = tunnels[0]; + aihint.ai_family = AF_UNSPEC; for (;;) { static const struct option opts[] = { @@ -149,6 +152,8 @@ int main(int argc, char *argv[]) { "usage", 0, 0, 'u' }, { "tunnels", 0, 0, '0' }, + { "ipv4", 0, 0, '4' }, + { "ipv6", 0, 0, '6' }, { "daemon", 0, 0, 'D' }, { "foreground", 0, 0, 'F' }, { "uid", OPTF_ARGREQ, 0, 'U' }, @@ -171,7 +176,7 @@ int main(int argc, char *argv[]) { 0, 0, 0, 0 } }; - i = mdwopt(argc, argv, "hvuDFU:G:b:n:p:d:k:K:t:a:m:" T("T:"), + i = mdwopt(argc, argv, "hvu46DFU:G:b:n:p:d:k:K:t:a:m:" T("T:"), opts, 0, 0, 0); if (i < 0) break; @@ -186,6 +191,12 @@ int main(int argc, char *argv[]) usage(stdout); exit(0); + case '4': + aihint.ai_family = AF_INET; + break; + case '6': + aihint.ai_family = AF_INET6; + break; case 'D': f |= f_daemon; break; @@ -199,25 +210,12 @@ int main(int argc, char *argv[]) f |= f_foreground; break; - case 'b': { - struct hostent *h = gethostbyname(optarg); - if (!h) - die(EXIT_FAILURE, "unknown host name `%s'", optarg); - memcpy(&baddr, h->h_addr, sizeof(struct in_addr)); - } break; - case 'p': { - char *p; - unsigned long i = strtoul(optarg, &p, 0); - if (*p) { - struct servent *s = getservbyname(optarg, "udp"); - if (!s) - die(EXIT_FAILURE, "unknown service name `%s'", optarg); - i = ntohs(s->s_port); - } - if (i >= 65536) - die(EXIT_FAILURE, "bad port number %lu", i); - port = i; - } break; + case 'b': + bindhost = optarg; + break; + case 'p': + bindsvc = optarg; + break; case 'n': { int i; for (i = 0;; i++) { @@ -273,6 +271,17 @@ int main(int argc, char *argv[]) if (!(~f & (f_daemon | f_foreground))) die(EXIT_FAILURE, "foreground operation for a daemon is silly"); + aihint.ai_protocol = IPPROTO_UDP; + aihint.ai_socktype = SOCK_DGRAM; + aihint.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + if ((err = getaddrinfo(bindhost, bindsvc, &aihint, &ailist)) != 0) { + die(EXIT_FAILURE, "couldn't resolve hostname %c%s%c, port `%s': %s", + bindhost ? '`' : '<', + bindhost ? bindhost : "nil", + bindhost ? '\'' : '>', + bindsvc, gai_strerror(err)); + } + if (chdir(dir)) { die(EXIT_FAILURE, "can't set current directory to `%s': %s", dir, strerror(errno)); @@ -285,7 +294,7 @@ int main(int argc, char *argv[]) signal(SIGPIPE, SIG_IGN); for (i = 0; tunnels[i]; i++) tunnels[i]->init(); - p_init(baddr, port); + p_init(ailist); freeaddrinfo(ailist); if (!(f & f_daemon)) { af = AF_WARN; #ifndef NTRACE