luajit: force scripts to have 'init' function that returns a table of 'needs' such as packet or payload.

pull/63/head
Victor Julien 13 years ago
parent fca70730a9
commit 69186cda12

@ -96,6 +96,43 @@ void DetectLuajitRegister(void) {
return;
}
#define DATATYPE_PACKET (1<<0)
#define DATATYPE_PAYLOAD (1<<1)
/** \brief dump stack from lua state to screen */
void LuaDumpStack(lua_State *state) {
int size = lua_gettop(state);
int i;
for (i = 1; i <= size; i++) {
int type = lua_type(state, i);
printf("Stack size=%d, level=%d, type=%d, ", size, i, type);
switch (type) {
case LUA_TFUNCTION:
printf("function %s", lua_tostring(state, i) ? "true" : "false");
break;
case LUA_TBOOLEAN:
printf("bool %s", lua_toboolean(state, i) ? "true" : "false");
break;
case LUA_TNUMBER:
printf("number %g", lua_tonumber(state, i));
break;
case LUA_TSTRING:
printf("string `%s'", lua_tostring(state, i));
break;
case LUA_TTABLE:
printf("table `%s'", lua_tostring(state, i));
break;
default:
printf("other %s", lua_typename(state, type));
break;
}
printf("\n");
}
}
/**
* \brief match the specified luajit
*
@ -121,15 +158,20 @@ static int DetectLuajitMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
if (tluajit == NULL)
SCReturnInt(0);
if ((tluajit->flags & DATATYPE_PAYLOAD) && p->payload_len)
SCReturnInt(0);
if ((tluajit->flags & DATATYPE_PACKET) && GET_PKT_LEN(p))
SCReturnInt(0);
lua_getglobal(tluajit->luastate, "match");
lua_newtable(tluajit->luastate); /* stack at -1 */
if (p->payload_len) {
if ((tluajit->flags & DATATYPE_PAYLOAD) && p->payload_len) {
lua_pushliteral(tluajit->luastate, "payload"); /* stack at -2 */
lua_pushlstring (tluajit->luastate, (const char *)p->payload, (size_t)p->payload_len); /* stack at -3 */
lua_settable(tluajit->luastate, -3);
}
if (GET_PKT_LEN(p)) {
if ((tluajit->flags & DATATYPE_PACKET) && GET_PKT_LEN(p)) {
lua_pushliteral(tluajit->luastate, "packet"); /* stack at -2 */
lua_pushlstring (tluajit->luastate, (const char *)GET_PKT_DATA(p), (size_t)GET_PKT_LEN(p)); /* stack at -3 */
lua_settable(tluajit->luastate, -3);
@ -140,12 +182,51 @@ static int DetectLuajitMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
SCLogInfo("failed to run script: %s", lua_tostring(tluajit->luastate, -1));
}
double script_ret = lua_tonumber(tluajit->luastate, 1);
SCLogDebug("script_ret %f", script_ret);
lua_pop(tluajit->luastate, 1);
/* process returns from script */
if (lua_gettop(tluajit->luastate) > 0) {
/* script returns a number (return 1 or return 0) */
if (lua_type(tluajit->luastate, 1) == LUA_TNUMBER) {
double script_ret = lua_tonumber(tluajit->luastate, 1);
SCLogDebug("script_ret %f", script_ret);
lua_pop(tluajit->luastate, 1);
if (script_ret == 1.0)
ret = 1;
/* script returns a table */
} else if (lua_type(tluajit->luastate, 1) == LUA_TTABLE) {
lua_pushnil(tluajit->luastate);
const char *k, *v;
while (lua_next(tluajit->luastate, -2)) {
v = lua_tostring(tluajit->luastate, -1);
lua_pop(tluajit->luastate, 1);
k = lua_tostring(tluajit->luastate, -1);
if (!k || !v)
continue;
SCLogDebug("k='%s', v='%s'", k, v);
if (strcmp(k, "retval") == 0) {
if (atoi(v) == 1)
ret = 1;
} else {
/* set flow var? */
}
}
/* pop the table */
lua_pop(tluajit->luastate, 1);
}
}
if (script_ret == 1.0)
ret = 1;
if (luajit->negated) {
if (ret == 1)
ret = 0;
else
ret = 1;
}
SCReturnInt(ret);
}
@ -170,8 +251,66 @@ static void *DetectLuajitThreadInit(void *data) {
fprintf(stderr, "Couldn't prime file: %s\n", lua_tostring(t->luastate, -1));
BUG_ON(1);
}
}
lua_getglobal(t->luastate, "init");
if (lua_type(t->luastate, -1) != LUA_TFUNCTION) {
SCLogInfo("no init function in script");
/** \todo proper cleanup */
return NULL;
}
lua_newtable(t->luastate); /* stack at -1 */
if (lua_gettop(t->luastate) == 0 || lua_type(t->luastate, 2) != LUA_TTABLE) {
SCLogInfo("no table setup");
/** \todo proper cleanup */
return NULL;
}
lua_pushliteral(t->luastate, "script_api_ver"); /* stack at -2 */
lua_pushnumber (t->luastate, 1); /* stack at -3 */
lua_settable(t->luastate, -3);
if (lua_pcall(t->luastate, 1, 1, 0) != 0) {
fprintf(stderr, "Couldn't prime file: %s\n", lua_tostring(t->luastate, -1));
BUG_ON(1);
}
/* process returns from script */
if (lua_gettop(t->luastate) == 0) {
SCLogInfo("init function in script should return table, nothing returned");
/** \todo proper cleanup */
return NULL;
}
if (lua_type(t->luastate, 1) != LUA_TTABLE) {
SCLogInfo("init function in script should return table, returned is not table");
/** \todo proper cleanup */
return NULL;
}
lua_pushnil(t->luastate);
const char *k, *v;
while (lua_next(t->luastate, -2)) {
v = lua_tostring(t->luastate, -1);
lua_pop(t->luastate, 1);
k = lua_tostring(t->luastate, -1);
if (!k || !v)
continue;
SCLogDebug("k='%s', v='%s'", k, v);
if (strcmp(k, "packet") == 0 && strcmp(v, "true") == 0) {
t->flags |= DATATYPE_PACKET;
} else if (strcmp(k, "payload") == 0 && strcmp(v, "true") == 0) {
t->flags |= DATATYPE_PAYLOAD;
} else {
SCLogInfo("unsupported data type %s", k);
}
}
/* pop the table */
lua_pop(t->luastate, 1);
}
return (void *)t;
}

@ -32,6 +32,7 @@
typedef struct DetectLuajitThreadData {
lua_State *luastate;
uint32_t flags;
} DetectLuajitThreadData;
typedef struct DetectLuajitData {

Loading…
Cancel
Save