Use MAC address documentation range in filter examples
[metze/wireshark/wip.git] / epan / dissectors / packet-esis.c
index 44e5cda45d2937f3e8b1305e46e104ae3e5ef2d9..35142fb6e170ada90306497aeb85b99a4cbee112 100644 (file)
@@ -2,11 +2,10 @@
  * Routines for ISO/OSI End System to Intermediate System
  * Routing Exchange Protocol ISO 9542.
  *
- * $Id$
  * Ralf Schneider <Ralf.Schneider@t-online.de>
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * 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
  *
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
-#include <stdio.h>
-#include <string.h>
-#include <glib.h>
 #include <epan/packet.h>
-#include "nlpid.h"
+#include <epan/expert.h>
+#include <epan/nlpid.h>
 #include "packet-osi.h"
 #include "packet-osi-options.h"
-#include "packet-esis.h"
 
+/* The version we support is 1 */
+#define ESIS_REQUIRED_VERSION    1
+
+/* ESIS PDU types */
+#define ESIS_ESH_PDU    02
+#define ESIS_ISH_PDU    04
+#define ESIS_RD_PDU     06
+
+/* The length of the fixed part */
+#define ESIS_HDR_FIXED_LENGTH 9
+
+void proto_register_esis(void);
+void proto_reg_handoff_esis(void);
 
 /* esis base header */
 static int  proto_esis        = -1;
@@ -48,9 +55,27 @@ static int  hf_esis_reserved  = -1;
 static int  hf_esis_type      = -1;
 static int  hf_esis_holdtime  = -1;
 static int  hf_esis_checksum  = -1;
+/* Generated from convert_proto_tree_add_text.pl */
+static int hf_esis_dal = -1;
+static int hf_esis_number_of_source_addresses = -1;
+static int hf_esis_netl = -1;
+static int hf_esis_sal = -1;
+static int hf_esis_sa = -1;
+static int hf_esis_bsnpal = -1;
+static int hf_esis_net = -1;
+static int hf_esis_da = -1;
+static int hf_esis_bsnpa = -1;
 
 static gint ett_esis              = -1;
 static gint ett_esis_area_addr    = -1;
