W5500 driver for mbed OS 5
Dependents: http-webserver-example mbed-os-example-sockets
Fork of W5500Interface by
DNSClient.cpp
00001 // DNSClient.cpp 2013/8/27 00002 #include "mbed.h" 00003 #include "mbed_debug.h" 00004 #include "DNSClient.h" 00005 #include "UDPSocket.h" 00006 #include "dnsname.h" 00007 #include "wiznet.h" 00008 00009 #if DBG_DNS 00010 #define DBG2(...) do{debug("[DNS]%p %d %s ", this,__LINE__,__PRETTY_FUNCTION__); debug(__VA_ARGS__); } while(0); 00011 #else 00012 #define DBG2(...) while(0); 00013 #endif 00014 00015 static SocketAddress theDnsServer; 00016 00017 DNSClient::DNSClient() : m_state(MYNETDNS_START), m_udp(NULL) { 00018 m_ns = NULL; 00019 00020 //default to google 00021 theDnsServer.set_ip_address("8.8.8.8"); // DNS 00022 theDnsServer.set_port(53); // DNS 00023 } 00024 00025 DNSClient::DNSClient(NetworkStack *ns, const char* hostname) : m_state(MYNETDNS_START), m_udp(NULL) { 00026 m_hostname = hostname; 00027 m_ns = ns; 00028 00029 //default to google 00030 theDnsServer.set_ip_address("8.8.8.8"); // DNS 00031 theDnsServer.set_port(53); // DNS 00032 } 00033 00034 DNSClient::DNSClient(NetworkStack *ns, SocketAddress* pHost) : m_state(MYNETDNS_START), m_udp(NULL) { 00035 m_ns = ns; 00036 00037 //default to google 00038 theDnsServer.set_ip_address("8.8.8.8"); // DNS 00039 theDnsServer.set_port(53); // DNS 00040 } 00041 00042 DNSClient::~DNSClient() { 00043 if (m_udp) { 00044 delete m_udp; 00045 } 00046 } 00047 00048 int DNSClient::setup(NetworkStack *ns) { 00049 m_ns = ns; 00050 return 0; 00051 } 00052 00053 bool DNSClient::set_server(const char* serverip, int port) { 00054 theDnsServer.set_ip_address(serverip); 00055 theDnsServer.set_port(port); 00056 return true; 00057 } 00058 00059 void DNSClient::callback() 00060 { 00061 uint8_t buf[512]; 00062 SocketAddress host; 00063 int len = m_udp->recvfrom(&host, (char*)buf, sizeof(buf)); 00064 if (len < 0) { 00065 return; 00066 } 00067 if (memcmp(buf+0, m_id, 2) != 0) { //verify 00068 return; 00069 } 00070 00071 int rcode = response(buf, len); 00072 if (rcode == 0) { 00073 m_state = MYNETDNS_OK; 00074 } else { 00075 m_state = MYNETDNS_NOTFOUND; 00076 } 00077 } 00078 00079 int DNSClient::response(uint8_t buf[], int size) { 00080 int rcode = buf[3] & 0x0f; 00081 if (rcode != 0) { 00082 return rcode; 00083 } 00084 int qdcount = buf[4]<<8|buf[5]; 00085 int ancount = buf[6]<<8|buf[7]; 00086 int pos = 12; 00087 while(qdcount-- > 0) { 00088 dnsname qname(buf); 00089 pos = qname.decode(pos); // qname 00090 pos += 4; // qtype qclass 00091 } 00092 while(ancount-- > 0) { 00093 dnsname name(buf); 00094 pos = name.decode(pos); // name 00095 int type = buf[pos]<<8|buf[pos+1]; 00096 pos += 8; // type class TTL 00097 int rdlength = buf[pos]<<8|buf[pos+1]; pos += 2; 00098 int rdata_pos = pos; 00099 pos += rdlength; 00100 if (type == 1) { // A record 00101 m_ip = (buf[rdata_pos]<<24) | (buf[rdata_pos+1]<<16) | (buf[rdata_pos+2]<<8) | buf[rdata_pos+3]; 00102 sprintf(m_ipaddr, "%d.%d.%d.%d", buf[rdata_pos],buf[rdata_pos+1],buf[rdata_pos+2],buf[rdata_pos+3]); 00103 } 00104 #if DBG_DNS 00105 printf("%s", name.str.c_str()); 00106 if (type == 1) { 00107 printf(" A %d.%d.%d.%d\n", 00108 buf[rdata_pos],buf[rdata_pos+1],buf[rdata_pos+2],buf[rdata_pos+3]); 00109 } else if (type == 5) { 00110 dnsname rdname(buf); 00111 rdname.decode(rdata_pos); 00112 printf(" CNAME %s\n", rdname.str.c_str()); 00113 } else { 00114 printf(" TYPE:%d", type); 00115 printfBytes(" RDATA:", &buf[rdata_pos], rdlength); 00116 } 00117 #endif 00118 } 00119 return rcode; 00120 } 00121 00122 int DNSClient::query(uint8_t buf[], int size, const char* hostname) { 00123 const uint8_t header[] = { 00124 0x00,0x00,0x01,0x00, // id=0x0000 QR=0 rd=1 opcode=0 rcode=0 00125 0x00,0x01,0x00,0x00, // qdcount=1 ancount=0 00126 0x00,0x00,0x00,0x00};// nscount=0 arcount=0 00127 const uint8_t tail[] = {0x00,0x01,0x00,0x01}; // qtype=A qclass=IN 00128 memcpy(buf, header, sizeof(header)); 00129 int t = rand(); 00130 m_id[0] = t>>8; 00131 m_id[1] = t; 00132 memcpy(buf, m_id, 2); 00133 dnsname qname(buf); 00134 int pos = qname.encode(sizeof(header), (char*)hostname); 00135 memcpy(buf+pos, tail, sizeof(tail)); 00136 pos += sizeof(tail); 00137 return pos; 00138 } 00139 00140 void DNSClient::resolve(const char* hostname) { 00141 if (m_udp == NULL) { 00142 m_udp = new UDPSocket; 00143 m_udp->open(m_ns); 00144 } 00145 m_udp->set_blocking(false); 00146 m_udp->bind(rand()&0x7fff); 00147 uint8_t buf[256]; 00148 int size = query(buf, sizeof(buf), hostname); 00149 #if DBG_DNS 00150 printf("hostname:[%s]\n", hostname); 00151 printHex(buf, size); 00152 #endif 00153 m_udp->sendto(theDnsServer, (char*)buf, size); 00154 m_interval.reset(); 00155 m_interval.start(); 00156 } 00157 00158 void DNSClient::poll() { 00159 #if DBG_DNS 00160 printf("%p m_state: %d, m_udp: %p\n", this, m_state, m_udp); 00161 wait_ms(400); 00162 #endif 00163 switch(m_state) { 00164 case MYNETDNS_START: 00165 m_retry = 0; 00166 resolve(m_hostname); 00167 m_state = MYNETDNS_PROCESSING; 00168 break; 00169 case MYNETDNS_PROCESSING: 00170 break; 00171 case MYNETDNS_NOTFOUND: 00172 break; 00173 case MYNETDNS_ERROR: 00174 break; 00175 case MYNETDNS_OK: 00176 DBG2("m_retry=%d, m_interval=%d\n", m_retry, m_interval.read_ms()); 00177 break; 00178 } 00179 if (m_interval.read_ms() > 1000) { 00180 m_interval.stop(); 00181 DBG2("timeout m_retry=%d\n", m_retry); 00182 if (++m_retry >= 2) { 00183 m_state = MYNETDNS_ERROR; 00184 } else { 00185 resolve(m_hostname); 00186 m_state = MYNETDNS_PROCESSING; 00187 } 00188 } 00189 } 00190 00191 //tests for a valid IP address, returns 0 if invalid IP address format, returns ip address if valid 00192 static uint32_t 00193 isValidIP(const char* ip) { 00194 int i1, i2, i3, i4; 00195 int len = strlen(ip); 00196 00197 if (len < 7) return 0; 00198 00199 //count the number of dots, there must be 3 00200 int dotcount = 0; 00201 for (int i = 0; i < len; i++) { 00202 if (ip[i] == '.' ) dotcount++; 00203 } 00204 00205 //there must be exactly 3 dots 00206 if (dotcount != 3) return 0; 00207 00208 sscanf((char*)ip, "%d.%d.%d.%d", &i1, &i2, &i3, &i4); 00209 00210 if (strlen(ip) <= 16 && (i1 >= 0 && i1 <= 255) && (i2 >= 0 && i2 <= 255) && 00211 (i3 >= 0 && i3 <= 255) && (i4 >= 0 && i4 <= 255)) { 00212 return ((i1<<24) | (i2<<16) | (i3<<8) | i4); 00213 } 00214 return 0; 00215 } 00216 00217 bool DNSClient::lookup(const char* hostname) { 00218 m_hostname = hostname; 00219 00220 uint32_t ip = isValidIP(hostname); 00221 00222 //check if hostname is an IP address 00223 if (ip > 0) { 00224 //if it is already an IP address just return immediately 00225 m_ip = ip; 00226 strcpy(m_ipaddr, hostname); 00227 m_state = MYNETDNS_OK; 00228 return true; 00229 } 00230 00231 m_state = MYNETDNS_START; 00232 while(1) { 00233 poll(); 00234 callback(); 00235 if (m_state != MYNETDNS_PROCESSING) { 00236 break; 00237 } 00238 } 00239 00240 if (m_udp) { 00241 delete m_udp; 00242 m_udp = NULL; 00243 } 00244 return m_state == MYNETDNS_OK; 00245 }
Generated on Tue Jul 12 2022 18:48:25 by 1.7.2