int main(void) { lua_State* L = luaL_newstate(); luaL_openlibs(L); // 加载并执行lua脚本 luaL_dofile(L, "luascripts/main.lua"); // 调用lua的函数,接收两个int值的参数 lua_pushinteger(L, 12); lua_pushinteger(L, 88); call_lua_function(L, "lua_add", 2, 1); // 调用lua的函数,打印由c api创建的table lua_newtable(L); // [..., table] lua_pushstring(L, "k1"); // [..., table, k1] lua_pushstring(L, "v1"); // [..., table, k1, v1] lua_settable(L, -3); // [..., table] 等于于 table[k1] = v1 的操作 lua_pushstring(L, "k2"); // [..., table, k2] lua_pushstring(L, "v2"); // [..., table, k2, v2] lua_settable(L, -3); // [..., table] 等于于 table[k2] = v2 的操作 lua_pushstring(L, "k3"); // [..., table, k3] lua_pushstring(L, "v3"); // [..., table, k3, v3] lua_settable(L, -3); // [..., table] 等于于 table[k3] = v3 的操作 //lua_setglobal(L, "map"); // 把table弹出并在全局变量表中增加一个名为map的变量,该变量可在脚本中直接使用 call_lua_function(L, "lua_print_table", 1); lua_close(L); return 0; }
int mlua_fetch(lua_State* L) { assert(L); const char* key = luaL_checkstring(L, 1); char* value = storage_fetch(key); if (!value || !value[0]) { #ifndef EMSCRIPTEN free(value); #endif lua_pushnil(L); return 1; } lua_pushcfunction(L, json_decode); lua_pushstring(L, value); call_lua_function(L, 1, 1); #ifndef EMSCRIPTEN free(value); #endif // table is returned by json_decode return 1; }
int mlua_store(lua_State* L) { assert(L); const char* key = luaL_checkstring(L, 1); lua_pushcfunction(L, json_encode); lua_pushvalue(L, 2); call_lua_function(L, 1, 1); // table in param, returns json const char* value = luaL_checkstring(L, -1); storage_store(key, value); return 0; }
/** * Call a Lua function when an error occur. * This function is protected against infinite recursion. */ int luasoul_error(lua_State *L, const char *msg) { static int in = 0; /* already in the function */ if (in) return 0; in = 1; /* 'protected block' */ { /* TODO: file, line number and function http://stackoverflow.com/questions/2780500 http://stackoverflow.com/questions/2555856/current-line-number-in-lua http://www.lua.org/manual/5.1/manual.html#lua_getinfo */ call_lua_function(L, "luasoul_error", "s", msg); } in = 0; return 0; }
/// single argument version std::vector<flexible_type> lualambda_master::bulk_eval(size_t lambda_hash, const std::vector<flexible_type>& args, bool skip_undefined, int seed) { size_t worker_id = pop_worker(); std::vector<flexible_type> ret; std::string lambdaname = "lambda" + std::to_string(lambda_hash); auto function = (*clients[worker_id])[lambdaname.c_str()]; try { ret.resize(args.size()); for (size_t i = 0;i < args.size(); ++i) { if (skip_undefined && args[i].get_type() == flex_type_enum::UNDEFINED) { ret[i] = FLEX_UNDEFINED; } else { call_lua_function(function, args[i], ret[i]); } } } catch (...) { push_worker(worker_id); throw; } push_worker(worker_id); return ret; }
void process_netflow_packet_v5(u_int8_t* packet, u_int len, std::string client_addres_in_string_format) { // logger<< log4cpp::Priority::INFO<<"We get v5 netflow packet!"; struct NF5_HEADER* nf5_hdr = (struct NF5_HEADER*)packet; if (len < sizeof(*nf5_hdr)) { logger << log4cpp::Priority::ERROR << "Short netflow v5 packet " << len; return; } u_int nflows = ntohs(nf5_hdr->c.flows); if (nflows == 0 || nflows > NF5_MAXFLOWS) { logger << log4cpp::Priority::ERROR << "Invalid number of flows in netflow " << nflows; return; } uint16_t netflow5_sampling_ratio = fast_ntoh(nf5_hdr->sampling_rate); // In first two bits we store sampling type. // We are not interested in it and should zeroify it for getting correct value of sampling rate clear_bit_value(netflow5_sampling_ratio, 15); clear_bit_value(netflow5_sampling_ratio, 16); // Sampling not enabled on device if (netflow5_sampling_ratio == 0) { netflow5_sampling_ratio = 1; } for (u_int i = 0; i < nflows; i++) { size_t offset = NF5_PACKET_SIZE(i); struct NF5_FLOW* nf5_flow = (struct NF5_FLOW*)(packet + offset); /* Check packet bounds */ if (offset + sizeof(struct NF5_FLOW) > len) { logger << log4cpp::Priority::ERROR << "Error! You will try to read outside the packet"; } /* Decode to host encoding */ // TODO: move to separate function nf5_flow->flow_octets = fast_ntoh(nf5_flow->flow_octets); nf5_flow->flow_packets = fast_ntoh(nf5_flow->flow_packets); nf5_flow->if_index_in = fast_ntoh(nf5_flow->if_index_in); nf5_flow->if_index_out = fast_ntoh(nf5_flow->if_index_out); // convert netflow to simple packet form simple_packet current_packet; current_packet.src_ip = nf5_flow->src_ip; current_packet.dst_ip = nf5_flow->dest_ip; current_packet.ts.tv_sec = ntohl(nf5_hdr->time_sec); current_packet.ts.tv_usec = ntohl(nf5_hdr->time_nanosec); current_packet.flags = 0; current_packet.source_port = 0; current_packet.destination_port = 0; // TODO: we should pass data about "flow" structure of this data current_packet.length = nf5_flow->flow_octets; current_packet.number_of_packets = nf5_flow->flow_packets; if (netflow_divide_counters_on_interval_length) { // This interval in milliseconds, convert it to seconds int64_t interval_length = (fast_ntoh(nf5_flow->flow_finish) - fast_ntoh(nf5_flow->flow_start)) / 1000; /* if (interval_length > 0) { logger << log4cpp::Priority::INFO << "NetFlow v5 from: " << client_addres_in_string_format << " start: " << fast_ntoh(nf5_flow->flow_start) << " finish: " << fast_ntoh(nf5_flow->flow_finish) << " interval length:" << interval_length << "\n"; } */ if (interval_length == 0) { // it's OK } else if (interval_length < 0) { // it's internal error logger << log4cpp::Priority::ERROR << "We got negative interval length from netflow agent, something goes wrong!"; } else { // OK, let's divide // We will get integer result for this operation current_packet.length = current_packet.length / interval_length; current_packet.number_of_packets = current_packet.number_of_packets / interval_length; } } // TODO: use sampling data from packet, disable customization here // Wireshark dump approves this idea current_packet.sample_ratio = netflow5_sampling_ratio; current_packet.source_port = fast_ntoh(nf5_flow->src_port); current_packet.destination_port = fast_ntoh(nf5_flow->dest_port); // We do not support IPv6 in NetFlow v5 at all current_packet.ip_protocol_version = 4; switch (nf5_flow->protocol) { case 1: { // ICMP current_packet.protocol = IPPROTO_ICMP; } break; case 6: { // TCP current_packet.protocol = IPPROTO_TCP; // TODO: flags can be in another format! current_packet.flags = nf5_flow->tcp_flags; } break; case 17: { // UDP current_packet.protocol = IPPROTO_UDP; } break; } #ifdef ENABLE_LUA_HOOKS if (lua_hooks_enabled) { // This code could be used only for tests with pcap_reader //if (lua_state == NULL) { // init_lua_jit(); //} if (call_lua_function("process_netflow", netflow_lua_state, client_addres_in_string_format, (void*)nf5_flow)) { // We will process this packet } else { logger << log4cpp::Priority::INFO << "We will drop this packets because LUA script decided to do it"; return; } } #endif // Call processing function for every flow in packet netflow_process_func_ptr(current_packet); } }
char *storage_fetch(const char *key) { long filesize = 0; FILE *file = NULL; char *data = NULL; char *value; lua_State *L; assert(key); L = luaL_newstate(); if (!L) log_oom_and_exit(); file = fopen(".storage", "r"); if (!file) { goto fail; } fseek(file, 0L, SEEK_END); filesize = ftell(file); if (filesize < 0) { goto fail; } fseek(file, 0L, SEEK_SET); data = mmap(0, filesize, PROT_READ, MAP_PRIVATE, fileno(file), 0); if (data == MAP_FAILED) { goto fail; } // decode the data from the file to a lua table lua_pushcfunction(L, json_decode); lua_pushstring(L, data); call_lua_function(L, 1, 1); // get the value associated with the key lua_pushstring(L, key); lua_gettable(L, 1); if (lua_isnil(L, -1)) { lua_pop(L, 2); goto fail; } value = xstrdup(luaL_checkstring(L, -1)); // pop the table and the string lua_pop(L, 2); assert(lua_gettop(L) == 0); munmap(data, filesize); fclose(file); lua_close(L); return value; fail: if (data) { munmap(data, filesize); } if (file) { fclose(file); } assert(lua_gettop(L) == 0); lua_close(L); return NULL; }
void storage_store(const char *key, const char *value) { long filesize; FILE *file = NULL; const char *stored_data; lua_State *L; assert(key); assert(value); L = luaL_newstate(); if (!L) log_oom_and_exit(); file = fopen(".storage", "r"); if (file) { fseek(file, 0L, SEEK_END); filesize = ftell(file); fseek(file, 0L, SEEK_SET); if (filesize > 0) { // If there is something in the file, we mmap it and decode it to create a table int r; char *data = mmap(0, filesize, PROT_READ, MAP_PRIVATE, fileno(file), 0); if (data == MAP_FAILED) { goto finish; } lua_pushcfunction(L, json_decode); lua_pushstring(L, data); call_lua_function(L, 1, 1); r = munmap(data, filesize); if (r < 0) { lua_pop(L, 1); goto finish; } } fclose(file); } else { lua_newtable(L); } file = fopen(".storage", "w"); if (!file) { goto finish; } // add the new element to the table lua_pushstring(L, value); lua_setfield(L, -2, key); // encode the table in json lua_pushcfunction(L, json_encode); lua_pushvalue(L, 1); call_lua_function(L, 1, 1); // store this in the file if (lua_isnil(L, -1)) { lua_pop(L, 2); goto finish; } stored_data = luaL_checkstring(L, -1); fputs(stored_data, file); // pop the table and the string lua_pop(L, 2); finish: if (file) { fclose(file); } assert(lua_gettop(L) == 0); lua_close(L); }