From 61ef846c801f027cee5febc9ea06acb2b99ade90 Mon Sep 17 00:00:00 2001 From: Hitoshi Irino Date: Sun, 4 Aug 2019 10:09:38 +0900 Subject: [PATCH] Change ntopng function - replace enable-zeromq to enable-ntopng - replace -v 11 to -v ntopng for NTOPNG direct injection --- Makefile.am | 15 ++++++----- configure.ac | 21 +++++++++------- netflow1.c | 5 ++-- netflow5.c | 4 +-- netflow9.c | 4 +-- netflow9.h | 4 +-- softflowd.c | 71 ++++++++++++++++++++++++++++++++-------------------- softflowd.h | 16 ++++++------ 8 files changed, 83 insertions(+), 57 deletions(-) diff --git a/Makefile.am b/Makefile.am index ca1e30d..ff58d6d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,14 +1,17 @@ bin_PROGRAMS = softflowd softflowctl COMMON = common.h convtime.h treetype.h sys-tree.h\ convtime.c strlcpy.c strlcat.c closefrom.c daemon.c -if ENABLE_ZEROMQ - ntopng.c = ntopng.c +if ENABLE_LEGACY + LEGACY_SOURCES = netflow9.c netflow1.c +endif +if ENABLE_NTOPNG + NTOPNG_SOURCES = ntopng.c endif softflowd_SOURCES = freelist.h log.h softflowd.h netflow9.h ipfix.h psamp.h\ - freelist.c softflowd.c log.c netflow5.c ipfix.c psamp.c $(ntopng.c)\ + freelist.c softflowd.c log.c netflow5.c ipfix.c psamp.c\ $(COMMON) -EXTRA_softflowd_SOURCES = netflow9.c netflow1.c -softflowd_LDADD = $(LEGACY) -softflowd_DEPENDENCIES = $(LEGACY) +EXTRA_softflowd_SOURCES = $(LEGACY_SOURCES) $(NTOPNG_SOURCES) +softflowd_LDADD = $(LEGACY) $(NTOPNG) +softflowd_DEPENDENCIES = $(LEGACY) $(NTOPNG) softflowctl_SOURCES = softflowctl.c $(COMMON) dist_man_MANS = softflowd.8 softflowctl.8 diff --git a/configure.ac b/configure.ac index 47ec597..96bf11d 100644 --- a/configure.ac +++ b/configure.ac @@ -39,9 +39,9 @@ AC_ARG_ENABLE(legacy, AC_ARG_ENABLE(pthread, AC_HELP_STRING([--enable-pthread], [enable pthread (default NO)]), [pthread=yes],[pthread=no]) -AC_ARG_ENABLE(zeromq, - AC_HELP_STRING([--enable-zeromq], [enable zeromq for notpng (default NO)]), - [zeromq=yes],[zeromq=no]) +AC_ARG_ENABLE(ntopng, + AC_HELP_STRING([--enable-ntopng], [enable flow sending to ntopng with zeromq (default NO)]), + [ntopng=yes],[ntopng=no]) AC_ARG_ENABLE(flow-spray, AC_HELP_STRING([--enable-flow-spray], [enable spray as flow tree type(default is RB)]), @@ -122,21 +122,24 @@ AC_CHECK_SIZEOF(long int, 4) AC_CHECK_SIZEOF(long long int, 8) if test "x$legacy" = "xyes" ; then - AC_DEFINE([LEGACY], 1, [enable legacy NetFlow implementation]) + AC_DEFINE([ENABLE_LEGACY], 1, [enable legacy NetFlow implementation]) LEGACY='netflow9.$(OBJEXT) netflow1.$(OBJEXT)' AC_SUBST([LEGACY]) fi +AM_CONDITIONAL([ENABLE_LEGACY], [test x$legacy = xyes]) if test "x$pthread" = "xyes" ; then AC_DEFINE([ENABLE_PTHREAD], 1, [enable pthread]) AC_CHECK_LIB(pthread, pthread_create, [],[AC_MSG_ERROR([pthread.h not found])]) AC_CHECK_HEADERS(pthread.h, [],[AC_MSG_ERROR([pthread.h not found])]) fi -if test "x$zeromq" = "xyes" ; then - AC_DEFINE([ENABLE_ZEROMQ], 1, [enable zeromq]) - AC_CHECK_LIB(zmq, zmq_connect, [],[AC_MSG_ERROR([libzmq not found])]) - AC_CHECK_HEADERS(zmq.h, [],[AC_MSG_ERROR([zmq.h not found])]) +if test "x$ntopng" = "xyes" ; then + AC_DEFINE([ENABLE_NTOPNG], 1, [enable ntopng]) + AC_CHECK_LIB(zmq, zmq_connect, [],[AC_MSG_ERROR([libzmq not found])]) + AC_CHECK_HEADERS(zmq.h, [],[AC_MSG_ERROR([zmq.h not found])]) + NTOPNG='ntopng.$(OBJEXT)' + AC_SUBST([NTOPNG]) fi -AM_CONDITIONAL([ENABLE_ZEROMQ], [test x$zeromq = xyes]) +AM_CONDITIONAL([ENABLE_NTOPNG], [test x$ntopng = xyes]) if test "x$ac_cv_type_uint8_t" = "xyes" ; then AC_DEFINE([OUR_CFG_U_INT8_T], [uint8_t], [8-bit unsigned int]) elif test "x$ac_cv_sizeof_char" = "x1" ; then diff --git a/netflow1.c b/netflow1.c index 037bac5..aad15cd 100644 --- a/netflow1.c +++ b/netflow1.c @@ -1,3 +1,4 @@ + /* * Copyright 2002 Damien Miller All rights reserved. * @@ -26,7 +27,7 @@ #include "treetype.h" #include "softflowd.h" -#ifdef LEGACY +#ifdef ENABLE_LEGACY /* * This is the Cisco Netflow(tm) version 1 packet format * Based on: @@ -174,4 +175,4 @@ send_netflow_v1 (struct SENDPARAMETER sp) { #endif /* ENABLE_PTHREAD */ return (num_packets); } -#endif /* LEGACY */ +#endif /* ENABLE_LEGACY */ diff --git a/netflow5.c b/netflow5.c index 40d56dd..ea4b861 100644 --- a/netflow5.c +++ b/netflow5.c @@ -225,9 +225,9 @@ send_netflow_v5 (struct SENDPARAMETER sp) { return send_netflow_v5_v1 (sp, 5); } -#ifndef LEGACY +#ifndef ENABLE_LEGACY int send_netflow_v1 (struct SENDPARAMETER sp) { return send_netflow_v5_v1 (sp, 1); } -#endif /* LEGACY */ +#endif /* ENABLE_LEGACY */ diff --git a/netflow9.c b/netflow9.c index 88e905a..4a6046f 100644 --- a/netflow9.c +++ b/netflow9.c @@ -329,7 +329,7 @@ nf_flow_to_flowset (const struct FLOW *flow, u_char * packet, u_int len, * Given an array of expired flows, send netflow v9 report packets * Returns number of packets sent or -1 on error */ -#ifdef LEGACY +#ifdef ENABLE_LEGACY int send_netflow_v9 (struct SENDPARAMETER sp) { struct FLOW **flows = sp.flows; @@ -478,7 +478,7 @@ send_netflow_v9 (struct SENDPARAMETER sp) { #endif /* ENABLE_PTHREAD */ return (num_packets); } -#endif /* LEGACY */ +#endif /* ENABLE_LEGACY */ void netflow9_resend_template (void) { diff --git a/netflow9.h b/netflow9.h index c19ffaa..1e34030 100644 --- a/netflow9.h +++ b/netflow9.h @@ -44,11 +44,11 @@ struct NFLOW9_HEADER { u_int32_t sequence, od_id; } __packed; -#ifdef LEGACY +#ifdef ENABLE_LEGACY /* Prototypes for functions to send NetFlow packets, from netflow*.c */ int send_netflow_v9 (struct SENDPARAMETER sp); /* Force a resend of the flow template */ void netflow9_resend_template (void); -#endif /* LEGACY */ +#endif /* ENABLE_LEGACY */ #endif /* _NETFLOW9_H */ diff --git a/softflowd.c b/softflowd.c index 757f0b5..aab29d2 100644 --- a/softflowd.c +++ b/softflowd.c @@ -121,24 +121,37 @@ struct NETFLOW_SENDER { }; #define NF_VERSION_IPFIX 10 -#define NF_VERSION_NTOPNG 11 +// The version field in NetFow and IPFIX headers is 16 bits unsiged int. +// If the version number is over 0x7fff0000, it is unique number in softflowd. +#define SOFTFLOWD_NF_VERSION_NTOPNG (0x7fff0001) +#define SOFTFLOWD_NF_VERSION_NTOPNG_STRING "ntopng" /* Array of NetFlow export function that we know of. NB. nf[0] is default */ static const struct NETFLOW_SENDER nf[] = { {5, send_netflow_v5, NULL, 0}, {1, send_netflow_v1, NULL, 0}, -#ifdef LEGACY +#ifdef ENABLE_LEGACY {9, send_netflow_v9, NULL, 1}, -#else /* LEGACY */ +#else /* ENABLE_LEGACY */ {9, send_nflow9, NULL, 1}, -#endif /* LEGACY */ +#endif /* ENABLE_LEGACY */ {NF_VERSION_IPFIX, send_ipfix, send_ipfix_bi, 1}, -#ifdef ENABLE_ZEROMQ - {NF_VERSION_NTOPNG, send_ntopng, NULL, 1}, +#ifdef ENABLE_NTOPNG + {SOFTFLOWD_NF_VERSION_NTOPNG, send_ntopng, NULL, 1}, #endif - {-1, NULL, NULL, 0}, }; +static const struct NETFLOW_SENDER * +lookup_netflow_sender (int version) { + int i, r; + for (i = 0, r = version; i < sizeof (nf) / sizeof (struct NETFLOW_SENDER); + i++) { + if (nf[i].version == r) + return &nf[i]; + } + return NULL; +} + /* Signal handlers */ static void sighand_graceful_shutdown (int signum) { @@ -1384,21 +1397,21 @@ accept_control (int lsock, struct NETFLOW_TARGET *target, *exit_request = 1; ret = 1; } else if (strcmp (buf, "expire-all") == 0) { -#ifdef LEGACY +#ifdef ENABLE_LEGACY netflow9_resend_template (); -#else /* LEGACY */ +#else /* ENABLE_LEGACY */ ipfix_resend_template (); -#endif /* LEGACY */ +#endif /* ENABLE_LEGACY */ fprintf (ctlf, "softflowd[%u]: Expired %d flows.\n", (unsigned int) getpid (), check_expired (ft, target, CE_EXPIRE_ALL)); ret = 0; } else if (strcmp (buf, "send-template") == 0) { -#ifdef LEGACY +#ifdef ENABLE_LEGACY netflow9_resend_template (); -#else /* LEGACY */ +#else /* ENABLE_LEGACY */ ipfix_resend_template (); -#endif /* LEGACY */ +#endif /* ENABLE_LEGACY */ fprintf (ctlf, "softflowd[%u]: Template will be sent at " "next flow export\n", (unsigned int) getpid ()); ret = 0; @@ -1667,9 +1680,11 @@ usage (void) { " (default: %s)\n" " -c socketfile Location of control socket\n" " (default: %s)\n" - " -v 1|5|9|%d|%d|psamp NetFlow export packet version\n" - " %d means IPFIX, %d means NTOPNG (if supported),\n" - " and psamp means PSAMP (packet sampling)\n" + " -v 1|5|9|10|psamp NetFlow export packet version\n" + " 10 means IPFIX and psamp means PSAMP (packet sampling)\n" +#ifdef ENABLE_NTOPNG + " ntopng ntopng means direct injection to NTOPNG (if supported).\n" +#endif " -L hoplimit Set TTL/hoplimit for export datagrams\n" " -T full|port|proto|ip| Set flow tracking level (default: full)\n" " vlan (\"vlan\" tracking means \"full\" tracking with vlanid)\n" @@ -1702,7 +1717,6 @@ usage (void) { "\n", PROGNAME, PROGNAME, PROGVER, DEFAULT_MAX_FLOWS, DEFAULT_PIDFILE, DEFAULT_CTLSOCK, - NF_VERSION_IPFIX, NF_VERSION_NTOPNG, NF_VERSION_IPFIX, NF_VERSION_NTOPNG, DEFAULT_TCP_TIMEOUT, DEFAULT_TCP_RST_TIMEOUT, DEFAULT_TCP_FIN_TIMEOUT, DEFAULT_UDP_TIMEOUT, DEFAULT_ICMP_TIMEOUT, DEFAULT_GENERAL_TIMEOUT, DEFAULT_MAXIMUM_LIFETIME, @@ -1887,6 +1901,7 @@ main (int argc, char **argv) { struct pollfd pl[2]; struct DESTINATION *dest; int protocol = IPPROTO_UDP; + int version = 0; #ifdef ENABLE_PTHREAD int use_thread = 0; pthread_t read_thread = 0; @@ -2022,15 +2037,16 @@ main (int argc, char **argv) { flowtrack.param.is_psamp = 1; break; } - for (i = 0, r = atoi (optarg); nf[i].version != -1; i++) { - if (nf[i].version == r) - break; + if (!strncmp (optarg, SOFTFLOWD_NF_VERSION_NTOPNG_STRING, + sizeof (SOFTFLOWD_NF_VERSION_NTOPNG_STRING))) { + version = SOFTFLOWD_NF_VERSION_NTOPNG; } - if (nf[i].version == -1) { + version = version ? version : atoi (optarg); + target.dialect = lookup_netflow_sender (version); + if (target.dialect == NULL) { fprintf (stderr, "Invalid NetFlow version\n"); exit (1); } - target.dialect = &nf[i]; break; case 's': flowtrack.param.option.sample = atoi (optarg); @@ -2116,18 +2132,19 @@ main (int argc, char **argv) { fprintf (stderr, "getnameinfo: %d\n", err); exit (1); } -#ifdef ENABLE_ZEROMQ - if (target.dialect->version == NF_VERSION_NTOPNG) { +#ifdef ENABLE_NTOPNG + if (target.dialect->version == SOFTFLOWD_NF_VERSION_NTOPNG) { int rc = connect_ntopng (dest->hostname, dest->servname, &dest->zmq); if (rc) { - fprintf (stderr, "Could not create ZeroMQ socket for %s:%s: (%d) %s\n", - dest->hostname, dest->servname, rc, strerror(rc)); + fprintf (stderr, + "Could not create ZeroMQ socket for %s:%s: (%d) %s\n", + dest->hostname, dest->servname, rc, strerror (rc)); exit (1); } } else #endif - dest->sock = connsock (&dest->ss, dest->sslen, hoplimit, protocol); + dest->sock = connsock (&dest->ss, dest->sslen, hoplimit, protocol); } } diff --git a/softflowd.h b/softflowd.h index 87ac95c..96db98c 100644 --- a/softflowd.h +++ b/softflowd.h @@ -32,9 +32,9 @@ #include extern int use_thread; #endif /* ENABLE_PTHREAD */ -#ifdef ENABLE_ZEROMQ +#ifdef ENABLE_NTOPNG #include -#endif /* ENABLE_ZEROMQ */ +#endif /* ENABLE_NTOPNG */ /* User to setuid to and directory to chroot to when we drop privs */ #ifndef PRIVDROP_USER @@ -232,7 +232,7 @@ struct EXPIRY { } reason; }; -#ifdef ENABLE_ZEROMQ +#ifdef ENABLE_NTOPNG struct ZMQ { void *context; void *socket; @@ -242,13 +242,13 @@ struct ZMQ { struct DESTINATION { char *arg; int sock; -#ifdef ENABLE_ZEROMQ - struct ZMQ zmq; -#endif struct sockaddr_storage ss; socklen_t sslen; char hostname[NI_MAXHOST]; char servname[NI_MAXSERV]; +#ifdef ENABLE_NTOPNG + struct ZMQ zmq; +#endif }; /* Describes a location where we send NetFlow packets to */ @@ -280,7 +280,9 @@ int send_netflow_v1 (struct SENDPARAMETER sp); int send_netflow_v5 (struct SENDPARAMETER sp); /* Protypes for ntopng.c */ -int connect_ntopng(const char *host, const char *port, struct ZMQ *zmq); +#ifdef ENABLE_NTOPNG +int connect_ntopng (const char *host, const char *port, struct ZMQ *zmq); int send_ntopng (struct SENDPARAMETER sp); +#endif /* ENABLE_NTOPNG */ #endif /* _SOFTFLOWD_H */