release
[hcoop/zz_old/debian/djbdns.git] / dns_ipq.c
CommitLineData
dc0d77d7
CE
1#include "stralloc.h"
2#include "case.h"
3#include "byte.h"
4#include "str.h"
5#include "dns.h"
6
7static int doit(stralloc *work,const char *rule)
8{
9 char ch;
10 unsigned int colon;
11 unsigned int prefixlen;
12
13 ch = *rule++;
14 if ((ch != '?') && (ch != '=') && (ch != '*') && (ch != '-')) return 1;
15 colon = str_chr(rule,':');
16 if (!rule[colon]) return 1;
17
18 if (work->len < colon) return 1;
19 prefixlen = work->len - colon;
20 if ((ch == '=') && prefixlen) return 1;
21 if (case_diffb(rule,colon,work->s + prefixlen)) return 1;
22 if (ch == '?') {
23 if (byte_chr(work->s,prefixlen,'.') < prefixlen) return 1;
24 if (byte_chr(work->s,prefixlen,'[') < prefixlen) return 1;
25 if (byte_chr(work->s,prefixlen,']') < prefixlen) return 1;
26 }
27
28 work->len = prefixlen;
29 if (ch == '-') work->len = 0;
30 return stralloc_cats(work,rule + colon + 1);
31}
32
33int dns_ip4_qualify_rules(stralloc *out,stralloc *fqdn,const stralloc *in,const stralloc *rules)
34{
35 unsigned int i;
36 unsigned int j;
37 unsigned int plus;
38 unsigned int fqdnlen;
39
40 if (!stralloc_copy(fqdn,in)) return -1;
41
42 for (j = i = 0;j < rules->len;++j)
43 if (!rules->s[j]) {
44 if (!doit(fqdn,rules->s + i)) return -1;
45 i = j + 1;
46 }
47
48 fqdnlen = fqdn->len;
49 plus = byte_chr(fqdn->s,fqdnlen,'+');
50 if (plus >= fqdnlen)
51 return dns_ip4(out,fqdn);
52
53 i = plus + 1;
54 for (;;) {
55 j = byte_chr(fqdn->s + i,fqdnlen - i,'+');
56 byte_copy(fqdn->s + plus,j,fqdn->s + i);
57 fqdn->len = plus + j;
58 if (dns_ip4(out,fqdn) == -1) return -1;
59 if (out->len) return 0;
60 i += j;
61 if (i >= fqdnlen) return 0;
62 ++i;
63 }
64}
65
66int dns_ip4_qualify(stralloc *out,stralloc *fqdn,const stralloc *in)
67{
68 static stralloc rules;
69 if (dns_resolvconfrewrite(&rules) == -1) return -1;
70 return dns_ip4_qualify_rules(out,fqdn,in,&rules);
71}