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