URI:
       tndb.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tndb.c (6152B)
       ---
            1 /*
            2  *  this currently only works for ethernet bootp's -- presotto
            3  */
            4 #include <u.h>
            5 #include <libc.h>
            6 #include <ip.h>
            7 #include <bio.h>
            8 #include <ndb.h>
            9 #include "dat.h"
           10 
           11 static void check72(Info *iip);
           12 
           13 Ndb *db;
           14 char *ndbfile;
           15 
           16 Iplifc*
           17 findlifc(uchar *ip)
           18 {
           19         uchar x[IPaddrlen];
           20         Ipifc *ifc;
           21         Iplifc *lifc;
           22 
           23         for(ifc = ipifcs; ifc; ifc = ifc->next){
           24                 for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
           25                         if(lifc->net[0] == 0)
           26                                 continue;
           27                         maskip(ip, lifc->mask, x);
           28                         if(memcmp(x, lifc->net, IPaddrlen) == 0)
           29                                 return lifc;
           30                 }
           31         }
           32         return nil;
           33 }
           34 
           35 int
           36 forme(uchar *ip)
           37 {
           38         Ipifc *ifc;
           39         Iplifc *lifc;
           40 
           41 extern uchar xmyipaddr[IPaddrlen];
           42 
           43 if(memcmp(ip, xmyipaddr, IPaddrlen) == 0)
           44         return 1;
           45 
           46         for(ifc = ipifcs; ifc; ifc = ifc->next){
           47                 for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next)
           48                         if(memcmp(ip, lifc->ip, IPaddrlen) == 0)
           49                                 return 1;
           50         }
           51         return 0;
           52 }
           53 
           54 uchar noetheraddr[6];
           55 
           56 static void
           57 setipaddr(uchar *addr, char *ip)
           58 {
           59         if(ipcmp(addr, IPnoaddr) == 0)
           60                 parseip(addr, ip);
           61 }
           62 
           63 static void
           64 setipmask(uchar *mask, char *ip)
           65 {
           66         if(ipcmp(mask, IPnoaddr) == 0)
           67                 parseipmask(mask, ip);
           68 }
           69 
           70 /*
           71  *  do an ipinfo with defaults
           72  */
           73 int
           74 lookupip(uchar *ipaddr, Info *iip, int gate)
           75 {
           76         char ip[32];
           77         Ndbtuple *t, *nt;
           78         char *attrs[32], **p;
           79 
           80         if(db == 0)
           81                 db = ndbopen(ndbfile);
           82         if(db == 0){
           83                 fprint(2, "can't open db\n");
           84                 return -1;
           85         }
           86 
           87         p = attrs;
           88         *p++ = "ip";
           89         *p++ = "ipmask";
           90         *p++ = "@ipgw";
           91         if(!gate){
           92                 *p++ = "bootf";
           93                 *p++ = "bootf2";
           94                 *p++ = "@tftp";
           95                 *p++ = "@tftp2";
           96                 *p++ = "rootpath";
           97                 *p++ = "dhcp";
           98                 *p++ = "vendorclass";
           99                 *p++ = "ether";
          100                 *p++ = "dom";
          101                 *p++ = "@fs";
          102                 *p++ = "@auth";
          103         }
          104         *p = 0;
          105 
          106         memset(iip, 0, sizeof(*iip));
          107         snprint(ip, sizeof(ip), "%I", ipaddr);
          108         t = ndbipinfo(db, "ip", ip, attrs, p - attrs);
          109         if(t == nil)
          110                 return -1;
          111 
          112         for(nt = t; nt != nil; nt = nt->entry){
          113                 if(strcmp(nt->attr, "ip") == 0)
          114                         setipaddr(iip->ipaddr, nt->val);
          115                 else
          116                 if(strcmp(nt->attr, "ipmask") == 0)
          117                         setipmask(iip->ipmask, nt->val);
          118                 else
          119                 if(strcmp(nt->attr, "fs") == 0)
          120                         setipaddr(iip->fsip, nt->val);
          121                 else
          122                 if(strcmp(nt->attr, "auth") == 0)
          123                         setipaddr(iip->auip, nt->val);
          124                 else
          125                 if(strcmp(nt->attr, "tftp") == 0)
          126                         setipaddr(iip->tftp, nt->val);
          127                 else
          128                 if(strcmp(nt->attr, "tftp2") == 0)
          129                         setipaddr(iip->tftp2, nt->val);
          130                 else
          131                 if(strcmp(nt->attr, "ipgw") == 0)
          132                         setipaddr(iip->gwip, nt->val);
          133                 else
          134                 if(strcmp(nt->attr, "ether") == 0){
          135                         if(memcmp(iip->etheraddr, noetheraddr, 6) == 0)
          136                                 parseether(iip->etheraddr, nt->val);
          137                         iip->indb = 1;
          138                 }
          139                 else
          140                 if(strcmp(nt->attr, "dhcp") == 0){
          141                         if(iip->dhcpgroup[0] == 0)
          142                                 strcpy(iip->dhcpgroup, nt->val);
          143                 }
          144                 else
          145                 if(strcmp(nt->attr, "bootf") == 0){
          146                         if(iip->bootf[0] == 0)
          147                                 strcpy(iip->bootf, nt->val);
          148                 }
          149                 else
          150                 if(strcmp(nt->attr, "bootf2") == 0){
          151                         if(iip->bootf2[0] == 0)
          152                                 strcpy(iip->bootf2, nt->val);
          153                 }
          154                 else
          155                 if(strcmp(nt->attr, "vendor") == 0){
          156                         if(iip->vendor[0] == 0)
          157                                 strcpy(iip->vendor, nt->val);
          158                 }
          159                 else
          160                 if(strcmp(nt->attr, "dom") == 0){
          161                         if(iip->domain[0] == 0)
          162                                 strcpy(iip->domain, nt->val);
          163                 }
          164                 else
          165                 if(strcmp(nt->attr, "rootpath") == 0){
          166                         if(iip->rootpath[0] == 0)
          167                                 strcpy(iip->rootpath, nt->val);
          168                 }
          169         }
          170         ndbfree(t);
          171         maskip(iip->ipaddr, iip->ipmask, iip->ipnet);
          172         return 0;
          173 }
          174 
          175 static uchar zeroes[6];
          176 
          177 /*
          178  *  lookup info about a client in the database.  Find an address on the
          179  *  same net as riip.
          180  */
          181 int
          182 lookup(Bootp *bp, Info *iip, Info *riip)
          183 {
          184         Ndbtuple *t, *nt;
          185         Ndbs s;
          186         char *hwattr;
          187         char *hwval, hwbuf[33];
          188         uchar ciaddr[IPaddrlen];
          189 
          190         if(db == 0)
          191                 db = ndbopen(ndbfile);
          192         if(db == 0){
          193                 fprint(2, "can't open db\n");
          194                 return -1;
          195         }
          196 
          197         memset(iip, 0, sizeof(*iip));
          198 
          199         /* client knows its address? */
          200         v4tov6(ciaddr, bp->ciaddr);
          201         if(validip(ciaddr)){
          202                 if(lookupip(ciaddr, iip, 0) < 0)
          203                         return -1;        /* don't know anything about it */
          204 
          205 check72(iip);
          206 
          207                 if(!samenet(riip->ipaddr, iip)){
          208                         warning(0, "%I not on %I", ciaddr, riip->ipnet);
          209                         return -1;
          210                 }
          211 
          212                 /*
          213                  *  see if this is a masquerade, i.e., if the ether
          214                  *  address doesn't match what we expected it to be.
          215                  */
          216                 if(memcmp(iip->etheraddr, zeroes, 6) != 0)
          217                 if(memcmp(bp->chaddr, iip->etheraddr, 6) != 0)
          218                         warning(0, "ciaddr %I rcvd from %E instead of %E",
          219                                 ciaddr, bp->chaddr, iip->etheraddr);
          220 
          221                 return 0;
          222         }
          223 
          224         if(bp->hlen > Maxhwlen)
          225                 return -1;
          226         switch(bp->htype){
          227         case 1:
          228                 hwattr = "ether";
          229                 hwval = hwbuf;
          230                 snprint(hwbuf, sizeof(hwbuf), "%E", bp->chaddr);
          231                 break;
          232         default:
          233                 syslog(0, blog, "not ethernet %E, htype %d, hlen %d",
          234                         bp->chaddr, bp->htype, bp->hlen);
          235                 return -1;
          236         }
          237 
          238         /*
          239          *  use hardware address to find an ip address on
          240          *  same net as riip
          241          */
          242         t = ndbsearch(db, &s, hwattr, hwval);
          243         while(t){
          244                 for(nt = t; nt; nt = nt->entry){
          245                         if(strcmp(nt->attr, "ip") != 0)
          246                                 continue;
          247                         parseip(ciaddr, nt->val);
          248                         if(lookupip(ciaddr, iip, 0) < 0)
          249                                 continue;
          250                         if(samenet(riip->ipaddr, iip)){
          251                                 ndbfree(t);
          252                                 return 0;
          253                         }
          254                 }
          255                 ndbfree(t);
          256                 t = ndbsnext(&s, hwattr, hwval);
          257         }
          258         return -1;
          259 }
          260 
          261 /*
          262  *  interface to ndbipinfo
          263  */
          264 Ndbtuple*
          265 lookupinfo(uchar *ipaddr, char **attr, int n)
          266 {
          267         char ip[32];
          268 
          269         sprint(ip, "%I", ipaddr);
          270         return ndbipinfo(db, "ip", ip, attr, n);
          271 }
          272 
          273 /*
          274  *  return the ip addresses for a type of server for system ip
          275  */
          276 int
          277 lookupserver(char *attr, uchar **ipaddrs, Ndbtuple *t)
          278 {
          279         Ndbtuple *nt;
          280         int rv = 0;
          281 
          282         for(nt = t; rv < 2 && nt != nil; nt = nt->entry)
          283                 if(strcmp(nt->attr, attr) == 0){
          284                         parseip(ipaddrs[rv], nt->val);
          285                         rv++;
          286                 }
          287         return rv;
          288 }
          289 
          290 /*
          291  *  just lookup the name
          292  */
          293 void
          294 lookupname(char *val, Ndbtuple *t)
          295 {
          296         Ndbtuple *nt;
          297 
          298         for(nt = t; nt != nil; nt = nt->entry)
          299                 if(strcmp(nt->attr, "dom") == 0){
          300                         strcpy(val, nt->val);
          301                         break;
          302                 }
          303 }
          304 
          305 uchar slash120[IPaddrlen] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          306                                 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0 };
          307 uchar net72[IPaddrlen] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
          308                                 0x0, 0x0, 0xff, 0xff, 135, 104, 72, 0 };
          309 
          310 static void
          311 check72(Info *iip)
          312 {
          313         uchar net[IPaddrlen];
          314 
          315         maskip(iip->ipaddr, slash120, net);
          316         if(ipcmp(net, net72) == 0)
          317                 syslog(0, blog, "check72 %I %M gw %I", iip->ipaddr, iip->ipmask, iip->gwip);
          318 }