1214456Srpaulo/* 2214456Srpaulo * Redistribution and use in source and binary forms, with or without 3214456Srpaulo * modification, are permitted provided that: (1) source code 4214456Srpaulo * distributions retain the above copyright notice and this paragraph 5214456Srpaulo * in its entirety, and (2) distributions including binary code include 6214456Srpaulo * the above copyright notice and this paragraph in its entirety in 7214456Srpaulo * the documentation or other materials provided with the distribution. 8214456Srpaulo * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 9214456Srpaulo * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 10214456Srpaulo * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 11214456Srpaulo * FOR A PARTICULAR PURPOSE. 12214456Srpaulo * 13214456Srpaulo * Copyright (c) 2009 Mojatatu Networks, Inc 14214456Srpaulo * 15214456Srpaulo */ 16214456Srpaulo 17214456Srpaulo#ifdef HAVE_CONFIG_H 18214456Srpaulo#include "config.h" 19214456Srpaulo#endif 20214456Srpaulo 21214456Srpaulo#include <tcpdump-stdinc.h> 22214456Srpaulo 23214456Srpaulo#include <stdio.h> 24214456Srpaulo#include <stdlib.h> 25214456Srpaulo 26214456Srpaulo#include "interface.h" 27214456Srpaulo#include "extract.h" 28214456Srpaulo 29214456Srpaulo#include "forces.h" 30214456Srpaulo 31214456Srpaulo#define RESLEN 4 32214456Srpaulo 33214456Srpauloint 34214456Srpauloprestlv_print(register const u_char * pptr, register u_int len, 35214456Srpaulo u_int16_t op_msk _U_, int indent) 36214456Srpaulo{ 37214456Srpaulo const struct forces_tlv *tlv = (struct forces_tlv *)pptr; 38214456Srpaulo register const u_char *tdp = (u_char *) TLV_DATA(tlv); 39214456Srpaulo struct res_val *r = (struct res_val *)tdp; 40214456Srpaulo u_int dlen; 41214456Srpaulo 42214456Srpaulo /* 43214456Srpaulo * pdatacnt_print() has ensured that len (the TLV length) 44214456Srpaulo * >= TLV_HDRL. 45214456Srpaulo */ 46214456Srpaulo dlen = len - TLV_HDRL; 47214456Srpaulo if (dlen != RESLEN) { 48214456Srpaulo printf("illegal RESULT-TLV: %d bytes!\n", dlen); 49214456Srpaulo return -1; 50214456Srpaulo } 51214456Srpaulo 52214456Srpaulo TCHECK(*r); 53214456Srpaulo if (r->result >= 0x18 && r->result <= 0xFE) { 54214456Srpaulo printf("illegal reserved result code: 0x%x!\n", r->result); 55214456Srpaulo return -1; 56214456Srpaulo } 57214456Srpaulo 58214456Srpaulo if (vflag >= 3) { 59214456Srpaulo char *ib = indent_pr(indent, 0); 60214456Srpaulo printf("%s Result: %s (code 0x%x)\n", ib, 61214456Srpaulo tok2str(ForCES_errs, NULL, r->result), r->result); 62214456Srpaulo } 63214456Srpaulo return 0; 64214456Srpaulo 65214456Srpaulotrunc: 66214456Srpaulo fputs("[|forces]", stdout); 67214456Srpaulo return -1; 68214456Srpaulo} 69214456Srpaulo 70214456Srpauloint 71214456Srpaulofdatatlv_print(register const u_char * pptr, register u_int len, 72214456Srpaulo u_int16_t op_msk _U_, int indent) 73214456Srpaulo{ 74214456Srpaulo const struct forces_tlv *tlv = (struct forces_tlv *)pptr; 75214456Srpaulo u_int rlen; 76214456Srpaulo register const u_char *tdp = (u_char *) TLV_DATA(tlv); 77214456Srpaulo u_int16_t type; 78214456Srpaulo 79214456Srpaulo /* 80214456Srpaulo * pdatacnt_print() or pkeyitlv_print() has ensured that len 81214456Srpaulo * (the TLV length) >= TLV_HDRL. 82214456Srpaulo */ 83214456Srpaulo rlen = len - TLV_HDRL; 84214456Srpaulo TCHECK(*tlv); 85214456Srpaulo type = EXTRACT_16BITS(&tlv->type); 86214456Srpaulo if (type != F_TLV_FULD) { 87214456Srpaulo printf("Error: expecting FULLDATA!\n"); 88214456Srpaulo return -1; 89214456Srpaulo } 90214456Srpaulo 91214456Srpaulo if (vflag >= 3) { 92214456Srpaulo char *ib = indent_pr(indent + 2, 1); 93214456Srpaulo printf("%s[", &ib[1]); 94214456Srpaulo hex_print_with_offset(ib, tdp, rlen, 0); 95214456Srpaulo printf("\n%s]\n", &ib[1]); 96214456Srpaulo } 97214456Srpaulo return 0; 98214456Srpaulo 99214456Srpaulotrunc: 100214456Srpaulo fputs("[|forces]", stdout); 101214456Srpaulo return -1; 102214456Srpaulo} 103214456Srpaulo 104214456Srpauloint 105214456Srpaulosdatailv_print(register const u_char * pptr, register u_int len, 106214456Srpaulo u_int16_t op_msk _U_, int indent) 107214456Srpaulo{ 108214456Srpaulo u_int rlen; 109214456Srpaulo const struct forces_ilv *ilv = (struct forces_ilv *)pptr; 110214456Srpaulo int invilv; 111214456Srpaulo 112214456Srpaulo if (len < ILV_HDRL) { 113214456Srpaulo printf("Error: BAD SPARSEDATA-TLV!\n"); 114214456Srpaulo return -1; 115214456Srpaulo } 116241235Sdelphij rlen = len; 117214456Srpaulo indent += 1; 118214456Srpaulo while (rlen != 0) { 119241235Sdelphij char *ib = indent_pr(indent, 1); 120241235Sdelphij register const u_char *tdp = (u_char *) ILV_DATA(ilv); 121214456Srpaulo TCHECK(*ilv); 122214456Srpaulo invilv = ilv_valid(ilv, rlen); 123214456Srpaulo if (invilv) { 124214456Srpaulo printf("%s[", &ib[1]); 125214456Srpaulo hex_print_with_offset(ib, tdp, rlen, 0); 126214456Srpaulo printf("\n%s]\n", &ib[1]); 127241235Sdelphij return -1; 128214456Srpaulo } 129241235Sdelphij if (vflag >= 3) { 130241235Sdelphij int ilvl = EXTRACT_32BITS(&ilv->length); 131241235Sdelphij printf("\n%s ILV: type %x length %d\n", &ib[1], 132241235Sdelphij EXTRACT_32BITS(&ilv->type), ilvl); 133241235Sdelphij hex_print_with_offset("\t\t[", tdp, ilvl-ILV_HDRL, 0); 134241235Sdelphij } 135214456Srpaulo 136214456Srpaulo ilv = GO_NXT_ILV(ilv, rlen); 137214456Srpaulo } 138214456Srpaulo 139214456Srpaulo return 0; 140214456Srpaulo 141214456Srpaulotrunc: 142214456Srpaulo fputs("[|forces]", stdout); 143214456Srpaulo return -1; 144214456Srpaulo} 145214456Srpaulo 146214456Srpauloint 147214456Srpaulosdatatlv_print(register const u_char * pptr, register u_int len, 148214456Srpaulo u_int16_t op_msk, int indent) 149214456Srpaulo{ 150214456Srpaulo const struct forces_tlv *tlv = (struct forces_tlv *)pptr; 151214456Srpaulo u_int rlen; 152214456Srpaulo register const u_char *tdp = (u_char *) TLV_DATA(tlv); 153214456Srpaulo u_int16_t type; 154214456Srpaulo 155214456Srpaulo /* 156214456Srpaulo * pdatacnt_print() has ensured that len (the TLV length) 157214456Srpaulo * >= TLV_HDRL. 158214456Srpaulo */ 159214456Srpaulo rlen = len - TLV_HDRL; 160214456Srpaulo TCHECK(*tlv); 161214456Srpaulo type = EXTRACT_16BITS(&tlv->type); 162214456Srpaulo if (type != F_TLV_SPAD) { 163214456Srpaulo printf("Error: expecting SPARSEDATA!\n"); 164214456Srpaulo return -1; 165214456Srpaulo } 166214456Srpaulo 167214456Srpaulo return sdatailv_print(tdp, rlen, op_msk, indent); 168214456Srpaulo 169214456Srpaulotrunc: 170214456Srpaulo fputs("[|forces]", stdout); 171214456Srpaulo return -1; 172214456Srpaulo} 173214456Srpaulo 174214456Srpauloint 175214456Srpaulopkeyitlv_print(register const u_char * pptr, register u_int len, 176214456Srpaulo u_int16_t op_msk, int indent) 177214456Srpaulo{ 178214456Srpaulo const struct forces_tlv *tlv = (struct forces_tlv *)pptr; 179214456Srpaulo register const u_char *tdp = (u_char *) TLV_DATA(tlv); 180214456Srpaulo register const u_char *dp = tdp + 4; 181214456Srpaulo const struct forces_tlv *kdtlv = (struct forces_tlv *)dp; 182214456Srpaulo u_int32_t id; 183214456Srpaulo char *ib = indent_pr(indent, 0); 184214456Srpaulo u_int16_t type, tll; 185214456Srpaulo int invtlv; 186214456Srpaulo 187214456Srpaulo TCHECK(*tdp); 188214456Srpaulo id = EXTRACT_32BITS(tdp); 189214456Srpaulo printf("%sKeyinfo: Key 0x%x\n", ib, id); 190214456Srpaulo TCHECK(*kdtlv); 191214456Srpaulo type = EXTRACT_16BITS(&kdtlv->type); 192214456Srpaulo invtlv = tlv_valid(kdtlv, len); 193214456Srpaulo 194214456Srpaulo if (invtlv) { 195214456Srpaulo printf("%s TLV type 0x%x len %d\n", 196214456Srpaulo tok2str(ForCES_TLV_err, NULL, invtlv), type, 197214456Srpaulo EXTRACT_16BITS(&kdtlv->length)); 198214456Srpaulo return -1; 199214456Srpaulo } 200214456Srpaulo /* 201214456Srpaulo * At this point, tlv_valid() has ensured that the TLV 202214456Srpaulo * length is large enough but not too large (it doesn't 203214456Srpaulo * go past the end of the containing TLV). 204214456Srpaulo */ 205214456Srpaulo tll = EXTRACT_16BITS(&kdtlv->length); 206214456Srpaulo dp = (u_char *) TLV_DATA(kdtlv); 207214456Srpaulo return fdatatlv_print(dp, tll, op_msk, indent); 208214456Srpaulo 209214456Srpaulotrunc: 210214456Srpaulo fputs("[|forces]", stdout); 211214456Srpaulo return -1; 212214456Srpaulo} 213214456Srpaulo 214214456Srpauloint 215214456Srpaulopdatacnt_print(register const u_char * pptr, register u_int len, 216235530Sdelphij u_int16_t IDcnt, u_int16_t op_msk, int indent) 217214456Srpaulo{ 218214456Srpaulo u_int i; 219214456Srpaulo u_int32_t id; 220214456Srpaulo char *ib = indent_pr(indent, 0); 221214456Srpaulo 222214456Srpaulo for (i = 0; i < IDcnt; i++) { 223214456Srpaulo TCHECK2(*pptr, 4); 224214456Srpaulo if (len < 4) 225214456Srpaulo goto trunc; 226214456Srpaulo id = EXTRACT_32BITS(pptr); 227214456Srpaulo if (vflag >= 3) 228214456Srpaulo printf("%s ID#%02u: %d\n", ib, i + 1, id); 229214456Srpaulo len -= 4; 230214456Srpaulo pptr += 4; 231214456Srpaulo } 232214456Srpaulo if (len) { 233214456Srpaulo const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; 234214456Srpaulo u_int16_t type; 235214456Srpaulo u_int16_t tll; 236214456Srpaulo int pad = 0; 237214456Srpaulo u_int aln; 238214456Srpaulo int invtlv; 239214456Srpaulo 240214456Srpaulo TCHECK(*pdtlv); 241214456Srpaulo type = EXTRACT_16BITS(&pdtlv->type); 242214456Srpaulo invtlv = tlv_valid(pdtlv, len); 243214456Srpaulo if (invtlv) { 244214456Srpaulo printf 245214456Srpaulo ("%s Outstanding bytes %d for TLV type 0x%x TLV len %d\n", 246214456Srpaulo tok2str(ForCES_TLV_err, NULL, invtlv), len, type, 247214456Srpaulo EXTRACT_16BITS(&pdtlv->length)); 248214456Srpaulo goto pd_err; 249214456Srpaulo } 250214456Srpaulo /* 251214456Srpaulo * At this point, tlv_valid() has ensured that the TLV 252214456Srpaulo * length is large enough but not too large (it doesn't 253214456Srpaulo * go past the end of the containing TLV). 254214456Srpaulo */ 255214456Srpaulo tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; 256214456Srpaulo aln = F_ALN_LEN(EXTRACT_16BITS(&pdtlv->length)); 257214456Srpaulo if (aln > EXTRACT_16BITS(&pdtlv->length)) { 258214456Srpaulo if (aln > len) { 259214456Srpaulo printf 260214456Srpaulo ("Invalid padded pathdata TLV type 0x%x len %d missing %d pad bytes\n", 261214456Srpaulo type, EXTRACT_16BITS(&pdtlv->length), aln - len); 262214456Srpaulo } else { 263214456Srpaulo pad = aln - EXTRACT_16BITS(&pdtlv->length); 264214456Srpaulo } 265214456Srpaulo } 266214456Srpaulo if (pd_valid(type)) { 267214456Srpaulo const struct pdata_ops *ops = get_forces_pd(type); 268214456Srpaulo 269214456Srpaulo if (vflag >= 3 && ops->v != F_TLV_PDAT) { 270214456Srpaulo if (pad) 271214456Srpaulo printf 272235530Sdelphij ("%s %s (Length %d DataLen %d pad %d Bytes)\n", 273214456Srpaulo ib, ops->s, EXTRACT_16BITS(&pdtlv->length), 274214456Srpaulo tll, pad); 275214456Srpaulo else 276214456Srpaulo printf 277214456Srpaulo ("%s %s (Length %d DataLen %d Bytes)\n", 278214456Srpaulo ib, ops->s, EXTRACT_16BITS(&pdtlv->length), 279214456Srpaulo tll); 280214456Srpaulo } 281214456Srpaulo 282214456Srpaulo chk_op_type(type, op_msk, ops->op_msk); 283214456Srpaulo 284241235Sdelphij if (ops->print((const u_char *)pdtlv, 285214456Srpaulo tll + pad + TLV_HDRL, op_msk, 286241235Sdelphij indent + 2) == -1) 287241235Sdelphij return -1; 288235530Sdelphij len -= (TLV_HDRL + pad + tll); 289214456Srpaulo } else { 290214456Srpaulo printf("Invalid path data content type 0x%x len %d\n", 291214456Srpaulo type, EXTRACT_16BITS(&pdtlv->length)); 292214456Srpaulopd_err: 293214456Srpaulo if (EXTRACT_16BITS(&pdtlv->length)) { 294214456Srpaulo hex_print_with_offset("Bad Data val\n\t [", 295214456Srpaulo pptr, len, 0); 296214456Srpaulo printf("]\n"); 297214456Srpaulo 298214456Srpaulo return -1; 299214456Srpaulo } 300214456Srpaulo } 301214456Srpaulo } 302235530Sdelphij return len; 303214456Srpaulo 304214456Srpaulotrunc: 305214456Srpaulo fputs("[|forces]", stdout); 306214456Srpaulo return -1; 307214456Srpaulo} 308214456Srpaulo 309214456Srpauloint 310214456Srpaulopdata_print(register const u_char * pptr, register u_int len, 311214456Srpaulo u_int16_t op_msk, int indent) 312214456Srpaulo{ 313214456Srpaulo const struct pathdata_h *pdh = (struct pathdata_h *)pptr; 314214456Srpaulo char *ib = indent_pr(indent, 0); 315214456Srpaulo u_int minsize = 0; 316235530Sdelphij int more_pd = 0; 317235530Sdelphij u_int16_t idcnt = 0; 318214456Srpaulo 319214456Srpaulo TCHECK(*pdh); 320214456Srpaulo if (len < sizeof(struct pathdata_h)) 321214456Srpaulo goto trunc; 322214456Srpaulo if (vflag >= 3) { 323214456Srpaulo printf("\n%sPathdata: Flags 0x%x ID count %d\n", 324214456Srpaulo ib, EXTRACT_16BITS(&pdh->pflags), EXTRACT_16BITS(&pdh->pIDcnt)); 325214456Srpaulo } 326214456Srpaulo 327214456Srpaulo if (EXTRACT_16BITS(&pdh->pflags) & F_SELKEY) { 328214456Srpaulo op_msk |= B_KEYIN; 329214456Srpaulo } 330214456Srpaulo pptr += sizeof(struct pathdata_h); 331214456Srpaulo len -= sizeof(struct pathdata_h); 332235530Sdelphij idcnt = EXTRACT_16BITS(&pdh->pIDcnt); 333235530Sdelphij minsize = idcnt * 4; 334214456Srpaulo if (len < minsize) { 335214456Srpaulo printf("\t\t\ttruncated IDs expected %uB got %uB\n", minsize, 336214456Srpaulo len); 337214456Srpaulo hex_print_with_offset("\t\t\tID Data[", pptr, len, 0); 338214456Srpaulo printf("]\n"); 339214456Srpaulo return -1; 340214456Srpaulo } 341235530Sdelphij more_pd = pdatacnt_print(pptr, len, idcnt, op_msk, indent); 342235530Sdelphij if (more_pd > 0) { 343235530Sdelphij int consumed = len - more_pd; 344235530Sdelphij pptr += consumed; 345235530Sdelphij len = more_pd; 346235530Sdelphij /* XXX: Argh, recurse some more */ 347235530Sdelphij return recpdoptlv_print(pptr, len, op_msk, indent+1); 348235530Sdelphij } else 349235530Sdelphij return 0; 350214456Srpaulo 351214456Srpaulotrunc: 352214456Srpaulo fputs("[|forces]", stdout); 353214456Srpaulo return -1; 354214456Srpaulo} 355214456Srpaulo 356214456Srpauloint 357214456Srpaulogenoptlv_print(register const u_char * pptr, register u_int len, 358214456Srpaulo u_int16_t op_msk, int indent) 359214456Srpaulo{ 360214456Srpaulo const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; 361214456Srpaulo u_int16_t type; 362214456Srpaulo int tll; 363214456Srpaulo int invtlv; 364214456Srpaulo char *ib = indent_pr(indent, 0); 365214456Srpaulo 366214456Srpaulo TCHECK(*pdtlv); 367214456Srpaulo type = EXTRACT_16BITS(&pdtlv->type); 368214456Srpaulo tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; 369214456Srpaulo invtlv = tlv_valid(pdtlv, len); 370214456Srpaulo printf("genoptlvprint - %s TLV type 0x%x len %d\n", 371214456Srpaulo tok2str(ForCES_TLV, NULL, type), type, EXTRACT_16BITS(&pdtlv->length)); 372214456Srpaulo if (!invtlv) { 373214456Srpaulo /* 374214456Srpaulo * At this point, tlv_valid() has ensured that the TLV 375214456Srpaulo * length is large enough but not too large (it doesn't 376214456Srpaulo * go past the end of the containing TLV). 377214456Srpaulo */ 378214456Srpaulo register const u_char *dp = (u_char *) TLV_DATA(pdtlv); 379214456Srpaulo if (!ttlv_valid(type)) { 380214456Srpaulo printf("%s TLV type 0x%x len %d\n", 381214456Srpaulo tok2str(ForCES_TLV_err, NULL, invtlv), type, 382214456Srpaulo EXTRACT_16BITS(&pdtlv->length)); 383214456Srpaulo return -1; 384214456Srpaulo } 385214456Srpaulo if (vflag >= 3) 386214456Srpaulo printf("%s%s, length %d (data length %d Bytes)", 387214456Srpaulo ib, tok2str(ForCES_TLV, NULL, type), 388214456Srpaulo EXTRACT_16BITS(&pdtlv->length), tll); 389214456Srpaulo 390214456Srpaulo return pdata_print(dp, tll, op_msk, indent + 1); 391214456Srpaulo } else { 392214456Srpaulo printf("\t\t\tInvalid ForCES TLV type=%x", type); 393214456Srpaulo return -1; 394214456Srpaulo } 395214456Srpaulo 396214456Srpaulotrunc: 397214456Srpaulo fputs("[|forces]", stdout); 398214456Srpaulo return -1; 399214456Srpaulo} 400214456Srpaulo 401214456Srpauloint 402214456Srpaulorecpdoptlv_print(register const u_char * pptr, register u_int len, 403214456Srpaulo u_int16_t op_msk, int indent) 404214456Srpaulo{ 405214456Srpaulo const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; 406214456Srpaulo int tll; 407214456Srpaulo int invtlv; 408214456Srpaulo u_int16_t type; 409214456Srpaulo register const u_char *dp; 410214456Srpaulo char *ib; 411214456Srpaulo 412214456Srpaulo while (len != 0) { 413214456Srpaulo TCHECK(*pdtlv); 414214456Srpaulo invtlv = tlv_valid(pdtlv, len); 415214456Srpaulo if (invtlv) { 416214456Srpaulo break; 417214456Srpaulo } 418214456Srpaulo 419214456Srpaulo /* 420214456Srpaulo * At this point, tlv_valid() has ensured that the TLV 421214456Srpaulo * length is large enough but not too large (it doesn't 422214456Srpaulo * go past the end of the containing TLV). 423214456Srpaulo */ 424214456Srpaulo ib = indent_pr(indent, 0); 425214456Srpaulo type = EXTRACT_16BITS(&pdtlv->type); 426214456Srpaulo dp = (u_char *) TLV_DATA(pdtlv); 427214456Srpaulo tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; 428214456Srpaulo 429214456Srpaulo if (vflag >= 3) 430214456Srpaulo printf 431214456Srpaulo ("%s%s, length %d (data encapsulated %d Bytes)", 432214456Srpaulo ib, tok2str(ForCES_TLV, NULL, type), 433214456Srpaulo EXTRACT_16BITS(&pdtlv->length), 434214456Srpaulo EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL); 435214456Srpaulo 436241235Sdelphij if (pdata_print(dp, tll, op_msk, indent + 1) == -1) 437241235Sdelphij return -1; 438214456Srpaulo pdtlv = GO_NXT_TLV(pdtlv, len); 439214456Srpaulo } 440214456Srpaulo 441214456Srpaulo if (len) { 442214456Srpaulo printf 443214456Srpaulo ("\n\t\tMessy PATHDATA TLV header, type (0x%x)\n\t\texcess of %d Bytes ", 444214456Srpaulo EXTRACT_16BITS(&pdtlv->type), len - EXTRACT_16BITS(&pdtlv->length)); 445214456Srpaulo return -1; 446214456Srpaulo } 447214456Srpaulo 448214456Srpaulo return 0; 449214456Srpaulo 450214456Srpaulotrunc: 451214456Srpaulo fputs("[|forces]", stdout); 452214456Srpaulo return -1; 453214456Srpaulo} 454214456Srpaulo 455214456Srpauloint 456214456Srpauloinvoptlv_print(register const u_char * pptr, register u_int len, 457214456Srpaulo u_int16_t op_msk _U_, int indent) 458214456Srpaulo{ 459214456Srpaulo char *ib = indent_pr(indent, 1); 460214456Srpaulo 461214456Srpaulo if (vflag >= 3) { 462214456Srpaulo printf("%sData[", &ib[1]); 463214456Srpaulo hex_print_with_offset(ib, pptr, len, 0); 464214456Srpaulo printf("%s]\n", ib); 465214456Srpaulo } 466214456Srpaulo return -1; 467214456Srpaulo} 468214456Srpaulo 469214456Srpauloint otlv_print(const struct forces_tlv *otlv, u_int16_t op_msk _U_, int indent) 470214456Srpaulo{ 471214456Srpaulo int rc = 0; 472214456Srpaulo register const u_char *dp = (u_char *) TLV_DATA(otlv); 473214456Srpaulo u_int16_t type; 474214456Srpaulo int tll; 475214456Srpaulo char *ib = indent_pr(indent, 0); 476214456Srpaulo const struct optlv_h *ops; 477214456Srpaulo 478214456Srpaulo /* 479214456Srpaulo * lfbselect_print() has ensured that EXTRACT_16BITS(&otlv->length) 480214456Srpaulo * >= TLV_HDRL. 481214456Srpaulo */ 482214456Srpaulo TCHECK(*otlv); 483214456Srpaulo type = EXTRACT_16BITS(&otlv->type); 484214456Srpaulo tll = EXTRACT_16BITS(&otlv->length) - TLV_HDRL; 485214456Srpaulo ops = get_forces_optlv_h(type); 486214456Srpaulo if (vflag >= 3) { 487214456Srpaulo printf("%sOper TLV %s(0x%x) length %d\n", ib, ops->s, type, 488214456Srpaulo EXTRACT_16BITS(&otlv->length)); 489214456Srpaulo } 490214456Srpaulo /* empty TLVs like COMMIT and TRCOMMIT are empty, we stop here .. */ 491214456Srpaulo if (!ops->flags & ZERO_TTLV) { 492214456Srpaulo if (tll != 0) /* instead of "if (tll)" - for readability .. */ 493214456Srpaulo printf("%s: Illegal - MUST be empty\n", ops->s); 494214456Srpaulo return rc; 495214456Srpaulo } 496214456Srpaulo /* rest of ops must at least have 12B {pathinfo} */ 497214456Srpaulo if (tll < OP_MIN_SIZ) { 498214456Srpaulo printf("\t\tOper TLV %s(0x%x) length %d\n", ops->s, type, 499214456Srpaulo EXTRACT_16BITS(&otlv->length)); 500214456Srpaulo printf("\t\tTruncated data size %d minimum required %d\n", tll, 501214456Srpaulo OP_MIN_SIZ); 502214456Srpaulo return invoptlv_print(dp, tll, ops->op_msk, indent); 503214456Srpaulo 504214456Srpaulo } 505214456Srpaulo 506214456Srpaulo rc = ops->print(dp, tll, ops->op_msk, indent + 1); 507214456Srpaulo return rc; 508214456Srpaulo 509214456Srpaulotrunc: 510214456Srpaulo fputs("[|forces]", stdout); 511214456Srpaulo return -1; 512214456Srpaulo} 513214456Srpaulo 514214456Srpaulo#define ASTDLN 4 515214456Srpaulo#define ASTMCD 255 516214456Srpauloint 517214456Srpauloasttlv_print(register const u_char * pptr, register u_int len, 518214456Srpaulo u_int16_t op_msk _U_, int indent) 519214456Srpaulo{ 520214456Srpaulo u_int32_t rescode; 521214456Srpaulo u_int dlen; 522214456Srpaulo char *ib = indent_pr(indent, 0); 523214456Srpaulo 524214456Srpaulo /* 525214456Srpaulo * forces_type_print() has ensured that len (the TLV length) 526214456Srpaulo * >= TLV_HDRL. 527214456Srpaulo */ 528214456Srpaulo dlen = len - TLV_HDRL; 529214456Srpaulo if (dlen != ASTDLN) { 530214456Srpaulo printf("illegal ASTresult-TLV: %d bytes!\n", dlen); 531214456Srpaulo return -1; 532214456Srpaulo } 533214456Srpaulo TCHECK2(*pptr, 4); 534214456Srpaulo rescode = EXTRACT_32BITS(pptr); 535214456Srpaulo if (rescode > ASTMCD) { 536214456Srpaulo printf("illegal ASTresult result code: %d!\n", rescode); 537214456Srpaulo return -1; 538214456Srpaulo } 539214456Srpaulo 540214456Srpaulo if (vflag >= 3) { 541214456Srpaulo printf("Teardown reason:\n%s", ib); 542214456Srpaulo switch (rescode) { 543214456Srpaulo case 0: 544214456Srpaulo printf("Normal Teardown"); 545214456Srpaulo break; 546214456Srpaulo case 1: 547214456Srpaulo printf("Loss of Heartbeats"); 548214456Srpaulo break; 549214456Srpaulo case 2: 550214456Srpaulo printf("Out of bandwidth"); 551214456Srpaulo break; 552214456Srpaulo case 3: 553214456Srpaulo printf("Out of Memory"); 554214456Srpaulo break; 555214456Srpaulo case 4: 556214456Srpaulo printf("Application Crash"); 557214456Srpaulo break; 558214456Srpaulo default: 559214456Srpaulo printf("Unknown Teardown reason"); 560214456Srpaulo break; 561214456Srpaulo } 562214456Srpaulo printf("(%x)\n%s", rescode, ib); 563214456Srpaulo } 564214456Srpaulo return 0; 565214456Srpaulo 566214456Srpaulotrunc: 567214456Srpaulo fputs("[|forces]", stdout); 568214456Srpaulo return -1; 569214456Srpaulo} 570214456Srpaulo 571214456Srpaulo#define ASRDLN 4 572214456Srpaulo#define ASRMCD 3 573214456Srpauloint 574214456Srpauloasrtlv_print(register const u_char * pptr, register u_int len, 575214456Srpaulo u_int16_t op_msk _U_, int indent) 576214456Srpaulo{ 577214456Srpaulo u_int32_t rescode; 578214456Srpaulo u_int dlen; 579214456Srpaulo char *ib = indent_pr(indent, 0); 580214456Srpaulo 581214456Srpaulo /* 582214456Srpaulo * forces_type_print() has ensured that len (the TLV length) 583214456Srpaulo * >= TLV_HDRL. 584214456Srpaulo */ 585214456Srpaulo dlen = len - TLV_HDRL; 586214456Srpaulo if (dlen != ASRDLN) { /* id, instance, oper tlv */ 587214456Srpaulo printf("illegal ASRresult-TLV: %d bytes!\n", dlen); 588214456Srpaulo return -1; 589214456Srpaulo } 590214456Srpaulo TCHECK2(*pptr, 4); 591214456Srpaulo rescode = EXTRACT_32BITS(pptr); 592214456Srpaulo 593214456Srpaulo if (rescode > ASRMCD) { 594214456Srpaulo printf("illegal ASRresult result code: %d!\n", rescode); 595214456Srpaulo return -1; 596214456Srpaulo } 597214456Srpaulo 598214456Srpaulo if (vflag >= 3) { 599214456Srpaulo printf("\n%s", ib); 600214456Srpaulo switch (rescode) { 601214456Srpaulo case 0: 602214456Srpaulo printf("Success "); 603214456Srpaulo break; 604214456Srpaulo case 1: 605214456Srpaulo printf("FE ID invalid "); 606214456Srpaulo break; 607214456Srpaulo case 2: 608214456Srpaulo printf("permission denied "); 609214456Srpaulo break; 610214456Srpaulo default: 611214456Srpaulo printf("Unknown "); 612214456Srpaulo break; 613214456Srpaulo } 614214456Srpaulo printf("(%x)\n%s", rescode, ib); 615214456Srpaulo } 616214456Srpaulo return 0; 617214456Srpaulo 618214456Srpaulotrunc: 619214456Srpaulo fputs("[|forces]", stdout); 620214456Srpaulo return -1; 621214456Srpaulo} 622214456Srpaulo 623214456Srpaulo/* 624214456Srpaulo * XXX - not used. 625214456Srpaulo */ 626214456Srpauloint 627214456Srpaulogentltlv_print(register const u_char * pptr _U_, register u_int len, 628214456Srpaulo u_int16_t op_msk _U_, int indent _U_) 629214456Srpaulo{ 630214456Srpaulo u_int dlen = len - TLV_HDRL; 631214456Srpaulo 632214456Srpaulo if (dlen < 4) { /* at least 32 bits must exist */ 633214456Srpaulo printf("truncated TLV: %d bytes missing! ", 4 - dlen); 634214456Srpaulo return -1; 635214456Srpaulo } 636214456Srpaulo return 0; 637214456Srpaulo} 638214456Srpaulo 639214456Srpaulo#define RD_MIN 8 640214456Srpauloint 641214456Srpauloprint_metailv(register const u_char * pptr, register u_int len, 642214456Srpaulo u_int16_t op_msk _U_, int indent) 643214456Srpaulo{ 644214456Srpaulo u_int dlen; 645214456Srpaulo u_int rlen; 646214456Srpaulo char *ib = indent_pr(indent, 0); 647214456Srpaulo /* XXX: check header length */ 648214456Srpaulo const struct forces_ilv *ilv = (struct forces_ilv *)pptr; 649214456Srpaulo 650214456Srpaulo /* 651214456Srpaulo * print_metatlv() has ensured that len (what remains in the 652214456Srpaulo * ILV) >= ILV_HDRL. 653214456Srpaulo */ 654214456Srpaulo dlen = len - ILV_HDRL; 655214456Srpaulo rlen = dlen; 656214456Srpaulo TCHECK(*ilv); 657214456Srpaulo printf("\n%sMetaID 0x%x length %d\n", ib, EXTRACT_32BITS(&ilv->type), 658214456Srpaulo EXTRACT_32BITS(&ilv->length)); 659214456Srpaulo hex_print_with_offset("\n\t\t\t\t[", ILV_DATA(ilv), rlen, 0); 660214456Srpaulo return 0; 661214456Srpaulo 662214456Srpaulotrunc: 663214456Srpaulo fputs("[|forces]", stdout); 664214456Srpaulo return -1; 665214456Srpaulo} 666214456Srpaulo 667214456Srpauloint 668214456Srpauloprint_metatlv(register const u_char * pptr, register u_int len, 669214456Srpaulo u_int16_t op_msk _U_, int indent) 670214456Srpaulo{ 671214456Srpaulo u_int dlen; 672214456Srpaulo char *ib = indent_pr(indent, 0); 673214456Srpaulo u_int rlen; 674214456Srpaulo const struct forces_ilv *ilv = (struct forces_ilv *)pptr; 675214456Srpaulo int invilv; 676214456Srpaulo 677214456Srpaulo /* 678214456Srpaulo * redirect_print() has ensured that len (what remains in the 679214456Srpaulo * TLV) >= TLV_HDRL. 680214456Srpaulo */ 681214456Srpaulo dlen = len - TLV_HDRL; 682214456Srpaulo rlen = dlen; 683214456Srpaulo printf("\n%s METADATA\n", ib); 684214456Srpaulo while (rlen != 0) { 685214456Srpaulo TCHECK(*ilv); 686214456Srpaulo invilv = ilv_valid(ilv, rlen); 687214456Srpaulo if (invilv) 688214456Srpaulo break; 689214456Srpaulo 690214456Srpaulo /* 691214456Srpaulo * At this point, ilv_valid() has ensured that the ILV 692214456Srpaulo * length is large enough but not too large (it doesn't 693214456Srpaulo * go past the end of the containing TLV). 694214456Srpaulo */ 695214456Srpaulo print_metailv((u_char *) ilv, rlen, 0, indent + 1); 696214456Srpaulo 697214456Srpaulo ilv = GO_NXT_ILV(ilv, rlen); 698214456Srpaulo } 699214456Srpaulo 700214456Srpaulo return 0; 701214456Srpaulo 702214456Srpaulotrunc: 703214456Srpaulo fputs("[|forces]", stdout); 704214456Srpaulo return -1; 705214456Srpaulo} 706214456Srpaulo 707214456Srpaulo/* 708214456Srpaulo*/ 709214456Srpauloint 710214456Srpauloprint_reddata(register const u_char * pptr, register u_int len, 711214456Srpaulo u_int16_t op_msk _U_, int indent _U_) 712214456Srpaulo{ 713214456Srpaulo u_int dlen; 714214456Srpaulo u_int rlen; 715214456Srpaulo int invtlv; 716214456Srpaulo const struct forces_tlv *tlv = (struct forces_tlv *)pptr; 717214456Srpaulo 718214456Srpaulo /* 719214456Srpaulo * redirect_print() has ensured that len (what remains in the 720214456Srpaulo * TLV) >= TLV_HDRL. 721214456Srpaulo */ 722214456Srpaulo dlen = len - TLV_HDRL; 723214456Srpaulo printf("\n\t\t Redirect DATA\n"); 724214456Srpaulo if (dlen <= RD_MIN) { 725214456Srpaulo printf("\n\t\ttruncated Redirect data: %d bytes missing! ", 726214456Srpaulo RD_MIN - dlen); 727214456Srpaulo return -1; 728214456Srpaulo } 729214456Srpaulo 730214456Srpaulo rlen = dlen; 731214456Srpaulo TCHECK(*tlv); 732214456Srpaulo invtlv = tlv_valid(tlv, rlen); 733214456Srpaulo 734214456Srpaulo if (invtlv) { 735214456Srpaulo printf("Redir data type 0x%x len %d\n", EXTRACT_16BITS(&tlv->type), 736214456Srpaulo EXTRACT_16BITS(&tlv->length)); 737214456Srpaulo return -1; 738214456Srpaulo } 739214456Srpaulo 740214456Srpaulo /* 741214456Srpaulo * At this point, tlv_valid() has ensured that the TLV 742214456Srpaulo * length is large enough but not too large (it doesn't 743214456Srpaulo * go past the end of the containing TLV). 744214456Srpaulo */ 745214456Srpaulo rlen -= TLV_HDRL; 746214456Srpaulo hex_print_with_offset("\n\t\t\t[", TLV_DATA(tlv), rlen, 0); 747214456Srpaulo return 0; 748214456Srpaulo 749214456Srpaulotrunc: 750214456Srpaulo fputs("[|forces]", stdout); 751214456Srpaulo return -1; 752214456Srpaulo} 753214456Srpaulo 754214456Srpauloint 755214456Srpauloredirect_print(register const u_char * pptr, register u_int len, 756214456Srpaulo u_int16_t op_msk _U_, int indent) 757214456Srpaulo{ 758214456Srpaulo const struct forces_tlv *tlv = (struct forces_tlv *)pptr; 759214456Srpaulo u_int dlen; 760214456Srpaulo u_int rlen; 761214456Srpaulo int invtlv; 762214456Srpaulo 763214456Srpaulo /* 764214456Srpaulo * forces_type_print() has ensured that len (the TLV length) 765214456Srpaulo * >= TLV_HDRL. 766214456Srpaulo */ 767214456Srpaulo dlen = len - TLV_HDRL; 768214456Srpaulo if (dlen <= RD_MIN) { 769214456Srpaulo printf("\n\t\ttruncated Redirect TLV: %d bytes missing! ", 770214456Srpaulo RD_MIN - dlen); 771214456Srpaulo return -1; 772214456Srpaulo } 773214456Srpaulo 774214456Srpaulo rlen = dlen; 775214456Srpaulo indent += 1; 776214456Srpaulo while (rlen != 0) { 777214456Srpaulo TCHECK(*tlv); 778214456Srpaulo invtlv = tlv_valid(tlv, rlen); 779214456Srpaulo if (invtlv) 780214456Srpaulo break; 781214456Srpaulo 782214456Srpaulo /* 783214456Srpaulo * At this point, tlv_valid() has ensured that the TLV 784214456Srpaulo * length is large enough but not too large (it doesn't 785214456Srpaulo * go past the end of the containing TLV). 786214456Srpaulo */ 787214456Srpaulo if (EXTRACT_16BITS(&tlv->type) == F_TLV_METD) { 788214456Srpaulo print_metatlv((u_char *) TLV_DATA(tlv), rlen, 0, indent); 789214456Srpaulo } else if ((EXTRACT_16BITS(&tlv->type) == F_TLV_REDD)) { 790214456Srpaulo print_reddata((u_char *) TLV_DATA(tlv), rlen, 0, indent); 791214456Srpaulo } else { 792214456Srpaulo printf("Unknown REDIRECT TLV 0x%x len %d\n", 793214456Srpaulo EXTRACT_16BITS(&tlv->type), EXTRACT_16BITS(&tlv->length)); 794214456Srpaulo } 795214456Srpaulo 796214456Srpaulo tlv = GO_NXT_TLV(tlv, rlen); 797214456Srpaulo } 798214456Srpaulo 799214456Srpaulo if (rlen) { 800214456Srpaulo printf 801214456Srpaulo ("\n\t\tMessy Redirect TLV header, type (0x%x)\n\t\texcess of %d Bytes ", 802214456Srpaulo EXTRACT_16BITS(&tlv->type), rlen - EXTRACT_16BITS(&tlv->length)); 803214456Srpaulo return -1; 804214456Srpaulo } 805214456Srpaulo 806214456Srpaulo return 0; 807214456Srpaulo 808214456Srpaulotrunc: 809214456Srpaulo fputs("[|forces]", stdout); 810214456Srpaulo return -1; 811214456Srpaulo} 812214456Srpaulo 813214456Srpaulo#define OP_OFF 8 814214456Srpaulo#define OP_MIN 12 815214456Srpaulo 816214456Srpauloint 817214456Srpaulolfbselect_print(register const u_char * pptr, register u_int len, 818214456Srpaulo u_int16_t op_msk, int indent) 819214456Srpaulo{ 820214456Srpaulo const struct forces_lfbsh *lfbs; 821214456Srpaulo const struct forces_tlv *otlv; 822214456Srpaulo char *ib = indent_pr(indent, 0); 823214456Srpaulo u_int dlen; 824214456Srpaulo u_int rlen; 825214456Srpaulo int invtlv; 826214456Srpaulo 827214456Srpaulo /* 828214456Srpaulo * forces_type_print() has ensured that len (the TLV length) 829214456Srpaulo * >= TLV_HDRL. 830214456Srpaulo */ 831214456Srpaulo dlen = len - TLV_HDRL; 832214456Srpaulo if (dlen <= OP_MIN) { /* id, instance, oper tlv header .. */ 833214456Srpaulo printf("\n\t\ttruncated lfb selector: %d bytes missing! ", 834214456Srpaulo OP_MIN - dlen); 835214456Srpaulo return -1; 836214456Srpaulo } 837214456Srpaulo 838214456Srpaulo /* 839214456Srpaulo * At this point, we know that dlen > OP_MIN; OP_OFF < OP_MIN, so 840214456Srpaulo * we also know that it's > OP_OFF. 841214456Srpaulo */ 842214456Srpaulo rlen = dlen - OP_OFF; 843214456Srpaulo 844214456Srpaulo lfbs = (const struct forces_lfbsh *)pptr; 845214456Srpaulo TCHECK(*lfbs); 846214456Srpaulo if (vflag >= 3) { 847214456Srpaulo printf("\n%s%s(Classid %x) instance %x\n", 848214456Srpaulo ib, tok2str(ForCES_LFBs, NULL, EXTRACT_32BITS(&lfbs->class)), 849214456Srpaulo EXTRACT_32BITS(&lfbs->class), 850214456Srpaulo EXTRACT_32BITS(&lfbs->instance)); 851214456Srpaulo } 852214456Srpaulo 853214456Srpaulo otlv = (struct forces_tlv *)(lfbs + 1); 854214456Srpaulo 855214456Srpaulo indent += 1; 856214456Srpaulo while (rlen != 0) { 857214456Srpaulo TCHECK(*otlv); 858214456Srpaulo invtlv = tlv_valid(otlv, rlen); 859214456Srpaulo if (invtlv) 860214456Srpaulo break; 861214456Srpaulo 862214456Srpaulo /* 863214456Srpaulo * At this point, tlv_valid() has ensured that the TLV 864214456Srpaulo * length is large enough but not too large (it doesn't 865214456Srpaulo * go past the end of the containing TLV). 866214456Srpaulo */ 867214456Srpaulo if (op_valid(EXTRACT_16BITS(&otlv->type), op_msk)) { 868214456Srpaulo otlv_print(otlv, 0, indent); 869214456Srpaulo } else { 870214456Srpaulo if (vflag < 3) 871214456Srpaulo printf("\n"); 872214456Srpaulo printf 873214456Srpaulo ("\t\tINValid oper-TLV type 0x%x length %d for this ForCES message\n", 874214456Srpaulo EXTRACT_16BITS(&otlv->type), EXTRACT_16BITS(&otlv->length)); 875214456Srpaulo invoptlv_print((u_char *)otlv, rlen, 0, indent); 876214456Srpaulo } 877214456Srpaulo otlv = GO_NXT_TLV(otlv, rlen); 878214456Srpaulo } 879214456Srpaulo 880214456Srpaulo if (rlen) { 881214456Srpaulo printf 882214456Srpaulo ("\n\t\tMessy oper TLV header, type (0x%x)\n\t\texcess of %d Bytes ", 883214456Srpaulo EXTRACT_16BITS(&otlv->type), rlen - EXTRACT_16BITS(&otlv->length)); 884214456Srpaulo return -1; 885214456Srpaulo } 886214456Srpaulo 887214456Srpaulo return 0; 888214456Srpaulo 889214456Srpaulotrunc: 890214456Srpaulo fputs("[|forces]", stdout); 891214456Srpaulo return -1; 892214456Srpaulo} 893214456Srpaulo 894214456Srpauloint 895214456Srpauloforces_type_print(register const u_char * pptr, const struct forcesh *fhdr _U_, 896214456Srpaulo register u_int mlen, const struct tom_h *tops) 897214456Srpaulo{ 898214456Srpaulo const struct forces_tlv *tltlv; 899214456Srpaulo u_int rlen; 900214456Srpaulo int invtlv; 901214456Srpaulo int rc = 0; 902214456Srpaulo int ttlv = 0; 903214456Srpaulo 904214456Srpaulo /* 905214456Srpaulo * forces_print() has already checked that mlen >= ForCES_HDRL 906214456Srpaulo * by calling ForCES_HLN_VALID(). 907214456Srpaulo */ 908214456Srpaulo rlen = mlen - ForCES_HDRL; 909214456Srpaulo 910214456Srpaulo if (rlen > TLV_HLN) { 911214456Srpaulo if (tops->flags & ZERO_TTLV) { 912214456Srpaulo printf("<0x%x>Illegal Top level TLV!\n", tops->flags); 913214456Srpaulo return -1; 914214456Srpaulo } 915214456Srpaulo } else { 916214456Srpaulo if (tops->flags & ZERO_MORE_TTLV) 917214456Srpaulo return 0; 918214456Srpaulo if (tops->flags & ONE_MORE_TTLV) { 919214456Srpaulo printf("\tTop level TLV Data missing!\n"); 920214456Srpaulo return -1; 921214456Srpaulo } 922214456Srpaulo } 923214456Srpaulo 924214456Srpaulo if (tops->flags & ZERO_TTLV) { 925214456Srpaulo return 0; 926214456Srpaulo } 927214456Srpaulo 928214456Srpaulo ttlv = tops->flags >> 4; 929214456Srpaulo tltlv = GET_TOP_TLV(pptr); 930214456Srpaulo 931214456Srpaulo /*XXX: 15 top level tlvs will probably be fine 932214456Srpaulo You are nuts if you send more ;-> */ 933214456Srpaulo while (rlen != 0) { 934214456Srpaulo TCHECK(*tltlv); 935214456Srpaulo invtlv = tlv_valid(tltlv, rlen); 936214456Srpaulo if (invtlv) 937214456Srpaulo break; 938214456Srpaulo 939214456Srpaulo /* 940214456Srpaulo * At this point, tlv_valid() has ensured that the TLV 941214456Srpaulo * length is large enough but not too large (it doesn't 942214456Srpaulo * go past the end of the packet). 943214456Srpaulo */ 944214456Srpaulo if (!ttlv_valid(EXTRACT_16BITS(&tltlv->type))) { 945214456Srpaulo printf("\n\tInvalid ForCES Top TLV type=0x%x", 946214456Srpaulo EXTRACT_16BITS(&tltlv->type)); 947214456Srpaulo return -1; 948214456Srpaulo } 949214456Srpaulo 950214456Srpaulo if (vflag >= 3) 951214456Srpaulo printf("\t%s, length %d (data length %d Bytes)", 952214456Srpaulo tok2str(ForCES_TLV, NULL, EXTRACT_16BITS(&tltlv->type)), 953214456Srpaulo EXTRACT_16BITS(&tltlv->length), 954214456Srpaulo EXTRACT_16BITS(&tltlv->length) - TLV_HDRL); 955214456Srpaulo 956214456Srpaulo rc = tops->print((u_char *) TLV_DATA(tltlv), 957214456Srpaulo EXTRACT_16BITS(&tltlv->length), tops->op_msk, 9); 958214456Srpaulo if (rc < 0) { 959214456Srpaulo return -1; 960214456Srpaulo } 961214456Srpaulo tltlv = GO_NXT_TLV(tltlv, rlen); 962214456Srpaulo ttlv--; 963214456Srpaulo if (ttlv <= 0) 964214456Srpaulo break; 965214456Srpaulo } 966214456Srpaulo /* 967214456Srpaulo * XXX - if ttlv != 0, does that mean that the packet was too 968214456Srpaulo * short, and didn't have *enough* TLVs in it? 969214456Srpaulo */ 970214456Srpaulo if (rlen) { 971214456Srpaulo printf("\tMess TopTLV header: min %u, total %d advertised %d ", 972214456Srpaulo TLV_HDRL, rlen, EXTRACT_16BITS(&tltlv->length)); 973214456Srpaulo return -1; 974214456Srpaulo } 975214456Srpaulo 976214456Srpaulo return 0; 977214456Srpaulo 978214456Srpaulotrunc: 979214456Srpaulo fputs("[|forces]", stdout); 980214456Srpaulo return -1; 981214456Srpaulo} 982214456Srpaulo 983214456Srpaulovoid forces_print(register const u_char * pptr, register u_int len) 984214456Srpaulo{ 985214456Srpaulo const struct forcesh *fhdr; 986214456Srpaulo u_int mlen; 987214456Srpaulo u_int32_t flg_raw; 988214456Srpaulo const struct tom_h *tops; 989214456Srpaulo int rc = 0; 990214456Srpaulo 991214456Srpaulo fhdr = (const struct forcesh *)pptr; 992214456Srpaulo TCHECK(*fhdr); 993214456Srpaulo if (!tom_valid(fhdr->fm_tom)) { 994214456Srpaulo printf("Invalid ForCES message type %d\n", fhdr->fm_tom); 995214456Srpaulo goto error; 996214456Srpaulo } 997214456Srpaulo 998214456Srpaulo mlen = ForCES_BLN(fhdr); 999214456Srpaulo 1000214456Srpaulo tops = get_forces_tom(fhdr->fm_tom); 1001214456Srpaulo if (tops->v == TOM_RSVD) { 1002214456Srpaulo printf("\n\tUnknown ForCES message type=0x%x", fhdr->fm_tom); 1003214456Srpaulo goto error; 1004214456Srpaulo } 1005214456Srpaulo 1006214456Srpaulo printf("\n\tForCES %s ", tops->s); 1007214456Srpaulo if (!ForCES_HLN_VALID(mlen, len)) { 1008214456Srpaulo printf 1009214456Srpaulo ("Illegal ForCES pkt len - min %u, total recvd %d, advertised %d ", 1010214456Srpaulo ForCES_HDRL, len, ForCES_BLN(fhdr)); 1011214456Srpaulo goto error; 1012214456Srpaulo } 1013214456Srpaulo 1014214456Srpaulo TCHECK2(*(pptr + 20), 4); 1015214456Srpaulo flg_raw = EXTRACT_32BITS(pptr + 20); 1016214456Srpaulo if (vflag >= 1) { 1017214456Srpaulo printf("\n\tForCES Version %d len %uB flags 0x%08x ", 1018214456Srpaulo ForCES_V(fhdr), mlen, flg_raw); 1019241235Sdelphij printf("\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIx64, 1020214456Srpaulo ForCES_SID(fhdr), ForCES_node(ForCES_SID(fhdr)), 1021214456Srpaulo ForCES_DID(fhdr), ForCES_node(ForCES_DID(fhdr)), 1022214456Srpaulo EXTRACT_64BITS(fhdr->fm_cor)); 1023214456Srpaulo 1024214456Srpaulo } 1025214456Srpaulo if (vflag >= 2) { 1026214456Srpaulo printf 1027214456Srpaulo ("\n\tForCES flags:\n\t %s(0x%x), prio=%d, %s(0x%x),\n\t %s(0x%x), %s(0x%x)\n", 1028214456Srpaulo ForCES_ACKp(ForCES_ACK(fhdr)), ForCES_ACK(fhdr), 1029214456Srpaulo ForCES_PRI(fhdr), 1030214456Srpaulo ForCES_EMp(ForCES_EM(fhdr)), ForCES_EM(fhdr), 1031214456Srpaulo ForCES_ATp(ForCES_AT(fhdr)), ForCES_AT(fhdr), 1032214456Srpaulo ForCES_TPp(ForCES_TP(fhdr)), ForCES_TP(fhdr)); 1033214456Srpaulo printf 1034214456Srpaulo ("\t Extra flags: rsv(b5-7) 0x%x rsv(b13-31) 0x%x\n", 1035214456Srpaulo ForCES_RS1(fhdr), ForCES_RS2(fhdr)); 1036214456Srpaulo } 1037214456Srpaulo rc = forces_type_print(pptr, fhdr, mlen, tops); 1038214456Srpaulo if (rc < 0) { 1039214456Srpauloerror: 1040214456Srpaulo hex_print_with_offset("\n\t[", pptr, len, 0); 1041214456Srpaulo printf("\n\t]"); 1042214456Srpaulo return; 1043214456Srpaulo } 1044214456Srpaulo 1045214456Srpaulo if (vflag >= 4) { 1046214456Srpaulo printf("\n\t Raw ForCES message\n\t ["); 1047214456Srpaulo hex_print_with_offset("\n\t ", pptr, len, 0); 1048214456Srpaulo printf("\n\t ]"); 1049214456Srpaulo } 1050214456Srpaulo printf("\n"); 1051214456Srpaulo return; 1052214456Srpaulo 1053214456Srpaulotrunc: 1054214456Srpaulo fputs("[|forces]", stdout); 1055214456Srpaulo} 1056