+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;
+}
+