From 1961ec6d58ea3e641a5df86df0c1ffb9527eff4f Mon Sep 17 00:00:00 2001 From: darkcoven Date: Thu, 17 Nov 2011 12:00:00 +0100 Subject: [PATCH] CLI: reunited commands in one file. CLI: added command autocompletion. Added storm filtering support. --- cli/admin.c | 166 +++++++------ cli/com_firmware.c | 64 ----- cli/com_list.c | 26 -- cli/com_login.c | 32 --- cli/com_name.c | 80 ------ cli/com_password.c | 60 ----- cli/com_ports.c | 116 --------- cli/com_quit.c | 20 -- cli/com_scan.c | 31 --- cli/command.c | 56 ----- cli/command.h | 20 -- cli/commands.c | 589 +++++++++++++++++++++++++++++++++++++++++++++ cli/commands.h | 31 +++ cli/common.c | 163 +++++++++++++ cli/common.h | 31 +-- lib/ngadmin.h | 17 ++ lib/src/ngadmin.c | 187 +++++++++++++- lib/src/protocol.c | 15 +- lib/src/protocol.h | 3 + 19 files changed, 1111 insertions(+), 596 deletions(-) delete mode 100644 cli/com_firmware.c delete mode 100644 cli/com_list.c delete mode 100644 cli/com_login.c delete mode 100644 cli/com_name.c delete mode 100644 cli/com_password.c delete mode 100644 cli/com_ports.c delete mode 100644 cli/com_quit.c delete mode 100644 cli/com_scan.c delete mode 100644 cli/command.c delete mode 100644 cli/command.h create mode 100644 cli/commands.c create mode 100644 cli/commands.h create mode 100644 cli/common.c diff --git a/cli/admin.c b/cli/admin.c index 523a96c..2644d38 100644 --- a/cli/admin.c +++ b/cli/admin.c @@ -4,74 +4,117 @@ #include #include -#include "command.h" #include "common.h" +#include "commands.h" -#define MAXCOM 8 +#define MAXCOM 32 +int cont=1; -int cont=1; + +const struct TreeNode* getSubCom (char **com, int n, int *t) { + + int i; + const struct TreeNode *cur, *next; + + + cur=&coms; + for (i=0; isub==NULL ) break; + + // search sub command in sub command array + for (next=cur->sub; next->name!=NULL && strcmp(next->name, com[i])!=0; ++next); + + // sub command not found, exit + if ( next->name==NULL ) { + next=NULL; + break; + } + + // next command is now the current one + cur=next; + + } + + *t=i; + + + return cur; + +} -static const struct TreeNode rootNode={.sub={ - &com_quit, - &com_login, - &com_scan, - &com_ports, - &com_password, - &com_list, - &com_firmware, - &com_name, - NULL -}}; +const struct TreeNode *compcur; -void printErrCode (int err) { + + +char* my_generator (const char* text, int state) { + + static int len; + static const struct TreeNode *tn; + const char *name; + + + if ( compcur==NULL ) { // sub command not found + return NULL; + } else if ( state==0 ) { + tn=compcur->sub; + if ( tn==NULL ) { // terminal command + return NULL; + } + len=strlen(text); + } + - switch ( err ) { - case ERR_OK: /*printf("ok\n");*/ break; - case ERR_NET: printf("network error\n"); break; - case ERR_NOTLOG: printf("no switch selected\n"); break; - case ERR_BADPASS: printf("wrong password\n"); break; - case ERR_BADID: printf("bad switch id\n"); break; - case ERR_INVARG: printf("invalid argument\n"); break; - case ERR_TIMEOUT: printf("timeout\n"); break; - default: printf("unknown status code (%i)\n", err); + while ( (name=tn->name)!=NULL ) { + ++tn; + + if ( strncmp(name, text, len)==0 ) { + return strdup(name); + } + } + return NULL; + } -void displaySwitchTab (const struct swi_attr *sa, int nb) { +char** my_completion (const char *text, int start, int end UNUSED) { - int i=0; + char **matches=NULL; + char *line, *com[MAXCOM]; + int i, n; - if ( nb==0 ) { - printf("no switch found\n"); - return; - } + memset(com, 0, MAXCOM*sizeof(char*)); + line=strdup(rl_line_buffer); + line[start]=0; + trim(line, start); + n=explode(line, com, MAXCOM); + free(line); - printf("Num\tMac\t\t\tProduct\t\tName\t\t\tIP/mask\t\t\t\tDHCP\tPorts\tFirmware\n"); + compcur=getSubCom(com, n, &i); - for (i=0; i "))==NULL ) goto end; trim(line, strlen(line)); if ( *line!=0 ) add_history(line); n=explode(line, com, MAXCOM); free(line); - - i=0; - for (next=&rootNode; isub; (next=*tab)!=NULL && strcmp(next->name, com[i])!=0; ++tab); - if ( next==NULL ) break; + if ( n==0 ) { + continue; } + cur=getSubCom(com, n, &i); - if ( ihasArgs ) { // left "commands" are in fact parameters - cur->comfunc(cur, n-i, (const char**)&com[i], nga); - } else { - if ( i==0 ) { - printf("unknown command\n"); - } else { - printf("unknown %s subcommand\n", com[i-1]); - } + cur->comfunc(n-i, (const char**)&com[i], nga); + } else if ( i==0 ) { // root command + printf("unknown command\n"); + } else if ( cur->sub==NULL ) { // terminal command without arguments + printf("%s as no subcommand and takes no parameter\n", com[i-1]); + } else { // intermediate command + printf("unknown %s subcommand\n", com[i-1]); } } else { - cur=next; - if ( cur->comfunc==NULL ) { + if ( cur->comfunc==NULL ) { // intermediate command // print available subcommands - for (tab=cur->sub; (next=*tab)!=NULL; ++tab) { + for (next=cur->sub; next!=NULL && next->name!=NULL; ++next) { printf("%s ", next->name); } printf("\n"); } else { // terminal command - - cur->comfunc(cur, 0, NULL, nga); - + cur->comfunc(0, NULL, nga); } - } - - /* - if ( n==0 ) { - // nothing: do nothing - - } else if ( strcmp(com[0], "timeout")==0 ) { - // } - */ + for (i=0; ifirmware); - - - end: - - return ret; - -} - - - -static bool do_firmware_upgrade (const struct TreeNode *tn UNUSED, int nb, const char **com UNUSED, struct ngadmin *nga) { - - const struct swi_attr *sa; - bool ret=true; - - - if ( nb!=1 ) { - printf("Usage: firmware upgrade \n"); - ret=false; - } - - if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { - printf("must be logged\n"); - ret=false; - goto end; - } - - printf("not implemented yet\n"); - - - end: - - return ret; - -} - - - -static const struct TreeNode com_firmware_show=COM("show", do_firmware_show, false, NULL); -static const struct TreeNode com_firmware_upgrade=COM("upgrade", do_firmware_upgrade, true, NULL); - -const struct TreeNode com_firmware=COM("firmware", NULL, false, &com_firmware_show, &com_firmware_upgrade, NULL); - - - diff --git a/cli/com_list.c b/cli/com_list.c deleted file mode 100644 index 3c8eb8c..0000000 --- a/cli/com_list.c +++ /dev/null @@ -1,26 +0,0 @@ - -#include "common.h" - - - - -static bool do_list (const struct TreeNode *tn UNUSED, int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { - - int n; - const struct swi_attr *sa; - - - sa=ngadmin_getSwitchTab(nga, &n); - displaySwitchTab(sa, n); - - - return true; - -} - - - -const struct TreeNode com_list=COM("list", do_list, false, NULL); - - - diff --git a/cli/com_login.c b/cli/com_login.c deleted file mode 100644 index e50e096..0000000 --- a/cli/com_login.c +++ /dev/null @@ -1,32 +0,0 @@ - -#include "common.h" - - - - -static bool do_login (const struct TreeNode *tn UNUSED, int nb, const char **com, struct ngadmin *nga) { - - int i; - - - if ( nb!=1 ) { - printf("Usage: login \n"); - return false; - } - - - i=strtol(com[0], NULL, 0); - i=ngadmin_login(nga, i); - printErrCode(i); - - - return true; - -} - - - -const struct TreeNode com_login=COM("login", do_login, true, NULL); - - - diff --git a/cli/com_name.c b/cli/com_name.c deleted file mode 100644 index 54b152e..0000000 --- a/cli/com_name.c +++ /dev/null @@ -1,80 +0,0 @@ - -#include "common.h" - - - - -static bool do_name_show (const struct TreeNode *tn UNUSED, int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { - - const struct swi_attr *sa; - - - if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { - printf("must be logged\n"); - return false; - } - - puts(sa->name); - - - return true; - -} - - - -static bool do_name_set (const struct TreeNode *tn UNUSED, int nb, const char **com, struct ngadmin *nga) { - - int i; - const struct swi_attr *sa; - - - if ( nb!=1 ) { - printf("Usage: name set \n"); - return false; - } - - if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { - printf("must be logged\n"); - return false; - } - - i=ngadmin_setName(nga, com[0]); - printErrCode(i); - - - return true; - -} - - - -static bool do_name_clear (const struct TreeNode *tn UNUSED, int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { - - int i; - const struct swi_attr *sa; - - - if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { - printf("must be logged\n"); - return false; - } - - i=ngadmin_setName(nga, NULL); - printErrCode(i); - - - return true; - -} - - - -static struct TreeNode com_name_show=COM("show", do_name_show, false, NULL); -static struct TreeNode com_name_set=COM("set", do_name_set, true, NULL); -static struct TreeNode com_name_clear=COM("clear", do_name_clear, false, NULL); - -const struct TreeNode com_name=COM("name", NULL, false, &com_name_show, &com_name_set, &com_name_clear, NULL); - - - diff --git a/cli/com_password.c b/cli/com_password.c deleted file mode 100644 index 4b1f184..0000000 --- a/cli/com_password.c +++ /dev/null @@ -1,60 +0,0 @@ - -#include "common.h" - - - - -static bool do_password_change (const struct TreeNode *tn UNUSED, int nb, const char **com, struct ngadmin *nga) { - - int i; - const struct swi_attr *sa; - - - if ( nb!=1 ) { - printf("Usage: password set \n"); - return false; - } - - if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { - printf("must be logged\n"); - return false; - } - - i=ngadmin_changePassword(nga, com[0]); - printErrCode(i); - - - return true; - -} - - - -static bool do_password_set (const struct TreeNode *tn UNUSED, int nb, const char **com, struct ngadmin *nga) { - - int i; - - - if ( nb!=1 ) { - printf("Usage: password set \n"); - return false; - } - - i=ngadmin_setPassword(nga, com[0]); - printErrCode(i); - - - return true; - -} - - - - -static const struct TreeNode com_password_change=COM("change", do_password_change, true, NULL); -static const struct TreeNode com_password_set=COM("set", do_password_set, true, NULL); - -const struct TreeNode com_password=COM("password", NULL, false, &com_password_change, &com_password_set, NULL); - - - diff --git a/cli/com_ports.c b/cli/com_ports.c deleted file mode 100644 index b520218..0000000 --- a/cli/com_ports.c +++ /dev/null @@ -1,116 +0,0 @@ - -#include "common.h" - - - - -static bool do_ports_state (const struct TreeNode *tn UNUSED, int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { - - int i; - const struct swi_attr *sa; - unsigned char *ports=NULL; - bool ret=true; - - - if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { - printf("must be logged\n"); - ret=false; - goto end; - } - - - ports=malloc(sa->ports*sizeof(unsigned char)); - if ( (i=ngadmin_getPortsStatus(nga, ports))<0 ) { - printErrCode(i); - ret=false; - goto end; - } - - for (i=0; iports; i++) { - printf("port %i: ", i+1); - switch ( ports[i] ) { - case 0: printf("down"); break; - case SPEED_10: printf("up, 10M"); break; - case SPEED_100: printf("up, 100M"); break; - case SPEED_1000: printf("up, 1000M"); break; - default: printf("unknown (%i)", ports[i]); - } - putchar('\n'); - } - - end: - free(ports); - - - return ret; - -} - - - -static bool do_ports_stats_show (const struct TreeNode *tn UNUSED, int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { - - int i; - const struct swi_attr *sa; - bool ret=true; - struct port_stats *ps=NULL; - - - if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { - printf("must be logged\n"); - ret=false; - goto end; - } - - ps=calloc(sa->ports, sizeof(struct port_stats)); - if ( (i=ngadmin_getPortsStatistics(nga, ps))<0 ) { - printErrCode(i); - ret=false; - goto end; - } - - printf("Port\tReceived\tSent\t\tCRC errors\n"); - for (i=0; iports; ++i) { - printf("%i\t%8llu\t%8llu\t%8llu\n", i+1, ps[i].recv, ps[i].sent, ps[i].crc); - } - - end: - free(ps); - - - return ret; - -} - - - -static bool do_ports_stats_reset (const struct TreeNode *tn UNUSED, int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { - - int i; - - - if ( ngadmin_getCurrentSwitch(nga)==NULL ) { - printf("must be logged\n"); - return false; - } - - i=ngadmin_resetPortsStatistics(nga); - printErrCode(i); - - - return true; - -} - - - -static const struct TreeNode com_ports_state=COM("state", do_ports_state, false, NULL); - -static const struct TreeNode com_ports_stats_show=COM("show", do_ports_stats_show, false, NULL); -static const struct TreeNode com_ports_stats_reset=COM("reset", do_ports_stats_reset, false, NULL); -static const struct TreeNode com_ports_stats=COM("stats", NULL, false, &com_ports_stats_reset, &com_ports_stats_show, NULL); - -const struct TreeNode com_ports=COM("ports", NULL, false, &com_ports_state, &com_ports_stats, NULL); - - - diff --git a/cli/com_quit.c b/cli/com_quit.c deleted file mode 100644 index 61dc5ce..0000000 --- a/cli/com_quit.c +++ /dev/null @@ -1,20 +0,0 @@ - -#include "common.h" - - - - -static bool do_quit (const struct TreeNode *tn UNUSED, int nb UNUSED, const char **com UNUSED, struct ngadmin *nga UNUSED) { - - cont=0; - - return true; - -} - - - -const struct TreeNode com_quit=COM("quit", do_quit, false, NULL); - - - diff --git a/cli/com_scan.c b/cli/com_scan.c deleted file mode 100644 index 51b24b8..0000000 --- a/cli/com_scan.c +++ /dev/null @@ -1,31 +0,0 @@ - -#include "common.h" - - - - -static bool do_scan (const struct TreeNode *tn UNUSED, int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { - - int i; - const struct swi_attr *sa; - - - if ( (i=ngadmin_scan(nga))<0 ) { - printErrCode(i); - return false; - } - - sa=ngadmin_getSwitchTab(nga, &nb); - displaySwitchTab(sa, nb); - - - return true; - -} - - - -const struct TreeNode com_scan=COM("scan", do_scan, false, NULL); - - - diff --git a/cli/command.c b/cli/command.c deleted file mode 100644 index 943d148..0000000 --- a/cli/command.c +++ /dev/null @@ -1,56 +0,0 @@ - -#include "command.h" - - - - -// ---------------------------- -int trim (char *txt, int start) { - - char *p, c; - - - if ( txt==NULL ) { - return 0; - } - - //for (p=txt; *p!=0; p++); - p=txt+start; - for (p--; p>=txt && ( (c=*p)==' ' || c=='\n' ); *p--=0); - - - return p-txt+1; - -} - - - -// -------------------------------------------------------- -int explode (const char *commande, char** tab, int maximum) { - - const char *start, *end; - char c; - int n=0, len; - - - for (end=commande; ; n++) { - - for (start=end; (c=*start)==' ' && c!=0; start++); - for (end=start; ( (c=*end)!=' ' || n>=maximum-1 ) && c!=0; end++); - - if ( (len=end-start)==0 ) { - break; - } - - tab[n]=malloc(sizeof(char)*(len+1)); - memcpy(tab[n], start, len); - tab[n][len]=0; - - } - - - return n; - -} - - diff --git a/cli/command.h b/cli/command.h deleted file mode 100644 index 0689b22..0000000 --- a/cli/command.h +++ /dev/null @@ -1,20 +0,0 @@ - -#ifndef DEF_COMMAND -#define DEF_COMMAND - - -#include -#include - - - -// -int trim (char *txt, int start); - -// -int explode (const char *commande, char** tab, int maximum); - - - -#endif - diff --git a/cli/commands.c b/cli/commands.c new file mode 100644 index 0000000..7ed9020 --- /dev/null +++ b/cli/commands.c @@ -0,0 +1,589 @@ + +#include "commands.h" + + + + +// ============================================================================= +// firmware + + +static bool do_firmware_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + const struct swi_attr *sa; + bool ret=true; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + puts(sa->firmware); + + + end: + + return ret; + +} + + + +static bool do_firmware_upgrade (int nb, const char **com UNUSED, struct ngadmin *nga) { + + const struct swi_attr *sa; + bool ret=true; + + + if ( nb!=1 ) { + printf("Usage: firmware upgrade \n"); + ret=false; + } + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + printf("not implemented yet\n"); + + + end: + + return ret; + +} + + + +// ============================================================================= +// list + + +static bool do_list (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int n; + const struct swi_attr *sa; + + + sa=ngadmin_getSwitchTab(nga, &n); + displaySwitchTab(sa, n); + + + return true; + +} + + + +// ============================================================================= +// login + + +static bool do_login (int nb, const char **com, struct ngadmin *nga) { + + int i; + + + if ( nb!=1 ) { + printf("Usage: login \n"); + return false; + } + + + i=strtol(com[0], NULL, 0); + i=ngadmin_login(nga, i); + printErrCode(i); + + + return true; + +} + + + +// ============================================================================= +// name + + +static bool do_name_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + const struct swi_attr *sa; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + return false; + } + + puts(sa->name); + + + return true; + +} + + + +static bool do_name_set (int nb, const char **com, struct ngadmin *nga) { + + int i; + const struct swi_attr *sa; + + + if ( nb!=1 ) { + printf("Usage: name set \n"); + return false; + } + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + return false; + } + + i=ngadmin_setName(nga, com[0]); + printErrCode(i); + + + return true; + +} + + + +static bool do_name_clear (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int i; + const struct swi_attr *sa; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + return false; + } + + i=ngadmin_setName(nga, NULL); + printErrCode(i); + + + return true; + +} + + + +// ============================================================================= +// password + + +static bool do_password_change (int nb, const char **com, struct ngadmin *nga) { + + int i; + const struct swi_attr *sa; + + + if ( nb!=1 ) { + printf("Usage: password set \n"); + return false; + } + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + return false; + } + + i=ngadmin_changePassword(nga, com[0]); + printErrCode(i); + + + return true; + +} + + + +static bool do_password_set (int nb, const char **com, struct ngadmin *nga) { + + int i; + + + if ( nb!=1 ) { + printf("Usage: password set \n"); + return false; + } + + i=ngadmin_setPassword(nga, com[0]); + printErrCode(i); + + + return true; + +} + + + +// ============================================================================= +// ports + + +static bool do_ports_state (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int i; + const struct swi_attr *sa; + unsigned char *ports=NULL; + bool ret=true; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + + ports=malloc(sa->ports*sizeof(unsigned char)); + if ( (i=ngadmin_getPortsStatus(nga, ports))<0 ) { + printErrCode(i); + ret=false; + goto end; + } + + for (i=0; iports; i++) { + printf("port %i: ", i+1); + switch ( ports[i] ) { + case 0: printf("down"); break; + case SPEED_10: printf("up, 10M"); break; + case SPEED_100: printf("up, 100M"); break; + case SPEED_1000: printf("up, 1000M"); break; + default: printf("unknown (%i)", ports[i]); + } + putchar('\n'); + } + + end: + free(ports); + + + return ret; + +} + + + +static bool do_ports_stats_reset (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int i; + + + if ( ngadmin_getCurrentSwitch(nga)==NULL ) { + printf("must be logged\n"); + return false; + } + + i=ngadmin_resetPortsStatistics(nga); + printErrCode(i); + + + return true; + +} + + + +static bool do_ports_stats_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int i; + const struct swi_attr *sa; + bool ret=true; + struct port_stats *ps=NULL; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + ps=calloc(sa->ports, sizeof(struct port_stats)); + if ( (i=ngadmin_getPortsStatistics(nga, ps))<0 ) { + printErrCode(i); + ret=false; + goto end; + } + + printf("Port\tReceived\tSent\t\tCRC errors\n"); + for (i=0; iports; ++i) { + printf("%i\t%8llu\t%8llu\t%8llu\n", i+1, ps[i].recv, ps[i].sent, ps[i].crc); + } + + end: + free(ps); + + + return ret; + +} + + + +// ============================================================================= +// quit + + +static bool do_quit (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga UNUSED) { + + cont=0; + + return true; + +} + + + +// ============================================================================= +// scan + + +static bool do_scan (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int i; + const struct swi_attr *sa; + + + if ( (i=ngadmin_scan(nga))<0 ) { + printErrCode(i); + return false; + } + + sa=ngadmin_getSwitchTab(nga, &nb); + displaySwitchTab(sa, nb); + + + return true; + +} + + + +// ============================================================================= +// stormfilt + + +static bool do_stormfilt_enable (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int i; + const struct swi_attr *sa; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + return false; + } + + i=ngadmin_setStormFilterState(nga, 1); + printErrCode(i); + + + return true; + +} + + + +static bool do_stormfilt_disable (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int i; + const struct swi_attr *sa; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + return false; + } + + i=ngadmin_setStormFilterState(nga, 0); + printErrCode(i); + + + return true; + +} + + + +static bool do_stormfilt_reset (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int i, *ports=NULL; + const struct swi_attr *sa; + bool ret=true; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + + ports=malloc(sa->ports*sizeof(int)); + for (i=0; iports; ++i) { + ports[i]=BITRATE_NOLIMIT; + } + + i=ngadmin_setStormFilterValues(nga, ports); + printErrCode(i); + + + end: + free(ports); + + return ret; + +} + + + +static bool do_stormfilt_set (int nb, const char **com, struct ngadmin *nga) { + + int i, p, *ports=NULL; + const struct swi_attr *sa; + bool ret=true; + + + if ( nb==0 ) { + printf("Usage: stormfilt set [ ...]\n"); + ret=false; + goto end; + } + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + + ports=malloc(sa->ports*sizeof(int)); + for (i=0; iports; ++i) { + ports[i]=BITRATE_UNSPEC; + } + + for (i=0; isa->ports ) continue; + ports[p-1]=parseBitrate(com[i+1]); + } + + + i=ngadmin_setStormFilterValues(nga, ports); + printErrCode(i); + + + end: + free(ports); + + return ret; + +} + + + +static bool do_stormfilt_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int i, s, ret=true, *ports=NULL; + const struct swi_attr *sa; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + if ( (i=ngadmin_getStormFilterState(nga, &s))!=ERR_OK ) { + printErrCode(i); + ret=false; + goto end; + } + + + if ( !s ) { + printf("storm filter is disabled\n"); + goto end; + } + + printf("storm filter is enabled\n"); + + ports=malloc(sa->ports*sizeof(int)); + if ( (i=ngadmin_getStormFilterValues(nga, ports))!=ERR_OK ) { + printErrCode(i); + ret=false; + goto end; + } + + for (i=0; iports; ++i) { + printf("port %i: ", i+1); + printBitrate(ports[i]); + } + + end: + free(ports); + + return ret; + +} + + + +// ============================================================================= + + +COM_ROOT_START(coms) + + COM_START(firmware) + COM_TERM(show, do_firmware_show, false) + COM_TERM(upgrade, do_firmware_upgrade, true) + COM_END + + COM_TERM(list, do_list, false) + + COM_TERM(login, do_login, true) + + COM_START(name) + COM_TERM(show, do_name_show, false) + COM_TERM(set, do_name_set, true) + COM_TERM(clear, do_name_clear, false) + COM_END + + COM_START(password) + COM_TERM(change, do_password_change, true) + COM_TERM(set, do_password_set, true) + COM_END + + COM_START(ports) + COM_TERM(state, do_ports_state, false) + COM_START(stats) + COM_TERM(reset, do_ports_stats_reset, false) + COM_TERM(show, do_ports_stats_show, false) + COM_END + COM_END + + COM_TERM(quit, do_quit, false) + + COM_TERM(scan, do_scan, false) + + COM_START(stormfilt) + COM_TERM(enable, do_stormfilt_enable, false) + COM_TERM(disable, do_stormfilt_disable, false) + COM_TERM(reset, do_stormfilt_reset, false) + COM_TERM(set, do_stormfilt_set, true) + COM_TERM(show, do_stormfilt_show, false) + COM_END + +COM_ROOT_END + + + diff --git a/cli/commands.h b/cli/commands.h new file mode 100644 index 0000000..f289e71 --- /dev/null +++ b/cli/commands.h @@ -0,0 +1,31 @@ + +#ifndef DEF_COMMANDS +#define DEF_COMMANDS + + +#include "common.h" + + + + +struct TreeNode { + const char *name; + bool (* const comfunc)(int, const char**, struct ngadmin*); + bool hasArgs; + const struct TreeNode *sub; +}; + + +#define COM_ROOT_START(v) const struct TreeNode v={.name="", .comfunc=NULL, .hasArgs=false, .sub=(const struct TreeNode[]){ +#define COM_ROOT_END {.name=NULL, .comfunc=NULL, .hasArgs=false, .sub=NULL}}}; +#define COM_START(nam) {.name=#nam, .comfunc=NULL, .hasArgs=false, .sub=(const struct TreeNode[]){ +#define COM_TERM(nam, func, args) {.name=#nam, .comfunc=func, .hasArgs=args, .sub=NULL}, +#define COM_END {.name=NULL, .comfunc=NULL, .hasArgs=false, .sub=NULL}}}, + + +extern const struct TreeNode coms; + + + +#endif + diff --git a/cli/common.c b/cli/common.c new file mode 100644 index 0000000..224344b --- /dev/null +++ b/cli/common.c @@ -0,0 +1,163 @@ + +#include "common.h" + + + + + + + +void printErrCode (int err) { + + + switch ( err ) { + case ERR_OK: /*printf("ok\n");*/ break; + case ERR_NET: printf("network error\n"); break; + case ERR_NOTLOG: printf("no switch selected\n"); break; + case ERR_BADPASS: printf("wrong password\n"); break; + case ERR_BADID: printf("bad switch id\n"); break; + case ERR_INVARG: printf("invalid argument\n"); break; + case ERR_TIMEOUT: printf("timeout\n"); break; + default: printf("unknown status code (%i)\n", err); + } + + +} + + + +void printBitrate (int br) { + + + switch ( br ) { + case BITRATE_UNSPEC: printf("unspecified\n"); break; + case BITRATE_NOLIMIT: printf("unlimited\n"); break; + case BITRATE_512K: printf("512K\n"); break; + case BITRATE_1M: printf("1M\n"); break; + case BITRATE_2M: printf("2M\n"); break; + case BITRATE_4M: printf("4M\n"); break; + case BITRATE_8M: printf("8M\n"); break; + case BITRATE_16M: printf("16M\n"); break; + case BITRATE_32M: printf("32M\n"); break; + case BITRATE_64M: printf("64M\n"); break; + case BITRATE_128M: printf("128M\n"); break; + case BITRATE_256M: printf("256M\n"); break; + case BITRATE_512M: printf("512M\n"); break; + default: printf("unknown (%i)\n", br); + } + + +} + + +struct BrStr { + const char *str; + int br; +}; + +static const struct BrStr bitrates[]={ + {"nl", BITRATE_NOLIMIT}, + {"512K", BITRATE_512K}, + {"1M", BITRATE_1M}, + {"2M", BITRATE_2M}, + {"4M", BITRATE_4M}, + {"8M", BITRATE_8M}, + {"16M", BITRATE_16M}, + {"32M", BITRATE_32M}, + {"64M", BITRATE_64M}, + {"128M", BITRATE_128M}, + {"256M", BITRATE_256M}, + {"512M", BITRATE_512M}, + {NULL, BITRATE_UNSPEC} +}; + + +int parseBitrate (const char *s) { + + const struct BrStr *b; + + + for (b=bitrates; b->str!=NULL && strcasecmp(b->str, s)!=0; ++b); + + + return b->br; + +} + + + +void displaySwitchTab (const struct swi_attr *sa, int nb) { + + int i=0; + + + if ( nb==0 ) { + printf("no switch found\n"); + return; + } + + + printf("Num\tMac\t\t\tProduct\t\tName\t\t\tIP/mask\t\t\t\tDHCP\tPorts\tFirmware\n"); + + for (i=0; i=txt && ( (c=*p)==' ' || c=='\n' ); *p--=0); + + + return p-txt+1; + +} + + + +// -------------------------------------------------------- +int explode (const char *commande, char** tab, int maximum) { + + const char *start, *end; + char c; + int n=0, len; + + + for (end=commande; ; n++) { + + for (start=end; (c=*start)==' ' && c!=0; start++); + for (end=start; ( (c=*end)!=' ' || n>=maximum-1 ) && c!=0; end++); + + if ( (len=end-start)==0 ) { + break; + } + + tab[n]=malloc(sizeof(char)*(len+1)); + memcpy(tab[n], start, len); + tab[n][len]=0; + + } + + + return n; + +} + + diff --git a/cli/common.h b/cli/common.h index ee845af..ea24327 100644 --- a/cli/common.h +++ b/cli/common.h @@ -5,21 +5,12 @@ #include #include +#include #include #define UNUSED __attribute__((unused)) -#define COM(nam, func, args, ...) {.name=nam, .comfunc=func, .hasArgs=args, .sub={__VA_ARGS__}} - - - -struct TreeNode { - const char *name; - bool (* const comfunc)(const struct TreeNode*, int, const char**, struct ngadmin*); - bool hasArgs; - const struct TreeNode *sub[]; -}; @@ -27,20 +18,16 @@ extern int cont; -extern const struct TreeNode com_quit; -extern const struct TreeNode com_login; -extern const struct TreeNode com_scan; -extern const struct TreeNode com_ports; -extern const struct TreeNode com_password; -extern const struct TreeNode com_list; -extern const struct TreeNode com_list; -extern const struct TreeNode com_firmware; -extern const struct TreeNode com_name; - - - void displaySwitchTab (const struct swi_attr *sa, int nb); void printErrCode (int err); +void printBitrate (int br); +int parseBitrate (const char *s); + +// +int trim (char *txt, int start); + +// +int explode (const char *commande, char** tab, int maximum); diff --git a/lib/ngadmin.h b/lib/ngadmin.h index 824b0dd..69286c7 100644 --- a/lib/ngadmin.h +++ b/lib/ngadmin.h @@ -48,6 +48,7 @@ #define PRIO_NORM 3 #define PRIO_LOW 4 +#define BITRATE_UNSPEC -1 #define BITRATE_NOLIMIT 0 #define BITRATE_512K 1 #define BITRATE_1M 2 @@ -146,6 +147,22 @@ int ngadmin_resetPortsStatistics (struct ngadmin *nga) EXPORT; int ngadmin_changePassword (struct ngadmin *nga, const char* pass) EXPORT; +// +int ngadmin_getStormFilterState (struct ngadmin *nga, int *s) EXPORT; + + +// +int ngadmin_setStormFilterState (struct ngadmin *nga, int s) EXPORT; + + +// +int ngadmin_getStormFilterValues (struct ngadmin *nga, int *ports) EXPORT; + + +// +int ngadmin_setStormFilterValues (struct ngadmin *nga, const int *ports) EXPORT; + + #endif diff --git a/lib/src/ngadmin.c b/lib/src/ngadmin.c index bdcc9b5..312ab58 100644 --- a/lib/src/ngadmin.c +++ b/lib/src/ngadmin.c @@ -404,7 +404,6 @@ int ngadmin_getPortsStatistics (struct ngadmin *nga, struct port_stats *ps) { return ret; - } @@ -499,3 +498,189 @@ int ngadmin_changePassword (struct ngadmin *nga, const char* pass) { } + +// ---------------------------------------------------------- +int ngadmin_getStormFilterState (struct ngadmin *nga, int *s) { + + List *attr; + ListNode *ln; + struct attr *at; + int ret=ERR_OK, i; + + + if ( nga==NULL || s==NULL ) { + return ERR_INVARG; + } else if ( nga->current==NULL ) { + return ERR_NOTLOG; + } + + + attr=createEmptyList(); + pushBackList(attr, newEmptyAttr(ATTR_STORM_ENABLE)); + pushBackList(attr, newEmptyAttr(ATTR_END)); + i=sendNgPacket(nga, CODE_READ_REQ, &nga->current->mac, ++nga->seq, attr); + destroyList(attr, (void(*)(void*))freeAttr); + if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL, &nga->current->mac, nga->seq))==NULL ) { + ret=ERR_NET; + goto end; + } + + for (ln=attr->first; ln!=NULL; ln=ln->next) { + at=ln->data; + if ( at->attr==ATTR_STORM_ENABLE && at->size>=1 ) { + *s= *(char*)at->data!=0 ; + break; + } + } + + destroyList(attr, (void(*)(void*))freeAttr); + + + end: + + return ret; + +} + + + +// --------------------------------------------------------- +int ngadmin_setStormFilterState (struct ngadmin *nga, int s) { + + List *attr; + int ret=ERR_OK, i; + char err; + unsigned short attr_error; + + + if ( nga==NULL ) { + return ERR_INVARG; + } else if ( nga->current==NULL ) { + return ERR_NOTLOG; + } + + + attr=createEmptyList(); + pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); + pushBackList(attr, newByteAttr(ATTR_STORM_ENABLE, s!=0)); + pushBackList(attr, newEmptyAttr(ATTR_END)); + i=sendNgPacket(nga, CODE_WRITE_REQ, &nga->current->mac, ++nga->seq, attr); + destroyList(attr, (void(*)(void*))freeAttr); + if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error, &nga->current->mac, nga->seq))==NULL ) { + ret=ERR_NET; + goto end; + } + + destroyList(attr, (void(*)(void*))freeAttr); + + if ( err==7 && attr_error==ATTR_PASSWORD ) { + ret=ERR_BADPASS; + goto end; + } + + + end: + + return ret; + +} + + + +// --------------------------------------------------------------- +int ngadmin_getStormFilterValues (struct ngadmin *nga, int *ports) { + + List *attr; + ListNode *ln; + struct attr *at; + int ret=ERR_OK, i; + + + if ( nga==NULL || ports==NULL ) { + return ERR_INVARG; + } else if ( nga->current==NULL ) { + return ERR_NOTLOG; + } + + + attr=createEmptyList(); + pushBackList(attr, newEmptyAttr(ATTR_STORM_BITRATE)); + pushBackList(attr, newEmptyAttr(ATTR_END)); + i=sendNgPacket(nga, CODE_READ_REQ, &nga->current->mac, ++nga->seq, attr); + destroyList(attr, (void(*)(void*))freeAttr); + if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL, &nga->current->mac, nga->seq))==NULL ) { + ret=ERR_NET; + goto end; + } + + for (ln=attr->first; ln!=NULL; ln=ln->next) { + at=ln->data; + if ( at->attr==ATTR_STORM_BITRATE && at->size>=5 && (i=*(char*)(at->data)-1)>=0 && icurrent->ports ) { + ports[i]=ntohl(*(int*)(1+(char*)at->data)); + } + } + + destroyList(attr, (void(*)(void*))freeAttr); + + + end: + + return ret; + +} + + + +// --------------------------------------------------------------------- +int ngadmin_setStormFilterValues (struct ngadmin *nga, const int *ports) { + + List *attr; + int ret=ERR_OK, i; + char err; + unsigned short attr_error; + char *p; + + + if ( nga==NULL || ports==NULL ) { + return ERR_INVARG; + } else if ( nga->current==NULL ) { + return ERR_NOTLOG; + } + + + attr=createEmptyList(); + pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); + + for (i=0; icurrent->ports; ++i) { + if ( ports[i]>=0 && ports[i]<=11 ) { + p=malloc(5); + *p=i+1; + *(int*)(p+1)=htonl(ports[i]); + pushBackList(attr, newAttr(ATTR_STORM_BITRATE, 5, p)); + } + } + + pushBackList(attr, newEmptyAttr(ATTR_END)); + i=sendNgPacket(nga, CODE_WRITE_REQ, &nga->current->mac, ++nga->seq, attr); + destroyList(attr, (void(*)(void*))freeAttr); + if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error, &nga->current->mac, nga->seq))==NULL ) { + ret=ERR_NET; + goto end; + } + + destroyList(attr, (void(*)(void*))freeAttr); + + if ( err==7 && attr_error==ATTR_PASSWORD ) { + ret=ERR_BADPASS; + goto end; + } + + + end: + + return ret; + +} + + + diff --git a/lib/src/protocol.c b/lib/src/protocol.c index 51e0611..b5d930e 100644 --- a/lib/src/protocol.c +++ b/lib/src/protocol.c @@ -178,7 +178,20 @@ struct attr* newByteAttr (unsigned short attr, unsigned char value) { *v=value; - return newAttr(attr, 1, v); + return newAttr(attr, sizeof(char), v); + +} + + + +// ----------------------------------------------------- +struct attr* newIntAttr (unsigned short attr, int value) { + + int *v=malloc(sizeof(int)); + + *v=value; + + return newAttr(attr, sizeof(int), v); } diff --git a/lib/src/protocol.h b/lib/src/protocol.h index abc7707..ee832f8 100644 --- a/lib/src/protocol.h +++ b/lib/src/protocol.h @@ -99,6 +99,9 @@ struct attr* newAttr (unsigned short attr, unsigned short size, void *data); // struct attr* newByteAttr (unsigned short attr, unsigned char value); +// +struct attr* newIntAttr (unsigned short attr, int value); + // void freeAttr (struct attr *at); -- 2.39.5