/* Set NAT access string */ static int set_nat_access(fko_ctx_t ctx, fko_cli_options_t *options, const char * const access_buf) { char nat_access_buf[MAX_LINE_LEN] = {0}; char tmp_access_port[MAX_PORT_STR_LEN+1] = {0}, *ndx = NULL; int access_port = 0, i = 0, is_err = 0; char dst_ip_str[INET_ADDRSTRLEN] = {0}; char hostname[HOSTNAME_BUFSIZE] = {0}; int port = 0; struct addrinfo hints; memset(&hints, 0 , sizeof(hints)); ndx = strchr(options->access_str, '/'); if(ndx == NULL) { log_msg(LOG_VERBOSITY_ERROR, "[*] Expecting <proto>/<port> for -A arg."); return FKO_ERROR_INVALID_DATA; } ndx++; while(*ndx != '\0' && isdigit(*ndx) && i < MAX_PORT_STR_LEN) { tmp_access_port[i] = *ndx; ndx++; i++; } tmp_access_port[i] = '\0'; access_port = strtol_wrapper(tmp_access_port, 1, MAX_PORT, NO_EXIT_UPON_ERR, &is_err); if(is_err != FKO_SUCCESS) { log_msg(LOG_VERBOSITY_ERROR, "[*] Invalid port value '%d' for -A arg.", access_port); return FKO_ERROR_INVALID_DATA; } if (options->nat_local && options->nat_access_str[0] == 0x0) { snprintf(nat_access_buf, MAX_LINE_LEN, NAT_ACCESS_STR_TEMPLATE, options->spa_server_str, access_port); } if (nat_access_buf[0] == 0x0 && options->nat_access_str[0] != 0x0) { if (ipv4_str_has_port(options->nat_access_str)) { snprintf(nat_access_buf, MAX_LINE_LEN, "%s", options->nat_access_str); } else { snprintf(nat_access_buf, MAX_LINE_LEN, NAT_ACCESS_STR_TEMPLATE, options->nat_access_str, access_port); } } /* Check if there is a hostname to resolve as an ip address in the NAT access buffer */ 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_dst_addr(hostname, &hints, dst_ip_str, sizeof(dst_ip_str), options) != 0) { log_msg(LOG_VERBOSITY_ERROR, "[*] Unable to resolve %s as an ip address", hostname); return FKO_ERROR_INVALID_DATA; } snprintf(nat_access_buf, MAX_LINE_LEN, NAT_ACCESS_STR_TEMPLATE, dst_ip_str, port); } /* Nothing to resolve */ else; if(options->nat_rand_port) { /* Must print to stdout what the random port is since * if not then the user will not which port will be * opened/NAT'd on the fwknopd side */ log_msg(LOG_VERBOSITY_NORMAL, "[+] Randomly assigned port '%d' on: '%s' will grant access to: '%s'", options->nat_port, access_buf, nat_access_buf); } return fko_set_spa_nat_access(ctx, nat_access_buf); }
/* Set NAT access string */ static int set_nat_access(fko_ctx_t ctx, fko_cli_options_t *options, const char * const access_buf) { char nat_access_buf[MAX_LINE_LEN] = {0}; char tmp_access_port[MAX_PORT_STR_LEN+1] = {0}, *ndx = NULL; int access_port = 0, i = 0, is_err = 0; char hostname[HOSTNAME_BUFSIZE] = {0}; int port = 0; struct addrinfo hints; memset(&hints, 0 , sizeof(hints)); ndx = strchr(options->access_str, '/'); if(ndx == NULL) { log_msg(LOG_VERBOSITY_ERROR, "[*] Expecting <proto>/<port> for -A arg."); return FKO_ERROR_INVALID_DATA; } ndx++; while(*ndx != '\0' && isdigit(*ndx) && i < MAX_PORT_STR_LEN) { tmp_access_port[i] = *ndx; ndx++; i++; } tmp_access_port[i] = '\0'; access_port = strtol_wrapper(tmp_access_port, 1, MAX_PORT, NO_EXIT_UPON_ERR, &is_err); if(is_err != FKO_SUCCESS) { log_msg(LOG_VERBOSITY_ERROR, "[*] Invalid port value '%d' for -A arg.", access_port); return FKO_ERROR_INVALID_DATA; } if (options->nat_local && options->nat_access_str[0] == 0x0) { snprintf(nat_access_buf, MAX_LINE_LEN, NAT_ACCESS_STR_TEMPLATE, options->spa_server_str, access_port); } if (nat_access_buf[0] == 0x0 && options->nat_access_str[0] != 0x0) { if (ipv4_str_has_port(options->nat_access_str)) { snprintf(nat_access_buf, MAX_LINE_LEN, "%s", options->nat_access_str); } else { snprintf(nat_access_buf, MAX_LINE_LEN, NAT_ACCESS_STR_TEMPLATE, options->nat_access_str, access_port); } } /* Check if there is a hostname to resolve as an ip address in the NAT access buffer */ if (is_hostname_str_with_port(nat_access_buf, hostname, sizeof(hostname), &port)) { /* We now send the hostname, and resolve it server side */ snprintf(nat_access_buf, MAX_LINE_LEN, "%s", options->nat_access_str); } /* assume just hostname */ else { snprintf(nat_access_buf, MAX_LINE_LEN, NAT_ACCESS_STR_TEMPLATE, options->nat_access_str, access_port); } if(options->nat_rand_port) { /* Must print to stdout what the random port is since * if not then the user will not which port will be * opened/NAT'd on the fwknopd side */ log_msg(LOG_VERBOSITY_NORMAL, "[+] Randomly assigned port '%d' on: '%s' will grant access to: '%s'", options->nat_port, access_buf, nat_access_buf); } return fko_set_spa_nat_access(ctx, nat_access_buf); }