-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 8467e0e
Showing
4 changed files
with
363 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
name: Build | ||
on: [push, pull_request, workflow_dispatch] | ||
|
||
jobs: | ||
build: | ||
strategy: | ||
matrix: | ||
sys: | ||
- { os: windows, shell: 'msys2 {0}' } | ||
- { os: ubuntu, shell: bash } | ||
- { os: macos, shell: bash } | ||
wireshark: | ||
- v4.4.0 | ||
|
||
runs-on: ${{ matrix.sys.os }}-latest | ||
|
||
defaults: | ||
run: | ||
shell: ${{ matrix.sys.shell }} | ||
|
||
steps: | ||
- name: Checkout Wireshark | ||
uses: actions/checkout@v4 | ||
with: | ||
repository: wireshark/wireshark | ||
ref: ${{ matrix.wireshark }} | ||
path: wireshark | ||
fetch-depth: 0 | ||
|
||
- name: Checkout CatSniffer Plugin | ||
uses: actions/checkout@v4 | ||
with: | ||
path: wireshark/plugins/epan/catsniffer | ||
fetch-depth: 0 | ||
|
||
- name: Install dependencies (Ubuntu) | ||
if: matrix.sys.os == 'ubuntu' | ||
run: sudo wireshark/tools/debian-setup.sh --install-all python3-pip -y | ||
|
||
- name: Install dependencies (Mac OS) | ||
if: matrix.sys.os == 'macos' | ||
run: wireshark/tools/macos-setup-brew.sh --install-optional --install-doc-deps --install-dmg-deps --install-test-deps | ||
env: | ||
HOMEBREW_NO_AUTO_UPDATE: 1 | ||
|
||
- name: Install MSYS2 (Windows) | ||
if: matrix.sys.os == 'windows' | ||
uses: msys2/setup-msys2@v2 | ||
with: | ||
msystem: UCRT64 | ||
update: true | ||
install: base-devel | ||
|
||
- name: Install dependencies (Windows) | ||
if: matrix.sys.os == 'windows' | ||
run: wireshark/tools/msys2-setup.sh --install-all --noconfirm | ||
|
||
- name: Configure | ||
run: cmake -B build -S wireshark -G Ninja -DCUSTOM_PLUGIN_SRC_DIR=plugins/epan/catsniffer -DCMAKE_INSTALL_PREFIX=/ | ||
|
||
- name: Build | ||
run: cmake --build build --target catsniffer | ||
|
||
- name: Install | ||
env: | ||
DESTDIR: ${{ github.workspace }}/dist | ||
run: cmake --build build --target plugins/epan/catsniffer/install | ||
|
||
- name: Upload artifacts | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: CatSniffer_Wireshark${{ matrix.wireshark }}_${{ matrix.sys.os }} | ||
path: dist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# CMakeLists.txt | ||
# | ||
# SPDX-FileCopyrightText: © 2024 Antonio Vázquez Blanco <[email protected]> | ||
# SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
include(WiresharkPlugin) | ||
|
||
# Plugin name and version info (major minor micro extra) | ||
set_module_info(catsniffer 0 0 1 0) | ||
|
||
set(DISSECTOR_SRC | ||
catsniffer.c | ||
) | ||
|
||
set(PLUGIN_FILES | ||
plugin.c | ||
${DISSECTOR_SRC} | ||
) | ||
|
||
set_source_files_properties( | ||
${PLUGIN_FILES} | ||
PROPERTIES | ||
COMPILE_FLAGS "${WERROR_COMMON_FLAGS}" | ||
) | ||
|
||
register_plugin_files(plugin.c | ||
plugin | ||
${DISSECTOR_SRC} | ||
) | ||
|
||
add_wireshark_plugin_library(catsniffer epan) | ||
|
||
target_link_libraries(catsniffer epan) | ||
|
||
install_plugin(catsniffer epan) | ||
|
||
file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") | ||
CHECKAPI( | ||
NAME | ||
catsniffer | ||
SWITCHES | ||
--group dissectors-prohibited | ||
--group dissectors-restricted | ||
SOURCES | ||
${DISSECTOR_SRC} | ||
${DISSECTOR_HEADERS} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# CatSniffer Wireshark Plugin | ||
|
||
This is a native version of a Wireshark plugin to inspect CatSniffer traffic. | ||
|
||
## Building | ||
|
||
Theoretically, there is a way to build Wireshark plugins out of tree. | ||
Unfortunatelly, there are some outstanding bugs in the way of correctly achieve this feat. | ||
See https://gitlab.com/wireshark/wireshark/-/issues/19976 and https://gitlab.com/wireshark/wireshark/-/issues/1199. | ||
This means there is no good way of building this plugin out of Wireshark source code tree. | ||
The good news is that the plugin can be built inside Wireshark source code and exported as a library to be distributed. | ||
|
||
To compile this plugin first checkout Wireshark source code to your preferred wireshark version: | ||
```bash | ||
git clone https://gitlab.com/wireshark/wireshark.git | ||
cd wireshark | ||
git checkout v4.4.0 | ||
``` | ||
|
||
Then, you need to clone this repository onto the epan plugins folder inside wireshark: | ||
```bash | ||
cd plugins/epan/ | ||
git clone https://github.com/ElectronicCats/CatSniffer-Wireshark.git catsniffer | ||
cd ../../ | ||
``` | ||
|
||
In Wireshark main directory, the project must be configured indicating there is an extra plugin. | ||
```bash | ||
cmake -B build -S . -DCUSTOM_PLUGIN_SRC_DIR=plugins/epan/catsniffer | ||
``` | ||
|
||
You may now build the plugin target alone witout having to compile the full Wireshark source code: | ||
```bash | ||
cmake --build build --target catsniffer | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
/* catsniffer_rpi.c | ||
* | ||
* SPDX-FileCopyrightText: © 2024 Antonio Vázquez Blanco <[email protected]> | ||
* SPDX-License-Identifier: GPL-2.0-or-later | ||
* | ||
* This file registers and handles CatSniffer Radio packets following the format shown below. | ||
* | ||
* | Version | Length | Interface Type | Interface ID | Protocol | PHY | Frequency | Channel | RSSI | Status | Payload | | ||
* |---------|--------|----------------|--------------|----------|-----|-----------|---------|------|--------|----------| | ||
* | 1B | 2B | 1B | 2B | 1B | 1B | 4B | 2B | 1B | 1B | Variable | | ||
* | ||
* If the received packet is BLE, there is a secondary header with the format below. | ||
* | ||
* | Connection Event Counter | Info | Payload | | ||
* |--------------------------|------|-----------------| | ||
* | 2B | 1B | Variable Length | | ||
* | ||
*/ | ||
|
||
#include <wireshark.h> | ||
#include <epan/packet.h> | ||
#include <epan/unit_strings.h> | ||
#include <wiretap/wtap.h> | ||
|
||
#define TI_RPI_MIN_LENGTH 17 | ||
|
||
// Dissector handles | ||
static dissector_handle_t handle_catsniffer_rpi; | ||
static dissector_handle_t handle_btle; | ||
static dissector_handle_t handle_wpan; | ||
|
||
// Protocol handles | ||
static int proto_catsniffer_rpi; | ||
static int proto_catsniffer_blepi; | ||
|
||
// Header field handles | ||
static int hf_catsniffer_rpi_version; | ||
static int hf_catsniffer_rpi_length; | ||
static int hf_catsniffer_rpi_interface_type; | ||
static int hf_catsniffer_rpi_interface_id; | ||
static int hf_catsniffer_rpi_protocol; | ||
static int hf_catsniffer_rpi_phy; | ||
static int hf_catsniffer_rpi_freq; | ||
static int hf_catsniffer_rpi_channel; | ||
static int hf_catsniffer_rpi_rssi; | ||
static int hf_catsniffer_rpi_fcs; | ||
static int hf_catsniffer_blepi_conn_event; | ||
|
||
// Subtree pointers | ||
static int ett_rpi; | ||
static int ett_blepi; | ||
|
||
// Value tables | ||
static const value_string table_interface_type[] = { | ||
{0, "COM"}, | ||
{1, "CEBAL"}, | ||
{0, NULL}}; | ||
|
||
static const value_string table_protocol[] = { | ||
{0, "Generic"}, | ||
{1, "802.15.4g"}, | ||
{2, "802.15.4"}, | ||
{3, "BLE"}, | ||
{4, "WBMS"}, | ||
{0, NULL}}; | ||
|
||
static const value_string table_phy[] = { | ||
{0, "Unused"}, | ||
{3, "O-QPSK"}, | ||
{5, "BLE 1 Mbps"}, | ||
{0, NULL}}; | ||
|
||
static const unit_name_string table_units_khz = {"kHz", NULL}; | ||
|
||
static const true_false_string table_fcs = {"Ok", "Bad FCS"}; | ||
|
||
static int dissect_catsniffer_blepi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) | ||
{ | ||
int offset = 0; | ||
(void)data; | ||
if (tvb_reported_length(tvb) == 0) | ||
return 0; | ||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Catsniffer BLE"); | ||
proto_item *ti = proto_tree_add_item(tree, proto_catsniffer_blepi, tvb, 0, -1, ENC_NA); | ||
proto_tree *ti_blepi = proto_item_add_subtree(ti, ett_blepi); | ||
// Connection Event | ||
proto_tree_add_item(ti_blepi, hf_catsniffer_blepi_conn_event, tvb, offset, 2, ENC_LITTLE_ENDIAN); | ||
offset += 2; | ||
proto_item_set_len(ti_blepi, offset); | ||
return offset; | ||
} | ||
|
||
static dissector_handle_t get_protocol_dissector_handle(int protocol) | ||
{ | ||
switch (protocol) | ||
{ | ||
case 2: | ||
// 802.15.4 | ||
return handle_wpan; | ||
case 3: | ||
// BLE | ||
return handle_btle; | ||
default: | ||
return NULL; | ||
} | ||
} | ||
|
||
static int dissect_catsniffer_rpi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) | ||
{ | ||
int offset = 0; | ||
int length; | ||
int protocol; | ||
|
||
if (tvb_captured_length(tvb) < TI_RPI_MIN_LENGTH) | ||
return 0; | ||
|
||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "CatSniffer Radio"); | ||
|
||
proto_item *ti = proto_tree_add_item(tree, proto_catsniffer_rpi, tvb, 0, -1, ENC_NA); | ||
proto_tree *ti_rpi = proto_item_add_subtree(ti, ett_rpi); | ||
// Version | ||
proto_tree_add_item(ti_rpi, hf_catsniffer_rpi_version, tvb, offset, 1, ENC_NA); | ||
offset += 1; | ||
// Packet length | ||
proto_tree_add_item_ret_uint(ti_rpi, hf_catsniffer_rpi_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &length); | ||
offset += 2; | ||
// Interface type | ||
proto_tree_add_item(ti_rpi, hf_catsniffer_rpi_interface_type, tvb, offset, 1, ENC_NA); | ||
offset += 1; | ||
// Interface id | ||
proto_tree_add_item(ti_rpi, hf_catsniffer_rpi_interface_id, tvb, offset, 2, ENC_LITTLE_ENDIAN); | ||
offset += 2; | ||
// Protocol | ||
proto_tree_add_item_ret_uint(ti_rpi, hf_catsniffer_rpi_protocol, tvb, offset, 1, ENC_NA, &protocol); | ||
offset += 1; | ||
// PHY | ||
proto_tree_add_item(ti_rpi, hf_catsniffer_rpi_phy, tvb, offset, 1, ENC_NA); | ||
offset += 1; | ||
// Freq | ||
proto_tree_add_item(ti_rpi, hf_catsniffer_rpi_freq, tvb, offset, 4, ENC_LITTLE_ENDIAN); | ||
offset += 4; | ||
// Channel | ||
proto_tree_add_item(ti_rpi, hf_catsniffer_rpi_channel, tvb, offset, 2, ENC_LITTLE_ENDIAN); | ||
offset += 2; | ||
// RSSI | ||
proto_tree_add_item(ti_rpi, hf_catsniffer_rpi_rssi, tvb, offset, 1, ENC_NA); | ||
offset += 1; | ||
// Status | ||
proto_tree_add_item(ti_rpi, hf_catsniffer_rpi_fcs, tvb, offset, 1, ENC_NA); | ||
offset += 1; | ||
proto_item_set_len(ti_rpi, offset); | ||
// Optional BLE header | ||
if (protocol == 3) | ||
{ | ||
tvbuff_t *tvb_blepi = tvb_new_subset_remaining(tvb, offset); | ||
offset += dissect_catsniffer_blepi(tvb_blepi, pinfo, tree, data); | ||
} | ||
// Payload | ||
int payload_offset = (protocol == 3) ? 0 : 4; | ||
tvbuff_t *tvb_payload = tvb_new_subset_remaining(tvb, offset + payload_offset); | ||
dissector_handle_t payload_dissector = get_protocol_dissector_handle(protocol); | ||
offset += call_dissector_with_data(payload_dissector, tvb_payload, pinfo, tree, data); | ||
// All done! | ||
return offset; | ||
} | ||
|
||
void proto_register_catsniffer_rpi(void) | ||
{ | ||
// Setup a list of header fields | ||
static hf_register_info hf[] = { | ||
{&hf_catsniffer_rpi_version, {"Version", "catsniffer.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}}, | ||
{&hf_catsniffer_rpi_length, {"Packet Length", "catsniffer.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}}, | ||
{&hf_catsniffer_rpi_interface_type, {"Interface Type", "catsniffer.interface_type", FT_UINT8, BASE_DEC, VALS(table_interface_type), 0x0, NULL, HFILL}}, | ||
{&hf_catsniffer_rpi_interface_id, {"Interface ID", "catsniffer.interface_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}}, | ||
{&hf_catsniffer_rpi_protocol, {"Protocol", "catsniffer.protocol", FT_UINT8, BASE_DEC, VALS(table_protocol), 0x0, NULL, HFILL}}, | ||
{&hf_catsniffer_rpi_phy, {"PHY", "catsniffer.phy", FT_UINT8, BASE_DEC, VALS(table_phy), 0x0, NULL, HFILL}}, | ||
{&hf_catsniffer_rpi_freq, {"Frequency", "catsniffer.freq", FT_UINT32, BASE_DEC | BASE_UNIT_STRING, UNS(&table_units_khz), 0x0, NULL, HFILL}}, | ||
{&hf_catsniffer_rpi_channel, {"Channel", "catsniffer.channel", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}}, | ||
{&hf_catsniffer_rpi_rssi, {"RSSI", "catsniffer.rssi", FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}}, | ||
{&hf_catsniffer_rpi_fcs, {"Frame Check Status", "catsniffer.fcs", FT_BOOLEAN, 8, TFS(&table_fcs), 0x80, NULL, HFILL}}, | ||
{&hf_catsniffer_blepi_conn_event, {"Connection Event", "catsniffer.conn_event", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}}, | ||
}; | ||
|
||
// Protocol subtree arrays | ||
static int *ett[] = { | ||
&ett_rpi, | ||
&ett_blepi}; | ||
|
||
// Register protocols | ||
proto_catsniffer_rpi = proto_register_protocol("CatSniffer Radio Packet Info", "CatSniffer RPI", "catsniffer_rpi"); | ||
proto_catsniffer_blepi = proto_register_protocol("CatSniffer BLE Packet Info", "CatSniffer BLEPI", "catsniffer_blepi"); | ||
|
||
// Register dissectors | ||
handle_catsniffer_rpi = register_dissector("catsniffer_rpi", dissect_catsniffer_rpi, proto_catsniffer_rpi); | ||
handle_btle = find_dissector("btle"); | ||
handle_wpan = find_dissector("wpan"); | ||
|
||
// Register header fields | ||
proto_register_field_array(proto_catsniffer_rpi, hf, array_length(hf)); | ||
|
||
// Register subtrees | ||
proto_register_subtree_array(ett, array_length(ett)); | ||
} | ||
|
||
void proto_reg_handoff_catsniffer_rpi(void) | ||
{ | ||
dissector_add_uint("wtap_encap", WTAP_ENCAP_USER0, handle_catsniffer_rpi); | ||
} |