2 * Routines for LMP packet disassembly
4 * (c) Copyright Ashok Narayanan <ashokn@cisco.com>
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
10 * Copyright 1998 Gerald Combs
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.
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.
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.
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.
33 * Support for LMP service discovery extensions added by Manu Pathak
34 * (mapathak@cisco.com), June 2005.
52 #include <epan/tvbuff.h>
53 #include <epan/packet.h>
55 #include <epan/in_cksum.h>
57 #include <epan/ipproto.h>
59 #include "packet-ip.h"
60 #include "packet-rsvp.h"
61 #include "packet-frame.h"
63 static int proto_lmp = -1;
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;
69 static dissector_handle_t lmp_handle;
71 /*----------------------------------------------------------------------
80 LMP_MSG_BEGIN_VERIFY_ACK,
81 LMP_MSG_BEGIN_VERIFY_NACK,
83 LMP_MSG_END_VERIFY_ACK,
85 LMP_MSG_TEST_STATUS_SUCCESS,
86 LMP_MSG_TEST_STATUS_FAILURE,
87 LMP_MSG_TEST_STATUS_ACK,
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
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. "},
127 /*------------------------------------------------------------------------------
130 #define LMP_CLASS_NULL 0
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
151 static value_string lmp_class_vals[] = {
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 " },
172 /*------------------------------------------------------------------------------
173 * Other constants & stuff
177 static const value_string channel_status_str[] = {
178 {1, "Signal Okay (OK)"},
179 {2, "Signal Degraded (SD)"},
180 {3, "Signal Failed (SF)"},
182 static const value_string channel_status_short_str[] = {
188 /* Service Discovery Client ServiceConfig object (defined in UNI 1.0) */
190 /* Client Port-Level Service Attribute Object */
193 static const value_string service_attribute_link_type_str[] = {
194 {5, "SDH ITU-T G.707"},
195 {6, "SONET ANSI T1.105"},
198 /* Signal Types for SDH */
199 static const value_string service_attribute_signal_types_sdh_str[] = {
210 /* Signal Types for SONET */
211 static const value_string service_attribute_signal_types_sonet_str[] = {
223 * These values are used by the code that handles the Service Discovery
224 * Client Port-Level Service Attributes Object.
226 #define LMP_CLASS_SERVICE_CONFIG_CPSA_SIGNAL_TYPES_SDH 5
227 #define LMP_CLASS_SERVICE_CONFIG_CPSA_SIGNAL_TYPES_SONET 6
229 /*------------------------------------------------------------------------------
233 enum lmp_filter_keys {
235 /* Message types ---------------- */
240 LMPF_MSG_CONFIG_NACK,
242 LMPF_MSG_BEGIN_VERIFY,
243 LMPF_MSG_BEGIN_VERIFY_ACK,
244 LMPF_MSG_BEGIN_VERIFY_NACK,
246 LMPF_MSG_END_VERIFY_ACK,
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,
264 /* LMP Message Header Fields ------------------ */
266 LMPF_HDR_FLAGS_CC_DOWN,
267 LMPF_HDR_FLAGS_REBOOT,
269 /* LMP Object Class Filters -------------------- */
275 LMPF_CLASS_INTERFACE_ID,
276 LMPF_CLASS_MESSAGE_ID,
279 LMPF_CLASS_BEGIN_VERIFY,
280 LMPF_CLASS_BEGIN_VERIFY_ACK,
281 LMPF_CLASS_VERIFY_ID,
283 LMPF_CLASS_DATA_LINK,
284 LMPF_CLASS_CHANNEL_STATUS,
285 LMPF_CLASS_CHANNEL_STATUS_REQUEST,
287 LMPF_CLASS_SERVICE_CONFIG,
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,
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,
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,
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,
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,
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,
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,
386 static int lmp_filter[LMPF_MAX];
388 static hf_register_info lmpf_info[] = {
390 /* Message type number */
391 {&lmp_filter[LMPF_MSG],
392 { "Message Type", "lmp.msg", FT_UINT8, BASE_DEC, VALS(message_type_vals), 0x0,
395 /* Message type shorthands */
396 {&lmp_filter[LMPF_MSG_CONFIG],
397 { "Config Message", "lmp.msg.config", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
400 {&lmp_filter[LMPF_MSG_CONFIG_ACK],
401 { "ConfigAck Message", "lmp.msg.configack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
404 {&lmp_filter[LMPF_MSG_CONFIG_NACK],
405 { "ConfigNack Message", "lmp.msg.confignack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
408 {&lmp_filter[LMPF_MSG_HELLO],
409 { "HELLO Message", "lmp.msg.hello", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
412 {&lmp_filter[LMPF_MSG_BEGIN_VERIFY],
413 { "BeginVerify Message", "lmp.msg.beginverify", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
416 {&lmp_filter[LMPF_MSG_BEGIN_VERIFY_ACK],
417 { "BeginVerifyAck Message", "lmp.msg.beginverifyack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
420 {&lmp_filter[LMPF_MSG_BEGIN_VERIFY_NACK],
421 { "BeginVerifyNack Message", "lmp.msg.beginverifynack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
424 {&lmp_filter[LMPF_MSG_END_VERIFY],
425 { "EndVerify Message", "lmp.msg.endverify", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
428 {&lmp_filter[LMPF_MSG_END_VERIFY_ACK],
429 { "EndVerifyAck Message", "lmp.msg.endverifyack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
432 {&lmp_filter[LMPF_MSG_TEST],
433 { "Test Message", "lmp.msg.test", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
436 {&lmp_filter[LMPF_MSG_TEST_STATUS_SUCCESS],
437 { "TestStatusSuccess Message", "lmp.msg.teststatussuccess", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
440 {&lmp_filter[LMPF_MSG_TEST_STATUS_FAILURE],
441 { "TestStatusFailure Message", "lmp.msg.teststatusfailure", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
444 {&lmp_filter[LMPF_MSG_TEST_STATUS_ACK],
445 { "TestStatusAck Message", "lmp.msg.teststatusack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
448 {&lmp_filter[LMPF_MSG_LINK_SUMMARY],
449 { "LinkSummary Message", "lmp.msg.linksummary", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
452 {&lmp_filter[LMPF_MSG_LINK_SUMMARY_ACK],
453 { "LinkSummaryAck Message", "lmp.msg.linksummaryack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
456 {&lmp_filter[LMPF_MSG_LINK_SUMMARY_NACK],
457 { "LinkSummaryNack Message", "lmp.msg.linksummarynack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
460 {&lmp_filter[LMPF_MSG_CHANNEL_STATUS],
461 { "ChannelStatus Message", "lmp.msg.channelstatus", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
464 {&lmp_filter[LMPF_MSG_CHANNEL_STATUS_ACK],
465 { "ChannelStatusAck Message", "lmp.msg.channelstatusack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
468 {&lmp_filter[LMPF_MSG_CHANNEL_STATUS_REQ],
469 { "ChannelStatusRequest Message", "lmp.msg.channelstatusrequest", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
472 {&lmp_filter[LMPF_MSG_CHANNEL_STATUS_RESP],
473 { "ChannelStatusResponse Message", "lmp.msg.channelstatusresponse", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
476 {&lmp_filter[LMPF_MSG_SERVICE_CONFIG],
477 { "ServiceConfig Message", "lmp.msg.serviceconfig", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
480 {&lmp_filter[LMPF_MSG_SERVICE_CONFIG_ACK],
481 { "ServiceConfigAck Message", "lmp.msg.serviceconfigack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
484 {&lmp_filter[LMPF_MSG_SERVICE_CONFIG_NACK],
485 { "ServiceConfigNack Message", "lmp.msg.serviceconfignack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
488 /* LMP Message Header Fields ------------------- */
490 {&lmp_filter[LMPF_HDR_FLAGS],
491 { "LMP Header - Flags", "lmp.hdr.flags", FT_UINT8, BASE_DEC, NULL, 0x0,
494 {&lmp_filter[LMPF_HDR_FLAGS_CC_DOWN],
495 { "ControlChannelDown", "lmp.hdr.ccdown", FT_BOOLEAN, 8, NULL, 0x01,
498 {&lmp_filter[LMPF_HDR_FLAGS_REBOOT],
499 { "Reboot", "lmp.hdr.reboot", FT_BOOLEAN, 8, NULL, 0x02,
502 /* LMP object class filters ------------------------------- */
504 {&lmp_filter[LMPF_OBJECT],
505 { "LOCAL_CCID", "lmp.object", FT_UINT8, BASE_DEC, NULL, 0x0,
508 {&lmp_filter[LMPF_CLASS_CCID],
509 { "CCID", "lmp.obj.ccid", FT_NONE, BASE_NONE, NULL, 0x0,
511 {&lmp_filter[LMPF_CLASS_NODE_ID],
512 { "NODE_ID", "lmp.obj.Nodeid", FT_NONE, BASE_NONE, NULL, 0x0,
514 {&lmp_filter[LMPF_CLASS_LINK_ID],
515 { "LINK_ID", "lmp.obj.linkid", FT_NONE, BASE_NONE, NULL, 0x0,
517 {&lmp_filter[LMPF_CLASS_INTERFACE_ID],
518 { "INTERFACE_ID", "lmp.obj.interfaceid", FT_NONE, BASE_NONE, NULL, 0x0,
520 {&lmp_filter[LMPF_CLASS_MESSAGE_ID],
521 { "MESSAGE_ID", "lmp.obj.messageid", FT_NONE, BASE_NONE, NULL, 0x0,
523 {&lmp_filter[LMPF_CLASS_CONFIG],
524 { "CONFIG", "lmp.obj.config", FT_NONE, BASE_NONE, NULL, 0x0,
526 {&lmp_filter[LMPF_CLASS_HELLO],
527 { "HELLO", "lmp.obj.hello", FT_NONE, BASE_NONE, NULL, 0x0,
529 {&lmp_filter[LMPF_CLASS_BEGIN_VERIFY],
530 { "BEGIN_VERIFY", "lmp.obj.begin_verify", FT_NONE, BASE_NONE, NULL, 0x0,
532 {&lmp_filter[LMPF_CLASS_BEGIN_VERIFY_ACK],
533 { "BEGIN_VERIFY_ACK", "lmp.obj.begin_verify_ack", FT_NONE, BASE_NONE, NULL, 0x0,
535 {&lmp_filter[LMPF_CLASS_VERIFY_ID],
536 { "VERIFY_ID", "lmp.obj.verifyid", FT_NONE, BASE_NONE, NULL, 0x0,
539 {&lmp_filter[LMPF_CLASS_TE_LINK],
540 { "TE_LINK", "lmp.obj.te_link", FT_NONE, BASE_NONE, NULL, 0x0,
542 {&lmp_filter[LMPF_CLASS_DATA_LINK],
543 { "DATA_LINK", "lmp.obj.data_link", FT_NONE, BASE_NONE, NULL, 0x0,
546 {&lmp_filter[LMPF_CLASS_CHANNEL_STATUS],
547 { "CHANNEL_STATUS", "lmp.obj.channel_status", FT_NONE, BASE_NONE, NULL, 0x0,
549 {&lmp_filter[LMPF_CLASS_CHANNEL_STATUS_REQUEST],
550 { "CHANNEL_STATUS_REQUEST", "lmp.obj.channel_status_request", FT_NONE, BASE_NONE, NULL, 0x0,
552 {&lmp_filter[LMPF_CLASS_ERROR],
553 { "ERROR", "lmp.obj.error", FT_NONE, BASE_NONE, NULL, 0x0,
556 {&lmp_filter[LMPF_CLASS_SERVICE_CONFIG],
557 { "SERVICE_CONFIG", "lmp.obj.serviceconfig", FT_NONE, BASE_NONE, NULL, 0x0,
560 /* Other LMP Value Filters ------------------------------ */
562 {&lmp_filter[LMPF_VAL_CTYPE],
563 { "Object C-Type", "lmp.obj.ctype", FT_UINT8, BASE_DEC, NULL, 0x0,
566 {&lmp_filter[LMPF_VAL_LOCAL_CCID],
567 { "Local CCID Value", "lmp.local_ccid", FT_UINT32, BASE_DEC, NULL, 0x0,
569 {&lmp_filter[LMPF_VAL_REMOTE_CCID],
570 { "Remote CCID Value", "lmp.remote_ccid", FT_UINT32, BASE_DEC, NULL, 0x0,
573 {&lmp_filter[LMPF_VAL_LOCAL_NODE_ID],
574 { "Local Node ID Value", "lmp.local_nodeid", FT_IPv4, BASE_NONE, NULL, 0x0,
576 {&lmp_filter[LMPF_VAL_REMOTE_NODE_ID],
577 { "Remote Node ID Value", "lmp.remote_nodeid", FT_IPv4, BASE_NONE, NULL, 0x0,
580 {&lmp_filter[LMPF_VAL_LOCAL_LINK_ID_IPV4],
581 { "Local Link ID - IPv4", "lmp.local_linkid_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
583 {&lmp_filter[LMPF_VAL_LOCAL_LINK_ID_UNNUM],
584 { "Local Link ID - Unnumbered", "lmp.local_linkid_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
586 {&lmp_filter[LMPF_VAL_REMOTE_LINK_ID_IPV4],
587 { "Remote Link ID - IPv4", "lmp.remote_linkid_ipv4", FT_UINT32, BASE_DEC, NULL, 0x0,
589 {&lmp_filter[LMPF_VAL_REMOTE_LINK_ID_UNNUM],
590 { "Remote Link ID - Unnumbered", "lmp.remote_linkid_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
593 {&lmp_filter[LMPF_VAL_LOCAL_INTERFACE_ID_IPV4],
594 { "Local Interface ID - IPv4", "lmp.local_interfaceid_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
596 {&lmp_filter[LMPF_VAL_LOCAL_INTERFACE_ID_UNNUM],
597 { "Local Interface ID - Unnumbered", "lmp.local_interfaceid_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
599 {&lmp_filter[LMPF_VAL_REMOTE_INTERFACE_ID_IPV4],
600 { "Remote Interface ID - IPv4", "lmp.remote_interfaceid_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
602 {&lmp_filter[LMPF_VAL_REMOTE_INTERFACE_ID_UNNUM],
603 { "Remote Interface ID - Unnumbered", "lmp.remote_interfaceid_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
606 {&lmp_filter[LMPF_VAL_MESSAGE_ID],
607 { "Message-ID Value", "lmp.messageid", FT_UINT32, BASE_DEC, NULL, 0x0,
609 {&lmp_filter[LMPF_VAL_MESSAGE_ID_ACK],
610 { "Message-ID Ack Value", "lmp.messageid_ack", FT_UINT32, BASE_DEC, NULL, 0x0,
613 {&lmp_filter[LMPF_VAL_CONFIG_HELLO],
614 { "HelloInterval", "lmp.hellointerval", FT_UINT32, BASE_DEC, NULL, 0x0,
616 {&lmp_filter[LMPF_VAL_CONFIG_HELLO_DEAD],
617 { "HelloDeadInterval", "lmp.hellodeadinterval", FT_UINT32, BASE_DEC, NULL, 0x0,
620 {&lmp_filter[LMPF_VAL_HELLO_TXSEQ],
621 { "TxSeqNum", "lmp.txseqnum", FT_UINT32, BASE_DEC, NULL, 0x0,
623 {&lmp_filter[LMPF_VAL_HELLO_RXSEQ],
624 { "RxSeqNum", "lmp.rxseqnum", FT_UINT32, BASE_DEC, NULL, 0x0,
627 {&lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS],
628 { "Flags", "lmp.begin_verify.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
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,
639 {&lmp_filter[LMPF_VAL_VERIFY_ID],
640 { "Verify-ID", "lmp.verifyid", FT_UINT32, BASE_DEC, NULL, 0x0,
643 {&lmp_filter[LMPF_VAL_TE_LINK_FLAGS],
644 { "TE-Link Flags", "lmp.te_link_flags", FT_UINT8, BASE_HEX, NULL, 0x0,
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,
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,
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,
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,
665 {&lmp_filter[LMPF_VAL_DATA_LINK_FLAGS],
666 { "Data-Link Flags", "lmp.data_link_flags", FT_UINT8, BASE_HEX, NULL, 0x0,
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,
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,
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,
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,
686 {&lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ],
687 { "Subobject", "lmp.data_link_subobj", FT_NONE, BASE_DEC, NULL, 0x0,
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 }},
696 {&lmp_filter[LMPF_VAL_ERROR],
697 { "Error Code", "lmp.error", FT_UINT32, BASE_HEX, NULL, 0x0,
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 }},
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 }},
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 }},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
828 {&lmp_filter[LMPF_VAL_SERVICE_CONFIG_NSA_TCM_FLAGS],
830 "lmp.service_config.nsa.tcm",
831 FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},
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}},
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}},
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}},
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}},
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}},
861 lmp_valid_class(int class)
863 /* Contiguous classes */
864 if (class > LMP_CLASS_NULL && class <= LMP_LAST_CONTIGUOUS_CLASS)
867 /* Noncontiguous classes */
868 if (class == LMP_CLASS_ERROR ||
869 class == LMP_CLASS_SERVICE_CONFIG)
876 lmp_class_to_filter_num(int class)
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.
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;
902 case LMP_CLASS_ERROR:
903 return LMPF_CLASS_ERROR;
905 case LMP_CLASS_SERVICE_CONFIG:
906 return LMPF_CLASS_SERVICE_CONFIG;
914 /*------------------------------------------------------------------------------
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
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,
942 #define NUM_LMP_SUBTREES (LMP_TREE_CLASS_START + LMP_CLASS_MAX)
944 static gint lmp_subtree[NUM_LMP_SUBTREES];
946 static int lmp_class_to_subtree(int class)
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];
953 return lmp_subtree[LMP_TREE_CLASS_START + class];
958 /*------------------------------------------------------------------------------
963 dissect_lmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
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;
977 guint16 cksum, computed_cksum;
986 proto = pinfo->ipproto;
988 /* Only process UDP packets */
989 if (proto != IP_PROTO_UDP) {
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);
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). "));
1007 msg_length = tvb_get_ntohs(tvb, offset+4);
1008 ti = proto_tree_add_item(tree, proto_lmp, tvb, offset, msg_length,
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",
1017 ti = proto_tree_add_text(lmp_header_tree, tvb, offset+2, 1, "Flags: %02x",
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",
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,
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);
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);
1048 if (computed_cksum == 0) {
1049 proto_tree_add_text(lmp_header_tree, tvb, offset+6, 2,
1050 "Message Checksum: 0x%04x (correct)",
1053 proto_tree_add_text(lmp_header_tree, tvb, offset+6, 2,
1054 "Message Checksum: 0x%04x (incorrect, should be 0x%04x)",
1056 in_cksum_shouldbe(cksum, computed_cksum));
1059 proto_tree_add_text(lmp_header_tree, tvb, offset+6, 2,
1060 "Message Checksum: 0x%04x",
1066 while (len < msg_length) {
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],
1080 if (lmp_valid_class(class)) {
1082 ti = proto_tree_add_item(lmp_tree,
1083 lmp_filter[lmp_class_to_filter_num(class)],
1084 tvb, offset, obj_length, FALSE);
1086 proto_tree_add_protocol_format(lmp_tree, proto_malformed, tvb,
1088 "Invalid class: %u", class);
1089 return tvb_length(tvb);
1091 lmp_object_tree = proto_item_add_subtree(ti, lmp_class_to_subtree(class));
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");
1098 lmp_object_header_tree =
1099 proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_OBJECT_HEADER]);
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);
1111 mylen = obj_length - 4;
1115 case LMP_CLASS_NULL:
1118 case LMP_CLASS_CCID:
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));
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));
1134 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1135 "Data (%d bytes)", mylen);
1140 case LMP_CLASS_NODE_ID:
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,
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,
1160 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1161 "Data (%d bytes)", mylen);
1166 case LMP_CLASS_LINK_ID:
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,
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)));
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,
1200 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1201 "Data (%d bytes)", mylen);
1206 case LMP_CLASS_INTERFACE_ID:
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,
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)));
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,
1241 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1242 "Data (%d bytes)", mylen);
1247 case LMP_CLASS_MESSAGE_ID:
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));
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));
1267 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1268 "Data (%d bytes)", mylen);
1273 case LMP_CLASS_CONFIG:
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],
1287 tvb_get_ntohs(tvb, offset2+2));
1291 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1292 "Data (%d bytes)", mylen);
1297 case LMP_CLASS_HELLO:
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],
1308 tvb_get_ntohl(tvb, offset2));
1309 proto_tree_add_uint(lmp_object_tree,
1310 lmp_filter[LMPF_VAL_HELLO_RXSEQ],
1312 tvb_get_ntohl(tvb, offset2+4));
1316 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1317 "Data (%d bytes)", mylen);
1322 case LMP_CLASS_BEGIN_VERIFY:
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);
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,
1357 tvb_get_ntohl(tvb, offset2+16));
1361 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1362 "Data (%d bytes)", mylen);
1367 case LMP_CLASS_BEGIN_VERIFY_ACK:
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));
1384 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1385 "Data (%d bytes)", mylen);
1390 case LMP_CLASS_VERIFY_ID:
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],
1400 tvb_get_ntohl(tvb, offset2));
1403 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1404 "Data (%d bytes)", mylen);
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);
1415 proto_item_append_text(ti2, ": %s%s",
1416 (l&0x01) ? "Fault-Mgmt-Supported " : "",
1417 (l&0x02) ? "Link-Verification-Supported " : "");
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);
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);
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)));
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));
1458 proto_tree_add_item(lmp_object_tree,
1459 lmp_filter[LMPF_VAL_TE_LINK_LOCAL_UNNUM],
1460 tvb, offset2+4, 4, FALSE);
1462 proto_tree_add_item(lmp_object_tree,
1463 lmp_filter[LMPF_VAL_TE_LINK_REMOTE_UNNUM],
1464 tvb, offset2+8, 4, FALSE);
1467 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1468 "Data (%d bytes)", mylen);
1473 case LMP_CLASS_DATA_LINK:
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 ");
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);
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)));
1498 proto_tree_add_item(lmp_object_tree,
1499 lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_IPV4],
1500 tvb, offset2+4, 4, FALSE);
1502 proto_tree_add_item(lmp_object_tree,
1503 lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_IPV4],
1504 tvb, offset2+8, 4, FALSE);
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)));
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);
1534 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
1535 "Data (%d bytes)", mylen);
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));
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)) {
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));
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,
1584 tvb_get_ntohl(tvb, offset2+l+4));
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));
1593 if (tvb_get_guint8(tvb, offset2+l+1) < 1)
1594 THROW(ReportedBoundsError);
1595 l += tvb_get_guint8(tvb, offset2+l+1);
1600 case LMP_CLASS_CHANNEL_STATUS:
1617 for (l=0; l<obj_length - 4; ) {
1619 ti2 = proto_tree_add_text(lmp_object_tree, tvb, offset2+l, k,
1621 lmp_subobj_tree = proto_item_add_subtree(ti2,
1622 lmp_subtree[LMP_TREE_CHANNEL_STATUS_ID]);
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)));
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)));
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));
1661 proto_tree_add_text(lmp_object_tree, tvb, offset2+l, obj_length-4-l,
1662 "Data (%d bytes)", obj_length-4-l);
1666 if (l == obj_length - 4) break;
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");
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). "));
1687 if (j==4 && l < obj_length - 4)
1688 proto_item_append_text(ti, " ...");
1692 case LMP_CLASS_CHANNEL_STATUS_REQUEST:
1693 for (l=0; l<obj_length - 4; ) {
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)));
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)));
1709 proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 4,
1710 "Interface ID: Unnumbered: %d",
1711 tvb_get_ntohl(tvb, offset2+l));
1716 proto_tree_add_text(lmp_object_tree, tvb, offset2+l,
1718 "Data (%d bytes)", obj_length-4-l);
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);
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],
1743 proto_tree_add_boolean(lmp_flags_tree,
1744 lmp_filter[LMPF_VAL_ERROR_VERIFY_UNWILLING],
1746 proto_tree_add_boolean(lmp_flags_tree,
1747 lmp_filter[LMPF_VAL_ERROR_VERIFY_TRANSPORT],
1749 proto_tree_add_boolean(lmp_flags_tree,
1750 lmp_filter[LMPF_VAL_ERROR_VERIFY_TE_LINK_ID],
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],
1767 proto_tree_add_boolean(lmp_flags_tree,
1768 lmp_filter[LMPF_VAL_ERROR_SUMMARY_RENEGOTIATE],
1770 proto_tree_add_boolean(lmp_flags_tree,
1771 lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_TE_LINK],
1773 proto_tree_add_boolean(lmp_flags_tree,
1774 lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_DATA_LINK],
1776 proto_tree_add_boolean(lmp_flags_tree,
1777 lmp_filter[LMPF_VAL_ERROR_SUMMARY_UNKNOWN_TEL_CTYPE],
1779 proto_tree_add_boolean(lmp_flags_tree,
1780 lmp_filter[LMPF_VAL_ERROR_SUMMARY_UNKNOWN_DL_CTYPE],
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);
1792 case LMP_CLASS_SERVICE_CONFIG:
1794 /* Support for the ServiceConfig object defined in the UNI 1.0 spec */
1798 /* Supported Signaling Protocols Object */
1800 /* Signaling Protocols */
1801 l = tvb_get_guint8(tvb, offset2);
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 " : "");
1810 lmp_flags_tree = proto_item_add_subtree(ti2,
1811 lmp_subtree[LMP_TREE_SERVICE_CONFIG_SP_FLAGS]);
1813 proto_tree_add_boolean(lmp_flags_tree,
1814 lmp_filter[LMPF_VAL_SERVICE_CONFIG_SP_FLAGS_RSVP],
1815 tvb, offset2, 1, l);
1817 proto_tree_add_boolean(lmp_flags_tree,
1818 lmp_filter[LMPF_VAL_SERVICE_CONFIG_SP_FLAGS_LDP],
1819 tvb, offset2, 1, l);
1822 proto_tree_add_text(lmp_object_tree, tvb, offset2+1, 1,
1824 tvb_get_guint8(tvb, offset2+1));
1828 /* Client Port-Level Service Attributes Object */
1831 proto_tree_add_text(lmp_object_tree, tvb, offset2, 1,
1833 val_to_str(tvb_get_guint8(tvb, offset2),
1834 service_attribute_link_type_str,
1837 proto_item_append_text(lmp_object_tree,
1838 val_to_str(tvb_get_guint8(tvb, offset2),
1839 service_attribute_link_type_str,
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,
1848 val_to_str(tvb_get_guint8(tvb, offset2+1),
1849 service_attribute_signal_types_sdh_str,
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,
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,
1862 val_to_str(tvb_get_guint8(tvb, offset2+1),
1863 service_attribute_signal_types_sonet_str,
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,
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);
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 " : "");
1883 lmp_flags_tree = proto_item_add_subtree(ti2,
1884 lmp_subtree[LMP_TREE_SERVICE_CONFIG_CPSA_TP_FLAGS]);
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);
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);
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);
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);
1904 lmp_flags_tree = proto_item_add_subtree(ti2,
1905 lmp_subtree[LMP_TREE_SERVICE_CONFIG_CPSA_CCT_FLAGS]);
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);
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));
1916 proto_tree_add_uint(lmp_object_tree,
1917 lmp_filter[LMPF_VAL_SERVICE_CONFIG_CPSA_MIN_NCC],
1919 tvb_get_ntohs(tvb, offset2+4));
1921 proto_tree_add_uint(lmp_object_tree,
1922 lmp_filter[LMPF_VAL_SERVICE_CONFIG_CPSA_MAX_NCC],
1924 tvb_get_ntohs(tvb, offset2+6));
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));
1931 proto_tree_add_uint(lmp_object_tree,
1932 lmp_filter[LMPF_VAL_SERVICE_CONFIG_CPSA_MIN_NVC],
1934 tvb_get_ntohs(tvb, offset2+8));
1936 proto_tree_add_uint(lmp_object_tree,
1937 lmp_filter[LMPF_VAL_SERVICE_CONFIG_CPSA_MAX_NVC],
1939 tvb_get_ntohs(tvb, offset2+10));
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)));
1945 proto_tree_add_item(lmp_object_tree,
1946 lmp_filter[LMPF_VAL_SERVICE_CONFIG_CPSA_INTERFACE_ID],
1947 tvb, offset2+12, 4, FALSE);
1953 /* Network Transparency Support and TCM Monitoring Object */
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);
1961 proto_item_append_text(ti2, ": %s %s",
1962 (l & 0x01) ? "Standard SOH/RSOH transparency supported " : "",
1963 (l & 0x02) ? "Standard LOH/MSOH transparency supported " : "");
1965 lmp_flags_tree = proto_item_add_subtree(ti2,
1966 lmp_subtree[LMP_TREE_SERVICE_CONFIG_NSA_TRANSPARENCY_FLAGS]);
1968 proto_tree_add_boolean(lmp_flags_tree,
1969 lmp_filter[LMPF_VAL_SERVICE_CONFIG_NSA_TRANSPARENCY_FLAGS_SOH],
1970 tvb, offset2, 4, l);
1972 proto_tree_add_boolean(lmp_flags_tree,
1973 lmp_filter[LMPF_VAL_SERVICE_CONFIG_NSA_TRANSPARENCY_FLAGS_LOH],
1974 tvb, offset2, 4, l);
1976 /* TCM Monitoring */
1977 l = tvb_get_guint8(tvb, offset2+7);
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);
1983 proto_item_append_text(ti2, ": %s",
1984 (l & 0x01) ? "Transparent Support of TCM available " : "");
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);
1994 /* Network Diversity Object */
1995 l = tvb_get_guint8(tvb,offset2+3);
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);
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 " : "");
2007 lmp_flags_tree = proto_item_add_subtree(ti2,
2008 lmp_subtree[LMP_TREE_SERVICE_CONFIG_NSA_NETWORK_DIVERSITY_FLAGS]);
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);
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);
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);
2024 /* Unknown type in Service Config object */
2025 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
2026 "Data (%d bytes)", mylen);
2031 proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
2032 "Data (%d bytes)", mylen);
2037 THROW(ReportedBoundsError);
2038 offset += obj_length;
2044 return tvb_length(tvb);
2047 lmp_prefs_applied (void)
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);
2057 register_lmp_prefs (void)
2059 module_t *lmp_module;
2061 lmp_module = prefs_register_protocol(proto_lmp, lmp_prefs_applied);
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");
2071 proto_register_lmp(void)
2073 static gint *ett[NUM_LMP_SUBTREES];
2076 for (i=0; i<NUM_LMP_SUBTREES; i++) {
2077 lmp_subtree[i] = -1;
2078 ett[i] = &lmp_subtree[i];
2081 proto_lmp = proto_register_protocol("Link Management Protocol (LMP)",
2083 proto_register_field_array(proto_lmp, lmpf_info, array_length(lmpf_info));
2084 proto_register_subtree_array(ett, array_length(ett));
2086 register_lmp_prefs();
2090 proto_reg_handoff_lmp(void)
2092 lmp_handle = new_create_dissector_handle(dissect_lmp, proto_lmp);
2093 dissector_add("udp.port", lmp_udp_port, lmp_handle);