Получение локального доменного имени с IP-адреса (например, обратный поиск DNS с многоадресным DNS и DNS-SD)

У меня есть серверное приложение, работающее на устройстве в локальной сети, которое можно обнаружить через DNS-SD (например, Zeroconf / Bonjour / Avahi). Клиентские устройства, также находящиеся в локальной сети, подключаются к этому серверу. Я не могу контролировать, какое приложение используется для подключения к моему серверному приложению, но я знаю, что они, вероятно, используют DNS-SD и mDNS для обнаружения и подключения к серверу. Как я могу получить локальное для ссылки доменное имя, идентифицирующее эти клиентские устройства, учитывая только их IP-адрес на C или C ++?

Согласно RFC 6762 Multicast DNS - Раздел 4. Обратное сопоставление адресов:
« Как и «.local.», домены обратного сопоставления IPv4 и IPv6 также определены быть локальным для ссылки ... Поскольку имена в этом домене соответствуют локальным адресам IPv4, логично, что локальная ссылка является лучшим местом для поиска информации, относящейся к этим именам "

Таким образом, теоретически должна существовать возможность поиска локальных доменных имен по IP-адресу. Кто-нибудь знает как? Возможно, я ищу не в тех местах, но я не вижу вызова API для этого в документации Bonjour.


person BigMacAttack    schedule 11.10.2013    source источник


Ответы (1)


В итоге я получил ответ на этот вопрос через список рассылки Apple Bonjour Dev.

Согласно Куинн "Эскимос!", вот как это можно сделать:

static void DNSCallback(
    DNSServiceRef                       sdRef,
    DNSServiceFlags                     flags,
    uint32_t                            interfaceIndex,
    DNSServiceErrorType                 errorCode,
    const char                          *fullname,
    uint16_t                            rrtype,
    uint16_t                            rrclass,
    uint16_t                            rdlen,
    const void                          *rdata,
    uint32_t                            ttl,
    void                                *context
)
{
    const uint8_t *     cursor;

    fprintf(stderr, "DNSCallback\n");
    assert(rrtype == kDNSServiceType_PTR);
    assert(rrclass == kDNSServiceClass_IN);
    cursor = (const uint8_t *) rdata;
    while ( *cursor != 0 ) {
        fprintf(stderr, "%.*s.", (int) *cursor, cursor + 1);
        cursor += *cursor + 1;
    }
    fprintf(stderr, "\n");
}

static void SocketCallBack(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
    DNSServiceErrorType err;

    fprintf(stderr, "SocketCallBack\n");

    err = DNSServiceProcessResult(((AppDelegate *) info)->sdRef);
    fprintf(stderr, "err = %d\n", (int) err);
}

- (IBAction)testAction:(id)sender
{
    DNSServiceErrorType err;
    int                 sock;
    CFSocketRef         cfSock;

    fprintf(stderr, "-[AppDelegate testAction:]\n");

    assert(self->sdRef == NULL);

    err = DNSServiceQueryRecord(
        &self->sdRef,
        kDNSServiceFlagsForceMulticast,
        0,
        "9.40.0.10.in-addr.arpa.",
        kDNSServiceType_PTR,
        kDNSServiceClass_IN,
        DNSCallback,
        self
    );
    fprintf(stderr, "err = %d\n", (int) err);

    sock = DNSServiceRefSockFD(self->sdRef);
    fprintf(stderr, "sock = %d\n", sock);

    CFSocketContext context = { 0, self, NULL, NULL, NULL };

    cfSock = CFSocketCreateWithNative(NULL, sock, kCFSocketReadCallBack, SocketCallBack, &context);
    assert(cfSock != NULL);

    CFRunLoopSourceRef rls;
    rls = CFSocketCreateRunLoopSource(NULL, cfSock, 0);
    assert(rls != NULL);

    CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
}

В этом примере будет найдено локальное имя хоста для IP-адреса 10.0.40.9. IP-адрес вставляется в обратном порядке.

person BigMacAttack    schedule 14.10.2013