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