1 /*
2 * DOCSIS configuration file encoder.
3 * Copyright (c) 2001,2005 Cornel Ciocirlan, ctrl@users.sourceforge.net.
4 * Copyright (c) 2002,2003,2004,2005 Evvolve Media SRL,office@evvolve.com
5 * Copyright (c) 2014 - 2015 Adrian Simionov, daniel.simionov@gmail.com
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * DOCSIS is a registered trademark of Cablelabs, http://www.cablelabs.com
22 */
23
24 #include <netdb.h>
25
26 #include <errno.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34
35 #include <fcntl.h>
36 #include <math.h>
37
38 #include "docsis_common.h"
39 #include "docsis_encode.h"
40 #include "docsis_snmp.h"
41 #include "ethermac.h"
42
43 extern unsigned int line; /* defined in docsis_lex.l */
44
45
encode_uint(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)46 int encode_uint ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
47 {
48 unsigned int int_value;
49 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
50 if ( buf == NULL ) {
51 fprintf(stderr, "encode_uint called w/NULL buffer\n");
52 exit (-1);
53 }
54
55 if ( tval == NULL ) {
56 fprintf(stderr, "encode_uint called w/NULL value struct\n");
57 exit (-1);
58 }
59 helper = (union t_val *) tval;
60 if ( sym_ptr->low_limit || sym_ptr->high_limit ) {
61 if ( helper->uintval < sym_ptr->low_limit || helper->uintval > sym_ptr->high_limit ) {
62 fprintf(stderr, "docsis: at line %d, %s value %d out of range %hd-%hd\n ", line,sym_ptr->sym_ident,helper->uintval,sym_ptr->low_limit, sym_ptr->high_limit);
63 exit(-15);
64 }
65 }
66 int_value = htonl( helper->uintval );
67 #ifdef DEBUG
68 fprintf(stderr, "encode_uint: found %s value %d\n",sym_ptr->sym_ident, helper->uintval);
69 #endif /* DEBUG */
70 memcpy ( buf,&int_value, sizeof(unsigned int));
71 return ( sizeof(unsigned int));
72 }
73
encode_uint24(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)74 int encode_uint24 ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
75 {
76 unsigned char byte1, byte2, byte3;
77 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
78
79 helper = (union t_val *) tval;
80
81 byte1 = (helper->uintval >> (0)) & 0xFF;
82 byte2 = (helper->uintval >> (8)) & 0xFF;
83 byte3 = (helper->uintval >> (16)) & 0xFF;
84
85 memcpy ( buf,&byte3, sizeof(char));
86 memcpy ( buf+sizeof(char),&byte2, sizeof(char));
87 memcpy ( buf+2*sizeof(char),&byte1, sizeof(char));
88 return ( 3 * sizeof(char));
89 }
90
encode_ushort(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)91 int encode_ushort ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
92 {
93 unsigned short sint;
94 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
95 if ( buf == NULL ) {
96 fprintf(stderr, "encode_ushort called w/NULL buffer\n");
97 exit (-1);
98 }
99
100 if ( tval == NULL ) {
101 fprintf(stderr, "encode_ushort called w/NULL value struct\n");
102 exit (-1);
103 }
104 helper = (union t_val *) tval;
105 if ( sym_ptr->low_limit || sym_ptr->high_limit ) {
106 if ( helper->uintval < sym_ptr->low_limit || helper->uintval > sym_ptr->high_limit ) {
107 fprintf(stderr, "docsis: at line %d, %s value %d out of range %hd-%hd\n ", line,sym_ptr->sym_ident,helper->uintval,sym_ptr->low_limit, sym_ptr->high_limit);
108 exit(-15);
109 }
110 }
111 sint = htons( (unsigned short) helper->uintval );
112 #ifdef DEBUG
113 fprintf(stderr, "encode_ushort: found %s value %hd\n",sym_ptr->sym_ident, helper->uintval);
114 #endif /* DEBUG */
115 memcpy ( buf,&sint,sizeof(unsigned short));
116 return ( sizeof(unsigned short));
117 }
118
encode_uchar(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)119 int encode_uchar ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
120 {
121 unsigned int int_value;
122 char *cp;
123 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
124 if ( buf == NULL ) {
125 fprintf(stderr, "encode_uchar called w/NULL buffer\n");
126 exit (-1);
127 }
128
129 if ( tval == NULL ) {
130 fprintf(stderr, "encode_uchar called w/NULL value struct\n");
131 exit (-1);
132 }
133
134 helper = (union t_val *) tval;
135 int_value = htonl( helper->uintval );
136
137 if ( sym_ptr->low_limit || sym_ptr->high_limit ) {
138 if ( helper->uintval < sym_ptr->low_limit || helper->uintval > sym_ptr->high_limit ) {
139 fprintf(stderr, "docsis: at line %d, %s value %d out of range %hd-%hd\n ", line,sym_ptr->sym_ident,helper->uintval,sym_ptr->low_limit, sym_ptr->high_limit);
140 exit(-15);
141 }
142 }
143 cp = (char *)&int_value;
144 buf[0]=(unsigned char)cp[3];
145 #ifdef DEBUG
146 fprintf(stderr, "encode_uchar: found %s value %hd\n",sym_ptr->sym_ident, helper->uintval);
147 #endif
148
149 return ( sizeof(unsigned char));
150 }
151
152
encode_ip(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)153 int encode_ip( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
154 {
155 struct in_addr in;
156 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
157
158 if ( buf == NULL ) {
159 fprintf(stderr, "encode_ip called w/NULL buffer\n");
160 exit (-1);
161 }
162
163 if ( tval == NULL ) {
164 fprintf(stderr, "encode_ip called w/NULL value struct\n");
165 exit (-1);
166 }
167
168 helper = (union t_val *) tval;
169
170 if ( !inet_aton ( helper->strval, &in) ) {
171 fprintf(stderr, "Invalid IP address %s at line %d", helper->strval, line );
172 exit (-1);
173 }
174 #ifdef DEBUG
175 fprintf(stderr, "encode_ip: found %s at line %d\n",inet_ntoa(in), line);
176 #endif /* DEBUG */
177 memcpy ( buf, &in, sizeof(struct in_addr));
178 free(helper->strval);
179 return ( sizeof(struct in_addr));
180 }
181
encode_ip_list(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)182 int encode_ip_list( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
183 {
184 int i;
185 char *token;
186 char *array[16];
187 const char s[2] = ",";
188 struct in_addr in;
189 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
190
191 helper = (union t_val *) tval;
192 i = 0;
193 token = strtok(helper->strval, s);
194 while (token != NULL)
195 {
196 array[i] = token;
197 token = strtok (NULL, s);
198 if ( inet_aton ( array[i], &in) ) {
199 memcpy ( buf + 4 * i, &in, sizeof(struct in_addr));
200 } else {
201 fprintf(stderr, "Invalid IP address %s at line %d\n", helper->strval, line );
202 exit (-1);
203 }
204 i++;
205 }
206 free(helper->strval);
207 return ( i * sizeof(struct in_addr));
208 }
209
encode_ip6(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)210 int encode_ip6( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
211 {
212 struct in6_addr in;
213 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
214
215 if ( buf == NULL ) {
216 fprintf(stderr, "encode_ip called w/NULL buffer\n");
217 exit (-1);
218 }
219
220 if ( tval == NULL ) {
221 fprintf(stderr, "encode_ip called w/NULL value struct\n");
222 exit (-1);
223 }
224
225 helper = (union t_val *) tval;
226
227 if ( !inet_pton(AF_INET6, helper->strval, &in) ) {
228 fprintf(stderr, "Invalid IP address %s at line %d\n", helper->strval, line );
229 exit (-1);
230 }
231 #ifdef DEBUG
232 fprintf(stderr, "encode_ip: found %s at line %d\n",inet_ntoa(in), line);
233 #endif /* DEBUG */
234 memcpy ( buf, &in, sizeof(struct in6_addr));
235 free(helper->strval);
236 return ( sizeof(struct in6_addr));
237 }
238
encode_ip6_list(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)239 int encode_ip6_list( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
240 {
241 int i;
242 char *token;
243 char *array[16];
244 const char s[2] = ",";
245 struct in6_addr in6;
246 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
247
248 helper = (union t_val *) tval;
249 i = 0;
250 token = strtok(helper->strval, s);
251 while (token != NULL)
252 {
253 array[i] = token;
254 token = strtok (NULL, s);
255 if ( inet_pton ( AF_INET6, array[i], &in6) ) {
256 memcpy ( buf + 16 * i, &in6, sizeof(struct in6_addr));
257 } else {
258 fprintf(stderr, "Invalid IP address %s at line %d\n", helper->strval, line );
259 exit (-1);
260 }
261 i++;
262 }
263 free(helper->strval);
264 return ( i * sizeof(struct in6_addr));
265 }
266
encode_ip6_prefix_list(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)267 int encode_ip6_prefix_list( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
268 {
269 char final;
270 char *str1, *str2, *token, *subtoken;
271 char *saveptr1, *saveptr2;
272 int j;
273 struct in6_addr in6;
274 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
275
276 helper = (union t_val *) tval;
277
278 for (j = 0, str1 = helper->strval; ; j++, str1 = NULL) {
279 token = strtok_r(str1, ",", &saveptr1);
280 if (token == NULL)
281 break;
282 for (str2 = token; ; str2 = NULL) {
283 subtoken = strtok_r(str2, "/", &saveptr2);
284 if (subtoken == NULL)
285 break;
286 if ( inet_pton ( AF_INET6, subtoken, &in6) ) {
287 memcpy ( buf + 17 * j, &in6, sizeof(struct in6_addr));
288 } else {
289 final = (char)atoi(subtoken);
290 memcpy ( buf + 17 * j + sizeof(struct in6_addr),&final,sizeof(unsigned char));
291 }
292 }
293 }
294
295 free(helper->strval);
296 return ( j * ( sizeof(struct in6_addr) + sizeof(unsigned char) ) );
297 }
298
encode_ip_ip6(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)299 int encode_ip_ip6( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
300 {
301 struct in6_addr in6;
302 struct in_addr in;
303 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
304
305 helper = (union t_val *) tval;
306
307 if ( inet_pton(AF_INET6, helper->strval, &in6) ) {
308 memcpy ( buf, &in6, sizeof(struct in6_addr));
309 free(helper->strval);
310 return ( sizeof(struct in6_addr));
311 } else if ( inet_aton ( helper->strval, &in) ) {
312 memcpy ( buf, &in, sizeof(struct in_addr));
313 free(helper->strval);
314 return ( sizeof(struct in_addr));
315 } else {
316 fprintf(stderr, "Invalid IP address %s at line %d\n", helper->strval, line );
317 exit (-1);
318 }
319 }
320
encode_char_ip_ip6(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)321 int encode_char_ip_ip6( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
322 {
323 struct in6_addr in6;
324 struct in_addr in;
325 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
326
327 char ipv4 = 1;
328 char ipv6 = 2;
329
330 helper = (union t_val *) tval;
331
332 if ( inet_pton(AF_INET6, helper->strval, &in6) ) {
333 memcpy ( buf, &ipv6, sizeof(char) );
334 memcpy ( buf + 1, &in6, sizeof(struct in6_addr));
335 free(helper->strval);
336 return ( sizeof(char) + sizeof(struct in6_addr));
337 } else if ( inet_aton ( helper->strval, &in) ) {
338 memcpy ( buf, &ipv4, sizeof(char) );
339 memcpy ( buf + 1, &in, sizeof(struct in_addr));
340 free(helper->strval);
341 return ( sizeof(char) + sizeof(struct in_addr));
342 } else {
343 fprintf(stderr, "Invalid IP address %s at line %d\n", helper->strval, line );
344 exit (-1);
345 }
346 }
347
encode_ip_ip6_port(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)348 int encode_ip_ip6_port( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
349 {
350 struct in6_addr in6;
351 struct in_addr in;
352 int i;
353 short int port;
354 char *token;
355 char *array[2];
356 const char s[2] = "/";
357
358 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
359
360 helper = (union t_val *) tval;
361
362 i = 0;
363 token = strtok(helper->strval, s);
364 while (token != NULL)
365 {
366 array[i++] = token;
367 token = strtok (NULL, s);
368 }
369 port = htons(atoi(array[1]));
370
371 if ( inet_pton(AF_INET6, array[0], &in6) ) {
372 memcpy ( buf, &in6, sizeof(struct in6_addr));
373 memcpy ( buf + sizeof(struct in6_addr),&port,sizeof(unsigned short));
374 free(helper->strval);
375 return ( sizeof(struct in6_addr) + sizeof(unsigned short));
376 } else if ( inet_aton ( array[0], &in) ) {
377 memcpy ( buf, &in, sizeof(struct in_addr));
378 memcpy ( buf + sizeof(struct in_addr),&port,sizeof(unsigned short));
379 free(helper->strval);
380 return ( sizeof(struct in_addr) + sizeof(unsigned short));
381 } else {
382 fprintf(stderr, "Invalid IP address / port combination %s at line %d\n", helper->strval, line );
383 exit (-1);
384 }
385 }
386
encode_lenzero(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)387 int encode_lenzero( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
388 {
389 return (0);
390 }
391
encode_ether(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)392 int encode_ether ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
393 {
394 int retval; /* return value of inet_aton */
395 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
396
397 if ( buf == NULL ) {
398 fprintf(stderr, "encode_ether called w/NULL buffer\n");
399 exit (-1);
400 }
401
402 if ( tval == NULL ) {
403 fprintf(stderr, "encode_ether called w/NULL value struct\n");
404 exit (-1);
405 }
406
407 helper = (union t_val *) tval;
408
409 if (!(retval = ether_aton ( helper->strval, buf)) ) {
410 fprintf(stderr, "Invalid MAC address %s at line %d", helper->strval, line );
411 exit (-1);
412 }
413 #ifdef DEBUG
414 fprintf(stderr, "encode_ether: found %s at line %d\n", ether_ntoa(buf), line);
415 #endif /* DEBUG */
416 free(helper->strval);
417 return retval; /* hopefully this equals 6 :) */
418 }
419
encode_dual_qtag(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)420 int encode_dual_qtag ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
421 {
422 int i, final;
423 char *token;
424 char *array[2];
425 const char s[2] = ",";
426 union t_val *helper;
427
428 #ifdef DEBUG
429 fprintf(stderr, "encode_dual_qtag: found '%s' on line %d\n", helper->strval, line );
430 #endif /* DEBUG */
431
432 helper = (union t_val *) tval;
433 i = 0;
434 token = strtok(helper->strval, s);
435 while (token != NULL)
436 {
437 array[i++] = token;
438 token = strtok (NULL, s);
439 }
440 final = htonl(atoi(array[0]) << 16 | atoi(array[1]));
441 memcpy (buf, &final, sizeof(final));
442 free(helper->strval);
443 return (sizeof(final));
444 }
445
encode_char_list(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)446 int encode_char_list ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
447 {
448 short int i;
449 char *token, final;
450 const char s[2] = ",";
451 union t_val *helper;
452
453 helper = (union t_val *) tval;
454 i = 0;
455 token = strtok(helper->strval, s);
456 while (token != NULL)
457 {
458 final = (char)atoi(token);
459 memcpy (buf + i, &final, sizeof(char));
460 token = strtok (NULL, s);
461 i++;
462 }
463 free(helper->strval);
464 return(i * sizeof(char));
465 }
466
encode_ethermask(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)467 int encode_ethermask ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
468 {
469 int reta, retb; /* return value of ether_aton */
470 char *ether,*mask;
471 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
472
473 if ( buf == NULL ) {
474 fprintf(stderr, "encode_ethermask called w/NULL buffer\n");
475 exit (-1);
476 }
477
478 if ( tval == NULL ) {
479 fprintf(stderr, "encode_ethermask called w/NULL value struct\n");
480 exit (-1);
481 }
482
483 helper = (union t_val *) tval;
484 ether = helper -> strval;
485
486 mask = strchr ( ether, (int) '/');
487 if (mask == NULL) {
488 fprintf(stderr, "encode_ethermask: at line %d, format should be <mac_address>/<mac_mask>\n", line);
489 exit (-1);
490 }
491 mask[0]=0x0; mask++; /* cut the string in two */
492
493 if (!(reta = ether_aton ( ether, buf)) ) {
494 fprintf(stderr, "Invalid MAC address %s at line %d\n", ether, line );
495 exit (-1);
496 }
497 if (!(retb = ether_aton ( mask, buf+reta*(sizeof(char))) ) ) {
498 fprintf(stderr, "Invalid MAC address %s at line %d\n", mask, line );
499 exit (-1);
500 }
501
502 #ifdef DEBUG
503 fprintf(stderr, "encode_ethermask: found %s/%s at line %d\n", ether_ntoa(buf), ether_ntoa(buf+reta*sizeof(char)), line);
504 #endif /* DEBUG */
505 free(helper->strval);
506 return (reta+retb); /* hopefully this equals 12 :) */
507 }
508
encode_string(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)509 int encode_string(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
510 {
511 unsigned int string_size;
512 /* We only use this to cast the void* we receive to what we think it should be */
513 union t_val *helper;
514
515 if ( buf == NULL ) {
516 fprintf(stderr, "encode_string called w/NULL buffer\n");
517 exit (-1);
518 }
519
520 if ( tval == NULL ) {
521 fprintf(stderr, "encode_string called w/NULL value struct\n");
522 exit (-1);
523 }
524 helper = (union t_val *) tval;
525 string_size = strlen ( helper->strval );
526 if (sym_ptr->low_limit || sym_ptr->high_limit) {
527 if ( string_size < sym_ptr->low_limit ) {
528 fprintf(stderr, "encode_string: String too short, must be min %d chars\n",
529 sym_ptr->low_limit);
530 exit(-1);
531 }
532 if ( sym_ptr->high_limit < string_size ) {
533 fprintf(stderr, "encode_string: String too long (%d chars), must be max %d chars\n",
534 string_size, sym_ptr->high_limit);
535 exit(-1);
536 }
537 }
538
539 #ifdef DEBUG
540 fprintf(stderr, "encode_string: found '%s' on line %d\n", helper->strval, line );
541 #endif /* DEBUG */
542 memset(buf,0,string_size+1);
543 memcpy ( buf, helper->strval, string_size);
544 /* No need to free strings because we use a static buffer to parse them */
545 return ( string_size );
546 }
547
548 /* This is for strings which need the terminating 0 at the end, e.g. Service Flow Class Name */
549
encode_strzero(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)550 int encode_strzero(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
551 {
552 unsigned int string_size;
553 /* We only use this to cast the void* we receive to what we think it should be */
554 union t_val *helper;
555
556 if ( buf == NULL ) {
557 fprintf(stderr, "encode_string called w/NULL buffer\n");
558 exit (-1);
559 }
560
561 if ( tval == NULL ) {
562 fprintf(stderr, "encode_string called w/NULL value struct\n");
563 exit (-1);
564 }
565 helper = (union t_val *) tval;
566 string_size = strlen ( helper->strval );
567 if (sym_ptr->low_limit || sym_ptr->high_limit) {
568 if ( string_size < sym_ptr->low_limit ) {
569 fprintf(stderr, "encode_string: String too short, must be min %d chars\n",
570 sym_ptr->low_limit);
571 exit(-1);
572 }
573 if ( sym_ptr->high_limit < string_size ) {
574 fprintf(stderr, "encode_string: String too long, must be max %d chars\n",
575 sym_ptr->high_limit);
576 exit(-1);
577 }
578 }
579
580 #ifdef DEBUG
581 fprintf(stderr, "encode_string: found '%s' on line %d\n", helper->strval, line );
582 #endif /* DEBUG */
583 memset(buf,0,string_size+1);
584 memcpy ( buf, helper->strval, string_size);
585 /* No need to free strings because we use a static buffer to parse them */
586 return ( string_size+1 );
587 }
588
encode_hexstr(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)589 int encode_hexstr (unsigned char *buf, void *tval, struct symbol_entry *sym_ptr)
590 {
591 unsigned int fragval;
592 unsigned int i;
593 int rval;
594 char *p;
595 unsigned int string_size;
596 /* We only use this to cast the void * we receive and extract the data from the union */
597 union t_val *helper;
598
599 if ( buf == NULL ) {
600 fprintf(stderr, "encode_hexstr called w/NULL buffer\n");
601 exit (-1);
602 }
603
604 if ( tval == NULL ) {
605 fprintf(stderr, "encode_hexstr called w/NULL value struct\n");
606 exit (-1);
607 }
608 helper = (union t_val *) tval;
609 string_size = strlen ( helper->strval );
610
611 if ( string_size % 2 != 0 ) {
612 fprintf(stderr, "encode_hexstr: invalid hex string\n");
613 exit (-1);
614 }
615
616 p = helper->strval;
617
618 if (p[0] != '0' || ( p[1] != 'x' && p[1] != 'X' )) {
619 fprintf(stderr, "encode_hexstr: invalid hex string %s\n", p);
620 exit (-1);
621 }
622
623 p += 2*sizeof(char);
624
625 i=0;
626
627 while (*p) {
628 if ( (rval=sscanf(p, "%02x", &fragval)) == 0) {
629 fprintf(stderr, "Invalid Hex Value %s\n", helper->strval);
630 exit (-1);
631 }
632 buf[i] = (char) fragval; i++;
633 p += 2*sizeof(char);
634 }
635
636 if (sym_ptr->low_limit || sym_ptr->high_limit) {
637 if ( i < sym_ptr->low_limit ) {
638 fprintf(stderr, "encode_hexstr: Hex value too short, must be min %d octets\n",
639 sym_ptr->low_limit);
640 exit(-1);
641 }
642 if ( sym_ptr->high_limit < i ) {
643 fprintf(stderr, "encode_hexstr: Hex value too long, must be max %d octets\n",
644 sym_ptr->high_limit);
645 exit(-1);
646 }
647 }
648 #ifdef DEBUG
649 fprintf(stderr, "encode_hexstr: found '%s' on line %d\n", helper->strval, line );
650 #endif /* DEBUG */
651 free(helper->strval);
652 /* TODO Fix bug added by free(helper->strval) when double quote is used in text config file. */
653 return ( i );
654 }
655
656 /* This is for strings which need the terminating 0 at the end, e.g. Service Flow Class Name */
657
encode_oid(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)658 int encode_oid(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
659 {
660 unsigned int output_size;
661 /* We only use this to cast the void* we receive to what we think it should be */
662 union t_val *helper;
663
664 if ( buf == NULL ) {
665 fprintf(stderr, "encode_oid called w/NULL buffer\n");
666 exit (-1);
667 }
668
669 if ( tval == NULL ) {
670 fprintf(stderr, "encode_oid called w/NULL value struct\n");
671 exit (-1);
672 }
673
674 helper = (union t_val *) tval;
675
676 output_size = encode_snmp_oid(helper->strval, buf, TLV_VSIZE);
677 free(helper->strval);
678 return ( output_size );
679 }
680
681
encode_ushort_list(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)682 int encode_ushort_list( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
683 {
684 unsigned short numbers[128];
685 unsigned long value_found;
686 unsigned int nr_found=0;
687 char *cp;
688 char *endptr[1];
689 #ifdef DEBUG
690 int i;
691 #endif
692
693 union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
694
695 if ( buf == NULL ) {
696 fprintf(stderr, "encode_ushort_list called w/NULL buffer\n");
697 exit (-1);
698 }
699
700 if ( tval == NULL ) {
701 fprintf(stderr, "encode_ushort_list called w/NULL value struct\n");
702 exit (-1);
703 }
704
705 helper = (union t_val *) tval;
706
707 cp = helper->strval;
708
709 do {
710 if(*cp ==',' || *cp == ' ') cp++;
711
712 value_found = strtoul( cp, endptr, 10);
713
714 if (endptr == NULL)
715
716 if (cp == *endptr) {
717 fprintf(stderr, "Parse error at line %d: expecting digits\n",line);
718 exit (-11);
719 }
720 if (value_found > 65535) {
721 fprintf(stderr, "Parse error at line %d: value cannot exceed 65535\n",line);
722 exit (-11);
723 }
724 nr_found++;
725 numbers[nr_found-1]=htons((unsigned short) value_found);
726
727 cp=*endptr;
728
729 } while (*cp);
730
731 if (sym_ptr->low_limit || sym_ptr->high_limit) {
732 if ( nr_found < sym_ptr->low_limit ) {
733 fprintf(stderr, "Line %d: Not enough numbers, minimum %d\n", line,
734 sym_ptr->low_limit);
735 exit(-1);
736 }
737 if ( sym_ptr->high_limit < nr_found ) {
738 fprintf(stderr, "Line %d: too many numbers, max %d\n", line,
739 sym_ptr->high_limit);
740 exit(-1);
741 }
742 }
743
744 #ifdef DEBUG
745 fprintf(stderr, "encode_ushort_list: found ");
746 for(i=0; i<nr_found; i++)
747 fprintf(stderr, "%d ", ntohs(numbers[i]) );
748 fprintf(stderr, "\n");
749
750 #endif /* DEBUG */
751 memcpy ( buf, numbers, nr_found*sizeof(unsigned short));
752 free(helper->strval);
753 return ( nr_found*sizeof(unsigned short));
754 }
755
encode_nothing(unsigned char * buf,void * tval,struct symbol_entry * sym_ptr)756 int encode_nothing(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
757 {
758 return 0;
759 }
760