void wtp_radio_reset() { int i, j; if (!g_wtp.radios) return; for (i = 0; i < g_wtp.radios->count; i++) { struct wtp_radio* radio = (struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i); for (j = 0; j < radio->wlan->count; j++) { struct wtp_radio_wlan *wlan = (struct wtp_radio_wlan *)capwap_array_get_item_pointer(radio->wlan, j); /* Destroy WLAN interface */ if (wlan->wlanhandle) wifi_wlan_stopap(wlan->wlanhandle); wlan->in_use = 0; } radio->initialized = 0; } }
void wtp_radio_close(void) { int i; ASSERT(g_wtp.radios != NULL); for (i = 0; i < g_wtp.radios->count; i++) { struct wtp_radio* radio = (struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i); if (radio->antenna.selections) { capwap_array_free(radio->antenna.selections); } for (i = 0; i < radio->wlan->count; i++) { struct wtp_radio_wlan *wlan = (struct wtp_radio_wlan *)capwap_array_get_item_pointer(radio->wlan, i); /* Destroy BSS interface */ if (wlan->wlanhandle) wifi_wlan_destroy(wlan->wlanhandle); } capwap_array_free(radio->wlan); } capwap_array_resize(g_wtp.radios, 0); }
static void* capwap_acipv6list_element_clone(void* data) { int i; struct capwap_acipv6list_element* cloneelement; struct capwap_acipv6list_element* element = (struct capwap_acipv6list_element*)data; ASSERT(data != NULL); cloneelement = capwap_clone(data, sizeof(struct capwap_acipv6list_element)); cloneelement->addresses = capwap_array_create(sizeof(struct in6_addr), 0, 0); for (i = 0; i < element->addresses->count; i++) { memcpy(capwap_array_get_item_pointer(cloneelement->addresses, i), capwap_array_get_item_pointer(element->addresses, i), sizeof(struct in6_addr)); } return cloneelement; }
static void* capwap_80211_antenna_element_clone(void* data) { int i; struct capwap_80211_antenna_element* cloneelement; struct capwap_80211_antenna_element* element = (struct capwap_80211_antenna_element*)data; ASSERT(data != NULL); cloneelement = capwap_clone(data, sizeof(struct capwap_80211_antenna_element)); cloneelement->selections = capwap_array_create(sizeof(uint8_t), 0, 1); for (i = 0; i < element->selections->count; i++) { memcpy(capwap_array_get_item_pointer(cloneelement->selections, i), capwap_array_get_item_pointer(element->selections, i), sizeof(uint8_t)); } return cloneelement; }
static void push_wtp_update_configuration_item(struct capwap_array *updateitems, int type, struct wtp_radio *radio) { struct wtp_update_configuration_item* item; item = (struct wtp_update_configuration_item *)capwap_array_get_item_pointer(updateitems, updateitems->count); item->type = type; item->radio = radio; }
static void capwap_acipv6list_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { unsigned long i; struct capwap_acipv6list_element* element = (struct capwap_acipv6list_element*)data; ASSERT(data != NULL); /* */ for (i = 0; i < element->addresses->count; i++) { func->write_block(handle, (uint8_t*)capwap_array_get_item_pointer(element->addresses, i), sizeof(struct in6_addr)); } }
struct wtp_radio* wtp_radio_create_phy(void) { struct wtp_radio* radio; /* Create disabled radio */ radio = (struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, g_wtp.radios->count); radio->radioid = (uint8_t)g_wtp.radios->count; radio->status = WTP_RADIO_DISABLED; /* Init configuration radio */ radio->wlan = capwap_array_create(sizeof(struct wtp_radio_wlan), 0, 1); radio->antenna.selections = capwap_array_create(sizeof(uint8_t), 0, 1); return radio; }
static void* capwap_80211_antenna_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { int i; uint8_t count; unsigned short length; struct capwap_80211_antenna_element* data; ASSERT(handle != NULL); ASSERT(func != NULL); length = func->read_ready(handle); if (length < 5) { capwap_logging_debug("Invalid IEEE 802.11 Antenna element"); return NULL; } length -= 4; if (length > CAPWAP_ANTENNASELECTIONS_MAXLENGTH) { capwap_logging_debug("Invalid IEEE 802.11 Antenna element"); return NULL; } /* */ data = (struct capwap_80211_antenna_element*)capwap_alloc(sizeof(struct capwap_80211_antenna_element)); memset(data, 0, sizeof(struct capwap_80211_antenna_element)); data->selections = capwap_array_create(sizeof(uint8_t), 0, 1); /* Retrieve data */ func->read_u8(handle, &data->radioid); if (!IS_VALID_RADIOID(data->radioid)) { capwap_80211_antenna_element_free((void*)data); capwap_logging_debug("Invalid IEEE 802.11 Antenna element element: invalid radio"); return NULL; } func->read_u8(handle, &data->diversity); func->read_u8(handle, &data->combiner); func->read_u8(handle, &count); /* Check */ if (count != length) { capwap_logging_debug("Invalid IEEE 802.11 Antenna element"); capwap_free(data); return NULL; } for (i = 0; i < count; i++) { func->read_u8(handle, (uint8_t*)capwap_array_get_item_pointer(data->selections, i)); } return data; }
void capwap_element_80211_antenna_copy(struct capwap_80211_antenna_element* dst, struct capwap_80211_antenna_element* src) { int i; ASSERT(dst != NULL); ASSERT(src != NULL); if (dst->selections) { capwap_array_resize(dst->selections, 0); } else { dst->selections = capwap_array_create(sizeof(uint8_t), 0, 1); } dst->radioid = src->radioid; dst->diversity = src->diversity; dst->combiner = src->combiner; if (src->selections) { for (i = 0; i < src->selections->count; i++) { uint8_t* value = (uint8_t*)capwap_array_get_item_pointer(dst->selections, i); *value = *(uint8_t*)capwap_array_get_item_pointer(src->selections, i); } } }
static void capwap_80211_antenna_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { int i; struct capwap_80211_antenna_element* element = (struct capwap_80211_antenna_element*)data; ASSERT(data != NULL); ASSERT(IS_VALID_RADIOID(element->radioid)); ASSERT(element->selections != NULL); func->write_u8(handle, element->radioid); func->write_u8(handle, element->diversity); func->write_u8(handle, element->combiner); func->write_u8(handle, element->selections->count); for (i = 0; i < element->selections->count; i++) { func->write_u8(handle, *(uint8_t*)capwap_array_get_item_pointer(element->selections, i)); } }
struct wtp_radio* wtp_radio_get_phy(uint8_t radioid) { int i; /* Check */ if (!IS_VALID_RADIOID(radioid)) { return NULL; } /* Retrieve radio */ for (i = 0; i < g_wtp.radios->count; i++) { struct wtp_radio* radio = (struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i); if (radioid == radio->radioid) { return radio; } } return NULL; }
struct wtp_radio_wlan *wtp_radio_get_wlan(struct wtp_radio *radio, uint8_t wlanid) { ASSERT(radio != NULL); /* Check */ if (!IS_VALID_WLANID(wlanid)) { log_printf(LOG_DEBUG, "wtp_radio_get_wlan: invalid wlanid (%d)", wlanid); return NULL; } if (wlanid > radio->wlan->count) { log_printf(LOG_WARNING, "wtp_radio_get_wlan: invalid wlanid (%d > %lu)", wlanid, radio->wlan->count); return NULL; } /* Retrieve BSS */ return (struct wtp_radio_wlan *)capwap_array_get_item_pointer(radio->wlan, wlanid); }
struct wtp_radio_wlan* wtp_radio_search_wlan(struct wtp_radio* radio, const uint8_t* bssid) { int i; ASSERT(bssid != NULL); if (radio) { return __wtp_radio_search_wlan(radio, bssid); } /* Search from any radio */ for (i = 0; i < g_wtp.radios->count; i++) { struct wtp_radio_wlan* wlansearch = __wtp_radio_search_wlan((struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i), bssid); if (wlansearch) { return wlansearch; } } return NULL; }
static struct wtp_radio_wlan *__wtp_radio_search_wlan(struct wtp_radio *radio, const uint8_t *bssid) { int i; ASSERT(radio != NULL); ASSERT(radio->wlan != NULL); /* Retrieve BSS */ for (i = 0; i < radio->wlan->count; i++) { struct wtp_radio_wlan *wlan = (struct wtp_radio_wlan *)capwap_array_get_item_pointer(radio->wlan, i); if (!wlan->wlanhandle) continue; if (!memcmp(bssid, wlan->wlanhandle->address, MACADDRESS_EUI48_LENGTH)) return wlan; } return NULL; }
void capwap_free_parsed_packet(struct capwap_parsed_packet* packet) { int i; struct capwap_list_item* itemlist; struct capwap_message_element_itemlist* messageelement; const struct capwap_message_elements_ops* msgops; ASSERT(packet != NULL); if (packet->rxmngpacket && packet->messages) { itemlist = packet->messages->first; while (itemlist) { messageelement = (struct capwap_message_element_itemlist*)itemlist->item; if (messageelement->data) { msgops = capwap_get_message_element_ops(messageelement->id); if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_SINGLE) { msgops->free(messageelement->data); } else if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_ARRAY) { struct capwap_array* arraymessageelement = (struct capwap_array*)messageelement->data; for (i = 0; i < arraymessageelement->count; i++) { msgops->free(*(void**)capwap_array_get_item_pointer(arraymessageelement, i)); } /* */ capwap_array_free(arraymessageelement); } } /* */ itemlist = itemlist->next; } /* */ packet->rxmngpacket = NULL; capwap_list_free(packet->messages); packet->messages = NULL; } }
static void* capwap_acipv6list_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { uint16_t length; struct capwap_acipv6list_element* data; ASSERT(handle != NULL); ASSERT(func != NULL); length = func->read_ready(handle); if ((length >= 16) && (length <= CAPWAP_ACIPV4LIST_MAX_ELEMENTS * 16) && (length % 16)) { log_printf(LOG_DEBUG, "Invalid AC IPv6 List element: underbuffer"); return NULL; } /* Retrieve data */ data = (struct capwap_acipv6list_element*)capwap_alloc(sizeof(struct capwap_acipv6list_element)); data->addresses = capwap_array_create(sizeof(struct in6_addr), 0, 0); while (length > 0) { struct in6_addr* address = (struct in6_addr*)capwap_array_get_item_pointer(data->addresses, data->addresses->count); func->read_block(handle, (uint8_t*)address, sizeof(struct in6_addr)); length -= 16; } return data; }
struct capwap_wtpboarddata_board_subelement* capwap_wtpboarddata_get_subelement(struct capwap_wtpboarddata_element* wtpboarddata, int subelement) { int i; ASSERT(wtpboarddata != NULL); ASSERT((subelement >= CAPWAP_BOARD_SUBELEMENT_TYPE_FIRST) && (subelement <= CAPWAP_BOARD_SUBELEMENT_TYPE_LAST)); /* */ for (i = 0; i < wtpboarddata->boardsubelement->count; i++) { struct capwap_wtpboarddata_board_subelement* desc = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(wtpboarddata->boardsubelement, i); if (desc->type == subelement) { return desc; } } return NULL; }
int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap_parsed_packet* packet) { unsigned short binding; unsigned short bodylength; ASSERT(rxmngpacket != NULL); ASSERT(packet != NULL); /* */ memset(packet, 0, sizeof(struct capwap_parsed_packet)); packet->rxmngpacket = rxmngpacket; packet->messages = capwap_list_create(); binding = GET_WBID_HEADER(packet->rxmngpacket->header); /* Position reader to capwap body */ memcpy(&rxmngpacket->readpos, &rxmngpacket->readbodypos, sizeof(struct read_block_from_pos)); /* */ bodylength = rxmngpacket->ctrlmsg.length - CAPWAP_CONTROL_MESSAGE_MIN_LENGTH; while (bodylength > 0) { struct capwap_message_element_id id = { .vendor = 0 }; uint16_t msglength; struct capwap_list_item* itemlist; struct capwap_message_element_itemlist* messageelement; void *element; const struct capwap_message_elements_ops* read_ops; /* Get type and length */ rxmngpacket->readerpacketallowed = sizeof(struct capwap_message_element); if (rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &id.type) != sizeof(uint16_t) || rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &msglength) != sizeof(uint16_t) || msglength > bodylength) return INVALID_MESSAGE_ELEMENT; /* Allowed to parsing only the size of message element */ rxmngpacket->readerpacketallowed = msglength; /* Check binding */ if (IS_80211_MESSAGE_ELEMENTS(id) && (binding != CAPWAP_WIRELESS_BINDING_IEEE80211)) return UNRECOGNIZED_MESSAGE_ELEMENT; log_printf(LOG_DEBUG, "MESSAGE ELEMENT: %d", id.type); if (id.type == CAPWAP_ELEMENT_VENDORPAYLOAD_TYPE) { struct capwap_message_element_id vendor_id; if (msglength < 7) { log_printf(LOG_DEBUG, "Invalid Vendor Specific Payload element: underbuffer"); return INVALID_MESSAGE_ELEMENT; } if ((msglength - 6) > CAPWAP_VENDORPAYLOAD_MAXLENGTH) { log_printf(LOG_DEBUG, "Invalid Vendor Specific Payload element: overbuffer"); return INVALID_MESSAGE_ELEMENT; } rxmngpacket->read_ops.read_u32((capwap_message_elements_handle)rxmngpacket, &vendor_id.vendor); rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &vendor_id.type); log_printf(LOG_DEBUG, "VENDOR MESSAGE ELEMENT: %06x:%d", vendor_id.vendor, vendor_id.type); read_ops = capwap_get_message_element_ops(vendor_id); log_printf(LOG_DEBUG, "vendor read_ops: %p", read_ops); if (read_ops) { id = vendor_id; element = read_ops->parse((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->read_ops); } else { read_ops = capwap_get_message_element_ops(id); element = capwap_unknown_vendorpayload_element_parsing((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->read_ops, msglength - 6, vendor_id); } } else { /* Reader function */ read_ops = capwap_get_message_element_ops(id); log_printf(LOG_DEBUG, "read_ops: %p", read_ops); if (!read_ops) return UNRECOGNIZED_MESSAGE_ELEMENT; /* Get message element */ element = read_ops->parse((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->read_ops); } if (!element) return INVALID_MESSAGE_ELEMENT; /* */ itemlist = capwap_get_message_element(packet, id); if (read_ops->category == CAPWAP_MESSAGE_ELEMENT_SINGLE) { /* Check for multiple message element */ if (itemlist) { return INVALID_MESSAGE_ELEMENT; } /* Create new message element */ itemlist = capwap_itemlist_create(sizeof(struct capwap_message_element_itemlist)); messageelement = (struct capwap_message_element_itemlist*)itemlist->item; messageelement->id = id; messageelement->category = CAPWAP_MESSAGE_ELEMENT_SINGLE; messageelement->data = element; /* */ capwap_itemlist_insert_after(packet->messages, NULL, itemlist); } else if (read_ops->category == CAPWAP_MESSAGE_ELEMENT_ARRAY) { struct capwap_array* arraymessageelement; if (itemlist) { messageelement = (struct capwap_message_element_itemlist*)itemlist->item; arraymessageelement = (struct capwap_array*)messageelement->data; } else { arraymessageelement = capwap_array_create(sizeof(void*), 0, 0); /* */ itemlist = capwap_itemlist_create(sizeof(struct capwap_message_element_itemlist)); messageelement = (struct capwap_message_element_itemlist*)itemlist->item; messageelement->id = id; messageelement->category = CAPWAP_MESSAGE_ELEMENT_ARRAY; messageelement->data = (void*)arraymessageelement; /* */ capwap_itemlist_insert_after(packet->messages, NULL, itemlist); } /* */ *(void **)capwap_array_get_item_pointer(arraymessageelement, arraymessageelement->count) = element; } /* Check if read all data of message element */ if (rxmngpacket->readerpacketallowed) { return INVALID_MESSAGE_ELEMENT; } /* */ bodylength -= (msglength + sizeof(struct capwap_message_element)); } return PARSING_COMPLETE; } /* */ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct capwap_array* returnedmessage) { unsigned short binding; struct capwap_resultcode_element* resultcode; ASSERT(packet != NULL); ASSERT(packet->rxmngpacket != NULL); binding = GET_WBID_HEADER(packet->rxmngpacket->header); switch (packet->rxmngpacket->ctrlmsg.type) { case CAPWAP_DISCOVERY_REQUEST: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_DISCOVERYTYPE) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPBOARDDATA) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPDESCRIPTOR) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPFRAMETUNNELMODE) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPMACTYPE)) { if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) { return 0; } } else { return 0; } } break; } case CAPWAP_DISCOVERY_RESPONSE: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ACDESCRIPTION) && capwap_get_message_element(packet, CAPWAP_ELEMENT_ACNAME) && (capwap_get_message_element(packet, CAPWAP_ELEMENT_CONTROLIPV4) || capwap_get_message_element(packet, CAPWAP_ELEMENT_CONTROLIPV6))) { return 0; } /* Check if packet contains Result Code with Error Message */ resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE); if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) { return 0; } break; } case CAPWAP_JOIN_REQUEST: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_LOCATION) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPBOARDDATA) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPDESCRIPTOR) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPNAME) && capwap_get_message_element(packet, CAPWAP_ELEMENT_SESSIONID) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPFRAMETUNNELMODE) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPMACTYPE) && capwap_get_message_element(packet, CAPWAP_ELEMENT_ECNSUPPORT) && (capwap_get_message_element(packet, CAPWAP_ELEMENT_LOCALIPV4) || capwap_get_message_element(packet, CAPWAP_ELEMENT_LOCALIPV6))) { if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) { return 0; } } else { return 0; } } break; } case CAPWAP_JOIN_RESPONSE: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE) && capwap_get_message_element(packet, CAPWAP_ELEMENT_ACDESCRIPTION) && capwap_get_message_element(packet, CAPWAP_ELEMENT_ACNAME) && capwap_get_message_element(packet, CAPWAP_ELEMENT_ECNSUPPORT) && (capwap_get_message_element(packet, CAPWAP_ELEMENT_CONTROLIPV4) || capwap_get_message_element(packet, CAPWAP_ELEMENT_CONTROLIPV6)) && (capwap_get_message_element(packet, CAPWAP_ELEMENT_LOCALIPV4) || capwap_get_message_element(packet, CAPWAP_ELEMENT_LOCALIPV6))) { return 0; } /* Check if packet contains Result Code with Error Message */ resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE); if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) { return 0; } break; } case CAPWAP_CONFIGURATION_STATUS_REQUEST: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ACNAME) && capwap_get_message_element(packet, CAPWAP_ELEMENT_RADIOADMSTATE) && capwap_get_message_element(packet, CAPWAP_ELEMENT_STATISTICSTIMER) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPREBOOTSTAT)) { if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) { return 0; } } else { return 0; } } break; } case CAPWAP_CONFIGURATION_STATUS_RESPONSE: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_TIMERS) && capwap_get_message_element(packet, CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD) && capwap_get_message_element(packet, CAPWAP_ELEMENT_IDLETIMEOUT) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPFALLBACK) && (capwap_get_message_element(packet, CAPWAP_ELEMENT_ACIPV4LIST) || capwap_get_message_element(packet, CAPWAP_ELEMENT_ACIPV6LIST))) { return 0; } /* Check if packet contains Result Code with Error Message */ resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE); if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) { return 0; } break; } case CAPWAP_CONFIGURATION_UPDATE_REQUEST: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ACNAMEPRIORITY) || capwap_get_message_element(packet, CAPWAP_ELEMENT_ACTIMESTAMP) || capwap_get_message_element(packet, CAPWAP_ELEMENT_ADDMACACL) || capwap_get_message_element(packet, CAPWAP_ELEMENT_TIMERS) || capwap_get_message_element(packet, CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD) || capwap_get_message_element(packet, CAPWAP_ELEMENT_DELETEMACACL) || capwap_get_message_element(packet, CAPWAP_ELEMENT_IDLETIMEOUT) || capwap_get_message_element(packet, CAPWAP_ELEMENT_LOCATION) || capwap_get_message_element(packet, CAPWAP_ELEMENT_RADIOADMSTATE) || capwap_get_message_element(packet, CAPWAP_ELEMENT_STATISTICSTIMER) || capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPFALLBACK) || capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPNAME) || capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPSTATICIPADDRESS) || capwap_get_message_element(packet, CAPWAP_ELEMENT_IMAGEIDENTIFIER) || capwap_get_message_element(packet, CAPWAP_ELEMENT_VENDORPAYLOAD)) { return 0; } break; } case CAPWAP_CONFIGURATION_UPDATE_RESPONSE: { return 0; } case CAPWAP_WTP_EVENT_REQUEST: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD) || capwap_get_message_element(packet, CAPWAP_ELEMENT_DUPLICATEIPV4) || capwap_get_message_element(packet, CAPWAP_ELEMENT_DUPLICATEIPV6) || capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPRADIOSTAT) || capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPREBOOTSTAT) || capwap_get_message_element(packet, CAPWAP_ELEMENT_DELETESTATION) || capwap_get_message_element(packet, CAPWAP_ELEMENT_VENDORPAYLOAD)) { return 0; } break; } case CAPWAP_WTP_EVENT_RESPONSE: { return 0; } case CAPWAP_CHANGE_STATE_EVENT_REQUEST: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RADIOOPRSTATE) && capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) { return 0; } break; } case CAPWAP_CHANGE_STATE_EVENT_RESPONSE: { return 0; } case CAPWAP_ECHO_REQUEST: { return 0; } case CAPWAP_ECHO_RESPONSE: { return 0; } case CAPWAP_IMAGE_DATA_REQUEST: { return 0; } case CAPWAP_IMAGE_DATA_RESPONSE: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) { return 0; } break; } case CAPWAP_RESET_REQUEST: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_IMAGEIDENTIFIER)) { return 0; } break; } case CAPWAP_RESET_RESPONSE: { return 0; } case CAPWAP_PRIMARY_DISCOVERY_REQUEST: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_DISCOVERYTYPE) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPBOARDDATA) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPDESCRIPTOR) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPFRAMETUNNELMODE) && capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPMACTYPE)) { if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) { return 0; } } else { return 0; } } break; } case CAPWAP_PRIMARY_DISCOVERY_RESPONSE: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ACDESCRIPTION) && capwap_get_message_element(packet, CAPWAP_ELEMENT_ACNAME) && (capwap_get_message_element(packet, CAPWAP_ELEMENT_CONTROLIPV4) || capwap_get_message_element(packet, CAPWAP_ELEMENT_CONTROLIPV6))) { return 0; } /* Check if packet contains Result Code with Error Message */ resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE); if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) { return 0; } break; } case CAPWAP_DATA_TRANSFER_REQUEST: { /* TODO */ break; } case CAPWAP_DATA_TRANSFER_RESPONSE: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) { return 0; } break; } case CAPWAP_CLEAR_CONFIGURATION_REQUEST: { return 0; } case CAPWAP_CLEAR_CONFIGURATION_RESPONSE: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) { return 0; } break; } case CAPWAP_STATION_CONFIGURATION_REQUEST: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ADDSTATION)) { if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_STATION)) { return 0; } } else { return 0; } } else if (capwap_get_message_element(packet, CAPWAP_ELEMENT_DELETESTATION)) { return 0; } break; } case CAPWAP_STATION_CONFIGURATION_RESPONSE: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) { return 0; } break; } case CAPWAP_IEEE80211_WLAN_CONFIGURATION_REQUEST: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_ADD_WLAN) || capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_UPDATE_WLAN) || capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_DELETE_WLAN)) { return 0; } break; } case CAPWAP_IEEE80211_WLAN_CONFIGURATION_RESPONSE: { if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) { return 0; } break; } } return -1; }
static void* capwap_wtpboarddata_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { struct capwap_wtpboarddata_element* data; ASSERT(handle != NULL); ASSERT(func != NULL); if (func->read_ready(handle) < 14) { capwap_logging_debug("Invalid WTP Board Data element: underbuffer"); return NULL; } /* */ data = (struct capwap_wtpboarddata_element*)capwap_alloc(sizeof(struct capwap_wtpboarddata_element)); data->boardsubelement = capwap_array_create(sizeof(struct capwap_wtpboarddata_board_subelement), 0, 1); /* Retrieve data */ func->read_u32(handle, &data->vendor); if (!data->vendor) { capwap_wtpboarddata_element_free((void*)data); capwap_logging_debug("Invalid WTP Board Data element: invalid vendor"); return NULL; } /* WTP Board Data Subelement */ while (func->read_ready(handle) > 0) { unsigned short length; struct capwap_wtpboarddata_board_subelement* desc = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(data->boardsubelement, data->boardsubelement->count); /* */ func->read_u16(handle, &desc->type); func->read_u16(handle, &desc->length); if ((desc->type < CAPWAP_BOARD_SUBELEMENT_TYPE_FIRST) || (desc->type > CAPWAP_BOARD_SUBELEMENT_TYPE_LAST)) { capwap_logging_debug("Invalid WTP Board Data element: invalid type"); capwap_wtpboarddata_element_free(data); return NULL; } /* Check buffer size */ length = func->read_ready(handle); if (!length || (length > CAPWAP_BOARD_SUBELEMENT_MAXDATA) || (length < desc->length)) { capwap_logging_debug("Invalid WTP Board Data element: invalid length"); capwap_wtpboarddata_element_free(data); return NULL; } desc->data = (uint8_t*)capwap_alloc(desc->length); func->read_block(handle, desc->data, desc->length); } return data; }
static uint32_t ac_dfa_state_join_create_response(struct ac_session_t* session, struct capwap_parsed_packet* packet, struct ac_soap_response* response, struct capwap_packet_txmng* txmngpacket) { int i; int j; int length; struct json_object* jsonroot; struct json_object* jsonelement; struct capwap_list* controllist; struct capwap_list_item* item; unsigned short binding = GET_WBID_HEADER(packet->rxmngpacket->header); /* Receive SOAP response with JSON result { WTPRadioInformation: [ <IEEE 802.11 BINDING> IEEE80211WTPRadioInformation: { RadioID: [int], Mode: [int] } ] ACIPv4List: [ { ACIPAddress: [string] } ], ACIPv6List: [ { ACIPAddress: [string] } ] <IEEE 802.11 BINDING> WTPRadio: [ { RadioID: [int], IEEE80211WTPRadioInformation: { Mode: [int] } } ] } */ /* Add message elements response, every local value can be overwrite from backend server */ jsonroot = ac_soapclient_parse_json_response(response); if (!jsonroot) { return CAPWAP_RESULTCODE_FAILURE; } /* AC Descriptor */ ac_update_statistics(); capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACDESCRIPTION, &g_ac.descriptor); /* AC Name */ capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACNAME, &g_ac.acname); /* WTP Radio Information */ if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) { struct ac_json_ieee80211_wtpradio wtpradio; struct capwap_array* wtpradioinformation = (struct capwap_array*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION); /* */ ac_json_ieee80211_init(&wtpradio); /* */ jsonelement = compat_json_object_object_get(jsonroot, IEEE80211_BINDING_JSON_ROOT); if (jsonelement) { ac_json_ieee80211_parsingjson(&wtpradio, jsonelement); } /* Copy WTP Radio Information if not present into SOAP response */ for (i = 0; i < wtpradioinformation->count; i++) { ac_json_ieee80211_addmessageelement(&wtpradio, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, *(struct capwap_80211_wtpradioinformation_element**)capwap_array_get_item_pointer(wtpradioinformation, i), 0); } /* */ ac_json_ieee80211_buildpacket(&wtpradio, txmngpacket); /* Free resource */ ac_json_ieee80211_free(&wtpradio); } /* ECN Support */ capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ECNSUPPORT, &session->dfa.ecn); /* Get information from any local address */ controllist = capwap_list_create(); ac_get_control_information(controllist); /* CAPWAP Control IP Address */ for (item = controllist->first; item != NULL; item = item->next) { struct ac_session_control* sessioncontrol = (struct ac_session_control*)item->item; if (sessioncontrol->localaddress.ss.ss_family == AF_INET) { struct capwap_controlipv4_element element; memcpy(&element.address, &((struct sockaddr_in*)&sessioncontrol->localaddress)->sin_addr, sizeof(struct in_addr)); element.wtpcount = sessioncontrol->count; capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV4, &element); } else if (sessioncontrol->localaddress.ss.ss_family == AF_INET6) { struct capwap_controlipv6_element element; memcpy(&element.address, &((struct sockaddr_in6*)&sessioncontrol->localaddress)->sin6_addr, sizeof(struct in6_addr)); element.wtpcount = sessioncontrol->count; capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV6, &element); } } capwap_list_free(controllist); /* CAPWAP Local IP Address */ if (session->dtls.localaddr.ss.ss_family == AF_INET) { struct capwap_localipv4_element addr; memcpy(&addr.address, &session->dtls.localaddr.sin.sin_addr, sizeof(struct in_addr)); capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_LOCALIPV4, &addr); } else if (session->dtls.localaddr.ss.ss_family == AF_INET6) { struct capwap_localipv6_element addr; memcpy(&addr.address, &session->dtls.localaddr.sin6.sin6_addr, sizeof(struct in6_addr)); capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_LOCALIPV6, &addr); } /* ACIPv4List */ jsonelement = NULL; if (jsonroot) { jsonelement = compat_json_object_object_get(jsonroot, "ACIPv4List"); if (jsonelement && (json_object_get_type(jsonelement) == json_type_array)) { length = json_object_array_length(jsonelement); } else { jsonelement = NULL; } } if (jsonelement) { struct capwap_acipv4list_element* responseacipv4list; responseacipv4list = (struct capwap_acipv4list_element*)capwap_alloc(sizeof(struct capwap_acipv4list_element)); responseacipv4list->addresses = capwap_array_create(sizeof(struct in_addr), 0, 0); for (j = 0; j < length; j++) { struct json_object* jsonvalue = json_object_array_get_idx(jsonelement, j); if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_object)) { struct json_object* jsonitem; /* ACIPAddress */ jsonitem = compat_json_object_object_get(jsonvalue, "ACIPAddress"); if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) { const char* value = json_object_get_string(jsonitem); if (value) { union sockaddr_capwap address; if (capwap_address_from_string(value, &address)) { /* Accept only IPv4 address */ if (address.ss.ss_family == AF_INET) { struct in_addr* responseaddress_in = (struct in_addr*)capwap_array_get_item_pointer(responseacipv4list->addresses, responseacipv4list->addresses->count); memcpy(responseaddress_in, &address.sin.sin_addr, sizeof(struct in_addr)); } } } } } } if (responseacipv4list->addresses->count > 0) { capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV4LIST, responseacipv4list); } capwap_array_free(responseacipv4list->addresses); capwap_free(responseacipv4list); } else if (session->dfa.acipv4list.addresses->count > 0) { capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV4LIST, &session->dfa.acipv4list); } /* ACIPv6List */ jsonelement = NULL; if (jsonroot) { jsonelement = compat_json_object_object_get(jsonroot, "ACIPv6List"); if (jsonelement && (json_object_get_type(jsonelement) == json_type_array)) { length = json_object_array_length(jsonelement); } else { jsonelement = NULL; } } if (jsonelement) { int j; struct capwap_acipv6list_element* responseacipv6list; responseacipv6list = (struct capwap_acipv6list_element*)capwap_alloc(sizeof(struct capwap_acipv6list_element)); responseacipv6list->addresses = capwap_array_create(sizeof(struct in6_addr), 0, 0); for (j = 0; j < length; j++) { struct json_object* jsonvalue = json_object_array_get_idx(jsonelement, j); if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_object)) { struct json_object* jsonitem; /* ACIPAddress */ jsonitem = compat_json_object_object_get(jsonvalue, "ACIPAddress"); if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) { const char* value = json_object_get_string(jsonitem); if (value) { union sockaddr_capwap address; if (capwap_address_from_string(value, &address)) { /* Accept only IPv6 address */ if (address.ss.ss_family == AF_INET6) { struct in6_addr* responseaddress_in6 = (struct in6_addr*)capwap_array_get_item_pointer(responseacipv6list->addresses, responseacipv6list->addresses->count); memcpy(responseaddress_in6, &address.sin6.sin6_addr, sizeof(struct in6_addr)); } } } } } } if (responseacipv6list->addresses->count > 0) { capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV6LIST, responseacipv6list); } capwap_array_free(responseacipv6list->addresses); capwap_free(responseacipv6list); } else if (session->dfa.acipv6list.addresses->count > 0) { capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV6LIST, &session->dfa.acipv6list); } /* CAPWAP Transport Protocol */ capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_TRANSPORT, &session->dfa.transport); /* CAPWAP_ELEMENT_IMAGEIDENTIFIER */ /* TODO */ /* CAPWAP_ELEMENT_MAXIMUMLENGTH */ /* TODO */ /* CAPWAP_ELEMENT_VENDORPAYLOAD */ /* TODO */ if (jsonroot) { json_object_put(jsonroot); } return CAPWAP_RESULTCODE_SUCCESS; }
static struct ac_soap_response* ac_dfa_state_join_parsing_request(struct ac_session_t* session, struct capwap_parsed_packet* packet) { int i; const char* jsonmessage; char* base64confstatus; struct json_object* jsonarray; struct json_object* jsonparam; struct json_object* jsonhash; struct ac_soap_response* response; struct capwap_location_element* location; struct capwap_wtpboarddata_element* wtpboarddata; struct capwap_wtpdescriptor_element* wtpdescriptor; struct capwap_wtpname_element* wtpname; struct capwap_wtpframetunnelmode_element* wtpframetunnelmode; struct capwap_wtpmactype_element* wtpmactype; struct capwap_ecnsupport_element* ecnsupport; struct capwap_localipv4_element* localipv4; struct capwap_localipv6_element* localipv6; struct capwap_wtprebootstat_element* wtprebootstat; unsigned short binding = GET_WBID_HEADER(packet->rxmngpacket->header); /* Create SOAP request with JSON param { Binding: { Type: [int] } LocationData: { Location: [string] }, WTPBoardData: { VendorIdentifier: [int], BoardDataSubElement: [ { BoardDataType: [int], BoardDataValue: [base64] } ] }, WTPDescriptor: { MaxRadios: [int], RadiosInUse: [int], EncryptionSubElement: [ { WBID: [int], EncryptionCapabilities: [int] } ], DescriptorSubElement: [ { DescriptorVendorIdentifier: [int], DescriptorType: [int], DescriptorData: [string] } ] }, WTPName: { Name: [string] }, WTPFrameTunnelMode: { NativeFrameTunnel: [bool] FrameTunnelMode8023: [bool], LocalBridge: [bool] }, WTPMACType: { Type: [int] }, <IEEE 802.11 BINDING> WTPRadio: [ { RadioID: [int], IEEE80211WTPRadioInformation: { Mode: [int] } } ] ECNSupport: { Mode: [int] } CAPWAPLocalIPv4Address: { Address: [string] }, CAPWAPLocalIPv6Address: { Address: [string] }, WTPRebootStatistics: { RebootCount: [int], ACInitiatedCount: [int], LinkFailureCount: [int], SWFailureCount: [int], HWFailureCount: [int], OtherFailureCount: [int], UnknownFailureCount: [int], LastFailureType: [int] } } */ /* */ jsonparam = json_object_new_object(); /* Binding */ jsonhash = json_object_new_object(); json_object_object_add(jsonhash, "Type", json_object_new_int((int)binding)); json_object_object_add(jsonparam, "Binding", jsonhash); /* LocationData */ location = (struct capwap_location_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_LOCATION); jsonhash = json_object_new_object(); json_object_object_add(jsonhash, "Location", json_object_new_string((char*)location->value)); json_object_object_add(jsonparam, "LocationData", jsonhash); /* WTPBoardData */ wtpboarddata = (struct capwap_wtpboarddata_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPBOARDDATA); jsonhash = json_object_new_object(); json_object_object_add(jsonhash, "VendorIdentifier", json_object_new_int((int)wtpboarddata->vendor)); jsonarray = json_object_new_array(); for (i = 0; i < wtpboarddata->boardsubelement->count; i++) { char* base64data; int base64length; struct json_object* jsonboard; struct capwap_wtpboarddata_board_subelement* wtpboarddata_board = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(wtpboarddata->boardsubelement, i); /* Encoded base64 board data */ base64data = (char*)capwap_alloc(AC_BASE64_ENCODE_LENGTH((int)wtpboarddata_board->length)); base64length = ac_base64_binary_encode((const char*)wtpboarddata_board->data, (int)wtpboarddata_board->length, base64data); base64data[base64length] = 0; jsonboard = json_object_new_object(); json_object_object_add(jsonboard, "BoardDataType", json_object_new_int((int)wtpboarddata_board->type)); json_object_object_add(jsonboard, "BoardDataValue", json_object_new_string(base64data)); json_object_array_add(jsonarray, jsonboard); capwap_free(base64data); } json_object_object_add(jsonhash, "BoardDataSubElement", jsonarray); json_object_object_add(jsonparam, "WTPBoardData", jsonhash); /* WTPDescriptor */ wtpdescriptor = (struct capwap_wtpdescriptor_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPDESCRIPTOR); jsonhash = json_object_new_object(); json_object_object_add(jsonhash, "MaxRadios", json_object_new_int((int)wtpdescriptor->maxradios)); json_object_object_add(jsonhash, "RadiosInUse", json_object_new_int((int)wtpdescriptor->radiosinuse)); jsonarray = json_object_new_array(); for (i = 0; i < wtpdescriptor->encryptsubelement->count; i++) { struct json_object* jsonencrypt; struct capwap_wtpdescriptor_encrypt_subelement* wtpdescriptor_encrypt = (struct capwap_wtpdescriptor_encrypt_subelement*)capwap_array_get_item_pointer(wtpdescriptor->encryptsubelement, i); jsonencrypt = json_object_new_object(); json_object_object_add(jsonencrypt, "WBID", json_object_new_int((int)wtpdescriptor_encrypt->wbid)); json_object_object_add(jsonencrypt, "EncryptionCapabilities", json_object_new_int((int)wtpdescriptor_encrypt->capabilities)); json_object_array_add(jsonarray, jsonencrypt); } json_object_object_add(jsonhash, "EncryptionSubElement", jsonarray); jsonarray = json_object_new_array(); for (i = 0; i < wtpdescriptor->descsubelement->count; i++) { struct json_object* jsondesc; struct capwap_wtpdescriptor_desc_subelement* wtpdescriptor_desc = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(wtpdescriptor->descsubelement, i); jsondesc = json_object_new_object(); json_object_object_add(jsondesc, "DescriptorVendorIdentifier", json_object_new_int((int)wtpdescriptor_desc->vendor)); json_object_object_add(jsondesc, "DescriptorType", json_object_new_int((int)wtpdescriptor_desc->type)); json_object_object_add(jsondesc, "DescriptorData", json_object_new_string((char*)wtpdescriptor_desc->data)); json_object_array_add(jsonarray, jsondesc); } json_object_object_add(jsonhash, "DescriptorSubElement", jsonarray); json_object_object_add(jsonparam, "WTPDescriptor", jsonhash); /* WTPName */ wtpname = (struct capwap_wtpname_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPNAME); jsonhash = json_object_new_object(); json_object_object_add(jsonhash, "Name", json_object_new_string((char*)wtpname->name)); json_object_object_add(jsonparam, "WTPName", jsonhash); /* WTPFrameTunnelMode */ wtpframetunnelmode = (struct capwap_wtpframetunnelmode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPFRAMETUNNELMODE); jsonhash = json_object_new_object(); json_object_object_add(jsonhash, "NativeFrameTunnel", json_object_new_boolean(((wtpframetunnelmode->mode & CAPWAP_WTP_NATIVE_FRAME_TUNNEL) ? 1 : 0))); json_object_object_add(jsonhash, "FrameTunnelMode8023", json_object_new_boolean(((wtpframetunnelmode->mode & CAPWAP_WTP_8023_FRAME_TUNNEL) ? 1 : 0))); json_object_object_add(jsonhash, "LocalBridge", json_object_new_boolean(((wtpframetunnelmode->mode & CAPWAP_WTP_LOCAL_BRIDGING) ? 1 : 0))); json_object_object_add(jsonparam, "WTPFrameTunnelMode", jsonhash); /* WTPMACType */ wtpmactype = (struct capwap_wtpmactype_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPMACTYPE); jsonhash = json_object_new_object(); json_object_object_add(jsonhash, "Type", json_object_new_int((int)wtpmactype->type)); json_object_object_add(jsonparam, "WTPMACType", jsonhash); /* Binding message */ if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) { struct ac_json_ieee80211_wtpradio wtpradio; struct capwap_list_item* search = packet->messages->first; /* Reording message by radioid and management */ ac_json_ieee80211_init(&wtpradio); while (search) { struct capwap_message_element_itemlist* messageelement = (struct capwap_message_element_itemlist*)search->item; /* Parsing only IEEE 802.11 message element */ if (IS_80211_MESSAGE_ELEMENTS(messageelement->type)) { if (!ac_json_ieee80211_parsingmessageelement(&wtpradio, messageelement)) { json_object_put(jsonparam); return NULL; } } /* Next */ search = search->next; } /* Generate JSON tree */ jsonarray = ac_json_ieee80211_getjson(&wtpradio); json_object_object_add(jsonparam, IEEE80211_BINDING_JSON_ROOT, jsonarray); /* Free resource */ ac_json_ieee80211_free(&wtpradio); } /* ECNSupport */ ecnsupport = (struct capwap_ecnsupport_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_ECNSUPPORT); jsonhash = json_object_new_object(); json_object_object_add(jsonhash, "Mode", json_object_new_int((int)ecnsupport->flag)); json_object_object_add(jsonparam, "ECNSupport", jsonhash); /* CAPWAPLocalIPv4Address */ localipv4 = (struct capwap_localipv4_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_LOCALIPV4); if (localipv4) { char ipbuffer[INET_ADDRSTRLEN]; jsonhash = json_object_new_object(); json_object_object_add(jsonhash, "Address", json_object_new_string(inet_ntop(AF_INET, (void*)&localipv4->address, ipbuffer, INET_ADDRSTRLEN))); json_object_object_add(jsonparam, "CAPWAPLocalIPv4Address", jsonhash); } /* CAPWAPLocalIPv6Address */ localipv6 = (struct capwap_localipv6_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_LOCALIPV6); if (localipv6) { char ipbuffer[INET6_ADDRSTRLEN]; jsonhash = json_object_new_object(); json_object_object_add(jsonhash, "Address", json_object_new_string(inet_ntop(AF_INET6, (void*)&localipv6->address, ipbuffer, INET6_ADDRSTRLEN))); json_object_object_add(jsonparam, "CAPWAPLocalIPv6Address", jsonhash); } /* WTPRebootStatistics */ wtprebootstat = (struct capwap_wtprebootstat_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPREBOOTSTAT); if (wtprebootstat) { jsonhash = json_object_new_object(); json_object_object_add(jsonhash, "RebootCount", json_object_new_int((int)wtprebootstat->rebootcount)); json_object_object_add(jsonhash, "ACInitiatedCount", json_object_new_int((int)wtprebootstat->acinitiatedcount)); json_object_object_add(jsonhash, "LinkFailureCount", json_object_new_int((int)wtprebootstat->linkfailurecount)); json_object_object_add(jsonhash, "SWFailureCount", json_object_new_int((int)wtprebootstat->swfailurecount)); json_object_object_add(jsonhash, "HWFailureCount", json_object_new_int((int)wtprebootstat->hwfailurecount)); json_object_object_add(jsonhash, "OtherFailureCount", json_object_new_int((int)wtprebootstat->otherfailurecount)); json_object_object_add(jsonhash, "UnknownFailureCount", json_object_new_int((int)wtprebootstat->unknownfailurecount)); json_object_object_add(jsonhash, "LastFailureType", json_object_new_int((int)wtprebootstat->lastfailuretype)); json_object_object_add(jsonparam, "WTPRebootStatistics", jsonhash); } /* Get JSON param and convert base64 */ jsonmessage = json_object_to_json_string(jsonparam); base64confstatus = capwap_alloc(AC_BASE64_ENCODE_LENGTH(strlen(jsonmessage))); ac_base64_string_encode(jsonmessage, base64confstatus); /* Send message */ response = ac_soap_joinwtpsession(session, session->wtpid, base64confstatus); /* Free JSON */ json_object_put(jsonparam); capwap_free(base64confstatus); return response; }
static struct ac_http_soap_server* ac_backend_get_server(void) { return *(struct ac_http_soap_server**)capwap_array_get_item_pointer(g_ac.availablebackends, g_ac_backend.activebackend); }
static void wtp_radio_setconfiguration_80211(struct capwap_parsed_packet *packet, struct capwap_array *updateitems) { int i; struct wtp_radio* radio; struct capwap_list_item* search; /* Set radio configuration and invalidate the old values */ for (search = packet->messages->first; search != NULL; search = search->next) { struct capwap_message_element_itemlist *messageelement = (struct capwap_message_element_itemlist *)search->item; struct capwap_array *messageelements = (struct capwap_array *)messageelement->data; /* Parsing only IEEE 802.11 message element */ if (!IS_80211_MESSAGE_ELEMENTS(messageelement->id) && memcmp(&messageelement->id, &CAPWAP_ELEMENT_80211N_RADIO_CONF, sizeof(messageelement->id)) != 0) continue; ASSERT(messageelements != NULL); ASSERT(messageelements->count > 0); switch (messageelement->id.type) { case CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_directsequencecontrol_element *directsequencecontrol = *(struct capwap_80211_directsequencecontrol_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(directsequencecontrol->radioid); if (!radio) continue; memset(&radio->directsequencecontrol, 0, sizeof(struct capwap_80211_directsequencecontrol_element)); memset(&radio->ofdmcontrol, 0, sizeof(struct capwap_80211_ofdmcontrol_element)); } break; case CAPWAP_ELEMENT_80211_OFDMCONTROL_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_ofdmcontrol_element* ofdmcontrol = *(struct capwap_80211_ofdmcontrol_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(ofdmcontrol->radioid); if (!radio) continue; memset(&radio->directsequencecontrol, 0, sizeof(struct capwap_80211_directsequencecontrol_element)); memset(&radio->ofdmcontrol, 0, sizeof(struct capwap_80211_ofdmcontrol_element)); } break; case CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_wtpradioinformation_element* radioinformation = *(struct capwap_80211_wtpradioinformation_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(radioinformation->radioid); if (!radio) continue; memcpy(&radio->radioinformation, radioinformation, sizeof(struct capwap_80211_wtpradioinformation_element)); } break; } } /* Update new values */ for (search = packet->messages->first; search != NULL; search = search->next) { struct capwap_message_element_itemlist* messageelement = (struct capwap_message_element_itemlist*)search->item; struct capwap_array *messageelements = (struct capwap_array *)messageelement->data; /* Parsing only IEEE 802.11 message element */ if (!IS_80211_MESSAGE_ELEMENTS(messageelement->id) && memcmp(&messageelement->id, &CAPWAP_ELEMENT_80211N_RADIO_CONF, sizeof(messageelement->id)) != 0) continue; ASSERT(messageelements != NULL); ASSERT(messageelements->count > 0); switch (messageelement->id.type) { case CAPWAP_ELEMENT_80211_ANTENNA_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_antenna_element *antenna = *(struct capwap_80211_antenna_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(antenna->radioid); if (!radio) continue; capwap_element_80211_antenna_copy(&radio->antenna, antenna); } break; case CAPWAP_ELEMENT_80211_MACOPERATION_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_macoperation_element *macoperation = *(struct capwap_80211_macoperation_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(macoperation->radioid); if (!radio) continue; memcpy(&radio->macoperation, macoperation, sizeof(struct capwap_80211_macoperation_element)); } break; case CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_multidomaincapability_element *multidomaincapability = *(struct capwap_80211_multidomaincapability_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(multidomaincapability->radioid); if (!radio) continue; memcpy(&radio->multidomaincapability, multidomaincapability, sizeof(struct capwap_80211_multidomaincapability_element)); } break; case CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_directsequencecontrol_element *directsequencecontrol = *(struct capwap_80211_directsequencecontrol_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(directsequencecontrol->radioid); if (!radio) continue; if (radio->radioinformation.radiotype & (CAPWAP_RADIO_TYPE_80211B | CAPWAP_RADIO_TYPE_80211G)) { memcpy(&radio->directsequencecontrol, directsequencecontrol, sizeof(struct capwap_80211_directsequencecontrol_element)); /* Pending change radio channel */ push_wtp_update_configuration_item(updateitems, WTP_UPDATE_FREQUENCY_DSSS, radio); } } break; case CAPWAP_ELEMENT_80211_OFDMCONTROL_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_ofdmcontrol_element *ofdmcontrol = *(struct capwap_80211_ofdmcontrol_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(ofdmcontrol->radioid); if (!radio) continue; if (radio->radioinformation.radiotype & CAPWAP_RADIO_TYPE_80211A) { memcpy(&radio->ofdmcontrol, ofdmcontrol, sizeof(struct capwap_80211_ofdmcontrol_element)); /* Pending change radio channel */ push_wtp_update_configuration_item(updateitems, WTP_UPDATE_FREQUENCY_OFDM, radio); } } break; case CAPWAP_ELEMENT_80211_RATESET_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_rateset_element *rateset = *(struct capwap_80211_rateset_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(rateset->radioid); if (!radio) continue; memcpy(&radio->rateset, rateset, sizeof(struct capwap_80211_rateset_element)); /* Pending change radio rates */ push_wtp_update_configuration_item(updateitems, WTP_UPDATE_RATES, radio); } break; case CAPWAP_ELEMENT_80211_SUPPORTEDRATES_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_supportedrates_element *supportedrates = *(struct capwap_80211_supportedrates_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(supportedrates->radioid); if (!radio) continue; memcpy(&radio->supportedrates, supportedrates, sizeof(struct capwap_80211_supportedrates_element)); } break; case CAPWAP_ELEMENT_80211_TXPOWER_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_txpower_element *txpower = *(struct capwap_80211_txpower_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(txpower->radioid); if (!radio) continue; memcpy(&radio->txpower, txpower, sizeof(struct capwap_80211_txpower_element)); } break; case CAPWAP_ELEMENT_80211_WTP_QOS_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_wtpqos_element* qos = *(struct capwap_80211_wtpqos_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(qos->radioid); if (!radio) continue; memcpy(&radio->qos, qos, sizeof(struct capwap_80211_wtpqos_element)); /* Pending change radio channel */ push_wtp_update_configuration_item(updateitems, WTP_UPDATE_TX_QUEUE, radio); } break; case CAPWAP_ELEMENT_80211_WTP_RADIO_CONF_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211_wtpradioconf_element* radioconfig = *(struct capwap_80211_wtpradioconf_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(radioconfig->radioid); if (!radio) continue; memcpy(&radio->radioconfig, radioconfig, sizeof(struct capwap_80211_wtpradioconf_element)); /* Pending change radio configuration */ push_wtp_update_configuration_item(updateitems, WTP_UPDATE_CONFIGURATION, radio); } break; case CAPWAP_ELEMENT_80211N_RADIO_CONF_TYPE: for (i = 0; i < messageelements->count; i++) { struct capwap_80211n_radioconf_element* radioconfig = *(struct capwap_80211n_radioconf_element**)capwap_array_get_item_pointer(messageelements, i); radio = wtp_radio_get_phy(radioconfig->radioid); if (!radio) continue; memcpy(&radio->radioconfig, radioconfig, sizeof(struct capwap_80211n_radioconf_element)); /* Pending change radio configuration */ #if 0 /* TODO: handle 802.11n config */ push_wtp_update_configuration_item(updateitems, WTP_UPDATE_80211N_CONFIG, radio); #endif } break; } } }
static void capwap_acdescriptor_element_free(void* data) { int i; struct capwap_acdescriptor_element* element = (struct capwap_acdescriptor_element*)data; ASSERT(element != NULL); ASSERT(element->descsubelement != NULL); /* */ for (i = 0; i < element->descsubelement->count; i++) { struct capwap_acdescriptor_desc_subelement* desc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(element->descsubelement, i); if (desc->data) { capwap_free(desc->data); } } capwap_array_free(element->descsubelement); capwap_free(data); }
int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet) { int i; int result = 0; struct capwap_array* updateitems; ASSERT(packet != NULL); /* */ updateitems = capwap_array_create(sizeof(struct wtp_update_configuration_item), 0, 1); /* */ switch (GET_WBID_HEADER(packet->rxmngpacket->header)) { case CAPWAP_WIRELESS_BINDING_IEEE80211: wtp_radio_setconfiguration_80211(packet, updateitems); break; } log_printf(LOG_DEBUG, "wtp_radio_setconfiguration result #1: %d", result); /* Update radio frequency */ for (i = 0; (i < updateitems->count) && !result; i++) { struct wtp_update_configuration_item* item = (struct wtp_update_configuration_item*)capwap_array_get_item_pointer(updateitems, i); switch (item->type) { case WTP_UPDATE_FREQUENCY_DSSS: result = wifi_device_setfrequency(item->radio->devicehandle, WIFI_BAND_2GHZ, item->radio->radioinformation.radiotype, item->radio->directsequencecontrol.currentchannel); break; case WTP_UPDATE_FREQUENCY_OFDM: result = wifi_device_setfrequency(item->radio->devicehandle, WIFI_BAND_5GHZ, item->radio->radioinformation.radiotype, item->radio->ofdmcontrol.currentchannel); break; } } log_printf(LOG_DEBUG, "wtp_radio_setconfiguration result #2: %d", result); /* Update radio configuration */ for (i = 0; (i < updateitems->count) && !result; i++) { struct wtp_update_configuration_item* item = (struct wtp_update_configuration_item*)capwap_array_get_item_pointer(updateitems, i); switch (item->type) { case WTP_UPDATE_RATES: result = wifi_device_updaterates(item->radio->devicehandle, item->radio->rateset.rateset, item->radio->rateset.ratesetcount); break; case WTP_UPDATE_CONFIGURATION: { struct device_setconfiguration_params params; memset(¶ms, 0, sizeof(struct device_setconfiguration_params)); params.shortpreamble = ((item->radio->radioconfig.shortpreamble == CAPWAP_WTP_RADIO_CONF_SHORTPREAMBLE_ENABLE) ? 1 : 0); params.maxbssid = item->radio->radioconfig.maxbssid; params.dtimperiod = item->radio->radioconfig.dtimperiod; memcpy(params.bssid, item->radio->radioconfig.bssid, ETH_ALEN); params.beaconperiod = item->radio->radioconfig.beaconperiod; memcpy(params.country, item->radio->radioconfig.country, WIFI_COUNTRY_LENGTH); result = wifi_device_setconfiguration(item->radio->devicehandle, ¶ms); break; } case WTP_UPDATE_TX_QUEUE: result = wifi_device_settxqueue(item->radio->devicehandle, &item->radio->qos); break; } } log_printf(LOG_DEBUG, "wtp_radio_setconfiguration result #3: %d", result); /* */ capwap_array_free(updateitems); return result; }
static void* capwap_acdescriptor_element_clone(void* data) { int i; struct capwap_acdescriptor_element* cloneelement; struct capwap_acdescriptor_element* element = (struct capwap_acdescriptor_element*)data; ASSERT(data != NULL); cloneelement = capwap_clone(data, sizeof(struct capwap_acdescriptor_element)); cloneelement->descsubelement = capwap_array_create(sizeof(struct capwap_acdescriptor_desc_subelement), 0, 1); for (i = 0; i < element->descsubelement->count; i++) { struct capwap_acdescriptor_desc_subelement* desc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(element->descsubelement, i); struct capwap_acdescriptor_desc_subelement* clonedesc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(cloneelement->descsubelement, i); memcpy(clonedesc, desc, sizeof(struct capwap_acdescriptor_desc_subelement)); if (desc->length) { clonedesc->data = capwap_clone(desc->data, desc->length); } } return cloneelement; }
static void capwap_acdescriptor_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { int i; struct capwap_acdescriptor_element* element = (struct capwap_acdescriptor_element*)data; ASSERT(data != NULL); ASSERT(!(element->security & ~CAPWAP_ACDESC_SECURITY_MASK)); ASSERT(!(element->dtlspolicy & ~CAPWAP_ACDESC_DTLS_POLICY_MASK)); ASSERT((element->rmacfield == CAPWAP_ACDESC_RMACFIELD_SUPPORTED) || (element->rmacfield == CAPWAP_ACDESC_RMACFIELD_NOTSUPPORTED)); ASSERT(element->descsubelement != NULL); /* */ func->write_u16(handle, element->stations); func->write_u16(handle, element->stationlimit); func->write_u16(handle, element->activewtp); func->write_u16(handle, element->maxwtp); func->write_u8(handle, element->security); func->write_u8(handle, element->rmacfield); func->write_u8(handle, 0); func->write_u8(handle, element->dtlspolicy); /* */ for (i = 0; i < element->descsubelement->count; i++) { struct capwap_acdescriptor_desc_subelement* desc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(element->descsubelement, i); ASSERT(desc->length > 0); ASSERT(desc->data != NULL); func->write_u32(handle, desc->vendor); func->write_u16(handle, desc->type); func->write_u16(handle, desc->length); func->write_block(handle, desc->data, desc->length); } }
static void* capwap_acdescriptor_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { struct capwap_acdescriptor_element* data; ASSERT(handle != NULL); ASSERT(func != NULL); if (func->read_ready(handle) < 12) { log_printf(LOG_DEBUG, "Invalid AC Descriptor element: underbuffer"); return NULL; } /* */ data = (struct capwap_acdescriptor_element*)capwap_alloc(sizeof(struct capwap_acdescriptor_element)); memset(data, 0, sizeof(struct capwap_acdescriptor_element)); data->descsubelement = capwap_array_create(sizeof(struct capwap_acdescriptor_desc_subelement), 0, 1); /* Retrieve data */ func->read_u16(handle, &data->stations); func->read_u16(handle, &data->stationlimit); func->read_u16(handle, &data->activewtp); func->read_u16(handle, &data->maxwtp); /* Check */ if (data->stations > data->stationlimit) { log_printf(LOG_DEBUG, "Invalid AC Descriptor element: stations > stationlimit"); capwap_acdescriptor_element_free(data); return NULL; } else if (data->activewtp > data->maxwtp) { log_printf(LOG_DEBUG, "Invalid AC Descriptor element: activewtp > maxwtp"); capwap_acdescriptor_element_free(data); return NULL; } /* */ func->read_u8(handle, &data->security); func->read_u8(handle, &data->rmacfield); func->read_u8(handle, NULL); func->read_u8(handle, &data->dtlspolicy); /* */ if (data->security & ~CAPWAP_ACDESC_SECURITY_MASK) { log_printf(LOG_DEBUG, "Invalid AC Descriptor element: security"); capwap_acdescriptor_element_free(data); return NULL; } else if (data->dtlspolicy & ~CAPWAP_ACDESC_DTLS_POLICY_MASK) { log_printf(LOG_DEBUG, "Invalid AC Descriptor element: dtlspolicy"); capwap_acdescriptor_element_free(data); return NULL; } else if ((data->rmacfield != CAPWAP_ACDESC_RMACFIELD_SUPPORTED) && (data->rmacfield != CAPWAP_ACDESC_RMACFIELD_NOTSUPPORTED)) { log_printf(LOG_DEBUG, "Invalid AC Descriptor element: rmacfield"); capwap_acdescriptor_element_free(data); return NULL; } /* Description Subelement */ while (func->read_ready(handle) > 0) { unsigned short length; struct capwap_acdescriptor_desc_subelement* desc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(data->descsubelement, data->descsubelement->count); /* */ func->read_u32(handle, &desc->vendor); func->read_u16(handle, &desc->type); func->read_u16(handle, &desc->length); if ((desc->type != CAPWAP_ACDESC_SUBELEMENT_HARDWAREVERSION) && (desc->type != CAPWAP_ACDESC_SUBELEMENT_SOFTWAREVERSION)) { log_printf(LOG_DEBUG, "Invalid AC Descriptor subelement: type"); capwap_acdescriptor_element_free(data); return NULL; } /* Check buffer size */ length = func->read_ready(handle); if ((length > CAPWAP_ACDESC_SUBELEMENT_MAXDATA) || (length < desc->length)) { log_printf(LOG_DEBUG, "Invalid AC Descriptor subelement: length"); capwap_acdescriptor_element_free(data); return NULL; } desc->data = (uint8_t*)capwap_alloc(desc->length + 1); func->read_block(handle, desc->data, desc->length); desc->data[desc->length] = 0; } return data; }
static struct capwap_packet_txmng* ac_create_discovery_response(struct capwap_parsed_packet* packet) { int i; unsigned short binding; struct capwap_list* controllist; struct capwap_list_item* item; struct capwap_header_data capwapheader; struct capwap_packet_txmng* txmngpacket; /* Check is valid binding */ binding = GET_WBID_HEADER(packet->rxmngpacket->header); if (!ac_valid_binding(binding)) { return NULL; } /* Update statistics */ ac_update_statistics(); /* Build packet */ capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, binding); txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_DISCOVERY_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, g_ac.mtu); /* Prepare discovery response */ capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACDESCRIPTION, &g_ac.descriptor); capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACNAME, &g_ac.acname); if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) { struct capwap_array* wtpradioinformation = (struct capwap_array*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION); for (i = 0; i < wtpradioinformation->count; i++) { struct capwap_80211_wtpradioinformation_element* radio; radio = *(struct capwap_80211_wtpradioinformation_element**)capwap_array_get_item_pointer(wtpradioinformation, i); capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, radio); } } /* Get information from any local address */ controllist = capwap_list_create(); ac_get_control_information(controllist); for (item = controllist->first; item != NULL; item = item->next) { struct ac_session_control* sessioncontrol = (struct ac_session_control*)item->item; if (sessioncontrol->localaddress.ss.ss_family == AF_INET) { struct capwap_controlipv4_element element; memcpy(&element.address, &((struct sockaddr_in*)&sessioncontrol->localaddress)->sin_addr, sizeof(struct in_addr)); element.wtpcount = sessioncontrol->count; capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV4, &element); } else if (sessioncontrol->localaddress.ss.ss_family == AF_INET6) { struct capwap_controlipv6_element element; memcpy(&element.address, &((struct sockaddr_in6*)&sessioncontrol->localaddress)->sin6_addr, sizeof(struct in6_addr)); element.wtpcount = sessioncontrol->count; capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV6, &element); } } capwap_list_free(controllist); /* CAPWAP_ELEMENT_VENDORPAYLOAD */ /* TODO */ return txmngpacket; }
static void capwap_wtpboarddata_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { int i; struct capwap_wtpboarddata_element* element = (struct capwap_wtpboarddata_element*)data; ASSERT(data != NULL); ASSERT(element->vendor != 0); ASSERT(element->boardsubelement->count > 0); /* */ func->write_u32(handle, element->vendor); /* */ for (i = 0; i < element->boardsubelement->count; i++) { struct capwap_wtpboarddata_board_subelement* desc = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(element->boardsubelement, i); ASSERT((desc->type >= CAPWAP_BOARD_SUBELEMENT_TYPE_FIRST) && (desc->type <= CAPWAP_BOARD_SUBELEMENT_TYPE_LAST)); ASSERT((desc->length > 0) && (desc->length <= CAPWAP_BOARD_SUBELEMENT_MAXDATA)); func->write_u16(handle, desc->type); func->write_u16(handle, desc->length); func->write_block(handle, desc->data, desc->length); } }