shithub: riscv

Download patch

ref: 50e617f8b60b61e98538cb8ccb09958740defb9a
parent: 168dabc142d40a1cdce87e836806a9913bb6534e
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Feb 11 18:38:58 EST 2019

ratfs: implement ipv6 support, replace v4parsecidr() with parseipandmask()

--- a/sys/src/cmd/ratfs/ctlfiles.c
+++ b/sys/src/cmd/ratfs/ctlfiles.c
@@ -1,5 +1,4 @@
 #include "ratfs.h"
-#include <ip.h>
 
 enum {
 	ACCEPT = 0,		/* verbs in control file */
@@ -40,6 +39,7 @@
 	Biobuf *bp;
 	char *cp;
 	Node *np, *dir, **l;
+	Cidraddr ip;
 
 	if(debugfd >= 0)
 		fprint(debugfd, "loading %s\n", conffile);
@@ -76,8 +76,10 @@
 			break;
 		if (strcmp(cp, "ournets") == 0){
 			for(cp += strlen(cp)+1; cp && *cp; cp += strlen(cp)+1){
+				if(cidrparse(&ip, cp) == -1)
+					continue;
 				np = newnode(dir, cp, Trustedperm, 0111, trustedqid++);
-				cidrparse(&np->ip, cp);
+				np->ip = ip;
 				subslash(cp);
 				np->d.name = atom(cp);
 			}
@@ -218,16 +220,12 @@
 /*
  *	parse a cidr specification in either IP/mask or IP#mask format
  */
-void
+int
 cidrparse(Cidraddr *cidr, char *cp)
 {
-
-	char *p, *slash;
+	uchar ip[IPaddrlen];
+	char buf[64], *p, *slash;
 	int c;
-	ulong a, m;
-	uchar addr[IPv4addrlen];
-	uchar mask[IPv4addrlen];
-	char buf[64];
 
 	/*
 	 * find '/' or '#' character in the cidr specification
@@ -250,25 +248,11 @@
 	}
 	*p = 0;
 
-	v4parsecidr(addr, mask, buf);
-	a = nhgetl(addr);
-	m = nhgetl(mask);
-	/*
-	 * if a mask isn't specified, we build a minimal mask
-	 * instead of using the default mask for that net.  in this
-	 * case we never allow a class A mask (0xff000000).
-	 */
-	if(slash == 0){
-		m = 0xff000000;
-		p = buf;
-		for(p = strchr(p, '.'); p && p[1]; p = strchr(p+1, '.'))
-				m = (m>>8)|0xff000000;
+	if(parseipandmask(ip, cidr->mask, buf, slash) == -1)
+		return -1;
+	maskip(ip, cidr->mask, cidr->ipaddr);
 
-		/* force at least a class B */
-		m |= 0xffff0000;
-	}
-	cidr->ipaddr = a;
-	cidr->mask = m;
+	return 0;
 }
 
 /*
@@ -335,7 +319,9 @@
 	char *tmp;
 	int i;
 	Address *ap;
-	if(cp == 0 || *cp == 0)
+	Cidraddr ip;
+
+	if(cp == 0 || *cp == 0 || cidrparse(&ip, cp) == -1)
 		return;
 
 	np = dirwalk("ip", np);
@@ -351,6 +337,7 @@
 	}
 
 	ap = &np->addrs[i];				/* new entry on end */
+	ap->ip = ip;
 	tmp = strdup(cp);
 	if(tmp == nil)
 		fatal("out of memory");
@@ -357,21 +344,12 @@
 	subslash(tmp);
 	ap->name = atom(tmp);
 	free(tmp);
-	cidrparse(&ap->ip, cp);
 }
 
-int
-ipcomp(void *a, void *b)
+static int
+ipaddrcomp(void *a, void *b)
 {
-	ulong aip, bip;
-
-	aip = ((Address*)a)->ip.ipaddr;
-	bip = ((Address*)b)->ip.ipaddr;
-	if(aip > bip)
-		return 1;
-	if(aip < bip)
-		return -1;
-	return 0;
+	return ipcmp(((Address*)a)->ip.ipaddr, ((Address*)b)->ip.ipaddr);
 }
 
 /*
@@ -389,7 +367,7 @@
 			continue;
 		for(np = dir->children; np; np = np->sibs){
 			if(np->d.type == IPaddr && np->count && np->addrs)
-				qsort(np->addrs, np->count, sizeof(Address), ipcomp);
+				qsort(np->addrs, np->count, sizeof(Address), ipaddrcomp);
 			np->baseqid = base;
 			base += np->count;
 		}
--- a/sys/src/cmd/ratfs/main.c
+++ b/sys/src/cmd/ratfs/main.c
@@ -39,9 +39,6 @@
 char	*ctlfile =	CTLFILE;
 char	*conffile =	CONFFILE;
 
-#pragma	varargck	type	"I"	Cidraddr*
-
-static	int	ipconv(Fmt*);
 static	void	post(int, char*);
 static	void	setroot(void);
 
@@ -75,7 +72,9 @@
 	if(argc != 0)
 		usage();
 
-	fmtinstall('I', ipconv);
+	fmtinstall('I', eipfmt);
+	fmtinstall('M', eipfmt);
+
 	setroot();
 	getconf();
 	reload();
@@ -263,10 +262,10 @@
 		fprint(debugfd, "\tTrusted Child: %p", np->children);
 		break;
 	case Trustedperm:
-		fprint(debugfd, "\tPerm Trustedfile: %I", &np->ip);
+		fprint(debugfd, "\tPerm Trustedfile: %I %M", np->ip.ipaddr, np->ip.mask);
 		break;
 	case Trustedtemp:
-		fprint(debugfd, "\tTemp Trustedfile: %I", &np->ip);
+		fprint(debugfd, "\tTemp Trustedfile: %I %M", np->ip.ipaddr, np->ip.mask);
 		break;
 	case Ctlfile:
 		fprint(debugfd, "\tCtlfile");
@@ -300,19 +299,4 @@
 			return;
 	for (np = np->children; np; np = np->sibs)
 		printtree(np);
-}
-
-static int
-ipconv(Fmt *f)
-{
-	Cidraddr *ip;
-	int i, j;
-	char *p;
-
-	ip = va_arg(f->args, Cidraddr*);
-	p = (char*)&ip->ipaddr;
-	i = 0;
-	for (j = ip->mask; j; j <<= 1)
-		i++;
-	return fmtprint(f, "%d.%d.%d.%d/%d", p[3]&0xff, p[2]&0xff, p[1]&0xff, p[0]&0xff, i);
 }
--- a/sys/src/cmd/ratfs/misc.c
+++ b/sys/src/cmd/ratfs/misc.c
@@ -1,5 +1,4 @@
 #include "ratfs.h"
-#include <ip.h>
 
 enum {
 	Maxdoms	=	10,		/* max domains in a path */
@@ -9,7 +8,7 @@
 static	int	accountmatch(char*, char**, int, char*);
 static	Node*	acctwalk(char*,  Node*);
 static	int	dommatch(char*, char*);
-static	Address* ipsearch(ulong, Address*, int);
+static	Address* ipsearch(uchar*, Address*, int);
 static	Node*	ipwalk(char*,  Node*);
 static	Node*	trwalk(char*, Node*);
 static	int	usermatch(char*, char*);
@@ -78,16 +77,17 @@
 static Node*
 trwalk(char *name, Node *np)
 {
+	uchar addr[IPaddrlen], net[IPaddrlen];
 	Node *p;
-	ulong peerip;
-	uchar addr[IPv4addrlen];
 
-	v4parseip(addr, name);
-	peerip = nhgetl(addr);
+	parseip(addr, name);
 
-	for(p = np->children; p; p = p->sibs)
-		if((peerip&p->ip.mask) == p->ip.ipaddr)
+	for(p = np->children; p; p = p->sibs){
+		maskip(addr, p->ip.mask, net);
+		if(ipcmp(net, p->ip.ipaddr) == 0)
 			break;
+	}
+
 	return p;
 }
 
@@ -97,17 +97,15 @@
 static Node*
 ipwalk(char *name,  Node *np)
 {
+	uchar addr[IPaddrlen];
 	Address *ap;
-	ulong peerip;
-	uchar addr[IPv4addrlen];
 
-	v4parseip(addr, name);
-	peerip = nhgetl(addr);
+	parseip(addr, name);
 
 	if(debugfd >= 0)
-		fprint(debugfd, "%d.%d.%d.%d - ", addr[0]&0xff, addr[1]&0xff,
-				addr[2]&0xff, addr[3]&0xff);
-	ap = ipsearch(peerip, np->addrs, np->count);
+		fprint(debugfd, "%I - ", addr);
+
+	ap = ipsearch(addr, np->addrs, np->count);
 	if(ap == 0)
 		return 0;
 
@@ -156,8 +154,9 @@
  */
 
 static Address*
-ipsearch(ulong addr, Address *base, int n)
+ipsearch(uchar *addr, Address *base, int n)
 {
+	uchar net[IPaddrlen];
 	ulong top, bot, mid;
 	Address *ap;
 
@@ -165,11 +164,12 @@
 	top = n;
 	for (mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {
 		ap = &base[mid];
-		if((addr&ap->ip.mask) == ap->ip.ipaddr)
+		maskip(addr, ap->ip.mask, net);
+		if(ipcmp(net, ap->ip.ipaddr) == 0)
 			return ap;
-		if(addr < ap->ip.ipaddr)
+		if(ipcmp(addr, ap->ip.ipaddr) < 0)
 			top = mid;
-		else if(mid != n-1 && addr >= base[mid+1].ip.ipaddr)
+		else if(mid != n-1 && ipcmp(addr, base[mid+1].ip.ipaddr) >= 0)
 			bot = mid;
 		else
 			break;
--- a/sys/src/cmd/ratfs/proto.c
+++ b/sys/src/cmd/ratfs/proto.c
@@ -302,6 +302,7 @@
 {
 	Fid *fidp;
 	Node *np;
+	Cidraddr ip;
 
 	fidp = newfid(f->fid);
 	np = fidp->node;
@@ -315,12 +316,16 @@
 		return;
 	}
 
-	/* Ignore the supplied mode and force it to be non-writable */
+	if(cidrparse(&ip, f->name) == -1){
+		reply(f, "bad cidr in filename");
+		return;
+	}
 
+	/* Ignore the supplied mode and force it to be non-writable */
 	np = newnode(np, f->name, Trustedtemp, 0444, trustedqid++);
+	np->ip = ip;
 	if(trustedqid >= Qaddrfile)			/* wrap QIDs */
 		trustedqid = Qtrustedfile;
-	cidrparse(&np->ip, f->name);
 	f->qid = np->d.qid;
 	np->d.uid = fidp->uid;
 	np->d.gid = np->d.uid;
--- a/sys/src/cmd/ratfs/ratfs.h
+++ b/sys/src/cmd/ratfs/ratfs.h
@@ -3,6 +3,7 @@
 #include <auth.h>
 #include <fcall.h>
 #include <bio.h>
+#include <ip.h>
 
 enum {
 	MAXRPC = 8192,
@@ -54,8 +55,8 @@
 
 struct	Cidraddr
 {
-	ulong	ipaddr;		/* CIDR base addr */
-	ulong	mask;		/* CIDR mask */
+	uchar	ipaddr[IPaddrlen];		/* CIDR base addr */
+	uchar	mask[IPaddrlen];		/* CIDR mask */
 };
 
 	/* an address is either an account name (domain!user) or Ip address */
@@ -98,7 +99,7 @@
 int	trustedqid;
 
 char*	atom(char*);
-void	cidrparse(Cidraddr*, char*);
+int	cidrparse(Cidraddr*, char*);
 void	cleantrusted(void);
 Node*	dirwalk(char*, Node*);
 int	dread(Fid*, int);