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.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo by
SocketAddress.cpp
00001 /* Socket 00002 * Copyright (c) 2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "SocketAddress.h" 00018 #include "NetworkInterface.h" 00019 #include "NetworkStack.h" 00020 #include <string.h> 00021 #include "mbed.h" 00022 00023 00024 static bool ipv4_is_valid(const char *addr) 00025 { 00026 int i = 0; 00027 00028 // Check each digit for [0-9.] 00029 for (; addr[i]; i++) { 00030 if (!(addr[i] >= '0' && addr[i] <= '9') && addr[i] != '.') { 00031 return false; 00032 } 00033 } 00034 00035 // Ending with '.' garuntees host 00036 if (i > 0 && addr[i-1] == '.') { 00037 return false; 00038 } 00039 00040 return true; 00041 } 00042 00043 static bool ipv6_is_valid(const char *addr) 00044 { 00045 // Check each digit for [0-9a-fA-F:] 00046 for (int i = 0; addr[i]; i++) { 00047 if (!(addr[i] >= '0' && addr[i] <= '9') && 00048 !(addr[i] >= 'a' && addr[i] <= 'f') && 00049 !(addr[i] >= 'A' && addr[i] <= 'F') && 00050 addr[i] != ':') { 00051 return false; 00052 } 00053 } 00054 00055 return true; 00056 } 00057 00058 static void ipv4_from_address(uint8_t *bytes, const char *addr) 00059 { 00060 int count = 0; 00061 int i = 0; 00062 00063 for (; count < NSAPI_IPv4_BYTES; count++) { 00064 int scanned = sscanf(&addr[i], "%hhu", &bytes[count]); 00065 if (scanned < 1) { 00066 return; 00067 } 00068 00069 for (; addr[i] != '.'; i++) { 00070 if (!addr[i]) { 00071 return; 00072 } 00073 } 00074 00075 i++; 00076 } 00077 } 00078 00079 static int ipv6_scan_chunk(uint16_t *shorts, const char *chunk) { 00080 int count = 0; 00081 int i = 0; 00082 00083 for (; count < NSAPI_IPv6_BYTES/2; count++) { 00084 int scanned = sscanf(&chunk[i], "%hx", &shorts[count]); 00085 if (scanned < 1) { 00086 return count; 00087 } 00088 00089 for (; chunk[i] != ':'; i++) { 00090 if (!chunk[i]) { 00091 return count+1; 00092 } 00093 } 00094 00095 i++; 00096 } 00097 00098 return count; 00099 } 00100 00101 static void ipv6_from_address(uint8_t *bytes, const char *addr) 00102 { 00103 // Start with zeroed address 00104 uint16_t shorts[NSAPI_IPv6_BYTES/2]; 00105 memset(shorts, 0, sizeof shorts); 00106 00107 int suffix = 0; 00108 00109 // Find double colons and scan suffix 00110 for (int i = 0; addr[i]; i++) { 00111 if (addr[i] == ':' && addr[i+1] == ':') { 00112 suffix = ipv6_scan_chunk(shorts, &addr[i+2]); 00113 break; 00114 } 00115 } 00116 00117 // Move suffix to end 00118 memmove(&shorts[NSAPI_IPv6_BYTES/2-suffix], &shorts[0], 00119 suffix*sizeof(uint16_t)); 00120 00121 // Scan prefix 00122 ipv6_scan_chunk(shorts, &addr[0]); 00123 00124 // Flip bytes 00125 for (int i = 0; i < NSAPI_IPv6_BYTES/2; i++) { 00126 bytes[2*i+0] = (uint8_t)(shorts[i] >> 8); 00127 bytes[2*i+1] = (uint8_t)(shorts[i] >> 0); 00128 } 00129 } 00130 00131 static void ipv4_to_address(char *addr, const uint8_t *bytes) 00132 { 00133 sprintf(addr, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]); 00134 } 00135 00136 static void ipv6_to_address(char *addr, const uint8_t *bytes) 00137 { 00138 for (int i = 0; i < NSAPI_IPv6_BYTES/2; i++) { 00139 sprintf(&addr[5*i], "%02x%02x", bytes[2*i], bytes[2*i+1]); 00140 addr[5*i+4] = ':'; 00141 } 00142 addr[NSAPI_IPv6_SIZE-1] = '\0'; 00143 } 00144 00145 00146 SocketAddress::SocketAddress(nsapi_addr_t addr, uint16_t port) 00147 { 00148 _ip_address[0] = '\0'; 00149 set_addr(addr); 00150 set_port(port); 00151 } 00152 00153 SocketAddress::SocketAddress(const char *addr, uint16_t port) 00154 { 00155 _ip_address[0] = '\0'; 00156 set_ip_address(addr); 00157 set_port(port); 00158 } 00159 00160 SocketAddress::SocketAddress(const void *bytes, nsapi_version_t version, uint16_t port) 00161 { 00162 _ip_address[0] = '\0'; 00163 set_ip_bytes(bytes, version); 00164 set_port(port); 00165 } 00166 00167 SocketAddress::SocketAddress(const SocketAddress &addr) 00168 { 00169 _ip_address[0] = '\0'; 00170 set_addr(addr.get_addr()); 00171 set_port(addr.get_port()); 00172 } 00173 00174 void SocketAddress::set_ip_address(const char *addr) 00175 { 00176 _ip_address[0] = '\0'; 00177 00178 if (addr && ipv4_is_valid(addr)) { 00179 _addr.version = NSAPI_IPv4; 00180 ipv4_from_address(_addr.bytes, addr); 00181 } else if (addr && ipv6_is_valid(addr)) { 00182 _addr.version = NSAPI_IPv6; 00183 ipv6_from_address(_addr.bytes, addr); 00184 } else { 00185 _addr = nsapi_addr_t(); 00186 } 00187 } 00188 00189 void SocketAddress::set_ip_bytes(const void *bytes, nsapi_version_t version) 00190 { 00191 nsapi_addr_t addr; 00192 addr.version = version; 00193 memcpy(addr.bytes, bytes, NSAPI_IP_BYTES); 00194 set_addr(addr); 00195 } 00196 00197 void SocketAddress::set_addr(nsapi_addr_t addr) 00198 { 00199 _ip_address[0] = '\0'; 00200 _addr = addr; 00201 } 00202 00203 void SocketAddress::set_port(uint16_t port) 00204 { 00205 _port = port; 00206 } 00207 00208 const char *SocketAddress::get_ip_address() const 00209 { 00210 char *ip_address = (char *)_ip_address; 00211 00212 if (!ip_address[0]) { 00213 if (_addr.version == NSAPI_IPv4) { 00214 ipv4_to_address(ip_address, _addr.bytes); 00215 } else if (_addr.version == NSAPI_IPv6) { 00216 ipv6_to_address(ip_address, _addr.bytes); 00217 } 00218 } 00219 00220 return ip_address; 00221 } 00222 00223 const void *SocketAddress::get_ip_bytes() const 00224 { 00225 return _addr.bytes; 00226 } 00227 00228 nsapi_version_t SocketAddress::get_ip_version() const 00229 { 00230 return _addr.version; 00231 } 00232 00233 nsapi_addr_t SocketAddress::get_addr() const 00234 { 00235 return _addr; 00236 } 00237 00238 uint16_t SocketAddress::get_port() const 00239 { 00240 return _port; 00241 } 00242 00243 SocketAddress::operator bool() const 00244 { 00245 int count = 0; 00246 if (_addr.version == NSAPI_IPv4) { 00247 count = NSAPI_IPv4_BYTES; 00248 } else if (_addr.version == NSAPI_IPv6) { 00249 count = NSAPI_IPv6_BYTES; 00250 } 00251 00252 for (int i = 0; i < count; i++) { 00253 if (_addr.bytes[i]) { 00254 return true; 00255 } 00256 } 00257 00258 return false; 00259 } 00260 00261 void SocketAddress::_SocketAddress(NetworkStack *iface, const char *host, uint16_t port) 00262 { 00263 _ip_address[0] = '\0'; 00264 00265 // Check for valid IP addresses 00266 if (host && ipv4_is_valid(host)) { 00267 _addr.version = NSAPI_IPv4; 00268 ipv4_from_address(_addr.bytes, host); 00269 _port = port; 00270 } else if (host && ipv6_is_valid(host)) { 00271 _addr.version = NSAPI_IPv6; 00272 ipv6_from_address(_addr.bytes, host); 00273 _port = port; 00274 } else { 00275 // DNS lookup 00276 int err = iface->gethostbyname(this, host); 00277 _port = port; 00278 if (err) { 00279 _addr = nsapi_addr_t(); 00280 _port = 0; 00281 } 00282 } 00283 }
Generated on Tue Jul 12 2022 12:28:49 by
1.7.2
