Coverage Report

Created: 2026-09-28 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-knxip.c
Line
Count
Source
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>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
/*
14
 * See
15
 *
16
 *    https://my.knx.org/en/shop/knx-specifications
17
 *
18
 * for the specifications.
19
 */
20
21
#include "config.h"
22
23
#include <stdlib.h>
24
#include <string.h>
25
26
#include <epan/packet.h>
27
#include <epan/expert.h>
28
#include <epan/proto.h>
29
#include <epan/prefs.h>
30
#include <epan/proto_data.h>
31
#include <epan/to_str.h>
32
#include <epan/tvbuff.h>
33
#include <epan/strutil.h>
34
#include <epan/unit_strings.h>
35
#include <epan/iana-info.h>
36
#include <wsutil/to_str.h>
37
38
#include "packet-tcp.h"
39
#include "packet-udp.h"
40
#include "packet-knxip.h"
41
#include "packet-knxip_decrypt.h"
42
43
32
#define KIP_DEFAULT_PORT_RANGE "3671" /* IANA-assigned (EIBnet aka KNXnet) */
44
/* Other ports are commonly used, especially 3672 by KNX IP Gateways, but
45
 * not registered.
46
 */
47
48
25
#define ECDH_PUBLIC_VALUE_SIZE  32
49
50
1.55k
#define KIP_HDR_LEN 6
51
52
 /* The following service families are defined for the
53
 version 1.0 KNXnet/IP implementation of the eFCP protocol
54
 */
55
502
#define KIP_SERVICE_CORE  0x02
56
502
#define KIP_SERVICE_MANAGEMENT  0x03
57
6.47k
#define KIP_SERVICE_TUNNELING  0x04
58
#define KIP_SERVICE_ROUTING  0x05
59
#define KIP_SERVICE_REMOTE_LOGGING  0x06
60
#define KIP_SERVICE_REMOTE_DIAG_AND_CONFIG  0x07
61
#define KIP_SERVICE_OBJECT_SERVER  0x08
62
#define KIP_SERVICE_SECURITY  0x09
63
64
 /* The service codes for the core services (device discovery,
65
 self description and connection management) as defined in
66
 chapter 2 of the KNXnet/IP system specification
67
 */
68
1
#define KIP_SEARCH_REQUEST  0x0201
69
236
#define KIP_SEARCH_RESPONSE  0x0202
70
1
#define KIP_DESCRIPTION_REQUEST  0x0203
71
136
#define KIP_DESCRIPTION_RESPONSE  0x0204
72
17
#define KIP_CONNECT_REQUEST  0x0205
73
9
#define KIP_CONNECT_RESPONSE  0x0206
74
3
#define KIP_CONNECTIONSTATE_REQUEST  0x0207
75
3
#define KIP_CONNECTIONSTATE_RESPONSE  0x0208
76
0
#define KIP_DISCONNECT_REQUEST  0x0209
77
3
#define KIP_DISCONNECT_RESPONSE  0x020A
78
53
#define KIP_SEARCH_REQUEST_EXT  0x020B
79
123
#define KIP_SEARCH_RESPONSE_EXT  0x020C
80
81
 /* The service codes for the device management services
82
 (tunneling of cEMI local management procedures) as
83
 defined in chapter 3 of the KNXnet/IP system specification
84
 */
85
75
#define KIP_CONFIGURATION_REQUEST  0x0310
86
1
#define KIP_CONFIGURATION_ACK  0x0311
87
88
 /* The service codes for the tunneling services
89
 (transport of cEMI frames from service interface) as
90
 defined in chapter 4 of the KNXnet/IP system specification
91
 */
92
1
#define KIP_TUNNELING_REQUEST  0x0420
93
0
#define KIP_TUNNELING_ACK  0x0421
94
10
#define KIP_TUNNELING_FEATURE_GET  0x0422
95
7
#define KIP_TUNNELING_FEATURE_RESPONSE  0x0423
96
5
#define KIP_TUNNELING_FEATURE_SET  0x0424
97
6
#define KIP_TUNNELING_FEATURE_INFO  0x0425
98
99
 /* The service codes for the routing services
100
 (transport of cEMI frames between EIB couplers) as
101
 defined in chapter 5 of the KNXnet/IP system specification
102
 */
103
2
#define KIP_ROUTING_INDICATION  0x0530
104
4
#define KIP_ROUTING_LOST_MESSAGE  0x0531
105
3
#define KIP_ROUTING_BUSY  0x0532
106
15
#define KIP_ROUTING_SYSTEM_BROADCAST  0x0533
107
108
 /* The service codes for RemoteDiagAndConfig
109
 */
110
0
#define KIP_REMOTE_DIAG_REQUEST  0x0740
111
1
#define KIP_REMOTE_DIAG_RESPONSE  0x0741
112
5
#define KIP_REMOTE_CONFIG_REQUEST  0x0742
113
4
#define KIP_REMOTE_RESET_REQUEST  0x0743
114
115
 /* The service codes for KNX-IP Secure
116
 */
117
6
#define KIP_SECURE_WRAPPER  0x0950
118
9
#define KIP_SESSION_REQUEST  0x0951
119
7
#define KIP_SESSION_RESPONSE  0x0952
120
3
#define KIP_SESSION_AUTHENTICATE  0x0953
121
0
#define KIP_SESSION_STATUS  0x0954
122
0
#define KIP_TIMER_NOTIFY  0x0955
123
124
 /* KNXnet/IP host protocols */
125
190
#define KIP_IPV4_UDP  0x01
126
623
#define KIP_IPV4_TCP  0x02
127
128
 /* The different types of DIBs (Description Information Blocks)
129
 for the KNXnet/IP Core Discovery and Description services
130
 as defined in chapter 1 of the KNXnet/IP system specification
131
 */
132
397
#define KIP_DIB_DEVICE_INFO  0x01
133
752
#define KIP_DIB_SUPP_SVC_FAMILIES  0x02
134
400
#define KIP_DIB_IP_CONFIG  0x03
135
346
#define KIP_DIB_CUR_CONFIG  0x04
136
109
#define KIP_DIB_KNX_ADDRESSES  0x05
137
262
#define KIP_DIB_SECURED_SERVICE_FAMILIES  0x06
138
192
#define KIP_DIB_TUNNELING_INFO  0x07
139
106
#define KIP_DIB_EXTENDED_DEVICE_INFO  0x08
140
17
#define KIP_DIB_MFR_DATA  0xFE
141
142
 /* The different types of SRPs (Search Request Parameter Blocks)
143
 for the KNXnet/IP Core Discovery and Description services
144
 */
145
#define KIP_SRP_BY_PROGMODE  0x01
146
#define KIP_SRP_BY_MACADDR  0x02
147
#define KIP_SRP_BY_SERVICE  0x03
148
#define KIP_SRP_REQUEST_DIBS  0x04
149
150
 /* The different KNX medium types for the hardware (device info)
151
 DIB as defined in AN033 Common EMI Specification
152
 */
153
16
#define KIP_KNXTYPE_TP0  0x01
154
16
#define KIP_KNXTYPE_TP1  0x02
155
16
#define KIP_KNXTYPE_PL110  0x04
156
16
#define KIP_KNXTYPE_PL132  0x08
157
16
#define KIP_KNXTYPE_RF  0x10
158
16
#define KIP_KNXTYPE_IP  0x20
159
160
 /* KNXnet/IP connection types */
161
2
#define KIP_DEVICE_MGMT_CONNECTION  0x03
162
2
#define KIP_TUNNEL_CONNECTION  0x04
163
2
#define KIP_REMLOG_CONNECTION  0x06
164
2
#define KIP_REMCONF_CONNECTION  0x07
165
2
#define KIP_OBJSVR_CONNECTION  0x08
166
167
 /* Tunneling v2 feature ids */
168
#define KIP_TUNNELING_FEATURE_ID_SUPPORTED_EMI_TYPE  0x01
169
#define KIP_TUNNELING_FEATURE_ID_HOST_DEVICE_DEVICE_DESCRIPTOR_TYPE_0  0x02
170
#define KIP_TUNNELING_FEATURE_ID_BUS_CONNECTION_STATUS 0x03
171
#define KIP_TUNNELING_FEATURE_ID_KNX_MANUFACTURER_CODE 0x04
172
#define KIP_TUNNELING_FEATURE_ID_ACTIVE_EMI_TYPE 0x05
173
#define KIP_TUNNELING_FEATURE_ID_INDIVIDUAL_ADDRESS 0x06
174
#define KIP_TUNNELING_FEATURE_ID_MAX_APDU_LENGTH 0x07
175
#define KIP_TUNNELING_FEATURE_ID_INFO_SERVICE_ENABLE 0x08
176
177
 /* KNXnet/IP tunnel types */
178
#define TUNNEL_LINKLAYER  0x02
179
#define TUNNEL_RAW  0x04
180
#define TUNNEL_BUSMONITOR  0x80
181
182
 /* KNXnet/IP error codes */
183
7
#define KIP_E_NO_ERROR  0x00
184
#define KIP_E_CONNECTION_ID  0x21
185
#define KIP_E_CONNECTION_TYPE  0x22
186
#define KIP_E_CONNECTION_OPTION  0x23
187
#define KIP_E_NO_MORE_CONNECTIONS  0x24
188
#define KIP_E_NO_MORE_UNIQUE_CONNECTIONS  0x25
189
#define KIP_E_DATA_CONNECTION  0x26
190
#define KIP_E_KNX_CONNECTION  0x27
191
#define KIP_E_TUNNELING_LAYER  0x29
192
193
/* KNXnet/IP remote selection types */
194
14
#define SELECT_PROGMODE  0x01
195
14
#define SELECT_MACADDRESS  0x02
196
197
/* SESSION_STATUS codes */
198
#define SESSION_STATUS_AUTHENTICATION_SUCCESS  0x00
199
#define SESSION_STATUS_AUTHENTICATION_FAILED  0x01
200
#define SESSION_STATUS_UNAUTHENTICATED  0x02
201
#define SESSION_STATUS_TIMEOUT  0x03
202
#define SESSION_STATUS_KEEPALIVE  0x04
203
#define SESSION_STATUS_CLOSE  0x05
204
205
/* Initialize the protocol identifier that is needed for the
206
 protocol hook and to register the fields in the protocol tree
207
*/
208
static int proto_knxip;
209
210
/* Initialize the registered fields identifiers. These fields
211
 will be registered with the protocol during initialization.
212
 Protocol fields are like type definitions. The protocol dissector
213
 later on adds items of these types to the protocol tree.
214
*/
215
static int hf_bytes;
216
static int hf_folder;
217
static int hf_knxip_header_length;
218
static int hf_knxip_protocol_version;
219
static int hf_knxip_service_id;
220
static int hf_knxip_service_family;
221
static int hf_knxip_service_type;
222
static int hf_knxip_total_length;
223
static int hf_knxip_structure_length;
224
static int hf_knxip_host_protocol;
225
static int hf_knxip_ip_address;
226
static int hf_knxip_port;
227
static int hf_knxip_description_type;
228
static int hf_knxip_knx_medium;
229
static int hf_knxip_knx_medium_flags_ip;
230
static int hf_knxip_knx_medium_flags_rf;
231
static int hf_knxip_knx_medium_flags_pl132;
232
static int hf_knxip_knx_medium_flags_pl110;
233
static int hf_knxip_knx_medium_flags_tp1;
234
static int hf_knxip_knx_medium_flags_tp0;
235
static int hf_knxip_device_status;
236
static int hf_knxip_program_mode;
237
static int hf_knxip_knx_address;
238
static int hf_knxip_knx_tunnel_usable;
239
static int hf_knxip_knx_tunnel_authorized;
240
static int hf_knxip_knx_tunnel_free;
241
static int hf_knxip_project_id;
242
static int hf_knxip_project_number;
243
static int hf_knxip_installation_number;
244
static int hf_knxip_serial_number;
245
static int hf_knxip_multicast_address;
246
static int hf_knxip_mac_address;
247
static int hf_knxip_friendly_name;
248
static int hf_knxip_service_version;
249
static int hf_knxip_security_version;
250
static int hf_knxip_manufacturer_code;
251
static int hf_knxip_connection_type;
252
static int hf_knxip_knx_layer;
253
static int hf_knxip_reserved;
254
static int hf_knxip_channel;
255
static int hf_knxip_status;
256
static int hf_knxip_seq_counter;
257
static int hf_knxip_ip_subnet;
258
static int hf_knxip_ip_gateway;
259
static int hf_knxip_ip_assign;
260
static int hf_knxip_ip_assign_auto;
261
static int hf_knxip_ip_assign_dhcp;
262
static int hf_knxip_ip_assign_bootp;
263
static int hf_knxip_ip_assign_manual;
264
static int hf_knxip_ip_caps;
265
static int hf_knxip_ip_dhcp;
266
static int hf_knxip_ip_caps_auto;
267
static int hf_knxip_ip_caps_dhcp;
268
static int hf_knxip_ip_caps_bootp;
269
static int hf_knxip_tunnel_feature;
270
static int hf_knxip_routing_loss;
271
static int hf_knxip_busy_time;
272
static int hf_knxip_busy_control;
273
static int hf_knxip_selector;
274
static int hf_knxip_max_apdu_length;
275
static int hf_knxip_medium_status;
276
static int hf_knxip_mask_version;
277
static int hf_knxip_srp_mandatory;
278
static int hf_knxip_srp_type;
279
static int hf_knxip_reset_command;
280
static int hf_knxip_session;
281
static int hf_knxip_tag;
282
static int hf_knxip_user;
283
static int hf_knxip_session_status;
284
285
/* Initialize the subtree pointers. These pointers are needed to
286
 display the protocol in a structured tree. Subtrees hook on
287
 already defined fields or (the topmost) on the protocol itself
288
*/
289
static int ett_kip;
290
static int ett_efcp;
291
static int ett_service;
292
static int ett_hpai;
293
static int ett_dib;
294
static int ett_medium;
295
static int ett_status;
296
static int ett_projectid;
297
static int ett_service_family;
298
static int ett_ip_assignment;
299
static int ett_cri;
300
static int ett_crd;
301
static int ett_cnhdr;
302
static int ett_loss;
303
static int ett_busy;
304
static int ett_selector;
305
static int ett_decrypted;
306
static int ett_tunnel;
307
308
/* Set up the value_string tables for the service families
309
 and the service types (note that the service types in KNXnet/IP
310
 version 1.0 are unique even across service families...)
311
*/
312
static const value_string knxip_service_family_vals[] = {
313
  { KIP_SERVICE_CORE, "Core" },
314
  { KIP_SERVICE_MANAGEMENT, "Device Management" },
315
  { KIP_SERVICE_TUNNELING, "Tunneling" },
316
  { KIP_SERVICE_ROUTING, "Routing" },
317
  { KIP_SERVICE_REMOTE_LOGGING, "Remote Logging" },
318
  { KIP_SERVICE_REMOTE_DIAG_AND_CONFIG, "Remote Diag And Config" },
319
  { KIP_SERVICE_OBJECT_SERVER, "Object Server" },
320
  { KIP_SERVICE_SECURITY, "Security" },
321
  { 0, NULL}
322
};
323
static const value_string knxip_service_type_vals[] = {
324
  { KIP_SEARCH_REQUEST, "Search Request" },
325
  { KIP_SEARCH_RESPONSE, "Search Response" },
326
  { KIP_DESCRIPTION_REQUEST, "Description Request" },
327
  { KIP_DESCRIPTION_RESPONSE, "Description Response" },
328
  { KIP_CONNECT_REQUEST, "Connect Request" },
329
  { KIP_CONNECT_RESPONSE, "Connect Response" },
330
  { KIP_CONNECTIONSTATE_REQUEST, "Connection State Request" },
331
  { KIP_CONNECTIONSTATE_RESPONSE, "Connection State Response" },
332
  { KIP_DISCONNECT_REQUEST, "Disconnect Request" },
333
  { KIP_DISCONNECT_RESPONSE, "Disconnect Response" },
334
  { KIP_SEARCH_REQUEST_EXT, "Search Request Extended" },
335
  { KIP_SEARCH_RESPONSE_EXT, "Search Response Extended" },
336
  { KIP_CONFIGURATION_REQUEST, "Configuration Request" },
337
  { KIP_CONFIGURATION_ACK, "Configuration Acknowledgement" },
338
  { KIP_TUNNELING_REQUEST, "Tunneling Request" },
339
  { KIP_TUNNELING_ACK, "Tunneling Acknowledgement" },
340
  { KIP_TUNNELING_FEATURE_GET, "Tunneling Feature Get" },
341
  { KIP_TUNNELING_FEATURE_RESPONSE, "Tunneling Feature Response" },
342
  { KIP_TUNNELING_FEATURE_SET, "Tunneling Feature Set" },
343
  { KIP_TUNNELING_FEATURE_INFO, "Tunneling Feature Info" },
344
  { KIP_ROUTING_INDICATION, "Routing Indication" },
345
  { KIP_ROUTING_LOST_MESSAGE, "Routing Loss" },
346
  { KIP_ROUTING_BUSY, "Routing Busy" },
347
  { KIP_ROUTING_SYSTEM_BROADCAST, "Routing System Broadcast" },
348
  { KIP_REMOTE_DIAG_REQUEST, "Remote Diagnostic Request" },
349
  { KIP_REMOTE_DIAG_RESPONSE, "Remote Diagnostic Response" },
350
  { KIP_REMOTE_CONFIG_REQUEST, "Remote Configuration Request" },
351
  { KIP_REMOTE_RESET_REQUEST, "Remote Reset Request" },
352
  { KIP_SECURE_WRAPPER, "Secure Wrapper" },
353
  { KIP_SESSION_REQUEST, "Session Request" },
354
  { KIP_SESSION_RESPONSE, "Session Response" },
355
  { KIP_SESSION_AUTHENTICATE, "Session Authenticate" },
356
  { KIP_SESSION_STATUS, "Session Status" },
357
  { KIP_TIMER_NOTIFY, "Timer Notify" },
358
  { 0, NULL}
359
};
360
static const value_string svc_vals[] = {  /* abbreviated service names */
361
  { KIP_SEARCH_REQUEST, "SearchReq" },
362
  { KIP_SEARCH_RESPONSE, "SearchResp" },
363
  { KIP_DESCRIPTION_REQUEST, "DescrReq" },
364
  { KIP_DESCRIPTION_RESPONSE, "DescrResp" },
365
  { KIP_CONNECT_REQUEST, "ConnectReq" },
366
  { KIP_CONNECT_RESPONSE, "ConnectResp" },
367
  { KIP_CONNECTIONSTATE_REQUEST, "ConnStateReq" },
368
  { KIP_CONNECTIONSTATE_RESPONSE, "ConnStateResp" },
369
  { KIP_DISCONNECT_REQUEST, "DisconnectReq" },
370
  { KIP_DISCONNECT_RESPONSE, "DisconnectResp" },
371
  { KIP_SEARCH_REQUEST_EXT, "SearchReqExt" },
372
  { KIP_SEARCH_RESPONSE_EXT, "SearchRespExt" },
373
  { KIP_CONFIGURATION_REQUEST, "ConfigReq" },
374
  { KIP_CONFIGURATION_ACK, "ConfigAck" },
375
  { KIP_TUNNELING_REQUEST, "TunnelReq" },
376
  { KIP_TUNNELING_ACK, "TunnelAck" },
377
  { KIP_TUNNELING_FEATURE_GET, "TunnelFeatureGet" },
378
  { KIP_TUNNELING_FEATURE_RESPONSE, "TunnelFeatureResp" },
379
  { KIP_TUNNELING_FEATURE_SET, "TunnelFeatureSet" },
380
  { KIP_TUNNELING_FEATURE_INFO, "TunnelFeatureInfo" },
381
  { KIP_ROUTING_INDICATION, "RoutingInd" },
382
  { KIP_ROUTING_LOST_MESSAGE, "RoutingLoss" },
383
  { KIP_ROUTING_BUSY, "RoutingBusy" },
384
  { KIP_ROUTING_SYSTEM_BROADCAST, "RoutingSBC" },
385
  { KIP_REMOTE_DIAG_REQUEST, "RemoteDiagReq" },
386
  { KIP_REMOTE_DIAG_RESPONSE, "RemoteDiagResp" },
387
  { KIP_REMOTE_CONFIG_REQUEST, "RemoteConfigReq" },
388
  { KIP_REMOTE_RESET_REQUEST, "RemoteResetReq" },
389
  { KIP_SECURE_WRAPPER, "SecureWrapper" },
390
  { KIP_SESSION_REQUEST, "SessionReq" },
391
  { KIP_SESSION_RESPONSE, "SessionResp" },
392
  { KIP_SESSION_AUTHENTICATE, "SessionAuth" },
393
  { KIP_SESSION_STATUS, "SessionStatus" },
394
  { KIP_TIMER_NOTIFY, "TimerNotify" },
395
  { 0, NULL}
396
};
397
static const value_string host_protocol_vals[] = {
398
  { KIP_IPV4_UDP, "IPv4 UDP" },
399
  { KIP_IPV4_TCP, "IPv4 TCP" },
400
  { 0, NULL}
401
};
402
static const value_string description_type_vals[] = {
403
  { KIP_DIB_DEVICE_INFO, "Device Information" },
404
  { KIP_DIB_SUPP_SVC_FAMILIES, "Supported Service Families" },
405
  { KIP_DIB_IP_CONFIG, "IP Configuration" },
406
  { KIP_DIB_CUR_CONFIG, "Current Configuration" },
407
  { KIP_DIB_KNX_ADDRESSES, "KNX Addresses" },
408
  { KIP_DIB_SECURED_SERVICE_FAMILIES, "Secured Service Families" },
409
  { KIP_DIB_TUNNELING_INFO, "Tunneling Information" },
410
  { KIP_DIB_EXTENDED_DEVICE_INFO, "Extended Device Information" },
411
  { KIP_DIB_MFR_DATA, "Manufacturer Data" },
412
  { 0, NULL}
413
};
414
static const value_string descr_type_vals[] = {  /* abbreviated DIB names */
415
  { KIP_DIB_DEVICE_INFO, "DevInfo" },
416
  { KIP_DIB_SUPP_SVC_FAMILIES, "SuppSvc" },
417
  { KIP_DIB_IP_CONFIG, "IpConfig" },
418
  { KIP_DIB_CUR_CONFIG, "CurConfig" },
419
  { KIP_DIB_KNX_ADDRESSES, "KnxAddr" },
420
  { KIP_DIB_SECURED_SERVICE_FAMILIES, "SecSvcFam" },
421
  { KIP_DIB_TUNNELING_INFO, "TunnelInfo" },
422
  { KIP_DIB_EXTENDED_DEVICE_INFO, "ExtDevInfo" },
423
  { KIP_DIB_MFR_DATA, "MfrData" },
424
  { 0, NULL}
425
};
426
#if 0
427
static const value_string search_request_parameter_type_vals[] = {
428
  { KIP_SRP_BY_PROGMODE, "By programming mode" },
429
  { KIP_SRP_BY_MACADDR, "By MAC address" },
430
  { KIP_SRP_BY_SERVICE, "By service" },
431
  { KIP_SRP_REQUEST_DIBS, "Request DIBs" },
432
  { 0, NULL }
433
};
434
#endif
435
static const value_string srp_type_vals[] = {  /* abbreviated SRP names */
436
  { KIP_SRP_BY_PROGMODE, "ProgMode" },
437
  { KIP_SRP_BY_MACADDR, "MacAddr" },
438
  { KIP_SRP_BY_SERVICE, "Service" },
439
  { KIP_SRP_REQUEST_DIBS, "Dibs" },
440
  { 0, NULL }
441
};
442
static const value_string medium_type_vals[] = {
443
  { KIP_KNXTYPE_TP0, "TP0" },
444
  { KIP_KNXTYPE_TP1, "TP1" },
445
  { KIP_KNXTYPE_PL110, "PL110" },
446
  { KIP_KNXTYPE_PL132, "PL132" },
447
  { KIP_KNXTYPE_RF, "RF" },
448
  { KIP_KNXTYPE_IP, "IP" },
449
  { 0, NULL}
450
};
451
static const value_string connection_type_vals[] = {
452
  { KIP_DEVICE_MGMT_CONNECTION, "Device Management Connection" },
453
  { KIP_TUNNEL_CONNECTION, "Tunneling Connection" },
454
  { KIP_REMLOG_CONNECTION, "Remote Logging Connection" },
455
  { KIP_REMCONF_CONNECTION, "Remote Configuration Connection" },
456
  { KIP_OBJSVR_CONNECTION, "Object Server Connection" },
457
  { 0, NULL}
458
};
459
static const value_string conn_type_vals[] = {
460
  { KIP_DEVICE_MGMT_CONNECTION, "Config" },
461
  { KIP_TUNNEL_CONNECTION, "Tunnel" },
462
  { KIP_REMLOG_CONNECTION, "RemoteLogging" },
463
  { KIP_REMCONF_CONNECTION, "RemoteConfig" },
464
  { KIP_OBJSVR_CONNECTION, "ObjectServer" },
465
  { 0, NULL }
466
};
467
static const value_string tunneling_feature_id_vals[] = {
468
  { KIP_TUNNELING_FEATURE_ID_SUPPORTED_EMI_TYPE, "SupportedEmiType" },
469
  { KIP_TUNNELING_FEATURE_ID_HOST_DEVICE_DEVICE_DESCRIPTOR_TYPE_0, "MaskVersion" },
470
  { KIP_TUNNELING_FEATURE_ID_BUS_CONNECTION_STATUS, "BusStatus" },
471
  { KIP_TUNNELING_FEATURE_ID_KNX_MANUFACTURER_CODE, "Manufacturer" },
472
  { KIP_TUNNELING_FEATURE_ID_ACTIVE_EMI_TYPE, "ActiveEmiType" },
473
  { KIP_TUNNELING_FEATURE_ID_INDIVIDUAL_ADDRESS, "IndividualAddress" },
474
  { KIP_TUNNELING_FEATURE_ID_MAX_APDU_LENGTH, "MaxApduLength" },
475
  { KIP_TUNNELING_FEATURE_ID_INFO_SERVICE_ENABLE, "InfoServiceEnable" },
476
  { 0, NULL }
477
};
478
static const value_string knx_layer_vals[] = {
479
  { TUNNEL_LINKLAYER, "LinkLayer" },
480
  { TUNNEL_RAW, "Raw" },
481
  { TUNNEL_BUSMONITOR, "Busmonitor" },
482
  { 0, NULL}
483
};
484
static const value_string error_vals[] = {
485
  { KIP_E_NO_ERROR, "OK" },
486
  { KIP_E_CONNECTION_ID, "E_CONNECTION_ID" },
487
  { KIP_E_CONNECTION_TYPE, "E_CONNECTION_TYPE" },
488
  { KIP_E_CONNECTION_OPTION, "E_CONNECTION_OPTION" },
489
  { KIP_E_NO_MORE_CONNECTIONS, "E_NO_MORE_CONNECTIONS" },
490
  { KIP_E_NO_MORE_UNIQUE_CONNECTIONS, "E_NO_MORE_UNIQUE_CONNECTIONS" },
491
  { KIP_E_DATA_CONNECTION, "E_DATA_CONNECTION" },
492
  { KIP_E_KNX_CONNECTION, "E_KNX_CONNECTION" },
493
  { KIP_E_TUNNELING_LAYER, "E_TUNNELING_LAYER" },
494
  { 0, NULL}
495
};
496
static const value_string session_status_vals[] = {
497
  { SESSION_STATUS_AUTHENTICATION_SUCCESS, "STATUS_AUTHENTICATION_SUCCESS" },
498
  { SESSION_STATUS_AUTHENTICATION_FAILED, "STATUS_AUTHENTICATION_FAILED" },
499
  { SESSION_STATUS_UNAUTHENTICATED, "STATUS_UNAUTHENTICATED" },
500
  { SESSION_STATUS_TIMEOUT, "STATUS_TIMEOUT" },
501
  { SESSION_STATUS_KEEPALIVE, "STATUS_KEEPALIVE" },
502
  { SESSION_STATUS_CLOSE, "STATUS_CLOSE" },
503
  { 0, NULL }
504
};
505
506
static int* const knx_ip_assign_flags[] = {
507
  &hf_knxip_ip_assign_auto,
508
  &hf_knxip_ip_assign_dhcp,
509
  &hf_knxip_ip_assign_bootp,
510
  &hf_knxip_ip_assign_manual,
511
  NULL
512
};
513
514
uint8_t knxip_error;
515
uint8_t knxip_host_protocol;
516
517
expert_field ei_knxip_error;
518
expert_field ei_knxip_warning;
519
520
static bool pref_desegment = true;
521
static const char* pref_key_texts[ MAX_KNX_DECRYPTION_KEYS ];
522
//static const char* authentication_code_text;
523
//static const char* password_hash_text;
524
static const char* pref_key_file_name;
525
static const char* pref_key_file_pwd;
526
static const char* pref_key_info_file_name;
527
528
/* KNX decryption keys
529
*/
530
uint8_t knx_decryption_keys[ MAX_KNX_DECRYPTION_KEYS ][ KNX_KEY_LENGTH ];
531
uint8_t knx_decryption_key_count;
532
533
/* Forward declarations
534
*/
535
static int dissect_knxip( tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_ );
536
void proto_reg_handoff_knxip( void );
537
void proto_register_knxip( void );
538
539
/* Add raw data to list view, tree view, and parent folder
540
*/
541
static proto_item* knxip_tree_add_data( proto_tree* tree, tvbuff_t* tvb, int offset, int length, column_info* cinfo, proto_item* item,
542
  const char* name, const char* text1, const char* text2 )
543
309
{
544
309
  proto_item* new_item = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, length, NULL, "%s: $", name );
545
309
  if( text1 ) col_append_str( cinfo, COL_INFO, text1 );
546
309
  if( text2 ) proto_item_append_text( item, "%s", text2 );
547
548
10.7k
  while( length > 0 )
549
10.4k
  {
550
10.4k
    uint8_t value = tvb_get_uint8( tvb, offset );
551
10.4k
    if( text1 ) col_append_fstr( cinfo, COL_INFO, "%02X", value );
552
10.4k
    if( text2 ) proto_item_append_text( item, "%02X", value );
553
10.4k
    proto_item_append_text( new_item, " %02X", value );
554
10.4k
    offset++;
555
10.4k
    length--;
556
10.4k
  }
557
558
309
  return new_item;
559
309
}
560
561
/* Show unknown or unexpected data
562
*/
563
static proto_item* knxip_tree_add_unknown_data( proto_tree* tree, tvbuff_t* tvb, int offset, int length )
564
2.40k
{
565
2.40k
  return proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, length, NULL, "? Unknown data (%d bytes)", length );
566
2.40k
}
567
568
static uint8_t hex_to_knx_key( const char* text, uint8_t key[ KNX_KEY_LENGTH ] )
569
160
{
570
160
  size_t n_bytes = 0;
571
160
  uint8_t* bytes = convert_string_to_hex( text, &n_bytes );
572
160
  if( bytes == NULL )
573
160
  {
574
160
    n_bytes = 0;
575
160
  }
576
0
  else
577
0
  {
578
0
    if( n_bytes )
579
0
    {
580
0
      if( n_bytes > KNX_KEY_LENGTH ) n_bytes = KNX_KEY_LENGTH;
581
0
      if( n_bytes ) memcpy( key, bytes, n_bytes );
582
0
      while( n_bytes < KNX_KEY_LENGTH ) key[ n_bytes++ ] = 0;
583
0
    }
584
0
    g_free( bytes );
585
0
  }
586
160
  return n_bytes != 0;
587
160
}
588
589
static proto_item* knxip_tree_add_status( proto_tree* tree, tvbuff_t* tvb, int offset )
590
17
{
591
17
  return proto_tree_add_item( tree, hf_knxip_status, tvb, offset, 1, ENC_BIG_ENDIAN );
592
17
}
593
594
static proto_item* knxip_tree_add_reserved( proto_tree* tree, tvbuff_t* tvb, int offset, packet_info* pinfo, uint8_t* p_ok )
595
207
{
596
207
  proto_item* new_item = proto_tree_add_item( tree, hf_knxip_reserved, tvb, offset, 1, ENC_BIG_ENDIAN );
597
207
  if( tvb_get_uint8( tvb, offset ) )
598
174
  {
599
174
    proto_item_prepend_text( new_item, "? " );
600
174
    expert_add_info_format( pinfo, new_item, KIP_ERROR, "Expected: 0x00" );
601
174
    if( p_ok ) *p_ok = 0;
602
174
  }
603
207
  return new_item;
604
207
}
605
606
static proto_item* knxip_tree_add_missing_reserved( proto_tree* tree, tvbuff_t* tvb, int offset, packet_info* pinfo )
607
0
{
608
0
  proto_item* new_item = proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Reserved: expected 1 byte" );
609
0
  return new_item;
610
0
}
611
612
613
static void knxip_item_illegal_length( proto_item* length_item, packet_info* pinfo, const char* info )
614
1.41k
{
615
1.41k
  proto_item_prepend_text( length_item, "? " );
616
1.41k
  expert_add_info_format( pinfo, length_item, KIP_ERROR, "%s", info );
617
1.41k
}
618
619
static proto_item* knxip_tree_add_knx_address( proto_tree* tree, int hfindex, tvbuff_t* tvb, int offset, char** output, wmem_allocator_t* output_scope )
620
1.19k
{
621
1.19k
  uint16_t value = tvb_get_ntohs( tvb, offset );
622
1.19k
  *output = wmem_strdup_printf(output_scope, "%u.%u.%u", (value >> 12) & 0xF, (value >> 8) & 0xF, value & 0xFF);
623
1.19k
  proto_item* new_item = proto_tree_add_item( tree, hfindex, tvb, offset, 2, ENC_BIG_ENDIAN );
624
1.19k
  proto_item_append_text( new_item, " = %s", *output);
625
1.19k
  return new_item;
626
1.19k
}
627
628
/* Dissect HPAI field
629
*/
630
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 )
631
231
{
632
231
  uint8_t ok = 1;
633
231
  int offset = *p_offset;
634
231
  int remaining_len = tvb_captured_length_remaining( tvb, offset );
635
231
  uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
636
231
  int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
637
638
231
  proto_item* hpai_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "HPAI %s Endpoint", name );
639
640
231
  wmem_strbuf_t* info = wmem_strbuf_new(pinfo->pool, "???");
641
642
231
  if( struct_len <= 0 )
643
16
  {
644
16
    proto_item_prepend_text( hpai_item, "Missing " );
645
16
    expert_add_info_format( pinfo, hpai_item, KIP_ERROR, "Expected: 8 bytes" );
646
16
    ok = 0;
647
16
  }
648
215
  else
649
215
  {
650
    /* 1 byte Structure Length */
651
215
    proto_tree* hpai_tree = proto_item_add_subtree( hpai_item, ett_hpai );
652
215
    proto_item* length_item = proto_tree_add_uint( hpai_tree, hf_knxip_structure_length, tvb, offset, 1, struct_len);
653
215
    proto_item* node;
654
655
215
    int end_pos = offset + eff_struct_len;
656
215
    offset++;
657
658
215
    if( struct_len != 8 )
659
210
    {
660
210
      knxip_item_illegal_length( length_item, pinfo, "Expected: 8 bytes" );
661
210
      ok = 0;
662
210
    }
663
664
215
    if( struct_len > remaining_len )
665
11
    {
666
11
      expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
667
11
      struct_len = (uint8_t) remaining_len;
668
669
11
      if( ok )
670
1
      {
671
1
        proto_item_prepend_text( length_item, "? " );
672
1
        ok = 0;
673
1
      }
674
11
    }
675
204
    else if( struct_len < 2 )
676
14
    {
677
14
      expert_add_info_format( pinfo, hpai_item, KIP_ERROR, "Missing 1 byte Host Protocol" );
678
14
      ok = 0;
679
14
    }
680
190
    else
681
190
    {
682
      /* 1 byte Host Protocol */
683
190
      uint8_t host_protocol = tvb_get_uint8( tvb, offset );
684
190
      const char* host_protocol_name = "???";
685
190
      uint8_t protocol_error = 0;
686
687
190
      node = proto_tree_add_item( hpai_tree, hf_knxip_host_protocol, tvb, offset, 1, ENC_BIG_ENDIAN );
688
689
190
      if( host_protocol == KIP_IPV4_UDP )
690
13
      {
691
13
        host_protocol_name = "UDP";
692
13
        if( check_protocol )
693
8
        {
694
8
          if( knxip_host_protocol != IP_PROTO_UDP && knxip_host_protocol != IP_PROTO_UDPLITE )
695
5
          {
696
5
            protocol_error = 1;
697
5
          }
698
8
        }
699
13
      }
700
177
      else if( host_protocol == KIP_IPV4_TCP )
701
24
      {
702
24
        host_protocol_name = "TCP";
703
24
        if( check_protocol )
704
8
        {
705
8
          if( knxip_host_protocol != IP_PROTO_TCP )
706
8
          {
707
8
            protocol_error = 1;
708
8
          }
709
8
        }
710
24
      }
711
153
      else
712
153
      {
713
153
        protocol_error = 2;
714
153
      }
715
716
190
      if( protocol_error )
717
166
      {
718
166
        proto_item_prepend_text( node, "? " );
719
166
        expert_add_info_format( pinfo, node, KIP_ERROR, (protocol_error == 1) ? "Wrong Host Protocol" : "Expected: 0x01 or 0x02" );
720
166
        ok = 0;
721
166
      }
722
723
190
      offset++;
724
725
190
      if( struct_len < 6 )
726
74
      {
727
74
        expert_add_info_format( pinfo, hpai_item, KIP_ERROR, "Missing 4 bytes IP Address" );
728
74
        ok = 0;
729
74
      }
730
116
      else
731
116
      {
732
        /* 4 bytes IP Address */
733
116
        ws_in4_addr addr_ipv4;
734
116
        node = proto_tree_add_item_ret_ipv4(hpai_tree, hf_knxip_ip_address, tvb, offset, 4, ENC_BIG_ENDIAN, &addr_ipv4);
735
736
116
        if( host_protocol == KIP_IPV4_TCP && addr_ipv4 != 0 )
737
15
        {
738
15
          proto_item_prepend_text( node, "? " );
739
15
          expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 0.0.0.0" );
740
15
          ok = 0;
741
15
        }
742
743
116
        offset += 4;
744
745
116
        info = wmem_strbuf_new(pinfo->pool, ip_addr_to_str(pinfo->pool, &addr_ipv4));
746
116
        wmem_strbuf_append_c(info, ':');
747
748
116
        if( struct_len < 8 )
749
9
        {
750
9
          expert_add_info_format( pinfo, hpai_item, KIP_ERROR, "Missing 2 bytes Port Number" );
751
9
          ok = 0;
752
9
        }
753
107
        else
754
107
        {
755
          /* 2 bytes Port Number */
756
107
          uint32_t port = tvb_get_ntohs( tvb, offset );
757
758
107
          node = proto_tree_add_item_ret_uint( hpai_tree, hf_knxip_port, tvb, offset, 2, ENC_BIG_ENDIAN, &port);
759
107
          wmem_strbuf_append_printf(info, "%u", port);
760
761
107
          if( host_protocol == KIP_IPV4_TCP && port != 0 )
762
12
          {
763
12
            proto_item_prepend_text( node, "? " );
764
12
            expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 0" );
765
12
            ok = 0;
766
12
          }
767
768
107
          offset += 2;
769
107
        }
770
116
      }
771
772
190
      if( offset < end_pos )
773
130
      {
774
130
        knxip_tree_add_unknown_data( hpai_tree, tvb, offset, end_pos - offset );
775
130
        ok = 0;
776
130
      }
777
778
190
      proto_item_append_text( hpai_item, ": %s %s", wmem_strbuf_get_str(info), host_protocol_name );
779
190
    }
780
215
  }
781
782
231
  col_append_fstr( pinfo->cinfo, COL_INFO, " @%s", wmem_strbuf_get_str(info));
783
231
  proto_item_append_text( item, ", %s @ %s", name, wmem_strbuf_get_str(info));
784
785
231
  if( !ok )
786
230
  {
787
230
    proto_item_prepend_text( hpai_item, "? " );
788
230
    if( p_ok ) *p_ok = 0;
789
230
  }
790
791
231
  *p_offset += struct_len;
792
231
  return struct_len;
793
231
}
794
795
/* Dissect CRI (= Connection Request Information)
796
*/
797
static uint8_t dissect_cri( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset, uint8_t* p_ok )
798
12
{
799
12
  int offset = *p_offset;
800
12
  int remaining_len = tvb_captured_length_remaining( tvb, offset );
801
12
  uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
802
12
  int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
803
804
12
  proto_item* cri_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "CRI" );
805
806
12
  uint8_t conn_type = 0;
807
12
  const char* conn_type_name = NULL;
808
12
  uint8_t ok = 0;
809
12
  char* extra_text = NULL;
810
811
12
  if( struct_len <= 0 )
812
1
  {
813
1
    proto_item_prepend_text( cri_item, "Missing " );
814
1
    expert_add_info_format( pinfo, cri_item, KIP_ERROR, "Expected: min 2 bytes" );
815
    //ok = 0;
816
1
  }
817
11
  else
818
11
  {
819
11
    proto_tree* cri_tree = proto_item_add_subtree( cri_item, ett_cri );
820
11
    proto_item* length_item = proto_tree_add_uint(cri_tree, hf_knxip_structure_length, tvb, offset, 1, struct_len);
821
11
    proto_item* type_item = NULL;
822
11
    uint8_t length_ok = 1;
823
824
11
    if( struct_len > remaining_len )
825
5
    {
826
5
      expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
827
5
      struct_len = (uint8_t) remaining_len;
828
      //ok = 0;
829
5
      length_ok = 0;
830
5
    }
831
832
11
    if( struct_len < 2 )
833
2
    {
834
2
      expert_add_info_format( pinfo, cri_item, KIP_ERROR, "Missing 1 byte Connection Type" );
835
      //ok = 0;
836
2
    }
837
9
    else
838
9
    {
839
9
      conn_type = tvb_get_uint8( tvb, offset + 1 );
840
9
      type_item = proto_tree_add_item( cri_tree, hf_knxip_connection_type, tvb, offset + 1, 1, ENC_BIG_ENDIAN );
841
9
      conn_type_name = try_val_to_str( conn_type, connection_type_vals );
842
9
      if( !conn_type_name )
843
5
      {
844
5
        proto_item_prepend_text( type_item, "? " );
845
5
        expert_add_info_format( pinfo, type_item, KIP_ERROR, "Unknown" );
846
        //ok = 0;
847
848
5
        if( struct_len > 2 )
849
4
        {
850
4
          knxip_tree_add_unknown_data( cri_tree, tvb, offset + 2, struct_len - 2 );
851
4
        }
852
5
      }
853
4
      else
854
4
      {
855
4
        proto_item_append_text( cri_item, " %s", conn_type_name );
856
4
        ok = 1;
857
858
4
        switch( conn_type )
859
4
        {
860
2
        case KIP_DEVICE_MGMT_CONNECTION:
861
2
        case KIP_REMLOG_CONNECTION:
862
2
        case KIP_REMCONF_CONNECTION:
863
2
        case KIP_OBJSVR_CONNECTION:
864
2
          if( struct_len > 2 )
865
2
          {
866
2
            expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 2 bytes" );
867
2
            length_ok = 0;
868
869
2
            knxip_tree_add_unknown_data( cri_tree, tvb, offset + 2, struct_len - 2 );
870
2
            ok = 0;
871
2
          }
872
2
          break;
873
874
2
        case KIP_TUNNEL_CONNECTION:
875
2
          if( (struct_len != 4) && (struct_len != 6) )
876
1
          {
877
1
            expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 4 or 6 bytes" );
878
1
            length_ok = 0;
879
1
            ok = 0;
880
1
          }
881
2
          if( struct_len >= 3 )
882
1
          {
883
1
            uint8_t knx_layer = tvb_get_uint8( tvb, offset + 2 );
884
1
            const char* knx_layer_name = try_val_to_str( knx_layer, knx_layer_vals );
885
1
            proto_item* layer_item = proto_tree_add_item( cri_tree, hf_knxip_knx_layer, tvb, offset + 2, 1, ENC_BIG_ENDIAN );
886
1
            proto_item_append_text( cri_item, ", Layer: %s", knx_layer_name ? knx_layer_name : "Unknown" );
887
1
            if( !knx_layer_name )
888
0
            {
889
0
              proto_item_prepend_text( layer_item, "? " );
890
0
              expert_add_info_format( pinfo, layer_item, KIP_ERROR, "Expected: 0x02" );
891
0
              ok = 0;
892
0
            }
893
894
1
            if( struct_len < 4 )
895
0
            {
896
0
              expert_add_info_format( pinfo, cri_item, KIP_ERROR, "Missing Reserved byte" );
897
0
              ok = 0;
898
0
            }
899
1
            else
900
1
            {
901
1
              knxip_tree_add_reserved( cri_tree, tvb, offset + 3, pinfo, &ok );
902
1
            }
903
1
            if( struct_len >= 6 )
904
0
            {
905
0
              knxip_tree_add_knx_address( cri_tree, hf_knxip_knx_address, tvb, offset + 4, &extra_text, pinfo->pool );
906
0
            }
907
1
            if( struct_len > 6 )
908
0
            {
909
0
              knxip_tree_add_unknown_data( cri_tree, tvb, offset + 6, struct_len - 6 );
910
0
              ok = 0;
911
0
            }
912
1
          }
913
2
          break;
914
4
        }
915
4
      }
916
9
    }
917
918
11
    if( !length_ok )
919
6
    {
920
6
      proto_item_prepend_text( length_item, "? " );
921
6
    }
922
11
  }
923
924
12
  conn_type_name = try_val_to_str( conn_type, conn_type_vals );
925
12
  if( !conn_type_name )
926
8
  {
927
8
    ok = 0;
928
8
  }
929
4
  else
930
4
  {
931
4
    if( pinfo )
932
4
    {
933
4
      column_info* cinfo = pinfo->cinfo;
934
4
      col_prepend_fstr( cinfo, COL_INFO, "%s ", conn_type_name );
935
4
      if (extra_text != NULL)
936
0
      {
937
0
        col_append_fstr( cinfo, COL_INFO, ", %s", extra_text);
938
0
      }
939
4
    }
940
941
4
    proto_item_append_text( item, ", %s", conn_type_name );
942
4
    if (extra_text != NULL)
943
0
    {
944
0
      proto_item_append_text( item, ", %s", extra_text);
945
0
    }
946
4
  }
947
948
12
  if( !ok )
949
12
  {
950
12
    proto_item_prepend_text( cri_item, "? " );
951
12
    if( p_ok ) *p_ok = 0;
952
12
  }
953
954
12
  *p_offset += struct_len;
955
12
  return struct_len;
956
12
}
957
958
/* Dissect CRD (= Connection Response Data)
959
*/
960
static uint8_t dissect_crd( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset, uint8_t* p_ok )
961
3
{
962
3
  int offset = *p_offset;
963
3
  int remaining_len = tvb_captured_length_remaining( tvb, offset );
964
3
  uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
965
3
  int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
966
967
3
  proto_item* crd_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "CRD" );
968
969
3
  uint8_t conn_type = 0;
970
3
  const char* conn_type_name = NULL;
971
3
  uint8_t ok = 0;
972
973
3
  if( struct_len <= 0 )
974
2
  {
975
2
    proto_item_prepend_text( crd_item, "Missing " );
976
2
    expert_add_info_format( pinfo, crd_item, KIP_ERROR, "Expected: min 2 bytes" );
977
    //ok = 0;
978
2
  }
979
1
  else
980
1
  {
981
1
    proto_tree* crd_tree = proto_item_add_subtree( crd_item, ett_crd );
982
1
    proto_item* length_item = proto_tree_add_uint(crd_tree, hf_knxip_structure_length, tvb, offset, 1, struct_len);
983
1
    proto_item* type_item = NULL;
984
1
    uint8_t length_ok = 1;
985
986
1
    if( struct_len > remaining_len )
987
0
    {
988
0
      expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
989
0
      struct_len = (uint8_t) remaining_len;
990
      //ok = 0;
991
0
      length_ok = 0;
992
0
    }
993
994
1
    if( struct_len < 2 )
995
0
    {
996
0
      expert_add_info_format( pinfo, crd_item, KIP_ERROR, "Missing 1 byte Connection Type" );
997
      //ok = 0;
998
0
    }
999
1
    else
1000
1
    {
1001
1
      conn_type = tvb_get_uint8( tvb, offset + 1 );
1002
1
      type_item = proto_tree_add_item( crd_tree, hf_knxip_connection_type, tvb, offset + 1, 1, ENC_BIG_ENDIAN );
1003
1
      conn_type_name = try_val_to_str( conn_type, connection_type_vals );
1004
1
      if( !conn_type_name )
1005
1
      {
1006
1
        proto_item_prepend_text( type_item, "? " );
1007
1
        expert_add_info_format( pinfo, type_item, KIP_ERROR, "Unknown" );
1008
        //ok = 0;
1009
1010
1
        if( struct_len > 2 )
1011
1
        {
1012
1
          knxip_tree_add_unknown_data( crd_tree, tvb, offset + 2, struct_len - 2 );
1013
1
        }
1014
1
      }
1015
0
      else
1016
0
      {
1017
0
        proto_item_append_text( crd_item, " %s", conn_type_name );
1018
0
        ok = 1;
1019
1020
0
        switch( conn_type )
1021
0
        {
1022
0
        case KIP_DEVICE_MGMT_CONNECTION:
1023
0
        case KIP_REMLOG_CONNECTION:
1024
0
        case KIP_REMCONF_CONNECTION:
1025
0
        case KIP_OBJSVR_CONNECTION:
1026
0
          if( struct_len > 2 )
1027
0
          {
1028
0
            expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 2 bytes" );
1029
0
            knxip_tree_add_unknown_data( crd_tree, tvb, offset + 2, struct_len - 2 );
1030
0
            ok = 0;
1031
0
            length_ok = 0;
1032
0
          }
1033
0
          break;
1034
1035
0
        case KIP_TUNNEL_CONNECTION:
1036
0
          if( struct_len != 4 )
1037
0
          {
1038
0
            expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 4 bytes" );
1039
0
            ok = 0;
1040
0
            length_ok = 0;
1041
0
          }
1042
1043
0
          if( struct_len < 4 )
1044
0
          {
1045
0
            expert_add_info_format( pinfo, crd_item, KIP_ERROR, "Missing 2 bytes KNX Address" );
1046
            //ok = 0;
1047
0
            if( struct_len > 2 )
1048
0
            {
1049
0
              knxip_tree_add_unknown_data( crd_tree, tvb, offset + 2, struct_len - 2 );
1050
0
            }
1051
0
          }
1052
0
          else
1053
0
          {
1054
0
            char* output;
1055
0
            knxip_tree_add_knx_address( crd_tree, hf_knxip_knx_address, tvb, offset + 2, &output, pinfo->pool );
1056
0
            proto_item_append_text( crd_item, ", KNX Address: %s", output );
1057
0
            col_append_fstr( pinfo->cinfo, COL_INFO, ", %s", output );
1058
0
            if( item )
1059
0
            {
1060
0
              proto_item_append_text( item, ", %s", output );
1061
0
            }
1062
0
            if( struct_len > 4 )
1063
0
            {
1064
0
              knxip_tree_add_unknown_data( crd_tree, tvb, offset + 4, struct_len - 4 );
1065
              //ok = 0;
1066
0
            }
1067
0
          }
1068
0
          break;
1069
0
        }
1070
0
      }
1071
1
    }
1072
1073
1
    if( !length_ok )
1074
0
    {
1075
0
      proto_item_prepend_text( length_item, "? " );
1076
0
    }
1077
1
  }
1078
1079
3
  conn_type_name = try_val_to_str( conn_type, conn_type_vals );
1080
3
  if( conn_type_name ) col_prepend_fstr( pinfo->cinfo, COL_INFO, "%s ", conn_type_name );
1081
3
  proto_item_append_text( item, ", %s", conn_type_name ? conn_type_name : "???" );
1082
1083
3
  if( !ok )
1084
3
  {
1085
3
    proto_item_prepend_text( crd_item, "? " );
1086
3
    if( p_ok ) *p_ok = 0;
1087
3
  }
1088
1089
3
  *p_offset += struct_len;
1090
3
  return struct_len;
1091
3
}
1092
1093
/* Dissect Connection Header
1094
*/
1095
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 )
1096
83
{
1097
83
  int offset = *p_offset;
1098
83
  int remaining_len = tvb_captured_length_remaining( tvb, offset );
1099
83
  uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
1100
83
  int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
1101
1102
83
  proto_item* cnhdr_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "Connection Header" );
1103
1104
83
  uint8_t ok = 0;
1105
83
  wmem_strbuf_t* info = wmem_strbuf_new(pinfo->pool, "#");
1106
1107
83
  if( struct_len <= 0 )
1108
6
  {
1109
6
    proto_item_prepend_text( cnhdr_item, "Missing " );
1110
6
    expert_add_info_format( pinfo, cnhdr_item, KIP_ERROR, "Expected: 4 bytes" );
1111
6
  }
1112
77
  else
1113
77
  {
1114
77
    proto_tree* cnhdr_tree = proto_item_add_subtree( cnhdr_item, ett_cnhdr );
1115
77
    proto_item* length_item = proto_tree_add_uint(cnhdr_tree, hf_knxip_structure_length, tvb, offset, 1, struct_len);
1116
1117
77
    int end_pos = offset + eff_struct_len;
1118
77
    offset++;
1119
1120
77
    if( struct_len == 4 )
1121
0
    {
1122
0
      ok = 1;
1123
0
    }
1124
77
    else
1125
77
    {
1126
77
      knxip_item_illegal_length( length_item, pinfo, "Expected: 4 bytes" );
1127
77
    }
1128
1129
77
    if( struct_len > remaining_len )
1130
3
    {
1131
3
      expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
1132
3
      struct_len = (uint8_t) remaining_len;
1133
1134
3
      if( ok )
1135
0
      {
1136
0
        proto_item_prepend_text( length_item, "? " );
1137
0
        ok = 0;
1138
0
      }
1139
3
    }
1140
1141
77
    if( struct_len < 2 )
1142
2
    {
1143
2
      expert_add_info_format( pinfo, cnhdr_item, KIP_ERROR, "Missing 1 byte Channel" );
1144
      //ok = 0;
1145
2
    }
1146
75
    else
1147
75
    {
1148
75
      wmem_strbuf_append_printf(info, "%02X:", tvb_get_uint8(tvb, offset));
1149
75
      proto_tree_add_item( cnhdr_tree, hf_knxip_channel, tvb, offset, 1, ENC_BIG_ENDIAN );
1150
75
      offset++;
1151
1152
75
      if( struct_len < 3 )
1153
1
      {
1154
1
        expert_add_info_format( pinfo, cnhdr_item, KIP_ERROR, "Missing 1 byte Sequence Counter" );
1155
        //ok = 0;
1156
1
      }
1157
74
      else
1158
74
      {
1159
74
        wmem_strbuf_append_printf(info, "%u", tvb_get_uint8(tvb, offset));
1160
74
        proto_tree_add_item( cnhdr_tree, hf_knxip_seq_counter, tvb, offset, 1, ENC_BIG_ENDIAN );
1161
74
        offset++;
1162
1163
74
        if( response )
1164
1
          wmem_strbuf_append_c(info, ' ');
1165
1166
74
        if( struct_len < 4 )
1167
1
        {
1168
1
          expert_add_info_format( pinfo, cnhdr_item, KIP_ERROR, "Missing 1 byte %s", response ? "Status" : "Reserved" );
1169
1
        }
1170
73
        else
1171
73
        {
1172
73
          if( response )
1173
1
          {
1174
1
            wmem_strbuf_append_printf(info, "%s", val_to_str(pinfo->pool, tvb_get_uint8( tvb, offset ), error_vals, "Error 0x%02x" ) );
1175
1
            knxip_tree_add_status( cnhdr_tree, tvb, offset );
1176
1
          }
1177
72
          else
1178
72
          {
1179
72
            knxip_tree_add_reserved( cnhdr_tree, tvb, offset, pinfo, &ok );
1180
72
          }
1181
1182
73
          offset++;
1183
73
        }
1184
74
      }
1185
1186
75
      if( offset < end_pos )
1187
73
      {
1188
73
        knxip_tree_add_unknown_data( cnhdr_tree, tvb, offset, end_pos - offset );
1189
        //ok = 0;
1190
73
      }
1191
1192
75
      proto_item_append_text( cnhdr_item, ": %s", wmem_strbuf_get_str(info) );
1193
75
    }
1194
77
  }
1195
1196
83
  col_append_fstr( pinfo->cinfo, COL_INFO, " %s", wmem_strbuf_get_str(info));
1197
83
  proto_item_append_text( item, ", %s", wmem_strbuf_get_str(info));
1198
1199
83
  if( !ok )
1200
83
  {
1201
83
    proto_item_prepend_text( cnhdr_item, "? " );
1202
83
    if( p_ok ) *p_ok = 0;
1203
83
  }
1204
1205
83
  *p_offset += struct_len;
1206
83
  return struct_len;
1207
83
}
1208
1209
/* Dissect tunneling feature frames.
1210
*/
1211
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 )
1212
6
{
1213
6
  column_info* cinfo = pinfo->cinfo;
1214
6
  int offset = *p_offset;
1215
6
  int remaining_len;
1216
6
  proto_item* node;
1217
6
  uint8_t c;
1218
6
  const char* name;
1219
6
  uint8_t ok = 1;
1220
6
  uint8_t isResponse = (service == KIP_TUNNELING_FEATURE_RESPONSE);
1221
6
  uint8_t status = 0;
1222
1223
  /* Connection Header */
1224
6
  dissect_cnhdr( tvb, pinfo, item, tree, &offset, &ok, false );
1225
1226
6
  remaining_len = tvb_captured_length_remaining( tvb, offset );
1227
1228
  /* 1 byte Feature Identifier */
1229
6
  if( remaining_len <= 0 )
1230
3
  {
1231
3
    proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Feature Identifier: expected 1 byte" );
1232
3
    ok = 0;
1233
3
  }
1234
3
  else
1235
3
  {
1236
3
    c = tvb_get_uint8( tvb, offset );
1237
3
    name = try_val_to_str( c, tunneling_feature_id_vals );
1238
3
    if( !name ) name = "Unknown";
1239
3
    node = proto_tree_add_item( tree, hf_knxip_tunnel_feature, tvb, offset, 1, ENC_BIG_ENDIAN );
1240
3
    proto_item_append_text( node, " = %s", name );
1241
3
    proto_item_append_text( item, " %s", name );
1242
3
    col_append_fstr( cinfo, COL_INFO, " %s", name );
1243
1244
3
    ++offset;
1245
3
    --remaining_len;
1246
3
  }
1247
1248
  /* 1 byte Return Code / Reserved */
1249
6
  name = isResponse ? "Status" : "Reserved";
1250
6
  if( remaining_len <= 0 )
1251
3
  {
1252
3
    proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? %s: expected 1 byte", name );
1253
3
    ok = 0;
1254
3
  }
1255
3
  else
1256
3
  {
1257
3
    status = tvb_get_uint8( tvb, offset );
1258
3
    proto_tree_add_item( tree, isResponse ? hf_knxip_status : hf_knxip_reserved, tvb, offset, 1, ENC_BIG_ENDIAN );
1259
1260
3
    if( isResponse && (status != 0 || remaining_len == 1) )
1261
0
    {
1262
0
      proto_item_append_text( item, " E=$%02X", status );
1263
0
      col_append_fstr( cinfo, COL_INFO, " E=$%02X", status );
1264
0
    }
1265
1266
3
    ++offset;
1267
3
    --remaining_len;
1268
3
  }
1269
1270
  /* Feature Value */
1271
6
  if( remaining_len <= 0 )
1272
3
  {
1273
3
    if( service != KIP_TUNNELING_FEATURE_GET && status == 0 )
1274
3
    {
1275
3
      proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Feature Value: missing" );
1276
3
      ok = 0;
1277
3
    }
1278
3
  }
1279
3
  else
1280
3
  {
1281
3
    node = knxip_tree_add_data( tree, tvb, offset, remaining_len, cinfo, item, "Feature Value", " $", " $" );
1282
3
    if( service == KIP_TUNNELING_FEATURE_GET )
1283
1
    {
1284
1
      expert_add_info_format( pinfo, node, KIP_ERROR, "Unexpected" );
1285
1
      ok = 0;
1286
1
    }
1287
3
    offset += remaining_len;
1288
3
  }
1289
1290
6
  *p_offset = offset;
1291
1292
6
  if( p_ok && !ok ) *p_ok = 0;
1293
6
}
1294
1295
/* Dissect cEMI
1296
*/
1297
static void dissect_cemi( tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int* p_offset )
1298
90
{
1299
90
  int offset = *p_offset;
1300
90
  int remaining_len = tvb_captured_length_remaining( tvb, offset );
1301
1302
  /* Call the cEMI data dissector for the remaining bytes
1303
  */
1304
90
  tvb = tvb_new_subset_remaining( tvb, offset );
1305
1306
90
  dissector_handle_t cemi_handle = find_dissector( "cemi" );
1307
90
  if( cemi_handle )
1308
90
  {
1309
90
    call_dissector( cemi_handle, tvb, pinfo, tree );
1310
90
  }
1311
1312
1313
90
  *p_offset = offset + remaining_len;
1314
90
}
1315
1316
/* Dissect ROUTING_LOSS
1317
*/
1318
static uint8_t dissect_routing_loss( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
1319
4
{
1320
4
  int offset = *p_offset;
1321
4
  int remaining_len = tvb_captured_length_remaining( tvb, offset );
1322
4
  uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
1323
4
  int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
1324
4
  uint8_t ok = 0;
1325
1326
4
  proto_item* info_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, struct_len, "Loss Info" );
1327
1328
4
  char* info = "???";
1329
1330
4
  if( struct_len <= 0 )
1331
1
  {
1332
1
    proto_item_prepend_text( info_item, "Missing " );
1333
1
    expert_add_info_format( pinfo, info_item, KIP_ERROR, "Expected: 4 bytes" );
1334
1
  }
1335
3
  else
1336
3
  {
1337
3
    proto_tree* info_tree = proto_item_add_subtree( info_item, ett_loss );
1338
3
    proto_item* length_item = proto_tree_add_uint(info_tree, hf_knxip_structure_length, tvb, offset, 1, struct_len);
1339
1340
3
    int end_pos = offset + eff_struct_len;
1341
3
    offset++;
1342
1343
3
    if( struct_len == 4 )
1344
0
    {
1345
0
      ok = 1;
1346
0
    }
1347
3
    else
1348
3
    {
1349
3
      expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 4 bytes" );
1350
3
    }
1351
1352
3
    if( struct_len > remaining_len )
1353
1
    {
1354
1
      expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
1355
1
      struct_len = (uint8_t) remaining_len;
1356
1
      ok = 0;
1357
1
    }
1358
1359
3
    if( !ok )
1360
3
    {
1361
3
      proto_item_prepend_text( length_item, "? " );
1362
3
    }
1363
1364
3
    if( struct_len >= 2 )
1365
3
    {
1366
3
      knxip_tree_add_status( info_tree, tvb, offset );
1367
3
      offset++;
1368
1369
      /* 2 bytes Lost Messages */
1370
3
      if( struct_len >= 4 )
1371
2
      {
1372
2
        uint32_t loss;
1373
2
        proto_tree_add_item_ret_uint( info_tree, hf_knxip_routing_loss, tvb, offset, 2, ENC_BIG_ENDIAN, &loss );
1374
2
        info = wmem_strdup_printf(pinfo->pool, "%u", loss);
1375
2
        offset += 2;
1376
2
      }
1377
1378
3
      if( offset < end_pos )
1379
2
      {
1380
2
        knxip_tree_add_unknown_data( info_tree, tvb, offset, end_pos - offset );
1381
2
      }
1382
1383
3
      proto_item_append_text( info_item, ": %s", info );
1384
3
    }
1385
3
  }
1386
1387
4
  if( pinfo ) col_append_fstr( pinfo->cinfo, COL_INFO, ": %s", info );
1388
4
  proto_item_append_text( item, ": %s", info );
1389
1390
4
  if( !ok )
1391
4
  {
1392
4
    proto_item_prepend_text( info_item, "? " );
1393
4
  }
1394
1395
4
  *p_offset += struct_len;
1396
4
  return ok;
1397
4
}
1398
1399
/* Dissect ROUTING_BUSY
1400
*/
1401
static uint8_t dissect_routing_busy( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
1402
3
{
1403
3
  int offset = *p_offset;
1404
3
  int remaining_len = tvb_captured_length_remaining( tvb, offset );
1405
3
  uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
1406
3
  int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
1407
3
  uint8_t ok = 0;
1408
1409
3
  proto_item* info_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "Busy Info" );
1410
1411
3
  char* info = "???";
1412
1413
3
  if( struct_len <= 0 )
1414
0
  {
1415
0
    proto_item_prepend_text( info_item, "Missing " );
1416
0
    expert_add_info_format( pinfo, info_item, KIP_ERROR, "Expected: 6 bytes" );
1417
0
  }
1418
3
  else
1419
3
  {
1420
3
    proto_tree* info_tree = proto_item_add_subtree( info_item, ett_loss );
1421
3
    proto_item* length_item = proto_tree_add_uint(info_tree, hf_knxip_structure_length, tvb, offset, 1, struct_len);
1422
1423
3
    int end_pos = offset + eff_struct_len;
1424
3
    offset++;
1425
1426
3
    if( struct_len == 6 )
1427
0
    {
1428
0
      ok = 1;
1429
0
    }
1430
3
    else
1431
3
    {
1432
3
      expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 6 bytes" );
1433
3
    }
1434
1435
3
    if( struct_len > remaining_len )
1436
1
    {
1437
1
      expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
1438
1
      struct_len = (uint8_t) remaining_len;
1439
1
      ok = 0;
1440
1
    }
1441
1442
3
    if( !ok )
1443
3
    {
1444
3
      proto_item_prepend_text( length_item, "? " );
1445
3
    }
1446
1447
3
    if( struct_len >= 2 )
1448
2
    {
1449
2
      knxip_tree_add_status( info_tree, tvb, offset );
1450
2
      offset++;
1451
1452
2
      if( struct_len >= 4 )
1453
2
      {
1454
        /* 2 bytes Wait Time (ms) */
1455
2
        uint32_t busy_time;
1456
2
        proto_tree_add_item_ret_uint( info_tree, hf_knxip_busy_time, tvb, offset, 2, ENC_BIG_ENDIAN, &busy_time );
1457
2
        info = wmem_strdup_printf(pinfo->pool, "%u ms", busy_time);
1458
2
        offset += 2;
1459
1460
2
        if( struct_len >= 6 )
1461
1
        {
1462
          /* 2 bytes Control */
1463
1
          proto_tree_add_item( info_tree, hf_knxip_busy_control, tvb, offset, 2, ENC_BIG_ENDIAN );
1464
1
          offset += 2;
1465
1
        }
1466
2
      }
1467
1468
2
      if( offset < end_pos )
1469
2
      {
1470
2
        knxip_tree_add_unknown_data( info_tree, tvb, offset, end_pos - offset );
1471
2
      }
1472
1473
2
      proto_item_append_text( info_item, ": %s", info );
1474
2
    }
1475
3
  }
1476
1477
3
  if( pinfo ) col_append_fstr( pinfo->cinfo, COL_INFO, ": %s", info );
1478
3
  proto_item_append_text( item, ": %s", info );
1479
1480
3
  if( !ok )
1481
3
  {
1482
3
    proto_item_prepend_text( info_item, "? " );
1483
3
  }
1484
1485
3
  *p_offset += struct_len;
1486
3
  return ok;
1487
3
}
1488
1489
/* Dissect SELECTOR field
1490
*/
1491
static uint8_t dissect_selector( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset, uint8_t* p_ok )
1492
10
{
1493
10
  int offset = *p_offset;
1494
10
  int remaining_len = tvb_captured_length_remaining( tvb, offset );
1495
10
  uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
1496
10
  int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
1497
10
  uint8_t ok = 0;
1498
1499
10
  proto_item* info_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "Selector" );
1500
1501
10
  char* info = "???";
1502
1503
10
  if( struct_len <= 0 )
1504
3
  {
1505
3
    proto_item_prepend_text( info_item, "Missing " );
1506
3
    expert_add_info_format( pinfo, info_item, KIP_ERROR, "Expected: min 2 bytes" );
1507
    //ok = 0;
1508
3
  }
1509
7
  else
