summaryrefslogtreecommitdiff
path: root/src/dnsstub/dns_domain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dnsstub/dns_domain.c')
-rw-r--r--src/dnsstub/dns_domain.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/dnsstub/dns_domain.c b/src/dnsstub/dns_domain.c
new file mode 100644
index 0000000..654a827
--- /dev/null
+++ b/src/dnsstub/dns_domain.c
@@ -0,0 +1,80 @@
+#include "alloc.h"
+#include "case.h"
+#include "byte.h"
+#include "dnsresolv.h"
+
+/**
+ @file dns_domain.c
+ @author djb
+ @source ucspi-tcp
+ @brief domain qualification
+*/
+
+unsigned int dns_domain_length(const char *dn)
+{
+ const char *x;
+ unsigned char c;
+
+ x = dn;
+ while ((c = *x++))
+ x += (unsigned int) c;
+ return x - dn;
+}
+
+void dns_domain_free(char **out)
+{
+ if (*out) {
+ alloc_free(*out);
+ *out = 0;
+ }
+}
+
+int dns_domain_copy(char **out,const char *in)
+{
+ unsigned int len;
+ char *x;
+
+ len = dns_domain_length(in);
+ x = alloc(len);
+ if (!x) return 0;
+ byte_copy(x,len,in);
+ if (*out) alloc_free(*out);
+ *out = x;
+ return 1;
+}
+
+int dns_domain_equal(const char *dn1,const char *dn2)
+{
+ unsigned int len;
+
+ len = dns_domain_length(dn1);
+ if (len != dns_domain_length(dn2)) return 0;
+
+ if (case_diffb((char *)dn1,len,(char *)dn2)) return 0; /* safe since 63 < 'A' */
+ return 1;
+}
+
+int dns_domain_suffix(const char *big,const char *little)
+{
+ unsigned char c;
+
+ for (;;) {
+ if (dns_domain_equal(big,little)) return 1;
+ c = *big++;
+ if (!c) return 0;
+ big += c;
+ }
+}
+
+unsigned int dns_domain_suffixpos(const char *big,const char *little)
+{
+ const char *orig = big;
+ unsigned char c;
+
+ for (;;) {
+ if (dns_domain_equal(big,little)) return big - orig;
+ c = *big++;
+ if (!c) return 0;
+ big += c;
+ }
+}