diff --git a/src/common/capwap_network.h b/src/common/capwap_network.h index 3928e82..054a5f8 100644 --- a/src/common/capwap_network.h +++ b/src/common/capwap_network.h @@ -11,6 +11,7 @@ /* */ #define CAPWAP_MACADDRESS_EUI48_BUFFER 18 #define CAPWAP_MACADDRESS_EUI64_BUFFER 24 +#define CAPWAP_MAX_FQDN_SIZE 256 /* */ union sockaddr_capwap { @@ -20,6 +21,12 @@ union sockaddr_capwap { struct sockaddr_storage ss; }; +struct addr_capwap { + char fqdn[CAPWAP_MAX_FQDN_SIZE]; + union sockaddr_capwap sockaddr; + char resolved; +}; + /* Helper */ #define CAPWAP_GET_NETWORK_PORT(addr) ntohs((((addr)->ss.ss_family == AF_INET) ? (addr)->sin.sin_port : (((addr)->ss.ss_family == AF_INET6) ? (addr)->sin6.sin6_port : 0))) #define CAPWAP_SET_NETWORK_PORT(addr, port) if ((addr)->ss.ss_family == AF_INET) { \ diff --git a/src/wtp/wtp.c b/src/wtp/wtp.c index 6893b1f..063b2dc 100644 --- a/src/wtp/wtp.c +++ b/src/wtp/wtp.c @@ -75,8 +75,8 @@ static int wtp_init(void) { /* AC information */ g_wtp.discoverytype.type = CAPWAP_DISCOVERYTYPE_TYPE_UNKNOWN; g_wtp.acdiscoveryrequest = 1; - g_wtp.acdiscoveryarray = capwap_array_create(sizeof(union sockaddr_capwap), 0, 0); - g_wtp.acpreferedarray = capwap_array_create(sizeof(union sockaddr_capwap), 0, 0); + g_wtp.acdiscoveryarray = capwap_array_create(sizeof(struct addr_capwap), 0, 0); + g_wtp.acpreferedarray = capwap_array_create(sizeof(struct addr_capwap), 0, 0); g_wtp.acdiscoveryresponse = capwap_array_create(sizeof(struct wtp_discovery_response), 0, 1); /* Radios */ @@ -136,14 +136,15 @@ static void wtp_destroy(void) { /* */ static void wtp_add_default_acaddress() { - union sockaddr_capwap address; + struct addr_capwap address; /* Broadcast IPv4 */ - memset(&address, 0, sizeof(union sockaddr_capwap)); - address.sin.sin_family = AF_INET; - address.sin.sin_addr.s_addr = INADDR_BROADCAST; - address.sin.sin_port = htons(CAPWAP_CONTROL_PORT); - memcpy(capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, g_wtp.acdiscoveryarray->count), &address, sizeof(union sockaddr_capwap)); + memset(&address, 0, sizeof(struct addr_capwap)); + address.resolved = 1; + address.sockaddr.sin.sin_family = AF_INET; + address.sockaddr.sin.sin_addr.s_addr = INADDR_BROADCAST; + address.sockaddr.sin.sin_port = htons(CAPWAP_CONTROL_PORT); + memcpy(capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, g_wtp.acdiscoveryarray->count), &address, sizeof(struct addr_capwap)); /* Multicast IPv4 */ /* TODO */ @@ -1202,20 +1203,22 @@ static int wtp_parsing_configuration_1_0(config_t* config) { for (i = 0; i < count; i++) { const char* address = config_setting_get_string_elem(configSetting, i); if (address != NULL) { - union sockaddr_capwap acaddr; + struct addr_capwap acaddr; + memset(&acaddr, 0, sizeof(struct addr_capwap)); + strncpy(acaddr.fqdn, address, CAPWAP_MAX_FQDN_SIZE-1); + acaddr.resolved = 0; /* Parsing address */ - if (capwap_address_from_string(address, &acaddr)) { - if (!CAPWAP_GET_NETWORK_PORT(&acaddr)) { - CAPWAP_SET_NETWORK_PORT(&acaddr, CAPWAP_CONTROL_PORT); + if (capwap_address_from_string(address, &acaddr.sockaddr)) { + if (!CAPWAP_GET_NETWORK_PORT(&acaddr.sockaddr)) { + CAPWAP_SET_NETWORK_PORT(&acaddr.sockaddr, CAPWAP_CONTROL_PORT); } - - memcpy(capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, g_wtp.acdiscoveryarray->count), &acaddr, sizeof(union sockaddr_capwap)); + acaddr.resolved = 1; g_wtp.discoverytype.type = CAPWAP_DISCOVERYTYPE_TYPE_STATIC; } else { - capwap_logging_error("Invalid configuration file, invalid application.acdiscovery.host value"); - return 0; + capwap_logging_info("%s:%d Could not resolve application.acdiscovery.host %s", __FILE__, __LINE__, address); } + memcpy(capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, g_wtp.acdiscoveryarray->count), &acaddr, sizeof(struct addr_capwap)); } } } @@ -1228,19 +1231,21 @@ static int wtp_parsing_configuration_1_0(config_t* config) { for (i = 0; i < count; i++) { const char* address = config_setting_get_string_elem(configSetting, i); if (address != NULL) { - union sockaddr_capwap acaddr; + struct addr_capwap acaddr; + memset(&acaddr, 0, sizeof(struct addr_capwap)); + strncpy(acaddr.fqdn, address, CAPWAP_MAX_FQDN_SIZE-1); + acaddr.resolved = 0; /* Parsing address */ - if (capwap_address_from_string(address, &acaddr)) { - if (!CAPWAP_GET_NETWORK_PORT(&acaddr)) { - CAPWAP_SET_NETWORK_PORT(&acaddr, CAPWAP_CONTROL_PORT); + if (capwap_address_from_string(address, &acaddr.sockaddr)) { + if (!CAPWAP_GET_NETWORK_PORT(&acaddr.sockaddr)) { + CAPWAP_SET_NETWORK_PORT(&acaddr.sockaddr, CAPWAP_CONTROL_PORT); } - - memcpy(capwap_array_get_item_pointer(g_wtp.acpreferedarray, g_wtp.acpreferedarray->count), &acaddr, sizeof(union sockaddr_capwap)); + acaddr.resolved = 1; } else { - capwap_logging_error("Invalid configuration file, invalid application.acprefered.host value"); - return 0; + capwap_logging_info("%s:%d Could not resolve application.acprefered.host %s", __FILE__, __LINE__, acaddr.fqdn); } + memcpy(capwap_array_get_item_pointer(g_wtp.acpreferedarray, g_wtp.acpreferedarray->count), &acaddr, sizeof(struct addr_capwap)); } } } diff --git a/src/wtp/wtp_dfa_discovery.c b/src/wtp/wtp_dfa_discovery.c index 5d6c9d9..6cc27fa 100644 --- a/src/wtp/wtp_dfa_discovery.c +++ b/src/wtp/wtp_dfa_discovery.c @@ -49,9 +49,18 @@ void wtp_dfa_state_discovery_timeout(struct capwap_timeout* timeout, unsigned lo /* Check for preferred AC */ for (j = 0; j < ((indexpreferred != -1) ? indexpreferred : g_wtp.acpreferedarray->count); j++) { - union sockaddr_capwap* acpreferredaddr = (union sockaddr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j); - - if (!capwap_compare_ip(acpreferredaddr, &checkaddr)) { + struct addr_capwap* acpreferredaddr = (struct addr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j); + if (!acpreferredaddr->resolved) { + if (capwap_address_from_string(acpreferredaddr->fqdn, &acpreferredaddr->sockaddr)) { + if (!CAPWAP_GET_NETWORK_PORT(&acpreferredaddr->sockaddr)) { + CAPWAP_SET_NETWORK_PORT(&acpreferredaddr->sockaddr, CAPWAP_CONTROL_PORT); + } + acpreferredaddr->resolved = 1; + } else { + capwap_logging_info("%s:%d Could not resolve application.acprefered.host %s", __FILE__, __LINE__, acpreferredaddr->fqdn); + } + } + if (!capwap_compare_ip(&acpreferredaddr->sockaddr, &checkaddr)) { indexpreferred = j; memcpy(&peeraddr, &checkaddr, sizeof(union sockaddr_capwap)); break; @@ -79,9 +88,18 @@ void wtp_dfa_state_discovery_timeout(struct capwap_timeout* timeout, unsigned lo /* Check for preferred AC */ for (j = 0; j < ((indexpreferred != -1) ? indexpreferred : g_wtp.acpreferedarray->count); j++) { - union sockaddr_capwap* acpreferredaddr = (union sockaddr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j); - - if (!capwap_compare_ip(acpreferredaddr, &checkaddr)) { + struct addr_capwap* acpreferredaddr = (struct addr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j); + if (!acpreferredaddr->resolved) { + if (capwap_address_from_string(acpreferredaddr->fqdn, &acpreferredaddr->sockaddr)) { + if (!CAPWAP_GET_NETWORK_PORT(&acpreferredaddr->sockaddr)) { + CAPWAP_SET_NETWORK_PORT(&acpreferredaddr->sockaddr, CAPWAP_CONTROL_PORT); + } + acpreferredaddr->resolved = 1; + } else { + capwap_logging_info("Could not resolve application.acprefered.host %s", acpreferredaddr->fqdn); + } + } + if (!capwap_compare_ip(&acpreferredaddr->sockaddr, &checkaddr)) { indexpreferred = j; memcpy(&peeraddr, &checkaddr, sizeof(union sockaddr_capwap)); break; @@ -183,8 +201,20 @@ void wtp_dfa_state_discovery_timeout(struct capwap_timeout* timeout, unsigned lo /* Send discovery request to AC */ for (i = 0; i < g_wtp.acdiscoveryarray->count; i++) { - if (!capwap_sendto_fragmentpacket(g_wtp.net.socket, g_wtp.requestfragmentpacket, (union sockaddr_capwap*)capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, i))) { - capwap_logging_debug("Warning: error to send discovery request packet"); + struct addr_capwap* addr = capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, i); + if (!addr->resolved) { + if (capwap_address_from_string(addr->fqdn, &addr->sockaddr)) { + if (!CAPWAP_GET_NETWORK_PORT(&addr->sockaddr)) { + CAPWAP_SET_NETWORK_PORT(&addr->sockaddr, CAPWAP_CONTROL_PORT); + } + addr->resolved = 1; + g_wtp.discoverytype.type = CAPWAP_DISCOVERYTYPE_TYPE_STATIC; + } else { + capwap_logging_info("%s:%d Could not resolve application.acdiscovery.host %s", __FILE__, __LINE__, addr->fqdn); + } + } + if (!capwap_sendto_fragmentpacket(g_wtp.net.socket, g_wtp.requestfragmentpacket, &addr->sockaddr)) { + capwap_logging_info("Error to send discovery request packet"); } } diff --git a/src/wtp/wtp_dfa_idle.c b/src/wtp/wtp_dfa_idle.c index 10ec27b..8985e9d 100644 --- a/src/wtp/wtp_dfa_idle.c +++ b/src/wtp/wtp_dfa_idle.c @@ -12,11 +12,12 @@ static int wtp_join_prefered_ac() while (g_wtp.acpreferedselected < g_wtp.acpreferedarray->count) { union sockaddr_capwap localaddr; - union sockaddr_capwap *peeraddr; + struct addr_capwap *peeraddr; /* Found in configuration file the AC address */ peeraddr = capwap_array_get_item_pointer(g_wtp.acpreferedarray, - g_wtp.acpreferedselected); + g_wtp.acpreferedselected); + /* Next AC */ g_wtp.acpreferedselected++; @@ -28,7 +29,18 @@ static int wtp_join_prefered_ac() return -1; } - if (capwap_connect_socket(&g_wtp.net, peeraddr) < 0) { + if(!peeraddr->resolved) { + if (capwap_address_from_string(peeraddr->fqdn, &peeraddr->sockaddr)) { + if (!CAPWAP_GET_NETWORK_PORT(&peeraddr->sockaddr)) { + CAPWAP_SET_NETWORK_PORT(&peeraddr->sockaddr, CAPWAP_CONTROL_PORT); + } + peeraddr->resolved = 1; + } else { + capwap_logging_info("%s:%d Could not resolve application.acprefered.host %s", __FILE__, __LINE__, peeraddr->fqdn); + } + } + + if (capwap_connect_socket(&g_wtp.net, &peeraddr->sockaddr) < 0) { capwap_logging_fatal("Cannot bind control address"); capwap_close_sockets(&g_wtp.net); return -1; @@ -42,7 +54,7 @@ static int wtp_join_prefered_ac() } /* */ - capwap_crypt_setconnection(&g_wtp.dtls, g_wtp.net.socket, &localaddr, peeraddr); + capwap_crypt_setconnection(&g_wtp.dtls, g_wtp.net.socket, &localaddr, &peeraddr->sockaddr); /* */ if (!g_wtp.enabledtls) {