Initial commit

FossilOrigin-Name: c53d95729c009f8f80a7d63847cef7668ff73f8af0523ab65f7734696f85399c
This commit is contained in:
7u83@mail.ru
2014-07-11 20:12:11 +00:00
parent 3234327f71
commit 2bae9358d7
136 changed files with 11071 additions and 0 deletions

161
src/capwap/Makefile Normal file
View File

@ -0,0 +1,161 @@
#CC = gcc
AR = ar
SYSARCH := $(shell uname -m)
ifndef ARCH
ARCH=$(SYSARCH)
endif
NAME=libcapwap.a
SOCKOBJS=sock_create.o sock_copyaddr.o sock_strtoaddr.o sock_cmpaddr.o sock_addrlen.o \
sock_receive.o sock_mwait.o sock_mreceive.o sock_addrtostr.o \
sock_setport.o \
sock_getport.o \
sock_getifaddr.o \
sock_getifhwaddr.o \
sock_hwaddrtostr.o \
sock_set_recvtimeout.o \
sock_getbroadcastaddr.o \
sock_addrinit.o \
sock_set_dontfrag.o
LOGOBJS=cw_log.o \
cw_log_debug.o \
cw_log_tofile.o \
cw_log_tosyslog.o
WTPINFOOBJS = wtpinfo_set_location.o \
wtpinfo_print.o
UTILOBJS=cw_setstr.o \
cw_rand.o \
cw_pseudo_rand.o \
cw_foreach_msgelem.o \
avltree.o \
avltree_get.o \
avltree_del_all.o \
avltree_foreach.o \
stravltree.o
#capwap_parse_ctrlhdr.o \
CAPWAPOBJS= \
cwmsg_init.o \
cwmsg_init_echo_request.o \
cwmsg_addelem.o \
cwmsg_addelem_ac_descriptor.o \
cwmsg_addelem_wtp_descriptor.o \
cwmsg_addelem_ctrl_ip_addrs.o \
cwmsg_addelem_wtp_radio_infos.o \
cwmsg_addelem_wtp_board_data.o \
cwmsg_addelem_cw_local_ip_addr.o \
cwmsg_addelem_mtu_discovery_padding.o \
cwmsg_addelem_result_code.o \
cwmsg_send.o \
cwsend_discovery_response.o \
cwread_discovery_response.o \
cwsend_discovery_request.o \
cwsend_join_request.o \
cwsend_join_response.o \
cwread_join_response.o \
cwsend_echo_request.o \
cwsend_echo_response.o \
process_msgelems_discovery_request.o \
process_discovery_request.o \
process_join_request.o \
wtpinfo_readelem_wtp_board_data.o \
wtpinfo_readelem_wtp_mac_type.o \
wtpinfo_readelem_wtp_radio_info.o \
wtpinfo_readelem_wtp_descriptor.o \
wtpinfo_readelem_discovery_type.o \
wtpinfo_readelem_wtp_frame_tunnel_mode.o \
wtpinfo_readelem_location_data.o \
wtpinfo_readelem_wtp_name.o \
wtpinfo_readelem_session_id.o \
wtpinfo.o \
aciplist.o \
acinfo.o \
acinfo_print.o
# cwmsg_set_control_header.o
# process_msgelems.o \
DTLSOBJS= dtls_openssl.o \
dtls_openssl_accept.o \
dtls_openssl_connect.o \
dtls_openssl_bio.o
CONNOBJS= conn.o \
conn_send_packet.o \
conn_send_cwmsg.o \
conn_process_packet.o \
conn_get_message.o \
conn_q_add_packet.o \
conn_q_get_packet.o \
conn_q_recv_packet.o \
conn_recv_packet.o \
connlist.o
FRAGOBJS=fragman.o
OBJS=$(CONNOBJS) $(FRAGOBJS) $(SOCKOBJS) $(CAPWAPOBJS) $(WTPINFOOBJS) $(LOGOBJS) $(UTILOBJS) $(DTLSOBJS)
O:=$(OBJS);
OBJS:=$(patsubst %.o,$(ARCH)/%.o,$(OBJS))
#CFLAGS = -Wall -g -O3 -D_REENTRANT -DWITH_IPV6
CFLAGS = -Wall -g -O0 -D_REENTRANT -DWITH_IPV6 -DWITH_RMAC_SUPPORT
CFLAGS += -DWITH_CW_LOG \
-DWITH_CW_LOG_DEBUG \
-DWITH_DTLS \
#SRCS = $(OBJS:.o=.c)
$(ARCH)/%.o:%.c
@mkdir -p $(ARCH)
@echo " CC "$<
@$(CC) -c $(CFLAGS) $< -o $@
$(ARCH)/$(NAME) : $(OBJS)
@echo " AR $(ARCH)/$(NAME)"
@$(AR) rcs $(ARCH)/$(NAME) $(OBJS)
#$(OBJS)
#.c.o:
# $(CC) -c $(CFLAGS) $<
SRCS = $(OBJS:.o=.c)
DEPS := $(OBJS:.o=.d)
.PHONY: deps clean clean_libs libs
# top-level rule, to compile everything.
all: $(ARCH)/$(NAME)
clean:
$(RM) $(OBJS)
$(RM) $(DEPS)
clean_deps:
$(DEPS)
deps: $(SRCS)
$(CC) -MD -E $(SRCS) $(CFLAGS) >/dev/null
-include $(DEPS)

166
src/capwap/acinfo.c Normal file
View File

@ -0,0 +1,166 @@
/*
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 <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include "capwap.h"
#include "cw_log.h"
#include "cw_util.h"
#include "acinfo.h"
int acinfo_readelem_ac_name(struct ac_info * acinfo,int type, uint8_t *msgelem, int len)
{
if (type != CWMSGELEM_AC_NAME)
return 0;
cw_setstr(&acinfo->ac_name,msgelem,len);
return 1;
}
int acinfo_readelem_ac_descriptor(struct ac_info * acinfo,int type, uint8_t *msgelem, int len)
{
if (type != CWMSGELEM_AC_DESCRIPTOR)
return 0;
if (len<12)
return -1;
uint32_t val;
/* read stations and limit */
val = ntohl(*((uint32_t*)msgelem));
acinfo->stations = val>>16;
acinfo->limit = val&0xffff;
/* read active wtps and max wtps */
val = ntohl(*((uint32_t*)(msgelem+4)));
acinfo->active_wtps = val>>16;
acinfo->max_wtps = val&0xffff;
/* read active wtps and max wtps */
val = ntohl(*((uint32_t*)(msgelem+8)));
acinfo->security = val >>24;
acinfo->rmac= (val >> 16)&0xff;
acinfo->dtls_policy=val&0xf;
int sub=12;
int sublen;
while (sub<len){
if (len-sub<8)
return -1;
uint32_t vendor = ntohl(*((uint32_t*)(msgelem+sub)));
val = ntohl(*((uint32_t*)(msgelem+sub+4)));
sublen = val&0xffff;
sub+=8;
if (vendor != 0){
sub+=sublen;
continue;
}
int subtype = val>>16;
if (sub+sublen>len)
return -1;
switch (subtype){
case 4:
cw_setstr(&acinfo->hardware_version,msgelem+sub,sublen);
break;
case 5:
cw_setstr(&acinfo->software_version,msgelem+sub,sublen);
break;
}
sub+=sublen;
}
return 1;
}
int acinfo_readelem_ctrl_ip_addr(struct ac_info * acinfo, int type, uint8_t*msgelem,int len)
{
switch (type){
case CWMSGELEM_CONTROL_IPV4_ADDRESS:
{
if (len!=6)
return -1;
if (!acinfo->aciplist)
return 1;
ACIP * acip = malloc(sizeof(ACIP));
if (!acip) {
cw_log(LOG_ERR,"Can't allocate memory for acv4ip: %s",strerror(errno));
return 1;
}
struct sockaddr_in addr;
memcpy(&addr.sin_addr,msgelem,4);
addr.sin_family=AF_INET;
memcpy(&acip->ip,&addr,sizeof(addr));
acip->wtp_count = ntohs( * ((uint16_t*)(msgelem+4)));
aciplist_add(acinfo->aciplist,acip);
return 1;
}
case CWMSGELEM_CONTROL_IPV6_ADDRESS:
{
if (len!=18)
return -1;
if (!acinfo->aciplist)
return 1;
ACIP * acip = malloc(sizeof(ACIP));
if (!acip) {
cw_log(LOG_ERR,"Can't allocate memory for acv4ip: %s",strerror(errno));
return 1;
}
struct sockaddr_in6 addr;
memcpy(&addr.sin6_addr,msgelem,16);
addr.sin6_family=AF_INET6;
memcpy(&acip->ip,&addr,sizeof(addr));
acip->wtp_count = ntohs( * ((uint16_t*)(msgelem+16)));
aciplist_add(acinfo->aciplist,acip);
return 1;
}
}
return 0;
}

62
src/capwap/acinfo.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef __ACINFO_H
#define __ACINFO_H
#include <stdint.h>
#include <sys/socket.h>
#include "avltree.h"
struct acip{
struct sockaddr_storage ip;
int wtp_count;
};
typedef struct acip ACIP;
typedef struct avltree ACIPLIST;
ACIPLIST * aciplist_create();
#define aciplist_destroy(l) avltree_destroy(l)
#define aciplist_add(l,elem) avltree_add(l,elem)
#define aciplist_foreach(l,callback,cbpriv) avltree_foreach(l,callback,cbpriv,1)
/* structure to hold info about an ac */
struct ac_info{
int stations;
int limit;
int active_wtps;
int max_wtps;
uint8_t * ac_name;
int ac_name_len;
int security;
int rmac;
int dtls_policy;
int vendor_id;
uint8_t * hardware_version;
uint8_t * software_version;
// const char * acname;
struct sockaddr * salist;
int salist_len;
ACIPLIST * aciplist;
uint8_t ecn_support;
struct sockaddr_storage local_ip;
};
typedef struct ac_info ACINFO;
extern int acinfo_readelem_ac_name(struct ac_info * acinfo,int type, uint8_t *msgelem, int len);
extern int acinfo_readelem_ac_descriptor(struct ac_info * acinfo,int type, uint8_t *msgelem, int len);
extern int acinfo_readelem_ctrl_ip_addr(struct ac_info * acinfo, int type, uint8_t*msgelem,int len);
extern int acinfo_print(char *str,const struct ac_info *acinfo);
#define acinfo_readelem_ecn_support(acinfo,type,msg,len) cw_readelem_ecn_support(&acinfo->ecn_support,type,msg,len)
#define acinfo_readelem_cw_local_ip_addr(acinfo,type,msg,len) cw_readelem_cw_local_ip_addr(&acinfo->local_ip,type,msg,len)
#endif

59
src/capwap/acinfo_print.c Normal file
View File

@ -0,0 +1,59 @@
#include <string.h>
#include <stdio.h>
#include "capwap.h"
#include "sock.h"
#include "acinfo.h"
int acinfo_print(char *str,const struct ac_info *acinfo)
{
char *s = str;
s+=sprintf(s,"\tAC name: %s\n",acinfo->ac_name);
s+=sprintf(s,"\tHardware version: %s\n",acinfo->hardware_version);
s+=sprintf(s,"\tSoftware version: %s\n",acinfo->software_version);
s+=sprintf(s,"\tStations: %i\n",acinfo->stations);
s+=sprintf(s,"\tSation limit: %i\n",acinfo->limit);
s+=sprintf(s,"\tActive WTPs: %i\n",acinfo->active_wtps);
s+=sprintf(s,"\tMax WTPs: %i\n",acinfo->max_wtps);
char help[64];
sock_addrtostr((struct sockaddr*)&acinfo->local_ip,help,64);
s+=sprintf(s,"\tLocal IP: %s\n",help);
s+=sprintf(s,"\tECN support: %s\n",acinfo->ecn_support==0 ? "limited" : "full");
s+=sprintf(s,"\tRMAC support: %s\n",acinfo->rmac==2 ? "supported" : "not supported");
help[0]=0;
if (acinfo->security & AC_SECURITY_S)
strcpy(help,"psk");
if (acinfo->security & AC_SECURITY_X){
if (strlen(help))
strcat(help,"/");
strcat(help,"X.509");
}
if (!strlen(help))
strcpy(help,"None");
s+=sprintf(s,"\tSecurity: %s\n",help);
help[0]=0;
if (acinfo->dtls_policy & AC_DTLS_POLICY_D){
strcpy(help,"dtls");
}
if (acinfo->dtls_policy & AC_DTLS_POLICY_C){
if(strlen(help))
strcat(help,"/");
strcat(help,"clear");
}
if (!strlen(help))
strcpy(help,"Not set");
s+=sprintf(s,"\tDTLS policy: %s\n",help);
return s-str;
}

53
src/capwap/aciplist.c Normal file
View File

@ -0,0 +1,53 @@
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "acinfo.h"
#include "avltree.h"
#include "sock.h"
static int acip_cmp(const void *x1, const void *x2)
{
struct acip * ip1 = (struct acip*)x1;
struct acip * ip2 = (struct acip*)x2;
if (ip1->ip.ss_family != ip2->ip.ss_family){
if (ip1->ip.ss_family == AF_INET)
return -1;
else
return 1;
}
if (ip1->ip.ss_family == AF_INET){
struct sockaddr_in * s2=(struct sockaddr_in*)&ip2->ip;
struct sockaddr_in * s1=(struct sockaddr_in*)&ip1->ip;
return memcmp(&s1->sin_addr,&s2->sin_addr,sock_addrlen((struct sockaddr*)s1));
}
if (ip1->ip.ss_family == AF_INET6){
struct sockaddr_in6 * s2=(struct sockaddr_in6*)&ip2->ip;
struct sockaddr_in6 * s1=(struct sockaddr_in6*)&ip1->ip;
return memcmp(&s1->sin6_addr.s6_addr,&s2->sin6_addr.s6_addr,sock_addrlen((struct sockaddr*)s1));
}
return -1;
}
static void acip_del(void*d)
{
free(d);
}
ACIPLIST * aciplist_create()
{
struct avltree *t = avltree_create(acip_cmp,acip_del);
return t;
}

669
src/capwap/avltree.c Normal file
View File

@ -0,0 +1,669 @@
/*
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 <stdlib.h>
#include <stdio.h>
#include "avltree.h"
struct avltree * avltree_create(int (*cmp)(const void*,const void*),void(*del)(void*))
{
struct avltree * t = malloc(sizeof(struct avltree));
if (!t)
return 0;
t->root=0;
t->count=0;
t->cmp=cmp;
t->del=del;
return t;
}
struct avlnode * avlnode_create(void * data)
{
struct avlnode * n = malloc(sizeof(struct avlnode));
if(!n)
return 0;
n->left=n->right=0;
n->bal=0;
n->data = data;
return n;
}
void avlnode_destroy(struct avltree *t,struct avlnode *n)
{
if(t->del){
t->del(n->data);
}
free(n);
t->count--;
}
static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** data)
{
// struct avlnode * rn;
struct avlnode *tmp;
struct avlnode * n = *parent;
int rc=t->cmp(*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)
return bal;
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;
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;
}
(*parent)->bal=0;
n->left->right=(*parent)->left;
(*parent)->left=n->left;
tmp = (*parent)->right;
(*parent)->right=n;
n->left=tmp;
return 0;
}
//printf("!!!!left bal = %i\n",n->left->bal);
//exit(0);
}
return bal;
}
/* n->left is 0 */
n->left=avlnode_create(*data);
if (!n->left)
return 3;
t->count++;
if(n->right==0){
n->bal=-1;
return 1;
}
n->bal=0;
return 0;
}
else{
if (n->right){
bal = avltree_add0(t,&n->right,data);
if(bal>1)
return bal;
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;
return 0;
}
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;
}
(*parent)->bal=0;
n->right->left=(*parent)->right;
(*parent)->right=n->right;
tmp = (*parent)->left;
(*parent)->left=n;
n->right=tmp;
return 0;
}
//printf("!!!!iright bal = %i\n",n->left->bal);
//exit(0);
}
return bal;
}
/* n->right is 0 */
n->right=avlnode_create(*data);
if (!n->right)
return 3;
t->count++;
if(n->left==0){
n->bal=1;
return 1;
}
n->bal=0;
return 0;
}
}
void * avltree_add(struct avltree *t, void * data)
{
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);
if (rc>3)
return 0;
return d;
}
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;
}
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;
}
/*
* Delete the node withe the highest value
* returns the rebalancing factor
*/
/*
static int avltree_delete_hi(struct avlnode **parent, void **data)
{
struct avlnode * n = *parent;
if(n->right!=0){
int bal = avltree_delete_hi(&n->right,data);
n->bal-=bal;
if (n->bal==-2){
// if (rotate_r(n,parent))
// return 0;
}
return bal;
}
*parent=n->left;
*data = n->data;
if (n->left){
free(n);
return 0;
}
free(n);
return 1;
}
*/
struct avltree * trrr;
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;
tmp = (*parent)->left;
(*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;
tmp = (*parent)->right;
(*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);
return 1;
}
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);
return 1;
}
// printf("adj bal l not handled \n");
// exit(0);
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);
return 1;
}
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);
return 1;
}
// printf("adj bal li left not handled \n");
// exit(0);
return -11; /* that should never happen */
}
static int avltree_del_lo(struct avlnode **parent, void **data)
{
struct avlnode * n = *parent;
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)
return bal;
adj_bal_l(n,parent);
return 0;
}
/* found the lowest element */
*parent=n->right;
*data = n->data;
free (n);
return 1;
if (n->right){
free(n);
return 1;
}
free(n);
return 1;
}
int avltree_del0(struct avltree *t, struct avlnode **parent, void **data)
{
struct avlnode * n = *parent;
int rc;
int bal;
rc =t->cmp(*data,n->data);
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);
return 1;
}
if (n->left && n->right==0){
avlnode_destroy(t,n);
*parent=n->left;
return 1;
}
/* node has two childs */
if (t->del){
t->del(n->data);
}
t->count--;
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);
}
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)
return 0;
if (n->bal!=2)
return bal;
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;
n->bal-=bal;
if (n->bal==-1)
return 0;
if (n->bal != -2)
return bal;
return adj_bal_r(n,parent);
}
return 2; /* not found */
}
}
void * avltree_del(struct avltree *t, void *data)
{
void *d = data;
int rc = avltree_del0(t,&t->root,&d);
if (rc==2)
return 0;
return data;
}
/*
static int cmp(const void *k1,const void *k2)
{
int x1 = *((int*)k1);
int x2 = *((int*)k2);
return x1-x2;
}
*/
//int data[]={10,37,60,10,5,35,36,26,3,11,18};
//int data[] = {100,50,75};
//int data[]={100,200,150,300,400};
//int data[]={100,200,150,170,470};
//int data[]={10,20,15,17,47,50,60,70,80};
//int data[]={9,8,7,6,5,4,3,2,1,0};
//int data[]={10,37,60,10,5,35,19,26,3,11,18};
//int data[]={0,11,14,33,37,20};
//int data[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
//int data[]={1,4,3,7,5,6,7,8,9,10};
//int data[]={11,4,5,6,3,4,3,2,1,0};
//int data[]={20,16,10,11,5,4,3,2,1,0};
/*
struct avlnode * ar[10000];
int tpw = 80;
static void print_tree0(struct avlnode * n,int d,int l,int r)
{
int pos = l+(r-l)/2;
ar[d*tpw+pos]=n;
if (n->right)
print_tree0(n->right,d+1,l+(r-l)/2,r);
if(n->left)
print_tree0(n->left,d+1,l,r-(r-l)/2);
}
void avltree_print(struct avlnode * n )
{
int y;
int i=0;
for(i=0; i<10000; i++)
ar[i]=0;
if (n==0){
printf("Empty Tree\n");
return ;
}
print_tree0(n,0,0,tpw);
for (i=0; i<10; i++) {
for (y=0; y<tpw; y++){
struct avlnode *r=ar[tpw*i+y];
if(r){
printf("%i(%i)",*(int*)(r->data),r->bal);
}
else{
printf(".");
}
}
printf("\n");
}
}
void walk(struct avlnode *n)
{
if (n == 0)
return;
walk(n->left);
int x = *((int*)(n->data));
printf("VAL: %i\n",x);
walk(n->right);
// x = *((int*)(n->data));
// printf("VALR: %i\n",x);
}
*/
void avltree_destroy(struct avltree *t)
{
avltree_del_all(t);
free (t);
}
//#include <time.h>
/*
//int data[]={5,1,9,7,0,10,8,0,4,3};
//int data[]={50,10,90,70,00,100,80,00,40,30,1,2,3};
int data[]={10,20,30,45,1,50,11,51,60,70,80,90,99,25,50,10,90,70,00,100,80,00,40,30,1,2,3};
int main()
{
struct avltree *t = avltree_create(cmp,0);
trrr=t;
printf("T: %p\n",t);
srand(time(NULL));
int i=0;
for (i=0; i<6; i++)
{
int r = rand()%0x3f; // % 0xiff;
// int r = rand(); //%0x3f; // % 0xiff;
// r = data[7-i];
r = data[i];
int * dr = malloc(sizeof(int));
*dr = r;
printf("Insert %i\n",*dr);
void * d = avltree_insert(t,dr);
printf("After insert %i\n",r);
print_tree(t->root);
if (d!=dr){
// printf("exists\n");
}
}
printf("Here it is\n");
print_tree(t->root);
// walk(t->root);
void * da;
int x = 110;
// void * drc = avltree_delete(t,&x);
avltree_delete_all(t);
// printf("Delete 110 rc = %p\n",drc);
print_tree(t->root);
printf("Count: %i\n",t->count);
return 0;
}
*/

