get ready for IPv6

git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@2883 7ae35d74-ebe9-4afe-98af-79ac388436b8
Hamlib-1.2.11
Stéphane Fillod, F8CFE 2010-04-16 20:50:14 +00:00
rodzic 9082a3a5da
commit 6ee58f0bff
8 zmienionych plików z 298 dodań i 124 usunięć

Wyświetl plik

@ -146,15 +146,7 @@ AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, main,
AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(ws2_32, main,
[NET_LIBS="$NET_LIBS -lws2_32"], [], []))
LIBS="$LIBS $NET_LIBS"
AC_CHECK_FUNCS(getaddrinfo gai_strerror)
AC_CHECK_TYPES([struct addrinfo],[],[],[
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
])
HL_GETADDRINFO
LIBS=$hl_oldLibs
AC_SUBST(NET_LIBS)

Wyświetl plik

@ -1,7 +1,7 @@
EXTRA_DIST = getopt.c getopt.h getopt_long.c usleep.c \
termios.c win32termios.h gettimeofday.c
termios.c win32termios.h gettimeofday.c getaddrinfo.c
noinst_LTLIBRARIES = libmisc.la
libmisc_la_SOURCES =
libmisc_la_LIBADD = @LTLIBOBJS@
libmisc_la_LIBADD = @LTLIBOBJS@ @NET_LIBS@

130
lib/getaddrinfo.c 100644
Wyświetl plik

@ -0,0 +1,130 @@
/*
* Hamlib Interface - getaddrinfo replacement
* Copyright (c) 2000-2010 by Stephane Fillod
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/* Forcing WINVER in MinGW yanks in getaddrinfo(), but locks out Win95/Win98 */
/* #define WINVER 0x0501 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h> /* Standard input/output definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <sys/types.h>
#include <signal.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#elif HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
/*
* Replacement for getaddrinfo. Only one addrinfo is returned.
* Weak checking.
* Return 0 when success, otherwise -1.
*/
#ifndef HAVE_GETADDRINFO
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints, struct addrinfo **res)
{
struct addrinfo *p;
int ai_family, ai_socktype, ai_protocol, ai_flags;
/* limitation: service must be non null */
if (!service)
return -1;
if (hints == NULL) {
ai_family = AF_UNSPEC;
ai_socktype = 0;
ai_protocol = 0;
ai_flags = 0;
} else {
ai_family = hints->ai_family;
ai_socktype = hints->ai_socktype;
ai_protocol = hints->ai_protocol;
ai_flags = hints->ai_flags;
}
/* limitation: this replacement function only for IPv4 */
if (ai_family == AF_UNSPEC)
ai_family = AF_INET;
if (ai_family != AF_INET)
return -1;
p = malloc(sizeof(struct addrinfo));
if (!p)
return -1;
memset(p, 0, sizeof(struct addrinfo));
p->ai_family = ai_family;
p->ai_socktype = ai_socktype;
p->ai_protocol = ai_protocol;
p->ai_addrlen = sizeof(struct sockaddr_in);
p->ai_addr = malloc(p->ai_addrlen);
if (!p->ai_addr) {
free(p);
return -1;
}
memset((char *) p->ai_addr, 0, p->ai_addrlen);
((struct sockaddr_in*)p->ai_addr)->sin_family = p->ai_family;
/* limitation: the service must be a port _number_ */
((struct sockaddr_in*)p->ai_addr)->sin_port = htons(atoi(service));
/* limitation: the node must be in numbers-and-dots notation */
if (!node && (ai_flags & AI_PASSIVE))
((struct sockaddr_in*)p->ai_addr)->sin_addr.s_addr = INADDR_ANY;
else
((struct sockaddr_in*)p->ai_addr)->sin_addr.s_addr = inet_addr(node);
*res = p;
return 0;
}
void freeaddrinfo(struct addrinfo *res)
{
free(res->ai_addr);
free(res);
}
#endif /* !HAVE_GETADDRINFO */
#if !defined(HAVE_GAI_STRERROR) && !defined(gai_strerror)
const char *gai_strerror(int errcode)
{
return strerror(errcode);
}
#endif /* !HAVE_GAI_STRERROR */

