Skip to content

Commit

Permalink
Merge branch 'udp_listener' into execvpe
Browse files Browse the repository at this point in the history
  • Loading branch information
mrash committed Oct 14, 2014
2 parents 00b229b + 2b04639 commit 0af8faa
Show file tree
Hide file tree
Showing 20 changed files with 539 additions and 43 deletions.
19 changes: 18 additions & 1 deletion configure.ac
Expand Up @@ -166,6 +166,16 @@ if test "x$want_fuzzing_interfaces" = "xyes"; then
AC_DEFINE([FUZZING_INTERFACES], [1], [Define for fuzzing interfaces support])
fi

dnl Decide whether or not to enable UDP server mode (no libpcap dependency)
dnl
want_udp_server=no
AC_ARG_ENABLE([udp-server],
[AS_HELP_STRING([--enable-udp-server],
[Enable UDP server mode for no libpcap dependency @<:@default is to disable@:>@])],
[want_udp_server=$enableval],
[])
AM_CONDITIONAL([UDP_SERVER], [test "$want_udp_server" = yes])

dnl Decide whether or not to enable all warnings with -Wall
dnl
use_wall=yes
Expand Down Expand Up @@ -443,12 +453,15 @@ AS_IF([test "x$WGET_EXE" != x],
dnl Check for libpcap, gdbm (or ndbm) if we are building the server component
dnl
AS_IF([test "$want_server" = yes], [
AS_IF([test "$want_udp_server" = no], [
# Looking for libpcap
#
AC_CHECK_LIB([pcap],[pcap_open_live],
[ AC_DEFINE([HAVE_LIBPCAP], [1], [Define if you have libpcap]) ],
[ AC_DEFINE([USE_LIBPCAP], [1], [Define if you have libpcap]) ],
[ AC_MSG_ERROR([fwknopd needs libpcap])]
)
])
AS_IF([test "$want_digest_cache" = yes], [
use_ndbm=no
Expand Down Expand Up @@ -687,6 +700,10 @@ if [test "$want_server" = "yes" ]; then
firewall type: $FIREWALL_TYPE
firewall program path: $FIREWALL_EXE
"
if [test "$want_udp_server" = "yes" ]; then
echo " UDP server mode enabled, no libpcap dependency
"
fi
if [test "$want_digest_cache" = "no" ]; then
echo " *WARNING*
Expand Down
29 changes: 21 additions & 8 deletions doc/fwknopd.man.asciidoc
Expand Up @@ -308,14 +308,14 @@ See the '@sysconfdir@/fwknop/fwknopd.conf'' file for the full list and correspon

*ENABLE_TCP_SERVER* '<Y/N>'::
Enable the fwknopd TCP server. This is a "dummy" TCP server that will
accept TCP connection requests on the specified TCPSERV_PORT.
If set to "Y", fwknopd will fork off a child process to listen for, and
accept incoming TCP request. This server only accepts the
request. It does not otherwise communicate. This is only to allow the
incoming SPA over TCP packet which is detected via PCAP. The connection
is closed after 1 second regardless.
Note that fwknopd still only gets its data via pcap, so the filter
defined by PCAP_FILTER needs to be updated to include this TCP port.
accept TCP connection requests on the specified TCPSERV_PORT.
If set to "Y", fwknopd will fork off a child process to listen for, and
accept incoming TCP request. This server only accepts the
request. It does not otherwise communicate. This is only to allow the
incoming SPA over TCP packet which is detected via PCAP. The connection
is closed after 1 second regardless.
Note that fwknopd still only gets its data via pcap, so the filter
defined by PCAP_FILTER needs to be updated to include this TCP port.

*PCAP_DISPATCH_COUNT* '<count>'::
Sets the number of packets that are processed when the *pcap_dispatch()*
Expand Down Expand Up @@ -346,6 +346,19 @@ See the '@sysconfdir@/fwknop/fwknopd.conf'' file for the full list and correspon
Set the port number that the ``dummy'' TCP server listens on. This server
is only spawned when ``ENABLE_TCP_SERVER'' is set to ``Y''.
*ENABLE_UDP_SERVER* '<Y/N>'::
Enable the *fwknopd* UDP server. This enables *fwknopd* to acquire SPA
packets via a UDP socket directly without having to use libpcap. When this
mode is enabled, *fwknop* should be compiled with *--enable-udp-server*
(passed to the *configure* script) so that libpcap can be removed as a
dependency. As one would expect, when the UDP server is used, no incoming
packets are ever acknowledged by *fwknopd* and therefore collecting SPA
packets in this mode is a good alternative to sniffing the wire directly.

*UDPSERV_PORT* '<port>'::
Set the port number that the UDP server listens on. This server
is only spawned when ``ENABLE_UDP_SERVER'' is set to ``Y''.
*SYSLOG_IDENTITY* '<identity>'::
Override syslog identity on message logged by *fwknopd*. The defaults
are usually ok.
Expand Down
13 changes: 9 additions & 4 deletions server/Makefile.am
Expand Up @@ -6,16 +6,21 @@ fwknopd_SOURCES = fwknopd.c fwknopd.h config_init.c config_init.h \
process_packet.h log_msg.c log_msg.h utils.c utils.h \
sig_handler.c sig_handler.h replay_cache.c replay_cache.h \
access.c access.h fwknopd_errors.c fwknopd_errors.h \
tcp_server.c tcp_server.h extcmd.c extcmd.h \
tcp_server.c tcp_server.h udp_server.c udp_server.h \
fw_util.c fw_util.h fw_util_ipf.c fw_util_ipf.h \
fw_util_firewalld.c fw_util_firewalld.h \
fw_util_iptables.c fw_util_iptables.h \
fw_util_ipfw.c fw_util_ipfw.h \
fw_util_pf.c fw_util_pf.h cmd_opts.h
fw_util_pf.c fw_util_pf.h cmd_opts.h \
extcmd.c extcmd.h

fwknopd_LDADD = $(top_builddir)/lib/libfko.la $(top_builddir)/common/libfko_util.a -lpcap
fwknopd_LDADD = $(top_builddir)/lib/libfko.la $(top_builddir)/common/libfko_util.a

if ! CONFIG_FILE_CACHE
if !UDP_SERVER
fwknopd_LDADD += -lpcap
endif

if !CONFIG_FILE_CACHE
if USE_NDBM
fwknopd_LDADD += -lndbm
else
Expand Down
4 changes: 4 additions & 0 deletions server/cmd_opts.h
Expand Up @@ -57,6 +57,9 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
"ENABLE_SPA_OVER_HTTP",
"ENABLE_TCP_SERVER",
"TCPSERV_PORT",
"ENABLE_UDP_SERVER",
"UDPSERV_PORT",
"UDPSERV_SELECT_TIMEOUT",
"LOCALE",
"SYSLOG_IDENTITY",
"SYSLOG_FACILITY",
Expand Down Expand Up @@ -186,6 +189,7 @@ static struct option cmd_opts[] =
{"restart", 0, NULL, 'R'},
{"status", 0, NULL, 'S'},
{"test", 0, NULL, 't'},
{"udp-server", 0, NULL, 'U'},
{"verbose", 0, NULL, 'v'},
{"version", 0, NULL, 'V'},
{0, 0, 0, 0}
Expand Down
31 changes: 31 additions & 0 deletions server/config_init.c
Expand Up @@ -151,6 +151,10 @@ validate_int_var_ranges(fko_srv_options_t *opts)
1, RCHK_MAX_SNIFF_BYTES);
range_check(opts, "TCPSERV_PORT", opts->config[CONF_TCPSERV_PORT],
1, RCHK_MAX_TCPSERV_PORT);
range_check(opts, "UDPSERV_PORT", opts->config[CONF_UDPSERV_PORT],
1, RCHK_MAX_UDPSERV_PORT);
range_check(opts, "UDPSERV_PORT", opts->config[CONF_UDPSERV_SELECT_TIMEOUT],
1, RCHK_MAX_UDPSERV_SELECT_TIMEOUT);

#if FIREWALL_IPFW
range_check(opts, "IPFW_START_RULE_NUM", opts->config[CONF_IPFW_START_RULE_NUM],
Expand Down Expand Up @@ -808,6 +812,30 @@ validate_options(fko_srv_options_t *opts)
if(opts->config[CONF_TCPSERV_PORT] == NULL)
set_config_entry(opts, CONF_TCPSERV_PORT, DEF_TCPSERV_PORT);

/* Enable UDP server.
*/
if(opts->config[CONF_ENABLE_UDP_SERVER] == NULL)
{
if((strncasecmp(DEF_ENABLE_UDP_SERVER, "Y", 1) == 0) &&
!opts->enable_udp_server)
{
log_msg(LOG_ERR, "pcap capture not enabled, forcing UDP server mode");
opts->enable_udp_server = 1;
}
set_config_entry(opts, CONF_ENABLE_UDP_SERVER, DEF_ENABLE_UDP_SERVER);
}

/* UDP Server port.
*/
if(opts->config[CONF_UDPSERV_PORT] == NULL)
set_config_entry(opts, CONF_UDPSERV_PORT, DEF_UDPSERV_PORT);

/* UDP server select() timeout in microseconds
*/
if(opts->config[CONF_UDPSERV_SELECT_TIMEOUT] == NULL)
set_config_entry(opts, CONF_UDPSERV_SELECT_TIMEOUT,
DEF_UDPSERV_SELECT_TIMEOUT);

/* Syslog identity.
*/
if(opts->config[CONF_SYSLOG_IDENTITY] == NULL)
Expand Down Expand Up @@ -1113,6 +1141,9 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
case 't':
opts->test = 1;
break;
case 'U':
opts->enable_udp_server = 1;
break;
/* Verbosity level */
case 'v':
opts->verbose++;
Expand Down
42 changes: 33 additions & 9 deletions server/fwknopd.c
Expand Up @@ -31,14 +31,17 @@
#include "fwknopd.h"
#include "access.h"
#include "config_init.h"
#include "process_packet.h"
#include "pcap_capture.h"
#include "log_msg.h"
#include "utils.h"
#include "fw_util.h"
#include "sig_handler.h"
#include "replay_cache.h"
#include "tcp_server.h"
#include "udp_server.h"

#if USE_LIBPCAP
#include "pcap_capture.h"
#endif

/* Prototypes
*/
Expand Down Expand Up @@ -178,7 +181,25 @@ main(int argc, char **argv)
if(!opts.test && (fw_initialize(&opts) != 1))
clean_exit(&opts, FW_CLEANUP, EXIT_FAILURE);

/* If the TCP server option was set, fire it up here.
/* If we are to acquire SPA data via a UDP socket, start it up here.
*/
if(opts.enable_udp_server ||
strncasecmp(opts.config[CONF_ENABLE_UDP_SERVER], "Y", 1) == 0)
{
if(run_udp_server(&opts) < 0)
{
log_msg(LOG_ERR, "Fatal run_udp_server() error");
clean_exit(&opts, FW_CLEANUP, EXIT_FAILURE);
}
else
{
break;
}
}

/* If the TCP server option was set, fire it up here. Note that in
* this mode, fwknopd still acquires SPA packets via libpcap. If you
* want to use UDP only without the libpcap dependency, see the FIXME...
*/
if(strncasecmp(opts.config[CONF_ENABLE_TCP_SERVER], "Y", 1) == 0)
{
Expand All @@ -189,9 +210,12 @@ main(int argc, char **argv)
}
}

#if USE_LIBPCAP
/* Intiate pcap capture mode...
*/
pcap_capture(&opts);
if(strncasecmp(opts.config[CONF_ENABLE_UDP_SERVER], "N", 1) == 0)
pcap_capture(&opts);
#endif

/* Deal with any signals that we've received and break out
* of the loop for any terminating signals
Expand Down Expand Up @@ -379,7 +403,7 @@ static int handle_signals(fko_srv_options_t *opts)

if(got_sighup)
{
log_msg(LOG_WARNING, "Got SIGHUP. Re-reading configs.");
log_msg(LOG_WARNING, "Got SIGHUP. Re-reading configs.");
free_configs(opts);
kill(opts->tcp_server_pid, SIGTERM);
usleep(1000000);
Expand All @@ -388,12 +412,12 @@ static int handle_signals(fko_srv_options_t *opts)
}
else if(got_sigint)
{
log_msg(LOG_WARNING, "Got SIGINT. Exiting...");
log_msg(LOG_WARNING, "Got SIGINT. Exiting...");
got_sigint = 0;
}
else if(got_sigterm)
{
log_msg(LOG_WARNING, "Got SIGTERM. Exiting...");
log_msg(LOG_WARNING, "Got SIGTERM. Exiting...");
got_sigterm = 0;
}
else
Expand All @@ -406,13 +430,13 @@ static int handle_signals(fko_srv_options_t *opts)
&& opts->packet_ctr >= opts->packet_ctr_limit)
{
log_msg(LOG_INFO,
"Packet count limit (%d) reached. Exiting...",
"Packet count limit (%d) reached. Exiting...",
opts->packet_ctr_limit);
}
else /* got_signal was not set (should be if we are here) */
{
log_msg(LOG_WARNING,
"Capture ended without signal. Exiting...");
"Capture ended without signal. Exiting...");
}
return rv;
}
Expand Down
15 changes: 14 additions & 1 deletion server/fwknopd_common.h
Expand Up @@ -41,7 +41,7 @@
#include <sys/stat.h>
#endif

#if HAVE_LIBPCAP
#if USE_LIBPCAP
#include <pcap.h>
#endif

Expand Down Expand Up @@ -101,6 +101,13 @@
#define DEF_ENABLE_SPA_OVER_HTTP "N"
#define DEF_ENABLE_TCP_SERVER "N"
#define DEF_TCPSERV_PORT "62201"
#if USE_LIBPCAP
#define DEF_ENABLE_UDP_SERVER "N"
#else
#define DEF_ENABLE_UDP_SERVER "Y"
#endif
#define DEF_UDPSERV_PORT "62201"
#define DEF_UDPSERV_SELECT_TIMEOUT "500000" /* half a second (in microseconds) */
#define DEF_SYSLOG_IDENTITY MY_NAME
#define DEF_SYSLOG_FACILITY "LOG_DAEMON"

Expand All @@ -112,6 +119,8 @@
#define RCHK_MAX_SPA_PACKET_AGE 100000 /* seconds, can disable */
#define RCHK_MAX_SNIFF_BYTES (2 << 14)
#define RCHK_MAX_TCPSERV_PORT ((2 << 16) - 1)
#define RCHK_MAX_UDPSERV_PORT ((2 << 16) - 1)
#define RCHK_MAX_UDPSERV_SELECT_TIMEOUT (2 << 22)
#define RCHK_MAX_PCAP_DISPATCH_COUNT (2 << 22)
#define RCHK_MAX_FW_TIMEOUT (2 << 22)

Expand Down Expand Up @@ -225,6 +234,9 @@ enum {
CONF_ENABLE_SPA_OVER_HTTP,
CONF_ENABLE_TCP_SERVER,
CONF_TCPSERV_PORT,
CONF_ENABLE_UDP_SERVER,
CONF_UDPSERV_PORT,
CONF_UDPSERV_SELECT_TIMEOUT,
CONF_LOCALE,
CONF_SYSLOG_IDENTITY,
CONF_SYSLOG_FACILITY,
Expand Down Expand Up @@ -567,6 +579,7 @@ typedef struct fko_srv_options
unsigned char test; /* Test mode flag */
unsigned char verbose; /* Verbose mode flag */
unsigned char exit_after_parse_config; /* Parse config and exit */
unsigned char enable_udp_server; /* Enable UDP server mode */

unsigned char firewd_disable_check_support; /* Don't use firewall-cmd ... -C */
unsigned char ipt_disable_check_support; /* Don't use iptables -C */
Expand Down
27 changes: 9 additions & 18 deletions server/pcap_capture.c
Expand Up @@ -28,12 +28,13 @@
*
*****************************************************************************
*/


#include <pcap.h>

#include "fwknopd_common.h"
#include "pcap_capture.h"
#include "process_packet.h"
#include "sig_handler.h"
#include "fw_util.h"
#include "log_msg.h"
#include "fwknopd_errors.h"
Expand All @@ -44,6 +45,8 @@
#include <sys/wait.h>
#endif

#if USE_LIBPCAP

/* The pcap capture routine.
*/
int
Expand Down Expand Up @@ -247,24 +250,10 @@ pcap_capture(fko_srv_options_t *opts)
got_sigchld = 0;
}

/* Any signal except USR1, USR2, and SIGCHLD mean break the loop.
*/
if(got_signal != 0)
if(sig_do_stop())
{
if(got_sigint || got_sigterm || got_sighup)
{
pcap_breakloop(pcap);
pending_break = 1;
}
else if(got_sigusr1 || got_sigusr2)
{
/* Not doing anything with these yet.
*/
got_sigusr1 = got_sigusr2 = 0;
got_signal = 0;
}
else
got_signal = 0;
pcap_breakloop(pcap);
pending_break = 1;
}

res = pcap_dispatch(pcap, pcap_dispatch_count,
Expand Down Expand Up @@ -347,4 +336,6 @@ pcap_capture(fko_srv_options_t *opts)
return(0);
}

#endif /* USE_LIBPCAP */

/***EOF***/

0 comments on commit 0af8faa

Please sign in to comment.