]> git.sur5r.net Git - ngadmin/commitdiff
CLI: separated commands by category in different files.
authordarkcoven <admin@darkcoven.tk>
Tue, 29 Nov 2011 11:00:00 +0000 (12:00 +0100)
committerdarkcoven <admin@darkcoven.tk>
Sat, 29 Dec 2012 21:45:11 +0000 (22:45 +0100)
Added support for reading VLAN 802.1q values.
Dissector: changed code structure.
Dissector: added checks of packet structure.
Dissector: added dissect support for most request types.

24 files changed:
cli/com_bitrate.c [new file with mode: 0644]
cli/com_cabletest.c [new file with mode: 0644]
cli/com_defaults.c [new file with mode: 0644]
cli/com_firmware.c [new file with mode: 0644]
cli/com_igmp.c [new file with mode: 0644]
cli/com_list.c [new file with mode: 0644]
cli/com_login.c [new file with mode: 0644]
cli/com_mirror.c [new file with mode: 0644]
cli/com_name.c [new file with mode: 0644]
cli/com_netconf.c [new file with mode: 0644]
cli/com_password.c [new file with mode: 0644]
cli/com_ports.c [new file with mode: 0644]
cli/com_qos.c [new file with mode: 0644]
cli/com_quit.c [new file with mode: 0644]
cli/com_restart.c [new file with mode: 0644]
cli/com_scan.c [new file with mode: 0644]
cli/com_stormfilter.c [new file with mode: 0644]
cli/com_tree.c [new file with mode: 0644]
cli/com_vlan.c [new file with mode: 0644]
cli/commands.c
lib/ngadmin.h
lib/src/network.c
lib/src/ngadmin.c
nsdp.lua