+static gint ett_esis_network      = -1;
+static gint ett_esis_dest_addr    = -1;
+static gint ett_esis_subnetwork   = -1;
+
+
+static expert_field ei_esis_version = EI_INIT;
+static expert_field ei_esis_length = EI_INIT;
+static expert_field ei_esis_type = EI_INIT;
 
 static const value_string esis_vals[] = {
   { ESIS_ESH_PDU, "ES HELLO"},
@@ -58,21 +83,12 @@ static const value_string esis_vals[] = {
   { ESIS_RD_PDU,  "RD REQUEST"},
   { 0,             NULL} };
 
-/* internal prototypes */
-
-static void esis_dissect_esh_pdu( guint8 len, tvbuff_t *tvb,
-                           proto_tree *treepd);
-static void esis_dissect_ish_pdu( guint8 len, tvbuff_t *tvb,
-                           proto_tree *tree);
-static void esis_dissect_redirect_pdu( guint8 len, tvbuff_t *tvb,
-                           proto_tree *tree);
-
 /* ################## Descriptions ###########################################*/
 /* Parameters for the ESH PDU
  * Source Address Parameter:
  *
  * Octet:    Length:   Parameter Type:
- *     10          1   Number of Source Adresses ( NSAPs served by this Network
+ *     10          1   Number of Source Addresses ( NSAPs served by this Network
  *     11          1   Source Address Length Indicator ( SAL )     #    Entity )
  * 12-m-1   variable   Source Address ( NSAP )
  *      m              Options, dissected in osi.c
@@ -116,143 +132,99 @@ static void esis_dissect_redirect_pdu( guint8 len, tvbuff_t *tvb,
 /* ############################ Tool Functions ############################## */
 
 
-/* ############################## Dissection Functions ###################### */
-/*
- * Name: dissect_esis_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!
- *
- *   This is just a copy of isis.c and isis.h, so I keep the stuff also
- *   and adapt the names to cover possible protocol errors! Ive really no
- *   idea wether I need this or not.
- *
- * Input
- *   tvbuff_t *      : tvbuff with packet data.
- *   proto_tree *    : tree of display data.  May be NULL.
- *   char *          : format text
- *   subsequent args : arguments to format
- *
- * Output:
- *   void (may modify proto tree)
- */
 static void
-esis_dissect_unknown( tvbuff_t *tvb, proto_tree *tree, char *fmat, ...){
-  va_list ap;
+esis_dissect_esh_pdu( guint8 len, tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo) {
+    proto_tree *esis_area_tree;
+    int         offset  = 0;
+    int         no_sa   = 0;
+    int         sal     = 0;
 
-  va_start(ap, fmat);
-  proto_tree_add_text_valist(tree, tvb, 0, -1, fmat, ap);
-  va_end(ap);
-}
+    proto_item  *ti;
 
-
-static void
-esis_dissect_esh_pdu( guint8 len, tvbuff_t *tvb, proto_tree *tree) {
-  proto_tree *esis_area_tree;
-  int         offset  = 0;
-  int         no_sa   = 0;
-  int         sal     = 0;
-
-  proto_item  *ti;
-
-  if (tree) {
     offset += ESIS_HDR_FIXED_LENGTH;
 
     no_sa  = tvb_get_guint8(tvb, offset);
     len   -= 1;
 
-    ti = proto_tree_add_text( tree, tvb, offset, -1,
-            "Number of Source Addresses (SA, Format: NSAP) : %u", no_sa );
+    ti = proto_tree_add_uint( tree, hf_esis_number_of_source_addresses, tvb, offset, 1, no_sa);
     offset++;
 
     esis_area_tree = proto_item_add_subtree( ti, ett_esis_area_addr );
     while ( no_sa-- > 0 ) {
-       sal = (int) tvb_get_guint8(tvb, offset);
-       proto_tree_add_text(esis_area_tree, tvb, offset, 1, "SAL: %2u Octets", sal);
-       offset++;
-       proto_tree_add_text(esis_area_tree, tvb, offset, sal,
-                           " SA: %s",
-                          print_nsap_net( tvb_get_ptr(tvb, offset, sal), sal ) );
-       offset += sal;
-       len    -= ( sal + 1 );
+      sal = (int) tvb_get_guint8(tvb, offset);
+      proto_tree_add_uint_format_value(esis_area_tree, hf_esis_sal, tvb, offset, 1, sal, "%2u Octets", sal);
+      offset++;
+      proto_tree_add_string(esis_area_tree, hf_esis_sa, tvb, offset, sal, print_nsap_net(tvb, offset, sal ) );
+      offset += sal;
+      len    -= ( sal + 1 );
     }
-    dissect_osi_options( len, tvb, offset, tree );
-  }
+    dissect_osi_options( len, tvb, offset, tree, pinfo );
+
 } /* esis_dissect_esh_pdu */
 
 static void
-esis_dissect_ish_pdu( guint8 len, tvbuff_t *tvb, proto_tree *tree) {
+esis_dissect_ish_pdu( guint8 len, tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo) {
 
-  int   offset  = 0;
-  int   netl    = 0;
+    int   offset  = 0;
+    int   netl    = 0;
+    proto_tree* network_tree;
 
-  if (tree) {
     offset += ESIS_HDR_FIXED_LENGTH;
 
     netl = (int) tvb_get_guint8(tvb, offset);
-    proto_tree_add_text( tree, tvb, offset, netl + 1,
+    network_tree = proto_tree_add_subtree( tree, tvb, offset, netl + 1, ett_esis_network, NULL,
                          "### Network Entity Title Section ###");
-    proto_tree_add_text( tree, tvb, offset++, 1, "NETL: %2u Octets", netl);
-    proto_tree_add_text( tree, tvb, offset, netl,
-                           " NET: %s",
-                          print_nsap_net( tvb_get_ptr(tvb, offset, netl), netl ) );
+    proto_tree_add_uint_format_value(network_tree, hf_esis_netl, tvb, offset++, 1, netl, "%2u Octets", netl);
+    proto_tree_add_string(network_tree, hf_esis_net, tvb, offset, netl, print_nsap_net( tvb, offset, netl ) );
     offset += netl;
     len    -= ( netl + 1 );
 
-    dissect_osi_options( len, tvb, offset, tree );
-  }
+    dissect_osi_options( len, tvb, offset, network_tree, pinfo );
 }
 
 static void
-esis_dissect_redirect_pdu( guint8 len, tvbuff_t *tvb, proto_tree *tree) {
+esis_dissect_redirect_pdu( guint8 len, tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo) {
 
-  int   offset  = 0;
-  int   tmpl    = 0;
+    int   offset  = 0;
+    int   tmpl    = 0;
+    proto_tree *dest_tree, *subnet_tree, *network_tree;
 
-  if (tree) {
     offset += ESIS_HDR_FIXED_LENGTH;
 
     tmpl = (int) tvb_get_guint8(tvb, offset);
-    proto_tree_add_text( tree, tvb, offset, tmpl + 1,
+    dest_tree = proto_tree_add_subtree( tree, tvb, offset, tmpl + 1, ett_esis_dest_addr, NULL,
                          "### Destination Address Section ###" );
-    proto_tree_add_text( tree, tvb, offset++, 1, "DAL: %2u Octets", tmpl);
-    proto_tree_add_text( tree, tvb, offset, tmpl,
-                         " DA : %s",
-                        print_nsap_net( tvb_get_ptr(tvb, offset, tmpl), tmpl ) );
+    proto_tree_add_uint_format_value(dest_tree, hf_esis_dal, tvb, offset++, 1, tmpl, "%2u Octets", tmpl);
+    proto_tree_add_string( dest_tree, hf_esis_da, tvb, offset, tmpl,
+                         print_nsap_net( tvb, offset, tmpl ) );
     offset += tmpl;
     len    -= ( tmpl + 1 );
     tmpl    = (int) tvb_get_guint8(tvb, offset);
 
-    proto_tree_add_text( tree, tvb, offset, tmpl + 1,
+    subnet_tree = proto_tree_add_subtree( tree, tvb, offset, tmpl + 1, ett_esis_subnetwork, NULL,
                          "###  Subnetwork Address Section ###");
-    proto_tree_add_text( tree, tvb, offset++, 1, "BSNPAL: %2u Octets", tmpl);
-    proto_tree_add_text( tree, tvb, offset, tmpl,
-                           " BSNPA: %s",
-                          print_system_id( tvb_get_ptr(tvb, offset, tmpl), tmpl ) );
+    proto_tree_add_uint_format_value(subnet_tree, hf_esis_bsnpal, tvb, offset++, 1, tmpl, "%2u Octets", tmpl);
+    proto_tree_add_item(subnet_tree, hf_esis_bsnpa, tvb, offset, tmpl, ENC_NA);
     offset += tmpl;
     len    -= ( tmpl + 1 );
     tmpl    = (int) tvb_get_guint8(tvb, offset);
 
     if ( 0 == tmpl ) {
-      proto_tree_add_text( tree, tvb, offset, 1,
+      network_tree = proto_tree_add_subtree( tree, tvb, offset, 1, ett_esis_network, NULL,
                            "### No Network Entity Title Section ###" );
       offset++;
       len--;
     }
     else {
-      proto_tree_add_text( tree, tvb, offset, 1,
+      network_tree = proto_tree_add_subtree( tree, tvb, offset, 1, ett_esis_network, NULL,
                            "### Network Entity Title Section ###" );
-      proto_tree_add_text( tree, tvb, offset++, 1, "NETL: %2u Octets", tmpl );
-      proto_tree_add_text( tree, tvb, offset, tmpl,
-                           " NET: %s",
-                          print_nsap_net( tvb_get_ptr(tvb, offset, tmpl), tmpl ) );
+      proto_tree_add_uint_format_value(network_tree, hf_esis_netl, tvb, offset++, 1, tmpl, "%2u Octets", tmpl );
+      proto_tree_add_string( network_tree, hf_esis_net, tvb, offset, tmpl,
+                           print_nsap_net( tvb, offset, tmpl ) );
       offset += tmpl;
       len    -= ( tmpl + 1 );
     }
-    dissect_osi_options( len, tvb, offset, tree );
-  }
+    dissect_osi_options( len, tvb, offset, network_tree, pinfo );
 }
 
 
@@ -273,121 +245,97 @@ esis_dissect_redirect_pdu( guint8 len, tvbuff_t *tvb, proto_tree *tree) {
  */
 static void
 dissect_esis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
-   const char *pdu_type_string        = NULL;
-   char       *pdu_type_format_string = "PDU Type      : %s (R:%s%s%s)";
-   esis_hdr_t  ehdr;
-   proto_item *ti;
-   proto_tree *esis_tree    = NULL;
-   guint8      variable_len;
-   guint       tmp_uint     = 0;
-   char       *cksum_status;
-
-   if (check_col(pinfo->cinfo, COL_PROTOCOL))
-     col_set_str(pinfo->cinfo, COL_PROTOCOL, "ESIS");
-   if (check_col(pinfo->cinfo, COL_INFO))
-     col_clear(pinfo->cinfo, COL_INFO);
-
-   tvb_memcpy(tvb, (guint8 *)&ehdr, 0, sizeof ehdr);
-
-   if (tree) {
-     ti = proto_tree_add_item(tree, proto_esis, tvb, 0, -1, FALSE);
-     esis_tree = proto_item_add_subtree(ti, ett_esis);
-
-     if (ehdr.esis_version != ESIS_REQUIRED_VERSION){
-       esis_dissect_unknown(tvb, esis_tree,
-                          "Unknown ESIS version (%u vs %u)",
-                           ehdr.esis_version, ESIS_REQUIRED_VERSION );
-       return;
-     }
-
-     if (ehdr.esis_length < ESIS_HDR_FIXED_LENGTH) {
-       esis_dissect_unknown(tvb, esis_tree,
-                          "Bogus ESIS length (%u, must be >= %u)",
-                           ehdr.esis_length, ESIS_HDR_FIXED_LENGTH );
-       return;
-     }
-     proto_tree_add_uint( esis_tree, hf_esis_nlpi, tvb, 0, 1, ehdr.esis_nlpi );
-     proto_tree_add_uint( esis_tree, hf_esis_length, tvb,
-                          1, 1, ehdr.esis_length );
-     proto_tree_add_uint( esis_tree, hf_esis_version, tvb, 2, 1,
-                          ehdr.esis_version );
-     proto_tree_add_uint( esis_tree, hf_esis_reserved, tvb, 3, 1,
-                          ehdr.esis_reserved );
-
-     pdu_type_string = val_to_str(ehdr.esis_type&OSI_PDU_TYPE_MASK,
-                                  esis_vals, "Unknown (0x%x)");
-
-     proto_tree_add_uint_format( esis_tree, hf_esis_type, tvb, 4, 1,
-                                 ehdr.esis_type,
-                                 pdu_type_format_string,
-                                 pdu_type_string,
-                                 (ehdr.esis_type&BIT_8) ? "1" : "0",
-                                 (ehdr.esis_type&BIT_7) ? "1" : "0",
-                                 (ehdr.esis_type&BIT_6) ? "1" : "0");
-
-     tmp_uint = pntohs( ehdr.esis_holdtime );
-     proto_tree_add_uint_format(esis_tree, hf_esis_holdtime, tvb, 5, 2,
-                                tmp_uint, "Holding Time  : %u seconds",
-                                tmp_uint );
-
-     tmp_uint = pntohs( ehdr.esis_checksum );
-
-     switch (calc_checksum( tvb, 0, ehdr.esis_length, tmp_uint )) {
-
-     case NO_CKSUM:
-       cksum_status = "Not Used";
-       break;
-
-     case DATA_MISSING:
-       cksum_status = "Not checkable - not all of packet was captured";
-       break;
-
-     case CKSUM_OK:
-       cksum_status = "Is good";
-       break;
-
-     case CKSUM_NOT_OK:
-       cksum_status = "Is wrong";
-       break;
-
-     default:
-       cksum_status = NULL;
-       DISSECTOR_ASSERT_NOT_REACHED();
-     }
-     proto_tree_add_uint_format( esis_tree, hf_esis_checksum, tvb, 7, 2,
-                                 tmp_uint, "Checksum      : 0x%x ( %s )",
-                                 tmp_uint, cksum_status );
-   }
-
-
-   /*
-    * Let us make sure we use the same names for all our decodes
-    * here.  First, dump the name into info column, and THEN
-    * dispatch the sub-type.
-    */
-   if (check_col(pinfo->cinfo, COL_INFO)) {
-     col_add_str(pinfo->cinfo, COL_INFO,
-                 val_to_str( ehdr.esis_type&OSI_PDU_TYPE_MASK, esis_vals,
-                             "Unknown (0x%x)" ) );
-   }
-
-   variable_len = ehdr.esis_length - ESIS_HDR_FIXED_LENGTH;
-
-   switch (ehdr.esis_type & OSI_PDU_TYPE_MASK) {
-     case ESIS_ESH_PDU:
-          esis_dissect_esh_pdu( variable_len, tvb, esis_tree);
-     break;
-     case ESIS_ISH_PDU:
-          esis_dissect_ish_pdu( variable_len, tvb, esis_tree);
-     break;
-     case ESIS_RD_PDU:
-          esis_dissect_redirect_pdu( variable_len, tvb, esis_tree);
-     break;
-     default:
-         esis_dissect_unknown(tvb, esis_tree,
-                             "Unknown ESIS packet type 0x%x",
-                             ehdr.esis_type & OSI_PDU_TYPE_MASK );
-   }
+  guint8 version, length;
+  proto_item *ti, *type_item;
+  proto_tree *esis_tree    = NULL;
+  guint8      variable_len, type;
+  guint16     holdtime, checksum;
+  const char *cksum_status;
+
+  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ESIS");
+  col_clear(pinfo->cinfo, COL_INFO);
+
+    ti = proto_tree_add_item(tree, proto_esis, tvb, 0, -1, ENC_NA);
+    esis_tree = proto_item_add_subtree(ti, ett_esis);
+
+    proto_tree_add_item( esis_tree, hf_esis_nlpi, tvb, 0, 1, ENC_BIG_ENDIAN);
+    ti = proto_tree_add_item( esis_tree, hf_esis_length, tvb, 1, 1, ENC_BIG_ENDIAN );
+    length = tvb_get_guint8(tvb, 1);
+    if (length < ESIS_HDR_FIXED_LENGTH) {
+      expert_add_info_format(pinfo, ti, &ei_esis_length,
+                           "Bogus ESIS length (%u, must be >= %u)",
+                           length, ESIS_HDR_FIXED_LENGTH );
+      return;
+    }
+
+    version = tvb_get_guint8(tvb, 2);
+    ti = proto_tree_add_item( esis_tree, hf_esis_version, tvb, 2, 1, ENC_BIG_ENDIAN);
+    if (version != ESIS_REQUIRED_VERSION){
+      expert_add_info_format(pinfo, ti, &ei_esis_version,
+                           "Unknown ESIS version (%u vs %u)",
+                           version, ESIS_REQUIRED_VERSION );
+    }
+
+    proto_tree_add_item( esis_tree, hf_esis_reserved, tvb, 3, 1, ENC_BIG_ENDIAN);
+
+    type_item = proto_tree_add_item( esis_tree, hf_esis_type, tvb, 4, 1, ENC_BIG_ENDIAN);
+    type = tvb_get_guint8(tvb, 4) & OSI_PDU_TYPE_MASK;
+
+    holdtime = tvb_get_ntohs(tvb, 5);
+    proto_tree_add_uint_format_value(esis_tree, hf_esis_holdtime, tvb, 5, 2,
+                               holdtime, "%u seconds", holdtime);
+
+    checksum = tvb_get_ntohs(tvb, 7);
+    switch (calc_checksum( tvb, 0, length, checksum)) {
+
+    case NO_CKSUM:
+      cksum_status = "Not Used";
+      break;
+
+    case DATA_MISSING:
+      cksum_status = "Not checkable - not all of packet was captured";
+      break;
+
+    case CKSUM_OK:
+      cksum_status = "Is good";
+      break;
+
+    case CKSUM_NOT_OK:
+      cksum_status = "Is wrong";
+      break;
+
+    default:
+      cksum_status = NULL;
+      DISSECTOR_ASSERT_NOT_REACHED();
+    }
+    proto_tree_add_uint_format_value( esis_tree, hf_esis_checksum, tvb, 7, 2,
+                                checksum, "0x%x ( %s )", checksum, cksum_status );
+
+
+  /*
+   * Let us make sure we use the same names for all our decodes
+   * here.  First, dump the name into info column, and THEN
+   * dispatch the sub-type.
+   */
+  col_add_str(pinfo->cinfo, COL_INFO,
+                val_to_str( type, esis_vals,
+                            "Unknown (0x%x)" ) );
+
+  variable_len = length - ESIS_HDR_FIXED_LENGTH;
+
+  switch (type) {
+  case ESIS_ESH_PDU:
+    esis_dissect_esh_pdu( variable_len, tvb, esis_tree, pinfo);
+    break;
+  case ESIS_ISH_PDU:
+    esis_dissect_ish_pdu( variable_len, tvb, esis_tree, pinfo);
+    break;
+  case ESIS_RD_PDU:
+    esis_dissect_redirect_pdu( variable_len, tvb, esis_tree, pinfo);
+    break;
+  default:
+    expert_add_info(pinfo, type_item, &ei_esis_type);
+  }
 } /* dissect_esis */
 
 
@@ -395,50 +343,77 @@ dissect_esis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
  * Name: proto_register_esis()
  *
  * Description:
- *     main register for esis protocol set.  We register some display
- *     formats and the protocol module variables.
+ *      main register for esis 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
+ *      NOTE: this procedure to autolinked by the makefile process that
+ *      builds register.c
  *
  * Input:
- *     void
+ *      void
  *
  * Output:
- *     void
+ *      void
  */
 void
 proto_register_esis(void) {
   static hf_register_info hf[] = {
     { &hf_esis_nlpi,
       { "Network Layer Protocol Identifier", "esis.nlpi",
-        FT_UINT8, BASE_HEX, VALS(nlpid_vals), 0x0, "", HFILL }},
+        FT_UINT8, BASE_HEX, VALS(nlpid_vals), 0x0, NULL, HFILL }},
+
     { &hf_esis_length,
-      { "PDU Length    ", "esis.length", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
+      { "PDU Length", "esis.length",  FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
     { &hf_esis_version,
-      { "Version (==1) ", "esis.ver",    FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
+      { "Version", "esis.ver",  FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
     { &hf_esis_reserved,
-      { "Reserved(==0) ", "esis.res",    FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
+      { "Reserved(==0)", "esis.res",  FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
     { &hf_esis_type,
-      { "PDU Type      ", "esis.type",   FT_UINT8, BASE_DEC, VALS(esis_vals),
-         0xff, "", HFILL }},
+      { "PDU Type", "esis.type",      FT_UINT8, BASE_DEC, VALS(esis_vals), OSI_PDU_TYPE_MASK, NULL, HFILL }},
+
     { &hf_esis_holdtime,
-      { "Holding Time  ", "esis.htime",  FT_UINT16, BASE_DEC, NULL, 0x0, " s", HFILL }},
+      { "Holding Time", "esis.htime", FT_UINT16, BASE_DEC, NULL, 0x0, "s", HFILL }},
+
     { &hf_esis_checksum,
-      { "Checksum      ", "esis.chksum", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}
+      { "Checksum", "esis.chksum",    FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+      /* Generated from convert_proto_tree_add_text.pl */
+      { &hf_esis_number_of_source_addresses, { "Number of Source Addresses (SA, Format: NSAP)", "esis.number_of_source_addresses", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_esis_sal, { "SAL", "esis.sal", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_esis_sa, { "SA", "esis.sa", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_esis_netl, { "NETL", "esis.netl", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_esis_dal, { "DAL", "esis.dal", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_esis_bsnpal, { "BSNPAL", "esis.bsnpal", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+      { &hf_esis_net, { "NET", "esis.net", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_esis_da, { "DA", "esis.da", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+      { &hf_esis_bsnpa, { "BSNPA", "esis.bsnpa", FT_SYSTEM_ID, BASE_NONE, NULL, 0x0, NULL, HFILL }},
   };
-  /*
-   *
-   *
-   */
+
   static gint *ett[] = {
     &ett_esis,
     &ett_esis_area_addr,
+    &ett_esis_network,
+    &ett_esis_dest_addr,
+    &ett_esis_subnetwork
+  };
+
+  static ei_register_info ei[] = {
+    { &ei_esis_version, { "esis.ver.unknown", PI_PROTOCOL, PI_WARN, "Unknown ESIS version", EXPFILL }},
+    { &ei_esis_length, { "esis.length.invalid", PI_MALFORMED, PI_ERROR, "Bogus ESIS length", EXPFILL }},
+    { &ei_esis_type, { "esis.type.unknown", PI_PROTOCOL, PI_WARN, "Unknown ESIS packet type", EXPFILL }},
   };
 
+  expert_module_t* expert_esis;
+
   proto_esis = proto_register_protocol( PROTO_STRING_ESIS, "ESIS", "esis");
   proto_register_field_array(proto_esis, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
+  expert_esis = expert_register_protocol(proto_esis);
+  expert_register_field_array(expert_esis, ei, array_length(ei));
+  register_dissector("esis", dissect_esis, proto_esis);
 }
 
 void
@@ -446,7 +421,19 @@ proto_reg_handoff_esis(void)
 {
   dissector_handle_t esis_handle;
 
-  esis_handle = create_dissector_handle(dissect_esis, proto_esis);
-  register_dissector("esis", dissect_esis, proto_esis);
-  dissector_add("osinl", NLPID_ISO9542_ESIS, esis_handle);
+  esis_handle = find_dissector("esis");
+  dissector_add_uint("osinl.incl", NLPID_ISO9542_ESIS, esis_handle);
 }
+
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local Variables:
+ * c-basic-offset: 2
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=2 tabstop=8 expandtab:
+ * :indentSize=2:tabSize=8:noTabs=true:
+ */