64
src/capwap/avltree.h Normal file
View File

@ -0,0 +1,64 @@
/*
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/>.
*/
/*
* yet another avl tree implementation!
*/
#ifndef __AVLTREE_H
#define __AVLTREE_H
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*);
int count;
};
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);
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_get(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);
extern void avltree_foreach(struct avltree *t, int (*callback)(void *,void*),void *cbpriv,int dir);
#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)
#endif

564
src/capwap/avltree.old.c Normal file
View File

@ -0,0 +1,564 @@
/*
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 <stdlib.h>
#include <stdio.h>
#include "avltree.h"
/*
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*);
int count;
};
*/
struct avltree * avltree_create(int (*cmp)(const void*,const void*),void(*del)(void*))
{
struct avltree * t = malloc(sizeof(struct avltree));
if (!t)
return 0;
t->root=0;
t->count=0;
t->cmp=cmp;
t->del=del;
return t;
}
struct avlnode * avlnode_create(void * data)
{
struct avlnode * n = malloc(sizeof(struct avlnode));
if(!n)
return 0;
n->left=n->right=0;
n->bal=0;
n->data = data;
return n;
}
int avltree_insert0(struct avltree *t, struct avlnode ** parent, void ** data)
{
// struct avlnode * rn;
struct avlnode *tmp;
struct avlnode * n = *parent;
int rc=t->cmp(*data,n->data);
int bal;
if (rc==0){
*data=n->data;
return 2;
}
if (rc<0){
if (n->left)
{
bal = avltree_insert0(t,&n->left,data);
if (bal>1)
return bal;
printf("Left ret bal %i\n",bal);
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;
// printf("Left rot a\n");
// print_tree(t->root);
return 0;
}
if (n->left->bal==1){
printf("BUMBUMBUM\n");
print_tree(t->root);
// n->bal=0;
// n->left->bal=0;
*parent=n->left->right;
if ((*parent)->bal==1) {
n->bal=0;
n->left->bal=-1;
}
else{
n->bal=1;
n->left->bal=0;
}
(*parent)->bal=0;
n->left->right=(*parent)->left;
(*parent)->left=n->left;
tmp = (*parent)->right;
(*parent)->right=n;
n->left=tmp;
printf("Left rot b\n");
// print_tree(t->root);
return 0;
}
print_tree(t->root);
printf("!!!!left bal = %i\n",n->left->bal);
exit(0);
}
return bal;
}
/* n->left is 0 */
n->left=avlnode_create(*data);
if (!n->left)
return 3;
t->count++;
if(n->right==0){
n->bal=-1;
return 1;
}
n->bal=0;
return 0;
}
else{
if (n->right){
bal = avltree_insert0(t,&n->right,data);
if(bal>1)
return bal;
printf("Right ret bal %i\n",bal);
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;
// printf("Right rot a\n");
// print_tree(t->root);
return 0;
}
else {
printf("Right rot b before\n");
// print_tree(t->root);
n->bal=0;
n->right->bal=0;
*parent=n->right->left;
(*parent)->bal=0;
n->right->left=(*parent)->right;
(*parent)->right=n->right;
tmp = (*parent)->left;
(*parent)->left=n;
n->right=tmp;
// printf("Right rot b\n");
// print_tree(t->root);
return 0;
}
}
return bal;
}
/* n->right is 0 */
n->right=avlnode_create(*data);
if (!n->right)
return 3;
t->count++;
if(n->left==0){
n->bal=1;
return 1;
}
n->bal=0;
return 0;
}
}
void * avltree_insert(struct avltree *t, void * data)
{
if (t->root==0){
t->root = avlnode_create(data);
return t->root->data;
}
void * d = data;
int rc = avltree_insert0(t,&t->root,&d);
if (rc>3)
return 0;
return d;
// printf("RC %i\n",rc);
}
static int rotate_r(struct avlnode *n, struct avlnode **parent)
{
if (n->bal!=-2)
return 0;
struct avlnode * tmp;
if (n->bal==-1){
n->bal=0;
n->left->bal=0;
*parent=n->left;
tmp=n->left->right;
n->left->right=n;
n->left=tmp;
return 1;
}
else /* if (n->left->bal==1)*/ {
n->bal=0;
n->left->bal=0;
*parent=n->left->right;
n->left->right=(*parent)->left;
(*parent)->left=n->left;
tmp = (*parent)->right;
(*parent)->right=n;
n->left=tmp;
return 1;
}
}
static int rotate_l(struct avlnode *n, struct avlnode **parent)
{
if (n->bal!=2)
return 0;
struct avlnode * tmp;
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 1;
}
else { /* n->bal musst be -1 */
n->bal=0;
n->right->bal=0;
*parent=n->right->left;
n->right->left=(*parent)->right;
(*parent)->right=n->right;
tmp = (*parent)->left;
(*parent)->left=n;
n->right=tmp;
return 1;
}
}
/*
* Delete the node withe the highest value
* returns the rebalancing factor
*/
static int avltree_delete_hi(struct avlnode **parent, void **data)
{
struct avlnode * n = *parent;
if(n->right!=0){
int bal = avltree_delete_hi(&n->right,data);
n->bal-=bal;
if (rotate_r(n,parent))
return 0;
return bal;
}
*parent=n->left;
*data = n->data;
if (n->left){
free(n);
return 0;
}
free(n);
return 1;
}
static int avltree_delete_lo(struct avlnode **parent, void **data)
{
struct avlnode * n = *parent;
if(n->left!=0){
int bal = avltree_delete_lo(&n->left,data);
n->bal+=bal;
if (rotate_l(n,parent))
return 0;
return bal;
}
*parent=n->right;
*data = n->data;
if (n->right){
free(n);
return 0;
}
free(n);
return 1;
}
int avltree_delete0(struct avltree *t, struct avlnode **parent, void **data)
{
struct avlnode * n = *parent;
int rc;
rc =t->cmp(*data,n->data);
if (rc==0){
if (n->right == 0 && n->left ==0){
printf("My case a!\n");
*parent=0;
return 1;
}
if (n->right && n->left==0){
printf("My case b!\n");
*parent=n->right;
return 1;
}
if (n->left && n->right==0){
printf("My case c!\n");
*parent=n->left;
return 1;
}
}
int bal;
if (rc<0){
if (n->left)
{
bal = avltree_delete0(t,&n->left,data);
printf("Ballla = %i\n",bal);
n->bal+=bal;
if (!rotate_l(n,parent))
return bal;
return bal;
}
}
else {
if (n->right){
printf("Bolla\n");
bal = avltree_delete0(t,&n->right,data);
n->bal-=bal;
if (!rotate_r(n,parent))
return bal;
return bal;
}
}
return 0;
}
void * avltree_delete(struct avltree *t, void *data)
{
void *d = data;
printf("deletelel %p\n",d);
avltree_delete0(t,&t->root,&d);
return 0;
}
static int cmp(const void *k1,const void *k2)
{
int x1 = *((int*)k1);
int x2 = *((int*)k2);
return x1-x2;
}
int data[]={10,37,60,10,5,35,36,26,3,11,18};
//int data[]={10,37,60,10,5,35,19,26,3,11,18};
//int data[]={0,11,14,33,37,20};
//int data[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
//int data[]={1,4,3,7,5,6,7,8,9,10};
//int data[]={11,4,5,6,3,4,3,2,1,0};
//int data[]={20,16,10,11,5,4,3,2,1,0};
struct avlnode * ar[10000];
int tpw = 100;
void print_tree0(struct avlnode * n,int d,int l,int r)
{
int pos = l+(r-l)/2;
ar[d*tpw+pos]=n;
if (n->right)
print_tree0(n->right,d+1,l+(r-l)/2,r);
if(n->left)
print_tree0(n->left,d+1,l,r-(r-l)/2);
}
void print_tree(struct avlnode * n )
{
int y;
int i=0;
for(i=0; i<10000; i++)
ar[i]=0;
if (n==0){
printf("Empty Tree\n");
return 0;
}
print_tree0(n,0,0,tpw);
for (i=0; i<10; i++) {
for (y=0; y<tpw; y++){
struct avlnode *r=ar[tpw*i+y];
if(r){
printf("%i(%i)",*(int*)(r->data),r->bal);
}
else{
printf(".");
}
}
printf("\n");
}
}
void walk(struct avlnode *n)
{
if (n == 0)
return;
walk(n->left);
int x = *((int*)(n->data));
printf("VAL: %i\n",x);
walk(n->right);
// x = *((int*)(n->data));
// printf("VALR: %i\n",x);
}
#include <time.h>
int main()
{
struct avltree *t = avltree_create(cmp,0);
printf("T: %p\n",t);
srand(time(NULL));
int i=0;
for (i=0; i<7; i++)
{
int r = rand()%0x3f; // % 0xiff;
r = data[7-i];
int * dr = malloc(sizeof(int));
*dr = r;
printf("Insert %i\n",*dr);
void * d = avltree_insert(t,dr);
printf("After insert %i\n",r);
print_tree(t->root);
if (d!=dr){
// printf("exists\n");
}
}
print_tree(t->root);
walk(t->root);
void * da;
// avltree_delete(t,&data[4]);
avltree_delete_hi(&t->root,&da);
// printf("after del\n");
// print_tree(t->root);
// avltree_delete(t,&data[7]);
avltree_delete_lo(&t->root,&da);
// printf("after del\n");
// print_tree(t->root);
// avltree_delete(t,&data[5]);
avltree_delete_lo(&t->root,&da);
// printf("after del\n");
// print_tree(t->root);
return 0;
}

View File

@ -0,0 +1,36 @@
/*
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 "avltree.h"
static void avltree_del_all0(struct avltree *t ,struct avlnode * n)
{
if (!n)
return;
avltree_del_all0(t,n->left);
avltree_del_all0(t,n->right);
avlnode_destroy(t,n);
}
void avltree_del_all(struct avltree *t)
{
avltree_del_all0(t,t->root);
t->root=0;
}

View File

@ -0,0 +1,51 @@
/*
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 "avltree.h"
int avltree_foreach_lr(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv)
{
if (!n)
return 1;
if (!avltree_foreach_lr(n->left,callback,cbpriv))
return 0;
if (!callback(cbpriv,n->data))
return 0;
return avltree_foreach_lr(n->right,callback,cbpriv);
}
int avltree_foreach_rl(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv)
{
if (!n)
return 1;
if (!avltree_foreach_rl(n->right,callback,cbpriv))
return 0;
if (!callback(cbpriv,n->data))
return 0;
return avltree_foreach_rl(n->left,callback,cbpriv);
}
void avltree_foreach(struct avltree *t, int (*callback)(void *,void *),void * cbpriv,int dir)
{
if (dir)
avltree_foreach_lr(t->root,callback,cbpriv);
else
avltree_foreach_rl(t->root,callback,cbpriv);
}

37
src/capwap/avltree_get.c Normal file
View File

@ -0,0 +1,37 @@
/*
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 "avltree.h"
void * avltree_get(struct avltree *t ,void *data)
{
struct avlnode *n = t->root;
while(n){
int rc=t->cmp(data,n->data);
if (rc==0)
return n->data;
if (rc<0)
n=n->left;
else
n=n->right;
}
return 0;
}

338
src/capwap/capwap.h Normal file
View File

@ -0,0 +1,338 @@
/*
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/>.
*/
#ifndef __CAPWAP_H
#define __CAPWAP_H
#include <stdint.h>
#include <arpa/inet.h>
#include "conn.h"
/* capwap version and iana number */
#define CW_VERSION 0
#define CWIANA_ENTERPRISE_NUMBER 13277
/* ports */
#define CAPWAP_CONTROL_PORT 5246
#define CAPWAP_CONTROL_PORT_STR "5246"
/* transport header flags */
#define CWTH_FLAGS_R1 0x01 /* bit 0 reserved 1 */
#define CWTH_FLAGS_R2 0x02 /* bit 1 reserved 2 */
#define CWTH_FLAGS_R3 0x04 /* bit 2 reserved 3 */
#define CWTH_FLAGS_K 0x08 /* bit 3 Keep alive flag */
#define CWTH_FLAGS_M 0x10 /* bit 4 MAC Adress field present*/
#define CWTH_FLAGS_W 0x20 /* bit 5 wireless info present */
#define CWTH_FLAGS_L 0x40 /* bit 6 last fragment */
#define CWTH_FLAGS_F 0x80 /* bit 7 fragment */
#define CWTH_FLAGS_T 0x100 /* bit 8 type of payload frame */
/* wireless binding ids */
#define CWTH_WBID_RESERVED1 0
#define CWTH_WBID_IEEE80211 1
#define CWTH_WBID_RESERVED2 2
#define CWTH_WBID_EPCGLOBAL 3
/* generic macroto to isolate bits from a dword */
#define CW_GET_DWORD_BITS(src,start,len) ((~(0xFFFFFFFF<<len)) & (src >> (32 - start - len)))
/* macros to acces transport header values */
#define CWTH_GET_PREAMBLE(th) (th[0])
//(ntohl(((uint32_t*)th)[0]) >> 24)
#define CWTH_GET_FRAGID(th) ((ntohl((((uint32_t*)th)[1]) >> 16) & 0xffff))
#define CWTH_GET_FRAGOFFSET(th) ((ntohl((((uint32_t*)th)[1]) >> 3) & 0x1fff))
#define CWTH_GET_RID(th) ((ntohl((((uint32_t*)th)[0]) >> 14) & 0x1f))
#define CWTH_GET_WBID(th) ((ntohl(((uint32_t*)th)[0]) >> 9) & 0x1f)
#define CWTH_GET_HLEN(th) ((ntohl(((uint32_t*)th)[0]) >> 19) & 0x1f)
#define CAPWAP_PACKET_PREAMBLE (CW_VERSION<<4)
#define CAPWAP_DTLS_PACKET_PREAMBLE (CW_VERSION<<4|1)
/*
* control header stuff
*/
struct capwap_ctrlhdr
{
int msgtype;
int seqnum;
int flags;
uint8_t * msgelems;
int msgelemslen;
};
//extern int capwap_parse_trnsprthdr(struct capwap_trnsprthdr * cwh,uint8_t *msg, int msglen);
//extern int capwap_parse_ctrlhdr(struct capwap_ctrlhdr * ch,uint8_t * msg, int len);
/* CAPWAP message types as defined in RFC 5416 */
#define CWMSG_DISCOVERY_REQUEST 1
#define CWMSG_DISCOVERY_RESPONSE 2
#define CWMSG_JOIN_REQUEST 3
#define CWMSG_JOIN_RESPONSE 4
/* Configuration Status Request 5
Configuration Status Response 6
Configuration Update Request 7
Configuration Update Response 8
WTP Event Request 9
WTP Event Response 10
Change State Event Request 11
Change State Event Response 12
*/
#define CWMSG_ECHO_REQUEST 13
#define CWMSG_ECHO_RESPONSE 14
/* Image Data Request 15
Image Data Response 16
*/
#define CWMSG_RESET_REQUEST 17
#define CWMSG_RESET_RESPONSE 18
/*
Reset Request 17
Reset Response 18
*/
#define CWMSG_PRIMARY_DISCOVERY_REQUEST 19
#define CWMSG_PRIMARY_DISCOVERY_RESPONSE 20
/* Data Transfer Request 21
Data Transfer Response 22
Clear Configuration Request 23
Clear Configuration Response 24
Station Configuration Request 25
Station Configuration Response 26
*/
#define CWMSG_MAXMSG 26
/*
* CAPWAP message elements as defined in RFC 5416
*/
#define CWMSGELEM_AC_DESCRIPTOR 1
/* AC IPv4 List 2
AC IPv6 List 3
*/
#define CWMSGELEM_AC_NAME 4
/*
AC Name with Priority 5
AC Timestamp 6
Add MAC ACL Entry 7
Add Station 8
Reserved 9
*/
#define CWMSGELEM_CONTROL_IPV4_ADDRESS 10
#define CWMSGELEM_CONTROL_IPV6_ADDRESS 11
#define CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS 30
#define CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS 50
/* CAPWAP Timers 12
CAPWAP Transport Protocol 51
Data Transfer Data 13
Data Transfer Mode 14
Decryption Error Report 15
Decryption Error Report Period 16
Delete MAC ACL Entry 17
Delete Station 18
Reserved 19
*/
#define CWMSGELEM_DISCOVERY_TYPE 20
/*
Duplicate IPv4 Address 21
Duplicate IPv6 Address 22
*/
#define CWMSGELEM_ECN_SUPPORT 53
/* Idle Timeout 23
Image Data 24
Image Identifier 25
Image Information 26
Initiate Download 27
*/
#define CWMSGELEM_LOCATION_DATA 28
#define CWMSGELEM_MAXIMUM_MESSAGE_LENGTH 29
#define CWMSGELEM_MTU_DISCOVERY_PADDING 52
/* Radio Administrative State 31
Radio Operational State 32
*/
#define CWMSGELEM_RESULT_CODE 33
/* Returned Message Element 34
*/
#define CWMSGELEM_SESSION_ID 35
/* Statistics Timer 36
Vendor Specific Payload 37
*/
#define CWMSGELEM_WTP_BOARD_DATA 38
#define CWMSGELEM_WTP_DESCRIPTOR 39
/* WTP Fallback 40
*/
#define CWMSGELEM_WTP_FRAME_TUNNEL_MODE 41
/*
Reserved 42
*/
/*
Reserved 43
*/
#define CWMSGELEM_WTP_MAC_TYPE 44
#define CWMSGELEM_WTP_NAME 45
/*
Unused/Reserved 46
WTP Radio Statistics 47
WTP Reboot Statistics 48
WTP Static IP Address Information 49
*/
/* wtp board data subelements */
#define CWBOARDDATA_MODELNO 0
#define CWBOARDDATA_SERIALNO 1
#define CWBOARDDATA_BOARDID 2
#define CWBOARDDATA_REVISION 3
#define CWBOARDDATA_MACADDRESS 4
/* */
#define CWACSECURITY_FLAGS_R 1 /* Reserved */
#define CWACSECURITY_FLAGS_S 2 /* DTLS psk */
#define CWACSECURITY_FLAGS_X 4 /* X.509 */
#define CWMSGSUBELEM_WTP_DESCRIPTOR_HARDWARE_VERSION 0
#define CWMSGSUBELEM_WTP_DESCRIPTOR_SOFTWARE_VERSION 1
#define CWMSGSUBELEM_WTP_DESCRIPTOR_BOOTLOADER_VERSION 2
#define CWMSGSUBELEM_WTP_DESCRIPTOR_OTHERSOFTWARE_VERSION 3
#include "wtpinfo.h"
#include "acinfo.h"
/* Frame tunnnel mode bits */
#define WTP_FRAME_TUNNEL_MODE_R 1 /* Reserved */
#define WTP_FRAME_TUNNEL_MODE_L 2 /* Local bridging */
#define WTP_FRAME_TUNNEL_MODE_E 4 /* 802.3 mode */
#define WTP_FRAME_TUNNEL_MODE_N 8 /* native mode */
#include "radioinfo.h"
#include "wtpinfo.h"
#define CW_DISCOVERY_TYPE_UNKNOWN 0
#define CW_DISCOVERY_TYPE_STATIC 1
#define CW_DISCOVERY_TYPE_DHCP 2
#define CW_DISCOVERY_TYPE_DNS 3
#define CW_DISCOVERY_TYPE_AC_REFERRAL 4
/* wtpinfo methods */
extern void wtpinfo_set_location(struct wtpinfo * wtpinfo, uint8_t * str, int len);
extern int wtpinfo_set_radioinfo(struct wtpinfo * wtpinfo,uint8_t *msgelem, int len);
#define CWRADIO_TYPE_B 1
#define CWRADIO_TYPE_A 2
#define CWRADIO_TYPE_G 4
#define CWRADIO_TYPE_N 8
/* wtp mac types */
#define WTP_MAC_TYPE_LOCAL 0
#define WTP_MAC_TYPE_SPLIT 1
#define WTP_MAC_TYPE_BOTH 2
//#define CWMSG_MAX_SIZE 65536
#define CWMSG_MAX_SIZE 2048
/* capwap timer default values */
#define CAPWAP_DISCOVERY_INTERVAL 5
#define CAPWAP_MAX_DISCOVERY_INTERVAL 20
#define CAPWAP_RETRANSMIT_INTERVAL 3
#define CAPWAP_MAX_DISCOVERIES 10
#define CAPWAP_MAX_RETRANSMIT 5
#define CAPWAP_SILENT_INTERVAL 30
#define CAPWAP_ECHO_INTERVAL 30
#define CAPWAP_CIPHER "PSK-AES128-CBC-SHA"
/* AC descriptor security flags */
#define AC_SECURITY_X 2 /* X.509 */
#define AC_SECURITY_S 4 /* PSK support */
/* AC dtls policy flags */
#define AC_DTLS_POLICY_C 2 /* Clear data channel support */
#define AC_DTLS_POLICY_D 4 /* DTLS Data channel support */
//struct capwap_msg * capwap_msg_new();
//int cwmsg_send(struct cwmsg * cwmsg, );
// void cwmsg_send(struct cwmsg * cwmsg ,struct conn * conn); //connint8_t * buffer,int msglen)
//void cwmsg_send(struct cwmsg * cwmsg, int rid, uint32_t * rmac, struct conn * conn) ;
//void cwmsg_send(struct cwmsg * cwmsg, int seqnum, int rid, struct conn * conn);
//extern void cwmsg_init(struct cwmsg * msg, uint8_t *buffer,int flag);
//extern void cwmsg_init(struct cwmsg * cwmsg, uint8_t *buffer, int type, uint8_t * rmac);
//void cwmsg_init(struct cwmsg * cwmsg, uint8_t *buffer, int type, struct radioinfo * radioinfo);
extern void cwmsg_addelem_wtp_descriptor(struct cwmsg * cwmsg, struct wtpinfo * wtpinfo);
extern void cwmsg_addelem_ctrl_ip_addrs(struct cwmsg *msg, struct ac_info *acinfo);
extern void cwmsg_addelem_wtp_board_data(struct cwmsg * cwmsg, struct wtpinfo * wtpinfo);
extern void cwmsg_addelem_cw_local_ip_addr(struct cwmsg *msg, struct conn * conn);
extern void cwmsg_addelem_wtp_radio_infos(struct cwmsg * cwmsg,struct wtpinfo * wtpinfo);
extern void cwmsg_addelem_result_code(struct cwmsg *msg,int rc);
//extern void cwsend_discovery_reponse(struct conn * conn, struct ac_info * acinfo);
//extern int process_msgelems(uint8_t * msgelems, int len,
// int (*callback)(void*,int,uint8_t*,int),void *arg );
//void cwsend_discovery_response(struct conn * conn,int seqnum, struct radioinfo * radioinfo, struct ac_info * acinfo, struct wtpinfo * wtpinfo);
//
extern void cwsend_discovery_response(struct conn * conn,int seqnum, struct radioinfo * radioinfo, struct ac_info * acinfo, struct wtpinfo * wtpinfo);
extern int cwsend_discovery_request(struct conn * conn,struct radioinfo * radioinfo,struct wtpinfo * wtpinfo);
extern void cwsend_join_response(struct conn * conn,int seqnum, int rc, struct radioinfo * radioinfo, struct ac_info * acinfo, struct wtpinfo * wtpinfo);
extern void process_discovery_request(struct wtpinfo * wtpinfo, uint8_t * msg, int len);
extern void process_join_request(struct wtpinfo * wtpinfo, uint8_t * msg, int len);
void cwread_discovery_response(struct ac_info * acinfo, uint8_t * msg, int len);
#endif

