176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @file 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This is the IPv4 address tools implementation. 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * All rights reserved. 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Redistribution and use in source and binary forms, with or without modification, 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * are permitted provided that the following conditions are met: 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1. Redistributions of source code must retain the above copyright notice, 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * this list of conditions and the following disclaimer. 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 2. Redistributions in binary form must reproduce the above copyright notice, 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * this list of conditions and the following disclaimer in the documentation 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * and/or other materials provided with the distribution. 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 3. The name of the author may not be used to endorse or promote products 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * derived from this software without specific prior written permission. 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * OF SUCH DAMAGE. 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This file is part of the lwIP TCP/IP stack. 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Author: Adam Dunkels <adam@sics.se> 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lwip/opt.h" 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lwip/ip_addr.h" 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lwip/netif.h" 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */ 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanconst ip_addr_t ip_addr_any = { IPADDR_ANY }; 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanconst ip_addr_t ip_addr_broadcast = { IPADDR_BROADCAST }; 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Determine if an address is a broadcast address on a network interface 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @param addr address to be checked 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @param netif the network interface against which the address is checked 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @return returns non-zero if the address is a broadcast address 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanu8_t 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanip4_addr_isbroadcast(u32_t addr, const struct netif *netif) 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ip_addr_t ipaddr; 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ip4_addr_set_u32(&ipaddr, addr); 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* all ones (broadcast) or all zeroes (old skool broadcast) */ 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((~addr == IPADDR_ANY) || 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (addr == IPADDR_ANY)) { 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* no broadcast support on this network interface? */ 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* the given address cannot be a broadcast address 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * nor can we check against any broadcast addresses */ 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* address matches network interface address exactly? => no broadcast */ 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if (addr == ip4_addr_get_u32(&netif->ip_addr)) { 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* on the same (sub) network... */ 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if (ip_addr_netcmp(&ipaddr, &(netif->ip_addr), &(netif->netmask)) 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* ...and host identifier bits are all ones? =>... */ 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman && ((addr & ~ip4_addr_get_u32(&netif->netmask)) == 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask)))) { 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* => network broadcast address */ 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Checks if a netmask is valid (starting with ones, then only zeros) 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @param netmask the IPv4 netmask to check (in network byte order!) 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @return 1 if the netmask is valid, 0 if it is not 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanu8_t 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanip4_addr_netmask_valid(u32_t netmask) 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t mask; 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t nm_hostorder = lwip_htonl(netmask); 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* first, check for the first zero */ 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (mask = 1UL << 31 ; mask != 0; mask >>= 1) { 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((nm_hostorder & mask) == 0) { 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* then check that there is no one */ 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (; mask != 0; mask >>= 1) { 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((nm_hostorder & mask) != 0) { 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* there is a one after the first zero -> invalid */ 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* no one after the first zero -> valid */ 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Here for now until needed in other places in lwIP */ 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef isprint 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define isprint(c) in_range(c, 0x20, 0x7f) 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define isdigit(c) in_range(c, '0', '9') 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define islower(c) in_range(c, 'a', 'z') 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Ascii internet address interpretation routine. 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The value returned is in network order. 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @param cp IP address in ascii represenation (e.g. "127.0.0.1") 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @return ip address in network order 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanu32_t 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipaddr_addr(const char *cp) 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ip_addr_t val; 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ipaddr_aton(cp, &val)) { 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ip4_addr_get_u32(&val); 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (IPADDR_NONE); 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Check whether "cp" is a valid ascii representation 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * of an Internet address and convert to a binary address. 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Returns 1 if the address is valid, 0 if not. 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This replaces inet_addr, the return value from which 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * cannot distinguish between failure and a local broadcast address. 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @param cp IP address in ascii represenation (e.g. "127.0.0.1") 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @param addr pointer to which to save the ip address in network order 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @return 1 if cp could be converted to addr, 0 on failure 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipaddr_aton(const char *cp, ip_addr_t *addr) 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t val; 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u8_t base; 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char c; 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t parts[4]; 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t *pp = parts; 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman c = *cp; 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (;;) { 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Collect number up to ``.''. 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Values are specified as for C: 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 0x=hex, 0=octal, 1-9=decimal. 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!isdigit(c)) 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (0); 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman val = 0; 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman base = 10; 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (c == '0') { 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman c = *++cp; 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (c == 'x' || c == 'X') { 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman base = 16; 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman c = *++cp; 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman base = 8; 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (;;) { 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (isdigit(c)) { 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman val = (val * base) + (int)(c - '0'); 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman c = *++cp; 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if (base == 16 && isxdigit(c)) { 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A')); 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman c = *++cp; 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (c == '.') { 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Internet format: 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * a.b.c.d 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * a.b.c (with c treated as 16 bits) 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * a.b (with b treated as 24 bits) 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (pp >= parts + 3) { 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (0); 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *pp++ = val; 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman c = *++cp; 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Check for trailing characters. 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (c != '\0' && !isspace(c)) { 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (0); 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Concoct the address according to 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * the number of parts specified. 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman switch (pp - parts + 1) { 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 0: 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (0); /* initial nondigit */ 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 1: /* a -- 32 bits */ 22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 2: /* a.b -- 8.24 bits */ 22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (val > 0xffffffUL) { 22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (0); 22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman val |= parts[0] << 24; 22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 3: /* a.b.c -- 8.8.16 bits */ 23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (val > 0xffff) { 23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (0); 23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman val |= (parts[0] << 24) | (parts[1] << 16); 23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 4: /* a.b.c.d -- 8.8.8.8 bits */ 23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (val > 0xff) { 23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (0); 23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); 24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman default: 24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LWIP_ASSERT("unhandled", 0); 24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (addr) { 24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ip4_addr_set_u32(addr, htonl(val)); 24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (1); 25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Convert numeric IP address into decimal dotted ASCII representation. 25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * returns ptr to static buffer; not reentrant! 25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @param addr ip address in network order to convert 25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @return pointer to a global static (!) buffer that holds the ASCII 25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * represenation of addr 25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanchar * 26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanipaddr_ntoa(const ip_addr_t *addr) 26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman static char str[16]; 26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ipaddr_ntoa_r(addr, str, 16); 26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. 26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @param addr ip address in network order to convert 27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @param buf target buffer where the string is stored 27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @param buflen length of buf 27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @return either pointer to buf which now holds the ASCII 27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * representation of addr or NULL if buf was too small 27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanchar *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen) 27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32_t s_addr; 27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char inv[3]; 28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char *rp; 28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u8_t *ap; 28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u8_t rem; 28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u8_t n; 28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u8_t i; 28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int len = 0; 28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s_addr = ip4_addr_get_u32(addr); 28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rp = buf; 29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ap = (u8_t *)&s_addr; 29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for(n = 0; n < 4; n++) { 29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman i = 0; 29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman do { 29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rem = *ap % (u8_t)10; 29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *ap /= (u8_t)10; 29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman inv[i++] = '0' + rem; 29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } while(*ap); 29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while(i--) { 29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (len++ >= buflen) { 30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return NULL; 30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *rp++ = inv[i]; 30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (len++ >= buflen) { 30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return NULL; 30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *rp++ = '.'; 30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ap++; 30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *--rp = 0; 31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return buf; 31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 313