From Ronald Henderson: make "format_text()", on Windows, escape all
[obnox/wireshark/wip.git] / packet-llc.c
index befa82067bcf064f4e6dadad65b4d6bc91240665..ec29413a01d7b5e98a3ba374e5fd2d703352839d 100644 (file)
@@ -2,22 +2,22 @@
  * Routines for IEEE 802.2 LLC layer
  * Gilbert Ramirez <gram@alumni.rice.edu>
  *
- * $Id: packet-llc.c,v 1.94 2002/01/20 22:12:26 guy Exp $
+ * $Id: packet-llc.c,v 1.105 2002/12/10 02:49:31 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 # include "config.h"
 #endif
 
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
 #include <glib.h>
-#include "packet.h"
+#include <epan/packet.h>
 #include "oui.h"
 #include "xdlc.h"
 #include "etypes.h"
 #include "llcsaps.h"
 #include "bridged_pids.h"
+#include "ppptypes.h"
+#include "packet-fc.h"
 #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"
 
+#define UDP_PORT_LLC1   12000
+#define UDP_PORT_LLC2   12001
+#define UDP_PORT_LLC3   12002
+#define UDP_PORT_LLC4   12003
+#define UDP_PORT_LLC5   12004
+
 static int proto_llc = -1;
 static int hf_llc_dsap = -1;
 static int hf_llc_ssap = -1;
@@ -67,17 +71,6 @@ static dissector_handle_t fddi_handle;
 static dissector_handle_t tr_handle;
 static dissector_handle_t data_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;
-};
-
 /*
  * Group/Individual bit, in the DSAP.
  */
@@ -110,7 +103,7 @@ struct sap_info {
  * IBM SNA Path Control, IBM Net Management), but, whilst 0xFE is
  * the ISO Network Layer Protocol, 0xFF is the Global LSAP.
  */
-static const value_string sap_vals[] = {
+const value_string sap_vals[] = {
        { SAP_NULL,           "NULL LSAP" },
        { SAP_LLC_SLMGMT,     "LLC Sub-Layer Management" },
        { SAP_SNA_PATHCTRL,   "SNA Path Control" },
@@ -128,6 +121,7 @@ static const value_string sap_vals[] = {
         */
        { 0x7F,               "ISO 802.2" },
        { SAP_XNS,            "XNS" },
+       { SAP_BACNET,         "BACnet" },
        { SAP_NESTAR,         "Nestar" },
        { SAP_PROWAY_ASLM,    "PROWAY (IEC955) Active Station List Maintenance" },
        { SAP_ARP,            "ARP" },  /* XXX - hand to "dissect_arp()"? */
@@ -145,13 +139,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
  *
@@ -174,31 +161,14 @@ 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) {
+capture_llc(const guchar *pd, int offset, int len, packet_counts *ld) {
 
        int             is_snap;
        guint16         control;
        int             llc_header_len;
        guint32         oui;
        guint16         etype;
-       capture_func_t  *capture;
 
        if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
                ld->other++;
@@ -213,8 +183,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 */
@@ -251,19 +220,28 @@ capture_llc(const u_char *pd, int offset, int len, packet_counts *ld) {
                                break;
                        }
                }
-       }               
+       }
        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;
                        }
                }
        }
