]> The Tcpdump Group git mirrors - tcpdump/blob - print-forces.c
Constify a bunch of stuff.
[tcpdump] / print-forces.c
1 /*
2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that: (1) source code
4 * distributions retain the above copyright notice and this paragraph
5 * in its entirety, and (2) distributions including binary code include
6 * the above copyright notice and this paragraph in its entirety in
7 * the documentation or other materials provided with the distribution.
8 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
10 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11 * FOR A PARTICULAR PURPOSE.
12 *
13 * Copyright (c) 2009 Mojatatu Networks, Inc
14 *
15 */
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include <tcpdump-stdinc.h>
22
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 #include "interface.h"
27 #include "extract.h"
28
29 #include "forces.h"
30
31 #define RESLEN 4
32
33 int
34 prestlv_print(register const u_char * pptr, register u_int len,
35 u_int16_t op_msk _U_, int indent)
36 {
37 const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
38 register const u_char *tdp = (u_char *) TLV_DATA(tlv);
39 struct res_val *r = (struct res_val *)tdp;
40 u_int dlen = len - TLV_HDRL;
41
42 if (dlen != RESLEN) {
43 printf("illegal RESULT-TLV: %d bytes!\n", dlen);
44 return -1;
45 }
46
47 TCHECK(*r);
48 if (r->result >= 0x18 && r->result <= 0xFE) {
49 printf("illegal reserved result code: 0x%x!\n", r->result);
50 return -1;
51 }
52
53 if (vflag >= 3) {
54 char *ib = indent_pr(indent, 0);
55 printf("%s Result: %s (code 0x%x)\n", ib,
56 tok2str(ForCES_errs, NULL, r->result), r->result);
57 }
58 return 0;
59
60 trunc:
61 fputs("[|forces]", stdout);
62 return -1;
63 }
64
65 int
66 fdatatlv_print(register const u_char * pptr, register u_int len,
67 u_int16_t op_msk _U_, int indent)
68 {
69 const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
70 u_int tll = len - TLV_HDRL;
71 register const u_char *tdp = (u_char *) TLV_DATA(tlv);
72 u_int16_t type;
73
74 TCHECK(*tlv);
75 type = EXTRACT_16BITS(&tlv->type);
76 if (type != F_TLV_FULD) {
77 printf("Error: expecting FULLDATA!\n");
78 return -1;
79 }
80
81 if (vflag >= 3) {
82 char *ib = indent_pr(indent + 2, 1);
83 printf("%s[", &ib[1]);
84 hex_print_with_offset(ib, tdp, tll, 0);
85 printf("\n%s]\n", &ib[1]);
86 }
87 return 0;
88
89 trunc:
90 fputs("[|forces]", stdout);
91 return -1;
92 }
93
94 int
95 sdatailv_print(register const u_char * pptr, register u_int len,
96 u_int16_t op_msk _U_, int indent)
97 {
98 u_int tll = len - ILV_HDRL;
99 const struct forces_ilv *ilv = (struct forces_ilv *)pptr;
100 int invilv;
101
102 indent += 1;
103 while (1) {
104 TCHECK(*ilv);
105 invilv = ilv_valid(ilv, tll);
106 if (invilv) {
107 printf("Error: BAD ILV!\n");
108 return -1;
109 }
110 if (vflag >= 3) {
111 register const u_char *tdp = (u_char *) ILV_DATA(ilv);
112 char *ib = indent_pr(indent, 1);
113 printf("\n%s SPARSEDATA: type %x length %d\n", &ib[1],
114 EXTRACT_32BITS(&ilv->type),
115 EXTRACT_32BITS(&ilv->length));
116 printf("%s[", &ib[1]);
117 hex_print_with_offset(ib, tdp, tll, 0);
118 printf("\n%s]\n", &ib[1]);
119 }
120
121 ilv = GO_NXT_ILV(ilv, tll);
122 }
123
124 return 0;
125
126 trunc:
127 fputs("[|forces]", stdout);
128 return -1;
129 }
130
131 int
132 sdatatlv_print(register const u_char * pptr, register u_int len,
133 u_int16_t op_msk, int indent)
134 {
135 const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
136 u_int tll = len - TLV_HDRL;
137 register const u_char *tdp = (u_char *) TLV_DATA(tlv);
138 u_int16_t type;
139
140 TCHECK(*tlv);
141 type = EXTRACT_16BITS(&tlv->type);
142 if (type != F_TLV_SPAD) {
143 printf("Error: expecting SPARSEDATA!\n");
144 return -1;
145 }
146
147 return sdatailv_print(tdp, tll, op_msk, indent);
148
149 trunc:
150 fputs("[|forces]", stdout);
151 return -1;
152 }
153
154 int
155 pkeyitlv_print(register const u_char * pptr, register u_int len,
156 u_int16_t op_msk, int indent)
157 {
158 const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
159 register const u_char *tdp = (u_char *) TLV_DATA(tlv);
160 register const u_char *dp = tdp + 4;
161 const struct forces_tlv *kdtlv = (struct forces_tlv *)dp;
162 u_int32_t id;
163 char *ib = indent_pr(indent, 0);
164 u_int16_t type, tll;
165 int invtlv;
166
167 TCHECK(*tdp);
168 id = EXTRACT_32BITS(tdp);
169 printf("%sKeyinfo: Key 0x%x\n", ib, id);
170 TCHECK(*kdtlv);
171 type = EXTRACT_16BITS(&kdtlv->type);
172 invtlv = tlv_valid(kdtlv, len);
173
174 if (invtlv) {
175 printf("%s TLV type 0x%x len %d\n",
176 tok2str(ForCES_TLV_err, NULL, invtlv), type,
177 EXTRACT_16BITS(&kdtlv->length));
178 return -1;
179 }
180 tll = EXTRACT_16BITS(&kdtlv->length);
181 dp = (u_char *) TLV_DATA(kdtlv);
182 return fdatatlv_print(dp, tll, op_msk, indent);
183
184 trunc:
185 fputs("[|forces]", stdout);
186 return -1;
187 }
188
189 int
190 pdatacnt_print(register const u_char * pptr, register u_int len,
191 u_int32_t IDcnt, u_int16_t op_msk, int indent)
192 {
193 u_int i;
194 int rc;
195 u_int32_t id;
196 char *ib = indent_pr(indent, 0);
197
198 for (i = 0; i < IDcnt; i++) {
199 TCHECK2(*pptr, 4);
200 id = EXTRACT_32BITS(pptr);
201 if (vflag >= 3)
202 printf("%s ID#%02u: %d\n", ib, i + 1, id);
203 len -= 4;
204 pptr += 4;
205 }
206 if (len) {
207 const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr;
208 u_int16_t type;
209 u_int16_t tll;
210 int pad = 0;
211 u_int aln;
212 int invtlv;
213
214 TCHECK(*pdtlv);
215 type = EXTRACT_16BITS(&pdtlv->type);
216 tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL;
217 aln = F_ALN_LEN(EXTRACT_16BITS(&pdtlv->length));
218 invtlv = tlv_valid(pdtlv, len);
219 if (invtlv) {
220 printf
221 ("%s Outstanding bytes %d for TLV type 0x%x TLV len %d\n",
222 tok2str(ForCES_TLV_err, NULL, invtlv), len, type,
223 EXTRACT_16BITS(&pdtlv->length));
224 goto pd_err;
225 }
226 if (aln > EXTRACT_16BITS(&pdtlv->length)) {
227 if (aln > len) {
228 printf
229 ("Invalid padded pathdata TLV type 0x%x len %d missing %d pad bytes\n",
230 type, EXTRACT_16BITS(&pdtlv->length), aln - len);
231 } else {
232 pad = aln - EXTRACT_16BITS(&pdtlv->length);
233 }
234 }
235 if (pd_valid(type)) {
236 const struct pdata_ops *ops = get_forces_pd(type);
237
238 if (vflag >= 3 && ops->v != F_TLV_PDAT) {
239 if (pad)
240 printf
241 ("%s %s (Length %d DataLen %d pad %d Bytes)\n",
242 ib, ops->s, EXTRACT_16BITS(&pdtlv->length),
243 tll, pad);
244 else
245 printf
246 ("%s %s (Length %d DataLen %d Bytes)\n",
247 ib, ops->s, EXTRACT_16BITS(&pdtlv->length),
248 tll);
249 }
250
251 chk_op_type(type, op_msk, ops->op_msk);
252
253 rc = ops->print((const u_char *)pdtlv,
254 tll + pad + TLV_HDRL, op_msk,
255 indent + 2);
256 } else {
257 printf("Invalid path data content type 0x%x len %d\n",
258 type, EXTRACT_16BITS(&pdtlv->length));
259 pd_err:
260 if (EXTRACT_16BITS(&pdtlv->length)) {
261 hex_print_with_offset("Bad Data val\n\t [",
262 pptr, len, 0);
263 printf("]\n");
264
265 return -1;
266 }
267 }
268 }
269 return 0;
270
271 trunc:
272 fputs("[|forces]", stdout);
273 return -1;
274 }
275
276 int
277 pdata_print(register const u_char * pptr, register u_int len,
278 u_int16_t op_msk, int indent)
279 {
280 const struct pathdata_h *pdh = (struct pathdata_h *)pptr;
281 char *ib = indent_pr(indent, 0);
282 u_int minsize = 0;
283
284 TCHECK(*pdh);
285 if (vflag >= 3) {
286 printf("\n%sPathdata: Flags 0x%x ID count %d\n",
287 ib, EXTRACT_16BITS(&pdh->pflags), EXTRACT_16BITS(&pdh->pIDcnt));
288 }
289
290 if (EXTRACT_16BITS(&pdh->pflags) & F_SELKEY) {
291 op_msk |= B_KEYIN;
292 }
293 pptr += sizeof(struct pathdata_h);
294 len -= sizeof(struct pathdata_h);
295 minsize = EXTRACT_16BITS(&pdh->pIDcnt) * 4;
296 if (len < minsize) {
297 printf("\t\t\ttruncated IDs expected %uB got %uB\n", minsize,
298 len);
299 hex_print_with_offset("\t\t\tID Data[", pptr, len, 0);
300 printf("]\n");
301 return -1;
302 }
303 return pdatacnt_print(pptr, len, EXTRACT_16BITS(&pdh->pIDcnt), op_msk, indent);
304
305 trunc:
306 fputs("[|forces]", stdout);
307 return -1;
308 }
309
310 int
311 genoptlv_print(register const u_char * pptr, register u_int len,
312 u_int16_t op_msk, int indent)
313 {
314 const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr;
315 u_int16_t type;
316 int tll;
317 int invtlv;
318 char *ib = indent_pr(indent, 0);
319
320 TCHECK(*pdtlv);
321 type = EXTRACT_16BITS(&pdtlv->type);
322 tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL;
323 invtlv = tlv_valid(pdtlv, len);
324 printf("genoptlvprint - %s TLV type 0x%x len %d\n",
325 tok2str(ForCES_TLV, NULL, type), type, EXTRACT_16BITS(&pdtlv->length));
326 if (!invtlv) {
327 register const u_char *dp = (u_char *) TLV_DATA(pdtlv);
328 if (!ttlv_valid(type)) {
329 printf("%s TLV type 0x%x len %d\n",
330 tok2str(ForCES_TLV_err, NULL, invtlv), type,
331 EXTRACT_16BITS(&pdtlv->length));
332 return -1;
333 }
334 if (vflag >= 3)
335 printf("%s%s, length %d (data length %d Bytes)",
336 ib, tok2str(ForCES_TLV, NULL, type),
337 EXTRACT_16BITS(&pdtlv->length), tll);
338
339 return pdata_print(dp, tll, op_msk, indent + 1);
340 } else {
341 printf("\t\t\tInvalid ForCES TLV type=%x", type);
342 return -1;
343 }
344
345 trunc:
346 fputs("[|forces]", stdout);
347 return -1;
348 }
349
350 int
351 recpdoptlv_print(register const u_char * pptr, register u_int len,
352 u_int16_t op_msk, int indent)
353 {
354 const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr;
355 int tll = len;
356 int rc = 0;
357 int invtlv;
358 u_int16_t type;
359 register const u_char *dp;
360 char *ib;
361
362 while (1) {
363 TCHECK(*pdtlv);
364 invtlv = tlv_valid(pdtlv, len);
365 if (invtlv) {
366 break;
367 }
368 ib = indent_pr(indent, 0);
369 type = EXTRACT_16BITS(&pdtlv->type);
370 dp = (u_char *) TLV_DATA(pdtlv);
371 tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL;
372
373 if (vflag >= 3)
374 printf
375 ("%s%s, length %d (data encapsulated %d Bytes)",
376 ib, tok2str(ForCES_TLV, NULL, type),
377 EXTRACT_16BITS(&pdtlv->length),
378 EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL);
379
380 rc = pdata_print(dp, tll, op_msk, indent + 1);
381 pdtlv = GO_NXT_TLV(pdtlv, len);
382 }
383
384 if (len) {
385 printf
386 ("\n\t\tMessy PATHDATA TLV header, type (0x%x)\n\t\texcess of %d Bytes ",
387 EXTRACT_16BITS(&pdtlv->type), tll - EXTRACT_16BITS(&pdtlv->length));
388 return -1;
389 }
390
391 return 0;
392
393 trunc:
394 fputs("[|forces]", stdout);
395 return -1;
396 }
397
398 int
399 invoptlv_print(register const u_char * pptr, register u_int len,
400 u_int16_t op_msk _U_, int indent)
401 {
402 char *ib = indent_pr(indent, 1);
403
404 if (vflag >= 3) {
405 printf("%sData[", &ib[1]);
406 hex_print_with_offset(ib, pptr, len, 0);
407 printf("%s]\n", ib);
408 }
409 return -1;
410 }
411
412 int otlv_print(const struct forces_tlv *otlv, u_int16_t op_msk _U_, int indent)
413 {
414 int rc = 0;
415 register const u_char *dp = (u_char *) TLV_DATA(otlv);
416 u_int16_t type;
417 int tll;
418 char *ib = indent_pr(indent, 0);
419 const struct optlv_h *ops;
420
421 TCHECK(*otlv);
422 type = EXTRACT_16BITS(&otlv->type);
423 tll = EXTRACT_16BITS(&otlv->length) - TLV_HDRL;
424 ops = get_forces_optlv_h(type);
425 if (vflag >= 3) {
426 printf("%sOper TLV %s(0x%x) length %d\n", ib, ops->s, type,
427 EXTRACT_16BITS(&otlv->length));
428 }
429 /* empty TLVs like COMMIT and TRCOMMIT are empty, we stop here .. */
430 if (!ops->flags & ZERO_TTLV) {
431 if (tll != 0) /* instead of "if (tll)" - for readability .. */
432 printf("%s: Illegal - MUST be empty\n", ops->s);
433 return rc;
434 }
435 /* rest of ops must at least have 12B {pathinfo} */
436 if (tll < OP_MIN_SIZ) {
437 printf("\t\tOper TLV %s(0x%x) length %d\n", ops->s, type,
438 EXTRACT_16BITS(&otlv->length));
439 printf("\t\tTruncated data size %d minimum required %d\n", tll,
440 OP_MIN_SIZ);
441 return invoptlv_print(dp, tll, ops->op_msk, indent);
442
443 }
444
445 rc = ops->print(dp, tll, ops->op_msk, indent + 1);
446 return rc;
447
448 trunc:
449 fputs("[|forces]", stdout);
450 return -1;
451 }
452
453 #define ASTDLN 4
454 #define ASTMCD 255
455 int
456 asttlv_print(register const u_char * pptr, register u_int len,
457 u_int16_t op_msk _U_, int indent)
458 {
459 u_int32_t rescode;
460 u_int dlen = len - TLV_HDRL;
461 char *ib = indent_pr(indent, 0);
462
463 if (dlen != ASTDLN) {
464 printf("illegal ASTresult-TLV: %d bytes!\n", dlen);
465 return -1;
466 }
467 TCHECK2(*pptr, 4);
468 rescode = EXTRACT_32BITS(pptr);
469 if (rescode > ASTMCD) {
470 printf("illegal ASTresult result code: %d!\n", rescode);
471 return -1;
472 }
473
474 if (vflag >= 3) {
475 printf("Teardown reason:\n%s", ib);
476 switch (rescode) {
477 case 0:
478 printf("Normal Teardown");
479 break;
480 case 1:
481 printf("Loss of Heartbeats");
482 break;
483 case 2:
484 printf("Out of bandwidth");
485 break;
486 case 3:
487 printf("Out of Memory");
488 break;
489 case 4:
490 printf("Application Crash");
491 break;
492 default:
493 printf("Unknown Teardown reason");
494 break;
495 }
496 printf("(%x)\n%s", rescode, ib);
497 }
498 return 0;
499
500 trunc:
501 fputs("[|forces]", stdout);
502 return -1;
503 }
504
505 #define ASRDLN 4
506 #define ASRMCD 3
507 int
508 asrtlv_print(register const u_char * pptr, register u_int len,
509 u_int16_t op_msk _U_, int indent)
510 {
511 u_int32_t rescode;
512 u_int dlen = len - TLV_HDRL;
513 char *ib = indent_pr(indent, 0);
514
515 if (dlen != ASRDLN) { /* id, instance, oper tlv */
516 printf("illegal ASRresult-TLV: %d bytes!\n", dlen);
517 return -1;
518 }
519 TCHECK2(*pptr, 4);
520 rescode = EXTRACT_32BITS(pptr);
521
522 if (rescode > ASRMCD) {
523 printf("illegal ASRresult result code: %d!\n", rescode);
524 return -1;
525 }
526
527 if (vflag >= 3) {
528 printf("\n%s", ib);
529 switch (rescode) {
530 case 0:
531 printf("Success ");
532 break;
533 case 1:
534 printf("FE ID invalid ");
535 break;
536 case 2:
537 printf("permission denied ");
538 break;
539 default:
540 printf("Unknown ");
541 break;
542 }
543 printf("(%x)\n%s", rescode, ib);
544 }
545 return 0;
546
547 trunc:
548 fputs("[|forces]", stdout);
549 return -1;
550 }
551
552 int
553 gentltlv_print(register const u_char * pptr _U_, register u_int len,
554 u_int16_t op_msk _U_, int indent _U_)
555 {
556 u_int dlen = len - TLV_HDRL;
557
558 if (dlen < 4) { /* at least 32 bits must exist */
559 printf("truncated TLV: %d bytes missing! ", 4 - dlen);
560 return -1;
561 }
562 return 0;
563 }
564
565 #define RD_MIN 8
566 int
567 print_metailv(register const u_char * pptr, register u_int len,
568 u_int16_t op_msk _U_, int indent)
569 {
570 u_int dlen = len - ILV_HDRL;
571 int tll = dlen;
572 char *ib = indent_pr(indent, 0);
573 /* XXX: check header length */
574 const struct forces_ilv *ilv = (struct forces_ilv *)pptr;
575
576 TCHECK(*ilv);
577 printf("\n%sMetaID 0x%x length %d\n", ib, EXTRACT_32BITS(&ilv->type),
578 EXTRACT_32BITS(&ilv->length));
579 hex_print_with_offset("\n\t\t\t\t[", ILV_DATA(ilv), tll, 0);
580 return 0;
581
582 trunc:
583 fputs("[|forces]", stdout);
584 return -1;
585 }
586
587 int
588 print_metatlv(register const u_char * pptr, register u_int len,
589 u_int16_t op_msk _U_, int indent)
590 {
591 u_int dlen = len - TLV_HDRL;
592 char *ib = indent_pr(indent, 0);
593 u_int tll = dlen;
594 const struct forces_ilv *ilv = (struct forces_ilv *)pptr;
595 int invilv;
596
597 printf("\n%s METADATA\n", ib);
598 while (1) {
599 TCHECK(*ilv);
600 invilv = ilv_valid(ilv, tll);
601 if (invilv)
602 break;
603 print_metailv((u_char *) ilv, tll, 0, indent + 1);
604
605 ilv = GO_NXT_ILV(ilv, tll);
606 }
607
608 return 0;
609
610 trunc:
611 fputs("[|forces]", stdout);
612 return -1;
613 }
614
615 /*
616 */
617 int
618 print_reddata(register const u_char * pptr, register u_int len,
619 u_int16_t op_msk _U_, int indent _U_)
620 {
621 u_int dlen = len - TLV_HDRL;
622 u_int tll = dlen;
623 int invtlv;
624 const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
625
626 printf("\n\t\t Redirect DATA\n");
627 if (dlen <= RD_MIN) {
628 printf("\n\t\ttruncated Redirect data: %d bytes missing! ",
629 RD_MIN - dlen);
630 return -1;
631 }
632
633 TCHECK(*tlv);
634 invtlv = tlv_valid(tlv, tll);
635
636 if (invtlv) {
637 printf("Redir data type 0x%x len %d\n", EXTRACT_16BITS(&tlv->type),
638 EXTRACT_16BITS(&tlv->length));
639 return -1;
640 }
641
642 tll -= TLV_HDRL;
643 hex_print_with_offset("\n\t\t\t[", TLV_DATA(tlv), tll, 0);
644 return 0;
645
646 trunc:
647 fputs("[|forces]", stdout);
648 return -1;
649 }
650
651 int
652 redirect_print(register const u_char * pptr, register u_int len,
653 u_int16_t op_msk _U_, int indent)
654 {
655 const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
656 u_int dlen = len - TLV_HDRL;
657 u_int tll = dlen;
658 int invtlv;
659
660 if (dlen <= RD_MIN) {
661 printf("\n\t\ttruncated Redirect TLV: %d bytes missing! ",
662 RD_MIN - dlen);
663 return -1;
664 }
665
666 indent += 1;
667 while (1) {
668 TCHECK(*tlv);
669 invtlv = tlv_valid(tlv, tll);
670 if (invtlv)
671 break;
672 if (EXTRACT_16BITS(&tlv->type) == F_TLV_METD) {
673 print_metatlv((u_char *) TLV_DATA(tlv), tll, 0, indent);
674 } else if ((EXTRACT_16BITS(&tlv->type) == F_TLV_REDD)) {
675 print_reddata((u_char *) TLV_DATA(tlv), tll, 0, indent);
676 } else {
677 printf("Unknown REDIRECT TLV 0x%x len %d\n",
678 EXTRACT_16BITS(&tlv->type), EXTRACT_16BITS(&tlv->length));
679 }
680
681 tlv = GO_NXT_TLV(tlv, tll);
682 }
683
684 if (tll) {
685 printf
686 ("\n\t\tMessy Redirect TLV header, type (0x%x)\n\t\texcess of %d Bytes ",
687 EXTRACT_16BITS(&tlv->type), tll - EXTRACT_16BITS(&tlv->length));
688 return -1;
689 }
690
691 return 0;
692
693 trunc:
694 fputs("[|forces]", stdout);
695 return -1;
696 }
697
698 #define OP_OFF 8
699 #define OP_MIN 12
700
701 int
702 lfbselect_print(register const u_char * pptr, register u_int len,
703 u_int16_t op_msk, int indent)
704 {
705 const struct forces_lfbsh *lfbs;
706 const struct forces_tlv *otlv;
707 char *ib = indent_pr(indent, 0);
708 u_int dlen = len - TLV_HDRL;
709 u_int tll = dlen - OP_OFF;
710 int invtlv;
711
712 if (dlen <= OP_MIN) { /* id, instance, oper tlv header .. */
713 printf("\n\t\ttruncated lfb selector: %d bytes missing! ",
714 OP_MIN - dlen);
715 return -1;
716 }
717
718 lfbs = (const struct forces_lfbsh *)pptr;
719 TCHECK(*lfbs);
720 if (vflag >= 3) {
721 printf("\n%s%s(Classid %x) instance %x\n",
722 ib, tok2str(ForCES_LFBs, NULL, EXTRACT_32BITS(&lfbs->class)),
723 EXTRACT_32BITS(&lfbs->class),
724 EXTRACT_32BITS(&lfbs->instance));
725 }
726
727 otlv = (struct forces_tlv *)(lfbs + 1);
728
729 indent += 1;
730 while (1) {
731 TCHECK(*otlv);
732 invtlv = tlv_valid(otlv, tll);
733 if (invtlv)
734 break;
735 if (op_valid(EXTRACT_16BITS(&otlv->type), op_msk)) {
736 otlv_print(otlv, 0, indent);
737 } else {
738 if (vflag < 3)
739 printf("\n");
740 printf
741 ("\t\tINValid oper-TLV type 0x%x length %d for this ForCES message\n",
742 EXTRACT_16BITS(&otlv->type), EXTRACT_16BITS(&otlv->length));
743 invoptlv_print((u_char *)otlv, tll, 0, indent);
744 }
745 otlv = GO_NXT_TLV(otlv, tll);
746 }
747
748 if (tll) {
749 printf
750 ("\n\t\tMessy oper TLV header, type (0x%x)\n\t\texcess of %d Bytes ",
751 EXTRACT_16BITS(&otlv->type), tll - EXTRACT_16BITS(&otlv->length));
752 return -1;
753 }
754
755 return 0;
756
757 trunc:
758 fputs("[|forces]", stdout);
759 return -1;
760 }
761
762 int
763 forces_type_print(register const u_char * pptr, const struct forcesh *fhdr _U_,
764 register u_int mlen, const struct tom_h *tops)
765 {
766 const struct forces_tlv *tltlv;
767 u_int tll;
768 int invtlv;
769 int rc = 0;
770 int ttlv = 0;
771
772 tll = mlen - sizeof(struct forcesh);
773
774 if (tll > TLV_HLN) {
775 if (tops->flags & ZERO_TTLV) {
776 printf("<0x%x>Illegal Top level TLV!\n", tops->flags);
777 return -1;
778 }
779 } else {
780 if (tops->flags & ZERO_MORE_TTLV)
781 return 0;
782 if (tops->flags & ONE_MORE_TTLV) {
783 printf("\tTop level TLV Data missing!\n");
784 return -1;
785 }
786 }
787
788 if (tops->flags & ZERO_TTLV) {
789 return 0;
790 }
791
792 ttlv = tops->flags >> 4;
793 tltlv = GET_TOP_TLV(pptr);
794
795 /*XXX: 15 top level tlvs will probably be fine
796 You are nuts if you send more ;-> */
797 while (1) {
798 TCHECK(*tltlv);
799 invtlv = tlv_valid(tltlv, tll);
800 if (invtlv)
801 break;
802 if (!ttlv_valid(EXTRACT_16BITS(&tltlv->type))) {
803 printf("\n\tInvalid ForCES Top TLV type=0x%x",
804 EXTRACT_16BITS(&tltlv->type));
805 return -1;
806 }
807
808 if (vflag >= 3)
809 printf("\t%s, length %d (data length %d Bytes)",
810 tok2str(ForCES_TLV, NULL, EXTRACT_16BITS(&tltlv->type)),
811 EXTRACT_16BITS(&tltlv->length), EXTRACT_16BITS(&tltlv->length) - 4);
812
813 rc = tops->print((u_char *) TLV_DATA(tltlv),
814 EXTRACT_16BITS(&tltlv->length), tops->op_msk, 9);
815 if (rc < 0) {
816 return -1;
817 }
818 tltlv = GO_NXT_TLV(tltlv, tll);
819 ttlv--;
820 if (ttlv <= 0)
821 break;
822 }
823 if (tll) {
824 printf("\tMess TopTLV header: min %lu, total %d advertised %d ",
825 (unsigned long)sizeof(struct forces_tlv),
826 tll, EXTRACT_16BITS(&tltlv->length));
827 return -1;
828 }
829
830 return 0;
831
832 trunc:
833 fputs("[|forces]", stdout);
834 return -1;
835 }
836
837 void forces_print(register const u_char * pptr, register u_int len)
838 {
839 const struct forcesh *fhdr;
840 u_int mlen;
841 u_int32_t flg_raw;
842 const struct tom_h *tops;
843 int rc = 0;
844
845 fhdr = (const struct forcesh *)pptr;
846 TCHECK(*fhdr);
847 if (!tom_valid(fhdr->fm_tom)) {
848 printf("Invalid ForCES message type %d\n", fhdr->fm_tom);
849 goto error;
850 }
851
852 mlen = ForCES_BLN(fhdr);
853
854 tops = get_forces_tom(fhdr->fm_tom);
855 if (tops->v == TOM_RSVD) {
856 printf("\n\tUnknown ForCES message type=0x%x", fhdr->fm_tom);
857 goto error;
858 }
859
860 printf("\n\tForCES %s ", tops->s);
861 if (!ForCES_HLN_VALID(mlen, len)) {
862 printf
863 ("Illegal ForCES pkt len - min %lu, total recvd %d, advertised %d ",
864 (unsigned long)sizeof(struct forcesh), len, ForCES_BLN(fhdr));
865 goto error;
866 }
867
868 TCHECK2(*(pptr + 20), 4);
869 flg_raw = EXTRACT_32BITS(pptr + 20);
870 if (vflag >= 1) {
871 printf("\n\tForCES Version %d len %uB flags 0x%08x ",
872 ForCES_V(fhdr), mlen, flg_raw);
873 printf("\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIu64,
874 ForCES_SID(fhdr), ForCES_node(ForCES_SID(fhdr)),
875 ForCES_DID(fhdr), ForCES_node(ForCES_DID(fhdr)),
876 EXTRACT_64BITS(fhdr->fm_cor));
877
878 }
879 if (vflag >= 2) {
880 printf
881 ("\n\tForCES flags:\n\t %s(0x%x), prio=%d, %s(0x%x),\n\t %s(0x%x), %s(0x%x)\n",
882 ForCES_ACKp(ForCES_ACK(fhdr)), ForCES_ACK(fhdr),
883 ForCES_PRI(fhdr),
884 ForCES_EMp(ForCES_EM(fhdr)), ForCES_EM(fhdr),
885 ForCES_ATp(ForCES_AT(fhdr)), ForCES_AT(fhdr),
886 ForCES_TPp(ForCES_TP(fhdr)), ForCES_TP(fhdr));
887 printf
888 ("\t Extra flags: rsv(b5-7) 0x%x rsv(b13-31) 0x%x\n",
889 ForCES_RS1(fhdr), ForCES_RS2(fhdr));
890 }
891 rc = forces_type_print(pptr, fhdr, mlen, tops);
892 if (rc < 0) {
893 error:
894 hex_print_with_offset("\n\t[", pptr, len, 0);
895 printf("\n\t]");
896 return;
897 }
898
899 if (vflag >= 4) {
900 printf("\n\t Raw ForCES message\n\t [");
901 hex_print_with_offset("\n\t ", pptr, len, 0);
902 printf("\n\t ]");
903 }
904 printf("\n");
905 return;
906
907 trunc:
908 fputs("[|forces]", stdout);
909 }