分享

自己实现gethostbyname

 昵称26654616 2015-07-15
  • #define点击(此处)折叠或打开
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <string.h>
    4. #include <sys/socket.h>
    5. #include <sys/types.h>
    6. #include <netinet/in.h>
    7. #include <arpa/inet.h>
    8. #include <unistd.h>
    9. #include <errno.h>
    10. #include <sys/stat.h>
    11. #include <sys/epoll.h>
    12. #include <time.h>

    13. #define BUF_SIZE 1024
    14. #define SRV_PORT 53
    15. #define DNS_FILE "/etc/resolv.conf"

    16. typedef unsigned short U16;
    17. //const char srv_ip[] = "208.67.222.222";

    18. typedef struct _DNS_HDR
    19. {
    20.     U16 id;
    21.     U16 tag;
    22.     U16 numq;
    23.     U16 numa;
    24.     U16 numa1;
    25.     U16 numa2;
    26. }DNS_HDR;

    27. typedef struct _DNS_QER
    28. {
    29.     U16 type;
    30.     U16 classes;
    31. }DNS_QER;

    32. char* get_dns_ip(void)
    33. {
    34.     FILE* fp = NULL;
    35.     static char addr[32] = {''};

    36.     fp = fopen(DNS_FILE, "r");
    37.     if(fp == NULL)
    38.         return NULL;
    39.     
    40.     fscanf(fp, "nameserver %s", addr);

    41.     fclose(fp);
    42.     return addr;
    43. }

    44. char* strtrim(char* str)
    45. {
    46.     char*p = NULL;
    47.     char*q = NULL;

    48.     p = str;
    49.     q = str + strlen(str) - 1;
    50.     while(isspace(*p))
    51.         p++;
    52.     while(isspace(*q))
    53.         q--;
    54.     *(q + 1) = '';
    55.     return p;
    56. }

    57. char* get_reverct_ip(char* ipaddr)
    58. {
    59.     if (ipaddr == NULL)
    60.         return NULL;
    61.     char ipstr[INET_ADDRSTRLEN] = {'',};
    62.     static char retstr[32] = {0};
    63.     char a[4][4];
    64.     struct in_addr addr1, addr2;
    65.     memset(&addr1, 0, sizeof(addr1));
    66.     memset(&addr2, 0, sizeof(addr2));
    67.     int i, j;
    68.     char *p = NULL;
    69.     for (i = 0; i < 4; i++)
    70.     {
    71.         for (j = 0; j < 4; j++)
    72.             a[i][j] = '';
    73.     }
    74.     i = 0;
    75.     p = strtok(ipaddr, ".");
    76.     while (p)
    77.     {
    78.         strcpy(a[i++], p);
    79.         p = strtok(NULL, ".");
    80.     }
    81.     sprintf(retstr, "%s.%s.%s.%s.in-addr.arpa", a[3],a[2],a[1],a[0]);

    82. #if 0
    83.     inet_pton(AF_INET, ipaddr, &addr1);
    84.     addr2.s_addr = ntohl(addr1.s_addr);
    85.     inet_ntop(AF_INET, &addr2, ipstr, sizeof(ipstr));
    86.     sprintf(retstr, "%s.in-addr.arpa", ipstr);
    87. #endif

    88.     return retstr;
    89. }

    90. int main(int argc, char** argv)
    91. {
    92.     int clifd, len = 0, i,count=0;
    93.     int ipv4 = 0, ipv6 = 0;
    94.     socklen_t socklen = 0;
    95.     char buf[BUF_SIZE] = {''};
    96.     char tmpip[32] = {''};
    97.     char *p = NULL;
    98.     char *ipaddr = NULL;
    99.     char *ipaddr2 = NULL;
    100.     time_t sendtime = 0, recvtime = 0, caltime = 0;
    101.     struct sockaddr_in servaddr;
    102.     struct sockaddr_in6 servaddr6;
    103.     struct timeval pretime, aftertime, tv;
    104.     memset(&tv, '', sizeof(tv));

    105.     if (strchr(argv[1], '.'))
    106.         ipv4 = 1;    
    107.     else if (strchr(argv[1], ':'))
    108.         ipv6 = 1;
    109.     else
    110.         return -1;

    111.     ipaddr = get_dns_ip();
    112.     if (ipv4)
    113.     {
    114.         clifd = socket(AF_INET, SOCK_DGRAM, 0 );
    115.         if (clifd < 0)
    116.         {
    117.             printf( " create socket error!\n " );
    118.             return -1;
    119.         }
    120.         bzero(&servaddr, sizeof(servaddr));
    121.         servaddr.sin_family = AF_INET;
    122.         servaddr.sin_port = htons(SRV_PORT);
    123.         inet_pton(AF_INET, ipaddr, &servaddr.sin_addr);
    124.     }
    125.     else if (ipv6)
    126.     {
    127.         clifd = socket(AF_INET6, SOCK_DGRAM, 0 );
    128.         if (clifd < 0)
    129.         {
    130.             printf( " create socket error!\n " );
    131.             return -1;
    132.         }
    133.         bzero(&servaddr6, sizeof(servaddr6));
    134.         servaddr6.sin6_family = AF_INET6;
    135.         servaddr6.sin6_port = htons(SRV_PORT);
    136.         inet_pton(AF_INET6, ipaddr, &servaddr6.sin6_addr);
    137.     }
    138.     
    139.     DNS_HDR *dnshdr = (DNS_HDR *)buf;
    140.     DNS_QER *dnsqer = (DNS_QER *)(buf + sizeof(DNS_HDR));
    141.     memset(buf, 0, BUF_SIZE);
    142.     dnshdr->id = (U16)1;
    143.     dnshdr->tag = htons(0x0100);
    144.     dnshdr->numq = htons(1);
    145.     dnshdr->numa = 0;

    146.     strncpy(buf + sizeof(DNS_HDR) + 1, argv[1], strlen(argv[1]));
    147.     p = buf + sizeof(DNS_HDR) + 1;
    148.     i = 0;
    149.     while (p < (buf + sizeof(DNS_HDR) + 1 + strlen(argv[1])))
    150.     {
    151.         if ( *p == '.')
    152.         {
    153.             *(p - i - 1) = i;
    154.             i = 0;
    155.         }
    156.         else
    157.         {
    158.             i++;
    159.         }
    160.         p++;
    161.     }
    162.     *(p - i - 1) = i;
    163.     
    164.     dnsqer = (DNS_QER *)(buf + sizeof(DNS_HDR) + 2 + strlen(argv[1]));
    165.     dnsqer->classes = htons(1);
    166.     dnsqer->type = htons(1);
    167.   
    168.     tv.tv_sec = 2;
    169.     tv.tv_usec = 0;
    170.     gettimeofday(&pretime, NULL);
    171.     if (ipv4)
    172.     {
    173.         setsockopt(clifd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    174.         socklen = sizeof(struct sockaddr_in);
    175.   
    176.         len = sendto(clifd, buf, sizeof(DNS_HDR) + sizeof(DNS_QER) + strlen(argv[1]) + 2, 0, (struct sockaddr *)&servaddr, socklen);
    177.         if (len < 0)
    178.         {
    179.             printf("send error\n");
    180.             return -1;
    181.         }
    182.         len = recvfrom(clifd, buf, BUF_SIZE, 0, (struct sockaddr *)&servaddr, &socklen);
    183.         if (len < 0)
    184.         {
    185.             if (errno == EAGAIN)
    186.             {
    187.                 printf("recvfrom timeout!\n");
    188.             }
    189.         }
    190.     }
    191.     else
    192.     {
    193.         setsockopt(clifd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    194.         socklen = sizeof(struct sockaddr_in6);
    195.         len = sendto(clifd, buf, sizeof(DNS_HDR) + sizeof(DNS_QER) + strlen(argv[1]) + 2, 0, (struct sockaddr *)&servaddr6, socklen);
    196.         if (len < 0)
    197.         {
    198.             printf("send error\n");
    199.             return -1;
    200.         }
    201.         len = recvfrom(clifd, buf, BUF_SIZE, 0, (struct sockaddr *)&servaddr6, &socklen);
    202.         if (len < 0)
    203.         {
    204.             if (errno == EAGAIN)
    205.             {
    206.                 fprintf(stdout, "recvfrom timeout!\n");
    207.             }
    208.         }
    209.     }
    210.     gettimeofday(&aftertime, NULL);
    211.     fprintf(stdout, "time ==> %d \n", (aftertime.tv_sec - pretime.tv_sec)*1000 + (aftertime.tv_usec - pretime.tv_usec)/1000);
    212.     
    213.     printf("answer: %d\n", dnshdr->numa);
    214.     if (dnshdr->numa == 0)
    215.     {
    216.         printf("ack error\n");
    217.         return -1;
    218.     }

    219.     p = buf + len -4;
    220.     printf("%s ==> %u.%u.%u.%u\n",argv[1], (unsigned char)*p, (unsigned char)*(p + 1),(unsigned char)*(p + 2), (unsigned char)*(p + 3));
    221.   
    222.     close(clifd);
    223.     return 0;
    224. }
     
    • 本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
      转藏 分享 献花(0

      0条评论

      发表

      请遵守用户 评论公约