aboutsummaryrefslogtreecommitdiffstats
path: root/src/clients/s6-dnsname-filter.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2014-12-10 03:05:47 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2014-12-10 03:05:47 +0000
commit416ef5e2bf59bb2e45066a1d5d91ac677c0f48e5 (patch)
tree1c746d673dcec7a8488c6ac51db8245411034376 /src/clients/s6-dnsname-filter.c
downloads6-dns-416ef5e2bf59bb2e45066a1d5d91ac677c0f48e5.tar.gz
Initial commit
Diffstat (limited to 'src/clients/s6-dnsname-filter.c')
-rw-r--r--src/clients/s6-dnsname-filter.c83
1 files changed, 83 insertions, 0 deletions
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) ;
+}