/src/wireshark/epan/dissectors/packet-dcerpc-ndr.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* packet-dcerpc-ndr.c |
2 | | * Routines for DCERPC NDR dissection |
3 | | * Copyright 2001, Todd Sabin <tas@webspan.net> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | #include "config.h" |
13 | | |
14 | | #include <epan/packet.h> |
15 | | |
16 | | #include <wsutil/ws_roundup.h> |
17 | | #include <wsutil/ws_padding_to.h> |
18 | | |
19 | | #include "packet-dcerpc.h" |
20 | | |
21 | | /* |
22 | | * The NDR routines are for use by dcerpc subdissetors. They're |
23 | | * primarily for making sure things are aligned properly according |
24 | | * to the rules of NDR. |
25 | | */ |
26 | | |
27 | | int |
28 | | dissect_ndr_uint8(tvbuff_t *tvb, int offset, packet_info *pinfo, |
29 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
30 | | int hfindex, uint8_t *pdata) |
31 | 0 | { |
32 | | /* Some callers expect us to initialize pdata, even in error conditions, so |
33 | | * do it right away in case we forget later */ |
34 | 0 | if (pdata) |
35 | 0 | *pdata = 0; |
36 | |
|
37 | 0 | if (di->conformant_run) { |
38 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
39 | 0 | return offset; |
40 | 0 | } |
41 | | |
42 | | /* no alignment needed */ |
43 | 0 | return dissect_dcerpc_uint8(tvb, offset, pinfo, |
44 | 0 | tree, drep, hfindex, pdata); |
45 | 0 | } |
46 | | |
47 | | int |
48 | | PIDL_dissect_uint8_val(tvbuff_t *tvb, int offset, packet_info *pinfo, |
49 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
50 | | int hfindex, uint32_t param, uint8_t *pval) |
51 | 0 | { |
52 | 0 | uint8_t val; |
53 | |
|
54 | 0 | if (di->conformant_run) { |
55 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
56 | 0 | return offset; |
57 | 0 | } |
58 | | |
59 | | /* no alignment needed */ |
60 | 0 | offset = dissect_dcerpc_uint8(tvb, offset, pinfo, |
61 | 0 | tree, drep, hfindex, &val); |
62 | |
|
63 | 0 | if (param&PIDL_SET_COL_INFO) { |
64 | 0 | header_field_info *hf_info; |
65 | 0 | char *valstr; |
66 | |
|
67 | 0 | hf_info = proto_registrar_get_nth(hfindex); |
68 | |
|
69 | 0 | valstr = (char *)wmem_alloc(pinfo->pool, 64); |
70 | 0 | valstr[0]=0; |
71 | |
|
72 | 0 | switch (hf_info->display) { |
73 | 0 | case BASE_DEC: |
74 | 0 | if (hf_info->strings) { |
75 | 0 | snprintf(valstr, 64, "%s(%d)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val); |
76 | 0 | } else { |
77 | 0 | snprintf(valstr, 64, "%d", val); |
78 | 0 | } |
79 | 0 | break; |
80 | 0 | case BASE_HEX: |
81 | 0 | if (hf_info->strings) { |
82 | 0 | snprintf(valstr, 64, "%s(0x%02x)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val); |
83 | 0 | } else { |
84 | 0 | snprintf(valstr, 64, "0x%02x", val); |
85 | 0 | } |
86 | 0 | break; |
87 | 0 | default: |
88 | 0 | REPORT_DISSECTOR_BUG("Invalid hf->display value"); |
89 | 0 | } |
90 | | |
91 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO," %s:%s", hf_info->name, valstr); |
92 | 0 | } |
93 | 0 | if (pval) { |
94 | 0 | *pval = val; |
95 | 0 | } |
96 | |
|
97 | 0 | return offset; |
98 | 0 | } |
99 | | |
100 | | int |
101 | | PIDL_dissect_uint8(tvbuff_t *tvb, int offset, packet_info *pinfo, |
102 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
103 | | int hfindex, uint32_t param) |
104 | 0 | { |
105 | 0 | return PIDL_dissect_uint8_val(tvb, offset, pinfo, tree, di, drep, hfindex, param, NULL); |
106 | 0 | } |
107 | | |
108 | | |
109 | | int |
110 | | dissect_ndr_uint16(tvbuff_t *tvb, int offset, packet_info *pinfo, |
111 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
112 | | int hfindex, uint16_t *pdata) |
113 | 0 | { |
114 | | /* Some callers expect us to initialize pdata, even in error conditions, so |
115 | | * do it right away in case we forget later */ |
116 | 0 | if (pdata) |
117 | 0 | *pdata = 0; |
118 | |
|
119 | 0 | if (di->conformant_run) { |
120 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
121 | 0 | return offset; |
122 | 0 | } |
123 | | |
124 | | |
125 | 0 | if (!di->no_align) { |
126 | 0 | offset = WS_ROUNDUP_2(offset); |
127 | 0 | } |
128 | 0 | return dissect_dcerpc_uint16(tvb, offset, pinfo, |
129 | 0 | tree, drep, hfindex, pdata); |
130 | 0 | } |
131 | | |
132 | | int |
133 | | PIDL_dissect_uint16_val(tvbuff_t *tvb, int offset, packet_info *pinfo, |
134 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
135 | | int hfindex, uint32_t param, uint16_t *pval) |
136 | 0 | { |
137 | 0 | uint16_t val; |
138 | |
|
139 | 0 | if (di->conformant_run) { |
140 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
141 | 0 | return offset; |
142 | 0 | } |
143 | | |
144 | | |
145 | 0 | if (!di->no_align) { |
146 | 0 | offset = WS_ROUNDUP_2(offset); |
147 | 0 | } |
148 | 0 | offset = dissect_dcerpc_uint16(tvb, offset, pinfo, |
149 | 0 | tree, drep, hfindex, &val); |
150 | |
|
151 | 0 | if (param&PIDL_SET_COL_INFO) { |
152 | 0 | header_field_info *hf_info; |
153 | 0 | char *valstr; |
154 | |
|
155 | 0 | hf_info = proto_registrar_get_nth(hfindex); |
156 | |
|
157 | 0 | valstr = (char *)wmem_alloc(pinfo->pool, 64); |
158 | 0 | valstr[0]=0; |
159 | |
|
160 | 0 | switch (hf_info->display) { |
161 | 0 | case BASE_DEC: |
162 | 0 | if (hf_info->strings) { |
163 | 0 | snprintf(valstr, 64, "%s(%d)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val); |
164 | 0 | } else { |
165 | 0 | snprintf(valstr, 64, "%d", val); |
166 | 0 | } |
167 | 0 | break; |
168 | 0 | case BASE_HEX: |
169 | 0 | if (hf_info->strings) { |
170 | 0 | snprintf(valstr, 64, "%s(0x%04x)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val); |
171 | 0 | } else { |
172 | 0 | snprintf(valstr, 64, "0x%04x", val); |
173 | 0 | } |
174 | 0 | break; |
175 | 0 | default: |
176 | 0 | REPORT_DISSECTOR_BUG("Invalid hf->display value"); |
177 | 0 | } |
178 | | |
179 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO," %s:%s", hf_info->name, valstr); |
180 | 0 | } |
181 | | |
182 | 0 | if (pval) { |
183 | 0 | *pval = val; |
184 | 0 | } |
185 | 0 | return offset; |
186 | 0 | } |
187 | | |
188 | | int |
189 | | PIDL_dissect_uint16(tvbuff_t *tvb, int offset, packet_info *pinfo, |
190 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
191 | | int hfindex, uint32_t param) |
192 | 0 | { |
193 | 0 | return PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hfindex, param, NULL); |
194 | 0 | } |
195 | | |
196 | | int |
197 | | dissect_ndr_uint32(tvbuff_t *tvb, int offset, packet_info *pinfo, |
198 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
199 | | int hfindex, uint32_t *pdata) |
200 | 0 | { |
201 | | /* Some callers expect us to initialize pdata, even in error conditions, so |
202 | | * do it right away in case we forget later */ |
203 | 0 | if (pdata) |
204 | 0 | *pdata = 0; |
205 | |
|
206 | 0 | if ((di != NULL) && (di->conformant_run)) { |
207 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
208 | 0 | return offset; |
209 | 0 | } |
210 | | |
211 | | |
212 | 0 | if ((di != NULL) && (!di->no_align)) { |
213 | 0 | offset = WS_ROUNDUP_4(offset); |
214 | 0 | } |
215 | 0 | return dissect_dcerpc_uint32(tvb, offset, pinfo, |
216 | 0 | tree, drep, hfindex, pdata); |
217 | 0 | } |
218 | | |
219 | | /* This is used to dissect the new datatypes, such as pointers and conformance |
220 | | data, which is 4 bytes in size in NDR but 8 bytes in NDR64. |
221 | | */ |
222 | | int |
223 | | dissect_ndr_uint3264(tvbuff_t *tvb, int offset, packet_info *pinfo, |
224 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
225 | | int hfindex, uint3264_t *pdata) |
226 | 0 | { |
227 | 0 | if (di->call_data->flags & DCERPC_IS_NDR64) { |
228 | 0 | return dissect_ndr_uint64(tvb, offset, pinfo, tree, di, drep, hfindex, pdata); |
229 | 0 | } else { |
230 | 0 | uint32_t val = 0; |
231 | 0 | offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hfindex, &val); |
232 | 0 | if (pdata) { |
233 | 0 | *pdata = val; |
234 | 0 | } |
235 | 0 | return offset; |
236 | 0 | } |
237 | 0 | } |
238 | | |
239 | | /* This is used to dissect the new datatypes, such as enums |
240 | | that are 2 bytes in size in NDR but 4 bytes in NDR64. |
241 | | */ |
242 | | int |
243 | | dissect_ndr_uint1632(tvbuff_t *tvb, int offset, packet_info *pinfo, |
244 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
245 | | int hfindex, uint1632_t *pdata) |
246 | 0 | { |
247 | 0 | if (di->call_data->flags & DCERPC_IS_NDR64) { |
248 | 0 | return dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hfindex, pdata); |
249 | 0 | } else { |
250 | 0 | uint16_t val = 0; |
251 | 0 | offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep, hfindex, &val); |
252 | 0 | if (pdata) { |
253 | 0 | *pdata = val; |
254 | 0 | } |
255 | 0 | return offset; |
256 | 0 | } |
257 | 0 | } |
258 | | |
259 | | int |
260 | | PIDL_dissect_uint32_val(tvbuff_t *tvb, int offset, packet_info *pinfo, |
261 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
262 | | int hfindex, uint32_t param, uint32_t *rval) |
263 | 0 | { |
264 | 0 | uint32_t val; |
265 | |
|
266 | 0 | if (di->conformant_run) { |
267 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
268 | 0 | return offset; |
269 | 0 | } |
270 | | |
271 | | |
272 | 0 | if (!di->no_align) { |
273 | 0 | offset = WS_ROUNDUP_4(offset); |
274 | 0 | } |
275 | 0 | offset = dissect_dcerpc_uint32(tvb, offset, pinfo, |
276 | 0 | tree, drep, hfindex, &val); |
277 | |
|
278 | 0 | if (param&PIDL_SET_COL_INFO) { |
279 | 0 | header_field_info *hf_info; |
280 | 0 | char *valstr; |
281 | |
|
282 | 0 | hf_info = proto_registrar_get_nth(hfindex); |
283 | |
|
284 | 0 | valstr = (char *)wmem_alloc(pinfo->pool, 64); |
285 | 0 | valstr[0]=0; |
286 | |
|
287 | 0 | switch (hf_info->display) { |
288 | 0 | case BASE_DEC: |
289 | 0 | if (hf_info->strings) { |
290 | 0 | snprintf(valstr, 64, "%s(%d)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val); |
291 | 0 | } else { |
292 | 0 | snprintf(valstr, 64, "%d", val); |
293 | 0 | } |
294 | 0 | break; |
295 | 0 | case BASE_HEX: |
296 | 0 | if (hf_info->strings) { |
297 | 0 | snprintf(valstr, 64, "%s(0x%08x)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val); |
298 | 0 | } else { |
299 | 0 | snprintf(valstr, 64, "0x%08x", val); |
300 | 0 | } |
301 | 0 | break; |
302 | 0 | default: |
303 | 0 | REPORT_DISSECTOR_BUG("Invalid hf->display value"); |
304 | 0 | } |
305 | | |
306 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO," %s:%s", hf_info->name, valstr); |
307 | 0 | } |
308 | 0 | if (rval != NULL) { |
309 | 0 | *rval = val; |
310 | 0 | } |
311 | 0 | return offset; |
312 | 0 | } |
313 | | |
314 | | int |
315 | | PIDL_dissect_uint32(tvbuff_t *tvb, int offset, packet_info *pinfo, |
316 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
317 | | int hfindex, uint32_t param) |
318 | 0 | { |
319 | 0 | return PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hfindex, param, NULL); |
320 | 0 | } |
321 | | |
322 | | /* Double uint32 |
323 | | This function dissects the 64bit datatype that is common for |
324 | | ms interfaces and which is 32bit aligned. |
325 | | It is really just 2 uint32's |
326 | | */ |
327 | | int |
328 | | dissect_ndr_duint32(tvbuff_t *tvb, int offset, packet_info *pinfo, |
329 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
330 | | int hfindex, uint64_t *pdata) |
331 | 0 | { |
332 | | /* Some callers expect us to initialize pdata, even in error conditions, so |
333 | | * do it right away in case we forget later */ |
334 | 0 | if (pdata) |
335 | 0 | *pdata = 0; |
336 | |
|
337 | 0 | if (di->conformant_run) { |
338 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
339 | 0 | return offset; |
340 | 0 | } |
341 | | |
342 | 0 | if (!di->no_align) { |
343 | 0 | offset = WS_ROUNDUP_4(offset); |
344 | 0 | } |
345 | 0 | return dissect_dcerpc_uint64(tvb, offset, pinfo, |
346 | 0 | tree, di, drep, hfindex, pdata); |
347 | 0 | } |
348 | | |
349 | | /* uint64 : hyper |
350 | | a 64 bit integer aligned to proper 8 byte boundaries |
351 | | */ |
352 | | int |
353 | | dissect_ndr_uint64(tvbuff_t *tvb, int offset, packet_info *pinfo, |
354 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
355 | | int hfindex, uint64_t *pdata) |
356 | 0 | { |
357 | | /* Some callers expect us to initialize pdata, even in error conditions, so |
358 | | * do it right away in case we forget later */ |
359 | 0 | if (pdata) |
360 | 0 | *pdata = 0; |
361 | |
|
362 | 0 | if (di->conformant_run) { |
363 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
364 | 0 | return offset; |
365 | 0 | } |
366 | | |
367 | 0 | if (!di->no_align) { |
368 | 0 | unsigned padding = WS_PADDING_TO_8(offset); |
369 | 0 | if (padding != 0) { |
370 | 0 | proto_tree_add_item(tree, hf_dcerpc_ndr_padding, tvb, offset, padding, ENC_NA); |
371 | 0 | offset += padding; |
372 | 0 | } |
373 | 0 | } |
374 | 0 | return dissect_dcerpc_uint64(tvb, offset, pinfo, |
375 | 0 | tree, di, drep, hfindex, pdata); |
376 | 0 | } |
377 | | |
378 | | int |
379 | | PIDL_dissect_uint64_val(tvbuff_t *tvb, int offset, packet_info *pinfo, |
380 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
381 | | int hfindex, uint32_t param, uint64_t *pval) |
382 | 0 | { |
383 | 0 | uint64_t val; |
384 | |
|
385 | 0 | if (di->conformant_run) { |
386 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
387 | 0 | return offset; |
388 | 0 | } |
389 | | |
390 | 0 | if (!di->no_align) { |
391 | 0 | offset = WS_ROUNDUP_8(offset); |
392 | 0 | } |
393 | 0 | offset = dissect_dcerpc_uint64(tvb, offset, pinfo, |
394 | 0 | tree, di, drep, hfindex, &val); |
395 | |
|
396 | 0 | if (param&PIDL_SET_COL_INFO) { |
397 | 0 | header_field_info *hf_info; |
398 | 0 | char *valstr; |
399 | |
|
400 | 0 | hf_info = proto_registrar_get_nth(hfindex); |
401 | |
|
402 | 0 | valstr = (char *)wmem_alloc(pinfo->pool, 64); |
403 | 0 | valstr[0]=0; |
404 | |
|
405 | 0 | switch (hf_info->display) { |
406 | 0 | case BASE_DEC: |
407 | 0 | if (hf_info->strings) { |
408 | 0 | snprintf(valstr, 64, "%s(%" PRIu64 ")",val_to_str( (uint32_t) val, (const value_string *)hf_info->strings, "Unknown:%u"), val); |
409 | 0 | } else { |
410 | 0 | snprintf(valstr, 64, "%" PRIu64, val); |
411 | 0 | } |
412 | 0 | break; |
413 | 0 | case BASE_HEX: |
414 | 0 | if (hf_info->strings) { |
415 | 0 | snprintf(valstr, 64, "%s(0x%" PRIx64 ")",val_to_str( (uint32_t) val, (const value_string *)hf_info->strings, "Unknown:%u"), val); |
416 | 0 | } else { |
417 | 0 | snprintf(valstr, 64, "0x%" PRIx64, val); |
418 | 0 | } |
419 | 0 | break; |
420 | 0 | default: |
421 | 0 | REPORT_DISSECTOR_BUG("Invalid hf->display value"); |
422 | 0 | } |
423 | | |
424 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO," %s:%s", hf_info->name, valstr); |
425 | 0 | } |
426 | | |
427 | 0 | if (pval) { |
428 | 0 | *pval = val; |
429 | 0 | } |
430 | 0 | return offset; |
431 | 0 | } |
432 | | |
433 | | int |
434 | | PIDL_dissect_uint64(tvbuff_t *tvb, int offset, packet_info *pinfo, |
435 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
436 | | int hfindex, uint32_t param) |
437 | 0 | { |
438 | 0 | return PIDL_dissect_uint64_val(tvb, offset, pinfo, tree, di, drep, hfindex, param, NULL); |
439 | 0 | } |
440 | | |
441 | | int |
442 | | dissect_ndr_float(tvbuff_t *tvb, int offset, packet_info *pinfo, |
443 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
444 | | int hfindex, float *pdata) |
445 | 0 | { |
446 | | /* Some callers expect us to initialize pdata, even in error conditions, so |
447 | | * do it right away in case we forget later */ |
448 | 0 | if (pdata) |
449 | 0 | *pdata = 0; |
450 | | |
451 | |
|
452 | 0 | if (di->conformant_run) { |
453 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
454 | 0 | return offset; |
455 | 0 | } |
456 | | |
457 | 0 | if (!di->no_align) { |
458 | 0 | offset = WS_ROUNDUP_4(offset); |
459 | 0 | } |
460 | 0 | return dissect_dcerpc_float(tvb, offset, pinfo, |
461 | 0 | tree, drep, hfindex, pdata); |
462 | 0 | } |
463 | | |
464 | | |
465 | | int |
466 | | dissect_ndr_double(tvbuff_t *tvb, int offset, packet_info *pinfo, |
467 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
468 | | int hfindex, double *pdata) |
469 | 0 | { |
470 | | /* Some callers expect us to initialize pdata, even in error conditions, so |
471 | | * do it right away in case we forget later */ |
472 | 0 | if (pdata) |
473 | 0 | *pdata = 0; |
474 | |
|
475 | 0 | if (di->conformant_run) { |
476 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
477 | 0 | return offset; |
478 | 0 | } |
479 | | |
480 | 0 | if (!di->no_align) { |
481 | 0 | offset = WS_ROUNDUP_8(offset); |
482 | 0 | } |
483 | 0 | return dissect_dcerpc_double(tvb, offset, pinfo, |
484 | 0 | tree, drep, hfindex, pdata); |
485 | 0 | } |
486 | | |
487 | | /* handles unix 32 bit time_t */ |
488 | | int |
489 | | dissect_ndr_time_t(tvbuff_t *tvb, int offset, packet_info *pinfo, |
490 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
491 | | int hfindex, uint32_t *pdata) |
492 | 0 | { |
493 | | /* Some callers expect us to initialize pdata, even in error conditions, so |
494 | | * do it right away in case we forget later */ |
495 | 0 | if (pdata) |
496 | 0 | *pdata = 0; |
497 | |
|
498 | 0 | if (di->conformant_run) { |
499 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
500 | 0 | return offset; |
501 | 0 | } |
502 | | |
503 | | |
504 | 0 | if (!di->no_align) { |
505 | 0 | offset = WS_ROUNDUP_4(offset); |
506 | 0 | } |
507 | 0 | return dissect_dcerpc_time_t(tvb, offset, pinfo, |
508 | 0 | tree, drep, hfindex, pdata); |
509 | 0 | } |
510 | | |
511 | | int |
512 | | dissect_ndr_uuid_t(tvbuff_t *tvb, int offset, packet_info *pinfo, |
513 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
514 | | int hfindex, e_guid_t *pdata) |
515 | 0 | { |
516 | | /* Some callers expect us to initialize pdata, even in error conditions, so |
517 | | * do it right away in case we forget later */ |
518 | 0 | if (pdata) |
519 | 0 | memset(pdata, 0, sizeof(*pdata)); |
520 | |
|
521 | 0 | if (di->conformant_run) { |
522 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
523 | 0 | return offset; |
524 | 0 | } |
525 | | |
526 | | /* uuid's are aligned to 4 bytes, due to initial uint32 in struct */ |
527 | 0 | if (!di->no_align) { |
528 | 0 | offset = WS_ROUNDUP_4(offset); |
529 | 0 | } |
530 | 0 | return dissect_dcerpc_uuid_t(tvb, offset, pinfo, |
531 | 0 | tree, drep, hfindex, pdata); |
532 | 0 | } |
533 | | |
534 | | /* |
535 | | * XXX - at least according to the DCE RPC 1.1 "nbase.idl", an |
536 | | * "ndr_context_handle" is an unsigned32 "context_handle_attributes" |
537 | | * and a uuid_t "context_handle_uuid". The attributes do not appear to |
538 | | * be used, and always appear to be set to 0, in the DCE RPC 1.1 code. |
539 | | * |
540 | | * Should we display an "ndr_context_handle" with a tree holding the |
541 | | * attributes and the uuid_t? |
542 | | */ |
543 | | int |
544 | | dissect_ndr_ctx_hnd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, |
545 | | proto_tree *tree, dcerpc_info *di, uint8_t *drep, |
546 | | int hfindex, e_ctx_hnd *pdata) |
547 | 0 | { |
548 | 0 | static e_ctx_hnd ctx_hnd; |
549 | |
|
550 | 0 | if (di->conformant_run) { |
551 | | /* just a run to handle conformant arrays, no scalars to dissect */ |
552 | 0 | return offset; |
553 | 0 | } |
554 | | |
555 | 0 | if (!di->no_align) { |
556 | 0 | offset = WS_ROUNDUP_4(offset); |
557 | 0 | } |
558 | 0 | ctx_hnd.attributes = dcerpc_tvb_get_ntohl(tvb, offset, drep); |
559 | 0 | dcerpc_tvb_get_uuid(tvb, offset+4, drep, &ctx_hnd.uuid); |
560 | 0 | if (tree) { |
561 | | /* Bytes is bytes - don't worry about the data representation */ |
562 | 0 | proto_tree_add_item(tree, hfindex, tvb, offset, 20, ENC_NA); |
563 | 0 | } |
564 | 0 | if (pdata) { |
565 | 0 | *pdata = ctx_hnd; |
566 | 0 | } |
567 | 0 | return offset + 20; |
568 | 0 | } |
569 | | |
570 | | /* |
571 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
572 | | * |
573 | | * Local variables: |
574 | | * c-basic-offset: 4 |
575 | | * tab-width: 8 |
576 | | * indent-tabs-mode: nil |
577 | | * End: |
578 | | * |
579 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
580 | | * :indentSize=4:tabSize=8:noTabs=true: |
581 | | */ |