remove dos style newlines

This commit is contained in:
Andreas Schultz 2016-02-05 17:38:49 +01:00
parent 6e3ce9ed74
commit 8c20d78941
104 changed files with 21740 additions and 21740 deletions

View File

@ -1,90 +1,90 @@
# AC configuration file
version = "1.0";
application: {
standalone = true;
name = "ac 1";
binding = [
"802.11"
];
descriptor: {
maxstations = 20;
maxwtp = 10;
security: {
presharedkey = false;
x509 = false;
};
rmacfiled: {
supported = false;
};
dtlspolicy: {
cleardatachannel = true;
dtlsdatachannel = true;
};
info = (
{ idvendor = 12345; type = "hardware"; value = "1.0"; },
{ idvendor = 33457; type = "software"; value = "2.0"; }
);
};
ecn = "limited";
timer: {
discovery = 20;
echorequest = 30;
decrypterrorreport = 120;
idletimeout = 320;
};
wtpfallback = true;
dtls: {
enable = true;
type = "x509";
presharedkey: {
hint = "esempio";
identity = "prova";
pskkey = "123456";
};
x509: {
calist = "/etc/capwap/ca.crt";
certificate = "/etc/capwap/ac.crt";
privatekey = "/etc/capwap/ac.key";
};
};
network: {
#binding = "eth1";
#listen = "";
transport = "udp";
mtu = 1400;
};
};
backend: {
id = "1";
version = "1.0";
server: (
{ url = "http://127.0.0.1/csoap.php"; }
#{ url = "https://127.0.0.1/csoap.php"; x509: { calist = "/etc/capwap/casoap.crt"; certificate = "/etc/capwap/clientsoap.crt"; privatekey = "/etc/capwap/clientsoap.key"; }; }
);
};
logging: {
enable = true;
level = "debug";
output = (
{ mode = "stdout"; }
);
};
# AC configuration file
version = "1.0";
application: {
standalone = true;
name = "ac 1";
binding = [
"802.11"
];
descriptor: {
maxstations = 20;
maxwtp = 10;
security: {
presharedkey = false;
x509 = false;
};
rmacfiled: {
supported = false;
};
dtlspolicy: {
cleardatachannel = true;
dtlsdatachannel = true;
};
info = (
{ idvendor = 12345; type = "hardware"; value = "1.0"; },
{ idvendor = 33457; type = "software"; value = "2.0"; }
);
};
ecn = "limited";
timer: {
discovery = 20;
echorequest = 30;
decrypterrorreport = 120;
idletimeout = 320;
};
wtpfallback = true;
dtls: {
enable = true;
type = "x509";
presharedkey: {
hint = "esempio";
identity = "prova";
pskkey = "123456";
};
x509: {
calist = "/etc/capwap/ca.crt";
certificate = "/etc/capwap/ac.crt";
privatekey = "/etc/capwap/ac.key";
};
};
network: {
#binding = "eth1";
#listen = "";
transport = "udp";
mtu = 1400;
};
};
backend: {
id = "1";
version = "1.0";
server: (
{ url = "http://127.0.0.1/csoap.php"; }
#{ url = "https://127.0.0.1/csoap.php"; x509: { calist = "/etc/capwap/casoap.crt"; certificate = "/etc/capwap/clientsoap.crt"; privatekey = "/etc/capwap/clientsoap.key"; }; }
);
};
logging: {
enable = true;
level = "debug";
output = (
{ mode = "stdout"; }
);
};

View File

@ -1,147 +1,147 @@
# WTP configuration file
version = "1.0";
application: {
standalone = true;
name = "wtp 1";
location = "Ufficio";
binding = "802.11";
tunnelmode: {
nativeframe = false;
ethframe = false;
localbridging = true;
};
mactype = "localmac";
boardinfo: {
idvendor = 123456;
element = (
{ name = "model"; value = "1.0"; },
{ name = "serial"; value = "2.0"; },
{ name = "id"; value = "3.0"; },
{ name = "revision"; value = "4.0"; },
{ name = "macaddress"; type = "interface"; value = "eth1"; }
);
};
descriptor: {
encryption = [
"802.11_AES",
"802.11_TKIP"
];
info = (
{ idvendor = 23456; type = "hardware"; value = "abcde"; },
{ idvendor = 33457; type = "software"; value = "fghil"; },
{ idvendor = 43458; type = "boot"; value = "mnopq"; },
{ idvendor = 53459; type = "other"; value = "qwert"; }
);
};
ecn = "limited";
timer: {
statistics = 120;
};
dtls: {
enable = true;
dtlspolicy: {
cleardatachannel = true;
dtlsdatachannel = true;
};
type = "x509";
presharedkey: {
identity = "prova";
pskkey = "123456";
};
x509: {
calist = "/etc/capwap/ca.crt";
certificate = "/etc/capwap/wtp.crt";
privatekey = "/etc/capwap/wtp.key";
};
};
wlan: {
prefix = "ap";
};
radio = (
{
device = "phy0";
enabled = true;
driver = "nl80211";
mode = "g";
country = "IT";
outdoor = false;
rtsthreshold = 2347;
shortretry = 7;
longretry = 4;
shortpreamble = true;
fragmentationthreshold = 2346;
txmsdulifetime = 512;
rxmsdulifetime = 512;
maxbssid = 1;
bssprefixname = "ap";
dtimperiod = 1;
beaconperiod = 100;
antenna = {
diversity = false;
combiner = "omni";
selection = [ "internal" ];
};
multidomaincapability = {
firstchannel = 1;
numberchannels = 11;
maxtxpower = 100;
};
supportedrates = [
12, 18, 24, 36, 48, 72, 96, 108
];
txpower = {
current = 100;
supported = [ 100 ];
};
}
);
network: {
#binding = "eth1";
#listen = "";
#port = 0;
transport = "udp";
mtu = 1400;
};
acdiscovery: {
search = true;
host = [
"127.0.0.1"
];
};
acprefered: {
host = [
"127.0.0.1"
];
};
};
logging: {
enable = true;
level = "debug";
output = (
{ mode = "stdout"; }
);
};
# WTP configuration file
version = "1.0";
application: {
standalone = true;
name = "wtp 1";
location = "Ufficio";
binding = "802.11";
tunnelmode: {
nativeframe = false;
ethframe = false;
localbridging = true;
};
mactype = "localmac";
boardinfo: {
idvendor = 123456;
element = (
{ name = "model"; value = "1.0"; },
{ name = "serial"; value = "2.0"; },
{ name = "id"; value = "3.0"; },
{ name = "revision"; value = "4.0"; },
{ name = "macaddress"; type = "interface"; value = "eth1"; }
);
};
descriptor: {
encryption = [
"802.11_AES",
"802.11_TKIP"
];
info = (
{ idvendor = 23456; type = "hardware"; value = "abcde"; },
{ idvendor = 33457; type = "software"; value = "fghil"; },
{ idvendor = 43458; type = "boot"; value = "mnopq"; },
{ idvendor = 53459; type = "other"; value = "qwert"; }
);
};
ecn = "limited";
timer: {
statistics = 120;
};
dtls: {
enable = true;
dtlspolicy: {
cleardatachannel = true;
dtlsdatachannel = true;
};
type = "x509";
presharedkey: {
identity = "prova";
pskkey = "123456";
};
x509: {
calist = "/etc/capwap/ca.crt";
certificate = "/etc/capwap/wtp.crt";
privatekey = "/etc/capwap/wtp.key";
};
};
wlan: {
prefix = "ap";
};
radio = (
{
device = "phy0";
enabled = true;
driver = "nl80211";
mode = "g";
country = "IT";
outdoor = false;
rtsthreshold = 2347;
shortretry = 7;
longretry = 4;
shortpreamble = true;
fragmentationthreshold = 2346;
txmsdulifetime = 512;
rxmsdulifetime = 512;
maxbssid = 1;
bssprefixname = "ap";
dtimperiod = 1;
beaconperiod = 100;
antenna = {
diversity = false;
combiner = "omni";
selection = [ "internal" ];
};
multidomaincapability = {
firstchannel = 1;
numberchannels = 11;
maxtxpower = 100;
};
supportedrates = [
12, 18, 24, 36, 48, 72, 96, 108
];
txpower = {
current = 100;
supported = [ 100 ];
};
}
);
network: {
#binding = "eth1";
#listen = "";
#port = 0;
transport = "udp";
mtu = 1400;
};
acdiscovery: {
search = true;
host = [
"127.0.0.1"
];
};
acprefered: {
host = [
"127.0.0.1"
];
};
};
logging: {
enable = true;
level = "debug";
output = (
{ mode = "stdout"; }
);
};

View File

@ -1,470 +1,470 @@
#include "ac.h"
#include "ac_json.h"
/* */
static struct ac_json_ieee80211_ops* ac_json_80211_message_elements[] = {
/* CAPWAP_ELEMENT_80211_ADD_WLAN */ &ac_json_80211_addwlan_ops,
/* CAPWAP_ELEMENT_80211_ANTENNA */ &ac_json_80211_antenna_ops,
/* CAPWAP_ELEMENT_80211_ASSIGN_BSSID */ &ac_json_80211_assignbssid_ops,
/* CAPWAP_ELEMENT_80211_DELETE_WLAN */ &ac_json_80211_deletewlan_ops,
/* CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL */ &ac_json_80211_directsequencecontrol_ops,
/* CAPWAP_ELEMENT_80211_IE */ &ac_json_80211_ie_ops,
/* CAPWAP_ELEMENT_80211_MACOPERATION */ &ac_json_80211_macoperation_ops,
/* CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES */ &ac_json_80211_miccountermeasures_ops,
/* CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY */ &ac_json_80211_multidomaincapability_ops,
/* CAPWAP_ELEMENT_80211_OFDMCONTROL */ &ac_json_80211_ofdmcontrol_ops,
/* CAPWAP_ELEMENT_80211_RATESET */ &ac_json_80211_rateset_ops,
/* CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT */ &ac_json_80211_rsnaerrorreport_ops,
/* CAPWAP_ELEMENT_80211_STATION */ NULL,
/* CAPWAP_ELEMENT_80211_STATION_QOS_PROFILE */ NULL,
/* CAPWAP_ELEMENT_80211_STATION_SESSION_KEY_PROFILE */ NULL,
/* CAPWAP_ELEMENT_80211_STATISTICS */ &ac_json_80211_statistics_ops,
/* CAPWAP_ELEMENT_80211_SUPPORTEDRATES */ &ac_json_80211_supportedrates_ops,
/* CAPWAP_ELEMENT_80211_TXPOWER */ &ac_json_80211_txpower_ops,
/* CAPWAP_ELEMENT_80211_TXPOWERLEVEL */ &ac_json_80211_txpowerlevel_ops,
/* CAPWAP_ELEMENT_80211_UPDATE_STATION_QOS */ NULL,
/* CAPWAP_ELEMENT_80211_UPDATE_WLAN */ &ac_json_80211_updatewlan_ops,
/* CAPWAP_ELEMENT_80211_WTP_QOS */ &ac_json_80211_wtpqos_ops,
/* CAPWAP_ELEMENT_80211_WTP_RADIO_CONF */ &ac_json_80211_wtpradioconf_ops,
/* CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM */ &ac_json_80211_wtpradiofailalarm_ops,
/* CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION */ &ac_json_80211_wtpradioinformation_ops
};
/* */
static struct ac_json_ieee80211_ops* ac_json_80211_getops_by_capwaptype(uint16_t type) {
int i;
for (i = 0; i < CAPWAP_80211_MESSAGE_ELEMENTS_COUNT; i++) {
if (ac_json_80211_message_elements[i] && (ac_json_80211_message_elements[i]->type == type)) {
return ac_json_80211_message_elements[i];
}
}
return NULL;
}
/* */
static struct ac_json_ieee80211_ops* ac_json_80211_getops_by_jsontype(char* type) {
int i;
for (i = 0; i < CAPWAP_80211_MESSAGE_ELEMENTS_COUNT; i++) {
if (ac_json_80211_message_elements[i] && !strcmp(ac_json_80211_message_elements[i]->json_type, type)) {
return ac_json_80211_message_elements[i];
}
}
return NULL;
}
/* */
void ac_json_ieee80211_init(struct ac_json_ieee80211_wtpradio* wtpradio) {
ASSERT(wtpradio != NULL);
memset(wtpradio, 0, sizeof(struct ac_json_ieee80211_wtpradio));
}
/* */
void ac_json_ieee80211_free(struct ac_json_ieee80211_wtpradio* wtpradio) {
int i, j;
ASSERT(wtpradio != NULL);
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
if (item->valid) {
if (item->addwlan) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ADD_WLAN)->free_message_element(item->addwlan);
}
if (item->antenna) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ANTENNA)->free_message_element(item->antenna);
}
if (item->assignbssid) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ASSIGN_BSSID)->free_message_element(item->assignbssid);
}
if (item->deletewlan) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DELETE_WLAN)->free_message_element(item->deletewlan);
}
if (item->directsequencecontrol) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL)->free_message_element(item->directsequencecontrol);
}
if (item->iearray) {
struct capwap_message_elements_ops* ieops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_IE);
for (j = 0; j < item->iearray->count; j++) {
ieops->free_message_element(*(struct capwap_80211_ie_element**)capwap_array_get_item_pointer(item->iearray, j));
}
capwap_array_free(item->iearray);
}
if (item->macoperation) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MACOPERATION)->free_message_element(item->macoperation);
}
if (item->miccountermeasures) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES)->free_message_element(item->miccountermeasures);
}
if (item->multidomaincapability) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY)->free_message_element(item->multidomaincapability);
}
if (item->ofdmcontrol) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_OFDMCONTROL)->free_message_element(item->ofdmcontrol);
}
if (item->rateset) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RATESET)->free_message_element(item->rateset);
}
if (item->rsnaerrorreport) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT)->free_message_element(item->rsnaerrorreport);
}
if (item->statistics) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_STATISTICS)->free_message_element(item->statistics);
}
if (item->supportedrates) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_SUPPORTEDRATES)->free_message_element(item->supportedrates);
}
if (item->txpower) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWER)->free_message_element(item->txpower);
}
if (item->txpowerlevel) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWERLEVEL)->free_message_element(item->txpowerlevel);
}
if (item->updatewlan) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_UPDATE_WLAN)->free_message_element(item->updatewlan);
}
if (item->wtpqos) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_QOS)->free_message_element(item->wtpqos);
}
if (item->wtpradioconf) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_CONF)->free_message_element(item->wtpradioconf);
}
if (item->wtpradiofailalarm) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM)->free_message_element(item->wtpradiofailalarm);
}
if (item->wtpradioinformation) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)->free_message_element(item->wtpradioinformation);
}
}
}
}
/* */
int ac_json_ieee80211_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, uint16_t type, void* data, int overwrite) {
struct ac_json_ieee80211_ops* ops;
ASSERT(wtpradio != NULL);
ASSERT(IS_80211_MESSAGE_ELEMENTS(type));
ASSERT(data != NULL);
/* */
ops = ac_json_80211_getops_by_capwaptype(type);
if (!ops) {
return 0;
}
return ops->add_message_element(wtpradio, data, overwrite);
}
/* */
int ac_json_ieee80211_parsingmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_message_element_itemlist* messageelement) {
int i;
ASSERT(wtpradio != NULL);
ASSERT(messageelement != NULL);
ASSERT(IS_80211_MESSAGE_ELEMENTS(messageelement->type));
if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_SINGLE) {
if (!ac_json_ieee80211_addmessageelement(wtpradio, messageelement->type, messageelement->data, 0)) {
return 0;
}
} else if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_ARRAY) {
struct capwap_array* items = (struct capwap_array*)messageelement->data;
for (i = 0; i < items->count; i++) {
if (!ac_json_ieee80211_addmessageelement(wtpradio, messageelement->type, *(void**)capwap_array_get_item_pointer(items, i), 0)) {
return 0;
}
}
} else {
return 0;
}
return 1;
}
/* */
int ac_json_ieee80211_parsingjson(struct ac_json_ieee80211_wtpradio* wtpradio, struct json_object* jsonroot) {
int i;
int length;
ASSERT(wtpradio != NULL);
ASSERT(jsonroot != NULL);
if (json_object_get_type(jsonroot) != json_type_array) {
return 0;
}
/* */
length = json_object_array_length(jsonroot);
for (i = 0; i < length; i++) {
struct json_object* jsonitem;
struct json_object* jsonradio = json_object_array_get_idx(jsonroot, i);
/* Get RadioID */
jsonitem = compat_json_object_object_get(jsonradio, "RadioID");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
int radioid = json_object_get_int(jsonitem);
if (IS_VALID_RADIOID(radioid)) {
struct lh_entry* entry;
/* Parsing every entry */
for(entry = json_object_get_object(jsonradio)->head; entry != NULL; entry = entry->next) {
struct ac_json_ieee80211_ops* ops = ac_json_80211_getops_by_jsontype((char*)entry->k); /* Retrieve JSON handler */
if (ops) {
void* data = ops->create_message_element((struct json_object*)entry->v, radioid);
if (data) {
/* Message element complete */
ac_json_ieee80211_addmessageelement(wtpradio, ops->type, data, 1);
/* Free resource */
capwap_get_message_element_ops(ops->type)->free_message_element(data);
}
}
}
}
}
}
return 1;
}
/* */
struct json_object* ac_json_ieee80211_getjson(struct ac_json_ieee80211_wtpradio* wtpradio) {
int i;
struct json_object* jsonarray;
struct json_object* jsonitems;
ASSERT(wtpradio != NULL);
jsonarray = json_object_new_array();
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
if (!item->valid) {
continue;
}
/* */
jsonitems = json_object_new_object();
/* Radio Id */
json_object_object_add(jsonitems, "RadioID", json_object_new_int(i + 1));
if (item->addwlan) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_ADD_WLAN)->create_json(jsonitems, item->addwlan);
}
if (item->antenna) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_ANTENNA)->create_json(jsonitems, item->antenna);
}
if (item->assignbssid) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_ASSIGN_BSSID)->create_json(jsonitems, item->assignbssid);
}
if (item->deletewlan) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_DELETE_WLAN)->create_json(jsonitems, item->deletewlan);
}
if (item->directsequencecontrol) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL)->create_json(jsonitems, item->directsequencecontrol);
}
if (item->iearray) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_IE)->create_json(jsonitems, item->iearray);
}
if (item->macoperation) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_MACOPERATION)->create_json(jsonitems, item->macoperation);
}
if (item->miccountermeasures) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES)->create_json(jsonitems, item->miccountermeasures);
}
if (item->multidomaincapability) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY)->create_json(jsonitems, item->multidomaincapability);
}
if (item->ofdmcontrol) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_OFDMCONTROL)->create_json(jsonitems, item->ofdmcontrol);
}
if (item->rateset) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_RATESET)->create_json(jsonitems, item->rateset);
}
if (item->rsnaerrorreport) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT)->create_json(jsonitems, item->rsnaerrorreport);
}
if (item->statistics) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_STATISTICS)->create_json(jsonitems, item->statistics);
}
if (item->supportedrates) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_SUPPORTEDRATES)->create_json(jsonitems, item->supportedrates);
}
if (item->txpower) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_TXPOWER)->create_json(jsonitems, item->txpower);
}
if (item->txpowerlevel) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_TXPOWERLEVEL)->create_json(jsonitems, item->txpowerlevel);
}
if (item->updatewlan) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_UPDATE_WLAN)->create_json(jsonitems, item->updatewlan);
}
if (item->wtpqos) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTP_QOS)->create_json(jsonitems, item->wtpqos);
}
if (item->wtpradioconf) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTP_RADIO_CONF)->create_json(jsonitems, item->wtpradioconf);
}
if (item->wtpradiofailalarm) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM)->create_json(jsonitems, item->wtpradiofailalarm);
}
if (item->wtpradioinformation) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)->create_json(jsonitems, item->wtpradioinformation);
}
/* */
json_object_array_add(jsonarray, jsonitems);
}
return jsonarray;
}
/* */
void ac_json_ieee80211_buildpacket(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_packet_txmng* txmngpacket) {
int i, j;
ASSERT(wtpradio != NULL);
ASSERT(txmngpacket != NULL);
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
if (item->valid) {
if (item->addwlan) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ADD_WLAN, item->addwlan);
}
if (item->antenna) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ANTENNA, item->antenna);
}
if (item->assignbssid) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ASSIGN_BSSID, item->assignbssid);
}
if (item->deletewlan) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_DELETE_WLAN, item->deletewlan);
}
if (item->directsequencecontrol) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL, item->directsequencecontrol);
}
if (item->iearray) {
for (j = 0; j < item->iearray->count; j++) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_IE, *(struct capwap_80211_ie_element**)capwap_array_get_item_pointer(item->iearray, j));
}
}
if (item->macoperation) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_MACOPERATION, item->macoperation);
}
if (item->miccountermeasures) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES, item->miccountermeasures);
}
if (item->multidomaincapability) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY, item->multidomaincapability);
}
if (item->ofdmcontrol) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_OFDMCONTROL, item->ofdmcontrol);
}
if (item->rateset) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_RATESET, item->rateset);
}
if (item->rsnaerrorreport) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT, item->rsnaerrorreport);
}
if (item->statistics) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_STATISTICS, item->statistics);
}
if (item->supportedrates) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_SUPPORTEDRATES, item->supportedrates);
}
if (item->txpower) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_TXPOWER, item->txpower);
}
if (item->txpowerlevel) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_TXPOWERLEVEL, item->txpowerlevel);
}
if (item->updatewlan) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_UPDATE_WLAN, item->updatewlan);
}
if (item->wtpqos) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTP_QOS, item->wtpqos);
}
if (item->wtpradioconf) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTP_RADIO_CONF, item->wtpradioconf);
}
if (item->wtpradiofailalarm) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM, item->wtpradiofailalarm);
}
if (item->wtpradioinformation) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, item->wtpradioinformation);
}
}
}
}
#include "ac.h"
#include "ac_json.h"
/* */
static struct ac_json_ieee80211_ops* ac_json_80211_message_elements[] = {
/* CAPWAP_ELEMENT_80211_ADD_WLAN */ &ac_json_80211_addwlan_ops,
/* CAPWAP_ELEMENT_80211_ANTENNA */ &ac_json_80211_antenna_ops,
/* CAPWAP_ELEMENT_80211_ASSIGN_BSSID */ &ac_json_80211_assignbssid_ops,
/* CAPWAP_ELEMENT_80211_DELETE_WLAN */ &ac_json_80211_deletewlan_ops,
/* CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL */ &ac_json_80211_directsequencecontrol_ops,
/* CAPWAP_ELEMENT_80211_IE */ &ac_json_80211_ie_ops,
/* CAPWAP_ELEMENT_80211_MACOPERATION */ &ac_json_80211_macoperation_ops,
/* CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES */ &ac_json_80211_miccountermeasures_ops,
/* CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY */ &ac_json_80211_multidomaincapability_ops,
/* CAPWAP_ELEMENT_80211_OFDMCONTROL */ &ac_json_80211_ofdmcontrol_ops,
/* CAPWAP_ELEMENT_80211_RATESET */ &ac_json_80211_rateset_ops,
/* CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT */ &ac_json_80211_rsnaerrorreport_ops,
/* CAPWAP_ELEMENT_80211_STATION */ NULL,
/* CAPWAP_ELEMENT_80211_STATION_QOS_PROFILE */ NULL,
/* CAPWAP_ELEMENT_80211_STATION_SESSION_KEY_PROFILE */ NULL,
/* CAPWAP_ELEMENT_80211_STATISTICS */ &ac_json_80211_statistics_ops,
/* CAPWAP_ELEMENT_80211_SUPPORTEDRATES */ &ac_json_80211_supportedrates_ops,
/* CAPWAP_ELEMENT_80211_TXPOWER */ &ac_json_80211_txpower_ops,
/* CAPWAP_ELEMENT_80211_TXPOWERLEVEL */ &ac_json_80211_txpowerlevel_ops,
/* CAPWAP_ELEMENT_80211_UPDATE_STATION_QOS */ NULL,
/* CAPWAP_ELEMENT_80211_UPDATE_WLAN */ &ac_json_80211_updatewlan_ops,
/* CAPWAP_ELEMENT_80211_WTP_QOS */ &ac_json_80211_wtpqos_ops,
/* CAPWAP_ELEMENT_80211_WTP_RADIO_CONF */ &ac_json_80211_wtpradioconf_ops,
/* CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM */ &ac_json_80211_wtpradiofailalarm_ops,
/* CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION */ &ac_json_80211_wtpradioinformation_ops
};
/* */
static struct ac_json_ieee80211_ops* ac_json_80211_getops_by_capwaptype(uint16_t type) {
int i;
for (i = 0; i < CAPWAP_80211_MESSAGE_ELEMENTS_COUNT; i++) {
if (ac_json_80211_message_elements[i] && (ac_json_80211_message_elements[i]->type == type)) {
return ac_json_80211_message_elements[i];
}
}
return NULL;
}
/* */
static struct ac_json_ieee80211_ops* ac_json_80211_getops_by_jsontype(char* type) {
int i;
for (i = 0; i < CAPWAP_80211_MESSAGE_ELEMENTS_COUNT; i++) {
if (ac_json_80211_message_elements[i] && !strcmp(ac_json_80211_message_elements[i]->json_type, type)) {
return ac_json_80211_message_elements[i];
}
}
return NULL;
}
/* */
void ac_json_ieee80211_init(struct ac_json_ieee80211_wtpradio* wtpradio) {
ASSERT(wtpradio != NULL);
memset(wtpradio, 0, sizeof(struct ac_json_ieee80211_wtpradio));
}
/* */
void ac_json_ieee80211_free(struct ac_json_ieee80211_wtpradio* wtpradio) {
int i, j;
ASSERT(wtpradio != NULL);
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
if (item->valid) {
if (item->addwlan) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ADD_WLAN)->free_message_element(item->addwlan);
}
if (item->antenna) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ANTENNA)->free_message_element(item->antenna);
}
if (item->assignbssid) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ASSIGN_BSSID)->free_message_element(item->assignbssid);
}
if (item->deletewlan) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DELETE_WLAN)->free_message_element(item->deletewlan);
}
if (item->directsequencecontrol) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL)->free_message_element(item->directsequencecontrol);
}
if (item->iearray) {
struct capwap_message_elements_ops* ieops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_IE);
for (j = 0; j < item->iearray->count; j++) {
ieops->free_message_element(*(struct capwap_80211_ie_element**)capwap_array_get_item_pointer(item->iearray, j));
}
capwap_array_free(item->iearray);
}
if (item->macoperation) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MACOPERATION)->free_message_element(item->macoperation);
}
if (item->miccountermeasures) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES)->free_message_element(item->miccountermeasures);
}
if (item->multidomaincapability) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY)->free_message_element(item->multidomaincapability);
}
if (item->ofdmcontrol) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_OFDMCONTROL)->free_message_element(item->ofdmcontrol);
}
if (item->rateset) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RATESET)->free_message_element(item->rateset);
}
if (item->rsnaerrorreport) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT)->free_message_element(item->rsnaerrorreport);
}
if (item->statistics) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_STATISTICS)->free_message_element(item->statistics);
}
if (item->supportedrates) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_SUPPORTEDRATES)->free_message_element(item->supportedrates);
}
if (item->txpower) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWER)->free_message_element(item->txpower);
}
if (item->txpowerlevel) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWERLEVEL)->free_message_element(item->txpowerlevel);
}
if (item->updatewlan) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_UPDATE_WLAN)->free_message_element(item->updatewlan);
}
if (item->wtpqos) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_QOS)->free_message_element(item->wtpqos);
}
if (item->wtpradioconf) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_CONF)->free_message_element(item->wtpradioconf);
}
if (item->wtpradiofailalarm) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM)->free_message_element(item->wtpradiofailalarm);
}
if (item->wtpradioinformation) {
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)->free_message_element(item->wtpradioinformation);
}
}
}
}
/* */
int ac_json_ieee80211_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, uint16_t type, void* data, int overwrite) {
struct ac_json_ieee80211_ops* ops;
ASSERT(wtpradio != NULL);
ASSERT(IS_80211_MESSAGE_ELEMENTS(type));
ASSERT(data != NULL);
/* */
ops = ac_json_80211_getops_by_capwaptype(type);
if (!ops) {
return 0;
}
return ops->add_message_element(wtpradio, data, overwrite);
}
/* */
int ac_json_ieee80211_parsingmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_message_element_itemlist* messageelement) {
int i;
ASSERT(wtpradio != NULL);
ASSERT(messageelement != NULL);
ASSERT(IS_80211_MESSAGE_ELEMENTS(messageelement->type));
if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_SINGLE) {
if (!ac_json_ieee80211_addmessageelement(wtpradio, messageelement->type, messageelement->data, 0)) {
return 0;
}
} else if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_ARRAY) {
struct capwap_array* items = (struct capwap_array*)messageelement->data;
for (i = 0; i < items->count; i++) {
if (!ac_json_ieee80211_addmessageelement(wtpradio, messageelement->type, *(void**)capwap_array_get_item_pointer(items, i), 0)) {
return 0;
}
}
} else {
return 0;
}
return 1;
}
/* */
int ac_json_ieee80211_parsingjson(struct ac_json_ieee80211_wtpradio* wtpradio, struct json_object* jsonroot) {
int i;
int length;
ASSERT(wtpradio != NULL);
ASSERT(jsonroot != NULL);
if (json_object_get_type(jsonroot) != json_type_array) {
return 0;
}
/* */
length = json_object_array_length(jsonroot);
for (i = 0; i < length; i++) {
struct json_object* jsonitem;
struct json_object* jsonradio = json_object_array_get_idx(jsonroot, i);
/* Get RadioID */
jsonitem = compat_json_object_object_get(jsonradio, "RadioID");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
int radioid = json_object_get_int(jsonitem);
if (IS_VALID_RADIOID(radioid)) {
struct lh_entry* entry;
/* Parsing every entry */
for(entry = json_object_get_object(jsonradio)->head; entry != NULL; entry = entry->next) {
struct ac_json_ieee80211_ops* ops = ac_json_80211_getops_by_jsontype((char*)entry->k); /* Retrieve JSON handler */
if (ops) {
void* data = ops->create_message_element((struct json_object*)entry->v, radioid);
if (data) {
/* Message element complete */
ac_json_ieee80211_addmessageelement(wtpradio, ops->type, data, 1);
/* Free resource */
capwap_get_message_element_ops(ops->type)->free_message_element(data);
}
}
}
}
}
}
return 1;
}
/* */
struct json_object* ac_json_ieee80211_getjson(struct ac_json_ieee80211_wtpradio* wtpradio) {
int i;
struct json_object* jsonarray;
struct json_object* jsonitems;
ASSERT(wtpradio != NULL);
jsonarray = json_object_new_array();
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
if (!item->valid) {
continue;
}
/* */
jsonitems = json_object_new_object();
/* Radio Id */
json_object_object_add(jsonitems, "RadioID", json_object_new_int(i + 1));
if (item->addwlan) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_ADD_WLAN)->create_json(jsonitems, item->addwlan);
}
if (item->antenna) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_ANTENNA)->create_json(jsonitems, item->antenna);
}
if (item->assignbssid) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_ASSIGN_BSSID)->create_json(jsonitems, item->assignbssid);
}
if (item->deletewlan) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_DELETE_WLAN)->create_json(jsonitems, item->deletewlan);
}
if (item->directsequencecontrol) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL)->create_json(jsonitems, item->directsequencecontrol);
}
if (item->iearray) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_IE)->create_json(jsonitems, item->iearray);
}
if (item->macoperation) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_MACOPERATION)->create_json(jsonitems, item->macoperation);
}
if (item->miccountermeasures) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES)->create_json(jsonitems, item->miccountermeasures);
}
if (item->multidomaincapability) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY)->create_json(jsonitems, item->multidomaincapability);
}
if (item->ofdmcontrol) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_OFDMCONTROL)->create_json(jsonitems, item->ofdmcontrol);
}
if (item->rateset) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_RATESET)->create_json(jsonitems, item->rateset);
}
if (item->rsnaerrorreport) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT)->create_json(jsonitems, item->rsnaerrorreport);
}
if (item->statistics) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_STATISTICS)->create_json(jsonitems, item->statistics);
}
if (item->supportedrates) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_SUPPORTEDRATES)->create_json(jsonitems, item->supportedrates);
}
if (item->txpower) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_TXPOWER)->create_json(jsonitems, item->txpower);
}
if (item->txpowerlevel) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_TXPOWERLEVEL)->create_json(jsonitems, item->txpowerlevel);
}
if (item->updatewlan) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_UPDATE_WLAN)->create_json(jsonitems, item->updatewlan);
}
if (item->wtpqos) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTP_QOS)->create_json(jsonitems, item->wtpqos);
}
if (item->wtpradioconf) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTP_RADIO_CONF)->create_json(jsonitems, item->wtpradioconf);
}
if (item->wtpradiofailalarm) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM)->create_json(jsonitems, item->wtpradiofailalarm);
}
if (item->wtpradioinformation) {
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)->create_json(jsonitems, item->wtpradioinformation);
}
/* */
json_object_array_add(jsonarray, jsonitems);
}
return jsonarray;
}
/* */
void ac_json_ieee80211_buildpacket(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_packet_txmng* txmngpacket) {
int i, j;
ASSERT(wtpradio != NULL);
ASSERT(txmngpacket != NULL);
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
if (item->valid) {
if (item->addwlan) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ADD_WLAN, item->addwlan);
}
if (item->antenna) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ANTENNA, item->antenna);
}
if (item->assignbssid) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ASSIGN_BSSID, item->assignbssid);
}
if (item->deletewlan) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_DELETE_WLAN, item->deletewlan);
}
if (item->directsequencecontrol) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL, item->directsequencecontrol);
}
if (item->iearray) {
for (j = 0; j < item->iearray->count; j++) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_IE, *(struct capwap_80211_ie_element**)capwap_array_get_item_pointer(item->iearray, j));
}
}
if (item->macoperation) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_MACOPERATION, item->macoperation);
}
if (item->miccountermeasures) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES, item->miccountermeasures);
}
if (item->multidomaincapability) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY, item->multidomaincapability);
}
if (item->ofdmcontrol) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_OFDMCONTROL, item->ofdmcontrol);
}
if (item->rateset) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_RATESET, item->rateset);
}
if (item->rsnaerrorreport) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT, item->rsnaerrorreport);
}
if (item->statistics) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_STATISTICS, item->statistics);
}
if (item->supportedrates) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_SUPPORTEDRATES, item->supportedrates);
}
if (item->txpower) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_TXPOWER, item->txpower);
}
if (item->txpowerlevel) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_TXPOWERLEVEL, item->txpowerlevel);
}
if (item->updatewlan) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_UPDATE_WLAN, item->updatewlan);
}
if (item->wtpqos) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTP_QOS, item->wtpqos);
}
if (item->wtpradioconf) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTP_RADIO_CONF, item->wtpradioconf);
}
if (item->wtpradiofailalarm) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM, item->wtpradiofailalarm);
}
if (item->wtpradioinformation) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, item->wtpradioinformation);
}
}
}
}

View File

@ -1,41 +1,41 @@
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_addwlan_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_addwlan_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_addwlan_element* addwlan = (struct capwap_80211_addwlan_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[addwlan->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ADD_WLAN);
if (item->addwlan) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->addwlan);
}
item->valid = 1;
item->addwlan = (struct capwap_80211_addwlan_element*)ops->clone_message_element(addwlan);
return 1;
}
/* */
static void ac_json_80211_addwlan_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_addwlan_ops = {
.type = CAPWAP_ELEMENT_80211_ADD_WLAN,
.json_type = "IEEE80211AddWLAN",
.create_message_element = ac_json_80211_addwlan_createmessageelement,
.add_message_element = ac_json_80211_addwlan_addmessageelement,
.create_json = ac_json_80211_addwlan_createjson
};
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_addwlan_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_addwlan_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_addwlan_element* addwlan = (struct capwap_80211_addwlan_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[addwlan->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ADD_WLAN);
if (item->addwlan) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->addwlan);
}
item->valid = 1;
item->addwlan = (struct capwap_80211_addwlan_element*)ops->clone_message_element(addwlan);
return 1;
}
/* */
static void ac_json_80211_addwlan_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_addwlan_ops = {
.type = CAPWAP_ELEMENT_80211_ADD_WLAN,
.json_type = "IEEE80211AddWLAN",
.create_message_element = ac_json_80211_addwlan_createmessageelement,
.add_message_element = ac_json_80211_addwlan_addmessageelement,
.create_json = ac_json_80211_addwlan_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_ADDWLAN_HEADER__
#define __AC_JSON_80211_ADDWLAN_HEADER__
#include "capwap_element_80211_addwlan.h"
extern struct ac_json_ieee80211_ops ac_json_80211_addwlan_ops;
#endif /* __AC_JSON_80211_ADDWLAN_HEADER__ */
#ifndef __AC_JSON_80211_ADDWLAN_HEADER__
#define __AC_JSON_80211_ADDWLAN_HEADER__
#include "capwap_element_80211_addwlan.h"
extern struct ac_json_ieee80211_ops ac_json_80211_addwlan_ops;
#endif /* __AC_JSON_80211_ADDWLAN_HEADER__ */

View File

@ -1,109 +1,109 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211Antenna: {
Diversity: [bool],
Combiner: [int],
AntennaSelection: [
[int]
]
}
*/
/* */
static void* ac_json_80211_antenna_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_antenna_element* antenna;
antenna = (struct capwap_80211_antenna_element*)capwap_alloc(sizeof(struct capwap_80211_antenna_element));
memset(antenna, 0, sizeof(struct capwap_80211_antenna_element));
antenna->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "Diversity");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_boolean)) {
antenna->diversity = (json_object_get_boolean(jsonitem) ? CAPWAP_ANTENNA_DIVERSITY_ENABLE : CAPWAP_ANTENNA_DIVERSITY_DISABLE);
} else {
capwap_free(antenna);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "Combiner");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
antenna->combiner = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(antenna);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "AntennaSelection");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_array)) {
int i;
int length;
antenna->selections = capwap_array_create(sizeof(uint8_t), 0, 1);
length = json_object_array_length(jsonitem);
for (i = 0; i < length; i++) {
struct json_object* jsonvalue = json_object_array_get_idx(jsonitem, i);
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
uint8_t* value = (uint8_t*)capwap_array_get_item_pointer(antenna->selections, antenna->selections->count);
*value = (uint8_t)json_object_get_int(jsonvalue);
}
}
} else {
capwap_free(antenna);
return NULL;
}
return antenna;
}
/* */
static int ac_json_80211_antenna_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_antenna_element* antenna = (struct capwap_80211_antenna_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[antenna->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ANTENNA);
if (item->antenna) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->antenna);
}
item->valid = 1;
item->antenna = (struct capwap_80211_antenna_element*)ops->clone_message_element(antenna);
return 1;
}
/* */
static void ac_json_80211_antenna_createjson(struct json_object* jsonparent, void* data) {
int i;
struct json_object* jsonantenna;
struct json_object* jsonitem;
struct capwap_80211_antenna_element* antenna = (struct capwap_80211_antenna_element*)data;
jsonantenna = json_object_new_array();
for (i = 0; i < antenna->selections->count; i++) {
json_object_array_add(jsonantenna, json_object_new_int((int)*(uint8_t*)capwap_array_get_item_pointer(antenna->selections, i)));
}
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "Diversity", json_object_new_boolean((antenna->diversity == CAPWAP_ANTENNA_DIVERSITY_ENABLE) ? 1 : 0));
json_object_object_add(jsonitem, "Combiner", json_object_new_int((int)antenna->combiner));
json_object_object_add(jsonitem, "AntennaSelection", jsonantenna);
json_object_object_add(jsonparent, "IEEE80211Antenna", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_antenna_ops = {
.type = CAPWAP_ELEMENT_80211_ANTENNA,
.json_type = "IEEE80211Antenna",
.create_message_element = ac_json_80211_antenna_createmessageelement,
.add_message_element = ac_json_80211_antenna_addmessageelement,
.create_json = ac_json_80211_antenna_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211Antenna: {
Diversity: [bool],
Combiner: [int],
AntennaSelection: [
[int]
]
}
*/
/* */
static void* ac_json_80211_antenna_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_antenna_element* antenna;
antenna = (struct capwap_80211_antenna_element*)capwap_alloc(sizeof(struct capwap_80211_antenna_element));
memset(antenna, 0, sizeof(struct capwap_80211_antenna_element));
antenna->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "Diversity");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_boolean)) {
antenna->diversity = (json_object_get_boolean(jsonitem) ? CAPWAP_ANTENNA_DIVERSITY_ENABLE : CAPWAP_ANTENNA_DIVERSITY_DISABLE);
} else {
capwap_free(antenna);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "Combiner");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
antenna->combiner = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(antenna);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "AntennaSelection");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_array)) {
int i;
int length;
antenna->selections = capwap_array_create(sizeof(uint8_t), 0, 1);
length = json_object_array_length(jsonitem);
for (i = 0; i < length; i++) {
struct json_object* jsonvalue = json_object_array_get_idx(jsonitem, i);
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
uint8_t* value = (uint8_t*)capwap_array_get_item_pointer(antenna->selections, antenna->selections->count);
*value = (uint8_t)json_object_get_int(jsonvalue);
}
}
} else {
capwap_free(antenna);
return NULL;
}
return antenna;
}
/* */
static int ac_json_80211_antenna_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_antenna_element* antenna = (struct capwap_80211_antenna_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[antenna->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ANTENNA);
if (item->antenna) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->antenna);
}
item->valid = 1;
item->antenna = (struct capwap_80211_antenna_element*)ops->clone_message_element(antenna);
return 1;
}
/* */
static void ac_json_80211_antenna_createjson(struct json_object* jsonparent, void* data) {
int i;
struct json_object* jsonantenna;
struct json_object* jsonitem;
struct capwap_80211_antenna_element* antenna = (struct capwap_80211_antenna_element*)data;
jsonantenna = json_object_new_array();
for (i = 0; i < antenna->selections->count; i++) {
json_object_array_add(jsonantenna, json_object_new_int((int)*(uint8_t*)capwap_array_get_item_pointer(antenna->selections, i)));
}
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "Diversity", json_object_new_boolean((antenna->diversity == CAPWAP_ANTENNA_DIVERSITY_ENABLE) ? 1 : 0));
json_object_object_add(jsonitem, "Combiner", json_object_new_int((int)antenna->combiner));
json_object_object_add(jsonitem, "AntennaSelection", jsonantenna);
json_object_object_add(jsonparent, "IEEE80211Antenna", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_antenna_ops = {
.type = CAPWAP_ELEMENT_80211_ANTENNA,
.json_type = "IEEE80211Antenna",
.create_message_element = ac_json_80211_antenna_createmessageelement,
.add_message_element = ac_json_80211_antenna_addmessageelement,
.create_json = ac_json_80211_antenna_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_ANTENNA_HEADER__
#define __AC_JSON_80211_ANTENNA_HEADER__
#include "capwap_element_80211_antenna.h"
extern struct ac_json_ieee80211_ops ac_json_80211_antenna_ops;
#endif /* __AC_JSON_80211_ANTENNA_HEADER__ */
#ifndef __AC_JSON_80211_ANTENNA_HEADER__
#define __AC_JSON_80211_ANTENNA_HEADER__
#include "capwap_element_80211_antenna.h"
extern struct ac_json_ieee80211_ops ac_json_80211_antenna_ops;
#endif /* __AC_JSON_80211_ANTENNA_HEADER__ */

View File

@ -1,41 +1,41 @@
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_assignbssid_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_assignbssid_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_assignbssid_element* assignbssid = (struct capwap_80211_assignbssid_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[assignbssid->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ASSIGN_BSSID);
if (item->assignbssid) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->assignbssid);
}
item->valid = 1;
item->assignbssid = (struct capwap_80211_assignbssid_element*)ops->clone_message_element(assignbssid);
return 1;
}
/* */
static void ac_json_80211_assignbssid_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_assignbssid_ops = {
.type = CAPWAP_ELEMENT_80211_ASSIGN_BSSID,
.json_type = "IEEE80211AssignBSSID",
.create_message_element = ac_json_80211_assignbssid_createmessageelement,
.add_message_element = ac_json_80211_assignbssid_addmessageelement,
.create_json = ac_json_80211_assignbssid_createjson
};
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_assignbssid_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_assignbssid_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_assignbssid_element* assignbssid = (struct capwap_80211_assignbssid_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[assignbssid->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ASSIGN_BSSID);
if (item->assignbssid) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->assignbssid);
}
item->valid = 1;
item->assignbssid = (struct capwap_80211_assignbssid_element*)ops->clone_message_element(assignbssid);
return 1;
}
/* */
static void ac_json_80211_assignbssid_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_assignbssid_ops = {
.type = CAPWAP_ELEMENT_80211_ASSIGN_BSSID,
.json_type = "IEEE80211AssignBSSID",
.create_message_element = ac_json_80211_assignbssid_createmessageelement,
.add_message_element = ac_json_80211_assignbssid_addmessageelement,
.create_json = ac_json_80211_assignbssid_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_ASSIGNBSSID_HEADER__
#define __AC_JSON_80211_ASSIGNBSSID_HEADER__
#include "capwap_element_80211_assignbssid.h"
extern struct ac_json_ieee80211_ops ac_json_80211_assignbssid_ops;
#endif /* __AC_JSON_80211_ASSIGNBSSID_HEADER__ */
#ifndef __AC_JSON_80211_ASSIGNBSSID_HEADER__
#define __AC_JSON_80211_ASSIGNBSSID_HEADER__
#include "capwap_element_80211_assignbssid.h"
extern struct ac_json_ieee80211_ops ac_json_80211_assignbssid_ops;
#endif /* __AC_JSON_80211_ASSIGNBSSID_HEADER__ */

View File

@ -1,41 +1,41 @@
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_deletewlan_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_deletewlan_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_deletewlan_element* deletewlan = (struct capwap_80211_deletewlan_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[deletewlan->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DELETE_WLAN);
if (item->deletewlan) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->deletewlan);
}
item->valid = 1;
item->deletewlan = (struct capwap_80211_deletewlan_element*)ops->clone_message_element(deletewlan);
return 1;
}
/* */
static void ac_json_80211_deletewlan_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_deletewlan_ops = {
.type = CAPWAP_ELEMENT_80211_DELETE_WLAN,
.json_type = "IEEE80211DeleteWLAN",
.create_message_element = ac_json_80211_deletewlan_createmessageelement,
.add_message_element = ac_json_80211_deletewlan_addmessageelement,
.create_json = ac_json_80211_deletewlan_createjson
};
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_deletewlan_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_deletewlan_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_deletewlan_element* deletewlan = (struct capwap_80211_deletewlan_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[deletewlan->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DELETE_WLAN);
if (item->deletewlan) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->deletewlan);
}
item->valid = 1;
item->deletewlan = (struct capwap_80211_deletewlan_element*)ops->clone_message_element(deletewlan);
return 1;
}
/* */
static void ac_json_80211_deletewlan_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_deletewlan_ops = {
.type = CAPWAP_ELEMENT_80211_DELETE_WLAN,
.json_type = "IEEE80211DeleteWLAN",
.create_message_element = ac_json_80211_deletewlan_createmessageelement,
.add_message_element = ac_json_80211_deletewlan_addmessageelement,
.create_json = ac_json_80211_deletewlan_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_DELETEWLAN_HEADER__
#define __AC_JSON_80211_DELETEWLAN_HEADER__
#include "capwap_element_80211_deletewlan.h"
extern struct ac_json_ieee80211_ops ac_json_80211_deletewlan_ops;
#endif /* __AC_JSON_80211_DELETEWLAN_HEADER__ */
#ifndef __AC_JSON_80211_DELETEWLAN_HEADER__
#define __AC_JSON_80211_DELETEWLAN_HEADER__
#include "capwap_element_80211_deletewlan.h"
extern struct ac_json_ieee80211_ops ac_json_80211_deletewlan_ops;
#endif /* __AC_JSON_80211_DELETEWLAN_HEADER__ */

View File

@ -1,88 +1,88 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211DirectSequenceControl: {
CurrentChan: [int],
CurrentCCA: [int],
EnergyDetectThreshold: [int]
}
*/
/* */
static void* ac_json_80211_directsequencecontrol_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_directsequencecontrol_element* directsequencecontrol;
directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)capwap_alloc(sizeof(struct capwap_80211_directsequencecontrol_element));
memset(directsequencecontrol, 0, sizeof(struct capwap_80211_directsequencecontrol_element));
directsequencecontrol->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "CurrentChan");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
directsequencecontrol->currentchannel = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(directsequencecontrol);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "CurrentCCA");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
directsequencecontrol->currentcca = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(directsequencecontrol);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "EnergyDetectThreshold");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
directsequencecontrol->enerydetectthreshold = (uint32_t)json_object_get_int(jsonitem);
} else {
capwap_free(directsequencecontrol);
return NULL;
}
return directsequencecontrol;
}
/* */
static int ac_json_80211_directsequencecontrol_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_directsequencecontrol_element* directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[directsequencecontrol->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL);
if (item->directsequencecontrol) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->directsequencecontrol);
}
item->valid = 1;
item->directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)ops->clone_message_element(directsequencecontrol);
return 1;
}
/* */
static void ac_json_80211_directsequencecontrol_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_directsequencecontrol_element* directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "CurrentChan", json_object_new_int((int)directsequencecontrol->currentchannel));
json_object_object_add(jsonitem, "CurrentCCA", json_object_new_int((int)directsequencecontrol->currentcca));
json_object_object_add(jsonitem, "EnergyDetectThreshold", json_object_new_int((int)directsequencecontrol->enerydetectthreshold));
json_object_object_add(jsonparent, "IEEE80211DirectSequenceControl", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_directsequencecontrol_ops = {
.type = CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL,
.json_type = "IEEE80211DirectSequenceControl",
.create_message_element = ac_json_80211_directsequencecontrol_createmessageelement,
.add_message_element = ac_json_80211_directsequencecontrol_addmessageelement,
.create_json = ac_json_80211_directsequencecontrol_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211DirectSequenceControl: {
CurrentChan: [int],
CurrentCCA: [int],
EnergyDetectThreshold: [int]
}
*/
/* */
static void* ac_json_80211_directsequencecontrol_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_directsequencecontrol_element* directsequencecontrol;
directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)capwap_alloc(sizeof(struct capwap_80211_directsequencecontrol_element));
memset(directsequencecontrol, 0, sizeof(struct capwap_80211_directsequencecontrol_element));
directsequencecontrol->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "CurrentChan");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
directsequencecontrol->currentchannel = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(directsequencecontrol);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "CurrentCCA");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
directsequencecontrol->currentcca = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(directsequencecontrol);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "EnergyDetectThreshold");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
directsequencecontrol->enerydetectthreshold = (uint32_t)json_object_get_int(jsonitem);
} else {
capwap_free(directsequencecontrol);
return NULL;
}
return directsequencecontrol;
}
/* */
static int ac_json_80211_directsequencecontrol_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_directsequencecontrol_element* directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[directsequencecontrol->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL);
if (item->directsequencecontrol) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->directsequencecontrol);
}
item->valid = 1;
item->directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)ops->clone_message_element(directsequencecontrol);
return 1;
}
/* */
static void ac_json_80211_directsequencecontrol_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_directsequencecontrol_element* directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "CurrentChan", json_object_new_int((int)directsequencecontrol->currentchannel));
json_object_object_add(jsonitem, "CurrentCCA", json_object_new_int((int)directsequencecontrol->currentcca));
json_object_object_add(jsonitem, "EnergyDetectThreshold", json_object_new_int((int)directsequencecontrol->enerydetectthreshold));
json_object_object_add(jsonparent, "IEEE80211DirectSequenceControl", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_directsequencecontrol_ops = {
.type = CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL,
.json_type = "IEEE80211DirectSequenceControl",
.create_message_element = ac_json_80211_directsequencecontrol_createmessageelement,
.add_message_element = ac_json_80211_directsequencecontrol_addmessageelement,
.create_json = ac_json_80211_directsequencecontrol_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_DIRECTSEQUENCECONTROL_HEADER__
#define __AC_JSON_80211_DIRECTSEQUENCECONTROL_HEADER__
#include "capwap_element_80211_directsequencecontrol.h"
extern struct ac_json_ieee80211_ops ac_json_80211_directsequencecontrol_ops;
#endif /* __AC_JSON_80211_DIRECTSEQUENCECONTROL_HEADER__ */
#ifndef __AC_JSON_80211_DIRECTSEQUENCECONTROL_HEADER__
#define __AC_JSON_80211_DIRECTSEQUENCECONTROL_HEADER__
#include "capwap_element_80211_directsequencecontrol.h"
extern struct ac_json_ieee80211_ops ac_json_80211_directsequencecontrol_ops;
#endif /* __AC_JSON_80211_DIRECTSEQUENCECONTROL_HEADER__ */

View File

@ -1,39 +1,39 @@
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_ie_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_ie_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_ie_element** ieclone;
struct capwap_80211_ie_element* ie = (struct capwap_80211_ie_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[ie->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_IE);
if (!item->iearray) {
item->iearray = capwap_array_create(sizeof(struct capwap_80211_ie_element*), 0, 0);
}
item->valid = 1;
ieclone = (struct capwap_80211_ie_element**)capwap_array_get_item_pointer(item->iearray, item->iearray->count);
*ieclone = (struct capwap_80211_ie_element*)ops->clone_message_element(ie);
return 1;
}
/* */
static void ac_json_80211_ie_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_ie_ops = {
.type = CAPWAP_ELEMENT_80211_IE,
.json_type = "IEEE80211IE",
.create_message_element = ac_json_80211_ie_createmessageelement,
.add_message_element = ac_json_80211_ie_addmessageelement,
.create_json = ac_json_80211_ie_createjson
};
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_ie_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_ie_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_ie_element** ieclone;
struct capwap_80211_ie_element* ie = (struct capwap_80211_ie_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[ie->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_IE);
if (!item->iearray) {
item->iearray = capwap_array_create(sizeof(struct capwap_80211_ie_element*), 0, 0);
}
item->valid = 1;
ieclone = (struct capwap_80211_ie_element**)capwap_array_get_item_pointer(item->iearray, item->iearray->count);
*ieclone = (struct capwap_80211_ie_element*)ops->clone_message_element(ie);
return 1;
}
/* */
static void ac_json_80211_ie_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_ie_ops = {
.type = CAPWAP_ELEMENT_80211_IE,
.json_type = "IEEE80211IE",
.create_message_element = ac_json_80211_ie_createmessageelement,
.add_message_element = ac_json_80211_ie_addmessageelement,
.create_json = ac_json_80211_ie_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_IE_HEADER__
#define __AC_JSON_80211_IE_HEADER__
#include "capwap_element_80211_ie.h"
extern struct ac_json_ieee80211_ops ac_json_80211_ie_ops;
#endif /* __AC_JSON_80211_IE_HEADER__ */
#ifndef __AC_JSON_80211_IE_HEADER__
#define __AC_JSON_80211_IE_HEADER__
#include "capwap_element_80211_ie.h"
extern struct ac_json_ieee80211_ops ac_json_80211_ie_ops;
#endif /* __AC_JSON_80211_IE_HEADER__ */

View File

@ -1,118 +1,118 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211MACOperation: {
RTSThreshold: [int],
ShortRetry: [int],
LongRetry: [int],
FragmentationThreshold: [int],
TxMSDULifetime: [int],
RxMSDULifetime: [int]
}
*/
/* */
static void* ac_json_80211_macoperation_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_macoperation_element* macoperation;
macoperation = (struct capwap_80211_macoperation_element*)capwap_alloc(sizeof(struct capwap_80211_macoperation_element));
memset(macoperation, 0, sizeof(struct capwap_80211_macoperation_element));
macoperation->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "RTSThreshold");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
macoperation->rtsthreshold = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(macoperation);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "ShortRetry");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
macoperation->shortretry = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(macoperation);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "LongRetry");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
macoperation->longretry = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(macoperation);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "FragmentationThreshold");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
macoperation->fragthreshold = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(macoperation);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "TxMSDULifetime");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
macoperation->txmsdulifetime = (uint32_t)json_object_get_int(jsonitem);
} else {
capwap_free(macoperation);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "RxMSDULifetime");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
macoperation->rxmsdulifetime = (uint32_t)json_object_get_int(jsonitem);
} else {
capwap_free(macoperation);
return NULL;
}
return macoperation;
}
/* */
static int ac_json_80211_macoperation_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_macoperation_element* macoperation = (struct capwap_80211_macoperation_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[macoperation->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MACOPERATION);
if (item->macoperation) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->macoperation);
}
item->valid = 1;
item->macoperation = (struct capwap_80211_macoperation_element*)ops->clone_message_element(macoperation);
return 1;
}
/* */
static void ac_json_80211_macoperation_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_macoperation_element* macoperation = (struct capwap_80211_macoperation_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "RTSThreshold", json_object_new_int((int)macoperation->rtsthreshold));
json_object_object_add(jsonitem, "ShortRetry", json_object_new_int((int)macoperation->shortretry));
json_object_object_add(jsonitem, "LongRetry", json_object_new_int((int)macoperation->longretry));
json_object_object_add(jsonitem, "FragmentationThreshold", json_object_new_int((int)macoperation->fragthreshold));
json_object_object_add(jsonitem, "TxMSDULifetime", json_object_new_int((int)macoperation->txmsdulifetime));
json_object_object_add(jsonitem, "RxMSDULifetime", json_object_new_int((int)macoperation->rxmsdulifetime));
json_object_object_add(jsonparent, "IEEE80211MACOperation", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_macoperation_ops = {
.type = CAPWAP_ELEMENT_80211_MACOPERATION,
.json_type = "IEEE80211MACOperation",
.create_message_element = ac_json_80211_macoperation_createmessageelement,
.add_message_element = ac_json_80211_macoperation_addmessageelement,
.create_json = ac_json_80211_macoperation_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211MACOperation: {
RTSThreshold: [int],
ShortRetry: [int],
LongRetry: [int],
FragmentationThreshold: [int],
TxMSDULifetime: [int],
RxMSDULifetime: [int]
}
*/
/* */
static void* ac_json_80211_macoperation_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_macoperation_element* macoperation;
macoperation = (struct capwap_80211_macoperation_element*)capwap_alloc(sizeof(struct capwap_80211_macoperation_element));
memset(macoperation, 0, sizeof(struct capwap_80211_macoperation_element));
macoperation->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "RTSThreshold");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
macoperation->rtsthreshold = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(macoperation);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "ShortRetry");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
macoperation->shortretry = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(macoperation);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "LongRetry");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
macoperation->longretry = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(macoperation);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "FragmentationThreshold");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
macoperation->fragthreshold = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(macoperation);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "TxMSDULifetime");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
macoperation->txmsdulifetime = (uint32_t)json_object_get_int(jsonitem);
} else {
capwap_free(macoperation);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "RxMSDULifetime");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
macoperation->rxmsdulifetime = (uint32_t)json_object_get_int(jsonitem);
} else {
capwap_free(macoperation);
return NULL;
}
return macoperation;
}
/* */
static int ac_json_80211_macoperation_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_macoperation_element* macoperation = (struct capwap_80211_macoperation_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[macoperation->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MACOPERATION);
if (item->macoperation) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->macoperation);
}
item->valid = 1;
item->macoperation = (struct capwap_80211_macoperation_element*)ops->clone_message_element(macoperation);
return 1;
}
/* */
static void ac_json_80211_macoperation_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_macoperation_element* macoperation = (struct capwap_80211_macoperation_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "RTSThreshold", json_object_new_int((int)macoperation->rtsthreshold));
json_object_object_add(jsonitem, "ShortRetry", json_object_new_int((int)macoperation->shortretry));
json_object_object_add(jsonitem, "LongRetry", json_object_new_int((int)macoperation->longretry));
json_object_object_add(jsonitem, "FragmentationThreshold", json_object_new_int((int)macoperation->fragthreshold));
json_object_object_add(jsonitem, "TxMSDULifetime", json_object_new_int((int)macoperation->txmsdulifetime));
json_object_object_add(jsonitem, "RxMSDULifetime", json_object_new_int((int)macoperation->rxmsdulifetime));
json_object_object_add(jsonparent, "IEEE80211MACOperation", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_macoperation_ops = {
.type = CAPWAP_ELEMENT_80211_MACOPERATION,
.json_type = "IEEE80211MACOperation",
.create_message_element = ac_json_80211_macoperation_createmessageelement,
.add_message_element = ac_json_80211_macoperation_addmessageelement,
.create_json = ac_json_80211_macoperation_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_MACOPERATION_HEADER__
#define __AC_JSON_80211_MACOPERATION_HEADER__
#include "capwap_element_80211_macoperation.h"
extern struct ac_json_ieee80211_ops ac_json_80211_macoperation_ops;
#endif /* __AC_JSON_80211_MACOPERATION_HEADER__ */
#ifndef __AC_JSON_80211_MACOPERATION_HEADER__
#define __AC_JSON_80211_MACOPERATION_HEADER__
#include "capwap_element_80211_macoperation.h"
extern struct ac_json_ieee80211_ops ac_json_80211_macoperation_ops;
#endif /* __AC_JSON_80211_MACOPERATION_HEADER__ */

View File

@ -1,41 +1,41 @@
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_miccountermeasures_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_miccountermeasures_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_miccountermeasures_element* miccountermeasures = (struct capwap_80211_miccountermeasures_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[miccountermeasures->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES);
if (item->miccountermeasures) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->miccountermeasures);
}
item->valid = 1;
item->miccountermeasures = (struct capwap_80211_miccountermeasures_element*)ops->clone_message_element(miccountermeasures);
return 1;
}
/* */
static void ac_json_80211_miccountermeasures_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_miccountermeasures_ops = {
.type = CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES,
.json_type = "IEEE80211MicCounterMeasures",
.create_message_element = ac_json_80211_miccountermeasures_createmessageelement,
.add_message_element = ac_json_80211_miccountermeasures_addmessageelement,
.create_json = ac_json_80211_miccountermeasures_createjson
};
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_miccountermeasures_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_miccountermeasures_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_miccountermeasures_element* miccountermeasures = (struct capwap_80211_miccountermeasures_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[miccountermeasures->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES);
if (item->miccountermeasures) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->miccountermeasures);
}
item->valid = 1;
item->miccountermeasures = (struct capwap_80211_miccountermeasures_element*)ops->clone_message_element(miccountermeasures);
return 1;
}
/* */
static void ac_json_80211_miccountermeasures_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_miccountermeasures_ops = {
.type = CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES,
.json_type = "IEEE80211MicCounterMeasures",
.create_message_element = ac_json_80211_miccountermeasures_createmessageelement,
.add_message_element = ac_json_80211_miccountermeasures_addmessageelement,
.create_json = ac_json_80211_miccountermeasures_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_MICCOUNTERMEASURES_HEADER__
#define __AC_JSON_80211_MICCOUNTERMEASURES_HEADER__
#include "capwap_element_80211_miccountermeasures.h"
extern struct ac_json_ieee80211_ops ac_json_80211_miccountermeasures_ops;
#endif /* __AC_JSON_80211_MICCOUNTERMEASURES_HEADER__ */
#ifndef __AC_JSON_80211_MICCOUNTERMEASURES_HEADER__
#define __AC_JSON_80211_MICCOUNTERMEASURES_HEADER__
#include "capwap_element_80211_miccountermeasures.h"
extern struct ac_json_ieee80211_ops ac_json_80211_miccountermeasures_ops;
#endif /* __AC_JSON_80211_MICCOUNTERMEASURES_HEADER__ */

View File

@ -1,88 +1,88 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211MultiDomainCapability: {
FirstChannel: [int],
NumberChannels: [int],
MaxTxPowerLevel: [int]
}
*/
/* */
static void* ac_json_80211_multidomaincapability_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_multidomaincapability_element* multidomaincapability;
multidomaincapability = (struct capwap_80211_multidomaincapability_element*)capwap_alloc(sizeof(struct capwap_80211_multidomaincapability_element));
memset(multidomaincapability, 0, sizeof(struct capwap_80211_multidomaincapability_element));
multidomaincapability->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "FirstChannel");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
multidomaincapability->firstchannel = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(multidomaincapability);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "NumberChannels");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
multidomaincapability->numberchannels = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(multidomaincapability);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "MaxTxPowerLevel");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
multidomaincapability->maxtxpowerlevel = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(multidomaincapability);
return NULL;
}
return multidomaincapability;
}
/* */
static int ac_json_80211_multidomaincapability_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_multidomaincapability_element* multidomaincapability = (struct capwap_80211_multidomaincapability_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[multidomaincapability->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY);
if (item->multidomaincapability) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->multidomaincapability);
}
item->valid = 1;
item->multidomaincapability = (struct capwap_80211_multidomaincapability_element*)ops->clone_message_element(multidomaincapability);
return 1;
}
/* */
static void ac_json_80211_multidomaincapability_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_multidomaincapability_element* multidomaincapability = (struct capwap_80211_multidomaincapability_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "FirstChannel", json_object_new_int((int)multidomaincapability->firstchannel));
json_object_object_add(jsonitem, "NumberChannels", json_object_new_int((int)multidomaincapability->numberchannels));
json_object_object_add(jsonitem, "MaxTxPowerLevel", json_object_new_int((int)multidomaincapability->maxtxpowerlevel));
json_object_object_add(jsonparent, "IEEE80211MultiDomainCapability", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_multidomaincapability_ops = {
.type = CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY,
.json_type = "IEEE80211MultiDomainCapability",
.create_message_element = ac_json_80211_multidomaincapability_createmessageelement,
.add_message_element = ac_json_80211_multidomaincapability_addmessageelement,
.create_json = ac_json_80211_multidomaincapability_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211MultiDomainCapability: {
FirstChannel: [int],
NumberChannels: [int],
MaxTxPowerLevel: [int]
}
*/
/* */
static void* ac_json_80211_multidomaincapability_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_multidomaincapability_element* multidomaincapability;
multidomaincapability = (struct capwap_80211_multidomaincapability_element*)capwap_alloc(sizeof(struct capwap_80211_multidomaincapability_element));
memset(multidomaincapability, 0, sizeof(struct capwap_80211_multidomaincapability_element));
multidomaincapability->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "FirstChannel");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
multidomaincapability->firstchannel = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(multidomaincapability);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "NumberChannels");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
multidomaincapability->numberchannels = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(multidomaincapability);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "MaxTxPowerLevel");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
multidomaincapability->maxtxpowerlevel = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(multidomaincapability);
return NULL;
}
return multidomaincapability;
}
/* */
static int ac_json_80211_multidomaincapability_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_multidomaincapability_element* multidomaincapability = (struct capwap_80211_multidomaincapability_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[multidomaincapability->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY);
if (item->multidomaincapability) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->multidomaincapability);
}
item->valid = 1;
item->multidomaincapability = (struct capwap_80211_multidomaincapability_element*)ops->clone_message_element(multidomaincapability);
return 1;
}
/* */
static void ac_json_80211_multidomaincapability_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_multidomaincapability_element* multidomaincapability = (struct capwap_80211_multidomaincapability_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "FirstChannel", json_object_new_int((int)multidomaincapability->firstchannel));
json_object_object_add(jsonitem, "NumberChannels", json_object_new_int((int)multidomaincapability->numberchannels));
json_object_object_add(jsonitem, "MaxTxPowerLevel", json_object_new_int((int)multidomaincapability->maxtxpowerlevel));
json_object_object_add(jsonparent, "IEEE80211MultiDomainCapability", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_multidomaincapability_ops = {
.type = CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY,
.json_type = "IEEE80211MultiDomainCapability",
.create_message_element = ac_json_80211_multidomaincapability_createmessageelement,
.add_message_element = ac_json_80211_multidomaincapability_addmessageelement,
.create_json = ac_json_80211_multidomaincapability_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_MULTIDOMAINCAPABILITY_HEADER__
#define __AC_JSON_80211_MULTIDOMAINCAPABILITY_HEADER__
#include "capwap_element_80211_multidomaincapability.h"
extern struct ac_json_ieee80211_ops ac_json_80211_multidomaincapability_ops;
#endif /* __AC_JSON_80211_MULTIDOMAINCAPABILITY_HEADER__ */
#ifndef __AC_JSON_80211_MULTIDOMAINCAPABILITY_HEADER__
#define __AC_JSON_80211_MULTIDOMAINCAPABILITY_HEADER__
#include "capwap_element_80211_multidomaincapability.h"
extern struct ac_json_ieee80211_ops ac_json_80211_multidomaincapability_ops;
#endif /* __AC_JSON_80211_MULTIDOMAINCAPABILITY_HEADER__ */

View File

@ -1,88 +1,88 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211OFDMControl: {
CurrentChan: [int],
BandSupport: [int],
TIThreshold: [int]
}
*/
/* */
static void* ac_json_80211_ofdmcontrol_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_ofdmcontrol_element* ofdmcontrol;
ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)capwap_alloc(sizeof(struct capwap_80211_ofdmcontrol_element));
memset(ofdmcontrol, 0, sizeof(struct capwap_80211_ofdmcontrol_element));
ofdmcontrol->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "CurrentChan");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
ofdmcontrol->currentchannel = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(ofdmcontrol);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "BandSupport");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
ofdmcontrol->bandsupport = (uint8_t)json_object_get_int(jsonitem) & CAPWAP_OFDMCONTROL_BAND_MASK;
} else {
capwap_free(ofdmcontrol);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "TIThreshold");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
ofdmcontrol->tithreshold = (uint32_t)json_object_get_int(jsonitem);
} else {
capwap_free(ofdmcontrol);
return NULL;
}
return ofdmcontrol;
}
/* */
static int ac_json_80211_ofdmcontrol_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_ofdmcontrol_element* ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[ofdmcontrol->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_OFDMCONTROL);
if (item->ofdmcontrol) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->ofdmcontrol);
}
item->valid = 1;
item->ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)ops->clone_message_element(ofdmcontrol);
return 1;
}
/* */
static void ac_json_80211_ofdmcontrol_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_ofdmcontrol_element* ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "CurrentChan", json_object_new_int((int)ofdmcontrol->currentchannel));
json_object_object_add(jsonitem, "BandSupport", json_object_new_int((int)ofdmcontrol->bandsupport));
json_object_object_add(jsonitem, "TIThreshold", json_object_new_int((int)ofdmcontrol->tithreshold));
json_object_object_add(jsonparent, "IEEE80211OFDMControl", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_ofdmcontrol_ops = {
.type = CAPWAP_ELEMENT_80211_OFDMCONTROL,
.json_type = "IEEE80211OFDMControl",
.create_message_element = ac_json_80211_ofdmcontrol_createmessageelement,
.add_message_element = ac_json_80211_ofdmcontrol_addmessageelement,
.create_json = ac_json_80211_ofdmcontrol_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211OFDMControl: {
CurrentChan: [int],
BandSupport: [int],
TIThreshold: [int]
}
*/
/* */
static void* ac_json_80211_ofdmcontrol_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_ofdmcontrol_element* ofdmcontrol;
ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)capwap_alloc(sizeof(struct capwap_80211_ofdmcontrol_element));
memset(ofdmcontrol, 0, sizeof(struct capwap_80211_ofdmcontrol_element));
ofdmcontrol->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "CurrentChan");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
ofdmcontrol->currentchannel = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(ofdmcontrol);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "BandSupport");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
ofdmcontrol->bandsupport = (uint8_t)json_object_get_int(jsonitem) & CAPWAP_OFDMCONTROL_BAND_MASK;
} else {
capwap_free(ofdmcontrol);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "TIThreshold");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
ofdmcontrol->tithreshold = (uint32_t)json_object_get_int(jsonitem);
} else {
capwap_free(ofdmcontrol);
return NULL;
}
return ofdmcontrol;
}
/* */
static int ac_json_80211_ofdmcontrol_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_ofdmcontrol_element* ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[ofdmcontrol->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_OFDMCONTROL);
if (item->ofdmcontrol) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->ofdmcontrol);
}
item->valid = 1;
item->ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)ops->clone_message_element(ofdmcontrol);
return 1;
}
/* */
static void ac_json_80211_ofdmcontrol_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_ofdmcontrol_element* ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "CurrentChan", json_object_new_int((int)ofdmcontrol->currentchannel));
json_object_object_add(jsonitem, "BandSupport", json_object_new_int((int)ofdmcontrol->bandsupport));
json_object_object_add(jsonitem, "TIThreshold", json_object_new_int((int)ofdmcontrol->tithreshold));
json_object_object_add(jsonparent, "IEEE80211OFDMControl", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_ofdmcontrol_ops = {
.type = CAPWAP_ELEMENT_80211_OFDMCONTROL,
.json_type = "IEEE80211OFDMControl",
.create_message_element = ac_json_80211_ofdmcontrol_createmessageelement,
.add_message_element = ac_json_80211_ofdmcontrol_addmessageelement,
.create_json = ac_json_80211_ofdmcontrol_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_OFDMCONTROL_HEADER__
#define __AC_JSON_80211_OFDMCONTROL_HEADER__
#include "capwap_element_80211_ofdmcontrol.h"
extern struct ac_json_ieee80211_ops ac_json_80211_ofdmcontrol_ops;
#endif /* __AC_JSON_80211_OFDMCONTROL_HEADER__ */
#ifndef __AC_JSON_80211_OFDMCONTROL_HEADER__
#define __AC_JSON_80211_OFDMCONTROL_HEADER__
#include "capwap_element_80211_ofdmcontrol.h"
extern struct ac_json_ieee80211_ops ac_json_80211_ofdmcontrol_ops;
#endif /* __AC_JSON_80211_OFDMCONTROL_HEADER__ */

View File

@ -1,81 +1,81 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211Rateset: [
[int]
]
*/
/* */
static void* ac_json_80211_rateset_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
int i;
int length;
struct capwap_80211_rateset_element* rateset;
if (json_object_get_type(jsonparent) != json_type_array) {
return NULL;
}
length = json_object_array_length(jsonparent);
if ((length < CAPWAP_RATESET_MINLENGTH) || (length > CAPWAP_RATESET_MAXLENGTH)) {
return NULL;
}
rateset = (struct capwap_80211_rateset_element*)capwap_alloc(sizeof(struct capwap_80211_rateset_element));
memset(rateset, 0, sizeof(struct capwap_80211_rateset_element));
rateset->radioid = radioid;
for (i = 0; i < length; i++) {
struct json_object* jsonvalue = json_object_array_get_idx(jsonparent, i);
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
rateset->ratesetcount++;
rateset->rateset[i] = (uint8_t)json_object_get_int(jsonvalue);
}
}
return rateset;
}
/* */
static int ac_json_80211_rateset_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_rateset_element* rateset = (struct capwap_80211_rateset_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[rateset->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RATESET);
if (item->rateset) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->rateset);
}
item->valid = 1;
item->rateset = (struct capwap_80211_rateset_element*)ops->clone_message_element(rateset);
return 1;
}
/* */
static void ac_json_80211_rateset_createjson(struct json_object* jsonparent, void* data) {
int i;
struct json_object* jsonrates;
struct capwap_80211_rateset_element* rateset = (struct capwap_80211_rateset_element*)data;
jsonrates = json_object_new_array();
for (i = 0; i < rateset->ratesetcount; i++) {
json_object_array_add(jsonrates, json_object_new_int((int)rateset->rateset[i]));
}
json_object_object_add(jsonparent, "IEEE80211Rateset", jsonrates);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_rateset_ops = {
.type = CAPWAP_ELEMENT_80211_RATESET,
.json_type = "IEEE80211Rateset",
.create_message_element = ac_json_80211_rateset_createmessageelement,
.add_message_element = ac_json_80211_rateset_addmessageelement,
.create_json = ac_json_80211_rateset_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211Rateset: [
[int]
]
*/
/* */
static void* ac_json_80211_rateset_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
int i;
int length;
struct capwap_80211_rateset_element* rateset;
if (json_object_get_type(jsonparent) != json_type_array) {
return NULL;
}
length = json_object_array_length(jsonparent);
if ((length < CAPWAP_RATESET_MINLENGTH) || (length > CAPWAP_RATESET_MAXLENGTH)) {
return NULL;
}
rateset = (struct capwap_80211_rateset_element*)capwap_alloc(sizeof(struct capwap_80211_rateset_element));
memset(rateset, 0, sizeof(struct capwap_80211_rateset_element));
rateset->radioid = radioid;
for (i = 0; i < length; i++) {
struct json_object* jsonvalue = json_object_array_get_idx(jsonparent, i);
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
rateset->ratesetcount++;
rateset->rateset[i] = (uint8_t)json_object_get_int(jsonvalue);
}
}
return rateset;
}
/* */
static int ac_json_80211_rateset_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_rateset_element* rateset = (struct capwap_80211_rateset_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[rateset->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RATESET);
if (item->rateset) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->rateset);
}
item->valid = 1;
item->rateset = (struct capwap_80211_rateset_element*)ops->clone_message_element(rateset);
return 1;
}
/* */
static void ac_json_80211_rateset_createjson(struct json_object* jsonparent, void* data) {
int i;
struct json_object* jsonrates;
struct capwap_80211_rateset_element* rateset = (struct capwap_80211_rateset_element*)data;
jsonrates = json_object_new_array();
for (i = 0; i < rateset->ratesetcount; i++) {
json_object_array_add(jsonrates, json_object_new_int((int)rateset->rateset[i]));
}
json_object_object_add(jsonparent, "IEEE80211Rateset", jsonrates);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_rateset_ops = {
.type = CAPWAP_ELEMENT_80211_RATESET,
.json_type = "IEEE80211Rateset",
.create_message_element = ac_json_80211_rateset_createmessageelement,
.add_message_element = ac_json_80211_rateset_addmessageelement,
.create_json = ac_json_80211_rateset_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_RATESET_HEADER__
#define __AC_JSON_80211_RATESET_HEADER__
#include "capwap_element_80211_rateset.h"
extern struct ac_json_ieee80211_ops ac_json_80211_rateset_ops;
#endif /* __AC_JSON_80211_RATESET_HEADER__ */
#ifndef __AC_JSON_80211_RATESET_HEADER__
#define __AC_JSON_80211_RATESET_HEADER__
#include "capwap_element_80211_rateset.h"
extern struct ac_json_ieee80211_ops ac_json_80211_rateset_ops;
#endif /* __AC_JSON_80211_RATESET_HEADER__ */

View File

@ -1,41 +1,41 @@
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_rsnaerrorreport_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_rsnaerrorreport_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_rsnaerrorreport_element* rsnaerrorreport = (struct capwap_80211_rsnaerrorreport_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[rsnaerrorreport->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT);
if (item->rsnaerrorreport) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->rsnaerrorreport);
}
item->valid = 1;
item->rsnaerrorreport = (struct capwap_80211_rsnaerrorreport_element*)ops->clone_message_element(rsnaerrorreport);
return 1;
}
/* */
static void ac_json_80211_rsnaerrorreport_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_rsnaerrorreport_ops = {
.type = CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT,
.json_type = "IEEE80211RSNAErrorReport",
.create_message_element = ac_json_80211_rsnaerrorreport_createmessageelement,
.add_message_element = ac_json_80211_rsnaerrorreport_addmessageelement,
.create_json = ac_json_80211_rsnaerrorreport_createjson
};
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_rsnaerrorreport_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_rsnaerrorreport_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_rsnaerrorreport_element* rsnaerrorreport = (struct capwap_80211_rsnaerrorreport_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[rsnaerrorreport->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT);
if (item->rsnaerrorreport) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->rsnaerrorreport);
}
item->valid = 1;
item->rsnaerrorreport = (struct capwap_80211_rsnaerrorreport_element*)ops->clone_message_element(rsnaerrorreport);
return 1;
}
/* */
static void ac_json_80211_rsnaerrorreport_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_rsnaerrorreport_ops = {
.type = CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT,
.json_type = "IEEE80211RSNAErrorReport",
.create_message_element = ac_json_80211_rsnaerrorreport_createmessageelement,
.add_message_element = ac_json_80211_rsnaerrorreport_addmessageelement,
.create_json = ac_json_80211_rsnaerrorreport_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_RSNAERRORREPORT_HEADER__
#define __AC_JSON_80211_RSNAERRORREPORT_HEADER__
#include "capwap_element_80211_rsnaerrorreport.h"
extern struct ac_json_ieee80211_ops ac_json_80211_rsnaerrorreport_ops;
#endif /* __AC_JSON_80211_RSNAERRORREPORT_HEADER__ */
#ifndef __AC_JSON_80211_RSNAERRORREPORT_HEADER__
#define __AC_JSON_80211_RSNAERRORREPORT_HEADER__
#include "capwap_element_80211_rsnaerrorreport.h"
extern struct ac_json_ieee80211_ops ac_json_80211_rsnaerrorreport_ops;
#endif /* __AC_JSON_80211_RSNAERRORREPORT_HEADER__ */

View File

@ -1,41 +1,41 @@
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_statistics_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_statistics_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_statistics_element* statistics = (struct capwap_80211_statistics_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[statistics->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_STATISTICS);
if (item->statistics) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->statistics);
}
item->valid = 1;
item->statistics = (struct capwap_80211_statistics_element*)ops->clone_message_element(statistics);
return 1;
}
/* */
static void ac_json_80211_statistics_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_statistics_ops = {
.type = CAPWAP_ELEMENT_80211_STATISTICS,
.json_type = "IEEE80211Statistics",
.create_message_element = ac_json_80211_statistics_createmessageelement,
.add_message_element = ac_json_80211_statistics_addmessageelement,
.create_json = ac_json_80211_statistics_createjson
};
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_statistics_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_statistics_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_statistics_element* statistics = (struct capwap_80211_statistics_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[statistics->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_STATISTICS);
if (item->statistics) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->statistics);
}
item->valid = 1;
item->statistics = (struct capwap_80211_statistics_element*)ops->clone_message_element(statistics);
return 1;
}
/* */
static void ac_json_80211_statistics_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_statistics_ops = {
.type = CAPWAP_ELEMENT_80211_STATISTICS,
.json_type = "IEEE80211Statistics",
.create_message_element = ac_json_80211_statistics_createmessageelement,
.add_message_element = ac_json_80211_statistics_addmessageelement,
.create_json = ac_json_80211_statistics_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_STATISTICS_HEADER__
#define __AC_JSON_80211_STATISTICS_HEADER__
#include "capwap_element_80211_statistics.h"
extern struct ac_json_ieee80211_ops ac_json_80211_statistics_ops;
#endif /* __AC_JSON_80211_STATISTICS_HEADER__ */
#ifndef __AC_JSON_80211_STATISTICS_HEADER__
#define __AC_JSON_80211_STATISTICS_HEADER__
#include "capwap_element_80211_statistics.h"
extern struct ac_json_ieee80211_ops ac_json_80211_statistics_ops;
#endif /* __AC_JSON_80211_STATISTICS_HEADER__ */

View File

@ -1,81 +1,81 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211SupportedRates: [
[int]
]
*/
/* */
static void* ac_json_80211_supportedrates_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
int i;
int length;
struct capwap_80211_supportedrates_element* supportedrates;
if (json_object_get_type(jsonparent) != json_type_array) {
return NULL;
}
length = json_object_array_length(jsonparent);
if ((length < CAPWAP_SUPPORTEDRATES_MINLENGTH) || (length > CAPWAP_SUPPORTEDRATES_MAXLENGTH)) {
return NULL;
}
supportedrates = (struct capwap_80211_supportedrates_element*)capwap_alloc(sizeof(struct capwap_80211_supportedrates_element));
memset(supportedrates, 0, sizeof(struct capwap_80211_supportedrates_element));
supportedrates->radioid = radioid;
for (i = 0; i < length; i++) {
struct json_object* jsonvalue = json_object_array_get_idx(jsonparent, i);
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
supportedrates->supportedratescount++;
supportedrates->supportedrates[i] = (uint8_t)json_object_get_int(jsonvalue);
}
}
return supportedrates;
}
/* */
static int ac_json_80211_supportedrates_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_supportedrates_element* supportedrates = (struct capwap_80211_supportedrates_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[supportedrates->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_SUPPORTEDRATES);
if (item->supportedrates) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->supportedrates);
}
item->valid = 1;
item->supportedrates = (struct capwap_80211_supportedrates_element*)ops->clone_message_element(supportedrates);
return 1;
}
/* */
static void ac_json_80211_supportedrates_createjson(struct json_object* jsonparent, void* data) {
int i;
struct json_object* jsonrates;
struct capwap_80211_supportedrates_element* supportedrates = (struct capwap_80211_supportedrates_element*)data;
jsonrates = json_object_new_array();
for (i = 0; i < supportedrates->supportedratescount; i++) {
json_object_array_add(jsonrates, json_object_new_int((int)supportedrates->supportedrates[i]));
}
json_object_object_add(jsonparent, "IEEE80211SupportedRates", jsonrates);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_supportedrates_ops = {
.type = CAPWAP_ELEMENT_80211_SUPPORTEDRATES,
.json_type = "IEEE80211SupportedRates",
.create_message_element = ac_json_80211_supportedrates_createmessageelement,
.add_message_element = ac_json_80211_supportedrates_addmessageelement,
.create_json = ac_json_80211_supportedrates_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211SupportedRates: [
[int]
]
*/
/* */
static void* ac_json_80211_supportedrates_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
int i;
int length;
struct capwap_80211_supportedrates_element* supportedrates;
if (json_object_get_type(jsonparent) != json_type_array) {
return NULL;
}
length = json_object_array_length(jsonparent);
if ((length < CAPWAP_SUPPORTEDRATES_MINLENGTH) || (length > CAPWAP_SUPPORTEDRATES_MAXLENGTH)) {
return NULL;
}
supportedrates = (struct capwap_80211_supportedrates_element*)capwap_alloc(sizeof(struct capwap_80211_supportedrates_element));
memset(supportedrates, 0, sizeof(struct capwap_80211_supportedrates_element));
supportedrates->radioid = radioid;
for (i = 0; i < length; i++) {
struct json_object* jsonvalue = json_object_array_get_idx(jsonparent, i);
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
supportedrates->supportedratescount++;
supportedrates->supportedrates[i] = (uint8_t)json_object_get_int(jsonvalue);
}
}
return supportedrates;
}
/* */
static int ac_json_80211_supportedrates_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_supportedrates_element* supportedrates = (struct capwap_80211_supportedrates_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[supportedrates->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_SUPPORTEDRATES);
if (item->supportedrates) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->supportedrates);
}
item->valid = 1;
item->supportedrates = (struct capwap_80211_supportedrates_element*)ops->clone_message_element(supportedrates);
return 1;
}
/* */
static void ac_json_80211_supportedrates_createjson(struct json_object* jsonparent, void* data) {
int i;
struct json_object* jsonrates;
struct capwap_80211_supportedrates_element* supportedrates = (struct capwap_80211_supportedrates_element*)data;
jsonrates = json_object_new_array();
for (i = 0; i < supportedrates->supportedratescount; i++) {
json_object_array_add(jsonrates, json_object_new_int((int)supportedrates->supportedrates[i]));
}
json_object_object_add(jsonparent, "IEEE80211SupportedRates", jsonrates);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_supportedrates_ops = {
.type = CAPWAP_ELEMENT_80211_SUPPORTEDRATES,
.json_type = "IEEE80211SupportedRates",
.create_message_element = ac_json_80211_supportedrates_createmessageelement,
.add_message_element = ac_json_80211_supportedrates_addmessageelement,
.create_json = ac_json_80211_supportedrates_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_SUPPORTEDRATES_HEADER__
#define __AC_JSON_80211_SUPPORTEDRATES_HEADER__
#include "capwap_element_80211_supportedrates.h"
extern struct ac_json_ieee80211_ops ac_json_80211_supportedrates_ops;
#endif /* __AC_JSON_80211_SUPPORTEDRATES_HEADER__ */
#ifndef __AC_JSON_80211_SUPPORTEDRATES_HEADER__
#define __AC_JSON_80211_SUPPORTEDRATES_HEADER__
#include "capwap_element_80211_supportedrates.h"
extern struct ac_json_ieee80211_ops ac_json_80211_supportedrates_ops;
#endif /* __AC_JSON_80211_SUPPORTEDRATES_HEADER__ */

View File

@ -1,68 +1,68 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211TxPower: {
CurrentTxPower: [int]
}
*/
/* */
static void* ac_json_80211_txpower_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_txpower_element* txpower;
txpower = (struct capwap_80211_txpower_element*)capwap_alloc(sizeof(struct capwap_80211_txpower_element));
memset(txpower, 0, sizeof(struct capwap_80211_txpower_element));
txpower->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "CurrentTxPower");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
txpower->currenttxpower = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(txpower);
return NULL;
}
return txpower;
}
/* */
static int ac_json_80211_txpower_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_txpower_element* txpower = (struct capwap_80211_txpower_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[txpower->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWER);
if (item->txpower) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->txpower);
}
item->valid = 1;
item->txpower = (struct capwap_80211_txpower_element*)ops->clone_message_element(txpower);
return 1;
}
/* */
static void ac_json_80211_txpower_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_txpower_element* txpower = (struct capwap_80211_txpower_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "CurrentTxPower", json_object_new_int((int)txpower->currenttxpower));
json_object_object_add(jsonparent, "IEEE80211TxPower", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_txpower_ops = {
.type = CAPWAP_ELEMENT_80211_TXPOWER,
.json_type = "IEEE80211TxPower",
.create_message_element = ac_json_80211_txpower_createmessageelement,
.add_message_element = ac_json_80211_txpower_addmessageelement,
.create_json = ac_json_80211_txpower_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211TxPower: {
CurrentTxPower: [int]
}
*/
/* */
static void* ac_json_80211_txpower_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_txpower_element* txpower;
txpower = (struct capwap_80211_txpower_element*)capwap_alloc(sizeof(struct capwap_80211_txpower_element));
memset(txpower, 0, sizeof(struct capwap_80211_txpower_element));
txpower->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "CurrentTxPower");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
txpower->currenttxpower = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(txpower);
return NULL;
}
return txpower;
}
/* */
static int ac_json_80211_txpower_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_txpower_element* txpower = (struct capwap_80211_txpower_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[txpower->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWER);
if (item->txpower) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->txpower);
}
item->valid = 1;
item->txpower = (struct capwap_80211_txpower_element*)ops->clone_message_element(txpower);
return 1;
}
/* */
static void ac_json_80211_txpower_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_txpower_element* txpower = (struct capwap_80211_txpower_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "CurrentTxPower", json_object_new_int((int)txpower->currenttxpower));
json_object_object_add(jsonparent, "IEEE80211TxPower", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_txpower_ops = {
.type = CAPWAP_ELEMENT_80211_TXPOWER,
.json_type = "IEEE80211TxPower",
.create_message_element = ac_json_80211_txpower_createmessageelement,
.add_message_element = ac_json_80211_txpower_addmessageelement,
.create_json = ac_json_80211_txpower_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_TXPOWER_HEADER__
#define __AC_JSON_80211_TXPOWER_HEADER__
#include "capwap_element_80211_txpower.h"
extern struct ac_json_ieee80211_ops ac_json_80211_txpower_ops;
#endif /* __AC_JSON_80211_TXPOWER_HEADER__ */
#ifndef __AC_JSON_80211_TXPOWER_HEADER__
#define __AC_JSON_80211_TXPOWER_HEADER__
#include "capwap_element_80211_txpower.h"
extern struct ac_json_ieee80211_ops ac_json_80211_txpower_ops;
#endif /* __AC_JSON_80211_TXPOWER_HEADER__ */

View File

@ -1,81 +1,81 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211TXPowerLevel: [
[int]
]
*/
/* */
static void* ac_json_80211_txpowerlevel_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
int i;
int length;
struct capwap_80211_txpowerlevel_element* txpowerlevel;
if (json_object_get_type(jsonparent) != json_type_array) {
return NULL;
}
length = json_object_array_length(jsonparent);
if (length > CAPWAP_TXPOWERLEVEL_MAXLENGTH) {
return NULL;
}
txpowerlevel = (struct capwap_80211_txpowerlevel_element*)capwap_alloc(sizeof(struct capwap_80211_txpowerlevel_element));
memset(txpowerlevel, 0, sizeof(struct capwap_80211_txpowerlevel_element));
txpowerlevel->radioid = radioid;
for (i = 0; i < length; i++) {
struct json_object* jsonvalue = json_object_array_get_idx(jsonparent, i);
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
txpowerlevel->numlevels++;
txpowerlevel->powerlevel[i] = (uint16_t)json_object_get_int(jsonvalue);
}
}
return txpowerlevel;
}
/* */
static int ac_json_80211_txpowerlevel_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_txpowerlevel_element* txpowerlevel = (struct capwap_80211_txpowerlevel_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[txpowerlevel->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWERLEVEL);
if (item->txpowerlevel) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->txpowerlevel);
}
item->valid = 1;
item->txpowerlevel = (struct capwap_80211_txpowerlevel_element*)ops->clone_message_element(txpowerlevel);
return 1;
}
/* */
static void ac_json_80211_txpowerlevel_createjson(struct json_object* jsonparent, void* data) {
int i;
struct json_object* jsontxpower;
struct capwap_80211_txpowerlevel_element* txpowerlevel = (struct capwap_80211_txpowerlevel_element*)data;
jsontxpower = json_object_new_array();
for (i = 0; i < txpowerlevel->numlevels; i++) {
json_object_array_add(jsontxpower, json_object_new_int((int)txpowerlevel->powerlevel[i]));
}
json_object_object_add(jsonparent, "IEEE80211TXPowerLevel", jsontxpower);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_txpowerlevel_ops = {
.type = CAPWAP_ELEMENT_80211_TXPOWERLEVEL,
.json_type = "IEEE80211TXPowerLevel",
.create_message_element = ac_json_80211_txpowerlevel_createmessageelement,
.add_message_element = ac_json_80211_txpowerlevel_addmessageelement,
.create_json = ac_json_80211_txpowerlevel_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211TXPowerLevel: [
[int]
]
*/
/* */
static void* ac_json_80211_txpowerlevel_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
int i;
int length;
struct capwap_80211_txpowerlevel_element* txpowerlevel;
if (json_object_get_type(jsonparent) != json_type_array) {
return NULL;
}
length = json_object_array_length(jsonparent);
if (length > CAPWAP_TXPOWERLEVEL_MAXLENGTH) {
return NULL;
}
txpowerlevel = (struct capwap_80211_txpowerlevel_element*)capwap_alloc(sizeof(struct capwap_80211_txpowerlevel_element));
memset(txpowerlevel, 0, sizeof(struct capwap_80211_txpowerlevel_element));
txpowerlevel->radioid = radioid;
for (i = 0; i < length; i++) {
struct json_object* jsonvalue = json_object_array_get_idx(jsonparent, i);
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
txpowerlevel->numlevels++;
txpowerlevel->powerlevel[i] = (uint16_t)json_object_get_int(jsonvalue);
}
}
return txpowerlevel;
}
/* */
static int ac_json_80211_txpowerlevel_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_txpowerlevel_element* txpowerlevel = (struct capwap_80211_txpowerlevel_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[txpowerlevel->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWERLEVEL);
if (item->txpowerlevel) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->txpowerlevel);
}
item->valid = 1;
item->txpowerlevel = (struct capwap_80211_txpowerlevel_element*)ops->clone_message_element(txpowerlevel);
return 1;
}
/* */
static void ac_json_80211_txpowerlevel_createjson(struct json_object* jsonparent, void* data) {
int i;
struct json_object* jsontxpower;
struct capwap_80211_txpowerlevel_element* txpowerlevel = (struct capwap_80211_txpowerlevel_element*)data;
jsontxpower = json_object_new_array();
for (i = 0; i < txpowerlevel->numlevels; i++) {
json_object_array_add(jsontxpower, json_object_new_int((int)txpowerlevel->powerlevel[i]));
}
json_object_object_add(jsonparent, "IEEE80211TXPowerLevel", jsontxpower);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_txpowerlevel_ops = {
.type = CAPWAP_ELEMENT_80211_TXPOWERLEVEL,
.json_type = "IEEE80211TXPowerLevel",
.create_message_element = ac_json_80211_txpowerlevel_createmessageelement,
.add_message_element = ac_json_80211_txpowerlevel_addmessageelement,
.create_json = ac_json_80211_txpowerlevel_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_TXPOWERLEVEL_HEADER__
#define __AC_JSON_80211_TXPOWERLEVEL_HEADER__
#include "capwap_element_80211_txpowerlevel.h"
extern struct ac_json_ieee80211_ops ac_json_80211_txpowerlevel_ops;
#endif /* __AC_JSON_80211_TXPOWERLEVEL_HEADER__ */
#ifndef __AC_JSON_80211_TXPOWERLEVEL_HEADER__
#define __AC_JSON_80211_TXPOWERLEVEL_HEADER__
#include "capwap_element_80211_txpowerlevel.h"
extern struct ac_json_ieee80211_ops ac_json_80211_txpowerlevel_ops;
#endif /* __AC_JSON_80211_TXPOWERLEVEL_HEADER__ */

View File

@ -1,41 +1,41 @@
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_updatewlan_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_updatewlan_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_updatewlan_element* updatewlan = (struct capwap_80211_updatewlan_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[updatewlan->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_UPDATE_WLAN);
if (item->updatewlan) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->updatewlan);
}
item->valid = 1;
item->updatewlan = (struct capwap_80211_updatewlan_element*)ops->clone_message_element(updatewlan);
return 1;
}
/* */
static void ac_json_80211_updatewlan_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_updatewlan_ops = {
.type = CAPWAP_ELEMENT_80211_UPDATE_WLAN,
.json_type = "IEEE80211UpdateWLAN",
.create_message_element = ac_json_80211_updatewlan_createmessageelement,
.add_message_element = ac_json_80211_updatewlan_addmessageelement,
.create_json = ac_json_80211_updatewlan_createjson
};
#include "ac.h"
#include "ac_json.h"
/* */
static void* ac_json_80211_updatewlan_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_updatewlan_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_updatewlan_element* updatewlan = (struct capwap_80211_updatewlan_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[updatewlan->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_UPDATE_WLAN);
if (item->updatewlan) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->updatewlan);
}
item->valid = 1;
item->updatewlan = (struct capwap_80211_updatewlan_element*)ops->clone_message_element(updatewlan);
return 1;
}
/* */
static void ac_json_80211_updatewlan_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_updatewlan_ops = {
.type = CAPWAP_ELEMENT_80211_UPDATE_WLAN,
.json_type = "IEEE80211UpdateWLAN",
.create_message_element = ac_json_80211_updatewlan_createmessageelement,
.add_message_element = ac_json_80211_updatewlan_addmessageelement,
.create_json = ac_json_80211_updatewlan_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_UPDATEWLAN_HEADER__
#define __AC_JSON_80211_UPDATEWLAN_HEADER__
#include "capwap_element_80211_updatewlan.h"
extern struct ac_json_ieee80211_ops ac_json_80211_updatewlan_ops;
#endif /* __AC_JSON_80211_UPDATEWLAN_HEADER__ */
#ifndef __AC_JSON_80211_UPDATEWLAN_HEADER__
#define __AC_JSON_80211_UPDATEWLAN_HEADER__
#include "capwap_element_80211_updatewlan.h"
extern struct ac_json_ieee80211_ops ac_json_80211_updatewlan_ops;
#endif /* __AC_JSON_80211_UPDATEWLAN_HEADER__ */

View File

@ -1,79 +1,79 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211WTPQoS: {
TaggingPolicy: [int],
Voice: {
QueueDepth: [int],
CWMin: [int],
CWMax: [int],
AIFS: [int],
Priority8021p: [int],
DSCP: [int]
}
Video: {
QueueDepth: [int],
CWMin: [int],
CWMax: [int],
AIFS: [int],
Priority8021p: [int],
DSCP: [int]
}
BestEffort: {
QueueDepth: [int],
CWMin: [int],
CWMax: [int],
AIFS: [int],
Priority8021p: [int],
DSCP: [int]
}
Background: {
QueueDepth: [int],
CWMin: [int],
CWMax: [int],
AIFS: [int],
Priority8021p: [int],
DSCP: [int]
}
}
*/
/* */
static void* ac_json_80211_wtpqos_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_wtpqos_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_wtpqos_element* wtpqos = (struct capwap_80211_wtpqos_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpqos->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_QOS);
if (item->wtpqos) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->wtpqos);
}
item->valid = 1;
item->wtpqos = (struct capwap_80211_wtpqos_element*)ops->clone_message_element(wtpqos);
return 1;
}
/* */
static void ac_json_80211_wtpqos_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_wtpqos_ops = {
.type = CAPWAP_ELEMENT_80211_WTP_QOS,
.json_type = "IEEE80211WTPQoS",
.create_message_element = ac_json_80211_wtpqos_createmessageelement,
.add_message_element = ac_json_80211_wtpqos_addmessageelement,
.create_json = ac_json_80211_wtpqos_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211WTPQoS: {
TaggingPolicy: [int],
Voice: {
QueueDepth: [int],
CWMin: [int],
CWMax: [int],
AIFS: [int],
Priority8021p: [int],
DSCP: [int]
}
Video: {
QueueDepth: [int],
CWMin: [int],
CWMax: [int],
AIFS: [int],
Priority8021p: [int],
DSCP: [int]
}
BestEffort: {
QueueDepth: [int],
CWMin: [int],
CWMax: [int],
AIFS: [int],
Priority8021p: [int],
DSCP: [int]
}
Background: {
QueueDepth: [int],
CWMin: [int],
CWMax: [int],
AIFS: [int],
Priority8021p: [int],
DSCP: [int]
}
}
*/
/* */
static void* ac_json_80211_wtpqos_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
return NULL; /* TODO */
}
/* */
static int ac_json_80211_wtpqos_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_wtpqos_element* wtpqos = (struct capwap_80211_wtpqos_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpqos->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_QOS);
if (item->wtpqos) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->wtpqos);
}
item->valid = 1;
item->wtpqos = (struct capwap_80211_wtpqos_element*)ops->clone_message_element(wtpqos);
return 1;
}
/* */
static void ac_json_80211_wtpqos_createjson(struct json_object* jsonparent, void* data) {
/* TODO */
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_wtpqos_ops = {
.type = CAPWAP_ELEMENT_80211_WTP_QOS,
.json_type = "IEEE80211WTPQoS",
.create_message_element = ac_json_80211_wtpqos_createmessageelement,
.add_message_element = ac_json_80211_wtpqos_addmessageelement,
.create_json = ac_json_80211_wtpqos_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_WTPQOS_HEADER__
#define __AC_JSON_80211_WTPQOS_HEADER__
#include "capwap_element_80211_wtpqos.h"
extern struct ac_json_ieee80211_ops ac_json_80211_wtpqos_ops;
#endif /* __AC_JSON_80211_WTPQOS_HEADER__ */
#ifndef __AC_JSON_80211_WTPQOS_HEADER__
#define __AC_JSON_80211_WTPQOS_HEADER__
#include "capwap_element_80211_wtpqos.h"
extern struct ac_json_ieee80211_ops ac_json_80211_wtpqos_ops;
#endif /* __AC_JSON_80211_WTPQOS_HEADER__ */

View File

@ -1,128 +1,128 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211WTPRadioConfiguration: {
ShortPreamble: [int],
NumBSSIDs: [int],
DTIMPeriod: [int],
BSSID: [string],
BeaconPeriod: [int],
CountryString: [string]
}
*/
/* */
static void* ac_json_80211_wtpradioconf_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_wtpradioconf_element* wtpradioconf;
wtpradioconf = (struct capwap_80211_wtpradioconf_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradioconf_element));
memset(wtpradioconf, 0, sizeof(struct capwap_80211_wtpradioconf_element));
wtpradioconf->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "ShortPreamble");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradioconf->shortpreamble = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(wtpradioconf);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "NumBSSIDs");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradioconf->maxbssid = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(wtpradioconf);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "DTIMPeriod");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradioconf->dtimperiod = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(wtpradioconf);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "BSSID");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
if (!capwap_scanf_macaddress((unsigned char*)wtpradioconf->bssid, json_object_get_string(jsonitem), MACADDRESS_EUI48_LENGTH)) {
capwap_free(wtpradioconf);
return NULL;
}
} else {
capwap_free(wtpradioconf);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "BeaconPeriod");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradioconf->beaconperiod = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(wtpradioconf);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "CountryString");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
const char* country = json_object_get_string(jsonitem);
if (strlen(country) == (CAPWAP_WTP_RADIO_CONF_COUNTRY_LENGTH - 1)) {
strcpy((char*)wtpradioconf->country, country);
} else {
capwap_free(wtpradioconf);
return NULL;
}
} else {
capwap_free(wtpradioconf);
return NULL;
}
return wtpradioconf;
}
/* */
static int ac_json_80211_wtpradioconf_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_wtpradioconf_element* wtpradioconf = (struct capwap_80211_wtpradioconf_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpradioconf->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_CONF);
if (item->wtpradioconf) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->wtpradioconf);
}
item->valid = 1;
item->wtpradioconf = (struct capwap_80211_wtpradioconf_element*)ops->clone_message_element(wtpradioconf);
return 1;
}
/* */
static void ac_json_80211_wtpradioconf_createjson(struct json_object* jsonparent, void* data) {
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
struct json_object* jsonitem;
struct capwap_80211_wtpradioconf_element* wtpradioconf = (struct capwap_80211_wtpradioconf_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "ShortPreamble", json_object_new_int((int)wtpradioconf->shortpreamble));
json_object_object_add(jsonitem, "NumBSSIDs", json_object_new_int((int)wtpradioconf->maxbssid));
json_object_object_add(jsonitem, "DTIMPeriod", json_object_new_int((int)wtpradioconf->dtimperiod));
json_object_object_add(jsonitem, "BSSID", json_object_new_string(capwap_printf_macaddress(buffer, wtpradioconf->bssid, MACADDRESS_EUI48_LENGTH)));
json_object_object_add(jsonitem, "BeaconPeriod", json_object_new_int((int)wtpradioconf->beaconperiod));
json_object_object_add(jsonitem, "CountryString", json_object_new_string((char*)wtpradioconf->country));
json_object_object_add(jsonparent, "IEEE80211WTPRadioConfiguration", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_wtpradioconf_ops = {
.type = CAPWAP_ELEMENT_80211_WTP_RADIO_CONF,
.json_type = "IEEE80211WTPRadioConfiguration",
.create_message_element = ac_json_80211_wtpradioconf_createmessageelement,
.add_message_element = ac_json_80211_wtpradioconf_addmessageelement,
.create_json = ac_json_80211_wtpradioconf_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211WTPRadioConfiguration: {
ShortPreamble: [int],
NumBSSIDs: [int],
DTIMPeriod: [int],
BSSID: [string],
BeaconPeriod: [int],
CountryString: [string]
}
*/
/* */
static void* ac_json_80211_wtpradioconf_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_wtpradioconf_element* wtpradioconf;
wtpradioconf = (struct capwap_80211_wtpradioconf_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradioconf_element));
memset(wtpradioconf, 0, sizeof(struct capwap_80211_wtpradioconf_element));
wtpradioconf->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "ShortPreamble");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradioconf->shortpreamble = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(wtpradioconf);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "NumBSSIDs");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradioconf->maxbssid = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(wtpradioconf);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "DTIMPeriod");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradioconf->dtimperiod = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(wtpradioconf);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "BSSID");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
if (!capwap_scanf_macaddress((unsigned char*)wtpradioconf->bssid, json_object_get_string(jsonitem), MACADDRESS_EUI48_LENGTH)) {
capwap_free(wtpradioconf);
return NULL;
}
} else {
capwap_free(wtpradioconf);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "BeaconPeriod");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradioconf->beaconperiod = (uint16_t)json_object_get_int(jsonitem);
} else {
capwap_free(wtpradioconf);
return NULL;
}
jsonitem = compat_json_object_object_get(jsonparent, "CountryString");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
const char* country = json_object_get_string(jsonitem);
if (strlen(country) == (CAPWAP_WTP_RADIO_CONF_COUNTRY_LENGTH - 1)) {
strcpy((char*)wtpradioconf->country, country);
} else {
capwap_free(wtpradioconf);
return NULL;
}
} else {
capwap_free(wtpradioconf);
return NULL;
}
return wtpradioconf;
}
/* */
static int ac_json_80211_wtpradioconf_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_wtpradioconf_element* wtpradioconf = (struct capwap_80211_wtpradioconf_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpradioconf->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_CONF);
if (item->wtpradioconf) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->wtpradioconf);
}
item->valid = 1;
item->wtpradioconf = (struct capwap_80211_wtpradioconf_element*)ops->clone_message_element(wtpradioconf);
return 1;
}
/* */
static void ac_json_80211_wtpradioconf_createjson(struct json_object* jsonparent, void* data) {
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
struct json_object* jsonitem;
struct capwap_80211_wtpradioconf_element* wtpradioconf = (struct capwap_80211_wtpradioconf_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "ShortPreamble", json_object_new_int((int)wtpradioconf->shortpreamble));
json_object_object_add(jsonitem, "NumBSSIDs", json_object_new_int((int)wtpradioconf->maxbssid));
json_object_object_add(jsonitem, "DTIMPeriod", json_object_new_int((int)wtpradioconf->dtimperiod));
json_object_object_add(jsonitem, "BSSID", json_object_new_string(capwap_printf_macaddress(buffer, wtpradioconf->bssid, MACADDRESS_EUI48_LENGTH)));
json_object_object_add(jsonitem, "BeaconPeriod", json_object_new_int((int)wtpradioconf->beaconperiod));
json_object_object_add(jsonitem, "CountryString", json_object_new_string((char*)wtpradioconf->country));
json_object_object_add(jsonparent, "IEEE80211WTPRadioConfiguration", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_wtpradioconf_ops = {
.type = CAPWAP_ELEMENT_80211_WTP_RADIO_CONF,
.json_type = "IEEE80211WTPRadioConfiguration",
.create_message_element = ac_json_80211_wtpradioconf_createmessageelement,
.add_message_element = ac_json_80211_wtpradioconf_addmessageelement,
.create_json = ac_json_80211_wtpradioconf_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_WTPRADIOCONF_HEADER__
#define __AC_JSON_80211_WTPRADIOCONF_HEADER__
#include "capwap_element_80211_wtpradioconf.h"
extern struct ac_json_ieee80211_ops ac_json_80211_wtpradioconf_ops;
#endif /* __AC_JSON_80211_WTPRADIOCONF_HEADER__ */
#ifndef __AC_JSON_80211_WTPRADIOCONF_HEADER__
#define __AC_JSON_80211_WTPRADIOCONF_HEADER__
#include "capwap_element_80211_wtpradioconf.h"
extern struct ac_json_ieee80211_ops ac_json_80211_wtpradioconf_ops;
#endif /* __AC_JSON_80211_WTPRADIOCONF_HEADER__ */

View File

@ -1,79 +1,79 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211WTPRadioFailAlarm: {
Type: [int],
Status: [int]
}
*/
/* */
static void* ac_json_80211_wtpradiofailalarm_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm;
wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradiofailalarm_element));
memset(wtpradiofailalarm, 0, sizeof(struct capwap_80211_wtpradiofailalarm_element));
wtpradiofailalarm->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "Type");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradiofailalarm->type = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(wtpradiofailalarm);
return NULL;
}
/* */
jsonitem = compat_json_object_object_get(jsonparent, "Status");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradiofailalarm->status = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(wtpradiofailalarm);
return NULL;
}
return wtpradiofailalarm;
}
/* */
static int ac_json_80211_wtpradiofailalarm_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpradiofailalarm->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM);
if (item->wtpradiofailalarm) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->wtpradiofailalarm);
}
item->valid = 1;
item->wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)ops->clone_message_element(wtpradiofailalarm);
return 1;
}
/* */
static void ac_json_80211_wtpradiofailalarm_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "Type", json_object_new_int((int)wtpradiofailalarm->type));
json_object_object_add(jsonitem, "Status", json_object_new_int((int)wtpradiofailalarm->status));
json_object_object_add(jsonparent, "IEEE80211WTPRadioFailAlarm", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_wtpradiofailalarm_ops = {
.type = CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM,
.json_type = "IEEE80211WTPRadioFailAlarm",
.create_message_element = ac_json_80211_wtpradiofailalarm_createmessageelement,
.add_message_element = ac_json_80211_wtpradiofailalarm_addmessageelement,
.create_json = ac_json_80211_wtpradiofailalarm_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211WTPRadioFailAlarm: {
Type: [int],
Status: [int]
}
*/
/* */
static void* ac_json_80211_wtpradiofailalarm_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm;
wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradiofailalarm_element));
memset(wtpradiofailalarm, 0, sizeof(struct capwap_80211_wtpradiofailalarm_element));
wtpradiofailalarm->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "Type");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradiofailalarm->type = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(wtpradiofailalarm);
return NULL;
}
/* */
jsonitem = compat_json_object_object_get(jsonparent, "Status");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradiofailalarm->status = (uint8_t)json_object_get_int(jsonitem);
} else {
capwap_free(wtpradiofailalarm);
return NULL;
}
return wtpradiofailalarm;
}
/* */
static int ac_json_80211_wtpradiofailalarm_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpradiofailalarm->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM);
if (item->wtpradiofailalarm) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->wtpradiofailalarm);
}
item->valid = 1;
item->wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)ops->clone_message_element(wtpradiofailalarm);
return 1;
}
/* */
static void ac_json_80211_wtpradiofailalarm_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "Type", json_object_new_int((int)wtpradiofailalarm->type));
json_object_object_add(jsonitem, "Status", json_object_new_int((int)wtpradiofailalarm->status));
json_object_object_add(jsonparent, "IEEE80211WTPRadioFailAlarm", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_wtpradiofailalarm_ops = {
.type = CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM,
.json_type = "IEEE80211WTPRadioFailAlarm",
.create_message_element = ac_json_80211_wtpradiofailalarm_createmessageelement,
.add_message_element = ac_json_80211_wtpradiofailalarm_addmessageelement,
.create_json = ac_json_80211_wtpradiofailalarm_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_WTPRADIOFAILALARM_HEADER__
#define __AC_JSON_80211_WTPRADIOFAILALARM_HEADER__
#include "capwap_element_80211_wtpradiofailalarm.h"
extern struct ac_json_ieee80211_ops ac_json_80211_wtpradiofailalarm_ops;
#endif /* __AC_JSON_80211_WTPRADIOFAILALARM_HEADER__ */
#ifndef __AC_JSON_80211_WTPRADIOFAILALARM_HEADER__
#define __AC_JSON_80211_WTPRADIOFAILALARM_HEADER__
#include "capwap_element_80211_wtpradiofailalarm.h"
extern struct ac_json_ieee80211_ops ac_json_80211_wtpradiofailalarm_ops;
#endif /* __AC_JSON_80211_WTPRADIOFAILALARM_HEADER__ */

View File

@ -1,68 +1,68 @@
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211WTPRadioInformation: {
Mode: [int]
}
*/
/* */
static void* ac_json_80211_wtpradioinformation_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_wtpradioinformation_element* wtpradioinformation;
wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradioinformation_element));
memset(wtpradioinformation, 0, sizeof(struct capwap_80211_wtpradioinformation_element));
wtpradioinformation->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "Mode");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradioinformation->radiotype = (uint32_t)json_object_get_int(jsonitem) & CAPWAP_RADIO_TYPE_MASK;
} else {
capwap_free(wtpradioinformation);
return NULL;
}
return wtpradioinformation;
}
/* */
static int ac_json_80211_wtpradioinformation_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_wtpradioinformation_element* wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpradioinformation->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION);
if (item->wtpradioinformation) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->wtpradioinformation);
}
item->valid = 1;
item->wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)ops->clone_message_element(wtpradioinformation);
return 1;
}
/* */
static void ac_json_80211_wtpradioinformation_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_wtpradioinformation_element* wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "Mode", json_object_new_int((int)wtpradioinformation->radiotype));
json_object_object_add(jsonparent, "IEEE80211WTPRadioInformation", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_wtpradioinformation_ops = {
.type = CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION,
.json_type = "IEEE80211WTPRadioInformation",
.create_message_element = ac_json_80211_wtpradioinformation_createmessageelement,
.add_message_element = ac_json_80211_wtpradioinformation_addmessageelement,
.create_json = ac_json_80211_wtpradioinformation_createjson
};
#include "ac.h"
#include "ac_json.h"
/*
IEEE80211WTPRadioInformation: {
Mode: [int]
}
*/
/* */
static void* ac_json_80211_wtpradioinformation_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
struct json_object* jsonitem;
struct capwap_80211_wtpradioinformation_element* wtpradioinformation;
wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradioinformation_element));
memset(wtpradioinformation, 0, sizeof(struct capwap_80211_wtpradioinformation_element));
wtpradioinformation->radioid = radioid;
/* */
jsonitem = compat_json_object_object_get(jsonparent, "Mode");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
wtpradioinformation->radiotype = (uint32_t)json_object_get_int(jsonitem) & CAPWAP_RADIO_TYPE_MASK;
} else {
capwap_free(wtpradioinformation);
return NULL;
}
return wtpradioinformation;
}
/* */
static int ac_json_80211_wtpradioinformation_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
struct capwap_80211_wtpradioinformation_element* wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)data;
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpradioinformation->radioid - 1];
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION);
if (item->wtpradioinformation) {
if (!overwrite) {
return 0;
}
ops->free_message_element(item->wtpradioinformation);
}
item->valid = 1;
item->wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)ops->clone_message_element(wtpradioinformation);
return 1;
}
/* */
static void ac_json_80211_wtpradioinformation_createjson(struct json_object* jsonparent, void* data) {
struct json_object* jsonitem;
struct capwap_80211_wtpradioinformation_element* wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)data;
jsonitem = json_object_new_object();
json_object_object_add(jsonitem, "Mode", json_object_new_int((int)wtpradioinformation->radiotype));
json_object_object_add(jsonparent, "IEEE80211WTPRadioInformation", jsonitem);
}
/* */
struct ac_json_ieee80211_ops ac_json_80211_wtpradioinformation_ops = {
.type = CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION,
.json_type = "IEEE80211WTPRadioInformation",
.create_message_element = ac_json_80211_wtpradioinformation_createmessageelement,
.add_message_element = ac_json_80211_wtpradioinformation_addmessageelement,
.create_json = ac_json_80211_wtpradioinformation_createjson
};

View File

@ -1,8 +1,8 @@
#ifndef __AC_JSON_80211_WTPRADIOINFORMATION_HEADER__
#define __AC_JSON_80211_WTPRADIOINFORMATION_HEADER__
#include "capwap_element_80211_wtpradioinformation.h"
extern struct ac_json_ieee80211_ops ac_json_80211_wtpradioinformation_ops;
#endif /* __AC_JSON_80211_WTPRADIOINFORMATION_HEADER__ */
#ifndef __AC_JSON_80211_WTPRADIOINFORMATION_HEADER__
#define __AC_JSON_80211_WTPRADIOINFORMATION_HEADER__
#include "capwap_element_80211_wtpradioinformation.h"
extern struct ac_json_ieee80211_ops ac_json_80211_wtpradioinformation_ops;
#endif /* __AC_JSON_80211_WTPRADIOINFORMATION_HEADER__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,22 @@
#ifndef __AC_BACKEND_HEADER__
#define __AC_BACKEND_HEADER__
/* */
#define SOAP_NAMESPACE_URI "http://smartcapwap/namespace"
/* SOAP event status*/
#define SOAP_EVENT_STATUS_GENERIC_ERROR -1
#define SOAP_EVENT_STATUS_CANCEL -2
#define SOAP_EVENT_STATUS_RUNNING 0
#define SOAP_EVENT_STATUS_COMPLETE 1
/* */
int ac_backend_start(void);
void ac_backend_stop(void);
void ac_backend_free(void);
/* */
int ac_backend_isconnect(void);
struct ac_http_soap_request* ac_backend_createrequest_with_session(char* method, char* uri);
#endif /* __AC_BACKEND_HEADER__ */
#ifndef __AC_BACKEND_HEADER__
#define __AC_BACKEND_HEADER__
/* */
#define SOAP_NAMESPACE_URI "http://smartcapwap/namespace"
/* SOAP event status*/
#define SOAP_EVENT_STATUS_GENERIC_ERROR -1
#define SOAP_EVENT_STATUS_CANCEL -2
#define SOAP_EVENT_STATUS_RUNNING 0
#define SOAP_EVENT_STATUS_COMPLETE 1
/* */
int ac_backend_start(void);
void ac_backend_stop(void);
void ac_backend_free(void);
/* */
int ac_backend_isconnect(void);
struct ac_http_soap_request* ac_backend_createrequest_with_session(char* method, char* uri);
#endif /* __AC_BACKEND_HEADER__ */

View File

@ -1,459 +1,459 @@
#include "ac.h"
#include "ac_session.h"
#include "ac_wlans.h"
/* */
static void ac_ieee80211_mgmt_probe_request_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
/* Accept probe request only if not sent by WTP */
if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH)) {
return;
}
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) {
return;
}
/* TODO */
}
/* */
static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
struct ac_station* station;
struct ac_wlan* wlan;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->authetication.ie[0], ielength)) {
return;
}
/* */
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && !memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
station = ac_stations_create_station(session, radioid, mgmt->bssid, mgmt->sa);
if (!station || !station->wlan) {
return;
}
/* */
capwap_logging_info("Receive IEEE802.11 Authentication Request from %s station", station->addrtext);
/* A station is removed if the association does not complete within a given period of time */
station->timeoutaction = AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE;
station->idtimeout = capwap_timeout_set(session->timeout, station->idtimeout, AC_STATION_TIMEOUT_ASSOCIATION_COMPLETE, ac_stations_timeout, station, session);
/* */
wlan = station->wlan;
if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
/* TODO */
} else if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
uint16_t algorithm;
uint16_t transactionseqnumber;
uint16_t responsestatuscode;
uint8_t buffer[IEEE80211_MTU];
struct ieee80211_authentication_params ieee80211_params;
int responselength;
/* Parsing Information Elements */
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->authetication.ie[0], ielength)) {
capwap_logging_info("Invalid IEEE802.11 Authentication Request from %s station", station->addrtext);
return;
}
/* */
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
/* */
responsestatuscode = IEEE80211_STATUS_NOT_SUPPORTED_AUTHENTICATION_ALGORITHM;
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (wlan->authmode == CAPWAP_ADD_WLAN_AUTHTYPE_OPEN)) {
if (transactionseqnumber == 1) {
responsestatuscode = IEEE80211_STATUS_SUCCESS;
station->authalgorithm = IEEE80211_AUTHENTICATION_ALGORITHM_OPEN;
} else {
responsestatuscode = IEEE80211_STATUS_UNKNOWN_AUTHENTICATION_TRANSACTION;
}
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (wlan->authmode == CAPWAP_ADD_WLAN_AUTHTYPE_WEP)) {
/* TODO */
}
/* Create authentication packet */
memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params));
memcpy(ieee80211_params.bssid, wlan->address, MACADDRESS_EUI48_LENGTH);
memcpy(ieee80211_params.station, mgmt->sa, MACADDRESS_EUI48_LENGTH);
ieee80211_params.algorithm = algorithm;
ieee80211_params.transactionseqnumber = transactionseqnumber + 1;
ieee80211_params.statuscode = responsestatuscode;
responselength = ieee80211_create_authentication_response(buffer, sizeof(buffer), &ieee80211_params);
if (responselength > 0) {
/* Send authentication response */
if (!ac_kmod_send_data(&session->sessionid, wlan->device->radioid, session->binding, buffer, responselength)) {
capwap_logging_info("Sent IEEE802.11 Authentication Response to %s station with %d status code", station->addrtext, (int)responsestatuscode);
station->flags |= AC_STATION_FLAGS_AUTHENTICATED;
} else {
capwap_logging_warning("Unable to send IEEE802.11 Authentication Response to %s station", station->addrtext);
ac_stations_delete_station(session, station);
}
} else {
capwap_logging_warning("Unable to create IEEE802.11 Authentication Response to %s station", station->addrtext);
ac_stations_delete_station(session, station);
}
}
} else if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->da);
if (station && station->wlan && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
uint16_t algorithm;
uint16_t transactionseqnumber;
uint16_t statuscode;
/* */
statuscode = __le16_to_cpu(mgmt->authetication.statuscode);
/* */
capwap_logging_info("Receive IEEE802.11 Authentication Response to %s station with %d status code", station->addrtext, (int)statuscode);
if (statuscode == IEEE80211_STATUS_SUCCESS) {
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
/* Check if authenticate */
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (transactionseqnumber == 2)) {
station->flags |= AC_STATION_FLAGS_AUTHENTICATED;
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (transactionseqnumber == 4)) {
/* TODO */
}
}
}
}
}
/* */
static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
struct ac_station* station;
struct ac_wlan* wlan;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationrequest));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationrequest.ie[0], ielength)) {
return;
}
/* Get station */
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && !memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->sa);
if (!station || !station->wlan) {
return;
}
/* */
capwap_logging_info("Receive IEEE802.11 Association Request from %s station", station->addrtext);
/* */
wlan = station->wlan;
if (!(station->flags & AC_STATION_FLAGS_AUTHENTICATED)) {
/* Invalid station, delete station */
capwap_logging_info("Receive IEEE802.11 Association Request from %s unauthorized station", station->addrtext);
ac_stations_delete_station(session, station);
return;
}
/* Get Station Info */
station->capability = __le16_to_cpu(mgmt->associationrequest.capability);
station->listeninterval = __le16_to_cpu(mgmt->associationrequest.listeninterval);
/* Get supported rates */
if (ieitems.supported_rates && ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) <= sizeof(station->supportedrates))) {
station->supportedratescount = ieitems.supported_rates->len;
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
if (ieitems.extended_supported_rates) {
station->supportedratescount += ieitems.extended_supported_rates->len;
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
}
/* */
if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
/* TODO */
} else if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
int responselength;
struct ieee80211_ie_items ieitems;
struct ieee80211_associationresponse_params ieee80211_params;
uint16_t resultstatuscode;
uint8_t buffer[IEEE80211_MTU];
/* Parsing Information Elements */
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationrequest.ie[0], ielength)) {
capwap_logging_info("Invalid IEEE802.11 Association Request from %s station", station->addrtext);
ac_stations_delete_station(session, station);
return;
}
/* Verify SSID */
if (ieee80211_is_valid_ssid(wlan->ssid, ieitems.ssid, NULL) != IEEE80211_VALID_SSID) {
resultstatuscode = IEEE80211_STATUS_UNSPECIFIED_FAILURE;
} else {
/* Check supported rates */
if (!ieitems.supported_rates || ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) > sizeof(station->supportedrates))) {
resultstatuscode = IEEE80211_STATUS_UNSPECIFIED_FAILURE;
} else {
station->capability = __le16_to_cpu(mgmt->associationrequest.capability);
station->listeninterval = __le16_to_cpu(mgmt->associationrequest.listeninterval);
if (ieee80211_aid_create(wlan->aidbitfield, &station->aid)) {
resultstatuscode = IEEE80211_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
} else {
/* Get supported rates */
station->supportedratescount = ieitems.supported_rates->len;
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
if (ieitems.extended_supported_rates) {
station->supportedratescount += ieitems.extended_supported_rates->len;
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
}
/* */
resultstatuscode = IEEE80211_STATUS_SUCCESS;
}
}
}
/* Create association response packet */
memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params));
memcpy(ieee80211_params.bssid, wlan->address, ETH_ALEN);
memcpy(ieee80211_params.station, mgmt->sa, ETH_ALEN);
ieee80211_params.capability = wlan->capability;
ieee80211_params.statuscode = resultstatuscode;
ieee80211_params.aid = IEEE80211_AID_FIELD | station->aid;
memcpy(ieee80211_params.supportedrates, wlan->device->supportedrates, wlan->device->supportedratescount);
ieee80211_params.supportedratescount = wlan->device->supportedratescount;
responselength = ieee80211_create_associationresponse_response(buffer, sizeof(buffer), &ieee80211_params);
if (responselength > 0) {
/* Send association response */
if (!ac_kmod_send_data(&session->sessionid, wlan->device->radioid, session->binding, buffer, responselength)) {
capwap_logging_info("Sent IEEE802.11 Association Response to %s station with %d status code", station->addrtext, (int)resultstatuscode);
/* Active Station */
station->flags |= AC_STATION_FLAGS_ASSOCIATE;
ac_stations_authorize_station(session, station);
} else {
capwap_logging_warning("Unable to send IEEE802.11 Association Response to %s station", station->addrtext);
ac_stations_delete_station(session, station);
}
} else {
capwap_logging_warning("Unable to create IEEE802.11 Association Response to %s station", station->addrtext);
ac_stations_delete_station(session, station);
}
}
}
}
}
/* */
static void ac_ieee80211_mgmt_association_response_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
struct ac_station* station;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationresponse));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationresponse.ie[0], ielength)) {
return;
}
/* Get station */
if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->da);
if (station && station->wlan && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
capwap_logging_info("Receive IEEE802.11 Association Response to %s station with %d status code", station->addrtext, (int)mgmt->associationresponse.statuscode);
if (mgmt->associationresponse.statuscode == IEEE80211_STATUS_SUCCESS) {
/* Get Station Info */
station->capability = __le16_to_cpu(mgmt->associationresponse.capability);
station->aid = __le16_to_cpu(mgmt->associationresponse.aid);
station->flags |= AC_STATION_FLAGS_ASSOCIATE;
/* Get supported rates */
if (ieitems.supported_rates && ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) <= sizeof(station->supportedrates))) {
station->supportedratescount = ieitems.supported_rates->len;
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
if (ieitems.extended_supported_rates) {
station->supportedratescount += ieitems.extended_supported_rates->len;
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
}
/* Active Station */
ac_stations_authorize_station(session, station);
}
}
}
}
}
/* */
static void ac_ieee80211_mgmt_reassociation_request_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationrequest));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->reassociationrequest.ie[0], ielength)) {
return;
}
/* TODO */
}
/* */
static void ac_ieee80211_mgmt_reassociation_response_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationresponse));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->reassociationresponse.ie[0], ielength)) {
return;
}
/* TODO */
}
/* */
static void ac_ieee80211_mgmt_disassociation_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->disassociation));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->disassociation.ie[0], ielength)) {
return;
}
/* TODO */
}
/* */
static void ac_ieee80211_mgmt_deauthentication_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
const uint8_t* stationaddress;
struct ac_station* station;
struct ieee80211_ie_items ieitems;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->deauthetication));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->deauthetication.ie[0], ielength)) {
return;
}
/* Get station address */
stationaddress = (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) ? mgmt->sa : mgmt->da);
/* Delete station */
station = ac_stations_get_station(session, radioid, NULL, stationaddress);
if (station) {
/* Delete station without forward another IEEE802.11 deauthentication message */
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE);
ac_stations_delete_station(session, station);
}
}
/* */
static void ac_ieee80211_mgmt_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, uint16_t framecontrol_subtype) {
switch (framecontrol_subtype) {
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_REQUEST: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest))) {
ac_ieee80211_mgmt_probe_request_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTHENTICATION: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication))) {
ac_ieee80211_mgmt_authentication_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_REQUEST: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->associationrequest))) {
ac_ieee80211_mgmt_association_request_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_RESPONSE: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->associationresponse))) {
ac_ieee80211_mgmt_association_response_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_REQUEST: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationrequest))) {
ac_ieee80211_mgmt_reassociation_request_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_RESPONSE: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationresponse))) {
ac_ieee80211_mgmt_reassociation_response_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOCIATION: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->disassociation))) {
ac_ieee80211_mgmt_disassociation_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DEAUTHENTICATION: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->deauthetication))) {
ac_ieee80211_mgmt_deauthentication_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ACTION: {
break;
}
}
}
/* */
void ac_ieee80211_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header* header, int length) {
uint16_t framecontrol;
uint16_t framecontrol_type;
uint16_t framecontrol_subtype;
ASSERT(session != NULL);
ASSERT(IS_VALID_RADIOID(radioid));
ASSERT(header != NULL);
ASSERT(length >= sizeof(struct ieee80211_header));
/* Get type frame */
framecontrol = __le16_to_cpu(header->framecontrol);
framecontrol_type = IEEE80211_FRAME_CONTROL_GET_TYPE(framecontrol);
framecontrol_subtype = IEEE80211_FRAME_CONTROL_GET_SUBTYPE(framecontrol);
/* Parsing frame */
if (framecontrol_type == IEEE80211_FRAMECONTROL_TYPE_MGMT) {
ac_ieee80211_mgmt_packet(session, radioid, (const struct ieee80211_header_mgmt*)header, length, framecontrol_subtype);
}
}
#include "ac.h"
#include "ac_session.h"
#include "ac_wlans.h"
/* */
static void ac_ieee80211_mgmt_probe_request_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
/* Accept probe request only if not sent by WTP */
if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH)) {
return;
}
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) {
return;
}
/* TODO */
}
/* */
static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
struct ac_station* station;
struct ac_wlan* wlan;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->authetication.ie[0], ielength)) {
return;
}
/* */
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && !memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
station = ac_stations_create_station(session, radioid, mgmt->bssid, mgmt->sa);
if (!station || !station->wlan) {
return;
}
/* */
capwap_logging_info("Receive IEEE802.11 Authentication Request from %s station", station->addrtext);
/* A station is removed if the association does not complete within a given period of time */
station->timeoutaction = AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE;
station->idtimeout = capwap_timeout_set(session->timeout, station->idtimeout, AC_STATION_TIMEOUT_ASSOCIATION_COMPLETE, ac_stations_timeout, station, session);
/* */
wlan = station->wlan;
if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
/* TODO */
} else if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
uint16_t algorithm;
uint16_t transactionseqnumber;
uint16_t responsestatuscode;
uint8_t buffer[IEEE80211_MTU];
struct ieee80211_authentication_params ieee80211_params;
int responselength;
/* Parsing Information Elements */
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->authetication.ie[0], ielength)) {
capwap_logging_info("Invalid IEEE802.11 Authentication Request from %s station", station->addrtext);
return;
}
/* */
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
/* */
responsestatuscode = IEEE80211_STATUS_NOT_SUPPORTED_AUTHENTICATION_ALGORITHM;
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (wlan->authmode == CAPWAP_ADD_WLAN_AUTHTYPE_OPEN)) {
if (transactionseqnumber == 1) {
responsestatuscode = IEEE80211_STATUS_SUCCESS;
station->authalgorithm = IEEE80211_AUTHENTICATION_ALGORITHM_OPEN;
} else {
responsestatuscode = IEEE80211_STATUS_UNKNOWN_AUTHENTICATION_TRANSACTION;
}
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (wlan->authmode == CAPWAP_ADD_WLAN_AUTHTYPE_WEP)) {
/* TODO */
}
/* Create authentication packet */
memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params));
memcpy(ieee80211_params.bssid, wlan->address, MACADDRESS_EUI48_LENGTH);
memcpy(ieee80211_params.station, mgmt->sa, MACADDRESS_EUI48_LENGTH);
ieee80211_params.algorithm = algorithm;
ieee80211_params.transactionseqnumber = transactionseqnumber + 1;
ieee80211_params.statuscode = responsestatuscode;
responselength = ieee80211_create_authentication_response(buffer, sizeof(buffer), &ieee80211_params);
if (responselength > 0) {
/* Send authentication response */
if (!ac_kmod_send_data(&session->sessionid, wlan->device->radioid, session->binding, buffer, responselength)) {
capwap_logging_info("Sent IEEE802.11 Authentication Response to %s station with %d status code", station->addrtext, (int)responsestatuscode);
station->flags |= AC_STATION_FLAGS_AUTHENTICATED;
} else {
capwap_logging_warning("Unable to send IEEE802.11 Authentication Response to %s station", station->addrtext);
ac_stations_delete_station(session, station);
}
} else {
capwap_logging_warning("Unable to create IEEE802.11 Authentication Response to %s station", station->addrtext);
ac_stations_delete_station(session, station);
}
}
} else if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->da);
if (station && station->wlan && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
uint16_t algorithm;
uint16_t transactionseqnumber;
uint16_t statuscode;
/* */
statuscode = __le16_to_cpu(mgmt->authetication.statuscode);
/* */
capwap_logging_info("Receive IEEE802.11 Authentication Response to %s station with %d status code", station->addrtext, (int)statuscode);
if (statuscode == IEEE80211_STATUS_SUCCESS) {
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
/* Check if authenticate */
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (transactionseqnumber == 2)) {
station->flags |= AC_STATION_FLAGS_AUTHENTICATED;
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (transactionseqnumber == 4)) {
/* TODO */
}
}
}
}
}
/* */
static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
struct ac_station* station;
struct ac_wlan* wlan;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationrequest));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationrequest.ie[0], ielength)) {
return;
}
/* Get station */
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && !memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->sa);
if (!station || !station->wlan) {
return;
}
/* */
capwap_logging_info("Receive IEEE802.11 Association Request from %s station", station->addrtext);
/* */
wlan = station->wlan;
if (!(station->flags & AC_STATION_FLAGS_AUTHENTICATED)) {
/* Invalid station, delete station */
capwap_logging_info("Receive IEEE802.11 Association Request from %s unauthorized station", station->addrtext);
ac_stations_delete_station(session, station);
return;
}
/* Get Station Info */
station->capability = __le16_to_cpu(mgmt->associationrequest.capability);
station->listeninterval = __le16_to_cpu(mgmt->associationrequest.listeninterval);
/* Get supported rates */
if (ieitems.supported_rates && ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) <= sizeof(station->supportedrates))) {
station->supportedratescount = ieitems.supported_rates->len;
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
if (ieitems.extended_supported_rates) {
station->supportedratescount += ieitems.extended_supported_rates->len;
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
}
/* */
if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
/* TODO */
} else if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
int responselength;
struct ieee80211_ie_items ieitems;
struct ieee80211_associationresponse_params ieee80211_params;
uint16_t resultstatuscode;
uint8_t buffer[IEEE80211_MTU];
/* Parsing Information Elements */
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationrequest.ie[0], ielength)) {
capwap_logging_info("Invalid IEEE802.11 Association Request from %s station", station->addrtext);
ac_stations_delete_station(session, station);
return;
}
/* Verify SSID */
if (ieee80211_is_valid_ssid(wlan->ssid, ieitems.ssid, NULL) != IEEE80211_VALID_SSID) {
resultstatuscode = IEEE80211_STATUS_UNSPECIFIED_FAILURE;
} else {
/* Check supported rates */
if (!ieitems.supported_rates || ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) > sizeof(station->supportedrates))) {
resultstatuscode = IEEE80211_STATUS_UNSPECIFIED_FAILURE;
} else {
station->capability = __le16_to_cpu(mgmt->associationrequest.capability);
station->listeninterval = __le16_to_cpu(mgmt->associationrequest.listeninterval);
if (ieee80211_aid_create(wlan->aidbitfield, &station->aid)) {
resultstatuscode = IEEE80211_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
} else {
/* Get supported rates */
station->supportedratescount = ieitems.supported_rates->len;
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
if (ieitems.extended_supported_rates) {
station->supportedratescount += ieitems.extended_supported_rates->len;
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
}
/* */
resultstatuscode = IEEE80211_STATUS_SUCCESS;
}
}
}
/* Create association response packet */
memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params));
memcpy(ieee80211_params.bssid, wlan->address, ETH_ALEN);
memcpy(ieee80211_params.station, mgmt->sa, ETH_ALEN);
ieee80211_params.capability = wlan->capability;
ieee80211_params.statuscode = resultstatuscode;
ieee80211_params.aid = IEEE80211_AID_FIELD | station->aid;
memcpy(ieee80211_params.supportedrates, wlan->device->supportedrates, wlan->device->supportedratescount);
ieee80211_params.supportedratescount = wlan->device->supportedratescount;
responselength = ieee80211_create_associationresponse_response(buffer, sizeof(buffer), &ieee80211_params);
if (responselength > 0) {
/* Send association response */
if (!ac_kmod_send_data(&session->sessionid, wlan->device->radioid, session->binding, buffer, responselength)) {
capwap_logging_info("Sent IEEE802.11 Association Response to %s station with %d status code", station->addrtext, (int)resultstatuscode);
/* Active Station */
station->flags |= AC_STATION_FLAGS_ASSOCIATE;
ac_stations_authorize_station(session, station);
} else {
capwap_logging_warning("Unable to send IEEE802.11 Association Response to %s station", station->addrtext);
ac_stations_delete_station(session, station);
}
} else {
capwap_logging_warning("Unable to create IEEE802.11 Association Response to %s station", station->addrtext);
ac_stations_delete_station(session, station);
}
}
}
}
}
/* */
static void ac_ieee80211_mgmt_association_response_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
struct ac_station* station;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationresponse));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationresponse.ie[0], ielength)) {
return;
}
/* Get station */
if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->da);
if (station && station->wlan && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
capwap_logging_info("Receive IEEE802.11 Association Response to %s station with %d status code", station->addrtext, (int)mgmt->associationresponse.statuscode);
if (mgmt->associationresponse.statuscode == IEEE80211_STATUS_SUCCESS) {
/* Get Station Info */
station->capability = __le16_to_cpu(mgmt->associationresponse.capability);
station->aid = __le16_to_cpu(mgmt->associationresponse.aid);
station->flags |= AC_STATION_FLAGS_ASSOCIATE;
/* Get supported rates */
if (ieitems.supported_rates && ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) <= sizeof(station->supportedrates))) {
station->supportedratescount = ieitems.supported_rates->len;
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
if (ieitems.extended_supported_rates) {
station->supportedratescount += ieitems.extended_supported_rates->len;
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
}
/* Active Station */
ac_stations_authorize_station(session, station);
}
}
}
}
}
/* */
static void ac_ieee80211_mgmt_reassociation_request_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationrequest));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->reassociationrequest.ie[0], ielength)) {
return;
}
/* TODO */
}
/* */
static void ac_ieee80211_mgmt_reassociation_response_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationresponse));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->reassociationresponse.ie[0], ielength)) {
return;
}
/* TODO */
}
/* */
static void ac_ieee80211_mgmt_disassociation_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->disassociation));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->disassociation.ie[0], ielength)) {
return;
}
/* TODO */
}
/* */
static void ac_ieee80211_mgmt_deauthentication_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
const uint8_t* stationaddress;
struct ac_station* station;
struct ieee80211_ie_items ieitems;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->deauthetication));
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->deauthetication.ie[0], ielength)) {
return;
}
/* Get station address */
stationaddress = (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) ? mgmt->sa : mgmt->da);
/* Delete station */
station = ac_stations_get_station(session, radioid, NULL, stationaddress);
if (station) {
/* Delete station without forward another IEEE802.11 deauthentication message */
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE);
ac_stations_delete_station(session, station);
}
}
/* */
static void ac_ieee80211_mgmt_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, uint16_t framecontrol_subtype) {
switch (framecontrol_subtype) {
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_REQUEST: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest))) {
ac_ieee80211_mgmt_probe_request_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTHENTICATION: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication))) {
ac_ieee80211_mgmt_authentication_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_REQUEST: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->associationrequest))) {
ac_ieee80211_mgmt_association_request_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_RESPONSE: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->associationresponse))) {
ac_ieee80211_mgmt_association_response_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_REQUEST: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationrequest))) {
ac_ieee80211_mgmt_reassociation_request_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_RESPONSE: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationresponse))) {
ac_ieee80211_mgmt_reassociation_response_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOCIATION: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->disassociation))) {
ac_ieee80211_mgmt_disassociation_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DEAUTHENTICATION: {
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->deauthetication))) {
ac_ieee80211_mgmt_deauthentication_packet(session, radioid, mgmt, mgmtlength);
}
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ACTION: {
break;
}
}
}
/* */
void ac_ieee80211_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header* header, int length) {
uint16_t framecontrol;
uint16_t framecontrol_type;
uint16_t framecontrol_subtype;
ASSERT(session != NULL);
ASSERT(IS_VALID_RADIOID(radioid));
ASSERT(header != NULL);
ASSERT(length >= sizeof(struct ieee80211_header));
/* Get type frame */
framecontrol = __le16_to_cpu(header->framecontrol);
framecontrol_type = IEEE80211_FRAME_CONTROL_GET_TYPE(framecontrol);
framecontrol_subtype = IEEE80211_FRAME_CONTROL_GET_SUBTYPE(framecontrol);
/* Parsing frame */
if (framecontrol_type == IEEE80211_FRAMECONTROL_TYPE_MGMT) {
ac_ieee80211_mgmt_packet(session, radioid, (const struct ieee80211_header_mgmt*)header, length, framecontrol_subtype);
}
}

View File

@ -1,92 +1,92 @@
#ifndef __AC_JSON_HEADER__
#define __AC_JSON_HEADER__
#include "capwap_array.h"
#include <json/json.h>
#define IEEE80211_BINDING_JSON_ROOT "WTPRadio"
struct ac_json_ieee80211_item {
int valid;
struct capwap_80211_addwlan_element* addwlan;
struct capwap_80211_antenna_element* antenna;
struct capwap_80211_assignbssid_element* assignbssid;
struct capwap_80211_deletewlan_element* deletewlan;
struct capwap_80211_directsequencecontrol_element* directsequencecontrol;
struct capwap_array* iearray;
struct capwap_80211_macoperation_element* macoperation;
struct capwap_80211_miccountermeasures_element* miccountermeasures;
struct capwap_80211_multidomaincapability_element* multidomaincapability;
struct capwap_80211_ofdmcontrol_element* ofdmcontrol;
struct capwap_80211_rateset_element* rateset;
struct capwap_80211_rsnaerrorreport_element* rsnaerrorreport;
struct capwap_80211_statistics_element* statistics;
struct capwap_80211_supportedrates_element* supportedrates;
struct capwap_80211_txpower_element* txpower;
struct capwap_80211_txpowerlevel_element* txpowerlevel;
struct capwap_80211_updatewlan_element* updatewlan;
struct capwap_80211_wtpqos_element* wtpqos;
struct capwap_80211_wtpradioconf_element* wtpradioconf;
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm;
struct capwap_80211_wtpradioinformation_element* wtpradioinformation;
};
struct ac_json_ieee80211_wtpradio {
struct ac_json_ieee80211_item items[RADIOID_MAX_COUNT];
};
/* JSON IEEE 802.11 message elements */
#include "ac_80211_json_addwlan.h"
#include "ac_80211_json_antenna.h"
#include "ac_80211_json_assignbssid.h"
#include "ac_80211_json_deletewlan.h"
#include "ac_80211_json_directsequencecontrol.h"
#include "ac_80211_json_ie.h"
#include "ac_80211_json_macoperation.h"
#include "ac_80211_json_miccountermeasures.h"
#include "ac_80211_json_multidomaincapability.h"
#include "ac_80211_json_ofdmcontrol.h"
#include "ac_80211_json_rateset.h"
#include "ac_80211_json_rsnaerrorreport.h"
#include "ac_80211_json_statistics.h"
#include "ac_80211_json_supportedrates.h"
#include "ac_80211_json_txpower.h"
#include "ac_80211_json_txpowerlevel.h"
#include "ac_80211_json_updatewlan.h"
#include "ac_80211_json_wtpqos.h"
#include "ac_80211_json_wtpradioconf.h"
#include "ac_80211_json_wtpradiofailalarm.h"
#include "ac_80211_json_wtpradioinformation.h"
/* */
struct ac_json_ieee80211_ops {
/* Message Element Type */
uint16_t type;
/* Message Element JSON Type */
char* json_type;
/* Build message element */
void* (*create_message_element)(struct json_object* jsonparent, uint16_t radioid);
int (*add_message_element)(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite);
/* Build JSON */
void (*create_json)(struct json_object* jsonparent, void* data);
};
/* */
void ac_json_ieee80211_init(struct ac_json_ieee80211_wtpradio* wtpradio);
void ac_json_ieee80211_free(struct ac_json_ieee80211_wtpradio* wtpradio);
/* */
int ac_json_ieee80211_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, uint16_t type, void* data, int overwrite);
int ac_json_ieee80211_parsingmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_message_element_itemlist* messageelement);
int ac_json_ieee80211_parsingjson(struct ac_json_ieee80211_wtpradio* wtpradio, struct json_object* jsonroot);
/* */
struct json_object* ac_json_ieee80211_getjson(struct ac_json_ieee80211_wtpradio* wtpradio);
void ac_json_ieee80211_buildpacket(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_packet_txmng* txmngpacket);
#endif /* __AC_JSON_HEADER__ */
#ifndef __AC_JSON_HEADER__
#define __AC_JSON_HEADER__
#include "capwap_array.h"
#include <json/json.h>
#define IEEE80211_BINDING_JSON_ROOT "WTPRadio"
struct ac_json_ieee80211_item {
int valid;
struct capwap_80211_addwlan_element* addwlan;
struct capwap_80211_antenna_element* antenna;
struct capwap_80211_assignbssid_element* assignbssid;
struct capwap_80211_deletewlan_element* deletewlan;
struct capwap_80211_directsequencecontrol_element* directsequencecontrol;
struct capwap_array* iearray;
struct capwap_80211_macoperation_element* macoperation;
struct capwap_80211_miccountermeasures_element* miccountermeasures;
struct capwap_80211_multidomaincapability_element* multidomaincapability;
struct capwap_80211_ofdmcontrol_element* ofdmcontrol;
struct capwap_80211_rateset_element* rateset;
struct capwap_80211_rsnaerrorreport_element* rsnaerrorreport;
struct capwap_80211_statistics_element* statistics;
struct capwap_80211_supportedrates_element* supportedrates;
struct capwap_80211_txpower_element* txpower;
struct capwap_80211_txpowerlevel_element* txpowerlevel;
struct capwap_80211_updatewlan_element* updatewlan;
struct capwap_80211_wtpqos_element* wtpqos;
struct capwap_80211_wtpradioconf_element* wtpradioconf;
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm;
struct capwap_80211_wtpradioinformation_element* wtpradioinformation;
};
struct ac_json_ieee80211_wtpradio {
struct ac_json_ieee80211_item items[RADIOID_MAX_COUNT];
};
/* JSON IEEE 802.11 message elements */
#include "ac_80211_json_addwlan.h"
#include "ac_80211_json_antenna.h"
#include "ac_80211_json_assignbssid.h"
#include "ac_80211_json_deletewlan.h"
#include "ac_80211_json_directsequencecontrol.h"
#include "ac_80211_json_ie.h"
#include "ac_80211_json_macoperation.h"
#include "ac_80211_json_miccountermeasures.h"
#include "ac_80211_json_multidomaincapability.h"
#include "ac_80211_json_ofdmcontrol.h"
#include "ac_80211_json_rateset.h"
#include "ac_80211_json_rsnaerrorreport.h"
#include "ac_80211_json_statistics.h"
#include "ac_80211_json_supportedrates.h"
#include "ac_80211_json_txpower.h"
#include "ac_80211_json_txpowerlevel.h"
#include "ac_80211_json_updatewlan.h"
#include "ac_80211_json_wtpqos.h"
#include "ac_80211_json_wtpradioconf.h"
#include "ac_80211_json_wtpradiofailalarm.h"
#include "ac_80211_json_wtpradioinformation.h"
/* */
struct ac_json_ieee80211_ops {
/* Message Element Type */
uint16_t type;
/* Message Element JSON Type */
char* json_type;
/* Build message element */
void* (*create_message_element)(struct json_object* jsonparent, uint16_t radioid);
int (*add_message_element)(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite);
/* Build JSON */
void (*create_json)(struct json_object* jsonparent, void* data);
};
/* */
void ac_json_ieee80211_init(struct ac_json_ieee80211_wtpradio* wtpradio);
void ac_json_ieee80211_free(struct ac_json_ieee80211_wtpradio* wtpradio);
/* */
int ac_json_ieee80211_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, uint16_t type, void* data, int overwrite);
int ac_json_ieee80211_parsingmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_message_element_itemlist* messageelement);
int ac_json_ieee80211_parsingjson(struct ac_json_ieee80211_wtpradio* wtpradio, struct json_object* jsonroot);
/* */
struct json_object* ac_json_ieee80211_getjson(struct ac_json_ieee80211_wtpradio* wtpradio);
void ac_json_ieee80211_buildpacket(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_packet_txmng* txmngpacket);
#endif /* __AC_JSON_HEADER__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,71 +1,71 @@
#ifndef __AC_KMOD_HEADER__
#define __AC_KMOD_HEADER__
/* */
#ifdef HAVE_LIBNL_10
#define nl_sock nl_handle
#endif
/* */
#define AC_KMOD_MODE_LOCAL 0x00000001
#define AC_KMOD_MODE_TUNNEL_USERMODE 0x00000002
#define AC_KMOD_MODE_TUNNEL_KERNELMODE 0x00000003
/* */
#define AC_KMOD_FLAGS_TUNNEL_NATIVE 0x00000000
#define AC_KMOD_FLAGS_TUNNEL_8023 0x00000001
/* */
struct ac_kmod_handle {
/* Callback */
struct nl_sock* nl;
int nl_fd;
struct nl_cb* nl_cb;
int nlsmartcapwap_id;
/* Send message */
capwap_lock_t msglock;
struct nl_sock* nlmsg;
struct nl_cb* nlmsg_cb;
};
/* */
#define AC_KMOD_EVENT_MAX_ITEMS 2
struct ac_kmod_event {
void (*event_handler)(int fd, void** params, int paramscount);
int paramscount;
void* params[AC_KMOD_EVENT_MAX_ITEMS];
};
/* */
int ac_kmod_init(void);
void ac_kmod_free(void);
/* */
int ac_kmod_isconnected(void);
int ac_kmod_getfd(struct pollfd* fds, struct ac_kmod_event* events, int count);
/* */
int ac_kmod_createdatachannel(int family, unsigned short port);
/* */
int ac_kmod_send_keepalive(struct capwap_sessionid_element* sessionid);
int ac_kmod_send_data(struct capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t binding, const uint8_t* data, int length);
/* */
int ac_kmod_create_iface(const char* ifname, uint16_t mtu);
int ac_kmod_delete_iface(int ifindex);
/* */
int ac_kmod_new_datasession(struct capwap_sessionid_element* sessionid, uint8_t binding, uint16_t mtu);
int ac_kmod_delete_datasession(struct capwap_sessionid_element* sessionid);
/* */
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 ac_kmod_removewlan(struct capwap_sessionid_element* sessionid);
/* */
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 ac_kmod_deauthorize_station(struct capwap_sessionid_element* sessionid, const uint8_t* macaddress);
#endif /* __AC_KMOD_HEADER__ */
#ifndef __AC_KMOD_HEADER__
#define __AC_KMOD_HEADER__
/* */
#ifdef HAVE_LIBNL_10
#define nl_sock nl_handle
#endif
/* */
#define AC_KMOD_MODE_LOCAL 0x00000001
#define AC_KMOD_MODE_TUNNEL_USERMODE 0x00000002
#define AC_KMOD_MODE_TUNNEL_KERNELMODE 0x00000003
/* */
#define AC_KMOD_FLAGS_TUNNEL_NATIVE 0x00000000
#define AC_KMOD_FLAGS_TUNNEL_8023 0x00000001
/* */
struct ac_kmod_handle {
/* Callback */
struct nl_sock* nl;
int nl_fd;
struct nl_cb* nl_cb;
int nlsmartcapwap_id;
/* Send message */
capwap_lock_t msglock;
struct nl_sock* nlmsg;
struct nl_cb* nlmsg_cb;
};
/* */
#define AC_KMOD_EVENT_MAX_ITEMS 2
struct ac_kmod_event {
void (*event_handler)(int fd, void** params, int paramscount);
int paramscount;
void* params[AC_KMOD_EVENT_MAX_ITEMS];
};
/* */
int ac_kmod_init(void);
void ac_kmod_free(void);
/* */
int ac_kmod_isconnected(void);
int ac_kmod_getfd(struct pollfd* fds, struct ac_kmod_event* events, int count);
/* */
int ac_kmod_createdatachannel(int family, unsigned short port);
/* */
int ac_kmod_send_keepalive(struct capwap_sessionid_element* sessionid);
int ac_kmod_send_data(struct capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t binding, const uint8_t* data, int length);
/* */
int ac_kmod_create_iface(const char* ifname, uint16_t mtu);
int ac_kmod_delete_iface(int ifindex);
/* */
int ac_kmod_new_datasession(struct capwap_sessionid_element* sessionid, uint8_t binding, uint16_t mtu);
int ac_kmod_delete_datasession(struct capwap_sessionid_element* sessionid);
/* */
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 ac_kmod_removewlan(struct capwap_sessionid_element* sessionid);
/* */
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 ac_kmod_deauthorize_station(struct capwap_sessionid_element* sessionid, const uint8_t* macaddress);
#endif /* __AC_KMOD_HEADER__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,114 +1,114 @@
#ifndef __AC_SOAP_HEADER__
#define __AC_SOAP_HEADER__
#include <libxml/tree.h>
#include <libxml/parser.h>
/* */
#define SOAP_HTTP_PROTOCOL 1
#define SOAP_HTTPS_PROTOCOL 2
#define SOAP_HTTP_PORT 80
#define SOAP_HTTPS_PORT 443
#define HTTP_RESULT_CONTINUE 100
#define HTTP_RESULT_OK 200
#define SOAP_PROTOCOL_REQUEST_TIMEOUT 10000
#define SOAP_PROTOCOL_RESPONSE_TIMEOUT 10000
#define SOAP_PROTOCOL_CLOSE_TIMEOUT 10000
/* */
struct ac_http_soap_server {
int protocol;
union sockaddr_capwap address;
char* host;
char* path;
/* SSL/TLS context */
void* sslcontext;
};
/* */
struct ac_soap_request {
xmlDocPtr xmlDocument;
xmlNodePtr xmlRoot;
xmlNodePtr xmlBody;
xmlNodePtr xmlRequest;
char* method;
};
/* */
struct ac_http_soap_request {
struct ac_http_soap_server* server;
struct ac_soap_request* request;
int sock;
int requesttimeout;
int responsetimeout;
/* SSL info */
struct capwap_socket_ssl* sslsock;
/* Information for SOAP Response */
int httpstate;
int responsecode;
int contentlength;
int contentxml;
};
/* */
struct ac_soap_response {
int responsecode;
xmlDocPtr xmlDocument;
xmlNodePtr xmlRoot;
xmlNodePtr xmlBody;
/* Valid response */
xmlNodePtr xmlResponse;
xmlNodePtr xmlResponseReturn;
/* Fault response */
xmlNodePtr xmlFault;
xmlNodePtr xmlFaultCode;
xmlNodePtr xmlFaultString;
};
/* */
void ac_soapclient_init(void);
void ac_soapclient_free(void);
/* */
struct ac_http_soap_server* ac_soapclient_create_server(const char* url);
void ac_soapclient_free_server(struct ac_http_soap_server* server);
/* Request */
struct ac_soap_request* ac_soapclient_create_request(char* method, char* urinamespace);
int ac_soapclient_add_param(struct ac_soap_request* request, const char* type, const char* name, const char* value);
char* ac_soapclient_get_request(struct ac_soap_request* request);
void ac_soapclient_free_request(struct ac_soap_request* request);
/* Transport Request */
struct ac_http_soap_request* ac_soapclient_prepare_request(struct ac_soap_request* request, struct ac_http_soap_server* server);
int ac_soapclient_send_request(struct ac_http_soap_request* httprequest, char* soapaction);
struct ac_soap_response* ac_soapclient_recv_response(struct ac_http_soap_request* httprequest);
struct json_object* ac_soapclient_parse_json_response(struct ac_soap_response* response);
void ac_soapclient_shutdown_request(struct ac_http_soap_request* httprequest);
void ac_soapclient_close_request(struct ac_http_soap_request* httprequest, int closerequest);
/* Response */
void ac_soapclient_free_response(struct ac_soap_response* response);
/* Base64 */
#define AC_BASE64_ENCODE_LENGTH(x) ((((x) + 2) / 3) * 4 + 1)
#define AC_BASE64_DECODE_LENGTH(x) (((x) / 4) * 3 + 1)
void ac_base64_string_encode(const char* plain, char* encoded);
int ac_base64_binary_encode(const char* plain, int length, char* encoded);
void ac_base64_string_decode(const char* encoded, char* plain);
int ac_base64_binary_decode(const char* encoded, int length, char* plain);
#endif /* __AC_SOAP_HEADER__ */
#ifndef __AC_SOAP_HEADER__
#define __AC_SOAP_HEADER__
#include <libxml/tree.h>
#include <libxml/parser.h>
/* */
#define SOAP_HTTP_PROTOCOL 1
#define SOAP_HTTPS_PROTOCOL 2
#define SOAP_HTTP_PORT 80
#define SOAP_HTTPS_PORT 443
#define HTTP_RESULT_CONTINUE 100
#define HTTP_RESULT_OK 200
#define SOAP_PROTOCOL_REQUEST_TIMEOUT 10000
#define SOAP_PROTOCOL_RESPONSE_TIMEOUT 10000
#define SOAP_PROTOCOL_CLOSE_TIMEOUT 10000
/* */
struct ac_http_soap_server {
int protocol;
union sockaddr_capwap address;
char* host;
char* path;
/* SSL/TLS context */
void* sslcontext;
};
/* */
struct ac_soap_request {
xmlDocPtr xmlDocument;
xmlNodePtr xmlRoot;
xmlNodePtr xmlBody;
xmlNodePtr xmlRequest;
char* method;
};
/* */
struct ac_http_soap_request {
struct ac_http_soap_server* server;
struct ac_soap_request* request;
int sock;
int requesttimeout;
int responsetimeout;
/* SSL info */
struct capwap_socket_ssl* sslsock;
/* Information for SOAP Response */
int httpstate;
int responsecode;
int contentlength;
int contentxml;
};
/* */
struct ac_soap_response {
int responsecode;
xmlDocPtr xmlDocument;
xmlNodePtr xmlRoot;
xmlNodePtr xmlBody;
/* Valid response */
xmlNodePtr xmlResponse;
xmlNodePtr xmlResponseReturn;
/* Fault response */
xmlNodePtr xmlFault;
xmlNodePtr xmlFaultCode;
xmlNodePtr xmlFaultString;
};
/* */
void ac_soapclient_init(void);
void ac_soapclient_free(void);
/* */
struct ac_http_soap_server* ac_soapclient_create_server(const char* url);
void ac_soapclient_free_server(struct ac_http_soap_server* server);
/* Request */
struct ac_soap_request* ac_soapclient_create_request(char* method, char* urinamespace);
int ac_soapclient_add_param(struct ac_soap_request* request, const char* type, const char* name, const char* value);
char* ac_soapclient_get_request(struct ac_soap_request* request);
void ac_soapclient_free_request(struct ac_soap_request* request);
/* Transport Request */
struct ac_http_soap_request* ac_soapclient_prepare_request(struct ac_soap_request* request, struct ac_http_soap_server* server);
int ac_soapclient_send_request(struct ac_http_soap_request* httprequest, char* soapaction);
struct ac_soap_response* ac_soapclient_recv_response(struct ac_http_soap_request* httprequest);
struct json_object* ac_soapclient_parse_json_response(struct ac_soap_response* response);
void ac_soapclient_shutdown_request(struct ac_http_soap_request* httprequest);
void ac_soapclient_close_request(struct ac_http_soap_request* httprequest, int closerequest);
/* Response */
void ac_soapclient_free_response(struct ac_soap_response* response);
/* Base64 */
#define AC_BASE64_ENCODE_LENGTH(x) ((((x) + 2) / 3) * 4 + 1)
#define AC_BASE64_DECODE_LENGTH(x) (((x) / 4) * 3 + 1)
void ac_base64_string_encode(const char* plain, char* encoded);
int ac_base64_binary_encode(const char* plain, int length, char* encoded);
void ac_base64_string_decode(const char* encoded, char* plain);
int ac_base64_binary_decode(const char* encoded, int length, char* plain);
#endif /* __AC_SOAP_HEADER__ */

View File

@ -1,488 +1,488 @@
#include "ac.h"
#include "ac_session.h"
#include "ac_wlans.h"
#include "ac_backend.h"
/* */
static void ac_stations_reset_station(struct ac_session_t* session, struct ac_station* station, struct ac_wlan* wlan) {
ASSERT(session != NULL);
ASSERT(station != NULL);
if (station->wlan) {
if (station->aid) {
if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
ieee80211_aid_free(station->wlan->aidbitfield, station->aid);
}
station->aid = 0;
}
/* Remove reference from current WLAN */
capwap_itemlist_remove(station->wlan->stations, station->wlanitem);
}
/* Remove timers */
if (station->idtimeout != CAPWAP_TIMEOUT_INDEX_NO_SET) {
capwap_timeout_deletetimer(session->timeout, station->idtimeout);
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
}
/* */
station->flags = 0;
/* Set WLAN */
station->wlan = wlan;
if (station->wlan) {
capwap_itemlist_insert_after(wlan->stations, NULL, station->wlanitem);
}
}
/* */
static void ac_stations_destroy_station(struct ac_session_t* session, struct ac_station* station) {
struct ac_station* authoritativestation;
ASSERT(session != NULL);
ASSERT(station != NULL);
/* */
capwap_logging_info("Destroy station: %s", station->addrtext);
/* Remove reference from Authoritative Stations List */
capwap_rwlock_wrlock(&g_ac.authstationslock);
/* Can delete global reference only if match session handler */
authoritativestation = (struct ac_station*)capwap_hash_search(g_ac.authstations, station->address);
if (authoritativestation && (authoritativestation->session == session)) {
capwap_hash_delete(g_ac.authstations, station->address);
}
capwap_rwlock_unlock(&g_ac.authstationslock);
/* Remove reference from WLAN */
ac_stations_reset_station(session, station, NULL);
/* */
capwap_hash_delete(session->wlans->stations, station->address);
/* Free station reference with itemlist */
capwap_itemlist_free(station->wlanitem);
}
/* */
static unsigned long ac_wlans_item_gethash(const void* key, unsigned long hashsize) {
uint8_t* macaddress = (uint8_t*)key;
return ((unsigned long)(macaddress[3] ^ macaddress[4] ^ macaddress[5]) % AC_WLANS_STATIONS_HASH_SIZE);
}
/* */
static const void* ac_wlans_item_getkey(const void* data) {
return (const void*)((struct ac_station*)data)->address;
}
/* */
static int ac_wlans_item_cmp(const void* key1, const void* key2) {
return memcmp(key1, key2, MACADDRESS_EUI48_LENGTH);
}
/* */
void ac_wlans_init(struct ac_session_t* session) {
int i;
ASSERT(session != NULL);
ASSERT(session->wlans == NULL);
/* */
session->wlans = (struct ac_wlans*)capwap_alloc(sizeof(struct ac_wlans));
memset(session->wlans, 0, sizeof(struct ac_wlans));
/* */
session->wlans->stations = capwap_hash_create(AC_WLANS_STATIONS_HASH_SIZE);
session->wlans->stations->item_gethash = ac_wlans_item_gethash;
session->wlans->stations->item_getkey = ac_wlans_item_getkey;
session->wlans->stations->item_cmp = ac_wlans_item_cmp;
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
session->wlans->devices[i].radioid = i + 1;
}
}
/* */
void ac_wlans_destroy(struct ac_session_t* session) {
int i;
struct capwap_list* items;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
/* */
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
if (session->wlans->devices[i].wlans) {
items = session->wlans->devices[i].wlans;
/* Delete WLANS */
while (items->first) {
ac_wlans_delete_bssid(session, i + 1, ((struct ac_wlan*)items->first->item)->address);
}
/* */
capwap_list_free(items);
}
}
/* */
ASSERT(session->wlans->stations->count == 0);
/* */
capwap_hash_free(session->wlans->stations);
capwap_free(session->wlans);
}
/* */
int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan) {
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(wlan != NULL);
ASSERT(wlan->device != NULL);
ASSERT(IS_VALID_RADIOID(wlan->device->radioid));
ASSERT(IS_VALID_WLANID(wlan->wlanid));
/* */
if (ac_wlans_get_bssid(session, wlan->device->radioid, wlan->address)) {
return -1;
}
/* */
wlan->session = session;
/* Create WLAN list */
if (!session->wlans->devices[wlan->device->radioid - 1].wlans) {
session->wlans->devices[wlan->device->radioid - 1].wlans = capwap_list_create();
}
/* Append WLAN to list */
capwap_itemlist_insert_after(session->wlans->devices[wlan->device->radioid - 1].wlans, NULL, wlan->wlanitem);
/* */
capwap_logging_info("Added new wlan with radioid: %d, wlanid: %d, bssid: %s", (int)wlan->device->radioid, (int)wlan->wlanid, capwap_printf_macaddress(buffer, wlan->address, MACADDRESS_EUI48_LENGTH));
return 0;
}
/* */
struct ac_wlan* ac_wlans_create_bssid(struct ac_device* device, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan) {
struct ac_wlan* wlan;
struct capwap_list_item* wlanitem;
ASSERT(device != NULL);
ASSERT(IS_VALID_WLANID(wlanid));
ASSERT(bssid != NULL);
/* */
wlanitem = capwap_itemlist_create(sizeof(struct ac_wlan));
wlan = (struct ac_wlan*)wlanitem->item;
memset(wlan, 0, sizeof(struct ac_wlan));
/* Init WLAN */
wlan->wlanitem = wlanitem;
memcpy(wlan->address, bssid, MACADDRESS_EUI48_LENGTH);
wlan->device = device;
wlan->wlanid = wlanid;
wlan->stations = capwap_list_create();
/* Set capability */
wlan->capability = addwlan->capability;
wlan->keyindex = addwlan->keyindex;
wlan->keystatus = addwlan->keystatus;
wlan->keylength = addwlan->keylength;
if (addwlan->key && (addwlan->keylength > 0)) {
wlan->key = (uint8_t*)capwap_clone(addwlan->key, wlan->keylength);
}
memcpy(wlan->grouptsc, addwlan->grouptsc, CAPWAP_ADD_WLAN_GROUPTSC_LENGTH);
wlan->qos = addwlan->qos;
wlan->authmode = addwlan->authmode;
wlan->macmode = addwlan->macmode;
wlan->tunnelmode = addwlan->tunnelmode;
wlan->suppressssid = addwlan->suppressssid;
strcpy(wlan->ssid, (const char*)addwlan->ssid);
return wlan;
}
/* */
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid) {
struct capwap_list_item* search;
struct ac_wlan* wlan = NULL;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(IS_VALID_RADIOID(radioid));
ASSERT(bssid != NULL);
/* */
if (session->wlans->devices[radioid - 1].wlans) {
for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
struct ac_wlan* item = (struct ac_wlan*)search->item;
if (!memcmp(bssid, item->address, MACADDRESS_EUI48_LENGTH)) {
wlan = item;
break;
}
}
}
return wlan;
}
/* */
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid) {
struct capwap_list_item* search;
struct ac_wlan* wlan = NULL;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(IS_VALID_RADIOID(radioid));
ASSERT(IS_VALID_WLANID(wlanid));
/* */
if (session->wlans->devices[radioid - 1].wlans) {
for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
struct ac_wlan* item = (struct ac_wlan*)search->item;
if (wlanid == item->wlanid) {
wlan = item;
break;
}
}
}
return wlan;
}
/* */
void ac_wlans_free_bssid(struct ac_wlan* wlan) {
ASSERT(wlan != NULL);
/* Free capability */
if (wlan->key) {
capwap_free(wlan->key);
}
/* */
capwap_list_free(wlan->stations);
capwap_itemlist_free(wlan->wlanitem);
}
/* */
void ac_wlans_delete_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid) {
struct capwap_list_item* search;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(IS_VALID_RADIOID(radioid));
ASSERT(bssid != NULL);
/* */
if (session->wlans->devices[radioid - 1].wlans) {
for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
struct ac_wlan* wlan = (struct ac_wlan*)search->item;
if (!memcmp(bssid, wlan->address, MACADDRESS_EUI48_LENGTH)) {
/* Remove stations */
while (wlan->stations->first) {
ac_stations_destroy_station(session, (struct ac_station*)wlan->stations->first->item);
}
/* */
capwap_itemlist_remove(session->wlans->devices[radioid - 1].wlans, search);
ac_wlans_free_bssid(wlan);
break;
}
}
}
}
/* */
struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
struct ac_station* station;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(address != NULL);
/* Get station */
station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
if (station && (station->flags & AC_STATION_FLAGS_ENABLED) && ((radioid == RADIOID_ANY) || (radioid == station->wlan->device->radioid)) && (!bssid || !memcmp(bssid, station->wlan->address, MACADDRESS_EUI48_LENGTH))) {
return station;
}
return NULL;
}
/* */
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
char buffer1[CAPWAP_MACADDRESS_EUI48_BUFFER];
char buffer2[CAPWAP_MACADDRESS_EUI48_BUFFER];
struct ac_wlan* wlan;
struct ac_station* authoritativestation;
struct ac_station* station = NULL;
struct ac_session_t* authoritativesession = NULL;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(IS_VALID_RADIOID(radioid));
ASSERT(bssid != NULL);
ASSERT(address != NULL);
/* */
capwap_printf_macaddress(buffer1, bssid, MACADDRESS_EUI48_LENGTH);
capwap_printf_macaddress(buffer2, address, MACADDRESS_EUI48_LENGTH);
capwap_logging_info("Create station to radioid: %d, bssid: %s, station address: %s", (int)radioid, buffer1, buffer2);
/* */
wlan = ac_wlans_get_bssid(session, radioid, bssid);
if (wlan) {
station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
if (!station) {
struct capwap_list_item* stationitem = capwap_itemlist_create(sizeof(struct ac_station));
station = (struct ac_station*)stationitem->item;
memset(station, 0, sizeof(struct ac_station));
/* */
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
memcpy(station->address, address, MACADDRESS_EUI48_LENGTH);
capwap_printf_macaddress(station->addrtext, address, MACADDRESS_EUI48_LENGTH);
station->wlanitem = stationitem;
station->session = session;
/* */
capwap_hash_add(session->wlans->stations, (void*)station);
}
/* Set station to WLAN */
ac_stations_reset_station(session, station, wlan);
station->flags |= AC_STATION_FLAGS_ENABLED;
/* Check Authoritative Stations List */
capwap_rwlock_rdlock(&g_ac.authstationslock);
authoritativestation = (struct ac_station*)capwap_hash_search(g_ac.authstations, address);
if (authoritativestation && authoritativestation->session) {
authoritativesession = authoritativestation->session;
}
capwap_rwlock_unlock(&g_ac.authstationslock);
/* Check Authoritative Session */
if (authoritativesession != session) {
/* Update Authoritative Stations List */
capwap_rwlock_wrlock(&g_ac.authstationslock);
capwap_hash_add(g_ac.authstations, (void*)station);
capwap_rwlock_unlock(&g_ac.authstationslock);
/* Release Station from old Authoritative Session */
if (authoritativesession) {
ac_session_send_action(authoritativesession, AC_SESSION_ACTION_STATION_ROAMING, 0, (void*)address, MACADDRESS_EUI48_LENGTH);
}
}
} else {
capwap_logging_warning("Unable to find radioid: %d, bssid: %s", (int)radioid, buffer1);
}
return station;
}
/* */
void ac_stations_delete_station(struct ac_session_t* session, struct ac_station* station) {
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(station != NULL);
/* Deauthorize station */
ac_stations_deauthorize_station(session, station);
/* Destroy station reference */
ac_stations_destroy_station(session, station);
}
/* */
void ac_stations_authorize_station(struct ac_session_t* session, struct ac_station* station) {
struct ac_notify_station_configuration_ieee8011_add_station notify;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(station != NULL);
/* Active Station only if Authenticated, Associated and not Authorizated */
if ((station->flags & AC_STATION_FLAGS_AUTHENTICATED) && (station->flags & AC_STATION_FLAGS_ASSOCIATE) && !(station->flags & AC_STATION_FLAGS_AUTHORIZED)) {
memset(&notify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
notify.radioid = station->wlan->device->radioid;
memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
notify.wlanid = station->wlan->wlanid;
notify.associationid = station->aid;
notify.capabilities = station->capability;
notify.supportedratescount = station->supportedratescount;
memcpy(notify.supportedrates, station->supportedrates, station->supportedratescount);
ac_session_send_action(session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_ADD_STATION, 0, &notify, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
}
}
/* */
void ac_stations_deauthorize_station(struct ac_session_t* session, struct ac_station* station) {
int responselength;
uint8_t buffer[IEEE80211_MTU];
struct ieee80211_deauthentication_params ieee80211_params;
struct ac_notify_station_configuration_ieee8011_delete_station notify;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(station != NULL);
if (station->flags & AC_STATION_FLAGS_AUTHORIZED) {
/* Deauthorize station */
memset(&notify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
notify.radioid = station->wlan->device->radioid;
memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
/* */
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE | AC_STATION_FLAGS_AUTHORIZED);
ac_session_send_action(session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION, 0, &notify, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
} else if (station->flags & AC_STATION_FLAGS_AUTHENTICATED) {
/* Create deauthentication packet */
memset(&ieee80211_params, 0, sizeof(struct ieee80211_deauthentication_params));
memcpy(ieee80211_params.bssid, station->wlan->address, MACADDRESS_EUI48_LENGTH);
memcpy(ieee80211_params.station, station->address, MACADDRESS_EUI48_LENGTH);
ieee80211_params.reasoncode = IEEE80211_REASON_PREV_AUTH_NOT_VALID;
/* */
responselength = ieee80211_create_deauthentication(buffer, IEEE80211_MTU, &ieee80211_params);
if (responselength > 0) {
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE);
ac_kmod_send_data(&session->sessionid, station->wlan->device->radioid, session->binding, buffer, responselength);
}
}
}
/* */
void ac_stations_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param) {
struct ac_station* station = (struct ac_station*)context;
ASSERT(station != NULL);
if (station->idtimeout == index) {
switch (station->timeoutaction) {
case AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE: {
capwap_logging_warning("The %s station has not completed the association in time", station->addrtext);
ac_stations_delete_station((struct ac_session_t*)param, station);
break;
}
}
}
}
#include "ac.h"
#include "ac_session.h"
#include "ac_wlans.h"
#include "ac_backend.h"
/* */
static void ac_stations_reset_station(struct ac_session_t* session, struct ac_station* station, struct ac_wlan* wlan) {
ASSERT(session != NULL);
ASSERT(station != NULL);
if (station->wlan) {
if (station->aid) {
if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
ieee80211_aid_free(station->wlan->aidbitfield, station->aid);
}
station->aid = 0;
}
/* Remove reference from current WLAN */
capwap_itemlist_remove(station->wlan->stations, station->wlanitem);
}
/* Remove timers */
if (station->idtimeout != CAPWAP_TIMEOUT_INDEX_NO_SET) {
capwap_timeout_deletetimer(session->timeout, station->idtimeout);
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
}
/* */
station->flags = 0;
/* Set WLAN */
station->wlan = wlan;
if (station->wlan) {
capwap_itemlist_insert_after(wlan->stations, NULL, station->wlanitem);
}
}
/* */
static void ac_stations_destroy_station(struct ac_session_t* session, struct ac_station* station) {
struct ac_station* authoritativestation;
ASSERT(session != NULL);
ASSERT(station != NULL);
/* */
capwap_logging_info("Destroy station: %s", station->addrtext);
/* Remove reference from Authoritative Stations List */
capwap_rwlock_wrlock(&g_ac.authstationslock);
/* Can delete global reference only if match session handler */
authoritativestation = (struct ac_station*)capwap_hash_search(g_ac.authstations, station->address);
if (authoritativestation && (authoritativestation->session == session)) {
capwap_hash_delete(g_ac.authstations, station->address);
}
capwap_rwlock_unlock(&g_ac.authstationslock);
/* Remove reference from WLAN */
ac_stations_reset_station(session, station, NULL);
/* */
capwap_hash_delete(session->wlans->stations, station->address);
/* Free station reference with itemlist */
capwap_itemlist_free(station->wlanitem);
}
/* */
static unsigned long ac_wlans_item_gethash(const void* key, unsigned long hashsize) {
uint8_t* macaddress = (uint8_t*)key;
return ((unsigned long)(macaddress[3] ^ macaddress[4] ^ macaddress[5]) % AC_WLANS_STATIONS_HASH_SIZE);
}
/* */
static const void* ac_wlans_item_getkey(const void* data) {
return (const void*)((struct ac_station*)data)->address;
}
/* */
static int ac_wlans_item_cmp(const void* key1, const void* key2) {
return memcmp(key1, key2, MACADDRESS_EUI48_LENGTH);
}
/* */
void ac_wlans_init(struct ac_session_t* session) {
int i;
ASSERT(session != NULL);
ASSERT(session->wlans == NULL);
/* */
session->wlans = (struct ac_wlans*)capwap_alloc(sizeof(struct ac_wlans));
memset(session->wlans, 0, sizeof(struct ac_wlans));
/* */
session->wlans->stations = capwap_hash_create(AC_WLANS_STATIONS_HASH_SIZE);
session->wlans->stations->item_gethash = ac_wlans_item_gethash;
session->wlans->stations->item_getkey = ac_wlans_item_getkey;
session->wlans->stations->item_cmp = ac_wlans_item_cmp;
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
session->wlans->devices[i].radioid = i + 1;
}
}
/* */
void ac_wlans_destroy(struct ac_session_t* session) {
int i;
struct capwap_list* items;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
/* */
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
if (session->wlans->devices[i].wlans) {
items = session->wlans->devices[i].wlans;
/* Delete WLANS */
while (items->first) {
ac_wlans_delete_bssid(session, i + 1, ((struct ac_wlan*)items->first->item)->address);
}
/* */
capwap_list_free(items);
}
}
/* */
ASSERT(session->wlans->stations->count == 0);
/* */
capwap_hash_free(session->wlans->stations);
capwap_free(session->wlans);
}
/* */
int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan) {
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(wlan != NULL);
ASSERT(wlan->device != NULL);
ASSERT(IS_VALID_RADIOID(wlan->device->radioid));
ASSERT(IS_VALID_WLANID(wlan->wlanid));
/* */
if (ac_wlans_get_bssid(session, wlan->device->radioid, wlan->address)) {
return -1;
}
/* */
wlan->session = session;
/* Create WLAN list */
if (!session->wlans->devices[wlan->device->radioid - 1].wlans) {
session->wlans->devices[wlan->device->radioid - 1].wlans = capwap_list_create();
}
/* Append WLAN to list */
capwap_itemlist_insert_after(session->wlans->devices[wlan->device->radioid - 1].wlans, NULL, wlan->wlanitem);
/* */
capwap_logging_info("Added new wlan with radioid: %d, wlanid: %d, bssid: %s", (int)wlan->device->radioid, (int)wlan->wlanid, capwap_printf_macaddress(buffer, wlan->address, MACADDRESS_EUI48_LENGTH));
return 0;
}
/* */
struct ac_wlan* ac_wlans_create_bssid(struct ac_device* device, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan) {
struct ac_wlan* wlan;
struct capwap_list_item* wlanitem;
ASSERT(device != NULL);
ASSERT(IS_VALID_WLANID(wlanid));
ASSERT(bssid != NULL);
/* */
wlanitem = capwap_itemlist_create(sizeof(struct ac_wlan));
wlan = (struct ac_wlan*)wlanitem->item;
memset(wlan, 0, sizeof(struct ac_wlan));
/* Init WLAN */
wlan->wlanitem = wlanitem;
memcpy(wlan->address, bssid, MACADDRESS_EUI48_LENGTH);
wlan->device = device;
wlan->wlanid = wlanid;
wlan->stations = capwap_list_create();
/* Set capability */
wlan->capability = addwlan->capability;
wlan->keyindex = addwlan->keyindex;
wlan->keystatus = addwlan->keystatus;
wlan->keylength = addwlan->keylength;
if (addwlan->key && (addwlan->keylength > 0)) {
wlan->key = (uint8_t*)capwap_clone(addwlan->key, wlan->keylength);
}
memcpy(wlan->grouptsc, addwlan->grouptsc, CAPWAP_ADD_WLAN_GROUPTSC_LENGTH);
wlan->qos = addwlan->qos;
wlan->authmode = addwlan->authmode;
wlan->macmode = addwlan->macmode;
wlan->tunnelmode = addwlan->tunnelmode;
wlan->suppressssid = addwlan->suppressssid;
strcpy(wlan->ssid, (const char*)addwlan->ssid);
return wlan;
}
/* */
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid) {
struct capwap_list_item* search;
struct ac_wlan* wlan = NULL;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(IS_VALID_RADIOID(radioid));
ASSERT(bssid != NULL);
/* */
if (session->wlans->devices[radioid - 1].wlans) {
for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
struct ac_wlan* item = (struct ac_wlan*)search->item;
if (!memcmp(bssid, item->address, MACADDRESS_EUI48_LENGTH)) {
wlan = item;
break;
}
}
}
return wlan;
}
/* */
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid) {
struct capwap_list_item* search;
struct ac_wlan* wlan = NULL;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(IS_VALID_RADIOID(radioid));
ASSERT(IS_VALID_WLANID(wlanid));
/* */
if (session->wlans->devices[radioid - 1].wlans) {
for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
struct ac_wlan* item = (struct ac_wlan*)search->item;
if (wlanid == item->wlanid) {
wlan = item;
break;
}
}
}
return wlan;
}
/* */
void ac_wlans_free_bssid(struct ac_wlan* wlan) {
ASSERT(wlan != NULL);
/* Free capability */
if (wlan->key) {
capwap_free(wlan->key);
}
/* */
capwap_list_free(wlan->stations);
capwap_itemlist_free(wlan->wlanitem);
}
/* */
void ac_wlans_delete_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid) {
struct capwap_list_item* search;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(IS_VALID_RADIOID(radioid));
ASSERT(bssid != NULL);
/* */
if (session->wlans->devices[radioid - 1].wlans) {
for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
struct ac_wlan* wlan = (struct ac_wlan*)search->item;
if (!memcmp(bssid, wlan->address, MACADDRESS_EUI48_LENGTH)) {
/* Remove stations */
while (wlan->stations->first) {
ac_stations_destroy_station(session, (struct ac_station*)wlan->stations->first->item);
}
/* */
capwap_itemlist_remove(session->wlans->devices[radioid - 1].wlans, search);
ac_wlans_free_bssid(wlan);
break;
}
}
}
}
/* */
struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
struct ac_station* station;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(address != NULL);
/* Get station */
station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
if (station && (station->flags & AC_STATION_FLAGS_ENABLED) && ((radioid == RADIOID_ANY) || (radioid == station->wlan->device->radioid)) && (!bssid || !memcmp(bssid, station->wlan->address, MACADDRESS_EUI48_LENGTH))) {
return station;
}
return NULL;
}
/* */
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
char buffer1[CAPWAP_MACADDRESS_EUI48_BUFFER];
char buffer2[CAPWAP_MACADDRESS_EUI48_BUFFER];
struct ac_wlan* wlan;
struct ac_station* authoritativestation;
struct ac_station* station = NULL;
struct ac_session_t* authoritativesession = NULL;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(IS_VALID_RADIOID(radioid));
ASSERT(bssid != NULL);
ASSERT(address != NULL);
/* */
capwap_printf_macaddress(buffer1, bssid, MACADDRESS_EUI48_LENGTH);
capwap_printf_macaddress(buffer2, address, MACADDRESS_EUI48_LENGTH);
capwap_logging_info("Create station to radioid: %d, bssid: %s, station address: %s", (int)radioid, buffer1, buffer2);
/* */
wlan = ac_wlans_get_bssid(session, radioid, bssid);
if (wlan) {
station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
if (!station) {
struct capwap_list_item* stationitem = capwap_itemlist_create(sizeof(struct ac_station));
station = (struct ac_station*)stationitem->item;
memset(station, 0, sizeof(struct ac_station));
/* */
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
memcpy(station->address, address, MACADDRESS_EUI48_LENGTH);
capwap_printf_macaddress(station->addrtext, address, MACADDRESS_EUI48_LENGTH);
station->wlanitem = stationitem;
station->session = session;
/* */
capwap_hash_add(session->wlans->stations, (void*)station);
}
/* Set station to WLAN */
ac_stations_reset_station(session, station, wlan);
station->flags |= AC_STATION_FLAGS_ENABLED;
/* Check Authoritative Stations List */
capwap_rwlock_rdlock(&g_ac.authstationslock);
authoritativestation = (struct ac_station*)capwap_hash_search(g_ac.authstations, address);
if (authoritativestation && authoritativestation->session) {
authoritativesession = authoritativestation->session;
}
capwap_rwlock_unlock(&g_ac.authstationslock);
/* Check Authoritative Session */
if (authoritativesession != session) {
/* Update Authoritative Stations List */
capwap_rwlock_wrlock(&g_ac.authstationslock);
capwap_hash_add(g_ac.authstations, (void*)station);
capwap_rwlock_unlock(&g_ac.authstationslock);
/* Release Station from old Authoritative Session */
if (authoritativesession) {
ac_session_send_action(authoritativesession, AC_SESSION_ACTION_STATION_ROAMING, 0, (void*)address, MACADDRESS_EUI48_LENGTH);
}
}
} else {
capwap_logging_warning("Unable to find radioid: %d, bssid: %s", (int)radioid, buffer1);
}
return station;
}
/* */
void ac_stations_delete_station(struct ac_session_t* session, struct ac_station* station) {
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(station != NULL);
/* Deauthorize station */
ac_stations_deauthorize_station(session, station);
/* Destroy station reference */
ac_stations_destroy_station(session, station);
}
/* */
void ac_stations_authorize_station(struct ac_session_t* session, struct ac_station* station) {
struct ac_notify_station_configuration_ieee8011_add_station notify;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(station != NULL);
/* Active Station only if Authenticated, Associated and not Authorizated */
if ((station->flags & AC_STATION_FLAGS_AUTHENTICATED) && (station->flags & AC_STATION_FLAGS_ASSOCIATE) && !(station->flags & AC_STATION_FLAGS_AUTHORIZED)) {
memset(&notify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
notify.radioid = station->wlan->device->radioid;
memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
notify.wlanid = station->wlan->wlanid;
notify.associationid = station->aid;
notify.capabilities = station->capability;
notify.supportedratescount = station->supportedratescount;
memcpy(notify.supportedrates, station->supportedrates, station->supportedratescount);
ac_session_send_action(session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_ADD_STATION, 0, &notify, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
}
}
/* */
void ac_stations_deauthorize_station(struct ac_session_t* session, struct ac_station* station) {
int responselength;
uint8_t buffer[IEEE80211_MTU];
struct ieee80211_deauthentication_params ieee80211_params;
struct ac_notify_station_configuration_ieee8011_delete_station notify;
ASSERT(session != NULL);
ASSERT(session->wlans != NULL);
ASSERT(station != NULL);
if (station->flags & AC_STATION_FLAGS_AUTHORIZED) {
/* Deauthorize station */
memset(&notify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
notify.radioid = station->wlan->device->radioid;
memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
/* */
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE | AC_STATION_FLAGS_AUTHORIZED);
ac_session_send_action(session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION, 0, &notify, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
} else if (station->flags & AC_STATION_FLAGS_AUTHENTICATED) {
/* Create deauthentication packet */
memset(&ieee80211_params, 0, sizeof(struct ieee80211_deauthentication_params));
memcpy(ieee80211_params.bssid, station->wlan->address, MACADDRESS_EUI48_LENGTH);
memcpy(ieee80211_params.station, station->address, MACADDRESS_EUI48_LENGTH);
ieee80211_params.reasoncode = IEEE80211_REASON_PREV_AUTH_NOT_VALID;
/* */
responselength = ieee80211_create_deauthentication(buffer, IEEE80211_MTU, &ieee80211_params);
if (responselength > 0) {
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE);
ac_kmod_send_data(&session->sessionid, station->wlan->device->radioid, session->binding, buffer, responselength);
}
}
}
/* */
void ac_stations_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param) {
struct ac_station* station = (struct ac_station*)context;
ASSERT(station != NULL);
if (station->idtimeout == index) {
switch (station->timeoutaction) {
case AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE: {
capwap_logging_warning("The %s station has not completed the association in time", station->addrtext);
ac_stations_delete_station((struct ac_session_t*)param, station);
break;
}
}
}
}

View File

@ -1,128 +1,128 @@
#ifndef __AC_WLANS_HEADER__
#define __AC_WLANS_HEADER__
#include "ieee80211.h"
/* */
#define RADIOID_ANY 0
/* */
#define AC_WLANS_STATIONS_HASH_SIZE 256
#define AC_WLANS_STATIONS_KEY_SIZE MACADDRESS_EUI48_LENGTH
/* AC WLAN */
struct ac_wlan {
struct capwap_list_item* wlanitem;
struct ac_device* device;
uint8_t address[MACADDRESS_EUI48_LENGTH];
uint8_t wlanid;
/* CAPWAP Session */
struct ac_session_t* session;
uint32_t aidbitfield[IEEE80211_AID_BITFIELD_SIZE];
/* Stations reference */
struct capwap_list* stations;
/* Capability */
uint16_t capability;
uint8_t keyindex;
uint8_t keystatus;
uint16_t keylength;
uint8_t* key;
uint8_t grouptsc[CAPWAP_ADD_WLAN_GROUPTSC_LENGTH];
uint8_t qos;
uint8_t authmode;
uint8_t macmode;
uint8_t tunnelmode;
uint8_t suppressssid;
char ssid[IEEE80211_SSID_MAX_LENGTH + 1];
};
/* */
struct ac_device {
uint8_t radioid;
struct capwap_list* wlans;
/* Rates */
unsigned long supportedratescount;
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
};
/* */
struct ac_wlans {
struct ac_device devices[RADIOID_MAX_COUNT];
/* Stations */
struct capwap_hash* stations;
};
/* */
#define AC_STATION_TIMEOUT_ASSOCIATION_COMPLETE 30000
/* */
#define AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE 0x00000001
/* */
#define AC_STATION_FLAGS_ENABLED 0x00000001
#define AC_STATION_FLAGS_AUTHENTICATED 0x00000002
#define AC_STATION_FLAGS_ASSOCIATE 0x00000004
#define AC_STATION_FLAGS_AUTHORIZED 0x00000008
/* AC Station */
struct ac_station {
uint8_t address[MACADDRESS_EUI48_LENGTH];
char addrtext[CAPWAP_MACADDRESS_EUI48_BUFFER];
/* */
unsigned long flags;
/* Reference of WLAN */
struct ac_wlan* wlan;
struct capwap_list_item* wlanitem;
/* Reference of Session */
struct ac_session_t* session;
/* Timers */
int timeoutaction;
unsigned long idtimeout;
/* */
uint16_t capability;
uint16_t listeninterval;
uint16_t aid;
/* */
int supportedratescount;
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
/* Authentication */
uint16_t authalgorithm;
};
/* Management WLANS */
void ac_wlans_init(struct ac_session_t* session);
void ac_wlans_destroy(struct ac_session_t* session);
/* */
struct ac_wlan* ac_wlans_create_bssid(struct ac_device* device, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan);
int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan);
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid);
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid);
void ac_wlans_delete_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid);
void ac_wlans_free_bssid(struct ac_wlan* wlan);
/* Management Stations */
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
void ac_stations_delete_station(struct ac_session_t* session, struct ac_station* station);
void ac_stations_authorize_station(struct ac_session_t* session, struct ac_station* station);
void ac_stations_deauthorize_station(struct ac_session_t* session, struct ac_station* station);
/* */
void ac_stations_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param);
#endif /* __AC_WLANS_HEADER__ */
#ifndef __AC_WLANS_HEADER__
#define __AC_WLANS_HEADER__
#include "ieee80211.h"
/* */
#define RADIOID_ANY 0
/* */
#define AC_WLANS_STATIONS_HASH_SIZE 256
#define AC_WLANS_STATIONS_KEY_SIZE MACADDRESS_EUI48_LENGTH
/* AC WLAN */
struct ac_wlan {
struct capwap_list_item* wlanitem;
struct ac_device* device;
uint8_t address[MACADDRESS_EUI48_LENGTH];
uint8_t wlanid;
/* CAPWAP Session */
struct ac_session_t* session;
uint32_t aidbitfield[IEEE80211_AID_BITFIELD_SIZE];
/* Stations reference */
struct capwap_list* stations;
/* Capability */
uint16_t capability;
uint8_t keyindex;
uint8_t keystatus;
uint16_t keylength;
uint8_t* key;
uint8_t grouptsc[CAPWAP_ADD_WLAN_GROUPTSC_LENGTH];
uint8_t qos;
uint8_t authmode;
uint8_t macmode;
uint8_t tunnelmode;
uint8_t suppressssid;
char ssid[IEEE80211_SSID_MAX_LENGTH + 1];
};
/* */
struct ac_device {
uint8_t radioid;
struct capwap_list* wlans;
/* Rates */
unsigned long supportedratescount;
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
};
/* */
struct ac_wlans {
struct ac_device devices[RADIOID_MAX_COUNT];
/* Stations */
struct capwap_hash* stations;
};
/* */
#define AC_STATION_TIMEOUT_ASSOCIATION_COMPLETE 30000
/* */
#define AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE 0x00000001
/* */
#define AC_STATION_FLAGS_ENABLED 0x00000001
#define AC_STATION_FLAGS_AUTHENTICATED 0x00000002
#define AC_STATION_FLAGS_ASSOCIATE 0x00000004
#define AC_STATION_FLAGS_AUTHORIZED 0x00000008
/* AC Station */
struct ac_station {
uint8_t address[MACADDRESS_EUI48_LENGTH];
char addrtext[CAPWAP_MACADDRESS_EUI48_BUFFER];
/* */
unsigned long flags;
/* Reference of WLAN */
struct ac_wlan* wlan;
struct capwap_list_item* wlanitem;
/* Reference of Session */
struct ac_session_t* session;
/* Timers */
int timeoutaction;
unsigned long idtimeout;
/* */
uint16_t capability;
uint16_t listeninterval;
uint16_t aid;
/* */
int supportedratescount;
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
/* Authentication */
uint16_t authalgorithm;
};
/* Management WLANS */
void ac_wlans_init(struct ac_session_t* session);
void ac_wlans_destroy(struct ac_session_t* session);
/* */
struct ac_wlan* ac_wlans_create_bssid(struct ac_device* device, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan);
int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan);
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid);
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid);
void ac_wlans_delete_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid);
void ac_wlans_free_bssid(struct ac_wlan* wlan);
/* Management Stations */
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
void ac_stations_delete_station(struct ac_session_t* session, struct ac_station* station);
void ac_stations_authorize_station(struct ac_session_t* session, struct ac_station* station);
void ac_stations_deauthorize_station(struct ac_session_t* session, struct ac_station* station);
/* */
void ac_stations_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param);
#endif /* __AC_WLANS_HEADER__ */

View File

@ -1,18 +1,18 @@
KVERSION = $(shell uname -r)
obj-m += smartcapwap.o
smartcapwap-y := \
main.o \
netlinkapp.o \
capwap.o \
capwap_private.o \
station.o \
socket.o \
iface.o
all:
make -C /lib/modules/$(KVERSION)/build M="$(PWD)" modules
clean:
make -C /lib/modules/$(KVERSION)/build M="$(PWD)" clean
KVERSION = $(shell uname -r)
obj-m += smartcapwap.o
smartcapwap-y := \
main.o \
netlinkapp.o \
capwap.o \
capwap_private.o \
station.o \
socket.o \
iface.o
all:
make -C /lib/modules/$(KVERSION)/build M="$(PWD)" modules
clean:
make -C /lib/modules/$(KVERSION)/build M="$(PWD)" clean

File diff suppressed because it is too large Load Diff

View File

@ -1,124 +1,124 @@
#ifndef __KMOD_CAPWAP_HEADER__
#define __KMOD_CAPWAP_HEADER__
#include "capwap_rfc.h"
#include "socket.h"
/* */
#define MAX_MTU 9000
#define DEFAULT_MTU 1450
#define MIN_MTU 500
#define IEEE80211_MTU 7981
/* */
#define CAPWAP_FRAGMENT_QUEUE 16
/* */
#define CAPWAP_FRAGMENT_ENABLE 0x0001
#define CAPWAP_FRAGMENT_LRUQUEUE 0x0002
#define CAPWAP_FRAGMENT_LAST 0x0004
/* */
#define SKB_CAPWAP_FLAG_FROM_DATA_CHANNEL 0x0001
#define SKB_CAPWAP_FLAG_FROM_USER_SPACE 0x0002
#define SKB_CAPWAP_FLAG_FROM_AC_TAP 0x0004
#define SKB_CAPWAP_FLAG_FROM_IEEE80211 0x0008
#define SKB_CAPWAP_FLAG_SESSIONID 0x0100
#define SKB_CAPWAP_FLAG_RADIOID 0x0200
#define SKB_CAPWAP_FLAG_BINDING 0x0400
#define SKB_CAPWAP_FLAG_WIRELESSINFORMATION 0x0800
#define SKB_CAPWAP_FLAG_FRAGMENT 0x1000
struct sc_skb_capwap_cb {
uint16_t flags;
/* Session ID */
struct sc_capwap_sessionid_element sessionid;
/* Capwap information */
uint8_t radioid;
uint8_t binding;
/* Wireless Information */
uint8_t winfo_rssi;
uint8_t winfo_snr;
uint16_t winfo_rate;
/* Fragment */
uint16_t frag_offset;
uint16_t frag_length;
};
#define CAPWAP_SKB_CB(skb) ((struct sc_skb_capwap_cb*)((skb)->cb))
/* */
struct sc_capwap_fragment {
struct list_head lru_list;
uint8_t flags;
ktime_t tstamp;
uint16_t fragmentid;
struct sk_buff* fragments;
struct sk_buff* lastfragment;
int recvlength;
int totallength;
};
/* */
struct sc_capwap_fragment_queue {
spinlock_t lock;
struct list_head lru_list;
struct sc_capwap_fragment queues[CAPWAP_FRAGMENT_QUEUE];
};
/* */
struct sc_capwap_session {
uint16_t mtu;
union capwap_addr peeraddr;
struct sc_capwap_sessionid_element sessionid;
uint16_t fragmentid;
spinlock_t fragmentid_lock;
struct sc_capwap_fragment_queue fragments;
};
/* */
extern union capwap_addr sc_localaddr;
/* Dipendent implementation function */
void sc_capwap_recvpacket(struct sk_buff* skb);
struct sc_capwap_session* sc_capwap_recvunknownkeepalive(const union capwap_addr* sockaddr, const struct sc_capwap_sessionid_element* sessionid);
void sc_capwap_parsingdatapacket(struct sc_capwap_session* session, struct sk_buff* skb);
void sc_capwap_parsingmgmtpacket(struct sc_capwap_session* session, struct sk_buff* skb);
/* Indipendent implementation function */
int sc_capwap_bind(union capwap_addr* sockaddr);
void sc_capwap_initsession(struct sc_capwap_session* session);
void sc_capwap_freesession(struct sc_capwap_session* session);
uint16_t sc_capwap_newfragmentid(struct sc_capwap_session* session);
int sc_capwap_8023_to_80211(struct sk_buff* skb, const uint8_t* bssid);
int sc_capwap_80211_to_8023(struct sk_buff* skb);
void sc_capwap_sessionid_printf(const struct sc_capwap_sessionid_element* sessionid, char* string);
int sc_capwap_createkeepalive(struct sc_capwap_sessionid_element* sessionid, uint8_t* buffer, int size);
int sc_capwap_parsingpacket(struct sc_capwap_session* session, const union capwap_addr* sockaddr, struct sk_buff* skb);
struct sc_capwap_radio_addr* sc_capwap_setradiomacaddress(uint8_t* buffer, int size, uint8_t* bssid);
struct sc_capwap_wireless_information* sc_capwap_setwinfo_frameinfo(uint8_t* buffer, int size, uint8_t rssi, uint8_t snr, uint16_t rate);
struct sc_capwap_wireless_information* sc_capwap_setwinfo_destwlans(uint8_t* buffer, int size, uint16_t wlanidbitmap);
int sc_capwap_forwarddata(struct sc_capwap_session* session, uint8_t radioid, uint8_t binding, struct sk_buff* skb, uint32_t flags, struct sc_capwap_radio_addr* radioaddr, int radioaddrlength, struct sc_capwap_wireless_information* winfo, int winfolength);
/* Private funciotn */
#include "capwap_private.h"
#endif /* __KMOD_CAPWAP_HEADER__ */
#ifndef __KMOD_CAPWAP_HEADER__
#define __KMOD_CAPWAP_HEADER__
#include "capwap_rfc.h"
#include "socket.h"
/* */
#define MAX_MTU 9000
#define DEFAULT_MTU 1450
#define MIN_MTU 500
#define IEEE80211_MTU 7981
/* */
#define CAPWAP_FRAGMENT_QUEUE 16
/* */
#define CAPWAP_FRAGMENT_ENABLE 0x0001
#define CAPWAP_FRAGMENT_LRUQUEUE 0x0002
#define CAPWAP_FRAGMENT_LAST 0x0004
/* */
#define SKB_CAPWAP_FLAG_FROM_DATA_CHANNEL 0x0001
#define SKB_CAPWAP_FLAG_FROM_USER_SPACE 0x0002
#define SKB_CAPWAP_FLAG_FROM_AC_TAP 0x0004
#define SKB_CAPWAP_FLAG_FROM_IEEE80211 0x0008
#define SKB_CAPWAP_FLAG_SESSIONID 0x0100
#define SKB_CAPWAP_FLAG_RADIOID 0x0200
#define SKB_CAPWAP_FLAG_BINDING 0x0400
#define SKB_CAPWAP_FLAG_WIRELESSINFORMATION 0x0800
#define SKB_CAPWAP_FLAG_FRAGMENT 0x1000
struct sc_skb_capwap_cb {
uint16_t flags;
/* Session ID */
struct sc_capwap_sessionid_element sessionid;
/* Capwap information */
uint8_t radioid;
uint8_t binding;
/* Wireless Information */
uint8_t winfo_rssi;
uint8_t winfo_snr;
uint16_t winfo_rate;
/* Fragment */
uint16_t frag_offset;
uint16_t frag_length;
};
#define CAPWAP_SKB_CB(skb) ((struct sc_skb_capwap_cb*)((skb)->cb))
/* */
struct sc_capwap_fragment {
struct list_head lru_list;
uint8_t flags;
ktime_t tstamp;
uint16_t fragmentid;
struct sk_buff* fragments;
struct sk_buff* lastfragment;
int recvlength;
int totallength;
};
/* */
struct sc_capwap_fragment_queue {
spinlock_t lock;
struct list_head lru_list;
struct sc_capwap_fragment queues[CAPWAP_FRAGMENT_QUEUE];
};
/* */
struct sc_capwap_session {
uint16_t mtu;
union capwap_addr peeraddr;
struct sc_capwap_sessionid_element sessionid;
uint16_t fragmentid;
spinlock_t fragmentid_lock;
struct sc_capwap_fragment_queue fragments;
};
/* */
extern union capwap_addr sc_localaddr;
/* Dipendent implementation function */
void sc_capwap_recvpacket(struct sk_buff* skb);
struct sc_capwap_session* sc_capwap_recvunknownkeepalive(const union capwap_addr* sockaddr, const struct sc_capwap_sessionid_element* sessionid);
void sc_capwap_parsingdatapacket(struct sc_capwap_session* session, struct sk_buff* skb);
void sc_capwap_parsingmgmtpacket(struct sc_capwap_session* session, struct sk_buff* skb);
/* Indipendent implementation function */
int sc_capwap_bind(union capwap_addr* sockaddr);
void sc_capwap_initsession(struct sc_capwap_session* session);
void sc_capwap_freesession(struct sc_capwap_session* session);
uint16_t sc_capwap_newfragmentid(struct sc_capwap_session* session);
int sc_capwap_8023_to_80211(struct sk_buff* skb, const uint8_t* bssid);
int sc_capwap_80211_to_8023(struct sk_buff* skb);
void sc_capwap_sessionid_printf(const struct sc_capwap_sessionid_element* sessionid, char* string);
int sc_capwap_createkeepalive(struct sc_capwap_sessionid_element* sessionid, uint8_t* buffer, int size);
int sc_capwap_parsingpacket(struct sc_capwap_session* session, const union capwap_addr* sockaddr, struct sk_buff* skb);
struct sc_capwap_radio_addr* sc_capwap_setradiomacaddress(uint8_t* buffer, int size, uint8_t* bssid);
struct sc_capwap_wireless_information* sc_capwap_setwinfo_frameinfo(uint8_t* buffer, int size, uint8_t rssi, uint8_t snr, uint16_t rate);
struct sc_capwap_wireless_information* sc_capwap_setwinfo_destwlans(uint8_t* buffer, int size, uint16_t wlanidbitmap);
int sc_capwap_forwarddata(struct sc_capwap_session* session, uint8_t radioid, uint8_t binding, struct sk_buff* skb, uint32_t flags, struct sc_capwap_radio_addr* radioaddr, int radioaddrlength, struct sc_capwap_wireless_information* winfo, int winfolength);
/* Private funciotn */
#include "capwap_private.h"
#endif /* __KMOD_CAPWAP_HEADER__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,67 +1,67 @@
#ifndef __KMOD_CAPWAP_PRIVATE_HEADER__
#define __KMOD_CAPWAP_PRIVATE_HEADER__
/* */
struct sc_capwap_wlan {
int used;
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
uint8_t macmode;
uint8_t tunnelmode;
};
/* */
struct sc_capwap_session_priv {
struct sc_capwap_session session;
struct list_head list;
struct sc_capwap_session_priv* __rcu next_ipaddr;
struct sc_capwap_session_priv* __rcu next_sessionid;
struct list_head list_stations;
struct list_head list_connections;
/* */
int isolation;
uint8_t binding;
struct sc_capwap_wlan wlans[CAPWAP_RADIOID_MAX_COUNT][CAPWAP_WLANID_MAX_COUNT];
};
/* */
struct sc_capwap_workthread {
struct task_struct* thread;
struct sk_buff_head queue;
wait_queue_head_t waitevent;
};
/* */
int sc_capwap_init(void);
void sc_capwap_close(void);
/* */
void sc_capwap_update_lock(void);
void sc_capwap_update_unlock(void);
#ifdef CONFIG_PROVE_LOCKING
int sc_capwap_update_lock_is_locked(void);
#else
static inline int sc_capwap_update_lock_is_locked(void) { return 1; }
#endif
/* */
int sc_capwap_sendkeepalive(const struct sc_capwap_sessionid_element* sessionid);
/* */
int sc_capwap_newsession(const struct sc_capwap_sessionid_element* sessionid, uint8_t binding, uint16_t mtu);
int sc_capwap_deletesession(const struct sc_capwap_sessionid_element* sessionid);
/* */
int sc_capwap_addwlan(const struct sc_capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t wlanid, const uint8_t* bssid, uint8_t macmode, uint8_t tunnelmode);
int sc_capwap_removewlan(const struct sc_capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t wlanid);
/* */
int sc_capwap_authstation(const struct sc_capwap_sessionid_element* sessionid, const uint8_t* address, uint32_t ifindex, uint8_t radioid, uint8_t wlanid, uint16_t vlan);
int sc_capwap_deauthstation(const struct sc_capwap_sessionid_element* sessionid, const uint8_t* address);
#endif /* __KMOD_CAPWAP_PRIVATE_HEADER__ */
#ifndef __KMOD_CAPWAP_PRIVATE_HEADER__
#define __KMOD_CAPWAP_PRIVATE_HEADER__
/* */
struct sc_capwap_wlan {
int used;
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
uint8_t macmode;
uint8_t tunnelmode;
};
/* */
struct sc_capwap_session_priv {
struct sc_capwap_session session;
struct list_head list;
struct sc_capwap_session_priv* __rcu next_ipaddr;
struct sc_capwap_session_priv* __rcu next_sessionid;
struct list_head list_stations;
struct list_head list_connections;
/* */
int isolation;
uint8_t binding;
struct sc_capwap_wlan wlans[CAPWAP_RADIOID_MAX_COUNT][CAPWAP_WLANID_MAX_COUNT];
};
/* */
struct sc_capwap_workthread {
struct task_struct* thread;
struct sk_buff_head queue;
wait_queue_head_t waitevent;
};
/* */
int sc_capwap_init(void);
void sc_capwap_close(void);
/* */
void sc_capwap_update_lock(void);
void sc_capwap_update_unlock(void);
#ifdef CONFIG_PROVE_LOCKING
int sc_capwap_update_lock_is_locked(void);
#else
static inline int sc_capwap_update_lock_is_locked(void) { return 1; }
#endif
/* */
int sc_capwap_sendkeepalive(const struct sc_capwap_sessionid_element* sessionid);
/* */
int sc_capwap_newsession(const struct sc_capwap_sessionid_element* sessionid, uint8_t binding, uint16_t mtu);
int sc_capwap_deletesession(const struct sc_capwap_sessionid_element* sessionid);
/* */
int sc_capwap_addwlan(const struct sc_capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t wlanid, const uint8_t* bssid, uint8_t macmode, uint8_t tunnelmode);
int sc_capwap_removewlan(const struct sc_capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t wlanid);
/* */
int sc_capwap_authstation(const struct sc_capwap_sessionid_element* sessionid, const uint8_t* address, uint32_t ifindex, uint8_t radioid, uint8_t wlanid, uint16_t vlan);
int sc_capwap_deauthstation(const struct sc_capwap_sessionid_element* sessionid, const uint8_t* address);
#endif /* __KMOD_CAPWAP_PRIVATE_HEADER__ */

View File

@ -1,187 +1,187 @@
#ifndef __KMOD_CAPWAP_RFC_HEADER__
#define __KMOD_CAPWAP_RFC_HEADER__
#include <linux/types.h>
#include <asm/byteorder.h>
/* */
#define CAPWAP_RADIOID_MAX_COUNT 31
#define IS_VALID_RADIOID(x) ((x >= 1) && (x <= CAPWAP_RADIOID_MAX_COUNT))
#define CAPWAP_WLANID_MAX_COUNT 16
#define IS_VALID_WLANID(x) ((x >= 1) && (x <= CAPWAP_WLANID_MAX_COUNT))
/* */
#define CAPWAP_WIRELESS_BINDING_NONE 0
#define CAPWAP_WIRELESS_BINDING_IEEE80211 1
/* */
#define CAPWAP_ELEMENT_SESSIONID 35
/* */
#define CAPWAP_KEEPALIVE_SIZE (sizeof(struct sc_capwap_dtls_header) + \
sizeof(struct sc_capwap_header) + \
sizeof(struct sc_capwap_data_message) + \
sizeof(struct sc_capwap_message_element) + \
sizeof(struct sc_capwap_sessionid_element))
/* Preamble */
struct sc_capwap_preamble {
#if defined(__BIG_ENDIAN_BITFIELD)
uint8_t version: 4,
type: 4;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
uint8_t type: 4,
version: 4;
#endif
} __packed;
/* DTLS header */
struct sc_capwap_dtls_header {
struct sc_capwap_preamble preamble;
uint8_t reserved[3];
} __packed;
/* Plain header */
struct sc_capwap_header {
struct sc_capwap_preamble preamble;
#if defined(__BIG_ENDIAN_BITFIELD)
uint16_t hlen: 5,
rid: 5,
wbid: 5,
flag_t: 1;
uint8_t flag_f: 1,
flag_l: 1,
flag_w: 1,
flag_m: 1,
flag_k: 1,
flag_res: 3;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
uint16_t _rid_hi: 3,
hlen: 5,
flag_t: 1,
wbid: 5,
_rid_lo: 2;
uint8_t flag_res: 3,
flag_k: 1,
flag_m: 1,
flag_w: 1,
flag_l: 1,
flag_f: 1;
#endif
__be16 frag_id;
__be16 frag_off;
} __packed;
/* Mac Address */
#define CAPWAP_RADIO_EUI48_LENGTH_PADDED 8
#define CAPWAP_RADIO_EUI64_LENGTH_PADDED 12
#define CAPWAP_RADIO_MAX_LENGTH_PADDED 12
struct sc_capwap_radio_addr {
uint8_t length;
uint8_t addr[0];
} __packed;
/* Wireless Information */
#define CAPWAP_WINFO_FRAMEINFO_LENGTH_PADDED 8
#define CAPWAP_WINFO_DESTWLAN_LENGTH_PADDED 8
#define CAPWAP_WINFO_MAX_LENGTH_PADDED 8
struct sc_capwap_wireless_information {
uint8_t length;
} __packed;
/* IEEE802.11 Wireless Information */
struct sc_capwap_ieee80211_frame_info {
uint8_t rssi;
uint8_t snr;
__be16 rate;
} __packed;
/* Destination WLANs */
struct sc_capwap_destination_wlans {
__be16 wlanidbitmap;
__be16 reserved;
} __packed;
/* */
#define CAPWAP_HEADER_MAX_LENGTH (sizeof(struct sc_capwap_header) + CAPWAP_RADIO_MAX_LENGTH_PADDED + CAPWAP_WINFO_MAX_LENGTH_PADDED)
/* Data channel message */
struct sc_capwap_data_message {
__be16 length;
} __packed;
/* Message element */
struct sc_capwap_message_element {
__be16 type;
__be16 length;
} __packed;
/* Session id message element */
struct sc_capwap_sessionid_element {
union {
uint8_t id[16];
uint32_t id32[4];
};
} __packed;
/* */
#define MACADDRESS_EUI48_LENGTH 6
struct sc_capwap_macaddress_eui48 {
uint8_t addr[MACADDRESS_EUI48_LENGTH];
} __packed;
/* */
#define MACADDRESS_EUI64_LENGTH 8
struct sc_capwap_macaddress_eui64 {
uint8_t addr[MACADDRESS_EUI64_LENGTH];
} __packed;
/* Capwap preamble */
#define CAPWAP_PROTOCOL_VERSION 0
#define CAPWAP_PREAMBLE_HEADER 0
#define CAPWAP_PREAMBLE_DTLS_HEADER 1
#define CAPWAP_WIRELESS_BINDING_NONE 0
#define CAPWAP_WIRELESS_BINDING_IEEE80211 1
/* */
#define CAPWAP_KEEP_ALIVE_MAX_SIZE (sizeof(struct sc_capwap_header) + sizeof(struct sc_capwap_data_message) + sizeof(struct sc_capwap_message_element) + sizeof(struct sc_capwap_sessionid_element))
/* */
#define GET_VERSION_HEADER(x) ((x)->preamble.version)
#define SET_VERSION_HEADER(x, y) ((x)->preamble.version = (uint8_t)(y))
#define GET_TYPE_HEADER(x) ((x)->preamble.type)
#define SET_TYPE_HEADER(x, y) ((x)->preamble.type = (uint8_t)(y))
#define GET_HLEN_HEADER(x) ((x)->hlen)
#define SET_HLEN_HEADER(x, y) ((x)->hlen = (uint16_t)(y))
#if defined(__BIG_ENDIAN_BITFIELD)
#define GET_RID_HEADER(x) ((uint8_t)((x)->rid))
#define SET_RID_HEADER(x, y) ((x)->rid = (uint16_t)(y))
#elif defined(__LITTLE_ENDIAN_BITFIELD)
#define GET_RID_HEADER(x) ((uint8_t)((uint16_t)((x)->_rid_hi << 2 | (x)->_rid_lo)))
#define SET_RID_HEADER(x, y) ({ (x)->_rid_hi = (uint16_t)((y) >> 2); (x)->_rid_lo = (uint16_t)((y) & 0x0003); })
#endif
#define GET_WBID_HEADER(x) ((uint8_t)((x)->wbid))
#define SET_WBID_HEADER(x, y) ((x)->wbid = (uint16_t)(y))
#define IS_FLAG_T_HEADER(x) ((x)->flag_t)
#define SET_FLAG_T_HEADER(x, y) ((x)->flag_t = ((y) ? 1 : 0))
#define IS_FLAG_F_HEADER(x) ((x)->flag_f)
#define SET_FLAG_F_HEADER(x, y) ((x)->flag_f = ((y) ? 1 : 0))
#define IS_FLAG_L_HEADER(x) ((x)->flag_l)
#define SET_FLAG_L_HEADER(x, y) ((x)->flag_l = ((y) ? 1 : 0))
#define IS_FLAG_W_HEADER(x) ((x)->flag_w)
#define SET_FLAG_W_HEADER(x, y) ((x)->flag_w = ((y) ? 1 : 0))
#define IS_FLAG_M_HEADER(x) ((x)->flag_m)
#define SET_FLAG_M_HEADER(x, y) ((x)->flag_m = ((y) ? 1 : 0))
#define IS_FLAG_K_HEADER(x) ((x)->flag_k)
#define SET_FLAG_K_HEADER(x, y) ((x)->flag_k = ((y) ? 1 : 0))
/* IEEE 802.11 Add WLAN */
#define CAPWAP_ADD_WLAN_TUNNELMODE_LOCAL 0
#define CAPWAP_ADD_WLAN_TUNNELMODE_8023 1
#define CAPWAP_ADD_WLAN_TUNNELMODE_80211 2
#endif /* __KMOD_CAPWAP_RFC_HEADER__ */
#ifndef __KMOD_CAPWAP_RFC_HEADER__
#define __KMOD_CAPWAP_RFC_HEADER__
#include <linux/types.h>
#include <asm/byteorder.h>
/* */
#define CAPWAP_RADIOID_MAX_COUNT 31
#define IS_VALID_RADIOID(x) ((x >= 1) && (x <= CAPWAP_RADIOID_MAX_COUNT))
#define CAPWAP_WLANID_MAX_COUNT 16
#define IS_VALID_WLANID(x) ((x >= 1) && (x <= CAPWAP_WLANID_MAX_COUNT))
/* */
#define CAPWAP_WIRELESS_BINDING_NONE 0
#define CAPWAP_WIRELESS_BINDING_IEEE80211 1
/* */
#define CAPWAP_ELEMENT_SESSIONID 35
/* */
#define CAPWAP_KEEPALIVE_SIZE (sizeof(struct sc_capwap_dtls_header) + \
sizeof(struct sc_capwap_header) + \
sizeof(struct sc_capwap_data_message) + \
sizeof(struct sc_capwap_message_element) + \
sizeof(struct sc_capwap_sessionid_element))
/* Preamble */
struct sc_capwap_preamble {
#if defined(__BIG_ENDIAN_BITFIELD)
uint8_t version: 4,
type: 4;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
uint8_t type: 4,
version: 4;
#endif
} __packed;
/* DTLS header */
struct sc_capwap_dtls_header {
struct sc_capwap_preamble preamble;
uint8_t reserved[3];
} __packed;
/* Plain header */
struct sc_capwap_header {
struct sc_capwap_preamble preamble;
#if defined(__BIG_ENDIAN_BITFIELD)
uint16_t hlen: 5,
rid: 5,
wbid: 5,
flag_t: 1;
uint8_t flag_f: 1,
flag_l: 1,
flag_w: 1,
flag_m: 1,
flag_k: 1,
flag_res: 3;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
uint16_t _rid_hi: 3,
hlen: 5,
flag_t: 1,
wbid: 5,
_rid_lo: 2;
uint8_t flag_res: 3,
flag_k: 1,
flag_m: 1,
flag_w: 1,
flag_l: 1,
flag_f: 1;
#endif
__be16 frag_id;
__be16 frag_off;
} __packed;
/* Mac Address */
#define CAPWAP_RADIO_EUI48_LENGTH_PADDED 8
#define CAPWAP_RADIO_EUI64_LENGTH_PADDED 12
#define CAPWAP_RADIO_MAX_LENGTH_PADDED 12
struct sc_capwap_radio_addr {
uint8_t length;
uint8_t addr[0];
} __packed;
/* Wireless Information */
#define CAPWAP_WINFO_FRAMEINFO_LENGTH_PADDED 8
#define CAPWAP_WINFO_DESTWLAN_LENGTH_PADDED 8
#define CAPWAP_WINFO_MAX_LENGTH_PADDED 8
struct sc_capwap_wireless_information {
uint8_t length;
} __packed;
/* IEEE802.11 Wireless Information */
struct sc_capwap_ieee80211_frame_info {
uint8_t rssi;
uint8_t snr;
__be16 rate;
} __packed;
/* Destination WLANs */
struct sc_capwap_destination_wlans {
__be16 wlanidbitmap;
__be16 reserved;
} __packed;
/* */
#define CAPWAP_HEADER_MAX_LENGTH (sizeof(struct sc_capwap_header) + CAPWAP_RADIO_MAX_LENGTH_PADDED + CAPWAP_WINFO_MAX_LENGTH_PADDED)
/* Data channel message */
struct sc_capwap_data_message {
__be16 length;
} __packed;
/* Message element */
struct sc_capwap_message_element {
__be16 type;
__be16 length;
} __packed;
/* Session id message element */
struct sc_capwap_sessionid_element {
union {
uint8_t id[16];
uint32_t id32[4];
};
} __packed;
/* */
#define MACADDRESS_EUI48_LENGTH 6
struct sc_capwap_macaddress_eui48 {
uint8_t addr[MACADDRESS_EUI48_LENGTH];
} __packed;
/* */
#define MACADDRESS_EUI64_LENGTH 8
struct sc_capwap_macaddress_eui64 {
uint8_t addr[MACADDRESS_EUI64_LENGTH];
} __packed;
/* Capwap preamble */
#define CAPWAP_PROTOCOL_VERSION 0
#define CAPWAP_PREAMBLE_HEADER 0
#define CAPWAP_PREAMBLE_DTLS_HEADER 1
#define CAPWAP_WIRELESS_BINDING_NONE 0
#define CAPWAP_WIRELESS_BINDING_IEEE80211 1
/* */
#define CAPWAP_KEEP_ALIVE_MAX_SIZE (sizeof(struct sc_capwap_header) + sizeof(struct sc_capwap_data_message) + sizeof(struct sc_capwap_message_element) + sizeof(struct sc_capwap_sessionid_element))
/* */
#define GET_VERSION_HEADER(x) ((x)->preamble.version)
#define SET_VERSION_HEADER(x, y) ((x)->preamble.version = (uint8_t)(y))
#define GET_TYPE_HEADER(x) ((x)->preamble.type)
#define SET_TYPE_HEADER(x, y) ((x)->preamble.type = (uint8_t)(y))
#define GET_HLEN_HEADER(x) ((x)->hlen)
#define SET_HLEN_HEADER(x, y) ((x)->hlen = (uint16_t)(y))
#if defined(__BIG_ENDIAN_BITFIELD)
#define GET_RID_HEADER(x) ((uint8_t)((x)->rid))
#define SET_RID_HEADER(x, y) ((x)->rid = (uint16_t)(y))
#elif defined(__LITTLE_ENDIAN_BITFIELD)
#define GET_RID_HEADER(x) ((uint8_t)((uint16_t)((x)->_rid_hi << 2 | (x)->_rid_lo)))
#define SET_RID_HEADER(x, y) ({ (x)->_rid_hi = (uint16_t)((y) >> 2); (x)->_rid_lo = (uint16_t)((y) & 0x0003); })
#endif
#define GET_WBID_HEADER(x) ((uint8_t)((x)->wbid))
#define SET_WBID_HEADER(x, y) ((x)->wbid = (uint16_t)(y))
#define IS_FLAG_T_HEADER(x) ((x)->flag_t)
#define SET_FLAG_T_HEADER(x, y) ((x)->flag_t = ((y) ? 1 : 0))
#define IS_FLAG_F_HEADER(x) ((x)->flag_f)
#define SET_FLAG_F_HEADER(x, y) ((x)->flag_f = ((y) ? 1 : 0))
#define IS_FLAG_L_HEADER(x) ((x)->flag_l)
#define SET_FLAG_L_HEADER(x, y) ((x)->flag_l = ((y) ? 1 : 0))
#define IS_FLAG_W_HEADER(x) ((x)->flag_w)
#define SET_FLAG_W_HEADER(x, y) ((x)->flag_w = ((y) ? 1 : 0))
#define IS_FLAG_M_HEADER(x) ((x)->flag_m)
#define SET_FLAG_M_HEADER(x, y) ((x)->flag_m = ((y) ? 1 : 0))
#define IS_FLAG_K_HEADER(x) ((x)->flag_k)
#define SET_FLAG_K_HEADER(x, y) ((x)->flag_k = ((y) ? 1 : 0))
/* IEEE 802.11 Add WLAN */
#define CAPWAP_ADD_WLAN_TUNNELMODE_LOCAL 0
#define CAPWAP_ADD_WLAN_TUNNELMODE_8023 1
#define CAPWAP_ADD_WLAN_TUNNELMODE_80211 2
#endif /* __KMOD_CAPWAP_RFC_HEADER__ */

View File

@ -1,13 +1,13 @@
#ifndef __KMOD_CONFIG_HEADER__
#define __KMOD_CONFIG_HEADER__
#define DEBUGKMOD 1
#ifdef DEBUGKMOD
#define TRACEKMOD(s, args...) printk("(%d) " s, smp_processor_id(), ##args)
#else
#define TRACEKMOD(s, args...)
#endif
#endif /* __KMOD_CONFIG_HEADER__ */
#ifndef __KMOD_CONFIG_HEADER__
#define __KMOD_CONFIG_HEADER__
#define DEBUGKMOD 1
#ifdef DEBUGKMOD
#define TRACEKMOD(s, args...) printk("(%d) " s, smp_processor_id(), ##args)
#else
#define TRACEKMOD(s, args...)
#endif
#endif /* __KMOD_CONFIG_HEADER__ */

View File

@ -1,300 +1,300 @@
#include "config.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/smp.h>
#include "iface.h"
#include "station.h"
#include "capwap.h"
/* */
#define CAPWAP_IFACE_COUNT 8
#define CAPWAP_IFACE_HASH(x) ((x) % CAPWAP_IFACE_COUNT)
static LIST_HEAD(sc_iface_list);
static struct sc_netdev_priv* __rcu sc_iface_hash[CAPWAP_IFACE_COUNT];
/* */
static void sc_iface_netdev_uninit(struct net_device* dev) {
struct sc_netdev_priv* search;
struct sc_capwap_station* temp;
struct sc_capwap_station* station;
int hash = CAPWAP_IFACE_HASH(dev->ifindex);
struct sc_netdev_priv* priv = (struct sc_netdev_priv*)netdev_priv(dev);
TRACEKMOD("### sc_iface_netdev_uninit\n");
sc_capwap_update_lock();
/* Close stations */
list_for_each_entry_safe(station, temp, &priv->list_stations, list_dev) {
sc_stations_releaseconnection(station);
sc_stations_free(station);
}
/* */
if (!list_empty(&priv->list_stations)) {
TRACEKMOD("*** Bug: the list stations of interface is not empty\n");
}
if (!list_empty(&priv->list_connections)) {
TRACEKMOD("*** Bug: the list connections of interface is not empty\n");
}
/* Remove interface from hash */
search = rcu_dereference_protected(sc_iface_hash[hash], sc_capwap_update_lock_is_locked());
if (search) {
if (priv == search) {
netif_tx_lock_bh(dev);
netif_carrier_off(dev);
netif_tx_unlock_bh(dev);
rcu_assign_pointer(sc_iface_hash[hash], priv->next);
list_del_rcu(&priv->list);
synchronize_net();
dev_put(dev);
} else {
while (rcu_access_pointer(search->next) && (rcu_access_pointer(search->next) != priv)) {
search = rcu_dereference_protected(search->next, sc_capwap_update_lock_is_locked());
}
if (rcu_access_pointer(search->next)) {
netif_tx_lock_bh(dev);
netif_carrier_off(dev);
netif_tx_unlock_bh(dev);
rcu_assign_pointer(search->next, priv->next);
list_del_rcu(&priv->list);
synchronize_net();
dev_put(dev);
}
}
}
sc_capwap_update_unlock();
}
/* */
static int sc_iface_netdev_open(struct net_device* dev) {
TRACEKMOD("### sc_iface_netdev_open\n");
netif_start_queue(dev);
return 0;
}
/* */
static int sc_iface_netdev_stop(struct net_device* dev) {
TRACEKMOD("### sc_iface_netdev_stop\n");
netif_stop_queue(dev);
return 0;
}
/* */
static int sc_iface_netdev_tx(struct sk_buff* skb, struct net_device* dev) {
struct sc_netdev_priv* priv = (struct sc_netdev_priv*)netdev_priv(dev);
TRACEKMOD("### sc_iface_netdev_tx %d\n", smp_processor_id());
if (dev->flags & IFF_UP) {
/* Ignore 802.1ad */
if (skb->vlan_proto == htons(ETH_P_8021AD) || (eth_hdr(skb)->h_proto == htons(ETH_P_8021AD))) {
goto drop;
}
/* */
spin_lock(&priv->lock);
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
spin_unlock(&priv->lock);
/* */
CAPWAP_SKB_CB(skb)->flags = SKB_CAPWAP_FLAG_FROM_AC_TAP;
sc_capwap_recvpacket(skb);
} else {
goto drop;
}
return 0;
drop:
/* Drop packet */
kfree_skb(skb);
/* */
spin_lock(&priv->lock);
dev->stats.rx_dropped++;
spin_unlock(&priv->lock);
return 0;
}
/* */
static int sc_iface_netdev_change_mtu(struct net_device* dev, int new_mtu) {
TRACEKMOD("### sc_iface_netdev_change_mtu\n");
/* TODO */
return 0;
}
/* */
static void sc_iface_netdev_setup(struct net_device* dev) {
struct sc_netdev_priv* devpriv = (struct sc_netdev_priv*)netdev_priv(dev);
TRACEKMOD("### sc_iface_netdev_setup\n");
/* */
memset(devpriv, 0, sizeof(struct sc_netdev_priv));
devpriv->dev = dev;
spin_lock_init(&devpriv->lock);
INIT_LIST_HEAD(&devpriv->list_stations);
INIT_LIST_HEAD(&devpriv->list_connections);
}
/* */
static const struct net_device_ops capwap_netdev_ops = {
.ndo_uninit = sc_iface_netdev_uninit,
.ndo_open = sc_iface_netdev_open,
.ndo_stop = sc_iface_netdev_stop,
.ndo_start_xmit = sc_iface_netdev_tx,
.ndo_change_mtu = sc_iface_netdev_change_mtu,
};
/* */
int sc_iface_create(const char* ifname, uint16_t mtu) {
int err;
int hash;
struct net_device* dev;
struct sc_netdev_priv* priv;
TRACEKMOD("### sc_iface_create\n");
/* Create interface */
dev = alloc_netdev(sizeof(struct sc_netdev_priv), ifname, sc_iface_netdev_setup);
if (!dev) {
return -ENOMEM;
}
/* */
priv = (struct sc_netdev_priv*)netdev_priv(dev);
dev->netdev_ops = &capwap_netdev_ops;
ether_setup(dev);
eth_hw_addr_random(dev);
dev->mtu = mtu;
dev->hw_features = NETIF_F_HW_CSUM;
dev->features = dev->hw_features;
/* */
err = register_netdev(dev);
if (err) {
free_netdev(dev);
return err;
}
/* */
hash = CAPWAP_IFACE_HASH(dev->ifindex);
/* */
sc_capwap_update_lock();
list_add_rcu(&priv->list, &sc_iface_list);
priv->next = rcu_dereference_protected(sc_iface_hash[hash], sc_capwap_update_lock_is_locked());
rcu_assign_pointer(sc_iface_hash[hash], priv);
dev_hold(dev);
sc_capwap_update_unlock();
/* Enable carrier */
netif_tx_lock_bh(dev);
netif_carrier_on(dev);
netif_tx_unlock_bh(dev);
return dev->ifindex;
}
/* */
int sc_iface_delete(uint32_t ifindex) {
struct sc_netdev_priv* priv;
struct net_device* dev = NULL;
TRACEKMOD("### sc_iface_delete\n");
rcu_read_lock();
/* Search device */
priv = sc_iface_search(ifindex);
if (priv) {
dev = priv->dev;
}
rcu_read_unlock();
/* */
if (!dev) {
return -ENOENT;
}
/* Unregister device */
unregister_netdev(dev);
free_netdev(dev);
return 0;
}
/* */
struct sc_netdev_priv* sc_iface_search(uint32_t ifindex) {
struct sc_netdev_priv* priv;
TRACEKMOD("### sc_iface_search\n");
priv = rcu_dereference_check(sc_iface_hash[CAPWAP_IFACE_HASH(ifindex)], lockdep_is_held(&sc_iface_mutex));
while (priv) {
if (priv->dev->ifindex == ifindex) {
break;
}
/* */
priv = rcu_dereference_check(priv->next, lockdep_is_held(&sc_iface_mutex));
}
return priv;
}
/* */
void sc_iface_closeall(void) {
struct sc_netdev_priv* priv;
TRACEKMOD("### sc_iface_closeall\n");
for (;;) {
struct net_device* dev = NULL;
rcu_read_lock();
/* Get device */
priv = list_first_or_null_rcu(&sc_iface_list, struct sc_netdev_priv, list);
if (priv) {
dev = priv->dev;
}
rcu_read_unlock();
/* */
if (!dev) {
break;
}
/* Unregister device */
unregister_netdev(dev);
free_netdev(dev);
}
}
#include "config.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/smp.h>
#include "iface.h"
#include "station.h"
#include "capwap.h"
/* */
#define CAPWAP_IFACE_COUNT 8
#define CAPWAP_IFACE_HASH(x) ((x) % CAPWAP_IFACE_COUNT)
static LIST_HEAD(sc_iface_list);
static struct sc_netdev_priv* __rcu sc_iface_hash[CAPWAP_IFACE_COUNT];
/* */
static void sc_iface_netdev_uninit(struct net_device* dev) {
struct sc_netdev_priv* search;
struct sc_capwap_station* temp;
struct sc_capwap_station* station;
int hash = CAPWAP_IFACE_HASH(dev->ifindex);
struct sc_netdev_priv* priv = (struct sc_netdev_priv*)netdev_priv(dev);
TRACEKMOD("### sc_iface_netdev_uninit\n");
sc_capwap_update_lock();
/* Close stations */
list_for_each_entry_safe(station, temp, &priv->list_stations, list_dev) {
sc_stations_releaseconnection(station);
sc_stations_free(station);
}
/* */
if (!list_empty(&priv->list_stations)) {
TRACEKMOD("*** Bug: the list stations of interface is not empty\n");
}
if (!list_empty(&priv->list_connections)) {
TRACEKMOD("*** Bug: the list connections of interface is not empty\n");
}
/* Remove interface from hash */
search = rcu_dereference_protected(sc_iface_hash[hash], sc_capwap_update_lock_is_locked());
if (search) {
if (priv == search) {
netif_tx_lock_bh(dev);
netif_carrier_off(dev);
netif_tx_unlock_bh(dev);
rcu_assign_pointer(sc_iface_hash[hash], priv->next);
list_del_rcu(&priv->list);
synchronize_net();
dev_put(dev);
} else {
while (rcu_access_pointer(search->next) && (rcu_access_pointer(search->next) != priv)) {
search = rcu_dereference_protected(search->next, sc_capwap_update_lock_is_locked());
}
if (rcu_access_pointer(search->next)) {
netif_tx_lock_bh(dev);
netif_carrier_off(dev);
netif_tx_unlock_bh(dev);
rcu_assign_pointer(search->next, priv->next);
list_del_rcu(&priv->list);
synchronize_net();
dev_put(dev);
}
}
}
sc_capwap_update_unlock();
}
/* */
static int sc_iface_netdev_open(struct net_device* dev) {
TRACEKMOD("### sc_iface_netdev_open\n");
netif_start_queue(dev);
return 0;
}
/* */
static int sc_iface_netdev_stop(struct net_device* dev) {
TRACEKMOD("### sc_iface_netdev_stop\n");
netif_stop_queue(dev);
return 0;
}
/* */
static int sc_iface_netdev_tx(struct sk_buff* skb, struct net_device* dev) {
struct sc_netdev_priv* priv = (struct sc_netdev_priv*)netdev_priv(dev);
TRACEKMOD("### sc_iface_netdev_tx %d\n", smp_processor_id());
if (dev->flags & IFF_UP) {
/* Ignore 802.1ad */
if (skb->vlan_proto == htons(ETH_P_8021AD) || (eth_hdr(skb)->h_proto == htons(ETH_P_8021AD))) {
goto drop;
}
/* */
spin_lock(&priv->lock);
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
spin_unlock(&priv->lock);
/* */
CAPWAP_SKB_CB(skb)->flags = SKB_CAPWAP_FLAG_FROM_AC_TAP;
sc_capwap_recvpacket(skb);
} else {
goto drop;
}
return 0;
drop:
/* Drop packet */
kfree_skb(skb);
/* */
spin_lock(&priv->lock);
dev->stats.rx_dropped++;
spin_unlock(&priv->lock);
return 0;
}
/* */
static int sc_iface_netdev_change_mtu(struct net_device* dev, int new_mtu) {
TRACEKMOD("### sc_iface_netdev_change_mtu\n");
/* TODO */
return 0;
}
/* */
static void sc_iface_netdev_setup(struct net_device* dev) {
struct sc_netdev_priv* devpriv = (struct sc_netdev_priv*)netdev_priv(dev);
TRACEKMOD("### sc_iface_netdev_setup\n");
/* */
memset(devpriv, 0, sizeof(struct sc_netdev_priv));
devpriv->dev = dev;
spin_lock_init(&devpriv->lock);
INIT_LIST_HEAD(&devpriv->list_stations);
INIT_LIST_HEAD(&devpriv->list_connections);
}
/* */
static const struct net_device_ops capwap_netdev_ops = {
.ndo_uninit = sc_iface_netdev_uninit,
.ndo_open = sc_iface_netdev_open,
.ndo_stop = sc_iface_netdev_stop,
.ndo_start_xmit = sc_iface_netdev_tx,
.ndo_change_mtu = sc_iface_netdev_change_mtu,
};
/* */
int sc_iface_create(const char* ifname, uint16_t mtu) {
int err;
int hash;
struct net_device* dev;
struct sc_netdev_priv* priv;
TRACEKMOD("### sc_iface_create\n");
/* Create interface */
dev = alloc_netdev(sizeof(struct sc_netdev_priv), ifname, sc_iface_netdev_setup);
if (!dev) {
return -ENOMEM;
}
/* */
priv = (struct sc_netdev_priv*)netdev_priv(dev);
dev->netdev_ops = &capwap_netdev_ops;
ether_setup(dev);
eth_hw_addr_random(dev);
dev->mtu = mtu;
dev->hw_features = NETIF_F_HW_CSUM;
dev->features = dev->hw_features;
/* */
err = register_netdev(dev);
if (err) {
free_netdev(dev);
return err;
}
/* */
hash = CAPWAP_IFACE_HASH(dev->ifindex);
/* */
sc_capwap_update_lock();
list_add_rcu(&priv->list, &sc_iface_list);
priv->next = rcu_dereference_protected(sc_iface_hash[hash], sc_capwap_update_lock_is_locked());
rcu_assign_pointer(sc_iface_hash[hash], priv);
dev_hold(dev);
sc_capwap_update_unlock();
/* Enable carrier */
netif_tx_lock_bh(dev);
netif_carrier_on(dev);
netif_tx_unlock_bh(dev);
return dev->ifindex;
}
/* */
int sc_iface_delete(uint32_t ifindex) {
struct sc_netdev_priv* priv;
struct net_device* dev = NULL;
TRACEKMOD("### sc_iface_delete\n");
rcu_read_lock();
/* Search device */
priv = sc_iface_search(ifindex);
if (priv) {
dev = priv->dev;
}
rcu_read_unlock();
/* */
if (!dev) {
return -ENOENT;
}
/* Unregister device */
unregister_netdev(dev);
free_netdev(dev);
return 0;
}
/* */
struct sc_netdev_priv* sc_iface_search(uint32_t ifindex) {
struct sc_netdev_priv* priv;
TRACEKMOD("### sc_iface_search\n");
priv = rcu_dereference_check(sc_iface_hash[CAPWAP_IFACE_HASH(ifindex)], lockdep_is_held(&sc_iface_mutex));
while (priv) {
if (priv->dev->ifindex == ifindex) {
break;
}
/* */
priv = rcu_dereference_check(priv->next, lockdep_is_held(&sc_iface_mutex));
}
return priv;
}
/* */
void sc_iface_closeall(void) {
struct sc_netdev_priv* priv;
TRACEKMOD("### sc_iface_closeall\n");
for (;;) {
struct net_device* dev = NULL;
rcu_read_lock();
/* Get device */
priv = list_first_or_null_rcu(&sc_iface_list, struct sc_netdev_priv, list);
if (priv) {
dev = priv->dev;
}
rcu_read_unlock();
/* */
if (!dev) {
break;
}
/* Unregister device */
unregister_netdev(dev);
free_netdev(dev);
}
}

View File

@ -1,27 +1,27 @@
#ifndef __KMOD_AC_IFACE_HEADER__
#define __KMOD_AC_IFACE_HEADER__
/* */
struct sc_netdev_priv {
struct list_head list;
struct net_device* dev;
spinlock_t lock;
struct list_head list_stations;
struct list_head list_connections;
struct sc_netdev_priv* __rcu next;
};
/* */
int sc_iface_create(const char* ifname, uint16_t mtu);
int sc_iface_delete(uint32_t ifindex);
/* */
struct sc_netdev_priv* sc_iface_search(uint32_t ifindex);
/* */
void sc_iface_closeall(void);
#endif /* __KMOD_AC_IFACE_HEADER__ */
#ifndef __KMOD_AC_IFACE_HEADER__
#define __KMOD_AC_IFACE_HEADER__
/* */
struct sc_netdev_priv {
struct list_head list;
struct net_device* dev;
spinlock_t lock;
struct list_head list_stations;
struct list_head list_connections;
struct sc_netdev_priv* __rcu next;
};
/* */
int sc_iface_create(const char* ifname, uint16_t mtu);
int sc_iface_delete(uint32_t ifindex);
/* */
struct sc_netdev_priv* sc_iface_search(uint32_t ifindex);
/* */
void sc_iface_closeall(void);
#endif /* __KMOD_AC_IFACE_HEADER__ */

View File

@ -1,32 +1,32 @@
#include "config.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include "netlinkapp.h"
/* */
static int __init smartcapwap_ac_init(void) {
int ret;
TRACEKMOD("### smartcapwap_ac_init\n");
/* Initialize netlink */
ret = sc_netlink_init();
if (ret) {
return ret;
}
return ret;
}
module_init(smartcapwap_ac_init);
/* */
static void __exit smartcapwap_ac_exit(void) {
TRACEKMOD("### smartcapwap_ac_exit\n");
sc_netlink_exit();
}
module_exit(smartcapwap_ac_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Massimo Vellucci <vemax78@gmail.com>");
MODULE_DESCRIPTION("SmartCAPWAP AC Data Channel Module");
#include "config.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include "netlinkapp.h"
/* */
static int __init smartcapwap_ac_init(void) {
int ret;
TRACEKMOD("### smartcapwap_ac_init\n");
/* Initialize netlink */
ret = sc_netlink_init();
if (ret) {
return ret;
}
return ret;
}
module_init(smartcapwap_ac_init);
/* */
static void __exit smartcapwap_ac_exit(void) {
TRACEKMOD("### smartcapwap_ac_exit\n");
sc_netlink_exit();
}
module_exit(smartcapwap_ac_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Massimo Vellucci <vemax78@gmail.com>");
MODULE_DESCRIPTION("SmartCAPWAP AC Data Channel Module");

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,15 @@
#ifndef __KMOD_AC_NETLINKAPP_HEADER__
#define __KMOD_AC_NETLINKAPP_HEADER__
#include "capwap_rfc.h"
#include "socket.h"
/* */
int sc_netlink_init(void);
void sc_netlink_exit(void);
/* */
int sc_netlink_notify_recv_keepalive(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid);
int sc_netlink_notify_recv_data(struct sc_capwap_sessionid_element* sessionid, uint8_t* packet, int length);
#endif /* __KMOD_AC_NETLINKAPP_HEADER__ */
#ifndef __KMOD_AC_NETLINKAPP_HEADER__
#define __KMOD_AC_NETLINKAPP_HEADER__
#include "capwap_rfc.h"
#include "socket.h"
/* */
int sc_netlink_init(void);
void sc_netlink_exit(void);
/* */
int sc_netlink_notify_recv_keepalive(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid);
int sc_netlink_notify_recv_data(struct sc_capwap_sessionid_element* sessionid, uint8_t* packet, int length);
#endif /* __KMOD_AC_NETLINKAPP_HEADER__ */

View File

@ -1,73 +1,73 @@
#ifndef __AC_NLSMARTCAPWAP_HEADER__
#define __AC_NLSMARTCAPWAP_HEADER__
/* */
#define NLSMARTCAPWAP_GENL_NAME "smartcapwap_ac"
/* */
#define NLSMARTCAPWAP_FLAGS_TUNNEL_8023 0x00000001
/* */
enum sc_netlink_attrs {
NLSMARTCAPWAP_ATTR_UNSPEC,
NLSMARTCAPWAP_ATTR_FLAGS,
NLSMARTCAPWAP_ATTR_SESSION_ID,
NLSMARTCAPWAP_ATTR_RADIOID,
NLSMARTCAPWAP_ATTR_WLANID,
NLSMARTCAPWAP_ATTR_BINDING,
NLSMARTCAPWAP_ATTR_MACMODE,
NLSMARTCAPWAP_ATTR_TUNNELMODE,
NLSMARTCAPWAP_ATTR_ADDRESS,
NLSMARTCAPWAP_ATTR_MTU,
NLSMARTCAPWAP_ATTR_DATA_FRAME,
NLSMARTCAPWAP_ATTR_IFPHY_NAME,
NLSMARTCAPWAP_ATTR_IFPHY_INDEX,
NLSMARTCAPWAP_ATTR_MACADDRESS,
NLSMARTCAPWAP_ATTR_BSSID,
NLSMARTCAPWAP_ATTR_VLAN,
/* Last attribute */
__NLSMARTCAPWAP_ATTR_AFTER_LAST,
NLSMARTCAPWAP_ATTR_MAX = __NLSMARTCAPWAP_ATTR_AFTER_LAST - 1
};
/* */
enum sc_netlink_commands {
NLSMARTCAPWAP_CMD_UNSPEC,
NLSMARTCAPWAP_CMD_LINK,
NLSMARTCAPWAP_CMD_ADD_IFACE,
NLSMARTCAPWAP_CMD_DELETE_IFACE,
NLSMARTCAPWAP_CMD_BIND,
NLSMARTCAPWAP_CMD_SEND_KEEPALIVE,
NLSMARTCAPWAP_CMD_RECV_KEEPALIVE,
NLSMARTCAPWAP_CMD_NEW_SESSION,
NLSMARTCAPWAP_CMD_DELETE_SESSION,
NLSMARTCAPWAP_CMD_ADD_WLAN,
NLSMARTCAPWAP_CMD_REMOVE_WLAN,
NLSMARTCAPWAP_CMD_SEND_DATA,
NLSMARTCAPWAP_CMD_RECV_DATA,
NLSMARTCAPWAP_CMD_AUTH_STATION,
NLSMARTCAPWAP_CMD_DEAUTH_STATION,
/* Last command */
__NLSMARTCAPWAP_CMD_AFTER_LAST,
NLSMARTCAPWAP_CMD_MAX = __NLSMARTCAPWAP_CMD_AFTER_LAST - 1
};
#endif /* __AC_NLSMARTCAPWAP_HEADER__ */
#ifndef __AC_NLSMARTCAPWAP_HEADER__
#define __AC_NLSMARTCAPWAP_HEADER__
/* */
#define NLSMARTCAPWAP_GENL_NAME "smartcapwap_ac"
/* */
#define NLSMARTCAPWAP_FLAGS_TUNNEL_8023 0x00000001
/* */
enum sc_netlink_attrs {
NLSMARTCAPWAP_ATTR_UNSPEC,
NLSMARTCAPWAP_ATTR_FLAGS,
NLSMARTCAPWAP_ATTR_SESSION_ID,
NLSMARTCAPWAP_ATTR_RADIOID,
NLSMARTCAPWAP_ATTR_WLANID,
NLSMARTCAPWAP_ATTR_BINDING,
NLSMARTCAPWAP_ATTR_MACMODE,
NLSMARTCAPWAP_ATTR_TUNNELMODE,
NLSMARTCAPWAP_ATTR_ADDRESS,
NLSMARTCAPWAP_ATTR_MTU,
NLSMARTCAPWAP_ATTR_DATA_FRAME,
NLSMARTCAPWAP_ATTR_IFPHY_NAME,
NLSMARTCAPWAP_ATTR_IFPHY_INDEX,
NLSMARTCAPWAP_ATTR_MACADDRESS,
NLSMARTCAPWAP_ATTR_BSSID,
NLSMARTCAPWAP_ATTR_VLAN,
/* Last attribute */
__NLSMARTCAPWAP_ATTR_AFTER_LAST,
NLSMARTCAPWAP_ATTR_MAX = __NLSMARTCAPWAP_ATTR_AFTER_LAST - 1
};
/* */
enum sc_netlink_commands {
NLSMARTCAPWAP_CMD_UNSPEC,
NLSMARTCAPWAP_CMD_LINK,
NLSMARTCAPWAP_CMD_ADD_IFACE,
NLSMARTCAPWAP_CMD_DELETE_IFACE,
NLSMARTCAPWAP_CMD_BIND,
NLSMARTCAPWAP_CMD_SEND_KEEPALIVE,
NLSMARTCAPWAP_CMD_RECV_KEEPALIVE,
NLSMARTCAPWAP_CMD_NEW_SESSION,
NLSMARTCAPWAP_CMD_DELETE_SESSION,
NLSMARTCAPWAP_CMD_ADD_WLAN,
NLSMARTCAPWAP_CMD_REMOVE_WLAN,
NLSMARTCAPWAP_CMD_SEND_DATA,
NLSMARTCAPWAP_CMD_RECV_DATA,
NLSMARTCAPWAP_CMD_AUTH_STATION,
NLSMARTCAPWAP_CMD_DEAUTH_STATION,
/* Last command */
__NLSMARTCAPWAP_CMD_AFTER_LAST,
NLSMARTCAPWAP_CMD_MAX = __NLSMARTCAPWAP_CMD_AFTER_LAST - 1
};
#endif /* __AC_NLSMARTCAPWAP_HEADER__ */

View File

@ -1,227 +1,227 @@
#include "config.h"
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/socket.h>
#include <linux/kthread.h>
#include <linux/net.h>
#include <linux/if_ether.h>
#include <linux/udp.h>
#include <net/ipv6.h>
#include <net/sock.h>
#include <net/udp.h>
#include "socket.h"
#include "capwap.h"
/* Socket */
#define SOCKET_COUNT 2
static struct socket* sc_sockets[SOCKET_COUNT];
/* */
int sc_socket_recvpacket(struct sock* sk, struct sk_buff* skb) {
TRACEKMOD("### sc_socket_recvpacket\n");
/* */
CAPWAP_SKB_CB(skb)->flags = SKB_CAPWAP_FLAG_FROM_DATA_CHANNEL;
/* */
sc_capwap_recvpacket(skb);
return 0;
}
/* */
static int sc_socket_create(int type, union capwap_addr* sockaddr, uint16_t protocol) {
int ret;
TRACEKMOD("### sc_socket_create\n");
/* Create socket */
ret = sock_create_kern(sockaddr->ss.ss_family, SOCK_DGRAM, protocol, &sc_sockets[type]);
if (ret) {
return ret;
}
/* Bind to interface */
ret = kernel_bind(sc_sockets[type], &sockaddr->sa, sizeof(union capwap_addr));
if (ret) {
goto failure;
}
/* Set callback */
udp_sk(sc_sockets[type]->sk)->encap_type = 1;
udp_sk(sc_sockets[type]->sk)->encap_rcv = sc_socket_recvpacket;
/* */
if (!((sockaddr->ss.ss_family == AF_INET) ? sockaddr->sin.sin_port : sockaddr->sin6.sin6_port)) {
union capwap_addr localaddr;
int localaddrsize = sizeof(union capwap_addr);
/* Retrieve port */
ret = kernel_getsockname(sc_sockets[type], &localaddr.sa, &localaddrsize);
if (ret) {
goto failure;
}
/* */
if ((sockaddr->ss.ss_family == AF_INET) && (localaddr.ss.ss_family == AF_INET)) {
sockaddr->sin.sin_port = localaddr.sin.sin_port;
} else if ((sockaddr->ss.ss_family == AF_INET6) && (localaddr.ss.ss_family == AF_INET6)) {
sockaddr->sin6.sin6_port = localaddr.sin6.sin6_port;
} else {
ret = -EFAULT;
goto failure;
}
}
return 0;
failure:
sock_release(sc_sockets[type]);
sc_sockets[type] = 0;
return ret;
}
/* */
int sc_socket_getpeeraddr(struct sk_buff* skb, union capwap_addr* peeraddr) {
unsigned char* nethdr;
TRACEKMOD("### sc_socket_getpeeraddr\n");
/* */
nethdr = skb_network_header(skb);
if (!nethdr) {
return -EINVAL;
}
/* */
switch (ntohs(skb->protocol)) {
case ETH_P_IP: {
/* Validate IPv4 header */
if ((nethdr[0] & 0xf0) != 0x40) {
return -EINVAL;
}
/* Retrieve address */
peeraddr->sin.sin_family = AF_INET;
peeraddr->sin.sin_addr.s_addr = ((struct iphdr*)nethdr)->saddr;
peeraddr->sin.sin_port = udp_hdr(skb)->source;
break;
}
case ETH_P_IPV6: {
/* Validate IPv6 header */
if ((nethdr[0] & 0xf0) != 0x60) {
return -EINVAL;
}
/* Retrieve address */
peeraddr->sin6.sin6_family = AF_INET6;
memcpy(&peeraddr->sin6.sin6_addr, &((struct ipv6hdr*)nethdr)->saddr, sizeof(struct in6_addr));
peeraddr->sin6.sin6_port = udp_hdr(skb)->source;
break;
}
default: {
return -EINVAL;
}
}
return 0;
}
/* */
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr) {
struct kvec vec;
struct msghdr msg;
TRACEKMOD("### sc_socket_send\n");
/* */
vec.iov_base = buffer;
vec.iov_len = length;
/* */
memset(&msg, 0, sizeof(struct msghdr));
msg.msg_name = sockaddr;
msg.msg_namelen = sizeof(union capwap_addr);
msg.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT;
/* */
return kernel_sendmsg(sc_sockets[type], &msg, &vec, 1, length);
}
/* */
int sc_socket_init(void) {
TRACEKMOD("### sc_socket_init\n");
memset(sc_sockets, 0, sizeof(sc_sockets));
return 0;
}
/* */
int sc_socket_bind(union capwap_addr* sockaddr) {
int ret;
TRACEKMOD("### sc_socket_bind\n");
/* */
if (sc_sockets[SOCKET_UDP] || sc_sockets[SOCKET_UDPLITE]) {
return -EBUSY;
}
/* UDP socket */
ret = sc_socket_create(SOCKET_UDP, sockaddr, IPPROTO_UDP);
if (ret) {
goto failure;
}
/* UDPLite socket */
ret = sc_socket_create(SOCKET_UDPLITE, sockaddr, IPPROTO_UDPLITE);
if (ret) {
goto failure;
}
/* */
udp_encap_enable();
if (sockaddr->ss.ss_family == AF_INET6) {
udpv6_encap_enable();
}
return 0;
failure:
sc_socket_close();
return ret;
}
/* */
void sc_socket_close(void) {
TRACEKMOD("### sc_socket_close\n");
/* Close sockets */
if (sc_sockets[SOCKET_UDP]) {
kernel_sock_shutdown(sc_sockets[SOCKET_UDP], SHUT_RDWR);
sock_release(sc_sockets[SOCKET_UDP]);
}
if (sc_sockets[SOCKET_UDPLITE]) {
kernel_sock_shutdown(sc_sockets[SOCKET_UDPLITE], SHUT_RDWR);
sock_release(sc_sockets[SOCKET_UDPLITE]);
}
memset(sc_sockets, 0, sizeof(sc_sockets));
}
/* */
int sc_addr_compare(const union capwap_addr* addr1, const union capwap_addr* addr2) {
TRACEKMOD("### sc_addr_compare\n");
if (addr1->ss.ss_family == addr2->ss.ss_family) {
if (addr1->ss.ss_family == AF_INET) {
return (((addr1->sin.sin_addr.s_addr == addr2->sin.sin_addr.s_addr) && (addr1->sin.sin_port == addr2->sin.sin_port)) ? 0 : -1);
} else if (addr1->ss.ss_family == AF_INET6) {
return ((!memcmp(&addr1->sin6.sin6_addr, &addr2->sin6.sin6_addr, sizeof(struct in6_addr)) && (addr1->sin6.sin6_port == addr2->sin6.sin6_port)) ? 0 : -1);
}
}
return -1;
}
#include "config.h"
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/socket.h>
#include <linux/kthread.h>
#include <linux/net.h>
#include <linux/if_ether.h>
#include <linux/udp.h>
#include <net/ipv6.h>
#include <net/sock.h>
#include <net/udp.h>
#include "socket.h"
#include "capwap.h"
/* Socket */
#define SOCKET_COUNT 2
static struct socket* sc_sockets[SOCKET_COUNT];
/* */
int sc_socket_recvpacket(struct sock* sk, struct sk_buff* skb) {
TRACEKMOD("### sc_socket_recvpacket\n");
/* */
CAPWAP_SKB_CB(skb)->flags = SKB_CAPWAP_FLAG_FROM_DATA_CHANNEL;
/* */
sc_capwap_recvpacket(skb);
return 0;
}
/* */
static int sc_socket_create(int type, union capwap_addr* sockaddr, uint16_t protocol) {
int ret;
TRACEKMOD("### sc_socket_create\n");
/* Create socket */
ret = sock_create_kern(sockaddr->ss.ss_family, SOCK_DGRAM, protocol, &sc_sockets[type]);
if (ret) {
return ret;
}
/* Bind to interface */
ret = kernel_bind(sc_sockets[type], &sockaddr->sa, sizeof(union capwap_addr));
if (ret) {
goto failure;
}
/* Set callback */
udp_sk(sc_sockets[type]->sk)->encap_type = 1;
udp_sk(sc_sockets[type]->sk)->encap_rcv = sc_socket_recvpacket;
/* */
if (!((sockaddr->ss.ss_family == AF_INET) ? sockaddr->sin.sin_port : sockaddr->sin6.sin6_port)) {
union capwap_addr localaddr;
int localaddrsize = sizeof(union capwap_addr);
/* Retrieve port */
ret = kernel_getsockname(sc_sockets[type], &localaddr.sa, &localaddrsize);
if (ret) {
goto failure;
}
/* */
if ((sockaddr->ss.ss_family == AF_INET) && (localaddr.ss.ss_family == AF_INET)) {
sockaddr->sin.sin_port = localaddr.sin.sin_port;
} else if ((sockaddr->ss.ss_family == AF_INET6) && (localaddr.ss.ss_family == AF_INET6)) {
sockaddr->sin6.sin6_port = localaddr.sin6.sin6_port;
} else {
ret = -EFAULT;
goto failure;
}
}
return 0;
failure:
sock_release(sc_sockets[type]);
sc_sockets[type] = 0;
return ret;
}
/* */
int sc_socket_getpeeraddr(struct sk_buff* skb, union capwap_addr* peeraddr) {
unsigned char* nethdr;
TRACEKMOD("### sc_socket_getpeeraddr\n");
/* */
nethdr = skb_network_header(skb);
if (!nethdr) {
return -EINVAL;
}
/* */
switch (ntohs(skb->protocol)) {
case ETH_P_IP: {
/* Validate IPv4 header */
if ((nethdr[0] & 0xf0) != 0x40) {
return -EINVAL;
}
/* Retrieve address */
peeraddr->sin.sin_family = AF_INET;
peeraddr->sin.sin_addr.s_addr = ((struct iphdr*)nethdr)->saddr;
peeraddr->sin.sin_port = udp_hdr(skb)->source;
break;
}
case ETH_P_IPV6: {
/* Validate IPv6 header */
if ((nethdr[0] & 0xf0) != 0x60) {
return -EINVAL;
}
/* Retrieve address */
peeraddr->sin6.sin6_family = AF_INET6;
memcpy(&peeraddr->sin6.sin6_addr, &((struct ipv6hdr*)nethdr)->saddr, sizeof(struct in6_addr));
peeraddr->sin6.sin6_port = udp_hdr(skb)->source;
break;
}
default: {
return -EINVAL;
}
}
return 0;
}
/* */
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr) {
struct kvec vec;
struct msghdr msg;
TRACEKMOD("### sc_socket_send\n");
/* */
vec.iov_base = buffer;
vec.iov_len = length;
/* */
memset(&msg, 0, sizeof(struct msghdr));
msg.msg_name = sockaddr;
msg.msg_namelen = sizeof(union capwap_addr);
msg.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT;
/* */
return kernel_sendmsg(sc_sockets[type], &msg, &vec, 1, length);
}
/* */
int sc_socket_init(void) {
TRACEKMOD("### sc_socket_init\n");
memset(sc_sockets, 0, sizeof(sc_sockets));
return 0;
}
/* */
int sc_socket_bind(union capwap_addr* sockaddr) {
int ret;
TRACEKMOD("### sc_socket_bind\n");
/* */
if (sc_sockets[SOCKET_UDP] || sc_sockets[SOCKET_UDPLITE]) {
return -EBUSY;
}
/* UDP socket */
ret = sc_socket_create(SOCKET_UDP, sockaddr, IPPROTO_UDP);
if (ret) {
goto failure;
}
/* UDPLite socket */
ret = sc_socket_create(SOCKET_UDPLITE, sockaddr, IPPROTO_UDPLITE);
if (ret) {
goto failure;
}
/* */
udp_encap_enable();
if (sockaddr->ss.ss_family == AF_INET6) {
udpv6_encap_enable();
}
return 0;
failure:
sc_socket_close();
return ret;
}
/* */
void sc_socket_close(void) {
TRACEKMOD("### sc_socket_close\n");
/* Close sockets */
if (sc_sockets[SOCKET_UDP]) {
kernel_sock_shutdown(sc_sockets[SOCKET_UDP], SHUT_RDWR);
sock_release(sc_sockets[SOCKET_UDP]);
}
if (sc_sockets[SOCKET_UDPLITE]) {
kernel_sock_shutdown(sc_sockets[SOCKET_UDPLITE], SHUT_RDWR);
sock_release(sc_sockets[SOCKET_UDPLITE]);
}
memset(sc_sockets, 0, sizeof(sc_sockets));
}
/* */
int sc_addr_compare(const union capwap_addr* addr1, const union capwap_addr* addr2) {
TRACEKMOD("### sc_addr_compare\n");
if (addr1->ss.ss_family == addr2->ss.ss_family) {
if (addr1->ss.ss_family == AF_INET) {
return (((addr1->sin.sin_addr.s_addr == addr2->sin.sin_addr.s_addr) && (addr1->sin.sin_port == addr2->sin.sin_port)) ? 0 : -1);
} else if (addr1->ss.ss_family == AF_INET6) {
return ((!memcmp(&addr1->sin6.sin6_addr, &addr2->sin6.sin6_addr, sizeof(struct in6_addr)) && (addr1->sin6.sin6_port == addr2->sin6.sin6_port)) ? 0 : -1);
}
}
return -1;
}

View File

@ -1,35 +1,35 @@
#ifndef __KMOD_SOCKET_HEADER__
#define __KMOD_SOCKET_HEADER__
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/skbuff.h>
/* */
#define SOCKET_UDP 0
#define SOCKET_UDPLITE 1
/* Universal socket address */
union capwap_addr {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
struct sockaddr_storage ss;
};
/* */
int sc_socket_init(void);
void sc_socket_close(void);
/* */
int sc_socket_bind(union capwap_addr* sockaddr);
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr);
/* */
int sc_socket_getpeeraddr(struct sk_buff* skb, union capwap_addr* peeraddr);
/* */
int sc_addr_compare(const union capwap_addr* addr1, const union capwap_addr* addr2);
#endif /* __KMOD_SOCKET_HEADER__ */
#ifndef __KMOD_SOCKET_HEADER__
#define __KMOD_SOCKET_HEADER__
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/skbuff.h>
/* */
#define SOCKET_UDP 0
#define SOCKET_UDPLITE 1
/* Universal socket address */
union capwap_addr {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
struct sockaddr_storage ss;
};
/* */
int sc_socket_init(void);
void sc_socket_close(void);
/* */
int sc_socket_bind(union capwap_addr* sockaddr);
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr);
/* */
int sc_socket_getpeeraddr(struct sk_buff* skb, union capwap_addr* peeraddr);
/* */
int sc_addr_compare(const union capwap_addr* addr1, const union capwap_addr* addr2);
#endif /* __KMOD_SOCKET_HEADER__ */

View File

@ -1,157 +1,157 @@
#include "config.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include "station.h"
#include "capwap.h"
#include "iface.h"
/* */
#define STATION_HASH_SIZE 65536
/* */
static LIST_HEAD(sc_station_list);
static struct sc_capwap_station* __rcu sc_station_hash_addr[STATION_HASH_SIZE];
/* */
static uint32_t sc_stations_hash_addr(const uint8_t* macaddress) {
TRACEKMOD("### sc_stations_hash_addr\n");
return (((((uint32_t)macaddress[4] << 8) | (uint32_t)macaddress[5]) ^ ((uint32_t)macaddress[3] << 4)) % STATION_HASH_SIZE);
}
/* */
static struct sc_capwap_connection* sc_stations_searchconnection(struct sc_capwap_station* station) {
struct sc_capwap_connection* connection;
struct sc_capwap_session_priv* sessionpriv = rcu_access_pointer(station->sessionpriv);
struct sc_netdev_priv* devpriv = rcu_access_pointer(station->devpriv);
TRACEKMOD("### sc_stations_searchconnection\n");
list_for_each_entry(connection, &sessionpriv->list_connections, list_session) {
if ((connection->devpriv == devpriv) && (connection->radioid == station->radioid) && (connection->vlan == station->vlan)) {
return connection;
}
}
return NULL;
}
/* */
void sc_stations_add(struct sc_capwap_station* station) {
uint32_t hash;
TRACEKMOD("### sc_stations_add\n");
/* */
list_add_rcu(&station->list, &sc_station_list);
hash = sc_stations_hash_addr(station->address);
station->next_addr = rcu_dereference_protected(sc_station_hash_addr[hash], sc_capwap_update_lock_is_locked());
rcu_assign_pointer(sc_station_hash_addr[hash], station);
}
/* */
struct sc_capwap_station* sc_stations_search(const uint8_t* macaddress) {
struct sc_capwap_station* station;
TRACEKMOD("### sc_stations_search\n");
/* */
station = rcu_dereference_check(sc_station_hash_addr[sc_stations_hash_addr(macaddress)], sc_capwap_update_lock_is_locked());
while (station) {
if (!memcmp(&station->address, macaddress, MACADDRESS_EUI48_LENGTH)) {
break;
}
/* */
station = rcu_dereference_check(station->next_addr, sc_capwap_update_lock_is_locked());
}
return station;
}
/* */
void sc_stations_free(struct sc_capwap_station* station) {
uint32_t hash;
struct sc_capwap_station* search;
TRACEKMOD("### sc_stations_free\n");
/* */
hash = sc_stations_hash_addr(station->address);
search = rcu_dereference_protected(sc_station_hash_addr[hash], sc_capwap_update_lock_is_locked());
if (search) {
if (search == station) {
rcu_assign_pointer(sc_station_hash_addr[hash], station->next_addr);
} else {
while (rcu_access_pointer(search->next_addr) && (rcu_access_pointer(search->next_addr) != station)) {
search = rcu_dereference_protected(search->next_addr, sc_capwap_update_lock_is_locked());
}
if (rcu_access_pointer(search->next_addr)) {
rcu_assign_pointer(search->next_addr, station->next_addr);
}
}
}
/* */
list_del_rcu(&station->list_dev);
list_del_rcu(&station->list_session);
synchronize_net();
kfree(station);
}
/* */
int sc_stations_setconnection(struct sc_capwap_station* station) {
struct sc_capwap_connection* connection;
TRACEKMOD("### sc_stations_setconnection\n");
/* */
connection = sc_stations_searchconnection(station);
if (!connection) {
connection = (struct sc_capwap_connection*)kzalloc(sizeof(struct sc_capwap_connection), GFP_KERNEL);
if (!connection) {
TRACEKMOD("*** Unable to create connection\n");
return -ENOMEM;
}
/* */
connection->sessionpriv = rcu_access_pointer(station->sessionpriv);
list_add_rcu(&connection->list_session, &connection->sessionpriv->list_connections);
connection->devpriv = rcu_access_pointer(station->devpriv);
list_add_rcu(&connection->list_dev, &connection->devpriv->list_connections);
connection->radioid = station->radioid;
connection->vlan = station->vlan;
}
/* */
connection->count++;
connection->wlanidmask |= 1 << (station->wlanid - 1);
return 0;
}
/* */
void sc_stations_releaseconnection(struct sc_capwap_station* station) {
struct sc_capwap_connection* connection;
TRACEKMOD("### sc_stations_releaseconnection\n");
connection = sc_stations_searchconnection(station);
if (connection) {
TRACEKMOD("*** Release connection reference %d\n", connection->count);
connection->count--;
if (!connection->count) {
list_del_rcu(&connection->list_session);
list_del_rcu(&connection->list_dev);
synchronize_net();
kfree(connection);
}
}
}
#include "config.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include "station.h"
#include "capwap.h"
#include "iface.h"
/* */
#define STATION_HASH_SIZE 65536
/* */
static LIST_HEAD(sc_station_list);
static struct sc_capwap_station* __rcu sc_station_hash_addr[STATION_HASH_SIZE];
/* */
static uint32_t sc_stations_hash_addr(const uint8_t* macaddress) {
TRACEKMOD("### sc_stations_hash_addr\n");
return (((((uint32_t)macaddress[4] << 8) | (uint32_t)macaddress[5]) ^ ((uint32_t)macaddress[3] << 4)) % STATION_HASH_SIZE);
}
/* */
static struct sc_capwap_connection* sc_stations_searchconnection(struct sc_capwap_station* station) {
struct sc_capwap_connection* connection;
struct sc_capwap_session_priv* sessionpriv = rcu_access_pointer(station->sessionpriv);
struct sc_netdev_priv* devpriv = rcu_access_pointer(station->devpriv);
TRACEKMOD("### sc_stations_searchconnection\n");
list_for_each_entry(connection, &sessionpriv->list_connections, list_session) {
if ((connection->devpriv == devpriv) && (connection->radioid == station->radioid) && (connection->vlan == station->vlan)) {
return connection;
}
}
return NULL;
}
/* */
void sc_stations_add(struct sc_capwap_station* station) {
uint32_t hash;
TRACEKMOD("### sc_stations_add\n");
/* */
list_add_rcu(&station->list, &sc_station_list);
hash = sc_stations_hash_addr(station->address);
station->next_addr = rcu_dereference_protected(sc_station_hash_addr[hash], sc_capwap_update_lock_is_locked());
rcu_assign_pointer(sc_station_hash_addr[hash], station);
}
/* */
struct sc_capwap_station* sc_stations_search(const uint8_t* macaddress) {
struct sc_capwap_station* station;
TRACEKMOD("### sc_stations_search\n");
/* */
station = rcu_dereference_check(sc_station_hash_addr[sc_stations_hash_addr(macaddress)], sc_capwap_update_lock_is_locked());
while (station) {
if (!memcmp(&station->address, macaddress, MACADDRESS_EUI48_LENGTH)) {
break;
}
/* */
station = rcu_dereference_check(station->next_addr, sc_capwap_update_lock_is_locked());
}
return station;
}
/* */
void sc_stations_free(struct sc_capwap_station* station) {
uint32_t hash;
struct sc_capwap_station* search;
TRACEKMOD("### sc_stations_free\n");
/* */
hash = sc_stations_hash_addr(station->address);
search = rcu_dereference_protected(sc_station_hash_addr[hash], sc_capwap_update_lock_is_locked());
if (search) {
if (search == station) {
rcu_assign_pointer(sc_station_hash_addr[hash], station->next_addr);
} else {
while (rcu_access_pointer(search->next_addr) && (rcu_access_pointer(search->next_addr) != station)) {
search = rcu_dereference_protected(search->next_addr, sc_capwap_update_lock_is_locked());
}
if (rcu_access_pointer(search->next_addr)) {
rcu_assign_pointer(search->next_addr, station->next_addr);
}
}
}
/* */
list_del_rcu(&station->list_dev);
list_del_rcu(&station->list_session);
synchronize_net();
kfree(station);
}
/* */
int sc_stations_setconnection(struct sc_capwap_station* station) {
struct sc_capwap_connection* connection;
TRACEKMOD("### sc_stations_setconnection\n");
/* */
connection = sc_stations_searchconnection(station);
if (!connection) {
connection = (struct sc_capwap_connection*)kzalloc(sizeof(struct sc_capwap_connection), GFP_KERNEL);
if (!connection) {
TRACEKMOD("*** Unable to create connection\n");
return -ENOMEM;
}
/* */
connection->sessionpriv = rcu_access_pointer(station->sessionpriv);
list_add_rcu(&connection->list_session, &connection->sessionpriv->list_connections);
connection->devpriv = rcu_access_pointer(station->devpriv);
list_add_rcu(&connection->list_dev, &connection->devpriv->list_connections);
connection->radioid = station->radioid;
connection->vlan = station->vlan;
}
/* */
connection->count++;
connection->wlanidmask |= 1 << (station->wlanid - 1);
return 0;
}
/* */
void sc_stations_releaseconnection(struct sc_capwap_station* station) {
struct sc_capwap_connection* connection;
TRACEKMOD("### sc_stations_releaseconnection\n");
connection = sc_stations_searchconnection(station);
if (connection) {
TRACEKMOD("*** Release connection reference %d\n", connection->count);
connection->count--;
if (!connection->count) {
list_del_rcu(&connection->list_session);
list_del_rcu(&connection->list_dev);
synchronize_net();
kfree(connection);
}
}
}

View File

@ -1,58 +1,58 @@
#ifndef __KMOD_AC_STATION_HEADER__
#define __KMOD_AC_STATION_HEADER__
#include "capwap_rfc.h"
/* */
struct sc_capwap_connection {
int count;
/* Session */
struct sc_capwap_session_priv* sessionpriv;
struct list_head list_session;
/* Interface */
struct sc_netdev_priv* devpriv;
struct list_head list_dev;
/* */
uint16_t vlan;
uint8_t radioid;
uint8_t wlanidmask;
};
/* */
struct sc_capwap_station {
struct list_head list;
/* */
uint8_t address[MACADDRESS_EUI48_LENGTH];
struct sc_capwap_station* __rcu next_addr;
/* Session */
struct sc_capwap_session_priv* __rcu sessionpriv;
struct list_head list_session;
/* Interface */
struct sc_netdev_priv* __rcu devpriv;
struct list_head list_dev;
/* */
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
uint16_t vlan;
uint8_t radioid;
uint8_t wlanid;
};
/* */
void sc_stations_add(struct sc_capwap_station* station);
void sc_stations_free(struct sc_capwap_station* station);
/* */
struct sc_capwap_station* sc_stations_search(const uint8_t* macaddress);
/* */
int sc_stations_setconnection(struct sc_capwap_station* station);
void sc_stations_releaseconnection(struct sc_capwap_station* station);
#endif /* __KMOD_AC_STATION_HEADER__ */
#ifndef __KMOD_AC_STATION_HEADER__
#define __KMOD_AC_STATION_HEADER__
#include "capwap_rfc.h"
/* */
struct sc_capwap_connection {
int count;
/* Session */
struct sc_capwap_session_priv* sessionpriv;
struct list_head list_session;
/* Interface */
struct sc_netdev_priv* devpriv;
struct list_head list_dev;
/* */
uint16_t vlan;
uint8_t radioid;
uint8_t wlanidmask;
};
/* */
struct sc_capwap_station {
struct list_head list;
/* */
uint8_t address[MACADDRESS_EUI48_LENGTH];
struct sc_capwap_station* __rcu next_addr;
/* Session */
struct sc_capwap_session_priv* __rcu sessionpriv;
struct list_head list_session;
/* Interface */
struct sc_netdev_priv* __rcu devpriv;
struct list_head list_dev;
/* */
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
uint16_t vlan;
uint8_t radioid;
uint8_t wlanid;
};
/* */
void sc_stations_add(struct sc_capwap_station* station);
void sc_stations_free(struct sc_capwap_station* station);
/* */
struct sc_capwap_station* sc_stations_search(const uint8_t* macaddress);
/* */
int sc_stations_setconnection(struct sc_capwap_station* station);
void sc_stations_releaseconnection(struct sc_capwap_station* station);
#endif /* __KMOD_AC_STATION_HEADER__ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,54 +1,54 @@
#ifndef __CAPWAP_HASH_HEADER__
#define __CAPWAP_HASH_HEADER__
typedef unsigned long (*capwap_hash_item_gethash)(const void* key, unsigned long hashsize);
typedef const void* (*capwap_hash_item_getkey)(const void* data);
typedef int (*capwap_hash_item_cmp)(const void* key1, const void* key2);
typedef void (*capwap_hash_item_free)(void* data);
#define HASH_BREAK 0
#define HASH_CONTINUE 1
#define HASH_DELETE_AND_BREAK 2
#define HASH_DELETE_AND_CONTINUE 3
typedef int (*capwap_hash_item_foreach)(void* data, void* param);
struct capwap_hash_item {
void* data;
int height;
struct capwap_hash_item* parent;
struct capwap_hash_item* left;
struct capwap_hash_item* right;
struct capwap_hash_item* removenext;
};
struct capwap_hash {
struct capwap_hash_item** items;
unsigned long hashsize;
/* */
unsigned long count;
/* */
struct capwap_hash_item* removeitems;
/* Callback functions */
capwap_hash_item_gethash item_gethash;
capwap_hash_item_getkey item_getkey;
capwap_hash_item_cmp item_cmp;
capwap_hash_item_free item_free;
};
struct capwap_hash* capwap_hash_create(unsigned long hashsize);
void capwap_hash_free(struct capwap_hash* hash);
void capwap_hash_add(struct capwap_hash* hash, void* data);
void capwap_hash_delete(struct capwap_hash* hash, const void* key);
void capwap_hash_deleteall(struct capwap_hash* hash);
void* capwap_hash_search(struct capwap_hash* hash, const void* key);
void capwap_hash_foreach(struct capwap_hash* hash, capwap_hash_item_foreach item_foreach, void* param);
#endif /* __CAPWAP_HASH_HEADER__ */
#ifndef __CAPWAP_HASH_HEADER__
#define __CAPWAP_HASH_HEADER__
typedef unsigned long (*capwap_hash_item_gethash)(const void* key, unsigned long hashsize);
typedef const void* (*capwap_hash_item_getkey)(const void* data);
typedef int (*capwap_hash_item_cmp)(const void* key1, const void* key2);
typedef void (*capwap_hash_item_free)(void* data);
#define HASH_BREAK 0
#define HASH_CONTINUE 1
#define HASH_DELETE_AND_BREAK 2
#define HASH_DELETE_AND_CONTINUE 3
typedef int (*capwap_hash_item_foreach)(void* data, void* param);
struct capwap_hash_item {
void* data;
int height;
struct capwap_hash_item* parent;
struct capwap_hash_item* left;
struct capwap_hash_item* right;
struct capwap_hash_item* removenext;
};
struct capwap_hash {
struct capwap_hash_item** items;
unsigned long hashsize;
/* */
unsigned long count;
/* */
struct capwap_hash_item* removeitems;
/* Callback functions */
capwap_hash_item_gethash item_gethash;
capwap_hash_item_getkey item_getkey;
capwap_hash_item_cmp item_cmp;
capwap_hash_item_free item_free;
};
struct capwap_hash* capwap_hash_create(unsigned long hashsize);
void capwap_hash_free(struct capwap_hash* hash);
void capwap_hash_add(struct capwap_hash* hash, void* data);
void capwap_hash_delete(struct capwap_hash* hash, const void* key);
void capwap_hash_deleteall(struct capwap_hash* hash);
void* capwap_hash_search(struct capwap_hash* hash, const void* key);
void capwap_hash_foreach(struct capwap_hash* hash, capwap_hash_item_foreach item_foreach, void* param);
#endif /* __CAPWAP_HASH_HEADER__ */

View File

@ -1,236 +1,236 @@
#ifndef __CAPWAP_RFC_HEADER__
#define __CAPWAP_RFC_HEADER__
#include <inttypes.h>
#ifndef STRUCT_PACKED
#define STRUCT_PACKED __attribute__((__packed__))
#endif
#define CAPWAP_PROTOCOL_VERSION 0
#define CAPWAP_MTU_DEFAULT 1400
#define CAPWAP_DONT_FRAGMENT 0
/* Capwap preamble */
#define CAPWAP_PREAMBLE_HEADER 0
#define CAPWAP_PREAMBLE_DTLS_HEADER 1
struct capwap_preamble {
#ifdef CAPWAP_BIG_ENDIAN
uint8_t version : 4;
uint8_t type : 4;
#else
uint8_t type : 4;
uint8_t version : 4;
#endif
} STRUCT_PACKED;
/* Capwap DTLS header */
struct capwap_dtls_header {
struct capwap_preamble preamble;
uint8_t reserved1;
uint8_t reserved2;
uint8_t reserved3;
} STRUCT_PACKED;
/* Capwap header: 8 (header) + 12 (radio mac) + 256 (wireless info) */
#define CAPWAP_HEADER_MAX_SIZE 276
struct capwap_header {
struct capwap_preamble preamble;
#ifdef CAPWAP_BIG_ENDIAN
uint16_t hlen : 5;
uint16_t rid : 5;
uint16_t wbid : 5;
uint16_t flag_t : 1;
uint8_t flag_f : 1;
uint8_t flag_l : 1;
uint8_t flag_w : 1;
uint8_t flag_m : 1;
uint8_t flag_k : 1;
uint8_t flag_res : 3;
#else
uint16_t _rid_hi : 3;
uint16_t hlen : 5;
uint16_t flag_t : 1;
uint16_t wbid : 5;
uint16_t _rid_lo : 2;
uint8_t flag_res : 3;
uint8_t flag_k : 1;
uint8_t flag_m : 1;
uint8_t flag_w : 1;
uint8_t flag_l : 1;
uint8_t flag_f : 1;
#endif
uint16_t frag_id;
uint16_t frag_off; /* Only first 13 bit */
} STRUCT_PACKED;
#define FRAGMENT_OFFSET_MASK 0xfff8
/* Mac Address */
struct capwap_mac_address {
uint8_t length;
uint8_t address[0];
} STRUCT_PACKED;
/* Wireless Information */
struct capwap_wireless_information {
uint8_t length;
uint8_t data[0];
} STRUCT_PACKED;
/* IEEE802.11 Wireless Information */
struct capwap_ieee80211_frame_info {
uint8_t rssi;
uint8_t snr;
uint16_t rate;
} STRUCT_PACKED;
/* Message element */
struct capwap_message_element {
uint16_t type;
uint16_t length;
uint8_t data[0];
} STRUCT_PACKED;
/* Control Message Type */
#define CAPWAP_FIRST_MESSAGE_TYPE 1
#define CAPWAP_DISCOVERY_REQUEST 1
#define CAPWAP_DISCOVERY_RESPONSE 2
#define CAPWAP_JOIN_REQUEST 3
#define CAPWAP_JOIN_RESPONSE 4
#define CAPWAP_CONFIGURATION_STATUS_REQUEST 5
#define CAPWAP_CONFIGURATION_STATUS_RESPONSE 6
#define CAPWAP_CONFIGURATION_UPDATE_REQUEST 7
#define CAPWAP_CONFIGURATION_UPDATE_RESPONSE 8
#define CAPWAP_WTP_EVENT_REQUEST 9
#define CAPWAP_WTP_EVENT_RESPONSE 10
#define CAPWAP_CHANGE_STATE_EVENT_REQUEST 11
#define CAPWAP_CHANGE_STATE_EVENT_RESPONSE 12
#define CAPWAP_ECHO_REQUEST 13
#define CAPWAP_ECHO_RESPONSE 14
#define CAPWAP_IMAGE_DATA_REQUEST 15
#define CAPWAP_IMAGE_DATA_RESPONSE 16
#define CAPWAP_RESET_REQUEST 17
#define CAPWAP_RESET_RESPONSE 18
#define CAPWAP_PRIMARY_DISCOVERY_REQUEST 19
#define CAPWAP_PRIMARY_DISCOVERY_RESPONSE 20
#define CAPWAP_DATA_TRANSFER_REQUEST 21
#define CAPWAP_DATA_TRANSFER_RESPONSE 22
#define CAPWAP_CLEAR_CONFIGURATION_REQUEST 23
#define CAPWAP_CLEAR_CONFIGURATION_RESPONSE 24
#define CAPWAP_STATION_CONFIGURATION_REQUEST 25
#define CAPWAP_STATION_CONFIGURATION_RESPONSE 26
#define CAPWAP_LAST_MESSAGE_TYPE 26
#define CAPWAP_VALID_MESSAGE_TYPE(x) (((x) >= CAPWAP_FIRST_MESSAGE_TYPE) && ((x) <= CAPWAP_LAST_MESSAGE_TYPE))
#define CAPWAP_IEEE80211_FIRST_MESSAGE_TYPE 3398913
#define CAPWAP_IEEE80211_WLAN_CONFIGURATION_REQUEST 3398913
#define CAPWAP_IEEE80211_WLAN_CONFIGURATION_RESPONSE 3398914
#define CAPWAP_IEEE80211_LAST_MESSAGE_TYPE 3398914
#define CAPWAP_VALID_IEEE80211_MESSAGE_TYPE(x) (((x) >= CAPWAP_IEEE80211_FIRST_MESSAGE_TYPE) && ((x) <= CAPWAP_IEEE80211_LAST_MESSAGE_TYPE))
/* Control Message */
#define CAPWAP_CONTROL_MESSAGE_MIN_LENGTH 3
struct capwap_control_message {
uint32_t type;
uint8_t seq;
uint16_t length;
uint8_t flags;
uint8_t elements[0];
} STRUCT_PACKED;
/* Data Message Keep-Alive*/
#define CAPWAP_DATA_MESSAGE_KEEPALIVE_MIN_LENGTH 2
struct capwap_data_message {
uint16_t length;
uint8_t elements[0];
} STRUCT_PACKED;
/* Capwap dtls header helper */
#define GET_DTLS_BODY(x) (void*)(((uint8_t*)(x)) + sizeof(struct capwap_dtls_header))
/* Capwap header helper */
#define GET_VERSION_HEADER(x) ((x)->preamble.version)
#define SET_VERSION_HEADER(x, y) ((x)->preamble.version = (uint8_t)(y))
#define GET_TYPE_HEADER(x) ((x)->preamble.type)
#define SET_TYPE_HEADER(x, y) ((x)->preamble.type = (uint8_t)(y))
#define GET_HLEN_HEADER(x) ((x)->hlen)
#define SET_HLEN_HEADER(x, y) ((x)->hlen = (uint16_t)(y))
#ifdef CAPWAP_BIG_ENDIAN
#define GET_RID_HEADER(x) ((uint8_t)((x)->rid))
#define SET_RID_HEADER(x, y) ((x)->rid = (uint16_t)(y))
#else
#define GET_RID_HEADER(x) ((uint8_t)((uint16_t)((x)->_rid_hi << 2 | (x)->_rid_lo)))
#define SET_RID_HEADER(x, y) ({ (x)->_rid_hi = (uint16_t)((y) >> 2); (x)->_rid_lo = (uint16_t)((y) & 0x0003); })
#endif
#define GET_WBID_HEADER(x) ((x)->wbid)
#define SET_WBID_HEADER(x, y) ((x)->wbid = (uint16_t)(y))
#define IS_FLAG_T_HEADER(x) ((x)->flag_t)
#define SET_FLAG_T_HEADER(x, y) ((x)->flag_t = ((y) ? 1 : 0))
#define IS_FLAG_F_HEADER(x) ((x)->flag_f)
#define SET_FLAG_F_HEADER(x, y) ((x)->flag_f = ((y) ? 1 : 0))
#define IS_FLAG_L_HEADER(x) ((x)->flag_l)
#define SET_FLAG_L_HEADER(x, y) ((x)->flag_l = ((y) ? 1 : 0))
#define IS_FLAG_W_HEADER(x) ((x)->flag_w)
#define SET_FLAG_W_HEADER(x, y) ((x)->flag_w = ((y) ? 1 : 0))
#define IS_FLAG_M_HEADER(x) ((x)->flag_m)
#define SET_FLAG_M_HEADER(x, y) ((x)->flag_m = ((y) ? 1 : 0))
#define IS_FLAG_K_HEADER(x) ((x)->flag_k)
#define SET_FLAG_K_HEADER(x, y) ((x)->flag_k = ((y) ? 1 : 0))
#define GET_FRAGMENT_ID_HEADER(x) (ntohs((x)->frag_id))
#define SET_FRAGMENT_ID_HEADER(x, y) ((x)->frag_id = htons((uint16_t)(y)))
#define GET_FRAGMENT_OFFSET_HEADER(x) (ntohs((x)->frag_off) & FRAGMENT_OFFSET_MASK)
#define SET_FRAGMENT_OFFSET_HEADER(x, y) ((x)->frag_off &= ~FRAGMENT_OFFSET_MASK, (x)->frag_off |= htons((uint16_t)(y) & FRAGMENT_OFFSET_MASK))
#define GET_RADIO_MAC_ADDRESS_STRUCT(x) ((struct capwap_mac_address*)(((uint8_t*)(x)) + sizeof(struct capwap_header)))
#define GET_WIRELESS_INFORMATION_STRUCT(x) ((struct capwap_wireless_information*)(((uint8_t*)(x)) + sizeof(struct capwap_header) + (IS_FLAG_M_HEADER(x) ? (((GET_RADIO_MAC_ADDRESS_STRUCT(x)->length + sizeof(struct capwap_mac_address)) + 3) / 4) * 4 : 0)))
#define GET_PAYLOAD_HEADER(x) ((void*)(((uint8_t*)(x)) + GET_HLEN_HEADER(x) * 4))
#define IS_SEQUENCE_SMALLER(s1, s2) (((((s1) < (s2)) && (((s2) - (s1)) < 128)) || (((s1) > (s2)) && (((s1) - (s2)) > 128))) ? 1 : 0)
/* */
#define MACADDRESS_NONE_LENGTH 0
/* */
#define MACADDRESS_EUI48_LENGTH 6
struct capwap_macaddress_eui48 {
uint8_t macaddress[MACADDRESS_EUI48_LENGTH];
} STRUCT_PACKED;
/* */
#define MACADDRESS_EUI64_LENGTH 8
struct capwap_macaddress_eui64 {
uint8_t macaddress[MACADDRESS_EUI64_LENGTH];
} STRUCT_PACKED;
#define IS_VALID_MACADDRESS_LENGTH(x) ((x == MACADDRESS_EUI48_LENGTH) || (x == MACADDRESS_EUI64_LENGTH))
#define RADIOID_MAX_COUNT 31
#define IS_VALID_RADIOID(x) ((x >= 1) && (x <= RADIOID_MAX_COUNT))
#define WLANID_MAX_COUNT 16
#define IS_VALID_WLANID(x) ((x >= 1) && (x <= WLANID_MAX_COUNT))
/* Standard message elements 1 -> 52 (1 - 1023) */
#define CAPWAP_MESSAGE_ELEMENTS_START 1
#define CAPWAP_MESSAGE_ELEMENTS_STOP 53
#define CAPWAP_MESSAGE_ELEMENTS_COUNT ((CAPWAP_MESSAGE_ELEMENTS_STOP - CAPWAP_MESSAGE_ELEMENTS_START) + 1)
#define IS_MESSAGE_ELEMENTS(x) (((x >= CAPWAP_MESSAGE_ELEMENTS_START) && (x <= CAPWAP_MESSAGE_ELEMENTS_STOP)) ? 1 : 0)
/* 802.11 message elements 1024 -> 1024 (1024 - 2047) */
#define CAPWAP_80211_MESSAGE_ELEMENTS_START 1024
#define CAPWAP_80211_MESSAGE_ELEMENTS_STOP 1048
#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_VALID_MESSAGE_ELEMENTS(x) (IS_MESSAGE_ELEMENTS(x) || IS_80211_MESSAGE_ELEMENTS(x))
#endif /* __CAPWAP_RFC_HEADER__ */
#ifndef __CAPWAP_RFC_HEADER__
#define __CAPWAP_RFC_HEADER__
#include <inttypes.h>
#ifndef STRUCT_PACKED
#define STRUCT_PACKED __attribute__((__packed__))
#endif
#define CAPWAP_PROTOCOL_VERSION 0
#define CAPWAP_MTU_DEFAULT 1400
#define CAPWAP_DONT_FRAGMENT 0
/* Capwap preamble */
#define CAPWAP_PREAMBLE_HEADER 0
#define CAPWAP_PREAMBLE_DTLS_HEADER 1
struct capwap_preamble {
#ifdef CAPWAP_BIG_ENDIAN
uint8_t version : 4;
uint8_t type : 4;
#else
uint8_t type : 4;
uint8_t version : 4;
#endif
} STRUCT_PACKED;
/* Capwap DTLS header */
struct capwap_dtls_header {
struct capwap_preamble preamble;
uint8_t reserved1;
uint8_t reserved2;
uint8_t reserved3;
} STRUCT_PACKED;
/* Capwap header: 8 (header) + 12 (radio mac) + 256 (wireless info) */
#define CAPWAP_HEADER_MAX_SIZE 276
struct capwap_header {
struct capwap_preamble preamble;
#ifdef CAPWAP_BIG_ENDIAN
uint16_t hlen : 5;
uint16_t rid : 5;
uint16_t wbid : 5;
uint16_t flag_t : 1;
uint8_t flag_f : 1;
uint8_t flag_l : 1;
uint8_t flag_w : 1;
uint8_t flag_m : 1;
uint8_t flag_k : 1;
uint8_t flag_res : 3;
#else
uint16_t _rid_hi : 3;
uint16_t hlen : 5;
uint16_t flag_t : 1;
uint16_t wbid : 5;
uint16_t _rid_lo : 2;
uint8_t flag_res : 3;
uint8_t flag_k : 1;
uint8_t flag_m : 1;
uint8_t flag_w : 1;
uint8_t flag_l : 1;
uint8_t flag_f : 1;
#endif
uint16_t frag_id;
uint16_t frag_off; /* Only first 13 bit */
} STRUCT_PACKED;
#define FRAGMENT_OFFSET_MASK 0xfff8
/* Mac Address */
struct capwap_mac_address {
uint8_t length;
uint8_t address[0];
} STRUCT_PACKED;
/* Wireless Information */
struct capwap_wireless_information {
uint8_t length;
uint8_t data[0];
} STRUCT_PACKED;
/* IEEE802.11 Wireless Information */
struct capwap_ieee80211_frame_info {
uint8_t rssi;
uint8_t snr;
uint16_t rate;
} STRUCT_PACKED;
/* Message element */
struct capwap_message_element {
uint16_t type;
uint16_t length;
uint8_t data[0];
} STRUCT_PACKED;
/* Control Message Type */
#define CAPWAP_FIRST_MESSAGE_TYPE 1
#define CAPWAP_DISCOVERY_REQUEST 1
#define CAPWAP_DISCOVERY_RESPONSE 2
#define CAPWAP_JOIN_REQUEST 3
#define CAPWAP_JOIN_RESPONSE 4
#define CAPWAP_CONFIGURATION_STATUS_REQUEST 5
#define CAPWAP_CONFIGURATION_STATUS_RESPONSE 6
#define CAPWAP_CONFIGURATION_UPDATE_REQUEST 7
#define CAPWAP_CONFIGURATION_UPDATE_RESPONSE 8
#define CAPWAP_WTP_EVENT_REQUEST 9
#define CAPWAP_WTP_EVENT_RESPONSE 10
#define CAPWAP_CHANGE_STATE_EVENT_REQUEST 11
#define CAPWAP_CHANGE_STATE_EVENT_RESPONSE 12
#define CAPWAP_ECHO_REQUEST 13
#define CAPWAP_ECHO_RESPONSE 14
#define CAPWAP_IMAGE_DATA_REQUEST 15
#define CAPWAP_IMAGE_DATA_RESPONSE 16
#define CAPWAP_RESET_REQUEST 17
#define CAPWAP_RESET_RESPONSE 18
#define CAPWAP_PRIMARY_DISCOVERY_REQUEST 19
#define CAPWAP_PRIMARY_DISCOVERY_RESPONSE 20
#define CAPWAP_DATA_TRANSFER_REQUEST 21
#define CAPWAP_DATA_TRANSFER_RESPONSE 22
#define CAPWAP_CLEAR_CONFIGURATION_REQUEST 23
#define CAPWAP_CLEAR_CONFIGURATION_RESPONSE 24
#define CAPWAP_STATION_CONFIGURATION_REQUEST 25
#define CAPWAP_STATION_CONFIGURATION_RESPONSE 26
#define CAPWAP_LAST_MESSAGE_TYPE 26
#define CAPWAP_VALID_MESSAGE_TYPE(x) (((x) >= CAPWAP_FIRST_MESSAGE_TYPE) && ((x) <= CAPWAP_LAST_MESSAGE_TYPE))
#define CAPWAP_IEEE80211_FIRST_MESSAGE_TYPE 3398913
#define CAPWAP_IEEE80211_WLAN_CONFIGURATION_REQUEST 3398913
#define CAPWAP_IEEE80211_WLAN_CONFIGURATION_RESPONSE 3398914
#define CAPWAP_IEEE80211_LAST_MESSAGE_TYPE 3398914
#define CAPWAP_VALID_IEEE80211_MESSAGE_TYPE(x) (((x) >= CAPWAP_IEEE80211_FIRST_MESSAGE_TYPE) && ((x) <= CAPWAP_IEEE80211_LAST_MESSAGE_TYPE))
/* Control Message */
#define CAPWAP_CONTROL_MESSAGE_MIN_LENGTH 3
struct capwap_control_message {
uint32_t type;
uint8_t seq;
uint16_t length;
uint8_t flags;
uint8_t elements[0];
} STRUCT_PACKED;
/* Data Message Keep-Alive*/
#define CAPWAP_DATA_MESSAGE_KEEPALIVE_MIN_LENGTH 2
struct capwap_data_message {
uint16_t length;
uint8_t elements[0];
} STRUCT_PACKED;
/* Capwap dtls header helper */
#define GET_DTLS_BODY(x) (void*)(((uint8_t*)(x)) + sizeof(struct capwap_dtls_header))
/* Capwap header helper */
#define GET_VERSION_HEADER(x) ((x)->preamble.version)
#define SET_VERSION_HEADER(x, y) ((x)->preamble.version = (uint8_t)(y))
#define GET_TYPE_HEADER(x) ((x)->preamble.type)
#define SET_TYPE_HEADER(x, y) ((x)->preamble.type = (uint8_t)(y))
#define GET_HLEN_HEADER(x) ((x)->hlen)
#define SET_HLEN_HEADER(x, y) ((x)->hlen = (uint16_t)(y))
#ifdef CAPWAP_BIG_ENDIAN
#define GET_RID_HEADER(x) ((uint8_t)((x)->rid))
#define SET_RID_HEADER(x, y) ((x)->rid = (uint16_t)(y))
#else
#define GET_RID_HEADER(x) ((uint8_t)((uint16_t)((x)->_rid_hi << 2 | (x)->_rid_lo)))
#define SET_RID_HEADER(x, y) ({ (x)->_rid_hi = (uint16_t)((y) >> 2); (x)->_rid_lo = (uint16_t)((y) & 0x0003); })
#endif
#define GET_WBID_HEADER(x) ((x)->wbid)
#define SET_WBID_HEADER(x, y) ((x)->wbid = (uint16_t)(y))
#define IS_FLAG_T_HEADER(x) ((x)->flag_t)
#define SET_FLAG_T_HEADER(x, y) ((x)->flag_t = ((y) ? 1 : 0))
#define IS_FLAG_F_HEADER(x) ((x)->flag_f)
#define SET_FLAG_F_HEADER(x, y) ((x)->flag_f = ((y) ? 1 : 0))
#define IS_FLAG_L_HEADER(x) ((x)->flag_l)
#define SET_FLAG_L_HEADER(x, y) ((x)->flag_l = ((y) ? 1 : 0))
#define IS_FLAG_W_HEADER(x) ((x)->flag_w)
#define SET_FLAG_W_HEADER(x, y) ((x)->flag_w = ((y) ? 1 : 0))
#define IS_FLAG_M_HEADER(x) ((x)->flag_m)
#define SET_FLAG_M_HEADER(x, y) ((x)->flag_m = ((y) ? 1 : 0))
#define IS_FLAG_K_HEADER(x) ((x)->flag_k)
#define SET_FLAG_K_HEADER(x, y) ((x)->flag_k = ((y) ? 1 : 0))
#define GET_FRAGMENT_ID_HEADER(x) (ntohs((x)->frag_id))
#define SET_FRAGMENT_ID_HEADER(x, y) ((x)->frag_id = htons((uint16_t)(y)))
#define GET_FRAGMENT_OFFSET_HEADER(x) (ntohs((x)->frag_off) & FRAGMENT_OFFSET_MASK)
#define SET_FRAGMENT_OFFSET_HEADER(x, y) ((x)->frag_off &= ~FRAGMENT_OFFSET_MASK, (x)->frag_off |= htons((uint16_t)(y) & FRAGMENT_OFFSET_MASK))
#define GET_RADIO_MAC_ADDRESS_STRUCT(x) ((struct capwap_mac_address*)(((uint8_t*)(x)) + sizeof(struct capwap_header)))
#define GET_WIRELESS_INFORMATION_STRUCT(x) ((struct capwap_wireless_information*)(((uint8_t*)(x)) + sizeof(struct capwap_header) + (IS_FLAG_M_HEADER(x) ? (((GET_RADIO_MAC_ADDRESS_STRUCT(x)->length + sizeof(struct capwap_mac_address)) + 3) / 4) * 4 : 0)))
#define GET_PAYLOAD_HEADER(x) ((void*)(((uint8_t*)(x)) + GET_HLEN_HEADER(x) * 4))
#define IS_SEQUENCE_SMALLER(s1, s2) (((((s1) < (s2)) && (((s2) - (s1)) < 128)) || (((s1) > (s2)) && (((s1) - (s2)) > 128))) ? 1 : 0)
/* */
#define MACADDRESS_NONE_LENGTH 0
/* */
#define MACADDRESS_EUI48_LENGTH 6
struct capwap_macaddress_eui48 {
uint8_t macaddress[MACADDRESS_EUI48_LENGTH];
} STRUCT_PACKED;
/* */
#define MACADDRESS_EUI64_LENGTH 8
struct capwap_macaddress_eui64 {
uint8_t macaddress[MACADDRESS_EUI64_LENGTH];
} STRUCT_PACKED;
#define IS_VALID_MACADDRESS_LENGTH(x) ((x == MACADDRESS_EUI48_LENGTH) || (x == MACADDRESS_EUI64_LENGTH))
#define RADIOID_MAX_COUNT 31
#define IS_VALID_RADIOID(x) ((x >= 1) && (x <= RADIOID_MAX_COUNT))
#define WLANID_MAX_COUNT 16
#define IS_VALID_WLANID(x) ((x >= 1) && (x <= WLANID_MAX_COUNT))
/* Standard message elements 1 -> 52 (1 - 1023) */
#define CAPWAP_MESSAGE_ELEMENTS_START 1
#define CAPWAP_MESSAGE_ELEMENTS_STOP 53
#define CAPWAP_MESSAGE_ELEMENTS_COUNT ((CAPWAP_MESSAGE_ELEMENTS_STOP - CAPWAP_MESSAGE_ELEMENTS_START) + 1)
#define IS_MESSAGE_ELEMENTS(x) (((x >= CAPWAP_MESSAGE_ELEMENTS_START) && (x <= CAPWAP_MESSAGE_ELEMENTS_STOP)) ? 1 : 0)
/* 802.11 message elements 1024 -> 1024 (1024 - 2047) */
#define CAPWAP_80211_MESSAGE_ELEMENTS_START 1024
#define CAPWAP_80211_MESSAGE_ELEMENTS_STOP 1048
#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_VALID_MESSAGE_ELEMENTS(x) (IS_MESSAGE_ELEMENTS(x) || IS_80211_MESSAGE_ELEMENTS(x))
#endif /* __CAPWAP_RFC_HEADER__ */

View File

@ -1,388 +1,388 @@
#include "capwap.h"
#include "capwap_network.h"
#include "capwap_socket.h"
#include <cyassl/options.h>
#include <cyassl/ssl.h>
/* */
static int capwap_socket_nonblocking(int sock, int nonblocking) {
int flags;
ASSERT(sock >= 0);
/* Retrieve file descriptor flags */
flags = fcntl(sock, F_GETFL, NULL);
if (flags < 0) {
return 0;
}
if (nonblocking) {
flags |= O_NONBLOCK;
} else {
flags &= ~O_NONBLOCK;
}
if(fcntl(sock, F_SETFL, flags) < 0) {
return 0;
}
return 1;
}
/* */
int capwap_socket_connect(int sock, union sockaddr_capwap* address, int timeout) {
int result;
struct pollfd fds;
socklen_t size;
ASSERT(sock >= 0);
ASSERT(address != NULL);
/* Non blocking socket */
if (!capwap_socket_nonblocking(sock, 1)) {
return 0;
}
/* */
result = connect(sock, &address->sa, sizeof(union sockaddr_capwap));
if (result < 0) {
if (errno == EINPROGRESS) {
/* Wait to connection complete */
for (;;) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = POLLOUT;
result = poll(&fds, 1, timeout);
if (!result || ((result < 0) && (errno != EINTR))) {
return 0;
} else if (result > 0) {
/* Check connection status */
size = sizeof(int);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&result, &size) < 0) {
return 0;
}
if (result) {
return 0;
}
/* Connection complete */
break;
}
}
} else {
/* Unable to connect to remote host */
return 0;
}
}
return 1;
}
/* */
static int capwap_socket_crypto_verifycertificate(int preverify, CYASSL_X509_STORE_CTX* store) {
return preverify;
}
/* */
void* capwap_socket_crypto_createcontext(char* calist, char* cert, char* privatekey) {
CYASSL_CTX* context = NULL;
ASSERT(calist != NULL);
ASSERT(cert != NULL);
ASSERT(privatekey != NULL);
/* Create SSL context */
context = CyaSSL_CTX_new(CyaTLSv1_2_client_method());
if (context) {
/* Public certificate */
if (!CyaSSL_CTX_use_certificate_file(context, cert, SSL_FILETYPE_PEM)) {
capwap_logging_debug("Error to load certificate file");
capwap_socket_crypto_freecontext(context);
return NULL;
}
/* Private key */
if (!CyaSSL_CTX_use_PrivateKey_file(context, privatekey, SSL_FILETYPE_PEM)) {
capwap_logging_debug("Error to load private key file");
capwap_socket_crypto_freecontext(context);
return NULL;
}
if (!CyaSSL_CTX_check_private_key(context)) {
capwap_logging_debug("Error to check private key");
capwap_socket_crypto_freecontext(context);
return NULL;
}
/* Certificate Authority */
if (!CyaSSL_CTX_load_verify_locations(context, calist, NULL)) {
capwap_logging_debug("Error to load ca file");
capwap_socket_crypto_freecontext(context);
return NULL;
}
/* Verify certificate callback */
CyaSSL_CTX_set_verify(context, SSL_VERIFY_PEER, capwap_socket_crypto_verifycertificate);
/* Set only high security cipher list */
if (!CyaSSL_CTX_set_cipher_list(context, "AES256-SHA")) {
capwap_logging_debug("Error to select cipher list");
capwap_socket_crypto_freecontext(context);
return NULL;
}
}
return (void*)context;
}
/* */
void capwap_socket_crypto_freecontext(void* context) {
CYASSL_CTX* sslcontext = (CYASSL_CTX*)context;
if (sslcontext) {
CyaSSL_CTX_free(sslcontext);
}
}
/* */
struct capwap_socket_ssl* capwap_socket_ssl_connect(int sock, void* sslcontext, int timeout) {
int result;
struct pollfd fds;
struct capwap_socket_ssl* sslsock;
ASSERT(sock >= 0);
ASSERT(sslcontext != NULL);
/* Create SSL session */
sslsock = capwap_alloc(sizeof(struct capwap_socket_ssl));
sslsock->sock = sock;
sslsock->sslcontext = sslcontext;
sslsock->sslsession = (void*)CyaSSL_new((CYASSL_CTX*)sslcontext);
if (!sslsock->sslsession) {
capwap_free(sslsock);
return NULL;
}
/* Set socket to SSL session */
if (!CyaSSL_set_fd((CYASSL*)sslsock->sslsession, sock)) {
CyaSSL_free((CYASSL*)sslsock->sslsession);
capwap_free(sslsock);
return NULL;
}
/* */
CyaSSL_set_using_nonblock((CYASSL*)sslsock->sslsession, 1);
/* Establish SSL connection */
for (;;) {
result = CyaSSL_connect((CYASSL*)sslsock->sslsession);
if (result == SSL_SUCCESS) {
break; /* Connection complete */
} else {
int error = CyaSSL_get_error((CYASSL*)sslsock->sslsession, 0);
if ((error == SSL_ERROR_WANT_READ) || (error == SSL_ERROR_WANT_WRITE)) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = ((error == SSL_ERROR_WANT_READ) ? POLLIN : POLLOUT);
result = poll(&fds, 1, timeout);
if (((result < 0) && (errno != EINTR)) || ((result > 0) && (fds.events != fds.revents))) {
CyaSSL_free((CYASSL*)sslsock->sslsession);
capwap_free(sslsock);
return NULL;
}
} else {
CyaSSL_free((CYASSL*)sslsock->sslsession);
capwap_free(sslsock);
return NULL;
}
}
}
return sslsock;
}
/* */
int capwap_socket_crypto_send(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout) {
int result;
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
ASSERT(sslsock->sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
result = CyaSSL_write((CYASSL*)sslsock->sslsession, buffer, length);
if (result != length) {
return -1;
}
return length;
}
/* */
int capwap_socket_crypto_recv(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout) {
int result;
struct pollfd fds;
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
ASSERT(sslsock->sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
for (;;) {
result = CyaSSL_read((CYASSL*)sslsock->sslsession, buffer, length);
if (result >= 0) {
return result;
} else {
int error = CyaSSL_get_error((CYASSL*)sslsock->sslsession, 0);
if ((error == SSL_ERROR_WANT_READ) || (error == SSL_ERROR_WANT_WRITE)) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sslsock->sock;
fds.events = ((error == SSL_ERROR_WANT_READ) ? POLLIN : POLLOUT);
result = poll(&fds, 1, timeout);
if (((result < 0) && (errno != EINTR)) || ((result > 0) && (fds.events != fds.revents))) {
break;
}
} else {
break;
}
}
}
return -1;
}
/* */
void capwap_socket_ssl_shutdown(struct capwap_socket_ssl* sslsock, int timeout) {
int result;
struct pollfd fds;
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
ASSERT(sslsock->sock >= 0);
/* */
for (;;) {
result = CyaSSL_shutdown((CYASSL*)sslsock->sslsession);
if (result >= 0) {
break; /* Shutdown complete */
} else {
int error = CyaSSL_get_error((CYASSL*)sslsock->sslsession, 0);
if ((error == SSL_ERROR_WANT_READ) || (error == SSL_ERROR_WANT_WRITE)) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sslsock->sock;
fds.events = ((error == SSL_ERROR_WANT_READ) ? POLLIN : POLLOUT);
result = poll(&fds, 1, timeout);
if (((result < 0) && (errno != EINTR)) || ((result > 0) && (fds.events != fds.revents))) {
break; /* Shutdown error */
}
} else {
break; /* Shutdown error */
}
}
}
}
/* */
void capwap_socket_ssl_close(struct capwap_socket_ssl* sslsock) {
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
CyaSSL_free((CYASSL*)sslsock->sslsession);
sslsock->sslsession = NULL;
}
/* */
void capwap_socket_shutdown(int sock) {
ASSERT(sock >= 0);
shutdown(sock, SHUT_RDWR);
}
/* */
void capwap_socket_close(int sock) {
ASSERT(sock >= 0);
capwap_socket_shutdown(sock);
capwap_socket_nonblocking(sock, 0);
close(sock);
}
/* */
int capwap_socket_send(int sock, void* buffer, size_t length, int timeout) {
int result;
struct pollfd fds;
size_t sendlength;
ASSERT(sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
sendlength = 0;
while (sendlength < length) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = POLLOUT;
result = poll(&fds, 1, timeout);
if ((result < 0) && (errno != EINTR)) {
return -1;
} else if (result > 0) {
if (fds.revents == POLLOUT) {
size_t leftlength = length - sendlength;
result = send(sock, &((char*)buffer)[sendlength], leftlength, 0);
if ((result < 0) && (errno != EINTR)) {
return -1;
} else if (result > 0) {
sendlength += result;
}
} else {
return -1;
}
}
}
return sendlength;
}
/* */
int capwap_socket_recv(int sock, void* buffer, size_t length, int timeout) {
int result;
struct pollfd fds;
ASSERT(sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
for (;;) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = POLLIN;
result = poll(&fds, 1, timeout);
if ((result < 0) && (errno != EINTR)) {
break;
} else if (result > 0) {
if (fds.revents == POLLIN) {
result = recv(sock, buffer, length, 0);
if ((result < 0) && (errno != EINTR)) {
break;
} else if (result >= 0) {
return result;
}
} else {
break;
}
}
}
return -1;
}
#include "capwap.h"
#include "capwap_network.h"
#include "capwap_socket.h"
#include <cyassl/options.h>
#include <cyassl/ssl.h>
/* */
static int capwap_socket_nonblocking(int sock, int nonblocking) {
int flags;
ASSERT(sock >= 0);
/* Retrieve file descriptor flags */
flags = fcntl(sock, F_GETFL, NULL);
if (flags < 0) {
return 0;
}
if (nonblocking) {
flags |= O_NONBLOCK;
} else {
flags &= ~O_NONBLOCK;
}
if(fcntl(sock, F_SETFL, flags) < 0) {
return 0;
}
return 1;
}
/* */
int capwap_socket_connect(int sock, union sockaddr_capwap* address, int timeout) {
int result;
struct pollfd fds;
socklen_t size;
ASSERT(sock >= 0);
ASSERT(address != NULL);
/* Non blocking socket */
if (!capwap_socket_nonblocking(sock, 1)) {
return 0;
}
/* */
result = connect(sock, &address->sa, sizeof(union sockaddr_capwap));
if (result < 0) {
if (errno == EINPROGRESS) {
/* Wait to connection complete */
for (;;) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = POLLOUT;
result = poll(&fds, 1, timeout);
if (!result || ((result < 0) && (errno != EINTR))) {
return 0;
} else if (result > 0) {
/* Check connection status */
size = sizeof(int);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&result, &size) < 0) {
return 0;
}
if (result) {
return 0;
}
/* Connection complete */
break;
}
}
} else {
/* Unable to connect to remote host */
return 0;
}
}
return 1;
}
/* */
static int capwap_socket_crypto_verifycertificate(int preverify, CYASSL_X509_STORE_CTX* store) {
return preverify;
}
/* */
void* capwap_socket_crypto_createcontext(char* calist, char* cert, char* privatekey) {
CYASSL_CTX* context = NULL;
ASSERT(calist != NULL);
ASSERT(cert != NULL);
ASSERT(privatekey != NULL);
/* Create SSL context */
context = CyaSSL_CTX_new(CyaTLSv1_2_client_method());
if (context) {
/* Public certificate */
if (!CyaSSL_CTX_use_certificate_file(context, cert, SSL_FILETYPE_PEM)) {
capwap_logging_debug("Error to load certificate file");
capwap_socket_crypto_freecontext(context);
return NULL;
}
/* Private key */
if (!CyaSSL_CTX_use_PrivateKey_file(context, privatekey, SSL_FILETYPE_PEM)) {
capwap_logging_debug("Error to load private key file");
capwap_socket_crypto_freecontext(context);
return NULL;
}
if (!CyaSSL_CTX_check_private_key(context)) {
capwap_logging_debug("Error to check private key");
capwap_socket_crypto_freecontext(context);
return NULL;
}
/* Certificate Authority */
if (!CyaSSL_CTX_load_verify_locations(context, calist, NULL)) {
capwap_logging_debug("Error to load ca file");
capwap_socket_crypto_freecontext(context);
return NULL;
}
/* Verify certificate callback */
CyaSSL_CTX_set_verify(context, SSL_VERIFY_PEER, capwap_socket_crypto_verifycertificate);
/* Set only high security cipher list */
if (!CyaSSL_CTX_set_cipher_list(context, "AES256-SHA")) {
capwap_logging_debug("Error to select cipher list");
capwap_socket_crypto_freecontext(context);
return NULL;
}
}
return (void*)context;
}
/* */
void capwap_socket_crypto_freecontext(void* context) {
CYASSL_CTX* sslcontext = (CYASSL_CTX*)context;
if (sslcontext) {
CyaSSL_CTX_free(sslcontext);
}
}
/* */
struct capwap_socket_ssl* capwap_socket_ssl_connect(int sock, void* sslcontext, int timeout) {
int result;
struct pollfd fds;
struct capwap_socket_ssl* sslsock;
ASSERT(sock >= 0);
ASSERT(sslcontext != NULL);
/* Create SSL session */
sslsock = capwap_alloc(sizeof(struct capwap_socket_ssl));
sslsock->sock = sock;
sslsock->sslcontext = sslcontext;
sslsock->sslsession = (void*)CyaSSL_new((CYASSL_CTX*)sslcontext);
if (!sslsock->sslsession) {
capwap_free(sslsock);
return NULL;
}
/* Set socket to SSL session */
if (!CyaSSL_set_fd((CYASSL*)sslsock->sslsession, sock)) {
CyaSSL_free((CYASSL*)sslsock->sslsession);
capwap_free(sslsock);
return NULL;
}
/* */
CyaSSL_set_using_nonblock((CYASSL*)sslsock->sslsession, 1);
/* Establish SSL connection */
for (;;) {
result = CyaSSL_connect((CYASSL*)sslsock->sslsession);
if (result == SSL_SUCCESS) {
break; /* Connection complete */
} else {
int error = CyaSSL_get_error((CYASSL*)sslsock->sslsession, 0);
if ((error == SSL_ERROR_WANT_READ) || (error == SSL_ERROR_WANT_WRITE)) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = ((error == SSL_ERROR_WANT_READ) ? POLLIN : POLLOUT);
result = poll(&fds, 1, timeout);
if (((result < 0) && (errno != EINTR)) || ((result > 0) && (fds.events != fds.revents))) {
CyaSSL_free((CYASSL*)sslsock->sslsession);
capwap_free(sslsock);
return NULL;
}
} else {
CyaSSL_free((CYASSL*)sslsock->sslsession);
capwap_free(sslsock);
return NULL;
}
}
}
return sslsock;
}
/* */
int capwap_socket_crypto_send(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout) {
int result;
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
ASSERT(sslsock->sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
result = CyaSSL_write((CYASSL*)sslsock->sslsession, buffer, length);
if (result != length) {
return -1;
}
return length;
}
/* */
int capwap_socket_crypto_recv(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout) {
int result;
struct pollfd fds;
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
ASSERT(sslsock->sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
for (;;) {
result = CyaSSL_read((CYASSL*)sslsock->sslsession, buffer, length);
if (result >= 0) {
return result;
} else {
int error = CyaSSL_get_error((CYASSL*)sslsock->sslsession, 0);
if ((error == SSL_ERROR_WANT_READ) || (error == SSL_ERROR_WANT_WRITE)) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sslsock->sock;
fds.events = ((error == SSL_ERROR_WANT_READ) ? POLLIN : POLLOUT);
result = poll(&fds, 1, timeout);
if (((result < 0) && (errno != EINTR)) || ((result > 0) && (fds.events != fds.revents))) {
break;
}
} else {
break;
}
}
}
return -1;
}
/* */
void capwap_socket_ssl_shutdown(struct capwap_socket_ssl* sslsock, int timeout) {
int result;
struct pollfd fds;
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
ASSERT(sslsock->sock >= 0);
/* */
for (;;) {
result = CyaSSL_shutdown((CYASSL*)sslsock->sslsession);
if (result >= 0) {
break; /* Shutdown complete */
} else {
int error = CyaSSL_get_error((CYASSL*)sslsock->sslsession, 0);
if ((error == SSL_ERROR_WANT_READ) || (error == SSL_ERROR_WANT_WRITE)) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sslsock->sock;
fds.events = ((error == SSL_ERROR_WANT_READ) ? POLLIN : POLLOUT);
result = poll(&fds, 1, timeout);
if (((result < 0) && (errno != EINTR)) || ((result > 0) && (fds.events != fds.revents))) {
break; /* Shutdown error */
}
} else {
break; /* Shutdown error */
}
}
}
}
/* */
void capwap_socket_ssl_close(struct capwap_socket_ssl* sslsock) {
ASSERT(sslsock != NULL);
ASSERT(sslsock->sslsession != NULL);
CyaSSL_free((CYASSL*)sslsock->sslsession);
sslsock->sslsession = NULL;
}
/* */
void capwap_socket_shutdown(int sock) {
ASSERT(sock >= 0);
shutdown(sock, SHUT_RDWR);
}
/* */
void capwap_socket_close(int sock) {
ASSERT(sock >= 0);
capwap_socket_shutdown(sock);
capwap_socket_nonblocking(sock, 0);
close(sock);
}
/* */
int capwap_socket_send(int sock, void* buffer, size_t length, int timeout) {
int result;
struct pollfd fds;
size_t sendlength;
ASSERT(sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
sendlength = 0;
while (sendlength < length) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = POLLOUT;
result = poll(&fds, 1, timeout);
if ((result < 0) && (errno != EINTR)) {
return -1;
} else if (result > 0) {
if (fds.revents == POLLOUT) {
size_t leftlength = length - sendlength;
result = send(sock, &((char*)buffer)[sendlength], leftlength, 0);
if ((result < 0) && (errno != EINTR)) {
return -1;
} else if (result > 0) {
sendlength += result;
}
} else {
return -1;
}
}
}
return sendlength;
}
/* */
int capwap_socket_recv(int sock, void* buffer, size_t length, int timeout) {
int result;
struct pollfd fds;
ASSERT(sock >= 0);
ASSERT(buffer != NULL);
ASSERT(length > 0);
for (;;) {
memset(&fds, 0, sizeof(struct pollfd));
fds.fd = sock;
fds.events = POLLIN;
result = poll(&fds, 1, timeout);
if ((result < 0) && (errno != EINTR)) {
break;
} else if (result > 0) {
if (fds.revents == POLLIN) {
result = recv(sock, buffer, length, 0);
if ((result < 0) && (errno != EINTR)) {
break;
} else if (result >= 0) {
return result;
}
} else {
break;
}
}
}
return -1;
}

View File

@ -1,30 +1,30 @@
#ifndef __CAPWAP_SOCKET_HEADER__
#define __CAPWAP_SOCKET_HEADER__
/* */
int capwap_socket_connect(int sock, union sockaddr_capwap* address, int timeout);
void capwap_socket_shutdown(int sock);
void capwap_socket_close(int sock);
/* Plain send/recv */
int capwap_socket_send(int sock, void* buffer, size_t length, int timeout);
int capwap_socket_recv(int sock, void* buffer, size_t length, int timeout);
/* SSL send/recv */
struct capwap_socket_ssl {
int sock;
void* sslcontext;
void* sslsession;
};
void* capwap_socket_crypto_createcontext(char* calist, char* cert, char* privatekey);
void capwap_socket_crypto_freecontext(void* context);
int capwap_socket_crypto_send(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout);
int capwap_socket_crypto_recv(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout);
struct capwap_socket_ssl* capwap_socket_ssl_connect(int sock, void* sslcontext, int timeout);
void capwap_socket_ssl_shutdown(struct capwap_socket_ssl* sslsock, int timeout);
void capwap_socket_ssl_close(struct capwap_socket_ssl* sslsock);
#endif /* __CAPWAP_SOCKET_HEADER__ */
#ifndef __CAPWAP_SOCKET_HEADER__
#define __CAPWAP_SOCKET_HEADER__
/* */
int capwap_socket_connect(int sock, union sockaddr_capwap* address, int timeout);
void capwap_socket_shutdown(int sock);
void capwap_socket_close(int sock);
/* Plain send/recv */
int capwap_socket_send(int sock, void* buffer, size_t length, int timeout);
int capwap_socket_recv(int sock, void* buffer, size_t length, int timeout);
/* SSL send/recv */
struct capwap_socket_ssl {
int sock;
void* sslcontext;
void* sslsession;
};
void* capwap_socket_crypto_createcontext(char* calist, char* cert, char* privatekey);
void capwap_socket_crypto_freecontext(void* context);
int capwap_socket_crypto_send(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout);
int capwap_socket_crypto_recv(struct capwap_socket_ssl* sslsock, void* buffer, size_t length, int timeout);
struct capwap_socket_ssl* capwap_socket_ssl_connect(int sock, void* sslcontext, int timeout);
void capwap_socket_ssl_shutdown(struct capwap_socket_ssl* sslsock, int timeout);
void capwap_socket_ssl_close(struct capwap_socket_ssl* sslsock);
#endif /* __CAPWAP_SOCKET_HEADER__ */

View File

@ -1,342 +1,342 @@
#include "capwap.h"
/* */
#define CAPWAP_TIMEOUT_HASH_COUNT 128
/* */
/* #define CAPWAP_TIMEOUT_LOGGING_DEBUG 1 */
/* */
static unsigned long capwap_timeout_hash_item_gethash(const void* key, unsigned long hashsize) {
return (*((unsigned long*)key) % hashsize);
}
/* */
static const void* capwap_timeout_hash_item_getkey(const void* data) {
return (const void*)&((struct capwap_timeout_item*)((struct capwap_list_item*)data)->item)->index;
}
/* */
static int capwap_timeout_hash_item_cmp(const void* key1, const void* key2) {
unsigned long value1 = *(unsigned long*)key1;
unsigned long value2 = *(unsigned long*)key2;
return ((value1 == value2) ? 0 : ((value1 < value2) ? -1 : 1));
}
/* */
static long capwap_timeout_getdelta(struct timeval* time1, struct timeval* time2) {
return (time1->tv_sec - time2->tv_sec) * 1000 + (time1->tv_usec - time2->tv_usec) / 1000;
}
/* */
static unsigned long capwap_timeout_set_bitfield(struct capwap_timeout* timeout) {
int i, j;
ASSERT(timeout != NULL);
/* Search free bitfield */
for (i = 0; i < CAPWAP_TIMEOUT_BITFIELD_SIZE; i++) {
if (timeout->timeoutbitfield[i] != 0xffffffff) {
uint32_t bitfield = timeout->timeoutbitfield[i];
for (j = 0; j < 32; j++) {
if (!(bitfield & (1 << j))) {
timeout->timeoutbitfield[i] |= (1 << j);
return (i * 32 + j + 1);
}
}
}
}
return CAPWAP_TIMEOUT_INDEX_NO_SET;
}
/* */
static void capwap_timeout_clear_bitfield(struct capwap_timeout* timeout, unsigned long value) {
ASSERT(timeout != NULL);
ASSERT(value > 0);
timeout->timeoutbitfield[(value - 1) / 32] &= ~(1 << ((value - 1) % 32));
}
/* */
static void capwap_timeout_additem(struct capwap_list* itemstimeout, struct capwap_list_item* itemlist) {
struct capwap_list_item* search;
struct capwap_list_item* last = NULL;
struct capwap_timeout_item* item = (struct capwap_timeout_item*)itemlist->item;
/* */
search = itemstimeout->first;
while (search) {
struct capwap_timeout_item* itemsearch = (struct capwap_timeout_item*)search->item;
if (capwap_timeout_getdelta(&item->expire, &itemsearch->expire) < 0) {
capwap_itemlist_insert_before(itemstimeout, last, itemlist);
break;
}
/* Next */
last = search;
search = search->next;
}
/* */
if (!search) {
capwap_itemlist_insert_after(itemstimeout, NULL, itemlist);
}
}
/* */
static void capwap_timeout_setexpire(long durate, struct timeval* now, struct timeval* expire) {
expire->tv_sec = now->tv_sec + durate / 1000;
expire->tv_usec = now->tv_usec + durate % 1000;
if (expire->tv_usec >= 1000000) {
expire->tv_sec++;
expire->tv_usec -= 1000000;
}
}
/* */
struct capwap_timeout* capwap_timeout_init(void) {
struct capwap_timeout* timeout;
/* */
timeout = (struct capwap_timeout*)capwap_alloc(sizeof(struct capwap_timeout));
memset(timeout, 0, sizeof(struct capwap_timeout));
/* */
timeout->itemsreference = capwap_hash_create(CAPWAP_TIMEOUT_HASH_COUNT);
timeout->itemsreference->item_gethash = capwap_timeout_hash_item_gethash;
timeout->itemsreference->item_getkey = capwap_timeout_hash_item_getkey;
timeout->itemsreference->item_cmp = capwap_timeout_hash_item_cmp;
timeout->itemstimeout = capwap_list_create();
return timeout;
}
/* */
void capwap_timeout_free(struct capwap_timeout* timeout) {
ASSERT(timeout != NULL);
capwap_hash_free(timeout->itemsreference);
capwap_list_free(timeout->itemstimeout);
capwap_free(timeout);
}
/* */
unsigned long capwap_timeout_createtimer(struct capwap_timeout* timeout) {
unsigned long index;
ASSERT(timeout != NULL);
/* Create new timeout index */
index = capwap_timeout_set_bitfield(timeout);
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Create new timer: %lu", index);
#endif
return index;
}
/* */
void capwap_timeout_deletetimer(struct capwap_timeout* timeout, unsigned long index) {
ASSERT(timeout != NULL);
if (index != CAPWAP_TIMEOUT_INDEX_NO_SET) {
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Delete timer: %lu", index);
#endif
/* Unset timeout timer */
capwap_timeout_unset(timeout, index);
/* Release timer index */
capwap_timeout_clear_bitfield(timeout, index);
}
}
/* */
unsigned long capwap_timeout_set(struct capwap_timeout* timeout, unsigned long index, long durate, capwap_timeout_expire callback, void* context, void* param) {
struct capwap_list_item* itemlist;
struct capwap_timeout_item* item;
struct timeval now;
ASSERT(timeout != NULL);
ASSERT(durate >= 0);
gettimeofday(&now, NULL);
if (index == CAPWAP_TIMEOUT_INDEX_NO_SET) {
index = capwap_timeout_createtimer(timeout);
} else {
/* Check can update timeout timer */
itemlist = (struct capwap_list_item*)capwap_hash_search(timeout->itemsreference, &index);
if (itemlist) {
/* Remove from timeout list */
capwap_itemlist_remove(timeout->itemstimeout, itemlist);
/* Update timeout */
item = (struct capwap_timeout_item*)itemlist->item;
item->durate = durate;
capwap_timeout_setexpire(item->durate, &now, &item->expire);
item->callback = callback;
item->context = context;
item->param = param;
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Update timeout: %lu %ld", item->index, item->durate);
#endif
/* Add itemlist into order list */
capwap_timeout_additem(timeout->itemstimeout, itemlist);
return index;
}
}
/* Create new timeout timer */
itemlist = capwap_itemlist_create(sizeof(struct capwap_timeout_item));
item = (struct capwap_timeout_item*)itemlist->item;
/* */
item->index = index;
item->durate = durate;
capwap_timeout_setexpire(item->durate, &now, &item->expire);
item->callback = callback;
item->context = context;
item->param = param;
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Set timeout: %lu %ld", item->index, item->durate);
#endif
/* Add itemlist into hash for rapid searching */
capwap_hash_add(timeout->itemsreference, (void*)itemlist);
/* Add itemlist into order list */
capwap_timeout_additem(timeout->itemstimeout, itemlist);
return item->index;
}
/* */
void capwap_timeout_unset(struct capwap_timeout* timeout, unsigned long index) {
struct capwap_list_item* itemlist;
ASSERT(timeout != NULL);
if (index != CAPWAP_TIMEOUT_INDEX_NO_SET) {
itemlist = (struct capwap_list_item*)capwap_hash_search(timeout->itemsreference, &index);
if (itemlist) {
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Unset timeout: %lu", index);
#endif
/* */
capwap_hash_delete(timeout->itemsreference, &index);
capwap_itemlist_free(capwap_itemlist_remove(timeout->itemstimeout, itemlist));
}
}
}
/* */
void capwap_timeout_unsetall(struct capwap_timeout* timeout) {
capwap_hash_deleteall(timeout->itemsreference);
capwap_list_flush(timeout->itemstimeout);
}
/* */
long capwap_timeout_getcoming(struct capwap_timeout* timeout) {
long delta;
struct timeval now;
struct capwap_list_item* search;
struct capwap_timeout_item* item;
ASSERT(timeout != NULL);
/* */
search = timeout->itemstimeout->first;
if (!search) {
return CAPWAP_TIMEOUT_INFINITE;
}
/* */
gettimeofday(&now, NULL);
item = (struct capwap_timeout_item*)search->item;
delta = capwap_timeout_getdelta(&item->expire, &now);
if (delta <= 0) {
return 0;
} else if (delta <= item->durate) {
return delta;
}
/* Recalculate all timeouts because delta > item->durate */
while (search) {
struct capwap_timeout_item* itemsearch = (struct capwap_timeout_item*)search->item;
capwap_timeout_setexpire(itemsearch->durate, &now, &itemsearch->expire);
search = search->next;
}
return item->durate;
}
/* */
unsigned long capwap_timeout_hasexpired(struct capwap_timeout* timeout) {
long delta;
struct capwap_timeout_item* item;
struct capwap_list_item* itemlist;
unsigned long index;
capwap_timeout_expire callback;
void* context;
void* param;
ASSERT(timeout != NULL);
/* */
delta = capwap_timeout_getcoming(timeout);
if ((delta > 0) || (delta == CAPWAP_TIMEOUT_INFINITE)) {
return 0;
}
/* */
itemlist = capwap_itemlist_remove_head(timeout->itemstimeout);
item = (struct capwap_timeout_item*)itemlist->item;
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Expired timeout: %lu", item->index);
#endif
/* Cache callback before release timeout timer */
index = item->index;
callback = item->callback;
context = item->context;
param = item->param;
/* Free memory */
capwap_hash_delete(timeout->itemsreference, &index);
capwap_itemlist_free(itemlist);
/* */
if (callback) {
callback(timeout, index, context, param);
}
return index;
}
/* */
int capwap_timeout_wait(long durate) {
if (durate < 0) {
return -1;
} else if (durate > 0) {
if (usleep((useconds_t)durate * 1000)) {
return ((errno == EINTR) ? 0 : -1);
}
}
return 1;
}
#include "capwap.h"
/* */
#define CAPWAP_TIMEOUT_HASH_COUNT 128
/* */
/* #define CAPWAP_TIMEOUT_LOGGING_DEBUG 1 */
/* */
static unsigned long capwap_timeout_hash_item_gethash(const void* key, unsigned long hashsize) {
return (*((unsigned long*)key) % hashsize);
}
/* */
static const void* capwap_timeout_hash_item_getkey(const void* data) {
return (const void*)&((struct capwap_timeout_item*)((struct capwap_list_item*)data)->item)->index;
}
/* */
static int capwap_timeout_hash_item_cmp(const void* key1, const void* key2) {
unsigned long value1 = *(unsigned long*)key1;
unsigned long value2 = *(unsigned long*)key2;
return ((value1 == value2) ? 0 : ((value1 < value2) ? -1 : 1));
}
/* */
static long capwap_timeout_getdelta(struct timeval* time1, struct timeval* time2) {
return (time1->tv_sec - time2->tv_sec) * 1000 + (time1->tv_usec - time2->tv_usec) / 1000;
}
/* */
static unsigned long capwap_timeout_set_bitfield(struct capwap_timeout* timeout) {
int i, j;
ASSERT(timeout != NULL);
/* Search free bitfield */
for (i = 0; i < CAPWAP_TIMEOUT_BITFIELD_SIZE; i++) {
if (timeout->timeoutbitfield[i] != 0xffffffff) {
uint32_t bitfield = timeout->timeoutbitfield[i];
for (j = 0; j < 32; j++) {
if (!(bitfield & (1 << j))) {
timeout->timeoutbitfield[i] |= (1 << j);
return (i * 32 + j + 1);
}
}
}
}
return CAPWAP_TIMEOUT_INDEX_NO_SET;
}
/* */
static void capwap_timeout_clear_bitfield(struct capwap_timeout* timeout, unsigned long value) {
ASSERT(timeout != NULL);
ASSERT(value > 0);
timeout->timeoutbitfield[(value - 1) / 32] &= ~(1 << ((value - 1) % 32));
}
/* */
static void capwap_timeout_additem(struct capwap_list* itemstimeout, struct capwap_list_item* itemlist) {
struct capwap_list_item* search;
struct capwap_list_item* last = NULL;
struct capwap_timeout_item* item = (struct capwap_timeout_item*)itemlist->item;
/* */
search = itemstimeout->first;
while (search) {
struct capwap_timeout_item* itemsearch = (struct capwap_timeout_item*)search->item;
if (capwap_timeout_getdelta(&item->expire, &itemsearch->expire) < 0) {
capwap_itemlist_insert_before(itemstimeout, last, itemlist);
break;
}
/* Next */
last = search;
search = search->next;
}
/* */
if (!search) {
capwap_itemlist_insert_after(itemstimeout, NULL, itemlist);
}
}
/* */
static void capwap_timeout_setexpire(long durate, struct timeval* now, struct timeval* expire) {
expire->tv_sec = now->tv_sec + durate / 1000;
expire->tv_usec = now->tv_usec + durate % 1000;
if (expire->tv_usec >= 1000000) {
expire->tv_sec++;
expire->tv_usec -= 1000000;
}
}
/* */
struct capwap_timeout* capwap_timeout_init(void) {
struct capwap_timeout* timeout;
/* */
timeout = (struct capwap_timeout*)capwap_alloc(sizeof(struct capwap_timeout));
memset(timeout, 0, sizeof(struct capwap_timeout));
/* */
timeout->itemsreference = capwap_hash_create(CAPWAP_TIMEOUT_HASH_COUNT);
timeout->itemsreference->item_gethash = capwap_timeout_hash_item_gethash;
timeout->itemsreference->item_getkey = capwap_timeout_hash_item_getkey;
timeout->itemsreference->item_cmp = capwap_timeout_hash_item_cmp;
timeout->itemstimeout = capwap_list_create();
return timeout;
}
/* */
void capwap_timeout_free(struct capwap_timeout* timeout) {
ASSERT(timeout != NULL);
capwap_hash_free(timeout->itemsreference);
capwap_list_free(timeout->itemstimeout);
capwap_free(timeout);
}
/* */
unsigned long capwap_timeout_createtimer(struct capwap_timeout* timeout) {
unsigned long index;
ASSERT(timeout != NULL);
/* Create new timeout index */
index = capwap_timeout_set_bitfield(timeout);
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Create new timer: %lu", index);
#endif
return index;
}
/* */
void capwap_timeout_deletetimer(struct capwap_timeout* timeout, unsigned long index) {
ASSERT(timeout != NULL);
if (index != CAPWAP_TIMEOUT_INDEX_NO_SET) {
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Delete timer: %lu", index);
#endif
/* Unset timeout timer */
capwap_timeout_unset(timeout, index);
/* Release timer index */
capwap_timeout_clear_bitfield(timeout, index);
}
}
/* */
unsigned long capwap_timeout_set(struct capwap_timeout* timeout, unsigned long index, long durate, capwap_timeout_expire callback, void* context, void* param) {
struct capwap_list_item* itemlist;
struct capwap_timeout_item* item;
struct timeval now;
ASSERT(timeout != NULL);
ASSERT(durate >= 0);
gettimeofday(&now, NULL);
if (index == CAPWAP_TIMEOUT_INDEX_NO_SET) {
index = capwap_timeout_createtimer(timeout);
} else {
/* Check can update timeout timer */
itemlist = (struct capwap_list_item*)capwap_hash_search(timeout->itemsreference, &index);
if (itemlist) {
/* Remove from timeout list */
capwap_itemlist_remove(timeout->itemstimeout, itemlist);
/* Update timeout */
item = (struct capwap_timeout_item*)itemlist->item;
item->durate = durate;
capwap_timeout_setexpire(item->durate, &now, &item->expire);
item->callback = callback;
item->context = context;
item->param = param;
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Update timeout: %lu %ld", item->index, item->durate);
#endif
/* Add itemlist into order list */
capwap_timeout_additem(timeout->itemstimeout, itemlist);
return index;
}
}
/* Create new timeout timer */
itemlist = capwap_itemlist_create(sizeof(struct capwap_timeout_item));
item = (struct capwap_timeout_item*)itemlist->item;
/* */
item->index = index;
item->durate = durate;
capwap_timeout_setexpire(item->durate, &now, &item->expire);
item->callback = callback;
item->context = context;
item->param = param;
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Set timeout: %lu %ld", item->index, item->durate);
#endif
/* Add itemlist into hash for rapid searching */
capwap_hash_add(timeout->itemsreference, (void*)itemlist);
/* Add itemlist into order list */
capwap_timeout_additem(timeout->itemstimeout, itemlist);
return item->index;
}
/* */
void capwap_timeout_unset(struct capwap_timeout* timeout, unsigned long index) {
struct capwap_list_item* itemlist;
ASSERT(timeout != NULL);
if (index != CAPWAP_TIMEOUT_INDEX_NO_SET) {
itemlist = (struct capwap_list_item*)capwap_hash_search(timeout->itemsreference, &index);
if (itemlist) {
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Unset timeout: %lu", index);
#endif
/* */
capwap_hash_delete(timeout->itemsreference, &index);
capwap_itemlist_free(capwap_itemlist_remove(timeout->itemstimeout, itemlist));
}
}
}
/* */
void capwap_timeout_unsetall(struct capwap_timeout* timeout) {
capwap_hash_deleteall(timeout->itemsreference);
capwap_list_flush(timeout->itemstimeout);
}
/* */
long capwap_timeout_getcoming(struct capwap_timeout* timeout) {
long delta;
struct timeval now;
struct capwap_list_item* search;
struct capwap_timeout_item* item;
ASSERT(timeout != NULL);
/* */
search = timeout->itemstimeout->first;
if (!search) {
return CAPWAP_TIMEOUT_INFINITE;
}
/* */
gettimeofday(&now, NULL);
item = (struct capwap_timeout_item*)search->item;
delta = capwap_timeout_getdelta(&item->expire, &now);
if (delta <= 0) {
return 0;
} else if (delta <= item->durate) {
return delta;
}
/* Recalculate all timeouts because delta > item->durate */
while (search) {
struct capwap_timeout_item* itemsearch = (struct capwap_timeout_item*)search->item;
capwap_timeout_setexpire(itemsearch->durate, &now, &itemsearch->expire);
search = search->next;
}
return item->durate;
}
/* */
unsigned long capwap_timeout_hasexpired(struct capwap_timeout* timeout) {
long delta;
struct capwap_timeout_item* item;
struct capwap_list_item* itemlist;
unsigned long index;
capwap_timeout_expire callback;
void* context;
void* param;
ASSERT(timeout != NULL);
/* */
delta = capwap_timeout_getcoming(timeout);
if ((delta > 0) || (delta == CAPWAP_TIMEOUT_INFINITE)) {
return 0;
}
/* */
itemlist = capwap_itemlist_remove_head(timeout->itemstimeout);
item = (struct capwap_timeout_item*)itemlist->item;
#ifdef CAPWAP_TIMEOUT_LOGGING_DEBUG
capwap_logging_debug("Expired timeout: %lu", item->index);
#endif
/* Cache callback before release timeout timer */
index = item->index;
callback = item->callback;
context = item->context;
param = item->param;
/* Free memory */
capwap_hash_delete(timeout->itemsreference, &index);
capwap_itemlist_free(itemlist);
/* */
if (callback) {
callback(timeout, index, context, param);
}
return index;
}
/* */
int capwap_timeout_wait(long durate) {
if (durate < 0) {
return -1;
} else if (durate > 0) {
if (usleep((useconds_t)durate * 1000)) {
return ((errno == EINTR) ? 0 : -1);
}
}
return 1;
}

View File

@ -1,49 +1,49 @@
#ifndef __CAPWAP_TIMEOUT_HEADER__
#define __CAPWAP_TIMEOUT_HEADER__
#include "capwap_hash.h"
#include "capwap_list.h"
/* */
#define CAPWAP_TIMEOUT_BITFIELD_SIZE 128
#define CAPWAP_TIMEOUT_INFINITE -1
#define CAPWAP_TIMEOUT_INDEX_NO_SET 0
/* */
struct capwap_timeout {
uint32_t timeoutbitfield[CAPWAP_TIMEOUT_BITFIELD_SIZE];
struct capwap_hash* itemsreference;
struct capwap_list* itemstimeout;
};
/* */
typedef void (*capwap_timeout_expire)(struct capwap_timeout* timeout, unsigned long index, void* context, void* param);
struct capwap_timeout_item {
unsigned long index;
long durate;
struct timeval expire;
capwap_timeout_expire callback;
void* context;
void* param;
};
/* */
struct capwap_timeout* capwap_timeout_init(void);
void capwap_timeout_free(struct capwap_timeout* timeout);
/* */
unsigned long capwap_timeout_createtimer(struct capwap_timeout* timeout);
void capwap_timeout_deletetimer(struct capwap_timeout* timeout, unsigned long index);
/* */
unsigned long capwap_timeout_set(struct capwap_timeout* timeout, unsigned long index, long durate, capwap_timeout_expire callback, void* context, void* param);
void capwap_timeout_unset(struct capwap_timeout* timeout, unsigned long index);
void capwap_timeout_unsetall(struct capwap_timeout* timeout);
long capwap_timeout_getcoming(struct capwap_timeout* timeout);
unsigned long capwap_timeout_hasexpired(struct capwap_timeout* timeout);
int capwap_timeout_wait(long durate);
#endif /* __CAPWAP_TIMEOUT_HEADER__ */
#ifndef __CAPWAP_TIMEOUT_HEADER__
#define __CAPWAP_TIMEOUT_HEADER__
#include "capwap_hash.h"
#include "capwap_list.h"
/* */
#define CAPWAP_TIMEOUT_BITFIELD_SIZE 128
#define CAPWAP_TIMEOUT_INFINITE -1
#define CAPWAP_TIMEOUT_INDEX_NO_SET 0
/* */
struct capwap_timeout {
uint32_t timeoutbitfield[CAPWAP_TIMEOUT_BITFIELD_SIZE];
struct capwap_hash* itemsreference;
struct capwap_list* itemstimeout;
};
/* */
typedef void (*capwap_timeout_expire)(struct capwap_timeout* timeout, unsigned long index, void* context, void* param);
struct capwap_timeout_item {
unsigned long index;
long durate;
struct timeval expire;
capwap_timeout_expire callback;
void* context;
void* param;
};
/* */
struct capwap_timeout* capwap_timeout_init(void);
void capwap_timeout_free(struct capwap_timeout* timeout);
/* */
unsigned long capwap_timeout_createtimer(struct capwap_timeout* timeout);
void capwap_timeout_deletetimer(struct capwap_timeout* timeout, unsigned long index);
/* */
unsigned long capwap_timeout_set(struct capwap_timeout* timeout, unsigned long index, long durate, capwap_timeout_expire callback, void* context, void* param);
void capwap_timeout_unset(struct capwap_timeout* timeout, unsigned long index);
void capwap_timeout_unsetall(struct capwap_timeout* timeout);
long capwap_timeout_getcoming(struct capwap_timeout* timeout);
unsigned long capwap_timeout_hasexpired(struct capwap_timeout* timeout);
int capwap_timeout_wait(long durate);
#endif /* __CAPWAP_TIMEOUT_HEADER__ */

View File

@ -1,155 +1,155 @@
#include "capwap.h"
#include "capwap_network.h"
#include <linux/socket.h>
#include "wifi_drivers.h"
#include "netlink_link.h"
/* */
struct netlink_request {
struct nlmsghdr hdr;
struct ifinfomsg ifinfo;
char opts[16];
};
/* */
struct netlink* netlink_init(void) {
int sock;
struct sockaddr_nl local;
struct netlink* netlinkhandle;
/* Create netlink socket */
sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (sock < 0) {
return NULL;
}
/* Bind to kernel */
memset(&local, 0, sizeof(struct sockaddr_nl));
local.nl_family = AF_NETLINK;
local.nl_groups = RTMGRP_LINK;
if (bind(sock, (struct sockaddr*)&local, sizeof(struct sockaddr_nl)) < 0) {
close(sock);
return NULL;
}
/* Netlink reference */
netlinkhandle = (struct netlink*)capwap_alloc(sizeof(struct netlink));
netlinkhandle->sock = sock;
netlinkhandle->nl_sequence = 1;
return netlinkhandle;
}
/* */
void netlink_free(struct netlink* netlinkhandle) {
ASSERT(netlinkhandle != NULL);
ASSERT(netlinkhandle->sock >= 0);
/* */
close(netlinkhandle->sock);
capwap_free(netlinkhandle);
}
/* */
void netlink_event_receive(int fd, void** params, int paramscount) {
int result;
struct netlink* netlinkhandle;
struct sockaddr_nl from;
socklen_t fromlen;
char buffer[8192];
struct nlmsghdr* message;
ASSERT(fd >= 0);
ASSERT(params != NULL);
ASSERT(paramscount == 2);
/* */
netlinkhandle = (struct netlink*)params[0];
/* Retrieve all netlink message */
for (;;) {
/* Get message */
fromlen = sizeof(struct sockaddr_nl);
result = recvfrom(netlinkhandle->sock, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr*)&from, &fromlen);
if (result <= 0) {
if (errno == EINTR) {
continue;
}
/* */
break;
}
/* Parsing message */
message = (struct nlmsghdr*)buffer;
while (NLMSG_OK(message, result)) {
switch (message->nlmsg_type) {
case RTM_NEWLINK: {
if (netlinkhandle->newlink_event && NLMSG_PAYLOAD(message, 0) >= sizeof(struct ifinfomsg)) {
netlinkhandle->newlink_event((wifi_global_handle)params[1], NLMSG_DATA(message), (uint8_t*)(NLMSG_DATA(message) + NLMSG_ALIGN(sizeof(struct ifinfomsg))), NLMSG_PAYLOAD(message, sizeof(struct ifinfomsg)));
}
break;
}
case RTM_DELLINK: {
if (netlinkhandle->dellink_event && NLMSG_PAYLOAD(message, 0) >= sizeof(struct ifinfomsg)) {
netlinkhandle->dellink_event((wifi_global_handle)params[1], NLMSG_DATA(message), (uint8_t*)(NLMSG_DATA(message) + NLMSG_ALIGN(sizeof(struct ifinfomsg))), NLMSG_PAYLOAD(message, sizeof(struct ifinfomsg)));
}
break;
}
}
/* */
message = NLMSG_NEXT(message, result);
}
}
}
int netlink_set_link_status(struct netlink* netlinkhandle, int ifindex, int linkmode, int operstate) {
char* data;
struct rtattr* rta;
struct netlink_request request;
ASSERT(netlinkhandle != NULL);
ASSERT(ifindex >= 0);
/* */
memset(&request, 0, sizeof(struct netlink_request));
request.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
request.hdr.nlmsg_type = RTM_SETLINK;
request.hdr.nlmsg_flags = NLM_F_REQUEST;
request.hdr.nlmsg_seq = netlinkhandle->nl_sequence++;
request.hdr.nlmsg_pid = 0;
request.ifinfo.ifi_family = AF_UNSPEC;
request.ifinfo.ifi_type = 0;
request.ifinfo.ifi_index = ifindex;
request.ifinfo.ifi_flags = 0;
request.ifinfo.ifi_change = 0;
if (linkmode != -1) {
rta = (struct rtattr*)((char*)&request + NLMSG_ALIGN(request.hdr.nlmsg_len));
rta->rta_type = IFLA_LINKMODE;
rta->rta_len = RTA_LENGTH(sizeof(char));
data = (char*)RTA_DATA(rta);
*data = (char)linkmode;
request.hdr.nlmsg_len = NLMSG_ALIGN(request.hdr.nlmsg_len) + RTA_LENGTH(sizeof(char));
}
if (operstate != -1) {
rta = (struct rtattr*)((char*)&request + NLMSG_ALIGN(request.hdr.nlmsg_len));
rta->rta_type = IFLA_OPERSTATE;
rta->rta_len = RTA_LENGTH(sizeof(char));
data = (char*)RTA_DATA(rta);
*data = (char)operstate;
request.hdr.nlmsg_len = NLMSG_ALIGN(request.hdr.nlmsg_len) + RTA_LENGTH(sizeof(char));
}
/* Send new interface operation state */
if (send(netlinkhandle->sock, &request, request.hdr.nlmsg_len, 0) < 0) {
return -1;
}
return 0;
}
#include "capwap.h"
#include "capwap_network.h"
#include <linux/socket.h>
#include "wifi_drivers.h"
#include "netlink_link.h"
/* */
struct netlink_request {
struct nlmsghdr hdr;
struct ifinfomsg ifinfo;
char opts[16];
};
/* */
struct netlink* netlink_init(void) {
int sock;
struct sockaddr_nl local;
struct netlink* netlinkhandle;
/* Create netlink socket */
sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (sock < 0) {
return NULL;
}
/* Bind to kernel */
memset(&local, 0, sizeof(struct sockaddr_nl));
local.nl_family = AF_NETLINK;
local.nl_groups = RTMGRP_LINK;
if (bind(sock, (struct sockaddr*)&local, sizeof(struct sockaddr_nl)) < 0) {
close(sock);
return NULL;
}
/* Netlink reference */
netlinkhandle = (struct netlink*)capwap_alloc(sizeof(struct netlink));
netlinkhandle->sock = sock;
netlinkhandle->nl_sequence = 1;
return netlinkhandle;
}
/* */
void netlink_free(struct netlink* netlinkhandle) {
ASSERT(netlinkhandle != NULL);
ASSERT(netlinkhandle->sock >= 0);
/* */
close(netlinkhandle->sock);
capwap_free(netlinkhandle);
}
/* */
void netlink_event_receive(int fd, void** params, int paramscount) {
int result;
struct netlink* netlinkhandle;
struct sockaddr_nl from;
socklen_t fromlen;
char buffer[8192];
struct nlmsghdr* message;
ASSERT(fd >= 0);
ASSERT(params != NULL);
ASSERT(paramscount == 2);
/* */
netlinkhandle = (struct netlink*)params[0];
/* Retrieve all netlink message */
for (;;) {
/* Get message */
fromlen = sizeof(struct sockaddr_nl);
result = recvfrom(netlinkhandle->sock, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr*)&from, &fromlen);
if (result <= 0) {
if (errno == EINTR) {
continue;
}
/* */
break;
}
/* Parsing message */
message = (struct nlmsghdr*)buffer;
while (NLMSG_OK(message, result)) {
switch (message->nlmsg_type) {
case RTM_NEWLINK: {
if (netlinkhandle->newlink_event && NLMSG_PAYLOAD(message, 0) >= sizeof(struct ifinfomsg)) {
netlinkhandle->newlink_event((wifi_global_handle)params[1], NLMSG_DATA(message), (uint8_t*)(NLMSG_DATA(message) + NLMSG_ALIGN(sizeof(struct ifinfomsg))), NLMSG_PAYLOAD(message, sizeof(struct ifinfomsg)));
}
break;
}
case RTM_DELLINK: {
if (netlinkhandle->dellink_event && NLMSG_PAYLOAD(message, 0) >= sizeof(struct ifinfomsg)) {
netlinkhandle->dellink_event((wifi_global_handle)params[1], NLMSG_DATA(message), (uint8_t*)(NLMSG_DATA(message) + NLMSG_ALIGN(sizeof(struct ifinfomsg))), NLMSG_PAYLOAD(message, sizeof(struct ifinfomsg)));
}
break;
}
}
/* */
message = NLMSG_NEXT(message, result);
}
}
}
int netlink_set_link_status(struct netlink* netlinkhandle, int ifindex, int linkmode, int operstate) {
char* data;
struct rtattr* rta;
struct netlink_request request;
ASSERT(netlinkhandle != NULL);
ASSERT(ifindex >= 0);
/* */
memset(&request, 0, sizeof(struct netlink_request));
request.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
request.hdr.nlmsg_type = RTM_SETLINK;
request.hdr.nlmsg_flags = NLM_F_REQUEST;
request.hdr.nlmsg_seq = netlinkhandle->nl_sequence++;
request.hdr.nlmsg_pid = 0;
request.ifinfo.ifi_family = AF_UNSPEC;
request.ifinfo.ifi_type = 0;
request.ifinfo.ifi_index = ifindex;
request.ifinfo.ifi_flags = 0;
request.ifinfo.ifi_change = 0;
if (linkmode != -1) {
rta = (struct rtattr*)((char*)&request + NLMSG_ALIGN(request.hdr.nlmsg_len));
rta->rta_type = IFLA_LINKMODE;
rta->rta_len = RTA_LENGTH(sizeof(char));
data = (char*)RTA_DATA(rta);
*data = (char)linkmode;
request.hdr.nlmsg_len = NLMSG_ALIGN(request.hdr.nlmsg_len) + RTA_LENGTH(sizeof(char));
}
if (operstate != -1) {
rta = (struct rtattr*)((char*)&request + NLMSG_ALIGN(request.hdr.nlmsg_len));
rta->rta_type = IFLA_OPERSTATE;
rta->rta_len = RTA_LENGTH(sizeof(char));
data = (char*)RTA_DATA(rta);
*data = (char)operstate;
request.hdr.nlmsg_len = NLMSG_ALIGN(request.hdr.nlmsg_len) + RTA_LENGTH(sizeof(char));
}
/* Send new interface operation state */
if (send(netlinkhandle->sock, &request, request.hdr.nlmsg_len, 0) < 0) {
return -1;
}
return 0;
}

View File

@ -1,59 +1,59 @@
#ifndef __NETLINK_LINK_HEADER__
#define __NETLINK_LINK_HEADER__
#include <linux/rtnetlink.h>
#include <linux/netlink.h>
/* */
#ifndef IFLA_IFNAME
#define IFLA_IFNAME 3
#endif
#ifndef IFLA_WIRELESS
#define IFLA_WIRELESS 11
#endif
#ifndef IFLA_OPERSTATE
#define IFLA_OPERSTATE 16
#endif
#ifndef IFLA_LINKMODE
#define IFLA_LINKMODE 17
#endif
#ifndef IF_OPER_DORMANT
#define IF_OPER_DORMANT 5
#endif
#ifndef IF_OPER_UP
#define IF_OPER_UP 6
#endif
#ifndef IFF_LOWER_UP
#define IFF_LOWER_UP 0x10000
#endif
#ifndef IFF_DORMANT
#define IFF_DORMANT 0x20000
#endif
/* */
struct netlink {
int sock;
void (*newlink_event)(wifi_global_handle handle, struct ifinfomsg* infomsg, uint8_t* data, int length);
void (*dellink_event)(wifi_global_handle handle, struct ifinfomsg* infomsg, uint8_t* data, int length);
int nl_sequence;
};
/* */
struct netlink* netlink_init(void);
void netlink_free(struct netlink* netlinkhandle);
/* */
int netlink_set_link_status(struct netlink* netlinkhandle, int ifindex, int linkmode, int operstate);
/* */
void netlink_event_receive(int fd, void** params, int paramscount);
#endif /* __NETLINK_LINK_HEADER__ */
#ifndef __NETLINK_LINK_HEADER__
#define __NETLINK_LINK_HEADER__
#include <linux/rtnetlink.h>
#include <linux/netlink.h>
/* */
#ifndef IFLA_IFNAME
#define IFLA_IFNAME 3
#endif
#ifndef IFLA_WIRELESS
#define IFLA_WIRELESS 11
#endif
#ifndef IFLA_OPERSTATE
#define IFLA_OPERSTATE 16
#endif
#ifndef IFLA_LINKMODE
#define IFLA_LINKMODE 17
#endif
#ifndef IF_OPER_DORMANT
#define IF_OPER_DORMANT 5
#endif
#ifndef IF_OPER_UP
#define IF_OPER_UP 6
#endif
#ifndef IFF_LOWER_UP
#define IFF_LOWER_UP 0x10000
#endif
#ifndef IFF_DORMANT
#define IFF_DORMANT 0x20000
#endif
/* */
struct netlink {
int sock;
void (*newlink_event)(wifi_global_handle handle, struct ifinfomsg* infomsg, uint8_t* data, int length);
void (*dellink_event)(wifi_global_handle handle, struct ifinfomsg* infomsg, uint8_t* data, int length);
int nl_sequence;
};
/* */
struct netlink* netlink_init(void);
void netlink_free(struct netlink* netlinkhandle);
/* */
int netlink_set_link_status(struct netlink* netlinkhandle, int ifindex, int linkmode, int operstate);
/* */
void netlink_event_receive(int fd, void** params, int paramscount);
#endif /* __NETLINK_LINK_HEADER__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,436 +1,436 @@
#ifndef __WIFI_DRIVERS_HEADER__
#define __WIFI_DRIVERS_HEADER__
#include <net/if_arp.h>
#include <linux/if_ether.h>
#include "ieee80211.h"
/* */
#define WIFI_DRIVER_NAME_SIZE 16
/* */
#define WIFI_BAND_UNKNOWN 0
#define WIFI_BAND_2GHZ 1
#define WIFI_BAND_5GHZ 2
/* */
#define WIFI_CAPABILITY_RADIOSUPPORTED 0x00000001
#define WIFI_CAPABILITY_RADIOTYPE 0x00000002
#define WIFI_CAPABILITY_BANDS 0x00000004
#define WIFI_CAPABILITY_CIPHERS 0x00000008
#define WIFI_CAPABILITY_ANTENNA_MASK 0x00000010
#define WIFI_CAPABILITY_MAX_SCAN_SSIDS 0x00000020
#define WIFI_CAPABILITY_MAX_SCHED_SCAN_SSIDS 0x00000040
#define WIFI_CAPABILITY_MAX_MATCH_SETS 0x00000080
#define WIFI_CAPABILITY_MAX_ACL_MACADDRESS 0x00000100
/* */
#define WIFI_CAPABILITY_FLAGS_OFFCHANNEL_TX_OK 0x00000001
#define WIFI_CAPABILITY_FLAGS_ROAM_SUPPORT 0x00000002
#define WIFI_CAPABILITY_FLAGS_SUPPORT_AP_UAPSD 0x00000004
#define WIFI_CAPABILITY_FLAGS_DEVICE_AP_SME 0x00000008
#define WIFI_CAPABILITY_FLAGS_PROBE_RESPONSE_OFFLOAD 0x00000010
/* */
#define WIFI_CAPABILITY_AP_SUPPORTED 0x00000001
#define WIFI_CAPABILITY_AP_VLAN_SUPPORTED 0x00000002
#define WIFI_CAPABILITY_ADHOC_SUPPORTED 0x00000004
#define WIFI_CAPABILITY_MONITOR_SUPPORTED 0x00000008
#define WIFI_CAPABILITY_WDS_SUPPORTED 0x00000010
#define FREQ_CAPABILITY_DISABLED 0x00000001
#define FREQ_CAPABILITY_PASSIVE_SCAN 0x00000002
#define FREQ_CAPABILITY_NO_IBBS 0x00000004
#define FREQ_CAPABILITY_RADAR 0x00000008
#define FREQ_CAPABILITY_DFS_STATE 0x00000010
#define FREQ_CAPABILITY_DFS_TIME 0x00000020
#define RATE_CAPABILITY_SHORTPREAMBLE 0x00000001
#define CIPHER_CAPABILITY_UNKNOWN 0
#define CIPHER_CAPABILITY_WEP40 1
#define CIPHER_CAPABILITY_WEP104 2
#define CIPHER_CAPABILITY_TKIP 3
#define CIPHER_CAPABILITY_CCMP 4
#define CIPHER_CAPABILITY_CMAC 5
#define CIPHER_CAPABILITY_GCMP 6
#define CIPHER_CAPABILITY_WPI_SMS4 7
#define IEEE80211_DFS_USABLE 0
#define IEEE80211_DFS_UNAVAILABLE 1
#define IEEE80211_DFS_AVAILABLE 2
#define WLAN_INTERFACE_AP 1
/* */
DECLARE_OPAQUE_TYPE(wifi_global_handle);
DECLARE_OPAQUE_TYPE(wifi_device_handle);
DECLARE_OPAQUE_TYPE(wifi_wlan_handle);
/* */
struct device_setrates_params {
int supportedratescount;
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
int basicratescount;
uint8_t basicrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
};
/* */
#define WIFI_COUNTRY_LENGTH 4
struct device_setconfiguration_params {
int shortpreamble;
uint8_t maxbssid;
uint8_t dtimperiod;
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
uint16_t beaconperiod;
uint8_t country[WIFI_COUNTRY_LENGTH];
};
/* */
typedef int (*send_frame_to_ac)(void* param, const uint8_t* frame, int length, uint8_t rssi, uint8_t snr, uint16_t rate);
struct wlan_startap_params {
uint8_t radioid;
uint8_t wlanid;
const char* ssid;
uint8_t ssid_hidden;
uint16_t capability;
uint8_t qos;
uint8_t authmode;
uint8_t macmode;
uint8_t tunnelmode;
};
/* */
struct wlan_send_frame_params {
uint8_t* packet;
int length;
uint32_t frequency;
uint32_t duration;
int offchannel_tx_ok;
int no_cck_rate;
int no_wait_ack;
uint64_t cookie;
};
/* */
struct station_add_params {
uint8_t* address;
};
/* Interface capability */
struct wifi_freq_capability {
unsigned long flags;
unsigned long frequency; /* MHz */
unsigned long channel;
unsigned long maxtxpower; /* mBm = 100 * dBm */
unsigned long dfsstate;
unsigned long dfstime; /* ms */
};
/* */
struct wifi_rate_capability {
unsigned long flags;
uint8_t bitrate;
};
/* */
struct wifi_band_capability {
unsigned long band;
unsigned long htcapability;
struct capwap_array* freq;
struct capwap_array* rate;
};
/* */
struct wifi_cipher_capability {
unsigned long cipher;
};
/* */
struct wifi_capability {
struct wifi_device* device;
unsigned long flags;
unsigned long capability;
/* WIFI_CAPABILITY_RADIOSUPPORTED */
unsigned long radiosupported;
/* WIFI_CAPABILITY_RADIOTYPE */
unsigned long radiotype;
/* WIFI_CAPABILITY_ANTENNA_MASK */
unsigned long txantennamask;
unsigned long rxantennamask;
/* WIFI_CAPABILITY_BANDS */
struct capwap_array* bands;
/* WIFI_CAPABILITY_CIPHERS */
struct capwap_array* ciphers;
/* WIFI_CAPABILITY_MAX_SCAN_SSIDS */
uint8_t maxscanssids;
/* WIFI_CAPABILITY_MAX_SCHED_SCAN_SSIDS */
uint8_t maxschedscanssids;
/* WIFI_CAPABILITY_MAX_MATCH_SETS */
uint8_t maxmatchsets;
/* WIFI_CAPABILITY_MAX_ACL_MACADDRESS */
uint8_t maxaclmacaddress;
};
/* Frequency configuration */
struct wifi_frequency {
uint32_t band;
uint32_t mode;
uint8_t channel;
uint32_t frequency;
};
/* */
#define WIFI_EVENT_MAX_ITEMS 2
struct wifi_event {
void (*event_handler)(int fd, void** params, int paramscount);
int paramscount;
void* params[WIFI_EVENT_MAX_ITEMS];
};
/* */
struct wifi_driver_instance {
struct wifi_driver_ops* ops; /* Driver functions */
wifi_global_handle handle; /* Global instance handle */
};
/* */
struct wifi_global {
int sock_util;
struct capwap_list* devices;
/* Timeout */
struct capwap_timeout* timeout;
/* Stations */
struct capwap_hash* stations;
};
/* Device handle */
#define WIFI_DEVICE_SET_FREQUENCY 0x00000001
#define WIFI_DEVICE_SET_RATES 0x00000002
#define WIFI_DEVICE_SET_CONFIGURATION 0x00000004
#define WIFI_DEVICE_REQUIRED_FOR_BSS (WIFI_DEVICE_SET_FREQUENCY | WIFI_DEVICE_SET_RATES | WIFI_DEVICE_SET_CONFIGURATION)
struct wifi_device {
struct wifi_global* global;
wifi_device_handle handle; /* Device handle */
struct wifi_driver_instance* instance; /* Driver instance */
uint32_t phyindex;
char phyname[IFNAMSIZ];
unsigned long flags;
/* */
struct capwap_list* wlans;
unsigned long wlanactive;
/* Current frequency */
struct wifi_frequency currentfrequency;
/* */
uint16_t beaconperiod;
uint8_t dtimperiod;
int shortpreamble;
/* Cached capability */
struct wifi_capability* capability;
/* Rates */
unsigned long supportedratescount;
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
unsigned long basicratescount;
uint8_t basicrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
/* ERP Information */
int olbc;
unsigned long stationsnonerpcount;
unsigned long stationsnoshortslottimecount;
unsigned long stationsnoshortpreamblecount;
};
/* WLAN handle */
#define WIFI_WLAN_RUNNING 0x00000001
#define WIFI_WLAN_SET_BEACON 0x00000002
#define WIFI_WLAN_OPERSTATE_RUNNING 0x00000004
struct wifi_wlan {
wifi_wlan_handle handle;
struct wifi_device* device;
unsigned long flags;
uint32_t virtindex;
char virtname[IFNAMSIZ];
uint8_t address[MACADDRESS_EUI48_LENGTH];
/* */
uint8_t radioid;
uint8_t wlanid;
/* WLAN information */
char ssid[IEEE80211_SSID_MAX_LENGTH + 1];
uint8_t ssid_hidden;
uint16_t capability;
/* Tunnel */
uint8_t macmode;
uint8_t tunnelmode;
/* Authentication */
uint8_t authmode;
/* Station information */
unsigned long stationscount;
unsigned long maxstationscount;
uint32_t aidbitfield[IEEE80211_AID_BITFIELD_SIZE];
};
/* Station handle */
#define WIFI_STATION_FLAGS_AUTHENTICATED 0x00000001
#define WIFI_STATION_FLAGS_ASSOCIATE 0x00000002
#define WIFI_STATION_FLAGS_NON_ERP 0x00000004
#define WIFI_STATION_FLAGS_NO_SHORT_SLOT_TIME 0x00000008
#define WIFI_STATION_FLAGS_NO_SHORT_PREAMBLE 0x00000010
#define WIFI_STATION_FLAGS_WMM 0x00000020
#define WIFI_STATION_FLAGS_AUTHORIZED 0x00000040
/* */
#define WIFI_STATION_TIMEOUT_ASSOCIATION_COMPLETE 30000
#define WIFI_STATION_TIMEOUT_AFTER_DEAUTHENTICATED 5000
/* */
#define WIFI_STATION_TIMEOUT_ACTION_DELETE 0x00000001
#define WIFI_STATION_TIMEOUT_ACTION_DEAUTHENTICATE 0x00000002
struct wifi_station {
uint8_t address[MACADDRESS_EUI48_LENGTH];
char addrtext[CAPWAP_MACADDRESS_EUI48_BUFFER];
/* */
struct wifi_wlan* wlan;
/* */
unsigned long flags;
/* Timers */
int timeoutaction;
unsigned long idtimeout;
/* */
uint16_t capability;
uint16_t listeninterval;
uint16_t aid;
/* */
int supportedratescount;
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
/* Authentication */
uint16_t authalgorithm;
};
/* */
struct wifi_driver_ops {
const char* name; /* Name of wifi driver */
const char* description; /* Description of wifi driver */
/* Global initialize driver */
wifi_global_handle (*global_init)(void);
int (*global_getfdevent)(wifi_global_handle handle, struct pollfd* fds, struct wifi_event* events);
void (*global_deinit)(wifi_global_handle handle);
/* Device functions */
int (*device_init)(wifi_global_handle handle, struct wifi_device* device);
int (*device_getfdevent)(struct wifi_device* device, struct pollfd* fds, struct wifi_event* events);
int (*device_getcapability)(struct wifi_device* device, struct wifi_capability* capability);
void (*device_updatebeacons)(struct wifi_device* device);
int (*device_setfrequency)(struct wifi_device* device);
void (*device_deinit)(struct wifi_device* device);
/* WLAN functions */
wifi_wlan_handle (*wlan_create)(struct wifi_device* device, struct wifi_wlan* wlan);
int (*wlan_getfdevent)(struct wifi_wlan* wlan, struct pollfd* fds, struct wifi_event* events);
int (*wlan_startap)(struct wifi_wlan* wlan);
void (*wlan_stopap)(struct wifi_wlan* wlan);
int (*wlan_sendframe)(struct wifi_wlan* wlan, uint8_t* frame, int length, uint32_t frequency, uint32_t duration, int offchannel_tx_ok, int no_cck_rate, int no_wait_ack);
void (*wlan_delete)(struct wifi_wlan* wlan);
/* Stations functions */
int (*station_authorize)(struct wifi_wlan* wlan, struct wifi_station* station);
int (*station_deauthorize)(struct wifi_wlan* wlan, const uint8_t* address);
};
/* Initialize wifi driver engine */
int wifi_driver_init(struct capwap_timeout* timeout);
void wifi_driver_free(void);
/* Get File Descriptor Event */
int wifi_event_getfd(struct pollfd* fds, struct wifi_event* events, int count);
/* */
struct wifi_wlan* wifi_get_wlan(uint32_t ifindex);
/* Device management */
struct wifi_device* wifi_device_connect(const char* ifname, const char* driver);
const struct wifi_capability* wifi_device_getcapability(struct wifi_device* device);
int wifi_device_setconfiguration(struct wifi_device* device, struct device_setconfiguration_params* params);
int wifi_device_setfrequency(struct wifi_device* device, uint32_t band, uint32_t mode, uint8_t channel);
int wifi_device_updaterates(struct wifi_device* device, uint8_t* rates, int ratescount);
/* WLAN management */
struct wifi_wlan* wifi_wlan_create(struct wifi_device* device, const char* ifname);
int wifi_wlan_startap(struct wifi_wlan* wlan, struct wlan_startap_params* params);
void wifi_wlan_stopap(struct wifi_wlan* wlan);
int wifi_wlan_getbssid(struct wifi_wlan* wlan, uint8_t* bssid);
uint16_t wifi_wlan_check_capability(struct wifi_wlan* wlan, uint16_t capability);
int wifi_wlan_send_frame(struct wifi_wlan* wlan, const uint8_t* data, int length, uint8_t rssi, uint8_t snr, uint16_t rate);
void wifi_wlan_destroy(struct wifi_wlan* wlan);
/* WLAN packet management */
void wifi_wlan_receive_station_frame(struct wifi_wlan* wlan, const struct ieee80211_header* frame, int length, uint32_t frequency, uint8_t rssi, uint8_t snr, uint16_t rate);
void wifi_wlan_receive_station_ackframe(struct wifi_wlan* wlan, const struct ieee80211_header* frame, int length, int ack);
void wifi_wlan_receive_ac_frame(struct wifi_wlan* wlan, struct ieee80211_header* frame, int length);
/* Station management */
int wifi_station_authorize(struct wifi_wlan* wlan, struct station_add_params* params);
void wifi_station_deauthorize(struct wifi_device* device, const uint8_t* address);
/* Util functions */
uint32_t wifi_iface_index(const char* ifname);
int wifi_iface_hwaddr(int sock, const char* ifname, uint8_t* hwaddr);
int wifi_frequency_to_radiotype(uint32_t freq);
/* */
int wifi_iface_getstatus(int sock, const char* ifname);
int wifi_iface_updown(int sock, const char* ifname, int up);
#define wifi_iface_up(sock, ifname) wifi_iface_updown(sock, ifname, 1)
#define wifi_iface_down(sock, ifname) wifi_iface_updown(sock, ifname, 0)
#endif /* __WIFI_DRIVERS_HEADER__ */
#ifndef __WIFI_DRIVERS_HEADER__
#define __WIFI_DRIVERS_HEADER__
#include <net/if_arp.h>
#include <linux/if_ether.h>
#include "ieee80211.h"
/* */
#define WIFI_DRIVER_NAME_SIZE 16
/* */
#define WIFI_BAND_UNKNOWN 0
#define WIFI_BAND_2GHZ 1
#define WIFI_BAND_5GHZ 2
/* */
#define WIFI_CAPABILITY_RADIOSUPPORTED 0x00000001
#define WIFI_CAPABILITY_RADIOTYPE 0x00000002
#define WIFI_CAPABILITY_BANDS 0x00000004
#define WIFI_CAPABILITY_CIPHERS 0x00000008
#define WIFI_CAPABILITY_ANTENNA_MASK 0x00000010
#define WIFI_CAPABILITY_MAX_SCAN_SSIDS 0x00000020
#define WIFI_CAPABILITY_MAX_SCHED_SCAN_SSIDS 0x00000040
#define WIFI_CAPABILITY_MAX_MATCH_SETS 0x00000080
#define WIFI_CAPABILITY_MAX_ACL_MACADDRESS 0x00000100
/* */
#define WIFI_CAPABILITY_FLAGS_OFFCHANNEL_TX_OK 0x00000001
#define WIFI_CAPABILITY_FLAGS_ROAM_SUPPORT 0x00000002
#define WIFI_CAPABILITY_FLAGS_SUPPORT_AP_UAPSD 0x00000004
#define WIFI_CAPABILITY_FLAGS_DEVICE_AP_SME 0x00000008
#define WIFI_CAPABILITY_FLAGS_PROBE_RESPONSE_OFFLOAD 0x00000010
/* */
#define WIFI_CAPABILITY_AP_SUPPORTED 0x00000001
#define WIFI_CAPABILITY_AP_VLAN_SUPPORTED 0x00000002
#define WIFI_CAPABILITY_ADHOC_SUPPORTED 0x00000004
#define WIFI_CAPABILITY_MONITOR_SUPPORTED 0x00000008
#define WIFI_CAPABILITY_WDS_SUPPORTED 0x00000010
#define FREQ_CAPABILITY_DISABLED 0x00000001
#define FREQ_CAPABILITY_PASSIVE_SCAN 0x00000002
#define FREQ_CAPABILITY_NO_IBBS 0x00000004
#define FREQ_CAPABILITY_RADAR 0x00000008
#define FREQ_CAPABILITY_DFS_STATE 0x00000010
#define FREQ_CAPABILITY_DFS_TIME 0x00000020
#define RATE_CAPABILITY_SHORTPREAMBLE 0x00000001
#define CIPHER_CAPABILITY_UNKNOWN 0
#define CIPHER_CAPABILITY_WEP40 1
#define CIPHER_CAPABILITY_WEP104 2
#define CIPHER_CAPABILITY_TKIP 3
#define CIPHER_CAPABILITY_CCMP 4
#define CIPHER_CAPABILITY_CMAC 5
#define CIPHER_CAPABILITY_GCMP 6
#define CIPHER_CAPABILITY_WPI_SMS4 7
#define IEEE80211_DFS_USABLE 0
#define IEEE80211_DFS_UNAVAILABLE 1
#define IEEE80211_DFS_AVAILABLE 2
#define WLAN_INTERFACE_AP 1
/* */
DECLARE_OPAQUE_TYPE(wifi_global_handle);
DECLARE_OPAQUE_TYPE(wifi_device_handle);
DECLARE_OPAQUE_TYPE(wifi_wlan_handle);
/* */
struct device_setrates_params {
int supportedratescount;
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
int basicratescount;
uint8_t basicrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
};
/* */
#define WIFI_COUNTRY_LENGTH 4
struct device_setconfiguration_params {
int shortpreamble;
uint8_t maxbssid;
uint8_t dtimperiod;
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
uint16_t beaconperiod;
uint8_t country[WIFI_COUNTRY_LENGTH];
};
/* */
typedef int (*send_frame_to_ac)(void* param, const uint8_t* frame, int length, uint8_t rssi, uint8_t snr, uint16_t rate);
struct wlan_startap_params {
uint8_t radioid;
uint8_t wlanid;
const char* ssid;
uint8_t ssid_hidden;
uint16_t capability;
uint8_t qos;
uint8_t authmode;
uint8_t macmode;
uint8_t tunnelmode;
};
/* */
struct wlan_send_frame_params {
uint8_t* packet;
int length;
uint32_t frequency;
uint32_t duration;
int offchannel_tx_ok;
int no_cck_rate;
int no_wait_ack;
uint64_t cookie;
};
/* */
struct station_add_params {
uint8_t* address;
};
/* Interface capability */
struct wifi_freq_capability {
unsigned long flags;
unsigned long frequency; /* MHz */
unsigned long channel;
unsigned long maxtxpower; /* mBm = 100 * dBm */
unsigned long dfsstate;
unsigned long dfstime; /* ms */
};
/* */
struct wifi_rate_capability {
unsigned long flags;
uint8_t bitrate;
};
/* */
struct wifi_band_capability {
unsigned long band;
unsigned long htcapability;
struct capwap_array* freq;
struct capwap_array* rate;
};
/* */
struct wifi_cipher_capability {
unsigned long cipher;
};
/* */
struct wifi_capability {
struct wifi_device* device;
unsigned long flags;
unsigned long capability;
/* WIFI_CAPABILITY_RADIOSUPPORTED */
unsigned long radiosupported;
/* WIFI_CAPABILITY_RADIOTYPE */
unsigned long radiotype;
/* WIFI_CAPABILITY_ANTENNA_MASK */
unsigned long txantennamask;
unsigned long rxantennamask;
/* WIFI_CAPABILITY_BANDS */
struct capwap_array* bands;
/* WIFI_CAPABILITY_CIPHERS */
struct capwap_array* ciphers;
/* WIFI_CAPABILITY_MAX_SCAN_SSIDS */
uint8_t maxscanssids;
/* WIFI_CAPABILITY_MAX_SCHED_SCAN_SSIDS */
uint8_t maxschedscanssids;
/* WIFI_CAPABILITY_MAX_MATCH_SETS */
uint8_t maxmatchsets;
/* WIFI_CAPABILITY_MAX_ACL_MACADDRESS */
uint8_t maxaclmacaddress;
};
/* Frequency configuration */
struct wifi_frequency {
uint32_t band;
uint32_t mode;
uint8_t channel;
uint32_t frequency;
};
/* */
#define WIFI_EVENT_MAX_ITEMS 2
struct wifi_event {
void (*event_handler)(int fd, void** params, int paramscount);
int paramscount;
void* params[WIFI_EVENT_MAX_ITEMS];
};
/* */
struct wifi_driver_instance {
struct wifi_driver_ops* ops; /* Driver functions */
wifi_global_handle handle; /* Global instance handle */
};
/* */
struct wifi_global {
int sock_util;
struct capwap_list* devices;
/* Timeout */
struct capwap_timeout* timeout;
/* Stations */
struct capwap_hash* stations;
};
/* Device handle */
#define WIFI_DEVICE_SET_FREQUENCY 0x00000001
#define WIFI_DEVICE_SET_RATES 0x00000002
#define WIFI_DEVICE_SET_CONFIGURATION 0x00000004
#define WIFI_DEVICE_REQUIRED_FOR_BSS (WIFI_DEVICE_SET_FREQUENCY | WIFI_DEVICE_SET_RATES | WIFI_DEVICE_SET_CONFIGURATION)
struct wifi_device {
struct wifi_global* global;
wifi_device_handle handle; /* Device handle */
struct wifi_driver_instance* instance; /* Driver instance */
uint32_t phyindex;
char phyname[IFNAMSIZ];
unsigned long flags;
/* */
struct capwap_list* wlans;
unsigned long wlanactive;
/* Current frequency */
struct wifi_frequency currentfrequency;
/* */
uint16_t beaconperiod;
uint8_t dtimperiod;
int shortpreamble;
/* Cached capability */
struct wifi_capability* capability;
/* Rates */
unsigned long supportedratescount;
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
unsigned long basicratescount;
uint8_t basicrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
/* ERP Information */
int olbc;
unsigned long stationsnonerpcount;
unsigned long stationsnoshortslottimecount;
unsigned long stationsnoshortpreamblecount;
};
/* WLAN handle */
#define WIFI_WLAN_RUNNING 0x00000001
#define WIFI_WLAN_SET_BEACON 0x00000002
#define WIFI_WLAN_OPERSTATE_RUNNING 0x00000004
struct wifi_wlan {
wifi_wlan_handle handle;
struct wifi_device* device;
unsigned long flags;
uint32_t virtindex;
char virtname[IFNAMSIZ];
uint8_t address[MACADDRESS_EUI48_LENGTH];
/* */
uint8_t radioid;
uint8_t wlanid;
/* WLAN information */
char ssid[IEEE80211_SSID_MAX_LENGTH + 1];
uint8_t ssid_hidden;
uint16_t capability;
/* Tunnel */
uint8_t macmode;
uint8_t tunnelmode;
/* Authentication */
uint8_t authmode;
/* Station information */
unsigned long stationscount;
unsigned long maxstationscount;
uint32_t aidbitfield[IEEE80211_AID_BITFIELD_SIZE];
};
/* Station handle */
#define WIFI_STATION_FLAGS_AUTHENTICATED 0x00000001
#define WIFI_STATION_FLAGS_ASSOCIATE 0x00000002
#define WIFI_STATION_FLAGS_NON_ERP 0x00000004
#define WIFI_STATION_FLAGS_NO_SHORT_SLOT_TIME 0x00000008
#define WIFI_STATION_FLAGS_NO_SHORT_PREAMBLE 0x00000010
#define WIFI_STATION_FLAGS_WMM 0x00000020
#define WIFI_STATION_FLAGS_AUTHORIZED 0x00000040
/* */
#define WIFI_STATION_TIMEOUT_ASSOCIATION_COMPLETE 30000
#define WIFI_STATION_TIMEOUT_AFTER_DEAUTHENTICATED 5000
/* */
#define WIFI_STATION_TIMEOUT_ACTION_DELETE 0x00000001
#define WIFI_STATION_TIMEOUT_ACTION_DEAUTHENTICATE 0x00000002
struct wifi_station {
uint8_t address[MACADDRESS_EUI48_LENGTH];
char addrtext[CAPWAP_MACADDRESS_EUI48_BUFFER];
/* */
struct wifi_wlan* wlan;
/* */
unsigned long flags;
/* Timers */
int timeoutaction;
unsigned long idtimeout;
/* */
uint16_t capability;
uint16_t listeninterval;
uint16_t aid;
/* */
int supportedratescount;
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
/* Authentication */
uint16_t authalgorithm;
};
/* */
struct wifi_driver_ops {
const char* name; /* Name of wifi driver */
const char* description; /* Description of wifi driver */
/* Global initialize driver */
wifi_global_handle (*global_init)(void);
int (*global_getfdevent)(wifi_global_handle handle, struct pollfd* fds, struct wifi_event* events);
void (*global_deinit)(wifi_global_handle handle);
/* Device functions */
int (*device_init)(wifi_global_handle handle, struct wifi_device* device);
int (*device_getfdevent)(struct wifi_device* device, struct pollfd* fds, struct wifi_event* events);
int (*device_getcapability)(struct wifi_device* device, struct wifi_capability* capability);
void (*device_updatebeacons)(struct wifi_device* device);
int (*device_setfrequency)(struct wifi_device* device);
void (*device_deinit)(struct wifi_device* device);
/* WLAN functions */
wifi_wlan_handle (*wlan_create)(struct wifi_device* device, struct wifi_wlan* wlan);
int (*wlan_getfdevent)(struct wifi_wlan* wlan, struct pollfd* fds, struct wifi_event* events);
int (*wlan_startap)(struct wifi_wlan* wlan);
void (*wlan_stopap)(struct wifi_wlan* wlan);
int (*wlan_sendframe)(struct wifi_wlan* wlan, uint8_t* frame, int length, uint32_t frequency, uint32_t duration, int offchannel_tx_ok, int no_cck_rate, int no_wait_ack);
void (*wlan_delete)(struct wifi_wlan* wlan);
/* Stations functions */
int (*station_authorize)(struct wifi_wlan* wlan, struct wifi_station* station);
int (*station_deauthorize)(struct wifi_wlan* wlan, const uint8_t* address);
};
/* Initialize wifi driver engine */
int wifi_driver_init(struct capwap_timeout* timeout);
void wifi_driver_free(void);
/* Get File Descriptor Event */
int wifi_event_getfd(struct pollfd* fds, struct wifi_event* events, int count);
/* */
struct wifi_wlan* wifi_get_wlan(uint32_t ifindex);
/* Device management */
struct wifi_device* wifi_device_connect(const char* ifname, const char* driver);
const struct wifi_capability* wifi_device_getcapability(struct wifi_device* device);
int wifi_device_setconfiguration(struct wifi_device* device, struct device_setconfiguration_params* params);
int wifi_device_setfrequency(struct wifi_device* device, uint32_t band, uint32_t mode, uint8_t channel);
int wifi_device_updaterates(struct wifi_device* device, uint8_t* rates, int ratescount);
/* WLAN management */
struct wifi_wlan* wifi_wlan_create(struct wifi_device* device, const char* ifname);
int wifi_wlan_startap(struct wifi_wlan* wlan, struct wlan_startap_params* params);
void wifi_wlan_stopap(struct wifi_wlan* wlan);
int wifi_wlan_getbssid(struct wifi_wlan* wlan, uint8_t* bssid);
uint16_t wifi_wlan_check_capability(struct wifi_wlan* wlan, uint16_t capability);
int wifi_wlan_send_frame(struct wifi_wlan* wlan, const uint8_t* data, int length, uint8_t rssi, uint8_t snr, uint16_t rate);
void wifi_wlan_destroy(struct wifi_wlan* wlan);
/* WLAN packet management */
void wifi_wlan_receive_station_frame(struct wifi_wlan* wlan, const struct ieee80211_header* frame, int length, uint32_t frequency, uint8_t rssi, uint8_t snr, uint16_t rate);
void wifi_wlan_receive_station_ackframe(struct wifi_wlan* wlan, const struct ieee80211_header* frame, int length, int ack);
void wifi_wlan_receive_ac_frame(struct wifi_wlan* wlan, struct ieee80211_header* frame, int length);
/* Station management */
int wifi_station_authorize(struct wifi_wlan* wlan, struct station_add_params* params);
void wifi_station_deauthorize(struct wifi_device* device, const uint8_t* address);
/* Util functions */
uint32_t wifi_iface_index(const char* ifname);
int wifi_iface_hwaddr(int sock, const char* ifname, uint8_t* hwaddr);
int wifi_frequency_to_radiotype(uint32_t freq);
/* */
int wifi_iface_getstatus(int sock, const char* ifname);
int wifi_iface_updown(int sock, const char* ifname, int up);
#define wifi_iface_up(sock, ifname) wifi_iface_updown(sock, ifname, 1)
#define wifi_iface_down(sock, ifname) wifi_iface_updown(sock, ifname, 0)
#endif /* __WIFI_DRIVERS_HEADER__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,45 +1,45 @@
#ifndef __WIFI_NL80211_HEADER__
#define __WIFI_NL80211_HEADER__
#include "capwap_hash.h"
#include "netlink_link.h"
/* Compatibility functions */
#ifdef HAVE_LIBNL_10
#define nl_sock nl_handle
#endif
/* */
typedef int (*nl_valid_cb)(struct nl_msg* msg, void* data);
/* Global handle */
struct nl80211_global_handle {
struct nl_sock* nl;
struct nl_cb* nl_cb;
int nl80211_id;
struct nl_sock* nl_event;
int nl_event_fd;
struct netlink* netlinkhandle;
int sock_util;
};
/* Device handle */
struct nl80211_device_handle {
struct nl80211_global_handle* globalhandle;
};
/* WLAN handle */
struct nl80211_wlan_handle {
struct nl80211_device_handle* devicehandle;
struct nl_sock* nl;
int nl_fd;
struct nl_cb* nl_cb;
uint64_t last_cookie;
};
#endif /* __WIFI_NL80211_HEADER__ */
#ifndef __WIFI_NL80211_HEADER__
#define __WIFI_NL80211_HEADER__
#include "capwap_hash.h"
#include "netlink_link.h"
/* Compatibility functions */
#ifdef HAVE_LIBNL_10
#define nl_sock nl_handle
#endif
/* */
typedef int (*nl_valid_cb)(struct nl_msg* msg, void* data);
/* Global handle */
struct nl80211_global_handle {
struct nl_sock* nl;
struct nl_cb* nl_cb;
int nl80211_id;
struct nl_sock* nl_event;
int nl_event_fd;
struct netlink* netlinkhandle;
int sock_util;
};
/* Device handle */
struct nl80211_device_handle {
struct nl80211_global_handle* globalhandle;
};
/* WLAN handle */
struct nl80211_wlan_handle {
struct nl80211_device_handle* devicehandle;
struct nl_sock* nl;
int nl_fd;
struct nl_cb* nl_cb;
uint64_t last_cookie;
};
#endif /* __WIFI_NL80211_HEADER__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,124 +1,124 @@
#ifndef __KMOD_CAPWAP_HEADER__
#define __KMOD_CAPWAP_HEADER__
#include "capwap_rfc.h"
#include "socket.h"
/* */
#define MAX_MTU 9000
#define DEFAULT_MTU 1450
#define MIN_MTU 500
#define IEEE80211_MTU 7981
/* */
#define CAPWAP_FRAGMENT_QUEUE 16
/* */
#define CAPWAP_FRAGMENT_ENABLE 0x0001
#define CAPWAP_FRAGMENT_LRUQUEUE 0x0002
#define CAPWAP_FRAGMENT_LAST 0x0004
/* */
#define SKB_CAPWAP_FLAG_FROM_DATA_CHANNEL 0x0001
#define SKB_CAPWAP_FLAG_FROM_USER_SPACE 0x0002
#define SKB_CAPWAP_FLAG_FROM_AC_TAP 0x0004
#define SKB_CAPWAP_FLAG_FROM_IEEE80211 0x0008
#define SKB_CAPWAP_FLAG_SESSIONID 0x0100
#define SKB_CAPWAP_FLAG_RADIOID 0x0200
#define SKB_CAPWAP_FLAG_BINDING 0x0400
#define SKB_CAPWAP_FLAG_WIRELESSINFORMATION 0x0800
#define SKB_CAPWAP_FLAG_FRAGMENT 0x1000
struct sc_skb_capwap_cb {
uint16_t flags;
/* Session ID */
struct sc_capwap_sessionid_element sessionid;
/* Capwap information */
uint8_t radioid;
uint8_t binding;
/* Wireless Information */
uint8_t winfo_rssi;
uint8_t winfo_snr;
uint16_t winfo_rate;
/* Fragment */
uint16_t frag_offset;
uint16_t frag_length;
};
#define CAPWAP_SKB_CB(skb) ((struct sc_skb_capwap_cb*)((skb)->cb))
/* */
struct sc_capwap_fragment {
struct list_head lru_list;
uint8_t flags;
ktime_t tstamp;
uint16_t fragmentid;
struct sk_buff* fragments;
struct sk_buff* lastfragment;
int recvlength;
int totallength;
};
/* */
struct sc_capwap_fragment_queue {
spinlock_t lock;
struct list_head lru_list;
struct sc_capwap_fragment queues[CAPWAP_FRAGMENT_QUEUE];
};
/* */
struct sc_capwap_session {
uint16_t mtu;
union capwap_addr peeraddr;
struct sc_capwap_sessionid_element sessionid;
uint16_t fragmentid;
spinlock_t fragmentid_lock;
struct sc_capwap_fragment_queue fragments;
};
/* */
extern union capwap_addr sc_localaddr;
/* Dipendent implementation function */
void sc_capwap_recvpacket(struct sk_buff* skb);
struct sc_capwap_session* sc_capwap_recvunknownkeepalive(const union capwap_addr* sockaddr, const struct sc_capwap_sessionid_element* sessionid);
void sc_capwap_parsingdatapacket(struct sc_capwap_session* session, struct sk_buff* skb);
void sc_capwap_parsingmgmtpacket(struct sc_capwap_session* session, struct sk_buff* skb);
/* Indipendent implementation function */
int sc_capwap_bind(union capwap_addr* sockaddr);
void sc_capwap_initsession(struct sc_capwap_session* session);
void sc_capwap_freesession(struct sc_capwap_session* session);
uint16_t sc_capwap_newfragmentid(struct sc_capwap_session* session);
int sc_capwap_8023_to_80211(struct sk_buff* skb, const uint8_t* bssid);
int sc_capwap_80211_to_8023(struct sk_buff* skb);
void sc_capwap_sessionid_printf(const struct sc_capwap_sessionid_element* sessionid, char* string);
int sc_capwap_createkeepalive(struct sc_capwap_sessionid_element* sessionid, uint8_t* buffer, int size);
int sc_capwap_parsingpacket(struct sc_capwap_session* session, const union capwap_addr* sockaddr, struct sk_buff* skb);
struct sc_capwap_radio_addr* sc_capwap_setradiomacaddress(uint8_t* buffer, int size, uint8_t* bssid);
struct sc_capwap_wireless_information* sc_capwap_setwinfo_frameinfo(uint8_t* buffer, int size, uint8_t rssi, uint8_t snr, uint16_t rate);
struct sc_capwap_wireless_information* sc_capwap_setwinfo_destwlans(uint8_t* buffer, int size, uint16_t wlanidbitmap);
int sc_capwap_forwarddata(struct sc_capwap_session* session, uint8_t radioid, uint8_t binding, struct sk_buff* skb, uint32_t flags, struct sc_capwap_radio_addr* radioaddr, int radioaddrlength, struct sc_capwap_wireless_information* winfo, int winfolength);
/* Private funciotn */
#include "capwap_private.h"
#endif /* __KMOD_CAPWAP_HEADER__ */
#ifndef __KMOD_CAPWAP_HEADER__
#define __KMOD_CAPWAP_HEADER__
#include "capwap_rfc.h"
#include "socket.h"
/* */
#define MAX_MTU 9000
#define DEFAULT_MTU 1450
#define MIN_MTU 500
#define IEEE80211_MTU 7981
/* */
#define CAPWAP_FRAGMENT_QUEUE 16
/* */
#define CAPWAP_FRAGMENT_ENABLE 0x0001
#define CAPWAP_FRAGMENT_LRUQUEUE 0x0002
#define CAPWAP_FRAGMENT_LAST 0x0004
/* */
#define SKB_CAPWAP_FLAG_FROM_DATA_CHANNEL 0x0001
#define SKB_CAPWAP_FLAG_FROM_USER_SPACE 0x0002
#define SKB_CAPWAP_FLAG_FROM_AC_TAP 0x0004
#define SKB_CAPWAP_FLAG_FROM_IEEE80211 0x0008
#define SKB_CAPWAP_FLAG_SESSIONID 0x0100
#define SKB_CAPWAP_FLAG_RADIOID 0x0200
#define SKB_CAPWAP_FLAG_BINDING 0x0400
#define SKB_CAPWAP_FLAG_WIRELESSINFORMATION 0x0800
#define SKB_CAPWAP_FLAG_FRAGMENT 0x1000
struct sc_skb_capwap_cb {
uint16_t flags;
/* Session ID */
struct sc_capwap_sessionid_element sessionid;
/* Capwap information */
uint8_t radioid;
uint8_t binding;
/* Wireless Information */
uint8_t winfo_rssi;
uint8_t winfo_snr;
uint16_t winfo_rate;
/* Fragment */
uint16_t frag_offset;
uint16_t frag_length;
};
#define CAPWAP_SKB_CB(skb) ((struct sc_skb_capwap_cb*)((skb)->cb))
/* */
struct sc_capwap_fragment {
struct list_head lru_list;
uint8_t flags;
ktime_t tstamp;
uint16_t fragmentid;
struct sk_buff* fragments;
struct sk_buff* lastfragment;
int recvlength;
int totallength;
};
/* */
struct sc_capwap_fragment_queue {
spinlock_t lock;
struct list_head lru_list;
struct sc_capwap_fragment queues[CAPWAP_FRAGMENT_QUEUE];
};
/* */
struct sc_capwap_session {
uint16_t mtu;
union capwap_addr peeraddr;
struct sc_capwap_sessionid_element sessionid;
uint16_t fragmentid;
spinlock_t fragmentid_lock;
struct sc_capwap_fragment_queue fragments;
};
/* */
extern union capwap_addr sc_localaddr;
/* Dipendent implementation function */
void sc_capwap_recvpacket(struct sk_buff* skb);
struct sc_capwap_session* sc_capwap_recvunknownkeepalive(const union capwap_addr* sockaddr, const struct sc_capwap_sessionid_element* sessionid);
void sc_capwap_parsingdatapacket(struct sc_capwap_session* session, struct sk_buff* skb);
void sc_capwap_parsingmgmtpacket(struct sc_capwap_session* session, struct sk_buff* skb);
/* Indipendent implementation function */
int sc_capwap_bind(union capwap_addr* sockaddr);
void sc_capwap_initsession(struct sc_capwap_session* session);
void sc_capwap_freesession(struct sc_capwap_session* session);
uint16_t sc_capwap_newfragmentid(struct sc_capwap_session* session);
int sc_capwap_8023_to_80211(struct sk_buff* skb, const uint8_t* bssid);
int sc_capwap_80211_to_8023(struct sk_buff* skb);
void sc_capwap_sessionid_printf(const struct sc_capwap_sessionid_element* sessionid, char* string);
int sc_capwap_createkeepalive(struct sc_capwap_sessionid_element* sessionid, uint8_t* buffer, int size);
int sc_capwap_parsingpacket(struct sc_capwap_session* session, const union capwap_addr* sockaddr, struct sk_buff* skb);
struct sc_capwap_radio_addr* sc_capwap_setradiomacaddress(uint8_t* buffer, int size, uint8_t* bssid);
struct sc_capwap_wireless_information* sc_capwap_setwinfo_frameinfo(uint8_t* buffer, int size, uint8_t rssi, uint8_t snr, uint16_t rate);
struct sc_capwap_wireless_information* sc_capwap_setwinfo_destwlans(uint8_t* buffer, int size, uint16_t wlanidbitmap);
int sc_capwap_forwarddata(struct sc_capwap_session* session, uint8_t radioid, uint8_t binding, struct sk_buff* skb, uint32_t flags, struct sc_capwap_radio_addr* radioaddr, int radioaddrlength, struct sc_capwap_wireless_information* winfo, int winfolength);
/* Private funciotn */
#include "capwap_private.h"
#endif /* __KMOD_CAPWAP_HEADER__ */

View File

@ -1,275 +1,275 @@
#include "config.h"
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/etherdevice.h>
#include <linux/ieee80211.h>
#include <net/mac80211.h>
#include <net/ipv6.h>
#include "capwap.h"
#include "nlsmartcapwap.h"
#include "netlinkapp.h"
/* */
static struct sc_capwap_session sc_acsession;
/* */
int sc_capwap_init(void) {
TRACEKMOD("### sc_capwap_init\n");
/* Init session */
memset(&sc_acsession, 0, sizeof(struct sc_capwap_session));
sc_capwap_initsession(&sc_acsession);
/* Init sockect */
memset(&sc_localaddr, 0, sizeof(union capwap_addr));
return sc_socket_init();
}
/* */
void sc_capwap_close(void) {
TRACEKMOD("### sc_capwap_close\n");
/* */
sc_socket_close();
memset(&sc_localaddr, 0, sizeof(union capwap_addr));
sc_capwap_freesession(&sc_acsession);
}
/* */
int sc_capwap_connect(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid, uint16_t mtu) {
TRACEKMOD("### sc_capwap_connect\n");
if ((sc_localaddr.ss.ss_family != AF_INET) && (sc_localaddr.ss.ss_family != AF_INET6)) {
return -ENONET;
}
/* AC address */
if ((sockaddr->ss.ss_family == AF_INET6) && ipv6_addr_v4mapped(&sockaddr->sin6.sin6_addr)) {
return -EINVAL;
} else if ((sc_localaddr.ss.ss_family == AF_INET) && (sockaddr->ss.ss_family == AF_INET6)) {
return -EINVAL;
}
/* */
memcpy(&sc_acsession.peeraddr, sockaddr, sizeof(union capwap_addr));
memcpy(&sc_acsession.sessionid, sessionid, sizeof(struct sc_capwap_sessionid_element));
sc_acsession.mtu = mtu;
return sc_capwap_sendkeepalive();
}
/* */
void sc_capwap_resetsession(void) {
TRACEKMOD("### sc_capwap_resetsession\n");
/* */
sc_capwap_freesession(&sc_acsession);
/* Reinit session */
memset(&sc_acsession, 0, sizeof(struct sc_capwap_session));
sc_capwap_initsession(&sc_acsession);
}
/* */
int sc_capwap_sendkeepalive(void) {
int ret;
int length;
uint8_t buffer[CAPWAP_KEEP_ALIVE_MAX_SIZE];
TRACEKMOD("### sc_capwap_sendkeepalive\n");
/* Build keepalive */
length = sc_capwap_createkeepalive(&sc_acsession.sessionid, buffer, CAPWAP_KEEP_ALIVE_MAX_SIZE);
/* Send packet */
ret = sc_socket_send(SOCKET_UDP, buffer, length, &sc_acsession.peeraddr);
TRACEKMOD("*** Send keep-alive result: %d\n", ret);
if (ret > 0) {
ret = 0;
}
return ret;
}
/* */
struct sc_capwap_session* sc_capwap_getsession(const union capwap_addr* sockaddr) {
TRACEKMOD("### sc_capwap_getsession\n");
if (!sockaddr) {
return &sc_acsession;
} else if (sc_acsession.peeraddr.ss.ss_family == sockaddr->ss.ss_family) {
if (sc_acsession.peeraddr.ss.ss_family == AF_INET) {
if ((sc_acsession.peeraddr.sin.sin_port == sockaddr->sin.sin_port) && (sc_acsession.peeraddr.sin.sin_addr.s_addr == sockaddr->sin.sin_addr.s_addr)) {
return &sc_acsession;
}
} else if (sc_acsession.peeraddr.ss.ss_family == AF_INET6) {
if ((sc_acsession.peeraddr.sin6.sin6_port == sockaddr->sin6.sin6_port) && !ipv6_addr_cmp(&sc_acsession.peeraddr.sin6.sin6_addr, &sockaddr->sin6.sin6_addr)) {
return &sc_acsession;
}
}
}
return NULL;
}
/* */
void sc_capwap_recvpacket(struct sk_buff* skb) {
union capwap_addr peeraddr;
struct sc_capwap_session* session;
TRACEKMOD("### sc_capwap_recvpacket\n");
/* Get peer address */
if (sc_socket_getpeeraddr(skb, &peeraddr)) {
goto drop;
}
/* Get session */
session = sc_capwap_getsession(&peeraddr);
if (!session) {
TRACEKMOD("*** Session not found\n");
goto drop;
}
/* Remove UDP header */
if (!skb_pull(skb, sizeof(struct udphdr))) {
TRACEKMOD("*** Invalid packet\n");
goto drop;
}
/* Parsing packet */
if (sc_capwap_parsingpacket(session, &peeraddr, skb)) {
TRACEKMOD("*** Parsing error\n");
goto drop;
}
return;
drop:
kfree_skb(skb);
}
/* */
struct sc_capwap_session* sc_capwap_recvunknownkeepalive(const union capwap_addr* sockaddr, const struct sc_capwap_sessionid_element* sessionid) {
TRACEKMOD("### sc_capwap_recvunknownkeepalive\n");
return NULL;
}
/* */
void sc_capwap_parsingdatapacket(struct sc_capwap_session* session, struct sk_buff* skb) {
uint8_t* pos;
uint8_t* dstaddress;
struct net_device* dev;
struct sc_capwap_header* header = (struct sc_capwap_header*)skb->data;
int is80211 = (IS_FLAG_T_HEADER(header) ? 1 : 0);
struct sc_capwap_radio_addr* radioaddr = NULL;
int radioaddrsize = 0;
struct sc_capwap_wireless_information* winfo = NULL;
struct sc_capwap_destination_wlans* destwlan = NULL;
int winfosize = 0;
TRACEKMOD("### sc_capwap_parsingdatapacket\n");
/* Retrieve optional attribute */
pos = skb->data + sizeof(struct sc_capwap_header);
if (IS_FLAG_M_HEADER(header)) {
radioaddr = (struct sc_capwap_radio_addr*)pos;
radioaddrsize = (sizeof(struct sc_capwap_radio_addr) + radioaddr->length + 3) & ~3;
pos += radioaddrsize;
}
if (IS_FLAG_W_HEADER(header)) {
winfo = (struct sc_capwap_wireless_information*)pos;
destwlan = (struct sc_capwap_destination_wlans*)(pos + sizeof(struct sc_capwap_wireless_information));
winfosize = (sizeof(struct sc_capwap_wireless_information) + winfo->length + 3) & ~3;
pos += winfosize;
}
/* Body packet */
skb_pull(skb, GET_HLEN_HEADER(header) * 4);
dstaddress = (is80211 ? ieee80211_get_DA((struct ieee80211_hdr*)skb->data) : (uint8_t*)((struct ethhdr*)skb->data)->h_dest);
if (is_multicast_ether_addr(dstaddress)) {
/* Accept only broadcast packet with wireless information */
if (winfo) {
uint8_t wlanid = 1;
uint16_t bitmask = be16_to_cpu(destwlan->wlanidbitmap);
while (bitmask) {
if (bitmask & 0x01) {
dev = sc_netlink_getdev_from_wlanid(GET_RID_HEADER(header), wlanid);
if (dev) {
struct sk_buff* clone = skb_copy_expand(skb, skb_headroom(skb), skb_tailroom(skb), GFP_KERNEL);
if (!clone) {
goto error;
}
/* */
if (!is80211) {
if (sc_capwap_8023_to_80211(clone, dev->dev_addr)) {
kfree_skb(clone);
goto error;
}
}
TRACEKMOD("*** Send broadcast packet to interface: %d\n", dev->ifindex);
/* Send packet */
local_bh_disable();
ieee80211_inject_xmit(clone, dev);
local_bh_enable();
} else {
TRACEKMOD("*** Unknown wlanid: %d\n", (int)wlanid);
}
}
/* Next */
wlanid++;
bitmask >>= 1;
}
} else {
TRACEKMOD("*** Invalid broadcast packet\n");
}
/* Free broadcast packet */
kfree_skb(skb);
} else {
/* Accept only 802.11 frame or 802.3 frame with radio address */
if (is80211 || (radioaddr && (radioaddr->length == MACADDRESS_EUI48_LENGTH))){
if (!is80211) {
if (sc_capwap_8023_to_80211(skb, radioaddr->addr)) {
goto error;
}
}
/* */
dev = sc_netlink_getdev_from_bssid(GET_RID_HEADER(header), ((struct ieee80211_hdr*)skb->data)->addr2);
if (!dev) {
goto error;
}
TRACEKMOD("** Send packet to interface: %d\n", dev->ifindex);
/* Send packet */
local_bh_disable();
ieee80211_inject_xmit(skb, dev);
local_bh_enable();
} else {
goto error;
}
}
return;
error:
TRACEKMOD("*** Invalid packet\n");
kfree_skb(skb);
}
/* */
void sc_capwap_parsingmgmtpacket(struct sc_capwap_session* session, struct sk_buff* skb) {
TRACEKMOD("### sc_capwap_parsingmgmtpacket\n");
/* Send packet with capwap header into userspace */
sc_netlink_notify_recv_data(skb->data, skb->len);
}
#include "config.h"
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/etherdevice.h>
#include <linux/ieee80211.h>
#include <net/mac80211.h>
#include <net/ipv6.h>
#include "capwap.h"
#include "nlsmartcapwap.h"
#include "netlinkapp.h"
/* */
static struct sc_capwap_session sc_acsession;
/* */
int sc_capwap_init(void) {
TRACEKMOD("### sc_capwap_init\n");
/* Init session */
memset(&sc_acsession, 0, sizeof(struct sc_capwap_session));
sc_capwap_initsession(&sc_acsession);
/* Init sockect */
memset(&sc_localaddr, 0, sizeof(union capwap_addr));
return sc_socket_init();
}
/* */
void sc_capwap_close(void) {
TRACEKMOD("### sc_capwap_close\n");
/* */
sc_socket_close();
memset(&sc_localaddr, 0, sizeof(union capwap_addr));
sc_capwap_freesession(&sc_acsession);
}
/* */
int sc_capwap_connect(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid, uint16_t mtu) {
TRACEKMOD("### sc_capwap_connect\n");
if ((sc_localaddr.ss.ss_family != AF_INET) && (sc_localaddr.ss.ss_family != AF_INET6)) {
return -ENONET;
}
/* AC address */
if ((sockaddr->ss.ss_family == AF_INET6) && ipv6_addr_v4mapped(&sockaddr->sin6.sin6_addr)) {
return -EINVAL;
} else if ((sc_localaddr.ss.ss_family == AF_INET) && (sockaddr->ss.ss_family == AF_INET6)) {
return -EINVAL;
}
/* */
memcpy(&sc_acsession.peeraddr, sockaddr, sizeof(union capwap_addr));
memcpy(&sc_acsession.sessionid, sessionid, sizeof(struct sc_capwap_sessionid_element));
sc_acsession.mtu = mtu;
return sc_capwap_sendkeepalive();
}
/* */
void sc_capwap_resetsession(void) {
TRACEKMOD("### sc_capwap_resetsession\n");
/* */
sc_capwap_freesession(&sc_acsession);
/* Reinit session */
memset(&sc_acsession, 0, sizeof(struct sc_capwap_session));
sc_capwap_initsession(&sc_acsession);
}
/* */
int sc_capwap_sendkeepalive(void) {
int ret;
int length;
uint8_t buffer[CAPWAP_KEEP_ALIVE_MAX_SIZE];
TRACEKMOD("### sc_capwap_sendkeepalive\n");
/* Build keepalive */
length = sc_capwap_createkeepalive(&sc_acsession.sessionid, buffer, CAPWAP_KEEP_ALIVE_MAX_SIZE);
/* Send packet */
ret = sc_socket_send(SOCKET_UDP, buffer, length, &sc_acsession.peeraddr);
TRACEKMOD("*** Send keep-alive result: %d\n", ret);
if (ret > 0) {
ret = 0;
}
return ret;
}
/* */
struct sc_capwap_session* sc_capwap_getsession(const union capwap_addr* sockaddr) {
TRACEKMOD("### sc_capwap_getsession\n");
if (!sockaddr) {
return &sc_acsession;
} else if (sc_acsession.peeraddr.ss.ss_family == sockaddr->ss.ss_family) {
if (sc_acsession.peeraddr.ss.ss_family == AF_INET) {
if ((sc_acsession.peeraddr.sin.sin_port == sockaddr->sin.sin_port) && (sc_acsession.peeraddr.sin.sin_addr.s_addr == sockaddr->sin.sin_addr.s_addr)) {
return &sc_acsession;
}
} else if (sc_acsession.peeraddr.ss.ss_family == AF_INET6) {
if ((sc_acsession.peeraddr.sin6.sin6_port == sockaddr->sin6.sin6_port) && !ipv6_addr_cmp(&sc_acsession.peeraddr.sin6.sin6_addr, &sockaddr->sin6.sin6_addr)) {
return &sc_acsession;
}
}
}
return NULL;
}
/* */
void sc_capwap_recvpacket(struct sk_buff* skb) {
union capwap_addr peeraddr;
struct sc_capwap_session* session;
TRACEKMOD("### sc_capwap_recvpacket\n");
/* Get peer address */
if (sc_socket_getpeeraddr(skb, &peeraddr)) {
goto drop;
}
/* Get session */
session = sc_capwap_getsession(&peeraddr);
if (!session) {
TRACEKMOD("*** Session not found\n");
goto drop;
}
/* Remove UDP header */
if (!skb_pull(skb, sizeof(struct udphdr))) {
TRACEKMOD("*** Invalid packet\n");
goto drop;
}
/* Parsing packet */
if (sc_capwap_parsingpacket(session, &peeraddr, skb)) {
TRACEKMOD("*** Parsing error\n");
goto drop;
}
return;
drop:
kfree_skb(skb);
}
/* */
struct sc_capwap_session* sc_capwap_recvunknownkeepalive(const union capwap_addr* sockaddr, const struct sc_capwap_sessionid_element* sessionid) {
TRACEKMOD("### sc_capwap_recvunknownkeepalive\n");
return NULL;
}
/* */
void sc_capwap_parsingdatapacket(struct sc_capwap_session* session, struct sk_buff* skb) {
uint8_t* pos;
uint8_t* dstaddress;
struct net_device* dev;
struct sc_capwap_header* header = (struct sc_capwap_header*)skb->data;
int is80211 = (IS_FLAG_T_HEADER(header) ? 1 : 0);
struct sc_capwap_radio_addr* radioaddr = NULL;
int radioaddrsize = 0;
struct sc_capwap_wireless_information* winfo = NULL;
struct sc_capwap_destination_wlans* destwlan = NULL;
int winfosize = 0;
TRACEKMOD("### sc_capwap_parsingdatapacket\n");
/* Retrieve optional attribute */
pos = skb->data + sizeof(struct sc_capwap_header);
if (IS_FLAG_M_HEADER(header)) {
radioaddr = (struct sc_capwap_radio_addr*)pos;
radioaddrsize = (sizeof(struct sc_capwap_radio_addr) + radioaddr->length + 3) & ~3;
pos += radioaddrsize;
}
if (IS_FLAG_W_HEADER(header)) {
winfo = (struct sc_capwap_wireless_information*)pos;
destwlan = (struct sc_capwap_destination_wlans*)(pos + sizeof(struct sc_capwap_wireless_information));
winfosize = (sizeof(struct sc_capwap_wireless_information) + winfo->length + 3) & ~3;
pos += winfosize;
}
/* Body packet */
skb_pull(skb, GET_HLEN_HEADER(header) * 4);
dstaddress = (is80211 ? ieee80211_get_DA((struct ieee80211_hdr*)skb->data) : (uint8_t*)((struct ethhdr*)skb->data)->h_dest);
if (is_multicast_ether_addr(dstaddress)) {
/* Accept only broadcast packet with wireless information */
if (winfo) {
uint8_t wlanid = 1;
uint16_t bitmask = be16_to_cpu(destwlan->wlanidbitmap);
while (bitmask) {
if (bitmask & 0x01) {
dev = sc_netlink_getdev_from_wlanid(GET_RID_HEADER(header), wlanid);
if (dev) {
struct sk_buff* clone = skb_copy_expand(skb, skb_headroom(skb), skb_tailroom(skb), GFP_KERNEL);
if (!clone) {
goto error;
}
/* */
if (!is80211) {
if (sc_capwap_8023_to_80211(clone, dev->dev_addr)) {
kfree_skb(clone);
goto error;
}
}
TRACEKMOD("*** Send broadcast packet to interface: %d\n", dev->ifindex);
/* Send packet */
local_bh_disable();
ieee80211_inject_xmit(clone, dev);
local_bh_enable();
} else {
TRACEKMOD("*** Unknown wlanid: %d\n", (int)wlanid);
}
}
/* Next */
wlanid++;
bitmask >>= 1;
}
} else {
TRACEKMOD("*** Invalid broadcast packet\n");
}
/* Free broadcast packet */
kfree_skb(skb);
} else {
/* Accept only 802.11 frame or 802.3 frame with radio address */
if (is80211 || (radioaddr && (radioaddr->length == MACADDRESS_EUI48_LENGTH))){
if (!is80211) {
if (sc_capwap_8023_to_80211(skb, radioaddr->addr)) {
goto error;
}
}
/* */
dev = sc_netlink_getdev_from_bssid(GET_RID_HEADER(header), ((struct ieee80211_hdr*)skb->data)->addr2);
if (!dev) {
goto error;
}
TRACEKMOD("** Send packet to interface: %d\n", dev->ifindex);
/* Send packet */
local_bh_disable();
ieee80211_inject_xmit(skb, dev);
local_bh_enable();
} else {
goto error;
}
}
return;
error:
TRACEKMOD("*** Invalid packet\n");
kfree_skb(skb);
}
/* */
void sc_capwap_parsingmgmtpacket(struct sc_capwap_session* session, struct sk_buff* skb) {
TRACEKMOD("### sc_capwap_parsingmgmtpacket\n");
/* Send packet with capwap header into userspace */
sc_netlink_notify_recv_data(skb->data, skb->len);
}

View File

@ -1,27 +1,27 @@
#ifndef __KMOD_CAPWAP_PRIVATE_HEADER__
#define __KMOD_CAPWAP_PRIVATE_HEADER__
/* */
struct sc_capwap_workthread {
struct task_struct* thread;
struct sk_buff_head queue;
wait_queue_head_t waitevent;
};
/* */
int sc_capwap_init(void);
void sc_capwap_close(void);
/* */
int sc_capwap_connect(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid, uint16_t mtu);
void sc_capwap_resetsession(void);
/* */
struct sc_capwap_session* sc_capwap_getsession(const union capwap_addr* sockaddr);
/* */
int sc_capwap_sendkeepalive(void);
#endif /* __KMOD_CAPWAP_PRIVATE_HEADER__ */
#ifndef __KMOD_CAPWAP_PRIVATE_HEADER__
#define __KMOD_CAPWAP_PRIVATE_HEADER__
/* */
struct sc_capwap_workthread {
struct task_struct* thread;
struct sk_buff_head queue;
wait_queue_head_t waitevent;
};
/* */
int sc_capwap_init(void);
void sc_capwap_close(void);
/* */
int sc_capwap_connect(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid, uint16_t mtu);
void sc_capwap_resetsession(void);
/* */
struct sc_capwap_session* sc_capwap_getsession(const union capwap_addr* sockaddr);
/* */
int sc_capwap_sendkeepalive(void);
#endif /* __KMOD_CAPWAP_PRIVATE_HEADER__ */

View File

@ -1,187 +1,187 @@
#ifndef __KMOD_CAPWAP_RFC_HEADER__
#define __KMOD_CAPWAP_RFC_HEADER__
#include <linux/types.h>
#include <asm/byteorder.h>
/* */
#define CAPWAP_RADIOID_MAX_COUNT 31
#define IS_VALID_RADIOID(x) ((x >= 1) && (x <= CAPWAP_RADIOID_MAX_COUNT))
#define CAPWAP_WLANID_MAX_COUNT 16
#define IS_VALID_WLANID(x) ((x >= 1) && (x <= CAPWAP_WLANID_MAX_COUNT))
/* */
#define CAPWAP_WIRELESS_BINDING_NONE 0
#define CAPWAP_WIRELESS_BINDING_IEEE80211 1
/* */
#define CAPWAP_ELEMENT_SESSIONID 35
/* */
#define CAPWAP_KEEPALIVE_SIZE (sizeof(struct sc_capwap_dtls_header) + \
sizeof(struct sc_capwap_header) + \
sizeof(struct sc_capwap_data_message) + \
sizeof(struct sc_capwap_message_element) + \
sizeof(struct sc_capwap_sessionid_element))
/* Preamble */
struct sc_capwap_preamble {
#if defined(__BIG_ENDIAN_BITFIELD)
uint8_t version: 4,
type: 4;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
uint8_t type: 4,
version: 4;
#endif
} __packed;
/* DTLS header */
struct sc_capwap_dtls_header {
struct sc_capwap_preamble preamble;
uint8_t reserved[3];
} __packed;
/* Plain header */
struct sc_capwap_header {
struct sc_capwap_preamble preamble;
#if defined(__BIG_ENDIAN_BITFIELD)
uint16_t hlen: 5,
rid: 5,
wbid: 5,
flag_t: 1;
uint8_t flag_f: 1,
flag_l: 1,
flag_w: 1,
flag_m: 1,
flag_k: 1,
flag_res: 3;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
uint16_t _rid_hi: 3,
hlen: 5,
flag_t: 1,
wbid: 5,
_rid_lo: 2;
uint8_t flag_res: 3,
flag_k: 1,
flag_m: 1,
flag_w: 1,
flag_l: 1,
flag_f: 1;
#endif
__be16 frag_id;
__be16 frag_off;
} __packed;
/* Mac Address */
#define CAPWAP_RADIO_EUI48_LENGTH_PADDED 8
#define CAPWAP_RADIO_EUI64_LENGTH_PADDED 12
#define CAPWAP_RADIO_MAX_LENGTH_PADDED 12
struct sc_capwap_radio_addr {
uint8_t length;
uint8_t addr[0];
} __packed;
/* Wireless Information */
#define CAPWAP_WINFO_FRAMEINFO_LENGTH_PADDED 8
#define CAPWAP_WINFO_DESTWLAN_LENGTH_PADDED 8
#define CAPWAP_WINFO_MAX_LENGTH_PADDED 8
struct sc_capwap_wireless_information {
uint8_t length;
} __packed;
/* IEEE802.11 Wireless Information */
struct sc_capwap_ieee80211_frame_info {
uint8_t rssi;
uint8_t snr;
__be16 rate;
} __packed;
/* Destination WLANs */
struct sc_capwap_destination_wlans {
__be16 wlanidbitmap;
__be16 reserved;
} __packed;
/* */
#define CAPWAP_HEADER_MAX_LENGTH (sizeof(struct sc_capwap_header) + CAPWAP_RADIO_MAX_LENGTH_PADDED + CAPWAP_WINFO_MAX_LENGTH_PADDED)
/* Data channel message */
struct sc_capwap_data_message {
__be16 length;
} __packed;
/* Message element */
struct sc_capwap_message_element {
__be16 type;
__be16 length;
} __packed;
/* Session id message element */
struct sc_capwap_sessionid_element {
union {
uint8_t id[16];
uint32_t id32[4];
};
} __packed;
/* */
#define MACADDRESS_EUI48_LENGTH 6
struct sc_capwap_macaddress_eui48 {
uint8_t addr[MACADDRESS_EUI48_LENGTH];
} __packed;
/* */
#define MACADDRESS_EUI64_LENGTH 8
struct sc_capwap_macaddress_eui64 {
uint8_t addr[MACADDRESS_EUI64_LENGTH];
} __packed;
/* Capwap preamble */
#define CAPWAP_PROTOCOL_VERSION 0
#define CAPWAP_PREAMBLE_HEADER 0
#define CAPWAP_PREAMBLE_DTLS_HEADER 1
#define CAPWAP_WIRELESS_BINDING_NONE 0
#define CAPWAP_WIRELESS_BINDING_IEEE80211 1
/* */
#define CAPWAP_KEEP_ALIVE_MAX_SIZE (sizeof(struct sc_capwap_header) + sizeof(struct sc_capwap_data_message) + sizeof(struct sc_capwap_message_element) + sizeof(struct sc_capwap_sessionid_element))
/* */
#define GET_VERSION_HEADER(x) ((x)->preamble.version)
#define SET_VERSION_HEADER(x, y) ((x)->preamble.version = (uint8_t)(y))
#define GET_TYPE_HEADER(x) ((x)->preamble.type)
#define SET_TYPE_HEADER(x, y) ((x)->preamble.type = (uint8_t)(y))
#define GET_HLEN_HEADER(x) ((x)->hlen)
#define SET_HLEN_HEADER(x, y) ((x)->hlen = (uint16_t)(y))
#if defined(__BIG_ENDIAN_BITFIELD)
#define GET_RID_HEADER(x) ((uint8_t)((x)->rid))
#define SET_RID_HEADER(x, y) ((x)->rid = (uint16_t)(y))
#elif defined(__LITTLE_ENDIAN_BITFIELD)
#define GET_RID_HEADER(x) ((uint8_t)((uint16_t)((x)->_rid_hi << 2 | (x)->_rid_lo)))
#define SET_RID_HEADER(x, y) ({ (x)->_rid_hi = (uint16_t)((y) >> 2); (x)->_rid_lo = (uint16_t)((y) & 0x0003); })
#endif
#define GET_WBID_HEADER(x) ((uint8_t)((x)->wbid))
#define SET_WBID_HEADER(x, y) ((x)->wbid = (uint16_t)(y))
#define IS_FLAG_T_HEADER(x) ((x)->flag_t)
#define SET_FLAG_T_HEADER(x, y) ((x)->flag_t = ((y) ? 1 : 0))
#define IS_FLAG_F_HEADER(x) ((x)->flag_f)
#define SET_FLAG_F_HEADER(x, y) ((x)->flag_f = ((y) ? 1 : 0))
#define IS_FLAG_L_HEADER(x) ((x)->flag_l)
#define SET_FLAG_L_HEADER(x, y) ((x)->flag_l = ((y) ? 1 : 0))
#define IS_FLAG_W_HEADER(x) ((x)->flag_w)
#define SET_FLAG_W_HEADER(x, y) ((x)->flag_w = ((y) ? 1 : 0))
#define IS_FLAG_M_HEADER(x) ((x)->flag_m)
#define SET_FLAG_M_HEADER(x, y) ((x)->flag_m = ((y) ? 1 : 0))
#define IS_FLAG_K_HEADER(x) ((x)->flag_k)
#define SET_FLAG_K_HEADER(x, y) ((x)->flag_k = ((y) ? 1 : 0))
/* IEEE 802.11 Add WLAN */
#define CAPWAP_ADD_WLAN_TUNNELMODE_LOCAL 0
#define CAPWAP_ADD_WLAN_TUNNELMODE_8023 1
#define CAPWAP_ADD_WLAN_TUNNELMODE_80211 2
#endif /* __KMOD_CAPWAP_RFC_HEADER__ */
#ifndef __KMOD_CAPWAP_RFC_HEADER__
#define __KMOD_CAPWAP_RFC_HEADER__
#include <linux/types.h>
#include <asm/byteorder.h>
/* */
#define CAPWAP_RADIOID_MAX_COUNT 31
#define IS_VALID_RADIOID(x) ((x >= 1) && (x <= CAPWAP_RADIOID_MAX_COUNT))
#define CAPWAP_WLANID_MAX_COUNT 16
#define IS_VALID_WLANID(x) ((x >= 1) && (x <= CAPWAP_WLANID_MAX_COUNT))
/* */
#define CAPWAP_WIRELESS_BINDING_NONE 0
#define CAPWAP_WIRELESS_BINDING_IEEE80211 1
/* */
#define CAPWAP_ELEMENT_SESSIONID 35
/* */
#define CAPWAP_KEEPALIVE_SIZE (sizeof(struct sc_capwap_dtls_header) + \
sizeof(struct sc_capwap_header) + \
sizeof(struct sc_capwap_data_message) + \
sizeof(struct sc_capwap_message_element) + \
sizeof(struct sc_capwap_sessionid_element))
/* Preamble */
struct sc_capwap_preamble {
#if defined(__BIG_ENDIAN_BITFIELD)
uint8_t version: 4,
type: 4;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
uint8_t type: 4,
version: 4;
#endif
} __packed;
/* DTLS header */
struct sc_capwap_dtls_header {
struct sc_capwap_preamble preamble;
uint8_t reserved[3];
} __packed;
/* Plain header */
struct sc_capwap_header {
struct sc_capwap_preamble preamble;
#if defined(__BIG_ENDIAN_BITFIELD)
uint16_t hlen: 5,
rid: 5,
wbid: 5,
flag_t: 1;
uint8_t flag_f: 1,
flag_l: 1,
flag_w: 1,
flag_m: 1,
flag_k: 1,
flag_res: 3;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
uint16_t _rid_hi: 3,
hlen: 5,
flag_t: 1,
wbid: 5,
_rid_lo: 2;
uint8_t flag_res: 3,
flag_k: 1,
flag_m: 1,
flag_w: 1,
flag_l: 1,
flag_f: 1;
#endif
__be16 frag_id;
__be16 frag_off;
} __packed;
/* Mac Address */
#define CAPWAP_RADIO_EUI48_LENGTH_PADDED 8
#define CAPWAP_RADIO_EUI64_LENGTH_PADDED 12
#define CAPWAP_RADIO_MAX_LENGTH_PADDED 12
struct sc_capwap_radio_addr {
uint8_t length;
uint8_t addr[0];
} __packed;
/* Wireless Information */
#define CAPWAP_WINFO_FRAMEINFO_LENGTH_PADDED 8
#define CAPWAP_WINFO_DESTWLAN_LENGTH_PADDED 8
#define CAPWAP_WINFO_MAX_LENGTH_PADDED 8
struct sc_capwap_wireless_information {
uint8_t length;
} __packed;
/* IEEE802.11 Wireless Information */
struct sc_capwap_ieee80211_frame_info {
uint8_t rssi;
uint8_t snr;
__be16 rate;
} __packed;
/* Destination WLANs */
struct sc_capwap_destination_wlans {
__be16 wlanidbitmap;
__be16 reserved;
} __packed;
/* */
#define CAPWAP_HEADER_MAX_LENGTH (sizeof(struct sc_capwap_header) + CAPWAP_RADIO_MAX_LENGTH_PADDED + CAPWAP_WINFO_MAX_LENGTH_PADDED)
/* Data channel message */
struct sc_capwap_data_message {
__be16 length;
} __packed;
/* Message element */
struct sc_capwap_message_element {
__be16 type;
__be16 length;
} __packed;
/* Session id message element */
struct sc_capwap_sessionid_element {
union {
uint8_t id[16];
uint32_t id32[4];
};
} __packed;
/* */
#define MACADDRESS_EUI48_LENGTH 6
struct sc_capwap_macaddress_eui48 {
uint8_t addr[MACADDRESS_EUI48_LENGTH];
} __packed;
/* */
#define MACADDRESS_EUI64_LENGTH 8
struct sc_capwap_macaddress_eui64 {
uint8_t addr[MACADDRESS_EUI64_LENGTH];
} __packed;
/* Capwap preamble */
#define CAPWAP_PROTOCOL_VERSION 0
#define CAPWAP_PREAMBLE_HEADER 0
#define CAPWAP_PREAMBLE_DTLS_HEADER 1
#define CAPWAP_WIRELESS_BINDING_NONE 0
#define CAPWAP_WIRELESS_BINDING_IEEE80211 1
/* */
#define CAPWAP_KEEP_ALIVE_MAX_SIZE (sizeof(struct sc_capwap_header) + sizeof(struct sc_capwap_data_message) + sizeof(struct sc_capwap_message_element) + sizeof(struct sc_capwap_sessionid_element))
/* */
#define GET_VERSION_HEADER(x) ((x)->preamble.version)
#define SET_VERSION_HEADER(x, y) ((x)->preamble.version = (uint8_t)(y))
#define GET_TYPE_HEADER(x) ((x)->preamble.type)
#define SET_TYPE_HEADER(x, y) ((x)->preamble.type = (uint8_t)(y))
#define GET_HLEN_HEADER(x) ((x)->hlen)
#define SET_HLEN_HEADER(x, y) ((x)->hlen = (uint16_t)(y))
#if defined(__BIG_ENDIAN_BITFIELD)
#define GET_RID_HEADER(x) ((uint8_t)((x)->rid))
#define SET_RID_HEADER(x, y) ((x)->rid = (uint16_t)(y))
#elif defined(__LITTLE_ENDIAN_BITFIELD)
#define GET_RID_HEADER(x) ((uint8_t)((uint16_t)((x)->_rid_hi << 2 | (x)->_rid_lo)))
#define SET_RID_HEADER(x, y) ({ (x)->_rid_hi = (uint16_t)((y) >> 2); (x)->_rid_lo = (uint16_t)((y) & 0x0003); })
#endif
#define GET_WBID_HEADER(x) ((uint8_t)((x)->wbid))
#define SET_WBID_HEADER(x, y) ((x)->wbid = (uint16_t)(y))
#define IS_FLAG_T_HEADER(x) ((x)->flag_t)
#define SET_FLAG_T_HEADER(x, y) ((x)->flag_t = ((y) ? 1 : 0))
#define IS_FLAG_F_HEADER(x) ((x)->flag_f)
#define SET_FLAG_F_HEADER(x, y) ((x)->flag_f = ((y) ? 1 : 0))
#define IS_FLAG_L_HEADER(x) ((x)->flag_l)
#define SET_FLAG_L_HEADER(x, y) ((x)->flag_l = ((y) ? 1 : 0))
#define IS_FLAG_W_HEADER(x) ((x)->flag_w)
#define SET_FLAG_W_HEADER(x, y) ((x)->flag_w = ((y) ? 1 : 0))
#define IS_FLAG_M_HEADER(x) ((x)->flag_m)
#define SET_FLAG_M_HEADER(x, y) ((x)->flag_m = ((y) ? 1 : 0))
#define IS_FLAG_K_HEADER(x) ((x)->flag_k)
#define SET_FLAG_K_HEADER(x, y) ((x)->flag_k = ((y) ? 1 : 0))
/* IEEE 802.11 Add WLAN */
#define CAPWAP_ADD_WLAN_TUNNELMODE_LOCAL 0
#define CAPWAP_ADD_WLAN_TUNNELMODE_8023 1
#define CAPWAP_ADD_WLAN_TUNNELMODE_80211 2
#endif /* __KMOD_CAPWAP_RFC_HEADER__ */

View File

@ -1,13 +1,13 @@
#ifndef __KMOD_CONFIG_HEADER__
#define __KMOD_CONFIG_HEADER__
#define DEBUGKMOD 1
#ifdef DEBUGKMOD
#define TRACEKMOD(s, args...) printk(s, ##args)
#else
#define TRACEKMOD(s, args...)
#endif
#endif /* __KMOD_CONFIG_HEADER__ */
#ifndef __KMOD_CONFIG_HEADER__
#define __KMOD_CONFIG_HEADER__
#define DEBUGKMOD 1
#ifdef DEBUGKMOD
#define TRACEKMOD(s, args...) printk(s, ##args)
#else
#define TRACEKMOD(s, args...)
#endif
#endif /* __KMOD_CONFIG_HEADER__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,19 @@
#ifndef __KMOD_WTP_NETLINKAPP_HEADER__
#define __KMOD_WTP_NETLINKAPP_HEADER__
#include "capwap_rfc.h"
#include "socket.h"
/* */
int sc_netlink_init(void);
void sc_netlink_exit(void);
/* */
struct net_device* sc_netlink_getdev_from_wlanid(uint8_t radioid, uint8_t wlanid);
struct net_device* sc_netlink_getdev_from_bssid(uint8_t radioid, const uint8_t* addr);
/* */
int sc_netlink_notify_recv_keepalive(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid);
int sc_netlink_notify_recv_data(uint8_t* packet, int length);
#endif /* __KMOD_WTP_NETLINKAPP_HEADER__ */
#ifndef __KMOD_WTP_NETLINKAPP_HEADER__
#define __KMOD_WTP_NETLINKAPP_HEADER__
#include "capwap_rfc.h"
#include "socket.h"
/* */
int sc_netlink_init(void);
void sc_netlink_exit(void);
/* */
struct net_device* sc_netlink_getdev_from_wlanid(uint8_t radioid, uint8_t wlanid);
struct net_device* sc_netlink_getdev_from_bssid(uint8_t radioid, const uint8_t* addr);
/* */
int sc_netlink_notify_recv_keepalive(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid);
int sc_netlink_notify_recv_data(uint8_t* packet, int length);
#endif /* __KMOD_WTP_NETLINKAPP_HEADER__ */

View File

@ -1,66 +1,66 @@
#ifndef __WTP_NLSMARTCAPWAP_HEADER__
#define __WTP_NLSMARTCAPWAP_HEADER__
/* */
#define NLSMARTCAPWAP_GENL_NAME "smartcapwap_wtp"
/* */
#define NLSMARTCAPWAP_FLAGS_TUNNEL_8023 0x00000001
/* */
enum nlsmartcapwap_attrs {
NLSMARTCAPWAP_ATTR_UNSPEC,
NLSMARTCAPWAP_ATTR_IFINDEX,
NLSMARTCAPWAP_ATTR_RADIOID,
NLSMARTCAPWAP_ATTR_WLANID,
NLSMARTCAPWAP_ATTR_BINDING,
NLSMARTCAPWAP_ATTR_FLAGS,
NLSMARTCAPWAP_ATTR_MGMT_SUBTYPE_MASK,
NLSMARTCAPWAP_ATTR_CTRL_SUBTYPE_MASK,
NLSMARTCAPWAP_ATTR_DATA_SUBTYPE_MASK,
NLSMARTCAPWAP_ATTR_ADDRESS,
NLSMARTCAPWAP_ATTR_MTU,
NLSMARTCAPWAP_ATTR_SESSION_ID,
NLSMARTCAPWAP_ATTR_DTLS,
NLSMARTCAPWAP_ATTR_DATA_FRAME,
NLSMARTCAPWAP_ATTR_RSSI,
NLSMARTCAPWAP_ATTR_SNR,
NLSMARTCAPWAP_ATTR_RATE,
/* Last attribute */
__NLSMARTCAPWAP_ATTR_AFTER_LAST,
NLSMARTCAPWAP_ATTR_MAX = __NLSMARTCAPWAP_ATTR_AFTER_LAST - 1
};
/* */
enum nlsmartcapwap_commands {
NLSMARTCAPWAP_CMD_UNSPEC,
NLSMARTCAPWAP_CMD_LINK,
NLSMARTCAPWAP_CMD_BIND,
NLSMARTCAPWAP_CMD_CONNECT,
NLSMARTCAPWAP_CMD_RESET,
NLSMARTCAPWAP_CMD_SEND_KEEPALIVE,
NLSMARTCAPWAP_CMD_RECV_KEEPALIVE,
NLSMARTCAPWAP_CMD_SEND_DATA,
NLSMARTCAPWAP_CMD_RECV_DATA,
NLSMARTCAPWAP_CMD_JOIN_MAC80211_DEVICE,
NLSMARTCAPWAP_CMD_LEAVE_MAC80211_DEVICE,
/* Last command */
__NLSMARTCAPWAP_CMD_AFTER_LAST,
NLSMARTCAPWAP_CMD_MAX = __NLSMARTCAPWAP_CMD_AFTER_LAST - 1
};
#endif /* __WTP_NLSMARTCAPWAP_HEADER__ */
#ifndef __WTP_NLSMARTCAPWAP_HEADER__
#define __WTP_NLSMARTCAPWAP_HEADER__
/* */
#define NLSMARTCAPWAP_GENL_NAME "smartcapwap_wtp"
/* */
#define NLSMARTCAPWAP_FLAGS_TUNNEL_8023 0x00000001
/* */
enum nlsmartcapwap_attrs {
NLSMARTCAPWAP_ATTR_UNSPEC,
NLSMARTCAPWAP_ATTR_IFINDEX,
NLSMARTCAPWAP_ATTR_RADIOID,
NLSMARTCAPWAP_ATTR_WLANID,
NLSMARTCAPWAP_ATTR_BINDING,
NLSMARTCAPWAP_ATTR_FLAGS,
NLSMARTCAPWAP_ATTR_MGMT_SUBTYPE_MASK,
NLSMARTCAPWAP_ATTR_CTRL_SUBTYPE_MASK,
NLSMARTCAPWAP_ATTR_DATA_SUBTYPE_MASK,
NLSMARTCAPWAP_ATTR_ADDRESS,
NLSMARTCAPWAP_ATTR_MTU,
NLSMARTCAPWAP_ATTR_SESSION_ID,
NLSMARTCAPWAP_ATTR_DTLS,
NLSMARTCAPWAP_ATTR_DATA_FRAME,
NLSMARTCAPWAP_ATTR_RSSI,
NLSMARTCAPWAP_ATTR_SNR,
NLSMARTCAPWAP_ATTR_RATE,
/* Last attribute */
__NLSMARTCAPWAP_ATTR_AFTER_LAST,
NLSMARTCAPWAP_ATTR_MAX = __NLSMARTCAPWAP_ATTR_AFTER_LAST - 1
};
/* */
enum nlsmartcapwap_commands {
NLSMARTCAPWAP_CMD_UNSPEC,
NLSMARTCAPWAP_CMD_LINK,
NLSMARTCAPWAP_CMD_BIND,
NLSMARTCAPWAP_CMD_CONNECT,
NLSMARTCAPWAP_CMD_RESET,
NLSMARTCAPWAP_CMD_SEND_KEEPALIVE,
NLSMARTCAPWAP_CMD_RECV_KEEPALIVE,
NLSMARTCAPWAP_CMD_SEND_DATA,
NLSMARTCAPWAP_CMD_RECV_DATA,
NLSMARTCAPWAP_CMD_JOIN_MAC80211_DEVICE,
NLSMARTCAPWAP_CMD_LEAVE_MAC80211_DEVICE,
/* Last command */
__NLSMARTCAPWAP_CMD_AFTER_LAST,
NLSMARTCAPWAP_CMD_MAX = __NLSMARTCAPWAP_CMD_AFTER_LAST - 1
};
#endif /* __WTP_NLSMARTCAPWAP_HEADER__ */

View File

@ -1,227 +1,227 @@
#include "config.h"
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/socket.h>
#include <linux/kthread.h>
#include <linux/net.h>
#include <linux/if_ether.h>
#include <linux/udp.h>
#include <net/ipv6.h>
#include <net/sock.h>
#include <net/udp.h>
#include "socket.h"
#include "capwap.h"
/* Socket */
#define SOCKET_COUNT 2
static struct socket* sc_sockets[SOCKET_COUNT];
/* */
int sc_socket_recvpacket(struct sock* sk, struct sk_buff* skb) {
TRACEKMOD("### sc_socket_recvpacket\n");
/* */
CAPWAP_SKB_CB(skb)->flags = SKB_CAPWAP_FLAG_FROM_DATA_CHANNEL;
/* */
sc_capwap_recvpacket(skb);
return 0;
}
/* */
static int sc_socket_create(int type, union capwap_addr* sockaddr, uint16_t protocol) {
int ret;
TRACEKMOD("### sc_socket_create\n");
/* Create socket */
ret = sock_create_kern(sockaddr->ss.ss_family, SOCK_DGRAM, protocol, &sc_sockets[type]);
if (ret) {
return ret;
}
/* Bind to interface */
ret = kernel_bind(sc_sockets[type], &sockaddr->sa, sizeof(union capwap_addr));
if (ret) {
goto failure;
}
/* Set callback */
udp_sk(sc_sockets[type]->sk)->encap_type = 1;
udp_sk(sc_sockets[type]->sk)->encap_rcv = sc_socket_recvpacket;
/* */
if (!((sockaddr->ss.ss_family == AF_INET) ? sockaddr->sin.sin_port : sockaddr->sin6.sin6_port)) {
union capwap_addr localaddr;
int localaddrsize = sizeof(union capwap_addr);
/* Retrieve port */
ret = kernel_getsockname(sc_sockets[type], &localaddr.sa, &localaddrsize);
if (ret) {
goto failure;
}
/* */
if ((sockaddr->ss.ss_family == AF_INET) && (localaddr.ss.ss_family == AF_INET)) {
sockaddr->sin.sin_port = localaddr.sin.sin_port;
} else if ((sockaddr->ss.ss_family == AF_INET6) && (localaddr.ss.ss_family == AF_INET6)) {
sockaddr->sin6.sin6_port = localaddr.sin6.sin6_port;
} else {
ret = -EFAULT;
goto failure;
}
}
return 0;
failure:
sock_release(sc_sockets[type]);
sc_sockets[type] = 0;
return ret;
}
/* */
int sc_socket_getpeeraddr(struct sk_buff* skb, union capwap_addr* peeraddr) {
unsigned char* nethdr;
TRACEKMOD("### sc_socket_getpeeraddr\n");
/* */
nethdr = skb_network_header(skb);
if (!nethdr) {
return -EINVAL;
}
/* */
switch (ntohs(skb->protocol)) {
case ETH_P_IP: {
/* Validate IPv4 header */
if ((nethdr[0] & 0xf0) != 0x40) {
return -EINVAL;
}
/* Retrieve address */
peeraddr->sin.sin_family = AF_INET;
peeraddr->sin.sin_addr.s_addr = ((struct iphdr*)nethdr)->saddr;
peeraddr->sin.sin_port = udp_hdr(skb)->source;
break;
}
case ETH_P_IPV6: {
/* Validate IPv6 header */
if ((nethdr[0] & 0xf0) != 0x60) {
return -EINVAL;
}
/* Retrieve address */
peeraddr->sin6.sin6_family = AF_INET6;
memcpy(&peeraddr->sin6.sin6_addr, &((struct ipv6hdr*)nethdr)->saddr, sizeof(struct in6_addr));
peeraddr->sin6.sin6_port = udp_hdr(skb)->source;
break;
}
default: {
return -EINVAL;
}
}
return 0;
}
/* */
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr) {
struct kvec vec;
struct msghdr msg;
TRACEKMOD("### sc_socket_send\n");
/* */
vec.iov_base = buffer;
vec.iov_len = length;
/* */
memset(&msg, 0, sizeof(struct msghdr));
msg.msg_name = sockaddr;
msg.msg_namelen = sizeof(union capwap_addr);
msg.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT;
/* */
return kernel_sendmsg(sc_sockets[type], &msg, &vec, 1, length);
}
/* */
int sc_socket_init(void) {
TRACEKMOD("### sc_socket_init\n");
memset(sc_sockets, 0, sizeof(sc_sockets));
return 0;
}
/* */
int sc_socket_bind(union capwap_addr* sockaddr) {
int ret;
TRACEKMOD("### sc_socket_bind\n");
/* */
if (sc_sockets[SOCKET_UDP] || sc_sockets[SOCKET_UDPLITE]) {
return -EBUSY;
}
/* UDP socket */
ret = sc_socket_create(SOCKET_UDP, sockaddr, IPPROTO_UDP);
if (ret) {
goto failure;
}
/* UDPLite socket */
ret = sc_socket_create(SOCKET_UDPLITE, sockaddr, IPPROTO_UDPLITE);
if (ret) {
goto failure;
}
/* */
udp_encap_enable();
if (sockaddr->ss.ss_family == AF_INET6) {
udpv6_encap_enable();
}
return 0;
failure:
sc_socket_close();
return ret;
}
/* */
void sc_socket_close(void) {
TRACEKMOD("### sc_socket_close\n");
/* Close sockets */
if (sc_sockets[SOCKET_UDP]) {
kernel_sock_shutdown(sc_sockets[SOCKET_UDP], SHUT_RDWR);
sock_release(sc_sockets[SOCKET_UDP]);
}
if (sc_sockets[SOCKET_UDPLITE]) {
kernel_sock_shutdown(sc_sockets[SOCKET_UDPLITE], SHUT_RDWR);
sock_release(sc_sockets[SOCKET_UDPLITE]);
}
memset(sc_sockets, 0, sizeof(sc_sockets));
}
/* */
int sc_addr_compare(const union capwap_addr* addr1, const union capwap_addr* addr2) {
TRACEKMOD("### sc_addr_compare\n");
if (addr1->ss.ss_family == addr2->ss.ss_family) {
if (addr1->ss.ss_family == AF_INET) {
return (((addr1->sin.sin_addr.s_addr == addr2->sin.sin_addr.s_addr) && (addr1->sin.sin_port == addr2->sin.sin_port)) ? 0 : -1);
} else if (addr1->ss.ss_family == AF_INET6) {
return ((!memcmp(&addr1->sin6.sin6_addr, &addr2->sin6.sin6_addr, sizeof(struct in6_addr)) && (addr1->sin6.sin6_port == addr2->sin6.sin6_port)) ? 0 : -1);
}
}
return -1;
}
#include "config.h"
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/socket.h>
#include <linux/kthread.h>
#include <linux/net.h>
#include <linux/if_ether.h>
#include <linux/udp.h>
#include <net/ipv6.h>
#include <net/sock.h>
#include <net/udp.h>
#include "socket.h"
#include "capwap.h"
/* Socket */
#define SOCKET_COUNT 2
static struct socket* sc_sockets[SOCKET_COUNT];
/* */
int sc_socket_recvpacket(struct sock* sk, struct sk_buff* skb) {
TRACEKMOD("### sc_socket_recvpacket\n");
/* */
CAPWAP_SKB_CB(skb)->flags = SKB_CAPWAP_FLAG_FROM_DATA_CHANNEL;
/* */
sc_capwap_recvpacket(skb);
return 0;
}
/* */
static int sc_socket_create(int type, union capwap_addr* sockaddr, uint16_t protocol) {
int ret;
TRACEKMOD("### sc_socket_create\n");
/* Create socket */
ret = sock_create_kern(sockaddr->ss.ss_family, SOCK_DGRAM, protocol, &sc_sockets[type]);
if (ret) {
return ret;
}
/* Bind to interface */
ret = kernel_bind(sc_sockets[type], &sockaddr->sa, sizeof(union capwap_addr));
if (ret) {
goto failure;
}
/* Set callback */
udp_sk(sc_sockets[type]->sk)->encap_type = 1;
udp_sk(sc_sockets[type]->sk)->encap_rcv = sc_socket_recvpacket;
/* */
if (!((sockaddr->ss.ss_family == AF_INET) ? sockaddr->sin.sin_port : sockaddr->sin6.sin6_port)) {
union capwap_addr localaddr;
int localaddrsize = sizeof(union capwap_addr);
/* Retrieve port */
ret = kernel_getsockname(sc_sockets[type], &localaddr.sa, &localaddrsize);
if (ret) {
goto failure;
}
/* */
if ((sockaddr->ss.ss_family == AF_INET) && (localaddr.ss.ss_family == AF_INET)) {
sockaddr->sin.sin_port = localaddr.sin.sin_port;
} else if ((sockaddr->ss.ss_family == AF_INET6) && (localaddr.ss.ss_family == AF_INET6)) {
sockaddr->sin6.sin6_port = localaddr.sin6.sin6_port;
} else {
ret = -EFAULT;
goto failure;
}
}
return 0;
failure:
sock_release(sc_sockets[type]);
sc_sockets[type] = 0;
return ret;
}
/* */
int sc_socket_getpeeraddr(struct sk_buff* skb, union capwap_addr* peeraddr) {
unsigned char* nethdr;
TRACEKMOD("### sc_socket_getpeeraddr\n");
/* */
nethdr = skb_network_header(skb);
if (!nethdr) {
return -EINVAL;
}
/* */
switch (ntohs(skb->protocol)) {
case ETH_P_IP: {
/* Validate IPv4 header */
if ((nethdr[0] & 0xf0) != 0x40) {
return -EINVAL;
}
/* Retrieve address */
peeraddr->sin.sin_family = AF_INET;
peeraddr->sin.sin_addr.s_addr = ((struct iphdr*)nethdr)->saddr;
peeraddr->sin.sin_port = udp_hdr(skb)->source;
break;
}
case ETH_P_IPV6: {
/* Validate IPv6 header */
if ((nethdr[0] & 0xf0) != 0x60) {
return -EINVAL;
}
/* Retrieve address */
peeraddr->sin6.sin6_family = AF_INET6;
memcpy(&peeraddr->sin6.sin6_addr, &((struct ipv6hdr*)nethdr)->saddr, sizeof(struct in6_addr));
peeraddr->sin6.sin6_port = udp_hdr(skb)->source;
break;
}
default: {
return -EINVAL;
}
}
return 0;
}
/* */
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr) {
struct kvec vec;
struct msghdr msg;
TRACEKMOD("### sc_socket_send\n");
/* */
vec.iov_base = buffer;
vec.iov_len = length;
/* */
memset(&msg, 0, sizeof(struct msghdr));
msg.msg_name = sockaddr;
msg.msg_namelen = sizeof(union capwap_addr);
msg.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT;
/* */
return kernel_sendmsg(sc_sockets[type], &msg, &vec, 1, length);
}
/* */
int sc_socket_init(void) {
TRACEKMOD("### sc_socket_init\n");
memset(sc_sockets, 0, sizeof(sc_sockets));
return 0;
}
/* */
int sc_socket_bind(union capwap_addr* sockaddr) {
int ret;
TRACEKMOD("### sc_socket_bind\n");
/* */
if (sc_sockets[SOCKET_UDP] || sc_sockets[SOCKET_UDPLITE]) {
return -EBUSY;
}
/* UDP socket */
ret = sc_socket_create(SOCKET_UDP, sockaddr, IPPROTO_UDP);
if (ret) {
goto failure;
}
/* UDPLite socket */
ret = sc_socket_create(SOCKET_UDPLITE, sockaddr, IPPROTO_UDPLITE);
if (ret) {
goto failure;
}
/* */
udp_encap_enable();
if (sockaddr->ss.ss_family == AF_INET6) {
udpv6_encap_enable();
}
return 0;
failure:
sc_socket_close();
return ret;
}
/* */
void sc_socket_close(void) {
TRACEKMOD("### sc_socket_close\n");
/* Close sockets */
if (sc_sockets[SOCKET_UDP]) {
kernel_sock_shutdown(sc_sockets[SOCKET_UDP], SHUT_RDWR);
sock_release(sc_sockets[SOCKET_UDP]);
}
if (sc_sockets[SOCKET_UDPLITE]) {
kernel_sock_shutdown(sc_sockets[SOCKET_UDPLITE], SHUT_RDWR);
sock_release(sc_sockets[SOCKET_UDPLITE]);
}
memset(sc_sockets, 0, sizeof(sc_sockets));
}
/* */
int sc_addr_compare(const union capwap_addr* addr1, const union capwap_addr* addr2) {
TRACEKMOD("### sc_addr_compare\n");
if (addr1->ss.ss_family == addr2->ss.ss_family) {
if (addr1->ss.ss_family == AF_INET) {
return (((addr1->sin.sin_addr.s_addr == addr2->sin.sin_addr.s_addr) && (addr1->sin.sin_port == addr2->sin.sin_port)) ? 0 : -1);
} else if (addr1->ss.ss_family == AF_INET6) {
return ((!memcmp(&addr1->sin6.sin6_addr, &addr2->sin6.sin6_addr, sizeof(struct in6_addr)) && (addr1->sin6.sin6_port == addr2->sin6.sin6_port)) ? 0 : -1);
}
}
return -1;
}

View File

@ -1,35 +1,35 @@
#ifndef __KMOD_SOCKET_HEADER__
#define __KMOD_SOCKET_HEADER__
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/skbuff.h>
/* */
#define SOCKET_UDP 0
#define SOCKET_UDPLITE 1
/* Universal socket address */
union capwap_addr {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
struct sockaddr_storage ss;
};
/* */
int sc_socket_init(void);
void sc_socket_close(void);
/* */
int sc_socket_bind(union capwap_addr* sockaddr);
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr);
/* */
int sc_socket_getpeeraddr(struct sk_buff* skb, union capwap_addr* peeraddr);
/* */
int sc_addr_compare(const union capwap_addr* addr1, const union capwap_addr* addr2);
#endif /* __KMOD_SOCKET_HEADER__ */
#ifndef __KMOD_SOCKET_HEADER__
#define __KMOD_SOCKET_HEADER__
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/skbuff.h>
/* */
#define SOCKET_UDP 0
#define SOCKET_UDPLITE 1
/* Universal socket address */
union capwap_addr {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
struct sockaddr_storage ss;
};
/* */
int sc_socket_init(void);
void sc_socket_close(void);
/* */
int sc_socket_bind(union capwap_addr* sockaddr);
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr);
/* */
int sc_socket_getpeeraddr(struct sk_buff* skb, union capwap_addr* peeraddr);
/* */
int sc_addr_compare(const union capwap_addr* addr1, const union capwap_addr* addr2);
#endif /* __KMOD_SOCKET_HEADER__ */

View File

@ -1,65 +1,65 @@
#include "wtp.h"
#include "wtp_radio.h"
/* */
void wtp_create_radioopsstate_element(struct capwap_packet_txmng* txmngpacket) {
int i;
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);
struct capwap_radiooprstate_element radiooprstate;
radiooprstate.radioid = radio->radioid;
radiooprstate.state = ((radio->status == WTP_RADIO_ENABLED) ? CAPWAP_RADIO_OPERATIONAL_STATE_ENABLED : CAPWAP_RADIO_OPERATIONAL_STATE_DISABLED);
if (radio->status == WTP_RADIO_ENABLED) {
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_NORMAL;
} else if (radio->status == WTP_RADIO_DISABLED) {
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_ADMINSET;
} else if (radio->status == WTP_RADIO_HWFAILURE) {
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_RADIOFAILURE;
} else if (radio->status == WTP_RADIO_SWFAILURE) {
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_SOFTWAREFAILURE;
} else {
/* Unknown value */
ASSERT(0);
}
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RADIOOPRSTATE, &radiooprstate);
}
}
/* */
void wtp_create_radioadmstate_element(struct capwap_packet_txmng* txmngpacket) {
int i;
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);
struct capwap_radioadmstate_element radioadmstate;
radioadmstate.radioid = radio->radioid;
radioadmstate.state = ((radio->status == WTP_RADIO_DISABLED) ? CAPWAP_RADIO_ADMIN_STATE_DISABLED : CAPWAP_RADIO_ADMIN_STATE_ENABLED);
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RADIOADMSTATE, &radioadmstate);
}
}
/* */
void wtp_create_80211_wtpradioinformation_element(struct capwap_packet_txmng* txmngpacket) {
int i;
struct wtp_radio* radio;
struct capwap_80211_wtpradioinformation_element element;
for (i = 0; i < g_wtp.radios->count; i++) {
radio = (struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i);
/* Set message element */
if (radio->status == WTP_RADIO_ENABLED) {
memcpy(&element, &radio->radioinformation, sizeof(struct capwap_80211_wtpradioinformation_element));
} else {
memset(&element, 0, sizeof(struct capwap_80211_wtpradioinformation_element));
element.radioid = radio->radioid;
}
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, &element);
}
}
#include "wtp.h"
#include "wtp_radio.h"
/* */
void wtp_create_radioopsstate_element(struct capwap_packet_txmng* txmngpacket) {
int i;
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);
struct capwap_radiooprstate_element radiooprstate;
radiooprstate.radioid = radio->radioid;
radiooprstate.state = ((radio->status == WTP_RADIO_ENABLED) ? CAPWAP_RADIO_OPERATIONAL_STATE_ENABLED : CAPWAP_RADIO_OPERATIONAL_STATE_DISABLED);
if (radio->status == WTP_RADIO_ENABLED) {
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_NORMAL;
} else if (radio->status == WTP_RADIO_DISABLED) {
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_ADMINSET;
} else if (radio->status == WTP_RADIO_HWFAILURE) {
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_RADIOFAILURE;
} else if (radio->status == WTP_RADIO_SWFAILURE) {
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_SOFTWAREFAILURE;
} else {
/* Unknown value */
ASSERT(0);
}
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RADIOOPRSTATE, &radiooprstate);
}
}
/* */
void wtp_create_radioadmstate_element(struct capwap_packet_txmng* txmngpacket) {
int i;
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);
struct capwap_radioadmstate_element radioadmstate;
radioadmstate.radioid = radio->radioid;
radioadmstate.state = ((radio->status == WTP_RADIO_DISABLED) ? CAPWAP_RADIO_ADMIN_STATE_DISABLED : CAPWAP_RADIO_ADMIN_STATE_ENABLED);
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RADIOADMSTATE, &radioadmstate);
}
}
/* */
void wtp_create_80211_wtpradioinformation_element(struct capwap_packet_txmng* txmngpacket) {
int i;
struct wtp_radio* radio;
struct capwap_80211_wtpradioinformation_element element;
for (i = 0; i < g_wtp.radios->count; i++) {
radio = (struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i);
/* Set message element */
if (radio->status == WTP_RADIO_ENABLED) {
memcpy(&element, &radio->radioinformation, sizeof(struct capwap_80211_wtpradioinformation_element));
} else {
memset(&element, 0, sizeof(struct capwap_80211_wtpradioinformation_element));
element.radioid = radio->radioid;
}
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, &element);
}
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More