From 4190fcd94a166852138aa381a2a9050ae84d08a2 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Fri, 16 Aug 2024 21:49:53 -0400 Subject: [PATCH] wireshark: add support for an IEEE 802.15.4 TAP Header, using a new ZIGBEE_TAP link type This check for an optional "channel" key in the pmt dict, and adds an additional TLV to the TAP header. --- grc/foo_wireshark_connector.block.yml | 4 +- include/foo/wireshark_connector.h | 3 +- lib/wireshark_connector_impl.cc | 53 +++++++++++++++++++ lib/wireshark_connector_impl.h | 29 ++++++++++ .../wireshark_connector_pydoc_template.h | 13 ++--- python/bindings/wireshark_connector_python.cc | 43 ++++++--------- 6 files changed, 107 insertions(+), 38 deletions(-) diff --git a/grc/foo_wireshark_connector.block.yml b/grc/foo_wireshark_connector.block.yml index 433397d..be33e84 100644 --- a/grc/foo_wireshark_connector.block.yml +++ b/grc/foo_wireshark_connector.block.yml @@ -9,8 +9,8 @@ parameters: label: Technology dtype: enum default: '127' - options: ['127', '195'] - option_labels: [WiFi, ZigBee] + options: ['127', '195', '283'] + option_labels: [WiFi, ZigBee, ZigBeeTap] - id: debug label: Debug dtype: bool diff --git a/include/foo/wireshark_connector.h b/include/foo/wireshark_connector.h index fad973c..34f84b1 100644 --- a/include/foo/wireshark_connector.h +++ b/include/foo/wireshark_connector.h @@ -25,7 +25,8 @@ namespace foo { enum LinkType { WIFI = 127, - ZIGBEE = 195 + ZIGBEE = 195, + ZIGBEE_TAP = 283 }; class FOO_API wireshark_connector : virtual public gr::block diff --git a/lib/wireshark_connector_impl.cc b/lib/wireshark_connector_impl.cc index 11c6ed9..7cf9280 100644 --- a/lib/wireshark_connector_impl.cc +++ b/lib/wireshark_connector_impl.cc @@ -16,6 +16,7 @@ */ #include "wireshark_connector_impl.h" #include +#include #include #include @@ -144,6 +145,58 @@ wireshark_connector_impl::handle_pdu(pmt::pmt_t pdu) { offset += sizeof(pcap_hdr); break; } + + case ZIGBEE_TAP:{ + + const size_t max_extra_size = sizeof(tap_hdr) + sizeof(tap_tlv_fcs) + sizeof(tap_tlv_channel); + size_t extra_size = sizeof(tap_hdr) + sizeof(tap_tlv_fcs); + d_msg = reinterpret_cast(std::malloc(len + sizeof(pcap_hdr) + max_extra_size)); + + + pcap_hdr *hdr = reinterpret_cast(d_msg); + hdr->ts_sec = ts_sec; + hdr->ts_usec = ts_usec; + // hdr->incl_len is set at the end of the scope + // hdr->orig_len is set at the end of the scope + offset += sizeof(pcap_hdr); + + tap_hdr *tap = reinterpret_cast(d_msg + offset); + tap->version = 0; + tap->reserved = 0; + // tap->length is set at the end of the scope + offset += sizeof(tap_hdr); + + tap_tlv_fcs *fcs = reinterpret_cast(d_msg + offset); + fcs->type = 0; // FCS_TYPE + fcs->length = 1; + fcs->fcs_type = 1; // 16 bit crc + for (int i = 0; i < 3; i++) { + fcs->padding[i] = 0; + } + offset += sizeof(tap_tlv_fcs); + + + pmt::pmt_t dict = pmt::car(pdu); + if(pmt::dict_has_key(dict, pmt::mp("channel"))) { + pmt::pmt_t s = pmt::dict_ref(dict, pmt::mp("channel"), pmt::PMT_NIL); + if(pmt::is_integer(s)) { + tap_tlv_channel *chan = reinterpret_cast(d_msg + offset); + chan->type = 3; // CHANNEL_ASSIGNMENT + chan->length = 3; + chan->channel_number = (uint16_t)pmt::to_long(s); + chan->channel_page = 0; + chan->padding = 0; + offset += sizeof(tap_tlv_channel); + extra_size += sizeof(tap_tlv_channel); + } + } + + tap->length = extra_size; + hdr->incl_len = len + extra_size; + hdr->orig_len = len + extra_size; + break; + } + } memcpy(d_msg + offset, buf, len); diff --git a/lib/wireshark_connector_impl.h b/lib/wireshark_connector_impl.h index b178e18..a56959b 100644 --- a/lib/wireshark_connector_impl.h +++ b/lib/wireshark_connector_impl.h @@ -75,6 +75,35 @@ namespace foo { }; #pragma pack(pop) + #pragma pack(push, 1) + // An 802.15.4 TAP header as defined in https://gitlab.com/exegin/ieee802-15-4-tap/ + struct tap_hdr { + uint8_t version; + uint8_t reserved; + uint16_t length; + }; + #pragma pack(pop) + + + #pragma pack(push, 1) + struct tap_tlv_fcs { + uint16_t type; // FCS_TYPE = 0 + uint16_t length; // 1 + uint8_t fcs_type; // 0 = None, 1 = 16-bit CRC, 2 = 32-bit CRC + uint8_t padding[3]; // Should be 0 padded + }; + #pragma pack(pop) + + #pragma pack(push, 1) + struct tap_tlv_channel { + uint16_t type; // CHANNEL_ASSIGNMENT = 3 + uint16_t length; // 3 + uint16_t channel_number; + uint8_t channel_page; + uint8_t padding; // Should be 0 padded + }; + #pragma pack(pop) + } // namespace foo } // namespace gr diff --git a/python/bindings/docstrings/wireshark_connector_pydoc_template.h b/python/bindings/docstrings/wireshark_connector_pydoc_template.h index 0ffe355..62e7e5f 100644 --- a/python/bindings/docstrings/wireshark_connector_pydoc_template.h +++ b/python/bindings/docstrings/wireshark_connector_pydoc_template.h @@ -1,5 +1,5 @@ /* - * Copyright 2021 Free Software Foundation, Inc. + * Copyright 2024 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -7,7 +7,7 @@ * */ #include "pydoc_macros.h" -#define D(...) DOC(gr,foo, __VA_ARGS__ ) +#define D(...) DOC(gr, foo, __VA_ARGS__) /* This file contains placeholders for docstrings for the Python bindings. Do not edit! These were automatically extracted during the binding process @@ -15,13 +15,10 @@ */ - - static const char *__doc_gr_foo_wireshark_connector = R"doc()doc"; +static const char* __doc_gr_foo_wireshark_connector = R"doc()doc"; - static const char *__doc_gr_foo_wireshark_connector_wireshark_connector = R"doc()doc"; +static const char* __doc_gr_foo_wireshark_connector_wireshark_connector_0 = R"doc()doc"; - static const char *__doc_gr_foo_wireshark_connector_make = R"doc()doc"; - - +static const char* __doc_gr_foo_wireshark_connector_make = R"doc()doc"; diff --git a/python/bindings/wireshark_connector_python.cc b/python/bindings/wireshark_connector_python.cc index b269e8a..f2e890f 100644 --- a/python/bindings/wireshark_connector_python.cc +++ b/python/bindings/wireshark_connector_python.cc @@ -1,5 +1,5 @@ /* - * Copyright 2021 Free Software Foundation, Inc. + * Copyright 2024 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -14,7 +14,7 @@ /* BINDTOOL_GEN_AUTOMATIC(0) */ /* BINDTOOL_USE_PYGCCXML(0) */ /* BINDTOOL_HEADER_FILE(wireshark_connector.h) */ -/* BINDTOOL_HEADER_FILE_HASH(10414a436e555bc27b41e65120989433) */ +/* BINDTOOL_HEADER_FILE_HASH(fcd645d2eb8f7772de5e8ded1ce89be8) */ /***********************************************************************************/ #include @@ -30,39 +30,28 @@ namespace py = pybind11; void bind_wireshark_connector(py::module& m) { - using wireshark_connector = ::gr::foo::wireshark_connector; + using wireshark_connector = ::gr::foo::wireshark_connector; - py::class_>(m, "wireshark_connector", D(wireshark_connector)) + py::class_>( + m, "wireshark_connector", D(wireshark_connector)) .def(py::init(&wireshark_connector::make), - py::arg("type"), - py::arg("debug") = false, - D(wireshark_connector,make) - ) - - + py::arg("type"), + py::arg("debug") = false, + D(wireshark_connector, make)) ; - py::enum_<::gr::foo::LinkType>(m,"LinkType") - .value("WIFI", ::gr::foo::WIFI) // 127 - .value("ZIGBEE", ::gr::foo::ZIGBEE) // 195 - .export_values() - ; + py::enum_<::gr::foo::LinkType>(m, "LinkType") + .value("WIFI", ::gr::foo::LinkType::WIFI) // 127 + .value("ZIGBEE", ::gr::foo::LinkType::ZIGBEE) // 195 + .value("ZIGBEE_TAP", ::gr::foo::LinkType::ZIGBEE_TAP) // 283 + .export_values(); py::implicitly_convertible(); - - - } - - - - - - - -