HACK: 2nd try to match RowsetProperties
[wireshark-wip.git] / epan / dissectors / packet-nlsp.c
blobb889e1bc0f9e5e824f4e1337618d258b77c7497c
1 /* packet-nlsp.c
2 * Routines for NetWare Link Services Protocol
4 * $Id$
6 * Based on ISIS dissector by Stuart Stanley <stuarts@mxmail.net>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "config.h"
29 #include <glib.h>
30 #include <epan/packet.h>
31 #include <epan/to_str.h>
32 #include "packet-ipx.h"
34 /* NLSP base header */
35 static int proto_nlsp = -1;
37 static int hf_nlsp_irpd = -1;
38 static int hf_nlsp_header_length = -1;
39 static int hf_nlsp_minor_version = -1;
40 static int hf_nlsp_nr = -1;
41 static int hf_nlsp_type = -1;
42 static int hf_nlsp_major_version = -1;
43 static int hf_nlsp_packet_length = -1;
44 static int hf_nlsp_hello_state = -1;
45 static int hf_nlsp_hello_multicast = -1;
46 static int hf_nlsp_hello_circuit_type = -1;
47 static int hf_nlsp_hello_holding_timer = -1;
48 static int hf_nlsp_hello_priority = -1;
49 static int hf_nlsp_lsp_sequence_number = -1;
50 static int hf_nlsp_lsp_checksum = -1;
51 static int hf_nlsp_lsp_p = -1;
52 static int hf_nlsp_lsp_attached_flag = -1;
53 static int hf_nlsp_lsp_lspdbol = -1;
54 static int hf_nlsp_lsp_router_type = -1;
55 static int hf_nlsp_lsp_link_info_clv_flags_cost_present = -1;
56 static int hf_nlsp_lsp_link_info_clv_flags_cost_metric = -1;
57 static int hf_nlsp_lsp_link_info_clv_flags_cost = -1;
59 static gint ett_nlsp = -1;
60 static gint ett_nlsp_hello_clv_area_addr = -1;
61 static gint ett_nlsp_hello_clv_neighbors = -1;
62 static gint ett_nlsp_hello_local_mtu = -1;
63 static gint ett_nlsp_hello_clv_unknown = -1;
64 static gint ett_nlsp_lsp_info = -1;
65 static gint ett_nlsp_lsp_clv_area_addr = -1;
66 static gint ett_nlsp_lsp_clv_mgt_info = -1;
67 static gint ett_nlsp_lsp_clv_link_info = -1;
68 static gint ett_nlsp_lsp_clv_svcs_info = -1;
69 static gint ett_nlsp_lsp_clv_ext_routes = -1;
70 static gint ett_nlsp_lsp_clv_unknown = -1;
71 static gint ett_nlsp_csnp_lsp_entries = -1;
72 static gint ett_nlsp_csnp_lsp_entry = -1;
73 static gint ett_nlsp_csnp_clv_unknown = -1;
74 static gint ett_nlsp_psnp_lsp_entries = -1;
75 static gint ett_nlsp_psnp_lsp_entry = -1;
76 static gint ett_nlsp_psnp_clv_unknown = -1;
78 #define PACKET_TYPE_MASK 0x1f
81 * See
83 * http://www.cisco.com/univercd/cc/td/doc/cisintwk/ito_doc/nlsp.htm
85 * for some information about Hello packets.
88 #define NLSP_TYPE_L1_HELLO 15
89 #define NLSP_TYPE_WAN_HELLO 17
90 #define NLSP_TYPE_L1_LSP 18
91 #define NLSP_TYPE_L1_CSNP 24
92 #define NLSP_TYPE_L1_PSNP 26
94 static const value_string nlsp_packet_type_vals[] = {
95 { NLSP_TYPE_L1_HELLO, "L1 Hello"},
96 { NLSP_TYPE_WAN_HELLO, "WAN Hello"},
97 { NLSP_TYPE_L1_LSP, "L1 LSP"},
98 { NLSP_TYPE_L1_CSNP, "L1 CSNP"},
99 { NLSP_TYPE_L1_PSNP, "L1 PSNP"},
100 { 0, NULL}
103 static const value_string nlsp_attached_flag_vals[] = {
104 { 0, "Other routing areas cannot be reached through this router"},
105 { 1, "Other routing areas can be reached through this router"},
106 { 0, NULL}
109 static const value_string nlsp_router_type_vals[] = {
110 { 1, "Level 1 Router"},
111 { 3, "Level 1 and Level 2 Router"},
112 { 0, NULL}
115 static const true_false_string tfs_internal_external = { "Internal", "External" };
118 * Our sub-packet dismantle structure for CLV's
120 typedef struct {
121 int optcode; /* code for option */
122 const char *tree_text; /* text for fold out */
123 gint *tree_id; /* id for add_item */
124 void (*dissect)(tvbuff_t *tvb, proto_tree *tree,
125 int offset, int length);
126 } nlsp_clv_handle_t;
129 * Name: nlsp_dissect_unknown()
131 * Description:
132 * There was some error in the protocol and we are in unknown space
133 * here. Add a tree item to cover the error and go on. Note
134 * that we make sure we don't go off the end of the bleedin packet here!
136 * Input
137 * tvbuff_t * : tvbuffer for packet data
138 * proto_tree * : tree of display data. May be NULL.
139 * int : current offset into packet data
140 * char * : format text
141 * subsequent args : arguments to format
143 * Output:
144 * void (may modify proto tree)
146 static void
147 nlsp_dissect_unknown(tvbuff_t *tvb, proto_tree *tree, int offset,
148 const char *fmat, ...)
150 va_list ap;
152 va_start(ap, fmat);
153 proto_tree_add_text_valist(tree, tvb, offset, -1, fmat, ap);
154 va_end(ap);
158 * Name: nlsp_dissect_clvs()
160 * Description:
161 * Dispatch routine to shred all the CLVs in a packet. We just
162 * walk through the clv entries in the packet. For each one, we
163 * search the passed in valid clv's for this protocol (opts) for
164 * a matching code. If found, we add to the display tree and
165 * then call the dissector. If it is not, we just post an
166 * "unknown" clv entry using the passed in unknown clv tree id.
167 * XXX: The "unknown tree id" is an 'ett' index for use
168 * when creating a subtree;
169 * Since the 'unknown' subtree was not actually used in the
170 * code below, what was the intention for this ?
171 * For now: code related to creating an 'unknown' subtrree
172 * disabled.
174 * Input:
175 * tvbuff_t * : tvbuffer for packet data
176 * proto_tree * : protocol display tree to fill out. May be NULL
177 * int : offset into packet data where we are.
178 * nlsp_clv_handle_t * : NULL dissector terminated array of codes
179 * and handlers (along with tree text and tree id's).
180 * int : length of CLV area.
181 * int : unknown clv tree id
183 * Output:
184 * void, but we will add to proto tree if !NULL.
186 static void
187 nlsp_dissect_clvs(tvbuff_t *tvb, proto_tree *tree, int offset,
188 const nlsp_clv_handle_t *opts, int len, int unknown_tree_id _U_)
190 guint8 code;
191 guint8 length;
192 int q;
193 proto_item *ti;
194 proto_tree *clv_tree;
196 while ( len > 0 ) {
197 code = tvb_get_guint8(tvb, offset);
198 offset += 1;
199 len -= 1;
200 if (len == 0)
201 break;
203 length = tvb_get_guint8(tvb, offset);
204 offset += 1;
205 len -= 1;
206 if (len == 0)
207 break;
209 if ( len < length ) {
210 nlsp_dissect_unknown(tvb, tree, offset,
211 "Short CLV header (%d vs %d)",
212 length, len );
213 return;
215 q = 0;
216 while ((opts[q].dissect != NULL )&&( opts[q].optcode != code )){
217 q++;
219 if ( opts[q].dissect ) {
220 if (tree) {
221 /* adjust by 2 for code/len octets */
222 ti = proto_tree_add_text(tree, tvb, offset - 2,
223 length + 2, "%s (%u)",
224 opts[q].tree_text, length );
225 clv_tree = proto_item_add_subtree(ti,
226 *opts[q].tree_id );
227 } else {
228 clv_tree = NULL;
230 opts[q].dissect(tvb, clv_tree, offset,
231 length);
232 } else {
233 if (tree) {
234 #if 0 /* XXX: ?? */
235 ti = proto_tree_add_text(tree, tvb, offset - 2,
236 length + 2, "Unknown code %u (%u)",
237 code, length);
238 clv_tree = proto_item_add_subtree(ti,
239 unknown_tree_id );
240 } else {
241 clv_tree = NULL;
242 #else
243 proto_tree_add_text(tree, tvb, offset - 2,
244 length + 2, "Unknown code %u (%u)",
245 code, length);
246 #endif
249 offset += length;
250 len -= length;
255 * Name: dissect_area_address_clv()
257 * Description:
258 * Decode an area address clv.
260 * Input:
261 * tvbuff_t * : tvbuffer for packet data
262 * proto_tree * : protocol display tree to fill out. May be NULL
263 * int : offset into packet data where we are.
264 * int : length of clv we are decoding
266 * Output:
267 * void, but we will add to proto tree if !NULL.
269 static void
270 dissect_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
271 int length)
273 while (length > 0) {
274 if (length < 4) {
275 nlsp_dissect_unknown(tvb, tree, offset,
276 "Short area address entry");
277 return;
279 if (tree) {
280 proto_tree_add_text(tree, tvb, offset, 4,
281 "Area address network number: 0x%08x",
282 tvb_get_ntohl(tvb, offset));
284 offset += 4;
285 length -= 4;
287 if (length < 4) {
288 nlsp_dissect_unknown(tvb, tree, offset,
289 "Short area address entry");
290 return;
292 if (tree) {
293 proto_tree_add_text(tree, tvb, offset, 4,
294 "Area address mask: 0x%08x",
295 tvb_get_ntohl(tvb, offset));
297 offset += 4;
298 length -= 4;
303 * Name: dissect_neighbor_clv()
305 * Description:
306 * Decode an neighbor clv.
308 * Input:
309 * tvbuff_t * : tvbuffer for packet data
310 * proto_tree * : protocol display tree to fill out. May be NULL
311 * int : offset into packet data where we are.
312 * int : length of clv we are decoding
314 * Output:
315 * void, but we will add to proto tree if !NULL.
317 static void
318 dissect_neighbor_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
319 int length)
321 while (length > 0) {
322 if (length < 6) {
323 nlsp_dissect_unknown(tvb, tree, offset,
324 "Short neighbor entry");
325 return;
327 if (tree) {
328 proto_tree_add_text(tree, tvb, offset, 6,
329 "Neighbor: %s",
330 tvb_ether_to_str(tvb, offset));
332 offset += 6;
333 length -= 6;
338 * Name: dissect_hello_local_mtu_clv()
340 * Description:
341 * Decode for a hello packet's local MTU clv.
343 * Input:
344 * tvbuff_t * : tvbuffer for packet data
345 * proto_tree * : protocol display tree to fill out. May be NULL
346 * int : offset into packet data where we are.
347 * int : length of clv we are decoding
349 * Output:
350 * void, but we will add to proto tree if !NULL.
352 static void
353 dissect_hello_local_mtu_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
354 int length)
356 if (length < 4) {
357 nlsp_dissect_unknown(tvb, tree, offset,
358 "Short link info entry");
359 return;
361 if (tree) {
362 proto_tree_add_text(tree, tvb, offset, 4,
363 "MTU Size: %u",
364 tvb_get_ntohl(tvb, offset));
368 static const nlsp_clv_handle_t clv_hello_opts[] = {
370 0xC0,
371 "Area address(es)",
372 &ett_nlsp_hello_clv_area_addr,
373 dissect_area_address_clv
377 "Neighbors",
378 &ett_nlsp_hello_clv_neighbors,
379 dissect_neighbor_clv
382 0xC5,
383 "Local MTU",
384 &ett_nlsp_hello_local_mtu,
385 dissect_hello_local_mtu_clv
391 NULL,
392 NULL
397 * Name: nlsp_dissect_nlsp_hello()
399 * Description:
400 * This procedure rips apart NLSP hellos.
402 * Input:
403 * tvbuff_t * : tvbuffer for packet data
404 * proto_tree * : protocol display tree to add to. May be NULL.
405 * int offset : our offset into packet data.
406 * int : hello type, a la NLSP_TYPE_* values
407 * int : header length of packet.
409 * Output:
410 * void, will modify proto_tree if not NULL.
412 #define NLSP_HELLO_CTYPE_MASK 0x03
413 #define NLSP_HELLO_STATE_MASK 0xC0
414 #define NLSP_HELLO_MULTICAST_MASK 0x10
416 static const value_string nlsp_hello_state_vals[] = {
417 { 0, "Up" },
418 { 1, "Initializing" },
419 { 2, "Down" },
420 { 0, NULL }
423 #define NLSP_HELLO_TYPE_RESERVED 0
424 #define NLSP_HELLO_TYPE_LEVEL_1 1
425 #define NLSP_HELLO_TYPE_LEVEL_2 2
426 #define NLSP_HELLO_TYPE_LEVEL_12 3
428 static const value_string nlsp_hello_circuit_type_vals[] = {
429 { NLSP_HELLO_TYPE_RESERVED, "Reserved 0 (discard PDU)"},
430 { NLSP_HELLO_TYPE_LEVEL_1, "Level 1 only"},
431 { NLSP_HELLO_TYPE_LEVEL_2, "Level 2 only"},
432 { NLSP_HELLO_TYPE_LEVEL_12, "Level 1 and 2"},
433 { 0, NULL}
436 #define NLSP_HELLO_PRIORITY_MASK 0x7f
438 static void
439 nlsp_dissect_nlsp_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
440 int offset, int hello_type, int header_length)
442 guint16 packet_length;
443 int len;
444 guint16 holding_timer;
446 if (tree) {
447 if (hello_type == NLSP_TYPE_WAN_HELLO) {
448 proto_tree_add_item(tree, hf_nlsp_hello_state, tvb,
449 offset, 1, ENC_BIG_ENDIAN);
450 } else {
451 proto_tree_add_item(tree, hf_nlsp_hello_multicast, tvb,
452 offset, 1, ENC_BIG_ENDIAN);
454 proto_tree_add_item(tree, hf_nlsp_hello_circuit_type, tvb,
455 offset, 1, ENC_BIG_ENDIAN);
457 offset += 1;
459 if (tree) {
460 proto_tree_add_text(tree, tvb, offset, 6,
461 "Sending Router System ID: %s",
462 tvb_ether_to_str(tvb, offset));
464 col_append_fstr(pinfo->cinfo, COL_INFO, ", System ID: %s",
465 tvb_ether_to_str(tvb, offset));
467 offset += 6;
469 if (tree) {
470 holding_timer = tvb_get_ntohs(tvb, offset);
471 proto_tree_add_uint_format_value(tree, hf_nlsp_hello_holding_timer,
472 tvb, offset, 2, holding_timer,
473 "%us", holding_timer);
475 offset += 2;
477 packet_length = tvb_get_ntohs(tvb, offset);
478 if (tree) {
479 proto_tree_add_uint(tree, hf_nlsp_packet_length, tvb,
480 offset, 2, packet_length);
482 offset += 2;
484 if (tree) {
485 proto_tree_add_item(tree, hf_nlsp_hello_priority, tvb,
486 offset, 1, ENC_BIG_ENDIAN);
488 offset += 1;
490 if (hello_type == NLSP_TYPE_WAN_HELLO) {
491 if (tree) {
492 proto_tree_add_text(tree, tvb, offset, 1,
493 "Local WAN Circuit ID: %u",
494 tvb_get_guint8(tvb, offset));
496 offset += 1;
497 } else {
498 if (tree) {
499 proto_tree_add_text(tree, tvb, offset, 6,
500 "Designated Router System ID: %s",
501 tvb_ether_to_str(tvb, offset));
502 proto_tree_add_text(tree, tvb, offset+6, 1,
503 "Designated Router Pseudonode ID: %u",
504 tvb_get_guint8(tvb, offset+6));
506 offset += 7;
509 len = packet_length - header_length;
510 if (len < 0) {
511 nlsp_dissect_unknown(tvb, tree, offset,
512 "packet header length %d went beyond packet",
513 header_length);
514 return;
518 * Now, we need to decode our CLVs. We need to pass in
519 * our list of valid ones!
521 nlsp_dissect_clvs(tvb, tree, offset,
522 clv_hello_opts, len, ett_nlsp_hello_clv_unknown);
526 * Name: dissect_lsp_mgt_info_clv()
528 * Description:
529 * Decode for a lsp packet's management information clv.
531 * Input:
532 * tvbuff_t * : tvbuffer for packet data
533 * proto_tree * : protocol display tree to fill out. May be NULL
534 * int : offset into packet data where we are.
535 * int : length of clv we are decoding
537 * Output:
538 * void, but we will add to proto tree if !NULL.
540 static void
541 dissect_lsp_mgt_info_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
542 int length)
544 guint8 name_length;
546 if (length < 4) {
547 nlsp_dissect_unknown(tvb, tree, offset,
548 "Short management info entry");
549 return;
551 if (tree) {
552 proto_tree_add_text(tree, tvb, offset, 4,
553 "Network number: 0x%08x",
554 tvb_get_ntohl(tvb, offset));
556 offset += 4;
557 length -= 4;
559 if (length < 6) {
560 nlsp_dissect_unknown(tvb, tree, offset,
561 "Short management info entry");
562 return;
564 if (tree) {
565 proto_tree_add_text(tree, tvb, offset, 6,
566 "Node number: %s",
567 tvb_ether_to_str(tvb, offset));
569 offset += 6;
570 length -= 6;
572 if (length < 1) {
573 nlsp_dissect_unknown(tvb, tree, offset,
574 "Short management info entry");
575 return;
577 if (tree) {
578 proto_tree_add_text(tree, tvb, offset, 1,
579 "IPX version number: %u",
580 tvb_get_guint8(tvb, offset));
582 offset += 1;
583 length -= 1;
585 if (length < 1) {
586 nlsp_dissect_unknown(tvb, tree, offset,
587 "Short management info entry");
588 return;
590 name_length = tvb_get_guint8(tvb, offset);
591 if (tree) {
592 proto_tree_add_text(tree, tvb, offset, 1,
593 "Name length: %u", name_length);
595 offset += 1;
596 length -= 1;
598 if (name_length != 0) {
599 if (length < name_length) {
600 nlsp_dissect_unknown(tvb, tree, offset,
601 "Short management info entry");
602 return;
604 if (tree) {
605 proto_tree_add_text(tree, tvb, offset, name_length,
606 "Name: %s",
607 tvb_format_text(tvb, offset, name_length));
613 * Name: dissect_lsp_link_info_clv()
615 * Description:
616 * Decode for a lsp packet's link information clv.
618 * Input:
619 * tvbuff_t * : tvbuffer for packet data
620 * proto_tree * : protocol display tree to fill out. May be NULL
621 * int : offset into packet data where we are.
622 * int : length of clv we are decoding
624 * Output:
625 * void, but we will add to proto tree if !NULL.
627 static const value_string media_type_vals[] = {
628 { 0x0000, "Generic LAN" },
629 { 0x8000, "Generic WAN" },
630 { 0x0001, "Localtalk" },
631 { 0x0002, "Ethernet II" },
632 { 0x0003, "IEEE 802.3 with IEEE 802.2 without SNAP" },
633 { 0x0005, "IEEE 802.3 with IPX header and no 802.2 header" },
634 { 0x000A, "IEEE 802.3 with IEEE 802.2 and SNAP" },
635 { 0x0004, "IEEE 802.5 with IEEE 802.2 without SNAP" },
636 { 0x000B, "IEEE 802.5 with IEEE 802.2 and SNAP" },
637 { 0x0006, "IEEE 802.4" },
638 { 0x0007, "IBM PC Network II" },
639 { 0x0008, "Gateway G/Net" },
640 { 0x0009, "Proteon ProNET" },
641 { 0x000C, "Racore LANPAC" },
642 { 0x800D, "ISDN" },
643 { 0x000E, "ARCnet" },
644 { 0x000F, "IBM PC Network II with 802.2 without SNAP" },
645 { 0x0010, "IBM PC Network II with 802.2 and SNAP" },
646 { 0x0011, "Corvus OmniNet at 4 Mbps" },
647 { 0x0012, "Harris Adacom" },
648 { 0x0013, "IP tunnel" },
649 { 0x8013, "IP Relay" },
650 { 0x0014, "FDDI with 802.2 without SNAP" },
651 { 0x0015, "Commtex IVDLAN" },
652 { 0x0016, "Dataco OSI" },
653 { 0x0017, "FDDI with 802.2 and SNAP" },
654 { 0x0018, "IBM SDLC tunnel" },
655 { 0x0019, "PC Office frame" },
656 { 0x001A, "Hypercommunications WAIDNET" },
657 { 0x801C, "PPP" },
658 { 0x801D, "Proxim RangeLAN" },
659 { 0x801E, "X.25" },
660 { 0x801F, "Frame Relay" },
661 { 0x0020, "Integrated Workstations BUS-NET" },
662 { 0x8021, "Novell SNA Links" },
663 { 0, NULL }
666 static void
667 dissect_lsp_link_info_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
668 int length)
670 guint8 flags_cost;
672 if (length < 1) {
673 nlsp_dissect_unknown(tvb, tree, offset,
674 "Short link info entry");
675 return;
677 if (tree) {
678 flags_cost = tvb_get_guint8(tvb, offset);
679 proto_tree_add_item(tree, hf_nlsp_lsp_link_info_clv_flags_cost_present, tvb, offset, 1, ENC_BIG_ENDIAN);
680 if (!(flags_cost & 0x80)) {
682 * 0x80 clear => cost present.
684 proto_tree_add_item(tree, hf_nlsp_lsp_link_info_clv_flags_cost_metric, tvb, offset, 1, ENC_BIG_ENDIAN);
685 proto_tree_add_item(tree, hf_nlsp_lsp_link_info_clv_flags_cost, tvb, offset, 1, ENC_BIG_ENDIAN);
688 offset += 1;
689 length -= 1;
691 if (length < 3) {
692 nlsp_dissect_unknown(tvb, tree, offset,
693 "Short link info entry");
694 return;
696 offset += 3; /* Reserved */
697 length -= 3;
699 if (length < 7) {
700 nlsp_dissect_unknown(tvb, tree, offset,
701 "Short link info entry");
702 return;
704 if (tree) {
705 proto_tree_add_text(tree, tvb, offset, 6,
706 "Router System ID: %s",
707 tvb_ether_to_str(tvb, offset));
708 proto_tree_add_text(tree, tvb, offset+6, 1,
709 "Router Pseudonode ID: %u",
710 tvb_get_guint8(tvb, offset+6));
712 offset += 7;
713 length -= 7;
715 if (length < 4) {
716 nlsp_dissect_unknown(tvb, tree, offset,
717 "Short link info entry");
718 return;
720 if (tree) {
721 proto_tree_add_text(tree, tvb, offset, 4,
722 "MTU Size: %u",
723 tvb_get_ntohl(tvb, offset));
725 offset += 4;
726 length -= 4;
728 if (length < 4) {
729 nlsp_dissect_unknown(tvb, tree, offset,
730 "Short link info entry");
731 return;
733 if (tree) {
734 proto_tree_add_text(tree, tvb, offset, 4,
735 "Delay: %uus",
736 tvb_get_ntohl(tvb, offset));
738 offset += 4;
739 length -= 4;
741 if (length < 4) {
742 nlsp_dissect_unknown(tvb, tree, offset,
743 "Short link info entry");
744 return;
746 if (tree) {
747 proto_tree_add_text(tree, tvb, offset, 4,
748 "Throughput: %u bits/s",
749 tvb_get_ntohl(tvb, offset));
751 offset += 4;
752 length -= 4;
754 if (length < 2) {
755 nlsp_dissect_unknown(tvb, tree, offset,
756 "Short link info entry");
757 return;
759 if (tree) {
760 proto_tree_add_text(tree, tvb, offset, 2,
761 "Media type: %s",
762 val_to_str(tvb_get_ntohs(tvb, offset), media_type_vals,
763 "Unknown (0x%04x)"));
768 * Name: dissect_lsp_svcs_info_clv()
770 * Description:
771 * Decode for a lsp packet's services information clv.
773 * Input:
774 * tvbuff_t * : tvbuffer for packet data
775 * proto_tree * : protocol display tree to fill out. May be NULL
776 * int : offset into packet data where we are.
777 * int : length of clv we are decoding
779 * Output:
780 * void, but we will add to proto tree if !NULL.
782 static void
783 dissect_lsp_svcs_info_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
784 int length)
786 if (length < 1) {
787 nlsp_dissect_unknown(tvb, tree, offset,
788 "Short services info entry");
789 return;
791 if (tree) {
792 proto_tree_add_text(tree, tvb, offset, 1,
793 "Hops to reach the service: %u",
794 tvb_get_guint8(tvb, offset));
796 offset += 1;
797 length -= 1;
799 if (length < 4) {
800 nlsp_dissect_unknown(tvb, tree, offset,
801 "Short services info entry");
802 return;
804 if (tree) {
805 proto_tree_add_text(tree, tvb, offset, 4,
806 "Network number: 0x%08x",
807 tvb_get_ntohl(tvb, offset));
809 offset += 4;
810 length -= 4;
812 if (length < 6) {
813 nlsp_dissect_unknown(tvb, tree, offset,
814 "Short services info entry");
815 return;
817 if (tree) {
818 proto_tree_add_text(tree, tvb, offset, 6,
819 "Node number: %s",
820 tvb_ether_to_str(tvb, offset));
822 offset += 6;
823 length -= 6;
825 if (length < 2) {
826 nlsp_dissect_unknown(tvb, tree, offset,
827 "Short services info entry");
828 return;
830 if (tree) {
831 proto_tree_add_text(tree, tvb, offset, 2,
832 "Socket: %s",
833 val_to_str_ext(tvb_get_ntohs(tvb, offset), &ipx_socket_vals_ext,
834 "Unknown (0x%04x)"));
836 offset += 2;
837 length -= 2;
839 if (length < 2) {
840 nlsp_dissect_unknown(tvb, tree, offset,
841 "Short services info entry");
842 return;
844 if (tree) {
845 proto_tree_add_text(tree, tvb, offset, 2,
846 "Type: %s",
847 val_to_str_ext(tvb_get_ntohs(tvb, offset), &novell_server_vals_ext,
848 "Unknown (0x%04x)"));
850 offset += 2;
851 length -= 2;
853 if (length > 0) {
854 if (tree) {
855 proto_tree_add_text(tree, tvb, offset, length,
856 "Service Name: %s",
857 tvb_format_text(tvb, offset, length));
864 * Name: dissect_lsp_ext_routes_clv()
866 * Description:
867 * Decode for a lsp packet's external routes clv.
869 * Input:
870 * tvbuff_t * : tvbuffer for packet data
871 * proto_tree * : protocol display tree to fill out. May be NULL
872 * int : offset into packet data where we are.
873 * int : length of clv we are decoding
875 * Output:
876 * void, but we will add to proto tree if !NULL.
878 static void
879 dissect_lsp_ext_routes_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
880 int length)
882 while (length > 0) {
883 if (length < 1) {
884 nlsp_dissect_unknown(tvb, tree, offset,
885 "Short external routes entry");
886 return;
888 if (tree) {
889 proto_tree_add_text(tree, tvb, offset, 1,
890 "Hops: %u",
891 tvb_get_guint8(tvb, offset));
893 offset += 1;
894 length -= 1;
896 if (length < 4) {
897 nlsp_dissect_unknown(tvb, tree, offset,
898 "Short external routes entry");
899 return;
901 if (tree) {
902 proto_tree_add_text(tree, tvb, offset, 4,
903 "Network number: 0x%08x",
904 tvb_get_ntohl(tvb, offset));
906 offset += 4;
907 length -= 4;
909 if (length < 2) {
910 nlsp_dissect_unknown(tvb, tree, offset,
911 "Short external routes entry");
912 return;
914 if (tree) {
915 proto_tree_add_text(tree, tvb, offset, 2,
916 "RIP delay: %u ticks",
917 tvb_get_ntohs(tvb, offset));
919 offset += 2;
920 length -= 2;
924 static const nlsp_clv_handle_t clv_l1_lsp_opts[] = {
926 0xC0,
927 "Area address(es)",
928 &ett_nlsp_lsp_clv_area_addr,
929 dissect_area_address_clv
932 0xC1,
933 "Management information",
934 &ett_nlsp_lsp_clv_mgt_info,
935 dissect_lsp_mgt_info_clv
938 0xC2,
939 "Link information",
940 &ett_nlsp_lsp_clv_link_info,
941 dissect_lsp_link_info_clv
944 0xC3,
945 "Services information",
946 &ett_nlsp_lsp_clv_svcs_info,
947 dissect_lsp_svcs_info_clv
950 0xC4,
951 "External routes",
952 &ett_nlsp_lsp_clv_ext_routes,
953 dissect_lsp_ext_routes_clv
959 NULL,
960 NULL
965 * Name: nlsp_dissect_nlsp_lsp()
967 * Description:
968 * Print out the LSP part of the main header and then call the CLV
969 * de-mangler with the right list of valid CLVs.
971 * Input:
972 * tvbuff_t * : tvbuffer for packet data
973 * proto_tree * : protocol display tree to add to. May be NULL.
974 * int offset : our offset into packet data.
975 * int : header length of packet.
977 * Output:
978 * void, but we will add to proto tree if !NULL.
980 /* P | ATT | OVERFLOW | ROUTER TYPE FIELD description */
981 #define NLSP_LSP_PARTITION_MASK 0x80
982 #define NLSP_LSP_PARTITION_SHIFT 7
983 #define NLSP_LSP_PARTITION(info) (((info) & NLSP_LSP_PARTITION_MASK) >> NLSP_LSP_PARTITION_SHIFT)
985 #define NLSP_LSP_ATT_MASK 0x78
986 #define NLSP_LSP_ATT_SHIFT 3
987 #define NLSP_LSP_ATT(info) (((info) & NLSP_LSP_ATT_MASK) >> NLSP_LSP_ATT_SHIFT)
989 #define NLSP_LSP_OVERFLOW_MASK 0x04
990 #define NLSP_LSP_OVERFLOW_SHIFT 2
991 #define NLSP_LSP_OVERFLOW(info) (((info) & NLSP_LSP_OVERFLOW_MASK) >> NLSP_LSP_OVERFLOW_SHIFT)
993 #define NLSP_LSP_ROUTER_TYPE_MASK 0x03
994 #define NLSP_LSP_ROUTER_TYPE(info) ((info) & NLSP_LSP_ROUTER_TYPE_MASK)
996 static void
997 nlsp_dissect_nlsp_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
998 int offset, int header_length)
1000 guint16 packet_length;
1001 guint16 remaining_lifetime;
1002 guint32 sequence_number;
1003 int len;
1005 packet_length = tvb_get_ntohs(tvb, offset);
1006 if (tree) {
1007 proto_tree_add_uint(tree, hf_nlsp_packet_length, tvb,
1008 offset, 2, packet_length);
1010 offset += 2;
1012 remaining_lifetime = tvb_get_ntohs(tvb, offset);
1013 if (tree) {
1014 proto_tree_add_text(tree, tvb, offset, 2,
1015 "Remaining Lifetime: %us",
1016 remaining_lifetime);
1018 offset += 2;
1020 col_append_fstr(pinfo->cinfo, COL_INFO, ", LSP ID: %s",
1021 tvb_ether_to_str(tvb, offset));
1023 proto_tree_add_text(tree, tvb, offset, 6,
1024 "LSP ID system ID: %s",
1025 tvb_ether_to_str(tvb, offset));
1027 offset += 6;
1028 /* XXX - append the pseudonode ID */
1029 proto_tree_add_text(tree, tvb, offset, 1,
1030 "LSP ID pseudonode ID: %u",
1031 tvb_get_guint8(tvb, offset));
1033 offset += 1;
1034 proto_tree_add_text(tree, tvb, offset, 1,
1035 "LSP ID LSP number: %u",
1036 tvb_get_guint8(tvb, offset));
1037 offset += 1;
1039 sequence_number = tvb_get_ntohl(tvb, offset);
1040 col_append_fstr(pinfo->cinfo, COL_INFO,
1041 ", Sequence: 0x%08x, Lifetime: %us",
1042 sequence_number, remaining_lifetime);
1044 proto_tree_add_uint(tree, hf_nlsp_lsp_sequence_number, tvb,
1045 offset, 4, sequence_number);
1046 offset += 4;
1048 /* XXX -> we could validate the cksum here! */
1049 proto_tree_add_item(tree, hf_nlsp_lsp_checksum, tvb,
1050 offset, 2, ENC_BIG_ENDIAN );
1052 offset += 2;
1054 if (tree) {
1055 proto_tree_add_item(tree, hf_nlsp_lsp_p, tvb,
1056 offset, 1, ENC_BIG_ENDIAN);
1057 proto_tree_add_item(tree, hf_nlsp_lsp_attached_flag, tvb,
1058 offset, 1, ENC_BIG_ENDIAN);
1059 proto_tree_add_item(tree, hf_nlsp_lsp_lspdbol, tvb,
1060 offset, 1, ENC_BIG_ENDIAN);
1061 proto_tree_add_item(tree, hf_nlsp_lsp_router_type, tvb,
1062 offset, 1, ENC_BIG_ENDIAN);
1064 offset += 1;
1066 len = packet_length - header_length;
1067 if (len < 0) {
1068 nlsp_dissect_unknown(tvb, tree, offset,
1069 "packet header length %d went beyond packet",
1070 header_length);
1071 return;
1075 * Now, we need to decode our CLVs. We need to pass in
1076 * our list of valid ones!
1078 nlsp_dissect_clvs(tvb, tree, offset,
1079 clv_l1_lsp_opts, len, ett_nlsp_lsp_clv_unknown);
1083 * Name: dissect_snp_lsp_entries()
1085 * Description:
1086 * All the snp packets use a common payload format. We have up
1087 * to n entries (based on length), which are made of:
1088 * 2 : remaining life time
1089 * 8 : lsp id
1090 * 4 : sequence number
1091 * 2 : checksum
1093 * Input:
1094 * tvbuff_t * : tvbuffer for packet data
1095 * proto_tree * : protocol display tree to fill out. May be NULL
1096 * int : offset into packet data where we are.
1097 * int : length of payload to decode.
1099 * Output:
1100 * void, but we will add to proto tree if !NULL.
1102 static void
1103 dissect_csnp_lsp_entries(tvbuff_t *tvb, proto_tree *tree, int offset,
1104 int length)
1106 proto_tree *subtree,*ti;
1108 while (length > 0) {
1109 if (length < 16) {
1110 nlsp_dissect_unknown(tvb, tree, offset,
1111 "Short CSNP header entry");
1112 return;
1115 ti = proto_tree_add_text(tree, tvb, offset, 16,
1116 "LSP-ID: %s, Sequence: 0x%08x, Lifetime: %5us, Checksum: 0x%04x",
1117 tvb_ether_to_str(tvb, offset+2), /* XXX - rest of system ID */
1118 tvb_get_ntohl(tvb, offset+10),
1119 tvb_get_ntohs(tvb, offset),
1120 tvb_get_ntohs(tvb, offset+14));
1122 subtree = proto_item_add_subtree(ti, ett_nlsp_csnp_lsp_entry);
1124 proto_tree_add_text(subtree, tvb, offset+2, 6,
1125 "LSP ID source ID: %s",
1126 tvb_ether_to_str(tvb, offset+2));
1127 proto_tree_add_text(subtree, tvb, offset+8, 1,
1128 "LSP ID pseudonode ID: %u",
1129 tvb_get_guint8(tvb, offset+8));
1130 proto_tree_add_text(subtree, tvb, offset+9, 1,
1131 "LSP ID LSP number: %u",
1132 tvb_get_guint8(tvb, offset+9));
1134 proto_tree_add_text(subtree, tvb, offset+10, 4,
1135 "LSP Sequence Number: 0x%08x",
1136 tvb_get_ntohl(tvb, offset+10));
1138 proto_tree_add_text(subtree, tvb, offset, 2,
1139 "Remaining Lifetime: %us",
1140 tvb_get_ntohs(tvb, offset));
1142 proto_tree_add_text(subtree, tvb, offset+14, 2,
1143 "LSP checksum: 0x%04x",
1144 tvb_get_ntohs(tvb, offset+14));
1146 length -= 16;
1147 offset += 16;
1151 static void
1152 dissect_psnp_lsp_entries(tvbuff_t *tvb, proto_tree *tree, int offset,
1153 int length)
1155 proto_tree *subtree,*ti;
1157 while (length > 0) {
1158 if (length < 16) {
1159 nlsp_dissect_unknown(tvb, tree, offset,
1160 "Short PSNP header entry");
1161 return;
1164 ti = proto_tree_add_text(tree, tvb, offset, 16,
1165 "LSP-ID: %s, Sequence: 0x%08x, Lifetime: %5us, Checksum: 0x%04x",
1166 tvb_ether_to_str(tvb, offset+2), /* XXX - rest of system ID */
1167 tvb_get_ntohl(tvb, offset+10),
1168 tvb_get_ntohs(tvb, offset),
1169 tvb_get_ntohs(tvb, offset+14));
1171 subtree = proto_item_add_subtree(ti, ett_nlsp_psnp_lsp_entry);
1173 proto_tree_add_text(subtree, tvb, offset+2, 6,
1174 "LSP ID source ID: %s",
1175 tvb_ether_to_str(tvb, offset+2));
1176 proto_tree_add_text(subtree, tvb, offset+8, 1,
1177 "LSP ID pseudonode ID: %u",
1178 tvb_get_guint8(tvb, offset+8));
1179 proto_tree_add_text(subtree, tvb, offset+9, 1,
1180 "LSP ID LSP number: %u",
1181 tvb_get_guint8(tvb, offset+9));
1183 proto_tree_add_text(subtree, tvb, offset+10, 4,
1184 "LSP Sequence Number: 0x%08x",
1185 tvb_get_ntohl(tvb, offset+10));
1187 proto_tree_add_text(subtree, tvb, offset, 2,
1188 "Remaining Lifetime: %us",
1189 tvb_get_ntohs(tvb, offset));
1191 proto_tree_add_text(subtree, tvb, offset+14, 2,
1192 "LSP checksum: 0x%04x",
1193 tvb_get_ntohs(tvb, offset+14));
1195 length -= 16;
1196 offset += 16;
1200 static const nlsp_clv_handle_t clv_l1_csnp_opts[] = {
1203 "LSP entries",
1204 &ett_nlsp_csnp_lsp_entries,
1205 dissect_csnp_lsp_entries
1211 NULL,
1212 NULL
1217 * Name: nlsp_dissect_nlsp_csnp()
1219 * Description:
1220 * Tear apart a L1 CSNP header and then call into payload dissect
1221 * to pull apart the lsp id payload.
1223 * Input:
1224 * tvbuff_t * : tvbuffer for packet data
1225 * proto_tree * : protocol display tree to add to. May be NULL.
1226 * int offset : our offset into packet data.
1227 * int : header length of packet.
1229 * Output:
1230 * void, but we will add to proto tree if !NULL.
1232 static void
1233 nlsp_dissect_nlsp_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1234 int offset, int header_length)
1236 guint16 packet_length;
1237 int len;
1239 packet_length = tvb_get_ntohs(tvb, offset);
1240 if (tree) {
1241 proto_tree_add_uint(tree, hf_nlsp_packet_length, tvb,
1242 offset, 2, packet_length);
1244 offset += 2;
1246 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source ID: %s",
1247 tvb_ether_to_str(tvb, offset));
1248 proto_tree_add_text(tree, tvb, offset, 6,
1249 "Source ID system ID: %s",
1250 tvb_ether_to_str(tvb, offset));
1251 offset += 6;
1252 /* XXX - add the pseudonode ID */
1253 proto_tree_add_text(tree, tvb, offset, 1,
1254 "Source ID pseudonode ID: %u",
1255 tvb_get_guint8(tvb, offset));
1256 offset += 1;
1258 col_append_fstr(pinfo->cinfo, COL_INFO, ", Start LSP ID: %s",
1259 tvb_ether_to_str(tvb, offset));
1260 proto_tree_add_text(tree, tvb, offset, 6,
1261 "Start LSP ID source ID: %s",
1262 tvb_ether_to_str(tvb, offset));
1263 offset += 6;
1264 /* XXX - append the pseudonode ID */
1265 proto_tree_add_text(tree, tvb, offset, 1,
1266 "Start LSP ID pseudonode ID: %u",
1267 tvb_get_guint8(tvb, offset));
1268 offset += 1;
1270 proto_tree_add_text(tree, tvb, offset, 1,
1271 "Start LSP ID LSP number: %u",
1272 tvb_get_guint8(tvb, offset));
1273 offset += 1;
1275 col_append_fstr(pinfo->cinfo, COL_INFO, ", End LSP ID: %s",
1276 tvb_ether_to_str(tvb, offset));
1277 proto_tree_add_text(tree, tvb, offset, 6,
1278 "End LSP ID source ID: %s",
1279 tvb_ether_to_str(tvb, offset));
1280 offset += 6;
1281 /* XXX - append the pseudonode ID */
1282 proto_tree_add_text(tree, tvb, offset, 1,
1283 "End LSP ID pseudonode ID: %u",
1284 tvb_get_guint8(tvb, offset));
1285 offset += 1;
1286 proto_tree_add_text(tree, tvb, offset, 1,
1287 "End LSP ID LSP number: %u",
1288 tvb_get_guint8(tvb, offset));
1289 offset += 1;
1291 len = packet_length - header_length;
1292 if (len < 0) {
1293 return;
1295 /* Call into payload dissector */
1296 nlsp_dissect_clvs(tvb, tree, offset,
1297 clv_l1_csnp_opts, len, ett_nlsp_csnp_clv_unknown);
1300 static const nlsp_clv_handle_t clv_l1_psnp_opts[] = {
1303 "LSP entries",
1304 &ett_nlsp_psnp_lsp_entries,
1305 dissect_psnp_lsp_entries
1311 NULL,
1312 NULL
1317 * Name: nlsp_dissect_nlsp_psnp()
1319 * Description:
1320 * Tear apart a L1 PSNP header and then call into payload dissect
1321 * to pull apart the lsp id payload.
1323 * Input:
1324 * tvbuff_t * : tvbuffer for packet data
1325 * proto_tree * : protocol display tree to add to. May be NULL.
1326 * int offset : our offset into packet data.
1327 * int : header length of packet.
1329 * Output:
1330 * void, but we will add to proto tree if !NULL.
1332 static void
1333 nlsp_dissect_nlsp_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1334 int offset, int header_length)
1336 guint16 packet_length;
1337 int len;
1339 packet_length = tvb_get_ntohs(tvb, offset);
1340 proto_tree_add_uint(tree, hf_nlsp_packet_length, tvb,
1341 offset, 2, packet_length);
1342 offset += 2;
1344 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source ID: %s",
1345 tvb_ether_to_str(tvb, offset));
1346 proto_tree_add_text(tree, tvb, offset, 6,
1347 "Source ID system ID: %s",
1348 tvb_ether_to_str(tvb, offset));
1349 offset += 6;
1350 /* XXX - add the pseudonode ID */
1351 proto_tree_add_text(tree, tvb, offset, 1,
1352 "Source ID pseudonode ID: %u",
1353 tvb_get_guint8(tvb, offset));
1354 offset += 1;
1356 len = packet_length - header_length;
1357 if (len < 0) {
1358 return;
1360 /* Call into payload dissector */
1361 nlsp_dissect_clvs(tvb, tree, offset,
1362 clv_l1_psnp_opts, len, ett_nlsp_psnp_clv_unknown);
1366 * Name: dissect_nlsp()
1368 * Description:
1369 * Main entry area for nlsp de-mangling. This will build the
1370 * main nlsp tree data and call the sub-protocols as needed.
1372 * Input:
1373 * tvbuff_t * : tvbuffer for packet data
1374 * packet_info * : info for current packet
1375 * proto_tree * : tree of display data. May be NULL.
1377 * Output:
1378 * void, but we will add to the proto_tree if it is not NULL.
1380 static void
1381 dissect_nlsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1383 proto_item *ti;
1384 proto_tree *nlsp_tree;
1385 int offset = 0;
1386 guint8 nlsp_major_version;
1387 guint8 nlsp_header_length;
1388 guint8 packet_type_flags;
1389 guint8 packet_type;
1391 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NLSP");
1392 col_clear(pinfo->cinfo, COL_INFO);
1394 nlsp_major_version = tvb_get_guint8(tvb, 5);
1395 if (nlsp_major_version != 1){
1396 col_add_fstr(pinfo->cinfo, COL_INFO,
1397 "Unknown NLSP version (%u vs 1)",
1398 nlsp_major_version);
1400 nlsp_dissect_unknown(tvb, tree, 0,
1401 "Unknown NLSP version (%d vs 1)",
1402 nlsp_major_version, 1);
1403 return;
1406 ti = proto_tree_add_item(tree, proto_nlsp, tvb, 0, -1, ENC_NA);
1407 nlsp_tree = proto_item_add_subtree(ti, ett_nlsp);
1409 proto_tree_add_item(nlsp_tree, hf_nlsp_irpd, tvb, offset, 1,
1410 ENC_BIG_ENDIAN );
1411 offset += 1;
1413 nlsp_header_length = tvb_get_guint8(tvb, 1);
1414 proto_tree_add_uint(nlsp_tree, hf_nlsp_header_length, tvb,
1415 offset, 1, nlsp_header_length );
1416 offset += 1;
1418 proto_tree_add_item(nlsp_tree, hf_nlsp_minor_version, tvb,
1419 offset, 1, ENC_BIG_ENDIAN );
1420 offset += 1;
1422 offset += 1; /* Reserved */
1424 packet_type_flags = tvb_get_guint8(tvb, offset);
1425 packet_type = packet_type_flags & PACKET_TYPE_MASK;
1426 col_add_str(pinfo->cinfo, COL_INFO,
1427 val_to_str(packet_type, nlsp_packet_type_vals, "Unknown (%u)"));
1428 if (packet_type == NLSP_TYPE_L1_LSP) {
1429 proto_tree_add_boolean(nlsp_tree, hf_nlsp_nr, tvb, offset, 1,
1430 packet_type_flags );
1432 proto_tree_add_uint(nlsp_tree, hf_nlsp_type, tvb, offset, 1,
1433 packet_type_flags );
1434 offset += 1;
1436 proto_tree_add_item(nlsp_tree, hf_nlsp_major_version, tvb,
1437 offset, 1, ENC_BIG_ENDIAN );
1438 offset += 1;
1440 offset += 2; /* Reserved */
1442 switch (packet_type) {
1444 case NLSP_TYPE_L1_HELLO:
1445 case NLSP_TYPE_WAN_HELLO:
1446 nlsp_dissect_nlsp_hello(tvb, pinfo, nlsp_tree, offset,
1447 packet_type, nlsp_header_length);
1448 break;
1450 case NLSP_TYPE_L1_LSP:
1451 nlsp_dissect_nlsp_lsp(tvb, pinfo, nlsp_tree, offset,
1452 nlsp_header_length);
1453 break;
1455 case NLSP_TYPE_L1_CSNP:
1456 nlsp_dissect_nlsp_csnp(tvb, pinfo, nlsp_tree, offset,
1457 nlsp_header_length);
1458 break;
1460 case NLSP_TYPE_L1_PSNP:
1461 nlsp_dissect_nlsp_psnp(tvb, pinfo, nlsp_tree, offset,
1462 nlsp_header_length);
1463 break;
1465 default:
1466 nlsp_dissect_unknown(tvb, tree, offset,
1467 "Unknown NLSP packet type");
1472 * Name: proto_register_nlsp()
1474 * Description:
1475 * main register for NLSP protocol set. We register some display
1476 * formats and the protocol module variables.
1478 * NOTE: this procedure to autolinked by the makefile process that
1479 * builds register.c
1481 * Input:
1482 * void
1484 * Output:
1485 * void
1487 void
1488 proto_register_nlsp(void)
1490 static hf_register_info hf[] = {
1491 { &hf_nlsp_irpd,
1492 { "NetWare Link Services Protocol Discriminator", "nlsp.irpd",
1493 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1495 { &hf_nlsp_header_length,
1496 { "PDU Header Length", "nlsp.header_length",
1497 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1499 { &hf_nlsp_minor_version,
1500 { "Minor Version", "nlsp.minor_version", FT_UINT8,
1501 BASE_DEC, NULL, 0x0, NULL, HFILL }},
1503 { &hf_nlsp_nr,
1504 { "Multi-homed Non-routing Server", "nlsp.nr", FT_BOOLEAN, 8,
1505 NULL, 0x80, NULL, HFILL }},
1507 { &hf_nlsp_type,
1508 { "Packet Type", "nlsp.type", FT_UINT8, BASE_DEC,
1509 VALS(nlsp_packet_type_vals), PACKET_TYPE_MASK, NULL, HFILL }},
1511 { &hf_nlsp_major_version,
1512 { "Major Version", "nlsp.major_version", FT_UINT8,
1513 BASE_DEC, NULL, 0x0, NULL, HFILL }},
1515 { &hf_nlsp_packet_length,
1516 { "Packet Length", "nlsp.packet_length",
1517 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1519 { &hf_nlsp_hello_state,
1520 { "State", "nlsp.hello.state", FT_UINT8, BASE_DEC,
1521 VALS(nlsp_hello_state_vals), NLSP_HELLO_STATE_MASK,
1522 NULL, HFILL }},
1524 { &hf_nlsp_hello_multicast,
1525 { "Multicast Routing", "nlsp.hello.multicast", FT_BOOLEAN, 8,
1526 TFS(&tfs_supported_not_supported), NLSP_HELLO_MULTICAST_MASK,
1527 "If set, this router supports multicast routing", HFILL }},
1529 { &hf_nlsp_hello_circuit_type,
1530 { "Circuit Type", "nlsp.hello.circuit_type", FT_UINT8, BASE_DEC,
1531 VALS(nlsp_hello_circuit_type_vals), NLSP_HELLO_CTYPE_MASK,
1532 NULL, HFILL }},
1534 { &hf_nlsp_hello_holding_timer,
1535 { "Holding Timer", "nlsp.hello.holding_timer", FT_UINT8, BASE_DEC,
1536 NULL, 0x0, NULL, HFILL }},
1538 { &hf_nlsp_hello_priority,
1539 { "Priority", "nlsp.hello.priority", FT_UINT8, BASE_DEC,
1540 NULL, NLSP_HELLO_PRIORITY_MASK,
1541 NULL, HFILL }},
1543 { &hf_nlsp_lsp_sequence_number,
1544 { "Sequence Number", "nlsp.sequence_number",
1545 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1547 { &hf_nlsp_lsp_checksum,
1548 { "Checksum", "nlsp.lsp.checksum",
1549 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1551 { &hf_nlsp_lsp_p,
1552 { "Partition Repair", "nlsp.lsp.partition_repair", FT_BOOLEAN, 8,
1553 TFS(&tfs_supported_not_supported), NLSP_LSP_PARTITION_MASK,
1554 "If set, this router supports the optional Partition Repair function", HFILL }},
1556 { &hf_nlsp_lsp_attached_flag,
1557 { "Attached Flag", "nlsp.lsp.attached_flag", FT_UINT8, BASE_DEC,
1558 VALS(nlsp_attached_flag_vals), NLSP_LSP_ATT_MASK, NULL, HFILL }},
1560 { &hf_nlsp_lsp_lspdbol,
1561 { "LSP Database Overloaded", "nlsp.lsp.lspdbol", FT_BOOLEAN, 8,
1562 NULL, NLSP_LSP_OVERFLOW_MASK, NULL, HFILL }},
1564 { &hf_nlsp_lsp_router_type,
1565 { "Router Type", "nlsp.lsp.router_type", FT_UINT8, BASE_DEC,
1566 VALS(nlsp_router_type_vals), NLSP_LSP_ROUTER_TYPE_MASK,
1567 NULL, HFILL }},
1569 { &hf_nlsp_lsp_link_info_clv_flags_cost_present,
1570 { "Cost present", "nlsp.lsp.link_info_clv.flags.cost_present", FT_BOOLEAN, 8,
1571 TFS(&tfs_no_yes), 0x80, NULL, HFILL }},
1573 { &hf_nlsp_lsp_link_info_clv_flags_cost_metric,
1574 { "Cost metric", "nlsp.lsp.link_info_clv.flags.cost_metric", FT_BOOLEAN, 8,
1575 TFS(&tfs_internal_external), 0x40, NULL, HFILL }},
1577 { &hf_nlsp_lsp_link_info_clv_flags_cost,
1578 { "Cost", "nlsp.lsp.link_info_clv.flags.cost", FT_UINT8, BASE_DEC,
1579 NULL, 0x3F, NULL, HFILL }},
1581 static gint *ett[] = {
1582 &ett_nlsp,
1583 &ett_nlsp_hello_clv_area_addr,
1584 &ett_nlsp_hello_clv_neighbors,
1585 &ett_nlsp_hello_local_mtu,
1586 &ett_nlsp_hello_clv_unknown,
1587 &ett_nlsp_lsp_info,
1588 &ett_nlsp_lsp_clv_area_addr,
1589 &ett_nlsp_lsp_clv_mgt_info,
1590 &ett_nlsp_lsp_clv_link_info,
1591 &ett_nlsp_lsp_clv_svcs_info,
1592 &ett_nlsp_lsp_clv_ext_routes,
1593 &ett_nlsp_lsp_clv_unknown,
1594 &ett_nlsp_csnp_lsp_entries,
1595 &ett_nlsp_csnp_lsp_entry,
1596 &ett_nlsp_csnp_clv_unknown,
1597 &ett_nlsp_psnp_lsp_entries,
1598 &ett_nlsp_psnp_lsp_entry,
1599 &ett_nlsp_psnp_clv_unknown,
1602 proto_nlsp = proto_register_protocol("NetWare Link Services Protocol",
1603 "NLSP", "nlsp");
1604 proto_register_field_array(proto_nlsp, hf, array_length(hf));
1605 proto_register_subtree_array(ett, array_length(ett));
1608 void
1609 proto_reg_handoff_nlsp(void)
1611 dissector_handle_t nlsp_handle;
1613 nlsp_handle = create_dissector_handle(dissect_nlsp, proto_nlsp);
1614 dissector_add_uint("ipx.socket", IPX_SOCKET_NLSP, nlsp_handle);