WIZNet W5500 with additional enhancements
Fork of WIZnetInterface 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 "eth_arch.h" 00008 00009 #define DBG_DNS 0 00010 00011 #if DBG_DNS 00012 #define DBG2(...) do{debug("[DNS]%p %d %s ", this,__LINE__,__PRETTY_FUNCTION__); debug(__VA_ARGS__); } while(0); 00013 #else 00014 #define DBG2(...) while(0); 00015 #endif 00016 00017 DNSClient::DNSClient(const char* hostname) : m_state(MYNETDNS_START), m_udp(NULL) { 00018 m_hostname = hostname; 00019 } 00020 00021 DNSClient::DNSClient(Endpoint* pHost) : m_state(MYNETDNS_START), m_udp(NULL) { 00022 } 00023 00024 DNSClient::~DNSClient() { 00025 if (m_udp) { 00026 delete m_udp; 00027 } 00028 } 00029 00030 void DNSClient::callback() 00031 { 00032 uint8_t buf[512]; 00033 Endpoint host; 00034 int len = m_udp->receiveFrom(host, (char*)buf, sizeof(buf)); 00035 if (len < 0) { 00036 return; 00037 } 00038 if (memcmp(buf+0, m_id, 2) != 0) { //verify 00039 return; 00040 } 00041 int rcode = response(buf, len); 00042 if (rcode == 0) { 00043 m_state = MYNETDNS_OK; 00044 } else { 00045 m_state = MYNETDNS_NOTFOUND; 00046 } 00047 } 00048 00049 int DNSClient::response(uint8_t buf[], int size) { 00050 int rcode = buf[3] & 0x0f; 00051 if (rcode != 0) { 00052 return rcode; 00053 } 00054 int qdcount = buf[4]<<8|buf[5]; 00055 int ancount = buf[6]<<8|buf[7]; 00056 int pos = 12; 00057 while(qdcount-- > 0) { 00058 dnsname qname(buf); 00059 pos = qname.decode(pos); // qname 00060 pos += 4; // qtype qclass 00061 } 00062 while(ancount-- > 0) { 00063 dnsname name(buf); 00064 pos = name.decode(pos); // name 00065 int type = buf[pos]<<8|buf[pos+1]; 00066 pos += 8; // type class TTL 00067 int rdlength = buf[pos]<<8|buf[pos+1]; pos += 2; 00068 int rdata_pos = pos; 00069 pos += rdlength; 00070 if (type == 1) { // A record 00071 ip = (buf[rdata_pos]<<24) | (buf[rdata_pos+1]<<16) | (buf[rdata_pos+2]<<8) | buf[rdata_pos+3]; 00072 } 00073 #if DBG_DNS 00074 printf("%s", name.str.c_str()); 00075 if (type == 1) { 00076 printf(" A %d.%d.%d.%d\n", 00077 buf[rdata_pos],buf[rdata_pos+1],buf[rdata_pos+2],buf[rdata_pos+3]); 00078 } else if (type == 5) { 00079 dnsname rdname(buf); 00080 rdname.decode(rdata_pos); 00081 printf(" CNAME %s\n", rdname.str.c_str()); 00082 } else { 00083 printf(" TYPE:%d", type); 00084 printfBytes(" RDATA:", &buf[rdata_pos], rdlength); 00085 } 00086 #endif 00087 } 00088 return rcode; 00089 } 00090 00091 int DNSClient::query(uint8_t buf[], int size, const char* hostname) { 00092 const uint8_t header[] = { 00093 0x00,0x00,0x01,0x00, // id=0x0000 QR=0 rd=1 opcode=0 rcode=0 00094 0x00,0x01,0x00,0x00, // qdcount=1 ancount=0 00095 0x00,0x00,0x00,0x00};// nscount=0 arcount=0 00096 const uint8_t tail[] = {0x00,0x01,0x00,0x01}; // qtype=A qclass=IN 00097 memcpy(buf, header, sizeof(header)); 00098 int t = rand(); 00099 m_id[0] = t>>8; 00100 m_id[1] = t; 00101 memcpy(buf, m_id, 2); 00102 dnsname qname(buf); 00103 int pos = qname.encode(sizeof(header), (char*)hostname); 00104 memcpy(buf+pos, tail, sizeof(tail)); 00105 pos += sizeof(tail); 00106 return pos; 00107 } 00108 00109 void DNSClient::resolve(const char* hostname) { 00110 if (m_udp == NULL) { 00111 m_udp = new UDPSocket; 00112 } 00113 m_udp->init(); 00114 m_udp->set_blocking(false); 00115 Endpoint server; 00116 00117 if (m_dnsServer) { 00118 server.set_address(m_dnsServer, 53); // DNS 00119 } else { 00120 server.set_address("8.8.8.8", 53); // DNS 00121 } 00122 m_udp->bind(rand()&0x7fff); 00123 uint8_t buf[256]; 00124 int size = query(buf, sizeof(buf), hostname); 00125 #if DBG_DNS 00126 printf("hostname:[%s]\n", hostname); 00127 printHex(buf, size); 00128 #endif 00129 m_udp->sendTo(server, (char*)buf, size); 00130 m_interval.reset(); 00131 m_interval.start(); 00132 } 00133 00134 void DNSClient::poll() { 00135 #if DBG_DNS 00136 printf("%p m_state: %d, m_udp: %p\n", this, m_state, m_udp); 00137 wait_ms(400); 00138 #endif 00139 switch(m_state) { 00140 case MYNETDNS_START: 00141 m_retry = 0; 00142 resolve(m_hostname); 00143 m_state = MYNETDNS_PROCESSING; 00144 break; 00145 case MYNETDNS_PROCESSING: 00146 break; 00147 case MYNETDNS_NOTFOUND: 00148 break; 00149 case MYNETDNS_ERROR: 00150 break; 00151 case MYNETDNS_OK: 00152 DBG2("m_retry=%d, m_interval=%d\n", m_retry, m_interval.read_ms()); 00153 break; 00154 } 00155 if (m_interval.read_ms() > 1000) { 00156 m_interval.stop(); 00157 DBG2("timeout m_retry=%d\n", m_retry); 00158 if (++m_retry >= 2) { 00159 m_state = MYNETDNS_ERROR; 00160 } else { 00161 resolve(m_hostname); 00162 m_state = MYNETDNS_PROCESSING; 00163 } 00164 } 00165 } 00166 00167 bool DNSClient::lookup(const char* hostname, uint32_t dnsServer) { 00168 m_hostname = hostname; 00169 m_dnsServer = dnsServer; 00170 m_state = MYNETDNS_START; 00171 while(1) { 00172 poll(); 00173 callback(); 00174 if (m_state != MYNETDNS_PROCESSING) { 00175 break; 00176 } 00177 } 00178 return m_state == MYNETDNS_OK; 00179 } 00180
Generated on Tue Jul 12 2022 17:13:34 by 1.7.2