aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ip/dhcpd/ndb.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-12-26 04:48:52 +0000
committerrsc <devnull@localhost>2005-12-26 04:48:52 +0000
commit87a52e0485d3281ebea6bf4b725aa8023690e96f (patch)
tree0abc2d2ddb875196177231639d3cb4519e814b9d /src/cmd/ip/dhcpd/ndb.c
parent35d26aa32167e84326cdb745c0e906393b8de71d (diff)
downloadplan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.tar.gz
plan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.tar.bz2
plan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.zip
new goodies
Diffstat (limited to 'src/cmd/ip/dhcpd/ndb.c')
-rwxr-xr-xsrc/cmd/ip/dhcpd/ndb.c318
1 files changed, 318 insertions, 0 deletions
diff --git a/src/cmd/ip/dhcpd/ndb.c b/src/cmd/ip/dhcpd/ndb.c
new file mode 100755
index 00000000..53ffb58f
--- /dev/null
+++ b/src/cmd/ip/dhcpd/ndb.c
@@ -0,0 +1,318 @@
+/*
+ * this currently only works for ethernet bootp's -- presotto
+ */
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include <bio.h>
+#include <ndb.h>
+#include "dat.h"
+
+static void check72(Info *iip);
+
+Ndb *db;
+char *ndbfile;
+
+Iplifc*
+findlifc(uchar *ip)
+{
+ uchar x[IPaddrlen];
+ Ipifc *ifc;
+ Iplifc *lifc;
+
+ for(ifc = ipifcs; ifc; ifc = ifc->next){
+ for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
+ if(lifc->net[0] == 0)
+ continue;
+ maskip(ip, lifc->mask, x);
+ if(memcmp(x, lifc->net, IPaddrlen) == 0)
+ return lifc;
+ }
+ }
+ return nil;
+}
+
+int
+forme(uchar *ip)
+{
+ Ipifc *ifc;
+ Iplifc *lifc;
+
+extern uchar xmyipaddr[IPaddrlen];
+
+if(memcmp(ip, xmyipaddr, IPaddrlen) == 0)
+ return 1;
+
+ for(ifc = ipifcs; ifc; ifc = ifc->next){
+ for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next)
+ if(memcmp(ip, lifc->ip, IPaddrlen) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+uchar noetheraddr[6];
+
+static void
+setipaddr(uchar *addr, char *ip)
+{
+ if(ipcmp(addr, IPnoaddr) == 0)
+ parseip(addr, ip);
+}
+
+static void
+setipmask(uchar *mask, char *ip)
+{
+ if(ipcmp(mask, IPnoaddr) == 0)
+ parseipmask(mask, ip);
+}
+
+/*
+ * do an ipinfo with defaults
+ */
+int
+lookupip(uchar *ipaddr, Info *iip, int gate)
+{
+ char ip[32];
+ Ndbtuple *t, *nt;
+ char *attrs[32], **p;
+
+ if(db == 0)
+ db = ndbopen(ndbfile);
+ if(db == 0){
+ fprint(2, "can't open db\n");
+ return -1;
+ }
+
+ p = attrs;
+ *p++ = "ip";
+ *p++ = "ipmask";
+ *p++ = "@ipgw";
+ if(!gate){
+ *p++ = "bootf";
+ *p++ = "bootf2";
+ *p++ = "@tftp";
+ *p++ = "@tftp2";
+ *p++ = "rootpath";
+ *p++ = "dhcp";
+ *p++ = "vendorclass";
+ *p++ = "ether";
+ *p++ = "dom";
+ *p++ = "@fs";
+ *p++ = "@auth";
+ }
+ *p = 0;
+
+ memset(iip, 0, sizeof(*iip));
+ snprint(ip, sizeof(ip), "%I", ipaddr);
+ t = ndbipinfo(db, "ip", ip, attrs, p - attrs);
+ if(t == nil)
+ return -1;
+
+ for(nt = t; nt != nil; nt = nt->entry){
+ if(strcmp(nt->attr, "ip") == 0)
+ setipaddr(iip->ipaddr, nt->val);
+ else
+ if(strcmp(nt->attr, "ipmask") == 0)
+ setipmask(iip->ipmask, nt->val);
+ else
+ if(strcmp(nt->attr, "fs") == 0)
+ setipaddr(iip->fsip, nt->val);
+ else
+ if(strcmp(nt->attr, "auth") == 0)
+ setipaddr(iip->auip, nt->val);
+ else
+ if(strcmp(nt->attr, "tftp") == 0)
+ setipaddr(iip->tftp, nt->val);
+ else
+ if(strcmp(nt->attr, "tftp2") == 0)
+ setipaddr(iip->tftp2, nt->val);
+ else
+ if(strcmp(nt->attr, "ipgw") == 0)
+ setipaddr(iip->gwip, nt->val);
+ else
+ if(strcmp(nt->attr, "ether") == 0){
+ if(memcmp(iip->etheraddr, noetheraddr, 6) == 0)
+ parseether(iip->etheraddr, nt->val);
+ iip->indb = 1;
+ }
+ else
+ if(strcmp(nt->attr, "dhcp") == 0){
+ if(iip->dhcpgroup[0] == 0)
+ strcpy(iip->dhcpgroup, nt->val);
+ }
+ else
+ if(strcmp(nt->attr, "bootf") == 0){
+ if(iip->bootf[0] == 0)
+ strcpy(iip->bootf, nt->val);
+ }
+ else
+ if(strcmp(nt->attr, "bootf2") == 0){
+ if(iip->bootf2[0] == 0)
+ strcpy(iip->bootf2, nt->val);
+ }
+ else
+ if(strcmp(nt->attr, "vendor") == 0){
+ if(iip->vendor[0] == 0)
+ strcpy(iip->vendor, nt->val);
+ }
+ else
+ if(strcmp(nt->attr, "dom") == 0){
+ if(iip->domain[0] == 0)
+ strcpy(iip->domain, nt->val);
+ }
+ else
+ if(strcmp(nt->attr, "rootpath") == 0){
+ if(iip->rootpath[0] == 0)
+ strcpy(iip->rootpath, nt->val);
+ }
+ }
+ ndbfree(t);
+ maskip(iip->ipaddr, iip->ipmask, iip->ipnet);
+ return 0;
+}
+
+static uchar zeroes[6];
+
+/*
+ * lookup info about a client in the database. Find an address on the
+ * same net as riip.
+ */
+int
+lookup(Bootp *bp, Info *iip, Info *riip)
+{
+ Ndbtuple *t, *nt;
+ Ndbs s;
+ char *hwattr;
+ char *hwval, hwbuf[33];
+ uchar ciaddr[IPaddrlen];
+
+ if(db == 0)
+ db = ndbopen(ndbfile);
+ if(db == 0){
+ fprint(2, "can't open db\n");
+ return -1;
+ }
+
+ memset(iip, 0, sizeof(*iip));
+
+ /* client knows its address? */
+ v4tov6(ciaddr, bp->ciaddr);
+ if(validip(ciaddr)){
+ if(lookupip(ciaddr, iip, 0) < 0)
+ return -1; /* don't know anything about it */
+
+check72(iip);
+
+ if(!samenet(riip->ipaddr, iip)){
+ warning(0, "%I not on %I", ciaddr, riip->ipnet);
+ return -1;
+ }
+
+ /*
+ * see if this is a masquerade, i.e., if the ether
+ * address doesn't match what we expected it to be.
+ */
+ if(memcmp(iip->etheraddr, zeroes, 6) != 0)
+ if(memcmp(bp->chaddr, iip->etheraddr, 6) != 0)
+ warning(0, "ciaddr %I rcvd from %E instead of %E",
+ ciaddr, bp->chaddr, iip->etheraddr);
+
+ return 0;
+ }
+
+ if(bp->hlen > Maxhwlen)
+ return -1;
+ switch(bp->htype){
+ case 1:
+ hwattr = "ether";
+ hwval = hwbuf;
+ snprint(hwbuf, sizeof(hwbuf), "%E", bp->chaddr);
+ break;
+ default:
+ syslog(0, blog, "not ethernet %E, htype %d, hlen %d",
+ bp->chaddr, bp->htype, bp->hlen);
+ return -1;
+ }
+
+ /*
+ * use hardware address to find an ip address on
+ * same net as riip
+ */
+ t = ndbsearch(db, &s, hwattr, hwval);
+ while(t){
+ for(nt = t; nt; nt = nt->entry){
+ if(strcmp(nt->attr, "ip") != 0)
+ continue;
+ parseip(ciaddr, nt->val);
+ if(lookupip(ciaddr, iip, 0) < 0)
+ continue;
+ if(samenet(riip->ipaddr, iip)){
+ ndbfree(t);
+ return 0;
+ }
+ }
+ ndbfree(t);
+ t = ndbsnext(&s, hwattr, hwval);
+ }
+ return -1;
+}
+
+/*
+ * interface to ndbipinfo
+ */
+Ndbtuple*
+lookupinfo(uchar *ipaddr, char **attr, int n)
+{
+ char ip[32];
+
+ sprint(ip, "%I", ipaddr);
+ return ndbipinfo(db, "ip", ip, attr, n);
+}
+
+/*
+ * return the ip addresses for a type of server for system ip
+ */
+int
+lookupserver(char *attr, uchar **ipaddrs, Ndbtuple *t)
+{
+ Ndbtuple *nt;
+ int rv = 0;
+
+ for(nt = t; rv < 2 && nt != nil; nt = nt->entry)
+ if(strcmp(nt->attr, attr) == 0){
+ parseip(ipaddrs[rv], nt->val);
+ rv++;
+ }
+ return rv;
+}
+
+/*
+ * just lookup the name
+ */
+void
+lookupname(char *val, Ndbtuple *t)
+{
+ Ndbtuple *nt;
+
+ for(nt = t; nt != nil; nt = nt->entry)
+ if(strcmp(nt->attr, "dom") == 0){
+ strcpy(val, nt->val);
+ break;
+ }
+}
+
+uchar slash120[IPaddrlen] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0 };
+uchar net72[IPaddrlen] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xff, 0xff, 135, 104, 72, 0 };
+
+static void
+check72(Info *iip)
+{
+ uchar net[IPaddrlen];
+
+ maskip(iip->ipaddr, slash120, net);
+ if(ipcmp(net, net72) == 0)
+ syslog(0, blog, "check72 %I %M gw %I", iip->ipaddr, iip->ipmask, iip->gwip);
+}