File: | builds/wireshark/wireshark/epan/dissectors/dcerpc/idl2wrs.c |
Warning: | line 2692, column 5 Potential leak of memory pointed to by 'pi' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* idl2wrs.c | ||||
2 | * DCE RPC IDL to Wireshark dissector compiler | ||||
3 | * | ||||
4 | * Wireshark - Network traffic analyzer | ||||
5 | * By Gerald Combs <[email protected]> | ||||
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 teh 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> ] inteface <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)){ | ||||
968 | ch=fgetc(fh); | ||||
969 | |||||
970 | /* full line comment */ | ||||
971 | if(fullinecomment){ | ||||
972 | if( (ch=='\n')||(ch=='\r') ){ | ||||
973 | fullinecomment=0; | ||||
974 | linepos=0; | ||||
975 | } | ||||
976 | continue; | ||||
977 | } | ||||
978 | if( (ch=='#')&&(linepos==0) ){ | ||||
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 int\n"); | ||||
1098 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1110 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1122 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1135 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1150 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1163 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1178 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1190 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1202 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1215 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1230 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1246 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1261 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1277 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1293 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1308 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1323 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1338 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1352 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1364 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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, int 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, int 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 int\n"); | ||||
1699 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1716 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1731 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1756 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1771 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1786 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
1810 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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, int 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, int 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&(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 int\n"); | ||||
2264 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
2407 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
2419 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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
| ||||
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
| ||||
2572 | FPRINTF(eth_code, "\n"); | ||||
2573 | FPRINTF(eth_code, "static int\n"); | ||||
2574 | FPRINTF(eth_code, "%s_dissect_%s_%s(tvbuff_t *tvb _U_, int 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 poitner 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
| ||||
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 int\n"); | ||||
2648 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
2664 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
2675 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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 int\n"); | ||||
2694 | FPRINTF(eth_code, "%s(tvbuff_t *tvb, int 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, "int %s(tvbuff_t *tvb, int 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, int 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){ | ||||
| |||||
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){ | ||||
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){ | ||||
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); | ||||
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 | */ |