00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <mem.h>
00034 #include <string.h>
00035 #include <stdio.h>
00036 #include <ctype.h>
00037
00038 #include "tcpip.h"
00039
00040 #include "dns.h"
00041
00042
00043
00044
00045 #define DNS_PORT 53 // Well known DNS port
00046
00047
00048 static unsigned int ident;
00049
00050 #define BUFSIZE 600
00051
00052 #define RRBUF 200
00053
00054 typedef struct dn_rr_struct {
00055 char rrname[RRBUF];
00056 unsigned int rrtype;
00057 unsigned int rrclass;
00058 unsigned long rrttl;
00059 char rrrdata[RRBUF];
00060 } dn_rr;
00061
00062
00063 #define DN_TYPE_A 1
00064 #define DN_TYPE_NS 2
00065 #define DN_TYPE_CNAME 5
00066 #define DN_TYPE_MX 15
00067
00068
00069 #define DN_CLASS_IN 1
00070
00071
00072 #ifdef MONITOR
00073
00074 void packetmonitor(int len2, char *buffer)
00075 {
00076 int j,i,k;
00077
00078 j=0;
00079 for(i=0;i<len2;i++)
00080 {
00081 if(j==0)
00082 {
00083 printf("\n\r%3X ",i);
00084 }
00085 printf("%02X ",buffer[i]&0xff);
00086 j++;
00087 if(j==16)
00088 {
00089 for(k=0;k<j;k++)
00090 {
00091 if(isprint(buffer[i-j+k+1]&0xff))
00092 printf("%c",buffer[i-j+k+1]&0xff);
00093 else
00094 printf(".");
00095 }
00096 j=0;
00097 }
00098 }
00099 i--;
00100 for(k=0;k<j;k++)
00101 {
00102 if(isprint(buffer[i-j+k+1]&0xff))
00103 printf("%c",buffer[i-j+k+1]&0xff);
00104 else
00105 printf(".");
00106 }
00107 j=0;
00108 }
00109 #endif
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 int dn_uncompress(char *dest, int len, char *packet, char *name)
00121 {
00122 int nlen, nlenok;
00123 unsigned int u;
00124
00125
00126 *dest= 0;
00127 nlen=nlenok= 0;
00128 while(*name) {
00129 if((*name&0xc0) == 0xc0) {
00130 u= ((*name&0x3f)<<8) + (*(name+1));
00131 if(packet+u > name)
00132 return -1;
00133 name=packet+u;
00134 if(nlenok == 0) {
00135 nlen+= 2;
00136 nlenok= 1;
00137 }
00138 }
00139 else {
00140 if(*name > (len-2))
00141 return -1;
00142 len-= *name;
00143 strncat(dest,name+1,*name);
00144 if(nlenok == 0) {
00145 nlen+=*name+1;
00146 }
00147 name+= *name+1;
00148 if(*name) {
00149 len--;
00150 strcat(dest,".");
00151 }
00152 }
00153 }
00154 if(nlenok == 0)
00155 nlen++;
00156 return nlen;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 int dn_unpackrr(dn_rr *rr, char *packet, char *message)
00168 {
00169 int i;
00170 unsigned int u;
00171
00172 if((i=dn_uncompress(rr->rrname,RRBUF,packet,message)) == -1)
00173 return -1;
00174 message+=i;
00175 rr->rrtype= ((*message)<<8) + (*(message+1));
00176 message+=2;
00177 rr->rrclass= ((*message)<<8) + (*(message+1));
00178 message+=2;
00179 rr->rrttl=((*message)<<24)&0xff000000L;
00180 rr->rrttl+=((*(message+1))<<16)&0xff0000L;
00181 rr->rrttl+=((*(message+2))<<8)&0xff00;
00182 rr->rrttl+=((*(message+3)))&0xff;
00183 message+=4;
00184 u= ((*message)<<8) + (*(message+1));
00185 message+=2;
00186 switch(rr->rrtype) {
00187 case DN_TYPE_CNAME:
00188 case DN_TYPE_NS:
00189 if(dn_uncompress(rr->rrrdata,RRBUF,packet,message) == -1)
00190 return -1;
00191 break;
00192
00193 case DN_TYPE_MX: *(rr->rrrdata)=*message;
00194 *(rr->rrrdata+1)=*(message+1);
00195 message+=2;
00196 if(dn_uncompress(rr->rrrdata+2,RRBUF-2,packet,message) == -1)
00197 return -1;
00198 break;
00199
00200 case DN_TYPE_A: if(rr->rrclass == DN_CLASS_IN) {
00201 *(rr->rrrdata)=*message;
00202 *(rr->rrrdata+1)=*(message+1);
00203 *(rr->rrrdata+2)=*(message+2);
00204 *(rr->rrrdata+3)=*(message+3);
00205 *(rr->rrrdata+4)=0;
00206 }
00207 else
00208 return -2;
00209 break;
00210 default: *(rr->rrrdata)=0;
00211 }
00212 return u+i+10;
00213 }
00214
00215
00216
00217
00218
00219
00220
00221 static int packdomain(char * dest, const char *src)
00222 {
00223 int i,n,cnt;
00224
00225 n=strlen(src);
00226 dest[n+1]=0;
00227
00228 cnt=0;
00229 for (i=n; i>0; i--)
00230 {
00231 if (src[i-1]=='.')
00232 {
00233 dest[i]=cnt;
00234 cnt=0;
00235 }
00236 else
00237 {
00238 dest[i]=src[i-1];
00239 cnt++;
00240 }
00241 }
00242 dest[0]=cnt;
00243 return n+2;
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 int gethostbyname( const char *dnsServerIP,
00259 const char *domainName,
00260 unsigned long *ttl,
00261 unsigned long *IP,
00262 char *dest)
00263 {
00264 unsigned char buffer[BUFSIZE+1];
00265 int sd,error;
00266 struct sockaddr_in addr;
00267 int i,j,k,len1,len2,nRR;
00268
00269 dn_rr myrr;
00270
00271 #ifdef TRACE
00272 char s[200];
00273 printf("\r\ndns server: %s Host: %s\r\n",dnsServerIP,domainName);
00274 #endif
00275
00276 setmem(buffer,BUFSIZE,0);
00277
00278
00279 if (++ident>126) ident=1;
00280 buffer[0]=(ident>>8);
00281 buffer[1]=(ident&0xff);
00282
00283 buffer[2]=1;
00284 buffer[3]=0;
00285
00286 buffer[4]=0;
00287 buffer[5]=1;
00288
00289 len1=12;
00290 len1+=packdomain((char *)&buffer[12],domainName);
00291 buffer[len1++]=0; buffer[len1++]=1;
00292 buffer[len1++]=0; buffer[len1++]=1;
00293
00294 #ifdef TRACE
00295 printf("Request holds %d bytes\r\n",len1);
00296 for (i=0; i<len1; i++) printf(" %X",buffer[i]&0x00ff);
00297 #endif
00298
00299 sd=opensocket(SOCK_DGRAM,&error);
00300 if (sd==API_ERROR) {
00301 printf("\r\nError %d opening socket\r\n",error);
00302 return 0;
00303 }
00304
00305 addr.sin_family = AF_INET;
00306 if(inet_addr((char *)dnsServerIP, &addr.sin_addr.s_addr)) {
00307 printf("\r\nError converting DNS Server address %s \r\n",dnsServerIP);
00308 printf("\r\nIP %lX",addr.sin_addr.s_addr);
00309 return 0;
00310 }
00311 addr.sin_port=htons(DNS_PORT);
00312
00313 if ( API_ERROR==sendto(sd, (char *)buffer, len1, MSG_BLOCKING, (const struct sockaddr * )&addr, &error))
00314 {
00315 printf("\r\nError %d sending data in line %d\r\n",error,__LINE__);
00316 closesocket(sd,&error);
00317 return 0;
00318 }
00319
00320 api_sleep(100);
00321
00322 len2=recvfrom(sd, (char *)buffer, BUFSIZE, MSG_TIMEOUT, 10000,(struct sockaddr *)&addr,&error);
00323 closesocket(sd,&error);
00324 if (len2<=len1)
00325 {
00326 printf("\r\nError %d receiving data\r\n",error);
00327 return 0;
00328 }
00329
00330 #ifdef MONITOR
00331 packetmonitor(len2, buffer);
00332 #endif
00333 #ifdef TRACE
00334 printf("\r\nReceived %d bytes\r\n",len2);
00335 printf("Header:");
00336 for (i=0; i<12; i++)
00337 printf(" %X",buffer[i]&0xff);
00338 printf("\r\n");
00339 #endif
00340
00341
00342
00343
00344 nRR=buffer[6];
00345 nRR=(nRR<<8)+buffer[7];
00346 #ifdef TRACE
00347 printf("\r\nGot %d answers",nRR);
00348 #endif
00349
00350
00351 i=len1;
00352
00353 k=1;
00354 while(nRR--) {
00355
00356 if((j=dn_unpackrr(&myrr, (char *)buffer,(char *)&buffer[i])) == -1) {
00357 printf("\r\nError in answer section from DNS-server");
00358 return 0;
00359 }
00360 #ifdef TRACE
00361 printf("\r\nA%i: name=%s type=%i class=%i ttl=%lu",k++,myrr.rrname,myrr.rrtype, myrr.rrclass, myrr.rrttl);
00362 if(myrr.rrtype == DN_TYPE_CNAME)
00363 printf(" cname=%s",myrr.rrrdata);
00364 #endif
00365 if(myrr.rrtype == DN_TYPE_A && myrr.rrclass == DN_CLASS_IN) {
00366 k= -1;
00367 break;
00368 }
00369 i+=j;
00370 }
00371 if (k != -1) {
00372 return 0;
00373 }
00374 memcpy((void *)IP,(void *)myrr.rrrdata,4);
00375 *ttl=myrr.rrttl;
00376 InetToAscii(IP,dest);
00377 return 1;
00378 }