Handle all strings as raw strings in HTTP content-type and content-disposition header parsing.

remotes/origin/master-1.2.x
Victor Julien 14 years ago
parent 222bc6e935
commit 4537f889ef

@ -67,6 +67,8 @@
#include "conf.h" #include "conf.h"
#include "util-memcmp.h"
/** Need a linked list in order to keep track of these */ /** Need a linked list in order to keep track of these */
typedef struct HTPCfgRec_ { typedef struct HTPCfgRec_ {
htp_cfg_t *cfg; htp_cfg_t *cfg;
@ -736,6 +738,258 @@ static int HTPCallbackRequestUriNormalize(htp_connp_t *c)
} }
#endif #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 * \brief Function callback to append chunks for Requests
* \param d pointer to the htp_tx_data_t structure (a chunk from htp lib) * \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) int HTPCallbackRequestBodyData(htp_tx_data_t *d)
{ {
SCEnter(); SCEnter();
const char *GROUP_DELIM = ";\r\n";
const char *FIELD_DELIM = ":= ";
HtpState *hstate = (HtpState *)d->tx->connp->user_data; 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 " SCLogDebug("New response body data available at %p -> %p -> %p, bodylen "
"%"PRIu32"", hstate, d, d->data, (uint32_t)d->len); "%"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; htud->body.operation = HTP_BODY_NONE;
htp_header_t *cl = table_getc(d->tx->request_headers, "content-length"); 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); 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, htp_header_t *h = (htp_header_t *)table_getc(d->tx->request_headers,
"Content-Type"); "Content-Type");
if (h != NULL && bstr_len(h->value) > 0) { if (h != NULL && bstr_len(h->value) > 0) {
uint8_t *content_type = (uint8_t*) SCMalloc(bstr_len(h->value)); uint8_t *boundary = NULL;
if (content_type == NULL) { size_t boundary_len = 0;
SCLogError(SC_ERR_MEM_ALLOC, "Could not allocate memory for content type");
exit(EXIT_FAILURE); int r = HTTPParseContentTypeHeader((uint8_t *)"boundary=", 9,
} (uint8_t *) bstr_ptr(h->value), bstr_len(h->value),
memcpy(content_type, (uint8_t*) bstr_ptr(h->value), bstr_len(h->value)); &boundary, &boundary_len);
if (r == 1) {
char *tok = NULL; #if 0
char *ftok = NULL; printf("BOUNDARY START: \n");
char *lctx1 = NULL; PrintRawDataFp(stdout, boundary, boundary_len);
char *lctx2 = NULL; printf("BOUNDARY END: \n");
#endif
tok = strtok_r((char *) content_type, GROUP_DELIM, &lctx1); htud->boundary = SCMalloc(boundary_len);
if (tok == NULL) { if (htud->boundary == NULL) {
SCLogWarning(SC_ERR_INVALID_VALUE, "Malformed content-type field (null)"); goto end;
} 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);
}
} }
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 */ /* 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) { if (htud->flags & HTP_BOUNDARY_SET) {
/* Checkout the boundaries */ /* Checkout the boundaries */
if ( !(htud->flags & HTP_BOUNDARY_OPEN)) { if (!(htud->flags & HTP_BOUNDARY_OPEN)) {
HtpBodyChunk *cur = htud->body.first; HtpBodyChunk *cur = htud->body.first;
uint8_t *chunks_buffer = NULL; uint8_t *chunks_buffer = NULL;
int32_t chunks_buffer_len = 0; 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 //TODO: of chunks and append only 1 big chunk
while (cur != NULL) { while (cur != NULL) {
chunks_buffer_len += cur->len; 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; goto end;
} }
memcpy(chunks_buffer + chunks_buffer_len - cur->len, cur->data, cur->len); memcpy(chunks_buffer + chunks_buffer_len - cur->len, cur->data, cur->len);
cur = cur->next; cur = cur->next;
} }
//PrintRawDataFp(stdout, chunks_buffer, chunks_buffer_len);
if (chunks_buffer != NULL) { 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) { if (expected_boundary == NULL) {
goto end; goto end;
} }
expected_boundary[0]='-'; memset(expected_boundary, '-', expected_boundary_len);
expected_boundary[1]='-'; memcpy(expected_boundary + 2, htud->boundary, htud->boundary_len);
strncat(expected_boundary + 2, (char *)htud->boundary, htud->boundary_len + 4);
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) { if (expected_boundary_end == NULL) {
goto end; goto end;
} }
expected_boundary_end[0]='-'; memset(expected_boundary_end, '-', expected_boundary_end_len);
expected_boundary_end[1]='-'; memcpy(expected_boundary_end + 2, htud->boundary, htud->boundary_len);
strncat(expected_boundary_end + 2, (char *)htud->boundary, htud->boundary_len + 4);
strncat(expected_boundary_end, "--", htud->boundary_len + 6);
uint8_t *filename = NULL; uint8_t *filename = NULL;
size_t filename_len = 0;
uint8_t *filetype = NULL; uint8_t *filetype = NULL;
size_t filetype_len = 0;
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 *header_start = Bs2bmSearch(chunks_buffer, chunks_buffer_len,
uint8_t *form_end = Bs2bmSearch(chunks_buffer, chunks_buffer_len, (uint8_t *) expected_boundary_end, strlen(expected_boundary_end)); expected_boundary, expected_boundary_len);
uint8_t *header_end = Bs2bmSearch(chunks_buffer, chunks_buffer_len,
SCLogDebug("Expected boundary: %s", expected_boundary); (uint8_t *)"\r\n\r\n", 4);
SCLogDebug("Expected boundary_end: %s", expected_boundary_end); uint8_t *form_end = Bs2bmSearch(chunks_buffer, chunks_buffer_len,
expected_boundary_end, expected_boundary_end_len);
uint8_t *header = NULL; uint8_t *header = NULL;
while (header_start != NULL && header_end != NULL && while (header_start != NULL && header_end != NULL &&
(header_end != form_end) && (header_end != form_end) &&
header_start < chunks_buffer + chunks_buffer_len && header_start < chunks_buffer + chunks_buffer_len &&
header_end < chunks_buffer + chunks_buffer_len && header_start < header_end) { 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); int header_len = header_end - header_start;
header[header_end - header_start] = '\0'; SCLogDebug("header_len %d", header_len);
header[1 + header_end - header_start] = '\0';
/* header = header_start + (expected_boundary_len + 2); // + for 0d 0a
header_len -= (expected_boundary_len + 2);
#if 0
printf("HEADER START: \n"); printf("HEADER START: \n");
PrintRawDataFp(stdout, header, header_end - header_start); PrintRawDataFp(stdout, header, header_len);
printf("HEADER END: \n"); printf("HEADER END: \n");
*/ #endif
while (header_len > 0) {
char *ftok2 = NULL; uint8_t *next_line = Bs2bmSearch(header, header_len, (uint8_t *)"\r\n", 2);
char *tok2 = NULL; uint8_t *line = header;
char *ctx1 = NULL; size_t line_len;
char *ctx2 = NULL; if (next_line == NULL) {
char *field = NULL; line_len = header_len;
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;
} else { } else {
/* TODO: else append chunk, update things...*/ line_len = next_line - header;
ffc = hstate->f->files;
} }
cur_file = FlowFileContainerRetrieve(ffc, filename, ALPROTO_HTTP, filetype); #if 0
if (cur_file == NULL) { printf("LINE START: \n");
cur_file = FlowFileAlloc(); PrintRawDataFp(stdout, line, line_len);
cur_file->name = filename; printf("LINE END: \n");
cur_file->name_len = strlen((char *)filename); #endif
for (i = strlen((char *)filename) - 1; i >= 0 && filename[i] != '.'; i--); SCLogDebug("line len %"PRIuMAX, (uintmax_t)line_len);
if (filename[i] == '.') { if (line_len >= C_D_HDR_LEN &&
cur_file->ext = SCStrdup((char *)&filename[i]); SCMemcmpLowercase(C_D_HDR, line, C_D_HDR_LEN) == 0)
printf("File ext: %s\n", cur_file->ext); {
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
} }
} else if (line_len >= C_T_HDR_LEN &&
if (filetype != NULL) { SCMemcmpLowercase(C_T_HDR, line, C_T_HDR_LEN) == 0)
cur_file->proto_type = filetype; {
cur_file->proto_type_len = strlen((char *)filetype); 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) { if (next_line == NULL)
/* We got a filetype but not the name of file, so removing */ break;
SCFree(filetype);
header_len -= ((next_line + 2) - header);
header = next_line + 2;
}
if (filename != NULL) {
HTTPStoreFileNameType(hstate->f, filename, filename_len,
filetype, filetype_len);
} }
filename = NULL; filename = NULL;
filetype = NULL; filetype = NULL;
/* Search next boundary entry after the start of body */ /* 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)) { 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; 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")); 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); SCFree(expected_boundary);
header = NULL; SCFree(expected_boundary_end);
} SCFree(chunks_buffer);
} }
} }
} }

@ -42,6 +42,7 @@
#include "util-unittest.h" #include "util-unittest.h"
#include "util-unittest-helper.h" #include "util-unittest-helper.h"
#include "util-spm-bm.h" #include "util-spm-bm.h"
#include "util-print.h"
#include "app-layer.h" #include "app-layer.h"
@ -113,20 +114,26 @@ int DetectFileextMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
SCEnter(); SCEnter();
int ret = 0; int ret = 0;
DetectFileextData *fileext = m->ctx; DetectFileextData *fileext = (DetectFileextData *)m->ctx;
SCMutexLock(&f->files_m); SCMutexLock(&f->files_m);
if (f->files != NULL && f->files->cnt > 0) { if (f->files != NULL && f->files->cnt > 0) {
FlowFile *file = f->files->start; FlowFile *file = f->files->start;
for (; file != NULL; file = file->next) {
if (file != NULL && file->ext != NULL && for (; file != NULL; file = file->next)
BoyerMooreNocase(fileext->ext, fileext->len, file->ext, {
file->ext_len, fileext->bm_ctx->bmGs, fileext->bm_ctx->bmBc) != NULL) if (file->ext != NULL) {
{ //PrintRawDataFp(stdout, file->ext, file->ext_len);
ret = 1;
SCLogDebug("File ext %s found", file->ext); if (BoyerMooreNocase(fileext->ext, fileext->len, file->ext,
/* Stop searching */ file->ext_len, fileext->bm_ctx->bmGs,
break; fileext->bm_ctx->bmBc) != NULL)
{
ret = 1;
SCLogDebug("File ext found");
/* Stop searching */
break;
}
} }
} }
} }

