一个简易的nslookup

总觉得用管道的方式来获取某域名的DNS不太好,于是就顺手写了个简易的nslookup。

 

//
//  main.cpp
//  nslookup
//
//  Created by Ryza 15/7/29.
//  Copyright (c) 2015 [data deleted]. All rights reserved.
//
 
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <iostream>
#include <netdb.h>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <vector>
 
/**
 *  @brief  查找所请求域名的所有IP
 *
 *  @param  domain_name 需要查询的域名
 *
 *  @return 该域名的所有IP
 */
std::vector<std::string> nslookup(const char * domain_name);

/**
 *  @brief  查找所请求域名的任一IP
 *
 *  @param  domain_name 需要查询的域名
 *
 *  @return 该域名的任一IP
 */
std::string nslookup1(const char * domain_name);

std::vector<std::string> nslookup(const char * domain_name) {
    std::vector<std::string> dns;
    
    struct addrinfo hints, *res, *res0;
    int error;
    int s = -1;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    error = getaddrinfo(domain_name, "http", &hints, &res0);

    if (!error) {
        for (res = res0; res; res = res->ai_next) {
            s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
            if (s < 0) continue;
            if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
                close(s);
                continue;
            }

            char hbuf[NI_MAXHOST];
            if (!getnameinfo(res->ai_addr, res->ai_addr->sa_len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV)) {
                dns.push_back(std::string(hbuf));
            }
        }
        freeaddrinfo(res0);
    }
    return dns;
}

std::string nslookup1(const char * domain_name) {
    struct addrinfo hints, *res, *res0;
    int error;
    int s = -1;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    error = getaddrinfo(domain_name, "http", &hints, &res0);

    if (!error) {
        for (res = res0; res; res = res->ai_next) {
            s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
            if (s < 0) continue;
            if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
                close(s);
                continue;
            }
            char hbuf[NI_MAXHOST];
            if (!getnameinfo(res->ai_addr, res->ai_addr->sa_len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV)) {
                freeaddrinfo(res0);
                return std::string(hbuf);
            }
        }
    }
    return NULL;
}

int main(int argc, const char * argv[]) {
    for (int i = 1; i < argc; i++) {
        auto dns = nslookup(argv[i]);
        printf("%s:\n",argv[i]);
        for (auto iter = dns.begin(); iter != dns.end(); iter++) {
            printf("%s\n",(*iter).c_str());
        }
        printf("\n");
    }
    return 0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *

6 + nine =