Example #1
0
void ac_dfa_retransmition_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param) {
	struct ac_session_t* session = (struct ac_session_t*)context;

	if (!session->requestfragmentpacket->count) {
		capwap_logging_warning("Invalid retransmition request packet");
		ac_session_teardown(session);
	} else {
		session->retransmitcount++;
		if (session->retransmitcount >= AC_MAX_RETRANSMIT) {
			capwap_logging_info("Retransmition request packet timeout");

			/* Timeout reset state */
			ac_free_reference_last_request(session);
			ac_session_teardown(session);
		} else {
			/* Retransmit Request */
			capwap_logging_debug("Retransmition request packet");
			if (!capwap_crypt_sendto_fragmentpacket(&session->dtls, session->requestfragmentpacket)) {
				capwap_logging_error("Error to send request packet");
			}

			/* Update timeout */
			capwap_timeout_set(session->timeout, session->idtimercontrol, AC_RETRANSMIT_INTERVAL, ac_dfa_retransmition_timeout, session, NULL);
		}
	}
}
Example #2
0
static void ac_dfa_execute(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
	ASSERT(session != NULL);
	ASSERT(packet != NULL);

	/* Execute state */
	switch (session->state) {
		case CAPWAP_DTLS_CONNECT_STATE: {
			ac_session_teardown(session);
			break;
		}

		case CAPWAP_JOIN_STATE: {
			ac_dfa_state_join(session, packet);
			break;
		}
		
		case CAPWAP_POSTJOIN_STATE: {
			ac_dfa_state_postjoin(session, packet);
			break;
		}

		case CAPWAP_IMAGE_DATA_STATE: {
			ac_dfa_state_imagedata(session, packet);
			break;
		}

		case CAPWAP_CONFIGURE_STATE: {
			ac_dfa_state_configure(session, packet);
			break;
		}

		case CAPWAP_RESET_STATE: {
			ac_dfa_state_reset(session, packet);
			break;
		}

		case CAPWAP_DATA_CHECK_STATE: {
			ac_dfa_state_datacheck(session, packet);
			break;
		}

		case CAPWAP_RUN_STATE: {
			ac_dfa_state_run(session, packet);
			break;
		}

		default: {
			capwap_logging_debug("Unknown AC action event: %lu", session->state);
			ac_session_teardown(session);
			break;
		}
	}
}
Example #3
0
static int ac_session_action_addwlan(struct ac_session_t* session, struct ac_notify_addwlan_t* notify) {
	struct capwap_header_data capwapheader;
	struct capwap_packet_txmng* txmngpacket;
	struct capwap_80211_addwlan_element addwlan;

	ASSERT(session->requestfragmentpacket->count == 0);

	/* Check if WLAN id is valid and not used */
	if (!IS_VALID_RADIOID(notify->radioid) || !IS_VALID_WLANID(notify->wlanid)) {
		return AC_NO_ERROR;
	} else if (ac_wlans_get_bssid_with_wlanid(session, notify->radioid, notify->wlanid)) {
		return AC_NO_ERROR;
	}

	/* */
	memset(&addwlan, 0, sizeof(struct capwap_80211_addwlan_element));
	addwlan.radioid = notify->radioid;
	addwlan.wlanid = notify->wlanid;
	addwlan.capability = notify->capability;
	addwlan.qos = notify->qos;
	addwlan.authmode = notify->authmode;
	addwlan.macmode = notify->macmode;
	addwlan.tunnelmode = notify->tunnelmode;
	addwlan.suppressssid = notify->suppressssid;
	addwlan.ssid = (uint8_t*)notify->ssid;

	/* Build packet */
	capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, session->binding);
	txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_IEEE80211_WLAN_CONFIGURATION_REQUEST, session->localseqnumber, session->mtu);

	/* Add message element */
	capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ADD_WLAN, &addwlan);

	/* CAPWAP_ELEMENT_80211_IE */

	/* CAPWAP_ELEMENT_VENDORPAYLOAD */				/* TODO */

	/* WLAN Configuration Request complete, get fragment packets */
	capwap_packet_txmng_get_fragment_packets(txmngpacket, session->requestfragmentpacket, session->fragmentid);
	if (session->requestfragmentpacket->count > 1) {
		session->fragmentid++;
	}

	/* Free packets manager */
	capwap_packet_txmng_free(txmngpacket);

	/* Send WLAN Configuration Request to WTP */
	if (capwap_crypt_sendto_fragmentpacket(&session->dtls, session->requestfragmentpacket)) {
		session->retransmitcount = 0;
		capwap_timeout_set(session->timeout, session->idtimercontrol, AC_RETRANSMIT_INTERVAL, ac_dfa_retransmition_timeout, session, NULL);
	} else {
		capwap_logging_debug("Warning: error to send WLAN Configuration Request packet");
		ac_free_reference_last_request(session);
		ac_session_teardown(session);
	}

	return AC_NO_ERROR;
}
Example #4
0
void ac_dfa_state_postjoin(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
	ASSERT(session != NULL);
	ASSERT(packet != NULL);

	if (packet->rxmngpacket->ctrlmsg.type == CAPWAP_CONFIGURATION_STATUS_REQUEST) {
		ac_dfa_change_state(session, CAPWAP_CONFIGURE_STATE);
		ac_dfa_state_configure(session, packet);
	} else if (packet->rxmngpacket->ctrlmsg.type == CAPWAP_IMAGE_DATA_REQUEST) {
		ac_dfa_change_state(session, CAPWAP_IMAGE_DATA_STATE);
		ac_dfa_state_imagedata(session, packet);
	} else {
		ac_session_teardown(session);
	}
}
Example #5
0
static int ac_session_action_station_configuration_ieee8011_delete_station(struct ac_session_t* session, struct ac_notify_station_configuration_ieee8011_delete_station* notify) {
	struct capwap_header_data capwapheader;
	struct capwap_packet_txmng* txmngpacket;
	struct capwap_deletestation_element deletestation;

	ASSERT(session->requestfragmentpacket->count == 0);

	/* Check if RADIO id is valid */
	if (!IS_VALID_RADIOID(notify->radioid)) {
		return AC_NO_ERROR;
	}

	/* */
	memset(&deletestation, 0, sizeof(struct capwap_deletestation_element));
	deletestation.radioid = notify->radioid;
	deletestation.length = MACADDRESS_EUI48_LENGTH;
	deletestation.address = notify->address;

	/* Build packet */
	capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, session->binding);
	txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_STATION_CONFIGURATION_REQUEST, session->localseqnumber, session->mtu);

	/* Add message element */
	capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_DELETESTATION, &deletestation);
	/* CAPWAP_ELEMENT_VENDORPAYLOAD */				/* TODO */

	/* Station Configuration Request complete, get fragment packets */
	capwap_packet_txmng_get_fragment_packets(txmngpacket, session->requestfragmentpacket, session->fragmentid);
	if (session->requestfragmentpacket->count > 1) {
		session->fragmentid++;
	}

	/* Free packets manager */
	capwap_packet_txmng_free(txmngpacket);

	/* Send Station Configuration Request to WTP */
	if (capwap_crypt_sendto_fragmentpacket(&session->dtls, session->requestfragmentpacket)) {
		session->retransmitcount = 0;
		capwap_timeout_set(session->timeout, session->idtimercontrol, AC_RETRANSMIT_INTERVAL, ac_dfa_retransmition_timeout, session, NULL);
	} else {
		capwap_logging_debug("Warning: error to send Station Configuration Request packet");
		ac_free_reference_last_request(session);
		ac_session_teardown(session);
	}

	return AC_NO_ERROR;
}
Example #6
0
static int ac_session_action_resetwtp(struct ac_session_t* session, struct ac_notify_reset_t* reset) {
	struct capwap_header_data capwapheader;
	struct capwap_packet_txmng* txmngpacket;
	struct capwap_imageidentifier_element imageidentifier;

	ASSERT(session->requestfragmentpacket->count == 0);

	/* */
	imageidentifier.vendor = reset->vendor;
	imageidentifier.name = reset->name;

	/* Build packet */
	capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, session->binding);
	txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_RESET_REQUEST, session->localseqnumber, session->mtu);

	/* Add message element */
	capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_IMAGEIDENTIFIER, &imageidentifier);
	/* CAPWAP_ELEMENT_VENDORPAYLOAD */				/* TODO */

	/* Reset request complete, get fragment packets */
	capwap_packet_txmng_get_fragment_packets(txmngpacket, session->requestfragmentpacket, session->fragmentid);
	if (session->requestfragmentpacket->count > 1) {
		session->fragmentid++;
	}

	/* Free packets manager */
	capwap_packet_txmng_free(txmngpacket);

	/* Send Reset Request to WTP */
	if (capwap_crypt_sendto_fragmentpacket(&session->dtls, session->requestfragmentpacket)) {
		session->retransmitcount = 0;
		ac_dfa_change_state(session, CAPWAP_RESET_STATE);
		capwap_timeout_set(session->timeout, session->idtimercontrol, AC_RETRANSMIT_INTERVAL, ac_dfa_retransmition_timeout, session, NULL);
	} else {
		capwap_logging_debug("Warning: error to send Reset Request packet");
		ac_free_reference_last_request(session);
		ac_session_teardown(session);
	}

	return AC_NO_ERROR;
}
Example #7
0
static void ac_session_run(struct ac_session_t* session) {
	int res;
	int check;
	int length;
	struct capwap_list_item* search;
	char buffer[CAPWAP_MAX_PACKET_SIZE];

	ASSERT(session != NULL);

	/* Configure DFA */
	if (g_ac.enabledtls) {
		if (!ac_dtls_setup(session)) {
			ac_session_teardown(session);			/* Teardown connection */
		}
	} else {
		/* Wait Join request */
		ac_dfa_change_state(session, CAPWAP_JOIN_STATE);
		capwap_timeout_set(session->timeout, session->idtimercontrol, AC_JOIN_INTERVAL, ac_dfa_teardown_timeout, session, NULL);
	}

	while (session->state != CAPWAP_DTLS_TEARDOWN_STATE) {
		/* Get packet */
		length = ac_network_read(session, buffer, sizeof(buffer));
		if (length < 0) {
			if ((length == CAPWAP_ERROR_SHUTDOWN) || (length == CAPWAP_ERROR_CLOSE)) {
				ac_session_teardown(session);
			}
		} else if (length > 0) {
			/* Check generic capwap packet */
			check = capwap_sanity_check(CAPWAP_UNDEF_STATE, buffer, length, 0);
			if (check == CAPWAP_PLAIN_PACKET) {
				struct capwap_parsed_packet packet;

				/* Defragment management */
				if (!session->rxmngpacket) {
					session->rxmngpacket = capwap_packet_rxmng_create_message();
				}

				/* If request, defragmentation packet */
				check = capwap_packet_rxmng_add_recv_packet(session->rxmngpacket, buffer, length);
				if (check == CAPWAP_RECEIVE_COMPLETE_PACKET) {
					/* Receive all fragment */
					if (capwap_is_request_type(session->rxmngpacket->ctrlmsg.type) && (session->remotetype == session->rxmngpacket->ctrlmsg.type) && (session->remoteseqnumber == session->rxmngpacket->ctrlmsg.seq)) {
						/* Retransmit response */
						if (!capwap_crypt_sendto_fragmentpacket(&session->dtls, session->responsefragmentpacket)) {
							capwap_logging_error("Error to resend response packet");
						} else {
							capwap_logging_debug("Retrasmitted control packet");
						}
					} else {
						/* Check message type */
						res = capwap_check_message_type(session->rxmngpacket);
						if (res == VALID_MESSAGE_TYPE) {
							res = capwap_parsing_packet(session->rxmngpacket, &packet);
							if (res == PARSING_COMPLETE) {
								int hasrequest = capwap_is_request_type(session->rxmngpacket->ctrlmsg.type);

								/* Validate packet */
								if (!capwap_validate_parsed_packet(&packet, NULL)) {
									/* Search into notify event */
									search = session->notifyevent->first;
									while (search != NULL) {
										struct ac_session_notify_event_t* notify = (struct ac_session_notify_event_t*)search->item;

										if (hasrequest && (notify->action == NOTIFY_ACTION_RECEIVE_REQUEST_CONTROLMESSAGE)) {
											char buffer[4];
											struct ac_soap_response* response;

											/* */
											response = ac_soap_updatebackendevent(session, notify->idevent, capwap_itoa(SOAP_EVENT_STATUS_COMPLETE, buffer));
											if (response) {
												ac_soapclient_free_response(response);
											}

											/* Remove notify event */
											capwap_itemlist_free(capwap_itemlist_remove(session->notifyevent, search));
											break;
										} else if (!hasrequest && (notify->action == NOTIFY_ACTION_RECEIVE_RESPONSE_CONTROLMESSAGE)) {
											char buffer[4];
											struct ac_soap_response* response;
											struct capwap_resultcode_element* resultcode;

											/* Check the success of the Request */
											resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(&packet, CAPWAP_ELEMENT_RESULTCODE);
											response = ac_soap_updatebackendevent(session, notify->idevent, capwap_itoa(((!resultcode || CAPWAP_RESULTCODE_OK(resultcode->code)) ? SOAP_EVENT_STATUS_COMPLETE : SOAP_EVENT_STATUS_GENERIC_ERROR), buffer));
											if (response) {
												ac_soapclient_free_response(response);
											}

											/* Remove notify event */
											capwap_itemlist_free(capwap_itemlist_remove(session->notifyevent, search));
											break;
										}

										search = search->next;
									}

									/* */
									ac_dfa_execute(session, &packet);
								} else {
									capwap_logging_debug("Failed validation parsed control packet");
									if (capwap_is_request_type(session->rxmngpacket->ctrlmsg.type)) {
										capwap_logging_warning("Missing Mandatory Message Element, send Response Packet with error");
										ac_send_invalid_request(session, CAPWAP_RESULTCODE_FAILURE_MISSING_MANDATORY_MSG_ELEMENT);
									}
								}
							} else {
								capwap_logging_debug("Failed parsing packet");
								if ((res == UNRECOGNIZED_MESSAGE_ELEMENT) && capwap_is_request_type(session->rxmngpacket->ctrlmsg.type)) {
									capwap_logging_warning("Unrecognized Message Element, send Response Packet with error");
									ac_send_invalid_request(session, CAPWAP_RESULTCODE_FAILURE_UNRECOGNIZED_MESSAGE_ELEMENT);
									/* TODO: add the unrecognized message element */
								}
							}
						} else {
							capwap_logging_debug("Invalid message type");
							if (res == INVALID_REQUEST_MESSAGE_TYPE) {
								capwap_logging_warning("Unexpected Unrecognized Request, send Response Packet with error");
								ac_send_invalid_request(session, CAPWAP_RESULTCODE_MSG_UNEXPECTED_UNRECOGNIZED_REQUEST);
							}
						}
					}

					/* Free memory */
					capwap_free_parsed_packet(&packet);
					if (session->rxmngpacket) {
						capwap_packet_rxmng_free(session->rxmngpacket);
						session->rxmngpacket = NULL;
					}
				} else if (check != CAPWAP_REQUEST_MORE_FRAGMENT) {
					/* Discard fragments */
					if (session->rxmngpacket) {
						capwap_packet_rxmng_free(session->rxmngpacket);
						session->rxmngpacket = NULL;
					}
				}
			}
		}
	}

	/* Wait teardown timeout before kill session */
	capwap_timeout_wait(AC_DTLS_SESSION_DELETE_INTERVAL);
	ac_dfa_state_teardown(session);

	/* Release reference session */
	ac_session_destroy(session);
}
Example #8
0
static int ac_session_action_authorizestation_response(struct ac_session_t* session, struct ac_soap_response* response, struct ac_notify_station_configuration_ieee8011_add_station* notify) {
	int result = -1;
	int ifindex = -1;
	uint16_t vlan = 0;
	struct ac_if_datachannel* datachannel;
	struct ac_wlan* wlan;
	struct json_object* jsonroot;
	struct json_object* jsonsection;
	struct json_object* jsonelement;
	struct capwap_header_data capwapheader;
	struct capwap_packet_txmng* txmngpacket;
	struct capwap_addstation_element addstation;
	struct capwap_80211_station_element station;

	/* Receive SOAP response with JSON result
		{
			DataChannelInterface: {
				Index: [int],
				VLAN: [int/string]
			},
		}
	*/

	/* */
	jsonroot = ac_soapclient_parse_json_response(response);
	if (!jsonroot) {
		return -1;
	}

	/* */
	jsonsection = compat_json_object_object_get(jsonroot, "DataChannelInterface");
	if (jsonsection && (json_object_get_type(jsonsection) == json_type_object)) {
		jsonelement = compat_json_object_object_get(jsonsection, "Index");
		if (jsonelement && (json_object_get_type(jsonelement) == json_type_int)) {
			unsigned long index = (unsigned long)json_object_get_int(jsonelement);

			/* Retrieve interface index */
			capwap_rwlock_rdlock(&g_ac.ifdatachannellock);

			datachannel = (struct ac_if_datachannel*)capwap_hash_search(g_ac.ifdatachannel, &index);
			if (datachannel) {
				ifindex = datachannel->ifindex;
			}

			capwap_rwlock_unlock(&g_ac.ifdatachannellock);

			/* Prepare request */
			if (ifindex >= 0) {
				wlan = ac_wlans_get_bssid_with_wlanid(session, notify->radioid, notify->wlanid);
				if (wlan) {
					memset(&addstation, 0, sizeof(struct capwap_addstation_element));
					addstation.radioid = notify->radioid;
					addstation.length = MACADDRESS_EUI48_LENGTH;
					addstation.address = notify->address;
					if (wlan->tunnelmode == CAPWAP_ADD_WLAN_TUNNELMODE_LOCAL) {
						jsonelement = compat_json_object_object_get(jsonsection, "VLAN");
						if (jsonelement && (json_object_get_type(jsonelement) == json_type_string)) {
							const char* wtpvlan = json_object_get_string(jsonelement);
							if (wtpvlan && (strlen(wtpvlan) < CAPWAP_ADDSTATION_VLAN_MAX_LENGTH)) {
								addstation.vlan = (uint8_t*)wtpvlan;		/* Free with jsonroot */
							}
						}
					}

					/* */
					memset(&station, 0, sizeof(struct capwap_80211_station_element));
					station.radioid = notify->radioid;
					station.associationid = notify->associationid;
					memcpy(station.address, notify->address, MACADDRESS_EUI48_LENGTH);
					station.capabilities = notify->capabilities;
					station.wlanid = notify->wlanid;
					station.supportedratescount = notify->supportedratescount;
					memcpy(station.supportedrates, notify->supportedrates, station.supportedratescount);

					/* Build packet */
					capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, session->binding);
					txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_STATION_CONFIGURATION_REQUEST, session->localseqnumber, session->mtu);

					/* Add message element */
					capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ADDSTATION, &addstation);
					capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_STATION, &station);

					/* CAPWAP_ELEMENT_VENDORPAYLOAD */				/* TODO */

					/* Station Configuration Request complete, get fragment packets */
					capwap_packet_txmng_get_fragment_packets(txmngpacket, session->requestfragmentpacket, session->fragmentid);
					if (session->requestfragmentpacket->count > 1) {
						session->fragmentid++;
					}

					/* Free packets manager */
					capwap_packet_txmng_free(txmngpacket);

					/* Send Station Configuration Request to WTP */
					if (capwap_crypt_sendto_fragmentpacket(&session->dtls, session->requestfragmentpacket)) {
						/* Retrive VLAN */
						if (wlan->tunnelmode != CAPWAP_ADD_WLAN_TUNNELMODE_LOCAL) {
							jsonelement = compat_json_object_object_get(jsonroot, "DataChannelInterface.VLAN");
							if (jsonelement && (json_object_get_type(jsonelement) == json_type_int)) {
								int acvlan = json_object_get_int(jsonelement);
								if ((acvlan > 0) && (acvlan < VLAN_MAX)) {
									vlan = (uint16_t)acvlan;
								}
							}
						}

						/* Authorize station also into kernel module */
						if (!ac_kmod_authorize_station(&session->sessionid, addstation.address, ifindex, notify->radioid, notify->wlanid, vlan)) {
							result = 0;
							session->retransmitcount = 0;
							capwap_timeout_set(session->timeout, session->idtimercontrol, AC_RETRANSMIT_INTERVAL, ac_dfa_retransmition_timeout, session, NULL);
						} else {
							capwap_logging_warning("Unable to authorize station into kernel module data channel");
							ac_free_reference_last_request(session);
							ac_session_teardown(session);
						}
					} else {
						capwap_logging_debug("Warning: error to send Station Configuration Request packet");
						ac_free_reference_last_request(session);
						ac_session_teardown(session);
					}
				}
			}
		}
	}

	/* */
	json_object_put(jsonroot);
	return result;
}
Example #9
0
void ac_dfa_teardown_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param) {
	capwap_logging_info("Session timeout, teardown");
	ac_session_teardown((struct ac_session_t*)context);
}
Example #10
0
void ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
	unsigned short binding;
	struct ac_soap_response* response;
	struct capwap_header_data capwapheader;
	struct capwap_packet_txmng* txmngpacket;
	struct capwap_sessionid_element* sessionid;
	struct capwap_wtpboarddata_element* wtpboarddata;
	struct capwap_resultcode_element resultcode = { .code = CAPWAP_RESULTCODE_FAILURE };

	ASSERT(session != NULL);
	ASSERT(packet != NULL);

	/* Check binding */
	binding = GET_WBID_HEADER(packet->rxmngpacket->header);
	if (ac_valid_binding(binding)) {
		if (packet->rxmngpacket->ctrlmsg.type == CAPWAP_JOIN_REQUEST) {
			/* Get sessionid and verify unique id */
			sessionid = (struct capwap_sessionid_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_SESSIONID);
			if (!ac_has_sessionid(sessionid)) {
				char* wtpid;

				/* Checking macaddress for detect if WTP already connected */
				wtpboarddata = (struct capwap_wtpboarddata_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPBOARDDATA);

				/* Get printable WTPID */
				wtpid = ac_get_printable_wtpid(wtpboarddata);
				if (wtpid && !ac_has_wtpid(wtpid)) {
					/* Request authorization of Backend for complete join */
					response = ac_soap_authorizewtpsession(session, wtpid);
					if (response) {
						resultcode.code = ac_dfa_state_join_check_authorizejoin(session, response);
						ac_soapclient_free_response(response);
					} else {
						resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_UNKNOWN_SOURCE;
					}
				} else {
					capwap_logging_info("WTP Id %s already used in another session", wtpid);
					resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_UNKNOWN_SOURCE;
				}

				/* */
				if (CAPWAP_RESULTCODE_OK(resultcode.code)) {
					session->wtpid = wtpid;
					memcpy(&session->sessionid, sessionid, sizeof(struct capwap_sessionid_element));
					session->binding = binding;
				} else if (wtpid) {
					capwap_free(wtpid);
				}
			} else {
				char sessionname[33];

				capwap_sessionid_printf(sessionid, sessionname);
				capwap_logging_info("Session Id %s already used in another session", sessionname);

				resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_ID_ALREADY_IN_USE;
			}
		} else {
			resultcode.code = CAPWAP_RESULTCODE_MSG_UNEXPECTED_INVALID_CURRENT_STATE;
		}
	} else {
		resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_BINDING_NOT_SUPPORTED;
	}

	/* Create response */
	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);

	/* */
	if (CAPWAP_RESULTCODE_OK(resultcode.code)) {
		response = ac_dfa_state_join_parsing_request(session, packet);
		if (response) {
			resultcode.code = ac_dfa_state_join_create_response(session, packet, response, txmngpacket);
			ac_soapclient_free_response(response);
		}
	}

	/* Add always result code message element */
	capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RESULTCODE, &resultcode);

	/* Join 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->remotetype = packet->rxmngpacket->ctrlmsg.type;
	session->remoteseqnumber = packet->rxmngpacket->ctrlmsg.seq;

	/* Send Join response to WTP */
	if (capwap_crypt_sendto_fragmentpacket(&session->dtls, session->responsefragmentpacket)) {
		if (CAPWAP_RESULTCODE_OK(resultcode.code)) {
			ac_dfa_change_state(session, CAPWAP_POSTJOIN_STATE);
			capwap_timeout_set(session->timeout, session->idtimercontrol, AC_JOIN_INTERVAL, ac_dfa_teardown_timeout, session, NULL);
		} else {
			ac_session_teardown(session);
		}
	} else {
		/* Error to send packets */
		capwap_logging_debug("Warning: error to send join response packet");
		ac_session_teardown(session);
	}
}
Example #11
0
void ac_dfa_state_imagedata(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
	/* TODO */
	ac_session_teardown(session);
}