diff options
author | alage <sphinxs1988@googlemail.com> | 2014-08-25 11:03:43 +0200 |
---|---|---|
committer | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2014-09-28 14:17:28 +0000 |
commit | 5a16ae72ee83e244a2a2ad6428a6c595ae05976a (patch) | |
tree | 63cb1f3b16dc211fc694e85cb699297cf05b79f7 /epan/dissectors/packet-knxnetip.c | |
parent | e9c4217dca91e3a403af9b16a317dba2e8a20559 (diff) |
New dissector for KNXnetIP protocol
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>
Diffstat (limited to 'epan/dissectors/packet-knxnetip.c')
-rw-r--r-- | epan/dissectors/packet-knxnetip.c | 1799 |
1 files changed, 1799 insertions, 0 deletions
diff --git a/epan/dissectors/packet-knxnetip.c b/epan/dissectors/packet-knxnetip.c new file mode 100644 index 0000000000..f6a27f7c0e --- /dev/null +++ b/epan/dissectors/packet-knxnetip.c @@ -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: + */ |