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