13 static const struct timeval default_timeout = {.tv_sec = 4, .tv_usec = 0};
17 struct ngadmin* ngadmin_init (const char *iface)
22 /* allocate main structure */
23 nga = malloc(sizeof(struct ngadmin));
24 memset(nga, 0, sizeof(struct ngadmin));
26 strncpy(nga->iface, iface, IFNAMSIZ - 1);
28 if (startNetwork(nga) < 0) {
33 nga->timeout = default_timeout;
34 if (updateTimeout(nga) < 0) {
44 int ngadmin_close (struct ngadmin *nga)
57 int ngadmin_forceInterface (struct ngadmin *nga)
62 return forceInterface(nga) == 0 ? ERR_OK : ERR_NET;
66 int ngadmin_setKeepBroadcasting (struct ngadmin *nga, bool value)
71 nga->keepbroad = value;
77 int ngadmin_useGlobalBroadcast (struct ngadmin *nga, bool value)
82 nga->globalbroad = value;
88 int ngadmin_setPassword (struct ngadmin *nga, const char *pass)
93 strncpy(nga->password, pass, PASSWORD_MAX);
99 int ngadmin_setTimeout (struct ngadmin *nga, const struct timeval *tv)
104 if (nga == NULL || tv == NULL)
108 if (updateTimeout(nga) < 0)
116 int ngadmin_scan (struct ngadmin *nga)
119 List *attr, *swiList;
122 sent by official win client:
138 static const unsigned short hello[] = {
161 /* create attributes for an "hello" request */
162 attr = createEmptyList();
164 pushBackList(attr, newEmptyAttr(hello[i]));
165 if (hello[i] == ATTR_END)
169 /* send request to all potential switches */
170 i = sendNgPacket(nga, CODE_READ_REQ, attr);
171 clearList(attr, (void(*)(void*))freeAttr);
177 /* try to receive any packets until timeout */
178 swiList = createEmptyList();
179 /* FIXME: end after timeout whatever received packet is good or not */
180 while (recvNgPacket(nga, CODE_READ_REP, NULL, NULL, attr) >= 0) {
181 sa = malloc(sizeof(struct swi_attr));
184 extractSwitchAttributes(sa, attr);
185 clearList(attr, (void(*)(void*))freeAttr);
186 pushBackList(swiList, sa);
189 nga->swi_count = swiList->count;
190 nga->swi_tab = convertToArray(swiList, sizeof(struct swi_attr));
191 destroyList(swiList, free);
192 destroyList(attr, (void(*)(void*))freeAttr);
199 const struct swi_attr* ngadmin_getSwitchTab (struct ngadmin *nga, int *nb)
201 if (nga == NULL || nb == NULL)
204 *nb = nga->swi_count;
210 const struct swi_attr* ngadmin_getCurrentSwitch (struct ngadmin *nga)
219 int ngadmin_login (struct ngadmin *nga, int id)
229 else if (id < 0 || id >= nga->swi_count)
232 sa = &nga->swi_tab[id];
234 nga->encrypt_pass = false;
236 attr = createEmptyList();
237 pushBackList(attr, newEmptyAttr(ATTR_ENCPASS));
238 ret = readRequest(nga, attr);
242 filterAttributes(attr, ATTR_ENCPASS, ATTR_END);
243 if (attr->first != NULL) {
244 at = attr->first->data;
245 nga->encrypt_pass = (at->size == 4 && ntohl(*(unsigned int*)at->data) == 1);
247 clearList(attr, (void(*)(void*))freeAttr);
249 /* Strangely, passwords must never be encrypted inside a read request,
250 * or it will be rejected. Seems more to be a firmware bug. */
251 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
252 ret = readRequest(nga, attr);
253 if (ret == ERR_OK ) {
254 /* login succeeded */
255 /* TODO: if keep broadcasting is disabled, connect() the UDP
256 socket so icmp errors messages (port unreachable, TTL exceeded
257 in transit, ...) can be received */
264 destroyList(attr, (void(*)(void*))freeAttr);
271 int ngadmin_upgradeFirmware (struct ngadmin *nga, const char *filename)
273 if (nga == NULL || filename == NULL || *filename == 0)
275 else if (nga->current == NULL)
279 Firmware upgrade is not yet implemented.
280 This would require much more work and the use of a TFTP client.
281 Overall, it could be quite dangerous, as the switch may not check the binary
289 int ngadmin_getPortsStatus (struct ngadmin *nga, unsigned char *ports)
295 struct attr_port_status *ps;
298 if (nga == NULL || ports == NULL)
300 else if (nga->current == NULL)
304 attr = createEmptyList();
305 pushBackList(attr, newEmptyAttr(ATTR_PORT_STATUS));
306 ret = readRequest(nga, attr);
310 filterAttributes(attr, ATTR_PORT_STATUS, ATTR_END);
312 memset(ports, SPEED_UNK, nga->current->ports);
314 for (ln = attr->first; ln != NULL; ln = ln->next) {
317 ports[ps->port - 1] = ps->status;
321 destroyList(attr, (void(*)(void*))freeAttr);
328 int ngadmin_setName (struct ngadmin *nga, const char *name)
336 else if (nga->current == NULL)
340 attr = createEmptyList();
341 pushBackList(attr, name == NULL ? newEmptyAttr(ATTR_NAME) : newAttr(ATTR_NAME, strlen(name), strdup(name)) );
342 ret = writeRequest(nga, attr);
346 /* successful, also update local name */
348 memset(nga->current->name, '\0', NAME_SIZE);
350 strncpy(nga->current->name, name, NAME_SIZE);
357 int ngadmin_getPortsStatistics (struct ngadmin *nga, struct port_stats *ps)
363 struct attr_port_stat *aps;
366 if (nga == NULL || ps == NULL)
368 else if (nga->current == NULL)
371 attr = createEmptyList();
372 pushBackList(attr, newEmptyAttr(ATTR_PORT_STATISTICS));
373 ret = readRequest(nga, attr);
377 filterAttributes(attr, ATTR_PORT_STATISTICS, ATTR_END);
379 memset(ps, 0, nga->current->ports * sizeof(struct port_stats));
381 for (ln = attr->first; ln != NULL; ln = ln->next) {
384 ps[aps->port -1].recv = aps->recv;
385 ps[aps->port -1].sent = aps->sent;
386 ps[aps->port -1].crc = aps->crc;
390 destroyList(attr, (void(*)(void*))freeAttr);
397 int ngadmin_resetPortsStatistics (struct ngadmin *nga)
402 attr = createEmptyList();
403 pushBackList(attr, newByteAttr(ATTR_STATS_RESET, 1));
406 return writeRequest(nga, attr);
410 int ngadmin_changePassword (struct ngadmin *nga, const char* pass)
417 if (nga == NULL || pass == NULL)
419 else if (nga->current == NULL)
423 attr = createEmptyList();
424 at = newAttr(ATTR_NEW_PASSWORD, strlen(pass), strdup(pass));
425 if (nga->encrypt_pass)
426 passwordEndecode(at->data, at->size);
427 pushBackList(attr, at);
428 ret = writeRequest(nga, attr);
433 /* successful, also update local password */
434 strncpy(nga->password, pass, PASSWORD_MAX);
442 int ngadmin_getStormFilterState (struct ngadmin *nga, int *s)
449 if (nga == NULL || s == NULL)
451 else if (nga->current == NULL)
455 attr = createEmptyList();
456 pushBackList(attr, newEmptyAttr(ATTR_STORM_ENABLE));
457 ret = readRequest(nga, attr);
461 filterAttributes(attr, ATTR_STORM_ENABLE, ATTR_END);
465 if (attr->first != NULL) {
466 at = attr->first->data;
467 *s = *(char*)at->data;
472 destroyList(attr, (void(*)(void*))freeAttr);
479 int ngadmin_setStormFilterState (struct ngadmin *nga, int s)
484 attr = createEmptyList();
485 pushBackList(attr, newByteAttr(ATTR_STORM_ENABLE, s != 0));
488 return writeRequest(nga, attr);
492 int ngadmin_getStormFilterValues (struct ngadmin *nga, int *ports)
497 int ret = ERR_OK, port;
498 struct attr_bitrate *sb;
501 if (nga == NULL || ports == NULL)
503 else if (nga->current == NULL)
507 attr = createEmptyList();
508 pushBackList(attr, newEmptyAttr(ATTR_STORM_BITRATE));
509 ret = readRequest(nga, attr);
513 filterAttributes(attr, ATTR_STORM_BITRATE, ATTR_END);
515 for (port = 0; port < nga->current->ports; port++)
516 ports[port] = BITRATE_UNSPEC;
518 for (ln = attr->first; ln != NULL; ln = ln->next) {
521 ports[sb->port - 1] = sb->bitrate;
526 destroyList(attr, (void(*)(void*))freeAttr);
533 int ngadmin_setStormFilterValues (struct ngadmin *nga, const int *ports)
537 struct attr_bitrate *sb;
540 if (nga == NULL || ports == NULL)
542 else if (nga->current == NULL)
546 attr = createEmptyList();
548 for (port = 0; port < nga->current->ports; port++) {
549 if (ports[port] != BITRATE_UNSPEC) {
550 sb = malloc(sizeof(struct attr_bitrate));
554 sb->bitrate = ports[port];
555 pushBackList(attr, newAttr(ATTR_STORM_BITRATE, sizeof(struct attr_bitrate), sb));
559 return writeRequest(nga, attr);
563 int ngadmin_getBitrateLimits (struct ngadmin *nga, int *ports)
568 int ret = ERR_OK, port;
569 struct attr_bitrate *pb;
572 if (nga == NULL || ports == NULL)
574 else if (nga->current == NULL)
578 attr = createEmptyList();
579 pushBackList(attr, newEmptyAttr(ATTR_BITRATE_INPUT));
580 pushBackList(attr, newEmptyAttr(ATTR_BITRATE_OUTPUT));
581 ret = readRequest(nga, attr);
586 for (port = 0; port < nga->current->ports; port++) {
587 ports[2 * port + 0] = BITRATE_UNSPEC;
588 ports[2 * port + 1] = BITRATE_UNSPEC;
591 for (ln = attr->first; ln != NULL; ln = ln->next) {
594 if (at->attr == ATTR_BITRATE_INPUT)
595 ports[(pb->port - 1) * 2 + 0] = pb->bitrate;
596 else if (at->attr == ATTR_BITRATE_OUTPUT)
597 ports[(pb->port - 1) * 2 + 1] = pb->bitrate;
602 destroyList(attr, (void(*)(void*))freeAttr);
608 int ngadmin_setBitrateLimits (struct ngadmin *nga, const int *ports)
612 struct attr_bitrate *pb;
615 if (nga == NULL || ports == NULL)
617 else if (nga->current == NULL)
621 attr = createEmptyList();
623 for (port = 0; port < nga->current->ports; port++) {
624 if (ports[2 * port + 0] >= BITRATE_NOLIMIT && ports[2 * port + 0] <= BITRATE_512M) {
625 pb = malloc(sizeof(struct attr_bitrate));
629 pb->bitrate = ports[2 * port + 0];
630 pushBackList(attr, newAttr(ATTR_BITRATE_INPUT, sizeof(struct attr_bitrate), pb));
632 if (ports[2 * port + 1] >= BITRATE_NOLIMIT && ports[2 * port + 1] <= BITRATE_512M) {
633 pb = malloc(sizeof(struct attr_bitrate));
637 pb->bitrate = ports[2 * port + 1];
638 pushBackList(attr, newAttr(ATTR_BITRATE_OUTPUT, sizeof(struct attr_bitrate), pb));
643 return writeRequest(nga, attr);
647 int ngadmin_getQOSMode (struct ngadmin *nga, int *s)
654 if (nga == NULL || s == NULL)
656 else if (nga->current == NULL)
660 attr = createEmptyList();
661 pushBackList(attr, newEmptyAttr(ATTR_QOS_TYPE));
662 ret = readRequest(nga, attr);
666 filterAttributes(attr, ATTR_QOS_TYPE, ATTR_END);
670 if (attr->first != NULL) {
671 at = attr->first->data;
672 *s = *(char*)at->data;
677 destroyList(attr, (void(*)(void*))freeAttr);
684 int ngadmin_setQOSMode (struct ngadmin *nga, int s)
689 attr = createEmptyList();
690 pushBackList(attr, newByteAttr(ATTR_QOS_TYPE, s));
693 return writeRequest(nga, attr);
697 int ngadmin_getQOSValues (struct ngadmin *nga, char *ports)
702 int ret = ERR_OK, port;
706 if (nga == NULL || ports == NULL)
708 else if (nga->current == NULL)
712 attr = createEmptyList();
713 pushBackList(attr, newEmptyAttr(ATTR_QOS_CONFIG));
714 ret = readRequest(nga, attr);
718 filterAttributes(attr, ATTR_QOS_CONFIG, ATTR_END);
720 for (port = 0; port < nga->current->ports; port++)
721 ports[port] = PRIO_UNSPEC;
723 for (ln = attr->first; ln != NULL; ln = ln->next) {
726 ports[aq->port - 1] = aq->prio;
731 destroyList(attr, (void(*)(void*))freeAttr);
738 int ngadmin_setQOSValues (struct ngadmin *nga, const char *ports)
745 if (nga == NULL || ports == NULL)
747 else if (nga->current == NULL)
751 attr = createEmptyList();
753 for (port = 0; port < nga->current->ports; port++) {
754 if (ports[port] >= PRIO_HIGH && ports[port] <= PRIO_LOW) {
755 aq = malloc(sizeof(struct attr_qos));
759 aq->prio = ports[port];
760 pushBackList(attr, newAttr(ATTR_QOS_CONFIG, sizeof(struct attr_qos), aq));
765 return writeRequest(nga, attr);
769 int ngadmin_restart (struct ngadmin *nga)
774 attr = createEmptyList();
775 pushBackList(attr, newByteAttr(ATTR_RESTART, 1));
778 return writeRequest(nga, attr);
782 int ngadmin_defaults (struct ngadmin *nga)
788 attr = createEmptyList();
789 pushBackList(attr, newByteAttr(ATTR_DEFAULTS, 1));
790 ret = writeRequest(nga, attr);
795 /* successful: delog and clean list */
806 int ngadmin_getMirror (struct ngadmin *nga, char *ports)
813 if (nga == NULL || ports == NULL)
815 else if (nga->current == NULL)
819 attr = createEmptyList();
820 pushBackList(attr, newEmptyAttr(ATTR_MIRROR));
821 ret = readRequest(nga, attr);
825 filterAttributes(attr, ATTR_MIRROR, ATTR_END);
827 memset(ports, 0, 1 + nga->current->ports);
829 if (attr->first != NULL) {
830 at = attr->first->data;
831 memcpy(ports, at->data, 1 + nga->current->ports);
836 destroyList(attr, (void(*)(void*))freeAttr);
843 int ngadmin_setMirror (struct ngadmin *nga, const char *ports)
851 else if (nga->current == NULL)
855 p = malloc(1 + nga->current->ports);
860 memset(p, 0, 1 + nga->current->ports);
862 memcpy(p, ports, 1 + nga->current->ports);
864 attr = createEmptyList();
865 pushBackList(attr, newAttr(ATTR_MIRROR, 1 + nga->current->ports, p));
868 return writeRequest(nga, attr);
872 int ngadmin_getIGMPConf (struct ngadmin *nga, struct igmp_conf *ic)
877 struct attr_igmp_vlan *aiv;
880 if (nga == NULL || ic == NULL)
882 else if (nga->current == NULL)
886 ATTR_IGMP_ENABLE_VLAN
890 Apparently, read-querying these attributes at the same time causes the switch to reply garbage.
891 Here we are forced to do like the official win app and send a separate request for each attribute.
895 attr = createEmptyList();
896 memset(ic, 0, sizeof(struct igmp_conf));
899 pushBackList(attr, newEmptyAttr(ATTR_IGMP_ENABLE_VLAN));
900 ret = readRequest(nga, attr);
904 filterAttributes(attr, ATTR_IGMP_ENABLE_VLAN, ATTR_END);
906 if (attr->first != NULL) {
907 at = attr->first->data;
909 ic->enable = aiv->enable;
910 ic->vlan = aiv->vlan;
913 clearList(attr, (void(*)(void*))freeAttr);
916 pushBackList(attr, newEmptyAttr(ATTR_IGMP_BLOCK_UNK));
917 ret = readRequest(nga, attr);
921 filterAttributes(attr, ATTR_IGMP_BLOCK_UNK, ATTR_END);
923 if (attr->first != NULL) {
924 at = attr->first->data;
925 ic->block = *(char*)at->data;
928 clearList(attr, (void(*)(void*))freeAttr);
931 pushBackList(attr, newEmptyAttr(ATTR_IGMP_VALID_V3));
932 ret = readRequest(nga, attr);
936 filterAttributes(attr, ATTR_IGMP_VALID_V3, ATTR_END);
938 if (attr->first != NULL) {
939 at = attr->first->data;
940 ic->validate = *(char*)at->data;
945 destroyList(attr, (void(*)(void*))freeAttr);
952 int ngadmin_setIGMPConf (struct ngadmin *nga, const struct igmp_conf *ic)
955 struct attr_igmp_vlan *aiv;
958 if (nga == NULL || ic == NULL)
960 else if (nga->current == NULL)
964 aiv = malloc(sizeof(struct attr_igmp_vlan));
967 aiv->enable = ic->enable;
968 aiv->vlan = ic->vlan;
971 attr = createEmptyList();
972 pushBackList(attr, newAttr(ATTR_IGMP_ENABLE_VLAN, sizeof(struct attr_igmp_vlan), aiv));
973 pushBackList(attr, newByteAttr(ATTR_IGMP_BLOCK_UNK, ic->block != false));
974 pushBackList(attr, newByteAttr(ATTR_IGMP_VALID_V3, ic->validate != false));
977 return writeRequest(nga, attr);
981 int ngadmin_cabletest (struct ngadmin *nga, struct cabletest *ct, int nb)
987 struct attr_cabletest_do *acd;
988 struct attr_cabletest_result *acr;
991 if (nga == NULL || ct == NULL)
993 else if (nga->current == NULL)
997 attr = createEmptyList();
999 for (i = 0; i < nb; i++) {
1001 acd = malloc(sizeof(struct attr_cabletest_do));
1004 acd->port = ct[i].port;
1006 pushBackList(attr, newAttr(ATTR_CABLETEST_DO, sizeof(struct attr_cabletest_do), acd));
1008 ret = writeRequest(nga, attr);
1013 /* the list is destroyed by writeRequest, so we need to recreate it */
1014 attr = createEmptyList();
1015 pushBackList(attr, newByteAttr(ATTR_CABLETEST_RESULT, ct[i].port));
1016 ret = readRequest(nga, attr);
1020 filterAttributes(attr, ATTR_CABLETEST_RESULT, ATTR_END);
1022 for (ln = attr->first; ln != NULL; ln = ln->next) {
1025 if (at->size == sizeof(struct attr_cabletest_result) && acr->port == ct[i].port) {
1032 /* just empty the list, it will be used at next iteration */
1033 clearList(attr, (void(*)(void*))freeAttr);
1038 destroyList(attr, (void(*)(void*))freeAttr);
1045 int ngadmin_setNetConf (struct ngadmin *nga, const struct net_conf *nc)
1049 struct swi_attr *sa;
1052 if (nga == NULL || nc == NULL)
1060 attr = createEmptyList();
1063 pushBackList(attr, newShortAttr(ATTR_DHCP, 1));
1065 pushBackList(attr, newShortAttr(ATTR_DHCP, 0));
1066 /* only add non-null values */
1067 if (nc->ip.s_addr != 0)
1068 pushBackList(attr, newAddrAttr(ATTR_IP, nc->ip));
1069 if (nc->netmask.s_addr != 0)
1070 pushBackList(attr, newAddrAttr(ATTR_NETMASK, nc->netmask));
1071 if (nc->gw.s_addr != 0)
1072 pushBackList(attr, newAddrAttr(ATTR_GATEWAY, nc->gw));
1075 ret = writeRequest(nga, attr);
1080 /* update local values */
1081 sa->nc.dhcp = nc->dhcp;
1083 if (nc->ip.s_addr !=0)
1085 if (nc->netmask.s_addr != 0)
1086 sa->nc.netmask = nc->netmask;
1087 if (nc->gw.s_addr != 0)
1098 int ngadmin_getVLANType (struct ngadmin *nga, int *t)
1105 if (nga == NULL || t == NULL)
1107 else if (nga->current == NULL)
1111 attr = createEmptyList();
1112 pushBackList(attr, newEmptyAttr(ATTR_VLAN_TYPE));
1113 ret=readRequest(nga, attr);
1117 filterAttributes(attr, ATTR_VLAN_TYPE, ATTR_END);
1121 if (attr->first != NULL) {
1122 at = attr->first->data;
1123 *t =(int)*(char*)at->data;
1128 destroyList(attr, (void(*)(void*))freeAttr);
1135 int ngadmin_setVLANType (struct ngadmin *nga, int t)
1140 if (nga == NULL || t < 1 || t > 4)
1142 else if (nga->current == NULL)
1146 attr = createEmptyList();
1147 pushBackList(attr, newByteAttr(ATTR_VLAN_TYPE, t));
1150 return writeRequest(nga, attr);
1154 int ngadmin_getVLANDotAllConf (struct ngadmin *nga, unsigned short *vlans, unsigned char *ports, int *nb)
1159 int ret = ERR_OK, total;
1160 struct attr_vlan_dot *avd;
1163 if (nga == NULL || vlans == NULL || ports== NULL || nb == NULL || *nb <= 0)
1165 else if (nga->current == NULL)
1172 attr = createEmptyList();
1173 pushBackList(attr, newEmptyAttr(ATTR_VLAN_DOT_CONF));
1174 ret = readRequest(nga, attr);
1178 filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
1180 memset(vlans, 0, total * sizeof(unsigned short));
1181 memset(ports, 0, total * nga->current->ports);
1183 for (ln = attr->first; ln != NULL; ln = ln->next) {
1188 memcpy(ports, avd->ports, nga->current->ports);
1191 ports += nga->current->ports;
1195 break; /* no more room */
1200 destroyList(attr, (void(*)(void*))freeAttr);
1207 int ngadmin_getVLANDotConf (struct ngadmin *nga, unsigned short vlan, unsigned char *ports)
1213 struct attr_vlan_dot *avd;
1216 if (nga == NULL || vlan < 1 || vlan > VLAN_MAX || ports == NULL)
1218 else if (nga->current == NULL)
1222 attr = createEmptyList();
1223 pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
1224 ret = readRequest(nga, attr);
1228 filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
1230 memset(ports, 0, nga->current->ports);
1232 for (ln = attr->first; ln != NULL; ln = ln->next) {
1235 if (avd->vlan == vlan) {
1236 memcpy(ports, avd->ports, nga->current->ports);
1243 destroyList(attr, (void(*)(void*))freeAttr);
1250 int ngadmin_setVLANDotConf (struct ngadmin *nga, unsigned short vlan, const unsigned char *ports)
1254 struct swi_attr *sa;
1255 struct attr_vlan_dot *avd;
1256 int ret = ERR_OK, port;
1259 if (nga == NULL || vlan < 1 || vlan > VLAN_MAX || ports == NULL)
1267 /* if nothing is to be changed, do nothing */
1268 for (port = 0; port < sa->ports && ports[port] == VLAN_UNSPEC; port++);
1269 if (port == sa->ports )
1273 attr = createEmptyList();
1274 avd = malloc(sizeof(struct attr_vlan_dot) + sa->ports);
1280 /* if all is to be changed, we do not need to read old config */
1281 if (memchr(ports, VLAN_UNSPEC, sa->ports) != NULL) {
1283 pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
1284 ret = readRequest(nga, attr);
1288 filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
1290 if (attr->first != NULL) {
1291 at = attr->first->data;
1292 memcpy(avd, at->data, sizeof(struct attr_vlan_dot) + sa->ports);
1295 clearList(attr, (void(*)(void*))freeAttr);
1300 for (port = 0; port < sa->ports; port++) {
1301 if (ports[port] != VLAN_UNSPEC)
1302 avd->ports[port] = ports[port];
1306 pushBackList(attr, newAttr(ATTR_VLAN_DOT_CONF, sizeof(struct attr_vlan_dot) + sa->ports, avd));
1307 ret = writeRequest(nga, attr);
1312 destroyList(attr, (void(*)(void*))freeAttr);
1319 int ngadmin_VLANDestroy (struct ngadmin *nga, unsigned short vlan)
1324 if (nga == NULL || vlan < 1 || vlan > VLAN_MAX)
1326 else if (nga->current == NULL)
1330 attr = createEmptyList();
1331 pushBackList(attr, newShortAttr(ATTR_VLAN_DESTROY, vlan));
1334 return writeRequest(nga, attr);
1338 int ngadmin_getAllPVID (struct ngadmin *nga, unsigned short *ports)
1344 struct attr_pvid *ap;
1347 if (nga == NULL || ports == NULL)
1349 else if (nga->current == NULL)
1353 attr = createEmptyList();
1354 pushBackList(attr, newEmptyAttr(ATTR_VLAN_PVID));
1355 ret = readRequest(nga, attr);
1359 filterAttributes(attr, ATTR_VLAN_PVID, ATTR_END);
1361 memset(ports, 0, nga->current->ports * sizeof(unsigned short));
1363 for (ln = attr->first; ln != NULL; ln = ln->next) {
1366 ports[ap->port - 1] = ap->vlan;
1371 destroyList(attr, (void(*)(void*))freeAttr);
1378 int ngadmin_setPVID (struct ngadmin *nga, unsigned char port, unsigned short vlan)
1381 struct attr_pvid *ap;
1384 if (nga == NULL || port < 1 || vlan < 1 || vlan > VLAN_MAX)
1386 else if (nga->current == NULL)
1388 else if (port > nga->current->ports)
1392 attr = createEmptyList();
1393 ap = malloc(sizeof(struct attr_pvid));
1399 pushBackList(attr, newAttr(ATTR_VLAN_PVID, sizeof(struct attr_pvid), ap));
1402 return writeRequest(nga, attr);