return addr;
}
+static bool net_addr2ip_inet4_fast(const char *addr, struct ip_addr *ip)
+{
+ uint8_t *s_addr = (void *)&ip->u.ip4.s_addr;
+ unsigned int i, num;
+
+ if (str_parse_uint(addr, &num, &addr) < 0)
+ return FALSE;
+ if (*addr == '\0' && num <= 0xffffffff) {
+ /* single-number IPv4 address */
+ ip->u.ip4.s_addr = htonl(num);
+ ip->family = AF_INET;
+ return TRUE;
+ }
+
+ /* try to parse as a.b.c.d */
+ i = 0;
+ for (;;) {
+ if (num >= 256)
+ return FALSE;
+ s_addr[i] = num;
+ if (i == 3)
+ break;
+ i++;
+ if (*addr != '.')
+ return FALSE;
+ addr++;
+ if (str_parse_uint(addr, &num, &addr) < 0)
+ return FALSE;
+ }
+ if (*addr != '\0')
+ return FALSE;
+ ip->family = AF_INET;
+ return TRUE;
+}
+
int net_addr2ip(const char *addr, struct ip_addr *ip)
{
int ret;
+ if (net_addr2ip_inet4_fast(addr, ip))
+ return 0;
+
if (strchr(addr, ':') != NULL) {
/* IPv6 */
T_BEGIN {
test_assert(net_addr2ip("127.0.0.1", &ip) == 0 &&
ip.family == AF_INET &&
ntohl(ip.u.ip4.s_addr) == (0x7f000001));
+ test_assert(net_addr2ip("2130706433", &ip) == 0 &&
+ ip.family == AF_INET &&
+ ntohl(ip.u.ip4.s_addr) == (0x7f000001));
+ test_assert(strcmp(net_ip2addr(&ip), "127.0.0.1") == 0);
+ test_assert(net_addr2ip("255.254.253.252", &ip) == 0 &&
+ ip.family == AF_INET &&
+ ntohl(ip.u.ip4.s_addr) == (0xfffefdfc));
+ test_assert(strcmp(net_ip2addr(&ip), "255.254.253.252") == 0);
test_assert(net_addr2ip("::5", &ip) == 0 &&
ip.family == AF_INET6 &&
ip.u.ip6.s6_addr[15] == 5);
+ test_assert(strcmp(net_ip2addr(&ip), "::5") == 0);
test_assert(net_addr2ip("[::5]", &ip) == 0 &&
ip.family == AF_INET6 &&
ip.u.ip6.s6_addr[15] == 5);
+ test_assert(strcmp(net_ip2addr(&ip), "::5") == 0);
ip.family = 123;
test_assert(net_addr2ip("abc", &ip) < 0 &&
ip.family == 123);