From 4537f889ef0f553df08ad8ab3dd45e16e31342ff Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sun, 17 Apr 2011 17:18:09 +0200 Subject: [PATCH] Handle all strings as raw strings in HTTP content-type and content-disposition header parsing. --- src/app-layer-htp.c | 529 ++++++++++++++++++++++++++++++------------- src/detect-fileext.c | 27 ++- src/flow-file.c | 58 ++++- src/flow-file.h | 7 +- 4 files changed, 440 insertions(+), 181 deletions(-) diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 0ad22e1334..655f66842e 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -67,6 +67,8 @@ #include "conf.h" +#include "util-memcmp.h" + /** Need a linked list in order to keep track of these */ typedef struct HTPCfgRec_ { htp_cfg_t *cfg; @@ -736,6 +738,258 @@ static int HTPCallbackRequestUriNormalize(htp_connp_t *c) } #endif +/** + * \param name /Lowercase/ version of the variable name + */ +static int HTTPParseContentDispositionHeader(uint8_t *name, size_t name_len, + uint8_t *data, size_t len, uint8_t **retptr, size_t *retlen) +{ +#if 0 + printf("DATA START: \n"); + PrintRawDataFp(stdout, data, len); + printf("DATA END: \n"); +#endif + size_t x; + int quote = 0; + + for (x = 0; x < len; x++) { + if (!(isspace(data[x]))) + break; + } + + if (x >= len) + return 0; + + uint8_t *line = data+x; + size_t line_len = len-x; + size_t offset = 0; +#if 0 + printf("LINE START: \n"); + PrintRawDataFp(stdout, line, line_len); + printf("LINE END: \n"); +#endif + for (x = 0 ; x < line_len; x++) { + if (x > 0) { + if (line[x - 1] != '\\' && line[x] == '\"') { + quote++; + } + + if (((line[x - 1] != '\\' && line[x] == ';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) { + uint8_t *token = line + offset; + size_t token_len = x - offset; + + if ((x + 1) == line_len) { + token_len++; + } + + offset = x + 1; + + while (offset < line_len && isspace(line[offset])) { + x++; + offset++; + } +#if 0 + printf("TOKEN START: \n"); + PrintRawDataFp(stdout, token, token_len); + printf("TOKEN END: \n"); +#endif + if (token_len > name_len) { + if (name == NULL || SCMemcmpLowercase(name, token, name_len) == 0) { + uint8_t *value = token + name_len; + size_t value_len = token_len - name_len; + + if (value[0] == '\"') { + value++; + value_len--; + } + if (value[value_len-1] == '\"') { + value_len--; + } +#if 0 + printf("VALUE START: \n"); + PrintRawDataFp(stdout, value, value_len); + printf("VALUE END: \n"); +#endif + *retptr = value; + *retlen = value_len; + return 1; + } + } + } + } + } + + return 0; +} + +/** + * \param name /Lowercase/ version of the variable name + */ +static int HTTPParseContentTypeHeader(uint8_t *name, size_t name_len, + uint8_t *data, size_t len, uint8_t **retptr, size_t *retlen) +{ + SCEnter(); +#if 0 + printf("DATA START: \n"); + PrintRawDataFp(stdout, data, len); + printf("DATA END: \n"); +#endif + size_t x; + int quote = 0; + + for (x = 0; x < len; x++) { + if (!(isspace(data[x]))) + break; + } + + if (x >= len) + return 0; + + uint8_t *line = data+x; + size_t line_len = len-x; + size_t offset = 0; +#if 0 + printf("LINE START: \n"); + PrintRawDataFp(stdout, line, line_len); + printf("LINE END: \n"); +#endif + for (x = 0 ; x < line_len; x++) { + if (x > 0) { + if (line[x - 1] != '\\' && line[x] == '\"') { + quote++; + } + + if (((line[x - 1] != '\\' && line[x] == ';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) { + uint8_t *token = line + offset; + size_t token_len = x - offset; + + if ((x + 1) == line_len) { + token_len++; + } + + offset = x + 1; + + while (offset < line_len && isspace(line[offset])) { + x++; + offset++; + } +#if 0 + printf("TOKEN START: \n"); + PrintRawDataFp(stdout, token, token_len); + printf("TOKEN END: \n"); +#endif + if (token_len > name_len) { + if (name == NULL || SCMemcmpLowercase(name, token, name_len) == 0) { + uint8_t *value = token + name_len; + size_t value_len = token_len - name_len; + + if (value[0] == '\"') { + value++; + value_len--; + } + if (value[value_len-1] == '\"') { + value_len--; + } +#if 0 + printf("VALUE START: \n"); + PrintRawDataFp(stdout, value, value_len); + printf("VALUE END: \n"); +#endif + *retptr = value; + *retlen = value_len; + return 1; + } + } + } + } + } + + return 0; +} + +static int HTTPStoreFileNameType(Flow *f, uint8_t *filename, size_t filename_len, + uint8_t *filetype, size_t filetype_len) +{ + if (filename == NULL) { + SCReturnInt(-1); + } + + int i = 0; + FlowFileContainer *ffc = NULL; + + SCMutexLock(&f->files_m); + { + /* We have to add/update the file */ + SCLogDebug("Adding file entry to flow"); + + if (f->files == NULL) { + ffc = FlowFileContainerAlloc(); + if (ffc == NULL) { + goto end; + } + f->files = ffc; + } else { + /* TODO: else append chunk, update things...*/ + ffc = f->files; + } + + FlowFile *cur_file = FlowFileContainerRetrieve(ffc, ALPROTO_HTTP, filename, + filename_len); + SCLogDebug("cur_file %p", cur_file); + + if (cur_file == NULL) { + cur_file = FlowFileAlloc(); + if (cur_file == NULL) { + goto end; + } + + cur_file->name = SCMalloc(filename_len); + if (cur_file->name == NULL) { + /** \todo remove cur_file */ + goto end; + } + memcpy(cur_file->name, filename, filename_len); + cur_file->name_len = filename_len; + + /* find the ext portion */ + for (i = filename_len - 2; i >= 0 && filename[i] != '.'; i--); + SCLogDebug("i %d", i); + if (filename[i] == '.') { + cur_file->ext = &cur_file->name[++i]; + cur_file->ext_len = filename_len - i; +#if 0 + printf("EXT START: \n"); + PrintRawDataFp(stdout, cur_file->ext, cur_file->ext_len); + printf("EXT END: \n"); +#endif + } + + if (filetype != NULL) { + cur_file->proto_type = SCMalloc(filetype_len); + if (cur_file->proto_type == NULL) { + goto end; + } + + memcpy(cur_file->proto_type, filetype, filetype_len); + cur_file->proto_type_len = filetype_len; + } + + cur_file->alproto = ALPROTO_HTTP; + SCLogDebug("Added"); + FlowFileContainerAdd(ffc, cur_file); + /* cur_file->ext = get extension */ + } + } +end: + SCMutexUnlock(&f->files_m); + SCReturnInt(0); +} + +#define C_D_HDR "content-disposition:" +#define C_D_HDR_LEN 20 +#define C_T_HDR "content-type:" +#define C_T_HDR_LEN 13 + /** * \brief Function callback to append chunks for Requests * \param d pointer to the htp_tx_data_t structure (a chunk from htp lib) @@ -744,10 +998,12 @@ static int HTPCallbackRequestUriNormalize(htp_connp_t *c) int HTPCallbackRequestBodyData(htp_tx_data_t *d) { SCEnter(); - const char *GROUP_DELIM = ";\r\n"; - const char *FIELD_DELIM = ":= "; HtpState *hstate = (HtpState *)d->tx->connp->user_data; + if (hstate == NULL) { + SCReturnInt(HOOK_ERROR); + } + SCLogDebug("New response body data available at %p -> %p -> %p, bodylen " "%"PRIu32"", hstate, d, d->data, (uint32_t)d->len); @@ -762,53 +1018,37 @@ int HTPCallbackRequestBodyData(htp_tx_data_t *d) htud->body.operation = HTP_BODY_NONE; htp_header_t *cl = table_getc(d->tx->request_headers, "content-length"); - if (cl != NULL) + if (cl != NULL) { htud->content_len = htp_parse_content_length(cl->value); + SCLogDebug("content_len %"PRIu32, htud->content_len); + } else { + SCLogDebug("no content_len header"); + } htp_header_t *h = (htp_header_t *)table_getc(d->tx->request_headers, "Content-Type"); if (h != NULL && bstr_len(h->value) > 0) { - uint8_t *content_type = (uint8_t*) SCMalloc(bstr_len(h->value)); - if (content_type == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Could not allocate memory for content type"); - exit(EXIT_FAILURE); - } - memcpy(content_type, (uint8_t*) bstr_ptr(h->value), bstr_len(h->value)); - - char *tok = NULL; - char *ftok = NULL; - char *lctx1 = NULL; - char *lctx2 = NULL; - - tok = strtok_r((char *) content_type, GROUP_DELIM, &lctx1); - if (tok == NULL) { - SCLogWarning(SC_ERR_INVALID_VALUE, "Malformed content-type field (null)"); - } else { - htud->contenttype = SCStrdup(tok); - htud->contenttype_len = strlen(tok); - - if (strcasecmp("multipart/form-data", tok) == 0) { - /* We have a form, let's see the boundary */ - tok = strtok_r(NULL, GROUP_DELIM, &lctx1); - while (tok != NULL) { - ftok = strtok_r(tok, FIELD_DELIM, &lctx2); - if (ftok == NULL) { - continue; - } - if (strcasecmp("boundary", ftok) == 0) { - ftok = strtok_r(NULL, FIELD_DELIM, &lctx2); - if (ftok == NULL) { - continue; - } - htud->boundary = SCStrdup(ftok); - htud->boundary_len = strlen(ftok); - htud->flags |= HTP_BOUNDARY_SET; - } - tok = strtok_r(NULL, GROUP_DELIM, &lctx1); - } + uint8_t *boundary = NULL; + size_t boundary_len = 0; + + int r = HTTPParseContentTypeHeader((uint8_t *)"boundary=", 9, + (uint8_t *) bstr_ptr(h->value), bstr_len(h->value), + &boundary, &boundary_len); + if (r == 1) { +#if 0 + printf("BOUNDARY START: \n"); + PrintRawDataFp(stdout, boundary, boundary_len); + printf("BOUNDARY END: \n"); +#endif + htud->boundary = SCMalloc(boundary_len); + if (htud->boundary == NULL) { + goto end; } + htud->boundary_len = boundary_len; + memcpy(htud->boundary, boundary, boundary_len); + + htud->flags |= HTP_BOUNDARY_SET; } - SCFree(content_type); } /* Set the user data for handling body chunks on this transaction */ @@ -847,7 +1087,7 @@ int HTPCallbackRequestBodyData(htp_tx_data_t *d) if (htud->flags & HTP_BOUNDARY_SET) { /* Checkout the boundaries */ - if ( !(htud->flags & HTP_BOUNDARY_OPEN)) { + if (!(htud->flags & HTP_BOUNDARY_OPEN)) { HtpBodyChunk *cur = htud->body.first; uint8_t *chunks_buffer = NULL; int32_t chunks_buffer_len = 0; @@ -855,159 +1095,136 @@ int HTPCallbackRequestBodyData(htp_tx_data_t *d) //TODO: of chunks and append only 1 big chunk while (cur != NULL) { chunks_buffer_len += cur->len; - if ( (chunks_buffer = SCRealloc(chunks_buffer, chunks_buffer_len)) == NULL) { + if ((chunks_buffer = SCRealloc(chunks_buffer, chunks_buffer_len)) == NULL) { goto end; } memcpy(chunks_buffer + chunks_buffer_len - cur->len, cur->data, cur->len); cur = cur->next; } - //PrintRawDataFp(stdout, chunks_buffer, chunks_buffer_len); + if (chunks_buffer != NULL) { - char *expected_boundary = (char*)SCMalloc(htud->boundary_len + 4); + //PrintRawDataFp(stdout, chunks_buffer, chunks_buffer_len); + + size_t expected_boundary_len = htud->boundary_len + 2; + uint8_t *expected_boundary = (uint8_t *)SCMalloc(expected_boundary_len); if (expected_boundary == NULL) { goto end; } - expected_boundary[0]='-'; - expected_boundary[1]='-'; - strncat(expected_boundary + 2, (char *)htud->boundary, htud->boundary_len + 4); + memset(expected_boundary, '-', expected_boundary_len); + memcpy(expected_boundary + 2, htud->boundary, htud->boundary_len); - char *expected_boundary_end = (char*)SCMalloc(htud->boundary_len + 6); + size_t expected_boundary_end_len = htud->boundary_len + 4; + uint8_t *expected_boundary_end = (uint8_t *)SCMalloc(expected_boundary_end_len); if (expected_boundary_end == NULL) { goto end; } - expected_boundary_end[0]='-'; - expected_boundary_end[1]='-'; - strncat(expected_boundary_end + 2, (char *)htud->boundary, htud->boundary_len + 4); - strncat(expected_boundary_end, "--", htud->boundary_len + 6); + memset(expected_boundary_end, '-', expected_boundary_end_len); + memcpy(expected_boundary_end + 2, htud->boundary, htud->boundary_len); uint8_t *filename = NULL; + size_t filename_len = 0; uint8_t *filetype = NULL; - - uint8_t *header_start = Bs2bmSearch(chunks_buffer, chunks_buffer_len, (uint8_t *) expected_boundary, strlen(expected_boundary)); - uint8_t *header_end = Bs2bmSearch(chunks_buffer, chunks_buffer_len, (uint8_t *)"\r\n\r\n", strlen("\r\n\r\n")); - uint8_t *form_end = Bs2bmSearch(chunks_buffer, chunks_buffer_len, (uint8_t *) expected_boundary_end, strlen(expected_boundary_end)); - - SCLogDebug("Expected boundary: %s", expected_boundary); - SCLogDebug("Expected boundary_end: %s", expected_boundary_end); - + size_t filetype_len = 0; + + uint8_t *header_start = Bs2bmSearch(chunks_buffer, chunks_buffer_len, + expected_boundary, expected_boundary_len); + uint8_t *header_end = Bs2bmSearch(chunks_buffer, chunks_buffer_len, + (uint8_t *)"\r\n\r\n", 4); + uint8_t *form_end = Bs2bmSearch(chunks_buffer, chunks_buffer_len, + expected_boundary_end, expected_boundary_end_len); uint8_t *header = NULL; while (header_start != NULL && header_end != NULL && (header_end != form_end) && header_start < chunks_buffer + chunks_buffer_len && - header_end < chunks_buffer + chunks_buffer_len && header_start < header_end) { - header = SCMalloc(sizeof(header_end - header_start) + 4); - memcpy(header, header_start, header_end - header_start); - header[header_end - header_start] = '\0'; - header[1 + header_end - header_start] = '\0'; + header_end < chunks_buffer + chunks_buffer_len && header_start < header_end) + { + int header_len = header_end - header_start; + SCLogDebug("header_len %d", header_len); - /* + header = header_start + (expected_boundary_len + 2); // + for 0d 0a + header_len -= (expected_boundary_len + 2); +#if 0 printf("HEADER START: \n"); - PrintRawDataFp(stdout, header, header_end - header_start); + PrintRawDataFp(stdout, header, header_len); printf("HEADER END: \n"); - */ - - char *ftok2 = NULL; - char *tok2 = NULL; - char *ctx1 = NULL; - char *ctx2 = NULL; - char *field = NULL; - tok2 = strtok_r((char *) header, GROUP_DELIM, &ctx1); - if (tok2 == NULL) { - SCLogWarning(SC_ERR_INVALID_VALUE, "Expecting Boundary headers"); - } else { - SCLogDebug("Token: %s", tok2); - if (tok2 != NULL && strcasecmp(expected_boundary, tok2) == 0) { - - tok2 = strtok_r(NULL, GROUP_DELIM, &ctx1); - /* We have the boundary! Extract filename, type, and so on */ - while (tok2 != NULL && strlen(tok2) > 0) { - SCLogDebug("TOKEN: %s", tok2); - field = SCStrdup(tok2); - ftok2 = strtok_r(field, FIELD_DELIM, &ctx2); - while (ftok2 != NULL && strlen(ftok2) > 0) { - if(strcasecmp("filename", ftok2) == 0) { - ftok2 = strtok_r(NULL, FIELD_DELIM, &ctx2); - if (ftok2 != NULL) { - filename = SCStrdup(ftok2); - SCLogDebug("got filename %s", filename); - } - } else if(strcasecmp("Content-Type", ftok2) == 0) { - ftok2 = strtok_r(NULL, FIELD_DELIM, &ctx2); - if (ftok2 != NULL) { - filetype = SCStrdup(ftok2); - SCLogDebug("got proto filetype %s", filetype); - } - } else { - SCLogDebug("-> ftok2 %s len %d", ftok2, (int)strlen(ftok2)); - } - ftok2 = strtok_r(NULL, FIELD_DELIM, &ctx2); - } - //SCFree(field); - tok2 = strtok_r(NULL, GROUP_DELIM, &ctx1); - } - } - //exit(EXIT_FAILURE); - } - if (filename != NULL) { - int i = 0; - SCMutexLock(&hstate->f->files_m); - FlowFileContainer *ffc = NULL; - /* We have to add/update the file */ - SCLogDebug("Adding file entry to flow: %s", filename); - FlowFile *cur_file = NULL; - if (hstate->f->files == NULL) { - ffc = FlowFileContainerAlloc(); - if (ffc == NULL) { - SCMutexUnlock(&hstate->f->files_m); - goto end; - } - hstate->f->files = ffc; - +#endif + while (header_len > 0) { + uint8_t *next_line = Bs2bmSearch(header, header_len, (uint8_t *)"\r\n", 2); + uint8_t *line = header; + size_t line_len; + if (next_line == NULL) { + line_len = header_len; } else { - /* TODO: else append chunk, update things...*/ - ffc = hstate->f->files; + line_len = next_line - header; } - cur_file = FlowFileContainerRetrieve(ffc, filename, ALPROTO_HTTP, filetype); - if (cur_file == NULL) { - cur_file = FlowFileAlloc(); - cur_file->name = filename; - cur_file->name_len = strlen((char *)filename); - for (i = strlen((char *)filename) - 1; i >= 0 && filename[i] != '.'; i--); - if (filename[i] == '.') { - cur_file->ext = SCStrdup((char *)&filename[i]); - printf("File ext: %s\n", cur_file->ext); +#if 0 + printf("LINE START: \n"); + PrintRawDataFp(stdout, line, line_len); + printf("LINE END: \n"); +#endif + SCLogDebug("line len %"PRIuMAX, (uintmax_t)line_len); + if (line_len >= C_D_HDR_LEN && + SCMemcmpLowercase(C_D_HDR, line, C_D_HDR_LEN) == 0) + { + uint8_t *value = line + C_D_HDR_LEN; + size_t value_len = line_len - C_D_HDR_LEN; + + /* parse content-disposition */ + int r = HTTPParseContentDispositionHeader((uint8_t *)"filename=", 9, + value, value_len, &filename, &filename_len); + if (r == 1) { +#if 0 + printf("FILENAME START: \n"); + PrintRawDataFp(stdout, filename, filename_len); + printf("FILENAME END: \n"); +#endif } - - if (filetype != NULL) { - cur_file->proto_type = filetype; - cur_file->proto_type_len = strlen((char *)filetype); + } else if (line_len >= C_T_HDR_LEN && + SCMemcmpLowercase(C_T_HDR, line, C_T_HDR_LEN) == 0) + { + SCLogDebug("content-type line"); + uint8_t *value = line + C_T_HDR_LEN; + size_t value_len = line_len - C_T_HDR_LEN; + + int r = HTTPParseContentTypeHeader(NULL, 0, + value, value_len, &filetype, &filetype_len); + if (r == 1) { +#if 0 + printf("FILETYPE START: \n"); + PrintRawDataFp(stdout, filetype, filetype_len); + printf("FILETYPE END: \n"); +#endif } - cur_file->alproto = ALPROTO_HTTP; - SCLogDebug("Added"); - FlowFileContainerAdd(ffc, cur_file); - /* cur_file->ext = get extension */ } - SCMutexUnlock(&hstate->f->files_m); - } else if (filetype != NULL) { - /* We got a filetype but not the name of file, so removing */ - SCFree(filetype); + + if (next_line == NULL) + break; + + header_len -= ((next_line + 2) - header); + header = next_line + 2; + } + + if (filename != NULL) { + HTTPStoreFileNameType(hstate->f, filename, filename_len, + filetype, filetype_len); } + filename = NULL; filetype = NULL; /* Search next boundary entry after the start of body */ if ( (form_end == NULL && header_end + 4 < chunks_buffer + chunks_buffer_len) || (form_end != NULL && header_end != NULL && header_end + 4 < form_end)) { uint32_t cursizeread = header_end - chunks_buffer; - header_start = Bs2bmSearch(header_end + 4, chunks_buffer_len - (cursizeread + 4), (uint8_t *) expected_boundary, strlen(expected_boundary)); + header_start = Bs2bmSearch(header_end + 4, chunks_buffer_len - (cursizeread + 4), (uint8_t *) expected_boundary, expected_boundary_len); header_end = Bs2bmSearch(header_end + 4, chunks_buffer_len - (cursizeread + 4), (uint8_t *) "\r\n\r\n", strlen("\r\n\r\n")); } } - if (header != NULL) { - SCFree(header); - header = NULL; - } + + SCFree(expected_boundary); + SCFree(expected_boundary_end); + SCFree(chunks_buffer); } } } diff --git a/src/detect-fileext.c b/src/detect-fileext.c index 5568b92fc1..3c3fe08c54 100644 --- a/src/detect-fileext.c +++ b/src/detect-fileext.c @@ -42,6 +42,7 @@ #include "util-unittest.h" #include "util-unittest-helper.h" #include "util-spm-bm.h" +#include "util-print.h" #include "app-layer.h" @@ -113,20 +114,26 @@ int DetectFileextMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, SCEnter(); int ret = 0; - DetectFileextData *fileext = m->ctx; + DetectFileextData *fileext = (DetectFileextData *)m->ctx; SCMutexLock(&f->files_m); if (f->files != NULL && f->files->cnt > 0) { FlowFile *file = f->files->start; - for (; file != NULL; file = file->next) { - if (file != NULL && file->ext != NULL && - BoyerMooreNocase(fileext->ext, fileext->len, file->ext, - file->ext_len, fileext->bm_ctx->bmGs, fileext->bm_ctx->bmBc) != NULL) - { - ret = 1; - SCLogDebug("File ext %s found", file->ext); - /* Stop searching */ - break; + + for (; file != NULL; file = file->next) + { + if (file->ext != NULL) { + //PrintRawDataFp(stdout, file->ext, file->ext_len); + + if (BoyerMooreNocase(fileext->ext, fileext->len, file->ext, + file->ext_len, fileext->bm_ctx->bmGs, + fileext->bm_ctx->bmBc) != NULL) + { + ret = 1; + SCLogDebug("File ext found"); + /* Stop searching */ + break; + } } } } diff --git a/src/flow-file.c b/src/flow-file.c index 6581c7427c..35592c7586 100644 --- a/src/flow-file.c +++ b/src/flow-file.c @@ -29,9 +29,15 @@ #include "flow-file.h" #include "util-hash.h" #include "util-debug.h" +#include "util-memcmp.h" - -FlowFileContainer *FlowFileContainerAlloc() { +/** + * \brief allocate a FlowFileContainer + * + * \retval new newly allocated FlowFileContainer + * \retval NULL error + */ +FlowFileContainer *FlowFileContainerAlloc(void) { FlowFileContainer *new = SCMalloc(sizeof(FlowFileContainer)); if (new == NULL) { SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem"); @@ -43,21 +49,35 @@ FlowFileContainer *FlowFileContainerAlloc() { return new; } +/** + * \brief Recycle a FlowFileContainer + * + * \param ffc FlowFileContainer + */ void FlowFileContainerRecycle(FlowFileContainer *ffc) { - FlowFile *ptr = ffc->start; + if (ffc == NULL) + return; + + FlowFile *cur = ffc->start; FlowFile *next = NULL; - for (;ptr != NULL && ffc->cnt > 0; ptr = next) { - next = ptr->next; - FlowFileFree(ptr); + for (;cur != NULL && ffc->cnt > 0; cur = next) { + next = cur->next; + FlowFileFree(cur); ffc->cnt--; } ffc->start = ffc->end = NULL; ffc->cnt = 0; } +/** + * \brief Free a FlowFileContainer + * + * \param ffc FlowFileContainer + */ void FlowFileContainerFree(FlowFileContainer *ffc) { if (ffc == NULL) return; + FlowFile *ptr = ffc->start; FlowFile *next = NULL; for (;ptr != NULL && ffc->cnt > 0; ptr = next) { @@ -70,28 +90,33 @@ void FlowFileContainerFree(FlowFileContainer *ffc) { SCFree(ffc); } -FlowFileChunk *FlowFileChunkAlloc() { +FlowFileChunk *FlowFileChunkAlloc(void) { FlowFileChunk *new = SCMalloc(sizeof(FlowFileChunk)); if (new == NULL) { SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem"); return NULL; } memset(new, 0, sizeof(new)); + return new; } void FlowFileChunkFree(FlowFileChunk *ffc) { + if (ffc == NULL) + return; + //TODO: To implement SCFree(ffc); } -FlowFile *FlowFileAlloc() { +FlowFile *FlowFileAlloc(void) { FlowFile *new = SCMalloc(sizeof(FlowFile)); if (new == NULL) { SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem"); return NULL; } memset(new, 0, sizeof(new)); + new->state = FLOWFILE_STATE_EMPTY; new->name = NULL; new->ext = NULL; @@ -100,10 +125,11 @@ FlowFile *FlowFileAlloc() { } void FlowFileFree(FlowFile *ff) { + if (ff == NULL) + return; + if (ff->name != NULL) SCFree(ff->name); - if (ff->ext != NULL) - SCFree(ff->ext); SCFree(ff); } @@ -117,16 +143,24 @@ void FlowFileContainerAdd(FlowFileContainer *ffc, FlowFile *ff) { ffc->cnt += 1; } -FlowFile *FlowFileContainerRetrieve(FlowFileContainer *ffc, uint8_t *name, uint16_t alproto, uint8_t *proto_type) { +FlowFile *FlowFileContainerRetrieve(FlowFileContainer *ffc, uint16_t alproto, + uint8_t *name, uint16_t name_len) //, uint8_t *type, uint16_t type_len) +{ FlowFile *ptr = ffc->start; + if (ffc->cnt > 0) { while (ptr != NULL) { - if ( (strcmp((char *)ptr->name, (char *)name) == 0) && ptr->alproto == alproto && (!proto_type || strcmp((char *)ptr->proto_type, (char *)proto_type) == 0)) { + if (ptr->alproto == alproto && + name_len == ptr->name_len && + SCMemcmp(ptr->name, name, name_len) == 0) + { return ptr; } + ptr = ptr->next; } } + return NULL; } diff --git a/src/flow-file.h b/src/flow-file.h index 6c7de2ebf2..ad67b5c2a1 100644 --- a/src/flow-file.h +++ b/src/flow-file.h @@ -41,14 +41,14 @@ typedef uint8_t FlowFileHash; typedef struct _FlowFileChunk { uint8_t *buf; - uint32_t *len; + uint32_t len; struct _FlowFileChunk *next; } FlowFileChunk; typedef struct _FlowFile { uint8_t *name; uint16_t name_len; - uint8_t *ext; + uint8_t *ext; /* ptr to extension portion in "name" */ uint16_t ext_len; uint8_t *real_type; uint16_t real_type_len; @@ -84,7 +84,8 @@ FlowFile *FlowFileAlloc(); void FlowFileFree(FlowFile *); void FlowFileContainerAdd(FlowFileContainer *, FlowFile *); -FlowFile *FlowFileContainerRetrieve(FlowFileContainer *, uint8_t *, uint16_t, uint8_t *); +//FlowFile *FlowFileContainerRetrieve(FlowFileContainer *, uint8_t *, uint16_t, uint8_t *); +FlowFile *FlowFileContainerRetrieve(FlowFileContainer *, uint16_t, uint8_t *, uint16_t); FlowFile *FlowFileAppendChunk(FlowFile *, FlowFileChunk *); #endif /* __FLOW_FILE_H__ */