]> git.sur5r.net Git - ngadmin/commitdiff
Merge branch 'autotools'
authordarkcoven <admin@darkcoven.tk>
Fri, 11 Oct 2013 19:48:29 +0000 (21:48 +0200)
committerdarkcoven <admin@darkcoven.tk>
Fri, 11 Oct 2013 19:48:29 +0000 (21:48 +0200)
Conflicts:
cli/src/admin.c

1  2 
cli/src/admin.c
cli/src/com_vlan.c

diff --combined cli/src/admin.c
index 0000000000000000000000000000000000000000,dbd30bbaeaf260fca48659de9cdf1fec1e376473..73ea79c7a3cc143a8cdcb5a48cadb70d857de0ca
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,407 +1,411 @@@
 -int main_loop_continue;
 -
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+ #endif
+ #include <stdio.h>
+ #include <signal.h>
+ #include <unistd.h>
+ #include <setjmp.h>
+ #include <getopt.h>
+ #ifdef HAVE_LIBREADLINE
+ #include <readline/readline.h>
+ #include <readline/history.h>
+ #endif
+ #include "common.h"
+ #include "commands.h"
+ #define MAXCOM        32
 -              if (!batch)
+ static const struct TreeNode* getSubCom (char **com, int n, int *t)
+ {
+       int i;
+       const struct TreeNode *cur, *next;
+       
+       
+       cur = &commands;
+       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)
+                       break;
+               
+               /* next command is now the current one */
+               cur = next;
+       }
+       
+       *t = i;
+       
+       
+       return cur;
+ }
+ #ifdef HAVE_LIBREADLINE
+ static const struct TreeNode *compcur;
+ static 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;
+               len = strlen(text);
+       }
+       
+       if (tn == NULL) /* terminal command */
+               return NULL;
+       
+       while ((name = tn++->name) != NULL) {
+               if (strncmp(name, text, len) == 0)
+                       return strdup(name);
+       }
+       
+       
+       return NULL;
+ }
+ static char** my_completion (const char *text, int start, int end UNUSED)
+ {
+       char **matches = NULL;
+       char *line, *com[MAXCOM];
+       int i, n;
+       
+       
+       memset(com, 0, MAXCOM * sizeof(char*));
+       line = strdup(rl_line_buffer);
+       line[start] = '\0';
+       trim(line, start);
+       n = explode(line, com, MAXCOM);
+       free(line);
+       
+       compcur = getSubCom(com, n, &i);
+       
+       if (i < n)
+               compcur = NULL;
+       matches = rl_completion_matches(text, my_generator);
+       
+       for (i = 0; com[i] != NULL; i++)
+               free(com[i]);
+       
+       
+       return matches;
+ }
+ #endif /* HAVE_LIBREADLINE */
++int main_loop_continue;
+ static struct ngadmin *nga;
+ static sigjmp_buf jmpbuf;
+ static struct termios orig_term;
+ struct termios current_term;
+ static bool batch;
+ NORET static void handler (int sig)
+ {
+       switch (sig) {
+       
+       case SIGTERM:
+       case SIGINT:
+               printf("interrupt\n");
+               
+               current_term.c_lflag |= ECHO;
+               tcsetattr(STDIN_FILENO, TCSANOW, &current_term);
+               
 -                      continue;
++              if (!batch && main_loop_continue)
+                       siglongjmp(jmpbuf, 1);
+       
+       default:
+               ngadmin_close(nga);
+               
+               tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
+               
+               exit(0);
+       }
+ }
+ static int pre_login (const struct ether_addr *mac, int retries)
+ {
+       const struct swi_attr *sa;
+       int i, n, err;
+       
+       
+       for (i = 1; retries <= 0 || i <= retries; i++) {
+               /* scan */
+               printf("scan... ");
+               fflush(stdout);
+               err = ngadmin_scan(nga);
+               if (err < 0) {
+                       printErrCode(err);
 -              {"global-broadcast", no_argument, NULL, 'g'},
++                      return err;
+               }
+               
+               /* search switch with requested MAC */
+               sa = ngadmin_getSwitchTab(nga, &n);
+               while (--n >= 0) {
+                       if (memcmp(mac, &sa[n].mac, ETH_ALEN) == 0)
+                               break;
+               }
+       
+               if (n < 0) {
+                       printf("no switch found\n");
+               } else {
+                       printf("done\n");
+                       break;
+               }
+       }
+       
+       if (n < 0)
+               return 1;
+       /* login */
+       printf("login... ");
+       fflush(stdout);
+       err = ngadmin_login(nga, n);
+       if (err < 0)
+               printErrCode(err);
+       else
+               printf("done\n");
+       
+       return err;
+ }
+ int main (int argc, char **argv)
+ {
+       static const struct option opts[] = {
+               {"batch", no_argument, NULL, 'a'},
+               {"keep-broadcasting", no_argument, NULL, 'b'},
+               {"force-interface", no_argument, NULL, 'f'},
 -      bool kb = false, force = false, global = false;
+               {"help", no_argument, NULL, 'h'},
+               {"interface", required_argument, NULL, 'i'},
++              {"local-broadcast", no_argument, NULL, 'l'},
+               {"mac", required_argument, NULL, 'm'},
+               {"password", required_argument, NULL, 'p'},
+               {"retries", required_argument, NULL, 'r'},
+               {"timeout", required_argument, NULL, 't'},
+               {0, 0, 0, 0}
+       };
+       char *line, *com[MAXCOM];
+       const char *iface = "eth0", *password = NULL;
+       float timeout = 0.f;
 -      while ((n = getopt_long(argc, argv, "abfghi:m:p:r:t:", opts, NULL)) != -1) {
++      bool kb = false, force = false, global = true;
+       struct timeval tv;
+       const struct TreeNode *cur, *next;
+       struct ether_addr *mac = NULL;
+       int i, n, retries = 3;
+       
+       
+       tcgetattr(STDIN_FILENO, &orig_term);
+       current_term = orig_term;
+ #ifdef HAVE_LIBREADLINE
+       batch = false;
+ #else
+       batch = true;
+ #endif
+       
+       opterr = 0;
+       
 -              case 'g':
 -                      global = true;
 -                      break;
 -              
++      while ((n = getopt_long(argc, argv, "abfhi:lm:p:r:t:", opts, NULL)) != -1) {
+               switch (n) {
+               
+               case 'a':
+                       batch = true;
+                       break;
+               
+               case 'b':
+                       kb = true;
+                       break;
+               
+               case 'f':
+                       force = true;
+                       break;
+               
 -      if (kb && ngadmin_setKeepBroadcasting(nga, true) != ERR_OK)
+               case 'h':
+                       printf("usage: %s [-a] [-b] [-f] [-g] [-i <interface>] [-m <MAC>] [-p <password>]\n", argv[0]);
+                       goto end;
+               
+               case 'i':
+                       iface = optarg;
+                       break;
+               
++              case 'l':
++                      global = false;
++                      break;
++              
+               case 'm':
+                       mac = ether_aton(optarg);
+                       if (mac == NULL) {
+                               printf("invalid MAC\n");
+                               goto end;
+                       }
+                       break;
+               
+               case 'p':
+                       password = optarg;
+                       break;
+               
+               case 'r':
+                       retries = strtol(optarg, NULL, 0);
+                       break;
+               
+               case 't':
+                       timeout = strtof(optarg, NULL);
+                       break;
+               
+               case '?':
+                       printf("unknown option: \"%s\"\n", argv[optind - 1]);
+                       goto end;
+               }
+       }
+       
+       argc -= optind;
+       argv += optind;
+       
+       if (argc != 0) {
+               printf("unknown trailing options\n");
+               goto end;
+       }
+       
+       
+       memset(com, 0, MAXCOM * sizeof(char*));
+       
+       nga = ngadmin_init(iface);
+       if (nga == NULL) {
+               fprintf(stderr, "initialization error\n");
+               goto end;
+       }
+       
+       /* set timeout */
+       if (timeout > 0.f) {
+               tv.tv_sec = (int)timeout;
+               tv.tv_usec = (int)((timeout - (float)tv.tv_sec) * 1.e6f);
+               ngadmin_setTimeout(nga, &tv);
+       }
+       
+       
 -      if (global && ngadmin_useGlobalBroadcast(nga, true) != ERR_OK)
++      if (ngadmin_setKeepBroadcasting(nga, kb) != ERR_OK)
+               goto end;
+       
+       if (force && ngadmin_forceInterface(nga) != ERR_OK)
+               goto end;
+       
 -      if (!batch) {
++      if (ngadmin_useGlobalBroadcast(nga, global) != ERR_OK)
+               goto end;
+       
+       /* non-TTY inputs are automatically set to batch mode */
+       if (!isatty(STDIN_FILENO))
+               batch = true;
+       
+       if (password != NULL)
+               ngadmin_setPassword(nga, password);
+       
+       signal(SIGTERM, handler);
+       signal(SIGINT, handler);
+       
+       /* automatic scan & login when switch MAC is specified on the command line */
+       if (mac != NULL && pre_login(mac, retries) != 0)
+               goto end;
+       
 -      
++      if (batch) {
++              /* in batch mode, we must be logged to continue */
++              if (ngadmin_getCurrentSwitch(nga) == NULL) {
++                      printf("must be logged\n");
++                      goto end;
++              }
++      } else {
+ #ifdef HAVE_LIBREADLINE
+               /* initialize readline functions */
+               rl_attempted_completion_function = my_completion;
+               rl_completion_entry_function = my_generator;
+               
+               sigsetjmp(jmpbuf, 1);
+ #endif
+       }
+       
+       main_loop_continue = 1;
+       while (main_loop_continue) {
+               /* read user input */
+               line = NULL;
+               n = 0;
+               if (batch)
+                       n = getline(&line, (size_t*)&i, stdin);
+ #ifdef HAVE_LIBREADLINE
+               else
+                       line = readline("> ");
+ #endif
+               if (n < 0 || line == NULL)
+                       goto end;
+               
+               /* split string into words */
+               trim(line, strlen(line));
+               n = explode(line, com, MAXCOM);
+               
+               if (n == 0) {
+                       free(line);
+                       continue;
+               } else {
+ #ifdef HAVE_LIBREADLINE
+                       if (!batch)
+                               add_history(line);
+ #endif
+                       free(line);
+               }
+               
+               cur = getSubCom(com, n, &i);
+               
+               if (cur->sub != NULL) {
+                       /* not terminal command */
+                       if (i == 0) {
+                               /* root command */
+                               printf("unknown command: %s\n", com[i]);
+                       } else if (i < n) {
+                               /* intermediate command, remaining string */
+                               printf("unknown %s subcommand: %s\n", com[i - 1], com[i]);
+                       } else {
+                               /* intermediate command, no remaining string */
+                               /* print available subcommands */
+                               for (next = cur->sub; next->name != NULL; next++)
+                                       printf("%s ", next->name);
+                               putchar('\n');
+                       }
+               } else if (cur->comfunc == NULL) {
+                       /* erroneous terminal command without function */
+                       printf("terminal command without function\n");
+               } else {
+                       /* execute terminal command */
+                       cur->comfunc(n - i, (const char**)&com[i], nga);
+               }
+               
+               for (i = 0; com[i] != NULL; i++) {
+                       free(com[i]);
+                       com[i] = NULL;
+               }
+       }
+       
+ end:
+       handler(0);
+ }
diff --combined cli/src/com_vlan.c
index 0000000000000000000000000000000000000000,34968152b9fe9a6963cd9e4d59da26154ad7793f..0baa1d5d0c32699d02278abe95c0e490a52974b9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,510 +1,511 @@@
 -      if (mode < 1 || mode > 4) {
+ #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 '?';
+       }
+ }
+ int do_vlan_8021q_del (int argc, const char **argv, struct ngadmin *nga)
+ {
+       const struct swi_attr *sa;
+       unsigned short vlan;
+       int i;
+       
+       
+       if (argc != 1) {
+               printf("usage: vlan 8021q del <vlan>\n");
+               return 1;
+       }
+       
+       sa = ngadmin_getCurrentSwitch(nga);
+       if (sa == NULL) {
+               printf("must be logged\n");
+               return 1;
+       }
+       
+       vlan=strtoul(argv[0], NULL, 0);
+       if (vlan < VLAN_MIN || vlan > VLAN_DOT_MAX) {
+               printf("vlan out of range\n");
+               return 1;
+       }
+       
+       i = ngadmin_VLANDestroy(nga, vlan);
+       printErrCode(i);
+       
+       
+       return 0;
+ }
+ int do_vlan_port_set (int argc, const char **argv, struct ngadmin *nga)
+ {
+       unsigned char vlan, port, *ports = NULL;
+       const struct swi_attr *sa;
+       int i, k = 0, ret = 0;
+       
+       
+       if (argc < 2) {
+               printf("usage: vlan port set [all <vlan>] [<port1> <vlan>] [<port2> <vlan>] [...]\n");
+               ret = 1;
+               goto end;
+       }
+       
+       sa = ngadmin_getCurrentSwitch(nga);
+       if (sa == NULL) {
+               printf("must be logged\n");
+               ret = 1;
+               goto end;
+       }
+       
+       ports = malloc(sa->ports * sizeof(unsigned char));
+       /* read defaults */
+       vlan = 0;
+       if (strcmp(argv[k], "all") == 0) {
+               k++;
+               vlan = strtoul(argv[k++], NULL, 0);
+               /* VLAN 0 is allowed and means no change */
+               if (vlan > VLAN_PORT_MAX) {
+                       printf("vlan out of range\n");
+                       ret = 1;
+                       goto end;
+               }
+       }
+       
+       /* apply defaults */
+       memset(ports, vlan, sa->ports);
+       
+       /* read and apply port specifics */
+       while (k < argc - 1) {
+               /* read port */
+               port = strtoul(argv[k++], NULL, 0);
+               if (port < 1 || port > sa->ports) {
+                       printf("port out of range\n");
+                       ret = 1;
+                       goto end;
+               }
+               
+               /* read vlan */
+               vlan = strtoul(argv[k++], NULL, 0);
+               /* VLAN 0 is allowed and means no change */
+               if (vlan > VLAN_PORT_MAX) {
+                       printf("vlan out of range\n");
+                       ret = 1;
+                       goto end;
+               }
+               
+               ports[port - 1] = vlan;
+       }
+       
+       /* set conf */
+       i = ngadmin_setVLANPortConf(nga, ports);
+       printErrCode(i);
+       
+ end:
+       free(ports);
+       
+       return ret;
+ }
+ int do_vlan_port_show (int argc, const char **argv UNUSED, struct ngadmin *nga)
+ {
+       unsigned char *ports = NULL;
+       const struct swi_attr *sa;
+       int i, ret = 0;
+       
+       
+       if (argc > 0) {
+               printf("this command takes no argument\n");
+               ret = 1;
+               goto end;
+       }
+       
+       sa = ngadmin_getCurrentSwitch(nga);
+       if (sa == NULL) {
+               printf("must be logged\n");
+               ret = 1;
+               goto end;
+       }
+       
+       ports = malloc(sa->ports * sizeof(unsigned char));
+       
+       /* request all VLANs config */
+       i = ngadmin_getVLANPortConf(nga, ports);
+       
+       if (i != ERR_OK) {
+               printErrCode(i);
+               ret = 1;
+               goto end;
+       }
+       
+       printf("Ports configuration: \n");
+       printf("Port\t");
+       for (i = 1; i <= sa->ports; i++)
+               printf("%i\t", i);
+       putchar('\n');
+       
+       /* show all VLANs */
+       printf("VLAN\t");
+       for (i = 0; i < sa->ports; i++)
+               printf("%u\t", ports[i]);
+       putchar('\n');
+       
+ end:
+       free(ports);
+       
+       return ret;
+ }
+ int do_vlan_8021q_set (int argc, const char **argv, struct ngadmin *nga)
+ {
+       unsigned char *ports = NULL, p, def = VLAN_UNSPEC;
+       const struct swi_attr *sa;
+       unsigned short vlan;
+       int i, k = 0, ret = 0;
+       
+       
+       if (argc == 0) {
+               printf("usage: vlan 802.1q set <vlan> [all unspec|no|untagged|tagged] [<port1> unspec|no|untagged|tagged ...]\n");
+               ret = 1;
+               goto end;
+       }
+       
+       sa = ngadmin_getCurrentSwitch(nga);
+       if (sa == NULL) {
+               printf("must be logged\n");
+               ret = 1;
+               goto end;
+       }
+       
+       /* read vlan */
+       vlan = strtoul(argv[k++], NULL, 0);
+       
+       if (vlan < VLAN_MIN || vlan > VLAN_DOT_MAX) {
+               printf("vlan out of range\n");
+               ret = 1;
+               goto end;
+       }
+       
+       /* read defaults */
+       if (k < argc - 1 && strcasecmp(argv[k], "all") == 0) {
+               k++;
+               if (strcasecmp(argv[k], "tagged") == 0) {
+                       def = VLAN_TAGGED;
+               } else if (strcasecmp(argv[k], "untagged") == 0) {
+                       def = VLAN_UNTAGGED;
+               } else if (strcasecmp(argv[k], "no") == 0) {
+                       def = VLAN_NO;
+               } else if (strcasecmp(argv[k], "unspec") == 0) {
+                       def = VLAN_UNSPEC;
+               } else {
+                       printf("incorrect type\n");
+                       ret = 1;
+                       goto end;
+               }
+               k++;
+       }
+       
+       ports = malloc(sa->ports * sizeof(unsigned char));
+       
+       /* apply defaults */
+       memset(ports, def, sa->ports);
+       
+       /* read and apply port specifics */
+       while (k < argc - 1) {
+               p = strtoul(argv[k++], NULL, 0) - 1;
+               if (p >= sa->ports) {
+                       printf("port out of range\n");
+                       ret = 1;
+                       goto end;
+               }
+               if (strcasecmp(argv[k], "tagged") ==0) {
+                       ports[p] = VLAN_TAGGED;
+               } else if (strcasecmp(argv[k], "untagged") == 0) {
+                       ports[p] = VLAN_UNTAGGED;
+               } else if (strcasecmp(argv[k], "no") == 0) {
+                       ports[p] = VLAN_NO;
+               } else if (strcasecmp(argv[k], "unspec") == 0) {
+                       ports[p] = VLAN_UNSPEC;
+               } else {
+                       printf("incorrect type\n");
+                       ret = 1;
+                       goto end;
+               }
+               k++;
+       }
+       
+       /* set conf */
+       i = ngadmin_setVLANDotConf(nga, vlan, ports);
+       printErrCode(i);
+       
+ end:
+       free(ports);
+       
+       return ret;
+ }
+ int do_vlan_8021q_show (int argc, const char **argv, struct ngadmin *nga)
+ {
+       unsigned short vl = 0, *vlans = NULL;
+       unsigned char *ports = NULL;
+       const struct swi_attr *sa;
+       int i, j, n = 16, ret = 0;
+       
+       
+       sa = ngadmin_getCurrentSwitch(nga);
+       if (sa == NULL) {
+               printf("must be logged\n");
+               ret = 1;
+               goto end;
+       }
+       
+       if (argc > 0)
+               vl = strtoul(argv[0], NULL, 0);
+       
+       ports = malloc(sa->ports * n * sizeof(unsigned char));
+       
+       if (vl == 0) {
+               /* request all VLANs config */
+               vlans = malloc(n * sizeof(unsigned short));
+               ports = malloc(sa->ports * n * sizeof(unsigned char));
+               i = ngadmin_getVLANDotAllConf(nga, vlans, ports, &n);
+       } else {
+               /* request single VLAN config */
+               ports = malloc(sa->ports * sizeof(unsigned char));
+               i = ngadmin_getVLANDotConf(nga, vl, ports);
+       }
+       
+       if (i != ERR_OK) {
+               printErrCode(i);
+               ret = 1;
+               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) {
+               /* show all VLANs */
+               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 {
+               /* show single VLAN config */
+               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;
+ }
+ int do_vlan_mode_set (int argc, const char **argv, struct ngadmin *nga)
+ {
+       int mode, i;
+       
+       
+       if (argc == 0) {
+               printf(
+               "usage: vlan mode set <mode>\n"
++              "0 - disabled\n"
+               "1 - basic port based\n"
+               "2 - advanced port based\n"
+               "3 - basic 802.1Q\n"
+               "4 - advanced 802.1Q\n"
+               );
+               return 0;
+       }
+       
+       if (ngadmin_getCurrentSwitch(nga) == NULL) {
+               printf("must be logged\n");
+               return 1;
+       }
+       
+       mode = strtoul(argv[0], NULL, 0);
++      if (mode < VLAN_DISABLED || mode > VLAN_DOT_ADV) {
+               printf("mode out of range\n");
+               return 1;
+       }
+       
+       i = ngadmin_setVLANType(nga, mode);
+       printErrCode(i);
+       
+       
+       return 0;
+ }
+ int do_vlan_mode_show (int argc, const char **argv UNUSED, struct ngadmin *nga)
+ {
+       int i, t, ret = 0;
+       
+       
+       if (argc > 0) {
+               printf("this command takes no argument\n");
+               ret = 1;
+               goto end;
+       }
+       
+       if (ngadmin_getCurrentSwitch(nga) == NULL) {
+               printf("must be logged\n");
+               ret = 1;
+               goto end;
+       }
+       
+       i = ngadmin_getVLANType(nga, &t);
+       if (i != ERR_OK) {
+               printErrCode(i);
+               ret = 1;
+               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;
+ }
+ int do_vlan_pvid_set (int argc, const char **argv, struct ngadmin *nga)
+ {
+       const struct swi_attr *sa;
+       unsigned char port;
+       unsigned short vlan;
+       int i;
+       
+       
+       if (argc != 2) {
+               printf("usage: vlan pvid set <port> <vlan>\n");
+               return 1;
+       }
+       
+       sa = ngadmin_getCurrentSwitch(nga);
+       if (sa == NULL) {
+               printf("must be logged\n");
+               return 1;
+       }
+       
+       port = strtoul(argv[0], NULL, 0);
+       vlan = strtoul(argv[1], NULL, 0);
+       
+       if (port < 1 || port > sa->ports) {
+               printf("port out of range\n");
+               return 1;
+       }
+       
+       if (vlan < VLAN_MIN || vlan > VLAN_DOT_MAX) {
+               printf("vlan out of range\n");
+               return 1;
+       }
+       
+       i = ngadmin_setPVID(nga, port, vlan);
+       printErrCode(i);
+       
+       
+       return 0;
+ }
+ int do_vlan_pvid_show (int argc, const char **argv UNUSED, struct ngadmin *nga)
+ {
+       unsigned short *ports = NULL;
+       const struct swi_attr *sa;
+       int i, ret = 0;
+       
+       
+       if (argc > 0) {
+               printf("this command takes no argument\n");
+               ret = 1;
+               goto end;
+       }
+       
+       sa = ngadmin_getCurrentSwitch(nga);
+       if (sa == NULL) {
+               printf("must be logged\n");
+               ret = 1;
+               goto end;
+       }
+       
+       ports = malloc(sa->ports * sizeof(unsigned short));
+       i = ngadmin_getAllPVID(nga, ports);
+       if (i != ERR_OK) {
+               printErrCode(i);
+               ret = 1;
+               goto end;
+       }
+       
+       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;
+ }