Inital commit.
FossilOrigin-Name: 9da7cbe914e6f056bfbaed633219d34df26d12d7991097d2ffac288d66a1b139
This commit is contained in:
parent
412c956673
commit
67f83ca65f
111
src/capwap/cw_in_wtp_descriptor.c
Normal file
111
src/capwap/cw_in_wtp_descriptor.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "capwap.h"
|
||||
#include "capwap_items.h"
|
||||
|
||||
#include "wtpinfo.h"
|
||||
|
||||
#include "cw_util.h"
|
||||
#include "cw_log.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 -1;
|
||||
|
||||
cw_itemstore_t itemstore = conn->itemstore;
|
||||
|
||||
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_CW_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 -1;
|
||||
}
|
||||
|
||||
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 -1;
|
||||
}
|
||||
|
||||
cw_dbg(DBG_ELEM,"Reading WTP descriptor subelement, type=%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)
|
||||
{
|
||||
int rc =readelem_wtp_descriptor(conn, a,data,len,0);
|
||||
if (rc==-1){
|
||||
cw_dbg(DBG_CW_RFC,"Bad WTP descriptor, trying cisco hack");
|
||||
rc =readelem_wtp_descriptor(conn, a,data,len,1);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
30
src/capwap/cw_msg_init.c
Normal file
30
src/capwap/cw_msg_init.c
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
#include "conn.h"
|
||||
#include "capwap.h"
|
||||
|
||||
|
||||
|
||||
void cw_init(struct conn * conn, uint8_t *buffer, int type, int seqnum, struct radioinfo * radioinfo)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cw_init_response(struct conn * conn, uint8_t *req)
|
||||
{
|
||||
uint8_t *buffer=conn->resp_buffer;
|
||||
int hbytes = cw_get_hdr_msg_offset(req);
|
||||
memcpy(buffer,req,hbytes);
|
||||
|
||||
uint8_t * msgptr = req+hbytes;
|
||||
uint8_t * dmsgptr = buffer+hbytes;
|
||||
|
||||
cw_set_msg_type(dmsgptr,cw_get_msg_type(msgptr)+1);
|
||||
cw_set_msg_seqnum(dmsgptr,cw_get_msg_seqnum(msgptr));
|
||||
cw_set_msg_flags(dmsgptr,0);
|
||||
|
||||
|
||||
}
|
68
src/capwap/cw_out_ac_descriptor.c
Normal file
68
src/capwap/cw_out_ac_descriptor.c
Normal file
@ -0,0 +1,68 @@
|
||||
#include "cw_log.h"
|
||||
#include "conn.h"
|
||||
|
||||
#include "itemstore.h"
|
||||
#include "capwap_items.h"
|
||||
#include "capwap.h"
|
||||
|
||||
|
||||
int cw_put_subelem_version(uint8_t *dst,uint16_t subelem_id, uint32_t vendor_id,bstr16_t data)
|
||||
{
|
||||
printf("Vendor putter %d\n",vendor_id);
|
||||
|
||||
uint8_t *d=dst;
|
||||
d += cw_put_dword(d,vendor_id);
|
||||
d += cw_put_dword(d, (subelem_id<<16) | bstr16_len(data));
|
||||
d += cw_put_data(d,bstr16_data(data),bstr16_len(data));
|
||||
return d-dst;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)
|
||||
{
|
||||
|
||||
uint8_t *d = dst+4;
|
||||
struct cw_item * i;
|
||||
i = cw_itemstore_get(conn->local,CW_ITEM_AC_STATUS);
|
||||
|
||||
if (!i) {
|
||||
cw_log(LOG_ERR,"Can't send AC Descriptor, no AC Status Item found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct cw_ac_status *s = (struct cw_ac_status*)(i->data);
|
||||
|
||||
d += cw_put_dword (d, (s->stations << 16) | (s->limit) );
|
||||
d += cw_put_dword (d, (s->active_wtps <<16) | (s->max_wtps) );
|
||||
d += cw_put_dword (d, (s->security<<24) | (s->rmac_field<<16) | (s->dtls_policy));
|
||||
|
||||
|
||||
|
||||
i = cw_itemstore_get(conn->local,CW_ITEM_AC_HARDWARE_VERSION);
|
||||
|
||||
if ( i ) {
|
||||
d += cw_put_subelem_version(d,CW_SUBELEM_AC_HARDWARE_VERSION,*((uint32_t*)(i->data)),i->data+4);
|
||||
}
|
||||
else {
|
||||
cw_dbg(DBG_ELEM_ERR, "Can't send hard version in AC descriptor, not set.");
|
||||
}
|
||||
|
||||
|
||||
i = cw_itemstore_get(conn->local,CW_ITEM_AC_SOFTWARE_VERSION);
|
||||
|
||||
if ( i ) {
|
||||
d += cw_put_subelem_version(d,CW_SUBELEM_AC_SOFTWARE_VERSION,*((uint32_t*)(i->data)),i->data+4);
|
||||
}
|
||||
else {
|
||||
cw_dbg(DBG_ELEM_ERR, "Can't send software version in AC descriptor, not set.");
|
||||
}
|
||||
|
||||
int len = d-dst-4;
|
||||
|
||||
return len + cw_put_elem_hdr(dst,CW_ELEM_AC_DESCRIPTOR,len);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
9
src/capwap/cw_out_ac_name.c
Normal file
9
src/capwap/cw_out_ac_name.c
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
#include "capwap.h"
|
||||
|
||||
int cw_out_ac_name(uint8_t * dst,cw_item *item)
|
||||
{
|
||||
uint8_t *data = item->data;
|
||||
int len = cw_put_data(dst+4,data,strlen(data));
|
||||
return len + cw_put_elem_hdr(str,CW_ELEM_AC_NAME,len);
|
||||
}
|
61
src/capwap/cw_out_capwap_control_ip_addrs.c
Normal file
61
src/capwap/cw_out_capwap_control_ip_addrs.c
Normal file
@ -0,0 +1,61 @@
|
||||
|
||||
#include "cw_log.h"
|
||||
|
||||
#include "capwap.h"
|
||||
#include "aciplist.h"
|
||||
#include "sock.h"
|
||||
|
||||
|
||||
static int put_ip(void *priv, void *data)
|
||||
{
|
||||
uint8_t ** dptr = (uint8_t **)priv;
|
||||
cw_acip_t *acip=(cw_acip_t*)data;
|
||||
|
||||
uint8_t * dst = *dptr;
|
||||
|
||||
uint8_t *d = dst+4;
|
||||
|
||||
d+=cw_put_sockaddr(d,&acip->ip);
|
||||
d+=cw_put_word(d,acip->wtp_count);
|
||||
|
||||
int fam = sock_addrfamily(&acip->ip);
|
||||
int elem_id=-1;
|
||||
switch (fam) {
|
||||
case AF_INET:
|
||||
elem_id = CW_ELEM_CAPWAP_CONTROL_IPV4_ADDRESS;
|
||||
break;
|
||||
case AF_INET6:
|
||||
elem_id = CW_ELEM_CAPWAP_CONTROL_IPV6_ADDRESS;
|
||||
break;
|
||||
default:
|
||||
cw_log(LOG_ERR,"Unknown adress family %d",fam);
|
||||
break;
|
||||
}
|
||||
|
||||
if (elem_id != -1 ) {
|
||||
d+=cw_put_elem_hdr(dst,elem_id,d-dst-4);
|
||||
*dptr = d-4;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int cw_out_capwap_control_ip_addrs(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)
|
||||
{
|
||||
if ( !item ) {
|
||||
cw_log(LOG_ERR, "Can't send CAPWAP Local IPv4/IPv6 Address, not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
cw_aciplist_t aciplist = (cw_aciplist_t) cw_item_get_data_ptr(item);
|
||||
|
||||
|
||||
uint8_t *d = dst;
|
||||
cw_aciplist_foreach(aciplist, put_ip, &d);
|
||||
|
||||
cw_item_release_data_ptr(item,aciplist);
|
||||
return d-dst;
|
||||
}
|
||||
|
35
src/capwap/cw_out_generic.c
Normal file
35
src/capwap/cw_out_generic.c
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
|
||||
#include "capwap.h"
|
||||
#include "capwap_items.h"
|
||||
|
||||
|
||||
int cw_put_item(uint8_t *dst,struct cw_item*item)
|
||||
{
|
||||
switch (item->type){
|
||||
case CW_ITEMTYPE_STR:
|
||||
printf("Outing str %s\n",item->data);
|
||||
return cw_put_data(dst,item->data,strlen( (char*)item->data));
|
||||
case CW_ITEMTYPE_BYTE:
|
||||
return cw_put_byte(dst,item->byte);
|
||||
case CW_ITEMTYPE_WORD:
|
||||
return cw_put_word(dst,item->word);
|
||||
case CW_ITEMTYPE_DWORD:
|
||||
return cw_put_word(dst,item->dword);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cw_out_generic(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)
|
||||
{
|
||||
int len;
|
||||
if ( !item )
|
||||
len=0;
|
||||
else
|
||||
len = cw_put_item(dst+4,item);
|
||||
return len + cw_put_elem_hdr(dst,elem_id,len);
|
||||
}
|
||||
|
||||
|
0
src/capwap/cw_strnelem.c
Normal file
0
src/capwap/cw_strnelem.c
Normal file
18
src/capwap/dbg.h
Normal file
18
src/capwap/dbg.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef __DBG_H
|
||||
#define __DBG_H
|
||||
|
||||
|
||||
|
||||
void cw_dbg_elem_(int msg, int msgelem, const uint8_t * msgbuf, int len);
|
||||
|
||||
|
||||
#ifdef WITH_CW_LOG_DEBUG
|
||||
|
||||
#define cw_dbg_elem(msgtype,msgelemtype,msgbuf,msglen) cw_dbg_elem_(msgtype,msgelemtype,msgbuf,msglen)
|
||||
|
||||
#else
|
||||
|
||||
#define cw_dbg_elem(...)
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user