diff options
author | Ting-Wei Lan <lantw44@gmail.com> | 2014-06-15 03:33:16 +0800 |
---|---|---|
committer | Ting-Wei Lan <lantw44@gmail.com> | 2014-06-15 03:33:16 +0800 |
commit | b3824f12e976c84eeac0a4de42d4a150c1d2950f (patch) | |
tree | a75dca234315725a81e2f758424e2725332b8125 | |
parent | 053413943c45d190bb69c997f94e3bee8fa7f95e (diff) | |
download | fastalg-protocol-b3824f12e976c84eeac0a4de42d4a150c1d2950f.tar.gz fastalg-protocol-b3824f12e976c84eeac0a4de42d4a150c1d2950f.tar.zst fastalg-protocol-b3824f12e976c84eeac0a4de42d4a150c1d2950f.zip |
dns: Handle DNS name pointers
-rw-r--r-- | falgproto/falgproto-protocol-dns.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/falgproto/falgproto-protocol-dns.c b/falgproto/falgproto-protocol-dns.c index 2207922..b0eb014 100644 --- a/falgproto/falgproto-protocol-dns.c +++ b/falgproto/falgproto-protocol-dns.c @@ -38,8 +38,33 @@ static inline ssize_t get_question_name ( /* We assume get_question_count are called before this function, so * we don't get a malformed or truncated packet */ - ssize_t i = 12, j = 0; + ssize_t i = 12, j = 0, out_len = 0; + bool in_pointer = false; for (; i < len && pkt[i] != 0; j++) { + + /* Handle DNS name pointers, but this should not happen because this + * is the first name field in the entire packet */ + if (pkt[i] > 63) { + + /* DNS name pointer should not be nested */ + if (in_pointer) { + return -1; + } + + if (i + 1 >= len) { + return -1; + } + + uint16_t next_label; + memcpy (&next_label, pkt + i, 2); + + in_pointer = true; + i = ntohs (next_label) & ~(0xc000); + if (i >= len) { + return -1; + } + } + unsigned int label_len = pkt[i]; for (i++; i < len && label_len > 0; i++, j++, label_len--) { if (out != NULL) { @@ -56,13 +81,15 @@ static inline ssize_t get_question_name ( out[j] = '\0'; } } + + out_len = j; } if (pkt[i] != 0) { return -1; } - return i - 12 - 1; + return out_len; } FALGPROTO_PARAM_GETTER_DECL (dns) { |