diff --git a/cli/com_bitrate.c b/cli/com_bitrate.c
new file mode 100644 (file)
index 0000000..94afad8
--- /dev/null
@@ -0,0 +1,121 @@
+
+#include "commands.h"
+
+
+
+// helper function to analyse bitrate speed specifications
+static int bitrate_analyse (int nb, const char **com, int *ports) {
+ int i=0, s;
+ while ( i<nb-1 ) {
+  s=parseBitrate(com[i+1]);
+  if ( strcmp(com[i], "inout")==0 ) {
+   ports[0]=s;
+   ports[1]=s;
+  } else if ( strcmp(com[i], "in")==0 ) {
+   ports[0]=s;
+  } else if ( strcmp(com[i], "out")==0 ) {
+   ports[1]=s;
+  } else {
+   break;
+  }
+  i+=2;
+ }
+ return i;
+}
+
+
+
+bool do_bitrate_set (int nb, const char **com, struct ngadmin *nga) {
+ int i, k=0, defs[]={12, 12}, p, *ports=NULL;
+ const struct swi_attr *sa;
+ bool ret=true;
+ if ( nb<2 ) {
+  printf("Usage: bitrate set [all SPEEDSPEC] <port1> SPEEDSPEC [<port2> SPEEDSPEC ...]\n");
+  printf("SPEEDSPEC: [inout <speed>] [in <ispeed>] [out <ospeed>]\n");
+  ret=false;
+  goto end;
+ }
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ ports=malloc(2*sa->ports*sizeof(int));
+ // get defaults if present
+ if ( strcmp(com[k], "all")==0 ) {
+  ++k;
+  k+=bitrate_analyse(nb-k, &com[k], defs);
+ }
+ // apply defaults
+ for (i=0; i<sa->ports; ++i) {
+  memcpy(&ports[2*i], defs, sizeof(defs));
+ }
+ // get ports specifics
+ while ( k<nb ) {
+  p=strtol(com[k++], NULL, 0)-1;
+  if ( p>=0 && p<sa->ports ) {
+   k+=bitrate_analyse(nb-k, &com[k], &ports[2*p]);
+  }
+ }
+ // send it to the switch
+ i=ngadmin_setBitrateLimits(nga, ports);
+ printErrCode(i);
+ end:
+ free(ports);
+ return ret;
+}
+
+
+
+bool do_bitrate_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
+ int i, ret=true, *ports=NULL;
+ const struct swi_attr *sa;
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ ports=malloc(2*sa->ports*sizeof(int));
+ if ( (i=ngadmin_getBitrateLimits(nga, ports))!=ERR_OK ) {
+  printErrCode(i);
+  ret=false;
+  goto end;
+ }
+ for (i=0; i<sa->ports; ++i) {
+  printf("port %i: in %s, out %s\n", i+1, bitrates[ports[2*i+0]], bitrates[ports[2*i+1]]);
+ }
+ end:
+ free(ports);
+ return ret;
+}
+
+
+
diff --git a/cli/com_cabletest.c b/cli/com_cabletest.c
new file mode 100644 (file)
index 0000000..521ada9
--- /dev/null
@@ -0,0 +1,53 @@
+
+#include "commands.h"
+
+
+
+bool do_cabletest (int nb, const char **com, struct ngadmin *nga) {
+ bool ret=true;
+ const struct swi_attr *sa;
+ struct cabletest *ct=NULL;
+ int i, j=0, k=0;
+ if ( nb<1 ) {
+  printf("Usage: cabletest <port1> [<port2> ...]\n");
+  goto end;
+ }
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ ct=malloc(sa->ports*sizeof(struct cabletest));
+ memset(ct, 0, sa->ports*sizeof(struct cabletest));
+ while ( k<nb ) {
+  ct[j].port=strtol(com[k++], NULL, 0);
+  if ( ct[j].port>=1 && ct[j].port<=sa->ports ) ++j;
+ }
+ i=ngadmin_cabletest(nga, ct, j);
+ if ( i<0 ) {
+  printErrCode(i);
+  ret=false;
+  goto end;
+ }
+ for (i=0; i<j; ++i) {
+  printf("port %i: %08X %08X\n", ct[i].port, ct[i].v1, ct[i].v2);
+ }
+ end:
+ free(ct);
+ return ret;
+}
+
+
diff --git a/cli/com_defaults.c b/cli/com_defaults.c
new file mode 100644 (file)
index 0000000..5855332
--- /dev/null
@@ -0,0 +1,35 @@
+
+#include "commands.h"
+
+
+
+bool do_defaults (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
+ int i, ret=true;
+ const struct swi_attr *sa;
+ char line[16];
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ printf("The switch settings will be CLEARED. Continue ? [y/N]: ");
+ fflush(stdout);
+ if ( fgets(line, sizeof(line), stdin)!=NULL && strcasecmp(line, "y\n")==0 ) {
+  i=ngadmin_defaults(nga);
+  printErrCode(i);
+ }
+ end:
+ return ret;
+}
+
+
diff --git a/cli/com_firmware.c b/cli/com_firmware.c
new file mode 100644 (file)
index 0000000..e4bc682
--- /dev/null
@@ -0,0 +1,56 @@
+
+#include "commands.h"
+
+
+
+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;
+}
+
+
+
+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;
+}
+
+
+
diff --git a/cli/com_igmp.c b/cli/com_igmp.c
new file mode 100644 (file)
index 0000000..efe39b8
--- /dev/null
@@ -0,0 +1,72 @@
+
+#include "commands.h"
+
+
+
+bool do_igmp_set (int nb, const char **com, struct ngadmin *nga) {
+ int i;
+ struct igmp_conf ic;
+ if ( nb!=4 ) {
+  printf("Usage: igmp set <enable> <vlan> <validate> <block>\n");
+  return false;
+ }
+ if ( ngadmin_getCurrentSwitch(nga)==NULL ) {
+  printf("must be logged\n");
+  return false;
+ }
+ ic.enable=strtol(com[0], NULL, 0);
+ ic.vlan=strtol(com[1], NULL, 0);
+ ic.validate=strtol(com[2], NULL, 0);
+ ic.block=strtol(com[3], NULL, 0);
+ i=ngadmin_setIGMPConf(nga, &ic);
+ printErrCode(i);
+ return true;
+}
+
+
+
+bool do_igmp_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
+ int i;
+ const struct swi_attr *sa;
+ struct igmp_conf ic;
+ bool ret=true;
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ i=ngadmin_getIGMPConf(nga, &ic);
+ if ( i!=ERR_OK ) {
+  printErrCode(i);
+  ret=false;
+  goto end;
+ }
+ printf("IGMP snooping enabled: %s\n", ic.enable ? "yes" : "no" );
+ printf("IGMP snooping vlan: %u\n", ic.vlan);
+ printf("Validate IGMPv3 headers: %s\n", ic.validate ? "yes" : "no" );
+ printf("Block unknown multicast addresses: %s\n", ic.block ? "yes" : "no" );
+ end:
+ return ret;
+}
+
+
diff --git a/cli/com_list.c b/cli/com_list.c
new file mode 100644 (file)
index 0000000..9630f76
--- /dev/null
@@ -0,0 +1,20 @@
+
+#include "commands.h"
+
+
+
+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;
+}
+
+
diff --git a/cli/com_login.c b/cli/com_login.c
new file mode 100644 (file)
index 0000000..dfd0a92
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include "commands.h"
+
+
+
+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;
+}
+
+
diff --git a/cli/com_mirror.c b/cli/com_mirror.c
new file mode 100644 (file)
index 0000000..67cbb04
--- /dev/null
@@ -0,0 +1,132 @@
+
+#include "commands.h"
+
+
+
+
+bool do_mirror_disable (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_setMirror(nga, NULL);
+ printErrCode(i);
+ return true;
+}
+
+
+
+bool do_mirror_set (int nb, const char **com, struct ngadmin *nga) {
+ const struct swi_attr *sa;
+ char *ports=NULL;
+ bool ret=true;
+ int i, k=0;
+ if ( nb<3 ) {
+  printf("Usage: mirror set <destination port> clone <port1> [<port2> ...]\n");
+  goto end;
+ }
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ ports=malloc((sa->ports+1)*sizeof(char));
+ memset(ports, 0, sa->ports+1);
+ ports[0]=strtol(com[k++], NULL, 0);
+ if ( ports[0]<1 || ports[0]>sa->ports || strcasecmp(com[k++], "clone")!=0 ) {
+  printf("syntax error\n");
+  ret=false;
+  goto end;
+ }
+ while ( k<nb ) {
+  i=strtol(com[k++], NULL, 0);
+  if ( i<1 || i>sa->ports ) {
+   printf("port out of range\n");
+   ret=false;
+   goto end;
+  } else if ( i==ports[0] ) {
+   printf("destination port cannot be in port list\n");
+   ret=false;
+   goto end;
+  }
+  ports[i]=1;
+ }
+ i=ngadmin_setMirror(nga, ports);
+ printErrCode(i);
+ end:
+ free(ports);
+ return ret;
+}
+
+
+
+bool do_mirror_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
+ const struct swi_attr *sa;
+ char *ports=NULL;
+ int i;
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  return false;
+ }
+ ports=malloc((sa->ports+1)*sizeof(char));
+ i=ngadmin_getMirror(nga, ports);
+ if ( i!=ERR_OK ) {
+  printErrCode(i);
+  goto end;
+ }
+ if ( ports[0]==0 ) {
+  printf("port mirroring is disabled\n");
+  goto end;
+ }
+ printf("destination: %i\n", ports[0]);
+ printf("ports: ");
+ for (i=1; i<=sa->ports; ++i) {
+  if ( ports[i] ) {
+   printf("%i ", i);
+  }
+ }
+ printf("\n");
+ end:
+ free(ports);
+ return true;
+}
+
+
+
diff --git a/cli/com_name.c b/cli/com_name.c
new file mode 100644 (file)
index 0000000..e561724
--- /dev/null
@@ -0,0 +1,70 @@
+
+#include "commands.h"
+
+
+
+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;
+}
+
+
+
+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;
+}
+
+
+
+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;
+}
+
+
diff --git a/cli/com_netconf.c b/cli/com_netconf.c
new file mode 100644 (file)
index 0000000..e4838b8
--- /dev/null
@@ -0,0 +1,80 @@
+
+#include "commands.h"
+
+
+
+bool do_netconf_set (int nb, const char **com, struct ngadmin *nga) {
+ int i, k;
+ const struct swi_attr *sa;
+ struct net_conf nc;
+ bool ret=true;
+ if ( nb==0 ) {
+  printf("Usage: netconf set [dhcp yes|no] [ip <ip>] [mask <mask>] [gw <gw>]\n");
+  return false;
+ }
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  return false;
+ }
+ memset(&nc, 0, sizeof(struct net_conf));
+ for (k=0; k<nb; k+=2) {
+  
+  if ( strcasecmp(com[k], "dhcp")==0 ) {
+   if ( strcasecmp(com[k+1], "yes")==0 ) {
+    nc.dhcp=true;
+   } else if ( strcasecmp(com[k+1], "no")==0 ) {
+    nc.dhcp=false;
+   } else {
+    printf("Incorrect DHCP value\n");
+    ret=false;
+    goto end;
+   }
+   
+  } else if ( strcasecmp(com[k], "ip")==0 ) {
+   if ( inet_aton(com[k+1], &nc.ip)==0 ) {
+    printf("Incorrect IP value\n");
+    ret=false;
+    goto end;
+   }
+   
+  } else if ( strcasecmp(com[k], "mask")==0 ) {
+   if ( inet_aton(com[k+1], &nc.netmask)==0 ) { // TODO: check if it is a correct mask
+    printf("Incorrect mask value\n");
+    ret=false;
+    goto end;
+   }
+   
+  } else if ( strcasecmp(com[k], "gw")==0 ) {
+   if ( inet_aton(com[k+1], &nc.gw)==0 ) {
+    printf("Incorrect gateway value\n");
+    ret=false;
+    goto end;
+   }
+   
+  }
+  
+ }
+ i=ngadmin_setNetConf(nga, &nc);
+ if ( i!=ERR_OK ) {
+  printErrCode(i);
+  ret=false;
+ }
+ end:
+ return ret;
+}
+
+
+
diff --git a/cli/com_password.c b/cli/com_password.c
new file mode 100644 (file)
index 0000000..f93412e
--- /dev/null
@@ -0,0 +1,51 @@
+
+#include "commands.h"
+
+
+
+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 change <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;
+}
+
+
+
+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;
+}
+
+
+
diff --git a/cli/com_ports.c b/cli/com_ports.c
new file mode 100644 (file)
index 0000000..baa8c8f
--- /dev/null
@@ -0,0 +1,105 @@
+
+#include "commands.h"
+
+
+
+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;
+}
+
+
+
+bool do_ports_statistics_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;
+}
+
+
+
+bool do_ports_statistics_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\tCRC errors\n");
+ for (i=0; i<sa->ports; ++i) {
+  printf("% 4i%12llu%12llu%14llu\n", i+1, ps[i].recv, ps[i].sent, ps[i].crc);
+ }
+ end:
+ free(ps);
+ return ret;
+}
+
+
+
diff --git a/cli/com_qos.c b/cli/com_qos.c
new file mode 100644 (file)
index 0000000..cd61741
--- /dev/null
@@ -0,0 +1,154 @@
+
+#include "commands.h"
+
+
+
+
+bool do_qos_mode (int nb, const char **com, struct ngadmin *nga) {
+ int i, s, ret=true;
+ const struct swi_attr *sa;
+ if ( nb==0 ) {
+  printf("Usage: qos mode port|802.1p\n");
+  goto end;
+ }
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ if ( strcasecmp(com[0], "port")==0 ) {
+  s=QOS_PORT;
+ } else if ( strcasecmp(com[0], "802.1p")==0 ) {
+  s=QOS_DOT;
+ } else {
+  printf("Unknown QOS mode\n");
+  ret=false;
+  goto end;
+ }
+ i=ngadmin_setQOSMode(nga, s);
+ printErrCode(i);
+ end:
+ return ret;
+}
+
+
+
+bool do_qos_set (int nb, const char **com, struct ngadmin *nga) {
+ int i, p;
+ const struct swi_attr *sa;
+ bool ret=true;
+ char d=PRIO_UNSPEC, *ports=NULL;
+ if ( nb<2 ) {
+  printf("Usage: qos set (all <prio0>)|(<port1> <prio1> [<port2> <prio2> ...])\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(char));
+ if ( strcmp(com[0], "all")==0 ) {
+  d=parsePrio(com[1]);
+  com+=2;
+  nb-=2;
+ }
+ for (i=0; i<sa->ports; ++i) {
+  ports[i]=d;
+ }
+ for (i=0; i<nb; i+=2) {
+  if ( (p=strtol(com[i], NULL, 0))<1 || p>sa->ports ) continue;
+  ports[p-1]=parsePrio(com[i+1]);
+ }
+ i=ngadmin_setQOSValues(nga, ports);
+ printErrCode(i);
+ end:
+ free(ports);
+ return ret;
+}
+
+
+
+bool do_qos_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
+ int i, s=0, ret=true;
+ const struct swi_attr *sa;
+ char *ports=NULL;
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ if ( (i=ngadmin_getQOSMode(nga, &s))!=ERR_OK ) {
+  printErrCode(i);
+  ret=false;
+  goto end;
+ }
+ printf("QOS mode: ");
+ if ( s==QOS_DOT ) {
+  printf("802.1p\n");
+  goto end;
+ } else if ( s!=QOS_PORT ) {
+  printf("unknown (%i)\n", s);
+  goto end;
+ }
+ printf("port based\n");
+ ports=malloc(sa->ports*sizeof(char));
+ if ( (i=ngadmin_getQOSValues(nga, ports))!=ERR_OK ) {
+  printErrCode(i);
+  ret=false;
+  goto end;
+ }
+ for (i=0; i<sa->ports; ++i) {
+  printf("port %i: %s\n", i+1, prio[(int)ports[i]]);
+ }
+ end:
+ free(ports);
+ return ret;
+}
+
+
+
+
diff --git a/cli/com_quit.c b/cli/com_quit.c
new file mode 100644 (file)
index 0000000..64c7824
--- /dev/null
@@ -0,0 +1,14 @@
+
+#include "commands.h"
+
+
+
+bool do_quit (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga UNUSED) {
+ cont=0;
+ return true;
+}
+
+
diff --git a/cli/com_restart.c b/cli/com_restart.c
new file mode 100644 (file)
index 0000000..8ad5845
--- /dev/null
@@ -0,0 +1,35 @@
+
+#include "commands.h"
+
+
+
+bool do_restart (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga UNUSED) {
+ int i, ret=true;
+ const struct swi_attr *sa;
+ char line[16];
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ printf("The switch will be restarted. Continue ? [y/N]: ");
+ fflush(stdout);
+ if ( fgets(line, sizeof(line), stdin)!=NULL && strcasecmp(line, "y\n")==0 ) {
+  i=ngadmin_restart(nga);
+  printErrCode(i);
+ }
+ end:
+ return ret;
+}
+
+
diff --git a/cli/com_scan.c b/cli/com_scan.c
new file mode 100644 (file)
index 0000000..98744ff
--- /dev/null
@@ -0,0 +1,25 @@
+
+#include "commands.h"
+
+
+
+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;
+}
+
+
diff --git a/cli/com_stormfilter.c b/cli/com_stormfilter.c
new file mode 100644 (file)
index 0000000..88afdae
--- /dev/null
@@ -0,0 +1,144 @@
+
+#include "commands.h"
+
+
+
+bool do_stormfilter_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;
+}
+
+
+
+bool do_stormfilter_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;
+}
+
+
+
+bool do_stormfilter_set (int nb, const char **com, struct ngadmin *nga) {
+ int i, d=BITRATE_UNSPEC, p, *ports=NULL;
+ const struct swi_attr *sa;
+ bool ret=true;
+ if ( nb<2 ) {
+  printf("Usage: stormfilt set (all <speed0>)|(<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));
+ if ( strcmp(com[0], "all")==0 ) {
+  d=parseBitrate(com[1]);
+  com+=2;
+  nb-=2;
+ }
+ for (i=0; i<sa->ports; ++i) {
+  ports[i]=d;
+ }
+ 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;
+}
+
+
+
+bool do_stormfilter_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: %s\n", i+1, bitrates[ports[i]]);
+ }
+ end:
+ free(ports);
+ return ret;
+}
+
+
+
diff --git a/cli/com_tree.c b/cli/com_tree.c
new file mode 100644 (file)
index 0000000..200ac41
--- /dev/null
@@ -0,0 +1,42 @@
+
+#include "commands.h"
+
+
+
+
+static void display_node (const struct TreeNode *tn, int depth) {
+ int i;
+ const struct TreeNode *s;
+ for (i=0; i<depth; ++i) {
+  putchar('\t');
+ }
+ puts(tn->name);
+ if ( tn->sub==NULL ) return;
+ for (s=tn->sub; s->name!=NULL; ++s) {
+  display_node(s, depth+1);
+ }
+}
+
+
+
+bool do_tree (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga UNUSED) {
+ display_node(&coms, 0);
+ return true;
+}
+
+
+
+
diff --git a/cli/com_vlan.c b/cli/com_vlan.c
new file mode 100644 (file)
index 0000000..14be784
--- /dev/null
@@ -0,0 +1,177 @@
+
+#include "commands.h"
+
+
+
+
+static char vlan_char (int t) {
+ switch ( t ) {
+  case VLAN_TAGGED: return 'T';
+  case VLAN_UNTAGGED: return 'U'; 
+  case VLAN_NO: return ' ';
+  default: return '?';
+ }
+}
+
+
+
+bool do_vlan_8021q_show (int nb, const char **com, struct ngadmin *nga) {
+ unsigned short vl=0, *vlans=NULL;
+ unsigned char *ports=NULL;
+ const struct swi_attr *sa;
+ int i, j, n=16;
+ bool ret=true;
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ if ( nb>0 ) {
+  vl=strtoul(com[0], NULL, 0);
+ }
+ ports=malloc(sa->ports*n*sizeof(unsigned char));
+ if ( vl==0 ) {
+  vlans=malloc(n*sizeof(unsigned short));
+  ports=malloc(sa->ports*n*sizeof(unsigned char));
+  i=ngadmin_getVLANDotAllConf(nga, vlans, ports, &n);
+ } else {
+  ports=malloc(sa->ports*sizeof(unsigned char));
+  i=ngadmin_getVLANDotConf(nga, vl, ports);
+ }
+ if ( i!=ERR_OK ) {
+  printErrCode(i);
+  ret=false;
+  goto end;
+ }
+ printf("Ports configuration: \n");
+ printf("VLAN\t");
+ for (i=1; i<=sa->ports; ++i) {
+  printf("%i\t", i);
+ }
+ putchar('\n');
+ if ( vl==0 ) {
+  
+  for (i=0; i<n; ++i) {
+   printf("%u\t", vlans[i]);
+   for (j=0; j<sa->ports; ++j) {
+    printf("%c\t", vlan_char(ports[i*sa->ports+j]));
+   }
+   putchar('\n');
+  }
+  
+ } else {
+  
+  printf("%u\t", vl);
+  for (j=0; j<sa->ports; ++j) {
+   printf("%c\t", vlan_char(ports[j]));
+  }
+  putchar('\n');
+  
+ }
+ end:
+ free(vlans);
+ free(ports);
+ return ret;
+}
+
+
+
+bool do_vlan_mode_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
+ int i, t, ret=true;
+ if ( ngadmin_getCurrentSwitch(nga)==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ if ( (i=ngadmin_getVLANType(nga, &t))!=ERR_OK ) {
+  printErrCode(i);
+  ret=false;
+  goto end;
+ }
+ printf("VLAN type: ");
+ switch ( t ) {
+  case VLAN_DISABLED: printf("disabled\n"); break;
+  case VLAN_PORT_BASIC: printf("port basic\n"); break;
+  case VLAN_PORT_ADV: printf("port advanced\n"); break;
+  case VLAN_DOT_BASIC: printf("802.1Q basic\n"); break;
+  case VLAN_DOT_ADV:printf("802.1Q advanced\n");break;
+  default: printf("unknown (%i)\n", t);
+ }
+ end:
+ return ret;
+}
+
+
+
+bool do_vlan_pvid_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
+ unsigned short *ports=NULL;
+ const struct swi_attr *sa;
+ int i;
+ bool ret=true;
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ ports=malloc(sa->ports*sizeof(unsigned short));
+ i=ngadmin_getPVID(nga, ports);
+ if ( i!=ERR_OK ) {
+  printErrCode(i);
+  ret=false;
+  goto end;
+ }
+ printf("PVID: \n");
+ printf("Port\t");
+ for (i=1; i<=sa->ports; ++i) {
+  printf("%i\t", i);
+ }
+ putchar('\n');
+ printf("VLAN\t");
+ for (i=0; i<sa->ports; ++i) {
+  printf("%u\t", ports[i]);
+ }
+ putchar('\n');
+ end:
+ free(ports);
+ return ret;
+}
+
+
index b26d2fd44951d3a764ba4fc0b41fe4f287153225..70740b2d64c6b9ece2d0c56f45b77b314676b20f 100644 (file)
 
 
 
