Mercurial > notdcc
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); +}