Work on Cisco elements

FossilOrigin-Name: e85120145936b3c53bef57144667078010c2e22d7db08797259bbc2670eb0a4b
This commit is contained in:
7u83@mail.ru
2018-05-07 08:57:12 +00:00
parent dd1d3f4dbc
commit 1bdaa652a4
28 changed files with 569 additions and 199 deletions

View File

@ -137,6 +137,7 @@ strict_capwap = off
# Defalut:
#listen = 192.168.0.14:1027
#listen = 192.168.56.1
#listen = 192.168.0.14
# broadcast_listen - Broadcast listen address
# If ommited, the boraadcast listen adresses a determined automatically
@ -211,7 +212,7 @@ ssl_cert="../../ssl/certs/ac-cisco.pem"
dbg += pkt_in # CAPWAP packets received
dbg += pkt_out # CAPWAP packets sent
dbg += pkt # CAPWAP packets both sent and received
# dbg += pkt_dmp # Hex dump CAPWAP packets.
dbg += pkt_dmp # Hex dump CAPWAP packets.
dbg += pkt_err # Show messages about malformed packets when detected
dbg += dtls # Messages concerning DTLS
# dbg += dtls_detail # DTLS in more detail
@ -220,6 +221,7 @@ ssl_cert="../../ssl/certs/ac-cisco.pem"
dbg += warn # misc warnings
dbg += mod # Debugs specific to mod
dbg += cfg_dmp
dbg += state
#
# dbg += all # all of the above
# dbg += err # Same as dbg_err and pkt_err

View File

@ -30,6 +30,7 @@ ac-descriptor/software/version :Bstr16: .x07036500
ac-descriptor/station-limit :Word: 1000
ac-descriptor/stations :Word: 0
capwap-control-ip-address/address.0 :IPAddress: 192.168.0.14
#capwap-control-ip-address/address.0 :IPAddress: 192.168.42.51
capwap-control-ip-address/wtps.0 :Word: 2
cisco/mwar-type :Byte: 0
maximum-message-length :Word: 4096
@ -50,8 +51,8 @@ capwap-control-ip-address/wtps.0:Word:0
cisco/ssl-keyfile:Str:"../../ssl/certs/cisco-ac.key"
cisco/ssl-certfile:Str:"../../ssl/certs/cisco-ac.pem"
cisco/ssl-cipher:Str:NORMAL
#+DHE-RSA:+AES-256-CBC:+AES-128-CBC:+SHA1:+PSK
cisco/ssl-cipher:Str:NORMAL
#cisco/ssl-cipher:Str:+DHE-RSA:+AES-256-CBC:+AES-128-CBC:+SHA1:+PSK
cisco/ssl-dhbits:Word:2048
capwap/ssl-cipher:Str:+DHE-RSA:+RSA:+AES-256-CBC:+AES-128-CBC:+SHA1:+PSK
@ -71,6 +72,14 @@ actube/listen:Bstr16:192.168.0.1
wait-dtls:Word:12
wait-join:Word:3
wait-join:Word:7
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
radio.255/admin-state :Str: enabled
radio.255/operational-state/cause :Str: Normal
radio.255/operational-state/state :Str: enabled

View File

