summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/nds/dswifi/arm9/source/sgIP_DNS.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/arm/nds/dswifi/arm9/source/sgIP_DNS.c')
-rw-r--r--c/src/lib/libbsp/arm/nds/dswifi/arm9/source/sgIP_DNS.c492
1 files changed, 0 insertions, 492 deletions
diff --git a/c/src/lib/libbsp/arm/nds/dswifi/arm9/source/sgIP_DNS.c b/c/src/lib/libbsp/arm/nds/dswifi/arm9/source/sgIP_DNS.c
deleted file mode 100644
index 432236b205..0000000000
--- a/c/src/lib/libbsp/arm/nds/dswifi/arm9/source/sgIP_DNS.c
+++ /dev/null
@@ -1,492 +0,0 @@
-// DSWifi Project - sgIP Internet Protocol Stack Implementation
-// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
-/******************************************************************************
-DSWifi Lib and test materials are licenced under the MIT open source licence:
-Copyright (c) 2005-2006 Stephen Stair
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-******************************************************************************/
-
-#include "sgIP_DNS.h"
-#include "sgIP_Hub.h"
-#include "netinet/in.h"
-#include "sys/socket.h"
-
-int dns_sock;
-int time_count;
-int last_id;
-int query_time_start;
-extern unsigned long volatile sgIP_timems;
-
-// cache record data
-sgIP_DNS_Record dnsrecords[SGIP_DNS_MAXRECORDSCACHE];
-
-// data to return via hostent
-volatile sgIP_DNS_Record dnsrecord_return;
-volatile char * alias_list[SGIP_DNS_MAXALIASES+1];
-volatile char * addr_list[SGIP_DNS_MAXRECORDADDRS+1];
-char ipaddr_alias[256];
-unsigned long ipaddr_ip;
-volatile sgIP_DNS_Hostent dnsrecord_hostent;
-
-unsigned char querydata[512];
-unsigned char responsedata[512];
-
-void sgIP_DNS_Init() {
- int i;
- for(i=0;i<SGIP_DNS_MAXRECORDSCACHE;i++) dnsrecords[i].flags=0;
- dns_sock=-1;
- time_count=0;
-}
-
-void sgIP_DNS_Timer1000ms() {
- int i;
- time_count++;
- for(i=0;i<SGIP_DNS_MAXRECORDSCACHE;i++) {
- if(dnsrecords[i].flags & SGIP_DNS_FLAG_RESOLVED) {
- dnsrecords[i].TTL-=1;
- if(dnsrecords[i].TTL<=0) {
- dnsrecords[i].flags=0;
- }
- }
- }
-}
-
-int sgIP_DNS_isipaddress(const char * name, unsigned long * ipdest) {
- int i,j,t,ndot;
- unsigned long out_addr, g[4];
- const char * c;
-
- ndot=0;
- c=name;
- while(*c) { // scan for invalid characters
- if(!((*c>='0' && *c<='9') || (*c>='A' && *c<='F') || (*c>='a' && *c<='f') || *c=='.' || *c=='x' || *c=='X')) return 0;
- if(*c=='.') ndot++;
- c++;
- }
- if(ndot>3) return 0;
- c=name;
- for(i=0;i<=ndot;i++) {
- g[i]=0;
- t=0;
- j=0;
- while(*c && *c!='.') {
- if(j==0 && *c=='0') { t++; }
- else if(j==1 && t==1 && (*c=='x' || *c=='X')) { t++; }
- else {
- switch(t) {
- case 0: // decimal
- if(*c=='x' || *c=='X' || (*c>='A' && *c<='F') || (*c>='a' && *c<='f')) return 0;
- g[i]=(g[i]*10)+(*c-'0');
- break;
- case 1: // octal
- if(*c=='x' || *c=='X' || (*c>='A' && *c<='F') || (*c>='a' && *c<='f') || *c=='8' || *c=='9') return 0;
- g[i]=(g[i]<<3)+(*c-'0');
- break;
- case 2: // hex
- if(*c=='x' || *c=='X') return 0;
- if(*c>='0' && *c<='9') {
- g[i]=(g[i]<<4)+(*c-'0');
- } else {
- g[i]=(g[i]<<4)+(*c&0xDF)+9;
- }
- break;
- }
- }
- j++; c++;
- }
- if(*c) c++; else break;
- }
- out_addr=0;
- switch(ndot) {
- case 0:
- out_addr=g[0];
- break;
- case 1:
- if(g[0]>=0x100 || g[1]>=0x1000000) return 0;
- out_addr= (g[0]<<24) | g[1];
- break;
- case 2:
- if(g[0]>=0x100 || g[1]>=0x100 || g[2]>=0x10000) return 0;
- out_addr= (g[0]<<24) | (g[1]<<16) | g[2];
- break;
- case 3:
- if(g[0]>=0x100 || g[1]>=0x100 || g[2]>=0x100 || g[3]>=0x100) return 0;
- out_addr= (g[0]<<24) | (g[1]<<16) | (g[2]<<8) | g[3];
- break;
- }
- *ipdest=htonl(out_addr);
- return 1;
-}
-
-sgIP_DNS_Record * sgIP_DNS_FindDNSRecord(const char * name) {
- int i,j,k,n,c,c2;
- SGIP_INTR_PROTECT();
- for(i=0;i<SGIP_DNS_MAXRECORDSCACHE;i++) {
- if((dnsrecords[i].flags&(SGIP_DNS_FLAG_ACTIVE|SGIP_DNS_FLAG_RESOLVED)) == (SGIP_DNS_FLAG_ACTIVE|SGIP_DNS_FLAG_RESOLVED)) {
- for(j=0;j<dnsrecords[i].numalias;j++) {
- k=0;
- for(n=0;name[n] && dnsrecords[i].aliases[j][n]; n++) { // obscure and complex case-insensitive string compare.
- c=name[n];
- c2=dnsrecords[i].aliases[j][n];
- if(c>='a' && c<='z') c+='A'-'a';
- if(c2>='a' && c2<='z') c2+='A'-'a';
- if(c==c2) {
- k++;
- } else {
- k=0; break;
- }
- }
- if(name[n] || dnsrecords[i].aliases[j][n]) k=0;
- if(k) {
- SGIP_INTR_UNPROTECT();
- return dnsrecords+i;
- }
- }
- }
- }
-
- SGIP_INTR_UNPROTECT();
- return 0;
-}
-
-sgIP_DNS_Record * sgIP_DNS_GetUnusedRecord() {
- int i,j,minttl;
- SGIP_INTR_PROTECT();
- for(i=0;i<SGIP_DNS_MAXRECORDSCACHE;i++) {
- if(!(dnsrecords[i].flags&SGIP_DNS_FLAG_ACTIVE)) {
- SGIP_INTR_UNPROTECT();
- return dnsrecords+i;
- }
- }
- minttl=dnsrecords[0].TTL; j=0;
- for(i=1;i<SGIP_DNS_MAXRECORDSCACHE;i++) {
- if(dnsrecords[i].TTL<minttl && !(dnsrecords[i].flags&SGIP_DNS_FLAG_BUSY)) {
- j=i;
- minttl=dnsrecords[i].TTL;
- }
- }
- dnsrecords[j].flags=0;
- SGIP_INTR_UNPROTECT();
- return dnsrecords+j;
-}
-
-static
-void sgIP_ntoa(unsigned long ipaddr) {
- int c,i,j,n;
- c=0;
- for(j=0;j<4;j++) {
- if(j) ipaddr_alias[c++]='.';
- n=(ipaddr>>(j*8))&255;
- i=0;
- if(n>=100) { i=n/100; ipaddr_alias[c++]='0'+i; n-=i*100; }
- if(n>=10 || i) { i=n/10; ipaddr_alias[c++]='0'+i; n-=i*10; }
- ipaddr_alias[c++]='0'+n;
- }
- ipaddr_alias[c]=0;
-}
-
-static
-sgIP_DNS_Hostent * sgIP_DNS_GenerateHostentIP(unsigned long ipaddr) {
-
- sgIP_ntoa(ipaddr);
-
- alias_list[0]=ipaddr_alias;
- alias_list[1]=0;
- ipaddr_ip=ipaddr;
- addr_list[0]=(char *)&ipaddr_ip;
- addr_list[1]=0;
-
- dnsrecord_hostent.h_addr_list=(char **)addr_list;
- dnsrecord_hostent.h_addrtype=1;
- dnsrecord_hostent.h_aliases=(char **)alias_list;
- dnsrecord_hostent.h_length=4;
- dnsrecord_hostent.h_name=ipaddr_alias;
- return (sgIP_DNS_Hostent *)&dnsrecord_hostent;
-}
-
-sgIP_DNS_Hostent * sgIP_DNS_GenerateHostent(sgIP_DNS_Record * dnsrec) {
- volatile int i;
- dnsrecord_return = *dnsrec; // copy struct
- for(i=0;i<dnsrecord_return.numalias;i++) {
- alias_list[i]=dnsrecord_return.aliases[i];
- }
- alias_list[i]=0;
- for(i=0;i<dnsrecord_return.numaddr;i++) {
- addr_list[i]=(char *)&(dnsrecord_return.addrdata[i*dnsrecord_return.addrlen]);
- }
- addr_list[i]=0;
- dnsrecord_hostent.h_addr_list=(char **)addr_list;
- dnsrecord_hostent.h_addrtype=dnsrecord_return.addrclass;
- dnsrecord_hostent.h_aliases=(char **)alias_list;
- dnsrecord_hostent.h_length=dnsrecord_return.addrlen;
- dnsrecord_hostent.h_name=(char *)dnsrecord_return.name;
- return (sgIP_DNS_Hostent *)&dnsrecord_hostent;
-}
-
-static
-int sgIP_DNS_genquery(const char * name) {
- int i,j,c,l;
- unsigned short * querydata_s = (unsigned short *) querydata;
- unsigned char * querydata_c = querydata;
- // header section
- querydata_s[0]=htons(time_count&0xFFFF);
- last_id=querydata_s[0];
- querydata_s[1]=htons(0x0100); // recursion desired, standard query
- querydata_s[2]=htons(1); // one QD (question)
- querydata_s[3]=0; // no resource records
- querydata_s[4]=0; // no nameserver records
- querydata_s[5]=0; // no additional records
- // question section
-
- querydata_c+=12;
- querydata_s+=6;
- j=0;
- i=0;
- while(1) {
- l=j;
- j++;
- c=0;
- while(name[i]!=0 && name[i]!='.' && i<255) {
- querydata_c[j++]=name[i++]; c++;
- }
- querydata_c[l]=c;
- if(name[i]==0 || i>=255) break;
- if(c==0) return 0; // this should never happen (unless there's really invalid input with 2 dots next to each other.)
- i++;
- }
- querydata_c[j++]=0; // terminating zero length
- // qtype
- querydata_c[j++]=0;
- querydata_c[j++]=1; // 00 01 "A" (address)
- // qclass
- querydata_c[j++]=0;
- querydata_c[j++]=1; // 00 01 "IN" (internet)
-
- return j+12; // length
-}
-
-void sgIP_DNS_CopyAliasAt(char * deststr,int offset) {
- char * c;
- int i,j;
- i=0;
- c=(char *)responsedata+offset;
- do {
- j=c[0];
- if(j>63) {
- j=((j&63)<<8) | c[1];
- c=(char *)responsedata+j;
- continue;
- }
- if(!j) break;
- c++;
- for(;j>0;j--) {
- deststr[i++]= *(c++);
- }
- deststr[i++]='.';
- } while(1);
- if(i>0) i--;
- deststr[i]=0;
-}
-
-
-sgIP_DNS_Hostent * sgIP_DNS_gethostbyname(const char * name) {
- sgIP_DNS_Record * rec;
- sgIP_DNS_Hostent * he;
- sgIP_Hub_HWInterface * hw;
- int len,i,sainlen;
- int retries,dtime;
- unsigned long serverip;
- struct sockaddr_in sain;
- unsigned long IP;
- SGIP_INTR_PROTECT();
-
- // is name an IP address?
- if(sgIP_DNS_isipaddress(name,&IP)) {
- SGIP_INTR_UNPROTECT();
- return sgIP_DNS_GenerateHostentIP(IP);
- }
-
- // check cache, return if value required is in cache...
- rec=sgIP_DNS_FindDNSRecord(name);
- if(rec) {
- he=sgIP_DNS_GenerateHostent(rec);
- SGIP_INTR_UNPROTECT();
- return he;
- }
-
- // not in cache? generate a query...
- len=sgIP_DNS_genquery(name);
-
- // send off the query, handle retransmit and trying other dns servers.
- if(dns_sock==-1) {
- hw=sgIP_Hub_GetDefaultInterface();
- serverip=hw->dns[0];
-
- dns_sock=socket(AF_INET,SOCK_DGRAM,0);
- i=1;
- i=ioctl(dns_sock,FIONBIO,&i); // set non-blocking
-
- retries=0;
- do {
- query_time_start=sgIP_timems;
- sain.sin_addr.s_addr=serverip;
- sain.sin_port=htons(53);
- i=sendto(dns_sock,querydata,len,0,(struct sockaddr *)&sain,sizeof(sain));
-dns_listenonly:
-
- do {
- i=recvfrom(dns_sock,responsedata,512,0,(struct sockaddr *)&sain,&sainlen);
- if(i!=-1) break;
- dtime=sgIP_timems-query_time_start;
- if(dtime>SGIP_DNS_TIMEOUTMS) break;
- SGIP_INTR_UNPROTECT();
- SGIP_WAITEVENT();
- SGIP_INTR_REPROTECT();
- } while(1);
-
- if(i==-1) { // no reply, retry
- retries++;
- if(retries>=SGIP_DNS_MAXRETRY) { // maybe try another server? for now just quit.
- closesocket(dns_sock);
- dns_sock=-1;
- SGIP_INTR_UNPROTECT();
-
- return NULL;
- }
- continue; // send again
- }
-
- // got something, is it what we want?
- if(i<12 || sain.sin_addr.s_addr!=serverip || sain.sin_port!=htons(53)) { // suspicious.
- goto dns_listenonly; // yay! a goto! - go back and see if we can get a more official response.
- }
-
- // parse response.
- {
- const unsigned short * resdata_s = (unsigned short *) responsedata;
- const unsigned char * resdata_c = responsedata;
- const char * c;
- int j,q,a, nalias,naddr;
- if(last_id!=resdata_s[0]) { // bad.
- goto dns_listenonly;
- }
- q=htons(resdata_s[2]);
- a=htons(resdata_s[3]);
- // no answer.
- if (a == 0)
- {
- closesocket(dns_sock);
- dns_sock=-1;
- SGIP_INTR_UNPROTECT();
-
- return NULL;
- }
-
- resdata_c+=12;
- while(q) { // ignore questions
- do {
- j=resdata_c[0];
- if(j>63) { resdata_c+=2; break; }
- resdata_c += j+1;
- } while(j);
- resdata_c+=4;
- q--;
- }
-
- nalias=0;
- naddr=0;
- rec=sgIP_DNS_GetUnusedRecord();
- rec->flags=SGIP_DNS_FLAG_ACTIVE | SGIP_DNS_FLAG_BUSY;
- while(a) {
- if(nalias<SGIP_DNS_MAXALIASES) sgIP_DNS_CopyAliasAt(rec->aliases[nalias++],resdata_c-responsedata);
- do {
- j=resdata_c[0];
- if(j>63) { resdata_c+=2; break; }
- resdata_c += j+1;
- } while(j);
- // CNAME=5, A=1
- j=resdata_c[1];
- rec->addrclass=(resdata_c[2]<<8)|resdata_c[3];
- rec->TTL = (resdata_c[4]<<24)|(resdata_c[5]<<16)|(resdata_c[6]<<8)|resdata_c[7];
- if(j==1) { // A
- if(naddr<SGIP_DNS_MAXRECORDADDRS) {
- rec->addrdata[naddr*4] = resdata_c[10];
- rec->addrdata[naddr*4+1] = resdata_c[11];
- rec->addrdata[naddr*4+2] = resdata_c[12];
- rec->addrdata[naddr*4+3] = resdata_c[13];
- naddr++;
- }
- }
- j=(resdata_c[8]<<8)|resdata_c[9];
- resdata_c+=10+j;
- a--;
- }
-
- // likely we have all the data we care for now.
- rec->addrlen=4;
- rec->numaddr=naddr;
- rec->numalias=nalias;
- for(c=name,i=0;*c;c++,i++) rec->name[i]=*c;
- rec->name[i]=0;
- rec->flags=SGIP_DNS_FLAG_ACTIVE | SGIP_DNS_FLAG_RESOLVED;
- break; // we got our answer, let's get out of here!
- }
- } while(1);
-
- closesocket(dns_sock);
- dns_sock=-1;
- } else {
- SGIP_INTR_UNPROTECT();
- return NULL;
- }
-
- // received response, return data
- he=sgIP_DNS_GenerateHostent(rec);
- SGIP_INTR_UNPROTECT();
- return he;
-}
-
-unsigned long inet_addr(const char *cp) {
- unsigned long IP;
- if(sgIP_DNS_isipaddress(cp,&IP)) {
- return IP;
- }
- return 0xFFFFFFFF;
-}
-
-int inet_aton(const char *cp, struct in_addr *inp) {
- unsigned long IP;
-
- if(sgIP_DNS_isipaddress(cp,&IP)) {
- inp->s_addr = IP;
- return 1;
- }
-
- return 0;
-}
-
-
-char *inet_ntoa(struct in_addr in) {
- sgIP_ntoa(in.s_addr);
- return (char *)ipaddr_alias;
-}
-
-
-