version 1.22, 1999/12/07 01:10:29 |
version 1.23, 1999/12/11 09:08:08 |
|
|
int argc; |
int argc; |
char *argv[]; |
char *argv[]; |
{ |
{ |
register struct hostent *host = 0, *alias = 0; |
struct addrinfo hints, *res, *res0; |
|
int error; |
#if defined(AF_INET6) |
#if defined(AF_INET6) |
struct sockaddr_in6 sin6; |
struct sockaddr_in6 sin6; |
#endif |
#endif |
|
|
char *srp = 0; |
char *srp = 0; |
int srlen; |
int srlen; |
#endif |
#endif |
|
int retry; |
char *cmd, *hostp = 0, *portp = 0, *user = 0, *aliasp = 0; |
char *cmd, *hostp = 0, *portp = 0, *user = 0, *aliasp = 0; |
int family, port; |
int family, port; |
|
|
|
|
} else { |
} else { |
abort(); |
abort(); |
} |
} |
} else { |
} else |
#endif |
#endif |
memset (&sin, 0, sizeof(sin)); |
{ |
#if defined(HAVE_INET_PTON) && defined(AF_INET6) |
hostname = hostp; |
memset (&sin6, 0, sizeof(sin6)); |
memset(&hints, 0, sizeof(hints)); |
|
hints.ai_family = PF_UNSPEC; |
if(inet_pton(AF_INET6, hostp, &sin6.sin6_addr)) { |
hints.ai_socktype = SOCK_STREAM; |
sin6.sin6_family = family = AF_INET6; |
hints.ai_flags = AI_CANONNAME; |
sa = (struct sockaddr *)&sin6; |
if (portp == NULL) { |
sa_size = sizeof(sin6); |
portp = "telnet"; |
strcpy(_hostname, hostp); |
} else if (*portp == '-') { |
hostname =_hostname; |
portp++; |
} else |
telnetport = 1; |
#endif |
} |
if(inet_aton(hostp, &sin.sin_addr)){ |
error = getaddrinfo(hostp, portp, &hints, &res0); |
sin.sin_family = family = AF_INET; |
if (error) { |
sa = (struct sockaddr *)&sin; |
warn("%s: %s", hostp, gai_strerror(error)); |
sa_size = sizeof(sin); |
herror(hostp); |
strcpy(_hostname, hostp); |
return 0; |
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; |
|
#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) |
|
} |
} |
#endif |
#if 0 |
if (portp) { |
if (portp) { |
if (*portp == '-') { |
if (*portp == '-') { |
portp++; |
portp++; |
|
|
} |
} |
telnetport = 1; |
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 |
#endif |
|
|
char buf[INET6_ADDRSTRLEN]; |
net = -1; |
|
retry = 0; |
|
for (res = res0; res; res = res->ai_next) { |
|
if (1 /* retry */) { |
|
char hbuf[MAXHOSTNAMELEN]; |
|
|
sin6.sin6_port = port; |
getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), |
#ifdef HAVE_INET_NTOP |
NULL, 0, NI_NUMERICHOST); |
printf("Trying %s...\r\n", inet_ntop(AF_INET6, |
printf("Trying %s...\r\n", hbuf); |
&sin6.sin6_addr, |
|
buf, |
|
sizeof(buf))); |
|
#endif |
|
break; |
|
} |
|
#endif |
|
default: |
|
abort(); |
|
} |
|
|
|
do { |
|
net = socket(family, SOCK_STREAM, 0); |
|
if (net < 0) { |
|
perror("telnet: socket"); |
|
return 0; |
|
} |
} |
|
net = socket(res->ai_family, res->ai_socktype, res->ai_protocol); |
|
if (net < 0) |
|
continue; |
|
|
if (aliasp) { |
if (aliasp) { |
memset ((caddr_t)&ladr, 0, sizeof (ladr)); |
struct addrinfo ahints, *ares; |
temp = inet_addr(aliasp); |
|
if (temp != INADDR_NONE) { |
memset(&ahints, 0, sizeof(ahints)); |
ladr.sin_addr.s_addr = temp; |
ahints.ai_family = PF_UNSPEC; |
ladr.sin_family = AF_INET; |
ahints.ai_socktype = SOCK_STREAM; |
alias = gethostbyaddr((char *)&temp, sizeof(temp), AF_INET); |
ahints.ai_flags = AI_PASSIVE; |
} else { |
error = getaddrinfo(aliasp, "0", &ahints, &ares); |
alias = gethostbyname(aliasp); |
if (error) { |
if (alias) { |
warn("%s: %s", aliasp, gai_strerror(error)); |
ladr.sin_family = alias->h_addrtype; |
close(net); |
#if defined(h_addr) /* In 4.3, this is a #define */ |
freeaddrinfo(ares); |
memmove((caddr_t)&ladr.sin_addr, |
continue; |
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; |
|
} |
|
} |
} |
ladr.sin_port = htons(0); |
if (bind(net, res->ai_addr, res->ai_addrlen) < 0) { |
|
perror(aliasp); |
if (bind (net, (struct sockaddr *)&ladr, sizeof(ladr)) < 0) { |
|
perror(aliasp);; |
|
(void) close(net); /* dump descriptor */ |
(void) close(net); /* dump descriptor */ |
return 0; |
freeaddrinfo(ares); |
|
continue; |
} |
} |
} |
freeaddrinfo(ares); |
#if defined(IP_OPTIONS) && defined(IPPROTO_IP) |
} |
if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) |
#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)"); |
perror("setsockopt (IP_OPTIONS)"); |
#endif |
#endif |
#if defined(IPPROTO_IP) && defined(IP_TOS) |
#if defined(IPPROTO_IP) && defined(IP_TOS) |
{ |
if (res->ai_family == AF_INET) { |
# if defined(HAS_GETTOS) |
# if defined(HAS_GETTOS) |
struct tosent *tp; |
struct tosent *tp; |
if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) |
if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) |
|
|
perror("setsockopt (SO_DEBUG)"); |
perror("setsockopt (SO_DEBUG)"); |
} |
} |
|
|
if (connect(net, sa, sa_size) < 0) { |
if (connect(net, res->ai_addr, res->ai_addrlen) < 0) { |
int retry = 0; |
char hbuf[MAXHOSTNAMELEN]; |
|
|
if (host && host->h_addr_list[1]) { |
getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), |
int oerrno = errno; |
NULL, 0, NI_NUMERICHOST); |
retry = 1; |
fprintf(stderr, "telnet: connect to address %s: ", hbuf); |
|
|
switch(family) { |
close(net); |
case AF_INET : |
net = -1; |
fprintf(stderr, "telnet: connect to address %s: ", |
retry++; |
inet_ntoa(sin.sin_addr)); |
continue; |
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); |
|
|
|
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; |
|
} |
} |
|
|
connected++; |
connected++; |
#if defined(AUTHENTICATION) || defined(ENCRYPTION) |
#if defined(AUTHENTICATION) || defined(ENCRYPTION) |
auth_encrypt_connect(connected); |
auth_encrypt_connect(connected); |
#endif /* defined(AUTHENTICATION) */ |
#endif /* defined(AUTHENTICATION) */ |
} while (connected == 0); |
break; |
|
} |
|
freeaddrinfo(res0); |
|
if (net < 0) { |
|
return 0; |
|
} |
cmdrc(hostp, hostname); |
cmdrc(hostp, hostname); |
if (autologin && user == NULL) { |
if (autologin && user == NULL) { |
struct passwd *pw; |
struct passwd *pw; |