On Windows, include "capture-wpcap.h", to define "has_wpcap".
[obnox/wireshark/wip.git] / packet-lapd.c
index 68f0a4b0ae1a32a3baa8aea087dd8a07485c9896..e5a013756e2f9263b4bf527a641f5ac029f6074c 100644 (file)
@@ -1,13 +1,12 @@
 /* packet-lapd.c
  * Routines for LAPD frame disassembly
- * Gilbert Ramirez <gram@xiexie.org>
+ * Gilbert Ramirez <gram@alumni.rice.edu>
  *
- * $Id: packet-lapd.c,v 1.14 2000/09/21 04:41:07 gram Exp $
+ * $Id: packet-lapd.c,v 1.29 2002/02/22 08:54:54 guy Exp $
  *
  * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@zing.org>
+ * By Gerald Combs <gerald@ethereal.com>
  * Copyright 1998
- *
  * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -35,9 +34,7 @@
 #include <stdio.h>
 #include <glib.h>
 #include <string.h>
-#include "packet.h"
-#include "packet-lapd.h"
-#include "packet-q931.h"
+#include <epan/packet.h>
 #include "xdlc.h"
 
 /* ISDN/LAPD references:
@@ -60,6 +57,9 @@ static gint ett_lapd = -1;
 static gint ett_lapd_address = -1;
 static gint ett_lapd_control = -1;
 
+static dissector_handle_t q931_handle;
+static dissector_handle_t data_handle;
+
 /*
  * Bits in the address field.
  */
@@ -83,23 +83,21 @@ static const value_string lapd_sapi_vals[] = {
        { 0,                    NULL }
 };
 
-void
+static void
 dissect_lapd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
        proto_tree      *lapd_tree, *addr_tree;
-       proto_item      *ti;
+       proto_item      *lapd_ti, *addr_ti;
        guint16         control;
        int             lapd_header_len;
        guint16         address, cr, sapi;
        gboolean        is_response;
        tvbuff_t        *next_tvb;
 
-       CHECK_DISPLAY_AS_DATA(proto_lapd, tvb, pinfo, tree);
-
-       pinfo->current_proto = "LAPD";
-
-       if (check_col(pinfo->fd, COL_PROTOCOL))
-               col_add_str(pinfo->fd, COL_PROTOCOL, "LAPD");
+       if (check_col(pinfo->cinfo, COL_PROTOCOL))
+               col_set_str(pinfo->cinfo, COL_PROTOCOL, "LAPD");
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_clear(pinfo->cinfo, COL_INFO);
 
        address = tvb_get_ntohs(tvb, 0);
        cr = address & LAPD_CR;
@@ -108,26 +106,27 @@ dissect_lapd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
        if (pinfo->pseudo_header->p2p.sent) {
                is_response = cr ? TRUE : FALSE;
-               if(check_col(pinfo->fd, COL_RES_DL_DST))
-                       col_add_str(pinfo->fd, COL_RES_DL_DST, "Network");
-               if(check_col(pinfo->fd, COL_RES_DL_SRC))
-                       col_add_str(pinfo->fd, COL_RES_DL_SRC, "User");
+               if(check_col(pinfo->cinfo, COL_RES_DL_DST))
+                       col_set_str(pinfo->cinfo, COL_RES_DL_DST, "Network");
+               if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
+                       col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "User");
        }
        else {
                is_response = cr ? FALSE : TRUE;
-               if(check_col(pinfo->fd, COL_RES_DL_DST))
-                   col_add_str(pinfo->fd, COL_RES_DL_DST, "User");
-               if(check_col(pinfo->fd, COL_RES_DL_SRC))
-                   col_add_str(pinfo->fd, COL_RES_DL_SRC, "Network");
+               if(check_col(pinfo->cinfo, COL_RES_DL_DST))
+                   col_set_str(pinfo->cinfo, COL_RES_DL_DST, "User");
+               if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
+                   col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "Network");
        }
 
