~ubuntu-branches/ubuntu/saucy/suricata/saucy-updates

« back to all changes in this revision

Viewing changes to src/detect-flowvar.c

  • Committer: Package Import Robot
  • Author(s): Pierre Chifflier
  • Date: 2013-05-29 16:24:52 UTC
  • mfrom: (1.1.20)
  • Revision ID: package-import@ubuntu.com-20130529162452-kujdwfkf24i9qdfu
Tags: 1.4.2-1
ImportedĀ UpstreamĀ versionĀ 1.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
 
45
45
int DetectFlowvarMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, SigMatch *);
46
46
static int DetectFlowvarSetup (DetectEngineCtx *, Signature *, char *);
 
47
static int DetectFlowvarPostMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *sm);
 
48
static void DetectFlowvarDataFree(void *ptr);
47
49
 
48
50
void DetectFlowvarRegister (void) {
49
51
    sigmatch_table[DETECT_FLOWVAR].name = "flowvar";
50
52
    sigmatch_table[DETECT_FLOWVAR].Match = DetectFlowvarMatch;
51
53
    sigmatch_table[DETECT_FLOWVAR].Setup = DetectFlowvarSetup;
52
 
    sigmatch_table[DETECT_FLOWVAR].Free  = NULL;
 
54
    sigmatch_table[DETECT_FLOWVAR].Free  = DetectFlowvarDataFree;
53
55
    sigmatch_table[DETECT_FLOWVAR].RegisterTests  = NULL;
54
56
 
 
57
    /* post-match for flowvar storage */
 
58
    sigmatch_table[DETECT_FLOWVAR_POSTMATCH].name = "__flowvar__postmatch__";
 
59
    sigmatch_table[DETECT_FLOWVAR_POSTMATCH].Match = DetectFlowvarPostMatch;
 
60
    sigmatch_table[DETECT_FLOWVAR_POSTMATCH].Setup = NULL;
 
61
    sigmatch_table[DETECT_FLOWVAR_POSTMATCH].Free  = DetectFlowvarDataFree;
 
62
    sigmatch_table[DETECT_FLOWVAR_POSTMATCH].RegisterTests  = NULL;
 
63
 
55
64
    const char *eb;
56
65
    int eo;
57
66
    int opts = 0;
76
85
    return;
77
86
}
78
87
 
 
88
/**
 
89
 * \brief this function will SCFree memory associated with DetectFlowvarData
 
90
 *
 
91
 * \param cd pointer to DetectCotentData
 
92
 */
 
93
static void DetectFlowvarDataFree(void *ptr) {
 
94
    if (ptr == NULL)
 
95
        SCReturn;
 
96
 
 
97
    DetectFlowvarData *fd = (DetectFlowvarData *)ptr;
 
98
 
 
99
    if (fd->name)
 
100
        SCFree(fd->name);
 
101
    if (fd->content)
 
102
        SCFree(fd->content);
 
103
 
 
104
    SCFree(fd);
 
105
}
 
106
 
79
107
/*
80
108
 * returns 0: no match
81
109
 *         1: match
249
277
}
250
278
 
251
279
 
 
280
/** \brief Store flowvar in det_ctx so we can exec it post-match */
 
281
int DetectFlowvarStoreMatch(DetectEngineThreadCtx *det_ctx, uint16_t idx, uint8_t *buffer, uint16_t len) {
 
282
    DetectFlowvarList *fs = det_ctx->flowvarlist;
 
283
 
 
284
    /* first check if we have had a previous match for this idx */
 
285
    for ( ; fs != NULL; fs = fs->next) {
 
286
        if (fs->idx == idx) {
 
287
            /* we're replacing the older store */
 
288
            SCFree(fs->buffer);
 
289
            fs->buffer = NULL;
 
290
            break;
 
291
        }
 
292
    }
 
293
 
 
294
    if (fs == NULL) {
 
295
        fs = SCMalloc(sizeof(*fs));
 
296
        if (unlikely(fs == NULL))
 
297
            return -1;
 
298
 
 
299
        fs->idx = idx;
 
300
 
 
301
        fs->next = det_ctx->flowvarlist;
 
302
        det_ctx->flowvarlist = fs;
 
303
    }
 
304
 
 
305
    fs->len = len;
 
306
    fs->buffer = buffer;
 
307
    return 0;
 
308
}
 
309
 
 
310
/** \brief Setup a post-match for flowvar storage
 
311
 *  We're piggyback riding the DetectFlowvarData struct
 
312
 */
 
313
int DetectFlowvarPostMatchSetup(Signature *s, uint16_t idx) {
 
314
    SigMatch *sm = NULL;
 
315
    DetectFlowvarData *fv = NULL;
 
316
 
 
317
    fv = SCMalloc(sizeof(DetectFlowvarData));
 
318
    if (unlikely(fv == NULL))
 
319
        goto error;
 
320
    memset(fv, 0x00, sizeof(*fv));
 
321
 
 
322
    /* we only need the idx */
 
323
    fv->idx = idx;
 
324
 
 
325
    sm = SigMatchAlloc();
 
326
    if (sm == NULL)
 
327
        goto error;
 
328
 
 
329
    sm->type = DETECT_FLOWVAR_POSTMATCH;
 
330
    sm->ctx = (void *)fv;
 
331
 
 
332
    SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_POSTMATCH);
 
333
    return 0;
 
334
error:
 
335
    return -1;
 
336
}
 
337
 
 
338
/** \internal
 
339
 *  \brief post-match func to store flowvars in the flow
 
340
 *  \param sm sigmatch containing the idx to store
 
341
 *  \retval 1 or -1 in case of error
 
342
 */
 
343
static int DetectFlowvarPostMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *sm) {
 
344
    DetectFlowvarList *fs, *prev;
 
345
    DetectFlowvarData *fd;
 
346
 
 
347
    if (det_ctx->flowvarlist == NULL || p->flow == NULL)
 
348
        return 1;
 
349
 
 
350
    fd = (DetectFlowvarData *)sm->ctx;
 
351
 
 
352
    prev = NULL;
 
353
    fs = det_ctx->flowvarlist;
 
354
    while (fs != NULL) {
 
355
        if (fd->idx == fs->idx) {
 
356
            FlowVarAddStr(p->flow, fs->idx, fs->buffer, fs->len);
 
357
            /* memory at fs->buffer is now the responsibility of
 
358
             * the flowvar code. */
 
359
 
 
360
            if (fs == det_ctx->flowvarlist) {
 
361
                det_ctx->flowvarlist = fs->next;
 
362
                SCFree(fs);
 
363
                fs = det_ctx->flowvarlist;
 
364
            } else {
 
365
                prev->next = fs->next;
 
366
                SCFree(fs);
 
367
                fs = prev->next;
 
368
            }
 
369
        } else {
 
370
            prev = fs;
 
371
            fs = fs->next;
 
372
        }
 
373
    }
 
374
    return 1;
 
375
}
 
376
 
 
377
/** \brief Clean flowvar candidate list in det_ctx */
 
378
void DetectFlowvarCleanupList(DetectEngineThreadCtx *det_ctx) {
 
379
    DetectFlowvarList *fs, *next;
 
380
    if (det_ctx->flowvarlist != NULL) {
 
381
        fs = det_ctx->flowvarlist;
 
382
        while (fs != NULL) {
 
383
            next = fs->next;
 
384
            SCFree(fs->buffer);
 
385
            SCFree(fs);
 
386
            fs = next;
 
387
        }
 
388
 
 
389
        det_ctx->flowvarlist = NULL;
 
390
    }
 
391
}
 
392