Inital commit.

FossilOrigin-Name: 9da7cbe914e6f056bfbaed633219d34df26d12d7991097d2ffac288d66a1b139
This commit is contained in:
7u83@mail.ru 2015-04-05 00:10:37 +00:00
parent 412c956673
commit 67f83ca65f
8 changed files with 332 additions and 0 deletions

View 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
View 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);
}

View 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);
}

View 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);
}

View 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;
}

View 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
View File

18
src/capwap/dbg.h Normal file
View 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