-
        if (tree) {
-               ti = proto_tree_add_item(tree, proto_lapd, tvb, 0, 3, FALSE);
-               lapd_tree = proto_item_add_subtree(ti, ett_lapd);
+               lapd_ti = proto_tree_add_item(tree, proto_lapd, tvb, 0, -1,
+                   FALSE);
+               lapd_tree = proto_item_add_subtree(lapd_ti, ett_lapd);
 
-               ti = proto_tree_add_uint(lapd_tree, hf_lapd_address, tvb, 0, 2, address);
-               addr_tree = proto_item_add_subtree(ti, ett_lapd_address);
+               addr_ti = proto_tree_add_uint(lapd_tree, hf_lapd_address, tvb,
+                   0, 2, address);
+               addr_tree = proto_item_add_subtree(addr_ti, ett_lapd_address);
 
                proto_tree_add_uint(addr_tree, hf_lapd_sapi,tvb, 0, 1, address);
                proto_tree_add_uint(addr_tree, hf_lapd_cr,  tvb, 0, 1, address);
@@ -136,6 +135,7 @@ dissect_lapd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                proto_tree_add_uint(addr_tree, hf_lapd_ea2, tvb, 1, 1, address);
        }
        else {
+               lapd_ti = NULL;
                lapd_tree = NULL;
        }
 
@@ -143,21 +143,24 @@ dissect_lapd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
            ett_lapd_control, is_response, TRUE);
        lapd_header_len += XDLC_CONTROL_LEN(control, TRUE);
 
+       if (tree)
+               proto_item_set_len(lapd_ti, lapd_header_len);
+
        next_tvb = tvb_new_subset(tvb, lapd_header_len, -1, -1);
        if (XDLC_IS_INFORMATION(control)) {
                /* call next protocol */
                switch (sapi) {
 
                case LAPD_SAPI_Q931:
-                       dissect_q931(next_tvb, pinfo, tree);
+                       call_dissector(q931_handle, next_tvb, pinfo, tree);
                        break;
 
                default:
-                       dissect_data(next_tvb, pinfo, tree);
+                       call_dissector(data_handle,next_tvb, pinfo, tree);
                        break;
                }
        } else
-               dissect_data(next_tvb, pinfo, tree);
+               call_dissector(data_handle,next_tvb, pinfo, tree);
 }
 
 void
@@ -166,31 +169,31 @@ proto_register_lapd(void)
     static hf_register_info hf[] = {
        { &hf_lapd_address,
          { "Address Field", "lapd.address", FT_UINT16, BASE_HEX, NULL, 0x0, 
-               "" }},
+               "Address", HFILL }},
 
        { &hf_lapd_sapi,
          { "SAPI", "lapd.sapi", FT_UINT16, BASE_DEC, VALS(lapd_sapi_vals), LAPD_SAPI,
-               "Service Access Point Identifier" }},
+               "Service Access Point Identifier", HFILL }},
 
        { &hf_lapd_cr,
          { "C/R", "lapd.cr", FT_UINT16, BASE_DEC, NULL, LAPD_CR,
-               "Command/Response bit" }},
+               "Command/Response bit", HFILL }},
 
        { &hf_lapd_ea1,
          { "EA1", "lapd.ea1", FT_UINT16, BASE_DEC, NULL, LAPD_EA1,
-               "First Address Extension bit" }},
+               "First Address Extension bit", HFILL }},
 
        { &hf_lapd_tei,
          { "TEI", "lapd.tei", FT_UINT16, BASE_DEC, NULL, LAPD_TEI,
-               "Terminal Endpoint Identifier" }},
+               "Terminal Endpoint Identifier", HFILL }},
 
        { &hf_lapd_ea2,
          { "EA2", "lapd.ea2", FT_UINT16, BASE_DEC, NULL, LAPD_EA2,
-               "Second Address Extension bit" }},
+               "Second Address Extension bit", HFILL }},
 
        { &hf_lapd_control,
          { "Control Field", "lapd.control", FT_UINT16, BASE_HEX, NULL, 0x0,
-               "" }},
+               "Control field", HFILL }},
     };
     static gint *ett[] = {
         &ett_lapd,
@@ -198,7 +201,23 @@ proto_register_lapd(void)
         &ett_lapd_control,
     };
 
-    proto_lapd = proto_register_protocol ("Link Access Procedure, Channel D (LAPD)", "lapd");
+    proto_lapd = proto_register_protocol("Link Access Procedure, Channel D (LAPD)",
+                                        "LAPD", "lapd");
     proto_register_field_array (proto_lapd, hf, array_length(hf));
     proto_register_subtree_array(ett, array_length(ett));
 }
+
+void
+proto_reg_handoff_lapd(void)
+{
+       dissector_handle_t lapd_handle;
+
+       /*
+        * Get handle for the Q.931 dissector.
+        */
+       q931_handle = find_dissector("q931");
+       data_handle = find_dissector("data");
+
+       lapd_handle = create_dissector_handle(dissect_lapd, proto_lapd);
+       dissector_add("wtap_encap", WTAP_ENCAP_LAPD, lapd_handle);
+}