summaryrefslogtreecommitdiff
path: root/DomainDig/ReverseDNSService.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-03-18 11:59:38 -0500
committerChristian Cleberg <[email protected]>2026-03-18 11:59:38 -0500
commit376e7b55b4a0c4f54faa0c2828dea4fd17dff288 (patch)
tree540d11ad423f14975553f2490617e05aea61ae2c /DomainDig/ReverseDNSService.swift
parente11b7d29a6aa9e52f63fcb35ee7ed9127850fffe (diff)
downloaddomain-dig-376e7b55b4a0c4f54faa0c2828dea4fd17dff288.tar.gz
domain-dig-376e7b55b4a0c4f54faa0c2828dea4fd17dff288.tar.bz2
domain-dig-376e7b55b4a0c4f54faa0c2828dea4fd17dff288.zip
realigning commits
Diffstat (limited to 'DomainDig/ReverseDNSService.swift')
-rw-r--r--DomainDig/ReverseDNSService.swift48
1 files changed, 48 insertions, 0 deletions
diff --git a/DomainDig/ReverseDNSService.swift b/DomainDig/ReverseDNSService.swift
new file mode 100644
index 0000000..caab0f7
--- /dev/null
+++ b/DomainDig/ReverseDNSService.swift
@@ -0,0 +1,48 @@
+import Foundation
+
+struct ReverseDNSService {
+ /// Look up the PTR record for an IPv4 address via Cloudflare DoH.
+ static func lookup(ip: String) async -> String? {
+ let octets = ip.split(separator: ".")
+ guard octets.count == 4 else { return nil }
+
+ let reversed = octets.reversed().joined(separator: ".")
+ let ptrDomain = "\(reversed).in-addr.arpa"
+
+ // PTR record type = 12
+ do {
+ let records = try await lookupPTR(domain: ptrDomain)
+ return records.first
+ } catch {
+ return nil
+ }
+ }
+
+ private static func lookupPTR(domain: String) async throws -> [String] {
+ var components = URLComponents(string: "https://cloudflare-dns.com/dns-query")!
+ components.queryItems = [
+ URLQueryItem(name: "name", value: domain),
+ URLQueryItem(name: "type", value: "12") // PTR
+ ]
+
+ var request = URLRequest(url: components.url!)
+ request.setValue("application/dns-json", forHTTPHeaderField: "Accept")
+
+ let (data, response) = try await URLSession.shared.data(for: request)
+
+ guard let httpResponse = response as? HTTPURLResponse,
+ httpResponse.statusCode == 200 else {
+ throw URLError(.badServerResponse)
+ }
+
+ let dnsResponse = try JSONDecoder().decode(CloudflareDNSResponse.self, from: data)
+
+ guard let answers = dnsResponse.Answer else {
+ return []
+ }
+
+ return answers
+ .filter { $0.type == 12 }
+ .map { $0.data.trimmingCharacters(in: CharacterSet(charactersIn: "\"")) }
+ }
+}