Wyświetl plik

@ -7,6 +7,7 @@ MACROS = \
gr_doxygen.m4 \
gr_pwin32.m4 \
gr_swig.m4 \
hl_getaddrinfo.m4 \
libtool.m4 \
ltdl.m4 \
perl.m4 \

Wyświetl plik

@ -0,0 +1,107 @@
# Check for getaddrinfo replacement. -*- Autoconf -*-
# Copyright (c) 2010 by Stephane Fillod
#
# This file is part of Hamlib
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU Library General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
AC_DEFUN([HL_GETADDRINFO],
[
AC_CHECK_TYPES([struct addrinfo],[],[],[
#if HAVE_NETDB_H
# include <netdb.h>
#endif
#ifdef HAVE_WS2TCPIP_H
# include <ws2tcpip.h>
#endif
])
AC_CHECK_FUNCS([getaddrinfo gai_strerror])
dnl Checks for replacements
AC_REPLACE_FUNCS([getaddrinfo])
AH_BOTTOM(
[
/* Define missing prototypes, implemented in replacement lib */
#ifdef __cplusplus
extern "C" {
#endif
#ifndef HAVE_STRUCT_ADDRINFO
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#elif HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
struct sockaddr *ai_addr;
};
#endif
#ifndef HAVE_GETADDRINFO
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#elif HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
#ifndef AI_PASSIVE
#define AI_PASSIVE 0x0001
#endif
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints, struct addrinfo **res);
void freeaddrinfo(struct addrinfo *res);
#endif
#if !defined(HAVE_GAI_STRERROR) && !defined(gai_strerror)
const char *gai_strerror(int errcode);
#endif /* !HAVE_GAI_STRERROR */
#ifdef __cplusplus
}
#endif
])
])

Wyświetl plik