-// =============================================================================
 // bitrate
+bool do_bitrate_set (int nb, const char **com, struct ngadmin *nga);
+bool do_bitrate_show (int nb, const char **com, struct ngadmin *nga);
 
 
-// helper function to analyse bitrate speed specifications
-static int bitrate_analyse (int nb, const char **com, int *ports) {
- int i=0, s;
- while ( i<nb-1 ) {
-  s=parseBitrate(com[i+1]);
-  if ( strcmp(com[i], "inout")==0 ) {
-   ports[0]=s;
-   ports[1]=s;
-  } else if ( strcmp(com[i], "in")==0 ) {
-   ports[0]=s;
-  } else if ( strcmp(com[i], "out")==0 ) {
-   ports[1]=s;
-  } else {
-   break;
-  }
-  i+=2;
- }
- return i;
-}
-
-
-static bool do_bitrate_set (int nb, const char **com, struct ngadmin *nga) {
- int i, k=0, defs[]={12, 12}, p, *ports=NULL;
- const struct swi_attr *sa;
- bool ret=true;
- if ( nb<2 ) {
-  printf("Usage: bitrate set [all SPEEDSPEC] <port1> SPEEDSPEC [<port2> SPEEDSPEC ...]\n");
-  printf("SPEEDSPEC: [inout <speed>] [in <ispeed>] [out <ospeed>]\n");
-  ret=false;
-  goto end;
- }
- if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
-  printf("must be logged\n");
-  ret=false;
-  goto end;
- }
- ports=malloc(2*sa->ports*sizeof(int));
- // get defaults if present
- if ( strcmp(com[k], "all")==0 ) {
-  ++k;
-  k+=bitrate_analyse(nb-k, &com[k], defs);
- }
- // apply defaults
- for (i=0; i<sa->ports; ++i) {
-  memcpy(&ports[2*i], defs, sizeof(defs));
- }
- // get ports specifics
- while ( k<nb ) {
-  p=strtol(com[k++], NULL, 0)-1;
-  if ( p>=0 && p<sa->ports ) {
-   k+=bitrate_analyse(nb-k, &com[k], &ports[2*p]);
-  }
- }
- // send it to the switch
- i=ngadmin_setBitrateLimits(nga, ports);
- printErrCode(i);
- end:
- free(ports);
- return ret;
-}
-
-
-
-static bool do_bitrate_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
- int i, ret=true, *ports=NULL;
- const struct swi_attr *sa;
- if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
-  printf("must be logged\n");
-  ret=false;
-  goto end;
- }
- ports=malloc(2*sa->ports*sizeof(int));
- if ( (i=ngadmin_getBitrateLimits(nga, ports))!=ERR_OK ) {
-  printErrCode(i);
-  ret=false;
-  goto end;
- }
- for (i=0; i<sa->ports; ++i) {
-  printf("port %i: in %s, out %s\n", i+1, bitrates[ports[2*i+0]], bitrates[ports[2*i+1]]);
- }
- end:
- free(ports);
- return ret;
-}
-
-
-
-// =============================================================================
 // cabletest
