HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / wslua / wslua_proto.c
bloba17f71f2f9ad18d78d79c98d379de7c2f8d21b8b
1 /*
2 * lua_proto.c
4 * wireshark's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
7 * (c) 2007, Tamas Regos <tamas.regos@ericsson.com>
9 * $Id$
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include "config.h"
32 #include <epan/emem.h>
34 /* WSLUA_MODULE Proto Functions for writing dissectors */
36 #include "wslua.h"
38 #include <epan/exceptions.h>
39 #include <epan/show_exception.h>
41 WSLUA_CLASS_DEFINE(Pref,NOP,NOP); /* A preference of a Protocol. */
43 static range_t* get_range(lua_State *L, int idx_r, int idx_m);
45 static enum_val_t* get_enum(lua_State *L, int idx)
47 double seq;
48 const gchar *str1, *str2;
49 enum_val_t *ret, last = {NULL, NULL, -1};
50 GArray* es = g_array_new(TRUE,TRUE,sizeof(enum_val_t));
52 luaL_checktype(L, idx, LUA_TTABLE);
53 lua_pushnil(L); /* first key */
55 while (lua_next(L, idx)) {
56 enum_val_t e = {NULL, NULL, -1};
58 luaL_checktype(L, -1, LUA_TTABLE);
59 lua_pushnil(L);
60 lua_next(L, -2);
61 if (! lua_isstring(L,-1)) {
62 luaL_argerror(L,idx,"First value of an enum table must be string");
63 g_array_free(es,TRUE);
64 return NULL;
66 str1 = lua_tostring(L, -1);
68 lua_pop(L, 1);
69 lua_next(L, -2);
70 if (! lua_isstring(L,-1)) {
71 luaL_argerror(L,idx,"Second value of an enum table must be string");
72 g_array_free(es,TRUE);
73 return NULL;
75 str2 = lua_tostring(L, -1);
77 lua_pop(L, 1);
78 lua_next(L, -2);
79 if (! lua_isnumber(L,-1)) {
80 luaL_argerror(L,idx,"Third value of an enum table must be an integer");
81 g_array_free(es,TRUE);
82 return NULL;
84 seq = lua_tonumber(L, -1);
86 e.name = g_strdup(str1);
87 e.description = g_strdup(str2);
88 e.value = (guint32)seq;
90 g_array_append_val(es,e);
92 lua_pop(L, 3); /* removes 'value'; keeps 'key' for next iteration */
95 g_array_append_val(es,last);
97 ret = (enum_val_t*)es->data;
99 g_array_free(es,FALSE);
101 return ret;
104 static int new_pref(lua_State* L, pref_type_t type) {
105 const gchar* label = luaL_optstring(L,1,NULL);
106 const gchar* descr = luaL_optstring(L,3,"");
108 Pref pref = (wslua_pref_t *)g_malloc(sizeof(wslua_pref_t));
109 pref->name = NULL;
110 pref->label = label ? g_strdup(label) : NULL;
111 pref->desc = g_strdup(descr);
112 pref->type = type;
113 pref->next = NULL;
114 pref->proto = NULL;
116 switch(type) {
117 case PREF_BOOL: {
118 gboolean def = lua_toboolean(L,2);
119 pref->value.b = def;
120 break;
122 case PREF_UINT: {
123 guint32 def = (guint32)luaL_optnumber(L,2,0);
124 pref->value.u = def;
125 break;
127 case PREF_STRING: {
128 gchar* def = g_strdup(luaL_optstring(L,2,""));
129 pref->value.s = def;
130 break;
132 case PREF_ENUM: {
133 guint32 def = (guint32)luaL_optnumber(L,2,0);
134 enum_val_t *enum_val = get_enum(L,4);
135 gboolean radio = lua_toboolean(L,5);
136 pref->value.e = def;
137 pref->info.enum_info.enumvals = enum_val;
138 pref->info.enum_info.radio_buttons = radio;
139 break;
141 case PREF_RANGE: {
142 range_t *range = get_range(L,2,4);
143 guint32 max = (guint32)luaL_optnumber(L,4,0);
144 pref->value.r = range;
145 pref->info.max_value = max;
146 break;
148 case PREF_STATIC_TEXT: {
149 /* This is just a static text. */
150 break;
152 default:
153 g_assert_not_reached();
154 break;
158 pushPref(L,pref);
159 return 1;
162 WSLUA_CONSTRUCTOR Pref_bool(lua_State* L) {
163 /* Creates a boolean preference to be added to a Protocol's prefs table. */
164 #define WSLUA_ARG_Pref_bool_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */
165 #define WSLUA_ARG_Pref_bool_DEFAULT 2 /* The default value for this preference */
166 #define WSLUA_ARG_Pref_bool_DESCR 3 /* A description of what this preference is */
167 return new_pref(L,PREF_BOOL);
170 WSLUA_CONSTRUCTOR Pref_uint(lua_State* L) {
171 /* Creates an (unsigned) integer preference to be added to a Protocol's prefs table. */
172 #define WSLUA_ARG_Pref_uint_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */
173 #define WSLUA_ARG_Pref_uint_DEFAULT 2 /* The default value for this preference */
174 #define WSLUA_ARG_Pref_uint_DESCR 3 /* A description of what this preference is */
175 return new_pref(L,PREF_UINT);
178 WSLUA_CONSTRUCTOR Pref_string(lua_State* L) {
179 /* Creates a string preference to be added to a Protocol's prefs table. */
180 #define WSLUA_ARG_Pref_string_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */
181 #define WSLUA_ARG_Pref_string_DEFAULT 2 /* The default value for this preference */
182 #define WSLUA_ARG_Pref_string_DESCR 3 /* A description of what this preference is */
183 return new_pref(L,PREF_STRING);
186 WSLUA_CONSTRUCTOR Pref_enum(lua_State* L) {
187 /* Creates an enum preference to be added to a Protocol's prefs table. */
188 #define WSLUA_ARG_Pref_enum_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */
189 #define WSLUA_ARG_Pref_enum_DEFAULT 2 /* The default value for this preference */
190 #define WSLUA_ARG_Pref_enum_DESCR 3 /* A description of what this preference is */
191 #define WSLUA_ARG_Pref_enum_ENUM 4 /* A enum table */
192 #define WSLUA_ARG_Pref_enum_RADIO 5 /* Radio button (true) or Combobox (false) */
193 return new_pref(L,PREF_ENUM);
196 WSLUA_CONSTRUCTOR Pref_range(lua_State* L) {
197 /* Creates a range preference to be added to a Protocol's prefs table. */
198 #define WSLUA_ARG_Pref_range_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */
199 #define WSLUA_ARG_Pref_range_DEFAULT 2 /* The default value for this preference, e.g., "53", "10-30", or "10-30,53,55,100-120" */
200 #define WSLUA_ARG_Pref_range_DESCR 3 /* A description of what this preference is */
201 #define WSLUA_ARG_Pref_range_MAX 4 /* The maximum value */
202 return new_pref(L,PREF_RANGE);
205 WSLUA_CONSTRUCTOR Pref_statictext(lua_State* L) {
206 /* Creates a static text preference to be added to a Protocol's prefs table. */
207 #define WSLUA_ARG_Pref_statictext_LABEL 1 /* The static text */
208 #define WSLUA_ARG_Pref_statictext_DESCR 2 /* The static text description */
209 return new_pref(L,PREF_STATIC_TEXT);
212 static range_t* get_range(lua_State *L, int idx_r, int idx_m)
214 static range_t *ret = NULL;
215 gchar *pattern = g_strdup(luaL_checkstring(L, idx_r));
217 switch (range_convert_str(&ret, pattern, (guint32)lua_tonumber(L, idx_m))) {
218 case CVT_NO_ERROR:
219 break;
220 case CVT_SYNTAX_ERROR:
221 WSLUA_ARG_ERROR(Pref_range,DEFAULT,"syntax error in default range");
222 break;
223 case CVT_NUMBER_TOO_BIG:
224 WSLUA_ARG_ERROR(Pref_range,DEFAULT,"value too large in default range");
225 break;
226 default:
227 WSLUA_ARG_ERROR(Pref_range,DEFAULT,"unknown error in default range");
228 break;
231 g_free (pattern);
232 return ret;
234 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
235 static int Pref__gc(lua_State* L) {
236 Pref pref = checkPref(L,1);
238 if (pref && ! pref->name) {
239 g_free(pref->label);
240 g_free(pref->desc);
241 if (pref->type == PREF_STRING)
242 g_free((void*)pref->value.s);
243 g_free(pref);
246 return 0;
249 WSLUA_METHODS Pref_methods[] = {
250 WSLUA_CLASS_FNREG(Pref,bool),
251 WSLUA_CLASS_FNREG(Pref,uint),
252 WSLUA_CLASS_FNREG(Pref,string),
253 WSLUA_CLASS_FNREG(Pref,enum),
254 WSLUA_CLASS_FNREG(Pref,range),
255 WSLUA_CLASS_FNREG(Pref,statictext),
256 {0,0}
259 WSLUA_META Pref_meta[] = {
260 {0,0}
264 WSLUA_REGISTER Pref_register(lua_State* L) {
265 WSLUA_REGISTER_CLASS(Pref);
266 return 1;
269 WSLUA_CLASS_DEFINE(Prefs,NOP,NOP); /* The table of preferences of a protocol */
271 WSLUA_METAMETHOD Prefs__newindex(lua_State* L) {
272 /* Creates a new preference */
273 #define WSLUA_ARG_Prefs__newindex_NAME 2 /* The abbreviation of this preference */
274 #define WSLUA_ARG_Prefs__newindex_PREF 3 /* A valid but still unassigned Pref object */
276 Pref prefs_p = checkPrefs(L,1);
277 const gchar* name = luaL_checkstring(L,WSLUA_ARG_Prefs__newindex_NAME);
278 Pref pref = checkPref(L,WSLUA_ARG_Prefs__newindex_PREF);
279 Pref p;
280 const gchar *c;
282 if (! prefs_p ) return 0;
284 if (! name )
285 WSLUA_ARG_ERROR(Prefs__newindex,NAME,"must be a string");
287 if (! pref )
288 WSLUA_ARG_ERROR(Prefs__newindex,PREF,"must be a valid Pref");
290 if (pref->name)
291 WSLUA_ARG_ERROR(Prefs__newindex,NAME,"cannot change existing preference");
293 if (pref->proto)
294 WSLUA_ARG_ERROR(Prefs__newindex,PREF,"cannot be added to more than one protocol");
296 p = prefs_p;
298 do {
299 if ( p->name && g_str_equal(p->name,name) ) {
300 luaL_error(L,"a preference named %s exists already",name);
301 return 0;
304 * Make sure that only lower-case ASCII letters, numbers,
305 * underscores, and dots appear in the preference name.
307 for (c = name; *c != '\0'; c++) {
308 if (!isascii((guchar)*c) ||
309 (!islower((guchar)*c) && !isdigit((guchar)*c) && *c != '_' && *c != '.'))
311 luaL_error(L,"illegal preference name \"%s\", only lower-case ASCII letters, numbers, underscores and dots may be used",name);
312 return 0;
316 if ( ! p->next) {
317 p->next = pref;
318 pref->name = g_strdup(name);
320 if (!pref->label)
321 pref->label = g_strdup(name);
323 if (!prefs_p->proto->prefs_module) {
324 prefs_p->proto->prefs_module = prefs_register_protocol(prefs_p->proto->hfid, wslua_prefs_changed);
327 switch(pref->type) {
328 case PREF_BOOL:
329 prefs_register_bool_preference(prefs_p->proto->prefs_module,
330 pref->name,
331 pref->label,
332 pref->desc,
333 &(pref->value.b));
334 break;
335 case PREF_UINT:
336 prefs_register_uint_preference(prefs_p->proto->prefs_module,
337 pref->name,
338 pref->label,
339 pref->desc,
341 &(pref->value.u));
342 break;
343 case PREF_STRING:
344 prefs_register_string_preference(prefs_p->proto->prefs_module,
345 pref->name,
346 pref->label,
347 pref->desc,
348 &(pref->value.s));
349 break;
350 case PREF_ENUM:
351 prefs_register_enum_preference(prefs_p->proto->prefs_module,
352 pref->name,
353 pref->label,
354 pref->desc,
355 &(pref->value.e),
356 pref->info.enum_info.enumvals,
357 pref->info.enum_info.radio_buttons);
358 break;
359 case PREF_RANGE:
360 prefs_register_range_preference(prefs_p->proto->prefs_module,
361 pref->name,
362 pref->label,
363 pref->desc,
364 &(pref->value.r),
365 pref->info.max_value);
366 break;
367 case PREF_STATIC_TEXT:
368 prefs_register_static_text_preference(prefs_p->proto->prefs_module,
369 pref->name,
370 pref->label,
371 pref->desc);
372 break;
373 default:
374 WSLUA_ERROR(Prefs__newindex,"Unknow Pref type");
377 pref->proto = p->proto;
379 WSLUA_RETURN(0);
381 } while (( p = p->next ));
383 luaL_error(L,"this should not happen!");
385 WSLUA_RETURN(0);
388 WSLUA_METAMETHOD Prefs__index(lua_State* L) {
389 /* Get the value of a preference setting */
390 #define WSLUA_ARG_Prefs__index_NAME 2 /* The abbreviation of this preference */
392 Pref prefs_p = checkPrefs(L,1);
393 const gchar* name = luaL_checkstring(L,WSLUA_ARG_Prefs__index_NAME);
395 if (! ( name && prefs_p ) ) return 0;
397 prefs_p = prefs_p->next;
399 do {
400 if ( g_str_equal(prefs_p->name,name) ) {
401 switch (prefs_p->type) {
402 case PREF_BOOL: lua_pushboolean(L, prefs_p->value.b); break;
403 case PREF_UINT: lua_pushnumber(L,(lua_Number)prefs_p->value.u); break;
404 case PREF_STRING: lua_pushstring(L,prefs_p->value.s); break;
405 case PREF_ENUM: lua_pushnumber(L,(lua_Number)prefs_p->value.e); break;
406 case PREF_RANGE: lua_pushstring(L,range_convert_range(prefs_p->value.r)); break;
407 default: WSLUA_ERROR(Prefs__index,"Unknow Pref type");
409 WSLUA_RETURN(1); /* The current value of the preference */
411 } while (( prefs_p = prefs_p->next ));
413 WSLUA_ARG_ERROR(Prefs__index,NAME,"no preference named like this");
416 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
417 static int Prefs__gc(lua_State* L _U_) {
418 /* do NOT free Prefs, it's never free'd */
419 return 0;
422 WSLUA_META Prefs_meta[] = {
423 {"__newindex", Prefs__newindex},
424 {"__index", Prefs__index},
425 {0,0}
428 WSLUA_REGISTER Prefs_register(lua_State* L) {
429 WSLUA_REGISTER_META(Prefs);
430 return 1;
433 WSLUA_CLASS_DEFINE(ProtoField,FAIL_ON_NULL("null ProtoField"),NOP);
434 /* A Protocol field (to be used when adding items to the dissection tree) */
436 static const wslua_ft_types_t ftenums[] = {
437 {"ftypes.BOOLEAN", FT_BOOLEAN},
438 {"ftypes.UINT8", FT_UINT8},
439 {"ftypes.UINT16", FT_UINT16},
440 {"ftypes.UINT24", FT_UINT24},
441 {"ftypes.UINT32", FT_UINT32},
442 {"ftypes.UINT64", FT_UINT64},
443 {"ftypes.INT8", FT_INT8},
444 {"ftypes.INT16", FT_INT16},
445 {"ftypes.INT24", FT_INT24},
446 {"ftypes.INT32", FT_INT32},
447 {"ftypes.INT64", FT_INT64},
448 {"ftypes.FLOAT", FT_FLOAT},
449 {"ftypes.DOUBLE", FT_DOUBLE},
450 {"ftypes.ABSOLUTE_TIME", FT_ABSOLUTE_TIME},
451 {"ftypes.RELATIVE_TIME", FT_RELATIVE_TIME},
452 {"ftypes.STRING", FT_STRING},
453 {"ftypes.STRINGZ", FT_STRINGZ},
454 {"ftypes.ETHER", FT_ETHER},
455 {"ftypes.BYTES", FT_BYTES},
456 {"ftypes.UINT_BYTES", FT_UINT_BYTES},
457 {"ftypes.IPv4", FT_IPv4},
458 {"ftypes.IPv6", FT_IPv6},
459 {"ftypes.IPXNET", FT_IPXNET},
460 {"ftypes.FRAMENUM", FT_FRAMENUM},
461 {"ftypes.GUID", FT_GUID},
462 {"ftypes.OID", FT_OID},
463 {"ftypes.REL_OID", FT_REL_OID},
464 {NULL, FT_NONE}
467 static enum ftenum get_ftenum(const gchar* type) {
468 const wslua_ft_types_t* ts;
469 for (ts = ftenums; ts->str; ts++) {
470 if ( g_str_equal(ts->str,type) ) {
471 return ts->id;
474 return FT_NONE;
477 static const gchar* ftenum_to_string(enum ftenum ft) {
478 const wslua_ft_types_t* ts;
479 for (ts = ftenums; ts->str; ts++) {
480 if ( ts->id == ft ) {
481 return ts->str;
484 return NULL;
487 struct base_display_string_t {
488 const gchar* str;
489 unsigned base;
492 static const struct base_display_string_t base_displays[] = {
493 {"base.NONE", BASE_NONE},
494 {"base.DEC", BASE_DEC},
495 {"base.HEX", BASE_HEX},
496 {"base.OCT", BASE_OCT},
497 {"base.DEC_HEX", BASE_DEC_HEX},
498 {"base.HEX_DEC", BASE_HEX_DEC},
499 /* for FT_BOOLEAN, how wide the parent bitfield is */
500 {"8",8},
501 {"16",16},
502 {"24",24},
503 {"32",32},
504 /* for FT_ABSOLUTE_TIME use values in absolute_time_display_e */
505 {"LOCAL", ABSOLUTE_TIME_LOCAL},
506 {"UTC", ABSOLUTE_TIME_UTC},
507 {"DOY_UTC", ABSOLUTE_TIME_DOY_UTC},
508 {NULL,0}
511 static const gchar* base_to_string(unsigned base) {
512 const struct base_display_string_t* b;
513 for (b=base_displays;b->str;b++) {
514 if ( base == b->base)
515 return b->str;
517 return NULL;
520 static unsigned string_to_base(const gchar* str) {
521 const struct base_display_string_t* b;
522 for (b=base_displays;b->str;b++) {
523 if ( g_str_equal(str,b->str))
524 return b->base;
526 return BASE_NONE;
529 static value_string* value_string_from_table(lua_State* L, int idx) {
530 GArray* vs = g_array_new(TRUE,TRUE,sizeof(value_string));
531 value_string* ret;
533 if(lua_isnil(L,idx)) {
534 return NULL;
535 } else if (!lua_istable(L,idx)) {
536 luaL_argerror(L,idx,"must be a table");
537 g_array_free(vs,TRUE);
538 return NULL;
541 lua_pushnil(L);
543 while (lua_next(L, idx) != 0) {
544 value_string v = {0,NULL};
546 if (! lua_isnumber(L,-2)) {
547 luaL_argerror(L,idx,"All keys of a table used as value_string must be integers");
548 g_array_free(vs,TRUE);
549 return NULL;
552 if (! lua_isstring(L,-1)) {
553 luaL_argerror(L,idx,"All values of a table used as value_string must be strings");
554 g_array_free(vs,TRUE);
555 return NULL;
558 v.value = (guint32)lua_tonumber(L,-2);
559 v.strptr = g_strdup(lua_tostring(L,-1));
561 g_array_append_val(vs,v);
563 lua_pop(L, 1);
566 ret = (value_string*)vs->data;
568 g_array_free(vs,FALSE);
570 return ret;
573 static val64_string* val64_string_from_table(lua_State* L, int idx) {
574 GArray* vs = g_array_new(TRUE,TRUE,sizeof(val64_string));
575 val64_string* ret;
577 if(lua_isnil(L,idx)) {
578 return NULL;
579 } else if (!lua_istable(L,idx)) {
580 luaL_argerror(L,idx,"must be a table");
581 g_array_free(vs,TRUE);
582 return NULL;
585 lua_pushnil(L);
587 while (lua_next(L, idx) != 0) {
588 val64_string v = {0,NULL};
590 if (! lua_isnumber(L,-2)) {
591 luaL_argerror(L,idx,"All keys of a table used as value string must be integers");
592 g_array_free(vs,TRUE);
593 return NULL;
596 if (! lua_isstring(L,-1)) {
597 luaL_argerror(L,idx,"All values of a table used as value string must be strings");
598 g_array_free(vs,TRUE);
599 return NULL;
602 v.value = (guint64)lua_tonumber(L, -2);
603 v.strptr = g_strdup(lua_tostring(L,-1));
605 g_array_append_val(vs,v);
607 lua_pop(L, 1);
610 ret = (val64_string*)vs->data;
612 g_array_free(vs,FALSE);
614 return ret;
617 static true_false_string* true_false_string_from_table(lua_State* L, int idx) {
618 GArray* tfs = g_array_new(TRUE,TRUE,sizeof(true_false_string));
619 true_false_string* ret;
620 true_false_string tf = { "True", "False" };
622 if (lua_isnil(L,idx)) {
623 return NULL;
624 } else if (!lua_istable(L,idx)) {
625 luaL_argerror(L,idx,"must be a table");
626 g_array_free(tfs,TRUE);
627 return NULL;
630 lua_pushnil(L);
632 while (lua_next(L, idx)) {
634 if (! lua_isnumber(L,-2)) {
635 luaL_argerror(L,idx,"All keys of a table used as true_false_string must be integers");
636 g_array_free(tfs,TRUE);
637 return NULL;
640 if (! lua_isstring(L,-1)) {
641 luaL_argerror(L,idx,"All values of a table used as true_false_string must be strings");
642 g_array_free(tfs,TRUE);
643 return NULL;
646 /* arrays in LUA start with index number 1 */
647 if ((guint32)lua_tonumber(L,-2) == 1)
648 tf.true_string = g_strdup(lua_tostring(L,-1));
650 if ((guint32)lua_tonumber(L,-2) == 2)
651 tf.false_string = g_strdup(lua_tostring(L,-1));
653 lua_pop(L, 1);
656 g_array_append_val(tfs,tf);
658 ret = (true_false_string*)tfs->data;
660 g_array_free(tfs,FALSE);
662 return ret;
665 WSLUA_CONSTRUCTOR ProtoField_new(lua_State* L) { /* Creates a new field to be used in a protocol. */
666 #define WSLUA_ARG_ProtoField_new_NAME 1 /* Actual name of the field (the string that appears in the tree). */
667 #define WSLUA_ARG_ProtoField_new_ABBR 2 /* Filter name of the field (the string that is used in filters). */
668 #define WSLUA_ARG_ProtoField_new_TYPE 3 /* Field Type: one of ftypes.NONE, ftypes.PROTOCOL, ftypes.BOOLEAN,
669 ftypes.UINT8, ftypes.UINT16, ftypes.UINT24, ftypes.UINT32, ftypes.UINT64, ftypes.INT8, ftypes.INT16
670 ftypes.INT24, ftypes.INT32, ftypes.INT64, ftypes.FLOAT, ftypes.DOUBLE, ftypes.ABSOLUTE_TIME
671 ftypes.RELATIVE_TIME, ftypes.STRING, ftypes.STRINGZ, ftypes.UINT_STRING, ftypes.ETHER, ftypes.BYTES
672 ftypes.UINT_BYTES, ftypes.IPv4, ftypes.IPv6, ftypes.IPXNET, ftypes.FRAMENUM, ftypes.PCRE, ftypes.GUID
673 ftypes.OID, ftypes.EUI64 */
674 #define WSLUA_OPTARG_ProtoField_new_VOIDSTRING 4 /* A VoidString object. */
675 #define WSLUA_OPTARG_ProtoField_new_BASE 5 /* The representation: one of base.NONE, base.DEC, base.HEX, base.OCT, base.DEC_HEX, base.HEX_DEC */
676 #define WSLUA_OPTARG_ProtoField_new_MASK 6 /* The bitmask to be used. */
677 #define WSLUA_OPTARG_ProtoField_new_DESCR 7 /* The description of the field. */
679 ProtoField f = (wslua_field_t *)g_malloc(sizeof(wslua_field_t));
680 value_string *vs32 = NULL;
681 val64_string *vs64 = NULL;
682 true_false_string *tfs = NULL;
683 const gchar *blob;
685 /* will be using -2 as far as the field has not been added to an array then it will turn -1 */
686 f->hfid = -2;
687 f->ett = -1;
688 f->name = g_strdup(luaL_checkstring(L,WSLUA_ARG_ProtoField_new_NAME));
689 f->abbr = g_strdup(luaL_checkstring(L,WSLUA_ARG_ProtoField_new_ABBR));
690 f->type = get_ftenum(luaL_checkstring(L,WSLUA_ARG_ProtoField_new_TYPE));
692 /*XXX do it better*/
693 if (f->type == FT_NONE) {
694 g_free(f->name);
695 g_free(f->abbr);
696 g_free(f);
697 WSLUA_ARG_ERROR(ProtoField_new,TYPE,"invalid ftypes");
700 if (!f->abbr || !f->abbr[0]) {
701 WSLUA_ARG_ERROR(ProtoField_new,ABBR,"Missing abbrev");
704 if (proto_check_field_name(f->abbr)) {
705 g_free(f->name);
706 g_free(f->abbr);
707 g_free(f);
708 WSLUA_ARG_ERROR(ProtoField_new,ABBR,"Invalid char in abbrev");
711 if (! lua_isnil(L,WSLUA_OPTARG_ProtoField_new_VOIDSTRING) ) {
712 if (f->type == FT_BOOLEAN) {
713 tfs = true_false_string_from_table(L,WSLUA_OPTARG_ProtoField_new_VOIDSTRING);
715 else if (f->type == FT_UINT64 || f->type == FT_INT64) {
716 vs64 = val64_string_from_table(L,WSLUA_OPTARG_ProtoField_new_VOIDSTRING);
718 else {
719 vs32 = value_string_from_table(L,WSLUA_OPTARG_ProtoField_new_VOIDSTRING);
722 if (vs32) {
723 f->vs = VALS(vs32);
724 } else if (tfs) {
725 f->vs = TFS(tfs);
726 } else if (vs64) {
727 f->vs = VALS(vs64);
728 } else {
729 g_free(f->name);
730 g_free(f->abbr);
731 g_free(f);
732 return 0;
735 } else {
736 f->vs = NULL;
739 /* XXX: need BASE_ERROR */
740 f->base = string_to_base(luaL_optstring(L, WSLUA_OPTARG_ProtoField_new_BASE, "BASE_NONE"));
741 if (vs64) {
742 /* Indicate that we are using val64_string */
743 f->base |= BASE_VAL64_STRING;
745 f->mask = (guint32)luaL_optnumber(L, WSLUA_OPTARG_ProtoField_new_MASK, 0x0);
746 blob = luaL_optstring(L,WSLUA_OPTARG_ProtoField_new_DESCR,NULL);
747 if (blob && strcmp(blob, f->name) != 0) {
748 f->blob = g_strdup(blob);
749 } else {
750 f->blob = NULL;
753 pushProtoField(L,f);
755 WSLUA_RETURN(1); /* The newly created ProtoField object */
758 static int ProtoField_integer(lua_State* L, enum ftenum type) {
759 ProtoField f;
760 const gchar* abbr = luaL_checkstring(L,1);
761 const gchar* name = luaL_optstring(L,2,abbr);
762 unsigned base = luaL_optint(L, 3, BASE_DEC);
763 value_string* vs32 = NULL;
764 val64_string* vs64 = NULL;
765 guint32 mask = (guint32)luaL_optnumber(L,5,0);
766 const gchar* blob = luaL_optstring(L,6,NULL);
768 if (lua_gettop(L) > 3) {
769 if (type == FT_UINT64 || type == FT_INT64) {
770 vs64 = val64_string_from_table(L,4);
771 } else {
772 vs32 = value_string_from_table(L,4);
776 if (type == FT_FRAMENUM) {
777 if (base != BASE_NONE)
778 luaL_argerror(L, 3, "ftypes.FRAMENUMs must use base.NONE");
779 else if (mask)
780 luaL_argerror(L, 3, "ftypes.FRAMENUMs can not have a bitmask");
781 } else if (base < BASE_DEC || base > BASE_HEX_DEC) {
782 luaL_argerror(L, 3, "Base must be either base.DEC, base.HEX, base.OCT,"
783 " base.DEC_HEX, base.DEC_HEX or base.HEX_DEC");
784 return 0;
785 } else if ((base == BASE_HEX || base == BASE_OCT) &&
786 (type == FT_INT8 || type == FT_INT16 || type == FT_INT24 || type == FT_INT32 || type == FT_INT64)) {
787 luaL_argerror(L, 3, "This type does not display as hexadecimal");
788 return 0;
791 if (!abbr || !abbr[0]) {
792 luaL_argerror(L, 1, "Missing abbrev");
793 return 0;
796 if (proto_check_field_name(abbr)) {
797 luaL_argerror(L, 1, "Invalid char in abbrev");
798 return 0;
801 f = g_new(wslua_field_t,1);
803 f->hfid = -2;
804 f->ett = -1;
805 f->name = g_strdup(name);
806 f->abbr = g_strdup(abbr);
807 f->type = type;
808 f->base = base;
809 if (vs64) {
810 /* Indicate that we are using val64_string */
811 f->base |= BASE_VAL64_STRING;
812 f->vs = VALS(vs64);
813 } else {
814 f->vs = VALS(vs32);
816 f->mask = mask;
817 if (blob && strcmp(blob, f->name) != 0) {
818 f->blob = g_strdup(blob);
819 } else {
820 f->blob = NULL;
823 pushProtoField(L,f);
825 return 1;
828 #define PROTOFIELD_INTEGER(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_integer(L,FT); }
829 /* _WSLUA_CONSTRUCTOR_ ProtoField_uint8 */
830 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
831 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
832 /* WSLUA_OPTARG_Protofield_uint8_BASE One of base.DEC, base.HEX or base.OCT */
833 /* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values */
834 /* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field */
835 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
836 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
838 /* _WSLUA_CONSTRUCTOR_ ProtoField_uint16 */
839 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
840 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
841 /* WSLUA_OPTARG_Protofield_uint8_BASE One of base.DEC, base.HEX or base.OCT */
842 /* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values */
843 /* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field */
844 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
845 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
847 /* _WSLUA_CONSTRUCTOR_ ProtoField_uint24 */
848 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
849 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
850 /* WSLUA_OPTARG_Protofield_uint8_BASE One of base.DEC, base.HEX or base.OCT */
851 /* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values */
852 /* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field */
853 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
854 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
856 /* _WSLUA_CONSTRUCTOR_ ProtoField_uint32 */
857 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
858 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
859 /* WSLUA_OPTARG_Protofield_uint8_BASE One of base.DEC, base.HEX or base.OCT */
860 /* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values */
861 /* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field */
862 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
863 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
865 /* _WSLUA_CONSTRUCTOR_ ProtoField_uint64 */
866 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
867 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
868 /* WSLUA_OPTARG_Protofield_uint8_BASE One of base.DEC, base.HEX or base.OCT */
869 /* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values */
870 /* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field */
871 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
872 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
874 /* _WSLUA_CONSTRUCTOR_ ProtoField_int8 */
875 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
876 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
877 /* WSLUA_OPTARG_Protofield_uint8_BASE One of base.DEC, base.HEX or base.OCT */
878 /* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values */
879 /* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field */
880 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
881 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
883 /* _WSLUA_CONSTRUCTOR_ ProtoField_int16 */
884 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
885 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
886 /* WSLUA_OPTARG_Protofield_uint8_BASE One of base.DEC, base.HEX or base.OCT */
887 /* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values */
888 /* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field */
889 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
890 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
892 /* _WSLUA_CONSTRUCTOR_ ProtoField_int24 */
893 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
894 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
895 /* WSLUA_OPTARG_Protofield_uint8_BASE One of base.DEC, base.HEX or base.OCT */
896 /* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values */
897 /* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field */
898 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
899 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
901 /* _WSLUA_CONSTRUCTOR_ ProtoField_int32 */
902 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
903 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
904 /* WSLUA_OPTARG_Protofield_uint8_BASE One of base.DEC, base.HEX or base.OCT */
905 /* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values */
906 /* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field */
907 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
908 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
910 /* _WSLUA_CONSTRUCTOR_ ProtoField_int64 */
911 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
912 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
913 /* WSLUA_OPTARG_Protofield_uint8_BASE One of base.DEC, base.HEX or base.OCT */
914 /* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values */
915 /* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field */
916 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
917 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
919 /* _WSLUA_CONSTRUCTOR_ ProtoField_framenum A frame number (for hyperlinks between frames) */
920 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
921 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
922 /* WSLUA_OPTARG_Protofield_uint8_BASE One of base.DEC, base.HEX or base.OCT */
923 /* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values */
924 /* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field */
925 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
926 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
928 PROTOFIELD_INTEGER(uint8,FT_UINT8)
929 PROTOFIELD_INTEGER(uint16,FT_UINT16)
930 PROTOFIELD_INTEGER(uint24,FT_UINT24)
931 PROTOFIELD_INTEGER(uint32,FT_UINT32)
932 PROTOFIELD_INTEGER(uint64,FT_UINT64)
933 PROTOFIELD_INTEGER(int8,FT_INT8)
934 PROTOFIELD_INTEGER(int16,FT_INT16)
935 PROTOFIELD_INTEGER(int24,FT_INT24)
936 PROTOFIELD_INTEGER(int32,FT_INT32)
937 PROTOFIELD_INTEGER(int64,FT_INT64)
938 PROTOFIELD_INTEGER(framenum,FT_FRAMENUM)
940 static int ProtoField_boolean(lua_State* L, enum ftenum type) {
941 ProtoField f;
942 const gchar* abbr = luaL_checkstring(L,1);
943 const gchar* name = luaL_optstring(L,2,abbr);
944 unsigned base = luaL_optint(L, 3, BASE_NONE);
945 true_false_string* tfs = (lua_gettop(L) > 3) ? true_false_string_from_table(L,4) : NULL;
946 guint32 mask = (guint32)luaL_optnumber(L,5,0);
947 const gchar* blob = luaL_optstring(L,6,NULL);
949 if (mask == 0x0 && base != BASE_NONE) {
950 luaL_argerror(L,2,"Fieldbase (fielddisplay) must be base.NONE"
951 " if bitmask is zero.");
952 return 0;
955 if (mask != 0x0 && (base < 1 || base > 64)) {
956 luaL_argerror(L,2,"Fieldbase (fielddisplay) must be between 1 and 64"
957 " if bitmask is non-zero.");
958 return 0;
961 if (!abbr || !abbr[0]) {
962 luaL_argerror(L,1,"Missing abbrev");
963 return 0;
966 if (proto_check_field_name(abbr)) {
967 luaL_argerror(L,1,"Invalid char in abbrev");
968 return 0;
971 f = g_new(wslua_field_t,1);
973 f->hfid = -2;
974 f->ett = -1;
975 f->name = g_strdup(name);
976 f->abbr = g_strdup(abbr);
977 f->type = type;
978 f->vs = TFS(tfs);
979 f->base = base;
980 f->mask = mask;
981 if (blob && strcmp(blob, f->name) != 0) {
982 f->blob = g_strdup(blob);
983 } else {
984 f->blob = NULL;
987 pushProtoField(L,f);
989 return 1;
992 #define PROTOFIELD_BOOL(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_boolean(L,FT); }
993 /* _WSLUA_CONSTRUCTOR_ ProtoField_bool */
994 /* WSLUA_ARG_Protofield_bool_ABBR Abbreviated name of the field (the string used in filters) */
995 /* WSLUA_OPTARG_Protofield_bool_NAME Actual name of the field (the string that appears in the tree) */
996 /* WSLUA_OPTARG_Protofield_bool_DISPLAY how wide the parent bitfield is (base.NONE is used for NULL-value) */
997 /* WSLUA_OPTARG_Protofield_bool_TRUE_FALSE_STRING A table containing the text that corresponds to the values */
998 /* WSLUA_OPTARG_Protofield_bool_MASK Integer mask of this field */
999 /* WSLUA_OPTARG_Protofield_bool_DESC Description of the field */
1000 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1002 /* XXX: T/F strings */
1003 PROTOFIELD_BOOL(bool,FT_BOOLEAN)
1005 static int ProtoField_time(lua_State* L,enum ftenum type) {
1006 ProtoField f;
1007 const gchar* abbr = luaL_checkstring(L,1);
1008 const gchar* name = luaL_optstring(L,2,abbr);
1009 unsigned base = luaL_optint(L,3,ABSOLUTE_TIME_LOCAL);
1010 const gchar* blob = luaL_optstring(L,4,NULL);
1012 if (!abbr || !abbr[0]) {
1013 luaL_argerror(L,1,"Missing abbrev");
1014 return 0;
1017 if (proto_check_field_name(abbr)) {
1018 luaL_argerror(L,1,"Invalid char in abbrev");
1019 return 0;
1022 if (type == FT_ABSOLUTE_TIME) {
1023 if (base < ABSOLUTE_TIME_LOCAL || base > ABSOLUTE_TIME_DOY_UTC) {
1024 luaL_argerror(L, 3, "Base must be either LOCAL, UTC, or DOY_UTC");
1025 return 0;
1029 f = g_new(wslua_field_t,1);
1031 f->hfid = -2;
1032 f->ett = -1;
1033 f->name = g_strdup(name);
1034 f->abbr = g_strdup(abbr);
1035 f->type = type;
1036 f->vs = NULL;
1037 f->base = base;
1038 f->mask = 0;
1039 if (blob && strcmp(blob, f->name) != 0) {
1040 f->blob = g_strdup(blob);
1041 } else {
1042 f->blob = NULL;
1045 pushProtoField(L,f);
1047 return 1;
1050 #define PROTOFIELD_TIME(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_time(L,FT); }
1051 /* _WSLUA_CONSTRUCTOR_ ProtoField_absolute_time */
1052 /* WSLUA_ARG_Protofield_absolute_time_ABBR Abbreviated name of the field (the string used in filters) */
1053 /* WSLUA_OPTARG_Protofield_absolute_time_NAME Actual name of the field (the string that appears in the tree) */
1054 /* WSLUA_OPTARG_Protofield_absolute_time_BASE One of base.LOCAL, base.UTC or base.DOY_UTC */
1055 /* WSLUA_OPTARG_Protofield_absolute_time_DESC Description of the field */
1056 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1058 /* _WSLUA_CONSTRUCTOR_ ProtoField_relative_time */
1059 /* WSLUA_ARG_Protofield_relative_ABBR Abbreviated name of the field (the string used in filters) */
1060 /* WSLUA_OPTARG_Protofield_relative_NAME Actual name of the field (the string that appears in the tree) */
1061 /* WSLUA_OPTARG_Protofield_relative_DESC Description of the field */
1062 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1065 PROTOFIELD_TIME(absolute_time,FT_ABSOLUTE_TIME)
1067 static int ProtoField_other(lua_State* L,enum ftenum type) {
1068 ProtoField f;
1069 const gchar* abbr = luaL_checkstring(L,1);
1070 const gchar* name = luaL_optstring(L,2,abbr);
1071 const gchar* blob = luaL_optstring(L,3,NULL);
1073 if (!abbr || !abbr[0]) {
1074 luaL_argerror(L,1,"Missing abbrev");
1075 return 0;
1078 if (proto_check_field_name(abbr)) {
1079 luaL_argerror(L,1,"Invalid char in abbrev");
1080 return 0;
1083 f = g_new(wslua_field_t,1);
1085 f->hfid = -2;
1086 f->ett = -1;
1087 f->name = g_strdup(name);
1088 f->abbr = g_strdup(abbr);
1089 f->type = type;
1090 f->vs = NULL;
1091 f->base = BASE_NONE;
1092 f->mask = 0;
1093 if (blob && strcmp(blob, f->name) != 0) {
1094 f->blob = g_strdup(blob);
1095 } else {
1096 f->blob = NULL;
1099 pushProtoField(L,f);
1101 return 1;
1104 #define PROTOFIELD_OTHER(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_other(L,FT); }
1105 /* _WSLUA_CONSTRUCTOR_ ProtoField_ipv4 */
1106 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
1107 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
1108 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
1109 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1111 /* _WSLUA_CONSTRUCTOR_ ProtoField_ipv6 */
1112 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
1113 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
1114 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
1115 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1117 /* _WSLUA_CONSTRUCTOR_ ProtoField_ether */
1118 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
1119 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
1120 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
1121 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1123 /* _WSLUA_CONSTRUCTOR_ ProtoField_float */
1124 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
1125 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
1126 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
1127 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1129 /* _WSLUA_CONSTRUCTOR_ ProtoField_double */
1130 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
1131 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
1132 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
1133 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1135 /* _WSLUA_CONSTRUCTOR_ ProtoField_string */
1136 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
1137 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
1138 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
1139 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1141 /* _WSLUA_CONSTRUCTOR_ ProtoField_stringz */
1142 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
1143 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
1144 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
1145 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1147 /* _WSLUA_CONSTRUCTOR_ ProtoField_bytes */
1148 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
1149 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
1150 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
1151 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1153 /* _WSLUA_CONSTRUCTOR_ ProtoField_ubytes */
1154 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
1155 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
1156 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
1157 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1159 /* _WSLUA_CONSTRUCTOR_ ProtoField_guid */
1160 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
1161 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
1162 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
1163 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1165 /* _WSLUA_CONSTRUCTOR_ ProtoField_oid */
1166 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
1167 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
1168 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
1169 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1171 /* _WSLUA_CONSTRUCTOR_ ProtoField_bool */
1172 /* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters) */
1173 /* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree) */
1174 /* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field */
1175 /* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */
1177 PROTOFIELD_OTHER(ipv4,FT_IPv4)
1178 PROTOFIELD_OTHER(ipv6,FT_IPv6)
1179 PROTOFIELD_OTHER(ipx,FT_IPXNET)
1180 PROTOFIELD_OTHER(ether,FT_ETHER)
1181 PROTOFIELD_OTHER(float,FT_FLOAT)
1182 PROTOFIELD_OTHER(double,FT_DOUBLE)
1183 PROTOFIELD_OTHER(relative_time,FT_RELATIVE_TIME)
1184 PROTOFIELD_OTHER(string,FT_STRING)
1185 PROTOFIELD_OTHER(stringz,FT_STRINGZ)
1186 PROTOFIELD_OTHER(bytes,FT_BYTES)
1187 PROTOFIELD_OTHER(ubytes,FT_UINT_BYTES)
1188 PROTOFIELD_OTHER(guid,FT_GUID)
1189 PROTOFIELD_OTHER(oid,FT_OID)
1190 PROTOFIELD_OTHER(rel_oid,FT_REL_OID)
1192 WSLUA_METAMETHOD ProtoField__tostring(lua_State* L) {
1193 /* Returns a string with info about a protofield (for debugging purposes) */
1194 ProtoField f = checkProtoField(L,1);
1195 gchar* s = (gchar *)ep_strdup_printf("ProtoField(%i): %s %s %s %s %p %.8x %s",f->hfid,f->name,f->abbr,ftenum_to_string(f->type),base_to_string(f->base),f->vs,f->mask,f->blob);
1196 lua_pushstring(L,s);
1197 return 1;
1200 static int ProtoField__gc(lua_State* L) {
1201 ProtoField f = checkProtoField(L,1);
1204 * A garbage collector for ProtoFields makes little sense.
1205 * Even if This cannot be used anymore because it has gone out of scope,
1206 * we can destroy the ProtoField only if it is not part of a ProtoFieldArray,
1207 * if it actualy belongs to one we need to preserve it as it is pointed by
1208 * a field array that may be registered afterwards causing a crash or memory corruption.
1211 if (!f) {
1212 luaL_argerror(L,1,"BUG: ProtoField_gc called for something not ProtoField");
1213 /* g_assert() ?? */
1214 } else if (f->hfid == -2) {
1215 g_free(f->name);
1216 g_free(f->abbr);
1217 g_free(f->blob);
1218 g_free(f);
1221 return 0;
1224 static const luaL_Reg ProtoField_methods[] = {
1225 {"new", ProtoField_new},
1226 {"uint8",ProtoField_uint8},
1227 {"uint16",ProtoField_uint16},
1228 {"uint24",ProtoField_uint24},
1229 {"uint32",ProtoField_uint32},
1230 {"uint64",ProtoField_uint64},
1231 {"int8",ProtoField_int8},
1232 {"int16",ProtoField_int16},
1233 {"int24",ProtoField_int24},
1234 {"int32",ProtoField_int32},
1235 {"int64",ProtoField_int64},
1236 {"framenum",ProtoField_framenum},
1237 {"ipv4",ProtoField_ipv4},
1238 {"ipv6",ProtoField_ipv6},
1239 {"ipx",ProtoField_ipx},
1240 {"ether",ProtoField_ether},
1241 {"bool",ProtoField_bool},
1242 {"float",ProtoField_float},
1243 {"double",ProtoField_double},
1244 {"absolute_time",ProtoField_absolute_time},
1245 {"relative_time",ProtoField_relative_time},
1246 {"string",ProtoField_string},
1247 {"stringz",ProtoField_stringz},
1248 {"bytes",ProtoField_bytes},
1249 {"ubytes",ProtoField_ubytes},
1250 {"guid",ProtoField_guid},
1251 {"oid",ProtoField_oid},
1252 {"rel_oid",ProtoField_rel_oid},
1253 { NULL, NULL }
1256 static const luaL_Reg ProtoField_meta[] = {
1257 {"__tostring", ProtoField__tostring },
1258 { NULL, NULL }
1261 int ProtoField_register(lua_State* L) {
1262 WSLUA_REGISTER_CLASS(ProtoField);
1263 return 1;
1266 WSLUA_CLASS_DEFINE(Proto,NOP,NOP);
1268 A new protocol in wireshark. Protocols have more uses, the main one is to dissect
1269 a protocol. But they can be just dummies used to register preferences for
1270 other purposes.
1273 static int protocols_table_ref = LUA_NOREF;
1275 WSLUA_CONSTRUCTOR Proto_new(lua_State* L) {
1276 #define WSLUA_ARG_Proto_new_NAME 1 /* The name of the protocol */
1277 #define WSLUA_ARG_Proto_new_DESC 2 /* A Long Text description of the protocol (usually lowercase) */
1278 const gchar* name = luaL_checkstring(L,WSLUA_ARG_Proto_new_NAME);
1279 const gchar* desc = luaL_checkstring(L,WSLUA_ARG_Proto_new_DESC);
1281 if ( name ) {
1282 gchar* loname_a;
1283 int proto_id;
1285 loname_a = g_ascii_strdown(name, -1);
1286 proto_id = proto_get_id_by_filter_name(loname_a);
1287 g_free(loname_a);
1288 if ( proto_id > 0 ) {
1289 WSLUA_ARG_ERROR(Proto_new,NAME,"there cannot be two protocols with the same name");
1290 } else {
1291 Proto proto = (wslua_proto_t *)g_malloc(sizeof(wslua_proto_t));
1292 gchar* loname = g_ascii_strdown(name, -1);
1293 gchar* hiname = g_ascii_strup(name, -1);
1295 proto->name = hiname;
1296 proto->desc = g_strdup(desc);
1297 proto->hfid = proto_register_protocol(proto->desc,hiname,loname);
1298 proto->ett = -1;
1299 proto->is_postdissector = FALSE;
1301 lua_newtable (L);
1302 proto->fields = luaL_ref(L, LUA_REGISTRYINDEX);
1304 proto->prefs.name = NULL;
1305 proto->prefs.label = NULL;
1306 proto->prefs.desc = NULL;
1307 proto->prefs.value.u = 0;
1308 proto->prefs.next = NULL;
1309 proto->prefs.proto = proto;
1311 proto->prefs_module = NULL;
1312 proto->handle = NULL;
1314 lua_rawgeti(L, LUA_REGISTRYINDEX, protocols_table_ref);
1316 lua_pushstring(L,loname);
1317 pushProto(L,proto);
1319 lua_settable(L, -3);
1321 pushProto(L,proto);
1323 WSLUA_RETURN(1); /* The newly created protocol */
1325 } else
1326 WSLUA_ARG_ERROR(Proto_new,NAME,"must be a string");
1328 return 0;
1331 static int Proto_tostring(lua_State* L) {
1332 Proto proto = checkProto(L,1);
1333 gchar* s;
1335 if (!proto) return 0;
1337 s = ep_strdup_printf("Proto: %s",proto->name);
1338 lua_pushstring(L,s);
1340 return 1;
1343 WSLUA_FUNCTION wslua_register_postdissector(lua_State* L) {
1344 /* Make a protocol (with a dissector) a postdissector. It will be called for every frame after dissection */
1345 #define WSLUA_ARG_register_postdissector_PROTO 1 /* the protocol to be used as postdissector */
1346 Proto proto = checkProto(L,WSLUA_ARG_register_postdissector_PROTO);
1347 if (!proto) return 0;
1349 if(!proto->is_postdissector) {
1350 if (! proto->handle) {
1351 proto->handle = new_create_dissector_handle(dissect_lua, proto->hfid);
1354 register_postdissector(proto->handle);
1355 } else {
1356 luaL_argerror(L,1,"this protocol is already registered as postdissector");
1359 return 0;
1362 static int Proto_get_dissector(lua_State* L) {
1363 Proto proto = toProto(L,1);
1365 if (proto->handle) {
1366 pushDissector(L,proto->handle);
1367 return 1;
1368 } else {
1369 luaL_error(L,"The protocol hasn't been registered yet");
1370 return 0;
1374 static int Proto_set_dissector(lua_State* L) {
1375 Proto proto = toProto(L,1);
1377 if (lua_isfunction(L,3)) {
1378 /* insert the dissector into the dissectors table */
1379 gchar* loname = g_ascii_strdown(proto->name, -1);
1381 lua_rawgeti(L, LUA_REGISTRYINDEX, lua_dissectors_table_ref);
1382 lua_replace(L, 1);
1383 lua_pushstring(L,proto->name);
1384 lua_replace(L, 2);
1385 lua_settable(L,1);
1387 proto->handle = new_create_dissector_handle(dissect_lua, proto->hfid);
1389 new_register_dissector(loname, dissect_lua, proto->hfid);
1391 return 0;
1392 } else {
1393 luaL_argerror(L,3,"The dissector of a protocol must be a function");
1394 return 0;
1398 static int Proto_get_prefs(lua_State* L) {
1399 Proto proto = toProto(L,1);
1400 pushPrefs(L,&proto->prefs);
1401 return 1;
1404 static int Proto_set_prefs_changed(lua_State* L) {
1405 Proto proto = toProto(L,1);
1407 if (lua_isfunction(L,3)) {
1408 /* insert the prefs changed callback into the prefs_changed table */
1409 lua_getglobal(L, WSLUA_PREFS_CHANGED);
1410 lua_replace(L, 1);
1411 lua_pushstring(L,proto->name);
1412 lua_replace(L, 2);
1413 lua_settable(L,1);
1415 } else {
1416 luaL_argerror(L,3,"The prefs of a protocol must be a function");
1418 return 0;
1421 static int Proto_set_init(lua_State* L) {
1422 Proto proto = toProto(L,1);
1424 if (lua_isfunction(L,3)) {
1425 /* insert the init routine into the init_routines table */
1426 lua_getglobal(L, WSLUA_INIT_ROUTINES);
1427 lua_replace(L, 1);
1428 lua_pushstring(L,proto->name);
1429 lua_replace(L, 2);
1430 lua_settable(L,1);
1432 return 0;
1433 } else {
1434 luaL_argerror(L,3,"The initializer of a protocol must be a function");
1435 return 0;
1439 static int Proto_get_name(lua_State* L) {
1440 Proto proto = toProto(L,1);
1441 lua_pushstring(L,proto->name);
1442 return 1;
1445 static int Proto_get_description(lua_State* L) {
1446 Proto proto = toProto(L,1);
1447 lua_pushstring(L,proto->desc);
1448 return 1;
1451 static int Proto_get_fields(lua_State* L) {
1452 Proto proto = toProto(L,1);
1453 lua_rawgeti(L, LUA_REGISTRYINDEX, proto->fields);
1454 return 1;
1457 void wslua_print_stack(char* s, lua_State* L) {
1458 int i;
1460 for (i=1;i<=lua_gettop(L);i++) {
1461 printf("%s-%i: %s\n",s,i,lua_typename (L,lua_type(L, i)));
1463 printf("\n");
1466 static int Proto_set_fields(lua_State* L) {
1467 Proto proto = toProto(L,1);
1468 #define FIELDS_TABLE 2
1469 #define NEW_TABLE 3
1470 #define NEW_FIELD 3
1472 lua_rawgeti(L, LUA_REGISTRYINDEX, proto->fields);
1473 lua_replace(L,FIELDS_TABLE);
1475 if( lua_istable(L,NEW_TABLE)) {
1476 for (lua_pushnil(L); lua_next(L, NEW_TABLE); ) {
1477 if (isProtoField(L,5)) {
1478 luaL_ref(L,FIELDS_TABLE);
1479 } else if (! lua_isnil(L,5) ) {
1480 return luaL_error(L,"only ProtoFields should be in the table");
1483 } else if (isProtoField(L,NEW_FIELD)){
1484 lua_pushvalue(L, NEW_FIELD);
1485 luaL_ref(L,FIELDS_TABLE);
1487 } else {
1488 return luaL_error(L,"either a ProtoField or an array of protofields");
1491 lua_pushvalue(L, 3);
1493 return 1;
1496 typedef struct {
1497 const gchar* name;
1498 lua_CFunction get;
1499 lua_CFunction set;
1500 } proto_actions_t;
1502 static const proto_actions_t proto_actions[] = {
1503 /* WSLUA_ATTRIBUTE Proto_dissector RW The protocol's dissector, a function you define.
1504 The called dissector function will be given three arguments of (1) a Tvb object, (2) a Pinfo object, and (3) a TreeItem object. */
1505 {"dissector", Proto_get_dissector, Proto_set_dissector},
1507 /* WSLUA_ATTRIBUTE Proto_fields RO The Fields Table of this dissector */
1508 {"fields", Proto_get_fields, Proto_set_fields},
1510 /* WSLUA_ATTRIBUTE Proto_prefs RO The preferences of this dissector */
1511 {"prefs", Proto_get_prefs, NULL},
1513 /* WSLUA_ATTRIBUTE Proto_prefs_changed WO The preferences changed routine of this dissector, a function you define. */
1514 {"prefs_changed", NULL, Proto_set_prefs_changed},
1516 /* WSLUA_ATTRIBUTE Proto_init WO The init routine of this dissector, a function you define.
1517 The called init function is passed no arguments. */
1518 {"init", NULL, Proto_set_init},
1520 /* WSLUA_ATTRIBUTE Proto_name RO The name given to this dissector */
1521 {"name", Proto_get_name, NULL},
1523 /* WSLUA_ATTRIBUTE Proto_description RO The description given to this dissector */
1524 {"description", Proto_get_description, NULL},
1526 {NULL,NULL,NULL}
1529 static int Proto_index(lua_State* L) {
1530 Proto proto = checkProto(L,1);
1531 const gchar* name = luaL_checkstring(L,2);
1532 const proto_actions_t* pa;
1534 if (! (proto && name) ) return 0;
1536 for (pa = proto_actions; pa->name; pa++) {
1537 if ( g_str_equal(name,pa->name) ) {
1538 if (pa->get) {
1539 return pa->get(L);
1540 } else {
1541 luaL_error(L,"You cannot get the `%s' attribute of a protocol",name);
1542 return 0;
1547 luaL_error(L,"A protocol doesn't have a `%s' attribute",name);
1548 return 0;
1551 static int Proto_newindex(lua_State* L) {
1552 Proto proto = checkProto(L,1);
1553 const gchar* name = luaL_checkstring(L,2);
1554 const proto_actions_t* pa;
1556 if (! (proto && name) ) return 0;
1558 for (pa = proto_actions; pa->name; pa++) {
1559 if ( g_str_equal(name,pa->name) ) {
1560 if (pa->set) {
1561 return pa->set(L);
1562 } else {
1563 luaL_error(L,"You cannot set the `%s' attribute of a protocol",name);
1564 return 0;
1569 luaL_error(L,"A protocol doesn't have a `%s' attribute",name);
1570 return 0;
1573 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
1574 static int Proto__gc(lua_State* L _U_) {
1575 /* do NOT free Proto, it's never free'd */
1576 return 0;
1579 static const luaL_Reg Proto_meta[] = {
1580 {"__tostring", Proto_tostring},
1581 {"__index", Proto_index},
1582 {"__newindex", Proto_newindex},
1583 { NULL, NULL }
1586 int Proto_register(lua_State* L) {
1588 WSLUA_REGISTER_META(Proto);
1590 lua_newtable(L);
1591 protocols_table_ref = luaL_ref(L, LUA_REGISTRYINDEX);
1593 lua_pushcfunction(L, Proto_new);
1594 lua_setglobal(L, "Proto");
1596 return 1;
1600 * Query field abbr that is defined and bound to a Proto in lua.
1601 * They are not registered untill the end of the initialization.
1603 int wslua_is_field_available(lua_State* L, const char* field_abbr) {
1604 lua_rawgeti(L, LUA_REGISTRYINDEX, protocols_table_ref);
1605 lua_pushnil(L);
1606 while (lua_next(L, -2)) {
1607 Proto proto;
1608 proto = checkProto(L, -1);
1610 lua_rawgeti(L, LUA_REGISTRYINDEX, proto->fields);
1612 lua_pushnil(L);
1613 while (lua_next(L, -2)) {
1614 ProtoField f = checkProtoField(L, -1);
1615 if (strcmp(field_abbr, f->abbr) == 0) {
1616 /* found! */
1617 lua_pop(L, 6);
1618 return 1;
1620 lua_pop(L, 1); /* table value */
1622 lua_pop(L, 2); /* proto->fields and table value */
1624 lua_pop(L, 1); /* protocols_table_ref */
1626 return 0;
1629 int Proto_commit(lua_State* L) {
1630 lua_settop(L,0);
1631 lua_rawgeti(L, LUA_REGISTRYINDEX, protocols_table_ref);
1633 for (lua_pushnil(L); lua_next(L, 1); lua_pop(L, 2)) {
1634 GArray* hfa = g_array_new(TRUE,TRUE,sizeof(hf_register_info));
1635 GArray* etta = g_array_new(TRUE,TRUE,sizeof(gint*));
1636 Proto proto;
1637 /* const gchar* proto_name = lua_tostring(L,2); */
1638 proto = checkProto(L,3);
1640 lua_rawgeti(L, LUA_REGISTRYINDEX, proto->fields);
1642 for (lua_pushnil(L); lua_next(L, 4); lua_pop(L, 1)) {
1643 ProtoField f = checkProtoField(L,6);
1644 hf_register_info hfri = { &(f->hfid), {f->name,f->abbr,f->type,f->base,VALS(f->vs),f->mask,f->blob,HFILL}};
1645 gint* ettp = &(f->ett);
1647 if (f->hfid != -2) {
1648 return luaL_error(L,"fields can be registered only once");
1651 f->hfid = -1;
1652 g_array_append_val(hfa,hfri);
1653 g_array_append_val(etta,ettp);
1656 proto_register_field_array(proto->hfid,(hf_register_info*)hfa->data,hfa->len);
1657 proto_register_subtree_array((gint**)etta->data,etta->len);
1659 g_array_free(hfa,FALSE);
1660 g_array_free(etta,FALSE);
1663 return 0;
1666 WSLUA_CLASS_DEFINE(Dissector,NOP,NOP);
1668 A refererence to a dissector, used to call a dissector against a packet or a part of it.
1671 WSLUA_CONSTRUCTOR Dissector_get (lua_State *L) {
1672 /* Obtains a dissector reference by name */
1673 #define WSLUA_ARG_Dissector_get_NAME 1 /* The name of the dissector */
1674 const gchar* name = luaL_checkstring(L,WSLUA_ARG_Dissector_get_NAME);
1675 Dissector d;
1677 if (!name)
1678 WSLUA_ARG_ERROR(Dissector_get,NAME,"must be a string");
1680 if ((d = find_dissector(name))) {
1681 pushDissector(L, d);
1682 WSLUA_RETURN(1); /* The Dissector reference */
1683 } else
1684 WSLUA_ARG_ERROR(Dissector_get,NAME,"No such dissector");
1687 WSLUA_METHOD Dissector_call(lua_State* L) {
1688 /* Calls a dissector against a given packet (or part of it) */
1689 #define WSLUA_ARG_Dissector_call_TVB 2 /* The buffer to dissect */
1690 #define WSLUA_ARG_Dissector_call_PINFO 3 /* The packet info */
1691 #define WSLUA_ARG_Dissector_call_TREE 4 /* The tree on which to add the protocol items */
1693 Dissector d = checkDissector(L,1);
1694 Tvb tvb = checkTvb(L,WSLUA_ARG_Dissector_call_TVB);
1695 Pinfo pinfo = checkPinfo(L,WSLUA_ARG_Dissector_call_PINFO);
1696 TreeItem ti = checkTreeItem(L,WSLUA_ARG_Dissector_call_TREE);
1697 const char *volatile error = NULL;
1699 if (! ( d && tvb && pinfo) ) return 0;
1701 TRY {
1702 call_dissector(d, tvb->ws_tvb, pinfo->ws_pinfo, ti->tree);
1703 /* XXX Are we sure about this??? is this the right/only thing to catch */
1704 } CATCH_NONFATAL_ERRORS {
1705 show_exception(tvb->ws_tvb, pinfo->ws_pinfo, ti->tree, EXCEPT_CODE, GET_MESSAGE);
1706 error = "Malformed frame";
1707 } ENDTRY;
1709 if (error) { WSLUA_ERROR(Dissector_call,error); }
1711 return 0;
1714 WSLUA_METAMETHOD Dissector__tostring(lua_State* L) {
1715 /* Gets the Dissector's protocol short name */
1716 Dissector d = checkDissector(L,1);
1717 if (!d) return 0;
1718 lua_pushstring(L,dissector_handle_get_short_name(d));
1719 WSLUA_RETURN(1); /* A string of the protocol's short name */
1722 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
1723 static int Dissector__gc(lua_State* L _U_) {
1724 /* do NOT free Dissector */
1725 return 0;
1728 static const luaL_Reg Dissector_methods[] = {
1729 {"get", Dissector_get },
1730 {"call", Dissector_call },
1731 { NULL, NULL }
1734 static const luaL_Reg Dissector_meta[] = {
1735 {"__tostring", Dissector__tostring},
1736 { NULL, NULL }
1739 int Dissector_register(lua_State* L) {
1740 WSLUA_REGISTER_CLASS(Dissector);
1741 return 1;
1744 WSLUA_CLASS_DEFINE(DissectorTable,NOP,NOP);
1746 A table of subdissectors of a particular protocol (e.g. TCP subdissectors like http, smtp, sip are added to table "tcp.port").
1747 Useful to add more dissectors to a table so that they appear in the Decode As... dialog.
1750 WSLUA_CONSTRUCTOR DissectorTable_new (lua_State *L) {
1751 /* Creates a new DissectorTable for your dissector's use. */
1752 #define WSLUA_ARG_DissectorTable_new_TABLENAME 1 /* The short name of the table. */
1753 #define WSLUA_OPTARG_DissectorTable_new_UINAME 2 /* The name of the table in the User Interface (defaults to the name given). */
1754 #define WSLUA_OPTARG_DissectorTable_new_TYPE 3 /* Either ftypes.UINT{8,16,24,32} or ftypes.STRING (defaults to ftypes.UINT32) */
1755 #define WSLUA_OPTARG_DissectorTable_new_BASE 4 /* Either base.NONE, base.DEC, base.HEX, base.OCT, base.DEC_HEX or base.HEX_DEC (defaults to base.DEC) */
1756 const gchar* name = (const gchar*)luaL_checkstring(L,WSLUA_ARG_DissectorTable_new_TABLENAME);
1757 const gchar* ui_name = (const gchar*)luaL_optstring(L,WSLUA_OPTARG_DissectorTable_new_UINAME,name);
1758 enum ftenum type = (enum ftenum)luaL_optint(L,WSLUA_OPTARG_DissectorTable_new_TYPE,FT_UINT32);
1759 unsigned base = (unsigned)luaL_optint(L,WSLUA_OPTARG_DissectorTable_new_BASE,BASE_DEC);
1761 if(!(name && ui_name)) return 0;
1763 switch(type) {
1764 case FT_STRING:
1765 base = BASE_NONE;
1766 /* fallthrough */
1767 case FT_UINT8:
1768 case FT_UINT16:
1769 case FT_UINT24:
1770 case FT_UINT32:
1772 DissectorTable dt = (DissectorTable)g_malloc(sizeof(struct _wslua_distbl_t));
1774 name = g_strdup(name);
1775 ui_name = g_strdup(ui_name);
1777 dt->table = register_dissector_table(name, ui_name, type, base);
1778 dt->name = name;
1779 pushDissectorTable(L, dt);
1781 WSLUA_RETURN(1); /* The newly created DissectorTable */
1782 default:
1783 WSLUA_OPTARG_ERROR(DissectorTable_new,TYPE,"must be ftypes.UINT{8,16,24,32} or ftypes.STRING");
1785 return 0;
1788 WSLUA_CONSTRUCTOR DissectorTable_get (lua_State *L) {
1790 Obtain a reference to an existing dissector table.
1792 #define WSLUA_ARG_DissectorTable_get_TABLENAME 1 /* The short name of the table. */
1793 const gchar* name = luaL_checkstring(L,WSLUA_ARG_DissectorTable_get_TABLENAME);
1794 dissector_table_t table;
1796 if(!name) return 0;
1798 table = find_dissector_table(name);
1800 if (table) {
1801 DissectorTable dt = (DissectorTable)g_malloc(sizeof(struct _wslua_distbl_t));
1802 dt->table = table;
1803 dt->name = g_strdup(name);
1805 pushDissectorTable(L, dt);
1807 WSLUA_RETURN(1); /* The DissectorTable */
1808 } else
1809 WSLUA_ARG_ERROR(DissectorTable_get,TABLENAME,"no such dissector_table");
1813 WSLUA_METHOD DissectorTable_add (lua_State *L) {
1815 Add a dissector or a range of dissectors to a table.
1817 #define WSLUA_ARG_DissectorTable_add_PATTERN 2 /* The pattern to match (either an integer, a integer range or a string depending on the table's type). */
1818 #define WSLUA_ARG_DissectorTable_add_DISSECTOR 3 /* The dissector to add (either an Proto or a Dissector). */
1820 DissectorTable dt = checkDissectorTable(L,1);
1821 ftenum_t type;
1822 Dissector handle;
1824 if (!dt) return 0;
1826 if( isProto(L,WSLUA_ARG_DissectorTable_add_DISSECTOR) ) {
1827 Proto p;
1828 p = toProto(L,WSLUA_ARG_DissectorTable_add_DISSECTOR);
1829 handle = p->handle;
1831 if (! handle)
1832 WSLUA_ARG_ERROR(DissectorTable_add,DISSECTOR,"a Protocol that does not have a dissector cannot be added to a table");
1834 } else if ( isDissector(L,WSLUA_ARG_DissectorTable_add_DISSECTOR) ) {
1835 handle = toDissector(L,WSLUA_ARG_DissectorTable_add_DISSECTOR);
1836 } else
1837 WSLUA_ARG_ERROR(DissectorTable_add,DISSECTOR,"must be either Proto or Dissector");
1839 type = get_dissector_table_selector_type(dt->name);
1841 if (type == FT_STRING) {
1842 gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_add_PATTERN));
1843 dissector_add_string(dt->name, pattern,handle);
1844 g_free (pattern);
1845 } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
1846 if (lua_isnumber(L, WSLUA_ARG_DissectorTable_add_PATTERN)) {
1847 int port = luaL_checkint(L, WSLUA_ARG_DissectorTable_add_PATTERN);
1848 dissector_add_uint(dt->name, port, handle);
1849 } else {
1850 /* Not a number, try as range */
1851 gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_add_PATTERN));
1852 range_t *range;
1853 if (range_convert_str(&range, pattern, G_MAXUINT32) == CVT_NO_ERROR)
1854 dissector_add_uint_range(dt->name, range, handle);
1855 else
1856 WSLUA_ARG_ERROR(DissectorTable_add,PATTERN,"invalid integer or range");
1857 g_free (pattern);
1859 } else {
1860 luaL_error(L,"Strange type %d for a DissectorTable",type);
1863 return 0;
1866 WSLUA_METHOD DissectorTable_set (lua_State *L) {
1868 Remove existing dissectors from a table and add a new or a range of new dissectors.
1870 #define WSLUA_ARG_DissectorTable_set_PATTERN 2 /* The pattern to match (either an integer, a integer range or a string depending on the table's type). */
1871 #define WSLUA_ARG_DissectorTable_set_DISSECTOR 3 /* The dissector to add (either an Proto or a Dissector). */
1873 DissectorTable dt = checkDissectorTable(L,1);
1874 ftenum_t type;
1875 Dissector handle;
1877 if (!dt) return 0;
1879 if( isProto(L,WSLUA_ARG_DissectorTable_set_DISSECTOR) ) {
1880 Proto p;
1881 p = toProto(L,WSLUA_ARG_DissectorTable_set_DISSECTOR);
1882 handle = p->handle;
1884 if (! handle)
1885 WSLUA_ARG_ERROR(DissectorTable_set,DISSECTOR,"a Protocol that does not have a dissector cannot be set to a table");
1887 } else if ( isDissector(L,WSLUA_ARG_DissectorTable_set_DISSECTOR) ) {
1888 handle = toDissector(L,WSLUA_ARG_DissectorTable_set_DISSECTOR);
1889 } else
1890 WSLUA_ARG_ERROR(DissectorTable_set,DISSECTOR,"must be either Proto or Dissector");
1892 type = get_dissector_table_selector_type(dt->name);
1894 if (type == FT_STRING) {
1895 gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_set_PATTERN));
1896 dissector_delete_all(dt->name, handle);
1897 dissector_add_string(dt->name, pattern,handle);
1898 g_free (pattern);
1899 } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
1900 if (lua_isnumber(L, WSLUA_ARG_DissectorTable_set_PATTERN)) {
1901 int port = luaL_checkint(L, WSLUA_ARG_DissectorTable_set_PATTERN);
1902 dissector_delete_all(dt->name, handle);
1903 dissector_add_uint(dt->name, port, handle);
1904 } else {
1905 /* Not a number, try as range */
1906 gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_set_PATTERN));
1907 range_t *range;
1908 if (range_convert_str(&range, pattern, G_MAXUINT32) == CVT_NO_ERROR) {
1909 dissector_delete_all(dt->name, handle);
1910 dissector_add_uint_range(dt->name, range, handle);
1911 } else {
1912 WSLUA_ARG_ERROR(DissectorTable_set,PATTERN,"invalid integer or range");
1914 g_free (pattern);
1916 } else {
1917 luaL_error(L,"Strange type %d for a DissectorTable",type);
1920 return 0;
1923 WSLUA_METHOD DissectorTable_remove (lua_State *L) {
1925 Remove a dissector or a range of dissectors from a table
1927 #define WSLUA_ARG_DissectorTable_remove_PATTERN 2 /* The pattern to match (either an integer, a integer range or a string depending on the table's type). */
1928 #define WSLUA_ARG_DissectorTable_remove_DISSECTOR 3 /* The dissector to remove (either an Proto or a Dissector). */
1929 DissectorTable dt = checkDissectorTable(L,1);
1930 ftenum_t type;
1931 Dissector handle;
1933 if (!dt) return 0;
1935 if( isProto(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR) ) {
1936 Proto p;
1937 p = toProto(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR);
1938 handle = p->handle;
1940 } else if ( isDissector(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR) ) {
1941 handle = toDissector(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR);
1942 } else
1943 WSLUA_ARG_ERROR(DissectorTable_remove,DISSECTOR,"must be either Proto or Dissector");
1945 type = get_dissector_table_selector_type(dt->name);
1947 if (type == FT_STRING) {
1948 gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_remove_PATTERN));
1949 dissector_delete_string(dt->name, pattern,handle);
1950 g_free (pattern);
1951 } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
1952 if (lua_isnumber(L, WSLUA_ARG_DissectorTable_remove_PATTERN)) {
1953 int port = luaL_checkint(L, WSLUA_ARG_DissectorTable_remove_PATTERN);
1954 dissector_delete_uint(dt->name, port, handle);
1955 } else {
1956 /* Not a number, try as range */
1957 gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_remove_PATTERN));
1958 range_t *range;
1959 if (range_convert_str(&range, pattern, G_MAXUINT32) == CVT_NO_ERROR)
1960 dissector_delete_uint_range(dt->name, range, handle);
1961 else
1962 WSLUA_ARG_ERROR(DissectorTable_remove,PATTERN,"invalid integer or range");
1963 g_free (pattern);
1967 return 0;
1970 WSLUA_METHOD DissectorTable_remove_all (lua_State *L) {
1972 Remove all dissectors from a table
1974 #define WSLUA_ARG_DissectorTable_remove_all_DISSECTOR 2 /* The dissector to add (either an Proto or a Dissector). */
1975 DissectorTable dt = checkDissectorTable(L,1);
1976 Dissector handle;
1978 if (!dt) return 0;
1980 if( isProto(L,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR) ) {
1981 Proto p;
1982 p = toProto(L,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR);
1983 handle = p->handle;
1985 } else if ( isDissector(L,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR) ) {
1986 handle = toDissector(L,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR);
1987 } else
1988 WSLUA_ARG_ERROR(DissectorTable_remove_all,DISSECTOR,"must be either Proto or Dissector");
1990 dissector_delete_all (dt->name, handle);
1992 return 0;
1995 WSLUA_METHOD DissectorTable_try (lua_State *L) {
1997 Try to call a dissector from a table
1999 #define WSLUA_ARG_DissectorTable_try_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */
2000 #define WSLUA_ARG_DissectorTable_try_TVB 3 /* The buffer to dissect */
2001 #define WSLUA_ARG_DissectorTable_try_PINFO 4 /* The packet info */
2002 #define WSLUA_ARG_DissectorTable_try_TREE 5 /* The tree on which to add the protocol items */
2003 DissectorTable dt = checkDissectorTable(L,1);
2004 Tvb tvb = checkTvb(L,WSLUA_ARG_DissectorTable_try_TVB);
2005 Pinfo pinfo = checkPinfo(L,WSLUA_ARG_DissectorTable_try_PINFO);
2006 TreeItem ti = checkTreeItem(L,WSLUA_ARG_DissectorTable_try_TREE);
2007 ftenum_t type;
2008 gboolean handled = FALSE;
2009 const gchar *volatile error = NULL;
2011 if (! (dt && tvb && tvb->ws_tvb && pinfo && ti) ) return 0;
2013 type = get_dissector_table_selector_type(dt->name);
2015 TRY {
2017 if (type == FT_STRING) {
2018 const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_try_PATTERN);
2020 if (!pattern)
2021 handled = TRUE;
2023 else if (dissector_try_string(dt->table,pattern,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree, NULL))
2024 handled = TRUE;
2026 } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
2027 int port = luaL_checkint(L, WSLUA_ARG_DissectorTable_try_PATTERN);
2029 if (dissector_try_uint(dt->table,port,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree))
2030 handled = TRUE;
2032 } else {
2033 luaL_error(L,"No such type of dissector_table");
2036 if (!handled)
2037 call_dissector(lua_data_handle,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree);
2039 /* XXX Are we sure about this??? is this the right/only thing to catch */
2040 } CATCH_NONFATAL_ERRORS {
2041 show_exception(tvb->ws_tvb, pinfo->ws_pinfo, ti->tree, EXCEPT_CODE, GET_MESSAGE);
2042 error = "Malformed frame";
2043 } ENDTRY;
2045 if (error) { WSLUA_ERROR(DissectorTable_try,error); }
2047 return 0;
2050 WSLUA_METHOD DissectorTable_get_dissector (lua_State *L) {
2052 Try to obtain a dissector from a table.
2054 #define WSLUA_ARG_DissectorTable_try_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */
2056 DissectorTable dt = checkDissectorTable(L,1);
2057 ftenum_t type;
2058 dissector_handle_t handle = lua_data_handle;
2060 if (!dt) return 0;
2062 type = get_dissector_table_selector_type(dt->name);
2064 if (type == FT_STRING) {
2065 const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_try_PATTERN);
2067 if (!pattern) WSLUA_ARG_ERROR(DissectorTable_try,PATTERN,"must be a string");
2069 handle = dissector_get_string_handle(dt->table,pattern);
2070 } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
2071 int port = luaL_checkint(L, WSLUA_ARG_DissectorTable_try_PATTERN);
2072 handle = dissector_get_uint_handle(dt->table,port);
2075 if (handle) {
2076 pushDissector(L,handle);
2077 WSLUA_RETURN(1); /* The dissector handle if found */
2078 } else {
2079 lua_pushnil(L);
2080 WSLUA_RETURN(1); /* nil if not found */
2084 /* XXX It would be nice to iterate and print which dissectors it has */
2085 WSLUA_METAMETHOD DissectorTable__tostring(lua_State* L) {
2086 /* Gets some debug information about the DissectorTable */
2087 DissectorTable dt = checkDissectorTable(L,1);
2088 GString* s;
2089 ftenum_t type;
2091 if (!dt) return 0;
2093 type = get_dissector_table_selector_type(dt->name);
2094 s = g_string_new("DissectorTable ");
2096 switch(type) {
2097 case FT_STRING:
2099 g_string_append_printf(s,"%s String:\n",dt->name);
2100 break;
2102 case FT_UINT8:
2103 case FT_UINT16:
2104 case FT_UINT24:
2105 case FT_UINT32:
2107 int base = get_dissector_table_base(dt->name);
2108 g_string_append_printf(s,"%s Integer(%i):\n",dt->name,base);
2109 break;
2111 default:
2112 luaL_error(L,"Strange table type");
2115 lua_pushstring(L,s->str);
2116 g_string_free(s,TRUE);
2117 WSLUA_RETURN(1); /* A string of debug information about the DissectorTable */
2120 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
2121 static int DissectorTable__gc(lua_State* L _U_) {
2122 /* do NOT free DissectorTable */
2123 return 0;
2126 static const luaL_Reg DissectorTable_methods[] = {
2127 {"new", DissectorTable_new },
2128 {"get", DissectorTable_get },
2129 {"add", DissectorTable_add },
2130 {"set", DissectorTable_set },
2131 {"remove", DissectorTable_remove },
2132 {"remove_all", DissectorTable_remove_all },
2133 {"try", DissectorTable_try },
2134 {"get_dissector", DissectorTable_get_dissector },
2135 { NULL, NULL }
2138 static const luaL_Reg DissectorTable_meta[] = {
2139 {"__tostring", DissectorTable__tostring},
2140 { NULL, NULL }
2143 int DissectorTable_register(lua_State* L) {
2144 WSLUA_REGISTER_CLASS(DissectorTable);
2145 return 1;