Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Windows wireshark custom plugin loading error

I developed a custom wireshark dissector plugin on linux debian on wireshark 4.2.5 (also working on 4.2.6) which is working completely fine. However, when I try to use the source code from this plugin and do a custom build on Windows 11 wireshark 4.3.0 (following the documentation instructions to build from VS Code), I get the following error: Couldn't load plugin 'wibotic.dll': 'C: \Development\wsbuild64\run\RelWithDebInfo\plugins\4.3\epan\wibotic.dll': The specified module could not be found.

The file exists at the above file path, so I'm not sure why it can't load it. For reference, I changed the top-level CMakeLists.txt and custom_plugins.txt files in accordance with the README.plugins. I also changed plugins.wxi, adding my custom plugin after the comments. Any help would be greatly appreciated!

Windows wireshark custom plugin loading error

I developed a custom wireshark dissector plugin on linux debian on wireshark 4.2.5 (also working on 4.2.6) which is working completely fine. However, when I try to use the source code from this plugin and do a custom build on Windows 11 wireshark 4.3.0 (following the documentation instructions to build from VS Code), I get the following error: error:

Couldn't load plugin 'wibotic.dll': 'C: \Development\wsbuild64\run\RelWithDebInfo\plugins\4.3\epan\wibotic.dll': The specified module could not be found.

The file exists at the above file path, so I'm not sure why it can't load it. For reference, I changed the top-level CMakeLists.txt and custom_plugins.txt files in accordance with the README.plugins. I also changed plugins.wxi, adding my custom plugin after the comments. Any help would be greatly appreciated!

Windows wireshark custom plugin loading error

I developed a custom wireshark dissector plugin on linux debian on wireshark 4.2.5 (also working on 4.2.6) which is working completely fine. However, when I try to use the source code from this plugin and do a custom build on Windows 11 wireshark 4.3.0 (following the documentation instructions to build from VS Code), I get the following error:

Couldn't load plugin 'wibotic.dll': 'C: \Development\wsbuild64\run\RelWithDebInfo\plugins\4.3\epan\wibotic.dll': 'C:

\Development\wsbuild64\run\RelWithDebInfo\plugins\4.3\epan\wibotic.dll':

The specified module could not be found.

The file exists at the above file path, so I'm not sure why it can't load it. For reference, I changed the top-level CMakeLists.txt and custom_plugins.txt files in accordance with the README.plugins. I also changed plugins.wxi, adding my custom plugin after the comments. Any help would be greatly appreciated!

click to hide/show revision 4
None

Windows wireshark custom plugin loading error

I developed a custom wireshark dissector plugin on linux debian on wireshark 4.2.5 (also working on 4.2.6) which is working completely fine. However, when I try to use the source code from this plugin and do a custom build on Windows 11 wireshark 4.3.0 (following the documentation instructions to build from VS Code), I get the following error:

Couldn't load plugin 'wibotic.dll': 'C:

\Development\wsbuild64\run\RelWithDebInfo\plugins\4.3\epan\wibotic.dll':

'wibotic.dll': 'C:\Development\wsbuild64\run\RelWithDebInfo\plugins\4.3\epan\wibotic.dll': The specified module could not be found.

found.

The file exists at the above file path, so I'm not sure why it can't load it. For reference, I changed the top-level CMakeLists.txt and custom_plugins.txt files in accordance with the README.plugins. I also changed plugins.wxi, adding my custom plugin after the comments. Any help would be greatly appreciated!

Windows wireshark custom plugin loading error

I developed a custom wireshark dissector plugin on linux debian on wireshark 4.2.5 (also working on 4.2.6) which is working completely fine. However, when I try to use the source code from this plugin and do a custom build on Windows 11 wireshark 4.3.0 (following the documentation instructions to build from VS Code), I get the following error:

Couldn't load plugin 'wibotic.dll':
 'C:\Development\wsbuild64\run\RelWithDebInfo\plugins\4.3\epan\wibotic.dll':
