Compare commits

...

55 Commits

Author SHA1 Message Date
7u83 5423709dda Removed libwifi dependencies 2022-09-20 10:35:23 +02:00
7u83 e974b3ae2d Work on wifi implemntation 2022-09-20 08:31:04 +02:00
7u83 07257f51fe Removed 2022-09-18 23:36:34 +02:00
7u83 dec1cf2003 Fixed missing hexdum for elems with "elem_dmp" 2022-09-18 23:14:22 +02:00
7u83 40427b3816 Use correct len for last fragmented packet 2022-09-18 18:06:53 +02:00
7u83 435b3f823e Correct fragment handling when sendig fragmented packets 2022-09-18 08:53:49 +02:00
7u83 ae686f4634 new funtion to send CAPWAP packets 2022-09-18 08:04:49 +02:00
7u83 b292b88d49 More dot11 stuff added 2022-09-15 07:47:41 +02:00
7u83 97533f67cc some stuff for dot11 handling added 2022-09-13 08:18:05 +02:00
7u83 259c6c5e66 Work on data channel 2022-09-12 00:28:58 +02:00
7u83 bc5dea6016 script to download and extract hostapd 2022-09-07 16:40:24 +02:00
7u83 ec6809b552 Work on data channel 2022-09-06 09:16:10 +02:00
7u83 1297c46a15 Removed netcon 2022-09-04 21:41:23 +02:00
7u83 cc257ed27f Fragman preserves packet header 2022-09-04 21:40:08 +02:00
7u83 059c0e542e Added verbosity for ap-mode 2022-09-04 21:38:22 +02:00
7u83 9d3fa452aa Fix: Add brackets around defined value 2022-09-04 18:43:17 +02:00
7u83 300b737efd Better formatting 2022-09-04 14:00:43 +02:00
7u83 085e657c76 Updated what you can do so far 2022-09-04 13:47:51 +02:00
7u83 f62b1c56e1 Added some (test) macros to git 2022-09-04 13:29:15 +02:00
7u83 acc7b692ee Deleted out-commented and unused code 2022-09-04 13:23:27 +02:00
7u83 8a8381731f fixed typo 2022-09-04 12:31:19 +02:00
7u83 6f4ba62080 actube -h shows some help about debug levels 2022-09-04 12:30:08 +02:00
7u83 0eb3e16932 Moved debug options into a mavl object
So there is an unlimited number of debug options, instead of 32 as
before.
2022-09-04 11:13:12 +02:00
7u83 ca4a6b9996 Ununsed stuff 2022-09-04 08:29:37 +02:00
7u83 66db979fdb New type cw_type_bits 2022-09-03 17:27:19 +02:00
7u83 0078c07e58 'CFG atcher' in wtpman 2022-09-02 12:03:38 +02:00
7u83 20bd835f63 Fixed size of led state config >= v7.3 2022-09-02 02:15:32 +02:00
7u83 1e8b52fd03 Moved Cisco ssl cfg stuff to mod/cisco 2022-09-02 02:00:43 +02:00
7u83 2f1985b821 Example WLAN definition 2022-09-02 01:51:38 +02:00
7u83 27506fa788 We can join an 1131 AP, and bring up a WLAN
data channel is currently missing
2022-09-01 23:09:33 +02:00
7u83 5ed35979cd Moved Callbacks to mods 2022-09-01 10:24:40 +02:00
7u83 2064f7dba1 put out a correct WTP Descriptor, even if no data is available 2022-08-30 22:13:22 +02:00
7u83 190c94ded4 Work on wtp descriptor CAPWAP 2022-08-30 20:25:55 +02:00
7u83 4fe2bae7f7 Deleted unused .ktv 2022-08-30 14:56:26 +02:00
7u83 89e7e61e1d Fixed some bugs, added more Cisco elements
Almost able to create a WLAN
2022-08-30 08:52:18 +02:00
7u83 2b055175c7 Uses DTLS_timer_cb to work with old APs 2022-08-29 21:29:11 +02:00
7u83 0ebac6c98e Cisco ht-caps can be parsed 2022-08-28 21:21:21 +02:00
7u83 15e363f34e Read SIG Payload and more cisco elements 2022-08-28 16:19:49 +02:00
7u83 2b6dc68ee5 Some macros added 2022-08-28 13:14:35 +02:00
7u83 e39f4eb097 load and save cmds are added 2022-08-28 13:10:36 +02:00
7u83 4ef1b69f83 Fixes in RPC 2022-08-28 11:42:11 +02:00
7u83 a77023165b Added lots of RPC cmds added. send is possible. 2022-08-28 09:06:15 +02:00
7u83 62616b5e7b New array type 2022-08-27 21:05:34 +02:00
7u83 79b688c38e Fixed seg fault when mods for some reason fail fail to load. 2022-08-27 10:40:13 +02:00
7u83 4995cac9b8 WTP reads two configs no
It read 1st the file startup.ckv, wich will
never be overwritten.
And then config.ckv, wich will saved when
ever config cahnges ar made.
2022-08-27 10:16:49 +02:00
7u83 d7c826fac6 Removed 2022-08-27 10:16:35 +02:00
7u83 d668e0e5a7 Initial commit 2022-08-27 10:15:36 +02:00
7u83 63cb0b928f Added comments 2022-08-27 10:05:02 +02:00
7u83 361e9dd1aa Removed radioinfo.h 2022-08-27 01:03:33 +02:00
7u83 3f69dbf67e More clean-up 2022-08-27 00:50:59 +02:00
7u83 43b75502f7 Fix: removed cw_in_generic_struct from Makefile 2022-08-27 00:45:08 +02:00
7u83 4a565efff1 Removed a lot of old stuff, compiles almost w/o warnings 2022-08-27 00:41:47 +02:00
7u83 54955daff4 More Cisco Elements decoded 2022-08-27 00:24:20 +02:00
7u83 4047707fa8 Unused files 2022-08-26 21:22:18 +02:00
7u83 5b1690bfbf Cisco RRM element implemented 2022-08-26 21:12:39 +02:00
145 changed files with 4440 additions and 5490 deletions

View File

@ -15,7 +15,6 @@ cd ..
make
Ubuntu
------

View File

@ -2,6 +2,62 @@ AC-Tube
=======
Open Source CAPWAP WLC + WTP
Current status: early development.
Current status: development.
See also http://7u83.cauwersin.com/?cat=28
What you can do so far ...
Read INSTALL and compile actube.
Then ...
Create certificates:
cd ssl
sh all.sh
cd ..
Edit src/actube/config.ckv and set your IP in
capwap/control-ip-address/address.0
Start actube with some debug options:
cd src/ac
./actube -d std -d mod -d elem\_detail -d elem\_dmp
If you have an AP with IOS 7.3x it should connect. Others
might connect, too.
Make sure on the AP you heve made
clear capwap private-config.
In another terminal window connect to the RPC interface:
cd src/ac
./act -s 127.0.0.1:5000
Send some commands to bring up a WLAN:
list # list all connected APs
select <apname> # set <apname> to the name of AP you want to select
status # show status of selected AP
# the following sequence activates a WLAN called actube on AP
load wlan1
send
clear
load activate
send
status # This should display now oper status for
# interface 0 enabled
CWAPWAP data layer is still not finished, so you can't use the WLAN

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<CodeLite_Workspace Name="actube" Database="">
<Project Name="ac" Path="ac.project" Active="No"/>
<Project Name="wtp" Path="wtp.project" Active="No"/>
<Project Name="mod_cipwap" Path="mod_cipwap.project" Active="No"/>
<Project Name="mod_capwap" Path="mod_capwap.project" Active="No"/>
<Project Name="mod_cisco" Path="mod_cisco.project" Active="Yes"/>
<Project Name="libcw" Path="libcw.project" Active="No"/>
<Project Name="mod_capwap80211" Path="mod_capwap80211.project" Active="No"/>
<Project Name="mod_fortinet" Path="mod_fortinet.project" Active="No"/>
<BuildMatrix>
<WorkspaceConfiguration Name="Debug" Selected="yes">
<Environment/>
<Project Name="ac" ConfigName="Debug"/>
<Project Name="wtp" ConfigName="Debug"/>
<Project Name="mod_cipwap" ConfigName="Debug"/>
<Project Name="mod_capwap" ConfigName="Debug"/>
<Project Name="mod_cisco" ConfigName="Debug"/>
<Project Name="libcw" ConfigName="Debug"/>
<Project Name="mod_capwap80211" ConfigName="Debug"/>
<Project Name="mod_fortinet" ConfigName="Debug"/>
</WorkspaceConfiguration>
<WorkspaceConfiguration Name="Release" Selected="yes">
<Environment/>
<Project Name="ac" ConfigName="Release"/>
<Project Name="wtp" ConfigName="Release"/>
<Project Name="mod_cipwap" ConfigName="Release"/>
<Project Name="mod_capwap" ConfigName="Release"/>
<Project Name="mod_cisco" ConfigName="Release"/>
<Project Name="libcw" ConfigName="Release"/>
<Project Name="mod_capwap80211" ConfigName="Release"/>
<Project Name="mod_fortinet" ConfigName="Release"/>
</WorkspaceConfiguration>
</BuildMatrix>
</CodeLite_Workspace>

View File

@ -9,6 +9,7 @@ OBJS = \
discovery_cache.o\
rpc.o\
statemachine.o\
#hapd.o
ACTOBJS = \
act.o
@ -26,13 +27,18 @@ LIBS+=-lnettle
LIBS+=-lssl
LIBS+=-lcrypto
LIBS+=-ledit
#LIBS+=-l:libhapd.a
INCL_DIRS=-I../ -I/usr/local/include -I./ -I../../include
INCL_DIRS=-I../ -I/usr/local/include -I./ -I../../include -I../../include/hostapd -I../../include/hostapd/utils
#FLAGS=-DWITH_IPV6 -DWITH_OPENSSL -DSYS_ARCH="$(ARCH)" -DSYS_ARCH="XXX"
FLAGS=-DWITH_IPV6 -DUSE_OPENSSL -DSYS_ARCH='"$(KERNEL)/$(ARCH)"'
all: act actube
act: act.c
$(CC) act.c $(INCL_DIRS) $(LIBPATH) -DSYS_ARCH='"$(KERNEL)/$(ARCH)"' -o act -l:libcw.a -lasan -lcrypto -ledit
.c.o:
@echo " $(CC) "$<
@ -43,8 +49,9 @@ all: $(PRG) $(ACTPRG)
$(PRG): $(OBJS)
$(CC) $(OBJS) -o $(PRG) $(LIBPATH) $(LDFLAGS) $(LIBS)
$(ACTPRG): $(ACTOBJS)
$(CC) $(ACTOBJS) -o $(ACTPRG) $(LIBPATH) $(LDFLAGS) $(LIBS) -ledit
#$(ACTPRG): $(ACTOBJS)
# $(CC) $(ACTOBJS) -o $(ACTPRG) $(LIBPATH) $(LIBS) -ledit
#$(CC) $(ACTOBJS) $(ACTPRG) $(LIBPATH) $(LDFLAGS) $(LIBS) -ledit

View File

@ -20,6 +20,7 @@ enum {
int start_rpc(cw_Cfg_t *global_cfg);
int test_shell();
void hapd_run();
#endif

View File

@ -124,10 +124,21 @@ static int parse_args (int argc, char *argv[], struct bootcfg * bootcfg)
case '?':
exit(EXIT_FAILURE);
default:
case 'h':
printf("%s: -vcmh\n",argv[0]);
case 'h':
{
FILE *out = stdout;
fprintf(out, "Usage:");
fprintf(out, "%s [ options ] ",argv[0]);
fprintf(out, "\nOptions are:\n");
fprintf(out, " -c <file>: specify a config file\n");
fprintf(out, " -p <path>: specify a path where to search for modules\n");
fprintf(out, " -v: print version information\n");
fprintf(out, " -d <level>: set debug level, multiple -d's are possible\n");
fprintf(out, " <level> can be one of these:\n");
cw_dbg_print_help(out," ");
exit(EXIT_SUCCESS);
break;
}
}
}
return 0;
@ -200,6 +211,7 @@ return 0;
*/
static cw_Cfg_t * global_cfg = NULL;
void process_wtp_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len, int dta);
int main (int argc, char *argv[])
@ -225,6 +237,12 @@ int main (int argc, char *argv[])
goto errX;
};
//hapd_run(); // init
//stop();
//const char *ttt = cw_cfg_get(global_cfg,"cisco/ssl-cipher",NULL);
//printf("CFG: %s\n",ttt);
//stop();
cw_log_name = "AC-Tube";
/*
@ -440,7 +458,7 @@ int ac_run(cw_Cfg_t * cfg)
(struct sockaddr *) &srcaddr,
&srcaddrlen);
process_cw_data_packet (i, (struct sockaddr *) &srcaddr, buffer, len);
process_wtp_packet (i, (struct sockaddr *) &srcaddr, buffer, len,1);
}
@ -453,7 +471,7 @@ int ac_run(cw_Cfg_t * cfg)
(struct sockaddr *) &srcaddr,
&srcaddrlen);
process_ctrl_packet (i, (struct sockaddr *) &srcaddr, buffer, len);
process_wtp_packet (i, (struct sockaddr *) &srcaddr, buffer, len,0);
}
}
@ -467,14 +485,14 @@ int ac_run(cw_Cfg_t * cfg)
void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
cw_dbg (DBG_X, "There is a data packet now");
// cw_dbg (DBG_X, "There is a data packet now");
dataman_list_lock();
cw_dbg (DBG_X, "Dataman list locked, now getting");
// cw_dbg (DBG_X, "Dataman list locked, now getting");
struct dataman * dm = dataman_list_get (socklist[index].data_sockfd, addr);
cw_dbg (DBG_X, "Dataman list locked, now gotted");
// cw_dbg (DBG_X, "Dataman list locked, now gotted");
cw_dbg (DBG_INFO, "Packet for dataman %s,%d", sock_addr2str_p (addr, sock_buf), socklist[index].data_sockfd);
// cw_dbg (DBG_INFO, "Packet for dataman %s,%d", sock_addr2str_p (addr, sock_buf), socklist[index].data_sockfd);
if (!dm) {
cw_dbg (DBG_INFO, "No dataman %s,%d", sock_addr2str_p (addr, sock_buf), socklist[index].data_sockfd);
@ -486,15 +504,12 @@ void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer,
}
dataman_list_add (dm);
dataman_start (dm);
}
dataman_list_unlock();
//dataman_add_packet (dm, buffer, len);
dataman_add_packet (dm, buffer, len);
return;
@ -517,7 +532,7 @@ void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer,
}
void process_cw_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len)
void process_wtp_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len, int dta)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
@ -537,6 +552,10 @@ void process_cw_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer,
if (!wtpman) {
if (dta){
cw_dbg(DBG_PKT_ERR,"Data packet w/o wtpman received, ignoring");
return;
}
wtpman = wtpman_create (index, addr, preamble & 0xf, global_cfg);
@ -558,9 +577,12 @@ void process_cw_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer,
wtpman_start (wtpman, preamble & 0xf);
}
//printf("Got Packet with len: %d\n",len);
wtpman_addpacket (wtpman, buffer, len);
if(!dta)
wtpman_addpacket (wtpman, buffer, len);
else{
// cw_dbg(DBG_X,"Data packet received");
wtpman_datapacket (wtpman, buffer, len);
}
wtplist_unlock();
}
@ -631,7 +653,7 @@ void process_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer, in
{
switch (socklist[index].ac_proto) {
case AC_PROTO_CAPWAP:
process_cw_ctrl_packet (index, addr, buffer, len);
// process_cw_ctrl_packet (index, addr, buffer, len);
return;
/*case AC_PROTO_LWAPP:

View File

@ -15,10 +15,18 @@ capwap/ssl-dhbits: 1024
capwap/ssl-keyfile: "../../ssl/intermediate-ca/int-ca.key"
capwap/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt"
cisco/ssl-keyfile: "../../ssl/intermediate-ca/int-ca.key"
cisco/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt"
cisco/ssl-cipher: DEFAULT
cisco/ssl-dhbits: 2048
#mod/cisco/ssl-keyfile: "../../ssl/intermediate-ca/int-ca.key"
#mod/cisco/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt"
#
mod/cisco/ssl-keyfile: "../../ssl/certs/ac-cisco.key"
mod/cisco/ssl-certfile: "../../ssl/certs/ac-cisco.pem"
#cisco/ssl-cipher: DEFAULT
mod/cisco/ssl-cipher: RSA
mod/cisco/ssl-dhbits: 2048
#
@ -43,7 +51,15 @@ actube/mod.2: capwap80211
#actube/rpc/listen: unix:/tmp/actube
actube/rpc/listen: tcp:127.0.0.1:5000
actube/rpc/enable: true
actube/rpc/macros-dir: ./rpc-macros
#
# This catches the initial config af a connecting WTP
# From Discovery to CFG Update
# The config is saved to a file named
# wtp-<wtpname-or-ip>.cfg
#
actube/save-initial-wtp-config: true
capwap/ac-descriptor/dtls-policy: 1
capwap/ac-descriptor/hardware/vendor: 4232704
@ -59,17 +75,100 @@ capwap/ac-descriptor/station-limit: 1000
capwap/ac-descriptor/stations: 0
capwap/control-ip-address/address.0: 192.168.0.24
capwap/control-ip-address/address.0: 192.168.0.14
wlan.0/capwap80211/capability: 0
wlan.0/capwap80211/key-index: 0
wlan.0/capwap80211/key-status: 0
wlan.0/capwap80211/key: 1234
wlan.0/capwap80211/group-tcs: 123
wlan.0/capwap80211/qos: 0
wlan.0/capwap80211/auth-type: 1
wlan.0/capwap80211/mac-mode: 1
wlan.0/capwap80211/tunnel-mode: 1
wlan.0/capwap80211/suppress-ssid: false
wlan.0/capwap80211/ssid: ssid
#
# CAPWAP Timers
#
capwap/timers/change-state-pending-timer: Word: 3
capwap/timers/data-check-timer: Word: 10
capwap/timers/echo-interval :Byte: 30
capwap/timers/max-discovery-interval :Byte: 10
capwap/timers/change-state-pending-timer: 3
capwap/timers/data-check-timer: 10
capwap/timers/echo-interval: 30
capwap/timers/max-discovery-interval: 10
capwap/decryption-error-report-period: 120
capwap/idle-timeout: 300
radio-cfg-a/capwap80211/wtp-radio-config/beacon-period: 100
radio-cfg-a/capwap80211/wtp-radio-config/bssid: .x003a9902fac0
radio-cfg-a/capwap80211/wtp-radio-config/cfg-period: 4
radio-cfg-a/capwap80211/wtp-radio-config/beacon-period: 100
radio-cfg-a/capwap80211/wtp-radio-config/bssid: .x003a9902fac0
radio-cfg-a/capwap80211/wtp-radio-config/cfg-period: 4
radio-cfg-a/capwap80211/wtp-radio-config/cfg-type: 1
radio-cfg-a/capwap80211/wtp-radio-config/cfp-maximum-duration: 60
radio-cfg-a/capwap80211/wtp-radio-config/country-str1: "DE "
radio-cfg-a/capwap80211/wtp-radio-config/country-str2: "DE "
radio-cfg-a/capwap80211/wtp-radio-config/occupancy-limit: 100
radio-cfg-a/capwap80211/wtp-radio-config/reg: 167772416
radio-cfg-a/cisco/direct-sequence-control/cfg-type: 1 - global
radio-cfg-a/cisco/direct-sequence-control/current-cca-mode: 0
radio-cfg-a/cisco/direct-sequence-control/current-channel: 1
radio-cfg-a/cisco/direct-sequence-control/energy-detect-threshold: -50
#mode-802.11g support
#radio-cfg-a/cisco/direct-sequence-control/unknown: 1
radio-cfg-a/cisco/mac-operation/fragmentation-threshold: 2346
radio-cfg-a/cisco/mac-operation/long-retry: 4
radio-cfg-a/cisco/mac-operation/reserved: 1
radio-cfg-a/cisco/mac-operation/rts-threshold: 2347
radio-cfg-a/cisco/mac-operation/rx-msdu-lifetime: 512
radio-cfg-a/cisco/mac-operation/short-retry: 7
radio-cfg-a/cisco/mac-operation/tx-msdu-lifetime: 512
radio-cfg-a/cisco/multi-domain-capability/first-channel: 1
radio-cfg-a/cisco/multi-domain-capability/max-tx-power-level: 65535
radio-cfg-a/cisco/multi-domain-capability/number-of-channels: 13
radio-cfg-a/cisco/multi-domain-capability/reserved: 1
radio-cfg-a/capwap80211/rate-set: .x82848b960c1218243048606c
radio-cfg-a/cisco/antenna-payload/802-11n-rx-antennas: 3
radio-cfg-a/cisco/antenna-payload/802-11n-tx-antennas: 7
radio-cfg-a/cisco/antenna-payload/antenna-cnt: 2
radio-cfg-a/cisco/antenna-payload/antenna-mode: 3
radio-cfg-a/cisco/antenna-payload/antenna.0: 1 - Internal Antenna
radio-cfg-a/cisco/antenna-payload/antenna.1: 1 - Internal Antenna
radio-cfg-a/cisco/antenna-payload/diversity-selection: 255
radio-cfg-a/cisco/antenna-payload/unknown: 0
radio-cfg-b/capwap80211/wtp-radio-config/beacon-period: 100
radio-cfg-b/capwap80211/wtp-radio-config/bssid: .x003a9902fac0
radio-cfg-b/capwap80211/wtp-radio-config/cfg-period: 4
radio-cfg-b/capwap80211/wtp-radio-config/beacon-period: 100
radio-cfg-b/capwap80211/wtp-radio-config/bssid: .x003a9902fac0
radio-cfg-b/capwap80211/wtp-radio-config/cfg-period: 4
radio-cfg-b/capwap80211/wtp-radio-config/cfg-type: 1
radio-cfg-b/capwap80211/wtp-radio-config/cfp-maximum-duration: 60
radio-cfg-b/capwap80211/wtp-radio-config/country-str1: "DE "
radio-cfg-b/capwap80211/wtp-radio-config/country-str2: "DE "
radio-cfg-b/capwap80211/wtp-radio-config/occupancy-limit: 100
radio-cfg-b/capwap80211/wtp-radio-config/reg: 167772416

View File

@ -5,10 +5,12 @@
#include "cw/timer.h"
#include "cw/cw.h"
#include "cw/format.h"
#include "cw/netconn.h"
#include "cw/conn.h"
#include "cw/log.h"
#include "cw/dbg.h"
#include "cw/file.h"
#include "cw/dot11.h"
#include "wtplist.h"
#include "dataman.h"
@ -19,8 +21,8 @@ pthread_mutex_t dataman_list_mutex;
static int cmp(const void *d1, const void *d2)
{
struct netconn *nc1 = ((struct dataman *) d1)->nc;
struct netconn *nc2 = ((struct dataman *) d1)->nc;
struct cw_Conn *nc1 = ((struct dataman *) d1)->nc;
struct cw_Conn *nc2 = ((struct dataman *) d1)->nc;
int r = nc1->sock - nc2->sock;
if (r != 0)
@ -52,7 +54,7 @@ void dataman_destroy(struct dataman *dm)
{
if (!dm)
return;
netconn_destroy(dm->nc);
conn_destroy(dm->nc);
}
struct dataman *dataman_create(int sock, struct sockaddr *addr)
@ -60,15 +62,15 @@ struct dataman *dataman_create(int sock, struct sockaddr *addr)
struct dataman *dm = malloc(sizeof(struct dataman));
if (!dm)
return NULL;
dm->nc = netconn_create(sock, addr, 100);
memset(dm,0,sizeof(struct dataman));
dm->nc = cw_conn_create(sock, addr, 100);
return dm;
}
struct dataman *dataman_list_get(int sock, struct sockaddr *addr)
{
struct netconn search_nc;
struct cw_Conn search_nc;
struct dataman search_dm;
search_nc.sock = sock;
@ -78,7 +80,7 @@ struct dataman *dataman_list_get(int sock, struct sockaddr *addr)
struct dataman *dm = mavl_get(dataman_list, &search_dm);
cw_dbg(DBG_X,"Getting dataman %p",dm);
// cw_dbg(DBG_X,"Getting dataman %p",dm);
return dm;
}
@ -91,7 +93,7 @@ struct dataman *dataman_list_add(struct dataman *dm)
int dataman_process_keep_alive(struct netconn *nc, uint8_t *rawmsg, int len)
int dataman_process_keep_alive(struct cw_Conn *nc, uint8_t *rawmsg, int len)
{
struct dataman * dm = (struct dataman *)(nc->data);
@ -133,7 +135,7 @@ int dataman_process_keep_alive(struct netconn *nc, uint8_t *rawmsg, int len)
printf("len len %d\n",l);
printf("Total len = %d\n",total_len);
netconn_send_capwap_msg(nc,buffer,total_len);
cw_send_msg(nc,buffer,total_len);
return len;
@ -167,26 +169,87 @@ int dataman_process_keep_alive(struct netconn *nc, uint8_t *rawmsg, int len)
return -1;
}
int dataman_process_message0(struct netconn *nc, uint8_t * rawmsg, int len,
int dataman_process_message0(struct cw_Conn *nc, uint8_t * rawmsg, int len,
struct sockaddr *from)
{
static int c=0;
char fn[100];
sprintf(fn,"wificap-%03d",c++);
/// cw_save_file(fn,(char*)rawmsg,len);
/// cw_dbg(DBG_X,"saving %d bytes",len);
int offs = cw_get_hdr_msg_offset(rawmsg);
int rc;
uint8_t * dot11frame = rawmsg + offs;
int dot11len = len-offs;
// cw_dbg(DBG_X,"802.11 - %s",dot11_get_frame_name(dot11frame));
// extern void ppacket(uint8_t * p, int len);
// ppacket (dot11frame,len-cw_get_hdr_msg_offset(rawmsg));
// cw_dbg(DBG_X,"802.11 - %s",dot11_get_frame_name(dot11frame));
// cw_dbg(DBG_X,"802.11 - T&S: %d %d",dot11_get_type(dot11frame),dot11_get_subtype(dot11frame));
// cw_dbg(DBG_X,"Frame CTL:%d,%d",frame.frame_control.type, frame.frame_control.subtype);
// cw_dbg(DBG_X,"CMP???CTL:%d,%d (%d,%d)",frame.frame_control.type, frame.frame_control.subtype,
// TYPE_MANAGEMENT,SUBTYPE_ASSOC_REQ);
// char ffr[1024];
// cw_format_dot11_hdr(ffr,dot11frame,dot11len);
// cw_dbg(DBG_X,ffr);
//
//
/* The very first data message MUST be a keep-alive message */
if (!cw_get_hdr_flag_k(rawmsg)){
// cw_dbg(DBG_X,"No K Flag founde");
errno = EAGAIN;
return -1;
}
// cw_dbg(DBG_X, "Goto Keep Alive Pack");
return dataman_process_keep_alive(nc,rawmsg,len);
}
int dataman_process_message(struct netconn *nc, uint8_t * rawmsg, int len,
int dataman_process_message(struct cw_Conn *nc, uint8_t * rawmsg, int len,
struct sockaddr *from)
{
if (cw_get_hdr_flag_k(rawmsg)){
return dataman_process_keep_alive(nc,rawmsg,len);
}
static int c=0;
char fn[100];
sprintf(fn,"wificap-%03d",c++);
cw_save_file(fn,(char*)rawmsg,len);
extern void ppacket(uint8_t * p, int len);
// ppacket (rawmsg,len);
cw_dbg(DBG_X,"There was someting else than dataman");
return 1;
}
@ -195,12 +258,22 @@ void dataman_run(struct dataman *dm)
{
time_t timer = cw_timer_start(2);
dm->nc->process_packet=netconn_process_packet;
dm->nc->process_packet=conn_process_packet;
dm->nc->process_message=dataman_process_message0;
dm->nc->data = dm;
while (1){
time_t timer = cw_timer_start(2);
while (!cw_timer_timeout(timer)){
cw_read_messages(dm->nc);
}
}
while (!cw_timer_timeout(timer)){
netconn_read_messages(dm->nc);
cw_read_messages(dm->nc);
}
if (!dm->wtpman){
@ -215,7 +288,7 @@ void dataman_run(struct dataman *dm)
while (1){
time_t timer = cw_timer_start(2);
while (!cw_timer_timeout(timer)){
netconn_read_messages(dm->nc);
cw_read_messages(dm->nc);
}
}

View File

@ -3,12 +3,11 @@
#include <pthread.h>
/*#include "cw/netconn.h"*/
#include "wtpman.h"
struct dataman {
struct netconn *nc;
struct cw_Conn *nc;
pthread_t thread;
struct wtpman * wtpman;
@ -28,6 +27,6 @@ extern pthread_mutex_t dataman_list_mutex;
#define dataman_list_lock() pthread_mutex_lock(&dataman_list_mutex)
#define dataman_list_unlock() pthread_mutex_unlock(&dataman_list_mutex)
#define dataman_add_packet(dm,data,len) (netconn_q_add_packet(dm->nc,data,len))
#define dataman_add_packet(dm,data,len) (conn_q_add_packet(dm->nc,data,len))
#endif

View File

@ -1,487 +0,0 @@
#include <sqlite3.h>
#include "cw/log.h"
#include "cw/dbg.h"
#include "cw/conn.h"
#include "conf.h"
static sqlite3 *handle;
static const char * init_tables = "\
CREATE TABLE IF NOT EXISTS acs (acid TEXT PRIMARY KEY, acname TEXT, lastseen TIMESTAMP); \
CREATE TABLE IF NOT EXISTS radios (\
wtpid TEXT,\
rid TEXT,\
key TEXT,\
sub_key,\
val TEXT, \
upd INTEGER, \
PRIMARY KEY (wtpid,rid,key,sub_key)\
);\
CREATE TABLE IF NOT EXISTS acips (acid TEXT,ip TEXT); \
CREATE TABLE IF NOT EXISTS wtps (wtpid TEXT PRIMARY KEY, acid TEXT,lastseen TIMESTAMP); \
CREATE TABLE IF NOT EXISTS wtpprops (\
wtpid TEXT NOT NULL,\
id TEXT NOT NULL,\
sub_id TEXT NOT NULL,\
val TEXT,\
upd INTEGER,\
PRIMARY KEY(wtpid,id,sub_id)\
);\
CREATE TABLE IF NOT EXISTS wlans (wlanid INTEGER PRIMARY KEY);\
CREATE TABLE IF NOT EXISTS wlanprops (wlanid INTEGER, id TEXT NOT NULL, val TEXT, PRIMARY KEY(wlanid,id));\
";
int db_init()
{
int rc;
const char * filename="ac.sqlite3";
cw_dbg(DBG_INFO,"Initializing Sqlite3 DB: %s, SQLite3 Version %s",filename,SQLITE_VERSION);
rc = sqlite3_config(SQLITE_CONFIG_SERIALIZED);
if (rc!=SQLITE_OK){
cw_log(LOG_ERR,"Error configuring SQLite3: %s",sqlite3_errmsg(handle));
return 0;
}
rc = sqlite3_initialize();
if (rc!=SQLITE_OK){
cw_log(LOG_ERR,"Error initializing SQLite3 DB : %s",sqlite3_errmsg(handle));
return 0;
}
rc = sqlite3_open(filename,&handle);
if (rc != SQLITE_OK)
{
cw_log(LOG_ERR,"Error opening SQLite3 DB %s: %s",filename,sqlite3_errmsg(handle));
return 0;
}
const char * cmd = init_tables;
rc = sqlite3_exec(handle,cmd,0,0,0);
if (rc)
{
const char *em = sqlite3_errmsg(handle);
cw_log(LOG_ERR,"Error executing SQL \"%s\"\nSQL Error Message: %s",cmd, em);
return 0;
}
return 1;
}
static sqlite3_stmt * ping_stmt;
static sqlite3_stmt * put_wtp_prop_stmt;
static sqlite3_stmt * get_tasks_stmt;
static sqlite3_stmt * stmt_get_radio_tasks;
static sqlite3_stmt * stmt_ping_wtp;
static sqlite3_stmt * stmt_put_radio_prop;
int db_start()
{
cw_dbg(DBG_INFO,"Starting Sqlite3 DB");
const char *sql="";
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2(handle, "INSERT OR REPLACE INTO acs (acid,acname) VALUES (?,?);",-1,&stmt,0);
if (rc)
goto errX;
rc = sqlite3_bind_text(stmt,1,conf_acid,-1,SQLITE_STATIC);
rc = sqlite3_bind_text(stmt,2,conf_acname,-1,SQLITE_STATIC);
sqlite3_step(stmt);
rc = sqlite3_prepare_v2(handle, "UPDATE acs SET lastseen=datetime('now') WHERE acid=?;",-1,&ping_stmt,0);
rc = sqlite3_bind_text(ping_stmt,1,conf_acid,-1,SQLITE_STATIC);
/* Prepare statement to update a WTP property */
sql = "INSERT OR REPLACE INTO wtpprops\
(wtpid,id,sub_id,val,upd)\
VALUES (?,?,?,?,?)";
rc = sqlite3_prepare_v2(handle, sql,-1, &put_wtp_prop_stmt,0);
if (rc)
goto errX;
sql = "INSERT OR REPLACE INTO radios\
(wtpid,rid,key,sub_key,val,upd)\
VALUES (?,?,?,?,?,0)";
rc = sqlite3_prepare_v2(handle, sql,-1, &stmt_put_radio_prop,0);
if (rc)
goto errX;
/* Prepare WTP ping statement */
sql = "INSERT OR REPLACE INTO wtps (wtpid,acid,lastseen) VALUES(?,?,datetime('now'))";
rc = sqlite3_prepare_v2(handle, sql,-1, &stmt_ping_wtp,0);
if (rc)
goto errX;
sql = "SELECT wtpid,id,sub_id,val FROM wtpprops WHERE upd>0 AND wtpid=?";
rc = sqlite3_prepare_v2(handle, sql,-1, &get_tasks_stmt,0);
if (rc)
goto errX;
sql = "SELECT wtpid,rid,key,sub_key,val FROM radios WHERE upd>0 AND wtpid=?";
rc = sqlite3_prepare_v2(handle, sql,-1, &stmt_get_radio_tasks,0);
if (rc)
goto errX;
return 1;
errX:
cw_log(LOG_ERR,"Fatal: Can't start Sqlite3 DB, Error while executing '%s' - %d - %s",sql,rc,sqlite3_errmsg(handle));
return 0;
}
void db_put_radio_prop(const char *wtp_id,const char *rid, const char * key,const char *sub_key,const char * val)
{
int rc=0;
/*// DBGX("Putting %s/%s:%s",id,sub_id,val);
// (wtpid,rid,key,sub_key,val,upd)
*/
sqlite3_reset(stmt_put_radio_prop);
sqlite3_clear_bindings(stmt_put_radio_prop);
if(sqlite3_bind_text(stmt_put_radio_prop,1,wtp_id,-1,SQLITE_STATIC))
goto errX;
if(sqlite3_bind_text(stmt_put_radio_prop,2,rid,-1,SQLITE_STATIC))
goto errX;
if (sqlite3_bind_text(stmt_put_radio_prop,3,key,-1,SQLITE_STATIC))
goto errX;
/* if (!sub_key)
sub_key=CW_ITEM_NONE;
*/
if (sqlite3_bind_text(stmt_put_radio_prop,4,sub_key,-1,SQLITE_STATIC))
goto errX;
if (sqlite3_bind_text(stmt_put_radio_prop,5,val,-1,SQLITE_STATIC))
goto errX;
/*
// if (sqlite3_bind_int(put_wtp_prop_stmt,5,0))
// goto errX;
// cw_dbg(DBG_X,"Her I am already, next is step");
*/
rc = sqlite3_step(stmt_put_radio_prop);
if (rc != SQLITE_DONE)
goto errX;
/*
// cw_dbg(DBG_X,"SQL schould be fine");
*/
return;
errX:
/*// cw_dbg (DBG_X, "Iam on err %d\n",rc);*/
if (rc) {
cw_log(LOG_ERR,"Can't update database with WTP props: %d - %s",
rc,sqlite3_errmsg(handle));
}
}
void db_ping()
{
int rc = sqlite3_step(ping_stmt);
if (rc!=SQLITE_DONE){
cw_log(LOG_ERR,"Error: Can't ping database, error code %d - %s",rc,sqlite3_errmsg(handle));
}
}
void db_ping_wtp(const char *wtpid,const char *acid)
{
int rc=0;
sqlite3_reset(stmt_ping_wtp);
sqlite3_clear_bindings(stmt_ping_wtp);
if(sqlite3_bind_text(stmt_ping_wtp,1,wtpid,-1,SQLITE_STATIC))
goto errX;
if(sqlite3_bind_text(stmt_ping_wtp,2,acid,-1,SQLITE_STATIC))
goto errX;
rc = sqlite3_step(stmt_ping_wtp);
errX:
if (rc!=SQLITE_DONE) {
cw_log(LOG_ERR,"Can't ping database for WTP: %d - %s",
rc,sqlite3_errmsg(handle));
}
}
void db_put_wtp_prop(const char *wtp_id,const char * id,const char *sub_id,const char * val)
{
int rc=0;
/*// DBGX("Putting %s/%s:%s",id,sub_id,val);
*/
sqlite3_reset(put_wtp_prop_stmt);
sqlite3_clear_bindings(put_wtp_prop_stmt);
if(sqlite3_bind_text(put_wtp_prop_stmt,1,wtp_id,-1,SQLITE_STATIC))
goto errX;
if(sqlite3_bind_text(put_wtp_prop_stmt,2,id,-1,SQLITE_STATIC))
goto errX;
/* if (!sub_id)
sub_id=CW_ITEM_NONE;
*/
if (sqlite3_bind_text(put_wtp_prop_stmt,3,sub_id,-1,SQLITE_STATIC))
goto errX;
if (sqlite3_bind_text(put_wtp_prop_stmt,4,val,-1,SQLITE_STATIC))
goto errX;
if (sqlite3_bind_int(put_wtp_prop_stmt,5,0))
goto errX;
/*// cw_dbg(DBG_X,"Her I am already, next is step");
*/
rc = sqlite3_step(put_wtp_prop_stmt);
if (rc != SQLITE_DONE)
goto errX;
/*
// cw_dbg(DBG_X,"SQL schould be fine");
*/
return;
errX:
/*// cw_dbg (DBG_X, "Iam on err %d\n",rc);*/
if (rc) {
cw_log(LOG_ERR,"Can't update database with WTP props: %d - %s",
rc,sqlite3_errmsg(handle));
}
}
/*// TODO XXXX*/
mavl_t db_get_update_tasks(struct conn * conn,const char * wtpid)
{
/*
sqlite3_reset(get_tasks_stmt);
sqlite3_clear_bindings(get_tasks_stmt);
mavl_conststr_t r = mavl_create_conststr();
if (!r)
return NULL;
int rc=0;
if(sqlite3_bind_text(get_tasks_stmt,1,wtpid,-1,SQLITE_STATIC))
goto errX;
while (SQLITE_ROW == sqlite3_step(get_tasks_stmt)) {
int ii;
//DBGX("-----------------------------------------------------","");
for (ii=0; ii<5; ii++){
//DBGX("CVALL: %s",(const char*)sqlite3_column_text(get_tasks_stmt,ii));
}
const char *id = (const char*)sqlite3_column_text(get_tasks_stmt,1);
if (!id) {
continue;
}
const char *sub_id = (const char*)sqlite3_column_text(get_tasks_stmt,2);
const char *val = (const char*)sqlite3_column_text(get_tasks_stmt,3);
//DBGX("ID: (%s), SubID (%s), Val (%s)",id,sub_id,val);
const struct cw_itemdef * cwi = cw_itemdef_get(conn->actions->items,id,sub_id);
if (!cwi) {
//DBGX("Not item definition found for: %s/%s",id,sub_id);
continue;
}
//uint8_t data[2048];
if (!cwi->type->from_str) {
cw_log(LOG_ERR,"Can't convert from string %s/%s - No method defined.",id,sub_id);
continue;
}
mbag_item_t * i = cwi->type->from_str(val);
i->id=cwi->id;
mbag_set(conn->outgoing,i);
mavl_add(r,(void*)cwi->id);
}
if (r->count)
return r;
mavl_destroy(r);
return NULL;
errX:
if (rc) {
cw_log(LOG_ERR,"Can't get tasks: %d - %s",
rc,sqlite3_errmsg(handle));
}
if (r)
mavl_destroy(r);
return NULL;
*/
}
mavl_t db_get_radio_tasks(struct conn * conn,const char * wtpid)
{
/*
//cw_dbg(DBG_X,"Get Radio Tasks for %s",wtpid);
sqlite3_reset(stmt_get_radio_tasks);
sqlite3_clear_bindings(stmt_get_radio_tasks);
mavl_conststr_t r = mavl_create_conststr();
if (!r)
return NULL;
int rc=0;
if(sqlite3_bind_text(stmt_get_radio_tasks,1,wtpid,-1,SQLITE_STATIC))
goto errX;
while (SQLITE_ROW == sqlite3_step(stmt_get_radio_tasks)) {
int ii;
//DBGX("-----------------------------------------------------","");
for (ii=0; ii<6; ii++){
DBGX("CVALL: %s",(const char*)sqlite3_column_text(stmt_get_radio_tasks,ii));
}
const char *strrid= (const char*)sqlite3_column_text(stmt_get_radio_tasks,1);
const char *id = (const char*)sqlite3_column_text(stmt_get_radio_tasks,2);
if (!id) {
continue;
}
const char *sub_id = (const char*)sqlite3_column_text(stmt_get_radio_tasks,3);
const char *val = (const char*)sqlite3_column_text(stmt_get_radio_tasks,4);
//DBGX("ID: (%s), SubID (%s), Val (%s)",id,sub_id,val);
const struct cw_itemdef * cwi = cw_itemdef_get(conn->actions->radioitems,id,sub_id);
if (!cwi) {
DBGX("No item definition found for: %s/%s",id,sub_id);
continue;
}
if (!cwi->type->from_str) {
cw_log(LOG_ERR,"Can't convert from string %s/%s - No method defined.",id,sub_id);
continue;
}
mbag_item_t * i = cwi->type->from_str(val);
i->id=cwi->id;
int rid = atoi(strrid);
cw_dbg(DBG_X,"RID: %d",rid);
mbag_t radio = mbag_i_get_mbag_c(conn->radios_upd,rid,mbag_create);
mbag_set(radio,i);
//mbag_set(conn->outgoing,i);
mavl_add(r,(void*)cwi->id);
}
if (r->count)
return r;
mavl_destroy(r);
return NULL;
errX:
if (rc) {
cw_log(LOG_ERR,"Can't get tasks: %d - %s",
rc,sqlite3_errmsg(handle));
}
if (r)
mavl_destroy(r);
return NULL;
*/
}

View File

@ -1,21 +0,0 @@
#ifndef CW_MAVL_H
#define CW_MAVL_H
#include "mavl.h"
extern void db_ping();
extern void db_ping_wtp(const char *wtpid,const char *acid);
extern int db_init();
int db_start();
int db_get_tasks(struct conn * conn,const char * wtpid);
void db_put_wtp_prop(const char *wtp_id,const char * id,const char *sub_id,const char * val);
mavl_t db_get_update_tasks(struct conn * conn,const char * wtpid);
void db_put_radio_prop(const char *wtp_id,const char *rid, const char * key,const char *sub_key,const char * val);
extern mavl_t db_get_radio_tasks(struct conn * conn,const char * wtpid);
#endif

View File

@ -1,29 +0,0 @@
#include "module.h"
static int init()
{
// regn = cw_register_actions_cipwap_ac(&capwap_actions);
return 1;
}
static struct ac_module module = {
.name="Cipwap",
.init= init,
.detect_by_discovery = 0
};
struct ac_module * mod_cipwap()
{
return &module;
}

View File

@ -1,13 +0,0 @@
#ifndef __MODULE_H
#define __MODULE_H
struct ac_module
{
const char *name;
int (*init)();
int (*detect_by_raw)(const char *msg, int len);
int (*detect_by_discovery)(const char*);
};
#endif

View File

@ -0,0 +1,5 @@
radio.255/capwap/operational-state/state: enabled
radio.255/capwap/admin-state: 1
radio.0/capwap/operational-state/state: enabled
radio.0/capwap/admin-state: 1

View File

@ -0,0 +1,5 @@
#
# Managed by acTube
#
radio.0/capwap/admin-state: 1

60
src/ac/rpc-macros/all.ckv Normal file
View File

@ -0,0 +1,60 @@
radio.0/cisco/air-space-capability: 0
radio.0/cisco/antenna-payload/802-11n-rx-antennas: 3
radio.0/cisco/antenna-payload/802-11n-tx-antennas: 7
radio.0/cisco/antenna-payload/antenna-cnt: 2
radio.0/cisco/antenna-payload/antenna-mode: 3
radio.0/cisco/antenna-payload/antenna.0: 1 - Internal Antenna
radio.0/cisco/antenna-payload/antenna.1: 1 - Internal Antenna
radio.0/cisco/antenna-payload/diversity-selection: 255
radio.0/cisco/antenna-payload/unknown: 0
radio.0/cisco/channel-power: .x08080d0108221c16100a04fefe0208221c16100a04fefe0308221c16100a04fefe0408221c16100a04fefe0508221c16100a04fefe0608221c16100a04fefe0708221c16100a04fefe0808221c16100a04fefe0908221c16100a04fefe0a08221c16100a04fefe0b08221c16100a04fefe0c08221c16100a04fefe0d08221c16100a04fefe
radio.0/capwap80211/rate-set: .x82848b960c1218243048606c
radio.0/capwap80211/tx-power/@cisco/cfg-type: 1 - global
radio.0/capwap80211/tx-power/current-tx-power: 1
radio.0/capwap80211/wtp-radio-config/beacon-period: 100
radio.0/capwap80211/wtp-radio-config/bssid: .x04fe7f499b90
radio.0/capwap80211/wtp-radio-config/cfg-period: 4
radio.0/capwap80211/wtp-radio-config/cfg-type: 1
radio.0/capwap80211/wtp-radio-config/cfp-maximum-duration: 60
radio.0/capwap80211/wtp-radio-config/country-str1: "DE "
radio.0/capwap80211/wtp-radio-config/country-str2: "DE "
radio.0/capwap80211/wtp-radio-config/occupancy-limit: 100
radio.0/capwap80211/wtp-radio-config/reg: 167772416
radio.0/capwap80211/wtp-radio-information: 1
radio.0/cisco/mac-operation/long-retry: 4
radio.0/cisco/mac-operation/reserved: 1
radio.0/cisco/mac-operation/rts-threshold: 2347
radio.0/cisco/mac-operation/rx-msdu-lifetime: 512
radio.0/cisco/mac-operation/short-retry: 7
radio.0/cisco/mac-operation/tx-msdu-lifetime: 512
radio.0/cisco/multi-domain-capability/first-channel: 1
radio.0/cisco/multi-domain-capability/max-tx-power-level: 65535
radio.0/cisco/multi-domain-capability/number-of-channels: 13
radio.0/cisco/multi-domain-capability/reserved: 1
radio.0/cisco/phy-ht-cap/asel-cap: 0
radio.0/cisco/phy-ht-cap/extended-ht-cap-info: .x0000
radio.0/cisco/phy-ht-cap/ht-cap-info: 6
radio.0/cisco/phy-ht-cap/mcsrates-1: .x00000000
radio.0/cisco/phy-ht-cap/mcsrates-2: .x00000000
radio.0/cisco/phy-ht-cap/mcsrates-3: .x00000000
radio.0/cisco/phy-ht-cap/mcsrates-4: .x0000ffff
radio.0/cisco/phy-ht-cap/tx-bf-cap: .x00000000
radio.0/cisco/phy-ht-control/cfg-type: 1 - global
radio.0/cisco/phy-ht-control/channel-width: 20
radio.0/cisco/phy-ht-control/cur-freq-is-dfs-channel: 0
radio.0/cisco/phy-ht-control/current-freq: 1
radio.0/cisco/phy-ht-control/enable-ht: 3
radio.0/cisco/phy-ht-control/ext-channel: 0
radio.0/cisco/phy-ht-control/flash-commit: 0
radio.0/cisco/phy-ht-control/frequency-bands-support: 206
radio.0/cisco/phy-ht-control/rest: .x00ffffff
radio.0/cisco/phy-ht-control/ti-threshold: 0

View File

@ -0,0 +1,10 @@
radio.0/cisco/air-space-capability: 0
radio.0/cisco/antenna-payload/802-11n-rx-antennas: 3
radio.0/cisco/antenna-payload/802-11n-tx-antennas: 7
radio.0/cisco/antenna-payload/antenna-cnt: 2
radio.0/cisco/antenna-payload/antenna-mode: 3
radio.0/cisco/antenna-payload/antenna.0: 1 - Internal Antenna
radio.0/cisco/antenna-payload/antenna.1: 1 - Internal Antenna
radio.0/cisco/antenna-payload/diversity-selection: 255
radio.0/cisco/antenna-payload/unknown: 0

View File

@ -0,0 +1,5 @@
#
# Managed by acTube
#
cisco/ap-led-state-config/led-state: 0

View File

@ -0,0 +1,5 @@
#
# Managed by acTube
#
cisco/ap-led-state-config/led-state: 1

View File

@ -0,0 +1,8 @@
radio.0/cisco/mac-operation/fragmentation-threshold: 2346
radio.0/cisco/mac-operation/long-retry: 4
radio.0/cisco/mac-operation/reserved: 1
radio.0/cisco/mac-operation/rts-threshold: 2347
radio.0/cisco/mac-operation/rx-msdu-lifetime: 512
radio.0/cisco/mac-operation/short-retry: 7
radio.0/cisco/mac-operation/tx-msdu-lifetime: 512

View File

@ -0,0 +1,5 @@
#
# Managed by acTube
#
radio.0/capwap/operational-state/state: disabled

View File

@ -0,0 +1,5 @@
#
# Managed by acTube
#
radio.0/capwap/operational-state/state: enabled

View File

@ -0,0 +1,13 @@
radio.0/capwap80211/tx-power/@cisco/cfg-type: 1 - global
radio.0/capwap80211/tx-power/current-tx-power: 1
radio.0/capwap80211/wtp-radio-config/beacon-period: 100
radio.0/capwap80211/wtp-radio-config/bssid: .x04fe7f499b90
radio.0/capwap80211/wtp-radio-config/cfg-period: 4
radio.0/capwap80211/wtp-radio-config/cfg-type: 1
radio.0/capwap80211/wtp-radio-config/cfp-maximum-duration: 60
radio.0/capwap80211/wtp-radio-config/country-str1: "DE "
radio.0/capwap80211/wtp-radio-config/country-str2: "DE "
radio.0/capwap80211/wtp-radio-config/occupancy-limit: 100
radio.0/capwap80211/wtp-radio-config/reg: 167772416
radio.0/capwap80211/wtp-radio-information: 1

89
src/ac/rpc-macros/sr.ckv Normal file
View File

@ -0,0 +1,89 @@
capwap/timers/echo-interval: 30
capwap/timers/max-discovery-interval: 10
radio.255/capwap/admin-state: 1 - enabled
radio.0/capwap/admin-state: 1 - enabled
radio.1/capwap/admin-state: 1 - enabled
radio.0/capwap/decryption-error-report-period: 120
radio.1/capwap/decryption-error-report-period: 120
capwap/idle-timeout: 300
capwap/wtp-fallback: 1
cisco/spam-domain-secret: .xe1ffd18a8f15b3b59c0a47a7f17a96e7cb36174f00
radio.0/capwap80211/wtp-radio-config/beacon-period: 100
radio.0/capwap80211/wtp-radio-config/bssid: .x003a9902fac0
radio.0/capwap80211/wtp-radio-config/cfg-period: 4
radio.0/capwap80211/wtp-radio-config/cfg-type: 1
radio.0/capwap80211/wtp-radio-config/cfp-maximum-duration: 60
radio.0/capwap80211/wtp-radio-config/country-str1: "DE "
radio.0/capwap80211/wtp-radio-config/country-str2: "DE "
radio.0/capwap80211/wtp-radio-config/occupancy-limit: 100
radio.0/capwap80211/wtp-radio-config/reg: 167772416
radio.0/capwap80211/wtp-radio-information: 1
radio.0/capwap80211/rate-set: .x82848b960c1218243048606c
radio.0/cisco/multi-domain-capability/first-channel: 1
radio.0/cisco/multi-domain-capability/max-tx-power-level: 65535
radio.0/cisco/multi-domain-capability/number-of-channels: 13
radio.0/cisco/multi-domain-capability/reserved: 1
radio.0/cisco/mac-operation/fragmentation-threshold: 2346
radio.0/cisco/mac-operation/long-retry: 4
radio.0/cisco/mac-operation/reserved: 1
radio.0/cisco/mac-operation/rts-threshold: 2347
radio.0/cisco/mac-operation/rx-msdu-lifetime: 512
radio.0/cisco/mac-operation/short-retry: 7
radio.0/cisco/mac-operation/tx-msdu-lifetime: 512
radio.1/capwap80211/tx-power/@cisco/cfg-type: 1 - global
radio.1/capwap80211/tx-power/current-tx-power: 1
radio.0/cisco/direct-sequence-control/cfg-type: 1 - global
radio.0/cisco/direct-sequence-control/current-cca-mode: 0
radio.0/cisco/direct-sequence-control/current-channel: 1
radio.0/cisco/direct-sequence-control/energy-detect-threshold: -50
radio.0/cisco/direct-sequence-control/unknown: 1
radio.0/cisco/antenna-payload/802-11n-rx-antennas: 3
radio.0/cisco/antenna-payload/802-11n-tx-antennas: 7
radio.0/cisco/antenna-payload/antenna-cnt: 2
radio.0/cisco/antenna-payload/antenna-mode: 3
radio.0/cisco/antenna-payload/antenna.0: 1 - Internal Antenna
radio.0/cisco/antenna-payload/antenna.1: 1 - Internal Antenna
radio.0/cisco/antenna-payload/diversity-selection: 255
radio.0/cisco/antenna-payload/unknown: 0
radio.0/cisco/air-space-capability: 0
radio.0/capwap/operational-state/cause: Normal
radio.0/capwap/operational-state/state: enabled
radio.0/cisco/80211h/count: 0
radio.0/cisco/80211h/enable: 0
radio.0/cisco/80211h/mode: 0
radio.0/cisco/80211h/power: 0
radio.0/cisco/elem153: .x00
radio.0/cisco/elem156: .x020100
radio.0/cisco/lwelem48: .x01055a0101a6c405b06432b03232
radio.1/cisco/lwelem33: .x00
radio.0/cisco/elem146: .x690f
radio.255/capwap/operational-state/cause: Normal
radio.255/capwap/operational-state/state: enabled
cisco/bcast-ssid-mode: 1
capwap/timers/max-discovery-interval: 10
capwap/timers/echo-interval: 30
cisco/client-auto-handoff: 0
cisco/lwelem14: .x000001000000000000000000000000000000

View File

@ -0,0 +1,5 @@
#
# Managed by acTube
#
cisco/ap-telnet-ssh/telnet: false

View File

@ -0,0 +1,5 @@
#
# Managed by acTube
#
cisco/ap-telnet-ssh/telnet: true

View File

@ -0,0 +1,3 @@
radio.0/capwap80211/tx-power/@cisco/cfg-type: 1 - global
radio.0/capwap80211/tx-power/current-tx-power: 1

View File

@ -0,0 +1,17 @@
radio.0/wlan.1/capwap80211/capability: 1073
radio.0/wlan.1/capwap80211/qos: 0
radio.0/wlan.1/capwap80211/ssid: tubeC
radio.0/wlan.1/cisco/aironet-ie: true
radio.0/wlan.1/cisco/broadcast-ssid: true
radio.0/wlan.1/cisco/dtim-period: 1
radio.0/wlan.1/cisco/encryption-policy: 4
radio.0/wlan.1/cisco/hreap-local-switch: 0
radio.0/wlan.1/cisco/profile-name: tubeC
radio.0/wlan.1/cisco/scan-defer-period: 28784
radio.0/wlan.1/cisco/scan-defer-time: 100
radio.0/wlan.1/cisco/session-timout: 1800
radio.0/wlan.1/cisco/wep-encryption: false
radio.0/wlan.1/cisco/wep-key: .xc3e9d4b1360d7cf5bcfc759753
radio.0/wlan.1/cisco/wep-key-index: 1
radio.0/wlan.1/radio-id: 0
radio.0/wlan.1/wlan-id: 1

View File

@ -0,0 +1,14 @@
radio.0/wlan.1/capwap80211/capability: 1057
radio.0/wlan.1/capwap80211/ssid: actube
radio.0/wlan.1/cisco/allow-aaa-override: 0
radio.0/wlan.1/cisco/broadcast-ssid: true
radio.0/wlan.1/cisco/dtim-period: 1
radio.0/wlan.1/cisco/encryption-policy: 16777216
radio.0/wlan.1/cisco/max-stations: 200
radio.0/wlan.1/cisco/profile-name: ACTUBE
radio.0/wlan.1/cisco/session-timout: 1800
radio.0/wlan.1/cisco/wep-encryption: 0
radio.0/wlan.1/cisco/wep-key: .x00000000000000000000000000
radio.0/wlan.1/radio-id: 0
radio.0/wlan.1/wlan-id: 1

View File

@ -0,0 +1,18 @@
radio.0/wlan.13/capwap80211/capability: 1057
radio.0/wlan.13/capwap80211/qos: 0
radio.0/wlan.13/capwap80211/ssid: SuperSSID
radio.0/wlan.13/cisco/aironet-ie: true
radio.0/wlan.13/cisco/broadcast-ssid: true
radio.0/wlan.13/cisco/dtim-period: 19
radio.0/wlan.13/cisco/encryption-policy: 1
radio.0/wlan.13/cisco/hreap-local-switch: 16
radio.0/wlan.13/cisco/profile-name: SuerWLAN
radio.0/wlan.13/cisco/scan-defer-period: 15420
radio.0/wlan.13/cisco/scan-defer-time: 100
radio.0/wlan.13/cisco/session-timout: 1800
radio.0/wlan.13/cisco/wep-encryption: false
radio.0/wlan.13/cisco/wep-key: .x55d80f0e2bf5223dd10f82407b
radio.0/wlan.13/cisco/wep-key-index: 1
radio.0/wlan.13/radio-id: 0
radio.0/wlan.13/wlan-id: 13

View File

@ -2,6 +2,7 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
@ -16,6 +17,7 @@
#include "cw/log.h"
#include "cw/dbg.h"
#include "wtpman.h"
#include "cw/connlist.h"
@ -64,6 +66,11 @@ int wlan0_cmd(struct rpcdata *sd, const char * cmd);
int exit_cmd(struct rpcdata *sd, const char * cmd);
int prompt_cmd(struct rpcdata *sd, const char * cmd);
int global_cfg_cmd(struct rpcdata *sd, const char * cmd);
int status_cmd(struct rpcdata *sd, const char * cmd);
void print_mw(FILE *f, int w, const char * str);
int clear_cmd(struct rpcdata *sd, const char *cmd);
int load_cmd(struct rpcdata *sd, const char *cmd);
int save_cmd(struct rpcdata *sd, const char *cmd);
//void show_cfg (FILE *out, mavl_t ktv);
int show_aps (FILE *out);
@ -88,6 +95,11 @@ static struct command cmdlist[]={
{"set", set_cmd },
{"wlan0",wlan0_cmd},
{"global_cfg", global_cfg_cmd},
{"status",status_cmd},
{"clear",clear_cmd},
{"load",load_cmd},
{"save",save_cmd},
{"@prompt",prompt_cmd},
@ -112,9 +124,18 @@ int prompt_cmd(struct rpcdata *sd, const char *cmd)
}
int global_cfg_cmd(struct rpcdata *sd, const char *cmd)
int global_cfg_cmd(struct rpcdata *sd, const char *str)
{
cw_cfg_fdump(sd->out,sd->global_cfg);
char *s;
while( isspace( *str ) )
str++;
s=(char*)str;
while (!isspace(*s) && *s!=0)
s++;
*s=0;
cw_cfg_fdump(sd->out,sd->global_cfg,str);
finish_cmd(sd->out);
return 0;
}
@ -138,10 +159,6 @@ int list_cmd(struct rpcdata *sd, const char *cmd)
int exit_cmd(struct rpcdata *sd, const char *cmd)
{
//fprintf(sd->out,"Unknown command: '%s'\n\r\n\r",cmd);
// printf("Exitcmd %s\n",cmd);
//fprintf(sd->out,"END: %s\n\r",cmd);
finish_cmd(sd->out);
fflush(sd->out);
return 1;
@ -149,8 +166,18 @@ int exit_cmd(struct rpcdata *sd, const char *cmd)
int cfg_cmd(struct rpcdata *sd, const char *cmd)
int cfg_cmd(struct rpcdata *sd, const char *str)
{
char *s;
while( isspace( *str ) )
str++;
s=(char*)str;
while (!isspace(*s) && *s!=0)
s++;
*s=0;
struct cw_Conn * conn;
wtplist_lock();
conn = find_ap(sd->prompt);
@ -158,37 +185,111 @@ int cfg_cmd(struct rpcdata *sd, const char *cmd)
fprintf(sd->out,"WTP '%s' not found\n",sd->prompt);
}
else {
cw_cfg_fdump(sd->out,conn->remote_cfg);
cw_cfg_fdump(sd->out,conn->remote_cfg,str);
}
finish_cmd(sd->out);
wtplist_unlock();
return 0;
}
int ucfg_cmd(struct rpcdata *sd, const char *cmd)
int status_cmd(struct rpcdata *sd, const char *cmd)
{
// struct cw_Conn * conn;
stop();
// show_cfg(sd->out,sd->update_cfg);
struct cw_Conn * conn;
int i;
char key[CW_CFG_MAX_KEY_LEN];
wtplist_lock();
print_mw(sd->out,8,"Radio");
print_mw(sd->out,15,"Admin State");
print_mw(sd->out,15,"Oper State");
print_mw(sd->out,13,"Cause");
fprintf(sd->out,"\n");
conn = find_ap(sd->prompt);
if (conn==NULL){
fprintf(sd->out,"WTP '%s' not found\n",sd->prompt);
goto errX;
}
i=0;
do {
char tmp[128];
sprintf(key,"radio.%d",i);
if (!cw_cfg_base_exists(conn->remote_cfg,key))
break;
sprintf(tmp,"%d",i);
print_mw(sd->out,8,tmp);
sprintf(key,"radio.%d/capwap/admin-state",i);
print_mw(sd->out,15, cw_cfg_get(conn->remote_cfg,key,"?"));
sprintf(key,"radio.%d/capwap/operational-state/state",i);
print_mw(sd->out,15, cw_cfg_get(conn->remote_cfg,key,"?"));
sprintf(key,"radio.%d/capwap/operational-state/cause",i);
print_mw(sd->out,13, cw_cfg_get(conn->remote_cfg,key,"?"));
fprintf(sd->out,"\n");
i++;
}while(1);
errX:
finish_cmd(sd->out);
wtplist_unlock();
return 0;
}
int ucfg_cmd(struct rpcdata *sd, const char *str)
{
char *s;
while( isspace( *str ) )
str++;
s=(char*)str;
while (!isspace(*s) && *s!=0)
s++;
*s=0;
cw_cfg_fdump(sd->out,sd->update_cfg,str);
finish_cmd(sd->out);
return 0;
}
int clear_cmd(struct rpcdata *sd, const char *cmd)
{
cw_cfg_clear(sd->update_cfg);
fprintf(sd->out,"ucfg cleard\n");
finish_cmd(sd->out);
return 0;
}
#include "wtpman.h"
int
send_cmd(struct rpcdata * sd, const char *cmd)
{
struct wtpman * wtpman;
struct cw_Conn * conn;
wtplist_lock();
conn = find_ap(sd->prompt);
if (conn==NULL){
fprintf(sd->out,"WTP '%s' not found\n",sd->prompt);
goto errX;
}
else {
conn->update_cfg=sd->update_cfg;
wtpman=conn->data;
cw_cfg_copy(sd->update_cfg,conn->update_cfg,0,NULL);
wtpman->update=1;
fprintf(sd->out, "Sending update cmd\n");
}
errX:
wtplist_unlock();
finish_cmd(sd->out);
return 0;
}
@ -205,8 +306,6 @@ wlan0_cmd(struct rpcdata * sd, const char *cmd)
}
else {
FILE *f=fopen("wlan0.ktv","r");
// cw_ktv_read_file(f,sd->update_cfg,conn->msgset->types_tree);
//conn->update_cfg=sd->update_cfg;
fclose(f);
}
wtplist_unlock();
@ -217,62 +316,78 @@ int set_cmd(struct rpcdata *sd, const char *str)
{
cw_Cfg_t *cfg;
cfg = cw_cfg_create();
cw_cfg_read_from_string(str,cfg);
cw_cfg_fdump(sd->out,cfg);
cw_cfg_fdump(sd->out,cfg,NULL);
cw_cfg_copy(cfg,sd->update_cfg,DBG_CFG_UPDATES,"rpc ucfg");
cw_cfg_destroy(cfg);
finish_cmd(sd->out);
// cw_ktv_init_str_reader(&r,str,strlen(str));
// cw_ktv_parse_string(&r,key,type,val);
/*cw_ktv_parse_string(key,type,val, 2048);*/
// fprintf(sd->out,"%s %s\n",key,val);
// cw_ktv_add(sd->update_cfg,key,CW_TYPE_STR,NULL,val,strlen(val));
return 0;
}
int load_cmd(struct rpcdata *sd, const char *str)
{
char fn[CW_CFG_MAX_KEY_LEN];
int rc;
const char * dir=cw_cfg_get(sd->global_cfg,"actube/rpc/macros-dir","./rpc-macros");
sprintf(fn,"%s/%s.ckv",dir,str);
rc= cw_cfg_load(fn,sd->update_cfg);
if (rc){
fprintf(sd->out,"Error loading %s: %s\n",fn,strerror(rc));
}
finish_cmd(sd->out);
return 0;
}
int save_cmd(struct rpcdata *sd, const char *str)
{
char fn[CW_CFG_MAX_KEY_LEN];
int rc;
const char * dir=cw_cfg_get(sd->global_cfg,"actube/rpc/macros-dir","./rpc-macros");
sprintf(fn,"%s/%s.ckv",dir,str);
rc= cw_cfg_save(fn,sd->update_cfg,"#\n# Managed by acTube\n#\n\n");
if (rc){
fprintf(sd->out,"Error saving %s: %s\n",fn,strerror(rc));
}
finish_cmd(sd->out);
return 0;
}
int del_cmd(struct rpcdata *sd, const char *str)
{
char key[CW_CFG_MAX_KEY_LEN];
sscanf(str,"%s",key);
stop();
// cw_ktv_del_sub(sd->update_cfg,key);
//
char *s;
while( isspace( *str ) )
str++;
s=(char*)str;
while (!isspace(*s) && *s!=0)
s++;
*s=0;
fprintf(sd->out,"DEL: '%s'\n",str);
cw_cfg_del(sd->update_cfg,str);
finish_cmd(sd->out);
return 0;
}
/*
void show_cfg (FILE *out, mavl_t ktv)
{
char value[500];
struct cw_Val * data;
mavliter_t it;
const struct cw_Type * type;
mavliter_init(&it,ktv);
mavliter_foreach(&it){
data = mavliter_get(&it);
type = data->type;
type->to_str(data,value,0);
fprintf(out,"%s :%s: %s\n",data->key,type->get_type_name(data), value);
}
}
*/
void print_mw(FILE *f, int w, const char * str)
{
int n,i;
@ -358,62 +473,6 @@ struct cw_Conn * find_ap(const char *name)
}
void con (FILE *out)
{
stop();
/*
struct connlist * cl;
mavliter_t it;
wtplist_lock();
cl = wtplist_get_connlist();
mavliter_init (&it, cl->by_addr);
fprintf (out, "IP\t\t\twtp-name\n");
mavliter_foreach (&it) {
cw_Val_t * result;
char addr[SOCK_ADDR_BUFSIZE];
char wtp_name[CAPWAP_MAX_WTP_NAME_LEN];
struct cw_Conn * conn;
conn = mavliter_get_ptr (&it);
sock_addr2str_p (&conn->addr, addr);
result = cw_ktv_get (conn->remote_cfg, "wtp-name", NULL);
if (result == NULL) {
strcpy (wtp_name, "");
} else {
result->type->to_str (result, wtp_name, CAPWAP_MAX_WTP_NAME_LEN);
}
fprintf (out, "Con!! %s\t\t%s\n", addr, wtp_name);
{
stop();
mavl_t update;
// update = cw_ktv_create();
// cw_ktv_set_byte(update,"radio.255/admin-state",1);
// conn->update_cfg=update;
}
fprintf(out,"\n");
}
wtplist_unlock();
*/
}
struct command * find_cmd(const char *cmd)
{
struct command * search,*result;
@ -438,7 +497,6 @@ int execute_cmd (struct rpcdata * sd, const char *str)
char cmd[1024];
char args[1024];
int n;
struct cw_Val_Reader reader;
struct command * searchcmd;
args[0]=0;
@ -450,7 +508,19 @@ int execute_cmd (struct rpcdata * sd, const char *str)
searchcmd = find_cmd(cmd);
if (searchcmd!=NULL){
if (searchcmd->fun != NULL){
return searchcmd->fun(sd, str+strlen(cmd));
char *args;
int n;
args = (char*)(str+strlen(cmd));
while( isspace( *args ) )
args++;
n = strlen(args);
n--;
while (n>=0 && isspace(args[n]))
n--;
args[n+1]=0;
return searchcmd->fun(sd, args);
}
}
else{
@ -460,73 +530,8 @@ int execute_cmd (struct rpcdata * sd, const char *str)
return 0;
char key[CW_CFG_MAX_KEY_LEN];
char type[128];
char val[2048];
key[0]=0;
type[0]=0;
val[0]=0;
stop();
// cw_ktv_init_str_reader(&reader,str, strlen(str));
// n = cw_ktv_parse_string(&reader, key,type,val);
if (n==-1){
int i;
fprintf(sd->out,"Error on pos %d\n",reader.pos);
fprintf(sd->out,"%s",str);
for(i=0;i<reader.pos;i++){
fprintf(sd->out," ");
}
fprintf(sd->out,"^\n");
fprintf(sd->out,"%s\n",reader.error);
}
else{
fprintf(sd->out,"%s :%s: %s\n", key,type,val);
}
return 0;
n = sscanf (str, "%s%s", cmd, args);
if (n<=0)
return 0;
/*printf("CMD: %s, ARGS:\n",cmd);*/
if (strcmp (cmd, "s") == 0) {
show_aps (sd->out);
return 0;
}
if (strcmp (cmd, "con")==0){
con(sd->out);
return 0;
}
return 0;
}
struct esc_strings {
char *str;
char * result;
};
struct esc_strings estr[] = {
{"\x1b[H", "home"},
{"\x1b[F", "end"},
{"\x1b[A", "up"},
{"\x1b[B", "donw"},
{"\x1b[D", "left"},
{"\x1b[C", "right"},
{NULL,NULL}
};
void rpc_loop (FILE *file, cw_Cfg_t *global_cfg)
@ -540,6 +545,7 @@ void rpc_loop (FILE *file, cw_Cfg_t *global_cfg)
sd.in = file;
sd.out = file;
sd.global_cfg=global_cfg;
sd.update_cfg=cw_cfg_create();
sprintf(sd.prompt,"%s","*");
@ -591,9 +597,6 @@ void * run_rpc_server (void * arg)
close (clientsock);
}
//cw_dbg (DBG_INFO,"Accepting shell session %i, %s", rc, strerror (errno));
}
return NULL;
@ -633,8 +636,6 @@ int create_tcp_fd(const char *name)
}
static int create_unix_fd(const char *name)
{
//struct sockaddr_storage client;
//socklen_t client_size;
struct sockaddr_un addr;
int rc,fd;
@ -648,7 +649,6 @@ static int create_unix_fd(const char *name)
cw_log (LOG_ERR, "Can't bind socket 'unix:%s', %s", name, strerror (errno));
return -1;
}
//int clientsock = accept (fd, (struct sockaddr*) &client, &client_size);
return fd;
}
@ -657,7 +657,7 @@ int start_rpc(cw_Cfg_t *global_cfg)
{
struct sockdata * sockdata;
const char *sockname;
int rc; //, type;
int rc;
int fd;
rc = cw_cfg_get_bool(global_cfg,"actube/rpc/enable",1);

View File

@ -44,6 +44,8 @@
#include "actube.h"
#include "cw/dot11.h"
static void wtpman_remove(struct wtpman *wtpman)
{
@ -298,6 +300,91 @@ int cw_run_state_machine(struct cw_Conn *conn, time_t * timer)
/*#define CW_TRANSITION(prestate,state) (prestate<<16|state)*/
int run_update(struct wtpman *wtpman)
{
int rc;
if (!wtpman->update)
return EAGAIN;
rc = cw_send_request(wtpman->conn, CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST);
cw_cfg_clear(wtpman->conn->update_cfg);
wtpman->update=0;
return rc;
}
static int dataman_process_msg(struct cw_Conn *nc, uint8_t * rawmsg, int len,
struct sockaddr *from)
{
char rframe[1000];
int offs = cw_get_hdr_msg_offset(rawmsg);
uint8_t * frame = rawmsg + offs;
int frame_len = len-offs;
cw_dbg_dot11_frame(frame,frame_len);
/* dot11_init_assoc_resp(frame);
dot11_copy_mac(dot11_get_sa(dot11frame),dot11_get_da(frame));
dot11_copy_mac(dot11_get_bssid(dot11frame),dot11_get_bssid(frame));
dot11_copy_mac(dot11_get_da(dot11frame),dot11_get_sa(frame));
dot11_set_seq(frame,0);
*/
if ( dot11_get_type_and_subtype(frame) == DOT11_ASSOC_REQ){
int l;
uint8_t rates[] = {
12,0x82,0x84,0x8b,0x96,0x0c,0x12,0x18,0x24,0x30,0x48,0x60,0x6c
};
cw_dbg(DBG_X, "there is an assoc request!");
uint8_t rframe[1000];
nc->mtu=800;
dot11_init_assoc_resp(rframe);
dot11_set_duration(rframe,100);
dot11_copy_mac(dot11_get_sa(frame),dot11_get_da(rframe));
dot11_copy_mac(dot11_get_bssid(frame),dot11_get_bssid(rframe));
dot11_copy_mac(dot11_get_da(frame),dot11_get_sa(rframe));
dot11_set_seq(rframe,dot11_get_seq(frame));
dot11_assoc_resp_set_cap(rframe,dot11_assoc_req_get_cap(frame));
dot11_assoc_resp_set_status_code(rframe,0);
dot11_assoc_resp_set_assoc_id(rframe,17);
l=24+6;
l+=dot11_put_supported_rates(rframe+l,rates);
cw_dbg_dot11_frame(rframe,l);
uint8_t buf[1024];
int hlen;
hlen = cw_init_capwap_packet(buf,1,0,NULL,NULL);
cw_set_hdr_flags(buf, CAPWAP_FLAG_HDR_T, 1);
cw_send_capwap_packet(nc,buf,hlen,rframe,l);
}
return 0;
}
static void *wtpman_data_main(void *arg)
{
struct wtpman * wtpman = arg;
struct cw_Conn * nc = wtpman->dconn;
nc->process_packet=conn_process_packet;
nc->process_message=dataman_process_msg;
while (1){
time_t timer = cw_timer_start(2);
while (!cw_timer_timeout(timer)){
cw_read_messages(nc);
}
}
}
static void *wtpman_main(void *arg)
{
//mavl_t r;
@ -343,6 +430,7 @@ static void *wtpman_main(void *arg)
conn->capwap_prevstate = CAPWAP_STATE_DTLS_SETUP;
conn->capwap_state = CAPWAP_STATE_JOIN;
rc = 0;
wtpman->update=0;
while (1) {
@ -359,59 +447,25 @@ static void *wtpman_main(void *arg)
while (!cw_timer_timeout(timer)) {
rc = run_update(wtpman);
if (rc !=EAGAIN)
break;
rc = cw_read_messages(wtpman->conn);
if (rc < 0) {
if (errno == EAGAIN)
if (errno == EAGAIN){
continue;
}
}
break;
}
if (rc < 0) {
conn->capwap_prevstate = conn->capwap_state;
conn->capwap_state = CAPWAP_STATE_TIMEOUT;
}
}
/* dtls is established, goto join state */
/*
conn->capwap_state = CAPWAP_STATE_JOIN;
if (!wtpman_join(wtpman)) {
wtpman_remove(wtpman);
return NULL;
}
cw_dbg(DBG_INFO, "WTP from %s has joined with session id: %s",
sock_addr2str_p(&conn->addr, sock_buf),
format_bin2hex(conn->session_id, 16));
*/
exit(0);
return NULL;
@ -433,72 +487,114 @@ void wtpman_destroy(struct wtpman *wtpman)
static void copy(struct cw_ElemHandlerParams * params)
{
// struct wtpman * wtpman;
//struct cw_Conn * conn;
//wtpman = (struct wtpman*)params->conn->data;
//conn = (struct cw_Conn*)params->conn;
// cw_dbg(DBG_X,"------------- Here is the config we ve got from WTP ---------------- ");
// cw_cfg_dump(params->cfg);
// cw_dbg(DBG_X,"------------- This was the config we ve got from WTP ---------------- ");
// cw_dbg(DBG_X,"Now copying:");
// cw_cfg_copy(params->cfg,conn->local_cfg,0,"");
cw_cfg_copy(params->cfg, params->conn->remote_cfg,DBG_CFG_UPDATES,"GlobalCfg");
// cw_dbg(DBG_X,"Copying done.");
}
static int discovery_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
static void catch_cfg(struct cw_ElemHandlerParams * params, int create, const char *format, ...)
{
struct cw_Conn * conn = (struct cw_Conn*)params->conn;
const char *wtpname;
char filename[200];
FILE *f;
cw_Cfg_t * cfg_list[3];
if (!cw_cfg_get_bool(params->conn->global_cfg,"actube/save-initial-wtp-config",0))
return;
cfg_list[0]=params->cfg;
cfg_list[1]=params->conn->remote_cfg;
cfg_list[2]=NULL;
wtpname = cw_cfg_get_l(cfg_list,"capwap/wtp-name","default");
sprintf(filename,"wtp-initial-%s.ckv",wtpname);
if (create)
f = fopen(filename,"w");
else
f = fopen(filename,"a");
if (f==NULL)
return;
if (create)
fprintf(f,"#\n# Initial config for WTP '%s' - catched by ACTube\n#\n\n",wtpname);
if (format !=NULL){
va_list args;
va_start(args,format);
vfprintf(f,format,args);
va_end(args);
}
cw_cfg_write_to_file(f, params->cfg);
fclose(f);
}
static int discovery_cb(struct cw_ElemHandlerParams * params, struct cw_MsgCb_data * d)
{
cw_dbg(DBG_X,"DISCOVERY Callback");
copy(params);
catch_cfg(params,1,"\n#\n# Discovery Request\n#\n");
const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default");
sprintf(filename,"wtp-discovery-%s.ckv",wtpname);
cw_cfg_save(filename,params->cfg,NULL);
cw_cfg_clear(params->cfg);
if (d->parent)
return d->parent->fun(params,d->parent);
return 0;
}
static int join_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
static int join_cb(struct cw_ElemHandlerParams * params, struct cw_MsgCb_data *d)
{
struct cw_Conn * conn = (struct cw_Conn*)params->conn;
char filename[200];
cw_dbg(DBG_X,"JOIN Callback");
copy(params);
const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default");
sprintf(filename,"wtp-join-%s.ckv",wtpname);
cw_cfg_save(filename,params->cfg,NULL);
cw_cfg_clear(params->cfg);
catch_cfg(params,0,"\n#\n# Join Request\n#\n");
if (d->parent)
return d->parent->fun(params,d->parent);
return 0;
}
static int update_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
/*
static int fill_update_cfg(struct cw_Conn * conn)
{
struct cw_Conn * conn = (struct cw_Conn*)params->conn;
char filename[200];
struct cw_Cfg_iter cfi;
struct cw_Cfg_entry *e;
cw_Cfg_t * u;
u=cw_cfg_create();
if( cw_cfg_load("status_response.ckv",u)){
cw_log(LOG_ERR,"Cant load file");
stop();
};
cw_cfg_dump(conn->remote_cfg);
cw_cfg_iter_init(u, &cfi, NULL);
while ((e = cw_cfg_iter_next(&cfi, NULL))!=NULL){
const char * r;
r = cw_cfg_get(conn->remote_cfg, e->key, "[]");
// cw_dbg(DBG_CFG_UPDATES,"check: %s: %s",e->key,e->val);
if (strcmp(r,e->val)==0)
continue;
cw_dbg(DBG_CFG_UPDATES,"Status reps: %s: %s -> %s",e->key,r,e->val);
}
cw_dbg(DBG_X,"UPDATE Callback");
copy(params);
return 0;
}
*/
const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default");
sprintf(filename,"wtp-status-%s.ckv",wtpname);
cw_cfg_save(filename,params->cfg,NULL);
//stop();
static int cfg_status_cb(struct cw_ElemHandlerParams * params, struct cw_MsgCb_data *d)
{
catch_cfg(params,0,"\n#\n# Configuration Status Request\n#\n");
if (d->parent)
return d->parent->fun(params,d->parent);
return 0;
}
static int event_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
static int event_cb(struct cw_ElemHandlerParams * params, struct cw_MsgCb_data *d)
{
struct cw_Conn * conn = (struct cw_Conn*)params->conn;
struct wtpman * wtpman = (struct wtpman *)conn->data;
char filename[200];
@ -507,9 +603,26 @@ static int event_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, i
copy(params);
const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default");
sprintf(filename,"wtp-event-%s.ckv",wtpname);
cw_cfg_save(filename,conn->remote_cfg,NULL);
//stop();
sprintf(filename,"wtp-event-%d-%s.ckv",wtpman->ctr++,wtpname);
cw_cfg_save(filename,params->cfg,NULL);
return 0;
}
static int change_state_event_cb(struct cw_ElemHandlerParams * params,struct cw_MsgCb_data * d)
{
struct cw_Conn * conn = (struct cw_Conn*)params->conn;
struct wtpman * wtpman = (struct wtpman *)conn->data;
char filename[200];
cw_dbg(DBG_X,"WTP EVENT Callback");
copy(params);
const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default");
sprintf(filename,"wtp-change-event-%d-%s.ckv",wtpman->ctr++,wtpname);
cw_cfg_save(filename,params->cfg,NULL);
return 0;
}
@ -522,7 +635,7 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
{
struct sockaddr dbgaddr;
socklen_t dbgaddrl;
int sockfd, replyfd;
int sockfd, replyfd, data_sockfd,data_replyfd;
char sock_buf[SOCK_ADDR_BUFSIZE];
struct wtpman *wtpman;
@ -530,10 +643,13 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
if (!wtpman)
return 0;
wtpman->ctr=0;
if (socklist[socklistindex].type != SOCKLIST_UNICAST_SOCKET) {
int port = sock_getport(&socklist[socklistindex].addr);
replyfd = socklist_find_reply_socket(srcaddr, port);
data_replyfd=replyfd;
if (replyfd == -1) {
cw_log(LOG_ERR,
@ -544,10 +660,11 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
}
} else {
replyfd = socklist[socklistindex].sockfd;
data_replyfd = socklist[socklistindex].data_sockfd;
}
sockfd = replyfd; /*//socklist[socklistindex].reply_sockfd; */
data_sockfd = data_replyfd;
dbgaddrl = sizeof(dbgaddr);
getsockname(sockfd, &dbgaddr, &dbgaddrl);
@ -565,6 +682,21 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
wtpman_destroy(wtpman);
return NULL;
}
wtpman->dconn = cw_conn_create(data_sockfd, srcaddr, 100);
if (!wtpman->dconn) {
wtpman_destroy(wtpman);
return NULL;
}
cw_conn_register_msg_cb(wtpman->conn,
CAPWAP_MSG_DISCOVERY_REQUEST,
discovery_cb);
wtpman->conn->global_cfg = global_cfg;
wtpman->conn->local_cfg = cw_cfg_create();
wtpman->wtp_cfg = cw_cfg_create();
@ -572,6 +704,7 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
wtpman->conn->role = CW_ROLE_AC;
wtpman->conn->data=wtpman;
wtpman->dconn->data=wtpman;
wtpman->conn->cfg_list[0]=wtpman->conn->update_cfg;
wtpman->conn->cfg_list[1]=wtpman->conn->remote_cfg;
@ -584,23 +717,6 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
sock_copyaddr(&wtpman->conn->data_addr,
(struct sockaddr *) &wtpman->conn->addr);
cw_conn_set_msg_cb(wtpman->conn,
CAPWAP_MSG_DISCOVERY_REQUEST,
discovery_cb);
cw_conn_set_msg_cb(wtpman->conn,
CAPWAP_MSG_JOIN_REQUEST,
join_cb);
cw_conn_set_msg_cb(wtpman->conn,
CAPWAP_MSG_CONFIGURATION_STATUS_REQUEST,
update_cb);
cw_conn_set_msg_cb(wtpman->conn,
CAPWAP_MSG_WTP_EVENT_REQUEST,
event_cb);
// wtpman->conn->mods = conf_mods;
@ -634,15 +750,37 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
cmod->name, bmod->name);
wtpman->conn->msgset =
cw_mod_get_msg_set(wtpman->conn, cmod, bmod);
wtpman->dconn->msgset=wtpman->conn->msgset;
wtpman->conn->detected = 1;
cmod->setup_cfg(wtpman->conn);
// if (wtpman->conn->setup_complete)
// wtpman->conn->setup_complete(wtpman->conn);
cw_conn_register_msg_cb(wtpman->conn,
CAPWAP_MSG_JOIN_REQUEST,
join_cb);
cw_conn_register_msg_cb(wtpman->conn,
CAPWAP_MSG_CONFIGURATION_STATUS_REQUEST,
cfg_status_cb);
cw_conn_register_msg_cb(wtpman->conn,
CAPWAP_MSG_WTP_EVENT_REQUEST,
event_cb);
/* cw_conn_register_msg_cb(wtpman->conn,
CAPWAP_MSG_CHANGE_STATE_EVENT_REQUEST,
change_state_event_cb);*/
}
}
cw_dbg(DBG_X,"WTPMAN_CREATED: %p",wtpman);
return wtpman;
@ -651,7 +789,6 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
void wtpman_addpacket(struct wtpman *wtpman, uint8_t * packet, int len)
{
// cw_dbg(DBG_X,"ADD PACKET DETECTED %d",wtpman->conn->detected);
conn_q_add_packet(wtpman->conn, packet, len);
}
@ -660,5 +797,14 @@ void wtpman_start(struct wtpman *wtpman, int dtlsmode)
cw_dbg(DBG_INFO, "Starting wtpman, DTLS mode = %d", dtlsmode);
wtpman->dtlsmode = dtlsmode;
pthread_create(&wtpman->thread, NULL, wtpman_main, (void *) wtpman);
pthread_create(&wtpman->thread, NULL, wtpman_data_main, (void *) wtpman);
return;
}
void wtpman_datapacket(struct wtpman *wtpman, uint8_t * packet, int len)
{
conn_q_add_packet(wtpman->dconn, packet, len);
}

