]> git.sur5r.net Git - ngadmin/blob - raw/src/encoding_attr.c
acb706f7429c284c0c4d606dc5c7c73ddcbb75f3
[ngadmin] / raw / src / encoding_attr.c
1
2 #include <ngadmin.h> /* FIXME */
3 #include <nsdp/protocol.h>
4 #include "encoding_attr.h"
5
6
7 #define UNUSED                  __attribute__((unused))
8 #define ATTR_HANDLER_ENTRY(at, sz, enc, dec)    {.attr = at, .size = sz, .encode = enc, .decode = dec}
9
10
11
12 static bool bool_endecode (struct attr *at, unsigned char ports UNUSED)
13 {
14         *(char*)at->data = (*(char*)at->data != 0);
15         
16         return true;
17 }
18
19
20 static bool ports_status_decode (struct attr *at, unsigned char ports)
21 {
22         struct attr_port_status *ps = at->data;
23         
24         if (ps->port < 1 || ps->port > ports)
25                 return false;
26         
27         switch (ps->status) {
28         case SPEED_DOWN:
29         case SPEED_10:
30         case SPEED_100:
31         case SPEED_1000:
32                 break;
33         default:
34                 return false;
35         }
36         
37         return true;
38 }
39
40
41 static bool port_stat_decode (struct attr *at, unsigned char ports)
42 {
43         struct attr_port_stat *ps = at->data;
44         unsigned long long *v;
45         
46         if (ps->port < 1 || ps->port > ports)
47                 return false;
48         
49         for (v = &ps->recv; ((char*)v) - ((char*)ps) < (int)sizeof(struct attr_port_stat); v++)
50                 *v = be64toh(*v);
51         
52         
53         return true;
54 }
55
56
57 static bool bitrate_decode (struct attr *at, unsigned char ports)
58 {
59         struct attr_bitrate *sb = at->data;
60         
61         if (sb->port < 1 || sb->port > ports)
62                 return false;
63         
64         sb->bitrate = ntohl(sb->bitrate);
65         if (sb->bitrate < BITRATE_UNSPEC || sb->bitrate > BITRATE_512M)
66                 return false;
67         
68         return true;
69 }
70
71
72 static bool bitrate_encode (struct attr *at, unsigned char ports)
73 {
74         struct attr_bitrate *sb = at->data;
75         
76         if (sb->port < 1 || sb->port > ports)
77                 return false;
78         
79         if (sb->bitrate < BITRATE_UNSPEC || sb->bitrate > BITRATE_512M)
80                 return false;
81         sb->bitrate = htonl(sb->bitrate);
82         
83         return true;
84 }
85
86
87 static bool qos_mode_endecode (struct attr *at, unsigned char ports UNUSED)
88 {
89         unsigned char v = *(char*)at->data;
90         
91         return (v == QOS_PORT || v == QOS_DOT);
92 }
93
94
95 static bool qos_endecode (struct attr *at, unsigned char ports)
96 {
97         struct attr_qos *aq = at->data;
98         
99         if (aq->port < 1 || aq->port > ports)
100                 return false;
101         
102         return (aq->prio >= PRIO_HIGH && aq->prio <= PRIO_LOW);
103 }
104
105
106 static bool pvid_decode (struct attr *at, unsigned char ports)
107 {
108         struct attr_pvid *ap= at->data;
109         
110         if (ap->port < 1 || ap->port > ports)
111                 return false;
112         
113         ap->vlan = ntohs(ap->vlan);
114         
115         return (ap->vlan >= VLAN_MIN && ap->vlan <= VLAN_DOT_MAX);
116 }
117
118
119 static bool pvid_encode (struct attr *at, unsigned char ports)
120 {
121         struct attr_pvid *ap= at->data;
122         
123         if (ap->port < 1 || ap->port > ports)
124                 return false;
125         
126         if (ap->vlan < VLAN_MIN || ap->vlan > VLAN_DOT_MAX)
127                 return false;
128         
129         ap->vlan = htons(ap->vlan);
130         
131         return true;
132 }
133
134
135 static bool vlan_destroy_encode (struct attr *at, unsigned char ports UNUSED)
136 {
137         unsigned short v = *(unsigned short*)at->data;
138         
139         if (v < VLAN_MIN || v > VLAN_DOT_MAX)
140                 return false;
141         
142         *(unsigned short*)at->data = htons(v);
143         
144         return true;
145 }
146
147
148 static bool mirror_decode (struct attr *at, unsigned char ports)
149 {
150         unsigned char *r = at->data, *p;
151         int port;
152         
153         
154         if (at->size != 3 + ((ports - 1) >> 3))
155                 return false;
156         
157         /* r[0] == 0 is allowed and means mirroring is disabled */
158         if (r[0] > ports)
159                 return false;
160         
161         p = malloc(1 + ports);
162         if (p == NULL)
163                 return false;
164         
165         memset(p, 0, 1 + ports);
166         
167         if (r[0] == 0)
168                 goto end;
169         
170         p[0] = r[0];
171         
172         for (port = 1; port <= ports; port++)
173                 p[port] = (r[2] >> (8 - port)) & 1; /* FIXME: if ports > 8 */
174         
175 end:
176         free(at->data);
177         at->data = p;
178         at->size = 1 + ports;
179         
180         
181         return true;
182 }
183
184
185 static bool mirror_encode (struct attr *at, unsigned char ports)
186 {
187         unsigned char *p = at->data, *r;
188         int port;
189         
190         
191         if (at->size != 1 + ports)
192                 return false;
193         
194         /* p[0] == 0 is allowed and means mirroring is disabled */
195         if (p[0] > ports)
196                 return false;
197         
198         r = malloc(3 + ((ports - 1) >> 3));
199         if (r == NULL)
200                 return false;
201         
202         memset(r, 0, 3 + ((ports - 1) >> 3));
203         
204         if (p[0] == 0)
205                 goto end;
206         
207         r[0] = p[0];
208         
209         for (port = 1; port <= ports; port++) {
210                 if (p[0] != port)
211                         r[2] |= (p[port] & 1) << (8 - port); /* FIXME: if ports > 8 */
212         }
213         
214 end:
215         free(at->data);
216         at->data = r;
217         at->size = 3 + ((ports - 1) >> 3);
218         
219         
220         return true;
221 }
222
223
224 static bool igmp_vlan_decode (struct attr *at, unsigned char ports UNUSED)
225 {
226         struct attr_igmp_vlan *aiv = at->data;
227         
228         aiv->enable = ntohs(aiv->enable);
229         if (aiv->enable != 0 && aiv->enable != 1)
230                 return false;
231         
232         aiv->vlan = ntohs(aiv->vlan);
233         if (aiv->vlan < VLAN_MIN || aiv->vlan > VLAN_DOT_MAX)
234                 return false;
235         
236         return true;
237 }
238
239
240 static bool igmp_vlan_encode (struct attr *at, unsigned char ports UNUSED)
241 {
242         struct attr_igmp_vlan *aiv = at->data;
243         
244         if (aiv->enable != 0 && aiv->enable != 1)
245                 return false;
246         aiv->enable = htons(aiv->enable);
247         
248         if (aiv->vlan < VLAN_MIN || aiv->vlan > VLAN_DOT_MAX)
249                 return false;
250         aiv->vlan = htons(aiv->vlan);
251         
252         return true;
253 }
254
255
256 static bool cabletest_do_encode (struct attr *at, unsigned char ports)
257 {
258         struct attr_cabletest_do *acd = at->data;
259         
260         if (acd->port < 1 || acd->port > ports)
261                 return false;
262         
263         return (acd->action == 1);
264 }
265
266
267 static bool cabletest_result_encode (struct attr *at, unsigned char ports)
268 {
269         unsigned char v = *(unsigned char*)at->data;
270         
271         return (v >= 1 && v <= ports);
272 }
273
274
275 static bool cabletest_result_decode (struct attr *at, unsigned char ports)
276 {
277         struct attr_cabletest_result *acr = at->data;
278         
279         if (acr->port < 1 || acr->port > ports)
280                 return false;
281         
282         acr->v1 = ntohl(acr->v1);
283         acr->v2 = ntohl(acr->v2);
284         
285         return true;
286 }
287
288
289 static bool cabletest_result_endecode (struct attr *at, unsigned char ports)
290 {
291         switch (at->size) {
292         
293         case 1:
294                 return cabletest_result_encode(at, ports);
295         
296         case sizeof(struct attr_cabletest_result):
297                 return cabletest_result_decode(at, ports);
298         
299         default:
300                 return false;
301         }
302 }
303
304
305 static bool vlan_type_endecode (struct attr *at, unsigned char ports UNUSED)
306 {
307         char v = *(char*)at->data;
308         
309         return (v >= VLAN_DISABLED && v <= VLAN_DOT_ADV);
310 }
311
312
313 static bool vlan_port_decode (struct attr *at, unsigned char ports)
314 {
315         char *r = at->data;
316         struct attr_vlan_conf *avc;
317         int port;
318         
319         
320         if (at->size != (2 + 1 + ((ports - 1) >> 3)))
321                 return false;
322         
323         avc = malloc(sizeof(struct attr_vlan_conf) + ports);
324         if (avc == NULL)
325                 return false;
326         
327         avc->vlan = ntohs(*(unsigned short*)r);
328         r += 2;
329         
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;
334                 else
335                         avc->ports[port] = VLAN_NO;
336         }
337         
338         free(at->data);
339         at->data = avc;
340         at->size = sizeof(struct attr_vlan_conf) + ports;
341         
342         
343         return true;
344 }
345
346
347 static bool vlan_port_encode (struct attr *at, unsigned char ports)
348 {
349         struct attr_vlan_conf *avc = at->data;
350         char *r;
351         unsigned int size, port;
352         
353         
354         if (avc->vlan < VLAN_MIN || avc->vlan > VLAN_PORT_MAX)
355                 return false;
356         
357         /* just a header is valid */
358         if (at->size == sizeof(struct attr_vlan_conf))
359                 size = 2;
360         else if (at->size == sizeof(struct attr_vlan_conf) + ports)
361                 size = (2 + 1 + ((ports - 1) >> 3));
362         else
363                 return false;
364         
365         r = malloc(size);
366         if (r == NULL)
367                 return false;
368         
369         memset(r, 0, size);
370         *(unsigned short*)r = htons(avc->vlan);
371         
372         if (size == 2)
373                 goto end;
374         
375         r += 2;
376
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));
381         }
382
383         r -= 2;
384         
385 end:
386         free(at->data);
387         at->data = r;
388         at->size = size;
389         
390         
391         return true;
392 }
393
394
395 static bool vlan_dot_decode (struct attr *at, unsigned char ports)
396 {
397         char *r = at->data;
398         struct attr_vlan_conf *avc;
399         int port;
400         
401         
402         if (at->size != (2 + 2 * (1 + ((ports - 1) >> 3))))
403                 return false;
404         
405         avc = malloc(sizeof(struct attr_vlan_conf) + ports);
406         if (avc == NULL)
407                 return false;
408         
409         avc->vlan = ntohs(*(unsigned short*)r);
410         r += 2;
411         
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;
418                 else
419                         avc->ports[port] = VLAN_NO;
420         }
421         
422         free(at->data);
423         at->data = avc;
424         at->size = sizeof(struct attr_vlan_conf) + ports;
425         
426         
427         return true;
428 }
429
430
431 static bool vlan_dot_encode (struct attr *at, unsigned char ports)
432 {
433         struct attr_vlan_conf *avc = at->data;
434         char *r, fl;
435         unsigned int size, port;
436         
437         
438         if (avc->vlan < VLAN_MIN || avc->vlan > VLAN_DOT_MAX)
439                 return false;
440         
441         /* just a header is valid */
442         if (at->size == sizeof(struct attr_vlan_conf))
443                 size = 2;
444         else if (at->size == sizeof(struct attr_vlan_conf) + ports)
445                 size = (2 + 2 * (1 + ((ports - 1) >> 3)));
446         else
447                 return false;
448         
449         r = malloc(size);
450         if (r == NULL)
451                 return false;
452         
453         memset(r, 0, size);
454         *(unsigned short*)r = htons(avc->vlan);
455         
456         if (size == 2)
457                 goto end;
458         
459         r += 2;
460         
461         for (port = 0; port < ports; port++) {
462                 /* FIXME: if ports > 8 */
463                 fl = (1 << (7 - port));
464                 switch (avc->ports[port]) {
465                 case VLAN_TAGGED:
466                         r[1] |= fl;
467                         /* a tagged VLAN is also marked as untagged
468                          * so do not put a "break" here */
469                 case VLAN_UNTAGGED:
470                         r[0] |= fl;
471                 }
472         }
473         
474         r -= 2;
475         
476 end:
477         free(at->data);
478         at->data = r;
479         at->size = size;
480         
481         
482         return true;
483 }
484
485
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)
517 };
518
519
520 const struct attr_handler* getAttrHandler (unsigned short attrcode)
521 {
522         const struct attr_handler *ah;
523         const unsigned int tab_size = sizeof(attrtab) / sizeof(struct attr_handler);
524         unsigned int inf, sup, index;
525         
526         
527         inf = 0;
528         sup = tab_size;
529         index = tab_size >> 1;
530         while (index < sup) {
531                 ah = &attrtab[index];
532                 
533                 if (ah->attr > attrcode) {
534                         sup = index;
535                         index -= ((index - inf) >> 1) + ((index - inf) & 1);
536                 } else if (ah->attr < attrcode) {
537                         inf = index;
538                         index += ((sup - index) >> 1) + ((sup - index) & 1);
539                 } else {
540                         return ah;
541                 }
542         }
543         
544         
545         return NULL;
546 }
547
548