Don't prime the display filter unless we're re-applying it; otherwise,
[obnox/wireshark/wip.git] / packet-vines.c
index 5b70badf7ed41755169431a7a0d61c067b7c8635..b383b738f1efa1d660c4347342702245ee5de8ab 100644 (file)
@@ -1,15 +1,14 @@
 /* packet-vines.c
  * Routines for Banyan VINES protocol packet disassembly
  *
- * $Id: packet-vines.c,v 1.22 2001/01/06 08:44:03 guy Exp $
+ * $Id: packet-vines.c,v 1.39 2002/01/21 07:36:44 guy Exp $
  *
  * Don Lafontaine <lafont02@cn.ca>
  *
  * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@zing.org>
+ * By Gerald Combs <gerald@ethereal.com>
  * Copyright 1998 Gerald Combs
- * Joerg Mayer <jmayer@telemation.de>
- *
+ * Joerg Mayer <jmayer@loplof.de>
  * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
 
 #include <string.h>
 #include <glib.h>
+#include <epan/packet.h>
+#include "packet-vines.h"
 #include "etypes.h"
 #include "ppptypes.h"
-#include "packet.h"
-#include "packet-vines.h"
-#include "packet-ip.h"
+#include "ipproto.h"
 
 #define UDP_PORT_VINES 573
 
@@ -72,11 +71,14 @@ static void dissect_vines_spp(tvbuff_t *, packet_info *, proto_tree *);
 static void dissect_vines(tvbuff_t *, packet_info *, proto_tree *);
 
 void
-capture_vines(const u_char *pd, int offset, packet_counts *ld)
+capture_vines(const u_char *pd, int offset, int len, packet_counts *ld)
 {
        ld->vines++;
 }
 
+static dissector_handle_t vines_handle;
+static dissector_handle_t data_handle;
+
 /* AFAIK Vines FRP (Fragmentation Protocol) is used on all media except
  * Ethernet and TR (and probably FDDI) - Fragmentation on these media types
  * is not possible
@@ -91,14 +93,10 @@ dissect_vines_frp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        gchar   frp_flags_str[32];
        tvbuff_t *next_tvb;
 
-       CHECK_DISPLAY_AS_DATA(proto_vines_frp, tvb, pinfo, tree);
-
-       pinfo->current_proto = "Vines FRP";
-
-       if (check_col(pinfo->fd, COL_PROTOCOL))
-               col_set_str(pinfo->fd, COL_PROTOCOL, "Vines FRP");
-       if (check_col(pinfo->fd, COL_INFO))
-               col_clear(pinfo->fd, COL_INFO);
+       if (check_col(pinfo->cinfo, COL_PROTOCOL))
+               col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines FRP");
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_clear(pinfo->cinfo, COL_INFO);
 
        if (tree) {
                ti = proto_tree_add_item(tree, proto_vines_frp, tvb, 0, 2,
@@ -146,7 +144,7 @@ dissect_vines_frp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
        /* Decode the "real" Vines now */
        next_tvb = tvb_new_subset(tvb, 2, -1, -1);
-       dissect_vines(tvb, pinfo, tree);
+       call_dissector(vines_handle, next_tvb, pinfo, tree);
 }
 
 void
@@ -164,30 +162,18 @@ proto_register_vines_frp(void)
 void
 proto_reg_handoff_vines_frp(void)
 {
-       dissector_add("ip.proto", IP_PROTO_VINES, dissect_vines_frp);
+       dissector_handle_t vines_frp_handle;
+
+       vines_frp_handle = create_dissector_handle(dissect_vines_frp,
+           proto_vines_frp);
+       dissector_add("ip.proto", IP_PROTO_VINES, vines_frp_handle);
 
        /* XXX: AFAIK, src and dst port must be the same; should
           the dissector check for that? */
-       dissector_add("udp.port", UDP_PORT_VINES, dissect_vines_frp);
+       dissector_add("udp.port", UDP_PORT_VINES, vines_frp_handle);
 }
 
-gchar *
-vines_addr_to_str(const guint8 *addrp)
-{
-  static gchar str[3][214];
-  static gchar *cur;
-
-  if (cur == &str[0][0]) {
-    cur = &str[1][0];
-  } else if (cur == &str[1][0]) {
-    cur = &str[2][0];
-  } else {
-    cur = &str[0][0];
-  }
-
-  sprintf(cur, "%08x.%04x", pntohl(&addrp[0]), pntohs(&addrp[4]));
-  return cur;
-}
+static dissector_table_t vines_dissector_table;
 
 static void
 dissect_vines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@@ -197,19 +183,15 @@ dissect_vines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        proto_tree *vip_tree;
        proto_item *ti;
 /*     gchar      tos_str[32]; */
-       guint8     *dst_addr, *src_addr;
+       const guint8     *dst_addr, *src_addr;
        int  is_broadcast = 0;
        int  hops = 0;
        tvbuff_t *next_tvb;
 
