Esempio n. 1
0
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;
	}
}
Esempio n. 2
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);
}
Esempio n. 3
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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));
	}
}
Esempio n. 7
0
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));
	}
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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;
	}
}
Esempio n. 16
0
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;
}
Esempio n. 18
0
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;
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
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);
}
Esempio n. 23
0
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;
		}
	}
}
Esempio n. 24
0
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);
}
Esempio n. 25
0
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(&params, 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, &params);
			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;
}
Esempio n. 26
0
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;
}
Esempio n. 27
0
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);
	}
}
Esempio n. 28
0
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;
}
Esempio n. 29
0
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);
	}
}