HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / wslua / wslua_tree.c
blob6246e3862fb5c09a96d7cf281a6ce76c88986da4
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 * $Id$
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.
30 #include "config.h"
32 #include <epan/emem.h>
34 /* WSLUA_MODULE Tree Adding information to the dissection tree */
36 #include "wslua.h"
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], ...)
61 TvbRange tvbr;
62 ProtoField field;
63 int hfid;
64 int ett;
65 ftenum_t type;
66 TreeItem tree_item = shiftTreeItem(L,1);
67 guint encoding;
68 proto_item* item = NULL;
70 if (!tree_item) {
71 return luaL_error(L,"not a TreeItem!");
73 if (tree_item->expired) {
74 luaL_error(L,"expired TreeItem");
75 return 0;
78 if (! ( field = shiftProtoField(L,1) ) ) {
79 luaL_error(L,"TreeField:add_packet_field not passed a ProtoField");
80 return 0;
82 hfid = field->hfid;
83 type = field->type;
84 ett = field->ett;
86 tvbr = shiftTvbRange(L,1);
87 if (!tvbr) {
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;
92 tvbr->offset = 0;
93 tvbr->len = 0;
96 encoding = (guint)luaL_checknumber(L,1);
97 lua_remove(L,1);
98 if (type == FT_STRINGZ) {
99 switch (encoding & ENC_CHARENCODING_MASK) {
101 case ENC_UTF_16:
102 case ENC_UCS_2:
103 tvbr->len = tvb_unicode_strsize (tvbr->tvb->ws_tvb, tvbr->offset);
104 break;
106 default:
107 tvbr->len = tvb_strsize (tvbr->tvb->ws_tvb, tvbr->offset);
108 break;
111 item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, encoding);
113 while(lua_gettop(L)) {
114 const gchar* s;
115 s = lua_tostring(L,1);
116 if (s) proto_item_append_text(item, " %s", s);
117 lua_remove(L,1);
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);
127 return 1;
130 static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
131 TvbRange tvbr;
132 Proto proto;
133 ProtoField field;
134 int hfid = -1;
135 int ett = -1;
136 ftenum_t type = FT_NONE;
137 TreeItem tree_item = shiftTreeItem(L,1);
138 proto_item* item = NULL;
140 if (!tree_item) {
141 return luaL_error(L,"not a TreeItem!");
143 if (tree_item->expired) {
144 luaL_error(L,"expired TreeItem");
145 return 0;
148 if (! ( field = shiftProtoField(L,1) ) ) {
149 if (( proto = shiftProto(L,1) )) {
150 hfid = proto->hfid;
151 type = FT_PROTOCOL;
152 ett = proto->ett;
154 } else {
155 hfid = field->hfid;
156 type = field->type;
157 ett = field->ett;
160 tvbr = shiftTvbRange(L,1);
162 if (!tvbr) {
163 tvbr = ep_new(struct _wslua_tvbrange);
164 tvbr->tvb = ep_new(struct _wslua_tvb);
165 tvbr->tvb->ws_tvb = lua_tvb;
166 tvbr->offset = 0;
167 tvbr->len = 0;
170 if (hfid > 0 ) {
171 if (lua_gettop(L)) {
172 switch(type) {
173 case FT_PROTOCOL:
174 item = proto_tree_add_item(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,ENC_NA);
175 lua_pushnumber(L,0);
176 lua_insert(L,1);
177 break;
178 case FT_BOOLEAN:
179 item = proto_tree_add_boolean(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(guint32)luaL_checknumber(L,1));
180 break;
181 case FT_UINT8:
182 case FT_UINT16:
183 case FT_UINT24:
184 case FT_UINT32:
185 case FT_FRAMENUM:
186 item = proto_tree_add_uint(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(guint32)luaL_checknumber(L,1));
187 break;
188 case FT_INT8:
189 case FT_INT16:
190 case FT_INT24:
191 case FT_INT32:
192 item = proto_tree_add_int(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(gint32)luaL_checknumber(L,1));
193 break;
194 case FT_FLOAT:
195 item = proto_tree_add_float(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(float)luaL_checknumber(L,1));
196 break;
197 case FT_DOUBLE:
198 item = proto_tree_add_double(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(double)luaL_checknumber(L,1));
199 break;
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));
203 break;
204 case FT_STRING:
205 item = proto_tree_add_string(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,luaL_checkstring(L,1));
206 break;
207 case FT_STRINGZ:
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));
209 break;
210 case FT_BYTES:
211 item = proto_tree_add_bytes(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len, (const guint8*) luaL_checkstring(L,1));
212 break;
213 case FT_UINT64:
214 item = proto_tree_add_uint64(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,*(UInt64)checkUInt64(L,1));
215 break;
216 case FT_INT64:
217 item = proto_tree_add_int64(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,*(Int64)checkInt64(L,1));
218 break;
219 case FT_IPv4:
220 item = proto_tree_add_ipv4(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,*((guint32*)(checkAddress(L,1)->data)));
221 break;
222 case FT_ETHER:
223 case FT_UINT_BYTES:
224 case FT_IPv6:
225 case FT_IPXNET:
226 case FT_GUID:
227 case FT_OID:
228 case FT_REL_OID:
229 default:
230 luaL_error(L,"FT_ not yet supported");
231 return 0;
234 lua_remove(L,1);
236 } else {
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);
244 lua_remove(L,1);
247 } else {
248 if (lua_gettop(L)) {
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);
251 lua_remove(L,1);
255 while(lua_gettop(L)) {
256 const gchar* s = lua_tostring(L,1);
257 if (s) proto_item_append_text(item, " %s", s);
258 lua_remove(L,1);
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);
268 return 1;
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);
294 const gchar* s;
296 if (ti) {
297 if (ti->expired) {
298 luaL_error(L,"expired TreeItem");
299 return 0;
302 s = luaL_checkstring(L,WSLUA_ARG_TreeItem_set_text_TEXT);
303 proto_item_set_text(ti->item,"%s",s);
306 return 0;
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);
313 const gchar* s;
315 if (ti) {
316 if (ti->expired) {
317 luaL_error(L,"expired TreeItem");
318 return 0;
321 s = luaL_checkstring(L,WSLUA_ARG_TreeItem_append_text_TEXT);
322 proto_item_append_text(ti->item,"%s",s);
324 return 0;
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);
331 const gchar* s;
333 if (ti) {
334 if (ti->expired) {
335 luaL_error(L,"expired TreeItem");
336 return 0;
339 s = luaL_checkstring(L,WSLUA_ARG_TreeItem_prepend_text_TEXT);
340 proto_item_prepend_text(ti->item,"%s",s);
342 return 0;
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 ) {
356 if (ti->expired) {
357 luaL_error(L,"expired TreeItem");
358 return 0;
360 expert_add_info_format_internal(lua_pinfo, ti->item, group, severity, "%s", str);
363 return 0;
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);
369 if (ti) {
370 if (ti->expired) {
371 luaL_error(L,"expired TreeItem");
372 return 0;
374 PROTO_ITEM_SET_GENERATED(ti->item);
376 return 0;
380 WSLUA_METHOD TreeItem_set_hidden(lua_State *L) {
381 /* Should not be used */
382 TreeItem ti = checkTreeItem(L,1);
383 if (ti) {
384 if (ti->expired) {
385 luaL_error(L,"expired TreeItem");
386 return 0;
388 PROTO_ITEM_SET_HIDDEN(ti->item);
390 return 0;
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);
397 gint len;
399 if (ti) {
400 if (ti->expired) {
401 luaL_error(L,"expired TreeItem");
402 return 0;
405 len = luaL_checkint(L,WSLUA_ARG_TreeItem_set_len_LEN);
406 proto_item_set_len(ti->item, len);
409 return 0;
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);
415 if (!ti) return 0;
416 if (!ti->expired)
417 ti->expired = TRUE;
418 else
419 g_free(ti);
420 return 0;
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},
434 { NULL, NULL }
437 static const luaL_Reg TreeItem_meta[] = {
438 { NULL, NULL }
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);
446 return 1;