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) {
67 lua_pushboolean(L,(int)fvalue_get_uinteger(&(fi->value)));
74 lua_pushnumber(L,(lua_Number)fvalue_get_uinteger(&(fi->value)));
80 lua_pushnumber(L,(lua_Number)fvalue_get_sinteger(&(fi->value)));
84 lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value)));
87 Int64 num = g_malloc(sizeof(gint64));
88 *num = fvalue_get_integer64(&(fi->value));
93 UInt64 num = g_malloc(sizeof(guint64));
94 *num = fvalue_get_integer64(&(fi->value));
99 Address eth = g_malloc(sizeof(address));
100 eth->type = AT_ETHER;
101 eth->len = fi->length;
102 eth->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
107 Address ipv4 = g_malloc(sizeof(address));
108 ipv4->type = AT_IPv4;
109 ipv4->len = fi->length;
110 ipv4->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
115 Address ipv6 = g_malloc(sizeof(address));
116 ipv6->type = AT_IPv6;
117 ipv6->len = fi->length;
118 ipv6->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
123 Address ipx = g_malloc(sizeof(address));
125 ipx->len = fi->length;
126 ipx->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
132 gchar* repr = fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL);
134 lua_pushstring(L,repr);
136 luaL_error(L,"field cannot be represented as string because it may contain invalid characters");
145 ByteArray ba = g_byte_array_new();
146 g_byte_array_append(ba, ep_tvb_memdup(fi->ds_tvb,fi->start,fi->length),fi->length);
151 luaL_error(L,"FT_ not yet supported");
156 WSLUA_METAMETHOD FieldInfo__tostring(lua_State* L) {
157 /* The string representation of the field */
158 FieldInfo fi = checkFieldInfo(L,1);
160 if (fi->value.ftype->val_to_string_repr) {
161 gchar* repr = fvalue_to_string_repr(&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");
167 luaL_error(L,"field has no string representation");
172 static int FieldInfo_get_range(lua_State* L) {
173 /* The TvbRange covering this field */
174 FieldInfo fi = checkFieldInfo(L,1);
175 TvbRange r = ep_alloc(sizeof(struct _wslua_tvbrange));
176 r->tvb = ep_alloc(sizeof(struct _wslua_tvb));
178 r->tvb->ws_tvb = fi->ds_tvb;
179 r->offset = fi->start;
186 static int FieldInfo_get_generated(lua_State* L) {
187 /* Whether this field was marked as generated. */
188 FieldInfo fi = checkFieldInfo(L,1);
189 lua_pushboolean(L,FI_GET_FLAG(fi, FI_GENERATED));
193 static int FieldInfo_get_name(lua_State* L) {
194 /* The filter name of this field. */
195 FieldInfo fi = checkFieldInfo(L,1);
196 lua_pushstring(L,fi->hfinfo->abbrev);
200 static const luaL_reg FieldInfo_get[] = {
201 /* {"data_source", FieldInfo_get_data_source }, */
202 {"range", FieldInfo_get_range},
203 /* {"hidden", FieldInfo_get_hidden}, */
204 {"generated", FieldInfo_get_generated},
206 /* WSLUA_ATTRIBUTE FieldInfo_name RO The name of this field */
207 {"name", FieldInfo_get_name},
208 /* WSLUA_ATTRIBUTE FieldInfo_label RO The string representing this field */
209 {"label", FieldInfo__tostring},
210 /* WSLUA_ATTRIBUTE FieldInfo_value RO The value of this field */
211 {"value", FieldInfo__call},
212 /* WSLUA_ATTRIBUTE FieldInfo_len RO The length of this field */
213 {"len", FieldInfo__len},
214 /* WSLUA_ATTRIBUTE FieldInfo_offset RO The offset of this field */
215 {"offset", FieldInfo__unm},
219 static int FieldInfo__index(lua_State* L) {
223 const gchar* idx = luaL_checkstring(L,2);
228 for (r = FieldInfo_get; r->name; r++) {
229 if (g_str_equal(r->name, idx)) {
237 WSLUA_METAMETHOD FieldInfo__eq(lua_State* L) {
238 /* Checks whether lhs is within rhs */
239 FieldInfo l = checkFieldInfo(L,1);
240 FieldInfo r = checkFieldInfo(L,2);
242 if (l->ds_tvb != r->ds_tvb)
243 WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields");
245 if (l->start <= r->start && r->start + r->length <= l->start + r->length) {
246 lua_pushboolean(L,1);
253 WSLUA_METAMETHOD FieldInfo__le(lua_State* L) {
254 /* Checks whether the end byte of lhs is before the end of rhs */
255 FieldInfo l = checkFieldInfo(L,1);
256 FieldInfo r = checkFieldInfo(L,2);
258 if (l->ds_tvb != r->ds_tvb)
261 if (r->start + r->length <= l->start + r->length) {
262 lua_pushboolean(L,1);
269 WSLUA_METAMETHOD FieldInfo__lt(lua_State* L) {
270 /* Checks whether the end byte of rhs is before the beginning of rhs */
271 FieldInfo l = checkFieldInfo(L,1);
272 FieldInfo r = checkFieldInfo(L,2);
274 if (l->ds_tvb != r->ds_tvb)
275 WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields");
277 if ( r->start + r->length < l->start ) {
278 lua_pushboolean(L,1);
286 static const luaL_reg FieldInfo_meta[] = {
287 {"__tostring", FieldInfo__tostring},
288 {"__call", FieldInfo__call},
289 {"__index", FieldInfo__index},
290 {"__len", FieldInfo__len},
291 {"__unm", FieldInfo__unm},
292 {"__eq", FieldInfo__eq},
293 {"__le", FieldInfo__le},
294 {"__lt", FieldInfo__lt},
298 int FieldInfo_register(lua_State* L) {
299 WSLUA_REGISTER_META(FieldInfo);
304 WSLUA_FUNCTION wslua_all_field_infos(lua_State* L) {
305 /* Obtain all fields from the current tree */
310 if (! lua_tree || ! lua_tree->tree ) {
311 WSLUA_ERROR(wslua_all_field_infos,"Cannot be called outside a listener or dissector");
314 found = proto_all_finfos(lua_tree->tree);
317 for (i=0; i<found->len; i++) {
318 pushFieldInfo(L,g_ptr_array_index(found,i));
322 g_ptr_array_free(found,TRUE);
328 WSLUA_CLASS_DEFINE(Field,NOP,NOP);
330 A Field extractor to to obtain field values.
333 static GPtrArray* wanted_fields = NULL;
336 * field extractor registartion is tricky, In order to allow
337 * the user to define them in the body of the script we will
338 * populate the Field value with a pointer of the abbrev of it
339 * to later replace it with the hfi.
341 * This will be added to the wanted_fields array that will
342 * exists only while they can be defined, and be cleared right
343 * after the fields are primed.
346 void lua_prime_all_fields(proto_tree* tree _U_) {
347 GString* fake_tap_filter = g_string_new("frame");
349 static gboolean fake_tap = FALSE;
351 for(i=0; i < wanted_fields->len; i++) {
352 Field f = g_ptr_array_index(wanted_fields,i);
353 gchar* name = *((gchar**)f);
355 *f = proto_registrar_get_byname(name);
358 report_failure("Could not find field `%s'",name);
366 g_string_append_printf(fake_tap_filter," || %s",(*f)->abbrev);
370 g_ptr_array_free(wanted_fields,TRUE);
371 wanted_fields = NULL;
374 /* a boring tap :-) */
375 GString* error = register_tap_listener("frame",
377 fake_tap_filter->str,
378 0, /* XXX - do we need the protocol tree or columns? */
382 report_failure("while registering lua_fake_tap:\n%s",error->str);
383 g_string_free(error,TRUE);
389 WSLUA_CONSTRUCTOR Field_new(lua_State *L) {
391 Create a Field extractor
393 #define WSLUA_ARG_Field_new_FIELDNAME 1 /* The filter name of the field (e.g. ip.addr) */
394 const gchar* name = luaL_checkstring(L,WSLUA_ARG_Field_new_FIELDNAME);
399 if (!proto_registrar_get_byname(name))
400 WSLUA_ARG_ERROR(Field_new,FIELDNAME,"a field with this name must exist");
403 WSLUA_ERROR(Field_get,"A Field extractor must be defined before Taps or Dissectors get called");
405 f = g_malloc(sizeof(void*));
406 *f = (header_field_info*)g_strdup(name); /* cheating */
408 g_ptr_array_add(wanted_fields,f);
411 WSLUA_RETURN(1); /* The field extractor */
414 WSLUA_METAMETHOD Field__call (lua_State* L) {
415 /* Obtain all values (see FieldInfo) for this field. */
416 Field f = checkField(L,1);
417 header_field_info* in = *f;
421 luaL_error(L,"invalid field");
426 WSLUA_ERROR(Field__call,"Fields cannot be used outside dissectors or taps");
430 for (;in;in = in->same_name_next) {
431 GPtrArray* found = proto_get_finfo_ptr_array(lua_tree->tree, in->id);
434 for (i=0; i<found->len; i++) {
435 pushFieldInfo(L,g_ptr_array_index(found,i));
441 WSLUA_RETURN(items_found); /* All the values of this field */
444 WSLUA_METAMETHOD Field_tostring(lua_State* L) {
445 /* Obtain a srting with the field name */
446 Field f = checkField(L,1);
449 luaL_error(L,"invalid Field");
454 lua_pushstring(L,*((gchar**)f));
456 lua_pushstring(L,(*f)->abbrev);
462 static const luaL_reg Field_methods[] = {
467 static const luaL_reg Field_meta[] = {
468 {"__tostring", Field_tostring},
469 {"__call", Field__call},
473 int Field_register(lua_State* L) {
475 wanted_fields = g_ptr_array_new();
477 WSLUA_REGISTER_CLASS(Field);