diff --git a/doc/src/api/lua_c/interface/interface_dump.lua b/doc/src/api/lua_c/interface/interface_dump.lua index 0466bbd970..2877f95471 100644 --- a/doc/src/api/lua_c/interface/interface_dump.lua +++ b/doc/src/api/lua_c/interface/interface_dump.lua @@ -40,3 +40,7 @@ function interface.getInterfacePacketsDumpedTap() --! @param cli_ip host/host@vlan to restrict capture only to the selected host. If nil, all interface traffic will be captured --! @return Success, or nil in case of failure. function interface.liveCapture(string host) + +--! @brief Dump active live captures for the specified web user +--! @return table containing live captures for the specified user +function interface.dumpLiveCaptures() diff --git a/include/NetworkInterface.h b/include/NetworkInterface.h index ad2e63259c..41fcf91dac 100644 --- a/include/NetworkInterface.h +++ b/include/NetworkInterface.h @@ -90,7 +90,7 @@ class NetworkInterface : public Checkpointable { struct ntopngLuaContext *live_captures[MAX_NUM_PCAP_CAPTURES]; static bool matchLiveCapture(struct ntopngLuaContext * const luactx, Flow * const f); void deliverLiveCapture(const struct pcap_pkthdr * const h, const u_char * const packet, Flow * const f); - + string ip_addresses; int id; bool bridge_interface, is_dynamic_interface; @@ -517,7 +517,7 @@ class NetworkInterface : public Checkpointable { PacketDumperTuntap *getPacketDumperTap(void) { return pkt_dumper_tap; } bool registerLiveCapture(struct ntopngLuaContext * const luactx); bool deregisterLiveCapture(struct ntopngLuaContext * const luactx); - + void dumpLiveCaptures(lua_State* vm); #ifdef NTOPNG_PRO #ifdef HAVE_NEDGE void updateHostsL7Policy(u_int16_t host_pool_id); diff --git a/include/ntop_typedefs.h b/include/ntop_typedefs.h index 0eb6b3e14b..2f664e4674 100644 --- a/include/ntop_typedefs.h +++ b/include/ntop_typedefs.h @@ -460,6 +460,7 @@ struct ntopngLuaContext { struct { u_int32_t capture_until, capture_max_pkts, num_captured_packets; void *matching_host; + char username[32]; /* Status */ bool pcaphdr_sent; diff --git a/scripts/lua/index.lua b/scripts/lua/index.lua index 738b8d29cb..5ee5d0a982 100644 --- a/scripts/lua/index.lua +++ b/scripts/lua/index.lua @@ -45,7 +45,6 @@ ifstats = interface.getStats() is_loopback = isLoopback(ifname) iface_id = interface.name2id(ifname) - -- Load from or set in redis the refresh frequency for the top flow sankey refresh = _GET["refresh"] diff --git a/src/LuaEngine.cpp b/src/LuaEngine.cpp index 2349cde52e..67651fa0a2 100644 --- a/src/LuaEngine.cpp +++ b/src/LuaEngine.cpp @@ -3628,6 +3628,32 @@ static int ntop_interface_set_idle(lua_State* vm) { /* ****************************************** */ +// ***API*** +static int ntop_interface_dump_live_captures(lua_State* vm) { + NetworkInterface *ntop_interface = getCurrentInterface(vm); + struct ntopngLuaContext *c; + NetworkInterface *iface = getCurrentInterface(vm); + + ntop->getTrace()->traceEvent(TRACE_DEBUG, "%s() called", __FUNCTION__); + + if(!Utils::isUserAdministrator(vm)) return(CONST_LUA_ERROR); + +#ifdef DONT_USE_LUAJIT + lua_getglobal(vm, "userdata"); + c = (struct ntopngLuaContext*)lua_touserdata(vm, lua_gettop(vm)); +#else + c = (struct ntopngLuaContext*)(G(vm)->userdata); +#endif + + if((!ntop_interface) || (!c)) + return(CONST_LUA_ERROR); + + iface->dumpLiveCaptures(vm); + return(CONST_LUA_OK); +} + +/* ****************************************** */ + // ***API*** static int ntop_interface_live_capture(lua_State* vm) { NetworkInterface *ntop_interface = getCurrentInterface(vm); @@ -3662,10 +3688,15 @@ static int ntop_interface_live_capture(lua_State* vm) { } c->live_capture.capture_until = time(NULL)+60; /* 1 min max */ - c->live_capture.num_captured_packets = 100000; /* No more than 100k packets */ + c->live_capture.capture_max_pkts = 100000; /* No more than 100k packets */ + c->live_capture.num_captured_packets = 0; c->live_capture.done = c->live_capture.pcaphdr_sent = false; - + snprintf(c->live_capture.username, sizeof(c->live_capture.username), "%s", c->user); ntop_interface->registerLiveCapture(c); + + ntop->getTrace()->traceEvent(TRACE_NORMAL, + "Starting live capture for user %s", + c->live_capture.username); while(!c->live_capture.done) { ntop->getTrace()->traceEvent(TRACE_INFO, "Capturing...."); @@ -7621,6 +7652,7 @@ static const luaL_Reg ntop_interface_reg[] = { /* Live Capture */ { "liveCapture", ntop_interface_live_capture }, + { "dumpLiveCaptures", ntop_interface_dump_live_captures }, /* Packet Capture */ { "captureToPcap", ntop_capture_to_pcap }, diff --git a/src/NetworkInterface.cpp b/src/NetworkInterface.cpp index d8962a4857..45985bc047 100644 --- a/src/NetworkInterface.cpp +++ b/src/NetworkInterface.cpp @@ -6644,3 +6644,49 @@ void NetworkInterface::deliverLiveCapture(const struct pcap_pkthdr * const h, } } } + +/* *************************************** */ + +void NetworkInterface::dumpLiveCaptures(lua_State* vm) { + struct ntopngLuaContext *c; + +#ifdef DONT_USE_LUAJIT + lua_getglobal(vm, "userdata"); + c = (struct ntopngLuaContext*)lua_touserdata(vm, lua_gettop(vm)); +#else + c = (struct ntopngLuaContext*)(G(vm)->userdata); +#endif + + active_captures_lock.lock(__FILE__, __LINE__); + + lua_newtable(vm); + + for(int i=0, capture_id=0; ilive_capture.username, c->user))) { + lua_newtable(vm); + + lua_push_int_table_entry(vm, "capture_until", + live_captures[i]->live_capture.capture_until); + lua_push_int_table_entry(vm, "capture_max_pkts", + live_captures[i]->live_capture.capture_max_pkts); + lua_push_int_table_entry(vm, "num_captured_packets", + live_captures[i]->live_capture.num_captured_packets); + + if(live_captures[i]->live_capture.matching_host != NULL) { + Host *h = (Host*)live_captures[i]->live_capture.matching_host; + char buf[64]; + + lua_push_str_table_entry(vm, "host", + h->get_ip()->print(buf, sizeof(buf))); + } + + lua_pushnumber(vm, ++capture_id); + lua_insert(vm, -2); + lua_settable(vm, -3); + } + } + + + active_captures_lock.unlock(__FILE__, __LINE__); +}