]> The Tcpdump Group git mirrors - tcpdump/blob - print-forces.c
Put PRIu64 on the same line as the rest of the format string.
[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 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 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 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 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 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 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 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 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 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 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 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 if (vflag >= 3) {
404 printf("%sData[", &ib[1]);
405 hex_print_with_offset(ib, pptr, len, 0);
406 printf("%s]\n", ib);
407 }
408 return -1;
409 }
410
411 int otlv_print(struct forces_tlv *otlv, u_int16_t op_msk _U_, int indent)
412 {
413 int rc = 0;
414 register const u_char *dp = (u_char *) TLV_DATA(otlv);
415 u_int16_t type;
416 int tll;
417 char *ib = indent_pr(indent, 0);
418 struct optlv_h *ops;
419
420 TCHECK(*otlv);
421 type = EXTRACT_16BITS(&otlv->type);
422 tll = EXTRACT_16BITS(&otlv->length) - TLV_HDRL;
423 ops = get_forces_optlv_h(type);
424 if (vflag >= 3) {
425 printf("%sOper TLV %s(0x%x) length %d\n", ib, ops->s, type,
426 EXTRACT_16BITS(&otlv->length));
427 }
428 /* empty TLVs like COMMIT and TRCOMMIT are empty, we stop here .. */
429 if (!ops->flags & ZERO_TTLV) {
430 if (tll != 0) /* instead of "if (tll)" - for readability .. */
431 printf("%s: Illegal - MUST be empty\n", ops->s);
432 return rc;
433 }
434 /* rest of ops must at least have 12B {pathinfo} */
435 if (tll < OP_MIN_SIZ) {
436 printf("\t\tOper TLV %s(0x%x) length %d\n", ops->s, type,
437 EXTRACT_16BITS(&otlv->length));
438 printf("\t\tTruncated data size %d minimum required %d\n", tll,
439 OP_MIN_SIZ);
440 return invoptlv_print(dp, tll, ops->op_msk, indent);
441
442 }
443
444 rc = ops->print(dp, tll, ops->op_msk, indent + 1);
445 return rc;
446
447 trunc:
448 fputs("[|forces]", stdout);
449 return -1;
450 }
451
452 #define ASTDLN 4
453 #define ASTMCD 255
454 int
455 asttlv_print(register const u_char * pptr, register u_int len,
456 u_int16_t op_msk _U_, int indent)
457 {
458
459 u_int32_t rescode;
460 u_int dlen = len - TLV_HDRL;
461 char *ib = indent_pr(indent, 0);
462 if (dlen != ASTDLN) {
463 printf("illegal ASTresult-TLV: %d bytes!\n", dlen);
464 return -1;
465 }
466 TCHECK2(*pptr, 4);
467 rescode = EXTRACT_32BITS(pptr);
468 if (rescode > ASTMCD) {
469 printf("illegal ASTresult result code: %d!\n", rescode);
470 return -1;
471 }
472
473 if (vflag >= 3) {
474 printf("Teardown reason:\n%s", ib);
475 switch (rescode) {
476 case 0:
477 printf("Normal Teardown");
478 break;
479 case 1:
480 printf("Loss of Heartbeats");
481 break;
482 case 2:
483 printf("Out of bandwidth");
484 break;
485 case 3:
486 printf("Out of Memory");
487 break;
488 case 4:
489 printf("Application Crash");
490 break;
491 default:
492 printf("Unknown Teardown reason");
493 break;
494 }
495 printf("(%x)\n%s", rescode, ib);
496 }
497 return 0;
498
499 trunc:
500 fputs("[|forces]", stdout);
501 return -1;
502 }
503
504 #define ASRDLN 4
505 #define ASRMCD 3
506 int
507 asrtlv_print(register const u_char * pptr, register u_int len,
508 u_int16_t op_msk _U_, int indent)
509 {
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 if (dlen < 4) { /* at least 32 bits must exist */
558 printf("truncated TLV: %d bytes missing! ", 4 - dlen);
559 return -1;
560 }
561 return 0;
562 }
563
564 #define RD_MIN 8
565 int
566 print_metailv(register const u_char * pptr, register u_int len,
567 u_int16_t op_msk _U_, int indent)
568 {
569 u_int dlen = len - ILV_HDRL;
570 int tll = dlen;
571 char *ib = indent_pr(indent, 0);
572 /* XXX: check header length */
573 struct forces_ilv *ilv = (struct forces_ilv *)pptr;
574
575 TCHECK(*ilv);
576 printf("\n%sMetaID 0x%x length %d\n", ib, EXTRACT_32BITS(&ilv->type),
577 EXTRACT_32BITS(&ilv->length));
578 hex_print_with_offset("\n\t\t\t\t[", ILV_DATA(ilv), tll, 0);
579 return 0;
580
581 trunc:
582 fputs("[|forces]", stdout);
583 return -1;
584 }
585
586 int
587 print_metatlv(register const u_char * pptr, register u_int len,
588 u_int16_t op_msk _U_, int indent)
589 {
590 u_int dlen = len - TLV_HDRL;
591 char *ib = indent_pr(indent, 0);
592 u_int tll = dlen;
593 struct forces_ilv *ilv = (struct forces_ilv *)pptr;
594 int invilv;
595
596 printf("\n%s METADATA\n", ib);
597 while (1) {
598 TCHECK(*ilv);
599 invilv = ilv_valid(ilv, tll);
600 if (invilv)
601 break;
602 print_metailv((u_char *) ilv, tll, 0, indent + 1);
603
604 ilv = GO_NXT_ILV(ilv, tll);
605 }
606
607 return 0;
608
609 trunc:
610 fputs("[|forces]", stdout);
611 return -1;
612 }
613
614 /*
615 */
616 int
617 print_reddata(register const u_char * pptr, register u_int len,
618 u_int16_t op_msk _U_, int indent _U_)
619 {
620 u_int dlen = len - TLV_HDRL;
621 u_int tll = dlen;
622 int invtlv;
623 struct forces_tlv *tlv = (struct forces_tlv *)pptr;
624
625 printf("\n\t\t Redirect DATA\n");
626 if (dlen <= RD_MIN) {
627 printf("\n\t\ttruncated Redirect data: %d bytes missing! ",
628 RD_MIN - dlen);
629 return -1;
630 }
631
632 TCHECK(*tlv);
633 invtlv = tlv_valid(tlv, tll);
634
635 if (invtlv) {
636 printf("Redir data type 0x%x len %d\n", EXTRACT_16BITS(&tlv->type),
637 EXTRACT_16BITS(&tlv->length));
638 return -1;
639 }
640
641 tll -= TLV_HDRL;
642 hex_print_with_offset("\n\t\t\t[", TLV_DATA(tlv), tll, 0);
643 return 0;
644
645 trunc:
646 fputs("[|forces]", stdout);
647 return -1;
648 }
649
650 int
651 redirect_print(register const u_char * pptr, register u_int len,
652 u_int16_t op_msk _U_, int indent)
653 {
654 struct forces_tlv *tlv = (struct forces_tlv *)pptr;
655 u_int dlen = len - TLV_HDRL;
656 u_int tll = dlen;
657 int invtlv;
658
659 if (dlen <= RD_MIN) {
660 printf("\n\t\ttruncated Redirect TLV: %d bytes missing! ",
661 RD_MIN - dlen);
662 return -1;
663 }
664
665 indent += 1;
666 while (1) {
667 TCHECK(*tlv);
668 invtlv = tlv_valid(tlv, tll);
669 if (invtlv)
670 break;
671 if (EXTRACT_16BITS(&tlv->type) == F_TLV_METD) {
672 print_metatlv((u_char *) TLV_DATA(tlv), tll, 0, indent);
673 } else if ((EXTRACT_16BITS(&tlv->type) == F_TLV_REDD)) {
674 print_reddata((u_char *) TLV_DATA(tlv), tll, 0, indent);
675 } else {
676 printf("Unknown REDIRECT TLV 0x%x len %d\n",
677 EXTRACT_16BITS(&tlv->type), EXTRACT_16BITS(&tlv->length));
678 }
679
680 tlv = GO_NXT_TLV(tlv, tll);
681 }
682
683 if (tll) {
684 printf
685 ("\n\t\tMessy Redirect TLV header, type (0x%x)\n\t\texcess of %d Bytes ",
686 EXTRACT_16BITS(&tlv->type), tll - EXTRACT_16BITS(&tlv->length));
687 return -1;
688 }
689
690 return 0;
691
692 trunc:
693 fputs("[|forces]", stdout);
694 return -1;
695 }
696
697 #define OP_OFF 8
698 #define OP_MIN 12
699
700 int
701 lfbselect_print(register const u_char * pptr, register u_int len,
702 u_int16_t op_msk, int indent)
703 {
704 const struct forces_lfbsh *lfbs;
705 struct forces_tlv *otlv;
706 char *ib = indent_pr(indent, 0);
707 u_int dlen = len - TLV_HDRL;
708 u_int tll = dlen - OP_OFF;
709 int invtlv;
710
711 if (dlen <= OP_MIN) { /* id, instance, oper tlv header .. */
712 printf("\n\t\ttruncated lfb selector: %d bytes missing! ",
713 OP_MIN - dlen);
714 return -1;
715 }
716
717 lfbs = (const struct forces_lfbsh *)pptr;
718 TCHECK(*lfbs);
719 if (vflag >= 3) {
720 printf("\n%s%s(Classid %x) instance %x\n",
721 ib, tok2str(ForCES_LFBs, NULL, EXTRACT_32BITS(&lfbs->class)),
722 EXTRACT_32BITS(&lfbs->class),
723 EXTRACT_32BITS(&lfbs->instance));
724 }
725
726 otlv = (struct forces_tlv *)(lfbs + 1);
727
728 indent += 1;
729 while (1) {
730 TCHECK(*otlv);
731 invtlv = tlv_valid(otlv, tll);
732 if (invtlv)
733 break;
734 if (op_valid(EXTRACT_16BITS(&otlv->type), op_msk)) {
735 otlv_print(otlv, 0, indent);
736 } else {
737 if (vflag < 3)
738 printf("\n");
739 printf
740 ("\t\tINValid oper-TLV type 0x%x length %d for this ForCES message\n",
741 EXTRACT_16BITS(&otlv->type), EXTRACT_16BITS(&otlv->length));
742 invoptlv_print((u_char *)otlv, tll, 0, indent);
743 }
744 otlv = GO_NXT_TLV(otlv, tll);
745 }
746
747 if (tll) {
748 printf
749 ("\n\t\tMessy oper TLV header, type (0x%x)\n\t\texcess of %d Bytes ",
750 EXTRACT_16BITS(&otlv->type), tll - EXTRACT_16BITS(&otlv->length));
751 return -1;
752 }
753
754 return 0;
755
756 trunc:
757 fputs("[|forces]", stdout);
758 return -1;
759 }
760
761 int
762 forces_type_print(register const u_char * pptr, const struct forcesh *fhdr _U_,
763 register u_int mlen, struct tom_h *tops)
764 {
765 struct forces_tlv *tltlv;
766 u_int tll;
767 int invtlv;
768 int rc = 0;
769 int ttlv = 0;
770
771 tll = mlen - sizeof(struct forcesh);
772
773 if (tll > TLV_HLN) {
774 if (tops->flags & ZERO_TTLV) {
775 printf("<0x%x>Illegal Top level TLV!\n", tops->flags);
776 return -1;
777 }
778 } else {
779 if (tops->flags & ZERO_MORE_TTLV)
780 return 0;
781 if (tops->flags & ONE_MORE_TTLV) {
782 printf("\tTop level TLV Data missing!\n");
783 return -1;
784 }
785 }
786
787 if (tops->flags & ZERO_TTLV) {
788 return 0;
789 }
790
791 ttlv = tops->flags >> 4;
792 tltlv = GET_TOP_TLV(pptr);
793
794 /*XXX: 15 top level tlvs will probably be fine
795 You are nuts if you send more ;-> */
796 while (1) {
797 TCHECK(*tltlv);
798 invtlv = tlv_valid(tltlv, tll);
799 if (invtlv)
800 break;
801 if (!ttlv_valid(EXTRACT_16BITS(&tltlv->type))) {
802 printf("\n\tInvalid ForCES Top TLV type=0x%x",
803 EXTRACT_16BITS(&tltlv->type));
804 return -1;
805 }
806
807 if (vflag >= 3)
808 printf("\t%s, length %d (data length %d Bytes)",
809 tok2str(ForCES_TLV, NULL, EXTRACT_16BITS(&tltlv->type)),
810 EXTRACT_16BITS(&tltlv->length), EXTRACT_16BITS(&tltlv->length) - 4);
811
812 rc = tops->print((u_char *) TLV_DATA(tltlv),
813 EXTRACT_16BITS(&tltlv->length), tops->op_msk, 9);
814 if (rc < 0) {
815 return -1;
816 }
817 tltlv = GO_NXT_TLV(tltlv, tll);
818 ttlv--;
819 if (ttlv <= 0)
820 break;
821 }
822 if (tll) {
823 printf("\tMess TopTLV header: min %lu, total %d advertised %d ",
824 (unsigned long)sizeof(struct forces_tlv),
825 tll, EXTRACT_16BITS(&tltlv->length));
826 return -1;
827 }
828
829 return 0;
830
831 trunc:
832 fputs("[|forces]", stdout);
833 return -1;
834 }
835
836 void forces_print(register const u_char * pptr, register u_int len)
837 {
838 const struct forcesh *fhdr;
839 u_int mlen;
840 u_int32_t flg_raw;
841 struct tom_h *tops;
842 int rc = 0;
843
844 fhdr = (const struct forcesh *)pptr;
845 TCHECK(*fhdr);
846 if (!tom_valid(fhdr->fm_tom)) {
847 printf("Invalid ForCES message type %d\n", fhdr->fm_tom);
848 goto error;
849 }
850
851 mlen = ForCES_BLN(fhdr);
852
853 tops = get_forces_tom(fhdr->fm_tom);
854 if (tops->v == TOM_RSVD) {
855 printf("\n\tUnknown ForCES message type=0x%x", fhdr->fm_tom);
856 goto error;
857 }
858
859 printf("\n\tForCES %s ", tops->s);
860 if (!ForCES_HLN_VALID(mlen, len)) {
861 printf
862 ("Illegal ForCES pkt len - min %lu, total recvd %d, advertised %d ",
863 (unsigned long)sizeof(struct forcesh), len, ForCES_BLN(fhdr));
864 goto error;
865 }
866
867 TCHECK2(*(pptr + 20), 4);
868 flg_raw = EXTRACT_32BITS(pptr + 20);
869 if (vflag >= 1) {
870 printf("\n\tForCES Version %d len %uB flags 0x%08x ",
871 ForCES_V(fhdr), mlen, flg_raw);
872 printf("\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIu64,
873 ForCES_SID(fhdr), ForCES_node(ForCES_SID(fhdr)),
874 ForCES_DID(fhdr), ForCES_node(ForCES_DID(fhdr)),
875 EXTRACT_64BITS(fhdr->fm_cor));
876
877 }
878 if (vflag >= 2) {
879 printf
880 ("\n\tForCES flags:\n\t %s(0x%x), prio=%d, %s(0x%x),\n\t %s(0x%x), %s(0x%x)\n",
881 ForCES_ACKp(ForCES_ACK(fhdr)), ForCES_ACK(fhdr),
882 ForCES_PRI(fhdr),
883 ForCES_EMp(ForCES_EM(fhdr)), ForCES_EM(fhdr),
884 ForCES_ATp(ForCES_AT(fhdr)), ForCES_AT(fhdr),
885 ForCES_TPp(ForCES_TP(fhdr)), ForCES_TP(fhdr));
886 printf
887 ("\t Extra flags: rsv(b5-7) 0x%x rsv(b13-31) 0x%x\n",
888 ForCES_RS1(fhdr), ForCES_RS2(fhdr));
889 }
890 rc = forces_type_print(pptr, fhdr, mlen, tops);
891 if (rc < 0) {
892 error:
893 hex_print_with_offset("\n\t[", pptr, len, 0);
894 printf("\n\t]");
895 return;
896 }
897
898 if (vflag >= 4) {
899 printf("\n\t Raw ForCES message\n\t [");
900 hex_print_with_offset("\n\t ", pptr, len, 0);
901 printf("\n\t ]");
902 }
903 printf("\n");
904 return;
905
906 trunc:
907 fputs("[|forces]", stdout);
908 }