'wibotic.dll': 'C:
\Development\wsbuild64\run\RelWithDebInfo\plugins\4.3\epan\wibotic.dll':
The specified module could not be found.

The file exists at the above file path, so I'm not sure why it can't load it. For reference, I changed the top-level CMakeLists.txt and custom_plugins.txt files in accordance with the README.plugins. I also changed plugins.wxi, adding my custom plugin after the comments. Any help would be greatly appreciated!

Windows wireshark custom plugin loading error

I developed a custom wireshark dissector plugin on linux debian on wireshark 4.2.5 (also working on 4.2.6) which is working completely fine. However, when I try to use the source code from this plugin and do a custom build on Windows 11 wireshark 4.3.0 (following the documentation instructions to build from VS Code), I get the following error:

Couldn't load plugin 'wibotic.dll': 'C:
\Development\wsbuild64\run\RelWithDebInfo\plugins\4.3\epan\wibotic.dll':
The specified module could not be found.

The file exists at the above file path, so I'm not sure why it can't load it. For reference, I changed the top-level CMakeLists.txt and custom_plugins.txt files in accordance with the README.plugins. I also changed plugins.wxi, adding my custom plugin after the comments. Any help would be greatly appreciated!

Info about the build and runtime environment: Version 4.3.0-Wibotic (v4.3.0rc1-234-g40da1d487563).

Copyright 1998-2024 Gerald Combs [email protected] and contributors.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

Compiled (64-bit) using Microsoft Visual Studio 2022 (VC++ 14.40, build 33811), with GLib 2.78.4, with Qt 6.6.3, with libpcap, with zlib 1.3.1, with zlib-ng 2.1.5, with PCRE2, with Lua 5.4.6 (with UfW patches), with GnuTLS 3.8.4 and PKCS #11 support, with Gcrypt 1.10.2-unknown, with Kerberos (MIT), with MaxMind, with nghttp2 1.61.0, with nghttp3 1.0.0, with brotli, with LZ4, with Zstandard, with Snappy, with libxml2 2.11.7, with libsmi 0.5.0, with QtMultimedia, with automatic updates using WinSparkle 0.8.0, with AirPcap, with Minizip, with binary plugins.

Running on 64-bit Windows 11 (23H2), build 22631, with Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz (with SSE4.2), with 7608 MB of physical memory, with GLib 2.78.4, with Qt 6.6.3, with Npcap version 1.79, based on libpcap version 1.10.4, with PCRE2 10.43 2024-02-16, with c-ares 1.27.0, with GnuTLS 3.8.4, with Gcrypt 1.10.2-unknown, with nghttp2 1.61.0, with nghttp3 1.0.0, with brotli 1.0.9, with LZ4 1.9.3, with Zstandard 1.5.2, without AirPcap, with light display mode, without HiDPI, with QPA plugin "windows", with LC_TYPE=English_United States.utf8, binary plugins supported.

Check the man page and www.wireshark.org for more information.

Windows wireshark custom plugin loading error

I developed a custom wireshark dissector plugin on linux debian on wireshark 4.2.5 (also working on 4.2.6) which is working completely fine. However, when I try to use the source code from this plugin and do a custom build on Windows 11 wireshark 4.3.0 (following the documentation instructions to build from VS Code), I get the following error:

Couldn't load plugin 'wibotic.dll': 'C:
\Development\wsbuild64\run\RelWithDebInfo\plugins\4.3\epan\wibotic.dll':
The specified module could not be found.

The file exists at the above file path, so I'm not sure why it can't load it. For reference, I changed the top-level CMakeLists.txt and custom_plugins.txt files in accordance with the README.plugins. I also changed plugins.wxi, adding my custom plugin after the comments. Any help would be greatly appreciated!

Info about the build and runtime environment: environment:

Version 4.3.0-Wibotic (v4.3.0rc1-234-g40da1d487563).

(v4.3.0rc1-234-g40da1d487563). Copyright 1998-2024 Gerald Combs [email protected] and contributors.

<[email protected]> and contributors. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

