aboutsummaryrefslogtreecommitdiffstats
path: root/packet-lwapp.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2003-08-29 22:27:14 +0000
committerGuy Harris <guy@alum.mit.edu>2003-08-29 22:27:14 +0000
commita42fd8fa504d53c0ca5293f740b12c54bf9ec5a1 (patch)
treeec026ddb677d30ec7b7e6f45d1b5ae3d99874d72 /packet-lwapp.c
parentc8ea4075266853bf4b3b3eba5515e5e40cb61961 (diff)
From David Frascone: LWAPP support.
svn path=/trunk/; revision=8315
Diffstat (limited to 'packet-lwapp.c')
-rw-r--r--packet-lwapp.c558
1 files changed, 558 insertions, 0 deletions
diff --git a/packet-lwapp.c b/packet-lwapp.c
new file mode 100644
index 0000000000..5188892d8d
--- /dev/null
+++ b/packet-lwapp.c
@@ -0,0 +1,558 @@
+/* packet-lwapp.c
+ *
+ * Routines for LWAPP encapsulated packet disassembly
+ *
+ * $Id: packet-lwapp.c,v 1.1 2003/08/29 22:27:14 guy Exp $
+ *
+ * Copyright (c) 2003 by David Frascone <dave@frascone.com>
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <glib.h>
+#include <epan/filesystem.h>
+#include "xmlstub.h"
+#include <epan/packet.h>
+#include <epan/resolv.h>
+#include "prefs.h"
+
+
+#ifdef NEED_SNPRINTF_H
+# include "snprintf.h"
+#endif
+
+#define LWAPP_FLAGS_T 0x04
+#define LWAPP_FLAGS_F 0x02
+#define LWAPP_FLAGS_FT 0x01
+
+static gint proto_lwapp = -1;
+static gint proto_lwapp_l3 = -1;
+static gint proto_lwapp_control = -1;
+static gint ett_lwapp = -1;
+static gint ett_lwapp_l3 = -1;
+static gint ett_lwapp_flags = -1;
+static gint ett_lwapp_control = -1;
+
+static gint hf_lwapp_version = -1;
+static gint hf_lwapp_slotid = -1;
+static gint hf_lwapp_flags_type = -1;
+static gint hf_lwapp_flags_fragment = -1;
+static gint hf_lwapp_flags_fragment_type = -1;
+static gint hf_lwapp_fragment_id = -1;
+static gint hf_lwapp_length = -1;
+static gint hf_lwapp_rssi = -1;
+static gint hf_lwapp_snr = -1;
+static gint hf_lwapp_control = -1;
+static gint hf_lwapp_control_type = -1;
+static gint hf_lwapp_control_seq_no = -1;
+static gint hf_lwapp_control_length = -1;
+
+static dissector_handle_t eth_handle;
+static dissector_handle_t wlan_handle;
+static dissector_handle_t data_handle;
+
+typedef struct {
+ guint8 flags;
+ guint8 fragmentId;
+ guint16 length;
+ guint8 rssi;
+ guint8 snr;
+} LWAPP_Header;
+
+typedef struct {
+ guint8 tag;
+ guint16 length;
+} CNTL_Data_Header;
+
+typedef struct {
+ guint8 type;
+ guint8 seqNo;
+ guint16 length;
+} CNTL_Header;
+
+typedef enum {
+ RESULT_CODE = 1,
+ MWAR_ADDR_PAYLOAD,
+ RAD_PAYLOAD,
+ RAD_SLOT_PAYLOAD,
+ RAD_NAME_PAYLOAD,
+ MWAR_PAYLOAD,
+ VAP_PAYLOAD,
+ STATION_CFG_PAYLOAD,
+ OPERATION_RATE_SET_PAYLOAD,
+ MULTI_DOMAIN_CAPABILITY_PAYLOAD,
+ MAC_OPERATION_PAYLOAD,
+ PHY_TX_POWER_PAYLOAD,
+ PHY_TX_POWER_LEVEL_PAYLOAD,
+ PHY_DSSS_PAYLOAD,
+ PHY_OFDM_PAYLOAD,
+ SUPPORTED_RATES_PAYLOAD,
+ AUTH_PAYLOAD,
+ TEST_PAYLOAD,
+ RRM_NEIGHBOR_CTRL_PAYLOAD,
+ RRM_NOISE_CTRL_PAYLOAD,
+ RRM_NOISE_DATA_PAYLOAD,
+ RRM_INTERFERENCE_CTRL_PAYLOAD,
+ RRM_INTERFERENCE_DATA_PAYLOAD,
+ RRM_LOAD_CTRL_PAYLOAD,
+ RRM_LOAD_DATA_PAYLOAD,
+ CHANGE_STATE_EVENT_PAYLOAD,
+ ADMIN_STATE_PAYLOAD,
+ DELETE_VAP_PAYLOAD,
+ ADD_MOBILE_PAYLOAD,
+ DELETE_MOBILE_PAYLOAD
+} control_tags;
+
+typedef enum
+ {
+ DISCOVERY_REQUEST = 1,
+ DISCOVERY_REPLY,
+ JOIN_REQUEST,
+ JOIN_REPLY,
+ HANDOFF_REQUEST,
+ HANDOFF_REPLY,
+ HANDOFF_COMMAND,
+ HANDOFF_RESPONSE,
+ HANDOFF_CONFIRM,
+ CONFIGURE_REQUEST,
+ CONFIGURE_RESPONSE,
+ CONFIGURE_COMMAND,
+ CONFIGURE_COMMAND_RES,
+ STATISTICS_INFO,
+ CHANGE_STATE_EVENT,
+ CHANGE_STATE_EVENT_RES,
+ RRM_CONTROL_REQ,
+ RRM_CONTROL_RES,
+ RRM_DATA_REQ,
+ RRM_DATA_RES,
+ ECHO_REQUEST,
+ ECHO_RESPONSE,
+ I_AM_UP_REQ,
+ I_AM_UP_RES
+ }CNTLMsgType;
+
+const value_string control_msg_vals[] = {
+ {DISCOVERY_REQUEST, "DISCOVERY_REQUEST"},
+ {DISCOVERY_REPLY, "DISCOVERY_REPLY"},
+ {JOIN_REQUEST, "JOIN_REQUEST"},
+ {JOIN_REPLY, "JOIN_REPLY"},
+ {HANDOFF_REQUEST, "HANDOFF_REQUEST"},
+ {HANDOFF_REPLY, "HANDOFF_REPLY"},
+ {HANDOFF_COMMAND, "HANDOFF_COMMAND"},
+ {HANDOFF_RESPONSE, "HANDOFF_RESPONSE"},
+ {HANDOFF_CONFIRM, "HANDOFF_CONFIRM"},
+ {CONFIGURE_REQUEST, "CONFIGURE_REQUEST"},
+ {CONFIGURE_RESPONSE, "CONFIGURE_RESPONSE"},
+ {CONFIGURE_COMMAND, "CONFIGURE_COMMAND"},
+ {CONFIGURE_COMMAND_RES, "CONFIGURE_COMMAND_RES"},
+ {STATISTICS_INFO, "STATISTICS_INFO"},
+ {CHANGE_STATE_EVENT, "CHANGE_STATE_EVENT"},
+ {CHANGE_STATE_EVENT_RES, "CHANGE_STATE_EVENT_RES"},
+ {RRM_CONTROL_REQ, "RRM_CONTROL_REQ"},
+ {RRM_CONTROL_RES, "RRM_CONTROL_RES"},
+ {RRM_DATA_REQ, "RRM_DATA_REQ"},
+ {RRM_DATA_RES, "RRM_DATA_RES"},
+ {ECHO_REQUEST, "ECHO_REQUEST"},
+ {ECHO_RESPONSE, "ECHO_RESPONSE"},
+ {I_AM_UP_REQ, "I_AM_UP_REQ"},
+ {I_AM_UP_RES, "I_AM_UP_RES"},
+
+ { 0, NULL}
+};
+const value_string control_tag_vals[] = {
+
+ {RESULT_CODE, "RESULT_CODE"},
+ {MWAR_ADDR_PAYLOAD, "MWAR_ADDR_PAYLOAD"},
+ {RAD_PAYLOAD, "RAD_PAYLOAD"},
+ {RAD_SLOT_PAYLOAD, "RAD_SLOT_PAYLOAD"},
+ {RAD_NAME_PAYLOAD, "RAD_NAME_PAYLOAD"},
+ {MWAR_PAYLOAD, "MWAR_PAYLOAD"},
+ {VAP_PAYLOAD, "VAP_PAYLOAD"},
+ {STATION_CFG_PAYLOAD, "STATION_CFG_PAYLOAD"},
+ {OPERATION_RATE_SET_PAYLOAD, "OPERATION_RATE_SET_PAYLOAD"},
+ {MULTI_DOMAIN_CAPABILITY_PAYLOAD, "MULTI_DOMAIN_CAPABILITY_PAYLOAD"},
+ {MAC_OPERATION_PAYLOAD, "MAC_OPERATION_PAYLOAD"},
+ {PHY_TX_POWER_PAYLOAD, "PHY_TX_POWER_PAYLOAD"},
+ {PHY_TX_POWER_LEVEL_PAYLOAD, "PHY_TX_POWER_LEVEL_PAYLOAD"},
+ {PHY_DSSS_PAYLOAD, "PHY_DSSS_PAYLOAD"},
+ {PHY_OFDM_PAYLOAD, "PHY_OFDM_PAYLOAD"},
+ {SUPPORTED_RATES_PAYLOAD, "SUPPORTED_RATES_PAYLOAD"},
+ {AUTH_PAYLOAD, "AUTH_PAYLOAD"},
+ {TEST_PAYLOAD, "TEST_PAYLOAD"},
+ {RRM_NEIGHBOR_CTRL_PAYLOAD, "RRM_NEIGHBOR_CTRL_PAYLOAD"},
+ {RRM_NOISE_CTRL_PAYLOAD, "RRM_NOISE_CTRL_PAYLOAD"},
+ {RRM_NOISE_DATA_PAYLOAD, "RRM_NOISE_DATA_PAYLOAD"},
+ {RRM_INTERFERENCE_CTRL_PAYLOAD, "RRM_INTERFERENCE_CTRL_PAYLOAD"},
+ {RRM_INTERFERENCE_DATA_PAYLOAD, "RRM_INTERFERENCE_DATA_PAYLOAD"},
+ {RRM_LOAD_CTRL_PAYLOAD, "RRM_LOAD_CTRL_PAYLOAD"},
+ {RRM_LOAD_DATA_PAYLOAD, "RRM_LOAD_DATA_PAYLOAD"},
+ {CHANGE_STATE_EVENT_PAYLOAD, "CHANGE_STATE_EVENT_PAYLOAD"},
+ {ADMIN_STATE_PAYLOAD, "ADMIN_STATE_PAYLOAD"},
+ {DELETE_VAP_PAYLOAD, "DELETE_VAP_PAYLOAD"},
+ {ADD_MOBILE_PAYLOAD, "ADD_MOBILE_PAYLOAD"},
+ {DELETE_MOBILE_PAYLOAD, "DELETE_MOBILE_PAYLOAD"},
+ {0, NULL}
+};
+
+static const true_false_string lwapp_flags_type = {
+ "LWAPP Control Packet" ,
+ "Encapsulated 80211"
+};
+
+static const true_false_string lwapp_set_truth = {
+ "Not Set",
+ "Set"
+};
+
+/*
+ * dissect lwapp control packets. This is not fully implemented,
+ * but it's a good start.
+ */
+static void dissect_control(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *tree)
+{
+ CNTL_Header header;
+ proto_tree *control_tree;
+ tvbuff_t *next_tvb;
+
+ /* Set up structures needed to add the protocol subtree and manage it */
+ proto_item *ti;
+ size_t offset=0;
+
+ /* Make entries in Protocol column and Info column on summary display */
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "LWAPP");
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_clear(pinfo->cinfo, COL_INFO);
+ col_add_str(pinfo->cinfo, COL_INFO,
+ "CNTL ");
+ }
+
+ /* Copy our header */
+ tvb_memcpy(tvb, (guint8*) &header, offset, sizeof(header));
+
+ /*
+ * Fix the length (network byte ordering), and set our version &
+ * slot id
+ */
+ header.length = g_ntohs(header.length);
+
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ gchar *description;
+
+ description = match_strval(header.type, control_msg_vals);
+ if (!description) {
+ description = alloca(120);
+ sprintf(description, "Bad Type: 0x%02x", header.type);
+ }
+ col_append_str(pinfo->cinfo, COL_INFO, description);
+ }
+
+ /* In the interest of speed, if "tree" is NULL, don't do any work not
+ necessary to generate protocol tree items. */
+ if (tree) {
+ /* create display subtree for the protocol */
+ ti = proto_tree_add_item(tree, proto_lwapp_control, tvb, offset,
+ -1, FALSE);
+ control_tree = proto_item_add_subtree(ti, ett_lwapp_control);
+
+ proto_tree_add_uint(control_tree, hf_lwapp_control_type,
+ tvb, offset, 1, header.type);
+ offset++;
+
+ proto_tree_add_uint(control_tree, hf_lwapp_control_seq_no,
+ tvb, offset, 1, header.seqNo);
+ offset++;
+
+ proto_tree_add_uint(control_tree, hf_lwapp_control_length,
+ tvb, offset, 2, header.length);
+ offset += 2;
+
+ /* Dissect rest of packet as data */
+ next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+ call_dissector(data_handle,next_tvb, pinfo, tree);
+ }
+
+} /* dissect_control */
+
+/*
+ * This lwapp dissector assumes that there is an 802.3 header at
+ * the start of the packet, so it simply re-calls the ethernet
+ * dissector on the packet.
+ */
+static void dissect_lwapp_l3(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *tree)
+{
+ /* Set up structures needed to add the protocol subtree and manage it */
+ proto_item *ti;
+ proto_tree *lwapp_tree;
+ size_t offset=0;
+ tvbuff_t *next_client;
+
+ /* Make entries in Protocol column and Info column on summary display */
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "LWAPP-L3");
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_clear(pinfo->cinfo, COL_INFO);
+ col_add_str(pinfo->cinfo, COL_INFO, "802.3 Packets over Layer 3");
+ }
+
+ if (tree) {
+ /* create display subtree for the protocol */
+ ti = proto_tree_add_item(tree, proto_lwapp_l3, tvb, offset,
+ -1, FALSE);
+ lwapp_tree = proto_item_add_subtree(ti, ett_lwapp_l3);
+ }
+
+ /* Dissect as Ethernet */
+ next_client = tvb_new_subset(tvb, 0, -1, -1);
+ call_dissector(eth_handle, next_client, pinfo, tree);
+ return;
+
+} /* dissect_lwapp_l3*/
+
+
+/*
+ * This dissector dissects the lwapp protocol itself. It assumes an
+ * lwapp payload in the data, and doesn't care whether the data was
+ * from a UDP packet, or a Layer 2 one.
+ */
+static void dissect_lwapp(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *tree)
+{
+ LWAPP_Header header;
+ guint8 slotId;
+ guint8 version;
+ proto_tree *lwapp_tree;
+ proto_tree *flags_tree;
+ tvbuff_t *next_client;
+
+ /* Set up structures needed to add the protocol subtree and manage it */
+ proto_item *ti;
+ size_t offset=0;
+
+ /* Make entries in Protocol column and Info column on summary display */
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "LWAPP");
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_clear(pinfo->cinfo, COL_INFO);
+ col_add_str(pinfo->cinfo, COL_INFO,
+ "LWAPP IP or Layer 2");
+ }
+
+ /* Copy our header */
+ tvb_memcpy(tvb, (guint8*) &header, offset, sizeof(header));
+
+ /*
+ * Fix the length (network byte ordering), and set our version &
+ * slot id
+ */
+ header.length = g_ntohs(header.length);
+ version = (header.flags & 0xc0) >> 6;
+ slotId = (header.flags & 0x38) >> 3;
+
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ if ((header.flags & LWAPP_FLAGS_T) != 0)
+ col_append_str(pinfo->cinfo, COL_INFO,
+ " Control Packet");
+ else
+ col_append_str(pinfo->cinfo, COL_INFO,
+ " 802.11 Packet");
+ }
+
+ /* In the interest of speed, if "tree" is NULL, don't do any work not
+ necessary to generate protocol tree items. */
+ if (tree) {
+
+ /* create display subtree for the protocol */
+ ti = proto_tree_add_item(tree, proto_lwapp, tvb, offset,
+ tvb_length(tvb), FALSE);
+ lwapp_tree = proto_item_add_subtree(ti, ett_lwapp);
+
+ proto_tree_add_uint(lwapp_tree, hf_lwapp_version,
+ tvb, offset, 1, version);
+ proto_tree_add_uint(lwapp_tree, hf_lwapp_slotid,
+ tvb, offset, 1, slotId);
+
+ flags_tree = proto_item_add_subtree(lwapp_tree, ett_lwapp_flags);
+ proto_tree_add_boolean(flags_tree, hf_lwapp_flags_type,
+ tvb, offset, 1, header.flags);
+ proto_tree_add_boolean(flags_tree, hf_lwapp_flags_fragment,
+ tvb, offset, 1, header.flags);
+ proto_tree_add_boolean(flags_tree, hf_lwapp_flags_fragment_type,
+ tvb, offset, 1, header.flags);
+ offset++;
+
+ proto_tree_add_uint(lwapp_tree, hf_lwapp_fragment_id,
+ tvb, offset, 1, header.fragmentId);
+ offset++;
+
+ proto_tree_add_uint(lwapp_tree, hf_lwapp_length,
+ tvb, offset, 2, header.length);
+ offset += 2;
+
+ proto_tree_add_uint(lwapp_tree, hf_lwapp_rssi,
+ tvb, offset, 1, header.rssi);
+ offset++;
+ proto_tree_add_uint(lwapp_tree, hf_lwapp_snr,
+ tvb, offset, 1, header.snr);
+ offset++;
+
+
+ } /* tree */
+
+ if ((header.flags & LWAPP_FLAGS_T) == 0) {
+ next_client = tvb_new_subset(tvb, sizeof(LWAPP_Header), -1, -1);
+ call_dissector(wlan_handle, next_client, pinfo, tree);
+ } else {
+ next_client = tvb_new_subset(tvb, sizeof(LWAPP_Header), -1, -1);
+ dissect_control(next_client, pinfo, tree);
+ }
+ return;
+
+} /* dissect_lwapp*/
+
+/* registration with the filtering engine */
+void
+proto_register_lwapp(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_lwapp_version,
+ { "Version", "lwapp.version", FT_UINT8, BASE_DEC, NULL, 0x00,
+ "", HFILL }},
+ { &hf_lwapp_slotid,
+ { "slotId","lwapp.slotId", FT_UINT24, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+ { &hf_lwapp_flags_type,
+ { "Type", "lwapp.flags.type", FT_BOOLEAN, 8,
+ TFS(&lwapp_flags_type), LWAPP_FLAGS_T, "", HFILL }},
+ { &hf_lwapp_flags_fragment,
+ { "Fragment", "lwapp.flags.fragment", FT_BOOLEAN, 8,
+ TFS(&lwapp_set_truth), LWAPP_FLAGS_F,
+ "", HFILL }},
+ { &hf_lwapp_flags_fragment_type,
+ { "Fragment Type", "lwapp.flags.fragmentType", FT_BOOLEAN, 8,
+ TFS(&lwapp_set_truth), LWAPP_FLAGS_FT,
+ "", HFILL }},
+ { &hf_lwapp_fragment_id,
+ { "Fragment Id","lwapp.fragmentId", FT_UINT8, BASE_HEX,
+ NULL, 0x0, "", HFILL }},
+ { &hf_lwapp_length,
+ { "Length","lwapp.Length", FT_UINT16, BASE_DEC,
+ NULL, 0x0, "", HFILL }},
+ { &hf_lwapp_rssi,
+ { "RSSI","lwapp.rssi", FT_UINT8, BASE_HEX,
+ NULL, 0x0, "", HFILL }},
+ { &hf_lwapp_snr,
+ { "SNR","lwapp.snr", FT_UINT8, BASE_HEX,
+ NULL, 0x0, "", HFILL }},
+ { &hf_lwapp_control,
+ { "Control Data (not dissected yet)","lwapp.control", FT_BYTES, BASE_NONE,
+ NULL, 0x0, "", HFILL }},
+ { &hf_lwapp_control_type,
+ { "Control Type", "lwapp.control.type", FT_UINT8, BASE_DEC, NULL, 0x00,
+ "", HFILL }},
+ { &hf_lwapp_control_seq_no,
+ { "Control Sequence Number", "lwapp.control.seqno", FT_UINT8, BASE_DEC, NULL, 0x00,
+ "", HFILL }},
+ { &hf_lwapp_control_length,
+ { "Control Length","lwapp.control.length", FT_UINT16, BASE_DEC,
+ NULL, 0x0, "", HFILL }},
+ };
+ static gint *ett[] = {
+ &ett_lwapp_l3,
+ &ett_lwapp,
+ &ett_lwapp_control,
+ &ett_lwapp_flags
+ };
+
+ proto_lwapp = proto_register_protocol ("LWAPP Encapsulated Packet",
+ "LWAPP", "lwapp");
+
+ proto_lwapp_l3 = proto_register_protocol ("LWAPP Layer 3 Packet",
+ "LWAPP-L3", "lwapp-l3");
+
+ proto_lwapp_control = proto_register_protocol ("LWAP Control Message",
+ "LWAPP-CNTL", "lwapp-cntl");
+ proto_register_field_array(proto_lwapp, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+} /* proto_register_diameter */
+
+void
+proto_reg_handoff_lwapp(void)
+{
+ dissector_handle_t lwapp_l3_handle;
+ dissector_handle_t lwapp_handle;
+
+ /*
+ * Get handles for the Ethernet, and wireless dissectors.
+ */
+ eth_handle = find_dissector("eth");
+ wlan_handle = find_dissector("wlan");
+ data_handle = find_dissector("data");
+
+
+ /* This dissector assumes lwapp packets in an 802.3 frame */
+ lwapp_l3_handle = create_dissector_handle(dissect_lwapp_l3, proto_lwapp_l3);
+
+ /* This dissector assumes a lwapp packet */
+ lwapp_handle = create_dissector_handle(dissect_lwapp, proto_lwapp);
+
+ /*
+ * Ok, the following deserves some comments. We have four
+ * different ways lwapp can appear on the wire. Mostly, this is
+ * because lwapp is such a new protocol.
+ *
+ * First, lwapp can join on multiple udp ports, as encapsulated
+ * packets on top of UDP. In this case, there is a full raw
+ * ethernet frame inside of the UDP packet. This method is
+ * becoming obscelete, but we still wanted to dissect the
+ * packets.
+ *
+ * Next, lwapp can be over UDP, but packged for L3 tunneling. This
+ * is the new-style. In this case, LWAP headers are just transmitted
+ * via UDP.
+ *
+ * The last method is lwapp directly over layer 2. For this, we
+ * dissect two different ethertypes (until IANA gives us one)
+ *
+ */
+
+ /* Obsceleted LWAP via encapsulated 802.3 over UDP */
+
+ dissector_add("udp.port", 12220, lwapp_l3_handle);
+
+ /* new-style lwapp directly over UDP: L3-lwapp*/
+ dissector_add("udp.port", 12222, lwapp_handle);
+
+ /* Lwapp over L2 */
+ dissector_add("ethertype", 0x88bb, lwapp_handle);
+ dissector_add("ethertype", 0xbbbb, lwapp_handle);
+
+}