regen pidl all: rm epan/dissectors/pidl/*-stamp; pushd epan/dissectors/pidl/ && make...
[wireshark-sm.git] / epan / wslua / wslua_field.c
blob6560feaceb6d60258e4df25751ab05e40e40acba
1 /*
2 * wslua_field.c
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 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include "config.h"
17 #include <epan/dfilter/dfilter.h>
18 #include <epan/ftypes/ftypes.h>
20 /* WSLUA_MODULE Field Obtaining Dissection Data */
22 #include "wslua.h"
24 /* any call to checkFieldInfo() will now error on null or expired, so no need to check again */
25 WSLUA_CLASS_DEFINE(FieldInfo,FAIL_ON_NULL_OR_EXPIRED("FieldInfo"));
27 An extracted Field from dissected packet data. A `FieldInfo` object can only be used within
28 the callback functions of dissectors, post-dissectors, heuristic-dissectors, and taps.
30 A `FieldInfo` can be called on either existing Wireshark fields by using either `Field.new()`
31 or `Field()` before-hand, or it can be called on new fields created by Lua from a `ProtoField`.
34 static GPtrArray* outstanding_FieldInfo;
36 FieldInfo* push_FieldInfo(lua_State* L, field_info* f) {
37 FieldInfo fi = (FieldInfo) g_malloc(sizeof(struct _wslua_field_info));
38 fi->ws_fi = f;
39 fi->expired = false;
40 g_ptr_array_add(outstanding_FieldInfo,fi);
41 return pushFieldInfo(L,fi);
44 CLEAR_OUTSTANDING(FieldInfo,expired,true)
46 /* WSLUA_ATTRIBUTE FieldInfo_len RO The length of this field. */
47 WSLUA_METAMETHOD FieldInfo__len(lua_State* L) {
49 Obtain the Length of the field
51 FieldInfo fi = checkFieldInfo(L,1);
53 lua_pushinteger(L,fi->ws_fi->length);
54 return 1;
57 /* WSLUA_ATTRIBUTE FieldInfo_offset RO The offset of this field. */
58 WSLUA_METAMETHOD FieldInfo__unm(lua_State* L) {
60 Obtain the Offset of the field
62 FieldInfo fi = checkFieldInfo(L,1);
64 lua_pushinteger(L,fi->ws_fi->start);
65 return 1;
68 /* WSLUA_ATTRIBUTE FieldInfo_value RO The value of this field. */
69 WSLUA_METAMETHOD FieldInfo__call(lua_State* L) {
71 Obtain the Value of the field.
73 Previous to 1.11.4, this function retrieved the value for most field types,
74 but for `ftypes.UINT_BYTES` it retrieved the `ByteArray` of the field's entire `TvbRange`.
75 In other words, it returned a `ByteArray` that included the leading length byte(s),
76 instead of just the *value* bytes. That was a bug, and has been changed in 1.11.4.
77 Furthermore, it retrieved an `ftypes.GUID` as a `ByteArray`, which is also incorrect.
79 If you wish to still get a `ByteArray` of the `TvbRange`, use `fieldinfo.range`
80 to get the `TvbRange`, and then use `tvbrange:bytes()` to convert it to a `ByteArray`.
82 FieldInfo fi = checkFieldInfo(L,1);
84 switch(fi->ws_fi->hfinfo->type) {
85 case FT_BOOLEAN:
86 lua_pushboolean(L,(int)fvalue_get_uinteger64(fi->ws_fi->value));
87 return 1;
88 case FT_CHAR:
89 case FT_UINT8:
90 case FT_UINT16:
91 case FT_UINT24:
92 case FT_UINT32:
93 case FT_FRAMENUM:
94 lua_pushinteger(L,(lua_Integer)(fvalue_get_uinteger(fi->ws_fi->value)));
95 return 1;
96 case FT_INT8:
97 case FT_INT16:
98 case FT_INT24:
99 case FT_INT32:
100 lua_pushinteger(L,(lua_Integer)(fvalue_get_sinteger(fi->ws_fi->value)));
101 return 1;
102 case FT_FLOAT:
103 case FT_DOUBLE:
104 lua_pushnumber(L,(lua_Number)(fvalue_get_floating(fi->ws_fi->value)));
105 return 1;
106 case FT_INT64: {
107 pushInt64(L,(Int64)(fvalue_get_sinteger64(fi->ws_fi->value)));
108 return 1;
110 case FT_UINT64: {
111 pushUInt64(L,fvalue_get_uinteger64(fi->ws_fi->value));
112 return 1;
114 case FT_ETHER: {
115 Address eth = (Address)g_malloc(sizeof(address));
116 alloc_address_tvb(NULL,eth,AT_ETHER,fi->ws_fi->length,fi->ws_fi->ds_tvb,fi->ws_fi->start);
117 pushAddress(L,eth);
118 return 1;
120 case FT_IPv4:{
121 Address ipv4 = (Address)g_malloc(sizeof(address));
122 alloc_address_tvb(NULL,ipv4,AT_IPv4,fi->ws_fi->length,fi->ws_fi->ds_tvb,fi->ws_fi->start);
123 pushAddress(L,ipv4);
124 return 1;
126 case FT_IPv6: {
127 Address ipv6 = (Address)g_malloc(sizeof(address));
128 alloc_address_tvb(NULL,ipv6,AT_IPv6,fi->ws_fi->length,fi->ws_fi->ds_tvb,fi->ws_fi->start);
129 pushAddress(L,ipv6);
130 return 1;
132 case FT_FCWWN: {
133 Address fcwwn = (Address)g_malloc(sizeof(address));
134 alloc_address_tvb(NULL,fcwwn,AT_FCWWN,fi->ws_fi->length,fi->ws_fi->ds_tvb,fi->ws_fi->start);
135 pushAddress(L,fcwwn);
136 return 1;
138 case FT_IPXNET:{
139 Address ipx = (Address)g_malloc(sizeof(address));
140 alloc_address_tvb(NULL,ipx,AT_IPX,fi->ws_fi->length,fi->ws_fi->ds_tvb,fi->ws_fi->start);
141 pushAddress(L,ipx);
142 return 1;
144 case FT_ABSOLUTE_TIME:
145 case FT_RELATIVE_TIME: {
146 NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t));
147 *nstime = *fvalue_get_time(fi->ws_fi->value);
148 pushNSTime(L,nstime);
149 return 1;
151 case FT_STRING:
152 case FT_STRINGZ:
153 case FT_STRINGZPAD: {
154 char* repr = fvalue_to_string_repr(NULL, fi->ws_fi->value, FTREPR_DISPLAY, BASE_NONE);
155 if (repr)
157 lua_pushstring(L, repr);
158 wmem_free(NULL, repr);
160 else
162 luaL_error(L,"field cannot be represented as string because it may contain invalid characters");
164 return 1;
166 case FT_NONE:
167 if (fi->ws_fi->length > 0 && fi->ws_fi->rep) {
168 /* it has a length, but calling fvalue_get() on an FT_NONE asserts,
169 so get the label instead (it's a FT_NONE, so a label is what it basically is) */
170 lua_pushstring(L, fi->ws_fi->rep->representation);
171 return 1;
173 return 0;
174 case FT_BYTES:
175 case FT_UINT_BYTES:
176 case FT_REL_OID:
177 case FT_SYSTEM_ID:
178 case FT_OID:
180 ByteArray ba = g_byte_array_new();
181 g_byte_array_append(ba, fvalue_get_bytes_data(fi->ws_fi->value),
182 (unsigned)fvalue_length2(fi->ws_fi->value));
183 pushByteArray(L,ba);
184 return 1;
186 case FT_PROTOCOL:
188 ByteArray ba = g_byte_array_new();
189 tvbuff_t* tvb = fvalue_get_protocol(fi->ws_fi->value);
190 uint8_t* raw;
191 if (tvb != NULL) {
192 raw = (uint8_t *)tvb_memdup(NULL, tvb, 0, tvb_captured_length(tvb));
193 g_byte_array_append(ba, raw, tvb_captured_length(tvb));
194 wmem_free(NULL, raw);
197 pushByteArray(L,ba);
198 return 1;
201 case FT_GUID:
202 default:
203 luaL_error(L,"FT_ not yet supported");
204 return 1;
208 /* WSLUA_ATTRIBUTE FieldInfo_label RO The string representing this field. */
209 WSLUA_METAMETHOD FieldInfo__tostring(lua_State* L) {
210 /* The string representation of the field. */
211 FieldInfo fi = checkFieldInfo(L,1);
213 char* repr = NULL;
215 if (fi->ws_fi->hfinfo->type == FT_PROTOCOL) {
216 repr = fvalue_to_string_repr(NULL, fi->ws_fi->value,FTREPR_DFILTER,BASE_NONE);
218 else {
219 repr = fvalue_to_string_repr(NULL, fi->ws_fi->value,FTREPR_DISPLAY,fi->ws_fi->hfinfo->display);
222 if (repr) {
223 lua_pushstring(L,repr);
224 /* fvalue_to_string_repr() wmem_alloc's the string's buffer */
225 wmem_free(NULL, repr);
227 else {
228 lua_pushstring(L,"(unknown)");
231 return 1;
234 /* WSLUA_ATTRIBUTE FieldInfo_display RO The string display of this field as seen in GUI. */
235 static int FieldInfo_get_display(lua_State* L) {
236 /* The display string of this field as seen in GUI. */
237 FieldInfo fi = checkFieldInfo(L,1);
238 char label_str[ITEM_LABEL_LENGTH+1];
239 char *label_ptr;
240 char *value_ptr;
242 if (!fi->ws_fi->rep) {
243 label_ptr = label_str;
244 proto_item_fill_label(fi->ws_fi, label_str, NULL);
245 } else
246 label_ptr = fi->ws_fi->rep->representation;
248 if (!label_ptr) return 0;
250 value_ptr = strstr(label_ptr, ": ");
251 if (!value_ptr) {
252 /* just use whatever's there */
253 lua_pushstring(L, label_ptr);
254 } else {
255 value_ptr += 2; /* get past the ': ' */
256 lua_pushstring(L, value_ptr);
259 return 1;
262 /* WSLUA_ATTRIBUTE FieldInfo_type RO The internal field type, a number which
263 matches one of the `ftype` values.
265 static int FieldInfo_get_type(lua_State* L) {
266 FieldInfo fi = checkFieldInfo(L,1);
268 if (fi->ws_fi->hfinfo) {
269 lua_pushinteger(L, fi->ws_fi->hfinfo->type);
271 else {
272 lua_pushnil(L);
275 return 1;
278 /* WSLUA_ATTRIBUTE FieldInfo_source RO The source `Tvb` object the `FieldInfo` is derived
279 from, or nil if there is none.
281 static int FieldInfo_get_source(lua_State* L) {
282 FieldInfo fi = checkFieldInfo(L,1);
284 if (fi->ws_fi->ds_tvb) {
285 push_Tvb(L, fi->ws_fi->ds_tvb);
287 else {
288 lua_pushnil(L);
291 return 1;
294 /* WSLUA_ATTRIBUTE FieldInfo_range RO The `TvbRange` covering the bytes of this field in a Tvb or nil if there is none. */
295 static int FieldInfo_get_range(lua_State* L) {
296 FieldInfo fi = checkFieldInfo(L,1);
298 if (!fi->ws_fi->ds_tvb) {
299 lua_pushnil(L);
300 return 1;
303 if (push_TvbRange (L, fi->ws_fi->ds_tvb, fi->ws_fi->start, fi->ws_fi->length)) {
304 return 1;
307 return 0;
310 /* WSLUA_ATTRIBUTE FieldInfo_generated RO Whether this field was marked as generated (boolean). */
311 static int FieldInfo_get_generated(lua_State* L) {
312 /* Whether this field was marked as generated. */
313 FieldInfo fi = checkFieldInfo(L,1);
315 lua_pushboolean(L,FI_GET_FLAG(fi->ws_fi, FI_GENERATED));
316 return 1;
319 /* WSLUA_ATTRIBUTE FieldInfo_hidden RO Whether this field was marked as hidden (boolean). */
320 static int FieldInfo_get_hidden(lua_State* L) {
321 FieldInfo fi = checkFieldInfo(L,1);
323 lua_pushboolean(L,FI_GET_FLAG(fi->ws_fi, FI_HIDDEN));
324 return 1;
327 /* WSLUA_ATTRIBUTE FieldInfo_is_url RO Whether this field was marked as being a URL (boolean). */
328 static int FieldInfo_get_is_url(lua_State* L) {
329 FieldInfo fi = checkFieldInfo(L,1);
331 lua_pushboolean(L,FI_GET_FLAG(fi->ws_fi, FI_URL));
332 return 1;
335 /* WSLUA_ATTRIBUTE FieldInfo_little_endian RO Whether this field is little-endian encoded (boolean). */
336 static int FieldInfo_get_little_endian(lua_State* L) {
337 FieldInfo fi = checkFieldInfo(L,1);
339 lua_pushboolean(L,FI_GET_FLAG(fi->ws_fi, FI_LITTLE_ENDIAN));
340 return 1;
343 /* WSLUA_ATTRIBUTE FieldInfo_big_endian RO Whether this field is big-endian encoded (boolean). */
344 static int FieldInfo_get_big_endian(lua_State* L) {
345 FieldInfo fi = checkFieldInfo(L,1);
347 lua_pushboolean(L,FI_GET_FLAG(fi->ws_fi, FI_BIG_ENDIAN));
348 return 1;
351 /* WSLUA_ATTRIBUTE FieldInfo_name RO The filter name of this field. */
352 static int FieldInfo_get_name(lua_State* L) {
353 /* The filter name of this field. */
354 FieldInfo fi = checkFieldInfo(L,1);
356 lua_pushstring(L,fi->ws_fi->hfinfo->abbrev);
357 return 1;
360 WSLUA_METAMETHOD FieldInfo__eq(lua_State* L) {
361 /* Checks whether lhs is within rhs. */
362 FieldInfo l = checkFieldInfo(L,1);
363 FieldInfo r = checkFieldInfo(L,2);
365 /* it is not an error if their ds_tvb are different... they're just not equal */
366 if (l->ws_fi->ds_tvb == r->ws_fi->ds_tvb &&
367 l->ws_fi->start == r->ws_fi->start &&
368 r->ws_fi->length == l->ws_fi->length) {
369 lua_pushboolean(L,1);
370 } else {
371 lua_pushboolean(L,0);
373 return 1;
376 WSLUA_METAMETHOD FieldInfo__le(lua_State* L) {
377 /* Checks whether the end byte of lhs is before the end of rhs. */
378 FieldInfo l = checkFieldInfo(L,1);
379 FieldInfo r = checkFieldInfo(L,2);
381 if (l->ws_fi->ds_tvb != r->ws_fi->ds_tvb)
382 WSLUA_ERROR(FieldInfo__le,"Data source must be the same for both fields");
384 if (l->ws_fi->start + l->ws_fi->length <= r->ws_fi->start + r->ws_fi->length) {
385 lua_pushboolean(L,1);
386 } else {
387 lua_pushboolean(L,0);
389 return 1;
392 WSLUA_METAMETHOD FieldInfo__lt(lua_State* L) {
393 /* Checks whether the end byte of lhs is before the beginning of rhs. */
394 FieldInfo l = checkFieldInfo(L,1);
395 FieldInfo r = checkFieldInfo(L,2);
397 if (l->ws_fi->ds_tvb != r->ws_fi->ds_tvb) {
398 WSLUA_ERROR(FieldInfo__lt,"Data source must be the same for both fields");
399 return 0;
402 if (l->ws_fi->start + l->ws_fi->length <= r->ws_fi->start) {
403 lua_pushboolean(L,1);
404 } else {
405 lua_pushboolean(L,0);
407 return 1;
410 /* Gets registered as metamethod automatically by WSLUA_REGISTER_META */
411 static int FieldInfo__gc(lua_State* L) {
412 FieldInfo fi = toFieldInfo(L,1);
414 if (!fi) return 0;
416 if (!fi->expired)
417 fi->expired = true;
418 else
419 /* do NOT free fi->ws_fi */
420 g_free(fi);
422 return 0;
425 /* This table is ultimately registered as a sub-table of the class' metatable,
426 * and if __index/__newindex is invoked then it calls the appropriate function
427 * from this table for getting/setting the members.
429 WSLUA_ATTRIBUTES FieldInfo_attributes[] = {
430 WSLUA_ATTRIBUTE_ROREG(FieldInfo,range),
431 WSLUA_ATTRIBUTE_ROREG(FieldInfo,generated),
432 WSLUA_ATTRIBUTE_ROREG(FieldInfo,hidden),
433 WSLUA_ATTRIBUTE_ROREG(FieldInfo,is_url),
434 WSLUA_ATTRIBUTE_ROREG(FieldInfo,little_endian),
435 WSLUA_ATTRIBUTE_ROREG(FieldInfo,big_endian),
436 WSLUA_ATTRIBUTE_ROREG(FieldInfo,name),
437 WSLUA_ATTRIBUTE_ROREG(FieldInfo,display),
438 WSLUA_ATTRIBUTE_ROREG(FieldInfo,type),
439 WSLUA_ATTRIBUTE_ROREG(FieldInfo,source),
440 { "label", FieldInfo__tostring, NULL },
441 { "value", FieldInfo__call, NULL },
442 { "tvb", FieldInfo_get_range, NULL },
443 { "len", FieldInfo__len, NULL },
444 { "offset", FieldInfo__unm, NULL },
445 { NULL, NULL, NULL }
448 WSLUA_META FieldInfo_meta[] = {
449 WSLUA_CLASS_MTREG(FieldInfo,tostring),
450 WSLUA_CLASS_MTREG(FieldInfo,call),
451 WSLUA_CLASS_MTREG(FieldInfo,len),
452 WSLUA_CLASS_MTREG(FieldInfo,unm),
453 WSLUA_CLASS_MTREG(FieldInfo,eq),
454 WSLUA_CLASS_MTREG(FieldInfo,le),
455 WSLUA_CLASS_MTREG(FieldInfo,lt),
456 { NULL, NULL }
459 int FieldInfo_register(lua_State* L) {
460 WSLUA_REGISTER_META_WITH_ATTRS(FieldInfo);
461 return 0;
465 WSLUA_FUNCTION wslua_all_field_infos(lua_State* L) {
467 Obtain all fields from the current tree. Note this only gets whatever fields the underlying
468 dissectors have filled in for this packet at this time - there may be fields applicable to
469 the packet that simply aren't being filled in because at this time they're not needed for anything.
470 This function only gets what the C-side code has currently populated, not the full list.
472 GPtrArray* found;
473 int items_found = 0;
474 unsigned i;
476 if (! lua_tree || ! lua_tree->tree ) {
477 WSLUA_ERROR(wslua_all_field_infos,"Cannot be called outside a listener or dissector");
478 return 0;
481 found = proto_all_finfos(lua_tree->tree);
483 if (found) {
484 for (i=0; i<found->len; i++) {
485 push_FieldInfo(L, (field_info *)g_ptr_array_index(found,i));
486 items_found++;
489 g_ptr_array_free(found,true);
492 return items_found;
495 WSLUA_CLASS_DEFINE(Field,FAIL_ON_NULL("Field"));
497 A Field extractor to obtain field values. A `Field` object can only be created *outside* of
498 the callback functions of dissectors, post-dissectors, heuristic-dissectors, and taps.
500 Once created, it is used *inside* the callback functions, to generate a `FieldInfo` object.
503 /* Array of Field (struct _wslua_header_field_info*) pointers.*/
504 static GPtrArray* wanted_fields;
505 static dfilter_t* wslua_dfilter;
507 /* We use a fake dfilter for Lua field extractors, so that
508 * epan_dissect_run() will populate the fields. This won't happen
509 * if the passed-in edt->tree is NULL, which it will be if the
510 * proto_tree isn't created by epan_dissect_init(). But that's by
511 * design - if shark doesn't pass in a proto_tree, it's probably for
512 * a good reason and we shouldn't override that. (right?)
514 void wslua_prime_dfilter(epan_dissect_t *edt) {
515 if (wslua_dfilter && edt && edt->tree) {
516 dfilter_prime_proto_tree(wslua_dfilter, edt->tree);
520 /* Check if we have any registered field extractors. */
521 bool wslua_has_field_extractors(void) {
522 return (wslua_dfilter && dfilter_has_interesting_fields(wslua_dfilter));
526 * field extractor registration is tricky, In order to allow
527 * the user to define them in the body of the script we will
528 * populate the Field value with a pointer of the abbrev of it
529 * to later replace it with the hfi.
531 * This will be added to the wanted_fields array that will
532 * exists only while they can be defined, and be cleared right
533 * after the fields are primed.
536 static bool fake_tap;
537 void lua_prime_all_fields(proto_tree* tree _U_) {
538 GString* fake_tap_filter = g_string_new("frame");
539 unsigned i;
540 df_error_t *df_err;
542 for(i=0; i < wanted_fields->len; i++) {
543 Field f = (Field)g_ptr_array_index(wanted_fields,i);
545 f->hfi = proto_registrar_get_byname(f->name);
546 if (!f->hfi) {
547 report_failure("Could not find field `%s'", f->name);
548 continue;
551 g_string_append_printf(fake_tap_filter, " || %s", f->hfi->abbrev);
552 fake_tap = true;
555 g_ptr_array_free(wanted_fields,true);
556 wanted_fields = NULL;
558 if (fake_tap && fake_tap_filter->len > strlen("frame")) {
559 /* a boring tap :-) */
560 GString* error = register_tap_listener("frame",
561 &fake_tap,
562 fake_tap_filter->str,
563 0, /* XXX - do we need the protocol tree or columns? */
564 NULL, NULL, NULL, NULL);
566 if (error) {
567 report_failure("while registering lua_fake_tap:\n%s",error->str);
568 g_string_free(error,TRUE);
569 } else if (!dfilter_compile(fake_tap_filter->str, &wslua_dfilter, &df_err)) {
570 report_failure("while compiling dfilter \"%s\" for wslua: %s", fake_tap_filter->str, df_err->msg);
571 df_error_free(&df_err);
574 g_string_free(fake_tap_filter, TRUE);
577 WSLUA_CONSTRUCTOR Field_new(lua_State *L) {
579 Create a Field extractor.
581 #define WSLUA_ARG_Field_new_FIELDNAME 1 /* The filter name of the field (e.g. ip.addr) */
582 const char* name = luaL_checkstring(L,WSLUA_ARG_Field_new_FIELDNAME);
583 Field f;
585 if (!proto_registrar_get_byname(name) && !wslua_is_field_available(L, name)) {
586 WSLUA_ARG_ERROR(Field_new,FIELDNAME,"a field with this name must exist");
587 return 0;
590 if (!wanted_fields) {
591 WSLUA_ERROR(Field_new,"A Field extractor must be defined before Taps or Dissectors get called");
592 return 0;
595 f = (Field)g_new0(struct _wslua_header_field_info, 1);
596 f->name = g_strdup(name);
598 g_ptr_array_add(wanted_fields, f);
600 pushField(L,f);
601 WSLUA_RETURN(1); /* The field extractor */
604 WSLUA_CONSTRUCTOR Field_list(lua_State *L) {
605 /* Gets a Lua array table of all registered field filter names.
607 NOTE: This is an expensive operation, and should only be used for troubleshooting.
609 void *cookie, *cookie2;
610 int i = -1;
611 int count = 0;
612 header_field_info *hfinfo = NULL;
614 lua_newtable(L);
616 for (i = proto_get_first_protocol(&cookie); i != -1;
617 i = proto_get_next_protocol(&cookie)) {
619 for (hfinfo = proto_get_first_protocol_field(i, &cookie2); hfinfo != NULL;
620 hfinfo = proto_get_next_protocol_field(i, &cookie2)) {
622 if (hfinfo->same_name_prev_id != -1) /* ignore duplicate names */
623 continue;
625 count++;
626 lua_pushstring(L,hfinfo->abbrev);
627 lua_rawseti(L,-2,count);
631 WSLUA_RETURN(1); /* The array table of field filter names */
634 /* the following is used in Field_get_xxx functions later. If called early
635 * (wanted_fields is not NULL), it will try to retrieve information directly.
636 * Otherwise it uses a cached field that was loaded in lua_prime_all_fields. */
637 #define GET_HFINFO_MEMBER(luafunc, member) \
638 if (wanted_fields) { \
639 hfinfo = proto_registrar_get_byname(f->name); \
640 if (!hfinfo) { \
641 /* could be a Lua-created field */ \
642 ProtoField pf = wslua_is_field_available(L, f->name); \
643 if (pf) { \
644 luafunc(L, pf->member); \
645 return 1; \
648 } else { \
649 hfinfo = f->hfi; \
652 if (hfinfo) { \
653 luafunc(L,hfinfo->member); \
654 } else \
655 lua_pushnil(L)
658 /* WSLUA_ATTRIBUTE Field_name RO The filter name of this field, or nil. */
659 static int Field_get_name(lua_State* L) {
660 Field f = checkField(L,1);
661 header_field_info* hfinfo = NULL;
663 GET_HFINFO_MEMBER(lua_pushstring, abbrev);
665 return 1;
668 /* WSLUA_ATTRIBUTE Field_display RO The full display name of this field, or nil. */
669 static int Field_get_display(lua_State* L) {
670 Field f = checkField(L,1);
671 header_field_info* hfinfo = NULL;
673 GET_HFINFO_MEMBER(lua_pushstring, name);
675 return 1;
678 /* WSLUA_ATTRIBUTE Field_type RO The `ftype` of this field, or nil. */
679 static int Field_get_type(lua_State* L) {
680 Field f = checkField(L,1);
681 header_field_info* hfinfo = NULL;
683 GET_HFINFO_MEMBER(lua_pushinteger, type);
685 return 1;
688 WSLUA_METAMETHOD Field__call (lua_State* L) {
689 /* Obtain all values (see `FieldInfo`) for this field. */
690 Field f = checkField(L,1);
691 header_field_info* in = f->hfi;
692 int items_found = 0;
694 if (! in) {
695 luaL_error(L,"invalid field");
696 return 0;
699 if (! lua_pinfo ) {
700 WSLUA_ERROR(Field__call,"Fields cannot be used outside dissectors or taps");
701 return 0;
704 while (in) {
705 GPtrArray* found = proto_get_finfo_ptr_array(lua_tree->tree, in->id);
706 unsigned i;
707 if (found) {
708 for (i=0; i<found->len; i++) {
709 push_FieldInfo(L, (field_info *) g_ptr_array_index(found,i));
710 items_found++;
713 in = (in->same_name_prev_id != -1) ? proto_registrar_get_nth(in->same_name_prev_id) : NULL;
716 WSLUA_RETURN(items_found); /* All the values of this field */
719 WSLUA_METAMETHOD Field__tostring(lua_State* L) {
720 /* Obtain a string with the field filter name. */
721 Field f = checkField(L,1);
723 if (f->hfi) {
724 /* If a field was found, return the actual field info. */
725 lua_pushstring(L, f->hfi->abbrev);
726 } else {
727 lua_pushstring(L, f->name);
730 return 1;
733 static int Field__gc(lua_State* L) {
734 Field f = toField(L,1);
735 if (!f) return 0;
737 // If out of scope before lua_prime_all_fields is even called, be sure to
738 // remove the pointer to avoid a use-after-free.
739 if (wanted_fields) {
740 g_ptr_array_remove_fast(wanted_fields, f);
743 g_free(f->name);
744 g_free(f);
745 return 0;
748 WSLUA_ATTRIBUTES Field_attributes[] = {
749 WSLUA_ATTRIBUTE_ROREG(Field,name),
750 WSLUA_ATTRIBUTE_ROREG(Field,display),
751 WSLUA_ATTRIBUTE_ROREG(Field,type),
752 { NULL, NULL, NULL }
755 WSLUA_METHODS Field_methods[] = {
756 WSLUA_CLASS_FNREG(Field,new),
757 WSLUA_CLASS_FNREG(Field,list),
758 { NULL, NULL }
761 WSLUA_META Field_meta[] = {
762 WSLUA_CLASS_MTREG(Field,tostring),
763 WSLUA_CLASS_MTREG(Field,call),
764 { NULL, NULL }
767 int Field_register(lua_State* L) {
769 if (wanted_fields != NULL) {
770 g_ptr_array_unref(wanted_fields);
772 wanted_fields = g_ptr_array_new();
774 WSLUA_REGISTER_CLASS_WITH_ATTRS(Field);
775 if (outstanding_FieldInfo != NULL) {
776 g_ptr_array_unref(outstanding_FieldInfo);
778 outstanding_FieldInfo = g_ptr_array_new();
780 return 0;
783 int wslua_deregister_fields(lua_State* L _U_) {
784 if (wslua_dfilter) {
785 dfilter_free(wslua_dfilter);
786 wslua_dfilter = NULL;
789 if (fake_tap) {
790 remove_tap_listener(&fake_tap);
791 fake_tap = false;
794 return 0;
798 * Editor modelines - https://www.wireshark.org/tools/modelines.html
800 * Local variables:
801 * c-basic-offset: 4
802 * tab-width: 8
803 * indent-tabs-mode: nil
804 * End:
806 * vi: set shiftwidth=4 tabstop=8 expandtab:
807 * :indentSize=4:tabSize=8:noTabs=true: