2 * Routines for NetWare Link Services Protocol
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.
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
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"},
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"},
109 static const value_string nlsp_router_type_vals
[] = {
110 { 1, "Level 1 Router"},
111 { 3, "Level 1 and Level 2 Router"},
115 static const true_false_string tfs_internal_external
= { "Internal", "External" };
118 * Our sub-packet dismantle structure for CLV's
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
);
129 * Name: nlsp_dissect_unknown()
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!
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
144 * void (may modify proto tree)
147 nlsp_dissect_unknown(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
148 const char *fmat
, ...)
153 proto_tree_add_text_valist(tree
, tvb
, offset
, -1, fmat
, ap
);
158 * Name: nlsp_dissect_clvs()
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
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
184 * void, but we will add to proto tree if !NULL.
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_
)
194 proto_tree
*clv_tree
;
197 code
= tvb_get_guint8(tvb
, offset
);
203 length
= tvb_get_guint8(tvb
, offset
);
209 if ( len
< length
) {
210 nlsp_dissect_unknown(tvb
, tree
, offset
,
211 "Short CLV header (%d vs %d)",
216 while ((opts
[q
].dissect
!= NULL
)&&( opts
[q
].optcode
!= code
)){
219 if ( opts
[q
].dissect
) {
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
,
230 opts
[q
].dissect(tvb
, clv_tree
, offset
,
235 ti
= proto_tree_add_text(tree
, tvb
, offset
- 2,
236 length
+ 2, "Unknown code %u (%u)",
238 clv_tree
= proto_item_add_subtree(ti
,
243 proto_tree_add_text(tree
, tvb
, offset
- 2,
244 length
+ 2, "Unknown code %u (%u)",
255 * Name: dissect_area_address_clv()
258 * Decode an area address clv.
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
267 * void, but we will add to proto tree if !NULL.
270 dissect_area_address_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
275 nlsp_dissect_unknown(tvb
, tree
, offset
,
276 "Short area address entry");
280 proto_tree_add_text(tree
, tvb
, offset
, 4,
281 "Area address network number: 0x%08x",
282 tvb_get_ntohl(tvb
, offset
));
288 nlsp_dissect_unknown(tvb
, tree
, offset
,
289 "Short area address entry");
293 proto_tree_add_text(tree
, tvb
, offset
, 4,
294 "Area address mask: 0x%08x",
295 tvb_get_ntohl(tvb
, offset
));
303 * Name: dissect_neighbor_clv()
306 * Decode an neighbor clv.
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
315 * void, but we will add to proto tree if !NULL.
318 dissect_neighbor_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
323 nlsp_dissect_unknown(tvb
, tree
, offset
,
324 "Short neighbor entry");
328 proto_tree_add_text(tree
, tvb
, offset
, 6,
330 tvb_ether_to_str(tvb
, offset
));
338 * Name: dissect_hello_local_mtu_clv()
341 * Decode for a hello packet's local MTU clv.
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
350 * void, but we will add to proto tree if !NULL.
353 dissect_hello_local_mtu_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
357 nlsp_dissect_unknown(tvb
, tree
, offset
,
358 "Short link info entry");
362 proto_tree_add_text(tree
, tvb
, offset
, 4,
364 tvb_get_ntohl(tvb
, offset
));
368 static const nlsp_clv_handle_t clv_hello_opts
[] = {
372 &ett_nlsp_hello_clv_area_addr
,
373 dissect_area_address_clv
378 &ett_nlsp_hello_clv_neighbors
,
384 &ett_nlsp_hello_local_mtu
,
385 dissect_hello_local_mtu_clv
397 * Name: nlsp_dissect_nlsp_hello()
400 * This procedure rips apart NLSP hellos.
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.
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
[] = {
418 { 1, "Initializing" },
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"},
436 #define NLSP_HELLO_PRIORITY_MASK 0x7f
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
;
444 guint16 holding_timer
;
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
);
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
);
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
));
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
);
477 packet_length
= tvb_get_ntohs(tvb
, offset
);
479 proto_tree_add_uint(tree
, hf_nlsp_packet_length
, tvb
,
480 offset
, 2, packet_length
);
485 proto_tree_add_item(tree
, hf_nlsp_hello_priority
, tvb
,
486 offset
, 1, ENC_BIG_ENDIAN
);
490 if (hello_type
== NLSP_TYPE_WAN_HELLO
) {
492 proto_tree_add_text(tree
, tvb
, offset
, 1,
493 "Local WAN Circuit ID: %u",
494 tvb_get_guint8(tvb
, offset
));
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));
509 len
= packet_length
- header_length
;
511 nlsp_dissect_unknown(tvb
, tree
, offset
,
512 "packet header length %d went beyond packet",
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()
529 * Decode for a lsp packet's management information clv.
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
538 * void, but we will add to proto tree if !NULL.
541 dissect_lsp_mgt_info_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
547 nlsp_dissect_unknown(tvb
, tree
, offset
,
548 "Short management info entry");
552 proto_tree_add_text(tree
, tvb
, offset
, 4,
553 "Network number: 0x%08x",
554 tvb_get_ntohl(tvb
, offset
));
560 nlsp_dissect_unknown(tvb
, tree
, offset
,
561 "Short management info entry");
565 proto_tree_add_text(tree
, tvb
, offset
, 6,
567 tvb_ether_to_str(tvb
, offset
));
573 nlsp_dissect_unknown(tvb
, tree
, offset
,
574 "Short management info entry");
578 proto_tree_add_text(tree
, tvb
, offset
, 1,
579 "IPX version number: %u",
580 tvb_get_guint8(tvb
, offset
));
586 nlsp_dissect_unknown(tvb
, tree
, offset
,
587 "Short management info entry");
590 name_length
= tvb_get_guint8(tvb
, offset
);
592 proto_tree_add_text(tree
, tvb
, offset
, 1,
593 "Name length: %u", name_length
);
598 if (name_length
!= 0) {
599 if (length
< name_length
) {
600 nlsp_dissect_unknown(tvb
, tree
, offset
,
601 "Short management info entry");
605 proto_tree_add_text(tree
, tvb
, offset
, name_length
,
607 tvb_format_text(tvb
, offset
, name_length
));
613 * Name: dissect_lsp_link_info_clv()
616 * Decode for a lsp packet's link information clv.
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
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" },
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" },
658 { 0x801D, "Proxim RangeLAN" },
660 { 0x801F, "Frame Relay" },
661 { 0x0020, "Integrated Workstations BUS-NET" },
662 { 0x8021, "Novell SNA Links" },
667 dissect_lsp_link_info_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
673 nlsp_dissect_unknown(tvb
, tree
, offset
,
674 "Short link info entry");
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
);
692 nlsp_dissect_unknown(tvb
, tree
, offset
,
693 "Short link info entry");
696 offset
+= 3; /* Reserved */
700 nlsp_dissect_unknown(tvb
, tree
, offset
,
701 "Short link info entry");
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));
716 nlsp_dissect_unknown(tvb
, tree
, offset
,
717 "Short link info entry");
721 proto_tree_add_text(tree
, tvb
, offset
, 4,
723 tvb_get_ntohl(tvb
, offset
));
729 nlsp_dissect_unknown(tvb
, tree
, offset
,
730 "Short link info entry");
734 proto_tree_add_text(tree
, tvb
, offset
, 4,
736 tvb_get_ntohl(tvb
, offset
));
742 nlsp_dissect_unknown(tvb
, tree
, offset
,
743 "Short link info entry");
747 proto_tree_add_text(tree
, tvb
, offset
, 4,
748 "Throughput: %u bits/s",
749 tvb_get_ntohl(tvb
, offset
));
755 nlsp_dissect_unknown(tvb
, tree
, offset
,
756 "Short link info entry");
760 proto_tree_add_text(tree
, tvb
, offset
, 2,
762 val_to_str(tvb_get_ntohs(tvb
, offset
), media_type_vals
,
763 "Unknown (0x%04x)"));
768 * Name: dissect_lsp_svcs_info_clv()
771 * Decode for a lsp packet's services information clv.
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
780 * void, but we will add to proto tree if !NULL.
783 dissect_lsp_svcs_info_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
787 nlsp_dissect_unknown(tvb
, tree
, offset
,
788 "Short services info entry");
792 proto_tree_add_text(tree
, tvb
, offset
, 1,
793 "Hops to reach the service: %u",
794 tvb_get_guint8(tvb
, offset
));
800 nlsp_dissect_unknown(tvb
, tree
, offset
,
801 "Short services info entry");
805 proto_tree_add_text(tree
, tvb
, offset
, 4,
806 "Network number: 0x%08x",
807 tvb_get_ntohl(tvb
, offset
));
813 nlsp_dissect_unknown(tvb
, tree
, offset
,
814 "Short services info entry");
818 proto_tree_add_text(tree
, tvb
, offset
, 6,
820 tvb_ether_to_str(tvb
, offset
));
826 nlsp_dissect_unknown(tvb
, tree
, offset
,
827 "Short services info entry");
831 proto_tree_add_text(tree
, tvb
, offset
, 2,
833 val_to_str_ext(tvb_get_ntohs(tvb
, offset
), &ipx_socket_vals_ext
,
834 "Unknown (0x%04x)"));
840 nlsp_dissect_unknown(tvb
, tree
, offset
,
841 "Short services info entry");
845 proto_tree_add_text(tree
, tvb
, offset
, 2,
847 val_to_str_ext(tvb_get_ntohs(tvb
, offset
), &novell_server_vals_ext
,
848 "Unknown (0x%04x)"));
855 proto_tree_add_text(tree
, tvb
, offset
, length
,
857 tvb_format_text(tvb
, offset
, length
));
864 * Name: dissect_lsp_ext_routes_clv()
867 * Decode for a lsp packet's external routes clv.
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
876 * void, but we will add to proto tree if !NULL.
879 dissect_lsp_ext_routes_clv(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
884 nlsp_dissect_unknown(tvb
, tree
, offset
,
885 "Short external routes entry");
889 proto_tree_add_text(tree
, tvb
, offset
, 1,
891 tvb_get_guint8(tvb
, offset
));
897 nlsp_dissect_unknown(tvb
, tree
, offset
,
898 "Short external routes entry");
902 proto_tree_add_text(tree
, tvb
, offset
, 4,
903 "Network number: 0x%08x",
904 tvb_get_ntohl(tvb
, offset
));
910 nlsp_dissect_unknown(tvb
, tree
, offset
,
911 "Short external routes entry");
915 proto_tree_add_text(tree
, tvb
, offset
, 2,
916 "RIP delay: %u ticks",
917 tvb_get_ntohs(tvb
, offset
));
924 static const nlsp_clv_handle_t clv_l1_lsp_opts
[] = {
928 &ett_nlsp_lsp_clv_area_addr
,
929 dissect_area_address_clv
933 "Management information",
934 &ett_nlsp_lsp_clv_mgt_info
,
935 dissect_lsp_mgt_info_clv
940 &ett_nlsp_lsp_clv_link_info
,
941 dissect_lsp_link_info_clv
945 "Services information",
946 &ett_nlsp_lsp_clv_svcs_info
,
947 dissect_lsp_svcs_info_clv
952 &ett_nlsp_lsp_clv_ext_routes
,
953 dissect_lsp_ext_routes_clv
965 * Name: nlsp_dissect_nlsp_lsp()
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.
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.
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)
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
;
1005 packet_length
= tvb_get_ntohs(tvb
, offset
);
1007 proto_tree_add_uint(tree
, hf_nlsp_packet_length
, tvb
,
1008 offset
, 2, packet_length
);
1012 remaining_lifetime
= tvb_get_ntohs(tvb
, offset
);
1014 proto_tree_add_text(tree
, tvb
, offset
, 2,
1015 "Remaining Lifetime: %us",
1016 remaining_lifetime
);
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
));
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
));
1034 proto_tree_add_text(tree
, tvb
, offset
, 1,
1035 "LSP ID LSP number: %u",
1036 tvb_get_guint8(tvb
, offset
));
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
);
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
);
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
);
1066 len
= packet_length
- header_length
;
1068 nlsp_dissect_unknown(tvb
, tree
, offset
,
1069 "packet header length %d went beyond packet",
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()
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
1090 * 4 : sequence number
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.
1100 * void, but we will add to proto tree if !NULL.
1103 dissect_csnp_lsp_entries(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
1106 proto_tree
*subtree
,*ti
;
1108 while (length
> 0) {
1110 nlsp_dissect_unknown(tvb
, tree
, offset
,
1111 "Short CSNP header entry");
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));
1152 dissect_psnp_lsp_entries(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
1155 proto_tree
*subtree
,*ti
;
1157 while (length
> 0) {
1159 nlsp_dissect_unknown(tvb
, tree
, offset
,
1160 "Short PSNP header entry");
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));
1200 static const nlsp_clv_handle_t clv_l1_csnp_opts
[] = {
1204 &ett_nlsp_csnp_lsp_entries
,
1205 dissect_csnp_lsp_entries
1217 * Name: nlsp_dissect_nlsp_csnp()
1220 * Tear apart a L1 CSNP header and then call into payload dissect
1221 * to pull apart the lsp id payload.
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.
1230 * void, but we will add to proto tree if !NULL.
1233 nlsp_dissect_nlsp_csnp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1234 int offset
, int header_length
)
1236 guint16 packet_length
;
1239 packet_length
= tvb_get_ntohs(tvb
, offset
);
1241 proto_tree_add_uint(tree
, hf_nlsp_packet_length
, tvb
,
1242 offset
, 2, packet_length
);
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
));
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
));
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
));
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
));
1270 proto_tree_add_text(tree
, tvb
, offset
, 1,
1271 "Start LSP ID LSP number: %u",
1272 tvb_get_guint8(tvb
, offset
));
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
));
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
));
1286 proto_tree_add_text(tree
, tvb
, offset
, 1,
1287 "End LSP ID LSP number: %u",
1288 tvb_get_guint8(tvb
, offset
));
1291 len
= packet_length
- header_length
;
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
[] = {
1304 &ett_nlsp_psnp_lsp_entries
,
1305 dissect_psnp_lsp_entries
1317 * Name: nlsp_dissect_nlsp_psnp()
1320 * Tear apart a L1 PSNP header and then call into payload dissect
1321 * to pull apart the lsp id payload.
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.
1330 * void, but we will add to proto tree if !NULL.
1333 nlsp_dissect_nlsp_psnp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1334 int offset
, int header_length
)
1336 guint16 packet_length
;
1339 packet_length
= tvb_get_ntohs(tvb
, offset
);
1340 proto_tree_add_uint(tree
, hf_nlsp_packet_length
, tvb
,
1341 offset
, 2, packet_length
);
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
));
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
));
1356 len
= packet_length
- header_length
;
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()
1369 * Main entry area for nlsp de-mangling. This will build the
1370 * main nlsp tree data and call the sub-protocols as needed.
1373 * tvbuff_t * : tvbuffer for packet data
1374 * packet_info * : info for current packet
1375 * proto_tree * : tree of display data. May be NULL.
1378 * void, but we will add to the proto_tree if it is not NULL.
1381 dissect_nlsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
1384 proto_tree
*nlsp_tree
;
1386 guint8 nlsp_major_version
;
1387 guint8 nlsp_header_length
;
1388 guint8 packet_type_flags
;
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);
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,
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
);
1418 proto_tree_add_item(nlsp_tree
, hf_nlsp_minor_version
, tvb
,
1419 offset
, 1, ENC_BIG_ENDIAN
);
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
);
1436 proto_tree_add_item(nlsp_tree
, hf_nlsp_major_version
, tvb
,
1437 offset
, 1, ENC_BIG_ENDIAN
);
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
);
1450 case NLSP_TYPE_L1_LSP
:
1451 nlsp_dissect_nlsp_lsp(tvb
, pinfo
, nlsp_tree
, offset
,
1452 nlsp_header_length
);
1455 case NLSP_TYPE_L1_CSNP
:
1456 nlsp_dissect_nlsp_csnp(tvb
, pinfo
, nlsp_tree
, offset
,
1457 nlsp_header_length
);
1460 case NLSP_TYPE_L1_PSNP
:
1461 nlsp_dissect_nlsp_psnp(tvb
, pinfo
, nlsp_tree
, offset
,
1462 nlsp_header_length
);
1466 nlsp_dissect_unknown(tvb
, tree
, offset
,
1467 "Unknown NLSP packet type");
1472 * Name: proto_register_nlsp()
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
1488 proto_register_nlsp(void)
1490 static hf_register_info hf
[] = {
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
}},
1504 { "Multi-homed Non-routing Server", "nlsp.nr", FT_BOOLEAN
, 8,
1505 NULL
, 0x80, NULL
, HFILL
}},
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
,
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
,
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
,
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
}},
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
,
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
[] = {
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
,
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",
1604 proto_register_field_array(proto_nlsp
, hf
, array_length(hf
));
1605 proto_register_subtree_array(ett
, array_length(ett
));
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
);