 |
Flowgrind
Advanced TCP traffic generator
|
Go to the documentation of this file.
36 #define daemon fake_daemon_function
47 #include <sys/utsname.h>
49 #include <netinet/in.h>
50 #include <netinet/tcp.h>
56 #include <xmlrpc-c/base.h>
57 #include <xmlrpc-c/server.h>
58 #include <xmlrpc-c/server_abyss.h>
59 #include <xmlrpc-c/util.h>
82 extern int daemon(
int,
int);
86 #define PARSE_ERR(err_msg, ...) do { \
87 errx(err_msg, ##__VA_ARGS__); \
88 usage(EXIT_FAILURE); \
107 static void usage(
short status) __attribute__((noreturn));
121 if (status != EXIT_SUCCESS) {
122 fprintf(stderr,
"Try '%s -h' for more information\n",
progname);
127 "Usage: %1$s [OPTION]...\n"
128 "Advanced TCP traffic generator for Linux, FreeBSD, and Mac OS X.\n\n"
130 "Mandatory arguments to long options are mandatory for short options too.\n"
131 " -b ADDR XML-RPC server bind address\n"
132 " -c # bound daemon to specific CPU. First CPU is 0\n"
134 " -d, --debug increase debugging verbosity. Add option multiple times to\n"
135 " increase the verbosity (no daemon, log to stderr)\n"
137 " -d don't fork into background, log to stderr\n"
139 " -h, --help display this help and exit\n"
140 " -p # XML-RPC server port\n"
142 " -w DIR target directory for dump files. The daemon must be run as root\n"
144 " -v, --version print version information and exit\n",
160 while (waitpid(-1, &status, WNOHANG) > 0)
161 logging(LOG_NOTICE,
"child returned (status = %d)",
165 logging(LOG_NOTICE,
"caught SIGHUP. don't know what to do.");
168 logging(LOG_NOTICE,
"caught SIGALRM, don't know what to do.");
174 logging(LOG_NOTICE,
"caught SIGINT/SIGTERM, tear down daemon");
178 logging(LOG_ALERT,
"caught signal %d, but don't remember "
179 "intercepting it, aborting...", sig);
189 crit(
"could not create pipe");
191 if ((flags = fcntl(
daemon_pipe[0], F_GETFL, 0)) == -1)
193 fcntl(
daemon_pipe[0], F_SETFL, flags | O_NONBLOCK);
195 pthread_mutex_init(&
mutex, NULL);
199 critc(rc,
"could not start thread");
204 pthread_t thread = pthread_self();
208 logging(LOG_WARNING,
"failed to bind %s (PID %d) to CPU core %i",
211 DEBUG_MSG(LOG_INFO,
"bind %s (PID %d) to CPU core %i",
220 struct stat dirstats;
222 if (stat(
dump_dir, &dirstats) == -1) {
228 if (!S_ISDIR(dirstats.st_mode)) {
229 DEBUG_MSG(LOG_ERR,
"provided path %s is not a directory",
234 if (access(
dump_dir, W_OK | X_OK) == -1) {
235 DEBUG_MSG(LOG_ERR,
"insufficent permissions to access %s: %s",
260 {
'd',
"debug",
ap_no, 0, 0},
262 {
'd', 0,
ap_no, 0, 0},
264 {
'h',
"help",
ap_no, 0, 0},
267 {
'v',
"version",
ap_no, 0, 0},
274 if (!
ap_init(&
parser, argc, (
const char*
const*) argv, options, 0))
275 critx(
"could not allocate memory for option parser");
290 PARSE_ERR(
"failed to parse bind address");
293 if (sscanf(arg,
"%u", &
core) != 1)
305 if (sscanf(arg,
"%u", &
port) != 1)
306 PARSE_ERR(
"failed to parse port number");
314 fprintf(stdout,
"%s %s\%s\n%s\n\n%s\n",
progname,
328 PARSE_ERR(
"the dump directory %s for tcpdumps does "
329 "either not exist or you have insufficient "
330 "permissions to write to it",
dump_dir);
332 warnx(
"tcpdumping will not be available since you "
333 "don't have sufficient permissions to write to "
342 errx(
"CPU binding failed. Given CPU ID is negative");
347 errx(
"CPU binding failed. Given CPU ID is higher then "
348 "available CPU cores");
365 int main(
int argc,
char *argv[])
374 sigemptyset (&sa.sa_mask);
375 if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
376 crit(
"could not ignore SIGPIPE");
377 if (sigaction (SIGHUP, &sa, NULL))
378 critx(
"could not set handler for SIGUP");
379 if (sigaction (SIGALRM, &sa, NULL))
380 critx(
"could not set handler for SIGALRM");
381 if (sigaction (SIGCHLD, &sa, NULL))
382 critx(
"could not set handler for SIGCHLD");
383 if (sigaction(SIGINT, &sa, NULL))
384 critx(
"could not set handler for SIGINT");
385 if (sigaction(SIGTERM, &sa, NULL))
386 critx(
"could not set handler for SIGTERM");
411 crit(
"daemon() failed");
412 logging(LOG_NOTICE,
"flowgrindd daemonized");
422 critx(
"control should never reach end of main()");
#define DEBUG_MSG(LVL, MSG,...)
Print debug message to standard error.
Packet capture support for the Flowgrind daemon.
static void sanity_check(void)
int fg_pcap_init(void)
Initialize flowgrind's pcap library.
#define daemon
Temporarily renaming daemon() so compiler does not see the warning on OS X.
Functions to manipulate strings used by Flowgrind.
CPU affinity routines used by Flowgrind.
void * daemon_main(void *ptr __attribute__((unused)))
int ap_code(const struct arg_parser *const ap, const int i)
Returns the code of a parsed option with given index.
static void tear_down_daemon(void)
Gracefully tear down daemon.
const char * ap_argument(const struct arg_parser *const ap, const int i)
Returns the argument of a parsed option.
const char * ap_error(const struct arg_parser *const ap)
Get the string containing errors encountered during parsing.
void init_rpc_server(struct fg_rpc_server *server, char *rpc_bind_addr, unsigned port)
Initializes the xmlrpc server.
#define crit(...)
To report an critical error w/ the corresponding system error message.
#define FLOWGRIND_COPYRIGHT
Flowgrind's copyright year.
@ NCORE_CURRENT
Processors available to the current process.
Internal state of the argument parser.
@ LOGGING_STDERR
Log to stderr.
void logging(int priority, const char *fmt,...)
Error-reporting routines used by Flowgrind.
@ ap_no
Option without argument (flag).
#define warnx(...)
To report a warning w/ a system error message.
static void sighandler(int sig)
Signal handler to catching signals.
Information about the daemons XMLrpc server.
static char * rpc_bind_addr
@ ap_yes
Argument required.
void run_rpc_server(struct fg_rpc_server *server)
Enters the xmlrpc server mainloop.
int get_ncores(enum ncore_query query)
Return either the total number of configured or available cores.
int code
Short option letter or code (code != 0).
bool ap_is_used(const struct arg_parser *const ap, int code)
Returns true if the option specified by code was given at least once.
void increase_debuglevel()
Decrease debug level.
int main(int argc, char *argv[])
#define errx(...)
To report an error w/o a system error message.
void ap_free(struct arg_parser *const ap)
Free internal state of arg-parser.
#define critc(code,...)
To report an critical error w/ the system error message 'code'.
#define FLOWGRIND_COPYING
Standard GPL3 no warranty message.
#define critx(...)
To report an critical error w/o a system error message.
RPCServer related functions and structs used by the Flowgrind daemon.
#define FLOWGRIND_AUTHORS
Flowgrind's authors in a printable string.
static void parse_cmdline(int argc, char *argv[])
Parse command line options to initialize global options.
int ap_arguments(const struct arg_parser *const ap)
Number of arguments parsed (may be different from argc).
Command line argument parser.
static void usage(short status) __attribute__((noreturn))
Print usage or error message and exit.
static int core
CPU core to which flowgrindd should bind to.
Defines a valid command line option.
Common definitions used by the Flowgrind daemon, controller, and libs.
Timing related routines used by Flowgrind.
#define FLOWGRIND_VERSION
Flowgrind version number.
void bind_daemon_to_core(void)
static struct arg_parser parser
Command line option parser.
Data structures used by the Flowgrind daemon and controller.
void set_progname(const char *argv0)
Set global variable 'progname', based on argv[0].
void close_logging(void)
Close logging stream.
int asprintf_append(char **strp, const char *fmt,...)
#define PARSE_ERR(err_msg,...)
Print error message, usage string and exit.
int pthread_setaffinity(pthread_t thread, unsigned core)
Set CPU affinity of the thread thread to the core core.
const char * progname
String containing name the program is called with.
#define DEFAULT_LISTEN_PORT
Daemon's default listen port.
void create_daemon_thread()
bool ap_init(struct arg_parser *const ap, const int argc, const char *const argv[], const struct ap_Option options[], const char in_order)
Initialize the arg-parser given command line and user-defined options.
Routines for statistics and advanced traffic generation.
Debugging routines for Flowgrind controller and daemon.
int fg_list_init(struct linked_list *const list)
Initializes the list by setting its head and tail to NULL and its size to 0.
Routines used by the Flowgrind daemon.
void init_logging(enum log_streams stream)
Open logging stream.
@ LOGGING_SYSLOG
Log to syslog.