1/* 2 * Copyright (c) 1982, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Copyright (c) 2009 Mojatatu Networks, Inc 34 * 35 */ 36 37/* 38 * Per draft-ietf-forces-protocol-22 39*/ 40#define ForCES_VERS 1 41#define ForCES_HDRL 24 42#define ForCES_ALNL 4U 43#define TLV_HDRL 4 44#define ILV_HDRL 8 45 46#define TOM_RSVD 0x0 47#define TOM_ASSNSETUP 0x1 48#define TOM_ASSNTEARD 0x2 49#define TOM_CONFIG 0x3 50#define TOM_QUERY 0x4 51#define TOM_EVENTNOT 0x5 52#define TOM_PKTREDIR 0x6 53#define TOM_HEARTBT 0x0F 54#define TOM_ASSNSETREP 0x11 55#define TOM_CONFIGREP 0x13 56#define TOM_QUERYREP 0x14 57 58/* 59 * tom_h Flags: resv1(8b):maxtlvs(4b):resv2(2b):mintlv(2b) 60*/ 61#define ZERO_TTLV 0x01 62#define ZERO_MORE_TTLV 0x02 63#define ONE_MORE_TTLV 0x04 64#define ZERO_TLV 0x00 65#define ONE_TLV 0x10 66#define TWO_TLV 0x20 67#define MAX_TLV 0xF0 68 69#define TTLV_T1 (ONE_MORE_TTLV|ONE_TLV) 70#define TTLV_T2 (ONE_MORE_TTLV|MAX_TLV) 71 72struct tom_h { 73 u_int32_t v; 74 u_int16_t flags; 75 u_int16_t op_msk; 76 const char *s; 77 int (*print) (register const u_char * pptr, register u_int len, 78 u_int16_t op_msk, int indent); 79}; 80 81enum { 82 TOM_RSV_I, 83 TOM_ASS_I, 84 TOM_AST_I, 85 TOM_CFG_I, 86 TOM_QRY_I, 87 TOM_EVN_I, 88 TOM_RED_I, 89 TOM_HBT_I, 90 TOM_ASR_I, 91 TOM_CNR_I, 92 TOM_QRR_I, 93 _TOM_RSV_MAX 94}; 95#define TOM_MAX_IND (_TOM_RSV_MAX - 1) 96 97int lfbselect_print(register const u_char * pptr, register u_int len, 98 u_int16_t op_msk, int indent); 99int redirect_print(register const u_char * pptr, register u_int len, 100 u_int16_t op_msk, int indent); 101int asrtlv_print(register const u_char * pptr, register u_int len, 102 u_int16_t op_msk, int indent); 103int asttlv_print(register const u_char * pptr, register u_int len, 104 u_int16_t op_msk, int indent); 105int gentltlv_print(register const u_char * pptr, register u_int len, 106 u_int16_t op_msk, int indent); 107int print_metailv(register const u_char * pptr, register u_int len, 108 u_int16_t op_msk, int indent); 109int print_metatlv(register const u_char * pptr, register u_int len, 110 u_int16_t op_msk, int indent); 111int print_reddata(register const u_char * pptr, register u_int len, 112 u_int16_t op_msk, int indent); 113 114static inline int tom_valid(u_int8_t tom) 115{ 116 if (tom > 0) { 117 if (tom >= 0x7 && tom <= 0xe) 118 return 0; 119 if (tom == 0x10) 120 return 0; 121 if (tom > 0x14) 122 return 0; 123 return 1; 124 } else 125 return 0; 126} 127 128static inline const char *ForCES_node(u_int32_t node) 129{ 130 if (node <= 0x3FFFFFFF) 131 return "FE"; 132 if (node >= 0x40000000 && node <= 0x7FFFFFFF) 133 return "CE"; 134 if (node >= 0xC0000000 && node <= 0xFFFFFFEF) 135 return "AllMulticast"; 136 if (node == 0xFFFFFFFD) 137 return "AllCEsBroadcast"; 138 if (node == 0xFFFFFFFE) 139 return "AllFEsBroadcast"; 140 if (node == 0xFFFFFFFF) 141 return "AllBroadcast"; 142 143 return "ForCESreserved"; 144 145} 146 147static inline const char *ForCES_ACKp(u_int32_t flg) 148{ 149 if (flg == 0x0) 150 return "NoACK"; 151 if (flg == 0x1) 152 return "SuccessACK"; 153 if (flg == 0x2) 154 return "FailureACK"; 155 if (flg == 0x3) 156 return "AlwaysACK"; 157 return "ACKUnknown"; 158} 159 160static inline const char *ForCES_EMp(u_int32_t flg) 161{ 162 if (flg == 0x0) 163 return "EMReserved"; 164 if (flg == 0x1) 165 return "execute-all-or-none"; 166 if (flg == 0x2) 167 return "execute-until-failure"; 168 if (flg == 0x3) 169 return "continue-execute-on-failure"; 170 return "EMUnknown"; 171} 172 173static inline const char *ForCES_ATp(u_int32_t flg) 174{ 175 if (flg == 0x0) 176 return "Standalone"; 177 if (flg == 0x1) 178 return "2PCtransaction"; 179 return "ATUnknown"; 180} 181 182static inline const char *ForCES_TPp(u_int32_t flg) 183{ 184 if (flg == 0x0) 185 return "StartofTransaction"; 186 if (flg == 0x1) 187 return "MiddleofTransaction"; 188 if (flg == 0x2) 189 return "EndofTransaction"; 190 if (flg == 0x3) 191 return "abort"; 192 return "TPUnknown"; 193} 194 195/* 196 * Structure of forces header, naked of TLVs. 197 */ 198struct forcesh { 199 u_int8_t fm_vrsvd; /* version and reserved */ 200#define ForCES_V(forcesh) ((forcesh)->fm_vrsvd >> 4) 201 u_int8_t fm_tom; /* type of message */ 202 u_int16_t fm_len; /* total length * 4 bytes */ 203#define ForCES_BLN(forcesh) ((u_int32_t)(EXTRACT_16BITS(&(forcesh)->fm_len) << 2)) 204 u_int32_t fm_sid; /* Source ID */ 205#define ForCES_SID(forcesh) EXTRACT_32BITS(&(forcesh)->fm_sid) 206 u_int32_t fm_did; /* Destination ID */ 207#define ForCES_DID(forcesh) EXTRACT_32BITS(&(forcesh)->fm_did) 208 u_int8_t fm_cor[8]; /* correlator */ 209 u_int32_t fm_flags; /* flags */ 210#define ForCES_ACK(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0xC0000000) >> 30) 211#define ForCES_PRI(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x38000000) >> 27) 212#define ForCES_RS1(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x07000000) >> 24) 213#define ForCES_EM(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00C00000) >> 22) 214#define ForCES_AT(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00200000) >> 21) 215#define ForCES_TP(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00180000) >> 19) 216#define ForCES_RS2(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x0007FFFF) >> 0) 217}; 218 219#define ForCES_HLN_VALID(fhl,tlen) ((tlen) >= ForCES_HDRL && \ 220 (fhl) >= ForCES_HDRL && \ 221 (fhl) == (tlen)) 222 223#define F_LFB_RSVD 0x0 224#define F_LFB_FEO 0x1 225#define F_LFB_FEPO 0x2 226const struct tok ForCES_LFBs[] = { 227 {F_LFB_RSVD, "Invalid TLV"}, 228 {F_LFB_FEO, "FEObj LFB"}, 229 {F_LFB_FEPO, "FEProtoObj LFB"}, 230 {0, NULL} 231}; 232 233int forces_type_print(register const u_char * pptr, const struct forcesh *fhdr, 234 register u_int mlen, const struct tom_h *tops); 235 236enum { 237 F_OP_RSV, 238 F_OP_SET, 239 F_OP_SETPROP, 240 F_OP_SETRESP, 241 F_OP_SETPRESP, 242 F_OP_DEL, 243 F_OP_DELRESP, 244 F_OP_GET, 245 F_OP_GETPROP, 246 F_OP_GETRESP, 247 F_OP_GETPRESP, 248 F_OP_REPORT, 249 F_OP_COMMIT, 250 F_OP_RCOMMIT, 251 F_OP_RTRCOMP, 252 _F_OP_MAX 253}; 254 255#define F_OP_MAX (_F_OP_MAX - 1) 256enum { 257 B_OP_SET = 1 << (F_OP_SET - 1), 258 B_OP_SETPROP = 1 << (F_OP_SETPROP - 1), 259 B_OP_SETRESP = 1 << (F_OP_SETRESP - 1), 260 B_OP_SETPRESP = 1 << (F_OP_SETPRESP - 1), 261 B_OP_DEL = 1 << (F_OP_DEL - 1), 262 B_OP_DELRESP = 1 << (F_OP_DELRESP - 1), 263 B_OP_GET = 1 << (F_OP_GET - 1), 264 B_OP_GETPROP = 1 << (F_OP_GETPROP - 1), 265 B_OP_GETRESP = 1 << (F_OP_GETRESP - 1), 266 B_OP_GETPRESP = 1 << (F_OP_GETPRESP - 1), 267 B_OP_REPORT = 1 << (F_OP_REPORT - 1), 268 B_OP_COMMIT = 1 << (F_OP_COMMIT - 1), 269 B_OP_RCOMMIT = 1 << (F_OP_RCOMMIT - 1), 270 B_OP_RTRCOMP = 1 << (F_OP_RTRCOMP - 1), 271}; 272 273struct optlv_h { 274 u_int16_t flags; 275 u_int16_t op_msk; 276 const char *s; 277 int (*print) (register const u_char * pptr, register u_int len, 278 u_int16_t op_msk, int indent); 279}; 280 281int genoptlv_print(register const u_char * pptr, register u_int len, 282 u_int16_t op_msk, int indent); 283int recpdoptlv_print(register const u_char * pptr, register u_int len, 284 u_int16_t op_msk, int indent); 285int invoptlv_print(register const u_char * pptr, register u_int len, 286 u_int16_t op_msk, int indent); 287 288#define OP_MIN_SIZ 8 289struct pathdata_h { 290 u_int16_t pflags; 291 u_int16_t pIDcnt; 292}; 293 294#define B_FULLD 0x1 295#define B_SPARD 0x2 296#define B_RESTV 0x4 297#define B_KEYIN 0x8 298 299static const struct optlv_h OPTLV_msg[F_OP_MAX + 1] = { 300 /* F_OP_RSV */ {ZERO_TTLV, 0, "Invalid OPTLV", invoptlv_print}, 301 /* F_OP_SET */ {TTLV_T2, B_FULLD | B_SPARD, " Set", recpdoptlv_print}, 302 /* F_OP_SETPROP */ 303 {TTLV_T2, B_FULLD | B_SPARD, " SetProp", recpdoptlv_print}, 304 /* F_OP_SETRESP */ {TTLV_T2, B_RESTV, " SetResp", recpdoptlv_print}, 305 /* F_OP_SETPRESP */ {TTLV_T2, B_RESTV, " SetPropResp", recpdoptlv_print}, 306 /* F_OP_DEL */ {ZERO_TTLV, 0, " Del", recpdoptlv_print}, 307 /* F_OP_DELRESP */ {TTLV_T2, B_RESTV, " DelResp", recpdoptlv_print}, 308 /* F_OP_GET */ {ZERO_TTLV, 0, " Get", recpdoptlv_print}, 309 /* F_OP_GETPROP */ {ZERO_TTLV, 0, " GetProp", recpdoptlv_print}, 310 /* F_OP_GETRESP */ 311 {TTLV_T2, B_FULLD | B_SPARD | B_RESTV, " GetResp", recpdoptlv_print}, 312 /* F_OP_GETPRESP */ 313 {TTLV_T2, B_FULLD | B_RESTV, " GetPropResp", recpdoptlv_print}, 314 /* F_OP_REPORT */ 315 {TTLV_T2, B_FULLD | B_SPARD, " Report", recpdoptlv_print}, 316 /* F_OP_COMMIT */ {ZERO_TTLV, 0, " Commit", NULL}, 317 /* F_OP_RCOMMIT */ {TTLV_T1, B_RESTV, " RCommit", genoptlv_print}, 318 /* F_OP_RTRCOMP */ {ZERO_TTLV, 0, " RTRCOMP", NULL}, 319}; 320 321static inline const struct optlv_h *get_forces_optlv_h(u_int16_t opt) 322{ 323 if (opt > F_OP_MAX || opt <= F_OP_RSV) 324 return &OPTLV_msg[F_OP_RSV]; 325 326 return &OPTLV_msg[opt]; 327} 328 329#define IND_SIZE 256 330#define IND_CHR ' ' 331#define IND_PREF '\n' 332#define IND_SUF 0x0 333char ind_buf[IND_SIZE]; 334 335static inline char *indent_pr(int indent, int nlpref) 336{ 337 int i = 0; 338 char *r = ind_buf; 339 340 if (indent > (IND_SIZE - 1)) 341 indent = IND_SIZE - 1; 342 343 if (nlpref) { 344 r[i] = IND_PREF; 345 i++; 346 indent--; 347 } 348 349 while (--indent >= 0) 350 r[i++] = IND_CHR; 351 352 r[i] = IND_SUF; 353 return r; 354} 355 356static inline int op_valid(u_int16_t op, u_int16_t mask) 357{ 358 int opb = 1 << (op - 1); 359 360 if (op == 0) 361 return 0; 362 if (opb & mask) 363 return 1; 364 /* I guess we should allow vendor operations? */ 365 if (op >= 0x8000) 366 return 1; 367 return 0; 368} 369 370#define F_TLV_RSVD 0x0000 371#define F_TLV_REDR 0x0001 372#define F_TLV_ASRS 0x0010 373#define F_TLV_ASRT 0x0011 374#define F_TLV_LFBS 0x1000 375#define F_TLV_PDAT 0x0110 376#define F_TLV_KEYI 0x0111 377#define F_TLV_FULD 0x0112 378#define F_TLV_SPAD 0x0113 379#define F_TLV_REST 0x0114 380#define F_TLV_METD 0x0115 381#define F_TLV_REDD 0x0116 382#define F_TLV_VNST 0x8000 383 384static const struct tok ForCES_TLV[] = { 385 {F_TLV_RSVD, "Invalid TLV"}, 386 {F_TLV_REDR, "REDIRECT TLV"}, 387 {F_TLV_ASRS, "ASResult TLV"}, 388 {F_TLV_ASRT, "ASTreason TLV"}, 389 {F_TLV_LFBS, "LFBselect TLV"}, 390 {F_TLV_PDAT, "PATH-DATA TLV"}, 391 {F_TLV_KEYI, "KEYINFO TLV"}, 392 {F_TLV_FULD, "FULLDATA TLV"}, 393 {F_TLV_SPAD, "SPARSEDATA TLV"}, 394 {F_TLV_REST, "RESULT TLV"}, 395 {F_TLV_METD, "METADATA TLV"}, 396 {F_TLV_REDD, "REDIRECTDATA TLV"}, 397 {0, NULL} 398}; 399 400#define TLV_HLN 4 401static inline int ttlv_valid(u_int16_t ttlv) 402{ 403 if (ttlv > 0) { 404 if (ttlv == 1 || ttlv == 0x1000) 405 return 1; 406 if (ttlv >= 0x10 && ttlv <= 0x11) 407 return 1; 408 if (ttlv >= 0x110 && ttlv <= 0x116) 409 return 1; 410 if (ttlv >= 0x8000) 411 return 0; /* XXX: */ 412 } 413 414 return 0; 415} 416 417struct forces_ilv { 418 u_int32_t type; 419 u_int32_t length; 420}; 421 422struct forces_tlv { 423 u_int16_t type; 424 u_int16_t length; 425}; 426 427int otlv_print(const struct forces_tlv *otlv, u_int16_t op_msk, int indent); 428 429#define F_ALN_LEN(len) ( ((len)+ForCES_ALNL-1) & ~(ForCES_ALNL-1) ) 430#define GET_TOP_TLV(fhdr) ((struct forces_tlv *)((fhdr) + sizeof (struct forcesh))) 431#define TLV_SET_LEN(len) (F_ALN_LEN(TLV_HDRL) + (len)) 432#define TLV_ALN_LEN(len) F_ALN_LEN(TLV_SET_LEN(len)) 433#define TLV_RDAT_LEN(tlv) ((int)(EXTRACT_16BITS(&(tlv)->length) - TLV_SET_LEN(0)) 434#define TLV_DATA(tlvp) ((void*)(((char*)(tlvp)) + TLV_SET_LEN(0))) 435#define GO_NXT_TLV(tlv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length)), \ 436 (struct forces_tlv*)(((char*)(tlv)) \ 437 + F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length)))) 438#define ILV_SET_LEN(len) (F_ALN_LEN(ILV_HDRL) + (len)) 439#define ILV_ALN_LEN(len) F_ALN_LEN(ILV_SET_LEN(len)) 440#define ILV_RDAT_LEN(ilv) ((int)(EXTRACT_32BITS(&(ilv)->length)) - ILV_SET_LEN(0)) 441#define ILV_DATA(ilvp) ((void*)(((char*)(ilvp)) + ILV_SET_LEN(0))) 442#define GO_NXT_ILV(ilv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length)), \ 443 (struct forces_ilv *)(((char*)(ilv)) \ 444 + F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length)))) 445#define INVALID_RLEN -1 446#define INVALID_STLN -2 447#define INVALID_LTLN -3 448#define INVALID_ALEN -4 449 450static const struct tok ForCES_TLV_err[] = { 451 {INVALID_RLEN, "Invalid total length"}, 452 {INVALID_STLN, "xLV too short"}, 453 {INVALID_LTLN, "xLV too long"}, 454 {INVALID_ALEN, "data padding missing"}, 455 {0, NULL} 456}; 457 458static inline int tlv_valid(const struct forces_tlv *tlv, u_int rlen) 459{ 460 if (rlen < TLV_HDRL) 461 return INVALID_RLEN; 462 if (EXTRACT_16BITS(&tlv->length) < TLV_HDRL) 463 return INVALID_STLN; 464 if (EXTRACT_16BITS(&tlv->length) > rlen) 465 return INVALID_LTLN; 466 if (rlen < F_ALN_LEN(EXTRACT_16BITS(&tlv->length))) 467 return INVALID_ALEN; 468 469 return 0; 470} 471 472static inline int ilv_valid(const struct forces_ilv *ilv, u_int rlen) 473{ 474 if (rlen < ILV_HDRL) 475 return INVALID_RLEN; 476 if (EXTRACT_32BITS(&ilv->length) < ILV_HDRL) 477 return INVALID_STLN; 478 if (EXTRACT_32BITS(&ilv->length) > rlen) 479 return INVALID_LTLN; 480 if (rlen < F_ALN_LEN(EXTRACT_32BITS(&ilv->length))) 481 return INVALID_ALEN; 482 483 return 0; 484} 485 486struct forces_lfbsh { 487 u_int32_t class; 488 u_int32_t instance; 489}; 490 491#define ASSNS_OPS (B_OP_REPORT) 492#define CFG_OPS (B_OP_SET|B_OP_SETPROP|B_OP_DEL|B_OP_COMMIT|B_OP_RTRCOMP) 493#define CFG_ROPS (B_OP_SETRESP|B_OP_SETPRESP|B_OP_DELRESP|B_OP_RCOMMIT) 494#define CFG_QY (B_OP_GET|B_OP_GETPROP) 495#define CFG_QYR (B_OP_GETRESP|B_OP_GETPRESP) 496#define CFG_EVN (B_OP_REPORT) 497 498static const struct tom_h ForCES_msg[TOM_MAX_IND + 1] = { 499 /* TOM_RSV_I */ {TOM_RSVD, ZERO_TTLV, 0, "Invalid message", NULL}, 500 /* TOM_ASS_I */ {TOM_ASSNSETUP, ZERO_MORE_TTLV | TWO_TLV, ASSNS_OPS, 501 "Association Setup", lfbselect_print}, 502 /* TOM_AST_I */ 503 {TOM_ASSNTEARD, TTLV_T1, 0, "Association TearDown", asttlv_print}, 504 /* TOM_CFG_I */ {TOM_CONFIG, TTLV_T2, CFG_OPS, "Config", lfbselect_print}, 505 /* TOM_QRY_I */ {TOM_QUERY, TTLV_T2, CFG_QY, "Query", lfbselect_print}, 506 /* TOM_EVN_I */ {TOM_EVENTNOT, TTLV_T1, CFG_EVN, "Event Notification", 507 lfbselect_print}, 508 /* TOM_RED_I */ 509 {TOM_PKTREDIR, TTLV_T2, 0, "Packet Redirect", redirect_print}, 510 /* TOM_HBT_I */ {TOM_HEARTBT, ZERO_TTLV, 0, "HeartBeat", NULL}, 511 /* TOM_ASR_I */ 512 {TOM_ASSNSETREP, TTLV_T1, 0, "Association Response", asrtlv_print}, 513 /* TOM_CNR_I */ {TOM_CONFIGREP, TTLV_T2, CFG_ROPS, "Config Response", 514 lfbselect_print}, 515 /* TOM_QRR_I */ 516 {TOM_QUERYREP, TTLV_T2, CFG_QYR, "Query Response", lfbselect_print}, 517}; 518 519static inline const struct tom_h *get_forces_tom(u_int8_t tom) 520{ 521 int i; 522 for (i = TOM_RSV_I; i <= TOM_MAX_IND; i++) { 523 const struct tom_h *th = &ForCES_msg[i]; 524 if (th->v == tom) 525 return th; 526 } 527 return &ForCES_msg[TOM_RSV_I]; 528} 529 530struct pdata_ops { 531 u_int32_t v; 532 u_int16_t flags; 533 u_int16_t op_msk; 534 const char *s; 535 int (*print) (register const u_char * pptr, register u_int len, 536 u_int16_t op_msk, int indent); 537}; 538 539enum { 540 PD_RSV_I, 541 PD_SEL_I, 542 PD_FDT_I, 543 PD_SDT_I, 544 PD_RES_I, 545 PD_PDT_I, 546 _PD_RSV_MAX 547}; 548#define PD_MAX_IND (_TOM_RSV_MAX - 1) 549 550static inline int pd_valid(u_int16_t pd) 551{ 552 if (pd >= F_TLV_PDAT && pd <= F_TLV_REST) 553 return 1; 554 return 0; 555} 556 557static inline void chk_op_type(u_int16_t type, u_int16_t msk, u_int16_t omsk) 558{ 559 if (type != F_TLV_PDAT) { 560 if (msk & B_KEYIN) { 561 if (type != F_TLV_KEYI) { 562 printf 563 ("Based on flags expected KEYINFO TLV!\n"); 564 } 565 } else { 566 if (!(msk & omsk)) { 567 printf 568 ("Illegal DATA encoding for type 0x%x programmed %x got %x \n", 569 type, omsk, msk); 570 } 571 } 572 } 573 574} 575 576int fdatatlv_print(register const u_char * pptr, register u_int len, 577 u_int16_t op_msk, int indent); 578int sdatailv_print(register const u_char * pptr, register u_int len, 579 u_int16_t op_msk, int indent); 580int sdatatlv_print(register const u_char * pptr, register u_int len, 581 u_int16_t op_msk, int indent); 582int pdatatlv_print(register const u_char * pptr, register u_int len, 583 u_int16_t op_msk, int indent); 584int pkeyitlv_print(register const u_char * pptr, register u_int len, 585 u_int16_t op_msk, int indent); 586 587int pdatacnt_print(register const u_char * pptr, register u_int len, 588 u_int16_t IDcnt, u_int16_t op_msk, int indent); 589int pdata_print(register const u_char * pptr, register u_int len, 590 u_int16_t op_msk, int indent); 591 592int prestlv_print(register const u_char * pptr, register u_int len, 593 u_int16_t op_msk, int indent); 594#define F_SELKEY 1 595 596struct res_val { 597 u_int8_t result; 598 u_int8_t resv1; 599 u_int16_t resv2; 600}; 601 602static const struct pdata_ops ForCES_pdata[PD_MAX_IND + 1] = { 603 /* PD_RSV_I */ {0, 0, 0, "Invalid message", NULL}, 604 /* PD_SEL_I */ {F_TLV_KEYI, 0, 0, "KEYINFO TLV", pkeyitlv_print}, 605 /* PD_FDT_I */ {F_TLV_FULD, 0, B_FULLD, "FULLDATA TLV", fdatatlv_print}, 606 /* PD_SDT_I */ {F_TLV_SPAD, 0, B_SPARD, "SPARSEDATA TLV", sdatatlv_print}, 607 /* PD_RES_I */ {F_TLV_REST, 0, B_RESTV, "RESULT TLV", prestlv_print}, 608 /* PD_PDT_I */ 609 {F_TLV_PDAT, 0, 0, "Inner PATH-DATA TLV", recpdoptlv_print}, 610}; 611 612static inline const struct pdata_ops *get_forces_pd(u_int16_t pd) 613{ 614 int i; 615 for (i = PD_RSV_I + 1; i <= PD_MAX_IND; i++) { 616 const struct pdata_ops *pdo = &ForCES_pdata[i]; 617 if (pdo->v == pd) 618 return pdo; 619 } 620 return &ForCES_pdata[TOM_RSV_I]; 621} 622 623enum { 624 E_SUCCESS, 625 E_INVALID_HEADER, 626 E_LENGTH_MISMATCH, 627 E_VERSION_MISMATCH, 628 E_INVALID_DESTINATION_PID, 629 E_LFB_UNKNOWN, 630 E_LFB_NOT_FOUND, 631 E_LFB_INSTANCE_ID_NOT_FOUND, 632 E_INVALID_PATH, 633 E_COMPONENT_DOES_NOT_EXIST, 634 E_EXISTS, 635 E_NOT_FOUND, 636 E_READ_ONLY, 637 E_INVALID_ARRAY_CREATION, 638 E_VALUE_OUT_OF_RANGE, 639 E_CONTENTS_TOO_LONG, 640 E_INVALID_PARAMETERS, 641 E_INVALID_MESSAGE_TYPE, 642 E_INVALID_FLAGS, 643 E_INVALID_TLV, 644 E_EVENT_ERROR, 645 E_NOT_SUPPORTED, 646 E_MEMORY_ERROR, 647 E_INTERNAL_ERROR, 648 /* 0x18-0xFE are reserved .. */ 649 E_UNSPECIFIED_ERROR = 0XFF 650}; 651 652const struct tok ForCES_errs[] = { 653 {E_SUCCESS, "SUCCESS"}, 654 {E_INVALID_HEADER, "INVALID HEADER"}, 655 {E_LENGTH_MISMATCH, "LENGTH MISMATCH"}, 656 {E_VERSION_MISMATCH, "VERSION MISMATCH"}, 657 {E_INVALID_DESTINATION_PID, "INVALID DESTINATION PID"}, 658 {E_LFB_UNKNOWN, "LFB UNKNOWN"}, 659 {E_LFB_NOT_FOUND, "LFB NOT FOUND"}, 660 {E_LFB_INSTANCE_ID_NOT_FOUND, "LFB INSTANCE ID NOT FOUND"}, 661 {E_INVALID_PATH, "INVALID PATH"}, 662 {E_COMPONENT_DOES_NOT_EXIST, "COMPONENT DOES NOT EXIST"}, 663 {E_EXISTS, "EXISTS ALREADY"}, 664 {E_NOT_FOUND, "NOT FOUND"}, 665 {E_READ_ONLY, "READ ONLY"}, 666 {E_INVALID_ARRAY_CREATION, "INVALID ARRAY CREATION"}, 667 {E_VALUE_OUT_OF_RANGE, "VALUE OUT OF RANGE"}, 668 {E_CONTENTS_TOO_LONG, "CONTENTS TOO LONG"}, 669 {E_INVALID_PARAMETERS, "INVALID PARAMETERS"}, 670 {E_INVALID_MESSAGE_TYPE, "INVALID MESSAGE TYPE"}, 671 {E_INVALID_FLAGS, "INVALID FLAGS"}, 672 {E_INVALID_TLV, "INVALID TLV"}, 673 {E_EVENT_ERROR, "EVENT ERROR"}, 674 {E_NOT_SUPPORTED, "NOT SUPPORTED"}, 675 {E_MEMORY_ERROR, "MEMORY ERROR"}, 676 {E_INTERNAL_ERROR, "INTERNAL ERROR"}, 677 {E_UNSPECIFIED_ERROR, "UNSPECIFIED ERROR"}, 678 {0, NULL} 679}; 680