@ -16,7 +16,30 @@
#include "wtplist.h"
void show_aps(FILE *out){
void show_cfg (FILE *out, mavl_t ktv)
{
char value[500];
struct cw_KTV * 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 show_aps (FILE *out)
{
struct connlist * cl;
mavliter_t it;
@ -27,75 +50,82 @@ void show_aps(FILE *out){
cl = wtplist_get_connlist();
mavliter_init(&it,cl->by_addr);
fprintf(out,"IP\t\t\twtp-name\n");
mavliter_foreach(&it){
mavliter_init (&it, cl->by_addr);
fprintf (out, "IP\t\t\twtp-name\n");
mavliter_foreach (&it) {
cw_KTV_t * result;
char addr[SOCK_ADDR_BUFSIZE];
char wtp_name[CAPWAP_MAX_WTP_NAME_LEN];
struct conn * conn;
conn = mavliter_get_ptr(&it);
conn = mavliter_get_ptr (&it);
sock_addr2str_p(&conn->addr,addr);
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);
}
result = cw_ktv_get (conn->remote_cfg, "wtp-name", NULL);
fprintf(out,"%s\t\t%s\n",addr,wtp_name);
if (result == NULL) {
strcpy (wtp_name, "");
} else {
result->type->to_str (result, wtp_name, CAPWAP_MAX_WTP_NAME_LEN);
}
fprintf (out, "%s\t\t%s\n", addr, wtp_name);
fprintf(out,"================= Local CFG: =================== \n");
show_cfg(out,conn->local_cfg);
fprintf(out,"================= Remote CFG: ================== \n");
show_cfg(out,conn->remote_cfg);
fprintf(out,"\n");
}
wtplist_unlock();
}
void execute_cmd(FILE * out, const char *str)
void execute_cmd (FILE * out, const char *str)
{
char cmd[1024];
char args[1024];
sscanf(str,"%s%s",cmd,args);
printf("CMD: %s, ARGS:\n",cmd);
sscanf (str, "%s%s", cmd, args);
/*printf("CMD: %s, ARGS:\n",cmd);*/
show_aps(out);
if (strcmp (cmd, "s") == 0) {
show_aps (out);
return;
}
}
void shell_loop(FILE *file)
void shell_loop (FILE *file)
{
int c;
/* setvbuf(file,NULL,_IONBF,0);
fflush(file);
*/
char str[2048];
do {
fprintf(file,"actube[%d]:>",fileno(file));
/* setvbuf(file,NULL,_IONBF,0);
fflush(file);
*/
char str[2048];
do {
fprintf (file, "actube[%d]:>", fileno (file));
fflush (file);
fgets(str,sizeof(str),file);
execute_cmd(file,str);
}while (c!=EOF);
fgets (str, sizeof (str), file);
execute_cmd (file, str);
} while (c != EOF);
}
void * run_shell(void * arg)
void * run_shell (void * arg)
{
struct sockaddr_storage server, client;
socklen_t client_size;
@ -106,47 +136,50 @@ void * run_shell(void * arg)
int sockfd, clientsock;
int yes;
rc = sock_strtoaddr(addr,(struct sockaddr*)&server);
if (! rc ){
cw_log(LOG_ERR,"Can't parse address '%s', %s",addr,strerror(errno));
rc = sock_strtoaddr (addr, (struct sockaddr*) &server);
if (! rc) {
cw_log (LOG_ERR, "Can't parse address '%s', %s", addr, strerror (errno));
}
sockfd = socket(((struct sockaddr*)&server)->sa_family,SOCK_STREAM,0);
sockfd = socket ( ( (struct sockaddr*) &server)->sa_family, SOCK_STREAM, 0);
yes = 1;
/* reuse address */
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (yes));
/* bind address */
rc = bind(sockfd,(struct sockaddr*)&server,sizeof(server));
if (rc ){
cw_log(LOG_ERR,"Can't bind socket address '%s', %s",addr,strerror(errno));
rc = bind (sockfd, (struct sockaddr*) &server, sizeof (server));
if (rc) {
cw_log (LOG_ERR, "Can't bind socket address '%s', %s", addr, strerror (errno));
}
rc = listen(sockfd,5);
if (rc ){
cw_log(LOG_ERR,"Can't listen on address '%s', %s",addr,strerror(errno));
rc = listen (sockfd, 5);
if (rc) {
cw_log (LOG_ERR, "Can't listen on address '%s', %s", addr, strerror (errno));
}
client_size = sizeof(client);
clientsock = accept(sockfd,(struct sockaddr*)&client,&client_size);
if (clientsock>0){
sock_addr2str_p(&client,sockstr);
cw_dbg(DBG_INFO, "Acceptiong session from %s",sockstr);
shell_loop(fdopen(clientsock,"a+"));
close(clientsock);
client_size = sizeof (client);
clientsock = accept (sockfd, (struct sockaddr*) &client, &client_size);
if (clientsock > 0) {
sock_addr2str_p (&client, sockstr);
cw_dbg (DBG_INFO, "Acceptiong session from %s", sockstr);
shell_loop (fdopen (clientsock, "a+"));
close (clientsock);
}
printf("Accepting %i, %s",rc,strerror(errno));
printf ("Accepting %i, %s", rc, strerror (errno));
return NULL;
}
@ -154,6 +187,6 @@ void * run_shell(void * arg)
void start_shell()
{
pthread_t thread;
pthread_create(&thread, NULL, run_shell,
NULL);
}
pthread_create (&thread, NULL, run_shell,
NULL);
}

View File

@ -90,15 +90,15 @@ static void wtpman_run_discovery(void *arg)
time_t timer = cw_timer_start(10);
wtpman->conn->capwap_transition = CAPWAP_STATE_DISCOVERY;
wtpman->conn->capwap_state = CAPWAP_STATE_DISCOVERY;
while (!cw_timer_timeout(timer)
&& wtpman->conn->capwap_transition == CAPWAP_STATE_DISCOVERY) {
&& wtpman->conn->capwap_state == CAPWAP_STATE_DISCOVERY) {
int rc;
rc = cw_read_messages(wtpman->conn);
if (cw_result_is_ok(rc)){
wtpman->conn->capwap_transition=CAPWAP_STATE_JOIN;
wtpman->conn->capwap_state=CAPWAP_STATE_JOIN;
cw_dbg(DBG_INFO,"Discovery has detected mods: %s %s",
wtpman->conn->cmod->name,wtpman->conn->bmod->name);
@ -166,7 +166,7 @@ static int wtpman_join(void *arg)
timer = cw_timer_start(wait_join);
while (!cw_timer_timeout(timer) && wtpman->conn->capwap_transition == CAPWAP_STATE_JOIN) {
while (!cw_timer_timeout(timer) && wtpman->conn->capwap_state == CAPWAP_STATE_JOIN) {
rc = cw_read_messages(wtpman->conn);
if (rc < 0) {
if (errno == EAGAIN)
@ -185,7 +185,7 @@ static int wtpman_join(void *arg)
}
if (wtpman->conn->capwap_transition != CAPWAP_STATE_JOIN_COMPLETE) {
if (wtpman->conn->capwap_state != CAPWAP_STATE_JOIN_COMPLETE) {
cw_dbg(DBG_MSG_ERR, "No join request from %s after %d seconds, WTP died.",
sock_addr2str(&wtpman->conn->addr,sock_buf), wait_join);
@ -279,6 +279,49 @@ void * wtpman_run_data(void *wtpman_arg)
}
int cw_run_state_machine(struct conn * conn, time_t *timer)
{
int timerval;
cw_StateMachineState_t search, *result;
while(1){
search.state = conn->capwap_state;
search.prevstate = conn->capwap_prevstate;
result = mavl_get(conn->msgset->state_machine,&search);
cw_dbg(DBG_STATE,"State transition: [%s -> %s]",
cw_strstate(conn->capwap_prevstate),
cw_strstate(conn->capwap_state)
);
if (result == NULL){
cw_log(LOG_ERR,"State not found");
return 0;
}
if (result->jump_state){
conn->capwap_state = result->jump_state;
conn->capwap_prevstate = result->jump_prevstate;
cw_dbg(DBG_STATE,"Jump to state: [%s->%s]",
cw_strstate(conn->capwap_prevstate),
cw_strstate(conn->capwap_state));
continue;
}
if (result->dbgmsg){
cw_dbg(DBG_STATE,"%s",result->dbgmsg);
}
if (result->timer_key){
timerval = cw_ktv_get_word(conn->local_cfg,result->timer_key,result->timer_default);
*timer = cw_timer_start(timerval);
cw_dbg(DBG_STATE,"Starting timer: [%s] - %d seconds.",result->timer_key,timerval);
}
return result->retval;
}
}
/*#define CW_TRANSITION(prestate,state) (prestate<<16|state)*/
@ -315,7 +358,7 @@ static void * wtpman_main(void *arg)
return NULL;
}
conn->capwap_transition = CAPWAP_STATE_DTLS_SETUP;
conn->capwap_state = CAPWAP_STATE_DTLS_SETUP;
/* establish dtls session */
if (!wtpman_dtls_setup(wtpman)) {
wtpman_remove(wtpman);
@ -325,7 +368,8 @@ static void * wtpman_main(void *arg)
/*last_state = conn->capwap_state;
conn->capwap_state = CAPWAP_STATE_JOIN;
*/
conn->capwap_transition = CW_TRANSITION(CAPWAP_STATE_DTLS_SETUP, CAPWAP_STATE_JOIN);
conn->capwap_prevstate = CAPWAP_STATE_DTLS_SETUP;
conn->capwap_state = CAPWAP_STATE_JOIN;
rc = 0;
while (1){
@ -333,8 +377,16 @@ static void * wtpman_main(void *arg)
int wait_join;
int wait_change_state;
if (!cw_run_state_machine(conn, &timer)){
cw_dbg(DBG_INFO,"WTP died");
wtpman_remove(wtpman);
return NULL;
};
/*
switch (conn->capwap_transition){
case CW_TRANSITION(CAPWAP_STATE_DTLS_SETUP, CAPWAP_STATE_JOIN):
{
@ -369,10 +421,6 @@ static void * wtpman_main(void *arg)
wait_change_state = cw_ktv_get_word(conn->global_cfg,
"capwap-timers/change-state-pending-timer",
CAPWAP_TIMER_CHANGE_STATE_PENDING_TIMER);
/* printf("Capwap state configure\n");
exit(0);
*/
break;
}
case CW_TRANSITION(CAPWAP_STATE_CONFIGURE,CAPWAP_STATE_TIMEOUT):
@ -386,7 +434,7 @@ static void * wtpman_main(void *arg)
}
*/
while (!cw_timer_timeout(timer)) {
rc = cw_read_messages(wtpman->conn);
@ -398,8 +446,8 @@ static void * wtpman_main(void *arg)
}
if(rc<0){
conn->capwap_transition =
CW_TRANSITION(conn->capwap_transition,CAPWAP_STATE_TIMEOUT);
conn->capwap_prevstate = conn->capwap_state;
conn->capwap_state = CAPWAP_STATE_TIMEOUT;
}
}
@ -427,7 +475,7 @@ static void * wtpman_main(void *arg)
/* dtls is established, goto join state */
conn->capwap_transition = CAPWAP_STATE_JOIN;
conn->capwap_state = CAPWAP_STATE_JOIN;
if (!wtpman_join(wtpman)) {
wtpman_remove(wtpman);
return NULL;
@ -454,7 +502,7 @@ exit(0);
rc = 0;
while (!cw_timer_timeout(timer)
&& wtpman->conn->capwap_transition == CAPWAP_STATE_CONFIGURE) {
&& wtpman->conn->capwap_state == CAPWAP_STATE_CONFIGURE) {
rc = cw_read_messages(wtpman->conn);
if (rc < 0) {
if (errno != EAGAIN)
@ -472,14 +520,14 @@ cw_dbg_ktv_dump(conn->remote_cfg,DBG_INFO,"-------------dump------------","DMP",
}
if (conn->capwap_transition == CW_STATE_IMAGE_DATA) {
if (conn->capwap_state == CW_STATE_IMAGE_DATA) {
wtpman_image_data(wtpman);
return NULL;
}
conn->capwap_transition = CAPWAP_STATE_RUN;
conn->capwap_state = CAPWAP_STATE_RUN;
/*
// XXX testing ...
// DBGX("Cofig to sql", "");
@ -492,7 +540,7 @@ cw_dbg_ktv_dump(conn->remote_cfg,DBG_INFO,"-------------dump------------","DMP",
reset_echointerval_timer(wtpman);
rc = 0;
while (wtpman->conn->capwap_transition == CAPWAP_STATE_RUN) {
while (wtpman->conn->capwap_state == CAPWAP_STATE_RUN) {
rc = cw_read_messages(wtpman->conn);
if (rc < 0) {
if (errno != EAGAIN)