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 #include <epan/emem.h>
32 #include <epan/ftypes/ftypes-int.h>
34 /* WSLUA_MODULE Field Obtaining dissection data */
38 WSLUA_CLASS_DEFINE(FieldInfo
,NOP
,NOP
);
43 WSLUA_METAMETHOD
FieldInfo__len(lua_State
* L
) {
45 Obtain the Length of the field
47 FieldInfo fi
= checkFieldInfo(L
,1);
48 lua_pushnumber(L
,fi
->length
);
52 WSLUA_METAMETHOD
FieldInfo__unm(lua_State
* L
) {
54 Obtain the Offset of the field
56 FieldInfo fi
= checkFieldInfo(L
,1);
57 lua_pushnumber(L
,fi
->start
);
61 WSLUA_METAMETHOD
FieldInfo__call(lua_State
* L
) {
63 Obtain the Value of the field
65 FieldInfo fi
= checkFieldInfo(L
,1);
67 switch(fi
->hfinfo
->type
) {
69 lua_pushboolean(L
,(int)fvalue_get_uinteger(&(fi
->value
)));
76 lua_pushnumber(L
,(lua_Number
)fvalue_get_uinteger(&(fi
->value
)));
82 lua_pushnumber(L
,(lua_Number
)fvalue_get_sinteger(&(fi
->value
)));
86 lua_pushnumber(L
,(lua_Number
)fvalue_get_floating(&(fi
->value
)));
89 Int64 num
= (Int64
)g_malloc(sizeof(gint64
));
90 *num
= fvalue_get_integer64(&(fi
->value
));
95 UInt64 num
= (UInt64
)g_malloc(sizeof(guint64
));
96 *num
= fvalue_get_integer64(&(fi
->value
));
101 Address eth
= (Address
)g_malloc(sizeof(address
));
102 eth
->type
= AT_ETHER
;
103 eth
->len
= fi
->length
;
104 eth
->data
= tvb_memdup(NULL
,fi
->ds_tvb
,fi
->start
,fi
->length
);
109 Address ipv4
= (Address
)g_malloc(sizeof(address
));
110 ipv4
->type
= AT_IPv4
;
111 ipv4
->len
= fi
->length
;
112 ipv4
->data
= tvb_memdup(NULL
,fi
->ds_tvb
,fi
->start
,fi
->length
);
117 Address ipv6
= (Address
)g_malloc(sizeof(address
));
118 ipv6
->type
= AT_IPv6
;
119 ipv6
->len
= fi
->length
;
120 ipv6
->data
= tvb_memdup(NULL
,fi
->ds_tvb
,fi
->start
,fi
->length
);
125 Address ipx
= (Address
)g_malloc(sizeof(address
));
127 ipx
->len
= fi
->length
;
128 ipx
->data
= tvb_memdup(NULL
,fi
->ds_tvb
,fi
->start
,fi
->length
);
132 case FT_ABSOLUTE_TIME
:
133 case FT_RELATIVE_TIME
: {
134 NSTime nstime
= (NSTime
)g_malloc(sizeof(nstime_t
));
135 *nstime
= *(NSTime
)fvalue_get(&(fi
->value
));
136 pushNSTime(L
,nstime
);
141 gchar
* repr
= fvalue_to_string_repr(&fi
->value
,FTREPR_DISPLAY
,NULL
);
143 lua_pushstring(L
,repr
);
145 luaL_error(L
,"field cannot be represented as string because it may contain invalid characters");
150 if (fi
->length
== 0) {
161 ByteArray ba
= g_byte_array_new();
162 g_byte_array_append(ba
, (const guint8
*)tvb_memdup(wmem_packet_scope(),fi
->ds_tvb
,fi
->start
,fi
->length
),fi
->length
);
167 luaL_error(L
,"FT_ not yet supported");
172 WSLUA_METAMETHOD
FieldInfo__tostring(lua_State
* L
) {
173 /* The string representation of the field */
174 FieldInfo fi
= checkFieldInfo(L
,1);
177 return luaL_error(L
,"Missing FieldInfo object");
180 if (fi
->value
.ftype
->val_to_string_repr
) {
181 gchar
* repr
= fvalue_to_string_repr(&fi
->value
,FTREPR_DISPLAY
,NULL
);
183 lua_pushstring(L
,repr
);
186 lua_pushstring(L
,"(unknown)");
189 else if (fi
->hfinfo
->type
== FT_NONE
) {
190 lua_pushstring(L
, "(none)");
193 lua_pushstring(L
,"(n/a)");
199 static int FieldInfo_display(lua_State
* L
) {
200 /* The display string of this field as seen in GUI */
201 FieldInfo fi
= checkFieldInfo(L
,1);
202 gchar label_str
[ITEM_LABEL_LENGTH
+1];
209 label_ptr
= label_str
;
210 proto_item_fill_label(fi
, label_str
);
212 label_ptr
= fi
->rep
->representation
;
214 if (!label_ptr
) return 0;
216 value_ptr
= strstr(label_ptr
, ": ");
218 /* just use whatever's there */
219 lua_pushstring(L
, label_ptr
);
221 value_ptr
+= 2; /* get past the ': ' */
222 lua_pushstring(L
, value_ptr
);
228 static int FieldInfo_get_range(lua_State
* L
) {
229 /* The TvbRange covering this field */
230 FieldInfo fi
= checkFieldInfo(L
,1);
231 TvbRange r
= ep_new(struct _wslua_tvbrange
);
232 r
->tvb
= ep_new(struct _wslua_tvb
);
234 r
->tvb
->ws_tvb
= fi
->ds_tvb
;
235 r
->tvb
->expired
= FALSE
;
236 r
->tvb
->need_free
= FALSE
;
237 r
->offset
= fi
->start
;
244 static int FieldInfo_get_generated(lua_State
* L
) {
245 /* Whether this field was marked as generated. */
246 FieldInfo fi
= checkFieldInfo(L
,1);
247 lua_pushboolean(L
,FI_GET_FLAG(fi
, FI_GENERATED
));
251 static int FieldInfo_get_name(lua_State
* L
) {
252 /* The filter name of this field. */
253 FieldInfo fi
= checkFieldInfo(L
,1);
254 lua_pushstring(L
,fi
->hfinfo
->abbrev
);
258 static const luaL_Reg FieldInfo_get
[] = {
259 /* {"data_source", FieldInfo_get_data_source }, */
260 {"range", FieldInfo_get_range
},
261 /* {"hidden", FieldInfo_get_hidden}, */
262 {"generated", FieldInfo_get_generated
},
264 /* WSLUA_ATTRIBUTE FieldInfo_name RO The name of this field */
265 {"name", FieldInfo_get_name
},
266 /* WSLUA_ATTRIBUTE FieldInfo_label RO The string representing this field */
267 {"label", FieldInfo__tostring
},
268 /* WSLUA_ATTRIBUTE FieldInfo_value RO The value of this field */
269 {"value", FieldInfo__call
},
270 /* WSLUA_ATTRIBUTE FieldInfo_tvb RO A tvbrange covering this field */
271 {"tvb", FieldInfo_get_range
},
272 /* WSLUA_ATTRIBUTE FieldInfo_len RO The length of this field */
273 {"len", FieldInfo__len
},
274 /* WSLUA_ATTRIBUTE FieldInfo_offset RO The offset of this field */
275 {"offset", FieldInfo__unm
},
276 /* WSLUA_ATTRIBUTE FieldInfo_display RO The string display of this field as seen in GUI */
277 {"display", FieldInfo_display
},
281 static int FieldInfo__index(lua_State
* L
) {
285 const gchar
* idx
= luaL_checkstring(L
,2);
290 for (r
= FieldInfo_get
; r
->name
; r
++) {
291 if (g_str_equal(r
->name
, idx
)) {
299 WSLUA_METAMETHOD
FieldInfo__eq(lua_State
* L
) {
300 /* Checks whether lhs is within rhs */
301 FieldInfo l
= checkFieldInfo(L
,1);
302 FieldInfo r
= checkFieldInfo(L
,2);
304 if (l
->ds_tvb
!= r
->ds_tvb
)
305 WSLUA_ERROR(FieldInfo__eq
,"Data source must be the same for both fields");
307 if (l
->start
<= r
->start
&& r
->start
+ r
->length
<= l
->start
+ r
->length
) {
308 lua_pushboolean(L
,1);
315 WSLUA_METAMETHOD
FieldInfo__le(lua_State
* L
) {
316 /* Checks whether the end byte of lhs is before the end of rhs */
317 FieldInfo l
= checkFieldInfo(L
,1);
318 FieldInfo r
= checkFieldInfo(L
,2);
320 if (l
->ds_tvb
!= r
->ds_tvb
)
321 WSLUA_ERROR(FieldInfo__le
,"Data source must be the same for both fields");
323 if (r
->start
+ r
->length
<= l
->start
+ r
->length
) {
324 lua_pushboolean(L
,1);
331 WSLUA_METAMETHOD
FieldInfo__lt(lua_State
* L
) {
332 /* Checks whether the end byte of rhs is before the beginning of rhs */
333 FieldInfo l
= checkFieldInfo(L
,1);
334 FieldInfo r
= checkFieldInfo(L
,2);
336 if (l
->ds_tvb
!= r
->ds_tvb
)
337 WSLUA_ERROR(FieldInfo__lt
,"Data source must be the same for both fields");
339 if ( r
->start
+ r
->length
< l
->start
) {
340 lua_pushboolean(L
,1);
347 static int FieldInfo__gc(lua_State
* L _U_
) {
348 /* do NOT free FieldInfo */
352 static const luaL_Reg FieldInfo_meta
[] = {
353 {"__tostring", FieldInfo__tostring
},
354 {"__call", FieldInfo__call
},
355 {"__index", FieldInfo__index
},
356 {"__len", FieldInfo__len
},
357 {"__unm", FieldInfo__unm
},
358 {"__eq", FieldInfo__eq
},
359 {"__le", FieldInfo__le
},
360 {"__lt", FieldInfo__lt
},
364 int FieldInfo_register(lua_State
* L
) {
365 WSLUA_REGISTER_META(FieldInfo
);
370 WSLUA_FUNCTION
wslua_all_field_infos(lua_State
* L
) {
372 Obtain all fields from the current tree. Note this only gets whatever fields the underlying
373 dissectors have filled in for this packet at this time - there may be fields applicable to
374 the packet that simply aren't being filled in because at this time they're not needed for anything.
375 This function only gets what the C-side code has currently populated, not the full list.
381 if (! lua_tree
|| ! lua_tree
->tree
) {
382 WSLUA_ERROR(wslua_all_field_infos
,"Cannot be called outside a listener or dissector");
385 found
= proto_all_finfos(lua_tree
->tree
);
388 for (i
=0; i
<found
->len
; i
++) {
389 pushFieldInfo(L
,(FieldInfo
)g_ptr_array_index(found
,i
));
393 g_ptr_array_free(found
,TRUE
);
399 WSLUA_CLASS_DEFINE(Field
,NOP
,NOP
);
401 A Field extractor to to obtain field values.
404 static GPtrArray
* wanted_fields
= NULL
;
405 static dfilter_t
* wslua_dfilter
= NULL
;
407 /* We use a fake dfilter for Lua field extractors, so that
408 * epan_dissect_run() will populate the fields. This won't happen
409 * if the passed-in edt->tree is NULL, which it will be if the
410 * proto_tree isn't created by epan_dissect_init(). But that's by
411 * design - if shark doesn't pass in a proto_tree, it's probably for
412 * a good reason and we shouldn't override that. (right?)
414 void wslua_prime_dfilter(epan_dissect_t
*edt
) {
415 if (wslua_dfilter
&& edt
&& edt
->tree
) {
416 dfilter_prime_proto_tree(wslua_dfilter
, edt
->tree
);
421 * field extractor registartion is tricky, In order to allow
422 * the user to define them in the body of the script we will
423 * populate the Field value with a pointer of the abbrev of it
424 * to later replace it with the hfi.
426 * This will be added to the wanted_fields array that will
427 * exists only while they can be defined, and be cleared right
428 * after the fields are primed.
431 void lua_prime_all_fields(proto_tree
* tree _U_
) {
432 GString
* fake_tap_filter
= g_string_new("frame");
434 static gboolean fake_tap
= FALSE
;
436 for(i
=0; i
< wanted_fields
->len
; i
++) {
437 Field f
= (Field
)g_ptr_array_index(wanted_fields
,i
);
438 gchar
* name
= *((gchar
**)f
);
440 *f
= proto_registrar_get_byname(name
);
443 report_failure("Could not find field `%s'",name
);
451 g_string_append_printf(fake_tap_filter
," || %s",(*f
)->abbrev
);
455 g_ptr_array_free(wanted_fields
,TRUE
);
456 wanted_fields
= NULL
;
459 /* a boring tap :-) */
460 GString
* error
= register_tap_listener("frame",
462 fake_tap_filter
->str
,
463 0, /* XXX - do we need the protocol tree or columns? */
467 report_failure("while registering lua_fake_tap:\n%s",error
->str
);
468 g_string_free(error
,TRUE
);
470 else if (!dfilter_compile(fake_tap_filter
->str
, &wslua_dfilter
)) {
471 report_failure("while compiling dfilter for wslua: '%s'", fake_tap_filter
->str
);
477 WSLUA_CONSTRUCTOR
Field_new(lua_State
*L
) {
479 Create a Field extractor
481 #define WSLUA_ARG_Field_new_FIELDNAME 1 /* The filter name of the field (e.g. ip.addr) */
482 const gchar
* name
= luaL_checkstring(L
,WSLUA_ARG_Field_new_FIELDNAME
);
487 if (!proto_registrar_get_byname(name
) && !wslua_is_field_available(L
, name
))
488 WSLUA_ARG_ERROR(Field_new
,FIELDNAME
,"a field with this name must exist");
491 WSLUA_ERROR(Field_new
,"A Field extractor must be defined before Taps or Dissectors get called");
493 f
= (Field
)g_malloc(sizeof(void*));
494 *f
= (header_field_info
*)g_strdup(name
); /* cheating */
496 g_ptr_array_add(wanted_fields
,f
);
499 WSLUA_RETURN(1); /* The field extractor */
502 WSLUA_METAMETHOD
Field__call (lua_State
* L
) {
503 /* Obtain all values (see FieldInfo) for this field. */
504 Field f
= checkField(L
,1);
505 header_field_info
* in
= *f
;
509 luaL_error(L
,"invalid field");
514 WSLUA_ERROR(Field__call
,"Fields cannot be used outside dissectors or taps");
518 GPtrArray
* found
= proto_get_finfo_ptr_array(lua_tree
->tree
, in
->id
);
521 for (i
=0; i
<found
->len
; i
++) {
522 pushFieldInfo(L
,(FieldInfo
)g_ptr_array_index(found
,i
));
526 in
= (in
->same_name_prev_id
!= -1) ? proto_registrar_get_nth(in
->same_name_prev_id
) : NULL
;
529 WSLUA_RETURN(items_found
); /* All the values of this field */
532 WSLUA_METAMETHOD
Field__tostring(lua_State
* L
) {
533 /* Obtain a string with the field name */
534 Field f
= checkField(L
,1);
537 luaL_error(L
,"invalid Field");
542 lua_pushstring(L
,*((gchar
**)f
));
544 lua_pushstring(L
,(*f
)->abbrev
);
550 static int Field__gc(lua_State
* L _U_
) {
551 /* do NOT free Field */
555 static const luaL_Reg Field_methods
[] = {
560 static const luaL_Reg Field_meta
[] = {
561 {"__tostring", Field__tostring
},
562 {"__call", Field__call
},
566 int Field_register(lua_State
* L
) {
568 wanted_fields
= g_ptr_array_new();
570 WSLUA_REGISTER_CLASS(Field
);
576 * Editor modelines - http://www.wireshark.org/tools/modelines.html
581 * indent-tabs-mode: nil
584 * vi: set shiftwidth=4 tabstop=8 expandtab:
585 * :indentSize=4:tabSize=8:noTabs=true: