Re: [resend] ipv6 support for tftp
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
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
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
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)); +