New dissector for KNXnetIP protocol
authoralage <sphinxs1988@googlemail.com>
Mon, 25 Aug 2014 09:03:43 +0000 (11:03 +0200)
committerAlexis La Goutte <alexis.lagoutte@gmail.com>
Sun, 28 Sep 2014 14:17:28 +0000 (14:17 +0000)
Bug:10403

Change-Id: I8c733ce69e6d44d1bff0ebbe72995f06212d9d93
Reviewed-on: https://code.wireshark.org/review/3828
Petri-Dish: Michael Mann <mmann78@netscape.net>
Reviewed-by: Evan Huus <eapache@gmail.com>
Petri-Dish: Evan Huus <eapache@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
epan/CMakeLists.txt
epan/dissectors/Makefile.common
epan/dissectors/packet-knxnetip.c [new file with mode: 0644]

index ba06729bf839a1922f86f11026000b8d290418af..4ea6588753aa9faa505932e843c83ad50657bebd 100644 (file)
@@ -876,6 +876,7 @@ set(DISSECTOR_SRC
        dissectors/packet-kismet.c
        dissectors/packet-klm.c
        dissectors/packet-knet.c
+       dissectors/packet-knxnetip.c
        dissectors/packet-kpasswd.c
        dissectors/packet-kt.c
        dissectors/packet-l1-events.c
index 648a9e9cfa412b86f742dccbb50fb7a2605ca14e..f39fa9f818154b2181182fadc22f8763fb1f8ef8 100644 (file)
@@ -798,6 +798,7 @@ DISSECTOR_SRC = \
        packet-kismet.c         \
        packet-klm.c            \
        packet-knet.c           \
+       packet-knxnetip.c       \
        packet-kpasswd.c        \
        packet-kt.c             \
        packet-l1-events.c      \
diff --git a/epan/dissectors/packet-knxnetip.c b/epan/dissectors/packet-knxnetip.c
new file mode 100644 (file)
index 0000000..f6a27f7
--- /dev/null
@@ -0,0 +1,1799 @@
+/* packet-knxnetip.c
+ * Routines for KNXnet/IP dissection
+ * Copyright 2014, Alexander Gaertner <gaertner.alex@gmx.de>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/expert.h>
+
+#define KNXNETIP_PROTOCOL_VERSION 0x10
+#define KNXNETIP_HEADER_LENGTH 0x06
+
+#define SEARCH_REQ 0x0201
+#define SEARCH_RES 0x0202
+#define DESCRIPTION_REQ 0x0203
+#define DESCRIPTION_RES 0x0204
+#define CONNECT_REQ 0x0205
+#define CONNECT_RES 0x0206
+#define CONNECTIONSTATE_REQ 0x0207
+#define CONNECTIONSTATE_RES 0x0208
+#define DISCONNECT_REQ 0x0209
+#define DISCONNECT_RES 0x020A
+#define DEVICE_CONFIGURATION_REQ 0x0310
+#define DEVICE_CONFIGURATION_ACK 0x0311
+#define TUNNELLING_REQ 0x0420
+#define TUNNELLING_ACK 0x0421
+#define ROUTING_INDICATION 0x0530
+#define ROUTING_LOST 0x0531
+#define ROUTING_BUSY 0x0532
+#define REMOTE_DIAG_REQ 0x0740
+#define REMOTE_DIAG_RES 0x0741
+#define REMOTE_BASIC_CONF_REQ 0x0742
+#define REMOTE_RESET_REQ 0x0743
+#define DIB_DEVICE_INFO 0x01
+#define DIB_SUPP_SVC 0x02
+#define DIB_IP_CONF 0x03
+#define DIB_IP_CURRENT 0x04
+#define DIB_KNX_ADDRESS 0x05
+#define DIB_MFR_DATA 0xFE
+#define KNX_TUNNEL_CONNECTION 0x04
+#define FLAGS_DEVICESTATUS_RESERVED 0xFE
+#define FLAGS_DEVICESTATUS_PROGRAM 0x01
+#define FLAGS_IPCAPABILITES_RESERVED 0xF8
+#define FLAGS_IPCAPABILITES_BOOTIP 0x01
+#define FLAGS_IPCAPABILITES_DHCP 0x02
+#define FLAGS_IPCAPABILITES_AUTOIP 0x04
+#define FLAGS_DEVICESTATE_RESERVED 0xFC
+#define FLAGS_DEVICESTATE_KNX 0x01
+#define FLAGS_DEVICESTATE_IP 0x02
+/*for CEMI*/
+#define RAW_REQ 0x10
+#define DATA_REQ 0x11
+#define POLL_DATA_REQ 0x13
+#define POLL_DATA_CON 0x25
+#define DATA_IND 0x29
+#define BUSMON_IND 0x2B
+#define RAW_IND 0x2D
+#define DATA_CON 0x2E
+#define RAW_CON 0x2F
+#define DATA_CONNEC_REQ 0x41
+#define DATA_INDV_REQ 0x4A
+#define DATA_CONNEC_IND 0x89
+#define DATA_INDV_IND 0x94
+#define RESET_IND 0xF0
+#define RESET_REQ 0xF1
+#define PROPWRITE_CON 0xF5
+#define PROPWRITE_REQ 0xF6
+#define PROPINFO_IND 0xF7
+#define FUNCPROPCOM_REQ 0xF8
+#define FUNCPROPSTATREAD_REQ 0xF9
+#define FUNCPROPCOM_CON 0xFA
+#define PROPREAD_CON 0xFB
+#define PROPREAD_REQ 0xFC
+#define PL_INFO 0x1
+#define RF_INFO 0x2
+#define BUSMON_INFO 0x3
+#define TIME_REL 0x4
+#define TIME_DELAY 0x5
+#define EXEND_TIME 0x6
+#define BIBAT_INFO 0x7
+#define RF_MULTI 0x8
+#define PREAMBEL 0x9
+#define RF_FAST_ACK 0xA
+#define MANU_DATA 0xFE
+#define RESER 0xFF
+#define A_GROUPVALUE_RES 0x040
+#define A_GROUPVALUE_WRT 0x080
+#define A_ADC_RED 0x180
+#define A_MEM_RED 0x200
+#define A_MEM_RES 0x240
+#define A_MEM_WRT 0x280
+
+#define FLAGS_CEMI_CONTROL1_FT 0x80
+#define FLAGS_CEMI_CONTROL1_R 0x20
+#define FLAGS_CEMI_CONTROL1_SB 0x10
+#define FLAGS_CEMI_CONTROL1_P 0x0C
+#define FLAGS_CEMI_CONTROL1_A 0x02
+#define FLAGS_CEMI_CONTROL1_C 0x01
+#define FLAGS_CEMI_CONTROL2_AT 0x80
+#define FLAGS_CEMI_CONTROL2_HC 0x70
+#define FLAGS_CEMI_CONTROL2_EFF 0x0F
+#define FLAGS_CEMI_RF_RESERVED 0xC0
+#define FLAGS_CEMI_RF_MESURE 0x30
+#define FLAGS_CEMI_RF_MESURE_RE 0x0C
+#define FLAGS_CEMI_RF_BATTERY 0x02
+#define FLAGS_CEMI_RF_BIDIRETIONAL 0x01
+#define FLAGS_CEMI_BUS_F 0x80
+#define FLAGS_CEMI_BUS_B 0x40
+#define FLAGS_CEMI_BUS_P 0x20
+#define FLAGS_CEMI_BUS_D 0x10
+#define FLAGS_CEMI_BUS_L 0x08
+#define FLAGS_CEMI_BUS_SSS 0x07
+#define FLAGS_CEMI_FASTACK_CRC 0x400
+#define FLAGS_CEMI_FASTACK_ERROR 0x200
+#define FLAGS_CEMI_FASTACK_RES 0x100
+#define FLAGS_CEMI_FASTACK_INFO 0xFF
+
+
+void proto_register_knxnetip(void);
+void proto_reg_handoff_knxnetip(void);
+
+static int proto_knxnetip = -1;
+static int hf_knxnetip_headerlength = -1;
+static int hf_knxnetip_version = -1;
+static int hf_knxnetip_servicetype = -1;
+static int hf_knxnetip_totallength = -1;
+static int hf_knxnetip_hpai = -1;
+static int hf_knxnetip_hpai_structure_length = -1;
+static int hf_knxnetip_hpai_host_protocol = -1;
+static int hf_knxnetip_hpai_ip_address = -1;
+static int hf_knxnetip_hpai_port = -1;
+static int hf_knxnetip_dib = -1;
+static int hf_knxnetip_structure_length = -1;
+static int hf_knxnetip_dib_type = -1;
+static int hf_knxnetip_dib_medium = -1;
+static int hf_knxnetip_knxaddress = -1;
+static int hf_knxnetip_dib_projectid = -1;
+static int hf_knxnetip_dib_serialnumber = -1;
+static int hf_knxnetip_dib_multicast_address = -1;
+static int hf_knxnetip_mac_address = -1;
+static int hf_knxnetip_dib_friendly = -1;
+static int hf_knxnetip_dib_service = -1;
+static int hf_knxnetip_dib_ipaddress = -1;
+static int hf_knxnetip_dib_subnet = -1;
+static int hf_knxnetip_dib_gateway = -1;
+static int hf_knxnetip_dib_ipassign = -1;
+static int hf_knxnetip_dib_dhcp = -1;
+static int hf_knxnetip_dib_manuid = -1;
+static int hf_knxnetip_dib_manudata = -1;
+static int hf_knxnetip_cri = -1;
+static int hf_knxnetip_connection_type = -1;
+static int hf_knxnetip_cri_protocol_data = -1;
+static int hf_knxnetip_communication_channel_id = -1;
+static int hf_knxnetip_crd_protocol_data = -1;
+static int hf_knxnetip_crd = -1;
+static int hf_knxnetip_connect_status = -1;
+static int hf_knxnetip_connectionstate_status = -1;
+static int hf_knxnetip_counter = -1;
+static int hf_knxnetip_confack_status = -1;
+static int hf_knxnetip_tunnelack_status = -1;
+static int hf_knxnetip_numberoflost = -1;
+static int hf_knxnetip_busywaittime = -1;
+static int hf_knxnetip_busycontrol = -1;
+static int hf_knxnetip_knxlayer = -1;
+static int hf_knxnetip_selector_type = -1;
+static int hf_knxnetip_reset = -1;
+static int hf_knxnetip_projectnumber = -1;
+static int hf_knxnetip_installnumber = -1;
+static int hf_knxnetip_dib_svc_version = -1;
+static int hf_knxnetip_reserved = -1;
+static int hf_knxnetip_raw = -1;
+static int hf_knxnetip_data = -1;
+static int hf_knxnetip_additional = -1;
+static int hf_knxnetip_unknown = -1;
+static int hf_knxnetip_polldata = -1;
+
+
+static int hf_knxnetip_cemi = -1;
+static int hf_knxnetip_cemi_mc = -1;
+static int hf_knxnetip_cemi_addlength = -1;
+static int hf_knxnetip_cemi_additemlength = -1;
+static int hf_knxnetip_cemi_typid = -1;
+static int hf_knxnetip_cemi_type_pl = -1;
+static int hf_knxnetip_cemi_type_relt = -1;
+static int hf_knxnetip_cemi_type_delay = -1;
+static int hf_knxnetip_cemi_type_exttime = -1;
+static int hf_knxnetip_cemi_type_bibat = -1;
+static int hf_knxnetip_cemi_sourceaddress = -1;
+static int hf_knxnetip_cemi_destaddress = -1;
+static int hf_knxnetip_cemi_tpci = -1;
+static int hf_knxnetip_cemi_counter = -1;
+static int hf_knxnetip_cemi_npdu_length = -1;
+static int hf_knxnetip_cemi_tpdu_length = -1;
+static int hf_knxnetip_cemi_apci = -1;
+static int hf_knxnetip_cemi_data = -1;
+static int hf_knxnetip_cemi_numberofslots = -1;
+static int hf_knxnetip_cemi_iot = -1;
+static int hf_knxnetip_cemi_oi = -1;
+static int hf_knxnetip_cemi_six = -1;
+static int hf_knxnetip_cemi_pid = -1;
+static int hf_knxnetip_cemi_reserved = -1;
+static int hf_knxnetip_cemi_noe = -1;
+static int hf_knxnetip_cemi_error = -1;
+static int hf_knxnetip_cemi_return = -1;
+static int hf_knxnetip_cemi_numberofelements = -1;
+static int hf_knxnetip_cemi_apci_memory_number = -1;
+static int hf_knxnetip_cemi_rf_lfn = -1;
+static int hf_knxnetip_cemi_type_bibat_block = -1;
+static int hf_knxnetip_cemi_type_rf_multi_fastack = -1;
+static int hf_knxnetip_cemi_type_rf_multi_freq = -1;
+static int hf_knxnetip_cemi_type_rf_multi_channel = -1;
+static int hf_knxnetip_cemi_type_rf_multi_recep_freq = -1;
+static int hf_knxnetip_cemi_rf_sn = -1;
+static int hf_knxnetip_cemi_type_preamble_length = -1;
+static int hf_knxnetip_cemi_type_postamble_length = -1;
+static int hf_knxnetip_cemi_subfunction = -1;
+static int hf_knxnetip_cemi_manuspecificdata = -1;
+
+
+/*FLAGS
+DIB Device Status Flags*/
+static int hf_knxnetip_dib_status = -1;
+static int hf_knxnetip_dib_status_flag_reserved = -1;
+static int hf_knxnetip_dib_status_flag_program = -1;
+static const int *dib_device_status_flags[] = {
+    &hf_knxnetip_dib_status_flag_reserved,
+    &hf_knxnetip_dib_status_flag_program,
+    NULL
+};
+/*DIB IP Capabilities Flags*/
+static int hf_knxnetip_dib_ipcapa = -1;
+static int hf_knxnetip_dib_ipcapa_flag_bootip = -1;
+static int hf_knxnetip_dib_ipcapa_flag_dhcp = -1;
+static int hf_knxnetip_dib_ipcapa_flag_autoip = -1;
+static int hf_knxnetip_dib_ipcapa_flag_reserved = -1;
+static const int *dib_ipcapabilities_flags[] = {
+    &hf_knxnetip_dib_ipcapa_flag_bootip,
+    &hf_knxnetip_dib_ipcapa_flag_dhcp,
+    &hf_knxnetip_dib_ipcapa_flag_autoip,
+    &hf_knxnetip_dib_ipcapa_flag_reserved,
+    NULL
+};
+/*Device State*/
+static int hf_knxnetip_devicestate = -1;
+static int hf_knxnetip_devicestate_reserved = -1;
+static int hf_knxnetip_devicestate_knx = -1;
+static int hf_knxnetip_devicestate_ip = -1;
+static const int *devicestate_flags[] = {
+    &hf_knxnetip_devicestate_knx,
+    &hf_knxnetip_devicestate_ip,
+    &hf_knxnetip_devicestate_reserved,
+    NULL
+};
+/*cEMI FLAGS
+controlfield 1*/
+static int hf_knxnetip_cemi_controlfield1 = -1;
+static int hf_knxnetip_cemi_flag_frametype = -1;
+static int hf_knxnetip_cemi_flag_repeat = -1;
+static int hf_knxnetip_cemi_flag_sb = -1;
+static int hf_knxnetip_cemi_flag_priority = -1;
+static int hf_knxnetip_cemi_flag_ack = -1;
+static int hf_knxnetip_cemi_flag_confirm = -1;
+static const int *cemi_control1_flags[] = {
+    &hf_knxnetip_cemi_flag_frametype,
+    &hf_knxnetip_cemi_flag_repeat,
+    &hf_knxnetip_cemi_flag_sb,
+    &hf_knxnetip_cemi_flag_priority,
+    &hf_knxnetip_cemi_flag_ack,
+    &hf_knxnetip_cemi_flag_confirm,
+    NULL
+};
+/*controlfield 2*/
+static int hf_knxnetip_cemi_controlfield2 = -1;
+static int hf_knxnetip_flag_destaddress = -1;
+static int hf_knxnetip_flag_hop = -1;
+static int hf_knxnetip_flag_eff = -1;
+static const int *cemi_control2_flags[] = {
+    &hf_knxnetip_flag_destaddress,
+    &hf_knxnetip_flag_hop,
+    &hf_knxnetip_flag_eff,
+    NULL
+};
+
+static int hf_knxnetip_cemi_type_rf_info = -1;
+static int hf_knxnetip_cemi_type_rf_reserved = -1;
+static int hf_knxnetip_cemi_type_rf_mesure = -1;
+static int hf_knxnetip_cemi_type_rf_mesure_re = -1;
+static int hf_knxnetip_cemi_type_rf_battery = -1;
+static int hf_knxnetip_cemi_type_rf_bidirekt = -1;
+static const int *cemi_rf_info[] = {
+    &hf_knxnetip_cemi_type_rf_reserved,
+    &hf_knxnetip_cemi_type_rf_mesure,
+    &hf_knxnetip_cemi_type_rf_mesure_re,
+    &hf_knxnetip_cemi_type_rf_battery,
+    &hf_knxnetip_cemi_type_rf_bidirekt,
+    NULL
+};
+
+static int hf_knxnetip_cemi_type_bus = -1;
+static int hf_knxnetip_cemi_type_bus_flag_f = -1;
+static int hf_knxnetip_cemi_type_bus_flag_b = -1;
+static int hf_knxnetip_cemi_type_bus_flag_p = -1;
+static int hf_knxnetip_cemi_type_bus_flag_d = -1;
+static int hf_knxnetip_cemi_type_bus_flag_l = -1;
+static int hf_knxnetip_cemi_type_bus_flag_sss = -1;
+static const int *cemi_bus_flags[] = {
+    &hf_knxnetip_cemi_type_bus_flag_f,
+    &hf_knxnetip_cemi_type_bus_flag_b,
+    &hf_knxnetip_cemi_type_bus_flag_p,
+    &hf_knxnetip_cemi_type_bus_flag_d,
+    &hf_knxnetip_cemi_type_bus_flag_l,
+    &hf_knxnetip_cemi_type_bus_flag_sss,
+    NULL
+};
+
+static int hf_knxnetip_cemi_type_fastack = -1;
+static int hf_knxnetip_cemi_type_fastack_crc = -1;
+static int hf_knxnetip_cemi_type_fastack_error = -1;
+static int hf_knxnetip_cemi_type_fastack_received = -1;
+static int hf_knxnetip_cemi_type_fastack_info = -1;
+static const int *cemi_fastack_flags[] = {
+    &hf_knxnetip_cemi_type_fastack_crc,
+    &hf_knxnetip_cemi_type_fastack_error,
+    &hf_knxnetip_cemi_type_fastack_received,
+    &hf_knxnetip_cemi_type_fastack_info,
+    NULL
+};
+
+
+static const value_string knxnetip_service_identifier[] = {
+    { SEARCH_REQ, "SEARCH_REQUEST" },
+    { SEARCH_RES, "SEARCH_RESPONSE" },
+    { DESCRIPTION_REQ, "DESCRIPTION_REQUEST" },
+    { DESCRIPTION_RES, "DESCRIPTION_RESPONSE" },
+    { CONNECT_REQ, "CONNECT_REQUEST" },
+    { CONNECT_RES, "CONNECT_RESPONSE" },
+    { CONNECTIONSTATE_REQ, "CONNECTIONSTATE_REQUEST" },
+    { CONNECTIONSTATE_RES, "CONNECTIONSTATE_RESPONSE" },
+    { DISCONNECT_REQ, "DISCONNECT_REQUEST" },
+    { DISCONNECT_RES, "DISCONNECT_RESPONSE" },
+    { DEVICE_CONFIGURATION_REQ, "DEVICE_CONFIGURATION_REQUEST" },
+    { DEVICE_CONFIGURATION_ACK, "DEVICE_CONFIGURATION_ACK" },
+    { TUNNELLING_REQ, "TUNNELLING_REQUEST" },
+    { TUNNELLING_ACK, "TUNNELING_ACK" },
+    { ROUTING_INDICATION, "ROUTING_INDICATION" },
+    { ROUTING_LOST, "ROUTING_LOST_MESSAGE" },
+    { ROUTING_BUSY, "ROUTING_BUSY" },
+    { REMOTE_DIAG_REQ, "REMOTE_DIAGNOSTIC_REQUEST" },
+    { REMOTE_DIAG_RES, "REMOTE_DIAGNOSTIC_RESPONSE" },
+    { REMOTE_BASIC_CONF_REQ, "REMOTE_BASIC_CONFIGURATION_REQUEST" },
+    { REMOTE_RESET_REQ, "REMOTE_RESET_REQUEST" },
+    { 0, NULL }
+};
+
+
+static const value_string knxnetip_service_types[] = {
+    { 0x02, "KNXnet/IP Core" },
+    { 0x03, "KNXnet/IP Device Management" },
+    { 0x04, "KNXnet/IP Tunneling" },
+    { 0x05, "KNXnet/IP Routing" },
+    { 0x06, "KNXnet/IP Remote Logging" },
+    { 0x07, "KNXnet/IP Remote Configuration and Diagnosis" },
+    { 0x08, "KNXnet/IP Object Server" },
+    { 0, NULL }
+};
+
+static const value_string knxnetip_connection_types[] = {
+    { 0x03, "DEVICE_MGMT_CONNECTION" },
+    { 0x04, "TUNNEL_CONNECTION" },
+    { 0x06, "REMLOG_CONNECTION" },
+    { 0x07, "REMCONF_CONNECTION" },
+    { 0x08, "OBJSVR_CONNECTION" },
+    { 0, NULL }
+};
+
+
+static const value_string knxnetip_connect_response_status_codes[] = {
+    { 0x00, "E_NO_ERROR - The connection was established successfully" },
+    { 0x22, "E_CONNECTION_TYPE - The KNXnet/IP server device does not support the requested connection type" },
+    { 0x23, "E_CONNECTION_OPTION - The KNXnet/IP server device does not support one or more requested connection options" },
+    { 0x24, "E_NO_MORE_CONNECTIONS - The KNXnet/IP server device could not accept the new data connection (busy)" },
+    { 0, NULL }
+};
+
+static const value_string knxnetip_connectionstate_response_status_codes[] = {
+    { 0x00, "E_NO_ERROR - The connection state is normal" },
+    { 0x21, "E_CONNECTION_ID - The KNXnet/IP server device could not find an active data connection with the specified ID" },
+    { 0x26, "E_DATA_CONNECTION - The KNXnet/IP server device detected an error concerning the data connection with the specified ID" },
+    { 0x27, "E_KNX_CONNECTION - The KNXnet/IP server device detected an error concerning the EIB bus / KNX subsystem connection with the specified ID" },
+    { 0, NULL }
+};
+
+static const value_string knxnetip_tunneling_error_codes[] = {
+    { 0x00, "E_NO_ERROR - The message was received succesfully" },
+    { 0x29, "E_TUNNELLING_LAYER - The KNXnet/IP server device does not support the requested tunnelling layer" },
+    { 0, NULL }
+};
+
+static const value_string knxnetip_device_configuration_ack_status_codes[] = {
+    { 0x00, "E_NO_ERROR - The message was received succesfully" },
+    { 0, NULL }
+};
+
+static const value_string knxnetip_dib_description_type_codes[] = {
+    { DIB_DEVICE_INFO, "DEVICE_INFO" },
+    { DIB_SUPP_SVC, "SUPP_SVC_FAMILIES" },
+    { DIB_IP_CONF, "IP_CONFIG" },
+    { DIB_IP_CURRENT, "IP_CUR_CONFIG" },
+    { DIB_KNX_ADDRESS, "KNX_ADDRESSES" },
+    { DIB_MFR_DATA, "MFR_DATA" },
+    { 0, NULL }
+};
+
+static const value_string knxnetip_dib_medium_codes[] = {
+    { 0x01, "reserved" },
+    { 0x02, "KNX TP" },
+    { 0x04, "KNX PL110" },
+    { 0x08, "reserved" },
+    { 0x10, "KNX RF" },
+    { 0x20, "KNX IP" },
+    { 0, NULL }
+};
+
+static const value_string knxnetip_host_protocol_codes[] = {
+    { 0x01, "IPV4_UDP" },
+    { 0x02, "IPV4_TCP" },
+    { 0, NULL }
+};
+
+static const value_string knxnetip_ip_assignment_method[] = {
+    { 0x01, "manuell" },
+    { 0x02, "BootP" },
+    { 0x04, "DHCP" },
+    { 0x08, "AutoIP" },
+    { 0, NULL }
+};
+
+static const value_string knxnetip_knxlayer_values[] = {
+    { 0x02, "TUNNEL_LINKLAYER" },
+    { 0x04, "TUNNEL_RAW"},
+    { 0x80, "TUNNEL_BUSMONITOR"},
+    { 0, NULL}
+};
+
+static const value_string knxnetip_selector_types[] = {
+    { 0x01, "PrgMode Selector" },
+    { 0x02, "MAC Selector" },
+    { 0, NULL }
+};
+
+static const value_string knxnetip_reset_codes[] = {
+    { 0x01, "Restart" },
+    { 0x02, "Master Reset" },
+    { 0, NULL }
+};
+
+/*for CEMI*/
+static const value_string cemi_messagecodes[] = {
+    { RAW_REQ, "L_Raw.req"},
+    { DATA_REQ, "L_Data.req"},
+    { POLL_DATA_REQ, "L_Poll_Data.req"},
+    { POLL_DATA_CON, "L_Poll_Data.con"},
+    { DATA_IND, "L_Data.ind"},
+    { BUSMON_IND, "L_Busmon.ind"},
+    { RAW_IND, "L_Raw.ind"},
+    { DATA_CON, "L_Data.con"},
+    { RAW_CON, "L_Raw.con"},
+    { DATA_CONNEC_REQ, "T_Data_Connected.req"},
+    { DATA_INDV_REQ, "T_Data_Individual.req"},
+    { DATA_CONNEC_IND, "T_Data_Connected.ind"},
+    { DATA_INDV_IND,  "T_Data_Individual.ind"},
+    { RESET_IND,  "M_Reset.ind"},
+    { RESET_REQ, "M_Reset.req"},
+    { PROPWRITE_CON, "M_PropWrite.con"},
+    { PROPWRITE_REQ, "M_PropWrite.req"},
+    { PROPINFO_IND, "M_PropInfo.ind"},
+    { FUNCPROPCOM_REQ, "M_FuncPropCommand.req"},
+    { FUNCPROPSTATREAD_REQ, "M_FuncPropStateRead.req"},
+    { FUNCPROPCOM_CON, "M_FuncPropCommand/StateRead.con"},
+    { PROPREAD_CON, "M_PropRead.con"},
+    { PROPREAD_REQ,  "M_PropRead.req"},
+    { 0, NULL }
+};
+
+static const value_string cemi_add_type_id[] = {
+    { 0x00, "reserved" },
+    { PL_INFO, "PL Info"},
+    { RF_INFO, "RF Info"},
+    { BUSMON_INFO, "Busmonitor Info"},
+    { TIME_REL, "relative timestamp"},
+    { TIME_DELAY, "time delay until send"},
+    { EXEND_TIME, "extended relative timestamp"},
+    { BIBAT_INFO, "BiBat information"},
+    { RF_MULTI, "RF Multi information"},
+    { PREAMBEL, "Preamble and postamble"},
+    { RF_FAST_ACK, "RF Fast Ack information"},
+    { MANU_DATA, "Manufacturer specific data"},
+    { RESER, "reserved"},
+    { 0, NULL}
+};
+
+static const value_string cemi_tpci_vals[] = {
+    { 0x0, "UDT (Unnumbered Data Packet)" },
+    { 0x2, "UCD (Unnumbered)"},
+    { 0x1, "NDT (Numbered Data Packet)"},
+    { 0x3, "NCD (Numbered Control Data)"},
+    { 0, NULL}
+};
+
+static const value_string cemi_apci_codes[] = {
+    { 0x00, "A_GroupValue_Read" },
+    { 0x1, "A_GroupValue_Response"},
+    { 0x2, "A_GroupValue_Write"},
+    { 0x0C0, "A_IndividualAddress_Write"},
+    { 0x100, "A_IndividualAddress_Read"},
+    { 0x140, "A_IndividualAddress_Response"},
+    { 0x6, "A_ADC_Read"},
+    { 0x1C0, "A_ADC_Response"},
+    { 0x1C4, "A_SystemNetworkParameter_Read"},
+    { 0x1C9, "A_SystemNetworkParameter_Response"},
+    { 0x1CA, "A_SystemNetworkParameter_Write"},
+    { 0x20, "A_Memory_Read"},
+    { 0x24, "A_Memory_Response"},
+    { 0x28, "A_Memory_Write"},
+    { 0x2C0, "A_UserMemory_Read"},
+    { 0x2C1, "A_UserMemory_Response"},
+    { 0x2C2, "A_UserMemory_Write"},
+    { 0x2C5, "A_UserManufacturerInfo_Read"},
+    { 0x2C6, "A_UserManufacturerInfo_Response"},
+    { 0x2C7, "A_FunctionPropertyCommand"},
+    { 0x2C8, "A_FunctionPropertyState_Read"},
+    { 0x2C9, "A_FunctionPropertyState_Response"},
+    { 0x300, "A_DeviceDescriptor_Read"},
+    { 0x340, "A_DeviceDescriptor_Response"},
+    { 0x380, "A_Restart"},
+    { 0x3D1, "A_Authorize_Request"},
+    { 0x3D2, "A_Authorize_Response"},
+    { 0x3D3, "A_Key_Write"},
+    { 0x3D4, "A_Key_Response"},
+    { 0x3D5, "A_PropertyValue_Read"},
+    { 0x3D6, "A_PropertyValue_Response"},
+    { 0x3D7, "A_PropertyValue_Write"},
+    { 0x3D8, "A_PropertyDescription_Read"},
+    { 0x3D9, "A_PropertyDescription_Response"},
+    { 0x3DA, "A_NetworkParameter_Read"},
+    { 0x3DB, "A_NetworkParameter_Response"},
+    { 0x3DC, "A_IndividualAddressSerialNumber_Read"},
+    { 0x3DD, "A_IndividualAddressSerialNumber_Response"},
+    { 0x3DF, "A_IndividualAddressSerialNumber_Write"},
+    { 0x3E0, "A_DomainAddress_Write"},
+    { 0x3E1, "A_DomainAddress_Read"},
+    { 0x3E2, "A_DomainAddress_Response"},
+    { 0x3E3, "A_DomainAddressSelective_Read"},
+    { 0x3E4, "A_NetworkParameter_Write"},
+    { 0x3E5, "A_Link_Read"},
+    { 0x3E6, "A_Link_Response"},
+    { 0x3E7, "A_Link_Write"},
+    { 0x3E8, "A_GroupPropValue_Read"},
+    { 0x3E9, "A_GroupPropValue_Response"},
+    { 0x3EA, "A_GroupPropValue_Write"},
+    { 0x3EB, "A_GroupPropValue_InfoReport"},
+    { 0x3EC, "A_DomainAddressSerialNumber_Read"},
+    { 0x3ED, "A_DomainAddressSerialNumber_Response"},
+    { 0x3EE, "A_DomainAddressSerialNumber_Write"},
+    { 0x3F0, "A_FileStream_InforReport"},
+    { 0, NULL}
+};
+
+static const value_string cemi_propertyid[] = {
+    { 1, "PID_OBJECT_TYPE" },
+    { 8, "PID_SERVICE_CONTROL" },
+    { 9, "PID_FIRMWARE_REVISION" },
+    { 11, "PID_SERIAL_NUMBER" },
+    { 12, "PID_MANUFACTURER_ID" },
+    { 14, "PID_DEVICE_CONTROL" },
+    { 19, "PID_MANUFACTURE_DATA" },
+    { 51, "PID_ROUTING_COUNT" },
+    { 52, "PID_MAX_RETRY_COUNT " },
+    { 53, "PID_ERROR_FLAGS" },
+    { 54, "PID_PROGMODE" },
+    { 56, "PID_MAX_APDULENGTH" },
+    { 57, "PID_SUBNET_ADDR" },
+    { 58, "PID_DEVICE_ADDR" },
+    { 59, "PID_PB_CONFIG" },
+    { 60, "PID_ADDR_REPORT" },
+    { 61, "PID_ADDR_CHECK" },
+    { 62, "PID_OBJECT_VALUE" },
+    { 63, "PID_OBJECTLINK" },
+    { 64, "PID_APPLICATION" },
+    { 65, "PID_PARAMETER" },
+    { 66, "PID_OBJECTADDRESS" },
+    { 67, "PID_PSU_TYPE" },
+    { 68, "PID_PSU_STATUS" },
+    { 70, "PID_DOMAIN_ADDR"},
+    { 71, "PID_IO_LIST"},
+    { 0, NULL }
+};
+
+static const value_string cemi_error_codes[] = {
+    { 0x00, "Unspecified Error"},
+    { 0x01, "Out of range"},
+    { 0x02, "Out of maxrange"},
+    { 0x03, "Out of minrange"},
+    { 0x04, "Memory Error"},
+    { 0x05, "Read only"},
+    { 0x06, "Illegal command"},
+    { 0x07, "Void DP"},
+    { 0x08, "Type conflict"},
+    { 0x09, "Prop. Index range error"},
+    { 0x0A, "Value temporarily not writeable"},
+    { 0, NULL }
+};
+
+static const value_string cemi_bibat_ctrl[] = {
+    { 0x0, "asynchr. RF frame"},
+    { 0x1, "Fast_ACK"},
+    { 0x4, "synchronous L_Data frames"},
+    { 0x5, "Sync frame"},
+    { 0x6, "Help Call"},
+    { 0x7, "Help Call Response"},
+    { 0, NULL }
+};
+
+static gint ett_knxnetip = -1;
+static gint ett_knxnetip_header = -1;
+static gint ett_knxnetip_body = -1;
+static gint ett_knxnetip_hpai = -1;
+static gint ett_knxnetip_dib = -1;
+static gint ett_knxnetip_dib_projectid = -1;
+static gint ett_knxnetip_dib_service = -1;
+static gint ett_knxnetip_cri = -1;
+static gint ett_knxnetip_crd = -1;
+static gint ett_knxnetip_dib_status = -1;
+static gint ett_knxnetip_dib_ipcapa = -1;
+static gint ett_knxnetip_devicestate = -1;
+static gint ett_knxnetip_cemi = -1;
+static gint ett_knxnetip_cemi_additional = -1;
+static gint ett_knxnetip_cemi_additional_item = -1;
+static gint ett_knxnetip_cemi_control1 = -1;
+static gint ett_knxnetip_cemi_control2 = -1;
+static gint ett_knxnetip_cemi_rf_info = -1;
+static gint ett_knxnetip_cemi_bus_info = -1;
+static gint ett_knxnetip_cemi_fastack = -1;
+
+static expert_field ei_knxnetip_length = EI_INIT;
+
+static void dissect_hpai(tvbuff_t *tvb, guint32 *offset, proto_tree *insert_tree, const char *append_text) {
+
+    proto_item *hpai_item = NULL;
+    proto_item *slength = NULL;
+
+    proto_tree *hpai_tree = NULL;
+
+    hpai_item = proto_tree_add_item( insert_tree, hf_knxnetip_hpai, tvb, *offset, 8, ENC_NA );
+    hpai_tree = proto_item_add_subtree(hpai_item, ett_knxnetip_hpai);
+    proto_item_append_text(hpai_item, "%s", append_text);
+    slength= proto_tree_add_item(hpai_tree, hf_knxnetip_hpai_structure_length, tvb, *offset, 1, ENC_BIG_ENDIAN);
+    proto_item_append_text(slength, " octets");
+    *offset+=1;
+    proto_tree_add_item(hpai_tree, hf_knxnetip_hpai_host_protocol, tvb, *offset, 1, ENC_BIG_ENDIAN);
+    *offset+=1;
+    proto_tree_add_item(hpai_tree, hf_knxnetip_hpai_ip_address, tvb, *offset, 4, ENC_BIG_ENDIAN);
+    *offset+=4;
+    proto_tree_add_item(hpai_tree, hf_knxnetip_hpai_port, tvb, *offset, 2, ENC_BIG_ENDIAN);
+    *offset+=2;
+
+};
+
+static gboolean dissect_dib(tvbuff_t *tvb, guint32 *offset, proto_tree *insert_tree) {
+
+    proto_item *dib_item = NULL;
+    proto_item *struct_length = NULL;
+    proto_item *projectid_item = NULL;
+    proto_item *service_item = NULL;
+
+    proto_tree *dib_tree = NULL;
+    proto_tree *projectid_tree = NULL;
+    proto_tree *service_tree = NULL;
+
+    guint8 i;
+    guint8 dib_type;
+    guint8 length;
+    guint16 knx_address;
+    guint16 install_id;
+
+    length = tvb_get_guint8(tvb, *offset);
+    dib_item = proto_tree_add_item(insert_tree, hf_knxnetip_dib, tvb, *offset, length, ENC_NA);
+    dib_tree = proto_item_add_subtree(dib_item, ett_knxnetip_dib);
+    struct_length= proto_tree_add_item(dib_tree, hf_knxnetip_structure_length, tvb, *offset, 1, ENC_BIG_ENDIAN);
+    proto_item_append_text(struct_length, " octets");
+    *offset+=1;
+    proto_tree_add_item(dib_tree, hf_knxnetip_dib_type, tvb, *offset, 1, ENC_BIG_ENDIAN);
+    dib_type = tvb_get_guint8(tvb, *offset);
+    proto_item_append_text(dib_item, ": %s", val_to_str_const(dib_type, knxnetip_dib_description_type_codes, "Unknown Type"));
+    *offset+=1;
+
+    switch (dib_type){
+
+        case(DIB_DEVICE_INFO):
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_medium, tvb, *offset, 1, ENC_BIG_ENDIAN);
+            *offset+=1;
+            proto_tree_add_bitmask(dib_tree, tvb, *offset, hf_knxnetip_dib_status, ett_knxnetip_dib_status, dib_device_status_flags, ENC_BIG_ENDIAN);
+            *offset+=1;
+            knx_address = tvb_get_ntohs(tvb, *offset);
+            proto_tree_add_uint_format(dib_tree, hf_knxnetip_knxaddress, tvb, *offset, 2, knx_address, "KNX Address %d.%d.%d", ((knx_address & 0xF000)>>12),((knx_address & 0x0F00)>>8),(knx_address & 0xFF));
+            *offset+=2;
+            projectid_item = proto_tree_add_item(dib_tree, hf_knxnetip_dib_projectid, tvb, *offset, 2, ENC_BIG_ENDIAN);
+            projectid_tree = proto_item_add_subtree(projectid_item, ett_knxnetip_dib_projectid);
+            install_id = tvb_get_ntohs(tvb, *offset);
+            proto_tree_add_uint_format(projectid_tree, hf_knxnetip_projectnumber, tvb, *offset, 2, install_id, "Project number %d", (install_id & 0xFFF0)>>4);
+            proto_tree_add_uint_format(projectid_tree, hf_knxnetip_installnumber, tvb, *offset, 2, install_id, "Installation number %d", (install_id & 0xF));
+            *offset+=2;
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_serialnumber, tvb, *offset, 6, ENC_NA);
+            *offset+=6;
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_multicast_address, tvb, *offset, 4, ENC_BIG_ENDIAN);
+            *offset+=4;
+            proto_tree_add_item(dib_tree, hf_knxnetip_mac_address, tvb, *offset, 6, ENC_NA);
+            *offset+=6;
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_friendly, tvb, *offset, 30, ENC_ASCII|ENC_NA );
+            *offset+=30;
+            break;
+
+        case(DIB_SUPP_SVC):
+             if (length > 4) {
+                length-=4;
+             } else {
+                return TRUE;
+             }
+
+             for (i = 0; i <= length; i+=2) {
+                 service_item = proto_tree_add_item(dib_tree, hf_knxnetip_dib_service, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                 service_tree = proto_item_add_subtree(service_item, ett_knxnetip_dib_service);
+                 *offset+=1;
+                 proto_tree_add_item(service_tree, hf_knxnetip_dib_svc_version, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                 *offset+=1;
+             }
+             break;
+
+        case(DIB_IP_CONF):
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_ipaddress, tvb, *offset, 4, ENC_BIG_ENDIAN);
+            *offset+=4;
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_subnet, tvb, *offset, 4, ENC_BIG_ENDIAN);
+            *offset+=4;
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_gateway, tvb, *offset, 4, ENC_BIG_ENDIAN);
+            *offset+=4;
+            proto_tree_add_bitmask(dib_tree, tvb, *offset, hf_knxnetip_dib_ipcapa, ett_knxnetip_dib_ipcapa, dib_ipcapabilities_flags, ENC_BIG_ENDIAN);
+            *offset+=1;
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_ipassign, tvb, *offset, 1, ENC_BIG_ENDIAN);
+            *offset+=1;
+            break;
+
+        case(DIB_IP_CURRENT):
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_ipaddress, tvb, *offset, 4, ENC_BIG_ENDIAN);
+            *offset+=4;
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_subnet, tvb, *offset, 4, ENC_BIG_ENDIAN);
+            *offset+=4;
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_gateway, tvb, *offset, 4, ENC_BIG_ENDIAN);
+            *offset+=4;
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_dhcp, tvb, *offset, 4, ENC_BIG_ENDIAN);
+            *offset+=4;
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_ipassign, tvb, *offset, 1, ENC_BIG_ENDIAN);
+            *offset+=1;
+            proto_tree_add_item(dib_tree, hf_knxnetip_reserved, tvb, *offset, 1, ENC_NA);
+            *offset+=1;
+            break;
+
+        case(DIB_KNX_ADDRESS):
+            if (length > 4) {
+                length-=4;
+            } else {
+                return TRUE;
+            }
+
+            for (i = 0; i <= length; i+=2) {
+                knx_address = tvb_get_ntohs(tvb, *offset);
+                proto_tree_add_uint_format(dib_tree, hf_knxnetip_knxaddress, tvb, *offset, 2, knx_address, "KNX Address %d.%d.%d", ((knx_address & 0xF000)>>12),((knx_address & 0x0F00)>>8),(knx_address & 0xFF));
+                *offset+=2;
+             }
+             break;
+
+        case(DIB_MFR_DATA):
+            if (length > 4) {
+                length-=4;
+            } else {
+                return TRUE;
+            }
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_manuid, tvb, *offset, 2, ENC_BIG_ENDIAN);
+            *offset+=2;
+            proto_tree_add_item(dib_tree, hf_knxnetip_dib_manudata, tvb, *offset, length, ENC_ASCII|ENC_NA);
+            *offset+=length;
+            break;
+    }
+
+    return FALSE;
+};
+
+static guint dissect_cri(tvbuff_t *tvb, guint32 offset, proto_tree *insert_tree) {
+
+    proto_item *cri_item = NULL;
+    proto_item *cri_length = NULL;
+    proto_tree *cri_tree = NULL;
+
+    guint8 length;
+
+    length = tvb_get_guint8(tvb ,offset);
+    cri_item = proto_tree_add_item(insert_tree, hf_knxnetip_cri, tvb, offset, length, ENC_NA);
+    cri_tree = proto_item_add_subtree(cri_item, ett_knxnetip_cri);
+
+    cri_length= proto_tree_add_item(cri_tree, hf_knxnetip_structure_length, tvb, offset, 1, ENC_BIG_ENDIAN);
+    proto_item_append_text(cri_length, " octets");
+    offset+=1;
+    proto_tree_add_item(cri_tree, hf_knxnetip_connection_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+    offset+=1;
+    if (tvb_get_guint8(tvb,offset-1)== KNX_TUNNEL_CONNECTION ){
+        proto_tree_add_item(cri_tree, hf_knxnetip_knxlayer, tvb, offset, 1, ENC_BIG_ENDIAN);
+        offset+=1;
+        proto_tree_add_item(cri_tree, hf_knxnetip_reserved, tvb, offset, 1, ENC_NA);
+        offset+=1;
+    }
+    else if (length > 2) {
+        proto_tree_add_item(cri_tree, hf_knxnetip_cri_protocol_data, tvb, offset, (length-2), ENC_NA);
+        offset+=(length-2);
+    }
+    return offset;
+};
+
+static void dissect_crd(tvbuff_t *tvb, guint32 *offset, proto_tree *insert_tree) {
+
+    proto_item *crd_item = NULL;
+    proto_item *crd_length = NULL;
+    proto_tree *crd_tree = NULL;
+
+    guint8 length;
+    guint16 knx_address;
+
+    length = tvb_get_guint8(tvb, *offset);
+    crd_item = proto_tree_add_item(insert_tree, hf_knxnetip_crd, tvb, *offset, length, ENC_NA);
+    crd_tree = proto_item_add_subtree(crd_item, ett_knxnetip_crd);
+
+    crd_length= proto_tree_add_item(crd_tree, hf_knxnetip_structure_length, tvb, *offset, 1, ENC_BIG_ENDIAN);
+    proto_item_append_text(crd_length, " octets");
+    *offset+=1;
+    proto_tree_add_item(crd_tree, hf_knxnetip_connection_type, tvb, *offset, 1, ENC_BIG_ENDIAN);
+    *offset+=1;
+    if (tvb_get_guint8(tvb, *offset-1) == KNX_TUNNEL_CONNECTION){
+        knx_address = tvb_get_ntohs(tvb, *offset);
+        proto_tree_add_uint_format(crd_tree, hf_knxnetip_knxaddress, tvb, *offset, 2, knx_address, "KNX Address %d.%d.%d", ((knx_address & 0xF000)>>12),((knx_address & 0x0F00)>>8),(knx_address & 0xFF));
+        *offset+=2;
+    }
+    else if (length > 2) {
+        proto_tree_add_item(crd_tree, hf_knxnetip_crd_protocol_data, tvb, *offset, (length-2), ENC_NA);
+        *offset+=(length-2);
+    }
+};
+
+static guint dissect_connection_header(tvbuff_t *tvb, guint32 offset, proto_tree *insert_tree, gboolean have_status) {
+
+    proto_item *struct_length = NULL;
+
+    struct_length= proto_tree_add_item(insert_tree, hf_knxnetip_structure_length, tvb, offset, 1, ENC_BIG_ENDIAN);
+    proto_item_append_text(struct_length, " octets");
+    offset+=1;
+    proto_tree_add_item(insert_tree, hf_knxnetip_communication_channel_id, tvb, offset, 1, ENC_BIG_ENDIAN);
+    offset+=1;
+    proto_tree_add_item(insert_tree, hf_knxnetip_counter, tvb, offset, 1, ENC_BIG_ENDIAN);
+    offset+=1;
+    if (have_status == FALSE){
+        proto_tree_add_item(insert_tree, hf_knxnetip_reserved, tvb, offset, 1, ENC_NA);
+        offset+=1;
+    }
+
+    return offset;
+};
+
+static guint dissect_selector(tvbuff_t *tvb, guint32 offset, proto_tree *insert_tree){
+
+    proto_item *struct_length = NULL;
+
+    struct_length= proto_tree_add_item(insert_tree, hf_knxnetip_structure_length, tvb, offset, 1, ENC_BIG_ENDIAN);
+    proto_item_append_text(struct_length, " octets");
+    offset+=1;
+    proto_tree_add_item(insert_tree, hf_knxnetip_selector_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+    offset+=1;
+    if (tvb_get_guint8(tvb, offset-1)==0x02){
+        proto_tree_add_item(insert_tree, hf_knxnetip_mac_address, tvb, offset, 6, ENC_NA);
+        offset+=6;
+    }
+    return offset;
+};
+
+static void dissect_apci(tvbuff_t *tvb, guint32 *offset, proto_tree *insert_tree, gboolean tpdu){
+
+    guint16 type;
+    guint8 length;
+
+    length = tvb_get_guint8(tvb, *offset-1);
+    if (tpdu == TRUE){
+        proto_tree_add_bits_item(insert_tree, hf_knxnetip_cemi_reserved, tvb, (*offset*8), 6, ENC_BIG_ENDIAN);
+    }
+    else {
+        proto_tree_add_bits_item(insert_tree, hf_knxnetip_cemi_tpci, tvb, (*offset*8), 2, ENC_BIG_ENDIAN);
+        type = (tvb_get_guint8(tvb, *offset)&0xC0);
+        if (type == 0x40 || type == 0xC0){
+            proto_tree_add_bits_item(insert_tree, hf_knxnetip_cemi_counter, tvb, ((*offset*8)+2), 4, ENC_BIG_ENDIAN);
+        }
+    }
+
+    if (length != 0) {
+        type = (tvb_get_ntohs(tvb, *offset) & 0x03C0);
+
+        if (type == A_GROUPVALUE_RES || type == A_GROUPVALUE_WRT || type == A_ADC_RED){
+            proto_tree_add_bits_item(insert_tree, hf_knxnetip_cemi_apci, tvb, (*offset*8)+6, 4, ENC_BIG_ENDIAN);
+            proto_tree_add_bits_item(insert_tree, hf_knxnetip_cemi_data, tvb, (*offset*8)+10, 6, ENC_BIG_ENDIAN);
+        }
+        else if(type == A_MEM_RED || type == A_MEM_RES || type == A_MEM_WRT ){
+            proto_tree_add_bits_item(insert_tree, hf_knxnetip_cemi_apci, tvb, (*offset*8)+6, 6, ENC_BIG_ENDIAN);
+            proto_tree_add_bits_item(insert_tree, hf_knxnetip_cemi_apci_memory_number, tvb, (*offset*8)+12, 4, ENC_BIG_ENDIAN);
+        }
+        else {
+            proto_tree_add_bits_item(insert_tree, hf_knxnetip_cemi_apci, tvb, (*offset*8)+6, 10, ENC_BIG_ENDIAN);
+        }
+        *offset+=2;
+        if (length >= 1){
+           length-=1;
+        }
+
+        if (length >= 1){
+            proto_tree_add_item(insert_tree, hf_knxnetip_data, tvb, *offset, -1, ENC_NA);
+            *offset+=length;
+        }
+
+    }
+    else {
+        *offset+=1;
+    }
+
+};
+
+
+static gboolean dissect_cemi(tvbuff_t *tvb, guint32 *offset, proto_tree *insert_tree, packet_info *pinfo){
+
+    proto_item *cemi_item = NULL;
+    proto_item *additional_info_totallength = NULL;
+    proto_item *additional_item = NULL;
+    proto_item *additional_info = NULL;
+    proto_item *tpdu_length = NULL;
+    proto_item *npdu_length = NULL;
+
+    proto_tree *cemi_tree = NULL;
+    proto_tree *additional_tree = NULL;
+    proto_tree *additional_subtree = NULL;
+
+    guint8 i;
+    guint8 messagecode;
+    guint8 length;
+    guint8 type_id;
+    guint8 noe;
+    guint8 num_of_octets;
+    guint16 knx_address;
+    guint16 six;
+
+    cemi_item = proto_tree_add_item(insert_tree, hf_knxnetip_cemi, tvb, *offset, -1, ENC_NA);
+    cemi_tree = proto_item_add_subtree(cemi_item, ett_knxnetip_cemi);
+    messagecode = tvb_get_guint8(tvb, *offset);
+    proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_mc, tvb, *offset, 1, ENC_BIG_ENDIAN);
+    col_append_fstr(pinfo->cinfo, COL_INFO, "| cEMI: %s", val_to_str(messagecode, cemi_messagecodes, "Unknown MC:0x%0x"));
+    *offset+=1;
+    /*check if M_ Message*/
+    if ((messagecode & 0xF0) < 0xF0){
+        length = tvb_get_guint8(tvb, *offset);
+        additional_info_totallength= proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_addlength, tvb, *offset, 1, ENC_BIG_ENDIAN);
+        proto_item_append_text(additional_info_totallength, " octets");
+        *offset+=1;
+
+        if (length != 0){
+
+            additional_info = proto_tree_add_item(cemi_tree, hf_knxnetip_additional, tvb, *offset, length, ENC_NA);
+            additional_tree = proto_item_add_subtree(additional_info, ett_knxnetip_cemi_additional);
+            do {
+                type_id = tvb_get_guint8(tvb, *offset);
+                additional_item = proto_tree_add_item(additional_tree, hf_knxnetip_cemi_typid, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                additional_subtree = proto_item_add_subtree(additional_item, ett_knxnetip_cemi_additional_item);
+                *offset+=1;
+                additional_info_totallength= proto_tree_add_item(additional_item, hf_knxnetip_cemi_additemlength, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                proto_item_append_text(additional_info_totallength, " octets");
+                *offset+=1;
+                if (length >= 2){
+                    length-=2;
+                }
+                else{
+                    return TRUE;
+                }
+
+                switch(type_id){
+                    case(PL_INFO):
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_type_pl, tvb, *offset, 2, ENC_BIG_ENDIAN);
+                        *offset+=2;
+                        if (length >= 2){
+                            length-=2;
+                        }
+                        else{
+                            return TRUE;
+                        }
+                        break;
+                    case(RF_INFO):
+                        proto_tree_add_bitmask(additional_subtree, tvb, *offset, hf_knxnetip_cemi_type_rf_info, ett_knxnetip_cemi_rf_info, cemi_rf_info, ENC_BIG_ENDIAN);
+                        *offset+=1;
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_rf_sn, tvb, *offset, 6, ENC_BIG_ENDIAN);
+                        *offset+=6;
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_rf_lfn, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                        *offset+=1;
+                        if (length >= 8){
+                            length-=8;
+                        }
+                        else{
+                            return TRUE;
+                        }
+                        break;
+                    case(BUSMON_INFO):
+                        proto_tree_add_bitmask(additional_subtree, tvb, *offset, hf_knxnetip_cemi_type_bus, ett_knxnetip_cemi_bus_info, cemi_bus_flags, ENC_BIG_ENDIAN);
+                        *offset+=1;
+                        if (length >= 1){
+                            length-=1;
+                        }
+                        else{
+                            return TRUE;
+                        }
+                        break;
+                    case(TIME_REL):
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_type_relt, tvb, *offset, 2, ENC_BIG_ENDIAN);
+                        *offset+=2;
+                        if (length >= 2){
+                            length-=2;
+                        }
+                        else{
+                            return TRUE;
+                        }
+                        break;
+                    case(TIME_DELAY):
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_type_delay, tvb, *offset, 4, ENC_BIG_ENDIAN);
+                        *offset+=4;
+                        if (length >= 4){
+                            length-=4;
+                        }
+                        else{
+                            return TRUE;
+                        }
+                        break;
+                    case(EXEND_TIME):
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_type_exttime, tvb, *offset, 4, ENC_BIG_ENDIAN);
+                        *offset+=4;
+                        if (length >= 4){
+                            length-=4;
+                        }
+                        else{
+                            return TRUE;
+                        }
+                        break;
+                    case(BIBAT_INFO):
+                        proto_tree_add_bits_item(additional_subtree, hf_knxnetip_cemi_type_bibat, tvb, (*offset*8), 4, ENC_BIG_ENDIAN);
+                        *offset+=1;
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_type_bibat_block, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                        *offset+=1;
+                        if (length >= 2){
+                            length-=2;
+                        }
+                        else{
+                            return TRUE;
+                        }
+                        break;
+                    case(RF_MULTI):
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_type_rf_multi_freq, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                        *offset+=1;
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_type_rf_multi_channel, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                        *offset+=1;
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_type_rf_multi_fastack, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                        *offset+=1;
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_type_rf_multi_recep_freq, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                        *offset+=1;
+                        if (length >= 4){
+                            length-=4;
+                        }
+                        else{
+                            return TRUE;
+                        }
+                        break;
+                    case(PREAMBEL):
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_type_preamble_length, tvb, *offset, 2, ENC_BIG_ENDIAN);
+                        *offset+=2;
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_type_postamble_length, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                        *offset+=1;
+                        if (length >= 3){
+                            length-=3;
+                        }
+                        else{
+                            return TRUE;
+                        }
+                        break;
+                    case(RF_FAST_ACK):
+                        num_of_octets = tvb_get_guint8(tvb, *offset-1);
+                        for(i=0; i<num_of_octets; i++) {
+                            proto_tree_add_bitmask(additional_subtree, tvb, *offset, hf_knxnetip_cemi_type_fastack, ett_knxnetip_cemi_fastack, cemi_fastack_flags, ENC_BIG_ENDIAN);
+                            *offset+=2;
+                            if (length >= 2){
+                            length-=2;
+                        }
+                        else{
+                            return TRUE;
+                        }
+                        }
+                        break;
+                    case(MANU_DATA):
+                        num_of_octets = tvb_get_guint8(tvb, *offset-1);
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_dib_manuid, tvb, *offset, 2, ENC_BIG_ENDIAN);
+                        *offset+=2;
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_subfunction, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                        *offset+=1;
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_cemi_manuspecificdata, tvb, *offset, (num_of_octets-3), ENC_NA);
+                        *offset+=(num_of_octets-3);
+                        if (length >= num_of_octets){
+                            length-=num_of_octets;
+                        }
+                        else{
+                            return TRUE;
+                        }
+                        break;
+                    default:
+                        proto_tree_add_item(additional_subtree, hf_knxnetip_unknown, tvb, *offset, -1, ENC_NA);
+                        return *offset;
+                }
+            } while (length > 0);
+        }
+    }
+        switch (messagecode){
+            case(DATA_REQ):
+            case(DATA_CON):
+            case(DATA_IND):
+            case(POLL_DATA_REQ):
+            case(POLL_DATA_CON):
+                proto_tree_add_bitmask(cemi_tree, tvb, *offset, hf_knxnetip_cemi_controlfield1, ett_knxnetip_cemi_control1, cemi_control1_flags, ENC_BIG_ENDIAN);
+                *offset+=1;
+                proto_tree_add_bitmask(cemi_tree, tvb, *offset, hf_knxnetip_cemi_controlfield2, ett_knxnetip_cemi_control2, cemi_control2_flags, ENC_BIG_ENDIAN);
+                *offset+=1;
+                knx_address = tvb_get_ntohs(tvb, *offset);
+                proto_tree_add_uint_format(cemi_tree, hf_knxnetip_cemi_sourceaddress, tvb, *offset, 2, knx_address, "Source Address %d.%d.%d", ((knx_address & 0xF000)>>12),((knx_address & 0x0F00)>>8),(knx_address & 0xFF));
+                *offset+=2;
+                knx_address = tvb_get_ntohs(tvb, *offset);
+                proto_tree_add_uint_format(cemi_tree, hf_knxnetip_cemi_destaddress, tvb, *offset, 2, knx_address, "Destination Address %d/%d/%d", ((knx_address & 0xF000)>>12),((knx_address & 0x0F00)>>8),(knx_address & 0xFF));
+                *offset+=2;
+                if (messagecode == POLL_DATA_REQ){
+                    proto_tree_add_bits_item(cemi_tree, hf_knxnetip_cemi_numberofslots, tvb, (*offset*8)+4, 4, ENC_BIG_ENDIAN);
+                    *offset+=1;
+                }
+                else if (messagecode == POLL_DATA_CON){
+                    proto_tree_add_bits_item(cemi_tree, hf_knxnetip_cemi_numberofslots, tvb, (*offset*8)+4, 4, ENC_BIG_ENDIAN);
+                    *offset+=1;
+                    proto_tree_add_item(cemi_tree, hf_knxnetip_polldata, tvb, *offset, -1, ENC_NA);
+
+                }
+                else {
+                    npdu_length = proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_npdu_length, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                    proto_item_append_text(npdu_length, " octets");
+                    *offset+=1;
+                    dissect_apci(tvb, offset, cemi_tree, FALSE);
+                }
+                break;
+            case(RAW_REQ):
+            case(RAW_CON):
+            case(RAW_IND):
+            case(BUSMON_IND):
+                proto_tree_add_item(cemi_tree, hf_knxnetip_raw, tvb, *offset, -1, ENC_NA);
+                break;
+            case(DATA_INDV_IND):
+            case(DATA_INDV_REQ):
+            case(DATA_CONNEC_IND):
+            case(DATA_CONNEC_REQ):
+                proto_tree_add_item(cemi_tree, hf_knxnetip_reserved, tvb, *offset, 6, ENC_NA);
+                *offset+=6;
+                tpdu_length = proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_tpdu_length, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                proto_item_append_text(tpdu_length, " octets");
+                *offset+=1;
+                dissect_apci(tvb, offset, cemi_tree, TRUE);
+                break;
+            case(PROPREAD_REQ):
+            case(PROPREAD_CON):
+            case(PROPWRITE_REQ):
+            case(PROPWRITE_CON):
+            case(PROPINFO_IND):
+                proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_iot, tvb, *offset, 2, ENC_BIG_ENDIAN);
+                *offset+=2;
+                proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_oi, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                *offset+=1;
+                proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_pid, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                *offset+=1;
+                noe = ((tvb_get_guint8(tvb, *offset)& 0xF0)>>4);
+                proto_tree_add_bits_item(cemi_tree, hf_knxnetip_cemi_noe, tvb, (*offset*8), 4, ENC_BIG_ENDIAN);
+                six = tvb_get_bits16(tvb, (*offset*8+4), 12, ENC_BIG_ENDIAN);
+                proto_tree_add_bits_item(cemi_tree, hf_knxnetip_cemi_six, tvb, (*offset*8)+4, 12, ENC_BIG_ENDIAN);
+                *offset+=2;
+                if (messagecode == PROPREAD_REQ || (messagecode == PROPREAD_CON && noe > 0)){
+                    break;
+                }
+                else if (noe == 0){
+                    proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_error, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                    *offset+=1;
+                }
+                else if (noe == 1 && six == 0){
+                    proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_numberofelements, tvb, *offset, 2, ENC_BIG_ENDIAN);
+                    *offset+=2;
+                }
+                else {
+                    proto_tree_add_item(cemi_tree, hf_knxnetip_data, tvb, *offset, -1, ENC_NA);
+                }
+                break;
+            case(FUNCPROPCOM_REQ):
+            case(FUNCPROPSTATREAD_REQ):
+            case(FUNCPROPCOM_CON):
+                proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_iot, tvb, *offset, 2, ENC_BIG_ENDIAN);
+                *offset+=2;
+                proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_oi, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                *offset+=1;
+                proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_pid, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                *offset+=1;
+                if (messagecode == FUNCPROPCOM_CON){
+                    proto_tree_add_item(cemi_tree, hf_knxnetip_cemi_return, tvb, *offset, 1, ENC_BIG_ENDIAN);
+                    *offset+=1;
+                }
+                proto_tree_add_item(cemi_tree, hf_knxnetip_data, tvb, *offset, -1, ENC_NA);
+                break;
+            case(RESET_REQ):
+            case(RESET_IND):
+                break;
+            default:
+                proto_tree_add_item(cemi_tree, hf_knxnetip_data, tvb, *offset, -1, ENC_NA);
+        }
+        return FALSE;
+};
+
+
+
+static void dissect_knxnetip (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
+    proto_item *knx_item = NULL;
+    proto_item *total_length = NULL;
+    proto_item *struct_length = NULL;
+    proto_item *busy_item = NULL;
+
+    proto_tree *knx_tree = NULL;
+    proto_tree *header_tree = NULL;
+    proto_tree *body_tree = NULL;
+
+    guint offset = 0;
+    guint16 service_type = 0;
+    gboolean err = FALSE;
+
+    col_set_str(pinfo->cinfo, COL_PROTOCOL, "KNXnetIP");
+    col_clear(pinfo->cinfo,COL_INFO);
+
+    knx_item = proto_tree_add_item(tree, proto_knxnetip, tvb, 0, -1, ENC_NA);
+    knx_tree = proto_item_add_subtree(knx_item, ett_knxnetip);
+
+    /* HEADER*/
+    header_tree = proto_tree_add_subtree(knx_tree, tvb, offset, 6, ett_knxnetip_header, NULL, "Header");
+    proto_tree_add_item(header_tree, hf_knxnetip_headerlength, tvb, offset, 1, ENC_BIG_ENDIAN);
+    offset+=1;
+    proto_tree_add_item(header_tree, hf_knxnetip_version, tvb, offset, 1, ENC_BIG_ENDIAN);
+    offset+=1;
+    service_type = tvb_get_ntohs(tvb, offset);
+    proto_tree_add_item(header_tree, hf_knxnetip_servicetype, tvb, offset, 2, ENC_BIG_ENDIAN);
+    col_add_fstr(pinfo->cinfo, COL_INFO, "%s %d > %d", val_to_str(service_type, knxnetip_service_identifier, "Unknown Identifier:0x%02x"), pinfo->srcport, pinfo->destport);
+    offset+=2;
+    total_length = proto_tree_add_item(header_tree, hf_knxnetip_totallength, tvb, offset, 2, ENC_BIG_ENDIAN);
+    proto_item_append_text(total_length, " octets");
+    offset+=2;
+    /* BODY */
+    body_tree = proto_tree_add_subtree(knx_tree, tvb, offset, -1, ett_knxnetip_body, NULL, "Body");
+
+    switch(service_type) {
+
+        case(SEARCH_REQ):
+            dissect_hpai(tvb, &offset, body_tree, ": Discovery endpoint");
+            break;
+        case(SEARCH_RES):
+            dissect_hpai(tvb, &offset, body_tree, ": Control endpoint");
+            err = dissect_dib(tvb, &offset, body_tree);
+            if (err == TRUE){
+                proto_tree_add_expert(body_tree, pinfo, &ei_knxnetip_length, tvb, offset, -1);
+                break;
+            }
+            err = dissect_dib(tvb, &offset, body_tree);
+            if (err == TRUE){
+                proto_tree_add_expert(body_tree, pinfo, &ei_knxnetip_length, tvb, offset, -1);
+                break;
+            }
+            break;
+        case(DESCRIPTION_REQ):
+            dissect_hpai(tvb, &offset, body_tree, ": Control endpoint");
+            break;
+        case(DESCRIPTION_RES):
+            err = dissect_dib(tvb, &offset, body_tree);
+            if (err == TRUE){
+                proto_tree_add_expert(body_tree, pinfo, &ei_knxnetip_length, tvb, offset, -1);
+                break;
+            }
+            err = dissect_dib(tvb, &offset, body_tree);
+            if (err == TRUE){
+                proto_tree_add_expert(body_tree, pinfo, &ei_knxnetip_length, tvb, offset, -1);
+                break;
+            }
+            if (tvb_reported_length_remaining(tvb, offset) != 0){
+                err = dissect_dib(tvb, &offset, body_tree);
+                if (err == TRUE){
+                    proto_tree_add_expert(body_tree, pinfo, &ei_knxnetip_length, tvb, offset, -1);
+                }
+            }
+            break;
+        case(CONNECT_REQ):
+            dissect_hpai(tvb, &offset, body_tree, ": Discovery endpoint");
+            dissect_hpai(tvb, &offset, body_tree, ": Data endpoint");
+            offset = dissect_cri(tvb, offset, body_tree);
+            break;
+        case(CONNECT_RES):
+            proto_tree_add_item(body_tree, hf_knxnetip_communication_channel_id, tvb, offset, 1, ENC_BIG_ENDIAN);
+            offset+=1;
+            proto_tree_add_item(body_tree, hf_knxnetip_connect_status, tvb, offset, 1, ENC_BIG_ENDIAN);
+            offset+=1;
+            dissect_hpai(tvb, &offset, body_tree, ": Data endpoint");
+            dissect_crd(tvb, &offset, body_tree);
+            break;
+        case(CONNECTIONSTATE_REQ):
+        case(DISCONNECT_REQ):
+            proto_tree_add_item(body_tree, hf_knxnetip_communication_channel_id, tvb, offset, 1, ENC_BIG_ENDIAN);
+            offset+=1;
+            proto_tree_add_item(body_tree, hf_knxnetip_reserved, tvb, offset, 1, ENC_NA);
+            offset+=1;
+            dissect_hpai(tvb, &offset, body_tree, ": Control endpoint");
+            break;
+        case(DISCONNECT_RES):
+        case(CONNECTIONSTATE_RES):
+            proto_tree_add_item(body_tree, hf_knxnetip_communication_channel_id, tvb, offset, 1, ENC_BIG_ENDIAN);
+            offset+=1;
+            proto_tree_add_item(body_tree, hf_knxnetip_connectionstate_status, tvb, offset, 1, ENC_BIG_ENDIAN);
+            offset+=1;
+            break;
+        case(DEVICE_CONFIGURATION_ACK):
+            offset = dissect_connection_header(tvb, offset, body_tree, TRUE);
+            proto_tree_add_item(body_tree, hf_knxnetip_confack_status, tvb, offset, 1, ENC_BIG_ENDIAN);
+            offset+=1;
+            break;
+        case(DEVICE_CONFIGURATION_REQ):
+        case(TUNNELLING_REQ):
+            offset = dissect_connection_header(tvb, offset, body_tree, FALSE);
+            err =  dissect_cemi (tvb, &offset, body_tree, pinfo);
+            if (err == TRUE){
+                proto_tree_add_expert(body_tree, pinfo, &ei_knxnetip_length, tvb, offset, -1);
+            }
+            break;
+        case(TUNNELLING_ACK):
+            offset = dissect_connection_header(tvb, offset, body_tree, TRUE);
+            proto_tree_add_item(body_tree, hf_knxnetip_tunnelack_status, tvb, offset, 1, ENC_BIG_ENDIAN);
+            break;
+        case(ROUTING_INDICATION):
+            err = dissect_cemi (tvb, &offset, body_tree, pinfo);
+            if (err == TRUE){
+                proto_tree_add_expert(body_tree, pinfo, &ei_knxnetip_length, tvb, offset, -1);
+            }
+            break;
+        case(ROUTING_LOST):
+            struct_length= proto_tree_add_item(body_tree, hf_knxnetip_structure_length, tvb, offset, 1, ENC_BIG_ENDIAN);
+            proto_item_append_text(struct_length, " octets");
+            offset+=1;
+            proto_tree_add_bitmask(body_tree, tvb, offset, hf_knxnetip_devicestate, ett_knxnetip_devicestate, devicestate_flags, ENC_BIG_ENDIAN);
+            offset+=1;
+            proto_tree_add_item(body_tree, hf_knxnetip_numberoflost, tvb, offset, 2, ENC_BIG_ENDIAN);
+            offset+=2;
+            break;
+        case(ROUTING_BUSY):
+            struct_length= proto_tree_add_item(body_tree, hf_knxnetip_structure_length, tvb, offset, 1, ENC_BIG_ENDIAN);
+            proto_item_append_text(struct_length, " octets");
+            offset+=1;
+            proto_tree_add_bitmask(body_tree, tvb, offset, hf_knxnetip_devicestate, ett_knxnetip_devicestate, devicestate_flags, ENC_BIG_ENDIAN);
+            offset+=1;
+            busy_item = proto_tree_add_item(body_tree, hf_knxnetip_busywaittime, tvb, offset, 2, ENC_BIG_ENDIAN);
+            proto_item_append_text(busy_item, " ms");
+            offset+=2;
+            proto_tree_add_item(body_tree, hf_knxnetip_busycontrol, tvb, offset, 2, ENC_BIG_ENDIAN);
+            offset+=2;
+            break;
+        case(REMOTE_DIAG_REQ):
+            dissect_hpai(tvb, &offset, body_tree, ": Discovery endpoint");
+            offset = dissect_selector(tvb ,offset, body_tree);
+            break;
+        case(REMOTE_DIAG_RES):
+            offset = dissect_selector(tvb ,offset, body_tree);
+            do{
+                err = dissect_dib(tvb, &offset, body_tree);
+                if (err == TRUE){
+                    proto_tree_add_expert(body_tree, pinfo, &ei_knxnetip_length, tvb, offset, -1);
+                    break;
+                }
+            } while (tvb_reported_length_remaining(tvb,offset) > 0);
+            break;
+        case(REMOTE_BASIC_CONF_REQ):
+            dissect_hpai(tvb, &offset, body_tree, ": Discovery endpoint");
+            offset = dissect_selector(tvb ,offset, body_tree);
+            err = dissect_dib(tvb, &offset, body_tree);
+            if (err == TRUE){
+                proto_tree_add_expert(body_tree, pinfo, &ei_knxnetip_length, tvb, offset, -1);
+                break;
+            }
+            if (tvb_reported_length_remaining(tvb,offset) > 0) {
+                err = dissect_dib(tvb, &offset, body_tree);
+                if (err == TRUE){
+                    proto_tree_add_expert(body_tree, pinfo, &ei_knxnetip_length, tvb, offset, -1);
+                }
+            }
+            break;
+        case(REMOTE_RESET_REQ):
+            offset = dissect_selector(tvb ,offset, body_tree);
+            proto_tree_add_item(body_tree, hf_knxnetip_reset, tvb, offset, 1, ENC_BIG_ENDIAN);
+            offset+=1;
+            proto_tree_add_item(body_tree, hf_knxnetip_reserved, tvb, offset, 1, ENC_NA);
+            offset+=1;
+            break;
+
+        default:
+            proto_tree_add_item(body_tree, hf_knxnetip_unknown, tvb, offset, -1, ENC_NA);
+    }
+};
+
+static gboolean dissect_knxnetip_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
+
+    gint idx;
+    idx = 0;
+
+    if (tvb_length(tvb) < 8){
+        return (FALSE);
+    }
+    if ( tvb_get_guint8(tvb, 0) != KNXNETIP_HEADER_LENGTH) {
+        return (FALSE);
+    }
+    if ( tvb_get_guint8(tvb, 1) != KNXNETIP_PROTOCOL_VERSION){
+        return (FALSE);
+    }
+    try_val_to_str_idx((guint32)tvb_get_ntohs(tvb, 2), knxnetip_service_identifier, &idx);
+    if (idx == -1){
+        return (FALSE);
+    }
+
+    dissect_knxnetip(tvb, pinfo, tree);
+    return (TRUE);
+};
+
+void proto_register_knxnetip (void) {
+    expert_module_t*  expert_knxnetip;
+
+    static hf_register_info hf[] = {
+        { &hf_knxnetip_headerlength,
+            { "Header Length", "knxnetip.headerlength", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_version,
+            { "Protocol Version", "knxnetip.version", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_servicetype,
+            { "Service Type Identifier", "knxnetip.servicetype", FT_UINT16, BASE_HEX, VALS(knxnetip_service_identifier), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_totallength,
+            { "Total Length", "knxnetip.totallength", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_hpai,
+            { "HPAI", "knxnetip.hpai", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_hpai_structure_length,
+            { "Structure Length", "knxnetip.hpailength", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_structure_length,
+            { "Structure Length", "knxnetip.structlength", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_hpai_host_protocol,
+            { "Host Protocol Code", "knxnetip.hpaihostprotocol", FT_UINT8, BASE_HEX, VALS(knxnetip_host_protocol_codes), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_hpai_ip_address,
+            { "IP Address", "knxnetip.hpaiip", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_hpai_port,
+            { "IP Port", "knxnetip.hpaiport", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib,
+            { "DIB", "knxnetip.dib", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cri,
+            { "Connection Request Information", "knxnetip.cri", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_type,
+            { "Description Type", "knxnetip.dibtype", FT_UINT8, BASE_HEX, VALS(knxnetip_dib_description_type_codes), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_medium,
+            { "KNX medium", "knxnetip.dibmedium", FT_UINT8, BASE_HEX, VALS(knxnetip_dib_medium_codes), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_status,
+            { "Device Status", "knxnetip.dibstatus", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_projectid,
+            { "Project-Installation identifier", "knxnetip.dibprojectid", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_knxaddress,
+            { "KNX Individual Address", "knxnetip.knxaddress", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_serialnumber,
+            { "KNXnet/IP device serial number", "knxnetip.serialnumber", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_multicast_address,
+            { "KNXnet/IP device multicast address", "knxnetip.multicast", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_mac_address,
+            { "KNXnet/IP device MAC address", "knxnetip.macaddress", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_friendly,
+            { "Device Friendly Name", "knxnetip.devicename", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_service,
+            { "Service ID", "knxnetip.dibservice", FT_UINT8, BASE_HEX, VALS(knxnetip_service_types), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_ipaddress,
+            { "IP Address", "knxnetip.dibipaddress", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_subnet,
+            { "Subnet Mask", "knxnetip.dibsubnet", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_gateway,
+            { "Default Gateway", "knxnetip.dibgateway", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_ipcapa,
+            { "IP Capabilities", "knxnetip.dibipcapabilities", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_ipassign,
+            { "IP assignment method", "knxnetip.dibassignment", FT_UINT8, BASE_HEX, VALS(knxnetip_ip_assignment_method), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_dhcp,
+            { "DHCP Server", "knxnetip.dibdhcp", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_manuid,
+            { "Manufacturer ID", "knxnetip.manid", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_manudata,
+            { "Manufacturer specific data", "knxnetip.mandata", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_connection_type,
+            { "Connection Type", "knxnetip.contype", FT_UINT8, BASE_HEX, VALS(knxnetip_connection_types), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cri_protocol_data,
+            { "Protocol Data", "knxnetip.cridata", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_communication_channel_id,
+            { "Communication Channel ID", "knxnetip.commid", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_connect_status,
+            { "Status", "knxnetip.connectstatus", FT_UINT8, BASE_HEX, VALS(knxnetip_connect_response_status_codes), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_crd_protocol_data,
+            { "Protocol Data", "knxnetip.crddata", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_crd,
+            { "Connection Response Data Block", "knxnetip.crd", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_connectionstate_status,
+            { "Status", "knxnetip.connectstatestatus", FT_UINT8, BASE_HEX, VALS(knxnetip_connectionstate_response_status_codes), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_counter,
+            { "Sequence Counter", "knxnetip.sequencecounter", FT_UINT8, BASE_DEC, 0x0, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_confack_status,
+            { "Status", "knxnetip.confackstatus", FT_UINT8, BASE_HEX, VALS(knxnetip_device_configuration_ack_status_codes), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_tunnelack_status,
+            { "Status", "knxnetip.tunnelstatus", FT_UINT8, BASE_HEX, VALS(knxnetip_tunneling_error_codes), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_status_flag_reserved,
+            { "reserved", "knxnetip.dibreserved", FT_UINT8, BASE_HEX, NULL, FLAGS_DEVICESTATUS_RESERVED, NULL, HFILL }},
+        { &hf_knxnetip_dib_status_flag_program,
+            { "program mode", "knxnetip.dibprog", FT_UINT8, BASE_DEC, NULL, FLAGS_DEVICESTATUS_PROGRAM, NULL , HFILL }},
+        { &hf_knxnetip_dib_ipcapa_flag_reserved,
+            { "reserved", "knxnetip.ipcapareserved", FT_UINT8, BASE_HEX, NULL, FLAGS_IPCAPABILITES_RESERVED, NULL, HFILL }},
+        { &hf_knxnetip_dib_ipcapa_flag_bootip,
+            { "BootIP", "knxnetip.ipcapabootip", FT_UINT8, BASE_DEC, NULL, FLAGS_IPCAPABILITES_BOOTIP, NULL, HFILL }},
+        { &hf_knxnetip_dib_ipcapa_flag_dhcp,
+            { "DHCP", "knxnetip.ipcapadhcp", FT_UINT8, BASE_DEC, NULL, FLAGS_IPCAPABILITES_DHCP, NULL, HFILL }},
+        { &hf_knxnetip_dib_ipcapa_flag_autoip,
+            { "AutoIP", "knxnetip.ipcapaautoip", FT_UINT8, BASE_DEC, NULL, FLAGS_IPCAPABILITES_AUTOIP, NULL, HFILL }},
+        { &hf_knxnetip_devicestate,
+            { "DeviceState", "knxnetip.devicestate", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_devicestate_reserved,
+            { "reserved", "knxnetip.devicestatereserved", FT_UINT8, BASE_HEX, NULL, FLAGS_DEVICESTATE_RESERVED, NULL, HFILL }},
+        { &hf_knxnetip_devicestate_knx,
+            { "KNX Fault", "knxnetip.devicestateknx", FT_UINT8, BASE_DEC, NULL, FLAGS_DEVICESTATE_KNX, "is set if KNX network cannot be accessed", HFILL }},
+        { &hf_knxnetip_devicestate_ip,
+            { "IP Fault", "knxnetip.devicestateip", FT_UINT8, BASE_DEC, NULL, FLAGS_DEVICESTATE_IP, "is set if IP network cannot be accessed", HFILL }},
+        { &hf_knxnetip_numberoflost,
+            { "NumberofLostMessages", "knxnetip.losmessages", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_busywaittime,
+            { "Busy Wait Time", "knxnetip.busytime", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_busycontrol,
+            { "Busy Control Field", "knxnetip.busycontrol", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_knxlayer,
+            { "KNX Layer", "knxnetip.layer", FT_UINT8, BASE_HEX, VALS(knxnetip_knxlayer_values), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_selector_type,
+            { "Selector Type Code", "knxnetip.selector", FT_UINT8, BASE_HEX, VALS(knxnetip_selector_types), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_reset,
+            { "Reset Command", "knxnetip.reset", FT_UINT8, BASE_HEX, VALS(knxnetip_reset_codes), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi,
+            { "cEMI", "knxnetip.cemi", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_mc,
+            { "messagecode", "knxnetip.cemimc", FT_UINT8, BASE_HEX, VALS(cemi_messagecodes), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_addlength,
+            { "add information length", "knxnetip.addlength", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_additemlength,
+            { "Length", "knxnetip.addlength", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_typid,
+            { "Type id", "knxnetip.cemitypeid", FT_UINT8, BASE_HEX, VALS(cemi_add_type_id), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_pl,
+            { "Domain-Address", "knxnetip.cemitypepl", FT_UINT16, BASE_HEX, 0x0, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_bus,
+            { "Busmonitor error flags", "knxnetip.cemitypebus", FT_UINT8, BASE_HEX, 0x0, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_relt,
+            { "relative timestamp", "knxnetip.cemitypereltime", FT_UINT16, BASE_HEX, 0x0, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_delay,
+            { "delay", "knxnetip.cemitypedelay", FT_UINT32, BASE_HEX, 0x0, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_exttime,
+            { "extended timestamp", "knxnetip.cemitypeexttime", FT_UINT32, BASE_HEX, 0x0, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_bibat,
+            { "BiBat", "knxnetip.cemitypebibat", FT_UINT8, BASE_HEX, VALS(cemi_bibat_ctrl), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_controlfield1,
+            { "Controlfield 1", "knxnetip.controlone", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_flag_frametype,
+            { "Frametype", "knxnetip.controltype", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_CONTROL1_FT, "0: extended frame; 1: standard frame", HFILL }},
+        { &hf_knxnetip_cemi_flag_repeat,
+            { "Repeat", "knxnetip.controlrepeat", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_CONTROL1_R, "0: repeat if error frame; 1: do not repeat", HFILL }},
+        { &hf_knxnetip_cemi_flag_sb,
+            { "System-Broadcast", "knxnetip.controlcast", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_CONTROL1_SB, "0: system-broadcast; 1: broadcast", HFILL }},
+        { &hf_knxnetip_cemi_flag_priority,
+            { "Priority", "knxnetip.controlprio", FT_UINT8, BASE_HEX, NULL, FLAGS_CEMI_CONTROL1_P, NULL, HFILL }},
+        { &hf_knxnetip_cemi_flag_ack,
+            { "Acknowledge-Request", "knxnetip.controlack", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_CONTROL1_A, "0: no request for ack; 1: request ack", HFILL }},
+        { &hf_knxnetip_cemi_flag_confirm,
+            { "Confirm-Flag", "knxnetip.controlconf", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_CONTROL1_C, "0: no error in frame; 1: error in frame", HFILL }},
+        { &hf_knxnetip_cemi_controlfield2,
+            { "Controlfield 2", "knxnetip.controltwo", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_flag_destaddress,
+            { "Destination address type", "knxnetip.controldestaddress", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_CONTROL2_AT, "0: individual; 1: group", HFILL }},
+        { &hf_knxnetip_flag_hop,
+            { "Hop count", "knxnetip.controlhop", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_CONTROL2_HC, NULL, HFILL }},
+        { &hf_knxnetip_flag_eff,
+            { "Extended Frame Format", "knxnetip.controleff", FT_UINT8, BASE_HEX, NULL, FLAGS_CEMI_CONTROL2_EFF, "0000b for standard frame", HFILL }},
+        { &hf_knxnetip_cemi_sourceaddress,
+            { "Source Address", "knxnetip.cemisource", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_destaddress,
+            { "Destination Address", "knxnetip.cemidestination", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_tpci,
+            { "TPCI", "knxnetip.cemitpci", FT_UINT8, BASE_HEX, VALS(cemi_tpci_vals), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_npdu_length,
+            { "NPDU length", "knxnetip.npdulength", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_tpdu_length,
+            { "TPDU length", "knxnetip.tpdulength", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_counter,
+            { "sequence NCD/NDT", "knxnetip.npduseq", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_apci,
+            { "APCI", "knxnetip.npduapci", FT_UINT16, BASE_HEX, VALS(cemi_apci_codes), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_data,
+            { "Data", "knxnetip.cemidata", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_numberofslots,
+            { "number of slots", "knxnetip.ceminumberofslots", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_apci_memory_number,
+            { "number of octets to be read/write", "knxnetip.cemidata", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_iot,
+            { "Interface object type", "knxnetip.cemiiot", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_oi,
+            { "Object Instance", "knxnetip.cemioi", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_pid,
+            { "Property Identifier", "knxnetip.cemipid", FT_UINT8, BASE_DEC, VALS(cemi_propertyid), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_noe,
+            { "Number of Elements", "knxnetip.ceminoe", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_six,
+            { "Startindex", "knxnetip.cemipid", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_numberofelements,
+            { "Number of Elements", "knxnetip.ceminumber", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_error,
+            { "Error Code", "knxnetip.cemierror", FT_UINT8, BASE_HEX, VALS(cemi_error_codes), 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_return,
+            { "retrun code", "knxnetip.cemireturn", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_reserved,
+            { "reserved", "knxnetip.cemireserved", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_rf_info,
+            { "RF-Info", "knxnetip.cemirfinfo", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_rf_mesure,
+            { "received signal strength", "knxnetip.cemirfmesure", FT_UINT8, BASE_HEX, NULL, FLAGS_CEMI_RF_MESURE, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_rf_reserved,
+            { "reserved", "knxnetip.cemirfreserved", FT_UINT8, BASE_HEX, NULL, FLAGS_CEMI_RF_RESERVED, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_rf_mesure_re,
+            { "retransmitter signal strrength", "knxnetip.cemirfmesurere", FT_UINT8, BASE_HEX, NULL, FLAGS_CEMI_RF_MESURE_RE, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_rf_battery,
+            { "Battery state", "knxnetip.cemirfbattery", FT_UINT8, BASE_HEX, NULL, FLAGS_CEMI_RF_BATTERY, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_rf_bidirekt,
+            { "is not bidirektional", "knxnetip.cemirfbattery", FT_UINT8, BASE_HEX, NULL, FLAGS_CEMI_RF_BIDIRETIONAL, NULL, HFILL }},
+        { &hf_knxnetip_cemi_rf_sn,
+            { "KNX Serial Number", "knxnetip.cemiknxsn", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_rf_lfn,
+            { "Data Link Layer frame number", "knxnetip.cemilfn", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_bus_flag_f,
+            { "Frame error flag", "knxnetip.cemibusferror", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_BUS_F, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_bus_flag_b,
+            { "Bit error flag", "knxnetip.cemibusberror", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_BUS_B, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_bus_flag_p,
+            { "Parity error flag", "knxnetip.cemibusparity", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_BUS_P, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_bus_flag_d,
+            { "dont care", "knxnetip.cemibusdont", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_BUS_D, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_bus_flag_l,
+            { "Lost flag", "knxnetip.cemibuslost", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_BUS_L, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_bus_flag_sss,
+            { "Sequence Number", "knxnetip.cemibusseq", FT_UINT8, BASE_DEC, NULL, FLAGS_CEMI_BUS_SSS, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_bibat_block,
+            { "BiBat Block number", "knxnetip.cemibibbatblock", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_rf_multi_fastack,
+            { "KNX RF Multi Fast Ack", "knxnetip.cemirffastack", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_rf_multi_freq,
+            { "KNX RF Multi Transmission Frequency", "knxnetip.cemirffreq", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_rf_multi_channel,
+            { "KNX RF Multi Call Channel", "knxnetip.cemirfchannel", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_rf_multi_recep_freq,
+            { "KNX RF Multi Reception Frequency", "knxnetip.cemirfrecfreq", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_preamble_length,
+            { "Preamble Length", "knxnetip.cemipreamblelength", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_postamble_length,
+            { "Postamble Length", "knxnetip.cemipostamblelength", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_fastack,
+            { "Fast Ack information", "knxnetip.cemifastack", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_fastack_crc,
+            { "Fast Ack is received with a CRC", "knxnetip.cemifastackcrc", FT_UINT16, BASE_DEC, NULL, FLAGS_CEMI_FASTACK_CRC, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_fastack_error,
+            { "Fast Ack is received with a Manchester error", "knxnetip.cemifastackerror", FT_UINT16, BASE_DEC, NULL, FLAGS_CEMI_FASTACK_ERROR, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_fastack_received,
+            { "Fast Ack has been received", "knxnetip.cemifastackres", FT_UINT16, BASE_DEC, NULL, FLAGS_CEMI_FASTACK_RES, NULL, HFILL }},
+        { &hf_knxnetip_cemi_type_fastack_info,
+            { "Fast Ack Info", "knxnetip.cemifastackinfo", FT_UINT16, BASE_HEX, NULL, FLAGS_CEMI_FASTACK_INFO, NULL, HFILL }},
+        { &hf_knxnetip_cemi_subfunction,
+            { "Subfunction", "knxnetip.cemisubfunction", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_cemi_manuspecificdata,
+            { "Manufacturer specific data", "knxnetip.cemimanuspecificdata", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_projectnumber,
+            { "Project number", "knxnetip.projectnumber", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_installnumber,
+            { "Installation number", "knxnetip.installnumber", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_dib_svc_version,
+            { "Version", "knxnetip.svcversion", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_reserved,
+            { "reserved", "knxnetip.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_data,
+            { "data", "knxnetip.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_polldata,
+            { "Poll data", "knxnetip.polldata", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_raw,
+            { "RAW Frame", "knxnetip.raw", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_additional,
+            { "Additional information", "knxnetip.additional", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+        { &hf_knxnetip_unknown,
+            { "UNKNOWN", "knxnetip.unknown", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}
+    };
+
+    static gint *ett[] = {
+        &ett_knxnetip,
+        &ett_knxnetip_header,
+        &ett_knxnetip_body,
+        &ett_knxnetip_hpai,
+        &ett_knxnetip_dib,
+        &ett_knxnetip_dib_projectid,
+        &ett_knxnetip_dib_service,
+        &ett_knxnetip_cri,
+        &ett_knxnetip_crd,
+        &ett_knxnetip_dib_status,
+        &ett_knxnetip_dib_ipcapa,
+        &ett_knxnetip_devicestate,
+        &ett_knxnetip_cemi,
+        &ett_knxnetip_cemi_additional,
+        &ett_knxnetip_cemi_additional_item,
+        &ett_knxnetip_cemi_control1,
+        &ett_knxnetip_cemi_control2,
+        &ett_knxnetip_cemi_rf_info,
+        &ett_knxnetip_cemi_bus_info,
+        &ett_knxnetip_cemi_fastack
+    };
+
+    static ei_register_info ei[] = {
+        { &ei_knxnetip_length, { "knxnetip.invalid.length", PI_PROTOCOL, PI_ERROR, "invalid length", EXPFILL }},
+  };
+
+    proto_knxnetip = proto_register_protocol("KNXnet/IP", "knxnetip", "knx");
+    proto_register_field_array(proto_knxnetip, hf, array_length(hf));
+    proto_register_subtree_array(ett, array_length(ett));
+    expert_knxnetip = expert_register_protocol(proto_knxnetip);
+    expert_register_field_array(expert_knxnetip, ei, array_length(ei));
+};
+
+
+void proto_reg_handoff_knxnetip(void) {
+    /* register as heuristic dissector for both TCP and UDP */
+    heur_dissector_add("tcp", dissect_knxnetip_heur, proto_knxnetip);
+    heur_dissector_add("udp", dissect_knxnetip_heur, proto_knxnetip);
+};
+
+
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 4
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */