diff options
author | John Denker <jsd@av8n.com> | 2012-06-01 23:07:51 -0700 |
---|---|---|
committer | John Denker <jsd@av8n.com> | 2012-06-02 17:30:23 -0700 |
commit | 0d0f7a0e7c32842edff533246a1f8523306f9ab0 (patch) | |
tree | 43dbb2fffaa8d490731969f39f5d20832523bd5d /ucspi-tcp-0.88/dns_packet.c | |
parent | 94c58d7f8cabd9b1ff4c33c57a6ff76cdf3f955e (diff) |
as downloaded : ucspi-tcp
Diffstat (limited to 'ucspi-tcp-0.88/dns_packet.c')
-rw-r--r-- | ucspi-tcp-0.88/dns_packet.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/ucspi-tcp-0.88/dns_packet.c b/ucspi-tcp-0.88/dns_packet.c new file mode 100644 index 0000000..04a2cc8 --- /dev/null +++ b/ucspi-tcp-0.88/dns_packet.c @@ -0,0 +1,77 @@ +/* +DNS should have used LZ77 instead of its own sophomoric compression algorithm. +*/ + +#include "error.h" +#include "dns.h" + +unsigned int dns_packet_copy(char *buf,unsigned int len,unsigned int pos,char *out,unsigned int outlen) +{ + while (outlen) { + if (pos >= len) { errno = error_proto; return 0; } + *out = buf[pos++]; + ++out; --outlen; + } + return pos; +} + +unsigned int dns_packet_skipname(char *buf,unsigned int len,unsigned int pos) +{ + unsigned char ch; + + for (;;) { + if (pos >= len) break; + ch = buf[pos++]; + if (ch >= 192) return pos + 1; + if (ch >= 64) break; + if (!ch) return pos; + pos += ch; + } + + errno = error_proto; + return 0; +} + +unsigned int dns_packet_getname(char *buf,unsigned int len,unsigned int pos,char **d) +{ + unsigned int loop = 0; + unsigned int state = 0; + unsigned int firstcompress = 0; + unsigned int where; + unsigned char ch; + char name[255]; + unsigned int namelen = 0; + + for (;;) { + if (pos >= len) goto PROTO; ch = buf[pos++]; + if (++loop >= 1000) goto PROTO; + + if (state) { + if (namelen + 1 > sizeof name) goto PROTO; name[namelen++] = ch; + --state; + } + else { + while (ch >= 192) { + where = ch; where -= 192; where <<= 8; + if (pos >= len) goto PROTO; ch = buf[pos++]; + if (!firstcompress) firstcompress = pos; + pos = where + ch; + if (pos >= len) goto PROTO; ch = buf[pos++]; + if (++loop >= 1000) goto PROTO; + } + if (ch >= 64) goto PROTO; + if (namelen + 1 > sizeof name) goto PROTO; name[namelen++] = ch; + if (!ch) break; + state = ch; + } + } + + if (!dns_domain_copy(d,name)) return 0; + + if (firstcompress) return firstcompress; + return pos; + + PROTO: + errno = error_proto; + return 0; +} |