/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Copyright 2022 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ │ above copyright notice and this permission notice appear in all copies. │ │ │ │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/str/str.h" #include "net/http/ip.h" /** * Parse IPv4 network address. * * For example, a router address might be `10.10.10.1/24` in which case * the IP address word `0x0a0a0a01` would be returned, whose CIDR would * be 24. That means your IP address is on a network with 24 bits which * converts to a netmask `0xffffff00` by using `1u << (32 - res.cidr)`. * You may specify the IP address portion as an integer. As an example, * the value `168430081/1` would be the same as `10.10.10.1/1` * * @param n if -1 implies strlen * @return ip is uint32 IPv4 address, or -1 on failure * @return cidr is number of bits in network, on interval [1,32]; it * defaults to 32; if the return ip is -1 then cidr is undefined */ struct Cidr ParseCidr(const char *s, size_t n) { size_t i; const char *p; struct Cidr c; if (n == -1) n = s ? strlen(s) : 0; if ((p = strchr(s, '/'))) { if ((c.addr = ParseIp(s, (i = p - s))) != -1) { c.cidr = 0; for (++i; i < n; ++i) { if (isdigit(s[i])) { c.cidr *= 10; c.cidr += s[i] - '0'; if (c.cidr > 32) { c.cidr = -1; break; } } else { c.cidr = -1; break; } } if (c.cidr <= 0) { c.addr = -1; } } } else { c.addr = ParseIp(s, n); c.cidr = 32; } return c; }