View File

@ -17,6 +17,7 @@ struct wtpman {
pthread_t thread;
struct cw_Conn *conn;
struct cw_Conn *dconn;
/* wtp data */
@ -40,8 +41,13 @@ struct wtpman {
cw_Cfg_t * wtp_cfg;
cw_Cfg_t * discovery_cfg;
cw_Cfg_t * join_cfg;
cw_Cfg_t * config_status_cfg;
int update;
int ctr;
};
/*
@ -62,6 +68,7 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
extern void wtpman_addpacket(struct wtpman *wtpman, uint8_t * packet, int len);
extern void wtpman_destroy(struct wtpman *wtpman);
extern void wtpman_start(struct wtpman *wtpman, int dtlsmode);
void wtpman_datapacket(struct wtpman *wtpman, uint8_t * packet, int len);

View File

@ -0,0 +1,5 @@
#!/bin/sh
wget https://w1.fi/releases/hostapd-2.10.tar.gz
tar xzvf hostapd-2.10.tar.gz

View File

@ -6,9 +6,6 @@ CWSRC=\
cw.c\
cw_check_missing_mand.c\
cw_clock_lap.c\
cw_dbg_elem.c\
cw_dbg_set_level.c\
cw_dbg_set_level_from_str.c\
cw_filename.c\
cw_format_dump.c\
cw_format_pkt_hdr.c\
@ -18,13 +15,11 @@ CWSRC=\
cw_in_capwap_local_ipv4_address.c\
cw_in_capwap_local_ipv6_address.c\
cw_in_generic_with_index.c\
cw_in_radio_generic_struct.c\
cw_in_idx_generic.c\
cw_in_idx_generic_struct.c\
cw_in_generic_indexed_enum.c\
cw_out_generic_indexed_enum.c\
cw_in_generic_enum.c\
cw_out_generic_struct.c\
cw_out_idx_generic_struct.c\
cw_init_data_keep_alive_msg.c\
cw_inline.c\
@ -37,7 +32,6 @@ CWSRC=\
cw_put_elem_radio_operational_state.c\
cw_put_image_data.c\
cw_put_local_ip_address.c\
cw_radio_set_admin_state.c\
cw_rand.c\
cw_randint.c\
cw_read_ac_descriptor.c\
@ -62,11 +56,12 @@ CWSRC=\
cw_type_ipaddress.c\
cw_type_word.c\
cw_type_sysptr.c\
cw_type_array.c\
cw_type_bits.c\
cw_write_descriptor_subelem.c\
cw_write_radio_element.c\
cw_detect_nat.c\
cw_read_from.c \
cw_in_generic_struct.c\
# cw_in_check_disc_req.c\
# cw_in_check_img_data_req_ac.c\
@ -77,46 +72,16 @@ CWSRC=\
# cw_out_generic.c\
#
# cw_process_element.c\
# cw_out_generic_struct.c\
cw_in_radio_generic_struct.c\
cw_in_generic_struct.c\
cw_radio_set_admin_state.c\
cw_dbg_elem.c\
KTVSRC=\
cfg.c\
# cw_ktv_add.c\
cw_ktv_idx_get.c\
cw_ktv_mavlcmp.c\
cw_ktv_mavlcmp_type_by_name.c\
cw_ktv_mavldel.c\
# cw_ktv_parser.c\
# cw_ktv_del_sub.c\
# cw_ktv_base_exists.c\
cw_ktv_add_from_str.c\
cw_ktv_read_file.c\
cw_ktv_readline.c\
cw_ktv_save.c\
cw_ktv_std_types.c\
cw_ktv_read_struct.c\
cw_ktv_write_struct.c\
# cw_ktv_get_byte.c\
cw_ktv_get_bool.c\
cw_ktv_get_bstr16.c\
cw_ktv_set_byte.c\
cw_ktv_set_word.c\
cw_ktv_set_dword.c\
# cw_ktv_get_word.c\
cw_ktv_get_dword.c\
cw_ktv_get_sysptr.c\
cw_ktv_get_str.c\
# cw_ktv_cast.c\
cw_ktv_replace.c\
cw_ktv_get.c\
LWSRC=\
lw_addelem.c\
lw_checksum.c\
@ -169,7 +134,8 @@ LOGSRC=\
log_errno.c\
log_syslog.c\
dbg.c\
dbg_strings.c\
# dbg_strings.c\
MISCSRC=\
bstr16_create.c\
@ -205,7 +171,6 @@ MISCSRC=\
msgset.c\
send.c\
strheap.c\
netconn.c\
conn.c \
val.c \
discovery.c\
@ -222,6 +187,7 @@ MISCSRC=\
# cw_put_msg.c\
# conn_process_packet.c\
# conn_destroy.c\
netconn.c\
DTLSSRC+=\
dtls_bio.c\

View File

@ -465,9 +465,9 @@ enum cw_reboot_failure_types {
/**
* The Missing AC List Result Code is sent by the
* WTP to the AC when the AC List is missing */
#define CW_RESULT_MISSING_AC_LIST 1
#define CAPWAP_RESULT_SUCCESS_NAT 2
#define CW_RESULT_JOIN_FAILURE 3
#define CW_RESULT_MISSING_AC_LIST 1
#define CAPWAP_RESULT_SUCCESS_NAT 2
#define CAPWAP_RESULT_JOIN_FAILURE 3
#define CW_RESULT_JOIN_RESOURCE_DEPLETION 4
#define CW_RESULT_JOIN_UNKNOWN_SOURCE 5
#define CW_RESULT_JOIN_INCORRECT_DATA 6
@ -491,7 +491,7 @@ enum cw_reboot_failure_types {
13 Configuration Failure (Unable to Apply Requested Configuration
- Service Not Provided)
*/
#define CAPWAP_RESULT_CONFIGURATION_FAILURE_SERVICE_NOT PROVIDED 13
#define CAPWAP_RESULT_CONFIGURATION_FAILURE_SERVICE_NOT_PROVIDED 13
/**
* Image Data Error (Invalid Checksum)
*/

View File

@ -86,12 +86,15 @@ enum radioelems {
};
/** IEEE 802.11 Radio Information Message Element */
#define CAPWAP80211_ELEM_WTP_RADIO_INFORMATION 1048
/** IEEE 802.11 Add WLAN Message element */
#define CAPWAP80211_ELEM_ADD_WLAN 1024
/** IEEE 802.11 Antenna Message element */
#define CAPWAP80211_ELEM_ANTENNA 1025
/** IEEE 802.11 WTP Radio Configuration */
#define CAPWAP80211_ELEM_WTP_RADIO_CONFIGURATION 1046
/** IEEE 802.11 Radio Information Message Element */
#define CAPWAP80211_ELEM_WTP_RADIO_INFORMATION 1048
/**

View File

@ -80,7 +80,13 @@ static void del(void *ptr)
free((void *) e->val);
}
/**
* Create an empty cfg
* @return A pointer to the cfg or NULL if an error has accoured.
*
* In case of an error consult errno to find out the reason.
* The created config must be freed by #cw_cfg_destroy.
*/
cw_Cfg_t *cw_cfg_create()
{
cw_Cfg_t * cfg;
@ -88,6 +94,7 @@ cw_Cfg_t *cw_cfg_create()
if (cfg == NULL)
return NULL;
memset(cfg,0,sizeof(cw_Cfg_t));
cfg->name = CW_CFG_DEFAULT_NAME;
cfg->cfg = mavl_create(cmp, del, sizeof(struct cw_Cfg_entry));
if (cfg->cfg==NULL){
cw_cfg_destroy(cfg);
@ -122,6 +129,16 @@ int cw_cfg_set(cw_Cfg_t * cfg, const char *key, const char *val)
return -1;
}
void cw_cfg_del(cw_Cfg_t * cfg, const char *key)
{
struct cw_Cfg_entry e;
e.key = key;
e.val=NULL;
mavl_del(cfg->cfg,&e);
}
const char *cw_cfg_get(cw_Cfg_t * cfg, const char *key, const char *def)
{
struct cw_Cfg_entry e, *r;
@ -137,7 +154,6 @@ const char *cw_cfg_get_l(cw_Cfg_t ** cfg, const char * key, const char *def)
int i;
struct cw_Cfg_entry e, *r;
for(i=0; cfg[i]!=NULL; i++){
// cw_dbg(DBG_X,"GET_L IN: %p",cfg[i]);
e.key = key;
r = mavl_get(cfg[i]->cfg, &e);
if (r!=NULL)
@ -160,11 +176,29 @@ bstr16_t cw_cfg_get_bstr16(cw_Cfg_t * cfg, const char * key, const char *def)
s = cw_cfg_get(cfg,key,def);
if(s==NULL)
s=def;
if (s==NULL)
return NULL;
return bstr16_create_from_str(s);
}
bstr16_t cw_cfg_get_bstr16_l(cw_Cfg_t **cfgs, const char * key, const char *def)
{
bstr16_t s;
int i;
for(i=0; cfgs[i]!=NULL; i++){
s = cw_cfg_get_bstr16(cfgs[i],key,NULL);
if (s!=NULL)
return s;
}
if (def == NULL)
return NULL;
return bstr16_create_from_str(def);
}
int cw_cfg_set_bstr16(cw_Cfg_t * cfg, const char * key, bstr16_t str)
{
CW_TYPE_BSTR16->read(cfg,key,bstr16_data(str),bstr16_len(str),NULL);
@ -186,7 +220,7 @@ void cw_cfg_dump(cw_Cfg_t * cfg)
}
}
void cw_cfg_fdump(FILE *f, cw_Cfg_t * cfg)
void cw_cfg_fdump(FILE *f, cw_Cfg_t * cfg, const char *filter)
{
mavliter_t it;
struct cw_Cfg_entry *e;
@ -194,6 +228,13 @@ void cw_cfg_fdump(FILE *f, cw_Cfg_t * cfg)
mavliter_foreach(&it) {
e = mavliter_get(&it);
if (filter != NULL){
if (strlen(filter)){
if (strstr(e->key,filter)==NULL){
continue;
}
}
}
fprintf(f,"%s: '%s'\n", e->key, e->val);
}
}
@ -487,6 +528,7 @@ int cw_cfg_load(const char *filename, cw_Cfg_t * cfg)
FILE *f = fopen(filename, "rb");
if (!f)
return errno;
errno=0;
errs = cw_cfg_read_from_file(f, cfg);
fclose(f);
@ -559,7 +601,12 @@ void cw_cfg_iter_init(cw_Cfg_t * cfg, struct cw_Cfg_iter *cfi, const char *base)
search.key = base;
mavliter_init(&(cfi->it), cfg->cfg);
mavliter_seek(&(cfi->it), &search, 0);
if (base == NULL){
mavliter_seek_set(&(cfi->it));
mavliter_next(&(cfi->it));
}
else
mavliter_seek(&(cfi->it), &search, 0);
cfi->base = base;
}
@ -568,16 +615,16 @@ struct cw_Cfg_entry *cw_cfg_iter_next(struct cw_Cfg_iter *cfi, const char *nnkey
{
struct cw_Cfg_entry *e;
int bl, kl;
const char *d;
// const char *d;
e = mavliter_get(&(cfi->it));
if (e == NULL)
if (e == NULL){
return NULL;
}
if (cfi->base ==NULL)
goto eeX;
bl = strlen(cfi->base);
kl = strlen(e->key);
if (bl > kl)
return NULL;
@ -590,16 +637,19 @@ struct cw_Cfg_entry *cw_cfg_iter_next(struct cw_Cfg_iter *cfi, const char *nnkey
}
}
d = strchr(e->key, '.');
if (d == NULL)
if (e->key[bl]!='.' && e->key[bl]!='/')
return NULL;
if (d - e->key != bl)
/* d = strchr(e->key, '.');
if (d == NULL)
return NULL;
if (d - e->key != bl)
return NULL;*/
if (strncmp(cfi->base, e->key, bl) != 0)
return NULL;
eeX:
mavliter_next(&(cfi->it));
return e;
}
@ -615,7 +665,13 @@ int cw_cfg_get_bool(cw_Cfg_t * cfg, const char * key, int def)
return v.val.boolean;
}
/*
int cw_cfg_set_bool(cw_Cfg_t * cfg, const char * key, int val)
{
return cw_cfg_set(cfg,key,val ? "true":"false");
}
*/
uint8_t cw_cfg_get_byte(cw_Cfg_t * cfg, char *key, uint8_t def)
{
struct cw_Val v;
@ -638,6 +694,14 @@ uint8_t cw_cfg_get_byte_l(cw_Cfg_t ** cfgs, char *key, uint8_t def)
return v.val.byte;
}
int cw_cfg_get_int(cw_Cfg_t * cfg, const char *key, int def)
{
const char *s = cw_cfg_get(cfg,key,NULL);
if (s==NULL)
return def;
return atoi(s);
}
uint16_t cw_cfg_get_word(cw_Cfg_t * cfg, const char *key, uint16_t def)
@ -662,7 +726,6 @@ uint16_t cw_cfg_get_word_l(cw_Cfg_t ** cfg, const char *key, uint16_t def)
/*
int cw_cfg_get_word(cw_Cfg_t * cfg, char *key, const char * def)
{
@ -682,8 +745,7 @@ void cw_cfg_set_int(cw_Cfg_t * cfg, const char * key, int val)
}
int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key)
int cw_cfg_get_new_index(cw_Cfg_t * cfg, const char *key)
{
char ikey[CW_CFG_MAX_KEY_LEN];
struct cw_Cfg_entry search, * result;
@ -699,7 +761,7 @@ int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key)
return 0;
}
d = strchr(result->key,'.');
d = strrchr(result->key,'.');
if (d==NULL){
return 0;
}
@ -710,6 +772,46 @@ int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key)
return atoi(d+1)+1;
}
int cw_cfg_get_first_index(cw_Cfg_t * cfg, const char *key, int n)
{
char ikey[CW_CFG_MAX_KEY_LEN];
struct cw_Cfg_entry search, * result;
char *d;
int l;
sprintf(ikey,"%s.%d",key,n);
search.key=ikey;
result = mavl_get_first(cfg->cfg,&search);
if (result == NULL){
return -1;
}
d = strrchr(ikey,'.');
if (d==NULL){
return -1;
}
l = d-ikey;
if (strncmp(result->key,ikey,l)!=0)
return -1;
return atoi(result->key+l+1);
}
int cw_cfg_get_first_index_l(cw_Cfg_t ** cfgs, const char *key, int n)
{
int r;
while(*cfgs != NULL){
r = cw_cfg_get_first_index(*cfgs,key,n);
if (r!=-1)
return r;
cfgs++;
}
return -1;
}
int cw_cfg_set_val(cw_Cfg_t * cfg, const char *key, const struct cw_Type *type, const void * valguard, const uint8_t * data, int len)
{
cw_Val_t mdata, *mresult;
@ -808,22 +910,43 @@ void cw_cfg_clear(cw_Cfg_t *cfg)
int cw_cfg_base_exists(cw_Cfg_t * cfg, const char *key)
{
struct cw_Cfg_entry e, *result;
//cw_dbg(DBG_X,"LOOX FOR: %s",key);
e.key=key;
result = mavl_get_first(cfg->cfg,&e);
if (result == NULL)
return 0;
//cw_dbg(DBG_X,"BASEXXX: %s",result->key);
int rl,kl;
char skey[CW_CFG_MAX_KEY_LEN];
char * delimiters = "/.";
char * d;
if (strlen(result->key)<strlen(key))
return 0;
//cw_dbg(DBG_X,"BASEXXX1: %d",strlen(key));
if (result->key[strlen(key)]!='/' && result->key[strlen(key)]!='.')
return 0;
//cw_dbg(DBG_X,"BASEXXX2: ");
if (strncmp(result->key,key,strlen(key))==0)
/* can we find the base exactly ?*/
if (cw_cfg_get(cfg,key,NULL)!=NULL)
return 1;
cw_dbg(DBG_X,"BASEXXX3: ");
for(d=delimiters; *d!=0; d++){
sprintf(skey,"%s%c",key,*d);
e.key=skey;
result = mavl_get_first(cfg->cfg,&e);
/* if we've found nothing, we can't check more */
if (result == NULL)
continue;
rl = strlen(result->key);
kl = strlen(skey);
/* if result key is shorter than key */
if (rl<kl)
continue;
/* both keys are identical in length */
if (rl==kl){
if (strcmp(result->key,key)==0)
return 1;
}
if (strncmp(result->key,skey,kl)==0)
return 1;
}
return 0;
}

