mirror of https://github.com/OISF/suricata
flow: add callbacks for flow init and flow updates
Adds user registerable callbacks for flow initialization, flow update and flow finish. Some plugins, such as other DPI libraries like nDPI need a way to hook into these flow lifecycle events. Ticket: #7319 Ticket: #7320pull/12117/head
parent
b30df19f1a
commit
a6fc37c90a
@ -0,0 +1,129 @@
|
||||
/* Copyright (C) 2024 Open Information Security Foundation
|
||||
*
|
||||
* You can copy, redistribute or modify this Program under the terms of
|
||||
* the GNU General Public License version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "flow-callbacks.h"
|
||||
|
||||
typedef struct FlowInitCallback_ {
|
||||
SCFlowInitCallbackFn Callback;
|
||||
void *user;
|
||||
struct FlowInitCallback_ *next;
|
||||
} FlowInitCallback;
|
||||
|
||||
static FlowInitCallback *init_callbacks = NULL;
|
||||
|
||||
typedef struct FlowUpdateCallback_ {
|
||||
SCFlowUpdateCallbackFn Callback;
|
||||
void *user;
|
||||
struct FlowUpdateCallback_ *next;
|
||||
} FlowUpdateCallback;
|
||||
|
||||
static FlowUpdateCallback *update_callbacks = NULL;
|
||||
|
||||
typedef struct FlowFinishCallback_ {
|
||||
SCFlowFinishCallbackFn Callback;
|
||||
void *user;
|
||||
struct FlowFinishCallback_ *next;
|
||||
} FlowFinishCallback;
|
||||
|
||||
static FlowFinishCallback *finish_callbacks = NULL;
|
||||
|
||||
bool SCFlowRegisterInitCallback(SCFlowInitCallbackFn fn, void *user)
|
||||
{
|
||||
FlowInitCallback *cb = SCCalloc(1, sizeof(*cb));
|
||||
if (cb == NULL) {
|
||||
return false;
|
||||
}
|
||||
cb->Callback = fn;
|
||||
cb->user = user;
|
||||
if (init_callbacks == NULL) {
|
||||
init_callbacks = cb;
|
||||
} else {
|
||||
FlowInitCallback *current = init_callbacks;
|
||||
while (current->next != NULL) {
|
||||
current = current->next;
|
||||
}
|
||||
current->next = cb;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SCFlowRunInitCallbacks(ThreadVars *tv, Flow *f, const Packet *p)
|
||||
{
|
||||
FlowInitCallback *cb = init_callbacks;
|
||||
while (cb != NULL) {
|
||||
cb->Callback(tv, f, p, cb->user);
|
||||
cb = cb->next;
|
||||
}
|
||||
}
|
||||
|
||||
bool SCFlowRegisterUpdateCallback(SCFlowUpdateCallbackFn fn, void *user)
|
||||
{
|
||||
FlowUpdateCallback *cb = SCCalloc(1, sizeof(*cb));
|
||||
if (cb == NULL) {
|
||||
return false;
|
||||
}
|
||||
cb->Callback = fn;
|
||||
cb->user = user;
|
||||
if (update_callbacks == NULL) {
|
||||
update_callbacks = cb;
|
||||
} else {
|
||||
FlowUpdateCallback *current = update_callbacks;
|
||||
while (current->next != NULL) {
|
||||
current = current->next;
|
||||
}
|
||||
current->next = cb;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SCFlowRunUpdateCallbacks(ThreadVars *tv, Flow *f, Packet *p)
|
||||
{
|
||||
FlowUpdateCallback *cb = update_callbacks;
|
||||
while (cb != NULL) {
|
||||
cb->Callback(tv, f, p, cb->user);
|
||||
cb = cb->next;
|
||||
}
|
||||
}
|
||||
|
||||
bool SCFlowRegisterFinishCallback(SCFlowFinishCallbackFn fn, void *user)
|
||||
{
|
||||
FlowFinishCallback *cb = SCCalloc(1, sizeof(*cb));
|
||||
if (cb == NULL) {
|
||||
return false;
|
||||
}
|
||||
cb->Callback = fn;
|
||||
cb->user = user;
|
||||
if (finish_callbacks == NULL) {
|
||||
finish_callbacks = cb;
|
||||
} else {
|
||||
FlowFinishCallback *current = finish_callbacks;
|
||||
while (current->next != NULL) {
|
||||
current = current->next;
|
||||
}
|
||||
current->next = cb;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SCFlowRunFinishCallbacks(ThreadVars *tv, Flow *f)
|
||||
{
|
||||
FlowFinishCallback *cb = finish_callbacks;
|
||||
while (cb != NULL) {
|
||||
cb->Callback(tv, f, cb->user);
|
||||
cb = cb->next;
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
/* Copyright (C) 2024 Open Information Security Foundation
|
||||
*
|
||||
* You can copy, redistribute or modify this Program under the terms of
|
||||
* the GNU General Public License version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef SURICATA_FLOW_CALLBACKS_H
|
||||
#define SURICATA_FLOW_CALLBACKS_H
|
||||
|
||||
#include "suricata-common.h"
|
||||
#include "flow.h"
|
||||
|
||||
/** \brief Function type for flow initialization callbacks.
|
||||
*
|
||||
* Once registered with SCFlowRegisterInitCallback, this function will
|
||||
* be called every time a flow is initialized, or in other words,
|
||||
* every time Suricata picks up a flow.
|
||||
*
|
||||
* \param tv The ThreadVars data structure for the thread creating the
|
||||
* flow.
|
||||
* \param f The newly initialized flow.
|
||||
* \param p The packet related to creating the new flow.
|
||||
* \param user The user data provided during callback registration.
|
||||
*/
|
||||
typedef void (*SCFlowInitCallbackFn)(ThreadVars *tv, Flow *f, const Packet *p, void *user);
|
||||
|
||||
/** \brief Register a flow init callback.
|
||||
*
|
||||
* Register a user provided function to be called every time a flow is
|
||||
* initialized for use.
|
||||
*
|
||||
* \param fn Pointer to function to be called
|
||||
* \param user Additional user data to be passed to callback
|
||||
*
|
||||
* \returns true if callback was registered, otherwise false if the
|
||||
* callback could not be registered due to memory allocation error.
|
||||
*/
|
||||
bool SCFlowRegisterInitCallback(SCFlowInitCallbackFn fn, void *user);
|
||||
|
||||
/** \internal
|
||||
*
|
||||
* Run all registered flow init callbacks.
|
||||
*/
|
||||
void SCFlowRunInitCallbacks(ThreadVars *tv, Flow *f, const Packet *p);
|
||||
|
||||
/** \brief Function type for flow update callbacks.
|
||||
*
|
||||
* Once registered with SCFlowRegisterUpdateCallback, this function
|
||||
* will be called every time a flow is updated by a packet (basically
|
||||
* everytime a packet is seen on a flow).
|
||||
*
|
||||
* \param tv The ThreadVars data structure for the thread updating the
|
||||
* flow.
|
||||
* \param f The flow being updated.
|
||||
* \param p The packet responsible for the flow update.
|
||||
* \param user The user data provided during callback registration.
|
||||
*/
|
||||
typedef void (*SCFlowUpdateCallbackFn)(ThreadVars *tv, Flow *f, Packet *p, void *user);
|
||||
|
||||
/** \brief Register a flow update callback.
|
||||
*
|
||||
* Register a user provided function to be called everytime a flow is
|
||||
* updated.
|
||||
*
|
||||
* \param fn Pointer to function to be called
|
||||
* \param user Additional user data to be passed to callback
|
||||
*
|
||||
* \returns true if callback was registered, otherwise false if the
|
||||
* callback could not be registered due to memory allocation error.
|
||||
*/
|
||||
bool SCFlowRegisterUpdateCallback(SCFlowUpdateCallbackFn fn, void *user);
|
||||
|
||||
/** \internal
|
||||
*
|
||||
* Run all registered flow update callbacks.
|
||||
*/
|
||||
void SCFlowRunUpdateCallbacks(ThreadVars *tv, Flow *f, Packet *p);
|
||||
|
||||
/** \brief Function type for flow finish callbacks.
|
||||
*
|
||||
* Once registered with SCFlowRegisterFinshCallback, this function
|
||||
* will be called when Suricata is done with a flow.
|
||||
*
|
||||
* \param tv The ThreadVars data structure for the thread finishing
|
||||
* the flow.
|
||||
* \param f The flow being finshed.
|
||||
* \param user The user data provided during callback registration.
|
||||
*/
|
||||
typedef void (*SCFlowFinishCallbackFn)(ThreadVars *tv, Flow *f, void *user);
|
||||
|
||||
/** \brief Register a flow init callback.
|
||||
*
|
||||
* Register a user provided function to be called every time a flow is
|
||||
* finished.
|
||||
*
|
||||
* \param fn Pointer to function to be called
|
||||
* \param user Additional user data to be passed to callback
|
||||
*
|
||||
* \returns true if callback was registered, otherwise false if the
|
||||
* callback could not be registered due to memory allocation error.
|
||||
*/
|
||||
bool SCFlowRegisterFinishCallback(SCFlowFinishCallbackFn fn, void *user);
|
||||
|
||||
/** \internal
|
||||
*
|
||||
* Run all registered flow init callbacks.
|
||||
*/
|
||||
void SCFlowRunFinishCallbacks(ThreadVars *tv, Flow *f);
|
||||
|
||||
#endif /* SURICATA_FLOW_CALLBACKS_H */
|
Loading…
Reference in New Issue