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/29
pull/345/head
Michael Black W9MDB 2020-06-21 17:47:04 -05:00
rodzic 379caace7c
commit e092a4a0a4
5 zmienionych plików z 153 dodań i 45 usunięć

Wyświetl plik

@ -1376,6 +1376,85 @@ vfo_t HAMLIB_API vfo_fixup(RIG *rig, vfo_t 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

Wyświetl plik

@ -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(int) parse_hoststr(char *host, char hoststr[256], char port[6]);
#ifdef PRId64
/** \brief printf(3) format to be used for long long (64bits) type */
# define PRIll PRId64

Wyświetl plik

@ -114,7 +114,6 @@ static void handle_error(enum rig_debug_level_e lvl, const char *msg)
#endif
}
/**
* \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 status;
struct addrinfo hints, *res, *saved_res;
char *hoststr = NULL, *portstr = NULL, *bracketstr1, *bracketstr2;
char hostname[FILPATHLEN];
char defaultportstr[8];
struct in6_addr serveraddr;
char hoststr[256], portstr[6];
rig_debug(RIG_DEBUG_VERBOSE, "%s called\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));
hints.ai_family = PF_UNSPEC;
hints.ai_flags = AI_NUMERICSERV;
hints.ai_family = AF_UNSPEC;
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;
}
/* default of all local interfaces */
hoststr = NULL;
if (rp->pathname[0] == ':')
if (rp->pathname[0] == ':' && rp->pathname[1] != ':')
{
portstr = rp->pathname + 1;
snprintf(portstr, sizeof(portstr) - 1, "%s", rp->pathname + 1);
}
else
{
if (strlen(rp->pathname))
{
snprintf(hostname, sizeof(hostname), "%s", rp->pathname);
hoststr = hostname;
/* look for IPv6 numeric form [<addr>] */
bracketstr1 = strchr(hoststr, '[');
bracketstr2 = strrchr(hoststr, ']');
status = parse_hoststr(rp->pathname, hoststr, portstr);
if (bracketstr1 && bracketstr2 && bracketstr2 > bracketstr1)
{
hoststr = bracketstr1 + 1;
*bracketstr2 = '\0';
portstr = bracketstr2 + 1; /* possible port after ]: */
}
else
{
bracketstr2 = NULL;
portstr = hoststr; /* possible port after : */
}
if (status != RIG_OK) { return status; }
/* search last ':' */
portstr = strrchr(portstr, ':');
rig_debug(RIG_DEBUG_ERR, "%s: hoststr=%s, portstr=%s\n", __func__, hoststr,
portstr);
if (portstr)
{
*portstr++ = '\0';
}
}
if (!portstr)
if (strlen(portstr) == 0)
{
sprintf(defaultportstr, "%d", default_port);
portstr = defaultportstr;
sprintf(portstr, "%d", default_port);
}
}
status = inet_pton(AF_INET, hoststr, &serveraddr);
if (status == 1) /* valid IPv4 address */
{
hints.ai_family = AF_INET;
hints.ai_flags |= AI_NUMERICHOST;
}
else
{
status = inet_pton(AF_INET6, hoststr, &serveraddr);
if (status == 1) /* valide IPv6 address */
{
hints.ai_family = AF_INET6;
hints.ai_flags |= AI_NUMERICHOST;
}
}
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)
{
rig_debug(RIG_DEBUG_ERR,

Wyświetl plik

@ -556,9 +556,9 @@ int HAMLIB_API rig_open(RIG *rig)
struct rig_state *rs;
int status = RIG_OK;
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;
char *token, *strtokp;
char hoststr[256], portstr[6];
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
@ -570,6 +570,14 @@ int HAMLIB_API rig_open(RIG *rig)
caps = rig->caps;
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
//
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)
{
rig_debug(RIG_DEBUG_TRACE, "%s: using network address %s\n", __func__,
@ -3054,9 +3064,11 @@ 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))
{
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)
{
@ -3084,11 +3096,14 @@ int HAMLIB_API rig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
/* try and revert even if we had an error above */
if (caps->set_vfo)
{
// 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) {
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));
// 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)
{
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));
rc2 = caps->set_vfo(rig, save_vfo);
}
else
@ -3631,6 +3646,7 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
{
return retcode;
}
#endif
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 */
retcode = rc2;
}
#endif
if (retcode == RIG_OK) // only update cache on success

Wyświetl plik

@ -686,11 +686,20 @@ int main(int argc, char *argv[])
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_flags = AI_CANONNAME;
hints.ai_protocol = 0; /* Any protocol */
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));
exit(2);