View File

@ -0,0 +1,29 @@
#define CWMSGELEM_IEEE80211_ADD_WLAN 1024
/* IEEE 802.11 Antenna 1025
IEEE 802.11 Assigned WTP BSSID 1026
IEEE 802.11 Delete WLAN 1027
IEEE 802.11 Direct Sequence Control 1028
IEEE 802.11 Information Element 1029
IEEE 802.11 MAC Operation 1030
IEEE 802.11 MIC Countermeasures 1031
IEEE 802.11 Multi-Domain Capability 1032
IEEE 802.11 OFDM Control 1033
IEEE 802.11 Rate Set 1034
IEEE 802.11 RSNA Error Report From Station 1035
IEEE 802.11 Station 1036
IEEE 802.11 Station QoS Profile 1037
IEEE 802.11 Station Session Key 1038
IEEE 802.11 Statistics 1039
IEEE 802.11 Supported Rates 1040
IEEE 802.11 Tx Power 1041
IEEE 802.11 Tx Power Level 1042
IEEE 802.11 Update Station QoS 1043
IEEE 802.11 Update WLAN 1044
IEEE 802.11 WTP Quality of Service 1045
IEEE 802.11 WTP Radio Configuration 1046
IEEE 802.11 WTP Radio Fail Alarm Indication 1047
*/
#define CWMSGELEM_IEEE80211_WTP_RADIO_INFO 1048

View File

@ -0,0 +1,25 @@
/*
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"
struct capwap_msg * capwap_msg_new()
{
}

View File

@ -0,0 +1,41 @@
/*
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"
int capwap_parse_ctrlhdr(struct capwap_ctrlhdr * ch,uint8_t * msg, int len)
{
if (len<8)
return 0;
uint32_t val;
ch->msgtype = ntohl(*((uint32_t*)(msg)))-CWIANA_ENTERPRISE_NUMBER*256;
val = ntohl(*((uint32_t*)(msg+4)));
ch->seqnum = CW_GET_DWORD_BITS(val,0,8);
ch->msgelemslen=CW_GET_DWORD_BITS(val,8,16)-3;
ch->flags=CW_GET_DWORD_BITS(val,24,8);
ch->msgelems=msg+8;
if (8+ch->msgelemslen != len)
{
return 0;
}
return 1;
}

117
src/capwap/conn.c Normal file
View File

@ -0,0 +1,117 @@
/*
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 <stdlib.h>
#include <string.h>
#include <errno.h>
#include "conn.h"
#include "capwap.h"
#include "sock.h"
#include "cw_log.h"
/**
* function
* @retval 1 Success
* @retval 0 failure, conslt errno for more details
*/
struct conn * conn_create(int sock, struct sockaddr * addr,
// void (*process_message)(void *arg,uint8_t *hdr,uint8_t *msg, int len),
// void (*process_message)(void *arg,struct cwrmsg *), //uint8_t *hdr,uint8_t *msg, int len),
// void *pmsgarg,
int qsize)
{
struct conn * conn;
conn = malloc(sizeof (struct conn));
if (!conn)
return NULL;
memset(conn,0,sizeof(struct conn));
conn->sock=sock;
if (addr)
sock_copyaddr(&conn->addr,addr);
// printf("AF IN: %i\n",addr->sa_family);
char str[200] ;
sock_addrtostr((struct sockaddr*)&conn->addr,str,200);
// printf("CONN CREATOR: %s\n",str);
conn->fragman = fragman_create();
if (conn->fragman==NULL){
conn_destroy(conn);
return NULL;
}
conn->qsize=qsize;
if (qsize != 0){
if (!(conn->q=malloc( sizeof(uint8_t *) * qsize))){
conn_destroy(conn);
return NULL;
}
conn->qrpos=-1;
if (sem_init(&conn->q_sem,0,0)!=0){
cw_log(LOG_ERR,"sem_init %s",strerror(errno));
conn_destroy(conn);
return NULL;
};
conn->recv_packet=conn_q_recv_packet;
}
else
conn->recv_packet = conn_recv_packet;
// conn->process_message=process_message;
// conn->pmsgarg=pmsgarg;
conn->last_seqnum_received=-1;
conn->mtu=1500;
conn->send_packet = conn_send_packet;
conn->cur_packet=0;
conn->recv_timeout=1;
conn->seqnum=-1;
conn->write = conn->send_packet;
conn->read = conn->recv_packet;
return conn;
}
void conn_destroy(struct conn * conn)
{
if (conn->fragman)
fragman_destroy(conn->fragman);
if (conn->q)
free (conn->q);
free(conn);
}
/*
void connn_get_next_seqnum(struct conn * conn)
{
return (++conn->seqnum)&0xff;
}
*/

147
src/capwap/conn.h Normal file
View File

@ -0,0 +1,147 @@
/*
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/>.
*/
#ifndef __CONN_H
#define __CONN_H
#include <stdint.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "fragman.h"
#include "cwmsg.h"
#include "cwrmsg.h"
struct conn{
int sock;
struct sockaddr_storage addr;
int recv_timeout;
FRAGMAN * fragman;
// void (* process_message)(void *,uint8_t *,uint8_t *, int);
// void (* process_message)(void *,struct cwrmsg *); //uint8_t *,uint8_t *, int);
// void * pmsgarg;
int fragid;
int seqnum;
int last_seqnum_received;
int last_message_id_received;
struct cwmsg * last_response;
struct cwmsg swm;
int last_response_seqnum;
int last_response_rid;
uint8_t buffer[65536];
int mtu;
/* receive and send methods */
int (*recv_packet)(struct conn *, uint8_t *,int);
int (*send_packet)(struct conn *, const uint8_t *, int);
int (*read)(struct conn *, uint8_t*, int);
int (*write)(struct conn *, const uint8_t*, int);
/* optional packet queue */
uint8_t ** q; //[WTPMAN_QSIZE];
int qsize;
int qrpos;
int qwpos;
sem_t q_sem;
uint8_t * cur_packet;
int cur_packet_len;
int cur_packet_pos;
#ifdef WITH_DTLS
/* dtls stuff */
int (*dtls_start)(struct conn*);
int (*dtls_accept)(struct conn*);
char * dtls_psk;
int dtls_psk_len;
char * dtls_cert_file;
char * dtls_key_file;
void * dtls_data;
char * dtls_cipher;
#endif
/* used to link the conn obj with other objects */
void * data;
};
struct conn * conn_create(int sock, struct sockaddr * addr,
// void (*process_message)(void *arg,uint8_t *hdr,uint8_t *msg, int len),
// void (*process_message)(void *arg,struct cwrmsg *), //uint8_t *hdr,uint8_t *msg, int len),
// void *pmsgarg,
int qsize);
extern int conn_send_cwmsg(struct conn * conn, struct cwmsg * cwmsg);
extern void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int(*cb)(void*,struct cwrmsg*),void *cbarg);
extern struct cwrmsg * conn_get_message(struct conn * conn);
extern int conn_send_packet(struct conn * conn,const uint8_t * buffer, int len);
extern void conn_destroy(struct conn * conn);
uint8_t * conn_q_get_packet(struct conn * conn);
extern int conn_q_recv_packet(struct conn * conn, uint8_t * buffer,int len);
extern int conn_recv_packet(struct conn* conn,uint8_t *buf,int len);
#define conn_get_next_seqnum(conn) (conn->seqnum=((conn->seqnum+1)&0xff))
#define conn_get_last_seqnum(conn) (conn->seqnum&0xff)
/* connlist stuff */
#include "avltree.h"
struct connlist {
/* struct conn ** connlist; */
struct avltree * t;
int len;
pthread_mutex_t connlist_mutex;
};
struct connlist * connlist_create(int len);
void connlist_lock(struct connlist * cl);
void connlist_unlock(struct connlist * cl);
void conlist_destroy(struct connlist * cl);
struct conn * connlist_get(struct connlist * cl, const struct sockaddr * addr);
struct conn * connlist_add(struct connlist * cl, struct conn * conn);
void connlist_remove(struct connlist *cl,struct conn * conn);
void connlist_destroy(struct connlist * cl);
#endif /* __CONLIST_H */

View File

@ -0,0 +1,51 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "conn.h"
#include "cwrmsg.h"
static int pmessage(void *w, struct cwrmsg * cwrmsg)
{
uint8_t * buffer;
buffer = malloc( sizeof (struct cwrmsg) + cwrmsg->msgelems_len);
memcpy(buffer,cwrmsg,sizeof(struct cwrmsg));
memcpy(buffer+sizeof(struct cwrmsg),cwrmsg->msgelems,cwrmsg->msgelems_len);
((struct cwrmsg*)(buffer))->msgelems=buffer+sizeof(struct cwrmsg);
*((void**)w) = (void*)buffer;
return 0;
}
struct cwrmsg * conn_get_message(struct conn * conn)
{
struct cwrmsg * cwrmsg=0;
// conn->process_message=pmessage;
// conn->pmsgarg=&cwrmsg;
uint8_t buf[2048];
int len=2048;
// int flags=0;
int n;
// do {
// n = conn->recv_packet(conn,(char*)buf,len);
n = conn->read(conn,buf,len);
//
// printf("GETMPACK %i\n",n);
if (n>0)
conn_process_packet(conn,buf,n,pmessage,&cwrmsg);
// } while (cwrmsg==0);
return cwrmsg;
}

View File

@ -0,0 +1,152 @@
#include <stdlib.h>
#include "capwap.h"
#include "cw_log.h"
#include "conn.h"
static int cwrmsg_init_ctrlhdr(struct cwrmsg * cwrmsg, uint8_t * msg, int len)
{
if (len<8)
return 0;
uint32_t val;
val = ntohl(*((uint32_t*)(msg+0)));
cwrmsg->type = ntohl(*((uint32_t*)(msg)))-CWIANA_ENTERPRISE_NUMBER*256;
val = ntohl(*((uint32_t*)(msg+4)));
cwrmsg->seqnum = CW_GET_DWORD_BITS(val,0,8);
cwrmsg->msgelems_len=CW_GET_DWORD_BITS(val,8,16)-3;
// ch->flags=CW_GET_DWORD_BITS(val,24,8);
cwrmsg->msgelems=msg+8;
if (8+cwrmsg->msgelems_len != len){
return 0;
}
return 1;
}
static int process_message(struct conn * conn,struct cwrmsg *cwrmsg,int (*cb)(void*,struct cwrmsg *),void *cbarg)
{
if (!(cwrmsg->type & 0x1)) {
/* It's a response message, no further examination required. */
// conn->process_message(conn->pmsgarg,cwrmsg);
cb(cbarg,cwrmsg);
return 0;
}
/* It's a request message, check if seqnum is right and if
* we have already sent a response message*/
int s1=conn->last_seqnum_received;
int s2=cwrmsg->seqnum;
int sd=s2-s1;
if ((sd>0 && sd<128) || (sd<0 && sd<-128) || s1<0){
/* seqnum is ok, normal message processing */
// conn->last_seqnum_received=cwrmsg->seqnum;
cb(cbarg,cwrmsg);
return 0;
}
if (sd != 0)
{
cw_log_debug0("Discarding message, old seqnum, seqnum = %d, last seqnum=%d",s2,s1);
return 1;
}
/* the received request message was retransmitte by our peer,
* let's retransmit our response message if we have one*/
cw_log_debug0("Retransmitted request message detected, seqnum=%d",s2);
if (!conn->last_response){
cw_log_debug0("No cached response for retransmission, request seqnum=%d",s2);
return 0;
}
cw_log_debug0("Retransmitting response message, seqnum=%d",s2);
// cwmsg_send(conn->last_response,conn->last_response_seqnum,conn->last_response_rid,conn);
conn_send_cwmsg(conn,conn->last_response);
return 1;
}
void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int (*cb)(void*,struct cwrmsg*),void *cbarg)
{
cw_log_debug2("Process conn Packet received, len=%d",len);
if (len<8){
/* packet too short */
cw_log_debug0("Discarding packet, packet too short, len=%d",len);
return;
}
uint32_t val = ntohl(*((uint32_t*)packet));
int preamble = val >> 24;
if ( (preamble & 0xf0) != CW_VERSION){
/* wrong version */
cw_log_debug0("Discarding packet, wrong version, version=%d",preamble&0xf0);
return;
}
if (preamble & 0xf ) {
/* decode dtls */
return;
}
int hlen = 4*((val >> 19) & 0x1f);
int payloadlen = len - hlen;
if (payloadlen<0){
cw_log_debug0("Discarding packet, hlen greater than len, hlen=%d",hlen);
/* EINVAL */
return;
}
struct cwrmsg cwrmsg;
cwrmsg.wbid=(val>>9) & 0x1f;
cwrmsg.rid=(val>>14) & 0x1f;
#ifdef WITH_RMAC_SUPPORT
if (val & CWTH_FLAGS_M){
if (*(packet+8)+8>hlen){
cw_log_debug0("Discarding packet, wrong rmac size, size=%d",*(packet+8));
/* wrong rmac size */
return;
}
cwrmsg.rmac = packet+8;
}
else
cwrmsg.rmac=NULL;
#endif
if (val & CWTH_FLAGS_F){ /* fragmented */
uint8_t * f;
// printf("fragman add\n");
f = fragman_add(conn->fragman, packet,hlen,payloadlen);
if (f==NULL)
return;
// printf("complete\n");
// printf ("msglen = %i\n",*((uint32_t*)f));
cwrmsg_init_ctrlhdr(&cwrmsg,f+4,*(uint32_t*)f);
process_message(conn,&cwrmsg,cb,cbarg); //packet,f+4,*(int32_t*)f);
free (f);
return;
}
cwrmsg_init_ctrlhdr(&cwrmsg,packet+hlen,len-hlen); //f+4,*(uint32_t*)f);
process_message(conn,&cwrmsg,cb,cbarg); //packet,f+4,*(int32_t*)f);
return;
}

View File

@ -0,0 +1,50 @@
/*
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 <stdlib.h>
#include <string.h>
#include "cw_log.h"
#include "conn.h"
void conn_q_add_packet(struct conn * conn,uint8_t *packet,int len)
{
int qwpos = conn->qwpos;
if (qwpos==conn->qsize)
qwpos=0;
if (conn->qrpos==qwpos){
/* no buffers, discard packet */
cw_log_debug0( "Discarding packet, no queu buffers left");
return;
}
conn->q[qwpos]=malloc(len+4);
if (conn->q[qwpos]==NULL)
return;
*((uint32_t*)(conn->q[qwpos]))=len;
memcpy(conn->q[qwpos]+4,packet,len);
conn->qwpos=qwpos+1;
sem_post(&conn->q_sem);
}

View File

@ -0,0 +1,32 @@
#include <time.h>
#include "conn.h"
uint8_t * conn_q_get_packet(struct conn * conn)
{
struct timespec timespec;
clock_gettime(CLOCK_REALTIME,&timespec);
timespec.tv_sec++;
// sem_wait(&conn->q_sem);
if (sem_timedwait(&conn->q_sem,&timespec)==-1){
return NULL;
};
int qrpos = conn->qrpos+1;
if (qrpos==conn->qsize)
qrpos=0;
conn->qrpos=qrpos;
return conn->q[qrpos];
/*
uint8_t * packet = conn->q[qrpos]+4;
int len = *( (uint32_t*)(conn->q[qrpos]));
conn_process_packet(conn->conn,packet,len);
// free(conn->q[qrpos]);
*/
}

View File

