1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "dns.h"
/** Generate a DNS encoded domain name into \p out from the dotted string in \c buf. */
int dns_domain_fromdot(char **out,const char *buf,unsigned int n)
{
char label[63];
unsigned int labellen = 0; /* <= sizeof label */
char name[255];
unsigned int namelen = 0; /* <= sizeof name */
char ch;
char *x;
errno = EPROTO;
for (;;) {
if (!n) break;
ch = *buf++; --n;
if (ch == '.') {
if (labellen) {
if (namelen + labellen + 1 > sizeof name) return 0;
name[namelen++] = labellen;
memcpy(name + namelen,label,labellen);
namelen += labellen;
labellen = 0;
}
continue;
}
if (ch == '\\') {
if (!n) break;
ch = *buf++; --n;
if ((ch >= '0') && (ch <= '7')) {
ch -= '0';
if (n && (*buf >= '0') && (*buf <= '7')) {
ch <<= 3;
ch += *buf - '0';
++buf; --n;
if (n && (*buf >= '0') && (*buf <= '7')) {
ch <<= 3;
ch += *buf - '0';
++buf; --n;
}
}
}
}
if (labellen >= sizeof label) return 0;
label[labellen++] = ch;
}
if (labellen) {
if (namelen + labellen + 1 > sizeof name) return 0;
name[namelen++] = labellen;
memcpy(name + namelen,label,labellen);
namelen += labellen;
labellen = 0;
}
if (namelen + 1 > sizeof name) return 0;
name[namelen++] = 0;
x = malloc(namelen);
if (!x) return 0;
memcpy(x,name,namelen);
if (*out) free(*out);
*out = x;
return 1;
}
#ifdef SELFTEST_MAIN
#include "iobuf.h"
void dump(const char* name)
{
int len;
do {
int i;
len = *name++;
obuf_putf(&outbuf, "\\[d\\]", len);
for (i = 0; i < len; i++, name++)
obuf_putc(&outbuf, *name);
} while (len > 0);
obuf_endl(&outbuf);
}
void testit(const char* dot)
{
char* name = 0;
debugfn(dns_domain_fromdot(&name, dot, strlen(dot)));
dump(name);
}
MAIN
{
testit("example.com");
testit("joe.example.org");
testit("\146oo");
}
#endif
#ifdef SELFTEST_EXP
result=1
[7]example[3]com[0]
result=1
[3]joe[7]example[3]org[0]
result=1
[3]foo[0]
#endif
|