-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[draft] flow callbacks for ndpi - v1 #11935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,7 @@ SUBDIRS = | |
if BUILD_PFRING | ||
SUBDIRS += pfring | ||
endif | ||
|
||
if BUILD_NDPI | ||
SUBDIRS += ndpi-dummy | ||
endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
pkglib_LTLIBRARIES = ndpi.la | ||
|
||
ndpi_la_LDFLAGS = -module -avoid-version -shared | ||
|
||
ndpi_la_SOURCES = ndpi.c | ||
|
||
install-exec-hook: | ||
cd $(DESTDIR)$(pkglibdir) && $(RM) $(pkglib_LTLIBRARIES) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* 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. | ||
*/ | ||
|
||
/* License note: While this "glue" code to the nDPI library is GPLv2, | ||
* nDPI is itself LGPLv3 which is known to be incompatible with the | ||
* GPLv2. */ | ||
|
||
#include "suricata-common.h" | ||
#include "suricata-plugin.h" | ||
#include "util-debug.h" | ||
|
||
#include "flow-callbacks.h" | ||
#include "flow-storage.h" | ||
|
||
static FlowStorageId flow_storage_id = { .id = -1 }; | ||
|
||
static void *FlowStorageAlloc(unsigned int size) | ||
{ | ||
SCLogNotice("Allocating nDPI flow storage, size=%d", size); | ||
return NULL; | ||
} | ||
|
||
static void FlowStorageFree(void *ptr) | ||
{ | ||
SCLogNotice("De-allocating nDPI flow storage"); | ||
int *dummy_storage = ptr; | ||
SCLogNotice("%d", *dummy_storage); | ||
SCFree(ptr); | ||
} | ||
|
||
static void OnFlowInit(Flow *f, const Packet *p) | ||
{ | ||
SCLogNotice("..."); | ||
static int counter = 0; | ||
int *dummy_storage = SCCalloc(1, sizeof(int)); | ||
*dummy_storage = counter++; | ||
FlowSetStorageById(f, flow_storage_id, dummy_storage); | ||
} | ||
|
||
static void OnFlowUpdate(Flow *f, Packet *p, ThreadVars *tv) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should there be user data here as well? general user data? Perhaps not needed for ndpi There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess more for the library, but if someone wanted to create a simple flow logger, they'd want to pass a file pointer around these callbacks to log a new flow creation, or a flow destruction, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably should have user data, was being short sighted and only looking at the case at hand which doesn't need it. |
||
{ | ||
SCLogNotice("..."); | ||
int *dummy_storage = FlowGetStorageById(f, flow_storage_id); | ||
SCLogNotice("dummy_storage=%d", *dummy_storage); | ||
} | ||
|
||
static void NdpiInit(void) | ||
{ | ||
SCLogNotice("Initializing nDPI plugin"); | ||
|
||
flow_storage_id = FlowStorageRegister("ndpi", sizeof(void *), NULL, FlowStorageFree); | ||
if (flow_storage_id.id < 0) { | ||
FatalError("Failed to register nDPI flow storage"); | ||
} | ||
|
||
SCFlowRegisterInitCallback(OnFlowInit); | ||
SCFlowRegisterUpdateCallback(OnFlowUpdate); | ||
} | ||
|
||
const SCPlugin PluginRegistration = { | ||
.name = "ndpi-dummy", | ||
.author = "FirstName LastName", | ||
.license = "GPLv2", | ||
.Init = NdpiInit, | ||
}; | ||
|
||
const SCPlugin *SCPluginRegister() | ||
{ | ||
return &PluginRegistration; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* 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 fn; | ||
struct FlowInitCallback_ *next; | ||
} FlowInitCallback; | ||
|
||
static FlowInitCallback *init_callbacks = NULL; | ||
|
||
typedef struct FlowUpdateCallback_ { | ||
SCFlowUpdateCallbackFn fn; | ||
struct FlowUpdateCallback_ *next; | ||
} FlowUpdateCallback; | ||
|
||
static FlowUpdateCallback *update_callbacks = NULL; | ||
|
||
bool SCFlowRegisterInitCallback(SCFlowInitCallbackFn fn) | ||
{ | ||
FlowInitCallback *cb = SCCalloc(1, sizeof(*cb)); | ||
if (cb == NULL) { | ||
return false; | ||
} | ||
cb->fn = fn; | ||
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(Flow *f, const Packet *p) | ||
{ | ||
FlowInitCallback *cb = init_callbacks; | ||
while (cb != NULL) { | ||
cb->fn(f, p); | ||
cb = cb->next; | ||
} | ||
} | ||
|
||
bool SCFlowRegisterUpdateCallback(SCFlowUpdateCallbackFn fn) | ||
{ | ||
FlowUpdateCallback *cb = SCCalloc(1, sizeof(*cb)); | ||
if (cb == NULL) { | ||
return false; | ||
} | ||
cb->fn = fn; | ||
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(Flow *f, Packet *p, ThreadVars *tv) | ||
{ | ||
FlowUpdateCallback *cb = update_callbacks; | ||
while (cb != NULL) { | ||
cb->fn(f, p, tv); | ||
cb = cb->next; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* 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" | ||
|
||
typedef void (*SCFlowInitCallbackFn)(Flow *f, const Packet *p); | ||
|
||
/** \brief Register a flow init callback. | ||
* | ||
* Register a user provided function to be called every time a flow is | ||
* initialized for use. | ||
* | ||
* \returns true if callback was registered, otherwise false if the | ||
* callback could not be registered due to memory allocation error. | ||
*/ | ||
bool SCFlowRegisterInitCallback(SCFlowInitCallbackFn fn); | ||
|
||
/** \internal | ||
* | ||
* Run all registered flow init callbacks. | ||
*/ | ||
void SCFlowRunInitCallbacks(Flow *f, const Packet *p); | ||
|
||
typedef void (*SCFlowUpdateCallbackFn)(Flow *f, Packet *p, ThreadVars *tv); | ||
|
||
/** \brief Register a flow update callback. | ||
* | ||
* Register a user provided function to be called everytime a flow is | ||
* updated. | ||
* | ||
* \returns true if callback was registered, otherwise false if the | ||
* callback could not be registered due to memory allocation error. | ||
*/ | ||
bool SCFlowRegisterUpdateCallback(SCFlowUpdateCallbackFn fn); | ||
|
||
/** \internal | ||
* | ||
* Run all registered flow update callbacks. | ||
*/ | ||
void SCFlowRunUpdateCallbacks(Flow *f, Packet *p, ThreadVars *tv); | ||
|
||
#endif /* SURICATA_FLOW_CALLBACKS_H */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I'd expect a OnFlowDestruct too, although perhaps we don't need it directly here, as the FlowStorage API knowns how to destroy the user data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, for completeness should probably add it. Not needed for storage cleanup using the storage API, and someone else uses the flow event for their private cleanup, but it does feel missing.