bug-inetutils
[Top][All Lists]
Advanced

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

Re: [bug-inetutils] [PATCH] Make `tftpd' IPv6-compatible


From: Guillem Jover
Subject: Re: [bug-inetutils] [PATCH] Make `tftpd' IPv6-compatible
Date: Wed, 8 Sep 2010 06:38:06 +0200
User-agent: Mutt/1.5.20 (2009-06-14)

Hi!

On Tue, 2010-09-07 at 18:05:37 +0200, Ludovic Courtès wrote:
> The attached patch makes ‘tftpd’ IPv6-compatible.  As a side effect, it
> makes it usable (!) on current GNU/Linux when a client connects via an
> address other than the loopback address (FROM is always AF_INET6 on my
> machine.)
> 
> The patch assumes that IPv6 support is available.  Besides, it’d be
> better to import Gnulib’s ‘inet_ntop’ modules.

Mats was already working on this, see also my review on that thread.
I'll comment on this one anyway, as I've seen some problems.


> From 3be7f44305103b39a0e1bc79a9960feb5d142485 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <address@hidden>
> Date: Tue, 7 Sep 2010 17:53:23 +0200
> Subject: [PATCH] Make `tftpd' IPv6-compatible.

> diff --git a/src/tftpd.c b/src/tftpd.c
> index 70602fa..719db81 100644
> --- a/src/tftpd.c
> +++ b/src/tftpd.c
> @@ -124,7 +124,8 @@ static int logging;
>  
>  static const char *errtomsg (int);
>  static void nak (int);
> -static const char *verifyhost (struct sockaddr_in *);
> +static char *verify_host (struct sockaddr_storage *, socklen_t,
> +                       char *, size_t);

Why remove the constness? the returned string is not supposed to be
modified nor freed.

> @@ -268,18 +269,19 @@ main (int argc, char *argv[])

>    memset (&sin, 0, sizeof (sin));
> -  sin.sin_family = AF_INET;
> +  sin.ss_family = from.ss_family;
>    if (bind (peer, (struct sockaddr *) &sin, sizeof (sin)) < 0)

The socklen_t argument should be fromlen so that this works on the
BSDs.

> @@ -360,8 +362,10 @@ again:
>    ecode = (*pf->f_validate) (&filename, tp->th_opcode);
>    if (logging)
>      {
> +      char node[1024];

This should be NI_MAXHOST instead.

>        syslog (LOG_INFO, "%s: %s request for %s: %s",
> -           verifyhost (&from),
> +           verify_host (&from, sizeof from,

Here fromlen too.

> +                        node, sizeof node),
>             tp->th_opcode == WRQ ? "write" : "read",
>             filename, errtomsg (ecode));
>      }
> @@ -736,17 +740,29 @@ nak (int error)
>      syslog (LOG_ERR, "nak: %m\n");
>  }
>  
> -static const char *
> -verifyhost (struct sockaddr_in *fromp)
> +static char *
> +verify_host (struct sockaddr_storage *addr, socklen_t addr_len,
> +          char *host_and_service, size_t len)
>  {
> -  struct hostent *hp;
> -
> -  hp = gethostbyaddr ((char *) &fromp->sin_addr, sizeof (fromp->sin_addr),
> -                   fromp->sin_family);
> -  if (hp)
> -    return hp->h_name;
> +  int err;
> +  char host[512], service[256];

Here NI_MAXHOST and NI_MAXSERV instead of magic values.

> +
> +  err = getnameinfo ((struct sockaddr *) addr, addr_len,
> +                  host, sizeof host,
> +                  service, sizeof service,
> +                  0);
> +
> +  if (err)
> +    inet_ntop (addr->ss_family,
> +            addr->ss_family == AF_INET
> +            ? (void *) &((struct sockaddr_in *) addr)->sin_addr
> +            : (void *) &((struct sockaddr_in6 *) addr)->sin6_addr,
> +            host_and_service, len);

The inet_ntop call should not be needed, getnameinfo should be able to
handle numeric addresses just fine.

>    else
> -    return inet_ntoa (fromp->sin_addr);
> +    snprintf (host_and_service, len, "%s%s%s",
> +           host, *service ? "/" : "", service);
> +
> +  return host_and_service;
>  }

regards,
guillem



reply via email to

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