@ -0,0 +1,50 @@
/*
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 <stdlib.h>
#include <string.h>
#include <errno.h>
#include "conn.h"
int conn_q_recv_packet(struct conn * conn, uint8_t * buffer,int len)
{
if ( !conn->cur_packet)
{
if ((conn->cur_packet = conn_q_get_packet(conn)) == 0){
errno = EAGAIN;
return -1;
}
conn->cur_packet_len = *((uint32_t*)conn->cur_packet);
conn->cur_packet_pos=4;
}
if (conn->cur_packet_len > len )
{
memcpy(buffer,conn->cur_packet+conn->cur_packet_pos,len);
conn->cur_packet_pos+=len;
conn->cur_packet_len-=len;
return len;
}
memcpy(buffer,conn->cur_packet+conn->cur_packet_pos,conn->cur_packet_len);
free (conn->cur_packet);
conn->cur_packet=0;
return conn->cur_packet_len;
}

View File

@ -0,0 +1,34 @@
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include "conn.h"
int conn_recv_packet(struct conn* conn,uint8_t *buf,int len)
{
// printf("Conn recv packet called\n");
int n;
int flags=0;
while( (n = recv(conn->sock,(char*)buf,len,flags)) < 0 ){
if (errno!=EINTR)
{
/* if (errno == EWOULDBLOCK)
{
printf("would block\n");
}
if ( errno==EAGAIN )
{
printf("again\n");
}
perror("recv");
*/
return n;
}
}
return n;
}

View File

@ -0,0 +1,96 @@
/*
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 <string.h>
#include "conn.h"
#include "capwap.h"
int conn_send_cwmsg(struct conn * conn, struct cwmsg * cwmsg)
{
uint32_t val;
/* second dword of message control header */
val = (cwmsg->seqnum<<24)|((cwmsg->pos+3)<<8);
*((uint32_t*)(cwmsg->ctrlhdr+4))=htonl(val);
// int msglen = cwmsg->ctrlhdr-cwmsg->buffer+cwmsg->pos;
int msglen = cwmsg->pos+8;
uint8_t * ptr = cwmsg->buffer;
int fragoffset = 0;
int hlen = cwmsg->hlen*4;
// printf("Hlen is %i\n",hlen);
int preamble = CW_VERSION | 0;
int wbid=CWTH_WBID_IEEE80211;
int packetlen = msglen+hlen;
int mtu = conn->mtu;
while (packetlen>mtu){
val = (preamble << 24) | ((hlen/4)<<19) | (cwmsg->rid<<14) |(wbid<<9) |
CWTH_FLAGS_T |
CWTH_FLAGS_F |
cwmsg->flags;
*((uint32_t*)ptr)=htonl(val);
// printf("setting frag id : %i\n",conn->fragid);
val = conn->fragid<<16 | fragoffset<<3;
// printf("VAAL: %08X\n",val);
*((uint32_t*)(ptr+4))=htonl(val);
// printf("Offset = %d\n",fragoffset);
// if (conn_send_packet(conn,ptr,mtu)<0)
// return -1;
if (conn->write(conn,ptr,mtu)<0)
return -1;
ptr +=mtu-hlen;
fragoffset+=(mtu-hlen)/8;
packetlen-=mtu-hlen;
// printf("Packelen=%d\n",packetlen);
if (hlen>8)
memcpy(ptr+8,cwmsg->ctrlhdr+8,hlen-8);
}
val = (preamble << 24) | ((hlen/4)<<19) | (cwmsg->rid<<14) |(wbid<<9) |
CWTH_FLAGS_T|cwmsg->flags;
if (fragoffset){
val |= CWTH_FLAGS_F | CWTH_FLAGS_L;
}
// printf("Setting first byte %08X\n",val);
*((uint32_t*)ptr)=htonl(val);
val = conn->fragid<<16 | fragoffset<<3;
*((uint32_t*)(ptr+4))=htonl(val);
return conn->write(conn,ptr,msglen-fragoffset*8+hlen);
}

View File

@ -0,0 +1,51 @@
/*
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 <errno.h>
#include <sys/socket.h>
#include "sock.h"
#include "conn.h"
#include <netinet/in.h>
#include <arpa/inet.h>
#include "cw_log.h"
int conn_send_packet(struct conn * conn, const uint8_t * buffer, int len)
{
#ifdef WITH_CW_LOG_DEBUG
char addrstr[64];
sock_addrtostr((struct sockaddr*)&conn->addr,addrstr,64);
cw_log_debug1("Sending packet to %s, len=%d",addrstr,len);
cw_log_debug2_dump(buffer,len,"Packet data for packet, sent to %s",addrstr);
#endif
int n;
while((n=sendto( conn->sock, buffer, len, 0,
(struct sockaddr*)&conn->addr,
sock_addrlen((struct sockaddr*)&conn->addr)))<0 ){
if(errno == EINTR)
continue;
return n;
}
return n;
}

98
src/capwap/connlist.c Normal file
View File

@ -0,0 +1,98 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include "conn.h"
#include "sock.h"
static int connlist_cmp(const void * d1,const void *d2)
{
struct conn * c1=(struct conn *) d1;
struct conn * c2=(struct conn *) d2;
return sock_cmpaddr((struct sockaddr*)&c1->addr,(struct sockaddr*)&c2->addr,1);
}
struct connlist * connlist_create(int len)
{
struct connlist * cl = malloc(sizeof(struct connlist));
if (!cl)
return 0;
cl->t = avltree_create(connlist_cmp,0);
if (!cl->t){
free(cl);
return 0;
}
if (pthread_mutex_init(&cl->connlist_mutex,NULL)){
avltree_destroy(cl->t);
free(cl);
return 0;
};
cl->len=len;
return cl;
}
void connlist_lock(struct connlist * cl)
{
pthread_mutex_lock(&cl->connlist_mutex);
}
void connlist_unlock(struct connlist * cl)
{
pthread_mutex_unlock(&cl->connlist_mutex);
}
void connlist_destroy(struct connlist * cl)
{
if (cl->t)
avltree_destroy(cl->t);
pthread_mutex_destroy(&cl->connlist_mutex);
free(cl);
}
struct conn * connlist_get(struct connlist * cl, const struct sockaddr * addr)
{
struct conn dummy;
sock_copyaddr(&dummy.addr,addr);
return avltree_get(cl->t,&dummy);
}
struct conn * connlist_add(struct connlist * cl, struct conn * conn)
{
if ( cl->len!=0)
if (cl->t->count>=cl->len)
return 0;
return avltree_add(cl->t,conn);
}
void connlist_remove(struct connlist *cl,struct conn * conn)
{
avltree_del(cl->t,conn);
}

View File

@ -0,0 +1,46 @@
/*
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"
/*
* for each capwap message element in msgelems call the callback function
*/
int cw_foreach_msgelem(uint8_t * msgelems, int len,
int (*callback)(void*,int,uint8_t*,int),void *arg )
{
uint32_t val;
int type;
int elen;
int i=0;
do {
val = ntohl(*(uint32_t*)(msgelems+i));
type=(val>>16) & 0xFFFF;
elen = val & 0xffff;
if (i+elen+4>len) {
return 0;
}
callback(arg,type,msgelems+i+4,elen);
i+=elen+4;
} while (i<len);
return 1;
}

26
src/capwap/cw_log.c Normal file
View File

@ -0,0 +1,26 @@
/*
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 <stdarg.h>
#include "cw_log.h"
void (*cw_log_cb)(int level,const char * fromat, ...) = CW_LOG_DEFAULT_LOG;
const char * cw_log_name = "cw";

76
src/capwap/cw_log.h Normal file
View File

@ -0,0 +1,76 @@
/*
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/>.
*/
#ifndef __CW_LOG_H
#define __CW_LOG_H
#include <stdarg.h>
#include <stdint.h>
#include <syslog.h>
#ifndef CW_LOG_DUMP_ROW_LEN
#define CW_LOG_DUMP_ROW_LEN 32
#endif
#ifndef CW_LOG_DUMP_ROW_TAB_LEN
#define CW_LOG_DUMP_ROW_TAB_LEN 8
#endif
#ifndef CW_LOG_DEFAULT_LOG
#define CW_LOG_DEFAULT_LOG cw_log_tosyslog
#endif
#ifdef WITH_CW_LOG
#define cw_log(level,...) cw_log_cb(level,__VA_ARGS__)
#else
#define cw_log(...)
#endif
#ifdef WITH_CW_LOG_DEBUG
#define cw_log_debug0(...) cw_log_debug_cbs[0](__VA_ARGS__)
#define cw_log_debug1(...) cw_log_debug_cbs[1](__VA_ARGS__)
#define cw_log_debug2(...) cw_log_debug_cbs[2](__VA_ARGS__)
#define cw_log_debug_dump(level,str,len,...) cw_log_debug_dump_(level,str,len,__VA_ARGS__)
#define cw_log_debug0_dump(str,len,...) cw_log_debug_dump_(0,str,len,__VA_ARGS__)
#define cw_log_debug1_dump(str,len,...) cw_log_debug_dump_(1,str,len,__VA_ARGS__)
#define cw_log_debug2_dump(str,len,...) cw_log_debug_dump_(2,str,len,__VA_ARGS__)
#define cw_log_debug(level,...) cw_log_debug_cbs[level](__VA_ARGS__)
#else
#define cw_log_debug0(...)
#define cw_log_debug1(...)
#define cw_log_debug2(...)
#define cw_log_debug(...)
#define cw_log_debug_dump(level,str,len)
#define cw_log_debug0_dump(level,str,len)
#define cw_log_debug1_dump(level,str,len)
#define cw_log_debug2_dump(level,str,len)
#endif
extern void (*cw_log_cb)(int level,const char * fromat, ...);
extern void (*cw_log_debug_cbs[])(const char * fromat, ...);
extern int cw_log_debug_dump_(int level,const uint8_t * data, int len, const char * format, ...);
extern void cw_vlog_(int level,const char * format, va_list args);
extern int cw_log_debug_level;
extern void cw_log_tosyslog(int level,const char *format, ...);
extern void cw_log_tofile(int level,const char *format, ...);
extern const char * cw_log_name;
#endif

116
src/capwap/cw_log_debug.c Normal file
View File

@ -0,0 +1,116 @@
/*
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 <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include "cw_log.h"
static void cw_log_debug0_(const char *format, ...)
{
if (cw_log_debug_level<0)
return;
va_list args;
va_start(args, format);
cw_vlog_(LOG_DEBUG,format,args);
va_end(args);
closelog();
}
static void cw_log_debug1_(const char *format, ...)
{
if (cw_log_debug_level<1)
return;
va_list args;
va_start(args, format);
cw_vlog_(LOG_DEBUG,format,args);
va_end(args);
closelog();
}
static void cw_log_debug2_(const char *format, ...)
{
if (cw_log_debug_level<2)
return;
va_list args;
va_start(args, format);
cw_vlog_(LOG_DEBUG,format,args);
va_end(args);
closelog();
}
int cw_log_debug_dump_(int level,const uint8_t * data, int len,const char * format, ...)
{
int maxtlen=2048;
int i;
int rowlen = CW_LOG_DUMP_ROW_LEN;
int rows = len/rowlen;
int tlen=0;
char * dst = malloc(len*3+(rows*2) + 8+maxtlen);
if ( !dst )
return 0;
if (format != NULL){
va_list args;
va_start(args,format);
tlen = vsnprintf(dst,maxtlen,format,args);
va_end(args);
}
if (len%CW_LOG_DUMP_ROW_LEN)
rows++;
char * pdst=dst+tlen;
sprintf(pdst,"\n\t");
pdst+=2;
for (i=0; i<len;i++){
sprintf(pdst,"%02X ",data[i]&0xff);
pdst+=3;
if ((i+1)%rowlen==0){
sprintf(pdst,"\n\t");
pdst+=2;
}
}
cw_log_debug_cbs[level]("%s",dst);
free (dst);
return 1;
}
int cw_log_debug_level=0;
void (*cw_log_debug_cbs[])(const char * fromat, ...) = {
cw_log_debug0_,
cw_log_debug1_,
cw_log_debug2_
};

View File

@ -0,0 +1,36 @@
#include <stdio.h>
#include "cw_log.h"
int cw_log_file_flags = LOG_PERROR;
char * cw_log_filename = NULL;
void cw_vlog_tofile_(int level,const char * format, va_list args)
{
switch(level){
case LOG_DEBUG:
printf("DEBUG:");
break;
case LOG_INFO:
printf("INFO:");
break;
}
vprintf(format,args);
}
void cw_log_tofile(int level,const char *format, ...)
{
va_list args;
va_start(args, format);
// cw_vlog_(level,format,args);
cw_vlog_tofile_(level,format,args);
va_end(args);
closelog();
}

View File

@ -0,0 +1,20 @@
#include "cw_log.h"
void cw_vlog_(int level,const char * format, va_list args)
{
openlog (cw_log_name, LOG_PERROR | LOG_CONS | LOG_PID | LOG_NDELAY, LOG_DEBUG);
vsyslog(level,format,args);
}
void cw_log_tosyslog(int level,const char *format, ...)
{
va_list args;
va_start(args, format);
cw_vlog_(level,format,args);
va_end(args);
closelog();
}

View File

@ -0,0 +1,12 @@
:q
const cw_msgelemtostr(int elem)
{
}

View File

@ -0,0 +1,36 @@
/*
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 <stdint.h>
#include <stdlib.h>
#include <time.h>
int cw_pseudo_rand(uint8_t *dst, int len)
{
static int init = 1;
if (init){
srand(time(NULL));
}
int i;
for (i=0; i<len; i++){
dst[i]=rand();
}
return len;
}

61
src/capwap/cw_rand.c Normal file
View File

@ -0,0 +1,61 @@
/*
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 <stdint.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "cw_util.h"
#include "cw_log.h"
char * cw_rand_dev = "/dev/random";
int cw_rand(uint8_t*dst, int len)
{
int rf;
int l;
rf = open(cw_rand_dev, O_RDONLY | O_NDELAY);
if (rf<0){
cw_log(LOG_ERR,"Can't open %s: %s",cw_rand_dev,strerror(errno));
return cw_pseudo_rand(dst,len);
}
l = read(rf, dst, len);
close(rf);
if ((l<0) && (errno != EAGAIN)){
cw_log(LOG_ERR,"Cant read from %s: %s",cw_rand_dev,strerror(errno));
return cw_pseudo_rand(dst,len);
}
if (l<len){
cw_log_debug2("Not enough entropy reading from %s, using pseudo rand",cw_rand_dev);
return cw_pseudo_rand(dst,len);
}
return l;
}

34
src/capwap/cw_setstr.c Normal file
View File

@ -0,0 +1,34 @@
/*
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 <stdlib.h>
#include <string.h>
#include "cw_util.h"
uint8_t * cw_setstr(uint8_t ** dst, const uint8_t *src, int len)
{
*dst = realloc(*dst,len+1);
if (*dst==NULL)
return NULL;
memcpy(*dst,src,len);
(*dst)[len]=0;
return *dst;
}

31
src/capwap/cw_util.h Normal file
View File

@ -0,0 +1,31 @@
/*
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 <stdint.h>
extern uint8_t * cw_setstr(uint8_t ** dst, const uint8_t *src, int len);
extern int cw_foreach_msgelem(uint8_t * msgelems, int len,
int (*callback)(void*,int,uint8_t*,int),void *arg );
extern int cw_pseudo_rand(uint8_t *dst, int len);
extern int cw_rand(uint8_t*dst, int len);

34
src/capwap/cwmsg.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef __CWMSG_H
#define __CWMSG_H
#include <stdint.h>
#include "radioinfo.h"
#include "acinfo.h"
struct cwmsg{
uint8_t * buffer;
uint8_t * trnsprthdr;
uint8_t * ctrlhdr;
uint8_t * msgelems;
int pos;
int flags;
int hlen;
int rid;
int seqnum;
int type;
};
struct conn;
extern void cwmsg_init(struct cwmsg * cwmsg, uint8_t *buffer, int type, int seqnum, struct radioinfo * radioinfo);
//int cwmsg_send(struct cwmsg * cwmsg, int seqnum, int rid, struct conn * conn);
//
extern void cwmsg_addelem(struct cwmsg *msg,int type, const uint8_t *elem, int len);
extern void cwmsg_addelem_ac_descriptor(struct cwmsg *msg,struct ac_info * acinfo);
extern void cwmsg_init_echo_request(struct cwmsg * cwmsg,uint8_t *buffer,struct conn * conn, struct radioinfo * radioinfo);
#endif

View File

@ -0,0 +1,32 @@
/*
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 <string.h>
#include <arpa/inet.h>
#include "cwmsg.h"
void cwmsg_addelem(struct cwmsg *msg,int type,const uint8_t*elem,int len)
{
uint32_t val = type<<16|len;
*((uint32_t*)(msg->msgelems+msg->pos))=htonl(val);
memcpy(msg->msgelems+4+msg->pos,elem,len);
msg->pos+=4+len;
}

View File

@ -0,0 +1,57 @@
/*
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 <string.h>
#include "capwap.h"
void cwmsg_addelem_ac_descriptor(struct cwmsg *msg,struct ac_info * acinfo)
{
uint8_t buffer[12+2048];
uint8_t * acd = buffer;
*((uint32_t*)(acd))=htonl((acinfo->stations<<16) | (acinfo->limit));
*((uint32_t*)(acd+4))=htonl((acinfo->active_wtps<<16) | acinfo->max_wtps);
*((uint32_t*)(acd+8))=htonl((acinfo->security<<24) | (acinfo->rmac<<16) | acinfo->dtls_policy );
int len = 12;
int sublen;
/* hardware version subelement */
*((uint32_t*)(acd+len))=0;
len+=4;
sublen=strlen(acinfo->hardware_version);
*((uint32_t*)(acd+len))=htonl((4<<16)|sublen);
len+=4;
memcpy(acd+len,acinfo->hardware_version,sublen);
len+=sublen;
/* software version subelement */
*((uint32_t*)(acd+len))=0;
len+=4;
sublen=strlen(acinfo->software_version);
*((uint32_t*)(acd+len))=htonl((5<<16)|sublen);
len+=4;
memcpy(acd+len,acinfo->software_version,sublen);
len+=sublen;
cwmsg_addelem(msg,CWMSGELEM_AC_DESCRIPTOR,acd,len);
}

View File

@ -0,0 +1,103 @@
/*
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 <string.h>
#include <netinet/in.h>
#include "capwap.h"
#include "acinfo.h"
#include "sock.h"
//static int cwmsg_addelem_acip(struct cwmsg * msg,ACIP *ip,int ctr)
static int cwmsg_addelem_acip(void * priv,void *data,int ctr)
{
struct cwmsg * msg = (struct cwmsg*)priv;
ACIP * acip = (ACIP*)data;
uint8_t ipmsg [18];
switch (acip->ip.ss_family){
case AF_INET:
{
struct sockaddr_in * sain = (struct sockaddr_in*)&acip->ip;
memcpy(ipmsg,&sain->sin_addr.s_addr, sizeof(sain->sin_addr.s_addr));
*((uint16_t*)(ipmsg+4))= htons(acip->wtp_count); /* number of wtps */
cwmsg_addelem(msg,CWMSGELEM_CONTROL_IPV4_ADDRESS,ipmsg,6);
}
break;
#ifdef WITH_IPV6
case AF_INET6:
{
struct sockaddr_in6 * sain = (struct sockaddr_in6*)&acip->ip;
memcpy(ipmsg,&sain->sin6_addr.s6_addr, sizeof(sain->sin6_addr.s6_addr));
*((uint16_t*)(ipmsg+16))= htons(acip->wtp_count); /* number of wtps */
cwmsg_addelem(msg,CWMSGELEM_CONTROL_IPV6_ADDRESS,ipmsg,18);
}
break;
#endif
}
return 1;
}
void cwmsg_addelem_ctrl_ip_addrs(struct cwmsg *msg, struct ac_info *acinfo)
{
// printf("Counter in the list: %i\n",acinfo->aciplist->count);
aciplist_foreach(acinfo->aciplist,cwmsg_addelem_acip,msg);
}
void ucwmsg_addelem_ctrl_ip_addrs(struct cwmsg *msg, struct ac_info *acinfo)
{
int i;
// printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaaa\n");
// printf("add elem %i\n",acinfo->salist_len);
for (i=0; i<acinfo->salist_len; i++)
{
uint8_t ipmsg [18];
switch (acinfo->salist[i].sa_family){
case AF_INET:
{
// printf("v4\n");
struct sockaddr_in * sain = (struct sockaddr_in*)&acinfo->salist[i];
memcpy(ipmsg,&sain->sin_addr, sizeof(sain->sin_addr));
*((uint16_t*)(ipmsg+4))= htons(0); /* number of wtps */
cwmsg_addelem(msg,CWMSGELEM_CONTROL_IPV4_ADDRESS,ipmsg,6);
}
break;
#ifdef WITH_IPV6
case AF_INET6:
{
// printf("v6\n");
struct sockaddr_in6 * sain = (struct sockaddr_in6*)&acinfo->salist[i];
memcpy(ipmsg,&sain->sin6_addr, sizeof(sain->sin6_addr));
*((uint16_t*)(ipmsg+16))= htons(0); /* number of wtps */
cwmsg_addelem(msg,CWMSGELEM_CONTROL_IPV6_ADDRESS,ipmsg,18);
}
break;
#endif
}
}
}

