diff dccd/dump-clients/dump-clients.c @ 0:c7f6b056b673

First import of vendor version
author Peter Gervai <grin@grin.hu>
date Tue, 10 Mar 2009 13:49:58 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dccd/dump-clients/dump-clients.c	Tue Mar 10 13:49:58 2009 +0100
@@ -0,0 +1,370 @@
+/* Distributed Checksum Clearinghouse
+ *
+ * dump list of dccd clients
+ *
+ * Copyright (c) 2008 by Rhyolite Software, LLC
+ *
+ * This agreement is not applicable to any entity which sells anti-spam
+ * solutions to others or provides an anti-spam solution as part of a
+ * security solution sold to other entities, or to a private network
+ * which employs the DCC or uses data provided by operation of the DCC
+ * but does not provide corresponding data to other users.
+ *
+ * Permission to use, copy, modify, and distribute this software without
+ * changes for any purpose with or without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice appear in all
+ * copies and any distributed versions or copies are either unchanged
+ * or not called anything similar to "DCC" or "Distributed Checksum
+ * Clearinghouse".
+ *
+ * Parties not eligible to receive a license under this agreement can
+ * obtain a commercial license to use DCC by contacting Rhyolite Software
+ * at sales@rhyolite.com.
+ *
+ * A commercial license would be for Distributed Checksum and Reputation
+ * Clearinghouse software.  That software includes additional features.  This
+ * free license for Distributed ChecksumClearinghouse Software does not in any
+ * way grant permision to use Distributed Checksum and Reputation Clearinghouse
+ * software
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC
+ * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Rhyolite Software DCC 1.3.103-1.20 $Revision$
+ */
+
+#include "dccd_defs.h"
+
+static const char *homedir;
+
+u_char grey_on;
+static u_char nonames, quiet, avg;
+
+
+static void NRATTRIB
+usage(void)
+{
+	fprintf(stderr, "usage: [-anqg] [-h homedir] [ifile1 ifile2 ...]\n");
+	exit(1);
+}
+
+
+
+static void PATTRIB(1,2)
+error_msg(const char *p, ...)
+{
+	va_list args;
+
+	fflush(stdout);
+
+	va_start(args, p);
+	vfprintf(stderr, p, args);
+	va_end(args);
+	putchar('\n');
+}
+
+
+
+static u_char
+clients_read(const char *fname, FILE *f, off_t pos, void *buf, int buf_len)
+{
+	int i;
+
+	if (fseeko(f, pos, 0)) {
+		error_msg("fseeko(%s,%d): %s", fname, (int)pos, ERROR_STR());
+		fclose(f);
+		return 0;
+	}
+
+	i = fread(buf, buf_len, 1, f);
+	if (i == 1)
+		return 1;
+
+	if (feof(f))
+		return 0;
+
+	error_msg("fread(%s): %s", fname, ERROR_STR());
+	fclose(f);
+	return 0;
+}
+
+
+
+static void
+dump_file(const char *fname0)
+{
+#	define PAT_REQUESTS	L_DWPAT(7)" "L_DWPAT(6)" "
+#	define PAT_REQUESTS_B   "%7s %6s "
+#	define PAT_AVGS		"%7d %6d %4.1f "
+#	define PAT_AVGS_B	"   %14s   "
+#	define PAT_DATE_ID	"%-14s %6d%c"
+#	define PAT_DATE_ID_B	"%-14s %6s "
+#	define PAT_VERS		"%1d "
+#	define PAT_VERS_B	"%1s "
+#	define PAT_DELAY	"%5.3f "
+#	define PAT_DELAY_B	"%5s "
+	DCC_PATH fname;
+	FILE *f;
+	struct stat sb;
+	CLIENTS_HEADER header;
+	RL_DATA data;
+	struct {
+	    u_int   hosts;
+	    u_int   requests;
+	    u_int   nops;
+	}  versions[DCC_PKT_VERSION_MAX+1];
+	time_t secs;
+	struct tm tm;
+	char date_buf[40];
+	char date_buf2[40];
+	int inflate;
+	double delay_us;
+	DCC_SOCKU su;
+	char name[DCC_MAXDOMAINLEN];
+	char sustr[DCC_SU2STR_SIZE];
+	off_t pos;
+	int total, active, i;
+
+	if (!fnm2abs(fname, fname0, 0)) {
+		error_msg("name \"%s\" too long", fname0);
+		exit(1);
+	}
+
+	printf("%s\n", fname);
+
+	f = fopen(fname, "r");
+	if (!f) {
+		error_msg("stat(%s): %s",
+			  fname, ERROR_STR());
+		exit(1);
+	}
+	if (0 > fstat(fileno(f), &sb)) {
+		error_msg("stat(%s): %s", fname, ERROR_STR());
+		exit(1);
+	}
+	pos = sb.st_size;
+	if (pos < ISZ(header)
+	    || ((pos - ISZ(header)) % ISZ(RL_DATA)) != 0) {
+		error_msg("%s has invalid size %d", fname, (int)pos);
+		exit(1);
+	}
+
+	if (!clients_read(fname, f, 0, &header, sizeof(header)))
+		exit(1);
+	if (strcmp(header.magic, CLIENTS_MAGIC(0))
+	    && strcmp(header.magic, CLIENTS_MAGIC(1))) {
+		error_msg("unrecognized magic in %s", fname);
+		exit(1);
+	}
+	if (header.hash_len > RL_MIN_MAX_MAX) {
+		error_msg("unrecognized hash_len=%d in %s",
+			  header.hash_len, fname);
+		exit(1);
+	}
+	strftime(date_buf, sizeof(date_buf), "%m/%d %X",
+		 gmtime_r(&header.now, &tm));
+	strftime(date_buf2, sizeof(date_buf2), "%m/%d %X",
+		 gmtime_r(&header.cleared, &tm));
+	printf("recorded %s  cleared %s  anon delay=", date_buf, date_buf2);
+	if (header.anon_delay_us == DCC_ANON_DELAY_FOREVER) {
+		printf("forever");
+	} else {
+		printf("%d", header.anon_delay_us/1000);
+		if (header.anon_delay_inflate != DCC_ANON_INFLATE_OFF)
+			printf(",%d", header.anon_delay_inflate);
+	}
+	putchar('\n');
+
+	if (avg)
+		printf(PAT_REQUESTS_B
+		       PAT_AVGS_B
+		       PAT_DATE_ID_B
+		       PAT_VERS_B
+		       PAT_DELAY_B "\n",
+		       "ops", "nops",
+		       "averages",
+		       "  last seen", "ID",
+		       "V",
+		       "delay");
+	else
+		printf(PAT_REQUESTS_B
+		       PAT_DATE_ID_B
+		       PAT_VERS_B
+		       PAT_DELAY_B "\n",
+		       "ops", "nops",
+		       "  last seen", "ID",
+		       "V",
+		       "delay");
+
+	total = 0;
+	active = 0;
+	memset(versions, 0, sizeof(versions));
+	while ((pos -= ISZ(RL_DATA)) >= ISZ(header)) {
+		if (!clients_read(fname, f, pos, &data, sizeof(data)))
+			break;
+
+		++total;
+		if (data.requests)
+			++active;
+
+		if (data.pkt_vers < DIM(versions))
+			i = data.pkt_vers;
+		else
+			i = 0;
+		++versions[i].hosts;
+		versions[i].requests += data.requests;
+		versions[i].nops += data.nops;
+
+		if (quiet)
+			continue;
+
+		if (data.requests != 0 || data.nops != 0) {
+			printf(PAT_REQUESTS,
+			       data.requests, data.nops);
+		} else {
+			printf(PAT_REQUESTS_B, "-", "-");
+		}
+
+		if (avg) {
+			if (data.requests_avg != 0 || data.nops_avg != 0) {
+				secs = header.now - data.requests_avg_start;
+				printf(PAT_AVGS,
+				       data.requests_avg, data.nops_avg,
+				       secs / (60*60*1.0));
+			} else {
+				printf(PAT_AVGS_B, "");
+			}
+		}
+
+		strftime(date_buf, sizeof(date_buf), "%m/%d %X",
+			 gmtime_r(&data.last_used, &tm));
+		if (data.clnt_id == DCC_ID_ANON)
+			printf(PAT_DATE_ID_B, date_buf, "");
+		else if (data.clnt_id == DCC_ID_SRVR_ROGUE)
+			printf(PAT_DATE_ID_B, date_buf, "server");
+		else
+			printf(PAT_DATE_ID, date_buf, data.clnt_id,
+			       (data.flags & RL_FG_ANON) ? '*' : ' ');
+
+		if (data.pkt_vers != 0)
+			printf(PAT_VERS, data.pkt_vers);
+		else if (data.clnt_id == DCC_ID_SRVR_ROGUE)
+			printf(PAT_VERS_B, "");
+		else
+			printf(PAT_VERS_B, "?");
+
+		if (data.flags & RL_FG_PASSWD) {
+			printf(PAT_DELAY_B, "pass");
+		} else if (data.flags & RL_FG_UKN_ID) {
+			printf(PAT_DELAY_B, "ID");
+		} else if (data.flags & RL_FG_BL_ADDR) {
+			printf(PAT_DELAY_B, "A BL");
+		} else if (data.flags & RL_FG_BL_ID) {
+			printf(PAT_DELAY_B, "ID BL");
+		} else if (data.flags & RL_FG_BL_BAD) {
+			printf(PAT_DELAY_B, "BAD");
+		} else if ((data.flags & RL_FG_ANON)
+			   && header.anon_delay_inflate != 0) {
+			inflate = 1 + (RL_REQUESTS_AVG(&data)
+				       / header.anon_delay_inflate);
+			if (inflate > (DCC_ANON_DELAY_MAX
+				       / header.anon_delay_us)) {
+				delay_us = DCC_ANON_DELAY_MAX;
+			} else {
+				delay_us = inflate*header.anon_delay_us;
+			}
+			printf(PAT_DELAY, delay_us/DCC_US);
+		} else {
+			printf(PAT_DELAY_B, "");
+		}
+
+		dcc_mk_su(&su, AF_INET6, &data.clnt_addr, 0);
+		if (nonames) {
+			printf("%s\n",
+			       dcc_su2str2(sustr, sizeof(sustr), &su));
+		} else {
+			printf("%-16s %s\n",
+			       dcc_su2str2(sustr, sizeof(sustr), &su),
+			       dcc_su2name(name, sizeof(name), &su));
+		}
+	}
+
+	fclose(f);
+
+	printf("%d of %d records active\n\n", active, total);
+
+	printf("version  hosts requests     nops\n");
+	for (i = 0; i < DIM(versions); ++i) {
+		if (versions[i].hosts == 0)
+			continue;
+		printf("%6d %6d %8d %8d\n",
+		       i, versions[i].hosts,
+		       versions[i].requests, versions[i].nops);
+	}
+
+	printf("\n       *  anonymous\n");
+	printf("    pass  bad password\n");
+	printf("      ID  unknown ID\n");
+	printf("    A BL  address blacklist\n");
+	printf("   ID BL  ID blacklist\n");
+	printf("     BAD  otherwise bad\n");
+}
+
+
+
+int NRATTRIB
+main(int argc, char **argv)
+{
+	int i;
+
+	avg = 0;
+	nonames = 0;
+	quiet = 0;
+
+	while ((i = getopt(argc, argv, "anqgh:")) != -1) {
+		switch (i) {
+		case 'a':
+			++avg;
+			break;
+
+		case 'n':
+			nonames = 1;
+			break;
+
+		case 'q':
+			quiet = 1;
+			break;
+
+		case 'g':
+			grey_on = 1;
+			break;
+
+		case 'h':
+			homedir = optarg;
+			break;
+
+		default:
+			usage();
+		}
+	}
+	argc -= optind;
+	argv += optind;
+
+	dcc_cdhome(0, homedir, 1);
+
+	if (argc == 0) {
+		dump_file(CLIENTS_NM());
+	} else {
+		for (i = 0; i < argc; ++i) {
+			dump_file(argv[i]);
+		}
+	}
+
+	exit(0);
+}