### Bug Summary

File: | builds/wireshark/wireshark/epan/dissectors/dcerpc/idl2wrs.c
Warning: | line 968, column 6 File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name idl2wrs.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2026-02-22-100341-3623-1 -x c /builds/wireshark/wireshark/epan/dissectors/dcerpc/idl2wrs.c

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

1 | /* idl2wrs.c
2 | * DCE RPC IDL to Wireshark dissector compiler
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 | /*
12 | TODO
13 | check that every cnf defined type,hffield,rename,... has been referenced
14 | at least once and if not, abort with an error
15 |
16 | need to distinguish between NTTIME (absolute time) and relative time
17 |
18 | prune_xxx should only act inside of '[' ']'
19 |
20 | add support for bool8,16,32,64 with tfs strings
21 |
22 | add the remaining array type (uvarray)
23 |
24 | add code to verify that union tag length is correct
25 | */
26 | /* List of built in types :
27 | WERROR A 32 bit integer holding a DCE/NT status code.
28 |
29 | uint8 A 8 bit integer
30 | int8
31 |
32 | uint16 A 16 bit integer
33 | int16
34 |
35 | uint32 A 32 bit integer
36 | int32
37 |
38 | uint64 A 64 bit integer
39 |
40 | udlong A 64 bit integer aligned on 4 byte boundary
41 | dlong
42 |
43 | time_t A 32 bit integer holding a unix style time_t
44 |
45 | NTTIME_hyper A 64 bit integer representing a NTTIME
46 | NTTIME_1sec
47 |
48 | unistr A conformant and varying unicode string
49 |
50 | ascstr A conformant and varying ascii string
51 |
52 |
53 | SID A SID structure.
54 |
55 | uuid_t A 16 byte FT_GUID blob.
56 | GUID
57 |
58 |
59 | policy_handle
60 | bool8
61 | uuid_t
62 | policy_handle
63 | NTTIME
64 | */
65 |
66 | /* All field dissectors that call a normal type
67 | (i.e. not a pointer, not an array)
68 | has a local variable unsigned param declared which is passed on to the
69 | type dissector.
70 | The default value is 0 but the PARAM_VALUE conformance tag can be used to
71 | change it.
72 | This is only meaningful if the called type dissector actually does anything
73 | with this parameter.
74 | */
75 |
76 | #define _GNU_SOURCE
77 |
78 | #include <glib.h>
79 | #include <glib/gstdio.h>
80 | #include <string.h>
81 | #include <stdlib.h>
82 | #include <stdarg.h>
83 | #include <wsutil/strtoi.h>
84 |
85 | #undef IDL2WRS_DEBUG
86 |
87 | #define DISSECTORNAME_MAXLEN256 256
88 |
89 | #define BASE_BUFFER_SIZE256 256
90 |
91 | static FILE *tfh, *eth_code, *eth_hdr, *eth_hf, *eth_hfarr, *eth_ett, *eth_ettarr, *eth_ft, *eth_handoff;
92 | static char *uuid=NULL((void*)0);
93 | static char *version=NULL((void*)0);
94 | static const char *pointer_default=NULL((void*)0);
95 | static char *ifname=NULL((void*)0);
96 | static char hf_status[BASE_BUFFER_SIZE256];
97 | static int lineno,linepos;
98 | static char line[4 * BASE_BUFFER_SIZE256];
99 |
100 | static void FPRINTF(FILE *fh, const char *format, ...)
101 | {
102 | va_list args;
103 |
104 | #ifdef IDL2WRS_DEBUG
105 | va_start(args, format)__builtin_va_start(args, format);
106 | vfprintf (stderrstderr, format, args);
107 | va_end(args)__builtin_va_end(args);
108 | #endif
109 | if (fh) {
110 | va_start(args, format)__builtin_va_start(args, format);
111 | vfprintf (fh, format, args);
112 | va_end(args)__builtin_va_end(args);
113 | }
114 | }
115 |
116 | typedef struct _pointer_item_t {
117 | struct _pointer_item_t *next;
118 | const char *type;
119 | } pointer_item_t;
120 |
121 | #define BI_CASE0x00000001 0x00000001
122 | #define BI_CASE_DEFAULT0x00000002 0x00000002
123 | #define BI_IN0x00000004 0x00000004
124 | #define BI_OUT0x00000008 0x00000008
125 | #define BI_SIZE_IS0x00000010 0x00000010
126 | #define BI_LENGTH_IS0x00000020 0x00000020
127 | #define BI_POINTER0x00000040 0x00000040
128 | #define BI_BITMAP80x00000100 0x00000100
129 | #define BI_BITMAP320x00000200 0x00000200
130 | #define BI_SWITCH_TYPE0x00000400 0x00000400
131 | typedef struct _bracket_item_t {
132 | unsigned int flags;
133 | const char *case_name;
134 | pointer_item_t *pointer_list;
135 | int union_tag_size;
136 | } bracket_item_t;
137 |
138 | typedef struct _no_emit_item_t {
139 | struct _no_emit_item_t *next;
140 | char *name;
141 | } no_emit_item_t;
142 | static no_emit_item_t *no_emit_list=NULL((void*)0);
143 |
144 | typedef struct _hf_rename_item_t {
145 | struct _hf_rename_item_t *next;
146 | int refcount; /* number of times this rename has been referenced */
147 | char *old_name;
148 | char *new_name;
149 | } hf_rename_item_t;
150 | static hf_rename_item_t *hf_rename_list=NULL((void*)0);
151 |
152 | typedef struct _enum_list_t {
153 | struct _enum_list_t *next;
154 | char *name;
155 | int val;
156 | } enum_list_t;
157 |
158 | typedef struct _token_item_t {
159 | struct _token_item_t *next;
160 | char *str;
161 | } token_item_t;
162 | static token_item_t *token_list=NULL((void*)0);
163 | static token_item_t *last_token_item=NULL((void*)0);
164 |
165 | typedef struct _type_item_t {
166 | struct _type_item_t *next;
167 | char *name;
168 | char *dissector;
169 | char *ft_type;
170 | char *base_type;
171 | char *mask;
172 | char *vals;
173 | int alignment;
174 | } type_item_t;
175 | static type_item_t *type_list=NULL((void*)0);
176 |
177 | typedef struct _union_tag_size_item_t {
178 | struct _union_tag_size_item_t *next;
179 | char *name;
180 | int size;
181 | } union_tag_size_item_t;
182 | static union_tag_size_item_t *union_tag_size_list=NULL((void*)0);
183 |
184 | typedef struct _hf_field_item_t {
185 | struct _hf_field_item_t *next;
186 | char *name;
187 | char *ft_type;
188 | } hf_field_item_t;
189 | static hf_field_item_t *hf_field_list=NULL((void*)0);
190 |
191 | typedef struct _dissector_param_value_t {
192 | struct _dissector_param_value_t *next;
193 | char *name;
194 | char *value;
195 | } dissector_param_value_t;
196 | static dissector_param_value_t *dissector_param_list=NULL((void*)0);
197 |
198 | static type_item_t *find_type(char *name);
199 | static int Exit(int code);
200 |
201 | static void
202 | register_dissector_param_value(const char *name, const char *value)
203 | {
204 | dissector_param_value_t *dpv;
205 | dpv=g_new0(dissector_param_value_t, 1)((dissector_param_value_t *) g_malloc0_n ((1), sizeof (dissector_param_value_t )));
206 | if (!dpv) {
207 | FPRINTF(stderrstderr, "Can't allocate memory. Exit.\n");
208 | exit(10);
209 | }
210 | dpv->next=dissector_param_list;
211 | dissector_param_list=dpv;
212 | dpv->name=g_strdup(name)g_strdup_inline (name);
213 | dpv->value=g_strdup(value)g_strdup_inline (value);
214 | }
215 |
216 | static const char *
217 | find_dissector_param_value(char *name)
218 | {
219 | dissector_param_value_t *dpv;
220 | for(dpv=dissector_param_list;dpv;dpv=dpv->next){
221 | if(!g_strcmp0(name,dpv->name)){
222 | return dpv->value;
223 | }
224 | }
225 | return "0";
226 | }
227 |
228 | static pointer_item_t *
229 | prepend_pointer_list(pointer_item_t *ptrs, int num_pointers)
230 | {
231 | pointer_item_t *pi;
232 |
233 | pi=ptrs;
234 | while(pi){
235 | if(num_pointers)num_pointers--;
236 | pi=pi->next;
237 | }
238 | pi=ptrs;
239 | while(num_pointers--){
240 | pi=g_new0(pointer_item_t, 1)((pointer_item_t *) g_malloc0_n ((1), sizeof (pointer_item_t) ));
241 | if (!pi) {
242 | FPRINTF(stderrstderr, "Can't allocate memory. Exit.\n");
243 | exit(10);
244 | }
245 | pi->next=ptrs;
246 | pi->type=pointer_default;
247 | ptrs=pi;
248 | }
249 | ptrs=pi;
250 |
251 | return ptrs;
252 | }
253 |
254 | static const char *
255 | ptr_to_define(const char *pointer_type)
256 | {
257 | if(!g_strcmp0(pointer_type, "unique")){
258 | return "NDR_POINTER_UNIQUE";
259 | } else if(!g_strcmp0(pointer_type, "ref")){
260 | return "NDR_POINTER_REF";
261 | } else if(!g_strcmp0(pointer_type, "ptr")){
262 | return "NDR_POINTER_PTR";
263 | }
264 |
265 | FPRINTF(stderrstderr, "prt_to_define, weirdo pointer :%s\n", pointer_type);
266 | exit(10);
267 | }
268 |
269 | static int
270 | get_union_tag_size(char *name)
271 | {
272 | union_tag_size_item_t *utsi;
273 | for(utsi=union_tag_size_list;utsi;utsi=utsi->next){
274 | if(!g_strcmp0(name, utsi->name)){
275 | return utsi->size;
276 | }
277 | }
278 | FPRINTF(stderrstderr, "ERROR: size of tag for union:%s is not known\n", name);
279 | FPRINTF(stderrstderr, " use the UNION_TAG_SIZE directive to specify it in the conformance file\n");
280 | exit(10);
281 | }
282 |
283 |
284 | /* this function will add an entry to the hf_rename list */
285 | static void
286 | register_hf_rename(const char *old_name, const char *new_name)
287 | {
288 | hf_rename_item_t *new_item;
289 | new_item=g_new0(hf_rename_item_t, 1)((hf_rename_item_t *) g_malloc0_n ((1), sizeof (hf_rename_item_t )));
290 | if (!new_item) {
291 | FPRINTF(stderrstderr, "Can't allocate memory. Exit.\n");
292 | exit(10);
293 | }
294 | new_item->next=hf_rename_list;
295 | hf_rename_list=new_item;
296 | new_item->refcount=0;
297 | new_item->old_name=g_strdup(old_name)g_strdup_inline (old_name);
298 | new_item->new_name=g_strdup(new_name)g_strdup_inline (new_name);
299 | }
300 |
301 | /* this function checks that all hf_rename fields have actually been referenced
302 | if not out conformance file is stale
303 | */
304 | static void
305 | check_hf_rename_refcount(void)
306 | {
307 | hf_rename_item_t *hri;
308 |
309 | /* don't generate code for renamed hf fields just return the new name*/
310 | for(hri=hf_rename_list;hri;hri=hri->next){
311 | if(!hri->refcount){
312 | FPRINTF(stderrstderr, "ERROR: the hf_rename field:%s was never referenced. it is likely the conformance file is stale\n", hri->old_name);
313 | exit(10);
314 | }
315 | }
316 | }
317 |
318 | static hf_field_item_t *
319 | find_hf_field(char *name)
320 | {
321 | hf_field_item_t *hfi;
322 |
323 | for(hfi=hf_field_list;hfi;hfi=hfi->next){
324 | if(!g_strcmp0(hfi->name, name)){
325 | break;
326 | }
327 | }
328 | if (!hfi) {
329 | FPRINTF(stderrstderr, "find_hf_field: unknown hf_field:%s\n",name);
330 | Exit(10);
331 | }
332 |
333 | return hfi;
334 | }
335 |
336 |
337 | /* this function will create the code required for a hf field.
338 | it MIGHT rename the field so a user MUST use the name returned
339 | from this function.
340 | for fields that are to be renamed no code is generated
341 | */
342 | static const char *
343 | register_hf_field(const char *hf_name, const char *title, const char *filter_name, const char *ft_type, const char *base_type, const char *valsstring, const char *mask, const char *blurb)
344 | {
345 | hf_field_item_t *hfi;
346 | hf_rename_item_t *hri;
347 |
348 | /* don't generate code for renamed hf fields just return the new name*/
349 | for(hri=hf_rename_list;hri;hri=hri->next){
350 | if(!strncmp(hf_name, hri->old_name, strlen(hf_name))){
351 | hfi=find_hf_field(hri->new_name);
352 | if(g_strcmp0(ft_type, hfi->ft_type)){
353 | FPRINTF(stderrstderr, "register_hf_field: hf_fields %s and %s have different types %s %s\n",hf_name,hfi->name,ft_type,hfi->ft_type);
354 | Exit(10);
355 | }
356 | hri->refcount++;
357 | return hri->new_name;
358 | }
359 | }
360 |
361 | hfi=g_new0(hf_field_item_t, 1)((hf_field_item_t *) g_malloc0_n ((1), sizeof (hf_field_item_t )));
362 | if (!hfi) {
363 | FPRINTF(stderrstderr, "Can't allocate memory. Exit.\n");
364 | exit(10);
365 | }
366 | hfi->next=hf_field_list;
367 | hf_field_list=hfi;
368 | hfi->name=g_strdup(hf_name)g_strdup_inline (hf_name);
369 | hfi->ft_type=g_strdup(ft_type)g_strdup_inline (ft_type);
370 |
371 | FPRINTF(eth_hf, "static int %s;\n", hf_name);
372 | FPRINTF(eth_hfarr, " { &%s,\n", hf_name);
373 | FPRINTF(eth_hfarr, " { \"%s\", \"%s\", %s, %s,\n", title, filter_name, ft_type, base_type);
374 | FPRINTF(eth_hfarr, " %s, %s,\n", valsstring, mask);
375 | if (strlen(blurb) > 0)
376 | FPRINTF(eth_hfarr, " \"%s\", HFILL }},\n", blurb);
377 | else
378 | FPRINTF(eth_hfarr, " NULL, HFILL }},\n");
379 | FPRINTF(eth_hfarr, "\n");
380 |
381 | return hf_name;
382 | }
383 |
384 | /* this function will parse the no emit list and decide whether code should
385 | be generated for this dissector or if we should only register the type.
386 | */
387 | static int
388 | check_if_to_emit(char *name)
389 | {
390 | no_emit_item_t *nel;
391 |
392 | for(nel=no_emit_list;nel;nel=nel->next){
393 | if(!g_strcmp0(name, nel->name)){
394 | FPRINTF(NULL((void*)0), "SKIPPED emitting of %s\n",name);
395 | return 0;
396 | }
397 | }
398 | return 1;
399 | }
400 |
401 | #if 0
402 | static void
403 | prune_keywords(char *name)
404 | {
405 | token_item_t *ti;
406 |
407 | for(ti=token_list;ti;ti=ti->next){
408 | if(!ti->next){
409 | break;
410 | }
411 | if(!g_strcmp0(ti->next->str, name)){
412 | if(!g_strcmp0(ti->next->next->str, ",")){
413 | ti->next=ti->next->next->next;
414 | } else {
415 | ti->next=ti->next->next;
416 | }
417 | }
418 | }
419 | }
420 | #endif
421 |
422 | static void
423 | rename_tokens(const char *old_name, const char *new_name)
424 | {
425 | token_item_t *ti;
426 |
427 | for(ti=token_list;ti;ti=ti->next){
428 | if(!g_strcmp0(ti->str, old_name)){
429 | ti->str=g_strdup(new_name)g_strdup_inline (new_name);
430 | }
431 | }
432 | }
433 |
434 | static void
435 | prune_keyword_parameters(const char *name)
436 | {
437 | token_item_t *ti, *tmpti;
438 |
439 | for(ti=token_list;ti;ti=ti->next){
440 | if(!g_strcmp0(ti->str, name)){
441 | if(!g_strcmp0(ti->next->str, "(")){
442 | tmpti=ti;
443 | while(1){
444 | if(!g_strcmp0(tmpti->str, ")")){
445 | ti->next=tmpti->next;
446 | break;
447 | }
448 | tmpti=tmpti->next;
449 | }
450 | }
451 | }
452 | }
453 | }
454 |
455 | /* this function will parse a bracket item
456 | [ ... ]
457 | it will return the token of the next item following the ']'
458 | */
459 | static token_item_t *
460 | parsebrackets(token_item_t *ti, bracket_item_t **bracket){
461 | bracket_item_t *br;
462 | const type_item_t *type_item;
463 |
464 | if(g_strcmp0(ti->str, "[")){
465 | FPRINTF(stderrstderr, "ERROR: parsebrackets first token is not '['\n");
466 | Exit(10);
467 | }
468 | ti=ti->next;
469 |
470 | br=g_new0(bracket_item_t, 1)((bracket_item_t *) g_malloc0_n ((1), sizeof (bracket_item_t) ));
471 | if (!br) {
472 | FPRINTF(stderrstderr, "Can't allocate memory. Exit.\n");
473 | exit(10);
474 | }
475 | *bracket=br;
476 | br->flags=0;
477 | br->case_name=NULL((void*)0);
478 | br->pointer_list=NULL((void*)0);
479 |
480 | while(ti){
481 | if( !g_strcmp0(ti->str, "{")
482 | ||!g_strcmp0(ti->str, "}")){
483 | FPRINTF(stderrstderr, "ERROR: parsebrackets '{' '}' inside bracket item\n");
484 | Exit(10);
485 | }
486 |
487 | if(!g_strcmp0(ti->str, "[")){
488 | FPRINTF(stderrstderr, "ERROR: parsebrackets '[' inside bracket item\n");
489 | Exit(10);
490 | }
491 |
492 | /* finished */
493 | if(!g_strcmp0(ti->str, "]")){
494 | /* check for [ ... ] [ ...] */
495 | ti=ti->next;
496 |
497 | if(!g_strcmp0(ti->str, "[")){
498 | ti=ti->next;
499 | continue;
500 | }
501 | return ti;
502 | }
503 |
504 | /* just ignore all ',' */
505 | if(!g_strcmp0(ti->str, ",")){
506 | ti=ti->next;
507 | continue;
508 | }
509 |
510 | /* case '(' tag ')' */
511 | if(!g_strcmp0(ti->str, "case")){
512 | br->flags|=BI_CASE0x00000001;
513 | ti=ti->next;
514 |
515 | if(g_strcmp0(ti->str, "(")){
516 | FPRINTF(stderrstderr, "ERROR: parsebrackets case not followed by '('\n");
517 | Exit(10);
518 | }
519 | ti=ti->next;
520 |
521 | /* name */
522 | br->case_name=ti->str;
523 | ti=ti->next;
524 |
525 | if(g_strcmp0(ti->str, ")")){
526 | FPRINTF(stderrstderr, "ERROR: parsebrackets case does not end with ')'\n");
527 | Exit(10);
528 | }
529 | ti=ti->next;
530 | continue;
531 | }
532 |
533 | /* default */
534 | if(!g_strcmp0(ti->str, "default")){
535 | br->flags|=BI_CASE0x00000001;
536 | br->flags|=BI_CASE_DEFAULT0x00000002;
537 | br->case_name="default";
538 | ti=ti->next;
539 | continue;
540 | }
541 |
542 |
543 | /* in */
544 | if(!g_strcmp0(ti->str, "in")){
545 | br->flags|=BI_IN0x00000004;
546 | ti=ti->next;
547 | continue;
548 | }
549 |
550 | /* out */
551 | if(!g_strcmp0(ti->str, "out")){
552 | br->flags|=BI_OUT0x00000008;
553 | ti=ti->next;
554 | continue;
555 | }
556 |
557 | /* public : we don't care about this one */
558 | if(!g_strcmp0(ti->str, "public")){
559 | ti=ti->next;
560 | continue;
561 | }
562 |
563 | /* gensize : we don't care about this one */
564 | if(!g_strcmp0(ti->str, "gensize")){
565 | ti=ti->next;
566 | continue;
567 | }
568 |
569 | /* switch_is */
570 | if(!g_strcmp0(ti->str, "switch_is")){
571 | FPRINTF(stderrstderr, "WARNING: parsebrackets can not handle switch_is properly yet so we can not verify the tag size\n");
572 | while(ti){
573 | if(!g_strcmp0(ti->str, ")")){
574 | ti=ti->next;
575 | break;
576 | }
577 | ti=ti->next;
578 | }
579 | continue;
580 | }
581 |
582 | /* switch_is */
583 | if(!g_strcmp0(ti->str, "subcontext")){
584 | while(ti){
585 | if(!g_strcmp0(ti->str, ")")){
586 | ti=ti->next;
587 | break;
588 | }
589 | ti=ti->next;
590 | }
591 | continue;
592 | }
593 |
594 | /* value we don't care about this one so just skip it */
595 | if(!g_strcmp0(ti->str, "value")){
596 | int level;
597 | ti=ti->next;
598 | if( g_strcmp0(ti->str, "(") ){
599 | FPRINTF(stderrstderr, "WARNING: parsebrackets value was not followed by '('\n");
600 | Exit(10);
601 | }
602 | level=0;
603 | while(ti){
604 | if(!g_strcmp0(ti->str, "(")){
605 | ti=ti->next;
606 | level++;
607 | continue;
608 | }
609 | if(!g_strcmp0(ti->str, ")")){
610 | ti=ti->next;
611 | level--;
612 | if(level){
613 | continue;
614 | }
615 | break;
616 | }
617 | ti=ti->next;
618 | }
619 | continue;
620 | }
621 |
622 | /* range we don't care about this one so just skip it */
623 | if(!g_strcmp0(ti->str, "range")){
624 | int level;
625 | ti=ti->next;
626 | if( g_strcmp0(ti->str, "(") ){
627 | FPRINTF(stderrstderr, "WARNING: parsebrackets range was not followed by '('\n");
628 | Exit(10);
629 | }
630 | level=0;
631 | while(ti){
632 | if(!g_strcmp0(ti->str, "(")){
633 | ti=ti->next;
634 | level++;
635 | continue;
636 | }
637 | if(!g_strcmp0(ti->str, ")")){
638 | ti=ti->next;
639 | level--;
640 | if(level){
641 | continue;
642 | }
643 | break;
644 | }
645 | ti=ti->next;
646 | }
647 | continue;
648 | }
649 |
650 | /* flag we don't care about this one so just skip it */
651 | if(!g_strcmp0(ti->str, "flag")){
652 | int level;
653 | ti=ti->next;
654 | if( g_strcmp0(ti->str, "(") ){
655 | FPRINTF(stderrstderr, "WARNING: parsebrackets flag was not followed by '('\n");
656 | Exit(10);
657 | }
658 | level=0;
659 | while(ti){
660 | if(!g_strcmp0(ti->str, "(")){
661 | ti=ti->next;
662 | level++;
663 | continue;
664 | }
665 | if(!g_strcmp0(ti->str, ")")){
666 | ti=ti->next;
667 | level--;
668 | if(level){
669 | continue;
670 | }
671 | break;
672 | }
673 | ti=ti->next;
674 | }
675 | continue;
676 | }
677 |
678 | /* switch_type */
679 | if(!g_strcmp0(ti->str, "switch_type")){
680 | br->flags|=BI_SWITCH_TYPE0x00000400;
681 | ti=ti->next;
682 |
683 | if(g_strcmp0(ti->str, "(")){
684 | FPRINTF(stderrstderr, "WARNING: parsebrackets switch_type was not followed by '('\n");
685 | Exit(10);
686 | }
687 | ti=ti->next;
688 |
689 | type_item=find_type(ti->str);
690 | if(!type_item){
691 | FPRINTF(stderrstderr, "ERROR : parsebrackets switch_type unknown type %s\n",ti->str);
692 | Exit(10);
693 | }
694 | br->union_tag_size=type_item->alignment;
695 | ti=ti->next;
696 |
697 | if(g_strcmp0(ti->str, ")")){
698 | FPRINTF(stderrstderr, "WARNING: parsebrackets switch_type did not end with ')'\n");
699 | Exit(10);
700 | }
701 | ti=ti->next;
702 |
703 | continue;
704 | }
705 |
706 | /* size_is */
707 | if(!g_strcmp0(ti->str, "size_is")){
708 | br->flags|=BI_SIZE_IS0x00000010;
709 | ti=ti->next;
710 | continue;
711 | }
712 |
713 | /* length_is */
714 | if(!g_strcmp0(ti->str, "length_is")){
715 | br->flags|=BI_LENGTH_IS0x00000020;
716 | ti=ti->next;
717 | continue;
718 | }
719 |
720 | /* bitmap8bit */
721 | if(!g_strcmp0(ti->str, "bitmap8bit")){
722 | br->flags|=BI_BITMAP80x00000100;
723 | ti=ti->next;
724 | continue;
725 | }
726 |
727 | /* bitmap32bit */
728 | if(!g_strcmp0(ti->str, "bitmap32bit")){
729 | br->flags|=BI_BITMAP320x00000200;
730 | ti=ti->next;
731 | continue;
732 | }
733 |
734 | /* ref, unique or ptr */
735 | if(!g_strcmp0(ti->str, "ref")
736 | || !g_strcmp0(ti->str, "unique")
737 | || !g_strcmp0(ti->str, "ptr")){
738 | pointer_item_t *newpi;
739 |
740 | br->flags|=BI_POINTER0x00000040;
741 | newpi=g_new0(pointer_item_t, 1)((pointer_item_t *) g_malloc0_n ((1), sizeof (pointer_item_t) ));
742 | if (!newpi) {
743 | FPRINTF(stderrstderr, "Can't allocate memory. Exit.\n");
744 | exit(10);
745 | }
746 | newpi->next=NULL((void*)0);
747 | newpi->type=ti->str;
748 | newpi->next=br->pointer_list;
749 | br->pointer_list=newpi;
750 | ti=ti->next;
751 | continue;
752 | }
753 | if(ti){
754 | FPRINTF(stderrstderr, "ERROR: parsebrackets should not be reached unknown tag:%s\n", ti->str);
755 | }
756 | Exit(10);
757 | }
758 |
759 | return NULL((void*)0);
760 | }
761 |
762 | /* this function will register a new type learnt from the IDL file
763 | */
764 | static type_item_t *
765 | register_new_type(const char *name, const char *dissectorname, const char *ft_type, const char *base_type, const char *mask, const char *valsstring, int alignment){
766 | type_item_t *new_type;
767 |
768 | FPRINTF(NULL((void*)0),"XXX new type:%s dissector:%s Type:%s Base:%s Mask:%s Vals:%s alignment:%d\n", name, dissectorname, ft_type, base_type, mask, valsstring, alignment);
769 |
770 | new_type=g_new0(type_item_t, 1)((type_item_t *) g_malloc0_n ((1), sizeof (type_item_t)));
771 | if (!new_type) {
772 | FPRINTF(stderrstderr, "Can't allocate memory. Exit.\n");
773 | exit(10);
774 | }
775 | new_type->next=type_list;
776 | new_type->name=g_strdup(name)g_strdup_inline (name);
777 | new_type->dissector=g_strdup(dissectorname)g_strdup_inline (dissectorname);
778 | new_type->ft_type=g_strdup(ft_type)g_strdup_inline (ft_type);
779 | new_type->base_type=g_strdup(base_type)g_strdup_inline (base_type);
780 | new_type->mask=g_strdup(mask)g_strdup_inline (mask);
781 | new_type->vals=g_strdup(valsstring)g_strdup_inline (valsstring);
782 | new_type->alignment=alignment;
783 | type_list=new_type;
784 |
785 | return new_type;
786 | }
787 |
788 |
789 | /* this function will print the remaining content of the token list
790 | */
791 | static void printtokenlist(int count)
792 | {
793 | token_item_t *ti;
794 | FPRINTF(stderrstderr, "TOKENLIST:\n");
795 | for(ti=token_list;ti&&count;count--,ti=ti->next){
796 | FPRINTF(stderrstderr, "Token \"%s\"\n",ti->str);
797 | }
798 | if(!count){
799 | FPRINTF(stderrstderr, " ...\n");
800 | }
801 | }
802 |
803 |
804 | /* this function will parse the header and pick up the fields
805 | * we are interested in.
806 | * the header is supposed to start at the very first token and look like
807 | * [ <fields> ] interface <ifname> {
808 | *
809 | * we are interested in the fields:
810 | * uuid
811 | * version
812 | * pointer_default
813 | *
814 | * this function will also g_remove the header from the token list
815 | */
816 | static void parseheader(void)
817 | {
818 | char filter_name[BASE_BUFFER_SIZE256];
819 | token_item_t *ti;
820 | int level=0;
821 | int major, minor;
822 |
823 | ti=token_list;
824 | if(!ti){
825 | FPRINTF(stderrstderr, "ERROR: no tokens\n");
826 | Exit(10);
827 | }
828 |
829 | /* first token must be '[' */
830 | if( g_strcmp0(ti->str, "[") ){
831 | FPRINTF(stderrstderr, "ERROR: first token is not '['\n");
832 | Exit(10);
833 | }
834 |
835 | for(ti=token_list;ti;ti=ti->next){
836 | if( !g_strcmp0(ti->str, "[")){
837 | level++;
838 | continue;
839 | }
840 | if( !g_strcmp0(ti->str, "]")){
841 | level--;
842 | if(!level){
843 | token_list=ti->next;
844 | break;
845 | }
846 | }
847 | if(level==1){
848 | if( !g_strcmp0(ti->str, "uuid")){
849 | uuid=ti->next->next->str;
850 | FPRINTF(NULL((void*)0),"UUID:%s\n",uuid);
851 | }
852 | if( !g_strcmp0(ti->str, "version")){
853 | version=ti->next->next->str;
854 | FPRINTF(NULL((void*)0),"VERSION:%s\n",version);
855 | }
856 | if( !g_strcmp0(ti->str, "pointer_default")){
857 | if(!g_strcmp0(ti->next->next->str, "unique")){
858 | pointer_default="unique";
859 | } else if(!g_strcmp0(ti->next->next->str, "ptr")){
860 | pointer_default="ptr";
861 | } else {
862 | FPRINTF(stderrstderr, "ERROR: unknown pointer type\n");
863 | Exit(10);
864 | }
865 | FPRINTF(NULL((void*)0),"POINTER_DEFAULT:%s\n",pointer_default);
866 | }
867 | }
868 | }
869 | if(!token_list){
870 | FPRINTF(stderrstderr, "ERROR: ran out of tokens inside header\n");
871 | Exit(10);
872 | }
873 | /* interface */
874 | if(g_strcmp0(token_list->str, "interface")){
875 | FPRINTF(stderrstderr, "ERROR: interface not found\n");
876 | Exit(10);
877 | }
878 | token_list=token_list->next;
879 | if (!token_list){
880 | FPRINTF(stderrstderr, "ERROR: ran out of tokens\n");
881 | Exit(10);
882 | }
883 | /* interface name */
884 | ifname=token_list->str;
885 | token_list=token_list->next;
886 | FPRINTF(NULL((void*)0),"Interface:%s\n",ifname);
887 |
888 | /* opnum */
889 | snprintf(hf_status, BASE_BUFFER_SIZE256, "hf_%s_opnum", ifname);
890 | snprintf(filter_name, BASE_BUFFER_SIZE256, "%s.opnum", ifname);
891 | register_hf_field(hf_status, "Operation", filter_name, "FT_UINT16", "BASE_DEC", "NULL", "0", "");
892 |
893 | /* status */
894 | snprintf(hf_status, BASE_BUFFER_SIZE256, "hf_%s_rc", ifname);
895 | snprintf(filter_name, BASE_BUFFER_SIZE256, "%s.rc", ifname);
896 | register_hf_field(hf_status, "Return code", filter_name, "FT_UINT32", "BASE_HEX|BASE_EXT_STRING", "&NT_errors_ext", "0", "");
897 |
898 | FPRINTF(eth_ett, "static int ett_%s;\n", ifname);
899 | FPRINTF(eth_ettarr, " &ett_%s,\n", ifname);
900 |
901 | /* the body must start with { */
902 | if(g_strcmp0(token_list->str, "{")){
903 | FPRINTF(stderrstderr, "ERROR: body does not start with '{'\n");
904 | Exit(10);
905 | }
906 |
907 | /* skip the initial '{' */
908 | token_list=token_list->next;
909 |
910 | if(!uuid){
911 | FPRINTF(stderrstderr, "ERROR: no uuid found\n");
912 | Exit(10);
913 | }
914 | FPRINTF(eth_code,"static e_guid_t uuid_dcerpc_%s = {\n", ifname);
915 | FPRINTF(eth_code," 0x%c%c%c%c%c%c%c%c, 0x%c%c%c%c, 0x%c%c%c%c,\n",uuid[1],uuid[2],uuid[3],uuid[4],uuid[5],uuid[6],uuid[7],uuid[8],uuid[10],uuid[11],uuid[12],uuid[13],uuid[15],uuid[16],uuid[17],uuid[18]);
916 | FPRINTF(eth_code," { 0x%c%c, 0x%c%c, 0x%c%c, 0x%c%c, 0x%c%c, 0x%c%c, 0x%c%c, 0x%c%c}\n",uuid[20],uuid[21],uuid[22],uuid[23],uuid[25],uuid[26],uuid[27],uuid[28],uuid[29],uuid[30],uuid[31],uuid[32],uuid[33],uuid[34],uuid[35],uuid[36]);
917 | FPRINTF(eth_code,"};\n");
918 | FPRINTF(eth_code,"\n");
919 |
920 | sscanf(version, "%d.%d", &major, &minor);
921 | FPRINTF(eth_code,"static uint16_t ver_%s = %d;\n", ifname, major);
922 | FPRINTF(eth_code,"\n");
923 |
924 | FPRINTF(eth_handoff, " dcerpc_init_uuid(proto_%s, ett_%s,\n", ifname, ifname);
925 | FPRINTF(eth_handoff, " &uuid_dcerpc_%s, ver_%s,\n", ifname, ifname);
926 | FPRINTF(eth_handoff, " function_dissectors, hf_%s_opnum);\n", ifname);
927 | }
928 |
929 |
930 |
931 | /* this helper function is called by the tokenizer and will just append the
932 | current token to the linked list
933 | */
934 | static void pushtoken(char *token)
935 | {
936 | token_item_t *new_token_item;
937 | new_token_item=g_new0(token_item_t, 1)((token_item_t *) g_malloc0_n ((1), sizeof (token_item_t)));
938 | if (!new_token_item) {
939 | FPRINTF(stderrstderr, "Can't allocate memory. Exit.\n");
940 | exit(10);
941 | }
942 | new_token_item->next=NULL((void*)0);
943 | new_token_item->str=token;
944 | if(!token_list){
945 | token_list=new_token_item;
946 | } else {
947 | last_token_item->next=new_token_item;
948 | }
949 | last_token_item=new_token_item;
950 | }
951 |
952 | /* this function reads the idl file and translates it into tokens.
953 | the tokens are stored in a linked list token_list of type token_item_t
954 | */
955 | static void tokenize(FILE *fh)
956 | {
957 | int ch;
958 | int fullinecomment=0;
959 | int normalcomment=0;
960 | int insidequote=0;
961 | char qs[4 * BASE_BUFFER_SIZE256];
962 | int qspos=0;
963 | int insidetoken=0;
964 | char token[4 * BASE_BUFFER_SIZE256];
965 | int tokenpos=0;
966 |
967 | while(!feof(fh)){
6 | ← | Loop condition is true. Entering loop body | →
9 | ← | Execution continues on line 967 | →
10 | ← | Loop condition is true. Entering loop body | →
13 | ← | Execution continues on line 967 | →
14 | ← | Loop condition is true. Entering loop body | →
968 | ch=fgetc(fh);
11 | ← | Assuming this stream operation fails | →
15 | ← | File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior
969 |
970 | /* full line comment */
971 | if(fullinecomment
6.1 | 'fullinecomment' is 0
11.1 | 'fullinecomment' is 1
){
972 | if( (ch=='\n')||(ch=='\r') ){
12 | ← | Taking false branch | →
973 | fullinecomment=0;
974 | linepos=0;
975 | }
976 | continue;
977 | }
978 | if( (ch=='#')&&(linepos
7.1 | 'linepos' is equal to 0
==0) ){
7 | ← | Assuming the condition is true | →
8 | ← | Taking true branch | →
979 | fullinecomment=1;
980 | continue;
981 | }
982 |
983 | /* normal comment */
984 | if(normalcomment==0){
985 | if(ch=='/'){
986 | int nextch;
987 | nextch=fgetc(fh);
988 | if(nextch=='*'){
989 | normalcomment=1;
990 | continue;
991 | }
992 | ungetc(nextch, fh);
993 | }
994 | } else {
995 | if(ch=='*'){
996 | int nextch;
997 | nextch=fgetc(fh);
998 | if(nextch=='/'){
999 | normalcomment=0;
1000 | continue;
1001 | }
1002 | ungetc(nextch, fh);
1003 | }
1004 | continue;
1005 | }
1006 |
1007 | /* quoted string */
1008 | if(insidequote){
1009 | if(ch=='"'){
1010 | insidequote=0;
1011 | qs[qspos++]='"';
1012 | qs[qspos]=0;
1013 | pushtoken(g_strdup(qs)g_strdup_inline (qs));
1014 | continue;
1015 | } else {
1016 | qs[qspos++]=(char)ch;
1017 | continue;
1018 | }
1019 | } else {
1020 | if(ch=='"'){
1021 | insidequote=1;
1022 | qs[0]='"';
1023 | qspos=1;
1024 | continue;
1025 | }
1026 | }
1027 |
1028 |
1029 | switch(ch){
1030 | case '\n':
1031 | case '\r':
1032 | if(insidetoken){
1033 | insidetoken=0;
1034 | token[tokenpos]=0;
1035 | pushtoken(g_strdup(token)g_strdup_inline (token));
1036 | }
1037 | line[linepos]=0;
1038 |
1039 | linepos=0;
1040 | lineno++;
1041 | break;
1042 | case '\t':
1043 | case ' ':
1044 | if(insidetoken){
1045 | insidetoken=0;
1046 | token[tokenpos]=0;
1047 | pushtoken(g_strdup(token)g_strdup_inline (token));
1048 | }
1049 | break;
1050 | case '[':
1051 | case ']':
1052 | case '(':
1053 | case ')':
1054 | case ',':
1055 | case ';':
1056 | case '*':
1057 | case '=':
1058 | if(insidetoken){
1059 | insidetoken=0;
1060 | token[tokenpos]=0;
1061 | pushtoken(g_strdup(token)g_strdup_inline (token));
1062 | }
1063 | token[0]=(char)ch;
1064 | token[1]=0;
1065 | pushtoken(g_strdup(token)g_strdup_inline (token));
1066 | break;
1067 | default:
1068 | if(!insidetoken){
1069 | tokenpos=0;
1070 | }
1071 | insidetoken=1;
1072 | token[tokenpos++]=(char)ch;
1073 | line[linepos++]=(char)ch;
1074 | break;
1075 | }
1076 |
1077 | }
1078 | }
1079 |
1080 |
1081 | static type_item_t *
1082 | find_type(char *name)
1083 | {
1084 | type_item_t *tmptype;
1085 | for(tmptype=type_list;tmptype;tmptype=tmptype->next){
1086 | if(!g_strcmp0(tmptype->name, name)){
1087 | break;
1088 | }
1089 | }
1090 | /* autogenerate built in types */
1091 | if(!tmptype){
1092 | char dissectorname[DISSECTORNAME_MAXLEN256];
1093 | if(!g_strcmp0(name,"uint16")){
1094 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1095 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1096 | FPRINTF(eth_code, "\n");
1097 | FPRINTF(eth_code, "static unsigned\n");
1098 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1099 | FPRINTF(eth_code, "{\n");
1100 | FPRINTF(eth_code, " offset=dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1101 | FPRINTF(eth_code, " return offset;\n");
1102 | FPRINTF(eth_code, "}\n");
1103 | FPRINTF(eth_code, "\n");
1104 | tmptype=register_new_type("uint16", dissectorname, "FT_UINT16", "BASE_DEC", "0", "NULL", 2);
1105 | } else if(!g_strcmp0(name,"int16")){
1106 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1107 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1108 | FPRINTF(eth_code, "\n");
1109 | FPRINTF(eth_code, "static unsigned\n");
1110 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1111 | FPRINTF(eth_code, "{\n");
1112 | FPRINTF(eth_code, " offset=dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1113 | FPRINTF(eth_code, " return offset;\n");
1114 | FPRINTF(eth_code, "}\n");
1115 | FPRINTF(eth_code, "\n");
1116 | tmptype=register_new_type("int16", dissectorname, "FT_INT16", "BASE_DEC", "0", "NULL", 2);
1117 | } else if(!g_strcmp0(name,"uint32")){
1118 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1119 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1120 | FPRINTF(eth_code, "\n");
1121 | FPRINTF(eth_code, "static unsigned\n");
1122 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1123 | FPRINTF(eth_code, "{\n");
1124 | FPRINTF(eth_code, " offset=dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1125 | FPRINTF(eth_code, " return offset;\n");
1126 | FPRINTF(eth_code, "}\n");
1127 | FPRINTF(eth_code, "\n");
1128 | tmptype=register_new_type("uint32", dissectorname, "FT_UINT32", "BASE_DEC", "0", "NULL", 4);
1129 | } else if( (!g_strcmp0(name,"int32"))
1130 | || (!g_strcmp0(name,"long")) ){
1131 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1132 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1133 | FPRINTF(eth_code, "\n");
1134 | FPRINTF(eth_code, "static unsigned\n");
1135 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1136 | FPRINTF(eth_code, "{\n");
1137 | FPRINTF(eth_code, " offset=dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1138 | FPRINTF(eth_code, " return offset;\n");
1139 | FPRINTF(eth_code, "}\n");
1140 | FPRINTF(eth_code, "\n");
1141 | if (!g_strcmp0(name,"int32"))
1142 | tmptype=register_new_type("int32", dissectorname, "FT_INT32", "BASE_DEC", "0", "NULL", 4);
1143 | else
1144 | tmptype=register_new_type("long", dissectorname, "FT_INT32", "BASE_DEC", "0", "NULL", 4);
1145 | } else if( (!g_strcmp0(name,"uint8")) ){
1146 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1147 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1148 | FPRINTF(eth_code, "\n");
1149 | FPRINTF(eth_code, "static unsigned\n");
1150 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1151 | FPRINTF(eth_code, "{\n");
1152 | FPRINTF(eth_code, " offset=dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1153 | FPRINTF(eth_code, " return offset;\n");
1154 | FPRINTF(eth_code, "}\n");
1155 | FPRINTF(eth_code, "\n");
1156 | tmptype=register_new_type("uint8", dissectorname, "FT_UINT8", "BASE_DEC", "0", "NULL", 1);
1157 | } else if( (!g_strcmp0(name,"int8"))
1158 | || (!g_strcmp0(name, "char")) ){
1159 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1160 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1161 | FPRINTF(eth_code, "\n");
1162 | FPRINTF(eth_code, "static unsigned\n");
1163 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1164 | FPRINTF(eth_code, "{\n");
1165 | FPRINTF(eth_code, " offset=dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1166 | FPRINTF(eth_code, " return offset;\n");
1167 | FPRINTF(eth_code, "}\n");
1168 | FPRINTF(eth_code, "\n");
1169 | if (!g_strcmp0(name,"int8"))
1170 | tmptype=register_new_type("int8", dissectorname, "FT_INT8", "BASE_DEC", "0", "NULL", 1);
1171 | else
1172 | tmptype=register_new_type("char", dissectorname, "FT_INT8", "BASE_DEC", "0", "NULL", 1);
1173 | } else if(!g_strcmp0(name,"bool8")){
1174 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1175 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1176 | FPRINTF(eth_code, "\n");
1177 | FPRINTF(eth_code, "static unsigned\n");
1178 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1179 | FPRINTF(eth_code, "{\n");
1180 | FPRINTF(eth_code, " offset=dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1181 | FPRINTF(eth_code, " return offset;\n");
1182 | FPRINTF(eth_code, "}\n");
1183 | FPRINTF(eth_code, "\n");
1184 | tmptype=register_new_type("bool8", dissectorname, "FT_INT8", "BASE_DEC", "0", "NULL", 1);
1185 | } else if(!g_strcmp0(name,"unistr")){
1186 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1187 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1188 | FPRINTF(eth_code, "\n");
1189 | FPRINTF(eth_code, "static unsigned\n");
1190 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1191 | FPRINTF(eth_code, "{\n");
1192 | FPRINTF(eth_code, " offset=dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep, 2, hf_index, false, NULL);\n");
1193 | FPRINTF(eth_code, " return offset;\n");
1194 | FPRINTF(eth_code, "}\n");
1195 | FPRINTF(eth_code, "\n");
1196 | tmptype=register_new_type("unistr", dissectorname, "FT_STRING", "BASE_NONE", "0", "NULL", 4);
1197 | } else if(!g_strcmp0(name,"ascstr")){
1198 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1199 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1200 | FPRINTF(eth_code, "\n");
1201 | FPRINTF(eth_code, "static unsigned\n");
1202 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1203 | FPRINTF(eth_code, "{\n");
1204 | FPRINTF(eth_code, " offset=dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep, 1, hf_index, false, NULL);\n");
1205 | FPRINTF(eth_code, " return offset;\n");
1206 | FPRINTF(eth_code, "}\n");
1207 | FPRINTF(eth_code, "\n");
1208 | tmptype=register_new_type("ascstr", dissectorname, "FT_STRING", "BASE_NONE", "0", "NULL", 4);
1209 | } else if(!g_strcmp0(name,"GUID")
1210 | ||!g_strcmp0(name,"uuid_t")){
1211 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1212 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1213 | FPRINTF(eth_code, "\n");
1214 | FPRINTF(eth_code, "static unsigned\n");
1215 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1216 | FPRINTF(eth_code, "{\n");
1217 | FPRINTF(eth_code, " offset=dissect_ndr_uuid_t(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1218 | FPRINTF(eth_code, " return offset;\n");
1219 | FPRINTF(eth_code, "}\n");
1220 | FPRINTF(eth_code, "\n");
1221 | tmptype=register_new_type(name, dissectorname, "FT_GUID", "BASE_NONE", "0", "NULL", 4);
1222 | } else if(!g_strcmp0(name,"policy_handle")){
1223 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1224 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1225 | FPRINTF(eth_code, "\n");
1226 | FPRINTF(eth_code, "static e_ctx_hnd policy_hnd;\n");
1227 | FPRINTF(eth_code, "static proto_item *hnd_item;\n");
1228 | FPRINTF(eth_code, "\n");
1229 | FPRINTF(eth_code, "static unsigned\n");
1230 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param)\n", dissectorname);
1231 | FPRINTF(eth_code, "{\n");
1232 | FPRINTF(eth_code, " offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,\n");
1233 | FPRINTF(eth_code, " hf_index, &policy_hnd, &hnd_item,\n");
1234 | FPRINTF(eth_code, " param);\n");
1235 |
1236 | FPRINTF(eth_code, " return offset;\n");
1237 | FPRINTF(eth_code, "}\n");
1238 | FPRINTF(eth_code, "\n");
1239 | tmptype=register_new_type("policy_handle", dissectorname, "FT_BYTES", "BASE_NONE", "0", "NULL", 4);
1240 | } else if(!g_strcmp0(name,"NTTIME")){
1241 | /* 8 bytes, aligned to 4 bytes */
1242 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1243 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1244 | FPRINTF(eth_code, "\n");
1245 | FPRINTF(eth_code, "static unsigned\n");
1246 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1247 | FPRINTF(eth_code, "{\n");
1248 | FPRINTF(eth_code, " offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep, hf_index);\n");
1249 |
1250 | FPRINTF(eth_code, "\n");
1251 | FPRINTF(eth_code, " return offset;\n");
1252 | FPRINTF(eth_code, "}\n");
1253 | FPRINTF(eth_code, "\n");
1254 | tmptype=register_new_type("NTTIME", dissectorname, "FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", "0", "NULL", 4);
1255 | } else if(!g_strcmp0(name,"NTTIME_hyper")){
1256 | /* 8 bytes, aligned to 8 bytes */
1257 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1258 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1259 | FPRINTF(eth_code, "\n");
1260 | FPRINTF(eth_code, "static unsigned\n");
1261 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1262 | FPRINTF(eth_code, "{\n");
1263 | FPRINTF(eth_code, " ALIGN_TO_8_BYTES;\n");
1264 | FPRINTF(eth_code, " offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep, hf_index);\n");
1265 |
1266 | FPRINTF(eth_code, "\n");
1267 | FPRINTF(eth_code, " return offset;\n");
1268 | FPRINTF(eth_code, "}\n");
1269 | FPRINTF(eth_code, "\n");
1270 | tmptype=register_new_type("NTTIME_hyper", dissectorname, "FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", "0", "NULL", 4);
1271 | } else if(!g_strcmp0(name,"NTTIME_1sec")){
1272 | /* 8 bytes, aligned to 8 bytes */
1273 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1274 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1275 | FPRINTF(eth_code, "\n");
1276 | FPRINTF(eth_code, "static unsigned\n");
1277 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1278 | FPRINTF(eth_code, "{\n");
1279 | FPRINTF(eth_code, " ALIGN_TO_8_BYTES;\n");
1280 | FPRINTF(eth_code, " offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep, hf_index);\n");
1281 |
1282 | FPRINTF(eth_code, "\n");
1283 | FPRINTF(eth_code, " return offset;\n");
1284 | FPRINTF(eth_code, "}\n");
1285 | FPRINTF(eth_code, "\n");
1286 | tmptype=register_new_type("NTTIME_1sec", dissectorname, "FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", "0", "NULL", 4);
1287 | } else if(!g_strcmp0(name,"udlong")){
1288 | /* 8 bytes, aligned to 4 bytes */
1289 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1290 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1291 | FPRINTF(eth_code, "\n");
1292 | FPRINTF(eth_code, "static unsigned\n");
1293 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1294 | FPRINTF(eth_code, "{\n");
1295 | FPRINTF(eth_code, "\n");
1296 | FPRINTF(eth_code, " offset=dissect_ndr_duint32(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1297 | FPRINTF(eth_code, "\n");
1298 | FPRINTF(eth_code, " return offset;\n");
1299 | FPRINTF(eth_code, "}\n");
1300 | FPRINTF(eth_code, "\n");
1301 | tmptype=register_new_type("udlong", dissectorname, "FT_UINT64", "BASE_DEC", "0", "NULL", 4);
1302 | } else if(!g_strcmp0(name,"dlong")){
1303 | /* 8 bytes, aligned to 4 bytes */
1304 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1305 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1306 | FPRINTF(eth_code, "\n");
1307 | FPRINTF(eth_code, "static unsigned\n");
1308 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1309 | FPRINTF(eth_code, "{\n");
1310 | FPRINTF(eth_code, "\n");
1311 | FPRINTF(eth_code, " offset=dissect_ndr_duint32(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1312 | FPRINTF(eth_code, "\n");
1313 | FPRINTF(eth_code, " return offset;\n");
1314 | FPRINTF(eth_code, "}\n");
1315 | FPRINTF(eth_code, "\n");
1316 | tmptype=register_new_type("dlong", dissectorname, "FT_INT64", "BASE_DEC", "0", "NULL", 4);
1317 | } else if(!g_strcmp0(name,"uint64")){
1318 | /* 8 bytes, aligned to 8 bytes */
1319 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1320 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1321 | FPRINTF(eth_code, "\n");
1322 | FPRINTF(eth_code, "static unsigned\n");
1323 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1324 | FPRINTF(eth_code, "{\n");
1325 | FPRINTF(eth_code, " \n");
1326 | FPRINTF(eth_code, " ALIGN_TO_8_BYTES;\n");
1327 | FPRINTF(eth_code, " offset=dissect_ndr_uint64(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1328 | FPRINTF(eth_code, "\n");
1329 | FPRINTF(eth_code, " return offset;\n");
1330 | FPRINTF(eth_code, "}\n");
1331 | FPRINTF(eth_code, "\n");
1332 | tmptype=register_new_type("uint64", dissectorname, "FT_UINT64", "BASE_DEC", "0", "NULL", 8);
1333 | } else if(!g_strcmp0(name,"time_t")){
1334 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1335 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1336 | FPRINTF(eth_code, "\n");
1337 | FPRINTF(eth_code, "static unsigned\n");
1338 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1339 | FPRINTF(eth_code, "{\n");
1340 | FPRINTF(eth_code, "\n");
1341 | FPRINTF(eth_code, " offset=dissect_ndr_time_t(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1342 | FPRINTF(eth_code, "\n");
1343 | FPRINTF(eth_code, " return offset;\n");
1344 | FPRINTF(eth_code, "}\n");
1345 | FPRINTF(eth_code, "\n");
1346 | tmptype=register_new_type("time_t", dissectorname, "FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", "0", "NULL", 4);
1347 | } else if(!g_strcmp0(name,"SID")){
1348 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1349 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1350 | FPRINTF(eth_code, "\n");
1351 | FPRINTF(eth_code, "static unsigned\n");
1352 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param)\n", dissectorname);
1353 | FPRINTF(eth_code, "{\n");
1354 | FPRINTF(eth_code, " offset=dissect_ndr_nt_SID_with_options(tvb, offset, pinfo, tree, di, drep, param, hf_index);\n");
1355 | FPRINTF(eth_code, " return offset;\n");
1356 | FPRINTF(eth_code, "}\n");
1357 | FPRINTF(eth_code, "\n");
1358 | tmptype=register_new_type("SID", dissectorname, "FT_STRING", "BASE_NONE", "0", "NULL", 4);
1359 | } else if(!g_strcmp0(name,"WERROR")){
1360 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, name);
1361 | FPRINTF(NULL((void*)0),"\nAutogenerating built-in type:%s\n------------\n",name);
1362 | FPRINTF(eth_code, "\n");
1363 | FPRINTF(eth_code, "static unsigned\n");
1364 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
1365 | FPRINTF(eth_code, "{\n");
1366 | FPRINTF(eth_code, " \n");
1367 | FPRINTF(eth_code, " offset=dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
1368 | FPRINTF(eth_code, "\n");
1369 | FPRINTF(eth_code, " return offset;\n");
1370 | FPRINTF(eth_code, "}\n");
1371 | FPRINTF(eth_code, "\n");
1372 | tmptype=register_new_type("WERROR", dissectorname, "FT_UINT32", "BASE_DEC|BASE_EXT_STRING", "0", "&WERR_errors_ext", 4);
1373 | }
1374 | }
1375 |
1376 | return tmptype;
1377 | }
1378 |
1379 |
1380 | /* this function will skip past an entire declare ... ; statement */
1381 | static void skipdeclare(void)
1382 | {
1383 | token_item_t *ti;
1384 |
1385 | /* first must be the keyword const */
1386 | ti=token_list;
1387 | if(strncmp(ti->str, "declare", 7)){
1388 | FPRINTF(stderrstderr, "ERROR: skipdeclare first token is not 'declare'\n");
1389 | Exit(10);
1390 | }
1391 | while(ti->str[0] != ';'){
1392 | ti=ti->next;
1393 | }
1394 | ti=ti->next;
1395 |
1396 | token_list=ti;
1397 | }
1398 |
1399 | /* this function will parse a
1400 | const
1401 | and generate the appropriate code
1402 | const must be followed by a suitable keyword [uint16|uint32|...]
1403 | the const will later be g_removed from the token list
1404 | the function assumes that the const is the first object in the token_list
1405 | */
1406 | static void parseconst(void)
1407 | {
1408 | token_item_t *ti;
1409 | char *name, *value;
1410 |
1411 | /* first must be the keyword const */
1412 | ti=token_list;
1413 | if(strncmp(ti->str, "const", 5)){
1414 | FPRINTF(stderrstderr, "ERROR: const first token is not 'const'\n");
1415 | Exit(10);
1416 | }
1417 | ti=ti->next;
1418 |
1419 | /* just skip second token */
1420 | ti=ti->next;
1421 |
1422 | /* third is a variable and not a type */
1423 | if(find_type(ti->str)){
1424 | FPRINTF(stderrstderr, "ERROR: const, not a variable name:%s\n", ti->str);
1425 | Exit(10);
1426 | }
1427 | name=ti->str;
1428 | ti=ti->next;
1429 |
1430 | /* fourth is '=' */
1431 | if(ti->str[0] != '='){
1432 | FPRINTF(stderrstderr, "ERROR: const fourth token is not '='\n");
1433 | Exit(10);
1434 | }
1435 | ti=ti->next;
1436 |
1437 | /* fifth is the value */
1438 | value=ti->str;
1439 | ti=ti->next;
1440 |
1441 | /* sixth is ';' */
1442 | if(ti->str[0] != ';'){
1443 | FPRINTF(stderrstderr, "ERROR: const sixth token is not ';'\n");
1444 | Exit(10);
1445 | }
1446 | ti=ti->next;
1447 |
1448 | FPRINTF(NULL((void*)0),"\nCONST:%s\n-------\n",name);
1449 |
1450 | FPRINTF(eth_hdr, "#define %s %s\n", name, value);
1451 |
1452 | FPRINTF(NULL((void*)0),"\n----------\nEND CONST:%s\n",name);
1453 |
1454 | token_list=ti;
1455 | }
1456 |
1457 | /* this function will parse a
1458 | typedef struct {
1459 | construct and generate the appropriate code.
1460 | the typedef will be g_removed from the token_list once it has been processed
1461 | the function assumes that the typedef is the first object in the token_list
1462 | the function will be called twice, once with pass=0 and once with pass=1
1463 | which controls whether subdissectors are to be generated or whether the
1464 | struct dissector itself is to be generated
1465 | */
1466 | static void parsetypedefstruct(int pass)
1467 | {
1468 | token_item_t *ti, *tmpti;
1469 | char *struct_name;
1470 | char dissectorname[DISSECTORNAME_MAXLEN256];
1471 | char tmpstr[BASE_BUFFER_SIZE256], *ptmpstr;
1472 | int level, num_pointers;
1473 | static int alignment;
1474 | type_item_t *type_item;
1475 | char hf_index[BASE_BUFFER_SIZE256];
1476 | bracket_item_t *bi=NULL((void*)0);
1477 | pointer_item_t *pi;
1478 | const char *pointer_type;
1479 | char *field_name;
1480 | uint32_t fixed_array_size;
1481 | int is_array_of_pointers;
1482 | int empty_struct = 0;
1483 |
1484 | ti=token_list;
1485 | if(g_strcmp0(ti->str, "typedef")){
1486 | FPRINTF(stderrstderr, "ERROR: typedefstruct first token is not 'typedef'\n");
1487 | Exit(10);
1488 | }
1489 | ti=ti->next;
1490 |
1491 | if(!g_strcmp0(ti->str, "[")){
1492 | ti=parsebrackets(ti, &bi);
1493 | }
1494 | /* check that we know how to handle the bracket thing */
1495 | if(bi){
1496 | if(bi->flags){
1497 | FPRINTF(stderrstderr, "ERROR: typedefstruct unknown bracket flags encountered : 0x%08x\n",bi->flags);
1498 | Exit(10);
1499 | }
1500 | }
1501 |
1502 | if(g_strcmp0(ti->str, "struct")){
1503 | FPRINTF(stderrstderr, "ERROR: typedefstruct second token is not 'struct'\n");
1504 | Exit(10);
1505 | }
1506 | ti=ti->next;
1507 |
1508 | if(g_strcmp0(ti->str, "{")){
1509 | FPRINTF(stderrstderr, "ERROR: typedefstruct third token is not '{'\n");
1510 | Exit(10);
1511 | }
1512 | ti=ti->next;
1513 |
1514 | /* Check if the struct is empty (search if there is no end bracket) */
1515 | if(g_strcmp0(ti->str, "}") == 0){
1516 | empty_struct = 1;
1517 | }
1518 |
1519 | /* search forward until the '}' so we can find the name of the struct */
1520 | for(tmpti=ti,level=0;tmpti;tmpti=tmpti->next){
1521 | if(!g_strcmp0(tmpti->str, "{")){
1522 | level++;
1523 | continue;
1524 | }
1525 | if(!g_strcmp0(tmpti->str, "}")){
1526 | if(!level){
1527 | break;
1528 | }
1529 | level--;
1530 | continue;
1531 | }
1532 | }
1533 | if(!tmpti || !tmpti->next){
1534 | FPRINTF(stderrstderr, "ERROR: typedefstruct missing matching '}'\n");
1535 | Exit(10);
1536 | }
1537 |
1538 | struct_name=tmpti->next->str;
1539 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, struct_name);
1540 |
1541 | FPRINTF(NULL((void*)0),"\nSTRUCT:%s pass:%d\n-------\n",struct_name,pass);
1542 |
1543 | if(!check_if_to_emit(dissectorname)){
1544 | FPRINTF(NULL((void*)0),"NOEMIT Skipping this struct dissector.\n");
1545 | ti=tmpti;
1546 | goto typedef_struct_finished;
1547 | }
1548 |
1549 | /* this is pass 0 so reset alignment to zero and update as items are
1550 | processed. we need alignment when pass 1 is run.
1551 | set alignment initially to 1 so we don't fail for empty structs
1552 | */
1553 | if(pass==0){
1554 | alignment=1;
1555 | }
1556 | /* pass 1 generate header for the struct dissector */
1557 | if(pass==1){
1558 | FPRINTF(eth_ett, "static int ett_%s_%s;\n", ifname, struct_name);
1559 | FPRINTF(eth_ettarr, " &ett_%s_%s,\n", ifname, struct_name);
1560 | FPRINTF(eth_hdr, "int %s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param);\n", dissectorname);
1561 | FPRINTF(eth_code, "\n");
1562 | FPRINTF(eth_code, "int\n");
1563 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo _U_, proto_tree *parent_tree, dcerpc_info *di _U_, uint8_t *drep _U_, int hf_index, uint32_t param _U_)\n", dissectorname);
1564 | FPRINTF(eth_code, "{\n");
1565 | FPRINTF(eth_code, " proto_item *item=NULL;\n");
1566 | if(!empty_struct){
1567 | FPRINTF(eth_code, " proto_tree *tree=NULL;\n");
1568 | }
1569 | FPRINTF(eth_code, " int old_offset;\n");
1570 | FPRINTF(eth_code, "\n");
1571 | switch(alignment){
1572 | case 1:
1573 | break;
1574 | case 2:
1575 | FPRINTF(eth_code, " ALIGN_TO_2_BYTES;\n");
1576 | FPRINTF(eth_code, "\n");
1577 | break;
1578 | case 4:
1579 | FPRINTF(eth_code, " ALIGN_TO_4_BYTES;\n");
1580 | FPRINTF(eth_code, "\n");
1581 | break;
1582 | case 8:
1583 | FPRINTF(eth_code, " ALIGN_TO_8_BYTES;\n");
1584 | FPRINTF(eth_code, "\n");
1585 | break;
1586 | default:
1587 | FPRINTF(stderrstderr, "ERROR: can not handle alignment:%d\n",alignment);
1588 | Exit(10);
1589 | }
1590 | FPRINTF(eth_code, " old_offset=offset;\n");
1591 | FPRINTF(eth_code, " if(parent_tree){\n");
1592 | FPRINTF(eth_code, " item=proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);\n");
1593 | if(!empty_struct){
1594 | FPRINTF(eth_code, " tree=proto_item_add_subtree(item, ett_%s_%s);\n", ifname, struct_name);
1595 | }
1596 | FPRINTF(eth_code, " }\n");
1597 | FPRINTF(eth_code, "\n");
1598 | }
1599 |
1600 | /* scan the struct and create all subdissectors */
1601 | level=0;
1602 | while(ti){
1603 | if(!g_strcmp0(ti->str, "{")){
1604 | level++;
1605 | ti=ti->next;
1606 | continue;
1607 | }
1608 | if(!g_strcmp0(ti->str, "}")){
1609 | if(!level){
1610 | break;
1611 | }
1612 | level--;
1613 | ti=ti->next;
1614 | continue;
1615 | }
1616 | if(!g_strcmp0(ti->str, "[")){
1617 | ti=parsebrackets(ti, &bi);
1618 | continue;
1619 | }
1620 |
1621 | /* check that we know how to handle the bracket thing */
1622 | if(bi){
1623 | if(bi->flags&(~(BI_SIZE_IS0x00000010|BI_LENGTH_IS0x00000020|BI_POINTER0x00000040))){
1624 | FPRINTF(stderrstderr, "ERROR: typedefstruct unknown bracket flags encountered : 0x%08x\n",bi->flags);
1625 | Exit(10);
1626 | }
1627 | }
1628 |
1629 | /* handle the type, verify that we KNOW this type */
1630 | type_item=find_type(ti->str);
1631 | if(!type_item){
1632 | FPRINTF(stderrstderr, "ERROR : typedefstruct unknown type %s\n",ti->str);
1633 | Exit(10);
1634 | }
1635 | ti=ti->next;
1636 | /* count the levels of pointers */
1637 | for(num_pointers=0;!g_strcmp0(ti->str, "*");ti=ti->next){
1638 | num_pointers++;
1639 | /* pointers are aligned at 4 byte boundaries */
1640 | if(alignment<4){
1641 | alignment=4;
1642 | }
1643 | }
1644 | /* now that we know how many real pointers there were we must
1645 | prepend default pointers to the list so it has the right
1646 | length.
1647 | */
1648 | pi=prepend_pointer_list(bi?bi->pointer_list:NULL((void*)0), num_pointers);
1649 | /* keep track of alignment */
1650 | if(alignment<type_item->alignment){
1651 | alignment=type_item->alignment;
1652 | }
1653 |
1654 | field_name=ti->str;
1655 | ti=ti->next;
1656 |
1657 | /* see if it is a fixed array */
1658 | fixed_array_size=0;
1659 | is_array_of_pointers=0;
1660 | if(!g_strcmp0(ti->str, "[")){
1661 | /* this might be a fixed array */
1662 | ti=ti->next;
1663 |
1664 | if(!g_strcmp0("]", ti->str)){
1665 | /* this is just a normal [] array */
1666 | fixed_array_size=0;
1667 | } else if(!g_strcmp0("*", ti->str)){
1668 | pi=prepend_pointer_list(pi, num_pointers+1);
1669 | fixed_array_size=0;
1670 | is_array_of_pointers=1;
1671 | ti=ti->next;
1672 | } else if (!ws_strtou32(ti->str, NULL((void*)0), &fixed_array_size)) {
1673 | FPRINTF(stderrstderr, "ERROR: invalid integer: %s\n", ti->str);
1674 | Exit(10);
1675 | } else {
1676 | ti=ti->next;
1677 | }
1678 |
1679 | if(g_strcmp0(ti->str, "]")){
1680 | FPRINTF(stderrstderr, "ERROR: typedefstruct fixed array does not end with ']' it ended with %s\n",ti->str);
1681 | Exit(10);
1682 | }
1683 | ti=ti->next;
1684 | }
1685 |
1686 | snprintf(hf_index, BASE_BUFFER_SIZE256, "hf_%s_%s_%s", ifname, struct_name, field_name);
1687 | /* pass 0 generate subdissectors */
1688 | if(pass==0){
1689 | char filter_name[BASE_BUFFER_SIZE256];
1690 | const char *hf;
1691 |
1692 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_dissect_%s_%s", ifname, struct_name, field_name);
1693 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1694 |
1695 | if(check_if_to_emit(tmpstr)){
1696 | snprintf(filter_name, BASE_BUFFER_SIZE256, "%s.%s.%s", ifname, struct_name, field_name);
1697 | hf=register_hf_field(hf_index, field_name, filter_name, type_item->ft_type, type_item->base_type, type_item->vals, type_item->mask, "");
1698 | FPRINTF(eth_code, "static unsigned\n");
1699 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", ptmpstr);
1700 | FPRINTF(eth_code, "{\n");
1701 | FPRINTF(eth_code, " uint32_t param=%s;\n",find_dissector_param_value(ptmpstr));
1702 | FPRINTF(eth_code, " offset=%s(tvb, offset, pinfo, tree, di, drep, %s, param);\n", type_item->dissector, hf);
1703 | FPRINTF(eth_code, " return offset;\n");
1704 | FPRINTF(eth_code, "}\n");
1705 | FPRINTF(eth_code, "\n");
1706 | } else {
1707 | FPRINTF(NULL((void*)0),"NOEMIT Skipping this struct item :%s\n",tmpstr);
1708 | }
1709 |
1710 | if(is_array_of_pointers){
1711 | pointer_type=pi->type;
1712 | pi=pi->next;
1713 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_%s", pointer_type, ptmpstr);
1714 | if(check_if_to_emit(tmpstr)){
1715 | FPRINTF(eth_code, "static unsigned\n");
1716 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", tmpstr);
1717 | FPRINTF(eth_code, "{\n");
1718 | FPRINTF(eth_code, " offset=dissect_ndr_embedded_pointer(tvb, offset, pinfo, tree, di, drep, %s, %s, \"%s\", -1);\n", ptmpstr, ptr_to_define(pointer_type), field_name);
1719 | FPRINTF(eth_code, " return offset;\n");
1720 | FPRINTF(eth_code, "}\n");
1721 | FPRINTF(eth_code, "\n");
1722 | } else {
1723 | FPRINTF(NULL((void*)0),"NOEMIT Skipping this struct item :%s\n",tmpstr);
1724 | }
1725 |
1726 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1727 | } else if(fixed_array_size){
1728 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "fixedarray_%s", ptmpstr);
1729 | if(check_if_to_emit(tmpstr)){
1730 | FPRINTF(eth_code, "static unsigned\n");
1731 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", tmpstr);
1732 | FPRINTF(eth_code, "{\n");
1733 | FPRINTF(eth_code, " int count=%d;\n",fixed_array_size);
1734 | FPRINTF(eth_code, " while(count--){\n");
1735 | FPRINTF(eth_code, " offset=%s(tvb, offset, pinfo, tree, di, drep);\n", ptmpstr);
1736 | FPRINTF(eth_code, " }\n");
1737 | FPRINTF(eth_code, "\n");
1738 | FPRINTF(eth_code, " return offset;\n");
1739 | FPRINTF(eth_code, "}\n");
1740 | FPRINTF(eth_code, "\n");
1741 | } else {
1742 | FPRINTF(NULL((void*)0),"NOEMIT Skipping this struct item :%s\n",tmpstr);
1743 | }
1744 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1745 | }
1746 |
1747 | /* handle switch_is */
1748 | if(bi){
1749 | switch(bi->flags&(BI_SIZE_IS0x00000010|BI_LENGTH_IS0x00000020)){
1750 | case 0:
1751 | break;
1752 | case BI_SIZE_IS0x00000010:
1753 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "ucarray_%s", ptmpstr);
1754 | if(check_if_to_emit(tmpstr)){
1755 | FPRINTF(eth_code, "static unsigned\n");
1756 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", tmpstr);
1757 | FPRINTF(eth_code, "{\n");
1758 | FPRINTF(eth_code, " offset=dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep, %s);\n", ptmpstr);
1759 | FPRINTF(eth_code, " return offset;\n");
1760 | FPRINTF(eth_code, "}\n");
1761 | FPRINTF(eth_code, "\n");
1762 | } else {
1763 | FPRINTF(NULL((void*)0),"NOEMIT Skipping this struct item :%s\n",tmpstr);
1764 | }
1765 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1766 | break;
1767 | case BI_LENGTH_IS0x00000020:
1768 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "uvarray_%s", ptmpstr);
1769 | if(check_if_to_emit(tmpstr)){
1770 | FPRINTF(eth_code, "static unsigned\n");
1771 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", tmpstr);
1772 | FPRINTF(eth_code, "{\n");
1773 | FPRINTF(eth_code, " offset=dissect_ndr_uvarray(tvb, offset, pinfo, tree, di, drep, %s);\n", ptmpstr);
1774 | FPRINTF(eth_code, " return offset;\n");
1775 | FPRINTF(eth_code, "}\n");
1776 | FPRINTF(eth_code, "\n");
1777 | } else {
1778 | FPRINTF(NULL((void*)0),"NOEMIT Skipping this struct item :%s\n",tmpstr);
1779 | }
1780 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1781 | break;
1782 | case BI_SIZE_IS0x00000010|BI_LENGTH_IS0x00000020:
1783 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "ucvarray_%s", ptmpstr);
1784 | if(check_if_to_emit(tmpstr)){
1785 | FPRINTF(eth_code, "static unsigned\n");
1786 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", tmpstr);
1787 | FPRINTF(eth_code, "{\n");
1788 | FPRINTF(eth_code, " offset=dissect_ndr_ucvarray(tvb, offset, pinfo, tree, di, drep, %s);\n", ptmpstr);
1789 | FPRINTF(eth_code, " return offset;\n");
1790 | FPRINTF(eth_code, "}\n");
1791 | FPRINTF(eth_code, "\n");
1792 | } else {
1793 | FPRINTF(NULL((void*)0),"NOEMIT Skipping this struct item :%s\n",tmpstr);
1794 | }
1795 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1796 | break;
1797 | default:
1798 | FPRINTF(stderrstderr, "ERROR: typedefstruct can not handle this combination of sizeis/lengthis\n");
1799 | Exit(10);
1800 | }
1801 | }
1802 |
1803 | /* handle pointers */
1804 | while(num_pointers--){
1805 | pointer_type=pi->type;
1806 | pi=pi->next;
1807 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_%s", pointer_type, ptmpstr);
1808 | if(check_if_to_emit(tmpstr)){
1809 | FPRINTF(eth_code, "static unsigned\n");
1810 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", tmpstr);
1811 | FPRINTF(eth_code, "{\n");
1812 | FPRINTF(eth_code, " offset=dissect_ndr_embedded_pointer(tvb, offset, pinfo, tree, di, drep, %s, %s, \"%s\", -1);\n", ptmpstr, ptr_to_define(pointer_type), field_name);
1813 | FPRINTF(eth_code, " return offset;\n");
1814 | FPRINTF(eth_code, "}\n");
1815 | FPRINTF(eth_code, "\n");
1816 | } else {
1817 | FPRINTF(NULL((void*)0),"NOEMIT Skipping this struct item :%s\n",tmpstr);
1818 | }
1819 |
1820 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1821 | }
1822 | }
1823 |
1824 | if(pass==1){
1825 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_dissect_%s_%s", ifname, struct_name, field_name);
1826 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1827 |
1828 | /* handle fixedsizearrays */
1829 | if(is_array_of_pointers){
1830 | pointer_type=pi->type;
1831 | pi=pi->next;
1832 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_%s", pointer_type, ptmpstr);
1833 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1834 | } else if(fixed_array_size){
1835 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "fixedarray_%s", ptmpstr);
1836 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1837 | }
1838 |
1839 | /* handle switch_is */
1840 | if(bi){
1841 | switch(bi->flags&(BI_SIZE_IS0x00000010|BI_LENGTH_IS0x00000020)){
1842 | case 0:
1843 | break;
1844 | case BI_SIZE_IS0x00000010:
1845 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "ucarray_%s", ptmpstr);
1846 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1847 | break;
1848 | case BI_LENGTH_IS0x00000020:
1849 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "uvarray_%s", ptmpstr);
1850 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1851 | break;
1852 | case BI_SIZE_IS0x00000010|BI_LENGTH_IS0x00000020:
1853 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "ucvarray_%s", ptmpstr);
1854 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1855 | break;
1856 | default:
1857 | FPRINTF(stderrstderr, "ERROR: typedefstruct can not handle this combination of sizeis/lengthis\n");
1858 | Exit(10);
1859 | }
1860 | }
1861 |
1862 | /* handle pointers */
1863 | while(num_pointers--){
1864 | pointer_type=pi->type;
1865 | pi=pi->next;
1866 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_%s", pointer_type, ptmpstr);
1867 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
1868 | }
1869 |
1870 | FPRINTF(eth_code, " offset=%s(tvb, offset, pinfo, tree, di, drep);\n", ptmpstr);
1871 | FPRINTF(eth_code, "\n");
1872 | }
1873 |
1874 | if(g_strcmp0(ti->str,";")){
1875 | FPRINTF(stderrstderr, "ERROR: field does not en with ';'\n");
1876 | Exit(10);
1877 | }
1878 | ti=ti->next;
1879 | bi=NULL((void*)0); /* clear bi before we start on the next field */
1880 | }
1881 |
1882 | if(pass==1){
1883 | FPRINTF(eth_code, " proto_item_set_len(item, offset-old_offset);\n");
1884 | FPRINTF(eth_code, "\n");
1885 | FPRINTF(eth_code, " return offset;\n");
1886 | FPRINTF(eth_code, "}\n");
1887 | register_new_type(struct_name, dissectorname, "FT_NONE", "BASE_NONE", "0", "NULL", alignment);
1888 | }
1889 |
1890 |
1891 | typedef_struct_finished:
1892 | FPRINTF(NULL((void*)0),"\nEND STRUCT:%s pass:%d\n-------\n",struct_name,pass);
1893 |
1894 | /* only advance token_list for pass==1
1895 | ti now points to the '}' token
1896 | */
1897 | if(pass==1){
1898 | if(!ti || g_strcmp0(ti->str,"}")){
1899 | FPRINTF(stderrstderr, "ERROR: struct does not end with '}'\n");
1900 | Exit(10);
1901 | }
1902 | ti=ti->next;
1903 |
1904 | /* just skip the name */
1905 | ti=ti->next;
1906 |
1907 | if(!ti || g_strcmp0(ti->str,";")){
1908 | FPRINTF(stderrstderr, "ERROR: struct does not end with ';'\n");
1909 | Exit(10);
1910 | }
1911 | ti=ti->next;
1912 |
1913 | token_list=ti;
1914 | }
1915 | }
1916 |
1917 | /* this function will parse a
1918 | typedef bitmap {
1919 | construct and generate the appropriate code.
1920 | the typedef will be g_removed from the token_list once it has been processed
1921 | the function assumes that the typedef is the first object in the token_list
1922 | the function will be called twice, once with pass=0 and once with pass=1
1923 | which controls whether subdissectors are to be generated or whether the
1924 | bitmap dissector itself is to be generated
1925 |
1926 | bitmaps are by default 32 bits
1927 | */
1928 | static void parsetypedefbitmap(int pass)
1929 | {
1930 | token_item_t *ti, *tmpti;
1931 | char *bitmap_name;
1932 | char dissectorname[BASE_BUFFER_SIZE256], hf_bitname[BASE_BUFFER_SIZE256];
1933 | int alignment;
1934 | unsigned int val;
1935 | char *name, *value;
1936 | bracket_item_t *bi=NULL((void*)0);
1937 |
1938 | ti=token_list;
1939 | if(g_strcmp0(ti->str, "typedef")){
1940 | FPRINTF(stderrstderr, "ERROR: typedefbitmap first token is not 'typedef'\n");
1941 | Exit(10);
1942 | }
1943 | ti=ti->next;
1944 |
1945 | alignment=4; /* default size is 32 bits */
1946 |
1947 | if(!g_strcmp0(ti->str, "[")){
1948 | ti=parsebrackets(ti, &bi);
1949 | }
1950 | /* check that we know how to handle the bracket thing */
1951 | if(bi){
1952 | if(bi->flags&(~(BI_BITMAP320x00000200|BI_BITMAP80x00000100))){
1953 | FPRINTF(stderrstderr, "ERROR: typedefbitmap unknown bracket flags encountered : 0x%08x\n",bi->flags);
1954 | Exit(10);
1955 | }
1956 | if(bi->flags&BI_BITMAP320x00000200){
1957 | alignment=4;
1958 | }
1959 | if(bi->flags&BI_BITMAP80x00000100){
1960 | alignment=1;
1961 | }
1962 | }
1963 |
1964 |
1965 | if(g_strcmp0(ti->str, "bitmap")){
1966 | FPRINTF(stderrstderr, "ERROR: typedefbitmap second token is not 'bitmap'\n");
1967 | Exit(10);
1968 | }
1969 | ti=ti->next;
1970 |
1971 | if(g_strcmp0(ti->str, "{")){
1972 | FPRINTF(stderrstderr, "ERROR: typedefbitmap third token is not '{'\n");
1973 | Exit(10);
1974 | }
1975 | ti=ti->next;
1976 |
1977 | /* search forward until the '}' so we can find the name of the bitmap */
1978 | for(tmpti=ti;tmpti;tmpti=tmpti->next){
1979 | if(!g_strcmp0(tmpti->str, "{")){
1980 | FPRINTF(stderrstderr, "ERROR: typedefbitmap '{' encountered inside bitmap\n");
1981 | Exit(10);
1982 | }
1983 | if(!g_strcmp0(tmpti->str, "}")){
1984 | break;
1985 | }
1986 | }
1987 | if (!tmpti || !tmpti->next){
1988 | FPRINTF(stderrstderr, "ERROR: typedefbitmap missing matching '}'\n");
1989 | Exit(10);
1990 | }
1991 | bitmap_name=tmpti->next->str;
1992 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, bitmap_name);
1993 |
1994 | FPRINTF(NULL((void*)0),"\nBITMAP:%s pass:%d\n-------\n",bitmap_name,pass);
1995 |
1996 | /* pass 1 generate header for the struct dissector */
1997 | if(pass==1){
1998 | FPRINTF(eth_ett, "static int ett_%s_%s;\n", ifname, bitmap_name);
1999 | FPRINTF(eth_ettarr, " &ett_%s_%s,\n", ifname, bitmap_name);
2000 | FPRINTF(eth_hdr, "int %s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param);\n", dissectorname);
2001 | FPRINTF(eth_code, "\n");
2002 | FPRINTF(eth_code, "int\n");
2003 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *parent_tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
2004 | FPRINTF(eth_code, "{\n");
2005 | FPRINTF(eth_code, " proto_item *item=NULL;\n");
2006 | FPRINTF(eth_code, " proto_tree *tree=NULL;\n");
2007 | switch(alignment){
2008 | case 1:
2009 | FPRINTF(eth_code, " uint8_t flags;\n");
2010 | FPRINTF(eth_code, "\n");
2011 | break;
2012 | case 4:
2013 | FPRINTF(eth_code, " uint32_t flags;\n");
2014 | FPRINTF(eth_code, "\n");
2015 | FPRINTF(eth_code, " ALIGN_TO_4_BYTES;\n");
2016 | break;
2017 | default:
2018 | FPRINTF(stderrstderr, "ERROR: typedefbitmap can not handle alignment:%d\n",alignment);
2019 | Exit(10);
2020 | }
2021 | FPRINTF(eth_code, "\n");
2022 | FPRINTF(eth_code, " if(parent_tree){\n");
2023 | FPRINTF(eth_code, " item=proto_tree_add_item(parent_tree, hf_index, tvb, offset, %d, ENC_LITTLE_ENDIAN);\n", alignment);
2024 | FPRINTF(eth_code, " tree=proto_item_add_subtree(item, ett_%s_%s);\n", ifname, bitmap_name);
2025 | FPRINTF(eth_code, " }\n");
2026 | FPRINTF(eth_code, "\n");
2027 | switch(alignment){
2028 | case 1:
2029 | FPRINTF(eth_code, " offset=dissect_ndr_uint8(tvb, offset, pinfo, NULL, di, drep, -1, &flags);\n");
2030 | FPRINTF(eth_code, "\n");
2031 | break;
2032 | case 4:
2033 | FPRINTF(eth_code, " offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep, -1, &flags);\n");
2034 | FPRINTF(eth_code, "\n");
2035 | break;
2036 | default:
2037 | FPRINTF(stderrstderr, "ERROR: typedefbitmap can not handle alignment:%d\n",alignment);
2038 | Exit(10);
2039 | }
2040 | FPRINTF(eth_code, "\n");
2041 | }
2042 |
2043 | /* scan the struct and create call for all bits */
2044 | while(ti){
2045 | if(!g_strcmp0(ti->str, "}")){
2046 | break;
2047 | }
2048 | if(!g_strcmp0(ti->str, "[")){
2049 | FPRINTF(stderrstderr, "ERROR: typedefbitmap can not handle '[' yet\n");
2050 | Exit(10);
2051 | }
2052 |
2053 | name=ti->str;
2054 | ti=ti->next;
2055 | snprintf(hf_bitname, BASE_BUFFER_SIZE256, "hf_%s_%s_%s", ifname, bitmap_name, name);
2056 |
2057 | if(g_strcmp0(ti->str, "=")){
2058 | FPRINTF(stderrstderr, "ERROR: typedefbitmap i expected a '=' here\n");
2059 | Exit(10);
2060 | }
2061 | ti=ti->next;
2062 |
2063 | value=ti->str;
2064 | ti=ti->next;
2065 | val=0;
2066 | if(!strncmp(value, "0x", 2)){
2067 | sscanf(value, "0x%x", &val);
2068 | } else {
2069 | FPRINTF(stderrstderr, "ERROR: typedefbitmap can only handle hexadecimal constants\n");
2070 | Exit(10);
2071 | }
2072 |
2073 | if((val == 0) || (val&(val-1))){
2074 | FPRINTF(stderrstderr, "ERROR: typedefbitmap can only handle single bit fields\n");
2075 | Exit(10);
2076 | }
2077 |
2078 | if(pass==0){
2079 | char filter_name[BASE_BUFFER_SIZE256], base_name[BASE_BUFFER_SIZE256], tfs_name[BASE_BUFFER_SIZE256];
2080 |
2081 | snprintf(filter_name, BASE_BUFFER_SIZE256, "%s.%s.%s", ifname, bitmap_name, name);
2082 | snprintf(base_name, BASE_BUFFER_SIZE256, "%d", alignment*8);
2083 | snprintf(tfs_name, BASE_BUFFER_SIZE256, "TFS(&%s_tfs)", name);
2084 | register_hf_field(hf_bitname, name, filter_name, "FT_BOOLEAN", base_name, tfs_name, value, "");
2085 |
2086 | FPRINTF(eth_code, "static const true_false_string %s_tfs = {\n",name);
2087 | FPRINTF(eth_code, " \"%s is SET\",\n", name);
2088 | FPRINTF(eth_code, " \"%s is NOT set\"\n", name);
2089 | FPRINTF(eth_code, "};\n");
2090 | FPRINTF(eth_code, "\n");
2091 | }
2092 |
2093 | if(pass==1){
2094 | FPRINTF(eth_code, " proto_tree_add_boolean(tree, %s, tvb, offset-%d, %d, flags);\n", hf_bitname, alignment, alignment);
2095 | FPRINTF(eth_code, " if(flags&%s){\n", value);
2096 | FPRINTF(eth_code, " proto_item_append_text(item, \" %s\");\n", name);
2097 | FPRINTF(eth_code, " }\n");
2098 | FPRINTF(eth_code, " flags&=(~%s);\n", value);
2099 | FPRINTF(eth_code, "\n");
2100 | }
2101 |
2102 | if(!g_strcmp0(ti->str, ",")){
2103 | ti=ti->next;
2104 | continue;
2105 | }
2106 | }
2107 |
2108 | if(pass==1){
2109 | FPRINTF(eth_code, " if(flags){\n");
2110 | FPRINTF(eth_code, " proto_item_append_text(item, \"UNKNOWN-FLAGS\");\n");
2111 | FPRINTF(eth_code, " }\n");
2112 | FPRINTF(eth_code, "\n");
2113 | FPRINTF(eth_code, " return offset;\n");
2114 | FPRINTF(eth_code, "}\n");
2115 | switch(alignment){
2116 | case 1:
2117 | register_new_type(bitmap_name, dissectorname, "FT_UINT8", "BASE_HEX", "0", "NULL", alignment);
2118 | break;
2119 | case 4:
2120 | register_new_type(bitmap_name, dissectorname, "FT_UINT32", "BASE_HEX", "0", "NULL", alignment);
2121 | break;
2122 | default:
2123 | FPRINTF(stderrstderr, "ERROR: typedefbitmap can not handle alignment:%d\n",alignment);
2124 | Exit(10);
2125 | }
2126 | }
2127 |
2128 | FPRINTF(NULL((void*)0),"\nEND BITMAP:%s pass:%d\n-------\n",bitmap_name,pass);
2129 |
2130 | /* only advance token_list for pass==1
2131 | ti now points to the '}' token
2132 | */
2133 | if(pass==1){
2134 | if(!ti || g_strcmp0(ti->str,"}")){
2135 | FPRINTF(stderrstderr, "ERROR: bitmap does not end with '}'\n");
2136 | Exit(10);
2137 | }
2138 | ti=ti->next;
2139 |
2140 | /* just skip the name */
2141 | ti=ti->next;
2142 |
2143 | if(!ti || g_strcmp0(ti->str,";")){
2144 | FPRINTF(stderrstderr, "ERROR: bitmap does not end with ';'\n");
2145 | Exit(10);
2146 | }
2147 | ti=ti->next;
2148 |
2149 | token_list=ti;
2150 | }
2151 | }
2152 |
2153 | /* a case tag might be a negative number, i.e. contain a '-' sign which
2154 | is not valid inside a symbol name in c.
2155 | */
2156 | static const char *
2157 | case2str(const char *str)
2158 | {
2159 | char *newstr;
2160 | if(str[0]!='-'){
2161 | return str;
2162 | }
2163 | newstr=g_strdup(str)g_strdup_inline (str);
2164 | newstr[0]='m';
2165 | return newstr;
2166 | }
2167 |
2168 | /* this function will parse a
2169 | typedef union {
2170 | construct and generate the appropriate code.
2171 | the typedef will be g_removed from the token_list once it has been processed
2172 | the function assumes that the typedef is the first object in the token_list
2173 | the function will be called twice, once with pass=0 and once with pass=1
2174 | which controls whether subdissectors are to be generated or whether the
2175 | union dissector itself is to be generated
2176 | */
2177 | static void parsetypedefunion(int pass)
2178 | {
2179 | char *union_name;
2180 | token_item_t *ti, *tmpti;
2181 | char dissectorname[BASE_BUFFER_SIZE256];
2182 | bracket_item_t *bi=NULL((void*)0);
2183 | char tmpstr[BASE_BUFFER_SIZE256], *ptmpstr;
2184 | int level, num_pointers;
2185 | static int alignment;
2186 | type_item_t *type_item;
2187 | char hf_index[BASE_BUFFER_SIZE256];
2188 | int tag_alignment, item_alignment;
2189 |
2190 | ti=token_list;
2191 | if(g_strcmp0(ti->str, "typedef")){
2192 | FPRINTF(stderrstderr, "ERROR: typedefunion first token is not 'typedef'\n");
2193 | Exit(10);
2194 | }
2195 | ti=ti->next;
2196 |
2197 | if(!g_strcmp0(ti->str, "[")){
2198 | ti=parsebrackets(ti, &bi);
2199 | }
2200 | /* check that we know how to handle the bracket thing */
2201 | if(bi){
2202 | if(bi->flags&(~(BI_SWITCH_TYPE0x00000400))){
2203 | FPRINTF(stderrstderr, "ERROR: typedefunion unknown bracket flags encountered : 0x%08x\n",bi->flags);
2204 | Exit(10);
2205 | }
2206 | }
2207 |
2208 | if(g_strcmp0(ti->str, "union")){
2209 | FPRINTF(stderrstderr, "ERROR: typedefunion second token is not 'union'\n");
2210 | Exit(10);
2211 | }
2212 | ti=ti->next;
2213 |
2214 | if(g_strcmp0(ti->str, "{")){
2215 | FPRINTF(stderrstderr, "ERROR: typedefunion third token is not '{'\n");
2216 | Exit(10);
2217 | }
2218 | ti=ti->next;
2219 |
2220 | /* search forward until the '}' so we can find the name of the union */
2221 | for(tmpti=ti,level=0;tmpti;tmpti=tmpti->next){
2222 | if(!g_strcmp0(tmpti->str, "{")){
2223 | level++;
2224 | continue;
2225 | }
2226 | if(!g_strcmp0(tmpti->str, "}")){
2227 | if(!level){
2228 | break;
2229 | }
2230 | level--;
2231 | continue;
2232 | }
2233 | }
2234 |
2235 | if (!tmpti || !tmpti->next){
2236 | FPRINTF(stderrstderr, "ERROR: typedefunion missing matching '}'\n");
2237 | Exit(10);
2238 | }
2239 | union_name=tmpti->next->str;
2240 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_union_%s", ifname, union_name);
2241 |
2242 | FPRINTF(NULL((void*)0),"\nUNION:%s pass:%d\n-------\n",union_name,pass);
2243 |
2244 | if(bi && bi->flags&BI_SWITCH_TYPE0x00000400){
2245 | tag_alignment=bi->union_tag_size;
2246 | } else {
2247 | tag_alignment=get_union_tag_size(union_name);
2248 | }
2249 |
2250 | /* this is pass 0 so reset alignment to the minimum possible value
2251 | and update as items are processed.
2252 | we need alignment when pass 1 is run
2253 | */
2254 | if(pass==0){
2255 | alignment=tag_alignment;
2256 | }
2257 |
2258 | /* pass 1 generate header for the struct dissector */
2259 | if(pass==1){
2260 | FPRINTF(eth_ett, "static int ett_%s_%s;\n", ifname, union_name);
2261 | FPRINTF(eth_ettarr, " &ett_%s_%s,\n", ifname, union_name);
2262 | FPRINTF(eth_code, "\n");
2263 | FPRINTF(eth_code, "static unsigned\n");
2264 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *parent_tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
2265 | FPRINTF(eth_code, "{\n");
2266 | FPRINTF(eth_code, " proto_item *item=NULL;\n");
2267 | FPRINTF(eth_code, " proto_tree *tree=NULL;\n");
2268 | FPRINTF(eth_code, " int old_offset;\n");
2269 | /* we do alignment on the tag itself here so that
2270 | we skip any alignment padding prior to where the tag
2271 | itself starts, this makes the byterange in the hexpane
2272 | for the union expansion start with the first byte of the tag
2273 | */
2274 | switch(tag_alignment){
2275 | case 1:
2276 | break;
2277 | case 2:
2278 | FPRINTF(eth_code, " uint16_t level;\n");
2279 | FPRINTF(eth_code, "\n");
2280 | FPRINTF(eth_code, " ALIGN_TO_2_BYTES;\n");
2281 | FPRINTF(eth_code, "\n");
2282 | break;
2283 | case 4:
2284 | FPRINTF(eth_code, " uint32_t level = 0;\n");
2285 | FPRINTF(eth_code, "\n");
2286 | FPRINTF(eth_code, " ALIGN_TO_4_BYTES;\n");
2287 | FPRINTF(eth_code, "\n");
2288 | break;
2289 | default:
2290 | FPRINTF(stderrstderr, "ERROR: typedefunion 1 can not handle alignment:%d\n",alignment);
2291 | Exit(10);
2292 | }
2293 | FPRINTF(eth_code, " old_offset=offset;\n");
2294 | FPRINTF(eth_code, " if(parent_tree){\n");
2295 | FPRINTF(eth_code, " tree=proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_%s_%s, &item, \"%s\");\n", ifname, union_name, union_name);
2296 | FPRINTF(eth_code, " }\n");
2297 | FPRINTF(eth_code, "\n");
2298 | switch(tag_alignment){
2299 | case 1:
2300 | break;
2301 | case 2:
2302 | FPRINTF(eth_code, " offset=dissect_ndr_uint16(tvb, offset, pinfo, tree,\n");
2303 | FPRINTF(eth_code, " di, drep, hf_index, &level);\n");
2304 | break;
2305 | case 4:
2306 | FPRINTF(eth_code, " offset=dissect_ndr_uint32(tvb, offset, pinfo, tree,\n");
2307 | FPRINTF(eth_code, " di, drep, hf_index, &level);\n");
2308 | break;
2309 | default:
2310 | FPRINTF(stderrstderr, "ERROR: typedefunion 2 can not handle alignment:%d\n",alignment);
2311 | Exit(10);
2312 | }
2313 | FPRINTF(eth_code, "\n");
2314 | FPRINTF(eth_code, " switch(level){\n");
2315 | }
2316 |
2317 | /* scan the struct and create all subdissectors */
2318 | level=0;
2319 | while(ti){
2320 | if(!g_strcmp0(ti->str, "{")){
2321 | ti=ti->next;
2322 | level++;
2323 | continue;
2324 | }
2325 | if(!g_strcmp0(ti->str, "}")){
2326 | if(!level){
2327 | break;
2328 | }
2329 | ti=ti->next;
2330 | level--;
2331 | continue;
2332 | }
2333 | if(!g_strcmp0(ti->str, "[")){
2334 | ti=parsebrackets(ti, &bi);
2335 | continue;
2336 | }
2337 |
2338 | if(!bi){
2339 | FPRINTF(stderrstderr, "ERROR : typedefunion no brackets found for case\n");
2340 | Exit(10);
2341 | }
2342 | /* make sure we catch when we havent implemented everything
2343 | yet.
2344 | we currently only know about CASE and CASE_DEFAULT flags
2345 | */
2346 | if(bi->flags&(~(BI_CASE0x00000001|BI_CASE_DEFAULT0x00000002|BI_POINTER0x00000040))){
2347 | FPRINTF(stderrstderr, "ERROR: typedefunion unknown bracket flags encountered : 0x%08x\n",bi->flags);
2348 | Exit(10);
2349 | }
2350 | if(!(bi->flags&BI_CASE0x00000001)){
2351 | FPRINTF(stderrstderr, "ERROR : typedefunion no case found in brackets\n");
2352 | Exit(10);
2353 | }
2354 | #ifdef g_removeD
2355 | /* only empty default cases for now */
2356 | if(bi->flags&BI_CASE_DEFAULT0x00000002){
2357 | if(g_strcmp0(ti->str,";")){
2358 | FPRINTF(stderrstderr, "ERROR: default tag is not empty\n");
2359 | Exit(10);
2360 | }
2361 | ti=ti->next;
2362 | continue;
2363 | }
2364 | #endif
2365 |
2366 | /* just skip all and any 'empty' arms */
2367 | if(!g_strcmp0(ti->str, ";")){
2368 | ti=ti->next;
2369 | continue;
2370 | }
2371 |
2372 | /* handle the type, verify that we KNOW this type */
2373 | type_item=find_type(ti->str);
2374 | if(!type_item){
2375 | FPRINTF(stderrstderr, "ERROR : typedefunion unknown type %s\n",ti->str);
2376 | Exit(10);
2377 | }
2378 | ti=ti->next;
2379 | /* count the levels of pointers */
2380 | for(num_pointers=0;!g_strcmp0(ti->str, "*");ti=ti->next){
2381 | num_pointers++;
2382 | }
2383 |
2384 | /* keep track of alignment */
2385 | if(num_pointers){
2386 | item_alignment=4;
2387 | } else {
2388 | item_alignment=type_item->alignment;
2389 | }
2390 | if(alignment<item_alignment){
2391 | alignment=item_alignment;
2392 | }
2393 |
2394 | snprintf(hf_index, BASE_BUFFER_SIZE256, "hf_%s_%s_%s_%s", ifname, union_name, case2str(bi->case_name), ti->str);
2395 | /* pass 0 generate subdissectors */
2396 | if(pass==0){
2397 | char filter_name[BASE_BUFFER_SIZE256];
2398 | const char *hf;
2399 |
2400 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_dissect_union_%s_%s_%s", ifname, union_name, case2str(bi->case_name), ti->str);
2401 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
2402 |
2403 | snprintf(filter_name, BASE_BUFFER_SIZE256, "%s.%s.%s", ifname, union_name, ti->str);
2404 | hf=register_hf_field(hf_index, ti->str, filter_name, type_item->ft_type, type_item->base_type, type_item->vals, type_item->mask, "");
2405 |
2406 | FPRINTF(eth_code, "static unsigned\n");
2407 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", ptmpstr);
2408 | FPRINTF(eth_code, "{\n");
2409 | FPRINTF(eth_code, " uint32_t param=%s;\n",find_dissector_param_value(ptmpstr));
2410 | FPRINTF(eth_code, " offset=%s(tvb, offset, pinfo, tree, di, drep, %s, param);\n", type_item->dissector, hf);
2411 | FPRINTF(eth_code, " return offset;\n");
2412 | FPRINTF(eth_code, "}\n");
2413 | FPRINTF(eth_code, "\n");
2414 |
2415 | /* handle pointers */
2416 | while(num_pointers--){
2417 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_%s", ptmpstr, "unique");
2418 | FPRINTF(eth_code, "static unsigned\n");
2419 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", tmpstr);
2420 | FPRINTF(eth_code, "{\n");
2421 | FPRINTF(eth_code, " offset=dissect_ndr_embedded_pointer(tvb, offset, pinfo, tree, di, drep, %s, NDR_POINTER_UNIQUE, \"%s\", -1);\n", ptmpstr, ti->str);
2422 | FPRINTF(eth_code, " return offset;\n");
2423 | FPRINTF(eth_code, "}\n");
2424 | FPRINTF(eth_code, "\n");
2425 |
2426 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
2427 |
2428 | }
2429 | }
2430 |
2431 | if(pass==1){
2432 | /* handle pointers */
2433 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_dissect_union_%s_%s_%s", ifname, union_name, case2str(bi->case_name), ti->str);
2434 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
2435 | while(num_pointers--){
2436 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_%s", ptmpstr, "unique");
2437 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
2438 | }
2439 |
2440 | if(bi->flags&BI_CASE_DEFAULT0x00000002){
2441 | FPRINTF(eth_code, " default:\n");
2442 | } else {
2443 | FPRINTF(eth_code, " case %s:\n",bi->case_name);
2444 | }
2445 | /* each arm itself is aligned independently */
2446 | switch(item_alignment){
2447 | case 1:
2448 | break;
2449 | case 2:
2450 | FPRINTF(eth_code, " ALIGN_TO_2_BYTES;\n");
2451 | break;
2452 | case 4:
2453 | FPRINTF(eth_code, " ALIGN_TO_4_BYTES;\n");
2454 | break;
2455 | case 8:
2456 | FPRINTF(eth_code, " ALIGN_TO_8_BYTES;\n");
2457 | break;
2458 | default:
2459 | FPRINTF(stderrstderr, "ERROR: typedefunion 3 can not handle alignment:%d\n",item_alignment);
2460 | Exit(10);
2461 | }
2462 | FPRINTF(eth_code, " offset=%s(tvb, offset, pinfo, tree, di, drep);\n", ptmpstr);
2463 | FPRINTF(eth_code, " break;\n");
2464 | FPRINTF(eth_code, "\n");
2465 | }
2466 | ti=ti->next;
2467 |
2468 | if(g_strcmp0(ti->str,";")){
2469 | FPRINTF(stderrstderr, "ERROR: field does not end with ';'\n");
2470 | Exit(10);
2471 | }
2472 | ti=ti->next;
2473 | }
2474 |
2475 | if(pass==1){
2476 | FPRINTF(eth_code, " }\n");
2477 | FPRINTF(eth_code, "\n");
2478 | FPRINTF(eth_code, " proto_item_set_len(item, offset-old_offset);\n");
2479 | FPRINTF(eth_code, "\n");
2480 | FPRINTF(eth_code, " return offset;\n");
2481 | FPRINTF(eth_code, "}\n");
2482 | switch(tag_alignment){
2483 | case 2:
2484 | register_new_type(union_name, dissectorname, "FT_UINT16", "BASE_DEC", "0", "NULL", alignment);
2485 | break;
2486 | case 4:
2487 | register_new_type(union_name, dissectorname, "FT_UINT32", "BASE_DEC", "0", "NULL", alignment);
2488 | break;
2489 | default:
2490 | FPRINTF(stderrstderr, "ERROR: typedefunion 4 can not handle alignment:%d\n",alignment);
2491 | Exit(10);
2492 | }
2493 | }
2494 |
2495 | FPRINTF(NULL((void*)0),"\nEND UNION:%s pass:%d\n-------\n",union_name,pass);
2496 |
2497 | /* only advance token_list for pass==1
2498 | ti now points to the '}' token
2499 | */
2500 | if(pass==1){
2501 | if(!ti || g_strcmp0(ti->str,"}")){
2502 | FPRINTF(stderrstderr, "ERROR: union does not end with '}'\n");
2503 | Exit(10);
2504 | }
2505 | ti=ti->next;
2506 |
2507 | /* just skip the name */
2508 | ti=ti->next;
2509 |
2510 | if(!ti || g_strcmp0(ti->str,";")){
2511 | FPRINTF(stderrstderr, "ERROR: union does not end with ';'\n");
2512 | Exit(10);
2513 | }
2514 | ti=ti->next;
2515 |
2516 | token_list=ti;
2517 | }
2518 | }
2519 |
2520 |
2521 | /* this function will parse a
2522 | WERROR function (
2523 | construct and generate the appropriate code.
2524 | the function will be g_removed from the token_list once it has been processed
2525 | the function assumes that the function is the first object in the token_list
2526 | the function will be called three times with
2527 | pass=0 generate subdissectors and entries for the function table
2528 | pass=1 generate code for the REQUEST
2529 | pass=2 generate code for the REPLY
2530 | */
2531 | static void parsefunction(int pass)
2532 | {
2533 | char *function_name;
2534 | static int funcno=0;
2535 | token_item_t *ti;
2536 | bracket_item_t *bi=NULL((void*)0);
2537 | pointer_item_t *pi;
2538 | const char *pointer_type;
2539 |
2540 | char tmpstr[BASE_BUFFER_SIZE256], *ptmpstr;
2541 | int level, num_pointers;
2542 | type_item_t *type_item;
2543 | char hf_index[BASE_BUFFER_SIZE256];
2544 |
2545 | ti=token_list;
2546 | if(g_strcmp0(ti->str, "WERROR")){
2547 | FPRINTF(stderrstderr, "ERROR: function first token is not 'WERROR'\n");
2548 | Exit(10);
2549 | }
2550 | ti=ti->next;
2551 |
2552 | function_name=ti->str;
2553 | ti=ti->next;
2554 |
2555 | if(g_strcmp0(ti->str, "(")){
2556 | FPRINTF(stderrstderr, "ERROR: function third token is not '('\n");
2557 | Exit(10);
2558 | }
2559 | ti=ti->next;
2560 |
2561 | FPRINTF(NULL((void*)0),"\nFUNCTION:%s pass:%d\n-------\n",function_name,pass);
2562 |
2563 | if(pass==0){
2564 | FPRINTF(eth_ft, " { %d, \"%s\",\n",funcno,function_name);
2565 | FPRINTF(eth_ft, " %s_dissect_%s_request,\n", ifname, function_name);
2566 | FPRINTF(eth_ft, " %s_dissect_%s_response },\n", ifname, function_name);
2567 | funcno++;
2568 | }
2569 |
2570 | /* pass 1,2 generate header for the function dissector */
2571 | if((pass==1)||(pass==2)){
2572 | FPRINTF(eth_code, "\n");
2573 | FPRINTF(eth_code, "static unsigned\n");
2574 | FPRINTF(eth_code, "%s_dissect_%s_%s(tvbuff_t *tvb _U_, unsigned offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)\n", ifname, function_name, (pass==1)?"request":"response");
2575 | FPRINTF(eth_code, "{\n");
2576 | }
2577 |
2578 | /* scan the struct and create all subdissectors */
2579 | level=0;
2580 | while(ti){
2581 | if(!g_strcmp0(ti->str, "(")){
2582 | ti=ti->next;
2583 | level++;
2584 | continue;
2585 | }
2586 | if(!g_strcmp0(ti->str, ")")){
2587 | if(!level){
2588 | break;
2589 | }
2590 | ti=ti->next;
2591 | level--;
2592 | continue;
2593 | }
2594 | if(!g_strcmp0(ti->str, "[")){
2595 | ti=parsebrackets(ti, &bi);
2596 | continue;
2597 | }
2598 |
2599 | if(!bi){
2600 | FPRINTF(stderrstderr, "ERROR : function no brackets found for case\n");
2601 | Exit(10);
2602 | }
2603 |
2604 | /* make sure we catch when we havent implemented everything
2605 | yet.
2606 | we currently only know about IN and OUT flags
2607 | */
2608 | if(bi->flags&(~(BI_IN0x00000004|BI_OUT0x00000008|BI_POINTER0x00000040|BI_SIZE_IS0x00000010|BI_LENGTH_IS0x00000020))){
2609 | FPRINTF(stderrstderr, "ERROR: function unknown bracket flags encountered : 0x%08x\n",bi->flags);
2610 | Exit(10);
2611 | }
2612 | if(!(bi->flags&(BI_IN0x00000004|BI_OUT0x00000008))){
2613 | FPRINTF(stderrstderr, "ERROR : function parameter is neither in nor out\n");
2614 | Exit(10);
2615 | }
2616 |
2617 | /* handle the type, verify that we KNOW this type */
2618 | type_item=find_type(ti->str);
2619 | if(!type_item){
2620 | FPRINTF(stderrstderr, "ERROR : function unknown type %s\n",ti->str);
2621 | Exit(10);
2622 | }
2623 | ti=ti->next;
2624 | /* count the levels of pointers */
2625 | for(num_pointers=0;!g_strcmp0(ti->str, "*");ti=ti->next){
2626 | num_pointers++;
2627 | }
2628 |
2629 | /* now that we know how many real pointer there were we must
2630 | prepend default pointers to the list so it has the right
2631 | length.
2632 | */
2633 | pi=prepend_pointer_list(bi->pointer_list, num_pointers);
2634 |
2635 | snprintf(hf_index, BASE_BUFFER_SIZE256, "hf_%s_%s_%s", ifname, function_name, ti->str);
2636 | /* pass 0 generate subdissectors */
2637 | if(pass==0){
2638 | char filter_name[BASE_BUFFER_SIZE256];
2639 | const char *hf;
2640 |
2641 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_dissect_%s_%s", ifname, function_name, ti->str);
2642 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
2643 |
2644 | snprintf(filter_name, BASE_BUFFER_SIZE256, "%s.%s.%s", ifname, function_name, ti->str);
2645 | hf=register_hf_field(hf_index, ti->str, filter_name, type_item->ft_type, type_item->base_type, type_item->vals, type_item->mask, "");
2646 |
2647 | FPRINTF(eth_code, "static unsigned\n");
2648 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", ptmpstr);
2649 | FPRINTF(eth_code, "{\n");
2650 | FPRINTF(eth_code, " uint32_t param=%s;\n",find_dissector_param_value(ptmpstr));
2651 | FPRINTF(eth_code, " offset=%s(tvb, offset, pinfo, tree, di, drep, %s, param);\n", type_item->dissector, hf);
2652 | FPRINTF(eth_code, " return offset;\n");
2653 | FPRINTF(eth_code, "}\n");
2654 | FPRINTF(eth_code, "\n");
2655 |
2656 |
2657 | /* handle switch_is */
2658 | switch(bi->flags&(BI_SIZE_IS0x00000010|BI_LENGTH_IS0x00000020)){
2659 | case 0:
2660 | break;
2661 | case BI_SIZE_IS0x00000010|BI_LENGTH_IS0x00000020:
2662 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "ucvarray_%s", ptmpstr);
2663 | FPRINTF(eth_code, "static unsigned\n");
2664 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", tmpstr);
2665 | FPRINTF(eth_code, "{\n");
2666 | FPRINTF(eth_code, " offset=dissect_ndr_ucvarray(tvb, offset, pinfo, tree, di, drep, %s);\n", ptmpstr);
2667 | FPRINTF(eth_code, " return offset;\n");
2668 | FPRINTF(eth_code, "}\n");
2669 | FPRINTF(eth_code, "\n");
2670 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
2671 | break;
2672 | case BI_SIZE_IS0x00000010:
2673 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "ucarray_%s", ptmpstr);
2674 | FPRINTF(eth_code, "static unsigned\n");
2675 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", tmpstr);
2676 | FPRINTF(eth_code, "{\n");
2677 | FPRINTF(eth_code, " offset=dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep, %s);\n", ptmpstr);
2678 | FPRINTF(eth_code, " return offset;\n");
2679 | FPRINTF(eth_code, "}\n");
2680 | FPRINTF(eth_code, "\n");
2681 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
2682 | break;
2683 | default:
2684 | FPRINTF(stderrstderr, "ERROR: typedeffunction can not handle this combination of sizeis/lengthis\n");
2685 | Exit(10);
2686 | }
2687 |
2688 | /* handle pointers */
2689 | while(num_pointers--){
2690 | pointer_type=pi->type;
2691 | pi=pi->next;
2692 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_%s", pointer_type, ptmpstr);
2693 | FPRINTF(eth_code, "static unsigned\n");
2694 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)\n", tmpstr);
2695 | FPRINTF(eth_code, "{\n");
2696 | FPRINTF(eth_code, " offset=dissect_ndr_toplevel_pointer(tvb, offset, pinfo, tree, di, drep, %s, %s, \"%s\", -1);\n", ptmpstr, ptr_to_define(pointer_type), ti->str);
2697 | FPRINTF(eth_code, " return offset;\n");
2698 | FPRINTF(eth_code, "}\n");
2699 | FPRINTF(eth_code, "\n");
2700 |
2701 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
2702 |
2703 | }
2704 | }
2705 |
2706 | if((pass==1)||(pass==2)){
2707 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_dissect_%s_%s", ifname, function_name, ti->str);
2708 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
2709 |
2710 | switch(bi->flags&(BI_SIZE_IS0x00000010|BI_LENGTH_IS0x00000020)){
2711 | case 0:
2712 | break;
2713 | case BI_SIZE_IS0x00000010|BI_LENGTH_IS0x00000020:
2714 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "ucvarray_%s", ptmpstr);
2715 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
2716 | break;
2717 | case BI_SIZE_IS0x00000010:
2718 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "ucarray_%s", ptmpstr);
2719 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
2720 | break;
2721 | default:
2722 | FPRINTF(stderrstderr, "ERROR: typedeffunction can not handle this combination of sizeis/lengthis\n");
2723 | Exit(10);
2724 | }
2725 |
2726 | /* handle pointers */
2727 | while(num_pointers--){
2728 | pointer_type=pi->type;
2729 | pi=pi->next;
2730 | snprintf(tmpstr, BASE_BUFFER_SIZE256, "%s_%s", pointer_type, ptmpstr);
2731 | ptmpstr=g_strdup(tmpstr)g_strdup_inline (tmpstr);
2732 | }
2733 |
2734 | if((pass==1)&&(bi->flags&BI_IN0x00000004)){
2735 | FPRINTF(eth_code, " offset=%s(tvb, offset, pinfo, tree, di, drep);\n", ptmpstr);
2736 | FPRINTF(eth_code, " offset=dissect_deferred_pointers(pinfo, tvb, offset, di, drep);\n");
2737 | FPRINTF(eth_code, "\n");
2738 | }
2739 | if((pass==2)&&(bi->flags&BI_OUT0x00000008)){
2740 | FPRINTF(eth_code, " offset=%s(tvb, offset, pinfo, tree, di, drep);\n", ptmpstr);
2741 | FPRINTF(eth_code, " offset=dissect_deferred_pointers(pinfo, tvb, offset, di, drep);\n");
2742 | FPRINTF(eth_code, "\n");
2743 | }
2744 | }
2745 | ti=ti->next;
2746 |
2747 |
2748 | if(!g_strcmp0(ti->str,",")){
2749 | ti=ti->next;
2750 | continue;
2751 | }
2752 | }
2753 |
2754 | if((pass==1)||(pass==2)){
2755 | if(pass==2){
2756 | FPRINTF(eth_code, " offset=dissect_ntstatus(tvb, offset, pinfo, tree, di, drep, %s, NULL);\n", hf_status);
2757 | FPRINTF(eth_code, "\n");
2758 | }
2759 | FPRINTF(eth_code, "\n");
2760 | FPRINTF(eth_code, " return offset;\n");
2761 | FPRINTF(eth_code, "}\n");
2762 | }
2763 |
2764 | FPRINTF(NULL((void*)0),"\nEND FUNCTION:%s pass:%d\n-------\n",function_name,pass);
2765 |
2766 | /* only advance token_list for pass==2
2767 | ti now points to the ')' token
2768 | */
2769 | if(pass==2){
2770 | if(!ti || g_strcmp0(ti->str,")")){
2771 | FPRINTF(stderrstderr, "ERROR: function does not end with ')'\n");
2772 | Exit(10);
2773 | }
2774 | ti=ti->next;
2775 |
2776 | if(!ti || g_strcmp0(ti->str,";")){
2777 | FPRINTF(stderrstderr, "ERROR: function does not end with ';'\n");
2778 | Exit(10);
2779 | }
2780 | ti=ti->next;
2781 |
2782 | token_list=ti;
2783 | }
2784 | }
2785 |
2786 |
2787 | /* this function will parse a
2788 | typedef enum {
2789 | or a
2790 | typedef [ v1_enum ] enum {
2791 | construct and generate the appropriate code.
2792 | the typedef will be g_removed from the token_list once it has been processed
2793 | the function assumes that the typedef is the first object in the token_list
2794 | */
2795 | static void parsetypedefenum(void)
2796 | {
2797 | token_item_t *ti;
2798 | enum_list_t *enum_list, *el, *lastel;
2799 | char *p;
2800 | long val;
2801 | int eval, enumsize;
2802 | char dissectorname[BASE_BUFFER_SIZE256], valsstring[BASE_BUFFER_SIZE256];
2803 | char *hfvalsstring;
2804 |
2805 | enumsize=16;
2806 |
2807 | ti=token_list;
2808 | if(g_strcmp0(ti->str, "typedef")){
2809 | FPRINTF(stderrstderr, "ERROR: typedefenum first token is not 'typedef'\n");
2810 | Exit(10);
2811 | }
2812 | ti=ti->next;
2813 |
2814 | /* this could be a [ v1_enum ] */
2815 | if(!g_strcmp0(ti->str, "[")){
2816 | ti=ti->next;
2817 |
2818 | if(g_strcmp0(ti->str, "v1_enum")){
2819 | FPRINTF(stderrstderr, "ERROR: typedefenum not 'v1_enum' inside brackets\n");
2820 | Exit(10);
2821 | }
2822 | ti=ti->next;
2823 |
2824 | if(g_strcmp0(ti->str, "]")){
2825 | FPRINTF(stderrstderr, "ERROR: typedefenum 'v1_enum' is not followed by ']'\n");
2826 | Exit(10);
2827 | }
2828 | ti=ti->next;
2829 |
2830 | enumsize=32;
2831 | }
2832 |
2833 |
2834 | if(g_strcmp0(ti->str, "enum")){
2835 | FPRINTF(stderrstderr, "ERROR: typedefenum second token is not 'enum'\n");
2836 | Exit(10);
2837 | }
2838 | ti=ti->next;
2839 |
2840 | if(g_strcmp0(ti->str, "{")){
2841 | FPRINTF(stderrstderr, "ERROR: typedefenum third token is not '{'\n");
2842 | Exit(10);
2843 | }
2844 | ti=ti->next;
2845 |
2846 | /* now parse all values until we find the "}" */
2847 | eval=0;
2848 | enum_list=NULL((void*)0);
2849 | lastel=NULL((void*)0);
2850 | while(1){
2851 | /* check for '}' */
2852 | if(!g_strcmp0(ti->str,"}")){
2853 | ti=ti->next;
2854 | break;
2855 | }
2856 |
2857 | /* handle 4 types of entries:
2858 | * 1, CONST = value,
2859 | * 2, CONST,
2860 | * 3, CONST = value}
2861 | * 4, CONST}
2862 | */
2863 | el=g_new0(enum_list_t, 1)((enum_list_t *) g_malloc0_n ((1), sizeof (enum_list_t)));
2864 | if (!el) {
2865 | FPRINTF(stderrstderr, "Can't allocate memory. Exit.\n");
2866 | exit(10);
2867 | }
2868 | el->next=NULL((void*)0);
2869 | if(!enum_list){
2870 | enum_list=el;
2871 | } else {
2872 | lastel->next=el;
2873 | }
2874 | lastel=el;
2875 |
2876 | /* grab CONST */
2877 | el->name=ti->str;
2878 | ti=ti->next;
2879 |
2880 | /* grab separator */
2881 | if(!g_strcmp0(ti->str,"=")){
2882 | ti=ti->next;
2883 | /* grab value */
2884 | val=strtol(ti->str,&p,0);
2885 | if (p==ti->str||*p) {
2886 | FPRINTF(stderrstderr, "ERROR: typedefenum value is not a number\n");
2887 | Exit(10);
2888 | }
2889 | el->val=(int)val;
2890 | ti=ti->next;
2891 | } else {
2892 | el->val=eval;
2893 | }
2894 | eval=el->val+1;
2895 |
2896 | /* check for ',' */
2897 | if(!g_strcmp0(ti->str,",")){
2898 | ti=ti->next;
2899 | continue;
2900 | }
2901 |
2902 | /* check for '}' */
2903 | if(!g_strcmp0(ti->str,"}")){
2904 | ti=ti->next;
2905 | break;
2906 | }
2907 |
2908 | FPRINTF(stderrstderr,"ERROR: typedefenum should not be reached\n");
2909 | Exit(10);
2910 | }
2911 |
2912 | /* verify that it ends with a ';' */
2913 | if(g_strcmp0(ti->next->str,";")){
2914 | FPRINTF(stderrstderr,"ERROR enum terminator is not ';'\n");
2915 | Exit(10);
2916 | }
2917 |
2918 | snprintf(valsstring, BASE_BUFFER_SIZE256, "%s_%s_vals", ifname, ti->str);
2919 | snprintf(dissectorname, DISSECTORNAME_MAXLEN256, "%s_dissect_%s", ifname, ti->str);
2920 |
2921 | FPRINTF(NULL((void*)0),"\nENUM:%s\n-------\n",ti->str);
2922 |
2923 | FPRINTF(eth_hdr, "\n");
2924 | for(el=enum_list;el;el=el->next){
2925 | FPRINTF(eth_hdr, "#define %s %d\n", el->name, el->val);
2926 | }
2927 |
2928 | FPRINTF(eth_hdr, "\n");
2929 | FPRINTF(eth_hdr, "extern const value_string %s[];\n", valsstring);
2930 | FPRINTF(eth_hdr, "unsigned %s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param);\n", dissectorname);
2931 |
2932 | FPRINTF(eth_code, "\n");
2933 | FPRINTF(eth_code, "const value_string %s[] = {\n", valsstring);
2934 |
2935 | for(el=enum_list;el;el=el->next){
2936 | FPRINTF(eth_code, " { %d , \"%s\" },\n", el->val, el->name);
2937 | }
2938 | FPRINTF(eth_code, " { 0 , NULL }\n");
2939 | FPRINTF(eth_code, "};\n");
2940 |
2941 | FPRINTF(eth_code, "\n");
2942 | FPRINTF(eth_code, "int\n");
2943 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep, int hf_index, uint32_t param _U_)\n", dissectorname);
2944 | FPRINTF(eth_code, "{\n");
2945 | switch(enumsize){
2946 | case 16:
2947 | FPRINTF(eth_code, " offset=dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
2948 | break;
2949 | case 32:
2950 | FPRINTF(eth_code, " offset=dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hf_index, NULL);\n");
2951 | break;
2952 | default:
2953 | FPRINTF(stderrstderr,"ERROR enum unknown size\n");
2954 | Exit(10);
2955 | }
2956 |
2957 | FPRINTF(eth_code, " return offset;\n");
2958 | FPRINTF(eth_code, "}\n");
2959 | FPRINTF(eth_code, "\n");
2960 |
2961 | hfvalsstring = g_strdup_printf("VALS(%s)", valsstring);
2962 | switch(enumsize){
2963 | case 16:
2964 | register_new_type(ti->str, dissectorname, "FT_INT16", "BASE_DEC", "0", hfvalsstring, 2);
2965 | break;
2966 | case 32:
2967 | register_new_type(ti->str, dissectorname, "FT_INT32", "BASE_DEC", "0", hfvalsstring, 4);
2968 | break;
2969 | default:
2970 | FPRINTF(stderrstderr,"ERROR enum unknown size\n");
2971 | g_free(hfvalsstring);
2972 | Exit(10);
2973 | }
2974 | g_free(hfvalsstring);
2975 |
2976 | FPRINTF(NULL((void*)0),"\n----------\nEND ENUM:%s\n",ti->str);
2977 |
2978 | /* skip past the name and the ';' */
2979 | token_list=ti->next->next;
2980 | }
2981 |
2982 | typedef struct _trimmed_prefixes_t {
2983 | struct _trimmed_prefixes_t *next;
2984 | char *name;
2985 | } trimmed_prefixes_t;
2986 | static trimmed_prefixes_t *prefixes_to_trim=NULL((void*)0);
2987 |
2988 | static void preparetrimprefix(char *prefix_name)
2989 | {
2990 | trimmed_prefixes_t *new_prefix;
2991 | new_prefix=g_new0(trimmed_prefixes_t, 1)((trimmed_prefixes_t *) g_malloc0_n ((1), sizeof (trimmed_prefixes_t )));
2992 | if (!new_prefix) {
2993 | FPRINTF(stderrstderr, "Can't allocate memory. Exit.\n");
2994 | exit(10);
2995 | }
2996 | new_prefix->next=prefixes_to_trim;
2997 | prefixes_to_trim=new_prefix;
2998 | new_prefix->name=g_strdup(prefix_name)g_strdup_inline (prefix_name);
2999 | }
3000 |
3001 | static void
3002 | trimprefix(void)
3003 | {
3004 | token_item_t *ti;
3005 | trimmed_prefixes_t *pfx;
3006 | size_t len;
3007 |
3008 | for(pfx=prefixes_to_trim;pfx;pfx=pfx->next){
3009 | len=strlen(pfx->name);
3010 | for(ti=token_list;ti;ti=ti->next){
3011 | if(!strncmp(ti->str, pfx->name, len)){
3012 | ti->str+=len;
3013 | }
3014 | }
3015 | }
3016 | }
3017 |
3018 | static int Exit(int code)
3019 | {
3020 | FPRINTF(stderrstderr, "The tokens remaining when aborting:\n");
3021 | printtokenlist(10);
3022 |
3023 | exit(code);
3024 | }
3025 |
3026 | static void usage(void)
3027 | {
3028 | FPRINTF(stderrstderr, "Usage: idl2wrs <interface>\n");
3029 | }
3030 |
3031 | static void
3032 | mergefile(const char *name, FILE *outfile)
3033 | {
3034 | FILE *infile;
3035 |
3036 | FPRINTF(outfile, "\n\n/* INCLUDED FILE : %s */\n", name);
3037 | infile=g_fopenfopen(name, "r");
3038 | while(!feof(infile)){
3039 | int ch;
3040 | ch=fgetc(infile);
3041 | if(ch!=-1){
3042 | fputc(ch, outfile);
3043 | }
3044 | }
3045 | fclose(infile);
3046 | FPRINTF(outfile, "/* END OF INCLUDED FILE : %s */\n\n\n", name);
3047 | }
3048 |
3049 |
3050 |
3051 | static char *
3052 | str_read_string(char *str, char **name)
3053 | {
3054 | char tmpstr[BASE_BUFFER_SIZE256], *strptr;
3055 | int skip_blanks;
3056 | int quoted_string;
3057 |
3058 | strptr=tmpstr;
3059 | skip_blanks=1;
3060 | quoted_string=0;
3061 | while(1){
3062 | if(!*str){
3063 | *strptr=0;
3064 | *name=g_strdup(tmpstr)g_strdup_inline (tmpstr);
3065 | return str;
3066 | }
3067 | if(skip_blanks){
3068 | if( (*str==' ') || (*str=='\t') ){
3069 | str++;
3070 | continue;
3071 | }
3072 | if( *str=='"' ){
3073 | str++;
3074 | quoted_string=1;
3075 | }
3076 | skip_blanks=0;
3077 | continue;
3078 | }
3079 | if( (*str==' ') || (*str=='\t') ){
3080 | if(quoted_string){
3081 | *strptr++ = *str++;
3082 | continue;
3083 | }
3084 | *strptr=0;
3085 | *name=g_strdup(tmpstr)g_strdup_inline (tmpstr);
3086 | return str;
3087 | }
3088 | if( (*str=='"') || (*str=='\n') ){
3089 | *strptr=0;
3090 | *name=g_strdup(tmpstr)g_strdup_inline (tmpstr);
3091 | return ++str;
3092 | }
3093 | *strptr++ = *str++;
3094 | }
3095 | return NULL((void*)0);
3096 | }
3097 |
3098 | static void
3099 | readcnffile(FILE *fh)
3100 | {
3101 | char cnfline[4 * BASE_BUFFER_SIZE256];
3102 |
3103 | FPRINTF(NULL((void*)0), "Reading conformance file\n=======================\n");
3104 | while(!feof(fh)){
3105 | cnfline[0]=0;
3106 | if(!fgets(cnfline, 4 * BASE_BUFFER_SIZE256, fh) || !cnfline[0]){
3107 | continue;
3108 | }
3109 | if(cnfline[0]=='#'){
3110 | /* ignore all comments */
3111 | } else if(!strncmp(cnfline, "NOEMIT", 6)){
3112 | no_emit_item_t *nei;
3113 | char *str, *name;
3114 |
3115 | str=cnfline+6;
3116 | str_read_string(str, &name);
3117 | nei=g_new0(no_emit_item_t, 1)((no_emit_item_t *) g_malloc0_n ((1), sizeof (no_emit_item_t) ));
3118 | if (!nei) {
3119 | FPRINTF(stderrstderr, "Can't allocate memory. Exit.\n");
3120 | exit(10);
3121 | }
3122 | nei->next=no_emit_list;
3123 | no_emit_list=nei;
3124 | nei->name=name;
3125 | FPRINTF(NULL((void*)0), "NOEMIT : %s\n", nei->name);
3126 | } else if(!strncmp(cnfline, "TYPE", 4)){
3127 | char *name, *dissectorname, *ft_type, *base_type;
3128 | char *mask, *valsstring, *al;
3129 | char *str;
3130 | int alignment;
3131 |
3132 | str=cnfline+4;
3133 | str=str_read_string(str, &name);
3134 | str=str_read_string(str, &dissectorname);
3135 | str=str_read_string(str, &ft_type);
3136 | str=str_read_string(str, &base_type);
3137 | str=str_read_string(str, &mask);
3138 | str=str_read_string(str, &valsstring);
3139 | str_read_string(str, &al);
3140 | if (ws_strtoi32(al, NULL((void*)0), &alignment)) {
3141 | FPRINTF(NULL((void*)0), "TYPE : X%s,%sX\n", name, dissectorname);
3142 | register_new_type(name, dissectorname, ft_type, base_type, mask, valsstring, alignment);
3143 | }
3144 | } else if(!strncmp(cnfline, "PARAM_VALUE", 11)){
3145 | char *dissectorname, *value;
3146 | char *str;
3147 |
3148 | str=cnfline+11;
3149 | str=str_read_string(str, &dissectorname);
3150 | str_read_string(str, &value);
3151 |
3152 | FPRINTF(NULL((void*)0), "PARAM_VALUE : %s=%s\n", dissectorname,value);
3153 | register_dissector_param_value(dissectorname, value);
3154 | } else if(!strncmp(cnfline, "HF_FIELD", 8)){
3155 | char *hf_index, *title, *filter_name, *ft_type;
3156 | char *base_type, *valsstring, *mask, *blurb;
3157 | char *str;
3158 |
3159 | str=cnfline+8;
3160 | str=str_read_string(str, &hf_index);
3161 | str=str_read_string(str, &title);
3162 | str=str_read_string(str, &filter_name);
3163 | str=str_read_string(str, &ft_type);
3164 | str=str_read_string(str, &base_type);
3165 | str=str_read_string(str, &valsstring);
3166 | str=str_read_string(str, &mask);
3167 | str_read_string(str, &blurb);
3168 | FPRINTF(NULL((void*)0), "HF_FIELD: %s \"%s\"\n", hf_index, title);
3169 | register_hf_field(hf_index, title, filter_name, ft_type, base_type, valsstring, mask, blurb);
3170 | } else if(!strncmp(cnfline, "HF_RENAME", 9)){
3171 | char *old_name, *new_name;
3172 | char *str;
3173 |
3174 | str=cnfline+9;
3175 | str=str_read_string(str, &old_name);
3176 | str_read_string(str, &new_name);
3177 | FPRINTF(NULL((void*)0), "HF_RENAME: %s -> %s\n", old_name, new_name);
3178 | register_hf_rename(old_name, new_name);
3179 | } else if(!strncmp(cnfline, "UNION_TAG_SIZE", 14)){
3180 | char *union_name, *union_tag;
3181 | int32_t union_tag_size;
3182 | union_tag_size_item_t *utsi;
3183 | char *str;
3184 |
3185 | str=cnfline+14;
3186 | str=str_read_string(str, &union_name);
3187 | str_read_string(str, &union_tag);
3188 | if (!ws_strtoi32(union_tag, NULL((void*)0), &union_tag_size)) {
3189 | FPRINTF(NULL((void*)0), "UNION_TAG_SIZE: invalid string: %s\n", union_tag);
3190 | exit(10);
3191 | }
3192 | FPRINTF(NULL((void*)0), "UNION_TAG_SIZE: %s == %d\n", union_name, union_tag_size);
3193 | utsi=g_new0(union_tag_size_item_t, 1)((union_tag_size_item_t *) g_malloc0_n ((1), sizeof (union_tag_size_item_t )));
3194 | if (!utsi) {
3195 | FPRINTF(stderrstderr, "Can't allocate memory. Exit.\n");
3196 | exit(10);
3197 | }
3198 | utsi->next=union_tag_size_list;
3199 | union_tag_size_list=utsi;
3200 | utsi->name=g_strdup(union_name)g_strdup_inline (union_name);
3201 | utsi->size=union_tag_size;
3202 | } else if(!strncmp(cnfline, "STRIP_PREFIX", 12)){
3203 | char *prefix_name;
3204 | char *str;
3205 |
3206 | str=cnfline+12;
3207 | str_read_string(str, &prefix_name);
3208 | FPRINTF(NULL((void*)0), "STRIP_PREFIX: %s\n", prefix_name);
3209 | preparetrimprefix(prefix_name);
3210 | } else {
3211 | FPRINTF(stderrstderr, "ERROR: could not parse cnf directive:%s\n",cnfline);
3212 | exit(10);
3213 | }
3214 | }
3215 | }
3216 |
3217 | int main(int argc, const char *argv[])
3218 | {
3219 | char idlfile[BASE_BUFFER_SIZE256];
3220 | char tmplfile[BASE_BUFFER_SIZE256];
3221 | char prefix_str[BASE_BUFFER_SIZE256];
3222 | bracket_item_t *bi;
3223 | FILE *fh;
3224 |
3225 | if(argc!=2){
1 | Assuming 'argc' is equal to 2 | →
2 | ← | Taking false branch | →
3226 | usage();
3227 | exit(0);
3228 | }
3229 |
3230 | eth_code=g_fopenfopen("ETH_CODE", "w");
3231 | eth_hdr=g_fopenfopen("ETH_HDR", "w");
3232 | eth_hfarr=g_fopenfopen("ETH_HFARR", "w");
3233 | eth_hf=g_fopenfopen("ETH_HF", "w");
3234 | eth_ettarr=g_fopenfopen("ETH_ETTARR", "w");
3235 | eth_ett=g_fopenfopen("ETH_ETT", "w");
3236 | eth_ft=g_fopenfopen("ETH_FT", "w");
3237 | eth_handoff=g_fopenfopen("ETH_HANDOFF", "w");
3238 |
3239 | snprintf(idlfile, BASE_BUFFER_SIZE256, "%s.cnf", argv[1]);
3240 | fh=g_fopenfopen(idlfile,"r");
3241 | if(fh
2.1 | 'fh' is null
){
3 | ← | Taking false branch | →
3242 | readcnffile(fh);
3243 | fclose(fh);
3244 | }
3245 |
3246 | snprintf(idlfile, BASE_BUFFER_SIZE256, "%s.idl", argv[1]);
3247 | fh=g_fopenfopen(idlfile,"r");
3248 | if(!fh
3.1 | 'fh' is non-null
){
4 | ← | Taking false branch | →
3249 | FPRINTF(stderrstderr, "ERROR: could not open idl-file:%s\n", idlfile);
3250 | Exit(0);
3251 | }
3252 |
3253 | lineno=0;
3254 | linepos=0;
3255 | tokenize(fh);
5 | ← | Calling 'tokenize' | →
3256 | prune_keyword_parameters("size_is");
3257 | prune_keyword_parameters("length_is");
3258 | rename_tokens("NTSTATUS", "WERROR");
3259 | rename_tokens("unistr_noterm", "unistr");
3260 | rename_tokens("ascstr_noterm", "ascstr");
3261 | rename_tokens("hyper", "uint64");
3262 | FPRINTF(NULL((void*)0),"\n\nParsing header:\n================\n");
3263 | parseheader();
3264 |
3265 | /* some idl files prepend a lot of symbols with <ifname>_
3266 | search through the tokenlist and g_remove all such
3267 | prefixes
3268 | */
3269 | snprintf(prefix_str, BASE_BUFFER_SIZE256, "%s_", ifname);
3270 | preparetrimprefix(prefix_str);
3271 | trimprefix();
3272 |
3273 | /* this is the main loop, each iteration it tries to identify what
3274 | kind of construct is the first entry in the token_list and call
3275 | the appropriate handler
3276 | */
3277 | while(1) {
3278 | /* just skip any [ ] that starts a new construct */
3279 | if( !g_strcmp0(token_list->str, "[") ){
3280 | token_list=parsebrackets(token_list, &bi);
3281 | continue;
3282 | }
3283 |
3284 | /* typedef enum { */
3285 | if( !g_strcmp0(token_list->str,"typedef")
3286 | &&!g_strcmp0(token_list->next->str,"enum") ){
3287 | parsetypedefenum();
3288 | continue;
3289 | }
3290 |
3291 | /* typedef [ v1_enum ] enum { */
3292 | if( !g_strcmp0(token_list->str,"typedef")
3293 | &&!g_strcmp0(token_list->next->str,"[")
3294 | &&!g_strcmp0(token_list->next->next->str,"v1_enum")
3295 | &&!g_strcmp0(token_list->next->next->next->str,"]")
3296 | &&!g_strcmp0(token_list->next->next->next->next->str,"enum") ){
3297 | parsetypedefenum();
3298 | continue;
3299 | }
3300 |
3301 | /* const */
3302 | if( !g_strcmp0(token_list->str,"const") ){
3303 | parseconst();
3304 | continue;
3305 | }
3306 |
3307 | /* typedef struct { */
3308 | if( !g_strcmp0(token_list->str,"typedef") ){
3309 | token_item_t *tmpti;
3310 |
3311 | tmpti=token_list->next;
3312 | if( !g_strcmp0(tmpti->str, "[") ){
3313 | tmpti=parsebrackets(tmpti, &bi);
3314 | /* do some sanity checks here of bi->flags */
3315 | }
3316 | if( !g_strcmp0(tmpti->str, "struct") ){
3317 | parsetypedefstruct(0);
3318 | parsetypedefstruct(1);
3319 | continue;
3320 | }
3321 | }
3322 |
3323 | /* typedef union { */
3324 | if( !g_strcmp0(token_list->str,"typedef") ){
3325 | token_item_t *tmpti;
3326 |
3327 | tmpti=token_list->next;
3328 | if( !g_strcmp0(tmpti->str, "[") ){
3329 | tmpti=parsebrackets(tmpti, &bi);
3330 | /* do some sanity checks here of bi->flags */
3331 | }
3332 | if( !g_strcmp0(tmpti->str, "union") ){
3333 | parsetypedefunion(0);
3334 | parsetypedefunion(1);
3335 | continue;
3336 | }
3337 | }
3338 |
3339 | /* typedef bitmap { */
3340 | if( !g_strcmp0(token_list->str,"typedef") ){
3341 | token_item_t *tmpti;
3342 |
3343 | tmpti=token_list->next;
3344 | if( !g_strcmp0(tmpti->str, "[") ){
3345 | tmpti=parsebrackets(tmpti, &bi);
3346 | /* do some sanity checks here of bi->flags */
3347 | }
3348 | if( !g_strcmp0(tmpti->str, "bitmap") ){
3349 | parsetypedefbitmap(0);
3350 | parsetypedefbitmap(1);
3351 | continue;
3352 | }
3353 | }
3354 |
3355 | /* functions: WERROR function '(' */
3356 | if( !g_strcmp0(token_list->str,"WERROR")
3357 | &&!g_strcmp0(token_list->next->next->str,"(") ){
3358 | parsefunction(0);
3359 | parsefunction(1);
3360 | parsefunction(2);
3361 | continue;
3362 | }
3363 |
3364 | /* declare ... ; */
3365 | if( !g_strcmp0(token_list->str,"declare") ){
3366 | skipdeclare();
3367 | continue;
3368 | }
3369 |
3370 |
3371 | break;
3372 | };
3373 |
3374 |
3375 | fclose(eth_code);
3376 | fclose(eth_hdr);
3377 | fclose(eth_hf);
3378 | fclose(eth_hfarr);
3379 | fclose(eth_ett);
3380 | fclose(eth_ettarr);
3381 | fclose(eth_ft);
3382 | fclose(eth_handoff);
3383 |
3384 | /* unless the token_list now only contains a single token : '}'
3385 | we have failed to compile the idl file properly
3386 | */
3387 | if( g_strcmp0(token_list->str, "}") || token_list->next){
3388 | FPRINTF(stderrstderr, "ERROR: we did not process all tokens. Compiler is incomplete.\n===========================================\n");
3389 | printtokenlist(10);
3390 | exit(10);
3391 | }
3392 |
3393 | check_hf_rename_refcount();
3394 |
3395 | /* merge code and template into dissector */
3396 | snprintf(line, 4 * BASE_BUFFER_SIZE256, "packet-dcerpc-%s.c", ifname);
3397 | fh=g_fopenfopen(line, "w");
3398 | snprintf(tmplfile, BASE_BUFFER_SIZE256, "packet-dcerpc-%s-template.c", argv[1]);
3399 | tfh=g_fopenfopen(tmplfile, "r");
3400 | if(!tfh){
3401 | FPRINTF(stderrstderr, "ERROR: could not find %s\n", tmplfile);
3402 | exit(10);
3403 | }
3404 | while(!feof(tfh)){
3405 | line[0]=0;
3406 | if(!fgets(line, 4 * BASE_BUFFER_SIZE256, tfh) || !line[0]){
3407 | continue;
3408 | }
3409 | if(!strncmp(line, "ETH_CODE", 8)){
3410 | mergefile("ETH_CODE",fh);
3411 | } else if(!strncmp(line, "ETH_HDR", 7)){
3412 | mergefile("ETH_HDR",fh);
3413 | } else if(!strncmp(line, "ETH_HFARR", 9)){
3414 | mergefile("ETH_HFARR",fh);
3415 | } else if(!strncmp(line, "ETH_HF", 6)){
3416 | mergefile("ETH_HF",fh);
3417 | } else if(!strncmp(line, "ETH_ETTARR", 10)){
3418 | mergefile("ETH_ETTARR",fh);
3419 | } else if(!strncmp(line, "ETH_ETT", 7)){
3420 | mergefile("ETH_ETT",fh);
3421 | } else if(!strncmp(line, "ETH_FT", 6)){
3422 | mergefile("ETH_FT",fh);
3423 | } else if(!strncmp(line, "ETH_HANDOFF", 11)){
3424 | mergefile("ETH_HANDOFF",fh);
3425 | } else {
3426 | fputs(line, fh);
3427 | }
3428 | }
3429 | fclose(fh);
3430 | fclose(tfh);
3431 |
3432 | snprintf(line, 4 * BASE_BUFFER_SIZE256, "packet-dcerpc-%s.h", ifname);
3433 | fh=g_fopenfopen(line, "w");
3434 | snprintf(tmplfile, BASE_BUFFER_SIZE256, "packet-dcerpc-%s-template.h", argv[1]);
3435 | tfh=g_fopenfopen(tmplfile, "r");
3436 | if(!tfh){
3437 | FPRINTF(stderrstderr, "ERROR: could not find %s\n", tmplfile);
3438 | exit(10);
3439 | }
3440 | while(!feof(tfh)){
3441 | line[0]=0;
3442 | if(!fgets(line, 4 * BASE_BUFFER_SIZE256, tfh) || !line[0]){
3443 | continue;
3444 | }
3445 | if(!strncmp(line, "ETH_CODE", 8)){
3446 | mergefile("ETH_CODE",fh);
3447 | } else if(!strncmp(line, "ETH_HDR", 7)){
3448 | mergefile("ETH_HDR",fh);
3449 | } else if(!strncmp(line, "ETH_HFARR", 9)){
3450 | mergefile("ETH_HFARR",fh);
3451 | } else if(!strncmp(line, "ETH_HF", 6)){
3452 | mergefile("ETH_HF",fh);
3453 | } else if(!strncmp(line, "ETH_ETTARR", 10)){
3454 | mergefile("ETH_ETTARR",fh);
3455 | } else if(!strncmp(line, "ETH_ETT", 7)){
3456 | mergefile("ETH_ETT",fh);
3457 | } else if(!strncmp(line, "ETH_FT", 6)){
3458 | mergefile("ETH_FT",fh);
3459 | } else if(!strncmp(line, "ETH_HANDOFF", 11)){
3460 | mergefile("ETH_HANDOFF",fh);
3461 | } else {
3462 | fputs(line, fh);
3463 | }
3464 | }
3465 |
3466 | g_print("%s was successfully compiled\n", ifname);
3467 |
3468 | fclose(fh);
3469 | fclose(tfh);
3470 |
3471 | if (g_removeremove("ETH_CODE") == -1) {
3472 | FPRINTF(stderrstderr, "Can't remove ETH_CODE");
3473 | }
3474 | if (g_removeremove("ETH_HDR") == -1) {
3475 | FPRINTF(stderrstderr, "Can't remove ETH_CODE");
3476 | }
3477 | if (g_removeremove("ETH_HFARR") == -1) {
3478 | FPRINTF(stderrstderr, "Can't remove ETH_CODE");
3479 | }
3480 | if (g_removeremove("ETH_HF") == -1) {
3481 | FPRINTF(stderrstderr, "Can't remove ETH_CODE");
3482 | }
3483 | if (g_removeremove("ETH_ETTARR") == -1) {
3484 | FPRINTF(stderrstderr, "Can't remove ETH_CODE");
3485 | }
3486 | if (g_removeremove("ETH_ETT") == -1) {
3487 | FPRINTF(stderrstderr, "Can't remove ETH_CODE");
3488 | }
3489 | if (g_removeremove("ETH_FT") == -1) {
3490 | FPRINTF(stderrstderr, "Can't remove ETH_CODE");
3491 | }
3492 | if (g_removeremove("ETH_HANDOFF") == -1) {
3493 | FPRINTF(stderrstderr, "Can't remove ETH_CODE");
3494 | }
3495 |
3496 |
3497 | return 0;
3498 | }
3499 |
3500 | /*
3501 | * Editor modelines - https://www.wireshark.org/tools/modelines.html
3502 | *
3503 | * Local variables:
3504 | * c-basic-offset: 8
3505 | * tab-width: 8
3506 | * indent-tabs-mode: t
3507 | * End:
3508 | *
3509 | * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3510 | * :indentSize=8:tabSize=8:noTabs=false:
3511 | */