diff --git a/Apps/WildIpApp/App.cs b/Apps/WildIpApp/App.cs new file mode 100644 index 00000000..274a22bc --- /dev/null +++ b/Apps/WildIpApp/App.cs @@ -0,0 +1,119 @@ +/* +Technitium DNS Server +Copyright (C) 2022 Shreyas Zare (shreyas@technitium.com) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +*/ + +using DnsServerCore.ApplicationCommon; +using System; +using System.Net; +using System.Threading.Tasks; +using TechnitiumLibrary.Net.Dns; +using TechnitiumLibrary.Net.Dns.ResourceRecords; + +namespace WildIp +{ + public class App : IDnsApplication, IDnsAppRecordRequestHandler + { + #region IDisposable + + public void Dispose() + { + //do nothing + } + + #endregion + + #region public + + public Task InitializeAsync(IDnsServer dnsServer, string config) + { + //do nothing + return Task.CompletedTask; + } + + public Task ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, DnsTransportProtocol protocol, bool isRecursionAllowed, string zoneName, string appRecordName, uint appRecordTtl, string appRecordData) + { + string qname = request.Question[0].Name; + + if (qname.Length == appRecordName.Length) + return Task.FromResult(null); + + DnsResourceRecord answer; + + switch (request.Question[0].Type) + { + case DnsResourceRecordType.A: + { + string subdomain = qname.Substring(0, qname.Length - appRecordName.Length); + string[] parts = subdomain.Split(new char[] { '.', '-' }, StringSplitOptions.RemoveEmptyEntries); + byte[] rawIp = new byte[4]; + int i = 0; + + for (int j = 0; (j < parts.Length) && (i < 4); j++) + { + if (byte.TryParse(parts[j], out byte x)) + rawIp[i++] = x; + } + + if (i < 4) + return Task.FromResult(null); + + IPAddress address = new IPAddress(rawIp); + + answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.A, DnsClass.IN, appRecordTtl, new DnsARecordData(address)); + } + break; + + case DnsResourceRecordType.AAAA: + { + string subdomain = qname.Substring(0, qname.Length - appRecordName.Length - 1); + string[] parts = subdomain.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries); + IPAddress address = null; + + foreach (string part in parts) + { + if (part.Contains('-') && IPAddress.TryParse(part.Replace('-', ':'), out address)) + break; + } + + if (address is null) + return Task.FromResult(null); + + answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.AAAA, DnsClass.IN, appRecordTtl, new DnsAAAARecordData(address)); + } + break; + + default: + return Task.FromResult(null); + } + + return Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, new DnsResourceRecord[] { answer })); + } + + #endregion + + #region properties + + public string Description + { get { return "Returns the IP address that was embedded in the subdomain name for A and AAAA queries. It works similar to sslip.io."; } } + + public string ApplicationRecordDataTemplate + { get { return null; } } + + #endregion + } +} diff --git a/Apps/WildIpApp/WildIpApp.csproj b/Apps/WildIpApp/WildIpApp.csproj new file mode 100644 index 00000000..c026f7e8 --- /dev/null +++ b/Apps/WildIpApp/WildIpApp.csproj @@ -0,0 +1,38 @@ + + + + net6.0 + false + true + 1.0 + Technitium + Technitium DNS Server + Shreyas Zare + WildIpApp + WildIp + https://technitium.com/dns/ + https://github.com/TechnitiumSoftware/DnsServer + false + Library + + + + + false + + + + + + ..\..\..\TechnitiumLibrary\bin\TechnitiumLibrary.Net.dll + false + + + + + + PreserveNewest + + + + diff --git a/Apps/WildIpApp/dnsApp.config b/Apps/WildIpApp/dnsApp.config new file mode 100644 index 00000000..7a2450c3 --- /dev/null +++ b/Apps/WildIpApp/dnsApp.config @@ -0,0 +1 @@ +#This app requires no config. \ No newline at end of file diff --git a/DnsServer.sln b/DnsServer.sln index 82e3a9cc..5058e5ef 100644 --- a/DnsServer.sln +++ b/DnsServer.sln @@ -37,6 +37,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NxDomainApp", "Apps\NxDomai EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlockPageApp", "Apps\BlockPageApp\BlockPageApp.csproj", "{45C6F9AD-57D6-4D6D-9498-10B5C828E47E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WildIpApp", "Apps\WildIpApp\WildIpApp.csproj", "{8B6BEB00-0AC2-4680-A848-31AD8A0FCD82}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -107,6 +109,10 @@ Global {45C6F9AD-57D6-4D6D-9498-10B5C828E47E}.Debug|Any CPU.Build.0 = Debug|Any CPU {45C6F9AD-57D6-4D6D-9498-10B5C828E47E}.Release|Any CPU.ActiveCfg = Release|Any CPU {45C6F9AD-57D6-4D6D-9498-10B5C828E47E}.Release|Any CPU.Build.0 = Release|Any CPU + {8B6BEB00-0AC2-4680-A848-31AD8A0FCD82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8B6BEB00-0AC2-4680-A848-31AD8A0FCD82}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8B6BEB00-0AC2-4680-A848-31AD8A0FCD82}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8B6BEB00-0AC2-4680-A848-31AD8A0FCD82}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -123,6 +129,7 @@ Global {A4C31093-CA65-42D4-928A-11907076C0DE} = {938BF8EF-74B9-4FE0-B46F-11EBB7A4B3D2} {BB0010FC-20E9-4397-BF9B-C9955D9AD339} = {938BF8EF-74B9-4FE0-B46F-11EBB7A4B3D2} {45C6F9AD-57D6-4D6D-9498-10B5C828E47E} = {938BF8EF-74B9-4FE0-B46F-11EBB7A4B3D2} + {8B6BEB00-0AC2-4680-A848-31AD8A0FCD82} = {938BF8EF-74B9-4FE0-B46F-11EBB7A4B3D2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {6747BB6D-2826-4356-A213-805FBCCF9201}