summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorshin <shin@FreeBSD.org>2000-01-27 09:28:38 +0000
committershin <shin@FreeBSD.org>2000-01-27 09:28:38 +0000
commitce15efb7c04858f00b57c16093d4a3043809048e (patch)
tree8b3d00f78a4a5a34cc3b17e29c28b4472d93a35c /crypto
parentdcbae417f8f4365a5eea807290162acd308b720d (diff)
downloadFreeBSD-src-ce15efb7c04858f00b57c16093d4a3043809048e.zip
FreeBSD-src-ce15efb7c04858f00b57c16093d4a3043809048e.tar.gz
another tcp apps IPv6 updates.(should be make world safe)
ftp, telnet, ftpd, faithd also telnet related sync with crypto, secure, kerberosIV Obtained from: KAME project
Diffstat (limited to 'crypto')
-rw-r--r--crypto/telnet/telnet/commands.c428
-rw-r--r--crypto/telnet/telnet/externs.h10
-rw-r--r--crypto/telnet/telnet/main.c45
-rw-r--r--crypto/telnet/telnet/telnet.112
-rw-r--r--crypto/telnet/telnetd/telnetd.85
-rw-r--r--crypto/telnet/telnetd/telnetd.c90
6 files changed, 396 insertions, 194 deletions
diff --git a/crypto/telnet/telnet/commands.c b/crypto/telnet/telnet/commands.c
index f6bece2..dd83669 100644
--- a/crypto/telnet/telnet/commands.c
+++ b/crypto/telnet/telnet/commands.c
@@ -29,6 +29,8 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -83,6 +85,7 @@ static const char sccsid[] = "@(#)commands.c 8.4 (Berkeley) 5/30/95";
# endif /* vax */
#endif /* !defined(CRAY) && !defined(sysV88) */
#include <netinet/ip.h>
+#include <netinet/ip6.h>
#ifndef MAXHOSTNAMELEN
@@ -2270,27 +2273,76 @@ ayt_status()
}
#endif
-unsigned long inet_addr();
+static const char *
+sockaddr_ntop(sa)
+ struct sockaddr *sa;
+{
+ void *addr;
+ static char addrbuf[INET6_ADDRSTRLEN];
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ addr = &((struct sockaddr_in *)sa)->sin_addr;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
+ break;
+#endif
+ default:
+ return NULL;
+ }
+ inet_ntop(sa->sa_family, addr, addrbuf, sizeof(addrbuf));
+ return addrbuf;
+}
+
+#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
+static int
+setpolicy(net, res, policy)
+ int net;
+ struct addrinfo *res;
+ char *policy;
+{
+ char *buf;
+ int level;
+ int optname;
+
+ if (policy == NULL)
+ return 0;
+
+ buf = ipsec_set_policy(policy, strlen(policy));
+ if (buf == NULL) {
+ printf("%s\n", ipsec_strerror());
+ return -1;
+ }
+ level = res->ai_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
+ optname = res->ai_family == AF_INET ? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY;
+ if (setsockopt(net, level, optname, buf, ipsec_get_policylen(buf)) < 0){
+ perror("setsockopt");
+ return -1;
+ }
+
+ free(buf);
+}
+#endif
int
tn(argc, argv)
int argc;
char *argv[];
{
- register struct hostent *host = 0;
- struct sockaddr_in sin, src_sin;
- struct servent *sp = 0;
- unsigned long temp;
- extern char *inet_ntoa();
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
+ struct sockaddr_storage ss, src_ss;
char *srp = 0, *strrchr();
- unsigned long sourceroute(), srlen;
-#endif
+ int proto, opt;
+ int sourceroute(), srlen;
+ int srcroute = 0, result;
char *cmd, *hostp = 0, *portp = 0, *user = 0;
char *src_addr = NULL;
+ struct addrinfo hints, *res;
+ int error = 0;
/* clear the socket address prior to use */
- memset((char *)&sin, 0, sizeof(sin));
+ memset((char *)&ss, 0, sizeof(ss));
if (connected) {
printf("?Already connected to %s\n", hostname);
@@ -2350,126 +2402,106 @@ tn(argc, argv)
goto usage;
if (src_addr != NULL) {
- bzero((char *)&src_sin, sizeof(src_sin));
- src_sin.sin_family = AF_INET;
- if (!inet_aton(src_addr, &src_sin.sin_addr)) {
- host = gethostbyname2(src_addr, AF_INET);
- if (host == NULL) {
- herror(src_addr);
- return 0;
- }
- if (host->h_length != sizeof(src_sin.sin_addr)) {
- fprintf(stderr, "telnet: gethostbyname2: invalid address\n");
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+ error = getaddrinfo(src_addr, 0, &hints, &res);
+ if (error == EAI_NONAME) {
+ hints.ai_flags = 0;
+ error = getaddrinfo(src_addr, 0, &hints, &res);
+ }
+ if (error != 0) {
+ fprintf(stderr, "%s: %s\n", src_addr, gai_strerror(error));
+ if (error == EAI_SYSTEM)
+ fprintf(stderr, "%s: %s\n", src_addr, strerror(errno));
return 0;
- }
- memcpy((void *)&src_sin.sin_addr, (void *)host->h_addr_list[0],
- sizeof(src_sin.sin_addr));
}
+ memcpy((void *)&src_ss, (void *)res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
}
-
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
if (hostp[0] == '@' || hostp[0] == '!') {
- if ((hostname = strrchr(hostp, ':')) == NULL)
+ if (
+#ifdef INET6
+ family == AF_INET6 ||
+#endif
+ (hostname = strrchr(hostp, ':')) == NULL)
hostname = strrchr(hostp, '@');
hostname++;
+ srcroute = 1;
+ } else
+ hostname = hostp;
+ if (!portp) {
+ telnetport = 1;
+ portp = "telnet";
+ } else if (*portp == '-') {
+ portp++;
+ telnetport = 1;
+ } else
+ telnetport = 0;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+ error = getaddrinfo(hostname, portp, &hints, &res);
+ if (error == 0) {
+ int gni_err = 1;
+
+ if (doaddrlookup)
+ gni_err = getnameinfo(res->ai_addr, res->ai_addr->sa_len,
+ _hostname, sizeof(_hostname) - 1, NULL, 0,
+ 0);
+ if (gni_err != 0)
+ (void) strncpy(_hostname, hostp, sizeof(_hostname) - 1);
+ _hostname[sizeof(_hostname)-1] = '\0';
+ hostname = _hostname;
+ } else if (error == EAI_NONAME) {
+ hints.ai_flags = AI_CANONNAME;
+ error = getaddrinfo(hostname, portp, &hints, &res);
+ if (error != 0) {
+ fprintf(stderr, "%s: %s\n", hostname, gai_strerror(error));
+ if (error == EAI_SYSTEM)
+ fprintf(stderr, "%s: %s\n", hostname, strerror(errno));
+ setuid(getuid());
+ return 0;
+ }
+ memcpy((void *)&ss, (void *)res->ai_addr, res->ai_addrlen);
+ if (srcroute != 0)
+ (void) strncpy(_hostname, hostname, sizeof(_hostname) - 1);
+ else if (res->ai_canonname != NULL)
+ strcpy(_hostname, res->ai_canonname);
+ else
+ (void) strncpy(_hostname, hostp, sizeof(_hostname) - 1);
+ _hostname[sizeof(_hostname)-1] = '\0';
+ hostname = _hostname;
+ }
+ if (srcroute != 0) {
srp = 0;
- temp = sourceroute(hostp, &srp, &srlen);
- if (temp == 0) {
- herror(srp);
+ result = sourceroute(res, hostp, &srp, &srlen, &proto, &opt);
+ if (result == 0) {
setuid(getuid());
+ freeaddrinfo(res);
return 0;
- } else if (temp == -1) {
+ } else if (result == -1) {
printf("Bad source route option: %s\n", hostp);
setuid(getuid());
+ freeaddrinfo(res);
return 0;
- } else {
- sin.sin_addr.s_addr = temp;
- sin.sin_family = AF_INET;
- }
- } else {
-#endif
- temp = inet_addr(hostp);
- if (temp != INADDR_NONE) {
- sin.sin_addr.s_addr = temp;
- sin.sin_family = AF_INET;
- if (doaddrlookup)
- host = gethostbyaddr((char *)&temp, sizeof(temp), AF_INET);
- if (host)
- (void) strncpy(_hostname, host->h_name, sizeof(_hostname));
- else
- (void) strncpy(_hostname, hostp, sizeof(_hostname));
- _hostname[sizeof(_hostname)-1] = '\0';
- hostname = _hostname;
- } else {
- host = gethostbyname(hostp);
- if (host) {
- sin.sin_family = host->h_addrtype;
-#if defined(h_addr) /* In 4.3, this is a #define */
- memmove((caddr_t)&sin.sin_addr,
- host->h_addr_list[0], host->h_length);
-#else /* defined(h_addr) */
- memmove((caddr_t)&sin.sin_addr, host->h_addr, host->h_length);
-#endif /* defined(h_addr) */
- strncpy(_hostname, host->h_name, sizeof(_hostname));
- _hostname[sizeof(_hostname)-1] = '\0';
- hostname = _hostname;
- } else {
- herror(hostp);
- setuid(getuid());
- return 0;
- }
- }
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
- }
-#endif
- if (portp) {
- if (*portp == '-') {
- portp++;
- telnetport = 1;
- } else
- telnetport = 0;
- sin.sin_port = atoi(portp);
- if (sin.sin_port == 0) {
- sp = getservbyname(portp, "tcp");
- if (sp)
- sin.sin_port = sp->s_port;
- else {
- printf("%s: bad port number\n", portp);
- setuid(getuid());
- return 0;
- }
- } else {
-#if !defined(htons)
- u_short htons P((unsigned short));
-#endif /* !defined(htons) */
- sin.sin_port = htons(sin.sin_port);
- }
- } else {
- if (sp == 0) {
- sp = getservbyname("telnet", "tcp");
- if (sp == 0) {
- fprintf(stderr, "telnet: tcp/telnet: unknown service\n");
- setuid(getuid());
- return 0;
- }
- sin.sin_port = sp->s_port;
}
- telnetport = 1;
}
- printf("Trying %s...\n", inet_ntoa(sin.sin_addr));
+ printf("Trying %s...\n", sockaddr_ntop(res->ai_addr));
do {
- net = socket(AF_INET, SOCK_STREAM, 0);
+ net = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
setuid(getuid());
if (net < 0) {
perror("telnet: socket");
return 0;
}
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
- if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0)
- perror("setsockopt (IP_OPTIONS)");
-#endif
+ if (srp && setsockopt(net, proto, opt, (char *)srp, srlen) < 0)
+ perror("setsockopt (source route)");
#if defined(IPPROTO_IP) && defined(IP_TOS)
- {
+ if (res->ai_family == PF_INET) {
# if defined(HAS_GETTOS)
struct tosent *tp;
if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
@@ -2490,28 +2522,31 @@ tn(argc, argv)
}
if (src_addr != NULL) {
- if (bind(net, (struct sockaddr *)&src_sin, sizeof(src_sin)) == -1) {
+ if (bind(net, (struct sockaddr *)&src_ss,
+ ((struct sockaddr *)&src_ss)->sa_len) == -1) {
perror("bind");
return 0;
}
}
+#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
+ if (setpolicy(net, res, ipsec_policy_in) < 0)
+ return 0;
+ if (setpolicy(net, res, ipsec_policy_out) < 0)
+ return 0;
+#endif
- if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
-#if defined(h_addr) /* In 4.3, this is a #define */
- if (host && host->h_addr_list[1]) {
+ if (connect(net, res->ai_addr, res->ai_addrlen) < 0) {
+ if (res->ai_next) {
int oerrno = errno;
fprintf(stderr, "telnet: connect to address %s: ",
- inet_ntoa(sin.sin_addr));
+ sockaddr_ntop(res->ai_addr));
errno = oerrno;
perror((char *)0);
- host->h_addr_list++;
- memmove((caddr_t)&sin.sin_addr,
- host->h_addr_list[0], host->h_length);
+ res = res->ai_next;
(void) NetClose(net);
continue;
}
-#endif /* defined(h_addr) */
perror("telnet: Unable to connect to remote host");
return 0;
}
@@ -2520,6 +2555,7 @@ tn(argc, argv)
auth_encrypt_connect(connected);
#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
} while (connected == 0);
+ freeaddrinfo(res);
cmdrc(hostp, hostname);
if (autologin && user == NULL) {
struct passwd *pw;
@@ -2861,8 +2897,6 @@ cmdrc(m1, m2)
fclose(rcfile);
}
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
-
/*
* Source route is handed in as
* [!]@hop1@hop2...[@|:]dst
@@ -2876,6 +2910,10 @@ cmdrc(m1, m2)
* be the address to connect() to.
*
* Arguments:
+ *
+ * res: ponter to addrinfo structure which contains sockaddr to
+ * the host to connect to.
+ *
* arg: pointer to route list to decipher
*
* cpp: If *cpp is not equal to NULL, this is a
@@ -2885,9 +2923,18 @@ cmdrc(m1, m2)
* lenp: pointer to an integer that contains the
* length of *cpp if *cpp != NULL.
*
+ * protop: pointer to an integer that should be filled in with
+ * appropriate protocol for setsockopt, as socket
+ * protocol family.
+ *
+ * optp: pointer to an integer that should be filled in with
+ * appropriate option for setsockopt, as socket protocol
+ * family.
+ *
* Return values:
*
- * Returns the address of the host to connect to. If the
+ * If the return value is 1, then all operations are
+ * successful. If the
* return value is -1, there was a syntax error in the
* option, either unknown characters, or too many hosts.
* If the return value is 0, one of the hostnames in the
@@ -2901,21 +2948,32 @@ cmdrc(m1, m2)
* *lenp: This will be filled in with how long the option
* pointed to by *cpp is.
*
+ * *protop: This will be filled in with appropriate protocol for
+ * setsockopt, as socket protocol family.
+ *
+ * *optp: This will be filled in with appropriate option for
+ * setsockopt, as socket protocol family.
*/
- unsigned long
-sourceroute(arg, cpp, lenp)
+int
+sourceroute(ai, arg, cpp, lenp, protop, optp)
+ struct addrinfo *ai;
char *arg;
char **cpp;
int *lenp;
+ int *protop;
+ int *optp;
{
- static char lsr[44];
+ static char buf[1024]; /*XXX*/
+ struct cmsghdr *cmsg;
#ifdef sysV88
static IOPTN ipopt;
#endif
- char *cp, *cp2, *lsrp, *lsrep;
+ char *cp, *cp2, *lsrp, *ep;
register int tmp;
- struct in_addr sin_addr;
- register struct hostent *host = 0;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+ struct addrinfo hints, *res;
+ int error;
register char c;
/*
@@ -2924,22 +2982,46 @@ sourceroute(arg, cpp, lenp)
*/
if (cpp == NULL || lenp == NULL)
return((unsigned long)-1);
- if (*cpp != NULL && *lenp < 7)
- return((unsigned long)-1);
+ if (*cpp != NULL) {
+ switch (res->ai_family) {
+ case AF_INET:
+ if (*lenp < 7)
+ return((unsigned long)-1);
+ break;
+#ifdef INET6
+ case AF_INET6:
+ if (*lenp < (sizeof(struct cmsghdr) +
+ sizeof(struct ip6_rthdr) +
+ sizeof(struct in6_addr)))
+ return((unsigned long)-1);
+ break;
+#endif
+ }
+ }
/*
* Decide whether we have a buffer passed to us,
* or if we need to use our own static buffer.
*/
if (*cpp) {
lsrp = *cpp;
- lsrep = lsrp + *lenp;
+ ep = lsrp + *lenp;
} else {
- *cpp = lsrp = lsr;
- lsrep = lsrp + 44;
+ *cpp = lsrp = buf;
+ ep = lsrp + 1024;
}
cp = arg;
+#ifdef INET6
+ if (ai->ai_family == AF_INET6) {
+ cmsg = inet6_rthdr_init(*cpp, IPV6_RTHDR_TYPE_0);
+ if (*cp != '@')
+ return -1;
+ *protop = IPPROTO_IPV6;
+ *optp = IPV6_PKTOPTIONS;
+ } else
+#endif
+ {
/*
* Next, decide whether we have a loose source
* route or a strict source route, and fill in
@@ -2966,13 +3048,20 @@ sourceroute(arg, cpp, lenp)
lsrp++; /* skip over length, we'll fill it in later */
*lsrp++ = 4;
#endif
+ *protop = IPPROTO_IP;
+ *optp = IP_OPTIONS;
+ }
cp++;
-
- sin_addr.s_addr = 0;
-
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = ai->ai_family;
+ hints.ai_socktype = SOCK_STREAM;
for (c = 0;;) {
- if (c == ':')
+ if (
+#ifdef INET6
+ ai->ai_family != AF_INET6 &&
+#endif
+ c == ':')
cp2 = 0;
else for (cp2 = cp; (c = *cp2); cp2++) {
if (c == ',') {
@@ -2981,7 +3070,11 @@ sourceroute(arg, cpp, lenp)
cp2++;
} else if (c == '@') {
*cp2++ = '\0';
- } else if (c == ':') {
+ } else if (
+#ifdef INET6
+ ai->ai_family != AF_INET6 &&
+#endif
+ c == ':') {
*cp2++ = '\0';
} else
continue;
@@ -2990,21 +3083,32 @@ sourceroute(arg, cpp, lenp)
if (!c)
cp2 = 0;
- if ((tmp = inet_addr(cp)) != -1) {
- sin_addr.s_addr = tmp;
- } else if ((host = gethostbyname(cp))) {
-#if defined(h_addr)
- memmove((caddr_t)&sin_addr,
- host->h_addr_list[0], host->h_length);
-#else
- memmove((caddr_t)&sin_addr, host->h_addr, host->h_length);
-#endif
- } else {
+ hints.ai_flags = AI_NUMERICHOST;
+ error = getaddrinfo(cp, NULL, &hints, &res);
+ if (error == EAI_NONAME) {
+ hints.ai_flags = 0;
+ error = getaddrinfo(cp, NULL, &hints, &res);
+ }
+ if (error != 0) {
+ fprintf(stderr, "%s: %s\n", cp, gai_strerror(error));
+ if (error == EAI_SYSTEM)
+ fprintf(stderr, "%s: %s\n", cp,
+ strerror(errno));
*cpp = cp;
return(0);
}
- memmove(lsrp, (char *)&sin_addr, 4);
+#ifdef INET6
+ if (res->ai_family == AF_INET6) {
+ sin6 = (struct sockaddr_in6 *)res->ai_addr;
+ inet6_rthdr_add(cmsg, &sin6->sin6_addr,
+ IPV6_RTHDR_LOOSE);
+ } else
+#endif
+ {
+ sin = (struct sockaddr_in *)res->ai_addr;
+ memcpy(lsrp, (char *)&sin->sin_addr, 4);
lsrp += 4;
+ }
if (cp2)
cp = cp2;
else
@@ -3012,9 +3116,27 @@ sourceroute(arg, cpp, lenp)
/*
* Check to make sure there is space for next address
*/
- if (lsrp + 4 > lsrep)
+#ifdef INET6
+ if (res->ai_family == AF_INET6) {
+ if (((char *)cmsg +
+ sizeof(struct cmsghdr) +
+ sizeof(struct ip6_rthdr) +
+ ((inet6_rthdr_segments(cmsg) + 1) *
+ sizeof(struct in6_addr))) > ep)
+ return((unsigned long)-1);
+ } else
+#endif
+ if (lsrp + 4 > ep)
return((unsigned long)-1);
+ freeaddrinfo(res);
}
+#ifdef INET6
+ if (res->ai_family == AF_INET6) {
+ inet6_rthdr_lasthop(cmsg, IPV6_RTHDR_LOOSE);
+ *lenp = cmsg->cmsg_len;
+ } else
+#endif
+ {
#ifndef sysV88
if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) {
*cpp = 0;
@@ -3033,6 +3155,10 @@ sourceroute(arg, cpp, lenp)
*lenp = sizeof(ipopt);
*cpp = (char *) &ipopt;
#endif
- return(sin_addr.s_addr);
+ }
+ freeaddrinfo(res);
+ return 1;
}
-#endif
+
+
+
diff --git a/crypto/telnet/telnet/externs.h b/crypto/telnet/telnet/externs.h
index 0c6894f..46253d9 100644
--- a/crypto/telnet/telnet/externs.h
+++ b/crypto/telnet/telnet/externs.h
@@ -31,6 +31,7 @@
* SUCH DAMAGE.
*
* @(#)externs.h 8.3 (Berkeley) 5/30/95
+ * $FreeBSD$
*/
#ifndef BSD
@@ -87,6 +88,14 @@ typedef unsigned char cc_t;
#include <strings.h>
#endif
+#if defined(IPSEC)
+#include <netinet6/ipsec.h>
+#if defined(IPSEC_POLICY_IPSEC)
+extern char *ipsec_policy_in;
+extern char *ipsec_policy_out;
+#endif
+#endif
+
#ifndef _POSIX_VDISABLE
# ifdef sun
# include <sys/param.h> /* pick up VDISABLE definition, mayby */
@@ -116,6 +125,7 @@ extern int
autologin, /* Autologin enabled */
skiprc, /* Don't process the ~/.telnetrc file */
eight, /* use eight bit mode (binary in and/or out */
+ family, /* address family of peer */
flushout, /* flush output */
connected, /* Are we connected to the other side? */
globalmode, /* Mode tty should be in */
diff --git a/crypto/telnet/telnet/main.c b/crypto/telnet/telnet/main.c
index 2dc05fd..c3d0f5d 100644
--- a/crypto/telnet/telnet/main.c
+++ b/crypto/telnet/telnet/main.c
@@ -29,6 +29,8 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $FreeBSD$
*/
#ifndef lint
@@ -42,6 +44,7 @@ static const char sccsid[] = "@(#)main.c 8.3 (Berkeley) 5/30/95";
#endif /* not lint */
#include <sys/types.h>
+#include <sys/socket.h>
#include <stdlib.h>
#include "ring.h"
@@ -70,6 +73,13 @@ void init_telnet(void);
void init_sys(void);
void init_3270(void);
+#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
+char *ipsec_policy_in = NULL;
+char *ipsec_policy_out = NULL;
+#endif
+
+int family = AF_UNSPEC;
+
/*
* Initialize variables.
*/
@@ -95,10 +105,10 @@ usage()
fprintf(stderr, "Usage: %s %s%s%s%s\n",
prompt,
#ifdef AUTHENTICATION
- "[-8] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-a] [-c] [-d]",
+ "[-4] [-6] [-8] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-a] [-c] [-d]",
"\n\t[-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
#else
- "[-8] [-E] [-L] [-N] [-S tos] [-a] [-c] [-d] [-e char] [-l user]",
+ "[-4] [-6] [-8] [-E] [-L] [-N] [-S tos] [-a] [-c] [-d] [-e char] [-l user]",
"\n\t[-n tracefile] ",
#endif
#if defined(TN3270) && defined(unix)
@@ -112,6 +122,9 @@ usage()
#else
"[-r] [-s src_addr] ",
#endif
+#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
+ "[-P policy]"
+#endif
#ifdef ENCRYPTION
"[-x] [host-name [port]]"
#else /* ENCRYPTION */
@@ -156,8 +169,24 @@ main(argc, argv)
rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
autologin = -1;
- while ((ch = getopt(argc, argv, "8EKLNS:X:acde:fFk:l:n:rs:t:x")) != EOF) {
+#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
+#define IPSECOPT "P:"
+#else
+#define IPSECOPT
+#endif
+ while ((ch = getopt(argc, argv,
+ "468EKLNS:X:acde:fFk:l:n:rs:t:x" IPSECOPT)) != -1)
+#undef IPSECOPT
+ {
switch(ch) {
+ case '4':
+ family = AF_INET;
+ break;
+#ifdef INET6
+ case '6':
+ family = AF_INET6;
+ break;
+#endif
case '8':
eight = 3; /* binary output and input */
break;
@@ -299,6 +328,16 @@ main(argc, argv)
prompt);
#endif /* ENCRYPTION */
break;
+#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
+ case 'P':
+ if (!strncmp("in", optarg, 2))
+ ipsec_policy_in = strdup(optarg);
+ else if (!strncmp("out", optarg, 3))
+ ipsec_policy_out = strdup(optarg);
+ else
+ usage();
+ break;
+#endif
case '?':
default:
usage();
diff --git a/crypto/telnet/telnet/telnet.1 b/crypto/telnet/telnet/telnet.1
index 9841462..3378d3a 100644
--- a/crypto/telnet/telnet/telnet.1
+++ b/crypto/telnet/telnet/telnet.1
@@ -30,8 +30,9 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)telnet.1 8.6 (Berkeley) 6/1/94
+.\" $FreeBSD$
.\"
-.Dd June 1, 1994
+.Dd January 27, 2000
.Dt TELNET 1
.Os BSD 4.2
.Sh NAME
@@ -549,9 +550,10 @@ will attempt to contact a
.Tn TELNET
server at the default port.
The host specification may be either a host name (see
-.Xr hosts 5 )
-or an Internet address specified in the \*(Lqdot notation\*(Rq (see
-.Xr inet 3 ) .
+.Xr hosts 5 ) ,
+an Internet address specified in the \*(Lqdot notation\*(Rq (see
+.Xr inet 3 ) ,
+or IPv6 host name or IPv6 coloned-hexadecimal addreess.
The
.Op Fl l
option may be used to specify the user name
@@ -1367,6 +1369,8 @@ The
.Nm Telnet
command appeared in
.Bx 4.2 .
+.Pp
+IPv6 support was added by WIDE/KAME project.
.Sh NOTES
.Pp
On some remote systems, echo has to be turned off manually when in
diff --git a/crypto/telnet/telnetd/telnetd.8 b/crypto/telnet/telnetd/telnetd.8
index e03f290..4e004a4 100644
--- a/crypto/telnet/telnetd/telnetd.8
+++ b/crypto/telnet/telnetd/telnetd.8
@@ -30,8 +30,9 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)telnetd.8 8.4 (Berkeley) 6/1/94
+.\" $FreeBSD$
.\"
-.Dd June 1, 1994
+.Dd January 27, 2000
.Dt TELNETD 8
.Os BSD 4.2
.Sh NAME
@@ -610,3 +611,5 @@ never sends
.Tn TELNET
.Dv IAC GA
(go ahead) commands.
+.Sh HISTORY
+IPv6 support was added by WIDE/KAME project.
diff --git a/crypto/telnet/telnetd/telnetd.c b/crypto/telnet/telnetd/telnetd.c
index 57e6ed2..6d7bcde 100644
--- a/crypto/telnet/telnetd/telnetd.c
+++ b/crypto/telnet/telnetd/telnetd.c
@@ -70,6 +70,12 @@ static const char rcsid[] =
#include <sys/secparm.h>
#include <sys/usrv.h>
# endif /* SO_SEC_MULTI */
+
+/* wrapper for KAME-special getnameinfo() */
+#ifndef NI_WITHSCOPEID
+#define NI_WITHSCOPEID 0
+#endif
+
int secflag;
char tty_dev[16];
struct secdev dv;
@@ -128,7 +134,7 @@ char ptyibuf2[BUFSIZ];
# include <termcap.h>
int readstream(int p, char *ibuf, int bufsize);
-void doit(struct sockaddr_in *who);
+void doit(struct sockaddr *who);
int terminaltypeok(char *s);
void startslave(char *host, int autologin, char *autoname);
@@ -145,7 +151,7 @@ int debug = 0;
int keepalive = 1;
char *altlogin;
-void doit __P((struct sockaddr_in *));
+void doit __P((struct sockaddr *));
int terminaltypeok __P((char *));
void startslave __P((char *, int, char *));
extern void usage P((void));
@@ -157,6 +163,7 @@ extern void usage P((void));
*/
char valid_opts[] = {
'd', ':', 'h', 'k', 'n', 'p', ':', 'S', ':', 'u', ':', 'U',
+ '4', '6',
#ifdef AUTHENTICATION
'a', ':', 'X', ':',
#endif
@@ -184,11 +191,13 @@ char valid_opts[] = {
'\0'
};
- int
+int family = AF_INET;
+
+int
main(argc, argv)
char *argv[];
{
- struct sockaddr_in from;
+ struct sockaddr_storage from;
int on = 1, fromlen;
register int ch;
#if defined(IPPROTO_IP) && defined(IP_TOS)
@@ -406,6 +415,16 @@ main(argc, argv)
break;
#endif /* AUTHENTICATION */
+ case '4':
+ family = AF_INET;
+ break;
+
+#ifdef INET6
+ case '6':
+ family = AF_INET6;
+ break;
+#endif
+
default:
warnx("%c: unknown option", ch);
/* FALLTHROUGH */
@@ -419,43 +438,41 @@ main(argc, argv)
argv += optind;
if (debug) {
- int s, ns, foo;
- struct servent *sp;
- static struct sockaddr_in sin = { AF_INET };
+ int s, ns, foo, error;
+ char *service = "telnet";
+ struct addrinfo hints, *res;
if (argc > 1) {
usage();
/* NOT REACHED */
- } else if (argc == 1) {
- if ((sp = getservbyname(*argv, "tcp"))) {
- sin.sin_port = sp->s_port;
- } else {
- sin.sin_port = atoi(*argv);
- if ((int)sin.sin_port <= 0) {
- warnx("%s: bad port #", *argv);
- usage();
- /* NOT REACHED */
- }
- sin.sin_port = htons((u_short)sin.sin_port);
- }
- } else {
- sp = getservbyname("telnet", "tcp");
- if (sp == 0)
- errx(1, "tcp/telnet: unknown service");
- sin.sin_port = sp->s_port;
+ } else if (argc == 1)
+ service = *argv;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ error = getaddrinfo(NULL, service, &hints, &res);
+
+ if (error) {
+ errx(1, "tcp/%s: %s\n", service, gai_strerror(error));
+ if (error == EAI_SYSTEM)
+ errx(1, "tcp/%s: %s\n", service, strerror(errno));
+ usage();
}
- s = socket(AF_INET, SOCK_STREAM, 0);
+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s < 0)
err(1, "socket");
(void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
(char *)&on, sizeof(on));
- if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0)
+ if (bind(s, res->ai_addr, res->ai_addrlen) < 0)
err(1, "bind");
if (listen(s, 1) < 0)
err(1, "listen");
- foo = sizeof sin;
- ns = accept(s, (struct sockaddr *)&sin, &foo);
+ foo = res->ai_addrlen;
+ ns = accept(s, res->ai_addr, &foo);
if (ns < 0)
err(1, "accept");
(void) dup2(ns, 0);
@@ -537,7 +554,7 @@ main(argc, argv)
}
#if defined(IPPROTO_IP) && defined(IP_TOS)
- {
+ if (from.ss_family == AF_INET) {
# if defined(HAS_GETTOS)
struct tosent *tp;
if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
@@ -553,7 +570,7 @@ main(argc, argv)
}
#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */
net = 0;
- doit(&from);
+ doit((struct sockaddr *)&from);
/* NOTREACHED */
return(0);
} /* end of main */
@@ -821,8 +838,9 @@ char user_name[256];
*/
void
doit(who)
- struct sockaddr_in *who;
+ struct sockaddr *who;
{
+ int err;
int ptynum;
/*
@@ -865,16 +883,18 @@ doit(who)
#endif /* _SC_CRAY_SECURE_SYS */
/* get name of connected client */
- if (realhostname(remote_hostname, sizeof(remote_hostname) - 1,
- &who->sin_addr) == HOSTNAME_INVALIDADDR && registerd_host_only)
+ if (realhostname_sa(remote_hostname, sizeof(remote_hostname) - 1,
+ who, who->sa_len) == HOSTNAME_INVALIDADDR && registerd_host_only)
fatal(net, "Couldn't resolve your address into a host name.\r\n\
Please contact your net administrator");
remote_hostname[sizeof(remote_hostname) - 1] = '\0';
trimdomain(remote_hostname, UT_HOSTSIZE);
if (!isdigit(remote_hostname[0]) && strlen(remote_hostname) > utmp_len)
- strncpy(remote_hostname, inet_ntoa(who->sin_addr),
- sizeof(remote_hostname) - 1);
+ err = getnameinfo(who, who->sa_len, remote_hostname,
+ sizeof(remote_hostname), NULL, 0,
+ NI_NUMERICHOST|NI_WITHSCOPEID);
+ /* XXX: do 'err' check */
(void) gethostname(host_name, sizeof(host_name) - 1);
host_name[sizeof(host_name) - 1] = '\0';
OpenPOWER on IntegriCloud