+bool do_cabletest (int nb, const char **com, struct ngadmin *nga);
 
 
-static bool do_cabletest (int nb, const char **com, struct ngadmin *nga) {
- bool ret=true;
- const struct swi_attr *sa;
- struct cabletest *ct=NULL;
- int i, j=0, k=0;
- if ( nb<1 ) {
-  printf("Usage: cabletest <port1> [<port2> ...]\n");
-  goto end;
- }
- if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
-  printf("must be logged\n");
-  ret=false;
-  goto end;
- }
- ct=malloc(sa->ports*sizeof(struct cabletest));
- memset(ct, 0, sa->ports*sizeof(struct cabletest));
- while ( k<nb ) {
-  ct[j].port=strtol(com[k++], NULL, 0);
-  if ( ct[j].port>=1 && ct[j].port<=sa->ports ) ++j;
- }
- i=ngadmin_cabletest(nga, ct, j);
- if ( i<0 ) {
-  printErrCode(i);
-  ret=false;
-  goto end;
- }
- for (i=0; i<j; ++i) {
-  printf("port %i: %08X %08X\n", ct[i].port, ct[i].v1, ct[i].v2);
- }
- end:
- free(ct);
- return ret;
-}
-
-
-
-// =============================================================================
 // defaults
+bool do_defaults (int nb, const char **com, struct ngadmin *nga);
 
 
-static bool do_defaults (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
- int i, ret=true;
- const struct swi_attr *sa;
- char line[16];
- if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
-  printf("must be logged\n");
-  ret=false;
-  goto end;
- }
- printf("The switch settings will be CLEARED. Continue ? [y/N]: ");
- fflush(stdout);
- if ( fgets(line, sizeof(line), stdin)!=NULL && strcasecmp(line, "y\n")==0 ) {
-  i=ngadmin_defaults(nga);
-  printErrCode(i);
- }
- end:
- return ret;
-}
-
-
-
-// =============================================================================
 // firmware
+bool do_firmware_show (int nb, const char **com, struct ngadmin *nga);
+bool do_firmware_upgrade (int nb, const char **com, struct ngadmin *nga);
 
 
-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;
-}
-
-
-
-// =============================================================================
 // igmp
+bool do_igmp_set (int nb, const char **com, struct ngadmin *nga);
+bool do_igmp_show (int nb, const char **com, struct ngadmin *nga);
 
 
-static bool do_igmp_set (int nb, const char **com, struct ngadmin *nga) {
- int i;
- struct igmp_conf ic;
- if ( nb!=4 ) {
-  printf("Usage: igmp set <enable> <vlan> <validate> <block>\n");
-  return false;
- }
- if ( ngadmin_getCurrentSwitch(nga)==NULL ) {
-  printf("must be logged\n");
-  return false;
- }
- ic.enable=strtol(com[0], NULL, 0);
- ic.vlan=strtol(com[1], NULL, 0);
- ic.validate=strtol(com[2], NULL, 0);
- ic.block=strtol(com[3], NULL, 0);
- i=ngadmin_setIGMPConf(nga, &ic);
- printErrCode(i);
- return true;
-}
-
-
-
-static bool do_igmp_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
- int i;
- const struct swi_attr *sa;
- struct igmp_conf ic;
- bool ret=true;
- if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
-  printf("must be logged\n");
-  ret=false;
-  goto end;
- }
- i=ngadmin_getIGMPConf(nga, &ic);
- if ( i!=ERR_OK ) {
-  printErrCode(i);
-  ret=false;
-  goto end;
- }
- printf("IGMP snooping enabled: %s\n", ic.enable ? "yes" : "no" );
- printf("IGMP snooping vlan: %u\n", ic.vlan);
- printf("Validate IGMPv3 headers: %s\n", ic.validate ? "yes" : "no" );
- printf("Block unknown multicast addresses: %s\n", ic.block ? "yes" : "no" );
- end:
- return ret;
-}
-
-
-
-// =============================================================================
 // list
+bool do_list (int nb, const char **com, struct ngadmin *nga);
 
 
-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
+bool do_login (int nb, const char **com, struct ngadmin *nga);
 
 
-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;
-}
-
-
-
-// =============================================================================
 // mirror
+bool do_mirror_disable (int nb, const char **com, struct ngadmin *nga);
+bool do_mirror_set (int nb, const char **com, struct ngadmin *nga);
+bool do_mirror_show (int nb, const char **com, struct ngadmin *nga);
 
 
-static bool do_mirror_disable (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_setMirror(nga, NULL);
- printErrCode(i);
- return true;
-}
-
-
-
-static bool do_mirror_set (int nb, const char **com, struct ngadmin *nga) {
- const struct swi_attr *sa;
- char *ports=NULL;
- bool ret=true;
- int i, k=0;
- if ( nb<3 ) {
-  printf("Usage: mirror set <destination port> clone <port1> [<port2> ...]\n");
-  goto end;
- }
- if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
-  printf("must be logged\n");
-  ret=false;
-  goto end;
- }
- ports=malloc((sa->ports+1)*sizeof(char));
- memset(ports, 0, sa->ports+1);
- ports[0]=strtol(com[k++], NULL, 0);
- if ( ports[0]<1 || ports[0]>sa->ports || strcasecmp(com[k++], "clone")!=0 ) {
-  printf("syntax error\n");
-  ret=false;
-  goto end;
- }
- while ( k<nb ) {
-  i=strtol(com[k++], NULL, 0);
-  if ( i<1 || i>sa->ports ) {
-   printf("port out of range\n");
-   ret=false;
-   goto end;
-  } else if ( i==ports[0] ) {
-   printf("destination port cannot be in port list\n");
-   ret=false;
-   goto end;
-  }
-  ports[i]=1;
- }
- i=ngadmin_setMirror(nga, ports);
- printErrCode(i);
- end:
- free(ports);
- return ret;
-}
-
-
-
-static bool do_mirror_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
- const struct swi_attr *sa;
- char *ports=NULL;
- int i;
- if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
-  printf("must be logged\n");
-  return false;
- }
- ports=malloc((sa->ports+1)*sizeof(char));
- i=ngadmin_getMirror(nga, ports);
- if ( i!=ERR_OK ) {
-  printErrCode(i);
-  goto end;
- }
- if ( ports[0]==0 ) {
-  printf("port mirroring is disabled\n");
-  goto end;
- }
- printf("destination: %i\n", ports[0]);
- printf("ports: ");
- for (i=1; i<=sa->ports; ++i) {
-  if ( ports[i] ) {
-   printf("%i ", i);
-  }
- }
- printf("\n");
- end:
- free(ports);
- return true;
-}
-
-
-
-// =============================================================================
 // name
+bool do_name_show (int nb, const char **com, struct ngadmin *nga);
+bool do_name_set (int nb, const char **com, struct ngadmin *nga);
+bool do_name_clear (int nb, const char **com, struct ngadmin *nga);
 
 
-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;
-}
-
-
-
-// =============================================================================
 // netconf
