diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2014-12-10 03:05:47 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2014-12-10 03:05:47 +0000 |
commit | 416ef5e2bf59bb2e45066a1d5d91ac677c0f48e5 (patch) | |
tree | 1c746d673dcec7a8488c6ac51db8245411034376 /src/clients | |
download | s6-dns-416ef5e2bf59bb2e45066a1d5d91ac677c0f48e5.tar.xz |
Initial commit
Diffstat (limited to 'src/clients')
34 files changed, 1325 insertions, 0 deletions
diff --git a/src/clients/deps-exe/s6-dnsip4 b/src/clients/deps-exe/s6-dnsip4 new file mode 100644 index 0000000..4181fd6 --- /dev/null +++ b/src/clients/deps-exe/s6-dnsip4 @@ -0,0 +1,4 @@ +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-dnsip4-filter b/src/clients/deps-exe/s6-dnsip4-filter new file mode 100644 index 0000000..2c61392 --- /dev/null +++ b/src/clients/deps-exe/s6-dnsip4-filter @@ -0,0 +1,6 @@ +libs6dnsgenericfilter.a +-lskadns +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-dnsip6 b/src/clients/deps-exe/s6-dnsip6 new file mode 100644 index 0000000..4181fd6 --- /dev/null +++ b/src/clients/deps-exe/s6-dnsip6 @@ -0,0 +1,4 @@ +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-dnsip6-filter b/src/clients/deps-exe/s6-dnsip6-filter new file mode 100644 index 0000000..2c61392 --- /dev/null +++ b/src/clients/deps-exe/s6-dnsip6-filter @@ -0,0 +1,6 @@ +libs6dnsgenericfilter.a +-lskadns +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-dnsmx b/src/clients/deps-exe/s6-dnsmx new file mode 100644 index 0000000..4181fd6 --- /dev/null +++ b/src/clients/deps-exe/s6-dnsmx @@ -0,0 +1,4 @@ +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-dnsname b/src/clients/deps-exe/s6-dnsname new file mode 100644 index 0000000..4181fd6 --- /dev/null +++ b/src/clients/deps-exe/s6-dnsname @@ -0,0 +1,4 @@ +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-dnsname-filter b/src/clients/deps-exe/s6-dnsname-filter new file mode 100644 index 0000000..2c61392 --- /dev/null +++ b/src/clients/deps-exe/s6-dnsname-filter @@ -0,0 +1,6 @@ +libs6dnsgenericfilter.a +-lskadns +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-dnsns b/src/clients/deps-exe/s6-dnsns new file mode 100644 index 0000000..4181fd6 --- /dev/null +++ b/src/clients/deps-exe/s6-dnsns @@ -0,0 +1,4 @@ +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-dnsq b/src/clients/deps-exe/s6-dnsq new file mode 100644 index 0000000..4181fd6 --- /dev/null +++ b/src/clients/deps-exe/s6-dnsq @@ -0,0 +1,4 @@ +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-dnsqr b/src/clients/deps-exe/s6-dnsqr new file mode 100644 index 0000000..4181fd6 --- /dev/null +++ b/src/clients/deps-exe/s6-dnsqr @@ -0,0 +1,4 @@ +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-dnsqualify b/src/clients/deps-exe/s6-dnsqualify new file mode 100644 index 0000000..295d71e --- /dev/null +++ b/src/clients/deps-exe/s6-dnsqualify @@ -0,0 +1,2 @@ +-ls6dns +-lskarnet diff --git a/src/clients/deps-exe/s6-dnssoa b/src/clients/deps-exe/s6-dnssoa new file mode 100644 index 0000000..4181fd6 --- /dev/null +++ b/src/clients/deps-exe/s6-dnssoa @@ -0,0 +1,4 @@ +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-dnssrv b/src/clients/deps-exe/s6-dnssrv new file mode 100644 index 0000000..4181fd6 --- /dev/null +++ b/src/clients/deps-exe/s6-dnssrv @@ -0,0 +1,4 @@ +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-dnstxt b/src/clients/deps-exe/s6-dnstxt new file mode 100644 index 0000000..4181fd6 --- /dev/null +++ b/src/clients/deps-exe/s6-dnstxt @@ -0,0 +1,4 @@ +-ls6dns +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-exe/s6-randomip b/src/clients/deps-exe/s6-randomip new file mode 100644 index 0000000..e027835 --- /dev/null +++ b/src/clients/deps-exe/s6-randomip @@ -0,0 +1,3 @@ +-lskarnet +${SOCKET_LIB} +${TAINNOW_LIB} diff --git a/src/clients/deps-lib/s6dnsgenericfilter b/src/clients/deps-lib/s6dnsgenericfilter new file mode 100644 index 0000000..2d5eee8 --- /dev/null +++ b/src/clients/deps-lib/s6dnsgenericfilter @@ -0,0 +1,2 @@ +s6dns_generic_filter_main.o +s6dns_namescanner.o diff --git a/src/clients/s6-dnsip4-filter.c b/src/clients/s6-dnsip4-filter.c new file mode 100644 index 0000000..6d6862e --- /dev/null +++ b/src/clients/s6-dnsip4-filter.c @@ -0,0 +1,52 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/fmtscan.h> +#include <skalibs/strerr2.h> +#include <skalibs/stralloc.h> +#include <s6-dns/s6dns-constants.h> +#include <s6-dns/s6dns-message.h> +#include "s6dns-generic-filter.h" + +#define USAGE "s6-dnsip4-filter [ -l lines ] [ -c concurrency ] [ -t timeout ] [ -f format ] [ -e errorformat ]" + +typedef struct s6dns_a1_s s6dns_a1_t, *s6dns_a1_t_ref ; +struct s6dns_a1_s +{ + char ip[4] ; + unsigned int got : 1 ; +} ; + +static int s6dns_message_parse_answer_a1 (s6dns_message_rr_t const *rr, char const *packet, unsigned int packetlen, unsigned int pos, unsigned int section, void *stuff) +{ + if ((section == 2) && (rr->rtype == S6DNS_T_A) && (rr->rdlength == 4)) + { + s6dns_a1_t *data = stuff ; + if (data->got) return 1 ; + byte_copy(data->ip, 4, packet+pos) ; + data->got = 1 ; + } + (void)packetlen ; + return 1 ; +} + +static int ipformatter (stralloc *sa, char const *packet, unsigned int packetlen) +{ + s6dns_a1_t data ; + s6dns_message_header_t h ; + register int r ; + data.got = 0 ; + r = s6dns_message_parse(&h, packet, packetlen, &s6dns_message_parse_answer_a1, &data) ; + if (r <= 0) return r ; + if (!data.got) return 1 ; + if (!stralloc_readyplus(sa, IP4_FMT)) return -1 ; + sa->len += ip4_fmt(sa->s + sa->len, data.ip) ; + stralloc_0(sa) ; + return 1 ; +} + +int main (int argc, char const *const *argv, char const *const *envp) +{ + PROG = "s6-dnsip4-filter" ; + return s6dns_generic_filter_main(argc, argv, envp, S6DNS_T_A, &s6dns_namescanner, &ipformatter, USAGE) ; +} diff --git a/src/clients/s6-dnsip4.c b/src/clients/s6-dnsip4.c new file mode 100644 index 0000000..03c52dd --- /dev/null +++ b/src/clients/s6-dnsip4.c @@ -0,0 +1,62 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint.h> +#include <skalibs/sgetopt.h> +#include <skalibs/bytestr.h> +#include <skalibs/strerr2.h> +#include <skalibs/buffer.h> +#include <skalibs/tai.h> +#include <skalibs/random.h> +#include <s6-dns/s6dns.h> + +#define USAGE "s6-dnsip4 [ -q ] [ -r ] [ -t timeout ] domain" +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + stralloc ips = STRALLOC_ZERO ; + tain_t deadline ; + unsigned int i = 0 ; + int flagqualify = 0 ; + int flagunsort = 0 ; + PROG = "s6-dnsip4" ; + + for (;;) + { + register int opt = subgetopt(argc, argv, "qrt:") ; + if (opt == -1) break ; + switch (opt) + { + case 'q' : flagqualify = 1 ; break ; + case 'r' : flagunsort = 1 ; break ; + case 't' : if (!uint0_scan(subgetopt_here.arg, &i)) dieusage() ; break ; + default : dieusage() ; + } + } + argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; + if (argc < 1) dieusage() ; + + tain_now_g() ; + if (i) tain_from_millisecs(&deadline, i) ; else deadline = tain_infinite_relative ; + tain_add_g(&deadline, &deadline) ; + if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ; + { + register int r = s6dns_resolve_a_g(&ips, argv[0], str_len(argv[0]), flagqualify, &deadline) ; + if (r < 0) strerr_diefu2sys((errno == ETIMEDOUT) ? 99 : 111, "resolve ", argv[0]) ; + if (!r) strerr_diefu4x(2, "resolve ", argv[0], ": ", s6dns_constants_error_str(errno)) ; + } + if (!ips.len) return 1 ; + if (flagunsort) random_unsort(ips.s, ips.len / 4, 4) ; + for (i = 0 ; i < ips.len / 4 ; i++) + { + char fmt[IP4_FMT] ; + register unsigned int n = ip4_fmt(fmt, ips.s + 4 * i) ; + fmt[n++] = '\n' ; + if (buffer_put(buffer_1small, fmt, n) < (int)n) + strerr_diefu1sys(111, "write to stdout") ; + } + if (!buffer_flush(buffer_1small)) + strerr_diefu1sys(111, "write to stdout") ; + return 0 ; +} diff --git a/src/clients/s6-dnsip6-filter.c b/src/clients/s6-dnsip6-filter.c new file mode 100644 index 0000000..a5c7418 --- /dev/null +++ b/src/clients/s6-dnsip6-filter.c @@ -0,0 +1,52 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/fmtscan.h> +#include <skalibs/strerr2.h> +#include <skalibs/stralloc.h> +#include <s6-dns/s6dns-constants.h> +#include <s6-dns/s6dns-message.h> +#include "s6dns-generic-filter.h" + +#define USAGE "s6-dnsip6-filter [ -l lines ] [ -c concurrency ] [ -t timeout ] [ -f format ] [ -e errorformat ]" + +typedef struct s6dns_aaaa1_s s6dns_aaaa1_t, *s6dns_aaaa1_t_ref ; +struct s6dns_aaaa1_s +{ + char ip[16] ; + unsigned int got : 1 ; +} ; + +static int s6dns_message_parse_answer_aaaa1 (s6dns_message_rr_t const *rr, char const *packet, unsigned int packetlen, unsigned int pos, unsigned int section, void *stuff) +{ + if ((section == 2) && (rr->rtype == S6DNS_T_AAAA) && (rr->rdlength == 16)) + { + s6dns_aaaa1_t *data = stuff ; + if (data->got) return 1 ; + byte_copy(data->ip, 16, packet+pos) ; + data->got = 1 ; + } + (void)packetlen ; + return 1 ; +} + +static int ipformatter (stralloc *sa, char const *packet, unsigned int packetlen) +{ + s6dns_aaaa1_t data ; + s6dns_message_header_t h ; + register int r ; + data.got = 0 ; + r = s6dns_message_parse(&h, packet, packetlen, &s6dns_message_parse_answer_aaaa1, &data) ; + if (r <= 0) return r ; + if (!data.got) return 1 ; + if (!stralloc_readyplus(sa, IP6_FMT)) return -1 ; + sa->len += ip6_fmt(sa->s + sa->len, data.ip) ; + stralloc_0(sa) ; + return 1 ; +} + +int main (int argc, char const *const *argv, char const *const *envp) +{ + PROG = "s6-dnsip6-filter" ; + return s6dns_generic_filter_main(argc, argv, envp, S6DNS_T_AAAA, &s6dns_namescanner, &ipformatter, USAGE) ; +} diff --git a/src/clients/s6-dnsip6.c b/src/clients/s6-dnsip6.c new file mode 100644 index 0000000..e07ba53 --- /dev/null +++ b/src/clients/s6-dnsip6.c @@ -0,0 +1,62 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint.h> +#include <skalibs/sgetopt.h> +#include <skalibs/bytestr.h> +#include <skalibs/strerr2.h> +#include <skalibs/buffer.h> +#include <skalibs/tai.h> +#include <skalibs/random.h> +#include <s6-dns/s6dns.h> + +#define USAGE "s6-dnsip6 [ -q ] [ -r ] [ -t timeout ] domain" +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + stralloc ips = STRALLOC_ZERO ; + tain_t deadline ; + unsigned int i = 0 ; + int flagqualify = 0 ; + int flagunsort = 0 ; + PROG = "s6-dnsip6" ; + + for (;;) + { + register int opt = subgetopt(argc, argv, "qrt:") ; + if (opt == -1) break ; + switch (opt) + { + case 'q' : flagqualify = 1 ; break ; + case 'r' : flagunsort = 1 ; break ; + case 't' : if (!uint0_scan(subgetopt_here.arg, &i)) dieusage() ; break ; + default : dieusage() ; + } + } + argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; + if (argc < 1) dieusage() ; + + tain_now_g() ; + if (i) tain_from_millisecs(&deadline, i) ; else deadline = tain_infinite_relative ; + tain_add_g(&deadline, &deadline) ; + if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ; + { + register int r = s6dns_resolve_aaaa_g(&ips, argv[0], str_len(argv[0]), flagqualify, &deadline) ; + if (r < 0) strerr_diefu2sys((errno == ETIMEDOUT) ? 99 : 111, "resolve ", argv[0]) ; + if (!r) strerr_diefu4x(2, "resolve ", argv[0], ": ", s6dns_constants_error_str(errno)) ; + } + if (!ips.len) return 1 ; + if (flagunsort) random_unsort(ips.s, ips.len / 16, 16) ; + for (i = 0 ; i < ips.len / 16 ; i++) + { + char fmt[IP6_FMT] ; + register unsigned int n = ip6_fmt(fmt, ips.s + 16 * i) ; + fmt[n++] = '\n' ; + if (buffer_put(buffer_1small, fmt, n) < (int)n) + strerr_diefu1sys(111, "write to stdout") ; + } + if (!buffer_flush(buffer_1small)) + strerr_diefu1sys(111, "write to stdout") ; + return 0 ; +} diff --git a/src/clients/s6-dnsmx.c b/src/clients/s6-dnsmx.c new file mode 100644 index 0000000..a495cb2 --- /dev/null +++ b/src/clients/s6-dnsmx.c @@ -0,0 +1,64 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/uint.h> +#include <skalibs/bytestr.h> +#include <skalibs/sgetopt.h> +#include <skalibs/strerr2.h> +#include <skalibs/buffer.h> +#include <skalibs/tai.h> +#include <skalibs/genalloc.h> +#include <skalibs/random.h> +#include <s6-dns/s6dns.h> + +#define USAGE "s6-dnsmx [ -q ] [ -r ] [ -t timeout ] name" +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + genalloc mxs = GENALLOC_ZERO ; /* array of s6dns_message_rr_mx_t */ + tain_t deadline ; + unsigned int i = 0 ; + int flagqualify = 0 ; + int flagunsort = 0 ; + PROG = "s6-dnsmx" ; + for (;;) + { + register int opt = subgetopt(argc, argv, "qrt:") ; + if (opt == -1) break ; + switch (opt) + { + case 'q' : flagqualify = 1 ; break ; + case 'r' : flagunsort = 1 ; break ; + case 't' : if (!uint0_scan(subgetopt_here.arg, &i)) dieusage() ; break ; + default : dieusage() ; + } + } + argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; + if (argc < 1) dieusage() ; + + tain_now_g() ; + if (i) tain_from_millisecs(&deadline, i) ; else deadline = tain_infinite_relative ; + tain_add_g(&deadline, &deadline) ; + if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ; + { + register int r = s6dns_resolve_mx_g(&mxs, argv[0], str_len(argv[0]), flagqualify, &deadline) ; + if (r < 0) strerr_diefu2sys((errno == ETIMEDOUT) ? 99 : 111, "resolve ", argv[0]) ; + if (!r) strerr_diefu4x(2, "resolve ", argv[0], ": ", s6dns_constants_error_str(errno)) ; + } + if (!genalloc_len(s6dns_message_rr_mx_t, &mxs)) return 1 ; + if (flagunsort) random_unsort(mxs.s, genalloc_len(s6dns_message_rr_mx_t, &mxs), sizeof(s6dns_message_rr_mx_t)) ; + for (i = 0 ; i < genalloc_len(s6dns_message_rr_mx_t, &mxs) ; i++) + { + char buf[S6DNS_FMT_MX] ; + register unsigned int len = s6dns_fmt_mx(buf, S6DNS_FMT_MX, genalloc_s(s6dns_message_rr_mx_t, &mxs) + i) ; + if (!len) strerr_diefu1sys(111, "format result") ; + if (buffer_put(buffer_1, buf, len) < 0) goto err ; + if (buffer_put(buffer_1, "\n", 1) < 0) goto err ; + } + if (!buffer_flush(buffer_1)) goto err ; + return 0 ; + err: + strerr_diefu1sys(111, "write to stdout") ; +} diff --git a/src/clients/s6-dnsname-filter.c b/src/clients/s6-dnsname-filter.c new file mode 100644 index 0000000..6522003 --- /dev/null +++ b/src/clients/s6-dnsname-filter.c @@ -0,0 +1,83 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/error.h> +#include <skalibs/strerr2.h> +#include <skalibs/fmtscan.h> +#include <skalibs/stralloc.h> +#include <s6-dns/s6dns-constants.h> +#include <s6-dns/s6dns-domain.h> +#include <s6-dns/s6dns-message.h> +#include "s6dns-generic-filter.h" + +#define USAGE "s6-dnsname-filter [ -4 ] [ -6 ] [ -l lines ] [ -c concurrency ] [ -t timeout ] [ -f format ] [ -e errorformat ]" + +static unsigned int ipscanner (s6dns_domain_t_ref d, char const *s) +{ + char ip[16] ; + register unsigned int pos ; + if (flag6) + { + pos = ip6_scan(s, ip) ; + if (pos) + { + s6dns_domain_arpafromip6(d, ip, 128) ; + goto yes ; + } + } + if (flag4) + { + pos = ip4_scan(s, ip) ; + if (pos) + { + s6dns_domain_arpafromip4(d, ip) ; + goto yes ; + } + } + return 0 ; + yes: + if (!s6dns_domain_encode(d)) return 0 ; + return pos ; +} + +typedef struct s6dns_domain1_s s6dns_domain1_t, *s6dns_domain1_t_ref ; +struct s6dns_domain1_s +{ + s6dns_domain_t d ; + unsigned int got : 1 ; +} ; + +static int s6dns_message_parse_answer_domain1 (s6dns_message_rr_t const *rr, char const *packet, unsigned int packetlen, unsigned int pos, unsigned int section, void *stuff) +{ + if ((section == 2) && (rr->rtype == S6DNS_T_PTR)) + { + s6dns_domain1_t *data = stuff ; + register unsigned int start = pos ; + if (data->got) return 1 ; + if (!s6dns_message_get_domain(&data->d, packet, packetlen, &pos)) return 0 ; + if (rr->rdlength != pos - start) return (errno = EPROTO, 0) ; + data->got = 1 ; + } + return 1 ; +} + +static int domainformatter (stralloc *sa, char const *packet, unsigned int packetlen) +{ + s6dns_domain1_t data ; + s6dns_message_header_t h ; + register int r ; + data.got = 0 ; + r = s6dns_message_parse(&h, packet, packetlen, &s6dns_message_parse_answer_domain1, &data) ; + if (r <= 0) return r ; + if (!data.got) return 1 ; + if (!stralloc_readyplus(sa, data.d.len + 1)) return -1 ; + sa->len += s6dns_domain_tostring(sa->s + sa->len, data.d.len + 1, &data.d) ; + stralloc_0(sa) ; + return 1 ; +} + +int main (int argc, char const *const *argv, char const *const *envp) +{ + PROG = "s6-dnsname-filter" ; + return s6dns_generic_filter_main(argc, argv, envp, S6DNS_T_PTR, &ipscanner, &domainformatter, USAGE) ; +} diff --git a/src/clients/s6-dnsname.c b/src/clients/s6-dnsname.c new file mode 100644 index 0000000..d65da3a --- /dev/null +++ b/src/clients/s6-dnsname.c @@ -0,0 +1,75 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/sgetopt.h> +#include <skalibs/strerr2.h> +#include <skalibs/buffer.h> +#include <skalibs/fmtscan.h> +#include <skalibs/tai.h> +#include <skalibs/genalloc.h> +#include <skalibs/ip46.h> +#include <skalibs/random.h> +#include <skalibs/s6dns.h> + +#define USAGE "s6-dnsname [ -4 | -6 ] [ -r ] [ -t timeout ] ip" +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + genalloc ds = GENALLOC_ZERO ; /* array of s6dns_domain_t */ + tain_t deadline ; + ip46full_t ip = IP46FULL_ZERO ; + unsigned int i = 0 ; + int flagunsort = 0 ; + int do4 = 0 ; + int do6 = 0 ; + PROG = "s6-dnsname" ; + for (;;) + { + register int opt = subgetopt(argc, argv, "46rt:") ; + if (opt == -1) break ; + switch (opt) + { + case '4' : do4 = 1 ; break ; + case '6' : do6 = 1 ; break ; + case 'r' : flagunsort = 1 ; break ; + case 't' : if (!uint0_scan(subgetopt_here.arg, &i)) dieusage() ; break ; + default : dieusage() ; + } + } + argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; + if (argc < 1) dieusage() ; + if (!do4 && !do6) do4 = do6 = 1 ; + if (do4 && do6) + { + if (!ip46full_scan(argv[0], &ip)) dieusage() ; + } + else if (do6) + { + if (!ip6_scan(argv[0], ip.ip)) dieusage() ; + ip.is6 = 1 ; + } + else if (!ip4_scan(argv[0], ip.ip)) dieusage() ; + + tain_now_g() ; + if (i) tain_from_millisecs(&deadline, i) ; else deadline = tain_infinite_relative ; + tain_add_g(&deadline, &deadline) ; + if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ; + { + register int r = ip.is6 ? s6dns_resolve_name6_g(&ds, ip.ip, &deadline) : s6dns_resolve_name4_g(&ds, ip.ip, &deadline) ; + if (r < 0) strerr_diefu2sys((errno == ETIMEDOUT) ? 99 : 111, "resolve ", argv[0]) ; + if (!r) strerr_diefu4x(2, "resolve ", argv[0], ": ", s6dns_constants_error_str(errno)) ; + } + if (!genalloc_len(s6dns_domain_t, &ds)) return 1 ; + if (flagunsort) random_unsort(ds.s, genalloc_len(s6dns_domain_t, &ds), sizeof(s6dns_domain_t)) ; + { + char buf[S6DNS_FMT_DOMAINLIST(genalloc_len(s6dns_domain_t, &ds))] ; + unsigned int len = s6dns_fmt_domainlist(buf, S6DNS_FMT_DOMAINLIST(genalloc_len(s6dns_domain_t, &ds)), genalloc_s(s6dns_domain_t, &ds), genalloc_len(s6dns_domain_t, &ds), "\n", 1) ; + if (!len) strerr_diefu1sys(111, "format result") ; + if (buffer_putalign(buffer_1, buf, len) < 0) goto err ; + } + if (buffer_putflush(buffer_1, "\n", 1) < 0) goto err ; + return 0 ; + err: + strerr_diefu1sys(111, "write to stdout") ; +} diff --git a/src/clients/s6-dnsns.c b/src/clients/s6-dnsns.c new file mode 100644 index 0000000..d1caba5 --- /dev/null +++ b/src/clients/s6-dnsns.c @@ -0,0 +1,61 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint.h> +#include <skalibs/bytestr.h> +#include <skalibs/sgetopt.h> +#include <skalibs/strerr2.h> +#include <skalibs/buffer.h> +#include <skalibs/tai.h> +#include <skalibs/genalloc.h> +#include <skalibs/random.h> +#include <s6-dns/s6dns.h> + +#define USAGE "s6-dnsns [ -q ] [ -r ] [ -t timeout ] name" +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + genalloc ds = GENALLOC_ZERO ; /* array of s6dns_domain_t */ + tain_t deadline ; + unsigned int i = 0 ; + int flagqualify = 0 ; + int flagunsort = 0 ; + PROG = "s6-dnsns" ; + for (;;) + { + register int opt = subgetopt(argc, argv, "qrt:") ; + if (opt == -1) break ; + switch (opt) + { + case 'q' : flagqualify = 1 ; break ; + case 'r' : flagunsort = 1 ; break ; + case 't' : if (!uint0_scan(subgetopt_here.arg, &i)) dieusage() ; break ; + default : dieusage() ; + } + } + argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; + if (argc < 1) dieusage() ; + + tain_now_g() ; + if (i) tain_from_millisecs(&deadline, i) ; else deadline = tain_infinite_relative ; + tain_add_g(&deadline, &deadline) ; + if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ; + { + register int r = s6dns_resolve_ns_g(&ds, argv[0], str_len(argv[0]), flagqualify, &deadline) ; + if (r < 0) strerr_diefu2sys((errno == ETIMEDOUT) ? 99 : 111, "resolve ", argv[0]) ; + if (!r) strerr_diefu4x(2, "resolve ", argv[0], ": ", s6dns_constants_error_str(errno)) ; + } + if (!genalloc_len(s6dns_domain_t, &ds)) return 1 ; + if (flagunsort) random_unsort(ds.s, genalloc_len(s6dns_domain_t, &ds), sizeof(s6dns_domain_t)) ; + { + char buf[S6DNS_FMT_DOMAINLIST(genalloc_len(s6dns_domain_t, &ds))] ; + unsigned int len = s6dns_fmt_domainlist(buf, S6DNS_FMT_DOMAINLIST(genalloc_len(s6dns_domain_t, &ds)), genalloc_s(s6dns_domain_t, &ds), genalloc_len(s6dns_domain_t, &ds), "\n", 1) ; + if (!len) strerr_diefu1sys(111, "format result") ; + if (buffer_put(buffer_1, buf, len) < 0) goto err ; + } + if (buffer_putflush(buffer_1, "\n", 1) < 0) goto err ; + return 0 ; + err: + strerr_diefu1sys(111, "write to stdout") ; +} diff --git a/src/clients/s6-dnsq.c b/src/clients/s6-dnsq.c new file mode 100644 index 0000000..76ca4ea --- /dev/null +++ b/src/clients/s6-dnsq.c @@ -0,0 +1,99 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/uint32.h> +#include <skalibs/uint.h> +#include <skalibs/bytestr.h> +#include <skalibs/bitarray.h> +#include <skalibs/strerr2.h> +#include <skalibs/sgetopt.h> +#include <skalibs/buffer.h> +#include <skalibs/genwrite.h> +#include <skalibs/tai.h> +#include <skalibs/ip46.h> +#include <s6-dns/s6dns.h> +#include <s6-dns/s6dns-analyze.h> +#include <s6-dns/s6dns-debug.h> + +#define USAGE "s6-dnsq [ -1 | -2 ] [ -t timeout ] [ -D debuglevel ] qtype query serverip..." +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + tain_t deadline ; + unsigned int debuglevel = 0 ; + uint16 qtype ; + genwrite_t *where = &genwrite_stderr ; + PROG = "s6-dnsq" ; + { + subgetopt_t l = SUBGETOPT_ZERO ; + unsigned int t = 0 ; + for (;;) + { + register int opt = subgetopt_r(argc, argv, "12t:D:", &l) ; + if (opt == -1) break ; + switch (opt) + { + case '1' : where = &genwrite_stdout ; break ; + case '2' : where = &genwrite_stderr ; break ; + case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ; + case 'D' : if (!uint0_scan(l.arg, &debuglevel)) dieusage() ; break ; + default : dieusage() ; + } + } + argc -= l.ind ; argv += l.ind ; + if (t) tain_from_millisecs(&deadline, t) ; else deadline = tain_infinite_relative ; + } + if (argc < 3) dieusage() ; + { + s6dns_debughook_t dbh = { .post_recv = 0, .pre_send = 0, .post_send = 0 } ; + s6dns_ip46list_t servers ; + s6dns_domain_t d ; + unsigned int i = 0, j = 0 ; + qtype = s6dns_analyze_qtype_parse(argv[0]) ; + if (!qtype) dieusage() ; + if (!s6dns_domain_fromstring_noqualify_encode(&d, argv[1], str_len(argv[1]))) + strerr_diefu2sys(100, "encode ", argv[1]) ; + dbh.external = where ; + byte_zero(&servers, sizeof(s6dns_ip46list_t)) ; + for (; (i < (unsigned int)(argc - 2)) && (j < S6DNS_MAX_SERVERS) ; i++) + { + ip46_t z[S6DNS_MAX_SERVERS] ; + unsigned int n ; + register unsigned int k = 0 ; + if (!*argv[2+i]) continue ; + if (!ip46_scanlist(z, S6DNS_MAX_SERVERS - j, argv[2 + i], &n)) + strerr_diefu2sys(100, "make an IP address list out of ", argv[2+i]) ; + for (; k < n ; k++) + { + byte_copy(s6dns_ip46list_ip(&servers, j + k), SKALIBS_IP_SIZE, z[k].ip) ; +#ifdef SKALIBS_IPV6_ENABLED + if (ip46_is6(z + k)) bitarray_set(servers.is6, j + k) ; +#endif + } + j += n ; + } + if (debuglevel & 1) dbh.post_recv = &s6dns_debug_dumpdt_post_recv ; + if (debuglevel & 2) { dbh.pre_send = &s6dns_debug_dumpdt_pre_send ; dbh.post_send = &s6dns_debug_dumpdt_post_send ; } + tain_now_g() ; + tain_add_g(&deadline, &deadline) ; + if (!s6dns_engine_init_r_g(&s6dns_engine_here, &servers, 0, d.s, d.len, qtype, &dbh, &deadline)) + strerr_diefu1sys(111, "initialize query") ; + } + if (!s6dns_resolve_loop_g(&deadline)) + { + char fmt[UINT16_FMT] ; + fmt[uint16_fmt(fmt, qtype)] = 0 ; + strerr_diefu6x((errno == ETIMEDOUT) ? 99 : 2, "resolve query ", argv[0], " of qtype ", fmt, ": ", s6dns_constants_error_str(errno)) ; + } + if (!s6dns_analyze_packet(&genwrite_stdout, s6dns_engine_packet(&s6dns_engine_here), s6dns_engine_packetlen(&s6dns_engine_here), 0)) + { + int e = errno ; + buffer_flush(buffer_1) ; + errno = e ; + strerr_diefu1sys(111, "analyze response") ; + } + if (!buffer_flush(buffer_1)) strerr_diefu1sys(111, "write to stdout") ; + return 0 ; +} diff --git a/src/clients/s6-dnsqr.c b/src/clients/s6-dnsqr.c new file mode 100644 index 0000000..1effe68 --- /dev/null +++ b/src/clients/s6-dnsqr.c @@ -0,0 +1,74 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/uint.h> +#include <skalibs/bytestr.h> +#include <skalibs/strerr2.h> +#include <skalibs/sgetopt.h> +#include <skalibs/buffer.h> +#include <skalibs/genwrite.h> +#include <skalibs/tai.h> +#include <s6-dns/s6dns.h> +#include <s6-dns/s6dns-analyze.h> +#include <s6-dns/s6dns-debug.h> + +#define USAGE "s6-dnsqr [ -1 | -2 ] [ -t timeout ] [ -D debuglevel ] qtype query" +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + tain_t deadline ; + unsigned int debuglevel = 0 ; + genwrite_t *where = &genwrite_stderr ; + PROG = "s6-dnsqr" ; + { + subgetopt_t l = SUBGETOPT_ZERO ; + unsigned int t = 0 ; + for (;;) + { + register int opt = subgetopt_r(argc, argv, "12t:D:", &l) ; + if (opt == -1) break ; + switch (opt) + { + case '1' : where = &genwrite_stdout ; break ; + case '2' : where = &genwrite_stderr ; break ; + case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ; + case 'D' : if (!uint0_scan(l.arg, &debuglevel)) dieusage() ; break ; + default : dieusage() ; + } + } + argc -= l.ind ; argv += l.ind ; + if (t) tain_from_millisecs(&deadline, t) ; else deadline = tain_infinite_relative ; + } + if (argc < 2) dieusage() ; + { + s6dns_debughook_t dbh = { .post_recv = 0, .pre_send = 0, .post_send = 0 } ; + s6dns_domain_t d ; + uint16 qtype = s6dns_analyze_qtype_parse(argv[0]) ; + if (!qtype) dieusage() ; + if (!s6dns_domain_fromstring_noqualify_encode(&d, argv[1], str_len(argv[1]))) + strerr_diefu2sys(100, "encode ", argv[1]) ; + dbh.external = where ; + if (debuglevel & 1) dbh.post_recv = &s6dns_debug_dumpdt_post_recv ; + if (debuglevel & 2) { dbh.pre_send = &s6dns_debug_dumpdt_pre_send ; dbh.post_send = &s6dns_debug_dumpdt_post_send ; } + tain_now_g() ; + tain_add_g(&deadline, &deadline) ; + if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ; + if (!s6dns_resolve_core_r_g(&d, qtype, &s6dns_engine_here, &s6dns_rci_here.servers, &dbh, &deadline)) + { + char fmt[UINT16_FMT] ; + fmt[uint16_fmt(fmt, qtype)] = 0 ; + strerr_diefu6x((errno == ETIMEDOUT) ? 99 : 2, "resolve query ", argv[1], " of qtype ", fmt, ": ", s6dns_constants_error_str(errno)) ; + } + } + if (!s6dns_analyze_packet(&genwrite_stdout, s6dns_engine_packet(&s6dns_engine_here), s6dns_engine_packetlen(&s6dns_engine_here), 1)) + { + int e = errno ; + buffer_flush(buffer_1) ; + errno = e ; + strerr_diefu1sys(111, "analyze response") ; + } + if (!buffer_flush(buffer_1)) strerr_diefu1sys(111, "write to stdout") ; + return 0 ; +} diff --git a/src/clients/s6-dnsqualify.c b/src/clients/s6-dnsqualify.c new file mode 100644 index 0000000..64767ae --- /dev/null +++ b/src/clients/s6-dnsqualify.c @@ -0,0 +1,34 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/strerr2.h> +#include <skalibs/buffer.h> +#include <s6-dns/s6dns.h> + +#define USAGE "s6-dnsqualify name" +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + s6dns_domain_t d ; + PROG = "s6-dnsqualify" ; + if (argc < 2) dieusage() ; + if (!s6dns_domain_fromstring(&d, argv[1], str_len(argv[1]))) + strerr_diefu2sys(100, "make a domain name from ", argv[1]) ; + if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ; + { + s6dns_domain_t list[s6dns_rci_here.rulesnum] ; + unsigned int n = s6dns_qualify(list, &d) ; + if (!n) strerr_diefu2sys(111, "qualify ", argv[1]) ; + { + char buf[S6DNS_FMT_DOMAINLIST(n)] ; + unsigned int len = s6dns_fmt_domainlist(buf, S6DNS_FMT_DOMAINLIST(n), list, n, "\n", 1) ; + if (!len) strerr_diefu1sys(111, "format result") ; + if (buffer_put(buffer_1, buf, len) < 0) goto err ; + } + } + if (buffer_putflush(buffer_1, "\n", 1) < 0) goto err ; + return 0 ; + err: + strerr_diefu1sys(111, "write to stdout") ; +} diff --git a/src/clients/s6-dnssoa.c b/src/clients/s6-dnssoa.c new file mode 100644 index 0000000..1b02ff6 --- /dev/null +++ b/src/clients/s6-dnssoa.c @@ -0,0 +1,63 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint.h> +#include <skalibs/bytestr.h> +#include <skalibs/sgetopt.h> +#include <skalibs/strerr2.h> +#include <skalibs/buffer.h> +#include <skalibs/tai.h> +#include <skalibs/genalloc.h> +#include <skalibs/random.h> +#include <s6-dns/s6dns.h> + +#define USAGE "s6-dnssoa [ -q ] [ -r ] [ -t timeout ] name" +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + genalloc soas = GENALLOC_ZERO ; /* array of s6dns_message_rr_soa_t */ + tain_t deadline ; + unsigned int i = 0 ; + int flagqualify = 0 ; + int flagunsort = 0 ; + PROG = "s6-dnssoa" ; + for (;;) + { + register int opt = subgetopt(argc, argv, "qrt:") ; + if (opt == -1) break ; + switch (opt) + { + case 'q' : flagqualify = 1 ; break ; + case 'r' : flagunsort = 1 ; break ; + case 't' : if (!uint0_scan(subgetopt_here.arg, &i)) dieusage() ; break ; + default : dieusage() ; + } + } + argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; + if (argc < 1) dieusage() ; + + tain_now_g() ; + if (i) tain_from_millisecs(&deadline, i) ; else deadline = tain_infinite_relative ; + tain_add_g(&deadline, &deadline) ; + if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ; + { + register int r = s6dns_resolve_soa_g(&soas, argv[0], str_len(argv[0]), flagqualify, &deadline) ; + if (r < 0) strerr_diefu2sys((errno == ETIMEDOUT) ? 99 : 111, "resolve ", argv[0]) ; + if (!r) strerr_diefu4x(2, "resolve ", argv[0], ": ", s6dns_constants_error_str(errno)) ; + } + if (!genalloc_len(s6dns_message_rr_soa_t, &soas)) return 1 ; + if (flagunsort) random_unsort(soas.s, genalloc_len(s6dns_message_rr_soa_t, &soas), sizeof(s6dns_message_rr_soa_t)) ; + for (i = 0 ; i < genalloc_len(s6dns_message_rr_soa_t, &soas) ; i++) + { + char buf[S6DNS_FMT_SOA] ; + register unsigned int len = s6dns_fmt_soa(buf, S6DNS_FMT_SOA, genalloc_s(s6dns_message_rr_soa_t, &soas) + i) ; + if (!len) strerr_diefu1sys(111, "format result") ; + if (buffer_put(buffer_1, buf, len) < 0) goto err ; + if (buffer_put(buffer_1, "\n", 1) < 0) goto err ; + } + if (!buffer_flush(buffer_1)) goto err ; + return 0 ; + err: + strerr_diefu1sys(111, "write to stdout") ; +} diff --git a/src/clients/s6-dnssrv.c b/src/clients/s6-dnssrv.c new file mode 100644 index 0000000..283f1cd --- /dev/null +++ b/src/clients/s6-dnssrv.c @@ -0,0 +1,75 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint.h> +#include <skalibs/bytestr.h> +#include <skalibs/sgetopt.h> +#include <skalibs/strerr2.h> +#include <skalibs/buffer.h> +#include <skalibs/tai.h> +#include <skalibs/genalloc.h> +#include <skalibs/random.h> +#include <s6-dns/s6dns.h> + +#define USAGE "s6-dnssrv [ -q ] [ -r ] [ -t timeout ] service protocol name" +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + genalloc srvs = GENALLOC_ZERO ; /* array of s6dns_message_rr_srv_t */ + tain_t deadline ; + unsigned int i = 0 ; + int flagqualify = 0 ; + int flagunsort = 0 ; + PROG = "s6-dnssrv" ; + for (;;) + { + register int opt = subgetopt(argc, argv, "qt:") ; + if (opt == -1) break ; + switch (opt) + { + case 'q' : flagqualify = 1 ; break ; + case 'r' : flagunsort = 1 ; break ; + case 't' : if (!uint0_scan(subgetopt_here.arg, &i)) dieusage() ; break ; + default : dieusage() ; + } + } + argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; + if (argc < 3) dieusage() ; + + tain_now_g() ; + if (i) tain_from_millisecs(&deadline, i) ; else deadline = tain_infinite_relative ; + tain_add_g(&deadline, &deadline) ; + if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ; + { + unsigned int n0 = str_len(argv[0]) ; + unsigned int n1 = str_len(argv[1]) ; + unsigned int n2 = str_len(argv[2]) ; + char name[n0 + n1 + n2 + 5] ; + name[0] = '_' ; + byte_copy(name + 1, n0, argv[0]) ; + name[n0 + 1] = '.' ; + name[n0 + 2] = '_' ; + byte_copy(name + n0 + 3, n1, argv[1]) ; + name[n0 + n1 + 3] = '.' ; + byte_copy(name + n0 + n1 + 4, n2, argv[2]) ; + name[n0 + n1 + n2 + 4] = 0 ; + register int r = s6dns_resolve_srv_g(&srvs, name, n0 + n1 + n2 + 4, flagqualify, &deadline) ; + if (r < 0) strerr_diefu2sys((errno == ETIMEDOUT) ? 99 : 111, "resolve ", argv[0]) ; + if (!r) strerr_diefu4x(2, "resolve ", name, ": ", s6dns_constants_error_str(errno)) ; + } + if (!genalloc_len(s6dns_message_rr_srv_t, &srvs)) return 1 ; + if (flagunsort) random_unsort(srvs.s, genalloc_len(s6dns_message_rr_srv_t, &srvs), sizeof(s6dns_message_rr_srv_t)) ; + for (i = 0 ; i < genalloc_len(s6dns_message_rr_srv_t, &srvs) ; i++) + { + char buf[S6DNS_FMT_SRV] ; + register unsigned int len = s6dns_fmt_srv(buf, S6DNS_FMT_SRV, genalloc_s(s6dns_message_rr_srv_t, &srvs) + i) ; + if (!len) strerr_diefu1sys(111, "format result") ; + if (buffer_put(buffer_1, buf, len) < 0) goto err ; + if (buffer_put(buffer_1, "\n", 1) < 0) goto err ; + } + if (!buffer_flush(buffer_1)) goto err ; + return 0 ; + err: + strerr_diefu1sys(111, "write to stdout") ; +} diff --git a/src/clients/s6-dnstxt.c b/src/clients/s6-dnstxt.c new file mode 100644 index 0000000..fde69d2 --- /dev/null +++ b/src/clients/s6-dnstxt.c @@ -0,0 +1,78 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint.h> +#include <skalibs/bytestr.h> +#include <skalibs/sgetopt.h> +#include <skalibs/strerr2.h> +#include <skalibs/buffer.h> +#include <skalibs/tai.h> +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/skamisc.h> +#include <skalibs/random.h> +#include <s6-dns/s6dns.h> + +#define USAGE "s6-dnstxt [ -q ] [ -r ] [ -t timeout ] name" +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + stralloc quoted = STRALLOC_ZERO ; + stralloc sa = STRALLOC_ZERO ; + genalloc offsets = GENALLOC_ZERO ; /* array of unsigned int */ + tain_t deadline, stamp ; + unsigned int n ; + unsigned int i = 0 ; + int flagqualify = 0 ; + int flagunsort = 0 ; + PROG = "s6-dnstxt" ; + for (;;) + { + register int opt = subgetopt(argc, argv, "qrt:") ; + if (opt == -1) break ; + switch (opt) + { + case 'q' : flagqualify = 1 ; break ; + case 'r' : flagunsort = 1 ; break ; + case 't' : if (!uint0_scan(subgetopt_here.arg, &i)) dieusage() ; break ; + default : dieusage() ; + } + } + argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; + if (argc < 1) dieusage() ; + + tain_now(&stamp) ; + if (i) tain_from_millisecs(&deadline, i) ; else deadline = tain_infinite_relative ; + tain_add(&deadline, &deadline, &stamp) ; + if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ; + { + register int r = s6dns_resolve_txt(&sa, &offsets, argv[0], str_len(argv[0]), flagqualify, &deadline, &stamp) ; + if (r < 0) strerr_diefu2sys((errno == ETIMEDOUT) ? 99 : 111, "resolve ", argv[0]) ; + if (!r) strerr_diefu4x(2, "resolve ", argv[0], ": ", s6dns_constants_error_str(errno)) ; + } + n = genalloc_len(unsigned int, &offsets) ; + if (!n) return 1 ; + { + unsigned int printable_offsets[n] ; + for (i = 0 ; i < n ; i++) + { + unsigned int beg = genalloc_s(unsigned int, &offsets)[i] ; + unsigned int end = (i < n-1 ? genalloc_s(unsigned int, &offsets)[i+1] : sa.len) - 1 ; + printable_offsets[i] = quoted.len ; + if (!string_quote("ed, sa.s + beg, end - beg) || !stralloc_0("ed)) + strerr_diefu2sys(111, "quote ", sa.s + beg) ; + } + genalloc_free(unsigned int, &offsets) ; + stralloc_free(&sa) ; + if (flagunsort) random_unsort((char *)printable_offsets, n, sizeof(unsigned int)) ; + for (i = 0 ; i < n ; i++) + if ((buffer_puts(buffer_1small, quoted.s + printable_offsets[i]) < 0) + || (buffer_put(buffer_1small, "\n", 1) < 1)) + strerr_diefu1sys(111, "write to stdout") ; + } + stralloc_free("ed) ; + if (!buffer_flush(buffer_1small)) + strerr_diefu1sys(111, "write to stdout") ; + return 0 ; +} diff --git a/src/clients/s6-randomip.c b/src/clients/s6-randomip.c new file mode 100644 index 0000000..b220374 --- /dev/null +++ b/src/clients/s6-randomip.c @@ -0,0 +1,62 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint.h> +#include <skalibs/sgetopt.h> +#include <skalibs/strerr2.h> +#include <skalibs/buffer.h> +#include <skalibs/fmtscan.h> +#include <skalibs/random.h> + +#define USAGE "s6-randomip [ -4 ] [ -6 ] [ -n number ]" +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + char fmt[IP6_FMT] ; + char ip[16] ; + unsigned int n ; + unsigned int i = 0 ; + unsigned int what = 0 ; + int finite = 0 ; + PROG = "s6-randomip" ; + for (;;) + { + register int opt = subgetopt(argc, argv, "46n:") ; + if (opt == -1) break ; + switch (opt) + { + case '4' : what |= 1 ; break ; + case '6' : what |= 2 ; break ; + case 'n' : + if (!uint0_scan(subgetopt_here.arg, &n)) dieusage() ; + finite = 1 ; + break ; + default : dieusage() ; + } + } + argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; + if (!what) what = 1 ; + what = 1 << (1 << what) ; + if (!badrandom_init()) strerr_diefu1sys(111, "init RNG") ; + for (i = 0 ; !finite || (i < n) ; i++) + { + unsigned int len = what ; + if (len > 16) + { + char c ; + if (badrandom_string(&c, 1) < 1) + strerr_diefu1sys(111, "badrandom_string") ; + len = (c & 1) ? 16 : 4 ; + } + if (badrandom_string(ip, len) < 4) + strerr_diefu1sys(111, "badrandom_string") ; + len = (len == 16) ? ip6_fmt(fmt, ip) : ip4_fmt(fmt, ip) ; + fmt[len++] = '\n' ; + if (buffer_put(buffer_1, fmt, len) < (int)len) + strerr_diefu1sys(111, "write to stdout") ; + } + if (!buffer_flush(buffer_1)) + strerr_diefu1sys(111, "write to stdout") ; + return 0 ; +} diff --git a/src/clients/s6dns-generic-filter.h b/src/clients/s6dns-generic-filter.h new file mode 100644 index 0000000..53fa560 --- /dev/null +++ b/src/clients/s6dns-generic-filter.h @@ -0,0 +1,22 @@ +/* ISC license. */ + +#ifndef SKADNS_GENERIC_FILTER_H +#define SKADNS_GENERIC_FILTER_H + +#include <skalibs/uint16.h> +#include <skalibs/stralloc.h> +#include <s6-dns/s6dns-domain.h> + +typedef unsigned int scan_func_t (s6dns_domain_t *, char const *) ; +typedef scan_func_t *scan_func_t_ref ; +typedef int fmt_func_t (stralloc *, char const *, unsigned int) ; +typedef fmt_func_t *fmt_func_t_ref ; + +extern unsigned int s6dns_namescanner (s6dns_domain_t *, char const *) ; +extern int s6dns_domainformatter (stralloc *, char const *, unsigned int) ; +extern int s6dns_generic_filter_main (int, char const *const *, char const *const *, uint16, scan_func_t_ref, fmt_func_t_ref, char const *) ; + +extern int flag4 ; +extern int flag6 ; + +#endif diff --git a/src/clients/s6dns_generic_filter_main.c b/src/clients/s6dns_generic_filter_main.c new file mode 100644 index 0000000..430b0c3 --- /dev/null +++ b/src/clients/s6dns_generic_filter_main.c @@ -0,0 +1,230 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/error.h> +#include <skalibs/uint16.h> +#include <skalibs/uint.h> +#include <skalibs/sgetopt.h> +#include <skalibs/strerr2.h> +#include <skalibs/env.h> +#include <skalibs/tai.h> +#include <skalibs/iopause.h> +#include <skalibs/djbunix.h> +#include <skalibs/stralloc.h> +#include <skalibs/buffer.h> +#include <skalibs/bufalloc.h> +#include <skalibs/skamisc.h> +#include <s6-dns/s6dns-constants.h> +#include <s6-dns/s6dns-domain.h> +#include <s6-dns/skadns.h> +#include "s6dns-generic-filter.h" + +#define dieusage() strerr_dief1x(100, USAGE) ; + +typedef struct line_s line_t, *line_t_ref ; +struct line_s +{ + stralloc swrd ; + unsigned int wpos ; + int dpos ; + char w[2] ; + unsigned int pending : 1 ; +} ; + +#define LINE_ZERO { STRALLOC_ZERO, 0, 0, "\0", 0 } + +static void line_recycle (line_t_ref l) +{ + l->swrd.len = 0 ; + l->pending = 0 ; +} + +int flag4 = 0 ; +int flag6 = 0 ; + +int s6dns_generic_filter_main (int argc, char const *const *argv, char const *const *envp, uint16 qtype, scan_func_t_ref scanner, fmt_func_t_ref formatter, char const *USAGE) +{ + skadns_t a = SKADNS_ZERO ; + tain_t deadline, tto ; + char const *normalformat = "%s=%d%w%r" ; + char const *errorformat = "%s=<%e>%w%r" ; + uint16 maxlines = 256 ; + uint16 maxconn = 128 ; + { + subgetopt_t l = SUBGETOPT_ZERO ; + unsigned int t = 0 ; + for (;;) + { + register int opt = subgetopt_r(argc, argv, (qtype == S6DNS_T_PTR) ? "46l:c:t:f:e:" : "l:c:t:f:e:", &l) ; + if (opt == -1) break ; + switch (opt) + { + case '4' : flag4 = 1 ; break ; + case '6' : flag6 = 1 ; break ; + case 'l' : if (!uint160_scan(l.arg, &maxlines)) dieusage() ; break ; + case 'c' : if (!uint160_scan(l.arg, &maxconn)) dieusage() ; break ; + case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ; + case 'f' : normalformat = l.arg ; break ; + case 'e' : errorformat = l.arg ; break ; + default : dieusage() ; + } + } + argc -= l.ind ; argv += l.ind ; + if (t) tain_from_millisecs(&tto, t) ; else tto = tain_infinite_relative ; + } + if (!flag4 && !flag6) flag4 = 1 ; + if (maxconn < 1) maxconn = 1 ; + if (maxconn > SKADNS_MAXCONCURRENCY) maxconn = SKADNS_MAXCONCURRENCY ; + if (maxlines < maxconn) maxlines = maxconn ; + + tain_now_g() ; + tain_addsec_g(&deadline, 2) ; + if (!skadns_startf_g(&a, &deadline)) + strerr_diefu1sys(111, "establish skadns connection") ; + if ((ndelay_on(0) < 0) || (ndelay_on(1) < 0)) + strerr_diefu1sys(111, "ndelay_on") ; + + { + iopause_fd x[3] = { { 0, 0, 0 }, { 1, 0, 0 }, { -1, 0, 0 } } ; + uint16 lhead = 0, ltail = 0, numlines = 0, pending = 0 ; + line_t storage[maxlines+1] ; + uint16 lineindex[maxconn] ; + x[2].fd = skadns_fd(&a) ; + { + line_t line_zero = LINE_ZERO ; + char const *args[4] = { "", "", "", "" } ; + uint16 i = 0 ; + for (; i <= maxlines ; i++) storage[i] = line_zero ; + if (!string_format(&storage[0].swrd, "sdwr", normalformat, args) + || !string_format(&storage[0].swrd, "sewr", errorformat, args)) + strerr_diefu1sys(111, "format a string") ; + storage[0].swrd.len = 0 ; + } + + for (;;) + { + x[0].events = !x[0].fd && (numlines < maxlines) && (pending < maxconn) ? IOPAUSE_READ : 0 ; + x[1].events = bufalloc_len(bufalloc_1) ? IOPAUSE_WRITE : 0 ; + x[2].events = pending ? IOPAUSE_READ : 0 ; + if (!x[0].events && !x[1].events && !x[2].events) break ; + tain_add_g(&deadline, &tain_infinite_relative) ; + + if (iopause_g(x + !(x[0].events & IOPAUSE_READ), 3 - !(x[0].events & IOPAUSE_READ), &deadline) < 0) + strerr_diefu1sys(111, "iopause") ; + + + /* Flush stdout */ + + if (x[1].revents) + { + if (!bufalloc_flush(bufalloc_1) && !error_isagain(errno)) + strerr_diefu1sys(111, "write to stdout") ; + } + + + /* Get and format results from skadnsd */ + + if (x[2].revents) + { + register int j = 0 ; + register uint16 const *list ; + int n = skadns_update(&a) ; + if (n < 0) strerr_diefu1sys(111, "skadns_update") ; + list = skadns_list(&a) ; + for (; j < n ; j++) + { + register uint16 i = lineindex[list[j]] ; + register char const *packet = skadns_packet(&a, list[j]) ; + if (packet) + { + register int r ; + r = (*formatter)(&storage[i].swrd, packet, skadns_packetlen(&a, list[j])) ; + if (r < 0) strerr_diefu1sys(111, "format skadns answer") ; + if (!r) storage[i].dpos = -errno ; + } + else storage[i].dpos = -errno ; + storage[i].pending = 0 ; + skadns_release(&a, list[j]) ; + pending-- ; + } + skadns_clearlist(&a) ; + } + + + /* Scan stdin and send queries to skadnsd */ + + if (buffer_len(buffer_0) || (!x[0].fd && x[0].revents)) + { + for (; (numlines < maxlines) && (pending < maxconn) ; lhead = (lhead+1) % (maxlines+1), numlines++) + { + s6dns_domain_t d ; + register line_t_ref line = storage + lhead ; + register int r = skagetln(buffer_0, &line->swrd, '\n') ; + if (r < 0) + { + if (error_isagain(errno)) break ; + if (errno != EPIPE) strerr_diefu1sys(111, "read from stdin") ; + if (!stralloc_catb(&line->swrd, "\n", 1)) strerr_diefu1sys(111, "stralloc_catb") ; + x[0].fd = -1 ; + break ; + } + else if (!r) + { + x[0].fd = -1 ; + break ; + } + line->swrd.s[line->swrd.len-1] = 0 ; + line->wpos = (*scanner)(&d, line->swrd.s) ; + if (!line->wpos) + { + line->wpos = line->swrd.len - 1 ; + line->w[0] = 0 ; + line->dpos = -errno ; + } + else + { + tain_t sendlimit ; + uint16 id ; + line->w[0] = line->swrd.s[line->wpos] ; + line->swrd.s[line->wpos] = 0 ; + tain_addsec_g(&sendlimit, 2) ; + tain_add_g(&deadline, &tto) ; + if (!skadns_send_g(&a, &id, &d, qtype, &deadline, &sendlimit)) + line->dpos = -errno ; + else + { + line->dpos = line->swrd.len ; + lineindex[id] = lhead ; + line->pending = 1 ; + pending++ ; + } + } + } + } + + if (x[0].revents & IOPAUSE_EXCEPT) x[0].fd = -1 ; + + + /* Send processed lines to stdout */ + + for (; ltail != lhead ; ltail = (ltail+1) % (maxlines+1), numlines--) + { + char *args[4] ; + register line_t_ref line = storage + ltail ; + if (line->pending) break ; + args[0] = line->swrd.s ; + args[1] = line->dpos < 0 ? (char *)s6dns_constants_error_str(-line->dpos) : line->swrd.s + line->dpos ; + args[2] = line->w ; + args[3] = line->swrd.s + line->wpos + !!line->w[0] ; + if (!string_format(&bufalloc_1->x, line->dpos < 0 ? "sewr" : "sdwr", line->dpos < 0 ? errorformat : normalformat, (char const **)args)) + strerr_diefu1sys(111, "format output line") ; + line_recycle(line) ; + if (!bufalloc_put(bufalloc_1, "\n", 1)) + strerr_diefu1sys(111, "bufalloc_put") ; + } + } + } + + (void)envp ; + return 0 ; +} diff --git a/src/clients/s6dns_namescanner.c b/src/clients/s6dns_namescanner.c new file mode 100644 index 0000000..b23fb3d --- /dev/null +++ b/src/clients/s6dns_namescanner.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <s6-dns/s6dns-domain.h> +#include <s6-dns/s6dns-generic-filter.h> + +unsigned int s6dns_namescanner (s6dns_domain_t *d, char const *s) +{ + register unsigned int pos = 0 ; + while (s[pos] && (s[pos] != ' ') && (s[pos] != '\t') && (s[pos] != '\r') && (s[pos] != '\n')) pos++ ; + if (!s6dns_domain_fromstring_noqualify_encode(d, s, pos)) return 0 ; + return pos ; +} |