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