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