View File

@ -5,28 +5,53 @@
#include "val.h"
#include "bstr.h"
#define CW_CFG_MAX_KEY_LEN 1024
/**
*@file
*@brief
*@defgroup CFG SOCK
*@{
*/
/** Maximum size of a key used in cfg objects */
#define CW_CFG_MAX_KEY_LEN 1024
/** Default name for fresh cfg's created by #cw_cfg_create */
#define CW_CFG_DEFAULT_NAME "[anonymous]"
/**
* A Cfg object
*/
struct cw_Cfg {
struct mavl * cfg;
const char *name;
struct mavl * cfg; /**< The AVL-tree containig the keys
and vals */
const char *name; /**< A name for this config object */
int dbg_level;
const char *dbg_prefix;
};
typedef struct cw_Cfg cw_Cfg_t;
/**
* An antry for a Cfg object
*/
struct cw_Cfg_entry{
const char *key; /**< A string representing the key
of this entry */
const char *val; /**< The value, represented by a string */
};
cw_Cfg_t * cw_cfg_create();
int cw_cfg_set(cw_Cfg_t *cfg,const char *key, const char *val);
void cw_cfg_dump(cw_Cfg_t *cfg);
int cw_cfg_read_from_file(FILE * file, cw_Cfg_t * cfg);
int cw_cfg_load(const char *filename,cw_Cfg_t * cfg);
struct cw_Cfg_entry{
const char *key;
const char *val;
};
struct cw_Cfg_iter{
struct mavliter it;
@ -44,7 +69,7 @@ void cw_cfg_set_int(cw_Cfg_t * cfg, const char * key, int val);
uint8_t cw_cfg_get_byte(cw_Cfg_t * cfg, char *key, uint8_t def);
bstr16_t cw_cfg_get_bstr16(cw_Cfg_t * cfg, const char * key, const char *def);
int cw_cfg_set_bstr16(cw_Cfg_t * cfg, const char * key, bstr16_t str);
int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key);
int cw_cfg_get_new_index(cw_Cfg_t * cfg, const char *key);
const char *cw_cfg_get_l(cw_Cfg_t ** cfg, const char * key, const char *def);
void cw_cfg_copy(cw_Cfg_t *src, cw_Cfg_t *dst,int dbg_level,const char *dbg_prefix);
void cw_cfg_destroy(cw_Cfg_t *cfg);
@ -56,14 +81,23 @@ int cw_cfg_base_exists_l(cw_Cfg_t ** cfgs, const char *key);
int cw_cfg_save(const char *filename, cw_Cfg_t *cfg, const char *format, ...);
uint16_t cw_cfg_get_word_l(cw_Cfg_t ** cfg, const char *key, uint16_t def);
void cw_cfg_fdump(FILE *f, cw_Cfg_t * cfg);
void cw_cfg_fdump(FILE *f, cw_Cfg_t * cfg, const char *filter);
int cw_cfg_read_from_string(const char *str, cw_Cfg_t *cfg);
void cw_cfg_del(cw_Cfg_t * cfg, const char *key);
int cw_cfg_get_first_index(cw_Cfg_t * cfg, const char *key, int n);
int cw_cfg_get_first_index_l(cw_Cfg_t ** cfgs, const char *key, int n);
int cw_cfg_get_int(cw_Cfg_t * cfg, const char *key, int def);
int cw_cfg_write_to_file(FILE *f, cw_Cfg_t * cfg);
#define cw_cfg_set_bool(cfg,key,val) \
cw_cfg_set(cfg,key,(val) ? "true":"false")
int cw_cfg_set_val(cw_Cfg_t * cfg, const char *key, const struct cw_Type *t, const void * valguard, const uint8_t * data, int len);
bstr16_t cw_cfg_get_bstr16_l(cw_Cfg_t **cfgs, const char * key, const char *def);
#define cw_cfg_get_word2(cfg1,cfg2,key,def) \
cw_cfg_get_word(cfg1,key,cw_cfg_get_word(cfg2,key,def))
@ -74,3 +108,6 @@ int cw_cfg_set_val(cw_Cfg_t * cfg, const char *key, const struct cw_Type *t, con
#endif
/**@}*/

View File

@ -24,11 +24,12 @@
#include "dtls.h"
#define MAX_MSG_CBS 5
struct msg_callback{
int type; /**< message type */
cw_MsgCallbackFun fun;
int type; /**< message type */
struct cw_MsgCb_data data[MAX_MSG_CBS];
int count;
};
int msg_callback_cmp(const void *v1,const void *v2)
@ -62,19 +63,55 @@ void cw_conn_init(struct cw_Conn * conn)
conn->remote_cfg = cw_cfg_create();
conn->local_cfg = cw_cfg_create();
conn->cfg_list[0]=NULL;
conn->remote_addr[0]=0;
}
int cw_conn_set_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun)
/**
* Register a message callback function.
* @param conn the connection the registered cb functions belongs to
* @param type The associated msg type. Whenever a message of this type is
* received, the callback function will be called
* @param fun A pinter to the callback function
*
*/
int cw_conn_register_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun)
{
struct msg_callback cb;
struct msg_callback cb, *result;
int exists;
cb.type = type;
cb.fun = fun;
mavl_insert(conn->msg_callbacks,&cb,&exists);
cb.data[0].fun = fun;
cb.data[0].parent = NULL;
cb.count = 0;
result = mavl_insert(conn->msg_callbacks,&cb,&exists);
cw_dbg(DBG_X, "Registering msg callback: %d %p",type,result);
if (result==NULL)
return 0;
if (exists){
if (result->count>=MAX_MSG_CBS){
cw_log(LOG_ERROR,"Too many msg callback registrations for msg id %d",type);
return 0;
}
result->count++;
result->data[result->count].fun=fun;
result->data[result->count].parent=&(result->data[result->count-1]);
cw_dbg(DBG_X,"The result exists: %p %p %d %p",result,&cb,result->count,
result->data[result->count].parent
);
}
return 1;
}
/*
cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type)
{
struct msg_callback cb,*result;
@ -83,8 +120,22 @@ cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type)
if (result == NULL)
return NULL;
return result->fun;
}*/
int cw_conn_run_msg_cbs(struct cw_Conn * conn, int type, struct cw_ElemHandlerParams *params)
{
struct msg_callback cb,*result;
cb.type=type;
result = mavl_get(conn->msg_callbacks,&cb);
if (result == NULL)
return -1;
return result->data[result->count].fun(params,&(result->data[result->count]));
}
/**
* Create a conn object
* @param sock a socket
@ -106,8 +157,10 @@ struct cw_Conn * cw_conn_create(int sock, struct sockaddr * addr, int qsize)
conn->sock=sock;
if (addr)
if (addr){
sock_copyaddr(&conn->addr,addr);
sock_addr2str_p(addr, conn->remote_addr);
}
conn->fragman = fragman_create();
@ -516,12 +569,12 @@ static int process_elements(struct cw_Conn *conn, uint8_t * rawmsg, int len,
message->postprocess(&params,elems_ptr, elems_len);
}
cw_MsgCallbackFun cb_fun = cw_conn_get_msg_cb(conn,message->type);
if (cb_fun != NULL){
result_code = cb_fun(&params,elems_ptr, elems_len);
}
else{
result_code = cw_conn_run_msg_cbs(conn,message->type,&params);
// cw_MsgCallbackFun cb_fun = cw_conn_get_msg_cb(conn,message->type);
if (result_code==-1){
cw_cfg_clear(conn->update_cfg);
result_code=0;
}
// conn->remote_cfg=params.cfg;
@ -554,7 +607,6 @@ static int process_elements(struct cw_Conn *conn, uint8_t * rawmsg, int len,
* Put further actions here, if needed.
*/
}
if (params.unrecognized)
mlist_destroy(params.unrecognized);
cw_cfg_destroy(params.cfg);
@ -713,24 +765,22 @@ int conn_process_packet2(struct cw_Conn *conn, uint8_t * packet, int len,
if (cw_get_hdr_flag_f(packet)) {
/* fragmented, add the packet to fragman */
uint8_t *f;
uint8_t *f,*fp;
int rc;
f = fragman_add(conn->fragman, packet, offs, payloadlen);
if (f == NULL) {
fp = fragman_add(conn->fragman, packet, offs, payloadlen);
if (fp == NULL) {
errno = EAGAIN;
return -1;
}
f =fp+MAX_PKT_HDR_LEN;
cw_dbg_pkt(DBG_PKT_IN, conn, f + 4, *(uint32_t *) f, from);
/*// cw_dbg_msg(DBG_MSG_IN, conn, f + 4, *(uint32_t *) f, from);*/
/* // XXX: Modify fragman to not throw away CAPWAP headers*/
cw_dbg_pkt(DBG_PKT_IN, conn, fp, *(uint32_t *) f+MAX_PKT_HDR_LEN, from);
rc = conn->process_message(conn, f + 4, *(uint32_t *) f, from);
free(f);
free(fp);
return rc;
}

View File

@ -58,6 +58,8 @@ struct cw_action_in;
struct cw_Conn {
int sock;
struct sockaddr_storage addr;
char remote_addr[64]; /* Contains a printfable string, of the connections
peer address */
struct connlist * connlist;
@ -71,19 +73,19 @@ struct cw_Conn {
int recv_timeout;
cw_Cfg_t * global_cfg; /**< This should set the global cfg of the program
cw_Cfg_t * global_cfg; /**< This should set to the global cfg of the program
which is using this conn object.
Teh global_cfg has to be treated read-only. */
cw_Cfg_t * local_cfg; /**< local_cfg contains overrides for global_cfg
wich are related to this conn object. */
wich are related to this conniection. */
cw_Cfg_t * remote_cfg; /**< contains the configuration we now from the
device this conn object ist connected to.
Typically this is what we have got from discovery
response or join response in WTP mode.
And in AC mode this contains date receive from
configuration status request. */
And in AC mode this contains datia received by
configuration status and join request. */
cw_Cfg_t * update_cfg;
@ -311,7 +313,18 @@ int conn_send_msg(struct cw_Conn *conn, uint8_t * rawmsg);
void conn_clear_upd(struct cw_Conn*conn, int merge);
int cw_conn_set_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun);
struct cw_MsgCb_data;
//typedef int (*cw_MsgCallbackFun)(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len,
// struct cw_MsgCb_data *d);
typedef int (*cw_MsgCallbackFun)(struct cw_ElemHandlerParams * params, struct cw_MsgCb_data *d);
struct cw_MsgCb_data{
cw_MsgCallbackFun fun;
struct cw_MsgCb_data * parent;
};
int cw_conn_register_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun);
cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type);
int cw_decode_element(struct cw_ElemHandlerParams *params, int proto,

View File

@ -53,10 +53,10 @@ int conn_send_msg(struct cw_Conn * conn, uint8_t *rawmsg)
/* Zyxel doesn't count msg element length from
behind seqnum */
// Zyxel doesn't count msg element length from
// behind seqnum * /
// if (conn->capwap_mode == CW_MODE_ZYXEL){
/* // XXX val-=3; */
// * // XXX val-=3; * /
// }
@ -75,7 +75,7 @@ mtu = 9440;
int offset = cw_get_hdr_msg_offset(rawmsg);
return cw_send_msg(conn,rawmsg+offset);
/*
if (packetlen>mtu){
cw_set_hdr_flags(ptr,CAPWAP_FLAG_HDR_F,1);
cw_set_dword(ptr+4, conn->fragid<<16 | fragoffset<<3 );
@ -103,7 +103,7 @@ mtu = 9440;
if (conn->write(conn,ptr,mtu)<0)
return -1;
/* // XXX Fragmentation stuff.. */
/ * // XXX Fragmentation stuff.. * /
ptr +=mtu-hlen;
fragoffset+=(mtu-hlen)/8;
@ -122,6 +122,6 @@ mtu = 9440;
cw_dbg_pkt(DBG_PKT_OUT,conn,ptr,packetlen,(struct sockaddr*)&conn->addr);
return conn->write(conn,ptr,packetlen-0);
return conn->write(conn,ptr,packetlen-0); */
}

View File

@ -11,7 +11,7 @@ int cw_in_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams *
char mkey[CW_CFG_MAX_KEY_LEN];
const char *key;
// cw_dbg(DBG_X,"HK: %s",handler->key,);
if (!type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
@ -25,21 +25,16 @@ int cw_in_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams *
else{
key = handler->key;
}
/* cw_dbg(DBG_X, "READ: %s / %s",type->name,key);*/
// cw_dbg(DBG_X, "READ: %s / %s",type->name,key);
type->read(params->cfg, key,elem_data,elem_len,handler->param);
return CAPWAP_RESULT_SUCCESS;
}
int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
int cw_out_generic0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst,const char *key)
{
int start, len, l;
// cw_dbg(DBG_X,"cw_out_generic (%s)%s",((struct cw_Type*)handler->type)->name,handler->key);
@ -47,10 +42,23 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams
// cw_dbg(DBG_X,"Generic out!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
// cw_cfg_dump(params->cfg);
// cw_dbg(DBG_X,"Generic out!!!!!!!!!!!!!!!!!!!!!!!!!!!! ENDDUMP");
//
//
if (!params->elemdata->mand){
if (!cw_cfg_base_exists(params->cfg_list[0],key)){
cw_dbg(DBG_MSG_COMPOSE," Add Elem: %d %d %d %s %s - (bskip)",
params->elemdata->proto,
params->elemdata->vendor,
params->elemdata->id,
handler->name, key);
return 0;
}
}
start = params->msgset->header_len(handler);
len = ((const cw_Type_t*)(handler->type))->
write(params->cfg_list,handler->key,dst+start,handler->param);
write(params->cfg_list,key,dst+start,handler->param);
// cw_dbg(DBG_X, "Type result is %d",len);
if (len == -1) {
@ -62,7 +70,7 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams
cw_log(LOG_ERR,
"Can't put mandatory element %s %d-(%s) into %s. No value for '%s' found.",
vendor, handler->id, handler->name, params->msgdata->name
, handler->key
, key
);
}
else{
@ -79,6 +87,15 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams
l = params->msgset->write_header(handler,dst,len);
return l;
}
int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
return cw_out_generic0(handler,params,dst,handler->key);
}
@ -117,6 +134,39 @@ int cw_out_radio_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerP
int len,i,l,start;
int radios;
len =0;
for (i=0; (i=cw_cfg_get_first_index_l(params->cfg_list,"radio",i))!=-1; i++){
sprintf(key,"radio.%d/%s",i,handler->key);
if (!params->elemdata->mand){
if (!cw_cfg_base_exists(params->cfg_list[0],key)){
cw_dbg(DBG_MSG_COMPOSE," Add Elem: %d %d %d %s %s - (skip)",
params->elemdata->proto,
params->elemdata->vendor,
params->elemdata->id,
handler->name, key);
continue;
}
}
type = (struct cw_Type*)handler->type;
start = params->msgset->header_len(handler)+len;
l = type->write(params->cfg_list, key,dst+start+1,handler->param);
if (l==-1)
continue;
l += cw_put_byte(dst+start,i);
l = params->msgset->write_header(handler,dst+len,l);
len+=l;
}
return len;
radios = cw_cfg_get_byte_l(params->cfg_list,"capwap/wtp-descriptor/max-radios",0);
for(i=0;i<radios;i++){
@ -270,3 +320,148 @@ cw_put_descriptor_subelem (uint8_t *dst, cw_Cfg_t ** cfg_list,
return d-dst;
}
/*
int cw_out_traverse0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst, int i, const char *current, const char * next,
int * stack)
{
char *sl;
int l;
char key[CW_CFG_MAX_KEY_LEN];
int len;
len = 0;
printf("Next: %s\n", next);
sl = strchr(next,'/');
if (sl==NULL){
cw_Val_t * result;
sprintf(key,"%s/%s",current,next);
result = cw_ktv_base_exists(params->cfg,key);
if (result != NULL){
int offset;
int i,l;
offset = params->msgset->header_len(handler);
printf("Yea! We can do it: %s\n",result->key);
for (i=0;i<stack[0];i++){
printf("I=%i\n",stack[i+1]);
}
l= cw_ktv_write_struct(params->cfg,params->cfg,
handler->type,key,dst+offset);
printf("Write struct len %i\n",l);
l=params->msgset->write_header(handler,dst,l);
printf("header wr len %d\n",l);
if (handler->patch){
handler->patch(dst+offset,stack);
}
return l;
}
return 0;
}
strcpy(key,current);
printf("current is %s\n", current);
if (key[0!=0])
strcat(key,"/");
l = sl - next;
strncat(key,next,l);
printf("Here we are %s\n",key);
cw_dbg_ktv_dump(params->cfg,DBG_INFO,"start"," ", "end" );
i=-1;
while(1){
char basekey[CW_CFG_MAX_KEY_LEN];
cw_Val_t * result;
i = cw_ktv_idx_get_next(params->cfg,key,i+1);
if (i==-1)
break;
sprintf(basekey,"%s.%d",key,i);
printf("Our basekey is %s\n",basekey);
result = cw_ktv_base_exists(params->cfg,basekey);
if (result == NULL){
continue;
}
stack[0]++;
stack[stack[0]]=i;
len += cw_out_traverse0(handler,params,dst+len,-1,basekey,next+l+1, stack);
printf("Len is now %d\n", len);
}
return len;
return 0;
}
*/
int cw_out_traverse(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
/* char current[CW_CFG_MAX_KEY_LEN];
int stack[10];
stack[0]=0;
current[0]=0;
// return cw_out_traverse0(handler,params,dst,-1,current,handler->key, stack);*/
return 0;
}
int walk0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst, const char *current, const char * next)
{
char key[CW_CFG_MAX_KEY_LEN];
const char *sl;
int rc;
int len=0;
/* Is this the last key ? */
sl = strchr(next,'/');
if (sl){
char basekey[CW_CFG_MAX_KEY_LEN+13];
int i,l;
strcpy(key,current);
l = sl - next;
strncat(key,next,l);
for (i=0; (i=cw_cfg_get_first_index_l(params->cfg_list,key,i))!=-1; i++){
sprintf(basekey,"%s.%d%c",key,i, *(sl+1) ?'/':'\0');
rc = walk0(handler,params,dst,basekey,next+l+1);
if (rc>0)
len+=rc;
}
return len;
}
printf("Final %s [%s]\n",current,next);
return cw_out_generic0(handler,params,dst,current);
return 0;
}
int cw_out_generic_walk(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
char current[CW_CFG_MAX_KEY_LEN];
// int stack[10];
// stack[0]=0;
current[0]=0;
return walk0(handler,params,dst,current,handler->key);
}

