summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-miwi-p2pstar.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:53 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:53 +0000
commita86c5f7cae7ec9a3398300555a0b644689d946a1 (patch)
tree39fe4b107c71174fd1e8a8ceb9a4d2aa14116248 /epan/dissectors/packet-miwi-p2pstar.c
parentReleasing progress-linux version 4.2.6-1~progress7.99u1. (diff)
downloadwireshark-a86c5f7cae7ec9a3398300555a0b644689d946a1.tar.xz
wireshark-a86c5f7cae7ec9a3398300555a0b644689d946a1.zip
Merging upstream version 4.4.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-miwi-p2pstar.c')
-rw-r--r--epan/dissectors/packet-miwi-p2pstar.c1904
1 files changed, 1904 insertions, 0 deletions
diff --git a/epan/dissectors/packet-miwi-p2pstar.c b/epan/dissectors/packet-miwi-p2pstar.c
new file mode 100644
index 00000000..6ab0fa91
--- /dev/null
+++ b/epan/dissectors/packet-miwi-p2pstar.c
@@ -0,0 +1,1904 @@
+/* packet-miwi_p2pstar.c
+ * Dissector routines for the Microchip MiWi_P2P_Star
+ * Copyright 2013 Martin Leixner <info@sewio.net>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *------------------------------------------------------------
+*/
+
+#include "config.h"
+#include <epan/packet.h>
+#include <epan/decode_as.h>
+#include <epan/exceptions.h>
+#include <epan/crc16-tvb.h>
+#include <epan/crc32-tvb.h>
+#include <epan/expert.h>
+#include <epan/addr_resolv.h>
+#include <epan/address_types.h>
+#include <epan/conversation.h>
+#include <epan/prefs.h>
+#include <epan/uat.h>
+#include <epan/strutil.h>
+#include <epan/to_str.h>
+#include <epan/show_exception.h>
+#include <epan/proto_data.h>
+#include <epan/etypes.h>
+#include <epan/oui.h>
+#include <wsutil/pint.h>
+
+/* Use libgcrypt for cipher libraries. */
+#include <wsutil/wsgcrypt.h>
+
+#include <wsutil/filesystem.h>
+#include "packet-ieee802154.h"
+#include <epan/prefs.h>
+#include <epan/strutil.h>
+#include <wsutil/wsgcrypt.h>
+
+/* Function declarations */
+void proto_register_miwi_p2pstar(void);
+void proto_reg_handoff_miwi_p2pstar(void);
+
+/* MiWi MAC Header FCF fields */
+#define MIWI_MAC_FCF_FRAME_TYPE 0x0007
+#define MIWI_MAC_FCF_SECURITY_EN 0x0008
+#define MIWI_MAC_FCF_FRAME_PENDING 0x0010
+#define MIWI_MAC_FCF_ACK_REQUEST 0x0020
+#define MIWI_MAC_FCF_PANID_COMP 0x0040
+#define MIWI_MAC_FCF_RESERVED 0x0380
+#define MIWI_MAC_FCF_DEST_ADDR_MODE 0x0C00
+#define MIWI_MAC_FCF_FRAME_VERSION 0x3000
+#define MIWI_MAC_FCF_SRC_ADDR_MODE 0xC000
+
+/* MiWi NWK Header FCF fields */
+#define MIWI_NWK_FCF_FRAME_TYPE 0x0003
+#define MIWI_NWK_FCF_SECURITY_EN 0x0004
+#define MIWI_NWK_FCF_INFRA_CLUSTER 0x0008
+#define MIWI_NWK_FCF_ACK_REQUEST 0x0010
+#define MIWI_NWK_FCF_ADDR_SAME_AS_MAC 0x0020
+#define MIWI_NWK_FCF_RESERVED 0x00C0
+
+/* Address Mode Definitions */
+#define MIWI_FCF_ADDR_NONE 0x0
+#define MIWI_FCF_ADDR_RESERVED 0x1
+#define MIWI_FCF_ADDR_SHORT 0x2
+#define MIWI_FCF_ADDR_EXT 0x3
+
+#define MIWI_SOURCE_ADDR_MODE 0x00 // to check
+
+/* MiWi NWK Header FCF fields */
+#define MIWI_CAP_INFO_RCV_ON_IDLE 0x0001
+#define MIWI_CAP_INFO_REQ_DATA_ON_WP 0x0002
+#define MIWI_CAP_INFO_NEED_TIME_SYNC 0x0004
+#define MIWI_CAP_INFO_SECURITY_CAP 0x0008
+#define MIWI_CAP_INFO_RESERVED 0x00F0
+
+/*Defined addresses*/
+#define MIWI_BCAST_ADDR 0xFFFF
+
+/*Command IDs*/
+#define MIWI_P2P_CMD_CONN_REQ 0x81
+#define MIWI_P2P_CMD_CONN_REMOVAL_REQ 0x82
+#define MIWI_P2P_CMD_DATA_REQ 0x83
+#define MIWI_P2P_CMD_CHANNEL_HOP 0x84
+#define MIWI_P2P_CMD_ACTIVE_SCAN_REQ 0x87
+#define MIWI_P2P_CMD_CONN_RES 0x91
+#define MIWI_P2P_CMD_CONN_REMOVAL_RES 0x92
+#define MIWI_P2P_CMD_ACTIVE_SCAN_RES 0x97
+
+#define MIWI_STAR_CMD_FORWARD_PACKET 0xCC
+#define MIWI_STAR_CMD_SOFT_ACK 0xDA
+#define MIWI_STAR_CMD_LINK_STATUS 0x7A
+#define MIWI_STAR_CMD_CONN_TABLE 0x77
+
+#define MIWI_CONN_STATUS_SUCCESS 0x00
+#define MIWI_CONN_STATUS_EXISTS 0x01
+#define MIWI_CONN_STATUS_ACTIVE_SCAN 0x02
+#define MIWI_CONN_STATUS_ENTRY_NOT_EXIST 0xF0
+#define MIWI_CONN_STATUS_NOT_ENOUGH_SPACE 0xF1
+#define MIWI_CONN_STATUS_NOT_SAME_PA 0xF2
+#define MIWI_CONN_STATUS_NOT_PERMITTED 0xF3
+
+/* FCS Types used by user configuration */
+#define MIWI_P2PSTAR_FCS_16_BIT 1/* CRC16 */
+
+/**MiWI Type of MAC frame */
+#define MIWI_MAC_FRAME_BEACON 0x00
+#define MIWI_MAC_FRAME_DATA 0x01
+#define MIWI_MAC_FRAME_ACK 0x02
+#define MIWI_MAC_FRAME_CMD 0x03
+#define MIWI_MAC_FRAME_RESERVED 0x04
+
+/* User string with the decryption key. */
+//static const char *miwi_p2pstar_key_str = NULL;
+
+/* Initialize protocol and registered fields. */
+static int proto_miwi_p2pstar;
+
+/* Initialize protocol subtrees. */
+static int ett_miwi_p2pstar;
+static int ett_miwi_p2pstar_fcf;
+static int ett_miwi_p2pstar_cmd_tree;
+static int ett_miwi_p2pstar_cap_info;
+static int ett_miwi_fcs;
+
+static dissector_handle_t miwi_p2pstar_handle;
+
+static int hf_miwi_frame_length;
+static int hf_miwi_fcf;
+static int hf_miwi_fcf_frame_type;
+static int hf_miwi_fcf_security_enabled;
+static int hf_miwi_fcf_frame_pending;
+static int hf_miwi_fcf_ack_req;
+static int hf_miwi_fcf_panid_comp;
+static int hf_miwi_fcf_reserved;
+static int hf_miwi_fcf_dest_addr_mode;
+static int hf_miwi_fcf_frame_version;
+static int hf_miwi_fcf_src_addr_mode;
+static int hf_miwi_seq;
+static int hf_miwi_dst_panid;
+static int hf_miwi_short_dst_addr;
+static int hf_miwi_ext_dst_addr;
+//static int hf_miwi_no_dst_addr;
+//static int hf_miwi_no_src_addr;
+static int hf_miwi_ext_src_addr;
+static int hf_miwi_short_src_addr;
+static int hf_miwi_addr16;
+static int hf_miwi_addr64;
+static int hf_miwi_src64_origin;
+static int hf_miwi_src_panid;
+static int hf_miwi_cmd_id;
+//static int hf_miwi_fcs;
+//static int hf_miwi_fcs_ok;
+
+static int hf_miwi_oper_chan;
+static int hf_miwi_cap_info;
+static int hf_miwi_cap_info_rcv_on_idle;
+static int hf_miwi_cap_info_rqst_data_on_wp;
+static int hf_miwi_cap_info_need_time_sync;
+static int hf_miwi_cap_info_security_cap;
+static int hf_miwi_cap_info_reserved;
+static int hf_miwi_conn_res_status;
+
+//static int hf_miwi_conn_rmv_req;
+static int hf_miwi_conn_rmv_res_status;
+//static int hf_miwi_data_req;
+//static int hf_miwi_chan_hop;
+//static int hf_miwi_conn_res;
+//static int hf_miwi_conn_rmv_res;
+//static int hf_miwi_active_scan_req;
+//static int hf_miwi_active_scan_cur_chan;
+
+//static int hf_miwi_active_scan_res;
+//static int hf_miwi_active_scan_res_node_id;
+
+//static int hf_miwi_fwd_pkt_cmd;
+static int hf_miwi_fwd_pkt_dst_addr;
+//static int hf_miwi_conn_tbl_bcast_cmd;
+static int hf_miwi_conn_tbl_size;
+//static int hf_miwi_software_ack;
+//static int hf_miwi_link_status;
+
+/*Channel hopping frame*/
+static int hf_miwi_current_op_channel;
+static int hf_miwi_dst_channel_to_jump_to;
+
+//static int hf_miwi_mic;
+//static int hf_miwi_key_number;
+
+static int miwi_short_address_type;
+
+//static expert_field ei_miwi_empty_payload;
+static expert_field ei_miwi_frame_ver;
+static expert_field ei_miwi_dst;
+static expert_field ei_miwi_src;
+static expert_field ei_miwi_invalid_addressing;
+static expert_field ei_miwi_invalid_panid_compression;
+static expert_field ei_miwi_invalid_panid_compression2;
+//static expert_field ei_miwi_fcs;
+/* 802.15.4-2003 security */
+//static int hf_miwi_sec_frame_counter;
+//static int hf_miwi_sec_key_sequence_counter;
+
+
+/* ethertype for 802.15.4 tag - encapsulating an Ethernet packet */
+static unsigned int miwi_ethertype = 0x809A;
+
+/* boolean value set if the FCS must be ok before payload is dissected */
+static bool miwi_fcs_ok = true;
+
+/* boolean value set to enable ack tracking */
+static bool miwi_ack_tracking = false;
+
+/* Preferences for 2003 security */
+//static int miwi_sec_suite = SECURITY_LEVEL_ENC_MIC_64;
+//static bool miwi_extend_auth = true;
+
+//static wmem_tree_t* mac_key_hash_handlers;
+
+/*
+ * Address Hash Tables
+ *
+ */
+static ieee802154_map_tab_t miwi_map = {NULL, NULL};
+
+//static ieee802154_key_t *miwi_keys = NULL;
+//static unsigned num_miwi_keys = 0;
+
+static int miwi_fcs_type = MIWI_P2PSTAR_FCS_16_BIT;
+
+static int* const fields[] = {
+ &hf_miwi_fcf_frame_type,
+ &hf_miwi_fcf_security_enabled,
+ &hf_miwi_fcf_frame_pending,
+ &hf_miwi_fcf_ack_req,
+ &hf_miwi_fcf_panid_comp,
+ &hf_miwi_fcf_reserved,
+ &hf_miwi_fcf_dest_addr_mode,
+ &hf_miwi_fcf_frame_version,
+ &hf_miwi_fcf_src_addr_mode,
+ NULL
+};
+
+static const value_string miwi_p2pstar_cmd_names[] ={
+ { MIWI_P2P_CMD_CONN_REQ, " Connection Request"},
+ { MIWI_P2P_CMD_CONN_REMOVAL_REQ, " Connection Removal Request"},
+ { MIWI_P2P_CMD_DATA_REQ, " Data Request"},
+ { MIWI_P2P_CMD_CHANNEL_HOP, " Channel Hopping"},
+ { MIWI_P2P_CMD_ACTIVE_SCAN_REQ, " Active Scan Request"},
+ { MIWI_P2P_CMD_CONN_RES, " Connection Response"},
+ { MIWI_P2P_CMD_CONN_REMOVAL_RES, " Connection Removal Response"},
+ { MIWI_P2P_CMD_ACTIVE_SCAN_RES, " Active Scan Response"},
+ { MIWI_STAR_CMD_FORWARD_PACKET, " Forward packet"},
+ { MIWI_STAR_CMD_SOFT_ACK, " Soft Acknowledgement"},
+ { MIWI_STAR_CMD_LINK_STATUS, " Link Status"},
+ { MIWI_STAR_CMD_CONN_TABLE, " Connection Table"},
+ { 0, NULL}
+};
+
+/* MAC Frame Types */
+static const value_string miwi_mac_frame_types[] = {
+ { MIWI_MAC_FRAME_BEACON, "Beacon"},
+ { MIWI_MAC_FRAME_DATA, "Data"},
+ { MIWI_MAC_FRAME_ACK, "Acknowledgement"},
+ { MIWI_MAC_FRAME_CMD, "Command"},
+ {MIWI_MAC_FRAME_RESERVED, "Reserved"},
+ { 0, NULL}
+};
+
+static const value_string miwi_addr_modes[] = {
+ { MIWI_FCF_ADDR_NONE, "None"},
+ { MIWI_FCF_ADDR_RESERVED, "Reserved"},
+ { MIWI_FCF_ADDR_SHORT, "Short/16-bit"},
+ { MIWI_FCF_ADDR_EXT, "Long/64-bit"},
+ { 0, NULL}
+};
+
+/* Versions */
+static const value_string miwi_frame_versions[] = {
+ { IEEE802154_VERSION_2003, "IEEE Std 802.15.4-2003"},
+ { IEEE802154_VERSION_2006, "IEEE Std 802.15.4-2006"},
+ { IEEE802154_VERSION_2015, "IEEE Std 802.15.4-2015"},
+ { IEEE802154_VERSION_RESERVED, "Reserved" },
+ { 0, NULL}
+};
+
+static const value_string miwi_p2pstar_conn_status[] = {
+ { MIWI_CONN_STATUS_SUCCESS, " (Successful)"},
+ { MIWI_CONN_STATUS_EXISTS, " (Already Exists)"},
+ { MIWI_CONN_STATUS_ACTIVE_SCAN, " (Active Scan State)"},
+ { MIWI_CONN_STATUS_ENTRY_NOT_EXIST, " (Entry Not Exist)"},
+ { MIWI_CONN_STATUS_NOT_ENOUGH_SPACE, " (Not Enough Space)"},
+ { MIWI_CONN_STATUS_NOT_SAME_PA, " (PANID Mismatch)"},
+ { MIWI_CONN_STATUS_NOT_PERMITTED, " (Not Permitted)"},
+ { 0, NULL}
+};
+
+#define miwi_packet ieee802154_packet
+
+ /* CRC definitions. IEEE 802.15.4 CRCs vary from ITU-T by using an initial value of
+ * 0x0000, and no XOR out. IEEE802154_CRC_XOR is defined as 0xFFFF in order to un-XOR
+ * the output from the ITU-T (CCITT) CRC routines in Wireshark. */
+#define MIWI_CRC_SEED 0x0000
+#define MIWI_CRC_XOROUT 0xFFFF
+#define miwi_crc_tvb(tvb, offset) (crc16_ccitt_tvb_seed(tvb, offset, MIWI_CRC_SEED) ^ MIWI_CRC_XOROUT)
+/* For the 32-bit CRC, IEEE 802.15.4 uses ITU-T (CCITT) CRC-32. */
+#define miwi_crc32_tvb(tvb, offset) (crc32_ccitt_tvb(tvb, offset))
+ /**
+ * Verify the 16/32 bit IEEE 802.15.4 FCS
+ * @param tvb the IEEE 802.15.4 frame from the FCF up to and including the FCS
+ * @return if the computed FCS matches the transmitted FCS
+ */
+static bool
+is_fcs_ok(tvbuff_t *tvb, unsigned fcs_len)
+{
+ if(fcs_len == 2){
+ /* The FCS is in the last two bytes of the packet. */
+ uint16_t fcs = tvb_get_letohs(tvb, tvb_reported_length(tvb)-2);
+ uint16_t fcs_calc = (uint16_t) miwi_crc_tvb(tvb, tvb_reported_length(tvb)-2);
+ return fcs == fcs_calc;
+ }
+ else{
+ /* The FCS is in the last four bytes of the packet. */
+ uint32_t fcs = tvb_get_letohl(tvb, tvb_reported_length(tvb)-4);
+ uint32_t fcs_calc = miwi_crc32_tvb(tvb, tvb_reported_length(tvb)-4);
+ return fcs == fcs_calc;
+ }
+}/* is_fcs_ok */
+
+/* Returns the prompt string for the Decode-As dialog. */
+static void miwi_da_prompt(packet_info *pinfo _U_, char* result)
+{
+ ieee802154_hints_t *hints;
+ hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_miwi_p2pstar, 0);
+ if(hints)
+ snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "MIWI P2P STAR PAN 0x%04x as", hints->src_pan);
+ else
+ snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "MIWI P2P STAR PAN Unknown");
+}/* miwi_da_prompt */
+/* Returns the value to index the panid decode table with (source PAN)*/
+static void *miwi_da_value(packet_info *pinfo _U_)
+{
+ ieee802154_hints_t *hints;
+ hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_miwi_p2pstar, 0);
+ if(hints)
+ return GUINT_TO_POINTER((unsigned)(hints->src_pan));
+ else
+ return NULL;
+}/* miwi_da_value */
+static int miwi_short_address_to_str(const address* addr, char *buf, int buf_len)
+{
+ uint16_t miwi_short_addr = pletoh16(addr->data);
+
+ if (miwi_short_addr == 0xffff)
+ {
+ g_strlcpy(buf, "Broadcast", buf_len);
+ return 10;
+ }
+
+ *buf++ = '0';
+ *buf++ = 'x';
+ buf = word_to_hex(buf, miwi_short_addr);
+ *buf = '\0'; /* NULL terminate */
+
+ return 7;
+} /* miwi_short_address_to_str */
+static int miwi_short_to_str(uint16_t miwi_short_addr, char *buf, int buf_len)
+{
+ if(miwi_short_addr == 0xffff)
+ {
+ g_strlcpy(buf, "Broadcast", buf_len);
+ return 10;
+ }
+
+ *buf++ = '0';
+ *buf++ = 'x';
+ buf = word_to_hex(buf, miwi_short_addr);
+ *buf = '\0'; /* NULL terminate */
+
+ return 7;
+}/* miwi_short_to_str */
+
+static int miwi_short_address_str_len(const address* addr _U_)
+{
+ return 11;
+}
+
+static int miwi_short_address_len(void)
+{
+ return 2;
+}
+
+/**
+ *Extracts an integer sub-field from an int with a given mask
+ *
+*/
+#if 0
+static unsigned miwi_get_bit_field(unsigned input, unsigned mask)
+{
+ /* Sanity Check, don't want infinite loops. */
+ if(mask == 0) return 0;
+ /* Shift input and mask together. */
+ while (!(mask & 0x1)){
+ input >>= 1;
+ mask >>=1;
+ }/* while */
+ return (input & mask);
+}/* miwi_get_bit_field */
+#endif
+
+/* Return the length in octets for the user configured
+ * FCS/metadata following the PHY Payload */
+static unsigned miwi_fcs_type_len(unsigned i)
+{
+ unsigned fcs_type_lengths[] = { 2, 2, 4 };
+ if(i < array_length(fcs_type_lengths)){
+ return fcs_type_lengths[i];
+ }
+ return 0;
+}/* miwi_fcs_type_len */
+
+#if 0
+/* Set MAC key function. */
+static unsigned miwi_set_mac_key(miwi_packet *packet, unsigned char *key, unsigned char *alt_key, ieee802154_key_t *uat_key)
+{
+ ieee802154_set_key_func func = (ieee802154_set_key_func)wmem_tree_lookup32(mac_key_hash_handlers, uat_key->hash_type);
+
+ if(func != NULL)
+ return func(packet, key, alt_key, uat_key);
+
+ /* Right now, KEY_HASH_NONE and KEY_HASH_ZIP are not registered because they
+ work with this "default" behavior */
+ if(packet->key_index == uat_key->key_index)
+ {
+ memcpy(key, uat_key->key, IEEE802154_CIPHER_SIZE);
+ return 1;
+ }
+
+ return 0;
+}/* miwi_set_mac_key */
+#endif
+/**
+ * Dissector helper, parses and displays the frame control field.
+ *
+ * @param tvb pointer to buffer containing raw packet.
+ * @param pinfo pointer to packet information fields
+ * @param tree pointer to data tree wireshark uses to display packet.
+ * @param packet Miwi P2PStar packet information.
+ * @param offset offset into the tvb to find the FCF.
+ *
+ */
+static void
+dissect_miwi_fcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, miwi_packet *packet, unsigned *offset)
+{
+ uint16_t miwi_fcf;
+
+ /*Frame control fields*/
+ miwi_fcf = tvb_get_letohs(tvb, (const int)*offset);
+ packet->frame_type = (miwi_fcf & MIWI_MAC_FCF_FRAME_TYPE);
+ packet->security_enable = (miwi_fcf & MIWI_MAC_FCF_SECURITY_EN) >> 3;
+ packet->frame_pending = (miwi_fcf & MIWI_MAC_FCF_FRAME_PENDING) >> 4;
+ packet->ack_request = (miwi_fcf & MIWI_MAC_FCF_ACK_REQUEST) >> 5;
+ packet->pan_id_compression = (miwi_fcf & MIWI_MAC_FCF_PANID_COMP) >> 6;
+ /*packet->reserved = (miwi_fcf & MIWI_MAC_FCF_RESERVED) >> 7;*/
+ packet->dst_addr_mode = (miwi_fcf & MIWI_MAC_FCF_DEST_ADDR_MODE) >> 10;
+ packet->version = (miwi_fcf & MIWI_MAC_FCF_FRAME_VERSION) >> 12;
+ packet->src_addr_mode = (miwi_fcf & MIWI_MAC_FCF_SRC_ADDR_MODE) >> 14;
+
+ proto_item_append_text(tree, " %s", val_to_str_const(packet->frame_type, miwi_mac_frame_types, "Reserved"));
+ col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->frame_type, miwi_mac_frame_types, "Reserved"));
+
+ proto_tree_add_bitmask(tree, tvb,(const int)*offset, hf_miwi_fcf,
+ ett_miwi_p2pstar_fcf, fields, ENC_LITTLE_ENDIAN);
+
+ *offset += 2;
+}/* dissect_miwi_fcf */
+
+/**
+ * Command subdissector routine for the Association request command.
+ *
+ * @param tvb pointer to buffer containing raw packet.
+ * @param pinfo pointer to packet information fields.
+ * @param tree pointer to protocol tree.
+ * @param packet Miwi P2PStar packet information.
+ * @param offset offset into the tvb to find the packet information.
+ */
+
+static void
+dissect_miwi_connect_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, miwi_packet *packet, unsigned *offset)
+{
+ uint8_t cap,oper_chan;
+ proto_tree *subtree;
+ static int* const capability[] = {
+ &hf_miwi_cap_info_rcv_on_idle,
+ &hf_miwi_cap_info_rqst_data_on_wp,
+ &hf_miwi_cap_info_need_time_sync,
+ &hf_miwi_cap_info_security_cap,
+ &hf_miwi_cap_info_reserved,
+ NULL
+ };
+
+ /* Create a subtree for this command frame. */
+ subtree = proto_tree_add_subtree(tree, tvb, *offset, 1,ett_miwi_p2pstar_cmd_tree, NULL,
+ val_to_str_const(packet->command_id, miwi_p2pstar_cmd_names, "Unknown Command"));
+ oper_chan = tvb_get_uint8(tvb, *offset);
+ proto_tree_add_uint(subtree, hf_miwi_oper_chan, tvb, *offset, 1, oper_chan);
+ *offset += 1;
+
+ /* Get and display capability info. */
+ cap = tvb_get_uint8(tvb, *offset);
+ proto_tree_add_uint(subtree, hf_miwi_cap_info, tvb, *offset, 1, cap);
+ proto_tree_add_bitmask_list(subtree, tvb, *offset, 1, capability, ENC_NA);
+ *offset += 1;
+
+ /* Call the data dissector for any leftover bytes. */
+ if(tvb_captured_length(tvb) > *offset){
+ call_data_dissector(tvb_new_subset_remaining(tvb, *offset), pinfo, tree);
+ }
+}/* dissect_miwi_connect_req */
+
+/**
+ * Command subdissector routine for the Association response command.
+ *
+ * @param tvb pointer to buffer containing raw packet.
+ * @param pinfo pointer to packet information fields.
+ * @param tree pointer to protocol tree.
+ * @param packet Miwi P2PStar packet information.
+ * @param offset offset into the tvb to find the packet information.
+ */
+static void
+dissect_miwi_connect_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, miwi_packet *packet, unsigned *offset)
+{
+ proto_tree *subtree;
+ proto_item *ti;
+ uint8_t status;
+ uint8_t cap;
+ static int* const capability[] = {
+ &hf_miwi_cap_info_rcv_on_idle,
+ &hf_miwi_cap_info_rqst_data_on_wp,
+ &hf_miwi_cap_info_need_time_sync,
+ &hf_miwi_cap_info_security_cap,
+ &hf_miwi_cap_info_reserved,
+ NULL
+ };
+
+ /* Create a subtree for this command frame. */
+ subtree = proto_tree_add_subtree(tree, tvb, *offset, 3, ett_miwi_p2pstar_cmd_tree, NULL,
+ val_to_str_const((const uint32_t)packet->command_id, miwi_p2pstar_cmd_names, "Unknown Command"));
+
+ /* Get and display the status. */
+ status = tvb_get_uint8(tvb, *offset);
+ if(tree){
+ ti = proto_tree_add_uint(subtree, hf_miwi_conn_res_status, tvb, *offset, 1, status);
+ proto_item_append_text(ti, "%s", val_to_str_const(status, miwi_p2pstar_conn_status, " (Reserved)"));
+ }
+ *offset += 1;
+ col_append_str(pinfo->cinfo, COL_INFO, " Connection Response");
+
+ /* Update the info column. */
+ if(status == IEEE802154_CMD_ASRSP_AS_SUCCESS){
+ /* Association was successful. */
+ if(packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT){
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", PAN: 0x%04x", packet->dst_pan);
+ }
+ if(packet->src16 != IEEE802154_NO_ADDR16){
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Addr: 0x%04x", packet->src16);
+ }
+ }
+ else{
+ /* Association was unsuccessful. */
+ col_append_str(pinfo->cinfo, COL_INFO, ", Unsuccessful");
+ }
+
+ /* Update the address table. */
+ if((status == IEEE802154_CMD_ASRSP_AS_SUCCESS) && (packet->src16 != IEEE802154_NO_ADDR16)){
+ ieee802154_addr_update(&miwi_map, packet->src16, packet->dst_pan, packet->dst64,
+ pinfo->current_proto, pinfo->num);
+ }
+
+ /* Get and display capability info. */
+ cap = tvb_get_uint8(tvb, *offset);
+ proto_tree_add_uint(subtree, hf_miwi_cap_info, tvb, *offset, 1, cap);
+ proto_tree_add_bitmask_list(subtree, tvb, *offset, 1, capability, ENC_NA);
+ *offset += 1;
+
+ /* Call the data dissector for any leftover bytes. */
+ if(tvb_captured_length(tvb) > *offset){
+ call_data_dissector(tvb_new_subset_remaining(tvb, *offset), pinfo, tree);
+ }
+}/* dissect_miwi_connect_rsp */
+/**
+ * Command subdissector routine for the Channel Hopping command.
+ *
+ * @param tvb pointer to buffer containing raw packet.
+ * @param pinfo pointer to packet information fields.
+ * @param tree pointer to protocol tree.
+ * @param packet Miwi P2PStar packet information.
+ * @param offset offset into the tvb to find the packet information.
+ */
+static void
+dissect_miwi_channel_hop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, miwi_packet *packet, unsigned *offset)
+{
+ uint8_t current_op_channel,dst_channel_to_jump_to;
+ proto_tree *subtree;
+ proto_item *ti;
+
+ /* Create a subtree for this command frame. */
+ subtree = proto_tree_add_subtree(tree, tvb, *offset, 1,ett_miwi_p2pstar_cmd_tree, NULL,
+ val_to_str_const(packet->command_id, miwi_p2pstar_cmd_names, "Unknown Command"));
+ current_op_channel = tvb_get_uint8(tvb, *offset);
+ ti = proto_tree_add_uint(subtree, hf_miwi_current_op_channel, tvb, *offset, 1, current_op_channel);
+ proto_item_append_text(ti, ", Current Operating Channel: %i", current_op_channel);
+ *offset +=1;
+
+ dst_channel_to_jump_to = tvb_get_uint8(tvb, *offset);
+ ti = proto_tree_add_uint(subtree, hf_miwi_dst_channel_to_jump_to, tvb, *offset, 1, dst_channel_to_jump_to);
+ proto_item_append_text(ti, ", Destination Channel to Jump to: %i", dst_channel_to_jump_to);
+ *offset +=1;
+
+ /* Call the data dissector for any leftover bytes. */
+ if(tvb_captured_length(tvb) > *offset){
+ call_data_dissector(tvb_new_subset_remaining(tvb, *offset), pinfo, tree);
+ }
+}/* dissect_miwi_channel_hop */
+
+/**
+ * Command subdissector routine for the Connection removal response command.
+ *
+ * @param tvb pointer to buffer containing raw packet.
+ * @param pinfo pointer to packet information fields.
+ * @param tree pointer to protocol tree.
+ * @param packet Miwi P2PStar packet information.
+ * @param offset offset into the tvb to find the packet information.
+ */
+static void
+dissect_miwi_connect_removal_res(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, miwi_packet *packet, unsigned *offset)
+{
+ uint8_t conn_rmv_res_status;
+ proto_tree *subtree;
+ proto_item *ti;
+
+ /* Create a subtree for this command frame. */
+ subtree = proto_tree_add_subtree(tree, tvb, *offset, 1,ett_miwi_p2pstar_cmd_tree, NULL,
+ val_to_str_const(packet->command_id, miwi_p2pstar_cmd_names, "Unknown Command"));
+ conn_rmv_res_status = tvb_get_uint8(tvb, *offset);
+ ti = proto_tree_add_uint(subtree, hf_miwi_conn_rmv_res_status, tvb, *offset, 1, conn_rmv_res_status);
+ *offset +=1;
+ if(conn_rmv_res_status == 0x00){
+ proto_item_append_text(ti, ", Successful [Status: %i]", conn_rmv_res_status);
+ } else
+ proto_item_append_text(ti, ", Failed [Error Code: %i]", conn_rmv_res_status);
+
+ /* Call the data dissector for any leftover bytes. */
+ if(tvb_captured_length(tvb) > *offset){
+ call_data_dissector(tvb_new_subset_remaining(tvb, *offset), pinfo, tree);
+ }
+}/* dissect_miwi_connect_removal_res */
+
+/**
+ * Command subdissector routine for the Scan request command.
+ *
+ * @param tvb pointer to buffer containing raw packet.
+ * @param pinfo pointer to packet information fields.
+ * @param tree pointer to protocol tree.
+ * @param packet Miwi P2PStar packet information.
+ * @param offset offset into the tvb to find the packet information.
+ */
+static void
+dissect_miwi_active_scan_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, miwi_packet *packet, unsigned *offset)
+{
+ uint8_t scan_cur_chan;
+ proto_tree *subtree;
+ proto_item *ti;
+
+ /* Create a subtree for this command frame. */
+ subtree = proto_tree_add_subtree(tree, tvb, *offset, 1,ett_miwi_p2pstar_cmd_tree, NULL,
+ val_to_str_const(packet->command_id, miwi_p2pstar_cmd_names, "Unknown Command"));
+ scan_cur_chan = tvb_get_uint8(tvb, *offset);
+ ti = proto_tree_add_uint(subtree, hf_miwi_current_op_channel, tvb, *offset, 1, scan_cur_chan);
+ proto_item_append_text(ti, ", Current operating Channel %i", scan_cur_chan);
+ *offset +=1;
+
+ /* Call the data dissector for any leftover bytes. */
+ if(tvb_captured_length(tvb) > *offset){
+ call_data_dissector(tvb_new_subset_remaining(tvb, *offset), pinfo, tree);
+ }
+}/* dissect_miwi_active_scan_req */
+/**
+ * Command subdissector routine for the Scan response command.
+ *
+ * @param tvb pointer to buffer containing raw packet.
+ * @param pinfo pointer to packet information fields.
+ * @param tree pointer to protocol tree.
+ * @param packet Miwi P2PStar packet information.
+ * @param offset offset into the tvb to find the packet information.
+ */
+
+static void
+dissect_miwi_active_scan_res(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, miwi_packet *packet, unsigned *offset)
+{
+ uint8_t cap,scan_res_node_id;
+ proto_tree *subtree;
+ static int* const capability[] = {
+ &hf_miwi_cap_info_rcv_on_idle,
+ &hf_miwi_cap_info_rqst_data_on_wp,
+ &hf_miwi_cap_info_need_time_sync,
+ &hf_miwi_cap_info_security_cap,
+ &hf_miwi_cap_info_reserved,
+ NULL
+ };
+
+ /* Create a subtree for this command frame. */
+ subtree = proto_tree_add_subtree(tree, tvb, *offset, 1,ett_miwi_p2pstar_cmd_tree, NULL,
+ val_to_str_const(packet->command_id, miwi_p2pstar_cmd_names, "Unknown Command"));
+
+ /* Get and display capability info. */
+ cap = tvb_get_uint8(tvb, *offset);
+ proto_tree_add_uint(subtree, hf_miwi_cap_info, tvb, *offset, 1, cap);
+ proto_tree_add_bitmask_list(subtree, tvb, *offset, 1, capability, ENC_NA);
+ *offset += 1;
+
+ scan_res_node_id = tvb_get_uint8(tvb, *offset);
+ proto_tree_add_uint(subtree, hf_miwi_oper_chan, tvb, *offset, 1, scan_res_node_id);
+ *offset += 1;
+
+ /* Call the data dissector for any leftover bytes. */
+ if(tvb_captured_length(tvb) > *offset){
+ call_data_dissector(tvb_new_subset_remaining(tvb, *offset), pinfo, tree);
+ }
+}/* dissect_miwi_active_scan_res */
+/**
+ * Command subdissector routine for the forward Packet command.
+ *
+ * @param tvb pointer to buffer containing raw packet.
+ * @param pinfo pointer to packet information fields.
+ * @param tree pointer to protocol tree.
+ * @param packet Miwi P2PStar packet information.
+ * @param offset offset into the tvb to find the packet information.
+ */
+static void
+dissect_miwi_fwd_packet_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, miwi_packet *packet, unsigned *offset)
+{
+ uint8_t fwd_pkt_dst_addr;
+ proto_tree *subtree;
+
+ /* Create a subtree for this command frame. */
+ subtree = proto_tree_add_subtree(tree, tvb, *offset, 1,ett_miwi_p2pstar_cmd_tree, NULL,
+ val_to_str_const(packet->command_id, miwi_p2pstar_cmd_names, "Unknown Command"));
+ fwd_pkt_dst_addr = tvb_get_uint8(tvb, *offset);
+ proto_tree_add_uint(subtree, hf_miwi_fwd_pkt_dst_addr, tvb, *offset, 1, fwd_pkt_dst_addr);
+ *offset +=1;
+
+ /* Call the data dissector for any leftover bytes. */
+ if(tvb_captured_length(tvb) > *offset){
+ call_data_dissector(tvb_new_subset_remaining(tvb, *offset), pinfo, tree);
+ }
+}/* dissect_miwi_fwd_packet_cmd */
+/**
+ * Command subdissector routine for the Connection table broadcast command.
+ *
+ * @param tvb pointer to buffer containing raw packet.
+ * @param pinfo pointer to packet information fields.
+ * @param tree pointer to protocol tree.
+ * @param packet Miwi P2PStar packet information.
+ * @param offset offset into the tvb to find the packet information.
+ */
+
+static void
+dissect_miwi_connect_tbl_bcast_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, miwi_packet *packet, unsigned *offset)
+{
+ uint8_t conn_tbl_size;
+ proto_tree *subtree;
+
+ /* Create a subtree for this command frame. */
+ subtree = proto_tree_add_subtree(tree, tvb, *offset, 1,ett_miwi_p2pstar_cmd_tree, NULL,
+ val_to_str_const(packet->command_id, miwi_p2pstar_cmd_names, "Unknown Command"));
+ conn_tbl_size = tvb_get_uint8(tvb, *offset);
+ proto_tree_add_uint(subtree, hf_miwi_conn_tbl_size, tvb, *offset, 1, conn_tbl_size);
+ *offset +=1;
+
+ /* Call the data dissector for any leftover bytes. */
+ if(tvb_captured_length(tvb) > *offset){
+ call_data_dissector(tvb_new_subset_remaining(tvb, *offset), pinfo, tree);
+ }
+}/* dissect_miwi_connect_tbl_bcast_cmd */
+
+/**
+ * Subdissector routine for MiWi P2P Star commands
+ *
+ * @param tvb pointer to buffer containing the command payload
+ * @param pinfo pointer to packet information fields
+ * @param tree pointer to the protocol tree
+ * @param packet Miwi P2P Star packet information
+ * @param offset offset into the tvb to find the packet information.
+ */
+static void
+dissect_miwi_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, miwi_packet *packet, unsigned *offset)
+{
+ col_append_str(pinfo->cinfo, COL_INFO, val_to_str_const((const uint32_t)packet->command_id, miwi_p2pstar_cmd_names, "Unknown Command"));
+
+ switch (packet->command_id){
+ case MIWI_P2P_CMD_CONN_REQ:
+ dissect_miwi_connect_req(tvb, pinfo, tree, packet,offset);
+ break;
+ case MIWI_P2P_CMD_CONN_RES:
+ dissect_miwi_connect_rsp(tvb, pinfo, tree, packet,offset);
+ break;
+ case MIWI_P2P_CMD_CHANNEL_HOP:
+ dissect_miwi_channel_hop(tvb, pinfo, tree, packet,offset);
+ break;
+ case MIWI_P2P_CMD_ACTIVE_SCAN_REQ:
+ dissect_miwi_active_scan_req(tvb, pinfo, tree, packet,offset);
+ break;
+ case MIWI_P2P_CMD_CONN_REMOVAL_RES:
+ dissect_miwi_connect_removal_res(tvb, pinfo, tree, packet,offset);
+ break;
+ case MIWI_P2P_CMD_ACTIVE_SCAN_RES:
+ dissect_miwi_active_scan_res(tvb, pinfo, tree, packet,offset);
+ break;
+ case MIWI_STAR_CMD_FORWARD_PACKET:
+ dissect_miwi_fwd_packet_cmd(tvb, pinfo, tree, packet,offset);
+ break;
+ case MIWI_STAR_CMD_CONN_TABLE:
+ dissect_miwi_connect_tbl_bcast_cmd(tvb, pinfo, tree, packet,offset);
+ break;
+ case MIWI_P2P_CMD_DATA_REQ:
+ case MIWI_P2P_CMD_CONN_REMOVAL_REQ:
+ case MIWI_STAR_CMD_SOFT_ACK:
+ case MIWI_STAR_CMD_LINK_STATUS:
+ /* No payload expected. */
+ break;
+ default:
+ proto_item_append_text(tree, ", Unknown Command");
+ if(tvb_captured_length_remaining(tvb, 0) > 0){
+ call_data_dissector(tvb, pinfo, tree);
+ break;
+ }
+ }/* switch */
+}/* dissect_miwi_command */
+
+/**
+ * Subdissector routine for MiWi P2P Star header parsing
+ *
+ * @param tvb pointer to buffer containing the command payload
+ * @param pinfo pointer to packet information fields
+ * @param tree pointer to the protocol tree
+ * @param created_header_tree new tree to parse the MiWi packet .
+ * @param parsed_info Miwi P2P Star packet information
+ */
+static unsigned
+miwi_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree **created_header_tree, miwi_packet **parsed_info)
+{
+ proto_tree *miwi_tree = NULL;
+ proto_item *proto_root = NULL;
+ proto_item *hidden_item;
+ proto_item *ti;
+ unsigned offset = 0;
+ bool dstPanPresent = false;
+ bool srcPanPresent = false;
+ miwi_packet *packet = wmem_new0(wmem_packet_scope(), miwi_packet);
+ ieee802154_short_addr addr16;
+ ieee802154_hints_t *ieee_hints;
+
+ packet->short_table = miwi_map.short_table;
+
+ /* Allocate frame data with hints for upper layers */
+ if(!PINFO_FD_VISITED(pinfo) ||
+ (ieee_hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_miwi_p2pstar, 0)) == NULL){
+ ieee_hints = wmem_new0(wmem_file_scope(), ieee802154_hints_t);
+ p_add_proto_data(wmem_file_scope(), pinfo, proto_miwi_p2pstar, 0, ieee_hints);
+ }
+
+ /* Save a pointer to the whole packet */
+ ieee_hints->packet = packet;
+
+ /* Create the protocol tree. */
+ if(tree){
+ proto_root = proto_tree_add_protocol_format(tree, proto_miwi_p2pstar, tvb, 0, tvb_captured_length(tvb), "IEEE 802.15.4-MiWi");
+ miwi_tree = proto_item_add_subtree(proto_root, ett_miwi_p2pstar);
+ }
+ /* Add the protocol name. */
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "MiWi P2P Star");
+
+ /* Set out parameters */
+ *created_header_tree = miwi_tree;
+ *parsed_info = packet;
+
+ /* Add the packet length to the filter field */
+ hidden_item = proto_tree_add_uint(miwi_tree, hf_miwi_frame_length, NULL, 0, 0, tvb_reported_length(tvb));
+ proto_item_set_hidden(hidden_item);
+
+ /* Frame Control Field */
+ dissect_miwi_fcf(tvb, pinfo, miwi_tree, packet, &offset);
+
+ /* Sequence Number */
+ /* IEEE 802.15.4 Sequence Number Suppression */
+ packet->seqno = tvb_get_uint8(tvb, offset);
+ proto_tree_add_uint(miwi_tree, hf_miwi_seq, tvb, offset, 1, packet->seqno);
+ /* For Ack packets display this in the root. */
+ if(packet->frame_type == IEEE802154_FCF_ACK){
+ proto_item_append_text(proto_root, ", Sequence Number: %u", packet->seqno);
+ }
+ offset += 1;
+
+ /*
+ * ADDRESSING FIELDS
+ */
+ /* Clear out the addressing strings. */
+ clear_address(&pinfo->net_dst);
+ clear_address(&pinfo->dl_dst);
+ clear_address(&pinfo->dst);
+ clear_address(&pinfo->net_src);
+ clear_address(&pinfo->dl_src);
+ clear_address(&pinfo->src);
+
+ if(packet->dst_addr_mode == IEEE802154_FCF_ADDR_RESERVED){
+ /* Invalid Destination Address Mode. Abort Dissection. */
+ expert_add_info(pinfo, proto_root, &ei_miwi_dst);
+ return 0;
+ }
+
+ if(packet->src_addr_mode == IEEE802154_FCF_ADDR_RESERVED){
+ /* Invalid Source Address Mode. Abort Dissection. */
+ expert_add_info(pinfo, proto_root, &ei_miwi_src);
+ return 0;
+ }
+
+ if(packet->version == IEEE802154_VERSION_RESERVED){
+ /* Unknown Frame Version. Abort Dissection. */
+ expert_add_info(pinfo, proto_root, &ei_miwi_frame_ver);
+ return 0;
+ }
+ else if((packet->version == IEEE802154_VERSION_2003) || /* For Frame Version 0b00 and */
+ (packet->version == IEEE802154_VERSION_2006)) { /* 0b01 effect defined in section 7.2.1.5 */
+
+ if((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* if both destination and source */
+ (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE)){ /* addressing information is present */
+ if(packet->pan_id_compression == 1){ /* PAN IDs are identical */
+ dstPanPresent = true;
+ srcPanPresent = false; /* source PAN ID is omitted */
+ }
+ else{ /* PAN IDs are different, both shall be included in the frame */
+ dstPanPresent = true;
+ srcPanPresent = true;
+ }
+ }
+ else{
+ if(packet->pan_id_compression == 1){ /* all remaining cases pan_id_compression must be zero */
+ expert_add_info(pinfo, proto_root, &ei_miwi_invalid_panid_compression);
+ return 0;
+ }
+ else{
+ /* only either the destination or the source addressing information is present */
+ if((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE)){ /* Not Present */
+ dstPanPresent = true;
+ srcPanPresent = false;
+ }
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
+ (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE)){ /* Present */
+ dstPanPresent = false;
+ srcPanPresent = true;
+ }
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE)){ /* Not Present */
+ dstPanPresent = false;
+ srcPanPresent = false;
+ }
+ else{
+ expert_add_info(pinfo, proto_root, &ei_miwi_invalid_addressing);
+ return 0;
+ }
+ }
+ }
+ }
+ else if(packet->version == IEEE802154_VERSION_2015){
+ /* for Frame Version 0b10 PAN Id Compression only applies to these frame types */
+ if((packet->frame_type == IEEE802154_FCF_BEACON) ||
+ (packet->frame_type == IEEE802154_FCF_DATA) ||
+ (packet->frame_type == IEEE802154_FCF_ACK) ||
+ (packet->frame_type == IEEE802154_FCF_CMD) ){
+
+ /* Implements Table 7-6 of IEEE 802.15.4-2015
+ *
+ * Destination Address Source Address Destination PAN ID Source PAN ID PAN ID Compression
+ *-------------------------------------------------------------------------------------------------
+ * 1. Not Present Not Present Not Present Not Present 0
+ * 2. Not Present Not Present Present Not Present 1
+ * 3. Present Not Present Present Not Present 0
+ * 4. Present Not Present Not Present Not Present 1
+ *
+ * 5. Not Present Present Not Present Present 0
+ * 6. Not Present Present Not Present Not Present 1
+ *
+ * 7. Extended Extended Present Not Present 0
+ * 8. Extended Extended Not Present Not Present 1
+ *
+ * 9. Short Short Present Present 0
+ * 10. Short Extended Present Present 0
+ * 11. Extended Short Present Present 0
+ *
+ * 12. Short Extended Present Not Present 1
+ * 13. Extended Short Present Not Present 1
+ * 14. Short Short Present Not Present 1
+ */
+
+ /* Row 1 */
+ if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
+ (packet->pan_id_compression == 0)){
+ dstPanPresent = false;
+ srcPanPresent = false;
+ }
+ /* Row 2 */
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
+ (packet->pan_id_compression == 1)){
+ dstPanPresent = true;
+ srcPanPresent = false;
+ }
+ /* Row 3 */
+ else if((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
+ (packet->pan_id_compression == 0)){
+ dstPanPresent = true;
+ srcPanPresent = false;
+ }
+ /* Row 4 */
+ else if((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
+ (packet->pan_id_compression == 1)){
+ dstPanPresent = false;
+ srcPanPresent = false;
+ }
+ /* Row 5 */
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
+ (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */
+ (packet->pan_id_compression == 0)){
+ dstPanPresent = false;
+ srcPanPresent = true;
+ }
+ /* Row 6 */
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
+ (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */
+ (packet->pan_id_compression == 1)){
+ dstPanPresent = false;
+ srcPanPresent = false;
+ }
+ /* Row 7 */
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
+ (packet->pan_id_compression == 0)){
+ dstPanPresent = true;
+ srcPanPresent = false;
+ }
+ /* Row 8 */
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
+ (packet->pan_id_compression == 1)){
+ dstPanPresent = false;
+ srcPanPresent = false;
+ }
+ /* Row 9 */
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
+ (packet->pan_id_compression == 0)){
+ dstPanPresent = true;
+ srcPanPresent = true;
+ }
+ /* Row 10 */
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
+ (packet->pan_id_compression == 0)){
+ dstPanPresent = true;
+ srcPanPresent = true;
+ }
+ /* Row 11 */
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
+ (packet->pan_id_compression == 0)){
+ dstPanPresent = true;
+ srcPanPresent = true;
+ }
+ /* Row 12 */
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
+ (packet->pan_id_compression == 1)){
+ dstPanPresent = true;
+ srcPanPresent = false;
+ }
+ /* Row 13 */
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
+ (packet->pan_id_compression == 1)){
+ dstPanPresent = true;
+ srcPanPresent = false;
+ }
+ /* Row 14 */
+ else if((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
+ (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
+ (packet->pan_id_compression == 1)){
+ dstPanPresent = true;
+ srcPanPresent = false;
+ }
+ else{
+ expert_add_info(pinfo, proto_root, &ei_miwi_invalid_panid_compression2);
+ return 0;
+ }
+ }
+ else{ /* Frame Type is neither Beacon, Data, Ack, nor Command: PAN ID Compression is not used */
+ dstPanPresent = false; /* no PAN ID will */
+ srcPanPresent = false; /* be present */
+ }
+ }
+ else{
+ /* Unknown Frame Version. Abort Dissection. */
+ expert_add_info(pinfo, proto_root, &ei_miwi_frame_ver);
+ return 0;
+ }
+
+ /*
+ * Addressing Fields
+ */
+
+ /* Destination PAN Id */
+ if(dstPanPresent){
+ char* pan_id = (char *)wmem_new(pinfo->pool, uint64_t);
+
+ packet->dst_pan = tvb_get_letohs(tvb, offset);
+ miwi_short_to_str(packet->dst_pan,pan_id,10);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Pan ID: %s", pan_id);
+ proto_tree_add_uint(miwi_tree, hf_miwi_dst_panid, tvb, offset, 2, packet->dst_pan);
+ offset += 2;
+ }
+
+ /* Destination Address */
+ if(packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT){
+ char* dst_addr = (char *)wmem_new(pinfo->pool, uint64_t);
+
+ /* Get the address. */
+ packet->dst16 = tvb_get_letohs(tvb, offset);
+
+ /* Provide address hints to higher layers that need it. */
+ if(ieee_hints){
+ ieee_hints->dst16 = packet->dst16;
+ }
+
+ set_address_tvb(&pinfo->dl_dst, miwi_short_address_type, 2, tvb, offset);
+ copy_address_shallow(&pinfo->dst, &pinfo->dl_dst);
+ miwi_short_to_str(packet->dst16,dst_addr,10);
+
+ proto_tree_add_uint(miwi_tree, hf_miwi_short_dst_addr, tvb, offset, 2, packet->dst16);
+ proto_item_append_text(proto_root, ", Dst: %s", dst_addr);
+ ti = proto_tree_add_uint(miwi_tree, hf_miwi_addr16, tvb, offset, 2, packet->dst16);
+ proto_item_set_generated(ti);
+ proto_item_set_hidden(ti);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", dst_addr);
+ offset += 2;
+ }
+ else if(packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT){
+ uint64_t *p_addr = (uint64_t *)wmem_new(pinfo->pool, uint64_t);
+
+ /* Get the address */
+ packet->dst64 = tvb_get_letoh64(tvb, offset);
+
+ /* Copy and convert the address to network byte order. */
+ *p_addr = pntoh64(&(packet->dst64));
+
+ /* Display the destination address. */
+ /* XXX - OUI resolution doesn't happen when displaying resolved
+ * EUI64 addresses; that should probably be fixed in
+ * epan/addr_resolv.c.
+ */
+ set_address(&pinfo->dl_dst, AT_EUI64, 8, p_addr);
+ copy_address_shallow(&pinfo->dst, &pinfo->dl_dst);
+ if(tree){
+ proto_tree_add_item(miwi_tree, hf_miwi_ext_dst_addr, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(proto_root, ", Dst: %s", eui64_to_display(wmem_packet_scope(), packet->dst64));
+ ti = proto_tree_add_item(miwi_tree, hf_miwi_addr64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ proto_item_set_generated(ti);
+ proto_item_set_hidden(ti);
+ }
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", eui64_to_display(wmem_packet_scope(), packet->dst64));
+ offset += 8;
+ }
+
+ /* Source PAN Id */
+ if(srcPanPresent){
+ char* pan_id = (char *)wmem_new(pinfo->pool, uint64_t);
+ packet->src_pan = tvb_get_letohs(tvb, offset);
+ miwi_short_to_str(packet->src_pan,pan_id,10);
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Src Pan ID: %s", pan_id);
+ proto_tree_add_uint(miwi_tree, hf_miwi_src_panid, tvb, offset, 2, packet->src_pan);
+ offset += 2;
+ }
+ else{
+ if(dstPanPresent){
+ packet->src_pan = packet->dst_pan;
+ }
+ else{
+ packet->src_pan = IEEE802154_BCAST_PAN;
+ }
+ }
+ if(ieee_hints){
+ ieee_hints->src_pan = packet->src_pan;
+ }
+
+ /* Source Address */
+ if(packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT){
+ char* src_addr = (char *)wmem_new(pinfo->pool, uint64_t);
+
+ /* Get the address. */
+ packet->src16 = tvb_get_letohs(tvb, offset);
+
+ if(!PINFO_FD_VISITED(pinfo)){
+ /* If we know our extended source address from previous packets,
+ * provide a pointer to it in a hint for upper layers */
+ addr16.addr = packet->src16;
+ addr16.pan = packet->src_pan;
+
+ if(ieee_hints){
+ ieee_hints->src16 = packet->src16;
+ ieee_hints->map_rec = (ieee802154_map_rec *)
+ g_hash_table_lookup(miwi_map.short_table, &addr16);
+ }
+ }
+
+ set_address_tvb(&pinfo->dl_src, miwi_short_address_type, 2, tvb, offset);
+ copy_address_shallow(&pinfo->src, &pinfo->dl_src);
+ miwi_short_to_str(packet->src16,src_addr,10);
+
+ /* Add the addressing info to the tree. */
+ if(tree){
+ proto_tree_add_uint(miwi_tree, hf_miwi_short_src_addr, tvb, offset, 2, packet->src16);
+ proto_item_append_text(proto_root, ", Src: %s", src_addr);
+ ti = proto_tree_add_uint(miwi_tree, hf_miwi_addr16, tvb, offset, 2, packet->src16);
+ proto_item_set_generated(ti);
+ proto_item_set_hidden(ti);
+
+ if(ieee_hints && ieee_hints->map_rec){
+ /* Display inferred source address info */
+ ti = proto_tree_add_eui64(miwi_tree, hf_miwi_short_src_addr, tvb, offset, 0,
+ ieee_hints->map_rec->addr64);
+ proto_item_set_generated(ti);
+ ti = proto_tree_add_eui64(miwi_tree, hf_miwi_addr64, tvb, offset, 0, ieee_hints->map_rec->addr64);
+ proto_item_set_generated(ti);
+ proto_item_set_hidden(ti);
+
+ if( ieee_hints->map_rec->start_fnum ){
+ ti = proto_tree_add_uint(miwi_tree, hf_miwi_src64_origin, tvb, 0, 0,
+ ieee_hints->map_rec->start_fnum);
+ }
+ else{
+ ti = proto_tree_add_uint_format_value(miwi_tree, hf_miwi_src64_origin, tvb, 0, 0,
+ ieee_hints->map_rec->start_fnum, "Pre-configured");
+ }
+ proto_item_set_generated(ti);
+ }
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", src_addr);
+
+ offset += 2;
+ }
+ else if(packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT){
+ uint64_t *p_addr = (uint64_t *)wmem_new(pinfo->pool, uint64_t);
+
+ /* Get the address. */
+ packet->src64 = tvb_get_letoh64(tvb, offset);
+
+ /* Copy and convert the address to network byte order. */
+ *p_addr = pntoh64(&(packet->src64));
+
+ /* Display the source address. */
+ /* XXX - OUI resolution doesn't happen when displaying resolved
+ * EUI64 addresses; that should probably be fixed in
+ * epan/addr_resolv.c.
+ */
+ set_address(&pinfo->dl_src, AT_EUI64, 8, p_addr);
+ copy_address_shallow(&pinfo->src, &pinfo->dl_src);
+ if(tree){
+ proto_tree_add_item(miwi_tree, hf_miwi_ext_src_addr, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(proto_root, ", Src: %s", eui64_to_display(wmem_packet_scope(), packet->src64));
+ ti = proto_tree_add_item(miwi_tree, hf_miwi_addr64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ proto_item_set_generated(ti);
+ proto_item_set_hidden(ti);
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", eui64_to_display(wmem_packet_scope(), packet->src64));
+ offset += 8;
+ }
+
+ /* All of the beacon fields, except the beacon payload are considered nonpayload. */
+ if((packet->version == IEEE802154_VERSION_2003) || (packet->version == IEEE802154_VERSION_2006)){
+
+ if(packet->frame_type == IEEE802154_FCF_CMD){
+ /**
+ * In IEEE802.15.4-2003 and 2006 the command identifier is considered to be part of the header
+ * and is thus not encrypted. For IEEE802.15.4-2012e and later the command id is considered to be
+ * part of the payload, is encrypted, and follows the payload IEs. Thus we only parse the command id
+ * here for 2006 and earlier frames. */
+ packet->command_id = tvb_get_uint8(tvb, offset);
+ if(tree){
+ proto_tree_add_uint(miwi_tree, hf_miwi_cmd_id, tvb, offset, 1, packet->command_id);
+ }
+ offset++;
+ }
+ }
+ return offset;
+}/*miwi_dissect_header*/
+
+/**
+ * Subdissector routine for MiWi P2P Star frame payload parsing
+ *
+ * @param tvb pointer to buffer containing the command payload
+ * @param pinfo pointer to packet information fields
+ * @param ieee802154_tree pointer to the protocol tree
+ * @param packet Miwi P2P Star packet information
+ * @param fcs_ok set to false to indicate FCS verification failed
+ * @param offset offset into the tvb to find the packet information.
+ */
+static unsigned miwi_dissect_frame_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ieee802154_tree, miwi_packet *packet, bool fcs_ok, unsigned *offset)
+{
+ tvbuff_t *payload_tvb = tvb;
+ proto_tree *tree = proto_tree_get_parent_tree(ieee802154_tree);
+ //heur_dtbl_entry_t *hdtbl_entry;
+
+ /* There are commands without payload */
+ if(tvb_captured_length(payload_tvb) > 0 || packet->frame_type == IEEE802154_FCF_CMD){
+ /*
+ * Wrap the sub-dissection in a try/catch block in case the payload is
+ * broken. First we store the current protocol so we can fix it if an
+ * exception is thrown by the subdissectors.
+ */
+ const char* saved_proto = pinfo->current_proto;
+ /* Try to dissect the payload. */
+ TRY {
+ switch (packet->frame_type){
+ case IEEE802154_FCF_BEACON:
+ call_data_dissector(tvb_new_subset_remaining(tvb, *offset), pinfo, tree);
+ break;
+
+ case IEEE802154_FCF_CMD:
+ dissect_miwi_command(payload_tvb, pinfo, ieee802154_tree, packet,offset);
+ break;
+
+ case IEEE802154_FCF_DATA:
+ /* Sanity-check. */
+ if((!fcs_ok && miwi_fcs_ok) || !tvb_reported_length(payload_tvb)){
+ call_data_dissector(tvb_new_subset_remaining(tvb, *offset), pinfo, tree);
+ }
+ break;
+ default:
+ /* Could not subdissect, call the data dissector instead. */
+ call_data_dissector(tvb_new_subset_remaining(tvb, *offset), pinfo, tree);
+ break;
+ }/* switch */
+ }
+ CATCH_ALL {
+ /*
+ * Someone encountered an error while dissecting the payload. But
+ * we haven't yet finished processing all of our layer. Catch and
+ * display the exception, then fall-through to finish displaying
+ * the FCS (which we display last so the frame is ordered correctly
+ * in the tree).
+ */
+ show_exception(payload_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
+ pinfo->current_proto = saved_proto;
+ }
+ ENDTRY;
+ }
+ return tvb_captured_length(tvb);
+}
+
+#if 0
+/**
+ * Dissect the FCS at the end of the frame.
+ * That is only displayed if the included length of the tvb encompasses it.
+ *
+ * @param tvb the MiWi P2P Star frame tvb
+ * @param ieee802154_tree the MiWi P2P Star protocol tree
+ * @param fcs_len length of the FCS field
+ * @param fcs_ok set to false to indicate FCS verification failed
+ */
+static void
+miwi_dissect_fcs(tvbuff_t *tvb, proto_tree *ieee802154_tree, unsigned fcs_len, bool fcs_ok)
+{
+ proto_item *ti;
+ /* The FCS should be the last bytes of the reported packet. */
+ unsigned offset = tvb_reported_length(tvb)-fcs_len;
+ /* Dissect the FCS only if it exists (captures which don't or can't get the
+ * FCS will simply truncate the packet to omit it, but should still set the
+ * reported length to cover the original packet length), so if the snapshot
+ * is too short for an FCS don't make a fuss.
+ */
+ if(ieee802154_tree){
+ if(fcs_len == 2){
+ uint16_t fcs = tvb_get_letohs(tvb, offset);
+
+ ti = proto_tree_add_uint(ieee802154_tree, hf_miwi_fcs, tvb, offset, 2, fcs);
+ if(fcs_ok){
+ proto_item_append_text(ti, " (Correct)");
+ }
+ else{
+ proto_item_append_text(ti, " (Incorrect, expected FCS=0x%04x)", miwi_crc_tvb(tvb, offset));
+ }
+ /* To Help with filtering, add the fcs_ok field to the tree. */
+ ti = proto_tree_add_boolean(ieee802154_tree, hf_miwi_fcs_ok, tvb, offset, 2, (uint32_t) fcs_ok);
+ proto_item_set_hidden(ti);
+ }
+ }
+}/* miwi_dissect_fcs */
+#endif
+
+/**
+ * MiWi P2P Star packet dissection routine for Wireshark.
+ *
+ * This function extracts all the information first before displaying.
+ * If payload exists, that portion will be passed into another dissector
+ * for further processing.
+ *
+ * This is called after the individual dissect_p2pstar* functions
+ * have been called to determine what sort of FCS is present, if any.
+ *
+ * @param tvb pointer to buffer containing raw packet.
+ * @param pinfo pointer to packet information fields
+ * @param fcs_len length of the FCS field
+ */
+static void
+dissect_miwi_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned fcs_len)
+{
+ proto_tree *miwi_tree;
+ miwi_packet *packet;
+ //bool fcs_present;
+ bool fcs_ok;
+ tvbuff_t* no_fcs_tvb;
+ unsigned offset = 0;
+
+ if(fcs_len != 0){
+ /*
+ * Well, this packet should, in theory, have an FCS or CC24xx
+ * metadata.
+ * Do we have the entire packet, and does it have enough data for
+ * the FCS/metadata?
+ */
+ unsigned reported_len = tvb_reported_length(tvb);
+
+ if(reported_len < fcs_len){
+ /*
+ * The packet is claimed not to even have enough data
+ * for the FCS/metadata. Pretend it doesn't have one.
+ */
+ no_fcs_tvb = tvb;
+ //fcs_present = false;
+ fcs_ok = true; // assume OK if not present
+ } else{
+ /*
+ * The packet is claimed to have enough data for the
+ * FCS/metadata.
+ * Slice it off from the reported length.
+ */
+ reported_len -= fcs_len;
+ no_fcs_tvb = tvb_new_subset_length(tvb, 0, reported_len);
+
+ /*
+ * Is the FCS/metadata present in the captured data?
+ * reported_len is now the length of the packet without the
+ * FCS/metadata, so the FCS/metadata begins at an offset of
+ * reported_len.
+ */
+ if(tvb_bytes_exist(tvb, reported_len, fcs_len)){
+ /*
+ * Yes. Check whether the FCS was OK.
+ *
+ * If we have an FCS, check it.
+ * If we have metadata, check its "FCS OK" flag.
+ */
+ //fcs_present = true;
+ fcs_ok = is_fcs_ok(tvb, fcs_len);
+ } else{
+ /*
+ * No.
+ *
+ * Either 1) this means that there was a snapshot length
+ * in effect when the capture was done, and that sliced
+ * some or all of the FCS/metadata off or 2) this is a
+ * capture with no FCS/metadata, using the same link-layer
+ * header type value as captures with the FCS/metadata,
+ * and indicating the lack of the FCS/metadata by having
+ * the captured length be the length of the packet minus
+ * the length of the FCS/metadata and the actual length
+ * being the length of the packet including the FCS/metadata,
+ * rather than by using the "no FCS" link-layer header type.
+ *
+ * We could try to distinguish between them by checking
+ * for a captured length that's exactly fcs_len bytes
+ * less than the actual length. That would allow us to
+ * report packets that are cut short just before, or in
+ * the middle of, the FCS as having been cut short by the
+ * snapshot length.
+ *
+ * However, we can't distinguish between a packet that
+ * happened to be cut fcs_len bytes short due to a
+ * snapshot length being in effect when the capture was
+ * done and a packet that *wasn't* cut short by a snapshot
+ * length but that doesn't include the FCS/metadata.
+ * Let's hope that rarely happens.
+ */
+ //fcs_present = false;
+ fcs_ok = true; // assume OK if not present
+ }
+ }
+ } else{
+ no_fcs_tvb = tvb;
+ //fcs_present = false;
+ fcs_ok = true; // assume OK if not present
+ }
+
+ unsigned mhr_len = miwi_dissect_header(no_fcs_tvb, pinfo, tree, &miwi_tree, &packet);
+ offset = mhr_len;
+ if(!mhr_len || tvb_reported_length_remaining(no_fcs_tvb, mhr_len) < 0 ){
+ return;
+ }
+
+ if(packet->frame_type == IEEE802154_FCF_DATA){
+ if((!fcs_ok && miwi_fcs_ok)){
+ call_data_dissector(tvb, pinfo, tree);
+ }
+ } else{
+ miwi_dissect_frame_payload(tvb, pinfo, miwi_tree, packet, fcs_ok, &offset);
+ }
+}
+
+/**
+ * Dissector for MiWi P2P Star packet with an FCS containing a 16/32-bit
+ * CRC value at the end.
+ *
+ * @param tvb pointer to buffer containing raw packet.
+ * @param pinfo pointer to packet information fields.
+ * @param tree pointer to data tree wireshark uses to display packet.
+ */
+static int
+dissect_miwi_p2pstar(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ unsigned fcs_len;
+
+ /* Set the default FCS length based on the FCS type in the configuration */
+ // fcs_len = miwi_fcs_type_len(miwi_fcs_type);
+ // unsigned offset = 0;
+ proto_tree *miwi_tree = NULL;
+ proto_item *proto_root = NULL;
+ // miwi_packet *packet = wmem_new0(wmem_packet_scope(), miwi_packet);
+
+ /* Set the default FCS length based on the FCS type in the configuration */
+ fcs_len = miwi_fcs_type_len(miwi_fcs_type);
+
+ /* Call the common dissector. */
+ // dissect_miwi_common1(tvb, pinfo, tree);//, fcs_len);
+ /* Create the protocol tree. */
+ if (tree) {
+ proto_root = proto_tree_add_protocol_format(tree, proto_miwi_p2pstar, tvb, 0, tvb_captured_length(tvb), "MiWi P2PStar Protocol");
+ miwi_tree = proto_item_add_subtree(proto_root, ett_miwi_p2pstar);
+ }
+ /*Enter name of protocol to info field*/
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "MiWi P2PStar");
+ /* Call the common dissector. */
+ dissect_miwi_common(tvb, pinfo, miwi_tree, fcs_len);
+ return tvb_captured_length(tvb);
+}/* dissect_miwi_p2pstar */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_miwimesh_heur
+ * DESCRIPTION
+ * Heuristic interpreter for the Lightweight Mesh.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_into *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
+ * RETURNS
+ * Boolean value, whether it handles the packet or not.
+ *---------------------------------------------------------------
+ */
+static bool
+dissect_miwi_p2pstar_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+#if 0
+ uint8_t endpt, srcep, dstep;
+
+ /* 1) first byte must have bits 0000xxxx */
+ if(tvb_get_uint8(tvb, 0) & LWM_FCF_RESERVED)
+ return (false);
+
+ /* The header should be at least long enough for the base header. */
+ if (tvb_reported_length(tvb) < LWM_HEADER_BASE_LEN)
+ return (false);
+
+ /* The endpoints should either both be zero, or both non-zero. */
+ endpt = tvb_get_uint8(tvb, 6);
+ srcep = (endpt & LWM_SRC_ENDP_MASK) >> LWM_SRC_ENDP_OFFSET;
+ dstep = (endpt & LWM_DST_ENDP_MASK) >> LWM_DST_ENDP_OFFSET;
+ if ((srcep == 0) && (dstep != 0))
+ return (false);
+ if ((srcep != 0) && (dstep == 0))
+ return (false);
+#endif
+ dissect_miwi_p2pstar(tvb, pinfo, tree, data);
+ return (true);
+} /* dissect_lwm_heur */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * proto_register_miwi_p2pstar
+ * DESCRIPTION
+ * MiWi P2P Star protocol registration routine.
+ * PARAMETERS
+ * none
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void proto_register_miwi_p2pstar(void)
+{
+
+ static hf_register_info hf[] = {
+
+ { &hf_miwi_frame_length,
+ { "Frame Length", "miwi_p2pstar.frame_length", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "Frame Length as reported from lower layer", HFILL }},
+
+ { &hf_miwi_fcf,
+ { "Frame Control Field", "miwi_p2pstar.fcf", FT_UINT16, BASE_HEX, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_miwi_fcf_frame_type,
+ { "Frame Type", "miwi_p2pstar.type", FT_UINT16, BASE_HEX, VALS(miwi_mac_frame_types),
+ MIWI_MAC_FCF_FRAME_TYPE, NULL, HFILL }},
+
+ { &hf_miwi_fcf_security_enabled,
+ { "Security Enabled", "miwi_p2pstar.security_enable", FT_BOOLEAN, 16, NULL, MIWI_MAC_FCF_SECURITY_EN,
+ "Whether security operations are performed at the MAC layer or not.", HFILL }},
+
+ { &hf_miwi_fcf_frame_pending,
+ { "Frame Pending", "miwi_p2pstar.pending", FT_BOOLEAN, 16, NULL, MIWI_MAC_FCF_FRAME_PENDING,
+ "Indication of additional packets waiting to be transferred from the source device.", HFILL }},
+
+ { &hf_miwi_fcf_ack_req,
+ { "Acknowledge Request", "miwi_p2pstar.ack_request", FT_BOOLEAN, 16, NULL, MIWI_MAC_FCF_ACK_REQUEST,
+ "Whether the sender of this packet requests acknowledgment or not.", HFILL }},
+
+ { &hf_miwi_fcf_panid_comp,
+ { "PAN ID Compression", "miwi_p2pstar.pan_id_compression", FT_BOOLEAN, 16, NULL, MIWI_MAC_FCF_PANID_COMP,
+ "Whether this packet contains the PAN ID or not.", HFILL }},
+
+ { &hf_miwi_fcf_reserved,
+ { "Reserved", "miwi_p2pstar.fcf.reserved", FT_UINT16, BASE_HEX, NULL, MIWI_MAC_FCF_RESERVED,
+ NULL, HFILL }},
+
+ { &hf_miwi_seq,
+ { "Sequence Number", "miwi_p2pstar.seq_no", FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_fcf_dest_addr_mode,
+ { "Destination Addressing Mode", "miwi_p2pstar.dst_addr_mode", FT_UINT16, BASE_HEX, VALS(miwi_addr_modes),
+ MIWI_MAC_FCF_DEST_ADDR_MODE, NULL, HFILL }},
+
+ { &hf_miwi_fcf_src_addr_mode,
+ { "Source Addressing Mode", "miwi_p2pstar.src_addr_mode", FT_UINT16, BASE_HEX, VALS(miwi_addr_modes),
+ MIWI_MAC_FCF_SRC_ADDR_MODE, NULL, HFILL }},
+
+ { &hf_miwi_fcf_frame_version,
+ { "Frame Version", "miwi_p2pstar.version", FT_UINT16, BASE_DEC, VALS(miwi_frame_versions),
+ MIWI_MAC_FCF_FRAME_VERSION, NULL, HFILL }},
+
+ { &hf_miwi_dst_panid,
+ { "Destination PAN", "miwi_p2pstar.dst_pan", FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_short_dst_addr,
+ { "Destination", "miwi_p2pstar.dst16", FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_ext_dst_addr,
+ { "Destination", "miwi_p2pstar.dst64", FT_EUI64, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_src_panid,
+ { "Source PAN", "miwi_p2pstar.src_pan", FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_short_src_addr,
+ { "Source", "miwi_p2pstar.src16", FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_ext_src_addr,
+ { "Extended Source", "miwi_p2pstar.src64", FT_EUI64, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_addr16,
+ { "Address", "miwi_p2pstar.addr16", FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_addr64,
+ { "Extended Address", "miwi_p2pstar.addr64", FT_EUI64, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_src64_origin,
+ { "Origin", "miwi_p2pstar.src64.origin", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+#if 0
+ { &hf_miwi_fcs,
+ { "FCS", "miwi_p2pstar.fcs", FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_fcs_ok,
+ { "FCS Valid", "miwi_p2pstar.fcs_ok", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+#endif
+
+ { &hf_miwi_cmd_id,
+ { "Command Identifier", "miwi_p2pstar.cmd", FT_UINT8, BASE_HEX, VALS(miwi_p2pstar_cmd_names), 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_cap_info,
+ { "Capability Information", "miwi_p2pstar.cap_info", FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_cap_info_rcv_on_idle,
+ { "Receiver On When Idle", "miwi_p2pstar.recv_on_when_idle", FT_BOOLEAN, 16, NULL, MIWI_CAP_INFO_RCV_ON_IDLE,
+ NULL, HFILL }},
+
+ { &hf_miwi_cap_info_rqst_data_on_wp,
+ { "Request Data On Wake-up", "miwi_p2pstar.req_data_on_wakeup", FT_BOOLEAN, 16, NULL, MIWI_CAP_INFO_REQ_DATA_ON_WP,
+ NULL, HFILL }},
+
+ { &hf_miwi_cap_info_need_time_sync,
+ { "Need Time Synchronization", "miwi_p2pstar.need_time_sync", FT_BOOLEAN, 16, NULL, MIWI_CAP_INFO_NEED_TIME_SYNC,
+ NULL, HFILL }},
+
+ { &hf_miwi_cap_info_security_cap,
+ { "Security Capable", "miwi_p2pstar.security_capable", FT_BOOLEAN, 16, NULL, MIWI_CAP_INFO_SECURITY_CAP,
+ NULL, HFILL }},
+
+ { &hf_miwi_cap_info_reserved,
+ { "Reserved", "miwi_p2pstar.cap_info.reserved", FT_UINT16, BASE_HEX, NULL, MIWI_CAP_INFO_RESERVED,
+ NULL, HFILL }},
+
+ { &hf_miwi_oper_chan,
+ { "Connection Request Operating Channel", "miwi_p2pstar.con_req_chan", FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_conn_res_status,
+ { "Connection Response Status", "miwi_p2pstar.con_res_status", FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_current_op_channel,
+ { "Channel Hop Current Operating Channel", "miwi_p2pstar.hop_op_chan", FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_dst_channel_to_jump_to,
+ { "Destination Channel to Jump to", "miwi_p2pstar.chan_jump_to", FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_conn_rmv_res_status,
+ { "Connection Removal Response Status", "miwi_p2pstar.con_rmvl_res_status", FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_fwd_pkt_dst_addr,
+ { "Forward Packet Command Destination Address", "miwi_p2pstar.fwd_pkt_dst-addr", FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_miwi_conn_tbl_size,
+ { "Connection Table Size", "miwi_p2pstar.conn_tbl_size", FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ };
+
+
+ /* Subtrees */
+ static int *ett[] = {
+ &ett_miwi_p2pstar,
+ &ett_miwi_p2pstar_fcf,
+ &ett_miwi_p2pstar_cmd_tree,
+ &ett_miwi_p2pstar_cap_info,
+ &ett_miwi_fcs,
+ };
+
+ static ei_register_info ei[] = {
+ //{ &ei_miwi_empty_payload, { "miwi_p2pstar.empty_payload", PI_MALFORMED, PI_ERROR, "Empty MiWi Payload!", EXPFILL }},
+ { &ei_miwi_frame_ver, { "miwi_p2pstar.frame_version_error", PI_COMMENTS_GROUP, PI_NOTE, "Source address can not be broadcast address !", EXPFILL }},
+ { &ei_miwi_dst, { "miwi_p2pstar.dst_addr_error", PI_COMMENTS_GROUP, PI_WARN, "destination address Error ", EXPFILL }},
+ { &ei_miwi_src, { "miwi_p2pstar.src_addr_error", PI_COMMENTS_GROUP, PI_WARN, "Source address Error ", EXPFILL }},
+ { &ei_miwi_invalid_addressing, { "miwi_p2pstar.invalid_addr_error", PI_PROTOCOL, PI_NOTE, "Invalid Address Error", EXPFILL }},
+ { &ei_miwi_invalid_panid_compression, { "miwi_p2pstar.invalid_panid_comp_error", PI_PROTOCOL, PI_WARN, "Panid compression error", EXPFILL }},
+ { &ei_miwi_invalid_panid_compression2, { "miwi_p2pstar.invalid_panid_comp2_error", PI_PROTOCOL, PI_WARN, "Panid2 compression error", EXPFILL }},
+// { &ei_miwi_fcs, { "miwi_p2pstar.fcs.bad", PI_CHECKSUM, PI_WARN, "Bad FCS", EXPFILL }},
+ };
+
+ static const enum_val_t fcs_type_vals[] = {
+ {"16", "CRC -16 BIT", MIWI_P2PSTAR_FCS_16_BIT},
+ {NULL, NULL, -1}
+ };
+
+ static build_valid_func miwi_da_build_value[1] = {miwi_da_value};
+ static decode_as_value_t miwi_da_values = {miwi_da_prompt, 1, miwi_da_build_value};
+ static decode_as_t miwi_da = {
+ IEEE802154_PROTOABBREV_WPAN, IEEE802154_PROTOABBREV_WPAN_PANID,
+ 1, 0, &miwi_da_values, NULL, NULL,
+ decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change,NULL
+ };
+
+ module_t *miwi_p2pstar_module;
+ expert_module_t* expert_miwi_p2pstar;
+
+ /* Register the protocol name and description */
+ proto_miwi_p2pstar = proto_register_protocol("MiWi P2P Star (v6.4)", "MiWi_P2PStar", "miwi_p2pstar");
+
+ /* Required function calls to register the header fields and subtree used */
+ proto_register_field_array(proto_miwi_p2pstar, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ expert_miwi_p2pstar = expert_register_protocol(proto_miwi_p2pstar);
+ expert_register_field_array(expert_miwi_p2pstar, ei, array_length(ei));
+
+ miwi_short_address_type = address_type_dissector_register("AT_IEEE_802_15_4_SHORT", "IEEE 802.15.4 16-bit short address", miwi_short_address_to_str, miwi_short_address_str_len, NULL, NULL, miwi_short_address_len, NULL, NULL);
+
+ /* add a user preference to set the 802.15.4 ethertype */
+ miwi_p2pstar_module = prefs_register_protocol(proto_miwi_p2pstar,
+ proto_reg_handoff_miwi_p2pstar);
+ prefs_register_uint_preference(miwi_p2pstar_module, "miwi_ethertype",
+ "802.15.4 Ethertype (in hex)",
+ "(Hexadecimal) Ethertype used to indicate IEEE 802.15.4 frame.",
+ 16, &miwi_ethertype);
+ prefs_register_enum_preference(miwi_p2pstar_module, "fcs_format",
+ "FCS format",
+ "The FCS format in the captured payload",
+ &miwi_fcs_type, fcs_type_vals, false);
+ prefs_register_bool_preference(miwi_p2pstar_module, "miwi_fcs_ok",
+ "Dissect only good FCS",
+ "Dissect payload only if FCS is valid.",
+ &miwi_fcs_ok);
+ prefs_register_bool_preference(miwi_p2pstar_module, "miwi_ack_tracking",
+ "Enable ACK tracking",
+ "Match frames with ACK request to ACK packets",
+ &miwi_ack_tracking);
+
+ miwi_p2pstar_handle = register_dissector("miwi_p2pstar", dissect_miwi_p2pstar, proto_miwi_p2pstar);
+ /* Register a Decode-As handler */
+ register_decode_as(&miwi_da);
+}/* proto_register_miwi_p2pstar */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * proto_reg_handoff_miwi_p2pstar
+ * DESCRIPTION
+ * Registers the miwi_p2pstar dissector with Wireshark.
+ * Will be called during Wireshark startup.
+ * PARAMETERS
+ * none
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void proto_reg_handoff_miwi_p2pstar(void)
+{
+#if 0
+ static bool prefs_initialized = false;
+ static unsigned int old_miwi_ethertype;
+
+ if(!prefs_initialized){
+ dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4, miwi_p2pstar_handle);
+
+ prefs_initialized = true;
+ } else{
+ dissector_delete_uint("ethertype", old_miwi_ethertype, miwi_p2pstar_handle);
+ }
+
+ old_miwi_ethertype = miwi_ethertype;
+
+ /* Register dissector handles. */
+ dissector_add_uint("ethertype", miwi_ethertype, miwi_p2pstar_handle);
+#endif
+ /* Register our dissector with IEEE 802.15.4 */
+ dissector_add_for_decode_as(IEEE802154_PROTOABBREV_WPAN_PANID, miwi_p2pstar_handle);
+ heur_dissector_add(IEEE802154_PROTOABBREV_WPAN, dissect_miwi_p2pstar_heur, "Miwi P2PStar over IEEE 802.15.4", "miwip2pstar", proto_miwi_p2pstar, HEURISTIC_DISABLE);
+}/* proto_reg_handoff_miwi_p2pstar */
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */