2

ローカルホストでブラウザーの DNS 要求をリッスンしようとしています。

私はこのコードを書きました:

WSADATA wsaData;
unsigned char hostname[100];

int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
int numbytes;
struct sockaddr_storage their_addr;
char buf[1000];
socklen_t addr_len;

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE; // use my IP


if (WSAStartup(MAKEWORD(2,0), &wsaData) != 0) 
{
    fprintf(stderr, "WSAStartup failed.\n");
    exit(1);
}

if ((rv = getaddrinfo(NULL, "53", &hints, &servinfo)) != 0) {
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
    return 1;
}

// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
    if ((sockfd = socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP)) == -1) {
        perror("listener: socket");
        continue;
    }

    if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
        closesocket(sockfd);
        perror("listener: bind");
        continue;
    }

    break;
}

if (p == NULL) {
    fprintf(stderr, "listener: failed to bind socket\n");
    return 2;
}

freeaddrinfo(servinfo);

printf("listener: waiting to recvfrom...\n");
addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, buf, 1000-1 , 0,(struct sockaddr *)&their_addr, &addr_len)) == -1) {
    perror("recvfrom");
    exit(1);

    printf("listener: packet is %d bytes long\n", numbytes);
    buf[numbytes] = '\0';
    printf("listener: packet contains \"%s\"\n", buf);
}

closesocket(sockfd);

読めない文字を含む 39 バイトの奇妙なパケットを取得しています...そして、何もサーフィンしていないときでも、常に 53 でパケットを取得しています。これは、DNS 要求をリッスンする良い方法ではありませんか?

Windows で DNS Ip を 127.0.0.1 に変更しました。

敬具、

4

2 に答える 2

4

DNSは HTTP のようなテキストベースのプロトコルではありません。パケットをデコードする必要があります。詳細を調べてRFC 1035ください。

于 2012-11-19T19:48:51.680 に答える
0

私はこのように解析しました:

    pointer = substring( buffer, 14, numbytes-18);
    //printf("Substring: %s \n",pointer);
    //printf("listener: packet contains \"%x\"\n", buffer);

    for( i = 0; i < strlen(pointer); i++)
    {
        // Indien kleiner als 32 dan moet het een . worden
        if(pointer[i] < 32)
            result[i] = '.';
        // Indien groeter als 32 en kleiner als 127 is het een char
        else if(pointer[i] > 32 && pointer[i] < 127)
            result[i] = (char)(pointer[i]);
        else
            continue;
    }
    result[i] = '\0';

次に、結果に「www.google.com」のようなものがあります。

于 2012-11-21T15:56:04.097 に答える