static void* capwap_radioadmstate_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { struct capwap_radioadmstate_element* data; ASSERT(handle != NULL); ASSERT(func != NULL); if (func->read_ready(handle) != 2) { log_printf(LOG_DEBUG, "Invalid Radio Administrative State element: underbuffer"); return NULL; } /* Retrieve data */ data = (struct capwap_radioadmstate_element*)capwap_alloc(sizeof(struct capwap_radioadmstate_element)); func->read_u8(handle, &data->radioid); func->read_u8(handle, &data->state); if (!IS_VALID_RADIOID(data->radioid)) { capwap_radioadmstate_element_free((void*)data); log_printf(LOG_DEBUG, "Invalid Radio Administrative State element: invalid radioid"); return NULL; } else if ((data->state != CAPWAP_RADIO_ADMIN_STATE_ENABLED) && (data->state != CAPWAP_RADIO_ADMIN_STATE_DISABLED)) { capwap_radioadmstate_element_free((void*)data); log_printf(LOG_DEBUG, "Invalid Radio Administrative State element: invalid state"); return NULL; } return data; }
int ac_kmod_addwlan(struct capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t wlanid, const uint8_t* bssid, uint8_t macmode, uint8_t tunnelmode) { int result; struct nl_msg* msg; ASSERT(sessionid != NULL); ASSERT(IS_VALID_RADIOID(radioid)); ASSERT(IS_VALID_WLANID(wlanid)); ASSERT(bssid != NULL); /* */ msg = nlmsg_alloc(); if (!msg) { return -1; } /* */ genlmsg_put(msg, 0, 0, g_ac.kmodhandle.nlsmartcapwap_id, 0, 0, NLSMARTCAPWAP_CMD_ADD_WLAN, 0); nla_put(msg, NLSMARTCAPWAP_ATTR_SESSION_ID, sizeof(struct capwap_sessionid_element), sessionid); nla_put_u8(msg, NLSMARTCAPWAP_ATTR_RADIOID, radioid); nla_put_u8(msg, NLSMARTCAPWAP_ATTR_WLANID, wlanid); nla_put(msg, NLSMARTCAPWAP_ATTR_MACADDRESS, MACADDRESS_EUI48_LENGTH, bssid); nla_put_u8(msg, NLSMARTCAPWAP_ATTR_MACMODE, macmode); nla_put_u8(msg, NLSMARTCAPWAP_ATTR_TUNNELMODE, tunnelmode); /* */ result = ac_kmod_send_and_recv_msg(msg, NULL, NULL); if (result) { log_printf(LOG_ERR, "Unable to add wlan: %d", result); } /* */ nlmsg_free(msg); return result; }
static void capwap_80211_addwlan_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { int length; struct capwap_80211_addwlan_element* element = (struct capwap_80211_addwlan_element*)data; ASSERT(data != NULL); ASSERT(IS_VALID_RADIOID(element->radioid)); ASSERT(IS_VALID_WLANID(element->wlanid)); func->write_u8(handle, element->radioid); func->write_u8(handle, element->wlanid); func->write_u16(handle, element->capability); func->write_u8(handle, element->keyindex); func->write_u8(handle, element->keystatus); func->write_u16(handle, element->keylength); if ((element->keylength > 0) && element->key) { func->write_block(handle, element->key, element->keylength); } func->write_block(handle, element->grouptsc, CAPWAP_ADD_WLAN_GROUPTSC_LENGTH); func->write_u8(handle, element->qos); func->write_u8(handle, element->authmode); func->write_u8(handle, element->macmode); func->write_u8(handle, element->tunnelmode); func->write_u8(handle, element->suppressssid); length = strlen((char*)element->ssid); ASSERT((length > 0) && (length <= CAPWAP_ADD_WLAN_SSID_LENGTH)); func->write_block(handle, element->ssid, length); }
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; }
static void capwap_decrypterrorreportperiod_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { struct capwap_decrypterrorreportperiod_element* element = (struct capwap_decrypterrorreportperiod_element*)data; ASSERT(data != NULL); ASSERT(IS_VALID_RADIOID(element->radioid)); /* */ func->write_u8(handle, element->radioid); func->write_u16(handle, element->interval); }
static void capwap_radioadmstate_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { struct capwap_radioadmstate_element* element = (struct capwap_radioadmstate_element*)data; ASSERT(data != NULL); ASSERT(IS_VALID_RADIOID(element->radioid)); ASSERT((element->state == CAPWAP_RADIO_ADMIN_STATE_ENABLED) || (element->state == CAPWAP_RADIO_ADMIN_STATE_DISABLED)); /* */ func->write_u8(handle, element->radioid); func->write_u8(handle, element->state); }
static void* capwap_80211_antenna_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { int i; uint8_t count; unsigned short length; struct capwap_80211_antenna_element* data; ASSERT(handle != NULL); ASSERT(func != NULL); length = func->read_ready(handle); if (length < 5) { capwap_logging_debug("Invalid IEEE 802.11 Antenna element"); return NULL; } length -= 4; if (length > CAPWAP_ANTENNASELECTIONS_MAXLENGTH) { capwap_logging_debug("Invalid IEEE 802.11 Antenna element"); return NULL; } /* */ data = (struct capwap_80211_antenna_element*)capwap_alloc(sizeof(struct capwap_80211_antenna_element)); memset(data, 0, sizeof(struct capwap_80211_antenna_element)); data->selections = capwap_array_create(sizeof(uint8_t), 0, 1); /* Retrieve data */ func->read_u8(handle, &data->radioid); if (!IS_VALID_RADIOID(data->radioid)) { capwap_80211_antenna_element_free((void*)data); capwap_logging_debug("Invalid IEEE 802.11 Antenna element element: invalid radio"); return NULL; } func->read_u8(handle, &data->diversity); func->read_u8(handle, &data->combiner); func->read_u8(handle, &count); /* Check */ if (count != length) { capwap_logging_debug("Invalid IEEE 802.11 Antenna element"); capwap_free(data); return NULL; } for (i = 0; i < count; i++) { func->read_u8(handle, (uint8_t*)capwap_array_get_item_pointer(data->selections, i)); } return data; }
static void* capwap_addstation_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { unsigned short length; struct capwap_addstation_element* data; ASSERT(handle != NULL); ASSERT(func != NULL); length = func->read_ready(handle); if (length < 8) { capwap_logging_debug("Invalid Add Station element: underbuffer"); return NULL; } length -= 2; /* */ data = (struct capwap_addstation_element*)capwap_alloc(sizeof(struct capwap_addstation_element)); memset(data, 0, sizeof(struct capwap_addstation_element)); /* Retrieve data */ func->read_u8(handle, &data->radioid); func->read_u8(handle, &data->length); if (!IS_VALID_RADIOID(data->radioid)) { capwap_addstation_element_free((void*)data); capwap_logging_debug("Invalid Add Station element: invalid radio"); return NULL; } else if (!IS_VALID_MACADDRESS_LENGTH(data->length) || (length < data->length)) { capwap_addstation_element_free((void*)data); capwap_logging_debug("Invalid Add Station element: invalid length"); return NULL; } data->address = (uint8_t*)capwap_alloc(data->length); func->read_block(handle, data->address, data->length); length -= data->length; if (length > 0) { if (length <= CAPWAP_ADDSTATION_VLAN_MAX_LENGTH) { data->vlan = (uint8_t*)capwap_alloc(length + 1); func->read_block(handle, data->vlan, length); data->vlan[length] = 0; } else { capwap_addstation_element_free((void*)data); capwap_logging_debug("Invalid Add Station element: invalid vlan"); return NULL; } } return data; }
static void capwap_radiooprstate_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { struct capwap_radiooprstate_element* element = (struct capwap_radiooprstate_element*)data; ASSERT(data != NULL); ASSERT(IS_VALID_RADIOID(element->radioid)); ASSERT((element->state == CAPWAP_RADIO_OPERATIONAL_STATE_ENABLED) || (element->state == CAPWAP_RADIO_OPERATIONAL_STATE_DISABLED)); ASSERT((element->cause == CAPWAP_RADIO_OPERATIONAL_CAUSE_NORMAL) || (element->cause == CAPWAP_RADIO_OPERATIONAL_CAUSE_RADIOFAILURE) || (element->cause == CAPWAP_RADIO_OPERATIONAL_CAUSE_SOFTWAREFAILURE) || (element->cause == CAPWAP_RADIO_OPERATIONAL_CAUSE_ADMINSET)); /* */ func->write_u8(handle, element->radioid); func->write_u8(handle, element->state); func->write_u8(handle, element->cause); }
static void capwap_80211_antenna_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { int i; struct capwap_80211_antenna_element* element = (struct capwap_80211_antenna_element*)data; ASSERT(data != NULL); ASSERT(IS_VALID_RADIOID(element->radioid)); ASSERT(element->selections != NULL); func->write_u8(handle, element->radioid); func->write_u8(handle, element->diversity); func->write_u8(handle, element->combiner); func->write_u8(handle, element->selections->count); for (i = 0; i < element->selections->count; i++) { func->write_u8(handle, *(uint8_t*)capwap_array_get_item_pointer(element->selections, i)); } }
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; }
struct wtp_radio* wtp_radio_get_phy(uint8_t radioid) { int i; /* Check */ if (!IS_VALID_RADIOID(radioid)) { return NULL; } /* Retrieve radio */ for (i = 0; i < g_wtp.radios->count; i++) { struct wtp_radio* radio = (struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i); if (radioid == radio->radioid) { return radio; } } return NULL; }
static void capwap_addstation_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { struct capwap_addstation_element* element = (struct capwap_addstation_element*)data; ASSERT(data != NULL); ASSERT(IS_VALID_RADIOID(element->radioid)); ASSERT(IS_VALID_MACADDRESS_LENGTH(element->length)); func->write_u8(handle, element->radioid); func->write_u8(handle, element->length); func->write_block(handle, element->address, element->length); if (element->vlan && *element->vlan) { unsigned short length = strlen((char*)element->vlan); ASSERT(length <= CAPWAP_ADDSTATION_VLAN_MAX_LENGTH); func->write_block(handle, element->vlan, length); } }
int ac_kmod_authorize_station(struct capwap_sessionid_element* sessionid, const uint8_t* macaddress, int ifindex, uint8_t radioid, uint8_t wlanid, uint16_t vlan) { int result; struct nl_msg* msg; ASSERT(sessionid != NULL); ASSERT(macaddress != NULL); ASSERT(ifindex >= 0); ASSERT(IS_VALID_RADIOID(radioid)); ASSERT(vlan < VLAN_MAX); /* */ msg = nlmsg_alloc(); if (!msg) { return -1; } /* */ genlmsg_put(msg, 0, 0, g_ac.kmodhandle.nlsmartcapwap_id, 0, 0, NLSMARTCAPWAP_CMD_AUTH_STATION, 0); nla_put(msg, NLSMARTCAPWAP_ATTR_SESSION_ID, sizeof(struct capwap_sessionid_element), sessionid); nla_put(msg, NLSMARTCAPWAP_ATTR_MACADDRESS, MACADDRESS_EUI48_LENGTH, macaddress); nla_put_u32(msg, NLSMARTCAPWAP_ATTR_IFPHY_INDEX, (unsigned long)ifindex); nla_put_u8(msg, NLSMARTCAPWAP_ATTR_RADIOID, radioid); nla_put_u8(msg, NLSMARTCAPWAP_ATTR_WLANID, wlanid); if (vlan > 0) { nla_put_u16(msg, NLSMARTCAPWAP_ATTR_VLAN, ifindex); } /* */ result = ac_kmod_send_and_recv_msg(msg, NULL, NULL); if (result) { log_printf(LOG_ERR, "Unable to authorize station: %d", result); } /* */ nlmsg_free(msg); return result; }
static int ac_session_action_station_configuration_ieee8011_add_station(struct ac_session_t* session, struct ac_notify_station_configuration_ieee8011_add_station* notify) { struct ac_soap_response* response; ASSERT(session->requestfragmentpacket->count == 0); /* Check if RADIO id and WLAN id is valid */ if (!IS_VALID_RADIOID(notify->radioid) || !IS_VALID_WLANID(notify->wlanid)) { return AC_NO_ERROR; } /* Need authorization of Director */ response = ac_session_action_authorizestation_request(session, notify->radioid, notify->wlanid, notify->address); if (response) { if (ac_session_action_authorizestation_response(session, response, notify)) { capwap_logging_info("Station is not authorized"); /* TODO kickoff station */ } ac_soapclient_free_response(response); } return AC_NO_ERROR; }
static void* capwap_radiooprstate_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { struct capwap_radiooprstate_element* data; ASSERT(handle != NULL); ASSERT(func != NULL); if (func->read_ready(handle) != 3) { log_printf(LOG_DEBUG, "Invalid Radio Operational State element: underbuffer"); return NULL; } /* Retrieve data */ data = (struct capwap_radiooprstate_element*)capwap_alloc(sizeof(struct capwap_radiooprstate_element)); func->read_u8(handle, &data->radioid); func->read_u8(handle, &data->state); func->read_u8(handle, &data->cause); if (!IS_VALID_RADIOID(data->radioid)) { capwap_radiooprstate_element_free((void*)data); log_printf(LOG_DEBUG, "Invalid Radio Operational State element: invalid radioid"); return NULL; } else if ((data->state != CAPWAP_RADIO_OPERATIONAL_STATE_ENABLED) && (data->state != CAPWAP_RADIO_OPERATIONAL_STATE_DISABLED)) { capwap_radiooprstate_element_free((void*)data); log_printf(LOG_DEBUG, "Invalid Radio Operational State element: invalid state"); return NULL; } else if ((data->cause != CAPWAP_RADIO_OPERATIONAL_CAUSE_NORMAL) && (data->cause != CAPWAP_RADIO_OPERATIONAL_CAUSE_RADIOFAILURE) && (data->cause != CAPWAP_RADIO_OPERATIONAL_CAUSE_SOFTWAREFAILURE) && (data->cause != CAPWAP_RADIO_OPERATIONAL_CAUSE_ADMINSET)) { capwap_radiooprstate_element_free((void*)data); log_printf(LOG_DEBUG, "Invalid Radio Operational State element: invalid cause"); return NULL; } return data; }
static void* capwap_decrypterrorreportperiod_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { struct capwap_decrypterrorreportperiod_element* data; ASSERT(handle != NULL); ASSERT(func != NULL); if (func->read_ready(handle) != 3) { capwap_logging_debug("Invalid Decryption Error Report Period element: underbuffer"); return NULL; } /* Retrieve data */ data = (struct capwap_decrypterrorreportperiod_element*)capwap_alloc(sizeof(struct capwap_decrypterrorreportperiod_element)); func->read_u8(handle, &data->radioid); func->read_u16(handle, &data->interval); if (!IS_VALID_RADIOID(data->radioid)) { capwap_decrypterrorreportperiod_element_free((void*)data); capwap_logging_debug("Invalid Decryption Error Report Period element: invalid radioid"); return NULL; } return data; }
static void* capwap_80211_addwlan_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { unsigned short length; struct capwap_80211_addwlan_element* data; ASSERT(handle != NULL); ASSERT(func != NULL); length = func->read_ready(handle); if (length < 20) { capwap_logging_debug("Invalid IEEE 802.11 Add WLAN element: underbuffer"); return NULL; } /* */ data = (struct capwap_80211_addwlan_element*)capwap_alloc(sizeof(struct capwap_80211_addwlan_element)); memset(data, 0, sizeof(struct capwap_80211_addwlan_element)); /* Retrieve data */ func->read_u8(handle, &data->radioid); func->read_u8(handle, &data->wlanid); if (!IS_VALID_RADIOID(data->radioid)) { capwap_80211_addwlan_element_free((void*)data); capwap_logging_debug("Invalid IEEE 802.11 Add WLAN element: invalid radioid"); return NULL; } else if (!IS_VALID_WLANID(data->wlanid)) { capwap_80211_addwlan_element_free((void*)data); capwap_logging_debug("Invalid IEEE 802.11 Add WLAN element: invalid wlanid"); return NULL; } func->read_u16(handle, &data->capability); func->read_u8(handle, &data->keyindex); func->read_u8(handle, &data->keystatus); func->read_u16(handle, &data->keylength); if (data->keylength > 0) { data->key = (uint8_t*)capwap_alloc(data->keylength); func->read_block(handle, data->key, data->keylength); } func->read_block(handle, data->grouptsc, CAPWAP_ADD_WLAN_GROUPTSC_LENGTH); func->read_u8(handle, &data->qos); func->read_u8(handle, &data->authmode); func->read_u8(handle, &data->macmode); func->read_u8(handle, &data->tunnelmode); func->read_u8(handle, &data->suppressssid); length = func->read_ready(handle); if (!length || (length > CAPWAP_ADD_WLAN_SSID_LENGTH)) { capwap_80211_addwlan_element_free((void*)data); capwap_logging_debug("Invalid IEEE 802.11 Add WLAN element: invalid ssid"); return NULL; } data->ssid = (uint8_t*)capwap_alloc(length + 1); func->read_block(handle, data->ssid, length); data->ssid[length] = 0; return data; }