View File

@ -0,0 +1,55 @@
/*
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 <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "capwap.h"
#include "cwmsg.h"
#include "conn.h"
void cwmsg_addelem_cw_local_ip_addr(struct cwmsg *msg, struct conn * conn)
{
struct sockaddr_storage a;
socklen_t alen = sizeof(struct sockaddr_storage);
getsockname (conn->sock,(struct sockaddr *)&a,&alen);
switch (((struct sockaddr*)&a)->sa_family){
case AF_INET:
{
struct sockaddr_in * sain = (struct sockaddr_in*)&a;
cwmsg_addelem(msg,CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS,(uint8_t*)&sain->sin_addr,4);
}
break;
#ifdef WITH_IPV6
case AF_INET6:
{
struct sockaddr_in6 * sain = (struct sockaddr_in6*)&a;
cwmsg_addelem(msg,CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS,(uint8_t*)&sain->sin6_addr,16);
}
break;
#endif
}
}

View File

@ -0,0 +1,19 @@
#include <string.h>
#include "capwap.h"
#include "conn.h"
#include "cwmsg.h"
void cwmsg_addelem_mtu_discovery_padding(struct cwmsg * msg, struct conn* conn)
{
int len = conn->mtu - (msg->msgelems-msg->buffer+msg->pos)-4;
if (len < 0 )
return;
uint32_t val = CWMSGELEM_MTU_DISCOVERY_PADDING<<16|len;
*((uint32_t*)(msg->msgelems+msg->pos))=htonl(val);
memset(msg->msgelems+4+msg->pos,0xff,len);
msg->pos+=4+len;
}

View File

@ -0,0 +1,10 @@
#include "capwap.h"
void cwmsg_addelem_result_code(struct cwmsg *msg,int rc)
{
uint8_t c[4];
*((uint32_t*)c)= htonl(rc);
cwmsg_addelem(msg,CWMSGELEM_RESULT_CODE,c,4);
}

View File

@ -0,0 +1,37 @@
#include <stdlib.h>
#include <string.h>
#include "capwap.h"
void cwmsg_addelem_wtp_board_data(struct cwmsg * cwmsg, struct wtpinfo * wtpinfo)
{
uint8_t msg[1030];
*((uint32_t*)msg)=htonl(wtpinfo->vendor_id);
int l;
int len=4;
if (wtpinfo->model_no){
l=strlen((char*)wtpinfo->model_no);
*((uint32_t*)(msg+len))=htonl(CWBOARDDATA_MODELNO<<16|l);
memcpy(msg+len+4,wtpinfo->model_no,l);
len+=l+4;
}
if (wtpinfo->serial_no){
l=strlen((char*)wtpinfo->serial_no);
*((uint32_t*)(msg+len))=htonl(CWBOARDDATA_SERIALNO<<16|l);
memcpy(msg+len+4,wtpinfo->serial_no,l);
len+=l+4;
}
if (wtpinfo->macaddress){
*((uint32_t*)(msg+len))=htonl(CWBOARDDATA_MACADDRESS<<16|wtpinfo->macaddress_len);
memcpy(msg+len+4,wtpinfo->macaddress,wtpinfo->macaddress_len);
len+=wtpinfo->macaddress_len+4;
}
cwmsg_addelem(cwmsg,CWMSGELEM_WTP_BOARD_DATA,msg,len);
}

View File

@ -0,0 +1,57 @@
#include <string.h>
#include "capwap.h"
static inline int wtpdesc_addsubelem(uint8_t * dst,uint8_t type,uint32_t vendorid,uint8_t * str)
{
// printf("add subelem\n");
int l;
*((uint32_t*)(dst))=htonl(vendorid);
// printf("htonl done\n");
l=strlen((char*)str);
// printf("strlne got %d\n",l);
*((uint32_t*)(dst+4))=htonl((type<<16)|l);
// printf("memcopy str %d\n",l);
memcpy(dst+8,str,l);
return l+8;
}
void cwmsg_addelem_wtp_descriptor(struct cwmsg * cwmsg, struct wtpinfo * wtpinfo)
{
uint8_t d[1024];
int len=0;
/* radios info */
*(d)= wtpinfo->max_radios;
*(d+1)=wtpinfo->radios_in_use;
len=2;
/* number of encryption elemnts */
*(d+len)=1;
len+=1;
/* encryption elements */
*(d+len)=CWTH_WBID_IEEE80211;
uint16_t val = 0;
*((uint16_t*)(d+len+1))=htons(val);
len+=3;
/* hardware subelem*/
len+=wtpdesc_addsubelem(d+len,CWMSGSUBELEM_WTP_DESCRIPTOR_HARDWARE_VERSION,
wtpinfo->hardware_vendor_id,wtpinfo->hardware_version);
/* software subelem*/
len+=wtpdesc_addsubelem(d+len,CWMSGSUBELEM_WTP_DESCRIPTOR_SOFTWARE_VERSION,
wtpinfo->software_vendor_id,wtpinfo->software_version);
/* bootloader subelem*/
len+=wtpdesc_addsubelem(d+len,CWMSGSUBELEM_WTP_DESCRIPTOR_BOOTLOADER_VERSION,
wtpinfo->bootloader_vendor_id,wtpinfo->bootloader_version);
cwmsg_addelem(cwmsg,CWMSGELEM_WTP_DESCRIPTOR,d,len);
}

View File

@ -0,0 +1,39 @@
/*
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_ieee80211.h"
void cwmsg_addelem_wtp_radio_info(struct cwmsg * msg,struct radioinfo *radioinfo)
{
uint8_t ri[5];
*ri = radioinfo->rid;
*((uint32_t*)(ri+1))=htonl(radioinfo->type);
cwmsg_addelem(msg,CWMSGELEM_IEEE80211_WTP_RADIO_INFO,ri,5);
}
void cwmsg_addelem_wtp_radio_infos(struct cwmsg * msg,struct wtpinfo * wtpinfo)
{
int i;
for (i=1; i<30; i++)
{
if (wtpinfo->radioinfo[i].rid!=0)
cwmsg_addelem_wtp_radio_info(msg,&wtpinfo->radioinfo[i]);
}
}

62
src/capwap/cwmsg_init.c Normal file
View File

@ -0,0 +1,62 @@
/*
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 <stdlib.h>
#include <string.h>
#include "capwap.h"
#include "cwmsg.h"
void cwmsg_init(struct cwmsg * cwmsg, uint8_t *buffer, int type, int seqnum, struct radioinfo * radioinfo)
{
int hlen=8;
cwmsg->buffer=buffer;
cwmsg->trnsprthdr=buffer;
#ifdef WITH_RMAC_SUPPORT
int rmaclen;
if (radioinfo->rmac){
rmaclen=(*radioinfo->rmac)+1;
memcpy(buffer+8,radioinfo->rmac,rmaclen);
cwmsg->flags=CWTH_FLAGS_M;
}
else
{
cwmsg->flags=0;
rmaclen=0;
}
hlen+=rmaclen;
if (hlen%4)
hlen = (hlen>>2)*4+4;
#endif
cwmsg->ctrlhdr=cwmsg->trnsprthdr+hlen;
cwmsg->msgelems=cwmsg->ctrlhdr+8;
*((uint32_t*)(cwmsg->ctrlhdr))=htonl(type+CWIANA_ENTERPRISE_NUMBER*256);
cwmsg->pos=0;
cwmsg->hlen=hlen/4;
cwmsg->rid=radioinfo->rid;
cwmsg->seqnum=seqnum;
cwmsg->type=type;
}

View File

@ -0,0 +1,28 @@
/*
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 "conn.h"
#include "cwmsg.h"
void cwmsg_init_echo_request(struct cwmsg * cwmsg,uint8_t *buffer,struct conn * conn, struct radioinfo * radioinfo)
{
cwmsg_init(cwmsg,buffer,CWMSG_ECHO_REQUEST,conn_get_next_seqnum(conn),radioinfo);
}

91
src/capwap/cwmsg_send.c Normal file
View File

@ -0,0 +1,91 @@
/*
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 "cwmsg.h"
int mtu = 564;
int __old_cwmsg_send(struct cwmsg * cwmsg, int seqnum, int rid, struct conn * conn)
{
uint32_t val;
/* second dword of message control header */
val = (seqnum<<24)|((cwmsg->pos+3)<<8);
*((uint32_t*)(cwmsg->ctrlhdr+4))=htonl(val);
// int msglen = cwmsg->ctrlhdr-cwmsg->buffer+cwmsg->pos;
int msglen = cwmsg->pos+8;
uint8_t * ptr = cwmsg->buffer;
int fragoffset = 0;
int hlen = cwmsg->hlen*4;
int preamble = CW_VERSION | 0;
int wbid=CWTH_WBID_IEEE80211;
int packetlen = msglen+hlen;
while (packetlen>mtu){
val = (preamble << 24) | ((hlen/4)<<19) | (rid<<14) |(wbid<<9) |
CWTH_FLAGS_T |
CWTH_FLAGS_F |
cwmsg->flags;
*((uint32_t*)ptr)=htonl(val);
val = conn->fragid<<16 | fragoffset<<3;
*((uint32_t*)(ptr+8))=htonl(val);
// printf("Offset = %d\n",fragoffset);
conn_send_packet(conn,ptr,mtu);
ptr +=mtu-hlen;
fragoffset+=(mtu-hlen)/8;
packetlen-=mtu-hlen;
// printf("Packelen=%d\n",packetlen);
}
val = (preamble << 24) | ((hlen/4)<<19) | (rid<<14) |(wbid<<9) |
CWTH_FLAGS_T|cwmsg->flags;
if (fragoffset)
val |= CWTH_FLAGS_F | CWTH_FLAGS_L;
// printf("Setting first byte %08X\n",val);
*((uint32_t*)ptr)=htonl(val);
val = conn->fragid<<16 | fragoffset<<3;
*((uint32_t*)(ptr+4))=htonl(val);
return conn_send_packet(conn,cwmsg->buffer,msglen-fragoffset*8+hlen);
}

View File

@ -0,0 +1,13 @@
#include "cwmsg.h"
void cwmsg_set_control_header(struct cwmsg * cwmsg,int msgtype, int seqnum)
{
uint32_t val;
val = htonl(msgtype);
*((uint32_t*)(cwmsg->ctrlhdr))=htonl(val);
val = (seqnum<<24)|(cwmsg->pos<<8);
*((uint32_t*)(cwmsg->ctrlhdr+4))=htonl(val);
}

View File

@ -0,0 +1,61 @@
/*
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 <stdlib.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include "capwap.h"
#include "acinfo.h"
#include "cw_util.h"
#include "cw_log.h"
#include <sys/socket.h>
#include <netinet/in.h>
static int acinfo_readelem_discovery_resp(void * a,int type,uint8_t* msgelem,int len)
{
struct ac_info * acinfo = (struct ac_info *)a;
cw_log_debug1("Process discovery resp msgelem, type=%d, len=%d\n",type,len);
if (acinfo_readelem_ac_descriptor(acinfo,type,msgelem,len))
return 1;
if (acinfo_readelem_ac_name(acinfo,type,msgelem,len))
return 1;
if (acinfo_readelem_ctrl_ip_addr(acinfo,type,msgelem,len))
return 1;
return 0;
}
void cwread_discovery_response(struct ac_info * acinfo, uint8_t * msg, int len)
{
cw_foreach_msgelem(msg,len,acinfo_readelem_discovery_resp,acinfo);
}

View File

@ -0,0 +1,58 @@
/*
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 "acinfo.h"
#include "cw_log.h"
#include "cw_util.h"
static int acinfo_readelem_join_resp(void * a,int type,uint8_t* msgelem,int len)
{
struct ac_info * acinfo = (struct ac_info *)a;
cw_log_debug1("Process join resp msgelem, type=%d, len=%d\n",type,len);
if (acinfo_readelem_ecn_support(acinfo,type,msgelem,len))
return 1;
if (acinfo_readelem_ac_descriptor(acinfo,type,msgelem,len))
return 1;
if (acinfo_readelem_ac_name(acinfo,type,msgelem,len))
return 1;
if (acinfo_readelem_ctrl_ip_addr(acinfo,type,msgelem,len))
return 1;
if (acinfo_readelem_cw_local_ip_addr(acinfo,type,msgelem,len))
return 1;
return 0;
}
void cwread_join_response(struct ac_info * acinfo, uint8_t * msg, int len)
{
cw_log_debug1("Reading join response");
cw_foreach_msgelem(msg,len,acinfo_readelem_join_resp,acinfo);
}

18
src/capwap/cwrmsg.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef __CWRMSG_H
#define __CWRMSG_H
struct cwrmsg{
int rid;
int wbid;
uint8_t * msgelems;
int msgelems_len;
int type;
int seqnum;
int msglen;
#ifdef WITH_RMAC_SUPPORT
uint8_t * rmac;
#endif
};
#endif

View File

@ -0,0 +1,39 @@
/*
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 "conn.h"
#include "cwmsg.h"
int cwsend_discovery_request(struct conn * conn,struct radioinfo * radioinfo,struct wtpinfo * wtpinfo)
{
uint8_t buffer[CWMSG_MAX_SIZE];
struct cwmsg cwmsg;
cwmsg_init(&cwmsg,buffer,CWMSG_DISCOVERY_REQUEST,conn_get_next_seqnum(conn),radioinfo);
cwmsg_addelem(&cwmsg,CWMSGELEM_DISCOVERY_TYPE,&wtpinfo->discovery_type,sizeof(uint8_t));
cwmsg_addelem_wtp_board_data(&cwmsg,wtpinfo);
cwmsg_addelem_wtp_descriptor(&cwmsg,wtpinfo);
cwmsg_addelem(&cwmsg,CWMSGELEM_WTP_FRAME_TUNNEL_MODE,&wtpinfo->frame_tunnel_mode,sizeof(uint8_t));
cwmsg_addelem(&cwmsg,CWMSGELEM_WTP_MAC_TYPE,&wtpinfo->mac_type,sizeof(uint8_t));
cwmsg_addelem_wtp_radio_infos(&cwmsg,wtpinfo);
cwmsg_addelem_mtu_discovery_padding(&cwmsg,conn);
return conn_send_cwmsg(conn,&cwmsg);
}

View File

@ -0,0 +1,47 @@
/*
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 <string.h>
#include "capwap.h"
#include "conn.h"
#include "cwmsg.h"
int conn_send_response(struct conn * conn,struct cwmsg * cwmsg,int seqnum)
{
conn->last_response = cwmsg;
// conn->last_response_seqnum=seqnum;
// cwmsg_send(cwmsg,seqnum,rid,conn);
conn_send_cwmsg(conn,cwmsg); //,seqnum);
return 1;
}
void cwsend_discovery_response(struct conn * conn,int seqnum, struct radioinfo * radioinfo, struct ac_info * acinfo, struct wtpinfo * wtpinfo)
{
struct cwmsg * cwmsg = &conn->swm;
cwmsg_init(cwmsg,conn->buffer,CWMSG_DISCOVERY_RESPONSE,seqnum,radioinfo);
cwmsg_addelem_ac_descriptor(cwmsg,acinfo);
cwmsg_addelem(cwmsg,CWMSGELEM_AC_NAME,(uint8_t*)acinfo->ac_name,strlen(acinfo->ac_name));
cwmsg_addelem_wtp_radio_infos(cwmsg,wtpinfo);
cwmsg_addelem_ctrl_ip_addrs(cwmsg,acinfo);
conn_send_response(conn,cwmsg,seqnum);
}

View File

@ -0,0 +1,33 @@
/*
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 "conn.h"
#include "cwmsg.h"
int cwsend_echo_request(struct conn * conn,struct radioinfo * radioinfo) //,struct wtpinfo * wtpinfo)
{
uint8_t buffer[CWMSG_MAX_SIZE];
struct cwmsg cwmsg;
// cwmsg_init(&cwmsg,buffer,CWMSG_ECHO_REQUEST,conn_get_next_seqnum(conn),radioinfo);
cwmsg_init_echo_request(&cwmsg,buffer,conn,radioinfo);
return conn_send_cwmsg(conn,&cwmsg);
}

View File

@ -0,0 +1,17 @@
#include "capwap.h"
#include "conn.h"
#include "cwmsg.h"
int cwsend_echo_response(struct conn * conn,int seqnum,struct radioinfo * radioinfo) //,struct wtpinfo * wtpinfo)
{
//uint8_t buffer[CWMSG_MAX_SIZE];
struct cwmsg * cwmsg = &conn->swm;
cwmsg_init(cwmsg,conn->buffer,CWMSG_ECHO_RESPONSE,seqnum,radioinfo);
conn_send_response(conn,cwmsg,seqnum);
return 1;
//cwmsg_init(&cwmsg,buffer,CWMSG_ECHO_REQUEST,conn_get_next_seqnum(conn),radioinfo);
// return conn_send_cwmsg(conn,&cwmsg);
}

View File

@ -0,0 +1,52 @@
/*
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 <string.h>
#include "capwap.h"
#include "conn.h"
#include "cwmsg.h"
int cwsend_join_request(struct conn * conn,struct radioinfo * radioinfo,struct wtpinfo * wtpinfo)
{
uint8_t buffer[CWMSG_MAX_SIZE];
struct cwmsg cwmsg;
cwmsg_init(&cwmsg,buffer,CWMSG_JOIN_REQUEST,conn_get_next_seqnum(conn),radioinfo);
cwmsg_addelem(&cwmsg,CWMSGELEM_LOCATION_DATA,wtpinfo->location,strlen((char*)wtpinfo->location));
cwmsg_addelem_wtp_board_data(&cwmsg,wtpinfo);
cwmsg_addelem_wtp_descriptor(&cwmsg,wtpinfo);
cwmsg_addelem(&cwmsg,CWMSGELEM_WTP_NAME,wtpinfo->name,strlen((char*)wtpinfo->name));
if (wtpinfo->session_id_len>0){
cwmsg_addelem(&cwmsg,CWMSGELEM_SESSION_ID,wtpinfo->session_id,wtpinfo->session_id_len);
}
cwmsg_addelem(&cwmsg,CWMSGELEM_WTP_FRAME_TUNNEL_MODE,&wtpinfo->frame_tunnel_mode,sizeof(uint8_t));
cwmsg_addelem(&cwmsg,CWMSGELEM_WTP_MAC_TYPE,&wtpinfo->mac_type,sizeof(uint8_t));
cwmsg_addelem_wtp_radio_infos(&cwmsg,wtpinfo);
cwmsg_addelem(&cwmsg,CWMSGELEM_ECN_SUPPORT,&wtpinfo->ecn_support,sizeof(uint8_t));
cwmsg_addelem_cw_local_ip_addr(&cwmsg,conn);
uint16_t l = htons(wtpinfo->max_msg_len);
cwmsg_addelem(&cwmsg,CWMSGELEM_MAXIMUM_MESSAGE_LENGTH,(uint8_t*)&l,sizeof(l));
return conn_send_cwmsg(conn,&cwmsg);
}

View File

@ -0,0 +1,26 @@
#include <string.h>
#include "capwap.h"
#include "conn.h"
void cwsend_join_response(struct conn * conn,int seqnum, int rc, struct radioinfo * radioinfo, struct ac_info * acinfo, struct wtpinfo * wtpinfo)
{
struct cwmsg * cwmsg = &conn->swm;
cwmsg_init(cwmsg,conn->buffer,CWMSG_JOIN_RESPONSE,seqnum,radioinfo);
cwmsg_addelem_result_code(cwmsg,rc);
cwmsg_addelem_ac_descriptor(cwmsg,acinfo);
cwmsg_addelem(cwmsg,CWMSGELEM_AC_NAME,acinfo->ac_name,strlen((char*)acinfo->ac_name));
cwmsg_addelem(cwmsg,CWMSGELEM_ECN_SUPPORT,&acinfo->ecn_support,sizeof(uint8_t));
cwmsg_addelem_ctrl_ip_addrs(cwmsg,acinfo);
cwmsg_addelem_cw_local_ip_addr(cwmsg,conn);
conn_send_response(conn,cwmsg,seqnum);
}

30
src/capwap/dtls.h Normal file
View File

@ -0,0 +1,30 @@
/*
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/>.
*/
#ifndef __DTLS_H
#define __DTLS_H
#include "dtls_openssl.h"
#define dtls_init dtls_openssl_init
#define dtls_accept dtls_openssl_accept
#define dtls_connect dtls_openssl_connect
#define dtls_shutdown dtls_openssl_shutdown
#endif

