From fb40c45300748a40ffea405dc01e7071945473c7 Mon Sep 17 00:00:00 2001 From: "7u83@mail.ru" <7u83@mail.ru@noemail.net> Date: Tue, 14 Apr 2015 05:48:52 +0000 Subject: [PATCH] Read WTP Desc. FossilOrigin-Name: 2a2806ef2d1fc790e2869d23e89b8bf8c26621559c0bd285851a9169e9df2ab9 --- src/capwap/cw_read_wtp_descriptor.c | 148 ++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 src/capwap/cw_read_wtp_descriptor.c diff --git a/src/capwap/cw_read_wtp_descriptor.c b/src/capwap/cw_read_wtp_descriptor.c new file mode 100644 index 00000000..d0c9962c --- /dev/null +++ b/src/capwap/cw_read_wtp_descriptor.c @@ -0,0 +1,148 @@ +/* + This file is part of libcapwap. + + libcapwap is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + libcapwap is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . + +*/ + + +#include "capwap.h" +#include "capwap_items.h" + +#include "wtpinfo.h" + +#include "cw_util.h" +#include "dbg.h" + + + + +static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, + uint8_t * data, int len, int cq) +{ + + if (len < 6) { + return 0; + } + + cw_itemstore_t itemstore = conn->incomming; + + cw_itemstore_set_byte(itemstore, CW_ITEM_WTP_MAX_RADIOS, cw_get_byte(data)); + cw_itemstore_set_byte(itemstore, CW_ITEM_WTP_RADIOS_IN_USE, + cw_get_byte(data + 1)); + + int ncrypt = cw_get_byte(data + 2); + int i; + if (ncrypt == 0) { + /* non-conform */ + cw_dbg(DBG_RFC, + "Non-standard-conform WTP descriptor detected (See RFC 5415)"); + if (!cq) + i = 3; + else + i = 4; + } else { + i = ncrypt * 3 + 3; + } + + do { + if (i + 8 > len) { + cw_dbg(DBG_ELEM_ERR, + "WTP descriptor subelement to long, length=%d>%d", i + 8, + len); + return 0; + } + + uint32_t vendor_id = cw_get_dword(data + i); //ntohl(*((uint32_t*)(msgelem+i))); + + uint32_t val = cw_get_dword(data + i + 4); + int subtype = (val >> 16) & 0xffff; + int sublen = val & 0xffff; + i += 8; + + if (sublen + i > len) { + cw_dbg(DBG_ELEM_ERR, + "WTP Descriptor subelement too long, length = %d", sublen); + return 0; + } + + cw_dbg(DBG_SUBELEM, "WTP Descriptor subtype=%d,len=%d", subtype, sublen); + + switch (subtype) { + case CW_SUBELEM_WTP_HARDWARE_VERSION: + cw_itemstore_set_dword(itemstore, + CW_ITEM_WTP_HARDWARE_VENDOR, + vendor_id); + cw_itemstore_set_bstrn(itemstore, + CW_ITEM_WTP_HARDWARE_VERSION, + data + i, sublen); + break; + case CW_SUBELEM_WTP_SOFTWARE_VERSION: + cw_itemstore_set_dword(itemstore, + CW_ITEM_WTP_SOFTWARE_VENDOR, + vendor_id); + cw_itemstore_set_bstrn(itemstore, + CW_ITEM_WTP_SOFTWARE_VERSION, + data + i, sublen); + break; + case CW_SUBELEM_WTP_BOOTLOADER_VERSION: + cw_itemstore_set_dword(itemstore, + CW_ITEM_WTP_BOOTLOADER_VENDOR, + vendor_id); + cw_itemstore_set_bstrn(itemstore, + CW_ITEM_WTP_BOOTLOADER_VERSION, + data + i, sublen); + break; + default: + cw_dbg(DBG_ELEM_ERR, + "Unknown WTP descriptor subelement, type = %d", + subtype); + break; + } + i += sublen; + + } while (i < len); + + return 1; +} + +int cw_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * data, + int len) +{ + switch (conn->capwap_mode) { + case CW_MODE_STD: + { + int rc = + readelem_wtp_descriptor(conn, a, data, len, + CW_MODE_STD); + if (!rc) { + cw_dbg(DBG_ELEM_ERR, "Bad WTP descriptor from %s", + sock_addr2str(&conn->addr)); + return 0; + } + return 1; + } + + + + } + + int rc = readelem_wtp_descriptor(conn, a, data, len, 0); + if (rc == -1) { + cw_dbg(DBG_RFC, "Bad WTP descriptor, trying cisco hack"); + rc = readelem_wtp_descriptor(conn, a, data, len, 1); + } + + return rc; +}