"Fossies" - the Fresh Open Source Software Archive

Member "sysdig-0.26.1/userspace/libsinsp/chisel_api.cpp" (24 May 2019, 34306 Bytes) of package /linux/misc/sysdig-0.26.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "chisel_api.cpp" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.25_vs_0.26.0.

    1 /*
    2 Copyright (C) 2013-2018 Draios Inc dba Sysdig.
    3 
    4 This file is part of sysdig.
    5 
    6 Licensed under the Apache License, Version 2.0 (the "License");
    7 you may not use this file except in compliance with the License.
    8 You may obtain a copy of the License at
    9 
   10     http://www.apache.org/licenses/LICENSE-2.0
   11 
   12 Unless required by applicable law or agreed to in writing, software
   13 distributed under the License is distributed on an "AS IS" BASIS,
   14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15 See the License for the specific language governing permissions and
   16 limitations under the License.
   17 
   18 */
   19 
   20 #include <iostream>
   21 #include <fstream>
   22 #include <cctype>
   23 #include <locale>
   24 #ifdef _WIN32
   25 #include <io.h>
   26 #else
   27 #include <limits.h>
   28 #include <stdlib.h>
   29 #include <unistd.h>
   30 #include <sys/ioctl.h>
   31 #endif
   32 #include <third-party/tinydir.h>
   33 #include <json/json.h>
   34 
   35 #include "sinsp.h"
   36 #include "sinsp_int.h"
   37 #include "chisel.h"
   38 #include "chisel_api.h"
   39 #include "filter.h"
   40 #include "filterchecks.h"
   41 #ifdef HAS_ANALYZER
   42 #include "analyzer.h"
   43 #endif
   44 
   45 #ifdef HAS_CHISELS
   46 #define HAS_LUA_CHISELS
   47 
   48 #ifdef HAS_LUA_CHISELS
   49 extern "C" {
   50 #include "lua.h"
   51 #include "lualib.h"
   52 #include "lauxlib.h"
   53 }
   54 #endif
   55 
   56 extern vector<chiseldir_info>* g_chisel_dirs;
   57 extern sinsp_filter_check_list g_filterlist;
   58 extern sinsp_evttables g_infotables;
   59 void lua_stackdump(lua_State *L);
   60 
   61 ///////////////////////////////////////////////////////////////////////////////
   62 // Lua callbacks
   63 ///////////////////////////////////////////////////////////////////////////////
   64 #ifdef HAS_LUA_CHISELS
   65 
   66 uint32_t lua_cbacks::rawval_to_lua_stack(lua_State *ls, uint8_t* rawval, ppm_param_type ptype, uint32_t len)
   67 {
   68     ASSERT(rawval != NULL);
   69 
   70     switch(ptype)
   71     {
   72         case PT_INT8:
   73             lua_pushnumber(ls, *(int8_t*)rawval);
   74             return 1;
   75         case PT_INT16:
   76             lua_pushnumber(ls, *(int16_t*)rawval);
   77             return 1;
   78         case PT_INT32:
   79             lua_pushnumber(ls, *(int32_t*)rawval);
   80             return 1;
   81         case PT_INT64:
   82         case PT_ERRNO:
   83         case PT_PID:
   84         case PT_FD:
   85             lua_pushnumber(ls, (double)*(int64_t*)rawval);
   86             return 1;
   87         case PT_L4PROTO: // This can be resolved in the future
   88         case PT_FLAGS8:
   89         case PT_UINT8:
   90             lua_pushnumber(ls, *(uint8_t*)rawval);
   91             return 1;
   92         case PT_PORT: // This can be resolved in the future
   93         case PT_FLAGS16:
   94         case PT_UINT16:
   95             lua_pushnumber(ls, *(uint16_t*)rawval);
   96             return 1;
   97         case PT_FLAGS32:
   98         case PT_UINT32:
   99         case PT_UID:
  100         case PT_GID:
  101             lua_pushnumber(ls, *(uint32_t*)rawval);
  102             return 1;
  103         case PT_UINT64:
  104         case PT_RELTIME:
  105         case PT_ABSTIME:
  106             lua_pushnumber(ls, (double)*(uint64_t*)rawval);
  107             return 1;
  108         case PT_DOUBLE:
  109             lua_pushnumber(ls, *(double*)rawval);
  110             return 1;
  111         case PT_CHARBUF:
  112         case PT_FSPATH:
  113             lua_pushlstring(ls, (char*)rawval, len);
  114             return 1;
  115         case PT_BYTEBUF:
  116             if(rawval[len] == 0)
  117             {
  118                 lua_pushlstring(ls, (char*)rawval, len);
  119                 return 1;
  120             }
  121             else
  122             {
  123                 lua_getglobal(ls, "sichisel");
  124                 sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  125                 lua_pop(ls, 1);
  126 
  127                 uint32_t max_len = len < sizeof(ch->m_lua_fld_storage) ?
  128                     len : sizeof(ch->m_lua_fld_storage) - 1;
  129 
  130                 memcpy(ch->m_lua_fld_storage, rawval, max_len);
  131                 ch->m_lua_fld_storage[max_len] = 0;
  132                 lua_pushlstring(ls, (char*)ch->m_lua_fld_storage, max_len);
  133                 return 1;
  134             }
  135         case PT_SOCKADDR:
  136             ASSERT(false);
  137             return 0;
  138         case PT_SOCKFAMILY:
  139             ASSERT(false);
  140             return 0;
  141         case PT_BOOL:
  142             lua_pushboolean(ls, (*(uint32_t*)rawval != 0));
  143             return 1;
  144         case PT_IPV4ADDR:
  145             {
  146                 lua_getglobal(ls, "sichisel");
  147                 sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  148                 lua_pop(ls, 1);
  149 
  150                 snprintf(ch->m_lua_fld_storage,
  151                             sizeof(ch->m_lua_fld_storage),
  152                             "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8,
  153                             rawval[0],
  154                             rawval[1],
  155                             rawval[2],
  156                             rawval[3]);
  157 
  158                 lua_pushstring(ls, ch->m_lua_fld_storage);
  159                 return 1;
  160             }
  161         case PT_IPV6ADDR:
  162             {
  163                 char address[100];
  164                 ipv6addr *ip = (ipv6addr *) rawval;
  165 
  166                 lua_getglobal(ls, "sichisel");
  167                 sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  168                 lua_pop(ls, 1);
  169 
  170                 if(NULL == inet_ntop(AF_INET6, ip->m_b, address, 100))
  171                 {
  172                     strcpy(address, "<NA>");
  173                 }
  174 
  175                 strncpy(ch->m_lua_fld_storage,
  176                     address,
  177                     sizeof(ch->m_lua_fld_storage));
  178 
  179                 lua_pushstring(ls, ch->m_lua_fld_storage);
  180                 return 1;
  181             }
  182                 case PT_IPADDR:
  183                 {
  184                 if(len == sizeof(struct in_addr))
  185                 {
  186                     return rawval_to_lua_stack(ls, rawval, PT_IPV4ADDR, len);
  187                 }
  188                 else if(len == sizeof(struct in6_addr))
  189                 {
  190                     return rawval_to_lua_stack(ls, rawval, PT_IPV6ADDR, len);
  191                 }
  192                 else
  193                 {
  194                     throw sinsp_exception("rawval_to_lua_stack called with IP address of incorrect size " + to_string(len));
  195                 }
  196             }
  197             break;
  198         default:
  199             ASSERT(false);
  200             string err = "wrong event type " + to_string((long long) ptype);
  201             fprintf(stderr, "%s\n", err.c_str());
  202             throw sinsp_exception("chisel error");
  203     }
  204 }
  205 
  206 int lua_cbacks::get_num(lua_State *ls)
  207 {
  208     lua_getglobal(ls, "sievt");
  209     sinsp_evt* evt = (sinsp_evt*)lua_touserdata(ls, -1);
  210     lua_pop(ls, 1);
  211 
  212     if(evt == NULL)
  213     {
  214         string err = "invalid call to evt.get_num()";
  215         fprintf(stderr, "%s\n", err.c_str());
  216         throw sinsp_exception("chisel error");
  217     }
  218 
  219     lua_pushnumber(ls, (double)evt->get_num());
  220     return 1;
  221 }
  222 
  223 int lua_cbacks::get_ts(lua_State *ls)
  224 {
  225     lua_getglobal(ls, "sievt");
  226     sinsp_evt* evt = (sinsp_evt*)lua_touserdata(ls, -1);
  227     lua_pop(ls, 1);
  228 
  229     if(evt == NULL)
  230     {
  231         string err = "invalid call to evt.get_ts()";
  232         fprintf(stderr, "%s\n", err.c_str());
  233         throw sinsp_exception("chisel error");
  234     }
  235 
  236     uint64_t ts = evt->get_ts();
  237 
  238     lua_pushinteger(ls, (uint32_t)(ts / 1000000000));
  239     lua_pushinteger(ls, (uint32_t)(ts % 1000000000));
  240     return 2;
  241 }
  242 
  243 int lua_cbacks::get_type(lua_State *ls)
  244 {
  245     lua_getglobal(ls, "sievt");
  246     sinsp_evt* evt = (sinsp_evt*)lua_touserdata(ls, -1);
  247     lua_pop(ls, 1);
  248 
  249     if(evt == NULL)
  250     {
  251         string err = "invalid call to evt.get_type()";
  252         fprintf(stderr, "%s\n", err.c_str());
  253         throw sinsp_exception("chisel error");
  254     }
  255 
  256     const char* evname;
  257     uint16_t etype = evt->get_type();
  258 
  259     if(etype == PPME_GENERIC_E || etype == PPME_GENERIC_X)
  260     {
  261         sinsp_evt_param *parinfo = evt->get_param(0);
  262         ASSERT(parinfo->m_len == sizeof(uint16_t));
  263         uint16_t evid = *(uint16_t *)parinfo->m_val;
  264 
  265         evname = g_infotables.m_syscall_info_table[evid].name;
  266     }
  267     else
  268     {
  269         evname = evt->get_name();
  270     }
  271 
  272     lua_pushstring(ls, evname);
  273 
  274     return 1;
  275 }
  276 
  277 int lua_cbacks::get_cpuid(lua_State *ls)
  278 {
  279     lua_getglobal(ls, "sievt");
  280     sinsp_evt* evt = (sinsp_evt*)lua_touserdata(ls, -1);
  281     lua_pop(ls, 1);
  282 
  283     if(evt == NULL)
  284     {
  285         string err = "invalid call to evt.get_cpuid()";
  286         fprintf(stderr, "%s\n", err.c_str());
  287         throw sinsp_exception("chisel error");
  288     }
  289 
  290     uint32_t cpuid = evt->get_cpuid();
  291 
  292     lua_pushinteger(ls, cpuid);
  293     return 1;
  294 }
  295 
  296 int lua_cbacks::request_field(lua_State *ls)
  297 {
  298     lua_getglobal(ls, "sichisel");
  299 
  300     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  301     lua_pop(ls, 1);
  302 
  303     sinsp* inspector = ch->m_inspector;
  304 
  305     const char* fld = lua_tostring(ls, 1);
  306 
  307     if(fld == NULL)
  308     {
  309         string err = "chisel requesting nil field";
  310         fprintf(stderr, "%s\n", err.c_str());
  311         throw sinsp_exception("chisel error");
  312     }
  313 
  314     sinsp_filter_check* chk = g_filterlist.new_filter_check_from_fldname(fld,
  315         inspector,
  316         false);
  317 
  318     if(chk == NULL)
  319     {
  320         string err = "chisel requesting nonexistent field " + string(fld);
  321         fprintf(stderr, "%s\n", err.c_str());
  322         throw sinsp_exception("chisel error");
  323     }
  324 
  325     chk->parse_field_name(fld, true, false);
  326 
  327     lua_pushlightuserdata(ls, chk);
  328 
  329     ch->m_allocated_fltchecks.push_back(chk);
  330 
  331     return 1;
  332 }
  333 
  334 int lua_cbacks::field(lua_State *ls)
  335 {
  336     lua_getglobal(ls, "sievt");
  337     sinsp_evt* evt = (sinsp_evt*)lua_touserdata(ls, -1);
  338     lua_pop(ls, 1);
  339 
  340     if(evt == NULL)
  341     {
  342         string err = "invalid call to evt.field()";
  343         fprintf(stderr, "%s\n", err.c_str());
  344         throw sinsp_exception("chisel error");
  345     }
  346 
  347     sinsp_filter_check* chk = (sinsp_filter_check*)lua_topointer(ls, 1);
  348     if(chk == NULL)
  349     {
  350         //
  351         // This happens if the lua code is calling field() without invoking
  352         // sysdig.request_field() before.
  353         //
  354         lua_pushnil(ls);
  355         return 1;
  356     }
  357 
  358     uint32_t vlen;
  359     uint8_t* rawval = chk->extract(evt, &vlen);
  360 
  361     if(rawval != NULL)
  362     {
  363         return rawval_to_lua_stack(ls, rawval, chk->get_field_info()->m_type, vlen);
  364     }
  365     else
  366     {
  367         lua_pushnil(ls);
  368         return 1;
  369     }
  370 }
  371 
  372 int lua_cbacks::set_global_filter(lua_State *ls)
  373 {
  374     lua_getglobal(ls, "sichisel");
  375 
  376     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  377     lua_pop(ls, 1);
  378 
  379     const char* filter = lua_tostring(ls, 1);
  380 
  381     ASSERT(ch);
  382     ASSERT(ch->m_lua_cinfo);
  383 
  384     try
  385     {
  386         ch->m_inspector->set_filter(filter);
  387     }
  388     catch(sinsp_exception& e)
  389     {
  390         string err = "invalid filter in chisel " + ch->m_filename + ": " + e.what();
  391         fprintf(stderr, "%s\n", err.c_str());
  392         throw sinsp_exception("chisel error");
  393     }
  394 
  395     return 0;
  396 }
  397 
  398 int lua_cbacks::set_filter(lua_State *ls)
  399 {
  400     lua_getglobal(ls, "sichisel");
  401 
  402     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  403     lua_pop(ls, 1);
  404 
  405     const char* filter = lua_tostring(ls, 1);
  406 
  407     ASSERT(ch);
  408     ASSERT(ch->m_lua_cinfo);
  409 
  410     try
  411     {
  412         ch->m_lua_cinfo->set_filter(filter);
  413     }
  414     catch(sinsp_exception& e)
  415     {
  416         string err = "invalid filter in chisel " + ch->m_filename + ": " + e.what();
  417         fprintf(stderr, "%s\n", err.c_str());
  418         throw sinsp_exception("chisel error");
  419     }
  420 
  421     return 0;
  422 }
  423 
  424 int lua_cbacks::set_snaplen(lua_State *ls)
  425 {
  426     lua_getglobal(ls, "sichisel");
  427 
  428     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  429     lua_pop(ls, 1);
  430 
  431     const uint32_t snaplen = (uint32_t)lua_tointeger(ls, 1);
  432 
  433     ASSERT(ch);
  434     ASSERT(ch->m_lua_cinfo);
  435 
  436     ch->m_inspector->set_snaplen(snaplen);
  437 
  438     return 0;
  439 }
  440 
  441 int lua_cbacks::set_output_format(lua_State *ls)
  442 {
  443     lua_getglobal(ls, "sichisel");
  444 
  445     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  446     lua_pop(ls, 1);
  447 
  448     ASSERT(ch);
  449     ASSERT(ch->m_lua_cinfo);
  450 
  451     if(ch->m_inspector->get_buffer_format() != sinsp_evt::PF_NORMAL)
  452     {
  453         //
  454         // This means that the user has forced the format on the command line.
  455         // We give that priority and we do nothing.
  456         //
  457         return 0;
  458     }
  459 
  460     const char* fmt = lua_tostring(ls, 1);
  461 
  462     if(string(fmt) == "normal")
  463     {
  464         ch->m_inspector->set_buffer_format(sinsp_evt::PF_NORMAL);
  465     }
  466     else if(string(fmt) == "json")
  467     {
  468         ch->m_inspector->set_buffer_format(sinsp_evt::PF_JSON);
  469     }
  470     else if(string(fmt) == "simple")
  471     {
  472         ch->m_inspector->set_buffer_format(sinsp_evt::PF_SIMPLE);
  473     }
  474     else if(string(fmt) == "hex")
  475     {
  476         ch->m_inspector->set_buffer_format(sinsp_evt::PF_HEX);
  477     }
  478     else if(string(fmt) == "hexascii")
  479     {
  480         ch->m_inspector->set_buffer_format(sinsp_evt::PF_HEXASCII);
  481     }
  482     else if(string(fmt) == "ascii")
  483     {
  484         ch->m_inspector->set_buffer_format(sinsp_evt::PF_EOLS);
  485     }
  486     else if(string(fmt) == "base64")
  487     {
  488         ch->m_inspector->set_buffer_format(sinsp_evt::PF_BASE64);
  489     }
  490     else if(string(fmt) == "jsonbase64")
  491     {
  492         ch->m_inspector->set_buffer_format(sinsp_evt::PF_JSONBASE64);
  493     }
  494     else
  495     {
  496         string err = "invalid set_output_format value in chisel " + ch->m_filename;
  497         fprintf(stderr, "%s\n", err.c_str());
  498         throw sinsp_exception("chisel error");
  499     }
  500 
  501     return 0;
  502 }
  503 
  504 int lua_cbacks::set_fatfile_dump_mode(lua_State *ls)
  505 {
  506     lua_getglobal(ls, "sichisel");
  507 
  508     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  509     lua_pop(ls, 1);
  510 
  511     int mode = lua_toboolean(ls, 1);
  512 
  513     ASSERT(ch);
  514     ASSERT(ch->m_lua_cinfo);
  515 
  516     ch->m_inspector->set_fatfile_dump_mode(mode != 0);
  517 
  518     return 0;
  519 }
  520 
  521 int lua_cbacks::make_ts(lua_State *ls)
  522 {
  523     lua_getglobal(ls, "sichisel");
  524 
  525     uint32_t op1 = (uint32_t)lua_tointeger(ls, 1);
  526     lua_pop(ls, 1);
  527     uint32_t op2 = (uint32_t)lua_tointeger(ls, 2);
  528     lua_pop(ls, 1);
  529 
  530     uint64_t sum = (uint64_t)op1 * ONE_SECOND_IN_NS + op2;
  531 
  532     lua_pushstring(ls, to_string((long long) sum).c_str());
  533     return 1;
  534 }
  535 
  536 int lua_cbacks::add_ts(lua_State *ls)
  537 {
  538     lua_getglobal(ls, "sichisel");
  539 
  540     uint64_t op1 = sinsp_numparser::parseu64(lua_tostring(ls, 1));
  541     lua_pop(ls, 1);
  542     uint64_t op2 = sinsp_numparser::parseu64(lua_tostring(ls, 2));
  543     lua_pop(ls, 1);
  544 
  545     uint64_t sum = (op1 + op2);
  546 
  547     lua_pushstring(ls, to_string((long long) sum).c_str());
  548     return 1;
  549 }
  550 
  551 int lua_cbacks::subtract_ts(lua_State *ls)
  552 {
  553     lua_getglobal(ls, "sichisel");
  554 
  555     uint64_t op1 = sinsp_numparser::parseu64(lua_tostring(ls, 1));
  556     lua_pop(ls, 1);
  557     uint64_t op2 = sinsp_numparser::parseu64(lua_tostring(ls, 2));
  558     lua_pop(ls, 1);
  559 
  560     uint64_t sum = (op1 - op2);
  561 
  562     lua_pushstring(ls, to_string((long long) sum).c_str());
  563     return 1;
  564 }
  565 
  566 int lua_cbacks::run_sysdig(lua_State *ls)
  567 {
  568     lua_getglobal(ls, "sichisel");
  569 
  570     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  571     lua_pop(ls, 1);
  572 
  573     const char* args = lua_tostring(ls, 1);
  574 
  575     ASSERT(ch);
  576     ASSERT(ch->m_lua_cinfo);
  577 
  578     ch->m_lua_cinfo->m_has_nextrun_args = true;
  579     ch->m_lua_cinfo->m_nextrun_args = args;
  580 
  581     return 0;
  582 }
  583 
  584 int lua_cbacks::end_capture(lua_State *ls)
  585 {
  586     lua_getglobal(ls, "sichisel");
  587 
  588     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  589     lua_pop(ls, 1);
  590 
  591     ASSERT(ch);
  592     ASSERT(ch->m_lua_cinfo);
  593 
  594     ch->m_lua_cinfo->m_end_capture = true;
  595 
  596     return 0;
  597 }
  598 
  599 int lua_cbacks::is_live(lua_State *ls)
  600 {
  601     lua_getglobal(ls, "sichisel");
  602 
  603     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  604     lua_pop(ls, 1);
  605 
  606     ASSERT(ch);
  607     ASSERT(ch->m_lua_cinfo);
  608 
  609     lua_pushboolean(ls, ch->m_inspector->is_live());
  610     return 1;
  611 }
  612 
  613 int lua_cbacks::is_tty(lua_State *ls)
  614 {
  615 #ifdef _WIN32
  616     int use_color = false;
  617 #else
  618     int use_color = isatty(1);
  619 #endif
  620 
  621     lua_pushboolean(ls, use_color);
  622     return 1;
  623 }
  624 
  625 int lua_cbacks::get_terminal_info(lua_State *ls)
  626 {
  627     int32_t width = -1;
  628     int32_t height = -1;
  629 #ifndef _WIN32
  630     struct winsize w;
  631 
  632     if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1)
  633     {
  634         width = w.ws_col;
  635         height = w.ws_row;
  636     }
  637 #endif
  638 
  639     lua_newtable(ls);
  640     lua_pushstring(ls, "width");
  641     lua_pushnumber(ls, width);
  642     lua_settable(ls, -3);
  643     lua_pushstring(ls, "height");
  644     lua_pushnumber(ls, height);
  645     lua_settable(ls, -3);
  646 
  647     return 1;
  648 }
  649 
  650 int lua_cbacks::get_filter(lua_State *ls)
  651 {
  652     lua_getglobal(ls, "sichisel");
  653 
  654     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  655     lua_pop(ls, 1);
  656 
  657     ASSERT(ch);
  658     ASSERT(ch->m_inspector);
  659 
  660     string flts = ch->m_inspector->get_filter();
  661 
  662     lua_pushstring(ls, flts.c_str());
  663 
  664     return 1;
  665 }
  666 
  667 int lua_cbacks::get_machine_info(lua_State *ls)
  668 {
  669     lua_getglobal(ls, "sichisel");
  670 
  671     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  672     lua_pop(ls, 1);
  673 
  674     ASSERT(ch);
  675     ASSERT(ch->m_lua_cinfo);
  676 
  677     const scap_machine_info* minfo = ch->m_inspector->get_machine_info();
  678 
  679     if(minfo == NULL)
  680     {
  681         string err = "get_machine_info can only be called from the on_capture_start callback";
  682         fprintf(stderr, "%s\n", err.c_str());
  683         throw sinsp_exception("chisel error");
  684     }
  685 
  686     lua_newtable(ls);
  687     lua_pushstring(ls, "num_cpus");
  688     lua_pushnumber(ls, minfo->num_cpus);
  689     lua_settable(ls, -3);
  690     lua_pushstring(ls, "memory_size_bytes");
  691     lua_pushnumber(ls, (double)minfo->memory_size_bytes);
  692     lua_settable(ls, -3);
  693     lua_pushstring(ls, "max_pid");
  694     lua_pushnumber(ls, (double)minfo->max_pid);
  695     lua_settable(ls, -3);
  696     lua_pushstring(ls, "hostname");
  697     lua_pushstring(ls, minfo->hostname);
  698     lua_settable(ls, -3);
  699 
  700     return 1;
  701 }
  702 
  703 int lua_cbacks::get_thread_table_int(lua_State *ls, bool include_fds, bool barebone)
  704 {
  705     unordered_map<int64_t, sinsp_fdinfo_t>::iterator fdit;
  706     uint32_t j;
  707     sinsp_filter_compiler* compiler = NULL;
  708     sinsp_filter* filter = NULL;
  709     sinsp_evt tevt;
  710     scap_evt tscapevt;
  711 
  712     //
  713     // Get the chisel state
  714     //
  715     lua_getglobal(ls, "sichisel");
  716 
  717     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
  718     lua_pop(ls, 1);
  719 
  720     ASSERT(ch);
  721     ASSERT(ch->m_lua_cinfo);
  722     ASSERT(ch->m_inspector);
  723 
  724     //
  725     // If the caller specified a filter, compile it
  726     //
  727     if(lua_isstring(ls, 1))
  728     {
  729         string filterstr = lua_tostring(ls, 1);
  730         lua_pop(ls, 1);
  731 
  732         if(filterstr != "")
  733         {
  734             try
  735             {
  736                 compiler = new sinsp_filter_compiler(ch->m_inspector, filterstr, true);
  737                 filter = compiler->compile();
  738             }
  739             catch(sinsp_exception& e)
  740             {
  741                 string err = "invalid filter argument for get_thread_table in chisel " + ch->m_filename + ": " + e.what();
  742                 fprintf(stderr, "%s\n", err.c_str());
  743                 throw sinsp_exception("chisel error");
  744             }
  745 
  746             tscapevt.ts = ch->m_inspector->m_lastevent_ts;
  747             tscapevt.type = PPME_SYSCALL_READ_X;
  748             tscapevt.len = 0;
  749             tscapevt.nparams = 0;
  750 
  751             tevt.m_inspector = ch->m_inspector;
  752             tevt.m_info = &(g_infotables.m_event_info[PPME_SYSCALL_READ_X]);
  753             tevt.m_pevt = NULL;
  754             tevt.m_cpuid = 0;
  755             tevt.m_evtnum = 0;
  756             tevt.m_pevt = &tscapevt;
  757         }
  758     }
  759 
  760     threadinfo_map_t* threadtable  = ch->m_inspector->m_thread_manager->get_threads();
  761 
  762     ASSERT(threadtable != NULL);
  763 
  764     lua_newtable(ls);
  765 
  766     threadtable->loop([&] (sinsp_threadinfo& tinfo) {
  767         //
  768         // Check if there's at least an fd that matches the filter.
  769         // If not, skip this thread
  770         //
  771         sinsp_fdtable* fdtable = tinfo.get_fd_table();
  772 
  773         if(filter != NULL)
  774         {
  775             bool match = false;
  776 
  777             for(fdit = fdtable->m_table.begin(); fdit != fdtable->m_table.end(); ++fdit)
  778             {
  779                 tevt.m_tinfo = &tinfo;
  780                 tevt.m_fdinfo = &(fdit->second);
  781                 tscapevt.tid = tinfo.m_tid;
  782                 int64_t tlefd = tevt.m_tinfo->m_lastevent_fd;
  783                 tevt.m_tinfo->m_lastevent_fd = fdit->first;
  784 
  785                 if(filter->run(&tevt))
  786                 {
  787                     match = true;
  788                     break;
  789                 }
  790 
  791                 tevt.m_tinfo->m_lastevent_fd = tlefd;
  792             }
  793 
  794             if(!match)
  795             {
  796                 return true;
  797             }
  798         }
  799 
  800         //
  801         // Set the thread properties
  802         //
  803         lua_newtable(ls);
  804         lua_pushliteral(ls, "tid");
  805         lua_pushnumber(ls, (uint32_t)tinfo.m_tid);
  806         lua_settable(ls, -3);
  807         lua_pushliteral(ls, "pid");
  808         lua_pushnumber(ls, (uint32_t)tinfo.m_pid);
  809         lua_settable(ls, -3);
  810         if(!barebone)
  811         {
  812             lua_pushliteral(ls, "ptid");
  813             lua_pushnumber(ls, (uint32_t)tinfo.m_ptid);
  814             lua_settable(ls, -3);
  815             lua_pushliteral(ls, "comm");
  816             lua_pushstring(ls, tinfo.m_comm.c_str());
  817             lua_settable(ls, -3);
  818             lua_pushliteral(ls, "exe");
  819             lua_pushstring(ls, tinfo.m_exe.c_str());
  820             lua_settable(ls, -3);
  821             lua_pushliteral(ls, "flags");
  822             lua_pushnumber(ls, (uint32_t)tinfo.m_flags);
  823             lua_settable(ls, -3);
  824             lua_pushliteral(ls, "fdlimit");
  825             lua_pushnumber(ls, (uint32_t)tinfo.m_fdlimit);
  826             lua_settable(ls, -3);
  827             lua_pushliteral(ls, "uid");
  828             lua_pushnumber(ls, (uint32_t)tinfo.m_uid);
  829             lua_settable(ls, -3);
  830             lua_pushliteral(ls, "gid");
  831             lua_pushnumber(ls, (uint32_t)tinfo.m_gid);
  832             lua_settable(ls, -3);
  833             lua_pushliteral(ls, "nchilds");
  834             lua_pushnumber(ls, (uint32_t)tinfo.m_nchilds);
  835             lua_settable(ls, -3);
  836             lua_pushliteral(ls, "vmsize_kb");
  837             lua_pushnumber(ls, (uint32_t)tinfo.m_vmsize_kb);
  838             lua_settable(ls, -3);
  839             lua_pushliteral(ls, "vmrss_kb");
  840             lua_pushnumber(ls, (uint32_t)tinfo.m_vmrss_kb);
  841             lua_settable(ls, -3);
  842             lua_pushliteral(ls, "vmswap_kb");
  843             lua_pushnumber(ls, (uint32_t)tinfo.m_vmswap_kb);
  844             lua_settable(ls, -3);
  845             lua_pushliteral(ls, "pfmajor");
  846             lua_pushnumber(ls, (uint32_t)tinfo.m_pfmajor);
  847             lua_settable(ls, -3);
  848             lua_pushliteral(ls, "pfminor");
  849             lua_pushnumber(ls, (uint32_t)tinfo.m_pfminor);
  850             lua_settable(ls, -3);
  851             lua_pushliteral(ls, "clone_ts");
  852             lua_pushstring(ls, to_string((long long int)tinfo.m_clone_ts).c_str());
  853             lua_settable(ls, -3);
  854 
  855             //
  856             // Extract the user name
  857             //
  858             string username;
  859             unordered_map<uint32_t, scap_userinfo*>::const_iterator uit;
  860 
  861             const unordered_map<uint32_t, scap_userinfo*>* userlist = ch->m_inspector->get_userlist();
  862             ASSERT(userlist->size() != 0);
  863 
  864             if(tinfo.m_uid == 0xffffffff)
  865             {
  866                 username = "<NA>";
  867             }
  868             else
  869             {
  870                 uit = userlist->find(tinfo.m_uid);
  871                 if(uit == userlist->end())
  872                 {
  873                     username = "<NA>";
  874                 }
  875                 else
  876                 {
  877                     ASSERT(uit->second != NULL);
  878                     username = uit->second->name;
  879                 }
  880             }
  881 
  882             lua_pushliteral(ls, "username");
  883             lua_pushstring(ls, username.c_str());
  884             lua_settable(ls, -3);
  885 
  886             //
  887             // Create the arguments sub-table
  888             //
  889             lua_pushstring(ls, "args");
  890 
  891             vector<string>* args = &tinfo.m_args;
  892             lua_newtable(ls);
  893             for(j = 0; j < args->size(); j++)
  894             {
  895                 lua_pushinteger(ls, j + 1);
  896                 lua_pushstring(ls, args->at(j).c_str());
  897                 lua_settable(ls, -3);
  898             }
  899             lua_settable(ls,-3);
  900 
  901             //
  902             // Create the environment variables sub-table
  903             //
  904             lua_pushstring(ls, "env");
  905 
  906             const auto& env = tinfo.get_env();
  907             lua_newtable(ls);
  908             for(j = 0; j < env.size(); j++)
  909             {
  910                 lua_pushinteger(ls, j + 1);
  911                 lua_pushstring(ls, env.at(j).c_str());
  912                 lua_settable(ls, -3);
  913             }
  914             lua_settable(ls,-3);
  915         }
  916 
  917         //
  918         // Create and populate the FD table
  919         //
  920         lua_pushstring(ls, "fdtable");
  921         lua_newtable(ls);
  922 
  923         if(include_fds)
  924         {
  925             for(fdit = fdtable->m_table.begin(); fdit != fdtable->m_table.end(); ++fdit)
  926             {
  927                 tevt.m_tinfo = &tinfo;
  928                 tevt.m_fdinfo = &(fdit->second);
  929                 tscapevt.tid = tinfo.m_tid;
  930                 int64_t tlefd = tevt.m_tinfo->m_lastevent_fd;
  931                 tevt.m_tinfo->m_lastevent_fd = fdit->first;
  932 
  933                 if(filter != NULL)
  934                 {
  935                     if(filter->run(&tevt) == false)
  936                     {
  937                         continue;
  938                     }
  939                 }
  940 
  941                 tevt.m_tinfo->m_lastevent_fd = tlefd;
  942 
  943                 lua_newtable(ls);
  944                 if(!barebone)
  945                 {
  946                     lua_pushliteral(ls, "name");
  947                     lua_pushstring(ls, fdit->second.tostring_clean().c_str());
  948                     lua_settable(ls, -3);
  949                     lua_pushliteral(ls, "type");
  950                     lua_pushstring(ls, fdit->second.get_typestring());
  951                     lua_settable(ls, -3);
  952                 }
  953 
  954                 scap_fd_type evt_type = fdit->second.m_type;
  955                 if(evt_type == SCAP_FD_IPV4_SOCK || evt_type == SCAP_FD_IPV4_SERVSOCK ||
  956                    evt_type == SCAP_FD_IPV6_SOCK || evt_type == SCAP_FD_IPV6_SERVSOCK)
  957                 {
  958                     bool include_client;
  959                     char sipbuf[128], cipbuf[128];
  960                     uint8_t *sip, *cip;
  961                     uint16_t sport, cport;
  962                     bool is_server;
  963                     int af;
  964 
  965                     if(evt_type == SCAP_FD_IPV4_SOCK)
  966                     {
  967                         include_client = true;
  968                         af = AF_INET;
  969                         cip = (uint8_t*)&(fdit->second.m_sockinfo.m_ipv4info.m_fields.m_sip);
  970                         sip = (uint8_t*)&(fdit->second.m_sockinfo.m_ipv4info.m_fields.m_dip);
  971                         cport = fdit->second.m_sockinfo.m_ipv4info.m_fields.m_sport;
  972                         sport = fdit->second.m_sockinfo.m_ipv4info.m_fields.m_dport;
  973                         is_server = fdit->second.is_role_server();
  974                     }
  975                     else if (evt_type == SCAP_FD_IPV4_SERVSOCK)
  976                     {
  977                         include_client = false;
  978                         af = AF_INET;
  979                         cip = NULL;
  980                         sip = (uint8_t*)&(fdit->second.m_sockinfo.m_ipv4serverinfo.m_ip);
  981                         sport = fdit->second.m_sockinfo.m_ipv4serverinfo.m_port;
  982                         is_server = true;
  983                     }
  984                     else if (evt_type == SCAP_FD_IPV6_SOCK)
  985                     {
  986                         include_client = true;
  987                         af = AF_INET6;
  988                         cip = (uint8_t*)&(fdit->second.m_sockinfo.m_ipv6info.m_fields.m_sip);
  989                         sip = (uint8_t*)&(fdit->second.m_sockinfo.m_ipv6info.m_fields.m_dip);
  990                         cport = fdit->second.m_sockinfo.m_ipv6info.m_fields.m_sport;
  991                         sport = fdit->second.m_sockinfo.m_ipv6info.m_fields.m_dport;
  992                         is_server = fdit->second.is_role_server();
  993                     }
  994                     else
  995                     {
  996                         include_client = false;
  997                         af = AF_INET6;
  998                         cip = NULL;
  999                         sip = (uint8_t*)&(fdit->second.m_sockinfo.m_ipv6serverinfo.m_ip);
 1000                         sport = fdit->second.m_sockinfo.m_ipv6serverinfo.m_port;
 1001                         is_server = true;
 1002                     }
 1003 
 1004                     // Now convert the raw sip/cip to strings
 1005                     if(NULL == inet_ntop(af, sip, sipbuf, sizeof(sipbuf)))
 1006                     {
 1007                         strcpy(sipbuf, "<NA>");
 1008                     }
 1009 
 1010                     if(cip)
 1011                     {
 1012                         if(NULL == inet_ntop(af, cip, cipbuf, sizeof(cipbuf)))
 1013                         {
 1014                             strcpy(cipbuf, "<NA>");
 1015                         }
 1016                     }
 1017 
 1018                     if(include_client)
 1019                     {
 1020                         // cip
 1021                         lua_pushliteral(ls, "cip");
 1022                         lua_pushstring(ls, cipbuf);
 1023                         lua_settable(ls, -3);
 1024                     }
 1025 
 1026                     // sip
 1027                     lua_pushliteral(ls, "sip");
 1028                     lua_pushstring(ls, sipbuf);
 1029                     lua_settable(ls, -3);
 1030 
 1031                     if(include_client)
 1032                     {
 1033                         // cport
 1034                         lua_pushliteral(ls, "cport");
 1035                         lua_pushnumber(ls, cport);
 1036                         lua_settable(ls, -3);
 1037                     }
 1038 
 1039                     // sport
 1040                     lua_pushliteral(ls, "sport");
 1041                     lua_pushnumber(ls, sport);
 1042                     lua_settable(ls, -3);
 1043 
 1044                     // is_server
 1045                     lua_pushliteral(ls, "is_server");
 1046                     lua_pushboolean(ls, is_server);
 1047                     lua_settable(ls, -3);
 1048 
 1049                     // l4proto
 1050                     const char* l4ps;
 1051                     scap_l4_proto l4p = fdit->second.get_l4proto();
 1052 
 1053                     switch(l4p)
 1054                     {
 1055                     case SCAP_L4_TCP:
 1056                         l4ps = "tcp";
 1057                         break;
 1058                     case SCAP_L4_UDP:
 1059                         l4ps = "udp";
 1060                         break;
 1061                     case SCAP_L4_ICMP:
 1062                         l4ps = "icmp";
 1063                         break;
 1064                     case SCAP_L4_RAW:
 1065                         l4ps = "raw";
 1066                         break;
 1067                     default:
 1068                         l4ps = "<NA>";
 1069                         break;
 1070                     }
 1071 
 1072                     // l4proto
 1073                     lua_pushliteral(ls, "l4proto");
 1074                     lua_pushstring(ls, l4ps);
 1075                     lua_settable(ls, -3);
 1076                 }
 1077 
 1078                 // is_server
 1079                 string l4proto;
 1080 
 1081                 lua_rawseti(ls,-2, (uint32_t)fdit->first);
 1082             }
 1083         }
 1084 
 1085 
 1086         lua_settable(ls,-3);
 1087 
 1088         //
 1089         // Set the key for this entry
 1090         //
 1091         lua_rawseti(ls,-2, (uint32_t)tinfo.m_tid);
 1092         return true;
 1093     });
 1094 
 1095     if(filter)
 1096     {
 1097         delete filter;
 1098     }
 1099 
 1100     return 1;
 1101 }
 1102 
 1103 int lua_cbacks::get_thread_table(lua_State *ls)
 1104 {
 1105     return get_thread_table_int(ls, true, false);
 1106 }
 1107 
 1108 int lua_cbacks::get_thread_table_nofds(lua_State *ls)
 1109 {
 1110     return get_thread_table_int(ls, false, false);
 1111 }
 1112 
 1113 int lua_cbacks::get_thread_table_barebone(lua_State *ls)
 1114 {
 1115     return get_thread_table_int(ls, true, true);
 1116 }
 1117 
 1118 int lua_cbacks::get_thread_table_barebone_nofds(lua_State *ls)
 1119 {
 1120     return get_thread_table_int(ls, false, true);
 1121 }
 1122 
 1123 int lua_cbacks::get_container_table(lua_State *ls)
 1124 {
 1125     unordered_map<int64_t, sinsp_fdinfo_t>::iterator fdit;
 1126     uint32_t j;
 1127     sinsp_evt tevt;
 1128 
 1129     //
 1130     // Get the chisel state
 1131     //
 1132     lua_getglobal(ls, "sichisel");
 1133 
 1134     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1135     lua_pop(ls, 1);
 1136 
 1137     ASSERT(ch);
 1138     ASSERT(ch->m_lua_cinfo);
 1139     ASSERT(ch->m_inspector);
 1140 
 1141     //
 1142     // Retrieve the container list
 1143     //
 1144     const unordered_map<string, sinsp_container_info>* ctable  = ch->m_inspector->m_container_manager.get_containers();
 1145 
 1146     ASSERT(ctable != NULL);
 1147 
 1148     lua_newtable(ls);
 1149 
 1150     //
 1151     // Go through the list
 1152     //
 1153     j = 0;
 1154     for(auto it = ctable->begin(); it != ctable->end(); ++it)
 1155     {
 1156         lua_newtable(ls);
 1157         lua_pushliteral(ls, "id");
 1158         lua_pushstring(ls, it->second.m_id.c_str());
 1159         lua_settable(ls, -3);
 1160         lua_pushliteral(ls, "name");
 1161         lua_pushstring(ls, it->second.m_name.c_str());
 1162         lua_settable(ls, -3);
 1163         lua_pushliteral(ls, "image");
 1164         lua_pushstring(ls, it->second.m_image.c_str());
 1165         lua_settable(ls, -3);
 1166 
 1167         lua_pushliteral(ls, "type");
 1168         if(it->second.m_type == CT_DOCKER)
 1169         {
 1170             lua_pushstring(ls, "docker");
 1171         }
 1172         else if(it->second.m_type == CT_LXC)
 1173         {
 1174             lua_pushstring(ls, "lxc");
 1175         }
 1176         else if(it->second.m_type == CT_LIBVIRT_LXC)
 1177         {
 1178             lua_pushstring(ls, "libvirt_lxc");
 1179         }
 1180         else if(it->second.m_type == CT_MESOS)
 1181         {
 1182             lua_pushstring(ls, "mesos");
 1183         }
 1184         else if(it->second.m_type == CT_RKT)
 1185         {
 1186             lua_pushstring(ls, "rkt");
 1187         }
 1188         else if(it->second.m_type == CT_CRI)
 1189         {
 1190             lua_pushstring(ls, "cri");
 1191         }
 1192         else if(it->second.m_type == CT_CONTAINERD)
 1193         {
 1194             lua_pushstring(ls, "containerd");
 1195         }
 1196         else if(it->second.m_type == CT_CRIO)
 1197         {
 1198             lua_pushstring(ls, "cri-o");
 1199         }
 1200         else if(it->second.m_type == CT_BPM)
 1201         {
 1202             lua_pushstring(ls, "bpm");
 1203         }
 1204         else
 1205         {
 1206             ASSERT(false);
 1207             lua_pushstring(ls, "unknown");
 1208         }
 1209         lua_settable(ls, -3);
 1210 
 1211         //
 1212         // Set the key for this entry
 1213         //
 1214         lua_rawseti(ls,-2, (uint32_t)++j);
 1215     }
 1216 
 1217     return 1;
 1218 }
 1219 
 1220 int lua_cbacks::is_print_container_data(lua_State *ls)
 1221 {
 1222         lua_getglobal(ls, "sichisel");
 1223 
 1224         sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1225         lua_pop(ls, 1);
 1226 
 1227         ASSERT(ch);
 1228         ASSERT(ch->m_lua_cinfo);
 1229 
 1230         lua_pushboolean(ls, ch->m_inspector->is_print_container_data());
 1231         return 1;
 1232 }
 1233 
 1234 
 1235 int lua_cbacks::get_output_format(lua_State *ls)
 1236 {
 1237     lua_getglobal(ls, "sichisel");
 1238 
 1239     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1240     lua_pop(ls, 1);
 1241 
 1242     ASSERT(ch);
 1243     ASSERT(ch->m_lua_cinfo);
 1244 
 1245     sinsp_evt::param_fmt fmt = ch->m_inspector->get_buffer_format();
 1246 
 1247     if(fmt & sinsp_evt::PF_JSON)
 1248     {
 1249         lua_pushstring(ls, "json");
 1250     }
 1251     else
 1252     {
 1253         lua_pushstring(ls, "normal");
 1254     }
 1255 
 1256     return 1;
 1257 }
 1258 
 1259 int lua_cbacks::get_evtsource_name(lua_State *ls)
 1260 {
 1261     lua_getglobal(ls, "sichisel");
 1262 
 1263     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1264     lua_pop(ls, 1);
 1265 
 1266     ASSERT(ch);
 1267     ASSERT(ch->m_lua_cinfo);
 1268 
 1269     if(ch->m_inspector->is_live())
 1270     {
 1271         lua_pushstring(ls, "");
 1272     }
 1273     else
 1274     {
 1275         lua_pushstring(ls, ch->m_inspector->get_input_filename().c_str());
 1276     }
 1277 
 1278     return 1;
 1279 }
 1280 
 1281 int lua_cbacks::get_firstevent_ts(lua_State *ls)
 1282 {
 1283     lua_getglobal(ls, "sichisel");
 1284 
 1285     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1286     lua_pop(ls, 1);
 1287 
 1288     ASSERT(ch);
 1289     ASSERT(ch->m_lua_cinfo);
 1290 
 1291     lua_pushstring(ls, to_string(ch->m_inspector->m_firstevent_ts).c_str());
 1292 
 1293     return 1;
 1294 }
 1295 
 1296 int lua_cbacks::get_lastevent_ts(lua_State *ls)
 1297 {
 1298     lua_getglobal(ls, "sichisel");
 1299 
 1300     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1301     lua_pop(ls, 1);
 1302 
 1303     ASSERT(ch);
 1304     ASSERT(ch->m_lua_cinfo);
 1305 
 1306     lua_pushstring(ls, to_string(ch->m_inspector->m_lastevent_ts).c_str());
 1307 
 1308     return 1;
 1309 }
 1310 
 1311 int lua_cbacks::set_event_formatter(lua_State *ls)
 1312 {
 1313     lua_getglobal(ls, "sichisel");
 1314 
 1315     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1316     lua_pop(ls, 1);
 1317 
 1318     const char* formatter = lua_tostring(ls, 1);
 1319 
 1320     ASSERT(ch);
 1321     ASSERT(ch->m_lua_cinfo);
 1322 
 1323     ch->m_lua_cinfo->set_formatter(formatter);
 1324 
 1325     return 0;
 1326 }
 1327 
 1328 int lua_cbacks::set_interval_ns(lua_State *ls)
 1329 {
 1330     lua_getglobal(ls, "sichisel");
 1331 
 1332     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1333     lua_pop(ls, 1);
 1334 
 1335     uint64_t interval = (uint64_t)lua_tonumber(ls, 1);
 1336 
 1337     ASSERT(ch);
 1338     ASSERT(ch->m_lua_cinfo);
 1339 
 1340     ch->m_lua_cinfo->set_callback_interval(interval);
 1341 
 1342     return 0;
 1343 }
 1344 
 1345 int lua_cbacks::set_interval_s(lua_State *ls)
 1346 {
 1347     lua_getglobal(ls, "sichisel");
 1348 
 1349     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1350     lua_pop(ls, 1);
 1351 
 1352     uint64_t interval = (uint64_t)lua_tonumber(ls, 1);
 1353 
 1354     ASSERT(ch);
 1355     ASSERT(ch->m_lua_cinfo);
 1356 
 1357     ch->m_lua_cinfo->set_callback_interval(interval * 1000000000);
 1358 
 1359     return 0;
 1360 }
 1361 
 1362 int lua_cbacks::set_precise_interval_ns(lua_State *ls)
 1363 {
 1364     lua_getglobal(ls, "sichisel");
 1365 
 1366     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1367     lua_pop(ls, 1);
 1368 
 1369     uint64_t interval = (uint64_t)lua_tonumber(ls, 1);
 1370 
 1371     ASSERT(ch);
 1372     ASSERT(ch->m_lua_cinfo);
 1373 
 1374     ch->m_lua_cinfo->set_callback_precise_interval(interval);
 1375 
 1376     return 0;
 1377 }
 1378 
 1379 int lua_cbacks::exec(lua_State *ls)
 1380 {
 1381     lua_getglobal(ls, "sichisel");
 1382 
 1383     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1384     lua_pop(ls, 1);
 1385 
 1386     ASSERT(ch);
 1387     ASSERT(ch->m_lua_cinfo);
 1388 
 1389     const char* chname = lua_tostring(ls, 1);
 1390     if(chname == NULL)
 1391     {
 1392         string err = "invalid exec field name in chisel " + ch->m_filename;
 1393         fprintf(stderr, "%s\n", err.c_str());
 1394         throw sinsp_exception("chisel error");
 1395     }
 1396 
 1397     ch->m_new_chisel_to_exec = chname;
 1398 
 1399     ch->m_argvals.clear();
 1400     uint32_t stackpos = 2;
 1401 
 1402     while(true)
 1403     {
 1404         const char* argval = lua_tostring(ls, stackpos++);
 1405         if(argval == NULL)
 1406         {
 1407             break;
 1408         }
 1409 
 1410         ch->m_argvals.push_back(argval);
 1411     }
 1412 
 1413     return 0;
 1414 }
 1415 
 1416 int lua_cbacks::log(lua_State *ls)
 1417 {
 1418     lua_getglobal(ls, "sichisel");
 1419 
 1420     string message(lua_tostring(ls, 1));
 1421     string sevstr(lua_tostring(ls, 2));
 1422 
 1423     sinsp_logger::severity sevcode = sinsp_logger::SEV_INFO;
 1424 
 1425     if(sevstr == "debug")
 1426     {
 1427         sevcode = sinsp_logger::SEV_DEBUG;
 1428     }
 1429     else if(sevstr == "info")
 1430     {
 1431         sevcode = sinsp_logger::SEV_INFO;
 1432     }
 1433     else if(sevstr == "warning")
 1434     {
 1435         sevcode = sinsp_logger::SEV_WARNING;
 1436     }
 1437     else if(sevstr == "error")
 1438     {
 1439         sevcode = sinsp_logger::SEV_ERROR;
 1440     }
 1441     else if(sevstr == "critical")
 1442     {
 1443         sevcode = sinsp_logger::SEV_CRITICAL;
 1444     }
 1445 
 1446     g_logger.log(message, sevcode);
 1447 
 1448     return 0;
 1449 }
 1450 
 1451 int lua_cbacks::udp_setpeername(lua_State *ls)
 1452 {
 1453     lua_getglobal(ls, "sichisel");
 1454     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1455 
 1456     string addr(lua_tostring(ls, 1));
 1457     string ports(lua_tostring(ls, 2));
 1458     uint16_t port = htons(sinsp_numparser::parseu16(ports));
 1459 
 1460     ch->m_udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
 1461     if(ch->m_udp_socket < 0)
 1462     {
 1463         string err = "udp_setpeername error: unable to create the socket";
 1464         fprintf(stderr, "%s\n", err.c_str());
 1465         throw sinsp_exception("chisel error");
 1466     }
 1467 
 1468     memset(&ch->m_serveraddr, 0, sizeof(ch->m_serveraddr));
 1469     ch->m_serveraddr.sin_family = AF_INET;
 1470     ch->m_serveraddr.sin_port = port;
 1471     if(inet_pton(AF_INET, addr.c_str(), &ch->m_serveraddr.sin_addr) <= 0)
 1472     {
 1473         string err = "inet_pton error occurred";
 1474         fprintf(stderr, "%s\n", err.c_str());
 1475         throw sinsp_exception("chisel error");
 1476     }
 1477 
 1478     return 0;
 1479 }
 1480 
 1481 int lua_cbacks::udp_send(lua_State *ls)
 1482 {
 1483     lua_getglobal(ls, "sichisel");
 1484     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1485 
 1486     string message(lua_tostring(ls, 1));
 1487 
 1488     if(sendto(ch->m_udp_socket, message.c_str(), message.size(), 0,
 1489         (struct sockaddr *)&ch->m_serveraddr, sizeof(ch->m_serveraddr)) < 0)
 1490     {
 1491         string err = "udp_send error: cannot send the buffer: ";
 1492         fprintf(stderr, "%s\n", err.c_str());
 1493         throw sinsp_exception("chisel error");
 1494     }
 1495 
 1496     return 0;
 1497 }
 1498 
 1499 int lua_cbacks::get_read_progress(lua_State *ls)
 1500 {
 1501     lua_getglobal(ls, "sichisel");
 1502 
 1503     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1504     lua_pop(ls, 1);
 1505 
 1506     ASSERT(ch);
 1507     ASSERT(ch->m_inspector);
 1508 
 1509     double pr = ch->m_inspector->get_read_progress();
 1510 
 1511     lua_pushnumber(ls, pr);
 1512 
 1513     return 1;
 1514 }
 1515 
 1516 #ifdef HAS_ANALYZER
 1517 int lua_cbacks::push_metric(lua_State *ls)
 1518 {
 1519     statsd_metric metric;
 1520     metric.m_type = statsd_metric::type_t::GAUGE;
 1521 
 1522     lua_getglobal(ls, "sichisel");
 1523 
 1524     sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
 1525     lua_pop(ls, 1);
 1526 
 1527     ASSERT(ch);
 1528     ASSERT(ch->m_lua_cinfo);
 1529 
 1530     sinsp* inspector = ch->m_inspector;
 1531 
 1532     //
 1533     // tags
 1534     //
 1535     if(lua_istable(ls, 3))
 1536     {
 1537         lua_pushnil(ls);
 1538 
 1539         while(lua_next(ls, 3) != 0)
 1540         {
 1541             string tag = lua_tostring(ls, -1);
 1542             metric.m_tags[tag] = "";
 1543             lua_pop(ls, 1);
 1544         }
 1545 
 1546         lua_pop(ls, 1);
 1547     }
 1548     else
 1549     {
 1550         string err = "error in chisel " + ch->m_filename + ": third argument must be a table";
 1551         fprintf(stderr, "%s\n", err.c_str());
 1552         throw sinsp_exception("chisel error");
 1553     }
 1554 
 1555     //
 1556     // Name
 1557     //
 1558     if(lua_isstring(ls, 1))
 1559     {
 1560         metric.m_name = lua_tostring(ls, 1);
 1561     }
 1562     else
 1563     {
 1564         string err = "errord in chisel " + ch->m_filename + ": first argument must be a string";
 1565         fprintf(stderr, "%s\n", err.c_str());
 1566         throw sinsp_exception("chisel error");
 1567     }
 1568 
 1569     //
 1570     // Value
 1571     //
 1572     if(lua_isnumber(ls, 2))
 1573     {
 1574         metric.m_value = lua_tonumber(ls, 2);
 1575     }
 1576     else
 1577     {
 1578         string err = "errord in chisel " + ch->m_filename + ": second argument must be a number";
 1579         fprintf(stderr, "%s\n", err.c_str());
 1580         throw sinsp_exception("chisel error");
 1581     }
 1582 
 1583     inspector->m_analyzer->add_chisel_metric(&metric);
 1584 
 1585     return 0;
 1586 }
 1587 
 1588 #endif // HAS_ANALYZER
 1589 #endif // HAS_LUA_CHISELS
 1590 #endif // HAS_CHISELS