summaryrefslogtreecommitdiff
path: root/sys/src/libip
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2019-02-11 23:26:57 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2019-02-11 23:26:57 +0100
commit0af11f97b582754df36b588e04fd9d9377b50823 (patch)
tree040f31c4fb33a1b11b39fc02a16f14a147097bdd /sys/src/libip
parent66b9196f77442ba8a2cbb1396c7640fd4176c4eb (diff)
libip: replace v4parsecidr() with new parseipandmask()
we want to accept V4 subnets in CIDR notation consistently which means we need to interpret the mask in context of the IP address. so parseipmask() now has an additional v4 flag argument which offsets the prefixlength by 96 so a /24 will be interpreted as a /120. parseipandmask() is the new function which handles this automatically depending on the ip address type. v4parsecidr() is now obsolete.
Diffstat (limited to 'sys/src/libip')
-rw-r--r--sys/src/libip/parseip.c38
-rw-r--r--sys/src/libip/readipifc.c7
2 files changed, 15 insertions, 30 deletions
diff --git a/sys/src/libip/parseip.c b/sys/src/libip/parseip.c
index 9f5d5dac7..757716770 100644
--- a/sys/src/libip/parseip.c
+++ b/sys/src/libip/parseip.c
@@ -122,7 +122,7 @@ parseip(uchar *to, char *from)
* style
*/
vlong
-parseipmask(uchar *to, char *from)
+parseipmask(uchar *to, char *from, int v4)
{
int i, w;
vlong x;
@@ -133,6 +133,8 @@ parseipmask(uchar *to, char *from)
i = atoi(from+1);
if(i < 0)
i = 0;
+ if(i <= 32 && v4)
+ i += 96;
if(i > 128)
i = 128;
w = i;
@@ -141,7 +143,6 @@ parseipmask(uchar *to, char *from)
*p++ = 0xff;
if(i > 0)
*p = ~((1<<(8-i))-1);
- x = nhgetl(to+IPv4off);
/*
* identify as ipv6 if the mask is inexpressible as a v4 mask
* (because it has too few mask bits). Arguably, we could
@@ -149,6 +150,7 @@ parseipmask(uchar *to, char *from)
*/
if (w < 8*(IPaddrlen-IPv4addrlen))
return 6;
+ x = nhgetl(to+IPv4off);
} else {
/* as a straight v4 bit mask */
x = parseip(to, from);
@@ -160,29 +162,15 @@ parseipmask(uchar *to, char *from)
return x;
}
-/*
- * parse a v4 ip address/mask in cidr format
- */
-char*
-v4parsecidr(uchar *addr, uchar *mask, char *from)
+vlong
+parseipandmask(uchar *ip, uchar *mask, char *ipstr, char *maskstr)
{
- int i;
- char *p;
- uchar *a;
-
- p = v4parseip(addr, from);
+ vlong x;
- if(*p == '/'){
- /* as a number of prefix bits */
- i = strtoul(p+1, &p, 0);
- if(i > 32)
- i = 32;
- memset(mask, 0, IPv4addrlen);
- for(a = mask; i >= 8; i -= 8)
- *a++ = 0xff;
- if(i > 0)
- *a = ~((1<<(8-i))-1);
- } else
- memcpy(mask, defmask(addr), IPv4addrlen);
- return p;
+ x = parseip(ip, ipstr);
+ if(x == -1)
+ return -1;
+ if(maskstr == nil || parseipmask(mask, maskstr, memcmp(ip, v4prefix, IPv4off) == 0) == -1)
+ memset(mask, 0xff, IPaddrlen);
+ return x;
}
diff --git a/sys/src/libip/readipifc.c b/sys/src/libip/readipifc.c
index 8169a14eb..70212ef57 100644
--- a/sys/src/libip/readipifc.c
+++ b/sys/src/libip/readipifc.c
@@ -31,9 +31,7 @@ _readoldipifc(char *buf, Ipifc **l, int index)
/* allocate new local address */
*ll = lifc = mallocz(sizeof(Iplifc), 1);
ll = &lifc->next;
-
- parseip(lifc->ip, f[i]);
- parseipmask(lifc->mask, f[i+1]);
+ parseipandmask(lifc->ip, lifc->mask, f[i], f[i+1]);
parseip(lifc->net, f[i+2]);
ifc->pktin = strtoul(f[i+3], nil, 10);
ifc->pktout = strtoul(f[i+4], nil, 10);
@@ -129,8 +127,7 @@ lose:
*ll = lifc = mallocz(sizeof(Iplifc), 1);
ll = &lifc->next;
- parseip(lifc->ip, f[0]);
- parseipmask(lifc->mask, f[1]);
+ parseipandmask(lifc->ip, lifc->mask, f[0], f[1]);
parseip(lifc->net, f[2]);
lifc->validlt = strtoul(f[3], nil, 10);