ratfs: implement ipv6 support, replace v4parsecidr() with parseipandmask()
This commit is contained in:
parent
168dabc142
commit
50e617f8b6
|
@ -1,5 +1,4 @@
|
||||||
#include "ratfs.h"
|
#include "ratfs.h"
|
||||||
#include <ip.h>
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ACCEPT = 0, /* verbs in control file */
|
ACCEPT = 0, /* verbs in control file */
|
||||||
|
@ -40,6 +39,7 @@ getconf(void)
|
||||||
Biobuf *bp;
|
Biobuf *bp;
|
||||||
char *cp;
|
char *cp;
|
||||||
Node *np, *dir, **l;
|
Node *np, *dir, **l;
|
||||||
|
Cidraddr ip;
|
||||||
|
|
||||||
if(debugfd >= 0)
|
if(debugfd >= 0)
|
||||||
fprint(debugfd, "loading %s\n", conffile);
|
fprint(debugfd, "loading %s\n", conffile);
|
||||||
|
@ -76,8 +76,10 @@ getconf(void)
|
||||||
break;
|
break;
|
||||||
if (strcmp(cp, "ournets") == 0){
|
if (strcmp(cp, "ournets") == 0){
|
||||||
for(cp += strlen(cp)+1; cp && *cp; cp += strlen(cp)+1){
|
for(cp += strlen(cp)+1; cp && *cp; cp += strlen(cp)+1){
|
||||||
|
if(cidrparse(&ip, cp) == -1)
|
||||||
|
continue;
|
||||||
np = newnode(dir, cp, Trustedperm, 0111, trustedqid++);
|
np = newnode(dir, cp, Trustedperm, 0111, trustedqid++);
|
||||||
cidrparse(&np->ip, cp);
|
np->ip = ip;
|
||||||
subslash(cp);
|
subslash(cp);
|
||||||
np->d.name = atom(cp);
|
np->d.name = atom(cp);
|
||||||
}
|
}
|
||||||
|
@ -218,16 +220,12 @@ findkey(char *val, Keyword *p)
|
||||||
/*
|
/*
|
||||||
* parse a cidr specification in either IP/mask or IP#mask format
|
* parse a cidr specification in either IP/mask or IP#mask format
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
cidrparse(Cidraddr *cidr, char *cp)
|
cidrparse(Cidraddr *cidr, char *cp)
|
||||||
{
|
{
|
||||||
|
uchar ip[IPaddrlen];
|
||||||
char *p, *slash;
|
char buf[64], *p, *slash;
|
||||||
int c;
|
int c;
|
||||||
ulong a, m;
|
|
||||||
uchar addr[IPv4addrlen];
|
|
||||||
uchar mask[IPv4addrlen];
|
|
||||||
char buf[64];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* find '/' or '#' character in the cidr specification
|
* find '/' or '#' character in the cidr specification
|
||||||
|
@ -250,25 +248,11 @@ cidrparse(Cidraddr *cidr, char *cp)
|
||||||
}
|
}
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
||||||
v4parsecidr(addr, mask, buf);
|
if(parseipandmask(ip, cidr->mask, buf, slash) == -1)
|
||||||
a = nhgetl(addr);
|
return -1;
|
||||||
m = nhgetl(mask);
|
maskip(ip, cidr->mask, cidr->ipaddr);
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
/* force at least a class B */
|
return 0;
|
||||||
m |= 0xffff0000;
|
|
||||||
}
|
|
||||||
cidr->ipaddr = a;
|
|
||||||
cidr->mask = m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -335,7 +319,9 @@ ipinsert(Node *np, char *cp)
|
||||||
char *tmp;
|
char *tmp;
|
||||||
int i;
|
int i;
|
||||||
Address *ap;
|
Address *ap;
|
||||||
if(cp == 0 || *cp == 0)
|
Cidraddr ip;
|
||||||
|
|
||||||
|
if(cp == 0 || *cp == 0 || cidrparse(&ip, cp) == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
np = dirwalk("ip", np);
|
np = dirwalk("ip", np);
|
||||||
|
@ -351,27 +337,19 @@ ipinsert(Node *np, char *cp)
|
||||||
}
|
}
|
||||||
|
|
||||||
ap = &np->addrs[i]; /* new entry on end */
|
ap = &np->addrs[i]; /* new entry on end */
|
||||||
|
ap->ip = ip;
|
||||||
tmp = strdup(cp);
|
tmp = strdup(cp);
|
||||||
if(tmp == nil)
|
if(tmp == nil)
|
||||||
fatal("out of memory");
|
fatal("out of memory");
|
||||||
subslash(tmp);
|
subslash(tmp);
|
||||||
ap->name = atom(tmp);
|
ap->name = atom(tmp);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
cidrparse(&ap->ip, cp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
ipcomp(void *a, void *b)
|
ipaddrcomp(void *a, void *b)
|
||||||
{
|
{
|
||||||
ulong aip, bip;
|
return ipcmp(((Address*)a)->ip.ipaddr, ((Address*)b)->ip.ipaddr);
|
||||||
|
|
||||||
aip = ((Address*)a)->ip.ipaddr;
|
|
||||||
bip = ((Address*)b)->ip.ipaddr;
|
|
||||||
if(aip > bip)
|
|
||||||
return 1;
|
|
||||||
if(aip < bip)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -389,7 +367,7 @@ ipsort(void)
|
||||||
continue;
|
continue;
|
||||||
for(np = dir->children; np; np = np->sibs){
|
for(np = dir->children; np; np = np->sibs){
|
||||||
if(np->d.type == IPaddr && np->count && np->addrs)
|
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;
|
np->baseqid = base;
|
||||||
base += np->count;
|
base += np->count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,6 @@ int trustedqid = Qtrustedfile;
|
||||||
char *ctlfile = CTLFILE;
|
char *ctlfile = CTLFILE;
|
||||||
char *conffile = CONFFILE;
|
char *conffile = CONFFILE;
|
||||||
|
|
||||||
#pragma varargck type "I" Cidraddr*
|
|
||||||
|
|
||||||
static int ipconv(Fmt*);
|
|
||||||
static void post(int, char*);
|
static void post(int, char*);
|
||||||
static void setroot(void);
|
static void setroot(void);
|
||||||
|
|
||||||
|
@ -75,7 +72,9 @@ main(int argc, char *argv[])
|
||||||
if(argc != 0)
|
if(argc != 0)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
fmtinstall('I', ipconv);
|
fmtinstall('I', eipfmt);
|
||||||
|
fmtinstall('M', eipfmt);
|
||||||
|
|
||||||
setroot();
|
setroot();
|
||||||
getconf();
|
getconf();
|
||||||
reload();
|
reload();
|
||||||
|
@ -263,10 +262,10 @@ printnode(Node *np)
|
||||||
fprint(debugfd, "\tTrusted Child: %p", np->children);
|
fprint(debugfd, "\tTrusted Child: %p", np->children);
|
||||||
break;
|
break;
|
||||||
case Trustedperm:
|
case Trustedperm:
|
||||||
fprint(debugfd, "\tPerm Trustedfile: %I", &np->ip);
|
fprint(debugfd, "\tPerm Trustedfile: %I %M", np->ip.ipaddr, np->ip.mask);
|
||||||
break;
|
break;
|
||||||
case Trustedtemp:
|
case Trustedtemp:
|
||||||
fprint(debugfd, "\tTemp Trustedfile: %I", &np->ip);
|
fprint(debugfd, "\tTemp Trustedfile: %I %M", np->ip.ipaddr, np->ip.mask);
|
||||||
break;
|
break;
|
||||||
case Ctlfile:
|
case Ctlfile:
|
||||||
fprint(debugfd, "\tCtlfile");
|
fprint(debugfd, "\tCtlfile");
|
||||||
|
@ -301,18 +300,3 @@ printtree(Node *np)
|
||||||
for (np = np->children; np; np = np->sibs)
|
for (np = np->children; np; np = np->sibs)
|
||||||
printtree(np);
|
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include "ratfs.h"
|
#include "ratfs.h"
|
||||||
#include <ip.h>
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
Maxdoms = 10, /* max domains in a path */
|
Maxdoms = 10, /* max domains in a path */
|
||||||
|
@ -9,7 +8,7 @@ enum {
|
||||||
static int accountmatch(char*, char**, int, char*);
|
static int accountmatch(char*, char**, int, char*);
|
||||||
static Node* acctwalk(char*, Node*);
|
static Node* acctwalk(char*, Node*);
|
||||||
static int dommatch(char*, char*);
|
static int dommatch(char*, char*);
|
||||||
static Address* ipsearch(ulong, Address*, int);
|
static Address* ipsearch(uchar*, Address*, int);
|
||||||
static Node* ipwalk(char*, Node*);
|
static Node* ipwalk(char*, Node*);
|
||||||
static Node* trwalk(char*, Node*);
|
static Node* trwalk(char*, Node*);
|
||||||
static int usermatch(char*, char*);
|
static int usermatch(char*, char*);
|
||||||
|
@ -78,16 +77,17 @@ dirwalk(char *name, Node *np)
|
||||||
static Node*
|
static Node*
|
||||||
trwalk(char *name, Node *np)
|
trwalk(char *name, Node *np)
|
||||||
{
|
{
|
||||||
|
uchar addr[IPaddrlen], net[IPaddrlen];
|
||||||
Node *p;
|
Node *p;
|
||||||
ulong peerip;
|
|
||||||
uchar addr[IPv4addrlen];
|
|
||||||
|
|
||||||
v4parseip(addr, name);
|
parseip(addr, name);
|
||||||
peerip = nhgetl(addr);
|
|
||||||
|
|
||||||
for(p = np->children; p; p = p->sibs)
|
for(p = np->children; p; p = p->sibs){
|
||||||
if((peerip&p->ip.mask) == p->ip.ipaddr)
|
maskip(addr, p->ip.mask, net);
|
||||||
|
if(ipcmp(net, p->ip.ipaddr) == 0)
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,17 +97,15 @@ trwalk(char *name, Node *np)
|
||||||
static Node*
|
static Node*
|
||||||
ipwalk(char *name, Node *np)
|
ipwalk(char *name, Node *np)
|
||||||
{
|
{
|
||||||
|
uchar addr[IPaddrlen];
|
||||||
Address *ap;
|
Address *ap;
|
||||||
ulong peerip;
|
|
||||||
uchar addr[IPv4addrlen];
|
|
||||||
|
|
||||||
v4parseip(addr, name);
|
parseip(addr, name);
|
||||||
peerip = nhgetl(addr);
|
|
||||||
|
|
||||||
if(debugfd >= 0)
|
if(debugfd >= 0)
|
||||||
fprint(debugfd, "%d.%d.%d.%d - ", addr[0]&0xff, addr[1]&0xff,
|
fprint(debugfd, "%I - ", addr);
|
||||||
addr[2]&0xff, addr[3]&0xff);
|
|
||||||
ap = ipsearch(peerip, np->addrs, np->count);
|
ap = ipsearch(addr, np->addrs, np->count);
|
||||||
if(ap == 0)
|
if(ap == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -156,8 +154,9 @@ acctwalk(char *name, Node *np)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static Address*
|
static Address*
|
||||||
ipsearch(ulong addr, Address *base, int n)
|
ipsearch(uchar *addr, Address *base, int n)
|
||||||
{
|
{
|
||||||
|
uchar net[IPaddrlen];
|
||||||
ulong top, bot, mid;
|
ulong top, bot, mid;
|
||||||
Address *ap;
|
Address *ap;
|
||||||
|
|
||||||
|
@ -165,11 +164,12 @@ ipsearch(ulong addr, Address *base, int n)
|
||||||
top = n;
|
top = n;
|
||||||
for (mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {
|
for (mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {
|
||||||
ap = &base[mid];
|
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;
|
return ap;
|
||||||
if(addr < ap->ip.ipaddr)
|
if(ipcmp(addr, ap->ip.ipaddr) < 0)
|
||||||
top = mid;
|
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;
|
bot = mid;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -302,6 +302,7 @@ rcreate(Fcall *f)
|
||||||
{
|
{
|
||||||
Fid *fidp;
|
Fid *fidp;
|
||||||
Node *np;
|
Node *np;
|
||||||
|
Cidraddr ip;
|
||||||
|
|
||||||
fidp = newfid(f->fid);
|
fidp = newfid(f->fid);
|
||||||
np = fidp->node;
|
np = fidp->node;
|
||||||
|
@ -315,12 +316,16 @@ rcreate(Fcall *f)
|
||||||
return;
|
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 = newnode(np, f->name, Trustedtemp, 0444, trustedqid++);
|
||||||
|
np->ip = ip;
|
||||||
if(trustedqid >= Qaddrfile) /* wrap QIDs */
|
if(trustedqid >= Qaddrfile) /* wrap QIDs */
|
||||||
trustedqid = Qtrustedfile;
|
trustedqid = Qtrustedfile;
|
||||||
cidrparse(&np->ip, f->name);
|
|
||||||
f->qid = np->d.qid;
|
f->qid = np->d.qid;
|
||||||
np->d.uid = fidp->uid;
|
np->d.uid = fidp->uid;
|
||||||
np->d.gid = np->d.uid;
|
np->d.gid = np->d.uid;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <auth.h>
|
#include <auth.h>
|
||||||
#include <fcall.h>
|
#include <fcall.h>
|
||||||
#include <bio.h>
|
#include <bio.h>
|
||||||
|
#include <ip.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MAXRPC = 8192,
|
MAXRPC = 8192,
|
||||||
|
@ -54,8 +55,8 @@ struct Fid
|
||||||
|
|
||||||
struct Cidraddr
|
struct Cidraddr
|
||||||
{
|
{
|
||||||
ulong ipaddr; /* CIDR base addr */
|
uchar ipaddr[IPaddrlen]; /* CIDR base addr */
|
||||||
ulong mask; /* CIDR mask */
|
uchar mask[IPaddrlen]; /* CIDR mask */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* an address is either an account name (domain!user) or Ip address */
|
/* an address is either an account name (domain!user) or Ip address */
|
||||||
|
@ -98,7 +99,7 @@ long lastctltime;
|
||||||
int trustedqid;
|
int trustedqid;
|
||||||
|
|
||||||
char* atom(char*);
|
char* atom(char*);
|
||||||
void cidrparse(Cidraddr*, char*);
|
int cidrparse(Cidraddr*, char*);
|
||||||
void cleantrusted(void);
|
void cleantrusted(void);
|
||||||
Node* dirwalk(char*, Node*);
|
Node* dirwalk(char*, Node*);
|
||||||
int dread(Fid*, int);
|
int dread(Fid*, int);
|
||||||
|
|
Loading…
Reference in a new issue