static void CreateTimeString (const struct timeval *ts, char *str, size_t size) { time_t time = ts->tv_sec; struct tm local_tm; struct tm *t = (struct tm *)SCLocalTime(time, &local_tm); snprintf(str, size, "%02d/%02d/%02d-%02d:%02d:%02d.%06u", t->tm_mon + 1, t->tm_mday, t->tm_year + 1900, t->tm_hour, t->tm_min, t->tm_sec, (uint32_t) ts->tv_usec); }
void SCProfilingKeywordDump(DetectEngineCtx *de_ctx) { int i; FILE *fp; struct timeval tval; struct tm *tms; struct tm local_tm; if (profiling_keyword_enabled == 0) return; gettimeofday(&tval, NULL); tms = SCLocalTime(tval.tv_sec, &local_tm); if (profiling_keywords_output_to_file == 1) { SCLogDebug("file %s mode %s", profiling_file_name, profiling_file_mode); fp = fopen(profiling_file_name, profiling_file_mode); if (fp == NULL) { SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", profiling_file_name, strerror(errno)); return; } } else { fp = stdout; } fprintf(fp, " ----------------------------------------------" "------------------------------------------------------" "----------------------------\n"); fprintf(fp, " Date: %" PRId32 "/%" PRId32 "/%04d -- " "%02d:%02d:%02d\n", tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900, tms->tm_hour,tms->tm_min, tms->tm_sec); /* global stats first */ DoDump(de_ctx->profile_keyword_ctx, fp, "total"); /* per buffer stats next, but only if there are stats to print */ for (i = 0; i < DETECT_SM_LIST_MAX; i++) { int j; uint64_t checks = 0; for (j = 0; j < DETECT_TBLSIZE; j++) { checks += de_ctx->profile_keyword_ctx_per_list[i]->data[j].checks; } if (checks) DoDump(de_ctx->profile_keyword_ctx_per_list[i], fp, DetectSigmatchListEnumToString(i)); } fprintf(fp,"\n"); if (fp != stdout) fclose(fp); SCLogPerf("Done dumping keyword profiling data."); }
/** * \brief Sets up the rule analyzer according to the config * \retval 1 if rule analyzer successfully enabled * \retval 0 if not enabled */ int SetupRuleAnalyzer(void) { ConfNode *conf = ConfGetNode("engine-analysis"); int enabled = 0; if (conf != NULL) { const char *value = ConfNodeLookupChildValue(conf, "rules"); if (value && ConfValIsTrue(value)) { enabled = 1; } else if (value && strcasecmp(value, "warnings-only") == 0) { enabled = 1; rule_warnings_only = 1; } if (enabled) { char *log_dir; log_dir = ConfigGetLogDirectory(); snprintf(log_path, sizeof(log_path), "%s/%s", log_dir, "rules_analysis.txt"); rule_engine_analysis_FD = fopen(log_path, "w"); if (rule_engine_analysis_FD == NULL) { SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", log_path, strerror(errno)); return 0; } SCLogInfo("Engine-Analysis for rules printed to file - %s", log_path); struct timeval tval; struct tm *tms; gettimeofday(&tval, NULL); struct tm local_tm; tms = SCLocalTime(tval.tv_sec, &local_tm); fprintf(rule_engine_analysis_FD, "----------------------------------------------" "---------------------\n"); fprintf(rule_engine_analysis_FD, "Date: %" PRId32 "/%" PRId32 "/%04d -- " "%02d:%02d:%02d\n", tms->tm_mday, tms->tm_mon + 1, tms->tm_year + 1900, tms->tm_hour, tms->tm_min, tms->tm_sec); fprintf(rule_engine_analysis_FD, "----------------------------------------------" "---------------------\n"); /*compile regex's for rule analysis*/ if (PerCentEncodingSetup()== 0) { fprintf(rule_engine_analysis_FD, "Error compiling regex; can't check for percent encoding in normalized http content.\n"); } } } else { SCLogInfo("Conf parameter \"engine-analysis.rules\" not found. " "Defaulting to not printing the rules analysis report."); } if (!enabled) { SCLogInfo("Engine-Analysis for rules disabled in conf file."); return 0; } return 1; }
/* Update the cached time string in cache index N, for the current minute. */ static int UpdateCachedTime(int n, time_t time) { struct tm local_tm; struct tm *t = (struct tm *)SCLocalTime(time, &local_tm); int cached_len = snprintf(cached_local_time[n], MAX_LOCAL_TIME_STRING, "%02d/%02d/%02d-%02d:%02d:", t->tm_mon + 1, t->tm_mday, t->tm_year + 1900, t->tm_hour, t->tm_min); cached_local_time_len[n] = cached_len; /* Store the time of the beginning of the minute. */ last_local_time[n] = time - t->tm_sec; mru_time_slot = n; return t->tm_sec; }
void CreateIsoTimeString (const struct timeval *ts, char *str, size_t size) { time_t time = ts->tv_sec; struct tm local_tm; memset(&local_tm, 0, sizeof(local_tm)); struct tm *t = (struct tm*)SCLocalTime(time, &local_tm); char time_fmt[64] = { 0 }; if (likely(t != NULL)) { strftime(time_fmt, sizeof(time_fmt), "%Y-%m-%dT%H:%M:%S.%%06u%z", t); snprintf(str, size, time_fmt, ts->tv_usec); } else { snprintf(str, size, "ts-error"); } }
/** * \brief Get seconds until a time unit changes. * * \param str String containing time type (minute, hour, etc). * \param epoch Epoch time. * * \retval seconds. */ uint64_t SCGetSecondsUntil (const char *str, time_t epoch) { uint64_t seconds = 0; struct tm tm; memset(&tm, 0, sizeof(tm)); struct tm *tp = (struct tm *)SCLocalTime(epoch, &tm); if (strcmp(str, "minute") == 0) seconds = 60 - tp->tm_sec; else if (strcmp(str, "hour") == 0) seconds = (60 * (60 - tp->tm_min)) + (60 - tp->tm_sec); else if (strcmp(str, "day") == 0) seconds = (3600 * (24 - tp->tm_hour)) + (60 * (60 - tp->tm_min)) + (60 - tp->tm_sec); return seconds; }
/** * \brief Sets up the fast pattern analyzer according to the config. * * \retval 1 If rule analyzer successfully enabled. * \retval 0 If not enabled. */ int SetupFPAnalyzer(void) { int fp_engine_analysis_set = 0; if ((ConfGetBool("engine-analysis.rules-fast-pattern", &fp_engine_analysis_set)) == 0) { return 0; } if (fp_engine_analysis_set == 0) return 0; char *log_dir; log_dir = ConfigGetLogDirectory(); snprintf(log_path, sizeof(log_path), "%s/%s", log_dir, "rules_fast_pattern.txt"); fp_engine_analysis_FD = fopen(log_path, "w"); if (fp_engine_analysis_FD == NULL) { SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", log_path, strerror(errno)); return 0; } SCLogInfo("Engine-Analysis for fast_pattern printed to file - %s", log_path); struct timeval tval; struct tm *tms; gettimeofday(&tval, NULL); struct tm local_tm; tms = SCLocalTime(tval.tv_sec, &local_tm); fprintf(fp_engine_analysis_FD, "----------------------------------------------" "---------------------\n"); fprintf(fp_engine_analysis_FD, "Date: %" PRId32 "/%" PRId32 "/%04d -- " "%02d:%02d:%02d\n", tms->tm_mday, tms->tm_mon + 1, tms->tm_year + 1900, tms->tm_hour, tms->tm_min, tms->tm_sec); fprintf(fp_engine_analysis_FD, "----------------------------------------------" "---------------------\n"); memset(&fp_pattern_stats, 0, sizeof(fp_pattern_stats)); return 1; }
void SCProfilingSghDump(DetectEngineCtx *de_ctx) { FILE *fp; struct timeval tval; struct tm *tms; struct tm local_tm; if (profiling_sghs_enabled == 0) return; gettimeofday(&tval, NULL); tms = SCLocalTime(tval.tv_sec, &local_tm); if (profiling_sghs_output_to_file == 1) { SCLogDebug("file %s mode %s", profiling_file_name, profiling_file_mode); fp = fopen(profiling_file_name, profiling_file_mode); if (fp == NULL) { SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", profiling_file_name, strerror(errno)); return; } } else { fp = stdout; } fprintf(fp, " ----------------------------------------------" "------------------------------------------------------" "----------------------------\n"); fprintf(fp, " Date: %" PRId32 "/%" PRId32 "/%04d -- " "%02d:%02d:%02d\n", tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900, tms->tm_hour,tms->tm_min, tms->tm_sec); DoDump(de_ctx->profile_sgh_ctx, fp, "rule groups"); fprintf(fp,"\n"); if (fp != stdout) fclose(fp); SCLogInfo("Done dumping rulegroup profiling data."); }
/** * \brief Convert epoch time to string pattern. * * This function converts epoch time to a string based on a pattern. * * \param epoch Epoch time. * \param pattern String pattern. * \param str Formated string. * \param size Size of allocated string. * * \retval 0 on success. * \retval 1 on failure. */ int SCTimeToStringPattern (time_t epoch, const char *pattern, char *str, size_t size) { struct tm tm; memset(&tm, 0, sizeof(tm)); struct tm *tp = (struct tm *)SCLocalTime(epoch, &tm); char buffer[PATH_MAX] = { 0 }; if (unlikely(tp == NULL)) { return 1; } int r = strftime(buffer, sizeof(buffer), pattern, tp); if (r == 0) { return 1; } strlcpy(str, buffer, size); return 0; }
int LogStatsLogger(ThreadVars *tv, void *thread_data, const StatsTable *st) { SCEnter(); LogStatsLogThread *aft = (LogStatsLogThread *)thread_data; struct timeval tval; struct tm *tms; gettimeofday(&tval, NULL); struct tm local_tm; tms = SCLocalTime(tval.tv_sec, &local_tm); /* Calculate the Engine uptime */ int up_time = (int)difftime(tval.tv_sec, st->start_time); int sec = up_time % 60; // Seconds in a minute int in_min = up_time / 60; int min = in_min % 60; // Minutes in a hour int in_hours = in_min / 60; int hours = in_hours % 24; // Hours in a day int days = in_hours / 24; MemBufferWriteString(aft->buffer, "----------------------------------------------" "---------------------\n"); MemBufferWriteString(aft->buffer, "Date: %" PRId32 "/%" PRId32 "/%04d -- " "%02d:%02d:%02d (uptime: %"PRId32"d, %02dh %02dm %02ds)\n", tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900, tms->tm_hour, tms->tm_min, tms->tm_sec, days, hours, min, sec); MemBufferWriteString(aft->buffer, "----------------------------------------------" "---------------------\n"); MemBufferWriteString(aft->buffer, "%-25s | %-25s | %-s\n", "Counter", "TM Name", "Value"); MemBufferWriteString(aft->buffer, "----------------------------------------------" "---------------------\n"); /* global stats */ uint32_t u = 0; if (aft->statslog_ctx->flags & LOG_STATS_TOTALS) { for (u = 0; u < st->nstats; u++) { if (st->stats[u].name == NULL) continue; char line[1024]; size_t len = snprintf(line, sizeof(line), "%-25s | %-25s | %-" PRIu64 "\n", st->stats[u].name, st->stats[u].tm_name, st->stats[u].value); /* since we can have many threads, the buffer might not be big enough. * Expand if necessary. */ if (MEMBUFFER_OFFSET(aft->buffer) + len > MEMBUFFER_SIZE(aft->buffer)) { MemBufferExpand(&aft->buffer, OUTPUT_BUFFER_SIZE); } MemBufferWriteString(aft->buffer, "%s", line); } } /* per thread stats */ if (st->tstats != NULL && aft->statslog_ctx->flags & LOG_STATS_THREADS) { /* for each thread (store) */ uint32_t x; for (x = 0; x < st->ntstats; x++) { uint32_t offset = x * st->nstats; /* for each counter */ for (u = offset; u < (offset + st->nstats); u++) { if (st->tstats[u].name == NULL) continue; char line[1024]; size_t len = snprintf(line, sizeof(line), "%-25s | %-25s | %-" PRIu64 "\n", st->tstats[u].name, st->tstats[u].tm_name, st->tstats[u].value); /* since we can have many threads, the buffer might not be big enough. * Expand if necessary. */ if (MEMBUFFER_OFFSET(aft->buffer) + len > MEMBUFFER_SIZE(aft->buffer)) { MemBufferExpand(&aft->buffer, OUTPUT_BUFFER_SIZE); } MemBufferWriteString(aft->buffer, "%s", line); } } } SCMutexLock(&aft->statslog_ctx->file_ctx->fp_mutex); aft->statslog_ctx->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), MEMBUFFER_OFFSET(aft->buffer), aft->statslog_ctx->file_ctx); SCMutexUnlock(&aft->statslog_ctx->file_ctx->fp_mutex); MemBufferReset(aft->buffer); SCReturnInt(0); }
/* Custom format logging */ static void LogHttpLogCustom(LogHttpLogThread *aft, htp_tx_t *tx, const struct timeval *ts, char *srcip, Port sp, char *dstip, Port dp) { LogHttpFileCtx *httplog_ctx = aft->httplog_ctx; uint32_t i; char buf[128]; htp_header_t *h_request_hdr = NULL; htp_header_t *h_response_hdr = NULL; time_t time = ts->tv_sec; struct tm local_tm; struct tm *timestamp = (struct tm *)SCLocalTime(time, &local_tm); for (i = 0; i < httplog_ctx->cf_n; i++) { switch (httplog_ctx->cf_nodes[i]->type){ case LOG_HTTP_CF_LITERAL: /* LITERAL */ PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)httplog_ctx->cf_nodes[i]->data, strlen(httplog_ctx->cf_nodes[i]->data)); break; case LOG_HTTP_CF_TIMESTAMP: /* TIMESTAMP */ if (httplog_ctx->cf_nodes[i]->data == '\0') { strftime(buf, 62, TIMESTAMP_DEFAULT_FORMAT, timestamp); } else { strftime(buf, 62, httplog_ctx->cf_nodes[i]->data, timestamp); } PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)buf,strlen(buf)); break; case LOG_HTTP_CF_TIMESTAMP_U: /* TIMESTAMP USECONDS */ snprintf(buf, 62, "%06u", (unsigned int) ts->tv_usec); PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)buf,strlen(buf)); break; case LOG_HTTP_CF_CLIENT_IP: /* CLIENT IP ADDRESS */ PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)srcip,strlen(srcip)); break; case LOG_HTTP_CF_SERVER_IP: /* SERVER IP ADDRESS */ PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)dstip,strlen(dstip)); break; case LOG_HTTP_CF_CLIENT_PORT: /* CLIENT PORT */ MemBufferWriteString(aft->buffer, "%" PRIu16 "", sp); break; case LOG_HTTP_CF_SERVER_PORT: /* SERVER PORT */ MemBufferWriteString(aft->buffer, "%" PRIu16 "", dp); break; case LOG_HTTP_CF_REQUEST_METHOD: /* METHOD */ if (tx->request_method != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_method), bstr_len(tx->request_method)); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_REQUEST_URI: /* URI */ if (tx->request_uri != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_uri), bstr_len(tx->request_uri)); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_REQUEST_HOST: /* HOSTNAME */ if (tx->parsed_uri != NULL && tx->parsed_uri->hostname != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->parsed_uri->hostname), bstr_len(tx->parsed_uri->hostname)); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_REQUEST_PROTOCOL: /* PROTOCOL */ if (tx->request_protocol != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_protocol), bstr_len(tx->request_protocol)); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_REQUEST_HEADER: /* REQUEST HEADER */ if (tx->request_headers != NULL) { h_request_hdr = table_getc(tx->request_headers, httplog_ctx->cf_nodes[i]->data); } if (h_request_hdr != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(h_request_hdr->value), bstr_len(h_request_hdr->value)); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_RESPONSE_STATUS: /* RESPONSE STATUS */ if (tx->response_status != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->response_status), bstr_len(tx->response_status)); /* Redirect? */ if ((tx->response_status_number > 300) && ((tx->response_status_number) < 303)){ htp_header_t *h_location = table_getc(tx->response_headers, "location"); if (h_location != NULL) { MemBufferWriteString(aft->buffer, "("); PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(h_location->value), bstr_len(h_location->value)); MemBufferWriteString(aft->buffer, ")"); } } } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_RESPONSE_HEADER: /* RESPONSE HEADER */ if (tx->response_headers != NULL) { h_response_hdr = table_getc(tx->response_headers, httplog_ctx->cf_nodes[i]->data); } if (h_response_hdr != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(h_response_hdr->value), bstr_len(h_response_hdr->value)); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_RESPONSE_LEN: /* RESPONSE LEN */ MemBufferWriteString(aft->buffer, "%"PRIuMAX"", (uintmax_t)tx->response_message_len); break; } } MemBufferWriteString(aft->buffer, "\n"); }
void SCProfilingRuleDump(SCProfileDetectCtx *rules_ctx) { uint32_t i; FILE *fp; if (rules_ctx == NULL) return; struct timeval tval; struct tm *tms; if (profiling_output_to_file == 1) { fp = fopen(profiling_file_name, profiling_file_mode); if (fp == NULL) { SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", profiling_file_name, strerror(errno)); return; } } else { fp = stdout; } int summary_size = sizeof(SCProfileSummary) * rules_ctx->size; SCProfileSummary *summary = SCMalloc(summary_size); if (unlikely(summary == NULL)) { SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for profiling summary"); return; } uint32_t count = rules_ctx->size; uint64_t total_ticks = 0; SCLogInfo("Dumping profiling data for %u rules.", count); memset(summary, 0, summary_size); for (i = 0; i < count; i++) { summary[i].sid = rules_ctx->data[i].sid; summary[i].rev = rules_ctx->data[i].rev; summary[i].gid = rules_ctx->data[i].gid; summary[i].ticks = rules_ctx->data[i].ticks_match + rules_ctx->data[i].ticks_no_match; summary[i].checks = rules_ctx->data[i].checks; if (summary[i].ticks > 0) { summary[i].avgticks = (long double)summary[i].ticks / (long double)summary[i].checks; } summary[i].matches = rules_ctx->data[i].matches; summary[i].max = rules_ctx->data[i].max; summary[i].ticks_match = rules_ctx->data[i].ticks_match; summary[i].ticks_no_match = rules_ctx->data[i].ticks_no_match; if (summary[i].ticks_match > 0) { summary[i].avgticks_match = (long double)summary[i].ticks_match / (long double)summary[i].matches; } if (summary[i].ticks_no_match > 0) { summary[i].avgticks_no_match = (long double)summary[i].ticks_no_match / ((long double)summary[i].checks - (long double)summary[i].matches); } total_ticks += summary[i].ticks; } switch (profiling_rules_sort_order) { case SC_PROFILING_RULES_SORT_BY_TICKS: qsort(summary, count, sizeof(SCProfileSummary), SCProfileSummarySortByTicks); break; case SC_PROFILING_RULES_SORT_BY_AVG_TICKS: qsort(summary, count, sizeof(SCProfileSummary), SCProfileSummarySortByAvgTicks); break; case SC_PROFILING_RULES_SORT_BY_CHECKS: qsort(summary, count, sizeof(SCProfileSummary), SCProfileSummarySortByChecks); break; case SC_PROFILING_RULES_SORT_BY_MATCHES: qsort(summary, count, sizeof(SCProfileSummary), SCProfileSummarySortByMatches); break; case SC_PROFILING_RULES_SORT_BY_MAX_TICKS: qsort(summary, count, sizeof(SCProfileSummary), SCProfileSummarySortByMaxTicks); break; case SC_PROFILING_RULES_SORT_BY_AVG_TICKS_MATCH: qsort(summary, count, sizeof(SCProfileSummary), SCProfileSummarySortByAvgTicksMatch); break; case SC_PROFILING_RULES_SORT_BY_AVG_TICKS_NO_MATCH: qsort(summary, count, sizeof(SCProfileSummary), SCProfileSummarySortByAvgTicksNoMatch); break; } gettimeofday(&tval, NULL); struct tm local_tm; tms = (struct tm *)SCLocalTime(tval.tv_sec, &local_tm); fprintf(fp, " ----------------------------------------------" "----------------------------\n"); fprintf(fp, " Date: %" PRId32 "/%" PRId32 "/%04d -- " "%02d:%02d:%02d\n", tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900, tms->tm_hour,tms->tm_min, tms->tm_sec); fprintf(fp, " ----------------------------------------------" "----------------------------\n"); fprintf(fp, " %-8s %-12s %-8s %-8s %-12s %-6s %-8s %-8s %-11s %-11s %-11s %-11s\n", "Num", "Rule", "Gid", "Rev", "Ticks", "%", "Checks", "Matches", "Max Ticks", "Avg Ticks", "Avg Match", "Avg No Match"); fprintf(fp, " -------- " "------------ " "-------- " "-------- " "------------ " "------ " "-------- " "-------- " "----------- " "----------- " "----------- " "-------------- " "\n"); for (i = 0; i < MIN(count, profiling_rules_limit); i++) { /* Stop dumping when we hit our first rule with 0 checks. Due * to sorting this will be the beginning of all the rules with * 0 checks. */ if (summary[i].checks == 0) break; double percent = (long double)summary[i].ticks / (long double)total_ticks * 100; fprintf(fp, " %-8"PRIu32" %-12u %-8"PRIu32" %-8"PRIu32" %-12"PRIu64" %-6.2f %-8"PRIu64" %-8"PRIu64" %-11"PRIu64" %-11.2f %-11.2f %-11.2f\n", i + 1, summary[i].sid, summary[i].gid, summary[i].rev, summary[i].ticks, percent, summary[i].checks, summary[i].matches, summary[i].max, summary[i].avgticks, summary[i].avgticks_match, summary[i].avgticks_no_match); } fprintf(fp,"\n"); if (fp != stdout) fclose(fp); SCFree(summary); SCLogInfo("Done dumping profiling data."); }
/* Custom format logging */ static void LogHttpLogCustom(LogHttpLogThread *aft, htp_tx_t *tx, const struct timeval *ts, char *srcip, Port sp, char *dstip, Port dp) { LogHttpFileCtx *httplog_ctx = aft->httplog_ctx; uint32_t i; uint32_t datalen; char buf[128]; uint8_t *cvalue = NULL; uint32_t cvalue_len = 0; htp_header_t *h_request_hdr; htp_header_t *h_response_hdr; time_t time = ts->tv_sec; struct tm local_tm; struct tm *timestamp = SCLocalTime(time, &local_tm); for (i = 0; i < httplog_ctx->cf_n; i++) { h_request_hdr = NULL; h_response_hdr = NULL; switch (httplog_ctx->cf_nodes[i]->type){ case LOG_HTTP_CF_LITERAL: /* LITERAL */ MemBufferWriteString(aft->buffer, "%s", httplog_ctx->cf_nodes[i]->data); break; case LOG_HTTP_CF_TIMESTAMP: /* TIMESTAMP */ if (httplog_ctx->cf_nodes[i]->data[0] == '\0') { strftime(buf, 62, TIMESTAMP_DEFAULT_FORMAT, timestamp); } else { strftime(buf, 62, httplog_ctx->cf_nodes[i]->data, timestamp); } PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)buf,strlen(buf)); break; case LOG_HTTP_CF_TIMESTAMP_U: /* TIMESTAMP USECONDS */ snprintf(buf, 62, "%06u", (unsigned int) ts->tv_usec); PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)buf,strlen(buf)); break; case LOG_HTTP_CF_CLIENT_IP: /* CLIENT IP ADDRESS */ PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)srcip,strlen(srcip)); break; case LOG_HTTP_CF_SERVER_IP: /* SERVER IP ADDRESS */ PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)dstip,strlen(dstip)); break; case LOG_HTTP_CF_CLIENT_PORT: /* CLIENT PORT */ MemBufferWriteString(aft->buffer, "%" PRIu16 "", sp); break; case LOG_HTTP_CF_SERVER_PORT: /* SERVER PORT */ MemBufferWriteString(aft->buffer, "%" PRIu16 "", dp); break; case LOG_HTTP_CF_REQUEST_METHOD: /* METHOD */ if (tx->request_method != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_method), bstr_len(tx->request_method)); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_REQUEST_URI: /* URI */ if (tx->request_uri != NULL) { datalen = httplog_ctx->cf_nodes[i]->maxlen; if (datalen == 0 || datalen > bstr_len(tx->request_uri)) { datalen = bstr_len(tx->request_uri); } PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_uri), datalen); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_REQUEST_HOST: /* HOSTNAME */ if (tx->request_hostname != NULL) { datalen = httplog_ctx->cf_nodes[i]->maxlen; if (datalen == 0 || datalen > bstr_len(tx->request_hostname)) { datalen = bstr_len(tx->request_hostname); } PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_hostname), datalen); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_REQUEST_PROTOCOL: /* PROTOCOL */ if (tx->request_protocol != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_protocol), bstr_len(tx->request_protocol)); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_REQUEST_HEADER: /* REQUEST HEADER */ if (tx->request_headers != NULL) { h_request_hdr = htp_table_get_c(tx->request_headers, httplog_ctx->cf_nodes[i]->data); } if (h_request_hdr != NULL) { datalen = httplog_ctx->cf_nodes[i]->maxlen; if (datalen == 0 || datalen > bstr_len(h_request_hdr->value)) { datalen = bstr_len(h_request_hdr->value); } PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(h_request_hdr->value), datalen); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_REQUEST_COOKIE: /* REQUEST COOKIE */ if (tx->request_headers != NULL) { h_request_hdr = htp_table_get_c(tx->request_headers, "Cookie"); if (h_request_hdr != NULL) { cvalue_len = GetCookieValue((uint8_t *) bstr_ptr(h_request_hdr->value), bstr_len(h_request_hdr->value), (char *) httplog_ctx->cf_nodes[i]->data, &cvalue); } } if (cvalue_len > 0 && cvalue != NULL) { datalen = httplog_ctx->cf_nodes[i]->maxlen; if (datalen == 0 || datalen > cvalue_len) { datalen = cvalue_len; } PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, cvalue, datalen); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_REQUEST_LEN: /* REQUEST LEN */ MemBufferWriteString(aft->buffer, "%"PRIuMAX"", (uintmax_t)tx->request_message_len); break; case LOG_HTTP_CF_RESPONSE_STATUS: /* RESPONSE STATUS */ if (tx->response_status != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->response_status), bstr_len(tx->response_status)); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_RESPONSE_HEADER: /* RESPONSE HEADER */ if (tx->response_headers != NULL) { h_response_hdr = htp_table_get_c(tx->response_headers, httplog_ctx->cf_nodes[i]->data); } if (h_response_hdr != NULL) { datalen = httplog_ctx->cf_nodes[i]->maxlen; if (datalen == 0 || datalen > bstr_len(h_response_hdr->value)) { datalen = bstr_len(h_response_hdr->value); } PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(h_response_hdr->value), datalen); } else { MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); } break; case LOG_HTTP_CF_RESPONSE_LEN: /* RESPONSE LEN */ MemBufferWriteString(aft->buffer, "%"PRIuMAX"", (uintmax_t)tx->response_message_len); break; default: /* NO MATCH */ MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); SCLogDebug("No matching parameter %%%c for custom http log.", httplog_ctx->cf_nodes[i]->type); break; } } MemBufferWriteString(aft->buffer, "\n"); }