]> git.sur5r.net Git - ngadmin/commitdiff
CLI: reunited commands in one file.
authordarkcoven <admin@darkcoven.tk>
Thu, 17 Nov 2011 11:00:00 +0000 (12:00 +0100)
committerdarkcoven <admin@darkcoven.tk>
Sat, 29 Dec 2012 20:46:06 +0000 (21:46 +0100)
CLI: added command autocompletion.
Added storm filtering support.

19 files changed:
cli/admin.c
cli/com_firmware.c [deleted file]
cli/com_list.c [deleted file]
cli/com_login.c [deleted file]
cli/com_name.c [deleted file]
cli/com_password.c [deleted file]
cli/com_ports.c [deleted file]
cli/com_quit.c [deleted file]
cli/com_scan.c [deleted file]
cli/command.c [deleted file]
cli/command.h [deleted file]
cli/commands.c [new file with mode: 0644]
cli/commands.h [new file with mode: 0644]
cli/common.c [new file with mode: 0644]
cli/common.h
lib/ngadmin.h
lib/src/ngadmin.c
lib/src/protocol.c
lib/src/protocol.h

index 523a96c188a6430d073ce3752fcafc1f506cc5fe..2644d38233d261763e11b5a6d13849274414baa3 100644 (file)
 #include <readline/readline.h>
 #include <readline/history.h>
 
-#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; i<n; ++i) {
+  
+  // we have reached a terminal command, exit
+  if ( cur->sub==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<nb; ++i) {
-  printf("%i\t%s\t%s\t\t%s\t%s/", i, ether_ntoa(&sa[i].mac), sa[i].product, sa[i].name, inet_ntoa(sa[i].nc.ip));
-  printf("%s\t%s\t%i\t%s\n", inet_ntoa(sa[i].nc.netmask), ( sa[i].nc.dhcp ? "Yes" : "No" ), sa[i].ports, sa[i].firmware);
- }
+ if ( i<n ) compcur=NULL;
+ matches=rl_completion_matches(text, my_generator);
  
- printf("\nfound %i switch(es)\n", nb);
  
+ return matches;
  
 }
 
@@ -83,7 +126,7 @@ int main (int argc, char **argv) {
  char *line, *com[MAXCOM];
  struct ngadmin *nga=NULL;
  struct timeval tv;
- const struct TreeNode *cur, *next, **tab;
+ const struct TreeNode *cur, *next;
  int i, n;
  
  
@@ -106,64 +149,53 @@ int main (int argc, char **argv) {
  ngadmin_setTimeout(nga, &tv);
  
  
- rl_bind_key('\t', rl_abort); // disable auto completion
+ //rl_bind_key('\t', rl_abort); // disable auto completion
+ rl_attempted_completion_function=my_completion;
  
  
  while ( cont ) {
   
+  //rl_bind_key('\t', rl_complete); // enable auto-complete
+  
   if ( (line=readline("> "))==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; i<n; ++i) {
-   cur=next;
-   for (tab=cur->sub; (next=*tab)!=NULL && strcmp(next->name, com[i])!=0; ++tab);
-   if ( next==NULL ) break;
+  if ( n==0 ) {
+   continue;
   }
   
+  cur=getSubCom(com, n, &i);
   
-  if ( i<n ) { // commands left uncompared
+  if ( i<n ) { // commands left unchecked
    
    if ( cur->hasArgs ) { // 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; i<MAXCOM; i++) {
    if ( com[i]!=NULL ) {
diff --git a/cli/com_firmware.c b/cli/com_firmware.c
deleted file mode 100644 (file)
index f697af6..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-
-#include "common.h"
-
-
-
-
-static bool do_firmware_show (const struct TreeNode *tn UNUSED, 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 (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 <file>\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 (file)
index 3c8eb8c..0000000
+++ /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 (file)
index e50e096..0000000
+++ /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 <num>\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 (file)
index 54b152e..0000000
+++ /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 <value>\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 (file)
index 4b1f184..0000000
+++ /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 <value>\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 <value>\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 (file)
index b520218..0000000
+++ /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; i<sa->ports; 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; i<sa->ports; ++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 (file)
index 61dc5ce..0000000
+++ /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 (file)
index 51b24b8..0000000
+++ /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 (file)
index 943d148..0000000
+++ /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 (file)
index 0689b22..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#ifndef DEF_COMMAND
-#define DEF_COMMAND
-
-
-#include <stdlib.h>
-#include <string.h>
-
-
-
-// 
-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 (file)
index 0000000..7ed9020
--- /dev/null
@@ -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 <file>\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 <num>\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 <value>\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 <value>\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 <value>\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; i<sa->ports; 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; i<sa->ports; ++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; i<sa->ports; ++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 <port1> <speed1> [<port2> <speed2> ...]\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; i<sa->ports; ++i) {
+  ports[i]=BITRATE_UNSPEC;
+ }
+ for (i=0; i<nb; i+=2) {
+  if ( (p=strtol(com[i], NULL, 0))<1 || p>sa->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; i<sa->ports; ++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 (file)
index 0000000..f289e71
--- /dev/null
@@ -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="<root>", .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 (file)
index 0000000..224344b
--- /dev/null
@@ -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<nb; ++i) {
+  printf("%i\t%s\t%s\t\t%s\t%s/", i, ether_ntoa(&sa[i].mac), sa[i].product, sa[i].name, inet_ntoa(sa[i].nc.ip));
+  printf("%s\t%s\t%i\t%s\n", inet_ntoa(sa[i].nc.netmask), ( sa[i].nc.dhcp ? "Yes" : "No" ), sa[i].ports, sa[i].firmware);
+ }
+ printf("\nfound %i switch(es)\n", nb);
+}
+
+
+
+// ----------------------------
+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;
+}
+
+
index ee845aff9e41bf48b9d8ff96ddc135c200eb9e56..ea24327ee03ff6434f4e72069f96af7debd0f8f4 100644 (file)
@@ -5,21 +5,12 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include <ngadmin.h>
 
 
 #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);
 
 
 
index 824b0dd1b36b74edb095c4bc1f270efce3d6444d..69286c79af916ec26cb1b4e99f8c7768b3ac9035 100644 (file)
@@ -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
 
index bdcc9b53ee402ccc655ac646e7b938a07b7d4572..312ab584ea3a5c6b3de784c2d32c9c6917641f6d 100644 (file)
@@ -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 && i<nga->current->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; i<nga->current->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;
+}
+
+
+
index 51e06118efa560fe156d6c6f72224e38efa3b7de..b5d930e4dbecc74f68964343357e7794c1fc13fe 100644 (file)
@@ -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);
  
 }
 
index abc7707b277fe6c26620ea3f03e2ae5a3aee5f6a..ee832f8ef8954afcbdf7391f81e6bf368b35cb5e 100644 (file)
@@ -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);