docsis_encode.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  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. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * DOCSIS is a registered trademark of Cablelabs, http://www.cablelabs.com
  21. */
  22. #include <netdb.h>
  23. #include <errno.h>
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <unistd.h>
  29. #include <netinet/in.h>
  30. #include <arpa/inet.h>
  31. #include <fcntl.h>
  32. #include <math.h>
  33. #include "docsis_common.h"
  34. #include "docsis_encode.h"
  35. #include "docsis_snmp.h"
  36. #include "ethermac.h"
  37. extern unsigned int line; /* defined in docsis_lex.l */
  38. int encode_uint ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  39. {
  40. unsigned int int_value;
  41. union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
  42. if ( buf == NULL ) {
  43. fprintf(stderr, "encode_uint called w/NULL buffer\n");
  44. exit (-1);
  45. }
  46. if ( tval == NULL ) {
  47. fprintf(stderr, "encode_uint called w/NULL value struct\n");
  48. exit (-1);
  49. }
  50. helper = (union t_val *) tval;
  51. if ( sym_ptr->low_limit || sym_ptr->high_limit ) {
  52. if ( helper->uintval < sym_ptr->low_limit || helper->uintval > sym_ptr->high_limit ) {
  53. 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);
  54. exit(-15);
  55. }
  56. }
  57. int_value = htonl( helper->uintval );
  58. #ifdef DEBUG
  59. fprintf(stderr, "encode_uint: found %s value %d\n",sym_ptr->sym_ident, helper->uintval);
  60. #endif /* DEBUG */
  61. memcpy ( buf,&int_value, sizeof(unsigned int));
  62. return ( sizeof(unsigned int));
  63. }
  64. int encode_ushort ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  65. {
  66. unsigned short sint;
  67. union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
  68. if ( buf == NULL ) {
  69. fprintf(stderr, "encode_ushort called w/NULL buffer\n");
  70. exit (-1);
  71. }
  72. if ( tval == NULL ) {
  73. fprintf(stderr, "encode_ushort called w/NULL value struct\n");
  74. exit (-1);
  75. }
  76. helper = (union t_val *) tval;
  77. if ( sym_ptr->low_limit || sym_ptr->high_limit ) {
  78. if ( helper->uintval < sym_ptr->low_limit || helper->uintval > sym_ptr->high_limit ) {
  79. 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);
  80. exit(-15);
  81. }
  82. }
  83. sint = htons( (unsigned short) helper->uintval );
  84. #ifdef DEBUG
  85. fprintf(stderr, "encode_ushort: found %s value %hd\n",sym_ptr->sym_ident, helper->uintval);
  86. #endif /* DEBUG */
  87. memcpy ( buf,&sint,sizeof(unsigned short));
  88. return ( sizeof(unsigned short));
  89. }
  90. int encode_uchar ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  91. {
  92. unsigned int int_value;
  93. char *cp;
  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_uchar called w/NULL buffer\n");
  97. exit (-1);
  98. }
  99. if ( tval == NULL ) {
  100. fprintf(stderr, "encode_uchar called w/NULL value struct\n");
  101. exit (-1);
  102. }
  103. helper = (union t_val *) tval;
  104. int_value = htonl( helper->uintval );
  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. cp = (char *)&int_value;
  112. buf[0]=(unsigned char)cp[3];
  113. #ifdef DEBUG
  114. fprintf(stderr, "encode_uchar: found %s value %hd\n",sym_ptr->sym_ident, helper->uintval);
  115. #endif
  116. return ( sizeof(unsigned char));
  117. }
  118. int encode_ip( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  119. {
  120. struct in_addr in;
  121. union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
  122. if ( buf == NULL ) {
  123. fprintf(stderr, "encode_ip called w/NULL buffer\n");
  124. exit (-1);
  125. }
  126. if ( tval == NULL ) {
  127. fprintf(stderr, "encode_ip called w/NULL value struct\n");
  128. exit (-1);
  129. }
  130. helper = (union t_val *) tval;
  131. if ( !inet_aton ( helper->strval, &in) ) {
  132. fprintf(stderr, "Invalid IP address %s at line %d", helper->strval, line );
  133. exit (-1);
  134. }
  135. #ifdef DEBUG
  136. fprintf(stderr, "encode_ip: found %s at line %d\n",inet_ntoa(in), line);
  137. #endif /* DEBUG */
  138. memcpy ( buf, &in, sizeof(struct in_addr));
  139. free(helper->strval);
  140. return ( sizeof(struct in_addr));
  141. }
  142. int encode_ip6( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  143. {
  144. struct in6_addr in;
  145. union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
  146. if ( buf == NULL ) {
  147. fprintf(stderr, "encode_ip called w/NULL buffer\n");
  148. exit (-1);
  149. }
  150. if ( tval == NULL ) {
  151. fprintf(stderr, "encode_ip called w/NULL value struct\n");
  152. exit (-1);
  153. }
  154. helper = (union t_val *) tval;
  155. if ( !inet_pton(AF_INET6, helper->strval, &in) ) {
  156. fprintf(stderr, "Invalid IP address %s at line %d\n", helper->strval, line );
  157. exit (-1);
  158. }
  159. #ifdef DEBUG
  160. fprintf(stderr, "encode_ip: found %s at line %d\n",inet_ntoa(in), line);
  161. #endif /* DEBUG */
  162. memcpy ( buf, &in, sizeof(struct in6_addr));
  163. free(helper->strval);
  164. return ( sizeof(struct in6_addr));
  165. }
  166. int encode_ip_ip6( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  167. {
  168. struct in6_addr in6;
  169. struct in_addr in;
  170. union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
  171. helper = (union t_val *) tval;
  172. if ( inet_pton(AF_INET6, helper->strval, &in6) ) {
  173. memcpy ( buf, &in6, sizeof(struct in6_addr));
  174. free(helper->strval);
  175. return ( sizeof(struct in6_addr));
  176. } else if ( inet_aton ( helper->strval, &in) ) {
  177. memcpy ( buf, &in, sizeof(struct in_addr));
  178. free(helper->strval);
  179. return ( sizeof(struct in_addr));
  180. } else {
  181. fprintf(stderr, "Invalid IP address %s at line %d\n", helper->strval, line );
  182. exit (-1);
  183. }
  184. }
  185. int encode_char_ip_ip6( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  186. {
  187. struct in6_addr in6;
  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. char ipv4 = 1;
  191. char ipv6 = 2;
  192. helper = (union t_val *) tval;
  193. if ( inet_pton(AF_INET6, helper->strval, &in6) ) {
  194. memcpy ( buf, &ipv6, sizeof(char) );
  195. memcpy ( buf + 1, &in6, sizeof(struct in6_addr));
  196. free(helper->strval);
  197. return ( sizeof(char) + sizeof(struct in6_addr));
  198. } else if ( inet_aton ( helper->strval, &in) ) {
  199. memcpy ( buf, &ipv4, sizeof(char) );
  200. memcpy ( buf + 1, &in, sizeof(struct in_addr));
  201. free(helper->strval);
  202. return ( sizeof(char) + sizeof(struct in_addr));
  203. } else {
  204. fprintf(stderr, "Invalid IP address %s at line %d\n", helper->strval, line );
  205. exit (-1);
  206. }
  207. }
  208. int encode_lenzero( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  209. {
  210. return (0);
  211. }
  212. int encode_ether ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  213. {
  214. int retval; /* return value of inet_aton */
  215. union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
  216. if ( buf == NULL ) {
  217. fprintf(stderr, "encode_ether called w/NULL buffer\n");
  218. exit (-1);
  219. }
  220. if ( tval == NULL ) {
  221. fprintf(stderr, "encode_ether called w/NULL value struct\n");
  222. exit (-1);
  223. }
  224. helper = (union t_val *) tval;
  225. if (!(retval = ether_aton ( helper->strval, buf)) ) {
  226. fprintf(stderr, "Invalid MAC address %s at line %d", helper->strval, line );
  227. exit (-1);
  228. }
  229. #ifdef DEBUG
  230. fprintf(stderr, "encode_ether: found %s at line %d\n", ether_ntoa(buf), line);
  231. #endif /* DEBUG */
  232. free(helper->strval);
  233. return retval; /* hopefully this equals 6 :) */
  234. }
  235. int encode_dual_qtag ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  236. {
  237. int i, final;
  238. char *token;
  239. char *array[2];
  240. const char s[2] = ",";
  241. union t_val *helper;
  242. #ifdef DEBUG
  243. fprintf(stderr, "encode_dual_qtag: found '%s' on line %d\n", helper->strval, line );
  244. #endif /* DEBUG */
  245. helper = (union t_val *) tval;
  246. i = 0;
  247. token = strtok(helper->strval, s);
  248. while (token != NULL)
  249. {
  250. array[i++] = token;
  251. token = strtok (NULL, s);
  252. }
  253. final = htonl(atoi(array[0]) << 16 | atoi(array[1]));
  254. memcpy (buf, &final, sizeof(final));
  255. free(helper->strval);
  256. return (sizeof(final));
  257. }
  258. int encode_dual_int ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  259. {
  260. short int i, final;
  261. char *token;
  262. char *array[2];
  263. const char s[2] = ",";
  264. union t_val *helper;
  265. #ifdef DEBUG
  266. fprintf(stderr, "encode_dual_int: found '%s' on line %d\n", helper->strval, line );
  267. #endif /* DEBUG */
  268. helper = (union t_val *) tval;
  269. i = 0;
  270. token = strtok(helper->strval, s);
  271. while (token != NULL)
  272. {
  273. array[i++] = token;
  274. token = strtok (NULL, s);
  275. }
  276. final = htons(atoi(array[0]) << 8 | atoi(array[1]));
  277. memcpy (buf, &final, sizeof(final));
  278. free(helper->strval);
  279. return(sizeof(final));
  280. }
  281. int encode_ethermask ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  282. {
  283. int reta, retb; /* return value of ether_aton */
  284. char *ether,*mask;
  285. union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
  286. if ( buf == NULL ) {
  287. fprintf(stderr, "encode_ethermask called w/NULL buffer\n");
  288. exit (-1);
  289. }
  290. if ( tval == NULL ) {
  291. fprintf(stderr, "encode_ethermask called w/NULL value struct\n");
  292. exit (-1);
  293. }
  294. helper = (union t_val *) tval;
  295. ether = helper -> strval;
  296. mask = strchr ( ether, (int) '/');
  297. if (mask == NULL) {
  298. fprintf(stderr, "encode_ethermask: at line %d, format should be <mac_address>/<mac_mask>\n", line);
  299. exit (-1);
  300. }
  301. mask[0]=0x0; mask++; /* cut the string in two */
  302. if (!(reta = ether_aton ( ether, buf)) ) {
  303. fprintf(stderr, "Invalid MAC address %s at line %d\n", ether, line );
  304. exit (-1);
  305. }
  306. if (!(retb = ether_aton ( mask, buf+reta*(sizeof(char))) ) ) {
  307. fprintf(stderr, "Invalid MAC address %s at line %d\n", mask, line );
  308. exit (-1);
  309. }
  310. #ifdef DEBUG
  311. fprintf(stderr, "encode_ethermask: found %s/%s at line %d\n", ether_ntoa(buf), ether_ntoa(buf+reta*sizeof(char)), line);
  312. #endif /* DEBUG */
  313. free(helper->strval);
  314. return (reta+retb); /* hopefully this equals 12 :) */
  315. }
  316. int encode_string(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  317. {
  318. unsigned int string_size;
  319. /* We only use this to cast the void* we receive to what we think it should be */
  320. union t_val *helper;
  321. if ( buf == NULL ) {
  322. fprintf(stderr, "encode_string called w/NULL buffer\n");
  323. exit (-1);
  324. }
  325. if ( tval == NULL ) {
  326. fprintf(stderr, "encode_string called w/NULL value struct\n");
  327. exit (-1);
  328. }
  329. helper = (union t_val *) tval;
  330. string_size = strlen ( helper->strval );
  331. if (sym_ptr->low_limit || sym_ptr->high_limit) {
  332. if ( string_size < sym_ptr->low_limit ) {
  333. fprintf(stderr, "encode_string: String too short, must be min %d chars\n",
  334. sym_ptr->low_limit);
  335. exit(-1);
  336. }
  337. if ( sym_ptr->high_limit < string_size ) {
  338. fprintf(stderr, "encode_string: String too long (%d chars), must be max %d chars\n",
  339. string_size, sym_ptr->high_limit);
  340. exit(-1);
  341. }
  342. }
  343. #ifdef DEBUG
  344. fprintf(stderr, "encode_string: found '%s' on line %d\n", helper->strval, line );
  345. #endif /* DEBUG */
  346. memset(buf,0,string_size+1);
  347. memcpy ( buf, helper->strval, string_size);
  348. /* No need to free strings because we use a static buffer to parse them */
  349. return ( string_size );
  350. }
  351. /* This is for strings which need the terminating 0 at the end, e.g. Service Flow Class Name */
  352. int encode_strzero(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  353. {
  354. unsigned int string_size;
  355. /* We only use this to cast the void* we receive to what we think it should be */
  356. union t_val *helper;
  357. if ( buf == NULL ) {
  358. fprintf(stderr, "encode_string called w/NULL buffer\n");
  359. exit (-1);
  360. }
  361. if ( tval == NULL ) {
  362. fprintf(stderr, "encode_string called w/NULL value struct\n");
  363. exit (-1);
  364. }
  365. helper = (union t_val *) tval;
  366. string_size = strlen ( helper->strval );
  367. if (sym_ptr->low_limit || sym_ptr->high_limit) {
  368. if ( string_size < sym_ptr->low_limit ) {
  369. fprintf(stderr, "encode_string: String too short, must be min %d chars\n",
  370. sym_ptr->low_limit);
  371. exit(-1);
  372. }
  373. if ( sym_ptr->high_limit < string_size ) {
  374. fprintf(stderr, "encode_string: String too long, must be max %d chars\n",
  375. sym_ptr->high_limit);
  376. exit(-1);
  377. }
  378. }
  379. #ifdef DEBUG
  380. fprintf(stderr, "encode_string: found '%s' on line %d\n", helper->strval, line );
  381. #endif /* DEBUG */
  382. memset(buf,0,string_size+1);
  383. memcpy ( buf, helper->strval, string_size);
  384. /* No need to free strings because we use a static buffer to parse them */
  385. return ( string_size+1 );
  386. }
  387. int encode_hexstr (unsigned char *buf, void *tval, struct symbol_entry *sym_ptr)
  388. {
  389. unsigned int fragval;
  390. unsigned int i;
  391. int rval;
  392. char *p;
  393. unsigned int string_size;
  394. /* We only use this to cast the void * we receive and extract the data from the union */
  395. union t_val *helper;
  396. if ( buf == NULL ) {
  397. fprintf(stderr, "encode_hexstr called w/NULL buffer\n");
  398. exit (-1);
  399. }
  400. if ( tval == NULL ) {
  401. fprintf(stderr, "encode_hexstr called w/NULL value struct\n");
  402. exit (-1);
  403. }
  404. helper = (union t_val *) tval;
  405. string_size = strlen ( helper->strval );
  406. if ( string_size % 2 != 0 ) {
  407. fprintf(stderr, "encode_hexstr: invalid hex string\n");
  408. exit (-1);
  409. }
  410. p = helper->strval;
  411. if (p[0] != '0' || ( p[1] != 'x' && p[1] != 'X' )) {
  412. fprintf(stderr, "encode_hexstr: invalid hex string %s\n", p);
  413. exit (-1);
  414. }
  415. p += 2*sizeof(char);
  416. i=0;
  417. while (*p) {
  418. if ( (rval=sscanf(p, "%02x", &fragval)) == 0) {
  419. fprintf(stderr, "Invalid Hex Value %s\n", helper->strval);
  420. exit (-1);
  421. }
  422. buf[i] = (char) fragval; i++;
  423. p += 2*sizeof(char);
  424. }
  425. if (sym_ptr->low_limit || sym_ptr->high_limit) {
  426. if ( i < sym_ptr->low_limit ) {
  427. fprintf(stderr, "encode_hexstr: Hex value too short, must be min %d octets\n",
  428. sym_ptr->low_limit);
  429. exit(-1);
  430. }
  431. if ( sym_ptr->high_limit < i ) {
  432. fprintf(stderr, "encode_hexstr: Hex value too long, must be max %d octets\n",
  433. sym_ptr->high_limit);
  434. exit(-1);
  435. }
  436. }
  437. #ifdef DEBUG
  438. fprintf(stderr, "encode_hexstr: found '%s' on line %d\n", helper->strval, line );
  439. #endif /* DEBUG */
  440. free(helper->strval);
  441. /* TODO Fix bug added by free(helper->strval) when double quote is used in text config file. */
  442. return ( i );
  443. }
  444. /* This is for strings which need the terminating 0 at the end, e.g. Service Flow Class Name */
  445. int encode_oid(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  446. {
  447. unsigned int output_size;
  448. /* We only use this to cast the void* we receive to what we think it should be */
  449. union t_val *helper;
  450. if ( buf == NULL ) {
  451. fprintf(stderr, "encode_oid called w/NULL buffer\n");
  452. exit (-1);
  453. }
  454. if ( tval == NULL ) {
  455. fprintf(stderr, "encode_oid called w/NULL value struct\n");
  456. exit (-1);
  457. }
  458. helper = (union t_val *) tval;
  459. output_size = encode_snmp_oid(helper->strval, buf, TLV_VSIZE);
  460. free(helper->strval);
  461. return ( output_size );
  462. }
  463. int encode_ushort_list( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  464. {
  465. unsigned short numbers[128];
  466. unsigned long value_found;
  467. unsigned int nr_found=0;
  468. char *cp;
  469. char *endptr[1];
  470. #ifdef DEBUG
  471. int i;
  472. #endif
  473. union t_val *helper; /* We only use this to cast the void* we receive to what we think it should be */
  474. if ( buf == NULL ) {
  475. fprintf(stderr, "encode_ushort_list called w/NULL buffer\n");
  476. exit (-1);
  477. }
  478. if ( tval == NULL ) {
  479. fprintf(stderr, "encode_ushort_list called w/NULL value struct\n");
  480. exit (-1);
  481. }
  482. helper = (union t_val *) tval;
  483. cp = helper->strval;
  484. do {
  485. if(*cp ==',' || *cp == ' ') cp++;
  486. value_found = strtoul( cp, endptr, 10);
  487. if (endptr == NULL)
  488. if (cp == *endptr) {
  489. fprintf(stderr, "Parse error at line %d: expecting digits\n",line);
  490. exit (-11);
  491. }
  492. if (value_found > 65535) {
  493. fprintf(stderr, "Parse error at line %d: value cannot exceed 65535\n",line);
  494. exit (-11);
  495. }
  496. nr_found++;
  497. numbers[nr_found-1]=htons((unsigned short) value_found);
  498. cp=*endptr;
  499. } while (*cp);
  500. if (sym_ptr->low_limit || sym_ptr->high_limit) {
  501. if ( nr_found < sym_ptr->low_limit ) {
  502. fprintf(stderr, "Line %d: Not enough numbers, minimum %d\n", line,
  503. sym_ptr->low_limit);
  504. exit(-1);
  505. }
  506. if ( sym_ptr->high_limit < nr_found ) {
  507. fprintf(stderr, "Line %d: too many numbers, max %d\n", line,
  508. sym_ptr->high_limit);
  509. exit(-1);
  510. }
  511. }
  512. #ifdef DEBUG
  513. fprintf(stderr, "encode_ushort_list: found ");
  514. for(i=0; i<nr_found; i++)
  515. fprintf(stderr, "%d ", ntohs(numbers[i]) );
  516. fprintf(stderr, "\n");
  517. #endif /* DEBUG */
  518. memcpy ( buf, numbers, nr_found*sizeof(unsigned short));
  519. free(helper->strval);
  520. return ( nr_found*sizeof(unsigned short));
  521. }
  522. int encode_nothing(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
  523. {
  524. return 0;
  525. }