-       CHECK_DISPLAY_AS_DATA(proto_vines, tvb, pinfo, tree);
-
-       pinfo->current_proto = "Vines";
-
-       if (check_col(pinfo->fd, COL_PROTOCOL))
-               col_set_str(pinfo->fd, COL_PROTOCOL, "Vines");
-       if (check_col(pinfo->fd, COL_INFO))
-               col_clear(pinfo->fd, COL_INFO);
+       if (check_col(pinfo->cinfo, COL_PROTOCOL))
+               col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines");
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_clear(pinfo->cinfo, COL_INFO);
 
        /* To do: check for runts, errs, etc. */
 
@@ -225,40 +207,40 @@ dissect_vines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
        switch (viph.vip_proto) {
        case VIP_PROTO_IPC:
-               if (check_col(pinfo->fd, COL_PROTOCOL))
-                       col_set_str(pinfo->fd, COL_PROTOCOL, "Vines IPC");
-               if (check_col(pinfo->fd, COL_INFO))
-                       col_add_fstr(pinfo->fd, COL_INFO, "IPC (%02x)", viph.vip_proto);
+               if (check_col(pinfo->cinfo, COL_PROTOCOL))
+                       col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines IPC");
+               if (check_col(pinfo->cinfo, COL_INFO))
+                       col_add_fstr(pinfo->cinfo, COL_INFO, "IPC (%02x)", viph.vip_proto);
                break;
        case VIP_PROTO_SPP:      
-               if (check_col(pinfo->fd, COL_PROTOCOL))
-                       col_set_str(pinfo->fd, COL_PROTOCOL, "Vines SPP");
-               if (check_col(pinfo->fd, COL_INFO))
-                       col_add_fstr(pinfo->fd, COL_INFO, "SPP (%02x)", viph.vip_proto);
+               if (check_col(pinfo->cinfo, COL_PROTOCOL))
+                       col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines SPP");
+               if (check_col(pinfo->cinfo, COL_INFO))
+                       col_add_fstr(pinfo->cinfo, COL_INFO, "SPP (%02x)", viph.vip_proto);
                break;
        case VIP_PROTO_ARP:
-               if (check_col(pinfo->fd, COL_PROTOCOL))
-                       col_set_str(pinfo->fd, COL_PROTOCOL, "Vines ARP");
-               if (check_col(pinfo->fd, COL_INFO))
-                       col_add_fstr(pinfo->fd, COL_INFO, "ARP (%02x)", viph.vip_proto);
+               if (check_col(pinfo->cinfo, COL_PROTOCOL))
+                       col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines ARP");
+               if (check_col(pinfo->cinfo, COL_INFO))
+                       col_add_fstr(pinfo->cinfo, COL_INFO, "ARP (%02x)", viph.vip_proto);
                break;
        case VIP_PROTO_RTP:
-               if (check_col(pinfo->fd, COL_PROTOCOL))
-                       col_set_str(pinfo->fd, COL_PROTOCOL, "Vines RTP");
-               if (check_col(pinfo->fd, COL_INFO))
-                       col_add_fstr(pinfo->fd, COL_INFO, "RTP (%02x)", viph.vip_proto);
+               if (check_col(pinfo->cinfo, COL_PROTOCOL))
+                       col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines RTP");
+               if (check_col(pinfo->cinfo, COL_INFO))
+                       col_add_fstr(pinfo->cinfo, COL_INFO, "RTP (%02x)", viph.vip_proto);
                break;
        case VIP_PROTO_ICP:
-               if (check_col(pinfo->fd, COL_PROTOCOL))
-                       col_set_str(pinfo->fd, COL_PROTOCOL, "Vines ICP");
-               if (check_col(pinfo->fd, COL_INFO))
-                       col_add_fstr(pinfo->fd, COL_INFO, "ICP (%02x)", viph.vip_proto);
+               if (check_col(pinfo->cinfo, COL_PROTOCOL))
+                       col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines ICP");
+               if (check_col(pinfo->cinfo, COL_INFO))
+                       col_add_fstr(pinfo->cinfo, COL_INFO, "ICP (%02x)", viph.vip_proto);
                break;
        default:
-               if (check_col(pinfo->fd, COL_PROTOCOL))
-                       col_set_str(pinfo->fd, COL_PROTOCOL, "Vines IP");
-               if (check_col(pinfo->fd, COL_INFO))
-                       col_add_fstr(pinfo->fd, COL_INFO, "Unknown VIP protocol (%02x)", 
+               if (check_col(pinfo->cinfo, COL_PROTOCOL))
+                       col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines IP");
+               if (check_col(pinfo->cinfo, COL_INFO))
+                       col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown VIP protocol (%02x)", 
                                     viph.vip_proto);
        }
 
@@ -329,15 +311,10 @@ dissect_vines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        }
 
        offset += 18;
-       switch (viph.vip_proto) {
-       case VIP_PROTO_SPP:
-               next_tvb = tvb_new_subset(tvb, offset, -1, -1);
-               dissect_vines_spp(next_tvb, pinfo, tree);
-               break;
-       default:
-               dissect_data(tvb, offset, pinfo, tree);
-               break;
-       }
+       next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+       if (!dissector_try_port(vines_dissector_table, viph.vip_proto,
+           next_tvb, pinfo, tree))
+               call_dissector(data_handle,next_tvb, pinfo, tree);
 }
 
 void
