Work on Cisco elements
FossilOrigin-Name: e85120145936b3c53bef57144667078010c2e22d7db08797259bbc2670eb0a4b
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
163
src/ac/shell.c
163
src/ac/shell.c
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
Reference in New Issue
Block a user