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.
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 "ip6string.h" 00022 #include "mbed.h" 00023 00024 00025 static bool ipv4_is_valid(const char *addr) 00026 { 00027 int i = 0; 00028 00029 // Check each digit for [0-9.] 00030 for (; addr[i]; i++) { 00031 if (!(addr[i] >= '0' && addr[i] <= '9') && addr[i] != '.') { 00032 return false; 00033 } 00034 } 00035 00036 // Ending with '.' garuntees host 00037 if (i > 0 && addr[i-1] == '.') { 00038 return false; 00039 } 00040 00041 return true; 00042 } 00043 00044 static bool ipv6_is_valid(const char *addr) 00045 { 00046 // Check each digit for [0-9a-fA-F:] 00047 // Must also have at least 2 colons 00048 int colons = 0; 00049 for (int i = 0; addr[i]; i++) { 00050 if (!(addr[i] >= '0' && addr[i] <= '9') && 00051 !(addr[i] >= 'a' && addr[i] <= 'f') && 00052 !(addr[i] >= 'A' && addr[i] <= 'F') && 00053 addr[i] != ':') { 00054 return false; 00055 } 00056 if (addr[i] == ':') { 00057 colons++; 00058 } 00059 } 00060 00061 return colons >= 2; 00062 } 00063 00064 static void ipv4_from_address(uint8_t *bytes, const char *addr) 00065 { 00066 int count = 0; 00067 int i = 0; 00068 00069 for (; count < NSAPI_IPv4_BYTES; count++) { 00070 unsigned d; 00071 // Not using %hh, since it might be missing in newlib-based toolchains. 00072 // See also: https://git.io/vxiw5 00073 int scanned = sscanf(&addr[i], "%u", &d); 00074 if (scanned < 1) { 00075 return; 00076 } 00077 00078 bytes[count] = static_cast<uint8_t>(d); 00079 00080 for (; addr[i] != '.'; i++) { 00081 if (!addr[i]) { 00082 return; 00083 } 00084 } 00085 00086 i++; 00087 } 00088 } 00089 00090 static void ipv6_from_address(uint8_t *bytes, const char *addr) 00091 { 00092 stoip6(addr, strlen(addr), bytes); 00093 } 00094 00095 static void ipv4_to_address(char *addr, const uint8_t *bytes) 00096 { 00097 sprintf(addr, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]); 00098 } 00099 00100 static void ipv6_to_address(char *addr, const uint8_t *bytes) 00101 { 00102 ip6tos(bytes, addr); 00103 } 00104 00105 00106 SocketAddress::SocketAddress(nsapi_addr_t addr, uint16_t port) 00107 { 00108 _ip_address[0] = '\0'; 00109 set_addr(addr); 00110 set_port(port); 00111 } 00112 00113 SocketAddress::SocketAddress(const char *addr, uint16_t port) 00114 { 00115 _ip_address[0] = '\0'; 00116 set_ip_address(addr); 00117 set_port(port); 00118 } 00119 00120 SocketAddress::SocketAddress(const void *bytes, nsapi_version_t version, uint16_t port) 00121 { 00122 _ip_address[0] = '\0'; 00123 set_ip_bytes(bytes, version); 00124 set_port(port); 00125 } 00126 00127 SocketAddress::SocketAddress(const SocketAddress &addr) 00128 { 00129 _ip_address[0] = '\0'; 00130 set_addr(addr.get_addr()); 00131 set_port(addr.get_port()); 00132 } 00133 00134 bool SocketAddress::set_ip_address(const char *addr) 00135 { 00136 _ip_address[0] = '\0'; 00137 00138 if (addr && ipv4_is_valid(addr)) { 00139 _addr.version = NSAPI_IPv4 ; 00140 ipv4_from_address(_addr.bytes, addr); 00141 return true; 00142 } else if (addr && ipv6_is_valid(addr)) { 00143 _addr.version = NSAPI_IPv6 ; 00144 ipv6_from_address(_addr.bytes, addr); 00145 return true; 00146 } else { 00147 _addr = nsapi_addr_t(); 00148 return false; 00149 } 00150 } 00151 00152 void SocketAddress::set_ip_bytes(const void *bytes, nsapi_version_t version) 00153 { 00154 nsapi_addr_t addr; 00155 00156 addr = nsapi_addr_t(); 00157 addr.version = version; 00158 if (version == NSAPI_IPv6 ) { 00159 memcpy(addr.bytes, bytes, NSAPI_IPv6_BYTES); 00160 } else if (version == NSAPI_IPv4 ) { 00161 memcpy(addr.bytes, bytes, NSAPI_IPv4_BYTES); 00162 } 00163 set_addr(addr); 00164 } 00165 00166 void SocketAddress::set_addr(nsapi_addr_t addr) 00167 { 00168 _ip_address[0] = '\0'; 00169 _addr = addr; 00170 } 00171 00172 void SocketAddress::set_port(uint16_t port) 00173 { 00174 _port = port; 00175 } 00176 00177 const char *SocketAddress::get_ip_address() const 00178 { 00179 if (_addr.version == NSAPI_UNSPEC ) { 00180 return NULL; 00181 } 00182 00183 if (!_ip_address[0]) { 00184 if (_addr.version == NSAPI_IPv4 ) { 00185 ipv4_to_address(_ip_address, _addr.bytes); 00186 } else if (_addr.version == NSAPI_IPv6 ) { 00187 ipv6_to_address(_ip_address, _addr.bytes); 00188 } 00189 } 00190 00191 return _ip_address; 00192 } 00193 00194 const void *SocketAddress::get_ip_bytes() const 00195 { 00196 return _addr.bytes; 00197 } 00198 00199 nsapi_version_t SocketAddress::get_ip_version() const 00200 { 00201 return _addr.version; 00202 } 00203 00204 nsapi_addr_t SocketAddress::get_addr() const 00205 { 00206 return _addr; 00207 } 00208 00209 uint16_t SocketAddress::get_port() const 00210 { 00211 return _port; 00212 } 00213 00214 SocketAddress::operator bool() const 00215 { 00216 if (_addr.version == NSAPI_IPv4 ) { 00217 for (int i = 0; i < NSAPI_IPv4_BYTES; i++) { 00218 if (_addr.bytes[i]) { 00219 return true; 00220 } 00221 } 00222 00223 return false; 00224 } else if (_addr.version == NSAPI_IPv6 ) { 00225 for (int i = 0; i < NSAPI_IPv6_BYTES; i++) { 00226 if (_addr.bytes[i]) { 00227 return true; 00228 } 00229 } 00230 00231 return false; 00232 } else { 00233 return false; 00234 } 00235 } 00236 00237 bool operator==(const SocketAddress &a, const SocketAddress &b) 00238 { 00239 if (!a && !b) { 00240 return true; 00241 } else if (a._addr.version != b._addr.version) { 00242 return false; 00243 } else if (a._addr.version == NSAPI_IPv4 ) { 00244 return memcmp(a._addr.bytes, b._addr.bytes, NSAPI_IPv4_BYTES) == 0; 00245 } else if (a._addr.version == NSAPI_IPv6 ) { 00246 return memcmp(a._addr.bytes, b._addr.bytes, NSAPI_IPv6_BYTES) == 0; 00247 } 00248 00249 MBED_UNREACHABLE; 00250 } 00251 00252 bool operator!=(const SocketAddress &a, const SocketAddress &b) 00253 { 00254 return !(a == b); 00255 } 00256 00257 void SocketAddress::_SocketAddress(NetworkStack *iface, const char *host, uint16_t port) 00258 { 00259 _ip_address[0] = '\0'; 00260 00261 // gethostbyname must check for literals, so can call it directly 00262 int err = iface->gethostbyname(host, this); 00263 _port = port; 00264 if (err) { 00265 _addr = nsapi_addr_t(); 00266 _port = 0; 00267 } 00268 }
Generated on Tue Jul 12 2022 12:45:46 by
1.7.2