docsis_decode.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  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. void *pq = malloc(19);
  267. void *pr = malloc(19);
  268. if (nohash) {
  269. memcpy (pi, "\x30\x26\x06\x0e\x2b\x06\x01\x04\x01\xa3\x0b\x02\x02\x01\x01\x02\x07", 17);
  270. memcpy (pj, tlvbuf, 17);
  271. if ( *(int*)pi == *(int*)pj ) {
  272. printf("/* ");
  273. printf("%s ", sym->sym_ident);
  274. decode_vbind (tlvbuf, length );
  275. printf(" */");
  276. printf("\n");
  277. return;
  278. }
  279. memcpy (pk, "\x30\x24\x06\x0c\x2b\x06\x01\x04\x01\xba\x08\x01\x01\x02\x09", 15);
  280. memcpy (pl, tlvbuf, 15);
  281. if ( *(int*)pk == *(int*)pl ) {
  282. printf("/* ");
  283. printf("%s ", sym->sym_ident);
  284. decode_vbind (tlvbuf, length );
  285. printf(" */");
  286. printf("\n");
  287. return;
  288. }
  289. }
  290. // when dialplan is shorter than 7F
  291. memcpy (pm, "\x06\x12\x2b\x06\x01\x04\x01\xa3\x0b\x02\x02\x08\x02\x01\x01\x03\x01\x01\x02", 19);
  292. memcpy (pn, tlvbuf + 2, 19);
  293. // when dialplan is longer than 7F
  294. memcpy (po, "\x06\x12\x2b\x06\x01\x04\x01\xa3\x0b\x02\x02\x08\x02\x01\x01\x03\x01\x01\x02", 19);
  295. memcpy (pp, tlvbuf + 4, 19);
  296. //special case dialplan between 0x69 and 0x7f
  297. memcpy (pq, "\x04\x82", 2);
  298. memcpy (pr, tlvbuf + 24, 2);
  299. if ( memcmp(pm, pn, 19) == 0 || memcmp(po, pp, 19) == 0 ) {
  300. FILE *dialplan = fopen("dialplan.txt", "w");
  301. // when dialplan is shorter than 7F
  302. if (*(int*)pm == *(int*)pn) {
  303. fwrite(tlvbuf+24, sizeof(char), length - 24, dialplan);
  304. }
  305. // when dialplan is longer than 7F
  306. if ( memcmp(po, pp, 19) == 0 ) {
  307. if ( memcmp(pq, pr, 2) == 0) {
  308. fwrite(tlvbuf+28, sizeof(char), length - 28, dialplan);
  309. } else {
  310. fwrite(tlvbuf+26, sizeof(char), length - 26, dialplan);
  311. }
  312. }
  313. fclose(dialplan);
  314. printf("/* ");
  315. printf("PC20 dialplan found, dialplan.txt file created.");
  316. printf(" */");
  317. printf("\n");
  318. return;
  319. }
  320. printf("%s ", sym->sym_ident);
  321. decode_vbind (tlvbuf, length );
  322. printf("\n");
  323. free(pi);
  324. free(pj);
  325. free(pk);
  326. free(pl);
  327. free(pm);
  328. free(pn);
  329. free(po);
  330. free(pp);
  331. free(pq);
  332. free(pr);
  333. }
  334. void decode_string (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  335. {
  336. static char helper[TLV_VSIZE];
  337. /* helper = (char *) malloc ( ((unsigned int) tlvbuf[1])+1 ); */
  338. memset ( helper, 0, length+1);
  339. strncpy ( helper, (char *) tlvbuf, length );
  340. printf("%s \"%s\";\n", sym->sym_ident, helper );
  341. }
  342. void decode_strzero (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  343. {
  344. char *helper;
  345. helper = (char *) malloc ( length +1 );
  346. memset ( helper, 0, length+1);
  347. strncpy ( helper, (char *) tlvbuf, length );
  348. printf("%s \"%s\";\n", sym->sym_ident, helper );
  349. free(helper);
  350. }
  351. void decode_hexstr (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  352. {
  353. char *helper;
  354. unsigned int i;
  355. unsigned int len;
  356. int ff = 0xFF;
  357. /* TODO */
  358. len = length;
  359. helper = (char *) malloc ( len+1 );
  360. memset ( helper, 0, len+1);
  361. memcpy ( helper, (char *) tlvbuf, len );
  362. printf("%s 0x", sym->sym_ident);
  363. for(i=0; i<len; i++) {
  364. printf("%02x", (unsigned char) helper[i]);
  365. }
  366. printf(";\n");
  367. if (!strncmp (sym->sym_ident, "VendorIdentifier", 16)) {
  368. if ( (ff != tlvbuf[0]) || (ff != tlvbuf[1]) || (ff != tlvbuf[2]) ) {
  369. is_vspecific = TRUE;
  370. }
  371. }
  372. free(helper);
  373. }
  374. void decode_ushort_list (unsigned char *tlvbuf, symbol_type *sym, size_t length)
  375. {
  376. char *helper;
  377. unsigned int i;
  378. unsigned int len;
  379. len = length ;
  380. helper = (char *) malloc ( len+1 );
  381. memset ( helper, 0, len+1);
  382. memcpy ( helper, (char *) tlvbuf, len );
  383. printf("%s ", sym->sym_ident);
  384. if ( len < 2*sym->low_limit || len > 2*sym->high_limit )
  385. printf("/* -- warning: illegal length of buffer --*/");
  386. for(i=0; i<len; i=i+2) {
  387. printf("%hu", ntohs( (* (unsigned short *) &helper[i])) );
  388. if (i< len-2) printf(",");
  389. }
  390. printf(";\n");
  391. free(helper);
  392. }
  393. void decode_unknown (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  394. {
  395. size_t len=0;
  396. char *cp,*value;
  397. char hexvalue[514];
  398. len = length ;
  399. if (len > 256 ) {
  400. fprintf(stderr, "/* ** next TLV is truncated** */"); len = 256;
  401. }
  402. memset (hexvalue, 0, 514);
  403. value = (char *) malloc ( len+1 );
  404. memset ( value, 0, len+1);
  405. memcpy ( value, (char *) tlvbuf+2, len );
  406. cp = value;
  407. if ( str_isprint(cp, len) && len > 1 ) {
  408. printf("GenericTLV TlvCode %d TlvString ",
  409. (unsigned int) tlvbuf[0]) ;
  410. printf("\"%s\"; /* tlv length = %zd */", cp, len);
  411. } else if ( len > 1 && cp[len-1] == 0 && str_isprint(cp, len-1 ) ) {
  412. printf("GenericTLV TlvCode %d TlvStringZero ",
  413. (unsigned int) tlvbuf[0] ) ;
  414. printf("\"%s\"; /* tlv length = %zd */", cp, len);
  415. } else {
  416. printf("GenericTLV TlvCode %d TlvLength %zd TlvValue ",
  417. (unsigned int) tlvbuf[0], len) ;
  418. snprint_hexadecimal ( hexvalue, 514, value, len);
  419. printf("%s;", hexvalue);
  420. }
  421. printf("\n");
  422. free(value);
  423. }
  424. void decode_special (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  425. {
  426. printf("%s\n", sym->sym_ident);
  427. }
  428. void decode_aggregate (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  429. {
  430. register unsigned char *cp;
  431. symbol_type *current_symbol;
  432. unsigned int tlv_llen = 1; /* length of "Length" encoding of current TLV */
  433. size_t tlv_vlen; /* length of "Value" encoding of current TLV */
  434. /* cp = tlvbuf+1+tlv_llen; */ /* skip type,len of parent TLV */
  435. cp = tlvbuf;
  436. printf("%s\n", sym->sym_ident);
  437. __docsis_indent(INDENT_NOOP, TRUE);
  438. printf("{\n");
  439. __docsis_indent(INDENT_INCREMENT, FALSE);
  440. /* while ( (unsigned int) (cp - tlvbuf +(sizeof(unsigned char))) < (unsigned int) tlvbuf[1] ) { */
  441. while ( (unsigned int) (cp - tlvbuf) < (unsigned int) length ) {
  442. __docsis_indent(INDENT_NOOP, TRUE);
  443. current_symbol = find_symbol_by_code_and_pid (cp[0], sym->id);
  444. tlv_vlen = (size_t) cp[1];
  445. /* printf("tlvbuf has value: %01x\n", tlvbuf); */
  446. if (is_vspecific == TRUE) {
  447. current_symbol = NULL;
  448. }
  449. if (current_symbol == NULL) {
  450. decode_unknown(cp, NULL, tlv_vlen );
  451. } else {
  452. current_symbol->decode_func (cp+1+tlv_llen, current_symbol, tlv_vlen);
  453. }
  454. cp = (unsigned char*) cp + 1 + tlv_llen + tlv_vlen; /* skip type, length value */
  455. }
  456. __docsis_indent(INDENT_DECREMENT, FALSE);
  457. __docsis_indent(INDENT_NOOP, TRUE);
  458. is_vspecific = FALSE;
  459. printf("}\n");
  460. }
  461. /*
  462. ** This is just like decode_aggregate, but it only does symbol lookup
  463. ** for the VendorIdentifier which is the only 'known' TLV.
  464. **/
  465. void decode_vspecific (unsigned char *tlvbuf, symbol_type *sym, size_t length )
  466. {
  467. register unsigned char *cp;
  468. symbol_type *first_symbol;
  469. unsigned int tlv_llen = 1; /* length of "Length" encoding of current TLV */
  470. size_t tlv_vlen; /* length of "Value" encoding of current TLV */
  471. /* cp = tlvbuf+1+tlv_llen; */ /* skip type,len of parent TLV */
  472. cp = tlvbuf;
  473. printf("%s\n", sym->sym_ident);
  474. __docsis_indent(INDENT_NOOP, TRUE);
  475. printf("{\n");
  476. __docsis_indent(INDENT_INCREMENT, FALSE);
  477. /* First TLV inside VendorSpecific has to be VendorIdentifier... the rest we don't care */
  478. first_symbol = find_symbol_by_code_and_pid (cp[0], sym->id);
  479. tlv_vlen = (size_t) cp[1];
  480. if (first_symbol == NULL) {
  481. __docsis_indent(INDENT_NOOP, TRUE);
  482. fprintf(stderr, "/* WARNING: Invalid VendorSpecific option - 1st element is NOT VendorIdentifier */\n");
  483. __docsis_indent(INDENT_NOOP, TRUE);
  484. decode_unknown(cp, NULL, tlv_vlen);
  485. } else {
  486. /* Symbol found ... check if it's the right one */
  487. if (!strncmp (first_symbol->sym_ident, "VendorIdentifier", 16))
  488. {
  489. __docsis_indent(INDENT_NOOP, TRUE);
  490. first_symbol->decode_func(cp+1+tlv_llen, first_symbol, tlv_vlen);
  491. }
  492. else
  493. {
  494. __docsis_indent(INDENT_NOOP, TRUE);
  495. fprintf(stderr, "/* Invalid VendorSpecific option - 1st element is NOT VendorIdentifier */");
  496. __docsis_indent(INDENT_NOOP, TRUE);
  497. decode_unknown(cp, NULL, tlv_vlen );
  498. }
  499. }
  500. cp = (unsigned char*) cp + 1 + tlv_llen + tlv_vlen; /* skip type, length, value */
  501. while ( (unsigned int) (cp - tlvbuf) < (unsigned int) length ) {
  502. __docsis_indent(INDENT_NOOP, TRUE);
  503. tlv_vlen = (size_t) cp[1];
  504. decode_unknown(cp, NULL, tlv_vlen );
  505. cp = (unsigned char*) cp + 1 + tlv_llen + tlv_vlen; /* skip type, length, value */
  506. }
  507. __docsis_indent(INDENT_DECREMENT, FALSE);
  508. __docsis_indent(INDENT_NOOP, TRUE);
  509. printf("}\n");
  510. }
  511. /*
  512. * This function is needed because we don't have a symbol to call it.
  513. * We can't put a "Main" symbol in the symtable because docsis_code is
  514. * unsigned char (in struct symbol_entry) and we reserve the values for
  515. * DOCSIS use.
  516. * It's also a bit different from docsis_aggregate in that docsis_aggregate
  517. * takes an aggregate tlvbuf as argument that INCLUDES the "parent" code and
  518. * length. On the main aggregate we don't have a code / length.
  519. */
  520. void decode_main_aggregate (unsigned char *tlvbuf, size_t buflen)
  521. {
  522. #define TLV_LEN_SIZE 1
  523. register unsigned char *cp = NULL;
  524. symbol_type *current_symbol;
  525. unsigned int tlv_llen = 1; /* length of "Length" encoding of current TLV */
  526. unsigned int is_mta = FALSE;
  527. size_t tlv_vlen; /* length of "Value" encoding of current TLV */
  528. cp = tlvbuf;
  529. __docsis_indent(INDENT_CLEAR, FALSE);
  530. printf("Main \n{\n");
  531. __docsis_indent(INDENT_INCREMENT, FALSE);
  532. while ( (unsigned int) (cp - tlvbuf) < buflen ) {
  533. __docsis_indent(INDENT_NOOP, TRUE);
  534. current_symbol = find_symbol_by_code_and_pid (cp[0],0);
  535. tlv_llen = 1;
  536. tlv_vlen = (size_t) cp[1];
  537. if (cp[0] == 254) {
  538. is_mta = TRUE;
  539. }
  540. if (is_mta) {
  541. if (cp[0] == 64) {
  542. current_symbol = find_symbol_by_code_and_pid (11,0);
  543. tlv_llen = 2;
  544. tlv_vlen = (size_t) ntohs(*((unsigned short *)(cp+1)));
  545. }
  546. }
  547. if (current_symbol == NULL) {
  548. decode_unknown(cp, NULL, (size_t) cp[1] );
  549. } else {
  550. current_symbol->decode_func (cp+1+tlv_llen, current_symbol, tlv_vlen );
  551. }
  552. #ifdef DEBUG
  553. if (cp[0] == 64 ) /* TLV 64 has length encoded as a short */
  554. printf("/* TLV 64, size %hu */ \n", ntohs(*((unsigned short *)(cp+1))) );
  555. #endif
  556. cp = (unsigned char*) cp + 1 + tlv_llen + tlv_vlen ; /* type, length, value */
  557. }
  558. __docsis_indent(INDENT_DECREMENT, FALSE);
  559. printf("}\n");
  560. }
  561. int
  562. hexadecimal_to_binary (const char *str, unsigned char * bufp)
  563. {
  564. int len, itmp;
  565. #ifdef DEBUG
  566. printf("Hex string rx'd: %s\n", str);
  567. #endif
  568. if (!bufp)
  569. return -1;
  570. if (*str && *str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X'))
  571. str += 2;
  572. for (len = 0; *str; str++)
  573. {
  574. if (isspace ((int) *str))
  575. continue;
  576. if (!isxdigit ((int) *str))
  577. return -1;
  578. len++;
  579. if (sscanf (str++, "%2x", &itmp) == 0)
  580. return -1;
  581. *bufp++ = itmp;
  582. if (!*str)
  583. return -1; /* odd number of chars is an error */
  584. }
  585. return len;
  586. }
  587. int
  588. str_isalpha (const char *str, size_t str_len)
  589. {
  590. unsigned int i;
  591. for (i=0; i<str_len; i++)
  592. if (!(isalnum((int) str[i]) && isprint((int) str[i]) && isascii((int) str[i])) ) return FALSE;
  593. return TRUE;
  594. }
  595. int
  596. str_isprint (const char *str, size_t str_len)
  597. {
  598. unsigned int i;
  599. for (i=0; i<str_len; i++)
  600. if (!(isprint((int) str[i]))) return FALSE;
  601. return TRUE;
  602. }
  603. /*
  604. * Print a string in hex format output ... for strings that are not alphanumeric, i.e.
  605. * HexString, BitString etc
  606. * str is the original string
  607. * str_len is the length of the original string
  608. * outbuf is a pointer to the output buffer
  609. */
  610. void
  611. snprint_hexadecimal ( char *outbuf, size_t outsize, const char *str, size_t str_len )
  612. {
  613. unsigned int i;
  614. char *cp;
  615. cp=outbuf;
  616. memset (outbuf, 0, outsize);
  617. sprintf(cp, "0x");
  618. cp = cp +2*sizeof(char);
  619. for (i=0; i<str_len && (unsigned int) (cp-outbuf) < outsize; i++) {
  620. sprintf(cp, "%02x", (unsigned char) str[i]);
  621. cp = cp +2*sizeof(char);
  622. }
  623. }
  624. /* Simple indent handler ... */
  625. void __docsis_indent(int opCode, int doPrint )
  626. {
  627. static int numtabs;
  628. int i;
  629. switch (opCode)
  630. {
  631. case INDENT_INCREMENT:
  632. numtabs++;
  633. break;
  634. ;;
  635. case INDENT_DECREMENT:
  636. numtabs--;
  637. break;
  638. ;;
  639. case INDENT_CLEAR:
  640. numtabs=0;
  641. break;
  642. ;;
  643. }
  644. if ( doPrint )
  645. {
  646. for (i=0; i<numtabs; i++) printf("\t");
  647. }
  648. }