+bool do_netconf_set (int nb, const char **com, struct ngadmin *nga);
 
 
-static bool do_netconf_set (int nb, const char **com, struct ngadmin *nga) {
- int i, k;
- const struct swi_attr *sa;
- struct net_conf nc;
- bool ret=true;
- if ( nb==0 ) {
-  printf("Usage: netconf set [dhcp yes|no] [ip <ip>] [mask <mask>] [gw <gw>]\n");
-  return false;
- }
- if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
-  printf("must be logged\n");
-  return false;
- }
- memset(&nc, 0, sizeof(struct net_conf));
- for (k=0; k<nb; k+=2) {
-  
-  if ( strcasecmp(com[k], "dhcp")==0 ) {
-   if ( strcasecmp(com[k+1], "yes")==0 ) {
-    nc.dhcp=true;
-   } else if ( strcasecmp(com[k+1], "no")==0 ) {
-    nc.dhcp=false;
-   } else {
-    printf("Incorrect DHCP value\n");
-    ret=false;
-    goto end;
-   }
-   
-  } else if ( strcasecmp(com[k], "ip")==0 ) {
-   if ( inet_aton(com[k+1], &nc.ip)==0 ) {
-    printf("Incorrect IP value\n");
-    ret=false;
-    goto end;
-   }
-   
-  } else if ( strcasecmp(com[k], "mask")==0 ) {
-   if ( inet_aton(com[k+1], &nc.netmask)==0 ) { // TODO: check if it is a correct mask
-    printf("Incorrect mask value\n");
-    ret=false;
-    goto end;
-   }
-   
-  } else if ( strcasecmp(com[k], "gw")==0 ) {
-   if ( inet_aton(com[k+1], &nc.gw)==0 ) {
-    printf("Incorrect gateway value\n");
-    ret=false;
-    goto end;
-   }
-   
-  }
-  
- }
- i=ngadmin_setNetConf(nga, &nc);
- if ( i!=ERR_OK ) {
-  printErrCode(i);
-  ret=false;
- }
- end:
- return ret;
-}
-
-
-
-// =============================================================================
 // password
+bool do_password_change (int nb, const char **com, struct ngadmin *nga);
+bool do_password_set (int nb, const char **com, struct ngadmin *nga);
 
 
-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 change <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
+bool do_ports_state (int nb, const char **com, struct ngadmin *nga);
+bool do_ports_statistics_reset (int nb, const char **com, struct ngadmin *nga);
+bool do_ports_statistics_show (int nb, const char **com, struct ngadmin *nga);
 
 
-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_statistics_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_statistics_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\tCRC errors\n");
- for (i=0; i<sa->ports; ++i) {
-  printf("% 4i%12llu%12llu%14llu\n", i+1, ps[i].recv, ps[i].sent, ps[i].crc);
- }
- end:
- free(ps);
- return ret;
-}
-
-
-
-
-// =============================================================================
 // qos
+bool do_qos_mode (int nb, const char **com, struct ngadmin *nga);
+bool do_qos_set (int nb, const char **com, struct ngadmin *nga);
+bool do_qos_show (int nb, const char **com, struct ngadmin *nga);
 
 
-
-static bool do_qos_mode (int nb, const char **com, struct ngadmin *nga) {
- int i, s, ret=true;
- const struct swi_attr *sa;
- if ( nb==0 ) {
-  printf("Usage: qos mode port|802.1p\n");
-  goto end;
- }
- if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
-  printf("must be logged\n");
-  ret=false;
-  goto end;
- }
- if ( strcasecmp(com[0], "port")==0 ) {
-  s=QOS_PORT;
- } else if ( strcasecmp(com[0], "802.1p")==0 ) {
-  s=QOS_DOT;
- } else {
-  printf("Unknown QOS mode\n");
-  ret=false;
-  goto end;
- }
- i=ngadmin_setQOSMode(nga, s);
- printErrCode(i);
- end:
- return ret;
-}
-
-
-
-static bool do_qos_set (int nb, const char **com, struct ngadmin *nga) {
- int i, p;
- const struct swi_attr *sa;
- bool ret=true;
- char d=PRIO_UNSPEC, *ports=NULL;
- if ( nb<2 ) {
-  printf("Usage: qos set (all <prio0>)|(<port1> <prio1> [<port2> <prio2> ...])\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(char));
- if ( strcmp(com[0], "all")==0 ) {
-  d=parsePrio(com[1]);
-  com+=2;
-  nb-=2;
- }
- for (i=0; i<sa->ports; ++i) {
-  ports[i]=d;
- }
- for (i=0; i<nb; i+=2) {
-  if ( (p=strtol(com[i], NULL, 0))<1 || p>sa->ports ) continue;
-  ports[p-1]=parsePrio(com[i+1]);
- }
- i=ngadmin_setQOSValues(nga, ports);
- printErrCode(i);
- end:
- free(ports);
- return ret;
-}
-
-
-
-static bool do_qos_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
- int i, s=0, ret=true;
- const struct swi_attr *sa;
- char *ports=NULL;
- if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
-  printf("must be logged\n");
-  ret=false;
-  goto end;
- }
- if ( (i=ngadmin_getQOSMode(nga, &s))!=ERR_OK ) {
-  printErrCode(i);
-  ret=false;
-  goto end;
- }
- printf("QOS mode: ");
- if ( s==QOS_DOT ) {
-  printf("802.1p\n");
-  goto end;
- } else if ( s!=QOS_PORT ) {
-  printf("unknown (%i)\n", s);
-  goto end;
- }
- printf("port based\n");
- ports=malloc(sa->ports*sizeof(char));
- if ( (i=ngadmin_getQOSValues(nga, ports))!=ERR_OK ) {
-  printErrCode(i);
-  ret=false;
-  goto end;
- }
- for (i=0; i<sa->ports; ++i) {
-  printf("port %i: %s\n", i+1, prio[(int)ports[i]]);
- }
- end:
- free(ports);
- return ret;
-}
-
-
-
-// =============================================================================
 // quit
+bool do_quit (int nb, const char **com, struct ngadmin *nga);
 
 
-static bool do_quit (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga UNUSED) {
- cont=0;
- return true;
-}
-
-
-
-// =============================================================================
 // restart
+bool do_restart (int nb, const char **com, struct ngadmin *nga);
 
 
-static bool do_restart (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga UNUSED) {
- int i, ret=true;
- const struct swi_attr *sa;
- char line[16];
- if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
-  printf("must be logged\n");
-  ret=false;
-  goto end;
- }
- printf("The switch will be restarted. Continue ? [y/N]: ");
- fflush(stdout);
- if ( fgets(line, sizeof(line), stdin)!=NULL && strcasecmp(line, "y\n")==0 ) {
-  i=ngadmin_restart(nga);
-  printErrCode(i);
- }
- end:
- return ret;
-}
-
-
-
-// =============================================================================
 // scan
+bool do_scan (int nb, const char **com, struct ngadmin *nga);
 
 
-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;
-}
-
-
-
-// =============================================================================
 // stormfilter
