zhang chenhong / Mbed 2 deprecated IDW01M1_Cloud_IBM

Dependencies:   mbed Servo X_NUCLEO_IKS01A2 X_NUCLEO_IDW01M1v2 NetworkSocketAPI NDefLib MQTT

Committer:
mridup
Date:
Fri Apr 08 12:07:17 2016 +0000
Revision:
0:cbf8bc43bc9e
changes for optimization in Keil compiler

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mridup 0:cbf8bc43bc9e 1 /* Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
mridup 0:cbf8bc43bc9e 2 *
mridup 0:cbf8bc43bc9e 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
mridup 0:cbf8bc43bc9e 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
mridup 0:cbf8bc43bc9e 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
mridup 0:cbf8bc43bc9e 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
mridup 0:cbf8bc43bc9e 7 * furnished to do so, subject to the following conditions:
mridup 0:cbf8bc43bc9e 8 *
mridup 0:cbf8bc43bc9e 9 * The above copyright notice and this permission notice shall be included in all copies or
mridup 0:cbf8bc43bc9e 10 * substantial portions of the Software.
mridup 0:cbf8bc43bc9e 11 *
mridup 0:cbf8bc43bc9e 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
mridup 0:cbf8bc43bc9e 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
mridup 0:cbf8bc43bc9e 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
mridup 0:cbf8bc43bc9e 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
mridup 0:cbf8bc43bc9e 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
mridup 0:cbf8bc43bc9e 17 */
mridup 0:cbf8bc43bc9e 18 #include "DnsQuery.h"
mridup 0:cbf8bc43bc9e 19 #include <stdio.h>
mridup 0:cbf8bc43bc9e 20 #include <string.h>
mridup 0:cbf8bc43bc9e 21
mridup 0:cbf8bc43bc9e 22
mridup 0:cbf8bc43bc9e 23 #define DNS_COUNT (sizeof DNS_IPS / sizeof DNS_IPS[0])
mridup 0:cbf8bc43bc9e 24 const char *DNS_IPS[] = {
mridup 0:cbf8bc43bc9e 25 "8.8.8.8",
mridup 0:cbf8bc43bc9e 26 "209.244.0.3",
mridup 0:cbf8bc43bc9e 27 "84.200.69.80",
mridup 0:cbf8bc43bc9e 28 "8.26.56.26",
mridup 0:cbf8bc43bc9e 29 "208.67.222.222"
mridup 0:cbf8bc43bc9e 30 };
mridup 0:cbf8bc43bc9e 31
mridup 0:cbf8bc43bc9e 32 static bool isIP(const char *host)
mridup 0:cbf8bc43bc9e 33 {
mridup 0:cbf8bc43bc9e 34 int i;
mridup 0:cbf8bc43bc9e 35
mridup 0:cbf8bc43bc9e 36 for (i = 0; host[i]; i++) {
mridup 0:cbf8bc43bc9e 37 if (!(host[i] >= '0' && host[i] <= '9') && host[i] != '.') {
mridup 0:cbf8bc43bc9e 38 return false;
mridup 0:cbf8bc43bc9e 39 }
mridup 0:cbf8bc43bc9e 40 }
mridup 0:cbf8bc43bc9e 41
mridup 0:cbf8bc43bc9e 42 // Ending with '.' garuntees host
mridup 0:cbf8bc43bc9e 43 if (i > 0 && host[i-1] == '.') {
mridup 0:cbf8bc43bc9e 44 return false;
mridup 0:cbf8bc43bc9e 45 }
mridup 0:cbf8bc43bc9e 46
mridup 0:cbf8bc43bc9e 47 return true;
mridup 0:cbf8bc43bc9e 48 }
mridup 0:cbf8bc43bc9e 49
mridup 0:cbf8bc43bc9e 50
mridup 0:cbf8bc43bc9e 51 static bool parseRR(uint8_t *resp, int &c, char *adr)
mridup 0:cbf8bc43bc9e 52 {
mridup 0:cbf8bc43bc9e 53 int n = 0;
mridup 0:cbf8bc43bc9e 54 while((n=resp[c++]) != 0) {
mridup 0:cbf8bc43bc9e 55 if ((n & 0xc0) != 0) {
mridup 0:cbf8bc43bc9e 56 // This is a link
mridup 0:cbf8bc43bc9e 57 c++;
mridup 0:cbf8bc43bc9e 58 break;
mridup 0:cbf8bc43bc9e 59 } else {
mridup 0:cbf8bc43bc9e 60 // skip this segment, not interested in string domain names
mridup 0:cbf8bc43bc9e 61 c+= n;
mridup 0:cbf8bc43bc9e 62 }
mridup 0:cbf8bc43bc9e 63 }
mridup 0:cbf8bc43bc9e 64
mridup 0:cbf8bc43bc9e 65 int TYPE = (((int)resp[c])<<8) + resp[c+1];
mridup 0:cbf8bc43bc9e 66 int CLASS = (((int)resp[c+2])<<8) + resp[c+3];
mridup 0:cbf8bc43bc9e 67 int RDLENGTH = (((int)resp[c+8])<<8) + resp[c+9];
mridup 0:cbf8bc43bc9e 68
mridup 0:cbf8bc43bc9e 69 c+= 10;
mridup 0:cbf8bc43bc9e 70 if ((CLASS == 1) && (TYPE == 1)) {
mridup 0:cbf8bc43bc9e 71 sprintf(adr,"%d.%d.%d.%d", resp[c], resp[c+1], resp[c+2], resp[c+3]);
mridup 0:cbf8bc43bc9e 72 c+= RDLENGTH;
mridup 0:cbf8bc43bc9e 73 return true;
mridup 0:cbf8bc43bc9e 74 }
mridup 0:cbf8bc43bc9e 75 c+= RDLENGTH;
mridup 0:cbf8bc43bc9e 76
mridup 0:cbf8bc43bc9e 77 return false;
mridup 0:cbf8bc43bc9e 78 }
mridup 0:cbf8bc43bc9e 79
mridup 0:cbf8bc43bc9e 80
mridup 0:cbf8bc43bc9e 81 static bool resolve(unsigned char *resp, char *ipaddress)
mridup 0:cbf8bc43bc9e 82 {
mridup 0:cbf8bc43bc9e 83
mridup 0:cbf8bc43bc9e 84 int ID = (((int)resp[0]) <<8) + resp[1];
mridup 0:cbf8bc43bc9e 85 int QR = resp[2] >>7;
mridup 0:cbf8bc43bc9e 86 int Opcode = (resp[2]>>3) & 0x0F;
mridup 0:cbf8bc43bc9e 87 int RCODE = (resp[3] & 0x0F);
mridup 0:cbf8bc43bc9e 88 int ANCOUNT = (((int)resp[6])<<8)+ resp[7];
mridup 0:cbf8bc43bc9e 89
mridup 0:cbf8bc43bc9e 90 if ((ID != 1) || (QR != 1) || (Opcode != 0) || (RCODE != 0)) {
mridup 0:cbf8bc43bc9e 91 return false;
mridup 0:cbf8bc43bc9e 92 }
mridup 0:cbf8bc43bc9e 93
mridup 0:cbf8bc43bc9e 94 int c = 12;
mridup 0:cbf8bc43bc9e 95 int d;
mridup 0:cbf8bc43bc9e 96 // Skip domain question
mridup 0:cbf8bc43bc9e 97 while( (d=resp[c++]) != 0) {
mridup 0:cbf8bc43bc9e 98 c+=d;
mridup 0:cbf8bc43bc9e 99 }
mridup 0:cbf8bc43bc9e 100 c+= 4; // skip QTYPE and QCLASS
mridup 0:cbf8bc43bc9e 101
mridup 0:cbf8bc43bc9e 102 // Here comes the resource record
mridup 0:cbf8bc43bc9e 103 for (int ans = 0 ; ans < ANCOUNT; ans++) {
mridup 0:cbf8bc43bc9e 104 if (parseRR(resp, c, ipaddress)) {
mridup 0:cbf8bc43bc9e 105 return true;
mridup 0:cbf8bc43bc9e 106 }
mridup 0:cbf8bc43bc9e 107 }
mridup 0:cbf8bc43bc9e 108
mridup 0:cbf8bc43bc9e 109 return false;
mridup 0:cbf8bc43bc9e 110 }
mridup 0:cbf8bc43bc9e 111
mridup 0:cbf8bc43bc9e 112
mridup 0:cbf8bc43bc9e 113 int32_t dnsQuery(NetworkInterface *iface, const char *host, char *ip)
mridup 0:cbf8bc43bc9e 114 {
mridup 0:cbf8bc43bc9e 115 if (isIP(host)) {
mridup 0:cbf8bc43bc9e 116 strcpy(ip, host);
mridup 0:cbf8bc43bc9e 117 return 0;
mridup 0:cbf8bc43bc9e 118 }
mridup 0:cbf8bc43bc9e 119
mridup 0:cbf8bc43bc9e 120 UDPSocket sock(iface);
mridup 0:cbf8bc43bc9e 121 int32_t err;
mridup 0:cbf8bc43bc9e 122
mridup 0:cbf8bc43bc9e 123 for (unsigned i = 0; i < DNS_COUNT; i++) {
mridup 0:cbf8bc43bc9e 124 err = sock.open(DNS_IPS[0], 53);
mridup 0:cbf8bc43bc9e 125 if (err < 0) {
mridup 0:cbf8bc43bc9e 126 return err;
mridup 0:cbf8bc43bc9e 127 }
mridup 0:cbf8bc43bc9e 128
mridup 0:cbf8bc43bc9e 129 err = dnsQuery(&sock, host, ip);
mridup 0:cbf8bc43bc9e 130 sock.close();
mridup 0:cbf8bc43bc9e 131 return err;
mridup 0:cbf8bc43bc9e 132 }
mridup 0:cbf8bc43bc9e 133
mridup 0:cbf8bc43bc9e 134 sock.close();
mridup 0:cbf8bc43bc9e 135 return NS_ERROR_DNS_FAILURE;
mridup 0:cbf8bc43bc9e 136 }
mridup 0:cbf8bc43bc9e 137
mridup 0:cbf8bc43bc9e 138 int32_t dnsQuery(UDPSocket *socket, const char *hostname, char *ipaddress)
mridup 0:cbf8bc43bc9e 139 {
mridup 0:cbf8bc43bc9e 140 int len = 0;
mridup 0:cbf8bc43bc9e 141 if (hostname == NULL) {
mridup 0:cbf8bc43bc9e 142 return false;
mridup 0:cbf8bc43bc9e 143 }
mridup 0:cbf8bc43bc9e 144 len = strlen(hostname);
mridup 0:cbf8bc43bc9e 145 if ((len > 128) || (len == 0)) {
mridup 0:cbf8bc43bc9e 146 return false;
mridup 0:cbf8bc43bc9e 147 }
mridup 0:cbf8bc43bc9e 148
mridup 0:cbf8bc43bc9e 149 int packetlen = /* size of HEADER structure */ 12 + /* size of QUESTION Structure */5 + len + 1;
mridup 0:cbf8bc43bc9e 150 uint8_t *packet = new uint8_t[packetlen]; /* this is the UDP packet to send to the DNS */
mridup 0:cbf8bc43bc9e 151 if (packet == NULL) {
mridup 0:cbf8bc43bc9e 152 return false;
mridup 0:cbf8bc43bc9e 153 }
mridup 0:cbf8bc43bc9e 154
mridup 0:cbf8bc43bc9e 155 // Fill the header
mridup 0:cbf8bc43bc9e 156 memset(packet, 0, packetlen);
mridup 0:cbf8bc43bc9e 157 packet[1] = 1; // ID = 1
mridup 0:cbf8bc43bc9e 158 packet[5] = 1; // QDCOUNT = 1 (contains one question)
mridup 0:cbf8bc43bc9e 159 packet[2] = 1; // recursion requested
mridup 0:cbf8bc43bc9e 160
mridup 0:cbf8bc43bc9e 161 int c = 13; // point to NAME element in question section or request
mridup 0:cbf8bc43bc9e 162 int cnt = 12; // points to the counter of
mridup 0:cbf8bc43bc9e 163 packet[cnt] = 0;
mridup 0:cbf8bc43bc9e 164 for (int i = 0 ; i < len ; i++) {
mridup 0:cbf8bc43bc9e 165 if (hostname[i] != '.') {
mridup 0:cbf8bc43bc9e 166 // Copy the character and increment the character counter
mridup 0:cbf8bc43bc9e 167 packet[cnt]++;
mridup 0:cbf8bc43bc9e 168 packet[c++] = hostname[i];
mridup 0:cbf8bc43bc9e 169 } else {
mridup 0:cbf8bc43bc9e 170 // Finished with this part, so go to the next
mridup 0:cbf8bc43bc9e 171 cnt = c++;
mridup 0:cbf8bc43bc9e 172 packet[cnt] = 0;
mridup 0:cbf8bc43bc9e 173 }
mridup 0:cbf8bc43bc9e 174 }
mridup 0:cbf8bc43bc9e 175
mridup 0:cbf8bc43bc9e 176 // Terminate this domain name with a zero entry
mridup 0:cbf8bc43bc9e 177 packet[c++] = 0;
mridup 0:cbf8bc43bc9e 178
mridup 0:cbf8bc43bc9e 179 // Set QTYPE
mridup 0:cbf8bc43bc9e 180 packet[c++] = 0;
mridup 0:cbf8bc43bc9e 181 packet[c++] = 1;
mridup 0:cbf8bc43bc9e 182 // Set QCLASS
mridup 0:cbf8bc43bc9e 183 packet[c++] = 0;
mridup 0:cbf8bc43bc9e 184 packet[c++] = 1;
mridup 0:cbf8bc43bc9e 185
mridup 0:cbf8bc43bc9e 186
mridup 0:cbf8bc43bc9e 187 if (socket->send(packet, packetlen) < 0) {
mridup 0:cbf8bc43bc9e 188 delete packet;
mridup 0:cbf8bc43bc9e 189 return false;
mridup 0:cbf8bc43bc9e 190 }
mridup 0:cbf8bc43bc9e 191 delete packet;
mridup 0:cbf8bc43bc9e 192
mridup 0:cbf8bc43bc9e 193 packet = new uint8_t [1024];
mridup 0:cbf8bc43bc9e 194
mridup 0:cbf8bc43bc9e 195 // Receive the answer from DNS
mridup 0:cbf8bc43bc9e 196 int response_length = 0;
mridup 0:cbf8bc43bc9e 197 response_length = socket->recv(packet, 1024);
mridup 0:cbf8bc43bc9e 198
mridup 0:cbf8bc43bc9e 199 if (response_length > 0 ) {
mridup 0:cbf8bc43bc9e 200 if (!resolve(packet, ipaddress)) {
mridup 0:cbf8bc43bc9e 201 delete packet;
mridup 0:cbf8bc43bc9e 202 return NS_ERROR_DNS_FAILURE;
mridup 0:cbf8bc43bc9e 203 }
mridup 0:cbf8bc43bc9e 204
mridup 0:cbf8bc43bc9e 205 // cleanup and return
mridup 0:cbf8bc43bc9e 206 delete packet;
mridup 0:cbf8bc43bc9e 207 return 0;
mridup 0:cbf8bc43bc9e 208 }
mridup 0:cbf8bc43bc9e 209
mridup 0:cbf8bc43bc9e 210 delete packet;
mridup 0:cbf8bc43bc9e 211 return NS_ERROR_DNS_FAILURE;
mridup 0:cbf8bc43bc9e 212 }
mridup 0:cbf8bc43bc9e 213
mridup 0:cbf8bc43bc9e 214