Show unknown AFP command codes in decimal in the summary line, as we
[obnox/wireshark/wip.git] / packet-llc.c
index 33df7f5ad1afe9b7e107ec9991a40006f3d7da72..fc48ab741fdffb9cfa44c039fa41b31b644cfee4 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for IEEE 802.2 LLC layer
  * Gilbert Ramirez <gram@alumni.rice.edu>
  *
- * $Id: packet-llc.c,v 1.89 2001/11/20 21:59:13 guy Exp $
+ * $Id: packet-llc.c,v 1.97 2002/04/24 06:03:34 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -32,7 +32,7 @@
 #endif
 
 #include <glib.h>
-#include "packet.h"
+#include <epan/packet.h>
 #include "oui.h"
 #include "xdlc.h"
 #include "etypes.h"
@@ -41,7 +41,7 @@
 #include "packet-ip.h"
 #include "packet-ipx.h"
 #include "packet-netbios.h"
-#include "sna-utils.h"
+#include <epan/sna-utils.h>
 
 #include "packet-llc.h"
 
@@ -65,17 +65,7 @@ static dissector_handle_t bpdu_handle;
 static dissector_handle_t eth_handle;
 static dissector_handle_t fddi_handle;
 static dissector_handle_t tr_handle;
-
-typedef void (capture_func_t)(const u_char *, int, int, packet_counts *);
-
-/* The SAP info is split into two tables, one value_string table and one
- * table of sap_info. This is so that the value_string can be used in the
- * header field registration.
- */
-struct sap_info {
-       guint8  sap;
-       capture_func_t *capture_func;
-};
+static dissector_handle_t data_handle;
 
 /*
  * Group/Individual bit, in the DSAP.
@@ -144,13 +134,6 @@ static const value_string sap_vals[] = {
        { 0x00,               NULL }
 };
 
-static struct sap_info saps[] = {
-       { SAP_IP,                       capture_ip },
-       { SAP_NETWARE,                  capture_ipx },
-       { SAP_NETBIOS,                  capture_netbios },
-       { 0x00,                         NULL}
-};
-
 /*
  * See
  *
@@ -173,22 +156,6 @@ http://www.cisco.com/univercd/cc/td/doc/product/software/ios113ed/113ed_cr/ibm_r
        { 0,               NULL }
 };
 
-static capture_func_t *
-sap_capture_func(u_char sap) {
-       int i=0;
-
-       /* look for the second record where sap == 0, which should
-        * be the last record
-        */
-       while (saps[i].sap > 0 || i == 0) {
-               if (saps[i].sap == sap) {
-                       return saps[i].capture_func;
-               }
-               i++;
-       }
-       return NULL;
-}
-
 void
 capture_llc(const u_char *pd, int offset, int len, packet_counts *ld) {
 
@@ -197,7 +164,6 @@ capture_llc(const u_char *pd, int offset, int len, packet_counts *ld) {
        int             llc_header_len;
        guint32         oui;
        guint16         etype;
-       capture_func_t  *capture;
 
        if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
                ld->other++;
@@ -212,8 +178,7 @@ capture_llc(const u_char *pd, int offset, int len, packet_counts *ld) {
         * uses extended operation, so we don't need to determine
         * whether it's basic or extended operation; is that the case?
         */
-       control = get_xdlc_control(pd, offset+2, pd[offset+1] & SSAP_CR_BIT,
-           TRUE);
+       control = get_xdlc_control(pd, offset+2, pd[offset+1] & SSAP_CR_BIT);
        llc_header_len += XDLC_CONTROL_LEN(control, TRUE);
        if (is_snap)
                llc_header_len += 5;    /* 3 bytes of OUI, 2 bytes of protocol ID */
@@ -252,17 +217,26 @@ capture_llc(const u_char *pd, int offset, int len, packet_counts *ld) {
                }
        }               
        else {
+               /* non-SNAP */
                if (XDLC_IS_INFORMATION(control)) {
-                       capture = sap_capture_func(pd[offset]);
+                       switch (pd[offset]) {
 
-                       /* non-SNAP */
-                       offset += llc_header_len;
+                       case SAP_IP:
+                               capture_ip(pd, offset + llc_header_len, len,
+                                   ld);
+                               break;
 
-                       if (capture) {
-                               capture(pd, offset, len, ld);
-                       }
-                       else {
+                       case SAP_NETWARE:
+                               capture_ipx(ld);
+                               break;
+
+                       case SAP_NETBIOS:
+                               capture_netbios(ld);
+                               break;
+
+                       default:
                                ld->other++;
+                               break;
                        }
                }
        }
@@ -279,16 +253,16 @@ dissect_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        guint8          dsap, ssap;
        tvbuff_t        *next_tvb;
 
-       if (check_col(pinfo->fd, COL_PROTOCOL)) {
-               col_set_str(pinfo->fd, COL_PROTOCOL, "LLC");
+       if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
+               col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLC");
        }
-       if (check_col(pinfo->fd, COL_INFO)) {
-               col_clear(pinfo->fd, COL_INFO);
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_clear(pinfo->cinfo, COL_INFO);
        }
 
        dsap = tvb_get_guint8(tvb, 0);
        if (tree) {
-               ti = proto_tree_add_item(tree, proto_llc, tvb, 0, 0, FALSE);
+               ti = proto_tree_add_item(tree, proto_llc, tvb, 0, -1, FALSE);
                llc_tree = proto_item_add_subtree(ti, ett_llc);
                proto_tree_add_uint(llc_tree, hf_llc_dsap, tvb, 0, 
                        1, dsap & SAP_MASK);
@@ -330,8 +304,8 @@ dissect_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                    hf_llc_oui, hf_llc_type, hf_llc_pid, 2);
        }
        else {
-               if (check_col(pinfo->fd, COL_INFO)) {
-                       col_append_fstr(pinfo->fd, COL_INFO, 
+               if (check_col(pinfo->cinfo, COL_INFO)) {
+                       col_append_fstr(pinfo->cinfo, COL_INFO, 
                            "; DSAP %s %s, SSAP %s %s",
                            val_to_str(dsap & SAP_MASK, sap_vals, "%02x"),
                            dsap & DSAP_GI_BIT ?
@@ -348,10 +322,10 @@ dissect_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                        /* do lookup with the subdissector table */
                        if (!dissector_try_port(subdissector_table, dsap,
                            next_tvb, pinfo, tree)) {
-                               dissect_data(next_tvb, 0, pinfo, tree);
+                               call_dissector(data_handle,next_tvb, pinfo, tree);
                        }
                } else {
-                       dissect_data(next_tvb, 0, pinfo, tree);
+                       call_dissector(data_handle,next_tvb, pinfo, tree);
                }
        }
 }
@@ -371,8 +345,8 @@ dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
        oui =   tvb_get_ntoh24(tvb, offset);
        etype = tvb_get_ntohs(tvb, offset+3);
 
-       if (check_col(pinfo->fd, COL_INFO)) {
-               col_append_fstr(pinfo->fd, COL_INFO,
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO,
                    "; SNAP, OUI 0x%06X (%s), PID 0x%04X",
                    oui, val_to_str(oui, oui_vals, "Unknown"), etype);
        }
@@ -397,7 +371,7 @@ dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
                            pinfo, tree, snap_tree, hf_type, -1);
                } else {
                        next_tvb = tvb_new_subset(tvb, offset+5, -1, -1);
-                       dissect_data(next_tvb, 0, pinfo, tree);
+                       call_dissector(data_handle,next_tvb, pinfo, tree);
                }
                break;
 
@@ -453,7 +427,7 @@ dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
 
                default:
                        next_tvb = tvb_new_subset(tvb, offset+5, -1, -1);
-                       dissect_data(next_tvb, 0, pinfo, tree);
+                       call_dissector(data_handle,next_tvb, pinfo, tree);
                        break;
                }
                break;
@@ -474,9 +448,9 @@ dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
                        /* for future reference, 0x0102 is Cisco DRIP */
                        if (!dissector_try_port(cisco_subdissector_table,
                            etype, next_tvb, pinfo, tree))
-                               dissect_data(next_tvb, 0, pinfo, tree);
+                               call_dissector(data_handle,next_tvb, pinfo, tree);
                } else
