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