summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarsten Keil <kkeil@suse.de>2008-08-01 16:31:06 +0200
committerH. Peter Anvin <hpa@zytor.com>2008-08-01 08:24:16 -0700
commit544abd789eebfafa0bb3f250f6a824e808e32122 (patch)
tree31e409b6caf8574113e04794ecbb1bf0f02e273a
parent18fd18bd5c101b787acfb764b44415651ab5eba4 (diff)
downloadtftp-hpa-544abd789eebfafa0bb3f250f6a824e808e32122.tar.gz
Add error messages if address types mismatch
If a user does supply a IPv4 or IPv6 address but force the other type with -4 or -6, give an error. The patch also fix the special [::ffff:127.0.1] address handling, it work now if you bind to this address but only if you not force IPv6 only, it seems that the kernel does not signal connections to a IPv6 socket listen on [::ffff:127.0.0.1], if it was bound IPv6 only. I think we can live with it and do not need a special test for this address. Signed-off-by: Karsten Keil <kkeil@suse.de> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--tftpd/tftpd.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/tftpd/tftpd.c b/tftpd/tftpd.c
index 00c511b..b29c49a 100644
--- a/tftpd/tftpd.c
+++ b/tftpd/tftpd.c
@@ -327,6 +327,7 @@ int main(int argc, char **argv)
struct sockaddr_in bindaddr4;
#ifdef HAVE_IPV6
struct sockaddr_in6 bindaddr6;
+ int force_ipv6 = 0;
#endif
int n;
int fd = -1;
@@ -367,6 +368,7 @@ int main(int argc, char **argv)
#ifdef HAVE_IPV6
case '6':
ai_fam = AF_INET6;
+ force_ipv6 = 1;
break;
#endif
case 'c':
@@ -561,6 +563,12 @@ int main(int argc, char **argv)
if (fd6 >= 0) {
close(fd6);
fd6 = -1;
+ if (ai_fam == AF_INET6) {
+ syslog(LOG_ERR,
+ "Address %s is not in address family AF_INET6",
+ address);
+ exit(EX_USAGE);
+ }
ai_fam = AF_INET;
}
break;
@@ -568,6 +576,12 @@ int main(int argc, char **argv)
if (fd4 >= 0) {
close(fd4);
fd4 = -1;
+ if (ai_fam == AF_INET) {
+ syslog(LOG_ERR,
+ "Address %s is not in address family AF_INET",
+ address);
+ exit(EX_USAGE);
+ }
ai_fam = AF_INET6;
}
break;
@@ -655,12 +669,12 @@ int main(int argc, char **argv)
}
#ifdef HAVE_IPV6
if (fd6 >= 0) {
- int on = 1;
#if defined(IPV6_V6ONLY)
- if (setsockopt(fd6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&on,
- sizeof(on))) {
- syslog(LOG_ERR, "cannot setsockopt IPV6_V6ONLY %m");
- }
+ int on = 1;
+ if (fd4 >= 0 || force_ipv6)
+ if (setsockopt(fd6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&on,
+ sizeof(on)))
+ syslog(LOG_ERR, "cannot setsockopt IPV6_V6ONLY %m");
#endif
if (bind(fd6, (struct sockaddr *)&bindaddr6,
sizeof(bindaddr6)) < 0) {