diff options
Diffstat (limited to 'Userland/Services/LookupServer/DNSName.cpp')
-rw-r--r-- | Userland/Services/LookupServer/DNSName.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/Userland/Services/LookupServer/DNSName.cpp b/Userland/Services/LookupServer/DNSName.cpp index 7385868076..ce9ad68f56 100644 --- a/Userland/Services/LookupServer/DNSName.cpp +++ b/Userland/Services/LookupServer/DNSName.cpp @@ -1,4 +1,5 @@ /* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> * Copyright (c) 2021, Sergey Bugaev <bugaevc@serenityos.org> * All rights reserved. * @@ -36,4 +37,36 @@ DNSName::DNSName(const String& name) m_name = name; } +DNSName DNSName::parse(const u8* data, size_t& offset, size_t max_offset, size_t recursion_level) +{ + if (recursion_level > 4) + return DNSName({}); + + StringBuilder builder; + while (true) { + if (offset >= max_offset) + return DNSName({}); + u8 b = data[offset++]; + if (b == '\0') { + // This terminates the name. + return builder.to_string(); + } else if ((b & 0xc0) == 0xc0) { + // The two bytes tell us the offset when to continue from. + if (offset >= max_offset) + return DNSName({}); + size_t dummy = (b & 0x3f) << 8 | data[offset++]; + auto rest_of_name = parse(data, dummy, max_offset, recursion_level + 1); + builder.append(rest_of_name.as_string()); + return builder.to_string(); + } else { + // This is the length of a part. + if (offset + b >= max_offset) + return DNSName({}); + builder.append((const char*)&data[offset], (size_t)b); + builder.append('.'); + offset += b; + } + } +} + } |