This is the Interface library for WIZnet W5500 chip which forked of EthernetInterfaceW5500, WIZnetInterface and WIZ550ioInterface. This library has simple name as "W5500Interface". and can be used for Wiz550io users also.
Dependents: EvrythngApi Websocket_Ethernet_HelloWorld_W5500 Websocket_Ethernet_W5500 CurrentWeatherData_W5500 ... more
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 #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 server.set_address("8.8.8.8", 53); // DNS 00117 m_udp->bind(rand()&0x7fff); 00118 uint8_t buf[256]; 00119 int size = query(buf, sizeof(buf), hostname); 00120 #if DBG_DNS 00121 printf("hostname:[%s]\n", hostname); 00122 printHex(buf, size); 00123 #endif 00124 m_udp->sendTo(server, (char*)buf, size); 00125 m_interval.reset(); 00126 m_interval.start(); 00127 } 00128 00129 void DNSClient::poll() { 00130 #if DBG_DNS 00131 printf("%p m_state: %d, m_udp: %p\n", this, m_state, m_udp); 00132 wait_ms(400); 00133 #endif 00134 switch(m_state) { 00135 case MYNETDNS_START: 00136 m_retry = 0; 00137 resolve(m_hostname); 00138 m_state = MYNETDNS_PROCESSING; 00139 break; 00140 case MYNETDNS_PROCESSING: 00141 break; 00142 case MYNETDNS_NOTFOUND: 00143 break; 00144 case MYNETDNS_ERROR: 00145 break; 00146 case MYNETDNS_OK: 00147 DBG2("m_retry=%d, m_interval=%d\n", m_retry, m_interval.read_ms()); 00148 break; 00149 } 00150 if (m_interval.read_ms() > 1000) { 00151 m_interval.stop(); 00152 DBG2("timeout m_retry=%d\n", m_retry); 00153 if (++m_retry >= 2) { 00154 m_state = MYNETDNS_ERROR; 00155 } else { 00156 resolve(m_hostname); 00157 m_state = MYNETDNS_PROCESSING; 00158 } 00159 } 00160 } 00161 00162 bool DNSClient::lookup(const char* hostname) { 00163 m_hostname = hostname; 00164 m_state = MYNETDNS_START; 00165 while(1) { 00166 poll(); 00167 callback(); 00168 if (m_state != MYNETDNS_PROCESSING) { 00169 break; 00170 } 00171 } 00172 return m_state == MYNETDNS_OK; 00173 }
Generated on Thu Jul 14 2022 02:02:03 by 1.7.2