static const uint8_t *DetectEngineSMTPGetBufferForTX(uint64_t tx_id, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Flow *f, File *curr_file, uint8_t flags, uint32_t *buffer_len, uint32_t *stream_start_offset) { SCEnter(); int index = 0; const uint8_t *buffer = NULL; *buffer_len = 0; *stream_start_offset = 0; uint64_t file_size = FileDataSize(curr_file); if (det_ctx->smtp_buffers_list_len == 0) { if (SMTPCreateSpace(det_ctx, 1) < 0) goto end; index = 0; if (det_ctx->smtp_buffers_list_len == 0) { det_ctx->smtp_start_tx_id = tx_id; } det_ctx->smtp_buffers_list_len++; } else { if ((tx_id - det_ctx->smtp_start_tx_id) < det_ctx->smtp_buffers_list_len) { if (det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer_len != 0) { *buffer_len = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer_len; *stream_start_offset = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].offset; buffer = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer; SCReturnPtr(buffer, "uint8_t"); } } else { if (SMTPCreateSpace(det_ctx, (tx_id - det_ctx->smtp_start_tx_id) + 1) < 0) goto end; if (det_ctx->smtp_buffers_list_len == 0) { det_ctx->smtp_start_tx_id = tx_id; } det_ctx->smtp_buffers_list_len++; } index = (tx_id - det_ctx->smtp_start_tx_id); } SCLogDebug("smtp_config.content_limit %u, smtp_config.content_inspect_min_size %u", smtp_config.content_limit, smtp_config.content_inspect_min_size); SCLogDebug("file %p size %"PRIu64", state %d", curr_file, file_size, curr_file->state); /* no new data */ if (curr_file->content_inspected == file_size) { SCLogDebug("no new data"); goto end; } if (file_size == 0) { SCLogDebug("no data to inspect for this transaction"); goto end; } if ((smtp_config.content_limit == 0 || file_size < smtp_config.content_limit) && file_size < smtp_config.content_inspect_min_size && !(flags & STREAM_EOF) && !(curr_file->state > FILE_STATE_OPENED)) { SCLogDebug("we still haven't seen the entire content. " "Let's defer content inspection till we see the " "entire content."); goto end; } StreamingBufferGetDataAtOffset(curr_file->sb, &det_ctx->smtp[index].buffer, &det_ctx->smtp[index].buffer_len, curr_file->content_inspected); det_ctx->smtp[index].offset = curr_file->content_inspected; /* updat inspected tracker */ curr_file->content_inspected = FileDataSize(curr_file); SCLogDebug("content_inspected %"PRIu64", offset %"PRIu64, curr_file->content_inspected, det_ctx->smtp[index].offset); buffer = det_ctx->smtp[index].buffer; *buffer_len = det_ctx->smtp[index].buffer_len; *stream_start_offset = det_ctx->smtp[index].offset; end: SCLogDebug("buffer %p, len %u", buffer, *buffer_len); SCReturnPtr(buffer, "uint8_t"); }
static uint8_t *DetectEngineSMTPGetBufferForTX(uint64_t tx_id, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Flow *f, File *curr_file, uint8_t flags, uint32_t *buffer_len, uint32_t *stream_start_offset) { SCEnter(); int index = 0; uint8_t *buffer = NULL; *buffer_len = 0; *stream_start_offset = 0; FileData *curr_chunk = NULL; if (det_ctx->smtp_buffers_list_len == 0) { if (SMTPCreateSpace(det_ctx, 1) < 0) goto end; index = 0; if (det_ctx->smtp_buffers_list_len == 0) { det_ctx->smtp_start_tx_id = tx_id; } det_ctx->smtp_buffers_list_len++; } else { if ((tx_id - det_ctx->smtp_start_tx_id) < det_ctx->smtp_buffers_list_len) { if (det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer_len != 0) { *buffer_len = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer_len; *stream_start_offset = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].offset; buffer = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer; SCReturnPtr(buffer, "uint8_t"); } } else { if (SMTPCreateSpace(det_ctx, (tx_id - det_ctx->smtp_start_tx_id) + 1) < 0) goto end; if (det_ctx->smtp_buffers_list_len == 0) { det_ctx->smtp_start_tx_id = tx_id; } det_ctx->smtp_buffers_list_len++; } index = (tx_id - det_ctx->smtp_start_tx_id); } SCLogDebug("smtp_config.content_limit %u, smtp_config.content_inspect_min_size %u", smtp_config.content_limit, smtp_config.content_inspect_min_size); SCLogDebug("file %p size %"PRIu64", state %d", curr_file, curr_file->content_len_so_far, curr_file->state); /* no new data */ if (curr_file->content_inspected == curr_file->content_len_so_far) { SCLogDebug("no new data"); goto end; } curr_chunk = curr_file->chunks_head; if (curr_chunk == NULL) { SCLogDebug("no data chunks to inspect for this transaction"); goto end; } if ((smtp_config.content_limit == 0 || curr_file->content_len_so_far < smtp_config.content_limit) && curr_file->content_len_so_far < smtp_config.content_inspect_min_size && !(flags & STREAM_EOF) && !(curr_file->state > FILE_STATE_OPENED)) { SCLogDebug("we still haven't seen the entire content. " "Let's defer content inspection till we see the " "entire content."); goto end; } int first = 1; curr_chunk = curr_file->chunks_head; while (curr_chunk != NULL) { /* see if we can filter out chunks */ if (curr_file->content_inspected > 0) { if (curr_chunk->stream_offset < curr_file->content_inspected) { if ((curr_file->content_inspected - curr_chunk->stream_offset) > smtp_config.content_inspect_window) { curr_chunk = curr_chunk->next; continue; } else { /* include this one */ } } else { /* include this one */ } } if (first) { det_ctx->smtp[index].offset = curr_chunk->stream_offset; first = 0; } /* see if we need to grow the buffer */ if (det_ctx->smtp[index].buffer == NULL || (det_ctx->smtp[index].buffer_len + curr_chunk->len) > det_ctx->smtp[index].buffer_size) { void *ptmp; det_ctx->smtp[index].buffer_size += curr_chunk->len * 2; if ((ptmp = SCRealloc(det_ctx->smtp[index].buffer, det_ctx->smtp[index].buffer_size)) == NULL) { SCFree(det_ctx->smtp[index].buffer); det_ctx->smtp[index].buffer = NULL; det_ctx->smtp[index].buffer_size = 0; det_ctx->smtp[index].buffer_len = 0; goto end; } det_ctx->smtp[index].buffer = ptmp; } memcpy(det_ctx->smtp[index].buffer + det_ctx->smtp[index].buffer_len, curr_chunk->data, curr_chunk->len); det_ctx->smtp[index].buffer_len += curr_chunk->len; curr_chunk = curr_chunk->next; } /* updat inspected tracker */ curr_file->content_inspected = curr_file->chunks_tail->stream_offset + curr_file->chunks_tail->len; SCLogDebug("curr_file->content_inspected now %"PRIu64, curr_file->content_inspected); buffer = det_ctx->smtp[index].buffer; *buffer_len = det_ctx->smtp[index].buffer_len; *stream_start_offset = det_ctx->smtp[index].offset; end: SCLogDebug("buffer %p, len %u", buffer, *buffer_len); SCReturnPtr(buffer, "uint8_t"); }