+bool do_stormfilter_enable (int nb, const char **com, struct ngadmin *nga);
+bool do_stormfilter_disable (int nb, const char **com, struct ngadmin *nga);
+bool do_stormfilter_set (int nb, const char **com, struct ngadmin *nga);
+bool do_stormfilter_show (int nb, const char **com, struct ngadmin *nga);
 
 
-static bool do_stormfilter_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_stormfilter_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_stormfilter_set (int nb, const char **com, struct ngadmin *nga) {
- int i, d=BITRATE_UNSPEC, p, *ports=NULL;
- const struct swi_attr *sa;
- bool ret=true;
- if ( nb<2 ) {
-  printf("Usage: stormfilt set (all <speed0>)|(<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));
- if ( strcmp(com[0], "all")==0 ) {
-  d=parseBitrate(com[1]);
-  com+=2;
-  nb-=2;
- }
- for (i=0; i<sa->ports; ++i) {
-  ports[i]=d;
- }
- 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_stormfilter_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: %s\n", i+1, bitrates[ports[i]]);
- }
- end:
- free(ports);
- return ret;
-}
-
-
-
-// =============================================================================
 // tree
+bool do_tree (int nb, const char **com, struct ngadmin *nga);
 
 
-static void display_node (const struct TreeNode *tn, int depth) {
- int i;
- const struct TreeNode *s;
- for (i=0; i<depth; ++i) {
-  putchar('\t');
- }
- puts(tn->name);
- if ( tn->sub==NULL ) return;
- for (s=tn->sub; s->name!=NULL; ++s) {
-  display_node(s, depth+1);
- }
-}
-
-
-static bool do_tree (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga UNUSED) {
- display_node(&coms, 0);
- return true;
-}
-
-
-
-// =============================================================================
 // vlan
+bool do_vlan_8021q_show (int nb, const char **com, struct ngadmin *nga);
+bool do_vlan_mode_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga);
+bool do_vlan_pvid_show (int nb, const char **com, struct ngadmin *nga);
 
 
-static char vlan_char (int t) {
- switch ( t ) {
-  case VLAN_TAGGED: return 'T';
-  case VLAN_UNTAGGED: return 'U'; 
-  case VLAN_NO: return ' ';
-  default: return '?';
- }
-}
-
-
-static bool print_vlan_pvid (struct ngadmin *nga) {
- unsigned short *ports=NULL;
- const struct swi_attr *sa;
- int i;
- bool ret=true;
- sa=ngadmin_getCurrentSwitch(nga);
- ports=malloc(sa->ports*sizeof(unsigned short));
- i=ngadmin_getPVID(nga, ports);
- if ( i!=ERR_OK ) {
-  printErrCode(i);
-  ret=false;
-  goto end;
- }
- printf("PVID: \n");
- printf("Port\t");
- for (i=1; i<=sa->ports; ++i) {
-  printf("%i\t", i);
- }
- putchar('\n');
- printf("VLAN\t");
- for (i=0; i<sa->ports; ++i) {
-  printf("%u\t", ports[i]);
- }
- putchar('\n');
- end:
- free(ports);
- return ret;
-}
-
-
-static bool print_vlan_dot_adv (struct ngadmin *nga) {
- char buffer[512], *b=buffer;
- const struct swi_attr *sa;
- int i, t;
- sa=ngadmin_getCurrentSwitch(nga);
- t=sizeof(buffer);
- i=ngadmin_getVLANDotConf(nga, buffer, &t);
- if ( i!=ERR_OK ) {
-  printErrCode(i);
-  return false;
- }
- printf("Ports configuration: \n");
- printf("VLAN\t");
- for (i=1; i<=sa->ports; ++i) {
-  printf("%i\t", i);
- }
- putchar('\n');
- while ( b-buffer<t ) {
-  printf("%u\t", *(unsigned short*)b);b+=2;
-  for (i=1; i<=sa->ports; ++i) {
-   printf("%c\t", vlan_char(*b++));
-  }
-  putchar('\n');
- }
- return true;
-}
-
-
-static bool do_vlan_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
- int i, t, ret=true;
- if ( ngadmin_getCurrentSwitch(nga)==NULL ) {
-  printf("must be logged\n");
-  ret=false;
-  goto end;
- }
- if ( (i=ngadmin_getVLANType(nga, &t))!=ERR_OK ) {
-  printErrCode(i);
-  ret=false;
-  goto end;
- }
- printf("VLAN type: ");
- switch ( t ) {
-  case VLAN_DISABLED: printf("disabled\n"); break;
-  case VLAN_PORT_BASIC: printf("port basic\n"); break;
-  case VLAN_PORT_ADV: printf("port advanced\n"); break;
-  case VLAN_DOT_BASIC: printf("802.1Q basic\n"); break;
-  
-  case VLAN_DOT_ADV:
-   printf("802.1Q advanced\n\n");
-   ret=print_vlan_dot_adv(nga);
-   putchar('\n');
-   ret=print_vlan_pvid(nga);
-  break;
-  
-  default: printf("unknown (%i)\n", t);
- }
- end:
- return ret;
-}
-
-
-
-// =============================================================================
-
 
+// commands structure
 COM_ROOT_START(coms)
  
  COM_START(bitrate)
@@ -1443,8 +175,28 @@ COM_ROOT_START(coms)
  COM_TERM(tree, do_tree, false)
  
  COM_START(vlan)
-  COM_TERM(show, do_vlan_show, false)
-  COM_TERM(mode, NULL, true)
+  COM_START(802.1q)
+   COM_START(port)
+    COM_TERM(add, NULL, true)
+    COM_TERM(del, NULL, true)
+   COM_END
+   COM_TERM(show, do_vlan_8021q_show, true)
+   COM_START(vlan)
+    COM_TERM(add, NULL, true)
+    COM_TERM(del, NULL, true)
+    COM_TERM(flush, NULL, true)
+   COM_END
+  COM_END
+  COM_START(mode)
+   COM_TERM(set, NULL, true)
+   COM_TERM(show, do_vlan_mode_show, false)
+  COM_END
+  COM_START(port)
+  COM_END
+  COM_START(pvid)
+   COM_TERM(set, NULL, true)
+   COM_TERM(show, do_vlan_pvid_show, false)
+  COM_END
  COM_END
  
 COM_ROOT_END
index d7d670262fd87179672b7f62e93e83f7112f9699..adaddfed53faf4ce33c74ffb6522f65de721b117 100644 (file)
@@ -252,7 +252,11 @@ int ngadmin_getVLANType (struct ngadmin *nga, int *t) EXPORT;
 
 
 // 
-int ngadmin_getVLANDotConf (struct ngadmin *nga, char *buf, int *len) EXPORT;
+int ngadmin_getVLANDotAllConf (struct ngadmin *nga, unsigned short *vlans, unsigned char *ports, int *nb) EXPORT;
+
+
+// 
+int ngadmin_getVLANDotConf (struct ngadmin *nga, unsigned short vlan, unsigned char *ports) EXPORT;
 
 
 // 