@@ -291,18 +269,18 @@ dissect_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        if (tree) {
                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, 
+               proto_tree_add_uint(llc_tree, hf_llc_dsap, tvb, 0,
                        1, dsap & SAP_MASK);
-               proto_tree_add_boolean(llc_tree, hf_llc_dsap_ig, tvb, 0, 
+               proto_tree_add_boolean(llc_tree, hf_llc_dsap_ig, tvb, 0,
                        1, dsap & DSAP_GI_BIT);
        } else
                llc_tree = NULL;
 
        ssap = tvb_get_guint8(tvb, 1);
        if (tree) {
-               proto_tree_add_uint(llc_tree, hf_llc_ssap, tvb, 1, 
+               proto_tree_add_uint(llc_tree, hf_llc_ssap, tvb, 1,
                        1, ssap & SAP_MASK);
-               proto_tree_add_boolean(llc_tree, hf_llc_ssap_cr, tvb, 1, 
+               proto_tree_add_boolean(llc_tree, hf_llc_ssap_cr, tvb, 1,
                        1, ssap & SSAP_CR_BIT);
        } else
                llc_tree = NULL;
@@ -332,7 +310,7 @@ dissect_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        }
        else {
                if (check_col(pinfo->cinfo, COL_INFO)) {
-                       col_append_fstr(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 ?
@@ -458,7 +436,7 @@ dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
                        break;
                }
                break;
-               
+
        case OUI_CISCO:
                /* So are all CDP packets LLC packets
                   with an OUI of OUI_CISCO and a
@@ -508,36 +486,36 @@ proto_register_llc(void)
 
        static hf_register_info hf[] = {
                { &hf_llc_dsap,
-               { "DSAP",       "llc.dsap", FT_UINT8, BASE_HEX, 
+               { "DSAP",       "llc.dsap", FT_UINT8, BASE_HEX,
                        VALS(sap_vals), 0x0, "", HFILL }},
 
                { &hf_llc_dsap_ig,
-               { "IG Bit",     "llc.dsap.ig", FT_BOOLEAN, BASE_HEX, 
+               { "IG Bit",     "llc.dsap.ig", FT_BOOLEAN, BASE_HEX,
                        &ig_bit, 0x0, "Individual/Group", HFILL }},
 
                { &hf_llc_ssap,
-               { "SSAP", "llc.ssap", FT_UINT8, BASE_HEX, 
+               { "SSAP", "llc.ssap", FT_UINT8, BASE_HEX,
                        VALS(sap_vals), 0x0, "", HFILL }},
 
                { &hf_llc_ssap_cr,
-               { "CR Bit", "llc.ssap.cr", FT_BOOLEAN, BASE_HEX, 
+               { "CR Bit", "llc.ssap.cr", FT_BOOLEAN, BASE_HEX,
                        &cr_bit, 0x0, "Command/Response", HFILL }},
 
                { &hf_llc_ctrl,
-               { "Control", "llc.control", FT_UINT16, BASE_HEX, 
+               { "Control", "llc.control", FT_UINT16, BASE_HEX,
                        NULL, 0x0, "", HFILL }},
 
                /* registered here but handled in ethertype.c */
                { &hf_llc_type,
-               { "Type", "llc.type", FT_UINT16, BASE_HEX, 
+               { "Type", "llc.type", FT_UINT16, BASE_HEX,
                        VALS(etype_vals), 0x0, "", HFILL }},
 
                { &hf_llc_oui,
-               { "Organization Code",  "llc.oui", FT_UINT24, BASE_HEX, 
+               { "Organization Code",  "llc.oui", FT_UINT24, BASE_HEX,
                        VALS(oui_vals), 0x0, "", HFILL }},
 
                { &hf_llc_pid,
-               { "Protocol ID", "llc.pid", FT_UINT16, BASE_HEX, 
+               { "Protocol ID", "llc.pid", FT_UINT16, BASE_HEX,
                        NULL, 0x0, "", HFILL }}
        };
        static gint *ett[] = {
@@ -575,4 +553,14 @@ proto_reg_handoff_llc(void)
 
        llc_handle = find_dissector("llc");
        dissector_add("wtap_encap", WTAP_ENCAP_ATM_RFC1483, llc_handle);
+       /* RFC 2043 */
+       dissector_add("ppp.protocol", PPP_LLC, llc_handle);
+       /* RFC 2353 */
+       dissector_add("udp.port", UDP_PORT_LLC1, llc_handle);
+       dissector_add("udp.port", UDP_PORT_LLC2, llc_handle);
+       dissector_add("udp.port", UDP_PORT_LLC3, llc_handle);
+       dissector_add("udp.port", UDP_PORT_LLC4, llc_handle);
+       dissector_add("udp.port", UDP_PORT_LLC5, llc_handle);
+       /* IP-over-FC when we have the full FC frame */
+       dissector_add("fc.ftype", FC_FTYPE_IP, llc_handle);
 }