1#include <stdio.h> 2#include <string.h> 3#include <unistd.h> 4#include <signal.h> 5#include <sys/types.h> 6#include <sys/time.h> 7#include <sys/wait.h> 8#include <sys/socket.h> 9#include <netinet/in.h> 10#include <arpa/inet.h> 11#include <errno.h> 12#include <fcntl.h> 13#include <unistd.h> 14#include <arpa/inet.h> 15#include <net/if.h> 16#include <sys/ioctl.h> 17 18#include "dns.h" 19 20#define DNS_PORT 53 21#define SVR_PORT 4567 22 23static int 24waitsock(int sockfd, int sec, int usec) 25{ 26 struct timeval tv; 27 fd_set fdvar; 28 int res; 29 30 FD_ZERO(&fdvar); 31 FD_SET(sockfd, &fdvar); 32 33 tv.tv_sec = sec; 34 tv.tv_usec = usec; 35 36 res = select(sockfd + 1, &fdvar, NULL, NULL, &tv); 37 38 return res; 39} 40 41 42void dns_query(char *svrip, char *hostname, char qtype, char *ret) 43{ 44 int sockfd; 45 struct sockaddr_in svr, cli, from; 46 char dnsbuf[MAX_PACKET_SIZE]; 47 int dnsbuflen; 48 dns_request_t m; 49 int i; 50 int retryCount; 51 52 if((sockfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0 ) 53 { 54 //perror("can't open datagram socket\n"); 55 return; 56 } 57 58 bzero((char *)&svr, sizeof(svr)); 59 svr.sin_family = AF_INET; 60 svr.sin_addr.s_addr = htonl(INADDR_ANY); 61 svr.sin_port = htons(SVR_PORT); 62 63 if(bind(sockfd, (struct sockaddr *)&svr, sizeof(svr))<0) 64 { 65 //perror("can't bind datagram socket\n"); 66 close(sockfd); 67 return; 68 } 69 70 bzero((char *)&cli, sizeof(cli)); 71 72 cli.sin_family = AF_INET; 73 cli.sin_addr.s_addr = inet_addr(svrip); 74 cli.sin_port = htons(DNS_PORT); 75 76 dnsbuflen = 0; 77 78 dnsbuf[dnsbuflen++] = 0x00; //Transaction ID 79 dnsbuf[dnsbuflen++] = 0x86; 80 dnsbuf[dnsbuflen++] = 0x01; //Flag: Standard query 81 dnsbuf[dnsbuflen++] = 0x00; 82 dnsbuf[dnsbuflen++] = 0x00; //Question 83 dnsbuf[dnsbuflen++] = 0x01; 84 memset(&dnsbuf[dnsbuflen], 0x00, 6);//Answer RRs, Authority RRs, Additional RRs 85 dnsbuflen+=6; 86 dnsbuflen+=dns_construct_name(hostname, &dnsbuf[dnsbuflen]); 87 if (qtype != 'M') 88 { 89 dnsbuf[dnsbuflen++] = 0x00; // Type a: host address 90 dnsbuf[dnsbuflen++] = 0x01; 91 } 92 else 93 { 94 dnsbuf[dnsbuflen++] = 0x00; // Type MX: Mail Exchanger 95 dnsbuf[dnsbuflen++] = 0x0f; 96 } 97 dnsbuf[dnsbuflen++] = 0x00; // Class : inet 98 dnsbuf[dnsbuflen++] = 0x01; 99 100 retryCount = 0; 101 102retry: 103 retryCount++; 104 105 if (retryCount==4) goto finish; 106 107 if(sendto(sockfd , dnsbuf, dnsbuflen , 0 ,(struct sockaddr *) &cli, sizeof(cli)) == -1) 108 { 109 //perror("sendto\n"); 110 goto retry; 111 } 112 113 if (waitsock(sockfd, 3, 0) == 0) 114 { 115 //perror("timeout\n"); 116 goto retry; 117 } 118 119 if ((m.numread=recvfrom(sockfd, m.original_buf, sizeof(m.original_buf), 0, NULL, sizeof(from))) == -1) 120 { 121 //perror("recvfrom\n"); 122 goto retry; 123 } 124 125 if (m.numread<sizeof(m.message.header)) 126 { 127 //perror("invalid packet\n"); 128 goto retry; 129 } 130 131 dns_decode_request(&m); 132 133 if (m.message.header.flags.f.rcode==0) 134 { 135 if (qtype != 'M') 136 sprintf(ret, "%s", m.ip); 137 else 138 sprintf(ret, "%s", m.cname); 139#ifdef REMOVE_WL600 140 printf("Recv: \n"); 141 for(i=0; i<m.numread; i++) 142 { 143 printf("%02x ", (unsigned char )m.original_buf[i]); 144 if (i%16==15) printf("\n"); 145 } 146#endif 147 } 148 else goto retry; 149 150finish: 151 close(sockfd); 152 return; 153} 154 155int dns_construct_name(char *name, char *encoded_name) 156{ 157 int i,j,k,n; 158 159 k = 0; /* k is the index to temp */ 160 i = 0; /* i is the index to name */ 161 while( name[i] ){ 162 163 /* find the dist to the next '.' or the end of the string and add it*/ 164 for( j = 0; name[i+j] && name[i+j] != '.'; j++); 165 encoded_name[k++] = j; 166 167 /* now copy the text till the next dot */ 168 for( n = 0; n < j; n++) 169 encoded_name[k++] = name[i+n]; 170 171 /* now move to the next dot */ 172 i += j + 1; 173 174 /* check to see if last dot was not the end of the string */ 175 if(!name[i-1])break; 176 } 177 encoded_name[k++] = 0; 178 return k; 179} 180 181/* CVS edit 1 */ 182