details. Compiled (64-bit) using Microsoft Visual Studio 2022 (VC++ 14.40, build 33811), with GLib 2.78.4, with Qt 6.6.3, with libpcap, with zlib 1.3.1, with zlib-ng 2.1.5, with PCRE2, with Lua 5.4.6 (with UfW patches), with GnuTLS 3.8.4 and PKCS #11 support, with Gcrypt 1.10.2-unknown, with Kerberos (MIT), with MaxMind, with nghttp2 1.61.0, with nghttp3 1.0.0, with brotli, with LZ4, with Zstandard, with Snappy, with libxml2 2.11.7, with libsmi 0.5.0, with QtMultimedia, with automatic updates using WinSparkle 0.8.0, with AirPcap, with Minizip, with binary plugins.

plugins. Running on 64-bit Windows 11 (23H2), build 22631, with Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz (with SSE4.2), with 7608 MB of physical memory, with GLib 2.78.4, with Qt 6.6.3, with Npcap version 1.79, based on libpcap version 1.10.4, with PCRE2 10.43 2024-02-16, with c-ares 1.27.0, with GnuTLS 3.8.4, with Gcrypt 1.10.2-unknown, with nghttp2 1.61.0, with nghttp3 1.0.0, with brotli 1.0.9, with LZ4 1.9.3, with Zstandard 1.5.2, without AirPcap, with light display mode, without HiDPI, with QPA plugin "windows", with LC_TYPE=English_United States.utf8, binary plugins supported.

supported. Check the man page and www.wireshark.org for more information.

information.

Windows wireshark custom plugin loading error

I developed a custom wireshark dissector plugin on linux debian on wireshark 4.2.5 (also working on 4.2.6) which is working completely fine. However, when I try to use the source code from this plugin and do a custom build on Windows 11 wireshark 4.3.0 (following the documentation instructions to build from VS Code), I get the following error:

Couldn't load plugin 'wibotic.dll': 'C:
\Development\wsbuild64\run\RelWithDebInfo\plugins\4.3\epan\wibotic.dll':
The specified module could not be found.

The file exists at the above file path, so I'm not sure why it can't load it. For reference, I changed the top-level CMakeLists.txt and custom_plugins.txt files in accordance with the README.plugins. I also changed plugins.wxi, adding my custom plugin after the comments. Any help would be greatly appreciated!

Info about the build and runtime environment:

Version 4.3.0-Wibotic (v4.3.0rc1-234-g40da1d487563).

Copyright 1998-2024 Gerald Combs <[email protected]> and contributors.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

Compiled (64-bit) using Microsoft Visual Studio 2022 (VC++ 14.40, build 33811), with GLib 2.78.4, with Qt 6.6.3, with libpcap, with zlib 1.3.1, with zlib-ng 2.1.5, with PCRE2, with Lua 5.4.6 (with UfW patches), with GnuTLS 3.8.4 and PKCS #11 support, with Gcrypt 1.10.2-unknown, with Kerberos (MIT), with MaxMind, with nghttp2 1.61.0, with nghttp3 1.0.0, with brotli, with LZ4, with Zstandard, with Snappy, with libxml2 2.11.7, with libsmi 0.5.0, with QtMultimedia, with automatic updates using WinSparkle 0.8.0, with AirPcap, with Minizip, with binary plugins.

Running on 64-bit Windows 11 (23H2), build 22631, with Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz (with SSE4.2), with 7608 MB of physical memory, with GLib 2.78.4, with Qt 6.6.3, with Npcap version 1.79, based on libpcap version 1.10.4, with PCRE2 10.43 2024-02-16, with c-ares 1.27.0, with GnuTLS 3.8.4, with Gcrypt 1.10.2-unknown, with nghttp2 1.61.0, with nghttp3 1.0.0, with brotli 1.0.9, with LZ4 1.9.3, with Zstandard 1.5.2, without AirPcap, with light display mode, without HiDPI, with QPA plugin "windows", with LC_TYPE=English_United States.utf8, binary plugins supported.

Check the man page and www.wireshark.org for more information.
/* packet-wibotic.c
 *
 * Routines for WiBotic protocol packet dissection
 * By Tong Lin <[email protected]>
 *
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <[email protected]>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 *
 */


