5 #include <nsdp/protocol.h>
11 int ngadmin_getVLANType (struct ngadmin *nga, int *t)
18 if (nga == NULL || t == NULL)
20 else if (nga->current == NULL)
24 attr = createEmptyList();
25 pushBackList(attr, newEmptyAttr(ATTR_VLAN_TYPE));
26 ret=readRequest(nga, attr);
30 filterAttributes(attr, ATTR_VLAN_TYPE, ATTR_END);
34 if (attr->first == NULL) {
38 at = attr->first->data;
39 *t =(int)*(char*)at->data;
42 destroyList(attr, (void(*)(void*))freeAttr);
49 int ngadmin_setVLANType (struct ngadmin *nga, int t)
54 if (nga == NULL || t < VLAN_DISABLED || t > VLAN_DOT_ADV)
56 else if (nga->current == NULL)
60 attr = createEmptyList();
61 pushBackList(attr, newByteAttr(ATTR_VLAN_TYPE, t));
64 return writeRequest(nga, attr);
68 int ngadmin_getVLANPortConf (struct ngadmin *nga, unsigned char *ports)
74 struct attr_vlan_conf *avc;
79 if (nga == NULL || ports== NULL)
87 attr = createEmptyList();
88 pushBackList(attr, newEmptyAttr(ATTR_VLAN_PORT_CONF));
89 ret = readRequest(nga, attr);
93 filterAttributes(attr, ATTR_VLAN_PORT_CONF, ATTR_END);
95 if (attr->first == NULL) {
100 memset(ports, 0, sa->ports);
102 for (ln = attr->first; ln != NULL; ln = ln->next) {
106 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
111 for (port = 0; port < sa->ports; port++) {
112 if (avc->ports[port] == VLAN_UNTAGGED)
113 ports[port] = avc->vlan;
119 destroyList(attr, (void(*)(void*))freeAttr);
126 int ngadmin_setVLANPortConf (struct ngadmin *nga, const unsigned char *ports)
128 List *conf_old = NULL, *conf_new = NULL;
132 struct attr_vlan_conf *avc_old, *avc_new;
133 int ret = ERR_OK, port;
136 if (nga == NULL || ports == NULL)
143 /* if nothing is to be changed, do nothing */
144 for (port = 0; port < sa->ports && ports[port] == 0; port++);
145 if (port == sa->ports)
148 /* read old config */
149 conf_old = createEmptyList();
150 pushBackList(conf_old, newEmptyAttr(ATTR_VLAN_PORT_CONF));
151 ret = readRequest(nga, conf_old);
155 filterAttributes(conf_old, ATTR_VLAN_PORT_CONF, ATTR_END);
157 if (conf_old->first == NULL) {
162 /* merge old config with requested config */
163 conf_new = createEmptyList();
164 avc_new = malloc(sizeof(struct attr_vlan_conf) + sa->ports);
166 for (ln = conf_old->first; ln != NULL; ln = ln->next) {
170 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
176 /* compute new VLAN configuration */
177 avc_new->vlan = avc_old->vlan;
179 for (port = 0; port < sa->ports; port++) {
180 if (ports[port] == 0)
181 avc_new->ports[port] = avc_old->ports[port];
182 else if (ports[port] == avc_new->vlan)
183 avc_new->ports[port] = VLAN_UNTAGGED;
185 avc_new->ports[port] = VLAN_NO;
188 /* only add it if it is different from old config */
189 if (memcmp(avc_old->ports, avc_new->ports, sa->ports) != 0) {
190 pushBackList(conf_new, newAttr(ATTR_VLAN_PORT_CONF, sizeof(struct attr_vlan_conf) + sa->ports, avc_new));
191 avc_new = malloc(sizeof(struct attr_vlan_conf) + sa->ports);
197 /* if no VLAN is changed, no need to send anything to the switch */
198 if (conf_new->first == NULL)
201 /* send new configuration to the switch */
202 ret = writeRequest(nga, conf_new);
206 destroyList(conf_old, (void(*)(void*))freeAttr);
207 destroyList(conf_new, (void(*)(void*))freeAttr);
214 int ngadmin_getVLANDotAllConf (struct ngadmin *nga, unsigned short *vlans, unsigned char *ports, int *nb)
219 int ret = ERR_OK, total;
220 struct attr_vlan_conf *avc;
224 if (nga == NULL || vlans == NULL || ports== NULL || nb == NULL || *nb <= 0)
235 attr = createEmptyList();
236 pushBackList(attr, newEmptyAttr(ATTR_VLAN_DOT_CONF));
237 ret = readRequest(nga, attr);
241 filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
243 if (attr->first == NULL) {
248 memset(vlans, 0, total * sizeof(unsigned short));
249 memset(ports, 0, total * sa->ports);
251 for (ln = attr->first; ln != NULL; ln = ln->next) {
255 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
261 memcpy(ports, avc->ports, sa->ports);
268 break; /* no more room */
273 destroyList(attr, (void(*)(void*))freeAttr);
280 int ngadmin_getVLANDotConf (struct ngadmin *nga, unsigned short vlan, unsigned char *ports)
287 struct attr_vlan_conf *avc;
290 if (nga == NULL || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX || ports == NULL)
297 attr = createEmptyList();
298 pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
299 ret = readRequest(nga, attr);
303 filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
305 if (attr->first == NULL) {
310 memset(ports, 0, sa->ports);
312 for (ln = attr->first; ln != NULL; ln = ln->next) {
316 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
321 if (avc->vlan == vlan) {
322 memcpy(ports, avc->ports, sa->ports);
329 destroyList(attr, (void(*)(void*))freeAttr);
336 int ngadmin_setVLANDotConf (struct ngadmin *nga, unsigned short vlan, const unsigned char *ports)
341 struct attr_vlan_conf *avc;
342 int ret = ERR_OK, port;
345 if (nga == NULL || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX || ports == NULL)
353 /* if nothing is to be changed, do nothing */
354 for (port = 0; port < sa->ports && ports[port] == VLAN_UNSPEC; port++);
355 if (port == sa->ports )
359 attr = createEmptyList();
360 avc = malloc(sizeof(struct attr_vlan_conf) + sa->ports);
366 /* if all is to be changed, we do not need to read old config */
367 if (memchr(ports, VLAN_UNSPEC, sa->ports) != NULL) {
369 pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
370 ret = readRequest(nga, attr);
374 filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
376 /* check if the switch is in 802.1Q mode */
377 if (attr->first == NULL) {
381 at = attr->first->data;
382 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
388 memcpy(avc, at->data, sizeof(struct attr_vlan_conf) + sa->ports);
389 clearList(attr, (void(*)(void*))freeAttr);
394 for (port = 0; port < sa->ports; port++) {
395 if (ports[port] != VLAN_UNSPEC)
396 avc->ports[port] = ports[port];
400 pushBackList(attr, newAttr(ATTR_VLAN_DOT_CONF, sizeof(struct attr_vlan_conf) + sa->ports, avc));
401 ret = writeRequest(nga, attr);
406 destroyList(attr, (void(*)(void*))freeAttr);
413 int ngadmin_VLANDestroy (struct ngadmin *nga, unsigned short vlan)
418 if (nga == NULL || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX)
420 else if (nga->current == NULL)
424 attr = createEmptyList();
425 pushBackList(attr, newShortAttr(ATTR_VLAN_DESTROY, vlan));
428 return writeRequest(nga, attr);
432 int ngadmin_getAllPVID (struct ngadmin *nga, unsigned short *ports)
438 struct attr_pvid *ap;
442 if (nga == NULL || ports == NULL)
450 attr = createEmptyList();
451 pushBackList(attr, newEmptyAttr(ATTR_VLAN_PVID));
452 ret = readRequest(nga, attr);
456 filterAttributes(attr, ATTR_VLAN_PVID, ATTR_END);
458 memset(ports, 0, sa->ports * sizeof(unsigned short));
460 for (ln = attr->first; ln != NULL; ln = ln->next) {
463 if (ap->port <= sa->ports)
464 ports[ap->port - 1] = ap->vlan;
469 destroyList(attr, (void(*)(void*))freeAttr);
476 int ngadmin_setPVID (struct ngadmin *nga, unsigned char port, unsigned short vlan)
479 struct attr_pvid *ap;
482 if (nga == NULL || port < 1 || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX)
484 else if (nga->current == NULL)
486 else if (port > nga->current->ports)
490 attr = createEmptyList();
491 ap = malloc(sizeof(struct attr_pvid));
497 pushBackList(attr, newAttr(ATTR_VLAN_PVID, sizeof(struct attr_pvid), ap));
500 return writeRequest(nga, attr);