aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-pcep.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2007-12-28 23:08:48 +0000
committerGuy Harris <guy@alum.mit.edu>2007-12-28 23:08:48 +0000
commit39dfc7b4db00ed5d89a12dbeb9e2f235b02927b7 (patch)
tree868bf79418e476fdde3575fe2bbdd55f8df0853d /epan/dissectors/packet-pcep.c
parenta930d7df28772eb22dc3641b9b529a92fd15d66c (diff)
Rename packet-pce.c to packet-pcep.c to match the protocol name.
svn path=/trunk/; revision=23965
Diffstat (limited to 'epan/dissectors/packet-pcep.c')
-rw-r--r--epan/dissectors/packet-pcep.c2345
1 files changed, 2345 insertions, 0 deletions
diff --git a/epan/dissectors/packet-pcep.c b/epan/dissectors/packet-pcep.c
new file mode 100644
index 0000000000..09a504e18c
--- /dev/null
+++ b/epan/dissectors/packet-pcep.c
@@ -0,0 +1,2345 @@
+/* packet-pcep.c
+ * Routines for PCEP packet disassembly
+ * draft-ietf-pce-pcep-09
+ * draft-ietf-pce-pcep-xro-02
+ * See also RFC 4655 and RFC 4657
+ *
+ * (c) Copyright 2007 Silvia Cristina Tejedor <silviacristina.tejedor@gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/emem.h>
+#include <epan/dissectors/packet-tcp.h>
+
+#include <epan/prefs.h>
+#include "packet-frame.h"
+
+/*differents types of objects*/
+#define PCEP_OPEN_OBJ 1
+#define PCEP_RP_OBJ 2
+#define PCEP_NO_PATH_OBJ 3
+#define PCEP_END_POINT_OBJ 4
+#define PCEP_BANDWIDTH_OBJ 5
+#define PCEP_METRIC_OBJ 6
+#define PCEP_EXPLICIT_ROUTE_OBJ 7
+#define PCEP_RECORD_ROUTE_OBJ 8
+#define PCEP_LSPA_OBJ 9
+#define PCEP_IRO_OBJ 10
+#define PCEP_SVEC_OBJ 11
+#define PCEP_NOTIFICATION_OBJ 12
+#define PCEP_PCEP_ERROR_OBJ 13
+#define PCEP_LOAD_BALANCING_OBJ 14
+#define PCEP_CLOSE_OBJ 15
+#define NO_DEFINED_OBJ 16
+#define PCEP_XRO_OBJ 17
+
+/*Subobjects of EXPLICIT ROUTE Object*/
+#define PCEP_SUB_IPv4 1
+#define PCEP_SUB_IPv6 2
+#define PCEP_SUB_LABEL_CONTROL 3
+#define PCEP_SUB_UNNUMB_INTERFACE_ID 4
+#define PCEP_SUB_SRLG 5
+#define PCEP_SUB_AUTONOMOUS_SYS_NUM 32
+#define PCEP_SUB_EXRS 33
+#define PCEP_SUB_AUTONOMOUS_SYS_NUM_XRO 4
+#define PCEP_SUB_UNNUMB_INTERFACE_ID_XRO 3
+
+/*Possible values of the NI in the NO-PATH object*/
+#define NO_SATISFYING 0
+#define CHAIN_BROKEN 1
+
+/*Possible values of "Type (T)" in the METRIC object */
+#define NO_DEFINED 0
+#define IGP_METRIC 1
+#define TE_METRIC 2
+#define HOP_COUNTS 3
+
+/*Possible values of L in the ERO and IRO objects */
+#define STRICT_HOP 0
+#define LOOSE_HOP 1
+
+/*Possible values of U in the ERO and RRO objects */
+#define DOWNSTREAM_LABEL 0
+#define UPSTREAM_LABEL 1
+
+/*Possible values of Notification Type */
+#define NOT_REQ_CANCEL 1
+#define PCEP_CONGESTION 2
+
+/*Possible values of Notification Value for NT=1*/
+#define NOTI_PCC_CANCEL_REQ 1
+#define NOTI_PCE_CANCEL_REQ 2
+
+/*Possible values of Notification Value for NT=2*/
+#define NOTI_PCE_CONGEST 1
+#define NOTI_PCE_NO_CONGEST 2
+
+/*Possible types of errors */
+#define ESTABLISH_FAILURE 1
+#define CAP_NOT_SUPPORTED 2
+#define UNKNOWN_OBJ 3
+#define NOT_SUPP_OBJ 4
+#define POLICY_VIOLATION 5
+#define MANDATORY_OBJ_MIS 6
+#define SYNCH_PCREQ_MIS 7
+#define UNKNOWN_REQ_REF 8
+#define ATTEMPT_2_SESSION 9
+#define UNRECO_IRO_SUBOBJ 11
+#define UNRECO_EXRS_SUBOBJ 12
+
+/*Different values of errors type=1*/
+#define RX_MALFORM_PKT 1
+#define NO_OPEN_MSG 2
+#define UNACEP_NO_NEGO_SSESION 3
+#define UNACEP_NEG_SESSION 4
+#define TWO_OPEN_MSG_UNACEP 5
+#define RX_PCEPERR_UNACEP_SESSION 6
+#define NO_KEEPALIVE_PCEPERR 7
+
+/*Different values of errors type=3*/
+#define UNRECON_OBJ_CLASS 1
+#define UNRECON_OBJ_TYPE 2
+
+/*Different values of errors type=4*/
+#define NO_SUPP_OBJ 1
+#define NO_SUPP_TYPE 2
+
+/*Different values of errors type=5*/
+#define C_METRIC_SET 1
+#define O_OBJ_SET 2
+
+/*Different values of errors type=6*/
+#define RP_OBJ_MISS 1
+#define RRO_OBJ_MISS 2
+#define END_POINT_OBJ_MISS 3
+
+/*Different values of Reason in the CLOSE object */
+#define NO_EXP_PROV 1
+#define DEADTIME_PROV 2
+#define RECEP_MALFORM_MSG 3
+
+/*Different values of Attribute in the XRO object */
+#define ATTR_INTERFACE 0
+#define ATTR_NODE 1
+#define ATTR_SRLG 2
+
+/*Mask for the flags of HEADER of Messages*/
+#define PCEP_HDR_MSG_RESERVED 0x1f
+
+/*Mask for the type of HEADER of Objects*/
+#define MASK_OBJ_TYPE 0xF0
+
+/*Mask for the flags of HEADER of Objects*/
+#define PCEP_HDR_OBJ_RESERVED 0x0C
+#define PCEP_HDR_OBJ_P 0x02
+#define PCEP_HDR_OBJ_I 0x01
+
+/*Mask for the flags of OPEN Object*/
+#define PCEP_OPEN_RES 0x1F
+
+/*Mask for the flags of RP Object*/
+#define PCEP_RP_PRI 0x000007
+#define PCEP_RP_R 0x000008
+#define PCEP_RP_B 0x000010
+#define PCEP_RP_O 0x000020
+#define PCEP_RP_RESERVED 0xFFFFC0
+
+/*Mask for the flags of NO PATH Object*/
+#define PCEP_NO_PATH_C 0x8000
+
+/*Mask for the flags of METRIC Object*/
+#define PCEP_METRIC_C 0x01
+#define PCEP_METRIC_B 0x02
+
+/*Mask for the flags of LSPA Object*/
+#define PCEP_LSPA_L 0x01
+
+/* Mask to differentiate the value of L and Type (Explicit Object)*/
+#define Mask_L 0x80
+#define Mask_Type 0x7f
+
+#define TCP_PORT_PCEP 1010
+
+#define IPv4 1
+#define IPv6 2
+
+/*Mask for the flags os SVEC Object*/
+#define PCEP_SVEC_L 0x000001
+#define PCEP_SVEC_N 0x000002
+#define PCEP_SVEC_S 0x000004
+
+/*Mask for the flags of XRO Object*/
+#define PCEP_XRO_F 0x0001
+
+/*Mask for the flags of IPv4, IPv6 and UNnumbered InterfaceID Subobjects of RRO Object*/
+#define PCEP_SUB_LPA 0x01
+#define PCEP_SUB_LPU 0x02
+
+/*Mask for the flags of Label SubObject*/
+#define PCEP_SUB_LABEL_GL 0x01
+
+
+static int proto_pcep = -1;
+static gint ett_pcep = -1;
+static gint ett_pcep_hdr = -1;
+static gint pcep_hdr_msg_flags_reserved= -1;
+static gint pcep_hdr_obj_flags_reserved= -1;
+static gint pcep_hdr_obj_flags_p= -1;
+static gint pcep_hdr_obj_flags_i= -1;
+static gint ett_pcep_obj_open = -1;
+static gint pcep_open_flags_res = -1;
+static gint ett_pcep_obj_request_parameters = -1;
+static gint pcep_rp_flags_pri = -1;
+static gint pcep_rp_flags_r = -1;
+static gint pcep_rp_flags_b = -1;
+static gint pcep_rp_flags_o = -1;
+static gint pcep_rp_flags_reserved = -1;
+static gint ett_pcep_obj_no_path = -1;
+static gint pcep_no_path_flags_c = -1;
+static gint ett_pcep_obj_end_point = -1;
+static gint ett_pcep_obj_bandwidth = -1;
+static gint ett_pcep_obj_metric = -1;
+static gint pcep_metric_flags_c = -1;
+static gint pcep_metric_flags_b = -1;
+static gint ett_pcep_obj_explicit_route = -1;
+static gint ett_pcep_obj_record_route = -1;
+static gint ett_pcep_obj_lspa = -1;
+static gint pcep_lspa_flags_l= -1;
+static gint ett_pcep_obj_iro = -1;
+static gint ett_pcep_obj_svec = -1;
+static gint pcep_svec_flags_l= -1;
+static gint pcep_svec_flags_n= -1;
+static gint pcep_svec_flags_s= -1;
+static gint ett_pcep_obj_notification = -1;
+static gint ett_pcep_obj_error = -1;
+static gint ett_pcep_obj_load_balancing = -1;
+static gint ett_pcep_obj_close = -1;
+static gint ett_pcep_obj_xro = -1;
+static gint pcep_xro_flags_f= -1;
+static gint pcep_subobj_flags_lpa= -1;
+static gint pcep_subobj_flags_lpu= -1;
+static gint pcep_subobj_label_flags_gl= -1;
+static gint ett_pcep_obj_unknown = -1;
+
+/* PCEP message types.*/
+typedef enum {
+ PCEP_MSG_NO_VALID,
+ PCEP_MSG_OPEN,
+ PCEP_MSG_KEEPALIVE,
+ PCEP_MSG_PATH_COMPUTATION_REQUEST,
+ PCEP_MSG_PATH_COMPUTATION_REPLY,
+ PCEP_MSG_NOTIFICATION,
+ PCEP_MSG_ERROR,
+ PCEP_MSG_CLOSE
+} pcep_message_types;
+
+static const value_string message_type_vals[] = {
+ {PCEP_MSG_OPEN, "OPEN MESSAGE" },
+ {PCEP_MSG_KEEPALIVE, "KEEPALIVE MESSAGE" },
+ {PCEP_MSG_PATH_COMPUTATION_REQUEST, "PATH COMPUTATION REQUEST MESSAGE" },
+ {PCEP_MSG_PATH_COMPUTATION_REPLY, "PATH COMPUTATION REPLY MESSAGE" },
+ {PCEP_MSG_NOTIFICATION, "NOTIFICATION MESSAGE" },
+ {PCEP_MSG_ERROR, "ERROR MESSAGE" },
+ {PCEP_MSG_CLOSE, "CLOSE MESSAGE" },
+ {0, NULL }
+};
+
+static const value_string pcep_class_vals[] = {
+ {PCEP_OPEN_OBJ, "OPEN OBJECT" },
+ {PCEP_RP_OBJ, "RP OBJECT" },
+ {PCEP_NO_PATH_OBJ, "NO-PATH OBJECT" },
+ {PCEP_END_POINT_OBJ, "END-POINT OBJECT" },
+ {PCEP_BANDWIDTH_OBJ, "BANDWIDTH OBJECT" },
+ {PCEP_METRIC_OBJ, "METRIC OBJECT" },
+ {PCEP_EXPLICIT_ROUTE_OBJ, "EXPLICIT ROUTE OBJECT (ERO)" },
+ {PCEP_RECORD_ROUTE_OBJ, "RECORD ROUTE OBJECT (RRO)" },
+ {PCEP_LSPA_OBJ, "LSPA OBJECT" },
+ {PCEP_IRO_OBJ, "IRO OBJECT" },
+ {PCEP_SVEC_OBJ, "SVEC OBJECT" },
+ {PCEP_NOTIFICATION_OBJ, "NOTIFICATION OBJECT" },
+ {PCEP_PCEP_ERROR_OBJ, "PCEP ERROR OBJECT" },
+ {PCEP_LOAD_BALANCING_OBJ, "LOAD BALANCING OBJECT" },
+ {PCEP_CLOSE_OBJ, "CLOSE OBJECT" },
+ {NO_DEFINED_OBJ, "Non Defined OBJECT" },
+ {PCEP_XRO_OBJ, "EXCLUDE ROUTE OBJECT (XRO)" },
+ {0, NULL }
+};
+
+static const value_string pcep_subobj_vals[] = {
+ {PCEP_SUB_IPv4, "SUBOBJECT IPv4" },
+ {PCEP_SUB_IPv6, "SUBOBJECT IPv6" },
+ {PCEP_SUB_LABEL_CONTROL, "SUBOBJECT LABEL" },
+ {PCEP_SUB_UNNUMB_INTERFACE_ID, "SUBOBJECT UNNUMBERED INTERFACE-ID" },
+ {PCEP_SUB_SRLG, "SUBOBJECT SRLG" },
+ {PCEP_SUB_AUTONOMOUS_SYS_NUM, "SUBOBJECT AUTONOMOUS SYSTEM NUMBER" },
+ {0, NULL }
+};
+
+
+static const value_string pcep_subobj_xro_vals[] = {
+ {PCEP_SUB_IPv4, "SUBOBJECT IPv4" },
+ {PCEP_SUB_IPv6, "SUBOBJECT IPv6" },
+ {PCEP_SUB_UNNUMB_INTERFACE_ID_XRO,"SUBOBJECT UNNUMBERED INTERFACE-ID" },
+ {PCEP_SUB_AUTONOMOUS_SYS_NUM_XRO,"SUBOBJECT AUTONOMOUS SYSTEM NUMBER" },
+ {PCEP_SUB_SRLG, "SUBOBJECT SRLG" },
+ {0, NULL }
+};
+
+/*In the NO-PATH Object the two different possibilities that NI can have*/
+static const value_string pcep_no_path_obj_vals[] = {
+ {NO_SATISFYING, "Nature of Issue: No path satisfying the set of constraints could be found (0x0)" },
+ {CHAIN_BROKEN, "Nature of Issue: PCEP Chain Broken (0x1)" },
+ {0, NULL }
+};
+
+/*Different values of "Type (T)" in the METRIC Obj */
+static const value_string pcep_metric_obj_vals[] = {
+ {NO_DEFINED, "Type not defined" },
+ {IGP_METRIC, "Type: IGP Metric (T=1)" },
+ {TE_METRIC, "Type: TE Metric (T=2)" },
+ {HOP_COUNTS, "Type: Hop Counts (T=3)" },
+ {0, NULL }
+};
+
+/*Different values for (L) in the ERO and IRO Objs */
+static const value_string pcep_route_l_obj_vals[] = {
+ {STRICT_HOP, "L=0 Strict Hop in the Explicit Route" },
+ {LOOSE_HOP, "L=1 Loose Hop in the Explicit Route" },
+ {0, NULL }
+};
+
+/*Different values of the direction of the label (U) in the ERO and RRO Objs */
+static const value_string pcep_route_u_obj_vals[] = {
+ {DOWNSTREAM_LABEL, "U=0 S Downstream Label" },
+ {UPSTREAM_LABEL, "U=1 Upstream Label" },
+ {0, NULL }
+};
+
+/*Values of Notification type*/
+static const value_string pcep_notification_types_vals[] = {
+ {NOT_REQ_CANCEL, "Pending Request Cancelled" },
+ {PCEP_CONGESTION, "PCE Congestion" },
+ {0, NULL }
+};
+
+/*Values of Notification value for Notification Type=1*/
+static const value_string pcep_notification_values1_vals[] = {
+ {NOTI_PCC_CANCEL_REQ, "PCC Cancels a set of Pending Request (s)" },
+ {NOTI_PCE_CANCEL_REQ, "PCE Cancels a set of Pending Request (s)" },
+ {0, NULL }
+};
+
+/*Values of Notification value for Notification Type=2*/
+static const value_string pcep_notification_values2_vals[] = {
+ {NOTI_PCE_CONGEST, "PCE in Congested State" },
+ {NOTI_PCE_NO_CONGEST, "PCE no Longer in Congested state" },
+ {0, NULL }
+};
+
+
+/*Values of different types of errors*/
+static const value_string pcep_error_types_obj_vals[] = {
+ {ESTABLISH_FAILURE, "1 PCEP Session Establishment Failure" },
+ {CAP_NOT_SUPPORTED, "2 Capability non supported" },
+ {UNKNOWN_OBJ, "3 Unknown Object" },
+ {NOT_SUPP_OBJ, "4 Not Supported Object" },
+ {POLICY_VIOLATION, "5 Policy Violation" },
+ {MANDATORY_OBJ_MIS, "6 Mandatory Object Missing" },
+ {SYNCH_PCREQ_MIS, "7 Synchronized Path Computation Request Missing" },
+ {UNKNOWN_REQ_REF, "8 Unknown Request Reference" },
+ {ATTEMPT_2_SESSION, "9 Attempt to Establish a Second PCEP Session" },
+ {UNRECO_IRO_SUBOBJ, "11 Unrecognized IRO Subobject" },
+ {UNRECO_EXRS_SUBOBJ, "12 Unrecognized EXRS Subobject" },
+ {0, NULL }
+};
+
+static const value_string pcep_close_reason_obj_vals[] = {
+ {NO_DEFINED, "Reason = 0 no defined" },
+ {NO_EXP_PROV, "Reason = 1 No Explanation Provided " },
+ {DEADTIME_PROV, "Reason = 2 Deadtime Expired" },
+ {RECEP_MALFORM_MSG, "Reason = 3 Reception of a Malformed PCEP Message" },
+ {0, NULL }
+};
+
+static const value_string pcep_xro_atribute_obj_vals[] = {
+ {ATTR_INTERFACE, "Atribute = 0 Interface" },
+ {ATTR_NODE, "Atribute = 1 Node " },
+ {ATTR_SRLG, "Atribute = 2 SRLG" },
+ {0, NULL }
+};
+
+/* The PCEP filtering keys */
+enum pcep_filter_keys{
+
+ PCEPF_MSG,
+
+ PCEPF_OPEN,
+ PCEPF_KEEPALIVE,
+ PCEPF_PATH_COMPUTATION_REQUEST,
+ PCEPF_PATH_COMPUTATION_REPLY,
+ PCEPF_NOTIFICATION,
+ PCEPF_ERROR,
+ PCEPF_CLOSE,
+
+ PCEPF_OBJECT_CLASS,
+ PCEPF_OBJ_OPEN,
+ PCEPF_OBJ_RP,
+ PCEPF_OBJ_NO_PATH,
+ PCEPF_OBJ_END_POINT,
+ PCEPF_OBJ_BANDWIDTH,
+ PCEPF_OBJ_METRIC,
+ PCEPF_OBJ_EXPLICIT_ROUTE,
+ PCEPF_OBJ_RECORD_ROUTE,
+ PCEPF_OBJ_LSPA,
+ PCEPF_OBJ_IRO,
+ PCEPF_OBJ_SVEC,
+ PCEPF_OBJ_NOTIFICATION,
+ PCEPF_NOTI_TYPE,
+ PCEPF_NOTI_VAL1,
+ PCEPF_NOTI_VAL2,
+ PCEPF_OBJ_PCEP_ERROR,
+ PCEPF_ERROR_TYPE,
+ PCEPF_OBJ_LOAD_BALANCING,
+ PCEPF_OBJ_CLOSE,
+ PCEPF_OBJ_XRO,
+ PCEPF_SUBOBJ,
+ PCEPF_SUBOBJ_IPv4,
+ PCEPF_SUBOBJ_IPv6,
+ PCEPF_SUBOBJ_LABEL_CONTROL,
+ PCEPF_SUBOBJ_UNNUM_INTERFACEID,
+ PCEPF_SUBOBJ_AUTONOMOUS_SYS_NUM,
+ PCEPF_SUBOBJ_SRLG,
+ PCEPF_SUBOBJ_EXRS,
+ PCEPF_SUBOBJ_XRO,
+ PCEPF_SUB_XRO_ATRIB,
+
+ PCEPF_MAX
+};
+
+
+/*Registering data structures*/
+
+static gint *ett[] = {
+ &ett_pcep,
+ &ett_pcep_hdr,
+ &ett_pcep_obj_open,
+ &ett_pcep_obj_request_parameters,
+ &ett_pcep_obj_no_path,
+ &ett_pcep_obj_end_point,
+ &ett_pcep_obj_bandwidth,
+ &ett_pcep_obj_metric,
+ &ett_pcep_obj_explicit_route,
+ &ett_pcep_obj_record_route,
+ &ett_pcep_obj_lspa,
+ &ett_pcep_obj_iro,
+ &ett_pcep_obj_svec,
+ &ett_pcep_obj_notification,
+ &ett_pcep_obj_error,
+ &ett_pcep_obj_load_balancing,
+ &ett_pcep_obj_close,
+ &ett_pcep_obj_xro,
+ &ett_pcep_obj_unknown
+};
+
+/*Registering data structures*/
+
+static int pcep_filter[PCEPF_MAX];
+
+static hf_register_info pcepf_info[] = {
+
+ /* Message type number */
+ {&pcep_filter[PCEPF_MSG],
+ { "Message Type", "pcep.msg", FT_UINT8, BASE_DEC, VALS(message_type_vals), 0x0,
+ "", HFILL }},
+ {&pcep_hdr_msg_flags_reserved,
+ { "Reserved Flags", "pcep.hdr.msg.flags.reserved", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_HDR_MSG_RESERVED,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OPEN],
+ { "Open Message", "pcep.msg.open", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_KEEPALIVE],
+ { "Keepalive Message", "pcep.msg.keepalive", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_PATH_COMPUTATION_REQUEST],
+ { "Path Computation Request Message", "pcep.msg.path.computation.request", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_PATH_COMPUTATION_REPLY],
+ { "Path Computation Reply Mesagge", "pcep.msg.path.computation.reply", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_NOTIFICATION],
+ { "Notification Message", "pcep.msg.notification", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_ERROR],
+ { "Error Message", "pcep.msg.error", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_CLOSE],
+ { "Close Message", "pcep.msg.close", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ /*Object header*/
+ {&pcep_hdr_obj_flags_reserved,
+ { "Reserved Flags", "pcep.hdr.obj.flags.reserved", FT_BOOLEAN, 4, TFS(&tfs_set_notset), PCEP_HDR_OBJ_RESERVED,
+ "", HFILL }},
+ {&pcep_hdr_obj_flags_p,
+ { "Processing-Rule (P)", "pcep.hdr.obj.flags.p", FT_BOOLEAN, 4, TFS(&tfs_set_notset), PCEP_HDR_OBJ_P,
+ "", HFILL }},
+ {&pcep_hdr_obj_flags_i,
+ { "Ignore (I)", "pcep.hdr.obj.flags.i", FT_BOOLEAN, 4, TFS(&tfs_set_notset), PCEP_HDR_OBJ_I,
+ "", HFILL }},
+ /* Object class */
+ {&pcep_filter[PCEPF_OBJECT_CLASS],
+ { "Object Class", "pcep.object", FT_UINT32, BASE_DEC, VALS(pcep_class_vals), 0x0,
+ "", HFILL }},
+
+ /* Object types */
+ {&pcep_filter[PCEPF_OBJ_OPEN],
+ { "OPEN object", "pcep.obj.open", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_open_flags_res,
+ { "Reserved Flags", "pcep.open.flags.res", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_OPEN_RES,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_RP],
+ { "RP object", "pcep.obj.rp", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_rp_flags_reserved,
+ { "Reserved Flags", "pcep.rp.flags.reserved", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_RESERVED,
+ "", HFILL }},
+ {&pcep_rp_flags_pri,
+ { "Priority (PRI)", "pcep.rp.flags.pri", FT_BOOLEAN, 24, TFS(&tfs_on_off), PCEP_RP_PRI,
+ "", HFILL }},
+ {&pcep_rp_flags_r,
+ { "Reoptimization (R)", "pcep.rp.flags.r", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_R,
+ "", HFILL }},
+ {&pcep_rp_flags_b,
+ { "Bi-directional (L)", "pcep.rp.flags.b", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_B,
+ "", HFILL }},
+ {&pcep_rp_flags_o,
+ { "Strict/Loose (L)", "pcep.rp.flags.o", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_O,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_NO_PATH],
+ { "NO-PATH object", "pcep.obj.nopath", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_no_path_flags_c,
+ { "C", "pcep.no.path.flags.c", FT_BOOLEAN, 16, TFS(&tfs_set_notset), PCEP_NO_PATH_C,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_END_POINT],
+ { "END-POINT object", "pcep.obj.endpoint", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_BANDWIDTH],
+ { "BANDWIDTH object", "pcep.obj.bandwidth", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_METRIC],
+ { "METRIC object", "pcep.obj.metric", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_metric_flags_c,
+ { "Cost (C)", "pcep.metric.flags.c", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_METRIC_C,
+ "", HFILL }},
+ {&pcep_metric_flags_b,
+ { "Bound (B)", "pcep.metric.flags.b", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_METRIC_B,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_EXPLICIT_ROUTE],
+ { "EXPLICIT ROUTE object (ERO)", "pcep.obj.ero", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_RECORD_ROUTE],
+ { "RECORD ROUTE object (RRO)", "pcep.obj.rro", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_LSPA],
+ { "LSPA object", "pcep.obj.lspa", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_lspa_flags_l,
+ { "Local Protection Desired (L)", "pcep.lspa.flags.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_LSPA_L,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_IRO],
+ { "IRO object", "pcep.obj.iro", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_SVEC],
+ { "SVEC object", "pcep.obj.svec", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&pcep_svec_flags_l,
+ { "Link diverse (L)", "pcep.svec.flags.l", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_SVEC_L,
+ "", HFILL }},
+
+ {&pcep_svec_flags_n,
+ { "Node diverse (N)", "pcep.svec.flags.n", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_SVEC_N,
+ "", HFILL }},
+
+ {&pcep_svec_flags_s,
+ { "SRLG diverse (S)", "pcep.svec.flags.s", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_SVEC_S,
+ "", HFILL }},
+
+ {&pcep_filter[PCEPF_OBJ_NOTIFICATION],
+ { "NOTIFICATION object", "pcep.obj.notification", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&pcep_filter[PCEPF_NOTI_TYPE],
+ { "Notification Value", "pcep.notification.value1", FT_UINT32, BASE_DEC, VALS(pcep_notification_types_vals), 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_NOTI_VAL1],
+ { "Notification Type", "pcep.notification.type2", FT_UINT32, BASE_DEC, VALS(pcep_notification_values1_vals), 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_NOTI_VAL2],
+ { "Notification Type", "pcep.notification.type", FT_UINT32, BASE_DEC, VALS(pcep_notification_values2_vals), 0x0,
+ "", HFILL }},
+
+ {&pcep_filter[PCEPF_OBJ_PCEP_ERROR],
+ { "ERROR object", "pcep.obj.error", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_ERROR_TYPE],
+ { "Error-Type", "pcep.error.type", FT_UINT8, BASE_DEC, VALS(pcep_error_types_obj_vals), 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_LOAD_BALANCING],
+ { "LOAD BALANCING object", "pcep.obj.loadbalancing", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_CLOSE],
+ { "CLOSE object", "pcep.obj.close", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_OBJ_XRO],
+ { "EXCLUDE ROUTE object (XRO)", "pcep.obj.xro", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ /*Subobjects*/
+ {&pcep_filter[PCEPF_SUBOBJ],
+ { "Type", "pcep.subobj", FT_UINT8, BASE_DEC, VALS(pcep_subobj_vals), 0x0,
+ "", HFILL }},
+
+ {&pcep_filter[PCEPF_SUBOBJ_IPv4],
+ { "SUBOBJECT: IPv4 Prefix", "pcep.subobj.ipv4", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_SUBOBJ_IPv6],
+ { "SUBOBJECT: IPv6 Prefix", "pcep.subobj.ipv6", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_SUBOBJ_LABEL_CONTROL],
+ { "SUBOBJECT: Label Control", "pcep.subobj.label.control", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_SUBOBJ_UNNUM_INTERFACEID],
+ { "SUBOBJECT: Unnumbered Interface ID", "pcep.subobj.unnum.interfaceid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_SUBOBJ_AUTONOMOUS_SYS_NUM],
+ { "SUBOBJECT: Autonomous System Number", "pcep.subobj.auntonomus.sys.num", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_SUBOBJ_SRLG],
+ { "SUBOBJECT: SRLG", "pcep.subobj.srlg", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_SUBOBJ_EXRS],
+ { "SUBOBJECT: EXRS", "pcep.subobj.exrs", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_SUBOBJ_XRO],
+ { "Type", "pcep.subobj.label", FT_UINT32, BASE_DEC, VALS(pcep_subobj_xro_vals), 0x0,
+ "", HFILL }},
+ {&pcep_xro_flags_f,
+ { "Fail (F)", "pcep.xro.flags.f", FT_BOOLEAN, 16, TFS(&tfs_set_notset), PCEP_XRO_F,
+ "", HFILL }},
+ {&pcep_filter[PCEPF_SUB_XRO_ATRIB],
+ { "Attribute", "pcep.xro.sub.atribute", FT_UINT32, BASE_DEC, VALS(pcep_xro_atribute_obj_vals), 0x0,
+ "", HFILL }},
+
+ {&pcep_subobj_flags_lpa,
+ { "Local Protection Available", "pcep.subobj.flags.lpa", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_SUB_LPA,
+ "", HFILL }},
+ {&pcep_subobj_flags_lpu,
+ { "Local protection in Use", "pcep.subobj.flags.lpu", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_SUB_LPU,
+ "", HFILL }},
+ {&pcep_subobj_label_flags_gl,
+ { "Global Label", "pcep.subobj.label.flags.gl", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_SUB_LABEL_GL,
+ "", HFILL }},
+};
+
+#define OBJ_HDR_LEN 4 /* length of object header */
+
+static void
+dissect_pcep_tlvs(proto_tree *pcep_obj, tvbuff_t *tvb, int offset, gint length, gint ett_pcep_obj)
+{
+ proto_tree *tlv;
+ proto_item *ti;
+ guint16 tlv_length;
+ guint16 tlv_type;
+ int j;
+ int m = 0;
+ int padding = 0;
+
+ for (j = 0; j < length; j += 4 + tlv_length + padding){
+ m = m+1;
+
+ tlv_type = tvb_get_ntohs(tvb, offset+j);
+ tlv_length = tvb_get_ntohs(tvb, offset + j + 2);
+ ti = proto_tree_add_text(pcep_obj, tvb, offset + j, tlv_length+4, "TLV %u", m);
+ tlv = proto_item_add_subtree(ti, ett_pcep_obj);
+ proto_tree_add_text(tlv, tvb, offset + j, 2, "Type: %u", tlv_type);
+ proto_tree_add_text(tlv, tvb, offset + 2 + j, 2, "Length: %u", tlv_length);
+ proto_tree_add_text(tlv, tvb, offset+4+j, tlv_length, "Data: %s",
+ bytestring_to_str(tvb_get_ptr(tvb, (offset) + 4 + j, tlv_length), tlv_length, ' '));
+ padding = (4 - (tlv_length % 4)) % 4;
+ if (padding != 0){
+ proto_tree_add_text(tlv, tvb, offset+4+j+tlv_length, padding, "Padding: %s",
+ bytestring_to_str(tvb_get_ptr(tvb, (offset) + 4 + j + tlv_length, padding), padding, ' '));
+ }
+ }
+}
+
+/*------------------------------------------------------------------------------
+ *SUBOBJECTS
+ *------------------------------------------------------------------------------*/
+static void
+dissect_subobj_ipv4(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int obj_class, gint ett_pcep_obj, guint l_and_or_type, guint length)
+{
+ proto_tree *pcep_subobj_ipv4;
+ proto_tree *pcep_subobj_ipv4_flags;
+ proto_item *ti;
+ guint8 prefix_length;
+ guint8 resvd;
+ guint l;
+
+ prefix_length = tvb_get_guint8(tvb, offset+6);
+ resvd = tvb_get_guint8(tvb, offset+7);
+
+ ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_IPv4], tvb, offset, length, FALSE);
+ pcep_subobj_ipv4 = proto_item_add_subtree(ti, ett_pcep_obj);
+
+ if (length != 8) {
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, length,
+ "Bad IPv4 subobject: length %u != 8", length);
+ return;
+ }
+
+ switch(obj_class){
+
+ case PCEP_EXPLICIT_ROUTE_OBJ:
+ l = (l_and_or_type& Mask_L)>>7;
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 1, val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
+ proto_tree_add_uint(pcep_subobj_ipv4, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+1, 1, "Length: %u", length);
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: (%s)", ip_to_str(tvb_get_ptr(tvb, offset+2, 4)));
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+6, 1, "Prefix Length: %u", prefix_length);
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1, "Padding: 0x%02x", resvd);
+ break;
+
+ case PCEP_RECORD_ROUTE_OBJ:
+ proto_tree_add_uint(pcep_subobj_ipv4, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, l_and_or_type);
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+1, 1, "Length: %u", length);
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: (%s)", ip_to_str(tvb_get_ptr(tvb, offset+2, 4)));
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+6, 1, "Prefix Length: %u", prefix_length);
+ ti = proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1, "Flags: 0x%02x ", resvd);
+ pcep_subobj_ipv4_flags = proto_item_add_subtree(ti, ett_pcep_obj);
+ proto_tree_add_boolean(pcep_subobj_ipv4_flags, pcep_subobj_flags_lpa, tvb, offset+7, 1, resvd);
+ proto_tree_add_boolean(pcep_subobj_ipv4_flags, pcep_subobj_flags_lpu, tvb, offset+7, 1, resvd);
+ break;
+
+ case PCEP_IRO_OBJ:
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 1, "l: %x", (l_and_or_type & 0x80)>>7);
+ proto_tree_add_uint(pcep_subobj_ipv4, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+1, 1, "Length: %u", length);
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: (%s)", ip_to_str(tvb_get_ptr(tvb, offset+2, 4)));
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+6, 1, "Prefix Length: %u", prefix_length);
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1, "Padding: 0x%02x", resvd);
+ break;
+
+ case PCEP_XRO_OBJ:
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 1, "X: %x", (l_and_or_type & 0x01)>>7);
+ proto_tree_add_uint(pcep_subobj_ipv4, pcep_filter[PCEPF_SUBOBJ_XRO], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 1, "Type: %u", (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+1, 1, "Length: %u", length);
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: (%s)", ip_to_str(tvb_get_ptr(tvb, offset+2, 4)));
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+6, 1, "Prefix Length: %u", prefix_length);
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1, val_to_str(resvd, pcep_xro_atribute_obj_vals, "Unknown Atribute (%u). "));
+ break;
+
+ default:
+ proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 8, "Non defined subobject for this object");
+ break;
+ }
+}
+
+static void
+dissect_subobj_ipv6(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int obj_class, gint ett_pcep_obj, guint l_and_or_type, guint length)
+{
+ proto_tree *pcep_subobj_ipv6;
+ proto_tree *pcep_subobj_ipv6_flags;
+ proto_item *ti;
+ guint8 prefix_length;
+ guint8 resv;
+ int l;
+
+ prefix_length = tvb_get_guint8(tvb, offset+18);
+ resv = tvb_get_guint8(tvb, offset+19);
+ ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_IPv6], tvb, offset, length, FALSE);
+ pcep_subobj_ipv6 = proto_item_add_subtree(ti, ett_pcep_obj);
+
+ if (length != 20) {
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset, length,
+ "Bad IPv6 subobject: length %u != 20", length);
+ return;
+ }
+
+ switch(obj_class){
+ case PCEP_EXPLICIT_ROUTE_OBJ:
+ l = (l_and_or_type& Mask_L)>>7;
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset, 1, val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
+ proto_tree_add_uint(pcep_subobj_ipv6, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+1, 1, "Length: %u", length);
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+2, 16, "IPv6 Address: %s", ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset+2, 16)));
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+18, 1, "Prefix Length: %u", prefix_length);
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+19, 1, "Padding: 0x%02x", resv);
+ break;
+
+ case PCEP_RECORD_ROUTE_OBJ:
+ proto_tree_add_uint(pcep_subobj_ipv6, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, l_and_or_type);
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+1, 1, "Length: %u", length);
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+2, 16, "IPv6 Address: %s", ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset+2, 16)));
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+18, 1, "Prefix Length: %u", prefix_length);
+ ti = proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+19, 1, "Flags: 0x%02x ", resv);
+ pcep_subobj_ipv6_flags = proto_item_add_subtree(ti, ett_pcep_obj);
+ proto_tree_add_boolean(pcep_subobj_ipv6_flags, pcep_subobj_flags_lpa, tvb, offset+19, 1, resv);
+ proto_tree_add_boolean(pcep_subobj_ipv6_flags, pcep_subobj_flags_lpu, tvb, offset+19, 1, resv);
+ break;
+
+ case PCEP_IRO_OBJ:
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset, 1, "l: %x", (l_and_or_type & 0x80)>>7);
+ proto_tree_add_uint(pcep_subobj_ipv6, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+1, 1, "Length: %u", length);
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+2, 16, "IPv6 Address: %s", ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset+2, 16)));
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+18, 1, "Prefix Length: %u", prefix_length);
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+19, 1, "Padding: 0x%02x", resv);
+ break;
+
+ case PCEP_XRO_OBJ:
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset, 1, "X: %x", (l_and_or_type & 0x01)>>7);
+ proto_tree_add_uint(pcep_subobj_ipv6, pcep_filter[PCEPF_SUBOBJ_XRO], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+1, 1, "Length: %u", length);
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+2, 16, "IPv6 Address: %s", ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset+2, 16)));
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+18, 1, "Prefix Length: %u", prefix_length);
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+19, 1, val_to_str(resv, pcep_xro_atribute_obj_vals, "Unknown Atribute (%u). "));
+ break;
+
+ default:
+ proto_tree_add_text(pcep_subobj_ipv6, tvb, offset, 20, "Non defined subobject for this object");
+ break;
+ }
+}
+
+
+static void
+dissect_subobj_label_control(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int obj_class, gint ett_pcep_obj, guint l_and_or_type, guint length)
+{
+ proto_tree *pcep_subobj_label_control;
+ proto_tree *pcep_subobj_label_flags;
+ proto_item *ti;
+ guint8 u_reserved;
+ guint8 c_type;
+ int l;
+ int u;
+
+ u_reserved = tvb_get_guint8(tvb, offset+2);
+ c_type = tvb_get_guint8(tvb, offset+3);
+
+ ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_LABEL_CONTROL], tvb, offset, length, FALSE);
+ pcep_subobj_label_control = proto_item_add_subtree(ti, ett_pcep_obj);
+
+ if (length < 5) {
+ proto_tree_add_text(pcep_subobj_label_control, tvb, offset, length,
+ "Bad label control subobject: length %u < 5", length);
+ return;
+ }
+
+ switch(obj_class){
+
+ case PCEP_EXPLICIT_ROUTE_OBJ:
+ l = (l_and_or_type& Mask_L)>>7;
+ proto_tree_add_text(pcep_subobj_label_control, tvb, offset, 1, val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
+ proto_tree_add_uint(pcep_subobj_label_control, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_label_control, tvb, offset+1, 1, "Length: %u", length);
+ u = (u_reserved & 0x80)>>7;
+ proto_tree_add_text(pcep_subobj_label_control, tvb, offset+2, 1, val_to_str(u, pcep_route_u_obj_vals, "Unknown Object (%u). "));
+ proto_tree_add_text(pcep_subobj_label_control, tvb, offset+2, 1, "Reserved: %u", (u_reserved & 0x7f));
+ proto_tree_add_text(pcep_subobj_label_control, tvb, offset+3, 1, "C-Type: %u", c_type);
+ proto_tree_add_text(pcep_subobj_label_control, tvb, offset+4, length-4, "Label: %s",
+ bytestring_to_str(tvb_get_ptr(tvb, offset+4, length-4), length-4, ' '));
+ break;
+
+ case PCEP_RECORD_ROUTE_OBJ:
+ proto_tree_add_uint(pcep_subobj_label_control, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, l_and_or_type);
+ proto_tree_add_text(pcep_subobj_label_control, tvb, offset+1, 1, "Length: %u", length);
+ u = (u_reserved & 0x80)>>7;
+ proto_tree_add_text(pcep_subobj_label_control, tvb, offset+2, 1, val_to_str(u, pcep_route_u_obj_vals, "Unknown Object (%u). "));
+
+ ti = proto_tree_add_text(pcep_subobj_label_control, tvb, offset+2, 1, "Flags: 0x%02x ", (u_reserved & 0x7f));
+ pcep_subobj_label_flags = proto_item_add_subtree(ti, ett_pcep_obj);
+ proto_tree_add_boolean(pcep_subobj_label_flags, pcep_subobj_label_flags_gl, tvb, offset+2, 1, (u_reserved & 0x7f));
+ proto_tree_add_text(pcep_subobj_label_control, tvb, offset+3, 1, "C-Type: %u", c_type);
+ proto_tree_add_text(pcep_subobj_label_control, tvb, offset+4, length-4, "Label: %s",
+ bytestring_to_str(tvb_get_ptr(tvb, offset+4, length-4), length-4, ' '));
+ break;
+
+ default:
+ proto_tree_add_text(pcep_subobj_label_control, tvb, offset, length, "Non defined subobject for this object");
+ break;
+ }
+}
+
+static void
+dissect_subobj_unnumb_interfaceID(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int obj_class, gint ett_pcep_obj, guint l_and_or_type, guint length)
+{
+ proto_tree *pcep_subobj_unnumb_interfaceID;
+ proto_tree *pcep_subobj_unnumb_interfaceID_flags;
+ proto_item *ti;
+ guint32 router_ID;
+ guint32 interface_ID;
+ guint16 reserved_flags;
+ int l;
+
+ reserved_flags = tvb_get_ntohs(tvb, offset+2);
+ router_ID = tvb_get_ntohl(tvb, offset+4);
+ interface_ID = tvb_get_ntohl(tvb, offset+8);
+
+ ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_UNNUM_INTERFACEID], tvb, offset, length, FALSE);
+ pcep_subobj_unnumb_interfaceID = proto_item_add_subtree(ti, ett_pcep_obj);
+
+ if (length != 12) {
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset, length,
+ "Bad unnumbered interface ID subobject: length %u != 12", length);
+ return;
+ }
+
+ switch(obj_class){
+
+ case PCEP_EXPLICIT_ROUTE_OBJ:
+ l = (l_and_or_type& Mask_L)>>7;
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset, 1, val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
+ proto_tree_add_uint(pcep_subobj_unnumb_interfaceID, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+1, 1, "Length: %u", length);
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+2, 2, "Reserved: 0x%04x", reserved_flags);
+ break;
+
+ case PCEP_RECORD_ROUTE_OBJ:
+ proto_tree_add_uint(pcep_subobj_unnumb_interfaceID, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, l_and_or_type);
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+1, 1, "Length: %u", length);
+
+ ti = proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+2, 2, "Flags: 0x%02x ", (reserved_flags & 0xff00)>>8);
+ pcep_subobj_unnumb_interfaceID_flags = proto_item_add_subtree(ti, ett_pcep_obj);
+ proto_tree_add_boolean(pcep_subobj_unnumb_interfaceID_flags, pcep_subobj_flags_lpa, tvb, offset+2, 1, (reserved_flags & 0xff00)>>8);
+ proto_tree_add_boolean(pcep_subobj_unnumb_interfaceID_flags, pcep_subobj_flags_lpu, tvb, offset+2, 1, (reserved_flags & 0xff00)>>8);
+
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+3, 1, "Reserved: 0x%02x", (reserved_flags & 0x00ff));
+ break;
+
+ case PCEP_IRO_OBJ:
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset, 1, "l: %x", (l_and_or_type & 0x80)>>7);
+ proto_tree_add_uint(pcep_subobj_unnumb_interfaceID, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+1, 1, "Length: %u", length);
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+2, 2, "Reserved: 0x%04x", reserved_flags);
+ break;
+
+ case PCEP_XRO_OBJ:
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset, 1, "X: %x", (l_and_or_type & 0x01)>>7);
+ proto_tree_add_uint(pcep_subobj_unnumb_interfaceID, pcep_filter[PCEPF_SUBOBJ_XRO], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+2, 1, "Reserved: 0x%02x", (reserved_flags & 0xff00)>>4);
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+3, 1, val_to_str((reserved_flags & 0x00ff), pcep_xro_atribute_obj_vals, "Unknown Atribute (%u). "));
+ break;
+
+ default:
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset, 12, "Non defined subobject for this object");
+ break;
+ }
+
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+4, 4, "Router ID: 0x%08x", router_ID);
+ proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+8, 4, "Interface ID: 0x%08x", interface_ID);
+}
+
+static void
+dissect_subobj_autonomous_sys_num(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int obj_class, guint ett_pcep_obj, guint l_and_or_type, guint length)
+{
+ proto_tree *pcep_subobj_autonomous_sys_num;
+ proto_item *ti;
+ guint16 AS_number;
+ guint8 reserved;
+ guint8 attribute;
+ guint16 op_AS_nu_high_oct;
+
+ int l;
+ l = (l_and_or_type& Mask_L)>>7;
+
+ if(obj_class == PCEP_XRO_OBJ){
+ reserved = tvb_get_guint8(tvb, offset+2);
+ attribute = tvb_get_guint8(tvb, offset+3);
+ op_AS_nu_high_oct = tvb_get_ntohs(tvb, offset+4);
+ AS_number = tvb_get_ntohs(tvb, offset+6);
+
+ ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_AUTONOMOUS_SYS_NUM], tvb, offset, length, FALSE);
+ pcep_subobj_autonomous_sys_num = proto_item_add_subtree(ti, ett_pcep_obj);
+ if (length != 8) {
+ proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset, length,
+ "Bad autonomous system number subobject: length %u != 8", length);
+ return;
+ }
+
+ proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset, 1, "X: %x", (l_and_or_type & 0x01)>>7);
+ proto_tree_add_uint(pcep_subobj_autonomous_sys_num, pcep_filter[PCEPF_SUBOBJ_XRO], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+1, 1, "Length: %u", length);
+
+ proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+2, 1, "Reserved: 0x%02x", reserved);
+ proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+3, 1, val_to_str(attribute, pcep_xro_atribute_obj_vals, "Unknown Object (%u)."));
+ proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+4, 2, "Optional AS Number High Octets: 0x%04x", AS_number);
+ proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+6, 2, "AS Number: 0x%04x", AS_number);
+ } else {
+ AS_number = tvb_get_ntohs(tvb, offset+2);
+
+ ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_AUTONOMOUS_SYS_NUM], tvb, offset, length, FALSE);
+ pcep_subobj_autonomous_sys_num = proto_item_add_subtree(ti, ett_pcep_obj);
+
+ if (length != 4) {
+ proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset, length,
+ "Bad autonomous system number subobject: length %u != 4", length);
+ return;
+ }
+
+ if(obj_class == PCEP_IRO_OBJ)
+ proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset, 1, "l: %x", (l_and_or_type & 0x80)>>7);
+ else
+ proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset, 1, val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
+ proto_tree_add_uint(pcep_subobj_autonomous_sys_num, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+1, 1, "Length: %u", length);
+ proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+2, 2, "AS Number: 0x%04x", AS_number);
+ }
+}
+
+static void
+dissect_subobj_srlg(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, guint ett_pcep_obj, guint l_and_or_type, guint length)
+{
+ proto_tree *pcep_subobj_srlg;
+ proto_item *ti;
+ guint32 srlg_id;
+ guint8 reserved;
+ guint8 attribute;
+
+ srlg_id = tvb_get_ntohl(tvb, offset+2);
+ reserved = tvb_get_guint8(tvb, offset+6);
+ attribute = tvb_get_guint8(tvb, offset+7);
+
+ ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_SRLG], tvb, offset, length, FALSE);
+ pcep_subobj_srlg = proto_item_add_subtree(ti, ett_pcep_obj);
+
+ if (length != 8) {
+ proto_tree_add_text(pcep_subobj_srlg, tvb, offset, length,
+ "Bad SRLG subobject: length %u != 8", length);
+ return;
+ }
+
+ proto_tree_add_text(pcep_subobj_srlg, tvb, offset, 1, "X: %x", (l_and_or_type & 0x01)>>7);
+ proto_tree_add_uint(pcep_subobj_srlg, pcep_filter[PCEPF_SUBOBJ_XRO], tvb, offset, 1, (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_srlg, tvb, offset+1, 1, "Length: %u", length);
+
+ proto_tree_add_text(pcep_subobj_srlg, tvb, offset+2, 4, "SRLG ID: 0x%08x", srlg_id);
+ proto_tree_add_text(pcep_subobj_srlg, tvb, offset+6, 1, "Reserved: 0x%02x", reserved);
+ proto_tree_add_text(pcep_subobj_srlg, tvb, offset+7, 1, val_to_str(attribute, pcep_xro_atribute_obj_vals, "Unknown Object (%u)."));
+}
+
+static void
+dissect_subobj_exrs(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int obj_class, guint ett_pcep_obj, guint type_iro, guint l_and_or_type, guint length)
+{
+ proto_tree *pcep_subobj_exrs;
+ proto_item *ti;
+ guint16 reserved;
+ guint8 l_type;
+ guint8 length2;
+ guint type_exrs;
+ guint offset_exrs = 0;
+ guint l;
+
+ ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_EXRS], tvb, offset, length, FALSE);
+ pcep_subobj_exrs = proto_item_add_subtree(ti, ett_pcep_obj);
+
+ if (length < 4) {
+ proto_tree_add_text(pcep_subobj_exrs, tvb, offset, length,
+ "Bad EXRS subobject: length %u < 4", length);
+ return;
+ }
+
+ l = (l_and_or_type& Mask_L)>>7;
+ proto_tree_add_text(pcep_subobj_exrs, tvb, offset, 1, val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
+ proto_tree_add_text(pcep_subobj_exrs, tvb, offset, 1, "Type: %u", (l_and_or_type & 0x7f));
+ proto_tree_add_text(pcep_subobj_exrs, tvb, offset+1, 1, "Length: %u", length);
+
+ reserved = tvb_get_ntohs(tvb, offset+2);
+ proto_tree_add_text(pcep_subobj_exrs, tvb, offset+2, 2, "Reserved: 0x%04x", reserved);
+
+ offset += 4;
+
+ while(offset_exrs<length-4){
+
+ l_type = tvb_get_guint8(tvb, offset);
+ length2 = tvb_get_guint8(tvb, offset+1);
+
+ if (length2 < 2) {
+ proto_tree_add_text(pcep_subobj_exrs, tvb, offset, 0,
+ "Bad packet: subobject length %u < 2",
+ length2);
+ break;
+ }
+
+ type_exrs = (l_type & Mask_Type);
+
+ if(type_iro==PCEP_SUB_EXRS)
+ obj_class = PCEP_XRO_OBJ;
+
+ switch(type_exrs) {
+
+ case PCEP_SUB_IPv4:
+ dissect_subobj_ipv4(pcep_subobj_exrs, tvb, offset, obj_class, ett_pcep_obj, l_type, length2);
+ break;
+ case PCEP_SUB_IPv6:
+ dissect_subobj_ipv6(pcep_subobj_exrs, tvb, offset, obj_class, ett_pcep_obj, l_type, length2);
+ break;
+ case PCEP_SUB_UNNUMB_INTERFACE_ID_XRO:
+ dissect_subobj_unnumb_interfaceID(pcep_subobj_exrs, tvb, offset, obj_class, ett_pcep_obj, l_type, length2);
+ break;
+ case PCEP_SUB_AUTONOMOUS_SYS_NUM_XRO:
+ dissect_subobj_autonomous_sys_num(pcep_subobj_exrs, tvb, offset, obj_class, ett_pcep_obj, l_type, length2);
+ break;
+ case PCEP_SUB_SRLG:
+ dissect_subobj_srlg(pcep_subobj_exrs, tvb, offset, ett_pcep_obj, l_type, length2);
+ break;
+ default:
+ proto_tree_add_text(pcep_subobj_exrs, tvb, offset+2, length-2,
+ "Non defined subobject (%d)", type_exrs);
+ break;
+ }
+ offset_exrs += length2;
+ offset += length2;
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * OPEN OBJECT
+ *------------------------------------------------------------------------------*/
+#define OPEN_OBJ_MIN_LEN 4
+
+static void
+dissect_pcep_open_obj (proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
+{
+ proto_tree *pcep_open_obj_flags;
+ proto_item *ti;
+ guint8 version_flags;
+ guint8 keepalive;
+ guint8 deadtimer;
+ guint8 SID;
+
+ if (obj_length < OBJ_HDR_LEN+OPEN_OBJ_MIN_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad OPEN object length %u, should be >= %u", obj_length,
+ OBJ_HDR_LEN+OPEN_OBJ_MIN_LEN);
+ return;
+ }
+
+ version_flags = tvb_get_guint8(tvb, offset2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "PCEP Version: %u", (version_flags & 0xe0)>>5);
+
+ ti = proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "Flags: 0x%02x", version_flags & 0x1f);
+ pcep_open_obj_flags = proto_item_add_subtree(ti, ett_pcep_obj_open);
+ proto_tree_add_boolean(pcep_open_obj_flags, pcep_open_flags_res, tvb, offset2, 1, version_flags & 0x1f);
+
+ keepalive = tvb_get_guint8(tvb, offset2+1);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 1, "Keepalive: %u", keepalive);
+
+ deadtimer = tvb_get_guint8(tvb, offset2+2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 1, "Deadtime: %u", deadtimer);
+
+ SID = tvb_get_guint8(tvb, offset2+3);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "SID: %u", SID);
+
+ /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
+ offset2 += OPEN_OBJ_MIN_LEN;
+ obj_length -= OBJ_HDR_LEN+OPEN_OBJ_MIN_LEN;
+ dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_open);
+}
+
+/*------------------------------------------------------------------------------
+ * RP OBJECT
+ *------------------------------------------------------------------------------*/
+#define RP_OBJ_MIN_LEN 8
+
+static void
+dissect_pcep_rp_obj(proto_tree *pcep_object_tree,
+ tvbuff_t *tvb, int offset2, int obj_length)
+{
+ proto_tree *pcep_rp_obj_flags;
+ proto_item *ti;
+ guint8 reserved;
+ guint32 flags;
+ guint32 requested_id_number;
+
+ if (obj_length < OBJ_HDR_LEN+RP_OBJ_MIN_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad RP object length %u, should be >= %u", obj_length,
+ OBJ_HDR_LEN+RP_OBJ_MIN_LEN);
+ return;
+ }
+
+ reserved = tvb_get_guint8(tvb, offset2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "Reserved: 0x%02x", reserved);
+
+ flags = tvb_get_ntoh24(tvb, offset2+1);
+ ti = proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 3, "Flags: 0x%06x ", flags);
+ pcep_rp_obj_flags = proto_item_add_subtree(ti, ett_pcep_obj_request_parameters);
+
+ proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_reserved, tvb, offset2+1, 3, flags);
+ proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_o, tvb, offset2+1, 3, flags);
+ proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_b, tvb, offset2+1, 3, flags);
+ proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_r, tvb, offset2+1, 3, flags);
+ proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_pri, tvb, offset2+1, 3, flags);
+
+ requested_id_number = tvb_get_ntohl(tvb, offset2+4);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Requested ID Number: 0x%08x", requested_id_number);
+
+ /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
+ offset2 += RP_OBJ_MIN_LEN;
+ obj_length -= OBJ_HDR_LEN+RP_OBJ_MIN_LEN;
+ dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_request_parameters);
+}
+
+/*------------------------------------------------------------------------------
+ * NO PATH OBJECT
+ *------------------------------------------------------------------------------*/
+#define NO_PATH_OBJ_MIN_LEN 4
+
+static void
+dissect_pcep_no_path_obj(proto_tree *pcep_object_tree,
+ tvbuff_t *tvb, int offset2, int obj_length)
+{
+ proto_tree *pcep_no_path_obj_flags;
+ proto_item *ti;
+ guint8 ni;
+ guint16 flags;
+ guint8 reserved;
+
+ if (obj_length < OBJ_HDR_LEN+NO_PATH_OBJ_MIN_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad NO-PATH object length %u, should be >= %u", obj_length,
+ OBJ_HDR_LEN+NO_PATH_OBJ_MIN_LEN);
+ return;
+ }
+
+ ni = tvb_get_guint8(tvb, offset2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, val_to_str(ni, pcep_no_path_obj_vals, "Unknown Object (%u). "));
+
+ flags = tvb_get_ntohs(tvb, offset2+1);
+ ti = proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 2, "Flags: 0x%04x", flags);
+ pcep_no_path_obj_flags = proto_item_add_subtree(ti, ett_pcep_obj_no_path);
+ proto_tree_add_boolean(pcep_no_path_obj_flags, pcep_no_path_flags_c, tvb, offset2+1, 2, flags);
+
+ reserved = tvb_get_guint8(tvb, offset2+3);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "Reserved: 0x%02x", reserved);
+
+ /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
+ offset2 += NO_PATH_OBJ_MIN_LEN;
+ obj_length -= OBJ_HDR_LEN+NO_PATH_OBJ_MIN_LEN;
+ dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_no_path);
+}
+
+/*------------------------------------------------------------------------------
+ * END POINT OBJECT
+ *------------------------------------------------------------------------------*/
+#define END_POINT_IPV4_OBJ_LEN 8
+#define END_POINT_IPV6_OBJ_LEN 32
+
+static void
+dissect_pcep_end_point_obj(proto_tree *pcep_object_tree,
+ tvbuff_t *tvb, int offset2, int obj_length, int type)
+{
+ switch(type)
+ {
+ case IPv4:
+ if (obj_length != OBJ_HDR_LEN+END_POINT_IPV4_OBJ_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad IPv4 END-POINTS object length %u, should be %u", obj_length,
+ OBJ_HDR_LEN+END_POINT_IPV4_OBJ_LEN);
+ return;
+ }
+
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 4, "Source IPv4 Address: (%s)", ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Destination IPv4 Address: (%s)", ip_to_str(tvb_get_ptr(tvb, offset2+4, 4)));
+ break;
+
+ case IPv6:
+ if (obj_length != OBJ_HDR_LEN+END_POINT_IPV6_OBJ_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad IPv6 END-POINTS object length %u, should be %u", obj_length,
+ OBJ_HDR_LEN+END_POINT_IPV6_OBJ_LEN);
+ return;
+ }
+
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 16, "Source IPv6 Address: %s",
+ ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+16, 16, "Destination IPv6 Address: %s",
+ ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+16, 16)));
+ break;
+
+ default:
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length-OBJ_HDR_LEN, "UNKNOWN Type Object (%u)", type);
+ break;
+ }
+}
+
+
+
+/*------------------------------------------------------------------------------
+ * BANDWIDTH OBJECT
+ *------------------------------------------------------------------------------*/
+#define BANDWIDTH_OBJ_LEN 4
+
+static void
+dissect_pcep_bandwidth_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
+{
+ guint32 bandwidth;
+
+ if (obj_length != OBJ_HDR_LEN+BANDWIDTH_OBJ_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad BANDWIDTH object length %u, should be %u", obj_length,
+ OBJ_HDR_LEN+BANDWIDTH_OBJ_LEN);
+ return;
+ }
+
+ bandwidth = tvb_get_ntohl(tvb, offset2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 4, "Bandwidth: 0x%x", bandwidth);
+}
+
+/*------------------------------------------------------------------------------
+ * METRIC OBJECT
+ *------------------------------------------------------------------------------*/
+#define METRIC_OBJ_LEN 8
+
+static void
+dissect_pcep_metric_obj(proto_tree *pcep_object_tree,
+ tvbuff_t *tvb, int offset2, int obj_length)
+{
+ proto_tree *pcep_metric_obj_flags;
+ proto_item *ti;
+ guint16 reserved;
+ guint8 flags;
+ guint8 metric_type;
+ guint32 metric_value;
+
+ if (obj_length != OBJ_HDR_LEN+METRIC_OBJ_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad METRIC object length %u, should be %u", obj_length,
+ OBJ_HDR_LEN+METRIC_OBJ_LEN);
+ return;
+ }
+
+ reserved = tvb_get_ntohs(tvb, offset2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 2, "Reserved: %u", reserved);
+
+ flags = tvb_get_guint8(tvb, offset2+2);
+ ti = proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 1, "Flags: 0x%02x", flags);
+ pcep_metric_obj_flags = proto_item_add_subtree(ti, ett_pcep_obj_metric);
+ proto_tree_add_boolean(pcep_metric_obj_flags, pcep_metric_flags_c, tvb, offset2+2, 1, flags);
+ proto_tree_add_boolean(pcep_metric_obj_flags, pcep_metric_flags_b, tvb, offset2+2, 1, flags);
+
+ metric_type = tvb_get_guint8(tvb, offset2+3);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, val_to_str(metric_type, pcep_metric_obj_vals, "Unknown Object (%u). "));
+
+ metric_value = tvb_get_ntohl(tvb, offset2+4);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Metric Value: 0x%x", metric_value);
+}
+
+/*------------------------------------------------------------------------------
+ * EXPLICIT ROUTE OBJECT (ERO)
+ *------------------------------------------------------------------------------*/
+static void
+dissect_pcep_explicit_route_obj(proto_tree *pcep_object_tree,
+ tvbuff_t *tvb, int offset2, int obj_length, int obj_class)
+{
+ guint8 l_type;
+ guint8 length;
+ guint type_exp_route;
+ guint body_obj_len;
+
+ body_obj_len = obj_length - OBJ_HDR_LEN;
+
+ while(body_obj_len){
+ if (body_obj_len < 2) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
+ "Bad ERO object: subobject goes past end of object");
+ break;
+ }
+
+ l_type = tvb_get_guint8(tvb, offset2);
+ length = tvb_get_guint8(tvb, offset2+1);
+
+ if (length < 2) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
+ "Bad ERO object: subobject length %u < 2",
+ length);
+ break;
+ }
+
+ type_exp_route = (l_type & Mask_Type);
+ if (body_obj_len <length) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, length,
+ "Bad ERO object: subobject length %u > remaining length %u",
+ length, body_obj_len);
+ break;
+ }
+
+ switch(type_exp_route) {
+
+ case PCEP_SUB_IPv4:
+ dissect_subobj_ipv4(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_explicit_route, l_type, length);
+ break;
+ case PCEP_SUB_IPv6:
+ dissect_subobj_ipv6(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_explicit_route, l_type, length);
+ break;
+ case PCEP_SUB_LABEL_CONTROL:
+ dissect_subobj_label_control(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_explicit_route, l_type, length);
+ break;
+ case PCEP_SUB_UNNUMB_INTERFACE_ID:
+ dissect_subobj_unnumb_interfaceID(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_explicit_route, l_type, length);
+ break;
+ case PCEP_SUB_AUTONOMOUS_SYS_NUM:
+ dissect_subobj_autonomous_sys_num(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_explicit_route, l_type, length);
+ break;
+ default:
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, length, "Non defined subobject (%d)", type_exp_route);
+ break;
+ }
+ offset2 += length;
+ body_obj_len -= length;
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * RECORD ROUTE OBJECT (RRO)
+ *------------------------------------------------------------------------------*/
+static void
+dissect_pcep_record_route_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length, int obj_class)
+{
+ guint8 type;
+ guint8 length;
+ guint body_obj_len;
+
+ body_obj_len = obj_length - OBJ_HDR_LEN;
+
+ while(body_obj_len){
+ if (body_obj_len < 2) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
+ "Bad RRO object: subobject goes past end of object");
+ break;
+ }
+
+ type = tvb_get_guint8(tvb, offset2);
+ length = tvb_get_guint8(tvb, offset2+1);
+
+ if (length < 2) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
+ "Bad RRO object: subobject length %u < 2",
+ length);
+ break;
+ }
+
+ if (body_obj_len <length) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, length,
+ "Bad RRO subobject: subobject length %u > remaining length %u",
+ length, body_obj_len);
+ break;
+ }
+
+ switch(type) {
+
+ case PCEP_SUB_IPv4:
+ dissect_subobj_ipv4(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_record_route, type, length);
+ break;
+ case PCEP_SUB_IPv6:
+ dissect_subobj_ipv6(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_record_route, type, length);
+ break;
+ case PCEP_SUB_LABEL_CONTROL:
+ dissect_subobj_label_control(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_record_route, type, length);
+ break;
+ case PCEP_SUB_UNNUMB_INTERFACE_ID:
+ dissect_subobj_unnumb_interfaceID(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_record_route, type, length);
+ break;
+ default:
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, length, "Non defined subobject (%d)", type);
+ break;
+ }
+ offset2 += length;
+ body_obj_len -= length;
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * LSPA OBJECT
+ *------------------------------------------------------------------------------*/
+#define LSPA_OBJ_MIN_LEN 16
+
+static void
+dissect_pcep_lspa_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
+{
+ proto_tree *pcep_lspa_obj_flags;
+ proto_item *ti;
+ guint32 exclude_any;
+ guint32 include_any;
+ guint32 include_all;
+ guint8 setup_prio;
+ guint8 holding_prio;
+ guint8 flags;
+ guint8 reserved;
+
+ if (obj_length < OBJ_HDR_LEN+LSPA_OBJ_MIN_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad LSPA object length %u, should be >= %u", obj_length,
+ OBJ_HDR_LEN+LSPA_OBJ_MIN_LEN);
+ return;
+ }
+
+ exclude_any = tvb_get_ntohl(tvb, offset2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 4, "Exclude-Any: 0x%08x", exclude_any);
+
+ include_any = tvb_get_ntohl(tvb, offset2+4);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Include-Any: 0x%08x", include_any);
+
+ include_all = tvb_get_ntohl(tvb, offset2+8);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+8, 4, "Include-All: 0x%08x", include_all);
+
+ setup_prio = tvb_get_guint8(tvb, offset2+12);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+12, 1, "Setup Priority: %u", setup_prio);
+
+ holding_prio = tvb_get_guint8(tvb, offset2+13);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+13, 1, "Holding Priority: %u", holding_prio);
+
+ flags = tvb_get_guint8(tvb, offset2+14);
+ ti = proto_tree_add_text(pcep_object_tree, tvb, offset2+14, 1, "Flags: 0x%02x", flags);
+ pcep_lspa_obj_flags = proto_item_add_subtree(ti, ett_pcep_obj_metric);
+ proto_tree_add_boolean(pcep_lspa_obj_flags, pcep_lspa_flags_l, tvb, offset2+14, 1, flags);
+
+ reserved = tvb_get_guint8(tvb, offset2+15);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+15, 1, "Reserved: 0x%02x", reserved);
+
+ /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
+ offset2 += LSPA_OBJ_MIN_LEN;
+ obj_length -= OBJ_HDR_LEN+LSPA_OBJ_MIN_LEN;
+ dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_lspa);
+}
+
+/*------------------------------------------------------------------------------
+ * INCLUDE ROUTE OBJECT (IRO)
+ *------------------------------------------------------------------------------*/
+static void
+dissect_pcep_iro_obj(proto_tree *pcep_object_tree,
+ tvbuff_t *tvb, int offset2, int obj_length, int obj_class)
+{
+ guint8 l_type;
+ guint8 length;
+ int type_iro;
+ guint body_obj_len;
+
+ body_obj_len = obj_length - OBJ_HDR_LEN;
+
+ while(body_obj_len){
+ if (body_obj_len < 2) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
+ "Bad IRO object: subobject goes past end of object");
+ break;
+ }
+
+ l_type = tvb_get_guint8(tvb, offset2);
+ length = tvb_get_guint8(tvb, offset2+1);
+
+ if (length < 2) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
+ "Bad IRO object: subobject length %u < 2",
+ length);
+ break;
+ }
+
+ type_iro = (l_type & Mask_Type);
+
+ if (body_obj_len <length) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, length,
+ "Bad IRO object: subobject length %u > remaining length %u",
+ length, body_obj_len);
+ break;
+ }
+
+ switch(type_iro) {
+
+ case PCEP_SUB_IPv4:
+ dissect_subobj_ipv4(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_iro, l_type, length);
+ break;
+ case PCEP_SUB_IPv6:
+ dissect_subobj_ipv6(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_iro, l_type, length);
+ break;
+ case PCEP_SUB_UNNUMB_INTERFACE_ID:
+ dissect_subobj_unnumb_interfaceID(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_iro, l_type, length);
+ break;
+ case PCEP_SUB_AUTONOMOUS_SYS_NUM:
+ dissect_subobj_autonomous_sys_num(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_iro, l_type, length);
+ break;
+ case PCEP_SUB_EXRS:
+ dissect_subobj_exrs(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_iro, type_iro, l_type, length);
+ break;
+ default:
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, length, "Non defined subobject (%d)", type_iro);
+ break;
+ }
+ offset2 += length;
+ body_obj_len -= length;
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * SVEC OBJECT
+ *------------------------------------------------------------------------------*/
+#define SVEC_OBJ_MIN_LEN 4
+
+static void
+dissect_pcep_svec_obj(proto_tree *pcep_object_tree,
+ tvbuff_t *tvb, int offset2, int obj_length)
+{
+ proto_item *ti;
+ proto_tree *pcep_svec_flags_obj;
+ guint8 reserved;
+ guint32 flags;
+ int m = 1;
+ int i = 0;
+
+ if (obj_length < OBJ_HDR_LEN+SVEC_OBJ_MIN_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad SVEC object length %u, should be >= %u", obj_length,
+ OBJ_HDR_LEN+SVEC_OBJ_MIN_LEN);
+ return;
+ }
+
+ reserved = tvb_get_guint8(tvb, offset2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "Reserved: 0x%02x", reserved);
+
+ flags = tvb_get_ntoh24(tvb, offset2+1);
+ ti = proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 3, "Flags: 0x%06x", flags);
+ pcep_svec_flags_obj = proto_item_add_subtree(ti, ett_pcep_obj_svec);
+ proto_tree_add_boolean(pcep_svec_flags_obj, pcep_svec_flags_l, tvb, offset2 + 1, 3, flags);
+ proto_tree_add_boolean(pcep_svec_flags_obj, pcep_svec_flags_n, tvb, offset2 + 1, 3, flags);
+ proto_tree_add_boolean(pcep_svec_flags_obj, pcep_svec_flags_s, tvb, offset2 + 1, 3, flags);
+
+ for ( i=4 ; i<(obj_length-OBJ_HDR_LEN) ; ){
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+i, 4, "Request-ID-Number %u: 0x%s", m,
+ bytestring_to_str(tvb_get_ptr(tvb, offset2+i, 4), 4, ' '));
+ i += 4;
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * NOTIFICATION OBJECT
+ *------------------------------------------------------------------------------*/
+#define NOTIFICATION_OBJ_MIN_LEN 4
+
+static void
+dissect_pcep_notification_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
+{
+ guint8 reserved;
+ guint8 flags;
+ guint8 nt;
+ guint8 nv;
+
+ if (obj_length < OBJ_HDR_LEN+NOTIFICATION_OBJ_MIN_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad NOTIFICATION object length %u, should be >= %u", obj_length,
+ OBJ_HDR_LEN+NOTIFICATION_OBJ_MIN_LEN);
+ return;
+ }
+
+ reserved = tvb_get_guint8(tvb, offset2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "Reserved: 0x%02x", reserved);
+
+ flags = tvb_get_guint8(tvb, offset2+1);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 1, "Flags: 0x%02x", flags);
+
+ nt = tvb_get_guint8(tvb, offset2+2);
+ proto_tree_add_uint(pcep_object_tree, pcep_filter[PCEPF_NOTI_TYPE], tvb, offset2+2, 1, nt);
+
+ switch(nt){
+
+ case 1:
+ proto_tree_add_uint(pcep_object_tree, pcep_filter[PCEPF_NOTI_VAL1], tvb, offset2+2, 1, nt);
+ break;
+
+ case 2:
+ proto_tree_add_uint(pcep_object_tree, pcep_filter[PCEPF_NOTI_VAL2], tvb, offset2+2, 1, nt);
+ break;
+
+ default:
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 1, "Notification Type: %u", nt);
+ break;
+ }
+
+ nv = tvb_get_guint8(tvb, offset2+3);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "Notification Value: 0x%02x", nv);
+
+ /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
+ offset2 += NOTIFICATION_OBJ_MIN_LEN;
+ obj_length -= OBJ_HDR_LEN+NOTIFICATION_OBJ_MIN_LEN;
+ dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_notification);
+}
+
+/*------------------------------------------------------------------------------
+ * ERROR OBJECT
+ *------------------------------------------------------------------------------*/
+#define ERROR_OBJ_MIN_LEN 4
+
+static void
+dissect_pcep_error_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
+{
+ proto_tree *pcep_error_types_obj;
+ proto_item *ti;
+ guint8 reserved;
+ guint8 flags;
+ guint8 error_type;
+ guint8 error_value;
+
+ if (obj_length < OBJ_HDR_LEN+ERROR_OBJ_MIN_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad ERROR object length %u, should be >= %u", obj_length,
+ OBJ_HDR_LEN+ERROR_OBJ_MIN_LEN);
+ return;
+ }
+
+ reserved = tvb_get_guint8(tvb, offset2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "Reserved: 0x%02x", reserved);
+
+ flags = tvb_get_guint8(tvb, offset2+1);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 1, "Flags: 0x%02x", flags);
+
+ error_type = tvb_get_guint8(tvb, offset2+2);
+ ti = proto_tree_add_uint(pcep_object_tree, pcep_filter[PCEPF_ERROR_TYPE], tvb, offset2+2, 1, error_type);
+ pcep_error_types_obj = proto_item_add_subtree(ti, ett_pcep_obj_error);
+
+ error_value = tvb_get_guint8(tvb, offset2+3);
+ switch(error_type){
+ case ESTABLISH_FAILURE:
+ switch(error_value){
+ case RX_MALFORM_PKT:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Reception of a Malformed Message ", error_value);
+ break;
+ case NO_OPEN_MSG:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u No Open Message received before the expiration of the OpenWait Timer ", error_value);
+ break;
+ case UNACEP_NO_NEGO_SSESION:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Unacceptable and non Negotiable session characteristics", error_value);
+ break;
+ case UNACEP_NEG_SESSION:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Unacceptable but Negotiable session characteristics", error_value);
+ break;
+ case TWO_OPEN_MSG_UNACEP:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Reception of a second Open Message with still Unacceptable Session characteristics", error_value);
+ break;
+ case RX_PCEPERR_UNACEP_SESSION:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Reception of a PCEPrr message proposing unacceptable session characteristics", error_value);
+ break;
+ case NO_KEEPALIVE_PCEPERR:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u NO Keepalive or PCEPrr message received before the expiration of the Keepwait timer supported", error_value);
+ break;
+ default:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
+ "Error-value: %u Non defined Error-Value", error_value);
+ }
+ break;
+
+ case CAP_NOT_SUPPORTED:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
+ break;
+
+ case UNKNOWN_OBJ:
+ switch(error_value){
+ case UNRECON_OBJ_CLASS:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Unrecognized object class", error_value);
+ break;
+ case UNRECON_OBJ_TYPE:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Unrecognized object type", error_value);
+ break;
+ default:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
+ "Error-value: %u Non defined Error-Value", error_value);
+ }
+ break;
+ case NOT_SUPP_OBJ:
+ switch(error_value){
+ case NO_SUPP_OBJ:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Not Supported Object Class", error_value);
+ break;
+ case NO_SUPP_TYPE:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Not Supported Object Type", error_value);
+ break;
+ default:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
+ "Error-value: %u Non defined Error-Value", error_value);
+ }
+ break;
+ case POLICY_VIOLATION:
+ switch(error_value){
+ case C_METRIC_SET:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u C bit of the METRIC object set (Request Rejected)", error_value);
+ break;
+ case O_OBJ_SET:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u O bit of the RP object set (Request Rejected)", error_value);
+ break;
+ default:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
+ "Error-value: %u Non defined Error-Value", error_value);
+ }
+ break;
+ case MANDATORY_OBJ_MIS:
+ switch(error_value){
+ case RP_OBJ_MISS:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u RP Object missing", error_value);
+ break;
+ case RRO_OBJ_MISS:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u RRO Object missing for a reoptimization request (R bit of the RP Object set) when bandwidth is not equal to 0", error_value);
+ break;
+ case END_POINT_OBJ_MISS:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u END-POINTS Objects missing", error_value);
+ break;
+ default:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
+ "Error-value: %u Non defined Error-Value", error_value);
+ }
+ break;
+ case SYNCH_PCREQ_MIS:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
+ break;
+ case UNKNOWN_REQ_REF:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
+ break;
+ case ATTEMPT_2_SESSION:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
+ break;
+ case UNRECO_IRO_SUBOBJ:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
+ break;
+ case UNRECO_EXRS_SUBOBJ:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
+ break;
+
+ default:
+ proto_tree_add_text(pcep_error_types_obj, tvb, offset2+2, 1, "Error-Type: %u Non defined Error-Value", error_type);
+ }
+
+ /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
+ offset2 += ERROR_OBJ_MIN_LEN;
+ obj_length -= OBJ_HDR_LEN+ERROR_OBJ_MIN_LEN;
+ dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_error);
+}
+
+
+/*------------------------------------------------------------------------------
+ * LOAD-BALANCING OBJECT
+ *------------------------------------------------------------------------------*/
+#define LOAD_BALANCING_OBJ_MIN_LEN 8
+
+static void
+dissect_pcep_balancing_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
+{
+ guint16 reserved;
+ guint8 flags;
+ guint8 max_LSP;
+ guint32 min_bandwidth;
+
+ if (obj_length < OBJ_HDR_LEN+LOAD_BALANCING_OBJ_MIN_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad LOAD-BALANCING object length %u, should be >= %u", obj_length,
+ OBJ_HDR_LEN+LOAD_BALANCING_OBJ_MIN_LEN);
+ return;
+ }
+
+ reserved = tvb_get_ntohs(tvb, offset2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 2, "Reserved: 0x%04x", reserved);
+
+ flags = tvb_get_guint8(tvb, offset2+2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 1, "Flags: 0x%02x", flags);
+
+ max_LSP = tvb_get_guint8(tvb, offset2+3);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "Maximun Number of TE LSPs: 0x%02x", max_LSP);
+
+ min_bandwidth = tvb_get_ntohl(tvb, offset2+4);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Minimun Bandwidth: 0x%08x", min_bandwidth);
+
+ /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
+ offset2 += LOAD_BALANCING_OBJ_MIN_LEN;
+ obj_length -= OBJ_HDR_LEN+LOAD_BALANCING_OBJ_MIN_LEN;
+ dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_load_balancing);
+}
+
+/*------------------------------------------------------------------------------
+ * CLOSE OBJECT
+ *------------------------------------------------------------------------------*/
+#define CLOSE_OBJ_MIN_LEN 4
+
+static void
+dissect_pcep_close_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
+{
+ guint16 reserved;
+ guint8 flags;
+ guint8 reason;
+
+ if (obj_length < OBJ_HDR_LEN+CLOSE_OBJ_MIN_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad CLOSE object length %u, should be >= %u", obj_length,
+ OBJ_HDR_LEN+CLOSE_OBJ_MIN_LEN);
+ return;
+ }
+
+ reserved = tvb_get_ntohs(tvb, offset2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 2, "Reserved: 0x%04x", reserved);
+
+ flags = tvb_get_guint8(tvb, offset2+2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 1, "Flags: 0x%02x", flags);
+
+ reason = tvb_get_guint8(tvb, offset2+3);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, val_to_str(reason, pcep_close_reason_obj_vals, "Unknown Object (%u). "));
+
+ /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
+ offset2 += CLOSE_OBJ_MIN_LEN;
+ obj_length -= OBJ_HDR_LEN+CLOSE_OBJ_MIN_LEN;
+ dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_load_balancing);
+}
+
+/*------------------------------------------------------------------------------
+ * XRO OBJECT
+ *------------------------------------------------------------------------------*/
+#define XRO_OBJ_MIN_LEN 4
+
+static void
+dissect_pcep_xro_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length, int obj_class)
+{
+ proto_tree *pcep_xro_flags_obj;
+ proto_item *ti;
+ guint16 reserved;
+ guint16 flags;
+ guint8 x_type;
+ guint8 length;
+ guint type_xro;
+ guint body_obj_len;
+
+ body_obj_len = obj_length - OBJ_HDR_LEN;
+
+ if (obj_length < OBJ_HDR_LEN+XRO_OBJ_MIN_LEN) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+ "Bad XRO object length %u, should be >= %u", obj_length,
+ OBJ_HDR_LEN+XRO_OBJ_MIN_LEN);
+ return;
+ }
+
+ reserved = tvb_get_ntohs(tvb, offset2);
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 2, "Reserved: 0x%04x", reserved);
+
+ flags = tvb_get_ntohs(tvb, offset2+2);
+ ti = proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 2, "Flags: 0x%04x ", flags);
+ pcep_xro_flags_obj = proto_item_add_subtree(ti, ett_pcep_obj_xro);
+ proto_tree_add_boolean(pcep_xro_flags_obj, pcep_xro_flags_f, tvb, offset2 + 2, 2, flags);
+
+ offset2 += XRO_OBJ_MIN_LEN;
+ body_obj_len -= XRO_OBJ_MIN_LEN;
+
+ while(body_obj_len >= 2){
+ if (body_obj_len < 2) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
+ "Bad XRO object: subobject goes past end of object");
+ break;
+ }
+
+ x_type = tvb_get_guint8(tvb, offset2);
+ length = tvb_get_guint8(tvb, offset2+1);
+
+ if (length < 2) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
+ "Bad XRO object: object length %u < 2", length);
+ break;
+ }
+
+ type_xro = (x_type & Mask_Type);
+
+ if (body_obj_len <length) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset2, length,
+ "Bad XRO object: object length %u > remaining length %u",
+ length, body_obj_len);
+ break;
+ }
+
+ switch(type_xro) {
+
+ case PCEP_SUB_IPv4:
+ dissect_subobj_ipv4(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_xro, x_type, length);
+ break;
+ case PCEP_SUB_IPv6:
+ dissect_subobj_ipv6(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_xro, x_type, length);
+ break;
+ case PCEP_SUB_UNNUMB_INTERFACE_ID_XRO:
+ dissect_subobj_unnumb_interfaceID(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_xro, x_type, length);
+ break;
+ case PCEP_SUB_AUTONOMOUS_SYS_NUM_XRO:
+ dissect_subobj_autonomous_sys_num(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_xro, x_type, length);
+ break;
+ case PCEP_SUB_SRLG:
+ dissect_subobj_srlg(pcep_object_tree, tvb, offset2, ett_pcep_obj_xro, x_type, length);
+ break;
+ default:
+ proto_tree_add_text(pcep_object_tree, tvb, offset2-4, length, "Non defined subobject (%d)", type_xro);
+ break;
+ }
+ offset2 += length;
+ body_obj_len -= length;
+ }
+}
+
+/*------------------------------------------------------------------------------*/
+/* Dissect in Objects */
+/*------------------------------------------------------------------------------*/
+static void
+dissect_pcep_obj_tree(proto_tree *pcep_tree, tvbuff_t *tvb, int len, int offset, int msg_length)
+{
+ guint8 obj_class;
+ guint8 ot_res_p_i;
+ guint16 obj_length;
+ int type;
+ proto_tree *pcep_object_tree;
+ proto_item *pcep_object_item;
+ proto_tree *pcep_header_obj_flags;
+ proto_item *ti;
+
+ while (len < msg_length) {
+ obj_class = tvb_get_guint8(tvb, offset);
+ switch (obj_class) {
+
+ case PCEP_OPEN_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_OPEN], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_open);
+ break;
+
+ case PCEP_RP_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_RP], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_request_parameters);
+ break;
+
+ case PCEP_NO_PATH_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_NO_PATH], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_no_path);
+ break;
+
+ case PCEP_END_POINT_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_END_POINT], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_end_point);
+ break;
+
+ case PCEP_BANDWIDTH_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_BANDWIDTH], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_bandwidth);
+ break;
+
+ case PCEP_METRIC_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_METRIC], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_metric);
+ break;
+
+ case PCEP_EXPLICIT_ROUTE_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_EXPLICIT_ROUTE], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_explicit_route);
+ break;
+
+ case PCEP_RECORD_ROUTE_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_RECORD_ROUTE], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_record_route);
+ break;
+
+ case PCEP_LSPA_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_LSPA], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_lspa);
+ break;
+
+ case PCEP_IRO_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_IRO], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_iro);
+ break;
+
+ case PCEP_SVEC_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_SVEC], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_svec);
+ break;
+
+ case PCEP_NOTIFICATION_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_NOTIFICATION], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_notification);
+ break;
+
+ case PCEP_PCEP_ERROR_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_PCEP_ERROR], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_error);
+ break;
+
+ case PCEP_LOAD_BALANCING_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_LOAD_BALANCING], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_load_balancing);
+ break;
+
+ case PCEP_CLOSE_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_CLOSE], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_close);
+ break;
+
+ case PCEP_XRO_OBJ:
+ pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_XRO], tvb, offset, -1, FALSE);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_xro);
+ break;
+
+ default:
+ pcep_object_item = proto_tree_add_text(pcep_tree, tvb, offset, -1, "Unknown object (%u)", obj_class);
+ pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_unknown);
+ break;
+ }
+
+ proto_tree_add_uint(pcep_object_tree, pcep_filter[PCEPF_OBJECT_CLASS], tvb, offset, 1, obj_class);
+
+ ot_res_p_i = tvb_get_guint8(tvb, offset+1);
+ type = (ot_res_p_i & MASK_OBJ_TYPE)>>4;
+ proto_tree_add_text(pcep_object_tree, tvb, offset+1, 1, "Object Type: %u", type);
+
+ ti = proto_tree_add_text(pcep_object_tree, tvb, offset+1, 1, "Flags");
+ pcep_header_obj_flags = proto_item_add_subtree(ti, ett_pcep_hdr);
+ proto_tree_add_boolean(pcep_header_obj_flags, pcep_hdr_obj_flags_reserved, tvb, offset+1, 1, ot_res_p_i);
+ proto_tree_add_boolean(pcep_header_obj_flags, pcep_hdr_obj_flags_p, tvb, offset+1, 1, ot_res_p_i);
+ proto_tree_add_boolean(pcep_header_obj_flags, pcep_hdr_obj_flags_i, tvb, offset+1, 1, ot_res_p_i);
+
+ obj_length = tvb_get_ntohs(tvb, offset+2);
+ proto_item_set_len(pcep_object_item, obj_length);
+ if (obj_length < 4) {
+ proto_tree_add_text(pcep_object_tree, tvb, offset+2, 2, "Object Length: %u (bogus, must be >= 4)", obj_length);
+ break;
+ }
+ proto_tree_add_text(pcep_object_tree, tvb, offset+2, 2, "Object Length: %u", obj_length);
+
+ switch(obj_class) {
+
+ case PCEP_OPEN_OBJ:
+ dissect_pcep_open_obj(pcep_object_tree, tvb, offset+4, obj_length);
+ break;
+
+ case PCEP_RP_OBJ:
+ dissect_pcep_rp_obj(pcep_object_tree, tvb, offset+4, obj_length);
+ break;
+
+ case PCEP_NO_PATH_OBJ:
+ dissect_pcep_no_path_obj(pcep_object_tree, tvb, offset+4, obj_length);
+ break;
+
+ case PCEP_END_POINT_OBJ:
+ dissect_pcep_end_point_obj(pcep_object_tree, tvb, offset+4, obj_length, type);
+ break;
+
+ case PCEP_BANDWIDTH_OBJ:
+ dissect_pcep_bandwidth_obj(pcep_object_tree, tvb, offset+4, obj_length);
+ break;
+
+ case PCEP_METRIC_OBJ:
+ dissect_pcep_metric_obj(pcep_object_tree, tvb, offset+4, obj_length);
+ break;
+
+ case PCEP_EXPLICIT_ROUTE_OBJ:
+ dissect_pcep_explicit_route_obj(pcep_object_tree, tvb, offset+4, obj_length, obj_class);
+ break;
+
+ case PCEP_RECORD_ROUTE_OBJ:
+ dissect_pcep_record_route_obj(pcep_object_tree, tvb, offset+4, obj_length, obj_class);
+ break;
+
+ case PCEP_LSPA_OBJ:
+ dissect_pcep_lspa_obj(pcep_object_tree, tvb, offset+4, obj_length);
+ break;
+
+ case PCEP_IRO_OBJ:
+ dissect_pcep_iro_obj(pcep_object_tree, tvb, offset+4, obj_length, obj_class);
+ break;
+
+ case PCEP_SVEC_OBJ:
+ dissect_pcep_svec_obj(pcep_object_tree, tvb, offset+4, obj_length);
+ break;
+
+ case PCEP_NOTIFICATION_OBJ:
+ dissect_pcep_notification_obj(pcep_object_tree, tvb, offset+4, obj_length);
+ break;
+
+ case PCEP_PCEP_ERROR_OBJ:
+ dissect_pcep_error_obj(pcep_object_tree, tvb, offset+4, obj_length);
+ break;
+
+ case PCEP_LOAD_BALANCING_OBJ:
+ dissect_pcep_balancing_obj(pcep_object_tree, tvb, offset+4, obj_length);
+ break;
+
+ case PCEP_CLOSE_OBJ:
+ dissect_pcep_close_obj(pcep_object_tree, tvb, offset+4, obj_length);
+ break;
+
+ case PCEP_XRO_OBJ:
+ dissect_pcep_xro_obj(pcep_object_tree, tvb, offset+4, obj_length, obj_class);
+ break;
+
+ default:
+ proto_tree_add_text(pcep_object_tree, tvb, offset+4, obj_length-OBJ_HDR_LEN, "PCEP Object BODY non defined (%u)", type);
+ break;
+ }
+
+ offset += obj_length;
+ len += obj_length;
+ }
+}
+
+
+/*------------------------------------------------------------------------------
+ * Dissect a single PCEP message in a tree
+ *------------------------------------------------------------------------------*/
+static void
+dissect_pcep_msg_tree(tvbuff_t *tvb, proto_tree *tree, guint tree_mode, packet_info *pinfo)
+{
+ proto_tree *pcep_tree = NULL;
+ proto_tree *pcep_header_tree;
+ proto_tree *ti;
+ proto_tree *pcep_header_msg_flags;
+
+ int offset = 0;
+ int len=0;
+ guint8 ver_flags;
+ guint8 message_type;
+ guint16 msg_length;
+
+ ver_flags = tvb_get_guint8(tvb, 0);
+ message_type = tvb_get_guint8(tvb, 1);
+ msg_length = tvb_get_ntohs(tvb, 2);
+
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(message_type, message_type_vals, "Unknown Message (%u). "));
+ }
+
+ ti = proto_tree_add_item(tree, proto_pcep, tvb, offset, msg_length, FALSE);
+ pcep_tree = proto_item_add_subtree(ti, tree_mode);
+
+ ti = proto_tree_add_text(pcep_tree, tvb, offset, 4, "%s Header", val_to_str(message_type, message_type_vals, "Unknown Message (%u). "));
+
+ pcep_header_tree = proto_item_add_subtree(ti, ett_pcep_hdr);
+
+ proto_tree_add_text(pcep_header_tree, tvb, offset, 1, "PCEP Version: %x", (ver_flags & 0x20)>>5);
+
+ ti = proto_tree_add_text(pcep_header_tree, tvb, offset, 1, "Flags: 0x%02x", ver_flags & 0x1f);
+ pcep_header_msg_flags = proto_item_add_subtree(ti, ett_pcep_hdr);
+ proto_tree_add_boolean(pcep_header_msg_flags, pcep_hdr_msg_flags_reserved, tvb, offset, 1, (ver_flags & 0x1f));
+ proto_tree_add_uint(pcep_header_tree, pcep_filter[PCEPF_MSG], tvb, offset+1, 1, message_type);
+ proto_tree_add_text(pcep_header_tree, tvb, offset+2, 2, "Message length: %u", msg_length);
+
+ switch (PCEPF_MSG + message_type) {
+
+ case PCEPF_OPEN:
+ case PCEPF_KEEPALIVE:
+ case PCEPF_PATH_COMPUTATION_REQUEST:
+ case PCEPF_PATH_COMPUTATION_REPLY:
+ case PCEPF_NOTIFICATION:
+ case PCEPF_ERROR:
+ case PCEPF_CLOSE:
+ proto_tree_add_boolean_hidden(pcep_header_tree, pcep_filter[PCEPF_MSG + message_type], tvb, offset+1, 1, 1);
+ break;
+
+ default:
+ proto_tree_add_protocol_format(pcep_header_tree, proto_malformed, tvb, offset+1, 1, "Invalid message type: %u", message_type);
+ return;
+ }
+
+ offset = 4;
+ len = 4;
+
+ dissect_pcep_obj_tree(pcep_tree, tvb, len, offset, msg_length);
+}
+
+
+static guint
+get_pcep_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
+{
+ guint16 plen;
+
+ /* Get the length of the PCEP packet.*/
+ plen = tvb_get_ntohs(tvb, offset+2);
+
+ return plen;
+}
+
+static void
+dissect_pcep_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+
+/* Set up structures needed to add the protocol subtree and manage it */
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCEP");
+
+ /* Clear out stuff in the info column */
+ if(check_col(pinfo->cinfo,COL_INFO))
+ col_clear(pinfo->cinfo,COL_INFO);
+
+ if (tree) {
+ dissect_pcep_msg_tree(tvb, tree, ett_pcep, pinfo);
+ }
+}
+
+static void
+dissect_pcep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 4, get_pcep_message_len,
+ dissect_pcep_pdu);
+}
+
+/*Register le protocol with wireshark*/
+void
+proto_register_pcep(void){
+
+/*Register the protocol name and description*/
+ proto_pcep = proto_register_protocol (
+ "Path Computation Element communication Protocol", /* name*/
+ "PCEP", /* short name */
+ "pcep" /* abbrev*/);
+
+/* Required function calls to register the header fields and subtrees used */
+ proto_register_field_array(proto_pcep, pcepf_info, array_length(pcepf_info));
+ proto_register_subtree_array(ett, array_length(ett));
+}
+
+/*Dissector Handoff*/
+void
+proto_reg_handoff_pcep(void)
+{
+ dissector_handle_t pcep_handle;
+
+ pcep_handle = create_dissector_handle(dissect_pcep, proto_pcep);
+ dissector_add("tcp.port", TCP_PORT_PCEP, pcep_handle);
+}