从iPhone设置中获取DNS服务器IP

问题描述 投票:0回答:5

我尝试找到一种方法来获取我的 DNS 服务器 IP,该 IP 地址显示在设置 -> wi-fi -> 详细信息 -> DNS 下。我不知道苹果是否允许以编程方式获取此信息。

ios objective-c iphone swift dns
5个回答
10
投票

这是(恕我直言)一个更好的 Swift3+ 变体,它是

libresolv
的 Swift 包装器的摘录,由 dig for iOS 使用,并正确处理 IPV6 名称服务器:

open class Resolver {

    fileprivate var state = __res_9_state()

    public init() {
        res_9_ninit(&state)
    }

    deinit {
        res_9_ndestroy(&state)
    }

    public final func getservers() -> [res_9_sockaddr_union] {

        let maxServers = 10
        var servers = [res_9_sockaddr_union](repeating: res_9_sockaddr_union(), count: maxServers)
        let found = Int(res_9_getservers(&state, &servers, Int32(maxServers)))

        // filter is to remove the erroneous empty entry when there's no real servers
       return Array(servers[0 ..< found]).filter() { $0.sin.sin_len > 0 }
    }
}

可以通过以下方式将

res_9_sockaddr_union
转换为其字符串值:

extension Resolver {
    public static func getnameinfo(_ s: res_9_sockaddr_union) -> String {
        var s = s
        var hostBuffer = [CChar](repeating: 0, count: Int(NI_MAXHOST))

        let sinlen = socklen_t(s.sin.sin_len)
        let _ = withUnsafePointer(to: &s) {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                Darwin.getnameinfo($0, sinlen,
                                   &hostBuffer, socklen_t(hostBuffer.count),
                                   nil, 0,
                                   NI_NUMERICHOST)
            }
        }

        return String(cString: hostBuffer)
    }
}

所有这些组合起来可以得到一个包含服务器列表的

String[]
,如下所示:

let servers = Resolver().getservers().map(Resolver.getnameinfo)

5
投票

如果您的项目中没有 Swift,则支持 IPV6 的 ObjC 版本:

#include <resolv.h>
#include <netdb.h>

@implementation DNSResolver {
    res_state _state;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        _state = malloc(sizeof(struct __res_state));
        if (EXIT_SUCCESS != res_ninit(_state)) {
            free(_state);
            return nil;
        }
    }
    return self;
}

- (void)dealloc {
    res_ndestroy(_state);
    free(_state);
}

#pragma mark - Public

- (NSString *)getDNSAddressesCSV
{
    NSMutableArray *addresses = [NSMutableArray new];

    union res_sockaddr_union servers[NI_MAXSERV];

    int serversFound = res_9_getservers(_state, servers, NI_MAXSERV);

    char hostBuffer[NI_MAXHOST];
    for (int i = 0; i < serversFound; i ++) {
        union res_sockaddr_union s = servers[i];
        if (s.sin.sin_len > 0) {
            if (EXIT_SUCCESS == getnameinfo((struct sockaddr *)&s.sin,  // Pointer to your struct sockaddr
                                            (socklen_t)s.sin.sin_len,   // Size of this struct
                                            (char *)&hostBuffer,        // Pointer to hostname string
                                            sizeof(hostBuffer),         // Size of this string
                                            nil,                        // Pointer to service name string
                                            0,                          // Size of this string
                                            NI_NUMERICHOST)) {          // Flags given
                [addresses addObject:[NSString stringWithUTF8String:hostBuffer]];
            }
        }
    }

    return [addresses componentsJoinedByString:@","];
}


@end

3
投票

我在 OS X 上使用了这个并为我工作,(也链接到 ibresolv.dylib)

#include <arpa/inet.h>
#include <ifaddrs.h>
#include <resolv.h>
#include <dns.h>

- (NSString *) getDNSAddressesStr 
{
    NSMutableString *addressStr = [[NSMutableString alloc]initWithString:@"DNS Addresses \n"];

    res_state res = malloc(sizeof(struct __res_state));

    int result = res_ninit(res);

    if ( result == 0 )
    {    
        for ( int i = 0; i < res->nscount; i++ )
        {
            NSString *s = [NSString stringWithUTF8String :  inet_ntoa(res->nsaddr_list[i].sin_addr)];
            [addressStr appendFormat:@"%@\n",s];
            NSLog(@"%@",s);
        }
    }
    else 
        [addressStr appendString:@" res_init result != 0"];

    return addressStr;
    }
}

-1
投票

这是已接受答案的 Swift3 变体:

func dnsServers() -> [in_addr_t] {
    var result = __res_9_state()
    guard res_9_ninit(&result) == 0 else { return [] }
    let sockets = result.nsaddr_list // note: nsaddr_list is a tuple, not an array
    let addresses = [sockets.0.sin_addr.s_addr, sockets.1.sin_addr.s_addr, sockets.2.sin_addr.s_addr]
    let filtered = addresses.filter { $0 != nil }
    return filtered
}

像往常一样,链接

libresolv.9.tbd
并将
#import <resolv.h>
添加到桥接头


-1
投票

请参阅以下 Swift 代码来获取网站的 DNS 解析。一种方法使用

CFHostStartInfoResolution
,而另一种方法使用
gethostbyname

这两个 API 都支持所有/多个 IP 地址解析。

private func urlToIP_cfHostResolution(_ url: String) -> [String] {

    var ipList: [String] = []

    let host = CFHostCreateWithName(nil,url as CFString).takeRetainedValue()

    CFHostStartInfoResolution(host, .addresses, nil)

    var success: DarwinBoolean = false

    if let addresses = CFHostGetAddressing(host, &success)?.takeUnretainedValue() as NSArray? {

        for case let theAddress as NSData in addresses {

            var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))

            if getnameinfo(theAddress.bytes.assumingMemoryBound(to: sockaddr.self), socklen_t(theAddress.length),
                       &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 {

                ipList.append(String(cString: hostname))
            }    
        }
    }

    return ipList
}

此方法返回

["151.101.129.69", "151.101.1.69", "151.101.193.69", "151.101.65.69"]
表示
www.stackoverflow.com

private func urlToIP_gethostbyname(_ url: URL) -> [String] {

    var ipList: [String] = []

    guard let hostname = url.host else {

        return ipList
    }

    guard let host = hostname.withCString({gethostbyname($0)}) else {

        return ipList
    }

    guard host.pointee.h_length > 0 else {

        return ipList
    }

    var index = 0

    while host.pointee.h_addr_list[index] != nil {

        var addr: in_addr = in_addr()

        memcpy(&addr.s_addr, host.pointee.h_addr_list[index], Int(host.pointee.h_length))

        guard let remoteIPAsC = inet_ntoa(addr) else {

            return ipList
        }

        ipList.append(String.init(cString: remoteIPAsC))

        index += 1
    }

    return ipList
}

此方法还为

["151.101.129.69", "151.101.1.69", "151.101.193.69", "151.101.65.69"]
 返回 
www.stackoverflow.com

希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.