/src/wireshark/epan/dissectors/packet-doip.c
Line | Count | Source |
1 | | /* packet-doip.c |
2 | | * Routines for DoIP (ISO13400) protocol packet disassembly |
3 | | * |
4 | | * Wireshark - Network traffic analyzer |
5 | | * By Gerald Combs <gerald@wireshark.org> |
6 | | * Copyright 1998 Gerald Combs |
7 | | * |
8 | | * SPDX-License-Identifier: GPL-2.0-or-later |
9 | | */ |
10 | | |
11 | | #include "config.h" |
12 | | #include <epan/packet.h> |
13 | | #include <epan/uat.h> |
14 | | #include <epan/expert.h> |
15 | | #include <epan/proto_data.h> |
16 | | |
17 | | #include "packet-tcp.h" |
18 | | #include "packet-tls.h" |
19 | | #include "packet-doip.h" |
20 | | |
21 | | void proto_register_doip(void); |
22 | | void proto_reg_handoff_doip(void); |
23 | | |
24 | | |
25 | 32 | #define DOIP_PORT 13400 |
26 | 16 | #define DOIP_TLS_PORT 3496 |
27 | | |
28 | 1 | #define DOIP_GENERIC_NACK 0x0000 |
29 | 2 | #define DOIP_VEHICLE_IDENTIFICATION_REQ 0x0001 |
30 | 0 | #define DOIP_VEHICLE_IDENTIFICATION_REQ_EID 0x0002 |
31 | 1 | #define DOIP_VEHICLE_IDENTIFICATION_REQ_VIN 0x0003 |
32 | 0 | #define DOIP_VEHICLE_ANNOUNCEMENT_MESSAGE 0x0004 |
33 | 0 | #define DOIP_ROUTING_ACTIVATION_REQUEST 0x0005 |
34 | 0 | #define DOIP_ROUTING_ACTIVATION_RESPONSE 0x0006 |
35 | 0 | #define DOIP_ALIVE_CHECK_REQUEST 0x0007 |
36 | 0 | #define DOIP_ALIVE_CHECK_RESPONSE 0x0008 |
37 | 0 | #define DOIP_ENTITY_STATUS_REQUEST 0x4001 |
38 | 0 | #define DOIP_ENTITY_STATUS_RESPONSE 0x4002 |
39 | 0 | #define DOIP_POWER_INFORMATION_REQUEST 0x4003 |
40 | 0 | #define DOIP_POWER_INFORMATION_RESPONSE 0x4004 |
41 | 22 | #define DOIP_DIAGNOSTIC_MESSAGE 0x8001 |
42 | 0 | #define DOIP_DIAGNOSTIC_MESSAGE_ACK 0x8002 |
43 | 0 | #define DOIP_DIAGNOSTIC_MESSAGE_NACK 0x8003 |
44 | | |
45 | | |
46 | | /* Header */ |
47 | 512 | #define DOIP_VERSION_OFFSET 0 |
48 | 426 | #define DOIP_VERSION_LEN 1 |
49 | 399 | #define DOIP_INV_VERSION_OFFSET (DOIP_VERSION_OFFSET + DOIP_VERSION_LEN) |
50 | 367 | #define DOIP_INV_VERSION_LEN 1 |
51 | 340 | #define DOIP_TYPE_OFFSET (DOIP_INV_VERSION_OFFSET + DOIP_INV_VERSION_LEN) |
52 | 286 | #define DOIP_TYPE_LEN 2 |
53 | 259 | #define DOIP_LENGTH_OFFSET (DOIP_TYPE_OFFSET + DOIP_TYPE_LEN) |
54 | 232 | #define DOIP_LENGTH_LEN 4 |
55 | 206 | #define DOIP_HEADER_LEN (DOIP_LENGTH_OFFSET + DOIP_LENGTH_LEN) |
56 | | |
57 | | #define RESERVED_VER 0x00 |
58 | 54 | #define ISO13400_2010 0x01 |
59 | 54 | #define ISO13400_2012 0x02 |
60 | 54 | #define ISO13400_2019 0x03 |
61 | 54 | #define ISO13400_2019_AMD1 0x04 |
62 | 54 | #define DEFAULT_VALUE 0xFF |
63 | | |
64 | | |
65 | | /* Generic NACK */ |
66 | 1 | #define DOIP_GENERIC_NACK_OFFSET DOIP_HEADER_LEN |
67 | 1 | #define DOIP_GENERIC_NACK_LEN 1 |
68 | | |
69 | | |
70 | | /* Common */ |
71 | 0 | #define DOIP_COMMON_VIN_LEN 17 |
72 | 0 | #define DOIP_COMMON_EID_LEN 6 |
73 | | |
74 | | |
75 | | /* Vehicle identification request */ |
76 | 0 | #define DOIP_VEHICLE_IDENTIFICATION_EID_OFFSET DOIP_HEADER_LEN |
77 | 0 | #define DOIP_VEHICLE_IDENTIFICATION_VIN_OFFSET DOIP_HEADER_LEN |
78 | | |
79 | | |
80 | | /* Routing activation request */ |
81 | 0 | #define DOIP_ROUTING_ACTIVATION_REQ_SRC_OFFSET DOIP_HEADER_LEN |
82 | 0 | #define DOIP_ROUTING_ACTIVATION_REQ_SRC_LEN 2 |
83 | 0 | #define DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET (DOIP_ROUTING_ACTIVATION_REQ_SRC_OFFSET + DOIP_ROUTING_ACTIVATION_REQ_SRC_LEN) |
84 | 0 | #define DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V1 2 |
85 | 0 | #define DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V2 1 |
86 | 0 | #define DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V1 (DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET + DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V1) |
87 | 0 | #define DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V2 (DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET + DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V2) |
88 | 0 | #define DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN 4 |
89 | 0 | #define DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V1 (DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V1 + DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN) |
90 | 0 | #define DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V2 (DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V2 + DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN) |
91 | 0 | #define DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN 4 |
92 | | |
93 | | |
94 | | /* Routing activation response */ |
95 | 0 | #define DOIP_ROUTING_ACTIVATION_RES_TESTER_OFFSET DOIP_HEADER_LEN |
96 | 0 | #define DOIP_ROUTING_ACTIVATION_RES_TESTER_LEN 2 |
97 | 0 | #define DOIP_ROUTING_ACTIVATION_RES_ENTITY_OFFSET (DOIP_ROUTING_ACTIVATION_RES_TESTER_OFFSET + DOIP_ROUTING_ACTIVATION_RES_TESTER_LEN) |
98 | 0 | #define DOIP_ROUTING_ACTIVATION_RES_ENTITY_LEN 2 |
99 | 0 | #define DOIP_ROUTING_ACTIVATION_RES_CODE_OFFSET (DOIP_ROUTING_ACTIVATION_RES_ENTITY_OFFSET + DOIP_ROUTING_ACTIVATION_RES_ENTITY_LEN) |
100 | 0 | #define DOIP_ROUTING_ACTIVATION_RES_CODE_LEN 1 |
101 | 0 | #define DOIP_ROUTING_ACTIVATION_RES_ISO_OFFSET (DOIP_ROUTING_ACTIVATION_RES_CODE_OFFSET + DOIP_ROUTING_ACTIVATION_RES_CODE_LEN) |
102 | 0 | #define DOIP_ROUTING_ACTIVATION_RES_ISO_LEN 4 |
103 | 0 | #define DOIP_ROUTING_ACTIVATION_RES_OEM_OFFSET (DOIP_ROUTING_ACTIVATION_RES_ISO_OFFSET + DOIP_ROUTING_ACTIVATION_RES_ISO_LEN) |
104 | 0 | #define DOIP_ROUTING_ACTIVATION_RES_OEM_LEN 4 |
105 | | |
106 | | |
107 | | /* Vehicle announcement message */ |
108 | 0 | #define DOIP_VEHICLE_ANNOUNCEMENT_VIN_OFFSET DOIP_HEADER_LEN |
109 | 0 | #define DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_OFFSET (DOIP_VEHICLE_ANNOUNCEMENT_VIN_OFFSET + DOIP_COMMON_VIN_LEN) |
110 | 0 | #define DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_LEN 2 |
111 | 0 | #define DOIP_VEHICLE_ANNOUNCEMENT_EID_OFFSET (DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_OFFSET + DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_LEN) |
112 | 0 | #define DOIP_VEHICLE_ANNOUNCEMENT_GID_OFFSET (DOIP_VEHICLE_ANNOUNCEMENT_EID_OFFSET + DOIP_COMMON_EID_LEN) |
113 | 0 | #define DOIP_VEHICLE_ANNOUNCEMENT_GID_LEN 6 |
114 | 0 | #define DOIP_VEHICLE_ANNOUNCEMENT_ACTION_OFFSET (DOIP_VEHICLE_ANNOUNCEMENT_GID_OFFSET + DOIP_VEHICLE_ANNOUNCEMENT_GID_LEN) |
115 | 0 | #define DOIP_VEHICLE_ANNOUNCEMENT_ACTION_LEN 1 |
116 | 0 | #define DOIP_VEHICLE_ANNOUNCEMENT_SYNC_OFFSET (DOIP_VEHICLE_ANNOUNCEMENT_ACTION_OFFSET + DOIP_VEHICLE_ANNOUNCEMENT_ACTION_LEN) |
117 | 0 | #define DOIP_VEHICLE_ANNOUNCEMENT_SYNC_LEN 1 |
118 | | |
119 | | |
120 | | /* Alive check response */ |
121 | 0 | #define DOIP_ALIVE_CHECK_RESPONSE_SOURCE_OFFSET DOIP_HEADER_LEN |
122 | 0 | #define DOIP_ALIVE_CHECK_RESPONSE_SOURCE_LEN 2 |
123 | | |
124 | | |
125 | | /* Entity status response */ |
126 | 0 | #define DOIP_ENTITY_STATUS_RESPONSE_NODE_OFFSET DOIP_HEADER_LEN |
127 | 0 | #define DOIP_ENTITY_STATUS_RESPONSE_NODE_LEN 1 |
128 | 0 | #define DOIP_ENTITY_STATUS_RESPONSE_MCTS_OFFSET (DOIP_ENTITY_STATUS_RESPONSE_NODE_OFFSET + DOIP_ENTITY_STATUS_RESPONSE_NODE_LEN) |
129 | 0 | #define DOIP_ENTITY_STATUS_RESPONSE_MCTS_LEN 1 |
130 | 0 | #define DOIP_ENTITY_STATUS_RESPONSE_NCTS_OFFSET (DOIP_ENTITY_STATUS_RESPONSE_MCTS_OFFSET + DOIP_ENTITY_STATUS_RESPONSE_MCTS_LEN) |
131 | 0 | #define DOIP_ENTITY_STATUS_RESPONSE_NCTS_LEN 1 |
132 | 0 | #define DOIP_ENTITY_STATUS_RESPONSE_MDS_OFFSET (DOIP_ENTITY_STATUS_RESPONSE_NCTS_OFFSET + DOIP_ENTITY_STATUS_RESPONSE_NCTS_LEN) |
133 | 0 | #define DOIP_ENTITY_STATUS_RESPONSE_MDS_LEN 4 |
134 | | |
135 | | |
136 | | /* Diagnostic power mode information response */ |
137 | 0 | #define DOIP_POWER_MODE_OFFSET DOIP_HEADER_LEN |
138 | 0 | #define DOIP_POWER_MODE_LEN 1 |
139 | | |
140 | | |
141 | | /* Common */ |
142 | 66 | #define DOIP_DIAG_COMMON_SOURCE_OFFSET DOIP_HEADER_LEN |
143 | 66 | #define DOIP_DIAG_COMMON_SOURCE_LEN 2 |
144 | 44 | #define DOIP_DIAG_COMMON_TARGET_OFFSET (DOIP_DIAG_COMMON_SOURCE_OFFSET + DOIP_DIAG_COMMON_SOURCE_LEN) |
145 | 44 | #define DOIP_DIAG_COMMON_TARGET_LEN 2 |
146 | | |
147 | | |
148 | | /* Diagnostic message */ |
149 | 22 | #define DOIP_DIAG_MESSAGE_DATA_OFFSET (DOIP_DIAG_COMMON_TARGET_OFFSET + DOIP_DIAG_COMMON_TARGET_LEN) |
150 | | |
151 | | |
152 | | /* Diagnostic message ACK */ |
153 | 0 | #define DOIP_DIAG_MESSAGE_ACK_CODE_OFFSET (DOIP_DIAG_COMMON_TARGET_OFFSET + DOIP_DIAG_COMMON_TARGET_LEN) |
154 | 0 | #define DOIP_DIAG_MESSAGE_ACK_CODE_LEN 1 |
155 | 0 | #define DOIP_DIAG_MESSAGE_ACK_PREVIOUS_OFFSET (DOIP_DIAG_MESSAGE_ACK_CODE_OFFSET + DOIP_DIAG_MESSAGE_ACK_CODE_LEN) |
156 | | |
157 | | |
158 | | /* Diagnostic message NACK */ |
159 | 0 | #define DOIP_DIAG_MESSAGE_NACK_CODE_OFFSET (DOIP_DIAG_COMMON_TARGET_OFFSET + DOIP_DIAG_COMMON_TARGET_LEN) |
160 | 0 | #define DOIP_DIAG_MESSAGE_NACK_CODE_LEN 1 |
161 | 0 | #define DOIP_DIAG_MESSAGE_NACK_PREVIOUS_OFFSET (DOIP_DIAG_MESSAGE_NACK_CODE_OFFSET + DOIP_DIAG_MESSAGE_NACK_CODE_LEN) |
162 | | |
163 | | |
164 | | |
165 | | /* |
166 | | * Enums |
167 | | */ |
168 | | |
169 | | /* Header */ |
170 | | /* Protocol version */ |
171 | | static const value_string doip_versions[] = { |
172 | | { RESERVED_VER, "Reserved" }, |
173 | | { ISO13400_2010, "DoIP ISO/DIS 13400-2:2010" }, |
174 | | { ISO13400_2012, "DoIP ISO 13400-2:2012" }, |
175 | | { ISO13400_2019, "DoIP ISO 13400-2:2019" }, |
176 | | { ISO13400_2019_AMD1, "DoIP ISO 13400-2:2019 Amd1 (experimental)" }, |
177 | | { DEFAULT_VALUE, "Default value for vehicle identification request messages" }, |
178 | | { 0, NULL } |
179 | | }; |
180 | | |
181 | | /* Payload type */ |
182 | | static const value_string doip_payloads[] = { |
183 | | { DOIP_GENERIC_NACK, "Generic DoIP header NACK" }, |
184 | | { DOIP_VEHICLE_IDENTIFICATION_REQ, "Vehicle identification request" }, |
185 | | { DOIP_VEHICLE_IDENTIFICATION_REQ_EID, "Vehicle identification request with EID" }, |
186 | | { DOIP_VEHICLE_IDENTIFICATION_REQ_VIN, "Vehicle identification request with VIN" }, |
187 | | { DOIP_VEHICLE_ANNOUNCEMENT_MESSAGE, "Vehicle announcement message/vehicle identification response message" }, |
188 | | { DOIP_ROUTING_ACTIVATION_REQUEST, "Routing activation request" }, |
189 | | { DOIP_ROUTING_ACTIVATION_RESPONSE, "Routing activation response" }, |
190 | | { DOIP_ALIVE_CHECK_REQUEST, "Alive check request" }, |
191 | | { DOIP_ALIVE_CHECK_RESPONSE, "Alive check response" }, |
192 | | { DOIP_ENTITY_STATUS_REQUEST, "DoIP entity status request" }, |
193 | | { DOIP_ENTITY_STATUS_RESPONSE, "DoIP entity status response" }, |
194 | | { DOIP_POWER_INFORMATION_REQUEST, "Diagnostic power mode information request" }, |
195 | | { DOIP_POWER_INFORMATION_RESPONSE, "Diagnostic power mode information response" }, |
196 | | { DOIP_DIAGNOSTIC_MESSAGE, "Diagnostic message" }, |
197 | | { DOIP_DIAGNOSTIC_MESSAGE_ACK, "Diagnostic message ACK" }, |
198 | | { DOIP_DIAGNOSTIC_MESSAGE_NACK, "Diagnostic message NACK" }, |
199 | | { 0, NULL } |
200 | | }; |
201 | | |
202 | | |
203 | | /* Generic NACK */ |
204 | | static const value_string nack_codes[] = { |
205 | | { 0x00, "Incorrect pattern format" }, |
206 | | { 0x01, "Unknown payload type" }, |
207 | | { 0x02, "Message too large" }, |
208 | | { 0x03, "Out of memory" }, |
209 | | { 0x04, "Invalid payload length" }, |
210 | | { 0, NULL } |
211 | | }; |
212 | | |
213 | | |
214 | | /* Routing activation request */ |
215 | | static const value_string activation_types[] = { |
216 | | { 0x00, "Default" }, |
217 | | { 0x01, "WWH-OBD" }, |
218 | | { 0xE0, "Central security" }, |
219 | | { 0, NULL } |
220 | | }; |
221 | | |
222 | | |
223 | | /* Routing activation response */ |
224 | | static const value_string activation_codes[] = { |
225 | | { 0x00, "Routing activation denied due to unknown source address." }, |
226 | | { 0x01, "Routing activation denied because all concurrently supported TCP_DATA sockets are registered and active." }, |
227 | | { 0x02, "Routing activation denied because an SA different from the table connection entry was received on the already activated TCP_DATA socket." }, |
228 | | { 0x03, "Routing activation denied because the SA is already registered and active on a different TCP_DATA socket." }, |
229 | | { 0x04, "Routing activation denied due to missing authentication." }, |
230 | | { 0x05, "Routing activation denied due to rejected confirmation." }, |
231 | | { 0x06, "Routing activation denied due to unsupported routing activation type." }, |
232 | | { 0x07, "Routing activation denied due to request for encrypted connection via TLS." }, |
233 | | { 0x08, "Reserved by ISO 13400." }, |
234 | | { 0x09, "Reserved by ISO 13400." }, |
235 | | { 0x0A, "Reserved by ISO 13400." }, |
236 | | { 0x0B, "Reserved by ISO 13400." }, |
237 | | { 0x0C, "Reserved by ISO 13400." }, |
238 | | { 0x0D, "Reserved by ISO 13400." }, |
239 | | { 0x0E, "Reserved by ISO 13400." }, |
240 | | { 0x0F, "Reserved by ISO 13400." }, |
241 | | { 0x10, "Routing successfully activated." }, |
242 | | { 0x11, "Routing will be activated; confirmation required." }, |
243 | | { 0, NULL } |
244 | | }; |
245 | | |
246 | | |
247 | | /* Vehicle announcement message */ |
248 | | /* Action code */ |
249 | | static const value_string action_codes[] = { |
250 | | { 0x00, "No further action required" }, |
251 | | { 0x01, "Reserved by ISO 13400" }, |
252 | | { 0x02, "Reserved by ISO 13400" }, |
253 | | { 0x03, "Reserved by ISO 13400" }, |
254 | | { 0x04, "Reserved by ISO 13400" }, |
255 | | { 0x05, "Reserved by ISO 13400" }, |
256 | | { 0x06, "Reserved by ISO 13400" }, |
257 | | { 0x07, "Reserved by ISO 13400" }, |
258 | | { 0x08, "Reserved by ISO 13400" }, |
259 | | { 0x09, "Reserved by ISO 13400" }, |
260 | | { 0x0A, "Reserved by ISO 13400" }, |
261 | | { 0x0B, "Reserved by ISO 13400" }, |
262 | | { 0x0C, "Reserved by ISO 13400" }, |
263 | | { 0x0D, "Reserved by ISO 13400" }, |
264 | | { 0x0E, "Reserved by ISO 13400" }, |
265 | | { 0x0F, "Reserved by ISO 13400" }, |
266 | | { 0x10, "Routing activation required to initiate central security" }, |
267 | | { 0, NULL } |
268 | | }; |
269 | | |
270 | | /* Sync status */ |
271 | | static const value_string sync_status[] = { |
272 | | { 0x00, "VIN and/or GID are synchronized" }, |
273 | | { 0x01, "Reserved by ISO 13400" }, |
274 | | { 0x02, "Reserved by ISO 13400" }, |
275 | | { 0x03, "Reserved by ISO 13400" }, |
276 | | { 0x04, "Reserved by ISO 13400" }, |
277 | | { 0x05, "Reserved by ISO 13400" }, |
278 | | { 0x06, "Reserved by ISO 13400" }, |
279 | | { 0x07, "Reserved by ISO 13400" }, |
280 | | { 0x08, "Reserved by ISO 13400" }, |
281 | | { 0x09, "Reserved by ISO 13400" }, |
282 | | { 0x0A, "Reserved by ISO 13400" }, |
283 | | { 0x0B, "Reserved by ISO 13400" }, |
284 | | { 0x0C, "Reserved by ISO 13400" }, |
285 | | { 0x0D, "Reserved by ISO 13400" }, |
286 | | { 0x0E, "Reserved by ISO 13400" }, |
287 | | { 0x0F, "Reserved by ISO 13400" }, |
288 | | { 0x10, "Incomplete: VIN and GID are NOT synchronized" }, |
289 | | { 0, NULL } |
290 | | }; |
291 | | |
292 | | /* Entity status response */ |
293 | | /* Node type */ |
294 | | static const value_string node_types[] = { |
295 | | { 0x00, "DoIP gateway" }, |
296 | | { 0x01, "DoIp node" }, |
297 | | { 0, NULL } |
298 | | }; |
299 | | |
300 | | |
301 | | /* Diagnostic power mode information response */ |
302 | | /* Power mode */ |
303 | | static const value_string power_modes[] = { |
304 | | { 0x00, "not ready" }, |
305 | | { 0x01, "ready" }, |
306 | | { 0x02, "not supported" }, |
307 | | { 0, NULL } |
308 | | }; |
309 | | |
310 | | |
311 | | /* Diagnostic message ACK */ |
312 | | static const value_string diag_ack_codes[] = { |
313 | | { 0x00, "ACK" }, |
314 | | { 0, NULL } |
315 | | }; |
316 | | |
317 | | |
318 | | /* Diagnostic message NACK */ |
319 | | static const value_string diag_nack_codes[] = { |
320 | | { 0x00, "Reserved by ISO 13400" }, |
321 | | { 0x01, "Reserved by ISO 13400" }, |
322 | | { 0x02, "Invalid source address" }, |
323 | | { 0x03, "Unknown target address" }, |
324 | | { 0x04, "Diagnostic message too large" }, |
325 | | { 0x05, "Out of memory" }, |
326 | | { 0x06, "Target unreachable" }, |
327 | | { 0x07, "Unknown network" }, |
328 | | { 0x08, "Transport protocol error" }, |
329 | | { 0, NULL } |
330 | | }; |
331 | | |
332 | | |
333 | | |
334 | | /* |
335 | | * Config |
336 | | */ |
337 | | |
338 | | static bool doip_hide_address_names = true; |
339 | | |
340 | | /* |
341 | | * Fields |
342 | | */ |
343 | | |
344 | | /* DoIP header */ |
345 | | static int hf_doip_version; |
346 | | static int hf_doip_inv_version; |
347 | | static int hf_doip_type; |
348 | | static int hf_doip_length; |
349 | | |
350 | | |
351 | | /* Generic NACK */ |
352 | | static int hf_generic_nack_code; |
353 | | |
354 | | |
355 | | /* Common */ |
356 | | static int hf_reserved_iso; |
357 | | static int hf_reserved_oem; |
358 | | |
359 | | |
360 | | /* Routing activation request */ |
361 | | static int hf_activation_type_v1; |
362 | | static int hf_activation_type_v2; |
363 | | |
364 | | |
365 | | /* Routing activation response */ |
366 | | static int hf_tester_logical_address; |
367 | | static int hf_tester_logical_address_name; |
368 | | static int hf_response_code; |
369 | | |
370 | | |
371 | | /* Vehicle announcement message */ |
372 | | static int hf_logical_address; |
373 | | static int hf_logical_address_name; |
374 | | static int hf_gid; |
375 | | static int hf_further_action; |
376 | | static int hf_sync_status; |
377 | | |
378 | | |
379 | | /* Diagnostic power mode information response */ |
380 | | static int hf_power_mode; |
381 | | |
382 | | |
383 | | /* Entity status response */ |
384 | | static int hf_node_type; |
385 | | static int hf_max_sockets; |
386 | | static int hf_current_sockets; |
387 | | static int hf_max_data_size; |
388 | | |
389 | | |
390 | | /* Common */ |
391 | | static int hf_vin; |
392 | | static int hf_eid; |
393 | | static int hf_source_address; |
394 | | static int hf_source_address_name; |
395 | | static int hf_target_address; |
396 | | static int hf_target_address_name; |
397 | | static int hf_previous; |
398 | | |
399 | | |
400 | | /* Diagnostic message */ |
401 | | static int hf_data; |
402 | | |
403 | | |
404 | | /* Diagnostic message ACK */ |
405 | | static int hf_ack_code; |
406 | | |
407 | | |
408 | | /* Diagnostic message NACK */ |
409 | | static int hf_nack_code; |
410 | | |
411 | | |
412 | | |
413 | | /* |
414 | | * Trees |
415 | | */ |
416 | | static int ett_doip; |
417 | | static int ett_header; |
418 | | static int ett_address; |
419 | | |
420 | | |
421 | | /* Misc */ |
422 | | static dissector_handle_t doip_handle; |
423 | | static dissector_handle_t uds_handle; |
424 | | static int proto_doip; |
425 | | |
426 | | |
427 | | /* expert info items */ |
428 | | static expert_field ei_doip_illegal_length_field; |
429 | | |
430 | | |
431 | | /* |
432 | | * UATs |
433 | | */ |
434 | | |
435 | | typedef struct _generic_one_id_string { |
436 | | unsigned id; |
437 | | char *name; |
438 | | } generic_one_id_string_t; |
439 | | |
440 | | /* ID -> Name */ |
441 | | static void * |
442 | 0 | copy_generic_one_id_string_cb(void* n, const void* o, size_t size _U_) { |
443 | 0 | generic_one_id_string_t* new_rec = (generic_one_id_string_t*)n; |
444 | 0 | const generic_one_id_string_t* old_rec = (const generic_one_id_string_t*)o; |
445 | |
|
446 | 0 | new_rec->name = g_strdup(old_rec->name); |
447 | 0 | new_rec->id = old_rec->id; |
448 | 0 | return new_rec; |
449 | 0 | } |
450 | | |
451 | | static bool |
452 | 0 | update_generic_one_identifier_16bit(void *r, char **err) { |
453 | 0 | generic_one_id_string_t *rec = (generic_one_id_string_t *)r; |
454 | |
|
455 | 0 | if (rec->id > 0xffff) { |
456 | 0 | *err = ws_strdup_printf("We currently only support 16 bit identifiers (ID: %i Name: %s)", rec->id, rec->name); |
457 | 0 | return false; |
458 | 0 | } |
459 | | |
460 | 0 | if (rec->name == NULL || rec->name[0] == 0) { |
461 | 0 | *err = g_strdup("Name cannot be empty"); |
462 | 0 | return false; |
463 | 0 | } |
464 | | |
465 | 0 | return true; |
466 | 0 | } |
467 | | |
468 | | static void |
469 | 0 | free_generic_one_id_string_cb(void*r) { |
470 | 0 | generic_one_id_string_t* rec = (generic_one_id_string_t*)r; |
471 | | /* freeing result of g_strdup */ |
472 | 0 | g_free(rec->name); |
473 | 0 | rec->name = NULL; |
474 | 0 | } |
475 | | |
476 | | /* |
477 | | * UAT DoIP Diagnostic Addresses |
478 | | */ |
479 | 16 | #define DATAFILE_DOIP_DIAG_ADDRESSES "DoIP_diagnostic_addresses" |
480 | | |
481 | | static GHashTable *data_doip_diag_addresses; |
482 | | static generic_one_id_string_t* doip_diag_addresses; |
483 | | static unsigned doip_diag_address_count; |
484 | | |
485 | 0 | UAT_HEX_CB_DEF(doip_diag_addresses, id, generic_one_id_string_t) Unexecuted instantiation: packet-doip.c:doip_diag_addresses_id_set_cb Unexecuted instantiation: packet-doip.c:doip_diag_addresses_id_tostr_cb |
486 | 0 | UAT_CSTRING_CB_DEF(doip_diag_addresses, name, generic_one_id_string_t) |
487 | | |
488 | | static void |
489 | 16 | post_update_doip_diag_addresses(void) { |
490 | | /* destroy old hash table, if it exists */ |
491 | 16 | if (data_doip_diag_addresses) { |
492 | 0 | g_hash_table_destroy(data_doip_diag_addresses); |
493 | 0 | } |
494 | | |
495 | | /* create new hash table */ |
496 | 16 | data_doip_diag_addresses = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); |
497 | | |
498 | 16 | for (unsigned i = 0; i < doip_diag_address_count; i++) { |
499 | 0 | g_hash_table_insert(data_doip_diag_addresses, GUINT_TO_POINTER(doip_diag_addresses[i].id), doip_diag_addresses[i].name); |
500 | 0 | } |
501 | 16 | } |
502 | | |
503 | | static void |
504 | 0 | reset_doip_diag_addresses_cb(void) { |
505 | | /* destroy hash table, if it exists */ |
506 | 0 | if (data_doip_diag_addresses) { |
507 | 0 | g_hash_table_destroy(data_doip_diag_addresses); |
508 | 0 | data_doip_diag_addresses = NULL; |
509 | 0 | } |
510 | 0 | } |
511 | | |
512 | | static proto_item * |
513 | 44 | doip_prototree_add_with_resolv(proto_tree* doip_tree, int hfindex, int hfindex_name, tvbuff_t* tvb, const int start, int length, const unsigned encoding, unsigned *diag_addr) { |
514 | 44 | unsigned diag_addr_tmp; |
515 | 44 | proto_item *ti; |
516 | 44 | proto_tree *tree; |
517 | | |
518 | 44 | ti = proto_tree_add_item_ret_uint(doip_tree, hfindex, tvb, start, length, encoding, &diag_addr_tmp); |
519 | 44 | const char *name = NULL; |
520 | | |
521 | 44 | if (data_doip_diag_addresses != NULL) { |
522 | 44 | name = g_hash_table_lookup(data_doip_diag_addresses, GUINT_TO_POINTER(diag_addr_tmp)); |
523 | 44 | } |
524 | | |
525 | 44 | if (name != NULL) { |
526 | 0 | proto_item_append_text(ti, " (%s)", name); |
527 | 0 | tree = proto_item_add_subtree(ti, ett_address); |
528 | 0 | ti = proto_tree_add_string(tree, hfindex_name, tvb, start, length, name); |
529 | |
|
530 | 0 | if (doip_hide_address_names) { |
531 | 0 | proto_item_set_hidden(ti); |
532 | 0 | } |
533 | 0 | } |
534 | | |
535 | 44 | if (diag_addr != NULL) { |
536 | 44 | *diag_addr = diag_addr_tmp; |
537 | 44 | } |
538 | | |
539 | 44 | return ti; |
540 | 44 | } |
541 | | |
542 | | /* |
543 | | * UAT DoIP Payload Types |
544 | | */ |
545 | 16 | #define DATAFILE_DOIP_PAYLOAD_TYPES "DoIP_payload_types" |
546 | | |
547 | | static GHashTable *data_doip_payload_types; |
548 | | static generic_one_id_string_t* doip_payload_types; |
549 | | static unsigned doip_payload_type_count; |
550 | | |
551 | 0 | UAT_HEX_CB_DEF(doip_payload_types, id, generic_one_id_string_t) Unexecuted instantiation: packet-doip.c:doip_payload_types_id_set_cb Unexecuted instantiation: packet-doip.c:doip_payload_types_id_tostr_cb |
552 | 0 | UAT_CSTRING_CB_DEF(doip_payload_types, name, generic_one_id_string_t) |
553 | | |
554 | | static void |
555 | 16 | post_update_doip_payload_types(void) { |
556 | | /* destroy old hash table, if it exists */ |
557 | 16 | if (data_doip_payload_types) { |
558 | 0 | g_hash_table_destroy(data_doip_payload_types); |
559 | 0 | } |
560 | | |
561 | | /* create new hash table */ |
562 | 16 | data_doip_payload_types = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); |
563 | | |
564 | 16 | for (unsigned i = 0; i < doip_payload_type_count; i++) { |
565 | 0 | g_hash_table_insert(data_doip_payload_types, GUINT_TO_POINTER(doip_payload_types[i].id), doip_payload_types[i].name); |
566 | 0 | } |
567 | 16 | } |
568 | | |
569 | | static void |
570 | 0 | reset_doip_payload_type_cb(void) { |
571 | | /* destroy hash table, if it exists */ |
572 | 0 | if (data_doip_payload_types) { |
573 | 0 | g_hash_table_destroy(data_doip_payload_types); |
574 | 0 | data_doip_payload_types = NULL; |
575 | 0 | } |
576 | 0 | } |
577 | | |
578 | | static const char* |
579 | 27 | resolve_doip_payload_type(wmem_allocator_t *scope, uint16_t payload_type, bool is_col) { |
580 | 27 | const char *tmp = NULL; |
581 | | |
582 | 27 | if (data_doip_payload_types != NULL) { |
583 | 27 | tmp = g_hash_table_lookup(data_doip_payload_types, GUINT_TO_POINTER(payload_type)); |
584 | 27 | } |
585 | | |
586 | | /* lets look at the static values, if nothing is configured */ |
587 | 27 | if (tmp == NULL) { |
588 | 27 | tmp = try_val_to_str(payload_type, doip_payloads); |
589 | 27 | } |
590 | | |
591 | | /* no configured or standardized name known */ |
592 | 27 | if (tmp != NULL) { |
593 | 23 | if (is_col) { |
594 | 0 | return tmp; |
595 | 23 | } else { |
596 | 23 | return wmem_strdup_printf(scope, "%s (0x%04x)", tmp, payload_type); |
597 | 23 | } |
598 | 23 | } |
599 | | |
600 | | /* just give back unknown */ |
601 | 4 | if (is_col) { |
602 | 0 | return wmem_strdup_printf(scope, "0x%04x Unknown Payload", payload_type); |
603 | 4 | } else { |
604 | 4 | return wmem_strdup_printf(scope, "Unknown (0x%04x)", payload_type); |
605 | 4 | } |
606 | 4 | } |
607 | | |
608 | | static void |
609 | | add_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *doip_tree) |
610 | 27 | { |
611 | 27 | uint32_t len; |
612 | 27 | uint32_t payload_type; |
613 | | |
614 | 27 | proto_tree *subtree = proto_tree_add_subtree(doip_tree, tvb, DOIP_VERSION_OFFSET, DOIP_HEADER_LEN, ett_header, NULL, "Header"); |
615 | 27 | proto_tree_add_item(subtree, hf_doip_version, tvb, DOIP_VERSION_OFFSET, DOIP_VERSION_LEN, ENC_BIG_ENDIAN); |
616 | 27 | proto_tree_add_item(subtree, hf_doip_inv_version, tvb, DOIP_INV_VERSION_OFFSET, DOIP_INV_VERSION_LEN, ENC_BIG_ENDIAN); |
617 | 27 | payload_type = tvb_get_uint16(tvb, DOIP_TYPE_OFFSET, ENC_BIG_ENDIAN); |
618 | 27 | proto_tree_add_uint_format(subtree, hf_doip_type, tvb, DOIP_TYPE_OFFSET, DOIP_TYPE_LEN, payload_type, "Type: %s", resolve_doip_payload_type(pinfo->pool, payload_type, false)); |
619 | 27 | proto_tree_add_item_ret_uint(subtree, hf_doip_length, tvb, DOIP_LENGTH_OFFSET, DOIP_LENGTH_LEN, ENC_BIG_ENDIAN, &len); |
620 | | |
621 | 27 | if (tvb_captured_length(tvb) < len) { |
622 | 26 | proto_tree_add_expert(doip_tree, pinfo, &ei_doip_illegal_length_field, tvb, DOIP_LENGTH_OFFSET, DOIP_LENGTH_LEN); |
623 | 26 | col_append_str(pinfo->cinfo, COL_INFO, " [DoIP Length Field: Illegal Value]"); |
624 | 26 | } |
625 | 27 | } |
626 | | |
627 | | |
628 | | static void |
629 | | add_generic_header_nack_fields(proto_tree *doip_tree, tvbuff_t *tvb) |
630 | 1 | { |
631 | 1 | proto_tree_add_item(doip_tree, hf_generic_nack_code, tvb, DOIP_GENERIC_NACK_OFFSET, DOIP_GENERIC_NACK_LEN, ENC_NA); |
632 | 1 | } |
633 | | |
634 | | |
635 | | static void |
636 | | add_vehicle_identification_eid_fields(proto_tree *doip_tree, tvbuff_t *tvb) |
637 | 0 | { |
638 | 0 | proto_tree_add_item(doip_tree, hf_eid, tvb, DOIP_VEHICLE_IDENTIFICATION_EID_OFFSET, DOIP_COMMON_EID_LEN, ENC_NA); |
639 | 0 | } |
640 | | |
641 | | |
642 | | static void |
643 | | add_vehicle_identification_vin_fields(proto_tree *doip_tree, tvbuff_t *tvb) |
644 | 0 | { |
645 | 0 | proto_tree_add_item(doip_tree, hf_vin, tvb, DOIP_VEHICLE_IDENTIFICATION_VIN_OFFSET, DOIP_COMMON_VIN_LEN, ENC_ASCII); |
646 | 0 | } |
647 | | |
648 | | |
649 | | static void |
650 | | add_routing_activation_request_fields(proto_tree *doip_tree, tvbuff_t *tvb, uint8_t version) |
651 | 0 | { |
652 | 0 | doip_prototree_add_with_resolv(doip_tree, hf_source_address, hf_source_address_name, tvb, DOIP_ROUTING_ACTIVATION_REQ_SRC_OFFSET, DOIP_ROUTING_ACTIVATION_REQ_SRC_LEN, ENC_BIG_ENDIAN, NULL); |
653 | |
|
654 | 0 | if (version == ISO13400_2010) { |
655 | 0 | proto_tree_add_item(doip_tree, hf_activation_type_v1, tvb, DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET, DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V1, ENC_BIG_ENDIAN); |
656 | 0 | proto_tree_add_item(doip_tree, hf_reserved_iso, tvb, DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V1, DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN, ENC_BIG_ENDIAN); |
657 | |
|
658 | 0 | if ( tvb_bytes_exist(tvb, DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V1, DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN) ) { |
659 | 0 | proto_tree_add_item(doip_tree, hf_reserved_oem, tvb, DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V1, DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN, ENC_BIG_ENDIAN); |
660 | 0 | } |
661 | 0 | } else if ((version == ISO13400_2012) || (version == ISO13400_2019)) { |
662 | 0 | proto_tree_add_item(doip_tree, hf_activation_type_v2, tvb, DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET, DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V2, ENC_NA); |
663 | 0 | proto_tree_add_item(doip_tree, hf_reserved_iso, tvb, DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V2, DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN, ENC_BIG_ENDIAN); |
664 | |
|
665 | 0 | if ( tvb_bytes_exist(tvb, DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V2, DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN) ) { |
666 | 0 | proto_tree_add_item(doip_tree, hf_reserved_oem, tvb, DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V2, DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN, ENC_BIG_ENDIAN); |
667 | 0 | } |
668 | 0 | } |
669 | 0 | } |
670 | | |
671 | | |
672 | | static void |
673 | | add_routing_activation_response_fields(proto_tree *doip_tree, tvbuff_t *tvb) |
674 | 0 | { |
675 | 0 | doip_prototree_add_with_resolv(doip_tree, hf_tester_logical_address, hf_tester_logical_address_name, tvb, DOIP_ROUTING_ACTIVATION_RES_TESTER_OFFSET, DOIP_ROUTING_ACTIVATION_RES_TESTER_LEN, ENC_BIG_ENDIAN, NULL); |
676 | 0 | doip_prototree_add_with_resolv(doip_tree, hf_source_address, hf_source_address_name, tvb, DOIP_ROUTING_ACTIVATION_RES_ENTITY_OFFSET, DOIP_ROUTING_ACTIVATION_RES_ENTITY_LEN, ENC_BIG_ENDIAN, NULL); |
677 | 0 | proto_tree_add_item(doip_tree, hf_response_code, tvb, DOIP_ROUTING_ACTIVATION_RES_CODE_OFFSET, DOIP_ROUTING_ACTIVATION_RES_CODE_LEN, ENC_NA); |
678 | 0 | proto_tree_add_item(doip_tree, hf_reserved_iso, tvb, DOIP_ROUTING_ACTIVATION_RES_ISO_OFFSET, DOIP_ROUTING_ACTIVATION_RES_ISO_LEN, ENC_BIG_ENDIAN); |
679 | |
|
680 | 0 | if ( tvb_bytes_exist(tvb, DOIP_ROUTING_ACTIVATION_RES_OEM_OFFSET, DOIP_ROUTING_ACTIVATION_RES_OEM_LEN) ) { |
681 | 0 | proto_tree_add_item(doip_tree, hf_reserved_oem, tvb, DOIP_ROUTING_ACTIVATION_RES_OEM_OFFSET, DOIP_ROUTING_ACTIVATION_RES_OEM_LEN, ENC_BIG_ENDIAN); |
682 | 0 | } |
683 | 0 | } |
684 | | |
685 | | |
686 | | static void |
687 | | add_vehicle_announcement_message_fields(proto_tree *doip_tree, tvbuff_t *tvb) |
688 | 0 | { |
689 | 0 | proto_tree_add_item(doip_tree, hf_vin, tvb, DOIP_VEHICLE_ANNOUNCEMENT_VIN_OFFSET, DOIP_COMMON_VIN_LEN, ENC_ASCII); |
690 | 0 | doip_prototree_add_with_resolv(doip_tree, hf_logical_address, hf_logical_address_name, tvb, DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_LEN, ENC_BIG_ENDIAN, NULL); |
691 | 0 | proto_tree_add_item(doip_tree, hf_eid, tvb, DOIP_VEHICLE_ANNOUNCEMENT_EID_OFFSET, DOIP_COMMON_EID_LEN, ENC_NA); |
692 | 0 | proto_tree_add_item(doip_tree, hf_gid, tvb, DOIP_VEHICLE_ANNOUNCEMENT_GID_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_GID_LEN, ENC_NA); |
693 | 0 | proto_tree_add_item(doip_tree, hf_further_action, tvb, DOIP_VEHICLE_ANNOUNCEMENT_ACTION_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_ACTION_LEN, ENC_BIG_ENDIAN); |
694 | |
|
695 | 0 | if ( tvb_bytes_exist(tvb, DOIP_VEHICLE_ANNOUNCEMENT_SYNC_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_SYNC_LEN) ) { |
696 | | /* Not part of version 1 and optional in version 2. */ |
697 | 0 | proto_tree_add_item(doip_tree, hf_sync_status, tvb, DOIP_VEHICLE_ANNOUNCEMENT_SYNC_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_SYNC_LEN, ENC_BIG_ENDIAN); |
698 | 0 | } |
699 | 0 | } |
700 | | |
701 | | |
702 | | static void |
703 | | add_alive_check_response_fields(proto_tree *doip_tree, tvbuff_t *tvb) |
704 | 0 | { |
705 | 0 | doip_prototree_add_with_resolv(doip_tree, hf_source_address, hf_source_address_name, tvb, DOIP_ALIVE_CHECK_RESPONSE_SOURCE_OFFSET, DOIP_ALIVE_CHECK_RESPONSE_SOURCE_LEN, ENC_BIG_ENDIAN, NULL); |
706 | 0 | } |
707 | | |
708 | | |
709 | | static void |
710 | | add_entity_status_response_fields(proto_tree *doip_tree, tvbuff_t *tvb) |
711 | 0 | { |
712 | 0 | proto_tree_add_item(doip_tree, hf_node_type, tvb, DOIP_ENTITY_STATUS_RESPONSE_NODE_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_NODE_LEN, ENC_NA); |
713 | 0 | proto_tree_add_item(doip_tree, hf_max_sockets, tvb, DOIP_ENTITY_STATUS_RESPONSE_MCTS_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_MCTS_LEN, ENC_NA); |
714 | 0 | proto_tree_add_item(doip_tree, hf_current_sockets, tvb, DOIP_ENTITY_STATUS_RESPONSE_NCTS_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_NCTS_LEN, ENC_NA); |
715 | 0 | if ( tvb_bytes_exist(tvb, DOIP_ENTITY_STATUS_RESPONSE_MDS_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_MDS_LEN) ) { |
716 | 0 | proto_tree_add_item(doip_tree, hf_max_data_size, tvb, DOIP_ENTITY_STATUS_RESPONSE_MDS_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_MDS_LEN, ENC_BIG_ENDIAN); |
717 | 0 | } |
718 | 0 | } |
719 | | |
720 | | |
721 | | static void |
722 | | add_power_mode_information_response_fields(proto_tree *doip_tree, tvbuff_t *tvb) |
723 | 0 | { |
724 | 0 | proto_tree_add_item(doip_tree, hf_power_mode, tvb, DOIP_POWER_MODE_OFFSET, DOIP_POWER_MODE_LEN, ENC_NA); |
725 | 0 | } |
726 | | |
727 | | |
728 | | static void |
729 | | add_diagnostic_message_fields(proto_tree *doip_tree, tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) |
730 | 22 | { |
731 | 22 | doip_info_t doip_info; |
732 | 22 | uint32_t tmp; |
733 | | |
734 | 22 | doip_prototree_add_with_resolv(doip_tree, hf_source_address, hf_source_address_name, tvb, DOIP_DIAG_COMMON_SOURCE_OFFSET, DOIP_DIAG_COMMON_SOURCE_LEN, ENC_BIG_ENDIAN, &tmp); |
735 | 22 | doip_info.source_address = tmp; |
736 | 22 | doip_prototree_add_with_resolv(doip_tree, hf_target_address, hf_target_address_name, tvb, DOIP_DIAG_COMMON_TARGET_OFFSET, DOIP_DIAG_COMMON_TARGET_LEN, ENC_BIG_ENDIAN, &tmp); |
737 | 22 | doip_info.target_address = tmp; |
738 | | |
739 | 22 | if (uds_handle != 0) { |
740 | 22 | call_dissector_with_data(uds_handle, tvb_new_subset_remaining(tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET), pinfo, parent_tree, &doip_info); |
741 | 22 | } else if (tvb_reported_length_remaining(tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET) > 0) { |
742 | 0 | proto_tree_add_item(doip_tree, hf_data, tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET, tvb_reported_length_remaining(tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET), ENC_NA); |
743 | 0 | } |
744 | 22 | } |
745 | | |
746 | | |
747 | | static void |
748 | | add_diagnostic_message_ack_fields(proto_tree *doip_tree, tvbuff_t *tvb) |
749 | 0 | { |
750 | 0 | doip_prototree_add_with_resolv(doip_tree, hf_source_address, hf_source_address_name, tvb, DOIP_DIAG_COMMON_SOURCE_OFFSET, DOIP_DIAG_COMMON_SOURCE_LEN, ENC_BIG_ENDIAN, NULL); |
751 | 0 | doip_prototree_add_with_resolv(doip_tree, hf_target_address, hf_target_address_name, tvb, DOIP_DIAG_COMMON_TARGET_OFFSET, DOIP_DIAG_COMMON_TARGET_LEN, ENC_BIG_ENDIAN, NULL); |
752 | 0 | proto_tree_add_item(doip_tree, hf_ack_code, tvb, DOIP_DIAG_MESSAGE_ACK_CODE_OFFSET, DOIP_DIAG_MESSAGE_ACK_CODE_LEN, ENC_NA); |
753 | |
|
754 | 0 | if (tvb_captured_length_remaining(tvb, DOIP_DIAG_MESSAGE_ACK_PREVIOUS_OFFSET) > 0) { |
755 | 0 | proto_tree_add_item(doip_tree, hf_previous, tvb, DOIP_DIAG_MESSAGE_ACK_PREVIOUS_OFFSET, tvb_captured_length_remaining(tvb, DOIP_DIAG_MESSAGE_ACK_PREVIOUS_OFFSET), ENC_NA); |
756 | 0 | } |
757 | 0 | } |
758 | | |
759 | | |
760 | | static void |
761 | | add_diagnostic_message_nack_fields(proto_tree *doip_tree, tvbuff_t *tvb) |
762 | 0 | { |
763 | 0 | doip_prototree_add_with_resolv(doip_tree, hf_source_address, hf_source_address_name, tvb, DOIP_DIAG_COMMON_SOURCE_OFFSET, DOIP_DIAG_COMMON_SOURCE_LEN, ENC_BIG_ENDIAN, NULL); |
764 | 0 | doip_prototree_add_with_resolv(doip_tree, hf_target_address, hf_target_address_name, tvb, DOIP_DIAG_COMMON_TARGET_OFFSET, DOIP_DIAG_COMMON_TARGET_LEN, ENC_BIG_ENDIAN, NULL); |
765 | 0 | proto_tree_add_item(doip_tree, hf_nack_code, tvb, DOIP_DIAG_MESSAGE_NACK_CODE_OFFSET, DOIP_DIAG_MESSAGE_NACK_CODE_LEN, ENC_NA); |
766 | |
|
767 | 0 | if (tvb_captured_length_remaining(tvb, DOIP_DIAG_MESSAGE_NACK_PREVIOUS_OFFSET) > 0) { |
768 | 0 | proto_tree_add_item(doip_tree, hf_previous, tvb, DOIP_DIAG_MESSAGE_NACK_PREVIOUS_OFFSET, tvb_captured_length_remaining(tvb, DOIP_DIAG_MESSAGE_NACK_PREVIOUS_OFFSET), ENC_NA); |
769 | 0 | } |
770 | 0 | } |
771 | | |
772 | | |
773 | | /* DoIP protocol dissector */ |
774 | | static void |
775 | | dissect_doip_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) |
776 | 27 | { |
777 | 27 | uint8_t version = tvb_get_uint8(tvb, DOIP_VERSION_OFFSET); |
778 | 27 | uint16_t payload_type = tvb_get_ntohs(tvb, DOIP_TYPE_OFFSET); |
779 | | |
780 | 27 | int raw_offset_tvb = tvb_raw_offset(tvb); |
781 | 27 | int *first_offset = (int *)p_get_proto_data(wmem_file_scope(), pinfo, proto_doip, 0); |
782 | | |
783 | 27 | if (!first_offset) { |
784 | 27 | first_offset = wmem_new0(wmem_file_scope(), int); |
785 | 27 | *first_offset = raw_offset_tvb; |
786 | 27 | p_add_proto_data(wmem_file_scope(), pinfo, proto_doip, 0, first_offset); |
787 | 27 | } |
788 | | |
789 | | /* Set protocol and clear information columns */ |
790 | 27 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "DoIP"); |
791 | | |
792 | 27 | if (*first_offset == raw_offset_tvb) { |
793 | 27 | col_clear(pinfo->cinfo, COL_INFO); |
794 | 27 | } else { |
795 | 0 | col_append_str(pinfo->cinfo, COL_INFO, " / "); |
796 | 0 | } |
797 | | |
798 | 27 | if ( |
799 | 27 | version == ISO13400_2010 || |
800 | 27 | version == ISO13400_2012 || |
801 | 27 | version == ISO13400_2019 || |
802 | 27 | version == ISO13400_2019_AMD1 || |
803 | 27 | (version == DEFAULT_VALUE && (payload_type >= DOIP_VEHICLE_IDENTIFICATION_REQ && payload_type <= DOIP_VEHICLE_IDENTIFICATION_REQ_VIN)) |
804 | 27 | ) { |
805 | 0 | col_append_str(pinfo->cinfo, COL_INFO, resolve_doip_payload_type(pinfo->pool, payload_type, true)); |
806 | 27 | } else { |
807 | 27 | col_append_str(pinfo->cinfo, COL_INFO, "Invalid/unsupported DoIP version"); |
808 | 27 | } |
809 | | |
810 | | |
811 | 27 | if (tree) { |
812 | 27 | proto_item *ti = NULL; |
813 | 27 | proto_tree *doip_tree = NULL; |
814 | | |
815 | 27 | ti = proto_tree_add_item(tree, proto_doip, tvb, 0, -1, ENC_NA); |
816 | 27 | doip_tree = proto_item_add_subtree(ti, ett_doip); |
817 | | |
818 | 27 | add_header(tvb, pinfo, doip_tree); |
819 | | |
820 | 27 | switch (payload_type) { |
821 | 1 | case DOIP_GENERIC_NACK: |
822 | 1 | add_generic_header_nack_fields(doip_tree, tvb); |
823 | 1 | break; |
824 | | |
825 | 0 | case DOIP_VEHICLE_IDENTIFICATION_REQ: |
826 | 0 | break; |
827 | | |
828 | 0 | case DOIP_VEHICLE_IDENTIFICATION_REQ_EID: |
829 | 0 | add_vehicle_identification_eid_fields(doip_tree, tvb); |
830 | 0 | break; |
831 | | |
832 | 0 | case DOIP_VEHICLE_IDENTIFICATION_REQ_VIN: |
833 | 0 | add_vehicle_identification_vin_fields(doip_tree, tvb); |
834 | 0 | break; |
835 | | |
836 | 0 | case DOIP_ROUTING_ACTIVATION_REQUEST: |
837 | 0 | add_routing_activation_request_fields(doip_tree, tvb, version); |
838 | 0 | break; |
839 | | |
840 | 0 | case DOIP_ROUTING_ACTIVATION_RESPONSE: |
841 | 0 | add_routing_activation_response_fields(doip_tree, tvb); |
842 | 0 | break; |
843 | | |
844 | 0 | case DOIP_VEHICLE_ANNOUNCEMENT_MESSAGE: |
845 | 0 | add_vehicle_announcement_message_fields(doip_tree, tvb); |
846 | 0 | break; |
847 | | |
848 | 0 | case DOIP_ALIVE_CHECK_REQUEST: |
849 | 0 | break; |
850 | | |
851 | 0 | case DOIP_ALIVE_CHECK_RESPONSE: |
852 | 0 | add_alive_check_response_fields(doip_tree, tvb); |
853 | 0 | break; |
854 | | |
855 | 0 | case DOIP_ENTITY_STATUS_REQUEST: |
856 | 0 | break; |
857 | | |
858 | 0 | case DOIP_ENTITY_STATUS_RESPONSE: |
859 | 0 | add_entity_status_response_fields(doip_tree, tvb); |
860 | 0 | break; |
861 | | |
862 | 0 | case DOIP_POWER_INFORMATION_REQUEST: |
863 | 0 | break; |
864 | | |
865 | 0 | case DOIP_POWER_INFORMATION_RESPONSE: |
866 | 0 | add_power_mode_information_response_fields(doip_tree, tvb); |
867 | 0 | break; |
868 | | |
869 | 22 | case DOIP_DIAGNOSTIC_MESSAGE: |
870 | 22 | add_diagnostic_message_fields(doip_tree, tvb, pinfo, tree); |
871 | 22 | break; |
872 | | |
873 | 0 | case DOIP_DIAGNOSTIC_MESSAGE_ACK: |
874 | 0 | add_diagnostic_message_ack_fields(doip_tree, tvb); |
875 | 0 | break; |
876 | | |
877 | 0 | case DOIP_DIAGNOSTIC_MESSAGE_NACK: |
878 | 0 | add_diagnostic_message_nack_fields(doip_tree, tvb); |
879 | 0 | break; |
880 | 27 | } |
881 | 27 | } else if (payload_type == DOIP_DIAGNOSTIC_MESSAGE) { |
882 | | /* Show UDS details in info column */ |
883 | 0 | if (uds_handle != 0) { |
884 | 0 | doip_info_t doip_info; |
885 | 0 | doip_info.source_address = tvb_get_uint16(tvb, DOIP_DIAG_COMMON_SOURCE_OFFSET, ENC_BIG_ENDIAN); |
886 | 0 | doip_info.target_address = tvb_get_uint16(tvb, DOIP_DIAG_COMMON_TARGET_OFFSET, ENC_BIG_ENDIAN); |
887 | 0 | call_dissector_with_data(uds_handle, tvb_new_subset_remaining(tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET), pinfo, NULL, &doip_info); |
888 | 0 | } |
889 | 0 | } |
890 | 27 | } |
891 | | |
892 | | |
893 | | /* determine PDU length of protocol DoIP */ |
894 | | static unsigned |
895 | | get_doip_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *p _U_) |
896 | 32 | { |
897 | 32 | uint8_t ver1 = tvb_get_uint8(tvb, offset + DOIP_VERSION_OFFSET); |
898 | 32 | uint8_t ver2 = tvb_get_uint8(tvb, offset + DOIP_INV_VERSION_OFFSET); |
899 | | |
900 | 32 | if (ver1 != ((~ver2) & 0xff)) { |
901 | | /* if ver2 is not the inverse of ver1, we are not at the start of a DoIP message! */ |
902 | | /* bounds_error: (0 < return < DOIP_HEADER_LEN) */ |
903 | 5 | return 1; |
904 | 5 | } |
905 | | |
906 | | /* PDU Length = length field value + header length */ |
907 | 27 | uint32_t ret = tvb_get_ntohl(tvb, offset + DOIP_LENGTH_OFFSET) + DOIP_HEADER_LEN; |
908 | | |
909 | 27 | if (ret < DOIP_HEADER_LEN || ret > 0x7fffffff) { |
910 | | /* catch illegal length fields (overflow or too big) */ |
911 | 3 | return DOIP_HEADER_LEN; |
912 | 3 | } |
913 | | |
914 | 24 | return ret; |
915 | 27 | } |
916 | | |
917 | | |
918 | | static int |
919 | | dissect_doip_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
920 | 27 | { |
921 | 27 | dissect_doip_message(tvb, pinfo, tree); |
922 | 27 | return tvb_captured_length(tvb); |
923 | 27 | } |
924 | | |
925 | | |
926 | | static int |
927 | | dissect_doip(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, void *data) |
928 | 28 | { |
929 | 28 | tcp_dissect_pdus(tvb, pinfo, tree, true, DOIP_HEADER_LEN, get_doip_message_len, dissect_doip_pdu, data); |
930 | 28 | return tvb_captured_length(tvb); |
931 | 28 | } |
932 | | |
933 | | |
934 | | /* Register DoIP Protocol */ |
935 | | void |
936 | | proto_register_doip(void) |
937 | 16 | { |
938 | 16 | module_t *doip_module = NULL; |
939 | 16 | expert_module_t *expert_module_doip = NULL; |
940 | 16 | uat_t *doip_diag_addr_uat = NULL; |
941 | 16 | uat_t *doip_payload_type_uat = NULL; |
942 | | |
943 | 16 | static hf_register_info hf[] = { |
944 | | /* Header */ |
945 | 16 | { &hf_doip_version, |
946 | 16 | { "Version", "doip.version", |
947 | 16 | FT_UINT8, BASE_HEX, |
948 | 16 | VALS(doip_versions), 0x0, |
949 | 16 | NULL, HFILL } |
950 | 16 | }, |
951 | 16 | { &hf_doip_inv_version, |
952 | 16 | { "Inverse version", "doip.inverse", |
953 | 16 | FT_UINT8, BASE_HEX, |
954 | 16 | NULL, 0x0, |
955 | 16 | NULL, HFILL } |
956 | 16 | }, |
957 | 16 | { &hf_doip_type, |
958 | 16 | { "Type", "doip.type", |
959 | 16 | FT_UINT16, BASE_HEX, |
960 | 16 | VALS(doip_payloads), 0x0, |
961 | 16 | NULL, HFILL } |
962 | 16 | }, |
963 | 16 | { &hf_doip_length, |
964 | 16 | { "Length", "doip.length", |
965 | 16 | FT_UINT32, BASE_DEC, |
966 | 16 | NULL, 0x0, |
967 | 16 | NULL, HFILL } |
968 | 16 | }, |
969 | | /* Generic NACK */ |
970 | 16 | { |
971 | 16 | &hf_generic_nack_code, |
972 | 16 | { |
973 | 16 | "DoIP Header NACK code", "doip.nack_code", |
974 | 16 | FT_UINT8, BASE_HEX, |
975 | 16 | VALS(nack_codes), 0x00, |
976 | 16 | NULL, HFILL |
977 | 16 | } |
978 | 16 | }, |
979 | | /* Vehicle announcement message */ |
980 | 16 | { |
981 | 16 | &hf_vin, |
982 | 16 | { |
983 | 16 | "VIN", "doip.vin", |
984 | 16 | FT_STRING, BASE_NONE, |
985 | 16 | NULL, 0x00, |
986 | 16 | NULL, HFILL |
987 | 16 | } |
988 | 16 | }, |
989 | 16 | { |
990 | 16 | &hf_logical_address, |
991 | 16 | { |
992 | 16 | "Logical Address", "doip.logical_address", |
993 | 16 | FT_UINT16, BASE_HEX, |
994 | 16 | NULL, 0x00, |
995 | 16 | NULL, HFILL |
996 | 16 | } |
997 | 16 | }, |
998 | 16 | { |
999 | 16 | &hf_logical_address_name, |
1000 | 16 | { |
1001 | 16 | "Logical Address Name", "doip.logical_address_name", |
1002 | 16 | FT_STRING, BASE_NONE, |
1003 | 16 | NULL, 0x00, |
1004 | 16 | NULL, HFILL |
1005 | 16 | } |
1006 | 16 | }, |
1007 | 16 | { |
1008 | 16 | &hf_eid, |
1009 | 16 | { |
1010 | 16 | "EID", "doip.eid", |
1011 | 16 | FT_BYTES, BASE_NONE, |
1012 | 16 | NULL, 0x00, |
1013 | 16 | NULL, HFILL |
1014 | 16 | } |
1015 | 16 | }, |
1016 | 16 | { |
1017 | 16 | &hf_gid, |
1018 | 16 | { |
1019 | 16 | "GID", "doip.gid", |
1020 | 16 | FT_BYTES, BASE_NONE, |
1021 | 16 | NULL, 0x00, |
1022 | 16 | NULL, HFILL |
1023 | 16 | } |
1024 | 16 | }, |
1025 | 16 | { |
1026 | 16 | &hf_further_action, |
1027 | 16 | { |
1028 | 16 | "Further action required", "doip.further_action", |
1029 | 16 | FT_UINT8, BASE_HEX, |
1030 | 16 | VALS(action_codes), 0x00, |
1031 | 16 | NULL, HFILL |
1032 | 16 | } |
1033 | 16 | }, |
1034 | 16 | { |
1035 | 16 | &hf_sync_status, |
1036 | 16 | { |
1037 | 16 | "VIN/GID sync. status", "doip.sync_status", |
1038 | 16 | FT_UINT8, BASE_HEX, |
1039 | 16 | VALS(sync_status), 0x00, |
1040 | 16 | NULL, HFILL |
1041 | 16 | } |
1042 | 16 | }, |
1043 | | /* Diagnostic power mode information response */ |
1044 | 16 | { |
1045 | 16 | &hf_power_mode, |
1046 | 16 | { |
1047 | 16 | "Diagnostic power mode", "doip.power_mode", |
1048 | 16 | FT_UINT8, BASE_HEX, |
1049 | 16 | VALS(power_modes), 0x00, |
1050 | 16 | NULL, HFILL |
1051 | 16 | } |
1052 | 16 | }, |
1053 | | /* Entity status response */ |
1054 | 16 | { |
1055 | 16 | &hf_node_type, |
1056 | 16 | { |
1057 | 16 | "Node type", "doip.node_type", |
1058 | 16 | FT_UINT8, BASE_HEX, |
1059 | 16 | VALS(node_types), 0x00, |
1060 | 16 | NULL, HFILL |
1061 | 16 | } |
1062 | 16 | }, |
1063 | 16 | { |
1064 | 16 | &hf_max_sockets, |
1065 | 16 | { |
1066 | 16 | "Max concurrent sockets", "doip.max_sockets", |
1067 | 16 | FT_UINT8, BASE_DEC, |
1068 | 16 | NULL, 0x00, |
1069 | 16 | NULL, HFILL |
1070 | 16 | } |
1071 | 16 | }, |
1072 | 16 | { |
1073 | 16 | &hf_current_sockets, |
1074 | 16 | { |
1075 | 16 | "Currently open sockets", "doip.sockets", |
1076 | 16 | FT_UINT8, BASE_DEC, |
1077 | 16 | NULL, 0x00, |
1078 | 16 | NULL, HFILL |
1079 | 16 | } |
1080 | 16 | }, |
1081 | 16 | { |
1082 | 16 | &hf_max_data_size, |
1083 | 16 | { |
1084 | 16 | "Max data size", "doip.max_data_size", |
1085 | 16 | FT_UINT32, BASE_DEC, |
1086 | 16 | NULL, 0x00, |
1087 | 16 | NULL, HFILL |
1088 | 16 | } |
1089 | 16 | }, |
1090 | | /* Common */ |
1091 | 16 | { |
1092 | 16 | &hf_source_address, |
1093 | 16 | { |
1094 | 16 | "Source Address", "doip.source_address", |
1095 | 16 | FT_UINT16, BASE_HEX, |
1096 | 16 | NULL, 0x00, |
1097 | 16 | NULL, HFILL |
1098 | 16 | } |
1099 | 16 | }, |
1100 | 16 | { |
1101 | 16 | &hf_source_address_name, |
1102 | 16 | { |
1103 | 16 | "Source Address Name", "doip.source_address_name", |
1104 | 16 | FT_STRING, BASE_NONE, |
1105 | 16 | NULL, 0x00, |
1106 | 16 | NULL, HFILL |
1107 | 16 | } |
1108 | 16 | }, |
1109 | 16 | { |
1110 | 16 | &hf_target_address, |
1111 | 16 | { |
1112 | 16 | "Target Address", "doip.target_address", |
1113 | 16 | FT_UINT16, BASE_HEX, |
1114 | 16 | NULL, 0x00, |
1115 | 16 | NULL, HFILL |
1116 | 16 | } |
1117 | 16 | }, |
1118 | 16 | { |
1119 | 16 | &hf_target_address_name, |
1120 | 16 | { |
1121 | 16 | "Target Address Name", "doip.target_address_name", |
1122 | 16 | FT_STRING, BASE_NONE, |
1123 | 16 | NULL, 0x00, |
1124 | 16 | NULL, HFILL |
1125 | 16 | } |
1126 | 16 | }, |
1127 | | /* Routing activation request */ |
1128 | 16 | { |
1129 | 16 | &hf_activation_type_v1, |
1130 | 16 | { |
1131 | 16 | "Activation type", "doip.activation_type_v1", |
1132 | 16 | FT_UINT16, BASE_HEX, |
1133 | 16 | NULL, 0x00, |
1134 | 16 | NULL, HFILL |
1135 | 16 | } |
1136 | 16 | }, |
1137 | 16 | { |
1138 | 16 | &hf_activation_type_v2, |
1139 | 16 | { |
1140 | 16 | "Activation type", "doip.activation_type", |
1141 | 16 | FT_UINT8, BASE_HEX, |
1142 | 16 | VALS(activation_types), 0x00, |
1143 | 16 | NULL, HFILL |
1144 | 16 | } |
1145 | 16 | }, |
1146 | | /* Routing activation response */ |
1147 | 16 | { |
1148 | 16 | &hf_tester_logical_address, |
1149 | 16 | { |
1150 | 16 | "Logical address of external tester", "doip.tester_logical_address", |
1151 | 16 | FT_UINT16, BASE_HEX, |
1152 | 16 | NULL, 0x00, |
1153 | 16 | NULL, HFILL |
1154 | 16 | } |
1155 | 16 | }, |
1156 | 16 | { |
1157 | 16 | &hf_tester_logical_address_name, |
1158 | 16 | { |
1159 | 16 | "Name of external tester", "doip.tester_logical_address_name", |
1160 | 16 | FT_STRING, BASE_NONE, |
1161 | 16 | NULL, 0x00, |
1162 | 16 | NULL, HFILL |
1163 | 16 | } |
1164 | 16 | }, |
1165 | 16 | { |
1166 | 16 | &hf_response_code, |
1167 | 16 | { |
1168 | 16 | "Routing activation response code", "doip.response_code", |
1169 | 16 | FT_UINT8, BASE_HEX, |
1170 | 16 | VALS(activation_codes), 0x00, |
1171 | 16 | NULL, HFILL |
1172 | 16 | } |
1173 | 16 | }, |
1174 | | /* Common */ |
1175 | 16 | { |
1176 | 16 | &hf_reserved_iso, |
1177 | 16 | { |
1178 | 16 | "Reserved by ISO", "doip.reserved_iso", |
1179 | 16 | FT_UINT32, BASE_HEX, |
1180 | 16 | NULL, 0x00, |
1181 | 16 | NULL, HFILL |
1182 | 16 | } |
1183 | 16 | }, |
1184 | 16 | { |
1185 | 16 | &hf_reserved_oem, |
1186 | 16 | { |
1187 | 16 | "Reserved by OEM", "doip.reserved_oem", |
1188 | 16 | FT_UINT32, BASE_HEX, |
1189 | 16 | NULL, 0x00, |
1190 | 16 | NULL, HFILL |
1191 | 16 | } |
1192 | 16 | }, |
1193 | | /* Diagnostic message */ |
1194 | 16 | { |
1195 | 16 | &hf_data, |
1196 | 16 | { |
1197 | 16 | "User data", "doip.data", |
1198 | 16 | FT_BYTES, BASE_NONE, |
1199 | 16 | NULL, 0x00, |
1200 | 16 | NULL, HFILL |
1201 | 16 | } |
1202 | 16 | }, |
1203 | | /* Diagnostic message ACK */ |
1204 | 16 | { |
1205 | 16 | &hf_ack_code, |
1206 | 16 | { |
1207 | 16 | "ACK code", "doip.diag_ack_code", |
1208 | 16 | FT_UINT8, BASE_HEX, |
1209 | 16 | VALS(diag_ack_codes), 0x00, |
1210 | 16 | NULL, HFILL |
1211 | 16 | } |
1212 | 16 | }, |
1213 | | /* Diagnostic message NACK */ |
1214 | 16 | { |
1215 | 16 | &hf_nack_code, |
1216 | 16 | { |
1217 | 16 | "NACK code", "doip.diag_nack_code", |
1218 | 16 | FT_UINT8, BASE_HEX, |
1219 | 16 | VALS(diag_nack_codes), 0x00, |
1220 | 16 | NULL, HFILL |
1221 | 16 | } |
1222 | 16 | }, |
1223 | | /* Common */ |
1224 | 16 | { |
1225 | 16 | &hf_previous, |
1226 | 16 | { |
1227 | 16 | "Previous message", "doip.previous", |
1228 | 16 | FT_BYTES, BASE_NONE, |
1229 | 16 | NULL, 0x00, |
1230 | 16 | NULL, HFILL |
1231 | 16 | } |
1232 | 16 | } |
1233 | 16 | }; |
1234 | | |
1235 | | /* Setup protocol subtree array */ |
1236 | 16 | static int *ett[] = { |
1237 | 16 | &ett_doip, |
1238 | 16 | &ett_header, |
1239 | 16 | &ett_address |
1240 | 16 | }; |
1241 | | |
1242 | | /* UAT definitions */ |
1243 | 16 | static uat_field_t doip_diag_addr_uat_fields[] = { |
1244 | 16 | UAT_FLD_HEX(doip_diag_addresses, id, "Diagnostic Address", "Diagnostic Address (hex uint16 without leading 0x)"), |
1245 | 16 | UAT_FLD_CSTRING(doip_diag_addresses, name, "Name", "Name of the ECU (string)"), |
1246 | 16 | UAT_END_FIELDS |
1247 | 16 | }; |
1248 | | |
1249 | 16 | static uat_field_t doip_payload_type_uat_fields[] = { |
1250 | 16 | UAT_FLD_HEX(doip_payload_types, id, "Payload Type", "Payload Type (hex uint16 without leading 0x)"), |
1251 | 16 | UAT_FLD_CSTRING(doip_payload_types, name, "Name", "Name of the Payload Type (string)"), |
1252 | 16 | UAT_END_FIELDS |
1253 | 16 | }; |
1254 | | |
1255 | 16 | proto_doip = proto_register_protocol ("DoIP (ISO13400) Protocol", "DoIP", "doip"); |
1256 | | |
1257 | 16 | proto_register_field_array(proto_doip, hf, array_length(hf)); |
1258 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
1259 | | |
1260 | 16 | doip_handle = register_dissector("doip", dissect_doip, proto_doip); |
1261 | 16 | doip_module = prefs_register_protocol(proto_doip, NULL); |
1262 | | |
1263 | | /* UATs */ |
1264 | 16 | doip_diag_addr_uat = uat_new("Diagnostic Addresses", |
1265 | 16 | sizeof(generic_one_id_string_t), /* record size */ |
1266 | 16 | DATAFILE_DOIP_DIAG_ADDRESSES, /* filename */ |
1267 | 16 | true, /* from profile */ |
1268 | 16 | (void**)&doip_diag_addresses, /* data_ptr */ |
1269 | 16 | &doip_diag_address_count, /* numitems_ptr */ |
1270 | 16 | UAT_AFFECTS_DISSECTION, /* but not fields */ |
1271 | 16 | NULL, /* help */ |
1272 | 16 | copy_generic_one_id_string_cb, /* copy callback */ |
1273 | 16 | update_generic_one_identifier_16bit, /* update callback */ |
1274 | 16 | free_generic_one_id_string_cb, /* free callback */ |
1275 | 16 | post_update_doip_diag_addresses, /* post update callback */ |
1276 | 16 | reset_doip_diag_addresses_cb, /* reset callback */ |
1277 | 16 | doip_diag_addr_uat_fields /* UAT field definitions */ |
1278 | 16 | ); |
1279 | | |
1280 | 16 | prefs_register_uat_preference(doip_module, "_udf_doip_diag_addresses", "Diagnostics Addresses", |
1281 | 16 | "A table to define names of Diagnostics Addresses.", doip_diag_addr_uat); |
1282 | | |
1283 | 16 | doip_payload_type_uat = uat_new("Payload Types", |
1284 | 16 | sizeof(generic_one_id_string_t), /* record size */ |
1285 | 16 | DATAFILE_DOIP_PAYLOAD_TYPES, /* filename */ |
1286 | 16 | true, /* from profile */ |
1287 | 16 | (void**)&doip_payload_types, /* data_ptr */ |
1288 | 16 | &doip_payload_type_count, /* numitems_ptr */ |
1289 | 16 | UAT_AFFECTS_DISSECTION, /* but not fields */ |
1290 | 16 | NULL, /* help */ |
1291 | 16 | copy_generic_one_id_string_cb, /* copy callback */ |
1292 | 16 | update_generic_one_identifier_16bit, /* update callback */ |
1293 | 16 | free_generic_one_id_string_cb, /* free callback */ |
1294 | 16 | post_update_doip_payload_types, /* post update callback */ |
1295 | 16 | reset_doip_payload_type_cb, /* reset callback */ |
1296 | 16 | doip_payload_type_uat_fields /* UAT field definitions */ |
1297 | 16 | ); |
1298 | | |
1299 | 16 | prefs_register_uat_preference(doip_module, "_udf_doip_payload_types", "Payload Types", |
1300 | 16 | "A table to define names of Payload Types.", doip_payload_type_uat); |
1301 | | |
1302 | 16 | prefs_register_bool_preference(doip_module, "hide_address_name_entries", |
1303 | 16 | "Hide Address Name Entries", |
1304 | 16 | "Should the dissector hide the names for addresses?", |
1305 | 16 | &doip_hide_address_names); |
1306 | | |
1307 | 16 | static ei_register_info ei[] = { |
1308 | 16 | { &ei_doip_illegal_length_field, { "doip.illegal_length_field", |
1309 | 16 | PI_MALFORMED, PI_ERROR, "DoIP illegal length field", EXPFILL } }, |
1310 | 16 | }; |
1311 | | |
1312 | 16 | expert_module_doip = expert_register_protocol(proto_doip); |
1313 | 16 | expert_register_field_array(expert_module_doip, ei, array_length(ei)); |
1314 | 16 | } |
1315 | | |
1316 | | void |
1317 | | proto_reg_handoff_doip(void) |
1318 | 16 | { |
1319 | 16 | dissector_add_uint("udp.port", DOIP_PORT, doip_handle); |
1320 | 16 | dissector_add_uint("tcp.port", DOIP_PORT, doip_handle); |
1321 | | |
1322 | 16 | ssl_dissector_add(DOIP_TLS_PORT, doip_handle); |
1323 | | |
1324 | 16 | uds_handle = find_dissector("uds_over_doip"); |
1325 | 16 | } |
1326 | | |
1327 | | /* |
1328 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1329 | | * |
1330 | | * Local variables: |
1331 | | * c-basic-offset: 4 |
1332 | | * tab-width: 8 |
1333 | | * indent-tabs-mode: nil |
1334 | | * End: |
1335 | | * |
1336 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
1337 | | * :indentSize=4:tabSize=8:noTabs=true: |
1338 | | */ |