More work on CAPWAP VM

FossilOrigin-Name: 9d9a86d2bafe31253a6f505e874f188792539485bb4462f4d778e6c53ac3000b
This commit is contained in:
7u83@mail.ru 2015-04-05 18:27:17 +00:00
parent ab8128a20f
commit 1158167262
33 changed files with 648 additions and 532 deletions

View File

@ -198,7 +198,7 @@ AP = RAD = WTP
| ResetBtnState |
+-+-+-+-+-+-+-+-+
Type: 128 for Cisco Rest Button State
Type: 128 for Cisco Reset Button State
Length: 1
ResetBtnState: 1 = Enabeled

View File

@ -98,7 +98,13 @@ int readelem_cisco_rad_name(struct conn *conn,struct cw_action * a,uint8_t *data
*/
/*
int avlprint(void *priv, void *data)
{
struct cw_str * d = (struct cw_str*) data;
printf("String: %d - %s\n",d->id,d->str);
}
*/
int main (int argc, const char * argv[])
{
@ -117,7 +123,19 @@ int main (int argc, const char * argv[])
cw_dbg_opt_detail=DBG_DETAIL_ASC_DMP;
cw_register_actions_capwap_ac(&capwap_actions);
cw_register_actions_cipwap_ac(&capwap_actions);
/*
struct avltree *avlt = capwap_actions.strelem;
avltree_foreach_asc(avlt,avlprint,0);
exit(0);
*/
ac_global_init();
/*

View File

@ -353,6 +353,7 @@ static struct cwrmsg * wtpman_wait_for_message(struct wtpman * wtpman, time_t ti
return cwrmsg;
}
int conn_msg_processor(struct conn *conn);
static void wtpman_run_discovery(void *arg)
@ -361,7 +362,6 @@ static void wtpman_run_discovery(void *arg)
struct wtpman * wtpman = (struct wtpman *)arg;
struct cwrmsg * cwrmsg;
void conn_msg_processor(struct conn *conn);
time_t timer = cw_timer_start(10);
@ -370,7 +370,6 @@ extern cw_actionlist_in_t the_tree;
wtpman->conn->capwap_state=CW_STATE_DISCOVERY;
wtpman->conn->actions = &capwap_actions;
wtpman->conn->itemstore = cw_itemstore_create();
wtpman->conn->local = ac_config;
wtpman->conn->remote = cw_itemstore_create();
@ -379,6 +378,12 @@ extern cw_actionlist_in_t the_tree;
conn_msg_processor(wtpman->conn);
}
struct cw_item * wn = cw_itemstore_get(wtpman->conn->remote,CW_ITEM_WTP_NAME);
if (wn ) {
printf("WTP Name: %s\n",wn->data);
}
wtpman_remove(wtpman);
return;
@ -594,16 +599,20 @@ wtpman->conn->capwap_state=CW_STATE_JOIN;
wtpman->conn->capwap_state=CW_STATE_JOIN;
wtpman->conn->actions = &capwap_actions;
wtpman->conn->itemstore = cw_itemstore_create();
// wtpman->conn->itemstore = cw_itemstore_create();
wtpman->conn->local = ac_config;
wtpman->conn->remote = cw_itemstore_create();
while ( !cw_timer_timeout(timer) && wtpman->conn->capwap_state==CW_STATE_JOIN){
conn_msg_processor(wtpman->conn);
int rc = conn_msg_processor(wtpman->conn);
if (rc <0 ) {
break;
}
}
printf("Breaked\n");
exit(0);

View File

@ -169,12 +169,15 @@ CAPWAPOBJS= \
capwap_strings_elem.o \
itemstore.o \
cw_in_vendor_specific_payload.o \
cw_in_wtp_name.o \
cw_in_wtp_board_data.o \
cw_out_generic.o \
cw_out_ac_descriptor.o \
cw_out_capwap_control_ip_addrs.o
cw_out_cisco_ac_descriptor.o \
cw_out_cisco_ap_timesync.o \
cw_out_capwap_control_ip_addrs.o \
strheap.o
#cw_in_wtp_name.o \
#cw_msgtostr.o \
#cw_msgelemtostr.o \
#cwmsg_addelem_ctrl_ip_addrs.o \
@ -265,6 +268,9 @@ CWACTION=action.o \
cw_in_generic.o \
cw_in_wtp_descriptor.o \
cipwap_actions_ac.o \
cipwap_strings_elem.o \
cw_put_msg.o \
capwap_action_helpers.o \

View File

@ -119,6 +119,10 @@ static int cw_action_out_cmp(const void *elem1,const void *elem2)
if (r!=0)
return r;
r = e1->vendor_id - e2->vendor_id;
if (r!=0)
return r;
return 0;
}
@ -163,3 +167,6 @@ cw_action_out_t * cw_actionlist_out_add(cw_actionlist_out_t t, struct cw_action_
}

View File

@ -25,6 +25,7 @@
#include "avltree.h"
#include "conn.h"
#include "itemstore.h"
#include "strheap.h"
/* Generic functions and structs */
@ -63,11 +64,12 @@ extern int cw_actionlist_in_register_actions(cw_actionlist_in_t t,cw_action_in_t
struct cw_action_out{
uint32_t msg_id;
uint32_t item_id;
uint32_t vendor_id;
uint16_t elem_id;
int (*out)(struct conn * conn, uint32_t elem_id, uint8_t * dst ,struct cw_item * item);
struct cw_item *(*get)(struct conn *conn,uint32_t item_id);
int (*out)(struct conn * conn, struct cw_action_out *a, uint8_t * dst);
struct cw_item *(*get)(struct conn *conn,struct cw_action_out *a);
};
typedef struct cw_action_out cw_action_out_t;
@ -84,6 +86,10 @@ extern int cw_actionlist_out_register_actions(cw_actionlist_out_t t,cw_action_ou
struct cw_actiondef{
cw_actionlist_in_t in;
cw_actionlist_out_t out;
cw_strheap_t strmsg;
cw_strheap_t strelem;
};

View File

@ -19,7 +19,7 @@
/**
* @file
* @brief Yet another AVL tree implementation
*/
*/
#include <stdlib.h>
#include <stdio.h>
@ -32,35 +32,36 @@
* @param cmp pointer compare function
* @param del pointer to delete function which is called when an element will be deletet
* @return pointer to an #avltree struct
*/
struct avltree * avltree_create(int (*cmp)(const void*,const void*),void(*del)(void*))
*/
struct avltree *avltree_create(int (*cmp) (const void *, const void *),
void (*del) (void *))
{
struct avltree * t = malloc(sizeof(struct avltree));
struct avltree *t = malloc(sizeof(struct avltree));
if (!t)
return NULL;
t->root=0;
t->count=0;
t->cmp=cmp;
t->del=del;
t->root = 0;
t->count = 0;
t->cmp = cmp;
t->del = del;
return t;
}
struct avlnode * avlnode_create(void * data)
struct avlnode *avlnode_create(void *data)
{
struct avlnode * n = malloc(sizeof(struct avlnode));
if(!n)
struct avlnode *n = malloc(sizeof(struct avlnode));
if (!n)
return NULL;
n->left=n->right=0;
n->bal=0;
n->left = n->right = 0;
n->bal = 0;
n->data = data;
return n;
}
void avlnode_destroy(struct avltree *t,struct avlnode *n)
void avlnode_destroy(struct avltree *t, struct avlnode *n)
{
if(t->del){
if (t->del) {
t->del(n->data);
}
free(n);
@ -68,66 +69,62 @@ void avlnode_destroy(struct avltree *t,struct avlnode *n)
}
static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** data)
static int avltree_add0(struct avltree *t, struct avlnode **parent, void **data)
{
// struct avlnode * rn;
// struct avlnode * rn;
struct avlnode *tmp;
struct avlnode * n = *parent;
int rc=t->cmp(*data,n->data);
struct avlnode *n = *parent;
int rc = t->cmp(*data, n->data);
int bal;
if (rc==0){
*data=n->data;
int bal;
if (rc == 0) {
*data = n->data;
return 2;
}
if (rc<0){
if (n->left)
{
bal = avltree_add0(t,&n->left,data);
if (bal>1)
if (rc < 0) {
if (n->left) {
bal = avltree_add0(t, &n->left, data);
if (bal > 1)
return bal;
n->bal -=bal;
if (n->bal==0)
n->bal -= bal;
if (n->bal == 0)
return 0;
if (n->bal==-2){
if (n->left->bal==-1){
n->bal=0;
n->left->bal=0;
*parent=n->left;
tmp=n->left->right;
n->left->right=n;
n->left=tmp;
if (n->bal == -2) {
if (n->left->bal == -1) {
n->bal = 0;
n->left->bal = 0;
*parent = n->left;
tmp = n->left->right;
n->left->right = n;
n->left = tmp;
return 0;
}
if (n->left->bal==1){
*parent=n->left->right;
if ((*parent)->bal==1) {
n->bal=0;
n->left->bal=-1;
}
else if ((*parent)->bal==-1){
n->bal=1;
n->left->bal=0;
}
else{
n->bal=0;
n->left->bal=0;
if (n->left->bal == 1) {
*parent = n->left->right;
if ((*parent)->bal == 1) {
n->bal = 0;
n->left->bal = -1;
} else if ((*parent)->bal == -1) {
n->bal = 1;
n->left->bal = 0;
} else {
n->bal = 0;
n->left->bal = 0;
}
(*parent)->bal=0;
n->left->right=(*parent)->left;
(*parent)->left=n->left;
(*parent)->bal = 0;
n->left->right = (*parent)->left;
(*parent)->left = n->left;
tmp = (*parent)->right;
(*parent)->right=n;
n->left=tmp;
(*parent)->right = n;
n->left = tmp;
return 0;
}
}
//printf("!!!!left bal = %i\n",n->left->bal);
//exit(0);
@ -137,67 +134,63 @@ static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** da
}
/* n->left is 0 */
n->left=avlnode_create(*data);
n->left = avlnode_create(*data);
if (!n->left)
return 3;
t->count++;
if(n->right==0){
n->bal=-1;
if (n->right == 0) {
n->bal = -1;
return 1;
}
n->bal=0;
n->bal = 0;
return 0;
}
else{
if (n->right){
bal = avltree_add0(t,&n->right,data);
if(bal>1)
} else {
if (n->right) {
bal = avltree_add0(t, &n->right, data);
if (bal > 1)
return bal;
n->bal+=bal;
if (n->bal==0)
n->bal += bal;
if (n->bal == 0)
return 0;
if (n->bal==2){
if (n->right->bal==1){
n->bal=0;
n->right->bal=0;
*parent=n->right;
tmp=n->right->left;
n->right->left=n;
n->right=tmp;
if (n->bal == 2) {
if (n->right->bal == 1) {
n->bal = 0;
n->right->bal = 0;
*parent = n->right;
tmp = n->right->left;
n->right->left = n;
n->right = tmp;
return 0;
}
else if(n->right->bal==-1){
*parent=n->right->left;
} else if (n->right->bal == -1) {
*parent = n->right->left;
if ((*parent)->bal==-1) {
n->bal=0;
n->right->bal=1;
}
else if ((*parent)->bal==1){
n->bal=-1;
n->right->bal=0;
}
else{
n->bal=0;
n->right->bal=0;
if ((*parent)->bal == -1) {
n->bal = 0;
n->right->bal = 1;
} else if ((*parent)->bal == 1) {
n->bal = -1;
n->right->bal = 0;
} else {
n->bal = 0;
n->right->bal = 0;
}
(*parent)->bal=0;
n->right->left=(*parent)->right;
(*parent)->right=n->right;
(*parent)->bal = 0;
n->right->left = (*parent)->right;
(*parent)->right = n->right;
tmp = (*parent)->left;
(*parent)->left=n;
n->right=tmp;
(*parent)->left = n;
n->right = tmp;
return 0;
}
//printf("!!!!iright bal = %i\n",n->left->bal);
@ -211,16 +204,16 @@ static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** da
/* n->right is 0 */
n->right=avlnode_create(*data);
n->right = avlnode_create(*data);
if (!n->right)
return 3;
t->count++;
if(n->left==0){
n->bal=1;
if (n->left == 0) {
n->bal = 1;
return 1;
}
n->bal=0;
n->bal = 0;
return 0;
}
}
@ -232,18 +225,18 @@ static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** da
* @data pointer to element
* @return added alement or NULL if error.
*/
void * avltree_add(struct avltree *t, void * data)
void *avltree_add(struct avltree *t, void *data)
{
if (t->root==0){
if (t->root == 0) {
t->root = avlnode_create(data);
if (t->root)
t->count++;
return t->root->data;
}
void * d = data;
int rc = avltree_add0(t,&t->root,&d);
void *d = data;
int rc = avltree_add0(t, &t->root, &d);
if (rc>3)
if (rc > 3)
return NULL;
return d;
@ -252,21 +245,21 @@ void * avltree_add(struct avltree *t, void * data)
static void rot_l(struct avlnode *n, struct avlnode **parent)
{
struct avlnode *tmp;
*parent=n->right;
tmp=n->right->left;
n->right->left=n;
n->right=tmp;
*parent = n->right;
tmp = n->right->left;
n->right->left = n;
n->right = tmp;
}
static void rot_r(struct avlnode *n, struct avlnode **parent)
{
struct avlnode *tmp;
*parent=n->left;
tmp=n->left->right;
n->left->right=n;
n->left=tmp;
}
*parent = n->left;
tmp = n->left->right;
n->left->right = n;
n->left = tmp;
}
@ -308,84 +301,79 @@ static int avltree_delete_hi(struct avlnode **parent, void **data)
static void rot_rl(struct avlnode *n, struct avlnode **parent)
{
struct avlnode * tmp;
*parent=n->right->left;
n->right->left=(*parent)->right;
(*parent)->right=n->right;
struct avlnode *tmp;
*parent = n->right->left;
n->right->left = (*parent)->right;
(*parent)->right = n->right;
tmp = (*parent)->left;
(*parent)->left=n;
n->right=tmp;
(*parent)->left = n;
n->right = tmp;
}
static void rot_lr(struct avlnode *n, struct avlnode **parent)
{
struct avlnode * tmp;
*parent=n->left->right;
n->left->right=(*parent)->left;
(*parent)->left=n->left;
struct avlnode *tmp;
*parent = n->left->right;
n->left->right = (*parent)->left;
(*parent)->left = n->left;
tmp = (*parent)->right;
(*parent)->right=n;
n->left=tmp;
(*parent)->right = n;
n->left = tmp;
}
static int adj_bal_l(struct avlnode *n, struct avlnode **parent)
{
if (n->right->bal==1){
n->bal=0;
n->right->bal=0;
rot_l(n,parent);
if (n->right->bal == 1) {
n->bal = 0;
n->right->bal = 0;
rot_l(n, parent);
return 1;
}
else if(n->right->bal==0){
n->bal=1;
n->right->bal=-1;
rot_l(n,parent);
} else if (n->right->bal == 0) {
n->bal = 1;
n->right->bal = -1;
rot_l(n, parent);
return 0;
}else if(n->right->bal==-1){
// int rb;
n->bal=0;
n->right->bal=0;
// rb = n->right->left->bal;
n->right->left->bal=0;
rot_rl(n,parent);
} else if (n->right->bal == -1) {
// int rb;
n->bal = 0;
n->right->bal = 0;
// rb = n->right->left->bal;
n->right->left->bal = 0;
rot_rl(n, parent);
return 1;
}
// printf("adj bal l not handled \n");
// exit(0);
// printf("adj bal l not handled \n");
// exit(0);
return -11; /* that should never happen */
return -11; /* that should never happen */
}
int adj_bal_r(struct avlnode *n, struct avlnode **parent)
{
if (n->left->bal==-1){
n->bal=0;
n->left->bal=0;
rot_r(n,parent);
if (n->left->bal == -1) {
n->bal = 0;
n->left->bal = 0;
rot_r(n, parent);
return 1;
}
else if(n->left->bal==0){
n->bal=-1;
n->left->bal=1;
rot_r(n,parent);
} else if (n->left->bal == 0) {
n->bal = -1;
n->left->bal = 1;
rot_r(n, parent);
return 0;
}
else if(n->left->bal==1){
// int rb;
n->bal=0;
n->left->bal=0;
// rb = n->left->right->bal;
n->left->right->bal=0;
rot_lr(n,parent);
} else if (n->left->bal == 1) {
// int rb;
n->bal = 0;
n->left->bal = 0;
// rb = n->left->right->bal;
n->left->right->bal = 0;
rot_lr(n, parent);
return 1;
}
// printf("adj bal li left not handled \n");
// exit(0);
return -11; /* that should never happen */
// printf("adj bal li left not handled \n");
// exit(0);
return -11; /* that should never happen */
}
@ -393,29 +381,29 @@ int adj_bal_r(struct avlnode *n, struct avlnode **parent)
static int avltree_del_lo(struct avlnode **parent, void **data)
{
struct avlnode * n = *parent;
struct avlnode *n = *parent;
if(n->left!=0){
int bal = avltree_del_lo(&n->left,data);
n->bal+=bal;
if (n->bal==1){
if (n->left != 0) {
int bal = avltree_del_lo(&n->left, data);
n->bal += bal;
if (n->bal == 1) {
return 0;
}
if (n->bal!=2)
}
if (n->bal != 2)
return bal;
adj_bal_l(n,parent);
adj_bal_l(n, parent);
return 0;
}
/* found the lowest element */
*parent=n->right;
*parent = n->right;
*data = n->data;
free (n);
free(n);
return 1;
if (n->right){
if (n->right) {
free(n);
return 1;
}
@ -429,98 +417,98 @@ static int avltree_del_lo(struct avlnode **parent, void **data)
int avltree_del0(struct avltree *t, struct avlnode **parent, void **data)
{
struct avlnode * n = *parent;
struct avlnode *n = *parent;
int rc;
int bal;
rc = t->cmp(*data, n->data);
rc =t->cmp(*data,n->data);
if (rc==0){
if (n->right == 0 && n->left ==0){
*parent=0;
avlnode_destroy(t,n);
if (rc == 0) {
if (n->right == 0 && n->left == 0) {
*parent = 0;
avlnode_destroy(t, n);
return 1;
}
if (n->right && n->left==0){
*parent=n->right;
avlnode_destroy(t,n);
if (n->right && n->left == 0) {
*parent = n->right;
avlnode_destroy(t, n);
return 1;
}
if (n->left && n->right==0){
avlnode_destroy(t,n);
*parent=n->left;
if (n->left && n->right == 0) {
avlnode_destroy(t, n);
*parent = n->left;
return 1;
}
/* node has two childs */
if (t->del){
if (t->del) {
t->del(n->data);
}
t->count--;
bal = avltree_del_lo(&n->right,&n->data);
n->bal-= bal;
if (n->bal==-1)
bal = avltree_del_lo(&n->right, &n->data);
n->bal -= bal;
if (n->bal == -1)
return 0;
if (n->bal != -2)
return bal;
return adj_bal_r(n,parent);
return adj_bal_r(n, parent);
}
if (rc<0){
if (n->left)
{
bal = avltree_del0(t,&n->left,data);
if (bal==2)
if (rc < 0) {
if (n->left) {
bal = avltree_del0(t, &n->left, data);
if (bal == 2)
return 2;
n->bal+=bal;
if (n->bal==1)
n->bal += bal;
if (n->bal == 1)
return 0;
if (n->bal!=2)
if (n->bal != 2)
return bal;
return adj_bal_l(n,parent);
return adj_bal_l(n, parent);
}
return 2; /* not found */
}
else { /* rc must be > 0 */
if (n->right){
bal = avltree_del0(t,&n->right,data);
if (bal==2)
return 2; /* not found */
} else { /* rc must be > 0 */
if (n->right) {
bal = avltree_del0(t, &n->right, data);
if (bal == 2)
return 2;
n->bal-=bal;
if (n->bal==-1)
n->bal -= bal;
if (n->bal == -1)
return 0;
if (n->bal != -2)
return bal;
return adj_bal_r(n,parent);
return adj_bal_r(n, parent);
}
return 2; /* not found */
return 2; /* not found */
}
}
void * avltree_del(struct avltree *t, void *data)
void *avltree_del(struct avltree *t, void *data)
{
if (!t->root)
return NULL;
void *d = data;
int rc = avltree_del0(t,&t->root,&d);
if (rc==2)
return 0;
int rc = avltree_del0(t, &t->root, &d);
if (rc == 2)
return NULL;
return data;
}
@ -609,11 +597,13 @@ void walk(struct avlnode *n)
*/
/*
void avltree_destroy(struct avltree *t)
{
avltree_del_all(t);
free (t);
}
*/
//#include <time.h>

View File

@ -16,65 +16,81 @@
*/
/*
* yet another avl tree implementation!
/**
* @file
* @brief Yet another avl tree implementation!
*/
#ifndef __AVLTREE_H
#define __AVLTREE_H
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct avlnode{
void * data;
struct avlnode * left;
struct avlnode * right;
struct avlnode {
void *data;
struct avlnode *left;
struct avlnode *right;
int bal;
};
struct avltree{
struct avlnode * root;
int (*cmp)(const void*,const void*);
void(*del)(void*);
struct avltree {
struct avlnode *root;
int (*cmp) (const void *, const void *);
void (*del) (void *);
int count;
};
void avlnode_destroy(struct avltree *t,struct avlnode *n);
void avlnode_destroy(struct avltree *t, struct avlnode *n);
struct avltree * avltree_create(int (*cmp)(const void*,const void*),void(*del)(void*));
void avltree_destroy(struct avltree *t);
struct avltree *avltree_create(int (*cmp) (const void *, const void *),
void (*del) (void *));
//void avltree_destroy(struct avltree *t);
void avltree_del_all(struct avltree *t);
void * avltree_del(struct avltree *t, void *data);
void * avltree_add(struct avltree *t, void *data);
void *avltree_del(struct avltree *t, void *data);
void *avltree_add(struct avltree *t, void *data);
//void * avltree_get(struct avltree *t ,void *data);
struct avlnode * avltree_get_node(struct avltree *t ,void *data);
struct avlnode *avltree_get_node(struct avltree *t, void *data);
extern int avltree_foreach_lr(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv);
extern int avltree_foreach_rl(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv);
int avltree_foreach_from_lr(struct avltree *t, struct avlnode *n, void *data,int (*callback)(void *,void *),void *cbpriv);
extern int avltree_foreach_lr(struct avlnode *n, int (*callback) (void *, void *),
void *cbpriv);
extern int avltree_foreach_rl(struct avlnode *n, int (*callback) (void *, void *),
void *cbpriv);
int avltree_foreach_from_lr(struct avltree *t, struct avlnode *n, void *data,
int (*callback) (void *, void *), void *cbpriv);
//extern void avltree_foreach(struct avltree *t, int (*callback)(void *,void*),void *cbpriv,int dir);
static inline void * avltree_get(struct avltree *t ,void *data){
struct avlnode * n = avltree_get_node(t,data);
static inline void *avltree_get(struct avltree *t, void *data)
{
struct avlnode *n = avltree_get_node(t, data);
if (!n)
return NULL;
return n->data;
}
static inline void * avltree_replace_data(struct avltree *t ,void *data,int len) {
void * df = avltree_get(t,data);
if(!df)
static inline void *avltree_replace_data(struct avltree *t, void *data, int len)
{
void *df = avltree_get(t, data);
if (!df)
return NULL;
memcpy(df,data,len);
memcpy(df, data, len);
return df;
}
static inline void avltree_destroy(struct avltree *t)
{
avltree_del_all(t);
free (t);
}
#define avltree_find(t,d) avltree_get(t,d)
#define avltree_insert(t,d) avltree_add(t,d)
//#define avltree_walk(t,dir) avltree_foreach(t,dir)
@ -86,5 +102,3 @@ static inline void * avltree_replace_data(struct avltree *t ,void *data,int len)
#endif

View File

@ -13,14 +13,22 @@
You should have received a copy of the GNU General Public License
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief Implementation of avltree_get
*/
#include <stdio.h>
#include "avltree.h"
/**
* Get an AVL tree element.
* @param data Element to get
* @return pointer to element or NULL if not found.
*/
void * avltree_get(struct avltree *t ,void *data)
{
struct avlnode *n = t->root;

View File

@ -34,6 +34,7 @@
#include "conn.h"
#include "lwapp.h"
#include "strheap.h"
/* capwap version and iana number */
#define CW_VERSION 0
@ -83,6 +84,9 @@ enum capwap_states {
#define CWTH_FLAGS_T 0x100 /* bit 8 type of payload frame */
/**
* CAWAP header flags.
*/
#define CW_FLAG_HDR_R1 0x01 /* bit 0 reserved 1 */
#define CW_FLAG_HDR_R2 0x02 /* bit 1 reserved 2 */
#define CW_FLAG_HDR_R3 0x04 /* bit 2 reserved 3 */
@ -521,6 +525,9 @@ extern int cw_readmsg_configuration_update_request(uint8_t * elems, int elems_le
#define cw_put_data lw_put_data
#define cw_put_bstr lw_put_bstr
#define cw_set_dword lw_set_dword
#define cw_get_byte lw_get_byte
#define cw_get_word lw_get_word
#define cw_get_dword lw_get_dword
@ -557,6 +564,36 @@ extern int cw_readmsg_configuration_update_request(uint8_t * elems, int elems_le
#define cw_get_hdr_msg_offset(th) (4*cw_get_hdr_hlen(th))
#define cw_get_hdr_msg_elems_offset(th) (cw_get_hdr_msg_offset(th)+8)
#define cw_set_hdr_preamble(th,v) ((*th)=v)
/**
* Set the HLEN field of a CAWAP Header
* @param th pointer to the header
* @param hlen velue to set (max. 5 bits)
*/
static inline void cw_set_hdr_hlen(uint8_t *th,int hlen){
uint32_t d = cw_get_dword(th);
d &= (0x1f << 19) ^ 0xffffffff;
d |= ((hlen) & 0x1f) <<19;
cw_set_dword(th,d);
}
/**
* Set CAPWAP header flags
* @param th pointer to header
* @param flags list of flags to set or unset
* @param set 1=set flag, 0=unset flag
*/
#define cw_set_hdr_flags(th,flags,set) \
( set ? ((*((uint32_t*)th)) |= htonl(flags)) : ((*((uint32_t*)th)) &= (0xffffffff^htonl(flags))) )
#define cw_set_hdr_flag_f(th,set) cw_set_hdr_flag(th, CW_FLAG_HDR_F)
/* Macros for message headers */
#define cw_get_msg_id(msgptr) (cw_get_dword(msgptr))
#define cw_get_msg_type(msgptr) cw_get_msg_id(msgptr)
@ -565,15 +602,6 @@ extern int cw_readmsg_configuration_update_request(uint8_t * elems, int elems_le
#define cw_get_msg_elems_ptr(msgptr) ((msgptr)+8)
#define cw_set_hdr_preamble(th,v) ((*th)=v)
#define cw_set_hdr_flags(th,val,set) \
( set ? ((*((uint32_t*)th)) |= htonl(val)) : ((*((uint32_t*)th)) &= (0xffffffff^htonl(val))) )
#define cw_set_hdr_flag_f(th,set) cw_set_hdr_flag(th, CW_FLAG_HDR_F)
#define cw_set_msg_id(msgptr,t) cw_put_dword(msgptr,t)
#define cw_set_msg_type(msgptr,t) cw_set_msg_id(msgptr,t)
#define cw_set_msg_seqnum(msgptr,s) cw_put_byte( (msgptr) +4,s);
@ -606,14 +634,14 @@ static inline int cw_get_hdr_msg_total_len(uint8_t * rawmsg)
* @pram e pointer to element (uint8_t*)
* @return type of element
*/
#define cw_get_elem_len(e) cw_get_word(e+2)
#define cw_get_elem_len(e) cw_get_word((e)+2)
/**
* Get a pointer to the data of a CAPWAP message element
* @param e pointer to message element
* @return pointer to data
*/
#define cw_get_elem_data(e) (e+4)
#define cw_get_elem_data(e) ((e)+4)
/**
* Iterate through message elements of a CAPWAP message
@ -770,19 +798,11 @@ extern int cw_send_configuration_update_response(struct conn *conn, int seqnum,
/* Message to text stuff */
struct cw_strlist {
uint32_t id;
const char *str;
};
extern const char *cw_strlist_get_str(struct cw_strlist *s, int id);
/* Constants to string conversion lists */
extern struct cw_strlist capwap_strings_msg[];
extern struct cw_strlist capwap_strings_state[];
extern struct cw_strlist capwap_strings_vendor[];
extern struct cw_strlist capwap_strings_elem[];
extern struct cw_str capwap_strings_msg[];
extern struct cw_str capwap_strings_state[];
extern struct cw_str capwap_strings_vendor[];
extern struct cw_str capwap_strings_elem[];
#define cw_strmsg(id) cw_strlist_get_str(capwap_strings_msg,id)
@ -791,6 +811,13 @@ extern struct cw_strlist capwap_strings_elem[];
#define cw_strvendor(id) cw_strlist_get_str(capwap_strings_vendor,id)
#define cw_strelemp(p,id) cw_strheap_get((p)->strelem,id)
extern const char *cw_strlist_get_str(struct cw_str *s, int id);
int cw_process_msg(struct conn *conn, uint8_t * rawmsg, int len);
@ -806,13 +833,18 @@ extern int cw_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8
int len);
//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, uint32_t elem_id, uint8_t * dst,
struct cw_item *item);
extern int cw_out_ac_descriptor(struct conn *conn, uint32_t elem_id, uint8_t * dst,
struct cw_item *item);
extern int cw_out_capwap_control_ip_addrs(struct conn *conn, uint32_t elem_id,
uint8_t * dst, struct cw_item *item);
extern int cw_out_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst); //, struct cw_item *item);
//extern int cw_out_ac_descriptor(struct conn *conn, uint32_t elem_id, uint8_t * dst,
//struct cw_item *item);
extern int cw_out_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst); //,struct cw_item * item)
//extern int cw_out_capwap_control_ip_addrs(struct conn *conn, uint32_t elem_id,
// uint8_t * dst, struct cw_item *item);
extern int cw_out_capwap_control_ip_addrs(struct conn *conn,struct cw_action_out *a,uint8_t *dst) ;
extern int cw_put_msg(struct conn *conn, uint8_t * rawout);
struct cw_ac_status {
@ -825,9 +857,42 @@ struct cw_ac_status {
int dtls_policy;
};
/**
* Put an cw_ac_stauts structure to a buffer
* @param dst destination buffer
* @param s #cw_ac_status to put
* @return number of bytes put
* This function is only useful (used) in conjunction with
* putting AC Descriptor message elements.
*/
static inline int cw_put_ac_status(uint8_t *dst, struct cw_ac_status *s){
uint8_t *d=dst;
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));
return d-dst;
}
static inline int cw_put_version(uint8_t *dst,uint16_t subelem_id, uint32_t vendor_id,bstr16_t data)
{
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_register_actions_capwap_ac(struct cw_actiondef *def);
int cw_register_actions_cipwap_ac(struct cw_actiondef *def);
int cw_in_set_state_none(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len);
struct cw_item *cw_out_get_local(struct conn *conn, struct cw_action_out *a);
#endif

View File

@ -61,7 +61,7 @@
CW_ITEM_WTP_MAC_TYPE, /* ID to use store */ \
1, 1 /* min/max length */
#define CW_ACTION_VENDOR_SPECIFIC_PAYLOAD \
#define CW_ACTION_IN_VENDOR_SPECIFIC_PAYLOAD \
CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, /* Element ID */ \
cw_in_vendor_specific_payload, 0 /* start/end callback*/ \

View File

@ -21,13 +21,7 @@
#include "action.h"
#include "capwap_items.h"
#include "capwap_actions.h"
int cw_in_set_state_none(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len)
{
conn->capwap_state=CW_STATE_NONE;
return 1;
}
#include "strheap.h"
@ -58,8 +52,7 @@ cw_action_in_t capwap_actions_ac_in[] = {
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_WTP_MAC_TYPE}
,
/* Vendor Specific Payload */
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ELEM_VENDOR_SPECIFIC_PAYLOAD,
cw_in_vendor_specific_payload, 0}
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_VENDOR_SPECIFIC_PAYLOAD}
,
/* -------------------------------------------------------------------------------*/
@ -90,6 +83,9 @@ cw_action_in_t capwap_actions_ac_in[] = {
/* Element WTP MAC Type */
{0, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, CW_ACTION_IN_WTP_MAC_TYPE}
,
/* Element Vendor Specific Payload */
{0, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, CW_ACTION_IN_VENDOR_SPECIFIC_PAYLOAD}
,
@ -121,6 +117,7 @@ cw_action_in_t capwap_actions_ac_in[] = {
};
/*
int cw_out_ac_name(uint8_t * dst, struct cw_item *item)
{
@ -130,13 +127,8 @@ int cw_out_ac_name(uint8_t * dst, struct cw_item *item)
int len = cw_put_data(dst + 4, data, strlen((char *) data));
return len + cw_put_elem_hdr(dst, CW_ELEM_AC_NAME, len);
}
*/
struct cw_item *cw_get_local(struct conn *conn, uint32_t item_id)
{
struct cw_item i;
i.id = item_id;
return cw_itemstore_get(conn->local, item_id);
}
@ -145,26 +137,38 @@ cw_action_out_t capwap_actions_ac_out[] = {
,
/* AC Descriptor */
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR,
CW_ELEM_AC_DESCRIPTOR, cw_out_ac_descriptor, 0}
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR, 0
,CW_ELEM_AC_DESCRIPTOR, cw_out_ac_descriptor, 0}
,
/* AC Name */
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_NAME,
CW_ELEM_AC_NAME, cw_out_generic, cw_get_local}
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_NAME, 0,
CW_ELEM_AC_NAME, cw_out_generic, cw_out_get_local}
,
/* List of CAPWAP Control IPv4 and IPv6 addresses */
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_CAPWAP_CONTROL_IP_LIST,
0, cw_out_capwap_control_ip_addrs, cw_get_local}
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_CAPWAP_CONTROL_IP_LIST, 0,
0, cw_out_capwap_control_ip_addrs, cw_out_get_local}
,
/* -------------------------------------------------------------------------------
* Join Response OUT
*/
{CW_MSG_JOIN_RESPONSE, CW_ITEM_NONE}
,
/* Result Code */
{CW_MSG_JOIN_RESPONSE, CW_ITEM_RESULT_CODE, 0,
CW_ELEM_RESULT_CODE, cw_out_generic, cw_out_get_local}
,
/* AC Descriptor */
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR, 0
,CW_ELEM_AC_DESCRIPTOR, cw_out_ac_descriptor, 0}
,
{CW_MSG_JOIN_RESPONSE, CW_ITEM_AC_NAME}
,
{CW_MSG_JOIN_RESPONSE, CW_ITEM_RESULT_CODE}
,
{0, 0}
@ -180,9 +184,18 @@ int cw_register_actions_capwap_ac(struct cw_actiondef *def)
{
def->in = cw_actionlist_in_create();
def->out = cw_actionlist_out_create();
def->strmsg = cw_strheap_create();
def->strelem = cw_strheap_create();
cw_actionlist_in_register_actions(def->in, capwap_actions_ac_in);
cw_actionlist_out_register_actions(def->out, capwap_actions_ac_out);
int rc ;
rc = cw_strheap_register_strings(def->strmsg,capwap_strings_msg);
rc += cw_strheap_register_strings(def->strelem,capwap_strings_elem);
printf("Registered %d strings\n",rc);
return 1;
}

View File

@ -46,6 +46,7 @@
#define CW_CISCO_DIRECT_SEQUENCE_CONTROL LW_ELEM_DIRECT_SEQUENCE_CONTROL /* 14 */
#define CW_CISCO_SUPPORTED_RATES LW_ELEM_80211_RATE_SET /* 16 */
#define CW_CISCO_MWAR_NAME LW_ELEM_AC_NAME /* 31 */
#define CW_CISCO_LOCATION_DATA LW_ELEM_LOCATION_DATA /* 35 */
#define CW_CISCO_STATISTICS_TIMER LW_ELEM_STATISTICS_TIMER /* 37 */
@ -92,15 +93,20 @@
* @param dst destination buffer
* @param time a unix timestamp
* @param type of time
* @return number of bytes put (15)
* @return number of bytes put (5)
*/
static inline int cw_addelem_cisco_ap_timesync(uint8_t * dst, time_t time, uint8_t type)
static inline int cw_put_cisco_ap_timesync(uint8_t * dst, time_t time, uint8_t type)
{
cw_put_dword(dst + 10, time);
cw_put_byte(dst + 14, type);
return 5 + cw_put_elem_vendor_hdr(dst, CW_VENDOR_ID_CISCO, CW_CISCO_AP_TIMESYNC, 5);
cw_put_dword(dst , time);
cw_put_byte(dst + 4, type);
return 5;
}
int cw_out_cisco_ap_timesync(struct conn *conn,struct cw_action_out * a,uint8_t *dst);
/**
* Add a Cisco RAD Name message element to buffer
* @param dst destination buffer
@ -184,6 +190,8 @@ extern const char * cw_cisco_id_to_str(int elem_id);
int cw_readelem_cisco_wtp_radio_cfg(int elem_id,uint8_t *elem, int len,struct radioinfo *ri);
int cw_addelem_cisco_wtp_radio_cfg(uint8_t*dst,struct radioinfo * ri);
extern int cw_out_cisco_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst) ;
/*

View File

@ -37,7 +37,12 @@ enum capwap_items {
CW_ITEM_LOCATION_DATA,
CW_ITEM_SESSION_ID,
CW_ITEM_AC_TIMESTAMP,
/* CIPWAP and Cisco */
CW_ITEM_WTP_GROUP_NAME
};

View File

@ -1,6 +1,6 @@
#include "capwap.h"
struct cw_strlist capwap_strings_elem[] = {
struct cw_str capwap_strings_elem[] = {
{CW_ELEM_AC_DESCRIPTOR, "AC Descriptor"},
{CW_ELEM_AC_IPV4_LIST, "AC IPv4 List"},
@ -55,12 +55,13 @@ struct cw_strlist capwap_strings_elem[] = {
{CW_ELEM_RESERVED_46, "Reserved 46"},
{CW_ELEM_WTP_RADIO_STATISTICS, "WTP Radio Statistics"},
{CWMSGELEM_WTP_REBOOT_STATISTICS, "WTP Reboot Statistics"},
{CW_ELEM_WTP_STATIC_IP_ADDRESS_INFORMATION, "WTP Static IP Address Information"}
{CW_ELEM_WTP_STATIC_IP_ADDRESS_INFORMATION, "WTP Static IP Address Information"},
/* Cisco's CAPWAP definitions (CAPWAP draft 7) */
/* CW_ELEM_WTP_IPV4_IP_ADDRESS 42
CW_ELEM_WTP_IPV6_IP_ADDRESS 43
*/
{0,"Unknown Element"}
};

View File

@ -1,6 +1,6 @@
#include "capwap.h"
struct cw_strlist capwap_strings_msg[] = {
struct cw_str capwap_strings_msg[] = {
{ CW_MSG_DISCOVERY_REQUEST, "Discovery Request" },
{ CW_MSG_DISCOVERY_RESPONSE,"Discovery Response" },
{ CW_MSG_JOIN_REQUEST, "Join Request"},

View File

@ -1,8 +1,10 @@
#include "capwap.h"
struct cw_strlist capwap_strings_state[] = {
struct cw_str capwap_strings_state[] = {
{ CW_STATE_DISCOVERY, "Discovery" },
{ CW_STATE_JOIN,"Join" },
{ CW_STATE_RUN,"Run" },
{ CW_STATE_CONFIGURE,"Configure" },
{ 0,"Undefined" }
};

View File

@ -1,7 +1,7 @@
#include "capwap.h"
struct cw_strlist capwap_strings_vendor[] = {
struct cw_str capwap_strings_vendor[] = {
{ CW_VENDOR_ID_CISCO, "Cisco" },
{ CW_VENDOR_ID_ZYXEL, "Zyxel" },
{ CW_VENDOR_ID_FSF, "FSF"}

View File

@ -1,28 +1,71 @@
#include "capwap.h"
#include "capwap_cisco.h"
#include "capwap_actions.h"
#include "cipwap.h"
/**
*@file
*brief CIPWAP Actions
*/
cw_action_in_t cipwap_actions_ac_in[] = {
/* Element Discovery Type */
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ELEM_DISCOVERY_TYPE,
cw_in_generic, 0, CW_ITEMTYPE_BYTE, CW_ITEM_DISCOVERY_TYPE, 4, 4}
/* -------------------------------------------------------------------------------
* Discovery Request IN
*/
{CW_VENDOR_ID_CISCO, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_CISCO_RAD_NAME,
cw_in_generic, 0, CW_ITEMTYPE_STR,CW_ITEM_WTP_NAME,1,512}
,
{CW_VENDOR_ID_CISCO, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, CW_CISCO_AP_GROUP_NAME,
cw_in_generic, 0, CW_ITEMTYPE_STR,CW_ITEM_WTP_GROUP_NAME,1,512}
,
{0,0,0}
};
extern struct cw_item *cw_get_local(struct conn *conn, struct cw_action_out *a);
cw_action_out_t cipwap_actions_ac_out[] = {
/* -------------------------------------------------------------------------------
* Discovery Response OUT
*/
/* AC Descriptor (Cisco) */
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR, 0 ,
CW_ELEM_AC_DESCRIPTOR, cw_out_cisco_ac_descriptor, 0}
,
/* Cisco AP Timesync - Important to get the WTP a DTLS
connection stablished*/
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_TIMESTAMP, CW_VENDOR_ID_CISCO,
CW_CISCO_AP_TIMESYNC, cw_out_cisco_ap_timesync, 0}
,
{0,0,0}
};
/**
* Register CiPWAP actions
*/
int cw_register_actions_cipwap_ac(struct cw_actiondef *def)
{
cw_register_actions_capwap_ac(def);
cw_actionlist_in_register_actions(def->in, cipwap_actions_ac_in);
// cw_actionlist_out_register_actions(def->out, capwap_actions_ac_out);
cw_actionlist_out_register_actions(def->out, cipwap_actions_ac_out);
cw_strheap_register_strings(def->strelem,cipwap_strings_elem);
return 1;
}

View File

@ -16,6 +16,10 @@
*/
/**
* @file
* @brief Connection object stuff
*/
#ifndef __CONN_H
#define __CONN_H
@ -35,14 +39,18 @@
#include "itemstore.h"
/**
* Connection Object
*/
struct conn {
int sock;
struct sockaddr_storage addr;
int recv_timeout;
cw_itemstore_t itemstore;
/** Basically used to store local conig data */
cw_itemstore_t local;
/** used to maintain the remote config, an AC holds here the WTP config.
A WTP holds here data about it's AC */
cw_itemstore_t remote;

View File

@ -32,12 +32,15 @@ static int message_cb(void *p, uint8_t *rawmsg, int len)
}
void conn_msg_processor(struct conn *conn)
int conn_msg_processor(struct conn *conn)
{
uint8_t buf[2024];
int len = 2024;
int n = conn->read(conn, buf, len);
if (n<0 )
return n;
if (n > 0)
conn_process_packet(conn, buf, n, cw_process_msg, conn);

View File

@ -1,5 +1,38 @@
#include "cw_log.h"
#include "capwap.h"
#include "capwap_cisco.h"
#include "dbg.h"
static int cw_format_vendor(char *dst, uint32_t vendor_id, int elem_id, const uint8_t * elem_data)
{
switch (vendor_id) {
case CW_VENDOR_ID_CISCO:
{
sprintf(dst, "%d - %s", elem_id,
cw_cisco_id_to_str(elem_id));
/* dive into LWAPP vendor specific decoding */
/*
if (elem_id == CW_CISCO_SPAM_VENDOR_SPECIFIC) {
uint32_t lw_elem_id = lw_get_word(elem_data + 4 + 6);
char b[256];
sprintf(b, "\n\t LWAPP Cisco Specific: %d - %s",
lw_elem_id, lw_cisco_id_to_str(lw_elem_id));
strcat(dst, b);
}
*/
break;
}
}
return 0;
}
@ -7,7 +40,7 @@
* print debug info for message elements
*/
void cw_dbg_elem_(int msg, int msgelem, const uint8_t * msgbuf, int len)
void cw_dbg_elem_(struct conn * conn, int msg, int msgelem, const uint8_t * msgbuf, int len)
{
if (!cw_dbg_is_level(DBG_ELEM))
return;
@ -20,26 +53,26 @@ void cw_dbg_elem_(int msg, int msgelem, const uint8_t * msgbuf, int len)
if (msgelem == CW_ELEM_VENDOR_SPECIFIC_PAYLOAD) {
uint32_t vendor_id = ntohl(*((uint32_t *) msgbuf));
int type = ntohs(*((uint16_t *) (msgbuf + 4)));
sprintf(vendorname, "%s/%s/%d",
(char *) cw_strelem(msgelem),
(char *) lw_vendor_id_to_str(vendor_id), type);
elemname = vendorname;
cw_format_vendor(vendor_details, vendor_id, type, msgbuf);
sprintf(vendorname, "%s/%s/%s",
cw_strelemp(conn->actions,msgelem),
(char *) lw_vendor_id_to_str(vendor_id), vendor_details);
elemname = vendorname;
} else {
elemname = cw_strelem(msgelem);
elemname = cw_strelemp(conn->actions,msgelem);
}
if (!cw_dbg_is_level(DBG_ELEM_DMP))
cw_dbg(DBG_ELEM,
"%s, CAWPAP element: %d (%s), len=%d%s",
cw_strmsg(msg), msgelem, elemname, len, vendor_details);
cw_strmsg(msg), msgelem, elemname, len, "");
else
cw_dbg_dmp(DBG_ELEM, msgbuf, len,
"%s, CAPWAP element: %d (%s), len=%d%s\n\tDump ...",
cw_strmsg(msg), msgelem, elemname, len, vendor_details);
cw_strmsg(msg), msgelem, elemname, len, "");
}

View File

@ -31,7 +31,7 @@ int cw_in_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int le
return 0;
}
cw_itemstore_set(conn->itemstore,a->item_id,a->itemtype,data,len);
cw_itemstore_set(conn->remote,a->item_id,a->itemtype,data,len);
return 0;
}

View File

@ -16,7 +16,6 @@ int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint
as.vendor_id = cw_get_dword(data);
as.elem_id = cw_get_word(data+4);
// printf("Vendor Specific: %d, %d\n",as.vendor_id,as.elem_id);
af = cw_actionlist_in_get(conn->actions->in,&as);
@ -27,8 +26,6 @@ int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint
return 0;
}
printf("Found\n");
if (af->start) {
af->start(conn,af,data+6,len-6);
}

View File

@ -96,7 +96,7 @@ int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * da
return 1;
}
cw_itemstore_t itemstore = conn->itemstore;
cw_itemstore_t itemstore = conn->remote;
cw_itemstore_set_dword(itemstore, CW_ITEM_WTP_BOARD_VENDOR,cw_get_dword(data));
readsubelems_wtp_board_data(itemstore,data+4,len-4);

View File

@ -34,7 +34,7 @@ static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, ui
if (len<6)
return -1;
cw_itemstore_t itemstore = conn->itemstore;
cw_itemstore_t itemstore = conn->remote;
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));

View File

@ -13,14 +13,21 @@ void cw_init(struct conn * conn, uint8_t *buffer, int type, int seqnum, struct r
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);
int shbytes = cw_get_hdr_msg_offset(req);
int dhbytes;
memcpy(buffer,req,shbytes);
cw_set_hdr_hlen(buffer,2);
cw_set_hdr_flags(buffer,CW_FLAG_HDR_M,1);
dhbytes = cw_get_hdr_msg_offset(buffer);
uint8_t * msgptr = req+hbytes;
uint8_t * dmsgptr = buffer+hbytes;
uint8_t * msgptr = req+shbytes;
uint8_t * dmsgptr = buffer+dhbytes;
cw_set_msg_type(dmsgptr,cw_get_msg_type(msgptr)+1);
cw_set_msg_seqnum(dmsgptr,cw_get_msg_seqnum(msgptr));

View File

@ -6,9 +6,9 @@
#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);
@ -16,10 +16,10 @@ printf("Vendor putter %d\n",vendor_id);
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)
int cw_out_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst)
{
uint8_t *d = dst+4;
@ -31,18 +31,14 @@ int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct
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));
d+=cw_put_ac_status(d ,(struct cw_ac_status*)(i->data));
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);
d += cw_put_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.");
@ -52,7 +48,7 @@ int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct
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);
d += cw_put_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.");
@ -60,7 +56,7 @@ int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct
int len = d-dst-4;
return len + cw_put_elem_hdr(dst,CW_ELEM_AC_DESCRIPTOR,len);
return len + cw_put_elem_hdr(dst,a->elem_id,len);
}

View File

@ -41,8 +41,10 @@ static int put_ip(void *priv, void *data)
}
int cw_out_capwap_control_ip_addrs(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)
int cw_out_capwap_control_ip_addrs(struct conn *conn,struct cw_action_out *a,uint8_t *dst)
{
struct cw_item * item = cw_itemstore_get(conn->local,a->item_id);
if ( !item ) {
cw_log(LOG_ERR, "Can't send CAPWAP Local IPv4/IPv6 Address, not found");
return 0;

View File

@ -9,27 +9,50 @@ 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 cw_put_dword(dst,item->dword);
}
return 0;
}
int cw_out_generic(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)
int cw_out_generic(struct conn *conn,struct cw_action_out *a,uint8_t *dst) // ,struct cw_item * item)
{
/* Get the item to put */
struct cw_item *item=NULL;
if (a->get){
item = a->get (conn,a);
}
printf("Out generic item %p\n",item);
/* Size for msg elem header depends on
vendor specific payload */
int start = a->vendor_id ? 10:4;
int len;
if ( !item )
len=0;
else
len = cw_put_item(dst+4,item);
return len + cw_put_elem_hdr(dst,elem_id,len);
else{
printf("Putting it\n");
printf("To put: %d %s\n",len,item->data);
len = cw_put_item(dst+start,item);
printf("Putted: %d %s\n",len,item->data);
}
if (a->vendor_id)
return len + cw_put_elem_vendor_hdr(dst,a->vendor_id,a->elem_id,len);
return len + cw_put_elem_hdr(dst,a->elem_id,len);
}

View File

@ -12,174 +12,26 @@
#include "dbg.h"
int snd_cb(void *c, void *d)
{
struct conn *conn = (struct conn *) c;
struct cw_action_in *a = (struct cw_action_in *) d;
if (a->start) {
a->start(conn, a, conn->resp_buffer, 0);
}
return 1;
}
extern int cw_init_response(struct conn *conn, uint8_t * req);
struct priv {
struct conn *conn;
uint8_t *buffer;
uint32_t msg_id;
int len;
};
int cw_additems_cb(void *p, void *i)
{
struct priv *priv = (struct priv *) p;
struct cw_item *item = (struct cw_item *) i;
printf("Item: %d - %d \n", priv->msg_id, item->id);
cw_action_out_t as;
as.item_id = item->id;
as.msg_id = priv->msg_id;
cw_action_out_t *a = cw_actionlist_out_get(priv->conn->actions->out, &as);
if (!a) {
printf("No out action found for %d\n", item->id);
return 1;
}
printf("Out action found\n");
return 1;
}
/*
int cw_additems( struct conn *conn,cw_itemstore_t itemstore)
{
struct priv priv;
priv.msg_id=CW_MSG_DISCOVERY_RESPONSE;
priv.conn=conn;
avltree_foreach_asc(itemstore, cw_additems_cb,&priv);
}
*/
int cb(void *p, void *ain)
{
cw_action_out_t *a = (cw_action_out_t *) ain;
struct priv *priv = (struct priv *) p;
if (priv->msg_id != a->msg_id)
return 0;
if (!a->item_id)
return 1;
printf("Put Msg ID %d (%s) - %d\n", a->msg_id, cw_strmsg(a->msg_id), a->elem_id);
struct cw_item *item = NULL;
if (a->get)
item = a->get(priv->conn, a->item_id);
int l = 0;
uint8_t *buffer = priv->buffer + priv->len;
printf("Writing to %p\n", buffer);
if (a->out) {
l = a->out(priv->conn, a->elem_id, buffer, item);
printf("The length is %d\n", l);
}
printf("+++++++++++++++++++Adding %d to privlen\n", l);
priv->len += l;
printf("Priveln is now %d\n", priv->len);
return 1;
}
//int cw_out_msg(struct conn *conn, uint8_t * rawout);
int conn_send_msg(struct conn *conn, uint8_t * rawmsg);
int cw_send_response(struct conn *conn, uint8_t * rawmsg, int len)
{
struct priv priv;
// struct priv priv;
cw_init_response(conn, rawmsg);
uint8_t *msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg);
// uint8_t *msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg);
cw_action_out_t as;
as.msg_id = cw_get_msg_type(msgptr) + 1;
as.item_id = CW_ITEM_NONE;
priv.msg_id = as.msg_id;
priv.conn = conn;
priv.len = 0;
priv.buffer = cw_get_hdr_msg_elems_ptr(conn->resp_buffer);
int off = cw_get_hdr_msg_offset(conn->resp_buffer);
printf("Offset is %d\n", off);
avltree_foreach_from_asc(conn->actions->out, &as, cb, &priv);
uint8_t *smptr = conn->resp_buffer + cw_get_hdr_msg_offset(conn->resp_buffer);
printf("Send Type: %d\n", cw_get_msg_type(smptr));
// cw_action_out_t as;
printf("The total msgelems length is %d\n", priv.len);
int offset = cw_get_hdr_msg_offset(conn->resp_buffer);
printf("Privlen = %d\n", priv.len);
cw_set_msg_elems_len(conn->resp_buffer + offset, priv.len);
int total = cw_get_hdr_msg_total_len(conn->resp_buffer);
printf("TOTAL lenz: %p %d\n", conn->resp_buffer, total);
cw_put_msg(conn,conn->resp_buffer);
conn_send_msg(conn, conn->resp_buffer);
return 1;
return 0;
/*
printf("The repoinse finder\n");
struct cw_action_in as,*af;
uint8_t * msg_ptr = rawmsg+cw_get_hdr_msg_offset(rawmsg);
as.msg_id = cw_get_msg_id(msg_ptr)+1;
if (as.msg_id & 1)
return 0;
printf("Message ID = %d\n",as.msg_id);
as.elem_id=0;
as.vendor_id=0;
as.proto=1;
as.capwap_state=1;
//avltree_foreach_from_asc(conn->msgtr, &as,snd_cb,conn);
printf("BLA\n");
*/
}
@ -248,7 +100,7 @@ int cw_process_msg(struct conn *conn, uint8_t * rawmsg, int len)
as.elem_id = cw_get_elem_id(elem);
int elem_len = cw_get_elem_len(elem);
cw_dbg_elem(as.msg_id, as.elem_id, cw_get_elem_data(elem), elem_len);
cw_dbg_elem(conn,as.msg_id, as.elem_id, cw_get_elem_data(elem), elem_len);
af = cw_actionlist_in_get(conn->actions->in, &as);

View File

@ -1,6 +1,6 @@
#include "capwap.h"
const char * cw_strlist_get_str(struct cw_strlist *s,int id)
const char * cw_strlist_get_str(struct cw_str *s,int id)
{
while ( s->id!=0){
if (s->id==id)

View File

@ -1,14 +1,14 @@
#ifndef __DBG_H
#define __DBG_H
#include "conn.h"
void cw_dbg_elem_(int msg, int msgelem, const uint8_t * msgbuf, int len);
void cw_dbg_elem_(struct conn * conn, 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)
#define cw_dbg_elem(conn,msgtype,msgelemtype,msgbuf,msglen) cw_dbg_elem_(conn,msgtype,msgelemtype,msgbuf,msglen)
#else