4 * Wireshark's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
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.
29 /* WSLUA_MODULE Field Obtaining dissection data */
33 WSLUA_CLASS_DEFINE(FieldInfo,NOP,NOP);
38 WSLUA_METAMETHOD FieldInfo__len(lua_State* L) {
40 Obtain the Length of the field
42 FieldInfo fi = checkFieldInfo(L,1);
43 lua_pushnumber(L,fi->length);
47 WSLUA_METAMETHOD FieldInfo__unm(lua_State* L) {
49 Obtain the Offset of the field
51 FieldInfo fi = checkFieldInfo(L,1);
52 lua_pushnumber(L,fi->start);
56 WSLUA_METAMETHOD FieldInfo__call(lua_State* L) {
58 Obtain the Value of the field
60 FieldInfo fi = checkFieldInfo(L,1);
62 switch(fi->hfinfo->type) {
71 lua_pushnumber(L,(lua_Number)fvalue_get_uinteger(&(fi->value)));
77 lua_pushnumber(L,(lua_Number)fvalue_get_sinteger(&(fi->value)));
81 lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value)));
84 Int64 num = g_malloc(sizeof(Int64));
85 *num = fvalue_get_integer64(&(fi->value));
90 UInt64 num = g_malloc(sizeof(UInt64));
91 *num = fvalue_get_integer64(&(fi->value));
96 Address eth = g_malloc(sizeof(address));
98 eth->len = fi->length;
99 eth->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
104 Address ipv4 = g_malloc(sizeof(address));
105 ipv4->type = AT_IPv4;
106 ipv4->len = fi->length;
107 ipv4->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
112 Address ipv6 = g_malloc(sizeof(address));
113 ipv6->type = AT_IPv6;
114 ipv6->len = fi->length;
115 ipv6->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
120 Address ipx = g_malloc(sizeof(address));
122 ipx->len = fi->length;
123 ipx->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
129 gchar* repr = fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL);
131 lua_pushstring(L,repr);
133 luaL_error(L,"field cannot be represented as string because it may contain invalid characters");
141 ByteArray ba = g_byte_array_new();
142 g_byte_array_append(ba, ep_tvb_memdup(fi->ds_tvb,fi->start,fi->length),fi->length);
147 luaL_error(L,"FT_ not yet supported");
152 WSLUA_METAMETHOD FieldInfo__tostring(lua_State* L) {
153 /* The string representation of the field */
154 FieldInfo fi = checkFieldInfo(L,1);
156 if (fi->value.ftype->val_to_string_repr) {
157 gchar* repr = fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL);
159 lua_pushstring(L,repr);
161 luaL_error(L,"field cannot be represented as string because it may contain invalid characters");
163 luaL_error(L,"field has no string representation");
168 int FieldInfo_get_range(lua_State* L) {
169 /* The TvbRange covering this field */
170 FieldInfo fi = checkFieldInfo(L,1);
171 TvbRange r = ep_alloc(sizeof(struct _wslua_tvbrange));
172 r->tvb = ep_alloc(sizeof(struct _wslua_tvb));
174 r->tvb->ws_tvb = fi->ds_tvb;
175 r->offset = fi->start;
182 int FieldInfo_get_generated(lua_State* L) {
183 /* Whether this field was marked as generated. */
184 FieldInfo fi = checkFieldInfo(L,1);
185 lua_pushboolean(L,FI_GET_FLAG(fi, FI_GENERATED));
189 int FieldInfo_get_name(lua_State* L) {
190 /* The filter name of this field. */
191 FieldInfo fi = checkFieldInfo(L,1);
192 lua_pushstring(L,fi->hfinfo->abbrev);
196 static const luaL_reg FieldInfo_get[] = {
197 /* {"data_source", FieldInfo_get_data_source }, */
198 {"range", FieldInfo_get_range},
199 /* {"hidden", FieldInfo_get_hidden}, */
200 {"generated", FieldInfo_get_generated},
202 /* WSLUA_ATTRIBUTE FieldInfo_name RO The name of this field */
203 {"name", FieldInfo_get_name},
204 /* WSLUA_ATTRIBUTE FieldInfo_label RO The string representing this field */
205 {"label", FieldInfo__tostring},
206 /* WSLUA_ATTRIBUTE FieldInfo_value RO The value of this field */
207 {"value", FieldInfo__call},
208 /* WSLUA_ATTRIBUTE FieldInfo_len RO The length of this field */
209 {"len", FieldInfo__len},
210 /* WSLUA_ATTRIBUTE FieldInfo_offset RO The offset of this field */
211 {"offset", FieldInfo__unm},
215 static int FieldInfo__index(lua_State* L) {
219 const gchar* index = luaL_checkstring(L,2);
224 for (r = FieldInfo_get; r->name; r++) {
225 if (g_str_equal(r->name, index)) {
233 WSLUA_METAMETHOD FieldInfo__eq(lua_State* L) {
234 /* Checks whether lhs is within rhs */
235 FieldInfo l = checkFieldInfo(L,1);
236 FieldInfo r = checkFieldInfo(L,2);
238 if (l->ds_tvb != r->ds_tvb)
239 WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields");
241 if (l->start <= r->start && r->start + r->length <= l->start + r->length) {
242 lua_pushboolean(L,1);
249 WSLUA_METAMETHOD FieldInfo__le(lua_State* L) {
250 /* Checks whether the end byte of lhs is before the end of rhs */
251 FieldInfo l = checkFieldInfo(L,1);
252 FieldInfo r = checkFieldInfo(L,2);
254 if (l->ds_tvb != r->ds_tvb)
257 if (r->start + r->length <= l->start + r->length) {
258 lua_pushboolean(L,1);
265 WSLUA_METAMETHOD FieldInfo__lt(lua_State* L) {
266 /* Checks whether the end byte of rhs is before the beginning of rhs */
267 FieldInfo l = checkFieldInfo(L,1);
268 FieldInfo r = checkFieldInfo(L,2);
270 if (l->ds_tvb != r->ds_tvb)
271 WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields");
273 if ( r->start + r->length < l->start ) {
274 lua_pushboolean(L,1);
282 static const luaL_reg FieldInfo_meta[] = {
283 {"__tostring", FieldInfo__tostring},
284 {"__call", FieldInfo__call},
285 {"__index", FieldInfo__index},
286 {"__len", FieldInfo__len},
287 {"__unm", FieldInfo__unm},
288 {"__eq", FieldInfo__eq},
289 {"__le", FieldInfo__le},
290 {"__lt", FieldInfo__lt},
294 int FieldInfo_register(lua_State* L) {
295 WSLUA_REGISTER_META(FieldInfo);
300 WSLUA_FUNCTION wslua_all_field_infos(lua_State* L) {
301 /* Obtain all fields from the current tree */
306 if (! lua_tree || ! lua_tree->tree ) {
307 WSLUA_ERROR(wslua_all_field_infos,"Cannot be called outside a listener or dissector");
310 found = proto_all_finfos(lua_tree->tree);
313 for (i=0; i<found->len; i++) {
314 pushFieldInfo(L,g_ptr_array_index(found,i));
318 g_ptr_array_free(found,TRUE);
324 WSLUA_CLASS_DEFINE(Field,NOP,NOP);
326 A Field extractor to to obtain field values.
329 static GPtrArray* wanted_fields = NULL;
332 * field extractor registartion is tricky, In order to allow
333 * the user to define them in the body of the script we will
334 * populate the Field value with a pointer of the abbrev of it
335 * to later replace it with the hfi.
337 * This will be added to the wanted_fields array that will
338 * exists only while they can be defined, and be cleared right
339 * after the fields are primed.
342 void lua_prime_all_fields(proto_tree* tree _U_) {
343 GString* fake_tap_filter = g_string_new("frame");
345 static gboolean fake_tap = FALSE;
347 for(i=0; i < wanted_fields->len; i++) {
348 Field f = g_ptr_array_index(wanted_fields,i);
349 gchar* name = *((gchar**)f);
351 *f = proto_registrar_get_byname(name);
354 report_failure("Could not find field `%s'",name);
362 g_string_append_printf(fake_tap_filter," || %s",(*f)->abbrev);
366 g_ptr_array_free(wanted_fields,TRUE);
367 wanted_fields = NULL;
370 /* a boring tap :-) */
371 GString* error = register_tap_listener("frame",
373 fake_tap_filter->str,
374 0, /* XXX - do we need the protocol tree or columns? */
378 report_failure("while registering lua_fake_tap:\n%s",error->str);
379 g_string_free(error,TRUE);
385 WSLUA_CONSTRUCTOR Field_new(lua_State *L) {
387 Create a Field extractor
389 #define WSLUA_ARG_Field_new_FIELDNAME 1 /* The filter name of the field (e.g. ip.addr) */
390 const gchar* name = luaL_checkstring(L,WSLUA_ARG_Field_new_FIELDNAME);
395 if (!proto_registrar_get_byname(name))
396 WSLUA_ARG_ERROR(Field_new,FIELDNAME,"a field with this name must exist");
399 WSLUA_ERROR(Field_get,"A Field extractor must be defined before Taps or Dissectors get called");
401 f = g_malloc(sizeof(void*));
402 *f = (header_field_info*)g_strdup(name); /* cheating */
404 g_ptr_array_add(wanted_fields,f);
407 WSLUA_RETURN(1); /* The field extractor */
410 WSLUA_METAMETHOD Field__call (lua_State* L) {
411 /* Obtain all values (see FieldInfo) for this field. */
412 Field f = checkField(L,1);
413 header_field_info* in = *f;
417 luaL_error(L,"invalid field");
422 WSLUA_ERROR(Field__call,"Fields cannot be used outside dissectors or taps");
426 for (;in;in = in->same_name_next) {
427 GPtrArray* found = proto_get_finfo_ptr_array(lua_tree->tree, in->id);
430 for (i=0; i<found->len; i++) {
431 pushFieldInfo(L,g_ptr_array_index(found,i));
437 WSLUA_RETURN(items_found); /* All the values of this field */
440 WSLUA_METAMETHOD Field_tostring(lua_State* L) {
441 /* Obtain a srting with the field name */
442 Field f = checkField(L,1);
445 luaL_error(L,"invalid Field");
450 lua_pushstring(L,*((gchar**)f));
452 lua_pushstring(L,(*f)->abbrev);
458 static const luaL_reg Field_methods[] = {
463 static const luaL_reg Field_meta[] = {
464 {"__tostring", Field_tostring},
465 {"__call", Field__call},
469 int Field_register(lua_State* L) {
471 wanted_fields = g_ptr_array_new();
473 WSLUA_REGISTER_CLASS(Field);