summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/include/ip.h4
-rw-r--r--sys/man/2/ip47
-rw-r--r--sys/src/libip/parseip.c38
-rw-r--r--sys/src/libip/readipifc.c7
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);