#ifdef __linux__
    #define _GNU_SOURCE
    #include <dlfcn.h>
#elif _WIN32
    #include <windows.h>
    #include <tchar.h>
    #include <stdio.h>

#endif

#include "config.h"
#include <epan packet.h="">
#include <epan tvbuff-int.h="">

#define PY_SSIZE_T_CLEAN
#include <python.h>

void proto_register_wibotic(void);
void proto_reg_handoff_wibotic(void);

#define WIBOTIC_WEBSOCKET_PORT 80

static int proto_wibotic;
static dissector_handle_t wibotic_handle;
proto_item* pi;
static int ett_wibotic = -1;
static int ett_adc = -1;
static int ett_adc_field = -1;

static int hf_packet_type = -1;
static int hf_device_id = -1;
static int hf_adc_data = -1;
static int hf_sub_adc_data = -1;
static int hf_adc_id = -1;
static int hf_adc_value = -1;
static int hf_param_id  = -1;
static int hf_value = -1;
static int hf_status = -1;
static int hf_location = -1;
static int hf_data = -1;
static int hf_devices = -1;
static int hf_level = -1;
static int hf_code = -1;
static int hf_message = -1;
static int hf_ext_param_id = -1;
static int hf_rssi = -1;
static int hf_mac_address = -1;
static int hf_completion = -1;
static int hf_state = -1;
static int hf_dest_id = -1;
static int hf_topic = -1;

typedef struct {
    char* field_name;
    int* field_var;
} hf_field;

hf_field hf_fields[] = {
    {"packet", &hf_packet_type},
    {"device", &hf_device_id},
    {"values", &hf_adc_data}, 
    {"param", &hf_param_id},
    {"value", &hf_value},
    {"status", &hf_status},
    {"location", &hf_location},
    {"data", &hf_data}, 
    {"devices", &hf_devices},
    {"level", &hf_level},
    {"code", &hf_code},
    {"message", &hf_message},
    {"ext_id", &hf_ext_param_id},
    {"rssi", &hf_rssi},
    {"mac", &hf_mac_address},
    {"completion", &hf_completion},
    {"state", &hf_state},
    {"dest", &hf_dest_id},
    {"topic", &hf_topic}
};

int lookup_correct_field(char* field_name) {
    for (int i = 0; i < (int) array_length(hf_fields); i++) {
        if (strcmp(hf_fields[i].field_name, field_name) == 0) {
            return *hf_fields[i].field_var;
        }
    }
    return 0;
}

void add_items_to_tree(proto_tree* tree, char** hf_field_list, tvbuff_t *tvb, char* struct_format, long encoding, char** attribute_names) {
    guint offset = 1;
    for (int i = 0; i < (int) strlen(struct_format); i++) {
        switch(struct_format[i]) {
            case 'B':
                pi = proto_tree_add_item(tree, lookup_correct_field(hf_field_list[i]), tvb, offset, 1, encoding);
                offset++;
                break;
            case 'H':
                pi = proto_tree_add_item(tree, lookup_correct_field(hf_field_list[i]), tvb, offset, 2, encoding);
                offset+=2;
                break;
            case 'L':
                pi = proto_tree_add_item(tree, lookup_correct_field(hf_field_list[i]), tvb, offset, 4, encoding);
                offset+=4;
                break;
            default: //assuming 1 char number
                int num = struct_format[i] - '0';
                pi = proto_tree_add_item(tree, lookup_correct_field(hf_field_list[i]), tvb, offset, num, encoding);
                offset+=2;
                break;
        }
        proto_item_append_text(pi, " %s", attribute_names[i]);
    }

    if (tvb_captured_length(tvb) > offset) {
        if (tvb_get_guint8(tvb, 0) == 0x82) { //hardcoded id to explicitly check for ADC update
            proto_item *adc = proto_tree_add_item(tree, hf_adc_data, tvb, offset, -1, encoding);
            proto_tree *adc_tree = proto_item_add_subtree(adc, ett_adc);

            int num_values = (tvb_captured_length(tvb) - 2)/6;
            for (int i = 0; i < 2*num_values; i+=2) {
                proto_item *adc_val = proto_tree_add_item(adc_tree, hf_sub_adc_data, tvb, offset, 6, encoding);
                proto_item_append_text(adc_val, " %s", attribute_names[i + strlen(struct_format)]);
                proto_tree *adc_subtree = proto_item_add_subtree(adc_val, ett_adc_field);

                pi = proto_tree_add_item(adc_subtree, hf_adc_id, tvb, offset, 2, encoding);
                offset+=2;

                pi = proto_tree_add_item(adc_subtree, hf_adc_value, tvb, offset, 4, encoding);
                proto_item_append_text(pi, " %s", attribute_names[i + strlen(struct_format) + 1]);
                offset+=4;
            }
        } else {
            proto_tree_add_item(tree, hf_data, tvb, offset, -1, encoding);
        }
    }
}

