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 "debug.h"
29 #include "detect.h"
30 #include "pkt-var.h"
31 #include "conf.h"
32 
33 #include "threads.h"
34 #include "threadvars.h"
35 #include "tm-threads.h"
36 
37 #include "util-print.h"
38 #include "util-unittest.h"
39 
40 #include "util-debug.h"
41 
42 #include "output.h"
43 #include "log-httplog.h"
44 #include "app-layer-htp.h"
45 #include "app-layer.h"
46 #include "app-layer-parser.h"
47 #include "util-privs.h"
48 #include "util-buffer.h"
49 
50 #include "util-logopenfile.h"
51 #include "util-time.h"
52 #include "log-cf-common.h"
53 
54 #define DEFAULT_LOG_FILENAME "http.log"
55 
56 #define MODULE_NAME "LogHttpLog"
57 
58 #define OUTPUT_BUFFER_SIZE 65535
59 
60 TmEcode LogHttpLogThreadInit(ThreadVars *, const void *, void **);
62 static void LogHttpLogDeInitCtx(OutputCtx *);
63 
64 int LogHttpLogger(ThreadVars *tv, void *thread_data, const Packet *, Flow *f, void *state, void *tx, uint64_t tx_id);
65 
66 void LogHttpLogRegister (void)
67 {
71 }
72 
73 #define LOG_HTTP_CF_REQUEST_HOST 'h'
74 #define LOG_HTTP_CF_REQUEST_PROTOCOL 'H'
75 #define LOG_HTTP_CF_REQUEST_METHOD 'm'
76 #define LOG_HTTP_CF_REQUEST_URI 'u'
77 #define LOG_HTTP_CF_REQUEST_TIME 't'
78 #define LOG_HTTP_CF_REQUEST_HEADER 'i'
79 #define LOG_HTTP_CF_REQUEST_COOKIE 'C'
80 #define LOG_HTTP_CF_REQUEST_LEN 'b'
81 #define LOG_HTTP_CF_RESPONSE_STATUS 's'
82 #define LOG_HTTP_CF_RESPONSE_HEADER 'o'
83 #define LOG_HTTP_CF_RESPONSE_LEN 'B'
84 
85 
86 typedef struct LogHttpFileCtx_ {
88  uint32_t flags; /** Store mode */
91 
92 #define LOG_HTTP_DEFAULT 0
93 #define LOG_HTTP_EXTENDED 1
94 #define LOG_HTTP_CUSTOM 2
95 
96 typedef struct LogHttpLogThread_ {
98  /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */
99  uint32_t uri_cnt;
100 
103 
104 /* Retrieves the selected cookie value */
105 static uint32_t GetCookieValue(uint8_t *rawcookies, uint32_t rawcookies_len, char *cookiename,
106  uint8_t **cookievalue)
107 {
108  uint8_t *p = rawcookies;
109  uint8_t *cn = p; /* ptr to cookie name start */
110  uint8_t *cv = NULL; /* ptr to cookie value start */
111  while (p < rawcookies + rawcookies_len) {
112  if (cv == NULL && *p == '=') {
113  cv = p + 1;
114  } else if (cv != NULL && (*p == ';' || p == rawcookies + rawcookies_len - 1) ) {
115  /* Found end of cookie */
116  p++;
117  if (strlen(cookiename) == (unsigned int) (cv-cn-1) &&
118  strncmp(cookiename, (char *) cn, cv-cn-1) == 0) {
119  *cookievalue = cv;
120  return (uint32_t) (p-cv);
121  }
122  cv = NULL;
123  cn = p + 1;
124  }
125  p++;
126  }
127  return 0;
128 }
129 
130 /* Custom format logging */
131 static void LogHttpLogCustom(LogHttpLogThread *aft, htp_tx_t *tx, const struct timeval *ts,
132  char *srcip, Port sp, char *dstip, Port dp)
133 {
134  LogHttpFileCtx *httplog_ctx = aft->httplog_ctx;
135  uint32_t i;
136  uint32_t datalen;
137  char buf[128];
138 
139  uint8_t *cvalue = NULL;
140  uint32_t cvalue_len = 0;
141 
142  htp_header_t *h_request_hdr;
143  htp_header_t *h_response_hdr;
144 
145  for (i = 0; i < httplog_ctx->cf->cf_n; i++) {
146  h_request_hdr = NULL;
147  h_response_hdr = NULL;
148 
149  LogCustomFormatNode * node = httplog_ctx->cf->cf_nodes[i];
150  if (! node) /* Should never happen */
151  continue;
152 
153  switch (node->type){
154  case LOG_CF_LITERAL:
155  /* LITERAL */
156  MemBufferWriteString(aft->buffer, "%s", node->data);
157  break;
158  case LOG_CF_TIMESTAMP:
159  /* TIMESTAMP */
161  break;
162  case LOG_CF_TIMESTAMP_U:
163  /* TIMESTAMP USECONDS */
164  snprintf(buf, sizeof(buf), "%06u", (unsigned int) ts->tv_usec);
165  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
166  aft->buffer->size, (uint8_t *)buf, MIN(strlen(buf),6));
167  break;
168  case LOG_CF_CLIENT_IP:
169  /* CLIENT IP ADDRESS */
170  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
171  aft->buffer->size, (uint8_t *)srcip,strlen(srcip));
172  break;
173  case LOG_CF_SERVER_IP:
174  /* SERVER IP ADDRESS */
175  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
176  aft->buffer->size, (uint8_t *)dstip,strlen(dstip));
177  break;
178  case LOG_CF_CLIENT_PORT:
179  /* CLIENT PORT */
180  MemBufferWriteString(aft->buffer, "%" PRIu16 "", sp);
181  break;
182  case LOG_CF_SERVER_PORT:
183  /* SERVER PORT */
184  MemBufferWriteString(aft->buffer, "%" PRIu16 "", dp);
185  break;
187  /* METHOD */
188  if (tx->request_method != NULL) {
189  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
190  aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_method),
191  bstr_len(tx->request_method));
192  } else {
194  }
195  break;
197  /* URI */
198  if (tx->request_uri != NULL) {
199  datalen = node->maxlen;
200  if (datalen == 0 || datalen > bstr_len(tx->request_uri)) {
201  datalen = bstr_len(tx->request_uri);
202  }
203  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
204  aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_uri),
205  datalen);
206  } else {
208  }
209  break;
211  /* HOSTNAME */
212  if (tx->request_hostname != NULL)
213  {
214  datalen = node->maxlen;
215  if (datalen == 0 || datalen > bstr_len(tx->request_hostname)) {
216  datalen = bstr_len(tx->request_hostname);
217  }
218  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
219  aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_hostname),
220  datalen);
221  } else {
223  }
224  break;
226  /* PROTOCOL */
227  if (tx->request_protocol != NULL) {
228  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
229  aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_protocol),
230  bstr_len(tx->request_protocol));
231  } else {
233  }
234  break;
236  /* REQUEST HEADER */
237  if (tx->request_headers != NULL) {
238  h_request_hdr = htp_table_get_c(tx->request_headers, node->data);
239  }
240  if (h_request_hdr != NULL) {
241  datalen = node->maxlen;
242  if (datalen == 0 || datalen > bstr_len(h_request_hdr->value)) {
243  datalen = bstr_len(h_request_hdr->value);
244  }
245  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
246  aft->buffer->size, (uint8_t *)bstr_ptr(h_request_hdr->value),
247  datalen);
248  } else {
250  }
251  break;
253  /* REQUEST COOKIE */
254  if (tx->request_headers != NULL) {
255  h_request_hdr = htp_table_get_c(tx->request_headers, "Cookie");
256  if (h_request_hdr != NULL) {
257  cvalue_len = GetCookieValue((uint8_t *) bstr_ptr(h_request_hdr->value),
258  bstr_len(h_request_hdr->value), (char *) node->data,
259  &cvalue);
260  }
261  }
262  if (cvalue_len > 0 && cvalue != NULL) {
263  datalen = node->maxlen;
264  if (datalen == 0 || datalen > cvalue_len) {
265  datalen = cvalue_len;
266  }
267  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
268  aft->buffer->size, cvalue, datalen);
269  } else {
271  }
272  break;
274  /* REQUEST LEN */
275  MemBufferWriteString(aft->buffer, "%"PRIuMAX"", (uintmax_t)tx->request_message_len);
276  break;
278  /* RESPONSE STATUS */
279  if (tx->response_status != NULL) {
280  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
281  aft->buffer->size, (uint8_t *)bstr_ptr(tx->response_status),
282  bstr_len(tx->response_status));
283  } else {
285  }
286  break;
288  /* RESPONSE HEADER */
289  if (tx->response_headers != NULL) {
290  h_response_hdr = htp_table_get_c(tx->response_headers,
291  node->data);
292  }
293  if (h_response_hdr != NULL) {
294  datalen = node->maxlen;
295  if (datalen == 0 || datalen > bstr_len(h_response_hdr->value)) {
296  datalen = bstr_len(h_response_hdr->value);
297  }
298  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
299  aft->buffer->size, (uint8_t *)bstr_ptr(h_response_hdr->value),
300  datalen);
301  } else {
303  }
304  break;
306  /* RESPONSE LEN */
307  MemBufferWriteString(aft->buffer, "%"PRIuMAX"", (uintmax_t)tx->response_message_len);
308  break;
309  default:
310  /* NO MATCH */
312  SCLogDebug("No matching parameter %%%c for custom http log.", node->type);
313  break;
314  }
315  }
316  MemBufferWriteString(aft->buffer, "\n");
317 }
318 
319 static void LogHttpLogExtended(LogHttpLogThread *aft, htp_tx_t *tx)
320 {
322 
323  /* referer */
324  htp_header_t *h_referer = NULL;
325  if (tx->request_headers != NULL) {
326  h_referer = htp_table_get_c(tx->request_headers, "referer");
327  }
328  if (h_referer != NULL) {
329  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
330  (uint8_t *)bstr_ptr(h_referer->value),
331  bstr_len(h_referer->value));
332  } else {
333  MemBufferWriteString(aft->buffer, "<no referer>");
334  }
335 
337 
338  /* method */
339  if (tx->request_method != NULL) {
340  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
341  (uint8_t *)bstr_ptr(tx->request_method),
342  bstr_len(tx->request_method));
343  }
345 
346  /* protocol */
347  if (tx->request_protocol != NULL) {
348  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
349  (uint8_t *)bstr_ptr(tx->request_protocol),
350  bstr_len(tx->request_protocol));
351  } else {
352  MemBufferWriteString(aft->buffer, "<no protocol>");
353  }
355 
356  /* response status */
357  if (tx->response_status != NULL) {
358  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
359  (uint8_t *)bstr_ptr(tx->response_status),
360  bstr_len(tx->response_status));
361  /* Redirect? */
362  if ((tx->response_status_number > 300) && ((tx->response_status_number) < 303)) {
363  htp_header_t *h_location = htp_table_get_c(tx->response_headers, "location");
364  if (h_location != NULL) {
365  MemBufferWriteString(aft->buffer, " => ");
366 
367  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
368  (uint8_t *)bstr_ptr(h_location->value),
369  bstr_len(h_location->value));
370  }
371  }
372  } else {
373  MemBufferWriteString(aft->buffer, "<no status>");
374  }
375 
376  /* length */
378  MemBufferWriteString(aft->buffer, "%"PRIuMAX" bytes", (uintmax_t)tx->response_message_len);
379 }
380 
381 static TmEcode LogHttpLogIPWrapper(ThreadVars *tv, void *data, const Packet *p, Flow *f, HtpState *htp_state, htp_tx_t *tx, uint64_t tx_id, int ipproto)
382 {
383  SCEnter();
384 
385  LogHttpLogThread *aft = (LogHttpLogThread *)data;
386  LogHttpFileCtx *hlog = aft->httplog_ctx;
387  char timebuf[64];
388 
389  /* check if we have HTTP state or not */
390  CreateTimeString(&p->ts, timebuf, sizeof(timebuf));
391 
392  char srcip[46], dstip[46];
393  Port sp, dp;
394  if ((PKT_IS_TOSERVER(p))) {
395  switch (ipproto) {
396  case AF_INET:
397  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip));
398  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip));
399  break;
400  case AF_INET6:
401  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip));
402  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip));
403  break;
404  default:
405  goto end;
406  }
407  sp = p->sp;
408  dp = p->dp;
409  } else {
410  switch (ipproto) {
411  case AF_INET:
412  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), srcip, sizeof(srcip));
413  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), dstip, sizeof(dstip));
414  break;
415  case AF_INET6:
416  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), srcip, sizeof(srcip));
417  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), dstip, sizeof(dstip));
418  break;
419  default:
420  goto end;
421  }
422  sp = p->dp;
423  dp = p->sp;
424  }
425 
426  SCLogDebug("got a HTTP request and now logging !!");
427 
428  /* reset */
429  MemBufferReset(aft->buffer);
430 
431  if (hlog->flags & LOG_HTTP_CUSTOM) {
432  LogHttpLogCustom(aft, tx, &p->ts, srcip, sp, dstip, dp);
433  } else {
434  /* time */
435  MemBufferWriteString(aft->buffer, "%s ", timebuf);
436 
437  /* hostname */
438  if (tx->request_hostname != NULL) {
439  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
440  (uint8_t *)bstr_ptr(tx->request_hostname),
441  bstr_len(tx->request_hostname));
442  } else {
443  MemBufferWriteString(aft->buffer, "<hostname unknown>");
444  }
446 
447  /* uri */
448  if (tx->request_uri != NULL) {
449  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
450  (uint8_t *)bstr_ptr(tx->request_uri),
451  bstr_len(tx->request_uri));
452  }
454 
455  /* user agent */
456  htp_header_t *h_user_agent = NULL;
457  if (tx->request_headers != NULL) {
458  h_user_agent = htp_table_get_c(tx->request_headers, "user-agent");
459  }
460  if (h_user_agent != NULL) {
461  PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
462  (uint8_t *)bstr_ptr(h_user_agent->value),
463  bstr_len(h_user_agent->value));
464  } else {
465  MemBufferWriteString(aft->buffer, "<useragent unknown>");
466  }
467  if (hlog->flags & LOG_HTTP_EXTENDED) {
468  LogHttpLogExtended(aft, tx);
469  }
470 
471  /* ip/tcp header info */
474  "%s:%" PRIu16 " -> %s:%" PRIu16 "\n",
475  srcip, sp, dstip, dp);
476  }
477 
478  aft->uri_cnt ++;
479 
480  hlog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer),
481  MEMBUFFER_OFFSET(aft->buffer), hlog->file_ctx);
482 
483 end:
484  SCReturnInt(0);
485 
486 }
487 
488 int LogHttpLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id)
489 {
490  SCEnter();
491 
492  if (!(PKT_IS_TCP(p))) {
494  }
495 
496  int r = 0;
497  if (PKT_IS_IPV4(p)) {
498  r = LogHttpLogIPWrapper(tv, thread_data, p, f, (HtpState *)state, (htp_tx_t *)tx, tx_id, AF_INET);
499  } else if (PKT_IS_IPV6(p)) {
500  r = LogHttpLogIPWrapper(tv, thread_data, p, f, (HtpState *)state, (htp_tx_t *)tx, tx_id, AF_INET6);
501  }
502 
503  SCReturnInt(r);
504 }
505 
506 TmEcode LogHttpLogThreadInit(ThreadVars *t, const void *initdata, void **data)
507 {
509  if (unlikely(aft == NULL))
510  return TM_ECODE_FAILED;
511  memset(aft, 0, sizeof(LogHttpLogThread));
512 
513  if(initdata == NULL)
514  {
515  SCLogDebug("Error getting context for LogHTTPLog. \"initdata\" argument NULL");
516  SCFree(aft);
517  return TM_ECODE_FAILED;
518  }
519 
521  if (aft->buffer == NULL) {
522  SCFree(aft);
523  return TM_ECODE_FAILED;
524  }
525 
526  /* Use the Ouptut Context (file pointer and mutex) */
527  aft->httplog_ctx= ((OutputCtx *)initdata)->data;
528 
529  *data = (void *)aft;
530  return TM_ECODE_OK;
531 }
532 
534 {
535  LogHttpLogThread *aft = (LogHttpLogThread *)data;
536  if (aft == NULL) {
537  return TM_ECODE_OK;
538  }
539 
540  MemBufferFree(aft->buffer);
541  /* clear memory */
542  memset(aft, 0, sizeof(LogHttpLogThread));
543 
544  SCFree(aft);
545  return TM_ECODE_OK;
546 }
547 
548 /** \brief Create a new http log LogFileCtx.
549  * \param conf Pointer to ConfNode containing this loggers configuration.
550  * \return NULL if failure, LogFileCtx* to the file_ctx if succesful
551  * */
553 {
554  OutputInitResult result = { NULL, false };
556  if(file_ctx == NULL) {
557  SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx");
558  return result;
559  }
560 
561  if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) {
562  LogFileFreeCtx(file_ctx);
563  return result;
564  }
565 
566  LogHttpFileCtx *httplog_ctx = SCMalloc(sizeof(LogHttpFileCtx));
567  if (unlikely(httplog_ctx == NULL)) {
568  LogFileFreeCtx(file_ctx);
569  return result;
570  }
571  memset(httplog_ctx, 0x00, sizeof(LogHttpFileCtx));
572 
573  httplog_ctx->file_ctx = file_ctx;
574 
575  const char *extended = ConfNodeLookupChildValue(conf, "extended");
576  const char *custom = ConfNodeLookupChildValue(conf, "custom");
577  const char *customformat = ConfNodeLookupChildValue(conf, "customformat");
578 
579  /* If custom logging format is selected, lets parse it */
580  if (custom != NULL && customformat != NULL && ConfValIsTrue(custom)) {
581 
582  httplog_ctx->cf = LogCustomFormatAlloc();
583  if (!httplog_ctx->cf) {
584  goto errorfree;
585  }
586 
587  httplog_ctx->flags |= LOG_HTTP_CUSTOM;
588 
589  /* Parsing */
590  if ( ! LogCustomFormatParse(httplog_ctx->cf, customformat)) {
591  goto parsererror;
592  }
593  } else {
594  if (extended == NULL) {
595  httplog_ctx->flags |= LOG_HTTP_DEFAULT;
596  } else {
597  if (ConfValIsTrue(extended)) {
598  httplog_ctx->flags |= LOG_HTTP_EXTENDED;
599  }
600  }
601  }
602 
603  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
604  if (unlikely(output_ctx == NULL)) {
605  goto parsererror;
606  }
607 
608  output_ctx->data = httplog_ctx;
609  output_ctx->DeInit = LogHttpLogDeInitCtx;
610 
611  SCLogDebug("HTTP log output initialized");
612 
613  /* enable the logger for the app layer */
615 
616  result.ctx = output_ctx;
617  result.ok = true;
618  return result;
619 
620 parsererror:
621  SCLogError(SC_ERR_INVALID_ARGUMENT,"Syntax error in custom http log format string.");
622 errorfree:
623  LogCustomFormatFree(httplog_ctx->cf);
624  LogFileFreeCtx(file_ctx);
625  SCFree(httplog_ctx);
626  return result;
627 
628 }
629 
630 static void LogHttpLogDeInitCtx(OutputCtx *output_ctx)
631 {
632  LogHttpFileCtx *httplog_ctx = (LogHttpFileCtx *)output_ctx->data;
633  LogCustomFormatFree(httplog_ctx->cf);
634  LogFileFreeCtx(httplog_ctx->file_ctx);
635  SCFree(httplog_ctx);
636  SCFree(output_ctx);
637 }
#define LOG_HTTP_CF_RESPONSE_STATUS
Definition: log-httplog.c:81
MemBuffer * MemBufferCreateNew(uint32_t size)
Definition: util-buffer.c:32
#define GET_IPV4_SRC_ADDR_PTR(p)
Definition: decode.h:214
#define SCLogDebug(...)
Definition: util-debug.h:335
int LogCustomFormatParse(LogCustomFormat *cf, const char *format)
Parses and saves format nodes for custom format.
Definition: log-cf-common.c:94
struct LogHttpFileCtx_ LogHttpFileCtx
#define LOG_CF_LITERAL
Definition: log-cf-common.h:40
#define MemBufferWriteString(dst,...)
Write a string buffer to the Membuffer dst.
Definition: util-buffer.h:162
char data[LOG_NODE_STRLEN]
Definition: log-cf-common.h:69
#define MODULE_NAME
Definition: log-httplog.c:56
#define unlikely(expr)
Definition: util-optimize.h:35
#define GET_IPV4_DST_ADDR_PTR(p)
Definition: decode.h:215
TmEcode LogHttpLogThreadDeinit(ThreadVars *, void *)
Definition: log-httplog.c:533
Port sp
Definition: decode.h:415
#define MemBufferReset(mem_buffer)
Reset the mem buffer.
Definition: util-buffer.h:42
uint32_t uri_cnt
Definition: log-httplog.c:99
Port dp
Definition: decode.h:423
struct LogHttpLogThread_ LogHttpLogThread
#define MIN(x, y)
#define PKT_IS_IPV6(p)
Definition: decode.h:252
#define LOG_HTTP_CF_REQUEST_COOKIE
Definition: log-httplog.c:79
void(* DeInit)(struct OutputCtx_ *)
Definition: tm-modules.h:84
#define LOG_HTTP_CF_REQUEST_URI
Definition: log-httplog.c:76
#define LOG_CF_CLIENT_PORT
Definition: log-cf-common.h:45
#define LOG_HTTP_CF_RESPONSE_LEN
Definition: log-httplog.c:83
MemBuffer * buffer
Definition: log-httplog.c:101
#define PKT_IS_IPV4(p)
Definition: decode.h:251
#define LOG_HTTP_CF_RESPONSE_HEADER
Definition: log-httplog.c:82
#define SCCalloc(nm, a)
Definition: util-mem.h:253
OutputInitResult LogHttpLogInitCtx(ConfNode *conf)
Create a new http log LogFileCtx.
Definition: log-httplog.c:552
const char * ConfNodeLookupChildValue(const ConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:843
#define LOG_CF_SERVER_PORT
Definition: log-cf-common.h:46
LogCustomFormatNode * cf_nodes[LOG_MAXN_NODES]
Definition: log-cf-common.h:75
#define LOG_HTTP_EXTENDED
Definition: log-httplog.c:93
#define GET_IPV6_DST_ADDR(p)
Definition: decode.h:220
uint32_t size
Definition: util-buffer.h:29
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
#define LOG_CF_TIMESTAMP_U
Definition: log-cf-common.h:42
void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
#define SCEnter(...)
Definition: util-debug.h:337
LogFileCtx * LogFileNewCtx(void)
LogFileNewCtx() Get a new LogFileCtx.
uint8_t * buffer
Definition: util-buffer.h:28
#define PKT_IS_TOSERVER(p)
Definition: decode.h:257
void LogHttpLogRegister(void)
Definition: log-httplog.c:66
int SCConfLogOpenGeneric(ConfNode *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
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:267
LogCustomFormat * cf
Definition: log-httplog.c:89
#define SCReturnInt(x)
Definition: util-debug.h:341
uint16_t Port
Definition: decode.h:235
#define LOG_CF_CLIENT_IP
Definition: log-cf-common.h:43
#define LOG_CF_TIMESTAMP
Definition: log-cf-common.h:41
#define MEMBUFFER_BUFFER(mem_buffer)
Get the MemBuffers underlying buffer.
Definition: util-buffer.h:50
int ConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:566
void PrintRawUriBuf(char *retbuf, uint32_t *offset, uint32_t retbuflen, uint8_t *buf, uint32_t buflen)
Definition: util-print.c:118
Definition: conf.h:32
int(* Write)(const char *buffer, int buffer_len, struct LogFileCtx_ *fp)
OutputCtx * ctx
Definition: output.h:42
#define SCMalloc(a)
Definition: util-mem.h:222
#define GET_IPV6_SRC_ADDR(p)
Definition: decode.h:219
int LogFileFreeCtx(LogFileCtx *lf_ctx)
LogFileFreeCtx() Destroy a LogFileCtx (Close the file and free memory)
LogFileCtx * file_ctx
Definition: log-httplog.c:87
#define SCFree(a)
Definition: util-mem.h:322
#define PKT_IS_TCP(p)
Definition: decode.h:253
#define LOG_HTTP_DEFAULT
Definition: log-httplog.c:92
uint16_t tx_id
LogHttpFileCtx * httplog_ctx
Definition: log-httplog.c:97
#define MEMBUFFER_OFFSET(mem_buffer)
Get the MemBuffers current offset.
Definition: util-buffer.h:55
uint64_t ts
void * data
Definition: tm-modules.h:81
void OutputRegisterTxModule(LoggerId id, const char *name, const char *conf_name, OutputInitFunc InitFunc, AppProto alproto, TxLogger TxLogFunc, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Register a tx output module.
Definition: output.c:389
#define LOG_CF_SERVER_IP
Definition: log-cf-common.h:44
#define LOG_HTTP_CF_REQUEST_LEN
Definition: log-httplog.c:80
Per thread variable structure.
Definition: threadvars.h:57
struct timeval ts
Definition: decode.h:451
uint32_t flags
Definition: log-httplog.c:88
#define LOG_HTTP_CF_REQUEST_HEADER
Definition: log-httplog.c:78
#define LOG_CF_NONE
Definition: log-cf-common.h:39
#define LOG_HTTP_CF_REQUEST_METHOD
Definition: log-httplog.c:75
void LogCustomFormatWriteTimestamp(MemBuffer *buffer, const char *fmt, const struct timeval *ts)
Writes a timestamp with given format into a MemBuffer.
#define DEFAULT_LOG_FILENAME
Definition: log-httplog.c:54
uint32_t offset
Definition: util-buffer.h:30
#define OUTPUT_BUFFER_SIZE
Definition: log-httplog.c:58
TmEcode LogHttpLogThreadInit(ThreadVars *, const void *, void **)
Definition: log-httplog.c:506
int LogHttpLogger(ThreadVars *tv, void *thread_data, const Packet *, Flow *f, void *state, void *tx, uint64_t tx_id)
Definition: log-httplog.c:488
Flow data structure.
Definition: flow.h:325
#define LOG_HTTP_CF_REQUEST_PROTOCOL
Definition: log-httplog.c:74
#define LOG_HTTP_CF_REQUEST_HOST
Definition: log-httplog.c:73
void MemBufferFree(MemBuffer *buffer)
Definition: util-buffer.c:82
void LogCustomFormatFree(LogCustomFormat *cf)
Frees memory held by a custom format.
Definition: log-cf-common.c:78
#define LOG_CF_WRITE_STAR_SEPATATOR(buffer)
Definition: log-cf-common.h:53
void CreateTimeString(const struct timeval *ts, char *str, size_t size)
Definition: util-time.c:245
#define LOG_HTTP_CUSTOM
Definition: log-httplog.c:94
LogCustomFormat * LogCustomFormatAlloc()
Creates a custom format.
Definition: log-cf-common.c:52