summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarsten Keil <kkeil@suse.de>2008-07-31 13:18:11 +0200
committerH. Peter Anvin <hpa@zytor.com>2008-07-31 11:48:18 -0700
commit18fd18bd5c101b787acfb764b44415651ab5eba4 (patch)
tree6ee38e876638a504b0e2acabca8e65e4905e66e9
parentbdb90cf17664d0305049d2425f839d7952e5d0a9 (diff)
downloadtftp-hpa-18fd18bd5c101b787acfb764b44415651ab5eba4.tar.gz
Improve address type error handling
This patch detects numeric address types to avoid unnecessary warnings/errors. It also cleans up error printing to not print error messages on stderr in the deamon case. Signed-off-by: Karsten Keil <kkeil@suse.de> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--common/tftpsubs.c9
-rw-r--r--configure.in1
-rw-r--r--tftp/main.c9
-rw-r--r--tftpd/tftpd.c57
4 files changed, 56 insertions, 20 deletions
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);
}
}