index 52837d0243260a5687ff06c5c079f2d36505be65..77012ea4376eaba1bd0bfe14b1647bbb4523b8bc 100644 (file)
@@ -218,6 +218,24 @@ int recvNgPacket (struct ngadmin *nga, char code, unsigned short *error, unsigne
 
 
 
+int checkErrorCode (unsigned short err, unsigned short attr_error) {
+ if ( err==0x0700 && attr_error==ATTR_PASSWORD ) {
+  return ERR_BADPASS;
+ }
+ if ( err==0x0500 ) {
+  return ERR_INVARG;
+ }
+ return ERR_OK;
+}
+
+
+
 // ----------------------------------------------
 int readRequest (struct ngadmin *nga, List *attr) {
  
@@ -243,14 +261,12 @@ int readRequest (struct ngadmin *nga, List *attr) {
   goto end;
  }
  
- if ( err==0x0700 && attr_error==ATTR_PASSWORD ) {
-  ret=ERR_BADPASS;
-  goto end;
- }
  
+ // check error code
+ ret=checkErrorCode(err, attr_error);
  
- end:
  
+ end:
  
  return ret;
  
@@ -295,12 +311,8 @@ int writeRequest (struct ngadmin *nga, List *attr) {
   goto end;
  }
  
- if ( err==0x0700 && attr_error==ATTR_PASSWORD ) {
-  ret=ERR_BADPASS;
-  goto end;
- }
- // err==0x0500
+ // check error code
+ ret=checkErrorCode(err, attr_error);
  
  
  end:
index 33930802a7d05df06327a5413aec843426f44c6b..f1dee3e595737a54477e9ac4d3c6009c29539e3a 100644 (file)
@@ -268,7 +268,10 @@ int ngadmin_login (struct ngadmin *nga, int id) {
  
  attr=createEmptyList();
  pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
- if ( (ret=readRequest(nga, attr))!=ERR_OK ) {
+ if ( (ret=readRequest(nga, attr))==ERR_OK ) {
+  // login succeeded
+  // TODO: if keep broadcasting is disabled, connect() the UDP socket so icmp errors messages (port unreachable, TTL exceeded in transit, ...)can be received
+ } else {
   // login failed
   nga->current=NULL;
  }
@@ -959,7 +962,7 @@ int ngadmin_getIGMPConf (struct ngadmin *nga, struct igmp_conf *ic) {
  ATTR_IGMP_BLOCK_UNK
  ATTR_IGMP_VALID_V3
  
- Apparently, read-querying theses attributes at the same time causes the switch to reply garbage. 
+ Apparently, read-querying these attributes at the same time causes the switch to reply garbage. 
  Here we are forced to do like the official win app and send a separate request for each attribute. 
  */
  
@@ -1211,26 +1214,26 @@ int ngadmin_getVLANType (struct ngadmin *nga, int *t) {
 
 
 
-// ------------------------------------------------------------------
-int ngadmin_getVLANDotConf (struct ngadmin *nga, char *buf, int *len) {
+// ------------------------------------------------------------------------------------------------------
+int ngadmin_getVLANDotAllConf (struct ngadmin *nga, unsigned short *vlans, unsigned char *ports, int *nb) {
  
  List *attr;
  ListNode *ln;
  struct attr *at;
  struct swi_attr *sa;
  int ret=ERR_OK, total, i;
- char *b=buf, *p=NULL;
+ char *p=NULL;
  
  
- if ( nga==NULL || buf==NULL || len==NULL || *len<=0 ) {
+ if ( nga==NULL || vlans==NULL || ports==NULL || nb==NULL || *nb<=0 ) {
   return ERR_INVARG;
  } else if ( (sa=nga->current)==NULL ) {
   return ERR_NOTLOG;
  }
  
  
- total=*len;
- *len=0;
+ total=*nb;
+ *nb=0;
  
  attr=createEmptyList();
  pushBackList(attr, newEmptyAttr(ATTR_VLAN_DOT_CONF));
@@ -1242,15 +1245,65 @@ int ngadmin_getVLANDotConf (struct ngadmin *nga, char *buf, int *len) {
  for (ln=attr->first; ln!=NULL; ln=ln->next) {
   at=ln->data;
   p=at->data;
-  if ( *len+2+sa->ports>total ) break; // no more room
+  if ( *nb>=sa->ports ) break; // no more room
   if ( at->attr==ATTR_VLAN_DOT_CONF && at->size>=4 ) {
-   *(unsigned short*)b=ntohs(*(unsigned short*)p);b+=2;
    for (i=1; i<=sa->ports; ++i) {
-    if ( (p[3]>>(sa->ports-i))&1 ) *b++=VLAN_TAGGED; // tagged
-    else if ( (p[2]>>(sa->ports-i))&1 ) *b++=VLAN_UNTAGGED; // untagged
-    else *b++=VLAN_NO;
+    if ( (p[3]>>(sa->ports-i))&1 ) ports[i-1]=VLAN_TAGGED; // tagged
+    else if ( (p[2]>>(sa->ports-i))&1 ) ports[i-1]=VLAN_UNTAGGED; // untagged
+    else ports[i-1]=VLAN_NO;
    }
-   *len+=2+sa->ports;
+   *vlans++=ntohs(*(unsigned short*)p);
+   ports+=sa->ports;
+   ++*nb;
+  }
+ }
+ end:
+ destroyList(attr, (void(*)(void*))freeAttr);
+ return ret;
+}
+
+
+
+// ----------------------------------------------------------------------------------------
+int ngadmin_getVLANDotConf (struct ngadmin *nga, unsigned short vlan, unsigned char *ports) {
+ List *attr;
+ ListNode *ln;
+ struct attr *at;
+ struct swi_attr *sa;
+ int ret=ERR_OK, i;
+ char *p=NULL;
+ if ( nga==NULL || ports==NULL ) {
+  return ERR_INVARG;
+ } else if ( (sa=nga->current)==NULL ) {
+  return ERR_NOTLOG;
+ }
+ attr=createEmptyList();
+ pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
+ if ( (ret=readRequest(nga, attr))!=ERR_OK ) {
+  goto end;
+ }
+ for (ln=attr->first; ln!=NULL; ln=ln->next) {
+  at=ln->data;
+  p=at->data;
+  if ( at->attr==ATTR_VLAN_DOT_CONF && at->size>=4 ) {
+   for (i=1; i<=sa->ports; ++i) {
+    if ( (p[3]>>(sa->ports-i))&1 ) ports[i-1]=VLAN_TAGGED; // tagged
+    else if ( (p[2]>>(sa->ports-i))&1 ) ports[i-1]=VLAN_UNTAGGED; // untagged
+    else ports[i-1]=VLAN_NO;
+   }
+   break;
   }
  }
  
index 11475ce20f4864b74a33917b78af58c831dfd30e..bbd3933c7252f46b9e74d1389cc25374d2c02208 100644 (file)
--- a/nsdp.lua
+++ b/nsdp.lua
@@ -1,5 +1,6 @@
 
 p_nsdp=Proto("nsdp", "Netgear Switch Description Protocol")
+
 local f_version=ProtoField.uint8("nsdp.version", "Version", base.DEC)
 local f_code=ProtoField.uint8("nsdp.code", "Operation Code", base.DEC)
 local f_error=ProtoField.uint8("nsdp.error", "Error Code", base.DEC)
@@ -8,34 +9,14 @@ local f_clientmac=ProtoField.ether("nsdp.clientmac", "Client MAC")
 local f_switchmac=ProtoField.ether("nsdp.switchmac", "Switch MAC")
 local f_seqnum=ProtoField.uint32("nsdp.seqnum", "Sequence Number", base.DEC)
 
-local f_attr=ProtoField.uint16("", "Attribute", base.HEX)
-local f_attr_code=ProtoField.uint16("", "Attribute Code", base.HEX)
-local f_attr_length=ProtoField.uint16("", "Attribute Length", base.DEC)
-local f_attr_data=ProtoField.bytes("", "Attribute Data")
-
-local f_attr_product=ProtoField.string("", "Product")
-local f_attr_name=ProtoField.string("", "Name")
-local f_attr_mac=ProtoField.ether("", "MAC")
-local f_attr_ip=ProtoField.ipv4("", "IP")
-local f_attr_mask=ProtoField.ipv4("", "Mask")
-local f_attr_gateway=ProtoField.ipv4("", "Gateway")
-local f_attr_newpassword=ProtoField.string("", "New Password")
-local f_attr_password=ProtoField.string("", "Password")
-local f_attr_dhcp=ProtoField.bool("", "DHCP")
-local f_attr_firmver=ProtoField.string("", "Firmare Version")
-local f_attr_portscount=ProtoField.uint8("", "Ports Count", base.DEC)
-local f_attr_port=ProtoField.uint8("", "Port", base.DEC)
-local f_attr_port_status=ProtoField.uint8("", "Port Status", base.DEC)
-
 p_nsdp.fields={
- f_version, f_code, f_error, f_errattr, f_clientmac, f_switchmac, f_seqnum, 
- f_attr, f_attr_code, f_attr_length, f_attr_data, 
- f_attr_product, f_attr_name, f_attr_mac, f_attr_ip, f_attr_mask, f_attr_gateway, f_attr_newpassword, f_attr_password, f_attr_portscount, 
- f_attr_dhcp, f_attr_port, f_attr_port_status, f_attr_firmver
+ f_version, f_code, f_error, f_errattr, f_clientmac, f_switchmac, f_seqnum
 }
 
 
 
+
+
 local op_codes={
  [1]="Read Request", 
  [2]="Read Reply", 
@@ -58,40 +39,179 @@ local status_codes={
 }
 
 
+local bitrates_codes={
+ [0]="unlimited", 
+ [1]="512K", 
+ [2]="1M", 
+ [3]="2M", 
+ [4]="4M", 
+ [5]="8M", 
+ [6]="16M", 
+ [7]="32M", 
+ [8]="64M", 
+ [9]="128M", 
+ [10]="256M", 
+ [11]="512M"
+}
+
+
+local vlan_type_codes={
+ [1]="port basic", 
+ [2]="port advanced", 
+ [3]="802.1Q basic", 
+ [4]="802.1Q advanced"
+}
+
+
+local qos_type_codes={
+ [1]="port based", 
+ [2]="802.1p"
+}
+
+
+local prio_codes={
+ [1]="high", 
+ [2]="medium", 
+ [3]="normal", 
+ [4]="low"
+}
+
+
 
 
+local function dissect_port_statistics (buffer, offset, subtree)
+ subtree:add(buffer(offset+4, 1), string.format("Port: %i", buffer(offset+4, 1):uint()))
+ subtree:add(buffer(offset+4+1+8*0, 8), "Received:", tostring(buffer(offset+4+1+8*0, 8):uint64()))
+ subtree:add(buffer(offset+4+1+8*1, 8), "Sent: ", tostring(buffer(offset+4+1+8*1, 8):uint64()))
+ subtree:add(buffer(offset+4+1+8*5, 8), "CRC Errors:", tostring(buffer(offset+4+1+8*5, 8):uint64()))
+end
+
 
-function dissect_port_status (buffer, offset, subtree)
+
+local function dissect_port_status (buffer, offset, subtree)
  
- subtree:add(f_attr_port, buffer(offset+4, 1))
- subtree:add(f_attr_port_status, buffer(offset+5, 1)):append_text(" ("..(status_codes[buffer(offset+5, 1):uint()] or "unk")..")")
+ local st=buffer(offset+5, 1):uint()
+ subtree:add(buffer(offset+4, 1), string.format("Port: %i", buffer(offset+4, 1):uint()))
+ subtree:add(buffer(offset+5, 1), string.format("Status: %i (%s)", st, status_codes[st] or "unk"))
  
 end
 
 
 
+local function dissect_bitrate (buffer, offset, subtree)
+ local sp=buffer(offset+5, 4):uint()
+ subtree:add(buffer(offset+4, 1), string.format("Port: %i", buffer(offset+4, 1):uint()))
+ subtree:add(buffer(offset+5, 4), string.format("Speed: %i (%s)", sp, bitrates_codes[sp] or "unk"))
+end
+
+
+local function dissect_vlan_type (buffer, offset, subtree)
+ local vt=buffer(offset+4, 1):uint()
+ subtree:add(buffer(offset+4, 1), string.format("VLAN Type: %i (%s)", vt, vlan_type_codes[vt] or "unk"))
+end
+
+
+local function parse_ports (val)
+ local ports=""
+ for i=8,1,-1 do
+  if ( val%2==1 ) then
+   ports=ports..i.." "
+  end
+  val=math.floor(val/2)
+ end
+ return ports
+end
+
+
+local function dissect_vlan_8021q_conf (buffer, offset, subtree)
+ subtree:add(buffer(offset+4, 2), string.format("VLAN: %u", buffer(offset+4, 2):uint()))
+ if ( buffer(offset+2, 2):uint()>=4 ) then
+  subtree:add(buffer(offset+6, 1), "Ports:", parse_ports(buffer(offset+6, 1):uint()))
+  subtree:add(buffer(offset+7, 1), "Tagged Ports:", parse_ports(buffer(offset+7, 1):uint()))
+ end
+end
+
+
+local function dissect_vlan_pvid (buffer, offset, subtree)
+ subtree:add(buffer(offset+4, 1), string.format("Port: %i", buffer(offset+4, 1):uint()))
+ subtree:add(buffer(offset+5, 2), string.format("VLAN: %u", buffer(offset+5, 2):uint()))
+end
+
+
+
+local function dissect_mirror (buffer, offset, subtree)
+ local op=buffer(offset+4, 1):uint()
+ if ( op==0 ) then
+  subtree:add(buffer(offset+4, 1), "Disabled")
+ else
+  subtree:add(buffer(offset+4, 1), "Output Port:", op)
+  subtree:add(buffer(offset+6, 1), "Ports:", parse_ports(buffer(offset+6, 1):uint()))
+ end
+end
+
 
 
 local attributes={
- [0x0001]={name="Product", dissect=f_attr_product}, 
- [0x0003]={name="Name", dissect=f_attr_name}, 
- [0x0004]={name="MAC", dissect=f_attr_mac}, 
- [0x0006]={name="IP", dissect=f_attr_ip}, 
- [0x0007]={name="Mask", dissect=f_attr_mask}, 
- [0x0008]={name="Gateway", dissect=f_attr_gateway}, 
- [0x0009]={name="New Password", dissect=f_attr_newpassword}, 
- [0x000A]={name="Password", dissect=f_attr_password}, 
- [0x000B]={name="DHCP", dissect=f_attr_dhcp}, 
- [0x000D]={name="Firmware Version", dissect=f_attr_firmver}, 
+ [0x0001]={name="Product", dissect="string"}, 
+ [0x0003]={name="Name", dissect="string"}, 
+ [0x0004]={name="MAC", dissect="ether"}, 
+ [0x0006]={name="IP", dissect="ipv4"}, 
+ [0x0007]={name="Mask", dissect="ipv4"}, 
+ [0x0008]={name="Gateway", dissect="ipv4"}, 
+ [0x0009]={name="New Password", dissect="string"}, 
+ [0x000A]={name="Password", dissect="string"}, 
+ [0x000B]={name="DHCP", dissect="uint"}, 
+ [0x000D]={name="Firmware Version", dissect="string"}, 
+ [0x0013]={name="Restart", dissect="uint"}, 
+ [0x0400]={name="Defaults", dissect="uint"}, 
  [0x0C00]={name="Port Status", dissect=dissect_port_status}, 
- [0x6000]={name="Ports Count", dissect=f_attr_portscount}
+ [0x1000]={name="Port Statistics", dissect=dissect_port_statistics}, 
+ [0x1400]={name="Reset Ports Statistics", dissect="uint"}, 
+ [0x1800]={name="Cabletest Do", dissect=nil}, 
+ [0x1C00]={name="Cabletest Result", dissect=nil}, 
+ [0x2000]={name="VLAN Type", dissect=dissect_vlan_type}, 
+ [0x2400]={name="VLAN Port Conf", dissect=nil}, 
+ [0x2800]={name="VLAN 802.1Q Conf", dissect=dissect_vlan_8021q_conf}, 
+ [0x2C00]={name="Destroy VLAN", dissect="uint"}, 
+ [0x3000]={name="VLAN PVID", dissect=dissect_vlan_pvid}, 
+ [0x3400]={name="QoS Type", dissect=nil}, 
+ [0x3800]={name="QoS Config", dissect=nil}, 
+ [0x4C00]={name="Input Bitrate", dissect=dissect_bitrate}, 
+ [0x5000]={name="Output Bitrate", dissect=dissect_bitrate}, 
+ [0x5400]={name="Broadcast Filtering State", dissect="uint"}, 
+ [0x5800]={name="Broadcast Filtering Bitrate", dissect=dissect_bitrate}, 
+ [0x5C00]={name="Mirror", dissect=dissect_mirror}, 
+ [0x6000]={name="Ports Count", dissect="uint"}, 
+ [0x6800]={name="IGMP Enable & VLAN", dissect=nil}, 
+ [0x6C00]={name="Block Unknown IGMP Addresses", dissect="uint"}, 
+ [0x7000]={name="Validate IGMPv3 Headers", dissect="uint"}, 
+ [0xFFFF]={name="End", dissect=nil}
 }
 
 
 
 
 
-function dissect_header (buffer, subtree)
+
+local function dissect_header (buffer, subtree)
  
  subtree:add(f_version, buffer(0, 1))
  
@@ -100,7 +220,7 @@ function dissect_header (buffer, subtree)
  local errcode=buffer(2, 1):uint()
  subtree:add(f_error, buffer(2, 1)):append_text(" ("..(error_codes[errcode] or "unknown")..")")
  
- -- print the erroneous attribute if an error occurred
+ -- add the erroneous attribute only if an error occurred
  if ( errcode~=0 ) then
   local atf=attributes[buffer(4, 2):uint()]
   subtree:add(f_errattr, buffer(4, 2)):append_text(" ("..(atf and atf.name or "unk")..")")
@@ -117,34 +237,46 @@ end
 
 
 
-function dissect_attributes (buffer, subtree)
+local function dissect_attributes (buffer, subtree)
  
  local offset=32
  
  while ( offset<buffer:len() ) do
   
+  if ( offset+4>buffer:len() ) then
+   -- no room for an attribute header, it is an error
+   subtree:add(buffer(offset), "Junk"):set_expert_flags(PI_MALFORMED, PI_ERROR)
+   break
+  end
+  
   local code=buffer(offset, 2):uint()
   local len=buffer(offset+2, 2):uint()
   local atf=attributes[code]
   
-  local attr=subtree:add(f_attr, buffer(offset, 4+len), code)
-  attr:append_text(" ("..(atf and atf.name or "unk")..")")
+  local attr=subtree:add(buffer(offset, math.min(4+len, buffer:len()-offset)), string.format("Attribute: 0x%04X (%s)", code, atf and atf.name or "unk"))
+  attr:add(buffer(offset, 2), string.format("Code: 0x%04X", code))
+  attr:add(buffer(offset+2, 2), string.format("Length: %u", len))
   
-  attr:add(f_attr_code, buffer(offset, 2))
+  if ( offset+4+len>buffer:len() ) then
+   -- attribute length is bigger than remaining packet size, it is an error
+   attr:append_text(" [malformed]")
+   attr:set_expert_flags(PI_MALFORMED, PI_ERROR)
+   break
+  end
   
-  attr:add(f_attr_length, buffer(offset+2, 2))
   
   if ( len<=0 ) then
    -- no data, display nothing
-  elseif ( atf==nil ) then
+  elseif ( atf==nil or atf.dissect==nil ) then
    -- unknown attribute, display raw bytes
-   attr:add(f_attr_data, buffer(offset+4, len))
+   attr:add(buffer(offset+4, len), "Data:", tostring(buffer(offset+4, len):bytes()))
   elseif ( type(atf.dissect)=="function" ) then
    -- custom sub-dissector for complex type
    atf.dissect(buffer, offset, attr)
   else
-   -- simple type, directly use field
-   attr:add(atf.dissect, buffer(offset+4, len))
+   -- simple type, directly show it
+   local func=assert(loadstring("return function(buffer, offset, len) return tostring(buffer(offset+4, len):"..atf.dissect.."()) end"))() -- ugly, isn't it ?
+   attr:add(buffer(offset+4, len), atf.name..":", func(buffer, offset, len))
   end
   
   offset=offset+4+len
@@ -166,7 +298,7 @@ function p_nsdp.dissector (buffer, pinfo, tree)
  dissect_header(buffer, subtree)
  
  -- stop if it is just a header
- if ( buffer:len()<=32 ) then return end
+ if ( buffer:len()==32 ) then return end
  
  local attr_list=subtree:add(buffer(32), "Attributes list")
  dissect_attributes(buffer, attr_list)