wtp can send an empty discovery request
FossilOrigin-Name: 440ee8b077901e593d994ef900088b648204f1c8637b35189a5cddd18ec8f08f
This commit is contained in:
parent
835dc82e6f
commit
8b2e36e912
@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CodeLite_Workspace Name="actube" Database="">
|
||||
<Project Name="ac" Path="ac.project" Active="No"/>
|
||||
<Project Name="wtp" Path="wtp.project" Active="No"/>
|
||||
<Project Name="wtp" Path="wtp.project" Active="Yes"/>
|
||||
<Project Name="mod_cipwap" Path="mod_cipwap.project" Active="No"/>
|
||||
<Project Name="mod_capwap" Path="mod_capwap.project" Active="No"/>
|
||||
<Project Name="mod_cisco" Path="mod_cisco.project" Active="No"/>
|
||||
<Project Name="libcw" Path="libcw.project" Active="Yes"/>
|
||||
<Project Name="libcw" Path="libcw.project" Active="No"/>
|
||||
<Project Name="mod_capwap80211" Path="mod_capwap80211.project" Active="No"/>
|
||||
<Project Name="mod_fortinet" Path="mod_fortinet.project" Active="No"/>
|
||||
<BuildMatrix>
|
||||
|
@ -325,6 +325,8 @@
|
||||
<File Name="src/cw/cw_ktv_read_file.c"/>
|
||||
<File Name="src/cw/cw_ktv_mavlcmp_type_by_name.c"/>
|
||||
<File Name="src/cw/msgset.h"/>
|
||||
<File Name="src/cw/mlist_get.c"/>
|
||||
<File Name="src/cw/mlist_replace.c"/>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
<Description/>
|
||||
|
@ -221,7 +221,7 @@ cw_action_out_t *cw_actionlist_out_add(cw_actionlist_out_t t, struct cw_action_o
|
||||
mavl_add(t,o,NULL);
|
||||
}
|
||||
|
||||
struct mlistelem * e = mlist_replace(o->mlist,NULL,a);
|
||||
struct mlistelem * e = mlist_replace(o->mlist,a);
|
||||
if (!e)
|
||||
e = mlist_append(o->mlist,a);
|
||||
|
||||
|
@ -669,7 +669,9 @@ extern int cw_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8
|
||||
//extern int cw_out_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len);
|
||||
*/
|
||||
|
||||
/*
|
||||
extern int cw_out_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst);
|
||||
*/
|
||||
|
||||
/*
|
||||
//extern int cw_out_ac_descriptor(struct conn *conn, uint32_t elem_id, uint8_t * dst,
|
||||
|
@ -73,6 +73,8 @@ struct conn {
|
||||
|
||||
|
||||
mavl_t remote_cfg;
|
||||
mavl_t local_cfg;
|
||||
|
||||
|
||||
|
||||
mbag_t outgoing;
|
||||
|
@ -308,6 +308,7 @@ struct cw_DescriptorSubelemDef {
|
||||
#define CW_APPEND 2
|
||||
#define CW_PREPEND 3
|
||||
#define CW_REPLACE 4
|
||||
#define CW_IGNORE 5
|
||||
|
||||
|
||||
int cw_check_missing_mand(struct cw_MsgData *msgdata, mavl_t keys );
|
||||
@ -359,7 +360,8 @@ int cw_in_generic(struct conn * conn, struct cw_ElemHandler * handler,
|
||||
int cw_in_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
|
||||
uint8_t * elem_data, int elem_len);
|
||||
|
||||
|
||||
int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
|
||||
, uint8_t * dst);
|
||||
|
||||
extern int cw_in_wtp_reboot_statistics(struct conn *conn, struct cw_action_in *a,
|
||||
uint8_t * data, int len, struct sockaddr *from);
|
||||
|
@ -4,31 +4,28 @@
|
||||
|
||||
#include "dbg.h"
|
||||
#include "log.h"
|
||||
#include "msgset.h"
|
||||
#include "ktv.h"
|
||||
|
||||
|
||||
int cw_out_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst)
|
||||
int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
|
||||
, uint8_t * dst)
|
||||
{
|
||||
|
||||
|
||||
/* Get the item to put */
|
||||
struct mbag_item *item = NULL;
|
||||
if (a->get) {
|
||||
item = a->get(conn, a);
|
||||
}
|
||||
|
||||
struct cw_KTV * elem;
|
||||
int start, len;
|
||||
/* Get the element to put */
|
||||
elem = mavl_get(params->conn->local_cfg, handler->key);
|
||||
|
||||
/* Size for msg elem header depends on
|
||||
vendor specific payload */
|
||||
int start = a->vendor_id ? 10 : 4;
|
||||
start = handler->vendor ? 10 : 4;
|
||||
|
||||
|
||||
int len;
|
||||
if (!item) {
|
||||
if (elem == NULL) {
|
||||
const char *vendor="";
|
||||
if ( a->vendor_id ) {
|
||||
vendor=cw_strvendor(a->vendor_id);
|
||||
if ( handler->vendor ) {
|
||||
vendor=cw_strvendor(handler->vendor);
|
||||
}
|
||||
if (a->mand) {
|
||||
if ( 0) {
|
||||
/* cw_log(LOG_ERR,
|
||||
"Can't put mandatory element %s %d - (%s) into %s. No value for '%s' found.",
|
||||
vendor,
|
||||
@ -45,15 +42,15 @@ int cw_out_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst)
|
||||
*/
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
len = cw_put_mbag_item(dst + start, item);
|
||||
}
|
||||
}
|
||||
len = handler->type->put(elem,dst+start);
|
||||
|
||||
/*(cw_put_mbag_item(dst + start, item);*/
|
||||
|
||||
if (a->vendor_id)
|
||||
return len + cw_put_elem_vendor_hdr(dst, a->vendor_id, a->elem_id, len);
|
||||
if (handler->vendor)
|
||||
return len + cw_put_elem_vendor_hdr(dst, handler->vendor, handler->id, len);
|
||||
|
||||
return len + cw_put_elem_hdr(dst, a->elem_id, len);
|
||||
return len + cw_put_elem_hdr(dst, handler->id, len);
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#include "log.h"
|
||||
#include "dbg.h"
|
||||
|
||||
#include "msgset.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -39,10 +39,56 @@
|
||||
int cw_put_msg(struct conn *conn, uint8_t * rawout)
|
||||
{
|
||||
|
||||
uint8_t *msgptr,*dst;
|
||||
int type;
|
||||
struct cw_MsgData * msg;
|
||||
struct mlistelem * elem;
|
||||
int len,l;
|
||||
|
||||
/* rawout is already initialized, so we can get
|
||||
msg type from buffer */
|
||||
uint8_t *msgptr = rawout + cw_get_hdr_msg_offset(rawout);
|
||||
* msg type from buffer */
|
||||
msgptr = rawout + cw_get_hdr_msg_offset(rawout);
|
||||
type = cw_get_msg_type(msgptr);
|
||||
|
||||
printf("Looking in %p for %d\n", conn->msgset,type);
|
||||
msg = cw_msgset_get_msgdata(conn->msgset,type);
|
||||
if (msg == NULL){
|
||||
cw_log(LOG_ERR,"Error: Can't create message of type %d (%s) - no definition found.",
|
||||
type, cw_strmsg(type));
|
||||
}
|
||||
|
||||
dst = msgptr+8;
|
||||
len =0;
|
||||
mlist_foreach(elem,msg->elements_list){
|
||||
struct cw_ElemData * data;
|
||||
struct cw_ElemHandler * handler;
|
||||
struct cw_ElemHandlerParams params;
|
||||
|
||||
data = mlistelem_dataptr(elem);
|
||||
handler = cw_msgset_get_elemhandler(conn->msgset,data->proto,data->vendor,data->id);
|
||||
printf("Elem: %d %d %d %s\n", data->proto, data->vendor, data->id, handler->name);
|
||||
if (handler->put == NULL){
|
||||
continue;
|
||||
}
|
||||
|
||||
params.conn=conn;
|
||||
params.elemdata = data;
|
||||
l = handler->put(handler,¶ms,dst+len);
|
||||
len += l;
|
||||
}
|
||||
|
||||
cw_set_msg_elems_len(msgptr, len);
|
||||
|
||||
if (type & 1) {
|
||||
/* It's a request, so we have to set seqnum */
|
||||
int s = conn_get_next_seqnum(conn);
|
||||
cw_set_msg_seqnum(msgptr,s);
|
||||
}
|
||||
|
||||
return len;
|
||||
|
||||
|
||||
printf("Message to send: %s\n",msg->name);
|
||||
|
||||
|
||||
/* create search paramaters */
|
||||
@ -52,9 +98,11 @@ int cw_put_msg(struct conn *conn, uint8_t * rawout)
|
||||
as.item_id = CW_ITEM_NONE;
|
||||
as.vendor_id = 0;
|
||||
|
||||
uint8_t *dst = msgptr+8;
|
||||
dst = msgptr+8;
|
||||
|
||||
printf("Put Message\n");
|
||||
exit(0);
|
||||
|
||||
/// TODO XXXX
|
||||
//mlist_t m = cw_actionlist_out_get(conn->actions->out,cw_get_msg_type(msgptr));
|
||||
mlist_t m =0;
|
||||
|
||||
@ -70,9 +118,10 @@ int cw_put_msg(struct conn *conn, uint8_t * rawout)
|
||||
|
||||
struct mlistelem *e;
|
||||
|
||||
int len = 0;
|
||||
len = 0;
|
||||
|
||||
for (e=m->first; e; e=e->next) {
|
||||
int l;
|
||||
cw_action_out_t *ae=(cw_action_out_t*)e;
|
||||
|
||||
//printf("Put %d %i %s\n",ae->msg_id,ae->elem_id,ae->item_id);
|
||||
@ -84,7 +133,7 @@ int cw_put_msg(struct conn *conn, uint8_t * rawout)
|
||||
/* Element is from next msg, close action */
|
||||
break;
|
||||
}
|
||||
int l=0;
|
||||
l=0;
|
||||
if (ae->out) {
|
||||
|
||||
// printf("Out Call with len =%d\n",len);
|
||||
|
@ -122,7 +122,7 @@ struct mavl *mavl_create ( int ( *cmp ) ( const void *, const void * ),
|
||||
|
||||
void *mavl_add ( struct mavl *t, const void *data, int *exists );
|
||||
/*void *mavl_add ( struct mavl *t, const void *data );*/
|
||||
void * mavl_get ( struct mavl *t , void *data );
|
||||
void * mavl_get ( struct mavl *t , const void *data );
|
||||
void *mavl_del ( struct mavl *t, const void *data );
|
||||
void *mavl_replace ( struct mavl *t, const void *data, int * result );
|
||||
void mavl_destroy ( struct mavl *t );
|
||||
|
@ -29,7 +29,7 @@
|
||||
* @param data Element to get
|
||||
* @return pointer to element or NULL if not found.
|
||||
*/
|
||||
void * mavl_get(struct mavl *t ,void *data)
|
||||
void * mavl_get(struct mavl *t ,const void *data)
|
||||
{
|
||||
struct mavlnode *n = t->root;
|
||||
while(n){
|
||||
|
@ -32,7 +32,7 @@ struct mlistelem *mlist_find(mlist_t l, struct mlistelem *start, void *data)
|
||||
}
|
||||
|
||||
|
||||
struct mlistelem * mlist_replace(mlist_t l, struct mlistelem *start, void *data)
|
||||
struct mlistelem * xmlist_replace(mlist_t l, struct mlistelem *start, void *data)
|
||||
{
|
||||
/*
|
||||
struct mlistelem *e;
|
||||
|
@ -64,10 +64,13 @@ typedef struct mlist * mlist_t;
|
||||
mlist_t mlist_create(int (*cmp) (const void *v1, const void *v2), void (*del)(void *), size_t data_size);
|
||||
|
||||
struct mlistelem *mlist_append(mlist_t l, void *data);
|
||||
struct mlistelem * mlist_get(mlist_t list, const void *data);
|
||||
void mlist_destroy(mlist_t l);
|
||||
struct mlistelem *mlist_replace(mlist_t l, void *data);
|
||||
|
||||
|
||||
extern struct mlistelem *mlist_find(mlist_t l, struct mlistelem *start, void *data);
|
||||
extern struct mlistelem *mlist_replace(mlist_t l, struct mlistelem *start, void *data);
|
||||
|
||||
|
||||
|
||||
|
||||
|
12
src/cw/mlist_get.c
Normal file
12
src/cw/mlist_get.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include "mlist.h"
|
||||
|
||||
struct mlistelem * mlist_get(mlist_t list, const void *data){
|
||||
struct mlistelem * elem;
|
||||
mlist_foreach(elem,list){
|
||||
void *tdata = mlistelem_dataptr(elem);
|
||||
if (list->cmp(tdata,data)==0){
|
||||
return tdata;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
14
src/cw/mlist_replace.c
Normal file
14
src/cw/mlist_replace.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include "mlist.h"
|
||||
|
||||
struct mlistelem * mlist_replace(mlist_t list, void *data)
|
||||
{
|
||||
struct mlistelem *e;
|
||||
|
||||
e = mlist_get(list,data);
|
||||
if (e == NULL)
|
||||
return NULL;
|
||||
|
||||
memcpy(mlistelem_dataptr(e), data,list->data_size);
|
||||
return e;
|
||||
|
||||
}
|
@ -62,9 +62,9 @@ static void msgdata_destroy(struct cw_MsgData *data)
|
||||
{
|
||||
if (!data)
|
||||
return;
|
||||
/* if (data->elements_list)
|
||||
if (data->elements_list)
|
||||
mlist_destroy(data->elements_list);
|
||||
*/
|
||||
|
||||
if (data->elements_tree)
|
||||
mavl_destroy(data->elements_tree);
|
||||
free(data);
|
||||
@ -92,7 +92,6 @@ void cw_msgset_destroy(struct cw_MsgSet *set)
|
||||
free(set);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a message set
|
||||
* @return Message set create, NULL if an error has occured
|
||||
@ -186,6 +185,7 @@ static int update_msgdata(struct cw_MsgSet *set, struct cw_MsgData *msgdata,
|
||||
ed.vendor = elemdef->vendor;
|
||||
ed.mand = elemdef->mand;
|
||||
|
||||
/* add message element to the elements tree */
|
||||
result = mavl_replace(msgdata->elements_tree, &ed, &replaced);
|
||||
|
||||
if (!replaced) {
|
||||
@ -197,8 +197,45 @@ static int update_msgdata(struct cw_MsgSet *set, struct cw_MsgData *msgdata,
|
||||
elemdef->proto,
|
||||
elemdef->vendor, elemdef->id, handler->name);
|
||||
}
|
||||
|
||||
{
|
||||
struct mlistelem *elem;
|
||||
elem = mlist_get(msgdata->elements_list,&ed);
|
||||
if (elem==NULL){
|
||||
printf("Elem is not in mlist\n");
|
||||
}
|
||||
else{
|
||||
printf("Elem was in mlsit\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* add message elemeent to the elements list */
|
||||
switch ( elemdef->op & 0xff){
|
||||
case CW_IGNORE:
|
||||
break;
|
||||
case CW_DELETE:
|
||||
break;
|
||||
case CW_APPEND:
|
||||
mlist_append(msgdata->elements_list, &ed);
|
||||
break;
|
||||
default:
|
||||
case CW_REPLACE:
|
||||
if (mlist_replace(msgdata->elements_list, &ed)==NULL){
|
||||
mlist_append(msgdata->elements_list, &ed);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (msgdata->mand_keys!=NULL){
|
||||
mlist_destroy(msgdata->mand_keys);
|
||||
}
|
||||
@ -258,6 +295,8 @@ int cw_msgset_add(struct cw_MsgSet *set,
|
||||
msg->elements_tree = mavl_create(cmp_elemdata, NULL,
|
||||
sizeof(struct cw_ElemData));
|
||||
msg->mand_keys=NULL;
|
||||
|
||||
msg->elements_list = mlist_create(cmp_elemdata,NULL,sizeof(struct cw_ElemData));
|
||||
}
|
||||
|
||||
/* Overwrite the found message */
|
||||
@ -299,5 +338,5 @@ struct cw_MsgData *cw_msgset_get_msgdata(struct cw_MsgSet *set, int type)
|
||||
{
|
||||
struct cw_MsgData search;
|
||||
search.type = type;
|
||||
return mavl_find_ptr(set->msgdata, &search);
|
||||
return mavl_find(set->msgdata, &search);
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ struct cw_ElemData{
|
||||
struct cw_ElemHandlerParams {
|
||||
struct conn * conn;
|
||||
struct cw_MsgData * msgdata;
|
||||
struct cw_ElemData * elemdata;
|
||||
struct sockaddr *from;
|
||||
mavl_t mand_found;
|
||||
};
|
||||
@ -47,6 +48,9 @@ struct cw_ElemHandler {
|
||||
const char * key;
|
||||
int (*get)(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
|
||||
uint8_t*data, int len);
|
||||
|
||||
int (*put)(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, uint8_t * dst);
|
||||
|
||||
/*
|
||||
int (*end_in)(struct conn *conn,struct cw_action_in *a,uint8_t*elem,int len,struct sockaddr *from);
|
||||
*/
|
||||
@ -83,7 +87,8 @@ extern struct cw_MsgSet * cw_msgset_create();
|
||||
extern void cw_msgset_destroy(struct cw_MsgSet * set);
|
||||
extern int cw_msgset_add(struct cw_MsgSet * set,
|
||||
struct cw_MsgDef messages[], struct cw_ElemHandler handlers[]);
|
||||
mlist_t cw_msgset_get_msg(struct cw_MsgSet * set, int type);
|
||||
/*mlist_t cw_msgset_get_msg(struct cw_MsgSet * set, int type);*/
|
||||
|
||||
struct cw_MsgData * cw_msgset_get_msgdata(struct cw_MsgSet *set,int type);
|
||||
struct cw_ElemHandler * cw_msgset_get_elemhandler(struct cw_MsgSet * set,
|
||||
int proto, int vendor, int id);
|
||||
|
@ -34,7 +34,8 @@ static struct cw_ElemHandler handlers[] = {
|
||||
1,1, /* min/max length */
|
||||
CW_TYPE_BYTE, /* type */
|
||||
"discovery_type", /* Key */
|
||||
cw_in_generic /* get */
|
||||
cw_in_generic, /* get */
|
||||
cw_out_generic /* put */
|
||||
}
|
||||
,
|
||||
{
|
||||
@ -44,7 +45,8 @@ static struct cw_ElemHandler handlers[] = {
|
||||
1,1, /* min/max length */
|
||||
CW_TYPE_BYTE, /* type */
|
||||
"wtp_mac_type", /* Key */
|
||||
cw_in_generic /* get */
|
||||
cw_in_generic, /* get */
|
||||
cw_out_generic /* put */
|
||||
}
|
||||
,
|
||||
{
|
||||
@ -54,7 +56,8 @@ static struct cw_ElemHandler handlers[] = {
|
||||
4,128, /* min/max length */
|
||||
NULL, /* type */
|
||||
"wtp_board_data", /* Key */
|
||||
capwap_in_wtp_board_data /* get */
|
||||
capwap_in_wtp_board_data, /* get */
|
||||
NULL /* put */
|
||||
}
|
||||
,
|
||||
{
|
||||
@ -64,7 +67,8 @@ static struct cw_ElemHandler handlers[] = {
|
||||
4,128, /* min/max length */
|
||||
NULL, /* type */
|
||||
"wtp_descriptor", /* Key */
|
||||
capwap_in_wtp_descriptor /* get */
|
||||
capwap_in_wtp_descriptor, /* get */
|
||||
NULL /* put */
|
||||
}
|
||||
,
|
||||
{
|
||||
@ -74,7 +78,8 @@ static struct cw_ElemHandler handlers[] = {
|
||||
1,1, /* min/max length */
|
||||
CW_TYPE_BYTE, /* type */
|
||||
"wtp_frame_tunnel_mode", /* Key */
|
||||
cw_in_generic /* get */
|
||||
cw_in_generic, /* get */
|
||||
cw_out_generic /* put */
|
||||
}
|
||||
,
|
||||
|
||||
@ -85,7 +90,8 @@ static struct cw_ElemHandler handlers[] = {
|
||||
0,0, /* min/max length */
|
||||
NULL, /* type */
|
||||
"vendor_specific_payload", /* Key */
|
||||
capwap_in_vendor_specific_payload /* get */
|
||||
capwap_in_vendor_specific_payload, /* get */
|
||||
NULL /* put */
|
||||
}
|
||||
,
|
||||
|
||||
@ -96,7 +102,8 @@ static struct cw_ElemHandler handlers[] = {
|
||||
0,0, /* min/max length */
|
||||
NULL, /* type */
|
||||
"mtu_discovery_padding", /* Key */
|
||||
capwap_in_mtu_discovery_padding /* get */
|
||||
capwap_in_mtu_discovery_padding, /* get */
|
||||
NULL /* put */
|
||||
}
|
||||
,
|
||||
|
||||
@ -114,7 +121,7 @@ static struct cw_ElemDef discovery_request_elements[] ={
|
||||
{0,0,CAPWAP_ELEM_WTP_FRAME_TUNNEL_MODE, 1, 0},
|
||||
{0,0,CAPWAP_ELEM_WTP_MAC_TYPE, 1, 0},
|
||||
{0,0,CAPWAP_ELEM_MTU_DISCOVERY_PADDING, 0, 0},
|
||||
{0,0,CAPWAP_ELEM_VENDOR_SPECIFIC_PAYLOAD, 0, 0},
|
||||
{0,0,CAPWAP_ELEM_VENDOR_SPECIFIC_PAYLOAD, 0, CW_IGNORE},
|
||||
{0,0,0,0,0}
|
||||
|
||||
};
|
||||
|
@ -31,7 +31,7 @@ endif
|
||||
|
||||
|
||||
#SRC=$(wildcard *.c)
|
||||
SRC=wtp_main.c
|
||||
SRC=wtp_main.c discovery.c
|
||||
|
||||
OBJS=$(patsubst %.c,%.o,$(SRC))
|
||||
OBJS:=$(patsubst %.o,$(OBJDIR)/%.o,$(OBJS))
|
||||
|
@ -1,145 +1,43 @@
|
||||
/*
|
||||
This file is part of AC-Tube.
|
||||
|
||||
AC-Tube 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.
|
||||
|
||||
AC-Tube 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 <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
#include "cw/capwap.h"
|
||||
#include "cw/capwap_items.h"
|
||||
#include "cw/log.h"
|
||||
#include "cw/conn.h"
|
||||
#include "cw/sock.h"
|
||||
#include "cw/cw_util.h"
|
||||
#include "cw/aciplist.h"
|
||||
#include "cw/acpriolist.h"
|
||||
#include "cw/ktv.h"
|
||||
#include "cw/log.h"
|
||||
#include "cw/dbg.h"
|
||||
#include "cw/timer.h"
|
||||
|
||||
|
||||
#include "wtp.h"
|
||||
#include "wtp_conf.h"
|
||||
#include "wtp_interface.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
cw_aciplist_t cw_select_ac(struct conn *conn, mbag_t discs)
|
||||
{
|
||||
|
||||
/* create a list for results */
|
||||
cw_aciplist_t resultlist=cw_aciplist_create();
|
||||
if (!resultlist)
|
||||
return NULL;
|
||||
if (!discs)
|
||||
return resultlist;
|
||||
|
||||
/*
|
||||
cw_aciplist_t aciplist = cw_aciplist_create();
|
||||
if (!aciplist) {
|
||||
cw_log(LOG_ERROR, "Can't allocate aciplist");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/* get the AC Name with Priority list */
|
||||
cw_acpriolist_t priolist;
|
||||
priolist = mbag_get_mavl(conn->config, CW_ITEM_AC_NAME_WITH_PRIORITY);
|
||||
if (!priolist )
|
||||
priolist=cw_acpriolist_create();
|
||||
|
||||
|
||||
/* for each discovery reponse */
|
||||
DEFINE_AVLITER(i, discs);
|
||||
avliter_foreach(&i){
|
||||
|
||||
mbag_t ac = ((mbag_item_t *) (avliter_get(&i)))->data;
|
||||
|
||||
/* get the ac name */
|
||||
char *ac_name = mbag_get_str(ac, CW_ITEM_AC_NAME,NULL);
|
||||
int prio = 256;
|
||||
|
||||
if (ac_name) {
|
||||
/* See if we can find AC Name in Priority List */
|
||||
if (priolist)
|
||||
prio = cw_acpriolist_get(priolist, ac_name);
|
||||
}
|
||||
|
||||
/* get the IP list, the current AC has sent */
|
||||
cw_aciplist_t acips =
|
||||
mbag_get_mavl(ac, CW_ITEM_CAPWAP_CONTROL_IP_ADDRESS_LIST);
|
||||
|
||||
if (!acips)
|
||||
continue;
|
||||
|
||||
/* for each IP from the current AC add it to the result list
|
||||
* and give it the priority whe have determined */
|
||||
DEFINE_AVLITER(i2, acips);
|
||||
avliter_foreach(&i2){
|
||||
|
||||
|
||||
cw_acip_t *acip = avliter_get(&i2);
|
||||
|
||||
cw_acip_t *n = malloc(sizeof(cw_acip_t));
|
||||
memcpy(n,acip,sizeof(cw_acip_t));
|
||||
|
||||
/* we missuse the wtp_count to sort by
|
||||
* priority and wp_count */
|
||||
n->index |= prio<<16;
|
||||
|
||||
cw_aciplist_del(resultlist,n);
|
||||
cw_aciplist_add(resultlist,n);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return resultlist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int run_discovery(struct conn *conn)
|
||||
{
|
||||
// conn->incomming = mbag_create();
|
||||
|
||||
/*// conn->incomming = mbag_create();*/
|
||||
time_t timer;
|
||||
|
||||
conn->capwap_state = CAPWAP_STATE_DISCOVERY;
|
||||
mbag_set_byte(conn->outgoing, CW_ITEM_DISCOVERY_TYPE,
|
||||
|
||||
/* mbag_set_byte(conn->outgoing, CW_ITEM_DISCOVERY_TYPE,
|
||||
CAPWAP_DISCOVERY_TYPE_UNKNOWN);
|
||||
|
||||
*/
|
||||
|
||||
cw_init_request(conn, CAPWAP_MSG_DISCOVERY_REQUEST);
|
||||
cw_put_msg(conn, conn->req_buffer);
|
||||
conn_send_msg(conn, conn->req_buffer);
|
||||
|
||||
|
||||
time_t timer = cw_timer_start(0);
|
||||
|
||||
timer = cw_timer_start(0);
|
||||
|
||||
while (!cw_timer_timeout(timer)
|
||||
&& conn->capwap_state == CAPWAP_STATE_DISCOVERY) {
|
||||
int rc;
|
||||
mavl_del_all(conn->incomming);
|
||||
|
||||
int rc = cw_read_from(conn);
|
||||
rc = cw_read_from(conn);
|
||||
|
||||
if (rc<0) {
|
||||
if (errno==EAGAIN)
|
||||
@ -150,7 +48,7 @@ static int run_discovery(struct conn *conn)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
mbag_t discs;
|
||||
discs = mbag_get_mavl(conn->remote, CW_ITEM_DISCOVERIES);
|
||||
|
||||
@ -177,30 +75,66 @@ static int run_discovery(struct conn *conn)
|
||||
mavl_del_all(conn->remote);
|
||||
|
||||
mbag_set_mavl(conn->local,CW_ITEM_CAPWAP_CONTROL_IP_ADDRESS_LIST,list);
|
||||
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Run discovery for on address (eg broadcast 255.255.255.255)
|
||||
*/
|
||||
static int cw_run_discovery(struct conn *conn, const char *acaddr)
|
||||
int cw_run_discovery(struct conn *conn, const char *addr, const char *bindaddr)
|
||||
{
|
||||
|
||||
char sock_buf[SOCK_ADDR_BUFSIZE];
|
||||
struct sockaddr_storage dstaddr;
|
||||
char caddr[256], control_port[64];
|
||||
|
||||
int rc;
|
||||
|
||||
/* get addr of destination */
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res, *res0;
|
||||
|
||||
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
|
||||
int rc = getaddrinfo(acaddr, conf_control_port, &hints, &res0);
|
||||
|
||||
|
||||
strncpy(caddr, addr, sizeof(caddr));
|
||||
|
||||
/* try to convert the given address string to sockaddr */
|
||||
rc = sock_strtoaddr(caddr,(struct sockaddr*)&dstaddr);
|
||||
if (rc) {
|
||||
cw_log(LOG_ERR, "Can't connect to AC %s: %s", acaddr, gai_strerror(rc));
|
||||
int iport;
|
||||
/* converting to socaddr was successful */
|
||||
iport = sock_getport((struct sockaddr*)&dstaddr);
|
||||
if (iport != 0)
|
||||
sprintf(control_port, "%d", iport);
|
||||
else
|
||||
sprintf(control_port,"%d", CAPWAP_CONTROL_PORT);
|
||||
}
|
||||
else{
|
||||
char * port;
|
||||
/* converting went wrong, so the address string might
|
||||
* be a DNS entry. Look for a colon to find the port. */
|
||||
port = strchr(addr,':');
|
||||
if (port){
|
||||
strncpy(control_port,port+1,sizeof(control_port));
|
||||
caddr[port-addr]=0;
|
||||
}
|
||||
else{
|
||||
sprintf(control_port,"%d", CAPWAP_CONTROL_PORT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*printf("Addr: %s, Port: %s\n",caddr,control_port);*/
|
||||
|
||||
rc = getaddrinfo(caddr, control_port, &hints, &res0);
|
||||
if (rc) {
|
||||
cw_log(LOG_ERR, "Can't connect to AC %s: %s", caddr, gai_strerror(rc));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -210,7 +144,7 @@ static int cw_run_discovery(struct conn *conn, const char *acaddr)
|
||||
int opt;
|
||||
sockfd = socket(res->ai_family, SOCK_DGRAM, 0);
|
||||
if (sockfd == -1) {
|
||||
cw_log(LOG_ERR, "Can't create socket for %s: %s", acaddr,
|
||||
cw_log(LOG_ERR, "Can't create socket for %s: %s", caddr,
|
||||
strerror(errno));
|
||||
continue;
|
||||
}
|
||||
@ -225,20 +159,25 @@ static int cw_run_discovery(struct conn *conn, const char *acaddr)
|
||||
sock_copyaddr(&conn->addr, res->ai_addr);
|
||||
|
||||
|
||||
if (conf_ip){
|
||||
if (bindaddr){
|
||||
int brc;
|
||||
|
||||
struct sockaddr bind_address;
|
||||
sock_strtoaddr(conf_ip,&bind_address);
|
||||
int brc = bind(sockfd,&bind_address,sock_addrlen(&bind_address));
|
||||
sock_strtoaddr(bindaddr,&bind_address);
|
||||
brc = bind(sockfd,&bind_address,sock_addrlen(&bind_address));
|
||||
if (brc<0) {
|
||||
cw_log(LOG_ERR,"Can't bind to %s",sock_addr2str(&bind_address));
|
||||
cw_log(LOG_ERR,"Can't bind to %s",sock_addr2str(&bind_address,sock_buf));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
conn->sock = sockfd;
|
||||
conn->readfrom = conn_recvfrom_packet;
|
||||
|
||||
|
||||
cw_dbg(DBG_INFO,"Discovery to %s", sock_addr2str_p(&conn->addr,sock_buf));
|
||||
|
||||
run_discovery(conn);
|
||||
|
||||
conn->readfrom=NULL;
|
||||
@ -253,13 +192,4 @@ static int cw_run_discovery(struct conn *conn, const char *acaddr)
|
||||
}
|
||||
|
||||
|
||||
int discovery()
|
||||
{
|
||||
struct conn *conn = get_conn();
|
||||
|
||||
printf("Radios = %d\n",conn->radios->count);
|
||||
|
||||
cw_run_discovery(conn, "255.255.255.255");
|
||||
conn->capwap_state=CAPWAP_STATE_JOIN;
|
||||
return 1;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ extern int configure();
|
||||
extern int run();
|
||||
extern int changestate();
|
||||
|
||||
int cw_run_discovery(struct conn *conn, const char *acaddr, const char *bindaddr);
|
||||
|
||||
|
||||
struct conn * get_conn();
|
||||
|
@ -10,12 +10,16 @@
|
||||
#include "cw/log.h"
|
||||
#include "cw/msgset.h"
|
||||
|
||||
|
||||
#include "wtp.h"
|
||||
|
||||
struct bootcfg{
|
||||
const char * modname;
|
||||
const char * modpath;
|
||||
const char * cfgfilename;
|
||||
};
|
||||
|
||||
|
||||
static int parse_args (int argc, char *argv[], struct bootcfg * bootcfg)
|
||||
{
|
||||
int c;
|
||||
@ -63,11 +67,10 @@ static int parse_args (int argc, char *argv[], struct bootcfg * bootcfg)
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
mavl_t types;
|
||||
mavliter_t it;
|
||||
struct bootcfg bootcfg;
|
||||
struct cw_Mod * mod;
|
||||
struct cw_MsgSet * msgset;
|
||||
struct conn * conn;
|
||||
|
||||
parse_args(argc,argv, &bootcfg);
|
||||
|
||||
@ -82,29 +85,25 @@ int main (int argc, char **argv)
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Build a message set from our loaded modules */
|
||||
mod->register_messages(msgset, CW_MOD_MODE_CAPWAP);
|
||||
mod->register_messages(msgset, CW_MOD_MODE_BINDINGS);
|
||||
|
||||
|
||||
|
||||
types = cw_ktv_create_types_tree();
|
||||
if (types == NULL){
|
||||
perror("Error creating types tree");
|
||||
/* create a connection object */
|
||||
conn = conn_create_noq(-1, NULL);
|
||||
if (conn==NULL){
|
||||
cw_log(LOG_ERR, "Connot create conn: %s", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
conn->detected = 1;
|
||||
conn->dtls_verify_peer=0;
|
||||
conn->dtls_mtu = 12000;
|
||||
conn->msgset=msgset;
|
||||
conn->local_cfg = cw_ktv_create();
|
||||
|
||||
cw_run_discovery(conn, "255.255.255.255","192.168.0.14");
|
||||
|
||||
|
||||
mavl_add_ptr(types,CW_TYPE_BSTR16);
|
||||
mavl_add_ptr(types,CW_TYPE_DWORD);
|
||||
|
||||
mavliter_init(&it,types);
|
||||
mavliter_foreach(&it){
|
||||
struct cw_Type * t = mavliter_get_ptr(&it);
|
||||
printf("The Type is %s\n",t->name);
|
||||
}
|
||||
|
||||
return (EXIT_SUCCESS);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user