From c89a63a441cdd176c52740bf386b78548f46d492 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sat, 7 Jun 2014 12:37:33 -0700 Subject: tftp: convert IPv6-mapped IPv4 addresses to IPv4 If we receive IPv4 addresses mapped to IPv6, convert them back to IPv4 so that mapping scripts which use \i behave sanely. Signed-off-by: H. Peter Anvin --- tftpd/recvfrom.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tftpd/recvfrom.c b/tftpd/recvfrom.c index d050b80..b613823 100644 --- a/tftpd/recvfrom.c +++ b/tftpd/recvfrom.c @@ -113,6 +113,25 @@ err: return rv; } +#ifdef HAVE_IPV6 +static void normalize_ip6_compat(union sock_addr *myaddr) +{ + static const uint8_t ip6_compat_prefix[12] = + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; + struct sockaddr_in in; + + if (!memcmp(&myaddr->s6.sin6_addr, ip6_compat_prefix, + sizeof ip6_compat_prefix)) { + bzero(&in, sizeof in); + in.sin_family = AF_INET; + in.sin_port = myaddr->s6.sin6_port; + memcpy(&in.sin_addr, (const char *)&myaddr->s6.sin6_addr + + sizeof ip6_compat_prefix, sizeof in.sin_addr); + memcpy(&myaddr->si, &in, sizeof in); + } +} +#endif + int myrecvfrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, socklen_t * fromlen, @@ -233,6 +252,7 @@ myrecvfrom(int s, void *buf, int len, unsigned int flags, sizeof(struct in6_addr)); } #endif + normalize_ip6_compat(myaddr); } #endif } -- cgit v1.2.1