Package: atftp
Version: 0.7.dfsg-9
Severity: serious
Tags: patch
thanks

On a running system where IPv6 is active, the functionality
of the client atftp is completely broken. The cause is found
in the library call gethostbyname(), which returns a IPv6-mapped
address for any IPv4 host. Atftp cannot handle this, and
aborts any transmission in the first sendto().

The following patch resolves the calamity.

-- 
Mats Erik Andersson, fil. dr
2459 41E9 C420 3F6D F68B  2E88 F768 4541 F25B 5D41

Abbonerar på: debian-mentors, debian-devel-games, debian-perl,
              debian-ipv6, debian-qa
Description: Enable address resolution on systems with valid IPv6.
 The previous use of gethostbyname() in the lookup function
 set_peer() does not work at all on systems where IPv4 as
 well as IPv6 are in productive use. In fact, it returns the
 IPv6 address structure, and thus cause a failure in the very
 first sendto() used for transmission. The solution is to
 migrate the code to use getaddrinfo().
Author: Mats Erik Andersson <deb...@gisladisker.se>
Forwarded: no
Last-Update: 2010-05-06
--- atftp-0.7.dfsg.debian/tftp.c
+++ atftp-0.7.dfsg/tftp.c
@@ -408,7 +408,7 @@ int process_cmd(int argc, char **argv)
  */
 int set_peer(int argc, char **argv)
 {
-     struct hostent *host;      /* for host name lookup */
+     struct addrinfo hints, *ai;   /* for host name lookup */
      struct servent *sp;        /* server entry for tftp service */
 
      /* sanity check */
@@ -425,19 +425,18 @@ int set_peer(int argc, char **argv)
           return ERR;
      }
 
+     memset(&hints, 0, sizeof(hints));
+     hints.ai_flags = AI_CANONNAME;
+     hints.ai_socktype = SOCK_DGRAM;
+     hints.ai_family = AF_INET;
+
      /* look up the host */
-     host = gethostbyname(argv[1]);
-     /* if valid, update s_inn structure */
-     if (host)
+     if (getaddrinfo(argv[1], "tftp", &hints, &ai) == 0)
      {
-          data.sa_peer.sin_family = host->h_addrtype;
-          if (host->h_length > sizeof(data.sa_peer.sin_addr))
-               host->h_length = sizeof(data.sa_peer.sin_addr);
-          memcpy(&data.sa_peer.sin_addr, host->h_addr, host->h_length);
-          Strncpy(data.hostname, host->h_name,
+          memcpy(&data.sa_peer, ai->ai_addr, ai->ai_addrlen);
+          Strncpy(data.hostname, ai->ai_canonname,
                   sizeof(data.hostname));
           data.hostname[sizeof(data.hostname)-1] = 0;
-          data.sa_peer.sin_port = sp->s_port;
      } 
      else
      {

Attachment: signature.asc
Description: Digital signature

Reply via email to