diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 1999-12-11 09:08:10 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 1999-12-11 09:08:10 +0000 |
commit | 940de116193b0bb58e1f997e389620cdf0e3e4c9 (patch) | |
tree | 5f7900b5d12fe6e648e8ab6afa5ff5a885694498 | |
parent | 69769019608a9abf3cf9e3adf079ff14cc278787 (diff) |
IPv6/IPv4 dual stack support. uses getaddrinfo() and getnameinfo()
throughout the code so please look at it with care (for auditing).
XXX source routing is not available for IPv6
(even before I modify, it was not available for IPv4 anyways)
-rw-r--r-- | usr.bin/telnet/commands.c | 247 | ||||
-rw-r--r-- | usr.bin/telnet/telnet.1 | 4 | ||||
-rw-r--r-- | usr.bin/telnet/telnet_locl.h | 4 |
3 files changed, 78 insertions, 177 deletions
diff --git a/usr.bin/telnet/commands.c b/usr.bin/telnet/commands.c index 8b1386b8a3f..6433aa4552d 100644 --- a/usr.bin/telnet/commands.c +++ b/usr.bin/telnet/commands.c @@ -1,4 +1,4 @@ -/* $OpenBSD: commands.c,v 1.22 1999/12/07 01:10:29 deraadt Exp $ */ +/* $OpenBSD: commands.c,v 1.23 1999/12/11 09:08:08 itojun Exp $ */ /* $NetBSD: commands.c,v 1.14 1996/03/24 22:03:48 jtk Exp $ */ /* @@ -2266,7 +2266,8 @@ tn(argc, argv) int argc; char *argv[]; { - register struct hostent *host = 0, *alias = 0; + struct addrinfo hints, *res, *res0; + int error; #if defined(AF_INET6) struct sockaddr_in6 sin6; #endif @@ -2281,6 +2282,7 @@ tn(argc, argv) char *srp = 0; int srlen; #endif + int retry; char *cmd, *hostp = 0, *portp = 0, *user = 0, *aliasp = 0; int family, port; @@ -2359,70 +2361,28 @@ tn(argc, argv) } else { abort(); } - } else { -#endif - memset (&sin, 0, sizeof(sin)); -#if defined(HAVE_INET_PTON) && defined(AF_INET6) - memset (&sin6, 0, sizeof(sin6)); - - if(inet_pton(AF_INET6, hostp, &sin6.sin6_addr)) { - sin6.sin6_family = family = AF_INET6; - sa = (struct sockaddr *)&sin6; - sa_size = sizeof(sin6); - strcpy(_hostname, hostp); - hostname =_hostname; - } else -#endif - if(inet_aton(hostp, &sin.sin_addr)){ - sin.sin_family = family = AF_INET; - sa = (struct sockaddr *)&sin; - sa_size = sizeof(sin); - strcpy(_hostname, hostp); - hostname = _hostname; - } else { -#ifdef HAVE_GETHOSTBYNAME2 - host = gethostbyname2(hostp, AF_INET6); - if(host == NULL) - host = gethostbyname2(hostp, AF_INET); -#else - host = gethostbyname(hostp); -#endif - if (host) { - strncpy(_hostname, host->h_name, sizeof(_hostname)); - family = host->h_addrtype; - - switch(family) { - case AF_INET: - memset(&sin, 0, sizeof(sin)); - sa_size = sizeof(sin); - sa = (struct sockaddr *)&sin; - sin.sin_family = family; - sin.sin_addr = *((struct in_addr *)(*host->h_addr_list)); - break; -#if defined(AF_INET6) && defined(HAVE_STRUCT_SOCKADDR_IN6) - case AF_INET6: - memset(&sin6, 0, sizeof(sin6)); - sa_size = sizeof(sin6); - sa = (struct sockaddr *)&sin6; - sin6.sin6_family = family; - sin6.sin6_addr = *((struct in6_addr *)(*host->h_addr_list)); - break; + } else #endif - default: - fprintf(stderr, "Bad address family: %d\n", family); - return 0; - } - - _hostname[sizeof(_hostname)-1] = '\0'; - hostname = _hostname; - } else { - herror(hostp); - return 0; - } - } -#if defined(IP_OPTIONS) && defined(IPPROTO_IP) + { + hostname = hostp; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + if (portp == NULL) { + portp = "telnet"; + } else if (*portp == '-') { + portp++; + telnetport = 1; + } + error = getaddrinfo(hostp, portp, &hints, &res0); + if (error) { + warn("%s: %s", hostp, gai_strerror(error)); + herror(hostp); + return 0; + } } -#endif +#if 0 if (portp) { if (*portp == '-') { portp++; @@ -2452,76 +2412,51 @@ tn(argc, argv) } telnetport = 1; } - switch(family) { - case AF_INET: - sin.sin_port = port; - printf("Trying %s...\r\n", inet_ntoa(sin.sin_addr)); - break; -#if defined(AF_INET6) && defined(HAVE_STRUCT_SOCKADDR_IN6) - case AF_INET6: { -#ifndef INET6_ADDRSTRLEN -#define INET6_ADDRSTRLEN 46 #endif - char buf[INET6_ADDRSTRLEN]; - - sin6.sin6_port = port; -#ifdef HAVE_INET_NTOP - printf("Trying %s...\r\n", inet_ntop(AF_INET6, - &sin6.sin6_addr, - buf, - sizeof(buf))); -#endif - break; - } -#endif - default: - abort(); - } + net = -1; + retry = 0; + for (res = res0; res; res = res->ai_next) { + if (1 /* retry */) { + char hbuf[MAXHOSTNAMELEN]; - do { - net = socket(family, SOCK_STREAM, 0); - if (net < 0) { - perror("telnet: socket"); - return 0; + getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), + NULL, 0, NI_NUMERICHOST); + printf("Trying %s...\r\n", hbuf); } + net = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (net < 0) + continue; + if (aliasp) { - memset ((caddr_t)&ladr, 0, sizeof (ladr)); - temp = inet_addr(aliasp); - if (temp != INADDR_NONE) { - ladr.sin_addr.s_addr = temp; - ladr.sin_family = AF_INET; - alias = gethostbyaddr((char *)&temp, sizeof(temp), AF_INET); - } else { - alias = gethostbyname(aliasp); - if (alias) { - ladr.sin_family = alias->h_addrtype; -#if defined(h_addr) /* In 4.3, this is a #define */ - memmove((caddr_t)&ladr.sin_addr, - alias->h_addr_list[0], alias->h_length); -#else /* defined(h_addr) */ - memmove((caddr_t)&ladr.sin_addr, alias->h_addr, - alias->h_length); -#endif /* defined(h_addr) */ - } else { - herror(aliasp); - return 0; - } + struct addrinfo ahints, *ares; + + memset(&ahints, 0, sizeof(ahints)); + ahints.ai_family = PF_UNSPEC; + ahints.ai_socktype = SOCK_STREAM; + ahints.ai_flags = AI_PASSIVE; + error = getaddrinfo(aliasp, "0", &ahints, &ares); + if (error) { + warn("%s: %s", aliasp, gai_strerror(error)); + close(net); + freeaddrinfo(ares); + continue; } - ladr.sin_port = htons(0); - - if (bind (net, (struct sockaddr *)&ladr, sizeof(ladr)) < 0) { - perror(aliasp);; + if (bind(net, res->ai_addr, res->ai_addrlen) < 0) { + perror(aliasp); (void) close(net); /* dump descriptor */ - return 0; + freeaddrinfo(ares); + continue; } - } - #if defined(IP_OPTIONS) && defined(IPPROTO_IP) - if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) + freeaddrinfo(ares); + } +#if defined(IP_OPTIONS) && defined(IPPROTO_IP) + if (srp && res->ai_family == AF_INET + && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) perror("setsockopt (IP_OPTIONS)"); #endif #if defined(IPPROTO_IP) && defined(IP_TOS) - { + if (res->ai_family == AF_INET) { # if defined(HAS_GETTOS) struct tosent *tp; if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) @@ -2541,63 +2476,29 @@ tn(argc, argv) perror("setsockopt (SO_DEBUG)"); } - if (connect(net, sa, sa_size) < 0) { - int retry = 0; + if (connect(net, res->ai_addr, res->ai_addrlen) < 0) { + char hbuf[MAXHOSTNAMELEN]; - if (host && host->h_addr_list[1]) { - int oerrno = errno; - retry = 1; - - switch(family) { - case AF_INET : - fprintf(stderr, "telnet: connect to address %s: ", - inet_ntoa(sin.sin_addr)); - sin.sin_addr = *((struct in_addr *)(*++host->h_addr_list)); - break; -#if defined(AF_INET6) && defined(HAVE_STRUCT_SOCKADDR_IN6) - case AF_INET6: { - char buf[INET6_ADDRSTRLEN]; - - fprintf(stderr, "telnet: connect to address %s: ", - inet_ntop(AF_INET6, &sin6.sin6_addr, buf, - sizeof(buf))); - sin6.sin6_addr = *((struct in6_addr *)(*++host->h_addr_list)); - break; - } -#endif - default: - abort(); - } - - errno = oerrno; - perror(NULL); + getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), + NULL, 0, NI_NUMERICHOST); + fprintf(stderr, "telnet: connect to address %s: ", hbuf); - switch(family) { - case AF_INET : - printf("Trying %s...\r\n", inet_ntoa(sin.sin_addr)); - break; -#if defined(AF_INET6) && defined(HAVE_STRUCT_SOCKADDR_IN6) - case AF_INET6: { - printf("Trying %s...\r\n", inet_ntop(AF_INET6, - &sin6.sin6_addr, - buf, - sizeof(buf))); - break; - } -#endif - } - - (void) NetClose(net); - continue; - } - perror("telnet: Unable to connect to remote host"); - return 0; + close(net); + net = -1; + retry++; + continue; } + connected++; #if defined(AUTHENTICATION) || defined(ENCRYPTION) auth_encrypt_connect(connected); #endif /* defined(AUTHENTICATION) */ - } while (connected == 0); + break; + } + freeaddrinfo(res0); + if (net < 0) { + return 0; + } cmdrc(hostp, hostname); if (autologin && user == NULL) { struct passwd *pw; diff --git a/usr.bin/telnet/telnet.1 b/usr.bin/telnet/telnet.1 index 21eb941c68a..4fc389c485a 100644 --- a/usr.bin/telnet/telnet.1 +++ b/usr.bin/telnet/telnet.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: telnet.1,v 1.19 1999/10/17 20:24:35 aaron Exp $ +.\" $OpenBSD: telnet.1,v 1.20 1999/12/11 09:08:09 itojun Exp $ .\" $NetBSD: telnet.1,v 1.5 1996/02/28 21:04:12 thorpej Exp $ .\" .\" Copyright (c) 1983, 1990, 1993 @@ -1491,3 +1491,5 @@ the terminal's .Ic eof character is only recognized (and sent to the remote system) when it is the first character on a line. +.Pp +Source routing is not supported yet for IPv6. diff --git a/usr.bin/telnet/telnet_locl.h b/usr.bin/telnet/telnet_locl.h index bbb39ed00ba..fb29f5383a2 100644 --- a/usr.bin/telnet/telnet_locl.h +++ b/usr.bin/telnet/telnet_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: telnet_locl.h,v 1.1 1998/03/12 04:57:44 art Exp $ */ +/* $OpenBSD: telnet_locl.h,v 1.2 1999/12/11 09:08:09 itojun Exp $ */ /* $KTH: telnet_locl.h,v 1.13 1997/11/03 21:37:55 assar Exp $ */ /* @@ -86,7 +86,5 @@ #include "defines.h" #include "types.h" -#undef AF_INET6 /* XXX - it has not been tested and it doesn't exist yet */ - /* prototypes */ |