/* darkstat 3
- * copyright (c) 2001-2008 Emil Mikulic.
+ * copyright (c) 2001-2010 Emil Mikulic.
*
* darkstat.c: signals, cmdline parsing, program body.
*
#include "err.h"
#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netdb.h>
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <syslog.h>
#include <unistd.h>
#include <pcap.h>
const char *capfile = NULL;
static void cb_capfile(const char *arg) { capfile = arg; }
+int want_snaplen = -1;
+static void cb_snaplen(const char *arg) { want_snaplen = parsenum(arg, 0); }
+
int want_pppoe = 0;
static void cb_pppoe(const char *arg _unused_) { want_pppoe = 1; }
+static void cb_syslog(const char *arg _unused_) { want_syslog = 1; }
+
static void cb_verbose(const char *arg _unused_) { want_verbose = 1; }
int want_daemonize = 1;
int want_macs = 1;
static void cb_no_macs(const char *arg _unused_) { want_macs = 0; }
+int want_lastseen = 1;
+static void cb_no_lastseen(const char *arg _unused_) { want_lastseen = 0; }
+
unsigned short bindport = 667;
static void cb_port(const char *arg) { bindport = parsenum(arg, 65536); }
-in_addr_t bindaddr = INADDR_ANY;
+char * bindaddr = NULL;
static void cb_bindaddr(const char *arg)
{
- bindaddr = inet_addr(arg);
- if (bindaddr == (in_addr_t)INADDR_NONE)
+ struct addrinfo hints, *ai;
+
+ memset(&hints, '\0', sizeof(hints));
+ hints.ai_flags = AI_PASSIVE;
+#ifdef AI_ADDRCONFIG
+ hints.ai_flags |= AI_ADDRCONFIG;
+#endif
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ if (getaddrinfo(arg, NULL, &hints, &ai))
errx(1, "malformed address \"%s\"", arg);
+
+ freeaddrinfo(ai);
+ bindaddr = strdup(arg);
}
const char *filter = NULL;
static void cb_highest_port(const char *arg)
{ highest_port = parsenum(arg, 65535); }
+int wait_secs = -1;
+static void cb_wait_secs(const char *arg)
+{ wait_secs = parsenum(arg, 0); }
+
+int want_hexdump = 0;
+static void cb_hexdump(const char *arg _unused_) { want_hexdump = 1; }
+
/* --- */
struct cmdline_arg {
static struct cmdline_arg cmdline_args[] = {
{"-i", "interface", cb_interface, 0},
{"-r", "file", cb_capfile, 0},
+ {"--snaplen", "bytes", cb_snaplen, 0},
{"--pppoe", NULL, cb_pppoe, 0},
+ {"--syslog", NULL, cb_syslog, 0},
{"--verbose", NULL, cb_verbose, 0},
{"--no-daemon", NULL, cb_no_daemon, 0},
{"--no-promisc", NULL, cb_no_promisc, 0},
{"--no-dns", NULL, cb_no_dns, 0},
{"--no-macs", NULL, cb_no_macs, 0},
+ {"--no-lastseen", NULL, cb_no_lastseen, 0},
{"-p", "port", cb_port, 0},
{"-b", "bindaddr", cb_bindaddr, 0},
{"-f", "filter", cb_filter, 0},
{"--ports-max", "count", cb_ports_max, 0},
{"--ports-keep", "count", cb_ports_keep, 0},
{"--highest-port", "port", cb_highest_port, 0},
+ {"--wait", "secs", cb_wait_secs, 0},
+ {"--hexdump", NULL, cb_hexdump, 0},
{NULL, NULL, NULL, 0}
};
printf(" ]\n");
}
printf("\n"
-"Please refer to the darkstat(1) manual page for further\n"
+"Please refer to the darkstat(8) manual page for further\n"
"documentation and usage examples.\n");
}
for (arg = cmdline_args; arg->name != NULL; arg++)
if (strcmp(argv[0], arg->name) == 0) {
if ((arg->arg_name != NULL) && (argc == 1)) {
- printf("\nerror: argument \"%s\" requires parameter \"%s\"\n",
+ fprintf(stderr,
+ "error: argument \"%s\" requires parameter \"%s\"\n",
arg->name, arg->arg_name);
usage();
exit(EXIT_FAILURE);
}
if (arg->num_seen > 0) {
- printf("\nerror: already specified argument \"%s\"\n",
+ fprintf(stderr,
+ "error: already specified argument \"%s\"\n",
arg->name);
usage();
exit(EXIT_FAILURE);
return;
}
- printf("\nerror: illegal argument: \"%s\"\n", argv[0]);
+ fprintf(stderr, "error: illegal argument: \"%s\"\n", argv[0]);
usage();
exit(EXIT_FAILURE);
}
parse_sub_cmdline(argc, argv);
+ /* start syslogging as early as possible */
+ if (want_syslog) openlog("darkstat", LOG_NDELAY | LOG_PID, LOG_DAEMON);
+
/* some default values */
if (chroot_dir == NULL) chroot_dir = CHROOT_DIR;
if (privdrop_user == NULL) privdrop_user = PRIVDROP_USER;
if ((interface != NULL) && (capfile != NULL))
errx(1, "can't specify both interface (-i) and capture file (-r)");
- if ((hosts_max != 0) && (hosts_keep >= hosts_max))
- errx(1, "must keep fewer hosts than --hosts-max (%u)", hosts_max);
+ if ((hosts_max != 0) && (hosts_keep >= hosts_max)) {
+ hosts_keep = hosts_max / 2;
+ warnx("reducing --hosts-keep to %u, to be under --hosts-max (%u)",
+ hosts_keep, hosts_max);
+ }
verbosef("max %u hosts, cutting down to %u when exceeded",
hosts_max, hosts_keep);
- if ((ports_max != 0) && (ports_keep >= ports_max))
- errx(1, "must keep fewer ports than --ports-max (%u)", ports_max);
+ if ((ports_max != 0) && (ports_keep >= ports_max)) {
+ ports_keep = ports_max / 2;
+ warnx("reducing --ports-keep to %u, to be under --ports-max (%u)",
+ ports_keep, ports_max);
+ }
verbosef("max %u ports per host, cutting down to %u when exceeded",
ports_max, ports_keep);
+
+ if (want_hexdump && !want_verbose) {
+ want_verbose = 1;
+ verbosef("--hexdump implies --verbose");
+ }
+
+ if (want_hexdump && want_daemonize) {
+ want_daemonize = 0;
+ verbosef("--hexdump implies --no-daemon");
+ }
}
static void