View File

@ -146,8 +146,10 @@
int cw_get_hdr_ws_len(uint8_t * th);
uint8_t *cw_get_hdr_ws_data(uint8_t * th);
int cw_get_hdr_ws_len_7(uint8_t * th);
uint8_t *cw_get_hdr_ws_data(uint8_t * th);
#define cw_get_hdr_ws_data_7(th) (cw_get_hdr_ws_data(th)+1)
#define cw_get_hdr_msg_offset(th) (4*cw_get_hdr_hlen(th))
@ -217,7 +219,7 @@ void cw_set_hdr_rid(uint8_t * th, int rid);
* @see #cw_is_request
*/
#define cw_is_response(msg_id) (!is_response(msg_id))
#define cw_is_response(msg_id) (!cw_is_resquest(msg_id))
uint8_t *cw_get_hdr_msg_elems_ptr(uint8_t * m);
@ -558,6 +560,18 @@ int cw_put_descriptor_subelem (uint8_t *dst, cw_Cfg_t ** cfg_list,
int cw_send_request(struct cw_Conn *conn,int msg_id);
int cw_out_generic_walk(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst);
int cw_out_generic0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst,const char *key);
int cw_init_capwap_packet( uint8_t * buf, int wbid ,int rid, bstr_t rmac, bstr_t wd);
int cw_send_capwap_packet(struct cw_Conn * conn, uint8_t * buf, int hlen, uint8_t * data, int len);
/**
*@}

View File

@ -1,12 +0,0 @@
#ifndef __CW_80211_H
#define __CW_80211_H
/*
int cw_in_80211_mac_operation(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len, struct sockaddr *from);
int cw_read_80211_mac_operation(uint8_t *data,mbag_t r);
*/
#endif

View File

@ -1,26 +0,0 @@
#include "dbg.h"
/**
* Set debug level
* @param level debug level to set, allowed values are enumberated in #cw_dbg_levels structure.
* @param on 1: turns the specified debug level on, 0: turns the specified debug level off.
*/
void cw_dbg_set_level (int level, int on)
{
switch (level) {
case DBG_ALL:
if (on)
cw_dbg_opt_level = 0xffffffff;
else
cw_dbg_opt_level = 0;
break;
default:
if (on)
cw_dbg_opt_level |= (level);
else
cw_dbg_opt_level &= (0xffffffff) ^ (level);
}
}

View File

@ -1,31 +0,0 @@
#include "dbg.h"
int cw_dbg_set_level_from_str(const char *level)
{
int blevel,on;
const char *slevel;
switch(*level){
case '-':
case '!':
case '~':
on =0;
slevel=level+1;
break;
case '+':
slevel=level+1;
on=1;
break;
default:
slevel=level;
on=1;
}
blevel = cw_strlist_get_id(cw_dbg_strings, slevel);
if (blevel==-1)
return 0;
cw_dbg_set_level(blevel,on);
return 1;
}

View File

@ -3,9 +3,10 @@
#include "dbg.h"
#include "cw.h"
#include "cfg.h"
/**
* @brief Detect NAT after a join/discovery request
* @brief Detect NAT after a Join Request
* @param conn Connection object
* @retval 1 NAT detected
* @retval 0 no NAT was detected
@ -15,7 +16,8 @@ int cw_detect_nat(struct cw_ElemHandlerParams *params)
const char * remote_str;
char local_str[128];
remote_str = cw_cfg_get(params->cfg,"capwap-local-ip-address",NULL);
remote_str = cw_cfg_get(params->cfg,"capwap/local-ip-address",NULL);
if (remote_str == NULL){
cw_dbg(DBG_WARN,"Can't detect NAT. No local IP from peer received.");
return 0;
@ -29,9 +31,12 @@ int cw_detect_nat(struct cw_ElemHandlerParams *params)
/* if connected and sent address is the same, there is
* no NAT */
if (strcmp(remote_str,local_str)==0)
if (strcmp(remote_str,local_str)==0){
cw_dbg(DBG_INFO,"Connection from %s: no NAT detected.",local_str);
return 0;
}
/* otherwise ther must be something between AC and WTP */
cw_dbg(DBG_INFO,"Connection from %s: NAT detected.",local_str);
return 1;
}

View File

@ -3,105 +3,104 @@
#include "conn.h"
#include "cw.h"
/**
* @brief Format a packet header for debugging purposes
* @param dst Destination buffer
* @param incomming True if the packet is an incomming packet, otherweise 0
* @param packet packet data
* @param len length of packet data
* @param from Address from where the packet was received
* @return Number of bytes written
*/
int cw_format_pkt_hdr(char *dst, int incomming, uint8_t * packet, int len,
struct sockaddr *from)
#include "dot11.h"
int cw_format_dot11_fc_flags(char *dst, uint8_t *frame){
char *s = dst;
uint8_t f = frame[0];
s+=sprintf(s,"ToDS:%d ", f&1 ? 1:0);
s+=sprintf(s,"FromDS:%d ", f&2 ? 1:0);
s+=sprintf(s,"More Frgs:%d ", f&4 ? 1:0);
s+=sprintf(s,"Retry:%d ", f&8 ? 1:0);
s+=sprintf(s,"PwrMgmt:%d ", f&16 ? 1:0);
s+=sprintf(s,"More Dta:%d ", f&32 ? 1:0);
s+=sprintf(s,"Protec:%d ", f&64 ? 1:0);
s+=sprintf(s,"+HTC/:%d ", f&128 ? 1:0);
return s-dst;
}
int cw_format_dot11_rates(char *dst, const uint8_t *src, int len)
{
int i;
char * k="";
char *s=dst;
for(i=0; i<len; i++){
int rate = src[i] &0x7f;
s+=sprintf(s,"%s%0.1f",k,dot11_rate2float(rate));
k=", ";
}
return s-dst;
}
int cw_format_dot11_elem(char *dst, uint8_t id, const uint8_t *src, int len)
{
char *s = dst;
s += sprintf(s,"elem(id=%d) ",id);
switch(id){
case DOT11_ELEM_SSID:
s+=sprintf(s," ssid: %.*s",len,src);
break;
case DOT11_ELEM_SUPPORTED_RATES:
s+=sprintf(s," Supported Rates:");
s+=cw_format_dot11_rates(s,src,len);
break;
case DOT11_ELEM_EXTENDED_SUPPORTED_RATES:
s+=sprintf(s," Extended Supported Rates");
break;
case DOT11_ELEM_POWER_CAPABILITY:
s+=sprintf(s," Power Capability");
break;
case DOT11_ELEM_SUPPORTED_CHANNELS:
s+=sprintf(s," Supported Channels");
break;
case DOT11_ELEM_SUPPORTED_OPERATING_CLASSES:
s+=sprintf(s," Supported Operating Classes");
break;
case DOT11_ELEM_VENDOR_SPECIFIC:
s+=sprintf(s," Vendor Specific");
break;
default:
break;
}
s+=sprintf(s,", len=%d",len);
return s-dst;
}
int cw_format_dot11_hdr(char * dst, uint8_t * packet, int len)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
int preamble;
char *s;
int hlen, rid, wbid;
int frag_id,frag_offs;
int type = dot11_get_type_and_subtype(packet);
s = dst;
s=dst;
if (incomming){
if (cw_get_hdr_flag_f(packet)) {
s += sprintf(s, "Fragment from %s",
sock_addr2str_p(from,sock_buf));
} else {
s += sprintf(s, "From %s", sock_addr2str_p(from,sock_buf));
}
}
else{
if (cw_get_hdr_flag_f(packet)) {
s += sprintf(s, "Fragment to %s", sock_addr2str(from,sock_buf));
} else {
s += sprintf(s, "To %s", sock_addr2str(from,sock_buf));
}
}
s += sprintf(s, " l=%d: ", len);
preamble = cw_get_hdr_preamble(packet);
if (preamble == 01) {
s += sprintf(s, " (encrypted)");
return s - dst;
}
if (len < 4)
goto abort;
/*
if (cw_get_hdr_flag_f(packet)){
s+=sprintf(s," (fragmented)");
}
*/
hlen = cw_get_hdr_hlen(packet);
rid = cw_get_hdr_rid(packet);
wbid = cw_get_hdr_wbid(packet);
s += sprintf(s, " H:%d R:%02d W:%02d", hlen, rid, wbid);
s += sprintf(s, " Flgs:");
s += format_hdr_flags(s, packet);
if (len < 8)
goto abort;
frag_id = cw_get_hdr_fragid(packet);
frag_offs = cw_get_hdr_fragoffset(packet);
s += sprintf(s, " Frag/Offs:%d/%d", frag_id, frag_offs);
if (cw_get_hdr_flag_m(packet)) {
/* rmac is present, print the rmac */
int rmac_len = cw_get_hdr_rmac_len(packet);
int plen = rmac_len;
if (rmac_len + 8 > len)
plen = len - 8;
if (rmac_len > 10)
plen = 10;
s += sprintf(s, " R-MAC:");
s += format_mac(s, cw_get_hdr_rmac_data(packet), plen);
if (rmac_len > 10) {
s += sprintf(s, " ... (len=%d)", rmac_len);
}
}
if (cw_get_hdr_flag_w(packet)) {
/* print wireless specific info */
int ws_len = cw_get_hdr_ws_len(packet);
int plen = ws_len > 20 ? 20 : ws_len;
s += sprintf(s, " WS:");
s += format_hexu(s, cw_get_hdr_ws_data(packet), plen);
if (ws_len > 20) {
s += sprintf(s, " ... (len=%d)", ws_len);
}
}
return s - dst;
abort:
s += sprintf(s, " Incomplete...");
return s - dst;
s+=sprintf(s,"IEEE 802.11 - %s",dot11_get_frame_name(packet));
s+=sprintf(s," da:");
s+=format_mac(s,dot11_get_da(packet),6);
s+=sprintf(s," sa:");
s+=format_mac(s,dot11_get_sa(packet),6);
s+=sprintf(s," bssid:");
s+=format_mac(s,dot11_get_bssid(packet),6);
s+=sprintf(s," seq: %d\n",dot11_get_seq(packet));
s+=cw_format_dot11_fc_flags(s,packet);
s+=sprintf(s,"\nDuration: %d",dot11_get_duration(packet));
//
/* switch (type){
case DOT11_ASSOC_REQ:
s+=sprintf(s,"\n ssid: %.*s",dot11_assoc_req_get_ssid_len(packet),
dot11_assoc_req_get_ssid(packet)
);
break;
}*/
}

View File

@ -1,37 +0,0 @@
#include "capwap.h"
#include "msgset.h"
#include "val.h"
#include "log.h"
#include "dbg.h"
int cw_in_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
uint8_t * elem_data, int elem_len)
{
cw_Type_t * type;
type = (cw_Type_t*)handler->type;
char mkey[CW_CFG_MAX_KEY_LEN];
const char *key;
if (!type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT;
}
if (handler->mkkey != NULL){
handler->mkkey(handler->key,elem_data,elem_len, mkey);
key = mkey;
}
else{
key = handler->key;
}
/* cw_dbg(DBG_X, "READ: %s / %s",type->name,key);*/
type->read(params->cfg, key,elem_data,elem_len,handler->param);
return CAPWAP_RESULT_SUCCESS;
}

View File

@ -1,36 +0,0 @@
#include "capwap.h"
#include "msgset.h"
#include "val.h"
#include "log.h"
#include "dbg.h"
int cw_in_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
uint8_t * elem_data, int elem_len)
{
cw_dbg(DBG_X,"STRUCT KEY: %s",handler->key);
stop();
/* const char * key;
char tmpkey[CW_CFG_MAX_KEY_LEN];
if (handler->mkkey != NULL){
handler->mkkey(key,elem_data,elem_len, tmpkey);
key = tmpkey;
}
else{
key = handler->key;
}
//printf("CW_IN_GENERIC STRUCT: %s\n",key);
if (!handler->type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT;
}
cw_ktv_read_struct(params->cfg,handler->type,key,elem_data,elem_len);
*/
return CAPWAP_RESULT_SUCCESS;
}

View File

@ -10,12 +10,14 @@
int cw_in_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
uint8_t * elem_data, int elem_len)
{
stop();
/*
char key[CW_CFG_MAX_KEY_LEN];
int idx;
cw_dbg(DBG_X,"Fix cw_in_idx_generic_struct");
stop();
if (!handler->type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
@ -26,6 +28,6 @@ int cw_in_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHand
sprintf(key, handler->key, idx);
cw_ktv_read_struct(params->cfg,handler->type,key,elem_data+1,elem_len-1);
*/
return CAPWAP_RESULT_SUCCESS;
}

View File

@ -15,6 +15,25 @@ int cw_get_hdr_ws_len(uint8_t * th)
return *(th + 9 + cw_get_hdr_rmac_len(th));
}
/**
* Get length of wireless specific data for CAPWAP packet draft 7
* @param th Pointer to packet
* @return length of wireless specific data
*
* Call this function only if the W flag is set
*/
int cw_get_hdr_ws_len_7(uint8_t * th)
{
if (!cw_get_hdr_flag_m(th)){
return *(th + 9);
}
return *(th + 10 + cw_get_hdr_rmac_len(th));
}
/**
* Get pointer to wireless specific data
* @param th Pointer to packet
@ -117,7 +136,7 @@ int cw_set_hdr_rmac(uint8_t * th, bstr_t rmac)
hlen++;
}
cw_set_hdr_hlen(th, hlen);
return 1;
return rmac_len;
}

View File

@ -25,16 +25,17 @@ int cw_out_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemH
ob = dst;
e = ie->type;
for(i=0; e[i].name!=NULL; i++) {
int b;
sprintf(key,"%s/%s",handler->key,e[i].name);
cw_dbg(DBG_X,"Her is the Key: %s %s\n",key,e[i].name);
b = cw_cfg_base_exists_l(params->cfg_list,handler->key);
b = cw_cfg_base_exists(params->cfg_list[0],handler->key);
if (!b){
stop();
//stop();
continue;
}
start = params->msgset->header_len(handler);

View File

@ -1,48 +0,0 @@
#include "capwap.h"
#include "msgset.h"
#include "val.h"
#include "log.h"
#include "cw.h"
#include "dbg.h"
int cw_out_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
cw_dbg(DBG_X,"Key: %s",handler->key);
stop();
int start;
int len;
cw_Val_t search, *result;
if (!handler->type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
return 0;
}
search.key = (char*)handler->key;
result = mavl_get_first(params->cfg,&search);
if (result == NULL ){
if (params->elemdata->mand)
cw_log(LOG_ERR,"Can't put mandatory message element %s, no data available",handler->name);
return 0;
}
if (strncmp(result->key,handler->key, strlen(handler->key))!=0){
if (params->elemdata->mand)
cw_log(LOG_ERR,"Can't put mandatory message element %s, no data available",handler->name);
return 0;
}
start = params->msgset->header_len(handler);
len = cw_ktv_write_struct(params->cfg,
params->cfg,
handler->type,handler->key,dst+start);
return params->msgset->write_header(handler,dst,len);
}

View File

@ -7,7 +7,7 @@ int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHan
{
stop();
/*
char key[CW_CFG_MAX_KEY_LEN];
struct cw_Val * elem, search;
int i;
@ -26,7 +26,7 @@ int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHan
sprintf(key,handler->key,i);
search.key=key;
/*elem = mavl_get(params->conn->local_cfg, &search);*/
/ * elem = mavl_get(params->conn->local_cfg, &search); * /
elem = mavl_get_first(params->cfg,&search);
if(elem != NULL){
printf("Elem key: %s\n",elem->key);
@ -55,14 +55,16 @@ int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHan
/* radios = cw_ktv_get_byte(params->conn->local_cfg,"wtp-descriptor/max-radios",0);
/ * radios = cw_ktv_get_byte(params->conn->local_cfg,"wtp-descriptor/max-radios",0);
for(i=1;i<radios+1;i++){
l = cw_write_radio_element(handler,params,i,dst+len);
cw_dbg_elem(DBG_ELEM_OUT,params->conn,params->msgdata->type,handler,dst,l);
len+=l;
}
*/
* /
return mdst-dst;
*/ return 0;
}

View File

@ -42,106 +42,8 @@ int cw_out_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemH
cdst+=params->msgset->write_header(handler,cdst,l);
}
return cdst-dst;
return cdst-dst;*/
}
int cw_out_traverse0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst, int i, const char *current, const char * next,
int * stack)
{
char *sl;
int l;
char key[CW_CFG_MAX_KEY_LEN];
int len;
len = 0;
printf("Next: %s\n", next);
sl = strchr(next,'/');
if (sl==NULL){
cw_Val_t * result;
sprintf(key,"%s/%s",current,next);
result = cw_ktv_base_exists(params->cfg,key);
if (result != NULL){
int offset;
int i,l;
offset = params->msgset->header_len(handler);
printf("Yea! We can do it: %s\n",result->key);
for (i=0;i<stack[0];i++){
printf("I=%i\n",stack[i+1]);
}
l= cw_ktv_write_struct(params->cfg,params->cfg,
handler->type,key,dst+offset);
printf("Write struct len %i\n",l);
l=params->msgset->write_header(handler,dst,l);
printf("header wr len %d\n",l);
if (handler->patch){
handler->patch(dst+offset,stack);
}
return l;
}
return 0;
}
strcpy(key,current);
printf("current is %s\n", current);
if (key[0!=0])
strcat(key,"/");
l = sl - next;
strncat(key,next,l);
printf("Here we are %s\n",key);
cw_dbg_ktv_dump(params->cfg,DBG_INFO,"start"," ", "end" );
i=-1;
while(1){
char basekey[CW_CFG_MAX_KEY_LEN];
cw_Val_t * result;
i = cw_ktv_idx_get_next(params->cfg,key,i+1);
if (i==-1)
break;
sprintf(basekey,"%s.%d",key,i);
printf("Our basekey is %s\n",basekey);
result = cw_ktv_base_exists(params->cfg,basekey);
if (result == NULL){
continue;
}
stack[0]++;
stack[stack[0]]=i;
len += cw_out_traverse0(handler,params,dst+len,-1,basekey,next+l+1, stack);
printf("Len is now %d\n", len);
}
return len;
*/
return 0;
}
int cw_out_traverse(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
//char current[CW_CFG_MAX_KEY_LEN];
//int stack[10];
//stack[0]=0;
//current[0]=0;
stop();
return 0;
// return cw_out_traverse0(handler,params,dst,-1,current,handler->key, stack);
}

View File

@ -49,6 +49,8 @@ int cw_setup_dtls(struct cw_Conn *conn, cw_Cfg_t * cfg, const char *prefix,
sprintf(key, "%s/%s", prefix, "ssl-cipher");
conn->dtls_cipher = cw_cfg_get(cfg, key, default_cipher);
cw_dbg(DBG_DTLS,"Using cipher: %s",conn->dtls_cipher);
sprintf(key, "%s/%s", prefix, "ssl-psk");
conn->dtls_psk = (bstr16_t)cw_cfg_get(cfg, key, NULL);

188
src/cw/cw_type_array.c Normal file
View File

@ -0,0 +1,188 @@
/*
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 "cw.h"
#include "val.h"
#include "dbg.h"
static cw_Val_t *get(cw_Val_t * data, const uint8_t * src, int len)
{
data->type = &cw_type_byte;
data->val.byte = cw_get_byte(src);
return data;
}
static int put(const cw_Val_t *data, uint8_t * dst)
{
return cw_put_byte(dst, data->val.byte);
}
static const char * get_guardstr(int val, const cw_ValValRange_t * valrange)
{
if (valrange==NULL)
return NULL;
while(valrange->name!=NULL){
if(val>=valrange->min && val<=valrange->max)
return valrange->name;
valrange++;
}
return NULL;
}
static int to_str(const cw_Val_t *data, char *dst, int max_len)
{
if (data->valguard!=NULL){
const char * name;
name = get_guardstr(data->val.byte,data->valguard);
if (name != NULL){
return sprintf(dst,"%s",name);
}
}
/*if (max_len<3){
return 0;
}*/
return sprintf(dst, "%d", data->val.byte);
}
static int get_guardval(const char *str, const cw_ValValRange_t * valrange)
{
while(valrange->name!=NULL){
if(strcmp(str,valrange->name)==0)
return valrange->min;
valrange++;
}
return -1;
}
static cw_Val_t *from_str(cw_Val_t * data, const char *src)
{
data->type = &cw_type_byte;
if (data->valguard != NULL){
int rc;
rc = get_guardval(src,data->valguard);
if (rc != -1){
data->val.byte = rc;
return data;
}
}
data->val.byte = atoi(src);
return data;
}
static int len (cw_Val_t * data)
{
return sizeof(data->val.byte);
}
static void * data(cw_Val_t * data)
{
return &data->val.byte;
}
static const char * get_type_name(cw_Val_t *data)
{
if (data->valguard != NULL){
return CW_TYPE_STR->name;
}
return CW_TYPE_BYTE->name;
}
static int cast(cw_Val_t * data)
{
if (strcmp(data->type->name,CW_TYPE_BYTE->name)==0)
return 1;
if (strcmp(data->type->name,CW_TYPE_STR->name)==0){
char *src = data->val.ptr;
CW_TYPE_BYTE->from_str(data,src);
free(src);
return 1;
}
return 0;
}
static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param)
{
uint8_t n,i;
int l;
char skey[CW_CFG_MAX_KEY_LEN];
const struct cw_ValArrayDef * def = param;
const int (*fun)(cw_Cfg_t*,const char *k,const uint8_t *s,int len,const void *p,int *l) = def->get_count;
n = fun(cfg,key,src,len,param,&l);
for (i=0; i<n && l<len; i++){
sprintf(skey,"%s.%d",key,i);
// printf("SKEY: %s\n",skey);
l+=def->type->read(cfg,skey,src,len,def->param);
}
return l;
}
static int bwrite(cw_Cfg_t ** cfgs, const char *key, uint8_t *dst, const void * param)
{
int i,l;
char skey[CW_CFG_MAX_KEY_LEN];
const struct cw_ValArrayDef * def = param;
const int (*fun)(cw_Cfg_t**,const char *k, uint8_t *s,const void *p,int l) = def->put_count;
i=0,l=0;
do {
sprintf(skey,"%s.%d",key,i);
// printf("iSKEY %s\n",skey);
i++;
if (cw_cfg_get_l(cfgs,skey,NULL)==NULL){
break;
}
l+=def->type->write(cfgs,skey,dst,def->param);
}while(1);
// printf("LEN: %d (K: %s)\n",l,key);
fun(cfgs,key,dst,param,l);
return l;
}
const struct cw_Type cw_type_array = {
"Array", /* name */
NULL, /* del */
put, /* put */
get, /* get */
to_str, /* to_str */
from_str, /* from_str */
len, /* len */
data, /* data */
get_type_name, /* get_type_name */
cast,
bread,
bwrite
};

84
src/cw/cw_type_bits.c Normal file
View File

@ -0,0 +1,84 @@
#include "val.h"
#include "cfg.h"
#include "dbg.h"
static int get_len(const struct cw_ValBit *bits)
{
int i;
for (i=0;bits[i].key!=NULL;i++);
return bits[i].bit;
}
static int get_bit(const uint8_t * src,int pos, int len)
{
int b;
uint8_t m;
b = len-1-pos/8;
m = 1<<(pos%8);
return src[b]&m ? 1:0;
}
static void set_bit(uint8_t * dst,int pos, int len,int val)
{
int b;
uint8_t m;
cw_dbg(DBG_X,"set bit val %d",val);
if (!val)
return;
b = len-1-pos/8;
m = 1<<(pos%8);
dst[b]|=m;
}
static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param)
{
char skey[CW_CFG_MAX_KEY_LEN];
const struct cw_ValBit * bits=param;
int l,i;
l = get_len(bits);
for(i=0;bits[i].key!=NULL;i++){
sprintf(skey,"%s/%s",key,bits[i].key);
cw_cfg_set_bool(cfg,skey,get_bit(src,bits[i].bit,l));
}
return 1;
}
static int bwrite(cw_Cfg_t ** cfgs, const char *key, uint8_t *dst, const void * param)
{
int l,i;
char skey[CW_CFG_MAX_KEY_LEN];
const struct cw_ValBit * bits=param;
l = get_len(bits);
memset(dst,0,l);
for(i=0;bits[i].key!=NULL;i++){
uint8_t val;
int rc;
val=0;
sprintf(skey,"%s/%s",key,bits[i].key);
rc = CW_TYPE_BOOL->write(cfgs, skey, &val, NULL);
if (rc<0)
val=0;
cw_dbg(DBG_X,"%s (rc: %d)",skey,rc);
set_bit(dst,bits[i].bit,l,val);
}
return l;
}
const struct cw_Type cw_type_bits = {
"Bits", /* name */
NULL, /* del */
NULL, /* put */
NULL, /* get */
NULL, /* to_str */
NULL, /* from_str */
NULL, /* len */
NULL, /* data */
NULL, /* get_type_name */
NULL,
bread,
bwrite
};

