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; 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

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(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

Wyświetl plik

@ -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,

Wyświetl plik

@ -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

Wyświetl plik

@ -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);