]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
examples: rename lib capture example to custom
authorJason Ish <jason.ish@oisf.net>
Wed, 10 Apr 2024 16:58:56 +0000 (10:58 -0600)
committerVictor Julien <victor@inliniac.net>
Tue, 1 Apr 2025 08:17:04 +0000 (10:17 +0200)
To keep the simple example simple, move the lib based capture method
example to its own example.

Ticket: #7240

Makefile.am
configure.ac
examples/lib/custom/.gitignore [new file with mode: 0644]
examples/lib/custom/Makefile.am [new file with mode: 0644]
examples/lib/custom/Makefile.example.in [new file with mode: 0644]
examples/lib/custom/README.md [new file with mode: 0644]
examples/lib/custom/main.c [new file with mode: 0644]
examples/lib/simple/Makefile.example.in
examples/lib/simple/main.c

index 48f1629127e49854b8bf36ac42eaf38537cf56e3..348ef59ba01dec29cc463ab1f0f594b7f0ac5674 100644 (file)
@@ -14,7 +14,7 @@ EXTRA_DIST = ChangeLog COPYING LICENSE suricata.yaml.in \
             examples/plugins
 SUBDIRS = $(HTP_DIR) rust src plugins qa rules doc etc python ebpf \
           $(SURICATA_UPDATE_DIR)
-DIST_SUBDIRS = $(SUBDIRS) examples/lib/simple
+DIST_SUBDIRS = $(SUBDIRS) examples/lib/simple examples/lib/custom
 
 CLEANFILES = stamp-h[0-9]*
 
index 3a69421c0fe76913b49759a503e49b96d75065c7..2a6c92007f7cd1f544b7d65030e77117e4d8ccb4 100644 (file)
@@ -2600,6 +2600,7 @@ AC_CONFIG_FILES(examples/plugins/c-json-filetype/Makefile)
 AC_CONFIG_FILES(examples/plugins/c-custom-loggers/Makefile)
 AC_CONFIG_FILES(examples/plugins/ci-capture/Makefile)
 AC_CONFIG_FILES(examples/lib/simple/Makefile examples/lib/simple/Makefile.example)
+AC_CONFIG_FILES(examples/lib/custom/Makefile examples/lib/custom/Makefile.example)
 AC_CONFIG_FILES(plugins/Makefile)
 AC_CONFIG_FILES(plugins/pfring/Makefile)
 AC_CONFIG_FILES(plugins/napatech/Makefile)
