forked from osmocom/wireshark
- pass the tvb too to tap packet callbacks
- Dumper (an interface to Wiretap dumpers) svn path=/trunk/; revision=17328
This commit is contained in:
parent
79053183c5
commit
bafca77aad
|
@ -34,6 +34,7 @@ lua_la_SOURCES = \
|
|||
lua_pinfo.c \
|
||||
lua_tap.c \
|
||||
lua_gui.c \
|
||||
lua_dumper.c \
|
||||
packet-lua.c \
|
||||
packet-lua.h \
|
||||
plugin.c
|
||||
|
|
|
@ -23,6 +23,7 @@ OBJECTS= \
|
|||
lua_pinfo.obj \
|
||||
lua_tap.obj \
|
||||
lua_gui.obj \
|
||||
lua_dumper.obj \
|
||||
packet-lua.obj \
|
||||
plugin.obj
|
||||
|
||||
|
|
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
* lua_dumper.c
|
||||
*
|
||||
* Ethereal's interface to the Lua Programming Language
|
||||
*
|
||||
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
*
|
||||
* $Id: lua_tvb.c 17307 2006-02-15 02:10:07Z lego $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "packet-lua.h"
|
||||
#include <math.h>
|
||||
|
||||
LUA_CLASS_DEFINE(Dumper,DUMPER,NOP)
|
||||
LUA_CLASS_DEFINE(PseudoHeader,PSEUDOHEADER,NOP)
|
||||
|
||||
enum lua_pseudoheader_type {
|
||||
PHDR_NONE,
|
||||
PHDR_ETH,
|
||||
PHDR_X25,
|
||||
PHDR_ISDN,
|
||||
PHDR_ATM,
|
||||
PHDR_ASCEND,
|
||||
PHDR_P2P,
|
||||
PHDR_WIFI,
|
||||
PHDR_COSINE,
|
||||
PHDR_IRDA,
|
||||
PHDR_NETTL,
|
||||
PHDR_MTP2,
|
||||
PHDR_K12
|
||||
};
|
||||
|
||||
struct lua_pseudo_header {
|
||||
enum lua_pseudoheader_type type;
|
||||
union wtap_pseudo_header* wph;
|
||||
};
|
||||
|
||||
static int PseudoHeader_none(lua_State* L) {
|
||||
PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
|
||||
ph->type = PHDR_NONE;
|
||||
ph->wph = NULL;
|
||||
|
||||
pushPseudoHeader(L,ph);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int PseudoHeader_eth(lua_State* L) {
|
||||
PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
|
||||
ph->type = PHDR_ETH;
|
||||
ph->wph = g_malloc(sizeof(union wtap_pseudo_header));
|
||||
ph->wph->eth.fcs_len = luaL_optint(L,1,-1);
|
||||
|
||||
pushPseudoHeader(L,ph);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int PseudoHeader_atm(lua_State* L) {
|
||||
PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
|
||||
ph->type = PHDR_ATM;
|
||||
ph->wph = g_malloc(sizeof(union wtap_pseudo_header));
|
||||
ph->wph->atm.aal = luaL_optint(L,1,5);
|
||||
ph->wph->atm.vpi = luaL_optint(L,2,1);
|
||||
ph->wph->atm.vci = luaL_optint(L,3,1);
|
||||
ph->wph->atm.channel = luaL_optint(L,4,0);
|
||||
ph->wph->atm.cells = luaL_optint(L,5,1);
|
||||
ph->wph->atm.aal5t_u2u = luaL_optint(L,6,1);
|
||||
ph->wph->atm.aal5t_len = luaL_optint(L,7,0);
|
||||
|
||||
pushPseudoHeader(L,ph);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int PseudoHeader_mtp2(lua_State* L) {
|
||||
PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
|
||||
ph->type = PHDR_MTP2;
|
||||
ph->wph = g_malloc(sizeof(union wtap_pseudo_header));
|
||||
ph->wph->mtp2.sent = luaL_optint(L,1,0);
|
||||
ph->wph->mtp2.annex_a_used = luaL_optint(L,2,0);
|
||||
ph->wph->mtp2.link_number = luaL_optint(L,3,0);
|
||||
|
||||
pushPseudoHeader(L,ph);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int PseudoHeader_x25(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_isdn(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_ascend(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_wifi(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_cosine(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_irda(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_nettl(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_k12(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
#endif
|
||||
|
||||
static luaL_reg PseudoHeader_meta[] = {
|
||||
{0,0}
|
||||
};
|
||||
|
||||
int PseudoHeader_register(lua_State* L) {
|
||||
luaL_newmetatable(L, PSEUDOHEADER);
|
||||
luaL_openlib(L, NULL, PseudoHeader_meta, 0);
|
||||
|
||||
lua_pushstring(L, "PH_MTP2");
|
||||
lua_pushcfunction(L, PseudoHeader_mtp2);
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
|
||||
lua_pushstring(L, "PH_ATM");
|
||||
lua_pushcfunction(L, PseudoHeader_atm);
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
|
||||
lua_pushstring(L, "PH_ETH");
|
||||
lua_pushcfunction(L, PseudoHeader_eth);
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
|
||||
lua_pushstring(L, "PH_NONE");
|
||||
lua_pushcfunction(L, PseudoHeader_none);
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static GHashTable* dumper_encaps = NULL;
|
||||
#define DUMPER_ENCAP(d) GPOINTER_TO_INT(g_hash_table_lookup(dumper_encaps,d))
|
||||
|
||||
static int Dumper_new(lua_State* L) {
|
||||
Dumper d;
|
||||
const char* filename = luaL_checkstring(L,1);
|
||||
int filetype = luaL_optint(L,2,WTAP_FILE_PCAP);
|
||||
int encap = luaL_optint(L,3,WTAP_ENCAP_ETHERNET);
|
||||
int err = 0;
|
||||
|
||||
if (! filename) return 0;
|
||||
|
||||
if (!wtap_dump_can_write_encap(filetype, encap)) {
|
||||
luaL_error(L,"Cannot write encap %s in filetype %s",
|
||||
wtap_encap_short_string(encap),
|
||||
wtap_file_type_string(filetype));
|
||||
return 0;
|
||||
}
|
||||
|
||||
d = wtap_dump_open(filename, filetype, encap,0 , FALSE, &err);
|
||||
|
||||
if (! d ) {
|
||||
luaL_error(L,"error while opening `%s': %s",
|
||||
filename,
|
||||
wtap_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_hash_table_insert(dumper_encaps,d,GINT_TO_POINTER(encap));
|
||||
|
||||
pushDumper(L,d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Dumper_close(lua_State* L) {
|
||||
Dumper d = checkDumper(L,1);
|
||||
int err;
|
||||
|
||||
if (!d) return 0;
|
||||
|
||||
g_hash_table_remove(dumper_encaps,d);
|
||||
|
||||
if (!wtap_dump_close(d, &err)) {
|
||||
luaL_error(L,"error closing: %s",
|
||||
wtap_strerror(err));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int Dumper_flush(lua_State* L) {
|
||||
Dumper d = checkDumper(L,1);
|
||||
|
||||
if (!d) return 0;
|
||||
|
||||
wtap_dump_flush(d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Dumper_dump(lua_State* L) {
|
||||
Dumper d = checkDumper(L,1);
|
||||
PseudoHeader ph;
|
||||
ByteArray ba;
|
||||
struct wtap_pkthdr pkthdr;
|
||||
double ts;
|
||||
int err;
|
||||
|
||||
if (!d) return 0;
|
||||
|
||||
ts = luaL_checknumber(L,2);
|
||||
ph = checkPseudoHeader(L,3);
|
||||
|
||||
if (!ph) {
|
||||
luaL_error(L,"Cannot do without a Pseudo Header");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ba = checkByteArray(L,4);
|
||||
|
||||
if (! ba) {
|
||||
luaL_error(L,"No data to dump!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkthdr.ts.secs = floor(ts);
|
||||
pkthdr.ts.nsecs = floor(ts - pkthdr.ts.secs) * 1000000000;
|
||||
pkthdr.len = ba->len;
|
||||
pkthdr.caplen = ba->len;
|
||||
pkthdr.pkt_encap = DUMPER_ENCAP(d);
|
||||
|
||||
if (! wtap_dump(d, &pkthdr, ph->wph, ba->data, &err)) {
|
||||
luaL_error(L,"error while dumping: %s",
|
||||
wtap_strerror(err));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int Dumper_new_for_current(lua_State* L) {
|
||||
Dumper d = checkDumper(L,1);
|
||||
const char* filename = luaL_checkstring(L,1);
|
||||
int filetype = luaL_optint(L,2,WTAP_FILE_PCAP);
|
||||
int encap;
|
||||
int err = 0;
|
||||
|
||||
if (!d) return 0;
|
||||
|
||||
if (! lua_pinfo ) {
|
||||
luaL_error(L,"Dumper.new_for_current cannot be used outside a tap or a dissector");
|
||||
return 0;
|
||||
}
|
||||
|
||||
encap = lua_pinfo->fd->lnk_t;
|
||||
|
||||
if (!wtap_dump_can_write_encap(filetype, encap)) {
|
||||
luaL_error(L,"Cannot write encap %s in filetype %s",
|
||||
wtap_encap_short_string(encap),
|
||||
wtap_file_type_string(filetype));
|
||||
return 0;
|
||||
}
|
||||
|
||||
d = wtap_dump_open(filename, filetype, encap, 0 , FALSE, &err);
|
||||
|
||||
if (! d ) {
|
||||
luaL_error(L,"error while opening `%s': %s",
|
||||
filename,
|
||||
wtap_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
|
||||
pushDumper(L,d);
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
static int Dumper_dump_current(lua_State* L) {
|
||||
Dumper d = checkDumper(L,1);
|
||||
struct wtap_pkthdr pkthdr;
|
||||
const guchar* data;
|
||||
tvbuff_t* data_src;
|
||||
int err = 0;
|
||||
|
||||
if (!d) return 0;
|
||||
|
||||
if (! lua_pinfo ) {
|
||||
luaL_error(L,"dump_current cannot be used outside a tap or a dissector");
|
||||
return 0;
|
||||
}
|
||||
|
||||
data_src = ((data_source*)(lua_pinfo->data_src->data))->tvb;
|
||||
|
||||
pkthdr.ts.secs = lua_pinfo->fd->abs_ts.secs;
|
||||
pkthdr.ts.nsecs = lua_pinfo->fd->abs_ts.nsecs;
|
||||
pkthdr.len = tvb_reported_length(data_src);
|
||||
pkthdr.caplen = tvb_length(data_src);
|
||||
pkthdr.pkt_encap = lua_pinfo->fd->lnk_t;
|
||||
|
||||
data = ep_tvb_memdup(data_src,0,pkthdr.caplen);
|
||||
|
||||
if (! wtap_dump(d, &pkthdr, lua_pinfo->pseudo_header, data, &err)) {
|
||||
luaL_error(L,"error while dumping: %s",
|
||||
wtap_strerror(err));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_reg Dumper_methods[] =
|
||||
{
|
||||
{"new", Dumper_new},
|
||||
{"new_for_current", Dumper_new_for_current},
|
||||
{"close", Dumper_close},
|
||||
{"flush", Dumper_flush},
|
||||
{"dump", Dumper_dump},
|
||||
{"dump_current", Dumper_dump_current},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static const luaL_reg Dumper_meta[] =
|
||||
{
|
||||
{"__index", Dumper_new},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
int Dumper_register(lua_State* L) {
|
||||
|
||||
dumper_encaps = g_hash_table_new(g_direct_hash,g_direct_equal);
|
||||
|
||||
luaL_openlib(L, DUMPER, Dumper_methods, 0);
|
||||
luaL_newmetatable(L, DUMPER);
|
||||
luaL_openlib(L, 0, Dumper_meta, 0);
|
||||
lua_pushliteral(L, "__index");
|
||||
lua_pushvalue(L, -3);
|
||||
lua_rawset(L, -3);
|
||||
lua_pushliteral(L, "__metatable");
|
||||
lua_pushvalue(L, -3);
|
||||
lua_rawset(L, -3);
|
||||
lua_pop(L, 1);
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -238,7 +238,7 @@ int tap_packet_cb_error_handler(lua_State* L) {
|
|||
}
|
||||
|
||||
|
||||
int lua_tap_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_ , const void *data _U_) {
|
||||
int lua_tap_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *data _U_) {
|
||||
Tap tap = tapdata;
|
||||
int retval = 0;
|
||||
|
||||
|
@ -250,10 +250,11 @@ int lua_tap_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_ ,
|
|||
lua_rawgeti(tap->L, LUA_REGISTRYINDEX, tap->packet_ref);
|
||||
|
||||
push_Pinfo(tap->L, pinfo);
|
||||
push_Tvb(tap->L, edt->tvb);
|
||||
|
||||
lua_rawgeti(tap->L, LUA_REGISTRYINDEX, tap->data_ref);
|
||||
|
||||
switch ( lua_pcall(tap->L,2,1,1) ) {
|
||||
switch ( lua_pcall(tap->L,3,1,1) ) {
|
||||
case 0:
|
||||
|
||||
if (lua_gettop(tap->L) == 1)
|
||||
|
|
|
@ -336,6 +336,9 @@ void register_lua(void) {
|
|||
Tap_register(L);
|
||||
Address_register(L);
|
||||
TextWindow_register(L);
|
||||
PseudoHeader_register(L);
|
||||
Dumper_register(L);
|
||||
|
||||
|
||||
/* print has been changed to yield an error if used */
|
||||
lua_pushstring(L, "print");
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include <wiretap/wtap.h>
|
||||
#include <epan/packet.h>
|
||||
#include <epan/strutil.h>
|
||||
#include <epan/prefs.h>
|
||||
|
@ -163,6 +164,12 @@ typedef struct _eth_tap* Tap;
|
|||
#define TEXT_WINDOW "TextWindow"
|
||||
typedef funnel_text_window_t* TextWindow;
|
||||
|
||||
#define DUMPER "Dumper"
|
||||
typedef wtap_dumper* Dumper;
|
||||
|
||||
#define PSEUDOHEADER "PseudoHeader"
|
||||
typedef struct lua_pseudo_header* PseudoHeader;
|
||||
|
||||
#define NOP
|
||||
|
||||
/*
|
||||
|
@ -240,6 +247,8 @@ LUA_CLASS_DECLARE(Dissector,DISSECTOR);
|
|||
LUA_CLASS_DECLARE(DissectorTable,DISSECTOR_TABLE);
|
||||
LUA_CLASS_DECLARE(Address,ADDRESS);
|
||||
LUA_CLASS_DECLARE(TextWindow,TEXT_WINDOW);
|
||||
LUA_CLASS_DECLARE(Dumper,DUMPER);
|
||||
LUA_CLASS_DECLARE(PseudoHeader,PSEUDOHEADER)
|
||||
|
||||
extern void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree);
|
||||
extern int lua_tap_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *data _U_);
|
||||
|
|
Loading…
Reference in New Issue