static tap_packet_status lua_tap_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *data) { Listener tap = (Listener)tapdata; tap_packet_status retval = TAP_PACKET_DONT_REDRAW; TreeItem lua_tree_tap; if (tap->packet_ref == LUA_NOREF) return TAP_PACKET_DONT_REDRAW; /* XXX - report error and return TAP_PACKET_FAILED? */ lua_settop(tap->L,0); lua_pushcfunction(tap->L,tap_packet_cb_error_handler); lua_rawgeti(tap->L, LUA_REGISTRYINDEX, tap->packet_ref); push_Pinfo(tap->L, pinfo); push_Tvb(tap->L, edt->tvb); if (tap->extractor) { tap->extractor(tap->L,data); } else { lua_pushnil(tap->L); } lua_pinfo = pinfo; lua_tvb = edt->tvb; lua_tree_tap = create_TreeItem(edt->tree, NULL); lua_tree = lua_tree_tap; switch ( lua_pcall(tap->L,3,1,1) ) { case 0: /* XXX - treat 2 as TAP_PACKET_FAILED? */ retval = luaL_optinteger(tap->L,-1,1) == 0 ? TAP_PACKET_DONT_REDRAW : TAP_PACKET_REDRAW; break; case LUA_ERRRUN: /* XXX - TAP_PACKET_FAILED? */ break; case LUA_ERRMEM: g_warning("Memory alloc error while calling listener tap callback packet"); /* XXX - TAP_PACKET_FAILED? */ break; default: g_assert_not_reached(); break; } clear_outstanding_Pinfo(); clear_outstanding_Tvb(); lua_pinfo = NULL; lua_tvb = NULL; lua_tree = NULL; g_free(lua_tree_tap); return retval; }
static int lua_tap_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *data) { Listener tap = (Listener)tapdata; int retval = 0; if (tap->packet_ref == LUA_NOREF) return 0; lua_settop(tap->L,0); lua_pushcfunction(tap->L,tap_packet_cb_error_handler); lua_rawgeti(tap->L, LUA_REGISTRYINDEX, tap->packet_ref); push_Pinfo(tap->L, pinfo); push_Tvb(tap->L, edt->tvb); if (tap->extractor) { tap->extractor(tap->L,data); } else { lua_pushnil(tap->L); } lua_pinfo = pinfo; lua_tvb = edt->tvb; lua_tree = (struct _wslua_treeitem *)g_malloc(sizeof(struct _wslua_treeitem)); lua_tree->tree = edt->tree; lua_tree->item = NULL; lua_tree->expired = FALSE; switch ( lua_pcall(tap->L,3,1,1) ) { case 0: retval = luaL_optint(tap->L,-1,1); break; case LUA_ERRRUN: break; case LUA_ERRMEM: g_warning("Memory alloc error while calling listener tap callback packet"); break; default: g_assert_not_reached(); break; } clear_outstanding_Pinfo(); clear_outstanding_Tvb(); lua_pinfo = NULL; lua_tvb = NULL; lua_tree = NULL; return retval; }
int dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) { int consumed_bytes = tvb->length; lua_pinfo = pinfo; lua_tvb = tvb; lua_tree = g_malloc(sizeof(struct _wslua_treeitem)); lua_tree->tree = tree; lua_tree->item = proto_tree_add_text(tree,tvb,0,0,"lua fake item"); lua_tree->expired = FALSE; PROTO_ITEM_SET_HIDDEN(lua_tree->item); /* * almost equivalent to Lua: * dissectors[current_proto](tvb,pinfo,tree) */ lua_settop(L,0); lua_rawgeti(L, LUA_REGISTRYINDEX, lua_dissectors_table_ref); lua_pushstring(L, pinfo->current_proto); lua_gettable(L, -2); lua_remove(L,1); if (lua_isfunction(L,1)) { push_Tvb(L,tvb); push_Pinfo(L,pinfo); push_TreeItem(L,lua_tree); if ( lua_pcall(L,3,1,0) ) { const gchar* error = lua_tostring(L,-1); proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua Error: %s",error); expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_ERROR ,"Lua Error"); } else { /* if the Lua dissector reported the consumed bytes, pass it to our caller */ if (lua_isnumber(L, -1)) { /* we got the consumed bytes or the missing bytes as a negative number */ consumed_bytes = (int) lua_tonumber(L, -1); lua_pop(L, 1); } } } else { proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua Error: did not find the %s dissector" " in the dissectors table",pinfo->current_proto); expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_ERROR ,"Lua Error"); } register_frame_end_routine(lua_frame_end); lua_pinfo = NULL; lua_tree = NULL; lua_tvb = NULL; return consumed_bytes; }