diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-02-11 23:26:57 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-02-11 23:26:57 +0100 |
commit | 0af11f97b582754df36b588e04fd9d9377b50823 (patch) | |
tree | 040f31c4fb33a1b11b39fc02a16f14a147097bdd /sys/src/libip | |
parent | 66b9196f77442ba8a2cbb1396c7640fd4176c4eb (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.c | 38 | ||||
-rw-r--r-- | sys/src/libip/readipifc.c | 7 |
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); |