diff --git a/common/tftpsubs.c b/common/tftpsubs.c index 9958184..a796bec 100644 --- a/common/tftpsubs.c +++ b/common/tftpsubs.c @@ -310,15 +310,10 @@ set_sock_addr(char *host,union sock_addr *s, char **name) hints.ai_family = s->sa.sa_family; hints.ai_flags = AI_CANONNAME; err = getaddrinfo(strip_address(host), NULL, &hints, &addrResult); - if (err) { - printf("Error : %s\n", gai_strerror(err)); - printf("%s: unknown host\n", host); + if (err) return err; - } - if (addrResult == NULL) { - printf("%s: unknown host\n", host); + if (addrResult == NULL) return EAI_NONAME; - } memcpy(s, addrResult->ai_addr, addrResult->ai_addrlen); if (name) { if (addrResult->ai_canonname) diff --git a/configure.in b/configure.in index 7f8a898..209b838 100644 --- a/configure.in +++ b/configure.in @@ -175,6 +175,7 @@ then AC_SEARCH_LIBS(inet_ntoa, [nsl resolv], , [AC_MSG_ERROR(inet_ntoa not found)]) fi +AC_SEARCH_LIBS(inet_aton, [nsl resolv], ,[AC_MSG_ERROR(inet_aton not found)]) AC_CHECK_FUNCS(daemon, , [XTRA=true; AC_LIBOBJ(daemon)]) AC_CHECK_FUNCS(dup2, , [XTRA=true; AC_LIBOBJ(dup2)]) diff --git a/tftp/main.c b/tftp/main.c index be11957..1b8a881 100644 --- a/tftp/main.c +++ b/tftp/main.c @@ -416,6 +416,8 @@ void setpeer(int argc, char *argv[]) peeraddr.sa.sa_family = ai_fam; err = set_sock_addr(argv[1], &peeraddr, &hostname); if (err) { + printf("Error: %s\n", gai_strerror(err)); + printf("%s: unknown host\n", argv[1]); connected = 0; return; } @@ -557,6 +559,8 @@ void put(int argc, char *argv[]) peeraddr.sa.sa_family = ai_fam; err = set_sock_addr(cp, &peeraddr,&hostname); if (err) { + printf("Error: %s\n", gai_strerror(err)); + printf("%s: unknown host\n", argv[1]); connected = 0; return; } @@ -645,8 +649,11 @@ void get(int argc, char *argv[]) *src++ = 0; peeraddr.sa.sa_family = ai_fam; err = set_sock_addr(argv[n], &peeraddr, &hostname); - if (err) + if (err) { + printf("Warning: %s\n", gai_strerror(err)); + printf("%s: unknown host\n", argv[1]); continue; + } ai_fam = peeraddr.sa.sa_family; connected = 1; } diff --git a/tftpd/tftpd.c b/tftpd/tftpd.c index 2266148..00c511b 100644 --- a/tftpd/tftpd.c +++ b/tftpd/tftpd.c @@ -258,23 +258,36 @@ static int recv_time(int s, void *rbuf, int len, unsigned int flags, static int split_port(char **ap, char **pp) { char *a, *p; + int ret = AF_UNSPEC; a = *ap; +#ifdef HAVE_IPV6 if (is_numeric_ipv6(a)) { if (*a++ != '[') - return 1; + return -1; *ap = a; p = strrchr(a, ']'); if (!p) - return 1; + return -1; *p++ = 0; a = p; + ret = AF_INET6; + p = strrchr(a, ':'); + if (p) + *p++ = 0; + } else +#endif + { + struct in_addr in; + + p = strrchr(a, ':'); + if (p) + *p++ = 0; + if (inet_aton(a, &in)) + ret = AF_INET; } - p = strrchr(a, ':'); - if (p) - *p++ = 0; *pp = p; - return 0; + return ret; } enum long_only_options { @@ -542,7 +555,26 @@ int main(int argc, char **argv) address = tfstrdup(address); err = split_port(&address, &portptr); - if (err) { + switch (err) { + case AF_INET: +#ifdef HAVE_IPV6 + if (fd6 >= 0) { + close(fd6); + fd6 = -1; + ai_fam = AF_INET; + } + break; + case AF_INET6: + if (fd4 >= 0) { + close(fd4); + fd4 = -1; + ai_fam = AF_INET6; + } + break; +#endif + case AF_UNSPEC: + break; + default: syslog(LOG_ERR, "Numeric IPv6 addresses need to be enclosed in []"); exit(EX_USAGE); @@ -556,8 +588,8 @@ int main(int argc, char **argv) (union sock_addr *)&bindaddr4, NULL); if (err) { syslog(LOG_ERR, - "cannot resolve local IPv4 bind address: %s", - address); + "cannot resolve local IPv4 bind address: %s, %s", + address, gai_strerror(err)); exit(EX_NOINPUT); } } @@ -570,13 +602,14 @@ int main(int argc, char **argv) if (fd4 >= 0) { syslog(LOG_ERR, "cannot resolve local IPv6 bind address: %s" - "; using IPv4 only", address); + "(%s); using IPv4 only", + address, gai_strerror(err)); close(fd6); fd6 = -1; } else { syslog(LOG_ERR, - "cannot resolve local IPv6 bind address: %s", - address); + "cannot resolve local IPv6 bind address: %s" + "(%s)", address, gai_strerror(err)); exit(EX_NOINPUT); } }