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