Resolve ip address in all of tha nat modes (mrash/fwknop#43).
This commit is contained in:
parent
8f3e6a4ed1
commit
fd767a1f47
155
client/fwknop.c
155
client/fwknop.c
@ -59,14 +59,117 @@ static void clean_exit(fko_ctx_t ctx, fko_cli_options_t *opts,
|
||||
unsigned int exit_status);
|
||||
static void *get_in_addr(struct sockaddr *sa);
|
||||
static int resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *ip_str, size_t ip_bufsize);
|
||||
static int is_hostname_str_with_port(const char *str, char *hostname, size_t hostname_bufsize, int *port);
|
||||
|
||||
#define MAX_CMDLINE_ARGS 50 /* should be way more than enough */
|
||||
#define MAX_CMDLINE_ARGS 50 /*!< should be way more than enough */
|
||||
#define IPV4_STR_TEMPLATE "%u.%u.%u.%u" /*!< Template for a string as an ipv4 address with sscanf */
|
||||
#define NAT_ACCESS_STR_TEMPLATE "%s,%d" /*!< Template for a nat access string ip,port with sscanf*/
|
||||
#define HOSTNAME_BUFSIZE 64 /*!< Maximum size of a hostname string */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check whether a string is an ipv4 address or not
|
||||
*
|
||||
* @param str String to check for an ipv4 address.
|
||||
*
|
||||
* @return 1 if the string is an ipv4 address, 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
is_ipv4_str(char *str)
|
||||
{
|
||||
int o1, o2, o3, o4;
|
||||
int valid_ipv4;
|
||||
|
||||
/* Check format and values.
|
||||
*/
|
||||
if((sscanf(str, IPV4_STR_TEMPLATE, &o1, &o2, &o3, &o4)) == 4
|
||||
&& o1 >= 0 && o1 <= 255
|
||||
&& o2 >= 0 && o2 <= 255
|
||||
&& o3 >= 0 && o3 <= 255
|
||||
&& o4 >= 0 && o4 <= 255)
|
||||
{
|
||||
valid_ipv4 = 1;
|
||||
}
|
||||
else
|
||||
valid_ipv4 = 0;
|
||||
|
||||
return valid_ipv4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether a string is an ipv6 address or not
|
||||
*
|
||||
* @param str String to check for an ipv6 address.
|
||||
*
|
||||
* @return 1 if the string is an ipv6 address, 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
is_ipv6_str(char *str)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check a string to find out if it is built as 'hostname,port'
|
||||
*
|
||||
* This function check if we can extract an hostname and a port from the string.
|
||||
* If yes, we return 1, and both the hostname buffer and the port number are set
|
||||
* accordingly.
|
||||
*
|
||||
* We could have used sscanf() here with a template "%[^,],%u", but this way we
|
||||
* do not limit the size of the value copy in the hostname destination buffer.
|
||||
* Limiting the string in the sscanf() can be done but would prevent any easy change
|
||||
* for the hostname buffer size.
|
||||
*
|
||||
* @param str String to parse.
|
||||
* @param hostname Buffer where to store the hostname value read from @str.
|
||||
* @param hostname_bufsize Hostname buffer size.
|
||||
* @param port Value of the port read from @str.
|
||||
*
|
||||
* @return 1 if the string is built as 'hostname,port', 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
is_hostname_str_with_port(const char *str, char *hostname, size_t hostname_bufsize, int *port)
|
||||
{
|
||||
int valid = 0; /* Result of the function */
|
||||
char buf[MAX_LINE_LEN]; /* Copy of the buffer eg. "hostname,port" */
|
||||
char *h; /* Pointer on the hostname string */
|
||||
char *p; /* Ponter on the port string */
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memset(hostname, 0, hostname_bufsize);
|
||||
*port = 0;
|
||||
|
||||
/* Replace the comma in the string with a NULL char to split the
|
||||
* buffer in two strings (hostname and port) */
|
||||
strlcpy(buf, str, sizeof(buf));
|
||||
p = strchr(buf, ',');
|
||||
|
||||
if(p != NULL)
|
||||
{
|
||||
*p++ = 0;
|
||||
h = buf;
|
||||
|
||||
*port = atoi(p);
|
||||
|
||||
/* If the string does not match an ipv4 or ipv6 address we assume this
|
||||
* is an hostname. We make sure the port is in the good range too */
|
||||
if ( (is_ipv4_str(buf) == 0)
|
||||
&& (is_ipv6_str(buf) == 0)
|
||||
&& ((*port > 0) && (*port < 65536)) )
|
||||
{
|
||||
strlcpy(hostname, h, hostname_bufsize);
|
||||
valid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Grab the sin address from the sockaddr structure.
|
||||
*
|
||||
* This functions returns the sin address as a sockaddr_in or sockaddr_in6
|
||||
* This function returns the sin address as a sockaddr_in or sockaddr_in6
|
||||
* structure according to the family set (ipv4 or ipv6) in the sockaddr
|
||||
* structure.
|
||||
*
|
||||
@ -74,7 +177,8 @@ static int resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *i
|
||||
*
|
||||
* @return the sin addr if the sa family is AF_INET or the sin6_addr otherwise.
|
||||
*/
|
||||
static void *get_in_addr(struct sockaddr *sa)
|
||||
static void *
|
||||
get_in_addr(struct sockaddr *sa)
|
||||
{
|
||||
if (sa->sa_family == AF_INET)
|
||||
{
|
||||
@ -97,7 +201,8 @@ static void *get_in_addr(struct sockaddr *sa)
|
||||
*
|
||||
* @return 0 if successful, 1 if an error occured.
|
||||
*/
|
||||
static int resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *ip_str, size_t ip_bufsize)
|
||||
static int
|
||||
resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *ip_str, size_t ip_bufsize)
|
||||
{
|
||||
int error; /* Function error return code */
|
||||
struct addrinfo *result; /* Result of getaddrinfo() */
|
||||
@ -747,7 +852,9 @@ set_nat_access(fko_ctx_t ctx, fko_cli_options_t *options, const char * const acc
|
||||
char nat_access_buf[MAX_LINE_LEN] = {0};
|
||||
char tmp_access_port[MAX_PORT_STR_LEN+1], *ndx = NULL;
|
||||
int access_port = 0, i = 0, is_err = 0;
|
||||
char dst_ip_str[INET_ADDRSTRLEN];
|
||||
char dst_ip_str[INET_ADDRSTRLEN] = {0};
|
||||
char hostname[HOSTNAME_BUFSIZE] = {0};
|
||||
int port = 0;
|
||||
struct addrinfo hints;
|
||||
|
||||
memset(nat_access_buf, 0x0, MAX_LINE_LEN);
|
||||
@ -781,22 +888,7 @@ set_nat_access(fko_ctx_t ctx, fko_cli_options_t *options, const char * const acc
|
||||
|
||||
if (options->nat_local && options->nat_access_str[0] == 0x0)
|
||||
{
|
||||
/* Speed up the name resolution by forcing ipv4 (AF_INET).
|
||||
* A NULL pointer could be used instead if there is no constraint.
|
||||
* Maybe when ipv6 support will be enable the structure could initialize the
|
||||
* family to either AF_INET or AF_INET6 */
|
||||
hints.ai_family = AF_INET;
|
||||
|
||||
if (resolve_dest_adr(options->spa_server_str, &hints, dst_ip_str, sizeof(dst_ip_str)) != 0)
|
||||
{
|
||||
fprintf(stderr, "[*] Unable to resolve %s as an ip address\n",
|
||||
options->spa_server_str);
|
||||
clean_exit(ctx, options, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
strlcpy(options->spa_server_str, dst_ip_str, sizeof(options->spa_server_str));
|
||||
|
||||
snprintf(nat_access_buf, MAX_LINE_LEN, "%s,%d",
|
||||
snprintf(nat_access_buf, MAX_LINE_LEN, NAT_ACCESS_STR_TEMPLATE,
|
||||
options->spa_server_str, access_port);
|
||||
}
|
||||
|
||||
@ -809,11 +901,30 @@ set_nat_access(fko_ctx_t ctx, fko_cli_options_t *options, const char * const acc
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(nat_access_buf, MAX_LINE_LEN, "%s,%d",
|
||||
snprintf(nat_access_buf, MAX_LINE_LEN, NAT_ACCESS_STR_TEMPLATE,
|
||||
options->nat_access_str, access_port);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_hostname_str_with_port(nat_access_buf, hostname, sizeof(hostname), &port))
|
||||
{
|
||||
/* Speed up the name resolution by forcing ipv4 (AF_INET).
|
||||
* A NULL pointer could be used instead if there is no constraint.
|
||||
* Maybe when ipv6 support will be enable the structure could initialize the
|
||||
* family to either AF_INET or AF_INET6 */
|
||||
hints.ai_family = AF_INET;
|
||||
|
||||
if (resolve_dest_adr(hostname, &hints, dst_ip_str, sizeof(dst_ip_str)) != 0)
|
||||
{
|
||||
fprintf(stderr, "[*] Unable to resolve %s as an ip address\n",
|
||||
hostname);
|
||||
clean_exit(ctx, options, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
snprintf(nat_access_buf, MAX_LINE_LEN, NAT_ACCESS_STR_TEMPLATE,
|
||||
dst_ip_str, port);
|
||||
}
|
||||
|
||||
if(options->nat_rand_port)
|
||||
{
|
||||
/* Must print to stdout what the random port is since
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
127.0.0.1: fwknoptest
|
||||
localhost: fwknoptest
|
||||
some.host.through.proxy.com: fwknoptest
|
||||
74.220.215.85: fwknoptest
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user