pktvars: same name pktvars, key-value vars

pull/2559/head
Victor Julien 9 years ago
parent 5ca4a2e6fe
commit 996112edf5

@ -302,8 +302,10 @@ typedef struct PktVar_ {
struct PktVar_ *next; /* right now just implement this as a list,
* in the long run we have thing of something
* faster. */
uint8_t *value;
uint16_t key_len;
uint16_t value_len;
uint8_t *key;
uint8_t *value;
} PktVar;
#ifdef PROFILING

@ -193,9 +193,29 @@ error:
return -1;
}
/** \brief Store flowvar in det_ctx so we can exec it post-match */
int DetectVarStoreMatchKeyValue(DetectEngineThreadCtx *det_ctx,
uint8_t *key, uint16_t key_len,
uint8_t *buffer, uint16_t len, int type)
{
DetectVarList *fs = SCCalloc(1, sizeof(*fs));
if (unlikely(fs == NULL))
return -1;
fs->len = len;
fs->type = type;
fs->buffer = buffer;
fs->key = key;
fs->key_len = key_len;
fs->next = det_ctx->varlist;
det_ctx->varlist = fs;
return 0;
}
/** \brief Store flowvar in det_ctx so we can exec it post-match */
int DetectVarStoreMatch(DetectEngineThreadCtx *det_ctx, uint32_t idx,
int DetectVarStoreMatch(DetectEngineThreadCtx *det_ctx,
uint32_t idx,
uint8_t *buffer, uint16_t len, int type)
{
DetectVarList *fs = det_ctx->varlist;
@ -211,7 +231,7 @@ int DetectVarStoreMatch(DetectEngineThreadCtx *det_ctx, uint32_t idx,
}
if (fs == NULL) {
fs = SCMalloc(sizeof(*fs));
fs = SCCalloc(1, sizeof(*fs));
if (unlikely(fs == NULL))
return -1;
@ -278,7 +298,7 @@ static int DetectFlowvarPostMatch(ThreadVars *tv,
prev = NULL;
fs = det_ctx->varlist;
while (fs != NULL) {
if (fd->idx == fs->idx) {
if (fd->idx == 0 || fd->idx == fs->idx) {
SCLogDebug("adding to the flow %u:", fs->idx);
//PrintRawDataFp(stdout, fs->buffer, fs->len);
@ -286,8 +306,20 @@ static int DetectFlowvarPostMatch(ThreadVars *tv,
FlowVarAddStrNoLock(p->flow, fs->idx, fs->buffer, fs->len);
/* memory at fs->buffer is now the responsibility of
* the flowvar code. */
} else if (fs->type == DETECT_VAR_TYPE_PKT_POSTMATCH && fs->key && p) {
/* pkt key/value */
if (PktVarAddKeyValue(p, (uint8_t *)fs->key, fs->key_len,
(uint8_t *)fs->buffer, fs->len) == -1)
{
SCFree(fs->key);
SCFree(fs->buffer);
/* the rest of fs is freed below */
}
} else if (fs->type == DETECT_VAR_TYPE_PKT_POSTMATCH && p) {
PktVarAdd(p, fs->idx, fs->buffer, fs->len);
if (PktVarAdd(p, fs->idx, fs->buffer, fs->len) == -1) {
SCFree(fs->buffer);
/* the rest of fs is freed below */
}
}
if (fs == det_ctx->varlist) {

@ -36,7 +36,10 @@ typedef struct DetectFlowvarData_ {
void DetectFlowvarRegister (void);
int DetectFlowvarPostMatchSetup(Signature *s, uint32_t idx);
int DetectVarStoreMatch(DetectEngineThreadCtx *, uint32_t, uint8_t *, uint16_t, int);
int DetectVarStoreMatch(DetectEngineThreadCtx *,
uint32_t, uint8_t *, uint16_t, int);
int DetectVarStoreMatchKeyValue(DetectEngineThreadCtx *,
uint8_t *, uint16_t, uint8_t *, uint16_t, int);
/* For use only by DetectFlowvarProcessList() */
void DetectVarProcessListInternal(DetectVarList *fs, Flow *f, Packet *p);

@ -230,7 +230,23 @@ int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, const Signature *s,
SCLogDebug("data %p/%u, type %u id %u p %p",
str_ptr, ret, pe->captypes[x], pe->capids[x], p);
if (pe->captypes[x] == VAR_TYPE_PKT_VAR) {
if (pe->captypes[x] == VAR_TYPE_PKT_VAR_KV) {
/* get the value, as first capture is the key */
const char *str_ptr2;
int ret2 = pcre_get_substring((char *)ptr, ov, MAX_SUBSTRINGS, x+2, &str_ptr2);
if (unlikely(ret2 == 0)) {
break;
}
/* key length is limited to 256 chars */
uint16_t key_len = (ret < 0xff) ? (uint16_t)ret : 0xff;
capture_len = (ret2 < 0xffff) ? (uint16_t)ret2 : 0xffff;
(void)DetectVarStoreMatchKeyValue(det_ctx,
(uint8_t *)str_ptr, key_len,
(uint8_t *)str_ptr2, capture_len,
DETECT_VAR_TYPE_PKT_POSTMATCH);
} else if (pe->captypes[x] == VAR_TYPE_PKT_VAR) {
/* store max 64k. Errors are ignored */
capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff;
(void)DetectVarStoreMatch(det_ctx, pe->capids[x],
@ -665,6 +681,7 @@ static int DetectPcreParseCapture(char *regexstr, DetectEngineCtx *de_ctx, Detec
char *name_array[DETECT_PCRE_CAPTURE_MAX] = { NULL };
int name_idx = 0;
int capture_cnt = 0;
int key = 0;
SCLogDebug("regexstr %s, pd %p", regexstr, pd);
@ -681,7 +698,25 @@ static int DetectPcreParseCapture(char *regexstr, DetectEngineCtx *de_ctx, Detec
}
SCLogDebug("name '%s'", name_array[name_idx]);
if (strncmp(name_array[name_idx], "flow:", 5) == 0) {
if (strcmp(name_array[name_idx], "pkt:key") == 0) {
key = 1;
SCLogDebug("key-value/key");
pd->captypes[pd->idx] = VAR_TYPE_PKT_VAR_KV;
SCLogDebug("id %u type %u", pd->capids[pd->idx], pd->captypes[pd->idx]);
pd->idx++;
} else if (key == 1 && strcmp(name_array[name_idx], "pkt:value") == 0) {
SCLogDebug("key-value/value");
key = 0;
/* kv error conditions */
} else if (key == 0 && strcmp(name_array[name_idx], "pkt:value") == 0) {
return -1;
} else if (key == 1) {
return -1;
} else if (strncmp(name_array[name_idx], "flow:", 5) == 0) {
pd->capids[pd->idx] = VarNameStoreSetupAdd(name_array[name_idx]+5, VAR_TYPE_FLOW_VAR);
pd->captypes[pd->idx] = VAR_TYPE_FLOW_VAR;
pd->idx++;

@ -500,7 +500,9 @@ typedef struct DetectReplaceList_ {
typedef struct DetectVarList_ {
uint32_t idx; /**< flowvar name idx */
uint16_t len; /**< data len */
uint16_t key_len;
int type; /**< type of store candidate POSTMATCH or ALWAYS */
uint8_t *key;
uint8_t *buffer; /**< alloc'd buffer, may be freed by
post-match, post-non-match */
struct DetectVarList_ *next;

@ -102,23 +102,44 @@ static void JsonAddPacketvars(const Packet *p, json_t *js_vars)
json_t *js_pktvars = NULL;
PktVar *pv = p->pktvar;
while (pv != NULL) {
const char *varname = VarNameStoreLookupById(pv->id, VAR_TYPE_PKT_VAR);
if (varname) {
if (pv->key || pv->id > 0) {
if (js_pktvars == NULL) {
js_pktvars = json_object();
js_pktvars = json_array();
if (js_pktvars == NULL)
break;
}
json_t *js_pair = json_object();
if (js_pair == NULL) {
break;
}
uint32_t len = pv->value_len;
uint8_t printable_buf[len + 1];
uint32_t offset = 0;
PrintStringsToBuffer(printable_buf, &offset,
sizeof(printable_buf),
pv->value, pv->value_len);
json_object_set_new(js_pktvars, varname,
json_string((char *)printable_buf));
if (pv->key != NULL) {
uint32_t offset = 0;
uint8_t keybuf[pv->key_len + 1];
PrintStringsToBuffer(keybuf, &offset,
sizeof(keybuf),
pv->key, pv->key_len);
uint32_t len = pv->value_len;
uint8_t printable_buf[len + 1];
offset = 0;
PrintStringsToBuffer(printable_buf, &offset,
sizeof(printable_buf),
pv->value, pv->value_len);
json_object_set_new(js_pair, (char *)keybuf,
json_string((char *)printable_buf));
} else {
const char *varname = VarNameStoreLookupById(pv->id, VAR_TYPE_PKT_VAR);
uint32_t len = pv->value_len;
uint8_t printable_buf[len + 1];
uint32_t offset = 0;
PrintStringsToBuffer(printable_buf, &offset,
sizeof(printable_buf),
pv->value, pv->value_len);
json_object_set_new(js_pair, varname,
json_string((char *)printable_buf));
}
json_array_append_new(js_pktvars, js_pair);
}
pv = pv->next;
}

@ -34,15 +34,6 @@
#include "pkt-var.h"
#include "util-debug.h"
/* puts a new value into a pktvar */
static void PktVarUpdate(PktVar *pv, uint8_t *value, uint16_t size)
{
if (pv->value)
SCFree(pv->value);
pv->value = value;
pv->value_len = size;
}
/* get the pktvar with name 'name' from the pkt
*
* name is a normal string*/
@ -58,37 +49,63 @@ PktVar *PktVarGet(Packet *p, uint32_t id)
return NULL;
}
/* add a pktvar to the pkt, or update it */
void PktVarAdd(Packet *p, uint32_t id, uint8_t *value, uint16_t size)
/**
* \brief add a key-value pktvar to the pkt
* \retval r 0 ok, -1 error
*/
int PktVarAddKeyValue(Packet *p, uint8_t *key, uint16_t ksize, uint8_t *value, uint16_t size)
{
//printf("Adding packet var \"%s\" with value(%" PRId32 ") \"%s\"\n", name, size, value);
PktVar *pv = SCCalloc(1, sizeof(PktVar));
if (unlikely(pv == NULL))
return -1;
PktVar *pv = PktVarGet(p, id);
if (pv == NULL) {
pv = SCMalloc(sizeof(PktVar));
if (unlikely(pv == NULL))
return;
pv->key = key;
pv->key_len = ksize;
pv->value = value;
pv->value_len = size;
pv->id = id;
pv->value = value;
pv->value_len = size;
pv->next = NULL;
PktVar *tpv = p->pktvar;
if (p->pktvar == NULL)
p->pktvar = pv;
else {
while(tpv) {
if (tpv->next == NULL) {
tpv->next = pv;
return 0;
}
tpv = tpv->next;
}
}
return 0;
}
/**
* \brief add a key-value pktvar to the pkt
* \retval r 0 ok, -1 error
*/
int PktVarAdd(Packet *p, uint32_t id, uint8_t *value, uint16_t size)
{
PktVar *pv = SCCalloc(1, sizeof(PktVar));
if (unlikely(pv == NULL))
return -1;
pv->id = id;
pv->value = value;
pv->value_len = size;
PktVar *tpv = p->pktvar;
if (p->pktvar == NULL)
p->pktvar = pv;
else {
while(tpv) {
if (tpv->next == NULL) {
tpv->next = pv;
return;
}
tpv = tpv->next;
PktVar *tpv = p->pktvar;
if (p->pktvar == NULL)
p->pktvar = pv;
else {
while(tpv) {
if (tpv->next == NULL) {
tpv->next = pv;
return 0;
}
tpv = tpv->next;
}
} else {
PktVarUpdate(pv, value, size);
}
return 0;
}
void PktVarFree(PktVar *pv)
@ -96,6 +113,8 @@ void PktVarFree(PktVar *pv)
if (pv == NULL)
return;
if (pv->key != NULL)
SCFree(pv->key);
if (pv->value != NULL)
SCFree(pv->value);
PktVar *pv_next = pv->next;

@ -24,7 +24,8 @@
#ifndef __PKT_VAR_H__
#define __PKT_VAR_H__
void PktVarAdd(Packet *, uint32_t id, uint8_t *, uint16_t);
int WARN_UNUSED PktVarAddKeyValue(Packet *, uint8_t *, uint16_t, uint8_t *, uint16_t);
int WARN_UNUSED PktVarAdd(Packet *, uint32_t id, uint8_t *, uint16_t);
PktVar *PktVarGet(Packet *, uint32_t id);
void PktVarFree(PktVar *);

@ -30,6 +30,7 @@ enum VarTypes {
VAR_TYPE_PKT_BIT,
VAR_TYPE_PKT_INT,
VAR_TYPE_PKT_VAR,
VAR_TYPE_PKT_VAR_KV, // key-value
VAR_TYPE_FLOW_BIT,
VAR_TYPE_FLOW_INT,

Loading…
Cancel
Save