Move the GSM SMS dissection to a dedicated subdissector (currently still within
[obnox/wireshark/wip.git] / 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: packet-lmp.c,v 1.18 2003/12/21 04:31:56 jmayer Exp $
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     if (VALID_09_CLASS(class))
824         return class + LMPF_09_OBJECT;
825     return -1;
826 }
827
828
829 /*------------------------------------------------------------------------------
830  * LMP Subtrees
831  *
832  * We have two types of subtrees - a statically defined, constant set and
833  * a class set - one for each class. The static ones are before all the class ones
834  */
835 enum {
836     LMP_TREE_MAIN,
837     LMP_TREE_HEADER,
838     LMP_TREE_HEADER_FLAGS,
839     LMP_TREE_OBJECT_HEADER,
840     LMP_TREE_ERROR_FLAGS,
841     LMP_TREE_BEGIN_VERIFY_FLAGS,
842     LMP_TREE_BEGIN_VERIFY_TRANSPORT_FLAGS,
843     LMP_TREE_TE_LINK_FLAGS,
844     LMP_TREE_DATA_LINK_FLAGS,
845     LMP_TREE_DATA_LINK_SUBOBJ,
846     LMP_TREE_CHANNEL_STATUS_ID,
847
848     LMP_TREE_CLASS_START
849 };
850 #define NUM_LMP_SUBTREES (LMP_TREE_CLASS_START + LMP_CLASS_MAX)
851 #define NUM_LMP_09_SUBTREES (LMP_TREE_CLASS_START + LMP_CLASS_MAX)
852
853 static gint lmp_subtree[MAX(NUM_LMP_SUBTREES,NUM_LMP_09_SUBTREES)];
854 static gint lmp_09_subtree[NUM_LMP_09_SUBTREES];
855
856 static int lmp_class_to_subtree(int class)
857 {
858     if (VALID_CLASS(class))
859         return lmp_subtree[LMP_TREE_CLASS_START + class];
860
861     return -1;
862 }
863
864 static int lmp_09_class_to_subtree(int class)
865 {
866     if (VALID_09_CLASS(class))
867         return lmp_09_subtree[LMP_TREE_CLASS_START + class];
868
869     return -1;
870 }
871
872 /*------------------------------------------------------------------------------
873  * Da code
874  */
875
876 static void
877 dissect_lmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
878 {
879     int offset = 0;
880     proto_tree *lmp_tree = NULL, *ti, *ti2;
881     proto_tree *lmp_header_tree;
882     proto_tree *lmp_header_flags_tree;
883     proto_tree *lmp_object_tree;
884     proto_tree *lmp_object_header_tree;
885     proto_tree *lmp_flags_tree;
886     proto_tree *lmp_subobj_tree;
887
888     guint8 version;
889     guint8 flags;
890     guint8 message_type;
891     guint16 cksum, computed_cksum;
892     vec_t cksum_vec[1];
893     int j, k, l, len;
894     int msg_length;
895     int obj_length;
896     int mylen;
897     int offset2;
898     int proto;
899
900     proto = pinfo->ipproto;
901     /* If the current preference is NOT LMP09, do not process UDP packets */
902     if ((proto == IP_PROTO_UDP) && (lmp_draft_ver != LMP_VER_DRAFT_CCAMP_09)) {
903         return;
904     }
905     /* If the current preference is NOT LMP09, process only UDP packets */
906     if ((proto != IP_PROTO_UDP) && (lmp_draft_ver == LMP_VER_DRAFT_CCAMP_09)) {
907         return;
908     }
909
910     if (check_col(pinfo->cinfo, COL_PROTOCOL))
911         col_set_str(pinfo->cinfo, COL_PROTOCOL, "LMP");
912     if (check_col(pinfo->cinfo, COL_INFO))
913         col_clear(pinfo->cinfo, COL_INFO);
914
915     version = (tvb_get_guint8(tvb, offset+0)) >> 4;
916     flags = tvb_get_guint8(tvb, offset+2);
917     message_type = tvb_get_guint8(tvb, offset+3);
918     if (check_col(pinfo->cinfo, COL_INFO)) {
919         col_add_str(pinfo->cinfo, COL_INFO,
920             val_to_str(message_type, message_type_vals, "Unknown (%u). "));
921     }
922
923     if (tree) {
924         msg_length = tvb_get_ntohs(tvb, offset+4);
925         ti = proto_tree_add_item(tree, proto_lmp, tvb, offset, msg_length,
926             FALSE);
927         lmp_tree = proto_item_add_subtree(ti, lmp_subtree[LMP_TREE_MAIN]);
928         ti = proto_tree_add_text(lmp_tree, tvb, offset, 12, "LMP Header. %s",
929                                  val_to_str(message_type, message_type_vals,
930                                             "Unknown Message (%u). "));
931         lmp_header_tree = proto_item_add_subtree(ti, lmp_subtree[LMP_TREE_HEADER]);
932         proto_tree_add_text(lmp_header_tree, tvb, offset, 1, "LMP Version: %u",
933                             version);
934         ti = proto_tree_add_text(lmp_header_tree, tvb, offset+2, 1, "Flags: %02x",
935                                  flags);
936         lmp_header_flags_tree = proto_item_add_subtree(ti, lmp_subtree[LMP_TREE_HEADER_FLAGS]);
937         proto_tree_add_boolean(lmp_header_flags_tree, lmp_filter[LMPF_HDR_FLAGS_CC_DOWN],
938                                tvb, offset+2, 1, flags);
939         proto_tree_add_boolean(lmp_header_flags_tree, lmp_filter[LMPF_HDR_FLAGS_REBOOT],
940                                tvb, offset+2, 1, flags);
941         proto_tree_add_uint(lmp_header_tree, lmp_filter[LMPF_MSG], tvb,
942                             offset+3, 1, message_type);
943         proto_tree_add_text(lmp_header_tree, tvb, offset+4, 2, "Length: %d bytes",
944                             msg_length);
945         if (LMPF_MSG + message_type <= LMPF_MSG_CHANNEL_STATUS_RESP &&
946                        message_type > 0) {
947             proto_tree_add_boolean_hidden(lmp_header_tree, lmp_filter[LMPF_MSG + message_type], tvb,
948                                           offset+3, 1, 1);
949         } else {
950             proto_tree_add_protocol_format(lmp_header_tree, proto_malformed, tvb, offset+3, 1,
951                                            "Invalid message type: %u", message_type);
952                 return;
953         }
954
955         cksum = tvb_get_ntohs(tvb, offset+6);
956         if (!pinfo->fragmented && (int) tvb_length(tvb) >= msg_length) {
957             /* The packet isn't part of a fragmented datagram and isn't
958                truncated, so we can checksum it. */
959             cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, msg_length);
960             cksum_vec[0].len = msg_length;
961             computed_cksum = in_cksum(&cksum_vec[0], 1);
962
963             if (computed_cksum == 0) {
964                 proto_tree_add_text(lmp_header_tree, tvb, offset+6, 2,
965                                     "Message Checksum: 0x%04x (correct)",
966                                     cksum);
967             } else {
968                 proto_tree_add_text(lmp_header_tree, tvb, offset+6, 2,
969                                     "Message Checksum: 0x%04x (incorrect, should be 0x%04x)",
970                                     cksum,
971                                     in_cksum_shouldbe(cksum, computed_cksum));
972             }
973         } else {
974             proto_tree_add_text(lmp_header_tree, tvb, offset+6, 2,
975                                 "Message Checksum: 0x%04x",
976                                 cksum);
977         }
978
979         proto_tree_add_text(lmp_header_tree, tvb, offset+8, 4,
980                             "Local Control Channel ID: %d (%s)",
981                             tvb_get_ntohl(tvb, offset+8),
982                             ip_to_str(tvb_get_ptr(tvb, offset+8, 4)));
983
984         offset += 8;
985         len = 8;
986         while (len < msg_length) {
987           guint8 class;
988           guint8 type;
989           guint8 negotiable;
990           char *object_type;
991
992           obj_length = tvb_get_ntohs(tvb, offset+2);
993           class = tvb_get_guint8(tvb, offset+1);
994           type = tvb_get_guint8(tvb, offset);
995           negotiable = (type >> 7); type &= 0x7f;
996           if (lmp_draft_ver == LMP_VER_DRAFT_CCAMP_09) {
997                 object_type = val_to_str(class, lmp_09_class_vals, "Unknown");
998                 proto_tree_add_uint_hidden(lmp_tree, lmp_filter[LMPF_09_OBJECT],
999                                            tvb,
1000                                            offset, 1, class);
1001                 if (VALID_09_CLASS(class)) {
1002                     ti = proto_tree_add_item(lmp_tree, lmp_filter[lmp_09_class_to_filter_num(class)],
1003                         tvb, offset, obj_length, FALSE);
1004                 } else {
1005                     proto_tree_add_protocol_format(lmp_tree, proto_malformed, tvb, offset+1, 1,
1006                         "Invalid class: %u", class);
1007                     return;
1008                 }
1009                 lmp_object_tree = proto_item_add_subtree(ti, lmp_09_class_to_subtree(class));
1010
1011                 ti2 = proto_tree_add_text(lmp_object_tree, tvb, offset, 4,
1012                                       "Header. Class %d, C-Type %d, Length %d, %s",
1013                                       class, type, obj_length,
1014                                       negotiable ? "Negotiable" : "Not Negotiable");
1015                 lmp_object_header_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_OBJECT_HEADER]);
1016                 proto_tree_add_text(lmp_object_header_tree, tvb, offset, 1,
1017                                 negotiable ? "Negotiable" : "Not Negotiable");
1018                 proto_tree_add_text(lmp_object_header_tree, tvb, offset+2, 2,
1019                                 "Length: %u", obj_length);
1020                 proto_tree_add_text(lmp_object_header_tree, tvb, offset+1, 1,
1021                                 "Object Class: %u - %s",
1022                                 class, object_type);
1023                 proto_tree_add_item(lmp_object_header_tree, lmp_filter[LMPF_VAL_CTYPE],
1024                                     tvb, offset, 1, type);
1025                 offset2 = offset+4;
1026                 mylen = obj_length - 4;
1027           } else /* LMP_VER_DRAFT_CCAMP_03 */ {
1028                 object_type = val_to_str(class, lmp_class_vals, "Unknown");
1029                 proto_tree_add_uint_hidden(lmp_tree, lmp_filter[LMPF_OBJECT],
1030                                            tvb,
1031                                            offset, 1, class);
1032
1033                 if (VALID_CLASS(class)) {
1034                     ti = proto_tree_add_item(lmp_tree, lmp_filter[lmp_class_to_filter_num(class)],
1035                         tvb, offset, obj_length, FALSE);
1036                 } else {
1037                     proto_tree_add_protocol_format(lmp_tree, proto_malformed, tvb, offset+1, 1,
1038                         "Invalid class: %u", class);
1039                     return;
1040                 }
1041
1042                 lmp_object_tree = proto_item_add_subtree(ti, lmp_class_to_subtree(class));
1043
1044                 ti2 = proto_tree_add_text(lmp_object_tree, tvb, offset, 4,
1045                                       "Header. Class %d, C-Type %d, Length %d, %s",
1046                                       class, type, obj_length,
1047                                       negotiable ? "Negotiable" : "Not Negotiable");
1048                 lmp_object_header_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_OBJECT_HEADER]);
1049                 proto_tree_add_text(lmp_object_header_tree, tvb, offset, 1,
1050                                 negotiable ? "Negotiable" : "Not Negotiable");
1051                 proto_tree_add_text(lmp_object_header_tree, tvb, offset+2, 2,
1052                                 "Length: %u", obj_length);
1053                 proto_tree_add_text(lmp_object_header_tree, tvb, offset+1, 1,
1054                                 "Object Class: %u - %s",
1055                                 class, object_type);
1056                 proto_tree_add_item(lmp_object_header_tree, lmp_filter[LMPF_VAL_CTYPE],
1057                                     tvb, offset, 1, type);
1058                 offset2 = offset+4;
1059                 mylen = obj_length - 4;
1060           }
1061
1062           if (lmp_draft_ver == LMP_VER_DRAFT_CCAMP_09) {
1063
1064             switch (class) {
1065
1066             case LMP_CLASS_NULL:
1067                 break;
1068
1069             case LMP_09_CLASS_CCID:
1070                 switch(type) {
1071                 case 1:
1072                     l = LMPF_VAL_LOCAL_CCID;
1073                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1074                     proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1075                                         tvb_get_ntohl(tvb, offset2));
1076                     break;
1077                 case 2:
1078                     l = LMPF_VAL_REMOTE_CCID;
1079                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1080                     proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1081                                         tvb_get_ntohl(tvb, offset2));
1082                 default:
1083                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1084                                         "Data (%d bytes)", mylen);
1085                     break;
1086                 }
1087                 break;
1088
1089             case LMP_09_CLASS_NODE_ID:
1090                 switch(type) {
1091                 case 1:
1092                     l = LMPF_VAL_LOCAL_NODE_ID;
1093                     proto_item_append_text(ti, ": %s",
1094                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1095                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1096                                         FALSE);
1097                     break;
1098                 case 2:
1099                     l = LMPF_VAL_REMOTE_NODE_ID;
1100                     proto_item_append_text(ti, ": %s",
1101                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1102                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1103                                         FALSE);
1104                     break;
1105                 default:
1106                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1107                                         "Data (%d bytes)", mylen);
1108                     break;
1109                 }
1110                 break;
1111
1112             case LMP_09_CLASS_LINK_ID:
1113                 switch(type) {
1114                 case 1:
1115                 case 2:
1116                     l = (type == 1)? LMPF_VAL_LOCAL_LINK_ID_IPV4:
1117                         LMPF_VAL_REMOTE_LINK_ID_IPV4;
1118                     proto_item_append_text(ti, ": IPv4 %s",
1119                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1120                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1121                                         FALSE);
1122                     break;
1123                 case 3:
1124                 case 4:
1125                     l = (type == 3)? LMPF_VAL_LOCAL_LINK_ID_IPV6:
1126                         LMPF_VAL_REMOTE_LINK_ID_IPV6;
1127                     proto_item_append_text(ti, ": IPv6 %s",
1128                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1129                     proto_tree_add_text(lmp_object_tree, tvb, offset2, 16, "IPv6: %s",
1130                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1131                     break;
1132                 case 5:
1133                 case 6:
1134                     l = (type == 5)? LMPF_VAL_LOCAL_LINK_ID_UNNUM:
1135                         LMPF_VAL_REMOTE_LINK_ID_UNNUM;
1136                     proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2));
1137                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1138                                         FALSE);
1139                     break;
1140
1141                 default:
1142                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1143                                         "Data (%d bytes)", mylen);
1144                     break;
1145                 }
1146                 break;
1147
1148             case LMP_09_CLASS_INTERFACE_ID:
1149                 switch(type) {
1150                 case 1:
1151                 case 2:
1152                     l = (type == 1)? LMPF_VAL_LOCAL_INTERFACE_ID_IPV4:
1153                         LMPF_VAL_REMOTE_INTERFACE_ID_IPV4;
1154                     proto_item_append_text(ti, ": IPv4 %s",
1155                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1156                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1157                                         FALSE);
1158                     break;
1159                 case 3:
1160                 case 4:
1161                     l = (type == 3)? LMPF_VAL_LOCAL_INTERFACE_ID_IPV6:
1162                         LMPF_VAL_REMOTE_INTERFACE_ID_IPV6;
1163                     proto_item_append_text(ti, ": IPv6 %s",
1164                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1165                     proto_tree_add_text(lmp_object_tree, tvb, offset2, 16, "IPv6: %s",
1166                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1167                     break;
1168                 case 5:
1169                 case 6:
1170                     l = (type == 5)? LMPF_VAL_LOCAL_INTERFACE_ID_UNNUM:
1171                         LMPF_VAL_REMOTE_INTERFACE_ID_UNNUM;
1172                     proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2));
1173                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1174                                         FALSE);
1175                     break;
1176                 default:
1177                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1178                                         "Data (%d bytes)", mylen);
1179                     break;
1180                 }
1181                 break;
1182
1183             case LMP_09_CLASS_MESSAGE_ID:
1184                 switch(type) {
1185                 case 1:
1186                     l = LMPF_VAL_MESSAGE_ID;
1187                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1188                     proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1189                                         tvb_get_ntohl(tvb, offset2));
1190                     break;
1191                 case 2:
1192                     l = LMPF_VAL_MESSAGE_ID_ACK;
1193                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1194                     proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1195                                         tvb_get_ntohl(tvb, offset2));
1196                     break;
1197
1198                 default:
1199                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1200                                         "Data (%d bytes)", mylen);
1201                     break;
1202                 }
1203                 break;
1204
1205             case LMP_09_CLASS_CONFIG:
1206                 switch(type) {
1207                 case 1:
1208                     proto_item_append_text(ti, ": HelloInterval: %d, HelloDeadInterval: %d",
1209                                            tvb_get_ntohs(tvb, offset2), tvb_get_ntohs(tvb, offset2+2));
1210                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_CONFIG_HELLO],
1211                                         tvb, offset2, 2, tvb_get_ntohs(tvb, offset2));
1212                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_CONFIG_HELLO_DEAD],
1213                                         tvb, offset2+2, 2, tvb_get_ntohs(tvb, offset2+2));
1214                     break;
1215                 default:
1216                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1217                                         "Data (%d bytes)", mylen);
1218                     break;
1219                 }
1220                 break;
1221
1222             case LMP_09_CLASS_HELLO:
1223                 switch(type) {
1224                 case 1:
1225                     proto_item_append_text(ti, ": TxSeq %d, RxSeq: %d",
1226                                            tvb_get_ntohl(tvb, offset2),
1227                                            tvb_get_ntohl(tvb, offset2+4));
1228                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_HELLO_TXSEQ],
1229                                         tvb, offset2, 4, tvb_get_ntohl(tvb, offset2));
1230                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_HELLO_RXSEQ],
1231                                         tvb, offset2+4, 4, tvb_get_ntohl(tvb, offset2+4));
1232                     break;
1233                 default:
1234                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1235                                         "Data (%d bytes)", mylen);
1236                     break;
1237                 }
1238                 break;
1239
1240             case LMP_09_CLASS_BEGIN_VERIFY:
1241                 switch(type) {
1242                 case 1:
1243                     l = tvb_get_ntohs(tvb, offset2);
1244                     ti2 = proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS],
1245                                               tvb, offset2, 2, FALSE);
1246
1247                     lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_BEGIN_VERIFY_FLAGS]);
1248                     proto_tree_add_boolean(lmp_flags_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_ALL_LINKS],
1249                                            tvb, offset2, 2, l);
1250                     proto_tree_add_boolean(lmp_flags_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_LINK_TYPE],
1251                                            tvb, offset2, 2, l);
1252                     proto_tree_add_text(lmp_object_tree, tvb, offset2+2, 2,
1253                                         "Verify Interval: %d ms", tvb_get_ntohs(tvb, offset2+2));
1254                     proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 4,
1255                                         "Number of Data Links: %d", tvb_get_ntohl(tvb, offset2+4));
1256                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_ENCTYPE],
1257                                         tvb, offset2+8, 1, FALSE);
1258                     proto_tree_add_text(lmp_object_tree, tvb, offset2+10, 2,
1259                                         "Verify Transport Mechanism: 0x%0x", tvb_get_ntohs(tvb, offset2+10));
1260                     proto_tree_add_text(lmp_object_tree, tvb, offset2+12, 4,
1261                                         "Transmission Rate: %.10g", tvb_get_ntohieee_float(tvb, offset2+12));
1262                     proto_tree_add_text(lmp_object_tree, tvb, offset2+16, 4,
1263                                         "Wavelength: %d", tvb_get_ntohl(tvb, offset2+4));
1264                     break;
1265                 default:
1266                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1267                                         "Data (%d bytes)", mylen);
1268                     break;
1269                 }
1270                 break;
1271
1272             case LMP_09_CLASS_BEGIN_VERIFY_ACK:
1273                 switch(type) {
1274                 case 1:
1275                     proto_item_append_text(ti, ": VerifyDeadInterval: %d, TransportResponse: 0x%0x",
1276                                            tvb_get_ntohs(tvb, offset2), tvb_get_ntohs(tvb, offset2+2));
1277                     proto_tree_add_text(lmp_object_tree, tvb, offset2, 2,
1278                                         "VerifyDeadInterval: %d ms", tvb_get_ntohs(tvb, offset2));
1279                     proto_tree_add_text(lmp_object_tree, tvb, offset2+2, 2,
1280                                         "Verify Transport Response: 0x%0x", tvb_get_ntohs(tvb, offset2+2));
1281                     break;
1282                 default:
1283                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1284                                         "Data (%d bytes)", mylen);
1285                     break;
1286                 }
1287                 break;
1288
1289             case LMP_09_CLASS_VERIFY_ID:
1290                 switch(type) {
1291                 case 1:
1292                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1293                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_VERIFY_ID], tvb, offset2, 4,
1294                                         tvb_get_ntohl(tvb, offset2));
1295                     break;
1296                 default:
1297                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1298                                         "Data (%d bytes)", mylen);
1299                     break;
1300                 }
1301                 break;
1302
1303             case LMP_09_CLASS_TE_LINK:
1304                 l = tvb_get_guint8(tvb, offset2);
1305                 ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_FLAGS],
1306                                           tvb, offset2, 1, l);
1307                 proto_item_append_text(ti2, ": %s%s",
1308                                        (l&0x01) ? "Fault-Mgmt-Supported " : "",
1309                                        (l&0x02) ? "Link-Verification-Supported " : "");
1310                 lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_TE_LINK_FLAGS]);
1311                 proto_tree_add_boolean(lmp_flags_tree,
1312                                        lmp_filter[LMPF_VAL_TE_LINK_FLAGS_FAULT_MGMT],
1313                                        tvb, offset2, 1, l);
1314                 proto_tree_add_boolean(lmp_flags_tree,
1315                                        lmp_filter[LMPF_VAL_TE_LINK_FLAGS_LINK_VERIFY],
1316                                        tvb, offset2, 1, l);
1317                 switch(type) {
1318                 case 1:
1319                     proto_item_append_text(ti, ": IPv4: Local %s, Remote %s",
1320                                            ip_to_str(tvb_get_ptr(tvb, offset2+4, 4)),
1321                                            ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
1322                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_LOCAL_IPV4],
1323                                         tvb, offset2+4, 4, FALSE);
1324                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_REMOTE_IPV4],
1325                                         tvb, offset2+8, 4, FALSE);
1326                     break;
1327                 case 2:
1328                     proto_item_append_text(ti, ": IPv6: Local %s, Remote %s",
1329                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)),
1330                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+8, 16)));
1331                     proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 16, "TE-Link Local ID - IPv6: %s",
1332                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1333                     proto_tree_add_text(lmp_object_tree, tvb, offset2+20,16, "TE-Link Remote ID - IPv6: %s",
1334                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)));
1335                     break;
1336                 case 3:
1337                     proto_item_append_text(ti, ": Unnumbered: Local %d, Remote %d",
1338                                            tvb_get_ntohl(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8));
1339                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_LOCAL_UNNUM],
1340                                         tvb, offset2+4, 4, FALSE);
1341                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_REMOTE_UNNUM],
1342                                         tvb, offset2+8, 4, FALSE);
1343                     break;
1344                 default:
1345                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1346                                         "Data (%d bytes)", mylen);
1347                     break;
1348                 }
1349                 break;
1350
1351             case LMP_09_CLASS_DATA_LINK:
1352                 l = tvb_get_guint8(tvb, offset2);
1353                 ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_FLAGS],
1354                                           tvb, offset2, 1, l);
1355                 proto_item_append_text(ti2, ": %s%s",
1356                                        (l&0x01) ? "Interface-Type-Port " : "Interface-Type-Component-Link ",
1357                                        (l&0x02) ? "Allocated " : "Unallocated ");
1358                 lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_DATA_LINK_FLAGS]);
1359                 proto_tree_add_boolean(lmp_flags_tree,
1360                                        lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_PORT],
1361                                        tvb, offset2, 1, l);
1362                 proto_tree_add_boolean(lmp_flags_tree,
1363                                        lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_ALLOCATED],
1364                                        tvb, offset2, 1, l);
1365                 switch(type) {
1366                 case 1:
1367                     proto_item_append_text(ti, ": IPv4: Local %s, Remote %s",
1368                                            ip_to_str(tvb_get_ptr(tvb, offset2+4, 4)),
1369                                            ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
1370                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_IPV4],
1371                                         tvb, offset2+4, 4, FALSE);
1372                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_IPV4],
1373                                         tvb, offset2+8, 4, FALSE);
1374                     l = 12;
1375                     break;
1376                 case 2:
1377                     proto_item_append_text(ti, ": IPv6: Local %s, Remote %s",
1378                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)),
1379                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+8, 16)));
1380                     proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 16,
1381                                         "Data-Link Local ID - IPv6: %s",
1382                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1383                     proto_tree_add_text(lmp_object_tree, tvb, offset2+20,16,
1384                                         "Data-Link Remote ID - IPv6: %s",
1385                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)));
1386                     l = 36;
1387                     break;
1388                 case 3:
1389                     proto_item_append_text(ti, ": Unnumbered: Local %d, Remote %d",
1390                                            tvb_get_ntohl(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8));
1391                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_UNNUM],
1392                                         tvb, offset2+4, 4, FALSE);
1393                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_UNNUM],
1394                                         tvb, offset2+8, 4, FALSE);
1395                     l = 12;
1396                     break;
1397                 default:
1398                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1399                                         "Data (%d bytes)", mylen);
1400                     break;
1401                 }
1402
1403                 while (l < obj_length - 4) {
1404                     mylen = tvb_get_guint8(tvb, offset2+l+1);
1405                     ti2 = proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ],
1406                                               tvb, offset2+l, mylen, FALSE);
1407                     lmp_subobj_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_DATA_LINK_SUBOBJ]);
1408                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 1,
1409                                         "Subobject Type: %d", tvb_get_guint8(tvb, offset2+l));
1410                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+1, 1,
1411                                         "Subobject Length: %d", mylen);
1412                     switch(tvb_get_guint8(tvb, offset2+l)) {
1413                     case 1:
1414                         proto_item_set_text(ti2, "Interface Switching Capability: "
1415                                             "Switching Cap: %s, Encoding Type: %s, Min BW: %.10g, Max BW: %.10g",
1416                                             val_to_str(tvb_get_guint8(tvb, offset2+l+2),
1417                                                        gmpls_switching_type_str, "Unknown (%d)"),
1418                                             val_to_str(tvb_get_guint8(tvb, offset2+l+3),
1419                                                        gmpls_lsp_enc_str, "Unknown (%d)"),
1420                                             tvb_get_ntohieee_float(tvb, offset2+l+4),
1421                                             tvb_get_ntohieee_float(tvb, offset2+l+8));
1422                         proto_tree_add_item(lmp_subobj_tree,
1423                                             lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_SWITCHING_TYPE],
1424                                             tvb, offset2+l+2, 1, FALSE);
1425                         proto_tree_add_item(lmp_subobj_tree,
1426                                             lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_LSP_ENCODING],
1427                                             tvb, offset2+l+3, 1, FALSE);
1428                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+4, 4,
1429                                             "Minimum Reservable Bandwidth: %.10g bytes/s",
1430                                             tvb_get_ntohieee_float(tvb, offset2+l+4));
1431                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+8, 4,
1432                                             "Maximum Reservable Bandwidth: %.10g bytes/s",
1433                                             tvb_get_ntohieee_float(tvb, offset2+l+8));
1434                         break;
1435
1436                     case 2:
1437                         proto_item_set_text(ti2, "Wavelength: %d",
1438                                             tvb_get_ntohl(tvb, offset2+l+2));
1439                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+4, 4,
1440                                             "Wavelength: %d",
1441                                             tvb_get_ntohl(tvb, offset2+l+2));
1442                         break;
1443
1444                     default:
1445                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l,
1446                                             tvb_get_guint8(tvb, offset2+l+1),
1447                                             "Data (%d bytes)", tvb_get_guint8(tvb, offset2+l+1));
1448                         break;
1449                     }
1450                     l += tvb_get_guint8(tvb, offset2+l+1);
1451                 }
1452
1453                 break;
1454
1455             case LMP_09_CLASS_CHANNEL_STATUS:
1456                 k = 0; j = 0;
1457                 switch(type) {
1458                 case 1:
1459                 case 3:
1460                     k = 8; break;
1461                 case 2:
1462                     k = 20; break;
1463                 }
1464                 if (!k)
1465                     break;
1466                 for (l=0; l<obj_length - 4; ) {
1467                     ti2 = proto_tree_add_text(lmp_object_tree, tvb, offset2+l, k,
1468                                               "Interface-Id");
1469                     lmp_subobj_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_CHANNEL_STATUS_ID]);
1470                     switch(type) {
1471                     case 1:
1472                         if (j < 4)
1473                             proto_item_append_text(ti, ": [IPv4-%s",
1474                                                    ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
1475                         proto_item_append_text(ti2, ": IPv4 %s",
1476                                                ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
1477                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
1478                                             "Interface ID: IPv4: %s",
1479                                             ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
1480                         l += 4;
1481                         break;
1482                     case 2:
1483                         if (j < 4)
1484                             proto_item_append_text(ti, ": [IPv6-%s",
1485                                                    ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
1486                         proto_item_append_text(ti2, ": IPv6 %s",
1487                                                ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
1488                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2, 16, "Interface ID: IPv6: %s",
1489                                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
1490                         l += 16;
1491                         break;
1492                     case 3:
1493                         if (j < 4)
1494                             proto_item_append_text(ti, ": [Unnum-%d", tvb_get_ntohl(tvb, offset2+l));
1495                         proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2+l));
1496                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
1497                                             "Interface ID: Unnumbered: %d",
1498                                             tvb_get_ntohl(tvb, offset2+l));
1499                         l += 4;
1500                         break;
1501                     default:
1502                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, obj_length-4-l,
1503                                             "Data (%d bytes)", obj_length-4-l);
1504                         l = obj_length - 4;
1505                         break;
1506                     }
1507                     if (l == obj_length - 4) break;
1508
1509                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 1,
1510                                         tvb_get_guint8(tvb, offset2+l) & 0x80 ?
1511                                         "Link Allocated - Active Monitoring" :
1512                                         "Link Not Allocated");
1513                     if (j < 4)
1514                         proto_item_append_text(ti, "-%s,%s], ",
1515                                                tvb_get_guint8(tvb, offset2+l) & 0x80 ? "Act" : "NA",
1516                                                val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
1517                                                           channel_status_short_str, "UNK (%u)."));
1518                     proto_item_append_text(ti2, ": %s, ",
1519                                            tvb_get_guint8(tvb, offset2+l) & 0x80 ? "Active" : "Not Active");
1520                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
1521                                         "Channel Status: %s",
1522                                         val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
1523                                                    channel_status_str, "Unknown (%u). "));
1524                     proto_item_append_text(ti2, val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
1525                                                            channel_status_str, "Unknown (%u). "));
1526                     j++;
1527                     l += 4;
1528                     if (j==4 && l < obj_length - 4)
1529                         proto_item_append_text(ti, " ...");
1530                 }
1531                 break;
1532
1533             case LMP_09_CLASS_CHANNEL_STATUS_REQUEST:
1534                 for (l=0; l<obj_length - 4; ) {
1535                     switch(type) {
1536                     case 1:
1537                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 4,
1538                                             "Interface ID: IPv4: %s",
1539                                             ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
1540                         l += 4;
1541                         break;
1542                     case 2:
1543                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 16, "Interface ID: IPv6: %s",
1544                                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l,16)));
1545                         l += 16;
1546                         break;
1547                     case 3:
1548                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 4,
1549                                             "Interface ID: Unnumbered: %d",
1550                                             tvb_get_ntohl(tvb, offset2+l));
1551                         l += 4;
1552                         break;
1553                     default:
1554                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, obj_length-4-l,
1555                                             "Data (%d bytes)", obj_length-4-l);
1556                         l = obj_length - 4;
1557                         break;
1558                     }
1559                 }
1560                 break;
1561
1562             case LMP_09_CLASS_ERROR:
1563                 l = tvb_get_ntohl(tvb, offset2);
1564                 ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_ERROR],
1565                                           tvb, offset2, 4, l);
1566
1567                 switch(type) {
1568                 case 1:
1569                         proto_item_append_text(ti, ": CONFIG_ERROR: %s%s%s",
1570                                                (l&0x01) ? "Unacceptable-Params " : "",
1571                                                (l&0x02) ? "Renegotiate" : "",
1572                                                (l&0x04) ? "Bad Received CCID" : "");
1573                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
1574                         proto_tree_add_boolean(lmp_flags_tree,
1575                                                lmp_filter[LMPF_VAL_ERROR_CONFIG_BAD_PARAMETERS],
1576                                                tvb, offset, 4, l);
1577                         proto_tree_add_boolean(lmp_flags_tree,
1578                                                lmp_filter[LMPF_VAL_ERROR_CONFIG_RENEGOTIATE],
1579                                                tvb, offset, 4, l);
1580                         proto_tree_add_boolean(lmp_flags_tree,
1581                                                lmp_filter[LMPF_VAL_ERROR_CONFIG_BAD_CCID],
1582                                                tvb, offset, 4, l);
1583                         break;
1584                 case 2:
1585                         proto_item_append_text(ti, ": BEGIN_VERIFY_ERROR: %s%s%s%s",
1586                                                (l&0x01) ? "Unsupported-Link " : "",
1587                                                (l&0x02) ? "Unwilling" : "",
1588                                                (l&0x04) ? "Unsupported-Transport" : "",
1589                                                (l&0x08) ? "TE-Link-ID" : "");
1590                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
1591                         proto_tree_add_boolean(lmp_flags_tree,
1592                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_UNSUPPORTED_LINK],
1593                                                tvb, offset, 4, l);
1594                         proto_tree_add_boolean(lmp_flags_tree,
1595                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_UNWILLING],
1596                                                tvb, offset, 4, l);
1597                         proto_tree_add_boolean(lmp_flags_tree,
1598                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_TRANSPORT],
1599                                                tvb, offset, 4, l);
1600                         proto_tree_add_boolean(lmp_flags_tree,
1601                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_TE_LINK_ID],
1602                                                tvb, offset, 4, l);
1603                         break;
1604                 case 3:
1605                         proto_item_append_text(ti, ": LINK_SUMMARY_ERROR: %s%s%s%s%s%s",
1606                                                (l&0x01) ? "Unacceptable-Params " : "",
1607                                                (l&0x02) ? "Renegotiate" : "",
1608                                                (l&0x04) ? "Bad-TE-Link" : "",
1609                                                (l&0x08) ? "Bad-Data-Link" : "",
1610                                                (l&0x10) ? "Bad-TE-Link-CType" : "",
1611                                                (l&0x20) ? "Bad-Data-Link-CType" : "");
1612                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
1613                         proto_tree_add_boolean(lmp_flags_tree,
1614                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_PARAMETERS],
1615                                                tvb, offset, 4, l);
1616                         proto_tree_add_boolean(lmp_flags_tree,
1617                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_RENEGOTIATE],
1618                                                tvb, offset, 4, l);
1619                         proto_tree_add_boolean(lmp_flags_tree,
1620                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_TE_LINK],
1621                                                tvb, offset, 4, l);
1622                         proto_tree_add_boolean(lmp_flags_tree,
1623                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_DATA_LINK],
1624                                                tvb, offset, 4, l);
1625                         proto_tree_add_boolean(lmp_flags_tree,
1626                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_UNKNOWN_TEL_CTYPE],
1627                                                tvb, offset, 4, l);
1628                         proto_tree_add_boolean(lmp_flags_tree,
1629                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_UNKNOWN_DL_CTYPE],
1630                                                tvb, offset, 4, l);
1631                         break;
1632                 default:
1633                         proto_item_append_text(ti, ": UNKNOWN_ERROR (%d): 0x%04x", type, l);
1634                         proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1635                                             "Data (%d bytes)", mylen);
1636                         break;
1637                 }
1638             default:
1639                 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1640                                             "Data (%d bytes)", mylen);
1641                 break;
1642             }
1643           } else {
1644             /* LMP 03 or LMP 02 */
1645             switch (class) {
1646             case LMP_CLASS_NULL:
1647                 break;
1648
1649             case LMP_CLASS_LOCAL_CCID:
1650             case LMP_CLASS_REMOTE_CCID:
1651                 switch(type) {
1652                 case 1:
1653                     l = (class == LMP_CLASS_LOCAL_CCID) ?
1654                         LMPF_VAL_LOCAL_CCID : LMPF_VAL_REMOTE_CCID;
1655                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1656                     proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1657                                         tvb_get_ntohl(tvb, offset2));
1658                     break;
1659                 default:
1660                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1661                                         "Data (%d bytes)", mylen);
1662                     break;
1663                 }
1664                 break;
1665
1666             case LMP_CLASS_LOCAL_NODE_ID:
1667             case LMP_CLASS_REMOTE_NODE_ID:
1668                 switch(type) {
1669                 case 1:
1670                     l = (class == LMP_CLASS_LOCAL_NODE_ID) ?
1671                         LMPF_VAL_LOCAL_NODE_ID : LMPF_VAL_REMOTE_NODE_ID;
1672                     proto_item_append_text(ti, ": %s",
1673                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1674                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1675                                         FALSE);
1676                     break;
1677                 default:
1678                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1679                                         "Data (%d bytes)", mylen);
1680                     break;
1681                 }
1682                 break;
1683
1684             case LMP_CLASS_LOCAL_LINK_ID:
1685             case LMP_CLASS_REMOTE_LINK_ID:
1686                 switch(type) {
1687                 case 1:
1688                     l = (class == LMP_CLASS_LOCAL_LINK_ID) ?
1689                         LMPF_VAL_LOCAL_LINK_ID_IPV4 : LMPF_VAL_REMOTE_LINK_ID_IPV4;
1690                     proto_item_append_text(ti, ": IPv4 %s",
1691                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1692                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1693                                         FALSE);
1694                     break;
1695                 case 2:
1696                     proto_item_append_text(ti, ": IPv6 %s",
1697                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1698                     proto_tree_add_text(lmp_object_tree, tvb, offset2, 16, "IPv6: %s",
1699                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1700                     break;
1701                 case 3:
1702                     l = (class == LMP_CLASS_LOCAL_LINK_ID) ?
1703                         LMPF_VAL_LOCAL_LINK_ID_UNNUM : LMPF_VAL_REMOTE_LINK_ID_UNNUM;
1704                     proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2));
1705                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1706                                         FALSE);
1707                     break;
1708                 default:
1709                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1710                                         "Data (%d bytes)", mylen);
1711                     break;
1712                 }
1713                 break;
1714
1715             case LMP_CLASS_LOCAL_INTERFACE_ID:
1716             case LMP_CLASS_REMOTE_INTERFACE_ID:
1717                 switch(type) {
1718                 case 1:
1719                     l = (class == LMP_CLASS_LOCAL_INTERFACE_ID) ?
1720                         LMPF_VAL_LOCAL_INTERFACE_ID_IPV4 : LMPF_VAL_REMOTE_INTERFACE_ID_IPV4;
1721                     proto_item_append_text(ti, ": IPv4 %s",
1722                                            ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1723                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1724                                         FALSE);
1725                     break;
1726                 case 2:
1727                     proto_item_append_text(ti, ": IPv6 %s",
1728                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1729                     proto_tree_add_text(lmp_object_tree, tvb, offset2, 16, "IPv6: %s",
1730                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1731                     break;
1732                 case 3:
1733                     l = (class == LMP_CLASS_LOCAL_INTERFACE_ID) ?
1734                         LMPF_VAL_LOCAL_INTERFACE_ID_UNNUM : LMPF_VAL_REMOTE_INTERFACE_ID_UNNUM;
1735                     proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2));
1736                     proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1737                                         FALSE);
1738                     break;
1739                 default:
1740                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1741                                         "Data (%d bytes)", mylen);
1742                     break;
1743                 }
1744                 break;
1745
1746             case LMP_CLASS_MESSAGE_ID:
1747             case LMP_CLASS_MESSAGE_ID_ACK:
1748                 switch(type) {
1749                 case 1:
1750                     l = (class == LMP_CLASS_MESSAGE_ID) ?
1751                         LMPF_VAL_MESSAGE_ID : LMPF_VAL_MESSAGE_ID_ACK;
1752                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1753                     proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
1754                                         tvb_get_ntohl(tvb, offset2));
1755                     break;
1756                 default:
1757                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1758                                         "Data (%d bytes)", mylen);
1759                     break;
1760                 }
1761                 break;
1762
1763             case LMP_CLASS_CONFIG:
1764                 switch(type) {
1765                 case 1:
1766                     proto_item_append_text(ti, ": HelloInterval: %d, HelloDeadInterval: %d",
1767                                            tvb_get_ntohs(tvb, offset2), tvb_get_ntohs(tvb, offset2+2));
1768                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_CONFIG_HELLO],
1769                                         tvb, offset2, 2, tvb_get_ntohs(tvb, offset2));
1770                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_CONFIG_HELLO_DEAD],
1771                                         tvb, offset2+2, 2, tvb_get_ntohs(tvb, offset2+2));
1772                     break;
1773                 default:
1774                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1775                                         "Data (%d bytes)", mylen);
1776                     break;
1777                 }
1778                 break;
1779
1780             case LMP_CLASS_HELLO:
1781                 switch(type) {
1782                 case 1:
1783                     proto_item_append_text(ti, ": TxSeq %d, RxSeq: %d",
1784                                            tvb_get_ntohl(tvb, offset2),
1785                                            tvb_get_ntohl(tvb, offset2+4));
1786                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_HELLO_TXSEQ],
1787                                         tvb, offset2, 4, tvb_get_ntohl(tvb, offset2));
1788                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_HELLO_RXSEQ],
1789                                         tvb, offset2+4, 4, tvb_get_ntohl(tvb, offset2+4));
1790                     break;
1791                 default:
1792                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1793                                         "Data (%d bytes)", mylen);
1794                     break;
1795                 }
1796                 break;
1797             case LMP_CLASS_BEGIN_VERIFY:
1798                 switch(type) {
1799                 case 1:
1800                     l = tvb_get_ntohs(tvb, offset2);
1801                     ti2 = proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS],
1802                                               tvb, offset2, 2, FALSE);
1803                         
1804                     lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_BEGIN_VERIFY_FLAGS]);
1805                     proto_tree_add_boolean(lmp_flags_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_ALL_LINKS],
1806                                            tvb, offset2, 2, l);
1807                     proto_tree_add_boolean(lmp_flags_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_LINK_TYPE],
1808                                            tvb, offset2, 2, l);
1809                     proto_tree_add_text(lmp_object_tree, tvb, offset2+2, 2,
1810                                         "Verify Interval: %d ms", tvb_get_ntohs(tvb, offset2+2));
1811                     proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 4,
1812                                         "Number of Data Links: %d", tvb_get_ntohl(tvb, offset2+4));
1813                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_ENCTYPE],
1814                                         tvb, offset2+8, 1, FALSE);
1815                     proto_tree_add_text(lmp_object_tree, tvb, offset2+10, 2,
1816                                         "Verify Transport Mechanism: 0x%0x", tvb_get_ntohs(tvb, offset2+10));
1817                     proto_tree_add_text(lmp_object_tree, tvb, offset2+12, 4,
1818                                         "Transmission Rate: %.10g", tvb_get_ntohieee_float(tvb, offset2+12));
1819                     proto_tree_add_text(lmp_object_tree, tvb, offset2+16, 4,
1820                                         "Wavelength: %d", tvb_get_ntohl(tvb, offset2+4));
1821                     break;
1822                 default:
1823                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1824                                         "Data (%d bytes)", mylen);
1825                     break;
1826                 }
1827                 break;
1828
1829             case LMP_CLASS_BEGIN_VERIFY_ACK:
1830                 switch(type) {
1831                 case 1:
1832                     proto_item_append_text(ti, ": VerifyDeadInterval: %d, TransportResponse: 0x%0x",
1833                                            tvb_get_ntohs(tvb, offset2), tvb_get_ntohs(tvb, offset2+2));
1834                     proto_tree_add_text(lmp_object_tree, tvb, offset2, 2,
1835                                         "VerifyDeadInterval: %d ms", tvb_get_ntohs(tvb, offset2));
1836                     proto_tree_add_text(lmp_object_tree, tvb, offset2+2, 2,
1837                                         "Verify Transport Response: 0x%0x", tvb_get_ntohs(tvb, offset2+2));
1838                     break;
1839                 default:
1840                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1841                                         "Data (%d bytes)", mylen);
1842                     break;
1843                 }
1844                 break;
1845
1846             case LMP_CLASS_VERIFY_ID:
1847                 switch(type) {
1848                 case 1:
1849                     proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
1850                     proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_VERIFY_ID], tvb, offset2, 4,
1851                                         tvb_get_ntohl(tvb, offset2));
1852                     break;
1853                 default:
1854                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1855                                         "Data (%d bytes)", mylen);
1856                     break;
1857                 }
1858                 break;
1859
1860             case LMP_CLASS_TE_LINK:
1861                 l = tvb_get_guint8(tvb, offset2);
1862                 ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_FLAGS],
1863                                           tvb, offset2, 1, l);
1864                 proto_item_append_text(ti2, ": %s%s",
1865                                        (l&0x01) ? "Fault-Mgmt-Supported " : "",
1866                                        (l&0x02) ? "Link-Verification-Supported " : "");
1867                 lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_TE_LINK_FLAGS]);
1868                 proto_tree_add_boolean(lmp_flags_tree,
1869                                        lmp_filter[LMPF_VAL_TE_LINK_FLAGS_FAULT_MGMT],
1870                                        tvb, offset2, 1, l);
1871                 proto_tree_add_boolean(lmp_flags_tree,
1872                                        lmp_filter[LMPF_VAL_TE_LINK_FLAGS_LINK_VERIFY],
1873                                        tvb, offset2, 1, l);
1874                 switch(type) {
1875                 case 1:
1876                     proto_item_append_text(ti, ": IPv4: Local %s, Remote %s",
1877                                            ip_to_str(tvb_get_ptr(tvb, offset2+4, 4)),
1878                                            ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
1879                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_LOCAL_IPV4],
1880                                         tvb, offset2+4, 4, FALSE);
1881                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_REMOTE_IPV4],
1882                                         tvb, offset2+8, 4, FALSE);
1883                     break;
1884                 case 2:
1885                     proto_item_append_text(ti, ": IPv6: Local %s, Remote %s",
1886                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)),
1887                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+8, 16)));
1888                     proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 16, "TE-Link Local ID - IPv6: %s",
1889                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1890                     proto_tree_add_text(lmp_object_tree, tvb, offset2+20,16, "TE-Link Remote ID - IPv6: %s",
1891                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)));
1892                     break;
1893                 case 3:
1894                     proto_item_append_text(ti, ": Unnumbered: Local %d, Remote %d",
1895                                            tvb_get_ntohl(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8));
1896                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_LOCAL_UNNUM],
1897                                         tvb, offset2+4, 4, FALSE);
1898                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_REMOTE_UNNUM],
1899                                         tvb, offset2+8, 4, FALSE);
1900                     break;
1901                 default:
1902                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1903                                         "Data (%d bytes)", mylen);
1904                     break;
1905                 }
1906                 break;
1907
1908             case LMP_CLASS_DATA_LINK:
1909                 l = tvb_get_guint8(tvb, offset2);
1910                 ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_FLAGS],
1911                                           tvb, offset2, 1, l);
1912                 proto_item_append_text(ti2, ": %s%s",
1913                                        (l&0x01) ? "Interface-Type-Port " : "Interface-Type-Component-Link ",
1914                                        (l&0x02) ? "Allocated " : "Unallocated ");
1915                 lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_DATA_LINK_FLAGS]);
1916                 proto_tree_add_boolean(lmp_flags_tree,
1917                                        lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_PORT],
1918                                        tvb, offset2, 1, l);
1919                 proto_tree_add_boolean(lmp_flags_tree,
1920                                        lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_ALLOCATED],
1921                                        tvb, offset2, 1, l);
1922                 switch(type) {
1923                 case 1:
1924                     proto_item_append_text(ti, ": IPv4: Local %s, Remote %s",
1925                                            ip_to_str(tvb_get_ptr(tvb, offset2+4, 4)),
1926                                            ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
1927                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_IPV4],
1928                                         tvb, offset2+4, 4, FALSE);
1929                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_IPV4],
1930                                         tvb, offset2+8, 4, FALSE);
1931                     l = 12;
1932                     break;
1933                 case 2:
1934                     proto_item_append_text(ti, ": IPv6: Local %s, Remote %s",
1935                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)),
1936                                            ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+8, 16)));
1937                     proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 16,
1938                                         "Data-Link Local ID - IPv6: %s",
1939                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1940                     proto_tree_add_text(lmp_object_tree, tvb, offset2+20,16,
1941                                         "Data-Link Remote ID - IPv6: %s",
1942                                         ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)));
1943                     l = 36;
1944                     break;
1945                 case 3:
1946                     proto_item_append_text(ti, ": Unnumbered: Local %d, Remote %d",
1947                                            tvb_get_ntohl(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8));
1948                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_UNNUM],
1949                                         tvb, offset2+4, 4, FALSE);
1950                     proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_UNNUM],
1951                                         tvb, offset2+8, 4, FALSE);
1952                     l = 12;
1953                     break;
1954                 default:
1955                     proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1956                                         "Data (%d bytes)", mylen);
1957                     break;
1958                 }
1959
1960                 while (l < obj_length - 4) {
1961                     mylen = tvb_get_guint8(tvb, offset2+l+1);
1962                     ti2 = proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ],
1963                                               tvb, offset2+l, mylen, FALSE);
1964                     lmp_subobj_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_DATA_LINK_SUBOBJ]);
1965                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 1,
1966                                         "Subobject Type: %d", tvb_get_guint8(tvb, offset2+l));
1967                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+1, 1,
1968                                         "Subobject Length: %d", mylen);
1969                     switch(tvb_get_guint8(tvb, offset2+l)) {
1970                     case 1:
1971                         proto_item_set_text(ti2, "Interface Switching Capability: "
1972                                             "Switching Cap: %s, Encoding Type: %s, Min BW: %.10g, Max BW: %.10g",
1973                                             val_to_str(tvb_get_guint8(tvb, offset2+l+2),
1974                                                        gmpls_switching_type_str, "Unknown (%d)"),
1975                                             val_to_str(tvb_get_guint8(tvb, offset2+l+3),
1976                                                        gmpls_lsp_enc_str, "Unknown (%d)"),
1977                                             tvb_get_ntohieee_float(tvb, offset2+l+4),
1978                                             tvb_get_ntohieee_float(tvb, offset2+l+8));
1979                         proto_tree_add_item(lmp_subobj_tree,
1980                                             lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_SWITCHING_TYPE],
1981                                             tvb, offset2+l+2, 1, FALSE);
1982                         proto_tree_add_item(lmp_subobj_tree,
1983                                             lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_LSP_ENCODING],
1984                                             tvb, offset2+l+3, 1, FALSE);
1985                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+4, 4,
1986                                             "Minimum Reservable Bandwidth: %.10g bytes/s",
1987                                             tvb_get_ntohieee_float(tvb, offset2+l+4));
1988                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+8, 4,
1989                                             "Maximum Reservable Bandwidth: %.10g bytes/s",
1990                                             tvb_get_ntohieee_float(tvb, offset2+l+8));
1991                         break;
1992
1993                     case 2:
1994                         proto_item_set_text(ti2, "Wavelength: %d",
1995                                             tvb_get_ntohl(tvb, offset2+l+2));
1996                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+4, 4,
1997                                             "Wavelength: %d",
1998                                             tvb_get_ntohl(tvb, offset2+l+2));
1999                         break;
2000                             
2001                     default:
2002                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l,
2003                                             tvb_get_guint8(tvb, offset2+l+1),
2004                                             "Data (%d bytes)", tvb_get_guint8(tvb, offset2+l+1));
2005                         break;
2006                     }
2007                     l += tvb_get_guint8(tvb, offset2+l+1);
2008                 }
2009                 break;
2010
2011             case LMP_CLASS_CHANNEL_STATUS:
2012                 k = 0; j = 0;
2013                 switch(type) {
2014                 case 1:
2015                 case 3:
2016                     k = 8; break;
2017                 case 2:
2018                     k = 20; break;
2019                 }
2020                 if (!k)
2021                     break;
2022                 for (l=0; l<obj_length - 4; ) {
2023                     ti2 = proto_tree_add_text(lmp_object_tree, tvb, offset2+l, k,
2024                                               "Interface-Id");
2025                     lmp_subobj_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_CHANNEL_STATUS_ID]);
2026                     switch(type) {
2027                     case 1:
2028                         if (j < 4)
2029                             proto_item_append_text(ti, ": [IPv4-%s",
2030                                                    ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
2031                         proto_item_append_text(ti2, ": IPv4 %s",
2032                                                ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
2033                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
2034                                             "Interface ID: IPv4: %s",
2035                                             ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
2036                         l += 4;
2037                         break;
2038                     case 2:
2039                         if (j < 4)
2040                             proto_item_append_text(ti, ": [IPv6-%s",
2041                                                    ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
2042                         proto_item_append_text(ti2, ": IPv6 %s",
2043                                                ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
2044                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2, 16, "Interface ID: IPv6: %s",
2045                                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
2046                         l += 16;
2047                         break;
2048                     case 3:
2049                         if (j < 4)
2050                             proto_item_append_text(ti, ": [Unnum-%d", tvb_get_ntohl(tvb, offset2+l));
2051                         proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2+l));
2052                         proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
2053                                             "Interface ID: Unnumbered: %d",
2054                                             tvb_get_ntohl(tvb, offset2+l));
2055                         l += 4;
2056                         break;
2057                     default:
2058                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, obj_length-4-l,
2059                                             "Data (%d bytes)", obj_length-4-l);
2060                         l = obj_length - 4;
2061                         break;
2062                     }
2063                     if (l == obj_length - 4) break;
2064
2065                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 1,
2066                                         tvb_get_guint8(tvb, offset2+l) & 0x80 ?
2067                                         "Link Allocated - Active Monitoring" :
2068                                         "Link Not Allocated");
2069                     if (j < 4)
2070                         proto_item_append_text(ti, "-%s,%s], ",
2071                                                tvb_get_guint8(tvb, offset2+l) & 0x80 ? "Act" : "NA",
2072                                                val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
2073                                                           channel_status_short_str, "UNK (%u)."));
2074                     proto_item_append_text(ti2, ": %s, ",
2075                                            tvb_get_guint8(tvb, offset2+l) & 0x80 ? "Active" : "Not Active");
2076                     proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
2077                                         "Channel Status: %s",
2078                                         val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
2079                                                    channel_status_str, "Unknown (%u). "));
2080                     proto_item_append_text(ti2, val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
2081                                                            channel_status_str, "Unknown (%u). "));
2082                     j++;
2083                     l += 4;
2084                     if (j==4 && l < obj_length - 4)
2085                         proto_item_append_text(ti, " ...");
2086                 }
2087                 break;
2088
2089             case LMP_CLASS_CHANNEL_STATUS_REQUEST:
2090                 for (l=0; l<obj_length - 4; ) {
2091                     switch(type) {
2092                     case 1:
2093                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 4,
2094                                             "Interface ID: IPv4: %s",
2095                                             ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
2096                         l += 4;
2097                         break;
2098                     case 2:
2099                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 16, "Interface ID: IPv6: %s",
2100                                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l,16)));
2101                         l += 16;
2102                         break;
2103                     case 3:
2104                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 4,
2105                                             "Interface ID: Unnumbered: %d",
2106                                             tvb_get_ntohl(tvb, offset2+l));
2107                         l += 4;
2108                         break;
2109                     default:
2110                         proto_tree_add_text(lmp_object_tree, tvb, offset2+l, obj_length-4-l,
2111                                             "Data (%d bytes)", obj_length-4-l);
2112                         l = obj_length - 4;
2113                         break;
2114                     }
2115                 }
2116                 break;
2117
2118             case LMP_CLASS_ERROR:
2119                 l = tvb_get_ntohl(tvb, offset2);
2120                 ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_ERROR],
2121                                           tvb, offset2, 4, l);
2122
2123                 /* Errors are different in draft-02 and draft-03 */
2124                 switch(lmp_draft_ver) {
2125                 case LMP_VER_DRAFT_CCAMP_02:
2126                     switch(type) {
2127                     case 1:
2128                         proto_item_append_text(ti, ": CONFIG_ERROR: %s%s%s",
2129                                                (l&0x01) ? "Unacceptable-Params " : "",
2130                                                (l&0x02) ? "Renegotiate" : "",
2131                                                (l&0x04) ? "Bad Received CCID" : "");
2132                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
2133                         proto_tree_add_boolean(lmp_flags_tree,
2134                                                lmp_filter[LMPF_VAL_ERROR_CONFIG_BAD_PARAMETERS],
2135                                                tvb, offset, 4, l);
2136                         proto_tree_add_boolean(lmp_flags_tree,
2137                                                lmp_filter[LMPF_VAL_ERROR_CONFIG_RENEGOTIATE],
2138                                                tvb, offset, 4, l);
2139                         proto_tree_add_boolean(lmp_flags_tree,
2140                                                lmp_filter[LMPF_VAL_ERROR_CONFIG_BAD_CCID],
2141                                                tvb, offset, 4, l);
2142                         break;
2143                     case 2:
2144                         proto_item_append_text(ti, ": BEGIN_VERIFY_ERROR: %s%s%s%s",
2145                                                (l&0x01) ? "Unsupported-Link " : "",
2146                                                (l&0x02) ? "Unwilling" : "",
2147                                                (l&0x04) ? "Unsupported-Transport" : "",
2148                                                (l&0x08) ? "TE-Link-ID" : "");
2149                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
2150                         proto_tree_add_boolean(lmp_flags_tree,
2151                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_UNSUPPORTED_LINK],
2152                                                tvb, offset, 4, l);
2153                         proto_tree_add_boolean(lmp_flags_tree,
2154                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_UNWILLING],
2155                                                tvb, offset, 4, l);
2156                         proto_tree_add_boolean(lmp_flags_tree,
2157                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_TRANSPORT],
2158                                                tvb, offset, 4, l);
2159                         proto_tree_add_boolean(lmp_flags_tree,
2160                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_TE_LINK_ID],
2161                                                tvb, offset, 4, l);
2162                         break;
2163                     case 3:
2164                         proto_item_append_text(ti, ": LINK_SUMMARY_ERROR: %s%s%s",
2165                                                (l&0x01) ? "Unacceptable-Params " : "",
2166                                                (l&0x02) ? "Renegotiate" : "",
2167                                                (l&0x04) ? "Remote-Link-ID" : "");
2168
2169
2170                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
2171                         proto_tree_add_boolean(lmp_flags_tree,
2172                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_PARAMETERS],
2173                                                tvb, offset, 4, l);
2174                         proto_tree_add_boolean(lmp_flags_tree,
2175                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_RENEGOTIATE],
2176                                                tvb, offset, 4, l);
2177                         proto_tree_add_boolean(lmp_flags_tree,
2178                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_REMOTE_LINK_ID],
2179                                                tvb, offset, 4, l);
2180                         break;
2181
2182                     default:
2183                         proto_item_append_text(ti, ": UNKNOWN_ERROR (%d): 0x%04x", type, l);
2184                         proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
2185                                             "Data (%d bytes)", mylen);
2186                         break;
2187                     }
2188                     break;
2189                 default:
2190                 case LMP_VER_DRAFT_CCAMP_03:
2191                     switch(type) {
2192                     case 1:
2193                         proto_item_append_text(ti, ": BEGIN_VERIFY_ERROR: %s%s%s%s",
2194                                                (l&0x01) ? "Unsupported-Link " : "",
2195                                                (l&0x02) ? "Unwilling" : "",
2196                                                (l&0x04) ? "Unsupported-Transport" : "",
2197                                                (l&0x08) ? "TE-Link-ID" : "");
2198                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
2199                         proto_tree_add_boolean(lmp_flags_tree,
2200                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_UNSUPPORTED_LINK],
2201                                                tvb, offset, 4, l);
2202                         proto_tree_add_boolean(lmp_flags_tree,
2203                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_UNWILLING],
2204                                                tvb, offset, 4, l);
2205                         proto_tree_add_boolean(lmp_flags_tree,
2206                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_TRANSPORT],
2207                                                tvb, offset, 4, l);
2208                         proto_tree_add_boolean(lmp_flags_tree,
2209                                                lmp_filter[LMPF_VAL_ERROR_VERIFY_TE_LINK_ID],
2210                                                tvb, offset, 4, l);
2211                         break;
2212                     case 2:
2213                         proto_item_append_text(ti, ": LINK_SUMMARY_ERROR: %s%s%s%s%s",
2214                                                (l&0x01) ? "Unacceptable-Params " : "",
2215                                                (l&0x02) ? "Renegotiate" : "",
2216                                                (l&0x04) ? "Remote-Link-ID" : "",
2217                                                (l&0x08) ? "TE-Link" : "",
2218                                                (l&0x10) ? "Data-Link" : "");
2219
2220                         lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
2221                         proto_tree_add_boolean(lmp_flags_tree,
2222                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_PARAMETERS],
2223                                                tvb, offset, 4, l);
2224                         proto_tree_add_boolean(lmp_flags_tree,
2225                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_RENEGOTIATE],
2226                                                tvb, offset, 4, l);
2227                         proto_tree_add_boolean(lmp_flags_tree,
2228                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_REMOTE_LINK_ID],
2229                                                tvb, offset, 4, l);
2230                         proto_tree_add_boolean(lmp_flags_tree,
2231                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_TE_LINK],
2232                                                tvb, offset, 4, l);
2233                         proto_tree_add_boolean(lmp_flags_tree,
2234                                                lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_DATA_LINK],
2235                                                tvb, offset, 4, l);
2236                         break;
2237                     default:
2238                         proto_item_append_text(ti, ": UNKNOWN_ERROR (%d): 0x%04x", type, l);
2239                         proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
2240                                             "Data (%d bytes)", mylen);
2241                         break;
2242                     } /* switch type */
2243                     break;
2244                   } /* default case in ERROR object switch */
2245
2246               default:
2247                 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
2248                                     "Data (%d bytes)", mylen);
2249                 break;
2250             }
2251
2252           } /* LMP_VER_DRAFT_CCAMP_03 */
2253
2254           offset += obj_length;
2255           len += obj_length;
2256
2257         } /* while */
2258     } /* tree */
2259 }
2260
2261 static void
2262 lmp_prefs_applied (void)
2263 {
2264     if (lmp_udp_port != lmp_udp_port_config) {
2265         dissector_delete("udp.port", lmp_udp_port, lmp_handle);
2266         lmp_udp_port = lmp_udp_port_config;
2267         dissector_add("udp.port", lmp_udp_port, lmp_handle);
2268     }
2269 }    
2270
2271 static void
2272 register_lmp_prefs (void)
2273 {
2274     module_t *lmp_module;
2275     static enum_val_t lmp_ver[] = {
2276         {"draft-ietf-ccamp-lmp-09", LMP_VER_DRAFT_CCAMP_09},
2277         {"draft-ietf-ccamp-lmp-03", LMP_VER_DRAFT_CCAMP_03},
2278         {"draft-ietf-ccamp-lmp-02", LMP_VER_DRAFT_CCAMP_02},
2279         {NULL, -1}
2280     };
2281
2282     lmp_module = prefs_register_protocol(proto_lmp, lmp_prefs_applied);
2283     prefs_register_enum_preference(
2284         lmp_module, "version",
2285         "Draft version of LMP",
2286         "Specifies the IETF CCAMP draft version of LMP to interpret",
2287         &lmp_draft_ver, lmp_ver, FALSE);
2288     prefs_register_uint_preference(
2289         lmp_module, "udp_port", "LMP UDP Port (draft-09 ONLY)",
2290         "UDP port number to use for LMP (draft-09 only)", 10, &lmp_udp_port_config);
2291 }
2292
2293 void
2294 proto_register_lmp(void)
2295 {
2296     static gint *ett[NUM_LMP_SUBTREES];
2297     int i;
2298
2299     for (i=0; i<NUM_LMP_SUBTREES; i++) {
2300         lmp_subtree[i] = -1;
2301         ett[i] = &lmp_subtree[i];
2302     }
2303
2304     proto_lmp = proto_register_protocol("Link Management Protocol (LMP)",
2305                                             "LMP", "lmp");
2306     proto_register_field_array(proto_lmp, lmpf_info, array_length(lmpf_info));
2307     proto_register_subtree_array(ett, array_length(ett));
2308
2309     register_lmp_prefs();
2310 }
2311
2312 void
2313 proto_reg_handoff_lmp(void)
2314 {
2315     lmp_handle = create_dissector_handle(dissect_lmp, proto_lmp);
2316     dissector_add("udp.port", lmp_udp_port, lmp_handle);
2317     dissector_add("ip.proto", IP_PROTO_LMP, lmp_handle);
2318 }