static int
dissect_wibotic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_)
{

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "WiBotic"); //set protocol column to recognize Wibotic
    col_clear(pinfo->cinfo,COL_INFO);


    proto_item* ti = proto_tree_add_item(tree, proto_wibotic, tvb, 0, -1, ENC_NA);
    proto_tree *wibotic_tree = proto_item_add_subtree(ti, ett_wibotic);

    //load in the file with the python methods
    PyObject* pName = PyUnicode_DecodeFSDefault("tvbparser");
    PyObject* pModule = PyImport_Import(pName); 
    Py_DECREF(pName);

    if (pModule != NULL) {
        PyObject* pFuncPacketType = PyObject_GetAttrString(pModule, "get_packet_type"); 
        if (pFuncPacketType && PyCallable_Check(pFuncPacketType)) {
            PyObject* pArgs = PyTuple_New(1);
            PyTuple_SetItem(pArgs, 0, PyBytes_FromStringAndSize(tvb->real_data, tvb_captured_length(tvb)));
            PyObject* pValue = PyObject_CallObject(pFuncPacketType, pArgs);
            if (pValue == NULL) {
                Py_DECREF(pFuncPacketType);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr,"Call #1 failed\n");
                return 1;
            }
            Py_DECREF(pFuncPacketType);

            //add type of update to column list
            PyObject* pPacketType = PyUnicode_AsUTF8String(pValue);
            char* packetType = strdup(PyBytes_AsString(pPacketType));
            col_add_fstr(pinfo->cinfo, COL_INFO, "Type %s", packetType);
            Py_DECREF(pValue);
            Py_DECREF(pPacketType);

            //add list of values to prototree
            //get endianness
            PyObject* pFuncEndian = PyObject_GetAttrString(pModule, "get_packet_endianness"); 
            if (pFuncEndian && PyCallable_Check(pFuncEndian)) {
                PyObject* pValue2 = PyObject_CallObject(pFuncEndian, pArgs);
                long endianness = PyLong_AsLong(pValue2);
                if (pValue2 == NULL || endianness == 1) {
                    Py_DECREF(pFuncEndian);
                    Py_DECREF(pModule);
                    PyErr_Print();
                    fprintf(stderr,"Call #2 failed\n");
                    return 1;
                }
                Py_DECREF(pFuncEndian);
                Py_DECREF(pValue2);

                //get struct format, array of string names of fields and parse
                PyObject* pFuncStructFormat = PyObject_GetAttrString(pModule, "get_struct_format"); 
                if (pFuncStructFormat && PyCallable_Check(pFuncStructFormat)) {
                    PyObject* pValue3 = PyObject_CallObject(pFuncStructFormat, pArgs);
                    if (pValue3 == NULL) {
                        Py_DECREF(pFuncStructFormat);
                        Py_DECREF(pModule);
                        PyErr_Print();
                        fprintf(stderr,"Call #3 failed\n");
                        return 1;
                    }
                    Py_DECREF(pFuncStructFormat);

                    //get struct_format
                    PyObject* pStructFormat = PyUnicode_AsUTF8String(pValue3);
                    char* structFormat = strdup(PyBytes_AsString(pStructFormat));
                    Py_DECREF(pValue3);
                    Py_DECREF(pStructFormat);

                    PyObject* pFuncFieldList = PyObject_GetAttrString(pModule, "get_packet_field_list"); 
                    if (pFuncFieldList && PyCallable_Check(pFuncFieldList)) {
                        PyObject* pValue4 = PyObject_CallObject(pFuncFieldList, pArgs);
                        if (pValue4 == NULL) {
                            Py_DECREF(pFuncFieldList);
                            Py_DECREF(pModule);
                            PyErr_Print();
                            fprintf(stderr,"Call #4 failed\n");
                            return 1;
                        }
                        Py_DECREF(pFuncFieldList);

                        //parse fields list
                        int listSize = PyList_Size(pValue4);
                        if (listSize != -1) {
                            char** hf_field_names = (char**) malloc(listSize * sizeof(char*));
                            if (hf_field_names == NULL) {
                                fprintf(stderr, "hf_field_names malloc failed");
                                return 1;
                            }
                            for (int i = 0; i < listSize; i++) {
                                PyObject* pItem = PyList_GetItem(pValue4, i);
                                PyObject* pFieldName = PyUnicode_AsUTF8String(pItem);
                                char* fieldName = strdup(PyBytes_AsString(pFieldName));
                                hf_field_names[i] = fieldName;
                            }

                            PyObject* pFuncAttributes = PyObject_GetAttrString(pModule, "get_attributes_list"); 
                            if (pFuncAttributes && PyCallable_Check(pFuncAttributes)) {
                                PyObject* pValue5 = PyObject_CallObject(pFuncAttributes, pArgs);
                                if (pValue5 == NULL) {
                                    Py_DECREF(pFuncAttributes);
                                    Py_DECREF(pModule);
                                    PyErr_Print();
                                    fprintf(stderr,"Call #5 failed\n");
                                    return 1;
                                }
                                Py_DECREF(pFuncAttributes);

                                int listSize2 = PyList_Size(pValue5);
                                if (listSize2 != -1) {
                                    char** attribute_names = (char**) malloc(listSize2 * sizeof(char*));
                                    if (attribute_names == NULL) {
                                        fprintf(stderr, "attribute_names malloc failed");
                                        return 1;
                                    }
                                    for (int i = 0; i < listSize2; i++) {
                                        PyObject* pItem2 = PyList_GetItem(pValue5, i);
                                        PyObject* pAttributeName = PyUnicode_AsUTF8String(pItem2);
                                        char* attributeName = strdup(PyBytes_AsString(pAttributeName));
                                        attribute_names[i] = attributeName;
                                    }
                                    //adds packet type to UI
                                    pi = proto_tree_add_item(wibotic_tree, hf_packet_type, tvb, 0, 1, endianness);
                                    proto_item_append_text(pi, " %s", packetType);

                                    //ignores first 2 characters of the struct format (endianness and packet)
                                    add_items_to_tree(wibotic_tree, hf_field_names, tvb, structFormat + 2, endianness, attribute_names);

                                    free(hf_field_names);
                                    free(attribute_names);
                                    Py_DECREF(pValue4);
                                    Py_DECREF(pArgs);
                                    Py_DECREF(pModule);
                                }
                            } else {
                                if (PyErr_Occurred())
                                    PyErr_Print();
                                fprintf(stderr, "Cannot find function \"get_struct_format\"\n");
                            }
                        } else {
                            fprintf(stderr, "Cannot find list of header field values\n");
                        }
                    } else {
                        if (PyErr_Occurred())
                            PyErr_Print();
                        fprintf(stderr, "Cannot find function \"get_struct_format\"\n");
                    }
                } else {
                    if (PyErr_Occurred())
                        PyErr_Print();
                    fprintf(stderr, "Cannot find function \"get_struct_format\"\n");
                }
            } else {
                if (PyErr_Occurred())
                    PyErr_Print();
                fprintf(stderr, "Cannot find function \"get_packet_endianness\"\n");
            }
        }
        else {
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr, "Cannot find function \"get_packet_type\"\n");
        }
    } else {
        PyErr_Print();
        printf("Failed to load tvb-parser");
    }

    return tvb_captured_length(tvb);
}

