Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
