2018-05-02 11:03:05 +02:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
2022-08-28 09:06:15 +02:00
|
|
|
#include <ctype.h>
|
2018-05-02 11:03:05 +02:00
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/socket.h>
|
2022-08-23 02:35:54 +02:00
|
|
|
#include <sys/un.h>
|
2022-08-23 19:55:36 +02:00
|
|
|
#include <sys/wait.h>
|
2022-08-23 02:35:54 +02:00
|
|
|
|
2022-08-23 19:55:36 +02:00
|
|
|
#include <arpa/telnet.h>
|
|
|
|
#include <histedit.h>
|
2022-08-23 02:35:54 +02:00
|
|
|
|
2018-05-02 11:03:05 +02:00
|
|
|
|
|
|
|
#include "cw/sock.h"
|
|
|
|
#include "cw/log.h"
|
|
|
|
#include "cw/dbg.h"
|
|
|
|
|
2022-08-28 09:06:15 +02:00
|
|
|
#include "wtpman.h"
|
2018-05-02 11:03:05 +02:00
|
|
|
|
2018-05-04 13:37:53 +02:00
|
|
|
#include "cw/connlist.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "wtplist.h"
|
|
|
|
|
2022-08-23 02:35:54 +02:00
|
|
|
#include "ac.h"
|
2018-05-14 23:30:48 +02:00
|
|
|
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
struct rpcdata{
|
2022-08-23 19:55:36 +02:00
|
|
|
|
|
|
|
FILE *in;
|
2018-05-14 23:30:48 +02:00
|
|
|
FILE *out;
|
2022-08-23 19:55:36 +02:00
|
|
|
|
2018-05-14 23:30:48 +02:00
|
|
|
char prompt[1024];
|
2022-08-23 19:55:36 +02:00
|
|
|
cw_Cfg_t * update_cfg;
|
2022-08-24 00:29:26 +02:00
|
|
|
cw_Cfg_t * global_cfg;
|
2022-08-23 02:35:54 +02:00
|
|
|
char *history[2000];
|
|
|
|
char line[4096];
|
|
|
|
int pos;
|
|
|
|
char esc[8];
|
|
|
|
int escpos;
|
2022-08-23 04:08:37 +02:00
|
|
|
int quit;
|
2022-08-23 19:55:36 +02:00
|
|
|
|
|
|
|
History *hist;
|
|
|
|
HistEvent ev;
|
|
|
|
Tokenizer *tok;
|
|
|
|
EditLine *el;
|
|
|
|
|
2022-08-23 02:35:54 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct sockdata{
|
|
|
|
const char *name;
|
|
|
|
int fd;
|
|
|
|
cw_Cfg_t * global_cfg;
|
2018-05-14 23:30:48 +02:00
|
|
|
};
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
int select_cmd(struct rpcdata *sd, const char *cmd);
|
|
|
|
int list_cmd(struct rpcdata *sd, const char * cmd);
|
|
|
|
int cfg_cmd(struct rpcdata *sd, const char * cmd);
|
|
|
|
int ucfg_cmd(struct rpcdata *sd, const char * cmd);
|
|
|
|
int set_cmd(struct rpcdata *sd, const char * cmd);
|
|
|
|
int del_cmd(struct rpcdata *sd, const char * cmd);
|
|
|
|
int send_cmd(struct rpcdata *sd, const char * cmd);
|
|
|
|
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);
|
2022-08-28 09:06:15 +02:00
|
|
|
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);
|
2022-08-24 00:29:26 +02:00
|
|
|
|
2022-08-19 22:23:55 +02:00
|
|
|
//void show_cfg (FILE *out, mavl_t ktv);
|
2022-08-24 00:29:26 +02:00
|
|
|
int show_aps (FILE *out);
|
2018-05-14 23:30:48 +02:00
|
|
|
|
2022-08-09 22:35:47 +02:00
|
|
|
struct cw_Conn * find_ap(const char *name);
|
2018-05-14 23:30:48 +02:00
|
|
|
|
|
|
|
struct command{
|
|
|
|
char * cmd;
|
2022-08-24 00:29:26 +02:00
|
|
|
int (*fun)(struct rpcdata *sd, const char *cmd);
|
|
|
|
|
2018-05-14 23:30:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct command cmdlist[]={
|
2022-08-23 04:08:37 +02:00
|
|
|
{"exit",exit_cmd},
|
2022-08-24 00:29:26 +02:00
|
|
|
{"bumm",exit_cmd},
|
2018-05-14 23:30:48 +02:00
|
|
|
{"cfg", cfg_cmd },
|
|
|
|
{"del", del_cmd },
|
|
|
|
{"ucfg", ucfg_cmd},
|
|
|
|
{"list", list_cmd },
|
|
|
|
{"select", select_cmd },
|
|
|
|
{"send", send_cmd},
|
|
|
|
{"set", set_cmd },
|
2022-07-30 19:44:57 +02:00
|
|
|
{"wlan0",wlan0_cmd},
|
2022-08-24 00:29:26 +02:00
|
|
|
{"global_cfg", global_cfg_cmd},
|
2022-08-28 09:06:15 +02:00
|
|
|
{"status",status_cmd},
|
|
|
|
{"clear",clear_cmd},
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
|
|
|
|
{"@prompt",prompt_cmd},
|
2018-05-14 23:30:48 +02:00
|
|
|
|
|
|
|
|
|
|
|
{NULL,NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
static void finish_cmd(FILE *f)
|
|
|
|
{
|
|
|
|
fprintf(f,"\n");
|
|
|
|
fflush(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
int prompt_cmd(struct rpcdata *sd, const char *cmd)
|
|
|
|
{
|
2022-08-24 16:24:57 +02:00
|
|
|
const char *acname = cw_cfg_get(sd->global_cfg,"capwap/ac-name","actube");
|
|
|
|
|
|
|
|
fprintf(sd->out,"%s[%s]:>\n",acname,sd->prompt);
|
2022-08-24 00:29:26 +02:00
|
|
|
finish_cmd(sd->out);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-28 09:06:15 +02:00
|
|
|
int global_cfg_cmd(struct rpcdata *sd, const char *str)
|
2022-08-24 00:29:26 +02:00
|
|
|
{
|
2022-08-28 09:06:15 +02:00
|
|
|
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);
|
2022-08-24 00:29:26 +02:00
|
|
|
finish_cmd(sd->out);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int select_cmd(struct rpcdata *sd, const char *cmd)
|
2018-05-14 23:30:48 +02:00
|
|
|
{
|
|
|
|
char ap [CAPWAP_MAX_WTP_NAME_LEN];
|
|
|
|
sscanf(cmd,"%s",ap);
|
|
|
|
strcpy(sd->prompt,ap);
|
2022-08-24 16:24:57 +02:00
|
|
|
finish_cmd(sd->out);
|
|
|
|
return 0;
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
int list_cmd(struct rpcdata *sd, const char *cmd)
|
2018-05-14 23:30:48 +02:00
|
|
|
{
|
|
|
|
show_aps(sd->out);
|
2022-08-24 16:24:57 +02:00
|
|
|
finish_cmd(sd->out);
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
int exit_cmd(struct rpcdata *sd, const char *cmd)
|
2022-08-23 04:08:37 +02:00
|
|
|
{
|
2022-08-24 00:29:26 +02:00
|
|
|
//fprintf(sd->out,"Unknown command: '%s'\n\r\n\r",cmd);
|
|
|
|
|
2022-08-26 17:38:28 +02:00
|
|
|
// printf("Exitcmd %s\n",cmd);
|
|
|
|
//fprintf(sd->out,"END: %s\n\r",cmd);
|
|
|
|
finish_cmd(sd->out);
|
2022-08-24 00:29:26 +02:00
|
|
|
fflush(sd->out);
|
|
|
|
return 1;
|
2022-08-23 04:08:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-08-28 09:06:15 +02:00
|
|
|
int cfg_cmd(struct rpcdata *sd, const char *str)
|
2018-05-14 23:30:48 +02:00
|
|
|
{
|
2022-08-28 09:06:15 +02:00
|
|
|
char *s;
|
|
|
|
while( isspace( *str ) )
|
|
|
|
str++;
|
|
|
|
s=(char*)str;
|
|
|
|
while (!isspace(*s) && *s!=0)
|
|
|
|
s++;
|
|
|
|
*s=0;
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-08-09 22:35:47 +02:00
|
|
|
struct cw_Conn * conn;
|
2018-05-14 23:30:48 +02:00
|
|
|
wtplist_lock();
|
|
|
|
conn = find_ap(sd->prompt);
|
|
|
|
if (conn==NULL){
|
|
|
|
fprintf(sd->out,"WTP '%s' not found\n",sd->prompt);
|
|
|
|
}
|
|
|
|
else {
|
2022-08-28 09:06:15 +02:00
|
|
|
cw_cfg_fdump(sd->out,conn->remote_cfg,str);
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
2022-08-24 16:24:57 +02:00
|
|
|
finish_cmd(sd->out);
|
2018-05-14 23:30:48 +02:00
|
|
|
wtplist_unlock();
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
|
|
|
|
2022-08-28 09:06:15 +02:00
|
|
|
|
|
|
|
int status_cmd(struct rpcdata *sd, const char *cmd)
|
2018-05-14 23:30:48 +02:00
|
|
|
{
|
2022-08-28 09:06:15 +02:00
|
|
|
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);
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
int
|
|
|
|
send_cmd(struct rpcdata * sd, const char *cmd)
|
2018-05-14 23:30:48 +02:00
|
|
|
{
|
2022-08-28 09:06:15 +02:00
|
|
|
struct wtpman * wtpman;
|
2022-08-09 22:35:47 +02:00
|
|
|
struct cw_Conn * conn;
|
2018-05-14 23:30:48 +02:00
|
|
|
wtplist_lock();
|
|
|
|
conn = find_ap(sd->prompt);
|
|
|
|
if (conn==NULL){
|
|
|
|
fprintf(sd->out,"WTP '%s' not found\n",sd->prompt);
|
2022-08-28 09:06:15 +02:00
|
|
|
goto errX;
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
|
|
|
else {
|
2022-08-28 09:06:15 +02:00
|
|
|
wtpman=conn->data;
|
|
|
|
cw_cfg_copy(sd->update_cfg,conn->update_cfg,0,NULL);
|
|
|
|
wtpman->update=1;
|
|
|
|
|
|
|
|
fprintf(sd->out, "Sending update cmd\n");
|
|
|
|
|
|
|
|
// conn->update_cfg=sd->update_cfg;
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
2022-08-28 09:06:15 +02:00
|
|
|
errX:
|
2018-05-14 23:30:48 +02:00
|
|
|
wtplist_unlock();
|
2022-08-28 09:06:15 +02:00
|
|
|
finish_cmd(sd->out);
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
int
|
|
|
|
wlan0_cmd(struct rpcdata * sd, const char *cmd)
|
2022-07-30 19:44:57 +02:00
|
|
|
{
|
2022-08-14 14:04:58 +02:00
|
|
|
stop();
|
|
|
|
|
2022-08-09 22:35:47 +02:00
|
|
|
struct cw_Conn * conn;
|
2022-07-30 19:44:57 +02:00
|
|
|
wtplist_lock();
|
|
|
|
conn = find_ap(sd->prompt);
|
|
|
|
if (conn==NULL){
|
|
|
|
fprintf(sd->out,"WTP '%s' not found\n",sd->prompt);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
FILE *f=fopen("wlan0.ktv","r");
|
2022-08-14 14:04:58 +02:00
|
|
|
// cw_ktv_read_file(f,sd->update_cfg,conn->msgset->types_tree);
|
2022-07-30 19:44:57 +02:00
|
|
|
//conn->update_cfg=sd->update_cfg;
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
wtplist_unlock();
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2022-07-30 19:44:57 +02:00
|
|
|
}
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
int set_cmd(struct rpcdata *sd, const char *str)
|
2018-05-14 23:30:48 +02:00
|
|
|
{
|
2022-08-24 16:24:57 +02:00
|
|
|
|
|
|
|
cw_Cfg_t *cfg;
|
|
|
|
cfg = cw_cfg_create();
|
|
|
|
|
|
|
|
cw_cfg_read_from_string(str,cfg);
|
|
|
|
|
2022-08-28 09:06:15 +02:00
|
|
|
cw_cfg_fdump(sd->out,cfg,NULL);
|
|
|
|
cw_cfg_copy(cfg,sd->update_cfg,DBG_CFG_UPDATES,"rpc ucfg");
|
2022-08-24 16:24:57 +02:00
|
|
|
|
|
|
|
cw_cfg_destroy(cfg);
|
|
|
|
|
|
|
|
finish_cmd(sd->out);
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
int del_cmd(struct rpcdata *sd, const char *str)
|
2018-05-14 23:30:48 +02:00
|
|
|
{
|
2022-08-28 09:06:15 +02:00
|
|
|
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);
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
2018-05-10 22:40:51 +02:00
|
|
|
|
|
|
|
|
2022-08-19 22:23:55 +02:00
|
|
|
/*
|
2018-05-07 10:57:12 +02:00
|
|
|
void show_cfg (FILE *out, mavl_t ktv)
|
|
|
|
{
|
|
|
|
char value[500];
|
2022-07-31 17:15:32 +02:00
|
|
|
struct cw_Val * data;
|
2018-05-07 10:57:12 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2022-08-19 22:23:55 +02:00
|
|
|
*/
|
2018-05-07 10:57:12 +02:00
|
|
|
|
2022-08-25 11:22:32 +02:00
|
|
|
|
|
|
|
void print_mw(FILE *f, int w, const char * str)
|
|
|
|
{
|
|
|
|
int n,i;
|
|
|
|
fprintf(f, "%.*s",w,str);
|
|
|
|
n=strlen(str);
|
|
|
|
|
|
|
|
if ( n>w ){
|
|
|
|
fprintf(f,"> ");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
n = w-n;
|
|
|
|
|
|
|
|
for(i=0;i<(n+2);i++){
|
|
|
|
fprintf(f,"%c",' ');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
int show_aps (FILE *out)
|
2018-05-07 10:57:12 +02:00
|
|
|
{
|
2022-08-24 16:24:57 +02:00
|
|
|
struct connlist * cl;
|
2018-05-04 13:37:53 +02:00
|
|
|
mavliter_t it;
|
|
|
|
wtplist_lock();
|
|
|
|
|
|
|
|
cl = wtplist_get_connlist();
|
|
|
|
|
|
|
|
|
2018-05-07 10:57:12 +02:00
|
|
|
mavliter_init (&it, cl->by_addr);
|
2022-08-25 11:22:32 +02:00
|
|
|
print_mw (out, 16, "AP Name");
|
|
|
|
print_mw (out, 16, "AP Model");
|
|
|
|
print_mw (out, 14, "Vendor");
|
|
|
|
print_mw (out, 16, "IP ");
|
|
|
|
fprintf(out,"\n");
|
|
|
|
|
2018-05-07 10:57:12 +02:00
|
|
|
mavliter_foreach (&it) {
|
2018-05-04 13:37:53 +02:00
|
|
|
char addr[SOCK_ADDR_BUFSIZE];
|
2022-08-25 11:22:32 +02:00
|
|
|
const char *vendor;
|
|
|
|
|
2022-08-09 22:35:47 +02:00
|
|
|
struct cw_Conn * conn;
|
2018-05-07 10:57:12 +02:00
|
|
|
conn = mavliter_get_ptr (&it);
|
2022-08-25 11:22:32 +02:00
|
|
|
|
2022-08-26 08:05:41 +02:00
|
|
|
print_mw(out,16,cw_cfg_get(conn->remote_cfg, "capwap/wtp-name", "Unknown"));
|
|
|
|
print_mw(out,16,cw_cfg_get(conn->remote_cfg, "capwap/wtp-board-data/model-no", "Unknown"));
|
|
|
|
vendor = cw_cfg_get(conn->remote_cfg, "capwap/wtp-board-data/vendor", "0");
|
2022-08-25 11:22:32 +02:00
|
|
|
print_mw(out,14,vendor);
|
2018-05-07 10:57:12 +02:00
|
|
|
sock_addr2str_p (&conn->addr, addr);
|
2022-08-25 11:22:32 +02:00
|
|
|
print_mw(out,16,addr);
|
|
|
|
fprintf(out,"\n");
|
2022-08-19 22:23:55 +02:00
|
|
|
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
|
|
|
wtplist_unlock();
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
2018-05-07 10:57:12 +02:00
|
|
|
|
2018-05-14 23:30:48 +02:00
|
|
|
|
|
|
|
|
2022-08-09 22:35:47 +02:00
|
|
|
struct cw_Conn * find_ap(const char *name)
|
2018-05-14 23:30:48 +02:00
|
|
|
{
|
2022-08-24 16:24:57 +02:00
|
|
|
|
2018-05-14 23:30:48 +02:00
|
|
|
struct connlist * cl;
|
|
|
|
mavliter_t it;
|
|
|
|
|
|
|
|
cl = wtplist_get_connlist();
|
|
|
|
|
|
|
|
mavliter_init (&it, cl->by_addr);
|
|
|
|
mavliter_foreach (&it) {
|
2022-08-24 16:24:57 +02:00
|
|
|
const char *wtpname;
|
2022-08-09 22:35:47 +02:00
|
|
|
struct cw_Conn * conn;
|
2018-05-14 23:30:48 +02:00
|
|
|
conn = mavliter_get_ptr (&it);
|
|
|
|
|
2022-08-26 08:05:41 +02:00
|
|
|
wtpname = cw_cfg_get (conn->remote_cfg, "capwap/wtp-name", NULL);
|
2018-05-14 23:30:48 +02:00
|
|
|
|
2022-08-24 16:24:57 +02:00
|
|
|
if (wtpname == NULL)
|
|
|
|
continue;
|
2018-05-14 23:30:48 +02:00
|
|
|
|
2022-08-24 16:24:57 +02:00
|
|
|
if(strcmp(wtpname,name)==0){
|
2018-05-14 23:30:48 +02:00
|
|
|
return conn;
|
|
|
|
}
|
2018-05-07 10:57:12 +02:00
|
|
|
|
2018-05-04 13:37:53 +02:00
|
|
|
}
|
2018-05-14 23:30:48 +02:00
|
|
|
return NULL;
|
2022-08-24 16:24:57 +02:00
|
|
|
|
2018-05-04 13:37:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-05-07 23:29:35 +02:00
|
|
|
void con (FILE *out)
|
|
|
|
{
|
2022-08-19 22:23:55 +02:00
|
|
|
stop();
|
|
|
|
|
|
|
|
/*
|
2018-05-07 23:29:35 +02:00
|
|
|
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) {
|
2022-07-31 17:15:32 +02:00
|
|
|
cw_Val_t * result;
|
2018-05-07 23:29:35 +02:00
|
|
|
char addr[SOCK_ADDR_BUFSIZE];
|
|
|
|
char wtp_name[CAPWAP_MAX_WTP_NAME_LEN];
|
2022-08-09 22:35:47 +02:00
|
|
|
struct cw_Conn * conn;
|
2018-05-07 23:29:35 +02:00
|
|
|
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);
|
|
|
|
|
|
|
|
{
|
2022-08-19 22:23:55 +02:00
|
|
|
stop();
|
|
|
|
|
2018-05-07 23:29:35 +02:00
|
|
|
mavl_t update;
|
2022-08-19 22:23:55 +02:00
|
|
|
// update = cw_ktv_create();
|
|
|
|
// cw_ktv_set_byte(update,"radio.255/admin-state",1);
|
|
|
|
// conn->update_cfg=update;
|
2018-05-07 23:29:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fprintf(out,"\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
wtplist_unlock();
|
2022-08-19 22:23:55 +02:00
|
|
|
*/
|
2018-05-07 23:29:35 +02:00
|
|
|
}
|
2018-05-07 10:57:12 +02:00
|
|
|
|
|
|
|
|
2018-05-14 23:30:48 +02:00
|
|
|
struct command * find_cmd(const char *cmd)
|
|
|
|
{
|
2022-08-25 11:22:32 +02:00
|
|
|
struct command * search,*result;
|
2018-05-14 23:30:48 +02:00
|
|
|
|
2022-08-25 11:22:32 +02:00
|
|
|
result=NULL;
|
2018-05-14 23:30:48 +02:00
|
|
|
search = cmdlist;
|
|
|
|
while (search->cmd!=NULL){
|
|
|
|
if (strncmp(cmd,search->cmd,strlen(cmd))==0){
|
2022-08-25 11:22:32 +02:00
|
|
|
if (result==NULL)
|
|
|
|
result = search;
|
|
|
|
else
|
|
|
|
return NULL;
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
|
|
|
search ++;
|
|
|
|
}
|
2022-08-25 11:22:32 +02:00
|
|
|
return result;
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
int execute_cmd (struct rpcdata * sd, const char *str)
|
2018-05-02 11:03:05 +02:00
|
|
|
{
|
|
|
|
char cmd[1024];
|
|
|
|
char args[1024];
|
2018-05-07 23:29:35 +02:00
|
|
|
int n;
|
2022-07-31 17:15:32 +02:00
|
|
|
struct cw_Val_Reader reader;
|
2018-05-14 23:30:48 +02:00
|
|
|
struct command * searchcmd;
|
|
|
|
|
|
|
|
args[0]=0;
|
|
|
|
|
|
|
|
n = sscanf (str, "%s", cmd);
|
|
|
|
if (n<=0)
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-14 23:30:48 +02:00
|
|
|
|
|
|
|
searchcmd = find_cmd(cmd);
|
|
|
|
if (searchcmd!=NULL){
|
|
|
|
if (searchcmd->fun != NULL){
|
2022-08-24 00:29:26 +02:00
|
|
|
return searchcmd->fun(sd, str+strlen(cmd));
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
2022-08-24 00:29:26 +02:00
|
|
|
fprintf(sd->out,"Unknown command: '%s'\n",cmd);
|
|
|
|
finish_cmd(sd->out);
|
2018-05-14 23:30:48 +02:00
|
|
|
}
|
2018-05-07 23:29:35 +02:00
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-14 23:30:48 +02:00
|
|
|
|
|
|
|
|
2022-08-14 12:26:34 +02:00
|
|
|
char key[CW_CFG_MAX_KEY_LEN];
|
2018-05-14 23:30:48 +02:00
|
|
|
char type[128];
|
|
|
|
char val[2048];
|
|
|
|
|
|
|
|
key[0]=0;
|
|
|
|
type[0]=0;
|
|
|
|
val[0]=0;
|
2022-08-19 22:23:55 +02:00
|
|
|
|
|
|
|
stop();
|
|
|
|
// cw_ktv_init_str_reader(&reader,str, strlen(str));
|
|
|
|
// n = cw_ktv_parse_string(&reader, key,type,val);
|
2018-05-14 23:30:48 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-14 23:30:48 +02:00
|
|
|
|
2018-05-02 11:03:05 +02:00
|
|
|
|
2018-05-07 23:29:35 +02:00
|
|
|
n = sscanf (str, "%s%s", cmd, args);
|
|
|
|
|
|
|
|
if (n<=0)
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-07 10:57:12 +02:00
|
|
|
/*printf("CMD: %s, ARGS:\n",cmd);*/
|
2018-05-04 13:37:53 +02:00
|
|
|
|
2018-05-07 10:57:12 +02:00
|
|
|
if (strcmp (cmd, "s") == 0) {
|
2018-05-14 23:30:48 +02:00
|
|
|
show_aps (sd->out);
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-07 10:57:12 +02:00
|
|
|
}
|
2018-05-07 23:29:35 +02:00
|
|
|
|
|
|
|
if (strcmp (cmd, "con")==0){
|
2018-05-14 23:30:48 +02:00
|
|
|
con(sd->out);
|
2022-08-24 00:29:26 +02:00
|
|
|
return 0;
|
2018-05-07 23:29:35 +02:00
|
|
|
}
|
2022-08-24 00:29:26 +02:00
|
|
|
|
|
|
|
return 0;
|
2018-05-02 11:03:05 +02:00
|
|
|
}
|
|
|
|
|
2022-08-23 02:35:54 +02:00
|
|
|
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}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
void rpc_loop (FILE *file, cw_Cfg_t *global_cfg)
|
2022-08-23 19:55:36 +02:00
|
|
|
{
|
2022-08-24 00:29:26 +02:00
|
|
|
struct rpcdata sd;
|
2018-05-02 11:03:05 +02:00
|
|
|
int c;
|
2022-07-29 09:18:55 +02:00
|
|
|
c=0;
|
2022-08-24 00:29:26 +02:00
|
|
|
|
2018-05-02 11:03:05 +02:00
|
|
|
char str[2048];
|
2018-05-14 23:30:48 +02:00
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
sd.in = file;
|
|
|
|
sd.out = file;
|
|
|
|
sd.global_cfg=global_cfg;
|
2022-08-28 09:06:15 +02:00
|
|
|
sd.update_cfg=cw_cfg_create();
|
2022-08-24 00:29:26 +02:00
|
|
|
|
2022-08-23 19:55:36 +02:00
|
|
|
|
2018-05-14 23:30:48 +02:00
|
|
|
sprintf(sd.prompt,"%s","*");
|
2022-08-23 04:08:37 +02:00
|
|
|
sd.quit=0;
|
2022-08-23 19:55:36 +02:00
|
|
|
|
2018-05-02 11:03:05 +02:00
|
|
|
do {
|
2022-08-23 02:35:54 +02:00
|
|
|
|
2018-05-07 23:29:35 +02:00
|
|
|
str[0]=0;
|
2022-08-23 02:35:54 +02:00
|
|
|
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
fgets (str, sizeof (str), file);
|
2022-08-23 02:35:54 +02:00
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
if (execute_cmd (&sd, str)) {
|
|
|
|
break;
|
|
|
|
}
|
2022-08-23 02:35:54 +02:00
|
|
|
|
2018-05-07 10:57:12 +02:00
|
|
|
} while (c != EOF);
|
2018-05-02 11:03:05 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
void * run_rpc_server (void * arg)
|
2022-08-23 02:35:54 +02:00
|
|
|
{
|
|
|
|
char sockstr[SOCK_ADDR_BUFSIZE];
|
|
|
|
struct sockdata * sockdata;
|
|
|
|
int clientsock;
|
|
|
|
struct sockaddr_storage client;
|
|
|
|
socklen_t client_size;
|
|
|
|
|
|
|
|
sockdata = (struct sockdata *)arg;
|
|
|
|
|
|
|
|
memset(&client,0,sizeof(client));
|
|
|
|
client_size=sizeof(client);
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
cw_dbg(DBG_INFO,"Starting RPC Service, listening on: %s (sock fd: %d)",sockdata->name, sockdata->fd);
|
2022-08-23 02:35:54 +02:00
|
|
|
|
|
|
|
while(1){
|
|
|
|
clientsock = accept (sockdata->fd, (struct sockaddr*) &client, &client_size);
|
|
|
|
if (clientsock == -1){
|
|
|
|
cw_log (LOG_ERR, "Accept error '%s', %s", "addr", strerror (errno));
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (clientsock > 0) {
|
|
|
|
sock_addr2str_p (&client, sockstr);
|
2022-08-24 00:29:26 +02:00
|
|
|
cw_dbg (DBG_INFO, "Accepting RPC session from %s", sockstr);
|
|
|
|
rpc_loop (fdopen (clientsock, "a+"),sockdata->global_cfg);
|
2022-08-23 02:35:54 +02:00
|
|
|
close (clientsock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//cw_dbg (DBG_INFO,"Accepting shell session %i, %s", rc, strerror (errno));
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int create_tcp_fd(const char *name)
|
2018-05-02 11:03:05 +02:00
|
|
|
{
|
2022-08-24 16:24:57 +02:00
|
|
|
struct sockaddr_storage server; //, client;
|
2018-05-02 11:03:05 +02:00
|
|
|
|
|
|
|
int rc;
|
2022-08-23 02:35:54 +02:00
|
|
|
const char * addr = name;
|
2022-08-24 16:24:57 +02:00
|
|
|
int sockfd;
|
2018-05-02 11:03:05 +02:00
|
|
|
int yes;
|
|
|
|
|
2018-05-07 10:57:12 +02:00
|
|
|
rc = sock_strtoaddr (addr, (struct sockaddr*) &server);
|
|
|
|
|
|
|
|
if (! rc) {
|
|
|
|
cw_log (LOG_ERR, "Can't parse address '%s', %s", addr, strerror (errno));
|
2022-08-23 02:35:54 +02:00
|
|
|
return -1;
|
2018-05-02 11:03:05 +02:00
|
|
|
}
|
2018-05-07 10:57:12 +02:00
|
|
|
|
|
|
|
sockfd = socket ( ( (struct sockaddr*) &server)->sa_family, SOCK_STREAM, 0);
|
2018-05-02 11:03:05 +02:00
|
|
|
yes = 1;
|
|
|
|
/* reuse address */
|
2018-05-07 10:57:12 +02:00
|
|
|
setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (yes));
|
|
|
|
|
2018-05-02 11:03:05 +02:00
|
|
|
|
|
|
|
/* bind address */
|
2022-08-23 19:55:36 +02:00
|
|
|
rc = bind (sockfd, (struct sockaddr*) &server, sizeof (struct sockaddr));
|
2018-05-07 10:57:12 +02:00
|
|
|
|
|
|
|
if (rc) {
|
|
|
|
cw_log (LOG_ERR, "Can't bind socket address '%s', %s", addr, strerror (errno));
|
2022-08-23 02:35:54 +02:00
|
|
|
return -1;
|
2018-05-02 11:03:05 +02:00
|
|
|
}
|
|
|
|
|
2022-08-23 02:35:54 +02:00
|
|
|
return sockfd;
|
|
|
|
}
|
|
|
|
static int create_unix_fd(const char *name)
|
|
|
|
{
|
2022-08-24 16:24:57 +02:00
|
|
|
//struct sockaddr_storage client;
|
|
|
|
//socklen_t client_size;
|
2022-08-23 02:35:54 +02:00
|
|
|
struct sockaddr_un addr;
|
|
|
|
int rc,fd;
|
|
|
|
|
|
|
|
unlink(name);
|
|
|
|
fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
|
|
|
|
2022-08-23 19:55:36 +02:00
|
|
|
sock_addrinit((struct sockaddr_storage*)&addr,AF_UNIX);
|
2022-08-23 02:35:54 +02:00
|
|
|
strncpy(addr.sun_path, name, sizeof(addr.sun_path)-1);
|
|
|
|
rc = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
|
2018-05-07 10:57:12 +02:00
|
|
|
if (rc) {
|
2022-08-23 02:35:54 +02:00
|
|
|
cw_log (LOG_ERR, "Can't bind socket 'unix:%s', %s", name, strerror (errno));
|
|
|
|
return -1;
|
2018-05-02 11:03:05 +02:00
|
|
|
}
|
2022-08-24 16:24:57 +02:00
|
|
|
//int clientsock = accept (fd, (struct sockaddr*) &client, &client_size);
|
2022-08-23 02:35:54 +02:00
|
|
|
|
|
|
|
return fd;
|
2018-05-02 11:03:05 +02:00
|
|
|
}
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
int start_rpc(cw_Cfg_t *global_cfg)
|
2018-05-02 11:03:05 +02:00
|
|
|
{
|
2022-08-23 02:35:54 +02:00
|
|
|
struct sockdata * sockdata;
|
|
|
|
const char *sockname;
|
2022-08-24 16:24:57 +02:00
|
|
|
int rc; //, type;
|
2022-08-23 02:35:54 +02:00
|
|
|
int fd;
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
rc = cw_cfg_get_bool(global_cfg,"actube/rpc/enable",1);
|
2022-08-23 02:35:54 +02:00
|
|
|
if (!rc)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
sockdata = malloc(sizeof(struct sockdata));
|
|
|
|
if (sockdata==NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
memset(sockdata,0,sizeof(struct sockdata));
|
|
|
|
|
|
|
|
sockdata->global_cfg = global_cfg;
|
|
|
|
sockdata->fd=-1;
|
|
|
|
|
2022-08-24 00:29:26 +02:00
|
|
|
sockname = cw_cfg_get(global_cfg,"actube/rpc/listen",NULL);
|
2022-08-23 02:35:54 +02:00
|
|
|
|
|
|
|
if (sockname==NULL) {
|
2022-08-24 00:29:26 +02:00
|
|
|
cw_log (LOG_ERR, "Can't get RPC listen address from global_cfg 'actube/rpc/listen");
|
2022-08-23 02:35:54 +02:00
|
|
|
goto errX;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strncmp("unix:",sockname,strlen("unix:"))==0){
|
|
|
|
fd = create_unix_fd(strchr(sockname,':')+1);
|
|
|
|
if (fd==-1)
|
|
|
|
goto errX;
|
|
|
|
sockdata->name=cw_strdup(sockname);
|
|
|
|
sockdata->fd=fd;
|
|
|
|
}else if (strncmp("tcp:",sockname,strlen("tcp:"))==0){
|
|
|
|
fd = create_tcp_fd(strchr(sockname,':')+1);
|
|
|
|
if (fd==-1)
|
|
|
|
goto errX;
|
|
|
|
sockdata->name=cw_strdup(sockname);
|
|
|
|
sockdata->fd=fd;
|
|
|
|
}else {
|
|
|
|
fd = create_tcp_fd(sockname);
|
|
|
|
if (fd==-1)
|
|
|
|
goto errX;
|
|
|
|
sockdata->name=cw_strdup(sockname);
|
|
|
|
sockdata->fd=fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rc = listen (sockdata->fd, 5);
|
|
|
|
if (rc) {
|
|
|
|
cw_log (LOG_ERR, "Can't listen on address '%s', %s", "addr", strerror (errno));
|
|
|
|
goto errX;
|
|
|
|
}
|
|
|
|
|
2018-05-02 11:03:05 +02:00
|
|
|
pthread_t thread;
|
2022-08-24 00:29:26 +02:00
|
|
|
pthread_create (&thread, NULL, run_rpc_server,
|
2022-08-23 02:35:54 +02:00
|
|
|
sockdata);
|
|
|
|
return 1;
|
|
|
|
errX:
|
|
|
|
if (sockdata->fd!=-1)
|
|
|
|
close(sockdata->fd);
|
|
|
|
if (sockdata->name)
|
2022-08-23 19:55:36 +02:00
|
|
|
free((void*)sockdata->name);
|
2022-08-23 02:35:54 +02:00
|
|
|
|
|
|
|
free(sockdata);
|
|
|
|
return 0;
|
2018-05-07 10:57:12 +02:00
|
|
|
}
|