From 721f4e7bb042b018a579c0168524af6ddea2a619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Mon, 17 Jan 2022 00:11:24 +0100 Subject: nepreverjeno, se pa prevede --- domain2name.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 10 deletions(-) (limited to 'domain2name.c') diff --git a/domain2name.c b/domain2name.c index 46fd2a3..7c84fbb 100644 --- a/domain2name.c +++ b/domain2name.c @@ -1,8 +1,8 @@ -int domain2name_len (const char * s, int l) { - int r = 1; /* ending terminator */ - int o = 0; /* label offset */ - for (int i = 0; i < l; i++) { - if (s[i] == '.') { +int domain2name_len (const char * s, int l) { /* TODO make domain2name FAIL at empty label (..) */ + 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 (!o) /* double period or starting period, label is empty */ break; o = 0; @@ -15,9 +15,9 @@ int domain2name_len (const char * s, int l) { } return r; } -int domain2name (char * d, const char * s, int l) { /* l is length of s */ - char * c = d; /* where to write the label size when done with label */ - char * w = d; +int domain2name (char * n /* at least _len bytes */, const char * s, int l) { /* l is length of s */ + char * c = n; /* where to write the label size when done with label */ + char * w = n; int o = 0; /* label offset */ for (int i = 0; i <= l /* yes, we go one more ... */; i++) { if (i == l /* ... here */ || s[i] == '.') { /* end of label or end of last label */ @@ -36,5 +36,84 @@ int domain2name (char * d, const char * s, int l) { /* l is length of s */ *c = 63; /* it at 63 bytes */ } *w++ = '\0'; /* luckily this makes domain2name kind of safe for handling as a string (: */ - return w-d; /* we return number of bytes written */ -} /* d must be allocated for at least _len. */ + 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 r = 0; + if (n < u+512 && *n == '\0') { + return 2; + } + while (n < u+512) { + if (*n & 1 << 7) { + if (!(*n & 1 << 6)) + return -1; /* 10xx xxxx not implemented - reserved for future use */ + n = u + N2DO(*n); + continue; + } + if (*n & 1 << 6) + return -2; /* 01xx xxxx not implemented - reserved for future use */ + if (!*n) + return r+1; + r += *n+1; + n += *n+1; + } + return -3; /* 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) { + 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') { + *w++ = '.'; + *w++ = '\0'; + return n; + } + while (n < u+512) { + 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; + continue; + } + if (*n & 1 << 6) + return NULL; /* 01xx xxxx N/I - reserved for future use as per RFC */ + if (!*n) { /* end of name */ + if (w) + *w++ = '\0'; + return r ? r : n; + } + const char * x = n+*n; + n++; + if (!(x < u+512)) + return NULL; /* malformed packet */ + while (n <= x) + if (w) + *w++ = *n++; + else + n++; + if (w) + *w++ = '.'; + } + return NULL; /* malformed packet */ +} /* Returns ptr to last byte of name - '\0' or dnsptr. Ret. NULL on fail (_len also returned < 0) */ +int normalizedomain_len (const char * s, int l) { + int ž = domain2name_len(s, l); + if (ž < 0) + return -4; + char * b = alloca(ž); + if (domain2name(b, s, l) != ž) + return -5; + 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; + char * b = alloca(ž); + if (domain2name(b, s, l) != ž) + return -5; + if (!name2domain(d, b, b)) + return -6; + return 0; +} -- cgit v1.2.3