W5200(WIZ820io) network interface
Embed:
(wiki syntax)
Show/hide line numbers
MyNetDnsRequest.cpp
00001 // MyNetDnsRequest.cpp 2012/4/19 00002 #include "mbed.h" 00003 #include "MyNetDnsRequest.h" 00004 #include "UDPSocket.h" 00005 #include <string> 00006 #include "dnsname.h" 00007 #include "W5200NetIf.h" 00008 //#define __DEBUG 00009 #include "dbg/dbg.h" 00010 00011 #ifdef __DEBUG 00012 #define DBG2(...) do{ DebugStream::debug("%p %d %s ", this,__LINE__,__PRETTY_FUNCTION__); DebugStream::debug(__VA_ARGS__); } while(0); 00013 #else 00014 #define DBG2(...) while(0); 00015 #endif //__DEBUG 00016 00017 //#define DEBUG 00018 00019 #ifdef DEBUG 00020 #include "Utils.h" 00021 #define PRINT_FUNC() printf("%p %d:%s\n", this,__LINE__,__PRETTY_FUNCTION__) 00022 #else //DEBUG 00023 #define PRINT_FUNC() 00024 #endif //DEBUG 00025 00026 00027 MyNetDnsRequest::MyNetDnsRequest(const char* hostname) : NetDnsRequest(hostname), 00028 m_state(MYNETDNS_START), m_cbFired(false), m_closing(false), m_udp(NULL) { 00029 PRINT_FUNC(); 00030 } 00031 00032 MyNetDnsRequest::MyNetDnsRequest(Host* pHost) : NetDnsRequest(pHost), 00033 m_state(MYNETDNS_START), m_cbFired(false), m_closing(false), m_udp(NULL) { 00034 PRINT_FUNC(); 00035 } 00036 00037 MyNetDnsRequest::~MyNetDnsRequest() { 00038 PRINT_FUNC(); 00039 if (m_udp) { 00040 delete m_udp; 00041 } 00042 } 00043 00044 void MyNetDnsRequest::callback(UDPSocketEvent e) 00045 { 00046 PRINT_FUNC(); 00047 DBG2("m_id[]=%02x:%02x\n", m_id[0], m_id[1]); 00048 uint8_t buf[512]; 00049 Host host; 00050 int len = m_udp->recvfrom((char*)buf, sizeof(buf), &host); 00051 if (memcmp(buf+0, m_id, 2) != 0) { //verify 00052 return; 00053 } 00054 int rcode = response(buf, len); 00055 if (rcode == 0) { 00056 m_state = MYNETDNS_OK; 00057 } else { 00058 m_state = MYNETDNS_NOTFOUND; 00059 } 00060 } 00061 00062 int MyNetDnsRequest::response(uint8_t buf[], int size) { 00063 PRINT_FUNC(); 00064 #ifdef DEBUG 00065 printHex(buf, size); 00066 #endif //DEBUG 00067 int rcode = buf[3] & 0x0f; 00068 if (rcode != 0) { 00069 return rcode; 00070 } 00071 int qdcount = buf[4]<<8|buf[5]; 00072 int ancount = buf[6]<<8|buf[7]; 00073 int pos = 12; 00074 while(qdcount-- > 0) { 00075 dnsname qname(buf); 00076 pos = qname.decode(pos); // qname 00077 pos += 4; // qtype qclass 00078 } 00079 while(ancount-- > 0) { 00080 dnsname name(buf); 00081 pos = name.decode(pos); // name 00082 int type = buf[pos]<<8|buf[pos+1]; 00083 pos += 8; // type class TTL 00084 int rdlength = buf[pos]<<8|buf[pos+1]; pos += 2; 00085 int rdata_pos = pos; 00086 pos += rdlength; 00087 if (type == 1) { // A record 00088 m_ip = IpAddr(buf[rdata_pos],buf[rdata_pos+1],buf[rdata_pos+2],buf[rdata_pos+3]); 00089 } 00090 #ifdef DEBUG 00091 printf("%s", name.str.c_str()); 00092 if (type == 1) { 00093 printf(" A %d.%d.%d.%d\n", 00094 buf[rdata_pos],buf[rdata_pos+1],buf[rdata_pos+2],buf[rdata_pos+3]); 00095 } else if (type == 5) { 00096 dnsname rdname(buf); 00097 rdname.decode(rdata_pos); 00098 printf(" CNAME %s\n", rdname.str.c_str()); 00099 } else { 00100 printf(" TYPE:%d", type); 00101 printfBytes(" RDATA:", &buf[rdata_pos], rdlength); 00102 } 00103 #endif //DEBUG 00104 } 00105 return rcode; 00106 } 00107 00108 int MyNetDnsRequest::query(uint8_t buf[], int size, const char* hostname) { 00109 PRINT_FUNC(); 00110 const uint8_t header[] = { 00111 0x00,0x00,0x01,0x00, // id=0x0000 QR=0 rd=1 opcode=0 rcode=0 00112 0x00,0x01,0x00,0x00, // qdcount=1 ancount=0 00113 0x00,0x00,0x00,0x00};// nscount=0 arcount=0 00114 const uint8_t tail[] = {0x00,0x01,0x00,0x01}; // qtype=A qclass=IN 00115 memcpy(buf, header, sizeof(header)); 00116 int t = clock(); 00117 m_id[0] = t>>8; 00118 m_id[1] = t; 00119 memcpy(buf, m_id, 2); 00120 dnsname qname(buf); 00121 int pos = qname.encode(sizeof(header), (char*)hostname); 00122 memcpy(buf+pos, tail, sizeof(tail)); 00123 pos += sizeof(tail); 00124 return pos; 00125 } 00126 00127 void MyNetDnsRequest::resolve(const char* hostname) { 00128 PRINT_FUNC(); 00129 if (m_udp == NULL) { 00130 m_udp = new UDPSocket; 00131 } 00132 m_udp->setOnEvent(this, &MyNetDnsRequest::callback); 00133 Host local(IpAddr(0,0,0,0), 1024 + rand()&0x7fff); 00134 IpAddr dns(8,8,8,8); 00135 NetIf* pIf = Net::getDefaultIf(); 00136 if (pIf) { 00137 dns = ((W5200NetIf*)pIf)->m_dns; 00138 } 00139 Host server(dns, 53); // DNS 00140 m_udp->bind(local); 00141 uint8_t buf[256]; 00142 int size = query(buf, sizeof(buf), hostname); 00143 #ifdef DEBUG 00144 printf("hostname:[%s]\n", hostname); 00145 printHex(buf, size); 00146 #endif 00147 m_udp->sendto((char*)buf, size, &server); 00148 m_interval.reset(); 00149 m_interval.start(); 00150 } 00151 00152 void MyNetDnsRequest::poll() { 00153 PRINT_FUNC(); 00154 #ifdef DEBUG 00155 printf("%p m_state: %d, m_udp: %p\n", this, m_state, m_udp); 00156 wait_ms(400); 00157 #endif //DEBUG 00158 switch(m_state) { 00159 case MYNETDNS_START: 00160 m_retry = 0; 00161 resolve(m_hostname); 00162 m_state = MYNETDNS_PROCESSING; 00163 break; 00164 case MYNETDNS_PROCESSING: 00165 break; 00166 case MYNETDNS_NOTFOUND: 00167 onReply(NETDNS_FOUND); 00168 break; 00169 case MYNETDNS_ERROR: 00170 onReply(NETDNS_ERROR); 00171 break; 00172 case MYNETDNS_OK: 00173 DBG2("m_retry=%d, m_interval=%d\n", m_retry, m_interval.read_ms()); 00174 onReply(NETDNS_FOUND); 00175 break; 00176 } 00177 if (m_interval.read_ms() > 1000) { 00178 m_interval.stop(); 00179 DBG2("timeout m_retry=%d\n", m_retry); 00180 if (++m_retry > 1) { 00181 m_state = MYNETDNS_ERROR; 00182 } else { 00183 resolve(m_hostname); 00184 m_state = MYNETDNS_PROCESSING; 00185 } 00186 } 00187 if(m_closing && (m_state!=MYNETDNS_PROCESSING)) { 00188 NetDnsRequest::close(); 00189 } 00190 } 00191 00192 void MyNetDnsRequest::close() { 00193 PRINT_FUNC(); 00194 if(m_state != MYNETDNS_PROCESSING) { 00195 NetDnsRequest::close(); 00196 } else { 00197 m_closing = true; 00198 } 00199 }
Generated on Tue Jul 12 2022 19:58:52 by 1.7.2