kopia lustrzana https://github.com/Hamlib/Hamlib
rigctld -T ::1 now works with rigctl -r ::1
More IPV6 testing needed on Windows and MacOS Still not binding to link local addresses to be addressed next https://github.com/Hamlib/Hamlib/issues/29pull/345/head
rodzic
379caace7c
commit
e092a4a0a4
79
src/misc.c
79
src/misc.c
|
@ -1376,6 +1376,85 @@ vfo_t HAMLIB_API vfo_fixup(RIG *rig, vfo_t vfo)
|
||||||
return vfo;
|
return vfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int HAMLIB_API parse_hoststr(char *hoststr, char host[256], char port[6])
|
||||||
|
{
|
||||||
|
unsigned int net1, net2, net3, net4, net5;
|
||||||
|
char dummy[2], link[32], *p;
|
||||||
|
host[0] = 0;
|
||||||
|
port[0] = 0;
|
||||||
|
dummy[0] = 0;
|
||||||
|
|
||||||
|
// bracketed IPV6 with optional port
|
||||||
|
int n = sscanf(hoststr, "[%255[^]]]:%s", host, port);
|
||||||
|
|
||||||
|
if (n >= 1)
|
||||||
|
{
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// non-bracketed IPV6 with optional link addr
|
||||||
|
n = sscanf(hoststr, "%x::%x:%x:%x:%x:%%%31[^:]:%s", &net1, &net2, &net3,
|
||||||
|
&net4, &net5, link, port);
|
||||||
|
|
||||||
|
if (strchr(hoststr, '%') && (n == 5 || n == 6))
|
||||||
|
{
|
||||||
|
strcpy(host, hoststr);
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
else if (n == 7)
|
||||||
|
{
|
||||||
|
strcpy(host, hoststr);
|
||||||
|
p = strrchr(host, ':'); // remove port from host
|
||||||
|
*p = 0;
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// non-bracketed IPV6 short form with optional port
|
||||||
|
n = sscanf(hoststr, "%x::%x:%x:%x:%x:%5[0-9]%1s", &net1, &net2, &net3, &net4,
|
||||||
|
&net5, port, dummy);
|
||||||
|
|
||||||
|
if (n == 5)
|
||||||
|
{
|
||||||
|
strcpy(host, hoststr);
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
else if (n == 6)
|
||||||
|
{
|
||||||
|
strcpy(host, hoststr);
|
||||||
|
p = strrchr(host, ':');
|
||||||
|
*p = 0;
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
else if (n == 7)
|
||||||
|
{
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bracketed localhost
|
||||||
|
if (strstr(hoststr, "::1"))
|
||||||
|
{
|
||||||
|
n = sscanf(hoststr, "::1%s", dummy);
|
||||||
|
strcpy(host, hoststr);
|
||||||
|
|
||||||
|
if (n == 1)
|
||||||
|
{
|
||||||
|
p = strrchr(host, ':');
|
||||||
|
*p = 0;
|
||||||
|
strcpy(port, p + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we're here then we must have a hostname
|
||||||
|
n = sscanf(hoststr, "%255[^:]:%5[0-9]%1s", host, port, dummy);
|
||||||
|
|
||||||
|
if (n >= 1 && strlen(dummy) == 0) { return RIG_OK; }
|
||||||
|
|
||||||
|
printf("Unhandled host=%s\n", hoststr);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
//! @endcond
|
//! @endcond
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,8 @@ extern HAMLIB_EXPORT(double) elapsed_ms(struct timespec *start, int start_flag);
|
||||||
|
|
||||||
extern HAMLIB_EXPORT(vfo_t) vfo_fixup(RIG *rig, vfo_t vfo);
|
extern HAMLIB_EXPORT(vfo_t) vfo_fixup(RIG *rig, vfo_t vfo);
|
||||||
|
|
||||||
|
extern HAMLIB_EXPORT(int) parse_hoststr(char *host, char hoststr[256], char port[6]);
|
||||||
|
|
||||||
#ifdef PRId64
|
#ifdef PRId64
|
||||||
/** \brief printf(3) format to be used for long long (64bits) type */
|
/** \brief printf(3) format to be used for long long (64bits) type */
|
||||||
# define PRIll PRId64
|
# define PRIll PRId64
|
||||||
|
|
|
@ -114,7 +114,6 @@ static void handle_error(enum rig_debug_level_e lvl, const char *msg)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Open network port using rig.state data
|
* \brief Open network port using rig.state data
|
||||||
*
|
*
|
||||||
|
@ -130,9 +129,8 @@ int network_open(hamlib_port_t *rp, int default_port)
|
||||||
int fd; /* File descriptor for the port */
|
int fd; /* File descriptor for the port */
|
||||||
int status;
|
int status;
|
||||||
struct addrinfo hints, *res, *saved_res;
|
struct addrinfo hints, *res, *saved_res;
|
||||||
char *hoststr = NULL, *portstr = NULL, *bracketstr1, *bracketstr2;
|
struct in6_addr serveraddr;
|
||||||
char hostname[FILPATHLEN];
|
char hoststr[256], portstr[6];
|
||||||
char defaultportstr[8];
|
|
||||||
|
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s version 1.0\n", __func__);
|
rig_debug(RIG_DEBUG_VERBOSE, "%s version 1.0\n", __func__);
|
||||||
|
@ -154,7 +152,8 @@ int network_open(hamlib_port_t *rp, int default_port)
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = PF_UNSPEC;
|
hints.ai_flags = AI_NUMERICSERV;
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
|
||||||
if (rp->type.rig == RIG_PORT_UDP_NETWORK)
|
if (rp->type.rig == RIG_PORT_UDP_NETWORK)
|
||||||
{
|
{
|
||||||
|
@ -165,53 +164,55 @@ int network_open(hamlib_port_t *rp, int default_port)
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* default of all local interfaces */
|
if (rp->pathname[0] == ':' && rp->pathname[1] != ':')
|
||||||
hoststr = NULL;
|
|
||||||
|
|
||||||
if (rp->pathname[0] == ':')
|
|
||||||
{
|
{
|
||||||
portstr = rp->pathname + 1;
|
snprintf(portstr, sizeof(portstr) - 1, "%s", rp->pathname + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (strlen(rp->pathname))
|
if (strlen(rp->pathname))
|
||||||
{
|
{
|
||||||
snprintf(hostname, sizeof(hostname), "%s", rp->pathname);
|
status = parse_hoststr(rp->pathname, hoststr, portstr);
|
||||||
hoststr = hostname;
|
|
||||||
/* look for IPv6 numeric form [<addr>] */
|
|
||||||
bracketstr1 = strchr(hoststr, '[');
|
|
||||||
bracketstr2 = strrchr(hoststr, ']');
|
|
||||||
|
|
||||||
if (bracketstr1 && bracketstr2 && bracketstr2 > bracketstr1)
|
if (status != RIG_OK) { return status; }
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: hoststr=%s, portstr=%s\n", __func__, hoststr,
|
||||||
|
portstr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(portstr) == 0)
|
||||||
{
|
{
|
||||||
hoststr = bracketstr1 + 1;
|
sprintf(portstr, "%d", default_port);
|
||||||
*bracketstr2 = '\0';
|
}
|
||||||
portstr = bracketstr2 + 1; /* possible port after ]: */
|
}
|
||||||
|
|
||||||
|
status = inet_pton(AF_INET, hoststr, &serveraddr);
|
||||||
|
|
||||||
|
if (status == 1) /* valid IPv4 address */
|
||||||
|
{
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
hints.ai_flags |= AI_NUMERICHOST;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bracketstr2 = NULL;
|
status = inet_pton(AF_INET6, hoststr, &serveraddr);
|
||||||
portstr = hoststr; /* possible port after : */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* search last ':' */
|
if (status == 1) /* valide IPv6 address */
|
||||||
portstr = strrchr(portstr, ':');
|
|
||||||
|
|
||||||
if (portstr)
|
|
||||||
{
|
{
|
||||||
*portstr++ = '\0';
|
hints.ai_family = AF_INET6;
|
||||||
}
|
hints.ai_flags |= AI_NUMERICHOST;
|
||||||
}
|
|
||||||
|
|
||||||
if (!portstr)
|
|
||||||
{
|
|
||||||
sprintf(defaultportstr, "%d", default_port);
|
|
||||||
portstr = defaultportstr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = getaddrinfo(hoststr, portstr, &hints, &res);
|
status = getaddrinfo(hoststr, portstr, &hints, &res);
|
||||||
|
|
||||||
|
if (status == 0 && res->ai_family == AF_INET6)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: Using IPV6\n", __func__);
|
||||||
|
//inet_pton(AF_INET6, hoststr, &h_addr.sin6_addr);
|
||||||
|
}
|
||||||
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
rig_debug(RIG_DEBUG_ERR,
|
rig_debug(RIG_DEBUG_ERR,
|
||||||
|
|
29
src/rig.c
29
src/rig.c
|
@ -556,9 +556,9 @@ int HAMLIB_API rig_open(RIG *rig)
|
||||||
struct rig_state *rs;
|
struct rig_state *rs;
|
||||||
int status = RIG_OK;
|
int status = RIG_OK;
|
||||||
value_t parm_value;
|
value_t parm_value;
|
||||||
unsigned int net1, net2, net3, net4, net5, net6, net7, net8, port;
|
//unsigned int net1, net2, net3, net4, net5, net6, net7, net8, port;
|
||||||
int is_network = 0;
|
int is_network = 0;
|
||||||
char *token, *strtokp;
|
char hoststr[256], portstr[6];
|
||||||
|
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||||
|
|
||||||
|
@ -570,6 +570,14 @@ int HAMLIB_API rig_open(RIG *rig)
|
||||||
caps = rig->caps;
|
caps = rig->caps;
|
||||||
rs = &rig->state;
|
rs = &rig->state;
|
||||||
|
|
||||||
|
if (strlen(rs->rigport.pathname) > 0)
|
||||||
|
{
|
||||||
|
status = parse_hoststr(rs->rigport.pathname, hoststr, portstr);
|
||||||
|
|
||||||
|
if (status == RIG_OK) { is_network = 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
// determine if we have a network address
|
// determine if we have a network address
|
||||||
//
|
//
|
||||||
is_network |= sscanf(rs->rigport.pathname, "%u.%u.%u.%u:%u", &net1, &net2,
|
is_network |= sscanf(rs->rigport.pathname, "%u.%u.%u.%u:%u", &net1, &net2,
|
||||||
|
@ -594,6 +602,8 @@ int HAMLIB_API rig_open(RIG *rig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
if (is_network)
|
if (is_network)
|
||||||
{
|
{
|
||||||
rig_debug(RIG_DEBUG_TRACE, "%s: using network address %s\n", __func__,
|
rig_debug(RIG_DEBUG_TRACE, "%s: using network address %s\n", __func__,
|
||||||
|
@ -3054,8 +3064,10 @@ int HAMLIB_API rig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
|
||||||
if (!rig_has_vfo_op(rig, RIG_OP_XCHG))
|
if (!rig_has_vfo_op(rig, RIG_OP_XCHG))
|
||||||
{
|
{
|
||||||
retcode = caps->set_vfo(rig, tx_vfo);
|
retcode = caps->set_vfo(rig, tx_vfo);
|
||||||
if (retcode != RIG_OK) return retcode;
|
|
||||||
|
if (retcode != RIG_OK) { return retcode; }
|
||||||
}
|
}
|
||||||
|
|
||||||
retcode = RIG_OK;
|
retcode = RIG_OK;
|
||||||
}
|
}
|
||||||
else if (rig_has_vfo_op(rig, RIG_OP_TOGGLE) && caps->vfo_op)
|
else if (rig_has_vfo_op(rig, RIG_OP_TOGGLE) && caps->vfo_op)
|
||||||
|
@ -3085,10 +3097,13 @@ int HAMLIB_API rig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
|
||||||
if (caps->set_vfo)
|
if (caps->set_vfo)
|
||||||
{
|
{
|
||||||
// If we started with RIG_VFO_CURR we need to choose VFO_A/MAIN as appropriate to return to
|
// If we started with RIG_VFO_CURR we need to choose VFO_A/MAIN as appropriate to return to
|
||||||
if (save_vfo == RIG_VFO_CURR) {
|
if (save_vfo == RIG_VFO_CURR)
|
||||||
save_vfo = VFO_HAS_A_B_ONLY?RIG_VFO_A:RIG_VFO_MAIN;
|
{
|
||||||
|
save_vfo = VFO_HAS_A_B_ONLY ? RIG_VFO_A : RIG_VFO_MAIN;
|
||||||
}
|
}
|
||||||
rig_debug(RIG_DEBUG_TRACE,"%s: retoring vfo=%s\n", __func__, rig_strvfo(save_vfo));
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: retoring vfo=%s\n", __func__,
|
||||||
|
rig_strvfo(save_vfo));
|
||||||
rc2 = caps->set_vfo(rig, save_vfo);
|
rc2 = caps->set_vfo(rig, save_vfo);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3631,6 +3646,7 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
|
||||||
{
|
{
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
retcode = caps->get_split_vfo(rig, vfo, split, tx_vfo);
|
retcode = caps->get_split_vfo(rig, vfo, split, tx_vfo);
|
||||||
|
@ -3643,6 +3659,7 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
|
||||||
/* return the first error code */
|
/* return the first error code */
|
||||||
retcode = rc2;
|
retcode = rc2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (retcode == RIG_OK) // only update cache on success
|
if (retcode == RIG_OK) // only update cache on success
|
||||||
|
|
|
@ -686,11 +686,20 @@ int main(int argc, char *argv[])
|
||||||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
||||||
hints.ai_socktype = SOCK_STREAM;/* TCP socket */
|
hints.ai_socktype = SOCK_STREAM;/* TCP socket */
|
||||||
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
|
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
|
||||||
|
hints.ai_flags = AI_CANONNAME;
|
||||||
hints.ai_protocol = 0; /* Any protocol */
|
hints.ai_protocol = 0; /* Any protocol */
|
||||||
|
|
||||||
retcode = getaddrinfo(src_addr, portno, &hints, &result);
|
retcode = getaddrinfo(src_addr, portno, &hints, &result);
|
||||||
|
|
||||||
if (retcode != 0)
|
if (retcode == 0 && result->ai_family == AF_INET6)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: Using IPV6\n", __func__);
|
||||||
|
}
|
||||||
|
else if (retcode == 0)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: Using IPV4\n", __func__);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(retcode));
|
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(retcode));
|
||||||
exit(2);
|
exit(2);
|
||||||
|
|
Ładowanie…
Reference in New Issue