Move dissectors to epan/dissectors directory.
[obnox/wireshark/wip.git] / epan / dissectors / packet-lmp.c
1 /* packet-lmp.c
2  * Routines for LMP packet disassembly
3  *
4  * (c) Copyright Ashok Narayanan <ashokn@cisco.com>
5  *
6  * $Id$
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 /*
28  * LMP as a standard has shown a remarkable ability to get completely rewritten
29  * across minor versions of the draft. This file currently implements
30  * three versions of LMP; IP based versions described in draft-ietf-ccamp-lmp-02.txt and
31  * draft-ietf-ccamp-lmp-03.txt, and the new UDP based version in draft-ietf-ccamp-lmp-09.txt. 
32  * The -09 version is the default; the version being dissected can be changed from 
33  * the LMP protocol preferences
34  */
35
36 #ifdef HAVE_CONFIG_H
37 # include "config.h"
38 #endif
39
40 #include <stdio.h>
41
42 #ifdef HAVE_UNISTD_H
43 #include <unistd.h>
44 #endif
45
46 #include <stdlib.h>
47 #include <string.h>
48
49 #include <glib.h>
50
51 #include <epan/tvbuff.h>
52 #include <epan/packet.h>
53 #include <prefs.h>
54 #include "in_cksum.h"
55 #include "etypes.h"
56 #include "ipproto.h"
57
58 #include "packet-ip.h"
59 #include "packet-rsvp.h"
60 #include "packet-frame.h"
61
62 static int proto_lmp = -1;
63 #define LMP_VER_DRAFT_CCAMP_02  2
64 #define LMP_VER_DRAFT_CCAMP_03  3
65 #define LMP_VER_DRAFT_CCAMP_09  9
66 static int lmp_draft_ver = LMP_VER_DRAFT_CCAMP_09;
67
68 #define IP_PROTO_LMP 140
69 #define UDP_PORT_LMP_DEFAULT 49998
70 static int lmp_udp_port = UDP_PORT_LMP_DEFAULT;
71 static int lmp_udp_port_config = UDP_PORT_LMP_DEFAULT;
72
73 static dissector_handle_t lmp_handle;
74
75 /*----------------------------------------------------------------------
76  * LMP message types
77  */
78 typedef enum {
79     LMP_MSG_CONFIG=1,
80     LMP_MSG_CONFIG_ACK,
81     LMP_MSG_CONFIG_NACK,
82     LMP_MSG_HELLO,
83     LMP_MSG_BEGIN_VERIFY,
84     LMP_MSG_BEGIN_VERIFY_ACK,
85     LMP_MSG_BEGIN_VERIFY_NACK,
86     LMP_MSG_END_VERIFY,
87     LMP_MSG_END_VERIFY_ACK,
88     LMP_MSG_TEST,
89     LMP_MSG_TEST_STATUS_SUCCESS,
90     LMP_MSG_TEST_STATUS_FAILURE,
91     LMP_MSG_TEST_STATUS_ACK,
92     LMP_MSG_LINK_SUMMARY,
93     LMP_MSG_LINK_SUMMARY_ACK,
94     LMP_MSG_LINK_SUMMARY_NACK,
95     LMP_MSG_CHANNEL_STATUS,
96     LMP_MSG_CHANNEL_STATUS_ACK,
97     LMP_MSG_CHANNEL_STATUS_REQ,
98     LMP_MSG_CHANNEL_STATUS_RESP
99 } lmp_message_types;
100
101 static value_string message_type_vals[] = {
102     {LMP_MSG_CONFIG,              "Config Message. "},
103     {LMP_MSG_CONFIG_ACK,          "ConfigAck Message. "},
104     {LMP_MSG_CONFIG_NACK,         "ConfigNack Message. "},
105     {LMP_MSG_HELLO,               "Hello Message. "},
106     {LMP_MSG_BEGIN_VERIFY,        "BeginVerify Message. "},
107     {LMP_MSG_BEGIN_VERIFY_ACK,    "BeginVerifyAck Message. "},
108     {LMP_MSG_BEGIN_VERIFY_NACK,   "BeginVerifyNack Message. "},
109     {LMP_MSG_END_VERIFY,          "EndVerify Message. "},
110     {LMP_MSG_END_VERIFY_ACK,      "EndVerifyAck Message. "},
111     {LMP_MSG_TEST,                "Test Message. "},
112     {LMP_MSG_TEST_STATUS_SUCCESS, "TestStatusSuccess Message. "},
113     {LMP_MSG_TEST_STATUS_FAILURE, "TestStatusFailure Message. "},
114     {LMP_MSG_TEST_STATUS_ACK,     "TestStatusAck Message. "},
115     {LMP_MSG_LINK_SUMMARY,        "LinkSummary Message. "},
116     {LMP_MSG_LINK_SUMMARY_ACK,    "LinkSummaryAck Message. "},
117     {LMP_MSG_LINK_SUMMARY_NACK,   "LinkSummaryNack Message. "},
118     {LMP_MSG_CHANNEL_STATUS,      "ChannelStatus Message. "},
119     {LMP_MSG_CHANNEL_STATUS_ACK,  "ChannelStatusAck Message. "},
120     {LMP_MSG_CHANNEL_STATUS_REQ,  "ChannelStatusRequest Message. "},
121     {LMP_MSG_CHANNEL_STATUS_RESP, "ChannelStatusResponse Message. "},
122     {0, NULL}
123 };
124
125 /*------------------------------------------------------------------------------
126  * LMP object classes
127  */
128 #define LMP_CLASS_NULL                          0
129
130 #define LMP_CLASS_LOCAL_CCID                    1
131 #define LMP_CLASS_REMOTE_CCID                   2
132 #define LMP_CLASS_LOCAL_NODE_ID                 3
133 #define LMP_CLASS_REMOTE_NODE_ID                4
134 #define LMP_CLASS_LOCAL_LINK_ID                 5
135 #define LMP_CLASS_REMOTE_LINK_ID                6
136 #define LMP_CLASS_LOCAL_INTERFACE_ID            7
137 #define LMP_CLASS_REMOTE_INTERFACE_ID           8
138 #define LMP_CLASS_MESSAGE_ID                    9
139 #define LMP_CLASS_MESSAGE_ID_ACK                10
140 #define LMP_CLASS_CONFIG                        11
141 #define LMP_CLASS_HELLO                         12
142 #define LMP_CLASS_BEGIN_VERIFY                  13
143 #define LMP_CLASS_BEGIN_VERIFY_ACK              14
144 #define LMP_CLASS_VERIFY_ID                     15
145 #define LMP_CLASS_TE_LINK                       16
146 #define LMP_CLASS_DATA_LINK                     17
147 #define LMP_CLASS_CHANNEL_STATUS                18
148 #define LMP_CLASS_CHANNEL_STATUS_REQUEST        19
149 #define LMP_CLASS_ERROR                         20
150 #define LMP_CLASS_MAX                           20
151
152 #define LMP_09_CLASS_CCID                       1
153 #define LMP_09_CLASS_NODE_ID                    2
154 #define LMP_09_CLASS_LINK_ID                    3
155 #define LMP_09_CLASS_INTERFACE_ID               4
156 #define LMP_09_CLASS_MESSAGE_ID                 5
157 #define LMP_09_CLASS_CONFIG                     6
158 #define LMP_09_CLASS_HELLO                      7
159 #define LMP_09_CLASS_BEGIN_VERIFY               8
160 #define LMP_09_CLASS_BEGIN_VERIFY_ACK           9
161 #define LMP_09_CLASS_VERIFY_ID                  10
162 #define LMP_09_CLASS_TE_LINK                    11
163 #define LMP_09_CLASS_DATA_LINK                  12
164 #define LMP_09_CLASS_CHANNEL_STATUS             13
165 #define LMP_09_CLASS_CHANNEL_STATUS_REQUEST     14
166 #define LMP_09_CLASS_ERROR                      20
167 #define LMP_09_CLASS_MAX                        15
168
169 static value_string lmp_class_vals[] = {
170
171     {LMP_CLASS_LOCAL_CCID, "LOCAL_CCID"},
172     {LMP_CLASS_REMOTE_CCID, "REMOTE_CCID"},
173     {LMP_CLASS_LOCAL_NODE_ID, "LOCAL_NODE_ID"},
174     {LMP_CLASS_REMOTE_NODE_ID, "REMOTE_NODE_ID"},
175     {LMP_CLASS_LOCAL_LINK_ID, "LOCAL_LINK_ID"},
176     {LMP_CLASS_REMOTE_LINK_ID, "REMOTE_LINK_ID"},
177     {LMP_CLASS_LOCAL_INTERFACE_ID, "LOCAL_INTERFACE_ID"},
178     {LMP_CLASS_REMOTE_INTERFACE_ID, "REMOTE_INTERFACE_ID"},
179     {LMP_CLASS_MESSAGE_ID, "MESSAGE_ID"},
180     {LMP_CLASS_MESSAGE_ID_ACK, "MESSAGE_ID_ACK"},
181     {LMP_CLASS_CONFIG, "CONFIG"},
182     {LMP_CLASS_HELLO, "HELLO"},
183     {LMP_CLASS_BEGIN_VERIFY, "BEGIN_VERIFY"},
184     {LMP_CLASS_BEGIN_VERIFY_ACK, "BEGIN_VERIFY_ACK"},
185     {LMP_CLASS_VERIFY_ID, "VERIFY_ID"},
186     {LMP_CLASS_TE_LINK, "TE_LINK"},
187     {LMP_CLASS_DATA_LINK, "DATA_LINK"},
188     {LMP_CLASS_CHANNEL_STATUS, "CHANNEL_STATUS"},
189     {LMP_CLASS_CHANNEL_STATUS_REQUEST, "CHANNEL_STATUS_REQUEST"},
190     {LMP_CLASS_ERROR, "ERROR"},
191 };
192
193 static value_string lmp_09_class_vals[] = {
194
195     {LMP_09_CLASS_CCID, "CCID"},
196     {LMP_09_CLASS_NODE_ID, "NODE_ID"},
197     {LMP_09_CLASS_LINK_ID, "LINK_ID"},
198     {LMP_09_CLASS_INTERFACE_ID, "INTERFACE_ID"},
199     {LMP_09_CLASS_MESSAGE_ID, "MESSAGE_ID"},
200     {LMP_09_CLASS_CONFIG, "CONFIG"},
201     {LMP_09_CLASS_HELLO, "HELLO"},
202     {LMP_09_CLASS_BEGIN_VERIFY, "BEGIN_VERIFY"},
203     {LMP_09_CLASS_BEGIN_VERIFY_ACK, "BEGIN_VERIFY_ACK"},
204     {LMP_09_CLASS_VERIFY_ID, "VERIFY_ID"},
205     {LMP_09_CLASS_TE_LINK, "TE_LINK"},
206     {LMP_09_CLASS_DATA_LINK, "DATA_LINK"},
207     {LMP_09_CLASS_CHANNEL_STATUS, "CHANNEL_STATUS"},
208     {LMP_09_CLASS_CHANNEL_STATUS_REQUEST, "CHANNEL_STATUS_REQUEST"},
209     {LMP_09_CLASS_ERROR, "ERROR"},
210 };
211
212
213 #define VALID_CLASS(class) ((class) > LMP_CLASS_NULL && (class) < LMP_CLASS_MAX)
214 #define VALID_09_CLASS(class) ((class) > LMP_CLASS_NULL && (((class) < LMP_09_CLASS_CHANNEL_STATUS_REQUEST) || ((class)==LMP_09_CLASS_ERROR)))
215
216 /*------------------------------------------------------------------------------
217  * Other constants & stuff
218  */
219
220 /* Channel Status */
221 static const value_string channel_status_str[] = {
222     {1, "Signal Okay (OK)"},
223     {2, "Signal Degraded (SD)"},
224     {3, "Signal Failed (SF)"},
225 };
226 static const value_string channel_status_short_str[] = {
227     {1, "OK"},
228     {2, "SD"},
229     {3, "SF"},
230 };
231
232 /*------------------------------------------------------------------------------
233  * LMP Filter values
234  */
235
236 enum lmp_filter_keys {
237
238   /* Message types ---------------- */
239   LMPF_MSG,
240
241   LMPF_MSG_CONFIG,
242   LMPF_MSG_CONFIG_ACK,
243   LMPF_MSG_CONFIG_NACK,
244   LMPF_MSG_HELLO,
245   LMPF_MSG_BEGIN_VERIFY,
246   LMPF_MSG_BEGIN_VERIFY_ACK,
247   LMPF_MSG_BEGIN_VERIFY_NACK,
248   LMPF_MSG_END_VERIFY,
249   LMPF_MSG_END_VERIFY_ACK,
250   LMPF_MSG_TEST,
251   LMPF_MSG_TEST_STATUS_SUCCESS,
252   LMPF_MSG_TEST_STATUS_FAILURE,
253   LMPF_MSG_TEST_STATUS_ACK,
254   LMPF_MSG_LINK_SUMMARY,
255   LMPF_MSG_LINK_SUMMARY_ACK,
256   LMPF_MSG_LINK_SUMMARY_NACK,
257   LMPF_MSG_CHANNEL_STATUS,
258   LMPF_MSG_CHANNEL_STATUS_ACK,
259   LMPF_MSG_CHANNEL_STATUS_REQ,
260   LMPF_MSG_CHANNEL_STATUS_RESP,
261
262   /* LMP Message Header Fields ------------------ */
263   LMPF_HDR_FLAGS,
264   LMPF_HDR_FLAGS_CC_DOWN,
265   LMPF_HDR_FLAGS_REBOOT,
266
267   /* LMP Object Class Filters -------------------- */
268   LMPF_OBJECT,
269
270   LMPF_CLASS_LOCAL_CCID,
271   LMPF_CLASS_REMOTE_CCID,
272   LMPF_CLASS_LOCAL_NODE_ID,
273   LMPF_CLASS_REMOTE_NODE_ID,
274   LMPF_CLASS_LOCAL_LINK_ID,
275   LMPF_CLASS_REMOTE_LINK_ID,
276   LMPF_CLASS_LOCAL_INTERFACE_ID,
277   LMPF_CLASS_REMOTE_INTERFACE_ID,
278   LMPF_CLASS_MESSAGE_ID,
279   LMPF_CLASS_MESSAGE_ID_ACK,
280   LMPF_CLASS_CONFIG,
281   LMPF_CLASS_HELLO,
282   LMPF_CLASS_BEGIN_VERIFY,
283   LMPF_CLASS_BEGIN_VERIFY_ACK,
284   LMPF_CLASS_VERIFY_ID,
285   LMPF_CLASS_TE_LINK,
286   LMPF_CLASS_DATA_LINK,
287   LMPF_CLASS_CHANNEL_STATUS,
288   LMPF_CLASS_CHANNEL_STATUS_REQUEST,
289   LMPF_CLASS_ERROR,
290
291   LMPF_09_OBJECT,
292
293   LMPF_09_CLASS_CCID,
294   LMPF_09_CLASS_NODE_ID,
295   LMPF_09_CLASS_LINK_ID,
296   LMPF_09_CLASS_INTERFACE_ID,
297   LMPF_09_CLASS_MESSAGE_ID,
298   LMPF_09_CLASS_CONFIG,
299   LMPF_09_CLASS_HELLO,
300   LMPF_09_CLASS_BEGIN_VERIFY,
301   LMPF_09_CLASS_BEGIN_VERIFY_ACK,
302   LMPF_09_CLASS_VERIFY_ID,
303   LMPF_09_CLASS_TE_LINK,
304   LMPF_09_CLASS_DATA_LINK,
305   LMPF_09_CLASS_CHANNEL_STATUS,
306   LMPF_09_CLASS_CHANNEL_STATUS_REQUEST,
307   LMPF_09_CLASS_ERROR,
308
309   LMPF_VAL_CTYPE,
310   LMPF_VAL_LOCAL_CCID,
311   LMPF_VAL_REMOTE_CCID,
312   LMPF_VAL_LOCAL_NODE_ID,
313   LMPF_VAL_REMOTE_NODE_ID,
314   LMPF_VAL_LOCAL_LINK_ID_IPV4,
315   LMPF_VAL_LOCAL_LINK_ID_IPV6,
316   LMPF_VAL_LOCAL_LINK_ID_UNNUM,
317   LMPF_VAL_REMOTE_LINK_ID_IPV4,
318   LMPF_VAL_REMOTE_LINK_ID_IPV6,
319   LMPF_VAL_REMOTE_LINK_ID_UNNUM,
320   LMPF_VAL_LOCAL_INTERFACE_ID_IPV4,
321   LMPF_VAL_LOCAL_INTERFACE_ID_IPV6,
322   LMPF_VAL_LOCAL_INTERFACE_ID_UNNUM,
323   LMPF_VAL_REMOTE_INTERFACE_ID_IPV4,
324   LMPF_VAL_REMOTE_INTERFACE_ID_IPV6,
325   LMPF_VAL_REMOTE_INTERFACE_ID_UNNUM,
326   LMPF_VAL_MESSAGE_ID,
327   LMPF_VAL_MESSAGE_ID_ACK,
328   LMPF_VAL_CONFIG_HELLO,
329   LMPF_VAL_CONFIG_HELLO_DEAD,
330   LMPF_VAL_HELLO_TXSEQ,
331   LMPF_VAL_HELLO_RXSEQ,
332
333   LMPF_VAL_BEGIN_VERIFY_FLAGS,
334   LMPF_VAL_BEGIN_VERIFY_FLAGS_ALL_LINKS,
335   LMPF_VAL_BEGIN_VERIFY_FLAGS_LINK_TYPE,
336   LMPF_VAL_BEGIN_VERIFY_INTERVAL,
337   LMPF_VAL_BEGIN_VERIFY_ENCTYPE,
338   LMPF_VAL_BEGIN_VERIFY_TRANSPORT,
339   LMPF_VAL_BEGIN_VERIFY_TRANSMISSION_RATE,
340   LMPF_VAL_BEGIN_VERIFY_WAVELENGTH,
341   LMPF_VAL_VERIFY_ID,
342
343   LMPF_VAL_TE_LINK_FLAGS,
344   LMPF_VAL_TE_LINK_FLAGS_FAULT_MGMT,
345   LMPF_VAL_TE_LINK_FLAGS_LINK_VERIFY,
346   LMPF_VAL_TE_LINK_LOCAL_IPV4,
347   LMPF_VAL_TE_LINK_LOCAL_UNNUM,
348   LMPF_VAL_TE_LINK_REMOTE_IPV4,
349   LMPF_VAL_TE_LINK_REMOTE_UNNUM,
350
351   LMPF_VAL_DATA_LINK_FLAGS,
352   LMPF_VAL_DATA_LINK_FLAGS_PORT,
353   LMPF_VAL_DATA_LINK_FLAGS_ALLOCATED,
354   LMPF_VAL_DATA_LINK_LOCAL_IPV4,
355   LMPF_VAL_DATA_LINK_LOCAL_UNNUM,
356   LMPF_VAL_DATA_LINK_REMOTE_IPV4,
357   LMPF_VAL_DATA_LINK_REMOTE_UNNUM,
358   LMPF_VAL_DATA_LINK_SUBOBJ,
359   LMPF_VAL_DATA_LINK_SUBOBJ_SWITCHING_TYPE,
360   LMPF_VAL_DATA_LINK_SUBOBJ_LSP_ENCODING,
361
362   LMPF_VAL_ERROR,
363   LMPF_VAL_ERROR_VERIFY_UNSUPPORTED_LINK,
364   LMPF_VAL_ERROR_VERIFY_UNWILLING,
365   LMPF_VAL_ERROR_VERIFY_TRANSPORT,
366   LMPF_VAL_ERROR_VERIFY_TE_LINK_ID,
367   LMPF_VAL_ERROR_VERIFY_UNKNOWN_CTYPE,
368   LMPF_VAL_ERROR_SUMMARY_BAD_PARAMETERS,
369   LMPF_VAL_ERROR_SUMMARY_RENEGOTIATE,
370   LMPF_VAL_ERROR_SUMMARY_BAD_TE_LINK,
371   LMPF_VAL_ERROR_SUMMARY_BAD_DATA_LINK,
372   LMPF_VAL_ERROR_SUMMARY_UNKNOWN_TEL_CTYPE,
373   LMPF_VAL_ERROR_SUMMARY_UNKNOWN_DL_CTYPE,
374   LMPF_VAL_ERROR_SUMMARY_BAD_REMOTE_LINK_ID,
375   LMPF_VAL_ERROR_CONFIG_BAD_PARAMETERS,
376   LMPF_VAL_ERROR_CONFIG_RENEGOTIATE,
377   LMPF_VAL_ERROR_CONFIG_BAD_CCID,
378
379   LMPF_VAL_SVCCFG_SIGPROTO_PROTO,
380   LMPF_VAL_SVCCFG_SIGPROTO_UNI_VERSION,
381   LMPF_VAL_SVCCFG_PORTATTR_LINK_TYPE,
382   LMPF_VAL_SVCCFG_PORTATTR_SIGNAL_TYPE,
383   LMPF_VAL_SVCCFG_PORTATTR_TP_TRANSPARENCY,
384   LMPF_VAL_SVCCFG_PORTATTR_MAX_NCC,
385   LMPF_VAL_SVCCFG_PORTATTR_MIN_NCC,
386   LMPF_VAL_SVCCFG_PORTATTR_MAX_NVC,
387   LMPF_VAL_SVCCFG_PORTATTR_MIN_NVC,
388   LMPF_VAL_SVCCFG_PORTATTR_INTFC_ID,
389   LMPF_VAL_SVCCFG_TRANSP_TRANSPARENCY,
390   LMPF_VAL_SVCCFG_TRANSP_TCM,
391   LMPF_VAL_SVCCFG_DIVERSITY_DIVERSITY,
392
393   LMPF_MAX
394 };
395
396 static int lmp_filter[LMPF_MAX];
397
398 static hf_register_info lmpf_info[] = {
399
400     /* Message type number */
401     {&lmp_filter[LMPF_MSG],
402      { "Message Type", "lmp.msg", FT_UINT8, BASE_DEC, VALS(message_type_vals), 0x0,
403         "", HFILL }},
404
405     /* Message type shorthands */
406     {&lmp_filter[LMPF_MSG_CONFIG],
407      { "Config Message", "lmp.msg.config", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
408         "", HFILL }},
409
410     {&lmp_filter[LMPF_MSG_CONFIG_ACK],
411      { "ConfigAck Message", "lmp.msg.configack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
412         "", HFILL }},
413
414     {&lmp_filter[LMPF_MSG_CONFIG_NACK],
415      { "ConfigNack Message", "lmp.msg.confignack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
416         "", HFILL }},
417
418     {&lmp_filter[LMPF_MSG_HELLO],
419      { "HELLO Message", "lmp.msg.hello", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
420         "", HFILL }},
421
422     {&lmp_filter[LMPF_MSG_BEGIN_VERIFY],
423      { "BeginVerify Message", "lmp.msg.beginverify", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
424         "", HFILL }},
425
426     {&lmp_filter[LMPF_MSG_BEGIN_VERIFY_ACK],
427      { "BeginVerifyAck Message", "lmp.msg.beginverifyack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
428         "", HFILL }},
429
430     {&lmp_filter[LMPF_MSG_BEGIN_VERIFY_NACK],
431      { "BeginVerifyNack Message", "lmp.msg.beginverifynack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
432         "", HFILL }},
433
434     {&lmp_filter[LMPF_MSG_END_VERIFY],
435      { "EndVerify Message", "lmp.msg.endverify", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
436         "", HFILL }},
437
438     {&lmp_filter[LMPF_MSG_END_VERIFY_ACK],
439      { "EndVerifyAck Message", "lmp.msg.endverifyack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
440         "", HFILL }},
441
442     {&lmp_filter[LMPF_MSG_TEST],
443      { "Test Message", "lmp.msg.test", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
444         "", HFILL }},
445
446     {&lmp_filter[LMPF_MSG_TEST_STATUS_SUCCESS],
447      { "TestStatusSuccess Message", "lmp.msg.teststatussuccess", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
448         "", HFILL }},
449
450     {&lmp_filter[LMPF_MSG_TEST_STATUS_FAILURE],
451      { "TestStatusFailure Message", "lmp.msg.teststatusfailure", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
452         "", HFILL }},
453
454     {&lmp_filter[LMPF_MSG_TEST_STATUS_ACK],
455      { "TestStatusAck Message", "lmp.msg.teststatusack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
456         "", HFILL }},
457
458     {&lmp_filter[LMPF_MSG_LINK_SUMMARY],
459      { "LinkSummary Message", "lmp.msg.linksummary", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
460         "", HFILL }},
461
462     {&lmp_filter[LMPF_MSG_LINK_SUMMARY_ACK],
463      { "LinkSummaryAck Message", "lmp.msg.linksummaryack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
464         "", HFILL }},
465
466     {&lmp_filter[LMPF_MSG_LINK_SUMMARY_NACK],
467      { "LinkSummaryNack Message", "lmp.msg.linksummarynack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
468         "", HFILL }},
469
470     {&lmp_filter[LMPF_MSG_CHANNEL_STATUS],
471      { "ChannelStatus Message", "lmp.msg.channelstatus", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
472         "", HFILL }},
473
474     {&lmp_filter[LMPF_MSG_CHANNEL_STATUS_ACK],
475      { "ChannelStatusAck Message", "lmp.msg.channelstatusack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
476         "", HFILL }},
477
478     {&lmp_filter[LMPF_MSG_CHANNEL_STATUS_REQ],
479      { "ChannelStatusRequest Message", "lmp.msg.channelstatusrequest", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
480         "", HFILL }},
481
482     {&lmp_filter[LMPF_MSG_CHANNEL_STATUS_RESP],
483      { "ChannelStatusResponse Message", "lmp.msg.channelstatusresponse", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
484         "", HFILL }},
485
486
487     /* LMP Message Header Fields ------------------- */
488
489     {&lmp_filter[LMPF_HDR_FLAGS],
490      { "LMP Header - Flags", "lmp.hdr.flags", FT_UINT8, BASE_DEC, NULL, 0x0,
491         "", HFILL }},
492
493     {&lmp_filter[LMPF_HDR_FLAGS_CC_DOWN],
494      { "ControlChannelDown", "lmp.hdr.ccdown", FT_BOOLEAN, 8, NULL, 0x01,
495         "", HFILL }},
496
497     {&lmp_filter[LMPF_HDR_FLAGS_REBOOT],
498      { "Reboot", "lmp.hdr.reboot", FT_BOOLEAN, 8, NULL, 0x02,
499         "", HFILL }},
500
501     /* LMP object class filters ------------------------------- */
502
503     {&lmp_filter[LMPF_OBJECT],
504      { "LOCAL_CCID", "lmp.object", FT_UINT8, BASE_DEC, NULL, 0x0,
505         "", HFILL }},
506
507     {&lmp_filter[LMPF_CLASS_LOCAL_CCID],
508      { "Local CCID", "lmp.obj.ccid", FT_NONE, BASE_NONE, NULL, 0x0,
509         "", HFILL }},
510     {&lmp_filter[LMPF_CLASS_REMOTE_CCID],
511      { "Remote CCID", "lmp.obj.ccid", FT_NONE, BASE_NONE, NULL, 0x0,
512         "", HFILL }},
513     {&lmp_filter[LMPF_CLASS_LOCAL_NODE_ID],
514      { "Local NODE_ID", "lmp.obj.Nodeid", FT_NONE, BASE_NONE, NULL, 0x0,
515         "", HFILL }},
516     {&lmp_filter[LMPF_CLASS_REMOTE_NODE_ID],
517      { "Remote NODE_ID", "lmp.obj.Nodeid", FT_NONE, BASE_NONE, NULL, 0x0,
518         "", HFILL }},
519     {&lmp_filter[LMPF_CLASS_LOCAL_LINK_ID],
520      { "Local LINK_ID", "lmp.obj.linkid", FT_NONE, BASE_NONE, NULL, 0x0,
521         "", HFILL }},
522     {&lmp_filter[LMPF_CLASS_REMOTE_LINK_ID],
523      { "Remote LINK_ID", "lmp.obj.linkid", FT_NONE, BASE_NONE, NULL, 0x0,
524         "", HFILL }},
525     {&lmp_filter[LMPF_CLASS_LOCAL_INTERFACE_ID],
526      { "Local INTERFACE_ID", "lmp.obj.interfaceid", FT_NONE, BASE_NONE, NULL, 0x0,
527         "", HFILL }},
528     {&lmp_filter[LMPF_CLASS_REMOTE_INTERFACE_ID],
529      { "Remote INTERFACE_ID", "lmp.obj.interfaceid", FT_NONE, BASE_NONE, NULL, 0x0,
530         "", HFILL }},
531     {&lmp_filter[LMPF_CLASS_MESSAGE_ID],
532      { "MESSAGE_ID", "lmp.obj.messageid", FT_NONE, BASE_NONE, NULL, 0x0,
533         "", HFILL }},
534     {&lmp_filter[LMPF_CLASS_MESSAGE_ID_ACK],
535      { "MESSAGE_ID Ack", "lmp.obj.messageid", FT_NONE, BASE_NONE, NULL, 0x0,
536         "", HFILL }},
537     {&lmp_filter[LMPF_CLASS_CONFIG],
538      { "CONFIG", "lmp.obj.config", FT_NONE, BASE_NONE, NULL, 0x0,
539         "", HFILL }},
540     {&lmp_filter[LMPF_CLASS_HELLO],
541      { "HELLO", "lmp.obj.hello", FT_NONE, BASE_NONE, NULL, 0x0,
542         "", HFILL }},
543     {&lmp_filter[LMPF_CLASS_BEGIN_VERIFY],
544      { "BEGIN_VERIFY", "lmp.obj.begin_verify", FT_NONE, BASE_NONE, NULL, 0x0,
545         "", HFILL }},
546     {&lmp_filter[LMPF_CLASS_BEGIN_VERIFY_ACK],
547      { "BEGIN_VERIFY_ACK", "lmp.obj.begin_verify_ack", FT_NONE, BASE_NONE, NULL, 0x0,
548         "", HFILL }},
549     {&lmp_filter[LMPF_CLASS_VERIFY_ID],
550      { "VERIFY_ID", "lmp.obj.verifyid", FT_NONE, BASE_NONE, NULL, 0x0,
551         "", HFILL }},
552
553     {&lmp_filter[LMPF_CLASS_TE_LINK],
554      { "TE_LINK", "lmp.obj.te_link", FT_NONE, BASE_NONE, NULL, 0x0,
555         "", HFILL }},
556     {&lmp_filter[LMPF_CLASS_DATA_LINK],
557      { "DATA_LINK", "lmp.obj.data_link", FT_NONE, BASE_NONE, NULL, 0x0,
558         "", HFILL }},
559
560     {&lmp_filter[LMPF_CLASS_CHANNEL_STATUS],
561      { "CHANNEL_STATUS", "lmp.obj.channel_status", FT_NONE, BASE_NONE, NULL, 0x0,
562         "", HFILL }},
563     {&lmp_filter[LMPF_CLASS_CHANNEL_STATUS_REQUEST],
564      { "CHANNEL_STATUS_REQUEST", "lmp.obj.channel_status_request", FT_NONE, BASE_NONE, NULL, 0x0,
565         "", HFILL }},
566     {&lmp_filter[LMPF_CLASS_ERROR],
567      { "ERROR", "lmp.obj.error", FT_NONE, BASE_NONE, NULL, 0x0,
568         "", HFILL }},
569
570     {&lmp_filter[LMPF_09_OBJECT],
571      { "LOCAL_CCID", "lmp.object", FT_UINT8, BASE_DEC, NULL, 0x0,
572         "", HFILL }},
573
574     {&lmp_filter[LMPF_09_CLASS_CCID],
575      { "CCID", "lmp.obj.ccid", FT_NONE, BASE_NONE, NULL, 0x0,
576         "", HFILL }},
577     {&lmp_filter[LMPF_09_CLASS_NODE_ID],
578      { "NODE_ID", "lmp.obj.Nodeid", FT_NONE, BASE_NONE, NULL, 0x0,
579         "", HFILL }},
580     {&lmp_filter[LMPF_09_CLASS_LINK_ID],
581      { "LINK_ID", "lmp.obj.linkid", FT_NONE, BASE_NONE, NULL, 0x0,
582         "", HFILL }},
583     {&lmp_filter[LMPF_09_CLASS_INTERFACE_ID],
584      { "INTERFACE_ID", "lmp.obj.interfaceid", FT_NONE, BASE_NONE, NULL, 0x0,
585         "", HFILL }},
586     {&lmp_filter[LMPF_09_CLASS_MESSAGE_ID],
587      { "MESSAGE_ID", "lmp.obj.messageid", FT_NONE, BASE_NONE, NULL, 0x0,
588         "", HFILL }},
589     {&lmp_filter[LMPF_09_CLASS_CONFIG],
590      { "CONFIG", "lmp.obj.config", FT_NONE, BASE_NONE, NULL, 0x0,
591         "", HFILL }},
592     {&lmp_filter[LMPF_09_CLASS_HELLO],
593      { "HELLO", "lmp.obj.hello", FT_NONE, BASE_NONE, NULL, 0x0,
594         "", HFILL }},
595     {&lmp_filter[LMPF_09_CLASS_BEGIN_VERIFY],
596      { "BEGIN_VERIFY", "lmp.obj.begin_verify", FT_NONE, BASE_NONE, NULL, 0x0,
597         "", HFILL }},
598     {&lmp_filter[LMPF_09_CLASS_BEGIN_VERIFY_ACK],
599      { "BEGIN_VERIFY_ACK", "lmp.obj.begin_verify_ack", FT_NONE, BASE_NONE, NULL, 0x0,
600         "", HFILL }},
601     {&lmp_filter[LMPF_09_CLASS_VERIFY_ID],
602      { "VERIFY_ID", "lmp.obj.verifyid", FT_NONE, BASE_NONE, NULL, 0x0,
603         "", HFILL }},
604
605     {&lmp_filter[LMPF_09_CLASS_TE_LINK],
606      { "TE_LINK", "lmp.obj.te_link", FT_NONE, BASE_NONE, NULL, 0x0,
607         "", HFILL }},
608     {&lmp_filter[LMPF_09_CLASS_DATA_LINK],
609      { "DATA_LINK", "lmp.obj.data_link", FT_NONE, BASE_NONE, NULL, 0x0,
610         "", HFILL }},
611
612     {&lmp_filter[LMPF_09_CLASS_CHANNEL_STATUS],
613      { "CHANNEL_STATUS", "lmp.obj.channel_status", FT_NONE, BASE_NONE, NULL, 0x0,
614         "", HFILL }},
615     {&lmp_filter[LMPF_09_CLASS_CHANNEL_STATUS_REQUEST],
616      { "CHANNEL_STATUS_REQUEST", "lmp.obj.channel_status_request", FT_NONE, BASE_NONE, NULL, 0x0,
617         "", HFILL }},
618     {&lmp_filter[LMPF_09_CLASS_ERROR],
619      { "ERROR", "lmp.obj.error", FT_NONE, BASE_NONE, NULL, 0x0,
620         "", HFILL }},
621
622     /* Other LMP Value Filters ------------------------------ */
623
624     {&lmp_filter[LMPF_VAL_CTYPE],
625      { "Object C-Type", "lmp.obj.ctype", FT_UINT8, BASE_DEC, NULL, 0x0,
626         "", HFILL }},
627
628     {&lmp_filter[LMPF_VAL_LOCAL_CCID],
629      { "Local CCID Value", "lmp.local_ccid", FT_UINT32, BASE_DEC, NULL, 0x0,
630         "", HFILL }},
631     {&lmp_filter[LMPF_VAL_REMOTE_CCID],
632      { "Remote CCID Value", "lmp.remote_ccid", FT_UINT32, BASE_DEC, NULL, 0x0,
633         "", HFILL }},
634
635     {&lmp_filter[LMPF_VAL_LOCAL_NODE_ID],
636      { "Local Node ID Value", "lmp.local_nodeid", FT_IPv4, BASE_NONE, NULL, 0x0,
637         "", HFILL }},
638     {&lmp_filter[LMPF_VAL_REMOTE_NODE_ID],
639      { "Remote Node ID Value", "lmp.remote_nodeid", FT_IPv4, BASE_NONE, NULL, 0x0,
640         "", HFILL }},
641
642     {&lmp_filter[LMPF_VAL_LOCAL_LINK_ID_IPV4],
643      { "Local Link ID - IPv4", "lmp.local_linkid_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
644         "", HFILL }},
645     {&lmp_filter[LMPF_VAL_LOCAL_LINK_ID_UNNUM],
646      { "Local Link ID - Unnumbered", "lmp.local_linkid_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
647         "", HFILL }},
648     {&lmp_filter[LMPF_VAL_REMOTE_LINK_ID_IPV4],
649      { "Remote Link ID - IPv4", "lmp.remote_linkid_ipv4", FT_UINT32, BASE_DEC, NULL, 0x0,
650         "", HFILL }},
651     {&lmp_filter[LMPF_VAL_REMOTE_LINK_ID_UNNUM],
652      { "Remote Link ID - Unnumbered", "lmp.remote_linkid_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
653         "", HFILL }},
654
655     {&lmp_filter[LMPF_VAL_LOCAL_INTERFACE_ID_IPV4],
656      { "Local Interface ID - IPv4", "lmp.local_interfaceid_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
657         "", HFILL }},
658     {&lmp_filter[LMPF_VAL_LOCAL_INTERFACE_ID_UNNUM],
659      { "Local Interface ID - Unnumbered", "lmp.local_interfaceid_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
660         "", HFILL }},
661     {&lmp_filter[LMPF_VAL_REMOTE_INTERFACE_ID_IPV4],
662      { "Remote Interface ID - IPv4", "lmp.remote_interfaceid_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
663         "", HFILL }},
664     {&lmp_filter[LMPF_VAL_REMOTE_INTERFACE_ID_UNNUM],
665      { "Remote Interface ID - Unnumbered", "lmp.remote_interfaceid_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
666         "", HFILL }},
667
668     {&lmp_filter[LMPF_VAL_MESSAGE_ID],
669      { "Message-ID Value", "lmp.messageid", FT_UINT32, BASE_DEC, NULL, 0x0,
670         "", HFILL }},
671     {&lmp_filter[LMPF_VAL_MESSAGE_ID_ACK],
672      { "Message-ID Ack Value", "lmp.messageid_ack", FT_UINT32, BASE_DEC, NULL, 0x0,
673         "", HFILL }},
674
675     {&lmp_filter[LMPF_VAL_CONFIG_HELLO],
676      { "HelloInterval", "lmp.hellointerval", FT_UINT32, BASE_DEC, NULL, 0x0,
677         "", HFILL }},
678     {&lmp_filter[LMPF_VAL_CONFIG_HELLO_DEAD],
679      { "HelloDeadInterval", "lmp.hellodeadinterval", FT_UINT32, BASE_DEC, NULL, 0x0,
680         "", HFILL }},
681
682     {&lmp_filter[LMPF_VAL_HELLO_TXSEQ],
683      { "TxSeqNum", "lmp.txseqnum", FT_UINT32, BASE_DEC, NULL, 0x0,
684         "", HFILL }},
685     {&lmp_filter[LMPF_VAL_HELLO_RXSEQ],
686      { "RxSeqNum", "lmp.rxseqnum", FT_UINT32, BASE_DEC, NULL, 0x0,
687         "", HFILL }},
688
689     {&lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS],
690      { "Flags", "lmp.begin_verify.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
691         "", HFILL }},
692     {&lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_ALL_LINKS],
693      { "Verify All Links", "lmp.begin_verify.all_links",
694        FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
695     {&lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_LINK_TYPE],
696      { "Data Link Type", "lmp.begin_verify.link_type",
697        FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
698     {&lmp_filter[LMPF_VAL_BEGIN_VERIFY_ENCTYPE],
699      { "Encoding Type", "lmp.begin_verify.enctype", FT_UINT8, BASE_DEC, VALS(gmpls_lsp_enc_str), 0x0,
700         "", HFILL }},
701     {&lmp_filter[LMPF_VAL_VERIFY_ID],
702      { "Verify-ID", "lmp.verifyid", FT_UINT32, BASE_DEC, NULL, 0x0,
703         "", HFILL }},
704
705     {&lmp_filter[LMPF_VAL_TE_LINK_FLAGS],
706      { "TE-Link Flags", "lmp.te_link_flags", FT_UINT8, BASE_HEX, NULL, 0x0,
707         "", HFILL }},
708     {&lmp_filter[LMPF_VAL_TE_LINK_FLAGS_FAULT_MGMT],
709      { "Fault Management Supported", "lmp.te_link.fault_mgmt",
710        FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
711     {&lmp_filter[LMPF_VAL_TE_LINK_FLAGS_LINK_VERIFY],
712      { "Link Verification Supported", "lmp.te_link.link_verify",
713        FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
714     {&lmp_filter[LMPF_VAL_TE_LINK_LOCAL_IPV4],
715      { "TE-Link Local ID - IPv4", "lmp.te_link.local_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
716         "", HFILL }},
717     {&lmp_filter[LMPF_VAL_TE_LINK_LOCAL_UNNUM],
718      { "TE-Link Local ID - Unnumbered", "lmp.te_link.local_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
719         "", HFILL }},
720     {&lmp_filter[LMPF_VAL_TE_LINK_REMOTE_IPV4],
721      { "TE-Link Remote ID - IPv4", "lmp.te_link.remote_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
722         "", HFILL }},
723     {&lmp_filter[LMPF_VAL_TE_LINK_REMOTE_UNNUM],
724      { "TE-Link Remote ID - Unnumbered", "lmp.te_link.remote_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
725         "", HFILL }},
726
727     {&lmp_filter[LMPF_VAL_DATA_LINK_FLAGS],
728      { "Data-Link Flags", "lmp.data_link_flags", FT_UINT8, BASE_HEX, NULL, 0x0,
729         "", HFILL }},
730     {&lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_PORT],
731      { "Data-Link is Individual Port", "lmp.data_link.port",
732        FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
733     {&lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_ALLOCATED],
734      { "Data-Link is Allocated", "lmp.data_link.link_verify",
735        FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
736     {&lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_IPV4],
737      { "Data-Link Local ID - IPv4", "lmp.data_link.local_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
738         "", HFILL }},
739     {&lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_UNNUM],
740      { "Data-Link Local ID - Unnumbered", "lmp.data_link.local_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
741         "", HFILL }},
742     {&lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_IPV4],
743      { "Data-Link Remote ID - IPv4", "lmp.data_link.remote_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
744         "", HFILL }},
745     {&lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_UNNUM],
746      { "Data-Link Remote ID - Unnumbered", "lmp.data_link.remote_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
747         "", HFILL }},
748     {&lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ],
749      { "Subobject", "lmp.data_link_subobj", FT_NONE, BASE_DEC, NULL, 0x0,
750         "", HFILL }},
751     {&lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_SWITCHING_TYPE],
752      { "Interface Switching Capability", "lmp.data_link_switching", FT_UINT8, BASE_DEC,
753        VALS(gmpls_switching_type_str), 0x0, "", HFILL }},
754     {&lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_LSP_ENCODING],
755      { "LSP Encoding Type", "lmp.data_link_encoding", FT_UINT8, BASE_DEC,
756        VALS(gmpls_lsp_enc_str), 0x0, "", HFILL }},
757
758     {&lmp_filter[LMPF_VAL_ERROR],
759      { "Error Code", "lmp.error", FT_UINT32, BASE_HEX, NULL, 0x0,
760         "", HFILL }},
761
762     {&lmp_filter[LMPF_VAL_ERROR_VERIFY_UNSUPPORTED_LINK],
763      { "Verification - Unsupported for this TE-Link", "lmp.error.verify_unsupported_link",
764        FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
765     {&lmp_filter[LMPF_VAL_ERROR_VERIFY_UNWILLING],
766      { "Verification - Unwilling to Verify at this time", "lmp.error.verify_unwilling",
767        FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
768     {&lmp_filter[LMPF_VAL_ERROR_VERIFY_TRANSPORT],
769      { "Verification - Transport Unsupported", "lmp.error.verify_unsupported_transport",
770        FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }},
771     {&lmp_filter[LMPF_VAL_ERROR_VERIFY_TE_LINK_ID],
772      { "Verification - TE Link ID Configuration Error", "lmp.error.verify_te_link_id",
773        FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }},
774
775     {&lmp_filter[LMPF_VAL_ERROR_VERIFY_UNKNOWN_CTYPE],
776      { "Verification - Unknown Object C-Type", "lmp.error.verify_unknown_ctype",
777        FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }},
778
779     {&lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_PARAMETERS],
780      { "Summary - Unacceptable non-negotiable parameters", "lmp.error.summary_bad_params",
781        FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
782     {&lmp_filter[LMPF_VAL_ERROR_SUMMARY_RENEGOTIATE],
783      { "Summary - Renegotiate Parametere", "lmp.error.summary_renegotiate",
784        FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
785     {&lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_TE_LINK],
786      { "Summary - Bad TE Link Object", "lmp.error.summary_bad_te_link",
787        FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }},
788     {&lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_DATA_LINK],
789      { "Summary - Bad Data Link Object", "lmp.error.summary_bad_data_link",
790        FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }},
791     {&lmp_filter[LMPF_VAL_ERROR_SUMMARY_UNKNOWN_TEL_CTYPE],
792      { "Summary - Bad TE Link C-Type", "lmp.error.summary_unknown_tel_ctype",
793        FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }},
794     {&lmp_filter[LMPF_VAL_ERROR_SUMMARY_UNKNOWN_DL_CTYPE],
795      { "Summary - Bad Data Link C-Type", "lmp.error.summary_unknown_dl_ctype",
796        FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }},
797     {&lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_REMOTE_LINK_ID],
798      { "Summary - Bad Remote Link ID", "lmp.error.summary_bad_remote_link_id",
799        FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }},
800     {&lmp_filter[LMPF_VAL_ERROR_CONFIG_BAD_PARAMETERS],
801      { "Config - Unacceptable non-negotiable parameters", "lmp.error.config_bad_params",
802        FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
803     {&lmp_filter[LMPF_VAL_ERROR_CONFIG_RENEGOTIATE],
804      { "Config - Renegotiate Parametere", "lmp.error.config_renegotiate",
805        FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
806     {&lmp_filter[LMPF_VAL_ERROR_CONFIG_BAD_CCID],
807      { "Config - Bad CC ID", "lmp.error.config_bad_ccid",
808        FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}
809
810 };
811
812 static int
813 lmp_class_to_filter_num(int class)
814 {
815     if (VALID_CLASS(class))
816         return class + LMPF_OBJECT;
817     return -1;
818 }
819
820 static int
821 lmp_09_class_to_filter_num(int class)
822 {
823     guint16 gap = LMP_09_CLASS_ERROR - LMP_09_CLASS_CHANNEL_STATUS_REQUEST;
824
825     if (VALID_09_CLASS(class)) {
826         if (class != LMP_09_CLASS_ERROR)
827             return LMPF_09_OBJECT + class;
828         else {
829             return LMPF_09_OBJECT + class - gap + 1;
830         }
831     }
832     return -1;
833 }
834
835
836 /*------------------------------------------------------------------------------
837  * LMP Subtrees
838  *
839  * We have two types of subtrees - a statically defined, constant set and
840  * a class set - one for each class. The static ones are before all the class ones
841  */
842 enum {
843     LMP_TREE_MAIN,
844     LMP_TREE_HEADER,
845     LMP_TREE_HEADER_FLAGS,
846     LMP_TREE_OBJECT_HEADER,
847     LMP_TREE_ERROR_FLAGS,
848     LMP_TREE_BEGIN_VERIFY_FLAGS,
849     LMP_TREE_BEGIN_VERIFY_TRANSPORT_FLAGS,
850     LMP_TREE_TE_LINK_FLAGS,
851     LMP_TREE_DATA_LINK_FLAGS,
852     LMP_TREE_DATA_LINK_SUBOBJ,
853     LMP_TREE_CHANNEL_STATUS_ID,
854
855     LMP_TREE_CLASS_START
856 };
857 #define NUM_LMP_SUBTREES (LMP_TREE_CLASS_START + LMP_CLASS_MAX)
858 #define NUM_LMP_09_SUBTREES (LMP_TREE_CLASS_START + LMP_09_CLASS_MAX)
859
860 static gint lmp_subtree[MAX(NUM_LMP_SUBTREES,NUM_LMP_09_SUBTREES)];
861 static gint lmp_09_subtree[NUM_LMP_09_SUBTREES];
862
863 static int lmp_class_to_subtree(int class)
864 {
865     if (VALID_CLASS(class))
866         return lmp_subtree[LMP_TREE_CLASS_START + class];
867
868     return -1;
869 }
870
871 static int lmp_09_class_to_subtree(int class)
872 {
873     if (VALID_09_CLASS(class))
874         return lmp_09_subtree[LMP_TREE_CLASS_START + class];
875
876     return -1;
877 }
878
879 /*------------------------------------------------------------------------------
880  * Da code
881  */
882
883 static void
884 dissect_lmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
885 {
886     int offset = 0;
887     proto_tree *lmp_tree = NULL, *ti, *ti2;
888     proto_tree *lmp_header_tree;
889     proto_tree *lmp_header_flags_tree;
890     proto_tree *lmp_object_tree;
891     proto_tree *lmp_object_header_tree;
892     proto_tree *lmp_flags_tree;
893     proto_tree *lmp_subobj_tree;
894
895     guint8 version;
896     guint8 flags;
897     guint8 message_type;
898     guint16 cksum, computed_cksum;
899     vec_t cksum_vec[1];
900     int j, k, l, len;
901     int msg_length;
902     int obj_length;
903     int mylen;
904     int offset2;
905     int proto;
906
907     proto = pinfo->ipproto;
908     /* If the current preference is NOT LMP09, do not process UDP packets */
909     if ((proto == IP_PROTO_UDP) && (lmp_draft_ver != LMP_VER_DRAFT_CCAMP_09)) {
910         return;
911     }
912     /* If the current preference is NOT LMP09, process only UDP packets */
913     if ((proto != IP_PROTO_UDP) && (lmp_draft_ver == LMP_VER_DRAFT_CCAMP_09)) {
914         return;
915     }
916
917     if (check_col(pinfo->cinfo, COL_PROTOCOL))
918         col_set_str(pinfo->cinfo, COL_PROTOCOL, "LMP");
919     if (check_col(pinfo->cinfo, COL_INFO))
920         col_clear(pinfo->cinfo, COL_INFO);
921
922     version = (tvb_get_guint8(tvb, offset+0)) >> 4;
923     flags = tvb_get_guint8(tvb, offset+2);
924     message_type = tvb_get_guint8(tvb, offset+3);
925     if (check_col(pinfo->cinfo, COL_INFO)) {
926         col_add_str(pinfo->cinfo, COL_INFO,
927             val_to_str(message_type, message_type_vals, "Unknown (%u). "));
928     }
929
930     if (tree) {
931         msg_length = tvb_get_ntohs(tvb, offset+4);
932         ti = proto_tree_add_item(tree, proto_lmp, tvb, offset, msg_length,
933             FALSE);
934         lmp_tree = proto_item_add_subtree(ti, lmp_subtree[LMP_TREE_MAIN]);
935         ti = proto_tree_add_text(lmp_tree, tvb, offset, 12, "LMP Header. %s",
936                                  val_to_str(message_type, message_type_vals,
937                                             "Unknown Message (%u). "));
938         lmp_header_tree = proto_item_add_subtree(ti, lmp_subtree[LMP_TREE_HEADER]);
939         proto_tree_add_text(lmp_header_tree, tvb, offset, 1, "LMP Version: %u",
940                             version);
941         ti = proto_tree_add_text(lmp_header_tree, tvb, offset+2, 1, "Flags: %02x",
942                                  flags);
943         lmp_header_flags_tree = proto_item_add_subtree(ti, lmp_subtree[LMP_TREE_HEADER_FLAGS]);
944         proto_tree_add_boolean(lmp_header_flags_tree, lmp_filter[LMPF_HDR_FLAGS_CC_DOWN],
945                                tvb, offset+2, 1, flags);
946         proto_tree_add_boolean(lmp_header_flags_tree, lmp_filter[LMPF_HDR_FLAGS_REBOOT],
947                                tvb, offset+2, 1, flags);
948         proto_tree_add_uint(lmp_header_tree, lmp_filter[LMPF_MSG], tvb,
949                             offset+3, 1, message_type);
950         proto_tree_add_text(lmp_header_tree, tvb, offset+4, 2, "Length: %d bytes",
951                             msg_length);
952         if (LMPF_MSG + message_type <= LMPF_MSG_CHANNEL_STATUS_RESP &&
953                        message_type > 0) {
954             proto_tree_add_boolean_hidden(lmp_header_tree, lmp_filter[LMPF_MSG + message_type], tvb,
955                                           offset+3, 1, 1);
956         } else {
957             proto_tree_add_protocol_format(lmp_header_tree, proto_malformed, tvb, offset+3, 1,
958                                            "Invalid message type: %u", message_type);
959                 return;
960         }
961
962         cksum = tvb_get_ntohs(tvb, offset+6);
963         if (!pinfo->fragmented && (int) tvb_length(tvb) >= msg_length) {
964             /* The packet isn't part of a fragmented datagram and isn't
965                truncated, so we can checksum it. */
966             cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, msg_length);
967             cksum_vec[0].len = msg_length;
968             computed_cksum = in_cksum(&cksum_vec[0], 1);
969
970             if (computed_cksum == 0) {
971                 proto_tree_add_text(lmp_header_tree, tvb, offset+6, 2,
972                                     "Message Checksum: 0x%04x (correct)",
973                                     cksum);
974             } else {
975                 proto_tree_add_text(lmp_header_tree, tvb, offset+6, 2,
976                                     "Message Checksum: 0x%04x (incorrect, should be 0x%04x)",
977                                     cksum,
978                                     in_cksum_shouldbe(cksum, computed_cksum));
979             }
980         } else {
981             proto_tree_add_text(lmp_header_tree, tvb, offset+6, 2,
982                                 "Message Checksum: 0x%04x",
983                                 cksum);
984         }
985
986         offset += 8;
987         len = 8;
988         while (len < msg_length) {
989           guint8 class;
990           guint8 type;
991           guint8 negotiable;
992           char *object_type;
993
994           obj_length = tvb_get_ntohs(tvb, offset+2);
995           class = tvb_get_guint8(tvb, offset+1);
996           type = tvb_get_guint8(tvb, offset);
997           negotiable = (type >> 7); type &= 0x7f;
998           if (lmp_draft_ver == LMP_VER_DRAFT_CCAMP_09) {
999                 object_type = val_to_str(class, lmp_09_class_vals, "Unknown");
1000                 proto_tree_add_uint_hidden(lmp_tree, lmp_filter[LMPF_09_OBJECT],
1001                                            tvb,
1002                                            offset, 1, class);
1003                 if (VALID_09_CLASS(class)) {
1004                     ti = proto_tree_add_item(lmp_tree, lmp_filter[lmp_09_class_to_filter_num(class)],
1005                         tvb, offset, obj_length, FALSE);
1006                 } else {
1007                     proto_tree_add_protocol_format(lmp_tree, proto_malformed, tvb, offset+1, 1,
1008                         "Invalid class: %u", class);
1009                     return;
1010                 }
1011                 lmp_object_tree = proto_item_add_subtree(ti, lmp_09_class_to_subtree(class));
1012
1013                 ti2 = proto_tree_add_text(lmp_object_tree, tvb, offset, 4,
1014                                       "Header. Class %d, C-Type %d, Length %d, %s",
1015                                       class, type, obj_length,
1016                                       negotiable ? "Negotiable" : "Not Negotiable");
1017                 lmp_object_header_tree = proto_item_add_subtree(ti2, lmp_09_subtree[LMP_TREE_OBJECT_HEADER]);
1018                 proto_tree_add_text(lmp_object_header_tree, tvb, offset, 1,
1019                                 negotiable ? "Negotiable" : "Not Negotiable");
1020                 proto_tree_add_text(lmp_object_header_tree, tvb, offset+2, 2,
1021                                 "Length: %u", obj_length);
1022                 proto_tree_add_text(lmp_object_header_tree, tvb, offset+1, 1,
1023                                 "Object Class: %u - %s",
1024                                 class, object_type);
1025                 proto_tree_add_item(lmp_object_header_tree, lmp_filter[LMPF_VAL_CTYPE],
1026                                     tvb, offset, 1, type);
1027                 offset2 = offset+4;
1028                 mylen = obj_length - 4;
1029           } else /* LMP_VER_DRAFT_CCAMP_03 */ {
1030                 object_type = val_to_str(class, lmp_class_vals, "Unknown");
1031                 proto_tree_add_uint_hidden(lmp_tree, lmp_filter[LMPF_OBJECT],
1032                                            tvb,
1033                                            offset, 1, class);
1034
1035                 if (VALID_CLASS(class)) {
1036                     ti = proto_tree_add_item(lmp_tree, lmp_filter[lmp_class_to_filter_num(class)],
1037                         tvb, offset, obj_length, FALSE);
1038                 } else {
1039                     proto_tree_add_protocol_format(lmp_tree, proto_malformed, tvb, offset+1, 1,
1040                         "Invalid class: %u", class);
1041                     return;
1042                 }
1043
1044                 lmp_object_tree = proto_item_add_subtree(ti, lmp_class_to_subtree(class));
1045
1046                 ti2 = proto_tree_add_text(lmp_object_tree, tvb, offset, 4,
1047                                       "Header. Class %d, C-Type %d, Length %d, %s",
1048                                       class, type, obj_length,
1049                                       negotiable ? "Negotiable" : "Not Negotiable");
1050                 lmp_object_header_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_OBJECT_HEADER]);
1051                 proto_tree_add_text(lmp_object_header_tree, tvb, offset, 1,
1052                                 negotiable ? "Negotiable" : "Not Negotiable");
1053                 proto_tree_add_text(lmp_object_header_tree, tvb, offset+2, 2,
1054                                 "Length: %u", obj_length);
1055                 proto_tree_add_text(lmp_object_header_tree, tvb, offset+1, 1,
1056                                 "Object Class: %u - %s",
1057                                 class, object_type);
1058                 proto_tree_add_item(lmp_object_header_tree, lmp_filter[LMPF_VAL_CTYPE],
1059                                     tvb, offset, 1, type);
1060                 offset2 = offset+4;
1061                 mylen = obj_length - 4;
1062           }
1063
1064           if (lmp_draft_ver == LMP_VER_DRAFT_CCAMP_09) {
1065
1066             switch (class) {
1067
1068             case LMP_CLASS_NULL:
1069                 break;
1070
1071             case LMP_09_CLASS_CCID:
1072                 switch(type) {
1073                 case 1:
1074                     l = LMPF_VAL_LOCAL_CCID;
1075                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1076                     proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1077                                         tvb_get_ntohl(tvb, offset2));
1078                     break;
1079                 case 2:
1080                     l = LMPF_VAL_REMOTE_CCID;
1081                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1082                     proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1083                                         tvb_get_ntohl(tvb, offset2));
1084                 default:
1085                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1086                                         "Data (%d bytes)", mylen);
1087                     break;
1088                 }
1089                 break;
1090
1091             case LMP_09_CLASS_NODE_ID:
1092                 switch(type) {
1093                 case 1:
1094                     l = LMPF_VAL_LOCAL_NODE_ID;
1095                     proto_item_append_text(ti, ": %s",
1096                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1097                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1098                                         FALSE);
1099                     break;
1100                 case 2:
1101                     l = LMPF_VAL_REMOTE_NODE_ID;
1102                     proto_item_append_text(ti, ": %s",
1103                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1104                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1105                                         FALSE);
1106                     break;
1107                 default:
1108                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1109                                         "Data (%d bytes)", mylen);
1110                     break;
1111                 }
1112                 break;
1113
1114             case LMP_09_CLASS_LINK_ID:
1115                 switch(type) {
1116                 case 1:
1117                 case 2:
1118                     l = (type == 1)? LMPF_VAL_LOCAL_LINK_ID_IPV4:
1119                         LMPF_VAL_REMOTE_LINK_ID_IPV4;
1120                     proto_item_append_text(ti, ": IPv4 %s",
1121                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1122                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1123                                         FALSE);
1124                     break;
1125                 case 3:
1126                 case 4:
1127                     l = (type == 3)? LMPF_VAL_LOCAL_LINK_ID_IPV6:
1128                         LMPF_VAL_REMOTE_LINK_ID_IPV6;
1129                     proto_item_append_text(ti, ": IPv6 %s",
1130                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1131                     proto_tree_add_text(lmp_object_tree, tvb, offset2, 16, "IPv6: %s",
1132                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1133                     break;
1134                 case 5:
1135                 case 6:
1136                     l = (type == 5)? LMPF_VAL_LOCAL_LINK_ID_UNNUM:
1137                         LMPF_VAL_REMOTE_LINK_ID_UNNUM;
1138                     proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2));
1139                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1140                                         FALSE);
1141                     break;
1142
1143                 default:
1144                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1145                                         "Data (%d bytes)", mylen);
1146                     break;
1147                 }
1148                 break;
1149
1150             case LMP_09_CLASS_INTERFACE_ID:
1151                 switch(type) {
1152                 case 1:
1153                 case 2:
1154                     l = (type == 1)? LMPF_VAL_LOCAL_INTERFACE_ID_IPV4:
1155                         LMPF_VAL_REMOTE_INTERFACE_ID_IPV4;
1156                     proto_item_append_text(ti, ": IPv4 %s",
1157                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1158                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1159                                         FALSE);
1160                     break;
1161                 case 3:
1162                 case 4:
1163                     l = (type == 3)? LMPF_VAL_LOCAL_INTERFACE_ID_IPV6:
1164                         LMPF_VAL_REMOTE_INTERFACE_ID_IPV6;
1165                     proto_item_append_text(ti, ": IPv6 %s",
1166                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1167                     proto_tree_add_text(lmp_object_tree, tvb, offset2, 16, "IPv6: %s",
1168                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1169                     break;
1170                 case 5:
1171                 case 6:
1172                     l = (type == 5)? LMPF_VAL_LOCAL_INTERFACE_ID_UNNUM:
1173                         LMPF_VAL_REMOTE_INTERFACE_ID_UNNUM;
1174                     proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2));
1175                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1176                                         FALSE);
1177                     break;
1178                 default:
1179                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1180                                         "Data (%d bytes)", mylen);
1181                     break;
1182                 }
1183                 break;
1184
1185             case LMP_09_CLASS_MESSAGE_ID:
1186                 switch(type) {
1187                 case 1:
1188                     l = LMPF_VAL_MESSAGE_ID;
1189                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1190                     proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1191                                         tvb_get_ntohl(tvb, offset2));
1192                     break;
1193                 case 2:
1194                     l = LMPF_VAL_MESSAGE_ID_ACK;
1195                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1196                     proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1197                                         tvb_get_ntohl(tvb, offset2));
1198                     break;
1199
1200                 default:
1201                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1202                                         "Data (%d bytes)", mylen);
1203                     break;
1204                 }
1205                 break;
1206
1207             case LMP_09_CLASS_CONFIG:
1208                 switch(type) {
1209                 case 1:
1210                     proto_item_append_text(ti, ": HelloInterval: %d, HelloDeadInterval: %d",
1211                                            tvb_get_ntohs(tvb, offset2), tvb_get_ntohs(tvb, offset2+2));
1212                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_CONFIG_HELLO],
1213                                         tvb, offset2, 2, tvb_get_ntohs(tvb, offset2));
1214                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_CONFIG_HELLO_DEAD],
1215                                         tvb, offset2+2, 2, tvb_get_ntohs(tvb, offset2+2));
1216                     break;
1217                 default:
1218                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1219                                         "Data (%d bytes)", mylen);
1220                     break;
1221                 }
1222                 break;
1223
1224             case LMP_09_CLASS_HELLO:
1225                 switch(type) {
1226                 case 1:
1227                     proto_item_append_text(ti, ": TxSeq %d, RxSeq: %d",
1228                                            tvb_get_ntohl(tvb, offset2),
1229                                            tvb_get_ntohl(tvb, offset2+4));
1230                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_HELLO_TXSEQ],
1231                                         tvb, offset2, 4, tvb_get_ntohl(tvb, offset2));
1232                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_HELLO_RXSEQ],
1233                                         tvb, offset2+4, 4, tvb_get_ntohl(tvb, offset2+4));
1234                     break;
1235                 default:
1236                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1237                                         "Data (%d bytes)", mylen);
1238                     break;
1239                 }
1240                 break;
1241
1242             case LMP_09_CLASS_BEGIN_VERIFY:
1243                 switch(type) {
1244                 case 1:
1245                     l = tvb_get_ntohs(tvb, offset2);
1246                     ti2 = proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS],
1247                                               tvb, offset2, 2, FALSE);
1248
1249                     lmp_flags_tree = proto_item_add_subtree(ti2, lmp_09_subtree[LMP_TREE_BEGIN_VERIFY_FLAGS]);
1250                     proto_tree_add_boolean(lmp_flags_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_ALL_LINKS],
1251                                            tvb, offset2, 2, l);
1252                     proto_tree_add_boolean(lmp_flags_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_LINK_TYPE],
1253                                            tvb, offset2, 2, l);
1254                     proto_tree_add_text(lmp_object_tree, tvb, offset2+2, 2,
1255                                         "Verify Interval: %d ms", tvb_get_ntohs(tvb, offset2+2));
1256                     proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 4,
1257                                         "Number of Data Links: %d", tvb_get_ntohl(tvb, offset2+4));
1258                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_ENCTYPE],
1259                                         tvb, offset2+8, 1, FALSE);
1260                     proto_tree_add_text(lmp_object_tree, tvb, offset2+10, 2,
1261                                         "Verify Transport Mechanism: 0x%0x", tvb_get_ntohs(tvb, offset2+10));
1262                     proto_tree_add_text(lmp_object_tree, tvb, offset2+12, 4,
1263                                         "Transmission Rate: %.10g", tvb_get_ntohieee_float(tvb, offset2+12));
1264                     proto_tree_add_text(lmp_object_tree, tvb, offset2+16, 4,
1265                                         "Wavelength: %d", tvb_get_ntohl(tvb, offset2+16));
1266                     break;
1267                 default:
1268                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1269                                         "Data (%d bytes)", mylen);
1270                     break;
1271                 }
1272                 break;
1273
1274             case LMP_09_CLASS_BEGIN_VERIFY_ACK:
1275                 switch(type) {
1276                 case 1:
1277                     proto_item_append_text(ti, ": VerifyDeadInterval: %d, TransportResponse: 0x%0x",
1278                                            tvb_get_ntohs(tvb, offset2), tvb_get_ntohs(tvb, offset2+2));
1279                     proto_tree_add_text(lmp_object_tree, tvb, offset2, 2,
1280                                         "VerifyDeadInterval: %d ms", tvb_get_ntohs(tvb, offset2));
1281                     proto_tree_add_text(lmp_object_tree, tvb, offset2+2, 2,
1282                                         "Verify Transport Response: 0x%0x", tvb_get_ntohs(tvb, offset2+2));
1283                     break;
1284                 default:
1285                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1286                                         "Data (%d bytes)", mylen);
1287                     break;
1288                 }
1289                 break;
1290
1291             case LMP_09_CLASS_VERIFY_ID:
1292                 switch(type) {
1293                 case 1:
1294                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1295                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_VERIFY_ID], tvb, offset2, 4,
1296                                         tvb_get_ntohl(tvb, offset2));
1297                     break;
1298                 default:
1299                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1300                                         "Data (%d bytes)", mylen);
1301                     break;
1302                 }
1303                 break;
1304
1305             case LMP_09_CLASS_TE_LINK:
1306                 l = tvb_get_guint8(tvb, offset2);
1307                 ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_FLAGS],
1308                                           tvb, offset2, 1, l);
1309                 proto_item_append_text(ti2, ": %s%s",
1310                                        (l&0x01) ? "Fault-Mgmt-Supported " : "",
1311                                        (l&0x02) ? "Link-Verification-Supported " : "");
1312                 lmp_flags_tree = proto_item_add_subtree(ti2, lmp_09_subtree[LMP_TREE_TE_LINK_FLAGS]);
1313                 proto_tree_add_boolean(lmp_flags_tree,
1314                                        lmp_filter[LMPF_VAL_TE_LINK_FLAGS_FAULT_MGMT],
1315                                        tvb, offset2, 1, l);
1316                 proto_tree_add_boolean(lmp_flags_tree,
1317                                        lmp_filter[LMPF_VAL_TE_LINK_FLAGS_LINK_VERIFY],
1318                                        tvb, offset2, 1, l);
1319                 switch(type) {
1320                 case 1:
1321                     proto_item_append_text(ti, ": IPv4: Local %s, Remote %s",
1322                                            ip_to_str(tvb_get_ptr(tvb, offset2+4, 4)),
1323                                            ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
1324                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_LOCAL_IPV4],
1325                                         tvb, offset2+4, 4, FALSE);
1326                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_REMOTE_IPV4],
1327                                         tvb, offset2+8, 4, FALSE);
1328                     break;
1329                 case 2:
1330                     proto_item_append_text(ti, ": IPv6: Local %s, Remote %s",
1331                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)),
1332                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+8, 16)));
1333                     proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 16, "TE-Link Local ID - IPv6: %s",
1334                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1335                     proto_tree_add_text(lmp_object_tree, tvb, offset2+20,16, "TE-Link Remote ID - IPv6: %s",
1336                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)));
1337                     break;
1338                 case 3:
1339                     proto_item_append_text(ti, ": Unnumbered: Local %d, Remote %d",
1340                                            tvb_get_ntohl(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8));
1341                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_LOCAL_UNNUM],
1342                                         tvb, offset2+4, 4, FALSE);
1343                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_REMOTE_UNNUM],
1344                                         tvb, offset2+8, 4, FALSE);
1345                     break;
1346                 default:
1347                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1348                                         "Data (%d bytes)", mylen);
1349                     break;
1350                 }
1351                 break;
1352
1353             case LMP_09_CLASS_DATA_LINK:
1354                 l = tvb_get_guint8(tvb, offset2);
1355                 ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_FLAGS],
1356                                           tvb, offset2, 1, l);
1357                 proto_item_append_text(ti2, ": %s%s",
1358                                        (l&0x01) ? "Interface-Type-Port " : "Interface-Type-Component-Link ",
1359                                        (l&0x02) ? "Allocated " : "Unallocated ");
1360                 lmp_flags_tree = proto_item_add_subtree(ti2, lmp_09_subtree[LMP_TREE_DATA_LINK_FLAGS]);
1361                 proto_tree_add_boolean(lmp_flags_tree,
1362                                        lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_PORT],
1363                                        tvb, offset2, 1, l);
1364                 proto_tree_add_boolean(lmp_flags_tree,
1365                                        lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_ALLOCATED],
1366                                        tvb, offset2, 1, l);
1367                 switch(type) {
1368                 case 1:
1369                     proto_item_append_text(ti, ": IPv4: Local %s, Remote %s",
1370                                            ip_to_str(tvb_get_ptr(tvb, offset2+4, 4)),
1371                                            ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
1372                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_IPV4],
1373                                         tvb, offset2+4, 4, FALSE);
1374                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_IPV4],
1375                                         tvb, offset2+8, 4, FALSE);
1376                     l = 12;
1377                     break;
1378                 case 2:
1379                     proto_item_append_text(ti, ": IPv6: Local %s, Remote %s",
1380                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)),
1381                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+8, 16)));
1382                     proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 16,
1383                                         "Data-Link Local ID - IPv6: %s",
1384                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1385                     proto_tree_add_text(lmp_object_tree, tvb, offset2+20,16,
1386                                         "Data-Link Remote ID - IPv6: %s",
1387                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)));
1388                     l = 36;
1389                     break;
1390                 case 3:
1391                     proto_item_append_text(ti, ": Unnumbered: Local %d, Remote %d",
1392                                            tvb_get_ntohl(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8));
1393                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_UNNUM],
1394                                         tvb, offset2+4, 4, FALSE);
1395                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_UNNUM],
1396                                         tvb, offset2+8, 4, FALSE);
1397                     l = 12;
1398                     break;
1399                 default:
1400                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1401                                         "Data (%d bytes)", mylen);
1402                     break;
1403                 }
1404
1405                 while (l < obj_length - 4) {
1406                     mylen = tvb_get_guint8(tvb, offset2+l+1);
1407                     ti2 = proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ],
1408                                               tvb, offset2+l, mylen, FALSE);
1409                     lmp_subobj_tree = proto_item_add_subtree(ti2, lmp_09_subtree[LMP_TREE_DATA_LINK_SUBOBJ]);
1410                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 1,
1411                                         "Subobject Type: %d", tvb_get_guint8(tvb, offset2+l));
1412                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+1, 1,
1413                                         "Subobject Length: %d", mylen);
1414                     switch(tvb_get_guint8(tvb, offset2+l)) {
1415                     case 1:
1416                         proto_item_set_text(ti2, "Interface Switching Capability: "
1417                                             "Switching Cap: %s, Encoding Type: %s, Min BW: %.10g, Max BW: %.10g",
1418                                             val_to_str(tvb_get_guint8(tvb, offset2+l+2),
1419                                                        gmpls_switching_type_str, "Unknown (%d)"),
1420                                             val_to_str(tvb_get_guint8(tvb, offset2+l+3),
1421                                                        gmpls_lsp_enc_str, "Unknown (%d)"),
1422                                             tvb_get_ntohieee_float(tvb, offset2+l+4),
1423                                             tvb_get_ntohieee_float(tvb, offset2+l+8));
1424                         proto_tree_add_item(lmp_subobj_tree,
1425                                             lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_SWITCHING_TYPE],
1426                                             tvb, offset2+l+2, 1, FALSE);
1427                         proto_tree_add_item(lmp_subobj_tree,
1428                                             lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_LSP_ENCODING],
1429                                             tvb, offset2+l+3, 1, FALSE);
1430                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+4, 4,
1431                                             "Minimum Reservable Bandwidth: %.10g bytes/s",
1432                                             tvb_get_ntohieee_float(tvb, offset2+l+4));
1433                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+8, 4,
1434                                             "Maximum Reservable Bandwidth: %.10g bytes/s",
1435                                             tvb_get_ntohieee_float(tvb, offset2+l+8));
1436                         break;
1437
1438                     case 2:
1439                         proto_item_set_text(ti2, "Wavelength: %d",
1440                                             tvb_get_ntohl(tvb, offset2+l+2));
1441                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+4, 4,
1442                                             "Wavelength: %d",
1443                                             tvb_get_ntohl(tvb, offset2+l+4));
1444                         break;
1445
1446                     default:
1447                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l,
1448                                             tvb_get_guint8(tvb, offset2+l+1),
1449                                             "Data (%d bytes)", tvb_get_guint8(tvb, offset2+l+1));
1450                         break;
1451                     }
1452                     l += tvb_get_guint8(tvb, offset2+l+1);
1453                 }
1454
1455                 break;
1456
1457             case LMP_09_CLASS_CHANNEL_STATUS:
1458                 k = 0; j = 0;
1459                 switch(type) {
1460                 case 1:
1461                 case 3:
1462                     k = 8; break;
1463                 case 2:
1464                     k = 20; break;
1465                 }
1466                 if (!k)
1467                     break;
1468                 for (l=0; l<obj_length - 4; ) {
1469                     ti2 = proto_tree_add_text(lmp_object_tree, tvb, offset2+l, k,
1470                                               "Interface-Id");
1471                     lmp_subobj_tree = proto_item_add_subtree(ti2, lmp_09_subtree[LMP_TREE_CHANNEL_STATUS_ID]);
1472                     switch(type) {
1473                     case 1:
1474                         if (j < 4)
1475                             proto_item_append_text(ti, ": [IPv4-%s",
1476                                                    ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
1477                         proto_item_append_text(ti2, ": IPv4 %s",
1478                                                ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
1479                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
1480                                             "Interface ID: IPv4: %s",
1481                                             ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
1482                         l += 4;
1483                         break;
1484                     case 2:
1485                         if (j < 4)
1486                             proto_item_append_text(ti, ": [IPv6-%s",
1487                                                    ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
1488                         proto_item_append_text(ti2, ": IPv6 %s",
1489                                                ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
1490                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2, 16, "Interface ID: IPv6: %s",
1491                                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
1492                         l += 16;
1493                         break;
1494                     case 3:
1495                         if (j < 4)
1496                             proto_item_append_text(ti, ": [Unnum-%d", tvb_get_ntohl(tvb, offset2+l));
1497                         proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2+l));
1498                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
1499                                             "Interface ID: Unnumbered: %d",
1500                                             tvb_get_ntohl(tvb, offset2+l));
1501                         l += 4;
1502                         break;
1503                     default:
1504                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, obj_length-4-l,
1505                                             "Data (%d bytes)", obj_length-4-l);
1506                         l = obj_length - 4;
1507                         break;
1508                     }
1509                     if (l == obj_length - 4) break;
1510
1511                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 1,
1512                                         tvb_get_guint8(tvb, offset2+l) & 0x80 ?
1513                                         "Link Allocated - Active Monitoring" :
1514                                         "Link Not Allocated");
1515                     if (j < 4)
1516                         proto_item_append_text(ti, "-%s,%s], ",
1517                                                tvb_get_guint8(tvb, offset2+l) & 0x80 ? "Act" : "NA",
1518                                                val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
1519                                                           channel_status_short_str, "UNK (%u)."));
1520                     proto_item_append_text(ti2, ": %s, ",
1521                                            tvb_get_guint8(tvb, offset2+l) & 0x80 ? "Active" : "Not Active");
1522                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
1523                                         "Channel Status: %s",
1524                                         val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
1525                                                    channel_status_str, "Unknown (%u). "));
1526                     proto_item_append_text(ti2, val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
1527                                                            channel_status_str, "Unknown (%u). "));
1528                     j++;
1529                     l += 4;
1530                     if (j==4 && l < obj_length - 4)
1531                         proto_item_append_text(ti, " ...");
1532                 }
1533                 break;
1534
1535             case LMP_09_CLASS_CHANNEL_STATUS_REQUEST:
1536                 for (l=0; l<obj_length - 4; ) {
1537                     switch(type) {
1538                     case 1:
1539                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 4,
1540                                             "Interface ID: IPv4: %s",
1541                                             ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
1542                         l += 4;
1543                         break;
1544                     case 2:
1545                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 16, "Interface ID: IPv6: %s",
1546                                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l,16)));
1547                         l += 16;
1548                         break;
1549                     case 3:
1550                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 4,
1551                                             "Interface ID: Unnumbered: %d",
1552                                             tvb_get_ntohl(tvb, offset2+l));
1553                         l += 4;
1554                         break;
1555                     default:
1556                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, obj_length-4-l,
1557                                             "Data (%d bytes)", obj_length-4-l);
1558                         l = obj_length - 4;
1559                         break;
1560                     }
1561                 }
1562                 break;
1563
1564             case LMP_09_CLASS_ERROR:
1565                 l = tvb_get_ntohl(tvb, offset2);
1566                 ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_ERROR],
1567                                           tvb, offset2, 4, l);
1568
1569                 switch(type) {
1570                 case 1:
1571                         proto_item_append_text(ti, ": BEGIN_VERIFY_ERROR: %s%s%s%s",
1572                                                (l&0x01) ? "Unsupported-Link " : "",
1573                                                (l&0x02) ? "Unwilling" : "",
1574                                                (l&0x04) ? "Unsupported-Transport" : "",
1575                                                (l&0x08) ? "TE-Link-ID" : "");
1576                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_09_subtree[LMP_TREE_ERROR_FLAGS]);
1577                         proto_tree_add_boolean(lmp_flags_tree,
1578                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_UNSUPPORTED_LINK],
1579                                                tvb, offset, 4, l);
1580                         proto_tree_add_boolean(lmp_flags_tree,
1581                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_UNWILLING],
1582                                                tvb, offset, 4, l);
1583                         proto_tree_add_boolean(lmp_flags_tree,
1584                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_TRANSPORT],
1585                                                tvb, offset, 4, l);
1586                         proto_tree_add_boolean(lmp_flags_tree,
1587                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_TE_LINK_ID],
1588                                                tvb, offset, 4, l);
1589                         break;
1590                 case 2:
1591                         proto_item_append_text(ti, ": LINK_SUMMARY_ERROR: %s%s%s%s%s%s",
1592                                                (l&0x01) ? "Unacceptable-Params " : "",
1593                                                (l&0x02) ? "Renegotiate" : "",
1594                                                (l&0x04) ? "Bad-TE-Link" : "",
1595                                                (l&0x08) ? "Bad-Data-Link" : "",
1596                                                (l&0x10) ? "Bad-TE-Link-CType" : "",
1597                                                (l&0x20) ? "Bad-Data-Link-CType" : "");
1598                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_09_subtree[LMP_TREE_ERROR_FLAGS]);
1599                         proto_tree_add_boolean(lmp_flags_tree,
1600                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_PARAMETERS],
1601                                                tvb, offset, 4, l);
1602                         proto_tree_add_boolean(lmp_flags_tree,
1603                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_RENEGOTIATE],
1604                                                tvb, offset, 4, l);
1605                         proto_tree_add_boolean(lmp_flags_tree,
1606                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_TE_LINK],
1607                                                tvb, offset, 4, l);
1608                         proto_tree_add_boolean(lmp_flags_tree,
1609                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_DATA_LINK],
1610                                                tvb, offset, 4, l);
1611                         proto_tree_add_boolean(lmp_flags_tree,
1612                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_UNKNOWN_TEL_CTYPE],
1613                                                tvb, offset, 4, l);
1614                         proto_tree_add_boolean(lmp_flags_tree,
1615                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_UNKNOWN_DL_CTYPE],
1616                                                tvb, offset, 4, l);
1617                         break;
1618                 default:
1619                         proto_item_append_text(ti, ": UNKNOWN_ERROR (%d): 0x%04x", type, l);
1620                         proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1621                                             "Data (%d bytes)", mylen);
1622                         break;
1623                 }
1624                 break;
1625                 
1626             default:
1627                 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1628                                             "Data (%d bytes)", mylen);
1629                 break;
1630             }
1631           } else {
1632             /* LMP 03 or LMP 02 */
1633             switch (class) {
1634             case LMP_CLASS_NULL:
1635                 break;
1636
1637             case LMP_CLASS_LOCAL_CCID:
1638             case LMP_CLASS_REMOTE_CCID:
1639                 switch(type) {
1640                 case 1:
1641                     l = (class == LMP_CLASS_LOCAL_CCID) ?
1642                         LMPF_VAL_LOCAL_CCID : LMPF_VAL_REMOTE_CCID;
1643                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1644                     proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1645                                         tvb_get_ntohl(tvb, offset2));
1646                     break;
1647                 default:
1648                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1649                                         "Data (%d bytes)", mylen);
1650                     break;
1651                 }
1652                 break;
1653
1654             case LMP_CLASS_LOCAL_NODE_ID:
1655             case LMP_CLASS_REMOTE_NODE_ID:
1656                 switch(type) {
1657                 case 1:
1658                     l = (class == LMP_CLASS_LOCAL_NODE_ID) ?
1659                         LMPF_VAL_LOCAL_NODE_ID : LMPF_VAL_REMOTE_NODE_ID;
1660                     proto_item_append_text(ti, ": %s",
1661                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1662                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1663                                         FALSE);
1664                     break;
1665                 default:
1666                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1667                                         "Data (%d bytes)", mylen);
1668                     break;
1669                 }
1670                 break;
1671
1672             case LMP_CLASS_LOCAL_LINK_ID:
1673             case LMP_CLASS_REMOTE_LINK_ID:
1674                 switch(type) {
1675                 case 1:
1676                     l = (class == LMP_CLASS_LOCAL_LINK_ID) ?
1677                         LMPF_VAL_LOCAL_LINK_ID_IPV4 : LMPF_VAL_REMOTE_LINK_ID_IPV4;
1678                     proto_item_append_text(ti, ": IPv4 %s",
1679                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1680                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1681                                         FALSE);
1682                     break;
1683                 case 2:
1684                     proto_item_append_text(ti, ": IPv6 %s",
1685                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1686                     proto_tree_add_text(lmp_object_tree, tvb, offset2, 16, "IPv6: %s",
1687                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1688                     break;
1689                 case 3:
1690                     l = (class == LMP_CLASS_LOCAL_LINK_ID) ?
1691                         LMPF_VAL_LOCAL_LINK_ID_UNNUM : LMPF_VAL_REMOTE_LINK_ID_UNNUM;
1692                     proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2));
1693                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1694                                         FALSE);
1695                     break;
1696                 default:
1697                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1698                                         "Data (%d bytes)", mylen);
1699                     break;
1700                 }
1701                 break;
1702
1703             case LMP_CLASS_LOCAL_INTERFACE_ID:
1704             case LMP_CLASS_REMOTE_INTERFACE_ID:
1705                 switch(type) {
1706                 case 1:
1707                     l = (class == LMP_CLASS_LOCAL_INTERFACE_ID) ?
1708                         LMPF_VAL_LOCAL_INTERFACE_ID_IPV4 : LMPF_VAL_REMOTE_INTERFACE_ID_IPV4;
1709                     proto_item_append_text(ti, ": IPv4 %s",
1710                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1711                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1712                                         FALSE);
1713                     break;
1714                 case 2:
1715                     proto_item_append_text(ti, ": IPv6 %s",
1716                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1717                     proto_tree_add_text(lmp_object_tree, tvb, offset2, 16, "IPv6: %s",
1718                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1719                     break;
1720                 case 3:
1721                     l = (class == LMP_CLASS_LOCAL_INTERFACE_ID) ?
1722                         LMPF_VAL_LOCAL_INTERFACE_ID_UNNUM : LMPF_VAL_REMOTE_INTERFACE_ID_UNNUM;
1723                     proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2));
1724                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1725                                         FALSE);
1726                     break;
1727                 default:
1728                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1729                                         "Data (%d bytes)", mylen);
1730                     break;
1731                 }
1732                 break;
1733
1734             case LMP_CLASS_MESSAGE_ID:
1735             case LMP_CLASS_MESSAGE_ID_ACK:
1736                 switch(type) {
1737                 case 1:
1738                     l = (class == LMP_CLASS_MESSAGE_ID) ?
1739                         LMPF_VAL_MESSAGE_ID : LMPF_VAL_MESSAGE_ID_ACK;
1740                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1741                     proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1742                                         tvb_get_ntohl(tvb, offset2));
1743                     break;
1744                 default:
1745                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1746                                         "Data (%d bytes)", mylen);
1747                     break;
1748                 }
1749                 break;
1750
1751             case LMP_CLASS_CONFIG:
1752                 switch(type) {
1753                 case 1:
1754                     proto_item_append_text(ti, ": HelloInterval: %d, HelloDeadInterval: %d",
1755                                            tvb_get_ntohs(tvb, offset2), tvb_get_ntohs(tvb, offset2+2));
1756                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_CONFIG_HELLO],
1757                                         tvb, offset2, 2, tvb_get_ntohs(tvb, offset2));
1758                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_CONFIG_HELLO_DEAD],
1759                                         tvb, offset2+2, 2, tvb_get_ntohs(tvb, offset2+2));
1760                     break;
1761                 default:
1762                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1763                                         "Data (%d bytes)", mylen);
1764                     break;
1765                 }
1766                 break;
1767
1768             case LMP_CLASS_HELLO:
1769                 switch(type) {
1770                 case 1:
1771                     proto_item_append_text(ti, ": TxSeq %d, RxSeq: %d",
1772                                            tvb_get_ntohl(tvb, offset2),
1773                                            tvb_get_ntohl(tvb, offset2+4));
1774                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_HELLO_TXSEQ],
1775                                         tvb, offset2, 4, tvb_get_ntohl(tvb, offset2));
1776                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_HELLO_RXSEQ],
1777                                         tvb, offset2+4, 4, tvb_get_ntohl(tvb, offset2+4));
1778                     break;
1779                 default:
1780                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1781                                         "Data (%d bytes)", mylen);
1782                     break;
1783                 }
1784                 break;
1785             case LMP_CLASS_BEGIN_VERIFY:
1786                 switch(type) {
1787                 case 1:
1788                     l = tvb_get_ntohs(tvb, offset2);
1789                     ti2 = proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS],
1790                                               tvb, offset2, 2, FALSE);
1791                         
1792                     lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_BEGIN_VERIFY_FLAGS]);
1793                     proto_tree_add_boolean(lmp_flags_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_ALL_LINKS],
1794                                            tvb, offset2, 2, l);
1795                     proto_tree_add_boolean(lmp_flags_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_LINK_TYPE],
1796                                            tvb, offset2, 2, l);
1797                     proto_tree_add_text(lmp_object_tree, tvb, offset2+2, 2,
1798                                         "Verify Interval: %d ms", tvb_get_ntohs(tvb, offset2+2));
1799                     proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 4,
1800                                         "Number of Data Links: %d", tvb_get_ntohl(tvb, offset2+4));
1801                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_ENCTYPE],
1802                                         tvb, offset2+8, 1, FALSE);
1803                     proto_tree_add_text(lmp_object_tree, tvb, offset2+10, 2,
1804                                         "Verify Transport Mechanism: 0x%0x", tvb_get_ntohs(tvb, offset2+10));
1805                     proto_tree_add_text(lmp_object_tree, tvb, offset2+12, 4,
1806                                         "Transmission Rate: %.10g", tvb_get_ntohieee_float(tvb, offset2+12));
1807                     proto_tree_add_text(lmp_object_tree, tvb, offset2+16, 4,
1808                                         "Wavelength: %d", tvb_get_ntohl(tvb, offset2+16));
1809                     break;
1810                 default:
1811                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1812                                         "Data (%d bytes)", mylen);
1813                     break;
1814                 }
1815                 break;
1816
1817             case LMP_CLASS_BEGIN_VERIFY_ACK:
1818                 switch(type) {
1819                 case 1:
1820                     proto_item_append_text(ti, ": VerifyDeadInterval: %d, TransportResponse: 0x%0x",
1821                                            tvb_get_ntohs(tvb, offset2), tvb_get_ntohs(tvb, offset2+2));
1822                     proto_tree_add_text(lmp_object_tree, tvb, offset2, 2,
1823                                         "VerifyDeadInterval: %d ms", tvb_get_ntohs(tvb, offset2));
1824                     proto_tree_add_text(lmp_object_tree, tvb, offset2+2, 2,
1825                                         "Verify Transport Response: 0x%0x", tvb_get_ntohs(tvb, offset2+2));
1826                     break;
1827                 default:
1828                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1829                                         "Data (%d bytes)", mylen);
1830                     break;
1831                 }
1832                 break;
1833
1834             case LMP_CLASS_VERIFY_ID:
1835                 switch(type) {
1836                 case 1:
1837                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1838                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_VERIFY_ID], tvb, offset2, 4,
1839                                         tvb_get_ntohl(tvb, offset2));
1840                     break;
1841                 default:
1842                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1843                                         "Data (%d bytes)", mylen);
1844                     break;
1845                 }
1846                 break;
1847
1848             case LMP_CLASS_TE_LINK:
1849                 l = tvb_get_guint8(tvb, offset2);
1850                 ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_FLAGS],
1851                                           tvb, offset2, 1, l);
1852                 proto_item_append_text(ti2, ": %s%s",
1853                                        (l&0x01) ? "Fault-Mgmt-Supported " : "",
1854                                        (l&0x02) ? "Link-Verification-Supported " : "");
1855                 lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_TE_LINK_FLAGS]);
1856                 proto_tree_add_boolean(lmp_flags_tree,
1857                                        lmp_filter[LMPF_VAL_TE_LINK_FLAGS_FAULT_MGMT],
1858                                        tvb, offset2, 1, l);
1859                 proto_tree_add_boolean(lmp_flags_tree,
1860                                        lmp_filter[LMPF_VAL_TE_LINK_FLAGS_LINK_VERIFY],
1861                                        tvb, offset2, 1, l);
1862                 switch(type) {
1863                 case 1:
1864                     proto_item_append_text(ti, ": IPv4: Local %s, Remote %s",
1865                                            ip_to_str(tvb_get_ptr(tvb, offset2+4, 4)),
1866                                            ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
1867                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_LOCAL_IPV4],
1868                                         tvb, offset2+4, 4, FALSE);
1869                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_REMOTE_IPV4],
1870                                         tvb, offset2+8, 4, FALSE);
1871                     break;
1872                 case 2:
1873                     proto_item_append_text(ti, ": IPv6: Local %s, Remote %s",
1874                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)),
1875                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+8, 16)));
1876                     proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 16, "TE-Link Local ID - IPv6: %s",
1877                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1878                     proto_tree_add_text(lmp_object_tree, tvb, offset2+20,16, "TE-Link Remote ID - IPv6: %s",
1879                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)));
1880                     break;
1881                 case 3:
1882                     proto_item_append_text(ti, ": Unnumbered: Local %d, Remote %d",
1883                                            tvb_get_ntohl(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8));
1884                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_LOCAL_UNNUM],
1885                                         tvb, offset2+4, 4, FALSE);
1886                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_REMOTE_UNNUM],
1887                                         tvb, offset2+8, 4, FALSE);
1888                     break;
1889                 default:
1890                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1891                                         "Data (%d bytes)", mylen);
1892                     break;
1893                 }
1894                 break;
1895
1896             case LMP_CLASS_DATA_LINK:
1897                 l = tvb_get_guint8(tvb, offset2);
1898                 ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_FLAGS],
1899                                           tvb, offset2, 1, l);
1900                 proto_item_append_text(ti2, ": %s%s",
1901                                        (l&0x01) ? "Interface-Type-Port " : "Interface-Type-Component-Link ",
1902                                        (l&0x02) ? "Allocated " : "Unallocated ");
1903                 lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_DATA_LINK_FLAGS]);
1904                 proto_tree_add_boolean(lmp_flags_tree,
1905                                        lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_PORT],
1906                                        tvb, offset2, 1, l);
1907                 proto_tree_add_boolean(lmp_flags_tree,
1908                                        lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_ALLOCATED],
1909                                        tvb, offset2, 1, l);
1910                 switch(type) {
1911                 case 1:
1912                     proto_item_append_text(ti, ": IPv4: Local %s, Remote %s",
1913                                            ip_to_str(tvb_get_ptr(tvb, offset2+4, 4)),
1914                                            ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
1915                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_IPV4],
1916                                         tvb, offset2+4, 4, FALSE);
1917                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_IPV4],
1918                                         tvb, offset2+8, 4, FALSE);
1919                     l = 12;
1920                     break;
1921                 case 2:
1922                     proto_item_append_text(ti, ": IPv6: Local %s, Remote %s",
1923                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)),
1924                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+8, 16)));
1925                     proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 16,
1926                                         "Data-Link Local ID - IPv6: %s",
1927                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1928                     proto_tree_add_text(lmp_object_tree, tvb, offset2+20,16,
1929                                         "Data-Link Remote ID - IPv6: %s",
1930                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)));
1931                     l = 36;
1932                     break;
1933                 case 3:
1934                     proto_item_append_text(ti, ": Unnumbered: Local %d, Remote %d",
1935                                            tvb_get_ntohl(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8));
1936                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_UNNUM],
1937                                         tvb, offset2+4, 4, FALSE);
1938                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_UNNUM],
1939                                         tvb, offset2+8, 4, FALSE);
1940                     l = 12;
1941                     break;
1942                 default:
1943                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1944                                         "Data (%d bytes)", mylen);
1945                     break;
1946                 }
1947
1948                 while (l < obj_length - 4) {
1949                     mylen = tvb_get_guint8(tvb, offset2+l+1);
1950                     ti2 = proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ],
1951                                               tvb, offset2+l, mylen, FALSE);
1952                     lmp_subobj_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_DATA_LINK_SUBOBJ]);
1953                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 1,
1954                                         "Subobject Type: %d", tvb_get_guint8(tvb, offset2+l));
1955                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+1, 1,
1956                                         "Subobject Length: %d", mylen);
1957                     switch(tvb_get_guint8(tvb, offset2+l)) {
1958                     case 1:
1959                         proto_item_set_text(ti2, "Interface Switching Capability: "
1960                                             "Switching Cap: %s, Encoding Type: %s, Min BW: %.10g, Max BW: %.10g",
1961                                             val_to_str(tvb_get_guint8(tvb, offset2+l+2),
1962                                                        gmpls_switching_type_str, "Unknown (%d)"),
1963                                             val_to_str(tvb_get_guint8(tvb, offset2+l+3),
1964                                                        gmpls_lsp_enc_str, "Unknown (%d)"),
1965                                             tvb_get_ntohieee_float(tvb, offset2+l+4),
1966                                             tvb_get_ntohieee_float(tvb, offset2+l+8));
1967                         proto_tree_add_item(lmp_subobj_tree,
1968                                             lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_SWITCHING_TYPE],
1969                                             tvb, offset2+l+2, 1, FALSE);
1970                         proto_tree_add_item(lmp_subobj_tree,
1971                                             lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_LSP_ENCODING],
1972                                             tvb, offset2+l+3, 1, FALSE);
1973                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+4, 4,
1974                                             "Minimum Reservable Bandwidth: %.10g bytes/s",
1975                                             tvb_get_ntohieee_float(tvb, offset2+l+4));
1976                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+8, 4,
1977                                             "Maximum Reservable Bandwidth: %.10g bytes/s",
1978                                             tvb_get_ntohieee_float(tvb, offset2+l+8));
1979                         break;
1980
1981                     case 2:
1982                         proto_item_set_text(ti2, "Wavelength: %d",
1983                                             tvb_get_ntohl(tvb, offset2+l+4));
1984                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+4, 4,
1985                                             "Wavelength: %d",
1986                                             tvb_get_ntohl(tvb, offset2+l+4));
1987                         break;
1988                             
1989                     default:
1990                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l,
1991                                             tvb_get_guint8(tvb, offset2+l+1),
1992                                             "Data (%d bytes)", tvb_get_guint8(tvb, offset2+l+1));
1993                         break;
1994                     }
1995                     l += tvb_get_guint8(tvb, offset2+l+1);
1996                 }
1997                 break;
1998
1999             case LMP_CLASS_CHANNEL_STATUS:
2000                 k = 0; j = 0;
2001                 switch(type) {
2002                 case 1:
2003                 case 3:
2004                     k = 8; break;
2005                 case 2:
2006                     k = 20; break;
2007                 }
2008                 if (!k)
2009                     break;
2010                 for (l=0; l<obj_length - 4; ) {
2011                     ti2 = proto_tree_add_text(lmp_object_tree, tvb, offset2+l, k,
2012                                               "Interface-Id");
2013                     lmp_subobj_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_CHANNEL_STATUS_ID]);
2014                     switch(type) {
2015                     case 1:
2016                         if (j < 4)
2017                             proto_item_append_text(ti, ": [IPv4-%s",
2018                                                    ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
2019                         proto_item_append_text(ti2, ": IPv4 %s",
2020                                                ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
2021                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
2022                                             "Interface ID: IPv4: %s",
2023                                             ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
2024                         l += 4;
2025                         break;
2026                     case 2:
2027                         if (j < 4)
2028                             proto_item_append_text(ti, ": [IPv6-%s",
2029                                                    ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
2030                         proto_item_append_text(ti2, ": IPv6 %s",
2031                                                ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
2032                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2, 16, "Interface ID: IPv6: %s",
2033                                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
2034                         l += 16;
2035                         break;
2036                     case 3:
2037                         if (j < 4)
2038                             proto_item_append_text(ti, ": [Unnum-%d", tvb_get_ntohl(tvb, offset2+l));
2039                         proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2+l));
2040                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
2041                                             "Interface ID: Unnumbered: %d",
2042                                             tvb_get_ntohl(tvb, offset2+l));
2043                         l += 4;
2044                         break;
2045                     default:
2046                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, obj_length-4-l,
2047                                             "Data (%d bytes)", obj_length-4-l);
2048                         l = obj_length - 4;
2049                         break;
2050                     }
2051                     if (l == obj_length - 4) break;
2052
2053                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 1,
2054                                         tvb_get_guint8(tvb, offset2+l) & 0x80 ?
2055                                         "Link Allocated - Active Monitoring" :
2056                                         "Link Not Allocated");
2057                     if (j < 4)
2058                         proto_item_append_text(ti, "-%s,%s], ",
2059                                                tvb_get_guint8(tvb, offset2+l) & 0x80 ? "Act" : "NA",
2060                                                val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
2061                                                           channel_status_short_str, "UNK (%u)."));
2062                     proto_item_append_text(ti2, ": %s, ",
2063                                            tvb_get_guint8(tvb, offset2+l) & 0x80 ? "Active" : "Not Active");
2064                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
2065                                         "Channel Status: %s",
2066                                         val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
2067                                                    channel_status_str, "Unknown (%u). "));
2068                     proto_item_append_text(ti2, val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
2069                                                            channel_status_str, "Unknown (%u). "));
2070                     j++;
2071                     l += 4;
2072                     if (j==4 && l < obj_length - 4)
2073                         proto_item_append_text(ti, " ...");
2074                 }
2075                 break;
2076
2077             case LMP_CLASS_CHANNEL_STATUS_REQUEST:
2078                 for (l=0; l<obj_length - 4; ) {
2079                     switch(type) {
2080                     case 1:
2081                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 4,
2082                                             "Interface ID: IPv4: %s",
2083                                             ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
2084                         l += 4;
2085                         break;
2086                     case 2:
2087                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 16, "Interface ID: IPv6: %s",
2088                                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l,16)));
2089                         l += 16;
2090                         break;
2091                     case 3:
2092                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 4,
2093                                             "Interface ID: Unnumbered: %d",
2094                                             tvb_get_ntohl(tvb, offset2+l));
2095                         l += 4;
2096                         break;
2097                     default:
2098                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, obj_length-4-l,
2099                                             "Data (%d bytes)", obj_length-4-l);
2100                         l = obj_length - 4;
2101                         break;
2102                     }
2103                 }
2104                 break;
2105
2106             case LMP_CLASS_ERROR:
2107                 l = tvb_get_ntohl(tvb, offset2);
2108                 ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_ERROR],
2109                                           tvb, offset2, 4, l);
2110
2111                 /* Errors are different in draft-02 and draft-03 */
2112                 switch(lmp_draft_ver) {
2113                 case LMP_VER_DRAFT_CCAMP_02:
2114                     switch(type) {
2115                     case 1:
2116                         proto_item_append_text(ti, ": CONFIG_ERROR: %s%s%s",
2117                                                (l&0x01) ? "Unacceptable-Params " : "",
2118                                                (l&0x02) ? "Renegotiate" : "",
2119                                                (l&0x04) ? "Bad Received CCID" : "");
2120                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
2121                         proto_tree_add_boolean(lmp_flags_tree,
2122                                                lmp_filter[LMPF_VAL_ERROR_CONFIG_BAD_PARAMETERS],
2123                                                tvb, offset, 4, l);
2124                         proto_tree_add_boolean(lmp_flags_tree,
2125                                                lmp_filter[LMPF_VAL_ERROR_CONFIG_RENEGOTIATE],
2126                                                tvb, offset, 4, l);
2127                         proto_tree_add_boolean(lmp_flags_tree,
2128                                                lmp_filter[LMPF_VAL_ERROR_CONFIG_BAD_CCID],
2129                                                tvb, offset, 4, l);
2130                         break;
2131                     case 2:
2132                         proto_item_append_text(ti, ": BEGIN_VERIFY_ERROR: %s%s%s%s",
2133                                                (l&0x01) ? "Unsupported-Link " : "",
2134                                                (l&0x02) ? "Unwilling" : "",
2135                                                (l&0x04) ? "Unsupported-Transport" : "",
2136                                                (l&0x08) ? "TE-Link-ID" : "");
2137                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
2138                         proto_tree_add_boolean(lmp_flags_tree,
2139                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_UNSUPPORTED_LINK],
2140                                                tvb, offset, 4, l);
2141                         proto_tree_add_boolean(lmp_flags_tree,
2142                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_UNWILLING],
2143                                                tvb, offset, 4, l);
2144                         proto_tree_add_boolean(lmp_flags_tree,
2145                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_TRANSPORT],
2146                                                tvb, offset, 4, l);
2147                         proto_tree_add_boolean(lmp_flags_tree,
2148                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_TE_LINK_ID],
2149                                                tvb, offset, 4, l);
2150                         break;
2151                     case 3:
2152                         proto_item_append_text(ti, ": LINK_SUMMARY_ERROR: %s%s%s",
2153                                                (l&0x01) ? "Unacceptable-Params " : "",
2154                                                (l&0x02) ? "Renegotiate" : "",
2155                                                (l&0x04) ? "Remote-Link-ID" : "");
2156
2157
2158                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
2159                         proto_tree_add_boolean(lmp_flags_tree,
2160                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_PARAMETERS],
2161                                                tvb, offset, 4, l);
2162                         proto_tree_add_boolean(lmp_flags_tree,
2163                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_RENEGOTIATE],
2164                                                tvb, offset, 4, l);
2165                         proto_tree_add_boolean(lmp_flags_tree,
2166                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_REMOTE_LINK_ID],
2167                                                tvb, offset, 4, l);
2168                         break;
2169
2170                     default:
2171                         proto_item_append_text(ti, ": UNKNOWN_ERROR (%d): 0x%04x", type, l);
2172                         proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
2173                                             "Data (%d bytes)", mylen);
2174                         break;
2175                     }
2176                     break;
2177                 default:
2178                 case LMP_VER_DRAFT_CCAMP_03:
2179                     switch(type) {
2180                     case 1:
2181                         proto_item_append_text(ti, ": BEGIN_VERIFY_ERROR: %s%s%s%s",
2182                                                (l&0x01) ? "Unsupported-Link " : "",
2183                                                (l&0x02) ? "Unwilling" : "",
2184                                                (l&0x04) ? "Unsupported-Transport" : "",
2185                                                (l&0x08) ? "TE-Link-ID" : "");
2186                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_09_subtree[LMP_TREE_ERROR_FLAGS]);
2187                         proto_tree_add_boolean(lmp_flags_tree,
2188                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_UNSUPPORTED_LINK],
2189                                                tvb, offset, 4, l);
2190                         proto_tree_add_boolean(lmp_flags_tree,
2191                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_UNWILLING],
2192                                                tvb, offset, 4, l);
2193                         proto_tree_add_boolean(lmp_flags_tree,
2194                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_TRANSPORT],
2195                                                tvb, offset, 4, l);
2196                         proto_tree_add_boolean(lmp_flags_tree,
2197                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_TE_LINK_ID],
2198                                                tvb, offset, 4, l);
2199                         break;
2200                     case 2:
2201                         proto_item_append_text(ti, ": LINK_SUMMARY_ERROR: %s%s%s%s%s",
2202                                                (l&0x01) ? "Unacceptable-Params " : "",
2203                                                (l&0x02) ? "Renegotiate" : "",
2204                                                (l&0x04) ? "Remote-Link-ID" : "",
2205                                                (l&0x08) ? "TE-Link" : "",
2206                                                (l&0x10) ? "Data-Link" : "");
2207
2208                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_09_subtree[LMP_TREE_ERROR_FLAGS]);
2209                         proto_tree_add_boolean(lmp_flags_tree,
2210                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_PARAMETERS],
2211                                                tvb, offset, 4, l);
2212                         proto_tree_add_boolean(lmp_flags_tree,
2213                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_RENEGOTIATE],
2214                                                tvb, offset, 4, l);
2215                         proto_tree_add_boolean(lmp_flags_tree,
2216                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_REMOTE_LINK_ID],
2217                                                tvb, offset, 4, l);
2218                         proto_tree_add_boolean(lmp_flags_tree,
2219                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_TE_LINK],
2220                                                tvb, offset, 4, l);
2221                         proto_tree_add_boolean(lmp_flags_tree,
2222                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_DATA_LINK],
2223                                                tvb, offset, 4, l);
2224                         break;
2225                     default:
2226                         proto_item_append_text(ti, ": UNKNOWN_ERROR (%d): 0x%04x", type, l);
2227                         proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
2228                                             "Data (%d bytes)", mylen);
2229                         break;
2230                     } /* switch type */
2231                     break;
2232                   } /* default case in ERROR object switch */
2233
2234               default:
2235                 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
2236                                     "Data (%d bytes)", mylen);
2237                 break;
2238             }
2239
2240           } /* LMP_VER_DRAFT_CCAMP_03 */
2241
2242           offset += obj_length;
2243           len += obj_length;
2244
2245         } /* while */
2246     } /* tree */
2247 }
2248
2249 static void
2250 lmp_prefs_applied (void)
2251 {
2252     if (lmp_udp_port != lmp_udp_port_config) {
2253         dissector_delete("udp.port", lmp_udp_port, lmp_handle);
2254         lmp_udp_port = lmp_udp_port_config;
2255         dissector_add("udp.port", lmp_udp_port, lmp_handle);
2256     }
2257 }    
2258
2259 static void
2260 register_lmp_prefs (void)
2261 {
2262     module_t *lmp_module;
2263     static enum_val_t lmp_ver[] = {
2264         {"draft-ietf-ccamp-lmp-09", "draft-ietf-ccamp-lmp-09", LMP_VER_DRAFT_CCAMP_09},
2265         {"draft-ietf-ccamp-lmp-03", "draft-ietf-ccamp-lmp-03", LMP_VER_DRAFT_CCAMP_03},
2266         {"draft-ietf-ccamp-lmp-02", "draft-ietf-ccamp-lmp-02", LMP_VER_DRAFT_CCAMP_02},
2267         {NULL, NULL, -1}
2268     };
2269
2270     lmp_module = prefs_register_protocol(proto_lmp, lmp_prefs_applied);
2271     prefs_register_enum_preference(
2272         lmp_module, "version",
2273         "Draft version of LMP",
2274         "Specifies the IETF CCAMP draft version of LMP to interpret",
2275         &lmp_draft_ver, lmp_ver, FALSE);
2276     prefs_register_uint_preference(
2277         lmp_module, "udp_port", "LMP UDP Port (draft-09 ONLY)",
2278         "UDP port number to use for LMP (draft-09 only)", 10, &lmp_udp_port_config);
2279 }
2280
2281 void
2282 proto_register_lmp(void)
2283 {
2284     static gint *ett[NUM_LMP_SUBTREES];
2285     int i;
2286
2287     for (i=0; i<NUM_LMP_SUBTREES; i++) {
2288         lmp_subtree[i] = -1;
2289         ett[i] = &lmp_subtree[i];
2290     }
2291
2292     proto_lmp = proto_register_protocol("Link Management Protocol (LMP)",
2293                                             "LMP", "lmp");
2294     proto_register_field_array(proto_lmp, lmpf_info, array_length(lmpf_info));
2295     proto_register_subtree_array(ett, array_length(ett));
2296
2297     register_lmp_prefs();
2298 }
2299
2300 void
2301 proto_reg_handoff_lmp(void)
2302 {
2303     lmp_handle = create_dissector_handle(dissect_lmp, proto_lmp);
2304     dissector_add("udp.port", lmp_udp_port, lmp_handle);
2305     dissector_add("ip.proto", IP_PROTO_LMP, lmp_handle);
2306 }