/* * find out everything we can about a system from what has been * specified. */ int ipinfo(Ndb *db, char *etherin, char *ipin, char *name, Ipinfo *iip) { Ndbtuple *t; Ndbs s; char ether[Ndbvlen]; char ip[Ndbvlen]; char fsname[Ndbvlen]; char gwname[Ndbvlen]; char auname[Ndbvlen]; memset(iip, 0, sizeof(Ipinfo)); fsname[0] = 0; gwname[0] = 0; auname[0] = 0; /* * look for a matching entry */ t = 0; if(etherin) t = ndbgetval(db, &s, "ether", etherin, "ip", ip); if(t == 0 && ipin) t = ndbsearch(db, &s, "ip", ipin); if(t == 0 && name) t = ndbgetval(db, &s, ipattr(name), name, "ip", ip); if(t){ /* * copy in addresses and name */ if(lookval(t, s.t, "ip", ip)) parseip(iip->ipaddr, ip); if(lookval(t, s.t, "ether", ether)) parseether(iip->etheraddr, ether); lookval(t, s.t, "dom", iip->domain); /* * Look for bootfile, fs, and gateway. * If necessary, search through all entries for * this ip address. */ while(t){ if(iip->bootf[0] == 0) lookval(t, s.t, "bootf", iip->bootf); if(fsname[0] == 0) lookval(t, s.t, "fs", fsname); if(gwname[0] == 0) lookval(t, s.t, "ipgw", gwname); if(auname[0] == 0) lookval(t, s.t, "auth", auname); ndbfree(t); if(iip->bootf[0] && fsname[0] && gwname[0] && auname[0]) break; t = ndbsnext(&s, "ether", ether); } } else if(ipin) { /* * copy in addresses (all we know) */ parseip(iip->ipaddr, ipin); if(etherin) parseether(iip->etheraddr, etherin); } else return -1; /* * Look up the client's network and find a subnet mask for it. * Fill in from the subnet (or net) entry anything we can't figure * out from the client record. */ recursesubnet(db, classmask[CLASS(iip->ipaddr)], iip, fsname, gwname, auname); /* lookup fs's and gw's ip addresses */ if(fsname[0]) lookupip(db, fsname, iip->fsip, iip); if(gwname[0]) lookupip(db, gwname, iip->gwip, iip); if(auname[0]) lookupip(db, auname, iip->auip, iip); return 0; }
/* * 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(opendb() == nil){ warning(1, "can't open db"); return -1; } memset(iip, 0, sizeof(*iip)); /* client knows its address? */ v4tov6(ciaddr, bp->ciaddr); if(validip(ciaddr)){ if(lookupip(ciaddr, iip, 0) < 0) { if (debug) warning(0, "don't know %I", ciaddr); return -1; /* don't know anything about it */ } 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; }