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;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
35
src/rig.c
35
src/rig.c
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Ładowanie…
Reference in New Issue