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