2 #include <ngadmin.h> /* FIXME */
4 #include "encoding_attr.h"
7 #define UNUSED __attribute__((unused))
8 #define ATTR_HANDLER_ENTRY(at, sz, enc, dec) {.attr = at, .size = sz, .encode = enc, .decode = dec}
12 static bool bool_endecode (struct attr *at, unsigned char ports UNUSED)
14 *(char*)at->data = (*(char*)at->data != 0);
20 static bool ports_status_decode (struct attr *at, unsigned char ports)
22 struct attr_port_status *ps = at->data;
24 if (ps->port < 1 || ps->port > ports)
41 static bool port_stat_decode (struct attr *at, unsigned char ports)
43 struct attr_port_stat *ps = at->data;
44 unsigned long long *v;
46 if (ps->port < 1 || ps->port > ports)
49 for (v = &ps->recv; ((char*)v) - ((char*)ps) < (int)sizeof(struct attr_port_stat); v++)
57 static bool bitrate_decode (struct attr *at, unsigned char ports)
59 struct attr_bitrate *sb = at->data;
61 if (sb->port < 1 || sb->port > ports)
64 sb->bitrate = ntohl(sb->bitrate);
65 if (sb->bitrate < BITRATE_UNSPEC || sb->bitrate > BITRATE_512M)
72 static bool bitrate_encode (struct attr *at, unsigned char ports)
74 struct attr_bitrate *sb = at->data;
76 if (sb->port < 1 || sb->port > ports)
79 if (sb->bitrate < BITRATE_UNSPEC || sb->bitrate > BITRATE_512M)
81 sb->bitrate = htonl(sb->bitrate);
87 static bool qos_mode_endecode (struct attr *at, unsigned char ports UNUSED)
89 unsigned char v = *(char*)at->data;
91 return (v == QOS_PORT || v == QOS_DOT);
95 static bool qos_endecode (struct attr *at, unsigned char ports)
97 struct attr_qos *aq = at->data;
99 if (aq->port < 1 || aq->port > ports)
102 return (aq->prio >= PRIO_HIGH && aq->prio <= PRIO_LOW);
106 static bool pvid_decode (struct attr *at, unsigned char ports)
108 struct attr_pvid *ap= at->data;
110 if (ap->port < 1 || ap->port > ports)
113 ap->vlan = ntohs(ap->vlan);
115 return (ap->vlan >= VLAN_MIN && ap->vlan <= VLAN_DOT_MAX);
119 static bool pvid_encode (struct attr *at, unsigned char ports)
121 struct attr_pvid *ap= at->data;
123 if (ap->port < 1 || ap->port > ports)
126 if (ap->vlan < VLAN_MIN || ap->vlan > VLAN_DOT_MAX)
129 ap->vlan = htons(ap->vlan);
135 static bool vlan_destroy_encode (struct attr *at, unsigned char ports UNUSED)
137 unsigned short v = *(unsigned short*)at->data;
139 if (v < VLAN_MIN || v > VLAN_DOT_MAX)
142 *(unsigned short*)at->data = htons(v);
148 static bool mirror_decode (struct attr *at, unsigned char ports)
150 unsigned char *r = at->data, *p;
154 if (at->size != 3 + ((ports - 1) >> 3))
157 /* r[0] == 0 is allowed and means mirroring is disabled */
161 p = malloc(1 + ports);
165 memset(p, 0, 1 + ports);
172 for (port = 1; port <= ports; port++)
173 p[port] = (r[2] >> (8 - port)) & 1; /* FIXME: if ports > 8 */
178 at->size = 1 + ports;
185 static bool mirror_encode (struct attr *at, unsigned char ports)
187 unsigned char *p = at->data, *r;
191 if (at->size != 1 + ports)
194 /* p[0] == 0 is allowed and means mirroring is disabled */
198 r = malloc(3 + ((ports - 1) >> 3));
202 memset(r, 0, 3 + ((ports - 1) >> 3));
209 for (port = 1; port <= ports; port++) {
211 r[2] |= (p[port] & 1) << (8 - port); /* FIXME: if ports > 8 */
217 at->size = 3 + ((ports - 1) >> 3);
224 static bool igmp_vlan_decode (struct attr *at, unsigned char ports UNUSED)
226 struct attr_igmp_vlan *aiv = at->data;
228 aiv->enable = ntohs(aiv->enable);
229 if (aiv->enable != 0 && aiv->enable != 1)
232 aiv->vlan = ntohs(aiv->vlan);
233 if (aiv->vlan < VLAN_MIN || aiv->vlan > VLAN_DOT_MAX)
240 static bool igmp_vlan_encode (struct attr *at, unsigned char ports UNUSED)
242 struct attr_igmp_vlan *aiv = at->data;
244 if (aiv->enable != 0 && aiv->enable != 1)
246 aiv->enable = htons(aiv->enable);
248 if (aiv->vlan < VLAN_MIN || aiv->vlan > VLAN_DOT_MAX)
250 aiv->vlan = htons(aiv->vlan);
256 static bool cabletest_do_encode (struct attr *at, unsigned char ports)
258 struct attr_cabletest_do *acd = at->data;
260 if (acd->port < 1 || acd->port > ports)
263 return (acd->action == 1);
267 static bool cabletest_result_encode (struct attr *at, unsigned char ports)
269 unsigned char v = *(unsigned char*)at->data;
271 return (v >= 1 && v <= ports);
275 static bool cabletest_result_decode (struct attr *at, unsigned char ports)
277 struct attr_cabletest_result *acr = at->data;
279 if (acr->port < 1 || acr->port > ports)
282 acr->v1 = ntohl(acr->v1);
283 acr->v2 = ntohl(acr->v2);
289 static bool cabletest_result_endecode (struct attr *at, unsigned char ports)
294 return cabletest_result_encode(at, ports);
296 case sizeof(struct attr_cabletest_result):
297 return cabletest_result_decode(at, ports);
305 static bool vlan_type_endecode (struct attr *at, unsigned char ports UNUSED)
307 char v = *(char*)at->data;
309 return (v >= VLAN_DISABLED && v <= VLAN_DOT_ADV);
313 static bool vlan_port_decode (struct attr *at, unsigned char ports)
316 struct attr_vlan_conf *avc;
320 if (at->size != (2 + 1 + ((ports - 1) >> 3)))
323 avc = malloc(sizeof(struct attr_vlan_conf) + ports);
327 avc->vlan = ntohs(*(unsigned short*)r);
330 for (port = 0; port < ports; port++) {
331 /* FIXME: if ports > 8 */
332 if ((r[0] >> (7 - port)) & 1)
333 avc->ports[port] = VLAN_UNTAGGED;
335 avc->ports[port] = VLAN_NO;
340 at->size = sizeof(struct attr_vlan_conf) + ports;
347 static bool vlan_port_encode (struct attr *at, unsigned char ports)
349 struct attr_vlan_conf *avc = at->data;
351 unsigned int size, port;
354 if (avc->vlan < VLAN_MIN || avc->vlan > VLAN_PORT_MAX)
357 /* just a header is valid */
358 if (at->size == sizeof(struct attr_vlan_conf))
360 else if (at->size == sizeof(struct attr_vlan_conf) + ports)
361 size = (2 + 1 + ((ports - 1) >> 3));
370 *(unsigned short*)r = htons(avc->vlan);
377 for (port = 0; port < ports; port++) {
378 /* FIXME: if ports > 8 */
379 if (avc->ports[port] == VLAN_UNTAGGED)
380 r[0] |= (1 << (7 - port));
395 static bool vlan_dot_decode (struct attr *at, unsigned char ports)
398 struct attr_vlan_conf *avc;
402 if (at->size != (2 + 2 * (1 + ((ports - 1) >> 3))))
405 avc = malloc(sizeof(struct attr_vlan_conf) + ports);
409 avc->vlan = ntohs(*(unsigned short*)r);
412 for (port = 0; port < ports; port++) {
413 /* FIXME: if ports > 8 */
414 if ((r[1] >> (7 - port)) & 1)
415 avc->ports[port] = VLAN_TAGGED;
416 else if ((r[0] >> (7 - port)) & 1)
417 avc->ports[port] = VLAN_UNTAGGED;
419 avc->ports[port] = VLAN_NO;
424 at->size = sizeof(struct attr_vlan_conf) + ports;
431 static bool vlan_dot_encode (struct attr *at, unsigned char ports)
433 struct attr_vlan_conf *avc = at->data;
435 unsigned int size, port;
438 if (avc->vlan < VLAN_MIN || avc->vlan > VLAN_DOT_MAX)
441 /* just a header is valid */
442 if (at->size == sizeof(struct attr_vlan_conf))
444 else if (at->size == sizeof(struct attr_vlan_conf) + ports)
445 size = (2 + 2 * (1 + ((ports - 1) >> 3)));
454 *(unsigned short*)r = htons(avc->vlan);
461 for (port = 0; port < ports; port++) {
462 /* FIXME: if ports > 8 */
463 fl = (1 << (7 - port));
464 switch (avc->ports[port]) {
467 /* a tagged VLAN is also marked as untagged
468 * so do not put a "break" here */
486 /* WARNING: attributes codes MUST be in ascending order */
487 static const struct attr_handler attrtab[] = {
488 ATTR_HANDLER_ENTRY(ATTR_MAC, 6, NULL, NULL),
489 ATTR_HANDLER_ENTRY(ATTR_IP, 4, NULL, NULL),
490 ATTR_HANDLER_ENTRY(ATTR_NETMASK, 4, NULL, NULL),
491 ATTR_HANDLER_ENTRY(ATTR_GATEWAY, 4, NULL, NULL),
492 ATTR_HANDLER_ENTRY(ATTR_DHCP, 2, NULL, NULL),
493 ATTR_HANDLER_ENTRY(ATTR_RESTART, 1, NULL, NULL),
494 ATTR_HANDLER_ENTRY(ATTR_ENCPASS, 4, NULL, NULL),
495 ATTR_HANDLER_ENTRY(ATTR_DEFAULTS, 1, NULL, NULL),
496 ATTR_HANDLER_ENTRY(ATTR_PORT_STATUS, sizeof(struct attr_port_status), NULL, ports_status_decode),
497 ATTR_HANDLER_ENTRY(ATTR_PORT_STATISTICS, sizeof(struct attr_port_stat), NULL, port_stat_decode),
498 ATTR_HANDLER_ENTRY(ATTR_STATS_RESET, 1, bool_endecode, bool_endecode),
499 ATTR_HANDLER_ENTRY(ATTR_CABLETEST_DO, sizeof(struct attr_cabletest_do), cabletest_do_encode, NULL),
500 ATTR_HANDLER_ENTRY(ATTR_CABLETEST_RESULT, 0, cabletest_result_endecode, cabletest_result_endecode),
501 ATTR_HANDLER_ENTRY(ATTR_VLAN_TYPE, 1, vlan_type_endecode, vlan_type_endecode),
502 ATTR_HANDLER_ENTRY(ATTR_VLAN_PORT_CONF, 0, vlan_port_encode, vlan_port_decode),
503 ATTR_HANDLER_ENTRY(ATTR_VLAN_DOT_CONF, 0, vlan_dot_encode, vlan_dot_decode),
504 ATTR_HANDLER_ENTRY(ATTR_VLAN_DESTROY, 2, vlan_destroy_encode, NULL),
505 ATTR_HANDLER_ENTRY(ATTR_VLAN_PVID, sizeof(struct attr_pvid), pvid_encode, pvid_decode),
506 ATTR_HANDLER_ENTRY(ATTR_QOS_TYPE, 1, qos_mode_endecode, qos_mode_endecode),
507 ATTR_HANDLER_ENTRY(ATTR_QOS_CONFIG, sizeof(struct attr_qos), qos_endecode, qos_endecode),
508 ATTR_HANDLER_ENTRY(ATTR_BITRATE_INPUT, sizeof(struct attr_bitrate), bitrate_encode, bitrate_decode),
509 ATTR_HANDLER_ENTRY(ATTR_BITRATE_OUTPUT, sizeof(struct attr_bitrate), bitrate_encode, bitrate_decode),
510 ATTR_HANDLER_ENTRY(ATTR_STORM_ENABLE, 1, bool_endecode, bool_endecode),
511 ATTR_HANDLER_ENTRY(ATTR_STORM_BITRATE, sizeof(struct attr_bitrate), bitrate_encode, bitrate_decode),
512 ATTR_HANDLER_ENTRY(ATTR_MIRROR, 0, mirror_encode, mirror_decode),
513 ATTR_HANDLER_ENTRY(ATTR_PORTS_COUNT, 1, NULL, NULL),
514 ATTR_HANDLER_ENTRY(ATTR_IGMP_ENABLE_VLAN, sizeof(struct attr_igmp_vlan), igmp_vlan_encode, igmp_vlan_decode),
515 ATTR_HANDLER_ENTRY(ATTR_IGMP_BLOCK_UNK, 1, bool_endecode, bool_endecode),
516 ATTR_HANDLER_ENTRY(ATTR_IGMP_VALID_V3, 1, bool_endecode, bool_endecode)
520 const struct attr_handler* getAttrHandler (unsigned short attrcode)
522 const struct attr_handler *ah;
523 const unsigned int tab_size = sizeof(attrtab) / sizeof(struct attr_handler);
524 unsigned int inf, sup, index;
529 index = tab_size >> 1;
530 while (index < sup) {
531 ah = &attrtab[index];
533 if (ah->attr > attrcode) {
535 index -= ((index - inf) >> 1) + ((index - inf) & 1);
536 } else if (ah->attr < attrcode) {
538 index += ((sup - index) >> 1) + ((sup - index) & 1);