diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-19 04:14:53 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-19 04:14:53 +0000 |
commit | a86c5f7cae7ec9a3398300555a0b644689d946a1 (patch) | |
tree | 39fe4b107c71174fd1e8a8ceb9a4d2aa14116248 /epan/dissectors/packet-miwi-p2pstar.c | |
parent | Releasing progress-linux version 4.2.6-1~progress7.99u1. (diff) | |
download | wireshark-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.c | 1904 |
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: + */ |