diff --git a/examples/lib/custom/.gitignore b/examples/lib/custom/.gitignore
new file mode 100644 (file)
index 0000000..579841d
--- /dev/null
@@ -0,0 +1,2 @@
+!/Makefile.example.in
+Makefile.example
diff --git a/examples/lib/custom/Makefile.am b/examples/lib/custom/Makefile.am
new file mode 100644 (file)
index 0000000..fc9899d
--- /dev/null
@@ -0,0 +1,12 @@
+bin_PROGRAMS = custom
+
+custom_SOURCES = main.c
+
+AM_CPPFLAGS = -I$(top_srcdir)/src
+
+custom_LDFLAGS = $(all_libraries) $(SECLDFLAGS)
+custom_LDADD = "-Wl,--start-group,$(top_builddir)/src/libsuricata_c.a,../../$(RUST_SURICATA_LIB),--end-group" $(RUST_LDADD)
+if HTP_LDADD
+custom_LDADD += ../../$(HTP_LDADD)
+endif
+custom_DEPENDENCIES = $(top_builddir)/src/libsuricata_c.a ../../$(RUST_SURICATA_LIB)
diff --git a/examples/lib/custom/Makefile.example.in b/examples/lib/custom/Makefile.example.in
new file mode 100644 (file)
index 0000000..d41a9c9
--- /dev/null
@@ -0,0 +1,16 @@
+LIBSURICATA_CONFIG ?=  @CONFIGURE_PREFIX@/bin/libsuricata-config
+
+SURICATA_LIBS =                `$(LIBSURICATA_CONFIG) --libs --static`
+SURICATA_CFLAGS :=     `$(LIBSURICATA_CONFIG) --cflags`
+
+# Currently the Suricata logging system requires this to be even for
+# plugins.
+CPPFLAGS +=    "-D__SCFILENAME__=\"$(*F)\""
+
+all: custom
+
+custom: main.c
+       $(CC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(SURICATA_CFLAGS) $(SURICATA_LIBS)
+
+clean:
+       rm -f custom
diff --git a/examples/lib/custom/README.md b/examples/lib/custom/README.md
new file mode 100644 (file)
index 0000000..2497ee9
--- /dev/null
@@ -0,0 +1,39 @@
+# Custom Library Example
+
+This is an example of using the Suriata library with your own packets
+and threads.
+
+## Building In Tree
+
+The Suricata build system has created a Makefile that should allow you
+to build this application in-tree on most supported platforms. To
+build simply run:
+
+```
+make
+```
+
+## Building Out of Tree
+
+A Makefile.example has also been generated to use as an example on how
+to build against the library in a standalone application.
+
+First build and install the Suricata library including:
+
+```
+make install-library
+make install-headers
+```
+
+Then run:
+
+```
+make -f Makefile.example
+```
+
+If you installed to a non-standard location, you need to ensure that
+`libsuricata-config` is in your path, for example:
+
+```
+PATH=/opt/suricata/bin:$PATH make -f Makefile.example
+```
diff --git a/examples/lib/custom/main.c b/examples/lib/custom/main.c
new file mode 100644 (file)
index 0000000..7e6900e
--- /dev/null
@@ -0,0 +1,125 @@
+/* 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 "suricata.h"
+#include "conf.h"
+#include "pcap.h"
+#include "runmode-lib.h"
+#include "source-lib.h"
+#include "threadvars.h"
+
+/* Suricata worker thread in library mode.
+   The functions should be wrapped in an API layer. */
+static void *SimpleWorker(void *arg)
+{
+    char *pcap_file = (char *)arg;
+
+    /* Create worker. */
+    ThreadVars *tv = RunModeCreateWorker();
+    if (!tv) {
+        pthread_exit(NULL);
+    }
+
+    /* Start worker. */
+    if (RunModeSpawnWorker(tv) != 0) {
+        pthread_exit(NULL);
+    }
+
+    /* Replay pcap. */
+    pcap_t *fp = pcap_open_offline(pcap_file, NULL);
+    if (fp == NULL) {
+        pthread_exit(NULL);
+    }
+
+    int datalink = pcap_datalink(fp);
+    struct pcap_pkthdr pkthdr;
+    const u_char *packet;
+    while ((packet = pcap_next(fp, &pkthdr)) != NULL) {
+        if (TmModuleLibHandlePacket(tv, packet, datalink, pkthdr.ts, pkthdr.len, 0, 0, NULL) != 0) {
+            pthread_exit(NULL);
+        }
+    }
+    pcap_close(fp);
+
+    /* Cleanup. */
+    RunModeDestroyWorker(tv);
+    pthread_exit(NULL);
+}
+
+int main(int argc, char **argv)
+{
+    SuricataPreInit(argv[0]);
+
+    /* Parse command line options. This is optional, you could
+     * directly configure Suricata through the Conf API.
+       The last argument is the PCAP file to replay. */
+    SCParseCommandLine(argc - 1, argv);
+
+    /* Set lib runmode. There is currently no way to set it via
+       the Conf API. */
+    SuricataSetLibRunmode();
+
+    /* Validate/finalize the runmode. */
+    if (SCFinalizeRunMode() != TM_ECODE_OK) {
+        exit(EXIT_FAILURE);
+    }
+
+    /* Handle internal runmodes. Typically you wouldn't do this as a
+     * library user, however this example is showing how to replicate
+     * the Suricata application with the library. */
+    switch (SCStartInternalRunMode(argc, argv)) {
+        case TM_ECODE_DONE:
+            exit(EXIT_SUCCESS);
+        case TM_ECODE_FAILED:
+            exit(EXIT_FAILURE);
+    }
+
+    /* Load configuration file, could be done earlier but must be done
+     * before SuricataInit, but even then its still optional as you
+     * may be programmatically configuration Suricata. */
+    if (SCLoadYamlConfig() != TM_ECODE_OK) {
+        exit(EXIT_FAILURE);
+    }
+
+    /* Set "offline" runmode to replay a pcap in library mode. */
+    if (!ConfSetFromString("runmode=offline", 1)) {
+        exit(EXIT_FAILURE);
+    }
+
+    SuricataInit();
+
+    /* Create and start worker on its own thread, passing the PCAP file
+       as argument. This needs to be done in between SuricataInit and
+       SuricataPostInit. */
+    pthread_t worker;
+    if (pthread_create(&worker, NULL, SimpleWorker, argv[argc - 1]) != 0) {
+        exit(EXIT_FAILURE);
+    }
+
+    /* Need to introduce a little sleep to allow the worker thread to
+       initialize before SuricataPostInit invokes TmThreadContinueThreads().
+       This should be handle at the API level. */
+    usleep(100);
+
+    SuricataPostInit();
+
+    /* Shutdown engine. */
+    SuricataShutdown();
+    GlobalsDestroy();
+
+    return EXIT_SUCCESS;
+}
index c9da97560e4dbe867d92a3a6bc8cd04a743abb86..724beccdb1409304538676f7658b9466be109db7 100644 (file)
@@ -1,16 +1,12 @@
 LIBSURICATA_CONFIG ?=  @CONFIGURE_PREFIX@/bin/libsuricata-config
 
-SURICATA_LIBS =                `$(LIBSURICATA_CONFIG) --libs --static`
+SURICATA_LIBS =                `$(LIBSURICATA_CONFIG) --libs`
 SURICATA_CFLAGS :=     `$(LIBSURICATA_CONFIG) --cflags`
 
-# Currently the Suricata logging system requires this to be even for
-# plugins.
-CPPFLAGS +=    "-D__SCFILENAME__=\"$(*F)\""
-
 all: simple
 
 simple: main.c
-       $(CC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(SURICATA_CFLAGS) $(SURICATA_LIBS)
+       $(CC) -o $@ $^ $(CFLAGS) $(SURICATA_CFLAGS) $(SURICATA_LIBS)
 
 clean:
        rm -f simple
index 7e6900e5f40cd226dd2d68d40f668a3e717a6725..f9c09fb0f55085e5ca147a7f6df3d8f96bbb4437 100644 (file)
  */
 
 #include "suricata.h"
-#include "conf.h"
-#include "pcap.h"
-#include "runmode-lib.h"
-#include "source-lib.h"
-#include "threadvars.h"
-
-/* Suricata worker thread in library mode.
-   The functions should be wrapped in an API layer. */
-static void *SimpleWorker(void *arg)
-{
-    char *pcap_file = (char *)arg;
-
-    /* Create worker. */
-    ThreadVars *tv = RunModeCreateWorker();
-    if (!tv) {
-        pthread_exit(NULL);
-    }
-
-    /* Start worker. */
-    if (RunModeSpawnWorker(tv) != 0) {
-        pthread_exit(NULL);
-    }
-
-    /* Replay pcap. */
-    pcap_t *fp = pcap_open_offline(pcap_file, NULL);
-    if (fp == NULL) {
-        pthread_exit(NULL);
-    }
-
-    int datalink = pcap_datalink(fp);
-    struct pcap_pkthdr pkthdr;
-    const u_char *packet;
-    while ((packet = pcap_next(fp, &pkthdr)) != NULL) {
-        if (TmModuleLibHandlePacket(tv, packet, datalink, pkthdr.ts, pkthdr.len, 0, 0, NULL) != 0) {
-            pthread_exit(NULL);
-        }
-    }
-    pcap_close(fp);
-
-    /* Cleanup. */
-    RunModeDestroyWorker(tv);
-    pthread_exit(NULL);
-}
 
 int main(int argc, char **argv)
 {
     SuricataPreInit(argv[0]);
 
     /* Parse command line options. This is optional, you could
-     * directly configure Suricata through the Conf API.
-       The last argument is the PCAP file to replay. */
-    SCParseCommandLine(argc - 1, argv);
-
-    /* Set lib runmode. There is currently no way to set it via
-       the Conf API. */
-    SuricataSetLibRunmode();
+     * directly configure Suricata through the Conf API. */
+    SCParseCommandLine(argc, argv);
 
     /* Validate/finalize the runmode. */
     if (SCFinalizeRunMode() != TM_ECODE_OK) {
@@ -95,28 +47,13 @@ int main(int argc, char **argv)
         exit(EXIT_FAILURE);
     }
 
-    /* Set "offline" runmode to replay a pcap in library mode. */
-    if (!ConfSetFromString("runmode=offline", 1)) {
-        exit(EXIT_FAILURE);
-    }
-
     SuricataInit();
-
-    /* Create and start worker on its own thread, passing the PCAP file
-       as argument. This needs to be done in between SuricataInit and
-       SuricataPostInit. */
-    pthread_t worker;
-    if (pthread_create(&worker, NULL, SimpleWorker, argv[argc - 1]) != 0) {
-        exit(EXIT_FAILURE);
-    }
-
-    /* Need to introduce a little sleep to allow the worker thread to
-       initialize before SuricataPostInit invokes TmThreadContinueThreads().
-       This should be handle at the API level. */
-    usleep(100);
-
     SuricataPostInit();
 
+    /* Suricata is now running, but we enter a loop to keep it running
+     * until it shouldn't be running anymore. */
+    SuricataMainLoop();
+
     /* Shutdown engine. */
     SuricataShutdown();
     GlobalsDestroy();