epan/dissectors/pidl/ C99 drsuapi
[wireshark-sm.git] / epan / dissectors / packet-knxip.c
blobbe57ae1ca7b8e2207e360b297f2212a978283846
1 /* packet-knxip.c
2 * Routines for KNXnet/IP dissection
3 * By Jan Kessler <kessler@ise.de>
4 * Copyright 2004, Jan Kessler <kessler@ise.de>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
14 * See
16 * https://my.knx.org/en/shop/knx-specifications
18 * for the specifications.
21 #include "config.h"
23 #include <stdlib.h>
24 #include <string.h>
26 #include <epan/packet.h>
27 #include <epan/expert.h>
28 #include <epan/proto.h>
29 #include <epan/ipproto.h>
30 #include <epan/prefs.h>
31 #include <epan/proto_data.h>
32 #include <epan/tvbuff.h>
33 #include <epan/strutil.h>
35 #include "packet-tcp.h"
36 #include "packet-udp.h"
37 #include "packet-knxip.h"
38 #include "packet-knxip_decrypt.h"
40 #define KIP_DEFAULT_PORT_RANGE "3671" /* IANA-assigned (EIBnet aka KNXnet) */
41 /* Other ports are commonly used, especially 3672 by KNX IP Gateways, but
42 * not registered.
45 #define ECDH_PUBLIC_VALUE_SIZE 32
47 #define KIP_HDR_LEN 6
49 /* The following service families are defined for the
50 version 1.0 KNXnet/IP implementation of the eFCP protocol
52 #define KIP_SERVICE_CORE 0x02
53 #define KIP_SERVICE_MANAGEMENT 0x03
54 #define KIP_SERVICE_TUNNELING 0x04
55 #define KIP_SERVICE_ROUTING 0x05
56 #define KIP_SERVICE_REMOTE_LOGGING 0x06
57 #define KIP_SERVICE_REMOTE_DIAG_AND_CONFIG 0x07
58 #define KIP_SERVICE_OBJECT_SERVER 0x08
59 #define KIP_SERVICE_SECURITY 0x09
61 /* The service codes for the core services (device discovery,
62 self description and connection management) as defined in
63 chapter 2 of the KNXnet/IP system specification
65 #define KIP_SEARCH_REQUEST 0x0201
66 #define KIP_SEARCH_RESPONSE 0x0202
67 #define KIP_DESCRIPTION_REQUEST 0x0203
68 #define KIP_DESCRIPTION_RESPONSE 0x0204
69 #define KIP_CONNECT_REQUEST 0x0205
70 #define KIP_CONNECT_RESPONSE 0x0206
71 #define KIP_CONNECTIONSTATE_REQUEST 0x0207
72 #define KIP_CONNECTIONSTATE_RESPONSE 0x0208
73 #define KIP_DISCONNECT_REQUEST 0x0209
74 #define KIP_DISCONNECT_RESPONSE 0x020A
75 #define KIP_SEARCH_REQUEST_EXT 0x020B
76 #define KIP_SEARCH_RESPONSE_EXT 0x020C
78 /* The service codes for the device management services
79 (tunneling of cEMI local management procedures) as
80 defined in chapter 3 of the KNXnet/IP system specification
82 #define KIP_CONFIGURATION_REQUEST 0x0310
83 #define KIP_CONFIGURATION_ACK 0x0311
85 /* The service codes for the tunneling services
86 (transport of cEMI frames from service interface) as
87 defined in chapter 4 of the KNXnet/IP system specification
89 #define KIP_TUNNELING_REQUEST 0x0420
90 #define KIP_TUNNELING_ACK 0x0421
91 #define KIP_TUNNELING_FEATURE_GET 0x0422
92 #define KIP_TUNNELING_FEATURE_RESPONSE 0x0423
93 #define KIP_TUNNELING_FEATURE_SET 0x0424
94 #define KIP_TUNNELING_FEATURE_INFO 0x0425
96 /* The service codes for the routing services
97 (transport of cEMI frames between EIB couplers) as
98 defined in chapter 5 of the KNXnet/IP system specification
100 #define KIP_ROUTING_INDICATION 0x0530
101 #define KIP_ROUTING_LOST_MESSAGE 0x0531
102 #define KIP_ROUTING_BUSY 0x0532
103 #define KIP_ROUTING_SYSTEM_BROADCAST 0x0533
105 /* The service codes for RemoteDiagAndConfig
107 #define KIP_REMOTE_DIAG_REQUEST 0x0740
108 #define KIP_REMOTE_DIAG_RESPONSE 0x0741
109 #define KIP_REMOTE_CONFIG_REQUEST 0x0742
110 #define KIP_REMOTE_RESET_REQUEST 0x0743
112 /* The service codes for KNX-IP Secure
114 #define KIP_SECURE_WRAPPER 0x0950
115 #define KIP_SESSION_REQUEST 0x0951
116 #define KIP_SESSION_RESPONSE 0x0952
117 #define KIP_SESSION_AUTHENTICATE 0x0953
118 #define KIP_SESSION_STATUS 0x0954
119 #define KIP_TIMER_NOTIFY 0x0955
121 /* KNXnet/IP host protocols */
122 #define KIP_IPV4_UDP 0x01
123 #define KIP_IPV4_TCP 0x02
125 /* The different types of DIBs (Description Information Blocks)
126 for the KNXnet/IP Core Discovery and Description services
127 as defined in chapter 1 of the KNXnet/IP system specification
129 #define KIP_DIB_DEVICE_INFO 0x01
130 #define KIP_DIB_SUPP_SVC_FAMILIES 0x02
131 #define KIP_DIB_IP_CONFIG 0x03
132 #define KIP_DIB_CUR_CONFIG 0x04
133 #define KIP_DIB_KNX_ADDRESSES 0x05
134 #define KIP_DIB_SECURED_SERVICE_FAMILIES 0x06
135 #define KIP_DIB_TUNNELING_INFO 0x07
136 #define KIP_DIB_EXTENDED_DEVICE_INFO 0x08
137 #define KIP_DIB_MFR_DATA 0xFE
139 /* The different types of SRPs (Search Request Parameter Blocks)
140 for the KNXnet/IP Core Discovery and Description services
142 #define KIP_SRP_BY_PROGMODE 0x01
143 #define KIP_SRP_BY_MACADDR 0x02
144 #define KIP_SRP_BY_SERVICE 0x03
145 #define KIP_SRP_REQUEST_DIBS 0x04
147 /* The different KNX medium types for the hardware (device info)
148 DIB as defined in AN033 Common EMI Specification
150 #define KIP_KNXTYPE_TP0 0x01
151 #define KIP_KNXTYPE_TP1 0x02
152 #define KIP_KNXTYPE_PL110 0x04
153 #define KIP_KNXTYPE_PL132 0x08
154 #define KIP_KNXTYPE_RF 0x10
155 #define KIP_KNXTYPE_IP 0x20
157 /* KNXnet/IP connection types */
158 #define KIP_DEVICE_MGMT_CONNECTION 0x03
159 #define KIP_TUNNEL_CONNECTION 0x04
160 #define KIP_REMLOG_CONNECTION 0x06
161 #define KIP_REMCONF_CONNECTION 0x07
162 #define KIP_OBJSVR_CONNECTION 0x08
164 /* Tunneling v2 feature ids */
165 #define KIP_TUNNELING_FEATURE_ID_SUPPORTED_EMI_TYPE 0x01
166 #define KIP_TUNNELING_FEATURE_ID_HOST_DEVICE_DEVICE_DESCRIPTOR_TYPE_0 0x02
167 #define KIP_TUNNELING_FEATURE_ID_BUS_CONNECTION_STATUS 0x03
168 #define KIP_TUNNELING_FEATURE_ID_KNX_MANUFACTURER_CODE 0x04
169 #define KIP_TUNNELING_FEATURE_ID_ACTIVE_EMI_TYPE 0x05
170 #define KIP_TUNNELING_FEATURE_ID_INDIVIDUAL_ADDRESS 0x06
171 #define KIP_TUNNELING_FEATURE_ID_MAX_APDU_LENGTH 0x07
172 #define KIP_TUNNELING_FEATURE_ID_INFO_SERVICE_ENABLE 0x08
174 /* KNXnet/IP tunnel types */
175 #define TUNNEL_LINKLAYER 0x02
176 #define TUNNEL_RAW 0x04
177 #define TUNNEL_BUSMONITOR 0x80
179 /* KNXnet/IP error codes */
180 #define KIP_E_NO_ERROR 0x00
181 #define KIP_E_CONNECTION_ID 0x21
182 #define KIP_E_CONNECTION_TYPE 0x22
183 #define KIP_E_CONNECTION_OPTION 0x23
184 #define KIP_E_NO_MORE_CONNECTIONS 0x24
185 #define KIP_E_NO_MORE_UNIQUE_CONNECTIONS 0x25
186 #define KIP_E_DATA_CONNECTION 0x26
187 #define KIP_E_KNX_CONNECTION 0x27
188 #define KIP_E_TUNNELING_LAYER 0x29
190 /* KNXnet/IP remote selection types */
191 #define SELECT_PROGMODE 0x01
192 #define SELECT_MACADDRESS 0x02
194 /* SESSION_STATUS codes */
195 #define SESSION_STATUS_AUTHENTICATION_SUCCESS 0x00
196 #define SESSION_STATUS_AUTHENTICATION_FAILED 0x01
197 #define SESSION_STATUS_UNAUTHENTICATED 0x02
198 #define SESSION_STATUS_TIMEOUT 0x03
199 #define SESSION_STATUS_KEEPALIVE 0x04
200 #define SESSION_STATUS_CLOSE 0x05
202 /* Initialize the protocol identifier that is needed for the
203 protocol hook and to register the fields in the protocol tree
205 static int proto_knxip;
207 /* Initialize the registered fields identifiers. These fields
208 will be registered with the protocol during initialization.
209 Protocol fields are like type definitions. The protocol dissector
210 later on adds items of these types to the protocol tree.
212 static int hf_bytes;
213 static int hf_folder;
214 static int hf_knxip_header_length;
215 static int hf_knxip_protocol_version;
216 static int hf_knxip_service_id;
217 static int hf_knxip_service_family;
218 static int hf_knxip_service_type;
219 static int hf_knxip_total_length;
220 static int hf_knxip_structure_length;
221 static int hf_knxip_host_protocol;
222 static int hf_knxip_ip_address;
223 static int hf_knxip_port;
224 static int hf_knxip_description_type;
225 static int hf_knxip_knx_medium;
226 static int hf_knxip_device_status;
227 static int hf_knxip_program_mode;
228 static int hf_knxip_knx_address;
229 static int hf_knxip_project_id;
230 static int hf_knxip_project_number;
231 static int hf_knxip_installation_number;
232 static int hf_knxip_serial_number;
233 static int hf_knxip_multicast_address;
234 static int hf_knxip_mac_address;
235 static int hf_knxip_friendly_name;
236 static int hf_knxip_service_version;
237 static int hf_knxip_security_version;
238 static int hf_knxip_manufacturer_code;
239 static int hf_knxip_connection_type;
240 static int hf_knxip_knx_layer;
241 static int hf_knxip_reserved;
242 static int hf_knxip_channel;
243 static int hf_knxip_status;
244 static int hf_knxip_seq_counter;
245 static int hf_knxip_ip_subnet;
246 static int hf_knxip_ip_gateway;
247 static int hf_knxip_ip_assign;
248 static int hf_knxip_ip_caps;
249 static int hf_knxip_ip_dhcp;
250 static int hf_knxip_tunnel_feature;
251 static int hf_knxip_routing_loss;
252 static int hf_knxip_busy_time;
253 static int hf_knxip_busy_control;
254 static int hf_knxip_selector;
255 static int hf_knxip_max_apdu_length;
256 static int hf_knxip_medium_status;
257 static int hf_knxip_mask_version;
258 static int hf_knxip_srp_mandatory;
259 static int hf_knxip_srp_type;
260 static int hf_knxip_reset_command;
261 static int hf_knxip_session;
262 static int hf_knxip_tag;
263 static int hf_knxip_user;
264 static int hf_knxip_session_status;
266 /* Initialize the subtree pointers. These pointers are needed to
267 display the protocol in a structured tree. Subtrees hook on
268 already defined fields or (the topmost) on the protocol itself
270 static int ett_kip;
271 static int ett_efcp;
272 static int ett_service;
273 static int ett_hpai;
274 static int ett_dib;
275 static int ett_medium;
276 static int ett_status;
277 static int ett_projectid;
278 static int ett_service_family;
279 static int ett_ip_assignment;
280 static int ett_cri;
281 static int ett_crd;
282 static int ett_cnhdr;
283 static int ett_loss;
284 static int ett_busy;
285 static int ett_selector;
286 static int ett_decrypted;
287 static int ett_tunnel;
289 /* Set up the value_string tables for the service families
290 and the service types (note that the service types in KNXnet/IP
291 version 1.0 are unique even across service families...)
293 static const value_string knxip_service_family_vals[] = {
294 { KIP_SERVICE_CORE, "Core" },
295 { KIP_SERVICE_MANAGEMENT, "Device Management" },
296 { KIP_SERVICE_TUNNELING, "Tunneling" },
297 { KIP_SERVICE_ROUTING, "Routing" },
298 { KIP_SERVICE_REMOTE_LOGGING, "Remote Logging" },
299 { KIP_SERVICE_REMOTE_DIAG_AND_CONFIG, "Remote Diag And Config" },
300 { KIP_SERVICE_OBJECT_SERVER, "Object Server" },
301 { KIP_SERVICE_SECURITY, "Security" },
302 { 0, NULL}
304 static const value_string knxip_service_type_vals[] = {
305 { KIP_SEARCH_REQUEST, "Search Request" },
306 { KIP_SEARCH_RESPONSE, "Search Response" },
307 { KIP_DESCRIPTION_REQUEST, "Description Request" },
308 { KIP_DESCRIPTION_RESPONSE, "Description Response" },
309 { KIP_CONNECT_REQUEST, "Connect Request" },
310 { KIP_CONNECT_RESPONSE, "Connect Response" },
311 { KIP_CONNECTIONSTATE_REQUEST, "Connection State Request" },
312 { KIP_CONNECTIONSTATE_RESPONSE, "Connection State Response" },
313 { KIP_DISCONNECT_REQUEST, "Disconnect Request" },
314 { KIP_DISCONNECT_RESPONSE, "Disconnect Response" },
315 { KIP_SEARCH_REQUEST_EXT, "Search Request Extended" },
316 { KIP_SEARCH_RESPONSE_EXT, "Search Response Extended" },
317 { KIP_CONFIGURATION_REQUEST, "Configuration Request" },
318 { KIP_CONFIGURATION_ACK, "Configuration Acknowledgement" },
319 { KIP_TUNNELING_REQUEST, "Tunneling Request" },
320 { KIP_TUNNELING_ACK, "Tunneling Acknowledgement" },
321 { KIP_TUNNELING_FEATURE_GET, "Tunneling Feature Get" },
322 { KIP_TUNNELING_FEATURE_RESPONSE, "Tunneling Feature Response" },
323 { KIP_TUNNELING_FEATURE_SET, "Tunneling Feature Set" },
324 { KIP_TUNNELING_FEATURE_INFO, "Tunneling Feature Info" },
325 { KIP_ROUTING_INDICATION, "Routing Indication" },
326 { KIP_ROUTING_LOST_MESSAGE, "Routing Loss" },
327 { KIP_ROUTING_BUSY, "Routing Busy" },
328 { KIP_ROUTING_SYSTEM_BROADCAST, "Routing System Broadcast" },
329 { KIP_REMOTE_DIAG_REQUEST, "Remote Diagnostic Request" },
330 { KIP_REMOTE_DIAG_RESPONSE, "Remote Diagnostic Response" },
331 { KIP_REMOTE_CONFIG_REQUEST, "Remote Configuration Request" },
332 { KIP_REMOTE_RESET_REQUEST, "Remote Reset Request" },
333 { KIP_SECURE_WRAPPER, "Secure Wrapper" },
334 { KIP_SESSION_REQUEST, "Session Request" },
335 { KIP_SESSION_RESPONSE, "Session Response" },
336 { KIP_SESSION_AUTHENTICATE, "Session Authenticate" },
337 { KIP_SESSION_STATUS, "Session Status" },
338 { KIP_TIMER_NOTIFY, "Timer Notify" },
339 { 0, NULL}
341 static const value_string svc_vals[] = { /* abbreviated service names */
342 { KIP_SEARCH_REQUEST, "SearchReq" },
343 { KIP_SEARCH_RESPONSE, "SearchResp" },
344 { KIP_DESCRIPTION_REQUEST, "DescrReq" },
345 { KIP_DESCRIPTION_RESPONSE, "DescrResp" },
346 { KIP_CONNECT_REQUEST, "ConnectReq" },
347 { KIP_CONNECT_RESPONSE, "ConnectResp" },
348 { KIP_CONNECTIONSTATE_REQUEST, "ConnStateReq" },
349 { KIP_CONNECTIONSTATE_RESPONSE, "ConnStateResp" },
350 { KIP_DISCONNECT_REQUEST, "DisconnectReq" },
351 { KIP_DISCONNECT_RESPONSE, "DisconnectResp" },
352 { KIP_SEARCH_REQUEST_EXT, "SearchReqExt" },
353 { KIP_SEARCH_RESPONSE_EXT, "SearchRespExt" },
354 { KIP_CONFIGURATION_REQUEST, "ConfigReq" },
355 { KIP_CONFIGURATION_ACK, "ConfigAck" },
356 { KIP_TUNNELING_REQUEST, "TunnelReq" },
357 { KIP_TUNNELING_ACK, "TunnelAck" },
358 { KIP_TUNNELING_FEATURE_GET, "TunnelFeatureGet" },
359 { KIP_TUNNELING_FEATURE_RESPONSE, "TunnelFeatureResp" },
360 { KIP_TUNNELING_FEATURE_SET, "TunnelFeatureSet" },
361 { KIP_TUNNELING_FEATURE_INFO, "TunnelFeatureInfo" },
362 { KIP_ROUTING_INDICATION, "RoutingInd" },
363 { KIP_ROUTING_LOST_MESSAGE, "RoutingLoss" },
364 { KIP_ROUTING_BUSY, "RoutingBusy" },
365 { KIP_ROUTING_SYSTEM_BROADCAST, "RoutingSBC" },
366 { KIP_REMOTE_DIAG_REQUEST, "RemoteDiagReq" },
367 { KIP_REMOTE_DIAG_RESPONSE, "RemoteDiagResp" },
368 { KIP_REMOTE_CONFIG_REQUEST, "RemoteConfigReq" },
369 { KIP_REMOTE_RESET_REQUEST, "RemoteResetReq" },
370 { KIP_SECURE_WRAPPER, "SecureWrapper" },
371 { KIP_SESSION_REQUEST, "SessionReq" },
372 { KIP_SESSION_RESPONSE, "SessionResp" },
373 { KIP_SESSION_AUTHENTICATE, "SessionAuth" },
374 { KIP_SESSION_STATUS, "SessionStatus" },
375 { KIP_TIMER_NOTIFY, "TimerNotify" },
376 { 0, NULL}
378 static const value_string host_protocol_vals[] = {
379 { KIP_IPV4_UDP, "IPv4 UDP" },
380 { KIP_IPV4_TCP, "IPv4 TCP" },
381 { 0, NULL}
383 static const value_string description_type_vals[] = {
384 { KIP_DIB_DEVICE_INFO, "Device Information" },
385 { KIP_DIB_SUPP_SVC_FAMILIES, "Supported Service Families" },
386 { KIP_DIB_IP_CONFIG, "IP Configuration" },
387 { KIP_DIB_CUR_CONFIG, "Current Configuration" },
388 { KIP_DIB_KNX_ADDRESSES, "KNX Addresses" },
389 { KIP_DIB_SECURED_SERVICE_FAMILIES, "Secured Service Families" },
390 { KIP_DIB_TUNNELING_INFO, "Tunneling Information" },
391 { KIP_DIB_EXTENDED_DEVICE_INFO, "Extended Device Information" },
392 { KIP_DIB_MFR_DATA, "Manufacturer Data" },
393 { 0, NULL}
395 static const value_string descr_type_vals[] = { /* abbreviated DIB names */
396 { KIP_DIB_DEVICE_INFO, "DevInfo" },
397 { KIP_DIB_SUPP_SVC_FAMILIES, "SuppSvc" },
398 { KIP_DIB_IP_CONFIG, "IpConfig" },
399 { KIP_DIB_CUR_CONFIG, "CurConfig" },
400 { KIP_DIB_KNX_ADDRESSES, "KnxAddr" },
401 { KIP_DIB_SECURED_SERVICE_FAMILIES, "SecSvcFam" },
402 { KIP_DIB_TUNNELING_INFO, "TunnelInfo" },
403 { KIP_DIB_EXTENDED_DEVICE_INFO, "ExtDevInfo" },
404 { KIP_DIB_MFR_DATA, "MfrData" },
405 { 0, NULL}
407 #if 0
408 static const value_string search_request_parameter_type_vals[] = {
409 { KIP_SRP_BY_PROGMODE, "By programming mode" },
410 { KIP_SRP_BY_MACADDR, "By MAC address" },
411 { KIP_SRP_BY_SERVICE, "By service" },
412 { KIP_SRP_REQUEST_DIBS, "Request DIBs" },
413 { 0, NULL }
415 #endif
416 static const value_string srp_type_vals[] = { /* abbreviated SRP names */
417 { KIP_SRP_BY_PROGMODE, "ProgMode" },
418 { KIP_SRP_BY_MACADDR, "MacAddr" },
419 { KIP_SRP_BY_SERVICE, "Service" },
420 { KIP_SRP_REQUEST_DIBS, "Dibs" },
421 { 0, NULL }
423 static const value_string medium_type_vals[] = {
424 { KIP_KNXTYPE_TP0, "TP0" },
425 { KIP_KNXTYPE_TP1, "TP1" },
426 { KIP_KNXTYPE_PL110, "PL110" },
427 { KIP_KNXTYPE_PL132, "PL132" },
428 { KIP_KNXTYPE_RF, "RF" },
429 { KIP_KNXTYPE_IP, "IP" },
430 { 0, NULL}
432 static const value_string connection_type_vals[] = {
433 { KIP_DEVICE_MGMT_CONNECTION, "Device Management Connection" },
434 { KIP_TUNNEL_CONNECTION, "Tunneling Connection" },
435 { KIP_REMLOG_CONNECTION, "Remote Logging Connection" },
436 { KIP_REMCONF_CONNECTION, "Remote Configuration Connection" },
437 { KIP_OBJSVR_CONNECTION, "Object Server Connection" },
438 { 0, NULL}
440 static const value_string conn_type_vals[] = {
441 { KIP_DEVICE_MGMT_CONNECTION, "Config" },
442 { KIP_TUNNEL_CONNECTION, "Tunnel" },
443 { KIP_REMLOG_CONNECTION, "RemoteLogging" },
444 { KIP_REMCONF_CONNECTION, "RemoteConfig" },
445 { KIP_OBJSVR_CONNECTION, "ObjectServer" },
446 { 0, NULL }
448 static const value_string tunneling_feature_id_vals[] = {
449 { KIP_TUNNELING_FEATURE_ID_SUPPORTED_EMI_TYPE, "SupportedEmiType" },
450 { KIP_TUNNELING_FEATURE_ID_HOST_DEVICE_DEVICE_DESCRIPTOR_TYPE_0, "MaskVersion" },
451 { KIP_TUNNELING_FEATURE_ID_BUS_CONNECTION_STATUS, "BusStatus" },
452 { KIP_TUNNELING_FEATURE_ID_KNX_MANUFACTURER_CODE, "Manufacturer" },
453 { KIP_TUNNELING_FEATURE_ID_ACTIVE_EMI_TYPE, "ActiveEmiType" },
454 { KIP_TUNNELING_FEATURE_ID_INDIVIDUAL_ADDRESS, "IndividualAddress" },
455 { KIP_TUNNELING_FEATURE_ID_MAX_APDU_LENGTH, "MaxApduLength" },
456 { KIP_TUNNELING_FEATURE_ID_INFO_SERVICE_ENABLE, "InfoServiceEnable" },
457 { 0, NULL }
459 static const value_string knx_layer_vals[] = {
460 { TUNNEL_LINKLAYER, "LinkLayer" },
461 { TUNNEL_RAW, "Raw" },
462 { TUNNEL_BUSMONITOR, "Busmonitor" },
463 { 0, NULL}
465 static const value_string error_vals[] = {
466 { KIP_E_NO_ERROR, "OK" },
467 { KIP_E_CONNECTION_ID, "E_CONNECTION_ID" },
468 { KIP_E_CONNECTION_TYPE, "E_CONNECTION_TYPE" },
469 { KIP_E_CONNECTION_OPTION, "E_CONNECTION_OPTION" },
470 { KIP_E_NO_MORE_CONNECTIONS, "E_NO_MORE_CONNECTIONS" },
471 { KIP_E_NO_MORE_UNIQUE_CONNECTIONS, "E_NO_MORE_UNIQUE_CONNECTIONS" },
472 { KIP_E_DATA_CONNECTION, "E_DATA_CONNECTION" },
473 { KIP_E_KNX_CONNECTION, "E_KNX_CONNECTION" },
474 { KIP_E_TUNNELING_LAYER, "E_TUNNELING_LAYER" },
475 { 0, NULL}
477 static const value_string session_status_vals[] = {
478 { SESSION_STATUS_AUTHENTICATION_SUCCESS, "STATUS_AUTHENTICATION_SUCCESS" },
479 { SESSION_STATUS_AUTHENTICATION_FAILED, "STATUS_AUTHENTICATION_FAILED" },
480 { SESSION_STATUS_UNAUTHENTICATED, "STATUS_UNAUTHENTICATED" },
481 { SESSION_STATUS_TIMEOUT, "STATUS_TIMEOUT" },
482 { SESSION_STATUS_KEEPALIVE, "STATUS_KEEPALIVE" },
483 { SESSION_STATUS_CLOSE, "STATUS_CLOSE" },
484 { 0, NULL }
487 uint8_t knxip_error;
488 uint8_t knxip_host_protocol;
490 expert_field ei_knxip_error;
491 expert_field ei_knxip_warning;
493 static bool pref_desegment = true;
494 static const char* pref_key_texts[ MAX_KNX_DECRYPTION_KEYS ];
495 //static const char* authentication_code_text;
496 //static const char* password_hash_text;
497 static const char* pref_key_file_name;
498 static const char* pref_key_file_pwd;
499 static const char* pref_key_info_file_name;
501 /* KNX decryption keys
503 uint8_t knx_decryption_keys[ MAX_KNX_DECRYPTION_KEYS ][ KNX_KEY_LENGTH ];
504 uint8_t knx_decryption_key_count;
506 /* Forward declarations
508 static int dissect_knxip( tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_ );
509 void proto_reg_handoff_knxip( void );
510 void proto_register_knxip( void );
512 /* Add raw data to list view, tree view, and parent folder
514 static proto_item* knxip_tree_add_data( proto_tree* tree, tvbuff_t* tvb, int offset, int length, column_info* cinfo, proto_item* item,
515 const char* name, const char* text1, const char* text2 )
517 proto_item* new_item = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, length, NULL, "%s: $", name );
518 if( text1 ) col_append_str( cinfo, COL_INFO, text1 );
519 if( text2 ) proto_item_append_text( item, "%s", text2 );
521 while( length > 0 )
523 uint8_t value = tvb_get_uint8( tvb, offset );
524 if( text1 ) col_append_fstr( cinfo, COL_INFO, "%02X", value );
525 if( text2 ) proto_item_append_text( item, "%02X", value );
526 proto_item_append_text( new_item, " %02X", value );
527 offset++;
528 length--;
531 return new_item;
534 /* Show unknown or unexpected data
536 static proto_item* knxip_tree_add_unknown_data( proto_tree* tree, tvbuff_t* tvb, int offset, int length )
538 return proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, length, NULL, "? Unknown data (%d bytes)", length );
541 static uint8_t hex_to_knx_key( const char* text, uint8_t key[ KNX_KEY_LENGTH ] )
543 size_t n_bytes = 0;
544 uint8_t* bytes = convert_string_to_hex( text, &n_bytes );
545 if( bytes == NULL )
547 n_bytes = 0;
549 else
551 if( n_bytes )
553 if( n_bytes > KNX_KEY_LENGTH ) n_bytes = KNX_KEY_LENGTH;
554 if( n_bytes ) memcpy( key, bytes, n_bytes );
555 while( n_bytes < KNX_KEY_LENGTH ) key[ n_bytes++ ] = 0;
557 g_free( bytes );
559 return n_bytes != 0;
562 static proto_item* knxip_tree_add_status( proto_tree* tree, tvbuff_t* tvb, int offset )
564 return proto_tree_add_item( tree, hf_knxip_status, tvb, offset, 1, ENC_BIG_ENDIAN );
567 static proto_item* knxip_tree_add_reserved( proto_tree* tree, tvbuff_t* tvb, int offset, packet_info* pinfo, uint8_t* p_ok )
569 proto_item* new_item = proto_tree_add_item( tree, hf_knxip_reserved, tvb, offset, 1, ENC_BIG_ENDIAN );
570 if( tvb_get_uint8( tvb, offset ) )
572 proto_item_prepend_text( new_item, "? " );
573 expert_add_info_format( pinfo, new_item, KIP_ERROR, "Expected: 0x00" );
574 if( p_ok ) *p_ok = 0;
576 return new_item;
579 static proto_item* knxip_tree_add_missing_reserved( proto_tree* tree, tvbuff_t* tvb, int offset, packet_info* pinfo )
581 proto_item* new_item = proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Reserved: expected 1 byte" );
582 return new_item;
585 static proto_item* knxip_tree_add_length( proto_tree* tree, tvbuff_t* tvb, int offset, int value )
587 return proto_tree_add_uint_format_value( tree, hf_knxip_structure_length, tvb, offset, 1, value, "%u bytes", value );
590 static void knxip_item_illegal_length( proto_item* length_item, packet_info* pinfo, const char* info )
592 proto_item_prepend_text( length_item, "? " );
593 expert_add_info_format( pinfo, length_item, KIP_ERROR, "%s", info );
596 static proto_item* knxip_tree_add_ip_address( proto_tree* tree, tvbuff_t* tvb, int offset, char* output, int output_max )
598 if( output )
600 const uint8_t* ipa = tvb_get_ptr( tvb, offset, 4 );
601 snprintf( output, output_max, "%u.%u.%u.%u", ipa[ 0 ], ipa[ 1 ], ipa[ 2 ], ipa[ 3 ] );
603 return proto_tree_add_item( tree, hf_knxip_ip_address, tvb, offset, 4, ENC_BIG_ENDIAN );
606 static proto_item* knxip_tree_add_knx_address( proto_tree* tree, int hfindex, tvbuff_t* tvb, int offset, char* output, int output_max )
608 uint16_t value = tvb_get_ntohs( tvb, offset );
609 char text[ 32 ];
610 snprintf( text, sizeof text, "%u.%u.%u", (value >> 12) & 0xF, (value >> 8) & 0xF, value & 0xFF );
611 if( output ) snprintf( output, output_max, "%s", text );
612 proto_item* new_item = proto_tree_add_item( tree, hfindex, tvb, offset, 2, ENC_BIG_ENDIAN );
613 proto_item_append_text( new_item, " = %s", text );
614 return new_item;
617 static proto_item* knxip_tree_add_bit( proto_tree* tree, tvbuff_t* tvb, int offset, int bitpos, const char* name, char* output, int output_max )
619 char format[ 32 ] = ".... .... = %s: %d";
620 uint8_t value = (tvb_get_uint8( tvb, offset ) >> bitpos) & 1;
621 format[ 7 - bitpos + (bitpos < 4) ] = '0' + value;
623 if( value && output )
625 if( *output )
627 do { ++output; --output_max; } while( *output );
628 snprintf( output, output_max, " | " );
629 while( *output ) { ++output; --output_max; }
632 snprintf( output, output_max, "%s", name );
635 return proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, 1, NULL, format, name, value );
638 static proto_item* knxip_tree_add_ip_assignment( proto_tree* tree, int hfindex, tvbuff_t* tvb, int offset, uint8_t manual )
640 proto_item* node = proto_tree_add_item( tree, hfindex, tvb, offset, 1, ENC_BIG_ENDIAN );
641 proto_tree* list = proto_item_add_subtree( node, ett_ip_assignment );
642 char output[ 128 ];
643 *output = '\0';
644 knxip_tree_add_bit( list, tvb, offset, 2 + manual, "AutoIP", output, sizeof output );
645 knxip_tree_add_bit( list, tvb, offset, 1 + manual, "DHCP", output, sizeof output );
646 knxip_tree_add_bit( list, tvb, offset, 0 + manual, "BootP", output, sizeof output );
647 if( manual ) knxip_tree_add_bit( list, tvb, offset, 0, "manual", output, sizeof output );
648 if( *output ) proto_item_append_text( node, " = %s", output );
649 return node;
652 /* Dissect HPAI field
654 static uint8_t dissect_hpai( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset, uint8_t* p_ok, char* name, uint8_t check_protocol )
656 uint8_t ok = 1;
657 int offset = *p_offset;
658 int remaining_len = tvb_captured_length_remaining( tvb, offset );
659 uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
660 int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
662 proto_item* hpai_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "HPAI %s Endpoint", name );
664 char info[ 80 ];
665 char* output = info;
666 int output_max = sizeof info;
667 snprintf( info, sizeof info, "???" );
669 if( struct_len <= 0 )
671 proto_item_prepend_text( hpai_item, "Missing " );
672 expert_add_info_format( pinfo, hpai_item, KIP_ERROR, "Expected: 8 bytes" );
673 ok = 0;
675 else
677 /* 1 byte Structure Length */
678 proto_tree* hpai_tree = proto_item_add_subtree( hpai_item, ett_hpai );
679 proto_item* length_item = knxip_tree_add_length( hpai_tree, tvb, offset, struct_len );
680 proto_item* node;
682 int end_pos = offset + eff_struct_len;
683 offset++;
685 if( struct_len != 8 )
687 knxip_item_illegal_length( length_item, pinfo, "Expected: 8 bytes" );
688 ok = 0;
691 if( struct_len > remaining_len )
693 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
694 struct_len = (uint8_t) remaining_len;
696 if( ok )
698 proto_item_prepend_text( length_item, "? " );
699 ok = 0;
702 else if( struct_len < 2 )
704 expert_add_info_format( pinfo, hpai_item, KIP_ERROR, "Missing 1 byte Host Protocol" );
705 ok = 0;
707 else
709 /* 1 byte Host Protocol */
710 uint8_t host_protocol = tvb_get_uint8( tvb, offset );
711 const char* host_protocol_name = "???";
712 uint8_t protocol_error = 0;
714 node = proto_tree_add_item( hpai_tree, hf_knxip_host_protocol, tvb, offset, 1, ENC_BIG_ENDIAN );
716 if( host_protocol == KIP_IPV4_UDP )
718 host_protocol_name = "UDP";
719 if( check_protocol )
721 if( knxip_host_protocol != IP_PROTO_UDP && knxip_host_protocol != IP_PROTO_UDPLITE )
723 protocol_error = 1;
727 else if( host_protocol == KIP_IPV4_TCP )
729 host_protocol_name = "TCP";
730 if( check_protocol )
732 if( knxip_host_protocol != IP_PROTO_TCP )
734 protocol_error = 1;
738 else
740 protocol_error = 2;
743 if( protocol_error )
745 proto_item_prepend_text( node, "? " );
746 expert_add_info_format( pinfo, node, KIP_ERROR, (protocol_error == 1) ? "Wrong Host Protocol" : "Expected: 0x01 or 0x02" );
747 ok = 0;
750 offset++;
752 if( struct_len < 6 )
754 expert_add_info_format( pinfo, hpai_item, KIP_ERROR, "Missing 4 bytes IP Address" );
755 ok = 0;
757 else
759 /* 4 bytes IP Address */
760 node = knxip_tree_add_ip_address( hpai_tree, tvb, offset, output, output_max );
762 if( host_protocol == KIP_IPV4_TCP && strcmp( output, "0.0.0.0" ) != 0 )
764 proto_item_prepend_text( node, "? " );
765 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 0.0.0.0" );
766 ok = 0;
769 offset += 4;
771 while( *output ) { ++output; --output_max; }
772 if( output_max > 1 ) { *output++ = ':'; --output_max; }
773 snprintf( output, output_max, "???" );
775 if( struct_len < 8 )
777 expert_add_info_format( pinfo, hpai_item, KIP_ERROR, "Missing 2 bytes Port Number" );
778 ok = 0;
780 else
782 /* 2 bytes Port Number */
783 uint16_t port = tvb_get_ntohs( tvb, offset );
785 snprintf( output, output_max, "%u", port );
786 while( *output ) { ++output; --output_max; }
788 node = proto_tree_add_item( hpai_tree, hf_knxip_port, tvb, offset, 2, ENC_BIG_ENDIAN );
790 if( host_protocol == KIP_IPV4_TCP && port != 0 )
792 proto_item_prepend_text( node, "? " );
793 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 0" );
794 ok = 0;
797 offset += 2;
801 if( offset < end_pos )
803 knxip_tree_add_unknown_data( hpai_tree, tvb, offset, end_pos - offset );
804 ok = 0;
807 proto_item_append_text( hpai_item, ": %s %s", info, host_protocol_name );
811 col_append_fstr( pinfo->cinfo, COL_INFO, " @%s", info );
812 proto_item_append_text( item, ", %s @ %s", name, info );
814 if( !ok )
816 proto_item_prepend_text( hpai_item, "? " );
817 if( p_ok ) *p_ok = 0;
820 *p_offset += struct_len;
821 return struct_len;
824 /* Dissect CRI (= Connection Request Information)
826 static uint8_t dissect_cri( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset, uint8_t* p_ok )
828 int offset = *p_offset;
829 int remaining_len = tvb_captured_length_remaining( tvb, offset );
830 uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
831 int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
833 proto_item* cri_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "CRI" );
835 uint8_t conn_type = 0;
836 const char* conn_type_name = NULL;
837 uint8_t ok = 0;
838 char extra_text[ 32 ];
839 *extra_text = '\0';
841 if( struct_len <= 0 )
843 proto_item_prepend_text( cri_item, "Missing " );
844 expert_add_info_format( pinfo, cri_item, KIP_ERROR, "Expected: min 2 bytes" );
845 //ok = 0;
847 else
849 proto_tree* cri_tree = proto_item_add_subtree( cri_item, ett_cri );
850 proto_item* length_item = knxip_tree_add_length( cri_tree, tvb, offset, struct_len );
851 proto_item* type_item = NULL;
852 uint8_t length_ok = 1;
854 if( struct_len > remaining_len )
856 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
857 struct_len = (uint8_t) remaining_len;
858 //ok = 0;
859 length_ok = 0;
862 if( struct_len < 2 )
864 expert_add_info_format( pinfo, cri_item, KIP_ERROR, "Missing 1 byte Connection Type" );
865 //ok = 0;
867 else
869 conn_type = tvb_get_uint8( tvb, offset + 1 );
870 type_item = proto_tree_add_item( cri_tree, hf_knxip_connection_type, tvb, offset + 1, 1, ENC_BIG_ENDIAN );
871 conn_type_name = try_val_to_str( conn_type, connection_type_vals );
872 if( !conn_type_name )
874 proto_item_prepend_text( type_item, "? " );
875 expert_add_info_format( pinfo, type_item, KIP_ERROR, "Unknown" );
876 //ok = 0;
878 if( struct_len > 2 )
880 knxip_tree_add_unknown_data( cri_tree, tvb, offset + 2, struct_len - 2 );
883 else
885 proto_item_append_text( cri_item, " %s", conn_type_name );
886 ok = 1;
888 switch( conn_type )
890 case KIP_DEVICE_MGMT_CONNECTION:
891 case KIP_REMLOG_CONNECTION:
892 case KIP_REMCONF_CONNECTION:
893 case KIP_OBJSVR_CONNECTION:
894 if( struct_len > 2 )
896 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 2 bytes" );
897 length_ok = 0;
899 knxip_tree_add_unknown_data( cri_tree, tvb, offset + 2, struct_len - 2 );
900 ok = 0;
902 break;
904 case KIP_TUNNEL_CONNECTION:
905 if( (struct_len != 4) && (struct_len != 6) )
907 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 4 or 6 bytes" );
908 length_ok = 0;
909 ok = 0;
911 if( struct_len >= 3 )
913 uint8_t knx_layer = tvb_get_uint8( tvb, offset + 2 );
914 const char* knx_layer_name = try_val_to_str( knx_layer, knx_layer_vals );
915 proto_item* layer_item = proto_tree_add_item( cri_tree, hf_knxip_knx_layer, tvb, offset + 2, 1, ENC_BIG_ENDIAN );
916 proto_item_append_text( cri_item, ", Layer: %s", knx_layer_name ? knx_layer_name : "Unknown" );
917 if( !knx_layer_name )
919 proto_item_prepend_text( layer_item, "? " );
920 expert_add_info_format( pinfo, layer_item, KIP_ERROR, "Expected: 0x02" );
921 ok = 0;
924 if( struct_len < 4 )
926 expert_add_info_format( pinfo, cri_item, KIP_ERROR, "Missing Reserved byte" );
927 ok = 0;
929 else
931 knxip_tree_add_reserved( cri_tree, tvb, offset + 3, pinfo, &ok );
933 if( struct_len >= 6 )
935 knxip_tree_add_knx_address( cri_tree, hf_knxip_knx_address, tvb, offset + 4, extra_text, sizeof extra_text );
937 if( struct_len > 6 )
939 knxip_tree_add_unknown_data( cri_tree, tvb, offset + 6, struct_len - 6 );
940 ok = 0;
943 break;
948 if( !length_ok )
950 proto_item_prepend_text( length_item, "? " );
954 conn_type_name = try_val_to_str( conn_type, conn_type_vals );
955 if( !conn_type_name )
957 ok = 0;
959 else
961 if( pinfo )
963 column_info* cinfo = pinfo->cinfo;
964 col_prepend_fstr( cinfo, COL_INFO, "%s ", conn_type_name );
965 if( *extra_text )
967 col_append_fstr( cinfo, COL_INFO, ", %s", extra_text );
971 proto_item_append_text( item, ", %s", conn_type_name );
972 if( *extra_text )
974 proto_item_append_text( item, ", %s", extra_text );
978 if( !ok )
980 proto_item_prepend_text( cri_item, "? " );
981 if( p_ok ) *p_ok = 0;
984 *p_offset += struct_len;
985 return struct_len;
988 /* Dissect CRD (= Connection Response Data)
990 static uint8_t dissect_crd( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset, uint8_t* p_ok )
992 int offset = *p_offset;
993 int remaining_len = tvb_captured_length_remaining( tvb, offset );
994 uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
995 int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
997 proto_item* crd_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "CRD" );
999 uint8_t conn_type = 0;
1000 const char* conn_type_name = NULL;
1001 uint8_t ok = 0;
1003 if( struct_len <= 0 )
1005 proto_item_prepend_text( crd_item, "Missing " );
1006 expert_add_info_format( pinfo, crd_item, KIP_ERROR, "Expected: min 2 bytes" );
1007 //ok = 0;
1009 else
1011 proto_tree* crd_tree = proto_item_add_subtree( crd_item, ett_crd );
1012 proto_item* length_item = knxip_tree_add_length( crd_tree, tvb, offset, struct_len );
1013 proto_item* type_item = NULL;
1014 uint8_t length_ok = 1;
1016 if( struct_len > remaining_len )
1018 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
1019 struct_len = (uint8_t) remaining_len;
1020 //ok = 0;
1021 length_ok = 0;
1024 if( struct_len < 2 )
1026 expert_add_info_format( pinfo, crd_item, KIP_ERROR, "Missing 1 byte Connection Type" );
1027 //ok = 0;
1029 else
1031 conn_type = tvb_get_uint8( tvb, offset + 1 );
1032 type_item = proto_tree_add_item( crd_tree, hf_knxip_connection_type, tvb, offset + 1, 1, ENC_BIG_ENDIAN );
1033 conn_type_name = try_val_to_str( conn_type, connection_type_vals );
1034 if( !conn_type_name )
1036 proto_item_prepend_text( type_item, "? " );
1037 expert_add_info_format( pinfo, type_item, KIP_ERROR, "Unknown" );
1038 //ok = 0;
1040 if( struct_len > 2 )
1042 knxip_tree_add_unknown_data( crd_tree, tvb, offset + 2, struct_len - 2 );
1045 else
1047 proto_item_append_text( crd_item, " %s", conn_type_name );
1048 ok = 1;
1050 switch( conn_type )
1052 case KIP_DEVICE_MGMT_CONNECTION:
1053 case KIP_REMLOG_CONNECTION:
1054 case KIP_REMCONF_CONNECTION:
1055 case KIP_OBJSVR_CONNECTION:
1056 if( struct_len > 2 )
1058 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 2 bytes" );
1059 knxip_tree_add_unknown_data( crd_tree, tvb, offset + 2, struct_len - 2 );
1060 ok = 0;
1061 length_ok = 0;
1063 break;
1065 case KIP_TUNNEL_CONNECTION:
1066 if( struct_len != 4 )
1068 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 4 bytes" );
1069 ok = 0;
1070 length_ok = 0;
1073 if( struct_len < 4 )
1075 expert_add_info_format( pinfo, crd_item, KIP_ERROR, "Missing 2 bytes KNX Address" );
1076 //ok = 0;
1077 if( struct_len > 2 )
1079 knxip_tree_add_unknown_data( crd_tree, tvb, offset + 2, struct_len - 2 );
1082 else
1084 char output[ 40 ];
1085 knxip_tree_add_knx_address( crd_tree, hf_knxip_knx_address, tvb, offset + 2, output, sizeof output );
1086 proto_item_append_text( crd_item, ", KNX Address: %s", output );
1087 if( pinfo )
1089 col_append_fstr( pinfo->cinfo, COL_INFO, ", %s", output );
1091 if( item )
1093 proto_item_append_text( item, ", %s", output );
1095 if( struct_len > 4 )
1097 knxip_tree_add_unknown_data( crd_tree, tvb, offset + 4, struct_len - 4 );
1098 //ok = 0;
1101 break;
1106 if( !length_ok )
1108 proto_item_prepend_text( length_item, "? " );
1112 conn_type_name = try_val_to_str( conn_type, conn_type_vals );
1113 if( pinfo && conn_type_name ) col_prepend_fstr( pinfo->cinfo, COL_INFO, "%s ", conn_type_name );
1114 proto_item_append_text( item, ", %s", conn_type_name ? conn_type_name : "???" );
1116 if( !ok )
1118 proto_item_prepend_text( crd_item, "? " );
1119 if( p_ok ) *p_ok = 0;
1122 *p_offset += struct_len;
1123 return struct_len;
1126 /* Dissect Connection Header
1128 static uint8_t dissect_cnhdr( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset, uint8_t* p_ok, uint8_t response )
1130 int offset = *p_offset;
1131 int remaining_len = tvb_captured_length_remaining( tvb, offset );
1132 uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
1133 int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
1135 proto_item* cnhdr_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "Connection Header" );
1137 uint8_t ok = 0;
1138 char info[ 100 ];
1139 int output_max = sizeof info;
1140 char* output = info;
1142 *output++ = '#';
1143 output_max--;
1144 snprintf( output, output_max, "???" );
1146 if( struct_len <= 0 )
1148 proto_item_prepend_text( cnhdr_item, "Missing " );
1149 expert_add_info_format( pinfo, cnhdr_item, KIP_ERROR, "Expected: 4 bytes" );
1151 else
1153 proto_tree* cnhdr_tree = proto_item_add_subtree( cnhdr_item, ett_cnhdr );
1154 proto_item* length_item = knxip_tree_add_length( cnhdr_tree, tvb, offset, struct_len );
1156 int end_pos = offset + eff_struct_len;
1157 offset++;
1159 if( struct_len == 4 )
1161 ok = 1;
1163 else
1165 knxip_item_illegal_length( length_item, pinfo, "Expected: 4 bytes" );
1168 if( struct_len > remaining_len )
1170 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
1171 struct_len = (uint8_t) remaining_len;
1173 if( ok )
1175 proto_item_prepend_text( length_item, "? " );
1176 ok = 0;
1180 if( struct_len < 2 )
1182 expert_add_info_format( pinfo, cnhdr_item, KIP_ERROR, "Missing 1 byte Channel" );
1183 //ok = 0;
1185 else
1187 snprintf( output, output_max, "%02X:", tvb_get_uint8( tvb, offset ) );
1188 while( *output ) { ++output; --output_max; }
1189 snprintf( output, output_max, "???" );
1191 proto_tree_add_item( cnhdr_tree, hf_knxip_channel, tvb, offset, 1, ENC_BIG_ENDIAN );
1192 offset++;
1194 if( struct_len < 3 )
1196 expert_add_info_format( pinfo, cnhdr_item, KIP_ERROR, "Missing 1 byte Sequence Counter" );
1197 //ok = 0;
1199 else
1201 snprintf( output, output_max, "%u", tvb_get_uint8( tvb, offset ) );
1202 while( *output ) { ++output; --output_max; }
1204 proto_tree_add_item( cnhdr_tree, hf_knxip_seq_counter, tvb, offset, 1, ENC_BIG_ENDIAN );
1205 offset++;
1207 if( response )
1209 if( output_max > 1 )
1211 *output++ = ' ';
1212 output_max--;
1213 snprintf( output, output_max, "???" );
1217 if( struct_len < 4 )
1219 expert_add_info_format( pinfo, cnhdr_item, KIP_ERROR, "Missing 1 byte %s", response ? "Status" : "Reserved" );
1220 //ok = 0;
1222 else
1224 if( response )
1226 snprintf( output, output_max, "%s", val_to_str( tvb_get_uint8( tvb, offset ), error_vals, "Error 0x%02x" ) );
1227 knxip_tree_add_status( cnhdr_tree, tvb, offset );
1229 else
1231 knxip_tree_add_reserved( cnhdr_tree, tvb, offset, pinfo, &ok );
1234 offset++;
1238 if( offset < end_pos )
1240 knxip_tree_add_unknown_data( cnhdr_tree, tvb, offset, end_pos - offset );
1241 //ok = 0;
1244 proto_item_append_text( cnhdr_item, ": %s", info );
1248 if( pinfo ) col_append_fstr( pinfo->cinfo, COL_INFO, " %s", info );
1249 proto_item_append_text( item, ", %s", info );
1251 if( !ok )
1253 proto_item_prepend_text( cnhdr_item, "? " );
1254 if( p_ok ) *p_ok = 0;
1257 *p_offset += struct_len;
1258 return struct_len;
1261 /* Dissect tunneling feature frames.
1263 static void dissect_tunneling_feature( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset, uint8_t* p_ok, uint16_t service )
1265 column_info* cinfo = pinfo->cinfo;
1266 int offset = *p_offset;
1267 int remaining_len;
1268 proto_item* node;
1269 uint8_t c;
1270 const char* name;
1271 uint8_t ok = 1;
1272 uint8_t isResponse = (service == KIP_TUNNELING_FEATURE_RESPONSE);
1273 uint8_t status = 0;
1275 /* Connection Header */
1276 dissect_cnhdr( tvb, pinfo, item, tree, &offset, &ok, false );
1278 remaining_len = tvb_captured_length_remaining( tvb, offset );
1280 /* 1 byte Feature Identifier */
1281 if( remaining_len <= 0 )
1283 proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Feature Identifier: expected 1 byte" );
1284 ok = 0;
1286 else
1288 c = tvb_get_uint8( tvb, offset );
1289 name = try_val_to_str( c, tunneling_feature_id_vals );
1290 if( !name ) name = "Unknown";
1291 node = proto_tree_add_item( tree, hf_knxip_tunnel_feature, tvb, offset, 1, ENC_BIG_ENDIAN );
1292 proto_item_append_text( node, " = %s", name );
1293 proto_item_append_text( item, " %s", name );
1294 col_append_fstr( cinfo, COL_INFO, " %s", name );
1296 ++offset;
1297 --remaining_len;
1300 /* 1 byte Return Code / Reserved */
1301 name = isResponse ? "Status" : "Reserved";
1302 if( remaining_len <= 0 )
1304 proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? %s: expected 1 byte", name );
1305 ok = 0;
1307 else
1309 status = tvb_get_uint8( tvb, offset );
1310 proto_tree_add_item( tree, isResponse ? hf_knxip_status : hf_knxip_reserved, tvb, offset, 1, ENC_BIG_ENDIAN );
1312 if( isResponse && (status != 0 || remaining_len == 1) )
1314 proto_item_append_text( item, " E=$%02X", status );
1315 col_append_fstr( cinfo, COL_INFO, " E=$%02X", status );
1318 ++offset;
1319 --remaining_len;
1322 /* Feature Value */
1323 if( remaining_len <= 0 )
1325 if( service != KIP_TUNNELING_FEATURE_GET && status == 0 )
1327 proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Feature Value: missing" );
1328 ok = 0;
1331 else
1333 node = knxip_tree_add_data( tree, tvb, offset, remaining_len, cinfo, item, "Feature Value", " $", " $" );
1334 if( service == KIP_TUNNELING_FEATURE_GET )
1336 expert_add_info_format( pinfo, node, KIP_ERROR, "Unexpected" );
1337 ok = 0;
1339 offset += remaining_len;
1342 *p_offset = offset;
1344 if( p_ok && !ok ) *p_ok = 0;
1347 /* Dissect cEMI
1349 static void dissect_cemi( tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int* p_offset )
1351 int offset = *p_offset;
1352 int remaining_len = tvb_captured_length_remaining( tvb, offset );
1354 /* Call the cEMI data dissector for the remaining bytes
1356 tvb = tvb_new_subset_remaining( tvb, offset );
1358 dissector_handle_t cemi_handle = find_dissector( "cemi" );
1359 if( cemi_handle )
1361 call_dissector( cemi_handle, tvb, pinfo, tree );
1365 *p_offset = offset + remaining_len;
1368 /* Dissect ROUTING_LOSS
1370 static uint8_t dissect_routing_loss( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
1372 int offset = *p_offset;
1373 int remaining_len = tvb_captured_length_remaining( tvb, offset );
1374 uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
1375 int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
1376 uint8_t ok = 0;
1378 proto_item* info_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, struct_len, "Loss Info" );
1380 char info[ 16 ];
1381 snprintf( info, sizeof info, "???" );
1383 if( struct_len <= 0 )
1385 proto_item_prepend_text( info_item, "Missing " );
1386 expert_add_info_format( pinfo, info_item, KIP_ERROR, "Expected: 4 bytes" );
1388 else
1390 proto_tree* info_tree = proto_item_add_subtree( info_item, ett_loss );
1391 proto_item* length_item = knxip_tree_add_length( info_tree, tvb, offset, struct_len );
1393 int end_pos = offset + eff_struct_len;
1394 offset++;
1396 if( struct_len == 4 )
1398 ok = 1;
1400 else
1402 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 4 bytes" );
1405 if( struct_len > remaining_len )
1407 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
1408 struct_len = (uint8_t) remaining_len;
1409 ok = 0;
1412 if( !ok )
1414 proto_item_prepend_text( length_item, "? " );
1417 if( struct_len >= 2 )
1419 knxip_tree_add_status( info_tree, tvb, offset );
1420 offset++;
1422 /* 2 bytes Lost Messages */
1423 if( struct_len >= 4 )
1425 uint16_t loss = tvb_get_ntohs( tvb, offset );
1426 snprintf( info, sizeof info, "%u", loss );
1427 proto_tree_add_item( info_tree, hf_knxip_routing_loss, tvb, offset, 2, ENC_BIG_ENDIAN );
1428 offset += 2;
1431 if( offset < end_pos )
1433 knxip_tree_add_unknown_data( info_tree, tvb, offset, end_pos - offset );
1436 proto_item_append_text( info_item, ": %s", info );
1440 if( pinfo ) col_append_fstr( pinfo->cinfo, COL_INFO, ": %s", info );
1441 proto_item_append_text( item, ": %s", info );
1443 if( !ok )
1445 proto_item_prepend_text( info_item, "? " );
1448 *p_offset += struct_len;
1449 return ok;
1452 /* Dissect ROUTING_BUSY
1454 static uint8_t dissect_routing_busy( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
1456 int offset = *p_offset;
1457 int remaining_len = tvb_captured_length_remaining( tvb, offset );
1458 uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
1459 int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
1460 uint8_t ok = 0;
1462 proto_item* info_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "Busy Info" );
1464 char info[ 16 ];
1465 snprintf( info, sizeof info, "???" );
1467 if( struct_len <= 0 )
1469 proto_item_prepend_text( info_item, "Missing " );
1470 expert_add_info_format( pinfo, info_item, KIP_ERROR, "Expected: 6 bytes" );
1472 else
1474 proto_tree* info_tree = proto_item_add_subtree( info_item, ett_loss );
1475 proto_item* length_item = knxip_tree_add_length( info_tree, tvb, offset, struct_len );
1477 int end_pos = offset + eff_struct_len;
1478 offset++;
1480 if( struct_len == 6 )
1482 ok = 1;
1484 else
1486 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 6 bytes" );
1489 if( struct_len > remaining_len )
1491 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
1492 struct_len = (uint8_t) remaining_len;
1493 ok = 0;
1496 if( !ok )
1498 proto_item_prepend_text( length_item, "? " );
1501 if( struct_len >= 2 )
1503 knxip_tree_add_status( info_tree, tvb, offset );
1504 offset++;
1506 if( struct_len >= 4 )
1508 /* 2 bytes Wait Time (ms) */
1509 proto_item* new_item = proto_tree_add_item( info_tree, hf_knxip_busy_time, tvb, offset, 2, ENC_BIG_ENDIAN );
1510 proto_item_append_text( new_item, " ms" );
1511 snprintf( info, sizeof info, "%u ms", tvb_get_ntohs( tvb, offset ) );
1512 offset += 2;
1514 if( struct_len >= 6 )
1516 /* 2 bytes Control */
1517 proto_tree_add_item( info_tree, hf_knxip_busy_control, tvb, offset, 2, ENC_BIG_ENDIAN );
1518 offset += 2;
1522 if( offset < end_pos )
1524 knxip_tree_add_unknown_data( info_tree, tvb, offset, end_pos - offset );
1527 proto_item_append_text( info_item, ": %s", info );
1531 if( pinfo ) col_append_fstr( pinfo->cinfo, COL_INFO, ": %s", info );
1532 proto_item_append_text( item, ": %s", info );
1534 if( !ok )
1536 proto_item_prepend_text( info_item, "? " );
1539 *p_offset += struct_len;
1540 return ok;
1543 /* Dissect SELECTOR field
1545 static uint8_t dissect_selector( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset, uint8_t* p_ok )
1547 int offset = *p_offset;
1548 int remaining_len = tvb_captured_length_remaining( tvb, offset );
1549 uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
1550 int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
1551 uint8_t ok = 0;
1553 proto_item* info_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "Selector" );
1555 char info[ 40 ];
1556 snprintf( info, sizeof info, "???" );
1558 if( struct_len <= 0 )
1560 proto_item_prepend_text( info_item, "Missing " );
1561 expert_add_info_format( pinfo, info_item, KIP_ERROR, "Expected: min 2 bytes" );
1562 //ok = 0;
1564 else
1566 proto_tree* info_tree = proto_item_add_subtree( info_item, ett_loss );
1567 proto_item* length_item = knxip_tree_add_length( info_tree, tvb, offset, struct_len );
1568 uint8_t length_ok = 1;
1570 int end_pos = offset + eff_struct_len;
1571 offset++;
1573 if( struct_len > remaining_len )
1575 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
1576 //ok = 0;
1577 length_ok = 0;
1578 struct_len = (uint8_t) remaining_len;
1581 if( struct_len < 2 )
1583 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: min 2 bytes" );
1584 //ok = 0;
1585 length_ok = 0;
1587 else
1589 /* 1 byte Selection Type */
1590 uint8_t sel = tvb_get_uint8( tvb, offset );
1591 proto_item* type_item = proto_tree_add_item( info_tree, hf_knxip_selector, tvb, offset, 1, ENC_BIG_ENDIAN );
1592 proto_item_append_text( type_item, " = %s", (sel == SELECT_PROGMODE) ? "ProgMode" : (sel == SELECT_MACADDRESS) ? "MAC" : "Unknown" );
1593 offset++;
1594 ok = 1;
1596 if( sel == SELECT_PROGMODE )
1598 snprintf( info, sizeof info, "ProgMode" );
1600 if( struct_len != 2 )
1602 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 2 bytes" );
1603 ok = 0;
1604 length_ok = 0;
1607 else if( sel == SELECT_MACADDRESS )
1609 char* output = info;
1610 int output_max = sizeof info;
1611 snprintf( output, output_max, "MAC=" );
1612 while( *output ) { ++output; --output_max; }
1613 snprintf( output, output_max, "???" );
1615 if( struct_len != 8 )
1617 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 8 bytes" );
1618 ok = 0;
1619 length_ok = 0;
1622 if( struct_len >= 8 )
1624 /* 6 bytes MAC Address */
1625 uint8_t mac[ 6 ];
1626 tvb_memcpy( tvb, mac, offset, 6 );
1627 snprintf( output, output_max, "%02x:%02x:%02x:%02x:%02x:%02x", mac[ 0 ], mac[ 1 ], mac[ 2 ], mac[ 3 ], mac[ 4 ], mac[ 5 ] );
1628 proto_tree_add_item( info_tree, hf_knxip_mac_address, tvb, offset, 6, ENC_NA );
1629 offset += 6;
1632 else
1634 proto_item_prepend_text( type_item, "? " );
1635 expert_add_info_format( pinfo, type_item, KIP_ERROR, "Unknown" );
1636 ok = 0;
1639 if( offset < end_pos )
1641 knxip_tree_add_unknown_data( info_tree, tvb, offset, end_pos - offset );
1642 ok = 0;
1645 proto_item_append_text( info_item, ": %s", info );
1648 if( !length_ok )
1650 proto_item_prepend_text( length_item, "? " );
1654 if( pinfo ) col_append_fstr( pinfo->cinfo, COL_INFO, " %s", info );
1655 proto_item_append_text( item, ", %s", info );
1657 if( !ok )
1659 proto_item_prepend_text( info_item, "? " );
1660 if( p_ok ) *p_ok = 0;
1663 *p_offset += struct_len;
1664 if( p_ok && !ok ) *p_ok = 0;
1665 return struct_len;
1668 /* Dissect DevInfo DIB
1670 static uint8_t dissect_dib_devinfo( tvbuff_t* tvb, packet_info* pinfo,
1671 proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
1672 int* p_offset, uint8_t struct_len, wmem_strbuf_t* output )
1674 int offset = *p_offset;
1675 wmem_strbuf_t* info = wmem_strbuf_new(pinfo->pool, "");
1676 uint8_t prog_mode = 0;
1677 uint8_t ok = 1;
1679 if( struct_len != 54 )
1681 if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: 54 bytes" );
1682 ok = 0;
1685 if( struct_len >= 3 )
1687 /* 1 byte KNX Medium */
1688 uint8_t knx_medium = tvb_get_uint8( tvb, offset );
1689 proto_item* item = proto_tree_add_item( dib_tree, hf_knxip_knx_medium, tvb, offset, 1, ENC_BIG_ENDIAN );
1690 proto_tree* tree = proto_item_add_subtree( item, ett_medium );
1691 knxip_tree_add_bit( tree, tvb, offset, 5, "IP", NULL, 0 );
1692 knxip_tree_add_bit( tree, tvb, offset, 4, "RF", NULL, 0 );
1693 knxip_tree_add_bit( tree, tvb, offset, 3, "PL132", NULL, 0 );
1694 knxip_tree_add_bit( tree, tvb, offset, 2, "PL110", NULL, 0 );
1695 knxip_tree_add_bit( tree, tvb, offset, 1, "TP1", NULL, 0 );
1696 knxip_tree_add_bit( tree, tvb, offset, 0, "TP0", NULL, 0 );
1698 /* Check for missing or multiple medium */
1700 uint8_t data = knx_medium;
1701 uint8_t media = 0;
1702 while( data )
1704 if( data & 1 )
1706 media++;
1708 data >>= 1;
1711 if( media != 1 )
1713 expert_add_info_format( pinfo, item, KIP_WARNING, media ? "Multiple" : "Missing" );
1717 offset++;
1719 if( struct_len >= 4 )
1721 /* 1 byte Device Status */
1722 uint8_t status = tvb_get_uint8( tvb, offset );
1723 item = proto_tree_add_item( dib_tree, hf_knxip_device_status, tvb, offset, 1, ENC_BIG_ENDIAN );
1724 tree = proto_item_add_subtree( item, ett_status );
1725 proto_tree_add_item( tree, hf_knxip_program_mode, tvb, offset, 1, ENC_BIG_ENDIAN );
1727 if( status & 0x01 )
1729 proto_item_append_text( item, " (ProgMode)" );
1730 prog_mode = 1;
1733 offset++;
1735 if( struct_len >= 6 )
1737 /* 2 bytes KNX Address */
1738 char addr[ 32 ];
1739 knxip_tree_add_knx_address( dib_tree, hf_knxip_knx_address, tvb, offset, addr, sizeof addr );
1740 wmem_strbuf_append( info, addr );
1742 offset += 2;
1744 if( struct_len >= 8 )
1746 /* 2 bytes Project Installation Identifier */
1747 uint16_t project_id = tvb_get_ntohs( tvb, offset );
1748 item = proto_tree_add_item( dib_tree, hf_knxip_project_id, tvb, offset, 2, ENC_BIG_ENDIAN );
1749 tree = proto_item_add_subtree( item, ett_projectid );
1750 proto_tree_add_item( tree, hf_knxip_project_number, tvb, offset, 2, ENC_BIG_ENDIAN );
1751 proto_tree_add_item( tree, hf_knxip_installation_number, tvb, offset, 2, ENC_BIG_ENDIAN );
1752 proto_item_append_text( item, " (%u:%u)", project_id / 16, project_id % 16 );
1754 offset += 2;
1756 if( struct_len >= 14 )
1758 /* 6 bytes KNX Serial Number */
1759 proto_tree_add_item( dib_tree, hf_knxip_serial_number, tvb, offset, 6, ENC_BIG_ENDIAN );
1760 offset += 6;
1763 if( struct_len >= 18 )
1765 /* 4 bytes Routing Multicast Address */
1766 proto_tree_add_item( dib_tree, hf_knxip_multicast_address, tvb, offset, 4, ENC_BIG_ENDIAN );
1767 offset += 4;
1769 if( struct_len >= 24 )
1771 /* 6 bytes MAC Address */
1772 proto_tree_add_item( dib_tree, hf_knxip_mac_address, tvb, offset, 6, ENC_NA );
1773 offset += 6;
1775 if( struct_len >= 54 )
1777 /* 30 bytes Friendly Name - ISO 8859-1 */
1778 char *friendly_name;
1780 proto_tree_add_item_ret_display_string( dib_tree, hf_knxip_friendly_name, tvb, offset, 30, ENC_ISO_8859_1 | ENC_NA, pinfo->pool, &friendly_name );
1782 wmem_strbuf_append_printf( info, " \"%s\"", friendly_name );
1784 offset += 30;
1793 if( wmem_strbuf_get_len( info ) == 0 )
1795 wmem_strbuf_append( info, "???" );
1797 if( prog_mode )
1799 wmem_strbuf_append( info, " PROGMODE" );
1801 if( output )
1803 wmem_strbuf_append( output, wmem_strbuf_get_str( info ) );
1805 proto_item_append_text( dib_item, ": %s", wmem_strbuf_get_str( info ) );
1807 *p_offset = offset;
1808 return ok;
1811 /* Dissect SuppSvc DIB
1813 static uint8_t dissect_dib_suppsvc( tvbuff_t* tvb, packet_info* pinfo,
1814 proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
1815 int* p_offset, uint8_t struct_len )
1817 int offset = *p_offset;
1818 int end_pos = offset - 2 + struct_len;
1819 uint8_t ok = 1;
1820 char separator = ':';
1821 uint8_t sf_count[ 8 ] = { 0 };
1823 if( struct_len & 1 )
1825 if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: even number" );
1826 ok = 0;
1829 while( offset + 2 <= end_pos )
1831 uint8_t service_family = tvb_get_uint8( tvb, offset );
1832 uint8_t version = tvb_get_uint8( tvb, offset + 1 );
1833 const char* service_family_name = try_val_to_str( service_family, knxip_service_family_vals );
1834 proto_item* item = proto_tree_add_none_format( dib_tree, hf_folder, tvb, offset, 2, "KNXnet/IP %s v%u",
1835 service_family_name ? service_family_name : "Unknown Service Family", version );
1836 proto_tree* tree = proto_item_add_subtree( item, ett_service_family );
1838 /* 1 byte Service Family ID */
1839 proto_tree_add_item( tree, hf_knxip_service_family, tvb, offset, 1, ENC_BIG_ENDIAN );
1841 /* 1 byte Service Family Version */
1842 proto_tree_add_item( tree, hf_knxip_service_version, tvb, offset + 1, 1, ENC_BIG_ENDIAN );
1844 if( service_family >= KIP_SERVICE_TUNNELING && service_family_name )
1846 proto_item_append_text( dib_item, "%c %s", separator, service_family_name );
1847 separator = ',';
1850 if( service_family < 8 )
1852 ++sf_count[ service_family ];
1855 offset += 2;
1858 if( !sf_count[ KIP_SERVICE_CORE ] )
1860 expert_add_info_format( pinfo, dib_item, KIP_WARNING, "Missing: Core (0x02)" );
1862 if( !sf_count[ KIP_SERVICE_MANAGEMENT ] )
1864 expert_add_info_format( pinfo, dib_item, KIP_WARNING, "Missing: Device Management (0x03)" );
1867 *p_offset = offset;
1868 return ok;
1871 /* Dissect IpConfig DIB
1873 static uint8_t dissect_dib_ipconfig( tvbuff_t* tvb, packet_info* pinfo,
1874 proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
1875 int* p_offset, uint8_t struct_len )
1877 int offset = *p_offset;
1878 uint8_t ok = 1;
1879 char text[ 32 ];
1881 if( struct_len != 16 )
1883 if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: 16 bytes" );
1884 ok = 0;
1887 if( struct_len < 6 )
1889 snprintf( text, sizeof text, "???" );
1891 else
1893 /* 4 bytes IP Address */
1894 knxip_tree_add_ip_address( dib_tree, tvb, offset, text, sizeof text );
1895 offset += 4;
1897 if( struct_len >= 10 )
1899 /* 4 bytes Subnet Mask */
1900 proto_tree_add_item( dib_tree, hf_knxip_ip_subnet, tvb, offset, 4, ENC_BIG_ENDIAN );
1901 offset += 4;
1903 if( struct_len >= 14 )
1905 /* 4 bytes Default Gateway */
1906 proto_tree_add_item( dib_tree, hf_knxip_ip_gateway, tvb, offset, 4, ENC_BIG_ENDIAN );
1907 offset += 4;
1909 if( struct_len >= 15 )
1911 /* 1 byte IP Capabilities */
1912 knxip_tree_add_ip_assignment( dib_tree, hf_knxip_ip_caps, tvb, offset, 0 );
1913 offset++;
1915 if( struct_len >= 16 )
1917 /* 1 byte IP Assignment Method */
1918 knxip_tree_add_ip_assignment( dib_tree, hf_knxip_ip_assign, tvb, offset, 1 );
1919 offset++;
1926 proto_item_append_text( dib_item, ": %s", text );
1928 *p_offset = offset;
1929 return ok;
1932 /* Dissect CurConfig DIB
1934 static uint8_t dissect_dib_curconfig( tvbuff_t* tvb, packet_info* pinfo,
1935 proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
1936 int* p_offset, uint8_t struct_len )
1938 int offset = *p_offset;
1939 uint8_t ok = 1;
1940 char text[ 32 ];
1942 if( struct_len != 20 )
1944 if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: 20 bytes" );
1945 ok = 0;
1948 if( struct_len < 6 )
1950 snprintf( text, sizeof text, "???" );
1952 else
1954 /* 4 bytes IP Address */
1955 knxip_tree_add_ip_address( dib_tree, tvb, offset, text, sizeof text );
1956 offset += 4;
1958 if( struct_len >= 10 )
1960 /* 4 bytes Subnet Mask */
1961 proto_tree_add_item( dib_tree, hf_knxip_ip_subnet, tvb, offset, 4, ENC_BIG_ENDIAN );
1962 offset += 4;
1964 if( struct_len >= 14 )
1966 /* 4 bytes Default Gateway */
1967 proto_tree_add_item( dib_tree, hf_knxip_ip_gateway, tvb, offset, 4, ENC_BIG_ENDIAN );
1968 offset += 4;
1970 if( struct_len >= 18 )
1972 /* 4 bytes DHCP Server */
1973 proto_tree_add_item( dib_tree, hf_knxip_ip_dhcp, tvb, offset, 4, ENC_BIG_ENDIAN );
1974 offset += 4;
1976 if( struct_len >= 19 )
1978 /* IP Assignment Method */
1979 knxip_tree_add_ip_assignment( dib_tree, hf_knxip_ip_assign, tvb, offset, 1 );
1980 offset++;
1982 if( struct_len >= 20 )
1984 /* Reserved Byte */
1985 knxip_tree_add_reserved( dib_tree, tvb, offset, pinfo, &ok );
1986 offset++;
1994 proto_item_append_text( dib_item, ": %s", text );
1996 *p_offset = offset;
1997 return ok;
2000 /* Dissect KnxAddr DIB
2002 static uint8_t dissect_dib_knxaddr( tvbuff_t* tvb, packet_info* pinfo,
2003 proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
2004 int* p_offset, uint8_t struct_len )
2006 int offset = *p_offset;
2007 uint8_t ok = 1;
2008 char text1[ 32 ];
2009 char text2[ 32 ];
2011 if( struct_len < 4 )
2013 if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: >= 4 bytes" );
2014 snprintf( text1, sizeof text1, "???" );
2015 ok = 0;
2017 else
2019 int end_pos = offset - 2 + struct_len;
2021 if( struct_len & 1 )
2023 if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: even number" );
2024 ok = 0;
2027 /* 2 bytes KNX Address */
2028 knxip_tree_add_knx_address( dib_tree, hf_knxip_knx_address, tvb, offset, text1, sizeof text1 );
2029 proto_item_append_text( dib_item, ": %s", text1 );
2030 offset += 2;
2032 while( offset + 2 <= end_pos )
2034 /* 2 bytes Additional KNX Address */
2035 knxip_tree_add_knx_address( dib_tree, hf_knxip_knx_address, tvb, offset, text2, sizeof text2 );
2036 proto_item_append_text( dib_item, ", %s", text2 );
2037 offset += 2;
2041 *p_offset = offset;
2042 return ok;
2045 /* Dissect SecuredServices DIB
2047 static uint8_t dissect_dib_secured_service_families( tvbuff_t* tvb, packet_info* pinfo,
2048 proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
2049 int* p_offset, uint8_t struct_len )
2051 int offset = *p_offset;
2052 int end_pos = offset - 2 + struct_len;
2053 uint8_t ok = 1;
2054 char separator = ':';
2056 if( struct_len & 1 )
2058 if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: even number" );
2059 ok = 0;
2062 while( offset + 2 <= end_pos )
2064 uint8_t service_family = tvb_get_uint8( tvb, offset );
2065 uint8_t version = tvb_get_uint8( tvb, offset + 1 );
2066 const char* service_family_name = try_val_to_str( service_family, knxip_service_family_vals );
2067 proto_item* item = proto_tree_add_none_format( dib_tree, hf_folder, tvb, offset, 2, "KNXnet/IP %s v%u",
2068 service_family_name ? service_family_name : "Unknown Service Family", version );
2069 proto_tree* tree = proto_item_add_subtree( item, ett_service_family );
2071 /* 1 byte Service Family ID */
2072 proto_tree_add_item( tree, hf_knxip_service_family, tvb, offset, 1, ENC_BIG_ENDIAN );
2074 /* 1 byte Security Version */
2075 proto_tree_add_item( tree, hf_knxip_security_version, tvb, offset + 1, 1, ENC_BIG_ENDIAN );
2077 if( service_family_name )
2079 proto_item_append_text( dib_item, "%c %s", separator, service_family_name );
2080 separator = ',';
2083 offset += 2;
2086 *p_offset = offset;
2087 return ok;
2090 /* Dissect TunnelingInfo DIB
2092 static uint8_t dissect_dib_tunneling_info( tvbuff_t* tvb, packet_info* pinfo,
2093 proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
2094 int* p_offset, uint8_t struct_len )
2096 int offset = *p_offset;
2097 uint8_t ok = 1;
2099 if( struct_len < 4 )
2101 if( length_ok )
2103 knxip_item_illegal_length( length_item, pinfo, "Expected: >= 4 bytes" );
2104 ok = 0;
2107 else
2109 int end_pos = offset - 2 + struct_len;
2110 char separator = ':';
2112 /* 2 bytes Max APDU Length */
2113 proto_tree_add_item( dib_tree, hf_knxip_max_apdu_length, tvb, offset, 2, ENC_BIG_ENDIAN );
2114 offset += 2;
2116 if( struct_len & 3 )
2118 if( length_ok )
2120 knxip_item_illegal_length( length_item, pinfo, "Expected: 4 + n * 4 bytes" );
2121 ok = 0;
2125 while( offset + 4 <= end_pos )
2127 uint8_t flags = tvb_get_uint8( tvb, offset + 3 );
2128 uint8_t is_free = flags & 1;
2129 char text[ 32 ];
2130 proto_item* node;
2131 proto_tree* list;
2133 node = proto_tree_add_none_format( dib_tree, hf_folder, tvb, offset, 4, "Tunneling Slot" );
2134 list = proto_item_add_subtree( node, ett_tunnel );
2136 /* 2 bytes KNX Address, 1 byte reserved */
2137 knxip_tree_add_knx_address( list, hf_knxip_knx_address, tvb, offset, text, sizeof text );
2138 proto_item_append_text( node, ": %s Free=%u", text, is_free );
2139 offset += 3;
2141 /* 1 byte flags */
2142 knxip_tree_add_bit( list, tvb, offset, 2, "Usable", NULL, 0 );
2143 knxip_tree_add_bit( list, tvb, offset, 1, "Authorized", NULL, 0 );
2144 knxip_tree_add_bit( list, tvb, offset, 0, "Free", NULL, 0 );
2145 offset++;
2147 if( !is_free )
2149 proto_item_append_text( dib_item, "%c %s", separator, text );
2150 separator = ',';
2155 *p_offset = offset;
2156 return ok;
2159 /* Dissect ExtDevInfo DIB
2161 static uint8_t dissect_dib_extdevinfo( tvbuff_t* tvb, packet_info* pinfo,
2162 proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
2163 int* p_offset, uint8_t struct_len )
2165 int offset = *p_offset;
2166 uint8_t status = 0;
2167 uint8_t ok = 1;
2169 if( struct_len != 8 )
2171 if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: 8 bytes" );
2172 ok = 0;
2175 if( struct_len >= 3 )
2177 /* 1 byte Medium Status */
2178 status = tvb_get_uint8( tvb, offset );
2179 proto_tree_add_item( dib_tree, hf_knxip_medium_status, tvb, offset, 1, ENC_BIG_ENDIAN );
2180 if( status )
2182 proto_item_append_text( dib_item, ": MediumStatus=$%02X", status );
2185 offset++;
2187 if( struct_len >= 4 )
2189 /* 1 byte reserved */
2190 knxip_tree_add_reserved( dib_tree, tvb, offset, pinfo, &ok );
2191 offset++;
2193 if( struct_len >= 6 )
2195 /* 2 bytes Max APDU Length */
2196 proto_tree_add_item( dib_tree, hf_knxip_max_apdu_length, tvb, offset, 2, ENC_BIG_ENDIAN );
2197 offset += 2;
2199 if( struct_len >= 8 )
2201 /* 2 bytes Mask Version */
2202 proto_tree_add_item( dib_tree, hf_knxip_mask_version, tvb, offset, 2, ENC_BIG_ENDIAN );
2203 offset += 2;
2209 *p_offset = offset;
2210 return ok;
2213 /* Dissect MfrData DIB
2215 static uint8_t dissect_dib_mfrdata( tvbuff_t* tvb, packet_info* pinfo,
2216 proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
2217 int* p_offset, uint8_t struct_len )
2219 int offset = *p_offset;
2220 uint8_t ok = 1;
2221 char text[ 32 ];
2223 if( struct_len < 4 )
2225 if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: >= 4 bytes" );
2226 snprintf( text, sizeof text, "???" );
2227 ok = 0;
2229 else
2231 proto_tree_add_item( dib_tree, hf_knxip_manufacturer_code, tvb, offset, 2, ENC_BIG_ENDIAN );
2232 snprintf( text, sizeof text, "0x%04x", tvb_get_ntohs( tvb, offset ) );
2233 offset += 2;
2236 proto_item_append_text( dib_item, ": %s", text );
2238 *p_offset = offset;
2239 return ok;
2242 /* Dissect DIB
2244 static uint8_t dissect_dib( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree,
2245 int* p_offset, wmem_strbuf_t* output, char separator, uint8_t* p_count, uint8_t* p_ok )
2247 int offset = *p_offset;
2248 int remaining_len = tvb_captured_length_remaining( tvb, offset );
2249 uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
2250 if( struct_len > 0 )
2252 int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
2253 int end_pos = offset + eff_struct_len;
2254 const char* dib_name = NULL;
2255 uint8_t dib_type = 0;
2256 uint8_t ok = 1;
2257 uint8_t length_ok = 1;
2259 proto_item* dib_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "DIB" );
2260 proto_tree* dib_tree = proto_item_add_subtree( dib_item, ett_dib );
2261 proto_item* length_item = knxip_tree_add_length( dib_tree, tvb, offset, struct_len );
2263 offset++;
2265 if( struct_len > remaining_len )
2267 proto_item_prepend_text( length_item, "? " );
2268 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
2269 struct_len = (uint8_t) remaining_len;
2270 ok = 0;
2271 length_ok = 0;
2274 if( eff_struct_len < 2 )
2276 expert_add_info_format( pinfo, dib_item, KIP_ERROR, "Missing 1 byte Description Type" );
2277 ok = 0;
2279 else
2281 proto_item* type_item = proto_tree_add_item( dib_tree, hf_knxip_description_type, tvb, offset, 1, ENC_BIG_ENDIAN );
2283 dib_type = tvb_get_uint8( tvb, offset );
2284 dib_name = try_val_to_str( dib_type, descr_type_vals );
2285 offset++;
2287 if( !dib_name )
2289 proto_item_append_text( dib_item, " ???" );
2290 proto_item_append_text( type_item, " (Unknown)" );
2292 else
2294 proto_item_append_text( dib_item, " %s", dib_name );
2297 if( p_count )
2299 ++p_count[ dib_type ];
2302 switch( dib_type )
2304 case KIP_DIB_DEVICE_INFO:
2305 ok &= dissect_dib_devinfo( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len, output );
2306 break;
2308 case KIP_DIB_SUPP_SVC_FAMILIES:
2309 ok &= dissect_dib_suppsvc( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2310 break;
2312 case KIP_DIB_IP_CONFIG:
2313 ok &= dissect_dib_ipconfig( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2314 break;
2316 case KIP_DIB_CUR_CONFIG:
2317 ok &= dissect_dib_curconfig( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2318 break;
2320 case KIP_DIB_KNX_ADDRESSES:
2321 ok &= dissect_dib_knxaddr( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2322 break;
2324 case KIP_DIB_SECURED_SERVICE_FAMILIES:
2325 ok &= dissect_dib_secured_service_families( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2326 break;
2328 case KIP_DIB_TUNNELING_INFO:
2329 ok &= dissect_dib_tunneling_info( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2330 break;
2332 case KIP_DIB_EXTENDED_DEVICE_INFO:
2333 ok &= dissect_dib_extdevinfo( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2334 break;
2336 case KIP_DIB_MFR_DATA:
2337 ok &= dissect_dib_mfrdata( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2338 break;
2340 default:
2341 expert_add_info_format( pinfo, type_item, KIP_WARNING, "Unknown DIB Type" );
2342 break;
2345 if( offset < end_pos )
2347 knxip_tree_add_unknown_data( dib_tree, tvb, offset, end_pos - offset );
2348 offset = end_pos;
2352 if( !output )
2354 if( pinfo )
2356 column_info* cinfo = pinfo->cinfo;
2357 col_append_fstr( cinfo, COL_INFO, "%c ", separator );
2359 if( !dib_name )
2361 col_append_str( cinfo, COL_INFO, "???" );
2363 else
2365 if( !ok ) col_append_str( cinfo, COL_INFO, "? " );
2366 col_append_str( cinfo, COL_INFO, dib_name );
2370 if( item )
2372 proto_item_append_text( item, "%c ", separator );
2374 if( !dib_name )
2376 proto_item_append_text( item, "???" );
2378 else
2380 if( !ok ) proto_item_append_text( item, "? " );
2381 proto_item_append_text( item, "%s", dib_name );
2386 if( !ok )
2388 proto_item_prepend_text( dib_item, "? " );
2389 if( p_ok ) *p_ok = 0;
2392 *p_offset = offset;
2395 return struct_len;
2398 /* Dissect sequence of DIBs
2400 static char dissect_dibs( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset, wmem_strbuf_t* output, char separator, uint8_t* p_count, uint8_t* p_ok )
2402 while( dissect_dib( tvb, pinfo, item, tree, p_offset, output, separator, p_count, p_ok ) )
2404 separator = ',';
2407 return separator;
2410 /* Dissect SRP
2412 static uint8_t dissect_srp( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset, uint8_t* p_ok )
2414 int offset = *p_offset;
2415 int remaining_len = tvb_captured_length_remaining( tvb, offset );
2416 uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
2417 if( struct_len > 0 )
2419 int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
2420 int end_pos = offset + eff_struct_len;
2421 column_info* cinfo = pinfo ? pinfo->cinfo : NULL;
2422 proto_item* srp_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "SRP" );
2423 proto_tree* srp_tree = proto_item_add_subtree( srp_item, ett_dib );
2424 proto_item* length_item = knxip_tree_add_length( srp_tree, tvb, offset, struct_len );
2425 uint8_t ok = 1;
2426 uint8_t length_ok = 1;
2428 offset++;
2430 if( struct_len > remaining_len )
2432 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
2433 ok = 0;
2434 length_ok = 0;
2437 if( eff_struct_len < 2 )
2439 expert_add_info_format( pinfo, srp_item, KIP_ERROR, "Missing 1 byte SRP Type" );
2440 ok = 0;
2442 else
2444 /* 1 bit Mandatory */
2445 proto_tree_add_item( srp_tree, hf_knxip_srp_mandatory, tvb, offset, 1, ENC_BIG_ENDIAN );
2447 /* 7 bits SRP Type */
2448 uint8_t srp_type = tvb_get_uint8( tvb, offset ) & 0x7F;
2449 const char* srp_name = try_val_to_str( srp_type, srp_type_vals );
2450 proto_item* type_item = proto_tree_add_item( srp_tree, hf_knxip_srp_type, tvb, offset, 1, ENC_BIG_ENDIAN );
2451 uint8_t expected_len = 0;
2452 uint8_t unknown = !srp_name;
2453 if( unknown )
2455 expert_add_info_format( pinfo, type_item, KIP_WARNING, "Unknown SRP Type" );
2456 srp_name = "???";
2459 proto_item_append_text( srp_item, " %s", srp_name ? srp_name : "???" );
2460 proto_item_append_text( type_item, " = %s", srp_name ? srp_name : "???" );
2462 if( !unknown )
2464 col_append_fstr( cinfo, COL_INFO, " %s", srp_name );
2465 proto_item_append_text( item, ", %s", srp_name );
2468 switch( srp_type )
2470 case 1:
2471 expected_len = 2;
2472 break;
2473 case 2:
2474 expected_len = 8;
2475 break;
2476 case 3:
2477 expected_len = 4;
2478 break;
2481 if( expected_len )
2483 if( struct_len != expected_len )
2485 expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: %u bytes", expected_len );
2486 ok = 0;
2487 length_ok = 0;
2490 offset++;
2492 if( offset < end_pos )
2494 knxip_tree_add_data( srp_tree, tvb, offset, end_pos - offset, srp_name ? cinfo : NULL, item, "Data", "=$", " = $" );
2496 proto_item_append_text( srp_item, ": $" );
2497 while( offset < end_pos )
2499 proto_item_append_text( srp_item, " %02X", tvb_get_uint8( tvb, offset ) );
2500 ++offset;
2503 //offset = end_pos;
2507 if( !ok )
2509 proto_item_prepend_text( srp_item, "? " );
2510 if( p_ok ) *p_ok = 0;
2513 if( !length_ok )
2515 proto_item_prepend_text( length_item, "? " );
2518 *p_offset += struct_len;
2521 return struct_len;
2524 /* Dissect sequence of SRPs
2526 static void dissect_srps( tvbuff_t *tvb, packet_info *pinfo, proto_item *item, proto_tree *tree, int *p_offset, uint8_t* p_ok )
2528 while( dissect_srp( tvb, pinfo, item, tree, p_offset, p_ok ) );
2531 /* Dissect RESET command
2533 static uint8_t dissect_resetter( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
2535 uint8_t ok = 0;
2536 int offset = *p_offset;
2537 int remaining_len = tvb_captured_length_remaining( tvb, offset );
2538 uint8_t struct_len = ((unsigned) remaining_len < 2) ? (uint8_t) remaining_len : 2;
2539 uint8_t mode = (struct_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
2540 const char* mode_name = (mode == 0x01) ? "Restart" : (mode == 0x02) ? "Master Reset" : NULL;
2541 const char* mode_info = mode_name ? mode_name : "???";
2542 proto_item* node;
2544 if( struct_len <= 0 )
2546 proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Command, Reserved: expected 2 bytes" );
2548 else
2550 /* 1 byte Reset Command */
2551 node = proto_tree_add_item( tree, hf_knxip_reset_command, tvb, offset, 1, ENC_BIG_ENDIAN );
2552 proto_item_append_text( node, " = %s", mode_info );
2554 if( !mode_name )
2556 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 0x01 or 0x02" );
2558 else
2560 ok = 1;
2563 if( struct_len != 2 )
2565 proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Reserved: expected 1 byte" );
2566 ok = 0;
2568 else
2570 /* 1 byte Reserved */
2571 knxip_tree_add_reserved( tree, tvb, offset + 1, pinfo, &ok );
2575 if( pinfo ) col_append_fstr( pinfo->cinfo, COL_INFO, ", %s", mode_info );
2576 proto_item_append_text( item, ", %s", mode_info );
2578 *p_offset += struct_len;
2579 return ok;
2582 /* Decrypt SECURE_WRAPPER. Returns decrypted part if MAC matches
2584 static uint8_t* decrypt_secure_wrapper( const uint8_t* key, const uint8_t* data, int h_length, int p_length )
2586 uint8_t header_length = *data;
2587 int a_length = header_length + 2;
2588 if( a_length > h_length )
2590 a_length = h_length;
2593 if( h_length >= header_length + 16 && p_length >= 16 )
2595 const uint8_t* nonce = data + a_length;
2596 uint8_t* decrypted = knxip_ccm_decrypt( NULL, key, data + h_length, p_length, nonce, 14 );
2598 if( decrypted )
2600 /* Calculate MAC */
2601 uint8_t mac[ KNX_KEY_LENGTH ];
2602 p_length -= 16;
2604 knxip_ccm_calc_cbc_mac( mac, key, data, a_length, decrypted, p_length, nonce, 14 );
2606 /* Check MAC */
2607 if( memcmp( decrypted + p_length, mac, 16 ) != 0 )
2609 wmem_free( wmem_packet_scope(), decrypted );
2610 decrypted = NULL;
2614 return decrypted;
2617 return NULL;
2620 static void make_key_info( char* text, int text_max, const uint8_t* key, const char* context )
2622 uint8_t count;
2624 if( !key )
2626 snprintf( text, text_max, "without key" );
2628 else
2630 if( context )
2632 snprintf( text, text_max, "with %s key", context );
2634 else
2636 snprintf( text, text_max, "with key" );
2639 for( count = 16; count; --count )
2641 while( *text ) { ++text; --text_max; }
2642 snprintf( text, text_max, " %02X", *key++ );
2647 /* Dissect SECURE_WRAPPER
2649 // NOLINTNEXTLINE(misc-no-recursion)
2650 static uint8_t dissect_secure_wrapper( uint8_t header_length, tvbuff_t* tvb, packet_info* pinfo, proto_tree* root, proto_item* item, proto_tree* tree, int* p_offset )
2652 uint8_t ok = 1;
2653 int offset = *p_offset;
2654 int size = tvb_captured_length_remaining( tvb, offset );
2655 column_info* cinfo = pinfo->cinfo;
2656 const uint8_t* dest_addr = (pinfo->dst.type == AT_IPv4) ? (const uint8_t*) pinfo->dst.data : NULL;
2657 proto_item* node;
2659 /* 2 bytes Session ID */
2660 if( size < 2 )
2662 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Session" );
2663 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 2 bytes" );
2664 ok = 0;
2666 else
2668 uint16_t session = tvb_get_ntohs( tvb, offset );
2669 proto_tree_add_item( tree, hf_knxip_session, tvb, offset, 2, ENC_BIG_ENDIAN );
2671 if( session )
2673 col_append_fstr( cinfo, COL_INFO, " #%04X", session );
2674 proto_item_append_text( item, ", Session: $%04X", session );
2677 offset += 2;
2678 size -= 2;
2680 /* 6 bytes Sequence Nr */
2681 if( size < 6 )
2683 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Sequence Number" );
2684 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 6 bytes" );
2685 ok = 0;
2687 else
2689 knxip_tree_add_data( tree, tvb, offset, 6, cinfo, item, "Sequence Number", " $", ", Seq Nr: $" );
2690 offset += 6;
2691 size -= 6;
2693 /* 6 bytes Serial Nr */
2694 if( size < 6 )
2696 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Serial Number" );
2697 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 6 bytes" );
2698 ok = 0;
2700 else
2702 knxip_tree_add_data( tree, tvb, offset, 6, cinfo, item, "Serial Number", ".", ", Ser Nr: $" );
2703 offset += 6;
2704 size -= 6;
2706 /* 2 bytes Tag */
2707 if( size < 2 )
2709 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Tag" );
2710 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 2 bytes" );
2711 ok = 0;
2713 else
2715 uint16_t tag = tvb_get_ntohs( tvb, offset );
2716 proto_tree_add_item( tree, hf_knxip_tag, tvb, offset, 2, ENC_BIG_ENDIAN );
2717 col_append_fstr( cinfo, COL_INFO, ".%04X", tag );
2718 proto_item_append_text( item, ", Tag: $%04X", tag );
2719 offset += 2;
2720 size -= 2;
2722 /* Encrypted part */
2723 if( size < 16 )
2725 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Encrypted" );
2726 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: min 16 bytes" );
2727 ok = 0;
2729 else
2731 const uint8_t* encrypted = tvb_get_ptr( tvb, offset, size - offset );
2732 const int a_length = header_length + 16; // length of leading non-encrypted data
2733 const uint8_t* a_data = encrypted - a_length; // ptr to KIP header
2734 uint8_t* decrypted = NULL;
2735 const uint8_t* key = NULL;
2736 char decrypt_info[ 128 ];
2737 struct knx_keyring_mca_keys* mca_key;
2738 uint8_t key_index;
2740 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, encrypted, "Encrypted (%d bytes)", size );
2742 *decrypt_info = '\0';
2744 if( dest_addr )
2746 // Try keys associateD with IP MCA in keyring.XML
2747 for( mca_key = knx_keyring_mca_keys; mca_key; mca_key = mca_key->next )
2749 if( memcmp( mca_key->mca, dest_addr, 4 ) == 0 )
2751 key = mca_key->key;
2752 decrypted = decrypt_secure_wrapper( key, a_data, a_length, size );
2753 if( decrypted )
2755 make_key_info( decrypt_info, sizeof decrypt_info, key, "MCA" );
2756 break;
2762 if( !decrypted )
2764 // Try explicitly specified keys
2765 for( key_index = 0; key_index < knx_decryption_key_count; ++key_index )
2767 key = knx_decryption_keys[ key_index ];
2768 decrypted = decrypt_secure_wrapper( key, a_data, a_length, size );
2769 if( decrypted )
2771 make_key_info( decrypt_info, sizeof decrypt_info, key, NULL );
2772 break;
2777 if( !decrypted )
2779 const char* text = knx_decryption_key_count ? " (decryption failed)" : knx_keyring_mca_keys ? " (no key found)" : " (no key available)";
2780 proto_item_append_text( node, "%s", text );
2782 else
2784 tvbuff_t* tvb2 = tvb_new_child_real_data( tvb, decrypted, size, size );
2785 int size2 = size - 16;
2786 proto_item_append_text( item, ", MAC OK" );
2787 //tvb_set_free_cb( tvb2, wmem_free );
2788 add_new_data_source( pinfo, tvb2, "Decrypted" );
2790 item = proto_tree_add_none_format( root, hf_folder, tvb2, 0, size, "Decrypted" );
2791 tree = proto_item_add_subtree( item, ett_decrypted );
2793 if( *decrypt_info )
2795 proto_item_append_text( item, " (%s)", decrypt_info );
2798 /* Embedded KIP packet */
2799 knxip_tree_add_data( tree, tvb2, 0, size2, NULL, NULL, "Embedded KNXnet/IP packet", NULL, NULL );
2801 /* MAC */
2802 knxip_tree_add_data( tree, tvb2, size2, 16, NULL, NULL, "Message Authentication Code", NULL, NULL );
2804 /* Dissect embedded KIP packet */
2806 tvbuff_t* tvb3 = tvb_new_subset_length( tvb2, 0, size2 );
2807 increment_dissection_depth(pinfo);
2808 dissect_knxip( tvb3, pinfo, root, NULL );
2809 decrement_dissection_depth(pinfo);
2818 *p_offset = offset + size;
2819 return ok;
2822 /* Check encrypted MAC in TIMER_NOTIFY
2824 static uint8_t check_timer_sync_mac( const uint8_t* key, const uint8_t* data, int header_length )
2826 // Calculate and encrypt MAC
2827 const uint8_t* nonce = data + header_length;
2828 uint8_t mac[ KNX_KEY_LENGTH ];
2829 knxip_ccm_calc_cbc_mac( mac, key, data, header_length, NULL, 0, nonce, 14 );
2830 knxip_ccm_encrypt( mac, key, NULL, 0, mac, nonce, 14 );
2832 // Check MAC
2833 return (memcmp( nonce + 14, mac, 16 ) == 0);
2836 /* Dissect TIMER_NOTIFY
2838 static uint8_t dissect_timer_notify( uint8_t header_length, tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
2840 uint8_t ok = 1;
2841 int offset = *p_offset;
2842 int size = tvb_captured_length_remaining( tvb, offset );
2843 column_info* cinfo = pinfo->cinfo;
2844 const uint8_t* dest_addr = (pinfo->dst.type == AT_IPv4) ? (const uint8_t*) pinfo->dst.data : NULL;
2845 proto_item* node;
2847 /* 6 bytes Timestamp */
2848 if( size < 6 )
2850 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Timestamp" );
2851 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 6 bytes" );
2852 ok = 0;
2854 else
2856 knxip_tree_add_data( tree, tvb, offset, 6, cinfo, item, "Timestamp", " $", ", Timestamp: $" );
2857 offset += 6;
2858 size -= 6;
2860 /* 6 bytes Serial Nr */
2861 if( size < 6 )
2863 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Serial Number" );
2864 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 6 bytes" );
2865 ok = 0;
2867 else
2869 knxip_tree_add_data( tree, tvb, offset, 6, cinfo, item, "Serial Number", ".", ", Ser Nr: $" );
2870 offset += 6;
2871 size -= 6;
2873 /* 2 bytes Tag */
2874 if( size < 2 )
2876 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Tag" );
2877 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 2 bytes" );
2878 ok = 0;
2880 else
2882 uint16_t tag = tvb_get_ntohs( tvb, offset );
2883 proto_tree_add_item( tree, hf_knxip_tag, tvb, offset, 2, ENC_BIG_ENDIAN );
2884 col_append_fstr( cinfo, COL_INFO, ".%04X", tag );
2885 proto_item_append_text( item, ", Tag: $%04X", tag );
2886 offset += 2;
2887 size -= 2;
2889 /* 16 bytes MAC */
2890 if( size < 16 )
2892 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Message Authentication Code" );
2893 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 16 bytes" );
2894 ok = 0;
2896 else
2898 const int a_length = header_length + 14; // length of leading non-encrypted data
2899 const uint8_t* a_data = tvb_get_ptr( tvb, offset - a_length, a_length + 16 );
2900 const uint8_t* key = NULL;
2901 uint8_t mac_ok = 0;
2902 uint8_t mac_error = 0;
2903 char mac_info[ 128 ];
2904 struct knx_keyring_mca_keys* mca_key;
2905 uint8_t key_index;
2907 knxip_tree_add_data( tree, tvb, offset, 16, NULL, NULL, "Message Authentication Code", NULL, NULL );
2909 *mac_info = '\0';
2911 if( dest_addr )
2913 // Try keys associated with IP MCA in keyring.XML
2914 for( mca_key = knx_keyring_mca_keys; mca_key; mca_key = mca_key->next )
2916 if( memcmp( mca_key->mca, dest_addr, 4 ) == 0 )
2918 key = mca_key->key;
2919 if( check_timer_sync_mac( key, a_data, header_length ) )
2921 mac_ok = 1;
2922 make_key_info( mac_info, sizeof mac_info, key, "MCA" );
2923 break;
2929 if( !mac_ok )
2931 // Try explicitly specified keys
2932 for( key_index = 0; key_index < knx_decryption_key_count; ++key_index )
2934 key = knx_decryption_keys[ key_index ];
2935 if( check_timer_sync_mac( key, a_data, header_length ) )
2937 mac_ok = 1;
2938 make_key_info( mac_info, sizeof mac_info, key, NULL );
2939 break;
2944 if( mac_ok )
2946 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "MAC OK" );
2947 col_append_str( cinfo, COL_INFO, " OK" );
2948 proto_item_append_text( item, ", MAC OK" );
2950 if( *mac_info )
2952 proto_item_append_text( node, " (%s)", mac_info );
2955 /* TODO: mac_error is never being set... */
2956 if( mac_error )
2958 expert_add_info_format( pinfo, node, KIP_WARNING, "OK with wrong key" );
2959 col_append_str( cinfo, COL_INFO, " (!)" );
2960 proto_item_append_text( item, " (!)" );
2964 offset += 16;
2965 size = 0;
2971 *p_offset = offset + size;
2972 return ok;
2975 /* Dissect SESSION_REQUEST
2977 static uint8_t dissect_session_request( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
2979 uint8_t ok = 1;
2980 int offset = *p_offset;
2982 /* Control Endpoint HPAI */
2983 if( dissect_hpai( tvb, pinfo, item, tree, &offset, &ok, "Control", 1 ) )
2985 int size = tvb_captured_length_remaining( tvb, offset );
2986 proto_item* node;
2988 /* DH Client Public Value */
2989 if( size <= 0 )
2991 proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? DH Client Public Value: missing" );
2992 ok = 0;
2994 else
2996 node = knxip_tree_add_data( tree, tvb, offset, size, NULL, NULL, "DH Client Public Value", NULL, NULL );
2998 #if ECDH_PUBLIC_VALUE_SIZE > 0
2999 if( size != ECDH_PUBLIC_VALUE_SIZE )
3001 proto_item_prepend_text( node, "? " );
3002 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: %u bytes", ECDH_PUBLIC_VALUE_SIZE );
3003 ok = 0;
3005 #endif
3007 offset += size;
3011 *p_offset = offset;
3012 return ok;
3015 /* Dissect SESSION_RESPONSE
3017 static uint8_t dissect_session_response( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
3019 uint8_t ok = 1;
3020 int offset = *p_offset;
3021 column_info* cinfo = pinfo->cinfo;
3022 int size = tvb_captured_length_remaining( tvb, offset );
3023 proto_item *node;
3025 /* 2 bytes Session ID */
3026 if( size < 2 )
3028 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Session" );
3029 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 2 bytes" );
3030 offset += size;
3031 ok = 0;
3033 else
3035 uint16_t session = tvb_get_ntohs( tvb, offset );
3036 col_append_fstr( cinfo, COL_INFO, " #%04X", session );
3037 proto_item_append_text( item, " #%04X", session );
3038 proto_tree_add_item( tree, hf_knxip_session, tvb, offset, 2, ENC_BIG_ENDIAN );
3039 offset += 2;
3040 size -= 2;
3042 /* DH Server Public Value */
3044 int size2 = size - 16;
3045 if( size2 < 0 )
3047 size2 = 0;
3050 node = knxip_tree_add_data( tree, tvb, offset, size2, NULL, NULL, "DH Server Public Value", NULL, NULL );
3052 if( size2 != ECDH_PUBLIC_VALUE_SIZE )
3054 proto_item_prepend_text( node, "? " );
3055 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: %u bytes", ECDH_PUBLIC_VALUE_SIZE );
3056 ok = 0;
3059 offset += size2;
3060 size -= size2;
3063 /* 16 bytes MAC */
3064 if( size < 16 )
3066 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Message Authentication Code" );
3067 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 16 bytes" );
3068 offset += size;
3069 ok = 0;
3071 else
3073 knxip_tree_add_data( tree, tvb, offset, 16, NULL, NULL, "Message Authentication Code", NULL, NULL );
3074 offset += 16;
3078 *p_offset = offset;
3079 return ok;
3082 /* Dissect SESSION_AUTHENTICATE
3084 static uint8_t dissect_session_auth( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
3086 uint8_t ok = 1;
3087 int offset = *p_offset;
3088 column_info* cinfo = pinfo->cinfo;
3089 int size = tvb_captured_length_remaining( tvb, offset );
3090 proto_item* node;
3092 /* 1 byte Reserved */
3093 if( size <= 0 )
3095 proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Reserved: expected 1 byte" );
3096 ok = 0;
3098 else
3100 knxip_tree_add_reserved( tree, tvb, offset, pinfo, &ok );
3101 ++offset;
3102 --size;
3104 /* 1 byte User ID */
3105 if( size <= 0 )
3107 proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? User: expected 1 byte" );
3108 ok = 0;
3110 else
3112 uint8_t user_id = tvb_get_uint8( tvb, offset );
3113 col_append_fstr( cinfo, COL_INFO, " User=%u", user_id );
3114 proto_item_append_text( item, ", User = %u", user_id );
3115 proto_tree_add_item( tree, hf_knxip_user, tvb, offset, 1, ENC_BIG_ENDIAN );
3116 ++offset;
3117 --size;
3119 /* 16 bytes MAC */
3120 if( size < 16 )
3122 node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Message Authentication Code" );
3123 expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 16 bytes" );
3124 offset += size;
3125 ok = 0;
3127 else
3129 knxip_tree_add_data( tree, tvb, offset, 16, NULL, NULL, "Message Authentication Code", NULL, NULL );
3130 offset += 16;
3135 *p_offset = offset;
3136 return ok;
3139 /* Dissect SESSION_STATUS
3141 static uint8_t dissect_session_status( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
3143 uint8_t ok = 1;
3144 int offset = *p_offset;
3145 column_info* cinfo = pinfo->cinfo;
3146 int size = tvb_captured_length_remaining( tvb, offset );
3148 /* 1 byte Status */
3149 if( size <= 0 )
3151 proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Status: expected 1 byte" );
3152 ok = 0;
3154 else
3156 uint8_t status = tvb_get_uint8( tvb, offset );
3157 col_append_fstr( cinfo, COL_INFO, " %u", status );
3158 proto_item_append_text( item, ": %u", status );
3159 proto_tree_add_item( tree, hf_knxip_session_status, tvb, offset, 1, ENC_BIG_ENDIAN );
3160 ++offset;
3161 --size;
3163 /* 1 byte Reserved */
3164 if( size <= 0 )
3166 proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Reserved: expected 1 byte" );
3167 ok = 0;
3169 else
3171 knxip_tree_add_reserved( tree, tvb, offset, pinfo, &ok );
3172 ++offset;
3173 --size;
3177 *p_offset = offset;
3178 return ok;
3181 /* Dissect KNX-IP data after KNX-IP header
3183 // NOLINTNEXTLINE(misc-no-recursion)
3184 static void dissect_knxip_data( uint8_t header_length, uint8_t protocol_version _U_, uint16_t service, tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, proto_item* kip_item, proto_tree* kip_tree )
3186 uint8_t ok = 1;
3187 uint8_t service_family = (service >> 8);
3188 const char* service_family_name = try_val_to_str( service_family, knxip_service_family_vals );
3189 const char* service_name = try_val_to_str( service, knxip_service_type_vals );
3190 const char* svc_name = try_val_to_str( service, svc_vals );
3191 int offset = header_length;
3192 int remaining_len = tvb_captured_length_remaining( tvb, offset );
3193 column_info* cinfo = pinfo->cinfo;
3195 /* Make sure that we cope with a well known service family
3197 if( service_family_name == NULL )
3199 col_set_str( cinfo, COL_INFO, "Unknown Service Family" );
3200 proto_item_append_text( kip_item, " Unknown Service Family" );
3201 ok = 0;
3203 else
3205 /* Make sure that we cope with a well known service type
3207 if( service_name == NULL )
3209 col_append_fstr( cinfo, COL_INFO, "%s: ? Unknown Service Type", service_family_name );
3210 proto_item_append_text( kip_item, " Unknown Service Type" );
3211 ok = 0;
3213 else
3215 col_append_str( cinfo, COL_INFO, svc_name ? svc_name : service_name );
3216 proto_item_append_text( kip_item, " %s", service_name );
3218 /* Dissect according to Service Type
3220 switch( service )
3223 /* CORE */
3225 case KIP_SEARCH_REQUEST:
3227 /* Discovery Endpoint HPAI */
3228 dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Discovery", 1 );
3230 break;
3232 case KIP_SEARCH_REQUEST_EXT:
3234 /* Discovery Endpoint HPAI */
3235 if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Discovery", 0 ) )
3237 /* Search Request Parameters */
3238 dissect_srps( tvb, pinfo, kip_item, kip_tree, &offset, &ok );
3241 break;
3243 case KIP_SEARCH_RESPONSE:
3244 case KIP_SEARCH_RESPONSE_EXT:
3246 /* Control Endpoint HPAI */
3247 if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Control", 0 ) )
3249 /* DIBs */
3250 uint8_t dib_count[ 256 ] = { 0 };
3251 wmem_strbuf_t* output;
3252 char *info;
3254 output = wmem_strbuf_new(pinfo->pool, "");
3255 dissect_dibs( tvb, pinfo, kip_item, kip_tree, &offset, output, '\0', dib_count, &ok );
3256 info = wmem_strbuf_finalize(output);
3257 if( *info )
3259 col_append_fstr( cinfo, COL_INFO, ", %s", info );
3260 proto_item_append_text( kip_item, ", %s", info );
3263 if( service == KIP_SEARCH_RESPONSE )
3265 if( !dib_count[ KIP_DIB_DEVICE_INFO ] )
3267 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB DevInfo" );
3268 ok = 0;
3270 if( !dib_count[ KIP_DIB_SUPP_SVC_FAMILIES ] )
3272 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB SuppSvc" );
3273 ok = 0;
3278 break;
3280 case KIP_DESCRIPTION_REQUEST:
3282 /* Control Endpoint HPAI */
3283 dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Control", 1 );
3285 break;
3287 case KIP_DESCRIPTION_RESPONSE:
3289 /* DIBs */
3290 uint8_t dib_count[ 256 ] = { 0 };
3291 dissect_dibs( tvb, pinfo, kip_item, kip_tree, &offset, NULL, ':', dib_count, &ok );
3292 if( !dib_count[ KIP_DIB_DEVICE_INFO ] )
3294 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB DevInfo" );
3295 ok = 0;
3297 if( !dib_count[ KIP_DIB_SUPP_SVC_FAMILIES ] )
3299 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB SuppSvc" );
3300 ok = 0;
3303 break;
3305 case KIP_CONNECT_REQUEST:
3307 /* Control Endpoint HPAI */
3308 if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Control", 1 ) )
3310 /* Data Endpoint HPAI */
3311 if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Data", 1 ) )
3313 /* CRI */
3314 dissect_cri( tvb, pinfo, kip_item, kip_tree, &offset, &ok );
3318 break;
3320 case KIP_CONNECT_RESPONSE:
3322 /* 1 byte Channel ID */
3323 if( remaining_len < 1 )
3325 col_append_str( cinfo, COL_INFO, " ???" );
3326 proto_item_append_text( kip_item, ", ???" );
3327 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Channel" );
3328 ok = 0;
3330 else
3332 uint8_t channel = tvb_get_uint8( tvb, offset );
3333 proto_tree_add_item( kip_tree, hf_knxip_channel, tvb, offset, 1, ENC_BIG_ENDIAN );
3334 offset++;
3336 /* 1 byte Status */
3337 if( remaining_len < 2 )
3339 col_append_str( cinfo, COL_INFO, " ???" );
3340 proto_item_append_text( kip_item, ", ???" );
3341 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Status" );
3342 ok = 0;
3344 else
3346 uint8_t status = tvb_get_uint8( tvb, offset );
3347 knxip_tree_add_status( kip_tree, tvb, offset );
3348 offset++;
3350 if( status == KIP_E_NO_ERROR )
3352 col_append_fstr( cinfo, COL_INFO, " #%02X", channel );
3353 proto_item_append_text( kip_item, ", Conn #%02X", channel );
3355 /* Data Endpoint HPAI */
3356 if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Data", 1 ) )
3358 /* CRD */
3359 dissect_crd( tvb, pinfo, kip_item, kip_tree, &offset, &ok );
3362 else
3364 const char* status_info = val_to_str( status, error_vals, "Error 0x%02x" );
3365 col_append_fstr( cinfo, COL_INFO, " %s", status_info );
3366 proto_item_append_text( kip_item, ": %s", status_info );
3371 break;
3373 case KIP_CONNECTIONSTATE_REQUEST:
3375 /* 1 byte Channel ID */
3376 col_append_str( cinfo, COL_INFO, " #" );
3377 proto_item_append_text( kip_item, ", Conn #" );
3379 if( remaining_len < 1 )
3381 col_append_str( cinfo, COL_INFO, "???" );
3382 proto_item_append_text( kip_item, "???" );
3383 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Channel" );
3384 ok = 0;
3386 else
3388 uint8_t channel = tvb_get_uint8( tvb, offset );
3389 col_append_fstr( cinfo, COL_INFO, "%02X", channel );
3390 proto_item_append_text( kip_item, "%02X", channel );
3391 proto_tree_add_item( kip_tree, hf_knxip_channel, tvb, offset, 1, ENC_BIG_ENDIAN );
3392 offset++;
3394 /* Reserved Byte */
3395 if( remaining_len < 2 )
3397 knxip_tree_add_missing_reserved( kip_tree, tvb, offset, pinfo );
3398 ok = 0;
3400 else
3402 knxip_tree_add_reserved( kip_tree, tvb, offset, pinfo, &ok );
3403 offset++;
3405 /* Control Endpoint HPAI */
3406 dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Control", 1 );
3410 break;
3412 case KIP_CONNECTIONSTATE_RESPONSE:
3414 /* 1 byte Channel ID */
3415 col_append_str( cinfo, COL_INFO, " #" );
3416 proto_item_append_text( kip_item, ", Conn #" );
3418 if( remaining_len < 1 )
3420 col_append_str( cinfo, COL_INFO, "???" );
3421 proto_item_append_text( kip_item, "???" );
3422 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Channel" );
3423 ok = 0;
3425 else
3427 uint8_t channel = tvb_get_uint8( tvb, offset );
3428 col_append_fstr( cinfo, COL_INFO, "%02X ", channel );
3429 proto_item_append_text( kip_item, "%02X: ", channel );
3430 proto_tree_add_item( kip_tree, hf_knxip_channel, tvb, offset, 1, ENC_BIG_ENDIAN );
3431 offset++;
3433 /* 1 byte Status */
3434 if( remaining_len < 2 )
3436 col_append_str( cinfo, COL_INFO, "???" );
3437 proto_item_append_text( kip_item, "???" );
3438 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Status" );
3439 ok = 0;
3441 else
3443 uint8_t status = tvb_get_uint8( tvb, offset );
3444 const char* status_info = val_to_str( status, error_vals, "Error 0x%02x" );
3445 col_append_str( cinfo, COL_INFO, status_info );
3446 proto_item_append_text( kip_item, "%s", status_info );
3447 knxip_tree_add_status( kip_tree, tvb, offset );
3448 offset++;
3452 break;
3454 case KIP_DISCONNECT_REQUEST:
3456 /* 1 byte Channel ID */
3457 col_append_str( cinfo, COL_INFO, " #" );
3458 proto_item_append_text( kip_item, ", Conn #" );
3460 if( remaining_len < 1 )
3462 col_append_str( cinfo, COL_INFO, "???" );
3463 proto_item_append_text( kip_item, "???" );
3464 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Channel" );
3465 ok = 0;
3467 else
3469 uint8_t channel = tvb_get_uint8( tvb, offset );
3470 col_append_fstr( cinfo, COL_INFO, "%02X", channel );
3471 proto_item_append_text( kip_item, "%02X", channel );
3472 proto_tree_add_item( kip_tree, hf_knxip_channel, tvb, offset, 1, ENC_BIG_ENDIAN );
3473 offset++;
3475 /* Reserved Byte */
3476 if( remaining_len < 2 )
3478 knxip_tree_add_missing_reserved( kip_tree, tvb, offset, pinfo );
3479 ok = 0;
3481 else
3483 knxip_tree_add_reserved( kip_tree, tvb, offset, pinfo, &ok );
3484 offset++;
3486 /* Control Endpoint HPAI */
3487 dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Control", 1 );
3491 break;
3493 case KIP_DISCONNECT_RESPONSE:
3495 /* 1 byte Channel ID */
3496 col_append_str( cinfo, COL_INFO, " #" );
3497 proto_item_append_text( kip_item, ", Conn #" );
3499 if( remaining_len < 1 )
3501 col_append_str( cinfo, COL_INFO, "???" );
3502 proto_item_append_text( kip_item, "???" );
3503 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Channel" );
3504 ok = 0;
3506 else
3508 uint8_t channel = tvb_get_uint8( tvb, offset );
3509 col_append_fstr( cinfo, COL_INFO, "%02X ", channel );
3510 proto_item_append_text( kip_item, "%02X: ", channel );
3511 proto_tree_add_item( kip_tree, hf_knxip_channel, tvb, offset, 1, ENC_BIG_ENDIAN );
3512 offset++;
3514 /* 1 byte Status */
3515 if( remaining_len < 2 )
3517 col_append_str( cinfo, COL_INFO, "???" );
3518 proto_item_append_text( kip_item, "???" );
3519 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Status" );
3520 ok = 0;
3522 else
3524 uint8_t status = tvb_get_uint8( tvb, offset );
3525 const char* status_info = val_to_str( status, error_vals, "Error 0x%02x" );
3526 col_append_str( cinfo, COL_INFO, status_info );
3527 proto_item_append_text( kip_item, "%s", status_info );
3528 knxip_tree_add_status( kip_tree, tvb, offset );
3529 offset++;
3533 break;
3535 /* MANAGEMENT */
3537 case KIP_CONFIGURATION_REQUEST:
3539 /* Connection Header */
3540 if( dissect_cnhdr( tvb, pinfo, kip_item, kip_tree, &offset, &ok, false ) )
3542 /* cEMI */
3543 dissect_cemi( tvb, pinfo, tree, &offset );
3546 break;
3548 case KIP_CONFIGURATION_ACK:
3550 /* Connection Header */
3551 dissect_cnhdr( tvb, pinfo, kip_item, kip_tree, &offset, &ok, true );
3553 break;
3555 /* TUNNELING */
3557 case KIP_TUNNELING_REQUEST:
3559 /* Connection Header */
3560 if( dissect_cnhdr( tvb, pinfo, kip_item, kip_tree, &offset, &ok, false ) )
3562 /* cEMI */
3563 dissect_cemi( tvb, pinfo, tree, &offset );
3566 break;
3568 case KIP_TUNNELING_ACK:
3570 /* Connection Header */
3571 dissect_cnhdr( tvb, pinfo, kip_item, kip_tree, &offset, &ok, true );
3573 break;
3575 case KIP_TUNNELING_FEATURE_GET:
3576 case KIP_TUNNELING_FEATURE_RESPONSE:
3577 case KIP_TUNNELING_FEATURE_SET:
3578 case KIP_TUNNELING_FEATURE_INFO:
3580 /* Connection Header, 1 byte Feature ID, 1 byte Return Code, Feature Value */
3581 dissect_tunneling_feature( tvb, pinfo, kip_item, kip_tree, &offset, &ok, service );
3583 break;
3585 /* ROUTING */
3587 case KIP_ROUTING_INDICATION:
3589 /* cEMI */
3590 dissect_cemi( tvb, pinfo, tree, &offset );
3592 break;
3594 case KIP_ROUTING_LOST_MESSAGE:
3596 /* Routing Loss */
3597 ok &= dissect_routing_loss( tvb, pinfo, kip_item, kip_tree, &offset );
3599 break;
3601 case KIP_ROUTING_BUSY:
3603 /* Routing Busy */
3604 ok &= dissect_routing_busy( tvb, pinfo, kip_item, kip_tree, &offset );
3606 break;
3608 case KIP_ROUTING_SYSTEM_BROADCAST:
3610 /* cEMI */
3611 dissect_cemi( tvb, pinfo, tree, &offset );
3613 break;
3615 /* REMOTE_DIAG_AND_CONFIG */
3617 case KIP_REMOTE_DIAG_REQUEST:
3619 /* Discovery Endpoint HPAI */
3620 if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Discovery", 0 ) )
3622 /* Selector */
3623 dissect_selector( tvb, pinfo, kip_item, kip_tree, &offset, &ok );
3626 break;
3628 case KIP_REMOTE_DIAG_RESPONSE:
3630 /* Selector */
3631 if( dissect_selector( tvb, pinfo, kip_item, kip_tree, &offset, &ok ) )
3633 /* DIBs */
3634 uint8_t dib_count[ 256 ] = { 0 };
3635 dissect_dibs( tvb, pinfo, kip_item, kip_tree, &offset, NULL, ',', dib_count, &ok );
3636 if( !dib_count[ KIP_DIB_IP_CONFIG ] )
3638 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB IpConfig" );
3639 ok = 0;
3641 if( !dib_count[ KIP_DIB_CUR_CONFIG ] )
3643 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB CurConfig" );
3644 ok = 0;
3646 if( !dib_count[ KIP_DIB_KNX_ADDRESSES ] )
3648 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB KnxAddr" );
3649 ok = 0;
3653 break;
3655 case KIP_REMOTE_CONFIG_REQUEST:
3657 /* Discovery Endpoint HPAI */
3658 if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Discovery", 0 ) )
3660 /* Selector */
3661 if( dissect_selector( tvb, pinfo, kip_item, kip_tree, &offset, &ok ) )
3663 /* DIBs */
3664 int old_offset = offset;
3665 dissect_dibs( tvb, pinfo, kip_item, kip_tree, &offset, NULL, ',', NULL, &ok );
3666 if( offset <= old_offset )
3668 expert_add_info_format( pinfo, kip_item, KIP_WARNING, "Missing DIB" );
3673 break;
3675 case KIP_REMOTE_RESET_REQUEST:
3677 /* Selector */
3678 if( dissect_selector( tvb, pinfo, kip_item, kip_tree, &offset, &ok ) )
3680 /* Reset Mode */
3681 ok &= dissect_resetter( tvb, pinfo, kip_item, kip_tree, &offset );
3684 break;
3686 case KIP_SECURE_WRAPPER:
3687 ok &= dissect_secure_wrapper( header_length, tvb, pinfo, tree, kip_item, kip_tree, &offset );
3688 break;
3690 case KIP_TIMER_NOTIFY:
3691 ok &= dissect_timer_notify( header_length, tvb, pinfo, kip_item, kip_tree, &offset );
3692 break;
3694 case KIP_SESSION_REQUEST:
3695 ok &= dissect_session_request( tvb, pinfo, kip_item, kip_tree, &offset );
3696 break;
3698 case KIP_SESSION_RESPONSE:
3699 ok &= dissect_session_response( tvb, pinfo, kip_item, kip_tree, &offset );
3700 break;
3702 case KIP_SESSION_AUTHENTICATE:
3703 ok &= dissect_session_auth( tvb, pinfo, kip_item, kip_tree, &offset );
3704 break;
3706 case KIP_SESSION_STATUS:
3707 ok &= dissect_session_status( tvb, pinfo, kip_item, kip_tree, &offset );
3708 break;
3713 if( offset >= 0 )
3715 remaining_len = tvb_captured_length_remaining( tvb, offset );
3716 if( remaining_len > 0 )
3718 if( tree )
3720 proto_item* unknown_item = knxip_tree_add_unknown_data( kip_tree, tvb, offset, remaining_len );
3721 expert_add_info_format( pinfo, unknown_item, KIP_ERROR, "Unexpected trailing data" );
3724 ok = 0;
3728 if( !ok )
3730 /* If not already done */
3731 if( !knxip_error )
3733 knxip_error = 1;
3734 col_prepend_fstr( cinfo, COL_INFO, "? " );
3737 proto_item_prepend_text( kip_item, "? " );
3741 static unsigned
3742 get_knxip_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
3744 return tvb_get_ntohs( tvb, offset+4 );
3747 // NOLINTNEXTLINE(misc-no-recursion)
3748 static int dissect_knxip( tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_ )
3750 int offset = 0;
3751 unsigned remaining_len = tvb_captured_length( tvb );
3752 uint8_t header_len = 0;
3753 uint8_t protocol_version = 0;
3754 uint16_t service_id = 0;
3755 uint16_t total_len = 0;
3756 uint8_t error = 0;
3758 column_info* cinfo = pinfo->cinfo;
3760 proto_item* kip_item = NULL;
3761 proto_tree* kip_tree = NULL;
3762 proto_item* header_item = NULL;
3763 proto_tree* header_tree = NULL;
3764 proto_item* header_len_item = NULL;
3765 proto_item* version_item = NULL;
3766 proto_item* service_item = NULL;
3767 proto_tree* service_tree = NULL;
3768 proto_item* total_length_item = NULL;
3770 char version_info[ 16 ];
3772 unsigned level = p_get_proto_depth(pinfo, proto_knxip);
3773 if( level == 0 )
3775 knxip_error = 0;
3776 col_set_str( cinfo, COL_PROTOCOL, "KNXnet/IP" );
3777 col_clear( cinfo, COL_INFO );
3779 else
3781 col_append_str( cinfo, COL_INFO, " " );
3783 p_set_proto_depth(pinfo, proto_knxip, level+1);
3785 kip_item = proto_tree_add_item( tree, proto_knxip, tvb, offset, (remaining_len <= 0) ? 0 : -1, ENC_BIG_ENDIAN );
3786 kip_tree = proto_item_add_subtree( kip_item, ett_kip );
3788 if( remaining_len <= 0 )
3790 /* This may happen if we are embedded in another KNXnet/IP frame (level != 0)
3792 proto_item_prepend_text( kip_item, "? " );
3793 expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Expected: min 6 bytes" );
3794 col_append_str( cinfo, COL_INFO, "? empty" );
3796 /* If not already done */
3797 if( !knxip_error )
3799 knxip_error = 1;
3800 col_prepend_fstr( cinfo, COL_INFO, "? " );
3803 else
3805 /* 1 byte Header Length */
3806 header_len = tvb_get_uint8( tvb, 0 );
3808 if( tree )
3810 header_item = proto_tree_add_none_format( kip_tree, hf_folder, tvb, 0,
3811 (header_len <= remaining_len) ? header_len : remaining_len, "KNX/IP Header" );
3812 header_tree = proto_item_add_subtree( header_item, ett_efcp );
3813 header_len_item = proto_tree_add_uint_format( header_tree, hf_knxip_header_length,
3814 tvb, 0, 1, header_len, "Header Length: %u bytes", header_len );
3817 if( header_len > remaining_len )
3819 proto_item_prepend_text( header_len_item, "? " );
3820 expert_add_info_format( pinfo, header_len_item, KIP_ERROR, "Available: %u bytes", remaining_len );
3821 error = 1;
3822 header_len = (uint8_t) remaining_len;
3824 else if( header_len != KIP_HDR_LEN )
3826 proto_item_prepend_text( header_len_item, "? " );
3827 expert_add_info_format( pinfo, header_len_item, KIP_ERROR, "Expected: 6 bytes" );
3828 error = 1;
3831 offset++;
3833 if( header_len >= 2 )
3835 /* 1 byte Protocol Version */
3836 protocol_version = tvb_get_uint8( tvb, 1 );
3837 snprintf( version_info, sizeof version_info, "%u.%u", hi_nibble( protocol_version ), lo_nibble( protocol_version ) );
3839 if( tree )
3841 version_item = proto_tree_add_uint_format( header_tree, hf_knxip_protocol_version,
3842 tvb, 1, 1, protocol_version, "Protocol Version: %s", version_info );
3845 if( protocol_version != 0x10 )
3847 proto_item_prepend_text( version_item, "? " );
3848 expert_add_info_format( pinfo, version_item, KIP_ERROR, "Expected: Protocol Version 1.0" );
3849 error = 1;
3852 offset++;
3854 if( header_len >= 4 )
3856 /* 2 bytes Service ID */
3857 service_id = tvb_get_ntohs( tvb, 2 );
3859 if( tree )
3861 const char* name = try_val_to_str( service_id, knxip_service_type_vals );
3862 proto_item_append_text( header_item, ": " );
3863 if( name )
3864 proto_item_append_text( header_item, "%s", name );
3865 else
3866 proto_item_append_text( header_item, "Service = 0x%04x", service_id );
3867 service_item = proto_tree_add_item( header_tree, hf_knxip_service_id, tvb, 2, 2, ENC_BIG_ENDIAN );
3868 service_tree = proto_item_add_subtree( service_item, ett_service );
3869 proto_tree_add_item( service_tree, hf_knxip_service_family, tvb, 2, 1, ENC_BIG_ENDIAN );
3870 proto_tree_add_item( service_tree, hf_knxip_service_type, tvb, 2, 2, ENC_BIG_ENDIAN );
3873 offset += 2;
3875 if( header_len >= KIP_HDR_LEN )
3877 /* 2 bytes Total Length */
3878 total_len = tvb_get_ntohs( tvb, 4 );
3880 if( tree )
3882 total_length_item = proto_tree_add_uint_format( header_tree, hf_knxip_total_length,
3883 tvb, 4, 2, total_len, "Total Length: %u bytes", total_len );
3886 if( total_len < header_len )
3888 proto_item_prepend_text( total_length_item, "? " );
3889 expert_add_info_format( pinfo, total_length_item, KIP_ERROR, "Expected: >= Header Length" );
3890 error = 1;
3892 else if( total_len > remaining_len )
3894 proto_item_prepend_text( total_length_item, "? " );
3895 expert_add_info_format( pinfo, total_length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
3896 error = 1;
3898 else if( total_len < remaining_len )
3900 proto_item_prepend_text( total_length_item, "? " );
3901 expert_add_info_format( pinfo, total_length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
3902 error = 1;
3905 offset += 2;
3910 if( offset < header_len )
3912 knxip_tree_add_unknown_data( header_tree, tvb, offset, header_len - offset );
3915 if( error )
3917 proto_item_prepend_text( header_item, "? " );
3919 if( level == 0 )
3921 col_prepend_fstr( cinfo, COL_PROTOCOL, "? " );
3923 else
3925 /* If not already done */
3926 if( !knxip_error )
3928 knxip_error = 1;
3929 col_prepend_fstr( cinfo, COL_INFO, "? " );
3934 dissect_knxip_data( header_len, protocol_version, service_id, tvb, pinfo, tree, kip_item, kip_tree );
3936 return tvb_captured_length( tvb );
3939 static int dissect_tcp_knxip( tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* udata )
3941 knxip_host_protocol = IP_PROTO_TCP;
3942 tcp_dissect_pdus(tvb, pinfo, tree, pref_desegment, KIP_HDR_LEN, get_knxip_pdu_len, dissect_knxip, udata);
3944 return tvb_captured_length( tvb );
3947 static int dissect_udp_knxip( tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* udata )
3949 knxip_host_protocol = IP_PROTO_UDP;
3950 udp_dissect_pdus( tvb, pinfo, tree, KIP_HDR_LEN, NULL, get_knxip_pdu_len, dissect_knxip, udata );
3951 return tvb_captured_length( tvb );
3954 void proto_register_knxip( void )
3956 /* Header fields */
3957 static hf_register_info hf[] =
3959 { &hf_bytes, { "Data", "knxip.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
3960 { &hf_folder, { "Folder", "knxip.folder", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } },
3961 { &hf_knxip_header_length, { "Header Length", "knxip.headerlength", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
3962 { &hf_knxip_protocol_version, { "Protocol Version", "knxip.version", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3963 { &hf_knxip_service_id, { "Service Identifier", "knxip.service", FT_UINT16, BASE_HEX, VALS( knxip_service_type_vals ), 0, NULL, HFILL } },
3964 { &hf_knxip_service_family, { "Service Family", "knxip.service.family", FT_UINT8, BASE_HEX, VALS( knxip_service_family_vals ), 0, NULL, HFILL } },
3965 { &hf_knxip_service_type, { "Service Type", "knxip.service.type", FT_UINT16, BASE_HEX, VALS( knxip_service_type_vals ), 0, NULL, HFILL } },
3966 { &hf_knxip_total_length, { "Total Length", "knxip.totallength", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
3967 { &hf_knxip_structure_length, { "Structure Length", "knxip.struct.length", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
3968 { &hf_knxip_host_protocol, { "Host Protocol", "knxip.hostprotocol", FT_UINT8, BASE_HEX, VALS( host_protocol_vals ), 0, NULL, HFILL } },
3969 { &hf_knxip_ip_address, { "IP Address", "knxip.ipaddr", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
3970 { &hf_knxip_port, { "Port Number", "knxip.port", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
3971 { &hf_knxip_description_type, { "Description Type", "knxip.dibtype", FT_UINT8, BASE_HEX, VALS( description_type_vals ), 0, NULL, HFILL } },
3972 { &hf_knxip_knx_medium, { "KNX Medium", "knxip.medium", FT_UINT8, BASE_HEX, VALS( medium_type_vals ), 0, NULL, HFILL } },
3973 { &hf_knxip_device_status, { "Device Status", "knxip.device.status", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3974 { &hf_knxip_program_mode, { "Programming Mode", "knxip.progmode", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
3975 { &hf_knxip_knx_address, { "KNX Individual Address", "knxip.knxaddr", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
3976 { &hf_knxip_project_id, { "Project Installation Identifier", "knxip.project", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
3977 { &hf_knxip_project_number, { "Project Number", "knxip.project.nr", FT_UINT16, BASE_DEC, NULL, 0xFFF0, NULL, HFILL } },
3978 { &hf_knxip_installation_number, { "Installation Number", "knxip.project.installation", FT_UINT16, BASE_DEC, NULL, 0x000F, NULL, HFILL } },
3979 { &hf_knxip_serial_number, { "KNX Serial Number", "knxip.sernr", FT_UINT48, BASE_HEX, NULL, 0, NULL, HFILL } },
3980 { &hf_knxip_multicast_address, { "Multicast Address", "knxip.mcaddr", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
3981 { &hf_knxip_mac_address, { "MAC Address", "knxip.macaddr", FT_ETHER, BASE_NONE, NULL, 0, NULL, HFILL } },
3982 { &hf_knxip_friendly_name, { "Friendly Name", "knxip.device.name", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
3983 { &hf_knxip_service_version, { "Service Version", "knxip.service.version", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3984 { &hf_knxip_security_version, { "Security Version", "knxip.security.version", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3985 { &hf_knxip_manufacturer_code, { "KNX Manufacturer Code", "knxip.manufacturer", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
3986 { &hf_knxip_connection_type, { "Connection Type", "knxip.conn.type", FT_UINT8, BASE_HEX, VALS( connection_type_vals ), 0, NULL, HFILL } },
3987 { &hf_knxip_knx_layer, { "KNX Layer", "knxip.tunnel.layer", FT_UINT8, BASE_HEX, VALS( knx_layer_vals ), 0, NULL, HFILL } },
3988 { &hf_knxip_channel, { "Channel", "knxip.channel", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3989 { &hf_knxip_status, { "Status", "knxip.status", FT_UINT8, BASE_HEX, VALS( error_vals ), 0, NULL, HFILL } },
3990 { &hf_knxip_reserved, { "Reserved", "knxip.reserved", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3991 { &hf_knxip_seq_counter, { "Sequence Counter", "knxip.seqctr", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
3992 { &hf_knxip_ip_subnet, { "Subnet Mask", "knxip.subnet", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
3993 { &hf_knxip_ip_gateway, { "Default Gateway", "knxip.gateway", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
3994 { &hf_knxip_ip_assign, { "IP Assignment", "knxip.ipassign", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3995 { &hf_knxip_ip_caps, { "IP Capabilities", "knxip.ipcaps", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3996 { &hf_knxip_ip_dhcp, { "DHCP Server", "knxip.dhcp", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
3997 { &hf_knxip_tunnel_feature, { "Tunneling Feature Identifier", "knxip.tunnel.feature", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3998 { &hf_knxip_routing_loss, { "Lost Messages", "knxip.loss", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
3999 { &hf_knxip_busy_time, { "Wait Time", "knxip.busy.time", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
4000 { &hf_knxip_busy_control, { "Control", "knxip.busy.control", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
4001 { &hf_knxip_selector, { "Selector", "knxip.selector", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
4002 { &hf_knxip_max_apdu_length, { "Max APDU Length", "knxip.maxapdulength", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
4003 { &hf_knxip_medium_status, { "Medium Status", "knxip.medium.status", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
4004 { &hf_knxip_mask_version, { "Mask Version", "knxip.mask.version", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
4005 { &hf_knxip_srp_mandatory, { "Mandatory", "knxip.srp.mandatory", FT_UINT8, BASE_DEC, NULL, 0x80, NULL, HFILL } },
4006 { &hf_knxip_srp_type, { "SRP Type", "knxip.srp.type", FT_UINT8, BASE_HEX, NULL, 0x7F, NULL, HFILL } },
4007 { &hf_knxip_reset_command, { "Command", "knxip.reset.command", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
4008 { &hf_knxip_session, { "Session", "knxip.session", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
4009 { &hf_knxip_tag, { "Tag", "knxip.tag", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
4010 { &hf_knxip_user, { "User", "knxip.user", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
4011 { &hf_knxip_session_status, { "Status", "knxip.session.status", FT_UINT8, BASE_HEX, VALS( session_status_vals ), 0, NULL, HFILL } },
4014 /* Subtrees */
4015 static int *ett[] =
4017 &ett_kip,
4018 &ett_efcp,
4019 &ett_service,
4020 &ett_hpai,
4021 &ett_dib,
4022 &ett_medium,
4023 &ett_status,
4024 &ett_projectid,
4025 &ett_service_family,
4026 &ett_ip_assignment,
4027 &ett_cri,
4028 &ett_crd,
4029 &ett_cnhdr,
4030 &ett_loss,
4031 &ett_busy,
4032 &ett_selector,
4033 &ett_decrypted,
4034 &ett_tunnel,
4037 static ei_register_info ei[] =
4039 { &ei_knxip_error, { "knxip.error", PI_MALFORMED, PI_ERROR, "KNX/IP error", EXPFILL }},
4040 { &ei_knxip_warning, { "knxip.warning", PI_PROTOCOL, PI_WARN, "KNX/IP warning", EXPFILL }},
4043 expert_module_t* expert_knxip;
4044 module_t* knxip_module;
4045 uint8_t x;
4047 proto_knxip = proto_register_protocol( "KNX/IP", "KNX/IP", "kip" );
4049 proto_register_field_array( proto_knxip, hf, array_length( hf ) );
4050 proto_register_subtree_array( ett, array_length( ett ) );
4052 register_dissector( "udp.knxip", dissect_udp_knxip, proto_knxip );
4053 register_dissector( "tcp.knxip", dissect_tcp_knxip, proto_knxip );
4055 //register_dissector_table( "knxip.version", "KNXnet/IP Protocol Version", proto_knxip, FT_UINT8, BASE_HEX );
4057 expert_knxip = expert_register_protocol( proto_knxip );
4058 expert_register_field_array( expert_knxip, ei, array_length( ei ) );
4060 knxip_module = prefs_register_protocol( proto_knxip, proto_reg_handoff_knxip );
4062 prefs_register_filename_preference( knxip_module, "key_file", "Key file", "Keyring.XML file (exported from ETS)",
4063 &pref_key_file_name, false );
4064 prefs_register_string_preference( knxip_module, "key_file_pwd", "Key file password", "Keyring password",
4065 &pref_key_file_pwd );
4066 prefs_register_filename_preference( knxip_module, "key_info_file", "Key info output file", "Output file (- for stdout) for keys extracted from key file",
4067 &pref_key_info_file_name, false );
4069 prefs_register_static_text_preference( knxip_module, "", "", NULL );
4071 prefs_register_static_text_preference( knxip_module, "keys_0",
4072 "KNX decryption keys",
4073 NULL );
4074 prefs_register_static_text_preference( knxip_module, "keys_1",
4075 "(KNX/IP multicast/group keys, KNX/IP unicast session keys, KNX data-security tool keys and link-table keys)",
4076 NULL );
4077 prefs_register_static_text_preference( knxip_module, "keys_2",
4078 "(format: 16 bytes as hex; example: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF)",
4079 NULL );
4081 for( x = 1; x <= MAX_KNX_DECRYPTION_KEYS; ++x )
4083 char* name = wmem_strdup_printf( wmem_epan_scope(), "key_%u", x );
4084 char* title = wmem_strdup_printf( wmem_epan_scope(), "%u. key", x );
4085 prefs_register_string_preference( knxip_module, name, title,
4086 "KNX decryption key (format: 16 bytes as hex; example: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF)",
4087 &pref_key_texts[ x - 1 ] );
4090 prefs_register_bool_preference(knxip_module, "desegment", "Reassemble KNX/IP messages spanning multiple TCP segments.", "Whether the KNX/IP dissector should reassemble messages spanning multiple TCP segments. To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", &pref_desegment);
4093 void proto_reg_handoff_knxip( void )
4095 dissector_handle_t knxip_handle;
4096 uint8_t x;
4097 const char* text;
4099 knxip_handle = find_dissector( "udp.knxip" );
4100 dissector_add_uint_range_with_preference("udp.port", KIP_DEFAULT_PORT_RANGE, knxip_handle);
4102 knxip_handle = find_dissector( "tcp.knxip" );
4103 dissector_add_uint_range_with_preference("tcp.port", KIP_DEFAULT_PORT_RANGE, knxip_handle);
4105 /* Evaluate preferences
4107 if( pref_key_file_name )
4109 /* Read Keyring.XML file (containing decryption keys, exported from ETS) */
4110 read_knx_keyring_xml_file( pref_key_file_name, pref_key_file_pwd, pref_key_info_file_name );
4113 knx_decryption_key_count = 0;
4114 for( x = 0; x < MAX_KNX_DECRYPTION_KEYS && knx_decryption_key_count < MAX_KNX_DECRYPTION_KEYS; ++x )
4116 text = pref_key_texts[ x ];
4117 if( text )
4119 if( hex_to_knx_key( text, knx_decryption_keys[ knx_decryption_key_count ] ) )
4121 ++knx_decryption_key_count;
4128 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4130 * Local variables:
4131 * c-basic-offset: 2
4132 * tab-width: 8
4133 * indent-tabs-mode: nil
4134 * End:
4136 * vi: set shiftwidth=2 tabstop=8 expandtab:
4137 * :indentSize=2:tabSize=8:noTabs=true: