Re: [resend] ipv6 support for tftp

2012-04-27 Thread Brad Smith

On 19/04/12 2:54 PM, Gleydson Soares wrote:

On Tue, Mar 06, 2012 at 09:32:47AM +, Stuart Henderson wrote:

On 2011/01/22 19:40, Gleydson Soares wrote:

can anyone test this diff? your feedback will be most welcome
On Wed, Sep 08, 2010 at 11:51:11AM -0300, Gleydson Soares wrote:

hi,

- ipv6 support for tftp client.

based on an old itojun's diff.


weerd@ pointed out this old diff - here's a slightly updated version;
only minor tweaks from gsoares@ version: whitespace nits in some lines
touched in the diff, and I rewrote the manpage diff.

works for me against usr/sbin/tftpd; any comments?


Tested against OpenBSD's tftpd and dnsmasq. Working fine for me.

--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.



Re: [resend] ipv6 support for tftp

2012-04-27 Thread Gleydson Soares
On Fri, Apr 27, 2012 at 12:34:19PM -0400, Brad Smith wrote:
 Tested against OpenBSD's tftpd and dnsmasq. Working fine for me.

here is an updated version of the diff.

- setpeer0() and setpeer() were renamed accordingly for clarity and 
consistency. (requested by henning@)
- fix memleak(call freeaddrinfo() to release *res0)
- checks against valid server port number
- man page tweaked based on points by sthen@ and jmc@

this diff has been OK by sthen@ jmc@ henning@
i will commit it tomorrow if no objections till there.
? 1
? tftp_ipv6_3.diff
Index: main.c
===
RCS file: /cvs/src/usr.bin/tftp/main.c,v
retrieving revision 1.30
diff -u -p -r1.30 main.c
--- main.c  27 Oct 2009 23:59:44 -  1.30
+++ main.c  24 Apr 2012 15:39:19 -
@@ -68,7 +68,8 @@ void   put(int, char **);
 voidquit(int, char **);
 voidsetascii(int, char **);
 voidsetbinary(int, char **);
-voidsetpeer(int, char **);
+voidsetpeer(char *, char *);
+voidparsearg(int, char **);
 voidsetrexmt(int, char **);
 voidsettimeout(int, char **);
 voidsettrace(int, char **);
@@ -86,9 +87,8 @@ static __dead void command(void);
 struct cmd *getcmd(char *);
 char   *tail(char *);
 
-struct sockaddr_in  peeraddr;
+struct sockaddr_storage peeraddr;
 int f;
-short   port;
 int trace;
 int verbose;
 int connected;
@@ -98,7 +98,6 @@ intmargc;
 char   *margv[MAXARGV+1];
 char   *prompt = tftp;
 voidintr(int);
-struct servent *sp;
 int rexmtval = TIMEOUT;
 int maxtimeout = 5 * TIMEOUT;
 charhostname[MAXHOSTNAMELEN];
