#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "gg_sniff.h" #if defined(__OpenBSD__) #include "pcap-int.h" #endif #define GG_SNIFF_USER "_gg_sniff" #define GG_SNIFF_LOGFILE "/var/log/ggsniff.log" struct event_base *_ev_base = NULL; #if defined(__OpenBSD__) void __dead #else void #endif usage(void) { extern char *__progname; fprintf(stderr, "usage: %s [-hv] [-i interface] [ip [port]]", __progname); exit(1); } static void sig_handler(int sig, short why, void *data) { gg_log_info("got signal %d", sig); if (sig == SIGINT || sig == SIGTERM) if (_ev_base) event_base_loopexit(_ev_base, NULL); } int main(int argc, char **argv) { struct gg_client *ggcli = NULL; struct ggnet *net = NULL; struct event *ev_sigint, *ev_sigterm, *ev_sigchld, *ev_sighup; char ggserv_ip[30] = "127.0.0.1"; char *iface = NULL; int ggserv_port = GLOUGLOU_PROBE_DEFAULT_PORT; int pcap_init = 0; int loglevel = 0; int retval = -1; int op; if (geteuid() != 0) errx(1, "must be root"); while ((op = getopt(argc, argv, "hi:v")) != -1) { switch (op) { case 'h': usage(); /* NOTREACHED */ case 'i': iface = strndup(optarg, 30); break; case 'v': loglevel++; break; default: usage(); /* NOTREACHED */ } } switch (argc - optind) { case 2: ggserv_port = atoi(argv[3]); case 1: strncpy(ggserv_ip, argv[2], sizeof(ggserv_ip)); case 0: break; default: usage(); /* NOTREACHED */ } gg_log_init(GG_SNIFF_LOGFILE, loglevel); gg_log_warn("Starting gg_sniff"); _ev_base = event_base_new(); net = ggnet_new(GGNET_MANAGE_CONNID_TRUE); if (!net) goto quit; ggcli = gg_client_connect(_ev_base, ggserv_ip, ggserv_port, NULL, NULL, NULL); if (!ggcli) goto quit; pcap_init = ggsniff_pcap_init(_ev_base, ggcli, net, iface); if (!pcap_init) goto quit; ev_sigint = evsignal_new(_ev_base, SIGINT, sig_handler, NULL); ev_sigterm = evsignal_new(_ev_base, SIGTERM, sig_handler, NULL); ev_sigchld = evsignal_new(_ev_base, SIGCHLD, sig_handler, NULL); ev_sighup = evsignal_new(_ev_base, SIGHUP, sig_handler, NULL); evsignal_add(ev_sigint, NULL); evsignal_add(ev_sigterm, NULL); evsignal_add(ev_sigchld, NULL); evsignal_add(ev_sighup, NULL); signal(SIGPIPE, SIG_IGN); droppriv(GG_SNIFF_USER, 1, NULL); gg_log_info("entering event loop"); event_base_dispatch(_ev_base); retval = 0; quit: if (pcap_init) ggsniff_pcap_shutdown(); if (ggcli) gg_client_disconnect(ggcli); if (net) ggnet_free(net); gg_log_warn("exiting"); gg_log_shutdown(); exit(retval); }