1510
7
  {
1511
7
    proto_tree* info_tree = proto_item_add_subtree( info_item, ett_loss );
1512
7
    proto_item* length_item = proto_tree_add_uint(info_tree, hf_knxip_structure_length, tvb, offset, 1, struct_len);
1513
7
    uint8_t length_ok = 1;
1514
1515
7
    int end_pos = offset + eff_struct_len;
1516
7
    offset++;
1517
1518
7
    if( struct_len > remaining_len )
1519
3
    {
1520
3
      expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
1521
      //ok = 0;
1522
3
      length_ok = 0;
1523
3
      struct_len = (uint8_t) remaining_len;
1524
3
    }
1525
1526
7
    if( struct_len < 2 )
1527
0
    {
1528
0
      expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: min 2 bytes" );
1529
      //ok = 0;
1530
0
      length_ok = 0;
1531
0
    }
1532
7
    else
1533
7
    {
1534
      /* 1 byte Selection Type */
1535
7
      uint8_t sel = tvb_get_uint8( tvb, offset );
1536
7
      proto_item* type_item = proto_tree_add_item( info_tree, hf_knxip_selector, tvb, offset, 1, ENC_BIG_ENDIAN );
1537
7
      proto_item_append_text( type_item, " = %s", (sel == SELECT_PROGMODE) ? "ProgMode" : (sel == SELECT_MACADDRESS) ? "MAC" : "Unknown" );
1538
7
      offset++;
1539
7
      ok = 1;
1540
1541
7
      if( sel == SELECT_PROGMODE )
1542
0
      {
1543
0
        info = "ProgMode";
1544
1545
0
        if( struct_len != 2 )
1546
0
        {
1547
0
          expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 2 bytes" );
1548
0
          ok = 0;
1549
0
          length_ok = 0;
1550
0
        }
1551
0
      }
1552
7
      else if( sel == SELECT_MACADDRESS )
1553
3
      {
1554
3
        info = "MAC=???";
1555
1556
3
        if( struct_len != 8 )
1557
3
        {
1558
3
          expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: 8 bytes" );
1559
3
          ok = 0;
1560
3
          length_ok = 0;
1561
3
        }
1562
1563
3
        if( struct_len >= 8 )
1564
0
        {
1565
          /* 6 bytes MAC Address */
1566
0
          proto_tree_add_item( info_tree, hf_knxip_mac_address, tvb, offset, 6, ENC_NA );
1567
0
          info = wmem_strdup_printf(pinfo->pool, "MAC=%s", tvb_ether_to_str(pinfo->pool, tvb, offset));
1568
0
          offset += 6;
1569
0
        }
1570
3
      }
1571
4
      else
1572
4
      {
1573
4
        proto_item_prepend_text( type_item, "? " );
1574
4
        expert_add_info_format( pinfo, type_item, KIP_ERROR, "Unknown" );
1575
4
        ok = 0;
1576
4
      }
1577
1578
7
      if( offset < end_pos )
1579
4
      {
1580
4
        knxip_tree_add_unknown_data( info_tree, tvb, offset, end_pos - offset );
1581
4
        ok = 0;
1582
4
      }
1583
1584
7
      proto_item_append_text( info_item, ": %s", info );
1585
7
    }
1586
1587
7
    if( !length_ok )
1588
6
    {
1589
6
      proto_item_prepend_text( length_item, "? " );
1590
6
    }
1591
7
  }
1592
1593
10
  if( pinfo ) col_append_fstr( pinfo->cinfo, COL_INFO, " %s", info );
1594
10
  proto_item_append_text( item, ", %s", info );
1595
1596
10
  if( !ok )
1597
10
  {
1598
10
    proto_item_prepend_text( info_item, "? " );
1599
10
    if( p_ok ) *p_ok = 0;
1600
10
  }
1601
1602
10
  *p_offset += struct_len;
1603
10
  if( p_ok && !ok ) *p_ok = 0;
1604
10
  return struct_len;
1605
10
}
1606
1607
/* Dissect DevInfo DIB
1608
*/
1609
static uint8_t dissect_dib_devinfo( tvbuff_t* tvb, packet_info* pinfo,
1610
  proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
1611
  int* p_offset, uint8_t struct_len, wmem_strbuf_t* output )
1612
147
{
1613
147
  int offset = *p_offset;
1614
147
  wmem_strbuf_t* info = wmem_strbuf_new(pinfo->pool, "");
1615
147
  uint8_t prog_mode = 0;
1616
147
  uint8_t ok = 1;
1617
1618
147
  if( struct_len != 54 )
1619
147
  {
1620
147
    if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: 54 bytes" );
1621
147
    ok = 0;
1622
147
  }
1623
1624
147
  if( struct_len >= 3 )
1625
146
  {
1626
146
    static int* const knx_medium_flags[] = {
1627
146
        &hf_knxip_knx_medium_flags_ip,
1628
146
        &hf_knxip_knx_medium_flags_rf,
1629
146
        &hf_knxip_knx_medium_flags_pl132,
1630
146
        &hf_knxip_knx_medium_flags_pl110,
1631
146
        &hf_knxip_knx_medium_flags_tp1,
1632
146
        &hf_knxip_knx_medium_flags_tp0,
1633
146
        NULL
1634
146
    };
1635
1636
    /* 1 byte KNX Medium */
1637
146
    uint8_t knx_medium = tvb_get_uint8( tvb, offset );
1638
146
    proto_item* item = proto_tree_add_bitmask( dib_tree, tvb, offset, hf_knxip_knx_medium, ett_medium, knx_medium_flags, ENC_BIG_ENDIAN);
1639
1640
    /* Check for missing or multiple medium */
1641
146
    {
1642
146
      uint8_t data = knx_medium;
1643
146
      uint8_t media = 0;
1644
499
      while( data )
1645
353
      {
1646
353
        if( data & 1 )
1647
217
        {
1648
217
          media++;
1649
217
        }
1650
353
        data >>= 1;
1651
353
      }
1652
1653
146
      if( media != 1 )
1654
79
      {
1655
79
        expert_add_info_format( pinfo, item, KIP_WARNING, media ? "Multiple" : "Missing" );
1656
79
      }
1657
146
    }
1658
1659
146
    offset++;
1660
1661
146
    if( struct_len >= 4 )
1662
139
    {
1663
139
      static int* const knx_status_flags[] = {
1664
139
        &hf_knxip_program_mode,
1665
139
        NULL
1666
139
      };
1667
1668
      /* 1 byte Device Status */
1669
139
      uint8_t status = tvb_get_uint8(tvb, offset);
1670
139
      proto_tree_add_bitmask(dib_tree, tvb, offset, hf_knxip_device_status, ett_status, knx_status_flags, ENC_BIG_ENDIAN);
1671
139
      prog_mode = (status & 0x01);
1672
139
      offset++;
1673
1674
139
      if( struct_len >= 6 )
1675
89
      {
1676
        /* 2 bytes KNX Address */
1677
89
        char* addr;
1678
89
        knxip_tree_add_knx_address( dib_tree, hf_knxip_knx_address, tvb, offset, &addr, pinfo->pool );
1679
89
        wmem_strbuf_append( info, addr );
1680
1681
89
        offset += 2;
1682
1683
89
        if( struct_len >= 8 )
1684
81
        {
1685
          /* 2 bytes Project Installation Identifier */
1686
81
          uint16_t project_id = tvb_get_ntohs( tvb, offset );
1687
81
          item = proto_tree_add_item( dib_tree, hf_knxip_project_id, tvb, offset, 2, ENC_BIG_ENDIAN );
1688
81
          proto_tree* tree = proto_item_add_subtree( item, ett_projectid );
1689
81
          proto_tree_add_item( tree, hf_knxip_project_number, tvb, offset, 2, ENC_BIG_ENDIAN );
1690
81
          proto_tree_add_item( tree, hf_knxip_installation_number, tvb, offset, 2, ENC_BIG_ENDIAN );
1691
81
          proto_item_append_text( item, " (%u:%u)", project_id / 16, project_id % 16 );
1692
1693
81
          offset += 2;
1694
1695
81
          if( struct_len >= 14 )
1696
66
          {
1697
            /* 6 bytes KNX Serial Number */
1698
66
            proto_tree_add_item( dib_tree, hf_knxip_serial_number, tvb, offset, 6, ENC_BIG_ENDIAN );
1699
66
            offset += 6;
1700
66
          }
1701
1702
81
          if( struct_len >= 18 )
1703
60
          {
1704
            /* 4 bytes Routing Multicast Address */
1705
60
            proto_tree_add_item( dib_tree, hf_knxip_multicast_address, tvb, offset, 4, ENC_BIG_ENDIAN );
1706
60
            offset += 4;
1707
1708
60
            if( struct_len >= 24 )
1709
58
            {
1710
              /* 6 bytes MAC Address */
1711
58
              proto_tree_add_item( dib_tree, hf_knxip_mac_address, tvb, offset, 6, ENC_NA );
1712
58
              offset += 6;
1713
1714
58
              if( struct_len >= 54 )
1715
27
              {
1716
                /* 30 bytes Friendly Name - ISO 8859-1 */
1717
27
                char *friendly_name;
1718
1719
27
                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 );
1720
1721
27
                wmem_strbuf_append_printf( info, " \"%s\"", friendly_name );
1722
1723
27
                offset += 30;
1724
27
              }
1725
58
            }
1726
60
          }
1727
81
        }
1728
89
      }
1729
139
    }
1730
146
  }
1731
1732
147
  if( wmem_strbuf_get_len( info ) == 0 )
1733
58
  {
1734
58
    wmem_strbuf_append( info, "???" );
1735
58
  }
1736
147
  if( prog_mode )
1737
79
  {
1738
79
    wmem_strbuf_append( info, " PROGMODE" );
1739
79
  }
1740
147
  if( output )
1741
38
  {
1742
38
    wmem_strbuf_append( output, wmem_strbuf_get_str( info ) );
1743
38
  }
1744
147
  proto_item_append_text( dib_item, ": %s", wmem_strbuf_get_str( info ) );
1745
1746
147
  *p_offset = offset;
1747
147
  return ok;
1748
147
}
1749
1750
/* Dissect SuppSvc DIB
1751
*/
1752
static uint8_t dissect_dib_suppsvc( tvbuff_t* tvb, packet_info* pinfo,
1753
  proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
1754
  int* p_offset, uint8_t struct_len )
1755
502
{
1756
502
  int offset = *p_offset;
1757
502
  int end_pos = offset - 2 + struct_len;
1758
502
  uint8_t ok = 1;
1759
502
  char separator = ':';
1760
502
  uint8_t sf_count[ 8 ] = { 0 };
1761
1762
502
  if( struct_len & 1 )
1763
27
  {
1764
27
    if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: even number" );
1765
27
    ok = 0;
1766
27
  }
1767
1768
3.73k
  while( offset + 2 <= end_pos )
1769
3.23k
  {
1770
3.23k
    uint8_t service_family = tvb_get_uint8( tvb, offset );
1771
3.23k
    uint8_t version = tvb_get_uint8( tvb, offset + 1 );
1772
3.23k
    const char* service_family_name = try_val_to_str( service_family, knxip_service_family_vals );
1773
3.23k
    proto_item* item = proto_tree_add_none_format( dib_tree, hf_folder, tvb, offset, 2, "KNXnet/IP %s v%u",
1774
3.23k
      service_family_name ? service_family_name : "Unknown Service Family", version );
1775
3.23k
    proto_tree* tree = proto_item_add_subtree( item, ett_service_family );
1776
1777
    /* 1 byte Service Family ID */
1778
3.23k
    proto_tree_add_item( tree, hf_knxip_service_family, tvb, offset, 1, ENC_BIG_ENDIAN );
1779
1780
    /* 1 byte Service Family Version */
1781
3.23k
    proto_tree_add_item( tree, hf_knxip_service_version, tvb, offset + 1, 1, ENC_BIG_ENDIAN );
1782
1783
3.23k
    if( service_family >= KIP_SERVICE_TUNNELING && service_family_name )
1784
459
    {
1785
459
      proto_item_append_text( dib_item, "%c %s", separator, service_family_name );
1786
459
      separator = ',';
1787
459
    }
1788
1789
3.23k
    if( service_family < 8 )
1790
1.29k
    {
1791
1.29k
      ++sf_count[ service_family ];
1792
1.29k
    }
1793
1794
3.23k
    offset += 2;
1795
3.23k
  }
1796
1797
502
  if( !sf_count[ KIP_SERVICE_CORE ] )
1798
414
  {
1799
414
    expert_add_info_format( pinfo, dib_item, KIP_WARNING, "Missing: Core (0x02)" );
1800
414
  }
1801
502
  if( !sf_count[ KIP_SERVICE_MANAGEMENT ] )
1802
431
  {
1803
431
    expert_add_info_format( pinfo, dib_item, KIP_WARNING, "Missing: Device Management (0x03)" );
1804
431
  }
1805
1806
502
  *p_offset = offset;
1807
502
  return ok;
1808
502
}
1809
1810
/* Dissect IpConfig DIB
1811
*/
1812
static uint8_t dissect_dib_ipconfig( tvbuff_t* tvb, packet_info* pinfo,
1813
  proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
1814
  int* p_offset, uint8_t struct_len )
1815
400
{
1816
400
  int offset = *p_offset;
1817
400
  uint8_t ok = 1;
1818
400
  char* text;
1819
1820
400
  if( struct_len != 16 )
1821
400
  {
1822
400
    if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: 16 bytes" );
1823
400
    ok = 0;
1824
400
  }
1825
1826
400
  if( struct_len < 6 )
1827
357
  {
1828
357
    text = "???";
1829
357
  }
1830
43
  else
1831
43
  {
1832
    /* 4 bytes IP Address */
1833
43
    ws_in4_addr addr_ipv4;
1834
43
    proto_tree_add_item_ret_ipv4(dib_tree, hf_knxip_ip_address, tvb, offset, 4, ENC_BIG_ENDIAN, &addr_ipv4);
1835
43
    text = ip_addr_to_str(pinfo->pool, &addr_ipv4);
1836
43
    offset += 4;
1837
1838
43
    if( struct_len >= 10 )
1839
37
    {
1840
      /* 4 bytes Subnet Mask */
1841
37
      proto_tree_add_item( dib_tree, hf_knxip_ip_subnet, tvb, offset, 4, ENC_BIG_ENDIAN );
1842
37
      offset += 4;
1843
1844
37
      if( struct_len >= 14 )
1845
28
      {
1846
        /* 4 bytes Default Gateway */
1847
28
        proto_tree_add_item( dib_tree, hf_knxip_ip_gateway, tvb, offset, 4, ENC_BIG_ENDIAN );
1848
28
        offset += 4;
1849
1850
28
        if( struct_len >= 15 )
1851
27
        {
1852
27
          static int* const ip_caps_flags[] = {
1853
27
            &hf_knxip_ip_caps_auto,
1854
27
            &hf_knxip_ip_caps_dhcp,
1855
27
            &hf_knxip_ip_caps_bootp,
1856
27
            NULL
1857
27
          };
1858
1859
          /* 1 byte IP Capabilities */
1860
27
          proto_tree_add_bitmask_with_flags(dib_tree, tvb, offset, hf_knxip_ip_caps, ett_ip_assignment, ip_caps_flags, ENC_BIG_ENDIAN, BMT_NO_FALSE);
1861
27
          offset++;
1862
1863
27
          if( struct_len >= 16 )
1864
26
          {
1865
            /* 1 byte IP Assignment Method */
1866
26
            proto_tree_add_bitmask_with_flags(dib_tree, tvb, offset, hf_knxip_ip_assign, ett_ip_assignment, knx_ip_assign_flags, ENC_BIG_ENDIAN, BMT_NO_FALSE);
1867
26
            offset++;
1868
26
          }
1869
27
        }
1870
28
      }
1871
37
    }
1872
43
  }
1873
1874
400
  proto_item_append_text( dib_item, ": %s", text );
1875
1876
400
  *p_offset = offset;
1877
400
  return ok;
1878
400
}
1879
1880
/* Dissect CurConfig DIB
1881
*/
1882
static uint8_t dissect_dib_curconfig( tvbuff_t* tvb, packet_info* pinfo,
1883
  proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
1884
  int* p_offset, uint8_t struct_len )
1885
346
{
1886
346
  int offset = *p_offset;
1887
346
  uint8_t ok = 1;
1888
346
  char* text;
1889
1890
346
  if( struct_len != 20 )
1891
340
  {
1892
340
    if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: 20 bytes" );
1893
340
    ok = 0;
1894
340
  }
1895
1896
346
  if( struct_len < 6 )
1897
242
  {
1898
242
    text = "???" ;
1899
242
  }
1900
104
  else
1901
104
  {
1902
    /* 4 bytes IP Address */
1903
104
    ws_in4_addr addr_ipv4;
1904
104
    proto_tree_add_item_ret_ipv4(dib_tree, hf_knxip_ip_address, tvb, offset, 4, ENC_BIG_ENDIAN, &addr_ipv4);
1905
104
    text = ip_addr_to_str(pinfo->pool, &addr_ipv4);
1906
104
    offset += 4;
1907
1908
104
    if( struct_len >= 10 )
1909
41
    {
1910
      /* 4 bytes Subnet Mask */
1911
41
      proto_tree_add_item( dib_tree, hf_knxip_ip_subnet, tvb, offset, 4, ENC_BIG_ENDIAN );
1912
41
      offset += 4;
1913
1914
41
      if( struct_len >= 14 )
1915
37
      {
1916
        /* 4 bytes Default Gateway */
1917
37
        proto_tree_add_item( dib_tree, hf_knxip_ip_gateway, tvb, offset, 4, ENC_BIG_ENDIAN );
1918
37
        offset += 4;
1919
1920
37
        if( struct_len >= 18 )
1921
37
        {
1922
          /* 4 bytes DHCP Server */
1923
37
          proto_tree_add_item( dib_tree, hf_knxip_ip_dhcp, tvb, offset, 4, ENC_BIG_ENDIAN );
1924
37
          offset += 4;
1925
1926
37
          if( struct_len >= 19 )
1927
37
          {
1928
            /* IP Assignment Method */
1929
37
            proto_tree_add_bitmask_with_flags(dib_tree, tvb, offset, hf_knxip_ip_assign, ett_ip_assignment, knx_ip_assign_flags, ENC_BIG_ENDIAN, BMT_NO_FALSE);
1930
37
            offset++;
1931
1932
37
            if( struct_len >= 20 )
1933
36
            {
1934
              /* Reserved Byte */
1935
36
              knxip_tree_add_reserved( dib_tree, tvb, offset, pinfo, &ok );
1936
36
              offset++;
1937
36
            }
1938
37
          }
1939
37
        }
1940
37
      }
1941
41
    }
1942
104
  }
1943
1944
346
  proto_item_append_text( dib_item, ": %s", text );
1945
1946
346
  *p_offset = offset;
1947
346
  return ok;
1948
346
}
1949
1950
/* Dissect KnxAddr DIB
1951
*/
1952
static uint8_t dissect_dib_knxaddr( tvbuff_t* tvb, packet_info* pinfo,
1953
  proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
1954
  int* p_offset, uint8_t struct_len )
1955
109
{
1956
109
  int offset = *p_offset;
1957
109
  uint8_t ok = 1;
1958
109
  char* text1;
1959
109
  char* text2;
1960
1961
109
  if( struct_len < 4 )
1962
3
  {
1963
3
    if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: >= 4 bytes" );
1964
3
    text1 = "???";
1965
3
    ok = 0;
1966
3
  }
1967
106
  else
1968
106
  {
1969
106
    int end_pos = offset - 2 + struct_len;
1970
1971
106
    if( struct_len & 1 )
1972
86
    {
1973
86
      if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: even number" );
1974
86
      ok = 0;
1975
86
    }
1976
1977
    /* 2 bytes KNX Address */
1978
106
    knxip_tree_add_knx_address( dib_tree, hf_knxip_knx_address, tvb, offset, &text1, pinfo->pool);
1979
106
    proto_item_append_text( dib_item, ": %s", text1 );
1980
106
    offset += 2;
1981
1982
692
    while( offset + 2 <= end_pos )
1983
586
    {
1984
      /* 2 bytes Additional KNX Address */
1985
586
      knxip_tree_add_knx_address( dib_tree, hf_knxip_knx_address, tvb, offset, &text2, pinfo->pool);
1986
586
      proto_item_append_text( dib_item, ", %s", text2 );
1987
586
      offset += 2;
1988
586
    }
1989
106
  }
1990
1991
109
  *p_offset = offset;
1992
109
  return ok;
1993
109
}
1994
1995
/* Dissect SecuredServices DIB
1996
*/
1997
static uint8_t dissect_dib_secured_service_families( tvbuff_t* tvb, packet_info* pinfo,
1998
  proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
1999
  int* p_offset, uint8_t struct_len )
2000
262
{
2001
262
  int offset = *p_offset;
2002
262
  int end_pos = offset - 2 + struct_len;
2003
262
  uint8_t ok = 1;
2004
262
  char separator = ':';
2005
2006
262
  if( struct_len & 1 )
2007
18
  {
2008
18
    if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: even number" );
2009
18
    ok = 0;
2010
18
  }
2011
2012
1.31k
  while( offset + 2 <= end_pos )
2013
1.05k
  {
2014
1.05k
    uint8_t service_family = tvb_get_uint8( tvb, offset );
2015
1.05k
    uint8_t version = tvb_get_uint8( tvb, offset + 1 );
2016
1.05k
    const char* service_family_name = try_val_to_str( service_family, knxip_service_family_vals );
2017
1.05k
    proto_item* item = proto_tree_add_none_format( dib_tree, hf_folder, tvb, offset, 2, "KNXnet/IP %s v%u",
2018
1.05k
      service_family_name ? service_family_name : "Unknown Service Family", version );
2019
1.05k
    proto_tree* tree = proto_item_add_subtree( item, ett_service_family );
2020
2021
    /* 1 byte Service Family ID */
2022
1.05k
    proto_tree_add_item( tree, hf_knxip_service_family, tvb, offset, 1, ENC_BIG_ENDIAN );
2023
2024
    /* 1 byte Security Version */
2025
1.05k
    proto_tree_add_item( tree, hf_knxip_security_version, tvb, offset + 1, 1, ENC_BIG_ENDIAN );
2026
2027
1.05k
    if( service_family_name )
2028
717
    {
2029
717
      proto_item_append_text( dib_item, "%c %s", separator, service_family_name );
2030
717
      separator = ',';
2031
717
    }
2032
2033
1.05k
    offset += 2;
2034
1.05k
  }
2035
2036
262
  *p_offset = offset;
2037
262
  return ok;
2038
262
}
2039
2040
/* Dissect TunnelingInfo DIB
2041
*/
2042
static uint8_t dissect_dib_tunneling_info( tvbuff_t* tvb, packet_info* pinfo,
2043
  proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
2044
  int* p_offset, uint8_t struct_len )
2045
192
{
2046
192
  int offset = *p_offset;
2047
192
  uint8_t ok = 1;
2048
192
  static int* const tunnel_flags[] = {
2049
192
      &hf_knxip_knx_tunnel_usable,
2050
192
      &hf_knxip_knx_tunnel_authorized,
2051
192
      &hf_knxip_knx_tunnel_free,
2052
192
      NULL
2053
192
  };
2054
2055
192
  if( struct_len < 4 )
2056
8
  {
2057
8
    if( length_ok )
2058
4
    {
2059
4
      knxip_item_illegal_length( length_item, pinfo, "Expected: >= 4 bytes" );
2060
4
      ok = 0;
2061
4
    }
2062
8
  }
2063
184
  else
2064
184
  {
2065
184
    int end_pos = offset - 2 + struct_len;
2066
184
    char separator = ':';
2067
2068
    /* 2 bytes Max APDU Length */
2069
184
    proto_tree_add_item( dib_tree, hf_knxip_max_apdu_length, tvb, offset, 2, ENC_BIG_ENDIAN );
2070
184
    offset += 2;
2071
2072
184
    if( struct_len & 3 )
2073
154
    {
2074
154
      if( length_ok )
2075
145
      {
2076
145
        knxip_item_illegal_length( length_item, pinfo, "Expected: 4 + n * 4 bytes" );
2077
145
        ok = 0;
2078
145
      }
2079
154
    }
2080
2081
602
    while( offset + 4 <= end_pos )
2082
418
    {
2083
418
      uint8_t flags;
2084
418
      uint8_t is_free;
2085
418
      char* text;
2086
418
      proto_item* node;
2087
418
      proto_tree* list;
2088
2089
418
      node = proto_tree_add_none_format( dib_tree, hf_folder, tvb, offset, 4, "Tunneling Slot" );
2090
418
      list = proto_item_add_subtree( node, ett_tunnel );
2091
2092
      /* 2 bytes KNX Address, 1 byte reserved */
2093
418
      knxip_tree_add_knx_address( list, hf_knxip_knx_address, tvb, offset, &text, pinfo->pool );
2094
418
      offset += 3;
2095
2096
      /* 1 byte flags */
2097
418
      proto_tree_add_bitmask_list(list, tvb, offset, 1, tunnel_flags, ENC_BIG_ENDIAN);
2098
418
      flags = tvb_get_uint8(tvb, offset);
2099
418
      is_free = flags & 1;
2100
418
      proto_item_append_text(node, ": %s Free=%u", text, is_free);
2101
418
      offset++;
2102
2103
418
      if( !is_free )
2104
222
      {
2105
222
        proto_item_append_text( dib_item, "%c %s", separator, text );
2106
222
        separator = ',';
2107
222
      }
2108
418
    }
2109
184
  }
2110
2111
192
  *p_offset = offset;
2112
192
  return ok;
2113
192
}
2114
2115
/* Dissect ExtDevInfo DIB
2116
*/
2117
static uint8_t dissect_dib_extdevinfo( tvbuff_t* tvb, packet_info* pinfo,
2118
  proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
2119
  int* p_offset, uint8_t struct_len )
2120
106
{
2121
106
  int offset = *p_offset;
2122
106
  uint8_t status = 0;
2123
106
  uint8_t ok = 1;
2124
2125
106
  if( struct_len != 8 )
2126
27
  {
2127
27
    if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: 8 bytes" );
2128
27
    ok = 0;
2129
27
  }
2130
2131
106
  if( struct_len >= 3 )
2132
97
  {
2133
    /* 1 byte Medium Status */
2134
97
    status = tvb_get_uint8( tvb, offset );
2135
97
    proto_tree_add_item( dib_tree, hf_knxip_medium_status, tvb, offset, 1, ENC_BIG_ENDIAN );
2136
97
    if( status )
2137
92
    {
2138
92
      proto_item_append_text( dib_item, ": MediumStatus=$%02X", status );
2139
92
    }
2140
2141
97
    offset++;
2142
2143
97
    if( struct_len >= 4 )
2144
93
    {
2145
      /* 1 byte reserved */
2146
93
      knxip_tree_add_reserved( dib_tree, tvb, offset, pinfo, &ok );
2147
93
      offset++;
2148
2149
93
      if( struct_len >= 6 )
2150
90
      {
2151
        /* 2 bytes Max APDU Length */
2152
90
        proto_tree_add_item( dib_tree, hf_knxip_max_apdu_length, tvb, offset, 2, ENC_BIG_ENDIAN );
2153
90
        offset += 2;
2154
2155
90
        if( struct_len >= 8 )
2156
87
        {
2157
          /* 2 bytes Mask Version */
2158
87
          proto_tree_add_item( dib_tree, hf_knxip_mask_version, tvb, offset, 2, ENC_BIG_ENDIAN );
2159
87
          offset += 2;
2160
87
        }
2161
90
      }
2162
93
    }
2163
97
  }
2164
2165
106
  *p_offset = offset;
2166
106
  return ok;
2167
106
}
2168
2169
/* Dissect MfrData DIB
2170
*/
2171
static uint8_t dissect_dib_mfrdata( tvbuff_t* tvb, packet_info* pinfo,
2172
  proto_item* dib_item, proto_tree* dib_tree, proto_item* length_item, uint8_t length_ok,
2173
  int* p_offset, uint8_t struct_len )
2174
17
{
2175
17
  int offset = *p_offset;
2176
17
  uint8_t ok = 1;
2177
17
  char* text;
2178
2179
17
  if( struct_len < 4 )
2180
10
  {
2181
10
    if( length_ok ) knxip_item_illegal_length( length_item, pinfo, "Expected: >= 4 bytes" );
2182
10
    text = "???";
2183
10
    ok = 0;
2184
10
  }
2185
7
  else
2186
7
  {
2187
7
    uint32_t code;
2188
7
    proto_tree_add_item_ret_uint( dib_tree, hf_knxip_manufacturer_code, tvb, offset, 2, ENC_BIG_ENDIAN, &code);
2189
7
    text = wmem_strdup_printf(pinfo->pool, "0x%04x", code);
2190
7
    offset += 2;
2191
7
  }
2192
2193
17
  proto_item_append_text( dib_item, ": %s", text );
2194
2195
17
  *p_offset = offset;
2196
17
  return ok;
2197
17
}
2198
2199
/* Dissect DIB
2200
*/
2201
static uint8_t dissect_dib( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree,
2202
  int* p_offset, wmem_strbuf_t* output, char separator, uint8_t* p_count, uint8_t* p_ok )
