Submitted by Reinhard Max
patch #8311: Add IPv6 support to the -Pnet:host:port option * ser_posix.c (net_open): Rewrite to use getaddrinfo() rather than gethostbyname() * avrdude.1: Document IPv6 feature * doc/avrdude.texi: (Dito) git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1421 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
f8cbb6ddad
commit
e5aca9db5b
|
@ -1,3 +1,12 @@
|
||||||
|
2018-01-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||||
|
|
||||||
|
Submitted by Reinhard Max
|
||||||
|
patch #8311: Add IPv6 support to the -Pnet:host:port option
|
||||||
|
* ser_posix.c (net_open): Rewrite to use getaddrinfo()
|
||||||
|
rather than gethostbyname()
|
||||||
|
* avrdude.1: Document IPv6 feature
|
||||||
|
* doc/avrdude.texi: (Dito)
|
||||||
|
|
||||||
2018-01-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
2018-01-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||||
|
|
||||||
Submitted by Maciej:
|
Submitted by Maciej:
|
||||||
|
|
2
NEWS
2
NEWS
|
@ -15,6 +15,7 @@ Current:
|
||||||
- UPDI support added (AVR8X family)
|
- UPDI support added (AVR8X family)
|
||||||
- TPI support for USBtinyISP
|
- TPI support for USBtinyISP
|
||||||
- AVR Doper uses libhidapi rather than raw libusb (patch #9033)
|
- AVR Doper uses libhidapi rather than raw libusb (patch #9033)
|
||||||
|
- -P net:host:port can use IPv6 now (Posix systems only)
|
||||||
|
|
||||||
* New devices supported:
|
* New devices supported:
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ Current:
|
||||||
patch #8910: ATxmega32c4 and ATxmega16c4 have wrong signatures
|
patch #8910: ATxmega32c4 and ATxmega16c4 have wrong signatures
|
||||||
patch #8219: Fix boot_start for xmega devices on jtagmkII
|
patch #8219: Fix boot_start for xmega devices on jtagmkII
|
||||||
patch #9185: Add extended_param to usbasp.c - erasing
|
patch #9185: Add extended_param to usbasp.c - erasing
|
||||||
|
patch #8311: Add IPv6 support to the -Pnet:host:port option
|
||||||
|
|
||||||
* Internals:
|
* Internals:
|
||||||
- New avrdude.conf keyword "family_id", used to verify SIB attributes
|
- New avrdude.conf keyword "family_id", used to verify SIB attributes
|
||||||
|
|
|
@ -505,12 +505,19 @@ network connection to (TCP)
|
||||||
on
|
on
|
||||||
.Ar host
|
.Ar host
|
||||||
is established.
|
is established.
|
||||||
|
Square brackets may be placed around
|
||||||
|
.Ar host
|
||||||
|
to improve readability, for numeric IPv6 addresses (e.g.
|
||||||
|
.Li net:[2001:db8::42]:1337 ) .
|
||||||
The remote endpoint is assumed to be a terminal or console server
|
The remote endpoint is assumed to be a terminal or console server
|
||||||
that connects the network stream to a local serial port where the
|
that connects the network stream to a local serial port where the
|
||||||
actual programmer has been attached to.
|
actual programmer has been attached to.
|
||||||
The port is assumed to be properly configured, for example using a
|
The port is assumed to be properly configured, for example using a
|
||||||
transparent 8-bit data connection without parity at 115200 Baud
|
transparent 8-bit data connection without parity at 115200 Baud
|
||||||
for a STK500.
|
for a STK500.
|
||||||
|
.Pp
|
||||||
|
Note: The ability to handle IPv6 hostnames and addresses is limited to
|
||||||
|
Posix systems (by now).
|
||||||
.It Fl q
|
.It Fl q
|
||||||
Disable (or quell) output of the progress bar while reading or writing
|
Disable (or quell) output of the progress bar while reading or writing
|
||||||
to the device. Specify it a second time for even quieter operation.
|
to the device. Specify it a second time for even quieter operation.
|
||||||
|
|
|
@ -218,7 +218,7 @@ AC_CHECK_HEADERS([netinet/in.h])
|
||||||
AC_CHECK_LIB([ws2_32], [puts])
|
AC_CHECK_LIB([ws2_32], [puts])
|
||||||
|
|
||||||
# Checks for library functions.
|
# Checks for library functions.
|
||||||
AC_CHECK_FUNCS([memset select strcasecmp strdup strerror strncasecmp strtol strtoul gettimeofday usleep])
|
AC_CHECK_FUNCS([memset select strcasecmp strdup strerror strncasecmp strtol strtoul gettimeofday usleep getaddrinfo])
|
||||||
|
|
||||||
AC_MSG_CHECKING([for a Win32 HID libray])
|
AC_MSG_CHECKING([for a Win32 HID libray])
|
||||||
SAVED_LIBS="${LIBS}"
|
SAVED_LIBS="${LIBS}"
|
||||||
|
|
|
@ -557,6 +557,9 @@ higher level protocol (as opposed to bit-bang style programmers),
|
||||||
In this case, instead of trying to open a local device, a TCP
|
In this case, instead of trying to open a local device, a TCP
|
||||||
network connection to (TCP) @var{port} on @var{host}
|
network connection to (TCP) @var{port} on @var{host}
|
||||||
is established.
|
is established.
|
||||||
|
Square brackets may be placed around @var{host} to improve
|
||||||
|
readability for numeric IPv6 addresses (e.g.
|
||||||
|
@code{net:[2001:db8::42]:1337}).
|
||||||
The remote endpoint is assumed to be a terminal or console server
|
The remote endpoint is assumed to be a terminal or console server
|
||||||
that connects the network stream to a local serial port where the
|
that connects the network stream to a local serial port where the
|
||||||
actual programmer has been attached to.
|
actual programmer has been attached to.
|
||||||
|
@ -564,6 +567,8 @@ The port is assumed to be properly configured, for example using a
|
||||||
transparent 8-bit data connection without parity at 115200 Baud
|
transparent 8-bit data connection without parity at 115200 Baud
|
||||||
for a STK500.
|
for a STK500.
|
||||||
|
|
||||||
|
Note: The ability to handle IPv6 hostnames and addresses is limited to
|
||||||
|
Posix systems (by now).
|
||||||
|
|
||||||
@item -q
|
@item -q
|
||||||
Disable (or quell) output of the progress bar while reading or writing
|
Disable (or quell) output of the progress bar while reading or writing
|
||||||
|
|
98
ser_posix.c
98
ser_posix.c
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#if !defined(WIN32NATIVE)
|
#if !defined(WIN32NATIVE)
|
||||||
|
|
||||||
|
#include "ac_cfg.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -36,7 +37,6 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
@ -159,23 +159,35 @@ static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||||
static int
|
static int
|
||||||
net_open(const char *port, union filedescriptor *fdp)
|
net_open(const char *port, union filedescriptor *fdp)
|
||||||
{
|
{
|
||||||
char *hstr, *pstr, *end;
|
#ifdef HAVE_GETADDRINFO
|
||||||
unsigned int pnum;
|
char *hp, *hstr, *pstr;
|
||||||
int fd;
|
int s, fd, ret = -1;
|
||||||
struct sockaddr_in sockaddr;
|
struct addrinfo hints;
|
||||||
struct hostent *hp;
|
struct addrinfo *result, *rp;
|
||||||
|
|
||||||
if ((hstr = strdup(port)) == NULL) {
|
if ((hstr = hp = strdup(port)) == NULL) {
|
||||||
avrdude_message(MSG_INFO, "%s: net_open(): Out of memory!\n",
|
avrdude_message(MSG_INFO, "%s: net_open(): Out of memory!\n",
|
||||||
progname);
|
progname);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((pstr = strchr(hstr, ':')) == NULL) || (pstr == hstr)) {
|
/*
|
||||||
|
* As numeric IPv6 addresses use colons as separators, we need to
|
||||||
|
* look for the last colon here, which separates the port number or
|
||||||
|
* service name from the host or IP address.
|
||||||
|
*/
|
||||||
|
if (((pstr = strrchr(hstr, ':')) == NULL) || (pstr == hstr)) {
|
||||||
avrdude_message(MSG_INFO, "%s: net_open(): Mangled host:port string \"%s\"\n",
|
avrdude_message(MSG_INFO, "%s: net_open(): Mangled host:port string \"%s\"\n",
|
||||||
progname, hstr);
|
progname, hstr);
|
||||||
free(hstr);
|
goto error;
|
||||||
return -1;
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove brackets from the host part, if present.
|
||||||
|
*/
|
||||||
|
if (*hstr == '[' && *(pstr-1) == ']') {
|
||||||
|
hstr++;
|
||||||
|
*(pstr-1) = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -183,43 +195,49 @@ net_open(const char *port, union filedescriptor *fdp)
|
||||||
*/
|
*/
|
||||||
*pstr++ = '\0';
|
*pstr++ = '\0';
|
||||||
|
|
||||||
pnum = strtoul(pstr, &end, 10);
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
s = getaddrinfo(hstr, pstr, &hints, &result);
|
||||||
|
|
||||||
if ((*pstr == '\0') || (*end != '\0') || (pnum == 0) || (pnum > 65535)) {
|
if (s != 0) {
|
||||||
avrdude_message(MSG_INFO, "%s: net_open(): Bad port number \"%s\"\n",
|
avrdude_message(MSG_INFO,
|
||||||
progname, pstr);
|
"%s: net_open(): Cannot resolve "
|
||||||
free(hstr);
|
"host=\"%s\", port=\"%s\": %s\n",
|
||||||
return -1;
|
progname, hstr, pstr, gai_strerror(s));
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||||
if ((hp = gethostbyname(hstr)) == NULL) {
|
fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||||
avrdude_message(MSG_INFO, "%s: net_open(): unknown host \"%s\"\n",
|
if (fd == -1) {
|
||||||
progname, hstr);
|
/* This one failed, loop over */
|
||||||
free(hstr);
|
continue;
|
||||||
return -1;
|
}
|
||||||
|
if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1) {
|
||||||
|
/* Success, we are connected */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
|
if (rp == NULL) {
|
||||||
free(hstr);
|
avrdude_message(MSG_INFO, "%s: net_open(): Cannot connect: %s\n",
|
||||||
|
|
||||||
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
|
|
||||||
avrdude_message(MSG_INFO, "%s: net_open(): Cannot open socket: %s\n",
|
|
||||||
progname, strerror(errno));
|
progname, strerror(errno));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
memset(&sockaddr, 0, sizeof(struct sockaddr_in));
|
fdp->ifd = fd;
|
||||||
sockaddr.sin_family = AF_INET;
|
ret = 0;
|
||||||
sockaddr.sin_port = htons(pnum);
|
|
||||||
memcpy(&(sockaddr.sin_addr.s_addr), hp->h_addr, sizeof(struct in_addr));
|
|
||||||
|
|
||||||
if (connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
|
|
||||||
avrdude_message(MSG_INFO, "%s: net_open(): Connect failed: %s\n",
|
|
||||||
progname, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
freeaddrinfo(result);
|
||||||
|
|
||||||
fdp->ifd = fd;
|
error:
|
||||||
return 0;
|
free(hp);
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
avrdude_message(MSG_INFO,
|
||||||
|
"%s: Networking is not supported on your platform.\n"
|
||||||
|
"If you need it, please open a bug report.\n", progname);
|
||||||
|
return -1;
|
||||||
|
#endif /* HAVE_GETADDRINFO */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue