Define some fcns & vars as static...
[metze/wireshark/wip.git] / epan / dissectors / packet-pcep.c
1 /* packet-pcep.c
2  * Routines for PCEP packet disassembly
3  * draft-ietf-pce-pcep-09
4  * draft-ietf-pce-pcep-xro-02
5  * See also RFC 4655 and RFC 4657
6  *
7  * (c) Copyright 2007 Silvia Cristina Tejedor <silviacristina.tejedor@gmail.com> 
8  *
9  * $Id$ 
10  *
11  * Wireshark - Network traffic analyzer
12  * By Gerald Combs <gerald@wireshark.org>
13  * Copyright 1998 Gerald Combs
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28  */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include <stdlib.h>
35
36 #include <glib.h>
37
38 #include <epan/packet.h>
39 #include <epan/dissectors/packet-tcp.h>
40
41 #include "packet-frame.h"
42
43 /*differents types of objects*/
44 #define PCEP_OPEN_OBJ                   1
45 #define PCEP_RP_OBJ                     2
46 #define PCEP_NO_PATH_OBJ                3
47 #define PCEP_END_POINT_OBJ              4
48 #define PCEP_BANDWIDTH_OBJ              5
49 #define PCEP_METRIC_OBJ                 6
50 #define PCEP_EXPLICIT_ROUTE_OBJ         7
51 #define PCEP_RECORD_ROUTE_OBJ           8
52 #define PCEP_LSPA_OBJ                   9
53 #define PCEP_IRO_OBJ                    10
54 #define PCEP_SVEC_OBJ                   11
55 #define PCEP_NOTIFICATION_OBJ           12
56 #define PCEP_PCEP_ERROR_OBJ             13
57 #define PCEP_LOAD_BALANCING_OBJ         14
58 #define PCEP_CLOSE_OBJ                  15
59 #define NO_DEFINED_OBJ                  16
60 #define PCEP_XRO_OBJ                    17
61
62 /*Subobjects of EXPLICIT ROUTE Object*/
63 #define PCEP_SUB_IPv4                           1
64 #define PCEP_SUB_IPv6                           2       
65 #define PCEP_SUB_LABEL_CONTROL                  3       
66 #define PCEP_SUB_UNNUMB_INTERFACE_ID            4
67 #define PCEP_SUB_SRLG                           5       
68 #define PCEP_SUB_AUTONOMOUS_SYS_NUM             32
69 #define PCEP_SUB_EXRS                           33
70 #define PCEP_SUB_AUTONOMOUS_SYS_NUM_XRO         4
71 #define PCEP_SUB_UNNUMB_INTERFACE_ID_XRO        3
72
73 /*Possible values of the NI in the NO-PATH object*/
74 #define NO_SATISFYING                   0
75 #define CHAIN_BROKEN                    1
76
77 /*Possible values of "Type (T)" in the METRIC object */
78 #define NO_DEFINED                      0
79 #define IGP_METRIC                      1
80 #define TE_METRIC                       2
81 #define HOP_COUNTS                      3
82
83 /*Possible values of L in the ERO and IRO objects */
84 #define STRICT_HOP                      0
85 #define LOOSE_HOP                       1
86
87 /*Possible values of U in the ERO and RRO objects */
88 #define DOWNSTREAM_LABEL                0
89 #define UPSTREAM_LABEL                  1
90
91 /*Possible values of Notification Type */
92 #define NOT_REQ_CANCEL                  1
93 #define PCEP_CONGESTION                 2
94
95 /*Possible values of Notification Value for NT=1*/
96 #define NOTI_PCC_CANCEL_REQ             1       
97 #define NOTI_PCE_CANCEL_REQ             2
98
99 /*Possible values of Notification Value for NT=2*/
100 #define NOTI_PCE_CONGEST                1       
101 #define NOTI_PCE_NO_CONGEST             2
102
103 /*Possible types of errors */
104 #define ESTABLISH_FAILURE               1
105 #define CAP_NOT_SUPPORTED               2
106 #define UNKNOWN_OBJ                     3       
107 #define NOT_SUPP_OBJ                    4
108 #define POLICY_VIOLATION                5
109 #define MANDATORY_OBJ_MIS               6       
110 #define SYNCH_PCREQ_MIS                 7       
111 #define UNKNOWN_REQ_REF                 8
112 #define ATTEMPT_2_SESSION               9
113 #define UNRECO_IRO_SUBOBJ               11
114 #define UNRECO_EXRS_SUBOBJ              12
115
116 /*Different values of errors type=1*/
117 #define RX_MALFORM_PKT                  1
118 #define NO_OPEN_MSG                     2
119 #define UNACEP_NO_NEGO_SSESION          3
120 #define UNACEP_NEG_SESSION              4       
121 #define TWO_OPEN_MSG_UNACEP             5
122 #define RX_PCEPERR_UNACEP_SESSION       6       
123 #define NO_KEEPALIVE_PCEPERR            7
124
125 /*Different values of errors type=3*/
126 #define UNRECON_OBJ_CLASS               1
127 #define UNRECON_OBJ_TYPE                2
128
129 /*Different values of errors type=4*/
130 #define NO_SUPP_OBJ                     1
131 #define NO_SUPP_TYPE                    2
132
133 /*Different values of errors type=5*/
134 #define C_METRIC_SET                    1
135 #define O_OBJ_SET                       2
136
137 /*Different values of errors type=6*/
138 #define RP_OBJ_MISS                     1
139 #define RRO_OBJ_MISS                    2
140 #define END_POINT_OBJ_MISS              3
141
142 /*Different values of Reason in the CLOSE object */
143 #define NO_EXP_PROV                     1
144 #define DEADTIME_PROV                   2
145 #define RECEP_MALFORM_MSG               3 
146
147 /*Different values of Attribute in the XRO object */
148 #define ATTR_INTERFACE                  0
149 #define ATTR_NODE                       1
150 #define ATTR_SRLG                       2
151
152 /*Mask for the flags of HEADER of Messages*/
153 #define  PCEP_HDR_MSG_RESERVED          0x1f
154
155 /*Mask for the type of HEADER of Objects*/
156 #define  MASK_OBJ_TYPE                  0xF0
157
158 /*Mask for the flags of HEADER of Objects*/
159 #define  PCEP_HDR_OBJ_RESERVED          0x0C
160 #define  PCEP_HDR_OBJ_P                 0x02
161 #define  PCEP_HDR_OBJ_I                 0x01
162
163 /*Mask for the flags of OPEN Object*/
164 #define  PCEP_OPEN_RES                  0x1F
165
166 /*Mask for the flags of RP Object*/
167 #define  PCEP_RP_PRI                    0x000007
168 #define  PCEP_RP_R                      0x000008
169 #define  PCEP_RP_B                      0x000010
170 #define  PCEP_RP_O                      0x000020
171 #define  PCEP_RP_RESERVED               0xFFFFC0
172
173 /*Mask for the flags of NO PATH Object*/
174 #define  PCEP_NO_PATH_C                 0x8000
175
176 /*Mask for the flags of METRIC Object*/
177 #define  PCEP_METRIC_C                  0x01
178 #define  PCEP_METRIC_B                  0x02
179
180 /*Mask for the flags of LSPA Object*/
181 #define  PCEP_LSPA_L                    0x01
182
183 /* Mask to differentiate the value of L and Type (Explicit Object)*/
184 #define Mask_L                          0x80
185 #define Mask_Type                       0x7f
186
187 #define TCP_PORT_PCEP                   1010    
188
189 #define IPv4                            1
190 #define IPv6                            2
191
192 /*Mask for the flags os SVEC Object*/
193 #define  PCEP_SVEC_L                    0x000001
194 #define  PCEP_SVEC_N                    0x000002
195 #define  PCEP_SVEC_S                    0x000004
196
197 /*Mask for the flags of XRO Object*/
198 #define  PCEP_XRO_F                     0x0001
199
200 /*Mask for the flags of IPv4, IPv6 and UNnumbered InterfaceID Subobjects of RRO Object*/
201 #define PCEP_SUB_LPA                    0x01
202 #define PCEP_SUB_LPU                    0x02
203
204 /*Mask for the flags of Label SubObject*/
205 #define PCEP_SUB_LABEL_GL               0x01
206
207
208 static int proto_pcep = -1;
209 static gint ett_pcep = -1;
210 static gint ett_pcep_hdr = -1;
211 static gint pcep_hdr_msg_flags_reserved= -1;
212 static gint pcep_hdr_obj_flags_reserved= -1;
213 static gint pcep_hdr_obj_flags_p= -1;
214 static gint pcep_hdr_obj_flags_i= -1;
215 static gint ett_pcep_obj_open = -1;
216 static gint pcep_open_flags_res = -1;
217 static gint ett_pcep_obj_request_parameters = -1;
218 static gint pcep_rp_flags_pri = -1;
219 static gint pcep_rp_flags_r = -1;
220 static gint pcep_rp_flags_b = -1;
221 static gint pcep_rp_flags_o = -1;
222 static gint pcep_rp_flags_reserved = -1;
223 static gint ett_pcep_obj_no_path = -1;
224 static gint pcep_no_path_flags_c = -1;
225 static gint ett_pcep_obj_end_point = -1;
226 static gint ett_pcep_obj_bandwidth = -1;
227 static gint ett_pcep_obj_metric = -1;
228 static gint pcep_metric_flags_c = -1;
229 static gint pcep_metric_flags_b = -1;
230 static gint ett_pcep_obj_explicit_route = -1;
231 static gint ett_pcep_obj_record_route = -1;
232 static gint ett_pcep_obj_lspa = -1;
233 static gint pcep_lspa_flags_l= -1;
234 static gint ett_pcep_obj_iro = -1;
235 static gint ett_pcep_obj_svec = -1;
236 static gint pcep_svec_flags_l= -1;
237 static gint pcep_svec_flags_n= -1;
238 static gint pcep_svec_flags_s= -1;
239 static gint ett_pcep_obj_notification = -1;
240 static gint ett_pcep_obj_error = -1;
241 static gint ett_pcep_obj_load_balancing = -1;
242 static gint ett_pcep_obj_close = -1;
243 static gint ett_pcep_obj_xro = -1;
244 static gint pcep_xro_flags_f= -1;
245 static gint pcep_subobj_flags_lpa= -1;
246 static gint pcep_subobj_flags_lpu= -1;
247 static gint pcep_subobj_label_flags_gl= -1;
248 static gint ett_pcep_obj_unknown = -1;
249
250 /* PCEP message types.*/
251 typedef enum {
252         PCEP_MSG_NO_VALID,
253         PCEP_MSG_OPEN,
254         PCEP_MSG_KEEPALIVE, 
255         PCEP_MSG_PATH_COMPUTATION_REQUEST,
256         PCEP_MSG_PATH_COMPUTATION_REPLY,        
257         PCEP_MSG_NOTIFICATION,          
258         PCEP_MSG_ERROR, 
259         PCEP_MSG_CLOSE   
260 } pcep_message_types;
261
262 static const value_string message_type_vals[] = {
263         {PCEP_MSG_OPEN,                         "OPEN MESSAGE"                          },
264         {PCEP_MSG_KEEPALIVE,                    "KEEPALIVE MESSAGE"                     },
265         {PCEP_MSG_PATH_COMPUTATION_REQUEST,     "PATH COMPUTATION REQUEST MESSAGE"      },
266         {PCEP_MSG_PATH_COMPUTATION_REPLY,       "PATH COMPUTATION REPLY MESSAGE"        },
267         {PCEP_MSG_NOTIFICATION,                 "NOTIFICATION MESSAGE"                  },
268         {PCEP_MSG_ERROR,                        "ERROR MESSAGE"                         },      
269         {PCEP_MSG_CLOSE,                        "CLOSE MESSAGE"                         },
270         {0,                                     NULL                                    }
271 };
272
273 static const value_string pcep_class_vals[] = {
274         {PCEP_OPEN_OBJ,                 "OPEN OBJECT"                   },
275         {PCEP_RP_OBJ,                   "RP OBJECT"                     },
276         {PCEP_NO_PATH_OBJ,              "NO-PATH OBJECT"                },
277         {PCEP_END_POINT_OBJ,            "END-POINT OBJECT"              },
278         {PCEP_BANDWIDTH_OBJ,            "BANDWIDTH OBJECT"              },
279         {PCEP_METRIC_OBJ,               "METRIC OBJECT"                 },      
280         {PCEP_EXPLICIT_ROUTE_OBJ,       "EXPLICIT ROUTE OBJECT (ERO)"   },      
281         {PCEP_RECORD_ROUTE_OBJ,         "RECORD ROUTE OBJECT (RRO)"     }, 
282         {PCEP_LSPA_OBJ,                 "LSPA OBJECT"                   },
283         {PCEP_IRO_OBJ,                  "IRO OBJECT"                    },
284         {PCEP_SVEC_OBJ,                 "SVEC OBJECT"                   },
285         {PCEP_NOTIFICATION_OBJ,         "NOTIFICATION OBJECT"           },
286         {PCEP_PCEP_ERROR_OBJ,           "PCEP ERROR OBJECT"             },
287         {PCEP_LOAD_BALANCING_OBJ,       "LOAD BALANCING OBJECT"         },
288         {PCEP_CLOSE_OBJ,                "CLOSE OBJECT"                  },
289         {NO_DEFINED_OBJ,                "Non Defined OBJECT"            },
290         {PCEP_XRO_OBJ,                  "EXCLUDE ROUTE OBJECT (XRO)"    },
291         {0,                              NULL                           }
292 };
293
294 static const value_string pcep_subobj_vals[] = {
295         {PCEP_SUB_IPv4,                 "SUBOBJECT IPv4"                        },
296         {PCEP_SUB_IPv6,                 "SUBOBJECT IPv6"                        },
297         {PCEP_SUB_LABEL_CONTROL,        "SUBOBJECT LABEL"                       },
298         {PCEP_SUB_UNNUMB_INTERFACE_ID,  "SUBOBJECT UNNUMBERED INTERFACE-ID"     },
299         {PCEP_SUB_SRLG,                 "SUBOBJECT SRLG"                        },
300         {PCEP_SUB_AUTONOMOUS_SYS_NUM,   "SUBOBJECT AUTONOMOUS SYSTEM NUMBER"    },
301         {0,                              NULL                                   }
302 };
303
304
305 static const value_string pcep_subobj_xro_vals[] = {
306         {PCEP_SUB_IPv4,                 "SUBOBJECT IPv4"                        },
307         {PCEP_SUB_IPv6,                 "SUBOBJECT IPv6"                        },
308         {PCEP_SUB_UNNUMB_INTERFACE_ID_XRO,"SUBOBJECT UNNUMBERED INTERFACE-ID"   }, 
309         {PCEP_SUB_AUTONOMOUS_SYS_NUM_XRO,"SUBOBJECT AUTONOMOUS SYSTEM NUMBER"   },
310         {PCEP_SUB_SRLG,                 "SUBOBJECT SRLG"                        },
311         {0,                              NULL                                   }
312 };
313
314 /*In the NO-PATH Object the two different possibilities that NI can have*/ 
315 static const value_string pcep_no_path_obj_vals[] = {
316         {NO_SATISFYING,                 "Nature of Issue: No path satisfying the set of constraints could be found (0x0)"       },
317         {CHAIN_BROKEN,                  "Nature of Issue: PCEP Chain Broken (0x1)"                                              },
318         {0,                              NULL                                                                                   }
319 };
320
321 /*Different values of "Type (T)" in the METRIC Obj */   
322 static const value_string pcep_metric_obj_vals[] = {
323         {NO_DEFINED,            "Type not defined"              },
324         {IGP_METRIC,            "Type: IGP Metric (T=1)"        },
325         {TE_METRIC,             "Type: TE Metric (T=2)"         },
326         {HOP_COUNTS,            "Type: Hop Counts (T=3)"        },      
327         {0,                      NULL                           }
328 };
329
330 /*Different values for (L) in the ERO and IRO Objs */ 
331 static const value_string pcep_route_l_obj_vals[] = {
332         {STRICT_HOP,                    "L=0 Strict Hop in the Explicit Route"          },
333         {LOOSE_HOP,                     "L=1 Loose Hop in the Explicit Route"           },
334         {0,                              NULL                                           }
335 };
336
337 /*Different values of the direction of the label (U) in the ERO and RRO Objs */ 
338 static const value_string pcep_route_u_obj_vals[] = {
339         {DOWNSTREAM_LABEL,                      "U=0 S Downstream Label" },
340         {UPSTREAM_LABEL,                        "U=1 Upstream Label"     },
341         {0,                                     NULL                     }
342 };
343
344 /*Values of Notification type*/
345 static const value_string pcep_notification_types_vals[] = {
346         {NOT_REQ_CANCEL,                "Pending Request Cancelled"     },
347         {PCEP_CONGESTION,               "PCE Congestion"                },
348         {0,                              NULL                                                   }
349 };
350
351 /*Values of Notification value for Notification Type=1*/
352 static const value_string pcep_notification_values1_vals[] = {
353         {NOTI_PCC_CANCEL_REQ,           "PCC Cancels a set of Pending Request (s)"      },
354         {NOTI_PCE_CANCEL_REQ,           "PCE Cancels a set of Pending Request (s)"      },
355         {0,                              NULL                                           }
356 };
357
358 /*Values of Notification value for Notification Type=2*/
359 static const value_string pcep_notification_values2_vals[] = {
360         {NOTI_PCE_CONGEST,              "PCE in Congested State"                },
361         {NOTI_PCE_NO_CONGEST,           "PCE no Longer in Congested state"      },
362         {0,                              NULL                                   }
363 };
364
365
366 /*Values of different types of errors*/
367 static const value_string pcep_error_types_obj_vals[] = {
368         {ESTABLISH_FAILURE,             "1 PCEP Session Establishment Failure"          },
369         {CAP_NOT_SUPPORTED,             "2 Capability non supported"                    },
370         {UNKNOWN_OBJ,                   "3 Unknown Object"                                      },
371         {NOT_SUPP_OBJ,                  "4 Not Supported Object"                                },
372         {POLICY_VIOLATION,              "5 Policy Violation"                            },
373         {MANDATORY_OBJ_MIS,             "6 Mandatory Object Missing"                    },
374         {SYNCH_PCREQ_MIS,               "7 Synchronized Path Computation Request Missing"       },
375         {UNKNOWN_REQ_REF,               "8 Unknown Request Reference"                   },
376         {ATTEMPT_2_SESSION,             "9 Attempt to Establish a Second PCEP Session"  },
377         {UNRECO_IRO_SUBOBJ,             "11 Unrecognized IRO Subobject" },
378         {UNRECO_EXRS_SUBOBJ,            "12 Unrecognized EXRS Subobject"        },
379         {0,                              NULL                                                   }
380 };
381
382 static const value_string pcep_close_reason_obj_vals[] = {
383         {NO_DEFINED,                    "Reason = 0 no defined"                                 },
384         {NO_EXP_PROV,                   "Reason = 1 No Explanation Provided "                   },
385         {DEADTIME_PROV,                 "Reason = 2 Deadtime Expired"                           },
386         {RECEP_MALFORM_MSG,             "Reason = 3 Reception of a Malformed PCEP Message"      },
387         {0,                              NULL                                                   }
388 };
389
390 static const value_string pcep_xro_attribute_obj_vals[] = {
391         {ATTR_INTERFACE,                "Attribute = 0 Interface"       },
392         {ATTR_NODE,                     "Attribute = 1 Node "           },
393         {ATTR_SRLG,                     "Attribute = 2 SRLG"            },
394         {0,                              NULL                   }
395 };
396
397 /* The PCEP filtering keys */
398 enum pcep_filter_keys{
399
400     PCEPF_MSG,
401
402     PCEPF_OPEN,
403     PCEPF_KEEPALIVE,
404     PCEPF_PATH_COMPUTATION_REQUEST,
405     PCEPF_PATH_COMPUTATION_REPLY,
406     PCEPF_NOTIFICATION,
407     PCEPF_ERROR,
408     PCEPF_CLOSE,     
409
410     PCEPF_OBJECT_CLASS,
411     PCEPF_OBJ_OPEN,
412     PCEPF_OBJ_RP,
413     PCEPF_OBJ_NO_PATH,
414     PCEPF_OBJ_END_POINT,
415     PCEPF_OBJ_BANDWIDTH,
416     PCEPF_OBJ_METRIC,
417     PCEPF_OBJ_EXPLICIT_ROUTE,
418     PCEPF_OBJ_RECORD_ROUTE,
419     PCEPF_OBJ_LSPA,
420     PCEPF_OBJ_IRO,
421     PCEPF_OBJ_SVEC,
422     PCEPF_OBJ_NOTIFICATION,
423     PCEPF_NOTI_TYPE,
424     PCEPF_NOTI_VAL1,
425     PCEPF_NOTI_VAL2,
426     PCEPF_OBJ_PCEP_ERROR,
427     PCEPF_ERROR_TYPE,
428     PCEPF_OBJ_LOAD_BALANCING,
429     PCEPF_OBJ_CLOSE,
430     PCEPF_OBJ_XRO,
431     PCEPF_SUBOBJ,
432     PCEPF_SUBOBJ_IPv4,
433     PCEPF_SUBOBJ_IPv6,
434     PCEPF_SUBOBJ_LABEL_CONTROL,
435     PCEPF_SUBOBJ_UNNUM_INTERFACEID,
436     PCEPF_SUBOBJ_AUTONOMOUS_SYS_NUM,
437     PCEPF_SUBOBJ_SRLG,
438     PCEPF_SUBOBJ_EXRS,
439     PCEPF_SUBOBJ_XRO,
440     PCEPF_SUB_XRO_ATTRIB,
441
442     PCEPF_MAX
443 };
444
445
446 /*Registering data structures*/
447
448 static gint *ett[] = {
449         &ett_pcep,
450         &ett_pcep_hdr,
451         &ett_pcep_obj_open,
452         &ett_pcep_obj_request_parameters,
453         &ett_pcep_obj_no_path,
454         &ett_pcep_obj_end_point,
455         &ett_pcep_obj_bandwidth,
456         &ett_pcep_obj_metric,
457         &ett_pcep_obj_explicit_route,
458         &ett_pcep_obj_record_route,
459         &ett_pcep_obj_lspa,
460         &ett_pcep_obj_iro,
461         &ett_pcep_obj_svec,
462         &ett_pcep_obj_notification,
463         &ett_pcep_obj_error,
464         &ett_pcep_obj_load_balancing,
465         &ett_pcep_obj_close, 
466         &ett_pcep_obj_xro,
467         &ett_pcep_obj_unknown
468 };
469
470 /*Registering data structures*/    
471
472 static int pcep_filter[PCEPF_MAX];
473
474 #define OBJ_HDR_LEN     4       /* length of object header */
475
476 static void
477 dissect_pcep_tlvs(proto_tree *pcep_obj, tvbuff_t *tvb, int offset, gint length, gint ett_pcep_obj)
478 {
479         proto_tree *tlv;
480         proto_item *ti;
481         guint16 tlv_length;
482         guint16 tlv_type;
483         int j;
484         int m = 0;
485         int padding = 0;
486
487         for (j = 0; j < length; j += 4 + tlv_length + padding){
488                 m = m+1;
489
490                 tlv_type = tvb_get_ntohs(tvb, offset+j);
491                 tlv_length = tvb_get_ntohs(tvb, offset + j + 2);
492                 ti = proto_tree_add_text(pcep_obj, tvb, offset + j, tlv_length+4, "TLV %u", m);
493                 tlv = proto_item_add_subtree(ti, ett_pcep_obj);
494                 proto_tree_add_text(tlv, tvb, offset + j, 2, "Type: %u", tlv_type);
495                 proto_tree_add_text(tlv, tvb, offset + 2 + j, 2, "Length: %u", tlv_length);
496                 proto_tree_add_text(tlv, tvb, offset+4+j, tlv_length, "Data: %s", 
497                                 bytestring_to_str(tvb_get_ptr(tvb, (offset) + 4 + j, tlv_length), tlv_length, ' '));
498                 padding = (4 - (tlv_length % 4)) % 4;
499                 if (padding != 0){
500                         proto_tree_add_text(tlv, tvb, offset+4+j+tlv_length, padding, "Padding: %s", 
501                                 bytestring_to_str(tvb_get_ptr(tvb, (offset) + 4 + j + tlv_length, padding), padding, ' '));
502                 }       
503         }
504 }
505
506 /*------------------------------------------------------------------------------
507  *SUBOBJECTS
508  *------------------------------------------------------------------------------*/
509 static void
510 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)
511 {
512         proto_tree *pcep_subobj_ipv4;
513         proto_tree *pcep_subobj_ipv4_flags;
514         proto_item *ti;
515         guint8 prefix_length;
516         guint8 resvd;
517         guint l;
518
519         prefix_length = tvb_get_guint8(tvb, offset+6);
520         resvd = tvb_get_guint8(tvb, offset+7);
521
522         ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_IPv4], tvb, offset, length, FALSE);
523         pcep_subobj_ipv4 = proto_item_add_subtree(ti, ett_pcep_obj);
524
525         if (length != 8) {
526                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, length,
527                     "Bad IPv4 subobject: length %u != 8", length);
528                 return;
529         }
530
531         switch(obj_class){
532
533         case PCEP_EXPLICIT_ROUTE_OBJ:
534                 l = (l_and_or_type& Mask_L)>>7;
535                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 1,  "%s",val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
536                 proto_tree_add_uint(pcep_subobj_ipv4, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
537                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+1, 1, "Length: %u", length);
538                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: (%s)", ip_to_str(tvb_get_ptr(tvb, offset+2, 4)));
539                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+6, 1, "Prefix Length: %u", prefix_length);
540                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1, "Padding: 0x%02x", resvd);
541                 break;
542
543         case PCEP_RECORD_ROUTE_OBJ:
544                 proto_tree_add_uint(pcep_subobj_ipv4, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, l_and_or_type);
545                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+1, 1, "Length: %u", length);
546                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: (%s)", ip_to_str(tvb_get_ptr(tvb, offset+2, 4)));
547                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+6, 1, "Prefix Length: %u", prefix_length);
548                 ti = proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1, "Flags: 0x%02x ", resvd);
549                 pcep_subobj_ipv4_flags = proto_item_add_subtree(ti, ett_pcep_obj);
550                 proto_tree_add_boolean(pcep_subobj_ipv4_flags, pcep_subobj_flags_lpa, tvb, offset+7, 1, resvd);
551                 proto_tree_add_boolean(pcep_subobj_ipv4_flags, pcep_subobj_flags_lpu, tvb, offset+7, 1, resvd);
552                 break;
553
554         case PCEP_IRO_OBJ:
555                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 1, "l: %x", (l_and_or_type & 0x80)>>7);
556                 proto_tree_add_uint(pcep_subobj_ipv4, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
557                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+1, 1, "Length: %u", length);
558                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: (%s)", ip_to_str(tvb_get_ptr(tvb, offset+2, 4)));
559                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+6, 1, "Prefix Length: %u", prefix_length);
560                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1, "Padding: 0x%02x", resvd);
561                 break;
562
563         case PCEP_XRO_OBJ:
564                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 1, "X: %x", (l_and_or_type & 0x01)>>7);
565                 proto_tree_add_uint(pcep_subobj_ipv4, pcep_filter[PCEPF_SUBOBJ_XRO], tvb, offset, 1, (l_and_or_type & 0x7f));
566                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 1, "Type: %u", (l_and_or_type & 0x7f));
567                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+1, 1, "Length: %u", length);
568                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: (%s)", ip_to_str(tvb_get_ptr(tvb, offset+2, 4)));
569                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+6, 1, "Prefix Length: %u", prefix_length);
570                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1,  "%s",val_to_str(resvd, pcep_xro_attribute_obj_vals, "Unknown Attribute (%u). "));
571                 break;
572
573         default:
574                 proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 8, "Non defined subobject for this object");
575                 break;
576         }
577 }
578
579 static void
580 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)
581 {
582         proto_tree *pcep_subobj_ipv6;
583         proto_tree *pcep_subobj_ipv6_flags;
584         proto_item *ti;
585         guint8 prefix_length;
586         guint8 resv;
587         int l;
588
589         prefix_length = tvb_get_guint8(tvb, offset+18);
590         resv = tvb_get_guint8(tvb, offset+19);
591         ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_IPv6], tvb, offset, length, FALSE);
592         pcep_subobj_ipv6 = proto_item_add_subtree(ti, ett_pcep_obj);
593
594         if (length != 20) {
595                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset, length,
596                     "Bad IPv6 subobject: length %u != 20", length);
597                 return;
598         }
599
600         switch(obj_class){
601         case PCEP_EXPLICIT_ROUTE_OBJ:
602                 l = (l_and_or_type& Mask_L)>>7;
603                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset, 1,  "%s",val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
604                 proto_tree_add_uint(pcep_subobj_ipv6, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
605                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+1, 1, "Length: %u", length);
606                 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)));
607                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+18, 1, "Prefix Length: %u", prefix_length);
608                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+19, 1, "Padding: 0x%02x", resv);
609                 break;
610
611         case PCEP_RECORD_ROUTE_OBJ:
612                 proto_tree_add_uint(pcep_subobj_ipv6, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, l_and_or_type);
613                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+1, 1, "Length: %u", length);
614                 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)));
615                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+18, 1, "Prefix Length: %u", prefix_length);
616                 ti = proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+19, 1, "Flags: 0x%02x ", resv);
617                 pcep_subobj_ipv6_flags = proto_item_add_subtree(ti, ett_pcep_obj);
618                 proto_tree_add_boolean(pcep_subobj_ipv6_flags, pcep_subobj_flags_lpa, tvb, offset+19, 1, resv);
619                 proto_tree_add_boolean(pcep_subobj_ipv6_flags, pcep_subobj_flags_lpu, tvb, offset+19, 1, resv);
620                 break;
621
622         case PCEP_IRO_OBJ:
623                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset, 1, "l: %x", (l_and_or_type & 0x80)>>7);
624                 proto_tree_add_uint(pcep_subobj_ipv6, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
625                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+1, 1, "Length: %u", length);
626                 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)));
627                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+18, 1, "Prefix Length: %u", prefix_length);
628                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+19, 1, "Padding: 0x%02x", resv);
629                 break;
630
631         case PCEP_XRO_OBJ:
632                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset, 1, "X: %x", (l_and_or_type & 0x01)>>7);
633                 proto_tree_add_uint(pcep_subobj_ipv6, pcep_filter[PCEPF_SUBOBJ_XRO], tvb, offset, 1, (l_and_or_type & 0x7f));
634                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+1, 1, "Length: %u", length);
635                 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)));
636                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+18, 1, "Prefix Length: %u", prefix_length);
637                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+19, 1, "%s", val_to_str(resv, pcep_xro_attribute_obj_vals, "Unknown Attribute (%u). "));
638                 break;
639
640         default:
641                 proto_tree_add_text(pcep_subobj_ipv6, tvb, offset, 20, "Non defined subobject for this object");
642                 break;
643         }       
644 }
645
646
647 static void
648 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)
649 {
650         proto_tree *pcep_subobj_label_control;
651         proto_tree *pcep_subobj_label_flags;
652         proto_item *ti;
653         guint8 u_reserved;
654         guint8 c_type;
655         int l;
656         int u;
657
658         u_reserved = tvb_get_guint8(tvb, offset+2);
659         c_type = tvb_get_guint8(tvb, offset+3);
660
661         ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_LABEL_CONTROL], tvb, offset, length, FALSE);
662         pcep_subobj_label_control = proto_item_add_subtree(ti, ett_pcep_obj);
663
664         if (length < 5) {
665                 proto_tree_add_text(pcep_subobj_label_control, tvb, offset, length,
666                     "Bad label control subobject: length %u < 5", length);
667                 return;
668         }
669
670         switch(obj_class){
671
672         case PCEP_EXPLICIT_ROUTE_OBJ:
673                 l = (l_and_or_type& Mask_L)>>7;
674                 proto_tree_add_text(pcep_subobj_label_control, tvb, offset, 1, "%s", val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
675                 proto_tree_add_uint(pcep_subobj_label_control, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
676                 proto_tree_add_text(pcep_subobj_label_control, tvb, offset+1, 1, "Length: %u", length);
677                 u = (u_reserved & 0x80)>>7;
678                 proto_tree_add_text(pcep_subobj_label_control, tvb, offset+2, 1, "%s", val_to_str(u, pcep_route_u_obj_vals, "Unknown Object (%u). "));
679                 proto_tree_add_text(pcep_subobj_label_control, tvb, offset+2, 1, "Reserved: %u", (u_reserved & 0x7f));
680                 proto_tree_add_text(pcep_subobj_label_control, tvb, offset+3, 1, "C-Type: %u", c_type);
681                 proto_tree_add_text(pcep_subobj_label_control, tvb, offset+4, length-4, "Label: %s", 
682                                 bytestring_to_str(tvb_get_ptr(tvb, offset+4, length-4), length-4, ' '));
683                 break;
684
685         case PCEP_RECORD_ROUTE_OBJ:     
686                 proto_tree_add_uint(pcep_subobj_label_control, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, l_and_or_type);
687                 proto_tree_add_text(pcep_subobj_label_control, tvb, offset+1, 1, "Length: %u", length);
688                 u = (u_reserved & 0x80)>>7;
689                 proto_tree_add_text(pcep_subobj_label_control, tvb, offset+2, 1, "%s", val_to_str(u, pcep_route_u_obj_vals, "Unknown Object (%u). "));
690
691                 ti = proto_tree_add_text(pcep_subobj_label_control, tvb, offset+2, 1, "Flags: 0x%02x ", (u_reserved & 0x7f));
692                 pcep_subobj_label_flags = proto_item_add_subtree(ti, ett_pcep_obj);
693                 proto_tree_add_boolean(pcep_subobj_label_flags, pcep_subobj_label_flags_gl, tvb, offset+2, 1, (u_reserved & 0x7f));
694                 proto_tree_add_text(pcep_subobj_label_control, tvb, offset+3, 1, "C-Type: %u", c_type);
695                 proto_tree_add_text(pcep_subobj_label_control, tvb, offset+4, length-4, "Label: %s", 
696                                 bytestring_to_str(tvb_get_ptr(tvb, offset+4, length-4), length-4, ' '));
697                 break;
698
699         default:
700                 proto_tree_add_text(pcep_subobj_label_control, tvb, offset, length, "Non defined subobject for this object");
701                 break;
702         }               
703 }
704
705 static void
706 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)
707 {
708         proto_tree *pcep_subobj_unnumb_interfaceID;
709         proto_tree *pcep_subobj_unnumb_interfaceID_flags;
710         proto_item *ti;
711         guint32 router_ID;
712         guint32 interface_ID;
713         guint16 reserved_flags;
714         int l;
715
716         reserved_flags = tvb_get_ntohs(tvb, offset+2);
717         router_ID = tvb_get_ntohl(tvb, offset+4);
718         interface_ID = tvb_get_ntohl(tvb, offset+8);
719
720         ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_UNNUM_INTERFACEID], tvb, offset, length, FALSE);
721         pcep_subobj_unnumb_interfaceID = proto_item_add_subtree(ti, ett_pcep_obj);
722
723         if (length != 12) {
724                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset, length,
725                     "Bad unnumbered interface ID subobject: length %u != 12", length);
726                 return;
727         }
728
729         switch(obj_class){
730
731         case PCEP_EXPLICIT_ROUTE_OBJ:
732                 l = (l_and_or_type& Mask_L)>>7;
733                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset, 1, "%s", val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
734                 proto_tree_add_uint(pcep_subobj_unnumb_interfaceID, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
735                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+1, 1, "Length: %u", length);
736                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+2, 2, "Reserved: 0x%04x", reserved_flags);
737                 break;
738
739         case PCEP_RECORD_ROUTE_OBJ:
740                 proto_tree_add_uint(pcep_subobj_unnumb_interfaceID, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, l_and_or_type);
741                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+1, 1, "Length: %u", length);
742
743                 ti = proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+2, 2, "Flags: 0x%02x ", (reserved_flags & 0xff00)>>8);
744                 pcep_subobj_unnumb_interfaceID_flags = proto_item_add_subtree(ti, ett_pcep_obj);
745                 proto_tree_add_boolean(pcep_subobj_unnumb_interfaceID_flags, pcep_subobj_flags_lpa, tvb, offset+2, 1, (reserved_flags & 0xff00)>>8);
746                 proto_tree_add_boolean(pcep_subobj_unnumb_interfaceID_flags, pcep_subobj_flags_lpu, tvb, offset+2, 1, (reserved_flags & 0xff00)>>8);
747
748                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+3, 1, "Reserved: 0x%02x", (reserved_flags & 0x00ff));
749                 break;
750
751         case PCEP_IRO_OBJ:
752                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset, 1, "l: %x", (l_and_or_type & 0x80)>>7);
753                 proto_tree_add_uint(pcep_subobj_unnumb_interfaceID, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
754                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+1, 1, "Length: %u", length);
755                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+2, 2, "Reserved: 0x%04x", reserved_flags);
756                 break;
757
758         case PCEP_XRO_OBJ:
759                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset, 1, "X: %x", (l_and_or_type & 0x01)>>7);
760                 proto_tree_add_uint(pcep_subobj_unnumb_interfaceID, pcep_filter[PCEPF_SUBOBJ_XRO], tvb, offset, 1, (l_and_or_type & 0x7f));
761                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+2, 1, "Reserved: 0x%02x", (reserved_flags & 0xff00)>>4);
762                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+3, 1, "%s", val_to_str((reserved_flags & 0x00ff), pcep_xro_attribute_obj_vals, "Unknown Attribute (%u). "));
763                 break;
764
765         default:
766                 proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset, 12, "Non defined subobject for this object");
767                 break;
768         }       
769
770         proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+4, 4, "Router ID: 0x%08x", router_ID);
771         proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+8, 4, "Interface ID: 0x%08x", interface_ID);
772 }
773
774 static void
775 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)
776 {
777         proto_tree *pcep_subobj_autonomous_sys_num;
778         proto_item *ti;
779         guint16 AS_number;
780         guint8 reserved;
781         guint8 attribute;
782         guint16 op_AS_nu_high_oct;
783
784         int l;
785         l = (l_and_or_type& Mask_L)>>7;
786
787         if(obj_class == PCEP_XRO_OBJ){  
788                 reserved = tvb_get_guint8(tvb, offset+2);
789                 attribute = tvb_get_guint8(tvb, offset+3);
790                 op_AS_nu_high_oct = tvb_get_ntohs(tvb, offset+4);
791                 AS_number = tvb_get_ntohs(tvb, offset+6);
792
793                 ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_AUTONOMOUS_SYS_NUM], tvb, offset, length, FALSE);
794                 pcep_subobj_autonomous_sys_num = proto_item_add_subtree(ti, ett_pcep_obj);
795                 if (length != 8) {
796                         proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset, length,
797                             "Bad autonomous system number subobject: length %u != 8", length);
798                         return;
799                 }
800
801                 proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset, 1, "X: %x", (l_and_or_type & 0x01)>>7);
802                 proto_tree_add_uint(pcep_subobj_autonomous_sys_num, pcep_filter[PCEPF_SUBOBJ_XRO], tvb, offset, 1, (l_and_or_type & 0x7f));
803                 proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+1, 1, "Length: %u", length);
804
805                 proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+2, 1, "Reserved: 0x%02x", reserved);
806                 proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+3, 1, "%s", val_to_str(attribute, pcep_xro_attribute_obj_vals, "Unknown Object (%u)."));
807                 proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+4, 2, "Optional AS Number High Octets: 0x%04x", AS_number);
808                 proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+6, 2, "AS Number: 0x%04x", AS_number);
809         } else {
810                 AS_number = tvb_get_ntohs(tvb, offset+2);
811
812                 ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_AUTONOMOUS_SYS_NUM], tvb, offset, length, FALSE);
813                 pcep_subobj_autonomous_sys_num = proto_item_add_subtree(ti, ett_pcep_obj);
814
815                 if (length != 4) {
816                         proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset, length,
817                             "Bad autonomous system number subobject: length %u != 4", length);
818                         return;
819                 }
820
821                 if(obj_class == PCEP_IRO_OBJ)
822                         proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset, 1, "l: %x", (l_and_or_type & 0x80)>>7);
823                 else    
824                         proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset, 1, "%s", val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
825                 proto_tree_add_uint(pcep_subobj_autonomous_sys_num, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
826                 proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+1, 1, "Length: %u", length);
827                 proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+2, 2, "AS Number: 0x%04x", AS_number);
828         }
829 }
830
831 static void
832 dissect_subobj_srlg(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, guint ett_pcep_obj, guint l_and_or_type, guint length)
833 {
834         proto_tree *pcep_subobj_srlg;
835         proto_item *ti;
836         guint32 srlg_id;
837         guint8 reserved;
838         guint8 attribute;
839
840         srlg_id = tvb_get_ntohl(tvb, offset+2);
841         reserved = tvb_get_guint8(tvb, offset+6);
842         attribute = tvb_get_guint8(tvb, offset+7);
843
844         ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_SRLG], tvb, offset, length, FALSE);
845         pcep_subobj_srlg = proto_item_add_subtree(ti, ett_pcep_obj);
846
847         if (length != 8) {
848                 proto_tree_add_text(pcep_subobj_srlg, tvb, offset, length,
849                     "Bad SRLG subobject: length %u != 8", length);
850                 return;
851         }
852
853         proto_tree_add_text(pcep_subobj_srlg, tvb, offset, 1, "X: %x", (l_and_or_type & 0x01)>>7);
854         proto_tree_add_uint(pcep_subobj_srlg, pcep_filter[PCEPF_SUBOBJ_XRO], tvb, offset, 1, (l_and_or_type & 0x7f));
855         proto_tree_add_text(pcep_subobj_srlg, tvb, offset+1, 1, "Length: %u", length);
856
857         proto_tree_add_text(pcep_subobj_srlg, tvb, offset+2, 4, "SRLG ID: 0x%08x", srlg_id);
858         proto_tree_add_text(pcep_subobj_srlg, tvb, offset+6, 1, "Reserved: 0x%02x", reserved);
859         proto_tree_add_text(pcep_subobj_srlg, tvb, offset+7, 1, "%s", val_to_str(attribute, pcep_xro_attribute_obj_vals, "Unknown Object (%u)."));
860 }
861
862 static void
863 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)
864 {
865         proto_tree *pcep_subobj_exrs;
866         proto_item *ti;
867         guint16 reserved;
868         guint8 l_type;
869         guint8 length2;
870         guint type_exrs;
871         guint offset_exrs = 0;
872         guint l;
873
874         ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_EXRS], tvb, offset, length, FALSE);
875         pcep_subobj_exrs = proto_item_add_subtree(ti, ett_pcep_obj);
876
877         if (length < 4) {
878                 proto_tree_add_text(pcep_subobj_exrs, tvb, offset, length,
879                     "Bad EXRS subobject: length %u < 4", length);
880                 return;
881         }
882
883         l = (l_and_or_type& Mask_L)>>7;
884         proto_tree_add_text(pcep_subobj_exrs, tvb, offset, 1, "%s", val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
885         proto_tree_add_text(pcep_subobj_exrs, tvb, offset, 1, "Type: %u", (l_and_or_type & 0x7f));
886         proto_tree_add_text(pcep_subobj_exrs, tvb, offset+1, 1, "Length: %u", length);
887
888         reserved = tvb_get_ntohs(tvb, offset+2);
889         proto_tree_add_text(pcep_subobj_exrs, tvb, offset+2, 2, "Reserved: 0x%04x", reserved);
890
891         offset += 4;
892
893         while(offset_exrs<length-4){
894
895                 l_type = tvb_get_guint8(tvb, offset);
896                 length2 = tvb_get_guint8(tvb, offset+1);
897
898                 if (length2 < 2) {
899                         proto_tree_add_text(pcep_subobj_exrs, tvb, offset, 0,
900                             "Bad packet: subobject length %u < 2",
901                             length2);
902                         break;
903                 }
904
905                 type_exrs = (l_type & Mask_Type);
906
907                 if(type_iro==PCEP_SUB_EXRS)
908                         obj_class = PCEP_XRO_OBJ;
909
910                 switch(type_exrs) {
911
912                 case PCEP_SUB_IPv4:
913                         dissect_subobj_ipv4(pcep_subobj_exrs, tvb, offset,  obj_class, ett_pcep_obj, l_type, length2);
914                         break;
915                 case PCEP_SUB_IPv6:
916                         dissect_subobj_ipv6(pcep_subobj_exrs, tvb, offset, obj_class, ett_pcep_obj, l_type, length2);
917                         break;
918                 case PCEP_SUB_UNNUMB_INTERFACE_ID_XRO:
919                         dissect_subobj_unnumb_interfaceID(pcep_subobj_exrs, tvb, offset, obj_class, ett_pcep_obj, l_type, length2);
920                         break;
921                 case PCEP_SUB_AUTONOMOUS_SYS_NUM_XRO:
922                         dissect_subobj_autonomous_sys_num(pcep_subobj_exrs, tvb, offset, obj_class, ett_pcep_obj, l_type, length2);
923                         break;
924                 case PCEP_SUB_SRLG:
925                         dissect_subobj_srlg(pcep_subobj_exrs, tvb, offset, ett_pcep_obj, l_type, length2);
926                         break;
927                 default:
928                         proto_tree_add_text(pcep_subobj_exrs, tvb, offset+2, length-2,
929                                 "Non defined subobject (%d)", type_exrs);
930                         break;
931                 }
932                 offset_exrs += length2;
933                 offset += length2;
934         }
935 }
936
937 /*------------------------------------------------------------------------------
938  * OPEN OBJECT
939  *------------------------------------------------------------------------------*/
940 #define OPEN_OBJ_MIN_LEN        4
941
942 static void
943 dissect_pcep_open_obj (proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
944 {
945     proto_tree *pcep_open_obj_flags;
946     proto_item *ti;
947     guint8 version_flags;
948     guint8 keepalive;
949     guint8 deadtimer;
950     guint8 SID;
951
952     if (obj_length < OBJ_HDR_LEN+OPEN_OBJ_MIN_LEN) {
953         proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
954             "Bad OPEN object length %u, should be >= %u", obj_length,
955             OBJ_HDR_LEN+OPEN_OBJ_MIN_LEN);
956         return;
957     }
958
959     version_flags = tvb_get_guint8(tvb, offset2);
960     proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "PCEP Version: %u", (version_flags & 0xe0)>>5);
961
962     ti = proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "Flags: 0x%02x", version_flags & 0x1f);
963     pcep_open_obj_flags = proto_item_add_subtree(ti, ett_pcep_obj_open);
964     proto_tree_add_boolean(pcep_open_obj_flags, pcep_open_flags_res, tvb, offset2, 1, version_flags & 0x1f);
965
966     keepalive = tvb_get_guint8(tvb, offset2+1);
967     proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 1, "Keepalive: %u", keepalive);
968
969     deadtimer = tvb_get_guint8(tvb, offset2+2);
970     proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 1, "Deadtime: %u", deadtimer);
971
972     SID = tvb_get_guint8(tvb, offset2+3);
973     proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "SID: %u", SID);
974
975     /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
976     offset2 += OPEN_OBJ_MIN_LEN;
977     obj_length -= OBJ_HDR_LEN+OPEN_OBJ_MIN_LEN;
978     dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_open);
979 }
980
981 /*------------------------------------------------------------------------------
982  * RP OBJECT
983  *------------------------------------------------------------------------------*/
984 #define RP_OBJ_MIN_LEN  8
985
986 static void 
987 dissect_pcep_rp_obj(proto_tree *pcep_object_tree,
988                   tvbuff_t *tvb, int offset2, int obj_length)
989
990         proto_tree *pcep_rp_obj_flags;
991         proto_item *ti;
992         guint8 reserved;
993         guint32 flags;
994         guint32 requested_id_number;
995
996         if (obj_length < OBJ_HDR_LEN+RP_OBJ_MIN_LEN) {
997                 proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
998                     "Bad RP object length %u, should be >= %u", obj_length,
999                     OBJ_HDR_LEN+RP_OBJ_MIN_LEN);
1000                 return;
1001         }
1002
1003         reserved = tvb_get_guint8(tvb, offset2);
1004         proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "Reserved: 0x%02x", reserved);
1005
1006         flags = tvb_get_ntoh24(tvb, offset2+1);
1007         ti = proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 3, "Flags: 0x%06x ", flags);
1008         pcep_rp_obj_flags = proto_item_add_subtree(ti, ett_pcep_obj_request_parameters);
1009
1010         proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_reserved, tvb, offset2+1, 3, flags);
1011         proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_o, tvb, offset2+1, 3, flags);
1012         proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_b, tvb, offset2+1, 3, flags);
1013         proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_r, tvb, offset2+1, 3, flags);
1014         proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_pri, tvb, offset2+1, 3, flags);
1015
1016         requested_id_number = tvb_get_ntohl(tvb, offset2+4);
1017         proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Requested ID Number: 0x%08x", requested_id_number);
1018
1019         /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
1020         offset2 += RP_OBJ_MIN_LEN;
1021         obj_length -= OBJ_HDR_LEN+RP_OBJ_MIN_LEN;
1022         dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_request_parameters);
1023 }
1024
1025 /*------------------------------------------------------------------------------
1026  * NO PATH OBJECT
1027  *------------------------------------------------------------------------------*/
1028 #define NO_PATH_OBJ_MIN_LEN     4
1029
1030 static void 
1031 dissect_pcep_no_path_obj(proto_tree *pcep_object_tree,
1032                   tvbuff_t *tvb, int offset2, int obj_length)
1033 {    
1034         proto_tree *pcep_no_path_obj_flags;
1035         proto_item *ti;
1036         guint8 ni;
1037         guint16 flags;
1038         guint8 reserved;
1039
1040         if (obj_length < OBJ_HDR_LEN+NO_PATH_OBJ_MIN_LEN) {
1041                 proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
1042                     "Bad NO-PATH object length %u, should be >= %u", obj_length,
1043                     OBJ_HDR_LEN+NO_PATH_OBJ_MIN_LEN);
1044                 return;
1045         }
1046
1047         ni = tvb_get_guint8(tvb, offset2);
1048         proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "%s", val_to_str(ni, pcep_no_path_obj_vals, "Unknown Object (%u). "));
1049
1050         flags = tvb_get_ntohs(tvb, offset2+1);
1051         ti = proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 2, "Flags: 0x%04x", flags);
1052         pcep_no_path_obj_flags = proto_item_add_subtree(ti, ett_pcep_obj_no_path);
1053         proto_tree_add_boolean(pcep_no_path_obj_flags, pcep_no_path_flags_c, tvb, offset2+1, 2, flags);
1054
1055         reserved = tvb_get_guint8(tvb, offset2+3);
1056         proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "Reserved: 0x%02x", reserved);
1057
1058         /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
1059         offset2 += NO_PATH_OBJ_MIN_LEN;
1060         obj_length -= OBJ_HDR_LEN+NO_PATH_OBJ_MIN_LEN;
1061         dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_no_path);
1062 }
1063
1064 /*------------------------------------------------------------------------------
1065  * END POINT OBJECT
1066  *------------------------------------------------------------------------------*/
1067 #define END_POINT_IPV4_OBJ_LEN  8
1068 #define END_POINT_IPV6_OBJ_LEN  32
1069
1070 static void 
1071 dissect_pcep_end_point_obj(proto_tree *pcep_object_tree,
1072                   tvbuff_t *tvb, int offset2, int obj_length, int type)
1073 {
1074         switch(type)
1075         {
1076           case IPv4:    
1077                 if (obj_length != OBJ_HDR_LEN+END_POINT_IPV4_OBJ_LEN) {
1078                         proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
1079                             "Bad IPv4 END-POINTS object length %u, should be %u", obj_length,
1080                             OBJ_HDR_LEN+END_POINT_IPV4_OBJ_LEN);
1081                         return;
1082                 }
1083
1084                 proto_tree_add_text(pcep_object_tree, tvb, offset2, 4, "Source IPv4 Address: (%s)", ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1085                 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)));
1086                 break;
1087
1088           case IPv6:
1089                 if (obj_length != OBJ_HDR_LEN+END_POINT_IPV6_OBJ_LEN) {
1090                         proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
1091                             "Bad IPv6 END-POINTS object length %u, should be %u", obj_length,
1092                             OBJ_HDR_LEN+END_POINT_IPV6_OBJ_LEN);
1093                         return;
1094                 }
1095
1096                 proto_tree_add_text(pcep_object_tree, tvb, offset2, 16, "Source IPv6 Address: %s",
1097                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1098                 proto_tree_add_text(pcep_object_tree, tvb, offset2+16, 16, "Destination IPv6 Address: %s",
1099                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+16, 16)));
1100                 break;
1101
1102           default:
1103                  proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length-OBJ_HDR_LEN, "UNKNOWN Type Object (%u)", type);
1104                  break;
1105         }     
1106 }
1107
1108
1109
1110 /*------------------------------------------------------------------------------
1111  * BANDWIDTH OBJECT
1112  *------------------------------------------------------------------------------*/
1113 #define BANDWIDTH_OBJ_LEN       4
1114
1115 static void 
1116 dissect_pcep_bandwidth_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
1117 {    
1118         guint32 bandwidth;
1119
1120         if (obj_length != OBJ_HDR_LEN+BANDWIDTH_OBJ_LEN) {
1121                 proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
1122                     "Bad BANDWIDTH object length %u, should be %u", obj_length,
1123                     OBJ_HDR_LEN+BANDWIDTH_OBJ_LEN);
1124                 return;
1125         }
1126                 
1127         bandwidth = tvb_get_ntohl(tvb, offset2);
1128         proto_tree_add_text(pcep_object_tree, tvb, offset2, 4, "Bandwidth: 0x%x", bandwidth);
1129 }
1130
1131 /*------------------------------------------------------------------------------
1132  * METRIC OBJECT
1133  *------------------------------------------------------------------------------*/
1134 #define METRIC_OBJ_LEN  8
1135
1136 static void 
1137 dissect_pcep_metric_obj(proto_tree *pcep_object_tree,
1138                   tvbuff_t *tvb, int offset2, int obj_length)
1139 {    
1140         proto_tree *pcep_metric_obj_flags;
1141         proto_item *ti;
1142         guint16 reserved;
1143         guint8 flags;
1144         guint8 metric_type;
1145         guint32 metric_value;
1146
1147         if (obj_length != OBJ_HDR_LEN+METRIC_OBJ_LEN) {
1148                 proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
1149                     "Bad METRIC object length %u, should be %u", obj_length,
1150                     OBJ_HDR_LEN+METRIC_OBJ_LEN);
1151                 return;
1152         }
1153
1154         reserved = tvb_get_ntohs(tvb, offset2);
1155         proto_tree_add_text(pcep_object_tree, tvb, offset2, 2, "Reserved: %u", reserved);
1156
1157         flags = tvb_get_guint8(tvb, offset2+2);
1158         ti = proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 1, "Flags: 0x%02x", flags);
1159         pcep_metric_obj_flags = proto_item_add_subtree(ti, ett_pcep_obj_metric);
1160         proto_tree_add_boolean(pcep_metric_obj_flags, pcep_metric_flags_c, tvb, offset2+2, 1, flags);
1161         proto_tree_add_boolean(pcep_metric_obj_flags, pcep_metric_flags_b, tvb, offset2+2, 1, flags);
1162
1163         metric_type = tvb_get_guint8(tvb, offset2+3);
1164         proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "%s", val_to_str(metric_type, pcep_metric_obj_vals, "Unknown Object (%u). "));
1165
1166         metric_value = tvb_get_ntohl(tvb, offset2+4);
1167         proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Metric Value: 0x%x", metric_value);
1168 }
1169
1170 /*------------------------------------------------------------------------------
1171  * EXPLICIT ROUTE OBJECT (ERO)
1172  *------------------------------------------------------------------------------*/
1173 static void 
1174 dissect_pcep_explicit_route_obj(proto_tree *pcep_object_tree,
1175                   tvbuff_t *tvb, int offset2, int obj_length, int obj_class)
1176 {
1177         guint8 l_type;
1178         guint8 length;
1179         guint type_exp_route;
1180         guint body_obj_len;
1181
1182         body_obj_len = obj_length - OBJ_HDR_LEN;
1183
1184         while(body_obj_len){
1185                 if (body_obj_len < 2) {
1186                         proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
1187                             "Bad ERO object: subobject goes past end of object");
1188                         break;
1189                 }
1190
1191                 l_type = tvb_get_guint8(tvb, offset2);
1192                 length = tvb_get_guint8(tvb, offset2+1);
1193
1194                 if (length < 2) {
1195                         proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
1196                             "Bad ERO object: subobject length %u < 2",
1197                             length);
1198                         break;
1199                 }
1200
1201                 type_exp_route = (l_type & Mask_Type);
1202                 if (body_obj_len <length) {
1203                         proto_tree_add_text(pcep_object_tree, tvb, offset2, length,
1204                             "Bad ERO object: subobject length %u > remaining length %u",
1205                                 length, body_obj_len);
1206                         break;
1207                 }
1208
1209                 switch(type_exp_route) {
1210
1211                 case PCEP_SUB_IPv4:
1212                         dissect_subobj_ipv4(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_explicit_route, l_type, length);
1213                         break;
1214                 case PCEP_SUB_IPv6:
1215                         dissect_subobj_ipv6(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_explicit_route, l_type, length);
1216                         break;
1217                 case PCEP_SUB_LABEL_CONTROL:
1218                         dissect_subobj_label_control(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_explicit_route, l_type, length);
1219                         break;
1220                 case PCEP_SUB_UNNUMB_INTERFACE_ID:
1221                         dissect_subobj_unnumb_interfaceID(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_explicit_route, l_type, length);
1222                         break;
1223                 case PCEP_SUB_AUTONOMOUS_SYS_NUM:
1224                         dissect_subobj_autonomous_sys_num(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_explicit_route, l_type, length);
1225                         break;
1226                 default:
1227                         proto_tree_add_text(pcep_object_tree, tvb, offset2, length, "Non defined subobject (%d)", type_exp_route);
1228                         break;
1229                 }                       
1230                 offset2 += length;
1231                 body_obj_len -= length;
1232         }          
1233 }
1234
1235 /*------------------------------------------------------------------------------
1236  * RECORD ROUTE OBJECT (RRO)
1237  *------------------------------------------------------------------------------*/
1238 static void 
1239 dissect_pcep_record_route_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length, int obj_class)
1240 {
1241         guint8 type;
1242         guint8 length;
1243         guint body_obj_len;
1244
1245         body_obj_len = obj_length - OBJ_HDR_LEN;
1246
1247         while(body_obj_len){
1248                 if (body_obj_len < 2) {
1249                         proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
1250                             "Bad RRO object: subobject goes past end of object");
1251                         break;
1252                 }
1253
1254                 type = tvb_get_guint8(tvb, offset2);
1255                 length = tvb_get_guint8(tvb, offset2+1);
1256
1257                 if (length < 2) {
1258                         proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
1259                             "Bad RRO object: subobject length %u < 2",
1260                             length);
1261                         break;
1262                 }
1263
1264                 if (body_obj_len <length) {
1265                         proto_tree_add_text(pcep_object_tree, tvb, offset2, length,
1266                             "Bad RRO subobject: subobject length %u > remaining length %u",
1267                                 length, body_obj_len);
1268                         break;
1269                 }
1270
1271                 switch(type) {
1272
1273                 case PCEP_SUB_IPv4:
1274                         dissect_subobj_ipv4(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_record_route, type, length);
1275                         break;
1276                 case PCEP_SUB_IPv6:
1277                         dissect_subobj_ipv6(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_record_route, type, length);
1278                         break;
1279                 case PCEP_SUB_LABEL_CONTROL:
1280                         dissect_subobj_label_control(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_record_route, type, length);
1281                         break;
1282                 case PCEP_SUB_UNNUMB_INTERFACE_ID:
1283                         dissect_subobj_unnumb_interfaceID(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_record_route, type, length);
1284                         break;
1285                 default:
1286                         proto_tree_add_text(pcep_object_tree, tvb, offset2, length, "Non defined subobject (%d)", type);
1287                         break;
1288                 }
1289                 offset2 += length;
1290                 body_obj_len -= length;
1291         }                       
1292 }
1293
1294 /*------------------------------------------------------------------------------
1295  * LSPA OBJECT
1296  *------------------------------------------------------------------------------*/
1297 #define LSPA_OBJ_MIN_LEN        16
1298
1299 static void 
1300 dissect_pcep_lspa_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
1301 {    
1302         proto_tree *pcep_lspa_obj_flags;
1303         proto_item *ti;
1304         guint32 exclude_any;
1305         guint32 include_any;
1306         guint32 include_all;
1307         guint8 setup_prio;
1308         guint8 holding_prio;
1309         guint8 flags;
1310         guint8 reserved;
1311
1312         if (obj_length < OBJ_HDR_LEN+LSPA_OBJ_MIN_LEN) {
1313                 proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
1314                     "Bad LSPA object length %u, should be >= %u", obj_length,
1315                     OBJ_HDR_LEN+LSPA_OBJ_MIN_LEN);
1316                 return;
1317         }
1318
1319         exclude_any = tvb_get_ntohl(tvb, offset2);
1320         proto_tree_add_text(pcep_object_tree, tvb, offset2, 4, "Exclude-Any: 0x%08x", exclude_any);
1321
1322         include_any = tvb_get_ntohl(tvb, offset2+4);
1323         proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Include-Any: 0x%08x", include_any);
1324
1325         include_all = tvb_get_ntohl(tvb, offset2+8);
1326         proto_tree_add_text(pcep_object_tree, tvb, offset2+8, 4, "Include-All: 0x%08x", include_all);
1327
1328         setup_prio = tvb_get_guint8(tvb, offset2+12);
1329         proto_tree_add_text(pcep_object_tree, tvb, offset2+12, 1, "Setup Priority: %u", setup_prio);
1330
1331         holding_prio = tvb_get_guint8(tvb, offset2+13);
1332         proto_tree_add_text(pcep_object_tree, tvb, offset2+13, 1, "Holding Priority: %u", holding_prio);
1333
1334         flags = tvb_get_guint8(tvb, offset2+14);
1335         ti = proto_tree_add_text(pcep_object_tree, tvb, offset2+14, 1, "Flags: 0x%02x", flags);
1336         pcep_lspa_obj_flags = proto_item_add_subtree(ti, ett_pcep_obj_metric);
1337         proto_tree_add_boolean(pcep_lspa_obj_flags, pcep_lspa_flags_l, tvb, offset2+14, 1, flags);
1338
1339         reserved = tvb_get_guint8(tvb, offset2+15);
1340         proto_tree_add_text(pcep_object_tree, tvb, offset2+15, 1, "Reserved: 0x%02x", reserved);
1341
1342         /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
1343         offset2 += LSPA_OBJ_MIN_LEN;
1344         obj_length -= OBJ_HDR_LEN+LSPA_OBJ_MIN_LEN;
1345         dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_lspa);
1346 }
1347
1348 /*------------------------------------------------------------------------------
1349  * INCLUDE ROUTE OBJECT (IRO)
1350  *------------------------------------------------------------------------------*/
1351 static void 
1352 dissect_pcep_iro_obj(proto_tree *pcep_object_tree,
1353                     tvbuff_t *tvb, int offset2, int obj_length, int obj_class)
1354 {    
1355         guint8 l_type;
1356         guint8 length;
1357         int type_iro;
1358         guint body_obj_len;
1359
1360         body_obj_len = obj_length - OBJ_HDR_LEN;
1361
1362         while(body_obj_len){
1363                 if (body_obj_len < 2) {
1364                         proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
1365                             "Bad IRO object: subobject goes past end of object");
1366                         break;
1367                 }
1368
1369                 l_type = tvb_get_guint8(tvb, offset2);
1370                 length = tvb_get_guint8(tvb, offset2+1);
1371
1372                 if (length < 2) {
1373                         proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
1374                             "Bad IRO object: subobject length %u < 2",
1375                             length);
1376                         break;
1377                 }
1378
1379                 type_iro = (l_type & Mask_Type);
1380
1381                 if (body_obj_len <length) {
1382                         proto_tree_add_text(pcep_object_tree, tvb, offset2, length,
1383                             "Bad IRO object: subobject length %u > remaining length %u",
1384                                 length, body_obj_len);
1385                         break;
1386                 }
1387
1388                 switch(type_iro) {
1389
1390                 case PCEP_SUB_IPv4:
1391                         dissect_subobj_ipv4(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_iro, l_type, length);
1392                         break;
1393                 case PCEP_SUB_IPv6:
1394                         dissect_subobj_ipv6(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_iro, l_type, length);
1395                         break;
1396                 case PCEP_SUB_UNNUMB_INTERFACE_ID:
1397                         dissect_subobj_unnumb_interfaceID(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_iro, l_type, length);
1398                         break;
1399                 case PCEP_SUB_AUTONOMOUS_SYS_NUM:
1400                         dissect_subobj_autonomous_sys_num(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_iro, l_type, length);
1401                         break;
1402                 case PCEP_SUB_EXRS:
1403                         dissect_subobj_exrs(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_iro, type_iro, l_type, length);
1404                         break;
1405                 default:
1406                         proto_tree_add_text(pcep_object_tree, tvb, offset2, length, "Non defined subobject (%d)", type_iro);
1407                         break;
1408                 } 
1409                 offset2 += length;
1410                 body_obj_len -= length;
1411         }
1412 }
1413
1414 /*------------------------------------------------------------------------------
1415  * SVEC OBJECT 
1416  *------------------------------------------------------------------------------*/
1417 #define SVEC_OBJ_MIN_LEN        4
1418
1419 static void 
1420 dissect_pcep_svec_obj(proto_tree *pcep_object_tree,
1421                   tvbuff_t *tvb, int offset2, int obj_length)
1422 {
1423         proto_item *ti;
1424         proto_tree *pcep_svec_flags_obj;
1425         guint8 reserved;
1426         guint32 flags;
1427         int m = 1;
1428         int i = 0;
1429
1430         if (obj_length < OBJ_HDR_LEN+SVEC_OBJ_MIN_LEN) {
1431                 proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
1432                     "Bad SVEC object length %u, should be >= %u", obj_length,
1433                     OBJ_HDR_LEN+SVEC_OBJ_MIN_LEN);
1434                 return;
1435         }
1436
1437         reserved = tvb_get_guint8(tvb, offset2);
1438         proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "Reserved: 0x%02x", reserved);
1439
1440         flags = tvb_get_ntoh24(tvb, offset2+1);
1441         ti = proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 3, "Flags: 0x%06x", flags);
1442         pcep_svec_flags_obj = proto_item_add_subtree(ti, ett_pcep_obj_svec);
1443         proto_tree_add_boolean(pcep_svec_flags_obj, pcep_svec_flags_l, tvb, offset2 + 1, 3, flags);
1444         proto_tree_add_boolean(pcep_svec_flags_obj, pcep_svec_flags_n, tvb, offset2 + 1, 3, flags);
1445         proto_tree_add_boolean(pcep_svec_flags_obj, pcep_svec_flags_s, tvb, offset2 + 1, 3, flags);
1446
1447         for ( i=4 ; i<(obj_length-OBJ_HDR_LEN) ; ){
1448                 proto_tree_add_text(pcep_object_tree, tvb, offset2+i, 4, "Request-ID-Number %u: 0x%s", m,
1449                         bytestring_to_str(tvb_get_ptr(tvb, offset2+i, 4), 4, ' '));
1450                 i += 4;
1451         }
1452 }
1453
1454 /*------------------------------------------------------------------------------
1455  * NOTIFICATION OBJECT 
1456  *------------------------------------------------------------------------------*/                    
1457 #define NOTIFICATION_OBJ_MIN_LEN        4
1458
1459 static void 
1460 dissect_pcep_notification_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
1461 {    
1462         guint8 reserved;
1463         guint8 flags;
1464         guint8 nt;
1465         guint8 nv;
1466
1467         if (obj_length < OBJ_HDR_LEN+NOTIFICATION_OBJ_MIN_LEN) {
1468                 proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
1469                     "Bad NOTIFICATION object length %u, should be >= %u", obj_length,
1470                     OBJ_HDR_LEN+NOTIFICATION_OBJ_MIN_LEN);
1471                 return;
1472         }
1473
1474         reserved = tvb_get_guint8(tvb, offset2);
1475         proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "Reserved: 0x%02x", reserved);
1476
1477         flags = tvb_get_guint8(tvb, offset2+1);
1478         proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 1, "Flags: 0x%02x", flags);
1479
1480         nt = tvb_get_guint8(tvb, offset2+2);
1481         proto_tree_add_uint(pcep_object_tree, pcep_filter[PCEPF_NOTI_TYPE], tvb, offset2+2, 1, nt);
1482
1483         switch(nt){
1484
1485         case 1:
1486                 proto_tree_add_uint(pcep_object_tree, pcep_filter[PCEPF_NOTI_VAL1], tvb, offset2+2, 1, nt);
1487                 break;
1488
1489         case 2: 
1490                 proto_tree_add_uint(pcep_object_tree, pcep_filter[PCEPF_NOTI_VAL2], tvb, offset2+2, 1, nt);
1491                 break;
1492
1493         default:
1494                 proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 1, "Notification Type: %u", nt);
1495                 break;
1496         }
1497
1498         nv = tvb_get_guint8(tvb, offset2+3);
1499         proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "Notification Value: 0x%02x", nv);
1500
1501         /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
1502         offset2 += NOTIFICATION_OBJ_MIN_LEN;
1503         obj_length -= OBJ_HDR_LEN+NOTIFICATION_OBJ_MIN_LEN;
1504         dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_notification);
1505 }
1506
1507 /*------------------------------------------------------------------------------
1508  * ERROR OBJECT 
1509  *------------------------------------------------------------------------------*/                    
1510 #define ERROR_OBJ_MIN_LEN       4
1511
1512 static void 
1513 dissect_pcep_error_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
1514 {       
1515         proto_tree *pcep_error_types_obj;
1516         proto_item *ti;
1517         guint8 reserved;
1518         guint8 flags;
1519         guint8 error_type;
1520         guint8 error_value;
1521
1522         if (obj_length < OBJ_HDR_LEN+ERROR_OBJ_MIN_LEN) {
1523                 proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
1524                     "Bad ERROR object length %u, should be >= %u", obj_length,
1525                     OBJ_HDR_LEN+ERROR_OBJ_MIN_LEN);
1526                 return;
1527         }
1528
1529         reserved = tvb_get_guint8(tvb, offset2);
1530         proto_tree_add_text(pcep_object_tree, tvb, offset2, 1, "Reserved: 0x%02x", reserved);
1531
1532         flags = tvb_get_guint8(tvb, offset2+1);
1533         proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 1, "Flags: 0x%02x", flags);
1534
1535         error_type = tvb_get_guint8(tvb, offset2+2);
1536         ti = proto_tree_add_uint(pcep_object_tree, pcep_filter[PCEPF_ERROR_TYPE], tvb, offset2+2, 1, error_type);
1537         pcep_error_types_obj = proto_item_add_subtree(ti, ett_pcep_obj_error);
1538
1539         error_value = tvb_get_guint8(tvb, offset2+3);
1540         switch(error_type){     
1541         case ESTABLISH_FAILURE:
1542                 switch(error_value){
1543                 case RX_MALFORM_PKT:
1544                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Reception of a Malformed Message ", error_value);
1545                         break;
1546                 case NO_OPEN_MSG:
1547                         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);
1548                         break;
1549                 case UNACEP_NO_NEGO_SSESION:
1550                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Unacceptable and non Negotiable session characteristics", error_value);
1551                         break;
1552                 case UNACEP_NEG_SESSION:
1553                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Unacceptable but Negotiable session characteristics", error_value);
1554                         break;
1555                 case TWO_OPEN_MSG_UNACEP:
1556                         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);
1557                         break;
1558                 case RX_PCEPERR_UNACEP_SESSION:
1559                         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);
1560                         break;
1561                 case NO_KEEPALIVE_PCEPERR:
1562                         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);
1563                         break;
1564                 default:
1565                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
1566                                 "Error-value: %u Non defined Error-Value", error_value);
1567                 }
1568                 break;
1569
1570         case CAP_NOT_SUPPORTED:
1571                 proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
1572                 break;
1573
1574         case UNKNOWN_OBJ:
1575                 switch(error_value){
1576                 case UNRECON_OBJ_CLASS:
1577                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Unrecognized object class", error_value);
1578                         break;
1579                 case UNRECON_OBJ_TYPE:
1580                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Unrecognized object type", error_value);
1581                         break;
1582                 default:
1583                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
1584                                 "Error-value: %u Non defined Error-Value", error_value);
1585                 } 
1586                 break;
1587         case NOT_SUPP_OBJ:
1588                 switch(error_value){
1589                 case NO_SUPP_OBJ:
1590                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Not Supported Object Class", error_value);
1591                         break;
1592                 case NO_SUPP_TYPE:
1593                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Not Supported Object Type", error_value);
1594                         break;
1595                 default:
1596                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
1597                                 "Error-value: %u Non defined Error-Value", error_value);
1598                 }
1599                 break;
1600         case POLICY_VIOLATION:
1601                 switch(error_value){
1602                 case C_METRIC_SET:
1603                         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);
1604                         break;
1605                 case O_OBJ_SET:
1606                         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);
1607                         break;
1608                 default:
1609                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
1610                                 "Error-value: %u Non defined Error-Value", error_value);
1611                 }
1612                 break;
1613         case MANDATORY_OBJ_MIS: 
1614                 switch(error_value){
1615                 case RP_OBJ_MISS:
1616                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u RP Object missing", error_value);
1617                         break;
1618                 case RRO_OBJ_MISS:
1619                         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);
1620                         break;
1621                 case END_POINT_OBJ_MISS:
1622                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u END-POINTS Objects missing", error_value);
1623                         break;
1624                 default:  
1625                         proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
1626                                 "Error-value: %u Non defined Error-Value", error_value);
1627                 }
1628                 break;
1629         case SYNCH_PCREQ_MIS:
1630                 proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
1631                 break;
1632         case UNKNOWN_REQ_REF:   
1633                 proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
1634                 break;
1635         case ATTEMPT_2_SESSION:
1636                 proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
1637                 break;
1638         case UNRECO_IRO_SUBOBJ:
1639                 proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
1640                 break;
1641         case UNRECO_EXRS_SUBOBJ:
1642                 proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
1643                 break;
1644
1645         default:
1646                 proto_tree_add_text(pcep_error_types_obj, tvb, offset2+2, 1, "Error-Type: %u Non defined Error-Value", error_type);
1647         }
1648
1649         /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
1650         offset2 += ERROR_OBJ_MIN_LEN;
1651         obj_length -= OBJ_HDR_LEN+ERROR_OBJ_MIN_LEN;
1652         dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_error);
1653 }
1654
1655
1656 /*------------------------------------------------------------------------------
1657  * LOAD-BALANCING OBJECT 
1658  *------------------------------------------------------------------------------*/                    
1659 #define LOAD_BALANCING_OBJ_LEN  8
1660
1661 static void 
1662 dissect_pcep_balancing_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
1663 {    
1664         guint16 reserved;
1665         guint8 flags;
1666         guint8 max_LSP;
1667         guint32 min_bandwidth;
1668
1669         if (obj_length != OBJ_HDR_LEN+LOAD_BALANCING_OBJ_LEN) {
1670                 proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
1671                     "Bad LOAD-BALANCING object length %u, should be %u", obj_length,
1672                     OBJ_HDR_LEN+LOAD_BALANCING_OBJ_LEN);
1673                 return;
1674         }
1675
1676         reserved = tvb_get_ntohs(tvb, offset2);
1677         proto_tree_add_text(pcep_object_tree, tvb, offset2, 2, "Reserved: 0x%04x", reserved);
1678
1679         flags = tvb_get_guint8(tvb, offset2+2);
1680         proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 1, "Flags: 0x%02x", flags);
1681
1682         max_LSP = tvb_get_guint8(tvb, offset2+3);
1683         proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "Maximum Number of TE LSPs: 0x%02x", max_LSP);
1684
1685         min_bandwidth = tvb_get_ntohl(tvb, offset2+4);
1686         proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Minimum Bandwidth: 0x%08x", min_bandwidth);
1687 }
1688
1689 /*------------------------------------------------------------------------------
1690  * CLOSE OBJECT 
1691  *------------------------------------------------------------------------------*/                    
1692 #define CLOSE_OBJ_MIN_LEN       4
1693
1694 static void 
1695 dissect_pcep_close_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
1696 {
1697         guint16 reserved;
1698         guint8 flags;
1699         guint8 reason;
1700
1701         if (obj_length < OBJ_HDR_LEN+CLOSE_OBJ_MIN_LEN) {
1702                 proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
1703                     "Bad CLOSE object length %u, should be >= %u", obj_length,
1704                     OBJ_HDR_LEN+CLOSE_OBJ_MIN_LEN);
1705                 return;
1706         }
1707
1708         reserved = tvb_get_ntohs(tvb, offset2);
1709         proto_tree_add_text(pcep_object_tree, tvb, offset2, 2, "Reserved: 0x%04x", reserved);
1710
1711         flags = tvb_get_guint8(tvb, offset2+2);
1712         proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 1, "Flags: 0x%02x", flags);
1713
1714         reason = tvb_get_guint8(tvb, offset2+3);
1715         proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "%s", val_to_str(reason, pcep_close_reason_obj_vals, "Unknown Object (%u). "));
1716
1717         /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
1718         offset2 += CLOSE_OBJ_MIN_LEN;
1719         obj_length -= OBJ_HDR_LEN+CLOSE_OBJ_MIN_LEN;
1720         dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_load_balancing);
1721 }
1722
1723 /*------------------------------------------------------------------------------
1724  * XRO OBJECT 
1725  *------------------------------------------------------------------------------*/      
1726 #define XRO_OBJ_MIN_LEN 4
1727
1728 static void 
1729 dissect_pcep_xro_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length, int obj_class)
1730 {
1731         proto_tree *pcep_xro_flags_obj;
1732         proto_item *ti;
1733         guint16 reserved;
1734         guint16 flags;
1735         guint8 x_type;
1736         guint8 length;
1737         guint type_xro;
1738         guint body_obj_len;
1739
1740         body_obj_len = obj_length - OBJ_HDR_LEN;
1741
1742         if (obj_length < OBJ_HDR_LEN+XRO_OBJ_MIN_LEN) {
1743                 proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
1744                     "Bad XRO object length %u, should be >= %u", obj_length,
1745                     OBJ_HDR_LEN+XRO_OBJ_MIN_LEN);
1746                 return;
1747         }
1748
1749         reserved = tvb_get_ntohs(tvb, offset2);
1750         proto_tree_add_text(pcep_object_tree, tvb, offset2, 2, "Reserved: 0x%04x", reserved);
1751
1752         flags = tvb_get_ntohs(tvb, offset2+2);
1753         ti =  proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 2, "Flags: 0x%04x ", flags);
1754         pcep_xro_flags_obj = proto_item_add_subtree(ti, ett_pcep_obj_xro);
1755         proto_tree_add_boolean(pcep_xro_flags_obj, pcep_xro_flags_f, tvb, offset2 + 2, 2, flags);
1756
1757         offset2 += XRO_OBJ_MIN_LEN;
1758         body_obj_len -= XRO_OBJ_MIN_LEN;
1759
1760         while(body_obj_len >= 2){
1761                 if (body_obj_len < 2) {
1762                         proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
1763                             "Bad XRO object: subobject goes past end of object");
1764                         break;
1765                 }
1766
1767                 x_type = tvb_get_guint8(tvb, offset2);
1768                 length = tvb_get_guint8(tvb, offset2+1);
1769
1770                 if (length < 2) {
1771                         proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
1772                             "Bad XRO object: object length %u < 2", length);
1773                         break;
1774                 }
1775
1776                 type_xro = (x_type & Mask_Type);
1777
1778                 if (body_obj_len <length) {
1779                         proto_tree_add_text(pcep_object_tree, tvb, offset2, length,
1780                             "Bad XRO object: object length %u > remaining length %u",
1781                                 length, body_obj_len);
1782                         break;
1783                 }
1784
1785                 switch(type_xro) {
1786
1787                 case PCEP_SUB_IPv4:
1788                         dissect_subobj_ipv4(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_xro, x_type, length);
1789                         break;
1790                 case PCEP_SUB_IPv6:
1791                         dissect_subobj_ipv6(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_xro, x_type, length);
1792                         break;
1793                 case PCEP_SUB_UNNUMB_INTERFACE_ID_XRO:
1794                         dissect_subobj_unnumb_interfaceID(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_xro, x_type, length);
1795                         break;
1796                 case PCEP_SUB_AUTONOMOUS_SYS_NUM_XRO:
1797                         dissect_subobj_autonomous_sys_num(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_xro, x_type, length);
1798                         break;
1799                 case PCEP_SUB_SRLG:
1800                         dissect_subobj_srlg(pcep_object_tree, tvb, offset2, ett_pcep_obj_xro, x_type, length);
1801                         break;
1802                 default:
1803                         proto_tree_add_text(pcep_object_tree, tvb, offset2-4, length, "Non defined subobject (%d)", type_xro);
1804                         break;
1805                 }
1806                 offset2 += length;
1807                 body_obj_len -= length;
1808         }
1809 }
1810
1811 /*------------------------------------------------------------------------------*/      
1812 /* Dissect in Objects */
1813 /*------------------------------------------------------------------------------*/
1814 static void
1815 dissect_pcep_obj_tree(proto_tree *pcep_tree, tvbuff_t *tvb, int len, int offset, int msg_length)  
1816 {  
1817   guint8 obj_class;
1818   guint8 ot_res_p_i;
1819   guint16 obj_length;
1820   int type;
1821   proto_tree *pcep_object_tree;
1822   proto_item *pcep_object_item;
1823   proto_tree *pcep_header_obj_flags;
1824   proto_item *ti;
1825
1826   while (len < msg_length) {
1827         obj_class = tvb_get_guint8(tvb, offset);
1828         switch (obj_class) {
1829
1830         case PCEP_OPEN_OBJ:
1831                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_OPEN], tvb, offset, -1, FALSE);
1832                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_open);
1833                 break;
1834
1835         case PCEP_RP_OBJ:
1836                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_RP], tvb, offset, -1, FALSE);
1837                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_request_parameters);
1838                 break;
1839
1840         case PCEP_NO_PATH_OBJ:
1841                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_NO_PATH], tvb, offset, -1, FALSE);
1842                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_no_path);
1843                 break;
1844
1845         case PCEP_END_POINT_OBJ:
1846                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_END_POINT], tvb, offset, -1, FALSE);
1847                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_end_point);
1848                 break;
1849
1850         case PCEP_BANDWIDTH_OBJ:
1851                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_BANDWIDTH], tvb, offset, -1, FALSE);
1852                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_bandwidth);
1853                 break;
1854
1855         case PCEP_METRIC_OBJ:
1856                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_METRIC], tvb, offset, -1, FALSE);
1857                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_metric);
1858                 break;
1859
1860         case PCEP_EXPLICIT_ROUTE_OBJ:
1861                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_EXPLICIT_ROUTE], tvb, offset, -1, FALSE);
1862                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_explicit_route);
1863                 break;
1864
1865         case PCEP_RECORD_ROUTE_OBJ:
1866                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_RECORD_ROUTE], tvb, offset, -1, FALSE);
1867                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_record_route);
1868                 break;
1869
1870         case PCEP_LSPA_OBJ:
1871                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_LSPA], tvb, offset, -1, FALSE);
1872                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_lspa);
1873                 break;
1874
1875         case PCEP_IRO_OBJ:
1876                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_IRO], tvb, offset, -1, FALSE);
1877                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_iro);
1878                 break;
1879
1880         case PCEP_SVEC_OBJ:
1881                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_SVEC], tvb, offset, -1, FALSE);
1882                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_svec);
1883                 break;
1884
1885         case PCEP_NOTIFICATION_OBJ:
1886                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_NOTIFICATION], tvb, offset, -1, FALSE);
1887                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_notification);
1888                 break;
1889
1890         case PCEP_PCEP_ERROR_OBJ:
1891                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_PCEP_ERROR], tvb, offset, -1, FALSE);
1892                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_error);
1893                 break;
1894
1895         case PCEP_LOAD_BALANCING_OBJ:
1896                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_LOAD_BALANCING], tvb, offset, -1, FALSE);
1897                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_load_balancing);
1898                 break;
1899
1900         case PCEP_CLOSE_OBJ:
1901                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_CLOSE], tvb, offset, -1, FALSE);
1902                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_close);
1903                 break;
1904
1905         case PCEP_XRO_OBJ:
1906                 pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_XRO], tvb, offset, -1, FALSE);
1907                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_xro);
1908                 break;
1909
1910         default:
1911                 pcep_object_item = proto_tree_add_text(pcep_tree, tvb, offset, -1, "Unknown object (%u)", obj_class);
1912                 pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_unknown);
1913                 break;
1914         }
1915
1916         proto_tree_add_uint(pcep_object_tree, pcep_filter[PCEPF_OBJECT_CLASS], tvb, offset, 1, obj_class);
1917
1918         ot_res_p_i = tvb_get_guint8(tvb, offset+1);
1919         type = (ot_res_p_i & MASK_OBJ_TYPE)>>4;
1920         proto_tree_add_text(pcep_object_tree, tvb, offset+1, 1, "Object Type: %u", type);
1921
1922         ti = proto_tree_add_text(pcep_object_tree, tvb, offset+1, 1, "Flags");
1923         pcep_header_obj_flags = proto_item_add_subtree(ti, ett_pcep_hdr);
1924         proto_tree_add_boolean(pcep_header_obj_flags, pcep_hdr_obj_flags_reserved, tvb, offset+1, 1, ot_res_p_i);
1925         proto_tree_add_boolean(pcep_header_obj_flags, pcep_hdr_obj_flags_p, tvb, offset+1, 1, ot_res_p_i);
1926         proto_tree_add_boolean(pcep_header_obj_flags, pcep_hdr_obj_flags_i, tvb, offset+1, 1, ot_res_p_i);
1927
1928         obj_length = tvb_get_ntohs(tvb, offset+2);
1929         proto_item_set_len(pcep_object_item, obj_length);
1930         if (obj_length < 4) {
1931             proto_tree_add_text(pcep_object_tree, tvb, offset+2, 2, "Object Length: %u (bogus, must be >= 4)", obj_length);
1932             break;
1933         }
1934         proto_tree_add_text(pcep_object_tree, tvb, offset+2, 2, "Object Length: %u", obj_length);
1935
1936         switch(obj_class) {
1937
1938         case PCEP_OPEN_OBJ:
1939             dissect_pcep_open_obj(pcep_object_tree, tvb, offset+4, obj_length);
1940             break;
1941
1942         case PCEP_RP_OBJ:
1943             dissect_pcep_rp_obj(pcep_object_tree, tvb, offset+4, obj_length);
1944             break;
1945
1946         case PCEP_NO_PATH_OBJ:
1947             dissect_pcep_no_path_obj(pcep_object_tree, tvb, offset+4, obj_length);
1948             break;
1949
1950         case PCEP_END_POINT_OBJ:
1951             dissect_pcep_end_point_obj(pcep_object_tree, tvb, offset+4, obj_length, type);
1952             break;
1953
1954         case PCEP_BANDWIDTH_OBJ:
1955             dissect_pcep_bandwidth_obj(pcep_object_tree, tvb, offset+4, obj_length);
1956             break;
1957
1958         case PCEP_METRIC_OBJ:
1959             dissect_pcep_metric_obj(pcep_object_tree, tvb, offset+4, obj_length);
1960             break;
1961
1962         case PCEP_EXPLICIT_ROUTE_OBJ:
1963             dissect_pcep_explicit_route_obj(pcep_object_tree, tvb, offset+4, obj_length, obj_class);
1964             break;
1965
1966         case PCEP_RECORD_ROUTE_OBJ:
1967             dissect_pcep_record_route_obj(pcep_object_tree, tvb, offset+4, obj_length, obj_class);
1968             break;
1969
1970         case PCEP_LSPA_OBJ:
1971             dissect_pcep_lspa_obj(pcep_object_tree, tvb, offset+4, obj_length);
1972             break;
1973
1974         case PCEP_IRO_OBJ:
1975             dissect_pcep_iro_obj(pcep_object_tree, tvb, offset+4, obj_length, obj_class);
1976             break;
1977
1978         case PCEP_SVEC_OBJ:
1979             dissect_pcep_svec_obj(pcep_object_tree, tvb, offset+4, obj_length);
1980             break;
1981
1982         case PCEP_NOTIFICATION_OBJ:
1983             dissect_pcep_notification_obj(pcep_object_tree, tvb, offset+4, obj_length);
1984             break;
1985
1986         case PCEP_PCEP_ERROR_OBJ:
1987             dissect_pcep_error_obj(pcep_object_tree, tvb, offset+4, obj_length);
1988             break;
1989
1990         case PCEP_LOAD_BALANCING_OBJ:
1991             dissect_pcep_balancing_obj(pcep_object_tree, tvb, offset+4, obj_length);
1992             break;
1993
1994         case PCEP_CLOSE_OBJ:
1995             dissect_pcep_close_obj(pcep_object_tree, tvb, offset+4, obj_length);
1996             break;
1997
1998         case PCEP_XRO_OBJ:
1999             dissect_pcep_xro_obj(pcep_object_tree, tvb, offset+4, obj_length, obj_class);
2000             break;
2001
2002         default:
2003             proto_tree_add_text(pcep_object_tree, tvb, offset+4, obj_length-OBJ_HDR_LEN, "PCEP Object BODY non defined (%u)", type);
2004             break;
2005         }
2006
2007         offset += obj_length;
2008         len += obj_length;
2009     }   
2010 }
2011
2012
2013 /*------------------------------------------------------------------------------
2014  * Dissect a single PCEP message in a tree
2015  *------------------------------------------------------------------------------*/
2016 static void
2017 dissect_pcep_msg_tree(tvbuff_t *tvb, proto_tree *tree, guint tree_mode, packet_info *pinfo)
2018 {
2019     proto_tree *pcep_tree = NULL;
2020     proto_tree *pcep_header_tree;
2021     proto_tree *ti;
2022     proto_tree *pcep_header_msg_flags;
2023     proto_item *hidden_item;
2024
2025     int offset = 0;
2026     int len=0;
2027     guint8 ver_flags;
2028     guint8 message_type;
2029     guint16 msg_length;
2030
2031     ver_flags = tvb_get_guint8(tvb, 0);
2032     message_type = tvb_get_guint8(tvb, 1);
2033     msg_length = tvb_get_ntohs(tvb, 2);
2034
2035     if (check_col(pinfo->cinfo, COL_INFO)) {
2036         col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(message_type, message_type_vals, "Unknown Message (%u). "));
2037     }
2038
2039     ti = proto_tree_add_item(tree, proto_pcep, tvb, offset, msg_length, FALSE);
2040     pcep_tree = proto_item_add_subtree(ti, tree_mode);
2041
2042     ti = proto_tree_add_text(pcep_tree, tvb, offset, 4, "%s Header", val_to_str(message_type, message_type_vals, "Unknown Message (%u). "));
2043
2044     pcep_header_tree = proto_item_add_subtree(ti, ett_pcep_hdr);
2045
2046     proto_tree_add_text(pcep_header_tree, tvb, offset, 1, "PCEP Version: %x", (ver_flags & 0x20)>>5);
2047
2048     ti = proto_tree_add_text(pcep_header_tree, tvb, offset, 1, "Flags: 0x%02x", ver_flags & 0x1f);
2049     pcep_header_msg_flags = proto_item_add_subtree(ti, ett_pcep_hdr);
2050     proto_tree_add_boolean(pcep_header_msg_flags, pcep_hdr_msg_flags_reserved, tvb, offset, 1, (ver_flags & 0x1f));
2051     proto_tree_add_uint(pcep_header_tree, pcep_filter[PCEPF_MSG], tvb, offset+1, 1, message_type);
2052     proto_tree_add_text(pcep_header_tree, tvb, offset+2, 2, "Message length: %u", msg_length);
2053
2054     switch (PCEPF_MSG + message_type) {
2055
2056     case PCEPF_OPEN:
2057     case PCEPF_KEEPALIVE:
2058     case PCEPF_PATH_COMPUTATION_REQUEST:
2059     case PCEPF_PATH_COMPUTATION_REPLY:
2060     case PCEPF_NOTIFICATION:
2061     case PCEPF_ERROR:
2062     case PCEPF_CLOSE:
2063         hidden_item = proto_tree_add_boolean(pcep_header_tree, pcep_filter[PCEPF_MSG + message_type], tvb, offset+1, 1, 1);
2064         PROTO_ITEM_SET_HIDDEN(hidden_item);
2065         break;
2066
2067     default:
2068         proto_tree_add_protocol_format(pcep_header_tree, proto_malformed, tvb, offset+1, 1, "Invalid message type: %u", message_type);
2069         return;
2070     }
2071
2072     offset = 4;
2073     len = 4;
2074
2075     dissect_pcep_obj_tree(pcep_tree, tvb, len, offset, msg_length);
2076 }
2077
2078
2079 static guint
2080 get_pcep_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
2081 {
2082     guint16 plen;
2083
2084     /* Get the length of the PCEP packet.*/
2085     plen = tvb_get_ntohs(tvb, offset+2);
2086
2087     return plen;
2088 }
2089
2090 static void
2091 dissect_pcep_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2092 {
2093
2094 /* Set up structures needed to add the protocol subtree and manage it */
2095
2096         col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCEP");
2097
2098         /* Clear out stuff in the info column */
2099         col_clear(pinfo->cinfo, COL_INFO);
2100
2101         dissect_pcep_msg_tree(tvb, tree, ett_pcep, pinfo);
2102 }
2103
2104 static void
2105 dissect_pcep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2106 {
2107   tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 4, get_pcep_message_len,
2108         dissect_pcep_pdu);
2109 }
2110
2111 /*Register the protocol with wireshark*/
2112 void
2113 proto_register_pcep(void){
2114
2115         static hf_register_info pcepf_info[] = {
2116
2117                 /* Message type number */
2118                 {&pcep_filter[PCEPF_MSG],
2119                  { "Message Type", "pcep.msg", FT_UINT8, BASE_DEC, VALS(message_type_vals), 0x0,
2120                         NULL, HFILL }},
2121                 {&pcep_hdr_msg_flags_reserved,
2122                  { "Reserved Flags", "pcep.hdr.msg.flags.reserved", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_HDR_MSG_RESERVED,
2123                         NULL, HFILL }},         
2124                 {&pcep_filter[PCEPF_OPEN],
2125                  { "Open Message", "pcep.msg.open", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2126                         NULL, HFILL }},
2127                 {&pcep_filter[PCEPF_KEEPALIVE],
2128                  { "Keepalive Message", "pcep.msg.keepalive", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2129                         NULL, HFILL }},
2130                 {&pcep_filter[PCEPF_PATH_COMPUTATION_REQUEST],
2131                  { "Path Computation Request Message", "pcep.msg.path.computation.request", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2132                         NULL, HFILL }},
2133                 {&pcep_filter[PCEPF_PATH_COMPUTATION_REPLY],
2134                  { "Path Computation Reply Mesagge", "pcep.msg.path.computation.reply", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2135                         NULL, HFILL }},
2136                 {&pcep_filter[PCEPF_NOTIFICATION],
2137                  { "Notification Message", "pcep.msg.notification", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2138                         NULL, HFILL }},
2139                 {&pcep_filter[PCEPF_ERROR],
2140                  { "Error Message", "pcep.msg.error", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2141                         NULL, HFILL }},
2142                 {&pcep_filter[PCEPF_CLOSE],
2143                  { "Close Message", "pcep.msg.close", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2144                         NULL, HFILL }},  
2145
2146                 /*Object header*/
2147                 {&pcep_hdr_obj_flags_reserved,
2148                  { "Reserved Flags", "pcep.hdr.obj.flags.reserved", FT_BOOLEAN, 4, TFS(&tfs_set_notset), PCEP_HDR_OBJ_RESERVED,
2149                 NULL, HFILL }},
2150                 {&pcep_hdr_obj_flags_p,
2151                  { "Processing-Rule (P)", "pcep.hdr.obj.flags.p", FT_BOOLEAN, 4, TFS(&tfs_set_notset), PCEP_HDR_OBJ_P,
2152                 NULL, HFILL }},
2153                 {&pcep_hdr_obj_flags_i,
2154                  { "Ignore (I)", "pcep.hdr.obj.flags.i", FT_BOOLEAN, 4, TFS(&tfs_set_notset), PCEP_HDR_OBJ_I,
2155                 NULL, HFILL }}, 
2156                 /* Object class */
2157                 {&pcep_filter[PCEPF_OBJECT_CLASS],
2158                  { "Object Class", "pcep.object", FT_UINT32, BASE_DEC, VALS(pcep_class_vals), 0x0,
2159                         NULL, HFILL }},
2160
2161                 /* Object types */
2162                 {&pcep_filter[PCEPF_OBJ_OPEN],
2163                  { "OPEN object", "pcep.obj.open", FT_NONE, BASE_NONE, NULL, 0x0,
2164                         NULL, HFILL }},
2165                 {&pcep_open_flags_res,
2166                  { "Reserved Flags", "pcep.open.flags.res", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_OPEN_RES,
2167                 NULL, HFILL }},
2168                 {&pcep_filter[PCEPF_OBJ_RP],
2169                  { "RP object", "pcep.obj.rp", FT_NONE, BASE_NONE, NULL, 0x0,
2170                         NULL, HFILL }},
2171                 {&pcep_rp_flags_reserved,
2172                  { "Reserved Flags", "pcep.rp.flags.reserved", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_RESERVED,
2173                 NULL, HFILL }},
2174                 {&pcep_rp_flags_pri,
2175                  { "Priority (PRI)", "pcep.rp.flags.pri", FT_BOOLEAN, 24, TFS(&tfs_on_off), PCEP_RP_PRI,
2176                 NULL, HFILL }},
2177                 {&pcep_rp_flags_r,
2178                  { "Reoptimization (R)", "pcep.rp.flags.r", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_R,
2179                 NULL, HFILL }},
2180                 {&pcep_rp_flags_b,
2181                  { "Bi-directional (L)", "pcep.rp.flags.b", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_B,
2182                 NULL, HFILL }},
2183                 {&pcep_rp_flags_o,
2184                  { "Strict/Loose (L)", "pcep.rp.flags.o", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_O,
2185                 NULL, HFILL }},
2186                 {&pcep_filter[PCEPF_OBJ_NO_PATH],
2187                  { "NO-PATH object", "pcep.obj.nopath", FT_NONE, BASE_NONE, NULL, 0x0,
2188                         NULL, HFILL }},
2189                 {&pcep_no_path_flags_c,
2190                  { "C", "pcep.no.path.flags.c", FT_BOOLEAN, 16, TFS(&tfs_set_notset), PCEP_NO_PATH_C,
2191                 NULL, HFILL }},
2192                 {&pcep_filter[PCEPF_OBJ_END_POINT],
2193                  { "END-POINT object", "pcep.obj.endpoint", FT_NONE, BASE_NONE, NULL, 0x0,
2194                         NULL, HFILL }}, 
2195                 {&pcep_filter[PCEPF_OBJ_BANDWIDTH],
2196                  { "BANDWIDTH object", "pcep.obj.bandwidth", FT_NONE, BASE_NONE, NULL, 0x0,
2197                         NULL, HFILL }},
2198                 {&pcep_filter[PCEPF_OBJ_METRIC],
2199                  { "METRIC object", "pcep.obj.metric", FT_NONE, BASE_NONE, NULL, 0x0,
2200                         NULL, HFILL }},
2201                 {&pcep_metric_flags_c,
2202                  { "Cost (C)", "pcep.metric.flags.c", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_METRIC_C,
2203                 NULL, HFILL }},
2204                 {&pcep_metric_flags_b,
2205                  { "Bound (B)", "pcep.metric.flags.b", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_METRIC_B,
2206                 NULL, HFILL }},
2207                 {&pcep_filter[PCEPF_OBJ_EXPLICIT_ROUTE],
2208                  { "EXPLICIT ROUTE object (ERO)", "pcep.obj.ero", FT_NONE, BASE_NONE, NULL, 0x0,
2209                         NULL, HFILL }},
2210                 {&pcep_filter[PCEPF_OBJ_RECORD_ROUTE],
2211                  { "RECORD ROUTE object (RRO)", "pcep.obj.rro", FT_NONE, BASE_NONE, NULL, 0x0,
2212                         NULL, HFILL }},   
2213                 {&pcep_filter[PCEPF_OBJ_LSPA],
2214                  { "LSPA object", "pcep.obj.lspa", FT_NONE, BASE_NONE, NULL, 0x0,
2215                         NULL, HFILL }},  
2216                 {&pcep_lspa_flags_l,
2217                  { "Local Protection Desired (L)", "pcep.lspa.flags.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_LSPA_L,
2218                 NULL, HFILL }},
2219                 {&pcep_filter[PCEPF_OBJ_IRO],
2220                  { "IRO object", "pcep.obj.iro", FT_NONE, BASE_NONE, NULL, 0x0,
2221                         NULL, HFILL }},   
2222                 {&pcep_filter[PCEPF_OBJ_SVEC],
2223                  { "SVEC object", "pcep.obj.svec", FT_NONE, BASE_NONE, NULL, 0x0,
2224                         NULL, HFILL }},  
2225
2226                 {&pcep_svec_flags_l,
2227                  { "Link diverse (L)", "pcep.svec.flags.l", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_SVEC_L,
2228                 NULL, HFILL }},
2229
2230                 {&pcep_svec_flags_n,
2231                  { "Node diverse (N)", "pcep.svec.flags.n", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_SVEC_N,
2232                 NULL, HFILL }},
2233
2234                 {&pcep_svec_flags_s,
2235                  { "SRLG diverse (S)", "pcep.svec.flags.s", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_SVEC_S,
2236                 NULL, HFILL }},         
2237
2238                 {&pcep_filter[PCEPF_OBJ_NOTIFICATION],
2239                  { "NOTIFICATION object", "pcep.obj.notification", FT_NONE, BASE_NONE, NULL, 0x0,
2240                         NULL, HFILL }}, 
2241
2242                 {&pcep_filter[PCEPF_NOTI_TYPE],
2243                  { "Notification Value", "pcep.notification.value1", FT_UINT32, BASE_DEC, VALS(pcep_notification_types_vals), 0x0,
2244                         NULL, HFILL }},
2245                 {&pcep_filter[PCEPF_NOTI_VAL1],
2246                  { "Notification Type", "pcep.notification.type2", FT_UINT32, BASE_DEC, VALS(pcep_notification_values1_vals), 0x0,
2247                         NULL, HFILL }},
2248                 {&pcep_filter[PCEPF_NOTI_VAL2],
2249                  { "Notification Type", "pcep.notification.type", FT_UINT32, BASE_DEC, VALS(pcep_notification_values2_vals), 0x0,
2250                         NULL, HFILL }},
2251
2252                 {&pcep_filter[PCEPF_OBJ_PCEP_ERROR],
2253                  { "ERROR object", "pcep.obj.error", FT_NONE, BASE_NONE, NULL, 0x0,
2254                         NULL, HFILL }}, 
2255                 {&pcep_filter[PCEPF_ERROR_TYPE],
2256                  { "Error-Type", "pcep.error.type", FT_UINT8, BASE_DEC, VALS(pcep_error_types_obj_vals), 0x0,
2257                         NULL, HFILL }},  
2258                 {&pcep_filter[PCEPF_OBJ_LOAD_BALANCING],
2259                  { "LOAD BALANCING object", "pcep.obj.loadbalancing", FT_NONE, BASE_NONE, NULL, 0x0,
2260                         NULL, HFILL }},   
2261                 {&pcep_filter[PCEPF_OBJ_CLOSE],
2262                  { "CLOSE object", "pcep.obj.close", FT_NONE, BASE_NONE, NULL, 0x0,
2263                         NULL, HFILL }}, 
2264                 {&pcep_filter[PCEPF_OBJ_XRO],
2265                  { "EXCLUDE ROUTE object (XRO)", "pcep.obj.xro", FT_NONE, BASE_NONE, NULL, 0x0,
2266                         NULL, HFILL }},
2267
2268                 /*Subobjects*/  
2269                 {&pcep_filter[PCEPF_SUBOBJ],
2270                  { "Type", "pcep.subobj", FT_UINT8, BASE_DEC, VALS(pcep_subobj_vals), 0x0,
2271                         NULL, HFILL }}, 
2272
2273                 {&pcep_filter[PCEPF_SUBOBJ_IPv4],
2274                  { "SUBOBJECT: IPv4 Prefix", "pcep.subobj.ipv4", FT_NONE, BASE_NONE, NULL, 0x0,
2275                         NULL, HFILL }},
2276                 {&pcep_filter[PCEPF_SUBOBJ_IPv6],
2277                  { "SUBOBJECT: IPv6 Prefix", "pcep.subobj.ipv6", FT_NONE, BASE_NONE, NULL, 0x0,
2278                         NULL, HFILL }},
2279                 {&pcep_filter[PCEPF_SUBOBJ_LABEL_CONTROL],
2280                  { "SUBOBJECT: Label Control", "pcep.subobj.label.control", FT_NONE, BASE_NONE, NULL, 0x0,
2281                         NULL, HFILL }},
2282                 {&pcep_filter[PCEPF_SUBOBJ_UNNUM_INTERFACEID],
2283                  { "SUBOBJECT: Unnumbered Interface ID", "pcep.subobj.unnum.interfaceid", FT_NONE, BASE_NONE, NULL, 0x0,
2284                         NULL, HFILL }},
2285                 {&pcep_filter[PCEPF_SUBOBJ_AUTONOMOUS_SYS_NUM],
2286                  { "SUBOBJECT: Autonomous System Number", "pcep.subobj.autonomous.sys.num", FT_NONE, BASE_NONE, NULL, 0x0,
2287                         NULL, HFILL }},
2288                 {&pcep_filter[PCEPF_SUBOBJ_SRLG],
2289                  { "SUBOBJECT: SRLG", "pcep.subobj.srlg", FT_NONE, BASE_NONE, NULL, 0x0,
2290                         NULL, HFILL }},
2291                 {&pcep_filter[PCEPF_SUBOBJ_EXRS],
2292                  { "SUBOBJECT: EXRS", "pcep.subobj.exrs", FT_NONE, BASE_NONE, NULL, 0x0,
2293                         NULL, HFILL }},
2294                 {&pcep_filter[PCEPF_SUBOBJ_XRO],
2295                  { "Type", "pcep.subobj.label", FT_UINT32, BASE_DEC, VALS(pcep_subobj_xro_vals), 0x0,
2296                         NULL, HFILL }},
2297                 {&pcep_xro_flags_f,
2298                  { "Fail (F)", "pcep.xro.flags.f", FT_BOOLEAN, 16, TFS(&tfs_set_notset), PCEP_XRO_F,
2299                 NULL, HFILL }},
2300                 {&pcep_filter[PCEPF_SUB_XRO_ATTRIB],
2301                  { "Attribute", "pcep.xro.sub.attribute", FT_UINT32, BASE_DEC, VALS(pcep_xro_attribute_obj_vals), 0x0,
2302                 NULL, HFILL }},
2303
2304                 {&pcep_subobj_flags_lpa,
2305                  { "Local Protection Available", "pcep.subobj.flags.lpa", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_SUB_LPA,
2306                 NULL, HFILL }},
2307                 {&pcep_subobj_flags_lpu,
2308                  { "Local protection in Use", "pcep.subobj.flags.lpu", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_SUB_LPU,
2309                 NULL, HFILL }}, 
2310                 {&pcep_subobj_label_flags_gl,
2311                  { "Global Label", "pcep.subobj.label.flags.gl", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_SUB_LABEL_GL,
2312                 NULL, HFILL }}, 
2313         };
2314
2315 /*Register the protocol name and description*/
2316         proto_pcep = proto_register_protocol (
2317                         "Path Computation Element communication Protocol",      /* name*/
2318                         "PCEP",         /* short name */
2319                         "pcep"          /* abbrev*/);
2320
2321 /* Required function calls to register the header fields and subtrees used */
2322         proto_register_field_array(proto_pcep, pcepf_info, array_length(pcepf_info));
2323         proto_register_subtree_array(ett, array_length(ett));
2324 }
2325
2326 /*Dissector Handoff*/
2327 void
2328 proto_reg_handoff_pcep(void)
2329 {
2330         dissector_handle_t pcep_handle;
2331
2332         pcep_handle = create_dissector_handle(dissect_pcep, proto_pcep);
2333         dissector_add("tcp.port", TCP_PORT_PCEP, pcep_handle);
2334 }