Improve memory administration for tx/rx packet manager
This commit is contained in:
		
							
								
								
									
										18
									
								
								src/ac/ac.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/ac/ac.c
									
									
									
									
									
								
							@ -22,11 +22,11 @@ static int ac_init(void) {
 | 
				
			|||||||
	g_ac.binding = capwap_array_create(sizeof(unsigned short), 0);
 | 
						g_ac.binding = capwap_array_create(sizeof(unsigned short), 0);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/* Standard name */
 | 
						/* Standard name */
 | 
				
			||||||
	strcpy(g_ac.acname.name, AC_STANDARD_NAME);
 | 
						strcpy((char*)g_ac.acname.name, AC_STANDARD_NAME);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/* Descriptor */
 | 
						/* Descriptor */
 | 
				
			||||||
	g_ac.descriptor.stationlimit = AC_DEFAULT_MAXSTATION;
 | 
						g_ac.descriptor.stationlimit = AC_DEFAULT_MAXSTATION;
 | 
				
			||||||
	g_ac.descriptor.wtplimit = AC_DEFAULT_MAXSESSIONS;
 | 
						g_ac.descriptor.maxwtp = AC_DEFAULT_MAXSESSIONS;
 | 
				
			||||||
	g_ac.descriptor.security = 0;
 | 
						g_ac.descriptor.security = 0;
 | 
				
			||||||
	g_ac.descriptor.rmacfield = CAPWAP_ACDESC_RMACFIELD_NOTSUPPORTED;
 | 
						g_ac.descriptor.rmacfield = CAPWAP_ACDESC_RMACFIELD_NOTSUPPORTED;
 | 
				
			||||||
	g_ac.descriptor.dtlspolicy = CAPWAP_ACDESC_CLEAR_DATA_CHANNEL_ENABLED;
 | 
						g_ac.descriptor.dtlspolicy = CAPWAP_ACDESC_CLEAR_DATA_CHANNEL_ENABLED;
 | 
				
			||||||
@ -44,8 +44,8 @@ static int ac_init(void) {
 | 
				
			|||||||
	g_ac.dfa.wtpfallback.mode = AC_DEFAULT_WTP_FALLBACK_MODE;
 | 
						g_ac.dfa.wtpfallback.mode = AC_DEFAULT_WTP_FALLBACK_MODE;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	g_ac.dfa.acipv4list = capwap_array_create(sizeof(struct capwap_acipv4list_element), 0);
 | 
						g_ac.dfa.acipv4list.addresses = capwap_array_create(sizeof(struct in_addr), 0);
 | 
				
			||||||
	g_ac.dfa.acipv6list = capwap_array_create(sizeof(struct capwap_acipv6list_element), 0);
 | 
						g_ac.dfa.acipv6list.addresses = capwap_array_create(sizeof(struct in6_addr), 0);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	g_ac.dfa.rfcWaitJoin = AC_DEFAULT_WAITJOIN_INTERVAL;
 | 
						g_ac.dfa.rfcWaitJoin = AC_DEFAULT_WAITJOIN_INTERVAL;
 | 
				
			||||||
@ -72,8 +72,8 @@ static void ac_destroy(void) {
 | 
				
			|||||||
	capwap_array_free(g_ac.binding);
 | 
						capwap_array_free(g_ac.binding);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	capwap_array_free(g_ac.dfa.acipv4list);
 | 
						capwap_array_free(g_ac.dfa.acipv4list.addresses);
 | 
				
			||||||
	capwap_array_free(g_ac.dfa.acipv6list);
 | 
						capwap_array_free(g_ac.dfa.acipv6list.addresses);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/* Sessions */
 | 
						/* Sessions */
 | 
				
			||||||
	capwap_list_free(g_ac.sessions);
 | 
						capwap_list_free(g_ac.sessions);
 | 
				
			||||||
@ -152,7 +152,7 @@ static int ac_parsing_configuration_1_0(config_t* config) {
 | 
				
			|||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		strcpy(g_ac.acname.name, configString);
 | 
							strcpy((char*)g_ac.acname.name, configString);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set binding of AC */
 | 
						/* Set binding of AC */
 | 
				
			||||||
@ -190,7 +190,7 @@ static int ac_parsing_configuration_1_0(config_t* config) {
 | 
				
			|||||||
	/* Set max wtp of AC */
 | 
						/* Set max wtp of AC */
 | 
				
			||||||
	if (config_lookup_int(config, "application.descriptor.maxwtp", &configLongInt) == CONFIG_TRUE) {
 | 
						if (config_lookup_int(config, "application.descriptor.maxwtp", &configLongInt) == CONFIG_TRUE) {
 | 
				
			||||||
		if ((configLongInt > 0) && (configLongInt < 65536)) {
 | 
							if ((configLongInt > 0) && (configLongInt < 65536)) {
 | 
				
			||||||
			g_ac.descriptor.wtplimit = (unsigned short)configLongInt;
 | 
								g_ac.descriptor.maxwtp = (unsigned short)configLongInt;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			capwap_logging_error("Invalid configuration file, unknown application.descriptor.maxwtp value");
 | 
								capwap_logging_error("Invalid configuration file, unknown application.descriptor.maxwtp value");
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
@ -266,7 +266,7 @@ static int ac_parsing_configuration_1_0(config_t* config) {
 | 
				
			|||||||
								desc->vendor = (unsigned long)configVendor;
 | 
													desc->vendor = (unsigned long)configVendor;
 | 
				
			||||||
								desc->type = type;
 | 
													desc->type = type;
 | 
				
			||||||
								desc->length = lengthValue;
 | 
													desc->length = lengthValue;
 | 
				
			||||||
								strcpy(desc->data, configValue);
 | 
													strcpy((char*)desc->data, configValue);
 | 
				
			||||||
							} else {
 | 
												} else {
 | 
				
			||||||
								capwap_logging_error("Invalid configuration file, application.descriptor.info.value string length exceeded");
 | 
													capwap_logging_error("Invalid configuration file, application.descriptor.info.value string length exceeded");
 | 
				
			||||||
								return 0;
 | 
													return 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -55,8 +55,8 @@ struct ac_state {
 | 
				
			|||||||
	struct capwap_wtpfallback_element wtpfallback;
 | 
						struct capwap_wtpfallback_element wtpfallback;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	capwap_acipv4list_element_array* acipv4list;
 | 
						struct capwap_acipv4list_element acipv4list;
 | 
				
			||||||
	capwap_acipv6list_element_array* acipv6list;
 | 
						struct capwap_acipv6list_element acipv6list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	int rfcWaitJoin;
 | 
						int rfcWaitJoin;
 | 
				
			||||||
 | 
				
			|||||||
@ -4,115 +4,73 @@
 | 
				
			|||||||
#include "ac_session.h"
 | 
					#include "ac_session.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_configure(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_configure(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	unsigned long i;
 | 
						unsigned long i;
 | 
				
			||||||
 | 
						unsigned short binding;
 | 
				
			||||||
 | 
						struct capwap_header_data capwapheader;
 | 
				
			||||||
 | 
						struct capwap_packet_txmng* txmngpacket;
 | 
				
			||||||
	int status = AC_DFA_ACCEPT_PACKET;
 | 
						int status = AC_DFA_ACCEPT_PACKET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if (packet) {
 | 
						if (packet) {
 | 
				
			||||||
		struct capwap_build_packet* buildpacket;
 | 
							binding = GET_WBID_HEADER(packet->rxmngpacket->header);
 | 
				
			||||||
	
 | 
							/* TODO: gestione richiesta */
 | 
				
			||||||
		buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
 | 
					 | 
				
			||||||
		if (buildpacket) {
 | 
					 | 
				
			||||||
			if (!capwap_build_packet_validate(buildpacket, NULL)) {
 | 
					 | 
				
			||||||
				unsigned short binding;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/* */
 | 
							/* Create response */
 | 
				
			||||||
				binding = GET_WBID_HEADER(&buildpacket->header);
 | 
							capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, binding);
 | 
				
			||||||
				if (ac_valid_binding(binding) && (ntohl(buildpacket->ctrlmsg.type) == CAPWAP_CONFIGURATION_STATUS_REQUEST) && IS_SEQUENCE_SMALLER(session->remoteseqnumber, buildpacket->ctrlmsg.seq)) {
 | 
							txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_CONFIGURATION_STATUS_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, session->mtu);
 | 
				
			||||||
					struct capwap_element_configurationstatus_request configurationstatusrequest;
 | 
					 | 
				
			||||||
					
 | 
					 | 
				
			||||||
					/* Configuration Status request info*/
 | 
					 | 
				
			||||||
					capwap_init_element_configurationstatus_request(&configurationstatusrequest, binding);
 | 
					 | 
				
			||||||
					
 | 
					 | 
				
			||||||
					/* Parsing elements list */
 | 
					 | 
				
			||||||
					if (capwap_parsing_element_configurationstatus_request(&configurationstatusrequest, buildpacket->elementslist->first)) {
 | 
					 | 
				
			||||||
						struct capwap_build_packet* responsepacket;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
						/* TODO: gestione richiesta */
 | 
							/* Add message element */
 | 
				
			||||||
 | 
							capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_TIMERS, &session->dfa.timers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						/* Create response */
 | 
							for (i = 0; i < packet->messageelements.radioadmstate->count; i++) {
 | 
				
			||||||
						responsepacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, binding);
 | 
								struct capwap_decrypterrorreportperiod_element report;
 | 
				
			||||||
						responsepacket->isctrlmsg = 1;
 | 
								struct capwap_radioadmstate_element* radioadm = *(struct capwap_radioadmstate_element**)capwap_array_get_item_pointer(packet->messageelements.radioadmstate, i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						/* Prepare configuration status response */
 | 
								report.radioid = radioadm->radioid;
 | 
				
			||||||
						capwap_build_packet_set_control_message_type(responsepacket, CAPWAP_CONFIGURATION_STATUS_RESPONSE, buildpacket->ctrlmsg.seq);
 | 
								report.interval = session->dfa.decrypterrorreport_interval;
 | 
				
			||||||
						capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_TIMERS_ELEMENT(&session->dfa.timers));
 | 
								capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD, &report);
 | 
				
			||||||
						
 | 
					 | 
				
			||||||
						for (i = 0; i < configurationstatusrequest.radioadmstatus->count; i++) {
 | 
					 | 
				
			||||||
							struct capwap_decrypterrorreportperiod_element report;
 | 
					 | 
				
			||||||
							struct capwap_radioadmstate_element* radioadm = (struct capwap_radioadmstate_element*)capwap_array_get_item_pointer(configurationstatusrequest.radioadmstatus, i);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							report.radioid = radioadm->radioid;
 | 
					 | 
				
			||||||
							report.interval = session->dfa.decrypterrorreport_interval;
 | 
					 | 
				
			||||||
							capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_DECRYPTERRORREPORTPERIOD_ELEMENT(&report));
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						
 | 
					 | 
				
			||||||
						capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_IDLETIMEOUT_ELEMENT(&session->dfa.idletimeout));
 | 
					 | 
				
			||||||
						capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_WTPFALLBACK_ELEMENT(&session->dfa.wtpfallback));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						if (session->dfa.acipv4list->count > 0) {
 | 
					 | 
				
			||||||
							capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ACIPV4LIST_ELEMENT(session->dfa.acipv4list));
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						if (session->dfa.acipv6list->count > 0) {
 | 
					 | 
				
			||||||
							capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ACIPV6LIST_ELEMENT(session->dfa.acipv6list));
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						
 | 
					 | 
				
			||||||
						/* CAPWAP_CREATE_RADIOOPRSTATE_ELEMENT */				/* TODO */
 | 
					 | 
				
			||||||
						/* CAPWAP_CREATE_WTPSTATICIPADDRESS_ELEMENT */			/* TODO */
 | 
					 | 
				
			||||||
						/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */		/* TODO */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						if (!capwap_build_packet_validate(responsepacket, NULL)) {
 | 
					 | 
				
			||||||
							int result;
 | 
					 | 
				
			||||||
							
 | 
					 | 
				
			||||||
							/* Free old reference for this request */
 | 
					 | 
				
			||||||
							ac_free_reference_last_response(session);
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
							/* Send configuration status response to WTP */
 | 
					 | 
				
			||||||
							result = capwap_fragment_build_packet(responsepacket, session->responsefragmentpacket, session->mtu, session->fragmentid);
 | 
					 | 
				
			||||||
							if (result >= 0) {
 | 
					 | 
				
			||||||
								if (result == 1) {
 | 
					 | 
				
			||||||
									session->fragmentid++;
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
								/* Save remote sequence number */
 | 
					 | 
				
			||||||
								session->remoteseqnumber = buildpacket->ctrlmsg.seq;
 | 
					 | 
				
			||||||
								capwap_get_packet_digest((void*)packet->header, packet->packetsize, session->lastrecvpackethash);
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
								/* Send */
 | 
					 | 
				
			||||||
								for (i = 0; i < session->responsefragmentpacket->count; i++) {
 | 
					 | 
				
			||||||
									struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(session->responsefragmentpacket, i);
 | 
					 | 
				
			||||||
									ASSERT(txpacket != NULL);
 | 
					 | 
				
			||||||
									
 | 
					 | 
				
			||||||
									if (!capwap_crypt_sendto(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], txpacket->header, txpacket->packetsize, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
					 | 
				
			||||||
										/* Response is already created and saved. When receive a re-request, DFA autoresponse */
 | 
					 | 
				
			||||||
										capwap_logging_debug("Warning: error to send configuration status response packet");
 | 
					 | 
				
			||||||
										break;
 | 
					 | 
				
			||||||
									}
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
								/* Change status */
 | 
					 | 
				
			||||||
								ac_dfa_change_state(session, CAPWAP_DATA_CHECK_STATE);
 | 
					 | 
				
			||||||
								capwap_set_timeout(session->dfa.rfcChangeStatePendingTimer, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						} else {
 | 
					 | 
				
			||||||
							capwap_logging_debug("Warning: build invalid configuration status response packet");
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						
 | 
					 | 
				
			||||||
						/* Free memory */
 | 
					 | 
				
			||||||
						capwap_build_packet_free(responsepacket);
 | 
					 | 
				
			||||||
					} 
 | 
					 | 
				
			||||||
					
 | 
					 | 
				
			||||||
					/* Free */
 | 
					 | 
				
			||||||
					capwap_free_element_configurationstatus_request(&configurationstatusrequest, binding);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/* Free */
 | 
					 | 
				
			||||||
			capwap_build_packet_free(buildpacket);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_IDLETIMEOUT, &session->dfa.idletimeout);
 | 
				
			||||||
 | 
							capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPFALLBACK, &session->dfa.wtpfallback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (session->dfa.acipv4list.addresses->count > 0) {
 | 
				
			||||||
 | 
								capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV4LIST, &session->dfa.acipv4list);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (session->dfa.acipv6list.addresses->count > 0) {
 | 
				
			||||||
 | 
								capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV6LIST, &session->dfa.acipv6list);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* CAPWAP_CREATE_RADIOOPRSTATE_ELEMENT */				/* TODO */
 | 
				
			||||||
 | 
							/* CAPWAP_CREATE_WTPSTATICIPADDRESS_ELEMENT */			/* TODO */
 | 
				
			||||||
 | 
							/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */		/* TODO */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Configure response complete, get fragment packets */
 | 
				
			||||||
 | 
							ac_free_reference_last_response(session);
 | 
				
			||||||
 | 
							capwap_packet_txmng_get_fragment_packets(txmngpacket, session->responsefragmentpacket, session->fragmentid);
 | 
				
			||||||
 | 
							if (session->responsefragmentpacket->count > 1) {
 | 
				
			||||||
 | 
								session->fragmentid++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Free packets manager */
 | 
				
			||||||
 | 
							capwap_packet_txmng_free(txmngpacket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Save remote sequence number */
 | 
				
			||||||
 | 
							session->remoteseqnumber = packet->rxmngpacket->ctrlmsg.seq;
 | 
				
			||||||
 | 
							capwap_get_packet_digest(packet->rxmngpacket, packet->connection, session->lastrecvpackethash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Send Configure response to WTP */
 | 
				
			||||||
 | 
							if (!capwap_crypt_sendto_fragmentpacket(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], session->responsefragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
				
			||||||
 | 
								/* Response is already created and saved. When receive a re-request, DFA autoresponse */
 | 
				
			||||||
 | 
								capwap_logging_debug("Warning: error to send configuration status response packet");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Change state */
 | 
				
			||||||
 | 
							ac_dfa_change_state(session, CAPWAP_DATA_CHECK_STATE);
 | 
				
			||||||
 | 
							capwap_set_timeout(session->dfa.rfcChangeStatePendingTimer, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* Configure timeout */
 | 
							/* Configure timeout */
 | 
				
			||||||
		ac_dfa_change_state(session, CAPWAP_CONFIGURE_TO_DTLS_TEARDOWN_STATE);
 | 
							ac_dfa_change_state(session, CAPWAP_CONFIGURE_TO_DTLS_TEARDOWN_STATE);
 | 
				
			||||||
@ -123,6 +81,6 @@ int ac_dfa_state_configure(struct ac_session_t* session, struct capwap_packet* p
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_configure_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_configure_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	return ac_session_teardown_connection(session);
 | 
						return ac_session_teardown_connection(session);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,91 +4,48 @@
 | 
				
			|||||||
#include "ac_session.h"
 | 
					#include "ac_session.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_datacheck(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_datacheck(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	unsigned long i;
 | 
						unsigned short binding;
 | 
				
			||||||
 | 
						struct capwap_header_data capwapheader;
 | 
				
			||||||
 | 
						struct capwap_packet_txmng* txmngpacket;
 | 
				
			||||||
	int status = AC_DFA_ACCEPT_PACKET;
 | 
						int status = AC_DFA_ACCEPT_PACKET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if (packet) {
 | 
						if (packet) {
 | 
				
			||||||
		struct capwap_build_packet* buildpacket;
 | 
							binding = GET_WBID_HEADER(packet->rxmngpacket->header);
 | 
				
			||||||
	
 | 
							/* TODO: gestione richiesta */
 | 
				
			||||||
		buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
 | 
					 | 
				
			||||||
		if (buildpacket) {
 | 
					 | 
				
			||||||
			if (!capwap_build_packet_validate(buildpacket, NULL)) {
 | 
					 | 
				
			||||||
				unsigned short binding;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/* */
 | 
							/* Create response */
 | 
				
			||||||
				binding = GET_WBID_HEADER(&buildpacket->header);
 | 
							capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, binding);
 | 
				
			||||||
				if (ac_valid_binding(binding) && (ntohl(buildpacket->ctrlmsg.type) == CAPWAP_CHANGE_STATE_EVENT_REQUEST) && IS_SEQUENCE_SMALLER(session->remoteseqnumber, buildpacket->ctrlmsg.seq)) {
 | 
							txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_CHANGE_STATE_EVENT_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, session->mtu);
 | 
				
			||||||
					struct capwap_element_changestateevent_request changeeventrequest;
 | 
					 | 
				
			||||||
					
 | 
					 | 
				
			||||||
					/* Change event request info */
 | 
					 | 
				
			||||||
					capwap_init_element_changestateevent_request(&changeeventrequest, binding);
 | 
					 | 
				
			||||||
					
 | 
					 | 
				
			||||||
					/* Parsing elements list */
 | 
					 | 
				
			||||||
					if (capwap_parsing_element_changestateevent_request(&changeeventrequest, buildpacket->elementslist->first)) {
 | 
					 | 
				
			||||||
						struct capwap_build_packet* responsepacket;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
						/* TODO: gestione richiesta */
 | 
							/* Add message element */
 | 
				
			||||||
 | 
							/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */		/* TODO */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						/* Create response */
 | 
							/* Change event response complete, get fragment packets */
 | 
				
			||||||
						responsepacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, binding);
 | 
							ac_free_reference_last_response(session);
 | 
				
			||||||
						responsepacket->isctrlmsg = 1;
 | 
							capwap_packet_txmng_get_fragment_packets(txmngpacket, session->responsefragmentpacket, session->fragmentid);
 | 
				
			||||||
 | 
							if (session->responsefragmentpacket->count > 1) {
 | 
				
			||||||
						/* Prepare change event response */
 | 
								session->fragmentid++;
 | 
				
			||||||
						capwap_build_packet_set_control_message_type(responsepacket, CAPWAP_CHANGE_STATE_EVENT_RESPONSE, buildpacket->ctrlmsg.seq);
 | 
					 | 
				
			||||||
						/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */		/* TODO */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						if (!capwap_build_packet_validate(responsepacket, NULL)) {
 | 
					 | 
				
			||||||
							int result;
 | 
					 | 
				
			||||||
							
 | 
					 | 
				
			||||||
							/* Free old reference for this request */
 | 
					 | 
				
			||||||
							ac_free_reference_last_response(session);
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
							/* Send change event response to WTP */
 | 
					 | 
				
			||||||
							result = capwap_fragment_build_packet(responsepacket, session->responsefragmentpacket, session->mtu, session->fragmentid);
 | 
					 | 
				
			||||||
							if (result >= 0) {
 | 
					 | 
				
			||||||
								if (result == 1) {
 | 
					 | 
				
			||||||
									session->fragmentid++;
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
								/* Save remote sequence number */
 | 
					 | 
				
			||||||
								session->remoteseqnumber = buildpacket->ctrlmsg.seq;
 | 
					 | 
				
			||||||
								capwap_get_packet_digest((void*)packet->header, packet->packetsize, session->lastrecvpackethash);
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
								/* Send */
 | 
					 | 
				
			||||||
								for (i = 0; i < session->responsefragmentpacket->count; i++) {
 | 
					 | 
				
			||||||
									struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(session->responsefragmentpacket, i);
 | 
					 | 
				
			||||||
									ASSERT(txpacket != NULL);
 | 
					 | 
				
			||||||
									
 | 
					 | 
				
			||||||
									if (!capwap_crypt_sendto(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], txpacket->header, txpacket->packetsize, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
					 | 
				
			||||||
										/* Response is already created and saved. When receive a re-request, DFA autoresponse */
 | 
					 | 
				
			||||||
										capwap_logging_debug("Warning: error to send change event response packet");
 | 
					 | 
				
			||||||
										break;
 | 
					 | 
				
			||||||
									}
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
								/* Change status */
 | 
					 | 
				
			||||||
								ac_dfa_change_state(session, CAPWAP_DATA_CHECK_TO_RUN_STATE);
 | 
					 | 
				
			||||||
								capwap_set_timeout(session->dfa.rfcDataCheckTimer, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						} else {
 | 
					 | 
				
			||||||
							capwap_logging_debug("Warning: build invalid configuration status response packet");
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						
 | 
					 | 
				
			||||||
						/* Free memory */
 | 
					 | 
				
			||||||
						capwap_build_packet_free(responsepacket);
 | 
					 | 
				
			||||||
					} 
 | 
					 | 
				
			||||||
					
 | 
					 | 
				
			||||||
					/* Free */
 | 
					 | 
				
			||||||
					capwap_free_element_changestateevent_request(&changeeventrequest, binding);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/* Free */
 | 
					 | 
				
			||||||
			capwap_build_packet_free(buildpacket);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Free packets manager */
 | 
				
			||||||
 | 
							capwap_packet_txmng_free(txmngpacket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Save remote sequence number */
 | 
				
			||||||
 | 
							session->remoteseqnumber = packet->rxmngpacket->ctrlmsg.seq;
 | 
				
			||||||
 | 
							capwap_get_packet_digest(packet->rxmngpacket, packet->connection, session->lastrecvpackethash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Send Change event response to WTP */
 | 
				
			||||||
 | 
							if (!capwap_crypt_sendto_fragmentpacket(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], session->responsefragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
				
			||||||
 | 
								/* Response is already created and saved. When receive a re-request, DFA autoresponse */
 | 
				
			||||||
 | 
								capwap_logging_debug("Warning: error to send change event response packet");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Change state */
 | 
				
			||||||
 | 
							ac_dfa_change_state(session, CAPWAP_DATA_CHECK_TO_RUN_STATE);
 | 
				
			||||||
 | 
							capwap_set_timeout(session->dfa.rfcDataCheckTimer, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* Configure timeout */
 | 
							/* Configure timeout */
 | 
				
			||||||
		ac_dfa_change_state(session, CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE);
 | 
							ac_dfa_change_state(session, CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE);
 | 
				
			||||||
@ -99,59 +56,54 @@ int ac_dfa_state_datacheck(struct ac_session_t* session, struct capwap_packet* p
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_datacheck_to_run(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_datacheck_to_run(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
 | 
						struct capwap_list* txfragpacket;
 | 
				
			||||||
 | 
						struct capwap_header_data capwapheader;
 | 
				
			||||||
 | 
						struct capwap_packet_txmng* txmngpacket;
 | 
				
			||||||
	int status = AC_DFA_ACCEPT_PACKET;
 | 
						int status = AC_DFA_ACCEPT_PACKET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if (packet) {
 | 
						if (packet) {
 | 
				
			||||||
		/* Wait Data Channel Keep-Alive packet */
 | 
							/* Wait Data Channel Keep-Alive packet */
 | 
				
			||||||
		if (!packet->socket.isctrlsocket) {
 | 
							if (!packet->rxmngpacket->isctrlpacket && IS_FLAG_K_HEADER(packet->rxmngpacket->header)) {
 | 
				
			||||||
			struct capwap_build_packet* buildpacket;
 | 
								if (!memcmp(packet->messageelements.sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
 | 
				
			||||||
		
 | 
									int result = 0;
 | 
				
			||||||
			buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
 | 
					
 | 
				
			||||||
			if (buildpacket) {
 | 
									/* Build packet */
 | 
				
			||||||
				struct capwap_sessionid_element sessionid;
 | 
									capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, GET_WBID_HEADER(packet->rxmngpacket->header));
 | 
				
			||||||
				
 | 
									capwap_header_set_keepalive_flag(&capwapheader, 1);
 | 
				
			||||||
				if (capwap_get_sessionid_from_keepalive(buildpacket, &sessionid)) {
 | 
									txmngpacket = capwap_packet_txmng_create_data_message(&capwapheader, session->mtu);
 | 
				
			||||||
					if (!memcmp(&sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
 | 
					
 | 
				
			||||||
						int result;
 | 
									/* Add message element */
 | 
				
			||||||
						capwap_fragment_packet_array* txfragpacket;
 | 
									capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_SESSIONID, &session->sessionid);
 | 
				
			||||||
						
 | 
					
 | 
				
			||||||
						/* Receive data packet keepalive, response with same packet */
 | 
									/* Data keepalive complete, get fragment packets into local list */
 | 
				
			||||||
						txfragpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
 | 
									txfragpacket = capwap_list_create();
 | 
				
			||||||
						result = capwap_fragment_build_packet(buildpacket, txfragpacket, CAPWAP_DONT_FRAGMENT, 0);
 | 
									capwap_packet_txmng_get_fragment_packets(txmngpacket, txfragpacket, 0);
 | 
				
			||||||
						if (!result) {
 | 
									if (txfragpacket->count == 1) {
 | 
				
			||||||
							struct capwap_packet* txpacket;
 | 
										/* Send Data keepalive to WTP */
 | 
				
			||||||
							
 | 
										if (capwap_crypt_sendto_fragmentpacket(&session->datadtls, session->datasocket.socket[session->datasocket.type], txfragpacket, &session->acdataaddress, &session->wtpdataaddress)) {
 | 
				
			||||||
							ASSERT(txfragpacket->count == 1);
 | 
											result = 1;
 | 
				
			||||||
							
 | 
										} else {
 | 
				
			||||||
							txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(txfragpacket, 0);
 | 
											capwap_logging_debug("Warning: error to send data channel keepalive packet");
 | 
				
			||||||
							ASSERT(txpacket != NULL);
 | 
					 | 
				
			||||||
							
 | 
					 | 
				
			||||||
							if (!capwap_crypt_sendto(&session->datadtls, session->datasocket.socket[session->datasocket.type], txpacket->header, txpacket->packetsize, &session->acdataaddress, &session->wtpdataaddress)) {
 | 
					 | 
				
			||||||
								capwap_logging_debug("Warning: error to send data channel keepalive packet");
 | 
					 | 
				
			||||||
								result = -1;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					
 | 
					 | 
				
			||||||
						/* */
 | 
					 | 
				
			||||||
						capwap_fragment_free(txfragpacket);
 | 
					 | 
				
			||||||
						capwap_array_free(txfragpacket);
 | 
					 | 
				
			||||||
						
 | 
					 | 
				
			||||||
						if (!result) {
 | 
					 | 
				
			||||||
							/* Capwap handshake complete */
 | 
					 | 
				
			||||||
							ac_dfa_change_state(session, CAPWAP_RUN_STATE);
 | 
					 | 
				
			||||||
							capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
					 | 
				
			||||||
						} else {
 | 
					 | 
				
			||||||
							ac_dfa_change_state(session, CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE);
 | 
					 | 
				
			||||||
							status = AC_DFA_NO_PACKET;
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										capwap_logging_debug("Warning: error to send data channel keepalive packet, fragment packet");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									/* Free packets manager */
 | 
				
			||||||
 | 
									capwap_list_free(txfragpacket);
 | 
				
			||||||
 | 
									capwap_packet_txmng_free(txmngpacket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (result) {
 | 
				
			||||||
 | 
										/* Capwap handshake complete */
 | 
				
			||||||
 | 
										ac_dfa_change_state(session, CAPWAP_RUN_STATE);
 | 
				
			||||||
 | 
										capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										ac_dfa_change_state(session, CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE);
 | 
				
			||||||
 | 
										status = AC_DFA_NO_PACKET;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				/* Free */
 | 
					 | 
				
			||||||
				capwap_build_packet_free(buildpacket);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
@ -164,6 +116,6 @@ int ac_dfa_state_datacheck_to_run(struct ac_session_t* session, struct capwap_pa
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_datacheck_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_datacheck_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	return ac_session_teardown_connection(session);
 | 
						return ac_session_teardown_connection(session);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,7 @@ int ac_bio_send(struct capwap_dtls* dtls, char* buffer, int length, void* param)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_dtlssetup(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_dtlssetup(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	int status = AC_DFA_ACCEPT_PACKET;
 | 
						int status = AC_DFA_ACCEPT_PACKET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
@ -37,7 +37,7 @@ int ac_dfa_state_dtlssetup(struct ac_session_t* session, struct capwap_packet* p
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_dtlsconnect(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_dtlsconnect(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
	ASSERT(packet == NULL);
 | 
						ASSERT(packet == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -46,6 +46,6 @@ int ac_dfa_state_dtlsconnect(struct ac_session_t* session, struct capwap_packet*
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_dtlsconnect_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_dtlsconnect_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	return ac_session_teardown_connection(session);
 | 
						return ac_session_teardown_connection(session);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@
 | 
				
			|||||||
#include "ac_session.h"
 | 
					#include "ac_session.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_imagedata(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_imagedata(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	int status = AC_DFA_ACCEPT_PACKET;
 | 
						int status = AC_DFA_ACCEPT_PACKET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* TODO */
 | 
						/* TODO */
 | 
				
			||||||
@ -13,6 +13,6 @@ int ac_dfa_state_imagedata(struct ac_session_t* session, struct capwap_packet* p
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_imagedata_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_imagedata_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	return ac_session_teardown_connection(session);
 | 
						return ac_session_teardown_connection(session);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,227 +4,130 @@
 | 
				
			|||||||
#include "ac_session.h"
 | 
					#include "ac_session.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_join(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
						struct capwap_header_data capwapheader;
 | 
				
			||||||
 | 
						struct capwap_packet_txmng* txmngpacket;
 | 
				
			||||||
	int status = AC_DFA_ACCEPT_PACKET;
 | 
						int status = AC_DFA_ACCEPT_PACKET;
 | 
				
			||||||
	struct capwap_resultcode_element resultcode = { CAPWAP_RESULTCODE_FAILURE };
 | 
						struct capwap_resultcode_element resultcode = { .code = CAPWAP_RESULTCODE_FAILURE };
 | 
				
			||||||
	struct capwap_build_packet* responsepacket;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if (packet) {
 | 
						if (packet) {
 | 
				
			||||||
		struct capwap_build_packet* buildpacket;
 | 
							unsigned short binding;
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
		buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
 | 
					 | 
				
			||||||
		if (buildpacket) {
 | 
					 | 
				
			||||||
			int validpacket;
 | 
					 | 
				
			||||||
			unsigned long checkpacket;
 | 
					 | 
				
			||||||
			struct capwap_array* returnedmessagearray = NULL;
 | 
					 | 
				
			||||||
			capwap_unrecognized_element_array* unrecognizedarray;
 | 
					 | 
				
			||||||
			struct capwap_element_join_request joinrequest;
 | 
					 | 
				
			||||||
			unsigned short binding = GET_WBID_HEADER(&buildpacket->header);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* */
 | 
							/* Check binding */
 | 
				
			||||||
			unrecognizedarray = capwap_array_create(sizeof(struct unrecognized_info), 0);
 | 
							binding = GET_WBID_HEADER(packet->rxmngpacket->header);
 | 
				
			||||||
			
 | 
							if (ac_valid_binding(binding)) {
 | 
				
			||||||
			/* */
 | 
								if (packet->rxmngpacket->ctrlmsg.type == CAPWAP_JOIN_REQUEST) {
 | 
				
			||||||
			checkpacket = capwap_build_packet_validate(buildpacket, unrecognizedarray);
 | 
									resultcode.code = CAPWAP_RESULTCODE_SUCCESS;
 | 
				
			||||||
			if (!checkpacket) {
 | 
					
 | 
				
			||||||
				if (ac_valid_binding(binding)) {
 | 
									/* Get sessionid */
 | 
				
			||||||
					if (ntohl(buildpacket->ctrlmsg.type) == CAPWAP_JOIN_REQUEST) {
 | 
									memcpy(&session->sessionid, packet->messageelements.sessionid, sizeof(struct capwap_sessionid_element));
 | 
				
			||||||
						resultcode.code = CAPWAP_RESULTCODE_SUCCESS;
 | 
					
 | 
				
			||||||
					} else {
 | 
									/* Get binding */
 | 
				
			||||||
						resultcode.code = CAPWAP_RESULTCODE_MSG_UNEXPECTED_INVALID_CURRENT_STATE;
 | 
									session->binding = binding;
 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_BINDING_NOT_SUPPORTED;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				if ((checkpacket & CAPWAP_MISSING_MANDATORY_MSG_ELEMENT) != 0) {
 | 
									resultcode.code = CAPWAP_RESULTCODE_MSG_UNEXPECTED_INVALID_CURRENT_STATE;
 | 
				
			||||||
					resultcode.code = CAPWAP_RESULTCODE_FAILURE_MISSING_MANDATORY_MSG_ELEMENT;
 | 
								}
 | 
				
			||||||
				} else if ((checkpacket & CAPWAP_UNRECOGNIZED_MSG_ELEMENT) != 0) {
 | 
							} else {
 | 
				
			||||||
					struct capwap_list_item* itemelement;
 | 
								resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_BINDING_NOT_SUPPORTED;
 | 
				
			||||||
					
 | 
							}
 | 
				
			||||||
					resultcode.code = CAPWAP_RESULTCODE_FAILURE_UNRECOGNIZED_MESSAGE_ELEMENT;
 | 
					 | 
				
			||||||
					returnedmessagearray = capwap_array_create(sizeof(struct capwap_returnedmessage_element), unrecognizedarray->count);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
					for (i = 0; i < unrecognizedarray->count; i++) {
 | 
							/* Create response */
 | 
				
			||||||
						struct unrecognized_info* reasoninfo = capwap_array_get_item_pointer(unrecognizedarray, i);
 | 
							capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, binding);
 | 
				
			||||||
						
 | 
							txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_JOIN_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, session->mtu);
 | 
				
			||||||
						/* Search element */
 | 
					 | 
				
			||||||
						itemelement = buildpacket->elementslist->first;
 | 
					 | 
				
			||||||
						while (itemelement != NULL) {
 | 
					 | 
				
			||||||
							struct capwap_message_element* elementitem = (struct capwap_message_element*)itemelement->item;
 | 
					 | 
				
			||||||
							
 | 
					 | 
				
			||||||
							if (ntohs(elementitem->type) == reasoninfo->element) {
 | 
					 | 
				
			||||||
								struct capwap_returnedmessage_element* returnedelement = capwap_array_get_item_pointer(returnedmessagearray, i);
 | 
					 | 
				
			||||||
								unsigned short length = sizeof(struct capwap_message_element) + ntohs(elementitem->length);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
								returnedelement->reason = reasoninfo->reason;
 | 
							/* Add message element */
 | 
				
			||||||
								returnedelement->length = min(length, CAPWAP_RETURNED_MESSAGE_MAX_LENGTH);
 | 
							capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RESULTCODE, &resultcode);
 | 
				
			||||||
								memcpy(&returnedelement->message[0], elementitem, returnedelement->length);
 | 
					
 | 
				
			||||||
								
 | 
							/* Check is valid packet after parsing request */
 | 
				
			||||||
								break;
 | 
							if ((resultcode.code == CAPWAP_RESULTCODE_SUCCESS) || (resultcode.code == CAPWAP_RESULTCODE_SUCCESS_NAT_DETECTED)) {
 | 
				
			||||||
							}
 | 
								struct capwap_list* controllist;
 | 
				
			||||||
							
 | 
								struct capwap_list_item* item;
 | 
				
			||||||
							/* Next */
 | 
					
 | 
				
			||||||
							itemelement = itemelement->next;
 | 
								/* Update statistics */
 | 
				
			||||||
						}
 | 
								ac_update_statistics();
 | 
				
			||||||
					}
 | 
								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) {
 | 
				
			||||||
 | 
									for (i = 0; i < packet->messageelements.ieee80211.wtpradioinformation->count; i++) {
 | 
				
			||||||
 | 
										struct capwap_80211_wtpradioinformation_element* radio;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
										radio = *(struct capwap_80211_wtpradioinformation_element**)capwap_array_get_item_pointer(packet->messageelements.ieee80211.wtpradioinformation, i);
 | 
				
			||||||
 | 
										capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, radio);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* */
 | 
								capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ECNSUPPORT, &session->dfa.ecn);
 | 
				
			||||||
			capwap_array_free(unrecognizedarray);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* */
 | 
								/* Get information from any local address */
 | 
				
			||||||
			capwap_init_element_join_request(&joinrequest, binding);
 | 
								controllist = capwap_list_create();
 | 
				
			||||||
			if (resultcode.code == CAPWAP_RESULTCODE_SUCCESS) {
 | 
								ac_get_control_information(controllist);
 | 
				
			||||||
				/* Parsing elements list */
 | 
					
 | 
				
			||||||
				if (capwap_parsing_element_join_request(&joinrequest, buildpacket->elementslist->first)) {
 | 
								for (item = controllist->first; item != NULL; item = item->next) {
 | 
				
			||||||
					/* TODO: gestione richiesta */
 | 
									struct ac_session_control* sessioncontrol = (struct ac_session_control*)item->item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (sessioncontrol->localaddress.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_family == AF_INET6) {
 | 
				
			||||||
 | 
										struct capwap_controlipv6_element element;
 | 
				
			||||||
					
 | 
										
 | 
				
			||||||
					/* Get sessionid */
 | 
										memcpy(&element.address, &((struct sockaddr_in6*)&sessioncontrol->localaddress)->sin6_addr, sizeof(struct in6_addr));
 | 
				
			||||||
					memcpy(&session->sessionid, joinrequest.sessionid, sizeof(struct capwap_sessionid_element));
 | 
										element.wtpcount = sessioncontrol->count;
 | 
				
			||||||
 | 
										capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV6, &element);
 | 
				
			||||||
					/* Get binding */
 | 
					 | 
				
			||||||
					session->binding = binding;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					resultcode.code = CAPWAP_RESULTCODE_SUCCESS;
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			/* Create response */
 | 
					 | 
				
			||||||
			responsepacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, binding);
 | 
					 | 
				
			||||||
			responsepacket->isctrlmsg = 1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Prepare join response */
 | 
								capwap_list_free(controllist);
 | 
				
			||||||
			capwap_build_packet_set_control_message_type(responsepacket, CAPWAP_JOIN_RESPONSE, buildpacket->ctrlmsg.seq);
 | 
					 | 
				
			||||||
			capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_RESULTCODE_ELEMENT(&resultcode));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Check is valid packet after parsing request */
 | 
								if (session->acctrladdress.ss_family == AF_INET) {
 | 
				
			||||||
			validpacket = (((resultcode.code == CAPWAP_RESULTCODE_SUCCESS) || (resultcode.code == CAPWAP_RESULTCODE_SUCCESS_NAT_DETECTED)) ? 1 : 0);
 | 
									struct capwap_localipv4_element addr;
 | 
				
			||||||
			if (validpacket) {
 | 
					 | 
				
			||||||
				struct capwap_list* controllist;
 | 
					 | 
				
			||||||
				struct capwap_list_item* item;
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
				/* Update statistics */
 | 
					 | 
				
			||||||
				ac_update_statistics();
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ACDESCRIPTOR_ELEMENT(&g_ac.descriptor));
 | 
					 | 
				
			||||||
				capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ACNAME_ELEMENT(&g_ac.acname));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
 | 
									memcpy(&addr.address, &((struct sockaddr_in*)&session->acctrladdress)->sin_addr, sizeof(struct in_addr));
 | 
				
			||||||
					for (i = 0; i < joinrequest.binding.ieee80211.wtpradioinformation->count; i++) {
 | 
									capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_LOCALIPV4, &addr);
 | 
				
			||||||
						struct capwap_80211_wtpradioinformation_element* radio;
 | 
								} else if (session->acctrladdress.ss_family == AF_INET6) {
 | 
				
			||||||
			
 | 
									struct capwap_localipv6_element addr;
 | 
				
			||||||
						radio = (struct capwap_80211_wtpradioinformation_element*)capwap_array_get_item_pointer(joinrequest.binding.ieee80211.wtpradioinformation, i);
 | 
					 | 
				
			||||||
						capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_80211_WTPRADIOINFORMATION_ELEMENT(radio));
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					capwap_logging_debug("Unknown capwap binding");
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ECNSUPPORT_ELEMENT(&session->dfa.ecn));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/* Get information from any local address */
 | 
									memcpy(&addr.address, &((struct sockaddr_in6*)&session->acctrladdress)->sin6_addr, sizeof(struct in6_addr));
 | 
				
			||||||
				controllist = capwap_list_create();
 | 
									capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_LOCALIPV6, &addr);
 | 
				
			||||||
				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_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_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_CONTROLIPV4_ELEMENT(&element));
 | 
					 | 
				
			||||||
					} else if (sessioncontrol->localaddress.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_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_CONTROLIPV6_ELEMENT(&element));
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
				capwap_list_free(controllist);	
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if (session->acctrladdress.ss_family == AF_INET) {
 | 
					 | 
				
			||||||
					struct capwap_localipv4_element addr;
 | 
					 | 
				
			||||||
					
 | 
					 | 
				
			||||||
					memcpy(&addr.address, &((struct sockaddr_in*)&session->acctrladdress)->sin_addr, sizeof(struct in_addr));
 | 
					 | 
				
			||||||
					capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_LOCALIPV4_ELEMENT(&addr));
 | 
					 | 
				
			||||||
				} else if (session->acctrladdress.ss_family == AF_INET6) {
 | 
					 | 
				
			||||||
					struct capwap_localipv6_element addr;
 | 
					 | 
				
			||||||
					
 | 
					 | 
				
			||||||
					memcpy(&addr.address, &((struct sockaddr_in6*)&session->acctrladdress)->sin6_addr, sizeof(struct in6_addr));
 | 
					 | 
				
			||||||
					capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_LOCALIPV6_ELEMENT(&addr));
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				/* CAPWAP_CREATE_ACIPV4LIST_ELEMENT */				/* TODO */
 | 
					 | 
				
			||||||
				/* CAPWAP_CREATE_ACIPV6LIST_ELEMENT */				/* TODO */
 | 
					 | 
				
			||||||
				capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_TRANSPORT_ELEMENT(&session->dfa.transport));
 | 
					 | 
				
			||||||
				/* CAPWAP_CREATE_IMAGEIDENTIFIER_ELEMENT */			/* TODO */
 | 
					 | 
				
			||||||
				/* CAPWAP_CREATE_MAXIMUMMESSAGELENGTH_ELEMENT */	/* TODO */
 | 
					 | 
				
			||||||
				/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */	/* TODO */
 | 
					 | 
				
			||||||
			} else if (resultcode.code == CAPWAP_RESULTCODE_FAILURE_UNRECOGNIZED_MESSAGE_ELEMENT) {
 | 
					 | 
				
			||||||
				ASSERT(returnedmessagearray != NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				for (i = 0; i < returnedmessagearray->count; i++) {
 | 
					 | 
				
			||||||
					capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_RETURNEDMESSAGE_ELEMENT(capwap_array_get_item_pointer(returnedmessagearray, i)));
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				capwap_array_free(returnedmessagearray);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Validate packet */
 | 
								/* CAPWAP_CREATE_ACIPV4LIST_ELEMENT */				/* TODO */
 | 
				
			||||||
			if (!validpacket || !capwap_build_packet_validate(responsepacket, NULL)) {
 | 
								/* CAPWAP_CREATE_ACIPV6LIST_ELEMENT */				/* TODO */
 | 
				
			||||||
				int result;
 | 
								capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_TRANSPORT, &session->dfa.transport);
 | 
				
			||||||
				
 | 
								/* CAPWAP_CREATE_IMAGEIDENTIFIER_ELEMENT */			/* TODO */
 | 
				
			||||||
				/* Free old reference for this request */
 | 
								/* CAPWAP_CREATE_MAXIMUMMESSAGELENGTH_ELEMENT */	/* TODO */
 | 
				
			||||||
				ac_free_reference_last_response(session);
 | 
								/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */	/* TODO */
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/* Send join response to WTP */
 | 
							/* Join response complete, get fragment packets */
 | 
				
			||||||
				result = capwap_fragment_build_packet(responsepacket, session->responsefragmentpacket, session->mtu, session->fragmentid);
 | 
							ac_free_reference_last_response(session);
 | 
				
			||||||
				if (result >= 0) {
 | 
							capwap_packet_txmng_get_fragment_packets(txmngpacket, session->responsefragmentpacket, session->fragmentid);
 | 
				
			||||||
					if (result == 1) {
 | 
							if (session->responsefragmentpacket->count > 1) {
 | 
				
			||||||
						session->fragmentid++;
 | 
								session->fragmentid++;
 | 
				
			||||||
					}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					/* Save remote sequence number */
 | 
							/* Free packets manager */
 | 
				
			||||||
					session->remoteseqnumber = buildpacket->ctrlmsg.seq;
 | 
							capwap_packet_txmng_free(txmngpacket);
 | 
				
			||||||
					capwap_get_packet_digest((void*)packet->header, packet->packetsize, session->lastrecvpackethash);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
					/* Send */
 | 
							/* Save remote sequence number */
 | 
				
			||||||
					for (i = 0; i < session->responsefragmentpacket->count; i++) {
 | 
							session->remoteseqnumber = packet->rxmngpacket->ctrlmsg.seq;
 | 
				
			||||||
						struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(session->responsefragmentpacket, i);
 | 
							capwap_get_packet_digest(packet->rxmngpacket, packet->connection, session->lastrecvpackethash);
 | 
				
			||||||
						ASSERT(txpacket != NULL);
 | 
					 | 
				
			||||||
						
 | 
					 | 
				
			||||||
						if (!capwap_crypt_sendto(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], txpacket->header, txpacket->packetsize, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
					 | 
				
			||||||
							/* Response is already created and saved. When receive a re-request, DFA autoresponse */
 | 
					 | 
				
			||||||
							capwap_logging_debug("Warning: error to send join response packet");
 | 
					 | 
				
			||||||
							break;
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				capwap_logging_debug("Warning: build invalid join response packet");
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Free memory */
 | 
							/* Send Join response to WTP */
 | 
				
			||||||
			capwap_build_packet_free(responsepacket);
 | 
							if (capwap_crypt_sendto_fragmentpacket(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], session->responsefragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
				
			||||||
			capwap_free_element_join_request(&joinrequest, binding);
 | 
								ac_dfa_change_state(session, CAPWAP_POSTJOIN_STATE);
 | 
				
			||||||
			capwap_build_packet_free(buildpacket);
 | 
							} else {
 | 
				
			||||||
					
 | 
								/* Error to send packets */
 | 
				
			||||||
			/* Change state */
 | 
								capwap_logging_debug("Warning: error to send join response packet");
 | 
				
			||||||
			if (validpacket) {
 | 
								ac_dfa_change_state(session, CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE);
 | 
				
			||||||
				ac_dfa_change_state(session, CAPWAP_POSTJOIN_STATE);
 | 
								status = AC_DFA_NO_PACKET;
 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				ac_dfa_change_state(session, CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE);
 | 
					 | 
				
			||||||
				status = AC_DFA_NO_PACKET;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* Join timeout */
 | 
							/* Join timeout */
 | 
				
			||||||
@ -236,26 +139,21 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_packet* packet
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_postjoin(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_postjoin(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	int status = AC_DFA_ACCEPT_PACKET;
 | 
						int status = AC_DFA_ACCEPT_PACKET;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if (packet) {
 | 
						if (packet) {
 | 
				
			||||||
		unsigned short lengthpayload;
 | 
							if (packet->rxmngpacket->ctrlmsg.type == CAPWAP_CONFIGURATION_STATUS_REQUEST) {
 | 
				
			||||||
 | 
								ac_dfa_change_state(session, CAPWAP_CONFIGURE_STATE);
 | 
				
			||||||
		lengthpayload = packet->packetsize - GET_HLEN_HEADER(packet->header) * 4;
 | 
								status = ac_dfa_state_configure(session, packet);
 | 
				
			||||||
		if (lengthpayload >= sizeof(struct capwap_control_message)) {
 | 
							} else if (packet->rxmngpacket->ctrlmsg.type == CAPWAP_IMAGE_DATA_REQUEST) {
 | 
				
			||||||
			struct capwap_control_message* ctrlmsg = (struct capwap_control_message*)packet->payload;
 | 
								ac_dfa_change_state(session, CAPWAP_IMAGE_DATA_STATE);
 | 
				
			||||||
			unsigned long type = ntohl(ctrlmsg->type);
 | 
								status = ac_dfa_state_imagedata(session, packet);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
			if (type == CAPWAP_CONFIGURATION_STATUS_REQUEST) {
 | 
								ac_dfa_change_state(session, CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE);
 | 
				
			||||||
				ac_dfa_change_state(session, CAPWAP_CONFIGURE_STATE);
 | 
								status = AC_DFA_NO_PACKET;
 | 
				
			||||||
				status = ac_dfa_state_configure(session, packet);
 | 
					 | 
				
			||||||
			} else if (type == CAPWAP_IMAGE_DATA_REQUEST) {
 | 
					 | 
				
			||||||
				ac_dfa_change_state(session, CAPWAP_IMAGE_DATA_STATE);
 | 
					 | 
				
			||||||
				status = ac_dfa_state_imagedata(session, packet);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* Join timeout */
 | 
							/* Join timeout */
 | 
				
			||||||
@ -267,6 +165,6 @@ int ac_dfa_state_postjoin(struct ac_session_t* session, struct capwap_packet* pa
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_join_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_join_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	return ac_session_teardown_connection(session);
 | 
						return ac_session_teardown_connection(session);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,69 +4,34 @@
 | 
				
			|||||||
#include "ac_session.h"
 | 
					#include "ac_session.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_reset(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_reset(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	int status = AC_DFA_ACCEPT_PACKET;
 | 
						int status = AC_DFA_ACCEPT_PACKET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (packet) {
 | 
						if (packet) {
 | 
				
			||||||
		if (!capwap_compare_ip(&session->wtpctrladdress, &packet->remoteaddr)) {
 | 
							unsigned short binding;
 | 
				
			||||||
			struct capwap_build_packet* buildpacket;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Parsing packet */
 | 
							/* */
 | 
				
			||||||
			buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
 | 
							binding = GET_WBID_HEADER(packet->rxmngpacket->header);
 | 
				
			||||||
			if (buildpacket) {
 | 
							if ((binding == session->binding) && (packet->rxmngpacket->ctrlmsg.type == CAPWAP_RESET_RESPONSE) && ((session->localseqnumber - 1) == packet->rxmngpacket->ctrlmsg.seq)) {
 | 
				
			||||||
				if (!capwap_build_packet_validate(buildpacket, NULL)) {
 | 
								ac_dfa_change_state(session, CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE);
 | 
				
			||||||
					unsigned short binding;
 | 
								status = AC_DFA_NO_PACKET;
 | 
				
			||||||
					
 | 
					 | 
				
			||||||
					/* */
 | 
					 | 
				
			||||||
					binding = GET_WBID_HEADER(&buildpacket->header);
 | 
					 | 
				
			||||||
					if ((binding == session->binding) && (ntohl(buildpacket->ctrlmsg.type) == CAPWAP_RESET_RESPONSE) && ((session->localseqnumber - 1) == buildpacket->ctrlmsg.seq)) {
 | 
					 | 
				
			||||||
						struct capwap_element_reset_response resetresponse;
 | 
					 | 
				
			||||||
						
 | 
					 | 
				
			||||||
						/* Valid packet, free request packet */
 | 
					 | 
				
			||||||
						ac_free_reference_last_request(session);
 | 
					 | 
				
			||||||
						
 | 
					 | 
				
			||||||
						/* Configuration status response info */
 | 
					 | 
				
			||||||
						capwap_init_element_reset_response(&resetresponse, binding);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
						/* Parsing elements list */
 | 
					 | 
				
			||||||
						if (capwap_parsing_element_reset_response(&resetresponse, buildpacket->elementslist->first)) {
 | 
					 | 
				
			||||||
							ac_dfa_change_state(session, CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE);
 | 
					 | 
				
			||||||
							status = AC_DFA_NO_PACKET;
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						
 | 
					 | 
				
			||||||
						/* Free join response */
 | 
					 | 
				
			||||||
						capwap_free_element_reset_response(&resetresponse, binding);
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				/* Free */				
 | 
					 | 
				
			||||||
				capwap_build_packet_free(buildpacket);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		int i;
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		/* No Configuration status response received */
 | 
							/* No Configuration status response received */
 | 
				
			||||||
		session->dfa.rfcRetransmitCount++;
 | 
							session->dfa.rfcRetransmitCount++;
 | 
				
			||||||
		if (session->dfa.rfcRetransmitCount >= session->dfa.rfcMaxRetransmit) {
 | 
							if (session->dfa.rfcRetransmitCount >= session->dfa.rfcMaxRetransmit) {
 | 
				
			||||||
			/* Timeout join state */
 | 
								/* Timeout reset state */
 | 
				
			||||||
			ac_free_reference_last_request(session);
 | 
								ac_free_reference_last_request(session);
 | 
				
			||||||
			ac_dfa_change_state(session, CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE);
 | 
								ac_dfa_change_state(session, CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE);
 | 
				
			||||||
			status = AC_DFA_NO_PACKET;
 | 
								status = AC_DFA_NO_PACKET;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			/* Retransmit configuration request */	
 | 
								/* Retransmit configuration request */	
 | 
				
			||||||
			for (i = 0; i < session->requestfragmentpacket->count; i++) {
 | 
								if (!capwap_crypt_sendto_fragmentpacket(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], session->requestfragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
				
			||||||
				struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(session->requestfragmentpacket, i);
 | 
									capwap_logging_debug("Warning: error to resend reset request packet");
 | 
				
			||||||
				ASSERT(txpacket != NULL);
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				if (!capwap_crypt_sendto(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], txpacket->header, txpacket->packetsize, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
					 | 
				
			||||||
					capwap_logging_debug("Warning: error to send configuration status request packet");
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
			/* Update timeout */
 | 
								/* Update timeout */
 | 
				
			||||||
			capwap_set_timeout(session->dfa.rfcRetransmitInterval, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
								capwap_set_timeout(session->dfa.rfcRetransmitInterval, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -76,6 +41,6 @@ int ac_dfa_state_reset(struct ac_session_t* session, struct capwap_packet* packe
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_reset_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_reset_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	return ac_session_teardown_connection(session);
 | 
						return ac_session_teardown_connection(session);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,185 +4,148 @@
 | 
				
			|||||||
#include "ac_session.h"
 | 
					#include "ac_session.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
static int receive_echo_request(struct ac_session_t* session, struct capwap_build_packet* buildpacket, struct capwap_packet* packet) {
 | 
					static int receive_echo_request(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	unsigned long i;
 | 
						struct capwap_header_data capwapheader;
 | 
				
			||||||
	unsigned short binding;
 | 
						struct capwap_packet_txmng* txmngpacket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
	ASSERT(buildpacket != NULL);
 | 
					 | 
				
			||||||
	ASSERT(packet != NULL);
 | 
						ASSERT(packet != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Create response */
 | 
				
			||||||
	binding = GET_WBID_HEADER(&buildpacket->header);
 | 
						capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, GET_WBID_HEADER(packet->rxmngpacket->header));
 | 
				
			||||||
	if (ac_valid_binding(binding) && IS_SEQUENCE_SMALLER(session->remoteseqnumber, buildpacket->ctrlmsg.seq)) {
 | 
						txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_ECHO_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, session->mtu);
 | 
				
			||||||
		struct capwap_element_echo_request echorequest;
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		/* Echo request info*/
 | 
					 | 
				
			||||||
		capwap_init_element_echo_request(&echorequest, binding);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		/* Parsing elements list */
 | 
					 | 
				
			||||||
		if (capwap_parsing_element_echo_request(&echorequest, buildpacket->elementslist->first)) {
 | 
					 | 
				
			||||||
			struct capwap_build_packet* responsepacket;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Create response */
 | 
						/* Add message element */
 | 
				
			||||||
			responsepacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, binding);
 | 
						/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */		/* TODO */
 | 
				
			||||||
			responsepacket->isctrlmsg = 1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Prepare echo response */
 | 
						/* Echo response complete, get fragment packets */
 | 
				
			||||||
			capwap_build_packet_set_control_message_type(responsepacket, CAPWAP_ECHO_RESPONSE, buildpacket->ctrlmsg.seq);
 | 
						ac_free_reference_last_response(session);
 | 
				
			||||||
			/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */		/* TODO */
 | 
						capwap_packet_txmng_get_fragment_packets(txmngpacket, session->responsefragmentpacket, session->fragmentid);
 | 
				
			||||||
 | 
						if (session->responsefragmentpacket->count > 1) {
 | 
				
			||||||
 | 
							session->fragmentid++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!capwap_build_packet_validate(responsepacket, NULL)) {
 | 
						/* Free packets manager */
 | 
				
			||||||
				int result;
 | 
						capwap_packet_txmng_free(txmngpacket);
 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				/* Free old reference for this request */
 | 
					 | 
				
			||||||
				ac_free_reference_last_response(session);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/* Send echo response to WTP */
 | 
						/* Save remote sequence number */
 | 
				
			||||||
				result = capwap_fragment_build_packet(responsepacket, session->responsefragmentpacket, session->mtu, session->fragmentid);
 | 
						session->remoteseqnumber = packet->rxmngpacket->ctrlmsg.seq;
 | 
				
			||||||
				if (result >= 0) {
 | 
						capwap_get_packet_digest(packet->rxmngpacket, packet->connection, session->lastrecvpackethash);
 | 
				
			||||||
					if (result == 1) {
 | 
					 | 
				
			||||||
						session->fragmentid++;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
					/* Save remote sequence number */
 | 
						/* Send Configure response to WTP */
 | 
				
			||||||
					session->remoteseqnumber = buildpacket->ctrlmsg.seq;
 | 
						if (!capwap_crypt_sendto_fragmentpacket(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], session->responsefragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
				
			||||||
					capwap_get_packet_digest((void*)packet->header, packet->packetsize, session->lastrecvpackethash);
 | 
							/* Response is already created and saved. When receive a re-request, DFA autoresponse */
 | 
				
			||||||
 | 
							capwap_logging_debug("Warning: error to send echo response packet");
 | 
				
			||||||
					/* Send */
 | 
					 | 
				
			||||||
					for (i = 0; i < session->responsefragmentpacket->count; i++) {
 | 
					 | 
				
			||||||
						struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(session->responsefragmentpacket, i);
 | 
					 | 
				
			||||||
						ASSERT(txpacket != NULL);
 | 
					 | 
				
			||||||
						
 | 
					 | 
				
			||||||
						if (!capwap_crypt_sendto(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], txpacket->header, txpacket->packetsize, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
					 | 
				
			||||||
							/* Response is already created and saved. When receive a re-request, DFA autoresponse */
 | 
					 | 
				
			||||||
							capwap_logging_debug("Warning: error to send echo response packet");
 | 
					 | 
				
			||||||
							break;
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			/* Free memory */
 | 
					 | 
				
			||||||
			capwap_build_packet_free(responsepacket);
 | 
					 | 
				
			||||||
		} 
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		/* Free */
 | 
					 | 
				
			||||||
		capwap_free_element_echo_request(&echorequest, binding);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_run(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					static int ac_send_data_keepalive(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
 | 
						struct capwap_list* txfragpacket;
 | 
				
			||||||
 | 
						struct capwap_header_data capwapheader;
 | 
				
			||||||
 | 
						struct capwap_packet_txmng* txmngpacket;
 | 
				
			||||||
 | 
						int result = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Build packet */
 | 
				
			||||||
 | 
						capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, GET_WBID_HEADER(packet->rxmngpacket->header));
 | 
				
			||||||
 | 
						capwap_header_set_keepalive_flag(&capwapheader, 1);
 | 
				
			||||||
 | 
						txmngpacket = capwap_packet_txmng_create_data_message(&capwapheader, session->mtu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Add message element */
 | 
				
			||||||
 | 
						capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_SESSIONID, &session->sessionid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Data keepalive complete, get fragment packets into local list */
 | 
				
			||||||
 | 
						txfragpacket = capwap_list_create();
 | 
				
			||||||
 | 
						capwap_packet_txmng_get_fragment_packets(txmngpacket, txfragpacket, 0);
 | 
				
			||||||
 | 
						if (txfragpacket->count == 1) {
 | 
				
			||||||
 | 
							/* Send Data keepalive to WTP */
 | 
				
			||||||
 | 
							if (capwap_crypt_sendto_fragmentpacket(&session->datadtls, session->datasocket.socket[session->datasocket.type], txfragpacket, &session->acdataaddress, &session->wtpdataaddress)) {
 | 
				
			||||||
 | 
								result = 0;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								capwap_logging_debug("Warning: error to send data channel keepalive packet");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							capwap_logging_debug("Warning: error to send data channel keepalive packet, fragment packet");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Free packets manager */
 | 
				
			||||||
 | 
						capwap_list_free(txfragpacket);
 | 
				
			||||||
 | 
						capwap_packet_txmng_free(txmngpacket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					int ac_dfa_state_run(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	int status = AC_DFA_ACCEPT_PACKET;
 | 
						int status = AC_DFA_ACCEPT_PACKET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (packet) {
 | 
						if (packet) {
 | 
				
			||||||
		struct capwap_build_packet* buildpacket;
 | 
							if (packet->rxmngpacket->isctrlpacket) {
 | 
				
			||||||
 | 
								if (capwap_is_request_type(packet->rxmngpacket->ctrlmsg.type) || ((session->localseqnumber - 1) == packet->rxmngpacket->ctrlmsg.seq)) {
 | 
				
			||||||
		buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
 | 
									switch (packet->rxmngpacket->ctrlmsg.type) {
 | 
				
			||||||
		if (buildpacket) {
 | 
										case CAPWAP_CONFIGURATION_UPDATE_REQUEST: {
 | 
				
			||||||
			if (!capwap_build_packet_validate(buildpacket, NULL)) {
 | 
					 | 
				
			||||||
				if (packet->socket.isctrlsocket) {
 | 
					 | 
				
			||||||
					unsigned long typemsg = ntohl(buildpacket->ctrlmsg.type);
 | 
					 | 
				
			||||||
					
 | 
					 | 
				
			||||||
					if (capwap_is_request_type(typemsg) || ((session->localseqnumber - 1) == buildpacket->ctrlmsg.seq)) {
 | 
					 | 
				
			||||||
						switch (typemsg) {
 | 
					 | 
				
			||||||
							case CAPWAP_CONFIGURATION_UPDATE_REQUEST: {
 | 
					 | 
				
			||||||
								/* TODO */
 | 
					 | 
				
			||||||
								capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
					 | 
				
			||||||
								break;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							
 | 
					 | 
				
			||||||
							case CAPWAP_CHANGE_STATE_EVENT_RESPONSE: {
 | 
					 | 
				
			||||||
								/* TODO */
 | 
					 | 
				
			||||||
								capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
					 | 
				
			||||||
								break;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							
 | 
					 | 
				
			||||||
							case CAPWAP_ECHO_REQUEST: {
 | 
					 | 
				
			||||||
								if (!receive_echo_request(session, buildpacket, packet)) {
 | 
					 | 
				
			||||||
									capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
					 | 
				
			||||||
								} else {
 | 
					 | 
				
			||||||
									ac_dfa_change_state(session, CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
 | 
					 | 
				
			||||||
									status = AC_DFA_NO_PACKET;
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
								
 | 
					 | 
				
			||||||
								break;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							
 | 
					 | 
				
			||||||
							case CAPWAP_CLEAR_CONFIGURATION_REQUEST: {
 | 
					 | 
				
			||||||
								/* TODO */
 | 
					 | 
				
			||||||
								capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
					 | 
				
			||||||
								break;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							
 | 
					 | 
				
			||||||
							case CAPWAP_WTP_EVENT_RESPONSE: {
 | 
					 | 
				
			||||||
								/* TODO */
 | 
					 | 
				
			||||||
								capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
					 | 
				
			||||||
								break;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							
 | 
					 | 
				
			||||||
							case CAPWAP_DATA_TRANSFER_REQUEST: {
 | 
					 | 
				
			||||||
								/* TODO */
 | 
					 | 
				
			||||||
								capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
					 | 
				
			||||||
								break;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							
 | 
					 | 
				
			||||||
							case CAPWAP_DATA_TRANSFER_RESPONSE: {
 | 
					 | 
				
			||||||
								/* TODO */
 | 
					 | 
				
			||||||
								capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
					 | 
				
			||||||
								break;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					if (IS_FLAG_K_HEADER(&buildpacket->header)) {
 | 
					 | 
				
			||||||
						struct capwap_sessionid_element sessionid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						if (capwap_get_sessionid_from_keepalive(buildpacket, &sessionid)) {
 | 
					 | 
				
			||||||
							if (!memcmp(&sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
 | 
					 | 
				
			||||||
								int result;
 | 
					 | 
				
			||||||
								capwap_fragment_packet_array* txfragpacket;
 | 
					 | 
				
			||||||
								
 | 
					 | 
				
			||||||
								/* Receive data packet keepalive, response with same packet */
 | 
					 | 
				
			||||||
								txfragpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
 | 
					 | 
				
			||||||
								result = capwap_fragment_build_packet(buildpacket, txfragpacket, CAPWAP_DONT_FRAGMENT, 0);
 | 
					 | 
				
			||||||
								if (!result) {
 | 
					 | 
				
			||||||
									struct capwap_packet* txpacket;
 | 
					 | 
				
			||||||
									
 | 
					 | 
				
			||||||
									ASSERT(txfragpacket->count == 1);
 | 
					 | 
				
			||||||
									
 | 
					 | 
				
			||||||
									txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(txfragpacket, 0);
 | 
					 | 
				
			||||||
									ASSERT(txpacket != NULL);
 | 
					 | 
				
			||||||
									
 | 
					 | 
				
			||||||
									if (!capwap_crypt_sendto(&session->datadtls, session->datasocket.socket[session->datasocket.type], txpacket->header, txpacket->packetsize, &session->acdataaddress, &session->wtpdataaddress)) {
 | 
					 | 
				
			||||||
										capwap_logging_debug("Warning: error to send data channel keepalive packet");
 | 
					 | 
				
			||||||
										result = -1;
 | 
					 | 
				
			||||||
									}
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
							
 | 
					 | 
				
			||||||
								/* */
 | 
					 | 
				
			||||||
								capwap_fragment_free(txfragpacket);
 | 
					 | 
				
			||||||
								capwap_array_free(txfragpacket);
 | 
					 | 
				
			||||||
								
 | 
					 | 
				
			||||||
								if (result) {
 | 
					 | 
				
			||||||
									ac_dfa_change_state(session, CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
 | 
					 | 
				
			||||||
									status = AC_DFA_NO_PACKET;
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					} else {
 | 
					 | 
				
			||||||
						/* TODO */
 | 
											/* TODO */
 | 
				
			||||||
 | 
											capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										case CAPWAP_CHANGE_STATE_EVENT_RESPONSE: {
 | 
				
			||||||
 | 
											/* TODO */
 | 
				
			||||||
 | 
											capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										case CAPWAP_ECHO_REQUEST: {
 | 
				
			||||||
 | 
											if (!receive_echo_request(session, packet)) {
 | 
				
			||||||
 | 
												capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
				
			||||||
 | 
											} else {
 | 
				
			||||||
 | 
												ac_dfa_change_state(session, CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
 | 
				
			||||||
 | 
												status = AC_DFA_NO_PACKET;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										case CAPWAP_CLEAR_CONFIGURATION_REQUEST: {
 | 
				
			||||||
 | 
											/* TODO */
 | 
				
			||||||
 | 
											capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										case CAPWAP_WTP_EVENT_RESPONSE: {
 | 
				
			||||||
 | 
											/* TODO */
 | 
				
			||||||
 | 
											capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										case CAPWAP_DATA_TRANSFER_REQUEST: {
 | 
				
			||||||
 | 
											/* TODO */
 | 
				
			||||||
 | 
											capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										case CAPWAP_DATA_TRANSFER_RESPONSE: {
 | 
				
			||||||
 | 
											/* TODO */
 | 
				
			||||||
 | 
											capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
							} else {
 | 
				
			||||||
			/* Free */
 | 
								if (IS_FLAG_K_HEADER(packet->rxmngpacket->header)) {
 | 
				
			||||||
			capwap_build_packet_free(buildpacket);
 | 
									if (!memcmp(packet->messageelements.sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
 | 
				
			||||||
 | 
										if (ac_send_data_keepalive(session, packet)) {
 | 
				
			||||||
 | 
											ac_dfa_change_state(session, CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
 | 
				
			||||||
 | 
											status = AC_DFA_NO_PACKET;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									/* TODO */
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		ac_dfa_change_state(session, CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
 | 
							ac_dfa_change_state(session, CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
 | 
				
			||||||
@ -193,71 +156,49 @@ int ac_dfa_state_run(struct ac_session_t* session, struct capwap_packet* packet)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_run_to_reset(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_run_to_reset(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	int status = AC_DFA_NO_PACKET;
 | 
						int status = AC_DFA_NO_PACKET;
 | 
				
			||||||
	struct capwap_build_packet* buildpacket;
 | 
						struct capwap_header_data capwapheader;
 | 
				
			||||||
 | 
						struct capwap_packet_txmng* txmngpacket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
	ASSERT(packet == NULL);
 | 
						ASSERT(packet == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Build packet */
 | 
						/* Build packet */
 | 
				
			||||||
	buildpacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, session->binding);
 | 
						capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, session->binding);
 | 
				
			||||||
	buildpacket->isctrlmsg = 1;
 | 
						txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_RESET_REQUEST, session->localseqnumber++, session->mtu);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	/* Prepare reset request */
 | 
						/* Add message element */
 | 
				
			||||||
	capwap_build_packet_set_control_message_type(buildpacket, CAPWAP_RESET_REQUEST, session->localseqnumber++);
 | 
						capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_IMAGEIDENTIFIER, &session->startupimage);
 | 
				
			||||||
	capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_IMAGEIDENTIFIER_ELEMENT(&session->startupimage));
 | 
					 | 
				
			||||||
	/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */	/* TODO */
 | 
						/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */	/* TODO */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!capwap_build_packet_validate(buildpacket, NULL)) {
 | 
						/* Reset request complete, get fragment packets */
 | 
				
			||||||
		int i;
 | 
						ac_free_reference_last_request(session);
 | 
				
			||||||
		int result;
 | 
						capwap_packet_txmng_get_fragment_packets(txmngpacket, session->requestfragmentpacket, session->fragmentid);
 | 
				
			||||||
		
 | 
						if (session->requestfragmentpacket->count > 1) {
 | 
				
			||||||
		/* Free old reference for this request */
 | 
							session->fragmentid++;
 | 
				
			||||||
		ac_free_reference_last_request(session);
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Send reset request to WTP */
 | 
						/* Free packets manager */
 | 
				
			||||||
		result = capwap_fragment_build_packet(buildpacket, session->requestfragmentpacket, session->mtu, session->fragmentid);
 | 
						capwap_packet_txmng_free(txmngpacket);
 | 
				
			||||||
		if (result >= 0) {
 | 
					
 | 
				
			||||||
			if (result == 1) {
 | 
						/* Send Configure response to WTP */
 | 
				
			||||||
				session->fragmentid++;
 | 
						if (capwap_crypt_sendto_fragmentpacket(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], session->requestfragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
				
			||||||
			}
 | 
							session->dfa.rfcRetransmitCount = 0;
 | 
				
			||||||
 | 
							capwap_killall_timeout(&session->timeout);
 | 
				
			||||||
			/* Send */
 | 
							capwap_set_timeout(session->dfa.rfcRetransmitInterval, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
				
			||||||
			for (i = 0; i < session->requestfragmentpacket->count; i++) {
 | 
							ac_dfa_change_state(session, CAPWAP_RESET_STATE);
 | 
				
			||||||
				struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(session->requestfragmentpacket, i);
 | 
							status = AC_DFA_ACCEPT_PACKET;
 | 
				
			||||||
				ASSERT(txpacket != NULL);
 | 
						} else {
 | 
				
			||||||
				
 | 
							capwap_logging_debug("Warning: error to send reset request packet");
 | 
				
			||||||
				if (!capwap_crypt_sendto(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], txpacket->header, txpacket->packetsize, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
							ac_free_reference_last_request(session);
 | 
				
			||||||
					capwap_logging_debug("Warning: error to send reset request packet");
 | 
							ac_dfa_change_state(session, CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE);
 | 
				
			||||||
					result = -1;
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (result == -1) {
 | 
					 | 
				
			||||||
			/* Error to send packets */
 | 
					 | 
				
			||||||
			ac_free_reference_last_request(session);
 | 
					 | 
				
			||||||
			ac_dfa_change_state(session, CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			session->dfa.rfcRetransmitCount = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			capwap_killall_timeout(&session->timeout);
 | 
					 | 
				
			||||||
			capwap_set_timeout(session->dfa.rfcRetransmitInterval, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			ac_dfa_change_state(session, CAPWAP_RESET_STATE);
 | 
					 | 
				
			||||||
			status = AC_DFA_ACCEPT_PACKET;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Free memory */
 | 
					 | 
				
			||||||
	capwap_build_packet_free(buildpacket);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return status;
 | 
						return status;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_run_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_run_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	return ac_session_teardown_connection(session);
 | 
						return ac_session_teardown_connection(session);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@
 | 
				
			|||||||
#include "ac_session.h"
 | 
					#include "ac_session.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_teardown(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_teardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
	ASSERT(packet == NULL);
 | 
						ASSERT(packet == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -14,7 +14,7 @@ int ac_dfa_state_teardown(struct ac_session_t* session, struct capwap_packet* pa
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_dead(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					int ac_dfa_state_dead(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
	ASSERT(packet == NULL);
 | 
						ASSERT(packet == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -88,44 +88,39 @@ void ac_discovery_add_packet(void* buffer, int buffersize, int sock, struct sock
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
static struct capwap_build_packet* ac_create_discovery_response(struct capwap_build_packet* packet, struct capwap_element_discovery_request* discoveryrequest, struct sockaddr_storage* sender) {
 | 
					static struct capwap_packet_txmng* ac_create_discovery_response(struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	unsigned short binding;
 | 
						unsigned short binding;
 | 
				
			||||||
	struct capwap_list* controllist;
 | 
						struct capwap_list* controllist;
 | 
				
			||||||
	struct capwap_list_item* item;
 | 
						struct capwap_list_item* item;
 | 
				
			||||||
	struct capwap_build_packet* responsepacket;
 | 
						struct capwap_header_data capwapheader;
 | 
				
			||||||
 | 
						struct capwap_packet_txmng* txmngpacket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(packet != NULL);
 | 
						ASSERT(packet != NULL);
 | 
				
			||||||
	ASSERT(discoveryrequest != NULL);
 | 
					 | 
				
			||||||
	ASSERT(sender != NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Check is valid binding */
 | 
						/* Check is valid binding */
 | 
				
			||||||
	binding = GET_WBID_HEADER(&packet->header);
 | 
						binding = GET_WBID_HEADER(packet->rxmngpacket->header);
 | 
				
			||||||
	if (!ac_valid_binding(binding)) {
 | 
						if (!ac_valid_binding(binding)) {
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Build packet */
 | 
					 | 
				
			||||||
	responsepacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, binding);
 | 
					 | 
				
			||||||
	responsepacket->isctrlmsg = 1;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Update statistics */
 | 
						/* Update statistics */
 | 
				
			||||||
	ac_update_statistics();
 | 
						ac_update_statistics();
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Prepare discovery response */
 | 
					 | 
				
			||||||
	capwap_build_packet_set_control_message_type(responsepacket, CAPWAP_DISCOVERY_RESPONSE, packet->ctrlmsg.seq);
 | 
					 | 
				
			||||||
	capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ACDESCRIPTOR_ELEMENT(&g_ac.descriptor));
 | 
					 | 
				
			||||||
	capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ACNAME_ELEMENT(&g_ac.acname));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 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) {
 | 
						if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
 | 
				
			||||||
		for (i = 0; i < discoveryrequest->binding.ieee80211.wtpradioinformation->count; i++) {
 | 
							for (i = 0; i < packet->messageelements.ieee80211.wtpradioinformation->count; i++) {
 | 
				
			||||||
			struct capwap_80211_wtpradioinformation_element* radio;
 | 
								struct capwap_80211_wtpradioinformation_element* radio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			radio = (struct capwap_80211_wtpradioinformation_element*)capwap_array_get_item_pointer(discoveryrequest->binding.ieee80211.wtpradioinformation, i);
 | 
								radio = *(struct capwap_80211_wtpradioinformation_element**)capwap_array_get_item_pointer(packet->messageelements.ieee80211.wtpradioinformation, i);
 | 
				
			||||||
			capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_80211_WTPRADIOINFORMATION_ELEMENT(radio));
 | 
								capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, radio);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		capwap_logging_debug("Unknown capwap binding");
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Get information from any local address */
 | 
						/* Get information from any local address */
 | 
				
			||||||
@ -137,24 +132,24 @@ static struct capwap_build_packet* ac_create_discovery_response(struct capwap_bu
 | 
				
			|||||||
	
 | 
						
 | 
				
			||||||
		if (sessioncontrol->localaddress.ss_family == AF_INET) {
 | 
							if (sessioncontrol->localaddress.ss_family == AF_INET) {
 | 
				
			||||||
			struct capwap_controlipv4_element element;
 | 
								struct capwap_controlipv4_element element;
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			memcpy(&element.address, &((struct sockaddr_in*)&sessioncontrol->localaddress)->sin_addr, sizeof(struct in_addr));
 | 
								memcpy(&element.address, &((struct sockaddr_in*)&sessioncontrol->localaddress)->sin_addr, sizeof(struct in_addr));
 | 
				
			||||||
			element.wtpcount = sessioncontrol->count;
 | 
								element.wtpcount = sessioncontrol->count;
 | 
				
			||||||
			capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_CONTROLIPV4_ELEMENT(&element));
 | 
								capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV4, &element);
 | 
				
			||||||
		} else if (sessioncontrol->localaddress.ss_family == AF_INET6) {
 | 
							} else if (sessioncontrol->localaddress.ss_family == AF_INET6) {
 | 
				
			||||||
			struct capwap_controlipv6_element element;
 | 
								struct capwap_controlipv6_element element;
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			memcpy(&element.address, &((struct sockaddr_in6*)&sessioncontrol->localaddress)->sin6_addr, sizeof(struct in6_addr));
 | 
								memcpy(&element.address, &((struct sockaddr_in6*)&sessioncontrol->localaddress)->sin6_addr, sizeof(struct in6_addr));
 | 
				
			||||||
			element.wtpcount = sessioncontrol->count;
 | 
								element.wtpcount = sessioncontrol->count;
 | 
				
			||||||
			capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_CONTROLIPV6_ELEMENT(&element));
 | 
								capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV6, &element);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	capwap_list_free(controllist);	
 | 
						capwap_list_free(controllist);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */	/* TODO */
 | 
						/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */	/* TODO */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return responsepacket;
 | 
						return txmngpacket;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Cleanup info discovery */
 | 
					/* Cleanup info discovery */
 | 
				
			||||||
@ -167,21 +162,21 @@ static void ac_discovery_cleanup(void) {
 | 
				
			|||||||
static void ac_discovery_run(void) {
 | 
					static void ac_discovery_run(void) {
 | 
				
			||||||
	int sizedata;
 | 
						int sizedata;
 | 
				
			||||||
	struct capwap_list_item* itempacket;
 | 
						struct capwap_list_item* itempacket;
 | 
				
			||||||
	struct capwap_build_packet* buildpacket;
 | 
						struct ac_discovery_packet* acpacket;
 | 
				
			||||||
	struct ac_discovery_packet* packet;
 | 
						struct capwap_parsed_packet packet;
 | 
				
			||||||
	unsigned short binding;
 | 
						struct capwap_packet_rxmng* rxmngpacket;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	while (!g_ac_discovery.endthread) {
 | 
						while (!g_ac_discovery.endthread) {
 | 
				
			||||||
		/* Get packet */
 | 
							/* Get packet */
 | 
				
			||||||
		capwap_lock_enter(&g_ac_discovery.packetslock);
 | 
							capwap_lock_enter(&g_ac_discovery.packetslock);
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		itempacket = NULL; 
 | 
							itempacket = NULL; 
 | 
				
			||||||
		if (g_ac_discovery.packets->count > 0) {
 | 
							if (g_ac_discovery.packets->count > 0) {
 | 
				
			||||||
			itempacket = capwap_itemlist_remove_head(g_ac_discovery.packets);
 | 
								itempacket = capwap_itemlist_remove_head(g_ac_discovery.packets);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		capwap_lock_exit(&g_ac_discovery.packetslock);
 | 
							capwap_lock_exit(&g_ac_discovery.packetslock);
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
		if (!itempacket) {
 | 
							if (!itempacket) {
 | 
				
			||||||
			/* Wait packet with timeout*/
 | 
								/* Wait packet with timeout*/
 | 
				
			||||||
			if (!capwap_event_wait_timeout(&g_ac_discovery.waitpacket, AC_DISCOVERY_CLEANUP_TIMEOUT)) {
 | 
								if (!capwap_event_wait_timeout(&g_ac_discovery.waitpacket, AC_DISCOVERY_CLEANUP_TIMEOUT)) {
 | 
				
			||||||
@ -190,74 +185,56 @@ static void ac_discovery_run(void) {
 | 
				
			|||||||
			
 | 
								
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		/* */
 | 
							/* */
 | 
				
			||||||
		packet = (struct ac_discovery_packet*)itempacket->item;
 | 
							acpacket = (struct ac_discovery_packet*)itempacket->item;
 | 
				
			||||||
		sizedata = itempacket->itemsize - sizeof(struct ac_discovery_packet);
 | 
							sizedata = itempacket->itemsize - sizeof(struct ac_discovery_packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Parsing packet */
 | 
							/* Accept only discovery request don't fragment */
 | 
				
			||||||
		buildpacket = capwap_rx_packet_create(packet->data, sizedata, 1);
 | 
							rxmngpacket = capwap_packet_rxmng_create_message(1);
 | 
				
			||||||
		if (buildpacket) {
 | 
							if (capwap_packet_rxmng_add_recv_packet(rxmngpacket, acpacket->data, sizedata) == CAPWAP_RECEIVE_COMPLETE_PACKET) {
 | 
				
			||||||
			if (!capwap_build_packet_validate(buildpacket, NULL)) {
 | 
								/* Validate message */
 | 
				
			||||||
				struct capwap_element_discovery_request discoveryrequest;
 | 
								if (capwap_check_message_type(rxmngpacket) == VALID_MESSAGE_TYPE) {
 | 
				
			||||||
				
 | 
									/* Parsing packet */
 | 
				
			||||||
				/* */
 | 
									if (!capwap_parsing_packet(rxmngpacket, NULL, &packet)) {
 | 
				
			||||||
				binding = GET_WBID_HEADER(&buildpacket->header);
 | 
										/* Validate packet */
 | 
				
			||||||
				capwap_init_element_discovery_request(&discoveryrequest, binding);
 | 
										if (!capwap_validate_parsed_packet(&packet, NULL)) {
 | 
				
			||||||
				
 | 
											struct capwap_packet_txmng* txmngpacket;
 | 
				
			||||||
				/* Parsing elements list */
 | 
					 | 
				
			||||||
				if (capwap_parsing_element_discovery_request(&discoveryrequest, buildpacket->elementslist->first)) {
 | 
					 | 
				
			||||||
					struct capwap_build_packet* txpacket;
 | 
					 | 
				
			||||||
					capwap_fragment_packet_array* responsefragmentpacket = NULL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
					/* Creare discovery response */
 | 
											/* Creare discovery response */
 | 
				
			||||||
					txpacket = ac_create_discovery_response(buildpacket, &discoveryrequest, &packet->sender);
 | 
											txmngpacket = ac_create_discovery_response(&packet);
 | 
				
			||||||
					if (txpacket) {
 | 
											if (txmngpacket) {
 | 
				
			||||||
						int result = -1;
 | 
												struct capwap_list* responsefragmentpacket;
 | 
				
			||||||
						
 | 
					
 | 
				
			||||||
						if (!capwap_build_packet_validate(txpacket, NULL)) {
 | 
												/* Discovery response complete, get fragment packets */
 | 
				
			||||||
							responsefragmentpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
 | 
												responsefragmentpacket = capwap_list_create();
 | 
				
			||||||
							result = capwap_fragment_build_packet(txpacket, responsefragmentpacket, g_ac.mtu, g_ac_discovery.fragmentid);
 | 
												capwap_packet_txmng_get_fragment_packets(txmngpacket, responsefragmentpacket, g_ac_discovery.fragmentid);
 | 
				
			||||||
							if (result == 1) {
 | 
												if (responsefragmentpacket->count > 1) {
 | 
				
			||||||
								g_ac_discovery.fragmentid++;
 | 
													g_ac_discovery.fragmentid++;
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						} else {
 | 
					
 | 
				
			||||||
							capwap_logging_debug("Warning: build invalid discovery response packet");
 | 
												/* Free packets manager */
 | 
				
			||||||
						}
 | 
												capwap_packet_txmng_free(txmngpacket);
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
						capwap_build_packet_free(txpacket);
 | 
												/* Send discovery response to WTP */
 | 
				
			||||||
	
 | 
												if (!capwap_sendto_fragmentpacket(acpacket->sendsock, responsefragmentpacket, NULL, &acpacket->sender)) {
 | 
				
			||||||
						/* Send discovery response to WTP */
 | 
													capwap_logging_debug("Warning: error to send discovery response packet");
 | 
				
			||||||
						if (result >= 0) {
 | 
					 | 
				
			||||||
							int i;
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
							for (i = 0; i < responsefragmentpacket->count; i++) {
 | 
					 | 
				
			||||||
								struct capwap_packet* sendpacket = (struct capwap_packet*)capwap_array_get_item_pointer(responsefragmentpacket, i);
 | 
					 | 
				
			||||||
								ASSERT(sendpacket != NULL);
 | 
					 | 
				
			||||||
								
 | 
					 | 
				
			||||||
								if (!capwap_sendto(packet->sendsock, sendpacket->header, sendpacket->packetsize, NULL, &packet->sender)) {
 | 
					 | 
				
			||||||
									capwap_logging_debug("Warning: error to send discovery response packet");
 | 
					 | 
				
			||||||
									break;
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
												/* Don't buffering a packets sent */
 | 
				
			||||||
 | 
												capwap_list_free(responsefragmentpacket);
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					
 | 
					 | 
				
			||||||
					/* Don't buffering a packets sent */
 | 
					 | 
				
			||||||
					if (responsefragmentpacket) {
 | 
					 | 
				
			||||||
						capwap_fragment_free(responsefragmentpacket);
 | 
					 | 
				
			||||||
						capwap_array_free(responsefragmentpacket);
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				
 | 
					
 | 
				
			||||||
				/* Free discovery request */
 | 
									/* Free resource */
 | 
				
			||||||
				capwap_free_element_discovery_request(&discoveryrequest, binding);
 | 
									capwap_free_parsed_packet(&packet);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			/* */
 | 
					 | 
				
			||||||
			capwap_build_packet_free(buildpacket);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Free resource */
 | 
				
			||||||
 | 
							capwap_packet_rxmng_free(rxmngpacket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Free packet */
 | 
							/* Free packet */
 | 
				
			||||||
		capwap_itemlist_free(itempacket);
 | 
							capwap_itemlist_free(itempacket);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -58,44 +58,68 @@ static struct ac_session_t* ac_search_session_from_wtpaddress(struct sockaddr_st
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
static struct ac_session_t* ac_get_session_from_keepalive(void* buffer, int buffersize) {
 | 
					static struct ac_session_t* ac_get_session_from_keepalive(void* buffer, int buffersize) {
 | 
				
			||||||
 | 
						struct capwap_parsed_packet packet;
 | 
				
			||||||
 | 
						struct capwap_packet_rxmng* rxmngpacket;
 | 
				
			||||||
	struct ac_session_t* result = NULL;
 | 
						struct ac_session_t* result = NULL;
 | 
				
			||||||
	struct capwap_build_packet* buildpacket;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(buffer != NULL);
 | 
						ASSERT(buffer != NULL);
 | 
				
			||||||
	ASSERT(buffersize > 0);
 | 
						ASSERT(buffersize > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buildpacket = capwap_rx_packet_create(buffer, buffersize, 0);
 | 
						/* Build receive manager CAPWAP message */
 | 
				
			||||||
	if (buildpacket) {
 | 
						rxmngpacket = capwap_packet_rxmng_create_message(0);
 | 
				
			||||||
		struct capwap_sessionid_element sessionid;
 | 
						if (capwap_packet_rxmng_add_recv_packet(rxmngpacket, buffer, buffersize) != CAPWAP_RECEIVE_COMPLETE_PACKET) {
 | 
				
			||||||
		
 | 
							/* Accept only keep alive without fragmentation */
 | 
				
			||||||
		if (capwap_get_sessionid_from_keepalive(buildpacket, &sessionid)) {
 | 
							capwap_packet_rxmng_free(rxmngpacket);
 | 
				
			||||||
 | 
							capwap_logging_debug("Receive data keep alive packet fragmentated");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Validate message */
 | 
				
			||||||
 | 
						if (capwap_check_message_type(rxmngpacket) != VALID_MESSAGE_TYPE) {
 | 
				
			||||||
 | 
							/* Invalid message */
 | 
				
			||||||
 | 
							capwap_packet_rxmng_free(rxmngpacket);
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid data packet message type");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Parsing packet */
 | 
				
			||||||
 | 
						if (!capwap_parsing_packet(rxmngpacket, NULL, &packet)) {
 | 
				
			||||||
 | 
							/* Validate packet */
 | 
				
			||||||
 | 
							if (!capwap_validate_parsed_packet(&packet, NULL)) {
 | 
				
			||||||
			struct capwap_list_item* search;
 | 
								struct capwap_list_item* search;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ASSERT(packet.messageelements.sessionid != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			capwap_lock_enter(&g_ac.sessionslock);
 | 
								capwap_lock_enter(&g_ac.sessionslock);
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			search = g_ac.sessions->first;
 | 
								search = g_ac.sessions->first;
 | 
				
			||||||
			while (search != NULL) {
 | 
								while (search != NULL) {
 | 
				
			||||||
				struct ac_session_t* session = (struct ac_session_t*)search->item;
 | 
									struct ac_session_t* session = (struct ac_session_t*)search->item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				ASSERT(session != NULL);
 | 
									ASSERT(session != NULL);
 | 
				
			||||||
				
 | 
					
 | 
				
			||||||
				if (!memcmp(&sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
 | 
									if (!memcmp(packet.messageelements.sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
 | 
				
			||||||
					session->count++;
 | 
										session->count++;
 | 
				
			||||||
					result = session;
 | 
										result = session;
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				
 | 
					
 | 
				
			||||||
				search = search->next;	
 | 
									search = search->next;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			capwap_lock_exit(&g_ac.sessionslock);
 | 
								capwap_lock_exit(&g_ac.sessionslock);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								capwap_logging_debug("Failed validation parsed data packet");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		/* Free */
 | 
							capwap_logging_debug("Failed parsing data packet");
 | 
				
			||||||
		capwap_build_packet_free(buildpacket);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return result;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Free resource */
 | 
				
			||||||
 | 
						capwap_free_parsed_packet(&packet);
 | 
				
			||||||
 | 
						capwap_packet_rxmng_free(rxmngpacket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Close session */
 | 
					/* Close session */
 | 
				
			||||||
@ -117,7 +141,7 @@ static void ac_close_sessions() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		ac_close_session(session);
 | 
							ac_close_session(session);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		search = search->next;	
 | 
							search = search->next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	capwap_lock_exit(&g_ac.sessionslock);
 | 
						capwap_lock_exit(&g_ac.sessionslock);
 | 
				
			||||||
@ -246,7 +270,7 @@ static struct ac_session_t* ac_create_session(struct sockaddr_storage* wtpaddres
 | 
				
			|||||||
	int result;
 | 
						int result;
 | 
				
			||||||
	struct capwap_list_item* itemlist;
 | 
						struct capwap_list_item* itemlist;
 | 
				
			||||||
	struct ac_session_t* session;
 | 
						struct ac_session_t* session;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(acaddress != NULL);
 | 
						ASSERT(acaddress != NULL);
 | 
				
			||||||
	ASSERT(wtpaddress != NULL);
 | 
						ASSERT(wtpaddress != NULL);
 | 
				
			||||||
	ASSERT(ctrlsock != NULL);
 | 
						ASSERT(ctrlsock != NULL);
 | 
				
			||||||
@ -263,37 +287,36 @@ static struct ac_session_t* ac_create_session(struct sockaddr_storage* wtpaddres
 | 
				
			|||||||
	
 | 
						
 | 
				
			||||||
	/* Duplicate state for DFA */
 | 
						/* Duplicate state for DFA */
 | 
				
			||||||
	memcpy(&session->dfa, &g_ac.dfa, sizeof(struct ac_state));
 | 
						memcpy(&session->dfa, &g_ac.dfa, sizeof(struct ac_state));
 | 
				
			||||||
	session->dfa.acipv4list = capwap_array_clone(g_ac.dfa.acipv4list);
 | 
						session->dfa.acipv4list.addresses = capwap_array_clone(g_ac.dfa.acipv4list.addresses);
 | 
				
			||||||
	session->dfa.acipv6list = capwap_array_clone(g_ac.dfa.acipv6list);
 | 
						session->dfa.acipv6list.addresses = capwap_array_clone(g_ac.dfa.acipv6list.addresses);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	session->dfa.rfcRetransmitInterval = AC_DEFAULT_RETRANSMIT_INTERVAL;
 | 
						session->dfa.rfcRetransmitInterval = AC_DEFAULT_RETRANSMIT_INTERVAL;
 | 
				
			||||||
	session->dfa.rfcMaxRetransmit = AC_MAX_RETRANSMIT;
 | 
						session->dfa.rfcMaxRetransmit = AC_MAX_RETRANSMIT;
 | 
				
			||||||
	session->dfa.rfcDTLSSessionDelete = AC_DEFAULT_DTLS_SESSION_DELETE;
 | 
						session->dfa.rfcDTLSSessionDelete = AC_DEFAULT_DTLS_SESSION_DELETE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Add default AC list if empty*/
 | 
						/* Add default AC list if empty*/
 | 
				
			||||||
	if ((session->dfa.acipv4list->count == 0) && (session->dfa.acipv6list->count == 0)) {
 | 
						if ((session->dfa.acipv4list.addresses->count == 0) && (session->dfa.acipv6list.addresses->count == 0)) {
 | 
				
			||||||
		if (session->acctrladdress.ss_family == AF_INET) {
 | 
							if (session->acctrladdress.ss_family == AF_INET) {
 | 
				
			||||||
			struct capwap_acipv4list_element* acip = (struct capwap_acipv4list_element*)capwap_array_get_item_pointer(session->dfa.acipv4list, 0);
 | 
								struct in_addr* acip = (struct in_addr*)capwap_array_get_item_pointer(session->dfa.acipv4list.addresses, 0);
 | 
				
			||||||
			memcpy(&acip->address, &((struct sockaddr_in*)&session->acctrladdress)->sin_addr, sizeof(struct in_addr));
 | 
								memcpy(acip, &((struct sockaddr_in*)&session->acctrladdress)->sin_addr, sizeof(struct in_addr));
 | 
				
			||||||
		} else if (session->acctrladdress.ss_family == AF_INET6) {
 | 
							} else if (session->acctrladdress.ss_family == AF_INET6) {
 | 
				
			||||||
			struct capwap_acipv6list_element* acip = (struct capwap_acipv6list_element*)capwap_array_get_item_pointer(session->dfa.acipv6list, 0);
 | 
								struct in6_addr* acip = (struct in6_addr*)capwap_array_get_item_pointer(session->dfa.acipv6list.addresses, 0);
 | 
				
			||||||
			memcpy(&acip->address, &((struct sockaddr_in6*)&session->acctrladdress)->sin6_addr, sizeof(struct in6_addr));
 | 
								memcpy(acip, &((struct sockaddr_in6*)&session->acctrladdress)->sin6_addr, sizeof(struct in6_addr));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	/* Init */
 | 
						/* Init */
 | 
				
			||||||
	capwap_event_init(&session->waitpacket);
 | 
						capwap_event_init(&session->waitpacket);
 | 
				
			||||||
	capwap_lock_init(&session->packetslock);
 | 
						capwap_lock_init(&session->packetslock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	session->controlpackets = capwap_list_create();
 | 
						session->controlpackets = capwap_list_create();
 | 
				
			||||||
	session->datapackets = capwap_list_create();
 | 
						session->datapackets = capwap_list_create();
 | 
				
			||||||
	session->requestfragmentpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
 | 
						session->requestfragmentpacket = capwap_list_create();
 | 
				
			||||||
	session->responsefragmentpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
 | 
						session->responsefragmentpacket = capwap_list_create();
 | 
				
			||||||
	session->rxfragmentpacket = capwap_defragment_init_list();
 | 
					
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	session->mtu = g_ac.mtu;
 | 
						session->mtu = g_ac.mtu;
 | 
				
			||||||
	session->state = CAPWAP_IDLE_STATE;
 | 
						session->state = CAPWAP_IDLE_STATE;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	/* Update session list */
 | 
						/* Update session list */
 | 
				
			||||||
	capwap_lock_enter(&g_ac.sessionslock);
 | 
						capwap_lock_enter(&g_ac.sessionslock);
 | 
				
			||||||
	capwap_itemlist_insert_after(g_ac.sessions, NULL, itemlist);
 | 
						capwap_itemlist_insert_after(g_ac.sessions, NULL, itemlist);
 | 
				
			||||||
@ -323,10 +346,10 @@ static struct ac_session_t* ac_create_session(struct sockaddr_storage* wtpaddres
 | 
				
			|||||||
/* Update statistics */
 | 
					/* Update statistics */
 | 
				
			||||||
void ac_update_statistics(void) {
 | 
					void ac_update_statistics(void) {
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	g_ac.descriptor.station = 0; /* TODO */
 | 
						g_ac.descriptor.stations = 0; /* TODO */
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_lock_enter(&g_ac.sessionslock);
 | 
						capwap_lock_enter(&g_ac.sessionslock);
 | 
				
			||||||
	g_ac.descriptor.wtp = g_ac.sessions->count;
 | 
						g_ac.descriptor.activewtp = g_ac.sessions->count;
 | 
				
			||||||
	capwap_lock_exit(&g_ac.sessionslock);
 | 
						capwap_lock_exit(&g_ac.sessionslock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -344,7 +367,7 @@ int ac_execute(void) {
 | 
				
			|||||||
	int result = CAPWAP_SUCCESSFUL;
 | 
						int result = CAPWAP_SUCCESSFUL;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	int index;
 | 
						int index;
 | 
				
			||||||
	int check;				
 | 
						int check;
 | 
				
			||||||
	int isctrlsocket = 0;
 | 
						int isctrlsocket = 0;
 | 
				
			||||||
	struct sockaddr_storage recvfromaddr;
 | 
						struct sockaddr_storage recvfromaddr;
 | 
				
			||||||
	struct sockaddr_storage recvtoaddr;
 | 
						struct sockaddr_storage recvtoaddr;
 | 
				
			||||||
@ -400,15 +423,15 @@ int ac_execute(void) {
 | 
				
			|||||||
					if (getsockname(fds[index].fd, (struct sockaddr*)&sockinfo, &sockinfolen) < 0) {
 | 
										if (getsockname(fds[index].fd, (struct sockaddr*)&sockinfo, &sockinfolen) < 0) {
 | 
				
			||||||
						break; 
 | 
											break; 
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					
 | 
					
 | 
				
			||||||
					CAPWAP_SET_NETWORK_PORT(&recvtoaddr, CAPWAP_GET_NETWORK_PORT(&sockinfo));
 | 
										CAPWAP_SET_NETWORK_PORT(&recvtoaddr, CAPWAP_GET_NETWORK_PORT(&sockinfo));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			/* Search the AC session */
 | 
								/* Search the AC session */
 | 
				
			||||||
			isctrlsocket = ((index < (fdscount / 2)) ? 1 : 0);
 | 
								isctrlsocket = ((index < (fdscount / 2)) ? 1 : 0);
 | 
				
			||||||
			session = ac_search_session_from_wtpaddress(&recvfromaddr, isctrlsocket);
 | 
								session = ac_search_session_from_wtpaddress(&recvfromaddr, isctrlsocket);
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			if (session) {
 | 
								if (session) {
 | 
				
			||||||
				/* Add packet*/
 | 
									/* Add packet*/
 | 
				
			||||||
				ac_session_add_packet(session, buffer, buffersize, isctrlsocket, 0);
 | 
									ac_session_add_packet(session, buffer, buffersize, isctrlsocket, 0);
 | 
				
			||||||
@ -418,38 +441,38 @@ int ac_execute(void) {
 | 
				
			|||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				if (isctrlsocket) {
 | 
									if (isctrlsocket) {
 | 
				
			||||||
					unsigned short sessioncount;
 | 
										unsigned short sessioncount;
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
					/* Get current session number */
 | 
										/* Get current session number */
 | 
				
			||||||
					capwap_lock_enter(&g_ac.sessionslock);
 | 
										capwap_lock_enter(&g_ac.sessionslock);
 | 
				
			||||||
					sessioncount = g_ac.sessions->count;
 | 
										sessioncount = g_ac.sessions->count;
 | 
				
			||||||
					capwap_lock_exit(&g_ac.sessionslock);
 | 
										capwap_lock_exit(&g_ac.sessionslock);
 | 
				
			||||||
					
 | 
					
 | 
				
			||||||
					/* PreParsing packet for reduce a DoS attack */
 | 
										/* PreParsing packet for reduce a DoS attack */
 | 
				
			||||||
					check = capwap_sanity_check(isctrlsocket, CAPWAP_UNDEF_STATE, buffer, buffersize, g_ac.enabledtls, 0);
 | 
										check = capwap_sanity_check(isctrlsocket, CAPWAP_UNDEF_STATE, buffer, buffersize, g_ac.enabledtls, 0);
 | 
				
			||||||
					if (check == CAPWAP_PLAIN_PACKET) {
 | 
										if (check == CAPWAP_PLAIN_PACKET) {
 | 
				
			||||||
						struct capwap_header* header = (struct capwap_header*)buffer;
 | 
											struct capwap_header* header = (struct capwap_header*)buffer;
 | 
				
			||||||
						
 | 
					
 | 
				
			||||||
						/* Accepted only packet without fragmentation */
 | 
											/* Accepted only packet without fragmentation */
 | 
				
			||||||
						if (!IS_FLAG_F_HEADER(header)) {
 | 
											if (!IS_FLAG_F_HEADER(header)) {
 | 
				
			||||||
							int headersize = GET_HLEN_HEADER(header) * 4;
 | 
												int headersize = GET_HLEN_HEADER(header) * 4;
 | 
				
			||||||
							if (buffersize >= (headersize + sizeof(struct capwap_control_message))) {
 | 
												if (buffersize >= (headersize + sizeof(struct capwap_control_message))) {
 | 
				
			||||||
								struct capwap_control_message* control = (struct capwap_control_message*)((char*)buffer + headersize);
 | 
													struct capwap_control_message* control = (struct capwap_control_message*)((char*)buffer + headersize);
 | 
				
			||||||
								unsigned long type = ntohl(control->type);
 | 
													unsigned long type = ntohl(control->type);
 | 
				
			||||||
								
 | 
					
 | 
				
			||||||
								if (type == CAPWAP_DISCOVERY_REQUEST) {
 | 
													if (type == CAPWAP_DISCOVERY_REQUEST) {
 | 
				
			||||||
									if (sessioncount < g_ac.descriptor.wtplimit) {
 | 
														if (sessioncount < g_ac.descriptor.maxwtp) {
 | 
				
			||||||
										ac_discovery_add_packet(buffer, buffersize, fds[index].fd, &recvfromaddr);
 | 
															ac_discovery_add_packet(buffer, buffersize, fds[index].fd, &recvfromaddr);
 | 
				
			||||||
									}
 | 
														}
 | 
				
			||||||
								} else if (!g_ac.enabledtls && (type == CAPWAP_JOIN_REQUEST)) {
 | 
													} else if (!g_ac.enabledtls && (type == CAPWAP_JOIN_REQUEST)) {
 | 
				
			||||||
									if (sessioncount < g_ac.descriptor.wtplimit) {
 | 
														if (sessioncount < g_ac.descriptor.maxwtp) {
 | 
				
			||||||
										/* Retrive socket info */
 | 
															/* Retrive socket info */
 | 
				
			||||||
										capwap_get_network_socket(&g_ac.net, &ctrlsock, fds[index].fd);
 | 
															capwap_get_network_socket(&g_ac.net, &ctrlsock, fds[index].fd);
 | 
				
			||||||
										
 | 
					
 | 
				
			||||||
										/* Create a new session */
 | 
															/* Create a new session */
 | 
				
			||||||
										session = ac_create_session(&recvfromaddr, &recvtoaddr, &ctrlsock);
 | 
															session = ac_create_session(&recvfromaddr, &recvtoaddr, &ctrlsock);
 | 
				
			||||||
										if (session) {
 | 
															if (session) {
 | 
				
			||||||
											ac_session_add_packet(session, buffer, buffersize, isctrlsocket, 1);
 | 
																ac_session_add_packet(session, buffer, buffersize, isctrlsocket, 1);
 | 
				
			||||||
									
 | 
					
 | 
				
			||||||
											/* Release reference */
 | 
																/* Release reference */
 | 
				
			||||||
											ac_session_release_reference(session);
 | 
																ac_session_release_reference(session);
 | 
				
			||||||
										}
 | 
															}
 | 
				
			||||||
@ -459,7 +482,7 @@ int ac_execute(void) {
 | 
				
			|||||||
						}
 | 
											}
 | 
				
			||||||
					} else if (check == CAPWAP_DTLS_PACKET) {
 | 
										} else if (check == CAPWAP_DTLS_PACKET) {
 | 
				
			||||||
						/* Need create a new sessione for check if it is a valid DTLS handshake */
 | 
											/* Need create a new sessione for check if it is a valid DTLS handshake */
 | 
				
			||||||
						if (sessioncount < g_ac.descriptor.wtplimit) {
 | 
											if (sessioncount < g_ac.descriptor.maxwtp) {
 | 
				
			||||||
							/* TODO prevent dos attack add filtering ip for multiple error */
 | 
												/* TODO prevent dos attack add filtering ip for multiple error */
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
							/* Retrive socket info */
 | 
												/* Retrive socket info */
 | 
				
			||||||
@ -512,7 +535,7 @@ int ac_execute(void) {
 | 
				
			|||||||
		
 | 
							
 | 
				
			||||||
		/* Wait that list is changed */
 | 
							/* Wait that list is changed */
 | 
				
			||||||
		capwap_logging_debug("Waiting for %d session terminate", count);
 | 
							capwap_logging_debug("Waiting for %d session terminate", count);
 | 
				
			||||||
		capwap_event_wait(&g_ac.changesessionlist);	
 | 
							capwap_event_wait(&g_ac.changesessionlist);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Free handshark session */
 | 
						/* Free handshark session */
 | 
				
			||||||
 | 
				
			|||||||
@ -27,6 +27,11 @@ static int ac_network_read(struct ac_session_t* session, void* buffer, int lengt
 | 
				
			|||||||
			struct capwap_list_item* itempacket;
 | 
								struct capwap_list_item* itempacket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			*isctrlpacket = ((session->controlpackets->count > 0) ? 1 : 0);
 | 
								*isctrlpacket = ((session->controlpackets->count > 0) ? 1 : 0);
 | 
				
			||||||
 | 
								if (*isctrlpacket) {
 | 
				
			||||||
 | 
									capwap_logging_debug("Receive control packet");
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									capwap_logging_debug("Receive data packet");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Get packet */
 | 
								/* Get packet */
 | 
				
			||||||
			itempacket = capwap_itemlist_remove_head((*isctrlpacket ? session->controlpackets : session->datapackets));
 | 
								itempacket = capwap_itemlist_remove_head((*isctrlpacket ? session->controlpackets : session->datapackets));
 | 
				
			||||||
@ -70,7 +75,7 @@ static int ac_network_read(struct ac_session_t* session, void* buffer, int lengt
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			return result;
 | 
								return result;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		capwap_lock_exit(&session->packetslock);
 | 
							capwap_lock_exit(&session->packetslock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Update timeout */
 | 
							/* Update timeout */
 | 
				
			||||||
@ -88,7 +93,7 @@ static int ac_network_read(struct ac_session_t* session, void* buffer, int lengt
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
static int ac_dfa_execute(struct ac_session_t* session, struct capwap_packet* packet) {
 | 
					static int ac_dfa_execute(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
				
			||||||
	int action = AC_DFA_ACCEPT_PACKET;
 | 
						int action = AC_DFA_ACCEPT_PACKET;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
@ -366,12 +371,47 @@ static int ac_dfa_execute(struct ac_session_t* session, struct capwap_packet* pa
 | 
				
			|||||||
	return action;
 | 
						return action;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					static struct capwap_packet_rxmng* ac_get_packet_rxmng(struct ac_session_t* session, int isctrlmsg) {
 | 
				
			||||||
 | 
						struct capwap_packet_rxmng* rxmngpacket = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (isctrlmsg) {
 | 
				
			||||||
 | 
							if (!session->rxmngctrlpacket) {
 | 
				
			||||||
 | 
								session->rxmngctrlpacket = capwap_packet_rxmng_create_message(1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							rxmngpacket = session->rxmngctrlpacket;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if (!session->rxmngdatapacket) {
 | 
				
			||||||
 | 
								session->rxmngdatapacket = capwap_packet_rxmng_create_message(0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							rxmngpacket = session->rxmngdatapacket;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rxmngpacket;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					static void ac_free_packet_rxmng(struct ac_session_t* session, int isctrlmsg) {
 | 
				
			||||||
 | 
						if (isctrlmsg && session->rxmngctrlpacket) {
 | 
				
			||||||
 | 
							capwap_packet_rxmng_free(session->rxmngctrlpacket);
 | 
				
			||||||
 | 
							session->rxmngctrlpacket = NULL;
 | 
				
			||||||
 | 
						} else if (!isctrlmsg && session->rxmngdatapacket) {
 | 
				
			||||||
 | 
							capwap_packet_rxmng_free(session->rxmngdatapacket);
 | 
				
			||||||
 | 
							session->rxmngdatapacket = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
static void ac_session_run(struct ac_session_t* session) {
 | 
					static void ac_session_run(struct ac_session_t* session) {
 | 
				
			||||||
 | 
						int res;
 | 
				
			||||||
	int check;
 | 
						int check;
 | 
				
			||||||
	int length;
 | 
						int length;
 | 
				
			||||||
	int isctrlsocket;
 | 
						int isctrlsocket;
 | 
				
			||||||
	int action = AC_DFA_ACCEPT_PACKET;
 | 
						struct capwap_connection connection;
 | 
				
			||||||
	char buffer[CAPWAP_MAX_PACKET_SIZE];
 | 
						char buffer[CAPWAP_MAX_PACKET_SIZE];
 | 
				
			||||||
 | 
						int action = AC_DFA_ACCEPT_PACKET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(session != NULL);
 | 
						ASSERT(session != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -402,35 +442,66 @@ static void ac_session_run(struct ac_session_t* session) {
 | 
				
			|||||||
					/* Check generic capwap packet */
 | 
										/* Check generic capwap packet */
 | 
				
			||||||
					check = capwap_sanity_check(isctrlsocket, CAPWAP_UNDEF_STATE, buffer, length, 0, 0);
 | 
										check = capwap_sanity_check(isctrlsocket, CAPWAP_UNDEF_STATE, buffer, length, 0, 0);
 | 
				
			||||||
					if (check == CAPWAP_PLAIN_PACKET) {
 | 
										if (check == CAPWAP_PLAIN_PACKET) {
 | 
				
			||||||
						struct capwap_packet packet;
 | 
											struct capwap_parsed_packet packet;
 | 
				
			||||||
						
 | 
											struct capwap_packet_rxmng* rxmngpacket;
 | 
				
			||||||
						check = capwap_defragment_packets(&session->wtpctrladdress, buffer, length, session->rxfragmentpacket, &packet);
 | 
					
 | 
				
			||||||
 | 
											/* Defragment management */
 | 
				
			||||||
 | 
											rxmngpacket = ac_get_packet_rxmng(session, isctrlsocket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											/* If request, defragmentation packet */
 | 
				
			||||||
 | 
											check = capwap_packet_rxmng_add_recv_packet(rxmngpacket, buffer, length);
 | 
				
			||||||
						if (check == CAPWAP_RECEIVE_COMPLETE_PACKET) {
 | 
											if (check == CAPWAP_RECEIVE_COMPLETE_PACKET) {
 | 
				
			||||||
							int ignorepacket = 0;
 | 
												int ignorepacket = 0;
 | 
				
			||||||
							
 | 
					
 | 
				
			||||||
 | 
												/* Receive all fragment */
 | 
				
			||||||
 | 
												memcpy(&connection.socket, (isctrlsocket ? &session->ctrlsocket : &session->datasocket), sizeof(struct capwap_socket));
 | 
				
			||||||
 | 
												memcpy(&connection.localaddr, (isctrlsocket ? &session->acctrladdress : &session->acdataaddress), sizeof(struct sockaddr_storage));
 | 
				
			||||||
 | 
												memcpy(&connection.remoteaddr, (isctrlsocket ? &session->wtpctrladdress : &session->wtpdataaddress), sizeof(struct sockaddr_storage));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							if (isctrlsocket) {
 | 
												if (isctrlsocket) {
 | 
				
			||||||
								/* Check for already response to packet */
 | 
													if (!capwap_recv_retrasmitted_request(&session->ctrldtls, rxmngpacket, &connection, session->lastrecvpackethash, session->responsefragmentpacket)) {
 | 
				
			||||||
								if (capwap_recv_retrasmitted_request(&session->ctrldtls, &packet, session->remoteseqnumber, session->lastrecvpackethash, &session->ctrlsocket, session->responsefragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
 | 
														/* Check message type */
 | 
				
			||||||
									ignorepacket = 1;
 | 
														res = capwap_check_message_type(rxmngpacket);
 | 
				
			||||||
								}
 | 
														if (res != VALID_MESSAGE_TYPE) {
 | 
				
			||||||
								
 | 
															if (res == INVALID_REQUEST_MESSAGE_TYPE) {
 | 
				
			||||||
								/* Check message type */
 | 
																/*TODO wtp_send_invalid_request(rxmngpacket, &connection);*/
 | 
				
			||||||
								if (!capwap_check_message_type(&session->ctrldtls, &packet, session->mtu)) {
 | 
															}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
															ignorepacket = 1;
 | 
				
			||||||
 | 
															capwap_logging_debug("Invalid message type");
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													} else {
 | 
				
			||||||
									ignorepacket = 1;
 | 
														ignorepacket = 1;
 | 
				
			||||||
 | 
														capwap_logging_debug("Retrasmitted packet");
 | 
				
			||||||
								}
 | 
													}
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							
 | 
					
 | 
				
			||||||
 | 
												/* Parsing packet */
 | 
				
			||||||
 | 
												if (!ignorepacket) {
 | 
				
			||||||
 | 
													if (!capwap_parsing_packet(rxmngpacket, &connection, &packet)) {
 | 
				
			||||||
 | 
														/* Validate packet */
 | 
				
			||||||
 | 
														if (capwap_validate_parsed_packet(&packet, NULL)) {
 | 
				
			||||||
 | 
															/* TODO gestione errore risposta */
 | 
				
			||||||
 | 
															ignorepacket = 1;
 | 
				
			||||||
 | 
															capwap_logging_debug("Failed validation parsed packet");
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													} else {
 | 
				
			||||||
 | 
														ignorepacket = 1;
 | 
				
			||||||
 | 
														capwap_logging_debug("Failed parsing packet");
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							/* */
 | 
												/* */
 | 
				
			||||||
							if (!ignorepacket && (action == AC_DFA_ACCEPT_PACKET)) {
 | 
												if (!ignorepacket && (action == AC_DFA_ACCEPT_PACKET)) {
 | 
				
			||||||
								memcpy(&packet.socket, (isctrlsocket ? &session->ctrlsocket : &session->datasocket), sizeof(struct capwap_socket));
 | 
					 | 
				
			||||||
								action = ac_dfa_execute(session, &packet);
 | 
													action = ac_dfa_execute(session, &packet);
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							
 | 
					
 | 
				
			||||||
							/* Free packet */
 | 
												/* Free memory */
 | 
				
			||||||
							capwap_free_packet(&packet);
 | 
												capwap_free_parsed_packet(&packet);
 | 
				
			||||||
 | 
												ac_free_packet_rxmng(session, isctrlsocket);
 | 
				
			||||||
						} else if (check != CAPWAP_REQUEST_MORE_FRAGMENT) {
 | 
											} else if (check != CAPWAP_REQUEST_MORE_FRAGMENT) {
 | 
				
			||||||
							/* Discard fragments */
 | 
												/* Discard fragments */
 | 
				
			||||||
							capwap_defragment_remove_sender(session->rxfragmentpacket, &session->wtpctrladdress);
 | 
												ac_free_packet_rxmng(session, isctrlsocket);
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -508,27 +579,27 @@ int ac_session_release_reference(struct ac_session_t* session) {
 | 
				
			|||||||
				capwap_lock_exit(&session->packetslock);
 | 
									capwap_lock_exit(&session->packetslock);
 | 
				
			||||||
				capwap_list_free(session->controlpackets);
 | 
									capwap_list_free(session->controlpackets);
 | 
				
			||||||
				capwap_list_free(session->datapackets);
 | 
									capwap_list_free(session->datapackets);
 | 
				
			||||||
				capwap_defragment_free_list(session->rxfragmentpacket);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/* Free fragments packet */
 | 
									/* Free fragments packet */
 | 
				
			||||||
				capwap_fragment_free(session->requestfragmentpacket);
 | 
									ac_free_packet_rxmng(session, 1);
 | 
				
			||||||
				capwap_fragment_free(session->responsefragmentpacket);
 | 
									ac_free_packet_rxmng(session, 0);
 | 
				
			||||||
				capwap_array_free(session->requestfragmentpacket);
 | 
					
 | 
				
			||||||
				capwap_array_free(session->responsefragmentpacket);
 | 
									capwap_list_free(session->requestfragmentpacket);
 | 
				
			||||||
 | 
									capwap_list_free(session->responsefragmentpacket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/* Free DFA resource */
 | 
									/* Free DFA resource */
 | 
				
			||||||
				capwap_array_free(session->dfa.acipv4list);
 | 
									capwap_array_free(session->dfa.acipv4list.addresses);
 | 
				
			||||||
				capwap_array_free(session->dfa.acipv6list);
 | 
									capwap_array_free(session->dfa.acipv6list.addresses);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/* Remove item from list */
 | 
									/* Remove item from list */
 | 
				
			||||||
				remove = 1;
 | 
									remove = 1;
 | 
				
			||||||
				capwap_itemlist_free(capwap_itemlist_remove(g_ac.sessions, search));
 | 
									capwap_itemlist_free(capwap_itemlist_remove(g_ac.sessions, search));
 | 
				
			||||||
				capwap_event_signal(&g_ac.changesessionlist);
 | 
									capwap_event_signal(&g_ac.changesessionlist);
 | 
				
			||||||
				
 | 
					
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
			search = search->next;	
 | 
								search = search->next;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -547,7 +618,7 @@ void* ac_session_thread(void* param) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* Thread exit */
 | 
						/* Thread exit */
 | 
				
			||||||
	pthread_exit(NULL);
 | 
						pthread_exit(NULL);
 | 
				
			||||||
	return NULL;	
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
@ -596,22 +667,22 @@ void ac_get_control_information(struct capwap_list* controllist) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	capwap_lock_exit(&g_ac.sessionslock);		
 | 
						capwap_lock_exit(&g_ac.sessionslock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void ac_free_reference_last_request(struct ac_session_t* session) {
 | 
					void ac_free_reference_last_request(struct ac_session_t* session) {
 | 
				
			||||||
	ASSERT(session);
 | 
						ASSERT(session);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	capwap_fragment_free(session->requestfragmentpacket);
 | 
						capwap_list_flush(session->requestfragmentpacket);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void ac_free_reference_last_response(struct ac_session_t* session) {
 | 
					void ac_free_reference_last_response(struct ac_session_t* session) {
 | 
				
			||||||
	ASSERT(session);
 | 
						ASSERT(session);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	capwap_fragment_free(session->responsefragmentpacket);
 | 
						capwap_list_flush(session->responsefragmentpacket);
 | 
				
			||||||
	memset(&session->lastrecvpackethash[0], 0, sizeof(session->lastrecvpackethash));
 | 
						memset(&session->lastrecvpackethash[0], 0, sizeof(session->lastrecvpackethash));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -51,9 +51,10 @@ struct ac_session_t {
 | 
				
			|||||||
	unsigned char remoteseqnumber;
 | 
						unsigned char remoteseqnumber;
 | 
				
			||||||
	unsigned short mtu;
 | 
						unsigned short mtu;
 | 
				
			||||||
	unsigned short fragmentid;
 | 
						unsigned short fragmentid;
 | 
				
			||||||
	capwap_fragment_list* rxfragmentpacket;
 | 
						struct capwap_packet_rxmng* rxmngctrlpacket;
 | 
				
			||||||
	capwap_fragment_packet_array* requestfragmentpacket;
 | 
						struct capwap_packet_rxmng* rxmngdatapacket;
 | 
				
			||||||
	capwap_fragment_packet_array* responsefragmentpacket;
 | 
						struct capwap_list* requestfragmentpacket;
 | 
				
			||||||
 | 
						struct capwap_list* responsefragmentpacket;
 | 
				
			||||||
	unsigned char lastrecvpackethash[16];
 | 
						unsigned char lastrecvpackethash[16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unsigned long state;
 | 
						unsigned long state;
 | 
				
			||||||
@ -73,40 +74,40 @@ void ac_free_reference_last_request(struct ac_session_t* session);
 | 
				
			|||||||
void ac_free_reference_last_response(struct ac_session_t* session);
 | 
					void ac_free_reference_last_response(struct ac_session_t* session);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_join(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int ac_dfa_state_postjoin(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_postjoin(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int ac_dfa_state_join_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_join_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_bio_send(struct capwap_dtls* dtls, char* buffer, int length, void* param);
 | 
					int ac_bio_send(struct capwap_dtls* dtls, char* buffer, int length, void* param);
 | 
				
			||||||
int ac_dfa_state_dtlssetup(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_dtlssetup(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int ac_dfa_state_dtlsconnect(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_dtlsconnect(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int ac_dfa_state_dtlsconnect_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_dtlsconnect_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_configure(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_configure(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int ac_dfa_state_configure_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_configure_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_datacheck(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_datacheck(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int ac_dfa_state_datacheck_to_run(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_datacheck_to_run(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int ac_dfa_state_datacheck_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_datacheck_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_imagedata(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_imagedata(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int ac_dfa_state_imagedata_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_imagedata_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_run(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_run(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int ac_dfa_state_run_to_reset(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_run_to_reset(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int ac_dfa_state_run_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_run_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_reset(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_reset(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int ac_dfa_state_reset_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_reset_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int ac_dfa_state_teardown(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_teardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int ac_dfa_state_dead(struct ac_session_t* session, struct capwap_packet* packet);
 | 
					int ac_dfa_state_dead(struct ac_session_t* session, struct capwap_parsed_packet* packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __AC_SESSION_HEADER__ */
 | 
					#endif /* __AC_SESSION_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -295,6 +295,12 @@ int capwap_crypt_init() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_crypt_free() {
 | 
					void capwap_crypt_free() {
 | 
				
			||||||
 | 
						/* Clear error queue */
 | 
				
			||||||
 | 
						ERR_clear_error();
 | 
				
			||||||
 | 
						ERR_remove_state(0);
 | 
				
			||||||
 | 
						ERR_remove_thread_state(NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* */
 | 
				
			||||||
#ifdef CAPWAP_MULTITHREADING_ENABLE
 | 
					#ifdef CAPWAP_MULTITHREADING_ENABLE
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int numlocks;
 | 
						int numlocks;
 | 
				
			||||||
@ -313,20 +319,17 @@ void capwap_crypt_free() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	capwap_free(l_mutex_buffer);
 | 
						capwap_free(l_mutex_buffer);
 | 
				
			||||||
	l_mutex_buffer = NULL;
 | 
						l_mutex_buffer = NULL;
 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	ERR_remove_state(0);
 | 
					 | 
				
			||||||
	ERR_free_strings();
 | 
						ERR_free_strings();
 | 
				
			||||||
	
 | 
						RAND_cleanup();
 | 
				
			||||||
	ENGINE_cleanup();
 | 
						ENGINE_cleanup();
 | 
				
			||||||
	EVP_cleanup();
 | 
						EVP_cleanup();
 | 
				
			||||||
	
 | 
						OBJ_cleanup();
 | 
				
			||||||
	CONF_modules_finish();
 | 
						CONF_modules_finish();
 | 
				
			||||||
	CONF_modules_free();
 | 
						CONF_modules_free();
 | 
				
			||||||
	CONF_modules_unload(1);
 | 
						CONF_modules_unload(1);
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	CRYPTO_cleanup_all_ex_data();
 | 
						CRYPTO_cleanup_all_ex_data();
 | 
				
			||||||
	sk_SSL_COMP_free (SSL_COMP_get_compression_methods()); 
 | 
						sk_SSL_COMP_free (SSL_COMP_get_compression_methods()); 
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -637,7 +640,9 @@ int capwap_crypt_createsession(struct capwap_dtls* dtls, int sessiontype, struct
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	SSL_set_read_ahead((SSL*)dtls->sslsession, 1);
 | 
						SSL_set_read_ahead((SSL*)dtls->sslsession, 1);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
 | 
						/* */
 | 
				
			||||||
 | 
						ERR_clear_error();
 | 
				
			||||||
	if (dtlscontext->type == CAPWAP_DTLS_SERVER) {
 | 
						if (dtlscontext->type == CAPWAP_DTLS_SERVER) {
 | 
				
			||||||
		SSL_set_accept_state((SSL*)dtls->sslsession);
 | 
							SSL_set_accept_state((SSL*)dtls->sslsession);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
@ -706,7 +711,7 @@ int capwap_crypt_open(struct capwap_dtls* dtls, struct sockaddr_storage* peeradd
 | 
				
			|||||||
void capwap_crypt_close(struct capwap_dtls* dtls) {
 | 
					void capwap_crypt_close(struct capwap_dtls* dtls) {
 | 
				
			||||||
	ASSERT(dtls != NULL);
 | 
						ASSERT(dtls != NULL);
 | 
				
			||||||
	ASSERT(dtls->enable != 0);
 | 
						ASSERT(dtls->enable != 0);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if ((dtls->action == CAPWAP_DTLS_ACTION_DATA) || (dtls->action == CAPWAP_DTLS_ACTION_SHUTDOWN)) {
 | 
						if ((dtls->action == CAPWAP_DTLS_ACTION_DATA) || (dtls->action == CAPWAP_DTLS_ACTION_SHUTDOWN)) {
 | 
				
			||||||
		SSL_shutdown((SSL*)dtls->sslsession);
 | 
							SSL_shutdown((SSL*)dtls->sslsession);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -751,7 +756,7 @@ void capwap_crypt_change_dtls(struct capwap_dtls* dtls, struct capwap_dtls* newd
 | 
				
			|||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_crypt_freesession(struct capwap_dtls* dtls) {
 | 
					void capwap_crypt_freesession(struct capwap_dtls* dtls) {
 | 
				
			||||||
	ASSERT(dtls != NULL);
 | 
						ASSERT(dtls != NULL);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	/* Free SSL session */
 | 
						/* Free SSL session */
 | 
				
			||||||
	if (dtls->sslsession) {
 | 
						if (dtls->sslsession) {
 | 
				
			||||||
		struct capwap_app_data* appdata = (struct capwap_app_data*)SSL_get_ex_data(dtls->sslsession, 0);
 | 
							struct capwap_app_data* appdata = (struct capwap_app_data*)SSL_get_ex_data(dtls->sslsession, 0);
 | 
				
			||||||
@ -761,7 +766,13 @@ void capwap_crypt_freesession(struct capwap_dtls* dtls) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		SSL_free((SSL*)dtls->sslsession);
 | 
							SSL_free((SSL*)dtls->sslsession);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
 | 
						/* */
 | 
				
			||||||
 | 
						ERR_clear_error();
 | 
				
			||||||
 | 
						ERR_remove_state(0);
 | 
				
			||||||
 | 
						ERR_remove_thread_state(NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* */
 | 
				
			||||||
	memset(dtls, 0, sizeof(struct capwap_dtls));
 | 
						memset(dtls, 0, sizeof(struct capwap_dtls));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -785,6 +796,31 @@ int capwap_crypt_sendto(struct capwap_dtls* dtls, int sock, void* buffer, int si
 | 
				
			|||||||
	return SSL_write((SSL*)dtls->sslsession, buffer, size);
 | 
						return SSL_write((SSL*)dtls->sslsession, buffer, size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					int capwap_crypt_sendto_fragmentpacket(struct capwap_dtls* dtls, int sock, struct capwap_list* fragmentlist, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr) {
 | 
				
			||||||
 | 
						struct capwap_list_item* item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(sock >= 0);
 | 
				
			||||||
 | 
						ASSERT(fragmentlist != NULL);
 | 
				
			||||||
 | 
						ASSERT(sendtoaddr != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						item = fragmentlist->first;
 | 
				
			||||||
 | 
						while (item) {
 | 
				
			||||||
 | 
							struct capwap_fragment_packet_item* fragmentpacket = (struct capwap_fragment_packet_item*)item->item;
 | 
				
			||||||
 | 
							ASSERT(fragmentpacket != NULL);
 | 
				
			||||||
 | 
							ASSERT(fragmentpacket->offset > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!capwap_crypt_sendto(dtls, sock, fragmentpacket->buffer, fragmentpacket->offset, sendfromaddr, sendtoaddr)) {
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* */
 | 
				
			||||||
 | 
							item = item->next;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_decrypt_packet(struct capwap_dtls* dtls, void* encrybuffer, int size, void* plainbuffer, int maxsize) {
 | 
					int capwap_decrypt_packet(struct capwap_dtls* dtls, void* encrybuffer, int size, void* plainbuffer, int maxsize) {
 | 
				
			||||||
	int sslerror;
 | 
						int sslerror;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,8 @@
 | 
				
			|||||||
#ifndef __CAPWAP_DTLS_HEADER__
 | 
					#ifndef __CAPWAP_DTLS_HEADER__
 | 
				
			||||||
#define __CAPWAP_DTLS_HEADER__
 | 
					#define __CAPWAP_DTLS_HEADER__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "capwap_list.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_DTLS_CLIENT						0
 | 
					#define CAPWAP_DTLS_CLIENT						0
 | 
				
			||||||
#define CAPWAP_DTLS_SERVER						1
 | 
					#define CAPWAP_DTLS_SERVER						1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -106,6 +108,7 @@ void capwap_crypt_change_bio_send(struct capwap_dtls* dtls, capwap_bio_send bios
 | 
				
			|||||||
void capwap_crypt_change_dtls(struct capwap_dtls* dtls, struct capwap_dtls* newdtls);
 | 
					void capwap_crypt_change_dtls(struct capwap_dtls* dtls, struct capwap_dtls* newdtls);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int capwap_crypt_sendto(struct capwap_dtls* dtls, int sock, void* buffer, int size, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr);
 | 
					int capwap_crypt_sendto(struct capwap_dtls* dtls, int sock, void* buffer, int size, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr);
 | 
				
			||||||
 | 
					int capwap_crypt_sendto_fragmentpacket(struct capwap_dtls* dtls, int sock, struct capwap_list* fragmentlist, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr);
 | 
				
			||||||
int capwap_decrypt_packet(struct capwap_dtls* dtls, void* encrybuffer, int size, void* plainbuffer, int maxsize);
 | 
					int capwap_decrypt_packet(struct capwap_dtls* dtls, void* encrybuffer, int size, void* plainbuffer, int maxsize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_DTLS_HEADER__ */
 | 
					#endif /* __CAPWAP_DTLS_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,6 +1,7 @@
 | 
				
			|||||||
#ifndef __CAPWAP_ELEMENT_HEADER__
 | 
					#ifndef __CAPWAP_ELEMENT_HEADER__
 | 
				
			||||||
#define __CAPWAP_ELEMENT_HEADER__
 | 
					#define __CAPWAP_ELEMENT_HEADER__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "capwap_rfc.h"
 | 
				
			||||||
#include "capwap_array.h"
 | 
					#include "capwap_array.h"
 | 
				
			||||||
#include "capwap_list.h"
 | 
					#include "capwap_list.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -16,26 +17,33 @@
 | 
				
			|||||||
#define CAPWAP_80211_MESSAGE_ELEMENTS_COUNT			((CAPWAP_80211_MESSAGE_ELEMENTS_STOP - CAPWAP_80211_MESSAGE_ELEMENTS_START) + 1)
 | 
					#define CAPWAP_80211_MESSAGE_ELEMENTS_COUNT			((CAPWAP_80211_MESSAGE_ELEMENTS_STOP - CAPWAP_80211_MESSAGE_ELEMENTS_START) + 1)
 | 
				
			||||||
#define IS_80211_MESSAGE_ELEMENTS(x)				(((x >= CAPWAP_80211_MESSAGE_ELEMENTS_START) && (x <= CAPWAP_80211_MESSAGE_ELEMENTS_STOP)) ? 1 : 0)
 | 
					#define IS_80211_MESSAGE_ELEMENTS(x)				(((x >= CAPWAP_80211_MESSAGE_ELEMENTS_START) && (x <= CAPWAP_80211_MESSAGE_ELEMENTS_STOP)) ? 1 : 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Message element */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element {
 | 
					typedef void* capwap_message_elements_handle;
 | 
				
			||||||
	unsigned short type;
 | 
					struct capwap_write_message_elements_ops {
 | 
				
			||||||
	unsigned short length;
 | 
						int (*write_u8)(capwap_message_elements_handle handle, uint8_t data);
 | 
				
			||||||
	char data[0];
 | 
						int (*write_u16)(capwap_message_elements_handle handle, uint16_t data);
 | 
				
			||||||
} __attribute__((__packed__));
 | 
						int (*write_u32)(capwap_message_elements_handle handle, uint32_t data);
 | 
				
			||||||
 | 
						int (*write_block)(capwap_message_elements_handle handle, uint8_t* data, unsigned short length);
 | 
				
			||||||
typedef struct capwap_message_element*(*capwap_create_message_element)(void* data, unsigned long length);
 | 
					 | 
				
			||||||
typedef int(*capwap_validate_message_element)(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
typedef void*(*capwap_parsing_message_element)(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
typedef void(*capwap_free_message_element)(void*);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct capwap_message_elements_func {
 | 
					 | 
				
			||||||
	capwap_create_message_element create;
 | 
					 | 
				
			||||||
	capwap_validate_message_element check;
 | 
					 | 
				
			||||||
	capwap_parsing_message_element parsing;
 | 
					 | 
				
			||||||
	capwap_free_message_element free;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_elements_func* capwap_get_message_element(unsigned long code);
 | 
					struct capwap_read_message_elements_ops {
 | 
				
			||||||
 | 
						unsigned short (*read_ready)(capwap_message_elements_handle handle);
 | 
				
			||||||
 | 
						int (*read_u8)(capwap_message_elements_handle handle, uint8_t* data);
 | 
				
			||||||
 | 
						int (*read_u16)(capwap_message_elements_handle handle, uint16_t* data);
 | 
				
			||||||
 | 
						int (*read_u32)(capwap_message_elements_handle handle, uint32_t* data);
 | 
				
			||||||
 | 
						int (*read_block)(capwap_message_elements_handle handle, uint8_t* data, unsigned short length);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops {
 | 
				
			||||||
 | 
						/* Build message element */
 | 
				
			||||||
 | 
						void (*create_message_element)(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Parsing message element */
 | 
				
			||||||
 | 
						void* (*parsing_message_element)(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func);
 | 
				
			||||||
 | 
						void (*free_parsed_message_element)(void*);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops* capwap_get_message_element_ops(unsigned short code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*********************************************************************************************************************/
 | 
					/*********************************************************************************************************************/
 | 
				
			||||||
/* Standard message elements */
 | 
					/* Standard message elements */
 | 
				
			||||||
@ -106,192 +114,66 @@ struct capwap_message_elements_func* capwap_get_message_element(unsigned long co
 | 
				
			|||||||
#include "capwap_element_80211_wtpradioinformation.h"	/* 01048 */
 | 
					#include "capwap_element_80211_wtpradioinformation.h"	/* 01048 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*********************************************************************************************************************/
 | 
					/*********************************************************************************************************************/
 | 
				
			||||||
struct capwap_element_discovery_request {
 | 
					struct capwap_message_elements {
 | 
				
			||||||
	struct capwap_discoverytype_element* discoverytype;
 | 
					 | 
				
			||||||
	struct capwap_wtpboarddata_element* wtpboarddata;
 | 
					 | 
				
			||||||
	struct capwap_wtpdescriptor_element* wtpdescriptor;
 | 
					 | 
				
			||||||
	struct capwap_wtpframetunnelmode_element* wtpframetunnel;
 | 
					 | 
				
			||||||
	struct capwap_wtpmactype_element* wtpmactype;
 | 
					 | 
				
			||||||
	struct capwap_mtudiscovery_element* mtudiscovery;
 | 
					 | 
				
			||||||
	struct capwap_vendorpayload_element* vendorpayload;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct {
 | 
					 | 
				
			||||||
			struct capwap_array* wtpradioinformation;
 | 
					 | 
				
			||||||
		} ieee80211;
 | 
					 | 
				
			||||||
	} binding;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void capwap_init_element_discovery_request(struct capwap_element_discovery_request* element, unsigned short binding);
 | 
					 | 
				
			||||||
int capwap_parsing_element_discovery_request(struct capwap_element_discovery_request* element, struct capwap_list_item* item);
 | 
					 | 
				
			||||||
void capwap_free_element_discovery_request(struct capwap_element_discovery_request* element, unsigned short binding);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
struct capwap_element_discovery_response {
 | 
					 | 
				
			||||||
	struct capwap_acdescriptor_element* acdescriptor;
 | 
						struct capwap_acdescriptor_element* acdescriptor;
 | 
				
			||||||
 | 
						struct capwap_acipv4list_element* acipv4list;
 | 
				
			||||||
 | 
						struct capwap_acipv6list_element* acipv6list;
 | 
				
			||||||
	struct capwap_acname_element* acname;
 | 
						struct capwap_acname_element* acname;
 | 
				
			||||||
	struct capwap_array* controlipv4;
 | 
					 | 
				
			||||||
	struct capwap_array* controlipv6;
 | 
					 | 
				
			||||||
	struct capwap_vendorpayload_element* vendorpayload;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct {
 | 
					 | 
				
			||||||
			struct capwap_array* wtpradioinformation;
 | 
					 | 
				
			||||||
		} ieee80211;
 | 
					 | 
				
			||||||
	} binding;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void capwap_init_element_discovery_response(struct capwap_element_discovery_response* element, unsigned short binding);
 | 
					 | 
				
			||||||
int capwap_parsing_element_discovery_response(struct capwap_element_discovery_response* element, struct capwap_list_item* item);
 | 
					 | 
				
			||||||
void capwap_free_element_discovery_response(struct capwap_element_discovery_response* element, unsigned short binding);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
struct capwap_element_join_request {
 | 
					 | 
				
			||||||
	struct capwap_location_element* locationdata;
 | 
					 | 
				
			||||||
	struct capwap_wtpboarddata_element* wtpboarddata;
 | 
					 | 
				
			||||||
	struct capwap_wtpdescriptor_element* wtpdescriptor;
 | 
					 | 
				
			||||||
	struct capwap_wtpname_element* wtpname;
 | 
					 | 
				
			||||||
	struct capwap_sessionid_element* sessionid;
 | 
					 | 
				
			||||||
	struct capwap_wtpframetunnelmode_element* wtpframetunnel;
 | 
					 | 
				
			||||||
	struct capwap_wtpmactype_element* wtpmactype;
 | 
					 | 
				
			||||||
	struct capwap_ecnsupport_element* ecnsupport;
 | 
					 | 
				
			||||||
	struct capwap_localipv4_element* localipv4;
 | 
					 | 
				
			||||||
	struct capwap_localipv6_element* localipv6;
 | 
					 | 
				
			||||||
	struct capwap_transport_element* trasport;
 | 
					 | 
				
			||||||
	struct capwap_maximumlength_element* maxiumlength;
 | 
					 | 
				
			||||||
	struct capwap_wtprebootstat_element* wtprebootstat;
 | 
					 | 
				
			||||||
	struct capwap_vendorpayload_element* vendorpayload;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct {
 | 
					 | 
				
			||||||
			struct capwap_array* wtpradioinformation;
 | 
					 | 
				
			||||||
		} ieee80211;
 | 
					 | 
				
			||||||
	} binding;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void capwap_init_element_join_request(struct capwap_element_join_request* element, unsigned short binding);
 | 
					 | 
				
			||||||
int capwap_parsing_element_join_request(struct capwap_element_join_request* element, struct capwap_list_item* item);
 | 
					 | 
				
			||||||
void capwap_free_element_join_request(struct capwap_element_join_request* element, unsigned short binding);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
struct capwap_element_join_response {
 | 
					 | 
				
			||||||
	struct capwap_resultcode_element* resultcode;
 | 
					 | 
				
			||||||
	struct capwap_array* returnedmessage;
 | 
					 | 
				
			||||||
	struct capwap_acdescriptor_element* acdescriptor;
 | 
					 | 
				
			||||||
	struct capwap_acname_element* acname;
 | 
					 | 
				
			||||||
	struct capwap_ecnsupport_element* ecnsupport;
 | 
					 | 
				
			||||||
	struct capwap_array* controlipv4;
 | 
					 | 
				
			||||||
	struct capwap_array* controlipv6;
 | 
					 | 
				
			||||||
	struct capwap_localipv4_element* localipv4;
 | 
					 | 
				
			||||||
	struct capwap_localipv6_element* localipv6;
 | 
					 | 
				
			||||||
	capwap_acipv4list_element_array* acipv4list;
 | 
					 | 
				
			||||||
	capwap_acipv6list_element_array* acipv6list;
 | 
					 | 
				
			||||||
	struct capwap_transport_element* trasport;
 | 
					 | 
				
			||||||
	struct capwap_imageidentifier_element* imageidentifier;
 | 
					 | 
				
			||||||
	struct capwap_maximumlength_element* maxiumlength;
 | 
					 | 
				
			||||||
	struct capwap_vendorpayload_element* vendorpayload;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct {
 | 
					 | 
				
			||||||
			struct capwap_array* wtpradioinformation;
 | 
					 | 
				
			||||||
		} ieee80211;
 | 
					 | 
				
			||||||
	} binding;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void capwap_init_element_join_response(struct capwap_element_join_response* element, unsigned short binding);
 | 
					 | 
				
			||||||
int capwap_parsing_element_join_response(struct capwap_element_join_response* element, struct capwap_list_item* item);
 | 
					 | 
				
			||||||
void capwap_free_element_join_response(struct capwap_element_join_response* element, unsigned short binding);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
struct capwap_element_configurationstatus_request {
 | 
					 | 
				
			||||||
	struct capwap_acname_element* acname;
 | 
					 | 
				
			||||||
	struct capwap_array* radioadmstatus;
 | 
					 | 
				
			||||||
	struct capwap_statisticstimer_element* statisticstimer;
 | 
					 | 
				
			||||||
	struct capwap_wtprebootstat_element* wtprebootstat;
 | 
					 | 
				
			||||||
	struct capwap_array* acnamepriority;
 | 
						struct capwap_array* acnamepriority;
 | 
				
			||||||
	struct capwap_transport_element* trasport;
 | 
						struct capwap_array* controlipv4;
 | 
				
			||||||
	struct capwap_wtpstaticipaddress_element* wtpstaticipaddress;
 | 
						struct capwap_array* controlipv6;
 | 
				
			||||||
	struct capwap_vendorpayload_element* vendorpayload;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void capwap_init_element_configurationstatus_request(struct capwap_element_configurationstatus_request* element, unsigned short binding);
 | 
					 | 
				
			||||||
int capwap_parsing_element_configurationstatus_request(struct capwap_element_configurationstatus_request* element, struct capwap_list_item* item);
 | 
					 | 
				
			||||||
void capwap_free_element_configurationstatus_request(struct capwap_element_configurationstatus_request* element, unsigned short binding);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
struct capwap_element_configurationstatus_response {
 | 
					 | 
				
			||||||
	struct capwap_timers_element* timers;
 | 
						struct capwap_timers_element* timers;
 | 
				
			||||||
	struct capwap_array* decrypterrorresultperiod;
 | 
						struct capwap_array* decrypterrorreportperiod;
 | 
				
			||||||
 | 
						struct capwap_discoverytype_element* discoverytype;
 | 
				
			||||||
	struct capwap_idletimeout_element* idletimeout;
 | 
						struct capwap_idletimeout_element* idletimeout;
 | 
				
			||||||
	struct capwap_wtpfallback_element* wtpfallback;
 | 
						struct capwap_imageidentifier_element* imageidentifier;
 | 
				
			||||||
	capwap_acipv4list_element_array* acipv4list;
 | 
						struct capwap_location_element* location;
 | 
				
			||||||
	capwap_acipv6list_element_array* acipv6list;
 | 
						struct capwap_maximumlength_element* maximumlength;
 | 
				
			||||||
	struct capwap_array* radiooprstatus;
 | 
						struct capwap_localipv4_element* localipv4;
 | 
				
			||||||
	struct capwap_wtpstaticipaddress_element* wtpstaticipaddress;
 | 
						struct capwap_array* radioadmstate;
 | 
				
			||||||
	struct capwap_vendorpayload_element* vendorpayload;
 | 
						struct capwap_array* radiooprstate;
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void capwap_init_element_configurationstatus_response(struct capwap_element_configurationstatus_response* element, unsigned short binding);
 | 
					 | 
				
			||||||
int capwap_parsing_element_configurationstatus_response(struct capwap_element_configurationstatus_response* element, struct capwap_list_item* item);
 | 
					 | 
				
			||||||
void capwap_free_element_configurationstatus_response(struct capwap_element_configurationstatus_response* element, unsigned short binding);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
struct capwap_element_changestateevent_request {
 | 
					 | 
				
			||||||
	struct capwap_array* radiooprstatus;
 | 
					 | 
				
			||||||
	struct capwap_resultcode_element* resultcode;
 | 
						struct capwap_resultcode_element* resultcode;
 | 
				
			||||||
	struct capwap_array* returnedmessage;
 | 
						struct capwap_array* returnedmessage;
 | 
				
			||||||
 | 
						struct capwap_sessionid_element* sessionid; 
 | 
				
			||||||
 | 
						struct capwap_statisticstimer_element* statisticstimer;
 | 
				
			||||||
	struct capwap_vendorpayload_element* vendorpayload;
 | 
						struct capwap_vendorpayload_element* vendorpayload;
 | 
				
			||||||
 | 
						struct capwap_wtpboarddata_element* wtpboarddata;
 | 
				
			||||||
 | 
						struct capwap_wtpdescriptor_element* wtpdescriptor;
 | 
				
			||||||
 | 
						struct capwap_wtpfallback_element* wtpfallback;
 | 
				
			||||||
 | 
						struct capwap_wtpframetunnelmode_element* wtpframetunnel;
 | 
				
			||||||
 | 
						struct capwap_wtpmactype_element* wtpmactype;
 | 
				
			||||||
 | 
						struct capwap_wtpname_element* wtpname;
 | 
				
			||||||
 | 
						struct capwap_wtprebootstat_element* wtprebootstat;
 | 
				
			||||||
 | 
						struct capwap_wtpstaticipaddress_element* wtpstaticipaddress;
 | 
				
			||||||
 | 
						struct capwap_localipv6_element* localipv6;
 | 
				
			||||||
 | 
						struct capwap_transport_element* transport;
 | 
				
			||||||
 | 
						struct capwap_mtudiscovery_element* mtudiscovery;
 | 
				
			||||||
 | 
						struct capwap_ecnsupport_element* ecnsupport;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								struct capwap_array* antenna;
 | 
				
			||||||
 | 
								struct capwap_array* directsequencecontrol;
 | 
				
			||||||
 | 
								struct capwap_array* macoperation;
 | 
				
			||||||
 | 
								struct capwap_array* multidomaincapability;
 | 
				
			||||||
 | 
								struct capwap_array* ofdmcontrol;
 | 
				
			||||||
 | 
								struct capwap_array* rateset;
 | 
				
			||||||
 | 
								struct capwap_array* supportedrates;
 | 
				
			||||||
 | 
								struct capwap_array* txpower;
 | 
				
			||||||
 | 
								struct capwap_array* txpowerlevel;
 | 
				
			||||||
 | 
								struct capwap_array* wtpradioinformation;
 | 
				
			||||||
 | 
							} ieee80211;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void capwap_init_element_changestateevent_request(struct capwap_element_changestateevent_request* element, unsigned short binding);
 | 
					struct capwap_parsed_packet {
 | 
				
			||||||
int capwap_parsing_element_changestateevent_request(struct capwap_element_changestateevent_request* element, struct capwap_list_item* item);
 | 
						struct capwap_packet_rxmng* rxmngpacket;
 | 
				
			||||||
void capwap_free_element_changestateevent_request(struct capwap_element_changestateevent_request* element, unsigned short binding);
 | 
						struct capwap_connection* connection;
 | 
				
			||||||
 | 
						struct capwap_message_elements messageelements;
 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
struct capwap_element_changestateevent_response {
 | 
					 | 
				
			||||||
	struct capwap_vendorpayload_element* vendorpayload;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void capwap_init_element_changestateevent_response(struct capwap_element_changestateevent_response* element, unsigned short binding);
 | 
					int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap_connection* connection, struct capwap_parsed_packet* packet);
 | 
				
			||||||
int capwap_parsing_element_changestateevent_response(struct capwap_element_changestateevent_response* element, struct capwap_list_item* item);
 | 
					int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct capwap_array* returnedmessage);
 | 
				
			||||||
void capwap_free_element_changestateevent_response(struct capwap_element_changestateevent_response* element, unsigned short binding);
 | 
					void capwap_free_parsed_packet(struct capwap_parsed_packet* packet);
 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
struct capwap_element_echo_request {
 | 
					 | 
				
			||||||
	struct capwap_vendorpayload_element* vendorpayload;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void capwap_init_element_echo_request(struct capwap_element_echo_request* element, unsigned short binding);
 | 
					 | 
				
			||||||
int capwap_parsing_element_echo_request(struct capwap_element_echo_request* element, struct capwap_list_item* item);
 | 
					 | 
				
			||||||
void capwap_free_element_echo_request(struct capwap_element_echo_request* element, unsigned short binding);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
struct capwap_element_echo_response {
 | 
					 | 
				
			||||||
	struct capwap_vendorpayload_element* vendorpayload;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void capwap_init_element_echo_response(struct capwap_element_echo_response* element, unsigned short binding);
 | 
					 | 
				
			||||||
int capwap_parsing_element_echo_response(struct capwap_element_echo_response* element, struct capwap_list_item* item);
 | 
					 | 
				
			||||||
void capwap_free_element_echo_response(struct capwap_element_echo_response* element, unsigned short binding);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
struct capwap_element_reset_request {
 | 
					 | 
				
			||||||
	struct capwap_imageidentifier_element* imageidentifier;
 | 
					 | 
				
			||||||
	struct capwap_vendorpayload_element* vendorpayload;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void capwap_init_element_reset_request(struct capwap_element_reset_request* element, unsigned short binding);
 | 
					 | 
				
			||||||
int capwap_parsing_element_reset_request(struct capwap_element_reset_request* element, struct capwap_list_item* item);
 | 
					 | 
				
			||||||
void capwap_free_element_reset_request(struct capwap_element_reset_request* element, unsigned short binding);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
struct capwap_element_reset_response {
 | 
					 | 
				
			||||||
	struct capwap_resultcode_element* resultcode;	
 | 
					 | 
				
			||||||
	struct capwap_vendorpayload_element* vendorpayload;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void capwap_init_element_reset_response(struct capwap_element_reset_response* element, unsigned short binding);
 | 
					 | 
				
			||||||
int capwap_parsing_element_reset_response(struct capwap_element_reset_response* element, struct capwap_list_item* item);
 | 
					 | 
				
			||||||
void capwap_free_element_reset_response(struct capwap_element_reset_response* element, unsigned short binding);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -17,98 +17,74 @@ Length:   >= 5
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_antenna_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char diversity;
 | 
					 | 
				
			||||||
	unsigned char combiner;
 | 
					 | 
				
			||||||
	unsigned char antennacount;
 | 
					 | 
				
			||||||
	unsigned char antennaselections[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_80211_antenna_element_create(void* data, unsigned long datalength) {
 | 
					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;
 | 
				
			||||||
	unsigned short antennalength;
 | 
					 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					 | 
				
			||||||
	struct capwap_80211_antenna_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_80211_antenna_element* dataelement = (struct capwap_80211_antenna_element*)data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_80211_antenna_element));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Alloc block of memory */
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	antennalength = dataelement->antennacount * sizeof(unsigned char);
 | 
						func->write_u8(handle, element->diversity);
 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_antenna_raw_element) + antennalength);
 | 
						func->write_u8(handle, element->combiner);
 | 
				
			||||||
	if (!element) {
 | 
						func->write_u8(handle, element->antennacount);
 | 
				
			||||||
		capwap_outofmemory();
 | 
						func->write_block(handle, element->antennaselections, element->antennacount);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create message element */
 | 
					 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_antenna_raw_element) + antennalength);
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_80211_ANTENNA);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_80211_antenna_raw_element) + antennalength);
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_80211_antenna_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	dataraw->diversity = dataelement->diversity;
 | 
					 | 
				
			||||||
	dataraw->combiner = dataelement->combiner;
 | 
					 | 
				
			||||||
	dataraw->antennacount = dataelement->antennacount;
 | 
					 | 
				
			||||||
	for (i = 0; i < dataelement->antennacount; i++) {
 | 
					 | 
				
			||||||
		dataraw->antennaselections[i] = dataelement->antennaselections[i];
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_80211_antenna_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_80211_antenna_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
						unsigned short length;
 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_80211_antenna_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
	unsigned short antennalength;
 | 
					 | 
				
			||||||
	struct capwap_80211_antenna_element* data;
 | 
						struct capwap_80211_antenna_element* data;
 | 
				
			||||||
	struct capwap_80211_antenna_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_ANTENNA);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	antennalength = ntohs(element->length);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	if (antennalength < 5) {
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						length = func->read_ready(handle);
 | 
				
			||||||
 | 
						if (length < 5) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Antenna element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	antennalength -= sizeof(struct capwap_80211_antenna_raw_element);
 | 
						length -= 4;
 | 
				
			||||||
	if (antennalength > CAPWAP_ANTENNASELECTIONS_MAXLENGTH) {
 | 
						if (length > CAPWAP_ANTENNASELECTIONS_MAXLENGTH) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Antenna element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dataraw = (struct capwap_80211_antenna_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	data = (struct capwap_80211_antenna_element*)capwap_alloc(sizeof(struct capwap_80211_antenna_element));
 | 
						data = (struct capwap_80211_antenna_element*)capwap_alloc(sizeof(struct capwap_80211_antenna_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						memset(data, 0, sizeof(struct capwap_80211_antenna_element));
 | 
				
			||||||
	data->diversity = dataraw->diversity;
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
	data->combiner = dataraw->combiner;
 | 
						func->read_u8(handle, &data->diversity);
 | 
				
			||||||
	data->antennacount = dataraw->antennacount;
 | 
						func->read_u8(handle, &data->combiner);
 | 
				
			||||||
	for (i = 0; i < dataraw->antennacount; i++) {
 | 
						func->read_u8(handle, &data->antennacount);
 | 
				
			||||||
		data->antennaselections[i] = dataraw->antennaselections[i];
 | 
					
 | 
				
			||||||
 | 
						/* Check */
 | 
				
			||||||
 | 
						if (data->antennacount != length) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Antenna element");
 | 
				
			||||||
 | 
							capwap_free(data);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						func->read_block(handle, data->antennaselections, length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_80211_antenna_element_free(void* data) {
 | 
					static void capwap_80211_antenna_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_80211_antenna_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_80211_antenna_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_80211_antenna_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_80211_antenna_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -3,16 +3,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ELEMENT_80211_ANTENNA			1025
 | 
					#define CAPWAP_ELEMENT_80211_ANTENNA			1025
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ANTENNASELECTIONS_MAXLENGTH		255
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct capwap_80211_antenna_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char diversity;
 | 
					 | 
				
			||||||
	unsigned char combiner;
 | 
					 | 
				
			||||||
	unsigned char antennacount;
 | 
					 | 
				
			||||||
	unsigned char antennaselections[CAPWAP_ANTENNASELECTIONS_MAXLENGTH];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CAPWAP_ANTENNA_DIVERSITY_DISABLE		0
 | 
					#define CAPWAP_ANTENNA_DIVERSITY_DISABLE		0
 | 
				
			||||||
#define CAPWAP_ANTENNA_DIVERSITY_ENABLE			1
 | 
					#define CAPWAP_ANTENNA_DIVERSITY_ENABLE			1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -24,15 +14,16 @@ struct capwap_80211_antenna_element {
 | 
				
			|||||||
#define CAPWAP_ANTENNA_INTERNAL					1
 | 
					#define CAPWAP_ANTENNA_INTERNAL					1
 | 
				
			||||||
#define CAPWAP_ANTENNA_EXTERNAL					2
 | 
					#define CAPWAP_ANTENNA_EXTERNAL					2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_80211_antenna_element_create(void* data, unsigned long length);
 | 
					#define CAPWAP_ANTENNASELECTIONS_MAXLENGTH		255
 | 
				
			||||||
int capwap_80211_antenna_element_validate(struct capwap_message_element* element);
 | 
					
 | 
				
			||||||
void* capwap_80211_antenna_element_parsing(struct capwap_message_element* element);
 | 
					struct capwap_80211_antenna_element {
 | 
				
			||||||
void capwap_80211_antenna_element_free(void* data);
 | 
						uint8_t radioid;
 | 
				
			||||||
 | 
						uint8_t diversity;
 | 
				
			||||||
 | 
						uint8_t combiner;
 | 
				
			||||||
 | 
						uint8_t antennacount;
 | 
				
			||||||
 | 
						uint8_t antennaselections[CAPWAP_ANTENNASELECTIONS_MAXLENGTH];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern struct capwap_message_elements_ops capwap_element_80211_antenna_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_80211_ANTENNA_ELEMENT(x)						({	\
 | 
					 | 
				
			||||||
																		struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_ANTENNA);	\
 | 
					 | 
				
			||||||
																		f->create(x, sizeof(struct capwap_80211_antenna_element));	\
 | 
					 | 
				
			||||||
																	})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_80211_ANTENNA_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_80211_ANTENNA_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -17,79 +17,59 @@ Length:   8
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_directsequencecontrol_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char reserved;
 | 
					 | 
				
			||||||
	unsigned char currentchannel;
 | 
					 | 
				
			||||||
	unsigned char currentcca;
 | 
					 | 
				
			||||||
	unsigned long enerydetectthreshold;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_80211_dscontrol_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_80211_directsequencecontrol_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_80211_directsequencecontrol_element* element = (struct capwap_80211_directsequencecontrol_element*)data;
 | 
				
			||||||
	struct capwap_80211_directsequencecontrol_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_80211_directsequencecontrol_element* dataelement = (struct capwap_80211_directsequencecontrol_element*)data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_80211_directsequencecontrol_element));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Alloc block of memory */
 | 
						/* */
 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_directsequencecontrol_raw_element));
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	if (!element) {
 | 
						func->write_u8(handle, 0);
 | 
				
			||||||
		capwap_outofmemory();
 | 
						func->write_u8(handle, element->currentchannel);
 | 
				
			||||||
	}
 | 
						func->write_u8(handle, element->currentcca);
 | 
				
			||||||
 | 
						func->write_u32(handle, element->enerydetectthreshold);
 | 
				
			||||||
	/* Create message element */
 | 
					 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_directsequencecontrol_raw_element));
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_80211_directsequencecontrol_raw_element));
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_80211_directsequencecontrol_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	dataraw->currentchannel = dataelement->currentchannel;
 | 
					 | 
				
			||||||
	dataraw->currentcca = dataelement->currentcca;
 | 
					 | 
				
			||||||
	dataraw->enerydetectthreshold = htonl(dataelement->enerydetectthreshold);
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_80211_dscontrol_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_80211_directsequencecontrol_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_80211_dscontrol_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_80211_directsequencecontrol_element* data;
 | 
						struct capwap_80211_directsequencecontrol_element* data;
 | 
				
			||||||
	struct capwap_80211_directsequencecontrol_raw_element* dataraw;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ntohs(element->length) != 8) {
 | 
						if (func->read_ready(handle) != 8) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Direct Sequence Control element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dataraw = (struct capwap_80211_directsequencecontrol_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	data = (struct capwap_80211_directsequencecontrol_element*)capwap_alloc(sizeof(struct capwap_80211_directsequencecontrol_element));
 | 
						data = (struct capwap_80211_directsequencecontrol_element*)capwap_alloc(sizeof(struct capwap_80211_directsequencecontrol_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						memset(data, 0, sizeof(struct capwap_80211_directsequencecontrol_element));
 | 
				
			||||||
	data->currentchannel = dataraw->currentchannel;
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
	data->currentcca = dataraw->currentcca;
 | 
						func->read_u8(handle, NULL);
 | 
				
			||||||
	data->enerydetectthreshold = ntohl(dataraw->enerydetectthreshold);
 | 
						func->read_u8(handle, &data->currentchannel);
 | 
				
			||||||
 | 
						func->read_u8(handle, &data->currentcca);
 | 
				
			||||||
 | 
						func->read_u32(handle, &data->enerydetectthreshold);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_80211_dscontrol_element_free(void* data) {
 | 
					static void capwap_80211_directsequencecontrol_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_80211_directsequencecontrol_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_80211_directsequencecontrol_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_80211_directsequencecontrol_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_80211_directsequencecontrol_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -3,28 +3,19 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL			1028
 | 
					#define CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL			1028
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_directsequencecontrol_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char currentchannel;
 | 
					 | 
				
			||||||
	unsigned char currentcca;
 | 
					 | 
				
			||||||
	unsigned long enerydetectthreshold;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CAPWAP_DSCONTROL_CCA_EDONLY				1
 | 
					#define CAPWAP_DSCONTROL_CCA_EDONLY				1
 | 
				
			||||||
#define CAPWAP_DSCONTROL_CCA_CSONLY				2
 | 
					#define CAPWAP_DSCONTROL_CCA_CSONLY				2
 | 
				
			||||||
#define CAPWAP_DSCONTROL_CCA_EDANDCS			4
 | 
					#define CAPWAP_DSCONTROL_CCA_EDANDCS			4
 | 
				
			||||||
#define CAPWAP_DSCONTROL_CCA_CSWITHTIME			8
 | 
					#define CAPWAP_DSCONTROL_CCA_CSWITHTIME			8
 | 
				
			||||||
#define CAPWAP_DSCONTROL_CCA_HRCSANDED			16
 | 
					#define CAPWAP_DSCONTROL_CCA_HRCSANDED			16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_80211_dscontrol_element_create(void* data, unsigned long length);
 | 
					struct capwap_80211_directsequencecontrol_element {
 | 
				
			||||||
int capwap_80211_dscontrol_element_validate(struct capwap_message_element* element);
 | 
						uint8_t radioid;
 | 
				
			||||||
void* capwap_80211_dscontrol_element_parsing(struct capwap_message_element* element);
 | 
						uint8_t currentchannel;
 | 
				
			||||||
void capwap_80211_dscontrol_element_free(void* data);
 | 
						uint8_t currentcca;
 | 
				
			||||||
 | 
						uint32_t enerydetectthreshold;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern struct capwap_message_elements_ops capwap_element_80211_directsequencecontrol_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_80211_DIRECTSEQUENCECONTROL_ELEMENT(x)		({	\
 | 
					 | 
				
			||||||
																		struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL);	\
 | 
					 | 
				
			||||||
																		f->create(x, sizeof(struct capwap_80211_directsequencecontrol_element));	\
 | 
					 | 
				
			||||||
																	})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -21,88 +21,65 @@ Length:   16
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_macoperation_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char reserved;
 | 
					 | 
				
			||||||
	unsigned short rtsthreshold;
 | 
					 | 
				
			||||||
	unsigned char shortretry;
 | 
					 | 
				
			||||||
	unsigned char longretry;
 | 
					 | 
				
			||||||
	unsigned short fragthreshold;
 | 
					 | 
				
			||||||
	unsigned long txmsdulifetime;
 | 
					 | 
				
			||||||
	unsigned long rxmsdulifetime;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_80211_macoperation_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_80211_macoperation_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_80211_macoperation_element* element = (struct capwap_80211_macoperation_element*)data;
 | 
				
			||||||
	struct capwap_80211_macoperation_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_80211_macoperation_element* dataelement = (struct capwap_80211_macoperation_element*)data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_80211_macoperation_element));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Alloc block of memory */
 | 
						/* */
 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_macoperation_raw_element));
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	if (!element) {
 | 
						func->write_u8(handle, 0);
 | 
				
			||||||
		capwap_outofmemory();
 | 
						func->write_u16(handle, element->rtsthreshold);
 | 
				
			||||||
	}
 | 
						func->write_u8(handle, element->shortretry);
 | 
				
			||||||
 | 
						func->write_u8(handle, element->longretry);
 | 
				
			||||||
	/* Create message element */
 | 
						func->write_u16(handle, element->fragthreshold);
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_macoperation_raw_element));
 | 
						func->write_u32(handle, element->txmsdulifetime);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_80211_MACOPERATION);
 | 
						func->write_u32(handle, element->rxmsdulifetime);
 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_80211_macoperation_raw_element));
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_80211_macoperation_raw_element*)element->data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	dataraw->rtsthreshold = htons(dataelement->rtsthreshold);
 | 
					 | 
				
			||||||
	dataraw->shortretry = dataelement->shortretry;
 | 
					 | 
				
			||||||
	dataraw->longretry = dataelement->longretry;
 | 
					 | 
				
			||||||
	dataraw->fragthreshold = htons(dataelement->fragthreshold);
 | 
					 | 
				
			||||||
	dataraw->txmsdulifetime = htonl(dataelement->txmsdulifetime);
 | 
					 | 
				
			||||||
	dataraw->rxmsdulifetime = htonl(dataelement->rxmsdulifetime);
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_80211_macoperation_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_80211_macoperation_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_80211_macoperation_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_80211_macoperation_element* data;
 | 
						struct capwap_80211_macoperation_element* data;
 | 
				
			||||||
	struct capwap_80211_macoperation_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_MACOPERATION);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) != 16) {
 | 
				
			||||||
	if (ntohs(element->length) != 16) {
 | 
							capwap_logging_debug("Invalid IEEE 802.11 MAC Operation element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dataraw = (struct capwap_80211_macoperation_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	data = (struct capwap_80211_macoperation_element*)capwap_alloc(sizeof(struct capwap_80211_macoperation_element));
 | 
						data = (struct capwap_80211_macoperation_element*)capwap_alloc(sizeof(struct capwap_80211_macoperation_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						memset(data, 0, sizeof(struct capwap_80211_macoperation_element));
 | 
				
			||||||
	data->rtsthreshold = ntohs(dataraw->rtsthreshold);
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
	data->shortretry = dataraw->shortretry;
 | 
						func->read_u8(handle, NULL);
 | 
				
			||||||
	data->longretry = dataraw->longretry;
 | 
						func->read_u16(handle, &data->rtsthreshold);
 | 
				
			||||||
	data->fragthreshold = ntohs(dataraw->fragthreshold);
 | 
						func->read_u8(handle, &data->shortretry);
 | 
				
			||||||
	data->txmsdulifetime = ntohl(dataraw->txmsdulifetime);
 | 
						func->read_u8(handle, &data->longretry);
 | 
				
			||||||
	data->rxmsdulifetime = ntohl(dataraw->rxmsdulifetime);
 | 
						func->read_u16(handle, &data->fragthreshold);
 | 
				
			||||||
 | 
						func->read_u32(handle, &data->txmsdulifetime);
 | 
				
			||||||
 | 
						func->read_u32(handle, &data->rxmsdulifetime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_80211_macoperation_element_free(void* data) {
 | 
					static void capwap_80211_macoperation_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_80211_macoperation_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_80211_macoperation_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_80211_macoperation_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_80211_macoperation_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -4,24 +4,15 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_80211_MACOPERATION			1030
 | 
					#define CAPWAP_ELEMENT_80211_MACOPERATION			1030
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_macoperation_element {
 | 
					struct capwap_80211_macoperation_element {
 | 
				
			||||||
	unsigned char radioid;
 | 
						uint8_t radioid;
 | 
				
			||||||
	unsigned short rtsthreshold;
 | 
						uint16_t rtsthreshold;
 | 
				
			||||||
	unsigned char shortretry;
 | 
						uint8_t shortretry;
 | 
				
			||||||
	unsigned char longretry;
 | 
						uint8_t longretry;
 | 
				
			||||||
	unsigned short fragthreshold;
 | 
						uint16_t fragthreshold;
 | 
				
			||||||
	unsigned long txmsdulifetime;
 | 
						uint32_t txmsdulifetime;
 | 
				
			||||||
	unsigned long rxmsdulifetime;
 | 
						uint32_t rxmsdulifetime;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_80211_macoperation_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_80211_macoperation_ops;
 | 
				
			||||||
int capwap_80211_macoperation_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_80211_macoperation_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_80211_macoperation_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_80211_MACOPERATION_ELEMENT(x)					({	\
 | 
					 | 
				
			||||||
																		struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_MACOPERATION);	\
 | 
					 | 
				
			||||||
																		f->create(x, sizeof(struct capwap_80211_macoperation_element));	\
 | 
					 | 
				
			||||||
																	})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_80211_MACOPERATION_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_80211_MACOPERATION_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -17,79 +17,59 @@ Length:   8
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_multidomaincapability_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char reserved;
 | 
					 | 
				
			||||||
	unsigned short firstchannel;
 | 
					 | 
				
			||||||
	unsigned short numberchannels;
 | 
					 | 
				
			||||||
	unsigned short maxtxpowerlevel;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_80211_multidomaincapability_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_80211_multidomaincapability_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_80211_multidomaincapability_element* element = (struct capwap_80211_multidomaincapability_element*)data;
 | 
				
			||||||
	struct capwap_80211_multidomaincapability_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_80211_multidomaincapability_element* dataelement = (struct capwap_80211_multidomaincapability_element*)data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_80211_multidomaincapability_element));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Alloc block of memory */
 | 
						/* */
 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_multidomaincapability_raw_element));
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	if (!element) {
 | 
						func->write_u8(handle, 0);
 | 
				
			||||||
		capwap_outofmemory();
 | 
						func->write_u16(handle, element->firstchannel);
 | 
				
			||||||
	}
 | 
						func->write_u16(handle, element->numberchannels);
 | 
				
			||||||
 | 
						func->write_u16(handle, element->maxtxpowerlevel);
 | 
				
			||||||
	/* Create message element */
 | 
					 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_multidomaincapability_raw_element));
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_80211_multidomaincapability_raw_element));
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_80211_multidomaincapability_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	dataraw->firstchannel = htons(dataelement->firstchannel);
 | 
					 | 
				
			||||||
	dataraw->numberchannels = htons(dataelement->numberchannels);
 | 
					 | 
				
			||||||
	dataraw->maxtxpowerlevel = htons(dataelement->maxtxpowerlevel);
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_80211_multidomaincapability_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_80211_multidomaincapability_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_80211_multidomaincapability_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_80211_multidomaincapability_element* data;
 | 
						struct capwap_80211_multidomaincapability_element* data;
 | 
				
			||||||
	struct capwap_80211_multidomaincapability_raw_element* dataraw;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ntohs(element->length) != 8) {
 | 
						if (func->read_ready(handle) != 8) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Multi-Domain Capability element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dataraw = (struct capwap_80211_multidomaincapability_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	data = (struct capwap_80211_multidomaincapability_element*)capwap_alloc(sizeof(struct capwap_80211_multidomaincapability_element));
 | 
						data = (struct capwap_80211_multidomaincapability_element*)capwap_alloc(sizeof(struct capwap_80211_multidomaincapability_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						memset(data, 0, sizeof(struct capwap_80211_multidomaincapability_element));
 | 
				
			||||||
	data->firstchannel = ntohs(dataraw->firstchannel);
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
	data->numberchannels = htons(dataraw->numberchannels);
 | 
						func->read_u8(handle, NULL);
 | 
				
			||||||
	data->maxtxpowerlevel = htons(dataraw->maxtxpowerlevel);
 | 
						func->read_u16(handle, &data->firstchannel);
 | 
				
			||||||
 | 
						func->read_u16(handle, &data->numberchannels);
 | 
				
			||||||
 | 
						func->read_u16(handle, &data->maxtxpowerlevel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_80211_multidomaincapability_element_free(void* data) {
 | 
					static void capwap_80211_multidomaincapability_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_80211_multidomaincapability_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_80211_multidomaincapability_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_80211_multidomaincapability_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_80211_multidomaincapability_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -4,21 +4,12 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY			1032
 | 
					#define CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY			1032
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_multidomaincapability_element {
 | 
					struct capwap_80211_multidomaincapability_element {
 | 
				
			||||||
	unsigned char radioid;
 | 
						uint8_t radioid;
 | 
				
			||||||
	unsigned short firstchannel;
 | 
						uint16_t firstchannel;
 | 
				
			||||||
	unsigned short numberchannels;
 | 
						uint16_t numberchannels;
 | 
				
			||||||
	unsigned short maxtxpowerlevel;
 | 
						uint16_t maxtxpowerlevel;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_80211_multidomaincapability_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_80211_multidomaincapability_ops;
 | 
				
			||||||
int capwap_80211_multidomaincapability_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_80211_multidomaincapability_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_80211_multidomaincapability_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_80211_MULTIDOMAINCAPABILITY_ELEMENT(x)		({	\
 | 
					 | 
				
			||||||
																		struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY);	\
 | 
					 | 
				
			||||||
																		f->create(x, sizeof(struct capwap_80211_multidomaincapability_element));	\
 | 
					 | 
				
			||||||
																	})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -17,79 +17,59 @@ Length:   8
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_ofdmcontrol_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char reserved;
 | 
					 | 
				
			||||||
	unsigned char currentchannel;
 | 
					 | 
				
			||||||
	unsigned char bandsupport;
 | 
					 | 
				
			||||||
	unsigned long tithreshold;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_80211_ofdmcontrol_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_80211_ofdmcontrol_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_80211_ofdmcontrol_element* element = (struct capwap_80211_ofdmcontrol_element*)data;
 | 
				
			||||||
	struct capwap_80211_ofdmcontrol_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_80211_ofdmcontrol_element* dataelement = (struct capwap_80211_ofdmcontrol_element*)data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_80211_ofdmcontrol_element));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Alloc block of memory */
 | 
						/* */
 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_ofdmcontrol_raw_element));
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	if (!element) {
 | 
						func->write_u8(handle, 0);
 | 
				
			||||||
		capwap_outofmemory();
 | 
						func->write_u8(handle, element->currentchannel);
 | 
				
			||||||
	}
 | 
						func->write_u8(handle, element->bandsupport);
 | 
				
			||||||
 | 
						func->write_u32(handle, element->tithreshold);
 | 
				
			||||||
	/* Create message element */
 | 
					 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_ofdmcontrol_raw_element));
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_80211_OFDMCONTROL);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_80211_ofdmcontrol_raw_element));
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_80211_ofdmcontrol_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	dataraw->currentchannel = dataelement->currentchannel;
 | 
					 | 
				
			||||||
	dataraw->bandsupport = dataelement->bandsupport;
 | 
					 | 
				
			||||||
	dataraw->tithreshold = htonl(dataelement->tithreshold);
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_80211_ofdmcontrol_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_80211_ofdmcontrol_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_80211_ofdmcontrol_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_80211_ofdmcontrol_element* data;
 | 
						struct capwap_80211_ofdmcontrol_element* data;
 | 
				
			||||||
	struct capwap_80211_ofdmcontrol_raw_element* dataraw;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_OFDMCONTROL);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ntohs(element->length) != 8) {
 | 
						if (func->read_ready(handle) != 8) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid IEEE 802.11 OFDM Control element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dataraw = (struct capwap_80211_ofdmcontrol_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	data = (struct capwap_80211_ofdmcontrol_element*)capwap_alloc(sizeof(struct capwap_80211_ofdmcontrol_element));
 | 
						data = (struct capwap_80211_ofdmcontrol_element*)capwap_alloc(sizeof(struct capwap_80211_ofdmcontrol_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						memset(data, 0, sizeof(struct capwap_80211_ofdmcontrol_element));
 | 
				
			||||||
	data->currentchannel = ntohs(dataraw->currentchannel);
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
	data->bandsupport = ntohs(dataraw->bandsupport);
 | 
						func->read_u8(handle, NULL);
 | 
				
			||||||
	data->tithreshold = ntohl(dataraw->tithreshold);
 | 
						func->read_u8(handle, &data->currentchannel);
 | 
				
			||||||
 | 
						func->read_u8(handle, &data->bandsupport);
 | 
				
			||||||
 | 
						func->read_u32(handle, &data->tithreshold);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_80211_ofdmcontrol_element_free(void* data) {
 | 
					static void capwap_80211_ofdmcontrol_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_80211_ofdmcontrol_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_80211_ofdmcontrol_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_80211_ofdmcontrol_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_80211_ofdmcontrol_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -3,13 +3,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ELEMENT_80211_OFDMCONTROL			1033
 | 
					#define CAPWAP_ELEMENT_80211_OFDMCONTROL			1033
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_ofdmcontrol_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char currentchannel;
 | 
					 | 
				
			||||||
	unsigned char bandsupport;
 | 
					 | 
				
			||||||
	unsigned long tithreshold;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CAPWAP_OFDMCONTROL_BAND_515_525				0x01
 | 
					#define CAPWAP_OFDMCONTROL_BAND_515_525				0x01
 | 
				
			||||||
#define CAPWAP_OFDMCONTROL_BAND_525_535				0x02
 | 
					#define CAPWAP_OFDMCONTROL_BAND_525_535				0x02
 | 
				
			||||||
#define CAPWAP_OFDMCONTROL_BAND_5725_5825			0x04
 | 
					#define CAPWAP_OFDMCONTROL_BAND_5725_5825			0x04
 | 
				
			||||||
@ -18,15 +11,13 @@ struct capwap_80211_ofdmcontrol_element {
 | 
				
			|||||||
#define CAPWAP_OFDMCONTROL_BAND_503_5091			0x20
 | 
					#define CAPWAP_OFDMCONTROL_BAND_503_5091			0x20
 | 
				
			||||||
#define CAPWAP_OFDMCONTROL_BAND_494_499				0x40
 | 
					#define CAPWAP_OFDMCONTROL_BAND_494_499				0x40
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_80211_ofdmcontrol_element_create(void* data, unsigned long length);
 | 
					struct capwap_80211_ofdmcontrol_element {
 | 
				
			||||||
int capwap_80211_ofdmcontrol_element_validate(struct capwap_message_element* element);
 | 
						uint8_t radioid;
 | 
				
			||||||
void* capwap_80211_ofdmcontrol_element_parsing(struct capwap_message_element* element);
 | 
						uint8_t currentchannel;
 | 
				
			||||||
void capwap_80211_ofdmcontrol_element_free(void* data);
 | 
						uint8_t bandsupport;
 | 
				
			||||||
 | 
						uint32_t tithreshold;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern struct capwap_message_elements_ops capwap_element_80211_ofdmcontrol_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_80211_OFDMCONTROL_ELEMENT(x)					({	\
 | 
					 | 
				
			||||||
																		struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_OFDMCONTROL);	\
 | 
					 | 
				
			||||||
																		f->create(x, sizeof(struct capwap_80211_ofdmcontrol_element));	\
 | 
					 | 
				
			||||||
																	})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_80211_OFDMCONTROL_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_80211_OFDMCONTROL_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -15,90 +15,61 @@ Length:   >= 3
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_rateset_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char rateset[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_80211_rateset_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_80211_rateset_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	int i;
 | 
						struct capwap_80211_rateset_element* element = (struct capwap_80211_rateset_element*)data;
 | 
				
			||||||
	unsigned short ratesetlength;
 | 
					 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					 | 
				
			||||||
	struct capwap_80211_rateset_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_80211_rateset_element* dataelement = (struct capwap_80211_rateset_element*)data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_80211_rateset_element));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Alloc block of memory */
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	ratesetlength = dataelement->ratesetcount * sizeof(unsigned char);
 | 
						func->write_block(handle, element->rateset, element->ratesetcount);
 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_rateset_raw_element) + ratesetlength);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create message element */
 | 
					 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_rateset_raw_element) + ratesetlength);
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_80211_RATESET);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_80211_rateset_raw_element) + ratesetlength);
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_80211_rateset_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	for (i = 0; i < dataelement->ratesetcount; i++) {
 | 
					 | 
				
			||||||
		dataraw->rateset[i] = dataelement->rateset[i];
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_80211_rateset_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_80211_rateset_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
						unsigned short length;
 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_80211_rateset_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
	unsigned short ratesetlength;
 | 
					 | 
				
			||||||
	struct capwap_80211_rateset_element* data;
 | 
						struct capwap_80211_rateset_element* data;
 | 
				
			||||||
	struct capwap_80211_rateset_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_RATESET);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ratesetlength = ntohs(element->length);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	if (ratesetlength < 3) {
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						length = func->read_ready(handle);
 | 
				
			||||||
 | 
						if (length < 3) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Rate Set element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ratesetlength -= sizeof(struct capwap_80211_rateset_raw_element);
 | 
						length -= 1;
 | 
				
			||||||
	if (ratesetlength > CAPWAP_SUPPORTEDRATES_MAXLENGTH) {
 | 
						if (length > CAPWAP_RATESET_MAXLENGTH) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Rate Set element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dataraw = (struct capwap_80211_rateset_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	data = (struct capwap_80211_rateset_element*)capwap_alloc(sizeof(struct capwap_80211_rateset_element));
 | 
						data = (struct capwap_80211_rateset_element*)capwap_alloc(sizeof(struct capwap_80211_rateset_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						memset(data, 0, sizeof(struct capwap_80211_rateset_element));
 | 
				
			||||||
	data->ratesetcount = ratesetlength;
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
	for (i = 0; i < ratesetlength; i++) {
 | 
						data->ratesetcount = length;
 | 
				
			||||||
		data->rateset[i] = dataraw->rateset[i];
 | 
						func->read_block(handle, data->rateset, length);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_80211_rateset_element_free(void* data) {
 | 
					static void capwap_80211_rateset_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_80211_rateset_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_80211_rateset_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_80211_rateset_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_80211_rateset_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -7,20 +7,11 @@
 | 
				
			|||||||
#define CAPWAP_RATESET_MAXLENGTH			8
 | 
					#define CAPWAP_RATESET_MAXLENGTH			8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_rateset_element {
 | 
					struct capwap_80211_rateset_element {
 | 
				
			||||||
	unsigned char radioid;
 | 
						uint8_t radioid;
 | 
				
			||||||
	unsigned char ratesetcount;
 | 
						uint8_t ratesetcount;
 | 
				
			||||||
	unsigned char rateset[CAPWAP_RATESET_MAXLENGTH];
 | 
						uint8_t rateset[CAPWAP_RATESET_MAXLENGTH];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_80211_rateset_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_80211_rateset_ops;
 | 
				
			||||||
int capwap_80211_rateset_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_80211_rateset_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_80211_rateset_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_80211_RATESET_ELEMENT(x)						({	\
 | 
					 | 
				
			||||||
																		struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_RATESET);	\
 | 
					 | 
				
			||||||
																		f->create(x, sizeof(struct capwap_80211_rateset_element));	\
 | 
					 | 
				
			||||||
																	})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_80211_RATESET_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_80211_RATESET_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -15,90 +15,61 @@ Length:   >= 3
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_supportedrates_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char supportedrates[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_80211_supportedrates_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_80211_supportedrates_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	int i;
 | 
						struct capwap_80211_supportedrates_element* element = (struct capwap_80211_supportedrates_element*)data;
 | 
				
			||||||
	unsigned short supportedrateslength;
 | 
					 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					 | 
				
			||||||
	struct capwap_80211_supportedrates_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_80211_supportedrates_element* dataelement = (struct capwap_80211_supportedrates_element*)data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_80211_supportedrates_element));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Alloc block of memory */
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	supportedrateslength = dataelement->supportedratescount * sizeof(unsigned char);
 | 
						func->write_block(handle, element->supportedrates, element->supportedratescount);
 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_supportedrates_raw_element) + supportedrateslength);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create message element */
 | 
					 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_supportedrates_raw_element) + supportedrateslength);
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_80211_SUPPORTEDRATES);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_80211_supportedrates_raw_element) + supportedrateslength);
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_80211_supportedrates_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	for (i = 0; i < dataelement->supportedratescount; i++) {
 | 
					 | 
				
			||||||
		dataraw->supportedrates[i] = dataelement->supportedrates[i];
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_80211_supportedrates_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_80211_supportedrates_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
						unsigned short length;
 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_80211_supportedrates_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
	unsigned short supportedrateslength;
 | 
					 | 
				
			||||||
	struct capwap_80211_supportedrates_element* data;
 | 
						struct capwap_80211_supportedrates_element* data;
 | 
				
			||||||
	struct capwap_80211_supportedrates_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_SUPPORTEDRATES);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	supportedrateslength = ntohs(element->length);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	if (supportedrateslength < 3) {
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						length = func->read_ready(handle);
 | 
				
			||||||
 | 
						if (length < 3) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Supported Rates element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	supportedrateslength -= sizeof(struct capwap_80211_supportedrates_raw_element);
 | 
						length -= 1;
 | 
				
			||||||
	if (supportedrateslength > CAPWAP_SUPPORTEDRATES_MAXLENGTH) {
 | 
						if (length > CAPWAP_RATESET_MAXLENGTH) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Supported Rates element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dataraw = (struct capwap_80211_supportedrates_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	data = (struct capwap_80211_supportedrates_element*)capwap_alloc(sizeof(struct capwap_80211_supportedrates_element));
 | 
						data = (struct capwap_80211_supportedrates_element*)capwap_alloc(sizeof(struct capwap_80211_supportedrates_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						memset(data, 0, sizeof(struct capwap_80211_supportedrates_element));
 | 
				
			||||||
	data->supportedratescount = supportedrateslength;
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
	for (i = 0; i < supportedrateslength; i++) {
 | 
						data->supportedratescount = length;
 | 
				
			||||||
		data->supportedrates[i] = dataraw->supportedrates[i];
 | 
						func->read_block(handle, data->supportedrates, length);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_80211_supportedrates_element_free(void* data) {
 | 
					static void capwap_80211_supportedrates_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_80211_supportedrates_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_80211_supportedrates_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_80211_supportedrates_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_80211_supportedrates_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -7,20 +7,11 @@
 | 
				
			|||||||
#define CAPWAP_SUPPORTEDRATES_MAXLENGTH			8
 | 
					#define CAPWAP_SUPPORTEDRATES_MAXLENGTH			8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_supportedrates_element {
 | 
					struct capwap_80211_supportedrates_element {
 | 
				
			||||||
	unsigned char radioid;
 | 
						uint8_t radioid;
 | 
				
			||||||
	unsigned char supportedratescount;
 | 
						uint8_t supportedratescount;
 | 
				
			||||||
	unsigned char supportedrates[CAPWAP_SUPPORTEDRATES_MAXLENGTH];
 | 
						uint8_t supportedrates[CAPWAP_SUPPORTEDRATES_MAXLENGTH];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_80211_supportedrates_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_80211_supportedrates_ops;
 | 
				
			||||||
int capwap_80211_supportedrates_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_80211_supportedrates_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_80211_supportedrates_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_80211_SUPPORTEDRATES_ELEMENT(x)				({	\
 | 
					 | 
				
			||||||
																		struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_SUPPORTEDRATES);	\
 | 
					 | 
				
			||||||
																		f->create(x, sizeof(struct capwap_80211_supportedrates_element));	\
 | 
					 | 
				
			||||||
																	})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_80211_SUPPORTEDRATES_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_80211_SUPPORTEDRATES_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -15,72 +15,55 @@ Length:   4
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_txpower_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned short currenttxpower;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_80211_txpower_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_80211_txpower_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_80211_txpower_element* element = (struct capwap_80211_txpower_element*)data;
 | 
				
			||||||
	struct capwap_80211_txpower_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	struct capwap_80211_txpower_element* dataelement = (struct capwap_80211_txpower_element*)data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_80211_txpower_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_txpower_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_txpower_raw_element));
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_80211_TXPOWER);
 | 
						func->write_u8(handle, 0);
 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_80211_txpower_raw_element));
 | 
						func->write_u16(handle, element->currenttxpower);
 | 
				
			||||||
	dataraw = (struct capwap_80211_txpower_raw_element*)element->data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	dataraw->currenttxpower = htons(dataelement->currenttxpower);
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_80211_txpower_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_80211_txpower_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_80211_txpower_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_80211_txpower_element* data;
 | 
						struct capwap_80211_txpower_element* data;
 | 
				
			||||||
	struct capwap_80211_txpower_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_TXPOWER);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) != 4) {
 | 
				
			||||||
	if (ntohs(element->length) != 4) {
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Tx Power element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dataraw = (struct capwap_80211_txpower_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	data = (struct capwap_80211_txpower_element*)capwap_alloc(sizeof(struct capwap_80211_txpower_element));
 | 
						data = (struct capwap_80211_txpower_element*)capwap_alloc(sizeof(struct capwap_80211_txpower_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						memset(data, 0, sizeof(struct capwap_80211_txpower_element));
 | 
				
			||||||
	data->currenttxpower = ntohs(dataraw->currenttxpower);
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
 | 
						func->read_u8(handle, NULL);
 | 
				
			||||||
 | 
						func->read_u16(handle, &data->currenttxpower);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_80211_txpower_element_free(void* data) {
 | 
					static void capwap_80211_txpower_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_80211_txpower_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_80211_txpower_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_80211_txpower_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_80211_txpower_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -4,19 +4,10 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_80211_TXPOWER				1041
 | 
					#define CAPWAP_ELEMENT_80211_TXPOWER				1041
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_txpower_element {
 | 
					struct capwap_80211_txpower_element {
 | 
				
			||||||
	unsigned char radioid;
 | 
						uint8_t radioid;
 | 
				
			||||||
	unsigned short currenttxpower;
 | 
						uint16_t currenttxpower;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_80211_txpower_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_80211_txpower_ops;
 | 
				
			||||||
int capwap_80211_txpower_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_80211_txpower_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_80211_txpower_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_80211_TXPOWER_ELEMENT(x)						({	\
 | 
					 | 
				
			||||||
																		struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_TXPOWER);	\
 | 
					 | 
				
			||||||
																		f->create(x, sizeof(struct capwap_80211_txpower_element));	\
 | 
					 | 
				
			||||||
																	})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_80211_TXPOWER_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_80211_TXPOWER_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -15,73 +15,38 @@ Length:   >= 4
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_txpowerlevel_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char numlevels;
 | 
					 | 
				
			||||||
	unsigned short powerlevel[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_80211_txpowerlevel_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_80211_txpowerlevel_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	unsigned short txpowerlength;
 | 
						struct capwap_80211_txpowerlevel_element* element = (struct capwap_80211_txpowerlevel_element*)data;
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					 | 
				
			||||||
	struct capwap_80211_txpowerlevel_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_80211_txpowerlevel_element* dataelement = (struct capwap_80211_txpowerlevel_element*)data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_80211_txpowerlevel_element));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Alloc block of memory */
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	txpowerlength = dataelement->numlevels * sizeof(unsigned char);
 | 
						func->write_u8(handle, element->numlevels);
 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_txpowerlevel_raw_element) + txpowerlength);
 | 
						for (i = 0; i < element->numlevels; i++) {
 | 
				
			||||||
	if (!element) {
 | 
							func->write_u16(handle, element->powerlevel[i]);
 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create message element */
 | 
					 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_txpowerlevel_raw_element) + txpowerlength);
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_80211_TXPOWERLEVEL);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_80211_txpowerlevel_raw_element) + txpowerlength);
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_80211_txpowerlevel_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	dataraw->numlevels = dataelement->numlevels;
 | 
					 | 
				
			||||||
	for (i = 0; i < dataelement->numlevels; i++) {
 | 
					 | 
				
			||||||
		dataraw->powerlevel[i] = htons(dataelement->powerlevel[i]);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_80211_txpowerlevel_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_80211_txpowerlevel_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_80211_txpowerlevel_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	unsigned short txpowerlength;
 | 
						unsigned short length;
 | 
				
			||||||
	struct capwap_80211_txpowerlevel_element* data;
 | 
						struct capwap_80211_txpowerlevel_element* data;
 | 
				
			||||||
	struct capwap_80211_txpowerlevel_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_TXPOWERLEVEL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	txpowerlength = ntohs(element->length);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	if (txpowerlength < 4) {
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						length = func->read_ready(handle);
 | 
				
			||||||
 | 
						if (length < 4) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Tx Power Level element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	txpowerlength -= sizeof(struct capwap_80211_txpowerlevel_raw_element);
 | 
						length -= 2;
 | 
				
			||||||
	if (txpowerlength > (CAPWAP_TXPOWERLEVEL_MAXLENGTH * sizeof(unsigned short))) {
 | 
						if ((length % sizeof(uint16_t)) || ((length / sizeof(uint16_t)) > CAPWAP_TXPOWERLEVEL_MAXLENGTH)) {
 | 
				
			||||||
		return NULL;
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Tx Power Level element");
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_80211_txpowerlevel_raw_element*)element->data;
 | 
					 | 
				
			||||||
	if ((dataraw->numlevels < 1) || (dataraw->numlevels > CAPWAP_TXPOWERLEVEL_MAXLENGTH)) {
 | 
					 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -91,19 +56,35 @@ void* capwap_80211_txpowerlevel_element_parsing(struct capwap_message_element* e
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						memset(data, 0, sizeof(struct capwap_80211_txpowerlevel_element));
 | 
				
			||||||
	data->numlevels = dataraw->numlevels;
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
	for (i = 0; i < dataraw->numlevels; i++) {
 | 
						func->read_u8(handle, &data->numlevels);
 | 
				
			||||||
		data->powerlevel[i] = dataraw->powerlevel[i];
 | 
					
 | 
				
			||||||
 | 
						/* Check */
 | 
				
			||||||
 | 
						if ((data->numlevels * sizeof(uint16_t)) != length) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid IEEE 802.11 Tx Power Level element");
 | 
				
			||||||
 | 
							capwap_free(data);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < data->numlevels; i++) {
 | 
				
			||||||
 | 
							func->read_u16(handle, &data->powerlevel[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_80211_txpowerlevel_element_free(void* data) {
 | 
					static void capwap_80211_txpowerlevel_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_80211_txpowerlevel_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_80211_txpowerlevel_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_80211_txpowerlevel_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_80211_txpowerlevel_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -6,20 +6,11 @@
 | 
				
			|||||||
#define CAPWAP_TXPOWERLEVEL_MAXLENGTH					8
 | 
					#define CAPWAP_TXPOWERLEVEL_MAXLENGTH					8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_txpowerlevel_element {
 | 
					struct capwap_80211_txpowerlevel_element {
 | 
				
			||||||
	unsigned char radioid;
 | 
						uint8_t radioid;
 | 
				
			||||||
	unsigned char numlevels;
 | 
						uint8_t numlevels;
 | 
				
			||||||
	unsigned short powerlevel[CAPWAP_TXPOWERLEVEL_MAXLENGTH];
 | 
						uint16_t powerlevel[CAPWAP_TXPOWERLEVEL_MAXLENGTH];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_80211_txpowerlevel_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_80211_txpowerlevel_ops;
 | 
				
			||||||
int capwap_80211_txpowerlevel_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_80211_txpowerlevel_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_80211_txpowerlevel_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_80211_TXPOWERLEVEL_ELEMENT(x)					({	\
 | 
					 | 
				
			||||||
																		struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_TXPOWERLEVEL);	\
 | 
					 | 
				
			||||||
																		f->create(x, sizeof(struct capwap_80211_txpowerlevel_element));	\
 | 
					 | 
				
			||||||
																	})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_80211_TXPOWERLEVEL_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_80211_TXPOWERLEVEL_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -17,72 +17,53 @@ Length:   5
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_wtpradioinformation_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned long radiotype;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_80211_wtpradioinformation_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_80211_wtpradioinformation_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_80211_wtpradioinformation_element* element = (struct capwap_80211_wtpradioinformation_element*)data;
 | 
				
			||||||
	struct capwap_80211_wtpradioinformation_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	struct capwap_80211_wtpradioinformation_element* dataelement = (struct capwap_80211_wtpradioinformation_element*)data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_80211_wtpradioinformation_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_wtpradioinformation_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_wtpradioinformation_raw_element));
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION);
 | 
						func->write_u32(handle, element->radiotype);
 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_80211_wtpradioinformation_raw_element));
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_80211_wtpradioinformation_raw_element*)element->data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	dataraw->radiotype = htonl(dataelement->radiotype);
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_80211_wtpradioinformation_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_80211_wtpradioinformation_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_80211_wtpradioinformation_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_80211_wtpradioinformation_element* data;
 | 
						struct capwap_80211_wtpradioinformation_element* data;
 | 
				
			||||||
	struct capwap_80211_wtpradioinformation_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) != 5) {
 | 
				
			||||||
	if (ntohs(element->length) != 5) {
 | 
							capwap_logging_debug("Invalid IEEE 802.11 WTP Radio Information element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dataraw = (struct capwap_80211_wtpradioinformation_raw_element*)element->data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	data = (struct capwap_80211_wtpradioinformation_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradioinformation_element));
 | 
						data = (struct capwap_80211_wtpradioinformation_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradioinformation_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						memset(data, 0, sizeof(struct capwap_80211_wtpradioinformation_element));
 | 
				
			||||||
	data->radiotype = ntohl(dataraw->radiotype);
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
 | 
						func->read_u32(handle, &data->radiotype);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_80211_wtpradioinformation_element_free(void* data) {
 | 
					static void capwap_80211_wtpradioinformation_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_80211_wtpradioinformation_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_80211_wtpradioinformation_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_80211_wtpradioinformation_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_80211_wtpradioinformation_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -3,25 +3,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION			1048
 | 
					#define CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION			1048
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CAPWAP_RADIO_TYPE_80211B			0x01
 | 
				
			||||||
 | 
					#define CAPWAP_RADIO_TYPE_80211A			0x02
 | 
				
			||||||
 | 
					#define CAPWAP_RADIO_TYPE_80211G			0x04
 | 
				
			||||||
 | 
					#define CAPWAP_RADIO_TYPE_80211N			0x08
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_80211_wtpradioinformation_element {
 | 
					struct capwap_80211_wtpradioinformation_element {
 | 
				
			||||||
	unsigned char radioid;
 | 
						uint8_t radioid;
 | 
				
			||||||
	unsigned long radiotype;
 | 
						uint32_t radiotype;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_RADIO_TYPE_80211N			0x08
 | 
					extern struct capwap_message_elements_ops capwap_element_80211_wtpradioinformation_ops;
 | 
				
			||||||
#define CAPWAP_RADIO_TYPE_80211G			0x04
 | 
					 | 
				
			||||||
#define CAPWAP_RADIO_TYPE_80211A			0x02
 | 
					 | 
				
			||||||
#define CAPWAP_RADIO_TYPE_80211B			0x01
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_80211_wtpradioinformation_element_create(void* data, unsigned long length);
 | 
					 | 
				
			||||||
int capwap_80211_wtpradioinformation_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_80211_wtpradioinformation_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_80211_wtpradioinformation_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_80211_WTPRADIOINFORMATION_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
																		struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION);	\
 | 
					 | 
				
			||||||
																		f->create(x, sizeof(struct capwap_80211_wtpradioinformation_element));	\
 | 
					 | 
				
			||||||
																	})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
|                  AC Information Sub-Element...
 | 
					|                  AC Information Sub-Element...
 | 
				
			||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
 0                   1                   2                   3
 | 
					 0                   1                   2                   3
 | 
				
			||||||
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 | 
					 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 | 
				
			||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
@ -31,109 +31,53 @@ Length:   >= 12
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_acdescriptor_raw_element {
 | 
					 | 
				
			||||||
	unsigned short stations;
 | 
					 | 
				
			||||||
	unsigned short limit;
 | 
					 | 
				
			||||||
	unsigned short activewtp;
 | 
					 | 
				
			||||||
	unsigned short maxwtp;
 | 
					 | 
				
			||||||
	unsigned char security;
 | 
					 | 
				
			||||||
	unsigned char rmacfield;
 | 
					 | 
				
			||||||
	unsigned char reserved;
 | 
					 | 
				
			||||||
	unsigned char dtlspolicy;
 | 
					 | 
				
			||||||
	char data[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct capwap_acdescriptor_raw_desc_subelement {
 | 
					 | 
				
			||||||
	unsigned long vendor;
 | 
					 | 
				
			||||||
	unsigned short type;
 | 
					 | 
				
			||||||
	unsigned short length;
 | 
					 | 
				
			||||||
	char data[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_acdescriptor_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_acdescriptor_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	char* pos;
 | 
						int i;
 | 
				
			||||||
	unsigned long i;
 | 
						struct capwap_acdescriptor_element* element = (struct capwap_acdescriptor_element*)data;
 | 
				
			||||||
	unsigned short length;
 | 
					
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					 | 
				
			||||||
	struct capwap_acdescriptor_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_acdescriptor_element* dataelement = (struct capwap_acdescriptor_element*)data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_acdescriptor_element));
 | 
					 | 
				
			||||||
	ASSERT(dataelement->descsubelement != NULL);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Calc length packet */
 | 
					 | 
				
			||||||
	length = sizeof(struct capwap_acdescriptor_raw_element);
 | 
					 | 
				
			||||||
	for (i = 0; i < dataelement->descsubelement->count; i++) {
 | 
					 | 
				
			||||||
		struct capwap_acdescriptor_desc_subelement* desc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(dataelement->descsubelement, i);
 | 
					 | 
				
			||||||
		length += sizeof(struct capwap_acdescriptor_raw_desc_subelement) + desc->length;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + length);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create message element */
 | 
					 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + length);
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_ACDESCRIPTION);
 | 
					 | 
				
			||||||
	element->length = htons(length);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Descriptor */
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_acdescriptor_raw_element*)element->data;
 | 
					 | 
				
			||||||
	dataraw->stations = htons(dataelement->station);
 | 
					 | 
				
			||||||
	dataraw->limit = htons(dataelement->stationlimit);
 | 
					 | 
				
			||||||
	dataraw->activewtp = htons(dataelement->wtp);
 | 
					 | 
				
			||||||
	dataraw->maxwtp = htons(dataelement->wtplimit);
 | 
					 | 
				
			||||||
	dataraw->security = dataelement->security;
 | 
					 | 
				
			||||||
	dataraw->rmacfield = dataelement->rmacfield;
 | 
					 | 
				
			||||||
	dataraw->dtlspolicy = dataelement->dtlspolicy;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Descriptor Sub-Element */
 | 
					 | 
				
			||||||
	pos = dataraw->data;
 | 
					 | 
				
			||||||
	for (i = 0; i < dataelement->descsubelement->count; i++) {
 | 
					 | 
				
			||||||
		struct capwap_acdescriptor_raw_desc_subelement* descraw = (struct capwap_acdescriptor_raw_desc_subelement*)pos;
 | 
					 | 
				
			||||||
		struct capwap_acdescriptor_desc_subelement* desc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(dataelement->descsubelement, i);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		descraw->vendor = htonl(desc->vendor);
 | 
					 | 
				
			||||||
		descraw->type = htons(desc->type);
 | 
					 | 
				
			||||||
		descraw->length = htons(desc->length);
 | 
					 | 
				
			||||||
		memcpy(descraw->data, desc->data, desc->length);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		pos += sizeof(struct capwap_acdescriptor_raw_desc_subelement) + desc->length;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
int capwap_acdescriptor_element_validate(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_acdescriptor_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	unsigned char i;
 | 
					 | 
				
			||||||
	long length;
 | 
					 | 
				
			||||||
	char* pos;
 | 
					 | 
				
			||||||
	struct capwap_acdescriptor_element* data;
 | 
					 | 
				
			||||||
	struct capwap_acdescriptor_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_ACDESCRIPTION);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	length = (long)ntohs(element->length);
 | 
					 | 
				
			||||||
	if (length < 12) {
 | 
					 | 
				
			||||||
		capwap_logging_debug("Invalid AC Descriptor element");
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	dataraw = (struct capwap_acdescriptor_raw_element*)element->data;
 | 
						func->write_u16(handle, element->stations);
 | 
				
			||||||
	if ((dataraw->stations > dataraw->limit) || (dataraw->activewtp > dataraw->maxwtp)) {
 | 
						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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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_free(void* data) {
 | 
				
			||||||
 | 
						struct capwap_acdescriptor_element* dataelement = (struct capwap_acdescriptor_element*)data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(dataelement != NULL);
 | 
				
			||||||
 | 
						ASSERT(dataelement->descsubelement != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						capwap_array_free(dataelement->descsubelement);
 | 
				
			||||||
 | 
						capwap_free(dataelement);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					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) {
 | 
				
			||||||
		capwap_logging_debug("Invalid AC Descriptor element");
 | 
							capwap_logging_debug("Invalid AC Descriptor element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -144,56 +88,56 @@ void* capwap_acdescriptor_element_parsing(struct capwap_message_element* element
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(data, 0, sizeof(struct capwap_acdescriptor_element));
 | 
				
			||||||
	data->descsubelement = capwap_array_create(sizeof(struct capwap_acdescriptor_desc_subelement), 0);
 | 
						data->descsubelement = capwap_array_create(sizeof(struct capwap_acdescriptor_desc_subelement), 0);
 | 
				
			||||||
	
 | 
						data->descsubelement->zeroed = 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) || (data->activewtp > data->maxwtp)) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid AC Descriptor element");
 | 
				
			||||||
 | 
							capwap_acdescriptor_element_free(data);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	data->station = htons(dataraw->stations);
 | 
						func->read_u8(handle, &data->security);
 | 
				
			||||||
	data->stationlimit = htons(dataraw->limit);
 | 
						func->read_u8(handle, &data->rmacfield);
 | 
				
			||||||
	data->wtp = htons(dataraw->activewtp);
 | 
						func->read_u8(handle, NULL);
 | 
				
			||||||
	data->wtplimit = htons(dataraw->maxwtp);
 | 
						func->read_u8(handle, &data->dtlspolicy);
 | 
				
			||||||
	data->security = dataraw->security;
 | 
					
 | 
				
			||||||
	data->rmacfield = dataraw->rmacfield;
 | 
					 | 
				
			||||||
	data->dtlspolicy = dataraw->dtlspolicy;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	pos = dataraw->data;
 | 
					 | 
				
			||||||
	length -= sizeof(struct capwap_acdescriptor_raw_element);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Description Subelement */
 | 
						/* Description Subelement */
 | 
				
			||||||
	i = 0;
 | 
						while (func->read_ready(handle) > 0) {
 | 
				
			||||||
	while (length > 0) {
 | 
							unsigned short length;
 | 
				
			||||||
		struct capwap_acdescriptor_desc_subelement* desc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(data->descsubelement, i);
 | 
							struct capwap_acdescriptor_desc_subelement* desc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(data->descsubelement, data->descsubelement->count);
 | 
				
			||||||
		struct capwap_acdescriptor_raw_desc_subelement* descraw = (struct capwap_acdescriptor_raw_desc_subelement*)pos;
 | 
					
 | 
				
			||||||
		unsigned short desclength = ntohs(descraw->length);
 | 
							/* */
 | 
				
			||||||
		unsigned short descrawlength = sizeof(struct capwap_acdescriptor_raw_desc_subelement) + desclength;
 | 
							func->read_u32(handle, &desc->vendor);
 | 
				
			||||||
		
 | 
							func->read_u16(handle, &desc->type);
 | 
				
			||||||
		if ((desclength > CAPWAP_ACDESC_SUBELEMENT_MAXDATA) || (length < descrawlength)) {
 | 
							func->read_u16(handle, &desc->length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Check buffer size */
 | 
				
			||||||
 | 
							length = func->read_ready(handle);
 | 
				
			||||||
 | 
							if ((length > CAPWAP_ACDESC_SUBELEMENT_MAXDATA) || (length < desc->length)) {
 | 
				
			||||||
			capwap_logging_debug("Invalid AC Descriptor element");
 | 
								capwap_logging_debug("Invalid AC Descriptor element");
 | 
				
			||||||
			capwap_acdescriptor_element_free(data);
 | 
								capwap_acdescriptor_element_free(data);
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		/* */
 | 
					 | 
				
			||||||
		desc->vendor = ntohl(descraw->vendor);
 | 
					 | 
				
			||||||
		desc->type = ntohs(descraw->type);
 | 
					 | 
				
			||||||
		desc->length = desclength;
 | 
					 | 
				
			||||||
		memcpy(desc->data, descraw->data, desclength);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* */
 | 
							func->read_block(handle, desc->data, desc->length);
 | 
				
			||||||
		i++;
 | 
					 | 
				
			||||||
		pos += descrawlength;
 | 
					 | 
				
			||||||
		length -= descrawlength;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_acdescriptor_element_free(void* data) {
 | 
					struct capwap_message_elements_ops capwap_element_acdescriptor_ops = {
 | 
				
			||||||
	struct capwap_acdescriptor_element* dataelement = (struct capwap_acdescriptor_element*)data;
 | 
						.create_message_element = capwap_acdescriptor_element_create,
 | 
				
			||||||
	
 | 
						.parsing_message_element = capwap_acdescriptor_element_parsing,
 | 
				
			||||||
	ASSERT(dataelement != NULL);
 | 
						.free_parsed_message_element = capwap_acdescriptor_element_free
 | 
				
			||||||
	ASSERT(dataelement->descsubelement != NULL);
 | 
					};
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	capwap_array_free(dataelement->descsubelement);
 | 
					 | 
				
			||||||
	capwap_free(dataelement);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -13,13 +13,13 @@
 | 
				
			|||||||
#define CAPWAP_ACDESC_CLEAR_DATA_CHANNEL_ENABLED	0x02
 | 
					#define CAPWAP_ACDESC_CLEAR_DATA_CHANNEL_ENABLED	0x02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_acdescriptor_element {
 | 
					struct capwap_acdescriptor_element {
 | 
				
			||||||
	unsigned short station;
 | 
						uint16_t stations;
 | 
				
			||||||
	unsigned short stationlimit;
 | 
						uint16_t stationlimit;
 | 
				
			||||||
	unsigned short wtp;
 | 
						uint16_t activewtp;
 | 
				
			||||||
	unsigned short wtplimit;
 | 
						uint16_t maxwtp;
 | 
				
			||||||
	unsigned char security;
 | 
						uint8_t security;
 | 
				
			||||||
	unsigned char rmacfield;
 | 
						uint8_t rmacfield;
 | 
				
			||||||
	unsigned char dtlspolicy;
 | 
						uint8_t dtlspolicy;
 | 
				
			||||||
	struct capwap_array* descsubelement;
 | 
						struct capwap_array* descsubelement;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -28,21 +28,12 @@ struct capwap_acdescriptor_element {
 | 
				
			|||||||
#define CAPWAP_ACDESC_SUBELEMENT_MAXDATA					1024
 | 
					#define CAPWAP_ACDESC_SUBELEMENT_MAXDATA					1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_acdescriptor_desc_subelement {
 | 
					struct capwap_acdescriptor_desc_subelement {
 | 
				
			||||||
	unsigned long vendor;
 | 
						uint32_t vendor;
 | 
				
			||||||
	unsigned short type;
 | 
						uint16_t type;
 | 
				
			||||||
	unsigned short length;
 | 
						uint16_t length;
 | 
				
			||||||
	char data[CAPWAP_ACDESC_SUBELEMENT_MAXDATA];
 | 
						uint8_t data[CAPWAP_ACDESC_SUBELEMENT_MAXDATA];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_acdescriptor_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_acdescriptor_ops;
 | 
				
			||||||
int capwap_acdescriptor_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_acdescriptor_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_acdescriptor_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_ACDESCRIPTOR_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_ACDESCRIPTION);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_acdescriptor_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_ACDESCRIPTOR_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_ACDESCRIPTOR_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,94 +10,68 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   2 for AC IPv4 List
 | 
					Type:   2 for AC IPv4 List
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   >= 4
 | 
					Length:   >= 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_acipv4list_raw_element {
 | 
					 | 
				
			||||||
	unsigned long address;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_acipv4list_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_acipv4list_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	int i;
 | 
						unsigned long i;
 | 
				
			||||||
	int items;
 | 
						struct capwap_acipv4list_element* element = (struct capwap_acipv4list_element*)data;
 | 
				
			||||||
	unsigned short sizeitems;
 | 
					
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					 | 
				
			||||||
	capwap_acipv4list_element_array* dataarray = (capwap_acipv4list_element_array*)data;
 | 
					 | 
				
			||||||
	struct capwap_acipv4list_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(capwap_acipv4list_element_array));
 | 
					
 | 
				
			||||||
	
 | 
						/* */
 | 
				
			||||||
	items = min(dataarray->count, CAPWAP_ACIPV4LIST_MAX_ELEMENTS);
 | 
						for (i = 0; i < element->addresses->count; i++) {
 | 
				
			||||||
	
 | 
							func->write_block(handle, (uint8_t*)capwap_array_get_item_pointer(element->addresses, i), sizeof(struct in_addr));
 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	sizeitems = sizeof(struct capwap_acipv4list_raw_element) * items;
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeitems);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create message element */
 | 
					 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeitems);
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_ACIPV4LIST);
 | 
					 | 
				
			||||||
	element->length = htons(sizeitems);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_acipv4list_raw_element*)element->data;
 | 
					 | 
				
			||||||
	for (i = 0; i < items; i++) {
 | 
					 | 
				
			||||||
		struct capwap_acipv4list_element* dataelement = (struct capwap_acipv4list_element*)capwap_array_get_item_pointer(dataarray, i);
 | 
					 | 
				
			||||||
		dataraw->address = dataelement->address.s_addr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Next raw item */
 | 
					 | 
				
			||||||
		dataraw++;		
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_acipv4list_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_acipv4list_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
						uint16_t length;
 | 
				
			||||||
	return 1;
 | 
						struct capwap_acipv4list_element* data;
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
void* capwap_acipv4list_element_parsing(struct capwap_message_element* element) {
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	int i;
 | 
					
 | 
				
			||||||
	int items;
 | 
						length = func->read_ready(handle);
 | 
				
			||||||
	unsigned short length;
 | 
						if ((length >= 4) && (length <= CAPWAP_ACIPV4LIST_MAX_ELEMENTS * 4) && (length % 4)) {
 | 
				
			||||||
	capwap_acipv4list_element_array* data;
 | 
							capwap_logging_debug("Invalid AC IPv4 List element");
 | 
				
			||||||
	struct capwap_acipv4list_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_ACIPV4LIST);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	length = ntohs(element->length);
 | 
					 | 
				
			||||||
	if ((length > 0) && ((length % sizeof(struct capwap_acipv4list_raw_element)) != 0)) {
 | 
					 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	items = length / sizeof(struct capwap_acipv4list_raw_element);
 | 
						data = (struct capwap_acipv4list_element*)capwap_alloc(sizeof(struct capwap_acipv4list_element));
 | 
				
			||||||
	data = (capwap_acipv4list_element_array*)capwap_array_create(sizeof(struct capwap_acipv4list_element), items);
 | 
						if (!data) {
 | 
				
			||||||
 | 
							capwap_outofmemory();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	dataraw = (struct capwap_acipv4list_raw_element*)element->data;
 | 
						data->addresses = capwap_array_create(sizeof(struct in_addr), 0);
 | 
				
			||||||
	for (i = 0; i < items; i++) {
 | 
						while (length > 0) {
 | 
				
			||||||
		struct capwap_acipv4list_element* dataelement = (struct capwap_acipv4list_element*)capwap_array_get_item_pointer(data, i);
 | 
							struct in_addr* address = (struct in_addr*)capwap_array_get_item_pointer(data->addresses, data->addresses->count);
 | 
				
			||||||
		dataelement->address.s_addr = dataraw->address;
 | 
							func->read_block(handle, (uint8_t*)address, sizeof(struct in_addr));
 | 
				
			||||||
 | 
							length -= 4;
 | 
				
			||||||
		/* Next raw item */
 | 
					 | 
				
			||||||
		dataraw++;		
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_acipv4list_element_free(void* data) {
 | 
					static void capwap_acipv4list_element_free(void* data) {
 | 
				
			||||||
 | 
						struct capwap_acipv4list_element* element = (struct capwap_acipv4list_element*)data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_array_free((capwap_acipv4list_element_array*)data);
 | 
						capwap_array_free(element->addresses);
 | 
				
			||||||
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_acipv4list_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_acipv4list_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_acipv4list_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_acipv4list_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -5,21 +5,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ACIPV4LIST_MAX_ELEMENTS						1024
 | 
					#define CAPWAP_ACIPV4LIST_MAX_ELEMENTS						1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct capwap_array capwap_acipv4list_element_array;
 | 
					 | 
				
			||||||
struct capwap_acipv4list_element {
 | 
					struct capwap_acipv4list_element {
 | 
				
			||||||
	struct in_addr address;
 | 
						struct capwap_array* addresses;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_acipv4list_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_acipv4list_ops;
 | 
				
			||||||
int capwap_acipv4list_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_acipv4list_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_acipv4list_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_ACIPV4LIST_ELEMENT(x)				({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_ACIPV4LIST);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(capwap_acipv4list_element_array));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_ACIPV4LIST_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_ACIPV4LIST_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -16,94 +16,68 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   3 for AC IPV6 List
 | 
					Type:   3 for AC IPV6 List
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   >= 16
 | 
					Length:   >= 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_acipv6list_raw_element {
 | 
					 | 
				
			||||||
	unsigned long address[4];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_acipv6list_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_acipv6list_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	int i;
 | 
						unsigned long i;
 | 
				
			||||||
	int items;
 | 
						struct capwap_acipv6list_element* element = (struct capwap_acipv6list_element*)data;
 | 
				
			||||||
	unsigned short sizeitems;
 | 
					
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					 | 
				
			||||||
	capwap_acipv6list_element_array* dataarray = (capwap_acipv6list_element_array*)data;
 | 
					 | 
				
			||||||
	struct capwap_acipv6list_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(capwap_acipv6list_element_array));
 | 
					
 | 
				
			||||||
	
 | 
						/* */
 | 
				
			||||||
	items = min(dataarray->count, CAPWAP_ACIPV6LIST_MAX_ELEMENTS);
 | 
						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));
 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	sizeitems = sizeof(struct capwap_acipv6list_raw_element) * items;
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeitems);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create message element */
 | 
					 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeitems);
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_ACIPV6LIST);
 | 
					 | 
				
			||||||
	element->length = htons(sizeitems);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_acipv6list_raw_element*)element->data;
 | 
					 | 
				
			||||||
	for (i = 0; i < items; i++) {
 | 
					 | 
				
			||||||
		struct capwap_acipv6list_element* dataelement = (struct capwap_acipv6list_element*)capwap_array_get_item_pointer(dataarray, i);
 | 
					 | 
				
			||||||
		memcpy(dataraw->address, dataelement->address.s6_addr32, sizeof(unsigned long) * 4);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Next raw item */
 | 
					 | 
				
			||||||
		dataraw++;		
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_acipv6list_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_acipv6list_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
						uint16_t length;
 | 
				
			||||||
	return 1;
 | 
						struct capwap_acipv6list_element* data;
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
void* capwap_acipv6list_element_parsing(struct capwap_message_element* element) {
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	int i;
 | 
					
 | 
				
			||||||
	int items;
 | 
						length = func->read_ready(handle);
 | 
				
			||||||
	unsigned short length;
 | 
						if ((length >= 16) && (length <= CAPWAP_ACIPV4LIST_MAX_ELEMENTS * 16) && (length % 16)) {
 | 
				
			||||||
	capwap_acipv6list_element_array* data;
 | 
							capwap_logging_debug("Invalid AC IPv6 List element");
 | 
				
			||||||
	struct capwap_acipv6list_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_ACIPV6LIST);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	length = ntohs(element->length);
 | 
					 | 
				
			||||||
	if ((length > 0) && ((length % sizeof(struct capwap_acipv6list_raw_element)) != 0)) {
 | 
					 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	items = length / sizeof(struct capwap_acipv6list_raw_element);
 | 
						data = (struct capwap_acipv6list_element*)capwap_alloc(sizeof(struct capwap_acipv6list_element));
 | 
				
			||||||
	data = (capwap_acipv6list_element_array*)capwap_array_create(sizeof(struct capwap_acipv6list_element), items);
 | 
						if (!data) {
 | 
				
			||||||
 | 
							capwap_outofmemory();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	dataraw = (struct capwap_acipv6list_raw_element*)element->data;
 | 
						data->addresses = capwap_array_create(sizeof(struct in6_addr), 0);
 | 
				
			||||||
	for (i = 0; i < items; i++) {
 | 
						while (length > 0) {
 | 
				
			||||||
		struct capwap_acipv6list_element* dataelement = (struct capwap_acipv6list_element*)capwap_array_get_item_pointer(data, i);
 | 
							struct in6_addr* address = (struct in6_addr*)capwap_array_get_item_pointer(data->addresses, data->addresses->count);
 | 
				
			||||||
		memcpy(dataelement->address.s6_addr32, dataraw->address, sizeof(unsigned long) * 4);
 | 
							func->read_block(handle, (uint8_t*)address, sizeof(struct in6_addr));
 | 
				
			||||||
 | 
							length -= 16;
 | 
				
			||||||
		/* Next raw item */
 | 
					 | 
				
			||||||
		dataraw++;		
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_acipv6list_element_free(void* data) {
 | 
					static void capwap_acipv6list_element_free(void* data) {
 | 
				
			||||||
 | 
						struct capwap_acipv6list_element* element = (struct capwap_acipv6list_element*)data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_array_free((capwap_acipv6list_element_array*)data);
 | 
						capwap_array_free(element->addresses);
 | 
				
			||||||
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_acipv6list_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_acipv6list_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_acipv6list_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_acipv6list_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -5,21 +5,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ACIPV6LIST_MAX_ELEMENTS						1024
 | 
					#define CAPWAP_ACIPV6LIST_MAX_ELEMENTS						1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct capwap_array capwap_acipv6list_element_array;
 | 
					 | 
				
			||||||
struct capwap_acipv6list_element {
 | 
					struct capwap_acipv6list_element {
 | 
				
			||||||
	struct in6_addr address;
 | 
						struct capwap_array* addresses;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_acipv6list_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_acipv6list_ops;
 | 
				
			||||||
int capwap_acipv6list_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_acipv6list_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_acipv6list_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_ACIPV6LIST_ELEMENT(x)				({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_ACIPV6LIST);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(capwap_acipv6list_element_array));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_ACIPV6LIST_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_ACIPV6LIST_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,77 +10,57 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   4 for AC Name
 | 
					Type:   4 for AC Name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   >= 1
 | 
					Length:   >= 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_acname_raw_element {
 | 
					 | 
				
			||||||
	char name[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_acname_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_acname_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	unsigned short namelength;
 | 
						struct capwap_acname_element* element = (struct capwap_acname_element*)data;
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					
 | 
				
			||||||
	struct capwap_acname_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_acname_element* dataelement = (struct capwap_acname_element*)data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_acname_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	namelength = strlen(dataelement->name);
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + namelength);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						func->write_block(handle, element->name, strlen((char*)element->name));
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + namelength);
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_ACNAME);
 | 
					 | 
				
			||||||
	element->length = htons(namelength);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_acname_raw_element*)element->data;
 | 
					 | 
				
			||||||
	memcpy(&dataraw->name[0], &dataelement->name[0], namelength);
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_acname_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_acname_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
						unsigned short length;
 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_acname_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	unsigned short namelength;
 | 
					 | 
				
			||||||
	struct capwap_acname_element* data;
 | 
						struct capwap_acname_element* data;
 | 
				
			||||||
	struct capwap_acname_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_ACNAME);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	namelength = ntohs(element->length);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	if (!namelength  || (namelength > CAPWAP_ACNAME_MAXLENGTH))  {
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						length = func->read_ready(handle);
 | 
				
			||||||
 | 
						if ((length < 1) || (length > CAPWAP_ACNAME_MAXLENGTH)) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid AC Name element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	dataraw = (struct capwap_acname_raw_element*)element->data;
 | 
					 | 
				
			||||||
	data = (struct capwap_acname_element*)capwap_alloc(sizeof(struct capwap_acname_element));
 | 
						data = (struct capwap_acname_element*)capwap_alloc(sizeof(struct capwap_acname_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	memcpy(&data->name[0], &dataraw->name[0], namelength);
 | 
						memset(data, 0, sizeof(struct capwap_acname_element));
 | 
				
			||||||
	data->name[namelength] = 0;
 | 
						func->read_block(handle, data->name, length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_acname_element_free(void* data) {
 | 
					static void capwap_acname_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_acname_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_acname_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_acname_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_acname_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -6,19 +6,9 @@
 | 
				
			|||||||
#define CAPWAP_ACNAME_MAXLENGTH			512
 | 
					#define CAPWAP_ACNAME_MAXLENGTH			512
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_acname_element {
 | 
					struct capwap_acname_element {
 | 
				
			||||||
	char name[CAPWAP_ACNAME_MAXLENGTH + 1];
 | 
						uint8_t name[CAPWAP_ACNAME_MAXLENGTH + 1];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_acname_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_acname_ops;
 | 
				
			||||||
int capwap_acname_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_acname_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_acname_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_ACNAME_ELEMENT(x)					({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_ACNAME);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_acname_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_ACNAME_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_ACNAME_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,82 +10,59 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   5 for AC Name with Priority
 | 
					Type:   5 for AC Name with Priority
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   >= 2
 | 
					Length:   >= 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_acnamepriority_raw_element {
 | 
					 | 
				
			||||||
	unsigned char priority;
 | 
					 | 
				
			||||||
	char name[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_acnamepriority_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_acnamepriority_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	unsigned short namelength;
 | 
						struct capwap_acnamepriority_element* element = (struct capwap_acnamepriority_element*)data;
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					
 | 
				
			||||||
	struct capwap_acnamepriority_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_acnamepriority_element* dataelement = (struct capwap_acnamepriority_element*)data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_acnamepriority_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	namelength = strlen(dataelement->name);
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_acnamepriority_raw_element) + namelength);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						func->write_u8(handle, element->priority);
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_acnamepriority_raw_element) + namelength);
 | 
						func->write_block(handle, element->name, strlen((char*)element->name));
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_ACNAMEPRIORITY);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_acnamepriority_raw_element) + namelength);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_acnamepriority_raw_element*)element->data;
 | 
					 | 
				
			||||||
	dataraw->priority = dataelement->priority;
 | 
					 | 
				
			||||||
	memcpy(&dataraw->name[0], &dataelement->name[0], namelength);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_acnamepriority_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_acnamepriority_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
						unsigned short length;
 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_acnamepriority_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	unsigned short namelength;
 | 
					 | 
				
			||||||
	struct capwap_acnamepriority_element* data;
 | 
						struct capwap_acnamepriority_element* data;
 | 
				
			||||||
	struct capwap_acnamepriority_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_ACNAMEPRIORITY);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	namelength = ntohs(element->length) - sizeof(struct capwap_acnamepriority_raw_element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	if (!namelength  || (namelength > CAPWAP_ACNAMEPRIORITY_MAXLENGTH))  {
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						length = func->read_ready(handle) - 1;
 | 
				
			||||||
 | 
						if ((length < 1) || (length > CAPWAP_ACNAMEPRIORITY_MAXLENGTH)) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid AC Name Priority element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	dataraw = (struct capwap_acnamepriority_raw_element*)element->data;
 | 
					 | 
				
			||||||
	data = (struct capwap_acnamepriority_element*)capwap_alloc(sizeof(struct capwap_acnamepriority_element));
 | 
						data = (struct capwap_acnamepriority_element*)capwap_alloc(sizeof(struct capwap_acnamepriority_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->priority = dataraw->priority;
 | 
						memset(data, 0, sizeof(struct capwap_acnamepriority_element));
 | 
				
			||||||
	memcpy(&data->name[0], &dataraw->name[0], namelength);
 | 
						func->read_u8(handle, &data->priority);
 | 
				
			||||||
	data->name[namelength] = 0;
 | 
						func->read_block(handle, data->name, length);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_acnamepriority_element_free(void* data) {
 | 
					static void capwap_acnamepriority_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_acnamepriority_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_acnamepriority_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_acnamepriority_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_acnamepriority_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -6,20 +6,10 @@
 | 
				
			|||||||
#define CAPWAP_ACNAMEPRIORITY_MAXLENGTH			512
 | 
					#define CAPWAP_ACNAMEPRIORITY_MAXLENGTH			512
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_acnamepriority_element {
 | 
					struct capwap_acnamepriority_element {
 | 
				
			||||||
	unsigned char priority;
 | 
						uint8_t priority;
 | 
				
			||||||
	char name[CAPWAP_ACNAMEPRIORITY_MAXLENGTH + 1];
 | 
						uint8_t name[CAPWAP_ACNAMEPRIORITY_MAXLENGTH + 1];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_acnamepriority_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_acnamepriority_ops;
 | 
				
			||||||
int capwap_acnamepriority_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_acnamepriority_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_acnamepriority_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_ACNAMEPRIORITY_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_ACNAMEPRIORITY);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_acnamepriority_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_ACNAMEPRIORITY_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_ACNAMEPRIORITY_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -12,57 +12,31 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   10 for CAPWAP Control IPv4 Address
 | 
					Type:   10 for CAPWAP Control IPv4 Address
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   6
 | 
					Length:   6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_controlipv4_raw_element {
 | 
					 | 
				
			||||||
	unsigned long address;
 | 
					 | 
				
			||||||
	unsigned short wtpcount;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_controlipv4_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_controlipv4_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_controlipv4_element* element = (struct capwap_controlipv4_element*)data;
 | 
				
			||||||
	struct capwap_controlipv4_element* dataelement = (struct capwap_controlipv4_element*)data;
 | 
					
 | 
				
			||||||
	struct capwap_controlipv4_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_controlipv4_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_controlipv4_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_controlipv4_raw_element));
 | 
						func->write_block(handle, (uint8_t*)&element->address, sizeof(struct in_addr));
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_CONTROLIPV4);
 | 
						func->write_u16(handle, element->wtpcount);
 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_controlipv4_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_controlipv4_raw_element*)element->data;
 | 
					 | 
				
			||||||
	dataraw->address = dataelement->address.s_addr;
 | 
					 | 
				
			||||||
	dataraw->wtpcount = htons(dataelement->wtpcount);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_controlipv4_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_controlipv4_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_controlipv4_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_controlipv4_element* data;
 | 
						struct capwap_controlipv4_element* data;
 | 
				
			||||||
	struct capwap_controlipv4_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_CONTROLIPV4);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) != 6) {
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_controlipv4_raw_element)) {
 | 
							capwap_logging_debug("Invalid Control IPv4 Address element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -72,17 +46,24 @@ void* capwap_controlipv4_element_parsing(struct capwap_message_element* element)
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	dataraw = (struct capwap_controlipv4_raw_element*)element->data;
 | 
						memset(data, 0, sizeof(struct capwap_controlipv4_element));
 | 
				
			||||||
	data->address.s_addr = dataraw->address;
 | 
						func->read_block(handle, (uint8_t*)&data->address, sizeof(struct in_addr));
 | 
				
			||||||
	data->wtpcount = ntohs(dataraw->wtpcount);
 | 
						func->read_u16(handle, &data->wtpcount);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_controlipv4_element_free(void* data) {
 | 
					static void capwap_controlipv4_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_controlipv4_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_controlipv4_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_controlipv4_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_controlipv4_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -5,19 +5,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct capwap_controlipv4_element {
 | 
					struct capwap_controlipv4_element {
 | 
				
			||||||
	struct in_addr address;
 | 
						struct in_addr address;
 | 
				
			||||||
	unsigned short wtpcount;
 | 
						uint16_t wtpcount;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_controlipv4_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_controlipv4_ops;
 | 
				
			||||||
int capwap_controlipv4_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_controlipv4_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_controlipv4_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_CONTROLIPV4_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_CONTROLIPV4);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_controlipv4_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_CONTROLIPV4_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_CONTROLIPV4_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -18,57 +18,31 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   11 for CAPWAP Control IPv6 Address
 | 
					Type:   11 for CAPWAP Control IPv6 Address
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   18
 | 
					Length:   18
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_controlipv6_raw_element {
 | 
					 | 
				
			||||||
	unsigned long address[4];
 | 
					 | 
				
			||||||
	unsigned short wtpcount;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_controlipv6_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_controlipv6_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_controlipv6_element* element = (struct capwap_controlipv6_element*)data;
 | 
				
			||||||
	struct capwap_controlipv6_element* dataelement = (struct capwap_controlipv6_element*)data;
 | 
					
 | 
				
			||||||
	struct capwap_controlipv6_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_controlipv6_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_controlipv6_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_controlipv6_raw_element));
 | 
						func->write_block(handle, (uint8_t*)&element->address, sizeof(struct in6_addr));
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_CONTROLIPV6);
 | 
						func->write_u16(handle, element->wtpcount);
 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_controlipv6_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_controlipv6_raw_element*)element->data;
 | 
					 | 
				
			||||||
	memcpy(dataraw->address, dataelement->address.s6_addr32, sizeof(unsigned long) * 4);
 | 
					 | 
				
			||||||
	dataraw->wtpcount = htons(dataelement->wtpcount);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_controlipv6_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_controlipv6_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_controlipv6_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_controlipv6_element* data;
 | 
						struct capwap_controlipv6_element* data;
 | 
				
			||||||
	struct capwap_controlipv6_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_CONTROLIPV6);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) != 18) {
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_controlipv6_raw_element)) {
 | 
							capwap_logging_debug("Invalid Control IPv6 Address element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,17 +52,24 @@ void* capwap_controlipv6_element_parsing(struct capwap_message_element* element)
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	dataraw = (struct capwap_controlipv6_raw_element*)element->data;
 | 
						memset(data, 0, sizeof(struct capwap_controlipv6_element));
 | 
				
			||||||
	memcpy(data->address.s6_addr32, dataraw->address, sizeof(unsigned long) * 4);
 | 
						func->read_block(handle, (uint8_t*)&data->address, sizeof(struct in6_addr));
 | 
				
			||||||
	data->wtpcount = ntohs(dataraw->wtpcount);
 | 
						func->read_u16(handle, &data->wtpcount);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_controlipv6_element_free(void* data) {
 | 
					static void capwap_controlipv6_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_controlipv6_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_controlipv6_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_controlipv6_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_controlipv6_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -8,16 +8,6 @@ struct capwap_controlipv6_element {
 | 
				
			|||||||
	unsigned short wtpcount;
 | 
						unsigned short wtpcount;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_controlipv6_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_controlipv6_ops;
 | 
				
			||||||
int capwap_controlipv6_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_controlipv6_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_controlipv6_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_CONTROLIPV6_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_CONTROLIPV6);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_controlipv6_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_CONTROLIPV4_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_CONTROLIPV4_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,57 +10,31 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   16 for Decryption Error Report Period
 | 
					Type:   16 for Decryption Error Report Period
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  3
 | 
					Length:  3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_decrypterrorreportperiod_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned short interval;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_decrypterrorreportperiod_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_decrypterrorreportperiod_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_decrypterrorreportperiod_element* element = (struct capwap_decrypterrorreportperiod_element*)data;
 | 
				
			||||||
	struct capwap_decrypterrorreportperiod_element* dataelement = (struct capwap_decrypterrorreportperiod_element*)data;
 | 
					
 | 
				
			||||||
	struct capwap_decrypterrorreportperiod_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_decrypterrorreportperiod_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_decrypterrorreportperiod_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_decrypterrorreportperiod_raw_element));
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD);
 | 
						func->write_u16(handle, element->interval);
 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_decrypterrorreportperiod_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_decrypterrorreportperiod_raw_element*)element->data;
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	dataraw->interval = htons(dataelement->interval);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_decrypterrorreportperiod_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_decrypterrorreportperiod_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_decrypterrorreportperiod_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_decrypterrorreportperiod_element* data;
 | 
						struct capwap_decrypterrorreportperiod_element* data;
 | 
				
			||||||
	struct capwap_decrypterrorreportperiod_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) != 3) {
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_decrypterrorreportperiod_raw_element)) {
 | 
							capwap_logging_debug("Invalid Decryption Error Report Period element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -70,17 +44,24 @@ void* capwap_decrypterrorreportperiod_element_parsing(struct capwap_message_elem
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	dataraw = (struct capwap_decrypterrorreportperiod_raw_element*)element->data;
 | 
						memset(data, 0, sizeof(struct capwap_decrypterrorreportperiod_element));
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
	data->interval = ntohs(dataraw->interval);
 | 
						func->read_u16(handle, &data->interval);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_decrypterrorreportperiod_element_free(void* data) {
 | 
					static void capwap_decrypterrorreportperiod_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_decrypterrorreportperiod_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_decrypterrorreportperiod_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_decrypterrorreportperiod_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_decrypterrorreportperiod_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -4,19 +4,10 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD			16
 | 
					#define CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD			16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_decrypterrorreportperiod_element {
 | 
					struct capwap_decrypterrorreportperiod_element {
 | 
				
			||||||
	unsigned char radioid;
 | 
						uint8_t radioid;
 | 
				
			||||||
	unsigned short interval;
 | 
						uint16_t interval;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_decrypterrorreportperiod_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_decrypterrorreportperiod_ops;
 | 
				
			||||||
int capwap_decrypterrorreportperiod_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_decrypterrorreportperiod_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_decrypterrorreportperiod_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_DECRYPTERRORREPORTPERIOD_ELEMENT(x)		({	\
 | 
					 | 
				
			||||||
																	struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD);	\
 | 
					 | 
				
			||||||
																	f->create(x, sizeof(struct capwap_decrypterrorreportperiod_element));	\
 | 
					 | 
				
			||||||
																})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,49 +10,30 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   20 for Discovery Type
 | 
					Type:   20 for Discovery Type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   1
 | 
					Length:   1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_discoverytype_raw_element {
 | 
					 | 
				
			||||||
	unsigned char type;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_discoverytype_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_discoverytype_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_discoverytype_element* element = (struct capwap_discoverytype_element*)data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_discoverytype_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_discoverytype_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_discoverytype_raw_element));
 | 
						func->write_u8(handle, element->type);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_DISCOVERYTYPE);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_discoverytype_raw_element));
 | 
					 | 
				
			||||||
	((struct capwap_discoverytype_raw_element*)element->data)->type = ((struct capwap_discoverytype_element*)data)->type;
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_discoverytype_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_discoverytype_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_discoverytype_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_discoverytype_element* data;
 | 
						struct capwap_discoverytype_element* data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_DISCOVERYTYPE);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_discoverytype_raw_element)) {
 | 
						if (func->read_ready(handle) != 1) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid Discovery Type element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -62,14 +43,23 @@ void* capwap_discoverytype_element_parsing(struct capwap_message_element* elemen
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->type = ((struct capwap_discoverytype_raw_element*)element->data)->type;
 | 
						memset(data, 0, sizeof(struct capwap_discoverytype_element));
 | 
				
			||||||
 | 
						func->read_u8(handle, &data->type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_discoverytype_element_free(void* data) {
 | 
					static void capwap_discoverytype_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_discoverytype_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_discoverytype_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_discoverytype_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_discoverytype_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -10,19 +10,9 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_DISCOVERYTYPE_TYPE_ACREFERRAL		4
 | 
					#define CAPWAP_ELEMENT_DISCOVERYTYPE_TYPE_ACREFERRAL		4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_discoverytype_element {
 | 
					struct capwap_discoverytype_element {
 | 
				
			||||||
	unsigned char type;
 | 
						uint8_t type;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_discoverytype_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_discoverytype_ops;
 | 
				
			||||||
int capwap_discoverytype_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_discoverytype_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_discoverytype_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_DISCOVERYTYPE_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_DISCOVERYTYPE);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_discoverytype_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_DISCOVERYTYPE_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_DISCOVERYTYPE_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,51 +10,30 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   53 for ECN Support
 | 
					Type:   53 for ECN Support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  1
 | 
					Length:  1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_ecnsupport_raw_element {
 | 
					 | 
				
			||||||
	char flag;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_ecnsupport_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_ecnsupport_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_ecnsupport_element* element = (struct capwap_ecnsupport_element*)data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_ecnsupport_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_ecnsupport_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_ecnsupport_raw_element));
 | 
						func->write_u8(handle, element->flag);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_ECNSUPPORT);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_ecnsupport_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	((struct capwap_ecnsupport_raw_element*)element->data)->flag = ((struct capwap_ecnsupport_element*)data)->flag;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_ecnsupport_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_ecnsupport_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_ecnsupport_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_ecnsupport_element* data;
 | 
						struct capwap_ecnsupport_element* data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_ECNSUPPORT);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_ecnsupport_raw_element)) {
 | 
						if (func->read_ready(handle) != 1) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid ECN Support element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,14 +43,23 @@ void* capwap_ecnsupport_element_parsing(struct capwap_message_element* element)
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->flag = ((struct capwap_ecnsupport_raw_element*)element->data)->flag;
 | 
						memset(data, 0, sizeof(struct capwap_ecnsupport_element));
 | 
				
			||||||
 | 
						func->read_u8(handle, &data->flag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_ecnsupport_element_free(void* data) {
 | 
					static void capwap_ecnsupport_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_ecnsupport_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_ecnsupport_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_ecnsupport_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_ecnsupport_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -3,22 +3,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ELEMENT_ECNSUPPORT			53
 | 
					#define CAPWAP_ELEMENT_ECNSUPPORT			53
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_ecnsupport_element {
 | 
					 | 
				
			||||||
	char flag;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CAPWAP_LIMITED_ECN_SUPPORT			0
 | 
					#define CAPWAP_LIMITED_ECN_SUPPORT			0
 | 
				
			||||||
#define CAPWAP_FULL_ECN_SUPPORT				1
 | 
					#define CAPWAP_FULL_ECN_SUPPORT				1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_ecnsupport_element_create(void* data, unsigned long length);
 | 
					struct capwap_ecnsupport_element {
 | 
				
			||||||
int capwap_ecnsupport_element_validate(struct capwap_message_element* element);
 | 
						uint8_t flag;
 | 
				
			||||||
void* capwap_ecnsupport_element_parsing(struct capwap_message_element* element);
 | 
					};
 | 
				
			||||||
void capwap_ecnsupport_element_free(void* data);
 | 
					
 | 
				
			||||||
 | 
					extern struct capwap_message_elements_ops capwap_element_ecnsupport_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_ECNSUPPORT_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_ECNSUPPORT);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_ecnsupport_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_ECNSUPPORT_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_ECNSUPPORT_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -14,47 +14,25 @@ Length:  4
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_idletimeout_raw_element {
 | 
					 | 
				
			||||||
	unsigned long timeout;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_idletimeout_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_idletimeout_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_idletimeout_element* element = (struct capwap_idletimeout_element*)data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_idletimeout_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_idletimeout_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_idletimeout_raw_element));
 | 
						func->write_u32(handle, element->timeout);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_IDLETIMEOUT);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_idletimeout_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	((struct capwap_idletimeout_raw_element*)element->data)->timeout = htonl(((struct capwap_idletimeout_element*)data)->timeout);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_idletimeout_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_idletimeout_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_idletimeout_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_idletimeout_element* data;
 | 
						struct capwap_idletimeout_element* data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_IDLETIMEOUT);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_idletimeout_raw_element)) {
 | 
						if (func->read_ready(handle) != 4) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid Idle Timeout element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,14 +42,23 @@ void* capwap_idletimeout_element_parsing(struct capwap_message_element* element)
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->timeout = ntohl(((struct capwap_idletimeout_raw_element*)element->data)->timeout);
 | 
						memset(data, 0, sizeof(struct capwap_idletimeout_element));
 | 
				
			||||||
 | 
						func->read_u32(handle, &data->timeout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_idletimeout_element_free(void* data) {
 | 
					static void capwap_idletimeout_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_idletimeout_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_idletimeout_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_idletimeout_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_idletimeout_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -4,18 +4,9 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_IDLETIMEOUT			23
 | 
					#define CAPWAP_ELEMENT_IDLETIMEOUT			23
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_idletimeout_element {
 | 
					struct capwap_idletimeout_element {
 | 
				
			||||||
	unsigned long timeout;
 | 
						uint32_t timeout;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_idletimeout_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_idletimeout_ops;
 | 
				
			||||||
int capwap_idletimeout_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_idletimeout_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_idletimeout_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_IDLETIMEOUT_ELEMENT(x)		({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_IDLETIMEOUT);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_idletimeout_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_IDLETIMEOUT_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_IDLETIMEOUT_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -12,82 +12,65 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   25 for Image Identifier
 | 
					Type:   25 for Image Identifier
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   >= 5
 | 
					Length:   >= 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_imageidentifier_raw_element {
 | 
					/* */
 | 
				
			||||||
	unsigned long vendor;
 | 
					static void capwap_imageidentifier_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	char name[0];
 | 
						struct capwap_imageidentifier_element* element = (struct capwap_imageidentifier_element*)data;
 | 
				
			||||||
} __attribute__((__packed__));
 | 
					
 | 
				
			||||||
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						func->write_u32(handle, element->vendor);
 | 
				
			||||||
 | 
						func->write_block(handle, element->name, strlen((char*)element->name));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_imageidentifier_element_create(void* data, unsigned long datalength) {
 | 
					static void* capwap_imageidentifier_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	unsigned short namelength;
 | 
						unsigned short length;
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_imageidentifier_element* data;
 | 
				
			||||||
	struct capwap_imageidentifier_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	struct capwap_imageidentifier_element* dataelement = (struct capwap_imageidentifier_element*)data;
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
					
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_imageidentifier_element));
 | 
						length = func->read_ready(handle);
 | 
				
			||||||
	
 | 
						if (length < 5) {
 | 
				
			||||||
	/* Alloc block of memory */
 | 
							capwap_logging_debug("Invalid Image Indentifier element");
 | 
				
			||||||
	namelength = strlen(dataelement->name);
 | 
							return NULL;
 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_imageidentifier_raw_element) + namelength);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						length -= 4;
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_imageidentifier_raw_element) + namelength);
 | 
						if (length > CAPWAP_IMAGEIDENTIFIER_MAXLENGTH) {
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_IMAGEIDENTIFIER);
 | 
							capwap_logging_debug("Invalid AC Name element");
 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_imageidentifier_raw_element) + namelength);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_imageidentifier_raw_element*)element->data;
 | 
					 | 
				
			||||||
	dataraw->vendor = htonl(dataelement->vendor);
 | 
					 | 
				
			||||||
	memcpy(&dataraw->name[0], &dataelement->name[0], namelength);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
int capwap_imageidentifier_element_validate(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_imageidentifier_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	unsigned short namelength;
 | 
					 | 
				
			||||||
	struct capwap_imageidentifier_element* data;
 | 
					 | 
				
			||||||
	struct capwap_imageidentifier_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_IMAGEIDENTIFIER);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	namelength = ntohs(element->length) - sizeof(struct capwap_imageidentifier_raw_element);
 | 
					 | 
				
			||||||
	if (!namelength  || (namelength > CAPWAP_IMAGEIDENTIFIER_MAXLENGTH))  {
 | 
					 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	dataraw = (struct capwap_imageidentifier_raw_element*)element->data;
 | 
					 | 
				
			||||||
	data = (struct capwap_imageidentifier_element*)capwap_alloc(sizeof(struct capwap_imageidentifier_element));
 | 
						data = (struct capwap_imageidentifier_element*)capwap_alloc(sizeof(struct capwap_imageidentifier_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->vendor = ntohl(dataraw->vendor);
 | 
						memset(data, 0, sizeof(struct capwap_imageidentifier_element));
 | 
				
			||||||
	memcpy(&data->name[0], &dataraw->name[0], namelength);
 | 
						func->read_u32(handle, &data->vendor);
 | 
				
			||||||
	data->name[namelength] = 0;
 | 
						func->read_block(handle, data->name, length);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_imageidentifier_element_free(void* data) {
 | 
					static void capwap_imageidentifier_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_imageidentifier_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_imageidentifier_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_imageidentifier_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_imageidentifier_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -6,20 +6,10 @@
 | 
				
			|||||||
#define CAPWAP_IMAGEIDENTIFIER_MAXLENGTH		1024
 | 
					#define CAPWAP_IMAGEIDENTIFIER_MAXLENGTH		1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_imageidentifier_element {
 | 
					struct capwap_imageidentifier_element {
 | 
				
			||||||
	unsigned long vendor;
 | 
						uint32_t vendor;
 | 
				
			||||||
	char name[CAPWAP_IMAGEIDENTIFIER_MAXLENGTH + 1];
 | 
						uint8_t name[CAPWAP_IMAGEIDENTIFIER_MAXLENGTH + 1];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_imageidentifier_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_imageidentifier_ops;
 | 
				
			||||||
int capwap_imageidentifier_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_imageidentifier_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_imageidentifier_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_IMAGEIDENTIFIER_ELEMENT(x)		({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_IMAGEIDENTIFIER);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_imageidentifier_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_IMAGEIDENTIFIER_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_IMAGEIDENTIFIER_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,55 +10,30 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   30 for CAPWAP Local IPv4 Address
 | 
					Type:   30 for CAPWAP Local IPv4 Address
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   4
 | 
					Length:   4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_localipv4_raw_element {
 | 
					 | 
				
			||||||
	unsigned long address;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_localipv4_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_localipv4_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_localipv4_element* element = (struct capwap_localipv4_element*)data;
 | 
				
			||||||
	struct capwap_localipv4_element* dataelement = (struct capwap_localipv4_element*)data;
 | 
					
 | 
				
			||||||
	struct capwap_localipv4_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_localipv4_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_localipv4_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_localipv4_raw_element));
 | 
						func->write_block(handle, (uint8_t*)&element->address, sizeof(struct in_addr));
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_LOCALIPV4);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_localipv4_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_localipv4_raw_element*)element->data;
 | 
					 | 
				
			||||||
	dataraw->address = dataelement->address.s_addr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_localipv4_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_localipv4_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_localipv4_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_localipv4_element* data;
 | 
						struct capwap_localipv4_element* data;
 | 
				
			||||||
	struct capwap_localipv4_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_LOCALIPV4);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) != 4) {
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_localipv4_raw_element)) {
 | 
							capwap_logging_debug("Invalid Local IPv4 Address element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -68,16 +43,23 @@ void* capwap_localipv4_element_parsing(struct capwap_message_element* element) {
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	dataraw = (struct capwap_localipv4_raw_element*)element->data;
 | 
						memset(data, 0, sizeof(struct capwap_localipv4_element));
 | 
				
			||||||
	data->address.s_addr = dataraw->address;
 | 
						func->read_block(handle, (uint8_t*)&data->address, sizeof(struct in_addr));
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_localipv4_element_free(void* data) {
 | 
					static void capwap_localipv4_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_localipv4_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_localipv4_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_localipv4_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_localipv4_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -7,16 +7,6 @@ struct capwap_localipv4_element {
 | 
				
			|||||||
	struct in_addr address;
 | 
						struct in_addr address;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_localipv4_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_localipv4_ops;
 | 
				
			||||||
int capwap_localipv4_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_localipv4_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_localipv4_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_LOCALIPV4_ELEMENT(x)				({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_LOCALIPV4);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_localipv4_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_LOCALIPV4_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_LOCALIPV4_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -20,51 +20,25 @@ Length:   16
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_localipv6_raw_element {
 | 
					 | 
				
			||||||
	unsigned long address[4];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_localipv6_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_localipv6_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_localipv6_element* element = (struct capwap_localipv6_element*)data;
 | 
				
			||||||
	struct capwap_localipv6_element* dataelement = (struct capwap_localipv6_element*)data;
 | 
					
 | 
				
			||||||
	struct capwap_localipv6_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_localipv6_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_localipv6_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_localipv6_raw_element));
 | 
						func->write_block(handle, (uint8_t*)&element->address, sizeof(struct in6_addr));
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_LOCALIPV6);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_localipv6_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_localipv6_raw_element*)element->data;
 | 
					 | 
				
			||||||
	memcpy(dataraw->address, dataelement->address.s6_addr32, sizeof(unsigned long) * 4);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_localipv6_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_localipv6_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_localipv6_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_localipv6_element* data;
 | 
						struct capwap_localipv6_element* data;
 | 
				
			||||||
	struct capwap_localipv6_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_LOCALIPV6);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) != 16) {
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_localipv6_raw_element)) {
 | 
							capwap_logging_debug("Invalid Local IPv6 Address element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -74,16 +48,23 @@ void* capwap_localipv6_element_parsing(struct capwap_message_element* element) {
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	dataraw = (struct capwap_localipv6_raw_element*)element->data;
 | 
						memset(data, 0, sizeof(struct capwap_localipv6_element));
 | 
				
			||||||
	memcpy(data->address.s6_addr32, dataraw->address, sizeof(unsigned long) * 4);
 | 
						func->read_block(handle, (uint8_t*)&data->address, sizeof(struct in6_addr));
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_localipv6_element_free(void* data) {
 | 
					static void capwap_localipv6_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_localipv6_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_localipv6_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_localipv6_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_localipv6_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -7,16 +7,6 @@ struct capwap_localipv6_element {
 | 
				
			|||||||
	struct in6_addr address;
 | 
						struct in6_addr address;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_localipv6_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_localipv6_ops;
 | 
				
			||||||
int capwap_localipv6_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_localipv6_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_localipv6_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_LOCALIPV6_ELEMENT(x)				({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_LOCALIPV6);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_localipv6_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_CONTROLIPV4_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_CONTROLIPV4_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,77 +10,57 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   28 for Location Data
 | 
					Type:   28 for Location Data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   >= 1
 | 
					Length:   >= 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_location_raw_element {
 | 
					 | 
				
			||||||
	char value[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_location_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_location_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	unsigned short namelength;
 | 
						struct capwap_location_element* element = (struct capwap_location_element*)data;
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					
 | 
				
			||||||
	struct capwap_location_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_location_element* dataelement = (struct capwap_location_element*)data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_location_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	namelength = strlen(dataelement->value);
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + namelength);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						func->write_block(handle, element->value, strlen((char*)element->value));
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + namelength);
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_LOCATION);
 | 
					 | 
				
			||||||
	element->length = htons(namelength);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_location_raw_element*)element->data;
 | 
					 | 
				
			||||||
	memcpy(&dataraw->value[0], &dataelement->value[0], namelength);
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_location_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_location_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
						unsigned short length;
 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_location_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	unsigned short namelength;
 | 
					 | 
				
			||||||
	struct capwap_location_element* data;
 | 
						struct capwap_location_element* data;
 | 
				
			||||||
	struct capwap_location_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_LOCATION);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	namelength = ntohs(element->length);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	if (!namelength  || (namelength > CAPWAP_LOCATION_MAXLENGTH))  {
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						length = func->read_ready(handle);
 | 
				
			||||||
 | 
						if ((length < 1) || (length > CAPWAP_ACNAME_MAXLENGTH)) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid AC Name element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	dataraw = (struct capwap_location_raw_element*)element->data;
 | 
					 | 
				
			||||||
	data = (struct capwap_location_element*)capwap_alloc(sizeof(struct capwap_location_element));
 | 
						data = (struct capwap_location_element*)capwap_alloc(sizeof(struct capwap_location_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	memcpy(&data->value[0], &dataraw->value[0], namelength);
 | 
						memset(data, 0, sizeof(struct capwap_location_element));
 | 
				
			||||||
	data->value[namelength] = 0;
 | 
						func->read_block(handle, data->value, length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_location_element_free(void* data) {
 | 
					static void capwap_location_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_location_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_location_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_location_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_location_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -6,19 +6,9 @@
 | 
				
			|||||||
#define CAPWAP_LOCATION_MAXLENGTH		1024
 | 
					#define CAPWAP_LOCATION_MAXLENGTH		1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_location_element {
 | 
					struct capwap_location_element {
 | 
				
			||||||
	char value[CAPWAP_LOCATION_MAXLENGTH + 1];
 | 
						uint8_t value[CAPWAP_LOCATION_MAXLENGTH + 1];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_location_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_location_ops;
 | 
				
			||||||
int capwap_location_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_location_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_location_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_LOCATION_ELEMENT(x)				({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_LOCATION);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_location_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_LOCATION_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_LOCATION_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,51 +10,30 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   29 for Maximum Message Length
 | 
					Type:   29 for Maximum Message Length
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  2
 | 
					Length:  2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_maximumlength_raw_element {
 | 
					 | 
				
			||||||
	unsigned short length;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_maximumlength_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_maximumlength_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_maximumlength_element* element = (struct capwap_maximumlength_element*)data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_maximumlength_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_maximumlength_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_maximumlength_raw_element));
 | 
						func->write_u16(handle, element->length);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_MAXIMUMLENGTH);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_maximumlength_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	((struct capwap_maximumlength_raw_element*)element->data)->length = htons(((struct capwap_maximumlength_element*)data)->length);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_maximumlength_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_maximumlength_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_maximumlength_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_maximumlength_element* data;
 | 
						struct capwap_maximumlength_element* data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_MAXIMUMLENGTH);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_maximumlength_raw_element)) {
 | 
						if (func->read_ready(handle) != 2) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid Maxium Message Length element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,14 +43,23 @@ void* capwap_maximumlength_element_parsing(struct capwap_message_element* elemen
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->length = ntohs(((struct capwap_maximumlength_raw_element*)element->data)->length);
 | 
						memset(data, 0, sizeof(struct capwap_maximumlength_element));
 | 
				
			||||||
 | 
						func->read_u16(handle, &data->length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_maximumlength_element_free(void* data) {
 | 
					static void capwap_maximumlength_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_maximumlength_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_maximumlength_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_maximumlength_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_maximumlength_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -4,18 +4,9 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_MAXIMUMLENGTH			29
 | 
					#define CAPWAP_ELEMENT_MAXIMUMLENGTH			29
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_maximumlength_element {
 | 
					struct capwap_maximumlength_element {
 | 
				
			||||||
	unsigned short length;
 | 
						uint16_t length;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_maximumlength_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_maximumlength_ops;
 | 
				
			||||||
int capwap_maximumlength_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_maximumlength_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_maximumlength_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_MAXIMUMLENGTH_ELEMENT(x)		({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_MAXIMUMLENGTH);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_maximumlength_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_MAXIMUMLENGTH_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_MAXIMUMLENGTH_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,63 +10,66 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-
 | 
					+-+-+-+-+-+-+-+-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   52 for MTU Discovery Padding
 | 
					Type:   52 for MTU Discovery Padding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  variable
 | 
					Length:  variable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_mtudiscovery_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_mtudiscovery_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						uint16_t length;
 | 
				
			||||||
	struct capwap_mtudiscovery_element* dataelement = (struct capwap_mtudiscovery_element*)data;
 | 
						struct capwap_mtudiscovery_element* element = (struct capwap_mtudiscovery_element*)data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_mtudiscovery_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + dataelement->length);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element));
 | 
						length = element->length;
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_MTUDISCOVERY);
 | 
						while (length > 0) {
 | 
				
			||||||
	element->length = htons(dataelement->length);
 | 
							func->write_u8(handle, 0xff);
 | 
				
			||||||
	
 | 
							length--;
 | 
				
			||||||
	if (dataelement->length > 0) {
 | 
					 | 
				
			||||||
		memset(element->data, 0xff, dataelement->length);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_mtudiscovery_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_mtudiscovery_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
						uint16_t length;
 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_mtudiscovery_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_mtudiscovery_element* data;
 | 
						struct capwap_mtudiscovery_element* data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_MTUDISCOVERY);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
 | 
						length = func->read_ready(handle);
 | 
				
			||||||
 | 
						if (length > 0) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid MTU Discovery Padding element");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	data = (struct capwap_mtudiscovery_element*)capwap_alloc(sizeof(struct capwap_mtudiscovery_element));
 | 
						data = (struct capwap_mtudiscovery_element*)capwap_alloc(sizeof(struct capwap_mtudiscovery_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->length = ntohs(element->length);
 | 
						data->length = length;
 | 
				
			||||||
 | 
						while (length > 0) {
 | 
				
			||||||
 | 
							func->read_u8(handle, NULL);
 | 
				
			||||||
 | 
							length--;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_mtudiscovery_element_free(void* data) {
 | 
					static void capwap_mtudiscovery_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_mtudiscovery_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_mtudiscovery_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_mtudiscovery_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_mtudiscovery_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -4,18 +4,9 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_MTUDISCOVERY			52
 | 
					#define CAPWAP_ELEMENT_MTUDISCOVERY			52
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_mtudiscovery_element {
 | 
					struct capwap_mtudiscovery_element {
 | 
				
			||||||
	unsigned short length;
 | 
						uint16_t length;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_mtudiscovery_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_mtudiscovery_ops;
 | 
				
			||||||
int capwap_mtudiscovery_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_mtudiscovery_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_mtudiscovery_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_MTUDISCOVERY_ELEMENT(x)		({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_MTUDISCOVERY);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_mtudiscovery_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_MTUDISCOVERY_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_MTUDISCOVERY_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,57 +10,31 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   31 for Radio Administrative State
 | 
					Type:   31 for Radio Administrative State
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  2
 | 
					Length:  2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_radioadmstate_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char state;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_radioadmstate_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_radioadmstate_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_radioadmstate_element* element = (struct capwap_radioadmstate_element*)data;
 | 
				
			||||||
	struct capwap_radioadmstate_element* dataelement = (struct capwap_radioadmstate_element*)data;
 | 
					
 | 
				
			||||||
	struct capwap_radioadmstate_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_radioadmstate_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_radioadmstate_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_radioadmstate_raw_element));
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_RADIOADMSTATE);
 | 
						func->write_u8(handle, element->state);
 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_radioadmstate_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_radioadmstate_raw_element*)element->data;
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	dataraw->state = dataelement->state;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_radioadmstate_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_radioadmstate_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_radioadmstate_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_radioadmstate_element* data;
 | 
						struct capwap_radioadmstate_element* data;
 | 
				
			||||||
	struct capwap_radioadmstate_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_RADIOADMSTATE);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) != 2) {
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_radioadmstate_raw_element)) {
 | 
							capwap_logging_debug("Invalid Radio Administrative State element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -70,17 +44,24 @@ void* capwap_radioadmstate_element_parsing(struct capwap_message_element* elemen
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	dataraw = (struct capwap_radioadmstate_raw_element*)element->data;
 | 
						memset(data, 0, sizeof(struct capwap_radioadmstate_element));
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
	data->state = dataraw->state;
 | 
						func->read_u8(handle, &data->state);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_radioadmstate_element_free(void* data) {
 | 
					static void capwap_radioadmstate_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_radioadmstate_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_radioadmstate_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_radioadmstate_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_radioadmstate_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -3,23 +3,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ELEMENT_RADIOADMSTATE		31
 | 
					#define CAPWAP_ELEMENT_RADIOADMSTATE		31
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_radioadmstate_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char state;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CAPWAP_RADIO_ADMIN_STATE_ENABLED		1
 | 
					#define CAPWAP_RADIO_ADMIN_STATE_ENABLED		1
 | 
				
			||||||
#define CAPWAP_RADIO_ADMIN_STATE_DISABLED		2
 | 
					#define CAPWAP_RADIO_ADMIN_STATE_DISABLED		2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_radioadmstate_element_create(void* data, unsigned long length);
 | 
					struct capwap_radioadmstate_element {
 | 
				
			||||||
int capwap_radioadmstate_element_validate(struct capwap_message_element* element);
 | 
						uint8_t radioid;
 | 
				
			||||||
void* capwap_radioadmstate_element_parsing(struct capwap_message_element* element);
 | 
						uint8_t state;
 | 
				
			||||||
void capwap_radioadmstate_element_free(void* data);
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern struct capwap_message_elements_ops capwap_element_radioadmstate_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_RADIOADMSTATE_ELEMENT(x)		({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_RADIOADMSTATE);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_radioadmstate_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_RADIOADMSTATE_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_RADIOADMSTATE_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,59 +10,32 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   32 for Radio Operational State
 | 
					Type:   32 for Radio Operational State
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  3
 | 
					Length:  3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_radiooprstate_raw_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char state;
 | 
					 | 
				
			||||||
	unsigned char cause;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_radiooprstate_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_radiooprstate_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_radiooprstate_element* element = (struct capwap_radiooprstate_element*)data;
 | 
				
			||||||
	struct capwap_radiooprstate_element* dataelement = (struct capwap_radiooprstate_element*)data;
 | 
					
 | 
				
			||||||
	struct capwap_radiooprstate_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_radiooprstate_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_radiooprstate_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_radiooprstate_raw_element));
 | 
						func->write_u8(handle, element->radioid);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_RADIOOPRSTATE);
 | 
						func->write_u8(handle, element->state);
 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_radiooprstate_raw_element));
 | 
						func->write_u8(handle, element->cause);
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_radiooprstate_raw_element*)element->data;
 | 
					 | 
				
			||||||
	dataraw->radioid = dataelement->radioid;
 | 
					 | 
				
			||||||
	dataraw->state = dataelement->state;
 | 
					 | 
				
			||||||
	dataraw->cause = dataelement->cause;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_radiooprstate_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_radiooprstate_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_radiooprstate_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_radiooprstate_element* data;
 | 
						struct capwap_radiooprstate_element* data;
 | 
				
			||||||
	struct capwap_radiooprstate_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_RADIOOPRSTATE);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) != 3) {
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_radiooprstate_raw_element)) {
 | 
							capwap_logging_debug("Invalid Radio Operational State element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -72,18 +45,25 @@ void* capwap_radiooprstate_element_parsing(struct capwap_message_element* elemen
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	dataraw = (struct capwap_radiooprstate_raw_element*)element->data;
 | 
						memset(data, 0, sizeof(struct capwap_radiooprstate_element));
 | 
				
			||||||
	data->radioid = dataraw->radioid;
 | 
						func->read_u8(handle, &data->radioid);
 | 
				
			||||||
	data->state = dataraw->state;
 | 
						func->read_u8(handle, &data->state);
 | 
				
			||||||
	data->cause = dataraw->cause;
 | 
						func->read_u8(handle, &data->cause);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_radiooprstate_element_free(void* data) {
 | 
					static void capwap_radiooprstate_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_radiooprstate_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_radiooprstate_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_radiooprstate_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_radiooprstate_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -3,12 +3,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ELEMENT_RADIOOPRSTATE		32
 | 
					#define CAPWAP_ELEMENT_RADIOOPRSTATE		32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_radiooprstate_element {
 | 
					 | 
				
			||||||
	unsigned char radioid;
 | 
					 | 
				
			||||||
	unsigned char state;
 | 
					 | 
				
			||||||
	unsigned char cause;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CAPWAP_RADIO_OPERATIONAL_STATE_ENABLED				1
 | 
					#define CAPWAP_RADIO_OPERATIONAL_STATE_ENABLED				1
 | 
				
			||||||
#define CAPWAP_RADIO_OPERATIONAL_STATE_DISABLED				2
 | 
					#define CAPWAP_RADIO_OPERATIONAL_STATE_DISABLED				2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -17,15 +11,12 @@ struct capwap_radiooprstate_element {
 | 
				
			|||||||
#define CAPWAP_RADIO_OPERATIONAL_CAUSE_SOFTWAREFAILURE		2
 | 
					#define CAPWAP_RADIO_OPERATIONAL_CAUSE_SOFTWAREFAILURE		2
 | 
				
			||||||
#define CAPWAP_RADIO_OPERATIONAL_CAUSE_ADMINSET				3
 | 
					#define CAPWAP_RADIO_OPERATIONAL_CAUSE_ADMINSET				3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_radiooprstate_element_create(void* data, unsigned long length);
 | 
					struct capwap_radiooprstate_element {
 | 
				
			||||||
int capwap_radiooprstate_element_validate(struct capwap_message_element* element);
 | 
						unsigned char radioid;
 | 
				
			||||||
void* capwap_radiooprstate_element_parsing(struct capwap_message_element* element);
 | 
						unsigned char state;
 | 
				
			||||||
void capwap_radiooprstate_element_free(void* data);
 | 
						unsigned char cause;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern struct capwap_message_elements_ops capwap_element_radiooprstate_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_RADIOOPRSTATE_ELEMENT(x)		({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_RADIOOPRSTATE);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_radiooprstate_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_RADIOOPRSTATE_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_RADIOOPRSTATE_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,51 +10,30 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   33 for Result Code
 | 
					Type:   33 for Result Code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  4
 | 
					Length:  4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_resultcode_raw_element {
 | 
					 | 
				
			||||||
	unsigned long code;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_resultcode_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_resultcode_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_resultcode_element* element = (struct capwap_resultcode_element*)data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_resultcode_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_resultcode_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_resultcode_raw_element));
 | 
						func->write_u32(handle, element->code);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_RESULTCODE);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_resultcode_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	((struct capwap_resultcode_raw_element*)element->data)->code = htonl(((struct capwap_resultcode_element*)data)->code);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_resultcode_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_resultcode_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_resultcode_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_resultcode_element* data;
 | 
						struct capwap_resultcode_element* data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_RESULTCODE);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_resultcode_raw_element)) {
 | 
						if (func->read_ready(handle) != 4) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid Result Code element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,14 +43,23 @@ void* capwap_resultcode_element_parsing(struct capwap_message_element* element)
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->code = ntohl(((struct capwap_resultcode_raw_element*)element->data)->code);
 | 
						memset(data, 0, sizeof(struct capwap_resultcode_element));
 | 
				
			||||||
 | 
						func->read_u32(handle, &data->code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_resultcode_element_free(void* data) {
 | 
					static void capwap_resultcode_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_resultcode_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_resultcode_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_resultcode_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_resultcode_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -28,18 +28,9 @@
 | 
				
			|||||||
#define CAPWAP_RESULTCODE_DATA_TRANSFER_ERROR						22
 | 
					#define CAPWAP_RESULTCODE_DATA_TRANSFER_ERROR						22
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
struct capwap_resultcode_element {
 | 
					struct capwap_resultcode_element {
 | 
				
			||||||
	unsigned long code;
 | 
						uint32_t code;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_resultcode_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_resultcode_ops;
 | 
				
			||||||
int capwap_resultcode_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_resultcode_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_resultcode_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_RESULTCODE_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_RESULTCODE);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_resultcode_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_RESULTCODE_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_RESULTCODE_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,84 +10,67 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   34 for Returned Message Element
 | 
					Type:   34 for Returned Message Element
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  >= 6
 | 
					Length:  >= 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_returnedmessage_raw_element {
 | 
					 | 
				
			||||||
	unsigned char reason;
 | 
					 | 
				
			||||||
	unsigned char length;
 | 
					 | 
				
			||||||
	char message[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_returnedmessage_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_returnedmessage_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	unsigned short length;
 | 
						struct capwap_returnedmessage_element* element = (struct capwap_returnedmessage_element*)data;
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					
 | 
				
			||||||
	struct capwap_returnedmessage_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_returnedmessage_element* dataelement = (struct capwap_returnedmessage_element*)data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_returnedmessage_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	length = sizeof(struct capwap_returnedmessage_raw_element) + dataelement->length;
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + length);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						func->write_u8(handle, element->reason);
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element));
 | 
						func->write_u8(handle, element->length);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_RETURNEDMESSAGE);
 | 
						func->write_block(handle, element->message, element->length);
 | 
				
			||||||
	element->length = htons(length);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_returnedmessage_raw_element*)element->data;
 | 
					 | 
				
			||||||
	dataraw->reason = dataelement->reason;
 | 
					 | 
				
			||||||
	dataraw->length = dataelement->length;
 | 
					 | 
				
			||||||
	memcpy(&dataraw->message[0], &dataelement->message[0], dataelement->length);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_returnedmessage_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_returnedmessage_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_returnedmessage_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	unsigned short length;
 | 
						unsigned short length;
 | 
				
			||||||
	struct capwap_returnedmessage_element* data;
 | 
						struct capwap_returnedmessage_element* data;
 | 
				
			||||||
	struct capwap_returnedmessage_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_RETURNEDMESSAGE);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	length = ntohs(element->length) - sizeof(struct capwap_returnedmessage_raw_element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	if (length > CAPWAP_RETURNED_MESSAGE_MAX_LENGTH)  {
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						length = func->read_ready(handle);
 | 
				
			||||||
 | 
						if (length < 6) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid Returned Message element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
 | 
						length -= 2;
 | 
				
			||||||
 | 
						if (length > CAPWAP_RETURNED_MESSAGE_MAX_LENGTH) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid Returned Message element");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	dataraw = (struct capwap_returnedmessage_raw_element*)element->data;
 | 
					 | 
				
			||||||
	data = (struct capwap_returnedmessage_element*)capwap_alloc(sizeof(struct capwap_returnedmessage_element));
 | 
						data = (struct capwap_returnedmessage_element*)capwap_alloc(sizeof(struct capwap_returnedmessage_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->reason = dataraw->reason;
 | 
						memset(data, 0, sizeof(struct capwap_returnedmessage_element));
 | 
				
			||||||
	data->length = dataraw->length;
 | 
						func->read_u8(handle, &data->reason);
 | 
				
			||||||
	memcpy(&data->message[0], &dataraw->message[0], dataraw->length);
 | 
						func->read_u8(handle, &data->length);
 | 
				
			||||||
	
 | 
						func->read_block(handle, data->message, data->length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_returnedmessage_element_free(void* data) {
 | 
					static void capwap_returnedmessage_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_returnedmessage_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_returnedmessage_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_returnedmessage_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_returnedmessage_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -11,20 +11,11 @@
 | 
				
			|||||||
#define CAPWAP_RETURNED_MESSAGE_MAX_LENGTH						255
 | 
					#define CAPWAP_RETURNED_MESSAGE_MAX_LENGTH						255
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
struct capwap_returnedmessage_element {
 | 
					struct capwap_returnedmessage_element {
 | 
				
			||||||
	unsigned char reason;
 | 
						uint8_t reason;
 | 
				
			||||||
	unsigned char length;
 | 
						uint8_t length;
 | 
				
			||||||
	char message[CAPWAP_RETURNED_MESSAGE_MAX_LENGTH];
 | 
						uint8_t message[CAPWAP_RETURNED_MESSAGE_MAX_LENGTH];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_returnedmessage_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_returnedmessage_ops;
 | 
				
			||||||
int capwap_returnedmessage_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_returnedmessage_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_returnedmessage_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_RETURNEDMESSAGE_ELEMENT(x)	({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_RETURNEDMESSAGE);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_returnedmessage_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_RETURNEDMESSAGE_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_RETURNEDMESSAGE_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -21,72 +21,6 @@ Length:   16
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_sessionid_raw_element {
 | 
					 | 
				
			||||||
	unsigned char id[16];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
struct capwap_message_element* capwap_sessionid_element_create(void* data, unsigned long datalength) {
 | 
					 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					 | 
				
			||||||
	struct capwap_sessionid_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_sessionid_element* dataelement = (struct capwap_sessionid_element*)data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
					 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_sessionid_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_sessionid_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create message element */
 | 
					 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_sessionid_element));
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_SESSIONID);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_sessionid_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_sessionid_raw_element*)element->data;
 | 
					 | 
				
			||||||
	memcpy(&dataraw->id[0], &dataelement->id[0], sizeof(unsigned char) * 16);
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
int capwap_sessionid_element_validate(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_sessionid_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_sessionid_element* data;
 | 
					 | 
				
			||||||
	struct capwap_sessionid_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_SESSIONID);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_sessionid_raw_element))  {
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* */
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_sessionid_raw_element*)element->data;
 | 
					 | 
				
			||||||
	data = (struct capwap_sessionid_element*)capwap_alloc(sizeof(struct capwap_sessionid_element));
 | 
					 | 
				
			||||||
	if (!data) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* */
 | 
					 | 
				
			||||||
	memcpy(&data->id[0], &dataraw->id[0], sizeof(unsigned char) * 16);
 | 
					 | 
				
			||||||
	return data;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void capwap_sessionid_element_free(void* data) {
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	capwap_free(data);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_sessionid_generate(struct capwap_sessionid_element* session) {
 | 
					void capwap_sessionid_generate(struct capwap_sessionid_element* session) {
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
@ -113,3 +47,51 @@ void capwap_sessionid_printf(struct capwap_sessionid_element* session, char* str
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	*pos = 0;
 | 
						*pos = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					static void capwap_sessionid_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
 | 
						struct capwap_sessionid_element* element = (struct capwap_sessionid_element*)data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						func->write_block(handle, element->id, 16);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					static void* capwap_sessionid_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
 | 
						struct capwap_sessionid_element* data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (func->read_ready(handle) != 16) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid Session ID element");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* */
 | 
				
			||||||
 | 
						data = (struct capwap_sessionid_element*)capwap_alloc(sizeof(struct capwap_sessionid_element));
 | 
				
			||||||
 | 
						if (!data) {
 | 
				
			||||||
 | 
							capwap_outofmemory();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Retrieve data */
 | 
				
			||||||
 | 
						memset(data, 0, sizeof(struct capwap_sessionid_element));
 | 
				
			||||||
 | 
						func->read_block(handle, data->id, 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					static void capwap_sessionid_element_free(void* data) {
 | 
				
			||||||
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						capwap_free(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_sessionid_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_sessionid_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_sessionid_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_sessionid_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -4,21 +4,13 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_SESSIONID		35
 | 
					#define CAPWAP_ELEMENT_SESSIONID		35
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_sessionid_element {
 | 
					struct capwap_sessionid_element {
 | 
				
			||||||
	unsigned char id[16];
 | 
						uint8_t id[16];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_sessionid_element_create(void* data, unsigned long datalength);
 | 
					/* */
 | 
				
			||||||
int capwap_sessionid_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_sessionid_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_sessionid_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void capwap_sessionid_generate(struct capwap_sessionid_element* session);
 | 
					void capwap_sessionid_generate(struct capwap_sessionid_element* session);
 | 
				
			||||||
void capwap_sessionid_printf(struct capwap_sessionid_element* session, char* string);
 | 
					void capwap_sessionid_printf(struct capwap_sessionid_element* session, char* string);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					extern struct capwap_message_elements_ops capwap_element_sessionid_ops;
 | 
				
			||||||
#define CAPWAP_CREATE_SESSIONID_ELEMENT(x)				({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_SESSIONID);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_sessionid_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_SESSIONID_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_SESSIONID_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,51 +10,30 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   36 for Statistics Timer
 | 
					Type:   36 for Statistics Timer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  2
 | 
					Length:  2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_statisticstimer_raw_element {
 | 
					 | 
				
			||||||
	unsigned short timer;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_statisticstimer_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_statisticstimer_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_statisticstimer_element* element = (struct capwap_statisticstimer_element*)data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_statisticstimer_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_statisticstimer_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_statisticstimer_raw_element));
 | 
						func->write_u16(handle, element->timer);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_STATISTICSTIMER);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_statisticstimer_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	((struct capwap_statisticstimer_raw_element*)element->data)->timer = htons(((struct capwap_statisticstimer_element*)data)->timer);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_statisticstimer_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_statisticstimer_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_statisticstimer_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_statisticstimer_element* data;
 | 
						struct capwap_statisticstimer_element* data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_STATISTICSTIMER);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_statisticstimer_raw_element)) {
 | 
						if (func->read_ready(handle) != 2) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid Statistics Timer element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,14 +43,23 @@ void* capwap_statisticstimer_element_parsing(struct capwap_message_element* elem
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->timer = ntohs(((struct capwap_statisticstimer_raw_element*)element->data)->timer);
 | 
						memset(data, 0, sizeof(struct capwap_statisticstimer_element));
 | 
				
			||||||
 | 
						func->read_u16(handle, &data->timer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_statisticstimer_element_free(void* data) {
 | 
					static void capwap_statisticstimer_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_statisticstimer_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_statisticstimer_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_statisticstimer_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_statisticstimer_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -4,18 +4,9 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_STATISTICSTIMER			36
 | 
					#define CAPWAP_ELEMENT_STATISTICSTIMER			36
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_statisticstimer_element {
 | 
					struct capwap_statisticstimer_element {
 | 
				
			||||||
	unsigned short timer;
 | 
						uint16_t timer;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_statisticstimer_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_statisticstimer_ops;
 | 
				
			||||||
int capwap_statisticstimer_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_statisticstimer_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_statisticstimer_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_STATISTICSTIMER_ELEMENT(x)	({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_STATISTICSTIMER);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_statisticstimer_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_STATISTICSTIMER_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_STATISTICSTIMER_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,57 +10,31 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   12 for CAPWAP Timers
 | 
					Type:   12 for CAPWAP Timers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  2
 | 
					Length:  2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_timers_raw_element {
 | 
					 | 
				
			||||||
	unsigned char discovery;
 | 
					 | 
				
			||||||
	unsigned char echorequest;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_timers_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_timers_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_timers_element* element = (struct capwap_timers_element*)data;
 | 
				
			||||||
	struct capwap_timers_element* dataelement = (struct capwap_timers_element*)data;
 | 
					
 | 
				
			||||||
	struct capwap_timers_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_timers_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_timers_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_timers_raw_element));
 | 
						func->write_u8(handle, element->discovery);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_TIMERS);
 | 
						func->write_u8(handle, element->echorequest);
 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_timers_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_timers_raw_element*)element->data;
 | 
					 | 
				
			||||||
	dataraw->discovery = dataelement->discovery;
 | 
					 | 
				
			||||||
	dataraw->echorequest = dataelement->echorequest;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_timers_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_timers_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_timers_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_timers_element* data;
 | 
						struct capwap_timers_element* data;
 | 
				
			||||||
	struct capwap_timers_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_TIMERS);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) != 2) {
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_timers_raw_element)) {
 | 
							capwap_logging_debug("Invalid Timers element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -70,17 +44,24 @@ void* capwap_timers_element_parsing(struct capwap_message_element* element) {
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	dataraw = (struct capwap_timers_raw_element*)element->data;
 | 
						memset(data, 0, sizeof(struct capwap_timers_element));
 | 
				
			||||||
	data->discovery = dataraw->discovery;
 | 
						func->read_u8(handle, &data->discovery);
 | 
				
			||||||
	data->echorequest = dataraw->echorequest;
 | 
						func->read_u8(handle, &data->echorequest);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_timers_element_free(void* data) {
 | 
					static void capwap_timers_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_timers_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_timers_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_timers_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_timers_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -4,19 +4,10 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_TIMERS				12
 | 
					#define CAPWAP_ELEMENT_TIMERS				12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_timers_element {
 | 
					struct capwap_timers_element {
 | 
				
			||||||
	unsigned char discovery;
 | 
						uint8_t discovery;
 | 
				
			||||||
	unsigned char echorequest;
 | 
						uint8_t echorequest;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_timers_element_create(void* data, unsigned long length);
 | 
					extern struct capwap_message_elements_ops capwap_element_timers_ops;
 | 
				
			||||||
int capwap_timers_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_timers_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_timers_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_TIMERS_ELEMENT(x)				({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_TIMERS);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_timers_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_TIMERS_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_TIMERS_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,51 +10,30 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   51 for CAPWAP Transport Protocol
 | 
					Type:   51 for CAPWAP Transport Protocol
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  1
 | 
					Length:  1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_transport_raw_element {
 | 
					 | 
				
			||||||
	char type;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_transport_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_transport_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_transport_element* element = (struct capwap_transport_element*)data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_transport_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_transport_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_transport_raw_element));
 | 
						func->write_u8(handle, element->type);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_TRANSPORT);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_transport_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	((struct capwap_transport_raw_element*)element->data)->type = ((struct capwap_transport_element*)data)->type;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_transport_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_transport_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_transport_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_transport_element* data;
 | 
						struct capwap_transport_element* data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_TRANSPORT);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_transport_raw_element)) {
 | 
						if (func->read_ready(handle) != 1) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid Transport Protocol element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,14 +43,23 @@ void* capwap_transport_element_parsing(struct capwap_message_element* element) {
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->type = ((struct capwap_transport_raw_element*)element->data)->type;
 | 
						memset(data, 0, sizeof(struct capwap_transport_element));
 | 
				
			||||||
 | 
						func->read_u8(handle, &data->type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_transport_element_free(void* data) {
 | 
					static void capwap_transport_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_transport_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_transport_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_transport_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_transport_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -3,22 +3,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ELEMENT_TRANSPORT			51
 | 
					#define CAPWAP_ELEMENT_TRANSPORT			51
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_transport_element {
 | 
					 | 
				
			||||||
	char type;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CAPWAP_UDPLITE_TRANSPORT		1
 | 
					#define CAPWAP_UDPLITE_TRANSPORT		1
 | 
				
			||||||
#define CAPWAP_UDP_TRANSPORT			2
 | 
					#define CAPWAP_UDP_TRANSPORT			2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_transport_element_create(void* data, unsigned long length);
 | 
					struct capwap_transport_element {
 | 
				
			||||||
int capwap_transport_element_validate(struct capwap_message_element* element);
 | 
						uint8_t type;
 | 
				
			||||||
void* capwap_transport_element_parsing(struct capwap_message_element* element);
 | 
					};
 | 
				
			||||||
void capwap_transport_element_free(void* data);
 | 
					
 | 
				
			||||||
 | 
					extern struct capwap_message_elements_ops capwap_element_transport_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_TRANSPORT_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_TRANSPORT);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_transport_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_TRANSPORT_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_TRANSPORT_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -12,88 +12,67 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   37 for Vendor Specific Payload
 | 
					Type:   37 for Vendor Specific Payload
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   >= 7
 | 
					Length:   >= 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_vendorpayload_raw_element {
 | 
					 | 
				
			||||||
	unsigned long vendorid;
 | 
					 | 
				
			||||||
	unsigned short elementid;
 | 
					 | 
				
			||||||
	char data[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_vendorpayload_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_vendorpayload_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	unsigned short elementlength;
 | 
						struct capwap_vendorpayload_element* element = (struct capwap_vendorpayload_element*)data;
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					
 | 
				
			||||||
	struct capwap_vendorpayload_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_vendorpayload_element* dataelement = (struct capwap_vendorpayload_element*)data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_vendorpayload_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* */
 | 
					 | 
				
			||||||
	if (!dataelement->datalength || (dataelement->datalength > CAPWAP_VENDORPAYLOAD_MAXLENGTH)) {
 | 
					 | 
				
			||||||
		return NULL; 
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	elementlength = sizeof(struct capwap_vendorpayload_raw_element) + dataelement->datalength;
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + elementlength);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						func->write_u32(handle, element->vendorid);
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + elementlength);
 | 
						func->write_u16(handle, element->elementid);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_VENDORPAYLOAD);
 | 
						func->write_block(handle, element->data, element->datalength);
 | 
				
			||||||
	element->length = htons(elementlength);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_vendorpayload_raw_element*)element->data;
 | 
					 | 
				
			||||||
	dataraw->vendorid = htonl(dataelement->vendorid);
 | 
					 | 
				
			||||||
	dataraw->elementid = htons(dataelement->elementid);
 | 
					 | 
				
			||||||
	memcpy(&dataraw->data[0], &dataelement->data[0], dataelement->datalength);
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_vendorpayload_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_vendorpayload_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
						unsigned short length;
 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_vendorpayload_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	unsigned short elementlength;
 | 
					 | 
				
			||||||
	struct capwap_vendorpayload_element* data;
 | 
						struct capwap_vendorpayload_element* data;
 | 
				
			||||||
	struct capwap_vendorpayload_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_VENDORPAYLOAD);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	elementlength = ntohs(element->length);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	if (elementlength > sizeof(struct capwap_vendorpayload_raw_element))  {
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						length = func->read_ready(handle);
 | 
				
			||||||
 | 
						if (length < 7) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid Vendor Specific Payload element");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						length -= 6;
 | 
				
			||||||
 | 
						if (length > CAPWAP_VENDORPAYLOAD_MAXLENGTH) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid Vendor Specific Payload element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	dataraw = (struct capwap_vendorpayload_raw_element*)element->data;
 | 
					 | 
				
			||||||
	data = (struct capwap_vendorpayload_element*)capwap_alloc(sizeof(struct capwap_vendorpayload_element));
 | 
						data = (struct capwap_vendorpayload_element*)capwap_alloc(sizeof(struct capwap_vendorpayload_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->vendorid = ntohl(dataraw->vendorid);
 | 
						memset(data, 0, sizeof(struct capwap_vendorpayload_element));
 | 
				
			||||||
	data->elementid = ntohs(dataraw->elementid);
 | 
						func->read_u32(handle, &data->vendorid);
 | 
				
			||||||
	data->datalength = elementlength - sizeof(struct capwap_vendorpayload_element);
 | 
						func->read_u16(handle, &data->elementid);
 | 
				
			||||||
	memcpy(&data->data[0], &dataraw->data[0], data->datalength);
 | 
						func->read_block(handle, data->data, length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_vendorpayload_element_free(void* data) {
 | 
					static void capwap_vendorpayload_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_vendorpayload_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_vendorpayload_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_vendorpayload_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_vendorpayload_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -6,22 +6,12 @@
 | 
				
			|||||||
#define CAPWAP_VENDORPAYLOAD_MAXLENGTH		2048
 | 
					#define CAPWAP_VENDORPAYLOAD_MAXLENGTH		2048
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_vendorpayload_element {
 | 
					struct capwap_vendorpayload_element {
 | 
				
			||||||
	unsigned long vendorid;
 | 
						uint32_t vendorid;
 | 
				
			||||||
	unsigned short elementid;
 | 
						uint16_t elementid;
 | 
				
			||||||
	unsigned short datalength;
 | 
						uint16_t datalength;
 | 
				
			||||||
	char data[CAPWAP_VENDORPAYLOAD_MAXLENGTH];
 | 
						uint8_t data[CAPWAP_VENDORPAYLOAD_MAXLENGTH];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_vendorpayload_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_vendorpayload_ops;
 | 
				
			||||||
int capwap_vendorpayload_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_vendorpayload_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_vendorpayload_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_VENDORPAYLOAD_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_VENDORPAYLOAD_MAXLENGTH);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_vendorpayload_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_VENDORPAYLOAD_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_VENDORPAYLOAD_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -21,141 +21,93 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   38 for WTP Board Data
 | 
					Type:   38 for WTP Board Data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   >=14
 | 
					Length:   >=14
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpboarddata_raw_element {
 | 
					 | 
				
			||||||
	unsigned long vendor;
 | 
					 | 
				
			||||||
	char data[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct capwap_wtpboarddata_raw_board_subelement {
 | 
					 | 
				
			||||||
	unsigned short type;
 | 
					 | 
				
			||||||
	unsigned short length;
 | 
					 | 
				
			||||||
	char data[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_wtpboarddata_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_wtpboarddata_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	char* pos;
 | 
						int i;
 | 
				
			||||||
	unsigned long i;
 | 
						struct capwap_wtpboarddata_element* element = (struct capwap_wtpboarddata_element*)data;
 | 
				
			||||||
	unsigned short length;
 | 
					
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					 | 
				
			||||||
	struct capwap_wtpboarddata_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_wtpboarddata_element* dataelement = (struct capwap_wtpboarddata_element*)data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_wtpboarddata_element));
 | 
					 | 
				
			||||||
	ASSERT(dataelement->boardsubelement != NULL);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Calc length packet */
 | 
					 | 
				
			||||||
	length = sizeof(struct capwap_wtpboarddata_raw_element);
 | 
					 | 
				
			||||||
	for (i = 0; i < dataelement->boardsubelement->count; i++) {
 | 
					 | 
				
			||||||
		struct capwap_wtpboarddata_board_subelement* board = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(dataelement->boardsubelement, i);
 | 
					 | 
				
			||||||
		length += sizeof(struct capwap_wtpboarddata_raw_board_subelement) + board->length;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + length);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create message element */
 | 
					 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + length);
 | 
					 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_WTPBOARDDATA);
 | 
					 | 
				
			||||||
	element->length = htons(length);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	dataraw = (struct capwap_wtpboarddata_raw_element*)element->data;
 | 
						func->write_u32(handle, element->vendor);
 | 
				
			||||||
	dataraw->vendor = htonl(dataelement->vendor);
 | 
					
 | 
				
			||||||
	pos = dataraw->data;
 | 
						/* */
 | 
				
			||||||
	
 | 
						for (i = 0; i < element->boardsubelement->count; i++) {
 | 
				
			||||||
	/* Board Sub-Element */
 | 
							struct capwap_wtpboarddata_board_subelement* desc = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(element->boardsubelement, i);
 | 
				
			||||||
	for (i = 0; i < dataelement->boardsubelement->count; i++) {
 | 
					
 | 
				
			||||||
		struct capwap_wtpboarddata_raw_board_subelement* boardraw = (struct capwap_wtpboarddata_raw_board_subelement*)pos;
 | 
							func->write_u16(handle, desc->type);
 | 
				
			||||||
		struct capwap_wtpboarddata_board_subelement* board = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(dataelement->boardsubelement, i);
 | 
							func->write_u16(handle, desc->length);
 | 
				
			||||||
		
 | 
							func->write_block(handle, desc->data, desc->length);
 | 
				
			||||||
		boardraw->type = htons(board->type);
 | 
					 | 
				
			||||||
		boardraw->length = htons(board->length);
 | 
					 | 
				
			||||||
		memcpy(boardraw->data, board->data, board->length);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		pos += sizeof(struct capwap_wtpboarddata_raw_board_subelement) + board->length;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_wtpboarddata_element_validate(struct capwap_message_element* element) {
 | 
					static void capwap_wtpboarddata_element_free(void* data) {
 | 
				
			||||||
	/* TODO */
 | 
						struct capwap_wtpboarddata_element* dataelement = (struct capwap_wtpboarddata_element*)data;
 | 
				
			||||||
	return 1;
 | 
					
 | 
				
			||||||
 | 
						ASSERT(dataelement != NULL);
 | 
				
			||||||
 | 
						ASSERT(dataelement->boardsubelement != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						capwap_array_free(dataelement->boardsubelement);
 | 
				
			||||||
 | 
						capwap_free(dataelement);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void* capwap_wtpboarddata_element_parsing(struct capwap_message_element* element) {
 | 
					static void* capwap_wtpboarddata_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	long i;
 | 
					 | 
				
			||||||
	char* pos;
 | 
					 | 
				
			||||||
	long length;
 | 
					 | 
				
			||||||
	struct capwap_wtpboarddata_element* data;
 | 
						struct capwap_wtpboarddata_element* data;
 | 
				
			||||||
	struct capwap_wtpboarddata_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_WTPBOARDDATA);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) < 14) {
 | 
				
			||||||
	length = (long)ntohs(element->length);
 | 
					 | 
				
			||||||
	if (length < 14) {
 | 
					 | 
				
			||||||
		capwap_logging_debug("Invalid WTP Board Data element");
 | 
							capwap_logging_debug("Invalid WTP Board Data element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	dataraw = (struct capwap_wtpboarddata_raw_element*)element->data;
 | 
					 | 
				
			||||||
	data = (struct capwap_wtpboarddata_element*)capwap_alloc(sizeof(struct capwap_wtpboarddata_element));
 | 
						data = (struct capwap_wtpboarddata_element*)capwap_alloc(sizeof(struct capwap_wtpboarddata_element));
 | 
				
			||||||
	data->boardsubelement = capwap_array_create(sizeof(struct capwap_wtpboarddata_board_subelement), 0);
 | 
						if (!data) {
 | 
				
			||||||
	
 | 
							capwap_outofmemory();
 | 
				
			||||||
	/* */
 | 
						}
 | 
				
			||||||
	data->vendor = ntohl(dataraw->vendor);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	pos = dataraw->data;
 | 
					 | 
				
			||||||
	length -= sizeof(struct capwap_wtpboarddata_raw_element);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Board Subelement */
 | 
						memset(data, 0, sizeof(struct capwap_wtpboarddata_element));
 | 
				
			||||||
	i = 0;
 | 
						data->boardsubelement = capwap_array_create(sizeof(struct capwap_wtpboarddata_board_subelement), 0);
 | 
				
			||||||
	while (length > 0) {
 | 
						data->boardsubelement->zeroed = 1;
 | 
				
			||||||
		struct capwap_wtpboarddata_board_subelement* board = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(data->boardsubelement, i);
 | 
					
 | 
				
			||||||
		struct capwap_wtpboarddata_raw_board_subelement* boardraw = (struct capwap_wtpboarddata_raw_board_subelement*)pos;
 | 
						/* Retrieve data */
 | 
				
			||||||
		unsigned short boardlength = ntohs(boardraw->length);
 | 
						func->read_u32(handle, &data->vendor);
 | 
				
			||||||
		unsigned short boardrawlength = sizeof(struct capwap_wtpboarddata_raw_board_subelement) + boardlength;
 | 
					
 | 
				
			||||||
		
 | 
						/* WTP Board Data Subelement */
 | 
				
			||||||
		if ((boardlength > CAPWAP_BOARD_SUBELEMENT_MAXDATA) || (length < boardrawlength)) {
 | 
						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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Check buffer size */
 | 
				
			||||||
 | 
							length = func->read_ready(handle);
 | 
				
			||||||
 | 
							if ((length > CAPWAP_BOARD_SUBELEMENT_MAXDATA) || (length < desc->length)) {
 | 
				
			||||||
			capwap_logging_debug("Invalid WTP Board Data element");
 | 
								capwap_logging_debug("Invalid WTP Board Data element");
 | 
				
			||||||
			capwap_wtpboarddata_element_free(data);
 | 
								capwap_wtpboarddata_element_free(data);
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		/* */
 | 
					 | 
				
			||||||
		board->type = ntohs(boardraw->type);
 | 
					 | 
				
			||||||
		board->length = boardlength;
 | 
					 | 
				
			||||||
		memcpy(board->data, boardraw->data, boardlength);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* */
 | 
							func->read_block(handle, desc->data, desc->length);
 | 
				
			||||||
		i++;
 | 
					 | 
				
			||||||
		pos += boardrawlength;
 | 
					 | 
				
			||||||
		length -= boardrawlength;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_wtpboarddata_element_free(void* data) {
 | 
					struct capwap_message_elements_ops capwap_element_wtpboarddata_ops = {
 | 
				
			||||||
	struct capwap_wtpboarddata_element* dataelement = (struct capwap_wtpboarddata_element*)data;
 | 
						.create_message_element = capwap_wtpboarddata_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_wtpboarddata_element_parsing,
 | 
				
			||||||
	ASSERT(dataelement != NULL);
 | 
						.free_parsed_message_element = capwap_wtpboarddata_element_free
 | 
				
			||||||
	ASSERT(dataelement->boardsubelement != NULL);
 | 
					};
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	capwap_array_free(dataelement->boardsubelement);
 | 
					 | 
				
			||||||
	capwap_free(dataelement);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_WTPBOARDDATA			38
 | 
					#define CAPWAP_ELEMENT_WTPBOARDDATA			38
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpboarddata_element {
 | 
					struct capwap_wtpboarddata_element {
 | 
				
			||||||
	unsigned long vendor;
 | 
						uint32_t vendor;
 | 
				
			||||||
	struct capwap_array* boardsubelement;
 | 
						struct capwap_array* boardsubelement;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -16,20 +16,11 @@ struct capwap_wtpboarddata_element {
 | 
				
			|||||||
#define CAPWAP_BOARD_SUBELEMENT_MAXDATA				1024
 | 
					#define CAPWAP_BOARD_SUBELEMENT_MAXDATA				1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpboarddata_board_subelement {
 | 
					struct capwap_wtpboarddata_board_subelement {
 | 
				
			||||||
	unsigned short type;
 | 
						uint16_t type;
 | 
				
			||||||
	unsigned short length;
 | 
						uint16_t length;
 | 
				
			||||||
	char data[CAPWAP_BOARD_SUBELEMENT_MAXDATA];
 | 
						uint8_t data[CAPWAP_BOARD_SUBELEMENT_MAXDATA];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_wtpboarddata_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_wtpboarddata_ops;
 | 
				
			||||||
int capwap_wtpboarddata_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_wtpboarddata_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_wtpboarddata_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_WTPBOARDDATA_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_WTPBOARDDATA);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_wtpboarddata_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_WTPBOARDDATA_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_WTPBOARDDATA_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -29,128 +29,65 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   39 for WTP Descriptor
 | 
					Type:   39 for WTP Descriptor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   >= 33
 | 
					Length:   >= 33
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpdescriptor_raw_element {
 | 
					 | 
				
			||||||
	unsigned char maxradios;
 | 
					 | 
				
			||||||
	unsigned char radiosinuse;
 | 
					 | 
				
			||||||
	unsigned char encryptcount;
 | 
					 | 
				
			||||||
	char data[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct capwap_wtpdescriptor_raw_encrypt_subelement {
 | 
					 | 
				
			||||||
#ifdef CAPWAP_BIG_ENDIAN
 | 
					 | 
				
			||||||
	unsigned char reserved : 3;
 | 
					 | 
				
			||||||
	unsigned char wbid : 5;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	unsigned char wbid : 5;
 | 
					 | 
				
			||||||
	unsigned char reserved : 3;
 | 
					 | 
				
			||||||
#endif	
 | 
					 | 
				
			||||||
	unsigned short capabilities;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct capwap_wtpdescriptor_raw_desc_subelement {
 | 
					 | 
				
			||||||
	unsigned long vendor;
 | 
					 | 
				
			||||||
	unsigned short type;
 | 
					 | 
				
			||||||
	unsigned short length;
 | 
					 | 
				
			||||||
	char data[0];
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_wtpdescriptor_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_wtpdescriptor_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	char* pos;
 | 
						int i;
 | 
				
			||||||
	unsigned long i;
 | 
						struct capwap_wtpdescriptor_element* element = (struct capwap_wtpdescriptor_element*)data;
 | 
				
			||||||
	unsigned short length;
 | 
					
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
					 | 
				
			||||||
	struct capwap_wtpdescriptor_raw_element* dataraw;
 | 
					 | 
				
			||||||
	struct capwap_wtpdescriptor_element* dataelement = (struct capwap_wtpdescriptor_element*)data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_wtpdescriptor_element));
 | 
					 | 
				
			||||||
	ASSERT(dataelement->encryptsubelement != NULL);
 | 
					 | 
				
			||||||
	ASSERT(dataelement->descsubelement != NULL);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Calc length packet */
 | 
					 | 
				
			||||||
	length = sizeof(struct capwap_wtpdescriptor_raw_element);
 | 
					 | 
				
			||||||
	length += dataelement->encryptsubelement->count * sizeof(struct capwap_wtpdescriptor_raw_encrypt_subelement);
 | 
					 | 
				
			||||||
	for (i = 0; i < dataelement->descsubelement->count; i++) {
 | 
					 | 
				
			||||||
		struct capwap_wtpdescriptor_desc_subelement* desc = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(dataelement->descsubelement, i);
 | 
					 | 
				
			||||||
		length += sizeof(struct capwap_wtpdescriptor_raw_desc_subelement) + desc->length;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + length);
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + length);
 | 
						func->write_u8(handle, element->maxradios);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_WTPDESCRIPTOR);
 | 
						func->write_u8(handle, element->radiosinuse);
 | 
				
			||||||
	element->length = htons(length);
 | 
						func->write_u8(handle, element->encryptsubelement->count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Descriptor */
 | 
						/* */
 | 
				
			||||||
	dataraw = (struct capwap_wtpdescriptor_raw_element*)element->data;
 | 
						for (i = 0; i < element->encryptsubelement->count; i++) {
 | 
				
			||||||
	dataraw->maxradios = dataelement->maxradios;
 | 
							struct capwap_wtpdescriptor_encrypt_subelement* desc = (struct capwap_wtpdescriptor_encrypt_subelement*)capwap_array_get_item_pointer(element->encryptsubelement, i);
 | 
				
			||||||
	dataraw->radiosinuse = dataelement->radiosinuse;
 | 
					 | 
				
			||||||
	dataraw->encryptcount = (unsigned char)dataelement->encryptsubelement->count;
 | 
					 | 
				
			||||||
	pos = dataraw->data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Encryption Sub-Element */
 | 
							func->write_u8(handle, desc->wbid & 0x1f);
 | 
				
			||||||
	for (i = 0; i < dataelement->encryptsubelement->count; i++) {
 | 
							func->write_u16(handle, desc->capabilities);
 | 
				
			||||||
		struct capwap_wtpdescriptor_raw_encrypt_subelement* encryptraw = (struct capwap_wtpdescriptor_raw_encrypt_subelement*)pos;
 | 
					 | 
				
			||||||
		struct capwap_wtpdescriptor_encrypt_subelement* encrypt = (struct capwap_wtpdescriptor_encrypt_subelement*)capwap_array_get_item_pointer(dataelement->encryptsubelement, i);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		encryptraw->wbid = encrypt->wbid;
 | 
					 | 
				
			||||||
		encryptraw->capabilities = htons(encrypt->capabilities);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		pos += sizeof(struct capwap_wtpdescriptor_raw_encrypt_subelement);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Descriptor Sub-Element */
 | 
					 | 
				
			||||||
	for (i = 0; i < dataelement->descsubelement->count; i++) {
 | 
					 | 
				
			||||||
		struct capwap_wtpdescriptor_raw_desc_subelement* descraw = (struct capwap_wtpdescriptor_raw_desc_subelement*)pos;
 | 
					 | 
				
			||||||
		struct capwap_wtpdescriptor_desc_subelement* desc = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(dataelement->descsubelement, i);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		descraw->vendor = htonl(desc->vendor);
 | 
					 | 
				
			||||||
		descraw->type = htons(desc->type);
 | 
					 | 
				
			||||||
		descraw->length = htons(desc->length);
 | 
					 | 
				
			||||||
		memcpy(descraw->data, desc->data, desc->length);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		pos += sizeof(struct capwap_wtpdescriptor_raw_desc_subelement) + desc->length;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
int capwap_wtpdescriptor_element_validate(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_wtpdescriptor_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	unsigned char i;
 | 
					 | 
				
			||||||
	long length;
 | 
					 | 
				
			||||||
	char* pos;
 | 
					 | 
				
			||||||
	struct capwap_wtpdescriptor_element* data;
 | 
					 | 
				
			||||||
	struct capwap_wtpdescriptor_raw_element* dataraw;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(element);
 | 
					 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_WTPDESCRIPTOR);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	length = (long)ntohs(element->length);
 | 
					 | 
				
			||||||
	if (length < 33) {
 | 
					 | 
				
			||||||
		capwap_logging_debug("Invalid WTP Descriptor element");
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	dataraw = (struct capwap_wtpdescriptor_raw_element*)element->data;
 | 
						for (i = 0; i < element->descsubelement->count; i++) {
 | 
				
			||||||
	if ((dataraw->radiosinuse > dataraw->maxradios) || (dataraw->encryptcount == 0)) {
 | 
							struct capwap_wtpdescriptor_desc_subelement* desc = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(element->descsubelement, i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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_wtpdescriptor_element_free(void* data) {
 | 
				
			||||||
 | 
						struct capwap_wtpdescriptor_element* dataelement = (struct capwap_wtpdescriptor_element*)data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(dataelement != NULL);
 | 
				
			||||||
 | 
						ASSERT(dataelement->encryptsubelement != NULL);
 | 
				
			||||||
 | 
						ASSERT(dataelement->descsubelement != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						capwap_array_free(dataelement->encryptsubelement);
 | 
				
			||||||
 | 
						capwap_array_free(dataelement->descsubelement);
 | 
				
			||||||
 | 
						capwap_free(dataelement);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
 | 
						uint8_t i;
 | 
				
			||||||
 | 
						uint8_t encryptlength;
 | 
				
			||||||
 | 
						struct capwap_wtpdescriptor_element* data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (func->read_ready(handle) < 33) {
 | 
				
			||||||
		capwap_logging_debug("Invalid WTP Descriptor element");
 | 
							capwap_logging_debug("Invalid WTP Descriptor element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -161,81 +98,76 @@ void* capwap_wtpdescriptor_element_parsing(struct capwap_message_element* elemen
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(data, 0, sizeof(struct capwap_wtpdescriptor_element));
 | 
				
			||||||
	data->encryptsubelement = capwap_array_create(sizeof(struct capwap_wtpdescriptor_encrypt_subelement), 0);
 | 
						data->encryptsubelement = capwap_array_create(sizeof(struct capwap_wtpdescriptor_encrypt_subelement), 0);
 | 
				
			||||||
 | 
						data->encryptsubelement->zeroed = 1;
 | 
				
			||||||
	data->descsubelement = capwap_array_create(sizeof(struct capwap_wtpdescriptor_desc_subelement), 0);
 | 
						data->descsubelement = capwap_array_create(sizeof(struct capwap_wtpdescriptor_desc_subelement), 0);
 | 
				
			||||||
	
 | 
						data->descsubelement->zeroed = 1;
 | 
				
			||||||
	/* */
 | 
					 | 
				
			||||||
	data->maxradios = dataraw->maxradios;
 | 
					 | 
				
			||||||
	data->radiosinuse = dataraw->radiosinuse;
 | 
					 | 
				
			||||||
	capwap_array_resize(data->encryptsubelement, dataraw->encryptcount);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	pos = dataraw->data;
 | 
					 | 
				
			||||||
	length -= sizeof(struct capwap_wtpdescriptor_raw_element);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Encrypt Subelement */
 | 
					 | 
				
			||||||
	for (i = 0; i < dataraw->encryptcount; i++) {
 | 
					 | 
				
			||||||
		struct capwap_wtpdescriptor_encrypt_subelement* encrypt = (struct capwap_wtpdescriptor_encrypt_subelement*)capwap_array_get_item_pointer(data->encryptsubelement, i);
 | 
					 | 
				
			||||||
		struct capwap_wtpdescriptor_raw_encrypt_subelement* encryptraw = (struct capwap_wtpdescriptor_raw_encrypt_subelement*)pos;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
		if (length < sizeof(struct capwap_wtpdescriptor_raw_element)) {
 | 
					 | 
				
			||||||
			capwap_logging_debug("Invalid WTP Descriptor element");
 | 
					 | 
				
			||||||
			capwap_wtpdescriptor_element_free(data);
 | 
					 | 
				
			||||||
			return NULL;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
		encrypt->wbid = encryptraw->wbid;
 | 
						func->read_u8(handle, &data->maxradios);
 | 
				
			||||||
		encrypt->capabilities = ntohs(encryptraw->capabilities);
 | 
						func->read_u8(handle, &data->radiosinuse);
 | 
				
			||||||
 | 
						func->read_u8(handle, &encryptlength);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* */	
 | 
						/* Check */
 | 
				
			||||||
		pos += sizeof(struct capwap_wtpdescriptor_raw_encrypt_subelement);
 | 
						if (!encryptlength) {
 | 
				
			||||||
		length -= sizeof(struct capwap_wtpdescriptor_raw_element);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	if (length < 0) {
 | 
					 | 
				
			||||||
		capwap_logging_debug("Invalid WTP Descriptor element");
 | 
							capwap_logging_debug("Invalid WTP Descriptor element");
 | 
				
			||||||
		capwap_wtpdescriptor_element_free(data);
 | 
							capwap_wtpdescriptor_element_free(data);
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Description Subelement */
 | 
						/* Encryption Subelement */
 | 
				
			||||||
	i = 0;
 | 
						for (i = 0; i < encryptlength; i++) {
 | 
				
			||||||
	while (length > 0) {
 | 
							struct capwap_wtpdescriptor_encrypt_subelement* desc;
 | 
				
			||||||
		struct capwap_wtpdescriptor_desc_subelement* desc = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(data->descsubelement, i);
 | 
					
 | 
				
			||||||
		struct capwap_wtpdescriptor_raw_desc_subelement* descraw = (struct capwap_wtpdescriptor_raw_desc_subelement*)pos;
 | 
							/* Check */
 | 
				
			||||||
		unsigned short desclength = ntohs(descraw->length);
 | 
							if (func->read_ready(handle) < 3) {
 | 
				
			||||||
		unsigned short descrawlength = sizeof(struct capwap_wtpdescriptor_raw_desc_subelement) + desclength;
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if ((desclength > CAPWAP_WTPDESC_SUBELEMENT_MAXDATA) || (length < descrawlength)) {
 | 
					 | 
				
			||||||
			capwap_logging_debug("Invalid WTP Descriptor element");
 | 
								capwap_logging_debug("Invalid WTP Descriptor element");
 | 
				
			||||||
			capwap_wtpdescriptor_element_free(data);
 | 
								capwap_wtpdescriptor_element_free(data);
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		/* */
 | 
					 | 
				
			||||||
		desc->vendor = ntohl(descraw->vendor);
 | 
					 | 
				
			||||||
		desc->type = ntohs(descraw->type);
 | 
					 | 
				
			||||||
		desc->length = desclength;
 | 
					 | 
				
			||||||
		memcpy(desc->data, descraw->data, desclength);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* */
 | 
							/* */
 | 
				
			||||||
		i++;
 | 
							desc = (struct capwap_wtpdescriptor_encrypt_subelement*)capwap_array_get_item_pointer(data->encryptsubelement, data->encryptsubelement->count);
 | 
				
			||||||
		pos += descrawlength;
 | 
							func->read_u8(handle, &desc->wbid);
 | 
				
			||||||
		length -= descrawlength;
 | 
							func->read_u16(handle, &desc->capabilities);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
 | 
						/* WTP Description Subelement */
 | 
				
			||||||
 | 
						while (func->read_ready(handle) > 0) {
 | 
				
			||||||
 | 
							unsigned short length;
 | 
				
			||||||
 | 
							struct capwap_wtpdescriptor_desc_subelement* desc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Check */
 | 
				
			||||||
 | 
							if (func->read_ready(handle) < 8) {
 | 
				
			||||||
 | 
								capwap_logging_debug("Invalid WTP Descriptor element");
 | 
				
			||||||
 | 
								capwap_wtpdescriptor_element_free(data);
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* */
 | 
				
			||||||
 | 
							desc = (struct capwap_wtpdescriptor_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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Check buffer size */
 | 
				
			||||||
 | 
							length = func->read_ready(handle);
 | 
				
			||||||
 | 
							if ((length > CAPWAP_WTPDESC_SUBELEMENT_MAXDATA) || (length < desc->length)) {
 | 
				
			||||||
 | 
								capwap_logging_debug("Invalid WTP Descriptor element");
 | 
				
			||||||
 | 
								capwap_wtpdescriptor_element_free(data);
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							func->read_block(handle, desc->data, desc->length);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_wtpdescriptor_element_free(void* data) {
 | 
					struct capwap_message_elements_ops capwap_element_wtpdescriptor_ops = {
 | 
				
			||||||
	struct capwap_wtpdescriptor_element* dataelement = (struct capwap_wtpdescriptor_element*)data;
 | 
						.create_message_element = capwap_wtpdescriptor_element_create,
 | 
				
			||||||
	
 | 
						.parsing_message_element = capwap_wtpdescriptor_element_parsing,
 | 
				
			||||||
	ASSERT(dataelement != NULL);
 | 
						.free_parsed_message_element = capwap_wtpdescriptor_element_free
 | 
				
			||||||
	ASSERT(dataelement->encryptsubelement != NULL);
 | 
					};
 | 
				
			||||||
	ASSERT(dataelement->descsubelement != NULL);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	capwap_array_free(dataelement->encryptsubelement);
 | 
					 | 
				
			||||||
	capwap_array_free(dataelement->descsubelement);
 | 
					 | 
				
			||||||
	capwap_free(dataelement);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -4,15 +4,15 @@
 | 
				
			|||||||
#define CAPWAP_ELEMENT_WTPDESCRIPTOR			39
 | 
					#define CAPWAP_ELEMENT_WTPDESCRIPTOR			39
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpdescriptor_element {
 | 
					struct capwap_wtpdescriptor_element {
 | 
				
			||||||
	unsigned char maxradios;
 | 
						uint8_t maxradios;
 | 
				
			||||||
	unsigned char radiosinuse;
 | 
						uint8_t radiosinuse;
 | 
				
			||||||
	struct capwap_array* encryptsubelement;
 | 
						struct capwap_array* encryptsubelement;
 | 
				
			||||||
	struct capwap_array* descsubelement;
 | 
						struct capwap_array* descsubelement;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpdescriptor_encrypt_subelement {
 | 
					struct capwap_wtpdescriptor_encrypt_subelement {
 | 
				
			||||||
	unsigned char wbid;
 | 
						uint8_t wbid;
 | 
				
			||||||
	unsigned short capabilities;
 | 
						uint16_t capabilities;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_WTPDESC_SUBELEMENT_HARDWAREVERSION			0
 | 
					#define CAPWAP_WTPDESC_SUBELEMENT_HARDWAREVERSION			0
 | 
				
			||||||
@ -22,21 +22,12 @@ struct capwap_wtpdescriptor_encrypt_subelement {
 | 
				
			|||||||
#define CAPWAP_WTPDESC_SUBELEMENT_MAXDATA					1024
 | 
					#define CAPWAP_WTPDESC_SUBELEMENT_MAXDATA					1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpdescriptor_desc_subelement {
 | 
					struct capwap_wtpdescriptor_desc_subelement {
 | 
				
			||||||
	unsigned long vendor;
 | 
						uint32_t vendor;
 | 
				
			||||||
	unsigned short type;
 | 
						uint16_t type;
 | 
				
			||||||
	unsigned short length;
 | 
						uint16_t length;
 | 
				
			||||||
	char data[CAPWAP_WTPDESC_SUBELEMENT_MAXDATA];
 | 
						uint8_t data[CAPWAP_WTPDESC_SUBELEMENT_MAXDATA];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_wtpdescriptor_element_create(void* data, unsigned long datalength);
 | 
					extern struct capwap_message_elements_ops capwap_element_wtpdescriptor_ops;
 | 
				
			||||||
int capwap_wtpdescriptor_element_validate(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void* capwap_wtpdescriptor_element_parsing(struct capwap_message_element* element);
 | 
					 | 
				
			||||||
void capwap_wtpdescriptor_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_WTPDESCRIPTOR_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
															struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_WTPDESCRIPTOR);	\
 | 
					 | 
				
			||||||
															f->create(x, sizeof(struct capwap_wtpdescriptor_element));	\
 | 
					 | 
				
			||||||
														})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_WTPDESCRIPTOR_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_WTPDESCRIPTOR_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,51 +10,30 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   40 for WTP Fallback
 | 
					Type:   40 for WTP Fallback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  1
 | 
					Length:  1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpfallback_raw_element {
 | 
					 | 
				
			||||||
	char mode;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_wtpfallback_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_wtpfallback_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_wtpfallback_element* element = (struct capwap_wtpfallback_element*)data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_wtpfallback_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_wtpfallback_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_wtpfallback_raw_element));
 | 
						func->write_u8(handle, element->mode);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_WTPFALLBACK);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_wtpfallback_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	((struct capwap_wtpfallback_raw_element*)element->data)->mode = ((struct capwap_wtpfallback_element*)data)->mode;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_wtpfallback_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_wtpfallback_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_wtpfallback_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_wtpfallback_element* data;
 | 
						struct capwap_wtpfallback_element* data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_WTPFALLBACK);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_wtpfallback_raw_element)) {
 | 
						if (func->read_ready(handle) != 1) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid WTP Fallback element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,14 +43,23 @@ void* capwap_wtpfallback_element_parsing(struct capwap_message_element* element)
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->mode = ((struct capwap_wtpfallback_raw_element*)element->data)->mode;
 | 
						memset(data, 0, sizeof(struct capwap_wtpfallback_element));
 | 
				
			||||||
 | 
						func->read_u8(handle, &data->mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_wtpfallback_element_free(void* data) {
 | 
					static void capwap_wtpfallback_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_wtpfallback_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_wtpfallback_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_wtpfallback_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_wtpfallback_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -3,22 +3,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ELEMENT_WTPFALLBACK			40
 | 
					#define CAPWAP_ELEMENT_WTPFALLBACK			40
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpfallback_element {
 | 
					 | 
				
			||||||
	char mode;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CAPWAP_WTP_FALLBACK_ENABLED			1
 | 
					#define CAPWAP_WTP_FALLBACK_ENABLED			1
 | 
				
			||||||
#define CAPWAP_WTP_FALLBACK_DISABLED		2
 | 
					#define CAPWAP_WTP_FALLBACK_DISABLED		2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_wtpfallback_element_create(void* data, unsigned long length);
 | 
					struct capwap_wtpfallback_element {
 | 
				
			||||||
int capwap_wtpfallback_element_validate(struct capwap_message_element* element);
 | 
						uint8_t mode;
 | 
				
			||||||
void* capwap_wtpfallback_element_parsing(struct capwap_message_element* element);
 | 
					};
 | 
				
			||||||
void capwap_wtpfallback_element_free(void* data);
 | 
					
 | 
				
			||||||
 | 
					extern struct capwap_message_elements_ops capwap_element_wtpfallback_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_WTPFALLBACK_ELEMENT(x)		({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_WTPFALLBACK);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_ecnsupport_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_WTPFALLBACK_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_WTPFALLBACK_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,72 +10,56 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   41 for WTP Frame Tunnel Mode
 | 
					Type:   41 for WTP Frame Tunnel Mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:   1
 | 
					Length:   1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpframetunnelmode_raw_element {
 | 
					 | 
				
			||||||
	unsigned char mode;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_wtpframetunnelmode_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_wtpframetunnelmode_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_wtpframetunnelmode_element* element = (struct capwap_wtpframetunnelmode_element*)data;
 | 
				
			||||||
	struct capwap_wtpframetunnelmode_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	struct capwap_wtpframetunnelmode_element* dataelement = (struct capwap_wtpframetunnelmode_element*)data;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength >= sizeof(struct capwap_wtpframetunnelmode_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_wtpframetunnelmode_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_wtpframetunnelmode_raw_element));
 | 
						func->write_u8(handle, element->mode & CAPWAP_WTP_FRAME_TUNNEL_MODE_MASK);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_WTPFRAMETUNNELMODE);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_wtpframetunnelmode_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	dataraw = (struct capwap_wtpframetunnelmode_raw_element*)element->data;
 | 
					 | 
				
			||||||
	dataraw->mode = dataelement->mode & CAPWAP_WTP_FRAME_TUNNEL_MODE_MASK;
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_wtpframetunnelmode_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_wtpframetunnelmode_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_wtpframetunnelmode_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_wtpframetunnelmode_element* data;
 | 
						struct capwap_wtpframetunnelmode_element* data;
 | 
				
			||||||
	struct capwap_wtpframetunnelmode_raw_element* dataraw;
 | 
					
 | 
				
			||||||
	
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_WTPFRAMETUNNELMODE);
 | 
					
 | 
				
			||||||
	
 | 
						if (func->read_ready(handle) != 1) {
 | 
				
			||||||
	if (ntohs(element->length) != 1) {
 | 
							capwap_logging_debug("Invalid WTP Frame Tunnel Mode element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
	dataraw = (struct capwap_wtpframetunnelmode_raw_element*)element->data;
 | 
					 | 
				
			||||||
	data = (struct capwap_wtpframetunnelmode_element*)capwap_alloc(sizeof(struct capwap_wtpframetunnelmode_element));
 | 
						data = (struct capwap_wtpframetunnelmode_element*)capwap_alloc(sizeof(struct capwap_wtpframetunnelmode_element));
 | 
				
			||||||
	if (!data) {
 | 
						if (!data) {
 | 
				
			||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->mode = dataraw->mode & CAPWAP_WTP_FRAME_TUNNEL_MODE_MASK;
 | 
						memset(data, 0, sizeof(struct capwap_wtpframetunnelmode_element));
 | 
				
			||||||
 | 
						func->read_u8(handle, &data->mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_wtpframetunnelmode_element_free(void* data) {
 | 
					static void capwap_wtpframetunnelmode_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_wtpframetunnelmode_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_wtpframetunnelmode_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_wtpframetunnelmode_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_wtpframetunnelmode_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -3,24 +3,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ELEMENT_WTPFRAMETUNNELMODE		41
 | 
					#define CAPWAP_ELEMENT_WTPFRAMETUNNELMODE		41
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpframetunnelmode_element {
 | 
					 | 
				
			||||||
	unsigned char mode;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CAPWAP_WTP_FRAME_TUNNEL_MODE_MASK		0x0e
 | 
					#define CAPWAP_WTP_FRAME_TUNNEL_MODE_MASK		0x0e
 | 
				
			||||||
#define CAPWAP_WTP_NATIVE_FRAME_TUNNEL			0x08
 | 
					#define CAPWAP_WTP_NATIVE_FRAME_TUNNEL			0x08
 | 
				
			||||||
#define CAPWAP_WTP_8023_FRAME_TUNNEL			0x04
 | 
					#define CAPWAP_WTP_8023_FRAME_TUNNEL			0x04
 | 
				
			||||||
#define CAPWAP_WTP_LOCAL_BRIDGING				0x02
 | 
					#define CAPWAP_WTP_LOCAL_BRIDGING				0x02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_wtpframetunnelmode_element_create(void* data, unsigned long datalength);
 | 
					struct capwap_wtpframetunnelmode_element {
 | 
				
			||||||
int capwap_wtpframetunnelmode_element_validate(struct capwap_message_element* element);
 | 
						uint8_t mode;
 | 
				
			||||||
void* capwap_wtpframetunnelmode_element_parsing(struct capwap_message_element* element);
 | 
					};
 | 
				
			||||||
void capwap_wtpframetunnelmode_element_free(void* data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					extern struct capwap_message_elements_ops capwap_element_wtpframetunnelmode_ops;
 | 
				
			||||||
#define CAPWAP_CREATE_WTPFRAMETUNNELMODE_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
																struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_WTPFRAMETUNNELMODE);	\
 | 
					 | 
				
			||||||
																f->create(x, sizeof(struct capwap_wtpframetunnelmode_element));	\
 | 
					 | 
				
			||||||
															})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_WTPFRAMETUNNELMODE_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_WTPFRAMETUNNELMODE_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -10,51 +10,30 @@
 | 
				
			|||||||
+-+-+-+-+-+-+-+-+
 | 
					+-+-+-+-+-+-+-+-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type:   44 for WTP MAC Type
 | 
					Type:   44 for WTP MAC Type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Length:  1
 | 
					Length:  1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
********************************************************************/
 | 
					********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpmactype_raw_element {
 | 
					 | 
				
			||||||
	char type;
 | 
					 | 
				
			||||||
} __attribute__((__packed__));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
struct capwap_message_element* capwap_wtpmactype_element_create(void* data, unsigned long datalength) {
 | 
					static void capwap_wtpmactype_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
 | 
				
			||||||
	struct capwap_message_element* element;
 | 
						struct capwap_wtpmactype_element* element = (struct capwap_wtpmactype_element*)data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	ASSERT(datalength == sizeof(struct capwap_wtpmactype_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* Alloc block of memory */
 | 
					 | 
				
			||||||
	element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_wtpmactype_raw_element));
 | 
					 | 
				
			||||||
	if (!element) {
 | 
					 | 
				
			||||||
		capwap_outofmemory();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create message element */
 | 
						/* */
 | 
				
			||||||
	memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_wtpmactype_raw_element));
 | 
						func->write_u8(handle, element->type);
 | 
				
			||||||
	element->type = htons(CAPWAP_ELEMENT_WTPMACTYPE);
 | 
					 | 
				
			||||||
	element->length = htons(sizeof(struct capwap_wtpmactype_raw_element));
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	((struct capwap_wtpmactype_raw_element*)element->data)->type = ((struct capwap_wtpmactype_element*)data)->type;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return element;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
int capwap_wtpmactype_element_validate(struct capwap_message_element* element) {
 | 
					static void* capwap_wtpmactype_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
 | 
				
			||||||
	/* TODO */
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* */
 | 
					 | 
				
			||||||
void* capwap_wtpmactype_element_parsing(struct capwap_message_element* element) {
 | 
					 | 
				
			||||||
	struct capwap_wtpmactype_element* data;
 | 
						struct capwap_wtpmactype_element* data;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ASSERT(element);
 | 
						ASSERT(handle != NULL);
 | 
				
			||||||
	ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_WTPMACTYPE);
 | 
						ASSERT(func != NULL);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if (ntohs(element->length) != sizeof(struct capwap_wtpmactype_raw_element)) {
 | 
						if (func->read_ready(handle) != 1) {
 | 
				
			||||||
 | 
							capwap_logging_debug("Invalid ECN Support element");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,14 +43,23 @@ void* capwap_wtpmactype_element_parsing(struct capwap_message_element* element)
 | 
				
			|||||||
		capwap_outofmemory();
 | 
							capwap_outofmemory();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* */
 | 
						/* Retrieve data */
 | 
				
			||||||
	data->type = ((struct capwap_wtpmactype_raw_element*)element->data)->type;
 | 
						memset(data, 0, sizeof(struct capwap_wtpmactype_element));
 | 
				
			||||||
 | 
						func->read_u8(handle, &data->type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* */
 | 
					/* */
 | 
				
			||||||
void capwap_wtpmactype_element_free(void* data) {
 | 
					static void capwap_wtpmactype_element_free(void* data) {
 | 
				
			||||||
	ASSERT(data != NULL);
 | 
						ASSERT(data != NULL);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	capwap_free(data);
 | 
						capwap_free(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					struct capwap_message_elements_ops capwap_element_wtpmactype_ops = {
 | 
				
			||||||
 | 
						.create_message_element = capwap_wtpmactype_element_create,
 | 
				
			||||||
 | 
						.parsing_message_element = capwap_wtpmactype_element_parsing,
 | 
				
			||||||
 | 
						.free_parsed_message_element = capwap_wtpmactype_element_free
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -3,22 +3,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CAPWAP_ELEMENT_WTPMACTYPE			44
 | 
					#define CAPWAP_ELEMENT_WTPMACTYPE			44
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_wtpmactype_element {
 | 
					 | 
				
			||||||
	char type;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CAPWAP_LOCALMAC				0
 | 
					#define CAPWAP_LOCALMAC				0
 | 
				
			||||||
#define CAPWAP_SPLITMAC				1
 | 
					#define CAPWAP_SPLITMAC				1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct capwap_message_element* capwap_wtpmactype_element_create(void* data, unsigned long length);
 | 
					struct capwap_wtpmactype_element {
 | 
				
			||||||
int capwap_wtpmactype_element_validate(struct capwap_message_element* element);
 | 
						uint8_t type;
 | 
				
			||||||
void* capwap_wtpmactype_element_parsing(struct capwap_message_element* element);
 | 
					};
 | 
				
			||||||
void capwap_wtpmactype_element_free(void* data);
 | 
					
 | 
				
			||||||
 | 
					extern struct capwap_message_elements_ops capwap_element_wtpmactype_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper */
 | 
					 | 
				
			||||||
#define CAPWAP_CREATE_WTPMACTYPE_ELEMENT(x)			({	\
 | 
					 | 
				
			||||||
														struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_WTPMACTYPE);	\
 | 
					 | 
				
			||||||
														f->create(x, sizeof(struct capwap_wtpmactype_element));	\
 | 
					 | 
				
			||||||
													})
 | 
					 | 
				
			||||||
														
 | 
					 | 
				
			||||||
#endif /* __CAPWAP_ELEMENT_WTPMACTYPE_HEADER__ */
 | 
					#endif /* __CAPWAP_ELEMENT_WTPMACTYPE_HEADER__ */
 | 
				
			||||||
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user