9 #define ATTR_HANDLER_ENTRY(at, sz, enc, dec) {.attr = at, .size = sz, .encode = enc, .decode = dec}
13 static bool bool_endecode (struct attr *at, unsigned char ports UNUSED)
15 *(char*)at->data = (*(char*)at->data != 0);
21 static bool ports_status_decode (struct attr *at, unsigned char ports)
23 struct attr_port_status *ps = at->data;
25 if (ps->port < 1 || ps->port > ports)
42 static bool port_stat_decode (struct attr *at, unsigned char ports)
44 struct attr_port_stat *ps = at->data;
45 unsigned long long *v;
47 if (ps->port < 1 || ps->port > ports)
50 for (v = &ps->recv; ((char*)v) - ((char*)ps) < (int)sizeof(struct attr_port_stat); v++)
58 static bool bitrate_decode (struct attr *at, unsigned char ports)
60 struct attr_bitrate *sb = at->data;
62 if (sb->port < 1 || sb->port > ports)
65 sb->bitrate = ntohl(sb->bitrate);
66 if (sb->bitrate < BITRATE_UNSPEC || sb->bitrate > BITRATE_512M)
73 static bool bitrate_encode (struct attr *at, unsigned char ports)
75 struct attr_bitrate *sb = at->data;
77 if (sb->port < 1 || sb->port > ports)
80 if (sb->bitrate < BITRATE_UNSPEC || sb->bitrate > BITRATE_512M)
82 sb->bitrate = htonl(sb->bitrate);
88 static bool qos_mode_endecode (struct attr *at, unsigned char ports UNUSED)
90 unsigned char v = *(char*)at->data;
92 return (v == QOS_PORT || v == QOS_DOT);
96 static bool qos_endecode (struct attr *at, unsigned char ports)
98 struct attr_qos *aq = at->data;
100 if (aq->port < 1 || aq->port > ports)
103 return (aq->prio >= PRIO_HIGH && aq->prio <= PRIO_LOW);
107 static bool pvid_decode (struct attr *at, unsigned char ports)
109 struct attr_pvid *ap= at->data;
111 if (ap->port < 1 || ap->port > ports)
114 ap->vlan = ntohs(ap->vlan);
116 return (ap->vlan >= VLAN_MIN && ap->vlan <= VLAN_MAX);
120 static bool pvid_encode (struct attr *at, unsigned char ports)
122 struct attr_pvid *ap= at->data;
124 if (ap->port < 1 || ap->port > ports)
127 if (ap->vlan < VLAN_MIN || ap->vlan > VLAN_MAX)
130 ap->vlan = htons(ap->vlan);
136 static bool vlan_destroy_encode (struct attr *at, unsigned char ports UNUSED)
138 unsigned short v = *(unsigned short*)at->data;
140 if (v < VLAN_MIN || v > VLAN_MAX)
143 *(unsigned short*)at->data = htons(v);
149 static bool mirror_decode (struct attr *at, unsigned char ports)
151 unsigned char *r = at->data, *p;
155 if (at->size != 3 + ((ports - 1) >> 3))
158 /* r[0] == 0 is allowed and means mirroring is disabled */
162 p = malloc(1 + ports);
166 memset(p, 0, 1 + ports);
173 for (port = 1; port <= ports; port++)
174 p[port] = (r[2] >> (8 - port)) & 1; /* FIXME: if ports > 8 */
179 at->size = 1 + ports;
186 static bool mirror_encode (struct attr *at, unsigned char ports)
188 unsigned char *p = at->data, *r;
192 if (at->size != 1 + ports)
195 /* p[0] == 0 is allowed and means mirroring is disabled */
199 r = malloc(3 + ((ports - 1) >> 3));
203 memset(r, 0, 3 + ((ports - 1) >> 3));
210 for (port = 1; port <= ports; port++) {
212 r[2] |= (p[port] & 1) << (8 - port); /* FIXME: if ports > 8 */
218 at->size = 3 + ((ports - 1) >> 3);
225 static bool igmp_vlan_decode (struct attr *at, unsigned char ports UNUSED)
227 struct attr_igmp_vlan *aiv = at->data;
229 aiv->enable = ntohs(aiv->enable);
230 if (aiv->enable != 0 && aiv->enable != 1)
233 aiv->vlan = ntohs(aiv->vlan);
234 if (aiv->vlan < VLAN_MIN || aiv->vlan > VLAN_MAX)
241 static bool igmp_vlan_encode (struct attr *at, unsigned char ports UNUSED)
243 struct attr_igmp_vlan *aiv = at->data;
245 if (aiv->enable != 0 && aiv->enable != 1)
247 aiv->enable = htons(aiv->enable);
249 if (aiv->vlan < VLAN_MIN || aiv->vlan > VLAN_MAX)
251 aiv->vlan = htons(aiv->vlan);
257 static bool cabletest_do_encode (struct attr *at, unsigned char ports)
259 struct attr_cabletest_do *acd = at->data;
261 if (acd->port < 1 || acd->port > ports)
264 return (acd->action == 1);
268 static bool cabletest_result_encode (struct attr *at, unsigned char ports)
270 unsigned char v = *(unsigned char*)at->data;
272 return (v >= 1 && v <= ports);
276 static bool cabletest_result_decode (struct attr *at, unsigned char ports)
278 struct attr_cabletest_result *acr = at->data;
280 if (acr->port < 1 || acr->port > ports)
283 acr->v1 = ntohl(acr->v1);
284 acr->v2 = ntohl(acr->v2);
290 static bool cabletest_result_endecode (struct attr *at, unsigned char ports)
295 return cabletest_result_encode(at, ports);
297 case sizeof(struct attr_cabletest_result):
298 return cabletest_result_decode(at, ports);
306 static bool vlan_type_endecode (struct attr *at, unsigned char ports UNUSED)
308 char v = *(char*)at->data;
310 return (v >= VLAN_DISABLED && v <= VLAN_DOT_ADV);
314 static bool vlan_dot_decode (struct attr *at, unsigned char ports)
317 struct attr_vlan_dot *avd;
321 if (at->size != (2 + 2 * (1 + ((ports - 1) >> 3))))
324 avd = malloc(sizeof(struct attr_vlan_dot) + ports);
328 avd->vlan = ntohs(*(unsigned short*)r);
331 for (port = 0; port < ports; port++) {
332 /* FIXME: if ports > 8 */
333 if ((r[1] >> (7 - port)) & 1)
334 avd->ports[port] = VLAN_TAGGED;
335 else if ((r[0] >> (7 - port)) & 1)
336 avd->ports[port] = VLAN_UNTAGGED;
338 avd->ports[port] = VLAN_NO;
343 at->size = sizeof(struct attr_vlan_dot) + ports;
350 static bool vlan_dot_encode (struct attr *at, unsigned char ports)
352 struct attr_vlan_dot *avd = at->data;
354 unsigned int size, port;
357 if (avd->vlan < VLAN_MIN || avd->vlan > VLAN_MAX)
360 /* just a header is valid */
361 if (at->size == sizeof(struct attr_vlan_dot))
363 else if (at->size == sizeof(struct attr_vlan_dot) + ports)
364 size = (2 + 2 * (1 + ((ports - 1) >> 3)));
373 *(unsigned short*)r = htons(avd->vlan);
380 for (port = 0; port < ports; port++) {
381 /* FIXME: if ports > 8 */
382 fl = (1 << (7 - port));
383 switch (avd->ports[port]) {
404 /* WARNING: attributes codes MUST be in ascending order */
405 static const struct attr_handler attrtab[] = {
406 ATTR_HANDLER_ENTRY(ATTR_MAC, 6, NULL, NULL),
407 ATTR_HANDLER_ENTRY(ATTR_IP, 4, NULL, NULL),
408 ATTR_HANDLER_ENTRY(ATTR_NETMASK, 4, NULL, NULL),
409 ATTR_HANDLER_ENTRY(ATTR_GATEWAY, 4, NULL, NULL),
410 ATTR_HANDLER_ENTRY(ATTR_DHCP, 2, NULL, NULL),
411 ATTR_HANDLER_ENTRY(ATTR_RESTART, 1, NULL, NULL),
412 ATTR_HANDLER_ENTRY(ATTR_DEFAULTS, 1, NULL, NULL),
413 ATTR_HANDLER_ENTRY(ATTR_PORT_STATUS, sizeof(struct attr_port_status), NULL, ports_status_decode),
414 ATTR_HANDLER_ENTRY(ATTR_PORT_STATISTICS, sizeof(struct attr_port_stat), NULL, port_stat_decode),
415 ATTR_HANDLER_ENTRY(ATTR_STATS_RESET, 1, bool_endecode, bool_endecode),
416 ATTR_HANDLER_ENTRY(ATTR_CABLETEST_DO, sizeof(struct attr_cabletest_do), cabletest_do_encode, NULL),
417 ATTR_HANDLER_ENTRY(ATTR_CABLETEST_RESULT, 0, cabletest_result_endecode, cabletest_result_endecode),
418 ATTR_HANDLER_ENTRY(ATTR_VLAN_TYPE, 1, vlan_type_endecode, vlan_type_endecode),
419 ATTR_HANDLER_ENTRY(ATTR_VLAN_DOT_CONF, 0, vlan_dot_encode, vlan_dot_decode),
420 ATTR_HANDLER_ENTRY(ATTR_VLAN_DESTROY, 2, vlan_destroy_encode, NULL),
421 ATTR_HANDLER_ENTRY(ATTR_VLAN_PVID, sizeof(struct attr_pvid), pvid_encode, pvid_decode),
422 ATTR_HANDLER_ENTRY(ATTR_QOS_TYPE, 1, qos_mode_endecode, qos_mode_endecode),
423 ATTR_HANDLER_ENTRY(ATTR_QOS_CONFIG, sizeof(struct attr_qos), qos_endecode, qos_endecode),
424 ATTR_HANDLER_ENTRY(ATTR_BITRATE_INPUT, sizeof(struct attr_bitrate), bitrate_encode, bitrate_decode),
425 ATTR_HANDLER_ENTRY(ATTR_BITRATE_OUTPUT, sizeof(struct attr_bitrate), bitrate_encode, bitrate_decode),
426 ATTR_HANDLER_ENTRY(ATTR_STORM_ENABLE, 1, bool_endecode, bool_endecode),
427 ATTR_HANDLER_ENTRY(ATTR_STORM_BITRATE, sizeof(struct attr_bitrate), bitrate_encode, bitrate_decode),
428 ATTR_HANDLER_ENTRY(ATTR_MIRROR, 0, mirror_encode, mirror_decode),
429 ATTR_HANDLER_ENTRY(ATTR_PORTS_COUNT, 1, NULL, NULL),
430 ATTR_HANDLER_ENTRY(ATTR_IGMP_ENABLE_VLAN, sizeof(struct attr_igmp_vlan), igmp_vlan_encode, igmp_vlan_decode),
431 ATTR_HANDLER_ENTRY(ATTR_IGMP_BLOCK_UNK, 1, bool_endecode, bool_endecode),
432 ATTR_HANDLER_ENTRY(ATTR_IGMP_VALID_V3, 1, bool_endecode, bool_endecode)
437 const struct attr_handler* getAttrHandler (unsigned short attrcode)
439 const struct attr_handler *ah;
440 const unsigned int tab_size = sizeof(attrtab) / sizeof(struct attr_handler);
441 unsigned int inf, sup, index;
446 index = tab_size >> 1;
447 while (index < sup) {
448 ah = &attrtab[index];
450 if (ah->attr > attrcode) {
452 index -= ((index - inf) >> 1) + ((index - inf) & 1);
453 } else if (ah->attr < attrcode) {
455 index += ((sup - index) >> 1) + ((sup - index) & 1);