ip/ipconfig, ip/ppp: preserve preexisting entries when writing /net/ndb

it is now possible to configure additional interfaces (like wifi)
and store the network information while preserving old entries
in /net/ndb. this allows to easily switch from ethernet to wifi
and have dhcp configure dns without having to clear /net/ndb.
This commit is contained in:
cinap_lenrek 2016-05-08 06:05:25 +02:00
parent 0e516cbf48
commit a630e17bd7
4 changed files with 86 additions and 133 deletions

View file

@ -108,7 +108,6 @@ void dhcpwatch(int);
void doadd(int); void doadd(int);
void doremove(void); void doremove(void);
void dounbind(void); void dounbind(void);
int getndb(void);
int ipconfig4(void); int ipconfig4(void);
int ipconfig6(int); int ipconfig6(int);
long jitter(void); long jitter(void);
@ -134,11 +133,9 @@ int parseverb(char*);
void procsetname(char *fmt, ...); void procsetname(char *fmt, ...);
void putndb(void); void putndb(void);
ulong randint(ulong low, ulong hi); ulong randint(ulong low, ulong hi);
void tweakservers(void);
void usage(void); void usage(void);
int validip(uchar*); int validip(uchar*);
void warning(char *fmt, ...); void warning(char *fmt, ...);
void writendb(char*, int, int);
/* /*
* IPv6 * IPv6

View file

@ -188,7 +188,6 @@ void dhcpwatch(int);
void doadd(int); void doadd(int);
void doremove(void); void doremove(void);
void dounbind(void); void dounbind(void);
int getndb(void);
void getoptions(uchar*); void getoptions(uchar*);
int ip4cfg(void); int ip4cfg(void);
int ip6cfg(int a); int ip6cfg(int a);
@ -217,10 +216,8 @@ int parseoptions(uchar *p, int n);
int parseverb(char*); int parseverb(char*);
void pppbinddev(void); void pppbinddev(void);
void putndb(void); void putndb(void);
void tweakservers(void);
void usage(void); void usage(void);
int validip(uchar*); int validip(uchar*);
void writendb(char*, int, int);
void void
usage(void) usage(void)
@ -593,23 +590,6 @@ main(int argc, char **argv)
exits(0); exits(0);
} }
int
havendb(char *net)
{
Dir *d;
char buf[128];
snprint(buf, sizeof buf, "%s/ndb", net);
if((d = dirstat(buf)) == nil)
return 0;
if(d->length == 0){
free(d);
return 0;
}
free(d);
return 1;
}
void void
doadd(int retry) doadd(int retry)
{ {
@ -619,7 +599,7 @@ doadd(int retry)
/* get number of preexisting interfaces */ /* get number of preexisting interfaces */
nip = nipifcs(conf.mpoint); nip = nipifcs(conf.mpoint);
if(beprimary == -1 && (nip == 0 || !havendb(conf.mpoint))) if(beprimary == -1 && nip == 0)
beprimary = 1; beprimary = 1;
/* get ipifc into name space and condition device for ip */ /* get ipifc into name space and condition device for ip */
@ -659,17 +639,17 @@ doadd(int retry)
} else } else
sysfatal("no success with DHCP"); sysfatal("no success with DHCP");
if(!noconfig) if(noconfig)
if(ip4cfg() < 0) return;
sysfatal("can't start ip");
else if(dodhcp && conf.lease != Lforever) if(ip4cfg() < 0)
dhcpwatch(0); sysfatal("can't start ip");
else if(dodhcp && conf.lease != Lforever)
dhcpwatch(0);
/* leave everything we've learned somewhere other procs can find it */ /* leave everything we've learned somewhere other procs can find it */
if(beprimary == 1){ if(beprimary)
putndb(); putndb();
tweakservers();
}
} }
void void
@ -893,10 +873,6 @@ ipunconfig(void)
ipmove(conf.laddr, IPnoaddr); ipmove(conf.laddr, IPnoaddr);
ipmove(conf.raddr, IPnoaddr); ipmove(conf.raddr, IPnoaddr);
ipmove(conf.mask, IPnoaddr); ipmove(conf.mask, IPnoaddr);
/* forget configuration info */
if(beprimary==1)
writendb("", 0, 0);
} }
void void
@ -1015,10 +991,8 @@ dhcpwatch(int needconfig)
* leave everything we've learned somewhere that * leave everything we've learned somewhere that
* other procs can find it. * other procs can find it.
*/ */
if(beprimary==1){ if(beprimary)
putndb(); putndb();
tweakservers();
}
} }
} }
} }
@ -1656,23 +1630,6 @@ parsebootp(uchar *p, int n)
return bp; return bp;
} }
/* write out an ndb entry */
void
writendb(char *s, int n, int append)
{
char file[64];
int fd;
snprint(file, sizeof file, "%s/ndb", conf.mpoint);
if(append){
fd = open(file, OWRITE);
seek(fd, 0, 2);
} else
fd = open(file, OWRITE|OTRUNC);
write(fd, s, n);
close(fd);
}
/* put server addresses into the ndb entry */ /* put server addresses into the ndb entry */
char* char*
putaddrs(char *p, char *e, char *attr, uchar *a, int len) putaddrs(char *p, char *e, char *attr, uchar *a, int len)
@ -1688,19 +1645,16 @@ putaddrs(char *p, char *e, char *attr, uchar *a, int len)
void void
putndb(void) putndb(void)
{ {
int append; static char buf[16*1024];
char buf[1024]; char file[64], *p, *e, *np;
char *p, *e, *np; Ndbtuple *t, *nt;
Ndb *db;
int fd;
p = buf; p = buf;
e = buf + sizeof buf; e = buf + sizeof buf;
if(getndb() == 0) p = seprint(p, e, "ip=%I ipmask=%M ipgw=%I\n",
append = 1; conf.laddr, conf.mask, conf.gaddr);
else {
append = 0;
p = seprint(p, e, "ip=%I ipmask=%M ipgw=%I\n",
conf.laddr, conf.mask, conf.gaddr);
}
if(np = strchr(conf.hostname, '.')){ if(np = strchr(conf.hostname, '.')){
if(*conf.domainname == 0) if(*conf.domainname == 0)
strcpy(conf.domainname, np+1); strcpy(conf.domainname, np+1);
@ -1721,54 +1675,41 @@ putndb(void)
p = putaddrs(p, e, "\tntp", conf.ntp, sizeof conf.ntp); p = putaddrs(p, e, "\tntp", conf.ntp, sizeof conf.ntp);
if(ndboptions) if(ndboptions)
p = seprint(p, e, "%s\n", ndboptions); p = seprint(p, e, "%s\n", ndboptions);
if(p > buf)
writendb(buf, p-buf, append);
}
/* get an ndb entry someone else wrote */ /* append preexisting entries not matching our ip */
int snprint(file, sizeof file, "%s/ndb", conf.mpoint);
getndb(void) db = ndbopen(file);
{ if(db != nil ){
char buf[1024]; while((t = ndbparse(db)) != nil){
int fd, n; uchar ip[IPaddrlen];
char *p;
snprint(buf, sizeof buf, "%s/ndb", conf.mpoint); if((nt = ndbfindattr(t, t, "ip")) == nil
fd = open(buf, OREAD); || parseip(ip, nt->val) < 0 || ipcmp(ip, conf.laddr) != 0){
n = read(fd, buf, sizeof buf-1); p = seprint(p, e, "\n");
close(fd); for(nt = t; nt != nil; nt = nt->entry)
if(n <= 0) p = seprint(p, e, "%s=%s%s", nt->attr, nt->val,
return -1; nt->entry==nil? "\n": nt->line!=nt->entry? "\n\t": " ");
buf[n] = 0; }
p = strstr(buf, "ip="); ndbfree(t);
if(p == nil) }
return -1; ndbclose(db);
if (parseip(conf.laddr, p+3) == -1) }
fprint(2, "%s: bad address %s\n", argv0, p+3);
return 0;
}
/* tell a server to refresh */ if((fd = open(file, OWRITE|OTRUNC)) < 0)
void
tweakserver(char *server)
{
int fd;
char file[64];
snprint(file, sizeof file, "%s/%s", conf.mpoint, server);
fd = open(file, ORDWR);
if(fd < 0)
return; return;
fprint(fd, "refresh"); write(fd, buf, p-buf);
close(fd); close(fd);
}
/* tell all servers to refresh their information */ snprint(file, sizeof file, "%s/cs", conf.mpoint);
void if((fd = open(file, OWRITE)) >= 0){
tweakservers(void) write(fd, "refresh", 7);
{ close(fd);
tweakserver("dns"); }
tweakserver("cs"); snprint(file, sizeof file, "%s/dns", conf.mpoint);
if((fd = open(file, OWRITE)) >= 0){
write(fd, "refresh", 7);
close(fd);
}
} }
/* return number of networks */ /* return number of networks */

View file

@ -14,11 +14,6 @@ pppbinddev(void)
Waitmsg *w; Waitmsg *w;
/* ppp does the binding */ /* ppp does the binding */
/* start with an empty config file */
if(nip == 0)
writendb("", 0, 0);
switch(pid = rfork(RFPROC|RFFDG|RFMEM)){ switch(pid = rfork(RFPROC|RFFDG|RFMEM)){
case -1: case -1:
sysfatal("can't start ppp: %r"); sysfatal("can't start ppp: %r");
@ -55,6 +50,5 @@ pppbinddev(void)
/* ppp sets up the configuration itself */ /* ppp sets up the configuration itself */
noconfig = 1; noconfig = 1;
getndb();
} }

View file

@ -2847,10 +2847,9 @@ main(int argc, char **argv)
/* wait until ip is configured */ /* wait until ip is configured */
rendezvous((void*)Rmagic, 0); rendezvous((void*)Rmagic, 0);
if(primary){ /* create a /net/ndb entry */
/* create a /net/ndb entry */ if(primary)
putndb(ppp, net); putndb(ppp, net);
}
exits(0); exits(0);
} }
@ -2917,15 +2916,16 @@ nipifcs(char *net)
static void static void
putndb(PPP *ppp, char *net) putndb(PPP *ppp, char *net)
{ {
char buf[1024]; static char buf[16*1024];
char file[64]; char file[64], *p, *e;
char *p, *e; Ndbtuple *t, *nt;
Ndb *db;
int fd; int fd;
e = buf + sizeof(buf); e = buf + sizeof(buf);
p = buf; p = buf;
p = seprint(p, e, "ip=%I ipmask=255.255.255.255 ipgw=%I\n", ppp->local, p = seprint(p, e, "ip=%I ipmask=255.255.255.255 ipgw=%I\n",
ppp->remote); ppp->local, ppp->remote);
if(validv4(ppp->dns[0])) if(validv4(ppp->dns[0]))
p = seprint(p, e, "\tdns=%I\n", ppp->dns[0]); p = seprint(p, e, "\tdns=%I\n", ppp->dns[0]);
if(validv4(ppp->dns[1])) if(validv4(ppp->dns[1]))
@ -2934,20 +2934,41 @@ putndb(PPP *ppp, char *net)
p = seprint(p, e, "\twins=%I\n", ppp->wins[0]); p = seprint(p, e, "\twins=%I\n", ppp->wins[0]);
if(validv4(ppp->wins[1])) if(validv4(ppp->wins[1]))
p = seprint(p, e, "\twins=%I\n", ppp->wins[1]); p = seprint(p, e, "\twins=%I\n", ppp->wins[1]);
seprint(file, file+sizeof file, "%s/ndb", net);
fd = open(file, OWRITE); /* append preexisting entries not matching our ip */
if(fd < 0) snprint(file, sizeof file, "%s/ndb", net);
db = ndbopen(file);
if(db != nil ){
while((t = ndbparse(db)) != nil){
uchar ip[IPaddrlen];
if((nt = ndbfindattr(t, t, "ip")) == nil
|| parseip(ip, nt->val) < 0 || ipcmp(ip, ppp->local) != 0){
p = seprint(p, e, "\n");
for(nt = t; nt != nil; nt = nt->entry)
p = seprint(p, e, "%s=%s%s", nt->attr, nt->val,
nt->entry==nil? "\n": nt->line!=nt->entry? "\n\t": " ");
}
ndbfree(t);
}
ndbclose(db);
}
if((fd = open(file, OWRITE|OTRUNC)) < 0)
return; return;
write(fd, buf, p-buf); write(fd, buf, p-buf);
close(fd); close(fd);
seprint(file, file+sizeof file, "%s/cs", net);
fd = open(file, OWRITE); snprint(file, sizeof file, "%s/cs", net);
write(fd, "refresh", 7); if((fd = open(file, OWRITE)) >= 0){
close(fd); write(fd, "refresh", 7);
seprint(file, file+sizeof file, "%s/dns", net); close(fd);
fd = open(file, OWRITE); }
write(fd, "refresh", 7); snprint(file, sizeof file, "%s/dns", net);
close(fd); if((fd = open(file, OWRITE)) >= 0){
write(fd, "refresh", 7);
close(fd);
}
} }
static void static void