diff --git a/sdt/sdt.c b/sdt/sdt.c index 940865c..6b66fe2 100644 --- a/sdt/sdt.c +++ b/sdt/sdt.c @@ -40,6 +40,7 @@ main(int argc, char *argv[]) pid_t pid = 0; int nd = 0; int ch = 0; + int di = 0; IS_NULL(ss = (SDT_STATE *)calloc(1, sizeof(SDT_STATE))); @@ -57,7 +58,9 @@ main(int argc, char *argv[]) ss->type = ns_t_txt; ss->verbose_lines = 100; - while ( (ch = getopt(argc, argv, "A:B:b:dF:hM:m:R:r:S:s:T:t:vx:")) != -1) { + ss->dname_next = &sdt_dns_dn_roundrobin; + + while ( (ch = getopt(argc, argv, "A:B:b:dF:hM:m:n:R:r:S:s:T:t:vx:")) != -1) { switch (ch) { case 'A': /* alarm, delay buf */ ss->delay = (u_int32_t)atoi(optarg); @@ -80,6 +83,14 @@ main(int argc, char *argv[]) case 'm': ss->sleep = (u_int32_t)atoi(optarg); break; + case 'n': /* strategy for shuffling domain name list */ + if (strcasecmp(optarg, "roundrobin") == 0) + ss->dname_next = &sdt_dns_dn_roundrobin; + else if (strcasecmp(optarg, "random") == 0) + ss->dname_next = &sdt_dns_dn_random; + else + usage(ss); + break; case 'R': /* Retry lookup */ sdt_dns_setopt(SDT_RES_RETRY, (u_int32_t)atoi(optarg)); break; @@ -129,10 +140,16 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if ( (argc != 1) || (strlen(argv[0]) > NS_MAXCDNAME - 1)) + if ( (argc == 0) || (argc >= MAXDNAMELIST)) usage(ss); - IS_NULL(ss->dname = strdup(argv[0])); + ss->dname_max = argc; + IS_NULL(ss->dname = (char **)calloc(argc, 1)); + for ( di = 0; di < argc; di++) { + if (strlen(argv[di]) > NS_MAXCDNAME - 1) + usage(ss); + IS_NULL(ss->dname[di] = strdup(argv[di])); + } IS_ERR(nd = open("/dev/null", O_RDWR, 0)); @@ -390,8 +407,9 @@ usage(SDT_STATE *ss) (void)fprintf(stderr, "-F \tFast start, number of small packets to pass w/out buffering (0 to disable) [default: %d]\n", ss->faststart); (void)fprintf(stderr, "-M\tMaximum number of polling query failures [default: %d]\n", ss->maxpollfail); (void)fprintf(stderr, "-m\tMinimum time to sleep between nameserver queries [default: %d us]\n", ss->sleep); + (void)fprintf(stderr, "-n \tStrategy for shuffling domain names [default: roundrobin]\n"); (void)fprintf(stderr, "-R \tNumber of retries for lookup\n"); - (void)fprintf(stderr, "-r\tNameserver (or keyword: random, opendns, verizon, speakeasy)\n"); + (void)fprintf(stderr, "-r\tNameserver (or keyword: random, opendns, verizon, speakeasy, google)\n"); (void)fprintf(stderr, "-S [rotate|blast]\tResolver strategy\n"); (void)fprintf(stderr, "-T \tUse TCP [0 = new connection for each request, 1 = pipeline requests]\n"); (void)fprintf(stderr, "-t \tTXT, CNAME [Default = TXT]\n"); diff --git a/sdt/sdt.h b/sdt/sdt.h index 024be38..a61a2a4 100644 --- a/sdt/sdt.h +++ b/sdt/sdt.h @@ -98,6 +98,8 @@ #define MAXBACKOFF 3000 /* 3000 * 20000 = 60,000,000 (1/minute) */ #define MAXPOLLFAIL 10 /* Number of TXT record failures before giving up */ +#define MAXDNAMELIST 256 /* arbitrary cutoff for number of domains */ + typedef union _SDT_ID { struct { @@ -109,7 +111,9 @@ typedef union _SDT_ID { } SDT_ID; typedef struct _SDT_STATE { - char *dname; + char **dname; + int dname_max; + int dname_iterator; SDT_ID sess; size_t sum; size_t sum_up; @@ -125,6 +129,8 @@ typedef struct _SDT_STATE { pid_t child; int verbose; int verbose_lines; + + char *(*dname_next)(void *state); } SDT_STATE; /* Resolver options */ @@ -151,10 +157,13 @@ int sdt_dns_parsens(SDT_STATE *ss, char *buf); int sdt_dns_A(SDT_STATE *ss, char *buf, ssize_t n); char *sdt_dns_poll(SDT_STATE *ss, size_t *len); char *sdt_dns_parse(SDT_STATE *ss, char *pkt, int *pktlen); -char * sdt_dns_dec_CNAME(SDT_STATE *ss, u_char *data, u_int16_t *n); -char * sdt_dns_dec_TXT(SDT_STATE *ss, u_char *data, u_int16_t *n); -char * sdt_dns_dec_NULL(SDT_STATE *ss, u_char *data, u_int16_t *n); +char *sdt_dns_dec_CNAME(SDT_STATE *ss, u_char *data, u_int16_t *n); +char *sdt_dns_dec_TXT(SDT_STATE *ss, u_char *data, u_int16_t *n); +char *sdt_dns_dec_NULL(SDT_STATE *ss, u_char *data, u_int16_t *n); void sdt_dns_print_servers(SDT_STATE *ss); +char *sdt_dns_dn_roundrobin(void *state); +char *sdt_dns_dn_random(void *state); + void sdt_rand_init(void); #ifndef HAVE_ARC4RANDOM diff --git a/sdt/sdt_dns.c b/sdt/sdt_dns.c index fd562e9..08e9b17 100644 --- a/sdt/sdt_dns.c +++ b/sdt/sdt_dns.c @@ -136,7 +136,7 @@ sdt_dns_A(SDT_STATE *ss, char *buf, ssize_t n) * $temp_payload.$nonce-$sum_up.id-$id.up.$extension */ (void)snprintf(query, sizeof(query), "%s.%u-%u.id-%u.up.%s", - dn, nonce, (u_int32_t)ss->sum_up, htonl(ss->sess.id), ss->dname); + dn, nonce, (u_int32_t)ss->sum_up, htonl(ss->sess.id), ss->dname_next(ss)); VERBOSE(2, "A:%s\n", query); if (res_search(query, ns_c_in, ns_t_a, (u_char *)&pkt, sizeof(pkt)) < 0) { @@ -166,7 +166,7 @@ sdt_dns_poll(SDT_STATE *ss, size_t *len) * $sum-$nonce.id-$id.down.$extension */ (void)snprintf(query, sizeof(query), "%u-%u.id-%u.down.%s", - (u_int32_t)ss->sum, nonce, htonl(ss->sess.id), ss->dname); + (u_int32_t)ss->sum, nonce, htonl(ss->sess.id), ss->dname_next(ss)); VERBOSE(2, "POLL:%s\n", query); @@ -415,3 +415,21 @@ sdt_dns_print_servers(SDT_STATE *ss) } } + +/* Strategies for iterating through multiple + * domain names */ + char * +sdt_dns_dn_roundrobin(void *state) +{ + SDT_STATE *ss = state; + return (ss->dname[ss->dname_iterator++ % ss->dname_max]); +} + + char * +sdt_dns_dn_random(void *state) +{ + SDT_STATE *ss = state; + return (ss->dname[sdt_rand() % ss->dname_max]); +} + + diff --git a/sods/sods.c b/sods/sods.c index bf3cb61..688b51f 100644 --- a/sods/sods.c +++ b/sods/sods.c @@ -39,6 +39,7 @@ main (int argc, char *argv[]) SDS_STATE *ss = NULL; int ch = 0; + int di = 0; IS_NULL(ss = (SDS_STATE *)calloc(1, sizeof(SDS_STATE))); @@ -102,10 +103,16 @@ main (int argc, char *argv[]) argc -= optind; argv += optind; - if ( (argc != 1) || (strlen(argv[0]) > NS_MAXDNAME - 1)) + if ( (argc == 0) || (argc >= MAXDNAMELIST)) usage(ss); - IS_NULL(ss->dn = strdup(argv[0])); + ss->dn_max = argc; + IS_NULL(ss->dn = (char **)calloc(argc, 1)); + for ( di = 0; di < argc; di++) { + if (strlen(argv[di]) > NS_MAXCDNAME - 1) + usage(ss); + IS_NULL(ss->dn[di] = strdup(argv[di])); + } if (ss->fwd == NULL) (void)sds_parse_forward(ss, "127.0.0.1:22"); diff --git a/sods/sods.h b/sods/sods.h index 0f0954d..049ea0b 100644 --- a/sods/sods.h +++ b/sods/sods.h @@ -80,7 +80,8 @@ #define BUFLEN 110 #define NS_TXTREC 65535 /* see http://www.zeroconf.org/Rendezvous/txtrecords.html */ -#define MAXFWDS 32 /* Maximum number of allowed forwarders */ +#define MAXFWDS 32 /* Maximum number of allowed forwarders */ +#define MAXDNAMELIST 256 /* Maximum number of domain names */ typedef struct _SDS_FWD { u_int8_t sess; /* Unused */ @@ -89,7 +90,8 @@ typedef struct _SDS_FWD { typedef struct _SDS_STATE { int s; - char *dn; + char **dn; + int dn_max; char *func; /* sshdns, socket ... */ SDS_FWD *fwd; size_t fwds; /* number of forwarded sessions */ diff --git a/sods/sods_dns.c b/sods/sods_dns.c index 3996998..9dd68de 100644 --- a/sods/sods_dns.c +++ b/sods/sods_dns.c @@ -408,6 +408,7 @@ sds_dns_packet(SDS_PKT *pkt, void *data, size_t len) sds_dns_checkdn(SDS_STATE *ss, char *domain) { char *p = NULL; + int i = 0; p = strchr(domain, '.'); *p++ = '\0'; @@ -417,11 +418,15 @@ sds_dns_checkdn(SDS_STATE *ss, char *domain) return (-1); #endif - if (strncmp(ss->dn, p, strlen(ss->dn)+1) != 0) { - VERBOSE(1, "rejecting request for domain: %s\n", p); - return (-1); + if (strcmp(ss->dn[0], "any") == 0) + return (0); + + for ( i = 0; i < ss->dn_max; i++) { + if (strncmp(ss->dn[i], p, strlen(ss->dn[i])+1) == 0) + return (0); } - return (0); + VERBOSE(1, "rejecting request for domain: %s\n", p); + return (-1); }