-
Notifications
You must be signed in to change notification settings - Fork 149
Expand file tree
/
Copy pathReverseResolve.swift
More file actions
85 lines (68 loc) · 2.21 KB
/
Copy pathReverseResolve.swift
File metadata and controls
85 lines (68 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
This source file is part of the Swift System open source project
Copyright (c) 2021 - 2025 Apple Inc. and the Swift System project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See https://swift.org/LICENSE.txt for license information
*/
import ArgumentParser
import SystemSockets
@available(System 99, *)
struct ReverseResolve: ParsableCommand {
static let configuration = CommandConfiguration(
abstract: "Reverse resolve an IP address to a hostname using getnameinfo"
)
@Argument(help: "The IP address to resolve (IPv4 or IPv6)")
var address: String
@Option(name: .shortAndLong, help: "Port number")
var port: UInt16 = 0
@Flag(name: .long, help: "Request numeric host (don't resolve)")
var numericHost: Bool = false
@Flag(name: .long, help: "Request numeric service (don't resolve)")
var numericService: Bool = false
func run() throws {
// Try to parse as IPv4
if let ipv4 = IPv4Address(address, port: port) {
let sockAddr = SocketAddress(ipv4: ipv4)
try resolve(sockAddr)
return
}
// Try to parse as IPv6
if let ipv6 = IPv6Address(address, port: port) {
let sockAddr = SocketAddress(ipv6: ipv6)
try resolve(sockAddr)
return
}
print("Error: '\(address)' is not a valid IPv4 or IPv6 address")
}
private func resolve(_ address: SocketAddress) throws {
var flags: SocketAddress.ReverseResolutionFlags = []
if numericHost {
flags.insert(.numericHost)
}
if numericService {
flags.insert(.numericService)
}
print("Resolving \(addressDescription(address))...")
let info = try address.reverseLookup(flags: flags)
print()
if let host = info.hostname {
print("Host: \(host)")
} else {
print("Host: (not resolved)")
}
if let service = info.service {
print("Service: \(service)")
} else {
print("Service: (not resolved)")
}
}
private func addressDescription(_ address: SocketAddress) -> String {
if let ipv4 = address.ipv4 {
return "\(ipv4.addressString):\(ipv4.port)"
} else if let ipv6 = address.ipv6 {
return "[\(ipv6.addressString)]:\(ipv6.port)"
} else {
return "(unknown address)"
}
}
}