suricata
custom-logger.c
Go to the documentation of this file.
1 /* Copyright (C) 2023-2024 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 #include "suricata-common.h"
19 #include "suricata-plugin.h"
20 
21 #include "output-packet.h"
22 #include "output-flow.h"
23 #include "output-tx.h"
24 #include "flow.h"
25 #include "util-print.h"
26 #include "output.h"
27 
28 static int CustomPacketLogger(ThreadVars *tv, void *thread_data, const Packet *p)
29 {
30  char src_ip[46] = { 0 }, dst_ip[46] = { 0 };
31 
32  if (PacketIsIPv4(p)) {
33  PrintInet(AF_INET, (const void *)&(p->src.addr_data32[0]), src_ip, sizeof(src_ip));
34  PrintInet(AF_INET, (const void *)&(p->dst.addr_data32[0]), dst_ip, sizeof(dst_ip));
35  } else if (PacketIsIPv6(p)) {
36  PrintInet(AF_INET6, (const void *)&(p->src.address), src_ip, sizeof(src_ip));
37  PrintInet(AF_INET6, (const void *)&(p->dst.address), dst_ip, sizeof(dst_ip));
38  } else {
39  SCLogNotice("Packet is not IP");
40  return 0;
41  }
42  SCLogNotice("Packet: %s -> %s", src_ip, dst_ip);
43  return 0;
44 }
45 
46 static bool CustomPacketLoggerCondition(ThreadVars *tv, void *thread_data, const Packet *)
47 {
48  /* Always true for this example. */
49  return true;
50 }
51 
52 static int CustomFlowLogger(ThreadVars *tv, void *thread_data, Flow *f)
53 {
54  char src_ip[46] = { 0 }, dst_ip[46] = { 0 };
55  Port sp, dp;
56 
57  if ((SCFlowGetFlags(f) & FLOW_DIR_REVERSED) == 0) {
58  if (SCFlowIsIPv4(f)) {
59  PrintInet(AF_INET, (const void *)SCFlowGetSourceAddressAsRawPtr(f), src_ip,
60  sizeof(src_ip));
61  PrintInet(AF_INET, (const void *)SCFlowGetDestinationAddressAsRawPtr(f), dst_ip,
62  sizeof(dst_ip));
63  } else if (SCFlowIsIPv6(f)) {
64  PrintInet(AF_INET6, (const void *)SCFlowGetSourceAddressAsRawPtr(f), src_ip,
65  sizeof(src_ip));
66  PrintInet(AF_INET6, (const void *)SCFlowGetDestinationAddressAsRawPtr(f), dst_ip,
67  sizeof(dst_ip));
68  }
69  sp = SCFlowGetSourcePort(f);
71  } else {
72  if (SCFlowIsIPv4(f)) {
73  PrintInet(AF_INET, (const void *)SCFlowGetDestinationAddressAsRawPtr(f), src_ip,
74  sizeof(src_ip));
75  PrintInet(AF_INET, (const void *)SCFlowGetSourceAddressAsRawPtr(f), dst_ip,
76  sizeof(dst_ip));
77  } else if (SCFlowIsIPv6(f)) {
78  PrintInet(AF_INET6, (const void *)SCFlowGetDestinationAddressAsRawPtr(f), src_ip,
79  sizeof(src_ip));
80  PrintInet(AF_INET6, (const void *)SCFlowGetSourceAddressAsRawPtr(f), dst_ip,
81  sizeof(dst_ip));
82  }
84  dp = SCFlowGetSourcePort(f);
85  }
86 
87  SCLogNotice("Flow: %s:%u -> %s:%u", src_ip, sp, dst_ip, dp);
88 
89  return 0;
90 }
91 
92 static int CustomDnsLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *state,
93  void *tx, uint64_t tx_id)
94 {
95  SCLogNotice("We have a DNS transaction");
96  return 0;
97 }
98 
99 static TmEcode ThreadInit(ThreadVars *tv, const void *initdata, void **data)
100 {
101  return TM_ECODE_OK;
102 }
103 
104 static TmEcode ThreadDeinit(ThreadVars *tv, void *data)
105 {
106  // Nothing to do. If we allocated data in ThreadInit we would free
107  // it here.
108  return TM_ECODE_OK;
109 }
110 
111 static void OnLoggingReady(void *arg)
112 {
113  SCOutputRegisterPacketLogger(LOGGER_USER, "custom-packet-logger", CustomPacketLogger,
114  CustomPacketLoggerCondition, NULL, ThreadInit, ThreadDeinit);
116  "custom-flow-logger", CustomFlowLogger, NULL, ThreadInit, ThreadDeinit);
117  SCOutputRegisterTxLogger(LOGGER_USER, "custom-dns-logger", ALPROTO_DNS, CustomDnsLogger, NULL,
118  -1, -1, NULL, ThreadInit, ThreadDeinit);
119 }
120 
121 static void Init(void)
122 {
123  // Register our callback for when logging is ready.
124  SCRegisterOnLoggingReady(OnLoggingReady, NULL);
125 }
126 
128  .version = SC_API_VERSION,
129  .suricata_version = SC_PACKAGE_VERSION,
130  .name = "CustomLogger",
131  .plugin_version = "1.0.0",
132  .author = "Firstname Lastname",
133  .license = "GPLv2",
134  .Init = Init,
135 };
136 
138 {
139  return &PluginRegistration;
140 }
SCFlowIsIPv4
bool SCFlowIsIPv4(const Flow *flow)
Return true if the flow is IPv4.
Definition: flow.c:1257
suricata-plugin.h
SCFlowGetSourceAddressAsRawPtr
const uint8_t * SCFlowGetSourceAddressAsRawPtr(const Flow *flow)
Returns a borrowed raw pointer to the flow source address.
Definition: flow.c:1244
output-tx.h
SCFlowGetDestinationPort
uint16_t SCFlowGetDestinationPort(const Flow *flow)
Get flow destination port.
Definition: flow.c:1290
ALPROTO_DNS
@ ALPROTO_DNS
Definition: app-layer-protos.h:47
LOGGER_USER
@ LOGGER_USER
Definition: suricata-common.h:522
Flow_
Flow data structure.
Definition: flow.h:355
output-packet.h
SCPlugin_::version
uint64_t version
Definition: suricata-plugin.h:43
p
Packet * p
Definition: fuzz_iprep.c:21
SCOutputRegisterFlowLogger
int SCOutputRegisterFlowLogger(const char *name, FlowLogger LogFunc, void *initdata, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
Register a flow logger.
Definition: output-flow.c:58
SCRegisterOnLoggingReady
int SCRegisterOnLoggingReady(SCOnLoggingReadyCallback callback, void *arg)
Register a callback to be called when logging is ready.
Definition: output.c:763
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
Address_::address
union Address_::@29 address
util-print.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
PrintInet
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:238
SCFlowGetSourcePort
uint16_t SCFlowGetSourcePort(const Flow *flow)
Get flow source port.
Definition: flow.c:1239
SCOutputRegisterTxLogger
int SCOutputRegisterTxLogger(LoggerId id, const char *name, AppProto alproto, TxLogger LogFunc, void *initdata, int tc_log_progress, int ts_log_progress, TxLoggerCondition LogCondition, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
Register a transaction logger.
Definition: output-tx.c:139
Packet_
Definition: decode.h:516
SCPlugin_
Definition: suricata-plugin.h:41
Port
uint16_t Port
Definition: decode.h:219
TmEcode
TmEcode
Definition: tm-threads-common.h:80
output-flow.h
SCOutputRegisterPacketLogger
int SCOutputRegisterPacketLogger(LoggerId logger_id, const char *name, PacketLogger LogFunc, PacketLogCondition ConditionFunc, void *initdata, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
Register a packet logger.
Definition: output-packet.c:55
SCFlowGetDestinationAddressAsRawPtr
const uint8_t * SCFlowGetDestinationAddressAsRawPtr(const Flow *flow)
Returns a borrowed raw pointer to the flow destination address.
Definition: flow.c:1249
SCFlowIsIPv6
bool SCFlowIsIPv6(const Flow *flow)
Return true if the flow is IPv6.
Definition: flow.c:1265
suricata-common.h
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:33
SCPluginRegister
const SCPlugin * SCPluginRegister(void)
Definition: custom-logger.c:137
SC_PACKAGE_VERSION
#define SC_PACKAGE_VERSION
Definition: suricata-plugin.h:36
PluginRegistration
const SCPlugin PluginRegistration
Definition: custom-logger.c:127
SCFlowGetFlags
uint64_t SCFlowGetFlags(const Flow *flow)
Get flow flags.
Definition: flow.c:1317
Packet_::dst
Address dst
Definition: decode.h:521
flow.h
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:250
FLOW_DIR_REVERSED
#define FLOW_DIR_REVERSED
Definition: flow.h:112
Packet_::src
Address src
Definition: decode.h:520
output.h