diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2000-01-04 00:08:02 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2000-01-04 00:08:02 +0000 |
commit | 573f387ec119d78734faf0f7bcb79a160ba603b7 (patch) | |
tree | 4fc970b6fb7642a6058e608f9887735328a35a7c /usr.bin/ssh/ssh.c | |
parent | b2e854e4813087bf22e3c8885da9db9fef77ce3b (diff) |
ipv6 support: mostly gethostbyname->getaddrinfo/getnameinfo, new features:
sshd allows multiple ListenAddress and Port options. note that libwrap is
not IPv6-ready. (based on patches from <kick@kyoto.wide.ad.jp> and
fujiwara@rcac.tdi.co.jp)
Diffstat (limited to 'usr.bin/ssh/ssh.c')
-rw-r--r-- | usr.bin/ssh/ssh.c | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c index 008d1b88f70..e4d48b5438d 100644 --- a/usr.bin/ssh/ssh.c +++ b/usr.bin/ssh/ssh.c @@ -11,7 +11,7 @@ */ #include "includes.h" -RCSID("$Id: ssh.c,v 1.36 1999/12/12 19:20:03 markus Exp $"); +RCSID("$Id: ssh.c,v 1.37 2000/01/04 00:08:00 markus Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -21,6 +21,10 @@ RCSID("$Id: ssh.c,v 1.36 1999/12/12 19:20:03 markus Exp $"); #include "readconf.h" #include "uidswap.h" +/* Flag indicating whether IPv4 or IPv6. This can be set on the command line. + Default value is AF_UNSPEC means both IPv4 and IPv6. */ +int IPv4or6 = AF_UNSPEC; + /* Flag indicating whether debug mode is on. This can be set on the command line. */ int debug_flag = 0; @@ -53,7 +57,7 @@ Options options; char *host; /* socket address the host resolves to */ -struct sockaddr_in hostaddr; +struct sockaddr_storage hostaddr; /* * Flag to indicate that we have received a window change signal which has @@ -108,6 +112,8 @@ usage() fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); fprintf(stderr, " -C Enable compression.\n"); fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); + fprintf(stderr, " -4 Use IPv4 only.\n"); + fprintf(stderr, " -6 Use IPv6 only.\n"); fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n"); exit(1); } @@ -244,6 +250,14 @@ main(int ac, char **av) optarg = NULL; } switch (opt) { + case '4': + IPv4or6 = AF_INET; + break; + + case '6': + IPv4or6 = AF_INET6; + break; + case 'n': stdin_null_flag = 1; break; @@ -341,8 +355,10 @@ main(int ac, char **av) break; case 'R': - if (sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, - &fwd_host_port) != 3) { + if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, + &fwd_host_port) != 3 && + sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, + &fwd_host_port) != 3) { fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); usage(); /* NOTREACHED */ @@ -351,8 +367,10 @@ main(int ac, char **av) break; case 'L': - if (sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, - &fwd_host_port) != 3) { + if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, + &fwd_host_port) != 3 && + sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, + &fwd_host_port) != 3) { fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); usage(); /* NOTREACHED */ @@ -465,14 +483,17 @@ main(int ac, char **av) /* Find canonic host name. */ if (strchr(host, '.') == 0) { - struct hostent *hp = gethostbyname(host); - if (hp != 0) { - if (strchr(hp->h_name, '.') != 0) - host = xstrdup(hp->h_name); - else if (hp->h_aliases != 0 - && hp->h_aliases[0] != 0 - && strchr(hp->h_aliases[0], '.') != 0) - host = xstrdup(hp->h_aliases[0]); + struct addrinfo hints; + struct addrinfo *ai = NULL; + int errgai; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_CANONNAME; + errgai = getaddrinfo(host, NULL, &hints, &ai); + if (errgai == 0) { + if (ai->ai_canonname != NULL) + host = xstrdup(ai->ai_canonname); + freeaddrinfo(ai); } } /* Disable rhosts authentication if not running as root. */ @@ -579,7 +600,7 @@ main(int ac, char **av) /* Log into the remote system. This never returns if the login fails. */ ssh_login(host_private_key_loaded, host_private_key, - host, &hostaddr, original_real_uid); + host, (struct sockaddr *)&hostaddr, original_real_uid); /* We no longer need the host private key. Clear it now. */ if (host_private_key_loaded) |