fix some more warnings
[metze/wireshark/wip.git] / epan / radius_dict.l
1 %option noyywrap
2
3 %option nounput
4 %option never-interactive
5 %option prefix="Radius"
6 %option caseless
7
8 %option outfile="radius_dict.c"
9
10 %{
11         /* radius_dict.l
12         *
13         * RADIUS dictionary parser
14         *
15         * $Id$
16         *
17         * Wireshark - Network traffic analyzer
18         * By Gerald Combs <gerald@wireshark.org>
19         * Copyright 1998 Gerald Combs
20         *
21         * This program is free software; you can redistribute it and/or
22         * modify it under the terms of the GNU General Public License
23         * as published by the Free Software Foundation; either version 2
24         * of the License, or (at your option) any later version.
25         *
26         * This program is distributed in the hope that it will be useful,
27         * but WITHOUT ANY WARRANTY; without even the implied warranty of
28         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29         * GNU General Public License for more details.
30         *
31         * You should have received a copy of the GNU General Public License
32         * along with this program; if not, write to the Free Software
33         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
34         *
35         */
36         
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40         
41 #include <glib.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <errno.h>
46 #include <epan/packet.h>
47 #include <epan/dissectors/packet-radius.h>
48 #define ECHO
49 #define MAX_INCLUDE_DEPTH 10
50
51         void add_vendor(const gchar* name, guint32 vendor_id);
52         void add_value(const gchar* attrib_name,const  gchar* value_repr, long value);
53         void add_attribute(const gchar*,const  gchar*, radius_attr_dissector_t,const  gchar*, gboolean, gboolean);
54         
55         static YY_BUFFER_STATE include_stack[10];
56         static int include_stack_ptr = 0;
57         
58         static radius_dictionary_t* dict = NULL;
59         static GHashTable* value_strings = NULL; /* GArray(value_string) by attribute name */
60         
61         static gchar* attr_name = NULL;
62         static gchar* attr_id = NULL;
63         static radius_attr_dissector_t* attr_type = NULL;
64         static gchar* attr_vendor = NULL;
65         static gchar* vendor_name = NULL;
66         static gchar* value_repr = NULL;
67         static gboolean encrypted = FALSE;
68         static gboolean has_tag = FALSE;
69         static gchar* current_vendor = NULL;
70         
71         static GString* error = NULL;
72         static gchar* directory = NULL;
73         static int linenums[] = {1,1,1,1,1,1,1,1,1,1};
74         static gchar* fullpaths[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
75         
76 %}
77
78 %START OUT VENDOR VENDOR_W_NAME ATTR ATTR_W_NAME ATTR_W_ID ATTR_W_TYPE ATTR_W_VENDOR VALUE VALUE_W_ATTR VALUE_W_NAME INCLUDE JUNK BEGIN_VENDOR END_VENDOR
79 %%
80 [:blank:]   ;
81 #[^\n]*         ;
82
83 <JUNK>.*\qn             ;
84
85 <OUT>VENDOR { BEGIN VENDOR; }
86 <OUT>ATTRIBUTE { BEGIN ATTR; }
87 <OUT>VALUE { BEGIN VALUE; }
88 <OUT>\$INCLUDE { BEGIN INCLUDE; }
89 <OUT>BEGIN-VENDOR { BEGIN BEGIN_VENDOR; }
90 <OUT>END-VENDOR { BEGIN END_VENDOR; }
91
92 <BEGIN_VENDOR>[0-9a-z_-]+ {
93     if (current_vendor) {
94         g_free(current_vendor);
95     }
96     current_vendor = g_strdup(yytext);
97     BEGIN OUT;
98 }
99 <END_VENDOR>[^\n]* {
100     if (current_vendor) {
101         g_free(current_vendor);
102         current_vendor = NULL;
103     }
104     BEGIN OUT;
105 }
106
107 <VENDOR>[0-9a-z_-]+   { vendor_name = g_strdup(yytext); BEGIN VENDOR_W_NAME; }
108 <VENDOR_W_NAME>[0-9]+   {
109     add_vendor(vendor_name,strtol(yytext,NULL,10));
110     g_free(vendor_name);
111     BEGIN OUT;
112 }
113 <VENDOR_W_NAME>0x[0-9a-f]+   {
114     add_vendor(vendor_name,strtol(yytext,NULL,16));
115     g_free(vendor_name);
116     BEGIN OUT;
117 }
118
119 <ATTR>[0-9a-z_/-]+                      { attr_name = g_strdup(yytext); encrypted = FALSE; has_tag = FALSE; BEGIN ATTR_W_NAME; }
120 <ATTR_W_NAME>[0-9]+                     { attr_id = g_strdup(yytext);  BEGIN ATTR_W_ID;}
121 <ATTR_W_NAME>0x[0-9a-f]+                { attr_id = g_strdup_printf("%u",(int)strtoul(yytext,NULL,16)); BEGIN ATTR_W_ID;}
122 <ATTR_W_ID>integer                      { attr_type = radius_integer;  BEGIN ATTR_W_TYPE; }
123 <ATTR_W_ID>string                       { attr_type = radius_string;  BEGIN ATTR_W_TYPE; }
124 <ATTR_W_ID>octets                       { attr_type = radius_octets;  BEGIN ATTR_W_TYPE; }
125 <ATTR_W_ID>ipaddr                       { attr_type = radius_ipaddr;  BEGIN ATTR_W_TYPE; }
126 <ATTR_W_ID>ipv6addr                     { attr_type = radius_ipv6addr;  BEGIN ATTR_W_TYPE; }
127 <ATTR_W_ID>ipxnet                       { attr_type = radius_ipxnet;  BEGIN ATTR_W_TYPE; }
128 <ATTR_W_ID>date                         { attr_type = radius_date;  BEGIN ATTR_W_TYPE; }
129 <ATTR_W_ID>ifid                         { attr_type = radius_ifid;  BEGIN ATTR_W_TYPE; }
130 <ATTR_W_ID>[0-9a-z_-]+                  { attr_type = radius_octets;  BEGIN ATTR_W_TYPE; }
131 <ATTR_W_TYPE>has_tag[,]?                { has_tag = TRUE; }
132 <ATTR_W_TYPE>encrypt=1[,]?              { encrypted=TRUE; }
133 <ATTR_W_TYPE>[0-9a-z_-]+=([^\n]*)       ;
134 <ATTR_W_TYPE>[0-9a-z_-]+                {
135     attr_vendor = g_strdup(yytext);
136     add_attribute(attr_name,attr_id,attr_type,attr_vendor,encrypted,has_tag);
137     g_free(attr_id);
138     g_free(attr_vendor);
139     g_free(attr_name);
140     attr_id = NULL;
141     attr_vendor = NULL;
142     attr_name = NULL;
143     BEGIN OUT;
144 }
145 <ATTR_W_TYPE>\n                                         {
146     add_attribute(attr_name,attr_id,attr_type,current_vendor,encrypted,has_tag);
147     g_free(attr_id);
148     g_free(attr_name);
149     linenums[include_stack_ptr]++;
150     has_tag = FALSE;
151     encrypted=FALSE;
152     BEGIN OUT;
153 }
154 <ATTR_W_VENDOR>\n                                       {
155     add_attribute(attr_name,attr_id,attr_type,attr_vendor,encrypted,has_tag);
156     g_free(attr_id);
157     g_free(attr_vendor);
158     g_free(attr_name);
159     linenums[include_stack_ptr]++; 
160     BEGIN OUT;
161 };
162
163 <VALUE>[0-9a-z_/-]+                                     { attr_name = g_strdup(yytext); BEGIN VALUE_W_ATTR; }
164 <VALUE_W_ATTR>[^[:blank:]]+                     { value_repr = g_strdup(yytext); BEGIN VALUE_W_NAME; }
165 <VALUE_W_NAME>[0-9]+                            { add_value(attr_name,value_repr,strtol(yytext,NULL,10));  g_free(attr_name); g_free(value_repr); BEGIN OUT;}
166 <VALUE_W_NAME>0x[0-9a-f]+                       { add_value(attr_name,value_repr,strtol(yytext,NULL,16));  g_free(attr_name); g_free(value_repr); BEGIN OUT;}
167
168 <INCLUDE>[^[:blank:]\n]+   {
169         if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) {
170                 g_string_sprintfa(error, "$INCLUDE files nested to deeply\n");
171                 yyterminate();
172         }
173         
174         include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
175         
176         fullpaths[include_stack_ptr] = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
177             directory,yytext);
178
179         yyin = fopen( fullpaths[include_stack_ptr], "r" );
180         
181         if (!yyin) {
182                 if (errno) {
183                         g_string_sprintfa(error, "Could not open file: '%s', error: %s\n", fullpaths[include_stack_ptr], strerror(errno) );
184                         yyterminate();
185                 }
186         } else {
187                 linenums[include_stack_ptr] = 1;
188                 yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
189         }
190         
191
192         BEGIN OUT;
193 }
194
195 <<EOF>> {
196         
197         fclose(yyin);
198         yyin = NULL;
199     
200         if ( --include_stack_ptr < 0 ) {
201                 yyterminate();
202         } else {
203                 g_free(fullpaths[include_stack_ptr+1]);
204                 fullpaths[include_stack_ptr+1] = NULL;
205                 
206                 yy_delete_buffer( YY_CURRENT_BUFFER );
207                 yy_switch_to_buffer(include_stack[include_stack_ptr]);
208         }
209
210         BEGIN OUT;
211 }
212
213 \n      { linenums[include_stack_ptr]++; BEGIN OUT; }
214
215
216 %%
217
218 void add_vendor(const gchar* name, guint32 vendor_id) {
219         radius_vendor_info_t* v = g_malloc(sizeof(radius_vendor_info_t));
220         
221         v->name = g_strdup(name);
222         v->code = vendor_id;
223         v->attrs_by_id = g_hash_table_new(g_direct_hash,g_direct_equal);
224         v->ett = -1;
225     
226         g_hash_table_insert(dict->vendors_by_id,GUINT_TO_POINTER(v->code),v);
227         g_hash_table_insert(dict->vendors_by_name, (gpointer) v->name, v);
228 }
229
230 void add_attribute(const gchar* name, const  gchar* code, radius_attr_dissector_t type, const  gchar* vendor_name, gboolean crypt, gboolean tagged) {
231         radius_attr_info_t* a = g_malloc(sizeof(radius_attr_info_t));
232         GHashTable* by_id;
233         
234         if (vendor_name) {
235                 radius_vendor_info_t* v;
236                 v = g_hash_table_lookup(dict->vendors_by_name,vendor_name);
237                 
238                 if (! v) {
239                         g_string_sprintfa(error, "Vendor: '%s', does not exist in %s:%i \n", vendor_name, fullpaths[include_stack_ptr], linenums[include_stack_ptr] );
240                         BEGIN JUNK;
241                         return;
242                 } else {
243                         by_id = v->attrs_by_id;
244                 }
245         } else {
246                 by_id = dict->attrs_by_id;
247         }
248         
249         a->name = g_strdup(name);
250         a->code = strtol(code,NULL,10);
251         a->encrypt = crypt;
252         a->tagged =  tagged;
253         a->type = type;
254         a->dissector = NULL;
255         a->vs = NULL;
256         a->hf = -1;
257         a->hf64 = -1;
258         a->hf_tag = -1;
259         a->hf_len = -1;
260         a->ett = -1;
261         
262         g_hash_table_insert(by_id,GUINT_TO_POINTER(a->code),a);
263         g_hash_table_insert(dict->attrs_by_name,(gpointer) (a->name),a);
264 }
265
266 void add_value(const gchar* attrib_name, const gchar* value_repr, long value) {
267         value_string v;
268         GArray* a = g_hash_table_lookup(value_strings,attrib_name);
269         
270         if (! a) {
271                 a = g_array_new(TRUE,TRUE,sizeof(value_string));
272                 g_hash_table_insert(value_strings,g_strdup(attrib_name),a);
273         }
274         
275         v.value = value;
276         v.strptr = g_strdup(value_repr);
277         
278         g_array_append_val(a,v);
279 }
280
281
282 static void setup_attrs(gpointer k _U_, gpointer v, gpointer p _U_) {
283         radius_attr_info_t* a = v;
284         gpointer key;
285         
286         union {
287                 GArray* a;
288                 gpointer p;
289         } vs;
290         
291         if (g_hash_table_lookup_extended(value_strings,a->name,&key,&vs.p) ) {
292                 a->vs = (value_string*) vs.a->data;
293                 g_array_free(vs.a,FALSE);
294                 g_hash_table_remove(value_strings,key);
295                 g_free(key);
296         }
297 }
298
299 static void setup_vendors(gpointer k _U_, gpointer v, gpointer p) {
300         radius_vendor_info_t* vnd = v;
301         
302         g_hash_table_foreach(vnd->attrs_by_id,setup_attrs,p);   
303 }
304
305 static gboolean destroy_value_strings(gpointer k, gpointer v, gpointer p _U_) {
306     value_string* vs = (value_string*)(((GArray*)v)->data);
307     
308         g_free(k);
309     
310     for (;vs->strptr;vs++) {
311         g_free((void*)vs->strptr);
312     }
313     
314         g_array_free(v,TRUE);
315         return TRUE;
316 }
317
318 static gboolean destroy_attrs(gpointer k _U_, gpointer v, gpointer p _U_) {
319         radius_attr_info_t* a = v;
320         int i;
321         
322         g_free((gpointer) (a->name));
323         if (a->vs) {
324                 for(i=0; a->vs[i].strptr; i++) {
325                         g_free((void *)a->vs[i].strptr);
326                 }
327                 g_free((void *)a->vs);
328         }
329         g_free(a);
330         return TRUE;
331 }
332
333 static gboolean destroy_vendors(gpointer k _U_, gpointer v, gpointer p) {
334         radius_vendor_info_t* vnd = v;
335         g_free( (gpointer) vnd->name);
336         g_hash_table_foreach_remove(vnd->attrs_by_id,destroy_attrs,p);
337         g_hash_table_destroy(vnd->attrs_by_id);
338         g_free(vnd);
339         return TRUE;
340 }
341
342 static void destroy_dict(radius_dictionary_t* d) {
343         g_hash_table_foreach_remove(d->attrs_by_id,destroy_attrs,NULL);
344         g_hash_table_foreach_remove(d->vendors_by_id,destroy_vendors,NULL);     
345         g_hash_table_destroy(d->vendors_by_id);
346         g_hash_table_destroy(d->attrs_by_id);
347         g_hash_table_destroy(d->vendors_by_name);
348         g_hash_table_destroy(d->attrs_by_name);
349         g_free(d);
350 }
351
352 radius_dictionary_t* radius_load_dictionary (gchar* dir, const gchar* filename, gchar** err_str) {
353         int i;
354         
355         directory = dir;
356         
357         fullpaths[include_stack_ptr] = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
358             directory,filename);
359         
360         error = g_string_new("");
361
362         yyin = fopen(fullpaths[include_stack_ptr],"r");
363         
364         if (!yyin) {
365                 g_string_sprintfa(error, "Could not open file: '%s', error: %s\n", fullpaths[include_stack_ptr], strerror(errno) );
366                 g_free(fullpaths[include_stack_ptr]);
367                 *err_str = error->str;
368                 g_string_free(error,FALSE);
369                 return NULL;
370         }
371
372         dict = g_malloc(sizeof(radius_dictionary_t));
373         dict->attrs_by_id = g_hash_table_new(g_direct_hash,g_direct_equal);
374         dict->attrs_by_name = g_hash_table_new(g_str_hash,g_str_equal);
375         dict->vendors_by_id = g_hash_table_new(g_direct_hash,g_direct_equal);
376         dict->vendors_by_name = g_hash_table_new(g_str_hash,g_str_equal);
377         
378         value_strings = g_hash_table_new(g_str_hash,g_str_equal);
379         
380         BEGIN OUT;
381
382         yylex();
383
384         if (yyin != NULL) fclose(yyin);
385         yyin = NULL;
386     
387         for (i=0; i < 10; i++) {
388                 if (fullpaths[i]) g_free(fullpaths[i]);
389         }
390                 
391         g_hash_table_foreach(dict->attrs_by_id,setup_attrs,NULL);
392         g_hash_table_foreach(dict->vendors_by_id,setup_vendors,NULL);   
393         g_hash_table_foreach_remove(value_strings,destroy_value_strings,NULL);
394         
395         if (error->len > 0) {
396                  *err_str = error->str;
397                 g_string_free(error,FALSE);
398                 destroy_dict(dict);
399                 return NULL;
400         } else {
401                 *err_str = NULL;
402                 g_string_free(error,TRUE);
403                 return dict;
404         }
405 }