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.
Fork of OmniWheels by
lwip_ip4_addr.c
00001 /** 00002 * @file 00003 * This is the IPv4 address tools implementation. 00004 * 00005 */ 00006 00007 /* 00008 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00009 * All rights reserved. 00010 * 00011 * Redistribution and use in source and binary forms, with or without modification, 00012 * are permitted provided that the following conditions are met: 00013 * 00014 * 1. Redistributions of source code must retain the above copyright notice, 00015 * this list of conditions and the following disclaimer. 00016 * 2. Redistributions in binary form must reproduce the above copyright notice, 00017 * this list of conditions and the following disclaimer in the documentation 00018 * and/or other materials provided with the distribution. 00019 * 3. The name of the author may not be used to endorse or promote products 00020 * derived from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00023 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00024 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00025 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00026 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00027 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00028 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00029 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00030 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00031 * OF SUCH DAMAGE. 00032 * 00033 * This file is part of the lwIP TCP/IP stack. 00034 * 00035 * Author: Adam Dunkels <adam@sics.se> 00036 * 00037 */ 00038 00039 #include "lwip/opt.h" 00040 00041 #if LWIP_IPV4 00042 00043 #include "lwip/ip_addr.h" 00044 #include "lwip/netif.h" 00045 00046 /* used by IP4_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */ 00047 const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY); 00048 const ip_addr_t ip_addr_broadcast = IPADDR4_INIT(IPADDR_BROADCAST); 00049 00050 /** 00051 * Determine if an address is a broadcast address on a network interface 00052 * 00053 * @param addr address to be checked 00054 * @param netif the network interface against which the address is checked 00055 * @return returns non-zero if the address is a broadcast address 00056 */ 00057 u8_t 00058 ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif) 00059 { 00060 ip4_addr_t ipaddr; 00061 ip4_addr_set_u32(&ipaddr, addr); 00062 00063 /* all ones (broadcast) or all zeroes (old skool broadcast) */ 00064 if ((~addr == IPADDR_ANY) || 00065 (addr == IPADDR_ANY)) { 00066 return 1; 00067 /* no broadcast support on this network interface? */ 00068 } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { 00069 /* the given address cannot be a broadcast address 00070 * nor can we check against any broadcast addresses */ 00071 return 0; 00072 /* address matches network interface address exactly? => no broadcast */ 00073 } else if (addr == ip4_addr_get_u32(netif_ip4_addr(netif))) { 00074 return 0; 00075 /* on the same (sub) network... */ 00076 } else if (ip4_addr_netcmp(&ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) 00077 /* ...and host identifier bits are all ones? =>... */ 00078 && ((addr & ~ip4_addr_get_u32(netif_ip4_netmask(netif))) == 00079 (IPADDR_BROADCAST & ~ip4_addr_get_u32(netif_ip4_netmask(netif))))) { 00080 /* => network broadcast address */ 00081 return 1; 00082 } else { 00083 return 0; 00084 } 00085 } 00086 00087 /** Checks if a netmask is valid (starting with ones, then only zeros) 00088 * 00089 * @param netmask the IPv4 netmask to check (in network byte order!) 00090 * @return 1 if the netmask is valid, 0 if it is not 00091 */ 00092 u8_t 00093 ip4_addr_netmask_valid(u32_t netmask) 00094 { 00095 u32_t mask; 00096 u32_t nm_hostorder = lwip_htonl(netmask); 00097 00098 /* first, check for the first zero */ 00099 for (mask = 1UL << 31 ; mask != 0; mask >>= 1) { 00100 if ((nm_hostorder & mask) == 0) { 00101 break; 00102 } 00103 } 00104 /* then check that there is no one */ 00105 for (; mask != 0; mask >>= 1) { 00106 if ((nm_hostorder & mask) != 0) { 00107 /* there is a one after the first zero -> invalid */ 00108 return 0; 00109 } 00110 } 00111 /* no one after the first zero -> valid */ 00112 return 1; 00113 } 00114 00115 /* Here for now until needed in other places in lwIP */ 00116 #ifndef isprint 00117 #define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) 00118 #define isprint(c) in_range(c, 0x20, 0x7f) 00119 #define isdigit(c) in_range(c, '0', '9') 00120 #define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) 00121 #define islower(c) in_range(c, 'a', 'z') 00122 #define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') 00123 #endif 00124 00125 /** 00126 * Ascii internet address interpretation routine. 00127 * The value returned is in network order. 00128 * 00129 * @param cp IP address in ascii representation (e.g. "127.0.0.1") 00130 * @return ip address in network order 00131 */ 00132 u32_t 00133 ipaddr_addr(const char *cp) 00134 { 00135 ip4_addr_t val; 00136 00137 if (ip4addr_aton(cp, &val)) { 00138 return ip4_addr_get_u32(&val); 00139 } 00140 return (IPADDR_NONE); 00141 } 00142 00143 /** 00144 * Check whether "cp" is a valid ascii representation 00145 * of an Internet address and convert to a binary address. 00146 * Returns 1 if the address is valid, 0 if not. 00147 * This replaces inet_addr, the return value from which 00148 * cannot distinguish between failure and a local broadcast address. 00149 * 00150 * @param cp IP address in ascii representation (e.g. "127.0.0.1") 00151 * @param addr pointer to which to save the ip address in network order 00152 * @return 1 if cp could be converted to addr, 0 on failure 00153 */ 00154 int 00155 ip4addr_aton(const char *cp, ip4_addr_t *addr) 00156 { 00157 u32_t val; 00158 u8_t base; 00159 char c; 00160 u32_t parts[4]; 00161 u32_t *pp = parts; 00162 00163 c = *cp; 00164 for (;;) { 00165 /* 00166 * Collect number up to ``.''. 00167 * Values are specified as for C: 00168 * 0x=hex, 0=octal, 1-9=decimal. 00169 */ 00170 if (!isdigit(c)) { 00171 return 0; 00172 } 00173 val = 0; 00174 base = 10; 00175 if (c == '0') { 00176 c = *++cp; 00177 if (c == 'x' || c == 'X') { 00178 base = 16; 00179 c = *++cp; 00180 } else { 00181 base = 8; 00182 } 00183 } 00184 for (;;) { 00185 if (isdigit(c)) { 00186 val = (val * base) + (u32_t)(c - '0'); 00187 c = *++cp; 00188 } else if (base == 16 && isxdigit(c)) { 00189 val = (val << 4) | (u32_t)(c + 10 - (islower(c) ? 'a' : 'A')); 00190 c = *++cp; 00191 } else { 00192 break; 00193 } 00194 } 00195 if (c == '.') { 00196 /* 00197 * Internet format: 00198 * a.b.c.d 00199 * a.b.c (with c treated as 16 bits) 00200 * a.b (with b treated as 24 bits) 00201 */ 00202 if (pp >= parts + 3) { 00203 return 0; 00204 } 00205 *pp++ = val; 00206 c = *++cp; 00207 } else { 00208 break; 00209 } 00210 } 00211 /* 00212 * Check for trailing characters. 00213 */ 00214 if (c != '\0' && !isspace(c)) { 00215 return 0; 00216 } 00217 /* 00218 * Concoct the address according to 00219 * the number of parts specified. 00220 */ 00221 switch (pp - parts + 1) { 00222 00223 case 0: 00224 return 0; /* initial nondigit */ 00225 00226 case 1: /* a -- 32 bits */ 00227 break; 00228 00229 case 2: /* a.b -- 8.24 bits */ 00230 if (val > 0xffffffUL) { 00231 return 0; 00232 } 00233 if (parts[0] > 0xff) { 00234 return 0; 00235 } 00236 val |= parts[0] << 24; 00237 break; 00238 00239 case 3: /* a.b.c -- 8.8.16 bits */ 00240 if (val > 0xffff) { 00241 return 0; 00242 } 00243 if ((parts[0] > 0xff) || (parts[1] > 0xff)) { 00244 return 0; 00245 } 00246 val |= (parts[0] << 24) | (parts[1] << 16); 00247 break; 00248 00249 case 4: /* a.b.c.d -- 8.8.8.8 bits */ 00250 if (val > 0xff) { 00251 return 0; 00252 } 00253 if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) { 00254 return 0; 00255 } 00256 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); 00257 break; 00258 default: 00259 LWIP_ASSERT("unhandled", 0); 00260 break; 00261 } 00262 if (addr) { 00263 ip4_addr_set_u32(addr, lwip_htonl(val)); 00264 } 00265 return 1; 00266 } 00267 00268 /** 00269 * Convert numeric IP address into decimal dotted ASCII representation. 00270 * returns ptr to static buffer; not reentrant! 00271 * 00272 * @param addr ip address in network order to convert 00273 * @return pointer to a global static (!) buffer that holds the ASCII 00274 * representation of addr 00275 */ 00276 char* 00277 ip4addr_ntoa(const ip4_addr_t *addr) 00278 { 00279 static char str[IP4ADDR_STRLEN_MAX]; 00280 return ip4addr_ntoa_r(addr, str, IP4ADDR_STRLEN_MAX); 00281 } 00282 00283 /** 00284 * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. 00285 * 00286 * @param addr ip address in network order to convert 00287 * @param buf target buffer where the string is stored 00288 * @param buflen length of buf 00289 * @return either pointer to buf which now holds the ASCII 00290 * representation of addr or NULL if buf was too small 00291 */ 00292 char* 00293 ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen) 00294 { 00295 u32_t s_addr; 00296 char inv[3]; 00297 char *rp; 00298 u8_t *ap; 00299 u8_t rem; 00300 u8_t n; 00301 u8_t i; 00302 int len = 0; 00303 00304 s_addr = ip4_addr_get_u32(addr); 00305 00306 rp = buf; 00307 ap = (u8_t *)&s_addr; 00308 for (n = 0; n < 4; n++) { 00309 i = 0; 00310 do { 00311 rem = *ap % (u8_t)10; 00312 *ap /= (u8_t)10; 00313 inv[i++] = (char)('0' + rem); 00314 } while (*ap); 00315 while (i--) { 00316 if (len++ >= buflen) { 00317 return NULL; 00318 } 00319 *rp++ = inv[i]; 00320 } 00321 if (len++ >= buflen) { 00322 return NULL; 00323 } 00324 *rp++ = '.'; 00325 ap++; 00326 } 00327 *--rp = 0; 00328 return buf; 00329 } 00330 00331 #endif /* LWIP_IPV4 */
Generated on Fri Jul 22 2022 04:53:52 by
1.7.2
