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);