docsis_decode.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. /*
  2. * DOCSIS configuration file encoder.
  3. * Copyright (c) 2001 Cornel Ciocirlan, ctrl@users.sourceforge.net.
  4. * Copyright (c) 2002 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. #include <sys/types.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <sys/socket.h>
  27. #include <netinet/in.h>
  28. #include <netdb.h>
  29. #include <math.h>
  30. #include <ctype.h>
  31. /* #include "docsis.h" */
  32. #include "docsis_decode.h"
  33. #include "docsis_globals.h"
  34. #include "docsis_snmp.h"
  35. #include "ethermac.h"
  36. extern unsigned int is_vspecific = FALSE;
  37. struct symbol_entry *
  38. find_symbol_by_code_and_pid (unsigned char code, unsigned int pid)
  39. {
  40. int i;
  41. for ( i=0; i<NUM_IDENTIFIERS; i++) {
  42. if (global_symtable[i].docsis_code == code && global_symtable[i].parent_id == pid) {
  43. return &global_symtable[i];
  44. }
  45. }
  46. return NULL;
  47. }
  48. void decode_uint (unsigned char *tlvbuf, struct symbol_entry *sym, size_t length)
  49. {
  50. static unsigned int helper;
  51. if (length != sizeof(unsigned int) ) {
  52. fprintf(stderr, "u_int length mismatch\n");
  53. exit(-45);
  54. }
  55. memset( &helper, 0, sizeof(unsigned int));
  56. memcpy( &helper, tlvbuf, length);
  57. printf("%s %u;\n", sym->sym_ident, ntohl(helper));
  58. }
  59. void decode_uint24 (unsigned char *tlvbuf, struct symbol_entry *sym, size_t length)
  60. {
  61. printf("%s %d;\n", sym->sym_ident, tlvbuf[0] * 256 * 256 + tlvbuf[1] * 256 + tlvbuf[2]);
  62. }
  63. void decode_ushort (unsigned char *tlvbuf, symbol_type *sym, size_t length)
  64. {
  65. static unsigned short helper;
  66. if (length != sizeof(unsigned short) ) {
  67. fprintf(stderr, "u_short length mismatch\n");
  68. exit(-45);
  69. }
  70. memset( &helper, 0, length);
  71. memcpy( &helper, tlvbuf, length );
  72. printf("%s %hu;\n", sym->sym_ident, ntohs(helper));
  73. }
  74. void decode_uchar (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  75. {
  76. printf("%s %hhu;\n", sym->sym_ident, (unsigned char) *tlvbuf );
  77. }
  78. void decode_ip (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  79. {
  80. static struct in_addr helper;
  81. if (length != sizeof(struct in_addr) ) {
  82. fprintf(stderr, "ip address length mismatch\n");
  83. exit(-45);
  84. }
  85. memcpy (&helper, tlvbuf, length );
  86. printf("%s %s;\n",
  87. sym->sym_ident, inet_ntoa(helper) );
  88. }
  89. void decode_ip_list (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  90. {
  91. static struct in_addr helper;
  92. unsigned int i;
  93. printf("%s ", sym->sym_ident);
  94. for ( i=0; i < length / 4; i++) {
  95. memcpy (&helper, tlvbuf + i * 4, 4 );
  96. printf( "%s", inet_ntoa(helper) );
  97. if (i < (length/4) - 1 ) {
  98. printf(",");
  99. }
  100. }
  101. printf(";\n");
  102. }
  103. void decode_ip6 (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  104. {
  105. static struct in6_addr helper;
  106. char ipstr[INET6_ADDRSTRLEN];
  107. if (length != sizeof(struct in6_addr) ) {
  108. fprintf(stderr, "ip address length mismatch\n");
  109. exit(-45);
  110. }
  111. memcpy (&helper, tlvbuf, length );
  112. fprintf (stdout, "%s %s;\n",
  113. sym->sym_ident, inet_ntop(AF_INET6,tlvbuf,ipstr,sizeof ipstr) );
  114. }
  115. void decode_ip6_list (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  116. {
  117. static struct in6_addr helper;
  118. char ipstr[INET6_ADDRSTRLEN];
  119. unsigned int i;
  120. printf("%s ", sym->sym_ident);
  121. for ( i=0; i < length / 16; i++) {
  122. memcpy (&helper, tlvbuf + i * 16, 16 );
  123. printf( "%s", inet_ntop(AF_INET6, tlvbuf + i * 16, ipstr, sizeof ipstr) );
  124. if (i < (length/16) - 1 ) {
  125. printf(",");
  126. }
  127. }
  128. printf(";\n");
  129. }
  130. void decode_ip6_prefix_list (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  131. {
  132. char ipstr[INET6_ADDRSTRLEN];
  133. unsigned int i;
  134. printf("%s ", sym->sym_ident);
  135. for ( i=0; i < length / 17; i++) {
  136. printf( "%s", inet_ntop(AF_INET6, tlvbuf + i * 17, ipstr, sizeof ipstr) );
  137. printf( "/%d", tlvbuf[i * 17 + 16] );
  138. if (i < (length/17) - 1 ) {
  139. printf(",");
  140. }
  141. }
  142. printf(";\n");
  143. }
  144. void decode_ip_ip6 (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  145. {
  146. static char ip6_addr[INET6_ADDRSTRLEN];
  147. char ipstr[INET6_ADDRSTRLEN];
  148. static struct in_addr ip_addr;
  149. if (length == 4 ) {
  150. memcpy (&ip_addr, tlvbuf, 4);
  151. printf("%s %s;\n", sym->sym_ident, inet_ntoa(ip_addr) );
  152. }
  153. if (length == 16 ) {
  154. memcpy (&ip6_addr, tlvbuf, INET6_ADDRSTRLEN);
  155. printf("%s %s;\n", sym->sym_ident, inet_ntop(AF_INET6,ip6_addr,ipstr,sizeof ipstr) );
  156. }
  157. }
  158. void decode_char_ip_ip6 (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  159. {
  160. static char ip6_addr[INET6_ADDRSTRLEN];
  161. char ipstr[INET6_ADDRSTRLEN];
  162. static struct in_addr ip_addr;
  163. if (length == 5 ) {
  164. memcpy (&ip_addr, tlvbuf + 1, 4);
  165. printf("%s %s;\n", sym->sym_ident, inet_ntoa(ip_addr) );
  166. }
  167. if (length == 17 ) {
  168. memcpy (&ip6_addr, tlvbuf + 1, INET6_ADDRSTRLEN);
  169. printf("%s %s;\n", sym->sym_ident, inet_ntop(AF_INET6,ip6_addr,ipstr,sizeof ipstr) );
  170. }
  171. }
  172. void decode_ip_ip6_port (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  173. {
  174. static char ip6_addr[INET6_ADDRSTRLEN];
  175. char ipstr[INET6_ADDRSTRLEN];
  176. static struct in_addr ip_addr;
  177. if (length == 6 ) {
  178. memcpy (&ip_addr, tlvbuf, 4);
  179. printf("%s %s/%d;\n", sym->sym_ident, inet_ntoa(ip_addr), tlvbuf[4] * 256 + tlvbuf[5] );
  180. }
  181. if (length == 18 ) {
  182. memcpy (&ip6_addr, tlvbuf, INET6_ADDRSTRLEN);
  183. printf("%s %s/%d;\n", sym->sym_ident, inet_ntop(AF_INET6,ip6_addr,ipstr,sizeof ipstr), tlvbuf[16] * 256 + tlvbuf[17] );
  184. }
  185. }
  186. void decode_lenzero (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  187. {
  188. printf("%s 0x00;\n", sym->sym_ident );
  189. }
  190. void decode_ether (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  191. {
  192. if (length != 6 ) {
  193. fprintf(stderr, "ethermac length mismatch\n");
  194. exit(-45);
  195. }
  196. printf("%s %s;\n",
  197. sym->sym_ident, ether_ntoa(tlvbuf) );
  198. }
  199. void decode_dual_qtag (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  200. {
  201. if (length != 4 ) {
  202. fprintf(stderr, "dual qtag length mismatch\n");
  203. exit(-45);
  204. }
  205. printf("%s %d,%d;\n", sym->sym_ident, tlvbuf[0] * 256 + tlvbuf[1], tlvbuf[2]*256 + tlvbuf[3]);
  206. }
  207. void decode_char_list (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  208. {
  209. unsigned int i;
  210. printf("%s ", sym->sym_ident);
  211. for (i = 0; i < length; i++) {
  212. printf("%d", tlvbuf[i]);
  213. if (i < (length - 1) ) {
  214. printf(",");
  215. }
  216. }
  217. printf(";\n");
  218. }
  219. void decode_ethermask (unsigned char *tlvbuf, symbol_type *sym, size_t length)
  220. {
  221. /* the return value of ether_ntoa is a pointer to a static string
  222. * in the ether_ntoa function, so we have to print the values in two
  223. * "passees" to avoid the 2nd call overwriting the 1st.
  224. */
  225. if (length != 12 ) {
  226. fprintf(stderr, "ethermac_and_mask length mismatch\n");
  227. exit(-45);
  228. }
  229. printf("%s %s/", sym->sym_ident, ether_ntoa(tlvbuf));
  230. printf("%s;\n", ether_ntoa(tlvbuf+6));
  231. }
  232. void decode_md5 (unsigned char *tlvbuf, symbol_type *sym, size_t length)
  233. {
  234. size_t j=0;
  235. if (length != 16 ) {
  236. fprintf(stderr, "md5digest length mismatch\n");
  237. exit(-45);
  238. }
  239. printf("/* %s ", sym->sym_ident);
  240. for (j=0;j<length;j++) printf("%02x", tlvbuf[j]);
  241. printf("; */\n");
  242. }
  243. void decode_snmp_wd (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  244. {
  245. printf( "%s ", sym->sym_ident);
  246. /* last char in this TLV is not part of OID */
  247. decode_snmp_oid (tlvbuf, (unsigned int) length-1 );
  248. printf(" %d ;\n", (unsigned int) tlvbuf[length-1] );
  249. }
  250. void decode_oid (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  251. {
  252. printf("%s ", sym->sym_ident);
  253. decode_snmp_oid (tlvbuf,(unsigned int) length );
  254. printf(";\n");
  255. }
  256. void decode_snmp_object (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  257. {
  258. void *pj = malloc(17);
  259. void *pi = malloc(17);
  260. void *pk = malloc(15);
  261. void *pl = malloc(15);
  262. void *pm = malloc(19);
  263. void *pn = malloc(19);
  264. void *po = malloc(19);
  265. void *pp = malloc(19);
  266. if (nohash) {
  267. memcpy (pi, "\x30\x26\x06\x0e\x2b\x06\x01\x04\x01\xa3\x0b\x02\x02\x01\x01\x02\x07", 17);
  268. memcpy (pj, tlvbuf, 17);
  269. if ( *(int*)pi == *(int*)pj ) {
  270. printf("/* ");
  271. printf("%s ", sym->sym_ident);
  272. decode_vbind (tlvbuf, length );
  273. printf(" */");
  274. printf("\n");
  275. return;
  276. }
  277. memcpy (pk, "\x30\x24\x06\x0c\x2b\x06\x01\x04\x01\xba\x08\x01\x01\x02\x09", 15);
  278. memcpy (pl, tlvbuf, 15);
  279. if ( *(int*)pk == *(int*)pl ) {
  280. printf("/* ");
  281. printf("%s ", sym->sym_ident);
  282. decode_vbind (tlvbuf, length );
  283. printf(" */");
  284. printf("\n");
  285. return;
  286. }
  287. }
  288. // when dialplan is shorter than 7F
  289. memcpy (pm, "\x06\x12\x2b\x06\x01\x04\x01\xa3\x0b\x02\x02\x08\x02\x01\x01\x03\x01\x01\x02", 19);
  290. memcpy (pn, tlvbuf + 2, 19);
  291. // when dialplan is longer than 7F
  292. memcpy (po, "\x06\x12\x2b\x06\x01\x04\x01\xa3\x0b\x02\x02\x08\x02\x01\x01\x03\x01\x01\x02", 19);
  293. memcpy (pp, tlvbuf + 4, 19);
  294. if ( memcmp(pm, pn, 19) == 0 || memcmp(po, pp, 19) == 0 ) {
  295. FILE *dialplan = fopen("dialplan.txt", "w");
  296. // when dialplan is shorter than 7F
  297. if (*(int*)pm == *(int*)pn) {
  298. fwrite(tlvbuf+24, sizeof(char), length - 24, dialplan);
  299. }
  300. // when dialplan is longer than 7F
  301. if ( memcmp(po, pp, 19) == 0 ) {
  302. fwrite(tlvbuf+28, sizeof(char), length - 28, dialplan);
  303. }
  304. fclose(dialplan);
  305. printf("/* ");
  306. printf("PC20 dialplan found, dialplan.txt file created.");
  307. printf(" */");
  308. printf("\n");
  309. return;
  310. }
  311. printf("%s ", sym->sym_ident);
  312. decode_vbind (tlvbuf, length );
  313. printf("\n");
  314. free(pi);
  315. free(pj);
  316. free(pk);
  317. free(pl);
  318. free(pm);
  319. free(pn);
  320. free(po);
  321. free(pp);
  322. }
  323. void decode_string (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  324. {
  325. static char helper[TLV_VSIZE];
  326. /* helper = (char *) malloc ( ((unsigned int) tlvbuf[1])+1 ); */
  327. memset ( helper, 0, length+1);
  328. strncpy ( helper, (char *) tlvbuf, length );
  329. printf("%s \"%s\";\n", sym->sym_ident, helper );
  330. }
  331. void decode_strzero (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  332. {
  333. char *helper;
  334. helper = (char *) malloc ( length +1 );
  335. memset ( helper, 0, length+1);
  336. strncpy ( helper, (char *) tlvbuf, length );
  337. printf("%s \"%s\";\n", sym->sym_ident, helper );
  338. free(helper);
  339. }
  340. void decode_hexstr (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  341. {
  342. char *helper;
  343. unsigned int i;
  344. unsigned int len;
  345. int ff = 0xFF;
  346. /* TODO */
  347. len = length;
  348. helper = (char *) malloc ( len+1 );
  349. memset ( helper, 0, len+1);
  350. memcpy ( helper, (char *) tlvbuf, len );
  351. printf("%s 0x", sym->sym_ident);
  352. for(i=0; i<len; i++) {
  353. printf("%02x", (unsigned char) helper[i]);
  354. }
  355. printf(";\n");
  356. if (!strncmp (sym->sym_ident, "VendorIdentifier", 16)) {
  357. if ( (ff != tlvbuf[0]) || (ff != tlvbuf[1]) || (ff != tlvbuf[2]) ) {
  358. is_vspecific = TRUE;
  359. }
  360. }
  361. free(helper);
  362. }
  363. void decode_ushort_list (unsigned char *tlvbuf, symbol_type *sym, size_t length)
  364. {
  365. char *helper;
  366. unsigned int i;
  367. unsigned int len;
  368. len = length ;
  369. helper = (char *) malloc ( len+1 );
  370. memset ( helper, 0, len+1);
  371. memcpy ( helper, (char *) tlvbuf, len );
  372. printf("%s ", sym->sym_ident);
  373. if ( len < 2*sym->low_limit || len > 2*sym->high_limit )
  374. printf("/* -- warning: illegal length of buffer --*/");
  375. for(i=0; i<len; i=i+2) {
  376. printf("%hu", ntohs( (* (unsigned short *) &helper[i])) );
  377. if (i< len-2) printf(",");
  378. }
  379. printf(";\n");
  380. free(helper);
  381. }
  382. void decode_unknown (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  383. {
  384. size_t len=0;
  385. char *cp,*value;
  386. char hexvalue[514];
  387. len = length ;
  388. if (len > 256 ) {
  389. fprintf(stderr, "/* ** next TLV is truncated** */"); len = 256;
  390. }
  391. memset (hexvalue, 0, 514);
  392. value = (char *) malloc ( len+1 );
  393. memset ( value, 0, len+1);
  394. memcpy ( value, (char *) tlvbuf+2, len );
  395. cp = value;
  396. if ( str_isprint(cp, len) && len > 1 ) {
  397. printf("GenericTLV TlvCode %d TlvString ",
  398. (unsigned int) tlvbuf[0]) ;
  399. printf("\"%s\"; /* tlv length = %zd */", cp, len);
  400. } else if ( len > 1 && cp[len-1] == 0 && str_isprint(cp, len-1 ) ) {
  401. printf("GenericTLV TlvCode %d TlvStringZero ",
  402. (unsigned int) tlvbuf[0] ) ;
  403. printf("\"%s\"; /* tlv length = %zd */", cp, len);
  404. } else {
  405. printf("GenericTLV TlvCode %d TlvLength %zd TlvValue ",
  406. (unsigned int) tlvbuf[0], len) ;
  407. snprint_hexadecimal ( hexvalue, 514, value, len);
  408. printf("%s;", hexvalue);
  409. }
  410. printf("\n");
  411. free(value);
  412. }
  413. void decode_special (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  414. {
  415. printf("%s\n", sym->sym_ident);
  416. }
  417. void decode_aggregate (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  418. {
  419. register unsigned char *cp;
  420. symbol_type *current_symbol;
  421. unsigned int tlv_llen = 1; /* length of "Length" encoding of current TLV */
  422. size_t tlv_vlen; /* length of "Value" encoding of current TLV */
  423. /* cp = tlvbuf+1+tlv_llen; */ /* skip type,len of parent TLV */
  424. cp = tlvbuf;
  425. printf("%s\n", sym->sym_ident);
  426. __docsis_indent(INDENT_NOOP, TRUE);
  427. printf("{\n");
  428. __docsis_indent(INDENT_INCREMENT, FALSE);
  429. /* while ( (unsigned int) (cp - tlvbuf +(sizeof(unsigned char))) < (unsigned int) tlvbuf[1] ) { */
  430. while ( (unsigned int) (cp - tlvbuf) < (unsigned int) length ) {
  431. __docsis_indent(INDENT_NOOP, TRUE);
  432. current_symbol = find_symbol_by_code_and_pid (cp[0], sym->id);
  433. tlv_vlen = (size_t) cp[1];
  434. /* printf("tlvbuf has value: %01x\n", tlvbuf); */
  435. if (is_vspecific == TRUE) {
  436. current_symbol = NULL;
  437. }
  438. if (current_symbol == NULL) {
  439. decode_unknown(cp, NULL, tlv_vlen );
  440. } else {
  441. current_symbol->decode_func (cp+1+tlv_llen, current_symbol, tlv_vlen);
  442. }
  443. cp = (unsigned char*) cp + 1 + tlv_llen + tlv_vlen; /* skip type, length value */
  444. }
  445. __docsis_indent(INDENT_DECREMENT, FALSE);
  446. __docsis_indent(INDENT_NOOP, TRUE);
  447. is_vspecific = FALSE;
  448. printf("}\n");
  449. }
  450. /*
  451. ** This is just like decode_aggregate, but it only does symbol lookup
  452. ** for the VendorIdentifier which is the only 'known' TLV.
  453. **/
  454. void decode_vspecific (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  455. {
  456. register unsigned char *cp;
  457. symbol_type *first_symbol;
  458. unsigned int tlv_llen = 1; /* length of "Length" encoding of current TLV */
  459. size_t tlv_vlen; /* length of "Value" encoding of current TLV */
  460. /* cp = tlvbuf+1+tlv_llen; */ /* skip type,len of parent TLV */
  461. cp = tlvbuf;
  462. printf("%s\n", sym->sym_ident);
  463. __docsis_indent(INDENT_NOOP, TRUE);
  464. printf("{\n");
  465. __docsis_indent(INDENT_INCREMENT, FALSE);
  466. /* First TLV inside VendorSpecific has to be VendorIdentifier... the rest we don't care */
  467. first_symbol = find_symbol_by_code_and_pid (cp[0], sym->id);
  468. tlv_vlen = (size_t) cp[1];
  469. if (first_symbol == NULL) {
  470. __docsis_indent(INDENT_NOOP, TRUE);
  471. fprintf(stderr, "/* WARNING: Invalid VendorSpecific option - 1st element is NOT VendorIdentifier */\n");
  472. __docsis_indent(INDENT_NOOP, TRUE);
  473. decode_unknown(cp, NULL, tlv_vlen);
  474. } else {
  475. /* Symbol found ... check if it's the right one */
  476. if (!strncmp (first_symbol->sym_ident, "VendorIdentifier", 16))
  477. {
  478. __docsis_indent(INDENT_NOOP, TRUE);
  479. first_symbol->decode_func(cp+1+tlv_llen, first_symbol, tlv_vlen);
  480. }
  481. else
  482. {
  483. __docsis_indent(INDENT_NOOP, TRUE);
  484. fprintf(stderr, "/* Invalid VendorSpecific option - 1st element is NOT VendorIdentifier */");
  485. __docsis_indent(INDENT_NOOP, TRUE);
  486. decode_unknown(cp, NULL, tlv_vlen );
  487. }
  488. }
  489. cp = (unsigned char*) cp + 1 + tlv_llen + tlv_vlen; /* skip type, length, value */
  490. while ( (unsigned int) (cp - tlvbuf) < (unsigned int) length ) {
  491. __docsis_indent(INDENT_NOOP, TRUE);
  492. tlv_vlen = (size_t) cp[1];
  493. decode_unknown(cp, NULL, tlv_vlen );
  494. cp = (unsigned char*) cp + 1 + tlv_llen + tlv_vlen; /* skip type, length, value */
  495. }
  496. __docsis_indent(INDENT_DECREMENT, FALSE);
  497. __docsis_indent(INDENT_NOOP, TRUE);
  498. printf("}\n");
  499. }
  500. /*
  501. * This function is needed because we don't have a symbol to call it.
  502. * We can't put a "Main" symbol in the symtable because docsis_code is
  503. * unsigned char (in struct symbol_entry) and we reserve the values for
  504. * DOCSIS use.
  505. * It's also a bit different from docsis_aggregate in that docsis_aggregate
  506. * takes an aggregate tlvbuf as argument that INCLUDES the "parent" code and
  507. * length. On the main aggregate we don't have a code / length.
  508. */
  509. void decode_main_aggregate (unsigned char *tlvbuf, size_t buflen)
  510. {
  511. #define TLV_LEN_SIZE 1
  512. register unsigned char *cp = NULL;
  513. symbol_type *current_symbol;
  514. unsigned int tlv_llen = 1; /* length of "Length" encoding of current TLV */
  515. unsigned int is_mta = FALSE;
  516. size_t tlv_vlen; /* length of "Value" encoding of current TLV */
  517. cp = tlvbuf;
  518. __docsis_indent(INDENT_CLEAR, FALSE);
  519. printf("Main \n{\n");
  520. __docsis_indent(INDENT_INCREMENT, FALSE);
  521. while ( (unsigned int) (cp - tlvbuf) < buflen ) {
  522. __docsis_indent(INDENT_NOOP, TRUE);
  523. current_symbol = find_symbol_by_code_and_pid (cp[0],0);
  524. tlv_llen = 1;
  525. tlv_vlen = (size_t) cp[1];
  526. if (cp[0] == 254) {
  527. is_mta = TRUE;
  528. }
  529. if (is_mta) {
  530. if (cp[0] == 64) {
  531. current_symbol = find_symbol_by_code_and_pid (11,0);
  532. tlv_llen = 2;
  533. tlv_vlen = (size_t) ntohs(*((unsigned short *)(cp+1)));
  534. }
  535. }
  536. if (current_symbol == NULL) {
  537. decode_unknown(cp, NULL, (size_t) cp[1] );
  538. } else {
  539. current_symbol->decode_func (cp+1+tlv_llen, current_symbol, tlv_vlen );
  540. }
  541. #ifdef DEBUG
  542. if (cp[0] == 64 ) /* TLV 64 has length encoded as a short */
  543. printf("/* TLV 64, size %hu */ \n", ntohs(*((unsigned short *)(cp+1))) );
  544. #endif
  545. cp = (unsigned char*) cp + 1 + tlv_llen + tlv_vlen ; /* type, length, value */
  546. }
  547. __docsis_indent(INDENT_DECREMENT, FALSE);
  548. printf("}\n");
  549. }
  550. int
  551. hexadecimal_to_binary (const char *str, unsigned char * bufp)
  552. {
  553. int len, itmp;
  554. #ifdef DEBUG
  555. printf("Hex string rx'd: %s\n", str);
  556. #endif
  557. if (!bufp)
  558. return -1;
  559. if (*str && *str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X'))
  560. str += 2;
  561. for (len = 0; *str; str++)
  562. {
  563. if (isspace ((int) *str))
  564. continue;
  565. if (!isxdigit ((int) *str))
  566. return -1;
  567. len++;
  568. if (sscanf (str++, "%2x", &itmp) == 0)
  569. return -1;
  570. *bufp++ = itmp;
  571. if (!*str)
  572. return -1; /* odd number of chars is an error */
  573. }
  574. return len;
  575. }
  576. int
  577. str_isalpha (const char *str, size_t str_len)
  578. {
  579. unsigned int i;
  580. for (i=0; i<str_len; i++)
  581. if (!(isalnum((int) str[i]) && isprint((int) str[i]) && isascii((int) str[i])) ) return FALSE;
  582. return TRUE;
  583. }
  584. int
  585. str_isprint (const char *str, size_t str_len)
  586. {
  587. unsigned int i;
  588. for (i=0; i<str_len; i++)
  589. if (!(isprint((int) str[i]))) return FALSE;
  590. return TRUE;
  591. }
  592. /*
  593. * Print a string in hex format output ... for strings that are not alphanumeric, i.e.
  594. * HexString, BitString etc
  595. * str is the original string
  596. * str_len is the length of the original string
  597. * outbuf is a pointer to the output buffer
  598. */
  599. void
  600. snprint_hexadecimal ( char *outbuf, size_t outsize, const char *str, size_t str_len )
  601. {
  602. unsigned int i;
  603. char *cp;
  604. cp=outbuf;
  605. memset (outbuf, 0, outsize);
  606. sprintf(cp, "0x");
  607. cp = cp +2*sizeof(char);
  608. for (i=0; i<str_len && (unsigned int) (cp-outbuf) < outsize; i++) {
  609. sprintf(cp, "%02x", (unsigned char) str[i]);
  610. cp = cp +2*sizeof(char);
  611. }
  612. }
  613. /* Simple indent handler ... */
  614. void __docsis_indent(int opCode, int doPrint )
  615. {
  616. static int numtabs;
  617. int i;
  618. switch (opCode)
  619. {
  620. case INDENT_INCREMENT:
  621. numtabs++;
  622. break;
  623. ;;
  624. case INDENT_DECREMENT:
  625. numtabs--;
  626. break;
  627. ;;
  628. case INDENT_CLEAR:
  629. numtabs=0;
  630. break;
  631. ;;
  632. }
  633. if ( doPrint )
  634. {
  635. for (i=0; i<numtabs; i++) printf("\t");
  636. }
  637. }