diff options
author | Karsten Keil <kkeil@suse.de> | 2008-08-01 16:31:06 +0200 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-08-01 08:24:16 -0700 |
commit | 544abd789eebfafa0bb3f250f6a824e808e32122 (patch) | |
tree | 31e409b6caf8574113e04794ecbb1bf0f02e273a | |
parent | 18fd18bd5c101b787acfb764b44415651ab5eba4 (diff) | |
download | tftp-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.c | 24 |
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) { |