Overhaul the ISIS dissectors
authorMichael Mann <mmann78@netscape.net>
Sun, 22 Dec 2013 18:18:12 +0000 (18:18 -0000)
committerMichael Mann <mmann78@netscape.net>
Sun, 22 Dec 2013 18:18:12 +0000 (18:18 -0000)
1. Make real dissectors and call dissector_try_uint_new for each "isis.type"
2. Use make_register script for dissector initialization
3. Replace isis_dissect_unknown() with real expert info
4. Use convert_proto_tree_add_text.pl to make many more filterable items and gets some files off of the checkAPIs.pl naughty list.
5. Remove (now unnecessary) dissector specific header files
6. Do some reordering of functions to eliminate the need for function declarations.

Additional whitespace formatting and modelines should probably be applied to all of these dissectors.

Used capture files from bug 5354 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5354) and bug 1792 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=1792) for fuzztesting.

svn path=/trunk/; revision=54367

12 files changed:
epan/dissectors/Makefile.common
epan/dissectors/packet-isis-clv.c
epan/dissectors/packet-isis-clv.h
epan/dissectors/packet-isis-hello.c
epan/dissectors/packet-isis-hello.h [deleted file]
epan/dissectors/packet-isis-lsp.c
epan/dissectors/packet-isis-lsp.h [deleted file]
epan/dissectors/packet-isis-snp.c
epan/dissectors/packet-isis-snp.h [deleted file]
epan/dissectors/packet-isis.c
epan/dissectors/packet-isis.h
epan/dissectors/packet-osi-options.c

index 2511842da9d88a35c6e425e308197cd19d9cc9af..a369f3673e397499bc422ee1b818dd0e90082dc2 100644 (file)
@@ -1445,9 +1445,6 @@ DISSECTOR_INCLUDES =      \
        packet-isakmp.h \
        packet-isis.h   \
        packet-isis-clv.h       \
-       packet-isis-hello.h     \
-       packet-isis-lsp.h       \
-       packet-isis-snp.h       \
        packet-isl.h    \
        packet-isup.h   \
        packet-jxta.h   \
index 4d401b3623422db76eb3d4f9fe8cecbd0736f29a..46396dc00d394b88981317df5aeabc42b1a7cd8e 100644 (file)
@@ -28,6 +28,7 @@
 #include <glib.h>
 
 #include <epan/packet.h>
+#include <epan/expert.h>
 #include "packet-osi.h"
 #include "packet-isis.h"
 #include "packet-isis-clv.h"
@@ -50,8 +51,8 @@
  *     void, but we will add to proto tree if !NULL.
  */
 void
-isis_dissect_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
-       int length)
+isis_dissect_area_address_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb,
+        expert_field* expert, int offset, int length)
 {
        int             arealen,area_idx;
 
@@ -59,12 +60,12 @@ isis_dissect_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
                arealen = tvb_get_guint8(tvb, offset);
                length--;
                if (length<=0) {
-                       isis_dissect_unknown(tvb, tree, offset,
+                       proto_tree_add_expert_format(tree, pinfo, expert, tvb, offset, -1,
                                "short address (no length for payload)");
                        return;
                }
                if ( arealen > length) {
-                       isis_dissect_unknown(tvb, tree, offset,
+                       proto_tree_add_expert_format(tree, pinfo, expert, tvb, offset, -1,
                                "short address, packet says %d, we have %d left",
                                arealen, length );
                        return;
@@ -85,7 +86,7 @@ isis_dissect_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
                        /*
                         * Lets turn the area address into "standard"
                         * xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx format string.
-                        * this is a private routine as the print_nsap_net in
+                        * this is a private routine as the print_nsap_net in
                         * epan/osi_utils.c is incomplete and we need only
                         * a subset - actually some nice placing of dots ....
                         */
@@ -124,8 +125,8 @@ isis_dissect_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *     void, but we will add to proto tree if !NULL.
  */
 void
-isis_dissect_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
-       int length)
+isis_dissect_authentication_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb,
+        expert_field* auth_expert, int offset, int length)
 {
        guchar pw_type;
        int auth_unsupported;
@@ -176,9 +177,8 @@ isis_dissect_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
                break;
        }
 
-               if ( auth_unsupported ) {
-               isis_dissect_unknown(tvb, tree, offset,
-                               "Unknown authentication type" );
+               if ( auth_unsupported ) {
+                       proto_tree_add_expert(tree, pinfo, auth_expert, tvb, offset, -1);
        }
 }
 
@@ -300,8 +300,8 @@ isis_dissect_mt_clv(tvbuff_t *tvb, proto_tree *tree, int offset, int length,
                        "malformed MT-ID");
                break;
            }
-           length=length-2;
-           offset=offset+2;
+           length -= 2;
+           offset += 2;
        }
 }
 
@@ -326,8 +326,8 @@ isis_dissect_mt_clv(tvbuff_t *tvb, proto_tree *tree, int offset, int length,
  *     void, but we will add to proto tree if !NULL.
  */
 void
-isis_dissect_ip_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
-       int length, int tree_id)
+isis_dissect_ip_int_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
+    int offset, int length, int tree_id)
 {
        if ( length <= 0 ) {
                return;
@@ -335,7 +335,7 @@ isis_dissect_ip_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
 
        while ( length > 0 ) {
                if ( length < 4 ) {
-                       isis_dissect_unknown(tvb, tree, offset,
+                       proto_tree_add_expert_format(tree, pinfo, expert, tvb, offset, -1,
                                "Short IP interface address (%d vs 4)",length );
                        return;
                }
@@ -368,8 +368,8 @@ isis_dissect_ip_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *     void, but we will add to proto tree if !NULL.
  */
 void
-isis_dissect_ipv6_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
-       int length, int tree_id)
+isis_dissect_ipv6_int_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
+    int offset, int length, int tree_id)
 {
        guint8 addr [16];
 
@@ -379,7 +379,7 @@ isis_dissect_ipv6_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
 
        while ( length > 0 ) {
                if ( length < 16 ) {
-                       isis_dissect_unknown(tvb, tree, offset,
+                       proto_tree_add_expert_format(tree, pinfo, expert, tvb, offset, -1,
                                "Short IPv6 interface address (%d vs 16)",length );
                        return;
                }
@@ -412,21 +412,20 @@ isis_dissect_ipv6_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *      void, but we will add to proto tree if !NULL.
  */
 void
-isis_dissect_te_router_id_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
-       int length, int tree_id)
+isis_dissect_te_router_id_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
+    int offset, int length, int tree_id)
 {
-        if ( length <= 0 ) {
-                return;
-        }
+       if ( length <= 0 ) {
+               return;
+       }
 
-        if ( length != 4 ) {
-               isis_dissect_unknown(tvb, tree, offset,
-                        "malformed Traffic Engineering Router ID (%d vs 4)",length );
-                return;
-        }
-        if ( tree ) {
-                proto_tree_add_item(tree, tree_id, tvb, offset, 4, ENC_BIG_ENDIAN);
-        }
+       if ( length != 4 ) {
+               proto_tree_add_expert_format(tree, pinfo, expert, tvb, offset, -1,
+                       "malformed Traffic Engineering Router ID (%d vs 4)",length );
+               return;
+       }
+
+       proto_tree_add_item(tree, tree_id, tvb, offset, 4, ENC_BIG_ENDIAN);
 }
 
 /*
@@ -479,8 +478,7 @@ isis_dissect_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int offset, int length)
                                                */
                                               (tvb_get_guint8(tvb, offset) == NLPID_IEEE_8021AQ
                                                ? "IEEE 802.1aq (SPB)"
-                                               : val_to_str_const(tvb_get_guint8(tvb, offset), nlpid_vals,
-                                                                   "Unknown")),
+                                               : val_to_str_const(tvb_get_guint8(tvb, offset), nlpid_vals, "Unknown")),
                                               tvb_get_guint8(tvb, offset));
                        offset++;
                        first = FALSE;
@@ -513,8 +511,8 @@ isis_dissect_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int offset, int length)
  *     void, but we will add to proto tree if !NULL.
  */
 void
-isis_dissect_clvs(tvbuff_t *tvb, proto_tree *tree, int offset,
-       const isis_clv_handle_t *opts, int len, int id_length,
+isis_dissect_clvs(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
+       const isis_clv_handle_t *opts, expert_field* expert_short_len, int len, int id_length,
        int unknown_tree_id _U_)
 {
        guint8 code;
@@ -537,7 +535,7 @@ isis_dissect_clvs(tvbuff_t *tvb, proto_tree *tree, int offset,
                        break;
 
                if ( len < length ) {
-                       isis_dissect_unknown(tvb, tree, offset,
+                       proto_tree_add_expert_format(tree, pinfo, expert_short_len, tvb, offset, -1,
                                "Short CLV header (%d vs %d)",
                                length, len );
                        return;
@@ -557,7 +555,7 @@ isis_dissect_clvs(tvbuff_t *tvb, proto_tree *tree, int offset,
                        } else {
                                clv_tree = NULL;
                        }
-                       opts[q].dissect(tvb, clv_tree, offset,
+                       opts[q].dissect(tvb, pinfo, clv_tree, offset,
                                id_length, length);
                } else {
 #if 0 /* XXX: Left as commented out in case info about "unknown code" is ever to be displayed under a sub-tree */
index 255424fae746ba5d61f455be5e3f92c512dd952e..a757ddcef8f0076bb2997c4f5045aa33876eb64b 100644 (file)
@@ -85,7 +85,7 @@ typedef struct {
         int     optcode;                /* code for option */
         const char    *tree_text;       /* text for fold out */
         gint    *tree_id;               /* id for add_item */
-        void    (*dissect)(tvbuff_t *tvb, proto_tree *tree,
+        void    (*dissect)(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree,
                                 int offset, int id_length, int length);
 } isis_clv_handle_t;
 
@@ -93,28 +93,28 @@ typedef struct {
  * Published API functions.  NOTE, this are "local" API functions and
  * are only valid from with isis decodes.
  */
-extern void isis_dissect_clvs(tvbuff_t *tvb, proto_tree *tree, int offset,
-        const isis_clv_handle_t *opts, int len, int id_length,
+extern void isis_dissect_clvs(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
+        const isis_clv_handle_t *opts, expert_field* expert_short_len, int len, int id_length,
         int unknown_tree_id);
 
 extern void isis_dissect_nlpid_clv(tvbuff_t *tvb, proto_tree *tree,
         int offset, int length);
-extern void isis_dissect_te_router_id_clv(tvbuff_t *tvb, proto_tree *tree,
+extern void isis_dissect_te_router_id_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
         int offset, int length, int tree_id);
-extern void isis_dissect_ipv6_int_clv(tvbuff_t *tvb, proto_tree *tree,
+extern void isis_dissect_ipv6_int_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
         int offset, int length, int tree_id);
-extern void isis_dissect_ip_int_clv(tvbuff_t *tvb, proto_tree *tree,
+extern void isis_dissect_ip_int_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
         int offset, int length, int tree_id);
 extern void isis_dissect_mt_clv(tvbuff_t *tvb, proto_tree *tree,
         int offset, int length, int tree_id);
 extern void isis_dissect_hostname_clv(tvbuff_t *tvb, proto_tree *tree,
         int offset, int length, int tree_id);
-extern void isis_dissect_authentication_clv(tvbuff_t *tvb, proto_tree *tree,
-        int offset, int length);
+extern void isis_dissect_authentication_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb,
+        expert_field* auth_expert, int offset, int length);
 extern void isis_dissect_ip_authentication_clv(tvbuff_t *tvb, proto_tree *tree,
         int offset, int length);
-extern void isis_dissect_area_address_clv(tvbuff_t *tvb, proto_tree *tree,
-        int offset, int length);
+extern void isis_dissect_area_address_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb,
+        expert_field* expert, int offset, int length);
 
 extern void isis_dissect_metric(tvbuff_t *tvb, proto_tree *tree, int offset,
         guint8 value, char *pstr, int force_supported);
index c354aadf1b693114473b74da13902638735bda17..aa3ab0a63f9e6cb5d168ca2da1e31c3fdae1b888 100644 (file)
 
 #include <glib.h>
 #include <epan/packet.h>
+#include <epan/expert.h>
 #include "packet-osi.h"
 #include "packet-isis.h"
 #include "packet-isis-clv.h"
-#include "packet-isis-hello.h"
 #include <epan/addr_resolv.h>
 
 
+/*
+ * Declarations for L1/L2 hello base header.
+ */
+#define ISIS_HELLO_CTYPE_MASK          0x03
+#define ISIS_HELLO_CT_RESERVED_MASK    0xfc
+#define ISIS_HELLO_PRIORITY_MASK       0x7f
+#define ISIS_HELLO_P_RESERVED_MASK     0x80
+
+#define ISIS_HELLO_TYPE_RESERVED       0
+#define ISIS_HELLO_TYPE_LEVEL_1                1
+#define ISIS_HELLO_TYPE_LEVEL_2                2
+#define ISIS_HELLO_TYPE_LEVEL_12       3
+
+/*
+ * misc. bittest macros
+ */
+
+#define ISIS_RESTART_RR                 0x01
+#define ISIS_RESTART_RA                 0x02
+#define ISIS_RESTART_SA                 0x04
+#define ISIS_MASK_RESTART_RR(x)            ((x)&ISIS_RESTART_RR)
+#define ISIS_MASK_RESTART_RA(x)            ((x)&ISIS_RESTART_RA)
+#define ISIS_MASK_RESTART_SA(x)            ((x)&ISIS_RESTART_SA)
+
+
 #define APPEND_BOOLEAN_FLAG(flag, item, string) \
     if(flag){                            \
         if(item)                        \
 static const char initial_sep[] = " (";
 static const char cont_sep[] = ", ";
 
+static int proto_isis_hello = -1;
 
 /* hello packets */
+static int hf_isis_hello_circuit = -1;
 static int hf_isis_hello_circuit_reserved = -1;
 static int hf_isis_hello_source_id = -1;
 static int hf_isis_hello_holding_timer = -1;
 static int hf_isis_hello_pdu_length = -1;
+static int hf_isis_hello_priority = -1;
 static int hf_isis_hello_priority_reserved = -1;
 static int hf_isis_hello_lan_id = -1;
 static int hf_isis_hello_local_circuit_id = -1;
@@ -62,6 +90,17 @@ static int hf_isis_hello_clv_restart_flags_ra = -1;
 static int hf_isis_hello_clv_restart_flags_sa = -1;
 static int hf_isis_hello_clv_restart_remain_time = -1;
 static int hf_isis_hello_clv_restart_neighbor = -1;
+/* Generated from convert_proto_tree_add_text.pl */
+static int hf_isis_hello_extended_local_circuit_id = -1;
+static int hf_isis_hello_adjacency_state = -1;
+static int hf_isis_hello_neighbor_systemid = -1;
+static int hf_isis_hello_digest = -1;
+static int hf_isis_hello_aux_mcid = -1;
+static int hf_isis_hello_mcid = -1;
+static int hf_isis_hello_is_neighbor = -1;
+static int hf_isis_hello_mtid = -1;
+static int hf_isis_hello_checksum = -1;
+static int hf_isis_hello_neighbor_extended_local_circuit_id = -1;
 
 static gint ett_isis_hello = -1;
 static gint ett_isis_hello_clv_area_addr = -1;
@@ -84,6 +123,11 @@ static gint ett_isis_hello_clv_mt_port_cap_spb_digest = -1;
 static gint ett_isis_hello_clv_mt_port_cap_spb_bvid_tuples = -1;
 static gint ett_isis_hello_clv_checksum = -1;
 
+static expert_field ei_isis_hello_short_packet = EI_INIT;
+static expert_field ei_isis_hello_long_packet = EI_INIT;
+static expert_field ei_isis_hello_subtlv = EI_INIT;
+static expert_field ei_isis_hello_authentication = EI_INIT;
+
 static const value_string isis_hello_circuit_type_vals[] = {
        { ISIS_HELLO_TYPE_RESERVED,     "Reserved 0 (discard PDU)"},
        { ISIS_HELLO_TYPE_LEVEL_1,      "Level 1 only"},
@@ -91,334 +135,49 @@ static const value_string isis_hello_circuit_type_vals[] = {
        { ISIS_HELLO_TYPE_LEVEL_12,     "Level 1 and 2"},
        { 0,            NULL} };
 
-/*
- * Predclare dissectors for use in clv dissection.
- */
-static void dissect_hello_padding_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-static void dissect_hello_is_neighbors_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-static void dissect_hello_ptp_adj_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-static void dissect_hello_area_address_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-static void dissect_hello_authentication_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-static void dissect_hello_ip_authentication_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-static void dissect_hello_checksum_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-static void dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-static void dissect_hello_ip_int_addr_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-static void dissect_hello_mt_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-static void dissect_hello_nlpid_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-static void dissect_hello_restart_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-static void dissect_hello_mt_port_cap_clv(tvbuff_t *tvb,
-               proto_tree *tree, int offset, int id_length, int length);
-
-
-static const isis_clv_handle_t clv_l1_hello_opts[] = {
-       {
-               ISIS_CLV_AREA_ADDRESS,
-               "Area address(es)",
-               &ett_isis_hello_clv_area_addr,
-               dissect_hello_area_address_clv
-       },
-       {
-               ISIS_CLV_IS_NEIGHBORS,
-               "IS Neighbor(s)",
-               &ett_isis_hello_clv_is_neighbors,
-               dissect_hello_is_neighbors_clv
-       },
-       {
-               ISIS_CLV_PADDING,
-               "Padding",
-               &ett_isis_hello_clv_padding,
-               dissect_hello_padding_clv
-       },
-       {
-               ISIS_CLV_PROTOCOLS_SUPPORTED,
-               "Protocols Supported",
-               &ett_isis_hello_clv_nlpid,
-               dissect_hello_nlpid_clv
-       },
-       {
-               ISIS_CLV_IP_ADDR,
-               "IP Interface address(es)",
-               &ett_isis_hello_clv_ipv4_int_addr,
-               dissect_hello_ip_int_addr_clv
-       },
-       {
-               ISIS_CLV_IP6_ADDR,
-               "IPv6 Interface address(es)",
-               &ett_isis_hello_clv_ipv6_int_addr,
-               dissect_hello_ipv6_int_addr_clv
-       },
-       {
-               ISIS_CLV_RESTART,
-               "Restart Signaling",
-               &ett_isis_hello_clv_restart,
-               dissect_hello_restart_clv
-       },
-       {
-               ISIS_CLV_AUTHENTICATION,
-               "Authentication",
-               &ett_isis_hello_clv_authentication,
-               dissect_hello_authentication_clv
-       },
-       {
-               ISIS_CLV_IP_AUTHENTICATION,
-               "IP Authentication",
-               &ett_isis_hello_clv_ip_authentication,
-               dissect_hello_ip_authentication_clv
-       },
-       {
-               ISIS_CLV_MT_SUPPORTED,
-               "Multi Topology",
-               &ett_isis_hello_clv_mt,
-               dissect_hello_mt_clv
-       },
-       {
-               ISIS_CLV_CHECKSUM,
-               "Checksum",
-               &ett_isis_hello_clv_checksum,
-               dissect_hello_checksum_clv
-       },
-       {
-               0,
-               "",
-               NULL,
-               NULL
-       }
-};
-
-static const isis_clv_handle_t clv_l2_hello_opts[] = {
-       {
-               ISIS_CLV_AREA_ADDRESS,
-               "Area address(es)",
-               &ett_isis_hello_clv_area_addr,
-               dissect_hello_area_address_clv
-       },
-       {
-               ISIS_CLV_IS_NEIGHBORS,
-               "IS Neighbor(s)",
-               &ett_isis_hello_clv_is_neighbors,
-               dissect_hello_is_neighbors_clv
-       },
-       {
-               ISIS_CLV_PADDING,
-               "Padding",
-               &ett_isis_hello_clv_padding,
-               dissect_hello_padding_clv
-       },
-       {
-               ISIS_CLV_PROTOCOLS_SUPPORTED,
-               "Protocols Supported",
-               &ett_isis_hello_clv_nlpid,
-               dissect_hello_nlpid_clv
-       },
-       {
-               ISIS_CLV_IP_ADDR,
-               "IP Interface address(es)",
-               &ett_isis_hello_clv_ipv4_int_addr,
-               dissect_hello_ip_int_addr_clv
-       },
-       {
-               ISIS_CLV_IP6_ADDR,
-               "IPv6 Interface address(es)",
-               &ett_isis_hello_clv_ipv6_int_addr,
-               dissect_hello_ipv6_int_addr_clv
-       },
-       {
-               ISIS_CLV_AUTHENTICATION,
-               "Authentication",
-               &ett_isis_hello_clv_authentication,
-               dissect_hello_authentication_clv
-       },
-       {
-               ISIS_CLV_IP_AUTHENTICATION,
-               "IP Authentication",
-               &ett_isis_hello_clv_ip_authentication,
-               dissect_hello_ip_authentication_clv
-       },
-       {
-               ISIS_CLV_RESTART,
-               "Restart Signaling",
-               &ett_isis_hello_clv_restart,
-               dissect_hello_restart_clv
-       },
-       {
-               ISIS_CLV_MT_SUPPORTED,
-               "Multi Topology",
-               &ett_isis_hello_clv_mt,
-               dissect_hello_mt_clv
-       },
-       {
-               ISIS_CLV_CHECKSUM,
-               "Checksum",
-               &ett_isis_hello_clv_checksum,
-               dissect_hello_checksum_clv
-       },
-       {
-               0,
-               "",
-               NULL,
-               NULL
-       }
-};
-
-static const isis_clv_handle_t clv_ptp_hello_opts[] = {
-       {
-               ISIS_CLV_AREA_ADDRESS,
-               "Area address(es)",
-               &ett_isis_hello_clv_area_addr,
-               dissect_hello_area_address_clv
-       },
-       {
-               ISIS_CLV_PADDING,
-               "Padding",
-               &ett_isis_hello_clv_padding,
-               dissect_hello_padding_clv
-       },
-       {
-               ISIS_CLV_PROTOCOLS_SUPPORTED,
-               "Protocols Supported",
-               &ett_isis_hello_clv_nlpid,
-               dissect_hello_nlpid_clv
-       },
-       {
-               ISIS_CLV_IP_ADDR,
-               "IP Interface address(es)",
-               &ett_isis_hello_clv_ipv4_int_addr,
-               dissect_hello_ip_int_addr_clv
-       },
-       {
-               ISIS_CLV_IP6_ADDR,
-               "IPv6 Interface address(es)",
-               &ett_isis_hello_clv_ipv6_int_addr,
-               dissect_hello_ipv6_int_addr_clv
-       },
-       {
-               ISIS_CLV_AUTHENTICATION,
-               "Authentication",
-               &ett_isis_hello_clv_authentication,
-               dissect_hello_authentication_clv
-       },
-       {
-               ISIS_CLV_IP_AUTHENTICATION,
-               "IP Authentication",
-               &ett_isis_hello_clv_ip_authentication,
-               dissect_hello_ip_authentication_clv
-       },
-       {
-               ISIS_CLV_MT_PORT_CAP,
-               "MT Port Capability",
-               &ett_isis_hello_clv_mt_port_cap,
-               dissect_hello_mt_port_cap_clv
-       },
-       {
-               ISIS_CLV_RESTART,
-               "Restart Option",
-               &ett_isis_hello_clv_restart,
-               dissect_hello_restart_clv
-       },
-       {
-               ISIS_CLV_PTP_ADJ_STATE,
-               "Point-to-point Adjacency State",
-               &ett_isis_hello_clv_ptp_adj,
-               dissect_hello_ptp_adj_clv
-       },
-       {
-               ISIS_CLV_MT_SUPPORTED,
-               "Multi Topology",
-               &ett_isis_hello_clv_mt,
-               dissect_hello_mt_clv
-       },
-       {
-               ISIS_CLV_CHECKSUM,
-               "Checksum",
-               &ett_isis_hello_clv_checksum,
-               dissect_hello_checksum_clv
-       },
-       {
-               0,
-               "",
-               NULL,
-               NULL
-       }
-};
 
 static void
-dissect_hello_mt_port_cap_spb_mcid_clv(tvbuff_t   *tvb,
+dissect_hello_mt_port_cap_spb_mcid_clv(tvbuff_t *tvb, packet_info* pinfo,
         proto_tree *tree, int offset, int subtype, int sublen)
 {
     const int MCID_LEN = 51;
     const int SUBLEN   = 2 * MCID_LEN;
+    proto_tree *subtree, *ti;
 
     if (sublen != SUBLEN) {
-        isis_dissect_unknown( tvb, tree, offset,
-                              "Short SPB MCID TLV (%d vs %d)", sublen, SUBLEN);
+        proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, -1,
+                                     "Short SPB MCID TLV (%d vs %d)", sublen, SUBLEN);
         return;
     }
-    else {
-        proto_tree *subtree, *ti;
-        const guint8 *mcid     = tvb_get_ptr(tvb, offset,            MCID_LEN);
-        const guint8 *aux_mcid = tvb_get_ptr(tvb, offset + MCID_LEN, MCID_LEN);
-        int i;
 
-        ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
-                                  "SPB MCID: Type: 0x%02x, Length: %d", subtype, sublen);
-        subtree = proto_item_add_subtree(ti, ett_isis_hello_clv_mt_port_cap_spb_mcid);
-
-        /* MCID: */
-        proto_tree_add_text( subtree, tvb, offset, MCID_LEN, "MCID:");
-        for (i = 0 ; i < 48 ; i+= 8, offset += 8) {
-            proto_tree_add_text( subtree, tvb, offset, 8,
-                                 "  %02x %02x %02x %02x %02x %02x %02x %02x",
-                                 mcid[i+0], mcid[i+1], mcid[i+2], mcid[i+3],
-                                 mcid[i+4], mcid[i+5], mcid[i+6], mcid[i+7]);
-        }
-        proto_tree_add_text( subtree, tvb, offset, 3,
-                             "  %02x %02x %02x",
-                             mcid[i+0], mcid[i+1], mcid[i+2]);
-        offset += 3;
-
-        /* Aux MCID: */
-        proto_tree_add_text( subtree, tvb, offset, MCID_LEN, "Aux MCID:");
-        for (i = 0 ; i < 48 ; i+= 8, offset += 8) {
-            proto_tree_add_text( subtree, tvb, offset, 8,
-                                 "  %02x %02x %02x %02x %02x %02x %02x %02x",
-                                 aux_mcid[i+0], aux_mcid[i+1], aux_mcid[i+2], aux_mcid[i+3],
-                                 aux_mcid[i+4], aux_mcid[i+5], aux_mcid[i+6], aux_mcid[i+7]);
-        }
-        proto_tree_add_text( subtree, tvb, offset, 3,
-                             "  %02x %02x %02x",
-                             aux_mcid[i+0], aux_mcid[i+1], aux_mcid[i+2]);
-        /*offset += 3;*/
-    }
+
+    ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
+                                "SPB MCID: Type: 0x%02x, Length: %d", subtype, sublen);
+    subtree = proto_item_add_subtree(ti, ett_isis_hello_clv_mt_port_cap_spb_mcid);
+
+    /* MCID: */
+    proto_tree_add_item(subtree, hf_isis_hello_mcid, tvb, offset, MCID_LEN, ENC_NA);
+    offset += MCID_LEN;
+
+    /* Aux MCID: */
+    proto_tree_add_item(subtree, hf_isis_hello_aux_mcid, tvb, offset, MCID_LEN, ENC_NA);
+    /* offset += MCID_LEN; */
 }
 
 static void
-dissect_hello_mt_port_cap_spb_digest_clv(tvbuff_t   *tvb,
+dissect_hello_mt_port_cap_spb_digest_clv(tvbuff_t *tvb, packet_info* pinfo,
         proto_tree *tree, int offset, int subtype, int sublen)
 {
     const int DIGEST_LEN = 32;
     const int SUBLEN     = 1 + DIGEST_LEN;
     if (sublen != SUBLEN) {
-        isis_dissect_unknown( tvb, tree, offset,
+        proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, -1,
                               "Short SPB Digest TLV (%d vs %d)", sublen, SUBLEN);
         return;
     }
     else {
         proto_tree *subtree, *ti;
         const guint8 vad     = tvb_get_guint8(tvb, offset);
-        const guint8 *digest = tvb_get_ptr(tvb, offset + 1, DIGEST_LEN);
-        int i;
 
         ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
                                   "SPB Digest: Type: 0x%02x, Length: %d", subtype, sublen);
@@ -432,18 +191,13 @@ dissect_hello_mt_port_cap_spb_digest_clv(tvbuff_t   *tvb,
         ++offset;
 
         /* Digest: */
-        proto_tree_add_text( subtree, tvb, offset, DIGEST_LEN, "Digest:");
-        for (i = 0 ; i < DIGEST_LEN ; i+= 8, offset += 8) {
-            proto_tree_add_text( subtree, tvb, offset, 8,
-                                 "  %02x %02x %02x %02x %02x %02x %02x %02x",
-                                 digest[i+0], digest[i+1], digest[i+2], digest[i+3],
-                                 digest[i+4], digest[i+5], digest[i+6], digest[i+7]);
-        }
+        proto_tree_add_item(subtree, hf_isis_hello_digest, tvb, offset, DIGEST_LEN, ENC_NA);
+        /* offset += DIGEST_LEN; */
     }
 }
 
 static void
-dissect_hello_mt_port_cap_spb_bvid_tuples_clv(tvbuff_t   *tvb,
+dissect_hello_mt_port_cap_spb_bvid_tuples_clv(tvbuff_t *tvb, packet_info* pinfo,
         proto_tree *tree, int offset, int subtype, int sublen)
 {
     proto_tree *subtree, *ti;
@@ -455,7 +209,7 @@ dissect_hello_mt_port_cap_spb_bvid_tuples_clv(tvbuff_t   *tvb,
 
     while (sublen > 0) {
         if (sublen < 6) {
-            isis_dissect_unknown( tvb, subtree, offset,
+            proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, -1,
                                   "Short SPB BVID header entry (%d vs %d)", sublen, 6);
             return;
         }
@@ -482,15 +236,12 @@ dissect_hello_mt_port_cap_spb_bvid_tuples_clv(tvbuff_t   *tvb,
 }
 
 static void
-dissect_hello_mt_port_cap_clv(tvbuff_t   *tvb,
+dissect_hello_mt_port_cap_clv(tvbuff_t *tvb, packet_info* pinfo,
         proto_tree *tree, int offset, int id_length _U_, int length)
 {
     if (length >= 2) {
         /* mtid */
-        guint16 mtid = tvb_get_ntohs(tvb, offset);
-        proto_tree_add_text( tree, tvb, offset, 2,
-                             "MTID: 0x%03x",
-                             (mtid & 0xfff));
+        proto_tree_add_item(tree, hf_isis_hello_mtid, tvb, offset, 2, ENC_BIG_ENDIAN);
         length -= 2;
         offset += 2;
         while (length >= 2) {
@@ -499,22 +250,22 @@ dissect_hello_mt_port_cap_clv(tvbuff_t   *tvb,
             length -= 2;
             offset += 2;
             if (subtlvlen > length) {
-                isis_dissect_unknown( tvb, tree, offset,
+                proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, -1,
                                       "Short type 0x%02x TLV (%d vs %d)", subtype, subtlvlen, length);
                 return;
             }
             if (subtype == 0x04) { /* SPB MCID */
-                dissect_hello_mt_port_cap_spb_mcid_clv(tvb, tree, offset, subtype, subtlvlen);
+                dissect_hello_mt_port_cap_spb_mcid_clv(tvb, pinfo, tree, offset, subtype, subtlvlen);
             }
             else if (subtype == 0x05) { /* SPB Digest */
-                dissect_hello_mt_port_cap_spb_digest_clv(tvb, tree, offset, subtype, subtlvlen);
+                dissect_hello_mt_port_cap_spb_digest_clv(tvb, pinfo, tree, offset, subtype, subtlvlen);
             }
             else if (subtype == 0x06) { /* SPB BVID Tuples */
-                dissect_hello_mt_port_cap_spb_bvid_tuples_clv(tvb, tree, offset, subtype, subtlvlen);
+                dissect_hello_mt_port_cap_spb_bvid_tuples_clv(tvb, pinfo, tree, offset, subtype, subtlvlen);
             }
             else {
-                isis_dissect_unknown( tvb, tree, offset,
-                                      "Unknown SubTlv: Type: 0x%02x, Length: %d", subtype, subtlvlen);
+                proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_subtlv, tvb, offset, -1,
+                         "Unknown SubTlv: Type: 0x%02x, Length: %d", subtype, subtlvlen );
             }
             length -= subtlvlen;
             offset += subtlvlen;
@@ -564,7 +315,7 @@ dissect_hello_mt_port_cap_clv(tvbuff_t   *tvb,
  */
 
 static void
-dissect_hello_restart_clv(tvbuff_t *tvb,
+dissect_hello_restart_clv(tvbuff_t *tvb, packet_info* pinfo _U_,
                proto_tree *tree, int offset, int id_length, int length)
 {
        int restart_options=0;
@@ -604,8 +355,8 @@ dissect_hello_restart_clv(tvbuff_t *tvb,
         * set
         */
        if (length >= 3 && ISIS_MASK_RESTART_RA(restart_options)) {
-           hold_time_item = proto_tree_add_uint ( tree, hf_isis_hello_clv_restart_remain_time,
-                   tvb, offset+1, 2, tvb_get_ntohs(tvb, offset+1) );
+           hold_time_item = proto_tree_add_item( tree, hf_isis_hello_clv_restart_remain_time,
+                   tvb, offset+1, 2, ENC_BIG_ENDIAN );
            proto_item_append_text( hold_time_item, "s" );
        }
 
@@ -639,7 +390,7 @@ dissect_hello_restart_clv(tvbuff_t *tvb,
  *     void, will modify proto_tree if not null.
  */
 static void
-dissect_hello_nlpid_clv(tvbuff_t *tvb,
+dissect_hello_nlpid_clv(tvbuff_t *tvb, packet_info* pinfo _U_,
        proto_tree *tree, int offset, int id_length _U_, int length)
 {
        isis_dissect_nlpid_clv(tvb, tree, offset, length);
@@ -664,7 +415,7 @@ dissect_hello_nlpid_clv(tvbuff_t *tvb,
  */
 
 static void
-dissect_hello_mt_clv(tvbuff_t *tvb,
+dissect_hello_mt_clv(tvbuff_t *tvb, packet_info* pinfo,
        proto_tree *tree, int offset, int id_length _U_, int length)
 {
        isis_dissect_mt_clv(tvb, tree, offset, length,
@@ -689,11 +440,11 @@ dissect_hello_mt_clv(tvbuff_t *tvb,
  *     void, will modify proto_tree if not null.
  */
 static void
-dissect_hello_ip_int_addr_clv(tvbuff_t *tvb,
+dissect_hello_ip_int_addr_clv(tvbuff_t *tvb, packet_info* pinfo, 
        proto_tree *tree, int offset, int id_length _U_, int length)
 {
-       isis_dissect_ip_int_clv(tvb, tree, offset, length,
-               hf_isis_hello_clv_ipv4_int_addr );
+       isis_dissect_ip_int_clv(tree, pinfo, tvb, &ei_isis_hello_short_packet,
+        offset, length, hf_isis_hello_clv_ipv4_int_addr );
 }
 
 /*
@@ -714,11 +465,11 @@ dissect_hello_ip_int_addr_clv(tvbuff_t *tvb,
  *     void, will modify proto_tree if not null.
  */
 static void
-dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb,
+dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb, packet_info* pinfo,
        proto_tree *tree, int offset, int id_length _U_, int length)
 {
-       isis_dissect_ipv6_int_clv(tvb, tree, offset, length,
-               hf_isis_hello_clv_ipv6_int_addr );
+       isis_dissect_ipv6_int_clv(tree, pinfo, tvb, &ei_isis_hello_short_packet,
+        offset, length, hf_isis_hello_clv_ipv6_int_addr );
 }
 
 /*
@@ -739,10 +490,10 @@ dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb,
  *     void, will modify proto_tree if not null.
  */
 static void
-dissect_hello_authentication_clv(tvbuff_t *tvb,
+dissect_hello_authentication_clv(tvbuff_t *tvb, packet_info* pinfo,
        proto_tree *tree, int offset, int id_length _U_, int length)
 {
-       isis_dissect_authentication_clv(tvb, tree, offset, length);
+       isis_dissect_authentication_clv(tree, pinfo, tvb, &ei_isis_hello_authentication, offset, length);
 }
 
 /*
@@ -763,7 +514,7 @@ dissect_hello_authentication_clv(tvbuff_t *tvb,
  *     void, will modify proto_tree if not null.
  */
 static void
-dissect_hello_ip_authentication_clv(tvbuff_t *tvb,
+dissect_hello_ip_authentication_clv(tvbuff_t *tvb, packet_info* pinfo,
        proto_tree *tree, int offset, int id_length _U_, int length)
 {
        isis_dissect_ip_authentication_clv(tvb, tree, offset, length);
@@ -786,54 +537,51 @@ dissect_hello_ip_authentication_clv(tvbuff_t *tvb,
  */
 
 static void
-dissect_hello_checksum_clv(tvbuff_t *tvb,
+dissect_hello_checksum_clv(tvbuff_t *tvb, packet_info* pinfo,
         proto_tree *tree, int offset, int id_length _U_, int length) {
 
-       guint16 pdu_length,checksum, cacl_checksum=0;
-
-       if (tree) {
-                if ( length != 2 ) {
-                        proto_tree_add_text ( tree, tvb, offset, length,
-                                              "incorrect checksum length (%u), should be (2)", length );
-                        return;
-                }
-
-               checksum = tvb_get_ntohs(tvb, offset);
-
-                /* the check_and_get_checksum() function needs to know how big
-                 * the packet is. we can either pass through the pdu-len through several layers
-                 * of dissectors and wrappers or extract the PDU length field from the PDU specific header
-                 * which is offseted 17 bytes in IIHs (relative to the beginning of the IS-IS packet) */
-
-               pdu_length = tvb_get_ntohs(tvb, 17);
-
-                /* unlike the LSP checksum verification which starts at an offset of 12 we start at offset 0*/
-               switch (check_and_get_checksum(tvb, 0, pdu_length, checksum, offset, &cacl_checksum))
-               {
-
-                       case NO_CKSUM :
-                                proto_tree_add_text ( tree, tvb, offset, length,
-                                                      "Checksum: 0x%04x [unused]", checksum);
-                               break;
-                       case DATA_MISSING :
-                               isis_dissect_unknown(tvb, tree, offset,
-                                                     "[packet length %d went beyond packet]",
-                                                     tvb_length(tvb));
-                       break;
-                       case CKSUM_NOT_OK :
-                                proto_tree_add_text ( tree, tvb, offset, length,
-                                                      "Checksum: 0x%04x [incorrect, should be 0x%04x]",
-                                                      checksum,
-                                                      cacl_checksum);
-                       break;
-                       case CKSUM_OK :
-                                proto_tree_add_text ( tree, tvb, offset, length,
-                                                      "Checksum: 0x%04x [correct]", checksum);
-                       break;
-                       default :
-                               g_message("'check_and_get_checksum' returned an invalid value");
-               }
-       }
+    guint16 pdu_length,checksum, cacl_checksum=0;
+
+    if (tree) {
+        if ( length != 2 ) {
+            proto_tree_add_text ( tree, tvb, offset, length,
+                                    "incorrect checksum length (%u), should be (2)", length );
+            return;
+        }
+
+        checksum = tvb_get_ntohs(tvb, offset);
+
+        /* the check_and_get_checksum() function needs to know how big
+         * the packet is. we can either pass through the pdu-len through several layers
+         * of dissectors and wrappers or extract the PDU length field from the PDU specific header
+         * which is offseted 17 bytes in IIHs (relative to the beginning of the IS-IS packet) */
+        pdu_length = tvb_get_ntohs(tvb, 17);
+
+        /* unlike the LSP checksum verification which starts at an offset of 12 we start at offset 0*/
+        switch (check_and_get_checksum(tvb, 0, pdu_length, checksum, offset, &cacl_checksum))
+        {
+            case NO_CKSUM :
+                proto_tree_add_uint_format_value( tree, hf_isis_hello_checksum, tvb, offset, length, checksum,
+                                                "0x%04x [unused]", checksum);
+            break;
+            case DATA_MISSING :
+                proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_long_packet, tvb, offset, -1,
+                        "Packet length %d went beyond packet", tvb_length(tvb) );
+            break;
+            case CKSUM_NOT_OK :
+                proto_tree_add_uint_format_value( tree, hf_isis_hello_checksum, tvb, offset, length, checksum,
+                                                "0x%04x [incorrect, should be 0x%04x]",
+                                                checksum,
+                                                cacl_checksum);
+            break;
+            case CKSUM_OK :
+                proto_tree_add_uint_format_value( tree, hf_isis_hello_checksum, tvb, offset, length, checksum,
+                                                "0x%04x [correct]", checksum);
+            break;
+            default :
+                g_message("'check_and_get_checksum' returned an invalid value");
+        }
+    }
 }
 
 
@@ -856,66 +604,53 @@ dissect_hello_checksum_clv(tvbuff_t *tvb,
  *     void, will modify proto_tree if not null.
  */
 static void
-dissect_hello_area_address_clv(tvbuff_t *tvb,
+dissect_hello_area_address_clv(tvbuff_t *tvb, packet_info* pinfo _U_,
        proto_tree *tree, int offset, int id_length _U_, int length)
 {
-       isis_dissect_area_address_clv(tvb, tree, offset, length);
+       isis_dissect_area_address_clv(tree, pinfo, tvb, &ei_isis_hello_short_packet, offset, length);
 }
 
-
+static const value_string adj_state_vals[] = {
+    { 0, "Up" },
+    { 1, "Initializing" },
+    { 2, "Down" },
+    { 0, NULL }
+};
 
 static void
-dissect_hello_ptp_adj_clv(tvbuff_t *tvb,
+dissect_hello_ptp_adj_clv(tvbuff_t *tvb, packet_info* pinfo,
                proto_tree *tree, int offset, int id_length, int length)
 {
-       static const value_string adj_state_vals[] = {
-           { 0, "Up" },
-           { 1, "Initializing" },
-           { 2, "Down" },
-           { 0, NULL }
-       };
-       guint8 adj_state;
-       const char *adj_state_str;
-
-       adj_state = tvb_get_guint8(tvb, offset);
-       adj_state_str = val_to_str(adj_state, adj_state_vals, "Unknown (%u)");
-       switch(length) {
-         case 1:
-           proto_tree_add_text ( tree, tvb, offset, 1,
-                                 "Adjacency State: %s", adj_state_str );
-           break;
-         case 5:
-           proto_tree_add_text ( tree, tvb, offset, 1,
-                                  "Adjacency State: %s", adj_state_str );
-           proto_tree_add_text ( tree, tvb, offset+1, 4,
-                                  "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
-           break;
-         case 11:
-            proto_tree_add_text ( tree, tvb, offset, 1,
-                                  "Adjacency State: %s", adj_state_str );
-            proto_tree_add_text ( tree, tvb, offset+1, 4,
-                                  "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
-            proto_tree_add_text ( tree, tvb, offset+5, id_length,
-                                  "Neighbor SystemID: %s",
-                                 print_system_id( tvb_get_ptr(tvb, offset+5, id_length), id_length ) );
-           break;
-         case 15:
-           proto_tree_add_text ( tree, tvb, offset, 1,
-                                  "Adjacency State: %s", adj_state_str );
-            proto_tree_add_text ( tree, tvb, offset+1, 4,
-                                  "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
-            proto_tree_add_text ( tree, tvb, offset+5, id_length,
-                                  "Neighbor SystemID: %s",
-                                 print_system_id( tvb_get_ptr(tvb, offset+5, id_length), id_length ) );
-            proto_tree_add_text ( tree, tvb, offset+5+id_length, 4,
-                                  "Neighbor Extended Local circuit ID: 0x%08x",
-                                 tvb_get_ntohl(tvb, offset+5+id_length) );
-           break;
-         default:
-           isis_dissect_unknown(tvb, tree, offset,
-                                "malformed TLV (%d vs 1,5,11,15)", length );
-           return;
-       }
+    const guint8 *source_id;
+
+    switch(length)
+    {
+    case 1:
+        proto_tree_add_item(tree, hf_isis_hello_adjacency_state, tvb, offset, 1, ENC_NA);
+        break;
+    case 5:
+        proto_tree_add_item(tree, hf_isis_hello_adjacency_state, tvb, offset, 1, ENC_NA);
+        proto_tree_add_item(tree, hf_isis_hello_extended_local_circuit_id, tvb, offset+1, 4, ENC_BIG_ENDIAN);
+        break;
+    case 11:
+        proto_tree_add_item(tree, hf_isis_hello_adjacency_state, tvb, offset, 1, ENC_NA);
+        proto_tree_add_item(tree, hf_isis_hello_extended_local_circuit_id, tvb, offset+1, 4, ENC_BIG_ENDIAN);
+        source_id = tvb_get_ptr(tvb, offset+5, id_length);
+        proto_tree_add_bytes_format_value(tree, hf_isis_hello_neighbor_systemid, tvb,
+                        offset+5, id_length, source_id, "%s", print_system_id(source_id, id_length ));
+    break;
+    case 15:
+        proto_tree_add_item(tree, hf_isis_hello_adjacency_state, tvb, offset, 1, ENC_NA);
+        proto_tree_add_item(tree, hf_isis_hello_extended_local_circuit_id, tvb, offset+1, 4, ENC_BIG_ENDIAN);
+        source_id = tvb_get_ptr(tvb, offset+5, id_length);
+        proto_tree_add_bytes_format_value(tree, hf_isis_hello_neighbor_systemid, tvb,
+                        offset+5, id_length, source_id, "%s", print_system_id( source_id, id_length ));
+        proto_tree_add_item(tree, hf_isis_hello_neighbor_extended_local_circuit_id, tvb, offset+5+id_length, 4, ENC_BIG_ENDIAN);
+    break;
+    default:
+        proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, -1,
+                   "malformed TLV (%d vs 1,5,11,15)", length );
+    }
 }
 
 /*
@@ -936,12 +671,12 @@ dissect_hello_ptp_adj_clv(tvbuff_t *tvb,
  *     void, but we will add to proto tree if !NULL.
  */
 static void
-dissect_hello_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_hello_is_neighbors_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
        while ( length > 0 ) {
                if (length<6) {
-                       isis_dissect_unknown(tvb, tree, offset,
+                       proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, -1,
                                "short is neighbor (%d vs 6)", length );
                        return;
                }
@@ -949,10 +684,7 @@ dissect_hello_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
                 * Lets turn the area address into "standard" 0000.0000.etc
                 * format string.
                 */
-               if ( tree ) {
-                       proto_tree_add_text ( tree, tvb, offset, 6,
-                               "IS Neighbor: %s", get_ether_name( tvb_get_ptr(tvb, offset, 6)) );
-               }
+               proto_tree_add_item(tree, hf_isis_hello_is_neighbor, tvb, offset, 6, ENC_NA);
                offset += 6;
                length -= 6;
        }
@@ -976,12 +708,242 @@ dissect_hello_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *     void
  */
 static void
-dissect_hello_padding_clv(tvbuff_t *tvb _U_, proto_tree *tree _U_, int offset _U_,
+dissect_hello_padding_clv(tvbuff_t *tvb _U_, packet_info* pinfo _U_, proto_tree *tree _U_, int offset _U_,
        int id_length _U_, int length _U_)
 {
        /* nothing to do here! */
 }
 
+static const isis_clv_handle_t clv_l1_hello_opts[] = {
+       {
+               ISIS_CLV_AREA_ADDRESS,
+               "Area address(es)",
+               &ett_isis_hello_clv_area_addr,
+               dissect_hello_area_address_clv
+       },
+       {
+               ISIS_CLV_IS_NEIGHBORS,
+               "IS Neighbor(s)",
+               &ett_isis_hello_clv_is_neighbors,
+               dissect_hello_is_neighbors_clv
+       },
+       {
+               ISIS_CLV_PADDING,
+               "Padding",
+               &ett_isis_hello_clv_padding,
+               dissect_hello_padding_clv
+       },
+       {
+               ISIS_CLV_PROTOCOLS_SUPPORTED,
+               "Protocols Supported",
+               &ett_isis_hello_clv_nlpid,
+               dissect_hello_nlpid_clv
+       },
+       {
+               ISIS_CLV_IP_ADDR,
+               "IP Interface address(es)",
+               &ett_isis_hello_clv_ipv4_int_addr,
+               dissect_hello_ip_int_addr_clv
+       },
+       {
+               ISIS_CLV_IP6_ADDR,
+               "IPv6 Interface address(es)",
+               &ett_isis_hello_clv_ipv6_int_addr,
+               dissect_hello_ipv6_int_addr_clv
+       },
+       {
+               ISIS_CLV_RESTART,
+               "Restart Signaling",
+               &ett_isis_hello_clv_restart,
+               dissect_hello_restart_clv
+       },
+       {
+               ISIS_CLV_AUTHENTICATION,
+               "Authentication",
+               &ett_isis_hello_clv_authentication,
+               dissect_hello_authentication_clv
+       },
+       {
+               ISIS_CLV_IP_AUTHENTICATION,
+               "IP Authentication",
+               &ett_isis_hello_clv_ip_authentication,
+               dissect_hello_ip_authentication_clv
+       },
+       {
+               ISIS_CLV_MT_SUPPORTED,
+               "Multi Topology",
+               &ett_isis_hello_clv_mt,
+               dissect_hello_mt_clv
+       },
+       {
+               ISIS_CLV_CHECKSUM,
+               "Checksum",
+               &ett_isis_hello_clv_checksum,
+               dissect_hello_checksum_clv
+       },
+       {
+               0,
+               "",
+               NULL,
+               NULL
+       }
+};
+
+static const isis_clv_handle_t clv_l2_hello_opts[] = {
+       {
+               ISIS_CLV_AREA_ADDRESS,
+               "Area address(es)",
+               &ett_isis_hello_clv_area_addr,
+               dissect_hello_area_address_clv
+       },
+       {
+               ISIS_CLV_IS_NEIGHBORS,
+               "IS Neighbor(s)",
+               &ett_isis_hello_clv_is_neighbors,
+               dissect_hello_is_neighbors_clv
+       },
+       {
+               ISIS_CLV_PADDING,
+               "Padding",
+               &ett_isis_hello_clv_padding,
+               dissect_hello_padding_clv
+       },
+       {
+               ISIS_CLV_PROTOCOLS_SUPPORTED,
+               "Protocols Supported",
+               &ett_isis_hello_clv_nlpid,
+               dissect_hello_nlpid_clv
+       },
+       {
+               ISIS_CLV_IP_ADDR,
+               "IP Interface address(es)",
+               &ett_isis_hello_clv_ipv4_int_addr,
+               dissect_hello_ip_int_addr_clv
+       },
+       {
+               ISIS_CLV_IP6_ADDR,
+               "IPv6 Interface address(es)",
+               &ett_isis_hello_clv_ipv6_int_addr,
+               dissect_hello_ipv6_int_addr_clv
+       },
+       {
+               ISIS_CLV_AUTHENTICATION,
+               "Authentication",
+               &ett_isis_hello_clv_authentication,
+               dissect_hello_authentication_clv
+       },
+       {
+               ISIS_CLV_IP_AUTHENTICATION,
+               "IP Authentication",
+               &ett_isis_hello_clv_ip_authentication,
+               dissect_hello_ip_authentication_clv
+       },
+       {
+               ISIS_CLV_RESTART,
+               "Restart Signaling",
+               &ett_isis_hello_clv_restart,
+               dissect_hello_restart_clv
+       },
+       {
+               ISIS_CLV_MT_SUPPORTED,
+               "Multi Topology",
+               &ett_isis_hello_clv_mt,
+               dissect_hello_mt_clv
+       },
+       {
+               ISIS_CLV_CHECKSUM,
+               "Checksum",
+               &ett_isis_hello_clv_checksum,
+               dissect_hello_checksum_clv
+       },
+       {
+               0,
+               "",
+               NULL,
+               NULL
+       }
+};
+
+static const isis_clv_handle_t clv_ptp_hello_opts[] = {
+       {
+               ISIS_CLV_AREA_ADDRESS,
+               "Area address(es)",
+               &ett_isis_hello_clv_area_addr,
+               dissect_hello_area_address_clv
+       },
+       {
+               ISIS_CLV_PADDING,
+               "Padding",
+               &ett_isis_hello_clv_padding,
+               dissect_hello_padding_clv
+       },
+       {
+               ISIS_CLV_PROTOCOLS_SUPPORTED,
+               "Protocols Supported",
+               &ett_isis_hello_clv_nlpid,
+               dissect_hello_nlpid_clv
+       },
+       {
+               ISIS_CLV_IP_ADDR,
+               "IP Interface address(es)",
+               &ett_isis_hello_clv_ipv4_int_addr,
+               dissect_hello_ip_int_addr_clv
+       },
+       {
+               ISIS_CLV_IP6_ADDR,
+               "IPv6 Interface address(es)",
+               &ett_isis_hello_clv_ipv6_int_addr,
+               dissect_hello_ipv6_int_addr_clv
+       },
+       {
+               ISIS_CLV_AUTHENTICATION,
+               "Authentication",
+               &ett_isis_hello_clv_authentication,
+               dissect_hello_authentication_clv
+       },
+       {
+               ISIS_CLV_IP_AUTHENTICATION,
+               "IP Authentication",
+               &ett_isis_hello_clv_ip_authentication,
+               dissect_hello_ip_authentication_clv
+       },
+       {
+               ISIS_CLV_MT_PORT_CAP,
+               "MT Port Capability",
+               &ett_isis_hello_clv_mt_port_cap,
+               dissect_hello_mt_port_cap_clv
+       },
+       {
+               ISIS_CLV_RESTART,
+               "Restart Option",
+               &ett_isis_hello_clv_restart,
+               dissect_hello_restart_clv
+       },
+       {
+               ISIS_CLV_PTP_ADJ_STATE,
+               "Point-to-point Adjacency State",
+               &ett_isis_hello_clv_ptp_adj,
+               dissect_hello_ptp_adj_clv
+       },
+       {
+               ISIS_CLV_MT_SUPPORTED,
+               "Multi Topology",
+               &ett_isis_hello_clv_mt,
+               dissect_hello_mt_clv
+       },
+       {
+               ISIS_CLV_CHECKSUM,
+               "Checksum",
+               &ett_isis_hello_clv_checksum,
+               dissect_hello_checksum_clv
+       },
+       {
+               0,
+               "",
+               NULL,
+               NULL
+       }
+};
 
 /*
  * Name: isis_dissect_isis_hello()
@@ -990,121 +952,102 @@ dissect_hello_padding_clv(tvbuff_t *tvb _U_, proto_tree *tree _U_, int offset _U
  *     This procedure rips apart the various types of ISIS hellos.  L1H and
  *     L2H's are identical for the most part, while the PTP hello has
  *     a shorter header.
- *
- * Input:
- *     tvbuff_t * : tvbuffer for packet data
- *     proto_tree * : protocol display tree to add to.  May be NULL.
- *     int offset : our offset into packet data.
- *     int : hello type, a la packet-isis.h ISIS_TYPE_* values
- *     int : header length of packet.
- *     int : length of IDs in packet.
- *
- * Output:
- *     void, will modify proto_tree if not NULL.
  */
-void
-isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
-       int hello_type, int header_length, int id_length)
+static void
+dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
+       const isis_clv_handle_t *opts, int header_length, int id_length)
 {
        proto_item      *ti;
-       proto_tree      *hello_tree = NULL;
-       int             len;
-       guint8          octet;
+       proto_tree      *hello_tree;
        const guint8    *source_id;
-       guint16         pdu_length;
+       int                             pdu_length;
        const guint8    *lan_id;
+       gchar* system_id;
 
-       if (tree) {
-               ti = proto_tree_add_text(tree, tvb, offset, -1, "ISIS HELLO");
-               hello_tree = proto_item_add_subtree(ti, ett_isis_hello);
-               octet = tvb_get_guint8(tvb, offset);
-               proto_tree_add_uint_format(hello_tree,
-                       hf_isis_hello_circuit_reserved,
-                       tvb, offset, 1, octet,
-                       "Circuit type              : %s, reserved(0x%02x == 0)",
-                               val_to_str(octet&ISIS_HELLO_CTYPE_MASK,
-                                       isis_hello_circuit_type_vals,
-                                       "Unknown (0x%x)"),
-                               octet&ISIS_HELLO_CT_RESERVED_MASK
-                       );
-       }
+       col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS HELLO");
+
+       ti = proto_tree_add_item(tree, proto_isis_hello, tvb, offset, -1, ENC_NA);
+       hello_tree = proto_item_add_subtree(ti, ett_isis_hello);
+
+       proto_tree_add_item(hello_tree, hf_isis_hello_circuit, tvb, offset, 1, ENC_NA);
+       proto_tree_add_item(hello_tree, hf_isis_hello_circuit_reserved, tvb, offset, 1, ENC_NA);
        offset += 1;
 
-       if (tree) {
-               source_id = tvb_get_ptr(tvb, offset, id_length);
-               proto_tree_add_bytes_format_value(hello_tree, hf_isis_hello_source_id, tvb,
+       source_id = tvb_get_ptr(tvb, offset, id_length);
+       system_id = print_system_id( source_id, id_length );
+       proto_tree_add_bytes_format_value(hello_tree, hf_isis_hello_source_id, tvb,
                                    offset, id_length, source_id,
-                                   "%s", print_system_id( source_id, id_length ) );
-       }
-       col_append_fstr(pinfo->cinfo, COL_INFO, ", System-ID: %s",
-                       print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) );
+                                   "%s", system_id);
+       col_append_fstr(pinfo->cinfo, COL_INFO, ", System-ID: %s", system_id);
 
        offset += id_length;
 
-       if (tree) {
-               proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, tvb,
+       proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, tvb,
                                    offset, 2, ENC_BIG_ENDIAN);
-       }
        offset += 2;
 
        pdu_length = tvb_get_ntohs(tvb, offset);
-       if (tree) {
-               proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb,
+       proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb,
                                    offset, 2, pdu_length);
-       }
        offset += 2;
 
-       if (hello_type == ISIS_TYPE_PTP_HELLO) {
-               if (tree) {
-                       proto_tree_add_item(hello_tree, hf_isis_hello_local_circuit_id, tvb,
+       if (opts == clv_ptp_hello_opts) {
+               proto_tree_add_item(hello_tree, hf_isis_hello_local_circuit_id, tvb,
                                         offset, 1, ENC_BIG_ENDIAN );
-               }
                offset += 1;
        } else {
-               if (tree) {
-                       octet = tvb_get_guint8(tvb, offset);
-                       proto_tree_add_uint_format(hello_tree, hf_isis_hello_priority_reserved, tvb,
-                                   offset, 1, octet,
-                                   "Priority                  : %d, reserved(0x%02x == 0)",
-                                       octet&ISIS_HELLO_PRIORITY_MASK,
-                                       octet&ISIS_HELLO_P_RESERVED_MASK );
-               }
+               proto_tree_add_item(hello_tree, hf_isis_hello_priority, tvb, offset, 1, ENC_NA);
+               proto_tree_add_item(hello_tree, hf_isis_hello_priority_reserved, tvb, offset, 1, ENC_NA);
                offset += 1;
 
-               if (tree) {
-                       lan_id = tvb_get_ptr(tvb, offset, id_length+1);
-                       proto_tree_add_bytes_format_value(hello_tree, hf_isis_hello_lan_id, tvb,
+               lan_id = tvb_get_ptr(tvb, offset, id_length+1);
+               proto_tree_add_bytes_format_value(hello_tree, hf_isis_hello_lan_id, tvb,
                                     offset, id_length + 1, lan_id,
                                         "%s", print_system_id( lan_id, id_length + 1 ) );
-               }
                offset += id_length + 1;
        }
 
-       len = pdu_length;
-       len -= header_length;
-       if (len < 0) {
-               isis_dissect_unknown(tvb, tree, offset,
-                       "Packet header length %d went beyond packet",
-                       header_length );
+       pdu_length -= header_length;
+       if (pdu_length < 0) {
+               expert_add_info_format(pinfo, ti, &ei_isis_hello_long_packet,
+                       "Packet header length %d went beyond packet", header_length );
                return;
        }
        /*
         * Now, we need to decode our CLVs.  We need to pass in
         * our list of valid ones!
         */
-       if (hello_type == ISIS_TYPE_L1_HELLO){
-               isis_dissect_clvs(tvb, hello_tree, offset,
-                       clv_l1_hello_opts, len, id_length,
+       isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
+                       opts, &ei_isis_hello_short_packet, pdu_length, id_length,
                        ett_isis_hello_clv_unknown);
-       } else if (hello_type == ISIS_TYPE_L2_HELLO) {
-               isis_dissect_clvs(tvb, hello_tree, offset,
-                       clv_l2_hello_opts, len, id_length,
-                       ett_isis_hello_clv_unknown);
-       } else {
-               isis_dissect_clvs(tvb, hello_tree, offset,
-                       clv_ptp_hello_opts, len, id_length,
-                       ett_isis_hello_clv_unknown);
-       }
+}
+
+
+static int
+dissect_isis_l1_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+       isis_data_t* isis = (isis_data_t*)data;
+       dissect_isis_hello(tvb, pinfo, tree, 0,
+               clv_l1_hello_opts, isis->header_length, isis->system_id_len);
+       return tvb_length(tvb);
+}
+
+static int
+dissect_isis_l2_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+       isis_data_t* isis = (isis_data_t*)data;
+       dissect_isis_hello(tvb, pinfo, tree, 0,
+               clv_l2_hello_opts, isis->header_length, isis->system_id_len);
+       return tvb_length(tvb);
+}
+
+static int
+dissect_isis_ptp_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+       isis_data_t* isis = (isis_data_t*)data;
+       dissect_isis_hello(tvb, pinfo, tree, 0,
+               clv_ptp_hello_opts, isis->header_length, isis->system_id_len);
+       return tvb_length(tvb);
 }
 
 /*
@@ -1120,11 +1063,16 @@ isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
  *     void
  */
 void
-isis_register_hello(int proto_isis) {
+proto_register_isis_hello(void)
+{
        static hf_register_info hf[] = {
-               { &hf_isis_hello_circuit_reserved,
+               { &hf_isis_hello_circuit,
                { "Circuit type", "isis.hello.circuit_type",
-                       FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+                       FT_UINT8, BASE_HEX, VALS(isis_hello_circuit_type_vals), ISIS_HELLO_CTYPE_MASK, NULL, HFILL }},
+
+               { &hf_isis_hello_circuit_reserved,
+               { "Reserved", "isis.hello.reserved",
+                       FT_UINT8, BASE_HEX, NULL, ISIS_HELLO_CT_RESERVED_MASK, NULL, HFILL }},
 
                { &hf_isis_hello_source_id,
                { "SystemID {Sender of PDU}", "isis.hello.source_id",
@@ -1138,8 +1086,12 @@ isis_register_hello(int proto_isis) {
                { "PDU length", "isis.hello.pdu_length",
                        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
 
-               { &hf_isis_hello_priority_reserved,
+               { &hf_isis_hello_priority,
                 { "Priority", "isis.hello.priority",
+                       FT_UINT8, BASE_DEC, NULL, ISIS_HELLO_PRIORITY_MASK, NULL, HFILL }},
+
+               { &hf_isis_hello_priority_reserved,
+                { "Reserved", "isis.hello.reserved",
                        FT_UINT8, BASE_DEC, NULL, ISIS_HELLO_P_RESERVED_MASK, NULL, HFILL }},
 
                { &hf_isis_hello_lan_id,
@@ -1195,8 +1147,21 @@ isis_register_hello(int proto_isis) {
                { &hf_isis_hello_clv_restart_neighbor,
                { "Restarting Neighbor ID", "isis.hello.clv_restart.neighbor",
                        FT_BYTES, BASE_NONE, NULL, 0x0,
-                       "The System ID of the restarting neighbor", HFILL }}
+                       "The System ID of the restarting neighbor", HFILL }},
+
+      /* Generated from convert_proto_tree_add_text.pl */
+      { &hf_isis_hello_mcid, { "MCID", "isis.hello.mcid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_hello_aux_mcid, { "Aux MCID", "isis.hello.aux_mcid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_hello_digest, { "Digest", "isis.hello.digest", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_hello_mtid, { "MTID", "isis.hello.mtid", FT_UINT16, BASE_HEX, NULL, 0xfff, NULL, HFILL }},
+      { &hf_isis_hello_checksum, { "Checksum", "isis.hello.checksum", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_hello_adjacency_state, { "Adjacency State", "isis.hello.adjacency_state", FT_UINT8, BASE_DEC, VALS(adj_state_vals), 0x0, NULL, HFILL }},
+      { &hf_isis_hello_extended_local_circuit_id, { "Extended Local circuit ID", "isis.hello.extended_local_circuit_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_hello_neighbor_systemid, { "Neighbor SystemID", "isis.hello.neighbor_systemid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_hello_neighbor_extended_local_circuit_id, { "Neighbor Extended Local circuit ID", "isis.hello.neighbor_extended_local_circuit_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_hello_is_neighbor, { "IS Neighbor", "isis.hello.is_neighbor", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }},
        };
+
        static gint *ett[] = {
                &ett_isis_hello,
                &ett_isis_hello_clv_area_addr,
@@ -1220,6 +1185,28 @@ isis_register_hello(int proto_isis) {
                &ett_isis_hello_clv_checksum
        };
 
-       proto_register_field_array(proto_isis, hf, array_length(hf));
+       static ei_register_info ei[] = {
+               { &ei_isis_hello_short_packet, { "isis.hello.short_packet", PI_MALFORMED, PI_ERROR, "Short packet", EXPFILL }},
+               { &ei_isis_hello_long_packet, { "isis.hello.long_packet", PI_MALFORMED, PI_ERROR, "Long packet", EXPFILL }},
+               { &ei_isis_hello_subtlv, { "isis.hello.subtlv.unknown", PI_PROTOCOL, PI_WARN, "Unknown SubTLV", EXPFILL }},
+               { &ei_isis_hello_authentication, { "isis.hello.authentication.unknown", PI_PROTOCOL, PI_WARN, "Unknown authentication type", EXPFILL }},
+       };
+
+       expert_module_t* expert_isis_hello;
+
+       /* Register the protocol name and description */
+       proto_isis_hello = proto_register_protocol("ISIS HELLO", "ISIS HELLO", "isis.hello");
+
+       proto_register_field_array(proto_isis_hello, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));
+       expert_isis_hello = expert_register_protocol(proto_isis_hello);
+       expert_register_field_array(expert_isis_hello, ei, array_length(ei));
+}
+
+void
+proto_reg_handoff_isis_hello(void)
+{
+       dissector_add_uint("isis.type", ISIS_TYPE_L1_HELLO, new_create_dissector_handle(dissect_isis_l1_hello, proto_isis_hello));
+       dissector_add_uint("isis.type", ISIS_TYPE_L2_HELLO, new_create_dissector_handle(dissect_isis_l2_hello, proto_isis_hello));
+       dissector_add_uint("isis.type", ISIS_TYPE_PTP_HELLO, new_create_dissector_handle(dissect_isis_ptp_hello, proto_isis_hello));
 }
diff --git a/epan/dissectors/packet-isis-hello.h b/epan/dissectors/packet-isis-hello.h
deleted file mode 100644 (file)
index b06bf71..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/* packet-isis-hello.h
- * Declares for hello handling inside isis.
- *
- * $Id$
- * Stuart Stanley <stuarts@mxmail.net>
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef _PACKET_ISIS_HELLO_H
-#define _PACKET_ISIS_HELLO_H
-
-/*
- * Declarations for L1/L2 hello base header.
- */
-#define ISIS_HELLO_CTYPE_MASK          0x03
-#define ISIS_HELLO_CT_RESERVED_MASK    0xfc
-#define ISIS_HELLO_PRIORITY_MASK       0x7f
-#define ISIS_HELLO_P_RESERVED_MASK     0x80
-
-#define ISIS_HELLO_TYPE_RESERVED       0
-#define ISIS_HELLO_TYPE_LEVEL_1                1
-#define ISIS_HELLO_TYPE_LEVEL_2                2
-#define ISIS_HELLO_TYPE_LEVEL_12       3
-
-/*
- * misc. bittest macros
- */
-
-#define ISIS_RESTART_RR                 0x01
-#define ISIS_RESTART_RA                 0x02
-#define ISIS_RESTART_SA                 0x04
-#define ISIS_MASK_RESTART_RR(x)            ((x)&ISIS_RESTART_RR)
-#define ISIS_MASK_RESTART_RA(x)            ((x)&ISIS_RESTART_RA)
-#define ISIS_MASK_RESTART_SA(x)            ((x)&ISIS_RESTART_SA)
-
-/*
- * Published API functions.  NOTE, this are "local" API functions and
- * are only valid from with isis decodes.
- */
-extern void isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-       int offset, int hello_type, int header_length,int id_length);
-extern void isis_register_hello(int proto_isis);
-
-#endif /* _PACKET_ISIS_HELLO_H */
index 73220d910d0c92568435436d387260a099e4ea6f..ff1f068e615e8b21d163057d0c2c1dae8697fd05 100644 (file)
 
 #include <glib.h>
 
-#include <epan/ipv4.h>
 #include <epan/packet.h>
+#include <epan/expert.h>
 #include "packet-osi.h"
 #include "packet-isis.h"
 #include "packet-isis-clv.h"
-#include "packet-isis-lsp.h"
 #include <epan/addr_resolv.h>
 #include <epan/addr_and_mask.h>
-#include <epan/expert.h>
+
+/*
+ * Declarations for L1/L2 LSP base header.
+ */
+
+/* P | ATT | HIPPITY | DS FIELD description */
+#define ISIS_LSP_PARTITION_MASK     0x80
+#define ISIS_LSP_PARTITION_SHIFT    7
+#define ISIS_LSP_PARTITION(info)    (((info) & ISIS_LSP_PARTITION_MASK) >> ISIS_LSP_PARTITION_SHIFT)
+
+#define ISIS_LSP_ATT_MASK     0x78
+#define ISIS_LSP_ATT_SHIFT    3
+#define ISIS_LSP_ATT(info)    (((info) & ISIS_LSP_ATT_MASK) >> ISIS_LSP_ATT_SHIFT)
+
+#define ISIS_LSP_ATT_ERROR(info)   ((info) >> 3)
+#define ISIS_LSP_ATT_EXPENSE(info) (((info) >> 2) & 1)
+#define ISIS_LSP_ATT_DELAY(info)   (((info) >> 1) & 1)
+#define ISIS_LSP_ATT_DEFAULT(info) ((info) & 1)
+
+#define ISIS_LSP_HIPPITY_MASK     0x04
+#define ISIS_LSP_HIPPITY_SHIFT    2
+#define ISIS_LSP_HIPPITY(info)    (((info) & ISIS_LSP_HIPPITY_MASK) >> ISIS_LSP_HIPPITY_SHIFT)
+
+#define ISIS_LSP_IS_TYPE_MASK     0x03
+#define ISIS_LSP_IS_TYPE(info)    ((info) & ISIS_LSP_IS_TYPE_MASK)
+
+#define ISIS_LSP_MT_MSHIP_RES_MASK   0xF000
+#define ISIS_LSP_MT_MSHIP_ID_MASK   0x0FFF
+
+
+#define ISIS_LSP_TYPE_UNUSED0          0
+#define ISIS_LSP_TYPE_LEVEL_1          1
+#define ISIS_LSP_TYPE_UNUSED2          2
+#define ISIS_LSP_TYPE_LEVEL_2          3
+
+#define ISIS_LSP_ATTACHED_NONE    0
+#define ISIS_LSP_ATTACHED_DEFAULT 1
+#define ISIS_LSP_ATTACHED_DELAY   2
+#define ISIS_LSP_ATTACHED_EXPENSE 4
+#define ISIS_LSP_ATTACHED_ERROR   8
+
+
+#define ISIS_LSP_CLV_METRIC_SUPPORTED(x)       ((x)&0x80)
+#define ISIS_LSP_CLV_METRIC_IE(x)               ((x)&0x40)
+#define ISIS_LSP_CLV_METRIC_RESERVED(x)                ((x)&0x40)
+#define ISIS_LSP_CLV_METRIC_UPDOWN(x)           ((x)&0x80)
+#define ISIS_LSP_CLV_METRIC_VALUE(x)           ((x)&0x3f)
 
 /* Sub-TLVs under Router Capability TLV
    As per RFC 6326 section 2.3 */
 #define FP_HMAC_LID_MASK   G_GINT64_CONSTANT(0x00000000FFFF)
 
 
+static int proto_isis_lsp = -1;
+
 /* lsp packets */
 static int hf_isis_lsp_pdu_length = -1;
 static int hf_isis_lsp_remaining_life = -1;
@@ -84,6 +131,105 @@ static int hf_isis_lsp_spb_port_count = -1;
 static int hf_isis_lsp_spb_port_id = -1;
 static int hf_isis_lsp_spb_sr_bit = -1;
 static int hf_isis_lsp_spb_spvid = -1;
+/* Generated from convert_proto_tree_add_text.pl */
+static int hf_isis_lsp_grp_address_length = -1;
+static int hf_isis_lsp_mt_cap_spb_instance_v = -1;
+static int hf_isis_lsp_mt_cap_spb_instance_cist_external_root_path_cost = -1;
+static int hf_isis_lsp_rt_capable_tree_used_id_starting_tree_no = -1;
+static int hf_isis_lsp_mt_cap_spb_instance_bridge_priority = -1;
+static int hf_isis_lsp_rt_capable_trees_length = -1;
+static int hf_isis_lsp_mt_cap_spbm_service_identifier_base_vid = -1;
+static int hf_isis_lsp_64_bit_administrative_tag = -1;
+static int hf_isis_lsp_grp_address_number_of_sources = -1;
+static int hf_isis_lsp_ext_is_reachability_traffic_engineering_default_metric = -1;
+static int hf_isis_lsp_grp_address_group_address = -1;
+static int hf_isis_lsp_rt_capable_tree_root_id_nickname = -1;
+static int hf_isis_lsp_ext_is_reachability_ipv4_interface_address = -1;
+static int hf_isis_lsp_ext_ip_reachability_metric = -1;
+static int hf_isis_lsp_ext_ip_reachability_ipv4_prefix = -1;
+static int hf_isis_lsp_eis_neighbors_es_neighbor = -1;
+static int hf_isis_lsp_rt_capable_interested_vlans_length = -1;
+static int hf_isis_lsp_expense_metric = -1;
+static int hf_isis_lsp_ext_is_reachability_link_remote_identifier = -1;
+static int hf_isis_lsp_rt_capable_vlan_group_secondary_vlan_id = -1;
+static int hf_isis_lsp_grp_address_vlan_id = -1;
+static int hf_isis_lsp_rt_capable_trill_length = -1;
+static int hf_isis_lsp_rt_capable_tree_root_id_starting_tree_no = -1;
+static int hf_isis_lsp_rt_capable_interested_vlans_nickname = -1;
+static int hf_isis_lsp_rt_capable_nickname_length = -1;
+static int hf_isis_lsp_ip_reachability_ipv4_prefix = -1;
+static int hf_isis_lsp_grp_address_topology_id = -1;
+static int hf_isis_lsp_ext_is_reachability_ipv4_neighbor_address = -1;
+static int hf_isis_lsp_rt_capable_vlan_group_nth_secondary_vlan_id = -1;
+static int hf_isis_lsp_ipv6_reachability_reserved_bits = -1;
+static int hf_isis_lsp_eis_neighbors_default_metric = -1;
+static int hf_isis_lsp_mt_cap_spb_instance_cist_root_identifier = -1;
+static int hf_isis_lsp_rt_capable_tree_used_id_nickname = -1;
+static int hf_isis_lsp_grp_address_source_address = -1;
+static int hf_isis_lsp_delay_metric = -1;
+static int hf_isis_lsp_ext_is_reachability_link_local_identifier = -1;
+static int hf_isis_lsp_mt_cap_mtid = -1;
+static int hf_isis_lsp_32_bit_administrative_tag = -1;
+static int hf_isis_lsp_ext_is_reachability_is_neighbor = -1;
+static int hf_isis_lsp_reservable_link_bandwidth = -1;
+static int hf_isis_lsp_rt_capable_vlan_group_primary_vlan_id = -1;
+static int hf_isis_lsp_rt_capable_interested_vlans_multicast_ipv4 = -1;
+static int hf_isis_lsp_rt_capable_interested_vlans_multicast_ipv6 = -1;
+static int hf_isis_lsp_mt_cap_spb_instance_number_of_trees = -1;
+static int hf_isis_lsp_mt_cap_spbm_service_identifier_b_mac = -1;
+static int hf_isis_lsp_ipv6_reachability_distribution = -1;
+static int hf_isis_lsp_ipv6_reachability_distribution_internal = -1;
+static int hf_isis_lsp_ipv6_reachability_metric = -1;
+static int hf_isis_lsp_rt_capable_trees_maximum_nof_trees_to_compute = -1;
+static int hf_isis_lsp_rt_capable_interested_vlans_vlan_start_id = -1;
+static int hf_isis_lsp_rt_capable_nickname_nickname_priority = -1;
+static int hf_isis_lsp_ext_is_reachability_metric = -1;
+static int hf_isis_lsp_default_metric = -1;
+static int hf_isis_lsp_ext_ip_reachability_distribution = -1;
+static int hf_isis_lsp_maximum_link_bandwidth = -1;
+static int hf_isis_lsp_rt_capable_tree_root_id_length = -1;
+static int hf_isis_lsp_rt_capable_nickname_tree_root_priority = -1;
+static int hf_isis_lsp_eis_neighbors_delay_metric = -1;
+static int hf_isis_lsp_rt_capable_trill_maximum_version = -1;
+static int hf_isis_lsp_rt_capable_interested_vlans_afs_lost_counter = -1;
+static int hf_isis_lsp_ipv6_reachability_ipv6_prefix = -1;
+static int hf_isis_lsp_eis_neighbors_error_metric = -1;
+static int hf_isis_lsp_rt_capable_interested_vlans_vlan_end_id = -1;
+static int hf_isis_lsp_error_metric = -1;
+static int hf_isis_lsp_grp_address_number_of_records = -1;
+static int hf_isis_lsp_rt_capable_tree_used_id_length = -1;
+static int hf_isis_lsp_rt_capable_nickname_nickname = -1;
+static int hf_isis_lsp_mt_id_reserved = -1;
+static int hf_isis_lsp_eis_neighbors_is_neighbor = -1;
+static int hf_isis_lsp_mt_id = -1;
+static int hf_isis_lsp_eis_neighbors_reserved = -1;
+static int hf_isis_lsp_ip_reachability_error_metric = -1;
+static int hf_isis_lsp_ip_reachability_delay_metric = -1;
+static int hf_isis_lsp_ip_reachability_expense_metric = -1;
+static int hf_isis_lsp_rt_capable_trees_nof_trees_to_use = -1;
+static int hf_isis_lsp_ip_reachability_default_metric = -1;
+static int hf_isis_lsp_rt_capable_trees_nof_trees_to_compute = -1;
+static int hf_isis_lsp_eis_neighbors_expense_metric = -1;
+static int hf_isis_lsp_rt_capable_vlan_group_length = -1;
+static int hf_isis_lsp_partition_designated_l2_is = -1;
+static int hf_isis_lsp_ip_reachability_default_metric_ie = -1;
+static int hf_isis_lsp_eis_neighbors_default_metric_ie = -1;
+static int hf_isis_lsp_eis_neighbors_error_metric_supported = -1;
+static int hf_isis_lsp_unrsv_bw_priority_level = -1;
+static int hf_isis_lsp_ip_reachability_expense_metric_support = -1;
+static int hf_isis_lsp_mt_cap_overload = -1;
+static int hf_isis_lsp_eis_neighbors_expense_metric_supported = -1;
+static int hf_isis_lsp_ip_reachability_delay_metric_support = -1;
+static int hf_isis_lsp_ip_reachability_error_metric_support = -1;
+static int hf_isis_lsp_mt_cap_spsourceid = -1;
+static int hf_isis_lsp_eis_neighbors_delay_metric_supported = -1;
+static int hf_isis_lsp_eis_neighbors_error_metric_ie = -1;
+static int hf_isis_lsp_eis_neighbors_expense_metric_ie = -1;
+static int hf_isis_lsp_eis_neighbors_delay_metric_ie = -1;
+static int hf_isis_lsp_ip_reachability_delay_metric_ie = -1;
+static int hf_isis_lsp_ip_reachability_distribution = -1;
+static int hf_isis_lsp_ip_reachability_error_metric_ie = -1;
+static int hf_isis_lsp_ip_reachability_expense_metric_ie = -1;
 
 static gint ett_isis_lsp = -1;
 static gint ett_isis_lsp_info = -1;
@@ -125,6 +271,10 @@ static gint ett_isis_lsp_clv_grp_address_IPv4_prefx = -1;  /* CLV 142 */
 static gint ett_isis_lsp_clv_mt_cap_spbv_mac_address = -1;
 
 static expert_field ie_isis_lsp_checksum_bad = EI_INIT;
+static expert_field ei_isis_lsp_short_packet = EI_INIT;
+static expert_field ei_isis_lsp_long_packet = EI_INIT;
+static expert_field ei_isis_lsp_subtlv = EI_INIT;
+static expert_field ei_isis_lsp_authentication = EI_INIT;
 
 static const value_string isis_lsp_istype_vals[] = {
        { ISIS_LSP_TYPE_UNUSED0,        "Unused 0x0 (invalid)"},
@@ -133,339 +283,10 @@ static const value_string isis_lsp_istype_vals[] = {
        { ISIS_LSP_TYPE_LEVEL_2,        "Level 2"},
        { 0, NULL } };
 
-
-/*
- * Predclare dissectors for use in clv dissection.
- */
-static void dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_partition_dis_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_area_address_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_isis_lsp_clv_mt_cap(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_authentication_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_ip_authentication_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_te_router_id_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_hostname_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_mt_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_nlpid_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_ip_reachability_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_ipreach_subclv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int clv_code, int clv_len);
-static void dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_isis_rt_capable_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_isis_grp_address_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length,int length);
-static void fp_get_hmac_addr (guint64 hmac, guint16 *swid,
-       guint16 *sswid, guint16 *lid);
-
-static const isis_clv_handle_t clv_l1_lsp_opts[] = {
-       {
-               ISIS_CLV_AREA_ADDRESS,
-               "Area address(es)",
-               &ett_isis_lsp_clv_area_addr,
-               dissect_lsp_area_address_clv
-       },
-       {
-               ISIS_CLV_IS_REACH,
-               "IS Reachability",
-               &ett_isis_lsp_clv_is_neighbors,
-               dissect_lsp_l1_is_neighbors_clv
-       },
-       {
-               ISIS_CLV_ES_NEIGHBORS,
-               "ES Neighbor(s)",
-               &ett_isis_lsp_clv_is_neighbors,
-               dissect_lsp_l1_es_neighbors_clv
-       },
-       {
-               ISIS_CLV_EXTD_IS_REACH,
-               "Extended IS reachability",
-               &ett_isis_lsp_clv_ext_is_reachability,
-               dissect_lsp_ext_is_reachability_clv
-       },
-       {
-               ISIS_CLV_INT_IP_REACH,
-               "IP Internal reachability",
-               &ett_isis_lsp_clv_ip_reachability,
-               dissect_lsp_ip_reachability_clv
-       },
-       {
-               ISIS_CLV_EXT_IP_REACH,
-               "IP External reachability",
-               &ett_isis_lsp_clv_ip_reachability,
-               dissect_lsp_ip_reachability_clv
-       },
-       {
-               ISIS_CLV_EXTD_IP_REACH,
-               "Extended IP Reachability",
-               &ett_isis_lsp_clv_ext_ip_reachability,
-               dissect_lsp_ext_ip_reachability_clv
-       },
-       {
-               ISIS_CLV_IP6_REACH,
-               "IPv6 reachability",
-               &ett_isis_lsp_clv_ipv6_reachability,
-               dissect_lsp_ipv6_reachability_clv
-       },
-       {
-               ISIS_CLV_PROTOCOLS_SUPPORTED,
-               "Protocols supported",
-               &ett_isis_lsp_clv_nlpid,
-               dissect_lsp_nlpid_clv
-       },
-       {
-               ISIS_CLV_HOSTNAME,
-               "Hostname",
-               &ett_isis_lsp_clv_hostname,
-               dissect_lsp_hostname_clv
-       },
-       {
-               ISIS_CLV_TE_ROUTER_ID,
-               "Traffic Engineering Router ID",
-               &ett_isis_lsp_clv_te_router_id,
-               dissect_lsp_te_router_id_clv
-       },
-       {
-               ISIS_CLV_IP_ADDR,
-               "IP Interface address(es)",
-               &ett_isis_lsp_clv_ipv4_int_addr,
-               dissect_lsp_ip_int_addr_clv
-       },
-       {
-               ISIS_CLV_IP6_ADDR,
-               "IPv6 Interface address(es)",
-               &ett_isis_lsp_clv_ipv6_int_addr,
-               dissect_lsp_ipv6_int_addr_clv
-       },
-       {
-               ISIS_CLV_MT_CAP,
-               "MT-Capability",
-               &ett_isis_lsp_clv_mt_cap,
-               dissect_isis_lsp_clv_mt_cap
-       },
-       {
-               ISIS_CLV_AUTHENTICATION,
-               "Authentication",
-               &ett_isis_lsp_clv_authentication,
-               dissect_lsp_authentication_clv
-       },
-       {
-               ISIS_CLV_IP_AUTHENTICATION,
-               "IP Authentication",
-               &ett_isis_lsp_clv_ip_authentication,
-               dissect_lsp_ip_authentication_clv
-       },
-       {
-               ISIS_CLV_MT_SUPPORTED,
-               "Multi Topology supported",
-               &ett_isis_lsp_clv_mt,
-               dissect_lsp_mt_clv
-       },
-       {
-               ISIS_CLV_MT_IS_REACH,
-               "Multi Topology IS Reachability",
-               &ett_isis_lsp_clv_mt_is,
-               dissect_lsp_mt_is_reachability_clv
-       },
-       {
-               ISIS_CLV_MT_IP_REACH,
-               "Multi Topology Reachable IPv4 Prefixes",
-               &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
-               dissect_lsp_mt_reachable_IPv4_prefx_clv
-       },
-       {
-               ISIS_CLV_MT_IP6_REACH,
-               "Multi Topology Reachable IPv6 Prefixes",
-               &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
-               dissect_lsp_mt_reachable_IPv6_prefx_clv
-       },
-       {
-               ISIS_CLV_RT_CAPABLE,
-               "Router Capability",
-               &ett_isis_lsp_clv_rt_capable_IPv4_prefx,
-               dissect_isis_rt_capable_clv
-       },
-       {
-               ISIS_GRP_ADDR,
-               "GROUP ADDRESS TLV",
-               &ett_isis_lsp_clv_grp_address_IPv4_prefx,
-               dissect_isis_grp_address_clv
-       },
-       {
-               0,
-               "",
-               NULL,
-               NULL
-       }
-};
-
-static const isis_clv_handle_t clv_l2_lsp_opts[] = {
-       {
-               ISIS_CLV_AREA_ADDRESS,
-               "Area address(es)",
-               &ett_isis_lsp_clv_area_addr,
-               dissect_lsp_area_address_clv
-       },
-       {
-               ISIS_CLV_IS_REACH,
-               "IS Reachability",
-               &ett_isis_lsp_clv_is_neighbors,
-               dissect_lsp_l2_is_neighbors_clv
-       },
-       {
-               ISIS_CLV_EXTD_IS_REACH,
-               "Extended IS reachability",
-               &ett_isis_lsp_clv_ext_is_reachability,
-               dissect_lsp_ext_is_reachability_clv
-       },
-       {
-               ISIS_CLV_PARTITION_DIS,
-               "Partition Designated Level 2 IS",
-               &ett_isis_lsp_clv_partition_dis,
-               dissect_lsp_partition_dis_clv
-       },
-       {
-               ISIS_CLV_PREFIX_NEIGHBORS,
-               "Prefix neighbors",
-               &ett_isis_lsp_clv_prefix_neighbors,
-               dissect_lsp_prefix_neighbors_clv
-       },
-       {
-               ISIS_CLV_INT_IP_REACH,
-               "IP Internal reachability",
-               &ett_isis_lsp_clv_ip_reachability,
-               dissect_lsp_ip_reachability_clv
-       },
-       {
-               ISIS_CLV_EXT_IP_REACH,
-               "IP External reachability",
-               &ett_isis_lsp_clv_ip_reachability,
-               dissect_lsp_ip_reachability_clv
-       },
-       {
-               ISIS_CLV_PROTOCOLS_SUPPORTED,
-               "Protocols supported",
-               &ett_isis_lsp_clv_nlpid,
-               dissect_lsp_nlpid_clv
-       },
-       {
-               ISIS_CLV_HOSTNAME,
-               "Hostname",
-               &ett_isis_lsp_clv_hostname,
-               dissect_lsp_hostname_clv
-       },
-       {
-               ISIS_CLV_TE_ROUTER_ID,
-               "Traffic Engineering Router ID",
-               &ett_isis_lsp_clv_te_router_id,
-               dissect_lsp_te_router_id_clv
-       },
-       {
-               ISIS_CLV_EXTD_IP_REACH,
-               "Extended IP Reachability",
-               &ett_isis_lsp_clv_ext_ip_reachability,
-               dissect_lsp_ext_ip_reachability_clv
-       },
-       {
-               ISIS_CLV_IP6_REACH,
-               "IPv6 reachability",
-               &ett_isis_lsp_clv_ipv6_reachability,
-               dissect_lsp_ipv6_reachability_clv
-       },
-       {
-               ISIS_CLV_IP_ADDR,
-               "IP Interface address(es)",
-               &ett_isis_lsp_clv_ipv4_int_addr,
-               dissect_lsp_ip_int_addr_clv
-       },
-       {
-               ISIS_CLV_IP6_ADDR,
-               "IPv6 Interface address(es)",
-               &ett_isis_lsp_clv_ipv6_int_addr,
-               dissect_lsp_ipv6_int_addr_clv
-       },
-       {
-               ISIS_CLV_MT_CAP,
-               "MT-Capability",
-               &ett_isis_lsp_clv_mt_cap,
-               dissect_isis_lsp_clv_mt_cap
-       },
-       {
-               ISIS_CLV_AUTHENTICATION,
-               "Authentication",
-               &ett_isis_lsp_clv_authentication,
-               dissect_lsp_authentication_clv
-       },
-       {
-               ISIS_CLV_IP_AUTHENTICATION,
-               "IP Authentication",
-               &ett_isis_lsp_clv_ip_authentication,
-               dissect_lsp_ip_authentication_clv
-       },
-       {
-               ISIS_CLV_MT_SUPPORTED,
-               "Multi Topology",
-               &ett_isis_lsp_clv_mt,
-               dissect_lsp_mt_clv
-       },
-       {
-               ISIS_CLV_MT_IS_REACH,
-               "Multi Topology IS Reachability",
-               &ett_isis_lsp_clv_mt_is,
-               dissect_lsp_mt_is_reachability_clv
-       },
-       {
-               ISIS_CLV_MT_IP_REACH,
-               "Multi Topology Reachable IPv4 Prefixes",
-               &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
-               dissect_lsp_mt_reachable_IPv4_prefx_clv
-       },
-       {
-               ISIS_CLV_MT_IP6_REACH,
-               "Multi Topology Reachable IPv6 Prefixes",
-               &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
-               dissect_lsp_mt_reachable_IPv6_prefx_clv
-       },
-       {
-               0,
-               "",
-               NULL,
-               NULL
-       }
-};
-
+static const true_false_string tfs_up_down = { "Up", "Down" };
+static const true_false_string tfs_notsupported_supported = { "Not Supported", "Supported" };
+static const true_false_string tfs_internal_external = { "Internal", "External" };
+static const true_false_string tfs_external_internal = { "External", "Internal" };
 
 static void
 fp_get_hmac_addr (guint64 hmac, guint16 *swid, guint16 *sswid, guint16 *lid) {
@@ -501,10 +322,9 @@ dissect_lsp_mt_id(tvbuff_t *tvb, proto_tree *tree, int offset)
        /* fetch two bytes */
        mt_block = tvb_get_ntohs(tvb, offset);
 
-       proto_tree_add_text ( tree, tvb, offset, 1 ,
-                            "4 most significant bits reserved, should be set to 0 (%d)", ISIS_LSP_MT_MSHIP_RES(mt_block));
+       proto_tree_add_item(tree, hf_isis_lsp_mt_id_reserved, tvb, offset, 2, ENC_NA);
 
-       mt_id = ISIS_LSP_MT_MSHIP_ID(mt_block);
+       mt_id = mt_block & ISIS_LSP_MT_MSHIP_ID_MASK;
        /*mask out the lower 12 bits */
        switch(mt_id) {
        case 0:
@@ -526,8 +346,8 @@ dissect_lsp_mt_id(tvbuff_t *tvb, proto_tree *tree, int offset)
                mt_desc=((mt_block & 0x0fff) < 3996) ? "Reserved for IETF Consensus" : "Development, Experimental and Proprietary features";
        }
 
-       proto_tree_add_text ( tree, tvb, offset, 2 ,
-                            "%s (%d)", mt_desc, mt_id);
+       proto_tree_add_uint_format( tree, hf_isis_lsp_mt_id, tvb, offset, 2,
+                            mt_id, "%s (%d)", mt_desc, mt_id);
 
 }
 
@@ -596,7 +416,7 @@ dissect_metric(tvbuff_t *tvb, proto_tree *tree,     int offset, guint8 value,
  *     void, will modify proto_tree if not null.
  */
 static void
-dissect_lsp_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_ip_reachability_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
        proto_item      *ti;
@@ -607,7 +427,7 @@ dissect_lsp_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
 
        while ( length > 0 ) {
                if (length<12) {
-                       isis_dissect_unknown(tvb, tree, offset,
+                       proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                                "short IP reachability (%d vs 12)", length );
                        return;
                }
@@ -632,50 +452,30 @@ dissect_lsp_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
                        /* XXX - We should probably have some sort of netmask_to_str() routine in to_str.c that does this. */
 
                        if(found_mask) {
-                         ti = proto_tree_add_text ( tree, tvb, offset, 12,
-                               "IPv4 prefix: %s/%d",
-                               ip_to_str((guint8*)&src),
-                               prefix_len );
+                         ti = proto_tree_add_ipv4_format_value( tree, hf_isis_lsp_ip_reachability_ipv4_prefix, tvb, offset, 12,
+                               src, "%s/%d", ip_to_str((guint8*)&src), prefix_len );
                        } else {
-                               ti = proto_tree_add_text ( tree, tvb, offset, 12,
-                               "IPv4 prefix: %s mask %s",
-                               ip_to_str((guint8*)&src),
-                               tvb_ip_to_str(tvb, offset+8));
+                         ti = proto_tree_add_ipv4_format_value( tree, hf_isis_lsp_ip_reachability_ipv4_prefix, tvb, offset, 12,
+                               src, "%s mask %s", ip_to_str((guint8*)&src), tvb_ip_to_str(tvb, offset+8));
                        };
 
-                       ntree = proto_item_add_subtree(ti,
-                               ett_isis_lsp_clv_ip_reachability);
+                       ntree = proto_item_add_subtree(ti, ett_isis_lsp_clv_ip_reachability);
 
-                       proto_tree_add_text (ntree, tvb, offset, 1,
-                               "Default Metric: %d, %s, Distribution: %s",
-                               ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
-                               ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal",
-                               ISIS_LSP_CLV_METRIC_UPDOWN(tvb_get_guint8(tvb, offset)) ? "down" : "up");
+                       proto_tree_add_item(ntree, hf_isis_lsp_ip_reachability_default_metric, tvb, offset, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_ip_reachability_default_metric_ie, tvb, offset, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_ip_reachability_distribution, tvb, offset, 1, ENC_NA);
 
+                       proto_tree_add_item(ntree, hf_isis_lsp_ip_reachability_delay_metric, tvb, offset+1, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_ip_reachability_delay_metric_support, tvb, offset+1, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_ip_reachability_delay_metric_ie, tvb, offset+1, 1, ENC_NA);
 
-                       if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
-                               proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric:   Not supported");
-                       } else {
-                               proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric:   %d, %s",
-                                                    ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
-                                                    ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
-                       }
-
-                       if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
-                               proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
-                       } else {
-                               proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric:  %d, %s",
-                                                    ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
-                                                    ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
-                       }
+                       proto_tree_add_item(ntree, hf_isis_lsp_ip_reachability_expense_metric, tvb, offset+2, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_ip_reachability_expense_metric_support, tvb, offset+2, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_ip_reachability_expense_metric_ie, tvb, offset+2, 1, ENC_NA);
 
-                       if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
-                               proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric:   Not supported");
-                       } else {
-                               proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric:   %d, %s",
-                                                    ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
-                                                    ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
-                       }
+                       proto_tree_add_item(ntree, hf_isis_lsp_ip_reachability_error_metric, tvb, offset+3, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_ip_reachability_error_metric_support, tvb, offset+3, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_ip_reachability_error_metric_ie, tvb, offset+3, 1, ENC_NA);
                }
                offset += 12;
                length -= 12;
@@ -703,20 +503,14 @@ dissect_ipreach_subclv(tvbuff_t *tvb, proto_tree *tree, int offset, int clv_code
        switch (clv_code) {
        case 1:
                while (clv_len >= 4) {
-                       proto_tree_add_text(tree, tvb, offset, 4,
-                                           "32-Bit Administrative tag: 0x%08x (=%u)",
-                                           tvb_get_ntohl(tvb, offset),
-                                           tvb_get_ntohl(tvb, offset));
+                       proto_tree_add_item(tree, hf_isis_lsp_32_bit_administrative_tag, tvb, offset, 4, ENC_BIG_ENDIAN);
                        offset+=4;
                        clv_len-=4;
                }
                break;
        case 2:
                while (clv_len >= 8) {
-                       proto_tree_add_text(tree, tvb, offset, 8,
-                                           "64-Bit Administrative tag: 0x%08x%08x",
-                                           tvb_get_ntohl(tvb, offset),
-                                           tvb_get_ntohl(tvb, offset+4));
+                       proto_tree_add_item(tree, hf_isis_lsp_64_bit_administrative_tag, tvb, offset, 8, ENC_BIG_ENDIAN);
                        offset+=8;
                        clv_len-=8;
                }
@@ -755,7 +549,7 @@ dissect_ipreach_subclv(tvbuff_t *tvb, proto_tree *tree, int offset, int clv_code
  *   void, will modify proto_tree if not null.
  */
 static void
-dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
+dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree,
        int offset, int id_length _U_, int length)
 {
        proto_item *pi = NULL;
@@ -777,7 +571,7 @@ dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
                bit_length = ctrl_info & 0x3f;
                byte_length = ipv4_addr_and_mask(tvb, offset+5, prefix, bit_length);
                if (byte_length == -1) {
-                        isis_dissect_unknown(tvb, tree, offset,
+                       proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                                "IPv4 prefix has an invalid length: %d bits", bit_length );
                                return;
                        }
@@ -786,24 +580,14 @@ dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
                if ((ctrl_info & 0x40) != 0)
                        subclvs_len = 1+tvb_get_guint8(tvb, offset+5+byte_length);
 
-               pi = proto_tree_add_text (tree, tvb, offset, 5+byte_length+subclvs_len,
-                                         "IPv4 prefix: %s/%d, Metric: %u, Distribution: %s, %ssub-TLVs present",
-                                         ip_to_str (prefix),
-                                         bit_length,
-                                         metric,
-                                         ((ctrl_info & 0x80) == 0) ? "up" : "down",
-                                         ((ctrl_info & 0x40) == 0) ? "no " : "" );
-
                /* open up a new tree per prefix */
+               pi = proto_tree_add_text (tree, tvb, offset, 5+byte_length+subclvs_len, "Ext. IP Reachability");
                subtree = proto_item_add_subtree (pi, ett_isis_lsp_part_of_clv_ext_ip_reachability);
 
-               proto_tree_add_text (subtree, tvb, offset+5, byte_length, "IPv4 prefix: %s/%u",
-                                    ip_to_str (prefix), bit_length);
-
-               proto_tree_add_text (subtree, tvb, offset, 4, "Metric: %u", metric);
-
-               proto_tree_add_text (subtree, tvb, offset+4, 1, "Distribution: %s",
-                                    ((ctrl_info & 0x80) == 0) ? "up" : "down");
+               proto_tree_add_ipv4_format_value(subtree, hf_isis_lsp_ext_ip_reachability_ipv4_prefix, tvb, offset+5, byte_length,
+                             tvb_get_ntohl(tvb, offset+5), "%s/%u", ip_to_str (prefix), bit_length);
+               proto_tree_add_item(subtree, hf_isis_lsp_ext_ip_reachability_metric, tvb, offset, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(subtree, hf_isis_lsp_ext_ip_reachability_distribution, tvb, offset+4, 1, ENC_NA);
 
                len = 5 + byte_length;
                if ((ctrl_info & 0x40) != 0) {
@@ -859,11 +643,10 @@ dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
  */
 
 static void
-dissect_isis_grp_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_isis_grp_address_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int tree_id,int length)
 {
        gint len;
-       gint record_num;
        gint source_num;
        gint k=1;
        guint16 mt_block;
@@ -875,9 +658,6 @@ dissect_isis_grp_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
        proto_item *ti=NULL;
        proto_tree *rt_tree=NULL;
 
-       const char *mt_desc;
-
-
        while (length>0) {
                /* fetch two bytes */
                mt_block=tvb_get_ntohs(tvb, offset);
@@ -886,76 +666,72 @@ dissect_isis_grp_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
 
 
                        case GRP_MAC_ADDRESS:
-                               mt_desc="GROUP MAC ADDRESS";
-
-                               ti = proto_tree_add_text (tree, tvb, offset,(mt_block&0x00ff)+2 , "%s SUB TLV", mt_desc);
+                               ti = proto_tree_add_text (tree, tvb, offset, (mt_block&0x00ff)+2, "GROUP MAC ADDRESS SUB TLV");
                                rt_tree = proto_item_add_subtree(ti,ett_isis_lsp_clv_grp_address_IPv4_prefx);
 
-                               length=length-1;
-                               offset=offset+1;
+                               length--;
+                               offset++;
 
                                len=tvb_get_guint8(tvb, offset);/* 1 byte fetched displays the length*/
-                               proto_tree_add_text (rt_tree, tvb, offset,1,"   Length :%d ",len);
+                               proto_tree_add_item(rt_tree, hf_isis_lsp_grp_address_length, tvb, offset, 1, ENC_NA);
 
                                if(len < 5) {
-                                       length=length-len;
-                                       offset=offset+len;
+                                       length -= len;
+                                       offset += len;
                                        break;
                                }
 
-                               length=length-1;
-                               offset=offset+1;
+                               length--;
+                               offset++;
 
+                               proto_tree_add_item(rt_tree, hf_isis_lsp_grp_address_topology_id, tvb, offset, 2, ENC_BIG_ENDIAN);
 
-                               mt_block=tvb_get_ntohs(tvb, offset);/* Fetch the data in the next two bytes for display*/
-                               proto_tree_add_text (rt_tree, tvb, offset,2,"   Topology ID:%d ",(mt_block&0x0fff) );
+                               length -= 2;
+                               offset += 2;
+                               len -= 2;
 
+                               proto_tree_add_item(rt_tree, hf_isis_lsp_grp_address_vlan_id, tvb, offset, 2, ENC_BIG_ENDIAN);
 
-                               length=length-2;
-                               offset=offset+2;
-                               len=len-2;
+                               length -= 2;
+                               offset += 2;
+                               len -= 2;
 
-                               mt_block=tvb_get_ntohs(tvb, offset);/* Fetch the data in the next two bytes for display*/
-                               proto_tree_add_text (rt_tree,tvb, offset,2,"   VLAN ID:%d ",(mt_block&0x0fff) );
+                               proto_tree_add_item(rt_tree, hf_isis_lsp_grp_address_number_of_records, tvb, offset, 1, ENC_NA);
 
-                               length=length-2;
-                               offset=offset+2;
-                               len=len-2;
-
-                               record_num=tvb_get_guint8(tvb, offset);/* 1 byte fetched displays the length*/
-                               proto_tree_add_text (rt_tree,tvb, offset,1, "   Number of records :%d ",record_num);
-
-                               length=length-1;
-                               offset=offset+1;
-                               len=len-1;
+                               length--;
+                               offset++;
+                               len--;
 
                                while(len > 0) {
 
                                        source_num=tvb_get_guint8(tvb, offset);
-                                       proto_tree_add_text (rt_tree,tvb, offset,1,"   Number of sources :%d ",source_num);
+                                       proto_tree_add_item(rt_tree, hf_isis_lsp_grp_address_number_of_sources, tvb, offset, 1, ENC_NA);
 
-                                       length=length-1;
-                                       offset=offset+1;
-                                       len=len-1;
+                                       length--;
+                                       offset++;
+                                       len--;
 
                                        hmac_src=tvb_get_ntoh48(tvb, offset);/* Fetch the data in the next two bytes for display*/
 
                                        fp_get_hmac_addr (hmac_src, &swid, &sswid, &lid);
-                                       proto_tree_add_text (rt_tree,tvb, offset,6,"  Group Address:%04x.%04x.%04x ",swid, sswid, lid );
+                                       proto_tree_add_bytes_format_value(rt_tree, hf_isis_lsp_grp_address_group_address, tvb, offset, 6,
+                                                tvb_get_ptr(tvb, offset, 6), "%04x.%04x.%04x", swid, sswid, lid );
 
-                                       length=length-6;
-                                       offset=offset+6;
-                                       len=len-6;
+                                       length -= 6;
+                                       offset += 6;
+                                       len -= 6;
 
                                        while((len > 0) && (source_num > 0)) {
                                                hmac_src = tvb_get_ntoh48 (tvb, offset);
                                                fp_get_hmac_addr (hmac_src, &swid, &sswid, &lid);
-                                               proto_tree_add_text (rt_tree,tvb, offset,6,"  Source Address (%d):%04x.%04x.%04x",k,swid, sswid, lid);
-
-                                               k=k+1;
-                                               length=length-6;
-                                               offset=offset+6;
-                                               len=len-6;
+                                               proto_tree_add_bytes_format(rt_tree, hf_isis_lsp_grp_address_source_address, tvb, offset, 6,
+                                                tvb_get_ptr(tvb, offset, 6), "Source Address (%d):%04x.%04x.%04x",
+                                                k, swid, sswid, lid);
+
+                                               k++;
+                                               length -= 6;
+                                               offset += 6;
+                                               len -= 6;
                                                source_num--;
                                        }
                                }
@@ -964,13 +740,11 @@ dissect_isis_grp_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
 
 
                        default:
-                               mt_desc="INVALID";
                                proto_tree_add_uint_format ( tree, tree_id, tvb, offset,(mt_block&0x00ff)+2,
-                                               mt_block,
-                                               "%s SUB TLV",mt_desc );
-                               offset=offset+1;
-                               length=length-2-(tvb_get_guint8(tvb, offset));
-                               offset=offset+1+(tvb_get_guint8(tvb, offset));
+                                               mt_block, "INVALID SUB TLV");
+                               offset++;
+                               length -= (2+tvb_get_guint8(tvb, offset));
+                               offset += (1+tvb_get_guint8(tvb, offset));
                                break;
                }
        }
@@ -1000,16 +774,14 @@ dissect_isis_grp_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
 
 /* As per RFC 6326 section 2.3 */
 static void
-dissect_isis_rt_capable_clv(tvbuff_t *tvb,
+dissect_isis_rt_capable_clv(tvbuff_t *tvb, packet_info* pinfo,
         proto_tree *tree, int offset, int id_length _U_, int length)
 {
        gint len;
        guint16 rt_block;
-       guint32 rt_block1;
        proto_item *ti;
        proto_tree *rt_tree;
 
-       const char *mt_desc;
        gint root_id = 1;       /* To display the root id */
        gint sec_vlan_id = 1;   /* To display the seconadary VLAN id */
        length = length - 5;    /* Ignoring the 5 reserved bytes */
@@ -1023,126 +795,99 @@ dissect_isis_rt_capable_clv(tvbuff_t *tvb,
                switch ((rt_block&0xff00)>>8) {
 
                case TRILL_VERSION:
-                       mt_desc = "TRILL version";
-
-                       ti = proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
-
+                       ti = proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "TRILL version sub tlv");
                        rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
 
-                       length = length-1;
-                       offset = offset+1;
+                       length--;
+                       offset++;
 
-                       len = tvb_get_guint8(tvb, offset); /* 1 byte fetched displays the length */
-                       proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_trill_length, tvb, offset, 1, ENC_NA);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_trill_maximum_version, tvb, offset+1, 1, ENC_NA);
 
-                       rt_block = tvb_get_ntohs(tvb, offset); /* Fetch the data in the next two bytes for display */
-                       proto_tree_add_text(rt_tree, tvb, offset+1, 1, "Maximum version: %d", (rt_block&0x00ff));
-
-                       length = length-2;
-                       offset = offset+2;
+                       length -= 2;
+                       offset += 2;
 
                        break;
 
                case TREES:
-                       mt_desc = "Trees";
-                       ti = proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
-
+                       ti = proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "Trees sub tlv");
                        rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
 
-                       length = length-1;
-                       offset = offset+1;
-
-                       len = tvb_get_guint8(tvb, offset);
-                       proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
-
-                       length = length-1;
-                       offset = offset+1;
+                       length--;
+                       offset++;
 
-                       rt_block = tvb_get_ntohs(tvb, offset);
-                       proto_tree_add_text(rt_tree, tvb, offset, 2, "Nof. trees to compute: %d", rt_block);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_trees_length, tvb, offset, 1, ENC_NA);
 
-                       length = length-2;
-                       offset = offset+2;
+                       length--;
+                       offset++;
 
-                       rt_block = tvb_get_ntohs(tvb, offset);
-                       proto_tree_add_text(rt_tree, tvb, offset, 2, "Maximum nof. trees to compute: %d", rt_block);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_trees_nof_trees_to_compute, tvb, offset, 2, ENC_BIG_ENDIAN);
 
-                       length = length-2;
-                       offset = offset+2;
+                       length -= 2;
+                       offset += 2;
 
-                       rt_block = tvb_get_ntohs(tvb, offset);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_trees_maximum_nof_trees_to_compute, tvb, offset, 2, ENC_BIG_ENDIAN);
 
-                       proto_tree_add_text(rt_tree, tvb, offset, 2, "Nof. trees to use: %d", rt_block);
+                       length -= 2;
+                       offset += 2;
 
-                       length = length-2;
-                       offset = offset+2;
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_trees_nof_trees_to_use, tvb, offset, 2, ENC_BIG_ENDIAN);
 
+                       length -= 2;
+                       offset += 2;
                        break;
 
                case TREE_IDENTIFIER:
-                       mt_desc = "Tree root identifier";
-                       ti=proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
-
+                       ti=proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "Tree root identifier sub tlv");
                        rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
 
-                       length = length-1;
-                       offset = offset+1;
+                       length--;
+                       offset++;
 
                        len = tvb_get_guint8(tvb, offset);
-                       proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_tree_root_id_length, tvb, offset, 1, ENC_NA);
 
-                       rt_block = tvb_get_ntohs(tvb, offset+1);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_tree_root_id_starting_tree_no, tvb, offset+1, 2, ENC_BIG_ENDIAN);
 
-                       proto_tree_add_text(rt_tree, tvb, offset+1, 2, "Starting tree no: %d", rt_block);
-
-                       len = len-2;
-                       length = length-2;
-                       offset = offset+3;
+                       len -= 2;
+                       length -= 2;
+                       offset += 2;
 
                        while (len>1) {
                                rt_block = tvb_get_ntohs(tvb, offset);
-                               proto_tree_add_text(rt_tree, tvb, offset, 2, "Nickname(%dth root): %d", root_id, rt_block);
-                               root_id = root_id+1;
-                               len = len-2;
-                               length = length-2;
-                               offset = offset+2;
+                               proto_tree_add_uint_format(rt_tree, hf_isis_lsp_rt_capable_tree_root_id_nickname, tvb, offset, 2,
+                                           rt_block, "Nickname(%dth root): %d", root_id, rt_block);
+                               root_id++;
+                               len -= 2;
+                               length -= 2;
+                               offset += 2;
                        }
                        break;
 
                case NICKNAME:
-                       mt_desc = "The nickname";
-                       ti=proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
-
+                       ti=proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "The nickname sub tlv");
                        rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
 
-                       length = length-1;
-                       offset = offset+1;
+                       length--;
+                       offset++;
                        len = tvb_get_guint8(tvb, offset);
 
-                       proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
-                       length = length-1;
-                       offset = offset+1;
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_nickname_length, tvb, offset, 1, ENC_NA);
+                       length--;
+                       offset++;
 
                        while (len>0) {
-                               rt_block = tvb_get_ntohs(tvb, offset);
-
-                               proto_tree_add_text(rt_tree, tvb, offset, 1, "Nickname priority: %d", ((rt_block&0xff00)>>8));
-
-                               length = length-1;
-                               offset = offset+1;
-                               len = len-1;
-                               rt_block = tvb_get_ntohs(tvb, offset);
-
-                               proto_tree_add_text(rt_tree, tvb, offset, 2, "Tree root priority: %d", rt_block);
-
-                               length = length-2;
-                               offset = offset+2;
-                               len = len-2;
-
-                               rt_block = tvb_get_ntohs(tvb, offset);
+                               proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_nickname_nickname_priority, tvb, offset, 1, ENC_NA);
+                               length--;
+                               offset++;
+                               len--;
 
-                               proto_tree_add_text(rt_tree, tvb, offset, 2, "Nickname: %x", rt_block);
+                               proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_nickname_tree_root_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
+                               len -= 2;
+                               length -= 2;
+                               offset += 2;
 
+                               proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_nickname_nickname, tvb, offset, 2, ENC_BIG_ENDIAN);
                                length = length-2;
                                offset = offset+2;
                                len = len-2;
@@ -1150,148 +895,123 @@ dissect_isis_rt_capable_clv(tvbuff_t *tvb,
                        break;
 
                case INTERESTED_VLANS:
-                       mt_desc = "Interested VLAN and spanning tree root";
-                       ti = proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
-
+                       ti = proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "Interested VLAN and spanning tree root sub tlv");
                        rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
 
-                       length = length-1;
-                       offset = offset+1;
+                       length--;
+                       offset++;
 
                        len = tvb_get_guint8(tvb, offset);
-                       proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
-
-                       length = length-1;
-                       offset = offset+1;
-                       len = len-1;
-
-                       rt_block = tvb_get_ntohs(tvb, offset);
-
-                       proto_tree_add_text(rt_tree, tvb, offset, 2, "Nickname: %x", rt_block);
-
-                       length = length-2;
-                       offset = offset+2;
-                       len = len-2;
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_interested_vlans_length, tvb, offset, 1, ENC_NA);
+                       length--;
+                       offset++;
+                       len--;
 
-                       rt_block = tvb_get_ntohs(tvb, offset);
-
-                       proto_tree_add_text(rt_tree, tvb, offset, 2,
-                                           "%s%s", (rt_block&0x8000) ? "IPv4 multicast router set, " : "IPv4 multicast router not set, ",
-                                           (rt_block&0x4000) ? "IPv6 multicast router set" : "IPv6 multicast router not set");
-                       proto_tree_add_text(rt_tree, tvb, offset, 2, "Vlan start id: %x", (rt_block&0x0fff));
-
-                       length = length-2;
-                       offset = offset+2;
-                       len = len-2;
-
-                       rt_block = tvb_get_ntohs(tvb, offset);
-
-                       proto_tree_add_text(rt_tree, tvb, offset, 2, "Vlan end id: %x", (rt_block&0x0fff));
-
-                       length = length-2;
-                       offset = offset+2;
-                       len = len-2;
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_interested_vlans_nickname, tvb, offset, 2, ENC_BIG_ENDIAN);
+                       len -= 2;
+                       length -= 2;
+                       offset += 2;
 
-                       rt_block1 = tvb_get_ntohl(tvb, offset);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_interested_vlans_multicast_ipv4, tvb, offset, 2, ENC_BIG_ENDIAN);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_interested_vlans_multicast_ipv6, tvb, offset, 2, ENC_BIG_ENDIAN);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_interested_vlans_vlan_start_id, tvb, offset, 2, ENC_BIG_ENDIAN);
+                       len -= 2;
+                       length -= 2;
+                       offset += 2;
 
-                       proto_tree_add_text(rt_tree, tvb, offset, 4, "Appointed forward state lost counter: %d", rt_block1);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_interested_vlans_vlan_end_id, tvb, offset, 2, ENC_BIG_ENDIAN);
+                       len -= 2;
+                       length -= 2;
+                       offset += 2;
 
-                       length = length-4;
-                       offset = offset+4;
-                       len = len-4;
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_interested_vlans_afs_lost_counter, tvb, offset, 4, ENC_BIG_ENDIAN);
+                       length -= 4;
+                       offset += 4;
+                       len -= 4;
 
                        while (len>0) {
                                proto_tree_add_item(rt_tree, hf_isis_lsp_root_id, tvb, offset, 6, ENC_BIG_ENDIAN);
 
-                               length = length-6;
-                               offset = offset+6;
-                               len = len-6;
-                               length = length-2;
+                               length -= 6;
+                               offset += 6;
+                               len -= 6;
                        }
                        break;
 
                case TREES_USED_IDENTIFIER:
-                       mt_desc = "Trees used identifier";
-
-                       ti=proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
-
+                       ti=proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "Trees used identifier sub tlv");
                        rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
 
-                       length = length-1;
-                       offset = offset+1;
+                       length--;
+                       offset++;
 
                        len = tvb_get_guint8(tvb, offset);
-                       proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_tree_used_id_length, tvb, offset, 1, ENC_NA);
 
-                       rt_block = tvb_get_ntohs(tvb, offset+1);
-
-                       proto_tree_add_text(rt_tree, tvb, offset+1, 2, "Starting tree no: %d", rt_block);
-                       len = len-2;
-                       length = length-2;
-                       offset = offset+3;
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_tree_used_id_starting_tree_no, tvb, offset+1, 2, ENC_BIG_ENDIAN);
+                       len -= 2;
+                       length += 2;
+                       offset += 3;
                        root_id = 1;
 
                        while (len>0) {
                                rt_block = tvb_get_ntohs(tvb, offset);
-                               proto_tree_add_text(rt_tree, tvb, offset,2,"Nickname(%dth root): %d", root_id, rt_block);
-                               root_id = root_id+1;
+                               proto_tree_add_uint_format(rt_tree, hf_isis_lsp_rt_capable_tree_used_id_nickname, tvb, offset,2,
+                                rt_block, "Nickname(%dth root): %d", root_id, rt_block);
+                               root_id++;
 
-                               len = len-2;
-                               offset = offset+2;
-                               length = length-2;
+                               len -= 2;
+                               offset += 2;
+                               length -= 2;
                        }
                        break;
 
                case VLAN_GROUP:
-                       mt_desc = "The VLAN group";
-                       ti = proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
-
+                       ti = proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "The VLAN group sub tlv");
                        rt_tree = proto_item_add_subtree(ti, ett_isis_lsp_clv_rt_capable_IPv4_prefx);
 
-                       length = length-1;
-                       offset = offset+1;
+                       length--;
+                       offset++;
 
                        len = tvb_get_guint8(tvb, offset);
-                       proto_tree_add_text(rt_tree, tvb, offset, 1, "Length: %d", len);
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_vlan_group_length, tvb, offset, 1, ENC_NA);
 
-                       len = len-1;
-                       length = length-1;
-                       offset = offset+1;
+                       len--;
+                       length--;
+                       offset++;
 
-                       rt_block = tvb_get_ntohs(tvb, offset);
-                       proto_tree_add_text(rt_tree, tvb, offset, 2, "Primary vlan id: %d", (rt_block&0x0fff));
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_vlan_group_primary_vlan_id, tvb, offset, 2, ENC_BIG_ENDIAN);
 
-                       length = length-2;
-                       offset = offset+2;
-                       len = len-2;
+                       len -= 2;
+                       offset += 2;
+                       length -= 2;
 
-                       rt_block = tvb_get_ntohs(tvb, offset);
-                       proto_tree_add_text(rt_tree, tvb, offset, 2, "Secondary vlan id: %d", (rt_block&0x0fff));
+                       proto_tree_add_item(rt_tree, hf_isis_lsp_rt_capable_vlan_group_secondary_vlan_id, tvb, offset, 2, ENC_BIG_ENDIAN);
 
-                       length = length-2;
-                       offset = offset+2;
-                       len = len-2;
+                       len -= 2;
+                       offset += 2;
+                       length -= 2;
                        sec_vlan_id = 1;
 
                        while (len>0) {
                                rt_block = tvb_get_ntohs(tvb, offset);
 
-                               proto_tree_add_text(rt_tree, tvb, offset, 2, "%dth secondary vlan id: %x", sec_vlan_id, rt_block);
+                               proto_tree_add_uint_format(rt_tree, hf_isis_lsp_rt_capable_vlan_group_nth_secondary_vlan_id, tvb, offset, 2, 
+                                           rt_block, "%dth secondary vlan id: %x", sec_vlan_id, rt_block);
 
-                               length = length-2;
-                               offset = offset+2;
-                               sec_vlan_id = sec_vlan_id+1;
-                               len = len-2;
+                               length -= 2;
+                               offset += 2;
+                               sec_vlan_id++;
+                               len -= 2;
                        }
                        break;
 
                default:
-                       mt_desc = "INVALID";
-                       proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "%s sub tlv", mt_desc);
+                       proto_tree_add_text(tree, tvb, offset, (rt_block&0x00ff)+2, "INVALID sub tlv");
 
-                       offset = offset+1;
-                       length = length-2-(tvb_get_guint8(tvb, offset));
-                       offset = offset+1+(tvb_get_guint8(tvb, offset));
+                       offset++;
+                       length -= (2+tvb_get_guint8(tvb, offset));
+                       offset += (1+tvb_get_guint8(tvb, offset));
                        break;
                }
        }
@@ -1318,7 +1038,7 @@ dissect_isis_rt_capable_clv(tvbuff_t *tvb,
  *   void, will modify proto_tree if not null.
  */
 static void
-dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
        proto_item        *pi;
@@ -1340,7 +1060,7 @@ dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
                bit_length = tvb_get_guint8(tvb, offset+5);
                byte_length = ipv6_addr_and_mask(tvb, offset+6, &prefix, bit_length);
                if (byte_length == -1) {
-                       isis_dissect_unknown(tvb, tree, offset,
+                       proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                                "IPv6 prefix has an invalid length: %d bits", bit_length );
                                return;
                        }
@@ -1349,33 +1069,18 @@ dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
                if ((ctrl_info & 0x20) != 0)
                        subclvs_len = 1+tvb_get_guint8(tvb, offset+6+byte_length);
 
-               pi = proto_tree_add_text (tree, tvb, offset, 6+byte_length+subclvs_len,
-                                         "IPv6 prefix: %s/%u, Metric: %u, Distribution: %s, %s, %ssub-TLVs present",
-                                         ip6_to_str (&prefix),
-                                         bit_length,
-                                         metric,
-                                         ((ctrl_info & 0x80) == 0) ? "up" : "down",
-                                         ((ctrl_info & 0x40) == 0) ? "internal" : "external",
-                                         ((ctrl_info & 0x20) == 0) ? "no " : "" );
-
+               pi = proto_tree_add_text (tree, tvb, offset, 6+byte_length+subclvs_len, "IPv6 Reachability");
                subtree = proto_item_add_subtree (pi, ett_isis_lsp_part_of_clv_ipv6_reachability);
 
-               proto_tree_add_text (subtree, tvb, offset+6, byte_length, "IPv6 prefix: %s/%u",
-                                    ip6_to_str (&prefix),
-                                    bit_length);
+               proto_tree_add_ipv6_format_value(subtree, hf_isis_lsp_ipv6_reachability_ipv6_prefix, tvb, offset+6, byte_length,
+                             (guint8*)&prefix, "IPv6 prefix: %s/%u", ip6_to_str (&prefix), bit_length);
 
-               proto_tree_add_text (subtree, tvb, offset, 4,
-                                    "Metric: %u", metric);
-
-               proto_tree_add_text (subtree, tvb, offset+4, 1,
-                                    "Distribution: %s, %s",
-                                    ((ctrl_info & 0x80) == 0) ? "up" : "down",
-                                    ((ctrl_info & 0x40) == 0) ? "internal" : "external" );
+               proto_tree_add_item(subtree, hf_isis_lsp_ipv6_reachability_metric, tvb, offset, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(subtree, hf_isis_lsp_ipv6_reachability_distribution, tvb, offset+4, 1, ENC_NA);
+               proto_tree_add_item(subtree, hf_isis_lsp_ipv6_reachability_distribution_internal, tvb, offset+4, 1, ENC_NA);
 
                if ((ctrl_info & 0x1f) != 0) {
-                       proto_tree_add_text (subtree, tvb, offset+4, 1,
-                                            "Reserved bits: 0x%x",
-                                            (ctrl_info & 0x1f) );
+                       proto_tree_add_item(subtree, hf_isis_lsp_ipv6_reachability_reserved_bits, tvb, offset+4, 1, ENC_NA);
                }
 
                len = 6 + byte_length;
@@ -1422,7 +1127,7 @@ dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *     void, will modify proto_tree if not null.
  */
 static void
-dissect_lsp_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_nlpid_clv(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
        isis_dissect_nlpid_clv(tvb, tree, offset, length);
@@ -1446,7 +1151,7 @@ dissect_lsp_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *     void, will modify proto_tree if not null.
  */
 static void
-dissect_lsp_mt_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_mt_clv(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
        isis_dissect_mt_clv(tvb, tree, offset, length, hf_isis_lsp_clv_mt );
@@ -1470,7 +1175,7 @@ dissect_lsp_mt_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *      void, will modify proto_tree if not null.
  */
 static void
-dissect_lsp_hostname_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_hostname_clv(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
        isis_dissect_hostname_clv(tvb, tree, offset, length,
@@ -1496,10 +1201,10 @@ dissect_lsp_hostname_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *      void, will modify proto_tree if not null.
  */
 static void
-dissect_lsp_te_router_id_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_te_router_id_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
-       isis_dissect_te_router_id_clv(tvb, tree, offset, length,
+       isis_dissect_te_router_id_clv(tree, pinfo, tvb, &ei_isis_lsp_short_packet, offset, length,
                hf_isis_lsp_clv_te_router_id );
 }
 
@@ -1522,10 +1227,10 @@ dissect_lsp_te_router_id_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *     void, will modify proto_tree if not null.
  */
 static void
-dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
-       isis_dissect_ip_int_clv(tvb, tree, offset, length,
+       isis_dissect_ip_int_clv(tree, pinfo, tvb, &ei_isis_lsp_short_packet, offset, length,
                hf_isis_lsp_clv_ipv4_int_addr );
 }
 
@@ -1547,15 +1252,15 @@ dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *   void, will modify proto_tree if not null.
  */
 static void
-dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
-       isis_dissect_ipv6_int_clv(tvb, tree, offset, length,
+       isis_dissect_ipv6_int_clv(tree, pinfo, tvb, &ei_isis_lsp_short_packet, offset, length,
                hf_isis_lsp_clv_ipv6_int_addr );
 }
 
 static void
-dissect_isis_lsp_clv_mt_cap_spb_instance(tvbuff_t   *tvb,
+dissect_isis_lsp_clv_mt_cap_spb_instance(tvbuff_t *tvb, packet_info *pinfo,
         proto_tree *tree, int offset, int subtype, int sublen)
 {
        const int CIST_ROOT_ID_LEN            = 8; /* CIST Root Identifier */
@@ -1573,7 +1278,7 @@ dissect_isis_lsp_clv_mt_cap_spb_instance(tvbuff_t   *tvb,
        const int VLAN_ID_TUPLE_LEN = 8;
 
        if (sublen < FIXED_LEN) {
-               isis_dissect_unknown( tvb, tree, offset,
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                                      "Short SPB Digest subTLV (%d vs %d)", sublen, FIXED_LEN);
                return;
        }
@@ -1581,9 +1286,6 @@ dissect_isis_lsp_clv_mt_cap_spb_instance(tvbuff_t   *tvb,
                proto_tree *subtree, *ti;
                int subofs = offset;
                const guint8 *cist_root_identifier = tvb_get_ptr   (tvb, subofs + CIST_ROOT_ID_OFFSET, CIST_ROOT_ID_LEN);
-               const guint32 cist_root_path_cost  = tvb_get_ntohl (tvb, subofs + CIST_EXT_ROOT_PATH_COST_OFFSET);
-               const guint16 bridge_priority      = tvb_get_ntohs (tvb, subofs + BRIDGE_PRI_OFFSET);
-               const guint32 v_spsourceid         = tvb_get_ntohl (tvb, subofs + V_SPSOURCEID_OFFSET);
                guint8        num_trees            = tvb_get_guint8(tvb, subofs + NUM_TREES_OFFSET);
 
                /*************************/
@@ -1592,34 +1294,20 @@ dissect_isis_lsp_clv_mt_cap_spb_instance(tvbuff_t   *tvb,
                subtree = proto_item_add_subtree(ti, ett_isis_lsp_clv_mt_cap_spb_instance);
 
                /*************************/
-               proto_tree_add_text( subtree, tvb, subofs + CIST_ROOT_ID_OFFSET, CIST_ROOT_ID_LEN,
-                                    "CIST Root Identifier: %08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x",
-                                    cist_root_identifier[0],
-                                    cist_root_identifier[1],
-                                    cist_root_identifier[2],
-                                    cist_root_identifier[3],
-                                    cist_root_identifier[4],
-                                    cist_root_identifier[5],
-                                    cist_root_identifier[6],
-                                    cist_root_identifier[7]);
-               proto_tree_add_text( subtree, tvb, subofs + CIST_EXT_ROOT_PATH_COST_OFFSET, CIST_EXT_ROOT_PATH_COST_LEN,
-                                    "CIST External Root Path Cost: 0x%08x (%u)",
-                                    cist_root_path_cost,
-                                    cist_root_path_cost);
-               proto_tree_add_text( subtree, tvb, subofs + BRIDGE_PRI_OFFSET, BRIDGE_PRI_LEN,
-                                    "Bridge Priority: 0x%04x (%u)",
-                                    bridge_priority,
-                                    bridge_priority);
-               proto_tree_add_text( subtree, tvb, subofs + V_SPSOURCEID_OFFSET, V_SPSOURCEID_LEN,
-                                    "V: %u, SPSourceId: 0x%05x (%u)",
-                                    (v_spsourceid & (1 << 20)) ? 1 : 0,
-                                    v_spsourceid & 0xfffff,
-                                    v_spsourceid & 0xfffff);
-               proto_tree_add_text( subtree, tvb, subofs + NUM_TREES_OFFSET, NUM_TREES_LEN,
-                                    "Number of Trees: 0x%02x (%u)%s",
-                                    num_trees,
-                                    num_trees,
-                                    num_trees ? "" : " Invalid subTLV: zero trees");
+               proto_tree_add_bytes_format_value( subtree, hf_isis_lsp_mt_cap_spb_instance_cist_root_identifier, tvb, subofs + CIST_ROOT_ID_OFFSET, CIST_ROOT_ID_LEN,
+                                    cist_root_identifier, "%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x",
+                                    cist_root_identifier[0], cist_root_identifier[1], cist_root_identifier[2],
+                                    cist_root_identifier[3], cist_root_identifier[4], cist_root_identifier[5],
+                                    cist_root_identifier[6], cist_root_identifier[7]);
+               proto_tree_add_item(subtree, hf_isis_lsp_mt_cap_spb_instance_cist_external_root_path_cost, tvb, subofs + CIST_EXT_ROOT_PATH_COST_OFFSET, CIST_EXT_ROOT_PATH_COST_LEN, ENC_BIG_ENDIAN);
+               proto_tree_add_item(subtree, hf_isis_lsp_mt_cap_spb_instance_bridge_priority, tvb, subofs + BRIDGE_PRI_OFFSET, BRIDGE_PRI_LEN, ENC_BIG_ENDIAN);
+
+               proto_tree_add_item(subtree, hf_isis_lsp_mt_cap_spb_instance_v, tvb, subofs + V_SPSOURCEID_OFFSET, V_SPSOURCEID_LEN, ENC_BIG_ENDIAN);
+
+               proto_tree_add_item(subtree, hf_isis_lsp_mt_cap_spsourceid, tvb, subofs + V_SPSOURCEID_OFFSET, V_SPSOURCEID_LEN, ENC_BIG_ENDIAN);
+               ti = proto_tree_add_item(subtree, hf_isis_lsp_mt_cap_spb_instance_number_of_trees, tvb, subofs + NUM_TREES_OFFSET, NUM_TREES_LEN, ENC_BIG_ENDIAN);
+               if (num_trees == 0)
+                       proto_item_append_text(ti, " Invalid subTLV: zero trees");
 
                subofs += FIXED_LEN;
                sublen -= FIXED_LEN;
@@ -1632,7 +1320,7 @@ dissect_isis_lsp_clv_mt_cap_spb_instance(tvbuff_t   *tvb,
                }
                while (sublen > 0 && num_trees > 0) {
                        if (sublen < VLAN_ID_TUPLE_LEN) {
-                               isis_dissect_unknown( tvb, subtree, offset,
+                               proto_tree_add_expert_format(subtree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                                                      "Short VLAN_ID entry (%d vs %d)", sublen, VLAN_ID_TUPLE_LEN);
                                return;
                        }
@@ -1660,7 +1348,7 @@ dissect_isis_lsp_clv_mt_cap_spb_instance(tvbuff_t   *tvb,
                        }
                }
                if (num_trees) {
-                       isis_dissect_unknown( tvb, subtree, offset,
+                       proto_tree_add_expert_format(subtree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                                              "Short subTLV (%d vs %d)", sublen, num_trees * VLAN_ID_TUPLE_LEN);
                        return;
                }
@@ -1670,11 +1358,11 @@ static void
 dissect_isis_lsp_clv_mt_cap_spb_oalg(tvbuff_t   *tvb,
        proto_tree *tree, int offset, int subtype, int sublen)
 {
-       isis_dissect_unknown( tvb, tree, offset,
+       proto_tree_add_text( tree, tvb, offset, -1,
                              "MT-Cap SPB Opaque Algorithm: Type: 0x%02x, Length: %d", subtype, sublen);
 }
 static void
-dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvbuff_t   *tvb,
+dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvbuff_t *tvb, packet_info *pinfo,
        proto_tree *tree, int offset, int subtype, int sublen)
 {
        const int BMAC_LEN = 6; /* B-MAC Address */
@@ -1687,15 +1375,13 @@ dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvbuff_t   *tvb,
        const int ISID_LEN = 4;
 
        if (sublen < FIXED_LEN) {
-               isis_dissect_unknown( tvb, tree, offset,
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                                      "Short SPBM Service Identifier and Unicast Address subTLV (%d vs %d)", sublen, FIXED_LEN);
                return;
        }
        else {
                proto_tree *subtree, *ti;
                int subofs = offset;
-               const guint8 *bmac = tvb_get_ptr  (tvb, subofs + BMAC_OFFSET, BMAC_LEN);
-               const guint16 bvid = tvb_get_ntohs(tvb, subofs + BVID_OFFSET);
 
                /*************************/
                ti = proto_tree_add_text( tree, tvb, offset-2, sublen+2,
@@ -1703,17 +1389,8 @@ dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvbuff_t   *tvb,
                subtree = proto_item_add_subtree(ti, ett_isis_lsp_clv_mt_cap_spbm_service_identifier);
 
                /*************************/
-               proto_tree_add_text( subtree, tvb, subofs + BMAC_OFFSET, BMAC_LEN,
-                                    "B-MAC: %02x-%02x-%02x-%02x-%02x-%02x",
-                                    bmac[0],
-                                    bmac[1],
-                                    bmac[2],
-                                    bmac[3],
-                                    bmac[4],
-                                    bmac[5]);
-               proto_tree_add_text( subtree, tvb, subofs + BVID_OFFSET, BVID_LEN,
-                                    "Base-VID: 0x%03x (%u)",
-                                    bvid, bvid);
+               proto_tree_add_item(subtree, hf_isis_lsp_mt_cap_spbm_service_identifier_b_mac, tvb, subofs + BMAC_OFFSET, BMAC_LEN, ENC_NA);
+               proto_tree_add_item(subtree, hf_isis_lsp_mt_cap_spbm_service_identifier_base_vid, tvb, subofs + BVID_OFFSET, BVID_LEN, ENC_BIG_ENDIAN);
 
                subofs += FIXED_LEN;
                sublen -= FIXED_LEN;
@@ -1721,7 +1398,7 @@ dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvbuff_t   *tvb,
                /*************************/
                while (sublen > 0) {
                        if (sublen < ISID_LEN) {
-                               isis_dissect_unknown( tvb, subtree, offset,
+                               proto_tree_add_expert_format(subtree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                                                      "Short ISID entry (%d vs %d)", sublen, ISID_LEN);
                                return;
                        }
@@ -1740,7 +1417,7 @@ dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvbuff_t   *tvb,
        }
 }
 static void
-dissect_isis_lsp_clv_mt_cap_spbv_mac_address(tvbuff_t   *tvb,
+dissect_isis_lsp_clv_mt_cap_spbv_mac_address(tvbuff_t *tvb, packet_info *pinfo,
        proto_tree *tree, int offset, int subtype, int sublen)
 {
        guint16 fixed_data;
@@ -1754,7 +1431,7 @@ dissect_isis_lsp_clv_mt_cap_spbv_mac_address(tvbuff_t   *tvb,
        const int FIXED_LEN    = SPVID_OFFSET + SPVID_LEN;
 
        if (sublen < FIXED_LEN) {
-               isis_dissect_unknown( tvb, tree, offset,
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                                      "Short SPBV Mac Address subTLV (%d vs %d)", sublen, FIXED_LEN);
                return;
        }
@@ -1782,8 +1459,8 @@ dissect_isis_lsp_clv_mt_cap_spbv_mac_address(tvbuff_t   *tvb,
                /*************************/
                while (sublen > 0) {
                        if (sublen < MAC_TUPLE_LEN) {
-                               isis_dissect_unknown( tvb, subtree, offset,
-                                                     "  Short MAC Address entry (%d vs %d)", sublen, MAC_TUPLE_LEN);
+                               proto_tree_add_expert_format(subtree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+                                                     "Short MAC Address entry (%d vs %d)", sublen, MAC_TUPLE_LEN);
                                return;
                        }
                        else {
@@ -1821,16 +1498,13 @@ dissect_isis_lsp_clv_mt_cap_spbv_mac_address(tvbuff_t   *tvb,
  *   void, will modify proto_tree if not null.
  */
 static void
-dissect_isis_lsp_clv_mt_cap(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_isis_lsp_clv_mt_cap(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
                             int id_length _U_, int length)
 {
        if (length >= 2) {
                /* mtid */
-               guint16 mtid = tvb_get_ntohs(tvb, offset);
-               proto_tree_add_text( tree, tvb, offset, 2,
-                                    "MTID: 0x%03x, Overload: %d",
-                                    (mtid & 0xfff),
-                                    (mtid & 0x8000) ? 1 : 0);
+               proto_tree_add_item( tree, hf_isis_lsp_mt_cap_mtid, tvb, offset, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_isis_lsp_mt_cap_overload, tvb, offset, 2, ENC_BIG_ENDIAN);
                length -= 2;
                offset += 2;
                while (length >= 2) {
@@ -1839,24 +1513,24 @@ dissect_isis_lsp_clv_mt_cap(tvbuff_t *tvb, proto_tree *tree, int offset,
                        length -= 2;
                        offset += 2;
                        if (subtlvlen > length) {
-                               isis_dissect_unknown( tvb, tree, offset,
+                               proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                                                      "Short type 0x%02x TLV (%d vs %d)", subtype, subtlvlen, length);
                                return;
                        }
                        if (subtype == 0x01) { /* SPB Instance */
-                               dissect_isis_lsp_clv_mt_cap_spb_instance(tvb, tree, offset, subtype, subtlvlen);
+                               dissect_isis_lsp_clv_mt_cap_spb_instance(tvb, pinfo, tree, offset, subtype, subtlvlen);
                        }
                        else if (subtype == 0x02) { /* OALG */
                                dissect_isis_lsp_clv_mt_cap_spb_oalg(tvb, tree, offset, subtype, subtlvlen);
                        }
                        else if (subtype == 0x03) { /* SPBM Service Identifier */
-                               dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvb, tree, offset, subtype, subtlvlen);
+                               dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvb, pinfo, tree, offset, subtype, subtlvlen);
                        }
                        else if (subtype == 0x04) { /* SPBV Mac Address */
-                               dissect_isis_lsp_clv_mt_cap_spbv_mac_address(tvb, tree, offset, subtype, subtlvlen);
+                               dissect_isis_lsp_clv_mt_cap_spbv_mac_address(tvb, pinfo, tree, offset, subtype, subtlvlen);
                        }
                        else {
-                               isis_dissect_unknown( tvb, tree, offset,
+                               proto_tree_add_expert_format( tree, pinfo, &ei_isis_lsp_subtlv, tvb, offset, -1,
                                                      "Unknown SubTlv: Type: 0x%02x, Length: %d", subtype, subtlvlen);
                        }
                        length -= subtlvlen;
@@ -1884,10 +1558,10 @@ dissect_isis_lsp_clv_mt_cap(tvbuff_t *tvb, proto_tree *tree, int offset,
  *     void, will modify proto_tree if not null.
  */
 static void
-dissect_lsp_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_authentication_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
-       isis_dissect_authentication_clv(tvb, tree, offset, length);
+       isis_dissect_authentication_clv(tree, pinfo, tvb, &ei_isis_lsp_authentication, offset, length);
 }
 
 /*
@@ -1908,7 +1582,7 @@ dissect_lsp_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *     void, will modify proto_tree if not null.
  */
 static void
-dissect_lsp_ip_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_ip_authentication_clv(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
        isis_dissect_ip_authentication_clv(tvb, tree, offset, length);
@@ -1932,10 +1606,10 @@ dissect_lsp_ip_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *      void, but we will add to proto tree if !NULL.
  */
 static void
-dissect_lsp_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_area_address_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
-       isis_dissect_area_address_clv(tvb, tree, offset, length);
+       isis_dissect_area_address_clv(tree, pinfo, tvb, &ei_isis_lsp_short_packet, offset, length);
 }
 
 /*
@@ -1963,7 +1637,7 @@ dissect_lsp_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *      void, but we will add to proto tree if !NULL.
  */
 static void
-dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, proto_tree *tree,
+dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        int offset, int length, int id_length, int show_virtual, int is_eis)
 {
        proto_item      *ti;
@@ -1978,9 +1652,7 @@ dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, proto_tree *tree,
                                proto_tree_add_text ( tree, tvb, offset, 1,
                                   tvb_get_guint8(tvb, offset) ? "IsVirtual" : "IsNotVirtual" );
                        } else {
-                               proto_tree_add_text ( tree, tvb, offset, 1,
-                                       "Reserved value 0x%02x, must == 0",
-                                       tvb_get_guint8(tvb, offset)  );
+                               proto_tree_add_item(tree, hf_isis_lsp_eis_neighbors_reserved, tvb, offset, 1, ENC_NA);
                        }
                }
                offset++;
@@ -1990,9 +1662,8 @@ dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, proto_tree *tree,
 
        while ( length > 0 ) {
                if (length<tlen) {
-                       isis_dissect_unknown(tvb, tree, offset,
-                               "short E/IS reachability (%d vs %d)", length,
-                               tlen );
+                       proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+                               "short E/IS reachability (%d vs %d)", length, tlen );
                        return;
                }
                /*
@@ -2000,49 +1671,31 @@ dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, proto_tree *tree,
                 */
                if ( tree ) {
                        if ( is_eis ) {
-                               ti = proto_tree_add_text(tree, tvb, offset, tlen,
-                                       "ES Neighbor: %s",
-                               print_system_id( tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
+                               ti = proto_tree_add_bytes_format_value(tree, hf_isis_lsp_eis_neighbors_es_neighbor, tvb, offset, tlen,
+                                       tvb_get_ptr(tvb, offset+4, id_length), "%s",
+                                               print_system_id( tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
                        } else {
-                               ti = proto_tree_add_text(tree, tvb, offset, tlen,
-                                       "IS Neighbor:  %s",
-                               print_system_id(tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
+                               ti = proto_tree_add_bytes_format_value(tree, hf_isis_lsp_eis_neighbors_is_neighbor, tvb, offset, tlen,
+                                       tvb_get_ptr(tvb, offset+4, id_length), "%s",
+                                               print_system_id( tvb_get_ptr(tvb, offset+4, id_length), id_length ) );
                        }
-                       ntree = proto_item_add_subtree(ti,
-                               ett_isis_lsp_clv_is_neighbors);
+                       ntree = proto_item_add_subtree(ti, ett_isis_lsp_clv_is_neighbors);
 
+                       proto_tree_add_item(ntree, hf_isis_lsp_eis_neighbors_default_metric, tvb, offset, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_eis_neighbors_default_metric_ie, tvb, offset, 1, ENC_NA);
 
+                       proto_tree_add_item(ntree, hf_isis_lsp_eis_neighbors_delay_metric, tvb, offset, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_eis_neighbors_delay_metric_supported, tvb, offset, 1, ENC_NA);
 
-                               proto_tree_add_text (ntree, tvb, offset, 1,
-                                                    "Default Metric: %d, %s",
-                                                    ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset)),
-                                                    ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset)) ? "External" : "Internal");
+                       proto_tree_add_item(ntree, hf_isis_lsp_eis_neighbors_delay_metric_ie, tvb, offset+1, 1, ENC_NA);
 
-                       if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+1))) {
-                               proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric:   Not supported");
-                       } else {
-                               proto_tree_add_text (ntree, tvb, offset+1, 1, "Delay Metric:   %d, %s",
-                                                    ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+1)),
-                                                    ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+1)) ? "External" : "Internal");
-                       }
-
-
-                       if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+2))) {
-                               proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: Not supported");
-                       } else {
-                               proto_tree_add_text (ntree, tvb, offset+2, 1, "Expense Metric: %d, %s",
-                                                    ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+2)),
-                                                    ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+2)) ? "External" : "Internal");
-                       }
-
-                       if (ISIS_LSP_CLV_METRIC_SUPPORTED(tvb_get_guint8(tvb, offset+3))) {
-                               proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric:   Not supported");
-                       } else {
-                               proto_tree_add_text (ntree, tvb, offset+3, 1, "Error Metric:   %d, %s",
-                                                    ISIS_LSP_CLV_METRIC_VALUE(tvb_get_guint8(tvb, offset+3)),
-                                                    ISIS_LSP_CLV_METRIC_IE(tvb_get_guint8(tvb, offset+3)) ? "External" : "Internal");
-                       }
+                       proto_tree_add_item(ntree, hf_isis_lsp_eis_neighbors_expense_metric, tvb, offset, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_eis_neighbors_expense_metric_supported, tvb, offset, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_eis_neighbors_expense_metric_ie, tvb, offset+2, 1, ENC_NA);
 
+                       proto_tree_add_item(ntree, hf_isis_lsp_eis_neighbors_error_metric, tvb, offset, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_eis_neighbors_error_metric_supported, tvb, offset, 1, ENC_NA);
+                       proto_tree_add_item(ntree, hf_isis_lsp_eis_neighbors_error_metric_ie, tvb, offset+3, 1, ENC_NA);
                }
                offset += tlen;
                length -= tlen;
@@ -2067,10 +1720,10 @@ dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, proto_tree *tree,
  *      void, but we will add to proto tree if !NULL.
  */
 static void
-dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length, int length)
 {
-       dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
+       dissect_lsp_eis_neighbors_clv_inner(tvb, pinfo, tree, offset,
                length, id_length, TRUE, FALSE);
 }
 
@@ -2092,10 +1745,10 @@ dissect_lsp_l1_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *      void, but we will add to proto tree if !NULL.
  */
 static void
-dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length, int length)
 {
-       dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
+       dissect_lsp_eis_neighbors_clv_inner(tvb, pinfo, tree, offset,
                length, id_length, TRUE, TRUE);
 }
 
@@ -2118,10 +1771,10 @@ dissect_lsp_l1_es_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *      void, but we will add to proto tree if !NULL.
  */
 static void
-dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_l2_is_neighbors_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length, int length)
 {
-       dissect_lsp_eis_neighbors_clv_inner(tvb, tree, offset,
+       dissect_lsp_eis_neighbors_clv_inner(tvb, pinfo, tree, offset,
                length, id_length, FALSE, FALSE);
 }
 
@@ -2184,9 +1837,9 @@ dissect_subclv_max_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
 {
        gfloat  bw;
 
-       bw = tvb_get_ntohieee_float(tvb, offset);
-       proto_tree_add_text (tree, tvb, offset-2, 6,
-               "Maximum link bandwidth : %.2f Mbps", bw*8/1000000 );
+       bw = tvb_get_ntohieee_float(tvb, offset)*8/1000000;
+       proto_tree_add_float_format_value(tree, hf_isis_lsp_maximum_link_bandwidth, tvb, offset-2, 6,
+               bw, "%.2f Mbps", bw);
 }
 
 /*
@@ -2210,9 +1863,9 @@ dissect_subclv_rsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
 {
        gfloat  bw;
 
-       bw = tvb_get_ntohieee_float(tvb, offset);
-       proto_tree_add_text (tree, tvb, offset-2, 6,
-               "Reservable link bandwidth: %.2f Mbps", bw*8/1000000 );
+       bw = tvb_get_ntohieee_float(tvb, offset)*8/1000000;
+       proto_tree_add_float_format_value (tree, hf_isis_lsp_reservable_link_bandwidth, tvb, offset-2, 6,
+               bw, "%.2f Mbps", bw );
 }
 
 /*
@@ -2243,9 +1896,9 @@ dissect_subclv_unrsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
        ntree = proto_item_add_subtree (ti, ett_isis_lsp_subclv_unrsv_bw);
 
        for (i = 0 ; i < 8 ; i++) {
-               bw = tvb_get_ntohieee_float(tvb, offset+4*i);
-               proto_tree_add_text (ntree, tvb, offset+4*i, 4,
-                       "priority level %d: %.2f Mbps", i, bw*8/1000000 );
+               bw = tvb_get_ntohieee_float(tvb, offset+4*i)*8/1000000;
+               proto_tree_add_float_format(ntree, hf_isis_lsp_unrsv_bw_priority_level, tvb, offset+4*i, 4,
+                       bw, "priority level %d: %.2f Mbps", i, bw );
        }
 }
 
@@ -2269,13 +1922,13 @@ dissect_subclv_unrsv_bw(tvbuff_t *tvb, proto_tree *tree, int offset)
  */
 
 static void
-dissect_subclv_spb_link_metric(tvbuff_t   *tvb,
+dissect_subclv_spb_link_metric(tvbuff_t *tvb, packet_info *pinfo,
         proto_tree *tree, int offset, int subtype, int sublen)
 {
        const int SUBLEN     = 6;
 
        if (sublen != SUBLEN) {
-               isis_dissect_unknown( tvb, tree, offset,
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                                      "Short SPB Link Metric sub-TLV (%d vs %d)", sublen, SUBLEN);
                return;
        }
@@ -2318,7 +1971,7 @@ dissect_subclv_spb_link_metric(tvbuff_t   *tvb,
  *   void, but we will add to proto tree if !NULL.
  */
 static void
-dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
+dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree,
        int offset, int id_length _U_, int length)
 {
        proto_item *ti;
@@ -2327,17 +1980,12 @@ dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
        guint      len, i;
        guint      clv_code, clv_len;
 
-       if (!tree) return;
-
        while (length > 0) {
-               ti = proto_tree_add_text (tree, tvb, offset, -1,
-                       "IS neighbor: %s",
-                       print_system_id (tvb_get_ptr(tvb, offset, 7), 7) );
-               ntree = proto_item_add_subtree (ti,
-                       ett_isis_lsp_part_of_clv_ext_is_reachability );
+               ti = proto_tree_add_bytes_format_value(tree, hf_isis_lsp_ext_is_reachability_is_neighbor, tvb, offset, -1,
+                       tvb_get_ptr(tvb, offset, 7), "%s", print_system_id (tvb_get_ptr(tvb, offset, 7), 7) );
+               ntree = proto_item_add_subtree (ti, ett_isis_lsp_part_of_clv_ext_is_reachability );
 
-               proto_tree_add_text (ntree, tvb, offset+7, 3,
-                       "Metric: %d", tvb_get_ntoh24(tvb, offset+7) );
+               proto_tree_add_item(ntree, hf_isis_lsp_ext_is_reachability_metric, tvb, offset+7, 3, ENC_BIG_ENDIAN);
 
                subclvs_len = tvb_get_guint8(tvb, offset+10);
                if (subclvs_len == 0) {
@@ -2353,18 +2001,14 @@ dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
                                        dissect_subclv_admin_group(tvb, ntree, offset+13+i);
                                        break;
                                case 4 :
-                                       proto_tree_add_text(ntree, tvb, offset+13+i, 4,
-                                               "Link Local Identifier: %d", tvb_get_ntohl(tvb, offset+13+i));
-                                       proto_tree_add_text(ntree, tvb, offset+17+i, 4,
-                                               "Link Remote Identifier: %d", tvb_get_ntohl(tvb, offset+17+i));
+                                       proto_tree_add_item(ntree, hf_isis_lsp_ext_is_reachability_link_local_identifier, tvb, offset+13+i, 4, ENC_BIG_ENDIAN);
+                                       proto_tree_add_item(ntree, hf_isis_lsp_ext_is_reachability_link_remote_identifier, tvb, offset+17+i, 4, ENC_BIG_ENDIAN);
                                        break;
                                case 6 :
-                                       proto_tree_add_text (ntree, tvb, offset+11+i, 6,
-                                               "IPv4 interface address: %s", tvb_ip_to_str(tvb, offset+13+i));
+                                       proto_tree_add_item(ntree, hf_isis_lsp_ext_is_reachability_ipv4_interface_address, tvb, offset+11+i, 6, ENC_BIG_ENDIAN);
                                        break;
                                case 8 :
-                                       proto_tree_add_text (ntree, tvb, offset+11+i, 6,
-                                               "IPv4 neighbor address: %s", tvb_ip_to_str(tvb, offset+13+i));
+                                       proto_tree_add_item(ntree, hf_isis_lsp_ext_is_reachability_ipv4_neighbor_address, tvb, offset+11+i, 6, ENC_BIG_ENDIAN);
                                        break;
                                case 9 :
                                        dissect_subclv_max_bw (tvb, ntree, offset+13+i);
@@ -2376,12 +2020,10 @@ dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
                                        dissect_subclv_unrsv_bw (tvb, ntree, offset+13+i);
                                        break;
                                case 18:
-                                       proto_tree_add_text (ntree, tvb, offset+11+i, 5,
-                                               "Traffic engineering default metric: %d",
-                                               tvb_get_ntoh24(tvb, offset+13+i) );
+                                       proto_tree_add_item(ntree, hf_isis_lsp_ext_is_reachability_traffic_engineering_default_metric, tvb, offset+11+i, 5, ENC_BIG_ENDIAN);
                                        break;
                                case 29:
-                                       dissect_subclv_spb_link_metric(tvb, ntree,
+                                       dissect_subclv_spb_link_metric(tvb, pinfo, ntree,
                                                offset+13+i, clv_code, clv_len);
                                        break;
                                case 250:
@@ -2426,18 +2068,16 @@ dissect_lsp_ext_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree,
  *   void, but we will add to proto tree if !NULL.
  */
 static void
-dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
+dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb, packet_info* pinfo,
         proto_tree *tree, int offset, int id_length _U_, int length)
 {
-       if (!tree) return;
        if (length < 2) {
-               isis_dissect_unknown(tvb, tree, offset,
-                               "short lsp multi-topology reachable IPv4 prefixes(%d vs %d)", length,
-                               2 );
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+                               "short lsp multi-topology reachable IPv4 prefixes(%d vs %d)", length, 2 );
                return;
        }
        dissect_lsp_mt_id(tvb, tree, offset);
-       dissect_lsp_ext_ip_reachability_clv(tvb, tree, offset+2, 0, length-2);
+       dissect_lsp_ext_ip_reachability_clv(tvb, pinfo, tree, offset+2, 0, length-2);
 }
 
 /*
@@ -2457,18 +2097,16 @@ dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb,
  *   void, but we will add to proto tree if !NULL.
  */
 static void
-dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
+dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb, packet_info* pinfo,
         proto_tree *tree, int offset, int id_length _U_, int length)
 {
-       if (!tree) return;
        if (length < 2) {
-               isis_dissect_unknown(tvb, tree, offset,
-                               "short lsp multi-topology reachable IPv6 prefixes(%d vs %d)", length,
-                               2 );
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+                               "short lsp multi-topology reachable IPv6 prefixes(%d vs %d)", length, 2 );
                return;
        }
        dissect_lsp_mt_id(tvb, tree, offset);
-       dissect_lsp_ipv6_reachability_clv(tvb, tree, offset+2, 0, length-2);
+       dissect_lsp_ipv6_reachability_clv(tvb, pinfo, tree, offset+2, 0, length-2);
 }
 
 
@@ -2490,14 +2128,12 @@ dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb,
  */
 
 static void
-dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
-       if (!tree) return;
        if (length < 2) {
-               isis_dissect_unknown(tvb, tree, offset,
-                               "short lsp reachability(%d vs %d)", length,
-                               2 );
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+                               "short lsp reachability(%d vs %d)", length, 2 );
                return;
        }
 
@@ -2510,7 +2146,7 @@ dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
         * fix here. No need to parse TLV 22 (with bugs) while it is
         * already done correctly!!
         */
-       dissect_lsp_ext_is_reachability_clv(tvb, tree, offset+2, 0, length-2);
+       dissect_lsp_ext_is_reachability_clv(tvb, pinfo, tree, offset+2, 0, length-2);
 }
 
 /*
@@ -2532,27 +2168,26 @@ dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *      void, but we will add to proto tree if !NULL.
  */
 static void
-dissect_lsp_partition_dis_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_partition_dis_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length, int length)
 {
        if ( length < id_length ) {
-               isis_dissect_unknown(tvb, tree, offset,
-                               "short lsp partition DIS(%d vs %d)", length,
-                               id_length );
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+                               "short lsp partition DIS(%d vs %d)", length, id_length );
                return;
        }
        /*
         * Gotta build a sub-tree for all our pieces
         */
        if ( tree ) {
-               proto_tree_add_text ( tree, tvb, offset, id_length,
-                       "Partition designated L2 IS: %s",
+               proto_tree_add_bytes_format_value( tree, hf_isis_lsp_partition_designated_l2_is, tvb, offset, id_length,
+                       tvb_get_ptr(tvb, offset, id_length), "%s",
                        print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) );
        }
        length -= id_length;
        offset += id_length;
        if ( length > 0 ) {
-               isis_dissect_unknown(tvb, tree, offset,
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_long_packet, tvb, offset, -1,
                                "Long lsp partition DIS, %d left over", length );
                return;
        }
@@ -2577,14 +2212,14 @@ dissect_lsp_partition_dis_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
  *      void, but we will add to proto tree if !NULL.
  */
 static void
-dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
+dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
        int id_length _U_, int length)
 {
        char *sbuf;
        int mylen;
 
        if ( length < 4 ) {
-               isis_dissect_unknown(tvb, tree, offset,
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                        "Short lsp prefix neighbors (%d vs 4)", length );
                return;
        }
@@ -2604,14 +2239,13 @@ dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
                mylen = tvb_get_guint8(tvb, offset);
                length--;
                if (length<=0) {
-                       isis_dissect_unknown(tvb, tree, offset,
+                       proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
                                "Zero payload space after length in prefix neighbor" );
                        return;
                }
                if ( mylen > length) {
-                       isis_dissect_unknown(tvb, tree, offset,
-                               "Integral length of prefix neighbor too long (%d vs %d)",
-                               mylen, length );
+                       proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_long_packet, tvb, offset, -1,
+                               "Integral length of prefix neighbor too long (%d vs %d)", mylen, length );
                        return;
                }
 
@@ -2628,27 +2262,302 @@ dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
                offset += mylen + 1;
                length -= mylen;        /* length already adjusted for len fld*/
        }
-}
-
-static void isis_lsp_checkum_additional_info(tvbuff_t * tvb, packet_info * pinfo,
-    proto_item * it_cksum, int offset, gboolean is_cksum_correct)
-{
-       proto_tree * checksum_tree;
-       proto_item * item;
+}
+
+static void isis_lsp_checkum_additional_info(tvbuff_t * tvb, packet_info * pinfo,
+    proto_item * it_cksum, int offset, gboolean is_cksum_correct)
+{
+       proto_tree * checksum_tree;
+       proto_item * item;
+
+       checksum_tree = proto_item_add_subtree(it_cksum, ett_isis_lsp_cksum);
+       item = proto_tree_add_boolean(checksum_tree, hf_isis_lsp_checksum_good, tvb,
+                                     offset, 2, is_cksum_correct);
+       PROTO_ITEM_SET_GENERATED(item);
+       item = proto_tree_add_boolean(checksum_tree, hf_isis_lsp_checksum_bad, tvb,
+                                     offset, 2, !is_cksum_correct);
+       PROTO_ITEM_SET_GENERATED(item);
+       if (!is_cksum_correct) {
+               expert_add_info(pinfo, item, &ie_isis_lsp_checksum_bad);
+               col_append_str(pinfo->cinfo, COL_INFO, " [ISIS CHECKSUM INCORRECT]");
+       }
+}
+
+static const isis_clv_handle_t clv_l1_lsp_opts[] = {
+       {
+               ISIS_CLV_AREA_ADDRESS,
+               "Area address(es)",
+               &ett_isis_lsp_clv_area_addr,
+               dissect_lsp_area_address_clv
+       },
+       {
+               ISIS_CLV_IS_REACH,
+               "IS Reachability",
+               &ett_isis_lsp_clv_is_neighbors,
+               dissect_lsp_l1_is_neighbors_clv
+       },
+       {
+               ISIS_CLV_ES_NEIGHBORS,
+               "ES Neighbor(s)",
+               &ett_isis_lsp_clv_is_neighbors,
+               dissect_lsp_l1_es_neighbors_clv
+       },
+       {
+               ISIS_CLV_EXTD_IS_REACH,
+               "Extended IS reachability",
+               &ett_isis_lsp_clv_ext_is_reachability,
+               dissect_lsp_ext_is_reachability_clv
+       },
+       {
+               ISIS_CLV_INT_IP_REACH,
+               "IP Internal reachability",
+               &ett_isis_lsp_clv_ip_reachability,
+               dissect_lsp_ip_reachability_clv
+       },
+       {
+               ISIS_CLV_EXT_IP_REACH,
+               "IP External reachability",
+               &ett_isis_lsp_clv_ip_reachability,
+               dissect_lsp_ip_reachability_clv
+       },
+       {
+               ISIS_CLV_EXTD_IP_REACH,
+               "Extended IP Reachability",
+               &ett_isis_lsp_clv_ext_ip_reachability,
+               dissect_lsp_ext_ip_reachability_clv
+       },
+       {
+               ISIS_CLV_IP6_REACH,
+               "IPv6 reachability",
+               &ett_isis_lsp_clv_ipv6_reachability,
+               dissect_lsp_ipv6_reachability_clv
+       },
+       {
+               ISIS_CLV_PROTOCOLS_SUPPORTED,
+               "Protocols supported",
+               &ett_isis_lsp_clv_nlpid,
+               dissect_lsp_nlpid_clv
+       },
+       {
+               ISIS_CLV_HOSTNAME,
+               "Hostname",
+               &ett_isis_lsp_clv_hostname,
+               dissect_lsp_hostname_clv
+       },
+       {
+               ISIS_CLV_TE_ROUTER_ID,
+               "Traffic Engineering Router ID",
+               &ett_isis_lsp_clv_te_router_id,
+               dissect_lsp_te_router_id_clv
+       },
+       {
+               ISIS_CLV_IP_ADDR,
+               "IP Interface address(es)",
+               &ett_isis_lsp_clv_ipv4_int_addr,
+               dissect_lsp_ip_int_addr_clv
+       },
+       {
+               ISIS_CLV_IP6_ADDR,
+               "IPv6 Interface address(es)",
+               &ett_isis_lsp_clv_ipv6_int_addr,
+               dissect_lsp_ipv6_int_addr_clv
+       },
+       {
+               ISIS_CLV_MT_CAP,
+               "MT-Capability",
+               &ett_isis_lsp_clv_mt_cap,
+               dissect_isis_lsp_clv_mt_cap
+       },
+       {
+               ISIS_CLV_AUTHENTICATION,
+               "Authentication",
+               &ett_isis_lsp_clv_authentication,
+               dissect_lsp_authentication_clv
+       },
+       {
+               ISIS_CLV_IP_AUTHENTICATION,
+               "IP Authentication",
+               &ett_isis_lsp_clv_ip_authentication,
+               dissect_lsp_ip_authentication_clv
+       },
+       {
+               ISIS_CLV_MT_SUPPORTED,
+               "Multi Topology supported",
+               &ett_isis_lsp_clv_mt,
+               dissect_lsp_mt_clv
+       },
+       {
+               ISIS_CLV_MT_IS_REACH,
+               "Multi Topology IS Reachability",
+               &ett_isis_lsp_clv_mt_is,
+               dissect_lsp_mt_is_reachability_clv
+       },
+       {
+               ISIS_CLV_MT_IP_REACH,
+               "Multi Topology Reachable IPv4 Prefixes",
+               &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
+               dissect_lsp_mt_reachable_IPv4_prefx_clv
+       },
+       {
+               ISIS_CLV_MT_IP6_REACH,
+               "Multi Topology Reachable IPv6 Prefixes",
+               &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
+               dissect_lsp_mt_reachable_IPv6_prefx_clv
+       },
+       {
+               ISIS_CLV_RT_CAPABLE,
+               "Router Capability",
+               &ett_isis_lsp_clv_rt_capable_IPv4_prefx,
+               dissect_isis_rt_capable_clv
+       },
+       {
+               ISIS_GRP_ADDR,
+               "GROUP ADDRESS TLV",
+               &ett_isis_lsp_clv_grp_address_IPv4_prefx,
+               dissect_isis_grp_address_clv
+       },
+       {
+               0,
+               "",
+               NULL,
+               NULL
+       }
+};
 
-       checksum_tree = proto_item_add_subtree(it_cksum, ett_isis_lsp_cksum);
-       item = proto_tree_add_boolean(checksum_tree, hf_isis_lsp_checksum_good, tvb,
-                                     offset, 2, is_cksum_correct);
-       PROTO_ITEM_SET_GENERATED(item);
-       item = proto_tree_add_boolean(checksum_tree, hf_isis_lsp_checksum_bad, tvb,
-                                     offset, 2, !is_cksum_correct);
-       PROTO_ITEM_SET_GENERATED(item);
-       if (!is_cksum_correct) {
-               expert_add_info(pinfo, item, &ie_isis_lsp_checksum_bad);
-               col_append_str(pinfo->cinfo, COL_INFO, " [ISIS CHECKSUM INCORRECT]");
+static const isis_clv_handle_t clv_l2_lsp_opts[] = {
+       {
+               ISIS_CLV_AREA_ADDRESS,
+               "Area address(es)",
+               &ett_isis_lsp_clv_area_addr,
+               dissect_lsp_area_address_clv
+       },
+       {
+               ISIS_CLV_IS_REACH,
+               "IS Reachability",
+               &ett_isis_lsp_clv_is_neighbors,
+               dissect_lsp_l2_is_neighbors_clv
+       },
+       {
+               ISIS_CLV_EXTD_IS_REACH,
+               "Extended IS reachability",
+               &ett_isis_lsp_clv_ext_is_reachability,
+               dissect_lsp_ext_is_reachability_clv
+       },
+       {
+               ISIS_CLV_PARTITION_DIS,
+               "Partition Designated Level 2 IS",
+               &ett_isis_lsp_clv_partition_dis,
+               dissect_lsp_partition_dis_clv
+       },
+       {
+               ISIS_CLV_PREFIX_NEIGHBORS,
+               "Prefix neighbors",
+               &ett_isis_lsp_clv_prefix_neighbors,
+               dissect_lsp_prefix_neighbors_clv
+       },
+       {
+               ISIS_CLV_INT_IP_REACH,
+               "IP Internal reachability",
+               &ett_isis_lsp_clv_ip_reachability,
+               dissect_lsp_ip_reachability_clv
+       },
+       {
+               ISIS_CLV_EXT_IP_REACH,
+               "IP External reachability",
+               &ett_isis_lsp_clv_ip_reachability,
+               dissect_lsp_ip_reachability_clv
+       },
+       {
+               ISIS_CLV_PROTOCOLS_SUPPORTED,
+               "Protocols supported",
+               &ett_isis_lsp_clv_nlpid,
+               dissect_lsp_nlpid_clv
+       },
+       {
+               ISIS_CLV_HOSTNAME,
+               "Hostname",
+               &ett_isis_lsp_clv_hostname,
+               dissect_lsp_hostname_clv
+       },
+       {
+               ISIS_CLV_TE_ROUTER_ID,
+               "Traffic Engineering Router ID",
+               &ett_isis_lsp_clv_te_router_id,
+               dissect_lsp_te_router_id_clv
+       },
+       {
+               ISIS_CLV_EXTD_IP_REACH,
+               "Extended IP Reachability",
+               &ett_isis_lsp_clv_ext_ip_reachability,
+               dissect_lsp_ext_ip_reachability_clv
+       },
+       {
+               ISIS_CLV_IP6_REACH,
+               "IPv6 reachability",
+               &ett_isis_lsp_clv_ipv6_reachability,
+               dissect_lsp_ipv6_reachability_clv
+       },
+       {
+               ISIS_CLV_IP_ADDR,
+               "IP Interface address(es)",
+               &ett_isis_lsp_clv_ipv4_int_addr,
+               dissect_lsp_ip_int_addr_clv
+       },
+       {
+               ISIS_CLV_IP6_ADDR,
+               "IPv6 Interface address(es)",
+               &ett_isis_lsp_clv_ipv6_int_addr,
+               dissect_lsp_ipv6_int_addr_clv
+       },
+       {
+               ISIS_CLV_MT_CAP,
+               "MT-Capability",
+               &ett_isis_lsp_clv_mt_cap,
+               dissect_isis_lsp_clv_mt_cap
+       },
+       {
+               ISIS_CLV_AUTHENTICATION,
+               "Authentication",
+               &ett_isis_lsp_clv_authentication,
+               dissect_lsp_authentication_clv
+       },
+       {
+               ISIS_CLV_IP_AUTHENTICATION,
+               "IP Authentication",
+               &ett_isis_lsp_clv_ip_authentication,
+               dissect_lsp_ip_authentication_clv
+       },
+       {
+               ISIS_CLV_MT_SUPPORTED,
+               "Multi Topology",
+               &ett_isis_lsp_clv_mt,
+               dissect_lsp_mt_clv
+       },
+       {
+               ISIS_CLV_MT_IS_REACH,
+               "Multi Topology IS Reachability",
+               &ett_isis_lsp_clv_mt_is,
+               dissect_lsp_mt_is_reachability_clv
+       },
+       {
+               ISIS_CLV_MT_IP_REACH,
+               "Multi Topology Reachable IPv4 Prefixes",
+               &ett_isis_lsp_clv_mt_reachable_IPv4_prefx,
+               dissect_lsp_mt_reachable_IPv4_prefx_clv
+       },
+       {
+               ISIS_CLV_MT_IP6_REACH,
+               "Multi Topology Reachable IPv6 Prefixes",
+               &ett_isis_lsp_clv_mt_reachable_IPv6_prefx,
+               dissect_lsp_mt_reachable_IPv6_prefx_clv
+       },
+       {
+               0,
+               "",
+               NULL,
+               NULL
        }
-}
-
+};
 
 /*
  * Name: isis_dissect_isis_lsp()
@@ -2668,9 +2577,9 @@ static void isis_lsp_checkum_additional_info(tvbuff_t * tvb, packet_info * pinfo
  * Output:
  *      void, but we will add to proto tree if !NULL.
  */
-void
-isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
-       int lsp_type, int header_length, int id_length)
+static void
+dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
+       const isis_clv_handle_t *opts, int header_length, int id_length)
 {
        proto_item      *ti, *to, *ta;
        proto_tree      *lsp_tree = NULL, *info_tree, *att_tree;
@@ -2678,40 +2587,34 @@ isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
        guint8          lsp_info, lsp_att;
        int             len, offset_checksum;
        proto_item      *it_cksum;
+       char* system_id;
 
-       if (tree) {
-               ti = proto_tree_add_text(tree, tvb, offset, -1,
-                   PROTO_STRING_LSP);
-               lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
-       }
+       col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS LSP");
+
+       ti = proto_tree_add_item(tree, proto_isis_lsp, tvb, offset, -1, ENC_NA);
+       lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
 
        pdu_length = tvb_get_ntohs(tvb, offset);
-       if (tree) {
-               proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, tvb,
+       proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, tvb,
                        offset, 2, pdu_length);
-       }
        offset += 2;
 
-       if (tree) {
-               proto_tree_add_item(lsp_tree, hf_isis_lsp_remaining_life,
+       proto_tree_add_item(lsp_tree, hf_isis_lsp_remaining_life,
                        tvb, offset, 2, ENC_BIG_ENDIAN);
-       }
+
        lifetime = tvb_get_ntohs(tvb, offset);
        offset += 2;
        offset_checksum = offset;
 
-       if (tree) {
-               char* value = print_system_id( tvb_get_ptr(tvb, offset, id_length+2),
+       system_id = print_system_id( tvb_get_ptr(tvb, offset, id_length+2),
                                    id_length+2);
-               proto_tree_add_string_format_value(lsp_tree, hf_isis_lsp_lsp_id,
+       proto_tree_add_bytes_format_value(lsp_tree, hf_isis_lsp_lsp_id,
                        tvb, offset, id_length + 2,
-                       value, "%s", value);
-       }
+                       tvb_get_ptr(tvb, offset, id_length+2), "%s", system_id);
 
-       col_append_fstr(pinfo->cinfo, COL_INFO, ", LSP-ID: %s",
-                       print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
+       col_append_fstr(pinfo->cinfo, COL_INFO, ", LSP-ID: %s", system_id);
 
-       offset += id_length + 2;
+       offset += (id_length + 2);
 
        proto_tree_add_item(lsp_tree, hf_isis_lsp_sequence_number,
                        tvb, offset, 4, ENC_BIG_ENDIAN);
@@ -2722,33 +2625,29 @@ isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
 
        offset += 4;
 
-       if (tree) {
-               checksum = lifetime ? tvb_get_ntohs(tvb, offset) : 0;
-               switch (check_and_get_checksum(tvb, offset_checksum, pdu_length-12, checksum, offset, &cacl_checksum)) {
-                       case NO_CKSUM :
-                               checksum = tvb_get_ntohs(tvb, offset);
-                               proto_tree_add_uint_format_value(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
+       checksum = lifetime ? tvb_get_ntohs(tvb, offset) : 0;
+       switch (check_and_get_checksum(tvb, offset_checksum, pdu_length-12, checksum, offset, &cacl_checksum)) {
+               case NO_CKSUM :
+                       checksum = tvb_get_ntohs(tvb, offset);
+                       proto_tree_add_uint_format_value(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
                                        "0x%04x [unused]", checksum);
-                       break;
-                       case DATA_MISSING :
-                               isis_dissect_unknown(tvb, tree, offset,
-                                       "[packet length %d went beyond packet]",
+               break;
+               case DATA_MISSING :
+                       proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_long_packet, tvb, offset, -1,
+                                       "Packet length %d went beyond packet",
                                        tvb_length_remaining(tvb, offset_checksum));
-                       break;
-                       case CKSUM_NOT_OK :
-                               it_cksum = proto_tree_add_uint_format_value(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
+               break;
+               case CKSUM_NOT_OK :
+                       it_cksum = proto_tree_add_uint_format_value(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
                                        "0x%04x [incorrect, should be 0x%04x]",
                                        checksum, cacl_checksum);
-                               isis_lsp_checkum_additional_info(tvb, pinfo, it_cksum, offset, FALSE);
-                       break;
-                       case CKSUM_OK :
-                               it_cksum = proto_tree_add_uint_format_value(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
+                       isis_lsp_checkum_additional_info(tvb, pinfo, it_cksum, offset, FALSE);
+               break;
+               case CKSUM_OK :
+                       it_cksum = proto_tree_add_uint_format_value(lsp_tree, hf_isis_lsp_checksum, tvb, offset, 2, checksum,
                                        "0x%04x [correct]", checksum);
                                isis_lsp_checkum_additional_info(tvb, pinfo, it_cksum, offset, TRUE);
-                       break;
-                       default :
-                               g_message("'check_and_get_checksum' returned an invalid value");
-               }
+               break;
        }
        offset += 2;
 
@@ -2771,14 +2670,10 @@ isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
                ta = proto_tree_add_uint(info_tree, hf_isis_lsp_att, tvb, offset, 1, lsp_info);
                att_tree = proto_item_add_subtree(ta, ett_isis_lsp_att);
                lsp_att = ISIS_LSP_ATT(lsp_info);
-               proto_tree_add_text(att_tree, tvb, offset, 1,
-                         "%d... = Error metric: %s", ISIS_LSP_ATT_ERROR(lsp_att), ISIS_LSP_ATT_ERROR(lsp_att) ? "Set" : "Unset");
-               proto_tree_add_text(att_tree, tvb, offset, 1,
-                         ".%d.. = Expense metric: %s", ISIS_LSP_ATT_EXPENSE(lsp_att), ISIS_LSP_ATT_EXPENSE(lsp_att) ? "Set" : "Unset");
-               proto_tree_add_text(att_tree, tvb, offset, 1,
-                         "..%d. = Delay metric: %s", ISIS_LSP_ATT_DELAY(lsp_att), ISIS_LSP_ATT_DELAY(lsp_att) ? "Set" : "Unset");
-               proto_tree_add_text(att_tree, tvb, offset, 1,
-                         "...%d = Default metric: %s", ISIS_LSP_ATT_DEFAULT(lsp_att), ISIS_LSP_ATT_DEFAULT(lsp_att) ? "Set" : "Unset");
+               proto_tree_add_item(att_tree, hf_isis_lsp_error_metric, tvb, offset, 1, ENC_NA);
+               proto_tree_add_item(att_tree, hf_isis_lsp_expense_metric, tvb, offset, 1, ENC_NA);
+               proto_tree_add_item(att_tree, hf_isis_lsp_delay_metric, tvb, offset, 1, ENC_NA);
+               proto_tree_add_item(att_tree, hf_isis_lsp_default_metric, tvb, offset, 1, ENC_NA);
                proto_tree_add_boolean(info_tree, hf_isis_lsp_hippity, tvb, offset, 1, lsp_info);
                proto_tree_add_uint(info_tree, hf_isis_lsp_is_type, tvb, offset, 1, lsp_info);
        }
@@ -2786,7 +2681,7 @@ isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
 
        len = pdu_length - header_length;
        if (len < 0) {
-               isis_dissect_unknown(tvb, tree, offset,
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_long_packet, tvb, offset, -1,
                        "packet header length %d went beyond packet",
                         header_length );
                return;
@@ -2795,30 +2690,31 @@ isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
         * Now, we need to decode our CLVs.  We need to pass in
         * our list of valid ones!
         */
-       if (lsp_type == ISIS_TYPE_L1_LSP) {
-               isis_dissect_clvs(tvb, lsp_tree, offset,
-                       clv_l1_lsp_opts, len, id_length,
-                       ett_isis_lsp_clv_unknown );
-       } else {
-               isis_dissect_clvs(tvb, lsp_tree, offset,
-                       clv_l2_lsp_opts, len, id_length,
-                       ett_isis_lsp_clv_unknown );
-       }
+       isis_dissect_clvs(tvb, pinfo, lsp_tree, offset,
+                       opts, &ei_isis_lsp_short_packet, len, id_length, ett_isis_lsp_clv_unknown );
 }
-/*
- * Name: isis_register_lsp()
- *
- * Description:
- *     Register our protocol sub-sets with protocol manager.
- *
- * Input:
- *     int : protocol index for the ISIS protocol
- *
- * Output:
- *     void
- */
+
+static int
+dissect_isis_l1_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+       isis_data_t* isis = (isis_data_t*)data;
+       dissect_isis_lsp(tvb, pinfo, tree, 0,
+               clv_l1_lsp_opts, isis->header_length, isis->system_id_len);
+       return tvb_length(tvb);
+}
+
+static int
+dissect_isis_l2_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+       isis_data_t* isis = (isis_data_t*)data;
+       dissect_isis_lsp(tvb, pinfo, tree, 0,
+               clv_l2_lsp_opts, isis->header_length, isis->system_id_len);
+       return tvb_length(tvb);
+}
+
 void
-isis_register_lsp(int proto_isis) {
+proto_register_isis_lsp(void)
+{
        static hf_register_info hf[] = {
                { &hf_isis_lsp_pdu_length,
                { "PDU length",         "isis.lsp.pdu_length", FT_UINT16,
@@ -2829,7 +2725,7 @@ isis_register_lsp(int proto_isis) {
                  BASE_DEC, NULL, 0x0, NULL, HFILL }},
 
                { &hf_isis_lsp_lsp_id,
-               { "LSP-ID", "isis.lsp.lsp_id", FT_STRING,
+               { "LSP-ID", "isis.lsp.lsp_id", FT_BYTES,
                  BASE_NONE, NULL, 0x0, NULL, HFILL }},
 
                { &hf_isis_lsp_hostname,
@@ -2910,8 +2806,107 @@ isis_register_lsp(int proto_isis) {
 
                { &hf_isis_lsp_spb_spvid,
                { "SPVID", "isis.lsp.spb.spvid",
-                       FT_UINT16, BASE_HEX_DEC, NULL, 0, NULL, HFILL }}
+                       FT_UINT16, BASE_HEX_DEC, NULL, 0, NULL, HFILL }},
 
+      /* Generated from convert_proto_tree_add_text.pl */
+      { &hf_isis_lsp_mt_id_reserved, { "Reserved", "isis.lsp.reserved", FT_UINT16, BASE_HEX, NULL, ISIS_LSP_MT_MSHIP_RES_MASK, NULL, HFILL }},
+      { &hf_isis_lsp_mt_id, { "MT ID", "isis.lsp.mt_id", FT_UINT16, BASE_DEC, NULL, ISIS_LSP_MT_MSHIP_ID_MASK, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_ipv4_prefix, { "IPv4 prefix", "isis.lsp.ip_reachability.ipv4_prefix", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_default_metric, { "Default Metric", "isis.lsp.ip_reachability.default_metric", FT_UINT8, BASE_DEC, NULL, 0x3F, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_delay_metric, { "Delay Metric", "isis.lsp.ip_reachability.delay_metric", FT_UINT8, BASE_DEC, NULL, 0x3F, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_expense_metric, { "Expense Metric", "isis.lsp.ip_reachability.expense_metric", FT_UINT8, BASE_DEC, NULL, 0x3F, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_error_metric, { "Error Metric", "isis.lsp.ip_reachability.error_metric", FT_UINT8, BASE_DEC, NULL, 0x3F, NULL, HFILL }},
+      { &hf_isis_lsp_32_bit_administrative_tag, { "32-Bit Administrative tag", "isis.lsp.32_bit_administrative_tag", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_64_bit_administrative_tag, { "64-Bit Administrative tag", "isis.lsp.64_bit_administrative_tag", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ext_ip_reachability_ipv4_prefix, { "IPv4 prefix", "isis.lsp.ext_ip_reachability.ipv4_prefix", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ext_ip_reachability_metric, { "Metric", "isis.lsp.ext_ip_reachability.metric", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ext_ip_reachability_distribution, { "Distribution", "isis.lsp.ext_ip_reachability.distribution", FT_BOOLEAN, 8, TFS(&tfs_up_down), 0x80, NULL, HFILL }},
+      { &hf_isis_lsp_grp_address_length, { "Length", "isis.lsp.grp_address.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_grp_address_topology_id, { "Topology ID", "isis.lsp.grp_address.topology_id", FT_UINT16, BASE_DEC, NULL, 0x0fff, NULL, HFILL }},
+      { &hf_isis_lsp_grp_address_vlan_id, { "VLAN ID", "isis.lsp.grp_address.vlan_id", FT_UINT16, BASE_DEC, NULL, 0x0fff, NULL, HFILL }},
+      { &hf_isis_lsp_grp_address_number_of_records, { "Number of records", "isis.lsp.grp_address.number_of_records", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_grp_address_number_of_sources, { "Number of sources", "isis.lsp.grp_address.number_of_sources", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_grp_address_group_address, { "Group Address", "isis.lsp.grp_address.group_address", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_grp_address_source_address, { "Source Address", "isis.lsp.grp_address.source_address", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_trill_length, { "Length", "isis.lsp.rt_capable.trill.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_trill_maximum_version, { "Maximum version", "isis.lsp.rt_capable.trill.maximum_version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_trees_length, { "Length", "isis.lsp.rt_capable.trees.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_trees_nof_trees_to_compute, { "Nof. trees to compute", "isis.lsp.rt_capable.trees.nof_trees_to_compute", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_trees_maximum_nof_trees_to_compute, { "Maximum nof. trees to compute", "isis.lsp.rt_capable.trees.maximum_nof_trees_to_compute", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_trees_nof_trees_to_use, { "Nof. trees to use", "isis.lsp.rt_capable.trees.nof_trees_to_use", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_tree_root_id_length, { "Length", "isis.lsp.rt_capable.tree_root_id.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_tree_root_id_starting_tree_no, { "Starting tree no", "isis.lsp.rt_capable.tree_root_id.starting_tree_no", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_tree_root_id_nickname, { "Nickname", "isis.lsp.rt_capable.tree_root_id.nickname", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_nickname_length, { "Length", "isis.lsp.rt_capable.nickname.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_nickname_nickname_priority, { "Nickname priority", "isis.lsp.rt_capable.nickname.nickname_priority", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_nickname_tree_root_priority, { "Tree root priority", "isis.lsp.rt_capable.nickname.tree_root_priority", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_nickname_nickname, { "Nickname", "isis.lsp.rt_capable.nickname.nickname", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_interested_vlans_length, { "Length", "isis.lsp.rt_capable.interested_vlans.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_interested_vlans_nickname, { "Nickname", "isis.lsp.rt_capable.interested_vlans.nickname", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_interested_vlans_multicast_ipv4, { "IPv4 multicast router", "isis.lsp.rt_capable.interested_vlans.multicast_ipv4", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x8000, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_interested_vlans_multicast_ipv6, { "IPv6 multicast router", "isis.lsp.rt_capable.interested_vlans.multicast_ipv6", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x4000, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_interested_vlans_vlan_start_id, { "Vlan start id", "isis.lsp.rt_capable.interested_vlans.vlan_start_id", FT_UINT16, BASE_HEX, NULL, 0x0fff, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_interested_vlans_vlan_end_id, { "Vlan end id", "isis.lsp.rt_capable.interested_vlans.vlan_end_id", FT_UINT16, BASE_HEX, NULL, 0x0fff, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_interested_vlans_afs_lost_counter, { "Appointed forward state lost counter", "isis.lsp.rt_capable.interested_vlans.afs_lost_counter", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_tree_used_id_length, { "Length", "isis.lsp.rt_capable.tree_used_id.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_tree_used_id_starting_tree_no, { "Starting tree no", "isis.lsp.rt_capable.tree_used_id.starting_tree_no", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_tree_used_id_nickname, { "Nickname", "isis.lsp.rt_capable.tree_used_id.nickname", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_vlan_group_length, { "Length", "isis.lsp.rt_capable.vlan_group.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_vlan_group_primary_vlan_id, { "Primary vlan id", "isis.lsp.rt_capable.vlan_group.primary_vlan_id", FT_UINT16, BASE_DEC, NULL, 0x0fff, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_vlan_group_secondary_vlan_id, { "Secondary vlan id", "isis.lsp.rt_capable.vlan_group.secondary_vlan_id", FT_UINT16, BASE_DEC, NULL, 0x0fff, NULL, HFILL }},
+      { &hf_isis_lsp_rt_capable_vlan_group_nth_secondary_vlan_id, { "%dth secondary vlan id", "isis.lsp.rt_capable.vlan_group.nth_secondary_vlan_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ipv6_reachability_ipv6_prefix, { "IPv6 prefix", "isis.lsp.ipv6_reachability.ipv6_prefix", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ipv6_reachability_metric, { "Metric", "isis.lsp.ipv6_reachability.metric", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ipv6_reachability_distribution, { "Distribution", "isis.lsp.ipv6_reachability.distribution", FT_BOOLEAN, 8, TFS(&tfs_up_down), 0x80, NULL, HFILL }},
+      { &hf_isis_lsp_ipv6_reachability_distribution_internal, { "Distribution", "isis.lsp.ipv6_reachability.distribution_internal", FT_BOOLEAN, 8, TFS(&tfs_internal_external), 0x40, NULL, HFILL }},
+      { &hf_isis_lsp_ipv6_reachability_reserved_bits, { "Reserved bits", "isis.lsp.ipv6_reachability.reserved_bits", FT_UINT8, BASE_HEX, NULL, 0x1F, NULL, HFILL }},
+      { &hf_isis_lsp_mt_cap_spb_instance_cist_root_identifier, { "CIST Root Identifier", "isis.lsp.mt_cap_spb_instance.cist_root_identifier", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_mt_cap_spb_instance_cist_external_root_path_cost, { "CIST External Root Path Cost", "isis.lsp.mt_cap_spb_instance.cist_external_root_path_cost", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_mt_cap_spb_instance_bridge_priority, { "Bridge Priority", "isis.lsp.mt_cap_spb_instance.bridge_priority", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_mt_cap_spb_instance_v, { "V", "isis.lsp.mt_cap_spb_instance.v", FT_BOOLEAN, 32, NULL, 0x00100000, NULL, HFILL }},
+      { &hf_isis_lsp_mt_cap_spb_instance_number_of_trees, { "Number of Trees", "isis.lsp.mt_cap_spb_instance.number_of_trees", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_mt_cap_spbm_service_identifier_b_mac, { "B-MAC", "isis.lsp.mt_cap_spbm_service_identifier.b_mac", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_mt_cap_spbm_service_identifier_base_vid, { "Base-VID", "isis.lsp.mt_cap_spbm_service_identifier.base_vid", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_mt_cap_mtid, { "MTID", "isis.lsp.mt_cap.mtid", FT_UINT16, BASE_HEX, NULL, 0xfff, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_reserved, { "Reserved", "isis.lsp.eis_neighbors_clv_inner.reserved", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_es_neighbor, { "ES Neighbor", "isis.lsp.eis_neighbors.es_neighbor", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_is_neighbor, { "IS Neighbor", "isis.lsp.eis_neighbors.is_neighbor", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_default_metric, { "Default Metric", "isis.lsp.eis_neighbors.default_metric", FT_UINT8, BASE_DEC, NULL, 0x3F, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_delay_metric, { "Delay Metric", "isis.lsp.eis_neighbors.delay_metric", FT_UINT8, BASE_DEC, NULL, 0x3F, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_expense_metric, { "Expense Metric", "isis.lsp.eis_neighbors.expense_metric", FT_UINT8, BASE_DEC, NULL, 0x3F, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_error_metric, { "Error Metric", "isis.lsp.eis_neighbors.error_metric", FT_UINT8, BASE_DEC, NULL, 0x3F, NULL, HFILL }},
+      { &hf_isis_lsp_maximum_link_bandwidth, { "Maximum link bandwidth", "isis.lsp.maximum_link_bandwidth", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_reservable_link_bandwidth, { "Reservable link bandwidth", "isis.lsp.reservable_link_bandwidth", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ext_is_reachability_is_neighbor, { "IS neighbor", "isis.lsp.ext_is_reachability.is_neighbor", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ext_is_reachability_metric, { "Metric", "isis.lsp.ext_is_reachability.metric", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ext_is_reachability_link_local_identifier, { "Link Local Identifier", "isis.lsp.ext_is_reachability.link_local_identifier", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ext_is_reachability_link_remote_identifier, { "Link Remote Identifier", "isis.lsp.ext_is_reachability.link_remote_identifier", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ext_is_reachability_ipv4_interface_address, { "IPv4 interface address", "isis.lsp.ext_is_reachability.ipv4_interface_address", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ext_is_reachability_ipv4_neighbor_address, { "IPv4 neighbor address", "isis.lsp.ext_is_reachability.ipv4_neighbor_address", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ext_is_reachability_traffic_engineering_default_metric, { "Traffic engineering default metric", "isis.lsp.ext_is_reachability.traffic_engineering_default_metric", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_partition_designated_l2_is, { "Partition designated L2 IS", "isis.lsp.partition_designated_l2_is", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_error_metric, { "Error metric", "isis.lsp.error_metric", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x08, NULL, HFILL }},
+      { &hf_isis_lsp_expense_metric, { "Expense metric", "isis.lsp.expense_metric", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x04, NULL, HFILL }},
+      { &hf_isis_lsp_delay_metric, { "Delay metric", "isis.lsp.delay_metric", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x02, NULL, HFILL }},
+      { &hf_isis_lsp_default_metric, { "Default metric", "isis.lsp.default_metric", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x01, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_default_metric_ie, { "Default Metric IE", "isis.lsp.ip_reachability.default_metric_ie", FT_BOOLEAN, 8, TFS(&tfs_external_internal), 0x40, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_delay_metric_support, { "Delay Metric", "isis.lsp.ip_reachability.delay_metric_support", FT_BOOLEAN, 8, TFS(&tfs_notsupported_supported), 0x80, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_expense_metric_support, { "Expense Metric", "isis.lsp.ip_reachability.expense_metric_support", FT_BOOLEAN, 8, TFS(&tfs_notsupported_supported), 0x80, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_error_metric_support, { "Error Metric", "isis.lsp.ip_reachability.error_metric_support", FT_BOOLEAN, 8, TFS(&tfs_notsupported_supported), 0x80, NULL, HFILL }},
+      { &hf_isis_lsp_mt_cap_spsourceid, { "SPSourceId", "isis.lsp.mt_cap.spsourceid", FT_UINT32, BASE_HEX_DEC, NULL, 0xfffff, NULL, HFILL }},
+      { &hf_isis_lsp_mt_cap_overload, { "Overload", "isis.lsp.overload", FT_BOOLEAN, 16, NULL, 0x8000, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_default_metric_ie, { "Default Metric", "isis.lsp.eis_neighbors.default_metric_ie", FT_BOOLEAN, 8, TFS(&tfs_external_internal), 0x40, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_delay_metric_supported, { "Delay Metric", "isis.lsp.eis_neighbors_delay_metric.supported", FT_BOOLEAN, 8, TFS(&tfs_notsupported_supported), 0x80, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_expense_metric_supported, { "Expense Metric", "isis.lsp.eis_neighbors.expense_metric_supported", FT_BOOLEAN, 8, TFS(&tfs_notsupported_supported), 0x80, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_error_metric_supported, { "Error Metric", "isis.lsp.eis_neighbors.error_metric_supported", FT_BOOLEAN, 8, TFS(&tfs_notsupported_supported), 0x80, NULL, HFILL }},
+      { &hf_isis_lsp_unrsv_bw_priority_level, { "priority level", "isis.lsp.unrsv_bw.priority_level", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_distribution, { "Distribution", "isis.lsp.ip_reachability.distribution", FT_BOOLEAN, 8, TFS(&tfs_up_down), 0x80, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_delay_metric_ie, { "Delay Metric", "isis.lsp.ip_reachability.delay_metric_ie", FT_BOOLEAN, 8, TFS(&tfs_external_internal), 0x40, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_expense_metric_ie, { "Expense Metric", "isis.lsp.ip_reachability.expense_metric_ie", FT_BOOLEAN, 8, TFS(&tfs_external_internal), 0x40, NULL, HFILL }},
+      { &hf_isis_lsp_ip_reachability_error_metric_ie, { "Error Metric", "isis.lsp.ip_reachability.error_metric_ie", FT_BOOLEAN, 8, TFS(&tfs_external_internal), 0x40, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_delay_metric_ie, { "Delay Metric", "isis.lsp.eis_neighbors.delay_metric_ie", FT_BOOLEAN, 8, TFS(&tfs_external_internal), 0x40, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_expense_metric_ie, { "Expense Metric", "isis.lsp.eis_neighbors.expense_metric_ie", FT_BOOLEAN, 8, TFS(&tfs_external_internal), 0x40, NULL, HFILL }},
+      { &hf_isis_lsp_eis_neighbors_error_metric_ie, { "Error Metric", "isis.lsp.eis_neighbors.error_metric_ie", FT_BOOLEAN, 8, TFS(&tfs_external_internal), 0x40, NULL, HFILL }},
        };
        static gint *ett[] = {
                &ett_isis_lsp,
@@ -2956,12 +2951,26 @@ isis_register_lsp(int proto_isis) {
 
        static ei_register_info ei[] = {
                { &ie_isis_lsp_checksum_bad, { "isis.lsp.checksum_bad.expert", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
+               { &ei_isis_lsp_short_packet, { "isis.lsp.short_packet", PI_MALFORMED, PI_ERROR, "Short packet", EXPFILL }},
+               { &ei_isis_lsp_long_packet, { "isis.lsp.long_packet", PI_MALFORMED, PI_ERROR, "Long packet", EXPFILL }},
+               { &ei_isis_lsp_subtlv, { "isis.lsp.subtlv.unknown", PI_PROTOCOL, PI_WARN, "Unknown SubTLV", EXPFILL }},
+               { &ei_isis_lsp_authentication, { "isis.lsp.authentication.unknown", PI_PROTOCOL, PI_WARN, "Unknown authentication type", EXPFILL }},
        };
 
-       expert_module_t* expert_isis;
+       expert_module_t* expert_isis_lsp;
+
+       /* Register the protocol name and description */
+       proto_isis_lsp = proto_register_protocol(PROTO_STRING_LSP, "ISIS LSP", "isis.lsp");
 
-       proto_register_field_array(proto_isis, hf, array_length(hf));
+       proto_register_field_array(proto_isis_lsp, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));
-       expert_isis = expert_register_protocol(proto_isis);
-       expert_register_field_array(expert_isis, ei, array_length(ei));
+       expert_isis_lsp = expert_register_protocol(proto_isis_lsp);
+       expert_register_field_array(expert_isis_lsp, ei, array_length(ei));
+}
+
+void
+proto_reg_handoff_isis_lsp(void)
+{
+       dissector_add_uint("isis.type", ISIS_TYPE_L1_LSP, new_create_dissector_handle(dissect_isis_l1_lsp, proto_isis_lsp));
+       dissector_add_uint("isis.type", ISIS_TYPE_L2_LSP, new_create_dissector_handle(dissect_isis_l2_lsp, proto_isis_lsp));
 }
diff --git a/epan/dissectors/packet-isis-lsp.h b/epan/dissectors/packet-isis-lsp.h
deleted file mode 100644 (file)
index e9b0cb6..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/* packet-isis-lsp.h
- * Defines and such for LSP and their CLV decodes
- *
- * $Id$
- * Stuart Stanley <stuarts@mxmail.net>
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef _PACKET_ISIS_LSP_H
-#define _PACKET_ISIS_LSP_H
-
-/*
- * Declarations for L1/L2 LSP base header.
- */
-
-/* P | ATT | HIPPITY | DS FIELD description */
-#define ISIS_LSP_PARTITION_MASK     0x80
-#define ISIS_LSP_PARTITION_SHIFT    7
-#define ISIS_LSP_PARTITION(info)    (((info) & ISIS_LSP_PARTITION_MASK) >> ISIS_LSP_PARTITION_SHIFT)
-
-#define ISIS_LSP_ATT_MASK     0x78
-#define ISIS_LSP_ATT_SHIFT    3
-#define ISIS_LSP_ATT(info)    (((info) & ISIS_LSP_ATT_MASK) >> ISIS_LSP_ATT_SHIFT)
-
-#define ISIS_LSP_ATT_ERROR(info)   ((info) >> 3)
-#define ISIS_LSP_ATT_EXPENSE(info) (((info) >> 2) & 1)
-#define ISIS_LSP_ATT_DELAY(info)   (((info) >> 1) & 1)
-#define ISIS_LSP_ATT_DEFAULT(info) ((info) & 1)
-
-#define ISIS_LSP_HIPPITY_MASK     0x04
-#define ISIS_LSP_HIPPITY_SHIFT    2
-#define ISIS_LSP_HIPPITY(info)    (((info) & ISIS_LSP_HIPPITY_MASK) >> ISIS_LSP_HIPPITY_SHIFT)
-
-#define ISIS_LSP_IS_TYPE_MASK     0x03
-#define ISIS_LSP_IS_TYPE(info)    ((info) & ISIS_LSP_IS_TYPE_MASK)
-
-#define ISIS_LSP_MT_MSHIP_RES_MASK    4
-#define ISIS_LSP_MT_MSHIP_RES_SHIFT   12
-#define ISIS_LSP_MT_MSHIP_RES(info)  (((info) >> ISIS_LSP_MT_MSHIP_RES_SHIFT) & ISIS_LSP_MT_MSHIP_RES_MASK)
-
-#define ISIS_LSP_MT_MSHIP_ID_MASK   0x0FFF
-#define ISIS_LSP_MT_MSHIP_ID(info)  ((info) & ISIS_LSP_MT_MSHIP_ID_MASK)
-
-
-#define ISIS_LSP_TYPE_UNUSED0          0
-#define ISIS_LSP_TYPE_LEVEL_1          1
-#define ISIS_LSP_TYPE_UNUSED2          2
-#define ISIS_LSP_TYPE_LEVEL_2          3
-
-#define ISIS_LSP_ATTACHED_NONE    0
-#define ISIS_LSP_ATTACHED_DEFAULT 1
-#define ISIS_LSP_ATTACHED_DELAY   2
-#define ISIS_LSP_ATTACHED_EXPENSE 4
-#define ISIS_LSP_ATTACHED_ERROR   8
-
-
-#define ISIS_LSP_CLV_METRIC_SUPPORTED(x)       ((x)&0x80)
-#define ISIS_LSP_CLV_METRIC_IE(x)               ((x)&0x40)
-#define ISIS_LSP_CLV_METRIC_RESERVED(x)                ((x)&0x40)
-#define ISIS_LSP_CLV_METRIC_UPDOWN(x)           ((x)&0x80)
-#define ISIS_LSP_CLV_METRIC_VALUE(x)           ((x)&0x3f)
-
-/*
- * Published API functions.  NOTE, this are "local" API functions and
- * are only valid from with isis decodes.
- */
-extern void isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-       int offset, int hello_type, int header_length, int id_length);
-extern void isis_register_lsp(int proto_isis);
-
-#endif /* _PACKET_ISIS_LSP_H */
index a5e073b08b7bfc463d8ce1ce0764230e47378e2d..be178bda04321546734d30d96c0d61b34ef6913d 100644 (file)
 
 #include <glib.h>
 #include <epan/packet.h>
+#include <epan/expert.h>
 #include "packet-osi.h"
 #include "packet-isis.h"
 #include "packet-isis-clv.h"
-#include "packet-isis-lsp.h"
-#include "packet-isis-snp.h"
+
+static int proto_isis_csnp = -1;
+static int proto_isis_psnp = -1;
 
 /* csnp packets */
 static int hf_isis_csnp_pdu_length = -1;
+static int hf_isis_csnp_source_id = -1;
+static int hf_isis_csnp_start_lsp_id = -1;
+static int hf_isis_csnp_end_lsp_id = -1;
+static int hf_isis_csnp_lsp_id = -1;
+static int hf_isis_csnp_lsp_seq_num = -1;
+static int hf_isis_csnp_lsp_remain_life = -1;
+static int hf_isis_csnp_lsp_checksum = -1;
+static int hf_isis_csnp_checksum = -1;
 static gint ett_isis_csnp = -1;
 static gint ett_isis_csnp_clv_lsp_entries = -1;
 static gint ett_isis_csnp_lsp_entry = -1;
@@ -43,8 +53,13 @@ static gint ett_isis_csnp_clv_ip_authentication = -1;
 static gint ett_isis_csnp_clv_checksum = -1;
 static gint ett_isis_csnp_clv_unknown = -1;
 
+static expert_field ei_isis_csnp_short_packet = EI_INIT;
+static expert_field ei_isis_csnp_long_packet = EI_INIT;
+static expert_field ei_isis_csnp_authentication = EI_INIT;
+
 /* psnp packets */
 static int hf_isis_psnp_pdu_length = -1;
+static int hf_isis_psnp_source_id = -1;
 static gint ett_isis_psnp = -1;
 static gint ett_isis_psnp_clv_lsp_entries = -1;
 static gint ett_isis_psnp_lsp_entry = -1;
@@ -53,14 +68,114 @@ static gint ett_isis_psnp_clv_ip_authentication = -1;
 static gint ett_isis_psnp_clv_checksum = -1;
 static gint ett_isis_psnp_clv_unknown = -1;
 
-static void dissect_snp_authentication_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_snp_ip_authentication_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_snp_checksum_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
-static void dissect_snp_lsp_entries_clv(tvbuff_t *tvb,
-       proto_tree *tree, int offset, int id_length, int length);
+static expert_field ei_isis_psnp_short_packet = EI_INIT;
+static expert_field ei_isis_psnp_long_packet = EI_INIT;
+
+static void
+dissect_snp_authentication_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
+       int id_length _U_, int length)
+{
+       isis_dissect_authentication_clv(tree, pinfo, tvb, &ei_isis_csnp_authentication, offset, length);
+}
+
+static void
+dissect_snp_ip_authentication_clv(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *tree, int offset,
+       int id_length _U_, int length)
+{
+       isis_dissect_ip_authentication_clv(tvb, tree, offset, length);
+}
+
+/*
+ * Name: dissect_snp_checksum_clv()
+ *
+ * Description:
+ *      dump and verify the optional checksum in TLV 12
+ */
+static void
+dissect_snp_checksum_clv(tvbuff_t *tvb, packet_info* pinfo,
+        proto_tree *tree, int offset, int id_length _U_, int length) {
+
+    guint16 pdu_length,checksum, cacl_checksum=0;
+    proto_item* ti;
+
+    if ( length != 2 ) {
+        proto_tree_add_expert_format(tree, pinfo, &ei_isis_csnp_short_packet, tvb, offset, -1,
+            "incorrect checksum length (%u), should be (2)", length );
+            return;
+    }
+
+    ti = proto_tree_add_item( tree, hf_isis_csnp_checksum, tvb, offset, length, ENC_BIG_ENDIAN);
+
+    checksum = tvb_get_ntohs(tvb, offset);
+
+        /* the check_and_get_checksum() function needs to know how big
+            * the packet is. we can either pass through the pdu-len through several layers
+            * of dissectors and wrappers or extract the PDU length field from the PDU specific header
+            * which is offseted 8 bytes (relative to the beginning of the IS-IS packet) in SNPs */
+
+    pdu_length = tvb_get_ntohs(tvb, 8);
+
+    /* unlike the LSP checksum verification which starts at an offset of 12 we start at offset 0*/
+    switch (check_and_get_checksum(tvb, 0, pdu_length, checksum, offset, &cacl_checksum))
+    {
+        case NO_CKSUM :
+             proto_item_append_text(ti, " [unused]");
+               break;
+        case DATA_MISSING :
+             expert_add_info_format(pinfo, ti, &ei_isis_csnp_long_packet,
+                                        "Packet length %d went beyond packet", tvb_length(tvb));
+        break;
+        case CKSUM_NOT_OK :
+             proto_item_append_text(ti, " [incorrect, should be 0x%04x]", cacl_checksum);
+        break;
+        case CKSUM_OK :
+             proto_item_append_text(ti, " [correct]");
+        break;
+    }
+}
+
+/*
+ * Name: dissect_snp_lsp_entries_clv()
+ *
+ * Description:
+ *     All the snp packets use a common payload format.  We have up
+ *     to n entries (based on length), which are made of:
+ *             2         : remaining life time
+ *             id_length : lsp id
+ *             4         : sequence number
+ *             2         : checksum
+ */
+static void
+dissect_snp_lsp_entries_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
+       int id_length, int length)
+{
+       proto_item *ti;
+       proto_tree *subtree;
+       const guint8 *source_id;
+
+       while ( length > 0 ) {
+               if ( length < 2+id_length+2+4+2 ) {
+                       proto_tree_add_expert_format(tree, pinfo, &ei_isis_csnp_short_packet, tvb, offset, -1,
+                               "Short SNP header entry (%d vs %d)", length, 2+id_length+2+4+2 );
+                       return;
+               }
+
+               ti = proto_tree_add_text(tree, tvb, offset, 2+id_length+2+4+2, "LSP Entry");
+               subtree = proto_item_add_subtree(ti,ett_isis_csnp_lsp_entry);
+
+               source_id = tvb_get_ptr(tvb, offset+2, id_length+2);
+               proto_tree_add_bytes_format_value(tree, hf_isis_csnp_lsp_id, tvb,
+                                               offset+2, 8, source_id, "%s", print_system_id(source_id, id_length+2));
+
+               proto_tree_add_item(subtree, hf_isis_csnp_lsp_seq_num, tvb, offset+2+id_length+2, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(subtree, hf_isis_csnp_lsp_remain_life, tvb, offset, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(subtree, hf_isis_csnp_lsp_checksum, tvb, offset+2+id_length+2+4, 2, ENC_BIG_ENDIAN);
+
+               length -= 2+id_length+2+4+2;
+               offset += 2+id_length+2+4+2;
+       }
+
+}
 
 static const isis_clv_handle_t clv_l1_csnp_opts[] = {
        {
@@ -182,356 +297,173 @@ static const isis_clv_handle_t clv_l2_psnp_opts[] = {
        }
 };
 
-/*
- * Name: dissect_snp_lsp_entries_clv()
- *
- * Description:
- *     All the snp packets use a common payload format.  We have up
- *     to n entries (based on length), which are made of:
- *             2         : remaining life time
- *             id_length : lsp id
- *             4         : sequence number
- *             2         : checksum
- *
- * Input:
- *     tvbuff_t * : tvbuffer for packet data
- *     proto_tree * : protocol display tree to fill out.  May be NULL
- *     int : offset into packet data where we are.
- *     int : length of IDs in packet.
- *     int : length of payload to decode.
- *
- * Output:
- *      void, but we will add to proto tree if !NULL.
- */
 static void
-dissect_snp_lsp_entries_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
-       int id_length, int length)
-{
-        proto_tree *subtree,*ti;
-
-       while ( length > 0 ) {
-               if ( length < 2+id_length+2+4+2 ) {
-                       isis_dissect_unknown(tvb, tree, offset,
-                               "Short SNP header entry (%d vs %d)", length,
-                               2+id_length+2+4+2 );
-                       return;
-               }
-
-               ti = proto_tree_add_text(tree, tvb, offset, 2+id_length+2+4+2,
-                                    "LSP-ID: %s, Sequence: 0x%08x, Lifetime: %5us, Checksum: 0x%04x",
-                                           print_system_id( tvb_get_ptr(tvb, offset+2, id_length+2), id_length+2 ),
-                                           tvb_get_ntohl(tvb, offset+2+id_length+2),
-                                           tvb_get_ntohs(tvb, offset),
-                                           tvb_get_ntohs(tvb, offset+2+id_length+2+4));
-
-                subtree = proto_item_add_subtree(ti,ett_isis_csnp_lsp_entry);
-
-               proto_tree_add_text(subtree, tvb, offset+2, 8,
-                       "LSP-ID:             : %s",
-                       print_system_id( tvb_get_ptr(tvb, offset+2, id_length+2), id_length+2 ));
-
-               proto_tree_add_text(subtree, tvb, offset+2+id_length+2, 4,
-                       "LSP Sequence Number : 0x%08x",
-                       tvb_get_ntohl(tvb, offset+2+id_length+2));
-
-               proto_tree_add_text(subtree, tvb, offset, 2,
-                       "Remaining Lifetime  : %us",
-                       tvb_get_ntohs(tvb, offset));
-
-               proto_tree_add_text(subtree, tvb, offset+2+id_length+2+4, 2,
-                       "LSP checksum        : 0x%04x",
-                       tvb_get_ntohs(tvb, offset+2+id_length+2+4));
-
-               length -= 2+id_length+2+4+2;
-               offset += 2+id_length+2+4+2;
-       }
-
-}
-
-
-/*
- * Name: isis_dissect_isis_csnp()
- *
- * Description:
- *     Tear apart a L1 or L2 CSNP header and then call into payload dissect
- *     to pull apart the lsp id payload.
- *
- * Input:
- *     tvbuff_t * : tvbuffer for packet data
- *     proto_tree * : protocol display tree to add to.  May be NULL.
- *     int offset : our offset into packet data.
- *     int : type (l1 csnp, l2 csnp)
- *     int : header length of packet.
- *     int : length of IDs in packet.
- *
- * Output:
- *      void, but we will add to proto tree if !NULL.
- */
-void
-isis_dissect_isis_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
-       int type, int header_length, int id_length)
+dissect_isis_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
+       const isis_clv_handle_t *opts, int header_length, int id_length)
 {
        proto_item      *ti;
        proto_tree      *csnp_tree = NULL;
        guint16         pdu_length;
        int             len;
+       const guint8    *source_id;
+       gchar* system_id;
 
-       if (tree) {
-               ti = proto_tree_add_text(tree, tvb, offset, -1,
-                   PROTO_STRING_CSNP);
-               csnp_tree = proto_item_add_subtree(ti, ett_isis_csnp);
-       }
+       col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS CSNP");
+
+       ti = proto_tree_add_item(tree, proto_isis_csnp, tvb, offset, -1, ENC_NA);
+       csnp_tree = proto_item_add_subtree(ti, ett_isis_csnp);
 
        pdu_length = tvb_get_ntohs(tvb, offset);
-       if (tree) {
-               proto_tree_add_uint(csnp_tree, hf_isis_csnp_pdu_length, tvb,
+       proto_tree_add_uint(csnp_tree, hf_isis_csnp_pdu_length, tvb,
                        offset, 2, pdu_length);
-       }
        offset += 2;
 
-       if (tree) {
-               proto_tree_add_text(csnp_tree, tvb, offset, id_length + 1,
-                       "Source-ID:    %s",
-                               print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
-       }
-       col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s",
-                       print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
-
+       source_id = tvb_get_ptr(tvb, offset, id_length);
+       system_id = print_system_id( source_id, id_length );
+       proto_tree_add_bytes_format_value(csnp_tree, hf_isis_csnp_source_id, tvb,
+                                   offset, id_length, source_id,
+                                   "%s", system_id);
+       col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s", system_id);
        offset += id_length + 1;
 
-       proto_tree_add_text(csnp_tree, tvb, offset, id_length + 2, "Start LSP-ID: %s",
-                                    print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
-
-       col_append_fstr(pinfo->cinfo, COL_INFO, ", Start LSP-ID: %s",
-                       print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
-
+       source_id = tvb_get_ptr(tvb, offset, id_length+2);
+       system_id = print_system_id( source_id, id_length+2 );
+       proto_tree_add_bytes_format_value(csnp_tree, hf_isis_csnp_start_lsp_id, tvb,
+                                   offset, id_length + 2, source_id,
+                                   "%s", system_id);
+       col_append_fstr(pinfo->cinfo, COL_INFO, ", Start LSP-ID: %s", system_id);
        offset += id_length + 2;
 
-       proto_tree_add_text(csnp_tree, tvb, offset, id_length + 2, "End LSP-ID: %s",
-                                    print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
-
-       col_append_fstr(pinfo->cinfo, COL_INFO, ", End LSP-ID: %s",
-                       print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
-
+       source_id = tvb_get_ptr(tvb, offset, id_length+2);
+       system_id = print_system_id( source_id, id_length+2 );
+       proto_tree_add_bytes_format_value(csnp_tree, hf_isis_csnp_end_lsp_id, tvb,
+                                   offset, id_length + 2, source_id,
+                                   "%s", system_id);
+       col_append_fstr(pinfo->cinfo, COL_INFO, ", End LSP-ID: %s", system_id);
        offset += id_length + 2;
 
        len = pdu_length - header_length;
        if (len < 0) {
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_csnp_short_packet, tvb, offset, -1,
+                       "packet header length %d went beyond packet", header_length );
                return;
        }
-       /* Call into payload dissector */
-       if (type == ISIS_TYPE_L1_CSNP ) {
-               isis_dissect_clvs(tvb, csnp_tree, offset,
-                       clv_l1_csnp_opts, len, id_length,
-                       ett_isis_csnp_clv_unknown );
-       } else {
-               isis_dissect_clvs(tvb, csnp_tree, offset,
-                       clv_l2_csnp_opts, len, id_length,
-                       ett_isis_csnp_clv_unknown );
-       }
+       
+       isis_dissect_clvs(tvb, pinfo, csnp_tree, offset,
+                       opts, &ei_isis_csnp_short_packet, len, id_length, ett_isis_csnp_clv_unknown );
 }
 
-/*
- * Name: isis_dissect_isis_psnp()
- *
- * Description:
- *     Tear apart a L1 or L2 PSNP header and then call into payload dissect
- *     to pull apart the lsp id payload.
- *
- * Input:
- *     tvbuff_t * : tvbuffer for packet data
- *     proto_tree * : protocol display tree to add to.  May be NULL.
- *     int : our offset into packet data
- *     int : type (l1 psnp, l2 psnp)
- *     int : header length of packet.
- *     int : length of IDs in packet.
- *
- * Output:
- *      void, but we will add to proto tree if !NULL.
- */
-void
-isis_dissect_isis_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
-       int type, int header_length, int id_length)
+
+static int
+dissect_isis_l1_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+       isis_data_t* isis = (isis_data_t*)data;
+       dissect_isis_csnp(tvb, pinfo, tree, 0,
+               clv_l1_csnp_opts, isis->header_length, isis->system_id_len);
+       return tvb_length(tvb);
+}
+
+static int
+dissect_isis_l2_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+       isis_data_t* isis = (isis_data_t*)data;
+       dissect_isis_csnp(tvb, pinfo, tree, 0,
+               clv_l2_csnp_opts, isis->header_length, isis->system_id_len);
+       return tvb_length(tvb);
+}
+
+static void
+dissect_isis_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
+       const isis_clv_handle_t *opts, int header_length, int id_length)
 {
        proto_item      *ti;
-       proto_tree      *psnp_tree = NULL;
+       proto_tree      *psnp_tree;
        guint16         pdu_length;
        int             len;
+       const guint8    *source_id;
+       gchar* system_id;
 
-       if (tree) {
-               ti = proto_tree_add_text(tree, tvb, offset, -1,
-                   PROTO_STRING_PSNP);
-               psnp_tree = proto_item_add_subtree(ti, ett_isis_psnp);
-       }
+       col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS PSNP");
+
+       ti = proto_tree_add_item(tree, proto_isis_psnp, tvb, offset, -1, ENC_NA);
+       psnp_tree = proto_item_add_subtree(ti, ett_isis_psnp);
 
        pdu_length = tvb_get_ntohs(tvb, offset);
-       if (tree) {
-               proto_tree_add_uint(psnp_tree, hf_isis_psnp_pdu_length, tvb,
+       proto_tree_add_uint(psnp_tree, hf_isis_psnp_pdu_length, tvb,
                        offset, 2, pdu_length);
-       }
        offset += 2;
 
-       proto_tree_add_text(psnp_tree, tvb, offset, id_length + 1, "Source-ID: %s",
-                       print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length + 1 ) );
-
-       col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s",
-                       print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
+       source_id = tvb_get_ptr(tvb, offset, id_length);
+       system_id = print_system_id( source_id, id_length );
+       proto_tree_add_bytes_format_value(psnp_tree, hf_isis_psnp_source_id, tvb,
+                                   offset, id_length, source_id,
+                                   "%s", system_id);
+       col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s", system_id);
 
        offset += id_length + 1;
 
        len = pdu_length - header_length;
        if (len < 0) {
-               isis_dissect_unknown(tvb, tree, offset,
-                       "packet header length %d went beyond packet",
-                       header_length );
+               proto_tree_add_expert_format(tree, pinfo, &ei_isis_psnp_long_packet, tvb, offset, -1,
+                       "packet header length %d went beyond packet", header_length );
                return;
        }
        /* Call into payload dissector */
-       if (type == ISIS_TYPE_L1_PSNP ) {
-               isis_dissect_clvs(tvb, psnp_tree, offset,
-                       clv_l1_psnp_opts, len, id_length,
-                       ett_isis_psnp_clv_unknown );
-       } else {
-               isis_dissect_clvs(tvb, psnp_tree, offset,
-                       clv_l2_psnp_opts, len, id_length,
-                       ett_isis_psnp_clv_unknown );
-       }
+       isis_dissect_clvs(tvb, pinfo, psnp_tree, offset,
+                       opts, &ei_isis_psnp_short_packet, len, id_length, ett_isis_psnp_clv_unknown );
 }
 
-/*
- * Name: dissect_snp_authentication_clv()
- *
- * Description:
- *     Decode for a snp packets authenticaion clv.
- *      Calls into the CLV common one.
- *
- * Input:
- *     tvbuff_t * : tvbuffer for packet data
- *     proto_tree * : proto tree to build on (may be null)
- *     int : current offset into packet data
- *     int : length of IDs in packet.
- *     int : length of this clv
- *
- * Output:
- *     void, will modify proto_tree if not null.
- */
-static void
-dissect_snp_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
-       int id_length _U_, int length)
+static int
+dissect_isis_l1_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
 {
-       isis_dissect_authentication_clv(tvb, tree, offset, length);
+       isis_data_t* isis = (isis_data_t*)data;
+       dissect_isis_psnp(tvb, pinfo, tree, 0,
+               clv_l1_psnp_opts, isis->header_length, isis->system_id_len);
+       return tvb_length(tvb);
 }
 
-/*
- * Name: dissect_snp_ip_authentication_clv()
- *
- * Description:
- *     Decode for a snp packets authenticaion clv.
- *      Calls into the CLV common one.
- *
- * Input:
- *     tvbuff_t * : tvbuffer for packet data
- *     proto_tree * : proto tree to build on (may be null)
- *     int : current offset into packet data
- *     int : length of IDs in packet.
- *     int : length of this clv
- *
- * Output:
- *     void, will modify proto_tree if not null.
- */
-static void
-dissect_snp_ip_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
-       int id_length _U_, int length)
+static int
+dissect_isis_l2_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
 {
-       isis_dissect_ip_authentication_clv(tvb, tree, offset, length);
+       isis_data_t* isis = (isis_data_t*)data;
+       dissect_isis_psnp(tvb, pinfo, tree, 0,
+               clv_l2_psnp_opts, isis->header_length, isis->system_id_len);
+       return tvb_length(tvb);
 }
 
-/*
- * Name: dissect_snp_checksum_clv()
- *
- * Description:
- *      dump and verify the optional checksum in TLV 12
- *
- * Input:
- *      tvbuff_t * : tvbuffer for packet data
- *      proto_tree * : protocol display tree to fill out.  May be NULL
- *      int : offset into packet data where we are.
- *      int : length of clv we are decoding
- *
- * Output:
- *      void, but we will add to proto tree if !NULL.
- */
-
-static void
-dissect_snp_checksum_clv(tvbuff_t *tvb,
-        proto_tree *tree, int offset, int id_length _U_, int length) {
-
-       guint16 pdu_length,checksum, cacl_checksum=0;
-
-       if (tree) {
-                if ( length != 2 ) {
-                        proto_tree_add_text ( tree, tvb, offset, length,
-                                              "incorrect checksum length (%u), should be (2)", length );
-                        return;
-                }
-
-               checksum = tvb_get_ntohs(tvb, offset);
-
-                /* the check_and_get_checksum() function needs to know how big
-                 * the packet is. we can either pass through the pdu-len through several layers
-                 * of dissectors and wrappers or extract the PDU length field from the PDU specific header
-                 * which is offseted 8 bytes (relative to the beginning of the IS-IS packet) in SNPs */
-
-               pdu_length = tvb_get_ntohs(tvb, 8);
-
-                /* unlike the LSP checksum verification which starts at an offset of 12 we start at offset 0*/
-               switch (check_and_get_checksum(tvb, 0, pdu_length, checksum, offset, &cacl_checksum))
-               {
-
-                       case NO_CKSUM :
-                                proto_tree_add_text ( tree, tvb, offset, length,
-                                                      "Checksum: 0x%04x [unused]", checksum);
-                               break;
-                       case DATA_MISSING :
-                               isis_dissect_unknown(tvb, tree, offset,
-                                                     "[packet length %d went beyond packet]",
-                                                     tvb_length(tvb));
-                       break;
-                       case CKSUM_NOT_OK :
-                                proto_tree_add_text ( tree, tvb, offset, length,
-                                                      "Checksum: 0x%04x [incorrect, should be 0x%04x]",
-                                                      checksum,
-                                                      cacl_checksum);
-                       break;
-                       case CKSUM_OK :
-                                proto_tree_add_text ( tree, tvb, offset, length,
-                                                      "Checksum: 0x%04x [correct]", checksum);
-                       break;
-                       default :
-                               g_message("'check_and_get_checksum' returned an invalid value");
-               }
-       }
-}
-
-/*
- * Name: isis_register_csnp()
- *
- * Description:
- *     Register our protocol sub-sets with protocol manager.
- *
- * Input:
- *     int : protocol index for the ISIS protocol
- *
- * Output:
- *     void
- */
 void
-isis_register_csnp(int proto_isis) {
+proto_register_isis_csnp(void)
+{
        static hf_register_info hf[] = {
                { &hf_isis_csnp_pdu_length,
                { "PDU length",         "isis.csnp.pdu_length", FT_UINT16,
                  BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_isis_csnp_source_id,
+               { "Source-ID", "isis.csnp.source_id",
+                       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_isis_csnp_start_lsp_id,
+               { "Start LSP-ID", "isis.csnp.start_lsp_id",
+                       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_isis_csnp_end_lsp_id,
+               { "End LSP-ID", "isis.csnp.end_lsp_id",
+                       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_isis_csnp_lsp_id,
+               { "LSP-ID", "isis.csnp.lsp_id",
+                       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_isis_csnp_lsp_seq_num,
+               { "LSP Sequence Number",                "isis.csnp.lsp_seq_num", FT_UINT32,
+                 BASE_HEX, NULL, 0x0, NULL, HFILL }},
+               { &hf_isis_csnp_lsp_remain_life,
+               { "Remaining Lifetime",         "isis.csnp.lsp_remain_life", FT_UINT16,
+                 BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_isis_csnp_lsp_checksum,
+               { "LSP checksum",               "isis.csnp.lsp_checksum", FT_UINT16,
+                 BASE_HEX, NULL, 0x0, NULL, HFILL }},
+               { &hf_isis_csnp_checksum,
+               { "Checksum",           "isis.csnp.checksum", FT_UINT16,
+                 BASE_HEX, NULL, 0x0, NULL, HFILL }},
        };
+
        static gint *ett[] = {
                &ett_isis_csnp,
                &ett_isis_csnp_clv_lsp_entries,
@@ -542,30 +474,41 @@ isis_register_csnp(int proto_isis) {
                &ett_isis_csnp_clv_unknown,
        };
 
-       proto_register_field_array(proto_isis, hf, array_length(hf));
+       static ei_register_info ei[] = {
+               { &ei_isis_csnp_short_packet, { "isis.csnp.short_packet", PI_MALFORMED, PI_ERROR, "Short packet", EXPFILL }},
+               { &ei_isis_csnp_long_packet, { "isis.csnp.long_packet", PI_MALFORMED, PI_ERROR, "Long packet", EXPFILL }},
+               { &ei_isis_csnp_authentication, { "isis.csnp.authentication.unknown", PI_PROTOCOL, PI_WARN, "Unknown authentication type", EXPFILL }},
+       };
+       expert_module_t* expert_isis_csnp;
+
+       /* Register the protocol name and description */
+       proto_isis_csnp = proto_register_protocol(PROTO_STRING_CSNP, "ISIS CSNP", "isis.csnp");
+
+       proto_register_field_array(proto_isis_csnp, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));
+       expert_isis_csnp = expert_register_protocol(proto_isis_csnp);
+       expert_register_field_array(expert_isis_csnp, ei, array_length(ei));
 }
 
+void
+proto_reg_handoff_isis_csnp(void)
+{
+       dissector_add_uint("isis.type", ISIS_TYPE_L1_CSNP, new_create_dissector_handle(dissect_isis_l1_csnp, proto_isis_csnp));
+       dissector_add_uint("isis.type", ISIS_TYPE_L2_CSNP, new_create_dissector_handle(dissect_isis_l2_csnp, proto_isis_csnp));
+}
 
-/*
- * Name: isis_register_psnp()
- *
- * Description:
- *     Register our protocol sub-sets with protocol manager.
- *
- * Input:
- *     int : protocol index for the ISIS protocol
- *
- * Output:
- *     void
- */
 void
-isis_register_psnp(int proto_isis) {
+proto_register_isis_psnp(void)
+{
        static hf_register_info hf[] = {
                { &hf_isis_psnp_pdu_length,
                { "PDU length",         "isis.psnp.pdu_length", FT_UINT16,
                  BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_isis_psnp_source_id,
+               { "Source-ID", "isis.psnp.source_id",
+                       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
        };
+
        static gint *ett[] = {
                &ett_isis_psnp,
                &ett_isis_psnp_clv_lsp_entries,
@@ -575,7 +518,24 @@ isis_register_psnp(int proto_isis) {
                &ett_isis_psnp_clv_checksum,
                &ett_isis_psnp_clv_unknown,
        };
+       static ei_register_info ei[] = {
+               { &ei_isis_psnp_long_packet, { "isis.psnp.long_packet", PI_MALFORMED, PI_ERROR, "Long packet", EXPFILL }},
+               { &ei_isis_psnp_short_packet, { "isis.psnp.short_packet", PI_MALFORMED, PI_ERROR, "Short packet", EXPFILL }},
+       };
+       expert_module_t* expert_isis_psnp;
 
-       proto_register_field_array(proto_isis, hf, array_length(hf));
+       /* Register the protocol name and description */
+       proto_isis_psnp = proto_register_protocol(PROTO_STRING_PSNP, "ISIS PSNP", "isis.psnp");
+
+       proto_register_field_array(proto_isis_psnp, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));
+       expert_isis_psnp = expert_register_protocol(proto_isis_psnp);
+       expert_register_field_array(expert_isis_psnp, ei, array_length(ei));
+}
+
+void
+proto_reg_handoff_isis_psnp(void)
+{
+       dissector_add_uint("isis.type", ISIS_TYPE_L1_PSNP, new_create_dissector_handle(dissect_isis_l1_psnp, proto_isis_psnp));
+       dissector_add_uint("isis.type", ISIS_TYPE_L2_PSNP, new_create_dissector_handle(dissect_isis_l2_psnp, proto_isis_psnp));
 }
diff --git a/epan/dissectors/packet-isis-snp.h b/epan/dissectors/packet-isis-snp.h
deleted file mode 100644 (file)
index e3a5efb..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* packet-isis-snp.h
- * Defines and such for CSNP, PSNP, and their payloads
- *
- * $Id$
- * Stuart Stanley <stuarts@mxmail.net>
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef _PACKET_ISIS_SNP_H
-#define _PACKET_ISIS_SNP_H
-
-/*
- * Published API functions.  NOTE, this are "local" API functions and
- * are only valid from with isis decodes.
- */
-extern void isis_dissect_isis_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-       int offset, int type, int header_length, int id_length);
-extern void isis_register_csnp(int proto_isis);
-extern void isis_dissect_isis_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-       int offset, int type, int header_length, int id_length);
-extern void isis_register_psnp(int proto_isis);
-
-#endif /* _PACKET_ISIS_CSNP_H */
index b7a7d96376441f75ecaaf76e25ea992f0cf08637..f60d8346bcb3ab1d29fbcc5439535a61bc19410e 100644 (file)
 
 #include <glib.h>
 #include <epan/packet.h>
+#include <epan/expert.h>
 #include <epan/nlpid.h>
 #include <epan/etypes.h>
 #include "packet-osi.h"
 #include "packet-isis.h"
-#include "packet-isis-lsp.h"
-#include "packet-isis-hello.h"
-#include "packet-isis-snp.h"
 
 void proto_register_isis(void);
 void proto_reg_handoff_isis(void);
 
+static dissector_table_t isis_dissector_table;
+
 /* isis base header */
 static int proto_isis               = -1;
 
@@ -47,12 +47,16 @@ static int hf_isis_header_length    = -1;
 static int hf_isis_version          = -1;
 static int hf_isis_system_id_length = -1;
 static int hf_isis_type             = -1;
+static int hf_isis_type_reserved    = -1;
 static int hf_isis_version2         = -1;
 static int hf_isis_reserved         = -1;
 static int hf_isis_max_area_adr     = -1;
 
 static gint ett_isis                = -1;
 
+static expert_field ei_isis_version = EI_INIT;
+static expert_field ei_isis_type = EI_INIT;
+
 static dissector_handle_t isis_handle;
 
 static const value_string isis_vals[] = {
@@ -67,194 +71,84 @@ static const value_string isis_vals[] = {
   { ISIS_TYPE_L2_PSNP,   "L2 PSNP"},
   { 0,                   NULL}      };
 
-/*
- * Name: isis_dissect_unknown()
- *
- * Description:
- *     There was some error in the protocol and we are in unknown space
- *     here.  Add a tree item to cover the error and go on.  Note
- *     that we make sure we don't go off the end of the bleedin packet here!
- *
- * Input
- *     tvbuff_t * : tvbuffer for packet data
- *     proto_tree * : tree of display data.  May be NULL.
- *     int : current offset into packet data
- *     char * : format text
- *     subsequent args : arguments to format
- *
- * Output:
- *     void (may modify proto tree)
- */
-void
-isis_dissect_unknown(tvbuff_t *tvb, proto_tree *tree, int offset,
-       const char *fmat, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmat);
-       proto_tree_add_text_valist(tree, tvb, offset, -1, fmat, ap);
-       va_end(ap);
-}
-
-/*
- * Name: dissect_isis()
- *
- * Description:
- *     Main entry area for isis de-mangling.  This will build the
- *     main isis tree data and call the sub-protocols as needed.
- *
- * Input:
- *     tvbuff_t * : tvbuffer for packet data
- *     packet_info * : info for current packet
- *     proto_tree * : tree of display data.  May be NULL.
- *
- * Output:
- *     void, but we will add to the proto_tree if it is not NULL.
- */
 static void
 dissect_isis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
-       proto_item *ti;
+       proto_item *ti, *version_item;
        proto_tree *isis_tree = NULL;
        int offset = 0;
        guint8 isis_version;
-       guint8 isis_header_length;
-       guint8 isis_type_reserved;
        guint8 isis_type;
-       guint8 isis_system_id_len;
+       tvbuff_t *next_tvb;
+       isis_data_t subdissector_data;
 
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS");
        col_clear(pinfo->cinfo, COL_INFO);
 
-       isis_version = tvb_get_guint8(tvb, 2);
-       if (isis_version != ISIS_REQUIRED_VERSION){
-               col_add_fstr(pinfo->cinfo, COL_INFO,
-                               "Unknown ISIS version (%u vs %u)",
-                               isis_version, ISIS_REQUIRED_VERSION );
-               isis_dissect_unknown(tvb, tree, 0,
-                       "Unknown ISIS version (%d vs %d)",
-                       isis_version, ISIS_REQUIRED_VERSION);
-               return;
-       }
-
        ti = proto_tree_add_item(tree, proto_isis, tvb, 0, -1, ENC_NA);
        isis_tree = proto_item_add_subtree(ti, ett_isis);
 
-       if (tree) {
-               proto_tree_add_item(isis_tree, hf_isis_irpd, tvb, offset, 1,
-                       ENC_BIG_ENDIAN );
-       }
+       proto_tree_add_item(isis_tree, hf_isis_irpd, tvb, offset, 1, ENC_BIG_ENDIAN );
        offset += 1;
 
-       isis_header_length = tvb_get_guint8(tvb, offset);
-       if (tree) {
-               proto_tree_add_uint(isis_tree, hf_isis_header_length, tvb,
-                       offset, 1, isis_header_length );
-       }
+       subdissector_data.header_length = tvb_get_guint8(tvb, offset);
+       proto_tree_add_uint(isis_tree, hf_isis_header_length, tvb,
+                       offset, 1, subdissector_data.header_length );
        offset += 1;
 
-       if (tree) {
-               proto_tree_add_uint(isis_tree, hf_isis_version, tvb,
+       isis_version = tvb_get_guint8(tvb, offset);
+       version_item = proto_tree_add_uint(isis_tree, hf_isis_version, tvb,
                        offset, 1, isis_version );
+       if (isis_version != ISIS_REQUIRED_VERSION){
+               col_add_fstr(pinfo->cinfo, COL_INFO,
+                               "Unknown ISIS version (%u vs %u)",
+                               isis_version, ISIS_REQUIRED_VERSION );
+               expert_add_info(pinfo, version_item, &ei_isis_version);
+               return;
        }
        offset += 1;
 
-       isis_system_id_len = tvb_get_guint8(tvb, offset);
-       if (tree) {
-               proto_tree_add_uint(isis_tree, hf_isis_system_id_length, tvb,
-                       offset, 1, isis_system_id_len );
-       }
+       subdissector_data.system_id_len = tvb_get_guint8(tvb, offset);
+       proto_tree_add_uint(isis_tree, hf_isis_system_id_length, tvb,
+                       offset, 1, subdissector_data.system_id_len );
        offset += 1;
 
-       isis_type_reserved = tvb_get_guint8(tvb, offset);
-       isis_type = isis_type_reserved & ISIS_TYPE_MASK;
+       isis_type = tvb_get_guint8(tvb, offset) & ISIS_TYPE_MASK;
        col_add_str(pinfo->cinfo, COL_INFO,
                        val_to_str ( isis_type, isis_vals, "Unknown (0x%x)" ) );
 
-       proto_tree_add_uint_format(isis_tree, hf_isis_type, tvb,
-                       offset, 1, isis_type,
-                       "PDU Type           : %s (R:%s%s%s)",
-                       val_to_str(isis_type, isis_vals, "Unknown (0x%x)"),
-                       (isis_type_reserved & ISIS_R8_MASK) ? "1" : "0",
-                       (isis_type_reserved & ISIS_R7_MASK) ? "1" : "0",
-                       (isis_type_reserved & ISIS_R6_MASK) ? "1" : "0");
-
+       proto_tree_add_item(isis_tree, hf_isis_type, tvb, offset, 1, ENC_BIG_ENDIAN );
+       proto_tree_add_item(isis_tree, hf_isis_type_reserved, tvb, offset, 1, ENC_BIG_ENDIAN );
        offset += 1;
 
-       if (tree) {
-               proto_tree_add_item(isis_tree, hf_isis_version2, tvb, offset, 1,
-                       ENC_BIG_ENDIAN );
-       }
+       proto_tree_add_item(isis_tree, hf_isis_version2, tvb, offset, 1, ENC_BIG_ENDIAN );
        offset += 1;
 
-       if (tree) {
-               proto_tree_add_item(isis_tree, hf_isis_reserved, tvb, offset, 1,
-                       ENC_BIG_ENDIAN );
-       }
+       proto_tree_add_item(isis_tree, hf_isis_reserved, tvb, offset, 1, ENC_BIG_ENDIAN );
        offset += 1;
 
-       if (tree) {
-               proto_tree_add_item(isis_tree, hf_isis_max_area_adr, tvb, offset, 1,
-                       ENC_BIG_ENDIAN );
-       }
+       proto_tree_add_item(isis_tree, hf_isis_max_area_adr, tvb, offset, 1, ENC_BIG_ENDIAN );
        offset += 1;
 
        /*
         * Interpret the system ID length.
         */
-       if (isis_system_id_len == 0)
-               isis_system_id_len = 6; /* zero means 6-octet ID field length */
-       else if (isis_system_id_len == 255) {
-               isis_system_id_len = 0; /* 255 means null ID field */
+       if (subdissector_data.system_id_len == 0)
+               subdissector_data.system_id_len = 6;    /* zero means 6-octet ID field length */
+       else if (subdissector_data.system_id_len == 255) {
+               subdissector_data.system_id_len = 0;    /* 255 means null ID field */
                /* XXX - what about the LAN ID? */
        }
        /* XXX - otherwise, must be in the range 1 through 8 */
 
-       switch (isis_type) {
-       case ISIS_TYPE_L1_HELLO:
-       case ISIS_TYPE_L2_HELLO:
-       case ISIS_TYPE_PTP_HELLO:
-               isis_dissect_isis_hello(tvb, pinfo, isis_tree, offset,
-                       isis_type, isis_header_length, isis_system_id_len);
-               break;
-       case ISIS_TYPE_L1_LSP:
-       case ISIS_TYPE_L2_LSP:
-               isis_dissect_isis_lsp(tvb, pinfo, isis_tree, offset,
-                       isis_type, isis_header_length, isis_system_id_len);
-               break;
-       case ISIS_TYPE_L1_CSNP:
-       case ISIS_TYPE_L2_CSNP:
-               isis_dissect_isis_csnp(tvb, pinfo, isis_tree, offset,
-                       isis_type, isis_header_length, isis_system_id_len);
-               break;
-       case ISIS_TYPE_L1_PSNP:
-       case ISIS_TYPE_L2_PSNP:
-               isis_dissect_isis_psnp(tvb, pinfo, isis_tree, offset,
-                       isis_type, isis_header_length, isis_system_id_len);
-               break;
-       default:
-               isis_dissect_unknown(tvb, tree, offset,
-                       "Unknown ISIS packet type");
+       next_tvb = tvb_new_subset_remaining(tvb, offset);
+       if (!dissector_try_uint_new(isis_dissector_table, isis_type, next_tvb,
+                                                               pinfo, tree, TRUE, &subdissector_data))
+       {
+               proto_tree_add_expert(tree, pinfo, &ei_isis_type, tvb, offset, -1);
        }
 } /* dissect_isis */
 
-
-/*
- * Name: proto_register_isis()
- *
- * Description:
- *     main register for isis protocol set.  We register some display
- *     formats and the protocol module variables.
- *
- *     NOTE: this procedure to autolinked by the makefile process that
- *     builds register.c
- *
- * Input:
- *     void
- *
- * Output:
- *     void
- */
 void
 proto_register_isis(void)
 {
@@ -267,7 +161,7 @@ proto_register_isis(void)
       { "PDU Header Length", "isis.len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
 
     { &hf_isis_version,
-      { "Version (==1)", "isis.version", FT_UINT8,
+      { "Version", "isis.version", FT_UINT8,
          BASE_DEC, NULL, 0x0, NULL, HFILL }},
 
     { &hf_isis_system_id_length,
@@ -276,7 +170,11 @@ proto_register_isis(void)
 
     { &hf_isis_type,
       { "PDU Type", "isis.type", FT_UINT8, BASE_DEC,
-        VALS(isis_vals), 0xff, NULL, HFILL }},
+        VALS(isis_vals), ISIS_TYPE_MASK, NULL, HFILL }},
+
+    { &hf_isis_type_reserved,
+      { "Reserved", "isis.reserved", FT_UINT8, BASE_HEX,
+        NULL, ISIS_TYPE_RESERVED_MASK, NULL, HFILL }},
 
     { &hf_isis_version2,
       { "Version2 (==1)", "isis.version2", FT_UINT8, BASE_DEC, NULL,
@@ -299,20 +197,23 @@ proto_register_isis(void)
       &ett_isis,
     };
 
-    proto_isis = proto_register_protocol(PROTO_STRING_ISIS, "ISIS", "isis");
-    proto_register_field_array(proto_isis, hf, array_length(hf));
-    proto_register_subtree_array(ett, array_length(ett));
+       static ei_register_info ei[] = {
+               { &ei_isis_version, { "isis.version.unknown", PI_PROTOCOL, PI_WARN, "Unknown ISIS version", EXPFILL }},
+               { &ei_isis_type, { "isis.type.unknown", PI_PROTOCOL, PI_WARN, "Unknown ISIS packet type", EXPFILL }},
+       };
 
-    isis_handle = register_dissector("isis", dissect_isis, proto_isis);
+       expert_module_t* expert_isis;
 
-    /*
-     * Call registration routines for other source files in the ISIS
-     * dissector.
-     */
-    isis_register_hello(proto_isis);
-    isis_register_lsp(proto_isis);
-    isis_register_csnp(proto_isis);
-    isis_register_psnp(proto_isis);
+       proto_isis = proto_register_protocol(PROTO_STRING_ISIS, "ISIS", "isis");
+       proto_register_field_array(proto_isis, hf, array_length(hf));
+       proto_register_subtree_array(ett, array_length(ett));
+       expert_isis = expert_register_protocol(proto_isis);
+       expert_register_field_array(expert_isis, ei, array_length(ei));
+
+       isis_handle = register_dissector("isis", dissect_isis, proto_isis);
+
+       isis_dissector_table = register_dissector_table("isis.type",
+                                                               "ISIS Type", FT_UINT8, BASE_DEC);
 }
 
 void
index 5dc2a0b9a86ef9fb5653f31c8467ef42c481b88c..43904e4bb37370315c9aa5c1af0df0d2f31d19be 100644 (file)
 #define ISIS_TYPE_L1_PSNP   26
 #define ISIS_TYPE_L2_PSNP   27
 
-#define ISIS_TYPE_MASK             0x1f
-#define ISIS_R8_MASK       0x80
-#define ISIS_R7_MASK       0x40
-#define ISIS_R6_MASK       0x20
+#define ISIS_TYPE_MASK                 0x1f
+#define ISIS_TYPE_RESERVED_MASK 0xe0
 
 /*
- * published API functions
+ * Data given to subdissectors
  */
-
-extern char *isis_address_to_string(tvbuff_t *tvb, int offset, int len);
-extern void isis_dissect_unknown(tvbuff_t *tvb, proto_tree *tree, int offset,
-       const char *fmat, ...);
+typedef struct isis_data {
+       guint8 header_length;
+       guint8 system_id_len;
+} isis_data_t;
 
 #endif /* _PACKET_ISIS_H */
index 137499205fb42e24238e40a270d8de493c70b1b6..03210e32f19266396519a0a31e3f4fd0f21c7323 100644 (file)
 
 #include <glib.h>
 #include <epan/packet.h>
+#include <epan/expert.h>
 #include <epan/nlpid.h>
 #include "packet-osi.h"
 #include "packet-isis.h"
 #include "packet-isis-clv.h"
-#include "packet-isis-hello.h"
-#include "packet-isis-lsp.h"
-#include "packet-isis-snp.h"
 #include "packet-esis.h"
 #include "packet-osi-options.h"