/* * * (C) 2013-21 - ntop.org * * * 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 3 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 "ntop_includes.h" /* ****************************************** */ static Flow* ntop_flow_get_context_flow(lua_State* vm) { struct ntopngLuaContext *c = getLuaVMContext(vm); return c->flow; } /* ****************************************** */ static int ntop_flow_get_status(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->getStatusBitmap().get()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_set_status(lua_State* vm) { FlowStatus new_status; u_int16_t flow_score, cli_score, srv_score; Flow *f = ntop_flow_get_context_flow(vm); char *script_key; ScriptCategory script_category = script_category_other; if(!f) return(CONST_LUA_ERROR); if(ntop_lua_check(vm, __FUNCTION__, 1, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); new_status = (FlowStatus)lua_tonumber(vm, 1); if(ntop_lua_check(vm, __FUNCTION__, 2, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); flow_score = (u_int16_t)lua_tonumber(vm, 2); if(ntop_lua_check(vm, __FUNCTION__, 3, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); cli_score = (u_int16_t)lua_tonumber(vm, 3); if(ntop_lua_check(vm, __FUNCTION__, 4, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); srv_score = (u_int16_t)lua_tonumber(vm, 4); if(ntop_lua_check(vm, __FUNCTION__, 5, LUA_TSTRING) != CONST_LUA_OK) return(CONST_LUA_ERROR); script_key = (char*)lua_tostring(vm, 5); if(ntop_lua_check(vm, __FUNCTION__, 6, LUA_TNUMBER) == CONST_LUA_OK && (ScriptCategory)lua_tointeger(vm, 6) < MAX_NUM_SCRIPT_CATEGORIES) script_category = (ScriptCategory)lua_tointeger(vm, 6); lua_pushboolean(vm, f->setStatus(new_status, flow_score, cli_score, srv_score, script_key, script_category)); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_status_set(lua_State* vm) { FlowStatus status; Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); if(ntop_lua_check(vm, __FUNCTION__, 1, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); status = (FlowStatus)lua_tonumber(vm, 1); lua_pushboolean(vm, f->getStatusBitmap().issetBit(status)); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_client_unicast(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, (f->get_cli_ip_addr() && !f->get_cli_ip_addr()->isBroadMulticastAddress())); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_server_unicast(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, (f->get_srv_ip_addr() && !f->get_srv_ip_addr()->isBroadMulticastAddress())); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_client_noip(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, (f->get_cli_ip_addr() && f->get_cli_ip_addr()->isEmpty())); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_server_noip(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, (f->get_srv_ip_addr() && f->get_srv_ip_addr()->isEmpty())); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_unicast(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); const IpAddress *cli_ip, *srv_ip; if(!f) return(CONST_LUA_ERROR); cli_ip = f->get_cli_ip_addr(); srv_ip = f->get_srv_ip_addr(); lua_pushboolean(vm, (cli_ip && srv_ip && !cli_ip->isBroadMulticastAddress() && !srv_ip->isBroadMulticastAddress())); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_remote_to_remote(lua_State* vm) { Host *cli_host, *srv_host; Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); cli_host = f->get_cli_host(); srv_host = f->get_srv_host(); lua_pushboolean(vm, (cli_host && srv_host && !cli_host->isLocalHost() && !srv_host->isLocalHost())); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_local_to_remote(lua_State* vm) { Host *cli_host, *srv_host; Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); cli_host = f->get_cli_host(); srv_host = f->get_srv_host(); lua_pushboolean(vm, (cli_host && srv_host && cli_host->isLocalHost() && !srv_host->isLocalHost())); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_remote_to_local(lua_State* vm) { Host *cli_host, *srv_host; Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); cli_host = f->get_cli_host(); srv_host = f->get_srv_host(); lua_pushboolean(vm, (cli_host && srv_host && !cli_host->isLocalHost() && srv_host->isLocalHost())); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_protocol(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_protocol()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_ndpi_cat_name(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushstring(vm, f->get_protocol_category_name()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_ndpi_protocol_name(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); char buf[64]; if(!f) return(CONST_LUA_ERROR); lua_pushstring(vm, f->get_detected_protocol_name(buf, sizeof(buf))); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_ndpi_category_id(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_protocol_category()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_ndpi_master_proto_id(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_detected_protocol().master_protocol); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_ndpi_app_proto_id(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_detected_protocol().app_protocol); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_cli_tcp_issues(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->getCliTcpIssues()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_srv_tcp_issues(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->getSrvTcpIssues()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_cli_retr_percentage(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushnumber(vm, (lua_Number)f->getCliRetrPercentage()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_srv_retr_percentage(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushnumber(vm, (lua_Number)f->getSrvRetrPercentage()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_retrieve_external_alert_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); f->luaRetrieveExternalAlert(vm); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); f->lua_get_min_info(vm); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_full_info(lua_State* vm) { AddressTree *ptree = get_allowed_nets(vm); Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); f->lua(vm, ptree, details_high, false); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_trigger_zero_window_alert(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); bool as_client, as_server; if(!f) return(CONST_LUA_ERROR); f->triggerZeroWindowAlert(&as_client, &as_server); lua_newtable(vm); lua_push_bool_table_entry(vm, "client", as_client); lua_push_bool_table_entry(vm, "server", as_server); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_unicast_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); f->lua_get_unicast_info(vm); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_key(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->key()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_hash_entry_id(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_hash_entry_id()); return(CONST_LUA_OK); } /* ****************************************** */ /* Get ICMP information that is specific for the serialization of ICMP data * into the flow status_info */ static int ntop_flow_get_icmp_status_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); if(f->isICMP()) { u_int8_t icmp_type, icmp_code; f->getICMP(&icmp_type, &icmp_code); lua_newtable(vm); lua_push_int32_table_entry(vm, "type", icmp_type); lua_push_int32_table_entry(vm, "code", icmp_code); } else lua_pushnil(vm); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_alerted_status_score(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->getAlertedStatusScore()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_local(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); bool is_local = false; if(!f) return(CONST_LUA_ERROR); if(f->get_cli_host() && f->get_srv_host()) is_local = f->get_cli_host()->isLocalHost() && f->get_srv_host()->isLocalHost(); lua_pushboolean(vm, is_local); return(CONST_LUA_OK); } /* ****************************************** */ #ifdef NTOPNG_PRO static int ntop_flow_get_score(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->getScore()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_score_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); const char *status_info; if(!f) return(CONST_LUA_ERROR); status_info = f->getStatusInfo(); lua_newtable(vm); lua_push_uint64_table_entry(vm, "status_map", f->getStatusBitmap().get()); lua_push_int32_table_entry(vm, "score", f->getScore()); if(status_info) lua_push_str_table_entry(vm, "status_info", status_info); return(CONST_LUA_OK); } #endif /* ****************************************** */ static int ntop_flow_is_not_purged(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, f->isNotPurged()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_tls_version(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->getTLSVersion()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_tcp_stats(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); f->lua_get_tcp_stats(vm); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_blacklisted_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_newtable(vm); if(f->isBlacklistedClient()) lua_push_bool_table_entry(vm, "blacklisted.cli", true); if(f->isBlacklistedServer()) lua_push_bool_table_entry(vm, "blacklisted.srv", true); if(f->get_protocol_category() == CUSTOM_CATEGORY_MALWARE) lua_push_bool_table_entry(vm, "blacklisted.cat", true); return(CONST_LUA_OK); } /* ****************************************** */ #ifdef HAVE_NEDGE static int ntop_flow_is_pass_verdict(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, f->isPassVerdict()); return(CONST_LUA_OK); } #endif /* ****************************************** */ static int ntop_flow_get_first_seen(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_first_seen()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_last_seen(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_last_seen()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_duration(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_duration()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_twh_ok(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, f->isThreeWayHandshakeOK()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_bidirectional(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, f->isBidirectional()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_packets_sent(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_packets_cli2srv()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_packets_rcvd(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_packets_srv2cli()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_packets(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_packets_cli2srv() + f->get_packets_srv2cli()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_bytes_sent(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_bytes_cli2srv()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_bytes_rcvd(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_bytes_srv2cli()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_bytes(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->get_bytes()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_goodput_ratio(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushnumber(vm, (float)(100*f->get_goodput_bytes()) / (float)f->get_bytes()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_ip(lua_State* vm, bool client) { Flow *f = ntop_flow_get_context_flow(vm); char buf[64]; if(!f) return(CONST_LUA_ERROR); if(client) lua_pushstring(vm, f->get_cli_ip_addr()->print(buf, sizeof(buf))); else lua_pushstring(vm, f->get_srv_ip_addr()->print(buf, sizeof(buf))); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_client_ip(lua_State* vm) { return ntop_flow_get_ip(vm, true /* Client */); } /* ****************************************** */ static int ntop_flow_get_server_ip(lua_State* vm) { return ntop_flow_get_ip(vm, false /* Server */); } /* ****************************************** */ static int ntop_flow_get_port(lua_State* vm, bool client) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); if(client) lua_pushinteger(vm, f->get_cli_port()); else lua_pushinteger(vm, f->get_srv_port()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_client_port(lua_State* vm) { return ntop_flow_get_port(vm, true /* Client */); } /* ****************************************** */ static int ntop_flow_get_server_port(lua_State* vm) { return ntop_flow_get_port(vm, false /* Server */); } /* ****************************************** */ static int ntop_flow_get_key(lua_State* vm, bool client) { Flow *f = ntop_flow_get_context_flow(vm); Host *h; char buf[64]; if(!f) return(CONST_LUA_ERROR); h = client ? f->get_cli_host() : f->get_srv_host(); lua_pushstring(vm, h ? h->get_hostkey(buf, sizeof(buf), true /* force VLAN, required by flow.lua */) : ""); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_client_key(lua_State* vm) { return ntop_flow_get_key(vm, true /* Client */); } /* ****************************************** */ static int ntop_flow_get_server_key(lua_State* vm) { return ntop_flow_get_key(vm, false /* Server */); } /* ****************************************** */ static int ntop_flow_get_proto_client_ip(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); Host *c, *s; char buf[64]; if(!f) return(CONST_LUA_ERROR); c = f->get_cli_host(), s = f->get_srv_host(); if(c && s) { if(c->isProtocolServer()) lua_pushstring(vm, s->get_string_key(buf, sizeof(buf))); else lua_pushstring(vm, c->get_string_key(buf, sizeof(buf))); } else lua_pushstring(vm, c ? c->get_string_key(buf, sizeof(buf)) : ""); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_proto_server_ip(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); Host *c, *s; char buf[64]; if(!f) return(CONST_LUA_ERROR); c = f->get_cli_host(), s = f->get_srv_host(); if(c && s) { if(c->isProtocolServer()) lua_pushstring(vm, c->get_string_key(buf, sizeof(buf))); else lua_pushstring(vm, s->get_string_key(buf, sizeof(buf))); } else lua_pushstring(vm, s ? c->get_string_key(buf, sizeof(buf)) : ""); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_dp_not_allowed(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, !f->isDeviceAllowedProtocol()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_tcp_connection_refused(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, (f->isTCPRefused())); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_tcp_connecting(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, (f->isTCPConnecting())); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_ssl_cipher_class(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); const char *rv; if(!f) return(CONST_LUA_ERROR); rv = f->getServerCipherClass(); if(rv) lua_pushstring(vm, rv); else lua_pushnil(vm); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_icmp_type(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->getICMPType()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_max_seen_icmp_size(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->getICMPPayloadSize()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_dns_query_invalid_chars(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, f->hasInvalidDNSQueryChars()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_dns_query(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushstring(vm, f->getDNSQuery()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_proto_breed(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushstring(vm, f->get_protocol_breed_name()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_has_malicious_tls_signature(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, f->hasMaliciousSignature()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_client_country(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); if(!f->get_cli_host() || !f->get_cli_host()->getCountryStats()) lua_pushnil(vm); else lua_pushstring(vm, f->get_cli_host()->getCountryStats()->get_country_name()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_server_country(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); if(!f->get_srv_host() || !f->get_srv_host()->getCountryStats()) lua_pushnil(vm); else lua_pushstring(vm, f->get_srv_host()->getCountryStats()->get_country_name()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_mac(lua_State* vm, bool client) { Flow *f = ntop_flow_get_context_flow(vm); lua_newtable(vm); if(f) f->lua_get_mac(vm, client); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_client_mac(lua_State* vm) { return ntop_flow_get_mac(vm, true /* Client */); }; /* ****************************************** */ static int ntop_flow_get_server_mac(lua_State* vm) { return ntop_flow_get_mac(vm, false /* Server */); }; /* ****************************************** */ static int ntop_flow_get_device_proto_allowed_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); f->lua_device_protocol_allowed_info(vm); return(CONST_LUA_OK); } /* ****************************************** */ static const char* mud_pref_2_str(MudRecording mud_pref) { switch(mud_pref) { case mud_recording_general_purpose: return(MUD_RECORDING_GENERAL_PURPOSE); case mud_recording_special_purpose: return(MUD_RECORDING_SPECIAL_PURPOSE); case mud_recording_disabled: return(MUD_RECORDING_DISABLED); default: return(MUD_RECORDING_DEFAULT); } } static int ntop_flow_get_mud_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); Host *cli_host, *srv_host; char buf[32]; if(!f) return(CONST_LUA_ERROR); lua_newtable(vm); cli_host = f->get_cli_host(); srv_host = f->get_srv_host(); if(!cli_host || !srv_host) return(CONST_LUA_OK); lua_push_str_table_entry(vm, "host_server_name", f->getFlowServerInfo()); lua_push_str_table_entry(vm, "protos.dns.last_query", f->getDNSQuery()); lua_push_bool_table_entry(vm, "is_local", cli_host->isLocalHost() && srv_host->isLocalHost()); lua_push_str_table_entry(vm, "cli.mud_recording", mud_pref_2_str(cli_host->getMUDRecording())); lua_push_str_table_entry(vm, "srv.mud_recording", mud_pref_2_str(srv_host->getMUDRecording())); lua_push_bool_table_entry(vm, "cli.serialize_by_mac", cli_host->serializeByMac()); lua_push_bool_table_entry(vm, "srv.serialize_by_mac", srv_host->serializeByMac()); lua_push_str_table_entry(vm, "cli.mac", Utils::formatMac(cli_host->get_mac(), buf, sizeof(buf))); lua_push_str_table_entry(vm, "srv.mac", Utils::formatMac(srv_host->get_mac(), buf, sizeof(buf))); lua_push_int32_table_entry(vm, "cli.devtype", cli_host->getDeviceType()); lua_push_int32_table_entry(vm, "srv.devtype", srv_host->getDeviceType()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_alerted_status(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushinteger(vm, f->getAlertedStatus()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_trigger_alert(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); FlowStatus status; AlertType atype; AlertLevel severity; u_int16_t alerted_status_score; bool triggered = false; const char *status_info = NULL; u_int32_t buflen; time_t now; bool first_alert; bool status_always_notify; if(!f) return(CONST_LUA_ERROR); first_alert = !f->isFlowAlerted(); if(ntop_lua_check(vm, __FUNCTION__, 1, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); status = (FlowStatus)lua_tonumber(vm, 1); if(ntop_lua_check(vm, __FUNCTION__, 2, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); atype = (AlertType)lua_tonumber(vm, 2); if(ntop_lua_check(vm, __FUNCTION__, 3, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); severity = (AlertLevel)lua_tointeger(vm, 3); if(ntop_lua_check(vm, __FUNCTION__, 4, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); alerted_status_score = lua_tointeger(vm, 4); if(ntop_lua_check(vm, __FUNCTION__, 5, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); now = (time_t) lua_tonumber(vm, 5); if(ntop_lua_check(vm, __FUNCTION__, 6, LUA_TBOOLEAN) != CONST_LUA_OK) return(CONST_LUA_ERROR); status_always_notify = lua_toboolean(vm, 6); if(lua_type(vm, 7) == LUA_TSTRING) status_info = lua_tostring(vm, 7); lua_newtable(vm); if(f->triggerAlert(status, atype, severity, alerted_status_score, status_info)) { /* The alert was successfully triggered */ triggered = true; ndpi_serializer flow_json; const char *flow_str; ndpi_init_serializer(&flow_json, ndpi_serialization_format_json); /* Only proceed if there is some space in the queues */ f->flow2alertJson(&flow_json, now); if(!first_alert) ndpi_serialize_string_boolean(&flow_json, "replace_alert", true); if(status_always_notify) ndpi_serialize_string_boolean(&flow_json, "status_always_notify", true); flow_str = ndpi_serializer_get_buffer(&flow_json, &buflen); if(flow_str) lua_push_str_table_entry(vm, "alert_json", flow_str); ndpi_term_serializer(&flow_json); } lua_push_bool_table_entry(vm, "triggered", triggered); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_is_blacklisted(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(!f) return(CONST_LUA_ERROR); lua_pushboolean(vm, f->isBlacklistedFlow()); return(CONST_LUA_OK); } /* ****************************************** */ static int ntop_flow_get_dir_iat(lua_State* vm, bool cli2srv) { Flow *f = ntop_flow_get_context_flow(vm); lua_newtable(vm); if(f) f->lua_get_dir_iat(vm, cli2srv); return CONST_LUA_OK; } /* ****************************************** */ static int ntop_flow_get_cli2srv_iat(lua_State* vm) { return ntop_flow_get_dir_iat(vm, true /* Client to Server */); } /* ****************************************** */ static int ntop_flow_get_srv2cli_iat(lua_State* vm) { return ntop_flow_get_dir_iat(vm, false /* Server to Client */); } /* ****************************************** */ static int ntop_flow_get_tls_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); lua_newtable(vm); if(f) f->lua_get_tls_info(vm); return CONST_LUA_OK; } /* ****************************************** */ static int ntop_flow_get_ssh_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); lua_newtable(vm); if(f) f->lua_get_ssh_info(vm); return CONST_LUA_OK; } /* ****************************************** */ static int ntop_flow_get_http_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); lua_newtable(vm); if(f) f->lua_get_http_info(vm); return CONST_LUA_OK; } /* ****************************************** */ static int ntop_flow_get_dns_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); lua_newtable(vm); if(f) f->lua_get_dns_info(vm); return CONST_LUA_OK; } /* ****************************************** */ static int ntop_flow_risk_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); lua_newtable(vm); if(f) f->lua_get_risk_info(vm, false); return CONST_LUA_OK; } /* ****************************************** */ static int ntop_flow_get_risk_bitmap(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(f) lua_pushinteger(vm, f->getRiskBitmap()); return CONST_LUA_OK; } /* ****************************************** */ static int ntop_flow_has_risk(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(f) { if(lua_type(vm, 1) == LUA_TNUMBER) lua_pushboolean(vm, f->hasRisk((ndpi_risk_enum)lua_tointeger(vm, 1))); else /* If there's no risk parameter specified, return true if a flow has any risk */ lua_pushboolean(vm, f->hasRisks()); } else lua_pushboolean(vm, false); return CONST_LUA_OK; } /* ****************************************** */ static int ntop_get_flow_info_field(lua_State* vm) { char buf[256]; Flow *f = ntop_flow_get_context_flow(vm); lua_pushstring(vm, f ? f->getFlowInfo(buf, sizeof(buf)) : ""); return CONST_LUA_OK; } /* ****************************************** */ static int ntop_flow_set_custom_info(lua_State* vm) { Flow *f = ntop_flow_get_context_flow(vm); if(f && ntop_lua_check(vm, __FUNCTION__, 1, LUA_TSTRING) == CONST_LUA_OK) { f->setCustomFlowInfo((char*)lua_tostring(vm, 1)); lua_pushboolean(vm, true); } else lua_pushboolean(vm, false); return CONST_LUA_OK; } /* ****************************************** */ void lua_push_rawdata_table_entry(lua_State *L, const char *key, u_int32_t len, u_int8_t *payload) { if(L) { lua_pushstring(L, key); lua_pushlstring(L, (const char*)payload, (size_t)len); lua_settable(L, -3); } } /* **************************************************************** */ static luaL_Reg _ntop_flow_reg[] = { /* Public User Scripts API, documented at doc/src/api/lua_c/flow_user_scripts/flow.lua */ { "getStatus", ntop_flow_get_status }, { "setStatus", ntop_flow_set_status }, { "isStatusSet", ntop_flow_is_status_set }, { "getAlertedStatus", ntop_flow_get_alerted_status }, { "isClientUnicast", ntop_flow_is_client_unicast }, { "isServerUnicast", ntop_flow_is_server_unicast }, { "isClientNoIP", ntop_flow_is_client_noip }, { "isServerNoIP", ntop_flow_is_server_noip }, { "isUnicast", ntop_flow_is_unicast }, { "isRemoteToRemote", ntop_flow_is_remote_to_remote }, { "isLocalToRemote", ntop_flow_is_local_to_remote }, { "isRemoteToLocal", ntop_flow_is_remote_to_local }, { "isLocal", ntop_flow_is_local }, { "isBlacklisted", ntop_flow_is_blacklisted }, { "isTwhOK", ntop_flow_is_twh_ok }, { "isBidirectional", ntop_flow_is_bidirectional }, { "getFullInfo", ntop_flow_get_full_info }, { "isTcpZeroWinAlert", ntop_flow_trigger_zero_window_alert }, { "getKey", ntop_flow_get_key }, { "getFirstSeen", ntop_flow_get_first_seen }, { "getLastSeen", ntop_flow_get_last_seen }, { "getDuration", ntop_flow_get_duration }, { "getPacketsSent", ntop_flow_get_packets_sent }, { "getPacketsRcvd", ntop_flow_get_packets_rcvd }, { "getPackets", ntop_flow_get_packets }, { "getBytesSent", ntop_flow_get_bytes_sent }, { "getBytesRcvd", ntop_flow_get_bytes_rcvd }, { "getBytes", ntop_flow_get_bytes }, { "getGoodputRatio", ntop_flow_get_goodput_ratio }, { "getClientIp", ntop_flow_get_client_ip }, { "getServerIp", ntop_flow_get_server_ip }, { "getClientPort", ntop_flow_get_client_port }, { "getServerPort", ntop_flow_get_server_port }, { "getClientKey", ntop_flow_get_client_key }, { "getServerKey", ntop_flow_get_server_key }, { "getFlowProtoClientIP", ntop_flow_get_proto_client_ip }, { "getFlowProtoServerIP", ntop_flow_get_proto_server_ip }, { "getProtocol", ntop_flow_get_protocol }, { "getnDPICategoryName", ntop_flow_get_ndpi_cat_name }, { "getnDPIProtocolName", ntop_flow_get_ndpi_protocol_name }, { "getnDPICategoryId", ntop_flow_get_ndpi_category_id }, { "getnDPIMasterProtoId", ntop_flow_get_ndpi_master_proto_id }, { "getnDPIAppProtoId", ntop_flow_get_ndpi_app_proto_id }, { "getDnsQuery", ntop_flow_get_dns_query }, { "getClientCountry", ntop_flow_get_client_country }, { "getServerCountry", ntop_flow_get_server_country }, { "getClientMac", ntop_flow_get_client_mac }, { "getServerMac", ntop_flow_get_server_mac }, { "getTLSVersion", ntop_flow_get_tls_version }, #ifdef NTOPNG_PRO { "getScore", ntop_flow_get_score }, #endif #ifdef HAVE_NEDGE { "isPassVerdict", ntop_flow_is_pass_verdict }, #endif /* END Public API */ { "getInfo", ntop_flow_get_info }, { "getUnicastInfo", ntop_flow_get_unicast_info }, { "triggerAlert", ntop_flow_trigger_alert }, { "getHashEntryId", ntop_flow_get_hash_entry_id }, { "getICMPStatusInfo", ntop_flow_get_icmp_status_info }, { "getAlertedStatusScore", ntop_flow_get_alerted_status_score }, { "getClientTCPIssues", ntop_flow_get_cli_tcp_issues }, { "getServerTCPIssues", ntop_flow_get_srv_tcp_issues }, { "getClientRetrPercentage", ntop_flow_get_cli_retr_percentage }, { "getServerRetrPercentage", ntop_flow_get_srv_retr_percentage }, { "isDeviceProtocolNotAllowed", ntop_flow_is_dp_not_allowed }, { "isTCPConnectionRefused", ntop_flow_is_tcp_connection_refused }, { "isTCPConnecting", ntop_flow_is_tcp_connecting }, { "getServerCipherClass", ntop_flow_get_ssl_cipher_class }, { "getICMPType", ntop_flow_get_icmp_type }, { "getMaxSeenIcmpPayloadSize", ntop_flow_get_max_seen_icmp_size }, { "dnsQueryHasInvalidChars", ntop_flow_dns_query_invalid_chars }, { "getProtoBreed", ntop_flow_get_proto_breed }, { "hasMaliciousTlsSignature", ntop_flow_has_malicious_tls_signature }, { "getMUDInfo", ntop_flow_get_mud_info }, { "isNotPurged", ntop_flow_is_not_purged }, { "getTCPStats", ntop_flow_get_tcp_stats }, { "getBlacklistedInfo", ntop_flow_get_blacklisted_info }, #ifdef NTOPNG_PRO { "getScoreInfo", ntop_flow_get_score_info }, #endif { "retrieveExternalAlertInfo", ntop_flow_retrieve_external_alert_info }, { "getDeviceProtoAllowedInfo", ntop_flow_get_device_proto_allowed_info}, { "getClient2ServerIAT", ntop_flow_get_cli2srv_iat }, { "getServer2ClientIAT", ntop_flow_get_srv2cli_iat }, { "getTLSInfo", ntop_flow_get_tls_info }, { "getSSHInfo", ntop_flow_get_ssh_info }, { "getHTTPInfo", ntop_flow_get_http_info }, { "getDNSInfo", ntop_flow_get_dns_info }, { "getRiskInfo", ntop_flow_risk_info }, { "getRiskBitmap", ntop_flow_get_risk_bitmap }, { "hasRisk", ntop_flow_has_risk }, { "getFlowInfoField", ntop_get_flow_info_field }, { "setCustomInfo", ntop_flow_set_custom_info }, { NULL, NULL } }; luaL_Reg *ntop_flow_reg = _ntop_flow_reg;