379
src/capwap/dtls_openssl.c Normal file
View File

@ -0,0 +1,379 @@
/*
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 <errno.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include "dtls_openssl.h"
#include "cw_log.h"
#include "conn.h"
int dtls_openssl_init()
{
cw_log_debug0("Init ssl library");
SSL_load_error_strings();
return SSL_library_init();
}
int dtls_openssl_log_error_queue(const char *txt)
{
int e = ERR_get_error();
if (e==0)
return 0;
char errstr[256];
while (e!=0){
ERR_error_string(e,errstr);
cw_log(LOG_ERR,"%s - %s",txt,errstr);
e = ERR_get_error();
}
return 1;
}
int dtls_openssl_log_error(SSL * ssl, int rc, const char *txt)
{
int en = errno; /* save errno */
if (!ssl){
return dtls_openssl_log_error_queue(txt);
}
int e;
e = SSL_get_error(ssl,rc);
switch (e){
case SSL_ERROR_ZERO_RETURN:
break;
case SSL_ERROR_SYSCALL:
if (!dtls_openssl_log_error_queue(txt)){
/* error queu was empty */
if (rc<0){
cw_log(LOG_ERR,"%s - %s",txt,strerror(en));
return 1;
}
cw_log(LOG_ERR,"%s - EOF observed",txt);
return 1;
}
}
return 0;
}
void dtls_openssl_data_destroy(struct dtls_openssl_data * d){
if (!d)
return;
if (d->ssl)
SSL_free(d->ssl);
if (d->ctx)
SSL_CTX_free(d->ctx);
free(d);
}
struct dtls_openssl_data * dtls_openssl_data_create(struct conn * conn, const SSL_METHOD * method, BIO_METHOD * bio)
{
struct dtls_openssl_data * d = malloc(sizeof(struct dtls_openssl_data));
if (!d)
return 0;
memset(d,0,sizeof(struct dtls_openssl_data));
d->ctx = SSL_CTX_new(method);
if (!d->ctx){
dtls_openssl_data_destroy(d);
return 0;
}
SSL_CTX_set_read_ahead(d->ctx, 1);
// int rc = SSL_CTX_set_cipher_list(d->ctx, "PSK-AES128-CBC-SHA");
//int rc = SSL_CTX_set_cipher_list(d->ctx, "PSiaK-AXES128-C5BC-SaHA");
int rc = SSL_CTX_set_cipher_list(d->ctx, conn->dtls_cipher);
if (!rc){
dtls_openssl_log_error(0,rc,"DTLS:");
dtls_openssl_data_destroy(d);
return 0;
}
d->ssl = SSL_new(d->ctx);
if (!d->ssl){
dtls_openssl_data_destroy(d);
return 0;
}
d->bio = BIO_new(bio);
d->bio->ptr = conn;
SSL_set_bio(d->ssl, d->bio, d->bio);
return d;
}
/*
* Convert the PSK key (psk_key) in ascii to binary (psk).
*/
int dtls_openssl_psk_key2bn(const char *psk_key, unsigned char *psk, unsigned int max_psk_len) {
unsigned int psk_len = 0;
int ret;
BIGNUM *bn = NULL;
ret = BN_hex2bn(&bn, psk_key);
if (!ret) {
cw_log(LOG_ERR,"Could not convert PSK key '%s' to BIGNUM\n", psk_key);
if (bn)
BN_free(bn);
return 0;
}
if (BN_num_bytes(bn) > max_psk_len) {
cw_log(LOG_ERR,"psk buffer of callback is too small (%d) for key (%d)\n",
max_psk_len, BN_num_bytes(bn));
BN_free(bn);
return 0;
}
psk_len = BN_bn2bin(bn, psk);
BN_free(bn);
if (psk_len < 0)
goto out_err;
return psk_len;
out_err:
return 0;
}
#include <arpa/inet.h>
//#include <socket.h>
#include <netinet/in.h>
int dtls_openssl_shutdown(struct conn *conn)
{
conn->write = conn->send_packet;
conn->read = conn->recv_packet;
struct dtls_openssl_data * d = (struct dtls_openssl_data*)conn->dtls_data;
if (!d)
return 0;
SSL_shutdown(d->ssl);
dtls_openssl_data_destroy(d);
conn->dtls_data=0;
return 1;
}
int cookie_initialized=0;
#define COOKIE_SECRET_LENGTH 16
unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
int dtls_openssl_generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
{
unsigned char *buffer, result[EVP_MAX_MD_SIZE];
unsigned int length = 0, resultlength;
union {
struct sockaddr_storage ss;
struct sockaddr_in6 s6;
struct sockaddr_in s4;
} peer;
/* Initialize a random secret */
if (!cookie_initialized)
{
if (!RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH))
{
printf("error setting random cookie secret\n");
return 0;
}
cookie_initialized = 1;
}
/* Read peer information */
(void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
/* Create buffer with peer's address and port */
length = 0;
switch (peer.ss.ss_family) {
case AF_INET:
length += sizeof(struct in_addr);
break;
case AF_INET6:
length += sizeof(struct in6_addr);
break;
default:
OPENSSL_assert(0);
break;
}
length += sizeof(in_port_t);
buffer = (unsigned char*) OPENSSL_malloc(length);
if (buffer == NULL)
{
printf("out of memory\n");
return 0;
}
switch (peer.ss.ss_family) {
case AF_INET:
memcpy(buffer,
&peer.s4.sin_port,
sizeof(in_port_t));
memcpy(buffer + sizeof(peer.s4.sin_port),
&peer.s4.sin_addr,
sizeof(struct in_addr));
break;
case AF_INET6:
memcpy(buffer,
&peer.s6.sin6_port,
sizeof(in_port_t));
memcpy(buffer + sizeof(in_port_t),
&peer.s6.sin6_addr,
sizeof(struct in6_addr));
break;
default:
OPENSSL_assert(0);
break;
}
/* Calculate HMAC of buffer using the secret */
HMAC(EVP_sha1(), (const void*) cookie_secret, COOKIE_SECRET_LENGTH,
(const unsigned char*) buffer, length, result, &resultlength);
OPENSSL_free(buffer);
memcpy(cookie, result, resultlength);
*cookie_len = resultlength;
return 1;
}
int dtls_openssl_verify_cookie(SSL *ssl, unsigned char *cookie, unsigned int cookie_len)
{
unsigned char *buffer, result[EVP_MAX_MD_SIZE];
unsigned int length = 0, resultlength;
union {
struct sockaddr_storage ss;
struct sockaddr_in6 s6;
struct sockaddr_in s4;
} peer;
/* If secret isn't initialized yet, the cookie can't be valid */
if (!cookie_initialized)
return 0;
/* Read peer information */
(void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
/* Create buffer with peer's address and port */
length = 0;
switch (peer.ss.ss_family) {
case AF_INET:
length += sizeof(struct in_addr);
break;
case AF_INET6:
length += sizeof(struct in6_addr);
break;
default:
OPENSSL_assert(0);
break;
}
length += sizeof(in_port_t);
buffer = (unsigned char*) OPENSSL_malloc(length);
if (buffer == NULL)
{
printf("out of memory\n");
return 0;
}
switch (peer.ss.ss_family) {
case AF_INET:
memcpy(buffer,
&peer.s4.sin_port,
sizeof(in_port_t));
memcpy(buffer + sizeof(in_port_t),
&peer.s4.sin_addr,
sizeof(struct in_addr));
break;
case AF_INET6:
memcpy(buffer,
&peer.s6.sin6_port,
sizeof(in_port_t));
memcpy(buffer + sizeof(in_port_t),
&peer.s6.sin6_addr,
sizeof(struct in6_addr));
break;
default:
OPENSSL_assert(0);
break;
}
/* Calculate HMAC of buffer using the secret */
HMAC(EVP_sha1(), (const void*) cookie_secret, COOKIE_SECRET_LENGTH,
(const unsigned char*) buffer, length, result, &resultlength);
OPENSSL_free(buffer);
if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0)
return 1;
return 0;
}
struct pass_info {
union {
struct sockaddr_storage ss;
struct sockaddr_in6 s6;
struct sockaddr_in s4;
} server_addr, client_addr;
SSL *ssl;
};
int dtls_openssl_read(struct conn * conn, uint8_t *buffer, int len)
{
struct dtls_openssl_data * d = conn->dtls_data;
return SSL_read(d->ssl,buffer,len);
}
int dtls_openssl_write(struct conn * conn, const uint8_t *buffer, int len)
{
struct dtls_openssl_data * d = conn->dtls_data;
return SSL_write(d->ssl,buffer,len);
}

48
src/capwap/dtls_openssl.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef __DTLS_OPENSLL_H
#define __DTLS_OPENSSL_H
#include <stdint.h>
#include <openssl/ssl.h>
#include "conn.h"
struct dtls_openssl_data{
SSL_CTX * ctx;
SSL * ssl;
BIO * bio;
uint8_t buffer[2048];
int len;
int pos;
};
extern int dtls_openssl_init();
//extern struct dtls_openssl_data * dtls_openssl_data_create(const SSL_METHOD * method );
//struct dtls_openssl_data * dtls_openssl_data_create(const SSL_METHOD * method, const BIO_METHOD * bio);
struct dtls_openssl_data * dtls_openssl_data_create(struct conn * conn, const SSL_METHOD * method, BIO_METHOD * bio);
extern int dtls_openssl_psk_key2bn(const char *psk_key, unsigned char *psk, unsigned int max_psk_len);
extern int dtls_openssl_generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len);
extern int dtls_openssl_verify_cookie(SSL *ssl, unsigned char *cookie, unsigned int cookie_len);
extern int dtls_openssl_read(struct conn * conn, uint8_t *buffer, int len);
extern int dtls_openssl_write(struct conn * conn, const uint8_t *buffer, int len);
extern int dtls_openssl_connect(struct conn * conn);
extern int dtls_openssl_log_error(SSL * ssl, int rc, const char *txt);
extern int dtls_openssl_bio_puts(BIO *bp, const char *str);
extern int dtls_openssl_bio_read(BIO *b, char *out, int maxlen);
extern int dtls_openssl_bio_write(BIO *b, const char *data, int len);
extern long dtls_openssl_bio_ctrl(BIO *b, int cmd, long num, void *ptr);
extern int dtls_openssl_bio_new(BIO *bi);
extern int dtls_openssl_bio_free(BIO *bio);
extern BIO *bbb;
#endif

View File

@ -0,0 +1,160 @@
#include <openssl/err.h>
#include "dtls_openssl.h"
#include "conn.h"
#include "cw_log.h"
static BIO_METHOD bio_methods = {
BIO_TYPE_DGRAM,
"cw packet",
dtls_openssl_bio_write,
dtls_openssl_bio_read,
dtls_openssl_bio_puts,
NULL, // dgram_gets
dtls_openssl_bio_ctrl,
dtls_openssl_bio_new,
dtls_openssl_bio_free,
NULL,
};
static unsigned int psk_server_cb(SSL *ssl,const char *identity, unsigned char * psk, unsigned int max_psk_len)
{
BIO * b = SSL_get_rbio(ssl);
struct conn * conn = b->ptr;
// printf("PSK_CB: %s\n",identity);
// printf("Conn psk : %s\n",conn->dtls_psk);
// printf("Max dtls psk len %i\n",max_psk_len);
// return dtls_openssl_psk_key2bn(conn->dtls_psk, psk, max_psk_len);
int l = conn->dtls_psk_len < max_psk_len ? conn->dtls_psk_len : max_psk_len;
// printf("PSK return l %d\n",l);
memcpy(psk,conn->dtls_psk,l);
return l;
}
int dtls_openssl_accept(struct conn * conn)
{
if (!conn->dtls_data)
conn->dtls_data = dtls_openssl_data_create(conn,DTLSv1_server_method(),&bio_methods);
struct dtls_openssl_data * d = (struct dtls_openssl_data*)conn->dtls_data;
if (!d)
return 0;
SSL_set_psk_server_callback( d->ssl, psk_server_cb);
int rc;
// do{
int i;
for (i=0; i<5; i++){
rc = SSL_accept(d->ssl);
if (rc==0){
int e;
e = SSL_get_error(d->ssl,rc);
switch (e){
case SSL_ERROR_SYSCALL:
printf("syscall EOF!\n");
break;
}
char errstr[256];
e = ERR_get_error();
while (e!=0){
ERR_error_string(e,errstr);
cw_log(LOG_ERR,"SSL_accept (e) - %s",e,errstr);
e = ERR_get_error();
}
continue;
}
if (rc == 1)
{
// printf("Juhu!\n");
conn->read = dtls_openssl_read;
conn->write = dtls_openssl_write;
return 1;
}
}
return 0;
// } while (rc == 0 );
if (rc != 1){
char errstr[256];
int e = ERR_get_error();
ERR_error_string(e,errstr);
cw_log(LOG_ERR,"SSL_accept %s",errstr);
return 0;
}
return 1;
/*
struct dtls_openssl_data * data = dtls_openssl_data_new();
if (!data)
return 0;
SSL_CTX * ctx = dtls_openssl_create_ctx(DTLSv1_server_method());
if (!ctx){
free (data);
return 0;
}
// dtls_init(conn,DTLSv1_server_method());
struct dtls_data * dtls_data = conn->dtls_data;
SSL * ssl = dtls_data->ssl;
//i printf("bio connected\n");
// BIO_ctrl(SSL_get_rbio(ssl), BIO_CTRL_DGRAM_SET_CONNECTED, 0, NULLi //&pinfo->client_addr.ss);
// printf("bio connected done\n");
int rc;
printf("doing accepz\n");
// do {
rc = SSL_accept(ssl);
printf("accept again\n");
// } while(rc==0);
perror ("ERRP");
printf("SSL accept rc %i\n",rc);
int e = ERR_get_error();
printf ("THE E: %i\n",e);
char es[499];
ERR_error_string(e,es);
printf ("ES: %s\n",es);
rc = SSL_get_error(ssl,rc);
printf("ERROR RC: %08X\n",rc);
exit(9);
*/
}

View File

@ -0,0 +1,171 @@
#include <arpa/inet.h>
#include "dtls_openssl.h"
#include "conn.h"
int dtls_openssl_bio_write(BIO *b, const char *data, int len)
{
// printf("bio_write %p %d",data,len);
struct conn * conn = b->ptr;
uint8_t buffer[2048];
*((uint32_t*)buffer)=htonl(1<<24);
memcpy(buffer+4,data,len);
int rc = conn->send_packet(conn,buffer,len+4);
if (rc<0)
return rc;
return rc-4;
}
int dtls_openssl_bio_read(BIO *b, char *out, int maxlen)
{
// printf("READER WHANT: %d\n",maxlen);
struct conn * conn = b->ptr;
struct dtls_openssl_data * dtls_data = conn->dtls_data;
// int len;
if (dtls_data->len==0){
int len = conn->recv_packet(conn,dtls_data->buffer,2048);
if (len<4)
return 0;
dtls_data->len=len-4;
dtls_data->pos=4;
// printf("DTLS_DATA_LEN: %d\n",dtls_data->len);
}
if (dtls_data->len > maxlen)
{
memcpy(out,dtls_data->buffer+dtls_data->pos,maxlen);
dtls_data->len-=maxlen;
dtls_data->pos+=maxlen;
// printf("Return %d, %d beyes left\n",maxlen,dtls_data->len);
return maxlen;
}
// printf("Return rest = %d\n",dtls_data->len);
memcpy(out,dtls_data->buffer+dtls_data->pos,dtls_data->len);
int ret = dtls_data->len;
dtls_data->len=0;
return ret;
}
int dtls_openssl_bio_new(BIO *bi)
{
bi->init = 1;
bi->num = 0;
bi->flags = 0;
bi->ptr = NULL;
return 1;
}
int dtls_openssl_bio_puts(BIO *b, const char *str)
{
return dtls_openssl_bio_write(b, str, strlen(str));
}
int dtls_openssl_bio_free(BIO *bio)
{
printf("Bio free\n");
if (bio == NULL)
return 0;
return 1;
}
long dtls_openssl_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret = 1;
// long sockopt_val = 0;
// unsigned int sockopt_len = 0;
// BIO_memory_data* pData = (BIO_memory_data*)b->ptr;
//
// printf("BIO CONTROL \n");
// exit(1);
switch (cmd)
{
case BIO_CTRL_RESET:
case BIO_CTRL_EOF:
ret = 0;
break;
case BIO_CTRL_INFO:
ret = 0;
break;
case BIO_CTRL_GET_CLOSE:
ret = 0;
break;
case BIO_CTRL_SET_CLOSE:
break;
case BIO_CTRL_WPENDING:
ret = 0;
break;
case BIO_CTRL_PENDING:
ret = 0;
break;
case BIO_CTRL_DUP:
ret = 1;
break;
case BIO_CTRL_FLUSH:
ret = 1;
break;
case BIO_CTRL_PUSH:
ret = 0;
break;
case BIO_CTRL_POP:
ret = 0;
case BIO_CTRL_DGRAM_QUERY_MTU:
{
ret = 1000;
/* sockopt_len = sizeof(sockopt_val);
if ((ret = getsockopt(pData->sock, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, &sockopt_len)) < 0 || sockopt_val < 0)
{
ret = 0;
}
else
{
pData->nMtu = sockopt_val;
ret = sockopt_val;
}
break;
*/ }
case BIO_CTRL_DGRAM_GET_MTU:
ret = 1000;
// ret = pData->nMtu;
break;
case BIO_CTRL_DGRAM_SET_MTU:
// pData->nMtu = num;
// ret = num;
break;
default:
ret = 0;
break;
}
return ret;
}

View File

@ -0,0 +1,98 @@
#include <openssl/err.h>
#include "dtls_openssl.h"
#include "cw_log.h"
static BIO_METHOD bio_methods = {
BIO_TYPE_DGRAM,
"cw packet",
dtls_openssl_bio_write,
dtls_openssl_bio_read,
dtls_openssl_bio_puts,
NULL, // dgram_gets
dtls_openssl_bio_ctrl,
dtls_openssl_bio_new,
dtls_openssl_bio_free,
NULL,
};
static unsigned int psk_client_cb(SSL *ssl,
const char *hint,
char *identity,
unsigned int max_identity_len,
unsigned char *psk,
unsigned int max_psk_len) {
BIO * b = SSL_get_rbio(ssl);
struct conn * conn = b->ptr;
// printf("KEYY: %s\n",conn->dtls_psk);
snprintf(identity, max_identity_len, "CLient_identity");
int l = conn->dtls_psk_len < max_psk_len ? conn->dtls_psk_len : max_psk_len;
memcpy(psk,conn->dtls_psk,l);
return l;
}
int dtls_openssl_connect(struct conn * conn)
{
if (!conn->dtls_data)
conn->dtls_data = dtls_openssl_data_create(conn,DTLSv1_client_method(),&bio_methods);
struct dtls_openssl_data * d = (struct dtls_openssl_data*)conn->dtls_data;
if (!d)
return 0;
SSL_set_psk_client_callback( d->ssl, psk_client_cb);
char errstr[256];
int rc;
do{
rc = SSL_connect(d->ssl);
/* if (rc <= 0){
int e;
e = SSL_get_error(d->ssl,rc);
printf("Get Err %i\n",e);
printf("SSL Connect rc = %i\n",rc);
e = ERR_get_error();
ERR_error_string(e,errstr);
cw_log(LOG_ERR,"SSL_connect %s",errstr);
}
*/
if(rc==1){
conn->read = dtls_openssl_read;
conn->write = dtls_openssl_write;
return 1;
}
rc = dtls_openssl_log_error(d->ssl,rc,"DTLS connect");
} while (rc == 0 );
// printf("DTLS connect RC: %i\n",rc);
// int e = ERR_get_error();
// ERR_error_string(e,errstr);
// cw_log(LOG_ERR,"SSL_accept %s",errstr);
return 0;
}

View File

@ -0,0 +1,41 @@
int dtls_openssl_init(struct conn * conn,const SSL_METHOD * method)
{
conn->dtls_data = malloc(sizeof(struct dtls_data));
struct dtls_data * dtls_data = conn->dtls_data;
if (!dtls_data)
return 0;
dtls_data->pos=0;
dtls_data->len=0;
SSL_CTX *ctx;
SSL *ssl;
BIO *bio = BIO_new(&bio_methods);
bio->ptr = conn;
printf("Assigning conn %p\n",bio->ptr);
OpenSSL_add_ssl_algorithms();
SSL_load_error_strings();
printf("Getting CTX\n");
ctx = SSL_CTX_new(method); //DTLSv1_client_method());
printf("CTX: %p\n",ctx);
int rc = SSL_CTX_set_cipher_list(ctx, "PSK-AES128-CBC-SHA");
printf("Set cipher RC: %d\n",rc);
SSL_CTX_set_psk_client_callback( ctx, psk_cb);
SSL_CTX_set_psk_server_callback( ctx, psk_server_cb);
SSL_CTX_set_read_ahead(ctx, 1);
SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie);
SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie);
ssl = SSL_new(ctx);
SSL_set_bio(ssl, bio, bio);
printf("New rc %p\n",ssl);
dtls_data->ssl=ssl;
return 0;
}

203
src/capwap/fragman.c Normal file
View File

@ -0,0 +1,203 @@
/*
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/>.
*/
/*
* This file implements a simple fragment management system
* for the capwap protocol.
*
* Usage goes as follows.
*
* First create a FRAGMAN object:
*
* FRAGMAN * fm = fragman_create()
*
* Now you can add received fragmented packets to the fragment manager:
*
* fragman_add(fm,packet,len)
*
* if you have got all fragments fragman_add will return the the
* reasembled packet in a struct frag. if not all packets are recieved
* fragman_add will return NULL. To check if there was an error you have
* to consult errno. errno will be set if fragman_add returns NULL and there
* was another problem storing the received packet.
*
* After you have got a reassembled packet and processed it yout must
* free the memory by calling fragman_free()
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "capwap.h"
#include "fragman.h"
/*
* check if we keep already fragments belonging to the
* specified fragment id
*/
static struct frag * frag_get(struct frag * frags, int fragid)
{
int i;
for (i=0;i<FRAG_MAXIDS; i++){
if (frags[i].buffer==NULL)
continue;
if (frags[i].fragid==fragid)
{
return &frags[i];
}
}
return NULL;
}
/*
* create a new fragment
*/
static struct frag * frag_new(struct frag * frags, int fragid)
{
struct timespec t;
clock_gettime(CLOCK_REALTIME,&t);
int i;
for (i=0; i<FRAG_MAXIDS; i++){
if (frags[i].buffer==NULL || (t.tv_sec - frags[i].t.tv_sec>FRAG_TTL) ){
// printf("******************************new frag, %p\n",frags[i].buffer);
frags[i].buffer=realloc(frags[i].buffer,FRAG_MAXSIZE);
if (frags[i].buffer==NULL)
return NULL;
frags[i].t=t;
frags[i].fragid=fragid;
frags[i].bytesreceived=0;
frags[i].bytesneeded=0;
return &frags[i];
}
}
return NULL;
}
/*
void fragman_free(FRAGMAN * frags,struct frag * f)
{
int i;
for (i=0; i<FRAG_MAXIDS; i++){
if (frags[i]->fragid==f->fragid){
frags[i]=NULL;
break;
}
}
free(f);
}
*/
uint8_t * fragman_add(FRAGMAN * frags, uint8_t *packet, int hlen, int payloadlen)
{
struct frag * f;
uint32_t val0,val1;
/* read the transport header dword 0,
* contains hlen*/
val0 = ntohl(*((uint32_t*)packet));
// int hlen = (val0 >> 19) & 0x1f;
/* read the transport header dword 1,
* contains fragid and fragoffset */
val1 = ntohl(*(((uint32_t*)packet)+1));
int fragid = val1>>16;
int fragoffset=(val1 >>3) & 0x1fff;
// printf("Fragid = %i, offset = %i\n",fragid,fragoffset);
/* determine size of payload */
/* int payloadlen = len - hlen*4;
if (payloadlen<0){
errno = EINVAL;
return NULL;
}
*/
/* find / create cfragment */
f = frag_get(frags,fragid);
if (!f){
f = frag_new(frags,fragid);
}
if (!f){
errno = ENOMEM;
/* out of fragmentation space */
return NULL;
}
errno = 0;
int dst = fragoffset*8;
/* copy fragment*/
if (dst + payloadlen < FRAG_MAXSIZE) {
memcpy( f->buffer+4+dst,packet+hlen,payloadlen);
f->bytesreceived+=payloadlen;
}
if (val0 & CWTH_FLAGS_L){
printf("Flags L found!\n");
f->bytesneeded=dst+payloadlen;
}
int ti;
for (ti=0; ti<16; ti++){
printf("%02X ",(f->buffer+4)[ti]);
}
if (f->bytesneeded>0 && f->bytesneeded<=f->bytesreceived){
uint8_t * r=f->buffer;
f->buffer=0;
printf("last bytes need %i\n",f->bytesneeded);
*((uint32_t*)(r))=f->bytesneeded;
return r;
}
// printf("Fragman bytes needed: %i, received %i\n",f->bytesneeded,f->bytesreceived);
return NULL;
}
FRAGMAN * fragman_create()
{
FRAGMAN * frags;
frags = malloc(sizeof(struct frag)*FRAG_MAXIDS);
if (frags == NULL )
return NULL;
memset (frags,0,(sizeof (struct frag ))*FRAG_MAXIDS);
return frags;
}
void fragman_destroy(FRAGMAN * frags)
{
int i;
for (i=0;i<FRAG_MAXIDS; i++){
if (frags[i].buffer==NULL)
continue;
free(frags[i].buffer);
}
free (frags);
}

64
src/capwap/fragman.h Normal file
View File

@ -0,0 +1,64 @@
/*
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/>.
*/
#ifndef __FRAGMAN_H
#define __FRAGMAN_H
#include <stdint.h>
#include <time.h>
#ifndef FRAG_MAXSIZE
#define FRAG_MAXSIZE 65536+4
#endif
#ifndef FRAG_MAXIDS
#define FRAG_MAXIDS 10
#endif
#ifndef FRAG_TTL
#define FRAG_TTL 5
#endif
struct frag {
// uint8_t buffer[FRAG_MAXSIZE];
uint8_t * buffer;
int fragid;
int bytesreceived;
int bytesneeded;
struct timespec t;
};
typedef struct frag FRAGMAN;
//extern struct frag * fragman_add(struct frag * frags[], uint8_t *packet, int len); // struct cw_transport_header * th)
//extern uint8_t * fragman_add(struct frag * frags, uint8_t *packet, int len); // struct cw_transport_header * th)
extern uint8_t * fragman_add( FRAGMAN * frags, uint8_t *packet, int hlen, int payloadlen );
extern FRAGMAN * fragman_create();
extern void fragman_destroy(FRAGMAN * frags);
//extern frag_init(struct frag ** frag[]);
extern void fragman_free(FRAGMAN * frags,struct frag * f);
#endif

View File

