4 * Wireshark's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <epan/emem.h>
30 #include <epan/dfilter/dfilter.h>
31 #include <epan/ftypes/ftypes-int.h>
33 /* WSLUA_MODULE Field Obtaining dissection data */
37 /* any call to checkFieldInfo() will now error on null or expired, so no need to check again */
38 WSLUA_CLASS_DEFINE(FieldInfo,FAIL_ON_NULL_OR_EXPIRED("FieldInfo"),NOP);
40 An extracted Field from dissected packet data. A `FieldInfo` object can only be used within
41 the callback functions of dissectors, post-dissectors, heuristic-dissectors, and taps.
43 A `FieldInfo` can be called on either existing Wireshark fields by using either `Field.new()`
44 or `Field()` before-hand, or it can be called on new fields created by Lua from a `ProtoField`.
47 static GPtrArray* outstanding_FieldInfo = NULL;
49 #define PUSH_FIELDINFO(L,fi) {g_ptr_array_add(outstanding_FieldInfo,fi);pushFieldInfo(L,fi);}
51 CLEAR_OUTSTANDING(FieldInfo,expired,TRUE)
53 /* WSLUA_ATTRIBUTE FieldInfo_len RO The length of this field. */
54 WSLUA_METAMETHOD FieldInfo__len(lua_State* L) {
56 Obtain the Length of the field
58 FieldInfo fi = checkFieldInfo(L,1);
60 lua_pushnumber(L,fi->ws_fi->length);
64 /* WSLUA_ATTRIBUTE FieldInfo_offset RO The offset of this field. */
65 WSLUA_METAMETHOD FieldInfo__unm(lua_State* L) {
67 Obtain the Offset of the field
69 FieldInfo fi = checkFieldInfo(L,1);
71 lua_pushnumber(L,fi->ws_fi->start);
75 /* WSLUA_ATTRIBUTE FieldInfo_value RO The value of this field. */
76 WSLUA_METAMETHOD FieldInfo__call(lua_State* L) {
78 Obtain the Value of the field.
80 Previous to 1.11.4, this function retrieved the value for most field types,
81 but for `ftypes.UINT_BYTES` it retrieved the `ByteArray` of the field's entire `TvbRange`.
82 In other words, it returned a `ByteArray` that included the leading length byte(s),
83 instead of just the *value* bytes. That was a bug, and has been changed in 1.11.4.
84 Furthermore, it retrieved an `ftypes.GUID` as a `ByteArray`, which is also incorrect.
86 If you wish to still get a `ByteArray` of the `TvbRange`, use `FieldInfo:get_range()`
87 to get the `TvbRange`, and then use `Tvb:bytes()` to convert it to a `ByteArray`.
89 FieldInfo fi = checkFieldInfo(L,1);
91 switch(fi->ws_fi->hfinfo->type) {
93 lua_pushboolean(L,(int)fvalue_get_uinteger(&(fi->ws_fi->value)));
100 lua_pushnumber(L,(lua_Number)(fvalue_get_uinteger(&(fi->ws_fi->value))));
106 lua_pushnumber(L,(lua_Number)(fvalue_get_sinteger(&(fi->ws_fi->value))));
110 lua_pushnumber(L,(lua_Number)(fvalue_get_floating(&(fi->ws_fi->value))));
113 pushInt64(L,(Int64)(fvalue_get_integer64(&(fi->ws_fi->value))));
117 pushUInt64(L,fvalue_get_integer64(&(fi->ws_fi->value)));
121 Address eth = (Address)g_malloc(sizeof(address));
122 eth->type = AT_ETHER;
123 eth->len = fi->ws_fi->length;
124 eth->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length);
129 Address ipv4 = (Address)g_malloc(sizeof(address));
130 ipv4->type = AT_IPv4;
131 ipv4->len = fi->ws_fi->length;
132 ipv4->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length);
137 Address ipv6 = (Address)g_malloc(sizeof(address));
138 ipv6->type = AT_IPv6;
139 ipv6->len = fi->ws_fi->length;
140 ipv6->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length);
145 Address ipx = (Address)g_malloc(sizeof(address));
147 ipx->len = fi->ws_fi->length;
148 ipx->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length);
152 case FT_ABSOLUTE_TIME:
153 case FT_RELATIVE_TIME: {
154 NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t));
155 *nstime = *(NSTime)fvalue_get(&(fi->ws_fi->value));
156 pushNSTime(L,nstime);
161 gchar* repr = fvalue_to_string_repr(&fi->ws_fi->value,FTREPR_DISPLAY,NULL);
163 lua_pushstring(L,repr);
165 luaL_error(L,"field cannot be represented as string because it may contain invalid characters");
170 if (fi->ws_fi->length == 0) {
181 ByteArray ba = g_byte_array_new();
182 g_byte_array_append(ba, (const guint8 *) fvalue_get(&fi->ws_fi->value),
183 fvalue_length(&fi->ws_fi->value));
189 ByteArray ba = g_byte_array_new();
190 tvbuff_t* tvb = (tvbuff_t *) fvalue_get(&fi->ws_fi->value);
191 g_byte_array_append(ba, (const guint8 *)tvb_memdup(wmem_packet_scope(), tvb, 0,
192 tvb_captured_length(tvb)), tvb_captured_length(tvb));
199 luaL_error(L,"FT_ not yet supported");
204 /* WSLUA_ATTRIBUTE FieldInfo_label RO The string representing this field */
205 WSLUA_METAMETHOD FieldInfo__tostring(lua_State* L) {
206 /* The string representation of the field. */
207 FieldInfo fi = checkFieldInfo(L,1);
209 if (fi->ws_fi->value.ftype->val_to_string_repr) {
212 if (fi->ws_fi->hfinfo->type == FT_PROTOCOL || fi->ws_fi->hfinfo->type == FT_PCRE) {
213 repr = fvalue_to_string_repr(&fi->ws_fi->value,FTREPR_DFILTER,NULL);
216 repr = fvalue_to_string_repr(&fi->ws_fi->value,FTREPR_DISPLAY,NULL);
220 lua_pushstring(L,repr);
221 /* fvalue_to_string_repr() g_malloc's the string's buffer */
225 lua_pushstring(L,"(unknown)");
228 else if (fi->ws_fi->hfinfo->type == FT_NONE) {
229 lua_pushstring(L, "(none)");
232 lua_pushstring(L,"(n/a)");
238 /* WSLUA_ATTRIBUTE FieldInfo_display RO The string display of this field as seen in GUI */
239 static int FieldInfo_get_display(lua_State* L) {
240 /* The display string of this field as seen in GUI. */
241 FieldInfo fi = checkFieldInfo(L,1);
242 gchar label_str[ITEM_LABEL_LENGTH+1];
246 if (!fi->ws_fi->rep) {
247 label_ptr = label_str;
248 proto_item_fill_label(fi->ws_fi, label_str);
250 label_ptr = fi->ws_fi->rep->representation;
252 if (!label_ptr) return 0;
254 value_ptr = strstr(label_ptr, ": ");
256 /* just use whatever's there */
257 lua_pushstring(L, label_ptr);
259 value_ptr += 2; /* get past the ': ' */
260 lua_pushstring(L, value_ptr);
266 /* WSLUA_ATTRIBUTE FieldInfo_range RO The `TvbRange` covering this field */
267 static int FieldInfo_get_range(lua_State* L) {
268 /* The `TvbRange` covering this field. */
269 FieldInfo fi = checkFieldInfo(L,1);
271 if (push_TvbRange (L, fi->ws_fi->ds_tvb, fi->ws_fi->start, fi->ws_fi->length)) {
278 /* WSLUA_ATTRIBUTE FieldInfo_generated RO Whether this field was marked as generated (boolean) */
279 static int FieldInfo_get_generated(lua_State* L) {
280 /* Whether this field was marked as generated. */
281 FieldInfo fi = checkFieldInfo(L,1);
283 lua_pushboolean(L,FI_GET_FLAG(fi->ws_fi, FI_GENERATED));
287 /* WSLUA_ATTRIBUTE FieldInfo_name RO The name of this field */
288 static int FieldInfo_get_name(lua_State* L) {
289 /* The filter name of this field. */
290 FieldInfo fi = checkFieldInfo(L,1);
292 lua_pushstring(L,fi->ws_fi->hfinfo->abbrev);
296 WSLUA_METAMETHOD FieldInfo__eq(lua_State* L) {
297 /* Checks whether lhs is within rhs. */
298 FieldInfo l = checkFieldInfo(L,1);
299 FieldInfo r = checkFieldInfo(L,2);
301 if (l->ws_fi->ds_tvb != r->ws_fi->ds_tvb) {
302 WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields");
306 if (l->ws_fi->start <= r->ws_fi->start && r->ws_fi->start + r->ws_fi->length <= l->ws_fi->start + r->ws_fi->length) {
307 lua_pushboolean(L,1);
314 WSLUA_METAMETHOD FieldInfo__le(lua_State* L) {
315 /* Checks whether the end byte of lhs is before the end of rhs. */
316 FieldInfo l = checkFieldInfo(L,1);
317 FieldInfo r = checkFieldInfo(L,2);
319 if (l->ws_fi->ds_tvb != r->ws_fi->ds_tvb)
320 WSLUA_ERROR(FieldInfo__le,"Data source must be the same for both fields");
322 if (r->ws_fi->start + r->ws_fi->length <= l->ws_fi->start + r->ws_fi->length) {
323 lua_pushboolean(L,1);
330 WSLUA_METAMETHOD FieldInfo__lt(lua_State* L) {
331 /* Checks whether the end byte of rhs is before the beginning of rhs. */
332 FieldInfo l = checkFieldInfo(L,1);
333 FieldInfo r = checkFieldInfo(L,2);
335 if (l->ws_fi->ds_tvb != r->ws_fi->ds_tvb) {
336 WSLUA_ERROR(FieldInfo__lt,"Data source must be the same for both fields");
340 if (r->ws_fi->start + r->ws_fi->length < l->ws_fi->start) {
341 lua_pushboolean(L,1);
348 /* Gets registered as metamethod automatically by WSLUA_REGISTER_META */
349 static int FieldInfo__gc(lua_State* L _U_) {
350 FieldInfo fi = toFieldInfo(L,1);
357 /* do NOT free fi->ws_fi */
363 /* This table is ultimately registered as a sub-table of the class' metatable,
364 * and if __index/__newindex is invoked then it calls the appropriate function
365 * from this table for getting/setting the members.
367 WSLUA_ATTRIBUTES FieldInfo_attributes[] = {
368 WSLUA_ATTRIBUTE_ROREG(FieldInfo,range),
369 WSLUA_ATTRIBUTE_ROREG(FieldInfo,generated),
370 WSLUA_ATTRIBUTE_ROREG(FieldInfo,name),
371 WSLUA_ATTRIBUTE_ROREG(FieldInfo,display),
372 { "label", FieldInfo__tostring, NULL },
373 { "value", FieldInfo__call, NULL },
374 { "tvb", FieldInfo_get_range, NULL },
375 { "len", FieldInfo__len, NULL },
376 { "offset", FieldInfo__unm, NULL },
380 WSLUA_META FieldInfo_meta[] = {
381 WSLUA_CLASS_MTREG(FieldInfo,tostring),
382 WSLUA_CLASS_MTREG(FieldInfo,call),
383 WSLUA_CLASS_MTREG(FieldInfo,len),
384 WSLUA_CLASS_MTREG(FieldInfo,unm),
385 WSLUA_CLASS_MTREG(FieldInfo,eq),
386 WSLUA_CLASS_MTREG(FieldInfo,le),
387 WSLUA_CLASS_MTREG(FieldInfo,lt),
391 int FieldInfo_register(lua_State* L) {
392 WSLUA_REGISTER_META(FieldInfo);
393 WSLUA_REGISTER_ATTRIBUTES(FieldInfo);
398 WSLUA_FUNCTION wslua_all_field_infos(lua_State* L) {
400 Obtain all fields from the current tree. Note this only gets whatever fields the underlying
401 dissectors have filled in for this packet at this time - there may be fields applicable to
402 the packet that simply aren't being filled in because at this time they're not needed for anything.
403 This function only gets what the C-side code has currently populated, not the full list.
409 if (! lua_tree || ! lua_tree->tree ) {
410 WSLUA_ERROR(wslua_all_field_infos,"Cannot be called outside a listener or dissector");
414 found = proto_all_finfos(lua_tree->tree);
417 for (i=0; i<found->len; i++) {
418 FieldInfo fi = (FieldInfo)g_malloc(sizeof(struct _wslua_field_info));
419 fi->ws_fi = (field_info *)g_ptr_array_index(found,i);
422 PUSH_FIELDINFO(L,fi);
426 g_ptr_array_free(found,TRUE);
432 WSLUA_CLASS_DEFINE(Field,FAIL_ON_NULL("Field"),NOP);
434 A Field extractor to to obtain field values. A `Field` object can only be created *outside* of
435 the callback functions of dissectors, post-dissectors, heuristic-dissectors, and taps.
437 Once created, it is used *inside* the callback functions, to generate a `FieldInfo` object.
440 static GPtrArray* wanted_fields = NULL;
441 static dfilter_t* wslua_dfilter = NULL;
443 /* We use a fake dfilter for Lua field extractors, so that
444 * epan_dissect_run() will populate the fields. This won't happen
445 * if the passed-in edt->tree is NULL, which it will be if the
446 * proto_tree isn't created by epan_dissect_init(). But that's by
447 * design - if shark doesn't pass in a proto_tree, it's probably for
448 * a good reason and we shouldn't override that. (right?)
450 void wslua_prime_dfilter(epan_dissect_t *edt) {
451 if (wslua_dfilter && edt && edt->tree) {
452 dfilter_prime_proto_tree(wslua_dfilter, edt->tree);
457 * field extractor registration is tricky, In order to allow
458 * the user to define them in the body of the script we will
459 * populate the Field value with a pointer of the abbrev of it
460 * to later replace it with the hfi.
462 * This will be added to the wanted_fields array that will
463 * exists only while they can be defined, and be cleared right
464 * after the fields are primed.
467 void lua_prime_all_fields(proto_tree* tree _U_) {
468 GString* fake_tap_filter = g_string_new("frame");
470 static gboolean fake_tap = FALSE;
472 for(i=0; i < wanted_fields->len; i++) {
473 Field f = (Field)g_ptr_array_index(wanted_fields,i);
474 gchar* name = *((gchar**)f);
476 *f = proto_registrar_get_byname(name);
479 report_failure("Could not find field `%s'",name);
487 g_string_append_printf(fake_tap_filter," || %s",(*f)->abbrev);
491 g_ptr_array_free(wanted_fields,TRUE);
492 wanted_fields = NULL;
495 /* a boring tap :-) */
496 GString* error = register_tap_listener("frame",
498 fake_tap_filter->str,
499 0, /* XXX - do we need the protocol tree or columns? */
503 report_failure("while registering lua_fake_tap:\n%s",error->str);
504 g_string_free(error,TRUE);
507 dfilter_free(wslua_dfilter);
508 wslua_dfilter = NULL;
510 if (!dfilter_compile(fake_tap_filter->str, &wslua_dfilter)) {
511 report_failure("while compiling dfilter for wslua: '%s'", fake_tap_filter->str);
518 WSLUA_CONSTRUCTOR Field_new(lua_State *L) {
520 Create a Field extractor.
522 #define WSLUA_ARG_Field_new_FIELDNAME 1 /* The filter name of the field (e.g. ip.addr) */
523 const gchar* name = luaL_checkstring(L,WSLUA_ARG_Field_new_FIELDNAME);
526 if (!proto_registrar_get_byname(name) && !wslua_is_field_available(L, name)) {
527 WSLUA_ARG_ERROR(Field_new,FIELDNAME,"a field with this name must exist");
531 if (!wanted_fields) {
532 WSLUA_ERROR(Field_new,"A Field extractor must be defined before Taps or Dissectors get called");
536 f = (Field)g_malloc(sizeof(void*));
537 *f = (header_field_info*)(void*)g_strdup(name); /* cheating */
539 g_ptr_array_add(wanted_fields,f);
542 WSLUA_RETURN(1); /* The field extractor */
545 WSLUA_CONSTRUCTOR Field_list(lua_State *L) {
546 /* Gets a Lua array table of all registered field filter names.
548 NOTE: this is an expensive operation, and should only be used for troubleshooting.
552 void *cookie, *cookie2;
555 header_field_info *hfinfo = NULL;
559 for (i = proto_get_first_protocol(&cookie); i != -1;
560 i = proto_get_next_protocol(&cookie)) {
562 for (hfinfo = proto_get_first_protocol_field(i, &cookie2); hfinfo != NULL;
563 hfinfo = proto_get_next_protocol_field(i, &cookie2)) {
565 if (hfinfo->same_name_prev_id != -1) /* ignore duplicate names */
569 lua_pushstring(L,hfinfo->abbrev);
570 lua_rawseti(L,1,count);
574 WSLUA_RETURN(1); /* The array table of field filter names */
577 WSLUA_METAMETHOD Field__call (lua_State* L) {
578 /* Obtain all values (see `FieldInfo`) for this field. */
579 Field f = checkField(L,1);
580 header_field_info* in = *f;
584 luaL_error(L,"invalid field");
589 WSLUA_ERROR(Field__call,"Fields cannot be used outside dissectors or taps");
594 GPtrArray* found = proto_get_finfo_ptr_array(lua_tree->tree, in->id);
597 for (i=0; i<found->len; i++) {
598 FieldInfo fi = (FieldInfo)g_malloc(sizeof(struct _wslua_field_info));
599 fi->ws_fi = (field_info *)g_ptr_array_index(found,i);
602 PUSH_FIELDINFO(L,fi);
606 in = (in->same_name_prev_id != -1) ? proto_registrar_get_nth(in->same_name_prev_id) : NULL;
609 WSLUA_RETURN(items_found); /* All the values of this field */
612 WSLUA_METAMETHOD Field__tostring(lua_State* L) {
613 /* Obtain a string with the field name. */
614 Field f = checkField(L,1);
617 lua_pushstring(L,*((gchar**)f));
619 lua_pushstring(L,(*f)->abbrev);
625 static int Field__gc(lua_State* L _U_) {
626 /* do NOT free Field */
630 WSLUA_METHODS Field_methods[] = {
631 WSLUA_CLASS_FNREG(Field,new),
632 WSLUA_CLASS_FNREG(Field,list),
636 WSLUA_META Field_meta[] = {
637 WSLUA_CLASS_MTREG(Field,tostring),
638 WSLUA_CLASS_MTREG(Field,call),
642 int Field_register(lua_State* L) {
644 wanted_fields = g_ptr_array_new();
646 WSLUA_REGISTER_CLASS(Field);
647 outstanding_FieldInfo = g_ptr_array_new();
653 * Editor modelines - http://www.wireshark.org/tools/modelines.html
658 * indent-tabs-mode: nil
661 * vi: set shiftwidth=4 tabstop=8 expandtab:
662 * :indentSize=4:tabSize=8:noTabs=true: