#define点击(此处)折叠或打开
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <sys/socket.h>
-
#include <sys/types.h>
-
#include <netinet/in.h>
-
#include <arpa/inet.h>
-
#include <unistd.h>
-
#include <errno.h>
-
#include <sys/stat.h>
-
#include <sys/epoll.h>
-
#include <time.h>
-
-
#define BUF_SIZE 1024
-
#define SRV_PORT 53
-
#define DNS_FILE "/etc/resolv.conf"
-
-
typedef unsigned short U16;
-
//const char srv_ip[] = "208.67.222.222";
-
-
typedef struct _DNS_HDR
-
{
-
U16 id;
-
U16 tag;
-
U16 numq;
-
U16 numa;
-
U16 numa1;
-
U16 numa2;
-
}DNS_HDR;
-
-
typedef struct _DNS_QER
-
{
-
U16 type;
-
U16 classes;
-
}DNS_QER;
-
-
char* get_dns_ip(void)
-
{
-
FILE* fp = NULL;
-
static char addr[32] = {''};
-
-
fp = fopen(DNS_FILE, "r");
-
if(fp == NULL)
-
return NULL;
-
-
fscanf(fp, "nameserver %s", addr);
-
-
fclose(fp);
-
return addr;
-
}
-
-
char* strtrim(char* str)
-
{
-
char*p = NULL;
-
char*q = NULL;
-
-
p = str;
-
q = str + strlen(str) - 1;
-
while(isspace(*p))
-
p++;
-
while(isspace(*q))
-
q--;
-
*(q + 1) = '';
-
return p;
-
}
-
-
char* get_reverct_ip(char* ipaddr)
-
{
-
if (ipaddr == NULL)
-
return NULL;
-
char ipstr[INET_ADDRSTRLEN] = {'',};
-
static char retstr[32] = {0};
-
char a[4][4];
-
struct in_addr addr1, addr2;
-
memset(&addr1, 0, sizeof(addr1));
-
memset(&addr2, 0, sizeof(addr2));
-
int i, j;
-
char *p = NULL;
-
for (i = 0; i < 4; i++)
-
{
-
for (j = 0; j < 4; j++)
-
a[i][j] = '';
-
}
-
i = 0;
-
p = strtok(ipaddr, ".");
-
while (p)
-
{
-
strcpy(a[i++], p);
-
p = strtok(NULL, ".");
-
}
-
sprintf(retstr, "%s.%s.%s.%s.in-addr.arpa", a[3],a[2],a[1],a[0]);
-
-
#if 0
-
inet_pton(AF_INET, ipaddr, &addr1);
-
addr2.s_addr = ntohl(addr1.s_addr);
-
inet_ntop(AF_INET, &addr2, ipstr, sizeof(ipstr));
-
sprintf(retstr, "%s.in-addr.arpa", ipstr);
-
#endif
-
-
return retstr;
-
}
-
-
int main(int argc, char** argv)
-
{
-
int clifd, len = 0, i,count=0;
-
int ipv4 = 0, ipv6 = 0;
-
socklen_t socklen = 0;
-
char buf[BUF_SIZE] = {''};
-
char tmpip[32] = {''};
-
char *p = NULL;
-
char *ipaddr = NULL;
-
char *ipaddr2 = NULL;
-
time_t sendtime = 0, recvtime = 0, caltime = 0;
-
struct sockaddr_in servaddr;
-
struct sockaddr_in6 servaddr6;
-
struct timeval pretime, aftertime, tv;
-
memset(&tv, '', sizeof(tv));
-
-
if (strchr(argv[1], '.'))
-
ipv4 = 1;
-
else if (strchr(argv[1], ':'))
-
ipv6 = 1;
-
else
-
return -1;
-
-
ipaddr = get_dns_ip();
-
if (ipv4)
-
{
-
clifd = socket(AF_INET, SOCK_DGRAM, 0 );
-
if (clifd < 0)
-
{
-
printf( " create socket error!\n " );
-
return -1;
-
}
-
bzero(&servaddr, sizeof(servaddr));
-
servaddr.sin_family = AF_INET;
-
servaddr.sin_port = htons(SRV_PORT);
-
inet_pton(AF_INET, ipaddr, &servaddr.sin_addr);
-
}
-
else if (ipv6)
-
{
-
clifd = socket(AF_INET6, SOCK_DGRAM, 0 );
-
if (clifd < 0)
-
{
-
printf( " create socket error!\n " );
-
return -1;
-
}
-
bzero(&servaddr6, sizeof(servaddr6));
-
servaddr6.sin6_family = AF_INET6;
-
servaddr6.sin6_port = htons(SRV_PORT);
-
inet_pton(AF_INET6, ipaddr, &servaddr6.sin6_addr);
-
}
-
-
DNS_HDR *dnshdr = (DNS_HDR *)buf;
-
DNS_QER *dnsqer = (DNS_QER *)(buf + sizeof(DNS_HDR));
-
memset(buf, 0, BUF_SIZE);
-
dnshdr->id = (U16)1;
-
dnshdr->tag = htons(0x0100);
-
dnshdr->numq = htons(1);
-
dnshdr->numa = 0;
-
-
strncpy(buf + sizeof(DNS_HDR) + 1, argv[1], strlen(argv[1]));
-
p = buf + sizeof(DNS_HDR) + 1;
-
i = 0;
-
while (p < (buf + sizeof(DNS_HDR) + 1 + strlen(argv[1])))
-
{
-
if ( *p == '.')
-
{
-
*(p - i - 1) = i;
-
i = 0;
-
}
-
else
-
{
-
i++;
-
}
-
p++;
-
}
-
*(p - i - 1) = i;
-
-
dnsqer = (DNS_QER *)(buf + sizeof(DNS_HDR) + 2 + strlen(argv[1]));
-
dnsqer->classes = htons(1);
-
dnsqer->type = htons(1);
-
-
tv.tv_sec = 2;
-
tv.tv_usec = 0;
-
gettimeofday(&pretime, NULL);
-
if (ipv4)
-
{
-
setsockopt(clifd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
-
socklen = sizeof(struct sockaddr_in);
-
-
len = sendto(clifd, buf, sizeof(DNS_HDR) + sizeof(DNS_QER) + strlen(argv[1]) + 2, 0, (struct sockaddr *)&servaddr, socklen);
-
if (len < 0)
-
{
-
printf("send error\n");
-
return -1;
-
}
-
len = recvfrom(clifd, buf, BUF_SIZE, 0, (struct sockaddr *)&servaddr, &socklen);
-
if (len < 0)
-
{
-
if (errno == EAGAIN)
-
{
-
printf("recvfrom timeout!\n");
-
}
-
}
-
}
-
else
-
{
-
setsockopt(clifd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
-
socklen = sizeof(struct sockaddr_in6);
-
len = sendto(clifd, buf, sizeof(DNS_HDR) + sizeof(DNS_QER) + strlen(argv[1]) + 2, 0, (struct sockaddr *)&servaddr6, socklen);
-
if (len < 0)
-
{
-
printf("send error\n");
-
return -1;
-
}
-
len = recvfrom(clifd, buf, BUF_SIZE, 0, (struct sockaddr *)&servaddr6, &socklen);
-
if (len < 0)
-
{
-
if (errno == EAGAIN)
-
{
-
fprintf(stdout, "recvfrom timeout!\n");
-
}
-
}
-
}
-
gettimeofday(&aftertime, NULL);
-
fprintf(stdout, "time ==> %d \n", (aftertime.tv_sec - pretime.tv_sec)*1000 + (aftertime.tv_usec - pretime.tv_usec)/1000);
-
-
printf("answer: %d\n", dnshdr->numa);
-
if (dnshdr->numa == 0)
-
{
-
printf("ack error\n");
-
return -1;
-
}
-
-
p = buf + len -4;
-
printf("%s ==> %u.%u.%u.%u\n",argv[1], (unsigned char)*p, (unsigned char)*(p + 1),(unsigned char)*(p + 2), (unsigned char)*(p + 3));
-
-
close(clifd);
-
return 0;
-
}
|