summaryrefslogtreecommitdiffstats
path: root/domain2name.c
diff options
context:
space:
mode:
Diffstat (limited to 'domain2name.c')
-rw-r--r--domain2name.c64
1 files changed, 40 insertions, 24 deletions
diff --git a/domain2name.c b/domain2name.c
index 7c84fbb..4f305fb 100644
--- a/domain2name.c
+++ b/domain2name.c
@@ -2,16 +2,18 @@ int domain2name_len (const char * s, int l) { /* TODO make domain2name FAIL at e
int r = 1; /* ending terminator */ /* make functions FAIL at label.length > 63 */
int o = 0; /* label offset */ /* currently domain2name never fails */
for (int i = 0; i < l; i++) { /* NOTE when using BOTH _len, check that they are */
- if (s[i] == '.') { /* NOT negative. d2n_len will fail in d future */
+ if (s[i] == '.') { /* NOT negative. d2n_len may fail in d future */
if (!o) /* double period or starting period, label is empty */
- break;
+ break; /* we could return -1 here if r == 1 */
o = 0;
continue;
}
if (!o) /* label has started */
r++;
- r++;
- o++;
+ if (o < 63) { /* we cap label length at 64 bytes. we could return -2 here. */
+ r++;
+ o++;
+ }
}
return r;
}
@@ -38,42 +40,56 @@ int domain2name (char * n /* at least _len bytes */, const char * s, int l) { /*
*w++ = '\0'; /* luckily this makes domain2name kind of safe for handling as a string (: */
return w-n; /* we return number of bytes written */
} /* no compression, it's 2022, net bandwidth is unlimited. n2d OFC does decompress ptrs acc2 std. */
-int name2domain_len (const char * u /* >= 512 bytes */, const char * n /* name */) {
-#define N2DO(x) ((x) & ~(1 << 7 & 1 << 6)) /* pointer offset */
+int name2domain_len (const char * u, int s /* size of u */, const char * n /* name */) {
+#define N2DO(x) (ntohs(x) & ~(1 << 15 | 1 << 14)) /* pointer offset */
int r = 0;
- if (n < u+512 && *n == '\0') {
+ char * f = alloca(s/8+1);
+ memset(f, '\0', s/8+1);
+ if (n < u+s && *n == '\0') {
return 2;
}
- while (n < u+512) {
+ while (n < u+s) {
if (*n & 1 << 7) {
if (!(*n & 1 << 6))
return -1; /* 10xx xxxx not implemented - reserved for future use */
- n = u + N2DO(*n);
+ if (n+1 >= u+s)
+ return -2; /* malformed packet */
+ if (f[(n-u)/8] & 1 << (n-u)%8)
+ return -3; /* infinite pointer loop detected */
+ f[(n-u)/8] |= 1 << (n-u)%8;
+ n = u + N2DO(*(uint16_t *) n);
continue;
}
if (*n & 1 << 6)
- return -2; /* 01xx xxxx not implemented - reserved for future use */
+ return -4; /* 01xx xxxx not implemented - reserved for future use */
if (!*n)
return r+1;
r += *n+1;
n += *n+1;
}
- return -3; /* malformed packet */
+ return -5; /* malformed packet */
} /* returns number of bytes needed for buffer, passed as the first argument of name2domain(). */
-const char * name2domain (char * d /* >= _len B */, const char * u /* >= 512 B */, const char * n) {
+const char * name2domain (char * d /* >= _len B */, const char * u, int s, const char * n) {
char * w = d; /* if d is NULL nothing is written and last byte of name is returned */
const char * r = NULL;
- if (n < u+512 && *n == '\0') {
+ char * f = alloca(s/8+1);
+ memset(f, '\0', s/8+1);
+ if (n < u+s && *n == '\0') {
*w++ = '.';
*w++ = '\0';
return n;
}
- while (n < u+512) {
+ while (n < u+s) {
if (*n & 1 << 7) {
if (!(*n & 1 << 6))
return NULL; /* 10xx xxxx N/I - reserved for future use as per RFC */
- n = u + N2DO(*n);
- r = n;
+ if (n+1 >= u+s)
+ return NULL;
+ r = n+1;
+ if (f[(n-u)/8] & 1 << (n-u)%8)
+ return NULL; /* infinite pointer loop detected */
+ f[(n-u)/8] |= 1 << (n-u)%8;
+ n = u + N2DO(*(uint16_t *) n);
continue;
}
if (*n & 1 << 6)
@@ -85,7 +101,7 @@ const char * name2domain (char * d /* >= _len B */, const char * u /* >= 512 B *
}
const char * x = n+*n;
n++;
- if (!(x < u+512))
+ if (!(x < u+s))
return NULL; /* malformed packet */
while (n <= x)
if (w)
@@ -100,20 +116,20 @@ const char * name2domain (char * d /* >= _len B */, const char * u /* >= 512 B *
int normalizedomain_len (const char * s, int l) {
int ž = domain2name_len(s, l);
if (ž < 0)
- return -4;
+ return -6;
char * b = alloca(ž);
if (domain2name(b, s, l) != ž)
- return -5;
- return name2domain_len(b, b);
+ return -7;
+ return name2domain_len(b, ž, b);
}
int normalizedomain (char * d /* at least _len bytes */, const char * s, int l) {
int ž = domain2name_len(s, l);
if (ž < 0)
- return -4;
+ return -6;
char * b = alloca(ž);
if (domain2name(b, s, l) != ž)
- return -5;
- if (!name2domain(d, b, b))
- return -6;
+ return -7;
+ if (!name2domain(d, b, ž, b))
+ return -8;
return 0;
}