@@ -134,7 +133,7 @@ struct cmd {
 };
 
 struct cmd cmdtab[] = {
-   { connect,chelp,  setpeer },
+   { connect,chelp,  parsearg },
{ mode,   mhelp,  modecmd },
{ put,shelp,  put },
{ get,rhelp,  get },
@@ -170,26 +169,14 @@ structmodes {
 int
 main(int argc, char *argv[])
 {
-   struct sockaddr_in  s_in;
-
-   /* socket, bind */
-   sp = getservbyname(tftp, udp);
-   if (sp == 0)
-   errx(1, udp/tftp: unknown service);
-   f = socket(AF_INET, SOCK_DGRAM, 0);
-   if (f  0)
-   err(3, socket);
-   bzero((char *)s_in, sizeof(s_in));
-   s_in.sin_family = AF_INET;
-   if (bind(f, (struct sockaddr *)s_in, sizeof(s_in))  0)
-   err(1, bind);
+   f = -1;
 
/* set default transfer mode */
strlcpy(mode, netascii, sizeof(mode));
 
/* set peer if given */
if (argc  1)
-   setpeer(argc, argv);
+   parsearg(argc, argv);
 
/* catch SIGINT */
signal(SIGINT, intr);
@@ -205,11 +192,73 @@ main(int argc, char *argv[])
 }
 
 void
-setpeer(int argc, char *argv[])
+setpeer(char *host, char *port)
 {
-   struct hostent  *host;
-   const char  *errstr;
+   struct addrinfo hints, *res0, *res;
+   int error;
+   struct sockaddr_storage ss;
+   char *cause = unknown;
+
+   if (connected) {
+   close(f);
+   f = -1;
+   }
+   connected = 0;
+
+   memset(hints, 0, sizeof(hints));
+   hints.ai_family = PF_UNSPEC;
+   hints.ai_socktype = SOCK_DGRAM;
+   hints.ai_protocol = IPPROTO_UDP;
+   hints.ai_flags = AI_CANONNAME;
+   if (!port)
+   port = tftp;
+   error = getaddrinfo(host, port, hints, res0);
+   if (error) {
+   warnx(%s, gai_strerror(error));
+   return;
+   }
+
+   for (res = res0; res; res = res-ai_next) {
+   if (res-ai_addrlen  sizeof(peeraddr))
+   continue;
+   f = socket(res-ai_family, res-ai_socktype, res-ai_protocol);
+   if (f  0) {
+   cause = socket;
+   continue;
+   }
 
+   memset(ss, 0, sizeof(ss));
+   ss.ss_family = res-ai_family;
+   ss.ss_len = res-ai_addrlen;
+   if (bind(f, (struct sockaddr *)ss, ss.ss_len)  0) {
+   cause = bind;
+   close(f);
+   f = -1;
+   continue;
+   }
+
+   break;
+   }
+
+   if (f  0)
+   warn(%s, cause);
+   else {
+   /* res-ai_addr = sizeof(peeraddr) is guaranteed */
+   memcpy(peeraddr, res-ai_addr, res-ai_addrlen);
+   if (res-ai_canonname) {
+   (void) strncpy(hostname, res-ai_canonname,
+   

Re: [resend] ipv6 support for tftp

2012-04-19 Thread Gleydson Soares
On Tue, Mar 06, 2012 at 09:32:47AM +, Stuart Henderson wrote:
 On 2011/01/22 19:40, Gleydson Soares wrote:
  can anyone test this diff? your feedback will be most welcome
  On Wed, Sep 08, 2010 at 11:51:11AM -0300, Gleydson Soares wrote:
   hi,
   
   - ipv6 support for tftp client.
   
   based on an old itojun's diff.
 
 weerd@ pointed out this old diff - here's a slightly updated version;
 only minor tweaks from gsoares@ version: whitespace nits in some lines
 touched in the diff, and I rewrote the manpage diff.
 
 works for me against usr/sbin/tftpd; any comments?

anyone willing to give this diff a go?
Index: main.c
===
RCS file: /cvs/src/usr.bin/tftp/main.c,v
retrieving revision 1.30
diff -u -p -r1.30 main.c
--- main.c  27 Oct 2009 23:59:44 -  1.30
+++ main.c  19 Apr 2012 18:47:44 -
@@ -68,6 +68,7 @@ void   put(int, char **);
 voidquit(int, char **);
 voidsetascii(int, char **);
 voidsetbinary(int, char **);
+voidsetpeer0(char *, char *);
 voidsetpeer(int, char **);
 voidsetrexmt(int, char **);
 voidsettimeout(int, char **);
@@ -86,9 +87,8 @@ static __dead void command(void);
 struct cmd *getcmd(char *);
 char   *tail(char *);
 
-struct sockaddr_in  peeraddr;
+struct sockaddr_storage peeraddr;
 int f;
-short   port;
 int trace;
 int verbose;
 int connected;
@@ -98,7 +98,6 @@ intmargc;
 char   *margv[MAXARGV+1];
 char   *prompt = tftp;
 voidintr(int);
-struct servent *sp;
 int rexmtval = TIMEOUT;
 int maxtimeout = 5 * TIMEOUT;
 charhostname[MAXHOSTNAMELEN];
@@ -170,19 +169,7 @@ struct modes {
 int
 main(int argc, char *argv[])
 {
-   struct sockaddr_in  s_in;
-
-   /* socket, bind */
-   sp = getservbyname(tftp, udp);
-   if (sp == 0)
-   errx(1, udp/tftp: unknown service);
-   f = socket(AF_INET, SOCK_DGRAM, 0);
-   if (f  0)
-   err(3, socket);
-   bzero((char *)s_in, sizeof(s_in));
-   s_in.sin_family = AF_INET;
-   if (bind(f, (struct sockaddr *)s_in, sizeof(s_in))  0)
-   err(1, bind);
+   f = -1;
 
/* set default transfer mode */
strlcpy(mode, netascii, sizeof(mode));
@@ -205,11 +192,69 @@ main(int argc, char *argv[])
 }
 
 void
-setpeer(int argc, char *argv[])
+setpeer0(char *host, char *port)
 {
-   struct hostent  *host;
-   const char  *errstr;
+   struct addrinfo hints, *res0, *res;
+   int error;
+   struct sockaddr_storage ss;
+   char *cause = unknown;
+
+   if (connected) {
+   close(f);
+   f = -1;
+   connected = 0;
+   }
+
+   memset(hints, 0, sizeof(hints));
+   hints.ai_family = PF_UNSPEC;
+   hints.ai_socktype = SOCK_DGRAM;
+   hints.ai_protocol = IPPROTO_UDP;
+   hints.ai_flags = AI_CANONNAME;
+   if (!port)
+   port = tftp;
+   error = getaddrinfo(host, port, hints, res0);
+   if (error) {
+   warnx(%s, gai_strerror(error));
+   return;
+   }
+
+   for (res = res0; res; res = res-ai_next) {
+   f = socket(res-ai_family, res-ai_socktype, res-ai_protocol);
+   if (f  0) {
+   cause = socket;
+   continue;
+   }
+
+   memset(ss, 0, sizeof(ss));
+   ss.ss_family = res-ai_family;
+   ss.ss_len = res-ai_addrlen;
+   if (bind(f, (struct sockaddr *)ss, ss.ss_len)  0) {
+   cause = bind;
+   close(f);
+   f = -1;
+   continue;
+   }
+
+   break;
+   }
+
+   if (f  0)
+   warn(%s, cause);
+   else {
+   memcpy(peeraddr, res-ai_addr, res-ai_addrlen);
+   if (res-ai_canonname) {
+   (void) strncpy(hostname, res-ai_canonname,
+   sizeof(hostname));
+   } else
+   (void) strncpy(hostname, host, sizeof(hostname));
+   hostname[sizeof(hostname)-1] = 0;
+   connected = 1;
+   }
+}
 
+void
+setpeer(int argc, char *argv[])
+{
if (argc  2) {
strlcpy(line, Connect , sizeof(line));
printf((to) );
@@ -223,32 +268,10 @@ setpeer(int argc, char *argv[])
printf(usage: %s [host [port]]\n, argv[0]);
return;
}
-   if (inet_aton(argv[1], peeraddr.sin_addr) != 0) {
-

Re: [resend] ipv6 support for tftp

2012-03-06 Thread Stuart Henderson
On 2011/01/22 19:40, Gleydson Soares wrote:
 can anyone test this diff? your feedback will be most welcome
 On Wed, Sep 08, 2010 at 11:51:11AM -0300, Gleydson Soares wrote:
  hi,
  
  - ipv6 support for tftp client.
  
  based on an old itojun's diff.

weerd@ pointed out this old diff - here's a slightly updated version;
only minor tweaks from gsoares@ version: whitespace nits in some lines
touched in the diff, and I rewrote the manpage diff.

works for me against usr/sbin/tftpd; any comments?

Index: tftp.1
===
RCS file: /cvs/src/usr.bin/tftp/tftp.1,v
retrieving revision 1.19
diff -u -p -r1.19 tftp.1
--- tftp.1  1 Mar 2012 03:47:19 -   1.19
+++ tftp.1  6 Mar 2012 09:30:31 -
@@ -156,6 +156,10 @@ When using the
 argument, the
 .Ar host
 will be used as the default host for future transfers.
+A
+.Ar host
+specified as a numeric IPv6 address must be wrapped in square brackets:
+.Ar [host]:filename .
 If
 .Ar remotename
 is specified, the file is stored remotely as
Index: main.c
===
RCS file: /cvs/src/usr.bin/tftp/main.c,v
retrieving revision 1.30
diff -u -p -r1.30 main.c
--- main.c  27 Oct 2009 23:59:44 -  1.30
+++ main.c  6 Mar 2012 09:30:31 -
@@ -68,6 +68,7 @@ void   put(int, char **);
 voidquit(int, char **);
 voidsetascii(int, char **);
 voidsetbinary(int, char **);
+voidsetpeer0(char *, char *);
 voidsetpeer(int, char **);
 voidsetrexmt(int, char **);
 voidsettimeout(int, char **);
@@ -86,9 +87,8 @@ static __dead void command(void);
 struct cmd *getcmd(char *);
 char   *tail(char *);
 
-struct sockaddr_in  peeraddr;
+struct sockaddr_storage peeraddr;
 int f;
-short   port;
 int trace;
 int verbose;
 int connected;
@@ -98,7 +98,6 @@ intmargc;
 char   *margv[MAXARGV+1];
 char   *prompt = tftp;
 voidintr(int);
-struct servent *sp;
 int rexmtval = TIMEOUT;
 int maxtimeout = 5 * TIMEOUT;
 charhostname[MAXHOSTNAMELEN];
@@ -170,19 +169,7 @@ struct modes {
 int
 main(int argc, char *argv[])
 {
-   struct sockaddr_in  s_in;
-
-   /* socket, bind */
-   sp = getservbyname(tftp, udp);
-   if (sp == 0)
-   errx(1, udp/tftp: unknown service);
-   f = socket(AF_INET, SOCK_DGRAM, 0);
-   if (f  0)
-   err(3, socket);
-   bzero((char *)s_in, sizeof(s_in));
-   s_in.sin_family = AF_INET;
-   if (bind(f, (struct sockaddr *)s_in, sizeof(s_in))  0)
-   err(1, bind);
+   f = -1;
 
/* set default transfer mode */
strlcpy(mode, netascii, sizeof(mode));
@@ -205,11 +192,69 @@ main(int argc, char *argv[])
 }
 
 void
-setpeer(int argc, char *argv[])
+setpeer0(char *host, char *port)
 {
-   struct hostent  *host;
-   const char  *errstr;
+   struct addrinfo hints, *res0, *res;
+   int error;
+   struct sockaddr_storage ss;
+   char *cause = unknown;
+
+   if (connected) {
+   close(f);
+   f = -1;
+   connected = 0;
+   }
+
+   memset(hints, 0, sizeof(hints));
+   hints.ai_family = PF_UNSPEC;
+   hints.ai_socktype = SOCK_DGRAM;
+   hints.ai_protocol = IPPROTO_UDP;
+   hints.ai_flags = AI_CANONNAME;
+   if (!port)
+   port = tftp;
+   error = getaddrinfo(host, port, hints, res0);
+   if (error) {
+   warnx(%s, gai_strerror(error));
+   return;
+   }
+
+   for (res = res0; res; res = res-ai_next) {
+   f = socket(res-ai_family, res-ai_socktype, res-ai_protocol);
+   if (f  0) {
+   cause = socket;
+   continue;
+   }
+
+   memset(ss, 0, sizeof(ss));
+   ss.ss_family = res-ai_family;
+   ss.ss_len = res-ai_addrlen;
+   if (bind(f, (struct sockaddr *)ss, ss.ss_len)  0) {
+   cause = bind;
+   close(f);
+   f = -1;
+   continue;
+   }
+
+   break;
+   }
+
+   if (f  0)
+   warn(%s, cause);
+   else {
+   memcpy(peeraddr, res-ai_addr, res-ai_addrlen);
+   if (res-ai_canonname) {
+   (void) strncpy(hostname, res-ai_canonname,
+   sizeof(hostname));
+   } else
+   (void) strncpy(hostname, host, sizeof(hostname));
+