Skip to content

Instantly share code, notes, and snippets.

@popmedic
Last active July 12, 2021 14:54
Show Gist options
  • Save popmedic/b39c52c10601f90013d7f9c1f349cfff to your computer and use it in GitHub Desktop.
Save popmedic/b39c52c10601f90013d7f9c1f349cfff to your computer and use it in GitHub Desktop.
Resolve a host for v4 or v6 in Swift
#if os(OSX)
import Cocoa
#else
import Foundation
#endif
/**
resolves a host names ip address for the specified family
- parameters:
- name: the host name to resolve
- family: AF_INET for V4 and AF_INET6 for V6
- returns: a string representation of the host name's IPv4 or IPv6 address, nil on error
*/
func resolve(host name: String,
for family: Int32) -> String? {
guard let cname = name.cString(using: .ascii) else { return nil }
var res: UnsafeMutablePointer<addrinfo>?
let status = getaddrinfo(cname, nil, nil, &res)
defer {
freeaddrinfo(res)
}
guard status == 0 else { return nil }
for res in sequence(first: res?.pointee.ai_next, next: { $0?.pointee.ai_next }) {
guard let addr = res?.pointee.ai_addr else { continue }
if addr.pointee.sa_family == family {
var buf = [CChar](repeating: 0, count: Int(NI_MAXHOST))
let status = getnameinfo(
addr,
socklen_t(addr.pointee.sa_len),
&buf,
socklen_t(buf.count),
nil,
socklen_t(0),
NI_NUMERICHOST
)
if status == 0 { return String(cString: buf) }
}
}
return nil
}
// ------------------ these are just for examples. ------------------
func getAddresses(of host: String) {
if let ipv6 = resolve(host: host, for: AF_INET6) {
print("IPv6 of \(host) = \(ipv6)")
} else {
print("error getting \(host) IPv6")
}
if let ipv4 = resolve(host: host, for: AF_INET) {
print("IPv4 of \(host) = \(ipv4)")
} else {
print("error getting \(host) IPv4")
}
}
getAddresses(of: "www.spectrum.com")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment