|
| 1 | +/* |
| 2 | + This source file is part of the Swift System open source project |
| 3 | + |
| 4 | + Copyright (c) 2021 Apple Inc. and the Swift System project authors |
| 5 | + Licensed under Apache License v2.0 with Runtime Library Exception |
| 6 | + |
| 7 | + See https://swift.org/LICENSE.txt for license information |
| 8 | +*/ |
| 9 | + |
| 10 | +import ArgumentParser |
| 11 | +#if SYSTEM_PACKAGE |
| 12 | +import SystemPackage |
| 13 | +#else |
| 14 | +import System |
| 15 | +#endif |
| 16 | + |
| 17 | +struct ReverseResolve: ParsableCommand { |
| 18 | + static var configuration = CommandConfiguration( |
| 19 | + commandName: "reverse", |
| 20 | + abstract: "Resolve a numerical IP address and port number into a hostname/service string" |
| 21 | + ) |
| 22 | + |
| 23 | + @Argument(help: "The IP address to resolve") |
| 24 | + var address: String? |
| 25 | + |
| 26 | + @Argument(help: "The port number to resolve") |
| 27 | + var port: String? |
| 28 | + |
| 29 | + @Flag(help: "No fully qualified domain for local addresses") |
| 30 | + var nofqdn: Bool = false |
| 31 | + |
| 32 | + @Flag(help: "Disable hostname resolution; hostname must be numeric address") |
| 33 | + var numericHost: Bool = false |
| 34 | + |
| 35 | + @Flag(help: "Disable service resolution; service name must be numeric") |
| 36 | + var numericService: Bool = false |
| 37 | + |
| 38 | + @Flag(help: "Look up a datagram service") |
| 39 | + var datagram: Bool = false |
| 40 | + |
| 41 | + @Flag(help: "Allow IPv6 scope identifiers") |
| 42 | + var scopeid: Bool = false |
| 43 | + |
| 44 | + func run() throws { |
| 45 | + // First, we need to get a sockaddr, so things start with forward resolution. |
| 46 | + let infos = try SocketAddress.resolveName( |
| 47 | + hostname: address, |
| 48 | + service: port, |
| 49 | + flags: [.numericHost, .numericService]) |
| 50 | + |
| 51 | + var results: Set<String> = [] |
| 52 | + for info in infos { |
| 53 | + // Now try a reverse lookup. |
| 54 | + var flags: SocketAddress.AddressResolverFlags = [] |
| 55 | + if nofqdn { |
| 56 | + flags.insert(.noFullyQualifiedDomain) |
| 57 | + } |
| 58 | + if numericHost { |
| 59 | + flags.insert(.numericHost) |
| 60 | + } |
| 61 | + if numericService { |
| 62 | + flags.insert(.numericService) |
| 63 | + } |
| 64 | + if datagram { |
| 65 | + flags.insert(.datagram) |
| 66 | + } |
| 67 | + if scopeid { |
| 68 | + flags.insert(.scopeIdentifier) |
| 69 | + } |
| 70 | + let (hostname, service) = try SocketAddress.resolveAddress(info.address, flags: flags) |
| 71 | + results.insert("\(hostname) \(service)") |
| 72 | + } |
| 73 | + for r in results.sorted() { |
| 74 | + print(r) |
| 75 | + } |
| 76 | + } |
| 77 | +} |
0 commit comments