@@ -351,19 +328,27 @@ proto_register_vines(void)
          { &hf_vines_protocol,
            { "Protocol",                       "vines.protocol",
              FT_UINT8,         BASE_HEX,       NULL,   0x0,
-             "Vines protocol" }}
+             "Vines protocol", HFILL }}
        };
 
        proto_vines = proto_register_protocol("Banyan Vines", "Vines", "vines");
        proto_register_field_array(proto_vines, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));
+
+       /* subdissector code */
+       vines_dissector_table = register_dissector_table("vines.proto",
+           "Vines protocol", FT_UINT8, BASE_HEX);
+
+       register_dissector("vines", dissect_vines, proto_vines);
+       vines_handle = find_dissector("vines");
 }
 
 void
 proto_reg_handoff_vines(void)
 {
-       dissector_add("ethertype", ETHERTYPE_VINES, dissect_vines);
-       dissector_add("ppp.protocol", PPP_VINES, dissect_vines);
+       dissector_add("ethertype", ETHERTYPE_VINES, vines_handle);
+       dissector_add("ppp.protocol", PPP_VINES, vines_handle);
+       data_handle = find_dissector("data");
 }
 
 static void
@@ -374,14 +359,10 @@ dissect_vines_spp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        proto_tree *vspp_tree;
        proto_item *ti;
 
-       CHECK_DISPLAY_AS_DATA(proto_vines_spp, tvb, pinfo, tree);
-
-       pinfo->current_proto = "Vines SPP";
-
-       if (check_col(pinfo->fd, COL_PROTOCOL))
-               col_set_str(pinfo->fd, COL_PROTOCOL, "VSPP");
-       if (check_col(pinfo->fd, COL_INFO))
-               col_clear(pinfo->fd, COL_INFO);
+       if (check_col(pinfo->cinfo, COL_PROTOCOL))
+               col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSPP");
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_clear(pinfo->cinfo, COL_INFO);
 
        /* To do: check for runts, errs, etc. */
 
@@ -395,28 +376,28 @@ dissect_vines_spp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
        switch (viph.vspp_pkttype) {
        case VSPP_PKTTYPE_DATA:      
-               if (check_col(pinfo->fd, COL_PROTOCOL))
-                       col_set_str(pinfo->fd, COL_PROTOCOL, "VSPP Data");
+               if (check_col(pinfo->cinfo, COL_PROTOCOL))
+                       col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSPP Data");
                break;
        case VSPP_PKTTYPE_DISC:      
-               if (check_col(pinfo->fd, COL_PROTOCOL))
-                       col_set_str(pinfo->fd, COL_PROTOCOL, "VSPP Disconnect");
+               if (check_col(pinfo->cinfo, COL_PROTOCOL))
+                       col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSPP Disconnect");
                break;
        case VSPP_PKTTYPE_PROBE:      
-               if (check_col(pinfo->fd, COL_PROTOCOL))
-                       col_set_str(pinfo->fd, COL_PROTOCOL, "VSPP Probe");
+               if (check_col(pinfo->cinfo, COL_PROTOCOL))
+                       col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSPP Probe");
                break;
        case VSPP_PKTTYPE_ACK:
-               if (check_col(pinfo->fd, COL_PROTOCOL))
-                       col_set_str(pinfo->fd, COL_PROTOCOL, "VSPP Ack");
+               if (check_col(pinfo->cinfo, COL_PROTOCOL))
+                       col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSPP Ack");
                break;
        default:
-               if (check_col(pinfo->fd, COL_PROTOCOL))
-                       col_set_str(pinfo->fd, COL_PROTOCOL, "VSPP Unknown");
+               if (check_col(pinfo->cinfo, COL_PROTOCOL))
+                       col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSPP Unknown");
        }
 
-       if (check_col(pinfo->fd, COL_INFO))
-               col_add_fstr(pinfo->fd, COL_INFO, 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_add_fstr(pinfo->cinfo, COL_INFO, 
                             "NS=%04x NR=%04x Window=%04x RID=%04x LID=%04x D=%04x S=%04x", 
                             viph.vspp_seqno, viph.vspp_ack, viph.vspp_win, 
                             viph.vspp_rmtid, viph.vspp_lclid, viph.vspp_dport,
@@ -474,7 +455,7 @@ dissect_vines_spp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                    "Window: 0x%04x", viph.vspp_win);
        }
        offset += 16; /* sizeof SPP */
-       dissect_data(tvb, offset, pinfo, tree);
+       call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,tvb_reported_length_remaining(tvb,offset)), pinfo, tree);
 }
 
 void
@@ -488,3 +469,13 @@ proto_register_vines_spp(void)
            "Vines SPP", "vines_spp");
        proto_register_subtree_array(ett, array_length(ett));
 }
+
+void
+proto_reg_handoff_vines_spp(void)
+{
+       dissector_handle_t vines_spp_handle;
+
+       vines_spp_handle = create_dissector_handle(dissect_vines_spp,
+           proto_vines_spp);
+       dissector_add("vines.proto", VIP_PROTO_SPP, vines_spp_handle);
+}