@ -29,9 +29,15 @@
#include "flow-file.h" #include "flow-file.h"
#include "util-hash.h" #include "util-hash.h"
#include "util-debug.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)); FlowFileContainer *new = SCMalloc(sizeof(FlowFileContainer));
if (new == NULL) { if (new == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem"); SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem");
@ -43,21 +49,35 @@ FlowFileContainer *FlowFileContainerAlloc() {
return new; return new;
} }
/**
* \brief Recycle a FlowFileContainer
*
* \param ffc FlowFileContainer
*/
void FlowFileContainerRecycle(FlowFileContainer *ffc) { void FlowFileContainerRecycle(FlowFileContainer *ffc) {
FlowFile *ptr = ffc->start; if (ffc == NULL)
return;
FlowFile *cur = ffc->start;
FlowFile *next = NULL; FlowFile *next = NULL;
for (;ptr != NULL && ffc->cnt > 0; ptr = next) { for (;cur != NULL && ffc->cnt > 0; cur = next) {
next = ptr->next; next = cur->next;
FlowFileFree(ptr); FlowFileFree(cur);
ffc->cnt--; ffc->cnt--;
} }
ffc->start = ffc->end = NULL; ffc->start = ffc->end = NULL;
ffc->cnt = 0; ffc->cnt = 0;
} }
/**
* \brief Free a FlowFileContainer
*
* \param ffc FlowFileContainer
*/
void FlowFileContainerFree(FlowFileContainer *ffc) { void FlowFileContainerFree(FlowFileContainer *ffc) {
if (ffc == NULL) if (ffc == NULL)
return; return;
FlowFile *ptr = ffc->start; FlowFile *ptr = ffc->start;
FlowFile *next = NULL; FlowFile *next = NULL;
for (;ptr != NULL && ffc->cnt > 0; ptr = next) { for (;ptr != NULL && ffc->cnt > 0; ptr = next) {
@ -70,28 +90,33 @@ void FlowFileContainerFree(FlowFileContainer *ffc) {
SCFree(ffc); SCFree(ffc);
} }
FlowFileChunk *FlowFileChunkAlloc() { FlowFileChunk *FlowFileChunkAlloc(void) {
FlowFileChunk *new = SCMalloc(sizeof(FlowFileChunk)); FlowFileChunk *new = SCMalloc(sizeof(FlowFileChunk));
if (new == NULL) { if (new == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem"); SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem");
return NULL; return NULL;
} }
memset(new, 0, sizeof(new)); memset(new, 0, sizeof(new));
return new; return new;
} }
void FlowFileChunkFree(FlowFileChunk *ffc) { void FlowFileChunkFree(FlowFileChunk *ffc) {
if (ffc == NULL)
return;
//TODO: To implement //TODO: To implement
SCFree(ffc); SCFree(ffc);
} }
FlowFile *FlowFileAlloc() { FlowFile *FlowFileAlloc(void) {
FlowFile *new = SCMalloc(sizeof(FlowFile)); FlowFile *new = SCMalloc(sizeof(FlowFile));
if (new == NULL) { if (new == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem"); SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem");
return NULL; return NULL;
} }
memset(new, 0, sizeof(new)); memset(new, 0, sizeof(new));
new->state = FLOWFILE_STATE_EMPTY; new->state = FLOWFILE_STATE_EMPTY;
new->name = NULL; new->name = NULL;
new->ext = NULL; new->ext = NULL;
@ -100,10 +125,11 @@ FlowFile *FlowFileAlloc() {
} }
void FlowFileFree(FlowFile *ff) { void FlowFileFree(FlowFile *ff) {
if (ff == NULL)
return;
if (ff->name != NULL) if (ff->name != NULL)
SCFree(ff->name); SCFree(ff->name);
if (ff->ext != NULL)
SCFree(ff->ext);
SCFree(ff); SCFree(ff);
} }
@ -117,16 +143,24 @@ void FlowFileContainerAdd(FlowFileContainer *ffc, FlowFile *ff) {
ffc->cnt += 1; 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; FlowFile *ptr = ffc->start;
if (ffc->cnt > 0) { if (ffc->cnt > 0) {
while (ptr != NULL) { 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; return ptr;
} }
ptr = ptr->next; ptr = ptr->next;
} }
} }
return NULL; return NULL;
} }

@ -41,14 +41,14 @@ typedef uint8_t FlowFileHash;
typedef struct _FlowFileChunk { typedef struct _FlowFileChunk {
uint8_t *buf; uint8_t *buf;
uint32_t *len; uint32_t len;
struct _FlowFileChunk *next; struct _FlowFileChunk *next;
} FlowFileChunk; } FlowFileChunk;
typedef struct _FlowFile { typedef struct _FlowFile {
uint8_t *name; uint8_t *name;
uint16_t name_len; uint16_t name_len;
uint8_t *ext; uint8_t *ext; /* ptr to extension portion in "name" */
uint16_t ext_len; uint16_t ext_len;
uint8_t *real_type; uint8_t *real_type;
uint16_t real_type_len; uint16_t real_type_len;
@ -84,7 +84,8 @@ FlowFile *FlowFileAlloc();
void FlowFileFree(FlowFile *); void FlowFileFree(FlowFile *);
void FlowFileContainerAdd(FlowFileContainer *, 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 *); FlowFile *FlowFileAppendChunk(FlowFile *, FlowFileChunk *);
#endif /* __FLOW_FILE_H__ */ #endif /* __FLOW_FILE_H__ */

Loading…
Cancel
Save