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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 /* WSLUA_MODULE Field Obtaining dissection data */
35 WSLUA_CLASS_DEFINE(FieldInfo,NOP,NOP);
40 WSLUA_METAMETHOD FieldInfo__len(lua_State* L) {
42 Obtain the Length of the field
44 FieldInfo fi = checkFieldInfo(L,1);
45 lua_pushnumber(L,fi->length);
49 WSLUA_METAMETHOD FieldInfo__unm(lua_State* L) {
51 Obtain the Offset of the field
53 FieldInfo fi = checkFieldInfo(L,1);
54 lua_pushnumber(L,fi->start);
58 WSLUA_METAMETHOD FieldInfo__call(lua_State* L) {
60 Obtain the Value of the field
62 FieldInfo fi = checkFieldInfo(L,1);
64 switch(fi->hfinfo->type) {
66 lua_pushboolean(L,(int)fvalue_get_uinteger(&(fi->value)));
73 lua_pushnumber(L,(lua_Number)fvalue_get_uinteger(&(fi->value)));
79 lua_pushnumber(L,(lua_Number)fvalue_get_sinteger(&(fi->value)));
83 lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value)));
86 Int64 num = (Int64)g_malloc(sizeof(gint64));
87 *num = fvalue_get_integer64(&(fi->value));
92 UInt64 num = (UInt64)g_malloc(sizeof(guint64));
93 *num = fvalue_get_integer64(&(fi->value));
98 Address eth = (Address)g_malloc(sizeof(address));
100 eth->len = fi->length;
101 eth->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
106 Address ipv4 = (Address)g_malloc(sizeof(address));
107 ipv4->type = AT_IPv4;
108 ipv4->len = fi->length;
109 ipv4->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
114 Address ipv6 = (Address)g_malloc(sizeof(address));
115 ipv6->type = AT_IPv6;
116 ipv6->len = fi->length;
117 ipv6->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
122 Address ipx = (Address)g_malloc(sizeof(address));
124 ipx->len = fi->length;
125 ipx->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
129 case FT_ABSOLUTE_TIME:
130 case FT_RELATIVE_TIME: {
131 NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t));
132 *nstime = *(NSTime)fvalue_get(&(fi->value));
133 pushNSTime(L,nstime);
138 gchar* repr = fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL);
140 lua_pushstring(L,repr);
142 luaL_error(L,"field cannot be represented as string because it may contain invalid characters");
147 if (fi->length == 0) {
157 ByteArray ba = g_byte_array_new();
158 g_byte_array_append(ba, (const guint8 *)ep_tvb_memdup(fi->ds_tvb,fi->start,fi->length),fi->length);
163 luaL_error(L,"FT_ not yet supported");
168 WSLUA_METAMETHOD FieldInfo__tostring(lua_State* L) {
169 /* The string representation of the field */
170 FieldInfo fi = checkFieldInfo(L,1);
173 return luaL_error(L,"Missing FieldInfo object");
176 if (fi->value.ftype->val_to_string_repr) {
177 gchar* repr = fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL);
179 lua_pushstring(L,repr);
182 lua_pushstring(L,"(unknown)");
185 else if (fi->hfinfo->type == FT_NONE) {
186 lua_pushstring(L, "(none)");
189 lua_pushstring(L,"(n/a)");
195 static int FieldInfo_display(lua_State* L) {
196 /* The display string of this field as seen in GUI */
197 FieldInfo fi = checkFieldInfo(L,1);
198 gchar label_str[ITEM_LABEL_LENGTH+1];
205 label_ptr = label_str;
206 proto_item_fill_label(fi, label_str);
208 label_ptr = fi->rep->representation;
210 if (!label_ptr) return 0;
212 value_ptr = strstr(label_ptr, ": ");
214 /* just use whatever's there */
215 lua_pushstring(L, label_ptr);
217 value_ptr += 2; /* get past the ': ' */
218 lua_pushstring(L, value_ptr);
224 static int FieldInfo_get_range(lua_State* L) {
225 /* The TvbRange covering this field */
226 FieldInfo fi = checkFieldInfo(L,1);
227 TvbRange r = ep_new(struct _wslua_tvbrange);
228 r->tvb = ep_new(struct _wslua_tvb);
230 r->tvb->ws_tvb = fi->ds_tvb;
231 r->tvb->expired = FALSE;
232 r->tvb->need_free = FALSE;
233 r->offset = fi->start;
240 static int FieldInfo_get_generated(lua_State* L) {
241 /* Whether this field was marked as generated. */
242 FieldInfo fi = checkFieldInfo(L,1);
243 lua_pushboolean(L,FI_GET_FLAG(fi, FI_GENERATED));
247 static int FieldInfo_get_name(lua_State* L) {
248 /* The filter name of this field. */
249 FieldInfo fi = checkFieldInfo(L,1);
250 lua_pushstring(L,fi->hfinfo->abbrev);
254 static const luaL_Reg FieldInfo_get[] = {
255 /* {"data_source", FieldInfo_get_data_source }, */
256 {"range", FieldInfo_get_range},
257 /* {"hidden", FieldInfo_get_hidden}, */
258 {"generated", FieldInfo_get_generated},
260 /* WSLUA_ATTRIBUTE FieldInfo_name RO The name of this field */
261 {"name", FieldInfo_get_name},
262 /* WSLUA_ATTRIBUTE FieldInfo_label RO The string representing this field */
263 {"label", FieldInfo__tostring},
264 /* WSLUA_ATTRIBUTE FieldInfo_value RO The value of this field */
265 {"value", FieldInfo__call},
266 /* WSLUA_ATTRIBUTE FieldInfo_tvb RO A tvbrange covering this field */
267 {"tvb", FieldInfo_get_range},
268 /* WSLUA_ATTRIBUTE FieldInfo_len RO The length of this field */
269 {"len", FieldInfo__len},
270 /* WSLUA_ATTRIBUTE FieldInfo_offset RO The offset of this field */
271 {"offset", FieldInfo__unm},
272 /* WSLUA_ATTRIBUTE FieldInfo_display RO The string display of this field as seen in GUI */
273 {"display", FieldInfo_display},
277 static int FieldInfo__index(lua_State* L) {
281 const gchar* idx = luaL_checkstring(L,2);
286 for (r = FieldInfo_get; r->name; r++) {
287 if (g_str_equal(r->name, idx)) {
295 WSLUA_METAMETHOD FieldInfo__eq(lua_State* L) {
296 /* Checks whether lhs is within rhs */
297 FieldInfo l = checkFieldInfo(L,1);
298 FieldInfo r = checkFieldInfo(L,2);
300 if (l->ds_tvb != r->ds_tvb)
301 WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields");
303 if (l->start <= r->start && r->start + r->length <= l->start + r->length) {
304 lua_pushboolean(L,1);
311 WSLUA_METAMETHOD FieldInfo__le(lua_State* L) {
312 /* Checks whether the end byte of lhs is before the end of rhs */
313 FieldInfo l = checkFieldInfo(L,1);
314 FieldInfo r = checkFieldInfo(L,2);
316 if (l->ds_tvb != r->ds_tvb)
317 WSLUA_ERROR(FieldInfo__le,"Data source must be the same for both fields");
319 if (r->start + r->length <= l->start + r->length) {
320 lua_pushboolean(L,1);
327 WSLUA_METAMETHOD FieldInfo__lt(lua_State* L) {
328 /* Checks whether the end byte of rhs is before the beginning of rhs */
329 FieldInfo l = checkFieldInfo(L,1);
330 FieldInfo r = checkFieldInfo(L,2);
332 if (l->ds_tvb != r->ds_tvb)
333 WSLUA_ERROR(FieldInfo__lt,"Data source must be the same for both fields");
335 if ( r->start + r->length < l->start ) {
336 lua_pushboolean(L,1);
343 static int FieldInfo__gc(lua_State* L _U_) {
344 /* do NOT free FieldInfo */
348 static const luaL_Reg FieldInfo_meta[] = {
349 {"__tostring", FieldInfo__tostring},
350 {"__call", FieldInfo__call},
351 {"__index", FieldInfo__index},
352 {"__len", FieldInfo__len},
353 {"__unm", FieldInfo__unm},
354 {"__eq", FieldInfo__eq},
355 {"__le", FieldInfo__le},
356 {"__lt", FieldInfo__lt},
360 int FieldInfo_register(lua_State* L) {
361 WSLUA_REGISTER_META(FieldInfo);
366 WSLUA_FUNCTION wslua_all_field_infos(lua_State* L) {
368 Obtain all fields from the current tree. Note this only gets whatever fields the underlying
369 dissectors have filled in for this packet at this time - there may be fields applicable to
370 the packet that simply aren't being filled in because at this time they're not needed for anything.
371 This function only gets what the C-side code has currently populated, not the full list.
377 if (! lua_tree || ! lua_tree->tree ) {
378 WSLUA_ERROR(wslua_all_field_infos,"Cannot be called outside a listener or dissector");
381 found = proto_all_finfos(lua_tree->tree);
384 for (i=0; i<found->len; i++) {
385 pushFieldInfo(L,(FieldInfo)g_ptr_array_index(found,i));
389 g_ptr_array_free(found,TRUE);
395 WSLUA_CLASS_DEFINE(Field,NOP,NOP);
397 A Field extractor to to obtain field values.
400 static GPtrArray* wanted_fields = NULL;
401 static dfilter_t* wslua_dfilter = NULL;
403 /* We use a fake dfilter for Lua field extractors, so that
404 * epan_dissect_run() will populate the fields. This won't happen
405 * if the passed-in edt->tree is NULL, which it will be if the
406 * proto_tree isn't created by epan_dissect_init(). But that's by
407 * design - if shark doesn't pass in a proto_tree, it's probably for
408 * a good reason and we shouldn't override that. (right?)
410 void wslua_prime_dfilter(epan_dissect_t *edt) {
411 if (wslua_dfilter && edt && edt->tree) {
412 dfilter_prime_proto_tree(wslua_dfilter, edt->tree);
417 * field extractor registartion is tricky, In order to allow
418 * the user to define them in the body of the script we will
419 * populate the Field value with a pointer of the abbrev of it
420 * to later replace it with the hfi.
422 * This will be added to the wanted_fields array that will
423 * exists only while they can be defined, and be cleared right
424 * after the fields are primed.
427 void lua_prime_all_fields(proto_tree* tree _U_) {
428 GString* fake_tap_filter = g_string_new("frame");
430 static gboolean fake_tap = FALSE;
432 for(i=0; i < wanted_fields->len; i++) {
433 Field f = (Field)g_ptr_array_index(wanted_fields,i);
434 gchar* name = *((gchar**)f);
436 *f = proto_registrar_get_byname(name);
439 report_failure("Could not find field `%s'",name);
447 g_string_append_printf(fake_tap_filter," || %s",(*f)->abbrev);
451 g_ptr_array_free(wanted_fields,TRUE);
452 wanted_fields = NULL;
455 /* a boring tap :-) */
456 GString* error = register_tap_listener("frame",
458 fake_tap_filter->str,
459 0, /* XXX - do we need the protocol tree or columns? */
463 report_failure("while registering lua_fake_tap:\n%s",error->str);
464 g_string_free(error,TRUE);
466 else if (!dfilter_compile(fake_tap_filter->str, &wslua_dfilter)) {
467 report_failure("while compiling dfilter for wslua: '%s'", fake_tap_filter->str);
473 WSLUA_CONSTRUCTOR Field_new(lua_State *L) {
475 Create a Field extractor
477 #define WSLUA_ARG_Field_new_FIELDNAME 1 /* The filter name of the field (e.g. ip.addr) */
478 const gchar* name = luaL_checkstring(L,WSLUA_ARG_Field_new_FIELDNAME);
483 if (!proto_registrar_get_byname(name))
484 WSLUA_ARG_ERROR(Field_new,FIELDNAME,"a field with this name must exist");
487 WSLUA_ERROR(Field_new,"A Field extractor must be defined before Taps or Dissectors get called");
489 f = (Field)g_malloc(sizeof(void*));
490 *f = (header_field_info*)g_strdup(name); /* cheating */
492 g_ptr_array_add(wanted_fields,f);
495 WSLUA_RETURN(1); /* The field extractor */
498 WSLUA_METAMETHOD Field__call (lua_State* L) {
499 /* Obtain all values (see FieldInfo) for this field. */
500 Field f = checkField(L,1);
501 header_field_info* in = *f;
505 luaL_error(L,"invalid field");
510 WSLUA_ERROR(Field__call,"Fields cannot be used outside dissectors or taps");
514 GPtrArray* found = proto_get_finfo_ptr_array(lua_tree->tree, in->id);
517 for (i=0; i<found->len; i++) {
518 pushFieldInfo(L,(FieldInfo)g_ptr_array_index(found,i));
522 in = (in->same_name_prev_id != -1) ? proto_registrar_get_nth(in->same_name_prev_id) : NULL;
525 WSLUA_RETURN(items_found); /* All the values of this field */
528 WSLUA_METAMETHOD Field__tostring(lua_State* L) {
529 /* Obtain a string with the field name */
530 Field f = checkField(L,1);
533 luaL_error(L,"invalid Field");
538 lua_pushstring(L,*((gchar**)f));
540 lua_pushstring(L,(*f)->abbrev);
546 static int Field__gc(lua_State* L _U_) {
547 /* do NOT free Field */
551 static const luaL_Reg Field_methods[] = {
556 static const luaL_Reg Field_meta[] = {
557 {"__tostring", Field__tostring},
558 {"__call", Field__call},
562 int Field_register(lua_State* L) {
564 wanted_fields = g_ptr_array_new();
566 WSLUA_REGISTER_CLASS(Field);
572 * Editor modelines - http://www.wireshark.org/tools/modelines.html
577 * indent-tabs-mode: nil
580 * vi: set shiftwidth=4 tabstop=8 expandtab:
581 * :indentSize=4:tabSize=8:noTabs=true: