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 | |
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.
-rw-r--r-- | sys/include/ip.h | 4 | ||||
-rw-r--r-- | sys/man/2/ip | 47 | ||||
-rw-r--r-- | sys/src/libip/parseip.c | 38 | ||||
-rw-r--r-- | sys/src/libip/readipifc.c | 7 |
4 files changed, 48 insertions, 48 deletions
diff --git a/sys/include/ip.h b/sys/include/ip.h index 56e707729..c2ab8dcf8 100644 --- a/sys/include/ip.h +++ b/sys/include/ip.h @@ -161,9 +161,9 @@ void maskip(uchar*, uchar*, uchar*); int eipfmt(Fmt*); int isv4(uchar*); vlong parseip(uchar*, char*); -vlong parseipmask(uchar*, char*); +vlong parseipmask(uchar*, char*, int); +vlong parseipandmask(uchar*, uchar*, char*, char*); char* v4parseip(uchar*, char*); -char* v4parsecidr(uchar*, uchar*, char*); int parseether(uchar*, char*); int myipaddr(uchar*, char*); int myetheraddr(uchar*, char*); diff --git a/sys/man/2/ip b/sys/man/2/ip index e84b14c08..d2fcab0dd 100644 --- a/sys/man/2/ip +++ b/sys/man/2/ip @@ -1,6 +1,6 @@ .TH IP 2 .SH NAME -eipfmt, parseip, parseipmask, v4parseip, v4parsecidr, parseether, myipaddr, myetheraddr, maskip, equivip4, equivip6, defmask, isv4, v4tov6, v6tov4, nhgetv, nhgetl, nhgets, hnputv, hnputl, hnputs, ptclbsum, readipifc \- Internet Protocol addressing +eipfmt, parseip, parseipmask, parseipandmask, v4parseip, parseether, myipaddr, myetheraddr, maskip, equivip4, equivip6, defmask, isv4, v4tov6, v6tov4, nhgetv, nhgetl, nhgets, hnputv, hnputl, hnputs, ptclbsum, readipifc \- Internet Protocol addressing .SH SYNOPSIS .B #include <u.h> .br @@ -15,13 +15,13 @@ int eipfmt(Fmt*) vlong parseip(uchar *ipaddr, char *str) .PP .B -vlong parseipmask(uchar *ipaddr, char *str) +vlong parseipmask(uchar *ipaddr, char *str, int v4) .PP .B -char* v4parseip(uchar *ipaddr, char *str) +vlong parseipandmask(uchar *ipaddr, uchar *ipmask, char *ipstr, char *maskstr) .PP .B -ulong v4parsecidr(uchar *addr, uchar *mask, char *str) +char* v4parseip(uchar *ipaddr, char *str) .PP .B int parseether(uchar *eaddr, char *str) @@ -152,13 +152,37 @@ As a concession to backwards compatibility, if the string is a V4 address, the return value is an unsigned long integer containing the big-endian V4 address. If not, the return value is 6. +.PP .I Parseipmask converts a string pointed to by .I str -to a 6-byte IP mask starting at +to a 16-byte IP mask starting at .IR ipaddr . It too returns an unsigned long big-endian V4 address or 6. -Both routines return -1 on errors. +.I Parseipmask +accepts a mask in +.BI / prefixlen +slash notation. When the +.IR v4 +argument is non-zero, then +.I prefixlen +in range [0..32] is offset by 96 to yield a mask for a V4 address. +.PP +.I Parseipandmask +combines +.I parseip +and +.I parseipmask +into a single call, interpreting the mask in context of the +supplied IP address type. +The returned IP mask is +.B /128 +when +.I maskstr +is +.BR nil . +.PP +All three functions return -1 on errors. .PP .I V4parseip converts a string pointed to by @@ -166,15 +190,6 @@ converts a string pointed to by to a 4-byte V4 IP address starting at .IR ipaddr . .PP -.I V4parsecidr -converts a string of the form -addr/mask, pointed to by -.IR str , -to a 4-byte V4 IP address starting at -.I ipaddr -and a 4-byte V4 IP mask starting at -.IR mask . -.PP .I Myipaddr returns the first valid IP address in the IP stack rooted at @@ -207,7 +222,7 @@ operates on v6 addresses. .PP .I Defmask returns the standard class A, B, or C mask for -.IR ipaddr . +.I ipaddr . .PP .I Isv4 returns non-zero if the V6 address is in the V4 space, that is, 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); |