suricata
log-httplog.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2013 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Victor Julien <victor@inliniac.net>
22 * \author Ignacio Sanchez <sanchezmartin.ji@gmail.com>
23 *
24 * Implements http logging portion of the engine.
25 */
26
27#include "suricata-common.h"
28#include "detect.h"
29#include "pkt-var.h"
30#include "conf.h"
31
32#include "threads.h"
33#include "threadvars.h"
34#include "tm-threads.h"
35
36#include "util-print.h"
37#include "util-unittest.h"
38
39#include "util-debug.h"
40
41#include "output.h"
42#include "log-httplog.h"
43#include "app-layer-htp.h"
44#include "app-layer.h"
45#include "app-layer-parser.h"
46#include "util-privs.h"
47#include "util-buffer.h"
48
49#include "util-logopenfile.h"
50#include "util-time.h"
51#include "log-cf-common.h"
52
53#define DEFAULT_LOG_FILENAME "http.log"
54
55#define MODULE_NAME "LogHttpLog"
56
57#define OUTPUT_BUFFER_SIZE 65535
58
59TmEcode LogHttpLogThreadInit(ThreadVars *, const void *, void **);
61static void LogHttpLogDeInitCtx(OutputCtx *);
62
63int LogHttpLogger(ThreadVars *tv, void *thread_data, const Packet *, Flow *f, void *state, void *tx, uint64_t tx_id);
64
70
71#define LOG_HTTP_CF_REQUEST_HOST 'h'
72#define LOG_HTTP_CF_REQUEST_PROTOCOL 'H'
73#define LOG_HTTP_CF_REQUEST_METHOD 'm'
74#define LOG_HTTP_CF_REQUEST_URI 'u'
75#define LOG_HTTP_CF_REQUEST_HEADER 'i'
76#define LOG_HTTP_CF_REQUEST_COOKIE 'C'
77#define LOG_HTTP_CF_REQUEST_LEN 'b'
78#define LOG_HTTP_CF_RESPONSE_STATUS 's'
79#define LOG_HTTP_CF_RESPONSE_HEADER 'o'
80#define LOG_HTTP_CF_RESPONSE_LEN 'B'
81
82
83typedef struct LogHttpFileCtx_ {
85 uint32_t flags; /** Store mode */
88
89#define LOG_HTTP_DEFAULT 0
90#define LOG_HTTP_EXTENDED 1
91#define LOG_HTTP_CUSTOM 2
92
93typedef struct LogHttpLogThread_ {
95 /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */
96 uint32_t uri_cnt;
97
100
101/* Retrieves the selected cookie value */
102static uint32_t GetCookieValue(const uint8_t *rawcookies, uint32_t rawcookies_len, char *cookiename,
103 const uint8_t **cookievalue)
104{
105 const uint8_t *p = rawcookies;
106 const uint8_t *cn = p; /* ptr to cookie name start */
107 const uint8_t *cv = NULL; /* ptr to cookie value start */
108 while (p < rawcookies + rawcookies_len) {
109 if (cv == NULL && *p == '=') {
110 cv = p + 1;
111 } else if (cv != NULL && (*p == ';' || p == rawcookies + rawcookies_len - 1) ) {
112 /* Found end of cookie */
113 p++;
114 if (strlen(cookiename) == (unsigned int) (cv-cn-1) &&
115 strncmp(cookiename, (char *) cn, cv-cn-1) == 0) {
116 *cookievalue = cv;
117 return (uint32_t) (p-cv);
118 }
119 cv = NULL;
120 cn = p + 1;
121 }
122 p++;
123 }
124 return 0;
125}
126
127/* Custom format logging */
128static void LogHttpLogCustom(LogHttpLogThread *aft, htp_tx_t *tx, const SCTime_t ts, char *srcip,
129 Port sp, char *dstip, Port dp)
130{
131 LogHttpFileCtx *httplog_ctx = aft->httplog_ctx;
132 uint32_t i;
133 size_t datalen;
134 char buf[128];
135
136 const uint8_t *cvalue = NULL;
137 uint32_t cvalue_len = 0;
138
139 const htp_header_t *h_request_hdr;
140 const htp_header_t *h_response_hdr;
141
142 for (i = 0; i < httplog_ctx->cf->cf_n; i++) {
143 h_request_hdr = NULL;
144 h_response_hdr = NULL;
145
146 LogCustomFormatNode * node = httplog_ctx->cf->cf_nodes[i];
147 if (! node) /* Should never happen */
148 continue;
149
150 switch (node->type){
151 case LOG_CF_LITERAL:
152 /* LITERAL */
153 MemBufferWriteString(aft->buffer, "%s", node->data);
154 break;
155 case LOG_CF_TIMESTAMP:
156 /* TIMESTAMP */
158 break;
160 /* TIMESTAMP USECONDS */
161 snprintf(buf, sizeof(buf), "%06u", (unsigned int)SCTIME_USECS(ts));
162 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
163 (uint8_t *)buf, MIN(strlen(buf), 6));
164 break;
165 case LOG_CF_CLIENT_IP:
166 /* CLIENT IP ADDRESS */
167 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
168 aft->buffer->size, (uint8_t *)srcip,strlen(srcip));
169 break;
170 case LOG_CF_SERVER_IP:
171 /* SERVER IP ADDRESS */
172 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
173 aft->buffer->size, (uint8_t *)dstip,strlen(dstip));
174 break;
176 /* CLIENT PORT */
177 MemBufferWriteString(aft->buffer, "%" PRIu16 "", sp);
178 break;
180 /* SERVER PORT */
181 MemBufferWriteString(aft->buffer, "%" PRIu16 "", dp);
182 break;
184 /* METHOD */
185 if (htp_tx_request_method(tx) != NULL) {
186 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
187 (uint8_t *)bstr_ptr(htp_tx_request_method(tx)),
188 bstr_len(htp_tx_request_method(tx)));
189 } else {
191 }
192 break;
194 /* URI */
195 if (htp_tx_request_uri(tx) != NULL) {
196 datalen = node->maxlen;
197 if (datalen == 0 || datalen > bstr_len(htp_tx_request_uri(tx))) {
198 datalen = bstr_len(htp_tx_request_uri(tx));
199 }
200 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
201 (uint8_t *)bstr_ptr(htp_tx_request_uri(tx)), datalen);
202 } else {
204 }
205 break;
207 /* HOSTNAME */
208 if (htp_tx_request_hostname(tx) != NULL) {
209 datalen = node->maxlen;
210 if (datalen == 0 || datalen > bstr_len(htp_tx_request_hostname(tx))) {
211 datalen = bstr_len(htp_tx_request_hostname(tx));
212 }
213 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
214 (uint8_t *)bstr_ptr(htp_tx_request_hostname(tx)), datalen);
215 } else {
217 }
218 break;
220 /* PROTOCOL */
221 if (htp_tx_request_protocol(tx) != NULL) {
222 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
223 (uint8_t *)bstr_ptr(htp_tx_request_protocol(tx)),
224 bstr_len(htp_tx_request_protocol(tx)));
225 } else {
227 }
228 break;
230 /* REQUEST HEADER */
231 h_request_hdr = htp_tx_request_header(tx, node->data);
232 if (h_request_hdr != NULL) {
233 datalen = node->maxlen;
234 if (datalen == 0 || datalen > htp_header_value_len(h_request_hdr)) {
235 datalen = htp_header_value_len(h_request_hdr);
236 }
237 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
238 htp_header_value_ptr(h_request_hdr), datalen);
239 } else {
241 }
242 break;
244 /* REQUEST COOKIE */
245 if (htp_tx_request_headers(tx) != NULL) {
246 h_request_hdr = htp_tx_request_header(tx, "Cookie");
247 if (h_request_hdr != NULL) {
248 cvalue_len = GetCookieValue(htp_header_value_ptr(h_request_hdr),
249 (uint32_t)htp_header_value_len(h_request_hdr), (char *)node->data,
250 &cvalue);
251 }
252 }
253 if (cvalue_len > 0 && cvalue != NULL) {
254 datalen = node->maxlen;
255 if (datalen == 0 || datalen > cvalue_len) {
256 datalen = cvalue_len;
257 }
258 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
259 aft->buffer->size, cvalue, datalen);
260 } else {
262 }
263 break;
265 /* REQUEST LEN */
267 aft->buffer, "%" PRIuMAX "", (uintmax_t)htp_tx_request_message_len(tx));
268 break;
270 /* RESPONSE STATUS */
271 if (htp_tx_response_status(tx) != NULL) {
272 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
273 (uint8_t *)bstr_ptr(htp_tx_response_status(tx)),
274 bstr_len(htp_tx_response_status(tx)));
275 } else {
277 }
278 break;
280 /* RESPONSE HEADER */
281 if (htp_tx_response_headers(tx) != NULL) {
282 h_response_hdr = htp_tx_response_header(tx, node->data);
283 }
284 if (h_response_hdr != NULL) {
285 datalen = node->maxlen;
286 if (datalen == 0 || datalen > htp_header_value_len(h_response_hdr)) {
287 datalen = htp_header_value_len(h_response_hdr);
288 }
289 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
290 aft->buffer->size, htp_header_value_ptr(h_response_hdr), datalen);
291 } else {
293 }
294 break;
296 /* RESPONSE LEN */
298 aft->buffer, "%" PRIuMAX "", (uintmax_t)htp_tx_response_message_len(tx));
299 break;
300 default:
301 /* NO MATCH */
303 SCLogDebug("No matching parameter %%%c for custom http log.", node->type);
304 break;
305 }
306 }
307 MemBufferWriteString(aft->buffer, "\n");
308}
309
310static void LogHttpLogExtended(LogHttpLogThread *aft, htp_tx_t *tx)
311{
313
314 /* referer */
315 const htp_header_t *h_referer = htp_tx_request_header(tx, "referer");
316
317 if (h_referer != NULL) {
318 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
319 htp_header_value_ptr(h_referer), htp_header_value_len(h_referer));
320 } else {
321 MemBufferWriteString(aft->buffer, "<no referer>");
322 }
323
325
326 /* method */
327 if (htp_tx_request_method(tx) != NULL) {
328 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
329 (uint8_t *)bstr_ptr(htp_tx_request_method(tx)),
330 bstr_len(htp_tx_request_method(tx)));
331 }
333
334 /* protocol */
335 if (htp_tx_request_protocol(tx) != NULL) {
336 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
337 (uint8_t *)bstr_ptr(htp_tx_request_protocol(tx)),
338 bstr_len(htp_tx_request_protocol(tx)));
339 } else {
340 MemBufferWriteString(aft->buffer, "<no protocol>");
341 }
343
344 /* response status */
345 if (htp_tx_response_status(tx) != NULL) {
346 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
347 (uint8_t *)bstr_ptr(htp_tx_response_status(tx)),
348 bstr_len(htp_tx_response_status(tx)));
349 /* Redirect? */
350 if ((htp_tx_response_status_number(tx) > 300) &&
351 ((htp_tx_response_status_number(tx)) < 303)) {
352 const htp_header_t *h_location = htp_tx_response_header(tx, "location");
353 if (h_location != NULL) {
354 MemBufferWriteString(aft->buffer, " => ");
355
356 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
357 htp_header_value_ptr(h_location), htp_header_value_len(h_location));
358 }
359 }
360 } else {
361 MemBufferWriteString(aft->buffer, "<no status>");
362 }
363
364 /* length */
367 aft->buffer, "%" PRIuMAX " bytes", (uintmax_t)htp_tx_response_message_len(tx));
368}
369
370static TmEcode LogHttpLogIPWrapper(ThreadVars *tv, void *data, const Packet *p, Flow *f, HtpState *htp_state, htp_tx_t *tx, uint64_t tx_id, int ipproto)
371{
372 SCEnter();
373
374 LogHttpLogThread *aft = (LogHttpLogThread *)data;
375 LogHttpFileCtx *hlog = aft->httplog_ctx;
376 char timebuf[64];
377
378 /* check if we have HTTP state or not */
379 CreateTimeString(p->ts, timebuf, sizeof(timebuf));
380
381 char srcip[46], dstip[46];
382 Port sp, dp;
383 if ((PKT_IS_TOSERVER(p))) {
384 switch (ipproto) {
385 case AF_INET:
386 PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip));
387 PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip));
388 break;
389 case AF_INET6:
390 PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip));
391 PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip));
392 break;
393 default:
394 goto end;
395 }
396 sp = p->sp;
397 dp = p->dp;
398 } else {
399 switch (ipproto) {
400 case AF_INET:
401 PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), srcip, sizeof(srcip));
402 PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), dstip, sizeof(dstip));
403 break;
404 case AF_INET6:
405 PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), srcip, sizeof(srcip));
406 PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), dstip, sizeof(dstip));
407 break;
408 default:
409 goto end;
410 }
411 sp = p->dp;
412 dp = p->sp;
413 }
414
415 SCLogDebug("got a HTTP request and now logging !!");
416
417 /* reset */
418 MemBufferReset(aft->buffer);
419
420 if (hlog->flags & LOG_HTTP_CUSTOM) {
421 LogHttpLogCustom(aft, tx, p->ts, srcip, sp, dstip, dp);
422 } else {
423 /* time */
424 MemBufferWriteString(aft->buffer, "%s ", timebuf);
425
426 /* hostname */
427 if (htp_tx_request_hostname(tx) != NULL) {
428 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
429 (uint8_t *)bstr_ptr(htp_tx_request_hostname(tx)),
430 bstr_len(htp_tx_request_hostname(tx)));
431 } else {
432 MemBufferWriteString(aft->buffer, "<hostname unknown>");
433 }
435
436 /* uri */
437 if (htp_tx_request_uri(tx) != NULL) {
438 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
439 (uint8_t *)bstr_ptr(htp_tx_request_uri(tx)), bstr_len(htp_tx_request_uri(tx)));
440 }
442
443 /* user agent */
444 const htp_header_t *h_user_agent = htp_tx_request_header(tx, "user-agent");
445 if (h_user_agent != NULL) {
446 PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
447 htp_header_value_ptr(h_user_agent), htp_header_value_len(h_user_agent));
448 } else {
449 MemBufferWriteString(aft->buffer, "<useragent unknown>");
450 }
451 if (hlog->flags & LOG_HTTP_EXTENDED) {
452 LogHttpLogExtended(aft, tx);
453 }
454
455 /* ip/tcp header info */
458 "%s:%" PRIu16 " -> %s:%" PRIu16 "\n",
459 srcip, sp, dstip, dp);
460 }
461
462 aft->uri_cnt ++;
463
464 hlog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer),
465 MEMBUFFER_OFFSET(aft->buffer), hlog->file_ctx);
466
467end:
468 SCReturnInt(0);
469
470}
471
472int LogHttpLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id)
473{
474 SCEnter();
475
476 if (!(PacketIsTCP(p))) {
478 }
479
480 int r = 0;
481 if (PacketIsIPv4(p)) {
482 r = LogHttpLogIPWrapper(tv, thread_data, p, f, (HtpState *)state, (htp_tx_t *)tx, tx_id, AF_INET);
483 } else if (PacketIsIPv6(p)) {
484 r = LogHttpLogIPWrapper(tv, thread_data, p, f, (HtpState *)state, (htp_tx_t *)tx, tx_id, AF_INET6);
485 }
486
487 SCReturnInt(r);
488}
489
490TmEcode LogHttpLogThreadInit(ThreadVars *t, const void *initdata, void **data)
491{
492 LogHttpLogThread *aft = SCCalloc(1, sizeof(LogHttpLogThread));
493 if (unlikely(aft == NULL))
494 return TM_ECODE_FAILED;
495
496 if(initdata == NULL)
497 {
498 SCLogDebug("Error getting context for LogHTTPLog. \"initdata\" argument NULL");
499 SCFree(aft);
500 return TM_ECODE_FAILED;
501 }
502
504 if (aft->buffer == NULL) {
505 SCFree(aft);
506 return TM_ECODE_FAILED;
507 }
508
509 /* Use the Output Context (file pointer and mutex) */
510 aft->httplog_ctx= ((OutputCtx *)initdata)->data;
511
512 *data = (void *)aft;
513 return TM_ECODE_OK;
514}
515
517{
518 LogHttpLogThread *aft = (LogHttpLogThread *)data;
519 if (aft == NULL) {
520 return TM_ECODE_OK;
521 }
522
523 MemBufferFree(aft->buffer);
524 /* clear memory */
525 memset(aft, 0, sizeof(LogHttpLogThread));
526
527 SCFree(aft);
528 return TM_ECODE_OK;
529}
530
531/** \brief Create a new http log LogFileCtx.
532 * \param conf Pointer to ConfNode containing this loggers configuration.
533 * \return NULL if failure, LogFileCtx* to the file_ctx if succesful
534 * */
536{
537 SCLogWarning("The http-log output has been deprecated and will be removed in Suricata 9.0.");
538 OutputInitResult result = { NULL, false };
539 LogFileCtx* file_ctx = LogFileNewCtx();
540 if(file_ctx == NULL) {
541 SCLogError("couldn't create new file_ctx");
542 return result;
543 }
544
545 if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) {
546 LogFileFreeCtx(file_ctx);
547 return result;
548 }
549
550 LogHttpFileCtx *httplog_ctx = SCCalloc(1, sizeof(LogHttpFileCtx));
551 if (unlikely(httplog_ctx == NULL)) {
552 LogFileFreeCtx(file_ctx);
553 return result;
554 }
555
556 httplog_ctx->file_ctx = file_ctx;
557
558 const char *extended = SCConfNodeLookupChildValue(conf, "extended");
559 const char *custom = SCConfNodeLookupChildValue(conf, "custom");
560 const char *customformat = SCConfNodeLookupChildValue(conf, "customformat");
561
562 /* If custom logging format is selected, lets parse it */
563 if (custom != NULL && customformat != NULL && SCConfValIsTrue(custom)) {
564
565 httplog_ctx->cf = LogCustomFormatAlloc();
566 if (!httplog_ctx->cf) {
567 goto errorfree;
568 }
569
570 httplog_ctx->flags |= LOG_HTTP_CUSTOM;
571
572 /* Parsing */
573 if ( ! LogCustomFormatParse(httplog_ctx->cf, customformat)) {
574 goto parsererror;
575 }
576 } else {
577 if (extended == NULL) {
578 httplog_ctx->flags |= LOG_HTTP_DEFAULT;
579 } else {
580 if (SCConfValIsTrue(extended)) {
581 httplog_ctx->flags |= LOG_HTTP_EXTENDED;
582 }
583 }
584 }
585
586 OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
587 if (unlikely(output_ctx == NULL)) {
588 goto parsererror;
589 }
590
591 output_ctx->data = httplog_ctx;
592 output_ctx->DeInit = LogHttpLogDeInitCtx;
593
594 SCLogDebug("HTTP log output initialized");
595
596 /* enable the logger for the app layer */
598
599 result.ctx = output_ctx;
600 result.ok = true;
601 return result;
602
603parsererror:
604 SCLogError("Syntax error in custom http log format string.");
605errorfree:
606 LogCustomFormatFree(httplog_ctx->cf);
607 LogFileFreeCtx(file_ctx);
608 SCFree(httplog_ctx);
609 return result;
610
611}
612
613static void LogHttpLogDeInitCtx(OutputCtx *output_ctx)
614{
615 LogHttpFileCtx *httplog_ctx = (LogHttpFileCtx *)output_ctx->data;
616 LogCustomFormatFree(httplog_ctx->cf);
617 LogFileFreeCtx(httplog_ctx->file_ctx);
618 SCFree(httplog_ctx);
619 SCFree(output_ctx);
620}
void SCAppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
@ ALPROTO_HTTP1
int SCConfValIsTrue(const char *val)
Check if a value is true.
Definition conf.c:551
const char * SCConfNodeLookupChildValue(const SCConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition conf.c:824
#define GET_IPV6_DST_ADDR(p)
Definition decode.h:204
#define GET_IPV4_SRC_ADDR_PTR(p)
Definition decode.h:198
#define GET_IPV6_SRC_ADDR(p)
Definition decode.h:203
#define PKT_IS_TOSERVER(p)
Definition decode.h:238
uint16_t Port
Definition decode.h:218
#define GET_IPV4_DST_ADDR_PTR(p)
Definition decode.h:199
ThreadVars * tv
void LogCustomFormatWriteTimestamp(MemBuffer *buffer, const char *fmt, const SCTime_t ts)
Writes a timestamp with given format into a MemBuffer.
void LogCustomFormatFree(LogCustomFormat *cf)
Frees memory held by a custom format.
LogCustomFormat * LogCustomFormatAlloc(void)
Creates a custom format.
int LogCustomFormatParse(LogCustomFormat *cf, const char *format)
Parses and saves format nodes for custom format.
#define LOG_CF_WRITE_STAR_SEPARATOR(buffer)
#define LOG_CF_TIMESTAMP
#define LOG_CF_NONE
#define LOG_CF_CLIENT_PORT
#define LOG_CF_SERVER_PORT
#define LOG_CF_LITERAL
#define LOG_CF_TIMESTAMP_U
#define LOG_CF_CLIENT_IP
#define LOG_CF_SERVER_IP
#define LOG_HTTP_CF_REQUEST_HEADER
Definition log-httplog.c:75
#define MODULE_NAME
Definition log-httplog.c:55
TmEcode LogHttpLogThreadInit(ThreadVars *, const void *, void **)
struct LogHttpFileCtx_ LogHttpFileCtx
TmEcode LogHttpLogThreadDeinit(ThreadVars *, void *)
#define OUTPUT_BUFFER_SIZE
Definition log-httplog.c:57
#define LOG_HTTP_CUSTOM
Definition log-httplog.c:91
#define LOG_HTTP_CF_RESPONSE_HEADER
Definition log-httplog.c:79
#define LOG_HTTP_EXTENDED
Definition log-httplog.c:90
void LogHttpLogRegister(void)
Definition log-httplog.c:65
#define LOG_HTTP_CF_RESPONSE_STATUS
Definition log-httplog.c:78
#define LOG_HTTP_CF_REQUEST_HOST
Definition log-httplog.c:71
#define LOG_HTTP_DEFAULT
Definition log-httplog.c:89
int LogHttpLogger(ThreadVars *tv, void *thread_data, const Packet *, Flow *f, void *state, void *tx, uint64_t tx_id)
#define LOG_HTTP_CF_RESPONSE_LEN
Definition log-httplog.c:80
#define LOG_HTTP_CF_REQUEST_COOKIE
Definition log-httplog.c:76
#define DEFAULT_LOG_FILENAME
Definition log-httplog.c:53
#define LOG_HTTP_CF_REQUEST_LEN
Definition log-httplog.c:77
struct LogHttpLogThread_ LogHttpLogThread
#define LOG_HTTP_CF_REQUEST_URI
Definition log-httplog.c:74
#define LOG_HTTP_CF_REQUEST_METHOD
Definition log-httplog.c:73
#define LOG_HTTP_CF_REQUEST_PROTOCOL
Definition log-httplog.c:72
OutputInitResult LogHttpLogInitCtx(SCConfNode *conf)
Create a new http log LogFileCtx.
void OutputRegisterTxModule(LoggerId id, const char *name, const char *conf_name, OutputInitFunc InitFunc, AppProto alproto, TxLogger TxLogFunc, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
Register a tx output module.
Definition output.c:398
uint64_t ts
Flow data structure.
Definition flow.h:356
char data[LOG_NODE_STRLEN]
LogCustomFormatNode * cf_nodes[LOG_MAXN_NODES]
int(* Write)(const char *buffer, int buffer_len, struct LogFileCtx_ *fp)
LogFileCtx * file_ctx
Definition log-httplog.c:84
LogCustomFormat * cf
Definition log-httplog.c:86
LogHttpFileCtx * httplog_ctx
Definition log-httplog.c:94
MemBuffer * buffer
Definition log-httplog.c:98
uint8_t buffer[]
Definition util-buffer.h:30
uint32_t size
Definition util-buffer.h:28
uint32_t offset
Definition util-buffer.h:29
void * data
Definition tm-modules.h:91
void(* DeInit)(struct OutputCtx_ *)
Definition tm-modules.h:94
OutputCtx * ctx
Definition output.h:47
SCTime_t ts
Definition decode.h:555
Port sp
Definition decode.h:508
Port dp
Definition decode.h:516
Per thread variable structure.
Definition threadvars.h:58
#define MIN(x, y)
@ LOGGER_HTTP
@ TM_ECODE_FAILED
@ TM_ECODE_OK
void MemBufferWriteString(MemBuffer *dst, const char *fmt,...)
MemBuffer * MemBufferCreateNew(uint32_t size)
Definition util-buffer.c:32
void MemBufferFree(MemBuffer *buffer)
Definition util-buffer.c:86
#define MEMBUFFER_BUFFER(mem_buffer)
Get the MemBuffers underlying buffer.
Definition util-buffer.h:51
#define MEMBUFFER_OFFSET(mem_buffer)
Get the MemBuffers current offset.
Definition util-buffer.h:56
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition util-debug.h:255
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
int LogFileFreeCtx(LogFileCtx *lf_ctx)
LogFileFreeCtx() Destroy a LogFileCtx (Close the file and free memory)
LogFileCtx * LogFileNewCtx(void)
LogFileNewCtx() Get a new LogFileCtx.
int SCConfLogOpenGeneric(SCConfNode *conf, LogFileCtx *log_ctx, const char *default_filename, int rotate)
open a generic output "log file", which may be a regular file or a socket
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define unlikely(expr)
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition util-print.c:231
void PrintRawUriBuf(char *retbuf, uint32_t *offset, uint32_t retbuflen, const uint8_t *buf, size_t buflen)
Definition util-print.c:93
void CreateTimeString(const SCTime_t ts, char *str, size_t size)
Definition util-time.c:272
#define SCTIME_USECS(t)
Definition util-time.h:56