View File

@ -38,14 +38,12 @@ static int read_struct(cw_Cfg_t * cfg,const cw_ValStruct_t * stru, const char *p
default:
l = stru[i].len;
if (pos+l > len){
l = len-pos;
l = pos<len ? len-pos : 0 ;
}
}
l=stru[i].type->read(cfg,key,data+pos,l,stru[i].valguard);
// printf("READ STRUCT (%d): %s: %s\n",pos,key,dbstr);
if (stru[i].len==-1){
@ -81,6 +79,7 @@ static int write_struct(cw_Cfg_t ** cfgs, const cw_ValStruct_t * stru, const ch
int pos, i;
const char * result;
int wrlen;
int rc;
cw_Val_t val;
memset(&val,0,sizeof(cw_Val_t));
@ -100,7 +99,10 @@ static int write_struct(cw_Cfg_t ** cfgs, const cw_ValStruct_t * stru, const ch
else
sprintf(key,"%s",pkey);
result = cw_cfg_get_l(cfgs,key,NULL);
// result = cw_cfg_get_l(cfgs,key,NULL);
rc = cw_cfg_base_exists_l(cfgs,key);
// cw_dbg(DBG_X,"Base? :'%s', %d\n",key,rc);
if(result) {
// char s[2048];
// result->type->to_str(result,s,2048);
@ -108,9 +110,15 @@ static int write_struct(cw_Cfg_t ** cfgs, const cw_ValStruct_t * stru, const ch
}
if (result == NULL){
cw_log(LOG_ERR,"Can't put %s, no value found, filling wth zeros.",key);
memset(dst+pos,0,stru[i].len);
if (!rc){
int l;
cw_log(LOG_ERR,"Can't put %s, no value found, filling with zeros.",key);
l = stru[i].len;
if (l==-1)
l = 0;
memset(dst+pos,0,l);
wrlen=l;
}
else{
struct cw_Type * type;

View File

@ -8,55 +8,38 @@
int cw_write_descriptor_subelem (uint8_t *dst, cw_Cfg_t ** cfg_list,
int subelem_id, const char * parent_key )
{
char key[256];
char key[CW_CFG_MAX_KEY_LEN];
uint32_t vendor;
//bstr16_t version;
bstr16_t version;
const char *vendor_s;
uint8_t *d;
/* d += cw_put_dword(d, bstrv_get_vendor_id(v));
d += cw_put_dword(d, (subelem_id << 16) | bstrv_len(v));
d += cw_put_data(d, bstrv_data(v), bstrv_len(v));
*/
sprintf (key, "%s/%s", parent_key, CW_SKEY_VENDOR);
vendor_s = cw_cfg_get_l (cfg_list, key, NULL);
if (vendor_s == NULL) {
cw_log (LOG_ERR, "Can't put subelem %s, no value of type Dword found.", key);
return 0;
cw_log (LOG_ERR, "Can't put subelem %s, no value found. Setting zero.", key);
vendor_s = "0";
}
vendor = atoi(vendor_s);
sprintf (key, "%s/%s", parent_key, CW_SKEY_VERSION);
cw_Val_t * val = cw_cfg_get_val_l(cfg_list, key, CW_TYPE_BSTR16);
//version = cw_cfg_get_bstr16 (cfg, key, NULL);
if (val == NULL) {
cw_log (LOG_ERR, "Can't put subelem %s, no value of type Bstr16 found.", key);
return 0;
version = cw_cfg_get_bstr16_l(cfg_list,key,NULL);
if (version == NULL) {
cw_log (LOG_ERR, "Can't put subelem %s, no value found. Setting zero.", key);
version = bstr16_create_from_str("0.0.0.0");
}
d = dst;
/* put vendor */
d += cw_put_dword(d, vendor); //->type->put (vendor, d);
d += cw_put_dword(d, vendor);
/* put version */
d += cw_put_dword (d, (subelem_id << 16) | val->type->len(val));
// d += cw_put_bstr16(d, version);
d += val->type->put(val,d);
d += cw_put_dword (d, (subelem_id << 16) | bstr16_len(version));
d += cw_put_bstr16(d, version);
cw_val_destroy(val);
// free(version);
free(version);
return d-dst;
}

View File

@ -31,27 +31,121 @@
#include "format.h"
#include "ansi_colors.h"
#include "dot11.h"
/**
*@addtogroup DBG
*@{
*/
/*
* @defgroup DebugFunctions Debug Functions
* @{
*/
uint32_t cw_dbg_opt_display = DBG_DISP_COLORS;
/**
* Current debug level
* Contains all debuglevels currently set
*/
uint32_t cw_dbg_opt_level = 0;
static struct mavl * cw_dbg_opt_level = NULL;
static int dbg_cmp(const void *a, const void*b)
{
return (*((int*)a)-*((int*)b));
}
struct cw_DbgStr {
int level;
const char *str;
const char ** str_list;
const char *descr;
};
static const char * dbg_level_msg[] = {
"msg_in", "msg_out", NULL
};
static const char * dbg_level_pkt[] = {
"pkt_in", "pkt_out", NULL
};
static const char * dbg_level_elem[]={
"elem_in","elem_out",NULL
};
static const char * dbg_level_elem_detail[] = {
"elem_detail_in", "elem_detail_out", NULL
};
static const char * dbg_level_elem_dmp[] = {
"elem_dmp_in", "elem_dmp_out", NULL
};
static const char * dbg_level_elem_all[] = {
"elem", "elem_dmp", "elem_detail",NULL
};
static const char * dbg_level_std[] = {
"msg","elem","msg_err", "elem_err", "pkt_err", "rfc", "warn", "state", "info", NULL
};
/**
* Debug strings
*/
struct cw_DbgStr cw_dbg_strings[] = {
{ 0, "std", dbg_level_std, "some useful standard options to debug CAPWAP"},
{ 0, "msg", dbg_level_msg, "messages headers" },
{ 0, "pkt", dbg_level_pkt, "packet headers" },
{ 0, "elem", dbg_level_elem, "message elemenst" },
{ 0, "elem_detail", dbg_level_elem_detail, "details for message elements"},
{ 0, "elem_dmp", dbg_level_elem_dmp,"hexdump element"},
{ 0, "elem_all", dbg_level_elem_all,"all possible elem options"},
{ DBG_WARN, "warn", NULL, "warnings" },
{ DBG_ELEM_ERR, "elem_err", NULL, "errors in elements" },
{ DBG_PKT_ERR, "pkt_err", NULL, "packets with errors which are usually would be discard" },
{ DBG_MSG_ERR, "msg_err", NULL, "message errors"},
{ DBG_RFC, "rfc", NULL, "errors related to RFC5415/RFC5416 viloations" },
{ DBG_CFG_UPDATES, "cfg_updates",NULL, "show configuration aupdates" },
{ DBG_MOD, "mod",NULL, "module related"},
{ DBG_MOD_DETAIL, "mod_detail",NULL, "module related details"},
{ DBG_STATE, "state",NULL, "CAWPAP states" },
{ DBG_MSG_COMPOSE, "msg_compose",NULL,"message composing details" },
{ DBG_INFO, "info", NULL, "several infos are displayed" },
{ DBG_PKT_IN, "pkt_in",NULL, "headers of incomming packets." },
{ DBG_PKT_OUT, "pkt_out",NULL, "headers out outgoing packets." },
{ DBG_PKT_DMP_IN, "pkt_dmp_in",NULL, "hex-dump incomming packets" },
{ DBG_PKT_DMP_OUT, "pkt_dmp_out",NULL, "hex-dump outgoing packets" },
{ DBG_MSG_IN, "msg_in", NULL, "incomming messages" },
{ DBG_MSG_OUT, "msg_out", NULL, "outgoing messages" },
{ DBG_MSG_DMP_IN, "msg_dmp_in", NULL, "hex-dump incomming messages" },
{ DBG_MSG_DMP_OUT, "msg_dmp_out", NULL,"hex-dump of outgong messages" },
{ DBG_ELEM_IN, "elem_in", NULL, "elements of incomming messages"},
{ DBG_ELEM_OUT, "elem_out", NULL, "elements of outgoing messages"},
{ DBG_ELEM_DETAIL_IN, "elem_detail_in", NULL, "details of incomming message elements" },
{ DBG_ELEM_DETAIL_OUT, "elem_detail_out",NULL, "details of outgoing message elememnts" },
{ DBG_ELEM_DMP_IN, "elem_dmp_in", NULL, "hex-dump of incoming elements"},
{ DBG_ELEM_DMP_OUT, "elem_dmp_out", NULL, "hex-dump of outgoing elements"},
{ DBG_ELEM_VNDR, "elem_vndr", NULL, "expand vendor specific payloads"},
{ DBG_DTLS, "dtls",NULL, "DTLS related stuff"},
{ DBG_DTLS_BIO, "dtls_bio",NULL, "DTLS BIO releated" },
{ DBG_DTLS_BIO_DMP, "dtls_bio_dmp",NULL, "hex-dump dtls packets" },
{ DBG_DTLS_DETAIL, "dtls_detail",NULL, "DTLS detailed messages"},
{ DBG_X, "x", NULL, "only for developers" },
{ DBG_ALL, "all", NULL, "all debug levels at once"},
{ 0, NULL }
};
@ -90,7 +184,8 @@ static struct cw_StrListElem theme0[] = {
{DBG_RFC, ANSI_BRED},
{DBG_X, "\x1b[31m"},
{DBG_WARN, ANSI_CYAN},
{DBG_MOD, ANSI_WHITE},
{DBG_MOD_DETAIL, ANSI_WHITE},
{DBG_MOD, ANSI_BBLACK ANSI_BOLD },
// {DBG_CFG_DMP, ANSI_BCYAN },
{DBG_CFG_UPDATES,ANSI_GREEN},
@ -102,7 +197,6 @@ static struct cw_StrListElem * color_on = theme0;
struct cw_StrListElem color_ontext[] = {
/* {DBG_ELEM_DMP, "\x1b[37m"},*/
{DBG_ELEM_DMP_OUT, ANSI_BBLACK ANSI_ITALIC},
{DBG_ELEM_DMP_IN, ANSI_BBLACK},
@ -117,23 +211,24 @@ static struct cw_StrListElem color_off[] = {
*/
static struct cw_StrListElem prefix[] = {
{DBG_INFO, "Info -"},
{DBG_PKT_IN, "Pkt In -"},
{DBG_PKT_OUT, "Pkt Out -"},
{DBG_INFO, "Info - "},
{DBG_PKT_IN, "Pkt In - "},
{DBG_PKT_OUT, "Pkt Out - "},
{DBG_MSG_IN, "Msg In - "},
{DBG_MSG_OUT, "Msg Out - "},
{DBG_ELEM_IN, " Msg Element -"},
{DBG_ELEM_OUT, " Msg Element -"},
{DBG_ELEM_IN, " Msg Element - "},
{DBG_ELEM_OUT, " Msg Element - "},
{DBG_MSG_ERR, " Msg Error -"},
{DBG_PKT_ERR, " Pkt Error -"},
{DBG_ELEM_ERR, " Elem Error -"},
{DBG_RFC, " RFC -"},
{DBG_MSG_ERR, " Msg Error - "},
{DBG_PKT_ERR, " Pkt Error - "},
{DBG_ELEM_ERR, " Elem Error - "},
{DBG_RFC, " RFC - "},
{DBG_DTLS, "DTLS - "},
{DBG_DTLS_DETAIL, "DTLS - "},
{DBG_WARN, " Warning - "},
{DBG_WARN, "Warning - "},
{DBG_MOD, "Mod - "},
{DBG_MOD_DETAIL, "Mod - "},
{DBG_STATE, "STATEMACHINE - "},
{DBG_CFG_UPDATES, "Cfg - "},
@ -180,16 +275,36 @@ const char *get_dbg_color_ontext(int level)
* @param level Level to check
* @return 0 if leveln is not set, otherwise level is set
*/
int cw_dbg_is_level(int level)
{
if (level > 1 && (level &1))
return 1;
if (cw_dbg_opt_level == NULL)
return 0;
/* if (level >= DBG_ALL ){
return 1;
}*/
return (cw_dbg_opt_level & (level));
return mavl_get(cw_dbg_opt_level,&level) == NULL ? 0:1;
}
/**
* Set debug level
* @param level debug level to set, allowed values are enumberated in #cw_dbg_levels structure.
* @param on 1: turns the specified debug level on, 0: turns the specified debug level off.
*
* To check if a specific debug level is set, call #cw_dbg_is_level.
*/
void cw_dbg_set_level (int level, int on)
{
int exists;
if (cw_dbg_opt_level == NULL){
cw_dbg_opt_level = mavl_create(dbg_cmp,NULL,sizeof(int));
if (cw_dbg_opt_level == NULL)
return;
}
if (on){
mavl_insert(cw_dbg_opt_level,&level,&exists);
}
else
mavl_del(cw_dbg_opt_level,&level);
}
@ -209,63 +324,37 @@ static void cw_dbg_vlog_line(struct cw_LogWriter * writer,
}
writer->write(LOG_DEBUG,fbuf,args,writer);
}
/**
* Put a list of missing mandatory message elements to debug output
*/
void cw_dbg_missing_mand(int level, struct cw_Conn *conn, int ** ml, int n,
int * a)
{
/*
// if (!cw_dbg_is_level(DBG_MSG_ERR) || n == 0)
// return;
*/
char buffer[2000];
/* char *p = buffer; */
int i;
/* char *delim = "";*/
if (!cw_dbg_is_level(level) || n == 0)
return;
/*
// TODO XXXX
*/
for (i = 0; i < n; i++) {
/* p += sprintf(p, "%s", delim);
delim = ", ";
p += sprintf(p, "%s", cw_strelemp(conn->actions, ml[i]->elem_id));
*/
}
cw_dbg(level, "Missing mandatory elements: [%s]", buffer);
}
/**
* Display a packet on for debugger
* Display a packet on debugger
*/
void cw_dbg_pkt(int level, struct cw_Conn *conn, uint8_t * packet, int len,
struct sockaddr *from)
{
/* int hlen;*/
char buf[1024];
int (*fmt_pkt_hdr)(char *dst, int incomming, uint8_t * packet, int len,
struct sockaddr *from);
fmt_pkt_hdr = NULL;
if (conn){
if (conn->msgset)
fmt_pkt_hdr = conn->msgset->format_pkt_hdr;
}
if (fmt_pkt_hdr==NULL){
fmt_pkt_hdr = cw_format_pkt_hdr;
}
if (!cw_dbg_is_level(level))
return;
if (level == DBG_PKT_IN)
cw_format_pkt_hdr(buf, 1, packet, len, from);
fmt_pkt_hdr(buf, 1, packet, len, from);
else
cw_format_pkt_hdr(buf, 0, packet, len, from);
fmt_pkt_hdr(buf, 0, packet, len, from);
/* hlen = cw_get_hdr_msg_offset(packet);*/
@ -412,7 +501,7 @@ void cw_dbg_elem(int level, struct cw_Conn *conn, int msg,
cw_dbg(level,"%s %d (%s), len=%d ",vendorname,handler->id,
handler->name,len);
if (cw_dbg_is_level(DBG_ELEM_DMP)) {
if (cw_dbg_is_level(DBG_ELEM_DMP_OUT) || cw_dbg_is_level(DBG_ELEM_DMP_IN)) {
if (level == DBG_ELEM_OUT)
cw_dbg_dmp(DBG_ELEM_DMP_OUT,msgbuf,len,"");
else
@ -427,36 +516,132 @@ void cw_dbg_elem(int level, struct cw_Conn *conn, int msg,
/*
void dbg_istore_dmp(mbag_t s)
int cw_dbg_set_level_from_str0(const char *level,int on)
{
DEFINE_AVLITER(it,s);
avliter_foreach(&it) {
int i,all;
all = strcmp(level,"all")==0 ? 1: 0;
for(i=0; cw_dbg_strings[i].str != NULL; i++){
if (strcmp(cw_dbg_strings[i].str,level)==0 || all){
if (cw_dbg_strings[i].str_list==NULL)
cw_dbg_set_level(cw_dbg_strings[i].level,on);
else {
const char **l;
for (l=cw_dbg_strings[i].str_list; *l; l++){
if (!cw_dbg_set_level_from_str0(*l,on)){
stop();
}
}
}
if (!all)
return 1;
}
}
if (all)
return 1;
/* blevel = cw_strlist_get_id(cw_dbg_strings, slevel);
if (blevel==-1)
return 0;
*/
// cw_dbg_set_level(blevel,on);
// return 1;
return 0;
}
mbag_item_t *i = avliter_get(&it);
char buffer[1000];
int cw_dbg_set_level_from_str(const char *level)
{
int on;
const char *slevel;
switch(*level){
case '-':
case '!':
case '~':
on =0;
slevel=level+1;
break;
case '+':
slevel=level+1;
on=1;
break;
default:
slevel=level;
on=1;
}
return cw_dbg_set_level_from_str0(slevel,on);
}
struct cw_str * strings = cw_item_strings;
const char * in = cw_strlist_get_str(strings,i->id);
cw_format_item(buffer,i);
printf("Item ID %d-%s: %s\n",i->id,in,buffer);
void cw_dbg_print_help(FILE *out, const char * prefix)
{
struct cw_DbgStr *s;
for (s=cw_dbg_strings; s->str != NULL; s++){
const char * descr = s->descr!=NULL ? s->descr : "";
fprintf(out,"%s%s: %s",prefix,s->str,descr);
if (s->str_list != NULL){
const char **l;
char *sp="";
fprintf(out," (");
for(l = s->str_list; *l!=NULL; l++){
fprintf(out,"%s%s",sp,*l);
sp=" ";
}
fprintf(out,")");
}
fprintf(out,"\n");
}
}
void cw_dbg_dot11_elems(const uint8_t *src,int len)
{
uint8_t id,l;
int p;
char str[1024];
for(p=0; p<len; p+=l+2){
if (len-p<3){
cw_dbg(DBG_X,"Error in dot11 element");
return;
}
id=src[p];
l=src[p+1];
cw_format_dot11_elem(str,id,src+p+2,l);
cw_dbg_dmp(DBG_X,src+p+2,l,"");
cw_dbg(DBG_X,str);
}
}
*/
void cw_dbg_dot11_frame(uint8_t * frame,int len)
{
char hdr[1024];
cw_format_dot11_hdr(hdr, frame, len);
cw_dbg(DBG_X,"%s",hdr);
int type =dot11_get_type_and_subtype(frame);
switch (type){
case DOT11_ASSOC_REQ:
cw_dbg_dot11_elems(frame+28,len-28);
break;
case DOT11_ASSOC_RESP:
cw_dbg(DBG_X," Capapility info: %04X",dot11_assoc_resp_get_cap(frame));
cw_dbg(DBG_X," Status CodeCapapility info: %04X",dot11_assoc_resp_get_status_code(frame));
cw_dbg(DBG_X," Assoc ID: %04X",dot11_assoc_resp_get_assoc_id(frame));
cw_dbg_dot11_elems((frame+DOT11_BODY_POS+DOT11_ASSOC_RESP_BODY_LEN),
len-DOT11_BODY_POS-DOT11_ASSOC_RESP_BODY_LEN);
break;
}
}
/**@}*/
/**@}*/

View File

@ -39,7 +39,7 @@
/**
*@addtogroup LOGDBG
*@addtogroup DBG
*@{
*/
@ -48,89 +48,91 @@
*/
enum cw_dbg_levels{
/** Show headers of incomming/outgoing CAPWAP packets */
DBG_PKT_IN = (1<<0),
DBG_PKT_OUT = (1<<1),
DBG_PKT_IN = 1,
DBG_PKT_OUT,
/** Hex-dump incomming/outgoing CAPWAP packets */
DBG_PKT_DMP_IN = (1<<3),
DBG_PKT_DMP_OUT = (1<<4),
DBG_PKT_DMP_IN,
DBG_PKT_DMP_OUT,
/** Incomming CAPWAP packets with errors, wich would
usually silently discarded */
DBG_PKT_ERR = (1<<5),
DBG_PKT_ERR,
/** Display incomming/outgoing CAPWAP/LWAPP messages */
DBG_MSG_IN = (1<<6),
DBG_MSG_OUT = (1<<7),
DBG_MSG_IN,
DBG_MSG_OUT,
/** Show hex-dump of messages */
DBG_MSG_DMP_IN = (1<<8),
DBG_MSG_DMP_OUT = (1<<9),
DBG_MSG_DMP_IN,
DBG_MSG_DMP_OUT,
/** Message errors */
DBG_MSG_ERR = (1<<10),
DBG_MSG_ERR,
/** Show message elements in incomming/outgoing messages */
DBG_ELEM_IN = (1<<11),
DBG_ELEM_OUT = (1<<12),
DBG_ELEM_IN,
DBG_ELEM_OUT,
/** Show message element details */
DBG_ELEM_DETAIL_IN = (1<<13),
DBG_ELEM_DETAIL_OUT = (1<<14),
DBG_ELEM_DETAIL_IN,
DBG_ELEM_DETAIL_OUT,
/** Error in msg elements */
DBG_ELEM_ERR = (1<<15),
/** hex dump elements */
DBG_ELEM_DMP = (1<<16),
DBG_ELEM_ERR,
/** General infos, like CAPWAP state */
DBG_INFO = (1<<17),
DBG_INFO,
/** Misc. warnings */
DBG_WARN = (1<<18),
DBG_WARN,
/** RFC related */
DBG_RFC = (1<<19),
DBG_RFC,
/** DTLS related messages */
DBG_DTLS = (1<<20),
DBG_DTLS,
/** DTLS BIOs in/out */
DBG_DTLS_BIO = (1<<21),
DBG_DTLS_BIO,
/** Dump DTLS BIO i/o */
DBG_DTLS_BIO_DMP = (1<<22),
DBG_DTLS_BIO_DMP,
/** Show DTLS Details */
DBG_DTLS_DETAIL = (1<<23),
DBG_DTLS_DETAIL,
// DBG_CFG_DMP = (1<<20),
// DBG_CFG_DMP,
// DBG_CFG_SET = (1<<21),
// DBG_CFG_SET,
/** Debug Mods */
DBG_MOD = (1<<24),
DBG_MOD,
/**Debug State machine */
DBG_STATE = (1<<25),
DBG_STATE,
/** Infos about nessage composing */
DBG_MSG_COMPOSE,
/** Debug Configuration updates */
DBG_CFG_UPDATES,
/** Debug Vendor elements */
DBG_ELEM_VNDR,
DBG_MSG_COMPOSE = (1<<26),
DBG_X,
DBG_CFG_UPDATES = (1<<27),
DBG_MOD_DETAIL,
DBG_ELEM_VNDR = (1<<28),
DBG_X = (1<<30),
DBG_ALL = (0x7fffffff),
DBG_ELEM_DMP_IN = 7,
DBG_ELEM_DMP_OUT = 9,
DBG_ALL,
/** Hexdump incoming msg elemenets */
DBG_ELEM_DMP_IN,
/** Hexdump outgoing msg elemenst */
DBG_ELEM_DMP_OUT,
};
@ -189,8 +191,8 @@ void cw_dbg_dmp(int level, const uint8_t * data, int len, const char *format, ..
extern uint32_t cw_dbg_opt_display;
extern uint32_t cw_dbg_opt_level;
extern struct cw_StrListElem cw_dbg_strings[];
//extern uint32_t cw_dbg_opt_level;
//extern struct cw_StrListElem cw_dbg_strings[];
/*
#define cw_dbg cw_dbg_colored
@ -217,8 +219,6 @@ void cw_dbg_msg(int level,struct cw_Conn *conn, uint8_t * packet, int len,struct
char * cw_dbg_mkdmp(const uint8_t * data, int len);
//void cw_dbg_version_subelem(int level, const char *context, int subtype,
// uint32_t vendor_id, const uint8_t * vstr, int len);
void cw_dbg_ktv_dump(mavl_t ktv, uint32_t dbglevel,
const char *header, const char *prefix, const char *footer );
/**
* Set debug level
@ -240,6 +240,10 @@ void cw_dbg_ktv_dump(mavl_t ktv, uint32_t dbglevel,
*/
int cw_dbg_is_level(int level);
void cw_dbg_print_help(FILE *out, const char * prefix);
void cw_dbg_dot11_frame(uint8_t * frame,int len);
#define stop() printf("STOP IN %s:%d - %s\n", __FILE__, __LINE__, __FUNCTION__); exit(1)

View File

@ -1,136 +0,0 @@
/*
This file is part of actube.
actube 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/>.
*/
/**
*@file
*@brief
*/
#include "dbg.h"
/**
*@addtogroup DbgOptions
*@{
*/
/**
* Debug strings
*/
struct cw_StrListElem cw_dbg_strings[] = {
{ DBG_INFO, "info", },
{ DBG_PKT_IN, "pkt_in" },
{ DBG_PKT_OUT, "pkt_out" },
{ DBG_PKT_ERR, "pkt_err" },
{ DBG_PKT_DMP_IN, "pkt_dmp_in" },
{ DBG_PKT_DMP_OUT, "pkt_dmp_out" },
{ DBG_MSG_IN, "msg_in" },
{ DBG_MSG_OUT, "msg_out" },
{ DBG_MSG_DMP_IN, "msg_dmp_in" },
{ DBG_MSG_DMP_OUT, "msg_dmp_out" },
{ DBG_MSG_ERR, "msg_err"},
{ DBG_RFC, "rfc", },
{ DBG_ELEM_IN, "elem_in"},
{ DBG_ELEM_OUT, "elem_out"},
{ DBG_ELEM_DMP, "elem_dmp"},
{ DBG_ELEM_ERR, "elem_err" },
{ DBG_ELEM_DETAIL_IN, "elem_detail_in" },
{ DBG_ELEM_DETAIL_OUT, "elem_detail_out" },
{ DBG_ELEM_VNDR, "elem_vndr"},
{ DBG_DTLS, "dtls" },
{ DBG_DTLS_BIO, "dtls_bio" },
{ DBG_DTLS_BIO_DMP, "dtls_bio_dmp"},
{ DBG_DTLS_DETAIL, "dtls_detail"},
{ DBG_CFG_UPDATES, "cfg_updates" },
// {DBG_CFG_DMP, "cfg_dmp" },
{ DBG_WARN, "warn" },
{ DBG_MOD, "mod"},
{ DBG_STATE, "state" },
{ DBG_MSG_COMPOSE, "msg_compose" },
{ (DBG_MSG_IN | DBG_MSG_OUT), "msg" },
{ (DBG_PKT_IN | DBG_PKT_OUT), "pkt" },
{ (DBG_ELEM_IN | DBG_ELEM_OUT), "elem" },
{ (DBG_ELEM_DETAIL_IN | DBG_ELEM_DETAIL_OUT), "elem_detail" },
{ (DBG_ELEM_IN | DBG_ELEM_OUT | DBG_ELEM_DMP | DBG_ELEM_DETAIL_IN | DBG_ELEM_DETAIL_OUT), "elem_all" },
{ ( DBG_MSG_IN | DBG_MSG_OUT |
DBG_ELEM_IN | DBG_ELEM_OUT |
DBG_MSG_ERR | DBG_ELEM_ERR |
DBG_PKT_ERR | DBG_RFC | DBG_WARN
| DBG_STATE), "std" },
{ DBG_ALL, "all"},
{ CW_STR_STOP, NULL }
};
/**
*@}
*/
/*
struct cw_dbg_cfgstrs cw_dbg_cfgstrs[] = {
{"info",DBG_CW_INFO},
{"msg",DBG_MSG},
{"elem",DBG_ELEM},
{"elem_dmp",DBG_ELEM_DMP},
{"rfc",DBG_CW_RFC},
{"pkt_in",DBG_CW_PKT_IN},
{"pkt_out",DBG_CW_PKT_OUT},
{"pkt_dtl",DBG_CW_PKT_DTL},
{"pkt",(DBG_CW_PKT_IN | DBG_CW_PKT_OUT)},
{"pkt_dmp",DBG_CW_PKT_DMP},
{"pkt_err",DBG_CW_PKT_ERR},
{"msg_err",DBG_MSG_ERR},
{"img_dtl",DBG_CW_IMG_DTL},
{"elem_err",DBG_ELEM_ERR},
{"dtls",DBG_DTLS},
{"dtls_dietail",DBG_DTLS_DETAIL},
{"dtls_bio",DBG_DTLS_BIO},
{"dtls_bio_dmp",DBG_DTLS_BIO_DMP},
{"all",DBG_ALL},
{"err",DBG_ERR},
{0,0}
};
*/

View File

@ -38,3 +38,28 @@ const char * dot11_type_strings[]=
"Probe Req",
"Probe Resp"
};
struct dot11_name{
uint8_t val;
const char * str;
};
struct cw_StrListElem dot11_names[]={
{DOT11_ASSOC_REQ, "Assoc Req"},
{DOT11_ASSOC_RESP, "Assoc Resp"},
{DOT11_REASSOC_REQ, "Reassoc Req"},
{DOT11_REASSOC_RESP, "Reassoc Resp"},
{DOT11_PROBE_REQ, "Probe Req"},
{DOT11_PROBE_RESP, "Probe Resp"},
{DOT11_TIMING_ADV, "Timing Adv"},
{DOT11_MGM_RES111, "MGMRES111"},
{DOT11_BEACON, "Beacon"},
{CW_STR_STOP,"Unknown"},
};
int dot11_init_assoc_resp(uint8_t * dst)
{
dot11_set_type_and_subtype(dst,DOT11_ASSOC_RESP);
}

View File

@ -20,6 +20,8 @@
#include <endian.h>
#endif
#include "strlist.h"
#include "bstr.h"
/**
* @defgroup DOT11_FRAME_TYPES Frame Types
@ -47,17 +49,17 @@
*
* @{
*/
#define DOT11_FC_ASSOC_REQ dot11_fc_mgm(0b0000)
#define DOT11_FC_ASSOC_RESP dot11_fc_mgm(0b0001)
#define DOT11_FC_REASSOC_REQ dot11_fc_mgm(0b0010)
#define DOT11_FC_REASSOC_RESP dot11_fc_mgm(0b0011)
#define DOT11_FC_PROBE_REQ dot11_fc_mgm(0b0100)
#define DOT11_FC_PROBE_RESP dot11_fc_mgm(0b0101)
#define DOT11_FC_TIMING_ADV dot11_fc_mgm(0b0110)
#define DOT11_FC_MGM_RES111 dot11_fc_mgm(0b0111)
#define DOT11_FC_BEACON dot11_fc_mgm(0b1000)
#define DOT11_ASSOC_REQ dot11_fc_mgm(0b0000)
#define DOT11_ASSOC_RESP dot11_fc_mgm(0b0001)
#define DOT11_REASSOC_REQ dot11_fc_mgm(0b0010)
#define DOT11_REASSOC_RESP dot11_fc_mgm(0b0011)
#define DOT11_PROBE_REQ dot11_fc_mgm(0b0100)
#define DOT11_PROBE_RESP dot11_fc_mgm(0b0101)
#define DOT11_TIMING_ADV dot11_fc_mgm(0b0110)
#define DOT11_MGM_RES111 dot11_fc_mgm(0b0111)
#define DOT11_BEACON dot11_fc_mgm(0b1000)
#define DOT11_FC_DATA dot11_fc_dta(0b0000)
#define DOT11_DATA dot11_fc_dta(0b0000)
/**
* @}
@ -109,11 +111,19 @@
* @defgroup DOT11_ELEMS
* @{
*/
#define DOT11_ELEM_SSID 0
#define DOT11_ELEM_SUPPORTED_RATES 1
#define DOT11_ELEM_FH_PARAM_SET 2
#define DOT11_ELEM_DSSS_PARAM_SET 3
#define DOT11_ELEM_CF_PARAM_SET 4
#define DOT11_ELEM_SSID 0
#define DOT11_ELEM_SUPPORTED_RATES 1
#define DOT11_ELEM_FH_PARAM_SET 2
#define DOT11_ELEM_DSSS_PARAM_SET 3
#define DOT11_ELEM_CF_PARAM_SET 4
#define DOT11_ELEM_POWER_CAPABILITY 33
#define DOT11_ELEM_SUPPORTED_CHANNELS 36
#define DOT11_ELEM_EXTENDED_SUPPORTED_RATES 50
#define DOT11_ELEM_AP_CHANNEL_REPORT 51
#define DOT11_ELEM_SUPPORTED_OPERATING_CLASSES 59
#define DOT11_ELEM_VENDOR_SPECIFIC 221
/**
* @}
*/
@ -125,27 +135,32 @@ extern const uint8_t dot11_tab_br[256];
#define dot11_get_byte(ptr) (*(ptr))
#define dot11_put_byte(ptr,b) (*(ptr) = b)
#define dot11_put_byte(ptr,b) (*(ptr) = b,1)
#define dot11_put_word(dst,v) ((*((uint16_t*)(dst))=htobe16(v)),2)
#define dot11_put_dword(dst,v) ((*((uint16_t*)(dst))=htobe16(v)),4)
#define dot11_put_dword(dst,v) ((*((uint32_t*)(dst))=htobe32(v)),4)
#define dot11_put_qword(dst,v) ((*((uint64_t*)(dst))=htobe64(v)),8)
#define dot11_set_byte(ptr,b) (*(ptr) = b)
#define dot11_set_word(dst,v) ((*((uint16_t*)(dst))=htobe16(v)))
#define dot11_set_dword(dst,v) ((*((uint32_t*)(dst))=htobe32(v)))
#define dot11_set_qword(dst,v) ((*((uint64_t*)(dst))=htobe64(v)))
#define dot11_set_byte(ptr,b) (*(ptr) = b)
uint16_t dot11_get_word(uint8_t * ptr);
#define dot11_get_version(frame) ((frame[1])&0x03)
#define dot11_get_type(frame) (((frame[1])&0x0c) >> 2)
#define dot11_get_subtype(frame) (((frame[1])&0xf0) >> 4)
/**
* Get Frame Control field
* @param frame
* @return Frame Control field
*/
#define dot11_get_fc(frame) dot11_get_word(frame)
#define dot11_get_version(frame) ( (frame)[1] & 0x03)
#define dot11_get_type(frame) ( ((frame)[1] & 0x0c) >> 2)
#define dot11_get_subtype(frame) ( (frame)[1] >> 4 )
#define dot11_get_type_and_subtype(frame) ((frame)[1])
#define dot11_set_type_and_subtype(frame,val) ((frame)[1]=val)
#define dot11_get_duration(frame) dot11_get_word(frame+2)
void dot11_get_address(uint8_t * dst, uint8_t * frame);
@ -201,6 +216,9 @@ void dot11_timer_set(uint64_t val);
#define dot11_put_address(dst,addr) (memcpy(dst,addr,6),6)
#define dot11_put_sequence_control(dst,v) (dot11_put_word(dst,v))
#define dot11_put_capability(dst,v) dot11_put_word(dst,v)
int dot11_put_ssid(uint8_t *dst,uint8_t * ssid,int len);
@ -221,7 +239,9 @@ int dot11_put_ssid(uint8_t *dst,uint8_t * ssid,int len);
*/
#define dot11_rate2float(rate) (((float)(rate))/2.0)
int dot11_put_supported_rates(uint8_t *dst, float *basic, float *rates);
int dot11_put_supported_rates(uint8_t *dst, bstr_t src);
// float *basic, float *rates);
int dot11_put_dsss_param_set(uint8_t *dst,int ch);
@ -235,7 +255,81 @@ extern uint8_t dot11_broadcast_address[6];
extern struct cw_StrListElem dot11_names[];
#define dot11_get_frame_name(data) cw_strlist_get_str(dot11_names,(data)[1])
/**
* Get Frame Control field
* @param frame uint8_t pointer to the frame
* @return uint16_t Frame Control field
*/
#define dot11_get_fc(frame) dot11_get_word(frame)
/** Get duration/aid field
* @param frame uint8_t pointer to frame */
#define dot11_get_duration(frame) dot11_get_word(frame+2)
#define dot11_get_da(frame) ((frame)+4)
#define dot11_get_sa(frame) ((frame)+10)
#define dot11_get_bssid(frame) ((frame)+16)
#define dot11_get_seq(frame) dot11_get_word((frame)+22)
#define dot11_get_body(frame) ((frame)+24)
#define DOT11_BODY_POS 24
#define dot11_set_duration(frame,d) dot11_set_word(frame+2,d)
#define dot11_set_seq(frame,s) dot11_set_word((frame)+22,s)
#define DOT11_ASSOC_RESP_BODY_LEN 6
#define dot11_assoc_req_get_cap(frame) \
dot11_get_word((frame)+24)
#define dot11_assoc_req_get_listen_interval(frame) \
dot11_get_word((frame)+24+2)
/*
#define dot11_assoc_req_get_ssid_len(frame)\
((frame)[29])
#define dot11_assoc_req_get_ssid(frame)\
(frame+30)
*/
#define dot11_assoc_resp_set_cap(frame,cap)\
dot11_set_word(dot11_get_body(frame),cap)
#define dot11_assoc_resp_get_cap(frame)\
dot11_get_word(dot11_get_body(frame))
#define dot11_assoc_resp_set_status_code(frame,code)\
dot11_set_word(dot11_get_body(frame)+2,code)
#define dot11_assoc_resp_get_status_code(frame)\
dot11_get_word(dot11_get_body(frame)+2)
#define dot11_assoc_resp_set_assoc_id(frame,id)\
dot11_set_word(dot11_get_body(frame)+4,id)
#define dot11_assoc_resp_get_assoc_id(frame)\
dot11_get_word(dot11_get_body(frame)+4)
//#define dot11_assoce_resp_get_var_body(frame)
// (get_frame_body(frame)+6)
#define dot11_copy_mac(src,dst)\
memcpy(dst,src,6);
struct cw_Dot11Elemenst {
bstr_t supportet_rates;
};
int dot11_init_assoc_resp(uint8_t * dst);
/**

View File

@ -31,8 +31,6 @@ uint64_t dot11_timer_get()
return 1000000 * tv.tv_sec + tv.tv_usec - dot11_timer_offset;
}
void dot11_timer_set(uint64_t val)
{
struct timeval tv;
@ -41,14 +39,15 @@ void dot11_timer_set(uint64_t val)
}
int dot11_put_ssid(uint8_t *dst,uint8_t * ssid,int len){
dot11_put_byte(dst,DOT11_ELEM_SSID);
dot11_put_byte(dst+1,len);
dot11_set_byte(dst,DOT11_ELEM_SSID);
dot11_set_byte(dst+1,len);
memcpy(dst+2,ssid,len);
return len;
}
int dot11_put_supported_rates(uint8_t *dst, float *basic, float *rates){
int dot11_convert_supported_rates(uint8_t *dst, float *basic, float *rates){
uint8_t *d = dst+2;
while(*basic != 0.0){
*d++ = 0x80 | dot11_float2rate(*basic);
@ -65,12 +64,25 @@ int dot11_put_supported_rates(uint8_t *dst, float *basic, float *rates){
}
int dot11_put_supported_rates(uint8_t * dst, bstr_t src)
{
int l = bstr_len(src);
dot11_set_byte(dst,DOT11_ELEM_SUPPORTED_RATES);
memcpy(dst+1, src,l+1);
return l+2;
}
int dot11_put_dsss_param_set(uint8_t *dst,int ch) {
dot11_put_byte(dst,DOT11_ELEM_DSSS_PARAM_SET);
dot11_put_byte(dst+1,1);
dot11_put_byte(dst+2,ch);
dot11_set_byte(dst,DOT11_ELEM_DSSS_PARAM_SET);
dot11_set_byte(dst+1,1);
dot11_set_byte(dst+2,ch);
return 3;
}
#define DOT11_INLINE

View File

@ -305,7 +305,10 @@ static unsigned int psk_server_cb(SSL *ssl,const char *identity, unsigned char *
*/
static unsigned int timer_cb(SSL *s, unsigned int timer_us)
{
return 5000000;
}
struct dtls_openssl_data * dtls_openssl_data_create(struct cw_Conn * conn, const SSL_METHOD * method, BIO_METHOD * bio)
{
@ -322,7 +325,7 @@ struct dtls_openssl_data * dtls_openssl_data_create(struct cw_Conn * conn, const
return NULL;
}
rc = SSL_CTX_get_security_level(d->ctx);
// rc = SSL_CTX_get_security_level(d->ctx);
SSL_CTX_set_security_level(d->ctx,0);
@ -338,6 +341,8 @@ struct dtls_openssl_data * dtls_openssl_data_create(struct cw_Conn * conn, const
return 0;
}
/* set dtls psk if exists */
/* if (conn->dtls_psk)
SSL_CTX_set_psk_server_callback( d->ctx, psk_server_cb);
@ -456,6 +461,7 @@ struct dtls_openssl_data * dtls_openssl_data_create(struct cw_Conn * conn, const
return 0;
}
DTLS_set_timer_cb(d->ssl,timer_cb);
d->bio = BIO_new(bio);
/* d->bio->ptr = conn;*/

View File

@ -27,6 +27,10 @@
#include "cw.h"
#include "format.h"
#include "capwap80211.h"
/**
* Format bytes as hex string.
* @param dst Destination buffer
@ -87,4 +91,145 @@ int format_hdr_flags(char *dst, uint8_t * th)
}
char * cw_format_radio_information(char * dst, int ri)
{
char *d = dst;
if (ri & CW_80211_RADIO_TYPE_A)
*d++='a';
if (ri & CW_80211_RADIO_TYPE_B)
*d++='b';
if (ri & CW_80211_RADIO_TYPE_G)
*d++='g';
if (ri & CW_80211_RADIO_TYPE_N)
*d++='n';
*d=0;
return dst;
}
static int cw_format_pkt_hdr0(char *dst, int incomming, uint8_t * packet, int len,
struct sockaddr *from, int draft7)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
int preamble;
char *s;
int hlen, rid, wbid;
int frag_id,frag_offs;
s = dst;
if (incomming){
if (cw_get_hdr_flag_f(packet)) {
s += sprintf(s, "Fragment from %s",
sock_addr2str_p(from,sock_buf));
} else {
s += sprintf(s, "From %s", sock_addr2str_p(from,sock_buf));
}
}
else{
if (cw_get_hdr_flag_f(packet)) {
s += sprintf(s, "Fragment to %s", sock_addr2str(from,sock_buf));
} else {
s += sprintf(s, "To %s", sock_addr2str(from,sock_buf));
}
}
s += sprintf(s, " l=%d: ", len);
preamble = cw_get_hdr_preamble(packet);
if (preamble == 01) {
s += sprintf(s, " (encrypted)");
return s - dst;
}
if (len < 4)
goto abort;
hlen = cw_get_hdr_hlen(packet);
rid = cw_get_hdr_rid(packet);
wbid = cw_get_hdr_wbid(packet);
s += sprintf(s, " H:%d R:%02d W:%02d", hlen, rid, wbid);
s += sprintf(s, " Flgs:");
s += format_hdr_flags(s, packet);
if (len < 8)
goto abort;
frag_id = cw_get_hdr_fragid(packet);
frag_offs = cw_get_hdr_fragoffset(packet);
s += sprintf(s, " Frag/Offs:%d/%d", frag_id, frag_offs);
if (cw_get_hdr_flag_m(packet)) {
/* rmac is present, print the rmac */
int rmac_len = cw_get_hdr_rmac_len(packet);
int plen = rmac_len;
if (rmac_len + 8 > len)
plen = len - 8;
if (rmac_len > 10)
plen = 10;
s += sprintf(s, " R-MAC:");
s += format_mac(s, cw_get_hdr_rmac_data(packet), plen);
if (rmac_len > 10) {
s += sprintf(s, " ... (len=%d)", rmac_len);
}
}
if (cw_get_hdr_flag_w(packet)) {
if (!draft7){
/* print wireless specific info */
int ws_len = cw_get_hdr_ws_len(packet);
int plen = ws_len > 20 ? 20 : ws_len;
s += sprintf(s, " WS:");
s += format_hexu(s, cw_get_hdr_ws_data(packet), plen);
if (ws_len > 20) {
s += sprintf(s, " ... (len=%d)", ws_len);
}
}
else {
int ws_len = cw_get_hdr_ws_len_7(packet);
int plen = ws_len > 20 ? 20 : ws_len;
s += sprintf(s, " WS:");
s += format_hexu(s, cw_get_hdr_ws_data_7(packet), plen);
if (ws_len > 20) {
s += sprintf(s, " ... (len=%d)", ws_len);
}
}
}
return s - dst;
abort:
s += sprintf(s, " Incomplete...");
return s - dst;
}
/**
* @brief Format a packet header for debugging purposes
* @param dst Destination buffer
* @param incomming True if the packet is an incomming packet, otherweise 0
* @param packet packet data
* @param len length of packet data
* @param from Address from where the packet was received
* @return Number of bytes written
*/
int cw_format_pkt_hdr(char *dst, int incomming, uint8_t * packet, int len,
struct sockaddr *from)
{
return cw_format_pkt_hdr0(dst, incomming, packet, len,
from, 0);
}
int cw_format_pkt_hdr_7(char *dst, int incomming, uint8_t * packet, int len,
struct sockaddr *from)
{
return cw_format_pkt_hdr0(dst, incomming, packet, len,
from, 1);
}

View File

@ -45,7 +45,6 @@ char *format_s_hex_bytes(char *dst, const char *format, const char *delim,
int cw_format_scan_hex_bytes(uint8_t *dst,const char *s, int len);
struct avltree;
/**
* Format bytes as a hex string. Hexadecimal letters are lower-case.
@ -110,8 +109,16 @@ char *cw_format_dump(const uint8_t * data, int len,
void cw_format_get_dump_defaults(struct cw_FormatDumpSettings * settings);
int cw_format_pkt_hdr(char *dst, int incomming, uint8_t * packet, int len,
struct sockaddr *from);
int cw_format_pkt_hdr_7(char *dst, int incomming, uint8_t * packet, int len,
struct sockaddr *from);
int cw_format_version(char *s, const uint8_t * version, int len);
char * cw_format_radio_information(char * dst, int ri);
int cw_format_dot11_hdr(char * dst, uint8_t *packet, int len);
int cw_format_dot11_elem(char *dst, uint8_t id, const uint8_t *src, int len);
/**@}*/
#endif

View File

@ -54,6 +54,7 @@
#include "capwap.h"
#include "cw.h"
#include "fragman.h"
/**
@ -101,20 +102,6 @@ static struct frag * frag_new(struct frag * frags, int fragid)
return NULL;
}
/*
void fragman_free(frag_t * 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);
}
*/
/**
* Add a fragment
* @pram frags Fragman object
@ -129,12 +116,10 @@ uint8_t * fragman_add(frag_t * frags, uint8_t *packet, int hlen, int payloadlen)
uint32_t val0,val1;
int fragid,fragoffset;
int dst;
int ti;
/* 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 */
@ -142,33 +127,30 @@ uint8_t * fragman_add(frag_t * frags, uint8_t *packet, int hlen, int payloadlen)
fragid = val1>>16;
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;
}
}
if (!f){
errno = ENOMEM;
/* out of fragmentation space */
return NULL;
}
errno = 0;
dst = fragoffset*8;
/* copy fragment*/
if (dst + payloadlen < FRAG_MAXSIZE) {
memcpy( f->buffer+4+dst,packet+hlen,payloadlen);
if (fragoffset==0){
/* preserve header of 1st fragment */
memset(f->buffer,0,MAX_PKT_HDR_LEN);
memcpy(f->buffer,packet,hlen);
cw_set_hdr_hlen(f->buffer,MAX_PKT_HDR_LEN/4);
cw_set_hdr_flags(f->buffer, CAPWAP_FLAG_HDR_F, 0);
}
memcpy( f->buffer+MAX_PKT_HDR_LEN+4+dst,packet+hlen,payloadlen);
f->bytesreceived+=payloadlen;
}
@ -176,22 +158,14 @@ uint8_t * fragman_add(frag_t * frags, uint8_t *packet, int hlen, int payloadlen)
f->bytesneeded=dst+payloadlen;
}
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;
*((uint32_t*)(r+MAX_PKT_HDR_LEN))=f->bytesneeded;
return r;
}
/*// printf("Fragman bytes needed: %i, received %i\n",f->bytesneeded,f->bytesreceived);*/
return NULL;
}

View File

@ -19,9 +19,9 @@
/**
*@defgroup Fragman FRAGMAN
*@breif Frgaman functions
*@brief Frgaman functions
*
* Detailed esription
* Detailed desription
*@{
*/
@ -33,18 +33,18 @@
#include <time.h>
#include <unistd.h>
#ifndef FRAG_MAXSIZE
/** maximaum size of a fragment */
#define FRAG_MAXSIZE 65536+4
#endif
#ifndef FRAG_MAXIDS
#define FRAG_MAXIDS 10
#endif
#define MAX_PKT_HDR_LEN 64
#ifndef FRAG_TTL
#define FRAG_TTL 5
#endif
/** maximaum size of a fragment */
#define FRAG_MAXSIZE (65536+MAX_PKT_HDR_LEN)
#define FRAG_MAXIDS 10
/**
* TTL of received fragment in seconds
*/
#define FRAG_TTL 5
struct frag {
@ -57,7 +57,7 @@ struct frag {
int bytesreceived;
int bytesneeded;
struct timespec t;
uint8_t * header;
// uint8_t * header;
};
typedef struct frag frag_t; /*FRAGMAN;*/

View File

@ -137,7 +137,7 @@
#define LW_ELEM_DIRECT_SEQUENCE_CONTROL 14
#define LW_ELEM_CHANGE_STATE_EVENT 26
#define LW_ELEM_80211_DELETE_WLAN 28
#define LWAPP_ELEM_80211_DELETE_WLAN 28
#define LW_ELEM_AC_NAME 31
#define LW_ELEM_LOCATION_DATA 35
@ -151,7 +151,7 @@
#define LW_ELEM_CERTIFICATE 44
#define LW_ELEM_WTP_BOARD_DATA 50
#define LW_BCAST_SSID_MODE 51
#define LWAPP_ELEM_BCAST_SSID_MODE 51
#define LW_ELEM_WTP_MODE_AND_TYPE 54
#define LW_ELEM_QOS 57

View File

@ -38,16 +38,16 @@ int cw_encode_elements(struct cw_ElemHandlerParams *params, mlist_t elements_lis
}
continue;
}
/*
if (!data->mand){
if (!cw_cfg_base_exists(params->cfg_list[0],handler->key)){
cw_dbg(DBG_MSG_COMPOSE," Add Elem: %d %d %d %s - (skip)",
data->proto, data->vendor, data->id, handler->name);
cw_dbg(DBG_MSG_COMPOSE," Add Elem: %d %d %d %s %s - (skip)",
data->proto, data->vendor, data->id, handler->name, handler->key);
continue;
}
}
*/
l = handler->put(handler,params,dst+len);
cw_dbg(DBG_MSG_COMPOSE," Add Elem: %d %d %d %s - (%d bytes)",
@ -233,6 +233,10 @@ int cw_decode_element(struct cw_ElemHandlerParams *params, int proto,
/* check the length of the message */
if (len < handler->min_len) {
if (!handler->flags || cw_dbg_is_level(DBG_ELEM_VNDR))
cw_dbg_elem(params->dbg_level, NULL, params->msgdata->type, handler,
data, len);
cw_dbg(DBG_ELEM_ERR,
"%d (%s) message element too short, len=%d, min len=%d",
handler->id, handler->name, len, handler->min_len);
@ -246,6 +250,10 @@ int cw_decode_element(struct cw_ElemHandlerParams *params, int proto,
if (len > handler->max_len && handler->max_len) {
if (!handler->flags || cw_dbg_is_level(DBG_ELEM_VNDR))
cw_dbg_elem(params->dbg_level, NULL, params->msgdata->type, handler,
data, len);
cw_dbg(DBG_ELEM_ERR,
"%d (%s) message element too big, len=%d, max len=%d",
handler->id, handler->name, len, handler->max_len);

View File

@ -139,14 +139,14 @@ struct cw_Mod *cw_mod_load(const char *mod_name, cw_Cfg_t * global_cfg, int role
/* Search for the module in mods_loaded, to see if it is
* already loaded or was statically linked */
cw_dbg(DBG_MOD, "MOD: Load module '%s'", mod_name);
cw_dbg(DBG_MOD, "Loading module '%s'.", mod_name);
memset(&search, 0, sizeof(search));
search.name = mod_name;
mod = mavl_get_ptr(mods_loaded, &search);
if (mod) {
cw_dbg(DBG_MOD, "MOD: Module already loaded '%s'", mod_name);
cw_dbg(DBG_MOD, "Module already loaded: '%s'.", mod_name);
return mod;
}
@ -165,7 +165,7 @@ struct cw_Mod *cw_mod_load(const char *mod_name, cw_Cfg_t * global_cfg, int role
if (filename == NULL)
return NULL;
cw_dbg(DBG_MOD, "MOD: loading module from file: %s", filename);
cw_dbg(DBG_MOD, "Loading module from file: %s", filename);
/* Open the DLL */
handle = dlopen(filename, RTLD_NOW);
@ -189,8 +189,11 @@ struct cw_Mod *cw_mod_load(const char *mod_name, cw_Cfg_t * global_cfg, int role
goto errX;
}
cw_dbg(DBG_MOD, "MOD: %s sucessfull loaded, calling init now.", filename);
mod->init(mod, global_cfg, role);
cw_dbg(DBG_MOD, "Module %s sucessfull loaded, calling init now.", filename);
if (!mod->init(mod, global_cfg, role)){
dlclose(handle);
mod=NULL;
}
errX:
free(filename);

View File

@ -56,7 +56,7 @@ struct cw_Mod {
int elems_len, struct sockaddr * from, int mode);
struct cw_MsgSet * (*register_messages)(struct cw_MsgSet * set, int mode);
struct cw_MsgSet * (*register_messages)(struct cw_MsgSet * set, int mode );
/**
* Handle returned by dlopen, if this module was loaded

View File

@ -223,7 +223,7 @@ static int update_msgdata(struct cw_MsgSet *set, struct cw_MsgData *msgdata,
break;
continue;
case CW_DELETE:
cw_dbg(DBG_MOD, " deleting message element %d %d %d - %s",
cw_dbg(DBG_MOD_DETAIL, " deleting message element %d %d %d - %s",
elemdef->proto,
elemdef->vendor, elemdef->id, handler->name);
@ -248,11 +248,11 @@ static int update_msgdata(struct cw_MsgSet *set, struct cw_MsgData *msgdata,
result = mavl_replace(msgdata->elements_tree, &ed, &replaced);
if (!replaced) {
cw_dbg(DBG_MOD, " adding message element %d %d %d - %s",
cw_dbg(DBG_MOD_DETAIL, " adding message element %d %d %d - %s",
elemdef->proto,
elemdef->vendor, elemdef->id, handler->name);
} else {
cw_dbg(DBG_MOD, " replacing message element %d %d %d - %s",
cw_dbg(DBG_MOD_DETAIL, " replacing message element %d %d %d - %s",
elemdef->proto,
elemdef->vendor, elemdef->id, handler->name);
}
@ -275,7 +275,7 @@ static int update_msgdata(struct cw_MsgSet *set, struct cw_MsgData *msgdata,
result->vendor, result->id);
if (result->mand){
mlist_append_ptr(msgdata->mand_keys,(void*)handler->key);
cw_dbg(DBG_MOD," Add mandatory key: %s",handler->key);
cw_dbg(DBG_MOD_DETAIL," Add mandatory key: %s",handler->key);
}
/*//printf("Have Result %d %d - %s\n",result->id,result->mand, handler->key);*/
}
@ -294,7 +294,7 @@ int cw_msgset_add(struct cw_MsgSet *set,
struct cw_MsgDef *msgdef;
/* Create mavl for all handlers */
for (handler = handlers; handler->id; handler++) {
cw_dbg(DBG_MOD, "Adding handler for element %d - %s - with key: %s",
cw_dbg(DBG_MOD_DETAIL, "Adding handler for element %d - %s - with key: %s",
handler->id, handler->name, handler->key);
mavl_replace(set->handlers_by_id, handler, NULL);
mavl_replace(set->handlers_by_key, handler, NULL);
@ -339,7 +339,7 @@ int cw_msgset_add(struct cw_MsgSet *set,
msg->receiver = msgdef->receiver;
cw_dbg(DBG_MOD, "Add message Type:%d - %s ", msgdef->type, msgdef->name);
cw_dbg(DBG_MOD_DETAIL, "Add message Type:%d - %s ", msgdef->type, msgdef->name);
update_msgdata(set, msg, msgdef);
@ -376,7 +376,7 @@ int cw_msgset_add_states(struct cw_MsgSet * set, cw_StateMachineState_t * states
else{
repstr = "Adding";
}
cw_dbg(DBG_MOD,"%s machine state : [%s->%s]",repstr,
cw_dbg(DBG_MOD_DETAIL,"%s machine state : [%s->%s]",repstr,
cw_strstate(s->prevstate),
cw_strstate(s->state));
s++;
@ -405,7 +405,9 @@ struct cw_MsgData *cw_msgset_get_msgdata(struct cw_MsgSet *set, int type)
return NULL;
}
typedef int (*cw_MsgCallbackFun)(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len);
//typedef int (*cw_MsgCallbackFun)(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len);
//
/*
cw_MsgCallbackFun cw_msgset_set_postprocess(struct cw_MsgSet * set,int msg_id,
cw_MsgCallbackFun fun)
@ -420,5 +422,5 @@ cw_MsgCallbackFun cw_msgset_set_postprocess(struct cw_MsgSet * set,int msg_id,
return old_callback;
}
*/

View File

@ -72,6 +72,9 @@ struct cw_MsgSet {
mavl_t statemachine_states;
int (*write_header)(struct cw_ElemHandler * handler, uint8_t * dst, int len);
int (*header_len)(struct cw_ElemHandler *handler);
int (*format_pkt_hdr)(char *dst, int incomming, uint8_t * packet, int len,
struct sockaddr *from);
};
@ -146,9 +149,8 @@ struct cw_ElemHandler * cw_msgset_get_elemhandler(struct cw_MsgSet * set,
#define CW_MSGSET_POSTPROCESS 1
#define CW_MSGSET_PREPROCESS 2
typedef int (*cw_MsgCallbackFun)(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len);
cw_MsgCallbackFun cw_msgset_set_postprocess(struct cw_MsgSet * set,int msg_id,
cw_MsgCallbackFun fun);
//cw_MsgCallbackFun cw_msgset_set_postprocess(struct cw_MsgSet * set,int msg_id,
// cw_MsgCallbackFun fun);
#endif

View File

@ -1,51 +0,0 @@
/*
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
#include "bstr.h"
struct radioinfo{
char set;
int rid;
uint32_t type;
int admin_state;
int state;
int cause;
bstr_t rmac;
uint16_t regDomain;
uint8_t country_str[4];
uint8_t country_str2[4];
int cfp_period;
int cfp_max_duration;
int beacon_period;
int dtim_period;
int max_bssid;
int occupancy_limit;
bstr_t bssid;
};
#endif

View File

@ -90,10 +90,143 @@ int conn_send_data_msg(struct cw_Conn * conn, uint8_t *rawmsg,int len)
return 0;
}
#define MAX_MTU 9500
/**
* Initialize a capwap header
*
* @param buf Buffer to be initialized
* @param wbid Wireless Binding ID
* @param rid Radio ID
* @param rmac Radio MAC, NULL if not present
* @param wd Wireless Data, NULL if not present
*
* @return Length of the header that was initialized
*/
int
cw_init_capwap_packet( uint8_t * buf, int wbid ,int rid, bstr_t rmac, bstr_t wd)
{
int len,hlen;
/* header len */
len = 8;
/* zero the first 8 bytes */
cw_set_dword(buf + 0, 0);
cw_set_dword(buf + 4, 0);
/* capwap version/unencrypted */
#if CAPWAP_VERSION != 0
cw_set_hdr_preamble(buf, CAPWAP_VERSION << 4 | 0);
#endif
/* set wbid and rid */
cw_set_hdr_wbid(buf, wbid);
cw_set_hdr_rid(buf, rid);
/* add rmac if present */
if (rmac != NULL){
int rmac_len = bstr_len(rmac);
memcpy(cw_get_hdr_rmac(buf), rmac, rmac_len + 1);
cw_set_hdr_flags(buf, CAPWAP_FLAG_HDR_M, 1);
len+=rmac_len+1;
}
/* Add wireless data if present */
if (wd!=NULL){
int wd_len = bstr_len(wd);
memcpy(buf+len, wd, wd_len + 1);
cw_set_hdr_flags(buf, CAPWAP_FLAG_HDR_M, 1);
len+=wd_len;
}
hlen = len / 4;
if (len % 4 != 0) {
hlen++;
}
cw_set_hdr_hlen(buf, hlen);
return hlen*4;
}
/**
* Send a CAPWAP packet and fragment it if nececerry
* @param conn connection where to send packet over
* @param buf pointer to a buffer initialized with #cw_init_capwap_packet
* @param hlen length of header, which is the value returned by #cw_init_capwap_packet
* @param data payload
* @param len length of payload
*/
int cw_send_capwap_packet(struct cw_Conn * conn, uint8_t * buf, int hlen, uint8_t * data, int len)
{
int fragoffset,mtu;
int fragid;
/* get mtu and align it to 8 */
mtu = conn->mtu;
mtu &= ~3;
/* initialize fragid and fragoffset */
fragoffset = 0;
if (len + hlen > mtu)
fragid = conn->fragid++;
else
fragid = 0;
/* create all fragments */
while (len + hlen > mtu){
memcpy(buf+hlen,data+(fragoffset*8),mtu-hlen);
len -= (mtu - hlen);
cw_set_hdr_flags(buf,CAPWAP_FLAG_HDR_F,1);
cw_set_dword(buf+4, fragid<<16 | fragoffset<<3 );
cw_dbg_pkt(DBG_PKT_OUT,conn,buf,mtu,(struct sockaddr*)&conn->addr);
if (conn->write(conn,buf,mtu)<0)
return -1;
fragoffset+=(mtu-hlen)/8;
/* put rmac and wireless data only into the 1st fragment */
if (hlen!=8){
cw_set_hdr_flags(buf,CAPWAP_FLAG_HDR_M,0);
cw_set_hdr_flags(buf,CAPWAP_FLAG_HDR_W,0);
hlen = 8;
cw_set_hdr_hlen(buf,hlen/4);
}
}
if (fragoffset)
cw_set_hdr_flags(buf,CAPWAP_FLAG_HDR_F | CAPWAP_FLAG_HDR_L,1);
else
cw_set_hdr_flags(buf,CAPWAP_FLAG_HDR_F,0);
memcpy(buf+hlen,data+(fragoffset*8),len);
cw_set_dword(buf+4, fragid<<16 | fragoffset<<3 );
cw_dbg_pkt(DBG_PKT_OUT,conn,buf,len+hlen,(struct sockaddr*)&conn->addr);
return conn->write(conn,buf,len + hlen);
}
int
cw_send_msg( struct cw_Conn * conn, uint8_t *msg)
{
uint8_t buf[MAX_MTU];
int hlen,msglen;
hlen = cw_init_capwap_packet(buf,1,0,NULL,NULL);
msglen = cw_get_msg_elems_len(msg) + 8;
return cw_send_capwap_packet(conn,buf,hlen,msg,msglen);
}
int
cw_send_msg_old( struct cw_Conn * conn, uint8_t *msg)
{
uint8_t buf[MAX_MTU];
int fragoffset,hlen,mtu;

View File

@ -1,89 +0,0 @@
/*
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/>.
*/
/**
* @file
* @brief bstr_create_from_cfgstr function
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "bstr.h"
/**
* Create a bstr16_t string from a string read from config file.
*
* @param s String from config file.
* @return The create bstr_t string.
*
* The string from config file is an ASCII-text which is interpreted
* as hexadecimal string if it starts with ".x"
*
* @see bstr16_t
*/
uint8_t * bstr16_create_from_cfgstr(const char * s)
{
int l = strlen(s);
if (s[0]!='.')
return bstr16_create((uint8_t*)s,l);
if (l<=2)
return bstr16_create((uint8_t*)s,l);
if (s[1]=='.')
return bstr16_create((uint8_t*)s+1,l-1);
if (s[1]=='x'){
uint8_t * ns=0;
int len=0;
int ch,cl;
const char *ss = s+2;
int rc ;
do {
rc = sscanf(ss,"%01X",&ch);
if (rc!=1)
break;
ss++;
rc = sscanf(ss,"%01X",&cl);
if (rc!=1)
cl=0;
ss++;
int c=(ch<<4) | cl;
len++;
ns = realloc(ns,len);
ns[len-1]=c;
}while (rc==1);
return bstr16_create(ns,len);
}
return NULL;
}

View File

@ -1,67 +0,0 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "bstr.h"
/**
* Create a bstr1616_t string from a string read from config file.
*
* @param s String from config file.
* @return The create bstr16_t string.
*
* The string from config file is an ASCII-text which is interpreted
* as hexadecimal string if it starts with ".x"
*
* @see bstr16_t
*/
uint8_t * bstr16cfgstr(const char * s)
{
int l = strlen(s);
if (s[0]!='.')
return bstr16_create((uint8_t*)s,l);
if (l<=2)
return bstr16_create((uint8_t*)s,l);
if (s[1]=='.')
return bstr16_create((uint8_t*)s+1,l-1);
if (s[1]=='x'){
uint8_t * ns=0;
int len=0;
int ch,cl;
const char *ss = s+2;
int rc ;
do {
rc = sscanf(ss,"%01X",&ch);
if (rc!=1)
break;
ss++;
rc = sscanf(ss,"%01X",&cl);
if (rc!=1)
cl=0;
ss++;
int c=(ch<<4) | cl;
len++;
ns = realloc(ns,len);
ns[len-1]=c;
}while (rc==1);
return bstr16_create(ns,len);
}
return NULL;
}

View File

@ -1,90 +0,0 @@
/*
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/>.
*/
/**
* @file
* @brief bstr_create_from_cfgstr function
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "bstr.h"
/**
* Create a bstr_t string from a string read from config file.
*
* @param s String from config file.
* @return The create bstr_t string.
*
* The string from config file is an ASCII-text which is interpreted
* as hexadecimal string if it starts with ".x"
*
* @see bstr_t
*/
uint8_t * bstr_create_from_cfgstr(const char * s)
{
int l = strlen(s);
if (s[0]!='.')
return bstr_create((uint8_t*)s,l);
if (l<=2)
return bstr_create((uint8_t*)s,l);
if (s[1]=='.')
return bstr_create((uint8_t*)s+1,l-1);
if (s[1]=='x'){
uint8_t * ns=0;
int len=0;
int ch,cl;
const char *ss = s+2;
int rc ;
do {
rc = sscanf(ss,"%01X",&ch);
if (rc!=1)
break;
ss++;
rc = sscanf(ss,"%01X",&cl);
if (rc!=1)
cl=0;
ss++;
int c=(ch<<4) | cl;
len++;
ns = realloc(ns,len);
ns[len-1]=c;
}while (rc==1);
return bstr_create(ns,len);
}
return NULL;
}

View File

@ -1,38 +0,0 @@
#include <stdio.h>
#include <string.h>
#include "bstr.h"
#include "cw_util.h"
int bstr_to_str(char *dst, bstr_t str,char * def)
{
if (!str){
if (!def)
return 0;
return sprintf(dst,"%s",def);
}
int printable = cw_is_printable(bstr_data(str),bstr_len(str));
int l=bstr_len(str);
if (printable){
memcpy((char*)dst,bstr_data(str),l);
*(dst+l)=0;
return l;
}
int i;
int c=0;
char *s = dst;
for (i=0; i<l; i++){
if (!c){
s += sprintf(s,"%02X",bstr_data(str)[i]);
c=1;
}
else
s += sprintf(s,",%02X",bstr_data(str)[i]);
}
return s-dst;
}

View File

@ -1,126 +0,0 @@
#include <stdio.h>
#include "capwap80211_types.h"
#include "dot11.h"
/*
static int to_str(void *item,char *dst)
{
mbag_item_t *it= item;
uint8_t *data = (uint8_t*)it->u2.data;
int n=*data;
data++;
char *d=dst;
char *space="";
int i;
for (i=0; i<n; i++){
int val = data[i];
d+=sprintf(d,"%s",space);
if (val & 0x80){
d+=sprintf(d,"*");
}
d+=sprintf(d,"%0.1f",dot11_rate2float(val & 0x7f));
space=" ";
}
return d-dst;
}
static struct mbag_item * from_str(const char *src)
{
mbag_item_t * item = mbag_item_new(CAPWAP80211_TYPE_RATESET);
if (!item)
return NULL;
if (strlen(src)==0)
return 0;
uint8_t rates[64];
int nrates =0;
const char *s = src;
while (*s!=0){
while (*s==' ')
s++;
int m=0;
if(*s=='*'){
m=0x80;
s++;
}
else{
m=0;
}
float val;
int n=sscanf(s,"%f",&val);
if (n!=1)
break;
int r = dot11_float2rate(val) | m;
rates[nrates++]=r;
while (*s!=0 && *s!=' ')
s++;
}
uint8_t *data = malloc(nrates+1);
*data=nrates;
memcpy(data+1,rates,nrates);
item->u2.data=data;
return item;
}
static struct mbag_item * get(const uint8_t *src,int len)
{
mbag_item_t * item = mbag_item_new(CAPWAP80211_TYPE_RATESET);
if (!item)
return NULL;
uint8_t *data = malloc(len+1);
if (!data){
free (item);
return NULL;
}
*data=len;
memcpy(data+1,src,len);
item->u2.data=data;
return item;
}
static int put(struct mbag_item *i,uint8_t *dst)
{
int l=*((uint8_t*)(i->u2.data));
memcpy(dst,i->u2.data+1,l);
return l;
}
const struct mbag_typedef capwap80211_type_rateset = {
.name = "802.11 Rate Set",
.del = free,
.from_str = from_str,
.to_str = to_str,
.get = get,
.put = put
};
*/

View File

@ -1,59 +0,0 @@
/**
* Add a Cisco AP Timesync message element to a buffer
* @param dst destination buffer
* @param time a unix timestamp
* @param type of time
* @return number of bytes put (5)
*/
/*
int cw_put_cisco_ap_timesync(uint8_t * dst, time_t time, uint8_t type)
{
cw_put_dword(dst , time);
cw_put_byte(dst + 4, type);
return 5;
}
*/
/*
int cw_addelem_cisco_ap_regulatory_domain(uint8_t *dst, struct radioinfo * ri){
uint8_t *d=dst+10;
d+=cw_put_byte(d,ri->rid); // Band ID
d+=cw_put_byte(d,1); // Set True/False
d+=cw_put_byte(d,ri->rid); // Slot ID
d+=cw_put_word(d,ri->regDomain);
return 5 + cw_put_elem_vendor_hdr(dst, CW_VENDOR_ID_CISCO, CW_CISCO_AP_REGULATORY_DOMAIN, 5);
}
*/
/**
* Add a Cisco Certificate payload message element
* @param dst destination buffer
* @param src pointer to DER certificate
* @param len length of certificate
* @return number of bytes put
*/
/*
int cw_addelem_cisco_certificate(uint8_t*dst,uint8_t*src,int len){
int l = lw_put_certificate(dst+10,src,len);
return l+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_CERTIFICATE,l);
}
*/
/*
int cw_addelem_cisco_wtp_radio_cfg(uint8_t * dst,struct radioinfo *ri){
int l = lw_put_80211_wtp_wlan_radio_configuration(dst+10,ri);
return l+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_STATION_CFG,l);
}
*/
/*
int cw_readelem_cisco_station_cfg(uint8_t *src,int len){
// lw_readelem_
return 0;
}
*/

View File

@ -1,175 +0,0 @@
#include "capwap.h"
#include "radio.h"
#include "log.h"
#include "dbg.h"
/*
int cw_put_cisco_wtp_radio_cfg(uint8_t *dst, int rid, mbag_t radio)
{
cw_put_byte(dst,rid);
cw_put_byte(dst+1,0); //?
cw_put_word(dst+2,mbag_get_word(radio,CW_RADIO_OCCUPANCY_LIMIT,12));
cw_put_byte(dst+4,mbag_get_byte(radio,CW_RADIO_CFP_PERIOD,8));
cw_put_word(dst+5,mbag_get_word(radio,CW_RADIO_CFP_MAX_DURATION,200));
bstr_t grmac = mbag_get_bstr(radio,CW_RADIO_BSSID,NULL);
//printf("GRMAC: %d\n",bstr_len(grmac));
if ( grmac) {
if (bstr_len(grmac)!=6){
cw_log(LOG_ERR,"Wrong bssid size");
exit(0);
grmac =NULL;
}
}
bstr_t rmac;
if (!grmac){
uint8_t defrmac[]={0,0,0,0,0,0};
rmac = bstr_create(defrmac,6);
}
else
rmac = grmac;
cw_put_bstr(dst+7,rmac);
if ( !grmac )
free(rmac);
cw_put_word(dst+13,0); // beacon period
cw_put_data(dst+15,mbag_get_raw(radio,CW_RADIO_COUNTRY_STRING,"DE "),3);
cw_put_data(dst+18,mbag_get_raw(radio,CW_RADIO_COUNTRY_STRING,"DE "),3);
cw_put_byte(dst+21,10); // gPeriod
cw_put_dword(dst+22,0x3538); // ?
cw_put_word(dst+26,0);
return 26+2; //+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_WTP_RADIO_CFG,28);
}
*/
/*
int cw_put_elem_cisco_ap_regulatory_domain(uint8_t *dst,int rid, mbag_t radio)
{
//int l=0;
uint8_t *d=dst+10;
d+=cw_put_byte(d,rid); //Band ID
d+=cw_put_byte(d,1); // Set True/False
d+=cw_put_byte(d,rid); //* Slot ID
d+=cw_put_word(d,mbag_get_word(radio,CW_RADIO_REG_DOMAIN,1));
return 5 + cw_put_elem_vendor_hdr(dst, CW_VENDOR_ID_CISCO, CW_CISCO_AP_REGULATORY_DOMAIN, 5);
}
*/
/*
int cw_put_elem_cisco_radio_cfg(uint8_t * dst,int rid, mbag_t radio)
{
int l = cw_put_cisco_wtp_radio_cfg(dst+10,rid,radio);
return l+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_WTP_RADIO_CFG,l);
}
int cw_out_cisco_wtp_radio_cfg(struct conn *conn, struct cw_action_out *a, uint8_t * dst)
{
int l=0;
MAVLITER_DEFINE(it,conn->radios);
mavliter_foreach(&it){
struct mbag_item *i = mavliter_get(&it);
if ( i->type != MBAG_MBAG ) {
continue;
}
// l+=cw_put_elem_radio_info(dst+l,i->id,i->data);
l+=cw_put_elem_cisco_radio_cfg(dst+l,i->u1.iid,i->u2.data);
l+=cw_put_elem_cisco_ap_regulatory_domain(dst+l,i->u1.iid,i->u2.data);
}
return l;
// MAVLITER_DEFINE
// int l = cw_out_cisco_wtp_radio_cfg_(conn,a,dst,0);
// return l+cw_out_cisco_wtp_radio_cfg_(conn,a,dst+l,1);
}
int cw_in_cisco_radio_cfg(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len,
struct sockaddr *from)
{
int rid = cw_get_byte(data);
mbag_t radio = mbag_i_get_mbag(conn->radios,rid,NULL);
if ( !radio){
cw_dbg(DBG_ELEM_ERR,"Radio ID %d not defined",rid);
return 0;
}
// printf("Here we are %d\n",rid);
return 0;
}
int cw_radio_cisco_set_state(struct conn * conn, uint8_t *data, int len, int cause)
{
int rid = cw_get_byte(data);
int state = cw_get_byte(data+1);
if (rid != 255)
return cw_radio_set_admin_state(conn->radios,rid,state,cause);
MAVLITER_DEFINE(it,conn->radios);
mavliter_foreach(&it){
mbag_item_t *i = mavliter_get(&it);
cw_radio_set_admin_state(conn->radios,i->u1.iid,state,cause);
}
return 1;
}
int cw_in_cisco_radio_administrative_state(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len,
struct sockaddr *from)
{
return cw_radio_cisco_set_state(conn,data,len,-1);
}
int cw_in_cisco_radio_administrative_state_wtp(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len,
struct sockaddr *from)
{
return cw_radio_cisco_set_state(conn,data,len,3);
}
*/

View File

@ -1,33 +0,0 @@
#include "capwap.h"
#include "conn.h"
#include "mavl.h"
/*
void conn_clear_upd(struct conn *conn, int merge)
{
if (merge){
mavl_merge(conn->config, conn->config_upd);
MAVLITER_DEFINE (it,conn->radios_upd);
mavliter_foreach(&it){
struct mbag_item * ruitem = mavliter_get(&it);
mavl_t radio_upd = ruitem->u2.data;
mbag_t radio = mbag_i_get_mbag(conn->radios,ruitem->u1.iid,NULL);
if (radio){
mavl_merge(radio,radio_upd);
}
}
}
mavl_del_all(conn->config_upd);
mavl_del_all(conn->radios_upd);
}
*/

View File

@ -1,26 +0,0 @@
#include "capwap.h"
#include "cw.h"
int cw_addelem_cisco_wtp_radio_cfg(uint8_t*dst,struct radioinfo *ri)
{
cw_put_byte(dst+10,ri->rid);
cw_put_byte(dst+10+1,0);
cw_put_word(dst+10+2,ri->occupancy_limit);
cw_put_byte(dst+10+4,ri->cfp_period);
cw_put_word(dst+10+5,ri->cfp_max_duration);
/* XXX catch rmac shorter or longer than 6*/
cw_put_bstr(dst+10+7,ri->rmac); /* length MUST be 6 */
cw_put_word(dst+10+13,ri->beacon_period);
cw_put_data(dst+10+15,ri->country_str,3);
cw_put_data(dst+10+18,ri->country_str2,3);
cw_put_byte(dst+10+21,10); // gPeriod
cw_put_dword(dst+10+22,0x3538); // ?
/* return 28+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_WTP_RADIO_CFG,28);*/
}

View File

@ -1,18 +0,0 @@
#include "cw.h"
#include "dbg.h"
#include "cw_80211.h"
/*
int cw_in_80211_mac_operation(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len, struct sockaddr *from)
{
int rid = cw_get_byte(data);
mbag_t r = mbag_i_get_mbag(conn->radios,rid,NULL);
if (!r){
cw_dbg(DBG_ELEM_ERR,"Radio %d not defined. Can't set mac operation.");
return 0;
}
return cw_read_80211_mac_operation(data+2,r);
}
*/

View File

@ -1,38 +0,0 @@
#include "dbg.h"
#include "capwap.h"
/*
int cw_in_cisco_image_identifier(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len,struct sockaddr *from)
{
if (len<a->min_len) {
cw_dbg(DBG_ELEM_ERR,"Message element too short, %d < %d", len,a->min_len);
return 0;
}
uint32_t vendor_id = cw_get_dword(data);
int dstart;
switch (vendor_id) {
case CW_VENDOR_ID_ZYXEL:
case CW_VENDOR_ID_CISCO:
case CW_VENDOR_ID_FSF:
case 0:
dstart=4;
len-=4;
break;
default:
vendor_id=CW_VENDOR_ID_CISCO;
dstart=0;
}
// mbag_set(conn->remote,a->item_id,a->itemtype,data+dstart,len);
// mbag_set_bstrv(conn->incomming,a->item_id,vendor_id,data+dstart,len);
return 1;
}
*/

View File

@ -1,22 +0,0 @@
#include "dbg.h"
#include "log.h"
#include "cw.h"
#include "radio.h"
int cw_in_radio_administrative_state(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len,
struct sockaddr *from)
{
/* int rid = cw_get_byte(data);
int state = cw_get_byte(data+1);
return cw_radio_set_admin_state(conn->radios,rid,state,-1);
*/
}

View File

@ -1,26 +0,0 @@
#include "dbg.h"
#include "log.h"
#include "capwap.h"
#include "radio.h"
int cw_in_radio_administrative_state_wtp(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len,
struct sockaddr *from)
{
if (!cw_in_radio_administrative_state(conn,a,data,len,from) )
return 0;
return 1;
}

View File

@ -1,123 +0,0 @@
/*
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.h"
#include "cw_util.h"
#include "dbg.h"
/*
static void readsubelems_wtp_board_data(mbag_t itemstore, uint8_t * msgelem,
int len)
{
if (len<4)
return;
int i = 0;
// uint32_t val;
do {
// val = ntohl(*((uint32_t *) (msgelem + i)));
// int subtype = (val >> 16) & 0xffff;
// int sublen = val & 0xffff;
//
int subtype = cw_get_word(msgelem+i);
int sublen = cw_get_word(msgelem+i+2);
i += 4;
if (sublen + i > len) {
cw_dbg(DBG_ELEM_ERR,
"WTP Board data sub-element too long, type=%d,len=%d",
subtype, sublen);
return;
}
cw_dbg(DBG_SUBELEM, "board data sub-element, type=%d (%s), len=%d",
subtype, cw_strboardelem(subtype),sublen);
cw_dbg_dmp(DBG_SUBELEM,msgelem+i,sublen,"Dump...");
switch (subtype) {
case CW_BOARDDATA_MODELNO:
mbag_set_bstrn(itemstore,
CW_ITEM_WTP_BOARD_MODELNO,
msgelem + i, sublen);
break;
case CW_BOARDDATA_SERIALNO:
mbag_set_bstrn(itemstore,
CW_ITEM_WTP_BOARD_SERIALNO,
msgelem + i, sublen);
break;
case CW_BOARDDATA_MACADDRESS:
mbag_set_bstrn(itemstore,
CW_ITEM_WTP_BOARD_MACADDRESS,
msgelem + i, sublen);
break;
case CW_BOARDDATA_BOARDID:
mbag_set_bstrn(itemstore, CW_ITEM_WTP_BOARD_ID,
msgelem + i, sublen);
break;
case CW_BOARDDATA_REVISION:
mbag_set_bstrn(itemstore,
CW_ITEM_WTP_BOARD_REVISION,
msgelem + i, sublen);
default:
break;
}
i += sublen;
} while (i < len);
}
*/
/**
* Parse a WTP Board Data messag element and put results to itemstore.
*/
/*
int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len, struct sockaddr *from)
{
if (len < 4) {
cw_dbg(DBG_ELEM_ERR,
"Discarding WTP_BOARD_DATA msgelem, wrong size, type=%d, len=%d",
a->elem_id, len);
return 0;
}
mbag_t itemstore = conn->incomming;
mbag_set_dword(itemstore, CW_ITEM_WTP_BOARD_VENDOR, cw_get_dword(data));
readsubelems_wtp_board_data(itemstore, data + 4, len - 4);
return 1;
}
*/

View File

@ -1,36 +0,0 @@
#include "cw.h"
#include "capwap80211.h"
#include "radio.h"
/*
int cw_put_elem_80211_supported_rates(uint8_t*dst,int radio_id,mbag_t radio)
{
struct mbag_item * sr = mbag_get(radio,CW_RADIO_SUPPORTED_RATES);
if (!sr)
return 0;
int n = cw_put_byte(dst+4,radio_id);
n+=cw_put_mbag_item(dst+5,sr);
return 5 + cw_put_elem_hdr(dst,CW_ELEM80211_SUPPORTED_RATES,5);
}
int cw_out_80211_supported_rates(struct conn *conn, struct cw_action_out *a, uint8_t * dst)
{
int l=0;
MAVLITER_DEFINE(it,conn->radios);
mavliter_foreach(&it){
struct mbag_item *i = mavliter_get(&it);
if ( i->type != MBAG_MBAG ) {
continue;
}
l+=cw_put_elem_80211_supported_rates(dst+l,i->u1.iid,i->u2.data);
}
return l;
}
*/

View File

@ -1,42 +0,0 @@
#include "cw.h"
#include "dbg.h"
#include "log.h"
#include "acpriolist.h"
int cw_put_ac_name_with_priority(uint8_t *dst,cw_acprio_t * acprio)
{
int len = strlen(acprio->name);
cw_put_byte(dst,acprio->prio);
cw_put_data(dst+1,(uint8_t*)acprio->name,len);
return len+1;
}
int cw_out_ac_name_with_priority(struct conn *conn, struct cw_action_out *a, uint8_t * dst)
{
/* cw_acpriolist_t prios = mbag_get_mavl(conn->config,CW_ITEM_AC_NAME_WITH_PRIORITY);
if (!prios)
return 0;
uint8_t *d = dst;
MAVLITER_DEFINE(it,prios);
mavliter_foreach(&it){
cw_acprio_t * ac = mavliter_get(&it);
int l = cw_put_ac_name_with_priority(d+4,ac);
d+=cw_put_elem_hdr(d,CW_ELEM_AC_NAME_WITH_PRIORITY,l)+l;
}
return d-dst;
*/
}

View File

@ -1,57 +0,0 @@
/*
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/>.
*/
/**
* @file
* @brief Implementation output handler of capwap cw_out_local_ip_address
*/
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "cw.h"
#include "dbg.h"
#include "log.h"
#include "conn.h"
/**
* Output handler for Capwap Local IP Address message element.
*
* @param conn Connection object
* @param action Pointer to action which called this handler
* @param dst Destination buffer
*
* This handler determines the IP address from #conn->sock.
* It can deal both with IPv4 and IPv6 sockets.
*
*/
/*
int cw_out_capwap_local_ip_address(struct conn *conn, struct cw_action_out *action,
uint8_t * dst)
{
return cw_put_local_ip_address(conn->sock,dst,CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS,CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS);
}
*/

View File

@ -1,58 +0,0 @@
#include <stdio.h>
#include <errno.h>
#include "cw.h"
#include "log.h"
#include "dbg.h"
#include "sock.h"
#include "lwapp.h"
int cw_out_image_data(struct conn *conn, struct cw_action_out *a, uint8_t * dst)
{
/*
mbag_item_t * item = mbag_get(conn->outgoing,CW_ITEM_IMAGE_FILEHANDLE);
if (!item) {
cw_log(LOG_ERR,"Can't put element Image Data, no image filehandle found");
return 0;
}
FILE *infile = item->u2.data;
if (infile==NULL){
cw_log(LOG_ERR,"Image Data Request infile = NULL");
return 0;
}
int bytes=0;
switch ( conn->capwap_mode_out){
case CW_MODE_CISCO:
bytes = lw_put_image_data(dst+4,infile);
if ( bytes != LW_BLOCKSIZE_IMAGE_DATA + 3) {
avltree_del(conn->outgoing, item);
}
break;
default:
bytes = cw_put_image_data(dst+4,infile);
if (dst[4] != 1){
avltree_del(conn->outgoing, item);
}
}
if ( ferror(infile)){
cw_log(LOG_ERROR,"Aborting image data transfer: %s",strerror(errno));
}
return bytes + cw_put_elem_hdr(dst,a->elem_id,bytes);
*/
return 0;
}

View File

@ -1,50 +0,0 @@
/*
#include "cw.h"
#include "cw/dbg.h"
int cw_out_radio_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst)
{
cw_dbg(DBG_X,"Radio Generic out %s",a->item_id);
int l=0;
MAVLITER_DEFINE(it,conn->radios_upd);
mavliter_foreach(&it){
struct mbag_item *radio = mavliter_get(&it);
if ( radio->type != MBAG_MBAG ) {
continue;
}
// Size for msg elem header depends on
// vendor specific payload
int start = a->vendor_id ? 10 : 4;
uint8_t * d = dst+l;
struct mbag_item * item = mbag_get(radio->u2.data,a->item_id);
if (!item){
cw_dbg(DBG_X,"Not found! %s for rid %d",a->item_id,radio->u1.iid);
continue;
}
int len=0;
len += cw_put_byte(d+start,radio->u1.iid);
cw_dbg(DBG_X, "Radio generic out '%s' fro rid %d",a->item_id,radio->u1.iid);
len += cw_put_mbag_item(d + start+1, item);
if (a->vendor_id)
l+= len + cw_put_elem_vendor_hdr(d, a->vendor_id, a->elem_id, len);
else
l += len + cw_put_elem_hdr(d, a->elem_id, len);
}
return l;
}
*/

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