bug-inetutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-inetutils] [PATCH] Implement IPv6 capability for the TFTP server.


From: Mats Erik Andersson
Subject: [bug-inetutils] [PATCH] Implement IPv6 capability for the TFTP server.
Date: Sun, 12 Sep 2010 02:47:27 +0200
User-agent: Mutt/1.5.18 (2008-05-17)

Hello,

I am suggesting to split off the IPv6-patch for "src/tftpd.c",
as it now is self-contained, apart from the elementary change
to "libinetutils/tftpsubs.c".

The previous thread

   "[patches 1,2,3] Making tftp/tftpd IPv6-capable."

is hereby declared closed, and its code is declared dead.
Well, it does return in a refined form!

The present patch for "src/tftpd.c" has been verified on
Debian Squeeze and OpenBSD 4.6. For the testing I have
used the IPv6-capable netkit-ftp client in Debian, for
which I am myself responsible for the implementation.

I am not at all certain that my formulation of the changelog
entry fulfill all your requirements, so do regard also that
as a valid reason for patch rejection, besides any further
nit picking in the C-code itself.

The corresponding changes to "src/tftp.c" will have to avait
a few days more until I finalize the details. A client is
always more delicate than an inetd-supported server code.


Best regards as always,
Mats E A

-------------------------------------------------------
From cd51b27c2638581d8d790c38c7d82044ee265bb1 Mon Sep 17 00:00:00 2001
From: Mats Erik Andersson <address@hidden>
Date: Sun, 12 Sep 2010 02:13:21 +0200
Subject: [PATCH] Implement IPv6 capability for the TFTP server.

---
 ChangeLog               |    9 +++++++++
 libinetutils/tftpsubs.c |    2 +-
 src/tftpd.c             |   45 ++++++++++++++++++++++++++++-----------------
 3 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7f3efb3..9cdbaaa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2010-09-12  Mats Erik Andersson <address@hidden>
+
+       * libinetutils/tftpsubs.c (synchnet): Upgrade the variable "from"
+       to be "struct sockaddr_storage".
+       * src/tftpd.c: Upgrade all "sockaddr_in" to "sockaddr_storage".
+       Accurate use of "fromlen" to track length of address structure.
+       (tftp): Let logging display "IPv4", "IPv6, or "?".
+       (verifyhost): New signature. Uses getnameinfo() as resolver.
+
 2010-09-09  Mats Erik Andersson <address@hidden>
 
        * src/tftp.c (peeraddr, f, trace, verbose, rexmtval)
diff --git a/libinetutils/tftpsubs.c b/libinetutils/tftpsubs.c
index bc1f84a..6fa78bc 100644
--- a/libinetutils/tftpsubs.c
+++ b/libinetutils/tftpsubs.c
@@ -285,7 +285,7 @@ synchnet (int f)
 {
   int i, j = 0;
   char rbuf[PKTSIZE];
-  struct sockaddr_in from;
+  struct sockaddr_storage from;
   socklen_t fromlen;
 
   while (1)
diff --git a/src/tftpd.c b/src/tftpd.c
index 70602fa..355fc0e 100644
--- a/src/tftpd.c
+++ b/src/tftpd.c
@@ -101,7 +101,7 @@ static int maxtimeout = 5 * TIMEOUT;
 #define PKTSIZE        SEGSIZE+4
 static char buf[PKTSIZE];
 static char ackbuf[PKTSIZE];
-static struct sockaddr_in from;
+static struct sockaddr_storage from;
 static socklen_t fromlen;
 
 void tftp (struct tftphdr *, int);
@@ -124,7 +124,7 @@ static int logging;
 
 static const char *errtomsg (int);
 static void nak (int);
-static const char *verifyhost (struct sockaddr_in *);
+static const char *verifyhost (struct sockaddr_storage *, socklen_t);
 
 
 
@@ -172,7 +172,7 @@ main (int argc, char *argv[])
   int index;
   register struct tftphdr *tp;
   int on, n;
-  struct sockaddr_in sin;
+  struct sockaddr_storage sin;
 
   set_program_name (argv[0]);
   iu_argp_init ("tftpd", default_program_authors);
@@ -268,24 +268,29 @@ main (int argc, char *argv[])
        exit (EXIT_SUCCESS);
       }
   }
-  from.sin_family = AF_INET;
+
   alarm (0);
   close (0);
   close (1);
-  peer = socket (AF_INET, SOCK_DGRAM, 0);
+
+  /* The peer's address 'from' is valid at this point.
+   * 'from.ss_family' contains the correct address
+   * family for any callback connection, and 'fromlen'
+   * is the length of the corresponding address structure. */
+  peer = socket (from.ss_family, SOCK_DGRAM, 0);
   if (peer < 0)
     {
       syslog (LOG_ERR, "socket: %m\n");
       exit (EXIT_FAILURE);
     }
   memset (&sin, 0, sizeof (sin));
-  sin.sin_family = AF_INET;
-  if (bind (peer, (struct sockaddr *) &sin, sizeof (sin)) < 0)
+  sin.ss_family = from.ss_family;
+  if (bind (peer, (struct sockaddr *) &sin, fromlen) < 0)
     {
       syslog (LOG_ERR, "bind: %m\n");
       exit (EXIT_FAILURE);
     }
-  if (connect (peer, (struct sockaddr *) &from, sizeof (from)) < 0)
+  if (connect (peer, (struct sockaddr *) &from, fromlen) < 0)
     {
       syslog (LOG_ERR, "connect: %m\n");
       exit (EXIT_FAILURE);
@@ -360,8 +365,10 @@ again:
   ecode = (*pf->f_validate) (&filename, tp->th_opcode);
   if (logging)
     {
-      syslog (LOG_INFO, "%s: %s request for %s: %s",
-             verifyhost (&from),
+      syslog (LOG_INFO, "%s (%s): %s request for %s: %s",
+             verifyhost (&from, fromlen),
+             from.ss_family == AF_INET ? "IPv4"
+               : (from.ss_family == AF_INET6 ? "IPv6" : "?"),
              tp->th_opcode == WRQ ? "write" : "read",
              filename, errtomsg (ecode));
     }
@@ -737,16 +744,20 @@ nak (int error)
 }
 
 static const char *
-verifyhost (struct sockaddr_in *fromp)
+verifyhost (struct sockaddr_storage *fromp, socklen_t frlen)
 {
-  struct hostent *hp;
+  int rc;
+  static char host[NI_MAXHOST];
 
-  hp = gethostbyaddr ((char *) &fromp->sin_addr, sizeof (fromp->sin_addr),
-                     fromp->sin_family);
-  if (hp)
-    return hp->h_name;
+  rc = getnameinfo ((struct sockaddr *) fromp, frlen,
+                   host, sizeof (host), NULL, 0, 0);
+  if (rc == 0)
+    return host;
   else
-    return inet_ntoa (fromp->sin_addr);
+    {
+      syslog (LOG_ERR, "getnameinfo: %s\n", gai_strerror(rc));
+      return "0.0.0.0";
+    }
 }
 
 static const char usage_str[] =
-- 
1.7.0

Attachment: signature.asc
Description: Digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]