2203
3.98k
{
2204
3.98k
  int offset = *p_offset;
2205
3.98k
  int remaining_len = tvb_captured_length_remaining( tvb, offset );
2206
3.98k
  uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
2207
3.98k
  if( struct_len > 0 )
2208
3.72k
  {
2209
3.72k
    int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
2210
3.72k
    int end_pos = offset + eff_struct_len;
2211
3.72k
    const char* dib_name = NULL;
2212
3.72k
    uint8_t dib_type = 0;
2213
3.72k
    uint8_t ok = 1;
2214
3.72k
    uint8_t length_ok = 1;
2215
2216
3.72k
    proto_item* dib_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "DIB" );
2217
3.72k
    proto_tree* dib_tree = proto_item_add_subtree( dib_item, ett_dib );
2218
3.72k
    proto_item* length_item = proto_tree_add_uint(dib_tree, hf_knxip_structure_length, tvb, offset, 1, struct_len);
2219
2220
3.72k
    offset++;
2221
2222
3.72k
    if( struct_len > remaining_len )
2223
194
    {
2224
194
      proto_item_prepend_text( length_item, "? " );
2225
194
      expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
2226
194
      struct_len = (uint8_t) remaining_len;
2227
194
      ok = 0;
2228
194
      length_ok = 0;
2229
194
    }
2230
2231
3.72k
    if( eff_struct_len < 2 )
2232
950
    {
2233
950
      expert_add_info_format( pinfo, dib_item, KIP_ERROR, "Missing 1 byte Description Type" );
2234
950
      ok = 0;
2235
950
    }
2236
2.77k
    else
2237
2.77k
    {
2238
2.77k
      proto_item* type_item = proto_tree_add_item( dib_tree, hf_knxip_description_type, tvb, offset, 1, ENC_BIG_ENDIAN );
2239
2240
2.77k
      dib_type = tvb_get_uint8( tvb, offset );
2241
2.77k
      dib_name = try_val_to_str( dib_type, descr_type_vals );
2242
2.77k
      offset++;
2243
2244
2.77k
      if( !dib_name )
2245
691
      {
2246
691
        proto_item_append_text( dib_item, " ???" );
2247
691
        proto_item_append_text( type_item, " (Unknown)" );
2248
691
      }
2249
2.08k
      else
2250
2.08k
      {
2251
2.08k
        proto_item_append_text( dib_item, " %s", dib_name );
2252
2.08k
      }
2253
2254
2.77k
      if( p_count )
2255
2.76k
      {
2256
2.76k
        ++p_count[ dib_type ];
2257
2.76k
      }
2258
2259
2.77k
      switch( dib_type )
2260
2.77k
      {
2261
147
      case KIP_DIB_DEVICE_INFO:
2262
147
        ok &= dissect_dib_devinfo( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len, output );
2263
147
        break;
2264
2265
502
      case KIP_DIB_SUPP_SVC_FAMILIES:
2266
502
        ok &= dissect_dib_suppsvc( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2267
502
        break;
2268
2269
400
      case KIP_DIB_IP_CONFIG:
2270
400
        ok &= dissect_dib_ipconfig( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2271
400
        break;
2272
2273
346
      case KIP_DIB_CUR_CONFIG:
2274
346
        ok &= dissect_dib_curconfig( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2275
346
        break;
2276
2277
109
      case KIP_DIB_KNX_ADDRESSES:
2278
109
        ok &= dissect_dib_knxaddr( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2279
109
        break;
2280
2281
262
      case KIP_DIB_SECURED_SERVICE_FAMILIES:
2282
262
        ok &= dissect_dib_secured_service_families( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2283
262
        break;
2284
2285
192
      case KIP_DIB_TUNNELING_INFO:
2286
192
        ok &= dissect_dib_tunneling_info( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2287
192
        break;
2288
2289
106
      case KIP_DIB_EXTENDED_DEVICE_INFO:
2290
106
        ok &= dissect_dib_extdevinfo( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2291
106
        break;
2292
2293
17
      case KIP_DIB_MFR_DATA:
2294
17
        ok &= dissect_dib_mfrdata( tvb, pinfo, dib_item, dib_tree, length_item, length_ok, &offset, struct_len );
2295
17
        break;
2296
2297
691
      default:
2298
691
        expert_add_info_format( pinfo, type_item, KIP_WARNING, "Unknown DIB Type" );
2299
691
        break;
2300
2.77k
      }
2301
2302
2.77k
      if( offset < end_pos )
2303
1.73k
      {
2304
1.73k
        knxip_tree_add_unknown_data( dib_tree, tvb, offset, end_pos - offset );
2305
1.73k
        offset =  end_pos;
2306
1.73k
      }
2307
2.77k
    }
2308
2309
3.72k
    if( !output )
2310
2.42k
    {
2311
2.42k
      if( pinfo )
2312
2.42k
      {
2313
2.42k
        column_info* cinfo = pinfo->cinfo;
2314
2.42k
        col_append_fstr( cinfo, COL_INFO, "%c ", separator );
2315
2316
2.42k
        if( !dib_name )
2317
1.26k
        {
2318
1.26k
          col_append_str( cinfo, COL_INFO, "???" );
2319
1.26k
        }
2320
1.15k
        else
2321
1.15k
        {
2322
1.15k
          if( !ok ) col_append_str( cinfo, COL_INFO, "? " );
2323
1.15k
          col_append_str( cinfo, COL_INFO, dib_name );
2324
1.15k
        }
2325
2.42k
      }
2326
2327
2.42k
      if( item )
2328
2.42k
      {
2329
2.42k
        proto_item_append_text( item, "%c ", separator );
2330
2331
2.42k
        if( !dib_name )
2332
1.26k
        {
2333
1.26k
          proto_item_append_text( item, "???" );
2334
1.26k
        }
2335
1.15k
        else
2336
1.15k
        {
2337
1.15k
          if( !ok ) proto_item_append_text( item, "? " );
2338
1.15k
          proto_item_append_text( item, "%s", dib_name );
2339
1.15k
        }
2340
2.42k
      }
2341
2.42k
    }
2342
2343
3.72k
    if( !ok )
2344
2.34k
    {
2345
2.34k
      proto_item_prepend_text( dib_item, "? " );
2346
2.34k
      if( p_ok ) *p_ok = 0;
2347
2.34k
    }
2348
2349
3.72k
    *p_offset = offset;
2350
3.72k
  }
2351
2352
3.98k
  return struct_len;
2353
3.98k
}
2354
2355
/* Dissect sequence of DIBs
2356
*/
2357
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 )
2358
258
{
2359
3.98k
  while( dissect_dib( tvb, pinfo, item, tree, p_offset, output, separator, p_count, p_ok ) )
2360
3.72k
  {
2361
3.72k
    separator = ',';
2362
3.72k
  }
2363
2364
258
  return separator;
2365
258
}
2366
2367
/* Dissect SRP
2368
*/
2369
static uint8_t dissect_srp( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset, uint8_t* p_ok )
2370
598
{
2371
598
  int offset = *p_offset;
2372
598
  int remaining_len = tvb_captured_length_remaining( tvb, offset );
2373
598
  uint8_t struct_len = (remaining_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
2374
598
  if( struct_len > 0 )
2375
547
  {
2376
547
    int eff_struct_len = (struct_len <= remaining_len) ? struct_len : remaining_len;
2377
547
    int end_pos = offset + eff_struct_len;
2378
547
    column_info* cinfo = pinfo ? pinfo->cinfo : NULL;
2379
547
    proto_item* srp_item = proto_tree_add_none_format( tree, hf_folder, tvb, offset, eff_struct_len, "SRP" );
2380
547
    proto_tree* srp_tree = proto_item_add_subtree( srp_item, ett_dib );
2381
547
    proto_item* length_item = proto_tree_add_uint(srp_tree, hf_knxip_structure_length, tvb, offset, 1, struct_len);
2382
547
    uint8_t ok = 1;
2383
547
    uint8_t length_ok = 1;
2384
2385
547
    offset++;
2386
2387
547
    if( struct_len > remaining_len )
2388
32
    {
2389
32
      expert_add_info_format( pinfo, length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
2390
32
      ok = 0;
2391
32
      length_ok = 0;
2392
32
    }
2393
2394
547
    if( eff_struct_len < 2 )
2395
105
    {
2396
105
      expert_add_info_format( pinfo, srp_item, KIP_ERROR, "Missing 1 byte SRP Type" );
2397
105
      ok = 0;
2398
105
    }
2399
442
    else
2400
442
    {
2401
      /* 1 bit Mandatory */
2402
442
      proto_tree_add_item( srp_tree, hf_knxip_srp_mandatory, tvb, offset, 1, ENC_BIG_ENDIAN );
2403
2404
      /* 7 bits SRP Type */
2405
442
      uint8_t srp_type = tvb_get_uint8( tvb, offset ) & 0x7F;
2406
442
      const char* srp_name = try_val_to_str( srp_type, srp_type_vals );
2407
442
      proto_item* type_item = proto_tree_add_item( srp_tree, hf_knxip_srp_type, tvb, offset, 1, ENC_BIG_ENDIAN );
2408
442
      uint8_t expected_len = 0;
2409
442
      uint8_t unknown = !srp_name;
2410
442
      if( unknown )
2411
213
      {
2412
213
        expert_add_info_format( pinfo, type_item, KIP_WARNING, "Unknown SRP Type" );
2413
213
        srp_name = "???";
2414
213
      }
2415
2416
442
      proto_item_append_text( srp_item, " %s", srp_name ? srp_name : "???" );
2417
442
      proto_item_append_text( type_item, " = %s", srp_name ? srp_name : "???" );
2418
2419
442
      if( !unknown )
2420
229
      {
2421
229
        col_append_fstr( cinfo, COL_INFO, " %s", srp_name );
2422
229
        proto_item_append_text( item, ", %s", srp_name );
2423
229
      }
2424
2425
442
      switch( srp_type )
2426
442
      {
2427
4
      case 1:
2428
4
        expected_len = 2;
2429
4
        break;
2430
144
      case 2:
2431
144
        expected_len = 8;
2432
144
        break;
2433
16
      case 3:
2434
16
        expected_len = 4;
2435
16
        break;
2436
442
      }
2437
2438
442
      if( expected_len )
2439
164
      {
2440
164
        if( struct_len != expected_len )
2441
163
        {
2442
163
          expert_add_info_format( pinfo, length_item, KIP_ERROR, "Expected: %u bytes", expected_len );
2443
163
          ok = 0;
2444
163
          length_ok = 0;
2445
163
        }
2446
164
      }
2447
442
      offset++;
2448
2449
442
      if( offset < end_pos )
2450
280
      {
2451
280
        knxip_tree_add_data( srp_tree, tvb, offset, end_pos - offset, srp_name ? cinfo : NULL, item, "Data", "=$", " = $" );
2452
2453
280
        proto_item_append_text( srp_item, ": $" );
2454
9.58k
        while( offset < end_pos )
2455
9.30k
        {
2456
9.30k
          proto_item_append_text( srp_item, " %02X", tvb_get_uint8( tvb, offset ) );
2457
9.30k
          ++offset;
2458
9.30k
        }
2459
2460
        //offset = end_pos;
2461
280
      }
2462
442
    }
2463
2464
547
    if( !ok )
2465
295
    {
2466
295
      proto_item_prepend_text( srp_item, "? " );
2467
295
      if( p_ok ) *p_ok = 0;
2468
295
    }
2469
2470
547
    if( !length_ok )
2471
190
    {
2472
190
      proto_item_prepend_text( length_item, "? " );
2473
190
    }
2474
2475
547
    *p_offset += struct_len;
2476
547
  }
2477
2478
598
  return struct_len;
2479
598
}
2480
2481
/* Dissect sequence of SRPs
2482
*/
2483
static void dissect_srps( tvbuff_t *tvb, packet_info *pinfo, proto_item *item, proto_tree *tree, int *p_offset, uint8_t* p_ok )
2484
51
{
2485
598
  while( dissect_srp( tvb, pinfo, item, tree, p_offset, p_ok ) );
2486
51
}
2487
2488
/* Dissect RESET command
2489
*/
2490
static uint8_t dissect_resetter( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
2491
3
{
2492
3
  uint8_t ok = 0;
2493
3
  int offset = *p_offset;
2494
3
  int remaining_len = tvb_captured_length_remaining( tvb, offset );
2495
3
  uint8_t struct_len = ((unsigned) remaining_len < 2) ? (uint8_t) remaining_len : 2;
2496
3
  uint8_t mode = (struct_len <= 0) ? 0 : tvb_get_uint8( tvb, offset );
2497
3
  const char* mode_name = (mode == 0x01) ? "Restart" : (mode == 0x02) ? "Master Reset" : NULL;
2498
3
  const char* mode_info = mode_name ? mode_name : "???";
2499
3
  proto_item* node;
2500
2501
3
  if( struct_len <= 0 )
2502
2
  {
2503
2
    proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Command, Reserved: expected 2 bytes" );
2504
2
  }
2505
1
  else
2506
1
  {
2507
    /* 1 byte Reset Command */
2508
1
    node = proto_tree_add_item( tree, hf_knxip_reset_command, tvb, offset, 1, ENC_BIG_ENDIAN );
2509
1
    proto_item_append_text( node, " = %s", mode_info );
2510
2511
1
    if( !mode_name )
2512
1
    {
2513
1
      expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 0x01 or 0x02" );
2514
1
    }
2515
0
    else
2516
0
    {
2517
0
      ok = 1;
2518
0
    }
2519
2520
1
    if( struct_len != 2 )
2521
0
    {
2522
0
      proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Reserved: expected 1 byte" );
2523
0
      ok = 0;
2524
0
    }
2525
1
    else
2526
1
    {
2527
      /* 1 byte Reserved */
2528
1
      knxip_tree_add_reserved( tree, tvb, offset + 1, pinfo, &ok );
2529
1
    }
2530
1
  }
2531
2532
3
  if( pinfo ) col_append_fstr( pinfo->cinfo, COL_INFO, ", %s", mode_info );
2533
3
  proto_item_append_text( item, ", %s", mode_info );
2534
2535
3
  *p_offset += struct_len;
2536
3
  return ok;
2537
3
}
2538
2539
/* Decrypt SECURE_WRAPPER. Returns decrypted part if MAC matches
2540
*/
2541
static uint8_t* decrypt_secure_wrapper(wmem_allocator_t* scope, const uint8_t* key, const uint8_t* data, int h_length, int p_length )
2542
0
{
2543
0
  uint8_t header_length = *data;
2544
0
  int a_length = header_length + 2;
2545
0
  if( a_length > h_length )
2546
0
  {
2547
0
    a_length = h_length;
2548
0
  }
2549
2550
0
  if( h_length >= header_length + 16 && p_length >= 16 )
2551
0
  {
2552
0
    const uint8_t* nonce = data + a_length;
2553
0
    uint8_t* decrypted = knxip_ccm_decrypt(scope, NULL, key, data + h_length, p_length, nonce, 14 );
2554
2555
0
    if( decrypted )
2556
0
    {
2557
      /* Calculate MAC */
2558
0
      uint8_t mac[ KNX_KEY_LENGTH ];
2559
0
      p_length -= 16;
2560
2561
0
      knxip_ccm_calc_cbc_mac( mac, key, data, a_length, decrypted, p_length, nonce, 14 );
2562
2563
      /* Check MAC */
2564
0
      if( memcmp( decrypted + p_length, mac, 16 ) != 0 )
2565
0
      {
2566
0
        wmem_free(scope, decrypted );
2567
0
        decrypted = NULL;
2568
0
      }
2569
0
    }
2570
2571
0
    return decrypted;
2572
0
  }
2573
2574
0
  return NULL;
2575
0
}
2576
2577
static const char* make_key_info(wmem_allocator_t* scope, const uint8_t* key, const char* context )
2578
0
{
2579
0
  uint8_t count;
2580
2581
0
  if( key  == NULL)
2582
0
    return "without key";
2583
2584
0
  wmem_strbuf_t* buf = wmem_strbuf_new(scope, "");
2585
0
  if (context)
2586
0
  {
2587
0
      wmem_strbuf_append_printf(buf, "with %s key", context);
2588
0
  }
2589
0
  else
2590
0
  {
2591
0
      wmem_strbuf_append(buf, "with key");
2592
0
  }
2593
2594
0
  for (count = 16; count; --count)
2595
0
  {
2596
0
      wmem_strbuf_append_printf(buf, " %02X", *key++);
2597
0
  }
2598
2599
0
  return wmem_strbuf_finalize(buf);
2600
0
}
2601
2602
/* Dissect SECURE_WRAPPER
2603
*/
2604
// NOLINTNEXTLINE(misc-no-recursion)
2605
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 )
2606
6
{
2607
6
  uint8_t ok = 1;
2608
6
  int offset = *p_offset;
2609
6
  int size = tvb_captured_length_remaining( tvb, offset );
2610
6
  column_info* cinfo = pinfo->cinfo;
2611
6
  const uint8_t* dest_addr = (pinfo->dst.type == AT_IPv4) ? (const uint8_t*) pinfo->dst.data : NULL;
2612
6
  proto_item* node;
2613
2614
  /* 2 bytes Session ID */
2615
6
  if( size < 2 )
2616
1
  {
2617
1
    node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Session" );
2618
1
    expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 2 bytes" );
2619
1
    ok = 0;
2620
1
  }
2621
5
  else
2622
5
  {
2623
5
    uint16_t session = tvb_get_ntohs( tvb, offset );
2624
5
    proto_tree_add_item( tree, hf_knxip_session, tvb, offset, 2, ENC_BIG_ENDIAN );
2625
2626
5
    if( session )
2627
3
    {
2628
3
      col_append_fstr( cinfo, COL_INFO, " #%04X", session );
2629
3
      proto_item_append_text( item, ", Session: $%04X", session );
2630
3
    }
2631
2632
5
    offset += 2;
2633
5
    size -= 2;
2634
2635
    /* 6 bytes Sequence Nr */
2636
5
    if( size < 6 )
2637
1
    {
2638
1
      node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Sequence Number" );
2639
1
      expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 6 bytes" );
2640
1
      ok = 0;
2641
1
    }
2642
4
    else
2643
4
    {
2644
4
      knxip_tree_add_data( tree, tvb, offset, 6, cinfo, item, "Sequence Number", " $", ", Seq Nr: $" );
2645
4
      offset += 6;
2646
4
      size -= 6;
2647
2648
      /* 6 bytes Serial Nr */
2649
4
      if( size < 6 )
2650
1
      {
2651
1
        node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Serial Number" );
2652
1
        expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 6 bytes" );
2653
1
        ok = 0;
2654
1
      }
2655
3
      else
2656
3
      {
2657
3
        knxip_tree_add_data( tree, tvb, offset, 6, cinfo, item, "Serial Number", ".", ", Ser Nr: $" );
2658
3
        offset += 6;
2659
3
        size -= 6;
2660
2661
        /* 2 bytes Tag */
2662
3
        if( size < 2 )
2663
1
        {
2664
1
          node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Tag" );
2665
1
          expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 2 bytes" );
2666
1
          ok = 0;
2667
1
        }
2668
2
        else
2669
2
        {
2670
2
          uint16_t tag = tvb_get_ntohs( tvb, offset );
2671
2
          proto_tree_add_item( tree, hf_knxip_tag, tvb, offset, 2, ENC_BIG_ENDIAN );
2672
2
          col_append_fstr( cinfo, COL_INFO, ".%04X", tag );
2673
2
          proto_item_append_text( item, ", Tag: $%04X", tag );
2674
2
          offset += 2;
2675
2
          size -= 2;
2676
2677
          /* Encrypted part */
2678
2
          if( size < 16 )
2679
1
          {
2680
1
            node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Encrypted" );
2681
1
            expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: min 16 bytes" );
2682
1
            ok = 0;
2683
1
          }
2684
1
          else
2685
1
          {
2686
1
            const uint8_t* encrypted = tvb_get_ptr( tvb, offset, size );
2687
1
            const int a_length = header_length + 16;  // length of leading non-encrypted data
2688
1
            const uint8_t* a_data = encrypted - a_length;  // ptr to KIP header
2689
1
            uint8_t* decrypted = NULL;
2690
1
            const uint8_t* key = NULL;
2691
1
            const char* decrypt_info = NULL;
2692
1
            struct knx_keyring_mca_keys* mca_key;
2693
1
            uint8_t key_index;
2694
2695
1
            node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, encrypted, "Encrypted (%d bytes)", size );
2696
2697
1
            if( dest_addr )
2698
0
            {
2699
              // Try keys associateD with IP MCA in keyring.XML
2700
0
              for( mca_key = knx_keyring_mca_keys; mca_key; mca_key = mca_key->next )
2701
0
              {
2702
0
                if( memcmp( mca_key->mca, dest_addr, 4 ) == 0 )
2703
0
                {
2704
0
                  key = mca_key->key;
2705
0
                  decrypted = decrypt_secure_wrapper(pinfo->pool, key, a_data, a_length, size );
2706
0
                  if( decrypted )
2707
0
                  {
2708
0
                    decrypt_info = make_key_info(pinfo->pool, key, "MCA");
2709
0
                    break;
2710
0
                  }
2711
0
                }
2712
0
              }
2713
0
            }
2714
2715
1
            if( !decrypted )
2716
1
            {
2717
              // Try explicitly specified keys
2718
1
              for( key_index = 0; key_index < knx_decryption_key_count; ++key_index )
2719
0
              {
2720
0
                key = knx_decryption_keys[ key_index ];
2721
0
                decrypted = decrypt_secure_wrapper(pinfo->pool, key, a_data, a_length, size );
2722
0
                if( decrypted )
2723
0
                {
2724
0
                  decrypt_info = make_key_info(pinfo->pool, key, NULL );
2725
0
                  break;
2726
0
                }
2727
0
              }
2728
1
            }
2729
2730
1
            if( !decrypted )
2731
1
            {
2732
1
              const char* text = knx_decryption_key_count ? " (decryption failed)" : knx_keyring_mca_keys ? " (no key found)" : " (no key available)";
2733
1
              proto_item_append_text( node, "%s", text );
2734
1
            }
2735
0
            else
2736
0
            {
2737
0
              tvbuff_t* tvb2 = tvb_new_child_real_data( tvb, decrypted, size, size );
2738
0
              int size2 = size - 16;
2739
0
              proto_item_append_text( item, ", MAC OK" );
2740
              //tvb_set_free_cb( tvb2, wmem_free );
2741
0
              add_new_data_source( pinfo, tvb2, "Decrypted" );
2742
2743
0
              item = proto_tree_add_none_format( root, hf_folder, tvb2, 0, size, "Decrypted" );
2744
0
              tree = proto_item_add_subtree( item, ett_decrypted );
2745
2746
0
              if ( decrypt_info != NULL )
2747
0
              {
2748
0
                proto_item_append_text( item, " (%s)", decrypt_info );
2749
0
              }
2750
2751
              /* Embedded KIP packet */
2752
0
              knxip_tree_add_data( tree, tvb2, 0, size2, NULL, NULL, "Embedded KNXnet/IP packet", NULL, NULL );
2753
2754
              /* MAC */
2755
0
              knxip_tree_add_data( tree, tvb2, size2, 16, NULL, NULL, "Message Authentication Code", NULL, NULL );
2756
2757
              /* Dissect embedded KIP packet */
2758
0
              {
2759
0
                tvbuff_t* tvb3 = tvb_new_subset_length( tvb2, 0, size2 );
2760
0
                increment_dissection_depth(pinfo);
2761
0
                dissect_knxip( tvb3, pinfo, root, NULL );
2762
0
                decrement_dissection_depth(pinfo);
2763
0
              }
2764
0
            }
2765
1
          }
2766
2
        }
2767
3
      }
2768
4
    }
2769
5
  }
2770
2771
6
  *p_offset = offset + size;
2772
6
  return ok;
2773
6
}
2774
2775
/* Check encrypted MAC in TIMER_NOTIFY
2776
*/
2777
static uint8_t check_timer_sync_mac(wmem_allocator_t* scope, const uint8_t* key, const uint8_t* data, int header_length )
2778
0
{
2779
  // Calculate and encrypt MAC
2780
0
  const uint8_t* nonce = data + header_length;
2781
0
  uint8_t mac[ KNX_KEY_LENGTH ];
2782
0
  knxip_ccm_calc_cbc_mac(mac, key, data, header_length, NULL, 0, nonce, 14 );
2783
0
  knxip_ccm_encrypt( scope, mac, key, NULL, 0, mac, nonce, 14 );
2784
2785
  // Check MAC
2786
0
  return (memcmp( nonce + 14, mac, 16 ) == 0);
2787
0
}
2788
2789
/* Dissect TIMER_NOTIFY
2790
*/
2791
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 )
2792
0
{
2793
0
  uint8_t ok = 1;
2794
0
  int offset = *p_offset;
2795
0
  int size = tvb_captured_length_remaining( tvb, offset );
2796
0
  column_info* cinfo = pinfo->cinfo;
2797
0
  const uint8_t* dest_addr = (pinfo->dst.type == AT_IPv4) ? (const uint8_t*) pinfo->dst.data : NULL;
2798
0
  proto_item* node;
2799
2800
  /* 6 bytes Timestamp */
2801
0
  if( size < 6 )
2802
0
  {
2803
0
    node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Timestamp" );
2804
0
    expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 6 bytes" );
2805
0
    ok = 0;
2806
0
  }
2807
0
  else
2808
0
  {
2809
0
    knxip_tree_add_data( tree, tvb, offset, 6, cinfo, item, "Timestamp", " $", ", Timestamp: $" );
2810
0
    offset += 6;
2811
0
    size -= 6;
2812
2813
    /* 6 bytes Serial Nr */
2814
0
    if( size < 6 )
2815
0
    {
2816
0
      node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Serial Number" );
2817
0
      expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 6 bytes" );
2818
0
      ok = 0;
2819
0
    }
2820
0
    else
2821
0
    {
2822
0
      knxip_tree_add_data( tree, tvb, offset, 6, cinfo, item, "Serial Number", ".", ", Ser Nr: $" );
2823
0
      offset += 6;
2824
0
      size -= 6;
2825
2826
      /* 2 bytes Tag */
2827
0
      if( size < 2 )
2828
0
      {
2829
0
        node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Tag" );
2830
0
        expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 2 bytes" );
2831
0
        ok = 0;
2832
0
      }
2833
0
      else
2834
0
      {
2835
0
        uint16_t tag = tvb_get_ntohs( tvb, offset );
2836
0
        proto_tree_add_item( tree, hf_knxip_tag, tvb, offset, 2, ENC_BIG_ENDIAN );
2837
0
        col_append_fstr( cinfo, COL_INFO, ".%04X", tag );
2838
0
        proto_item_append_text( item, ", Tag: $%04X", tag );
2839
0
        offset += 2;
2840
0
        size -= 2;
2841
2842
        /* 16 bytes MAC */
2843
0
        if( size < 16 )
2844
0
        {
2845
0
          node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Message Authentication Code" );
2846
0
          expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 16 bytes" );
2847
0
          ok = 0;
2848
0
        }
2849
0
        else
2850
0
        {
2851
0
          const int a_length = header_length + 14;  // length of leading non-encrypted data
2852
0
          const uint8_t* a_data = tvb_get_ptr( tvb, offset - a_length, a_length + 16 );
2853
0
          const uint8_t* key = NULL;
2854
0
          uint8_t mac_ok = 0;
2855
0
          uint8_t mac_error = 0;
2856
0
          const char* mac_info = NULL;
2857
0
          struct knx_keyring_mca_keys* mca_key;
2858
0
          uint8_t key_index;
2859
2860
0
          knxip_tree_add_data( tree, tvb, offset, 16, NULL, NULL, "Message Authentication Code", NULL, NULL );
2861
2862
0
          if( dest_addr )
2863
0
          {
2864
            // Try keys associated with IP MCA in keyring.XML
2865
0
            for( mca_key = knx_keyring_mca_keys; mca_key; mca_key = mca_key->next )
2866
0
            {
2867
0
              if( memcmp( mca_key->mca, dest_addr, 4 ) == 0 )
2868
0
              {
2869
0
                key = mca_key->key;
2870
0
                if( check_timer_sync_mac(pinfo->pool, key, a_data, header_length ) )
2871
0
                {
2872
0
                  mac_ok = 1;
2873
0
                  mac_info = make_key_info(pinfo->pool, key, "MCA");
2874
0
                  break;
2875
0
                }
2876
0
              }
2877
0
            }
2878
0
          }
2879
2880
0
          if( !mac_ok )
2881
0
          {
2882
            // Try explicitly specified keys
2883
0
            for( key_index = 0; key_index < knx_decryption_key_count; ++key_index )
2884
0
            {
2885
0
              key = knx_decryption_keys[ key_index ];
2886
0
              if( check_timer_sync_mac(pinfo->pool, key, a_data, header_length ) )
2887
0
              {
2888
0
                mac_ok = 1;
2889
0
                mac_info = make_key_info(pinfo->pool, key, NULL );
2890
0
                break;
2891
0
              }
2892
0
            }
2893
0
          }
2894
2895
0
          if( mac_ok )
2896
0
          {
2897
0
            node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "MAC OK" );
2898
0
            col_append_str( cinfo, COL_INFO, " OK" );
2899
0
            proto_item_append_text( item, ", MAC OK" );
2900
2901
0
            if ( mac_info != NULL )
2902
0
            {
2903
0
              proto_item_append_text( node, " (%s)", mac_info );
2904
0
            }
2905
2906
      /* TODO: mac_error is never being set... */
2907
0
            if( mac_error )
2908
0
            {
2909
0
              expert_add_info_format( pinfo, node, KIP_WARNING, "OK with wrong key" );
2910
0
              col_append_str( cinfo, COL_INFO, " (!)" );
2911
0
              proto_item_append_text( item, " (!)" );
2912
0
            }
2913
0
          }
2914
2915
0
          offset += 16;
2916
0
          size = 0;
2917
0
        }
2918
0
      }
2919
0
    }
2920
0
  }
2921
2922
0
  *p_offset = offset + size;
2923
0
  return ok;
2924
0
}
2925
2926
/* Dissect SESSION_REQUEST
2927
*/
2928
static uint8_t dissect_session_request( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
2929
9
{
2930
9
  uint8_t ok = 1;
2931
9
  int offset = *p_offset;
2932
2933
  /* Control Endpoint HPAI */
2934
9
  if( dissect_hpai( tvb, pinfo, item, tree, &offset, &ok, "Control", 1 ) )
2935
8
  {
2936
8
    int size = tvb_captured_length_remaining( tvb, offset );
2937
8
    proto_item* node;
2938
2939
    /* DH Client Public Value */
2940
8
    if( size <= 0 )
2941
1
    {
2942
1
      proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? DH Client Public Value: missing" );
2943
1
      ok = 0;
2944
1
    }
2945
7
    else
2946
7
    {
2947
7
      node = knxip_tree_add_data( tree, tvb, offset, size, NULL, NULL, "DH Client Public Value", NULL, NULL );
2948
2949
7
#if ECDH_PUBLIC_VALUE_SIZE > 0
2950
7
      if( size != ECDH_PUBLIC_VALUE_SIZE )
2951
6
      {
2952
6
        proto_item_prepend_text( node, "? " );
2953
6
        expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: %u bytes", ECDH_PUBLIC_VALUE_SIZE );
2954
6
        ok = 0;
2955
6
      }
2956
7
#endif
2957
2958
7
      offset += size;
2959
7
    }
2960
8
  }
2961
2962
9
  *p_offset = offset;
2963
9
  return ok;
2964
9
}
2965
2966
/* Dissect SESSION_RESPONSE
2967
*/
2968
static uint8_t dissect_session_response( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
2969
7
{
2970
7
  uint8_t ok = 1;
2971
7
  int offset = *p_offset;
2972
7
  column_info* cinfo = pinfo->cinfo;
2973
7
  int size = tvb_captured_length_remaining( tvb, offset );
2974
7
  proto_item *node;
2975
2976
  /* 2 bytes Session ID */
2977
7
  if( size < 2 )
2978
1
  {
2979
1
    node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Session" );
2980
1
    expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 2 bytes" );
2981
1
    offset += size;
2982
1
    ok = 0;
2983
1
  }
2984
6
  else
2985
6
  {
2986
6
    uint16_t session = tvb_get_ntohs( tvb, offset );
2987
6
    col_append_fstr( cinfo, COL_INFO, " #%04X", session );
2988
6
    proto_item_append_text( item, " #%04X", session );
2989
6
    proto_tree_add_item( tree, hf_knxip_session, tvb, offset, 2, ENC_BIG_ENDIAN );
2990
6
    offset += 2;
2991
6
    size -= 2;
2992
2993
    /* DH Server Public Value */
2994
6
    {
2995
6
      int size2 = size - 16;
2996
6
      if( size2 < 0 )
2997
1
      {
2998
1
        size2 = 0;
2999
1
      }
3000
3001
6
      node = knxip_tree_add_data( tree, tvb, offset, size2, NULL, NULL, "DH Server Public Value", NULL, NULL );
3002
3003
6
      if( size2 != ECDH_PUBLIC_VALUE_SIZE )
3004
6
      {
3005
6
        proto_item_prepend_text( node, "? " );
3006
6
        expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: %u bytes", ECDH_PUBLIC_VALUE_SIZE );
3007
6
        ok = 0;
3008
6
      }
3009
3010
6
      offset += size2;
3011
6
      size -= size2;
3012
6
    }
3013
3014
    /* 16 bytes MAC */
3015
6
    if( size < 16 )
3016
1
    {
3017
1
      node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Message Authentication Code" );
3018
1
      expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 16 bytes" );
3019
1
      offset += size;
3020
1
      ok = 0;
3021
1
    }
3022
5
    else
3023
5
    {
3024
5
      knxip_tree_add_data( tree, tvb, offset, 16, NULL, NULL, "Message Authentication Code", NULL, NULL );
3025
5
      offset += 16;
3026
5
    }
3027
6
  }
3028
3029
7
  *p_offset = offset;
3030
7
  return ok;
3031
7
}
3032
3033
/* Dissect SESSION_AUTHENTICATE
3034
*/
3035
static uint8_t dissect_session_auth( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
3036
3
{
3037
3
  uint8_t ok = 1;
3038
3
  int offset = *p_offset;
3039
3
  column_info* cinfo = pinfo->cinfo;
3040
3
  int size = tvb_captured_length_remaining( tvb, offset );
3041
3
  proto_item* node;
3042
3043
  /* 1 byte Reserved */
3044
3
  if( size <= 0 )
3045
1
  {
3046
1
    proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Reserved: expected 1 byte" );
3047
1
    ok = 0;
3048
1
  }
3049
2
  else
3050
2
  {
3051
2
    knxip_tree_add_reserved( tree, tvb, offset, pinfo, &ok );
3052
2
    ++offset;
3053
2
    --size;
3054
3055
    /* 1 byte User ID */
3056
2
    if( size <= 0 )
3057
0
    {
3058
0
      proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? User: expected 1 byte" );
3059
0
      ok = 0;
3060
0
    }
3061
2
    else
3062
2
    {
3063
2
      uint8_t user_id = tvb_get_uint8( tvb, offset );
3064
2
      col_append_fstr( cinfo, COL_INFO, " User=%u", user_id );
3065
2
      proto_item_append_text( item, ", User = %u", user_id );
3066
2
      proto_tree_add_item( tree, hf_knxip_user, tvb, offset, 1, ENC_BIG_ENDIAN );
3067
2
      ++offset;
3068
2
      --size;
3069
3070
      /* 16 bytes MAC */
3071
2
      if( size < 16 )
3072
1
      {
3073
1
        node = proto_tree_add_bytes_format( tree, hf_bytes, tvb, offset, size, NULL, "? Message Authentication Code" );
3074
1
        expert_add_info_format( pinfo, node, KIP_ERROR, "Expected: 16 bytes" );
3075
1
        offset += size;
3076
1
        ok = 0;
3077
1
      }
3078
1
      else
3079
1
      {
3080
1
        knxip_tree_add_data( tree, tvb, offset, 16, NULL, NULL, "Message Authentication Code", NULL, NULL );
3081
1
        offset += 16;
3082
1
      }
3083
2
    }
3084
2
  }
3085
3086
3
  *p_offset = offset;
3087
3
  return ok;
3088
3
}
3089
3090
/* Dissect SESSION_STATUS
3091
*/
3092
static uint8_t dissect_session_status( tvbuff_t* tvb, packet_info* pinfo, proto_item* item, proto_tree* tree, int* p_offset )
3093
0
{
3094
0
  uint8_t ok = 1;
3095
0
  int offset = *p_offset;
3096
0
  column_info* cinfo = pinfo->cinfo;
3097
0
  int size = tvb_captured_length_remaining( tvb, offset );
3098
3099
  /* 1 byte Status */
3100
0
  if( size <= 0 )
3101
0
  {
3102
0
    proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Status: expected 1 byte" );
3103
0
    ok = 0;
3104
0
  }
3105
0
  else
3106
0
  {
3107
0
    uint8_t status = tvb_get_uint8( tvb, offset );
3108
0
    col_append_fstr( cinfo, COL_INFO, " %u", status );
3109
0
    proto_item_append_text( item, ": %u", status );
3110
0
    proto_tree_add_item( tree, hf_knxip_session_status, tvb, offset, 1, ENC_BIG_ENDIAN );
3111
0
    ++offset;
3112
0
    --size;
3113
3114
    /* 1 byte Reserved */
3115
0
    if( size <= 0 )
3116
0
    {
3117
0
      proto_tree_add_expert_format( tree, pinfo, KIP_ERROR, tvb, offset, 0, "? Reserved: expected 1 byte" );
3118
0
      ok = 0;
3119
0
    }
3120
0
    else
3121
0
    {
3122
0
      knxip_tree_add_reserved( tree, tvb, offset, pinfo, &ok );
3123
0
      ++offset;
3124
0
      --size;
3125
0
    }
3126
0
  }
3127
3128
0
  *p_offset = offset;
3129
0
  return ok;
3130
0
}
3131
3132
/* Dissect KNX-IP data after KNX-IP header
3133
*/
3134
// NOLINTNEXTLINE(misc-no-recursion)
3135
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 )
3136
551
{
3137
551
  uint8_t ok = 1;
3138
551
  uint8_t service_family = (service >> 8);
3139
551
  const char* service_family_name = try_val_to_str( service_family, knxip_service_family_vals );
3140
551
  const char* service_name = try_val_to_str( service, knxip_service_type_vals );
3141
551
  const char* svc_name = try_val_to_str( service, svc_vals );
3142
551
  int offset = header_length;
3143
551
  int remaining_len = tvb_captured_length_remaining( tvb, offset );
3144
3145
  /* Make sure that we cope with a well known service family
3146
  */
3147
551
  if( service_family_name == NULL )
3148
48
  {
3149
48
    col_set_str(pinfo->cinfo, COL_INFO, "Unknown Service Family" );
3150
48
    proto_item_append_text( kip_item, " Unknown Service Family" );
3151
48
    ok = 0;
3152
48
  }
3153
503
  else
3154
503
  {
3155
    /* Make sure that we cope with a well known service type
3156
    */
3157
503
    if( service_name == NULL )
3158
12
    {
3159
12
      col_append_fstr(pinfo->cinfo, COL_INFO, "%s: ? Unknown Service Type", service_family_name );
3160
12
      proto_item_append_text( kip_item, " Unknown Service Type" );
3161
12
      ok = 0;
3162
12
    }
3163
491
    else
3164
491
    {
3165
491
      col_append_str(pinfo->cinfo, COL_INFO, svc_name ? svc_name : service_name );
3166
491
      proto_item_append_text( kip_item, " %s", service_name );
3167
3168
      /* Dissect according to Service Type
3169
      */
3170
491
      switch( service )
3171
491
      {
3172
3173
        /* CORE */
3174
3175
1
      case KIP_SEARCH_REQUEST:
3176
1
        {
3177
          /* Discovery Endpoint HPAI */
3178
1
          dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Discovery", 1 );
3179
1
        }
3180
1
        break;
3181
3182
53
      case KIP_SEARCH_REQUEST_EXT:
3183
53
        {
3184
          /* Discovery Endpoint HPAI */
3185
53
          if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Discovery", 0 ) )
3186
51
          {
3187
            /* Search Request Parameters */
3188
51
            dissect_srps( tvb, pinfo, kip_item, kip_tree, &offset, &ok );
3189
51
          }
3190
53
        }
3191
53
        break;
3192
3193
118
      case KIP_SEARCH_RESPONSE:
3194
123
      case KIP_SEARCH_RESPONSE_EXT:
3195
123
        {
3196
          /* Control Endpoint HPAI */
3197
123
          if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Control", 0 ) )
3198
118
          {
3199
            /* DIBs */
3200
118
            uint8_t dib_count[ 256 ] = { 0 };
3201
118
            wmem_strbuf_t* output;
3202
118
            char *info;
3203
3204
118
            output = wmem_strbuf_new(pinfo->pool, "");
3205
118
            dissect_dibs( tvb, pinfo, kip_item, kip_tree, &offset, output, '\0', dib_count, &ok );
3206
118
            info = wmem_strbuf_finalize(output);
3207
118
            if( *info )
3208
25
            {
3209
25
              col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", info );
3210
25
              proto_item_append_text( kip_item, ", %s", info );
3211
25
            }
3212
3213
118
            if( service == KIP_SEARCH_RESPONSE )
3214
114
            {
3215
114
              if( !dib_count[ KIP_DIB_DEVICE_INFO ] )
3216
91
              {
3217
91
                expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB DevInfo" );
3218
91
                ok = 0;
3219
91
              }
3220
114
              if( !dib_count[ KIP_DIB_SUPP_SVC_FAMILIES ] )
3221
59
              {
3222
59
                expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB SuppSvc" );
3223
59
                ok = 0;
3224
59
              }
3225
114
            }
3226
118
          }
3227
123
        }
3228
123
        break;
3229
3230
1
      case KIP_DESCRIPTION_REQUEST:
3231
1
        {
3232
          /* Control Endpoint HPAI */
3233
1
          dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Control", 1 );
3234
1
        }
3235
1
        break;
3236
3237
136
      case KIP_DESCRIPTION_RESPONSE:
3238
136
        {
3239
          /* DIBs */
3240
136
          uint8_t dib_count[ 256 ] = { 0 };
3241
136
          dissect_dibs( tvb, pinfo, kip_item, kip_tree, &offset, NULL, ':', dib_count, &ok );
3242
136
          if( !dib_count[ KIP_DIB_DEVICE_INFO ] )
3243
85
          {
3244
85
            expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB DevInfo" );
3245
85
            ok = 0;
3246
85
          }
3247
136
          if( !dib_count[ KIP_DIB_SUPP_SVC_FAMILIES ] )
3248
85
          {
3249
85
            expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB SuppSvc" );
3250
85
            ok = 0;
3251
85
          }
3252
136
        }
3253
136
        break;
3254
3255
17
      case KIP_CONNECT_REQUEST:
3256
17
        {
3257
          /* Control Endpoint HPAI */
3258
17
          if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Control", 1 ) )
3259
15
          {
3260
            /* Data Endpoint HPAI */
3261
15
            if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Data", 1 ) )
3262
12
            {
3263
              /* CRI */
3264
12
              dissect_cri( tvb, pinfo, kip_item, kip_tree, &offset, &ok );
3265
12
            }
3266
15
          }
3267
17
        }
3268
17
        break;
3269
3270
9
      case KIP_CONNECT_RESPONSE:
3271
9
        {
3272
          /* 1 byte Channel ID */
3273
9
          if( remaining_len < 1 )
3274
1
          {
3275
1
            col_append_str(pinfo->cinfo, COL_INFO, " ???" );
3276
1
            proto_item_append_text( kip_item, ", ???" );
3277
1
            expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Channel" );
3278
1
            ok = 0;
3279
1
          }
3280
8
          else
3281
8
          {
3282
8
            uint8_t channel = tvb_get_uint8( tvb, offset );
3283
8
            proto_tree_add_item( kip_tree, hf_knxip_channel, tvb, offset, 1, ENC_BIG_ENDIAN );
3284
8
            offset++;
3285
3286
            /* 1 byte Status */
3287
8
            if( remaining_len < 2 )
3288
1
            {
3289
1
              col_append_str(pinfo->cinfo, COL_INFO, " ???" );
3290
1
              proto_item_append_text( kip_item, ", ???" );
3291
1
              expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Status" );
3292
1
              ok = 0;
3293
1
            }
3294
7
            else
3295
7
            {
3296
7
              uint8_t status = tvb_get_uint8( tvb, offset );
3297
7
              knxip_tree_add_status( kip_tree, tvb, offset );
3298
7
              offset++;
3299
3300
7
              if( status == KIP_E_NO_ERROR )
3301
5
              {
3302
5
                col_append_fstr(pinfo->cinfo, COL_INFO, " #%02X", channel );
3303
5
                proto_item_append_text( kip_item, ", Conn #%02X", channel );
3304
3305
                /* Data Endpoint HPAI */
3306
5
                if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Data", 1 ) )
3307
3
                {
3308
                  /* CRD */
3309
3
                  dissect_crd( tvb, pinfo, kip_item, kip_tree, &offset, &ok );
3310
3
                }
3311
5
              }
3312
2
              else
3313
2
              {
3314
2
                const char* status_info = val_to_str(pinfo->pool, status, error_vals, "Error 0x%02x" );
3315
2
                col_append_fstr(pinfo->cinfo, COL_INFO, " %s", status_info );
3316
2
                proto_item_append_text( kip_item, ": %s", status_info );
3317
2
              }
3318
7
            }
3319
8
          }
3320
9
        }
3321
9
        break;
3322
3323
3
      case KIP_CONNECTIONSTATE_REQUEST:
3324
3
        {
3325
          /* 1 byte Channel ID */
3326
3
          col_append_str(pinfo->cinfo, COL_INFO, " #" );
3327
3
          proto_item_append_text( kip_item, ", Conn #" );
3328
3329
3
          if( remaining_len < 1 )
3330
1
          {
3331
1
            col_append_str(pinfo->cinfo, COL_INFO, "???" );
3332
1
            proto_item_append_text( kip_item, "???" );
3333
1
            expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Channel" );
3334
1
            ok = 0;
3335
1
          }
3336
2
          else
3337
2
          {
3338
2
            uint8_t channel = tvb_get_uint8( tvb, offset );
3339
2
            col_append_fstr(pinfo->cinfo, COL_INFO, "%02X", channel );
3340
2
            proto_item_append_text( kip_item, "%02X", channel );
3341
2
            proto_tree_add_item( kip_tree, hf_knxip_channel, tvb, offset, 1, ENC_BIG_ENDIAN );
3342
2
            offset++;
3343
3344
            /* Reserved Byte */
3345
2
            if( remaining_len < 2 )
3346
0
            {
3347
0
              knxip_tree_add_missing_reserved( kip_tree, tvb, offset, pinfo );
3348
0
              ok = 0;
3349
0
            }
3350
2
            else
3351
2
            {
3352
2
              knxip_tree_add_reserved( kip_tree, tvb, offset, pinfo, &ok );
3353
2
              offset++;
3354
3355
              /* Control Endpoint HPAI */
3356
2
              dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Control", 1 );
3357
2
            }
3358
2
          }
3359
3
        }
3360
3
        break;
3361
3362
3
      case KIP_CONNECTIONSTATE_RESPONSE:
3363
3
        {
3364
          /* 1 byte Channel ID */
3365
3
          col_append_str(pinfo->cinfo, COL_INFO, " #" );
3366
3
          proto_item_append_text( kip_item, ", Conn #" );
3367
3368
3
          if( remaining_len < 1 )
3369
1
          {
3370
1
            col_append_str(pinfo->cinfo, COL_INFO, "???" );
3371
1
            proto_item_append_text( kip_item, "???" );
3372
1
            expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Channel" );
3373
1
            ok = 0;
3374
1
          }
3375
2
          else
3376
2
          {
3377
2
            uint8_t channel = tvb_get_uint8( tvb, offset );
3378
2
            col_append_fstr(pinfo->cinfo, COL_INFO, "%02X ", channel );
3379
2
            proto_item_append_text( kip_item, "%02X: ", channel );
3380
2
            proto_tree_add_item( kip_tree, hf_knxip_channel, tvb, offset, 1, ENC_BIG_ENDIAN );
3381
2
            offset++;
3382
3383
            /* 1 byte Status */
3384
2
            if( remaining_len < 2 )
3385
0
            {
3386
0
              col_append_str(pinfo->cinfo, COL_INFO, "???" );
3387
0
              proto_item_append_text( kip_item, "???" );
3388
0
              expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Status" );
3389
0
              ok = 0;
3390
0
            }
3391
2
            else
3392
2
            {
3393
2
              uint8_t status = tvb_get_uint8( tvb, offset );
3394
2
              const char* status_info = val_to_str(pinfo->pool, status, error_vals, "Error 0x%02x" );
3395
2
              col_append_str(pinfo->cinfo, COL_INFO, status_info );
3396
2
              proto_item_append_text( kip_item, "%s", status_info );
3397
2
              knxip_tree_add_status( kip_tree, tvb, offset );
3398
2
              offset++;
3399
2
            }
3400
2
          }
3401
3
        }
3402
3
        break;
3403
3404
0
      case KIP_DISCONNECT_REQUEST:
3405
0
        {
3406
          /* 1 byte Channel ID */
3407
0
          col_append_str(pinfo->cinfo, COL_INFO, " #" );
3408
0
          proto_item_append_text( kip_item, ", Conn #" );
3409
3410
0
          if( remaining_len < 1 )
3411
0
          {
3412
0
            col_append_str(pinfo->cinfo, COL_INFO, "???" );
3413
0
            proto_item_append_text( kip_item, "???" );
3414
0
            expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Channel" );
3415
0
            ok = 0;
3416
0
          }
3417
0
          else
3418
0
          {
3419
0
            uint8_t channel = tvb_get_uint8( tvb, offset );
3420
0
            col_append_fstr(pinfo->cinfo, COL_INFO, "%02X", channel );
3421
0
            proto_item_append_text( kip_item, "%02X", channel );
3422
0
            proto_tree_add_item( kip_tree, hf_knxip_channel, tvb, offset, 1, ENC_BIG_ENDIAN );
3423
0
            offset++;
3424
3425
            /* Reserved Byte */
3426
0
            if( remaining_len < 2 )
3427
0
            {
3428
0
              knxip_tree_add_missing_reserved( kip_tree, tvb, offset, pinfo );
3429
0
              ok = 0;
3430
0
            }
3431
0
            else
3432
0
            {
3433
0
              knxip_tree_add_reserved( kip_tree, tvb, offset, pinfo, &ok );
3434
0
              offset++;
3435
3436
              /* Control Endpoint HPAI */
3437
0
              dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Control", 1 );
3438
0
            }
3439
0
          }
3440
0
        }
3441
0
        break;
3442
3443
3
      case KIP_DISCONNECT_RESPONSE:
3444
3
        {
3445
          /* 1 byte Channel ID */
3446
3
          col_append_str(pinfo->cinfo, COL_INFO, " #" );
3447
3
          proto_item_append_text( kip_item, ", Conn #" );
3448
3449
3
          if( remaining_len < 1 )
3450
1
          {
3451
1
            col_append_str(pinfo->cinfo, COL_INFO, "???" );
3452
1
            proto_item_append_text( kip_item, "???" );
3453
1
            expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Channel" );
3454
1
            ok = 0;
3455
1
          }
3456
2
          else
3457
2
          {
3458
2
            uint8_t channel = tvb_get_uint8( tvb, offset );
3459
2
            col_append_fstr(pinfo->cinfo, COL_INFO, "%02X ", channel );
3460
2
            proto_item_append_text( kip_item, "%02X: ", channel );
3461
2
            proto_tree_add_item( kip_tree, hf_knxip_channel, tvb, offset, 1, ENC_BIG_ENDIAN );
3462
2
            offset++;
3463
3464
            /* 1 byte Status */
3465
2
            if( remaining_len < 2 )
3466
0
            {
3467
0
              col_append_str(pinfo->cinfo, COL_INFO, "???" );
3468
0
              proto_item_append_text( kip_item, "???" );
3469
0
              expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing 1 byte Status" );
3470
0
              ok = 0;
3471
0
            }
3472
2
            else
3473
2
            {
3474
2
              uint8_t status = tvb_get_uint8( tvb, offset );
3475
2
              const char* status_info = val_to_str(pinfo->pool, status, error_vals, "Error 0x%02x" );
3476
2
              col_append_str(pinfo->cinfo, COL_INFO, status_info );
3477
2
              proto_item_append_text( kip_item, "%s", status_info );
3478
2
              knxip_tree_add_status( kip_tree, tvb, offset );
3479
2
              offset++;
3480
2
            }
3481
2
          }
3482
3
        }
3483
3
        break;
3484
3485
        /* MANAGEMENT */
3486
3487
75
      case KIP_CONFIGURATION_REQUEST:
3488
75
        {
3489
          /* Connection Header */
3490
75
          if( dissect_cnhdr( tvb, pinfo, kip_item, kip_tree, &offset, &ok, false ) )
3491
73
          {
3492
            /* cEMI */
3493
73
            dissect_cemi( tvb, pinfo, tree, &offset );
3494
73
          }
3495
75
        }
3496
75
        break;
3497
3498
1
      case KIP_CONFIGURATION_ACK:
3499
1
        {
3500
          /* Connection Header */
3501
1
          dissect_cnhdr( tvb, pinfo, kip_item, kip_tree, &offset, &ok, true );
3502
1
        }
3503
1
        break;
3504
3505
        /* TUNNELING */
3506
3507
1
      case KIP_TUNNELING_REQUEST:
3508
1
        {
3509
          /* Connection Header */
3510
1
          if( dissect_cnhdr( tvb, pinfo, kip_item, kip_tree, &offset, &ok, false ) )
3511
0
          {
3512
            /* cEMI */
3513
0
            dissect_cemi( tvb, pinfo, tree, &offset );
3514
0
          }
3515
1
        }
3516
1
        break;
3517
3518
0
      case KIP_TUNNELING_ACK:
3519
0
        {
3520
          /* Connection Header */
3521
0
          dissect_cnhdr( tvb, pinfo, kip_item, kip_tree, &offset, &ok, true );
3522
0
        }
3523
0
        break;
3524
3525
1
      case KIP_TUNNELING_FEATURE_GET:
3526
1
      case KIP_TUNNELING_FEATURE_RESPONSE:
3527
5
      case KIP_TUNNELING_FEATURE_SET:
3528
6
      case KIP_TUNNELING_FEATURE_INFO:
3529
6
        {
3530
          /* Connection Header, 1 byte Feature ID, 1 byte Return Code, Feature Value */
3531
6
          dissect_tunneling_feature( tvb, pinfo, kip_item, kip_tree, &offset, &ok, service );
3532
6
        }
3533
6
        break;
3534
3535
        /* ROUTING */
3536
3537
2
      case KIP_ROUTING_INDICATION:
3538
2
        {
3539
          /* cEMI */
3540
2
          dissect_cemi( tvb, pinfo, tree, &offset );
3541
2
        }
3542
2
        break;
3543
3544
4
      case KIP_ROUTING_LOST_MESSAGE:
3545
4
        {
3546
          /* Routing Loss */
3547
4
          ok &= dissect_routing_loss( tvb, pinfo, kip_item, kip_tree, &offset );
3548
4
        }
3549
4
        break;
3550
3551
3
      case KIP_ROUTING_BUSY:
3552
3
        {
3553
          /* Routing Busy */
3554
3
          ok &= dissect_routing_busy( tvb, pinfo, kip_item, kip_tree, &offset );
3555
3
        }
3556
3
        break;
3557
3558
15
      case KIP_ROUTING_SYSTEM_BROADCAST:
3559
15
        {
3560
          /* cEMI */
3561
15
          dissect_cemi( tvb, pinfo, tree, &offset );
3562
15
        }
3563
15
        break;
3564
3565
        /* REMOTE_DIAG_AND_CONFIG */
3566
3567
0
      case KIP_REMOTE_DIAG_REQUEST:
3568
0
        {
3569
          /* Discovery Endpoint HPAI */
3570
0
          if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Discovery", 0 ) )
3571
0
          {
3572
            /* Selector */
3573
0
            dissect_selector( tvb, pinfo, kip_item, kip_tree, &offset, &ok );
3574
0
          }
3575
0
        }
3576
0
        break;
3577
3578
1
      case KIP_REMOTE_DIAG_RESPONSE:
3579
1
        {
3580
          /* Selector */
3581
1
          if( dissect_selector( tvb, pinfo, kip_item, kip_tree, &offset, &ok ) )
3582
0
          {
3583
            /* DIBs */
3584
0
            uint8_t dib_count[ 256 ] = { 0 };
3585
0
            dissect_dibs( tvb, pinfo, kip_item, kip_tree, &offset, NULL, ',', dib_count, &ok );
3586
0
            if( !dib_count[ KIP_DIB_IP_CONFIG ] )
3587
0
            {
3588
0
              expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB IpConfig" );
3589
0
              ok = 0;
3590
0
            }
3591
0
            if( !dib_count[ KIP_DIB_CUR_CONFIG ] )
3592
0
            {
3593
0
              expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB CurConfig" );
3594
0
              ok = 0;
3595
0
            }
3596
0
            if( !dib_count[ KIP_DIB_KNX_ADDRESSES ] )
3597
0
            {
3598
0
              expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Missing DIB KnxAddr" );
3599
0
              ok = 0;
3600
0
            }
3601
0
          }
3602
1
        }
3603
1
        break;
3604
3605
5
      case KIP_REMOTE_CONFIG_REQUEST:
3606
5
        {
3607
          /* Discovery Endpoint HPAI */
3608
5
          if( dissect_hpai( tvb, pinfo, kip_item, kip_tree, &offset, &ok, "Discovery", 0 ) )
3609
5
          {
3610
            /* Selector */
3611
5
            if( dissect_selector( tvb, pinfo, kip_item, kip_tree, &offset, &ok ) )
3612
4
            {
3613
              /* DIBs */
3614
4
              int old_offset = offset;
3615
4
              dissect_dibs( tvb, pinfo, kip_item, kip_tree, &offset, NULL, ',', NULL, &ok );
3616
4
              if( offset <= old_offset )
3617
1
              {
3618
1
                expert_add_info_format( pinfo, kip_item, KIP_WARNING, "Missing DIB" );
3619
1
              }
3620
4
            }
3621
5
          }
3622
5
        }
3623
5
        break;
3624
3625
4
      case KIP_REMOTE_RESET_REQUEST:
3626
4
        {
3627
          /* Selector */
3628
4
          if( dissect_selector( tvb, pinfo, kip_item, kip_tree, &offset, &ok ) )
3629
3
          {
3630
            /* Reset Mode */
3631
3
            ok &= dissect_resetter( tvb, pinfo, kip_item, kip_tree, &offset );
3632
3
          }
3633
4
        }
3634
4
        break;
3635
3636
6
      case KIP_SECURE_WRAPPER:
3637
6
        ok &= dissect_secure_wrapper( header_length, tvb, pinfo, tree, kip_item, kip_tree, &offset );
3638
6
        break;
3639
3640
0
      case KIP_TIMER_NOTIFY:
3641
0
        ok &= dissect_timer_notify( header_length, tvb, pinfo, kip_item, kip_tree, &offset );
3642
0
        break;
3643
3644
9
      case KIP_SESSION_REQUEST:
3645
9
        ok &= dissect_session_request( tvb, pinfo, kip_item, kip_tree, &offset );
3646
9
        break;
3647
3648
7
      case KIP_SESSION_RESPONSE:
3649
7
        ok &= dissect_session_response( tvb, pinfo, kip_item, kip_tree, &offset );
3650
7
        break;
3651
3652
3
      case KIP_SESSION_AUTHENTICATE:
3653
3
        ok &= dissect_session_auth( tvb, pinfo, kip_item, kip_tree, &offset );
3654
3
        break;
3655
3656
0
      case KIP_SESSION_STATUS:
3657
0
        ok &= dissect_session_status( tvb, pinfo, kip_item, kip_tree, &offset );
3658
0
        break;
3659
491
      }
3660
491
    }
3661
503
  }
3662
3663
551
  if( offset >= 0 )
3664
551
  {
3665
551
    remaining_len = tvb_captured_length_remaining( tvb, offset );
3666
551
    if( remaining_len > 0 )
3667
139
    {
3668
139
      if( tree )
3669
139
      {
3670
139
        proto_item* unknown_item = knxip_tree_add_unknown_data( kip_tree, tvb, offset, remaining_len );
3671
139
        expert_add_info_format( pinfo, unknown_item, KIP_ERROR, "Unexpected trailing data" );
3672
139
      }
3673
3674
139
      ok = 0;
3675
139
    }
3676
551
  }
3677
3678
551
  if( !ok )
3679
531
  {
3680
    /* If not already done */
3681
531
    if( !knxip_error )
3682
424
    {
3683
424
      knxip_error = 1;
3684
424
      col_prepend_fstr(pinfo->cinfo, COL_INFO, "? " );
3685
424
    }
3686
3687
531
    proto_item_prepend_text( kip_item, "? " );
3688
531
  }
3689
551
}
3690
3691
static unsigned
3692
get_knxip_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
3693
559
{
3694
559
  return tvb_get_ntohs( tvb, offset+4 );
3695
559
}
3696
3697
// NOLINTNEXTLINE(misc-no-recursion)
3698
static int dissect_knxip( tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_ )
3699
551
{
3700
551
  int offset = 0;
3701
551
  unsigned remaining_len = tvb_captured_length( tvb );
3702
551
  uint8_t header_len = 0;
3703
551
  uint8_t protocol_version = 0;
3704
551
  uint16_t service_id = 0;
3705
551
  uint16_t total_len = 0;
3706
551
  uint8_t error = 0;
3707
3708
551
  column_info* cinfo = pinfo->cinfo;
3709
3710
551
  proto_item* kip_item = NULL;
3711
551
  proto_tree* kip_tree = NULL;
3712
551
  proto_item* header_item = NULL;
3713
551
  proto_tree* header_tree = NULL;
3714
551
  proto_item* header_len_item = NULL;
3715
551
  proto_item* version_item = NULL;
3716
551
  proto_item* service_item = NULL;
3717
551
  proto_tree* service_tree = NULL;
3718
551
  proto_item* total_length_item = NULL;
3719
3720
551
  char* version_info2;
3721
3722
551
  unsigned level = p_get_proto_depth(pinfo, proto_knxip);
3723
551
  if( level == 0 )
3724
512
  {
3725
512
    knxip_error = 0;
3726
512
    col_set_str( cinfo, COL_PROTOCOL, "KNXnet/IP" );
3727
512
    col_clear( cinfo, COL_INFO );
3728
512
  }
3729
39
  else
3730
39
  {
3731
39
    col_append_str( cinfo, COL_INFO, " " );
3732
39
  }
3733
551
  p_set_proto_depth(pinfo, proto_knxip, level+1);
3734
3735
551
  kip_item = proto_tree_add_item( tree, proto_knxip, tvb, offset, (remaining_len <= 0) ? 0 : -1, ENC_BIG_ENDIAN );
3736
551
  kip_tree = proto_item_add_subtree( kip_item, ett_kip );
3737
3738
551
  if( remaining_len <= 0 )
3739
0
  {
3740
    /* This may happen if we are embedded in another KNXnet/IP frame (level != 0)
3741
    */
3742
0
    proto_item_prepend_text( kip_item, "? " );
3743
0
    expert_add_info_format( pinfo, kip_item, KIP_ERROR, "Expected: min 6 bytes" );
3744
0
    col_append_str( cinfo, COL_INFO, "? empty" );
3745
3746
    /* If not already done */
3747
0
    if( !knxip_error )
3748
0
    {
3749
0
      knxip_error = 1;
3750
0
      col_prepend_fstr( cinfo, COL_INFO, "? " );
3751
0
    }
3752
0
  }
3753
551
  else
3754
551
  {
3755
    /* 1 byte Header Length */
3756
551
    header_len = tvb_get_uint8( tvb, 0 );
3757
3758
551
    if( tree )
3759
551
    {
3760
551
      header_item = proto_tree_add_none_format( kip_tree, hf_folder, tvb, 0,
3761
551
        (header_len <= remaining_len) ? header_len : remaining_len, "KNX/IP Header" );
3762
551
      header_tree = proto_item_add_subtree( header_item, ett_efcp );
3763
551
      header_len_item = proto_tree_add_uint_format_value( header_tree, hf_knxip_header_length,
3764
551
        tvb, 0, 1, header_len, "%u bytes", header_len );
3765
551
    }
3766
3767
551
    if( header_len > remaining_len )
3768
38
    {
3769
38
      proto_item_prepend_text( header_len_item, "? " );
3770
38
      expert_add_info_format( pinfo, header_len_item, KIP_ERROR, "Available: %u bytes", remaining_len );
3771
38
      error = 1;
3772
38
      header_len = (uint8_t) remaining_len;
3773
38
    }
3774
513
    else if( header_len != KIP_HDR_LEN )
3775
508
    {
3776
508
      proto_item_prepend_text( header_len_item, "? " );
3777
508
      expert_add_info_format( pinfo, header_len_item, KIP_ERROR, "Expected: 6 bytes" );
3778
508
      error = 1;
3779
508
    }
3780
3781
551
    offset++;
3782
3783
551
    if( header_len >= 2 )
3784
535
    {
3785
      /* 1 byte Protocol Version */
3786
535
      protocol_version = tvb_get_uint8( tvb, 1 );
3787
535
      version_info2 = wmem_strdup_printf(pinfo->pool, "%u.%u", hi_nibble( protocol_version ), lo_nibble( protocol_version ) );
3788
3789
535
      version_item = proto_tree_add_uint_format_value( header_tree, hf_knxip_protocol_version,
3790
535
          tvb, 1, 1, protocol_version, "%s", version_info2 );
3791
3792
535
      if( protocol_version != 0x10 )
3793
533
      {
3794
533
        proto_item_prepend_text( version_item, "? " );
3795
533
        expert_add_info_format( pinfo, version_item, KIP_ERROR, "Expected: Protocol Version 1.0" );
3796
533
        error = 1;
3797
533
      }
3798
3799
535
      offset++;
3800
3801
535
      if( header_len >= 4 )
3802
528
      {
3803
        /* 2 bytes Service ID */
3804
528
        service_id = tvb_get_ntohs( tvb, 2 );
3805
3806
528
        if( tree )
3807
528
        {
3808
528
          const char* name = try_val_to_str( service_id, knxip_service_type_vals );
3809
528
          proto_item_append_text( header_item, ": " );
3810
528
          if( name )
3811
491
            proto_item_append_text( header_item, "%s", name );
3812
37
          else
3813
37
            proto_item_append_text( header_item, "Service = 0x%04x", service_id );
3814
528
          service_item = proto_tree_add_item( header_tree, hf_knxip_service_id, tvb, 2, 2, ENC_BIG_ENDIAN );
3815
528
          service_tree = proto_item_add_subtree( service_item, ett_service );
3816
528
          proto_tree_add_item( service_tree, hf_knxip_service_family, tvb, 2, 1, ENC_BIG_ENDIAN );
3817
528
          proto_tree_add_item( service_tree, hf_knxip_service_type, tvb, 2, 2, ENC_BIG_ENDIAN );
3818
528
        }
3819
3820
528
        offset += 2;
3821
3822
528
        if( header_len >= KIP_HDR_LEN )
3823
321
        {
3824
          /* 2 bytes Total Length */
3825
321
          total_len = tvb_get_ntohs( tvb, 4 );
3826
3827
321
          if( tree )
3828
321
          {
3829
321
            total_length_item = proto_tree_add_uint_format_value( header_tree, hf_knxip_total_length,
3830
321
              tvb, 4, 2, total_len, "%u bytes", total_len );
3831
321
          }
3832
3833
321
          if( total_len < header_len )
3834
0
          {
3835
0
            proto_item_prepend_text( total_length_item, "? " );
3836
0
            expert_add_info_format( pinfo, total_length_item, KIP_ERROR, "Expected: >= Header Length" );
3837
0
            error = 1;
3838
0
          }
3839
321
          else if( total_len > remaining_len )
3840
302
          {
3841
302
            proto_item_prepend_text( total_length_item, "? " );
3842
302
            expert_add_info_format( pinfo, total_length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
3843
302
            error = 1;
3844
302
          }
3845
19
          else if( total_len < remaining_len )
3846
0
          {
3847
0
            proto_item_prepend_text( total_length_item, "? " );
3848
0
            expert_add_info_format( pinfo, total_length_item, KIP_ERROR, "Available: %u bytes", remaining_len );
3849
0
            error = 1;
3850
0
          }
3851
3852
321
          offset += 2;
3853
321
        }
3854
528
      }
3855
535
    }
3856
3857
551
    if( offset < header_len )
3858
314
    {
3859
314
      knxip_tree_add_unknown_data( header_tree, tvb, offset, header_len - offset );
3860
314
    }
3861
3862
551
    if( error )
3863
551
    {
3864
551
      proto_item_prepend_text( header_item, "? " );
3865
3866
551
      if( level == 0 )
3867
512
      {
3868
512
        col_prepend_fstr( cinfo, COL_PROTOCOL, "? " );
3869
512
      }
3870
39
      else
3871
39
      {
3872
        /* If not already done */
3873
39
        if( !knxip_error )
3874
0
        {
3875
0
          knxip_error = 1;
3876
0
          col_prepend_fstr( cinfo, COL_INFO, "? " );
3877
0
        }
3878
39
      }
3879
551
    }
3880
3881
551
    dissect_knxip_data( header_len, protocol_version, service_id, tvb, pinfo, tree, kip_item, kip_tree );
3882
551
  }
3883
551
  return tvb_captured_length( tvb );
3884
551
}
3885
3886
static int dissect_tcp_knxip( tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* udata )
3887
224
{
3888
224
  knxip_host_protocol = IP_PROTO_TCP;
3889
224
  tcp_dissect_pdus(tvb, pinfo, tree, pref_desegment, KIP_HDR_LEN, get_knxip_pdu_len, dissect_knxip, udata);
3890
3891
224
  return tvb_captured_length( tvb );
3892
224
}
3893
3894
static int dissect_udp_knxip( tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* udata )
3895
292
{
3896
292
  knxip_host_protocol = IP_PROTO_UDP;
3897
292
  udp_dissect_pdus( tvb, pinfo, tree, KIP_HDR_LEN, NULL, get_knxip_pdu_len, dissect_knxip, udata );
3898
292
  return tvb_captured_length( tvb );
3899
292
}
3900
3901
void proto_register_knxip( void )
3902
16
{
3903
  /* Header fields */
3904
16
  static hf_register_info hf[] =
3905
16
  {
3906
16
    { &hf_bytes, { "Data", "knxip.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
3907
16
    { &hf_folder, { "Folder", "knxip.folder", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } },
3908
16
    { &hf_knxip_header_length, { "Header Length", "knxip.headerlength", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
3909
16
    { &hf_knxip_protocol_version, { "Protocol Version", "knxip.version", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3910
16
    { &hf_knxip_service_id, { "Service Identifier", "knxip.service", FT_UINT16, BASE_HEX, VALS( knxip_service_type_vals ), 0, NULL, HFILL } },
3911
16
    { &hf_knxip_service_family, { "Service Family", "knxip.service.family", FT_UINT8, BASE_HEX, VALS( knxip_service_family_vals ), 0, NULL, HFILL } },
3912
16
    { &hf_knxip_service_type, { "Service Type", "knxip.service.type", FT_UINT16, BASE_HEX, VALS( knxip_service_type_vals ), 0, NULL, HFILL } },
3913
16
    { &hf_knxip_total_length, { "Total Length", "knxip.totallength", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
3914
16
    { &hf_knxip_structure_length, { "Structure Length", "knxip.struct.length", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0, NULL, HFILL } },
3915
16
    { &hf_knxip_host_protocol, { "Host Protocol", "knxip.hostprotocol", FT_UINT8, BASE_HEX, VALS( host_protocol_vals ), 0, NULL, HFILL } },
3916
16
    { &hf_knxip_ip_address, { "IP Address", "knxip.ipaddr", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
3917
16
    { &hf_knxip_port, { "Port Number", "knxip.port", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
3918
16
    { &hf_knxip_description_type, { "Description Type", "knxip.dibtype", FT_UINT8, BASE_HEX, VALS( description_type_vals ), 0, NULL, HFILL } },
3919
16
    { &hf_knxip_knx_medium, { "KNX Medium", "knxip.medium", FT_UINT8, BASE_HEX, VALS( medium_type_vals ), 0, NULL, HFILL } },
3920
16
    { &hf_knxip_knx_medium_flags_ip, { "IP", "knxip.medium.ip", FT_UINT8, BASE_DEC, NULL, KIP_KNXTYPE_IP, NULL, HFILL } },
3921
16
    { &hf_knxip_knx_medium_flags_rf, { "RF", "knxip.medium.rf", FT_UINT8, BASE_DEC, NULL, KIP_KNXTYPE_RF, NULL, HFILL } },
3922
16
    { &hf_knxip_knx_medium_flags_pl132, { "PL132", "knxip.medium.pl132", FT_UINT8, BASE_DEC, NULL, KIP_KNXTYPE_PL132, NULL, HFILL } },
3923
16
    { &hf_knxip_knx_medium_flags_pl110, { "PL110", "knxip.medium.pl110", FT_UINT8, BASE_DEC, NULL, KIP_KNXTYPE_PL110, NULL, HFILL } },
3924
16
    { &hf_knxip_knx_medium_flags_tp1, { "TP1", "knxip.medium.tp1", FT_UINT8, BASE_DEC, NULL, KIP_KNXTYPE_TP1, NULL, HFILL } },
3925
16
    { &hf_knxip_knx_medium_flags_tp0, { "TP0", "knxip.medium.tp0", FT_UINT8, BASE_DEC, NULL, KIP_KNXTYPE_TP0, NULL, HFILL } },
3926
16
    { &hf_knxip_device_status, { "Device Status", "knxip.device.status", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3927
16
    { &hf_knxip_program_mode, { "Programming Mode", "knxip.progmode", FT_UINT8, BASE_DEC, NULL, 0x1, NULL, HFILL } },
3928
16
    { &hf_knxip_knx_address, { "KNX Individual Address", "knxip.knxaddr", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
3929
16
    { &hf_knxip_knx_tunnel_usable, { "Usable", "knxip.tunnel.usable", FT_UINT8, BASE_DEC, NULL, 0x04, NULL, HFILL } },
3930
16
    { &hf_knxip_knx_tunnel_authorized, { "Authorized", "knxip.tunnel.authorized", FT_UINT8, BASE_DEC, NULL, 0x02, NULL, HFILL } },
3931
16
    { &hf_knxip_knx_tunnel_free, { "Free", "knxip.tunnel.free", FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL } },
3932
16
    { &hf_knxip_project_id, { "Project Installation Identifier", "knxip.project", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
3933
16
    { &hf_knxip_project_number, { "Project Number", "knxip.project.nr", FT_UINT16, BASE_DEC, NULL, 0xFFF0, NULL, HFILL } },
3934
16
    { &hf_knxip_installation_number, { "Installation Number", "knxip.project.installation", FT_UINT16, BASE_DEC, NULL, 0x000F, NULL, HFILL } },
3935
16
    { &hf_knxip_serial_number, { "KNX Serial Number", "knxip.sernr", FT_UINT48, BASE_HEX, NULL, 0, NULL, HFILL } },
3936
16
    { &hf_knxip_multicast_address, { "Multicast Address", "knxip.mcaddr", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
3937
16
    { &hf_knxip_mac_address, { "MAC Address", "knxip.macaddr", FT_ETHER, BASE_NONE, NULL, 0, NULL, HFILL } },
3938
16
    { &hf_knxip_friendly_name, { "Friendly Name", "knxip.device.name", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
3939
16
    { &hf_knxip_service_version, { "Service Version", "knxip.service.version", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3940
16
    { &hf_knxip_security_version, { "Security Version", "knxip.security.version", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3941
16
    { &hf_knxip_manufacturer_code, { "KNX Manufacturer Code", "knxip.manufacturer", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
3942
16
    { &hf_knxip_connection_type, { "Connection Type", "knxip.conn.type", FT_UINT8, BASE_HEX, VALS( connection_type_vals ), 0, NULL, HFILL } },
3943
16
    { &hf_knxip_knx_layer, { "KNX Layer", "knxip.tunnel.layer", FT_UINT8, BASE_HEX, VALS( knx_layer_vals ), 0, NULL, HFILL } },
3944
16
    { &hf_knxip_channel, { "Channel", "knxip.channel", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3945
16
    { &hf_knxip_status, { "Status", "knxip.status", FT_UINT8, BASE_HEX, VALS( error_vals ), 0, NULL, HFILL } },
3946
16
    { &hf_knxip_reserved, { "Reserved", "knxip.reserved", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3947
16
    { &hf_knxip_seq_counter, { "Sequence Counter", "knxip.seqctr", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
3948
16
    { &hf_knxip_ip_subnet, { "Subnet Mask", "knxip.subnet", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
3949
16
    { &hf_knxip_ip_gateway, { "Default Gateway", "knxip.gateway", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
3950
16
    { &hf_knxip_ip_assign, { "IP Assignment", "knxip.ipassign", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3951
16
    { &hf_knxip_ip_assign_auto, { "AutoIP", "knxip.ipassign.auto", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL } },
3952
16
    { &hf_knxip_ip_assign_dhcp, { "DHCP", "knxip.ipassign.dhcp", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL } },
3953
16
    { &hf_knxip_ip_assign_bootp, { "BootP", "knxip.ipassign.bootp", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL } },
3954
16
    { &hf_knxip_ip_assign_manual, { "Manual", "knxip.ipassign.manual", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL } },
3955
16
    { &hf_knxip_ip_caps, { "IP Capabilities", "knxip.ipcaps", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3956
16
    { &hf_knxip_ip_caps_auto, { "AutoIP", "knxip.ipcaps.auto", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL } },
3957
16
    { &hf_knxip_ip_caps_dhcp, { "DHCP", "knxip.ipcaps.dhcp", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL } },
3958
16
    { &hf_knxip_ip_caps_bootp, { "BootP", "knxip.ipcaps.bootp", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL } },
3959
16
    { &hf_knxip_ip_dhcp, { "DHCP Server", "knxip.dhcp", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
3960
16
    { &hf_knxip_tunnel_feature, { "Tunneling Feature Identifier", "knxip.tunnel.feature", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3961
16
    { &hf_knxip_routing_loss, { "Lost Messages", "knxip.loss", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
3962
16
    { &hf_knxip_busy_time, { "Wait Time", "knxip.busy.time", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0, NULL, HFILL}},
3963
16
    { &hf_knxip_busy_control, { "Control", "knxip.busy.control", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
3964
16
    { &hf_knxip_selector, { "Selector", "knxip.selector", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3965
16
    { &hf_knxip_max_apdu_length, { "Max APDU Length", "knxip.maxapdulength", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
3966
16
    { &hf_knxip_medium_status, { "Medium Status", "knxip.medium.status", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3967
16
    { &hf_knxip_mask_version, { "Mask Version", "knxip.mask.version", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
3968
16
    { &hf_knxip_srp_mandatory, { "Mandatory", "knxip.srp.mandatory", FT_UINT8, BASE_DEC, NULL, 0x80, NULL, HFILL } },
3969
16
    { &hf_knxip_srp_type, { "SRP Type", "knxip.srp.type", FT_UINT8, BASE_HEX, NULL, 0x7F, NULL, HFILL } },
3970
16
    { &hf_knxip_reset_command, { "Command", "knxip.reset.command", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3971
16
    { &hf_knxip_session, { "Session", "knxip.session", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
3972
16
    { &hf_knxip_tag, { "Tag", "knxip.tag", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
3973
16
    { &hf_knxip_user, { "User", "knxip.user", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
3974
16
    { &hf_knxip_session_status, { "Status", "knxip.session.status", FT_UINT8, BASE_HEX, VALS( session_status_vals ), 0, NULL, HFILL } },
3975
16
  };
3976
3977
  /* Subtrees */
3978
16
  static int *ett[] =
3979
16
  {
3980
16
    &ett_kip,
3981
16
    &ett_efcp,
3982
16
    &ett_service,
3983
16
    &ett_hpai,
3984
16
    &ett_dib,
3985
16
    &ett_medium,
3986
16
    &ett_status,
3987
16
    &ett_projectid,
3988
16
    &ett_service_family,
3989
16
    &ett_ip_assignment,
3990
16
    &ett_cri,
3991
16
    &ett_crd,
3992
16
    &ett_cnhdr,
3993
16
    &ett_loss,
3994
16
    &ett_busy,
3995
16
    &ett_selector,
3996
16
    &ett_decrypted,
3997
16
    &ett_tunnel,
3998
16
  };
3999
4000
16
  static ei_register_info ei[] =
4001
16
  {
4002
16
    { &ei_knxip_error, { "knxip.error", PI_MALFORMED, PI_ERROR, "KNX/IP error", EXPFILL }},
4003
16
    { &ei_knxip_warning, { "knxip.warning", PI_PROTOCOL, PI_WARN, "KNX/IP warning", EXPFILL }},
4004
16
  };
4005
4006
16
  expert_module_t* expert_knxip;
4007
16
  module_t* knxip_module;
4008
16
  uint8_t x;
4009
4010
16
  proto_knxip = proto_register_protocol( "KNX/IP", "KNX/IP", "kip" );
4011
4012
16
  proto_register_field_array( proto_knxip, hf, array_length( hf ) );
4013
16
  proto_register_subtree_array( ett, array_length( ett ) );
4014
4015
16
  register_dissector( "udp.knxip", dissect_udp_knxip, proto_knxip );
4016
16
  register_dissector( "tcp.knxip", dissect_tcp_knxip, proto_knxip );
4017
4018
  //register_dissector_table( "knxip.version", "KNXnet/IP Protocol Version", proto_knxip, FT_UINT8, BASE_HEX );
4019
4020
16
  expert_knxip = expert_register_protocol( proto_knxip );
4021
16
  expert_register_field_array( expert_knxip, ei, array_length( ei ) );
4022
4023
16
  knxip_module = prefs_register_protocol( proto_knxip, proto_reg_handoff_knxip );
4024
4025
16
  prefs_register_filename_preference( knxip_module, "key_file", "Key file", "Keyring.XML file (exported from ETS)",
4026
16
    &pref_key_file_name, false );
4027
16
  prefs_register_string_preference( knxip_module, "key_file_pwd", "Key file password", "Keyring password",
4028
16
    &pref_key_file_pwd );
4029
16
  prefs_register_filename_preference( knxip_module, "key_info_file", "Key info output file", "Output file (- for stdout) for keys extracted from key file",
4030
16
    &pref_key_info_file_name, false );
4031
4032
16
  prefs_register_static_text_preference( knxip_module, "", "", NULL );
4033
4034
16
  prefs_register_static_text_preference( knxip_module, "keys_0",
4035
16
    "KNX decryption keys",
4036
16
    NULL );
4037
16
  prefs_register_static_text_preference( knxip_module, "keys_1",
4038
16
    "(KNX/IP multicast/group keys, KNX/IP unicast session keys, KNX data-security tool keys and link-table keys)",
4039
16
    NULL );
4040
16
  prefs_register_static_text_preference( knxip_module, "keys_2",
4041
16
    "(format: 16 bytes as hex; example: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF)",
4042
16
    NULL );
4043
4044
176
  for( x = 1; x <= MAX_KNX_DECRYPTION_KEYS; ++x )
4045
160
  {
4046
160
    char* name = wmem_strdup_printf( wmem_epan_scope(), "key_%u", x );
4047
160
    char* title = wmem_strdup_printf( wmem_epan_scope(), "%u. key", x );
4048
160
    prefs_register_string_preference( knxip_module, name, title,
4049
160
      "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)",
4050
160
      &pref_key_texts[ x - 1 ] );
4051
160
  }
4052
4053
16
  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);
4054
16
}
4055
4056
void proto_reg_handoff_knxip( void )
4057
16
{
4058
16
  dissector_handle_t knxip_handle;
4059
16
  uint8_t x;
4060
16
  const char* text;
4061
4062
16
  knxip_handle = find_dissector( "udp.knxip" );
4063
16
  dissector_add_uint_range_with_preference("udp.port", KIP_DEFAULT_PORT_RANGE, knxip_handle);
4064
4065
16
  knxip_handle = find_dissector( "tcp.knxip" );
4066
16
  dissector_add_uint_range_with_preference("tcp.port", KIP_DEFAULT_PORT_RANGE, knxip_handle);
4067
4068
  /* Evaluate preferences
4069
  */
4070
16
  if ((pref_key_file_name != NULL) && (pref_key_file_name[0] != '\0'))
4071
0
  {
4072
    /* Read Keyring.XML file (containing decryption keys, exported from ETS) */
4073
0
    read_knx_keyring_xml_file( pref_key_file_name, pref_key_file_pwd, pref_key_info_file_name );
4074
0
  }
4075
4076
16
  knx_decryption_key_count = 0;
4077
176
  for( x = 0; x < MAX_KNX_DECRYPTION_KEYS && knx_decryption_key_count < MAX_KNX_DECRYPTION_KEYS; ++x )
4078
160
  {
4079
160
    text = pref_key_texts[ x ];
4080
160
    if( text )
4081
160
    {
4082
160
      if( hex_to_knx_key( text, knx_decryption_keys[ knx_decryption_key_count ] ) )
4083
0
      {
4084
0
        ++knx_decryption_key_count;
4085
0
      }
4086
160
    }
4087
160
  }
4088
16
}
4089
4090
/*
4091
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
4092
 *
4093
 * Local variables:
4094
 * c-basic-offset: 2
4095
 * tab-width: 8
4096
 * indent-tabs-mode: nil
4097
 * End:
4098
 *
4099
 * vi: set shiftwidth=2 tabstop=8 expandtab:
4100
 * :indentSize=2:tabSize=8:noTabs=true:
4101
 */