void
proto_register_wibotic(void)
{
    static hf_register_info hf[] = { //add all fields...
        {&hf_packet_type,
            { "Packet Type", "wibotic.packettype",
                FT_UINT8, BASE_HEX,
                NULL, 0x0,
                NULL, HFILL}
        },
        { &hf_device_id,
            { "Device ID", "wibotic.deviceid",
            FT_UINT8, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_adc_data,
            { "ADC Data", "wibotic.adcdata",
            FT_NONE, BASE_NONE,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_sub_adc_data,
            { "ADC Data Field", "wibotic.adcdatafield",
            FT_NONE, BASE_NONE,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_adc_id,
            { "ADC Field ID", "wibotic.adcid",
            FT_UINT16, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_adc_value,
            { "ADC Field Value", "wibotic.adcvalue",
            FT_NONE, BASE_NONE,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_param_id,
            { "Parameter ID", "wibotic.parameterid",
            FT_UINT32, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_value,
            { "Value", "wibotic.value",
            FT_UINT32, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_status,
            { "Status", "wibotic.status",
            FT_UINT8, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
         { &hf_location,
            { "Location", "wibotic.location",
            FT_UINT8, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_data,
            { "Data", "wibotic.data",
            FT_NONE, BASE_NONE,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_devices,
            { "Connected Devices", "wibotic.devices",
            FT_UINT16, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_level,
            { "Severity Level", "wibotic.level",
            FT_UINT8, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_code,
            { "Code", "wibotic.code",
            FT_STRING, BASE_NONE,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_message,
            { "Message", "wibotic.message",
            FT_NONE, BASE_NONE,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_ext_param_id, 
            { "Ext Param ID", "wibotic.extparamid",
            FT_UINT16, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_rssi,
            { "RSSI", "wibotic.rssi",
            FT_UINT8, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_mac_address,
            { "MAC", "wibotic.MAC",
            FT_UINT48, BASE_HEX,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_completion,
            { "Completion", "wibotic.completion",
            FT_UINT8, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_state,
            { "State", "wibotic.state",
            FT_UINT8, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_dest_id, 
            { "Destination ID", "wibotic.dest",
            FT_UINT8, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        },
        { &hf_topic, 
            { "Topic ID", "wibotic.topicid",
            FT_UINT8, BASE_DEC,
            NULL, 0x0,
            NULL, HFILL }
        }  
    };

    static int *ett[] = {
        &ett_wibotic,
        &ett_adc,
        &ett_adc_field
    };

    proto_wibotic = proto_register_protocol (
        "WiBotic Protocol ", /* name        */
        "WiBotic",          /* short name  */
        "wibotic"           /* filter_name */
        );

    proto_register_field_array(proto_wibotic, hf, array_length(hf));
    proto_register_subtree_array(ett, array_length(ett));

    register_postdissector(wibotic_handle);
}

void
proto_reg_handoff_wibotic(void)
{

    wibotic_handle = create_dissector_handle(dissect_wibotic, proto_wibotic);
    dissector_add_string("ws.protocol", "wibotic", wibotic_handle);

    Py_Initialize();
    char filePath[100];

    #ifdef _WIN32
        GetFullPathNameA("tvbparser.py", sizeof(filePath), filePath, NULL);
    #elif __linux__
        Dl_info info;
        dladdr((void*) proto_reg_handoff_wibotic, &info);
        strcpy(filePath, info.dli_fname);
        int len = strlen(filePath);
        filePath[len-10] = '\0';
        strncat(filePath, "python-scripts", 23);
    #endif
    char cmd[300];
    snprintf(cmd, sizeof(cmd), "import sys\nsys.path.append(\"%s\")", filePath);
    PyRun_SimpleString(cmd);
}