4 * Ethereal's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 ELUA_CLASS_DEFINE(Pref,NOP) /* A preference of a Protocol. */
33 static int new_pref(lua_State* L, pref_type_t type) {
34 const gchar* label = luaL_optstring(L,1,NULL);
35 const gchar* descr = luaL_optstring(L,3,"");
37 Pref pref = g_malloc(sizeof(eth_pref_t));
39 pref->label = label ? g_strdup(label) : NULL;
40 pref->desc = g_strdup(descr);
47 gboolean def = lua_toboolean(L,2);
52 guint32 def = (guint32)luaL_optnumber(L,2,0);
57 gchar* def = g_strdup(luaL_optstring(L,2,""));
62 g_assert_not_reached();
72 ELUA_CONSTRUCTOR Pref_bool(lua_State* L) {
74 * Creates a boolean preference to be added to a Protocol's prefs table.
76 #define ELUA_ATTR_Pref_bool_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */
77 #define ELUA_ATTR_Pref_bool_DEFAULT 2 /* The default value for this preference */
78 #define ELUA_ATTR_Pref_bool_DESCR 3 /* A description of what this preference is */
79 return new_pref(L,PREF_BOOL);
82 ELUA_CONSTRUCTOR Pref_uint(lua_State* L) {
84 * Creates an (unsigned) integer preference to be added to a Protocol's prefs table.
86 #define ELUA_ATTR_Pref_uint_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */
87 #define ELUA_ATTR_Pref_uint_DEFAULT 2 /* The default value for this preference */
88 #define ELUA_ATTR_Pref_uint_DESCR 3 /* A description of what this preference is */
89 return new_pref(L,PREF_UINT);
92 ELUA_CONSTRUCTOR Pref_string(lua_State* L) {
94 * Creates a string preference to be added to a Protocol's prefs table.
96 #define ELUA_ATTR_Pref_string_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */
97 #define ELUA_ATTR_Pref_string_DEFAULT 2 /* The default value for this preference */
98 #define ELUA_ATTR_Pref_string_DESCR 3 /* A description of what this preference is */
99 return new_pref(L,PREF_STRING);
102 static int Pref_gc(lua_State* L) {
103 Pref pref = checkPref(L,1);
105 if (pref && ! pref->name) {
106 if (pref->label) g_free(pref->label);
107 if (pref->desc) g_free(pref->desc);
108 if (pref->type == PREF_STRING) g_free((void*)pref->value.s);
115 ELUA_METHODS Pref_methods[] = {
118 {"string", Pref_string},
122 ELUA_META Pref_meta[] = {
128 ELUA_REGISTER Pref_register(lua_State* L) {
129 ELUA_REGISTER_CLASS(Pref);
133 ELUA_CLASS_DEFINE(Prefs,NOP) /* The table of preferences of a protocol */
135 ELUA_METAMETHOD Prefs__newindex(lua_State* L) {
136 /* creates a new preference */
137 #define ELUA_ARG_Prefs__newindex_NAME 2 /* The abbreviation of this preference */
138 #define ELUA_ARG_Prefs__newindex_PREF 3 /* A valid still unassigned Pref object */
140 Pref prefs = checkPrefs(L,1);
141 const gchar* name = luaL_checkstring(L,ELUA_ARG_Prefs__newindex_NAME);
142 Pref pref = checkPref(L,ELUA_ARG_Prefs__newindex_PREF);
145 if (! prefs ) return 0;
148 ELUA_ARG_ERROR(Prefs__newindex,NAME,"must be a string");
151 ELUA_ARG_ERROR(Prefs__newindex,PREF,"must be a valid Pref");
154 ELUA_ARG_ERROR(Prefs__newindex,NAME,"cannot change existing preference");
157 ELUA_ARG_ERROR(Prefs__newindex,PREF,"cannot be added to more than one protocol");
162 if ( p->name && g_str_equal(p->name,name) ) {
163 luaL_error(L,"a preference named %s exists already",name);
170 pref->name = g_strdup(name);
173 pref->label = g_strdup(name);
175 if (!prefs->proto->prefs_module) {
176 prefs->proto->prefs_module = prefs_register_protocol(prefs->proto->hfid, NULL);
182 prefs_register_bool_preference(prefs->proto->prefs_module,
189 prefs_register_uint_preference(prefs->proto->prefs_module,
197 prefs_register_string_preference(prefs->proto->prefs_module,
204 ELUA_ERROR(Prefs__newindex,"unknow Pref type");
207 pref->proto = p->proto;
211 } while (( p = p->next ));
213 luaL_error(L,"this should not happen!");
218 ELUA_METAMETHOD Prefs__index(lua_State* L) {
219 /* get the value of a preference setting */
220 #define ELUA_ARG_Prefs__index_NAME 2 /* The abbreviation of this preference */
222 Pref prefs = checkPrefs(L,1);
223 const gchar* name = luaL_checkstring(L,2);
225 if (! ( name && prefs ) ) return 0;
230 if ( g_str_equal(prefs->name,name) ) {
231 switch (prefs->type) {
232 case PREF_BOOL: lua_pushboolean(L, prefs->value.b); break;
233 case PREF_UINT: lua_pushnumber(L,(lua_Number)prefs->value.u); break;
234 case PREF_STRING: lua_pushstring(L,prefs->value.s); break;
235 default: ELUA_ERROR(Prefs__index,"unknow Pref type");
237 ELUA_RETURN(1); /* the current value of the preference */
239 } while (( prefs = prefs->next ));
241 ELUA_ARG_ERROR(Prefs__index,NAME,"no preference named like this");
245 ELUA_META Prefs_meta[] = {
246 {"__newindex", Prefs__newindex},
247 {"__index", Prefs__index},
251 ELUA_REGISTER Prefs_register(lua_State* L) {
252 ELUA_REGISTER_META(Prefs);
257 ELUA_CLASS_DEFINE(ProtoField,FAIL_ON_NULL("null ProtoField"))
259 * A Protocol field (to be used when adding items to the dissection tree)
262 static const eth_ft_types_t ftenums[] = {
263 {"FT_BOOLEAN",FT_BOOLEAN},
264 {"FT_UINT8",FT_UINT8},
265 {"FT_UINT16",FT_UINT16},
266 {"FT_UINT24",FT_UINT24},
267 {"FT_UINT32",FT_UINT32},
268 {"FT_UINT64",FT_UINT64},
270 {"FT_INT16",FT_INT16},
271 {"FT_INT24",FT_INT24},
272 {"FT_INT32",FT_INT32},
273 {"FT_INT64",FT_INT64},
274 {"FT_FLOAT",FT_FLOAT},
275 {"FT_DOUBLE",FT_DOUBLE},
276 {"FT_STRING",FT_STRING},
277 {"FT_STRINGZ",FT_STRINGZ},
278 {"FT_ETHER",FT_ETHER},
279 {"FT_BYTES",FT_BYTES},
280 {"FT_UINT_BYTES",FT_UINT_BYTES},
283 {"FT_IPXNET",FT_IPXNET},
284 {"FT_FRAMENUM",FT_FRAMENUM},
291 static enum ftenum get_ftenum(const gchar* type) {
292 const eth_ft_types_t* ts;
293 for (ts = ftenums; ts->str; ts++) {
294 if ( g_str_equal(ts->str,type) ) {
303 static const gchar* ftenum_to_string(enum ftenum ft) {
304 const eth_ft_types_t* ts;
305 for (ts = ftenums; ts->str; ts++) {
306 if ( ts->id == ft ) {
314 struct base_display_string_t {
319 static const struct base_display_string_t base_displays[] = {
320 { "BASE_NONE", BASE_NONE},
321 {"BASE_DEC", BASE_DEC},
322 {"BASE_HEX", BASE_HEX},
323 {"BASE_OCT", BASE_OCT},
324 {"BASE_DEC_HEX", BASE_DEC_HEX},
325 {"BASE_HEX_DEC", BASE_HEX_DEC},
329 static const gchar* base_to_string(base_display_e base) {
330 const struct base_display_string_t* b;
331 for (b=base_displays;b->str;b++) {
332 if ( base == b->base)
339 static base_display_e string_to_base(const gchar* str) {
340 const struct base_display_string_t* b;
341 for (b=base_displays;b->str;b++) {
342 if ( g_str_equal(str,b->str))
349 static value_string* value_string_from_table(lua_State* L, int idx) {
350 GArray* vs = g_array_new(TRUE,TRUE,sizeof(value_string));
353 if(lua_isnil(L,idx)) {
355 } else if (!lua_istable(L,idx)) {
356 luaL_argerror(L,idx,"must be a table");
357 g_array_free(vs,TRUE);
363 while (lua_next(L, idx) != 0) {
364 value_string v = {0,NULL};
366 if (! lua_isnumber(L,-2)) {
367 luaL_argerror(L,idx,"All keys of a table used as vaalue_string must be integers");
368 g_array_free(vs,TRUE);
372 if (! lua_isstring(L,-1)) {
373 luaL_argerror(L,idx,"All values of a table used as vaalue_string must be strings");
374 g_array_free(vs,TRUE);
378 v.value = (guint32)lua_tonumber(L,-2);
379 v.strptr = g_strdup(lua_tostring(L,-1));
381 g_array_append_val(vs,v);
388 ret = (value_string*)vs->data;
390 g_array_free(vs,FALSE);
396 ELUA_CONSTRUCTOR ProtoField_new(lua_State* L) { /* Creates a new field to be used in a protocol. */
397 #define ELUA_ARG_ProtoField_new_NAME 1 /* Actual name of the field (the string that appears in the tree). */
398 #define ELUA_ARG_ProtoField_new_ABBR 2 /* Filter name of the field (the string that is used in filters). */
399 #define ELUA_ARG_ProtoField_new_TYPE 3 /* Field Type (FT_*). */
400 #define ELUA_OPTARG_ProtoField_new_VALUESTRING 3 /* a ValueString object. */
401 #define ELUA_OPTARG_ProtoField_new_BASE 4 /* The representation BASE_*. */
402 #define ELUA_OPTARG_ProtoField_new_MASK 5 /* the bitmask to be used. */
403 #define ELUA_OPTARG_ProtoField_new_DESCR 6 /* The description of the field. */
405 ProtoField f = g_malloc(sizeof(eth_field_t));
408 /* will be using -2 as far as the field has not been added to an array then it will turn -1 */
411 f->name = g_strdup(luaL_checkstring(L,ELUA_ARG_ProtoField_new_NAME));
412 f->abbr = g_strdup(luaL_checkstring(L,ELUA_ARG_ProtoField_new_ABBR));
413 f->type = luaL_checkint(L,ELUA_ARG_ProtoField_new_TYPE);
416 if (f->type == FT_NONE) {
417 ELUA_ARG_ERROR(ProtoField_new,TYPE,"invalid FT_type");
421 if (! lua_isnil(L,4) ) {
422 vs = value_string_from_table(L,4);
436 /* XXX: need BASE_ERROR */
437 f->base = luaL_optint(L, ELUA_OPTARG_ProtoField_new_BASE, BASE_NONE);
438 f->mask = luaL_optint(L, ELUA_OPTARG_ProtoField_new_MASK, 0x0);
439 f->blob = g_strdup(luaL_optstring(L,ELUA_OPTARG_ProtoField_new_DESCR,""));
443 ELUA_RETURN(1); /* The newly created ProtoField object */
447 static int ProtoField_integer(lua_State* L, enum ftenum type) {
448 ProtoField f = g_malloc(sizeof(eth_field_t));
449 const gchar* abbr = luaL_checkstring(L,1);
450 const gchar* name = luaL_optstring(L,2,abbr);
451 base_display_e base = luaL_optint(L, 3, BASE_DEC);
452 value_string* vs = (lua_gettop(L) > 3) ? value_string_from_table(L,4) : NULL;
453 int mask = luaL_optint(L, 5, 0x0);
454 const gchar* blob = luaL_optstring(L,6,"");
456 if (base < BASE_DEC || base > BASE_HEX_DEC) {
457 luaL_argerror(L,2,"Base must be either BASE_DEC, BASE_HEX, BASE_OCT,"
458 " BASE_DEC_HEX, BASE_DEC_HEX or BASE_HEX_DEC");
464 f->name = g_strdup(name);
465 f->abbr = g_strdup(abbr);
470 f->blob = g_strdup(blob);
478 #define PROTOFIELD_INTEGER(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_integer(L,FT); }
479 /* ELUA_SECTION Protofield integer constructors */
480 /* ELUA_TEXT integer type ProtoField constructors use the following arguments */
481 /* ELUA_ARG_DESC Protofield_integer ABBR abbreviated name of the field (the string used in filters) */
482 /* ELUA_OPTARG_DESC Protofield_integer NAME Actual name of the field (the string that appears in the tree) */
483 /* ELUA_ARGDESC Protofield_integer DESC description of the field */
484 /* _ELUA_RETURNS_ Protofield_integer a protofiled item to be added to a ProtoFieldArray */
485 /* _ELUA_CONSTRUCTOR_ ProtoField_uint8 */
486 /* _ELUA_CONSTRUCTOR_ ProtoField_uint16 */
487 /* _ELUA_CONSTRUCTOR_ ProtoField_uint24 */
488 /* _ELUA_CONSTRUCTOR_ ProtoField_uint32 */
489 /* _ELUA_CONSTRUCTOR_ ProtoField_uint64 */
490 /* _ELUA_CONSTRUCTOR_ ProtoField_int8 */
491 /* _ELUA_CONSTRUCTOR_ ProtoField_int16 */
492 /* _ELUA_CONSTRUCTOR_ ProtoField_int24 */
493 /* _ELUA_CONSTRUCTOR_ ProtoField_int32 */
494 /* _ELUA_CONSTRUCTOR_ ProtoField_int64 */
495 /* _ELUA_CONSTRUCTOR_ ProtoField_framenum */
496 PROTOFIELD_INTEGER(uint8,FT_UINT8)
497 PROTOFIELD_INTEGER(uint16,FT_UINT16)
498 PROTOFIELD_INTEGER(uint24,FT_UINT24)
499 PROTOFIELD_INTEGER(uint32,FT_UINT32)
500 PROTOFIELD_INTEGER(uint64,FT_UINT64)
501 PROTOFIELD_INTEGER(int8,FT_INT8)
502 PROTOFIELD_INTEGER(int16,FT_INT8)
503 PROTOFIELD_INTEGER(int24,FT_INT8)
504 PROTOFIELD_INTEGER(int32,FT_INT8)
505 PROTOFIELD_INTEGER(int64,FT_INT8)
506 PROTOFIELD_INTEGER(framenum,FT_FRAMENUM)
508 static int ProtoField_other(lua_State* L,enum ftenum type) {
509 ProtoField f = g_malloc(sizeof(eth_field_t));
510 const gchar* abbr = luaL_checkstring(L,1);
511 const gchar* name = luaL_optstring(L,2,abbr);
512 const gchar* blob = luaL_optstring(L,3,"");
516 f->name = g_strdup(name);
517 f->abbr = g_strdup(abbr);
520 f->base = ( type == FT_FLOAT || type == FT_DOUBLE) ? BASE_DEC : BASE_NONE;
522 f->blob = g_strdup(blob);
529 #define PROTOFIELD_OTHER(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_other(L,FT); }
530 /* ELUA_SECTION Protofield integer constructors */
531 /* ELUA_TEXT integer type ProtoField constructors use the following arguments */
532 /* ELUA_ARG_DESC Protofield_integer ABBR abbreviated name of the field (the string used in filters) */
533 /* ELUA_OPTARG_DESC Protofield_integer NAME Actual name of the field (the string that appears in the tree) */
534 /* ELUA_ARGDESC Protofield_integer DESC : description of the field */
535 /* _ELUA_RETURNS_ Protofield non integer : a protofiled item to be added to a ProtoFieldArray */
536 /* _ELUA_CONSTRUCTOR_ ProtoField_ipv4 */
537 /* _ELUA_CONSTRUCTOR_ ProtoField_ipv6 */
538 /* _ELUA_CONSTRUCTOR_ ProtoField_ether */
539 /* _ELUA_CONSTRUCTOR_ ProtoField_float */
540 /* _ELUA_CONSTRUCTOR_ ProtoField_double */
541 /* _ELUA_CONSTRUCTOR_ ProtoField_string */
542 /* _ELUA_CONSTRUCTOR_ ProtoField_strigz */
543 /* _ELUA_CONSTRUCTOR_ ProtoField_bytes */
544 /* _ELUA_CONSTRUCTOR_ ProtoField_ubytes */
545 /* _ELUA_CONSTRUCTOR_ ProtoField_guid */
546 /* _ELUA_CONSTRUCTOR_ ProtoField_oid */
547 /* _ELUA_CONSTRUCTOR_ ProtoField_bool */
548 PROTOFIELD_OTHER(ipv4,FT_IPv4)
549 PROTOFIELD_OTHER(ipv6,FT_IPv6)
550 PROTOFIELD_OTHER(ipx,FT_IPXNET)
551 PROTOFIELD_OTHER(ether,FT_ETHER)
552 PROTOFIELD_OTHER(float,FT_FLOAT)
553 PROTOFIELD_OTHER(double,FT_DOUBLE)
554 PROTOFIELD_OTHER(string,FT_STRING)
555 PROTOFIELD_OTHER(stringz,FT_STRINGZ)
556 PROTOFIELD_OTHER(bytes,FT_BYTES)
557 PROTOFIELD_OTHER(ubytes,FT_UINT_BYTES)
558 PROTOFIELD_OTHER(guid,FT_GUID)
559 PROTOFIELD_OTHER(oid,FT_OID)
561 /* XXX: T/F strings */
562 PROTOFIELD_OTHER(bool,FT_BOOLEAN)
565 static int ProtoField_tostring(lua_State* L) {
566 ProtoField f = checkProtoField(L,1);
567 gchar* s = g_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);
575 static int ProtoField_gc(lua_State* L) {
576 ProtoField f = checkProtoField(L,1);
579 * A garbage collector for ProtoFields makes little sense.
580 * Even if This cannot be used anymore because it has gone out of scope,
581 * we can destroy the ProtoField only if it is not part of a ProtoFieldArray,
582 * if it actualy belongs to one we need to preserve it as it is pointed by
583 * a field array that may be registered afterwards causing a crash or memory corruption.
587 luaL_argerror(L,1,"BUG: ProtoField_gc called for something not ProtoField");
589 } else if (f->hfid == -2) {
600 static const luaL_reg ProtoField_methods[] = {
601 {"new", ProtoField_new},
602 {"uint8",ProtoField_uint8},
603 {"uint16",ProtoField_uint16},
604 {"uint24",ProtoField_uint24},
605 {"uint32",ProtoField_uint32},
606 {"uint64",ProtoField_uint64},
607 {"int8",ProtoField_int8},
608 {"int16",ProtoField_int16},
609 {"int24",ProtoField_int24},
610 {"int32",ProtoField_int32},
611 {"int64",ProtoField_int64},
612 {"framenum",ProtoField_framenum},
613 {"ipv4",ProtoField_ipv4},
614 {"ipv6",ProtoField_ipv6},
615 {"ipx",ProtoField_ipx},
616 {"ether",ProtoField_ether},
617 {"bool",ProtoField_bool},
618 {"float",ProtoField_float},
619 {"double",ProtoField_double},
620 {"string",ProtoField_string},
621 {"stringz",ProtoField_stringz},
622 {"bytes",ProtoField_bytes},
623 {"ubytes",ProtoField_ubytes},
624 {"guid",ProtoField_guid},
625 {"oid",ProtoField_oid},
629 static const luaL_reg ProtoField_meta[] = {
630 {"__gc", ProtoField_gc },
631 {"__tostring", ProtoField_tostring },
635 int ProtoField_register(lua_State* L) {
637 ELUA_REGISTER_CLASS(ProtoField);
642 ELUA_CLASS_DEFINE(Proto,NOP)
644 A new protocol in wireshark. Protocols have more uses, the main one is to dissect
645 a protocol. But they can be just dummies used to register preferences for
649 static int protocols_table_ref = LUA_NOREF;
651 ELUA_CONSTRUCTOR Proto_new(lua_State* L) {
652 #define ELUA_ARG_Proto_new_NAME 1 /* The name of the protocol */
653 #define ELUA_ARG_Proto_new_DESC 1 /* A Long Text description of the protocol (usually lowercase) */
654 const gchar* name = luaL_checkstring(L,1);
655 const gchar* desc = luaL_checkstring(L,2);
658 gchar* loname = ep_strdup(name);
660 if ( proto_get_id_by_filter_name(loname) > 0 ) {
661 ELUA_ARG_ERROR(Proto_new,NAME,"there cannot be two protocols with the same name");
663 Proto proto = g_malloc(sizeof(eth_proto_t));
664 gchar* loname = g_strdup(name);
665 gchar* hiname = g_strdup(name);
670 proto->name = hiname;
671 proto->desc = g_strdup(desc);
672 proto->hfid = proto_register_protocol(proto->desc,hiname,loname);
674 proto->is_postdissector = FALSE;
677 proto->fields = luaL_ref(L, LUA_REGISTRYINDEX);
679 proto->prefs.name = NULL;
680 proto->prefs.label = NULL;
681 proto->prefs.desc = NULL;
682 proto->prefs.value.u = 0;
683 proto->prefs.next = NULL;
684 proto->prefs.proto = proto;
686 proto->prefs_module = NULL;
687 proto->handle = NULL;
689 lua_rawgeti(L, LUA_REGISTRYINDEX, protocols_table_ref);
691 lua_pushstring(L,loname);
698 ELUA_RETURN(1); /* The newly created protocol */
701 ELUA_ARG_ERROR(Proto_new,NAME,"must be a string");
709 static int Proto_tostring(lua_State* L) {
710 Proto proto = checkProto(L,1);
713 if (!proto) return 0;
715 s = g_strdup_printf("Proto: %s",proto->name);
722 ELUA_FUNCTION elua_register_postdissector(lua_State* L) {
723 Proto proto = checkProto(L,1);
724 if (!proto) return 0;
726 if(!proto->is_postdissector) {
727 if (! proto->handle) {
728 proto->handle = create_dissector_handle(dissect_lua, proto->hfid);
731 register_postdissector(proto->handle);
733 luaL_argerror(L,1,"this protocol is already registered as postdissector");
740 static int Proto_get_dissector(lua_State* L) {
741 Proto proto = toProto(L,1);
744 pushDissector(L,proto->handle);
747 luaL_error(L,"The protocol hasn't been registered yet");
753 static int Proto_set_dissector(lua_State* L) {
754 Proto proto = toProto(L,1);
756 if (lua_isfunction(L,3)) {
757 /* insert the dissector into the dissectors table */
759 lua_rawgeti(L, LUA_REGISTRYINDEX, lua_dissectors_table_ref);
761 lua_pushstring(L,proto->name);
765 proto->handle = create_dissector_handle(dissect_lua, proto->hfid);
769 luaL_argerror(L,3,"The dissector of a protocol must be a function");
774 static int Proto_get_prefs(lua_State* L) {
775 Proto proto = toProto(L,1);
777 pushPrefs(L,&proto->prefs);
781 static int Proto_set_init(lua_State* L) {
782 Proto proto = toProto(L,1);
784 if (lua_isfunction(L,3)) {
785 /* insert the dissector into the dissectors table */
786 lua_pushstring(L, ELUA_INIT_ROUTINES);
787 lua_gettable(L, LUA_GLOBALSINDEX);
789 lua_pushstring(L,proto->name);
795 luaL_argerror(L,3,"The initializer of a protocol must be a function");
800 static int Proto_get_name(lua_State* L) {
801 Proto proto = toProto(L,1);
803 lua_pushstring(L,proto->name);
808 static int Proto_get_fields(lua_State* L) {
809 Proto proto = toProto(L,1);
810 lua_rawgeti(L, LUA_REGISTRYINDEX, proto->fields);
814 void elua_print_stack(char* s, lua_State* L) {
817 for (i=1;i<=lua_gettop(L);i++) {
818 printf("%s-%i: %s\n",s,i,lua_typename (L,lua_type(L, i)));
823 static int Proto_set_fields(lua_State* L) {
824 Proto proto = toProto(L,1);
825 #define FIELDS_TABLE 2
829 lua_rawgeti(L, LUA_REGISTRYINDEX, proto->fields);
830 lua_replace(L,FIELDS_TABLE);
833 if( lua_istable(L,NEW_TABLE)) {
834 for (lua_pushnil(L); lua_next(L, NEW_TABLE); ) {
835 if (isProtoField(L,5)) {
836 luaL_ref(L,FIELDS_TABLE);
837 } else if (! lua_isnil(L,5) ) {
838 return luaL_error(L,"only ProtoFields should be in the table");
841 } else if (isProtoField(L,NEW_FIELD)){
842 lua_pushvalue(L, NEW_FIELD);
843 luaL_ref(L,FIELDS_TABLE);
846 return luaL_error(L,"either a ProtoField or an array of protofields");
862 static const proto_actions_t proto_actions[] = {
863 /* ELUA_ATTRIBUTE Pinfo_dissector RW the protocol's dissector, a function you define */
864 {"dissector",Proto_get_dissector, Proto_set_dissector},
866 /* ELUA_ATTRIBUTE Pinfo_fields RO the Fields Table of this dissector */
867 {"fields" ,Proto_get_fields, Proto_set_fields},
869 /* ELUA_ATTRIBUTE Proto_get_prefs RO the preferences of this dissector */
870 {"prefs",Proto_get_prefs,NULL},
872 /* ELUA_ATTRIBUTE Proto_init WO the init routine of this dissector, a function you define */
873 {"init",NULL,Proto_set_init},
875 /* ELUA_ATTRIBUTE Proto_init RO the name given to this dissector */
876 {"name",Proto_get_name,NULL},
880 static int Proto_index(lua_State* L) {
881 Proto proto = checkProto(L,1);
882 const gchar* name = luaL_checkstring(L,2);
883 const proto_actions_t* pa;
885 if (! (proto && name) ) return 0;
887 for (pa = proto_actions; pa->name; pa++) {
888 if ( g_str_equal(name,pa->name) ) {
892 luaL_error(L,"You cannot get the `%s' attribute of a protocol",name);
898 luaL_error(L,"A protocol doesn't have a `%s' attribute",name);
903 static int Proto_newindex(lua_State* L) {
904 Proto proto = checkProto(L,1);
905 const gchar* name = luaL_checkstring(L,2);
906 const proto_actions_t* pa;
908 if (! (proto && name) ) return 0;
910 for (pa = proto_actions; pa->name; pa++) {
911 if ( g_str_equal(name,pa->name) ) {
915 luaL_error(L,"You cannot set the `%s' attribute of a protocol",name);
921 luaL_error(L,"A protocol doesn't have a `%s' attribute",name);
925 static const luaL_reg Proto_meta[] = {
926 {"__tostring", Proto_tostring},
927 {"__index", Proto_index},
928 {"__newindex", Proto_newindex},
932 int Proto_register(lua_State* L) {
934 ELUA_REGISTER_META(Proto);
937 protocols_table_ref = luaL_ref(L, LUA_REGISTRYINDEX);
939 lua_pushstring(L, "Proto");
940 lua_pushcfunction(L, Proto_new);
941 lua_settable(L, LUA_GLOBALSINDEX);
949 int Proto_commit(lua_State* L) {
951 lua_rawgeti(L, LUA_REGISTRYINDEX, protocols_table_ref);
953 for (lua_pushnil(L); lua_next(L, 1); lua_pop(L, 2)) {
954 GArray* hfa = g_array_new(TRUE,TRUE,sizeof(hf_register_info));
955 GArray* etta = g_array_new(TRUE,TRUE,sizeof(gint*));
957 const gchar* proto_name;
958 proto_name = lua_tostring(L,2);
959 proto = checkProto(L,3);
961 lua_rawgeti(L, LUA_REGISTRYINDEX, proto->fields);
963 for (lua_pushnil(L); lua_next(L, 4); lua_pop(L, 1)) {
964 ProtoField f = checkProtoField(L,6);
965 hf_register_info hfri = { &(f->hfid), {f->name,f->abbr,f->type,f->base,VALS(f->vs),f->mask,f->blob,HFILL}};
966 gint* ettp = &(f->ett);
969 return luaL_error(L,"fields can be registered only once");
973 g_array_append_val(hfa,hfri);
974 g_array_append_val(etta,ettp);
977 proto_register_field_array(proto->hfid,(hf_register_info*)hfa->data,hfa->len);
978 proto_register_subtree_array((gint**)etta->data,etta->len);
980 g_array_free(hfa,FALSE);
981 g_array_free(etta,FALSE);
989 ELUA_CLASS_DEFINE(Dissector,NOP)
991 A refererence to a dissector, used to call a dissector against a packet or a part of it.
995 ELUA_CONSTRUCTOR Dissector_get (lua_State *L) {
997 * Obtains a dissector reference by name
999 #define ELUA_ARG_Dissector_get_NAME 1 /* The name of the dissector */
1000 const gchar* name = luaL_checkstring(L,1);
1004 ELUA_ARG_ERROR(Dissector_get,NAME,"must be a string");
1006 if ((d = find_dissector(name))) {
1007 pushDissector(L, d);
1008 ELUA_RETURN(1); /* The Dissector reference */
1010 ELUA_ARG_ERROR(Dissector_get,NAME,"No such dissector");
1014 ELUA_METHOD Dissector_call(lua_State* L) {
1016 * Calls a dissector against a given packet (or part of it)
1018 #define ELUA_ARG_Dissector_call_TVB 2 /* The buffer to dissect */
1019 #define ELUA_ARG_Dissector_call_PINFO 3 /* The packet info */
1020 #define ELUA_ARG_Dissector_call_TREE 4 /* The tree on which to add the protocol items */
1022 Dissector d = checkDissector(L,1);
1023 Tvb tvb = checkTvb(L,ELUA_ARG_Dissector_call_TVB);
1024 Pinfo pinfo = checkPinfo(L,ELUA_ARG_Dissector_call_PINFO);
1025 TreeItem ti = checkTreeItem(L,ELUA_ARG_Dissector_call_TREE);
1027 if (! ( d && tvb && pinfo) ) return 0;
1030 call_dissector(d, tvb, pinfo, ti->tree);
1031 /* XXX Are we sure about this??? is this the right/only thing to catch */
1032 } CATCH(ReportedBoundsError) {
1033 proto_tree_add_protocol_format(lua_tree->tree, lua_malformed, lua_tvb, 0, 0, "[Malformed Frame: Packet Length]" );
1034 ELUA_ERROR(Dissector_call,"malformed frame");
1042 static int Dissector_tostring(lua_State* L) {
1043 Dissector d = checkDissector(L,1);
1045 lua_pushstring(L,dissector_handle_get_short_name(d));
1049 static const luaL_reg Dissector_methods[] = {
1050 {"get", Dissector_get },
1051 {"call", Dissector_call },
1055 static const luaL_reg Dissector_meta[] = {
1056 {"__tostring", Dissector_tostring},
1060 int Dissector_register(lua_State* L) {
1061 ELUA_REGISTER_CLASS(Dissector);
1066 ELUA_CLASS_DEFINE(DissectorTable,NOP)
1068 A table of subdissectors of a particular protocol (e.g. TCP subdissectors like http, smtp, sip are added to table "tcp.port").
1069 Useful to add more dissectors to a table so that they appear in the Decode As... dialog.
1072 ELUA_CONSTRUCTOR DissectorTable_new (lua_State *L) {
1074 Creates a new DissectorTable for your dissector's use .
1076 #define ELUA_ARG_DissectorTable_new_TABLENAME 1 /* The short name of the table. */
1077 #define ELUA_OPTARG_DissectorTable_new_UINAME 2 /* The name of the table in the User Interface (defaults to the name given). */
1078 #define ELUA_OPTARG_DissectorTable_new_TYPE 3 /* either FT_UINT* or FT_STRING (defaults to FT_UINT32) */
1079 gchar* name = (void*)luaL_checkstring(L,ELUA_ARG_DissectorTable_new_TABLENAME);
1080 gchar* ui_name = (void*)luaL_optstring(L,ELUA_OPTARG_DissectorTable_new_UINAME,name);
1081 enum ftenum type = luaL_optint(L,ELUA_OPTARG_DissectorTable_new_TYPE,FT_UINT32);
1082 base_display_e base = luaL_optint(L,4,BASE_DEC);
1084 if(!(name && ui_name)) return 0;
1086 name = g_strdup(name);
1087 ui_name = g_strdup(ui_name);
1097 DissectorTable dt = g_malloc(sizeof(struct _eth_distbl_t));
1099 dt->table = register_dissector_table(name, ui_name, type, base);
1101 pushDissectorTable(L, dt);
1103 ELUA_RETURN(1); /* The newly created DissectorTable */
1105 ELUA_OPTARG_ERROR(DissectorTable_new,TYPE,"must be FTUINT* or FT_STRING");
1110 ELUA_CONSTRUCTOR DissectorTable_get (lua_State *L) {
1112 Obtain a reference to an existing dissector table.
1114 #define ELUA_ARG_DissectorTable_get_TABLENAME 1 /* The short name of the table. */
1115 const gchar* name = luaL_checkstring(L,ELUA_ARG_DissectorTable_get_TABLENAME);
1116 dissector_table_t table;
1120 table = find_dissector_table(name);
1123 DissectorTable dt = g_malloc(sizeof(struct _eth_distbl_t));
1125 dt->name = g_strdup(name);
1127 pushDissectorTable(L, dt);
1129 ELUA_RETURN(1); /* The DissectorTable */
1131 ELUA_ARG_ERROR(DissectorTable_get,TABLENAME,"no such dissector_table");
1136 ELUA_METHOD DissectorTable_add (lua_State *L) {
1138 Add a dissector to a table.
1140 #define ELUA_ARG_DissectorTable_add_PATTERN 2 /* The pattern to match (either an integer or a string depending on the table's type). */
1141 #define ELUA_ARG_DissectorTable_add_DISSECTOR 3 /* The dissector to add (either an Proto or a Dissector). */
1143 DissectorTable dt = checkDissectorTable(L,1);
1149 if( isProto(L,ELUA_ARG_DissectorTable_add_DISSECTOR) ) {
1151 p = toProto(L,ELUA_ARG_DissectorTable_add_DISSECTOR);
1155 ELUA_ARG_ERROR(DissectorTable_add,DISSECTOR,"a Protocol that does not have a dissector cannot be added to a table");
1157 } else if ( isDissector(L,ELUA_ARG_DissectorTable_add_DISSECTOR) ) {
1158 handle = toDissector(L,ELUA_ARG_DissectorTable_add_DISSECTOR);
1160 ELUA_ARG_ERROR(DissectorTable_add,DISSECTOR,"must be either Proto or Dissector");
1162 type = get_dissector_table_selector_type(dt->name);
1164 if (type == FT_STRING) {
1165 gchar* pattern = g_strdup(luaL_checkstring(L,ELUA_ARG_DissectorTable_add_PATTERN));
1166 dissector_add_string(dt->name, pattern,handle);
1167 } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
1168 int port = luaL_checkint(L, ELUA_ARG_DissectorTable_add_PATTERN);
1169 dissector_add(dt->name, port, handle);
1171 luaL_error(L,"Strange type %d for a DissectorTable",type);
1177 ELUA_METHOD DissectorTable_remove (lua_State *L) {
1179 Remove a dissector from a table
1181 #define ELUA_ARG_DissectorTable_remove_PATTERN 2 /* The pattern to match (either an integer or a string depending on the table's type). */
1182 #define ELUA_ARG_DissectorTable_remove_DISSECTOR 3 /* The dissector to add (either an Proto or a Dissector). */
1183 DissectorTable dt = checkDissectorTable(L,1);
1189 if( isProto(L,ELUA_ARG_DissectorTable_remove_DISSECTOR) ) {
1191 p = toProto(L,ELUA_ARG_DissectorTable_remove_DISSECTOR);
1194 } else if ( isDissector(L,ELUA_ARG_DissectorTable_remove_DISSECTOR) ) {
1195 handle = toDissector(L,ELUA_ARG_DissectorTable_remove_DISSECTOR);
1197 ELUA_ARG_ERROR(DissectorTable_add,DISSECTOR,"must be either Proto or Dissector");
1199 type = get_dissector_table_selector_type(dt->name);
1201 if (type == FT_STRING) {
1202 gchar* pattern = g_strdup(luaL_checkstring(L,2));
1203 dissector_delete_string(dt->name, pattern,handle);
1204 } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
1205 int port = luaL_checkint(L, 2);
1206 dissector_delete(dt->name, port, handle);
1213 ELUA_METHOD DissectorTable_try (lua_State *L) {
1215 Try to call a dissector from a table
1217 #define ELUA_ARG_DissectorTable_try_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */
1218 #define ELUA_ARG_DissectorTable_try_TVB 3 /* The buffer to dissect */
1219 #define ELUA_ARG_DissectorTable_try_PINFO 4 /* The packet info */
1220 #define ELUA_ARG_DissectorTable_try_TREE 5 /* The tree on which to add the protocol items */
1221 DissectorTable dt = checkDissectorTable(L,1);
1222 Tvb tvb = checkTvb(L,3);
1223 Pinfo pinfo = checkPinfo(L,4);
1224 TreeItem ti = checkTreeItem(L,5);
1227 if (! (dt && tvb && pinfo && ti) ) return 0;
1229 type = get_dissector_table_selector_type(dt->name);
1233 if (type == FT_STRING) {
1234 const gchar* pattern = luaL_checkstring(L,2);
1236 if (!pattern) return 0;
1238 if (dissector_try_string(dt->table,pattern,tvb,pinfo,ti->tree))
1241 } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
1242 int port = luaL_checkint(L, 2);
1244 if (dissector_try_port(dt->table,port,tvb,pinfo,ti->tree))
1248 luaL_error(L,"No such type of dissector_table");
1251 call_dissector(lua_data_handle,tvb,pinfo,ti->tree);
1253 /* XXX Are we sure about this??? is this the right/only thing to catch */
1254 } CATCH(ReportedBoundsError) {
1255 proto_tree_add_protocol_format(lua_tree->tree, lua_malformed, lua_tvb, 0, 0, "[Malformed Frame: Packet Length]" );
1256 ELUA_ERROR(DissectorTable_try,"malformed frame");
1263 ELUA_METHOD DissectorTable_get_dissector (lua_State *L) {
1265 Try to obtain a dissector from a table.
1267 #define ELUA_ARG_DissectorTable_try_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */
1269 DissectorTable dt = checkDissectorTable(L,1);
1271 dissector_handle_t handle = lua_data_handle;
1275 type = get_dissector_table_selector_type(dt->name);
1277 if (type == FT_STRING) {
1278 const gchar* pattern = luaL_checkstring(L,ELUA_ARG_DissectorTable_try_PATTERN);
1280 if (!pattern) ELUA_ARG_ERROR(DissectorTable_try,PATTERN,"must be a string");
1282 handle = dissector_get_string_handle(dt->table,pattern);
1283 } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
1284 int port = luaL_checkint(L, ELUA_ARG_DissectorTable_try_PATTERN);
1285 handle = dissector_get_port_handle(dt->table,port);
1289 pushDissector(L,handle);
1290 ELUA_RETURN(1); /* The dissector handle if found */
1293 ELUA_RETURN(1); /* nil if not found */
1298 static int DissectorTable_tostring(lua_State* L) {
1299 /* XXX It would be nice to iterate and print which dissectors it has */
1300 DissectorTable dt = checkDissectorTable(L,1);
1306 type = get_dissector_table_selector_type(dt->name);
1307 s = g_string_new("DissectorTable ");
1312 g_string_sprintfa(s,"%s String:\n",dt->name);
1320 int base = get_dissector_table_base(dt->name);
1321 g_string_sprintfa(s,"%s Integer(%i):\n",dt->name,base);
1325 luaL_error(L,"Strange table type");
1328 lua_pushstring(L,s->str);
1329 g_string_free(s,TRUE);
1333 static const luaL_reg DissectorTable_methods[] = {
1334 {"new", DissectorTable_new },
1335 {"get", DissectorTable_get },
1336 {"add", DissectorTable_add },
1337 {"remove", DissectorTable_remove },
1338 {"try", DissectorTable_try },
1339 {"get_dissector", DissectorTable_get_dissector },
1343 static const luaL_reg DissectorTable_meta[] = {
1344 {"__tostring", DissectorTable_tostring},
1348 int DissectorTable_register(lua_State* L) {
1349 ELUA_REGISTER_CLASS(DissectorTable);