regen pidl all: rm epan/dissectors/pidl/*-stamp; pushd epan/dissectors/pidl/ && make...
[wireshark-sm.git] / epan / wslua / wslua_tree.c
blob55b05dc0deccbf5ab202618e60e7b66af9e62b73
1 /*
2 * wslua_tree.c
4 * Wireshark's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
7 * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include "config.h"
18 /* WSLUA_MODULE Tree Adding Information To The Dissection Tree */
20 #include "wslua.h"
21 #include <epan/exceptions.h>
22 #include <epan/show_exception.h>
24 static int wslua_ett = -1;
26 static GPtrArray* outstanding_TreeItem;
29 /* pushing a TreeItem with a NULL item or subtree is completely valid for this function */
30 TreeItem push_TreeItem(lua_State *L, proto_tree *tree, proto_item *item) {
31 TreeItem ti = g_new(struct _wslua_treeitem, 1);
33 ti->tree = tree;
34 ti->item = item;
35 ti->expired = false;
37 g_ptr_array_add(outstanding_TreeItem, ti);
39 return *(pushTreeItem(L,ti));
42 /* creates the TreeItem but does NOT push it into Lua */
43 TreeItem create_TreeItem(proto_tree* tree, proto_item* item)
45 TreeItem tree_item = (TreeItem)g_malloc(sizeof(struct _wslua_treeitem));
46 tree_item->tree = tree;
47 tree_item->item = item;
48 tree_item->expired = false;
50 return tree_item;
53 CLEAR_OUTSTANDING(TreeItem, expired, true)
55 WSLUA_CLASS_DEFINE(TreeItem,FAIL_ON_NULL_OR_EXPIRED("TreeItem"));
56 /* <<lua_class_TreeItem,`TreeItem`>>s represent information in the https://www.wireshark.org/docs/wsug_html_chunked/ChUsePacketDetailsPaneSection.html[packet details] pane of Wireshark, and the packet details view of TShark.
57 A <<lua_class_TreeItem,`TreeItem`>> represents a node in the tree, which might also be a subtree and have a list of children.
58 The children of a subtree have zero or more siblings which are other children of the same <<lua_class_TreeItem,`TreeItem`>> subtree.
60 During dissection, heuristic-dissection, and post-dissection, a root <<lua_class_TreeItem,`TreeItem`>> is passed to dissectors as the third argument of the function
61 callback (e.g., `myproto.dissector(tvbuf,pktinfo,root)`).
63 In some cases the tree is not truly added to, in order to improve performance.
64 For example for packets not currently displayed/selected in Wireshark's visible
65 window pane, or if TShark isn't invoked with the `-V` switch. However the
66 "add" type <<lua_class_TreeItem,`TreeItem`>> functions can still be called, and still return <<lua_class_TreeItem,`TreeItem`>>
67 objects - but the info isn't really added to the tree. Therefore you do not
68 typically need to worry about whether there's a real tree or not. If, for some
69 reason, you need to know it, you can use the <<lua_class_attrib_treeitem_visible,`TreeItem.visible`>> attribute getter
70 to retrieve the state.
73 /* the following is used by TreeItem_add_packet_field() - this can THROW errors */
74 static proto_item *
75 try_add_packet_field(lua_State *L, TreeItem tree_item, TvbRange tvbr, const int hfid,
76 const ftenum_t type, const unsigned encoding, int *ret_err)
78 int err = 0;
79 proto_item *volatile item = NULL;
80 int endoff = 0;
82 switch(type) {
83 /* these all generate ByteArrays */
84 case FT_BYTES:
85 case FT_UINT_BYTES:
86 case FT_OID:
87 case FT_REL_OID:
88 case FT_SYSTEM_ID:
90 /* GByteArray and its data will be g_free'd by Lua */
91 GByteArray *gba = g_byte_array_new();
92 item = proto_tree_add_bytes_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
93 tvbr->offset, tvbr->len, encoding,
94 gba, &endoff, &err);
95 if (err == 0) {
96 pushByteArray(L, gba);
97 lua_pushinteger(L, endoff);
100 break;
102 case FT_ABSOLUTE_TIME:
103 case FT_RELATIVE_TIME:
105 /* nstime_t will be g_free'd by Lua */
106 nstime_t *nstime = g_new0(nstime_t, 1);
107 item = proto_tree_add_time_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
108 tvbr->offset, tvbr->len, encoding,
109 nstime, &endoff, &err);
110 if (err == 0) {
111 pushNSTime(L,nstime);
112 lua_pushinteger(L, endoff);
115 break;
117 case FT_INT8:
118 case FT_INT16:
119 case FT_INT24:
120 case FT_INT32:
122 int32_t ret;
123 item = proto_tree_add_item_ret_int(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
124 tvbr->offset, tvbr->len, encoding,
125 &ret);
126 lua_pushinteger(L, (lua_Integer)ret);
127 lua_pushinteger(L, tvbr->offset + tvbr->len);
129 break;
131 case FT_INT40:
132 case FT_INT48:
133 case FT_INT56:
134 case FT_INT64:
136 int64_t ret;
137 item = proto_tree_add_item_ret_int64(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
138 tvbr->offset, tvbr->len, encoding,
139 &ret);
140 pushInt64(L, ret);
141 lua_pushinteger(L, tvbr->offset + tvbr->len);
143 break;
145 case FT_CHAR:
146 case FT_UINT8:
147 case FT_UINT16:
148 case FT_UINT24:
149 case FT_UINT32:
151 uint32_t ret;
152 item = proto_tree_add_item_ret_uint(tree_item-> tree, hfid, tvbr->tvb->ws_tvb,
153 tvbr->offset, tvbr->len, encoding,
154 &ret);
155 lua_pushinteger(L, (lua_Integer)ret);
156 lua_pushinteger(L, tvbr->offset + tvbr->len);
158 break;
160 case FT_UINT40:
161 case FT_UINT48:
162 case FT_UINT56:
163 case FT_UINT64:
165 uint64_t ret;
166 item = proto_tree_add_item_ret_uint64(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
167 tvbr->offset, tvbr->len, encoding,
168 &ret);
169 pushUInt64(L, ret);
170 lua_pushinteger(L, tvbr->offset + tvbr->len);
172 break;
174 case FT_BOOLEAN:
176 bool ret;
177 item = proto_tree_add_item_ret_boolean(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
178 tvbr->offset, tvbr->len, encoding,
179 &ret);
180 lua_pushboolean(L, ret);
181 lua_pushinteger(L, tvbr->offset + tvbr->len);
183 break;
185 case FT_STRING:
187 const uint8_t *ret;
188 int len;
189 item = proto_tree_add_item_ret_string_and_length(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
190 tvbr->offset, tvbr->len, encoding,
191 NULL, &ret, &len);
192 lua_pushstring(L, ret);
193 lua_pushinteger(L, tvbr->offset + len);
194 wmem_free(NULL, (void*)ret);
196 break;
198 case FT_STRINGZ:
200 const uint8_t *ret;
201 int len;
202 item = proto_tree_add_item_ret_string_and_length(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
203 tvbr->offset, -1, encoding,
204 NULL, &ret, &len);
205 lua_pushstring(L, ret);
206 lua_pushinteger(L, tvbr->offset + len);
207 wmem_free(NULL, (void*)ret);
209 break;
211 case FT_FLOAT:
213 float ret;
214 item = proto_tree_add_item_ret_float(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
215 tvbr->offset, tvbr->len, encoding,
216 &ret);
217 lua_pushnumber(L, (lua_Number)ret);
218 lua_pushinteger(L, tvbr->offset + tvbr->len);
220 break;
222 case FT_DOUBLE:
224 double ret;
225 item = proto_tree_add_item_ret_double(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
226 tvbr->offset, tvbr->len, encoding,
227 &ret);
228 lua_pushnumber(L, (lua_Number)ret);
229 lua_pushinteger(L, tvbr->offset + tvbr->len);
231 break;
233 case FT_IPv4:
235 Address addr = g_new(address,1);
236 ws_in4_addr ret;
237 item = proto_tree_add_item_ret_ipv4(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
238 tvbr->offset, tvbr->len, encoding,
239 &ret);
240 alloc_address_wmem(NULL, addr, AT_IPv4, sizeof(ret), &ret);
241 pushAddress(L, addr);
242 lua_pushinteger(L, tvbr->offset + tvbr->len);
244 break;
246 case FT_IPv6:
248 Address addr = g_new(address, 1);
249 ws_in6_addr ret;
250 item = proto_tree_add_item_ret_ipv6(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
251 tvbr->offset, tvbr->len, encoding,
252 &ret);
253 alloc_address_wmem(NULL, addr, AT_IPv6, sizeof(ret), &ret);
254 pushAddress(L, addr);
255 lua_pushinteger(L, tvbr->offset + tvbr->len);
257 break;
259 case FT_ETHER:
261 Address addr = g_new(address, 1);
262 uint8_t bytes[FT_ETHER_LEN];
264 item = proto_tree_add_item_ret_ether(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
265 tvbr->offset, tvbr->len, encoding,
266 bytes);
267 alloc_address_wmem(NULL, addr, AT_ETHER, sizeof(bytes), bytes);
268 pushAddress(L, addr);
269 lua_pushinteger(L, tvbr->offset + tvbr->len);
271 break;
273 default:
274 item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, encoding);
275 lua_pushnil(L);
276 lua_pushnil(L);
277 break;
280 if (ret_err) *ret_err = err;
282 return item;
285 WSLUA_METHOD TreeItem_add_packet_field(lua_State *L) {
287 Adds a new child tree for the given <<lua_class_ProtoField,`ProtoField`>> object to this tree item,
288 returning the new child <<lua_class_TreeItem,`TreeItem`>>.
290 Unlike `TreeItem:add()` and `TreeItem:add_le()`, the <<lua_class_ProtoField,`ProtoField`>> argument
291 is not optional, and cannot be a `Proto` object. Instead, this function always
292 uses the <<lua_class_ProtoField,`ProtoField`>> to determine the type of field to extract from the
293 passed-in `TvbRange`, highlighting the relevant bytes in the Packet Bytes pane
294 of the GUI (if there is a GUI), etc. If no <<lua_class_TvbRange,`TvbRange`>>is given, no bytes are
295 highlighted and the field's value cannot be determined; the <<lua_class_ProtoField,`ProtoField`>> must
296 have been defined/created not to have a length in such a case, or an error will
297 occur. For backwards-compatibility reasons the `encoding` argument, however,
298 must still be given.
300 Unlike `TreeItem:add()` and `TreeItem:add_le()`, this function performs both
301 big-endian and little-endian decoding, by setting the `encoding` argument to
302 be `ENC_BIG_ENDIAN` or `ENC_LITTLE_ENDIAN`.
304 The signature of this function:
306 [source,lua]
307 ----
308 tree_item:add_packet_field(proto_field [,tvbrange], encoding, ...)
309 ----
311 This function returns more than just the new child <<lua_class_TreeItem,`TreeItem`>>.
312 The child is the first return value, so that function chaining will still work; but it
313 also returns more information. The second return is the value of the extracted field
314 (i.e., a number, `UInt64`, `Address`, etc.). The third return is is the offset where
315 data should be read next. This is useful when the length of the field is not known in
316 advance. The additional return values may be null if the field type is not well supported
317 in the Lua API.
319 This function can extract a <<lua_class_ProtoField,`ProtoField`>> of type `ftypes.BYTES`
320 or `ftypes.ABSOLUTE_TIME` from a string in the `TvbRange` in ASCII-based and similar
321 encodings. For example, a `ProtoField` of `ftypes.BYTES` can be extracted from a `TvbRange`
322 containing the ASCII string "a1b2c3d4e5f6", and it will correctly decode the ASCII both in the
323 tree as well as for the second return value, which will be a <<lua_class_ByteArray,`ByteArray`>>.
324 To do so, you must set the `encoding` argument of this function to the appropriate string `ENC_*`
325 value, bitwise-or'd (or added) with the `ENC_STR_HEX` value and one or more `ENC_SEP_XXX` values
326 indicating which encodings are allowed. For `ftypes.ABSOLUTE_TIME`, one of the `ENC_ISO_8601_*`
327 encodings or `ENC_IMF_DATE_TIME` must be used, and the second return value is a <<lua_class_NSTime,`NSTime`>>.
328 Only single-byte ASCII digit string encodings such as `ENC_ASCII` and `ENC_UTF_8` can be used for this.
330 For example, assuming the <<lua_class_Tvb,`Tvb`>> named "`tvb`" contains the string "abcdef"
331 (61 62 63 64 65 66 in hex):
333 [source,lua]
334 ----
335 -- this is done earlier in the script
336 local myfield = ProtoField.new("Transaction ID", "myproto.trans_id", ftypes.BYTES)
337 myproto.fields = { myfield }
339 -- this is done inside a dissector, post-dissector, or heuristic function
340 -- child will be the created child tree, and value will be the ByteArray "abcdef" or nil on failure
341 local child, value = tree:add_packet_field(myfield, tvb:range(0,6), ENC_UTF_8 + ENC_STR_HEX + ENC_SEP_NONE)
342 ----
345 #define WSLUA_ARG_TreeItem_add_packet_field_PROTOFIELD 2 /* The ProtoField field object to add to the tree. */
346 #define WSLUA_OPTARG_TreeItem_add_packet_field_TVBRANGE 3 /* The <<lua_class_TvbRange,`TvbRange`>> of bytes in the packet this tree item covers/represents. */
347 #define WSLUA_ARG_TreeItem_add_packet_field_ENCODING 4 /* The field's encoding in the `TvbRange`. */
348 #define WSLUA_OPTARG_TreeItem_add_packet_field_LABEL 5 /* One or more strings to append to the created <<lua_class_TreeItem,`TreeItem`>>. */
349 volatile TvbRange tvbr;
350 ProtoField field;
351 int hfid;
352 volatile int ett;
353 ftenum_t type;
354 TreeItem tree_item = shiftTreeItem(L,1);
355 unsigned encoding;
356 proto_item* item = NULL;
357 volatile int nargs;
358 volatile int err = 0;
359 const char *volatile error = NULL;
361 if (!tree_item) {
362 return luaL_error(L,"not a TreeItem!");
364 if (tree_item->expired) {
365 luaL_error(L,"expired TreeItem");
366 return 0;
369 if (! ( field = shiftProtoField(L,1) ) ) {
370 luaL_error(L,"TreeField:add_packet_field not passed a ProtoField");
371 return 0;
373 if (field->hfid == -2) {
374 luaL_error(L, "ProtoField %s unregistered (not added to a Proto.fields attribute)", field->abbrev);
376 hfid = field->hfid;
377 type = field->type;
378 ett = field->ett;
380 tvbr = shiftTvbRange(L,1);
381 if (!tvbr) {
382 /* No TvbRange specified */
383 tvbr = wmem_new(lua_pinfo->pool, struct _wslua_tvbrange);
384 tvbr->tvb = wmem_new(lua_pinfo->pool, struct _wslua_tvb);
385 tvbr->tvb->ws_tvb = lua_tvb;
386 tvbr->offset = 0;
387 tvbr->len = 0;
390 encoding = wslua_checkuint(L,1);
391 lua_remove(L,1);
393 /* get the number of additional args before we add more to the stack */
394 nargs = lua_gettop(L);
396 /* XXX: why is this being done? If the length was -1, FT_STRINGZ figures out
397 * the right length in tvb_get_stringz_enc(); if it was 0, it should remain zero;
398 * if it was greater than zero, then it's the length the caller wanted.
400 if (type == FT_STRINGZ) {
401 switch (encoding & ENC_CHARENCODING_MASK) {
403 case ENC_UTF_16:
404 case ENC_UCS_2:
405 tvbr->len = tvb_unicode_strsize (tvbr->tvb->ws_tvb, tvbr->offset);
406 break;
408 default:
409 if (tvb_find_uint8 (tvbr->tvb->ws_tvb, tvbr->offset, -1, 0) == -1) {
410 luaL_error(L,"out of bounds");
411 return 0;
413 tvbr->len = tvb_strsize (tvbr->tvb->ws_tvb, tvbr->offset);
414 break;
418 TRY {
419 int errx = 0;
420 item = try_add_packet_field(L, tree_item, tvbr, hfid, type, encoding, &errx);
421 err = errx;
422 } CATCH_ALL {
423 show_exception(tvbr->tvb->ws_tvb, lua_pinfo, tree_item->tree, EXCEPT_CODE, GET_MESSAGE);
424 error = "Lua programming error";
425 } ENDTRY;
427 if (error) { WSLUA_ERROR(TreeItem_add_packet_field,error); }
429 if (err != 0) {
430 lua_pushnil(L);
431 lua_pushnil(L);
434 while(nargs) {
435 const char* s;
436 s = lua_tostring(L,1);
437 if (s) proto_item_append_text(item, " %s", s);
438 lua_remove(L,1);
439 nargs--;
442 push_TreeItem(L, proto_item_add_subtree(item,ett > 0 ? ett : wslua_ett), item);
444 /* move the tree object before the field value */
445 lua_insert(L, 1);
447 WSLUA_RETURN(3); /* The new child <<lua_class_TreeItem,`TreeItem`>>, the field's extracted value or nil, and offset or nil. */
450 /* The following is used by TreeItem_add() and TreeItem_le() and can THROW.
451 * It should be called inside a TRY (e.g. WRAP_NON_LUA_EXCEPTIONS) block and
452 * THROW_LUA_ERROR should be used insteadof lua[L]_error.
454 static int TreeItem_add_item_any(lua_State *L, bool little_endian) {
455 TvbRange tvbr;
456 Proto proto;
457 ProtoField field;
458 int hfid = -1;
459 int ett = -1;
460 ftenum_t type = FT_NONE;
461 TreeItem tree_item = shiftTreeItem(L,1);
462 proto_item* item = NULL;
464 if (!tree_item) {
465 THROW_LUA_ERROR("not a TreeItem!");
467 if (tree_item->expired) {
468 THROW_LUA_ERROR("expired TreeItem");
469 return 0;
472 if (! ( field = shiftProtoField(L,1) ) ) {
473 if (( proto = shiftProto(L,1) )) {
474 hfid = proto->hfid;
475 type = FT_PROTOCOL;
476 ett = proto->ett;
477 } else if (lua_isnil(L, 1)) {
478 THROW_LUA_ERROR("first argument to TreeItem:add is nil!");
480 } else {
481 hfid = field->hfid;
482 type = field->type;
483 ett = field->ett;
486 tvbr = shiftTvbRange(L,1);
488 if (!tvbr) {
489 tvbr = wmem_new(lua_pinfo->pool, struct _wslua_tvbrange);
490 tvbr->tvb = wmem_new(lua_pinfo->pool, struct _wslua_tvb);
491 tvbr->tvb->ws_tvb = lua_tvb;
492 tvbr->offset = 0;
493 tvbr->len = 0;
496 if (hfid > 0 ) {
497 /* hfid is > 0 when the first arg was a ProtoField or Proto */
499 if (type == FT_STRINGZ) {
500 if (tvb_find_uint8 (tvbr->tvb->ws_tvb, tvbr->offset, -1, 0) == -1) {
501 THROW_LUA_ERROR("out of bounds");
502 return 0;
504 tvbr->len = tvb_strsize (tvbr->tvb->ws_tvb, tvbr->offset);
507 if (lua_gettop(L)) {
508 /* if we got here, the (L,1) index is the value to add, instead of decoding from the Tvb */
510 /* It's invalid for it to be nil (which has been documented for
511 * a long time). Make sure we throw our error instead of an
512 * internal Lua error (due to nested setjmp/longjmp).
514 if (lua_isnil(L, 1)) {
515 THROW_LUA_ERROR("TreeItem:add value argument is nil!");
518 switch(type) {
519 case FT_PROTOCOL:
520 item = proto_tree_add_item(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,ENC_NA);
521 lua_pushinteger(L,0);
522 lua_insert(L,1);
523 break;
524 case FT_BOOLEAN:
526 uint64_t val;
527 switch(lua_type(L, 1)) {
529 case LUA_TUSERDATA:
530 val = checkUInt64(L, 1);
531 break;
533 default:
534 /* this needs to use checkinteger so that it can accept a Lua boolean and coerce it to an int */
535 val = (uint64_t) (wslua_tointeger(L,1));
537 item = proto_tree_add_boolean(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,val);
539 break;
540 case FT_CHAR:
541 case FT_UINT8:
542 case FT_UINT16:
543 case FT_UINT24:
544 case FT_UINT32:
545 case FT_FRAMENUM:
546 item = proto_tree_add_uint(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,wslua_checkuint32(L,1));
547 break;
548 case FT_INT8:
549 case FT_INT16:
550 case FT_INT24:
551 case FT_INT32:
552 item = proto_tree_add_int(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,wslua_checkint32(L,1));
553 break;
554 case FT_FLOAT:
555 item = proto_tree_add_float(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(float)luaL_checknumber(L,1));
556 break;
557 case FT_DOUBLE:
558 item = proto_tree_add_double(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(double)luaL_checknumber(L,1));
559 break;
560 case FT_ABSOLUTE_TIME:
561 case FT_RELATIVE_TIME:
562 item = proto_tree_add_time(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,checkNSTime(L,1));
563 break;
564 case FT_STRING:
565 case FT_STRINGZ:
566 item = proto_tree_add_string(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,luaL_checkstring(L,1));
567 break;
568 case FT_BYTES:
569 item = proto_tree_add_bytes(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len, (const uint8_t*) luaL_checkstring(L,1));
570 break;
571 case FT_UINT64:
572 item = proto_tree_add_uint64(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,checkUInt64(L,1));
573 break;
574 case FT_INT64:
575 item = proto_tree_add_int64(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,checkInt64(L,1));
576 break;
577 case FT_IPv4:
579 Address addr = checkAddress(L,1);
580 uint32_t addr_value;
582 if (addr->type != AT_IPv4) {
583 THROW_LUA_ERROR("Expected IPv4 address for FT_IPv4 field");
584 return 0;
588 * The address is not guaranteed to be aligned on a
589 * 32-bit boundary, so we can't safely dereference
590 * the pointer as if it were so aligned.
592 memcpy(&addr_value, addr->data, sizeof addr_value);
593 item = proto_tree_add_ipv4(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,addr_value);
595 break;
596 case FT_IPv6:
598 Address addr = checkAddress(L,1);
599 if (addr->type != AT_IPv6) {
600 THROW_LUA_ERROR("Expected IPv6 address for FT_IPv6 field");
601 return 0;
604 item = proto_tree_add_ipv6(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, (const ws_in6_addr *)addr->data);
606 break;
607 case FT_ETHER:
609 Address addr = checkAddress(L,1);
610 if (addr->type != AT_ETHER) {
611 THROW_LUA_ERROR("Expected MAC address for FT_ETHER field");
612 return 0;
615 item = proto_tree_add_ether(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, (const uint8_t *)addr->data);
617 break;
618 case FT_UINT_BYTES:
619 case FT_IPXNET:
620 case FT_GUID:
621 case FT_OID:
622 case FT_REL_OID:
623 case FT_SYSTEM_ID:
624 case FT_VINES:
625 case FT_FCWWN:
626 default:
627 THROW_LUA_ERROR("%s not yet supported", ftype_name(type));
628 return 0;
631 lua_remove(L,1);
633 } else {
634 if (type == FT_FRAMENUM) {
635 THROW_LUA_ERROR("ProtoField FRAMENUM cannot fetch value from Tvb");
636 return 0;
638 /* the Lua stack is empty - no value was given - so decode the value from the tvb */
639 item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
642 if ( lua_gettop(L) ) {
643 /* if there was a value, it was removed earlier, so what's left is the display string to set */
644 const char* s = lua_tostring(L,1);
645 if (s) proto_item_set_text(item,"%s",s);
646 lua_remove(L,1);
649 } else {
650 /* no ProtoField or Proto was given - we're adding a text-only field,
651 * any remaining parameters are parts of the text label. */
652 if (lua_gettop(L)) {
653 const char* s = lua_tostring(L,1);
654 const int hf = get_hf_wslua_text();
655 if (hf > -1) {
656 /* use proto_tree_add_none_format() instead? */
657 item = proto_tree_add_item(tree_item->tree, hf, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, ENC_NA);
658 proto_item_set_text(item, "%s", s);
659 } else {
660 THROW_LUA_ERROR("Internal error: hf_wslua_text not registered");
662 lua_remove(L,1);
663 } else {
664 THROW_LUA_ERROR("Tree item ProtoField/Protocol handle is invalid (ProtoField/Proto not registered?)");
668 while(lua_gettop(L)) {
669 /* keep appending more text */
670 const char* s = lua_tostring(L,1);
671 if (s) proto_item_append_text(item, " %s", s);
672 lua_remove(L,1);
675 push_TreeItem(L, proto_item_add_subtree(item,ett > 0 ? ett : wslua_ett), item);
677 return 1;
681 WSLUA_METHOD TreeItem_add(lua_State *L) {
683 Adds a child item to this tree item, returning the new child <<lua_class_TreeItem,`TreeItem`>>.
685 If the <<lua_class_ProtoField,`ProtoField`>> represents a numeric value (int, uint or float), then it's treated as a Big Endian (network order) value.
687 This function has a complicated form: 'treeitem:add([protofield,] [tvbrange,] [[value], label]])', such that if the first
688 argument is a <<lua_class_ProtoField,`ProtoField`>> or a <<lua_class_Proto,`Proto`>>, the second argument is a <<lua_class_TvbRange,`TvbRange`>>, and a third argument is given, it's a value;
689 but if the second argument is a non-<<lua_class_TvbRange,`TvbRange`>>, then it's the value (as opposed to filling that argument with 'nil',
690 which is invalid for this function). If the first argument is a non-<<lua_class_ProtoField,`ProtoField`>> and a non-<<lua_class_Proto,`Proto`>> then this argument can
691 be either a <<lua_class_TvbRange,`TvbRange`>> or a label, and the value is not in use.
693 [discrete]
694 ====== Example
696 [source,lua]
697 ----
698 local proto_foo = Proto("foo", "Foo Protocol")
699 proto_foo.fields.bytes = ProtoField.bytes("foo.bytes", "Byte array")
700 proto_foo.fields.u16 = ProtoField.uint16("foo.u16", "Unsigned short", base.HEX)
702 function proto_foo.dissector(buf, pinfo, tree)
703 -- ignore packets less than 4 bytes long
704 if buf:len() < 4 then return end
706 -- ##############################################
707 -- # Assume buf(0,4) == {0x00, 0x01, 0x00, 0x02}
708 -- ##############################################
710 local t = tree:add( proto_foo, buf() )
712 -- Adds a byte array that shows as: "Byte array: 00010002"
713 t:add( proto_foo.fields.bytes, buf(0,4) )
715 -- Adds a byte array that shows as "Byte array: 313233"
716 -- (the ASCII char code of each character in "123")
717 t:add( proto_foo.fields.bytes, buf(0,4), "123" )
719 -- Adds a tree item that shows as: "Unsigned short: 0x0001"
720 t:add( proto_foo.fields.u16, buf(0,2) )
722 -- Adds a tree item that shows as: "Unsigned short: 0x0064"
723 t:add( proto_foo.fields.u16, buf(0,2), 100 )
725 -- Adds a tree item that shows as: "Unsigned short: 0x0064 ( big endian )"
726 t:add( proto_foo.fields.u16, buf(1,2), 100, nil, "(", nil, "big", 999, nil, "endian", nil, ")" )
728 -- LITTLE ENDIAN: Adds a tree item that shows as: "Unsigned short: 0x0100"
729 t:add_le( proto_foo.fields.u16, buf(0,2) )
731 -- LITTLE ENDIAN: Adds a tree item that shows as: "Unsigned short: 0x6400"
732 t:add_le( proto_foo.fields.u16, buf(0,2), 100 )
734 -- LITTLE ENDIAN: Adds a tree item that shows as: "Unsigned short: 0x6400 ( little endian )"
735 t:add_le( proto_foo.fields.u16, buf(1,2), 100, nil, "(", nil, "little", 999, nil, "endian", nil, ")" )
738 udp_table = DissectorTable.get("udp.port")
739 udp_table:add(7777, proto_foo)
740 ----
742 #define WSLUA_OPTARG_TreeItem_add_PROTOFIELD 2 /* The <<lua_class_ProtoField,`ProtoField`>> field or <<lua_class_Proto,`Proto`>> protocol object to add to the tree. */
743 #define WSLUA_OPTARG_TreeItem_add_TVBRANGE 3 /* The <<lua_class_TvbRange,`TvbRange`>> of bytes in the packet this tree item covers/represents. */
744 #define WSLUA_OPTARG_TreeItem_add_VALUE 4 /* The field's value, instead of the ProtoField/Proto one. */
745 #define WSLUA_OPTARG_TreeItem_add_LABEL 5 /* One or more strings to use for the tree item label, instead of the ProtoField/Proto one. */
747 volatile int ret;
748 WRAP_NON_LUA_EXCEPTIONS(
749 ret = TreeItem_add_item_any(L,false);
751 WSLUA_RETURN(ret); /* The new child TreeItem. */
754 WSLUA_METHOD TreeItem_add_le(lua_State *L) {
756 Adds a child item to this tree item, returning the new child <<lua_class_TreeItem,`TreeItem`>>.
758 If the <<lua_class_ProtoField,`ProtoField`>> represents a numeric value (int, uint or float), then it's treated as a Little Endian value.
760 This function has a complicated form: 'treeitem:add_le([protofield,] [tvbrange,] [[value], label]])', such that if the first
761 argument is a <<lua_class_ProtoField,`ProtoField`>> or a <<lua_class_Proto,`Proto`>>, the second argument is a <<lua_class_TvbRange,`TvbRange`>>, and a third argument is given, it's a value;
762 but if the second argument is a non-<<lua_class_TvbRange,`TvbRange`>>, then it's the value (as opposed to filling that argument with 'nil',
763 which is invalid for this function). If the first argument is a non-<<lua_class_ProtoField,`ProtoField`>> and a non-<<lua_class_Proto,`Proto`>> then this argument can
764 be either a <<lua_class_TvbRange,`TvbRange`>> or a label, and the value is not in use.
766 #define WSLUA_OPTARG_TreeItem_add_le_PROTOFIELD 2 /* The ProtoField field or Proto protocol object to add to the tree. */
767 #define WSLUA_OPTARG_TreeItem_add_le_TVBRANGE 3 /* The TvbRange of bytes in the packet this tree item covers/represents. */
768 #define WSLUA_OPTARG_TreeItem_add_le_VALUE 4 /* The field's value, instead of the ProtoField/Proto one. */
769 #define WSLUA_OPTARG_TreeItem_add_le_LABEL 5 /* One or more strings to use for the tree item label, instead of the ProtoField/Proto one. */
770 volatile int ret;
771 WRAP_NON_LUA_EXCEPTIONS(
772 ret = TreeItem_add_item_any(L,true);
774 WSLUA_RETURN(ret); /* The new child TreeItem. */
777 /* WSLUA_ATTRIBUTE TreeItem_text RW Set/get the <<lua_class_TreeItem,`TreeItem`>>'s display string (string).
779 For the getter, if the TreeItem has no display string, then nil is returned.
781 static int TreeItem_get_text(lua_State* L) {
782 TreeItem ti = checkTreeItem(L,1);
783 char label_str[ITEM_LABEL_LENGTH+1];
784 char *label_ptr;
786 if (ti->item && PITEM_FINFO(ti->item)) {
787 field_info *fi = PITEM_FINFO(ti->item);
789 if (!fi->rep) {
790 label_ptr = label_str;
791 proto_item_fill_label(fi, label_str, NULL);
792 } else
793 label_ptr = fi->rep->representation;
795 if (label_ptr) {
796 lua_pushstring(L, label_ptr);
797 } else {
798 lua_pushnil(L);
800 } else {
801 lua_pushnil(L);
804 return 1;
807 /* the following is used as both a method and attribute */
808 WSLUA_METHOD TreeItem_set_text(lua_State *L) {
809 /* Sets the text of the label.
811 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
813 #define WSLUA_ARG_TreeItem_set_text_TEXT 2 /* The text to be used. */
814 TreeItem ti = checkTreeItem(L,1);
815 const char* s = luaL_checkstring(L,WSLUA_ARG_TreeItem_set_text_TEXT);
817 proto_item_set_text(ti->item,"%s",s);
819 /* copy the TreeItem userdata so we give it back */
820 lua_pushvalue(L, 1);
822 WSLUA_RETURN(1); /* The same TreeItem. */
825 WSLUA_METHOD TreeItem_append_text(lua_State *L) {
826 /* Appends text to the label.
828 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
830 #define WSLUA_ARG_TreeItem_append_text_TEXT 2 /* The text to be appended. */
831 TreeItem ti = checkTreeItem(L,1);
832 const char* s = luaL_checkstring(L,WSLUA_ARG_TreeItem_append_text_TEXT);
834 proto_item_append_text(ti->item,"%s",s);
836 /* copy the TreeItem userdata so we give it back */
837 lua_pushvalue(L, 1);
839 WSLUA_RETURN(1); /* The same TreeItem. */
842 WSLUA_METHOD TreeItem_prepend_text(lua_State *L) {
843 /* Prepends text to the label.
845 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
847 #define WSLUA_ARG_TreeItem_prepend_text_TEXT 2 /* The text to be prepended. */
848 TreeItem ti = checkTreeItem(L,1);
849 const char* s = luaL_checkstring(L,WSLUA_ARG_TreeItem_prepend_text_TEXT);
851 proto_item_prepend_text(ti->item,"%s",s);
853 /* copy the TreeItem userdata so we give it back */
854 lua_pushvalue(L, 1);
856 WSLUA_RETURN(1); /* The same TreeItem. */
859 WSLUA_METHOD TreeItem_add_expert_info(lua_State *L) {
860 /* Sets the expert flags of the item and adds expert info to the packet.
862 This function does *not* create a truly filterable expert info for a protocol.
863 Instead you should use `TreeItem.add_proto_expert_info()`.
865 Note: This function is provided for backwards compatibility only, and should not
866 be used in new Lua code. It may be removed in the future. You should only
867 use `TreeItem.add_proto_expert_info()`.
869 #define WSLUA_OPTARG_TreeItem_add_expert_info_GROUP 2 /* One of:
870 `PI_CHECKSUM`,
871 `PI_SEQUENCE`,
872 `PI_RESPONSE_CODE`,
873 `PI_REQUEST_CODE`,
874 `PI_UNDECODED`,
875 `PI_REASSEMBLE`,
876 `PI_MALFORMED`,
877 `PI_DEBUG`,
878 `PI_PROTOCOL`,
879 `PI_SECURITY`,
880 `PI_COMMENTS_GROUP`,
881 `PI_DECRYPTION`,
882 `PI_ASSUMPTION`,
883 `PI_DEPRECATED`,
884 `PI_RECEIVE`,
885 `PI_INTERFACE`,
886 or `PI_DISSECTOR_BUG`. */
887 #define WSLUA_OPTARG_TreeItem_add_expert_info_SEVERITY 3 /* One of:
888 `PI_COMMENT`,
889 `PI_CHAT`,
890 `PI_NOTE`,
891 `PI_WARN`,
892 or `PI_ERROR`. */
893 #define WSLUA_OPTARG_TreeItem_add_expert_info_TEXT 4 /* The text for the expert info display. */
894 TreeItem ti = checkTreeItem(L,1);
895 int group = (int)luaL_optinteger(L,WSLUA_OPTARG_TreeItem_add_expert_info_GROUP,PI_DEBUG);
896 int severity = (int)luaL_optinteger(L,WSLUA_OPTARG_TreeItem_add_expert_info_SEVERITY,PI_CHAT);
897 expert_field* ei_info = wslua_get_expert_field(group, severity);
898 const char* str;
900 if (lua_gettop(L) >= WSLUA_OPTARG_TreeItem_add_expert_info_TEXT) {
901 str = wslua_checkstring_only(L, WSLUA_OPTARG_TreeItem_add_expert_info_TEXT);
902 expert_add_info_format(lua_pinfo, ti->item, ei_info, "%s", str);
903 } else {
904 expert_add_info(lua_pinfo, ti->item, ei_info);
907 /* copy the TreeItem userdata so we give it back */
908 lua_pushvalue(L, 1);
910 WSLUA_RETURN(1); /* The same TreeItem. */
913 WSLUA_METHOD TreeItem_add_proto_expert_info(lua_State *L) {
914 /* Sets the expert flags of the tree item and adds expert info to the packet. */
915 #define WSLUA_ARG_TreeItem_add_proto_expert_info_EXPERT 2 /* The <<lua_class_ProtoExpert,`ProtoExpert`>> object to add to the tree. */
916 #define WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT 3 /* Text for the expert info display
917 (default is to use the registered
918 text). */
919 TreeItem ti = checkTreeItem(L,1);
920 ProtoExpert expert = checkProtoExpert(L,WSLUA_ARG_TreeItem_add_proto_expert_info_EXPERT);
921 const char* str;
923 if (expert->ids.ei == EI_INIT_EI || expert->ids.hf == EI_INIT_HF) {
924 luaL_error(L, "ProtoExpert is not registered");
925 return 0;
928 if (lua_gettop(L) >= WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT) {
929 str = wslua_checkstring_only(L, WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT);
930 expert_add_info_format(lua_pinfo, ti->item, &expert->ids, "%s", str);
931 } else {
932 expert_add_info(lua_pinfo, ti->item, &expert->ids);
935 /* copy the TreeItem userdata so we give it back */
936 lua_pushvalue(L, 1);
938 WSLUA_RETURN(1); /* The same TreeItem. */
941 WSLUA_METHOD TreeItem_add_tvb_expert_info(lua_State *L) {
942 /* Sets the expert flags of the tree item and adds expert info to the packet
943 associated with the <<lua_class_Tvb,`Tvb`>> or <<lua_class_TvbRange,`TvbRange`>> bytes in the packet. */
944 #define WSLUA_ARG_TreeItem_add_tvb_expert_info_EXPERT 2 /* The <<lua_class_ProtoExpert,`ProtoExpert`>> object to add to the tree. */
945 #define WSLUA_ARG_TreeItem_add_tvb_expert_info_TVB 3 /* The <<lua_class_Tvb,`Tvb`>> or <<lua_class_TvbRange,`TvbRange`>> object bytes to associate
946 the expert info with. */
947 #define WSLUA_OPTARG_TreeItem_add_tvb_expert_info_TEXT 4 /* Text for the expert info display
948 (default is to use the registered
949 text). */
950 TreeItem ti = checkTreeItem(L,1);
951 ProtoExpert expert = checkProtoExpert(L,WSLUA_ARG_TreeItem_add_proto_expert_info_EXPERT);
952 TvbRange tvbr;
953 const char* str;
955 if (expert->ids.ei == EI_INIT_EI || expert->ids.hf == EI_INIT_HF) {
956 luaL_error(L, "ProtoExpert is not registered");
957 return 0;
960 tvbr = shiftTvbRange(L,WSLUA_ARG_TreeItem_add_tvb_expert_info_TVB);
962 if (!tvbr) {
963 tvbr = wmem_new(lua_pinfo->pool, struct _wslua_tvbrange);
964 tvbr->tvb = shiftTvb(L,WSLUA_ARG_TreeItem_add_tvb_expert_info_TVB);
965 if (!tvbr->tvb) {
966 tvbr->tvb = wmem_new(lua_pinfo->pool, struct _wslua_tvb);
968 tvbr->tvb->ws_tvb = lua_tvb;
969 tvbr->offset = 0;
970 tvbr->len = 0;
973 if (lua_gettop(L) >= WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT) {
974 str = wslua_checkstring_only(L, WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT);
975 proto_tree_add_expert_format(ti->tree, lua_pinfo, &expert->ids,
976 tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len,
977 "%s", str);
978 } else {
979 proto_tree_add_expert(ti->tree, lua_pinfo, &expert->ids,
980 tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
983 /* copy the TreeItem userdata so we give it back */
984 lua_pushvalue(L, 1);
986 WSLUA_RETURN(1); /* The same TreeItem. */
990 /* WSLUA_ATTRIBUTE TreeItem_visible RO Get the <<lua_class_TreeItem,`TreeItem`>>'s subtree visibility status (boolean). */
991 static int TreeItem_get_visible(lua_State* L) {
992 TreeItem ti = checkTreeItem(L,1);
994 if (ti->tree) {
995 lua_pushboolean(L, PTREE_DATA(ti->tree)->visible);
997 else {
998 lua_pushboolean(L, false);
1001 return 1;
1005 /* WSLUA_ATTRIBUTE TreeItem_generated RW Set/get the <<lua_class_TreeItem,`TreeItem`>>'s generated state (boolean). */
1006 static int TreeItem_get_generated(lua_State* L) {
1007 TreeItem ti = checkTreeItem(L,1);
1009 lua_pushboolean(L, proto_item_is_generated(ti->item));
1011 return 1;
1014 /* the following is used as both a method and attribute. As a method it defaults
1015 to setting the value, because that's what it used to do before. */
1016 WSLUA_METHOD TreeItem_set_generated(lua_State *L) {
1017 /* Marks the <<lua_class_TreeItem,`TreeItem`>> as a generated field (with data inferred but not contained in the packet).
1019 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
1021 #define WSLUA_OPTARG_TreeItem_set_generated_BOOL 2 /* A Lua boolean, which if `true` sets the <<lua_class_TreeItem,`TreeItem`>>
1022 generated flag, else clears it (default=true) */
1023 TreeItem ti = checkTreeItem(L,1);
1024 bool set = wslua_optbool(L, WSLUA_OPTARG_TreeItem_set_generated_BOOL, true);
1026 if (set) {
1027 proto_item_set_generated(ti->item);
1028 } else {
1029 if (ti->item)
1030 FI_RESET_FLAG(PITEM_FINFO(ti->item), FI_GENERATED);
1033 /* copy the TreeItem userdata so we give it back */
1034 lua_pushvalue(L, 1);
1036 WSLUA_RETURN(1); /* The same TreeItem. */
1039 /* WSLUA_ATTRIBUTE TreeItem_hidden RW Set/get <<lua_class_TreeItem,`TreeItem`>>'s hidden state (boolean). */
1040 static int TreeItem_get_hidden(lua_State* L) {
1041 TreeItem ti = checkTreeItem(L,1);
1043 lua_pushboolean(L, proto_item_is_hidden(ti->item));
1045 return 1;
1048 /* the following is used as both a method and attribute. As a method it defaults
1049 to setting the value, because that's what it used to do before. */
1050 WSLUA_METHOD TreeItem_set_hidden(lua_State *L) {
1052 Marks the <<lua_class_TreeItem,`TreeItem`>> as a hidden field (neither displayed nor used in filters).
1053 Deprecated
1055 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
1057 #define WSLUA_OPTARG_TreeItem_set_hidden_BOOL 2 /* A Lua boolean, which if `true` sets the <<lua_class_TreeItem,`TreeItem`>>
1058 hidden flag, else clears it. Default is `true`. */
1059 TreeItem ti = checkTreeItem(L,1);
1060 bool set = wslua_optbool(L, WSLUA_OPTARG_TreeItem_set_hidden_BOOL, true);
1062 if (set) {
1063 proto_item_set_hidden(ti->item);
1064 } else {
1065 proto_item_set_visible(ti->item);
1068 /* copy the TreeItem userdata so we give it back */
1069 lua_pushvalue(L, 1);
1071 WSLUA_RETURN(1); /* The same TreeItem. */
1074 /* WSLUA_ATTRIBUTE TreeItem_len RW Set/get <<lua_class_TreeItem,`TreeItem`>>'s length inside tvb, after it has already been created. */
1075 static int TreeItem_get_len(lua_State* L) {
1076 TreeItem ti = checkTreeItem(L,1);
1077 int len = 0;
1079 /* XXX - this is *NOT* guaranteed to return a correct value! */
1080 len = proto_item_get_len(ti->item);
1082 lua_pushinteger(L, len > 0 ? len : 0);
1084 return 1;
1087 WSLUA_METHOD TreeItem_set_len(lua_State *L) {
1088 /* Set <<lua_class_TreeItem,`TreeItem`>>'s length inside tvb, after it has already been created.
1090 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
1092 #define WSLUA_ARG_TreeItem_set_len_LEN 2 /* The length to be used. */
1093 TreeItem ti = checkTreeItem(L,1);
1094 int len = (int)luaL_checkinteger(L,WSLUA_ARG_TreeItem_set_len_LEN);
1096 proto_item_set_len(ti->item, len);
1098 /* copy the TreeItem userdata so we give it back */
1099 lua_pushvalue(L, 1);
1101 WSLUA_RETURN(1); /* The same TreeItem. */
1104 WSLUA_METHOD TreeItem_referenced(lua_State *L) {
1105 /* Checks if a <<lua_class_ProtoField,`ProtoField`>> or <<lua_class_Dissector,`Dissector`>> is referenced by a filter/tap/UI.
1107 If this function returns `false`, it means that the field (or dissector) does not need to be dissected
1108 and can be safely skipped. By skipping a field rather than dissecting it, the dissector will
1109 usually run faster since Wireshark will not do extra dissection work when it doesn't need the field.
1111 You can use this in conjunction with the TreeItem.visible attribute. This function will always return
1112 true when the TreeItem is visible. When it is not visible and the field is not referenced, you can
1113 speed up the dissection by not dissecting the field as it is not needed for display or filtering.
1115 This function takes one parameter that can be a <<lua_class_ProtoField,`ProtoField`>> or <<lua_class_Dissector,`Dissector`>>.
1116 The <<lua_class_Dissector,`Dissector`>> form is useful when you need to decide whether to call a sub-dissector.
1118 #define WSLUA_ARG_TreeItem_referenced_PROTOFIELD 2 /* The <<lua_class_ProtoField,`ProtoField`>> or <<lua_class_Dissector,`Dissector`>> to check if referenced. */
1119 TreeItem ti = checkTreeItem(L, 1);
1120 if (!ti) return 0;
1121 ProtoField f = shiftProtoField(L, WSLUA_ARG_TreeItem_referenced_PROTOFIELD);
1122 if (f) {
1123 lua_pushboolean(L, proto_field_is_referenced(ti->tree, f->hfid));
1125 else {
1126 Dissector d = checkDissector(L, WSLUA_ARG_TreeItem_referenced_PROTOFIELD);
1127 if (!d) return 0;
1128 lua_pushboolean(L, proto_field_is_referenced(ti->tree, dissector_handle_get_protocol_index(d)));
1130 WSLUA_RETURN(1); /* A boolean indicating if the ProtoField/Dissector is referenced */
1133 WSLUA_METAMETHOD TreeItem__tostring(lua_State* L) {
1134 /* Returns string debug information about the <<lua_class_TreeItem,`TreeItem`>>. */
1135 TreeItem ti = toTreeItem(L,1);
1137 if (ti) {
1138 lua_pushfstring(L,
1139 "TreeItem: expired=%s, has item=%s, has subtree=%s, they are %sthe same",
1140 ti->expired ? "true" : "false",
1141 ti->item ? "true" : "false",
1142 ti->tree ? "true" : "false",
1143 (ti->tree == ti->item) ? "" : "not ");
1145 else {
1146 lua_pushstring(L, "No TreeItem object!");
1149 return 1;
1152 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
1153 static int TreeItem__gc(lua_State* L) {
1154 TreeItem ti = toTreeItem(L,1);
1155 if (!ti) return 0;
1156 if (!ti->expired)
1157 ti->expired = true;
1158 else
1159 g_free(ti);
1160 return 0;
1163 WSLUA_ATTRIBUTES TreeItem_attributes[] = {
1164 WSLUA_ATTRIBUTE_RWREG(TreeItem,generated),
1165 WSLUA_ATTRIBUTE_RWREG(TreeItem,hidden),
1166 WSLUA_ATTRIBUTE_RWREG(TreeItem,len),
1167 WSLUA_ATTRIBUTE_RWREG(TreeItem,text),
1168 WSLUA_ATTRIBUTE_ROREG(TreeItem,visible),
1169 { NULL, NULL, NULL }
1172 WSLUA_METHODS TreeItem_methods[] = {
1173 WSLUA_CLASS_FNREG(TreeItem,add_packet_field),
1174 WSLUA_CLASS_FNREG(TreeItem,add),
1175 WSLUA_CLASS_FNREG(TreeItem,add_le),
1176 WSLUA_CLASS_FNREG(TreeItem,set_text),
1177 WSLUA_CLASS_FNREG(TreeItem,append_text),
1178 WSLUA_CLASS_FNREG(TreeItem,prepend_text),
1179 WSLUA_CLASS_FNREG(TreeItem,add_expert_info),
1180 WSLUA_CLASS_FNREG(TreeItem,add_proto_expert_info),
1181 WSLUA_CLASS_FNREG(TreeItem,add_tvb_expert_info),
1182 WSLUA_CLASS_FNREG(TreeItem,set_generated),
1183 WSLUA_CLASS_FNREG(TreeItem,set_hidden),
1184 WSLUA_CLASS_FNREG(TreeItem,set_len),
1185 WSLUA_CLASS_FNREG(TreeItem,referenced),
1186 { NULL, NULL }
1189 WSLUA_META TreeItem_meta[] = {
1190 WSLUA_CLASS_MTREG(TreeItem,tostring),
1191 { NULL, NULL }
1194 int TreeItem_register(lua_State *L) {
1195 int* etts[] = { &wslua_ett };
1196 wslua_ett = -1; /* Reset to support reload Lua plugins */
1197 WSLUA_REGISTER_CLASS_WITH_ATTRS(TreeItem);
1198 if (outstanding_TreeItem != NULL) {
1199 g_ptr_array_unref(outstanding_TreeItem);
1201 outstanding_TreeItem = g_ptr_array_new();
1202 proto_register_subtree_array(etts,1);
1203 return 0;
1207 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1209 * Local variables:
1210 * c-basic-offset: 4
1211 * tab-width: 8
1212 * indent-tabs-mode: nil
1213 * End:
1215 * vi: set shiftwidth=4 tabstop=8 expandtab:
1216 * :indentSize=4:tabSize=8:noTabs=true: