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;
43 *t =(int)*(char*)at->data;
46 destroyList(attr, (void(*)(void*))freeAttr);
53 int ngadmin_setVLANType (struct ngadmin *nga, int t)
58 if (nga == NULL || t < VLAN_DISABLED || t > VLAN_DOT_ADV)
60 else if (nga->current == NULL)
64 attr = createEmptyList();
65 pushBackList(attr, newByteAttr(ATTR_VLAN_TYPE, t));
68 return writeRequest(nga, attr);
72 int ngadmin_getVLANPortConf (struct ngadmin *nga, unsigned char *ports)
78 struct attr_vlan_conf *avc;
83 if (nga == NULL || ports== NULL)
91 attr = createEmptyList();
92 pushBackList(attr, newEmptyAttr(ATTR_VLAN_PORT_CONF));
93 ret = readRequest(nga, attr);
97 filterAttributes(attr, ATTR_VLAN_PORT_CONF, ATTR_END);
99 if (attr->first == NULL) {
104 memset(ports, 0, sa->ports);
106 for (ln = attr->first; ln != NULL; ln = ln->next) {
110 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
115 for (port = 0; port < sa->ports; port++) {
116 if (avc->ports[port] == VLAN_UNTAGGED)
117 ports[port] = avc->vlan;
123 destroyList(attr, (void(*)(void*))freeAttr);
130 int ngadmin_setVLANPortConf (struct ngadmin *nga, const unsigned char *ports)
132 List *conf_old = NULL, *conf_new = NULL;
136 struct attr_vlan_conf *avc_old, *avc_new;
137 int ret = ERR_OK, port;
140 if (nga == NULL || ports == NULL)
147 /* if nothing is to be changed, do nothing */
148 for (port = 0; port < sa->ports && ports[port] == 0; port++);
149 if (port == sa->ports)
152 /* read old config */
153 conf_old = createEmptyList();
154 pushBackList(conf_old, newEmptyAttr(ATTR_VLAN_PORT_CONF));
155 ret = readRequest(nga, conf_old);
159 filterAttributes(conf_old, ATTR_VLAN_PORT_CONF, ATTR_END);
161 if (conf_old->first == NULL) {
166 /* merge old config with requested config */
167 conf_new = createEmptyList();
168 avc_new = malloc(sizeof(struct attr_vlan_conf) + sa->ports);
170 for (ln = conf_old->first; ln != NULL; ln = ln->next) {
174 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
180 /* compute new VLAN configuration */
181 avc_new->vlan = avc_old->vlan;
183 for (port = 0; port < sa->ports; port++) {
184 if (ports[port] == 0)
185 avc_new->ports[port] = avc_old->ports[port];
186 else if (ports[port] == avc_new->vlan)
187 avc_new->ports[port] = VLAN_UNTAGGED;
189 avc_new->ports[port] = VLAN_NO;
192 /* only add it if it is different from old config */
193 if (memcmp(avc_old->ports, avc_new->ports, sa->ports) != 0) {
194 pushBackList(conf_new, newAttr(ATTR_VLAN_PORT_CONF, sizeof(struct attr_vlan_conf) + sa->ports, avc_new));
195 avc_new = malloc(sizeof(struct attr_vlan_conf) + sa->ports);
201 /* if no VLAN is changed, no need to send anything to the switch */
202 if (conf_new->first == NULL)
205 /* send new configuration to the switch */
206 ret = writeRequest(nga, conf_new);
210 destroyList(conf_old, (void(*)(void*))freeAttr);
211 destroyList(conf_new, (void(*)(void*))freeAttr);
218 int ngadmin_getVLANDotAllConf (struct ngadmin *nga, unsigned short *vlans, unsigned char *ports, int *nb)
223 int ret = ERR_OK, total;
224 struct attr_vlan_conf *avc;
228 if (nga == NULL || vlans == NULL || ports== NULL || nb == NULL || *nb <= 0)
239 attr = createEmptyList();
240 pushBackList(attr, newEmptyAttr(ATTR_VLAN_DOT_CONF));
241 ret = readRequest(nga, attr);
245 filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
247 if (attr->first == NULL) {
252 memset(vlans, 0, total * sizeof(unsigned short));
253 memset(ports, 0, total * sa->ports);
255 for (ln = attr->first; ln != NULL; ln = ln->next) {
259 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
265 memcpy(ports, avc->ports, sa->ports);
272 break; /* no more room */
277 destroyList(attr, (void(*)(void*))freeAttr);
284 int ngadmin_getVLANDotConf (struct ngadmin *nga, unsigned short vlan, unsigned char *ports)
291 struct attr_vlan_conf *avc;
294 if (nga == NULL || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX || ports == NULL)
301 attr = createEmptyList();
302 pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
303 ret = readRequest(nga, attr);
307 filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
309 if (attr->first == NULL) {
314 memset(ports, 0, sa->ports);
316 for (ln = attr->first; ln != NULL; ln = ln->next) {
320 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
325 if (avc->vlan == vlan) {
326 memcpy(ports, avc->ports, sa->ports);
333 destroyList(attr, (void(*)(void*))freeAttr);
340 int ngadmin_setVLANDotConf (struct ngadmin *nga, unsigned short vlan, const unsigned char *ports)
345 struct attr_vlan_conf *avc;
346 int ret = ERR_OK, port;
349 if (nga == NULL || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX || ports == NULL)
357 /* if nothing is to be changed, do nothing */
358 for (port = 0; port < sa->ports && ports[port] == VLAN_UNSPEC; port++);
359 if (port == sa->ports )
363 attr = createEmptyList();
364 avc = malloc(sizeof(struct attr_vlan_conf) + sa->ports);
370 /* if all is to be changed, we do not need to read old config */
371 if (memchr(ports, VLAN_UNSPEC, sa->ports) != NULL) {
373 pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
374 ret = readRequest(nga, attr);
378 filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
380 /* check if the switch is in 802.1Q mode */
381 if (attr->first == NULL) {
385 at = attr->first->data;
386 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
392 memcpy(avc, at->data, sizeof(struct attr_vlan_conf) + sa->ports);
393 clearList(attr, (void(*)(void*))freeAttr);
398 for (port = 0; port < sa->ports; port++) {
399 if (ports[port] != VLAN_UNSPEC)
400 avc->ports[port] = ports[port];
404 pushBackList(attr, newAttr(ATTR_VLAN_DOT_CONF, sizeof(struct attr_vlan_conf) + sa->ports, avc));
405 ret = writeRequest(nga, attr);
410 destroyList(attr, (void(*)(void*))freeAttr);
417 int ngadmin_VLANDestroy (struct ngadmin *nga, unsigned short vlan)
422 if (nga == NULL || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX)
424 else if (nga->current == NULL)
428 attr = createEmptyList();
429 pushBackList(attr, newShortAttr(ATTR_VLAN_DESTROY, vlan));
432 return writeRequest(nga, attr);
436 int ngadmin_getAllPVID (struct ngadmin *nga, unsigned short *ports)
442 struct attr_pvid *ap;
446 if (nga == NULL || ports == NULL)
454 attr = createEmptyList();
455 pushBackList(attr, newEmptyAttr(ATTR_VLAN_PVID));
456 ret = readRequest(nga, attr);
460 filterAttributes(attr, ATTR_VLAN_PVID, ATTR_END);
462 memset(ports, 0, sa->ports * sizeof(unsigned short));
464 for (ln = attr->first; ln != NULL; ln = ln->next) {
471 if (ap->port <= sa->ports)
472 ports[ap->port - 1] = ap->vlan;
477 destroyList(attr, (void(*)(void*))freeAttr);
484 int ngadmin_setPVID (struct ngadmin *nga, unsigned char port, unsigned short vlan)
487 struct attr_pvid *ap;
490 if (nga == NULL || port < 1 || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX)
492 else if (nga->current == NULL)
494 else if (port > nga->current->ports)
498 attr = createEmptyList();
499 ap = malloc(sizeof(struct attr_pvid));
505 pushBackList(attr, newAttr(ATTR_VLAN_PVID, sizeof(struct attr_pvid), ap));
508 return writeRequest(nga, attr);