@ -0,0 +1,48 @@
#include <stdio.h> //tube
#include <stdlib.h>
#include <string.h>
#include "capwap.h"
#include "capwap_ieee80211.h"
#include "cw_log.h"
#include "cw_util.h"
//static int wtpinfo_readelem_discovery_req(struct wtpinfo *wtpinfo,int type,uint8_t* msgelem,int len)
static int wtpinfo_readelem_discovery_req(void * w,int type,uint8_t* msgelem,int len)
{
struct wtpinfo * wtpinfo = (struct wtpinfo *)w;
cw_log_debug1("Process discovery req msgelem, type=%d, len=%d\n",type,len);
if (wtpinfo_readelem_discovery_type(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_wtp_board_data(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_wtp_descriptor(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_wtp_frame_tunnel_mode(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_wtp_mac_type(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_wtp_radio_info(wtpinfo,type,msgelem,len))
return 1;
return 0;
}
void process_discovery_request(struct wtpinfo * wtpinfo, uint8_t * msg, int len)
{
cw_foreach_msgelem(msg,len,wtpinfo_readelem_discovery_req,wtpinfo);
}

View File

@ -0,0 +1,55 @@
#include "capwap.h"
#include "capwap_ieee80211.h"
#include <stdio.h> //Tube
#include <stdlib.h>
#include <string.h>
#include "wtpinfo.h"
#include "cw_util.h"
//static int process_elem(struct wtpinfo *wtpinfo,int type,uint8_t* msgelem,int len)
static int process_elem(void *w,int type,uint8_t* msgelem,int len)
{
struct wtpinfo * wtpinfo = (struct wtpinfo*)w;
if (wtpinfo_readelem_location_data(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_wtp_board_data(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_wtp_descriptor(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_wtp_name(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_session_id(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_wtp_frame_tunnel_mode(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_wtp_mac_type(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_wtp_radio_info(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_ecn_support(wtpinfo,type,msgelem,len))
return 1;
if (wtpinfo_readelem_cw_local_ip_addr(wtpinfo,type,msgelem,len))
return 1;
return 0;
}
void process_join_request(struct wtpinfo * wtpinfo, uint8_t * msg, int len)
{
cw_foreach_msgelem(msg,len,process_elem,(void*)wtpinfo);
}

View File

@ -0,0 +1,53 @@
/*
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"
/*
* for each capwap message element in msgelems call the callback function
*/
int process_msgelems(uint8_t * msgelems, int len,
int (*callback)(void*,int,uint8_t*,int),void *arg )
{
// printf("NUNU %08X\n",msgelems);
uint32_t val;
int type;
int elen;
int i=0;
do {
val = ntohl(*(uint32_t*)(msgelems+i));
type=(val>>16) & 0xFFFF;
elen = val & 0xffff;
if (i+elen+4>len) {
// printf("Error AAA");
// exit(88);
return 0;
}
callback(arg,type,msgelems+i+4,elen);
// process_joinmsgelem(wtpman,msgelems+i+4,type,elen);
// printf("type %d, len %d\n",type,elen);
i+=elen+4;
// printf("I %d, len %d\n",i,len);
} while (i<len);
return 1;
}

View File

@ -0,0 +1,60 @@
/*
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"
/*
int process_msgelems_discovery_request(struct wtpinfo *wtpinfo,int type,uint8_t* msgelem,int len)
{
// printf("pdiscovery msgelem: %d\n",type);
uint8_t val;
switch (type){
case CWMSGELEM_DISCOVERY_TYPE:
if (len!=1)
return 0;
uint8_t ditype = *((uint8_t*)msgelem);
// printf("Discovery type: %d\n",ditype);
break;
case CWMSGELEM_WTP_BOARD_DATA:
if (len<4)
return 0;
wtpinfo->vendor_id = ntohl(*((uint32_t*)msgelem));
// printf("Vendor ID %d\n",wtp_info.vendor_id);
parse_wtp_board_data(wtpinfo,msgelem+4,len-4);
case CWMSGELEM_WTP_DESCRIPTOR:
printf("DESCRIPTOR\n");
if (len<4)
return;
val = ntohl(*((uint32_t*)msgelem));
wtpinfo->max_radios=val>>24;
wtpinfo->radios_in_use=(val>>16)&0xff;
// printf("Vendor ID %d\n",wtp_info.vendorid);
// parse_wtp_board_data(&wtp_info,msgelem+4,len-4);
// printf("MAX RAD %d, %d\n",wtp_info.max_radios,wtp_info.radios_in_use);
break;
}
return 1;
}
*/

32
src/capwap/radioinfo.h Normal file
View File

@ -0,0 +1,32 @@
/*
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/>.
*/
#ifndef __RADIOINFO_H
#define __RADIOINFO_H
struct radioinfo{
int rid;
uint32_t type;
#ifdef WITH_RMAC_SUPPORT
uint8_t * rmac;
#endif
};
#endif

70
src/capwap/sock.h Normal file
View File

@ -0,0 +1,70 @@
/*
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/>.
*/
#ifndef __SOCK_H
#define __SOCK_H
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#ifdef __FreeBSD__
#define HAVE_SIN_LEN
#define HAVE_SIN6_LEN
#endif
extern int sock_create(const struct sockaddr * sa);
extern int sock_mwait(int * socklist, int socklistlen,fd_set * fset);
extern void sock_copyaddr(struct sockaddr_storage *dst, const struct sockaddr * src);
extern int sock_cmpaddr(const struct sockaddr *addr1, const struct sockaddr *addr2,int cmpport);
extern int sock_addrlen(const struct sockaddr * sa);
extern int sock_receive(int sock,void *buf, size_t len, int flags, struct sockaddr * srcaddr,socklen_t *addrlen);
extern int sock_mreceive(int * socklist, int socklistlen, void(*callback) (int * socklist,int index,struct sockaddr*,uint8_t*buf,int len));
extern int sock_getifaddr(const char * ifname,int family, int type, struct sockaddr * sa);
extern int sock_getifhwaddr(const char *ifname, uint8_t * hwaddr, uint8_t * addrlen);
extern void sock_hwaddrtostr(const uint8_t *haddr,int len,char *dst);
extern char *sock_addrtostr(const struct sockaddr *sa, char *s, size_t maxlen);
extern int sock_strtoaddr( const char * s,struct sockaddr * saout);
extern int sock_set_recvtimeout(int sock, int seconds);
extern int sock_getport(struct sockaddr *addr);
extern int sock_setport(struct sockaddr *addr, int port);
extern int sock_getbroadcastaddr(const struct sockaddr * addr,struct sockaddr * broadcastaddr);
extern void sock_addrinit(struct sockaddr *addr,int type);
extern int sock_set_dontfrag(int sock,int val);
/*
enum {
SOCK_IFADDR_ADDRESS,
SOCK_IFADDR_BROADCAST,
};
*/
#ifndef SOCK_RECBUFFERSIZE
#define SOCK_RECBUFFERSIZE 4096
#endif
#endif /* __SOCK_H */

View File

@ -0,0 +1,22 @@
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
void sock_addrinit(struct sockaddr *addr,int type)
{
switch (type){
case AF_INET:
memset(addr,0,sizeof(struct sockaddr_in));
addr->sa_family=type;
#ifdef HAVE_SIN_LEN
addr_sa_len=sizeof(struct sockaddr_in);
#endif
return;
}
}

61
src/capwap/sock_addrlen.c Normal file
View File

@ -0,0 +1,61 @@
/*
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 <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef AF_LINK
# include <net/if_dl.h>
#endif
#ifdef AF_PACKET
# include <netpacket/packet.h>
#endif
#include "sock.h"
/**
* Determine the length of a sockaddr struct
*/
int sock_addrlen(const struct sockaddr * sa)
{
/* determine length */
switch(sa->sa_family){
case AF_INET:
return sizeof(struct sockaddr_in);
#ifdef WITH_IPV6
case AF_INET6:
return sizeof(struct sockaddr_in6);
#endif
#ifdef AF_PACKET
case AF_PACKET:
return sizeof(struct sockaddr_ll);
#endif
#ifdef AF_LINK
case AF_LINK:
return sizeof(struct sockaddr_dl);
#endif
default:
return 0;
}
}

View File

@ -0,0 +1,95 @@
/*
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 <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#ifdef AF_LINK
# include <net/if_dl.h>
#endif
#ifdef AF_PACKET
# include <netpacket/packet.h>
#endif
#include "sock.h"
/*
void sock_hwaddrtostr(const uint8_t *haddr,int len,char *dst)
{
int i;
for (i=0; i<len-1; i++){
sprintf(dst,"%02X:",haddr[i]);
dst+=3;
}
sprintf(dst,"%02X",haddr[i]);
}
*/
char *sock_addrtostr(const struct sockaddr *sa, char *s, size_t maxlen)
{
int port;
switch(sa->sa_family) {
case AF_INET:
inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), s, maxlen);
port = ((struct sockaddr_in *)sa)->sin_port;
sprintf(s,"%s:%i",s,ntohs(port));
break;
case AF_INET6:
inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), s, maxlen);
break;
#ifdef AF_LINK
case AF_LINK:
{
struct sockaddr_dl *sl=(struct sockaddr_dl*)sa;
sock_hwaddrtostr(((uint8_t*)sl->sdl_data)+sl->sdl_nlen,sl->sdl_alen,s);
}
break;
#endif /* AF_LINLK */
#ifdef AF_PACKET
case AF_PACKET:
{
int i;
char *sp=s;
struct sockaddr_ll *sl=(struct sockaddr_ll*)sa;
for (i=0; i<sl->sll_halen-1; i++){
sprintf(sp,"%02X:",sl->sll_addr[i]);
sp+=3;
}
sprintf(sp,"%02X",sl->sll_addr[i]);
}
break;
#endif /* AF_PACKET */
default:
strncpy(s, "Unknown AF", maxlen);
return NULL;
}
return s;
}

78
src/capwap/sock_cmpaddr.c Normal file
View File

@ -0,0 +1,78 @@
/*
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 <stdint.h>
#include <string.h>
#include <netinet/in.h>
#include "sock.h"
/*
* compare two sockaddrs
* returns 0 if both addrs are equal
*
*/
int sock_cmpaddr(const struct sockaddr *addr1, const struct sockaddr *addr2,int cmpport)
{
uint8_t * s1, * s2;
int p1,p2;
int slen;
if (addr1->sa_family != addr2->sa_family){
addr1->sa_family - addr2->sa_family;
}
switch (addr1->sa_family){
case AF_INET:
if (cmpport){
p1 = ((struct sockaddr_in*)addr1)->sin_port;
p2 = ((struct sockaddr_in*)addr2)->sin_port;
if (p1!=p2)
return p1-p2;
}
s1 = (uint8_t*)&(((struct sockaddr_in*)addr1)->sin_addr);
s2 = (uint8_t*)&(((struct sockaddr_in*)addr2)->sin_addr);
slen = sizeof(struct in_addr);
break;
#ifdef WITH_IPV6
case AF_INET6:
if (cmpport){
p1 = ((struct sockaddr_in6*)addr1)->sin6_port;
p2 = ((struct sockaddr_in6*)addr2)->sin6_port;
if (p1!=p2)
return p1-p2;
}
s1 = (uint8_t*)&(((struct sockaddr_in6*)addr1)->sin6_addr);
s2 = (uint8_t*)&(((struct sockaddr_in6*)addr2)->sin6_addr);
slen = sizeof(struct in6_addr);
break;
#endif
default:
return -1;
}
return memcmp(s1,s2,slen);
}

View File

@ -0,0 +1,28 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include "sock.h"
void sock_copyaddr(struct sockaddr_storage *dst, const struct sockaddr * src){
int salen;
/* determine length */
switch(src->sa_family){
case AF_INET:
salen = sizeof(struct sockaddr_in);
break;
#ifdef WITH_IPV6
case AF_INET6:
salen = sizeof(struct sockaddr_in6);
break;
#endif
default:
return;
}
memcpy(dst,src,salen);
}

65
src/capwap/sock_create.c Normal file
View File

@ -0,0 +1,65 @@
/*
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 <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "sock.h"
int sock_create(const struct sockaddr * sa)
{
int sock;
int yes=1;
int salen;
/* determine length */
switch(sa->sa_family){
case AF_INET:
salen = sizeof(struct sockaddr_in);
break;
#ifdef WITH_IPV6
case AF_INET6:
salen = sizeof(struct sockaddr_in6);
break;
#endif
default:
return -1;
}
/* bind a unicast address */
if((sock = socket(sa->sa_family, SOCK_DGRAM, 0)) < 0) {
return -1;
}
/* reuse address */
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes))){
return -1;
};
/* bind address */
if ( bind(sock,sa,salen) < 0) {
return -1;
}
return sock;
}

View File

@ -0,0 +1,31 @@
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include "sock.h"
int sock_getbroadcastaddr(const struct sockaddr * addr,struct sockaddr * broadcastaddr)
{
struct ifaddrs *ifap,*ifa;
if ( getifaddrs(&ifap)==-1)
return 0;
int rc=0;
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if (sock_cmpaddr(addr,ifa->ifa_addr,0))
continue;
memcpy (broadcastaddr, ifa->ifa_broadaddr, sock_addrlen(ifa->ifa_broadaddr));
rc=1;
break;
}
freeifaddrs(ifap);
return rc;
}

View File

@ -0,0 +1,72 @@
/*
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 <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <ifaddrs.h>
#include "sock.h"
int sock_getifaddr(const char * ifname,int family, int type,struct sockaddr * sa)
{
struct ifaddrs *ifap,*ifa;
if ( getifaddrs(&ifap)==-1)
return 0;
int rc=0;
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if (strcmp(ifname,ifa->ifa_name))
continue;
if (ifa->ifa_addr->sa_family != family)
continue;
if (type != 0)
if (!(ifa->ifa_flags & type))
continue;
switch (type){
case 0:
memcpy (sa, ifa->ifa_addr, sock_addrlen(ifa->ifa_addr));
rc=1;
break;
case IFF_BROADCAST:
// memcpy (sa, ifa->ifa_ifu.ifu_broadaddr, sock_addrlen(ifa->ifa_addr));
memcpy (sa, ifa->ifa_broadaddr, sock_addrlen(ifa->ifa_addr));
rc=1;
break;
default:
break;
}
// rc=1;
break;
}
// printf("safam: %i\n",sa->sa_family);
freeifaddrs(ifap);
return rc;
}

View File

@ -0,0 +1,39 @@
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifdef AF_LINK
# include <net/if_dl.h>
#endif
#ifdef AF_PACKET
# include <netpacket/packet.h>
#endif
#include "sock.h"
int sock_getifhwaddr(const char *ifname, uint8_t * hwaddr, uint8_t * addrlen)
{
struct sockaddr_storage sa;
uint8_t *src;
#ifdef AF_PACKET
if (!sock_getifaddr(ifname,AF_PACKET,0,(struct sockaddr*)&sa))
return 0;
*addrlen = ((struct sockaddr_ll*)&sa)->sll_halen;
src = ((struct sockaddr_ll*)&sa)->sll_addr;
#endif
#ifdef AF_LINK
if (!sock_getifaddr(ifname,AF_LINK,0,(struct sockaddr*)&sa))
return 0;
struct sockaddr_dl *sdl = ((struct sockaddr_dl*)&sa);
*addrlen = sdl->sdl_alen;
src = ((uint8_t*)sdl->sdl_data)+sdl->sdl_nlen;
#endif
memcpy(hwaddr,src,*addrlen);
return 1;
}

35
src/capwap/sock_getport.c Normal file
View File

@ -0,0 +1,35 @@
/*
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 "sock.h"
#include <sys/socket.h>
#include <netinet/in.h>
int sock_getport(struct sockaddr *addr)
{
switch (addr->sa_family){
case AF_INET:
return ntohs (((struct sockaddr_in*)addr)->sin_port);
#ifdef WITH_IPV6
case AF_INET6:
return ntohs (((struct sockaddr_in6*)addr)->sin6_port);
#endif
}
return -1;
}

View File

@ -0,0 +1,33 @@
/*
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 <stdio.h>
#include "sock.h"
void sock_hwaddrtostr(const uint8_t *haddr,int len,char *dst)
{
int i;
for (i=0; i<len-1; i++){
sprintf(dst,"%02X:",haddr[i]);
dst+=3;
}
sprintf(dst,"%02X",haddr[i]);
}

View File

@ -0,0 +1,61 @@
/*
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 <stdint.h>
#include <sys/select.h>
#include <string.h>
#include "sock.h"
int sock_mreceive(int * socklist, int socklistlen,
void(*callback) (int * socklist, int index, struct sockaddr*,uint8_t*buf,int len))
{
int n;
fd_set fset;
if ((n=sock_mwait(socklist,socklistlen,&fset))<0)
return -1;
int i;
uint8_t buffer[SOCK_RECBUFFERSIZE];
for( i=0; i<socklistlen; i++){
if (socklist[i]<0)
continue;
if (!FD_ISSET(socklist[i],&fset))
continue;
struct sockaddr_storage srcaddr;
socklen_t sockaddrlen;
memset(&srcaddr,0,sizeof(struct sockaddr_storage));
sockaddrlen = sizeof(struct sockaddr_storage);
int len = sock_receive(socklist[i],
buffer, SOCK_RECBUFFERSIZE,
0,
(struct sockaddr*)&srcaddr, &sockaddrlen);
callback(socklist,i,(struct sockaddr*)&srcaddr,buffer,len);
}
return n;
}

46
src/capwap/sock_mwait.c Normal file
View File

@ -0,0 +1,46 @@
/*
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 <sys/select.h>
#include <stdlib.h>
#include <errno.h>
#include "sock.h"
int sock_mwait(int * socklist, int socklistlen,fd_set * fset)
{
int i;
FD_ZERO(fset);
int max = 0;
for (i=0; i<socklistlen; i++){
if (socklist[i]<=0)
continue;
FD_SET(socklist[i],fset);
if (socklist[i]>max)
max=socklist[i];
}
int n;
while((n=select(max+1, fset, NULL, NULL, NULL)) < 0) {
if (errno != EINTR)
return n;
}
return n;
}

56
src/capwap/sock_receive.c Normal file
View File

@ -0,0 +1,56 @@
/*
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 <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "sock.h"
int sock_receive(int sock,void *buf, size_t len, int flags, struct sockaddr * srcaddr,socklen_t *addrlen)
{
//unsigned int al;
socklen_t al;
al = sizeof (struct sockaddr_storage);
memset(srcaddr, 0, sizeof(struct sockaddr));
// srcaddr->sa_port=999;
int n;
while( (n = recvfrom(sock,(char*)buf,len,flags,srcaddr,&al)) < 0 ){
if (errno!=EINTR)
return n ;
}
// printf("Received betes %d\n",n);
// char str[8000];
// sock_addrtostr(srcaddr,str,1000);
// printf("RECFROM: %s\n",str);
// struct sockaddr_in * s = (struct sockaddr_in*)srcaddr;
// s->sin_port=htons(78);
// sock_addrtostr(srcaddr,str,1000);
// printf("RECFROMset: %s\n",str);
// exit(9);
return n;
}

View File

@ -0,0 +1,25 @@
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
int sock_set_dontfrag(int sock,int val)
{
#if defined IP_MTU_DISCOVER && defined IP_PMTUDISC_DONT
int mtu_type;
if (val)
mtu_type = IP_PMTUDISC_DO;
else
mtu_type = IP_PMTUDISC_WANT;
return setsockopt(sock, SOL_IP, IP_MTU_DISCOVER, &mtu_type, sizeof (mtu_type));
#elif defined IP_DONTFRAG
const int opt = val;
return setsockopt(sock, IPPROTO_IP, IP_DONTFRAG, &opt, sizeof (opt));
#endif
}

View File

@ -0,0 +1,14 @@
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include "sock.h"
int sock_set_recvtimeout(int sock, int seconds)
{
struct timeval timeval;
memset(&timeval,0,sizeof(timeval));
timeval.tv_sec=1;
return setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,&timeval,sizeof(timeval));
}

21
src/capwap/sock_setport.c Normal file
View File

@ -0,0 +1,21 @@
#include "sock.h"
#include <sys/socket.h>
#include <netinet/in.h>
int sock_setport(struct sockaddr *addr, int port)
{
switch (addr->sa_family){
case AF_INET:
((struct sockaddr_in*)addr)->sin_port=htons(port);
break;
#ifdef WITH_IPV6
case AF_INET6:
((struct sockaddr_in6*)addr)->sin6_port=htonl(port);
break;
#endif
default:
return 0;
}
return 1;
}

110
src/capwap/sock_strtoaddr.c Normal file
View File

@ -0,0 +1,110 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include "sock.h"
/*
* convert a string to sockaddr struct.
* the string can contain a ipv4 or ipv6 address including a port number.
* returns 1 on success
* otherwise no success
*/
int sock_strtoaddr(const char * s,struct sockaddr * saout){
char *ips,*ps;
struct in_addr ia;
int port;
#ifdef WITH_IPV6
struct in6_addr ia6;
#endif
int rc;
/* copy the string */
ips = malloc(strlen(s)+1);
strcpy(ips,s);
/* search for a collon to separate the port */
ps = strchr(ips,':');
if (ps != NULL){
*ps='\0';
ps++;
}
else
ps="0";
/* try to parse ip4 address */
rc = inet_pton(AF_INET,ips,&ia);
if (rc==1)
{
port = atoi(ps);
if (port > 65535)
rc=0;
}
if (rc==1){
/* it's an ipv4 address */
struct sockaddr_in * sa;
sa = (struct sockaddr_in*)saout;
memset(sa,0,sizeof(struct sockaddr_in));
#ifdef HAVE_SIN_LEN
sa->sin_len=sizeof(struct sockaddr_in);
#endif
sa->sin_family = AF_INET;
sa->sin_addr=ia;
sa->sin_port=htons(port);
}
#ifdef WITH_IPV6
if (rc==0){
strcpy(ips,s);
ps = strchr(ips,'.');
if (ps != NULL){
*ps='\0';
ps++;
}
else
ps="0";
rc = inet_pton(AF_INET6,s,&ia6);
if (rc==1){
/* it's an ipv6 address */
struct sockaddr_in6 * sa;
sa = (struct sockaddr_in6*)saout;
memset(sa,0,sizeof(struct sockaddr_in6));
#ifdef HAVE_SIN_LEN
sa->sin6_len=sizeof(struct sockaddr_in6);
#endif
sa->sin6_family = AF_INET6;
sa->sin6_addr=ia6;
sa->sin6_port=htons(atoi(ps));
}
}
#endif
if (rc!=1){
if (rc!=-1)
errno=EINVAL;
}
free (ips);
return rc;
}

30
src/capwap/stravltree.c Normal file
View File

@ -0,0 +1,30 @@
#include <string.h>
#include <stdlib.h>
#include "stravltree.h"
static int cmp(const void *v1,const void*v2)
{
return strcmp( (char*)v1,(char*)v2);
}
static void del(void* d)
{
free (d);
return;
}
struct avltree * stravltree_create()
{
return avltree_create(cmp,del);
}
const char * stravltree_add(struct avltree * t, const char * str)
{
char * s = strdup(str);
if (!s)
return 0;
return avltree_add(t,s);
}

12
src/capwap/stravltree.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef __STRAVLTREE_H
#define __STRAVLTREE_H
#include "avltree.h"
extern struct avltree * stravltree_create();
const char * stravltree_add(struct avltree * t, const char * str);
#define stravltree_destroy(t) avltree_destroy(t)
#define stravltree_foreach(t,f,p,d) avltree_foreach(t,f,p,d)
#endif

121
src/capwap/wtpinfo.c Normal file
View File

@ -0,0 +1,121 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "wtpinfo.h"
#include "capwap.h"
#include "cw_log.h"
int cw_readelem_ecn_support(uint8_t *ecn_support, int type, uint8_t * msgelem, int len)
{
if (type != CWMSGELEM_ECN_SUPPORT)
return 0;
if (len!=1){
cw_log_debug0("Discarding ECN_SUPPORT msgelem, wrong size, type=%d,len=%d",type,len);
return 1;
}
*ecn_support=*msgelem;
return 1;
}
/*
int wtpinfo_readelem_ecn_support(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len)
{
if (type != CWMSGELEM_ECN_SUPPORT)
return 0;
if (len!=1){
cw_log_debug0("Discarding ECN_SUPPORT msgelem, wrong size, type=%d,len=%d",type,len);
return 1;
}
wtpinfo->ecn_support=*msgelem;
return 1;
}
*/
int cw_readelem_cw_local_ip_addr(struct sockaddr * local_ip, int type, uint8_t * msgelem, int len)
{
switch (type){
case CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS:
{
if (len!=4)
return -1;
struct sockaddr_in * sain = (struct sockaddr_in*)local_ip;
memset(sain,0,sizeof(struct sockaddr_in));
#ifdef HAVE_SIN_LEN
sain->sa_len=sizeof(struct sockaddr_in);
#endif
memcpy(&sain->sin_addr,msgelem,len);
sain->sin_family=AF_INET;
return 1;
}
#ifdef WITH_IPV6
case CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS:
{
if (len!=16)
return -1;
struct sockaddr_in6 * sain = (struct sockaddr_in6*)local_ip;
memset(sain,0,sizeof(struct sockaddr_in6));
#ifdef HAVE_SIN6_LEN
sain->sa_len=sizeof(struct sockaddr_in);
#endif
memcpy(&sain->sin6_addr,msgelem,len);
sain->sin6_family=AF_INET6;
return 1;
}
#endif
}
return 0;
}
int wtpinfo_readelem_cw_local_ip_addr(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len)
{
switch (type){
case CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS:
{
if (len!=4)
return -1;
struct sockaddr_in * sain = (struct sockaddr_in*)&wtpinfo->local_ip;
memset(sain,0,sizeof(struct sockaddr_in));
#ifdef HAVE_SIN_LEN
sain->sa_len=sizeof(struct sockaddr_in);
#endif
memcpy(&sain->sin_addr,msgelem,len);
sain->sin_family=AF_INET;
return 1;
}
#ifdef WITH_IPV6
case CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS:
{
if (len!=16)
return -1;
struct sockaddr_in6 * sain = (struct sockaddr_in6*)&wtpinfo->local_ip;
memset(sain,0,sizeof(struct sockaddr_in6));
#ifdef HAVE_SIN6_LEN
sain->sa_len=sizeof(struct sockaddr_in);
#endif
memcpy(&sain->sin6_addr,msgelem,len);
sain->sin6_family=AF_INET6;
return 1;
}
#endif
}
return 0;
}

80
src/capwap/wtpinfo.h Normal file
View File

@ -0,0 +1,80 @@
/*
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/>.
*/
#ifndef __WTPINFO_H
#define __WTPINFO_H
#include <stdint.h>
#include <sys/socket.h>
#include "radioinfo.h"
/* structure to hold info about a wtp */
struct wtpinfo{
uint8_t *name;
uint8_t * location;
uint32_t vendor_id;
uint8_t* model_no;
uint8_t* serial_no;
int max_radios;
int radios_in_use;
uint8_t frame_tunnel_mode;
uint8_t mac_type;
uint8_t * session_id;
int session_id_len;
struct radioinfo radioinfo[31];
uint8_t * hardware_version;
uint32_t hardware_vendor_id;
uint8_t * software_version;
uint32_t software_vendor_id;
uint8_t * bootloader_version;
uint32_t bootloader_vendor_id;
uint8_t * macaddress;
int macaddress_len;
uint8_t ecn_support;
uint16_t max_msg_len;
uint8_t discovery_type;
struct sockaddr_storage local_ip;
};
extern int wtpinfo_readelem_wtp_board_data(struct wtpinfo *wtpinfo, int type, uint8_t *msgelem, int len);
extern int wtpinfo_readelem_wtp_mac_type(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len);
extern int wtpinfo_readelem_wtp_radio_info(struct wtpinfo * wtpinfo,int type,uint8_t *msgelem, int len);
extern int wtpinfo_readelem_wtp_descriptor(struct wtpinfo * wtpinfo, int type, uint8_t *msgelem, int len);
extern int wtpinfo_readelem_wtp_frame_tunnel_mode(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len);
extern int wtpinfo_readelem_discovery_type(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len);
extern int wtpinfo_readelem_location_data(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len);
extern int wtpinfo_readelem_wtp_name(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len);
extern int wtpinfo_readelem_session_id(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len);
//extern int wtpinfo_readelem_ecn_support(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len);
extern int wtpinfo_readelem_cw_local_ip_addr(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len);
#define wtpinfo_readelem_ecn_support(wtpinfo,type,msg,len) cw_readelem_ecn_support(&wtpinfo->ecn_support,type,msg,len)
#endif

131
src/capwap/wtpinfo_print.c Normal file
View File

@ -0,0 +1,131 @@
/*
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 <stdio.h>
#include <stdlib.h>
#include "capwap.h"
#include "sock.h"
void radioinfo_print(struct radioinfo * radioinfo)
{
printf(" RID %d\n",radioinfo->rid);
printf(" Modes: ");
if(radioinfo->type & CWRADIO_TYPE_B){
printf("B");
}
if(radioinfo->type & CWRADIO_TYPE_G){
printf("G");
}
if(radioinfo->type & CWRADIO_TYPE_A){
printf("A");
}
if(radioinfo->type & CWRADIO_TYPE_N){
printf("N");
}
printf("\n");
}
void wtpinfo_print(struct wtpinfo * wtpinfo)
{
char str[64];
printf ("=== WTP Info: %p ===\n",wtpinfo);
printf (" Name:\t\t\t%s\n", (!wtpinfo->name ? (uint8_t*)"Not set" : wtpinfo->name) );
printf (" Location:\t\t%s\n", (!wtpinfo->location ? (uint8_t*)"Not set" : wtpinfo->location) );
printf (" MAC Adress:\t\t");
if (wtpinfo->macaddress){
sock_hwaddrtostr(wtpinfo->macaddress,wtpinfo->macaddress_len,str);
printf("%s\n",str);
}
else
printf("Not set\n");
sock_addrtostr((struct sockaddr*)&wtpinfo->local_ip,str,64);
printf (" Local IP:\t\t%s\n",str);
printf (" Vendor ID:\t\t%d\n", wtpinfo->vendor_id );
printf (" Model No.:\t\t%s\n", (!wtpinfo->model_no ? (uint8_t*)"Not set" : wtpinfo->model_no) );
printf (" Serial No.:\t\t%s\n", (!wtpinfo->serial_no ? (uint8_t*)"Not set" : wtpinfo->serial_no) );
printf (" Software Version:\t%s\n", (!wtpinfo->software_version ? (uint8_t*)"Not set" : wtpinfo->software_version) );
printf (" Max Radios:\t\t%d\n",wtpinfo->max_radios);
printf (" Radios in use:\t\t%d\n",wtpinfo->radios_in_use);
printf (" Session ID:\t\t");
if (wtpinfo->session_id) {
int i;
for (i=0; i<wtpinfo->session_id_len; i++)
printf("%02X",wtpinfo->session_id[i]);
}
else
printf ("Not set");
printf("\n");
printf (" MAC Type:\t\t");
switch (wtpinfo->mac_type){
case WTP_MAC_TYPE_LOCAL:
printf("local");
break;
case WTP_MAC_TYPE_SPLIT:
printf("split");
break;
case WTP_MAC_TYPE_BOTH:
printf("local, split");
break;
}
printf("\n");
printf (" Frame Tunnel Mode:\t");
printf("(%08X)",wtpinfo->frame_tunnel_mode);
char * c="";
if (wtpinfo->frame_tunnel_mode & WTP_FRAME_TUNNEL_MODE_N){
printf ("%snative",c);c=", ";
}
if (wtpinfo->frame_tunnel_mode & WTP_FRAME_TUNNEL_MODE_E){
printf ("%s802.3",c);c=", ";
}
if (wtpinfo->frame_tunnel_mode & WTP_FRAME_TUNNEL_MODE_L){
printf ("%sLocal bridging",c);c=", ";
}
if (wtpinfo->frame_tunnel_mode == 0)
printf(" None");
printf("\n");
printf(" Radios: %d\n",wtpinfo->max_radios);
int i;
for (i=0; i<wtpinfo->max_radios; i++){
radioinfo_print(&wtpinfo->radioinfo[i+1]);
}
}

View File

@ -0,0 +1,23 @@
#include "wtpinfo.h"
#include "capwap.h"
#include "cw_log.h"
int wtpinfo_readelem_discovery_type(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len)
{
if (type != CWMSGELEM_DISCOVERY_TYPE)
return 0;
if (len!=1){
cw_log_debug0("Discarding WTP_DISCOVERY_TYPE msgelem, wrong size, type=%d,len=%d",type,len);
return 1;
}
wtpinfo->discovery_type=*msgelem;
return 1;
}

View File

@ -0,0 +1,19 @@
#include "wtpinfo.h"
#include "capwap.h"
#include "cw_util.h"
#include "cw_log.h"
int wtpinfo_readelem_location_data(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len)
{
if (type != CWMSGELEM_LOCATION_DATA)
return 0;
cw_setstr(&wtpinfo->location,msgelem,len);
return 1;
}

Some files were not shown because too many files have changed in this diff Show More