153f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Redistribution and use in source and binary forms, with or without
353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * modification, are permitted provided that: (1) source code
453f17a9db278d33517d9888dd77848f554522a38JP Abgrall * distributions retain the above copyright notice and this paragraph
553f17a9db278d33517d9888dd77848f554522a38JP Abgrall * in its entirety, and (2) distributions including binary code include
653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * the above copyright notice and this paragraph in its entirety in
753f17a9db278d33517d9888dd77848f554522a38JP Abgrall * the documentation or other materials provided with the distribution.
853f17a9db278d33517d9888dd77848f554522a38JP Abgrall * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
1053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * FOR A PARTICULAR PURPOSE.
1253f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
1353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Copyright (c) 2009 Mojatatu Networks, Inc
1453f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
1553f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
1653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
17e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes/* \summary: Forwarding and Control Element Separation (ForCES) Protocol printer */
18e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
19e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes/* specification: RFC 5810 */
20e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
2153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#ifdef HAVE_CONFIG_H
2253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "config.h"
2353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#endif
2453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
25e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#include <netdissect-stdinc.h>
2653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
27e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#include "netdissect.h"
2853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "extract.h"
2953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
30892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic const char tstr[] = "[|forces]";
3153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
3253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define	ForCES_VERS	1
3353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define	ForCES_HDRL	24
3453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define	ForCES_ALNL	4U
3553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TLV_HDRL	4
3653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ILV_HDRL	8
3753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
3853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOM_RSVD 	0x0
3953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOM_ASSNSETUP 	0x1
4053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOM_ASSNTEARD 	0x2
4153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOM_CONFIG 	0x3
4253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOM_QUERY 	0x4
4353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOM_EVENTNOT 	0x5
4453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOM_PKTREDIR 	0x6
4553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOM_HEARTBT 	0x0F
4653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOM_ASSNSETREP 	0x11
4753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOM_CONFIGREP 	0x13
4853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOM_QUERYREP 	0x14
4953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
5053f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
5153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * tom_h Flags: resv1(8b):maxtlvs(4b):resv2(2b):mintlv(2b)
5253f17a9db278d33517d9888dd77848f554522a38JP Abgrall*/
5353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ZERO_TTLV	0x01
5453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ZERO_MORE_TTLV	0x02
5553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ONE_MORE_TTLV	0x04
5653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ZERO_TLV	0x00
5753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ONE_TLV		0x10
5853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TWO_TLV		0x20
5953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MAX_TLV		0xF0
6053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
6153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TTLV_T1		(ONE_MORE_TTLV|ONE_TLV)
6253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TTLV_T2		(ONE_MORE_TTLV|MAX_TLV)
6353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
6453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct tom_h {
65892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint32_t v;
66892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t flags;
67892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t op_msk;
6853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	const char *s;
69892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	int (*print) (netdissect_options *ndo, register const u_char * pptr, register u_int len,
70892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		      uint16_t op_msk, int indent);
7153f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
7253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
7353f17a9db278d33517d9888dd77848f554522a38JP Abgrallenum {
7453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	TOM_RSV_I,
7553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	TOM_ASS_I,
7653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	TOM_AST_I,
7753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	TOM_CFG_I,
7853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	TOM_QRY_I,
7953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	TOM_EVN_I,
8053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	TOM_RED_I,
8153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	TOM_HBT_I,
8253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	TOM_ASR_I,
8353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	TOM_CNR_I,
8453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	TOM_QRR_I,
8553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	_TOM_RSV_MAX
8653f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
8753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOM_MAX_IND (_TOM_RSV_MAX - 1)
8853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
89892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic inline int tom_valid(uint8_t tom)
9053f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
9153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (tom > 0) {
9253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (tom >= 0x7 && tom <= 0xe)
9353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return 0;
9453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (tom == 0x10)
9553f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return 0;
9653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (tom > 0x14)
9753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return 0;
9853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return 1;
9953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	} else
10053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return 0;
10153f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
10253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
103892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic inline const char *ForCES_node(uint32_t node)
10453f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
10553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (node <= 0x3FFFFFFF)
10653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return "FE";
10753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (node >= 0x40000000 && node <= 0x7FFFFFFF)
10853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return "CE";
10953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (node >= 0xC0000000 && node <= 0xFFFFFFEF)
11053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return "AllMulticast";
11153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (node == 0xFFFFFFFD)
11253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return "AllCEsBroadcast";
11353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (node == 0xFFFFFFFE)
11453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return "AllFEsBroadcast";
11553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (node == 0xFFFFFFFF)
11653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return "AllBroadcast";
11753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
11853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return "ForCESreserved";
11953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
12053f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
12153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
122892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic const struct tok ForCES_ACKs[] = {
123892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x0, "NoACK"},
124892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x1, "SuccessACK"},
125892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x2, "FailureACK"},
126892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x3, "AlwaysACK"},
127892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0, NULL}
128892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes};
12953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
130892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic const struct tok ForCES_EMs[] = {
131892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x0, "EMReserved"},
132892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x1, "execute-all-or-none"},
133892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x2, "execute-until-failure"},
134892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x3, "continue-execute-on-failure"},
135892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0, NULL}
136892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes};
13753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
138892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic const struct tok ForCES_ATs[] = {
139892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x0, "Standalone"},
140892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x1, "2PCtransaction"},
141892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0, NULL}
142892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes};
14353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
144892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic const struct tok ForCES_TPs[] = {
145892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x0, "StartofTransaction"},
146892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x1, "MiddleofTransaction"},
147892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x2, "EndofTransaction"},
148892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0x3, "abort"},
149892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	{0, NULL}
150892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes};
15153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
15253f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
15353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Structure of forces header, naked of TLVs.
15453f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
15553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct forcesh {
156e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint8_t fm_vrsvd;	/* version and reserved */
15753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ForCES_V(forcesh)	((forcesh)->fm_vrsvd >> 4)
158e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint8_t fm_tom;	/* type of message */
159e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint16_t fm_len;	/* total length * 4 bytes */
160892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#define ForCES_BLN(forcesh)	((uint32_t)(EXTRACT_16BITS(&(forcesh)->fm_len) << 2))
161e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint32_t fm_sid;	/* Source ID */
16253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ForCES_SID(forcesh)	EXTRACT_32BITS(&(forcesh)->fm_sid)
163e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint32_t fm_did;	/* Destination ID */
16453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ForCES_DID(forcesh)	EXTRACT_32BITS(&(forcesh)->fm_did)
165e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint8_t fm_cor[8];	/* correlator */
166e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint32_t fm_flags;	/* flags */
16753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ForCES_ACK(forcesh)	((EXTRACT_32BITS(&(forcesh)->fm_flags)&0xC0000000) >> 30)
16853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ForCES_PRI(forcesh)	((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x38000000) >> 27)
16953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ForCES_RS1(forcesh)	((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x07000000) >> 24)
17053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ForCES_EM(forcesh)	((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00C00000) >> 22)
17153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ForCES_AT(forcesh)	((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00200000) >> 21)
17253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ForCES_TP(forcesh)	((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00180000) >> 19)
17353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ForCES_RS2(forcesh)	((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x0007FFFF) >> 0)
17453f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
17553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
17653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ForCES_HLN_VALID(fhl,tlen) ((tlen) >= ForCES_HDRL && \
17753f17a9db278d33517d9888dd77848f554522a38JP Abgrall				   (fhl) >= ForCES_HDRL && \
17853f17a9db278d33517d9888dd77848f554522a38JP Abgrall				   (fhl) == (tlen))
17953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
18053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_LFB_RSVD 0x0
18153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_LFB_FEO 0x1
18253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_LFB_FEPO 0x2
18353f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok ForCES_LFBs[] = {
18453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_LFB_RSVD, "Invalid TLV"},
18553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_LFB_FEO, "FEObj LFB"},
18653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_LFB_FEPO, "FEProtoObj LFB"},
18753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{0, NULL}
18853f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
18953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
190892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes/* this is defined in RFC5810 section A.2 */
191892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes/*   http://www.iana.org/assignments/forces/forces.xhtml#oper-tlv-types */
19253f17a9db278d33517d9888dd77848f554522a38JP Abgrallenum {
193892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_RSV        = 0,
194892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_SET        = 1,
195892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_SETPROP    = 2,
196892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_SETRESP    = 3,
197892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_SETPRESP   = 4,
198892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_DEL        = 5,
199892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_DELRESP    = 6,
200892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_GET        = 7,
201892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_GETPROP    = 8,
202892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_GETRESP    = 9,
203892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_GETPRESP   = 10,
204892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_REPORT     = 11,
205892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_COMMIT     = 12,
206892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_RCOMMIT    = 13,
207892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	F_OP_RTRCOMP    = 14,
20853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	_F_OP_MAX
20953f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
21053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_OP_MAX	(_F_OP_MAX - 1)
211892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
21253f17a9db278d33517d9888dd77848f554522a38JP Abgrallenum {
21353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_SET = 1 << (F_OP_SET - 1),
21453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_SETPROP = 1 << (F_OP_SETPROP - 1),
21553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_SETRESP = 1 << (F_OP_SETRESP - 1),
21653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_SETPRESP = 1 << (F_OP_SETPRESP - 1),
21753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_DEL = 1 << (F_OP_DEL - 1),
21853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_DELRESP = 1 << (F_OP_DELRESP - 1),
21953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_GET = 1 << (F_OP_GET - 1),
22053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_GETPROP = 1 << (F_OP_GETPROP - 1),
22153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_GETRESP = 1 << (F_OP_GETRESP - 1),
22253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_GETPRESP = 1 << (F_OP_GETPRESP - 1),
22353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_REPORT = 1 << (F_OP_REPORT - 1),
22453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_COMMIT = 1 << (F_OP_COMMIT - 1),
22553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	B_OP_RCOMMIT = 1 << (F_OP_RCOMMIT - 1),
226e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	B_OP_RTRCOMP = 1 << (F_OP_RTRCOMP - 1)
22753f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
22853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
22953f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct optlv_h {
230892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t flags;
231892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t op_msk;
23253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	const char *s;
233892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	int (*print) (netdissect_options *ndo, register const u_char * pptr, register u_int len,
234892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		      uint16_t op_msk, int indent);
23553f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
23653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
237892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int genoptlv_print(netdissect_options *, register const u_char * pptr, register u_int len,
238892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 uint16_t op_msk, int indent);
239892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int recpdoptlv_print(netdissect_options *, register const u_char * pptr, register u_int len,
240892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			    uint16_t op_msk, int indent);
241892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int invoptlv_print(netdissect_options *, register const u_char * pptr, register u_int len,
242892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			  uint16_t op_msk, int indent);
24353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
24453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define OP_MIN_SIZ 8
24553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct pathdata_h {
246e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint16_t pflags;
247e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint16_t pIDcnt;
24853f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
24953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
25053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define	B_FULLD		0x1
25153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define	B_SPARD 	0x2
25253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define B_RESTV		0x4
25353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define B_KEYIN		0x8
25453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define B_APPND		0x10
25553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define B_TRNG		0x20
25653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
25753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct optlv_h OPTLV_msg[F_OP_MAX + 1] = {
25853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_RSV */ {ZERO_TTLV, 0, "Invalid OPTLV", invoptlv_print},
25953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_SET */ {TTLV_T2, B_FULLD | B_SPARD, " Set", recpdoptlv_print},
26053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_SETPROP */
26153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    {TTLV_T2, B_FULLD | B_SPARD, " SetProp", recpdoptlv_print},
26253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_SETRESP */ {TTLV_T2, B_RESTV, " SetResp", recpdoptlv_print},
26353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_SETPRESP */ {TTLV_T2, B_RESTV, " SetPropResp", recpdoptlv_print},
26453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_DEL */ {ZERO_TTLV, 0, " Del", recpdoptlv_print},
26553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_DELRESP */ {TTLV_T2, B_RESTV, " DelResp", recpdoptlv_print},
26653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_GET */ {ZERO_TTLV, 0, " Get", recpdoptlv_print},
26753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_GETPROP */ {ZERO_TTLV, 0, " GetProp", recpdoptlv_print},
26853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_GETRESP */
26953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    {TTLV_T2, B_FULLD | B_SPARD | B_RESTV, " GetResp", recpdoptlv_print},
27053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_GETPRESP */
27153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    {TTLV_T2, B_FULLD | B_RESTV, " GetPropResp", recpdoptlv_print},
27253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_REPORT */
27353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    {TTLV_T2, B_FULLD | B_SPARD, " Report", recpdoptlv_print},
27453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_COMMIT */ {ZERO_TTLV, 0, " Commit", NULL},
27553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_RCOMMIT */ {TTLV_T1, B_RESTV, " RCommit", genoptlv_print},
27653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* F_OP_RTRCOMP */ {ZERO_TTLV, 0, " RTRCOMP", NULL},
27753f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
27853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
279892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic inline const struct optlv_h *get_forces_optlv_h(uint16_t opt)
28053f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
28153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (opt > F_OP_MAX || opt <= F_OP_RSV)
28253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return &OPTLV_msg[F_OP_RSV];
28353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
28453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return &OPTLV_msg[opt];
28553f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
28653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
28753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define IND_SIZE 256
28853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define IND_CHR ' '
28953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define IND_PREF '\n'
29053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define IND_SUF 0x0
291e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesstatic char ind_buf[IND_SIZE];
29253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
29353f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic inline char *indent_pr(int indent, int nlpref)
29453f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
29553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int i = 0;
29653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *r = ind_buf;
29753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
29853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (indent > (IND_SIZE - 1))
29953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		indent = IND_SIZE - 1;
30053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
30153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (nlpref) {
30253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		r[i] = IND_PREF;
30353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		i++;
30453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		indent--;
30553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
30653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
30753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	while (--indent >= 0)
30853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		r[i++] = IND_CHR;
30953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
31053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	r[i] = IND_SUF;
31153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return r;
31253f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
31353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
314892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic inline int op_valid(uint16_t op, uint16_t mask)
31553f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
31653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int opb = 1 << (op - 1);
31753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
31853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (op == 0)
31953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return 0;
32053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (opb & mask)
32153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return 1;
32253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* I guess we should allow vendor operations? */
32353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (op >= 0x8000)
32453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return 1;
32553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
32653f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
32753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
32853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_RSVD	0x0000
32953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_REDR	0x0001
33053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_ASRS	0x0010
33153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_ASRT	0x0011
33253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_LFBS	0x1000
33353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_PDAT	0x0110
33453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_KEYI	0x0111
33553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_FULD	0x0112
33653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_SPAD	0x0113
33753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_REST	0x0114
33853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_METD	0x0115
33953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_REDD	0x0116
34053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_TRNG	0x0117
34153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
34253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
34353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TLV_VNST	0x8000
34453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
34553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok ForCES_TLV[] = {
34653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_TLV_RSVD, "Invalid TLV"},
34753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_TLV_REDR, "REDIRECT TLV"},
34853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_TLV_ASRS, "ASResult TLV"},
34953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_TLV_ASRT, "ASTreason TLV"},
35053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_TLV_LFBS, "LFBselect TLV"},
35153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_TLV_PDAT, "PATH-DATA TLV"},
35253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_TLV_KEYI, "KEYINFO TLV"},
35353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_TLV_FULD, "FULLDATA TLV"},
35453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_TLV_SPAD, "SPARSEDATA TLV"},
35553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_TLV_REST, "RESULT TLV"},
35653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_TLV_METD, "METADATA TLV"},
35753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{F_TLV_REDD, "REDIRECTDATA TLV"},
35853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{0, NULL}
35953f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
36053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
36153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TLV_HLN	4
362892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic inline int ttlv_valid(uint16_t ttlv)
36353f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
36453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (ttlv > 0) {
36553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (ttlv == 1 || ttlv == 0x1000)
36653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return 1;
36753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (ttlv >= 0x10 && ttlv <= 0x11)
36853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return 1;
36953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (ttlv >= 0x110 && ttlv <= 0x116)
37053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return 1;
37153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (ttlv >= 0x8000)
37253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return 0;	/* XXX: */
37353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
37453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
37553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
37653f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
37753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
37853f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct forces_ilv {
379e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint32_t type;
380e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint32_t length;
38153f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
38253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
38353f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct forces_tlv {
384e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint16_t type;
385e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint16_t length;
38653f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
38753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
38853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_ALN_LEN(len) ( ((len)+ForCES_ALNL-1) & ~(ForCES_ALNL-1) )
389e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#define	GET_TOP_TLV(fhdr) ((const struct forces_tlv *)((fhdr) + sizeof (struct forcesh)))
39053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TLV_SET_LEN(len)  (F_ALN_LEN(TLV_HDRL) + (len))
39153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TLV_ALN_LEN(len)  F_ALN_LEN(TLV_SET_LEN(len))
39253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TLV_RDAT_LEN(tlv) ((int)(EXTRACT_16BITS(&(tlv)->length) - TLV_SET_LEN(0))
393e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#define TLV_DATA(tlvp)   ((const void*)(((const char*)(tlvp)) + TLV_SET_LEN(0)))
39453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define GO_NXT_TLV(tlv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length)), \
395e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		              (const struct forces_tlv*)(((const char*)(tlv)) \
39653f17a9db278d33517d9888dd77848f554522a38JP Abgrall				      + F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length))))
39753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ILV_SET_LEN(len)  (F_ALN_LEN(ILV_HDRL) + (len))
39853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ILV_ALN_LEN(len)  F_ALN_LEN(ILV_SET_LEN(len))
39953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ILV_RDAT_LEN(ilv) ((int)(EXTRACT_32BITS(&(ilv)->length)) - ILV_SET_LEN(0))
400e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#define ILV_DATA(ilvp)   ((const void*)(((const char*)(ilvp)) + ILV_SET_LEN(0)))
40153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define GO_NXT_ILV(ilv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length)), \
402e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		              (const struct forces_ilv *)(((const char*)(ilv)) \
40353f17a9db278d33517d9888dd77848f554522a38JP Abgrall				      + F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length))))
404892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#define INVALID_RLEN 1
405892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#define INVALID_STLN 2
406892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#define INVALID_LTLN 3
407892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#define INVALID_ALEN 4
40853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
40953f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok ForCES_TLV_err[] = {
41053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{INVALID_RLEN, "Invalid total length"},
41153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{INVALID_STLN, "xLV too short"},
41253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{INVALID_LTLN, "xLV too long"},
41353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{INVALID_ALEN, "data padding missing"},
41453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{0, NULL}
41553f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
41653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
417892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic inline u_int tlv_valid(const struct forces_tlv *tlv, u_int rlen)
41853f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
41953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (rlen < TLV_HDRL)
42053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return INVALID_RLEN;
42153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (EXTRACT_16BITS(&tlv->length) < TLV_HDRL)
42253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return INVALID_STLN;
42353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (EXTRACT_16BITS(&tlv->length) > rlen)
42453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return INVALID_LTLN;
42553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (rlen < F_ALN_LEN(EXTRACT_16BITS(&tlv->length)))
42653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return INVALID_ALEN;
42753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
42853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
42953f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
43053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
43153f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic inline int ilv_valid(const struct forces_ilv *ilv, u_int rlen)
43253f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
43353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (rlen < ILV_HDRL)
43453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return INVALID_RLEN;
43553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (EXTRACT_32BITS(&ilv->length) < ILV_HDRL)
43653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return INVALID_STLN;
43753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (EXTRACT_32BITS(&ilv->length) > rlen)
43853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return INVALID_LTLN;
43953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (rlen < F_ALN_LEN(EXTRACT_32BITS(&ilv->length)))
44053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return INVALID_ALEN;
44153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
44253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
44353f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
44453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
445892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int lfbselect_print(netdissect_options *, register const u_char * pptr, register u_int len,
446892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			   uint16_t op_msk, int indent);
447892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int redirect_print(netdissect_options *, register const u_char * pptr, register u_int len,
448892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			  uint16_t op_msk, int indent);
449892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int asrtlv_print(netdissect_options *, register const u_char * pptr, register u_int len,
450892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			uint16_t op_msk, int indent);
451892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int asttlv_print(netdissect_options *, register const u_char * pptr, register u_int len,
452892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			uint16_t op_msk, int indent);
45353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
45453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct forces_lfbsh {
455e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint32_t class;
456e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint32_t instance;
45753f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
45853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
45953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ASSNS_OPS (B_OP_REPORT)
46053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFG_OPS	(B_OP_SET|B_OP_SETPROP|B_OP_DEL|B_OP_COMMIT|B_OP_RTRCOMP)
46153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFG_ROPS (B_OP_SETRESP|B_OP_SETPRESP|B_OP_DELRESP|B_OP_RCOMMIT)
46253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFG_QY (B_OP_GET|B_OP_GETPROP)
46353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFG_QYR (B_OP_GETRESP|B_OP_GETPRESP)
46453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFG_EVN (B_OP_REPORT)
46553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
46653f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tom_h ForCES_msg[TOM_MAX_IND + 1] = {
46753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* TOM_RSV_I */ {TOM_RSVD, ZERO_TTLV, 0, "Invalid message", NULL},
46853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* TOM_ASS_I */ {TOM_ASSNSETUP, ZERO_MORE_TTLV | TWO_TLV, ASSNS_OPS,
46953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       "Association Setup", lfbselect_print},
47053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* TOM_AST_I */
47153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    {TOM_ASSNTEARD, TTLV_T1, 0, "Association TearDown", asttlv_print},
47253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* TOM_CFG_I */ {TOM_CONFIG, TTLV_T2, CFG_OPS, "Config", lfbselect_print},
47353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* TOM_QRY_I */ {TOM_QUERY, TTLV_T2, CFG_QY, "Query", lfbselect_print},
47453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* TOM_EVN_I */ {TOM_EVENTNOT, TTLV_T1, CFG_EVN, "Event Notification",
47553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       lfbselect_print},
47653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* TOM_RED_I */
47753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    {TOM_PKTREDIR, TTLV_T2, 0, "Packet Redirect", redirect_print},
47853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* TOM_HBT_I */ {TOM_HEARTBT, ZERO_TTLV, 0, "HeartBeat", NULL},
47953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* TOM_ASR_I */
48053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    {TOM_ASSNSETREP, TTLV_T1, 0, "Association Response", asrtlv_print},
48153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* TOM_CNR_I */ {TOM_CONFIGREP, TTLV_T2, CFG_ROPS, "Config Response",
48253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       lfbselect_print},
48353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* TOM_QRR_I */
48453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    {TOM_QUERYREP, TTLV_T2, CFG_QYR, "Query Response", lfbselect_print},
48553f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
48653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
487892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic inline const struct tom_h *get_forces_tom(uint8_t tom)
48853f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
48953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int i;
49053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	for (i = TOM_RSV_I; i <= TOM_MAX_IND; i++) {
49153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		const struct tom_h *th = &ForCES_msg[i];
49253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (th->v == tom)
49353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return th;
49453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
49553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return &ForCES_msg[TOM_RSV_I];
49653f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
49753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
49853f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct pdata_ops {
499892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint32_t v;
500892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t flags;
501892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t op_msk;
50253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	const char *s;
503892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	int (*print) (netdissect_options *, register const u_char * pptr, register u_int len,
504892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		      uint16_t op_msk, int indent);
50553f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
50653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
50753f17a9db278d33517d9888dd77848f554522a38JP Abgrallenum {
50853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	PD_RSV_I,
50953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	PD_SEL_I,
51053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	PD_FDT_I,
51153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	PD_SDT_I,
51253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	PD_RES_I,
51353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	PD_PDT_I,
51453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	_PD_RSV_MAX
51553f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
51653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define PD_MAX_IND (_TOM_RSV_MAX - 1)
51753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
518892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic inline int pd_valid(uint16_t pd)
51953f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
52053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (pd >= F_TLV_PDAT && pd <= F_TLV_REST)
52153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return 1;
52253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
52353f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
52453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
525892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic inline void
526892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hugheschk_op_type(netdissect_options *ndo,
527892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            uint16_t type, uint16_t msk, uint16_t omsk)
52853f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
52953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (type != F_TLV_PDAT) {
53053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (msk & B_KEYIN) {
53153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (type != F_TLV_KEYI) {
532892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "Based on flags expected KEYINFO TLV!\n"));
53353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
53453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		} else {
53553f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (!(msk & omsk)) {
536892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "Illegal DATA encoding for type 0x%x programmed %x got %x \n",
537892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				          type, omsk, msk));
53853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
53953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
54053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
54153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
54253f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
54353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
54453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_SELKEY 1
54553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_SELTABRANGE 2
54653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define F_TABAPPEND 4
54753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
54853f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct res_val {
549e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint8_t result;
550e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint8_t resv1;
551e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	nd_uint16_t resv2;
55253f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
55353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
554892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int prestlv_print(netdissect_options *, register const u_char * pptr, register u_int len,
555892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 uint16_t op_msk, int indent);
556892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int pkeyitlv_print(netdissect_options *, register const u_char * pptr, register u_int len,
557892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			  uint16_t op_msk, int indent);
558892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int fdatatlv_print(netdissect_options *, register const u_char * pptr, register u_int len,
559892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			  uint16_t op_msk, int indent);
560892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int sdatatlv_print(netdissect_options *, register const u_char * pptr, register u_int len,
561892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			  uint16_t op_msk, int indent);
56253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
56353f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct pdata_ops ForCES_pdata[PD_MAX_IND + 1] = {
56453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* PD_RSV_I */ {0, 0, 0, "Invalid message", NULL},
56553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* PD_SEL_I */ {F_TLV_KEYI, 0, 0, "KEYINFO TLV", pkeyitlv_print},
56653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* PD_FDT_I */ {F_TLV_FULD, 0, B_FULLD, "FULLDATA TLV", fdatatlv_print},
56753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* PD_SDT_I */ {F_TLV_SPAD, 0, B_SPARD, "SPARSEDATA TLV", sdatatlv_print},
56853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* PD_RES_I */ {F_TLV_REST, 0, B_RESTV, "RESULT TLV", prestlv_print},
56953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* PD_PDT_I */
57053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    {F_TLV_PDAT, 0, 0, "Inner PATH-DATA TLV", recpdoptlv_print},
57153f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
57253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
573892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic inline const struct pdata_ops *get_forces_pd(uint16_t pd)
57453f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
57553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int i;
57653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	for (i = PD_RSV_I + 1; i <= PD_MAX_IND; i++) {
57753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		const struct pdata_ops *pdo = &ForCES_pdata[i];
57853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (pdo->v == pd)
57953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return pdo;
58053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
58153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return &ForCES_pdata[TOM_RSV_I];
58253f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
58353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
58453f17a9db278d33517d9888dd77848f554522a38JP Abgrallenum {
58553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_SUCCESS,
58653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_INVALID_HEADER,
58753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_LENGTH_MISMATCH,
58853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_VERSION_MISMATCH,
58953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_INVALID_DESTINATION_PID,
59053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_LFB_UNKNOWN,
59153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_LFB_NOT_FOUND,
59253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_LFB_INSTANCE_ID_NOT_FOUND,
59353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_INVALID_PATH,
59453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_COMPONENT_DOES_NOT_EXIST,
59553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_EXISTS,
59653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_NOT_FOUND,
59753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_READ_ONLY,
59853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_INVALID_ARRAY_CREATION,
59953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_VALUE_OUT_OF_RANGE,
60053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_CONTENTS_TOO_LONG,
60153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_INVALID_PARAMETERS,
60253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_INVALID_MESSAGE_TYPE,
60353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_INVALID_FLAGS,
60453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_INVALID_TLV,
60553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_EVENT_ERROR,
60653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_NOT_SUPPORTED,
60753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_MEMORY_ERROR,
60853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_INTERNAL_ERROR,
60953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* 0x18-0xFE are reserved .. */
61053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	E_UNSPECIFIED_ERROR = 0XFF
61153f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
61253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
61353f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok ForCES_errs[] = {
61453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_SUCCESS, "SUCCESS"},
61553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_INVALID_HEADER, "INVALID HEADER"},
61653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_LENGTH_MISMATCH, "LENGTH MISMATCH"},
61753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_VERSION_MISMATCH, "VERSION MISMATCH"},
61853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_INVALID_DESTINATION_PID, "INVALID DESTINATION PID"},
61953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_LFB_UNKNOWN, "LFB UNKNOWN"},
62053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_LFB_NOT_FOUND, "LFB NOT FOUND"},
62153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_LFB_INSTANCE_ID_NOT_FOUND, "LFB INSTANCE ID NOT FOUND"},
62253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_INVALID_PATH, "INVALID PATH"},
62353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_COMPONENT_DOES_NOT_EXIST, "COMPONENT DOES NOT EXIST"},
62453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_EXISTS, "EXISTS ALREADY"},
62553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_NOT_FOUND, "NOT FOUND"},
62653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_READ_ONLY, "READ ONLY"},
62753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_INVALID_ARRAY_CREATION, "INVALID ARRAY CREATION"},
62853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_VALUE_OUT_OF_RANGE, "VALUE OUT OF RANGE"},
62953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_CONTENTS_TOO_LONG, "CONTENTS TOO LONG"},
63053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_INVALID_PARAMETERS, "INVALID PARAMETERS"},
63153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_INVALID_MESSAGE_TYPE, "INVALID MESSAGE TYPE"},
63253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_INVALID_FLAGS, "INVALID FLAGS"},
63353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_INVALID_TLV, "INVALID TLV"},
63453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_EVENT_ERROR, "EVENT ERROR"},
63553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_NOT_SUPPORTED, "NOT SUPPORTED"},
63653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_MEMORY_ERROR, "MEMORY ERROR"},
63753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_INTERNAL_ERROR, "INTERNAL ERROR"},
63853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{E_UNSPECIFIED_ERROR, "UNSPECIFIED ERROR"},
63953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{0, NULL}
64053f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
64153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
64253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define RESLEN	4
64353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
64453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
645892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesprestlv_print(netdissect_options *ndo,
646892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes              register const u_char * pptr, register u_int len,
647892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes              uint16_t op_msk _U_, int indent)
64853f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
649e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct forces_tlv *tlv = (const struct forces_tlv *)pptr;
650e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	register const u_char *tdp = (const u_char *) TLV_DATA(tlv);
651e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct res_val *r = (const struct res_val *)tdp;
65253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int dlen;
65353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
65453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
65553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * pdatacnt_print() has ensured that len (the TLV length)
65653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * >= TLV_HDRL.
65753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
65853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	dlen = len - TLV_HDRL;
65953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (dlen != RESLEN) {
660892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "illegal RESULT-TLV: %d bytes!\n", dlen));
66153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
66253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
66353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
664892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(*r);
66553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (r->result >= 0x18 && r->result <= 0xFE) {
666892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "illegal reserved result code: 0x%x!\n", r->result));
66753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
66853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
66953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
670892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 3) {
67153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		char *ib = indent_pr(indent, 0);
672892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "%s  Result: %s (code 0x%x)\n", ib,
673892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       tok2str(ForCES_errs, NULL, r->result), r->result));
67453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
67553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
67653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
67753f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
678892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
67953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
68053f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
68153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
68253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
683892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesfdatatlv_print(netdissect_options *ndo,
684892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               register const u_char * pptr, register u_int len,
685892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               uint16_t op_msk _U_, int indent)
68653f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
687e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct forces_tlv *tlv = (const struct forces_tlv *)pptr;
68853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int rlen;
689e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	register const u_char *tdp = (const u_char *) TLV_DATA(tlv);
690892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t type;
69153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
69253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
69353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * pdatacnt_print() or pkeyitlv_print() has ensured that len
69453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * (the TLV length) >= TLV_HDRL.
69553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
69653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	rlen = len - TLV_HDRL;
697892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(*tlv);
69853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	type = EXTRACT_16BITS(&tlv->type);
69953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (type != F_TLV_FULD) {
700892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "Error: expecting FULLDATA!\n"));
70153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
70253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
70353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
704892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 3) {
70553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		char *ib = indent_pr(indent + 2, 1);
706892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "%s[", &ib[1]));
707892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		hex_print_with_offset(ndo, ib, tdp, rlen, 0);
708892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n%s]\n", &ib[1]));
70953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
71053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
71153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
71253f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
713892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
71453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
71553f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
71653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
71753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
718892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughessdatailv_print(netdissect_options *ndo,
719892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               register const u_char * pptr, register u_int len,
720892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               uint16_t op_msk _U_, int indent)
72153f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
72253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int rlen;
723e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct forces_ilv *ilv = (const struct forces_ilv *)pptr;
72453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int invilv;
72553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
72653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (len < ILV_HDRL) {
727892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "Error: BAD SPARSEDATA-TLV!\n"));
72853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
72953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
73053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	rlen = len;
73153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	indent += 1;
73253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	while (rlen != 0) {
73353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#if 0
734892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "Jamal - outstanding length <%d>\n", rlen));
73553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#endif
73653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		char *ib = indent_pr(indent, 1);
737e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		register const u_char *tdp = (const u_char *) ILV_DATA(ilv);
738892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK(*ilv);
73953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		invilv = ilv_valid(ilv, rlen);
74053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (invilv) {
741892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "%s[", &ib[1]));
742892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			hex_print_with_offset(ndo, ib, tdp, rlen, 0);
743892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "\n%s]\n", &ib[1]));
74453f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return -1;
74553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
746892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (ndo->ndo_vflag >= 3) {
74753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			int ilvl = EXTRACT_32BITS(&ilv->length);
748892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "\n%s ILV: type %x length %d\n", &ib[1],
749892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			       EXTRACT_32BITS(&ilv->type), ilvl));
750892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			hex_print_with_offset(ndo, "\t\t[", tdp, ilvl-ILV_HDRL, 0);
75153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
75253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
75353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		ilv = GO_NXT_ILV(ilv, rlen);
75453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
75553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
75653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
75753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
75853f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
759892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
76053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
76153f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
76253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
76353f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
764892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughessdatatlv_print(netdissect_options *ndo,
765892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               register const u_char * pptr, register u_int len,
766892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               uint16_t op_msk, int indent)
76753f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
768e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct forces_tlv *tlv = (const struct forces_tlv *)pptr;
76953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int rlen;
770e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	register const u_char *tdp = (const u_char *) TLV_DATA(tlv);
771892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t type;
77253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
77353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
77453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * pdatacnt_print() has ensured that len (the TLV length)
77553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * >= TLV_HDRL.
77653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
77753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	rlen = len - TLV_HDRL;
778892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(*tlv);
77953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	type = EXTRACT_16BITS(&tlv->type);
78053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (type != F_TLV_SPAD) {
781892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "Error: expecting SPARSEDATA!\n"));
78253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
78353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
78453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
785892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	return sdatailv_print(ndo, tdp, rlen, op_msk, indent);
78653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
78753f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
788892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
78953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
79053f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
79153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
79253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
793892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughespkeyitlv_print(netdissect_options *ndo,
794892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               register const u_char * pptr, register u_int len,
795892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               uint16_t op_msk, int indent)
79653f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
797e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct forces_tlv *tlv = (const struct forces_tlv *)pptr;
798e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	register const u_char *tdp = (const u_char *) TLV_DATA(tlv);
79953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	register const u_char *dp = tdp + 4;
800e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct forces_tlv *kdtlv = (const struct forces_tlv *)dp;
801892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint32_t id;
80253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib = indent_pr(indent, 0);
803892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t type, tll;
804892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	u_int invtlv;
80553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
806892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(*tdp);
80753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	id = EXTRACT_32BITS(tdp);
808892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%sKeyinfo: Key 0x%x\n", ib, id));
809892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(*kdtlv);
81053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	type = EXTRACT_16BITS(&kdtlv->type);
81153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	invtlv = tlv_valid(kdtlv, len);
81253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
81353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (invtlv) {
814892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "%s TLV type 0x%x len %d\n",
81553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       tok2str(ForCES_TLV_err, NULL, invtlv), type,
816892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       EXTRACT_16BITS(&kdtlv->length)));
81753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
81853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
81953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
82053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * At this point, tlv_valid() has ensured that the TLV
82153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * length is large enough but not too large (it doesn't
82253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * go past the end of the containing TLV).
82353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
82453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	tll = EXTRACT_16BITS(&kdtlv->length);
825e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	dp = (const u_char *) TLV_DATA(kdtlv);
826892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	return fdatatlv_print(ndo, dp, tll, op_msk, indent);
82753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
82853f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
829892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
83053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
83153f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
83253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
83353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define PTH_DESC_SIZE 12
83453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
83553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
836892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughespdatacnt_print(netdissect_options *ndo,
837892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               register const u_char * pptr, register u_int len,
838892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               uint16_t IDcnt, uint16_t op_msk, int indent)
83953f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
84053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int i;
841892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint32_t id;
84253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib = indent_pr(indent, 0);
84353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
844892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if ((op_msk & B_APPND) && ndo->ndo_vflag >= 3) {
845892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "%sTABLE APPEND\n", ib));
84653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
84753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	for (i = 0; i < IDcnt; i++) {
848892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK2(*pptr, 4);
84953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (len < 4)
85053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			goto trunc;
85153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		id = EXTRACT_32BITS(pptr);
852892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (ndo->ndo_vflag >= 3)
853892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "%sID#%02u: %d\n", ib, i + 1, id));
85453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		len -= 4;
85553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		pptr += 4;
85653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
85753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
85853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if ((op_msk & B_TRNG) || (op_msk & B_KEYIN)) {
85953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (op_msk & B_TRNG) {
860892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			uint32_t starti, endi;
86153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
86253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (len < PTH_DESC_SIZE) {
863892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "pathlength %d with key/range too short %d\n",
864892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				       len, PTH_DESC_SIZE));
86553f17a9db278d33517d9888dd77848f554522a38JP Abgrall				return -1;
86653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
86753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
86853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			pptr += sizeof(struct forces_tlv);
86953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			len -= sizeof(struct forces_tlv);
87053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
87153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			starti = EXTRACT_32BITS(pptr);
87253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			pptr += 4;
87353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			len -= 4;
87453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
87553f17a9db278d33517d9888dd77848f554522a38JP Abgrall			endi = EXTRACT_32BITS(pptr);
87653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			pptr += 4;
87753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			len -= 4;
87853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
879892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			if (ndo->ndo_vflag >= 3)
880892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "%sTable range: [%d,%d]\n", ib, starti, endi));
88153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
88253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
88353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (op_msk & B_KEYIN) {
884e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			const struct forces_tlv *keytlv;
885892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			uint16_t tll;
88653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
88753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (len < PTH_DESC_SIZE) {
888892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "pathlength %d with key/range too short %d\n",
889892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				       len, PTH_DESC_SIZE));
89053f17a9db278d33517d9888dd77848f554522a38JP Abgrall				return -1;
89153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
89253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
89353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			/* skip keyid */
89453f17a9db278d33517d9888dd77848f554522a38JP Abgrall			pptr += 4;
89553f17a9db278d33517d9888dd77848f554522a38JP Abgrall			len -= 4;
896e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			keytlv = (const struct forces_tlv *)pptr;
89753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			/* skip header */
89853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			pptr += sizeof(struct forces_tlv);
89953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			len -= sizeof(struct forces_tlv);
90053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			/* skip key content */
90153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			tll = EXTRACT_16BITS(&keytlv->length);
90253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (tll < TLV_HDRL) {
903892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "key content length %u < %u\n",
904892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					tll, TLV_HDRL));
90553f17a9db278d33517d9888dd77848f554522a38JP Abgrall				return -1;
90653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
90753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			tll -= TLV_HDRL;
90853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (len < tll) {
909892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "key content too short\n"));
91053f17a9db278d33517d9888dd77848f554522a38JP Abgrall				return -1;
91153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
91253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			pptr += tll;
91353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			len -= tll;
91453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
91553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
91653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
91753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
91853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (len) {
919e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		const struct forces_tlv *pdtlv = (const struct forces_tlv *)pptr;
920892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		uint16_t type;
921892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		uint16_t tll;
92253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		int pad = 0;
92353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		u_int aln;
924892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		u_int invtlv;
92553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
926892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK(*pdtlv);
92753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		type = EXTRACT_16BITS(&pdtlv->type);
92853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		invtlv = tlv_valid(pdtlv, len);
92953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (invtlv) {
930892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "%s Outstanding bytes %d for TLV type 0x%x TLV len %d\n",
931892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			          tok2str(ForCES_TLV_err, NULL, invtlv), len, type,
932892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			          EXTRACT_16BITS(&pdtlv->length)));
93353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			goto pd_err;
93453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
93553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		/*
93653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * At this point, tlv_valid() has ensured that the TLV
93753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * length is large enough but not too large (it doesn't
93853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * go past the end of the containing TLV).
93953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 */
94053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL;
94153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		aln = F_ALN_LEN(EXTRACT_16BITS(&pdtlv->length));
94253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (aln > EXTRACT_16BITS(&pdtlv->length)) {
94353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (aln > len) {
944892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo,
945892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				          "Invalid padded pathdata TLV type 0x%x len %d missing %d pad bytes\n",
946892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				          type, EXTRACT_16BITS(&pdtlv->length), aln - len));
94753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			} else {
94853f17a9db278d33517d9888dd77848f554522a38JP Abgrall				pad = aln - EXTRACT_16BITS(&pdtlv->length);
94953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
95053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
95153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (pd_valid(type)) {
95253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			const struct pdata_ops *ops = get_forces_pd(type);
95353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
954892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			if (ndo->ndo_vflag >= 3 && ops->v != F_TLV_PDAT) {
95553f17a9db278d33517d9888dd77848f554522a38JP Abgrall				if (pad)
956892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					ND_PRINT((ndo, "%s  %s (Length %d DataLen %d pad %d Bytes)\n",
957892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					          ib, ops->s, EXTRACT_16BITS(&pdtlv->length), tll, pad));
95853f17a9db278d33517d9888dd77848f554522a38JP Abgrall				else
959892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					ND_PRINT((ndo, "%s  %s (Length %d DataLen %d Bytes)\n",
960892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					          ib, ops->s, EXTRACT_16BITS(&pdtlv->length), tll));
96153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
96253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
963892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			chk_op_type(ndo, type, op_msk, ops->op_msk);
96453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
965892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			if (ops->print(ndo, (const u_char *)pdtlv,
96653f17a9db278d33517d9888dd77848f554522a38JP Abgrall					tll + pad + TLV_HDRL, op_msk,
96753f17a9db278d33517d9888dd77848f554522a38JP Abgrall					indent + 2) == -1)
96853f17a9db278d33517d9888dd77848f554522a38JP Abgrall				return -1;
96953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			len -= (TLV_HDRL + pad + tll);
97053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		} else {
971892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Invalid path data content type 0x%x len %d\n",
972892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			       type, EXTRACT_16BITS(&pdtlv->length)));
97353f17a9db278d33517d9888dd77848f554522a38JP Abgrallpd_err:
97453f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (EXTRACT_16BITS(&pdtlv->length)) {
975892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                hex_print_with_offset(ndo, "Bad Data val\n\t  [",
97653f17a9db278d33517d9888dd77848f554522a38JP Abgrall						      pptr, len, 0);
977892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "]\n"));
97853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
97953f17a9db278d33517d9888dd77848f554522a38JP Abgrall				return -1;
98053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
98153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
98253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
98353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return len;
98453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
98553f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
986892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
98753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
98853f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
98953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
99053f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
991892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughespdata_print(netdissect_options *ndo,
992892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            register const u_char * pptr, register u_int len,
993892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            uint16_t op_msk, int indent)
99453f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
995e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct pathdata_h *pdh = (const struct pathdata_h *)pptr;
99653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib = indent_pr(indent, 0);
99753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int minsize = 0;
99853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int more_pd = 0;
999892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t idcnt = 0;
100053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1001892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(*pdh);
100253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (len < sizeof(struct pathdata_h))
100353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		goto trunc;
1004892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 3) {
1005892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n%sPathdata: Flags 0x%x ID count %d\n",
1006892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       ib, EXTRACT_16BITS(&pdh->pflags), EXTRACT_16BITS(&pdh->pIDcnt)));
100753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
100853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
100953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (EXTRACT_16BITS(&pdh->pflags) & F_SELKEY) {
101053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		op_msk |= B_KEYIN;
101153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
101253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
101353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* Table GET Range operation */
101453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (EXTRACT_16BITS(&pdh->pflags) & F_SELTABRANGE) {
101553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		op_msk |= B_TRNG;
101653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
101753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* Table SET append operation */
101853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (EXTRACT_16BITS(&pdh->pflags) & F_TABAPPEND) {
101953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		op_msk |= B_APPND;
102053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
102153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
102253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	pptr += sizeof(struct pathdata_h);
102353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	len -= sizeof(struct pathdata_h);
102453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	idcnt = EXTRACT_16BITS(&pdh->pIDcnt);
102553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	minsize = idcnt * 4;
102653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (len < minsize) {
1027892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\t\t\ttruncated IDs expected %uB got %uB\n", minsize,
1028892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       len));
1029892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		hex_print_with_offset(ndo, "\t\t\tID Data[", pptr, len, 0);
1030892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "]\n"));
103153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
103253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
103353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
103453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if ((op_msk & B_TRNG) && (op_msk & B_KEYIN)) {
1035892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\t\t\tIllegal to have both Table ranges and keys\n"));
103653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
103753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
103853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1039892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	more_pd = pdatacnt_print(ndo, pptr, len, idcnt, op_msk, indent);
104053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (more_pd > 0) {
104153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		int consumed = len - more_pd;
104253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		pptr += consumed;
1043892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		len = more_pd;
104453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		/* XXX: Argh, recurse some more */
1045892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		return recpdoptlv_print(ndo, pptr, len, op_msk, indent+1);
104653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	} else
104753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return 0;
104853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
104953f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
1050892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
105153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
105253f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
105353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
105453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1055892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesgenoptlv_print(netdissect_options *ndo,
1056892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               register const u_char * pptr, register u_int len,
1057892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               uint16_t op_msk, int indent)
105853f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
1059e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct forces_tlv *pdtlv = (const struct forces_tlv *)pptr;
1060892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t type;
106153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int tll;
1062892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	u_int invtlv;
106353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib = indent_pr(indent, 0);
106453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1065892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(*pdtlv);
106653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	type = EXTRACT_16BITS(&pdtlv->type);
106753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL;
106853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	invtlv = tlv_valid(pdtlv, len);
1069892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "genoptlvprint - %s TLV type 0x%x len %d\n",
1070892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	       tok2str(ForCES_TLV, NULL, type), type, EXTRACT_16BITS(&pdtlv->length)));
107153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (!invtlv) {
107253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		/*
107353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * At this point, tlv_valid() has ensured that the TLV
107453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * length is large enough but not too large (it doesn't
107553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * go past the end of the containing TLV).
107653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 */
1077e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		register const u_char *dp = (const u_char *) TLV_DATA(pdtlv);
107853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (!ttlv_valid(type)) {
1079892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "%s TLV type 0x%x len %d\n",
108053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			       tok2str(ForCES_TLV_err, NULL, invtlv), type,
1081892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			       EXTRACT_16BITS(&pdtlv->length)));
108253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return -1;
108353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
1084892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (ndo->ndo_vflag >= 3)
1085892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "%s%s, length %d (data length %d Bytes)",
108653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			       ib, tok2str(ForCES_TLV, NULL, type),
1087892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			       EXTRACT_16BITS(&pdtlv->length), tll));
108853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1089892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		return pdata_print(ndo, dp, tll, op_msk, indent + 1);
109053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	} else {
1091892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\t\t\tInvalid ForCES TLV type=%x", type));
109253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
109353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
109453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
109553f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
1096892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
109753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
109853f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
109953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
110053f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1101892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesrecpdoptlv_print(netdissect_options *ndo,
1102892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 register const u_char * pptr, register u_int len,
1103892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 uint16_t op_msk, int indent)
110453f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
1105e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct forces_tlv *pdtlv = (const struct forces_tlv *)pptr;
110653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int tll;
1107892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	u_int invtlv;
1108892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t type;
110953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	register const u_char *dp;
111053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib;
111153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
111253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	while (len != 0) {
1113892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK(*pdtlv);
111453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		invtlv = tlv_valid(pdtlv, len);
111553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (invtlv) {
111653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
111753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
111853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
111953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		/*
112053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * At this point, tlv_valid() has ensured that the TLV
112153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * length is large enough but not too large (it doesn't
112253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * go past the end of the containing TLV).
112353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 */
112453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		ib = indent_pr(indent, 0);
112553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		type = EXTRACT_16BITS(&pdtlv->type);
1126e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		dp = (const u_char *) TLV_DATA(pdtlv);
112753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL;
112853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1129892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (ndo->ndo_vflag >= 3)
1130892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "%s%s, length %d (data encapsulated %d Bytes)",
1131892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			          ib, tok2str(ForCES_TLV, NULL, type),
1132892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			          EXTRACT_16BITS(&pdtlv->length),
1133892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			          EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL));
113453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1135892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (pdata_print(ndo, dp, tll, op_msk, indent + 1) == -1)
113653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return -1;
113753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		pdtlv = GO_NXT_TLV(pdtlv, len);
113853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
113953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
114053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (len) {
1141892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo,
1142892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		          "\n\t\tMessy PATHDATA TLV header, type (0x%x)\n\t\texcess of %d Bytes ",
1143892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		          EXTRACT_16BITS(&pdtlv->type), len - EXTRACT_16BITS(&pdtlv->length)));
114453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
114553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
114653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
114753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
114853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
114953f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
1150892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
115153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
115253f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
115353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
115453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1155892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesinvoptlv_print(netdissect_options *ndo,
1156892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               register const u_char * pptr, register u_int len,
1157892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               uint16_t op_msk _U_, int indent)
115853f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
115953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib = indent_pr(indent, 1);
116053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1161892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 3) {
1162892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "%sData[", &ib[1]));
1163892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		hex_print_with_offset(ndo, ib, pptr, len, 0);
1164892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "%s]\n", ib));
116553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
116653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
116753f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
116853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
116953f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1170892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesotlv_print(netdissect_options *ndo,
1171892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes           const struct forces_tlv *otlv, uint16_t op_msk _U_, int indent)
117253f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
117353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int rc = 0;
1174e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	register const u_char *dp = (const u_char *) TLV_DATA(otlv);
1175892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t type;
117653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int tll;
117753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib = indent_pr(indent, 0);
117853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	const struct optlv_h *ops;
117953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
118053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
118153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * lfbselect_print() has ensured that EXTRACT_16BITS(&otlv->length)
118253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * >= TLV_HDRL.
118353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
1184892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(*otlv);
118553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	type = EXTRACT_16BITS(&otlv->type);
118653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	tll = EXTRACT_16BITS(&otlv->length) - TLV_HDRL;
118753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	ops = get_forces_optlv_h(type);
1188892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 3) {
1189892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "%sOper TLV %s(0x%x) length %d\n", ib, ops->s, type,
1190892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       EXTRACT_16BITS(&otlv->length)));
119153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
119253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* rest of ops must at least have 12B {pathinfo} */
119353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (tll < OP_MIN_SIZ) {
1194892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\t\tOper TLV %s(0x%x) length %d\n", ops->s, type,
1195892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       EXTRACT_16BITS(&otlv->length)));
1196892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\t\tTruncated data size %d minimum required %d\n", tll,
1197892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       OP_MIN_SIZ));
1198892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		return invoptlv_print(ndo, dp, tll, ops->op_msk, indent);
119953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
120053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
120153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1202892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	/* XXX - do anything with ops->flags? */
1203892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if(ops->print) {
1204892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                rc = ops->print(ndo, dp, tll, ops->op_msk, indent + 1);
1205892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        }
120653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return rc;
120753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
120853f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
1209892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
121053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
121153f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
121253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
121353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ASTDLN	4
121453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ASTMCD	255
121553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1216892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesasttlv_print(netdissect_options *ndo,
1217892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes             register const u_char * pptr, register u_int len,
1218892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes             uint16_t op_msk _U_, int indent)
121953f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
1220892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint32_t rescode;
122153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int dlen;
122253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib = indent_pr(indent, 0);
122353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
122453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
122553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * forces_type_print() has ensured that len (the TLV length)
122653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * >= TLV_HDRL.
122753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
122853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	dlen = len - TLV_HDRL;
122953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (dlen != ASTDLN) {
1230892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "illegal ASTresult-TLV: %d bytes!\n", dlen));
123153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
123253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
1233892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(*pptr, 4);
123453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	rescode = EXTRACT_32BITS(pptr);
123553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (rescode > ASTMCD) {
1236892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "illegal ASTresult result code: %d!\n", rescode));
123753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
123853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
123953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1240892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 3) {
1241892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "Teardown reason:\n%s", ib));
124253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		switch (rescode) {
124353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case 0:
1244892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Normal Teardown"));
124553f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
124653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case 1:
1247892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Loss of Heartbeats"));
124853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
124953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case 2:
1250892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Out of bandwidth"));
125153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
125253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case 3:
1253892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Out of Memory"));
125453f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
125553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case 4:
1256892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Application Crash"));
125753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
125853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		default:
1259892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Unknown Teardown reason"));
126053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
126153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
1262892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "(%x)\n%s", rescode, ib));
126353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
126453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
126553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
126653f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
1267892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
126853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
126953f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
127053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
127153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ASRDLN	4
127253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ASRMCD	3
127353f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1274892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesasrtlv_print(netdissect_options *ndo,
1275892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes             register const u_char * pptr, register u_int len,
1276892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes             uint16_t op_msk _U_, int indent)
127753f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
1278892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint32_t rescode;
127953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int dlen;
128053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib = indent_pr(indent, 0);
128153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
128253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
128353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * forces_type_print() has ensured that len (the TLV length)
128453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * >= TLV_HDRL.
128553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
128653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	dlen = len - TLV_HDRL;
128753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (dlen != ASRDLN) {	/* id, instance, oper tlv */
1288892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "illegal ASRresult-TLV: %d bytes!\n", dlen));
128953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
129053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
1291892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(*pptr, 4);
129253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	rescode = EXTRACT_32BITS(pptr);
129353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
129453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (rescode > ASRMCD) {
1295892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "illegal ASRresult result code: %d!\n", rescode));
129653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
129753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
129853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1299892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 3) {
1300892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n%s", ib));
130153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		switch (rescode) {
130253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case 0:
1303892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Success "));
130453f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
130553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case 1:
1306892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "FE ID invalid "));
130753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
130853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case 2:
1309892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "permission denied "));
131053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
131153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		default:
1312892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Unknown "));
131353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
131453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
1315892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "(%x)\n%s", rescode, ib));
131653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
131753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
131853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
131953f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
1320892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
132153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
132253f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
132353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
132453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#if 0
132553f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
132653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * XXX - not used.
132753f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
132853f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1329892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesgentltlv_print(netdissect_options *ndo,
1330892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               register const u_char * pptr _U_, register u_int len,
1331892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               uint16_t op_msk _U_, int indent _U_)
133253f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
133353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int dlen = len - TLV_HDRL;
133453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
133553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (dlen < 4) {		/* at least 32 bits must exist */
1336892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "truncated TLV: %d bytes missing! ", 4 - dlen));
133753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
133853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
133953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
134053f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
134153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#endif
134253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
134353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define RD_MIN 8
134453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
134553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1346892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesprint_metailv(netdissect_options *ndo,
1347892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes              register const u_char * pptr, uint16_t op_msk _U_, int indent)
134853f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
134953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int rlen;
135053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib = indent_pr(indent, 0);
135153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* XXX: check header length */
1352e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct forces_ilv *ilv = (const struct forces_ilv *)pptr;
135353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
135453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
135553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * print_metatlv() has ensured that len (what remains in the
135653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * ILV) >= ILV_HDRL.
135753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
135853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	rlen = EXTRACT_32BITS(&ilv->length) - ILV_HDRL;
1359892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(*ilv);
1360892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%sMetaID 0x%x length %d\n", ib, EXTRACT_32BITS(&ilv->type),
1361892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	       EXTRACT_32BITS(&ilv->length)));
1362892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 3) {
1363892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		hex_print_with_offset(ndo, "\t\t[", ILV_DATA(ilv), rlen, 0);
1364892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, " ]\n"));
136553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
136653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
136753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
136853f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
1369892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
137053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
137153f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
137253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
137353f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1374892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesprint_metatlv(netdissect_options *ndo,
1375892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes              register const u_char * pptr, register u_int len,
1376892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes              uint16_t op_msk _U_, int indent)
137753f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
137853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int dlen;
137953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib = indent_pr(indent, 0);
138053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int rlen;
1381e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct forces_ilv *ilv = (const struct forces_ilv *)pptr;
138253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int invilv;
138353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
138453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
138553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * redirect_print() has ensured that len (what remains in the
138653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * TLV) >= TLV_HDRL.
138753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
138853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	dlen = len - TLV_HDRL;
138953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	rlen = dlen;
1390892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "\n%s METADATA length %d \n", ib, rlen));
139153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	while (rlen != 0) {
1392892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK(*ilv);
139353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		invilv = ilv_valid(ilv, rlen);
139453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (invilv) {
139553f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
139653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
139753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
139853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		/*
139953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * At this point, ilv_valid() has ensured that the ILV
140053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * length is large enough but not too large (it doesn't
140153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * go past the end of the containing TLV).
140253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 */
1403e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		print_metailv(ndo, (const u_char *) ilv, 0, indent + 1);
140453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		ilv = GO_NXT_ILV(ilv, rlen);
140553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
140653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
140753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
140853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
140953f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
1410892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
141153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
141253f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
141353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
141453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
141553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1416892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesprint_reddata(netdissect_options *ndo,
1417892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes              register const u_char * pptr, register u_int len,
1418e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes              uint16_t op_msk _U_, int indent)
141953f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
142053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int dlen;
142153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib = indent_pr(indent, 0);
142253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int rlen;
142353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
142453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	dlen = len - TLV_HDRL;
142553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	rlen = dlen;
1426892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "\n%s Redirect Data length %d \n", ib, rlen));
142753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1428892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 3) {
1429892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\t\t["));
1430892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		hex_print_with_offset(ndo, "\n\t\t", pptr, rlen, 0);
1431892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\t\t]"));
143253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
143353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
143453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
143553f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
143653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
143753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1438892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesredirect_print(netdissect_options *ndo,
1439892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               register const u_char * pptr, register u_int len,
1440892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               uint16_t op_msk _U_, int indent)
144153f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
1442e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const struct forces_tlv *tlv = (const struct forces_tlv *)pptr;
144353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int dlen;
144453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int rlen;
1445892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	u_int invtlv;
144653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
144753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
144853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * forces_type_print() has ensured that len (the TLV length)
144953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * >= TLV_HDRL.
145053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
145153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	dlen = len - TLV_HDRL;
145253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (dlen <= RD_MIN) {
1453892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\t\ttruncated Redirect TLV: %d bytes missing! ",
1454892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       RD_MIN - dlen));
145553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
145653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
145753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
145853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	rlen = dlen;
145953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	indent += 1;
146053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	while (rlen != 0) {
1461892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK(*tlv);
146253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		invtlv = tlv_valid(tlv, rlen);
146353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (invtlv) {
1464892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Bad Redirect data\n"));
146553f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
146653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
146753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
146853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		/*
146953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * At this point, tlv_valid() has ensured that the TLV
147053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * length is large enough but not too large (it doesn't
147153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * go past the end of the containing TLV).
147253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 */
147353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (EXTRACT_16BITS(&tlv->type) == F_TLV_METD) {
1474e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			print_metatlv(ndo, (const u_char *) TLV_DATA(tlv),
147553f17a9db278d33517d9888dd77848f554522a38JP Abgrall				      EXTRACT_16BITS(&tlv->length), 0, indent);
147653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		} else if ((EXTRACT_16BITS(&tlv->type) == F_TLV_REDD)) {
1477e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			print_reddata(ndo, (const u_char *) TLV_DATA(tlv),
147853f17a9db278d33517d9888dd77848f554522a38JP Abgrall				      EXTRACT_16BITS(&tlv->length), 0, indent);
147953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		} else {
1480892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Unknown REDIRECT TLV 0x%x len %d\n",
148153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			       EXTRACT_16BITS(&tlv->type),
1482892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			       EXTRACT_16BITS(&tlv->length)));
148353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
148453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
148553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		tlv = GO_NXT_TLV(tlv, rlen);
148653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
148753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
148853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (rlen) {
1489892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo,
1490892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		          "\n\t\tMessy Redirect TLV header, type (0x%x)\n\t\texcess of %d Bytes ",
1491892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		          EXTRACT_16BITS(&tlv->type),
1492892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		          rlen - EXTRACT_16BITS(&tlv->length)));
149353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
149453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
149553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
149653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
149753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
149853f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
1499892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
150053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
150153f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
150253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
150353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define OP_OFF 8
150453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define OP_MIN 12
150553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
150653f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1507892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hugheslfbselect_print(netdissect_options *ndo,
1508892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                register const u_char * pptr, register u_int len,
1509892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                uint16_t op_msk, int indent)
151053f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
151153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	const struct forces_lfbsh *lfbs;
151253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	const struct forces_tlv *otlv;
151353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char *ib = indent_pr(indent, 0);
151453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int dlen;
151553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int rlen;
1516892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	u_int invtlv;
151753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
151853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
151953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * forces_type_print() has ensured that len (the TLV length)
152053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * >= TLV_HDRL.
152153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
152253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	dlen = len - TLV_HDRL;
152353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (dlen <= OP_MIN) {	/* id, instance, oper tlv header .. */
1524892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\t\ttruncated lfb selector: %d bytes missing! ",
1525892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       OP_MIN - dlen));
152653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
152753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
152853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
152953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
153053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * At this point, we know that dlen > OP_MIN; OP_OFF < OP_MIN, so
153153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * we also know that it's > OP_OFF.
153253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
153353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	rlen = dlen - OP_OFF;
153453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
153553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	lfbs = (const struct forces_lfbsh *)pptr;
1536892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(*lfbs);
1537892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 3) {
1538892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n%s%s(Classid %x) instance %x\n",
153953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       ib, tok2str(ForCES_LFBs, NULL, EXTRACT_32BITS(&lfbs->class)),
154053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       EXTRACT_32BITS(&lfbs->class),
1541892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       EXTRACT_32BITS(&lfbs->instance)));
154253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
154353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1544e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	otlv = (const struct forces_tlv *)(lfbs + 1);
154553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
154653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	indent += 1;
154753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	while (rlen != 0) {
1548892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK(*otlv);
154953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		invtlv = tlv_valid(otlv, rlen);
155053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (invtlv)
155153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
155253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
155353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		/*
155453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * At this point, tlv_valid() has ensured that the TLV
155553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * length is large enough but not too large (it doesn't
155653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * go past the end of the containing TLV).
155753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 */
155853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (op_valid(EXTRACT_16BITS(&otlv->type), op_msk)) {
1559892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			otlv_print(ndo, otlv, 0, indent);
156053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		} else {
1561892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			if (ndo->ndo_vflag < 3)
1562892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "\n"));
1563892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo,
1564892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			          "\t\tINValid oper-TLV type 0x%x length %d for this ForCES message\n",
1565892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			          EXTRACT_16BITS(&otlv->type), EXTRACT_16BITS(&otlv->length)));
1566e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			invoptlv_print(ndo, (const u_char *)otlv, rlen, 0, indent);
156753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
156853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		otlv = GO_NXT_TLV(otlv, rlen);
156953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
157053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
157153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (rlen) {
1572892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo,
1573892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		          "\n\t\tMessy oper TLV header, type (0x%x)\n\t\texcess of %d Bytes ",
1574892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		          EXTRACT_16BITS(&otlv->type), rlen - EXTRACT_16BITS(&otlv->length)));
157553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
157653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
157753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
157853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
157953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
158053f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
1581892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
158253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
158353f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
158453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
158553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1586892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesforces_type_print(netdissect_options *ndo,
1587892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                  register const u_char * pptr, const struct forcesh *fhdr _U_,
1588892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                  register u_int mlen, const struct tom_h *tops)
158953f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
159053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	const struct forces_tlv *tltlv;
159153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int rlen;
1592892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	u_int invtlv;
159353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int rc = 0;
159453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int ttlv = 0;
159553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
159653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
159753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * forces_print() has already checked that mlen >= ForCES_HDRL
159853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * by calling ForCES_HLN_VALID().
159953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
160053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	rlen = mlen - ForCES_HDRL;
160153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
160253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (rlen > TLV_HLN) {
160353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (tops->flags & ZERO_TTLV) {
1604892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "<0x%x>Illegal Top level TLV!\n", tops->flags));
160553f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return -1;
160653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
160753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	} else {
160853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (tops->flags & ZERO_MORE_TTLV)
160953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return 0;
161053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (tops->flags & ONE_MORE_TTLV) {
1611892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "\tTop level TLV Data missing!\n"));
161253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return -1;
161353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
161453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
161553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
161653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (tops->flags & ZERO_TTLV) {
161753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return 0;
161853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
161953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
162053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	ttlv = tops->flags >> 4;
162153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	tltlv = GET_TOP_TLV(pptr);
162253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
162353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*XXX: 15 top level tlvs will probably be fine
162453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	   You are nuts if you send more ;-> */
162553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	while (rlen != 0) {
1626892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK(*tltlv);
162753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		invtlv = tlv_valid(tltlv, rlen);
162853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (invtlv)
162953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
163053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
163153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		/*
163253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * At this point, tlv_valid() has ensured that the TLV
163353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * length is large enough but not too large (it doesn't
163453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * go past the end of the packet).
163553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 */
163653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (!ttlv_valid(EXTRACT_16BITS(&tltlv->type))) {
1637892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "\n\tInvalid ForCES Top TLV type=0x%x",
1638892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			       EXTRACT_16BITS(&tltlv->type)));
163953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return -1;
164053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
164153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1642892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (ndo->ndo_vflag >= 3)
1643892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "\t%s, length %d (data length %d Bytes)",
164453f17a9db278d33517d9888dd77848f554522a38JP Abgrall			       tok2str(ForCES_TLV, NULL, EXTRACT_16BITS(&tltlv->type)),
164553f17a9db278d33517d9888dd77848f554522a38JP Abgrall			       EXTRACT_16BITS(&tltlv->length),
1646892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			       EXTRACT_16BITS(&tltlv->length) - TLV_HDRL));
164753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1648e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		rc = tops->print(ndo, (const u_char *) TLV_DATA(tltlv),
164953f17a9db278d33517d9888dd77848f554522a38JP Abgrall				 EXTRACT_16BITS(&tltlv->length), tops->op_msk, 9);
165053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (rc < 0) {
165153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return -1;
165253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
165353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		tltlv = GO_NXT_TLV(tltlv, rlen);
165453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		ttlv--;
165553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (ttlv <= 0)
165653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
165753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
165853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/*
165953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * XXX - if ttlv != 0, does that mean that the packet was too
166053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 * short, and didn't have *enough* TLVs in it?
166153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	 */
166253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (rlen) {
1663892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\tMess TopTLV header: min %u, total %d advertised %d ",
1664892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       TLV_HDRL, rlen, EXTRACT_16BITS(&tltlv->length)));
166553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return -1;
166653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
166753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
166853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 0;
166953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
167053f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
1671892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
167253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
167353f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
167453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
167553f17a9db278d33517d9888dd77848f554522a38JP Abgrallvoid
1676892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesforces_print(netdissect_options *ndo,
1677892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes             register const u_char * pptr, register u_int len)
167853f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
167953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	const struct forcesh *fhdr;
168053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int mlen;
1681892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint32_t flg_raw;
168253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	const struct tom_h *tops;
168353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int rc = 0;
168453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
168553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	fhdr = (const struct forcesh *)pptr;
1686892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(*fhdr);
168753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (!tom_valid(fhdr->fm_tom)) {
1688892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "Invalid ForCES message type %d\n", fhdr->fm_tom));
168953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		goto error;
169053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
169153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
169253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	mlen = ForCES_BLN(fhdr);
169353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
169453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	tops = get_forces_tom(fhdr->fm_tom);
169553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (tops->v == TOM_RSVD) {
1696892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\tUnknown ForCES message type=0x%x", fhdr->fm_tom));
169753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		goto error;
169853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
169953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1700892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "\n\tForCES %s ", tops->s));
170153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (!ForCES_HLN_VALID(mlen, len)) {
1702892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo,
1703892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		          "Illegal ForCES pkt len - min %u, total recvd %d, advertised %d ",
1704892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		          ForCES_HDRL, len, ForCES_BLN(fhdr)));
170553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		goto error;
170653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
170753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1708892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(*(pptr + 20), 4);
170953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	flg_raw = EXTRACT_32BITS(pptr + 20);
1710892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 1) {
1711892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\tForCES Version %d len %uB flags 0x%08x ",
1712892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       ForCES_V(fhdr), mlen, flg_raw));
1713892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo,
1714892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       "\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIx64,
171553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       ForCES_SID(fhdr), ForCES_node(ForCES_SID(fhdr)),
171653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       ForCES_DID(fhdr), ForCES_node(ForCES_DID(fhdr)),
1717892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       EXTRACT_64BITS(fhdr->fm_cor)));
171853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
171953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
1720892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 2) {
1721892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo,
1722892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		     "\n\tForCES flags:\n\t  %s(0x%x), prio=%d, %s(0x%x),\n\t  %s(0x%x), %s(0x%x)\n",
1723892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		     tok2str(ForCES_ACKs, "ACKUnknown", ForCES_ACK(fhdr)),
1724892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		     ForCES_ACK(fhdr),
172553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		     ForCES_PRI(fhdr),
1726892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		     tok2str(ForCES_EMs, "EMUnknown", ForCES_EM(fhdr)),
1727892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		     ForCES_EM(fhdr),
1728892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		     tok2str(ForCES_ATs, "ATUnknown", ForCES_AT(fhdr)),
1729892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		     ForCES_AT(fhdr),
1730892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		     tok2str(ForCES_TPs, "TPUnknown", ForCES_TP(fhdr)),
1731892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		     ForCES_TP(fhdr)));
1732892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo,
1733892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		     "\t  Extra flags: rsv(b5-7) 0x%x rsv(b13-31) 0x%x\n",
1734892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		     ForCES_RS1(fhdr), ForCES_RS2(fhdr)));
173553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
1736892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	rc = forces_type_print(ndo, pptr, fhdr, mlen, tops);
173753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (rc < 0) {
173853f17a9db278d33517d9888dd77848f554522a38JP Abgrallerror:
1739892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		hex_print_with_offset(ndo, "\n\t[", pptr, len, 0);
1740892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\t]"));
174153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		return;
174253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
174353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1744892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_vflag >= 4) {
1745892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\t  Raw ForCES message\n\t ["));
1746892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		hex_print_with_offset(ndo, "\n\t ", pptr, len, 0);
1747892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\t ]"));
174853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
1749892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "\n"));
175053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return;
175153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
175253f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
1753892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s", tstr));
175453f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
1755892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes/*
1756892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * Local Variables:
1757892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * c-style: whitesmith
1758892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * c-basic-offset: 8
1759892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * End:
1760892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes */
1761