-                       dissect_data(next_tvb, 0, pinfo, tree);
+                       call_dissector(data_handle,next_tvb, pinfo, tree);
                break;
 
        case OUI_CABLE_BPDU:    /* DOCSIS cable modem spanning tree BPDU */
@@ -494,7 +468,7 @@ dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
                            etype);
                }
                next_tvb = tvb_new_subset(tvb, offset+5, -1, -1);
-               dissect_data(next_tvb, 0, pinfo, tree);
+               call_dissector(data_handle,next_tvb, pinfo, tree);
                break;
        }
 }
@@ -549,8 +523,10 @@ proto_register_llc(void)
        proto_register_subtree_array(ett, array_length(ett));
 
 /* subdissector code */
-       subdissector_table = register_dissector_table("llc.dsap");
-       cisco_subdissector_table = register_dissector_table("llc.cisco_pid");
+       subdissector_table = register_dissector_table("llc.dsap",
+         "LLC SAP", FT_UINT8, BASE_HEX);
+       cisco_subdissector_table = register_dissector_table("llc.cisco_pid",
+         "Cisco OUI PID", FT_UINT16, BASE_HEX);
 
        register_dissector("llc", dissect_llc, proto_llc);
 }
@@ -558,6 +534,8 @@ proto_register_llc(void)
 void
 proto_reg_handoff_llc(void)
 {
+       dissector_handle_t llc_handle;
+
        /*
         * Get handles for the BPDU, Ethernet, FDDI, and Token Ring
         * dissectors.
@@ -566,7 +544,8 @@ proto_reg_handoff_llc(void)
        eth_handle = find_dissector("eth");
        fddi_handle = find_dissector("fddi");
        tr_handle = find_dissector("tr");
+       data_handle = find_dissector("data");
 
-       dissector_add("wtap_encap", WTAP_ENCAP_ATM_RFC1483, dissect_llc,
-           proto_llc);
+       llc_handle = find_dissector("llc");
+       dissector_add("wtap_encap", WTAP_ENCAP_ATM_RFC1483, llc_handle);
 }