@ -1,6 +1,6 @@
/*
* Hamlib Interface - network communication low-level support
* Copyright (c) 2000-2008 by Stephane Fillod
* Copyright (c) 2000-2010 by Stephane Fillod
*
* $Id: network.c,v 1.6 2008-11-05 23:02:00 fillods Exp $
*
@ -45,8 +45,6 @@
#include <errno.h> /* Error number definitions */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
@ -70,72 +68,6 @@
#include "misc.h"
#ifndef HAVE_STRUCT_ADDRINFO
struct addrinfo {
int ai_family;
int ai_socktype;
int ai_protocol;
struct sockaddr *ai_addr;
socklen_t ai_addrlen;
};
#endif
/*
* Replacement for getaddrinfo. Only one addrinfo is returned.
* Weak checking.
*/
#ifndef HAVE_GETADDRINFO
static int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints, struct addrinfo **res)
{
struct addrinfo *p;
/* limitation: this replacement function only for IPv4 */
if (hints && hints->ai_family != AF_INET)
return EINVAL;
p = malloc(sizeof(struct addrinfo));
if (!p)
return ENOMEM;
memset(p, 0, sizeof(struct addrinfo));
p->ai_family = hints->ai_family;
p->ai_socktype = hints->ai_socktype;
p->ai_protocol = hints->ai_protocol;
p->ai_addrlen = sizeof(struct sockaddr_in);
p->ai_addr = malloc(p->ai_addrlen);
if (!p->ai_addr) {
free(p);
return ENOMEM;
}
memset((char *) p->ai_addr, 0, p->ai_addrlen);
((struct sockaddr_in*)p->ai_addr)->sin_family = p->ai_family;
/* limitation: the service must be a port _number_ */
((struct sockaddr_in*)p->ai_addr)->sin_port = htons(atoi(service));
/* limitation: the node must be in numbers-and-dots notation */
((struct sockaddr_in*)p->ai_addr)->sin_addr.s_addr = inet_addr(node);
*res = p;
return 0;
}
static void freeaddrinfo(struct addrinfo *res)
{
free(res->ai_addr);
free(res);
}
#endif /* !HAVE_GETADDRINFO */
#if !defined(HAVE_GAI_STRERROR) && !defined(gai_strerror)
static const char *gai_strerror(int errcode)
{
return strerror(errcode);
}
#endif /* !HAVE_GAI_STRERROR */
#ifdef __MINGW32__
static int wsstarted;
#endif
@ -170,7 +102,7 @@ int network_open(hamlib_port_t *rp, int default_port)
return -RIG_EINVAL;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET /* PF_UNSPEC */;
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (rp->pathname[0] == ':') {

Wyświetl plik

@ -1,11 +1,9 @@
/*
* rigctld.c - (C) Stephane Fillod 2000-2009
* rigctld.c - (C) Stephane Fillod 2000-2010
*
* This program test/control a radio using Hamlib.
* It takes commands from network connection.
*
* $Id: rigctld.c,v 1.11 2009-01-04 14:49:17 fillods Exp $
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -49,6 +47,9 @@
#elif HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_PTHREAD
#include <pthread.h>
@ -110,8 +111,8 @@ int vfo_mode = 0; /* vfo_mode=0 means target VFO is current VFO */
char send_cmd_term = '\r'; /* send_cmd termination char */
int portno = 4532;
uint32_t src_addr = INADDR_ANY;
const char *portno = "4532";
const char *src_addr = NULL; /* INADDR_ANY */
#define MAXCONFLEN 128
@ -132,10 +133,9 @@ int main (int argc, char *argv[])
char *civaddr = NULL; /* NULL means no need to set conf */
char conf_parms[MAXCONFLEN] = "";
struct addrinfo hints, *result;
int sock_listen;
struct sockaddr_in serv_addr;
int reuseaddr = 1;
int a0,a1,a2,a3;
while(1) {
int c;
@ -247,18 +247,14 @@ int main (int argc, char *argv[])
usage(); /* wrong arg count */
exit(1);
}
portno = atoi(optarg);
portno = optarg;
break;
case 'T':
if (!optarg) {
usage(); /* wrong arg count */
exit(1);
}
if (4 != sscanf(optarg, "%d.%d.%d.%d", &a0,&a1,&a2,&a3)) {
usage(); /* wrong arg count */
exit(1);
}
src_addr = (a0<<24)|(a1<<16)|(a2<<8)|a3;
src_addr = optarg;
break;
case 'o':
vfo_mode++;
@ -358,27 +354,37 @@ int main (int argc, char *argv[])
/*
* Prepare listening socket
*/
sock_listen = socket(AF_INET, SOCK_STREAM, 0);
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM;/* TCP socket */
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
retcode = getaddrinfo(src_addr, portno, &hints, &result);
if (retcode != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(retcode));
exit(2);
}
sock_listen = socket(result->ai_family, result->ai_socktype,
result->ai_protocol);
if (sock_listen < 0) {
perror("ERROR opening socket");
exit(2);
}
memset((char *)&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
serv_addr.sin_addr.s_addr = htonl(src_addr);
if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR,
(char *)&reuseaddr, sizeof(reuseaddr)) < 0) {
rig_debug(RIG_DEBUG_ERR, "setsockopt: %s\n", strerror(errno));
exit (1);
}
if (bind(sock_listen, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
if (bind(sock_listen, result->ai_addr, result->ai_addrlen) < 0) {
rig_debug(RIG_DEBUG_ERR, "binding: %s\n", strerror(errno));
exit (1);
}
freeaddrinfo(result); /* No longer needed */
if (listen(sock_listen, 4) < 0) {
rig_debug(RIG_DEBUG_ERR, "listening: %s\n", strerror(errno));
exit (1);
@ -505,7 +511,7 @@ void usage(void)
" -D, --dcd-type=TYPE set type of the DCD device to operate on\n"
" -s, --serial-speed=BAUD set serial speed of the serial port\n"
" -c, --civaddr=ID set CI-V address, decimal (for Icom rigs only)\n"
" -t, --port=NUM set TCP listening port, default %d\n"
" -t, --port=NUM set TCP listening port, default %s\n"
" -T, --listen-addr=IPADDR set listening IP address, default ANY\n"
" -C, --set-conf=PARM=VAL set config parameters\n"
" -L, --show-conf list all config parameters\n"

Wyświetl plik

@ -4,8 +4,6 @@
* This program test/control a rotator using Hamlib.
* It takes commands from network connection.
*
* $Id: rotctld.c,v 1.7 2009-01-04 14:49:17 fillods Exp $
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -49,6 +47,9 @@
#elif HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_PTHREAD
#include <pthread.h>
@ -99,8 +100,8 @@ int interactive = 1; /* no cmd because of daemon */
int prompt= 0 ; /* Daemon mode for rigparse return string */
int opt_end= 0 ; /* END marker for rotctld */
int portno = 4533;
uint32_t src_addr = INADDR_ANY;
const char *portno = "4533";
const char *src_addr = NULL; /* INADDR_ANY */
char send_cmd_term = '\r'; /* send_cmd termination char */
@ -121,10 +122,9 @@ int main (int argc, char *argv[])
int serial_rate = 0;
char conf_parms[MAXCONFLEN] = "";
struct addrinfo hints, *result;
int sock_listen;
struct sockaddr_in serv_addr;
int reuseaddr = 1;
int a0,a1,a2,a3;
while(1) {
int c;
@ -177,18 +177,14 @@ int main (int argc, char *argv[])
usage(); /* wrong arg count */
exit(1);
}
portno = atoi(optarg);
portno = optarg;
break;
case 'T':
if (!optarg) {
usage(); /* wrong arg count */
exit(1);
}
if (4 != sscanf(optarg, "%d.%d.%d.%d", &a0,&a1,&a2,&a3)) {
usage(); /* wrong arg count */
exit(1);
}
src_addr = (a0<<24)|(a1<<16)|(a2<<8)|a3;
src_addr = optarg;
break;
case 'v':
verbose++;
@ -273,27 +269,37 @@ int main (int argc, char *argv[])
/*
* Prepare listening socket
*/
sock_listen = socket(AF_INET, SOCK_STREAM, 0);
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM;/* TCP socket */
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
retcode = getaddrinfo(src_addr, portno, &hints, &result);
if (retcode != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(retcode));
exit(2);
}
sock_listen = socket(result->ai_family, result->ai_socktype,
result->ai_protocol);
if (sock_listen < 0) {
perror("ERROR opening socket");
exit(1);
}
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
serv_addr.sin_addr.s_addr = htonl(src_addr);
if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR,
(char *)&reuseaddr,sizeof(reuseaddr)) < 0) {
rig_debug(RIG_DEBUG_ERR, "setsockopt: %s\n", strerror(errno));
exit (1);
}
if (bind(sock_listen, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
if (bind(sock_listen, result->ai_addr, result->ai_addrlen) < 0) {
rig_debug(RIG_DEBUG_ERR, "binding: %s\n", strerror(errno));
exit (1);
}
freeaddrinfo(result); /* No longer needed */
if (listen(sock_listen,4) < 0) {
rig_debug(RIG_DEBUG_ERR, "listening: %s\n", strerror(errno));
exit (1);
@ -414,7 +420,7 @@ void usage()
" -m, --model=ID select rotator model number. See model list\n"
" -r, --rot-file=DEVICE set device of the rotator to operate on\n"
" -s, --serial-speed=BAUD set serial speed of the serial port\n"
" -t, --port=NUM set TCP listening port, default %d\n"
" -t, --port=NUM set TCP listening port, default %s\n"
" -T, --listen-addr=IPADDR set listening IP address, default ANY\n"
" -C, --set-conf=PARM=VAL set config parameters\n"
" -L, --show-conf list all config parameters\n"