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>
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <epan/emem.h>
34 /* WSLUA_MODULE Tree Adding information to the dissection tree */
37 #include <epan/expert.h>
39 static gint wslua_ett
= -1;
41 static GPtrArray
* outstanding_TreeItem
= NULL
;
43 #define PUSH_TREEITEM(L,i) {g_ptr_array_add(outstanding_TreeItem,i);pushTreeItem(L,i);}
45 TreeItem
* push_TreeItem(lua_State
*L
, TreeItem t
) {
46 g_ptr_array_add(outstanding_TreeItem
,t
);
47 return pushTreeItem(L
,t
);
50 CLEAR_OUTSTANDING(TreeItem
, expired
, TRUE
)
52 WSLUA_CLASS_DEFINE(TreeItem
,NOP
,NOP
);
53 /* TreeItems represent information in the packet-details pane.
54 A root TreeItem is passed to dissectors as the third argument. */
56 WSLUA_METHOD
TreeItem_add_packet_field(lua_State
*L
) {
58 Adds an child item to a given item, returning the child.
59 tree_item:add_packet_field([proto_field], [tvbrange], [encoding], ...)
66 TreeItem tree_item
= shiftTreeItem(L
,1);
68 proto_item
* item
= NULL
;
71 return luaL_error(L
,"not a TreeItem!");
73 if (tree_item
->expired
) {
74 luaL_error(L
,"expired TreeItem");
78 if (! ( field
= shiftProtoField(L
,1) ) ) {
79 luaL_error(L
,"TreeField:add_packet_field not passed a ProtoField");
86 tvbr
= shiftTvbRange(L
,1);
88 /* No TvbRange specified */
89 tvbr
= ep_new(struct _wslua_tvbrange
);
90 tvbr
->tvb
= ep_new(struct _wslua_tvb
);
91 tvbr
->tvb
->ws_tvb
= lua_tvb
;
96 encoding
= (guint
)luaL_checknumber(L
,1);
98 if (type
== FT_STRINGZ
) {
99 switch (encoding
& ENC_CHARENCODING_MASK
) {
103 tvbr
->len
= tvb_unicode_strsize (tvbr
->tvb
->ws_tvb
, tvbr
->offset
);
107 tvbr
->len
= tvb_strsize (tvbr
->tvb
->ws_tvb
, tvbr
->offset
);
111 item
= proto_tree_add_item(tree_item
->tree
, hfid
, tvbr
->tvb
->ws_tvb
, tvbr
->offset
, tvbr
->len
, encoding
);
113 while(lua_gettop(L
)) {
115 s
= lua_tostring(L
,1);
116 if (s
) proto_item_append_text(item
, " %s", s
);
120 tree_item
= (TreeItem
)g_malloc(sizeof(struct _wslua_treeitem
));
121 tree_item
->item
= item
;
122 tree_item
->tree
= proto_item_add_subtree(item
,ett
> 0 ? ett
: wslua_ett
);
123 tree_item
->expired
= FALSE
;
125 PUSH_TREEITEM(L
,tree_item
);
130 static int TreeItem_add_item_any(lua_State
*L
, gboolean little_endian
) {
136 ftenum_t type
= FT_NONE
;
137 TreeItem tree_item
= shiftTreeItem(L
,1);
138 proto_item
* item
= NULL
;
141 return luaL_error(L
,"not a TreeItem!");
143 if (tree_item
->expired
) {
144 luaL_error(L
,"expired TreeItem");
148 if (! ( field
= shiftProtoField(L
,1) ) ) {
149 if (( proto
= shiftProto(L
,1) )) {
160 tvbr
= shiftTvbRange(L
,1);
163 tvbr
= ep_new(struct _wslua_tvbrange
);
164 tvbr
->tvb
= ep_new(struct _wslua_tvb
);
165 tvbr
->tvb
->ws_tvb
= lua_tvb
;
174 item
= proto_tree_add_item(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvbr
->len
,ENC_NA
);
179 item
= proto_tree_add_boolean(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvbr
->len
,(guint32
)luaL_checknumber(L
,1));
186 item
= proto_tree_add_uint(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvbr
->len
,(guint32
)luaL_checknumber(L
,1));
192 item
= proto_tree_add_int(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvbr
->len
,(gint32
)luaL_checknumber(L
,1));
195 item
= proto_tree_add_float(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvbr
->len
,(float)luaL_checknumber(L
,1));
198 item
= proto_tree_add_double(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvbr
->len
,(double)luaL_checknumber(L
,1));
200 case FT_ABSOLUTE_TIME
:
201 case FT_RELATIVE_TIME
:
202 item
= proto_tree_add_time(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvbr
->len
,checkNSTime(L
,1));
205 item
= proto_tree_add_string(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvbr
->len
,luaL_checkstring(L
,1));
208 item
= proto_tree_add_string(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvb_strsize (tvbr
->tvb
->ws_tvb
, tvbr
->offset
),luaL_checkstring(L
,1));
211 item
= proto_tree_add_bytes(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvbr
->len
, (const guint8
*) luaL_checkstring(L
,1));
214 item
= proto_tree_add_uint64(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvbr
->len
,*(UInt64
)checkUInt64(L
,1));
217 item
= proto_tree_add_int64(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvbr
->len
,*(Int64
)checkInt64(L
,1));
220 item
= proto_tree_add_ipv4(tree_item
->tree
,hfid
,tvbr
->tvb
->ws_tvb
,tvbr
->offset
,tvbr
->len
,*((guint32
*)(checkAddress(L
,1)->data
)));
230 luaL_error(L
,"FT_ not yet supported");
237 if (type
== FT_STRINGZ
) tvbr
->len
= tvb_strsize (tvbr
->tvb
->ws_tvb
, tvbr
->offset
);
238 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
);
241 if ( lua_gettop(L
) ) {
242 const gchar
* s
= lua_tostring(L
,1);
243 if (s
) proto_item_set_text(item
,"%s",s
);
249 const gchar
* s
= lua_tostring(L
,1);
250 item
= proto_tree_add_text(tree_item
->tree
, tvbr
->tvb
->ws_tvb
, tvbr
->offset
, tvbr
->len
,"%s",s
);
255 while(lua_gettop(L
)) {
256 const gchar
* s
= lua_tostring(L
,1);
257 if (s
) proto_item_append_text(item
, " %s", s
);
261 tree_item
= (TreeItem
)g_malloc(sizeof(struct _wslua_treeitem
));
262 tree_item
->item
= item
;
263 tree_item
->tree
= proto_item_add_subtree(item
,ett
> 0 ? ett
: wslua_ett
);
264 tree_item
->expired
= FALSE
;
266 PUSH_TREEITEM(L
,tree_item
);
272 WSLUA_METHOD
TreeItem_add(lua_State
*L
) {
274 Adds an child item to a given item, returning the child.
275 tree_item:add([proto_field | proto], [tvbrange], [label], ...)
276 if the proto_field represents a numeric value (int, uint or float) is to be treated as a Big Endian (network order) Value.
278 WSLUA_RETURN(TreeItem_add_item_any(L
,FALSE
)); /* The child item */
281 WSLUA_METHOD
TreeItem_add_le(lua_State
*L
) {
283 Adds (and returns) an child item to a given item, returning the child.
284 tree_item:add([proto_field | proto], [tvbrange], [label], ...)
285 if the proto_field represents a numeric value (int, uint or float) is to be treated as a Little Endian Value.
287 WSLUA_RETURN(TreeItem_add_item_any(L
,TRUE
)); /* The child item */
290 WSLUA_METHOD
TreeItem_set_text(lua_State
*L
) {
291 /* Sets the text of the label */
292 #define WSLUA_ARG_TreeItem_set_text_TEXT 2 /* The text to be used. */
293 TreeItem ti
= checkTreeItem(L
,1);
298 luaL_error(L
,"expired TreeItem");
302 s
= luaL_checkstring(L
,WSLUA_ARG_TreeItem_set_text_TEXT
);
303 proto_item_set_text(ti
->item
,"%s",s
);
309 WSLUA_METHOD
TreeItem_append_text(lua_State
*L
) {
310 /* Appends text to the label */
311 #define WSLUA_ARG_TreeItem_append_text_TEXT 2 /* The text to be appended. */
312 TreeItem ti
= checkTreeItem(L
,1);
317 luaL_error(L
,"expired TreeItem");
321 s
= luaL_checkstring(L
,WSLUA_ARG_TreeItem_append_text_TEXT
);
322 proto_item_append_text(ti
->item
,"%s",s
);
327 WSLUA_METHOD
TreeItem_prepend_text(lua_State
*L
) {
328 /* Prepends text to the label */
329 #define WSLUA_ARG_TreeItem_prepend_text_TEXT 2 /* The text to be prepended */
330 TreeItem ti
= checkTreeItem(L
,1);
335 luaL_error(L
,"expired TreeItem");
339 s
= luaL_checkstring(L
,WSLUA_ARG_TreeItem_prepend_text_TEXT
);
340 proto_item_prepend_text(ti
->item
,"%s",s
);
345 WSLUA_METHOD
TreeItem_add_expert_info(lua_State
*L
) {
346 /* Sets the expert flags of the item and adds expert info to the packet. */
347 #define WSLUA_OPTARG_TreeItem_add_expert_info_GROUP 2 /* One of PI_CHECKSUM, PI_SEQUENCE, PI_RESPONSE_CODE, PI_REQUEST_CODE, PI_UNDECODED, PI_REASSEMBLE, PI_MALFORMED or PI_DEBUG */
348 #define WSLUA_OPTARG_TreeItem_add_expert_info_SEVERITY 3 /* One of PI_CHAT, PI_NOTE, PI_WARN, PI_ERROR */
349 #define WSLUA_OPTARG_TreeItem_add_expert_info_TEXT 4 /* The text for the expert info */
350 TreeItem ti
= checkTreeItem(L
,1);
351 int group
= luaL_optint(L
,WSLUA_OPTARG_TreeItem_add_expert_info_GROUP
,PI_DEBUG
);
352 int severity
= luaL_optint(L
,WSLUA_OPTARG_TreeItem_add_expert_info_SEVERITY
,PI_CHAT
);
353 const gchar
* str
= luaL_optstring(L
,WSLUA_OPTARG_TreeItem_add_expert_info_TEXT
,"Expert Info");
355 if ( ti
&& ti
->item
) {
357 luaL_error(L
,"expired TreeItem");
360 expert_add_info_format_internal(lua_pinfo
, ti
->item
, group
, severity
, "%s", str
);
366 WSLUA_METHOD
TreeItem_set_generated(lua_State
*L
) {
367 /* Marks the TreeItem as a generated field (with data infered but not contained in the packet). */
368 TreeItem ti
= checkTreeItem(L
,1);
371 luaL_error(L
,"expired TreeItem");
374 PROTO_ITEM_SET_GENERATED(ti
->item
);
380 WSLUA_METHOD
TreeItem_set_hidden(lua_State
*L
) {
381 /* Should not be used */
382 TreeItem ti
= checkTreeItem(L
,1);
385 luaL_error(L
,"expired TreeItem");
388 PROTO_ITEM_SET_HIDDEN(ti
->item
);
393 WSLUA_METHOD
TreeItem_set_len(lua_State
*L
) {
394 /* Set TreeItem's length inside tvb, after it has already been created. */
395 #define WSLUA_ARG_TreeItem_set_len_LEN 2 /* The length to be used. */
396 TreeItem ti
= checkTreeItem(L
,1);
401 luaL_error(L
,"expired TreeItem");
405 len
= luaL_checkint(L
,WSLUA_ARG_TreeItem_set_len_LEN
);
406 proto_item_set_len(ti
->item
, len
);
412 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
413 static int TreeItem__gc(lua_State
* L
) {
414 TreeItem ti
= checkTreeItem(L
,1);
423 static const luaL_Reg TreeItem_methods
[] = {
424 {"add_packet_field", TreeItem_add_packet_field
},
425 {"add", TreeItem_add
},
426 {"add_le", TreeItem_add_le
},
427 {"set_text", TreeItem_set_text
},
428 {"append_text", TreeItem_append_text
},
429 {"prepend_text", TreeItem_prepend_text
},
430 {"add_expert_info", TreeItem_add_expert_info
},
431 {"set_generated", TreeItem_set_generated
},
432 {"set_hidden", TreeItem_set_hidden
},
433 {"set_len", TreeItem_set_len
},
437 static const luaL_Reg TreeItem_meta
[] = {
441 int TreeItem_register(lua_State
*L
) {
442 gint
* etts
[] = { &wslua_ett
};
443 WSLUA_REGISTER_CLASS(TreeItem
);
444 outstanding_TreeItem
= g_ptr_array_new();
445 proto_register_subtree_array(etts
,1);