summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTing-Wei Lan <lantw44@gmail.com>2014-06-15 03:33:16 +0800
committerTing-Wei Lan <lantw44@gmail.com>2014-06-15 03:33:16 +0800
commitb3824f12e976c84eeac0a4de42d4a150c1d2950f (patch)
treea75dca234315725a81e2f758424e2725332b8125
parent053413943c45d190bb69c997f94e3bee8fa7f95e (diff)
downloadfastalg-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.c31
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) {