17dd7cddfSDavid du Colombier /* 27dd7cddfSDavid du Colombier * this currently only works for ethernet bootp's -- presotto 37dd7cddfSDavid du Colombier */ 47dd7cddfSDavid du Colombier #include <u.h> 57dd7cddfSDavid du Colombier #include <libc.h> 67dd7cddfSDavid du Colombier #include <ip.h> 77dd7cddfSDavid du Colombier #include <bio.h> 87dd7cddfSDavid du Colombier #include <ndb.h> 97dd7cddfSDavid du Colombier #include "dat.h" 107dd7cddfSDavid du Colombier 117dd7cddfSDavid du Colombier Ndb *db; 127dd7cddfSDavid du Colombier char *ndbfile; 137dd7cddfSDavid du Colombier 149a747e4fSDavid du Colombier Iplifc* 159a747e4fSDavid du Colombier findlifc(uchar *ip) 167dd7cddfSDavid du Colombier { 177dd7cddfSDavid du Colombier uchar x[IPaddrlen]; 187dd7cddfSDavid du Colombier Ipifc *ifc; 199a747e4fSDavid du Colombier Iplifc *lifc; 207dd7cddfSDavid du Colombier 217dd7cddfSDavid du Colombier for(ifc = ipifcs; ifc; ifc = ifc->next){ 229a747e4fSDavid du Colombier for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){ 239a747e4fSDavid du Colombier if(lifc->net[0] == 0) 247dd7cddfSDavid du Colombier continue; 259a747e4fSDavid du Colombier maskip(ip, lifc->mask, x); 269a747e4fSDavid du Colombier if(memcmp(x, lifc->net, IPaddrlen) == 0) 279a747e4fSDavid du Colombier return lifc; 287dd7cddfSDavid du Colombier } 299a747e4fSDavid du Colombier } 309a747e4fSDavid du Colombier return nil; 317dd7cddfSDavid du Colombier } 327dd7cddfSDavid du Colombier 339a747e4fSDavid du Colombier int 347dd7cddfSDavid du Colombier forme(uchar *ip) 357dd7cddfSDavid du Colombier { 367dd7cddfSDavid du Colombier Ipifc *ifc; 379a747e4fSDavid du Colombier Iplifc *lifc; 387dd7cddfSDavid du Colombier 397dd7cddfSDavid du Colombier for(ifc = ipifcs; ifc; ifc = ifc->next){ 409a747e4fSDavid du Colombier for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next) 419a747e4fSDavid du Colombier if(memcmp(ip, lifc->ip, IPaddrlen) == 0) 429a747e4fSDavid du Colombier return 1; 437dd7cddfSDavid du Colombier } 447dd7cddfSDavid du Colombier return 0; 457dd7cddfSDavid du Colombier } 467dd7cddfSDavid du Colombier 477dd7cddfSDavid du Colombier uchar noetheraddr[6]; 487dd7cddfSDavid du Colombier 497dd7cddfSDavid du Colombier static void 507dd7cddfSDavid du Colombier setipaddr(uchar *addr, char *ip) 517dd7cddfSDavid du Colombier { 527dd7cddfSDavid du Colombier if(ipcmp(addr, IPnoaddr) == 0) 537dd7cddfSDavid du Colombier parseip(addr, ip); 547dd7cddfSDavid du Colombier } 557dd7cddfSDavid du Colombier 567dd7cddfSDavid du Colombier static void 577dd7cddfSDavid du Colombier setipmask(uchar *mask, char *ip) 587dd7cddfSDavid du Colombier { 597dd7cddfSDavid du Colombier if(ipcmp(mask, IPnoaddr) == 0) 607dd7cddfSDavid du Colombier parseipmask(mask, ip); 617dd7cddfSDavid du Colombier } 627dd7cddfSDavid du Colombier 637dd7cddfSDavid du Colombier /* 647dd7cddfSDavid du Colombier * do an ipinfo with defaults 657dd7cddfSDavid du Colombier */ 667dd7cddfSDavid du Colombier int 673ff48bf5SDavid du Colombier lookupip(uchar *ipaddr, Info *iip, int gate) 687dd7cddfSDavid du Colombier { 697dd7cddfSDavid du Colombier char ip[32]; 707dd7cddfSDavid du Colombier Ndbtuple *t, *nt; 717dd7cddfSDavid du Colombier char *attrs[32], **p; 727dd7cddfSDavid du Colombier 737dd7cddfSDavid du Colombier if(db == 0) 747dd7cddfSDavid du Colombier db = ndbopen(ndbfile); 757dd7cddfSDavid du Colombier if(db == 0){ 768c6ab946SDavid du Colombier warning(1, "can't open db"); 777dd7cddfSDavid du Colombier return -1; 787dd7cddfSDavid du Colombier } 797dd7cddfSDavid du Colombier 807dd7cddfSDavid du Colombier p = attrs; 817dd7cddfSDavid du Colombier *p++ = "ip"; 827dd7cddfSDavid du Colombier *p++ = "ipmask"; 833ff48bf5SDavid du Colombier *p++ = "@ipgw"; 843ff48bf5SDavid du Colombier if(!gate){ 857dd7cddfSDavid du Colombier *p++ = "bootf"; 86da51d93aSDavid du Colombier *p++ = "bootf2"; 873ff48bf5SDavid du Colombier *p++ = "@tftp"; 88da51d93aSDavid du Colombier *p++ = "@tftp2"; 899a747e4fSDavid du Colombier *p++ = "rootpath"; 907dd7cddfSDavid du Colombier *p++ = "dhcp"; 9139734e7eSDavid du Colombier *p++ = "vendorclass"; 927dd7cddfSDavid du Colombier *p++ = "ether"; 937dd7cddfSDavid du Colombier *p++ = "dom"; 947dd7cddfSDavid du Colombier *p++ = "@fs"; 957dd7cddfSDavid du Colombier *p++ = "@auth"; 963ff48bf5SDavid du Colombier } 977dd7cddfSDavid du Colombier *p = 0; 987dd7cddfSDavid du Colombier 997dd7cddfSDavid du Colombier memset(iip, 0, sizeof(*iip)); 1007dd7cddfSDavid du Colombier snprint(ip, sizeof(ip), "%I", ipaddr); 1017dd7cddfSDavid du Colombier t = ndbipinfo(db, "ip", ip, attrs, p - attrs); 1027dd7cddfSDavid du Colombier if(t == nil) 1037dd7cddfSDavid du Colombier return -1; 1047dd7cddfSDavid du Colombier 1057dd7cddfSDavid du Colombier for(nt = t; nt != nil; nt = nt->entry){ 1067dd7cddfSDavid du Colombier if(strcmp(nt->attr, "ip") == 0) 1077dd7cddfSDavid du Colombier setipaddr(iip->ipaddr, nt->val); 1087dd7cddfSDavid du Colombier else 1097dd7cddfSDavid du Colombier if(strcmp(nt->attr, "ipmask") == 0) 1107dd7cddfSDavid du Colombier setipmask(iip->ipmask, nt->val); 1117dd7cddfSDavid du Colombier else 1127dd7cddfSDavid du Colombier if(strcmp(nt->attr, "fs") == 0) 1137dd7cddfSDavid du Colombier setipaddr(iip->fsip, nt->val); 1147dd7cddfSDavid du Colombier else 1157dd7cddfSDavid du Colombier if(strcmp(nt->attr, "auth") == 0) 1167dd7cddfSDavid du Colombier setipaddr(iip->auip, nt->val); 1177dd7cddfSDavid du Colombier else 1183ff48bf5SDavid du Colombier if(strcmp(nt->attr, "tftp") == 0) 1193ff48bf5SDavid du Colombier setipaddr(iip->tftp, nt->val); 1203ff48bf5SDavid du Colombier else 1213ff48bf5SDavid du Colombier if(strcmp(nt->attr, "tftp2") == 0) 1223ff48bf5SDavid du Colombier setipaddr(iip->tftp2, nt->val); 1233ff48bf5SDavid du Colombier else 1247dd7cddfSDavid du Colombier if(strcmp(nt->attr, "ipgw") == 0) 1257dd7cddfSDavid du Colombier setipaddr(iip->gwip, nt->val); 1267dd7cddfSDavid du Colombier else 1277dd7cddfSDavid du Colombier if(strcmp(nt->attr, "ether") == 0){ 1282ddf2468SDavid du Colombier /* 1292ddf2468SDavid du Colombier * this is probably wrong for machines with multiple 1302ddf2468SDavid du Colombier * ethers. bootp or dhcp requests could come from any 1312ddf2468SDavid du Colombier * of the ethers listed in the ndb entry. 1322ddf2468SDavid du Colombier */ 1337dd7cddfSDavid du Colombier if(memcmp(iip->etheraddr, noetheraddr, 6) == 0) 1347dd7cddfSDavid du Colombier parseether(iip->etheraddr, nt->val); 1357dd7cddfSDavid du Colombier iip->indb = 1; 1367dd7cddfSDavid du Colombier } 1377dd7cddfSDavid du Colombier else 1387dd7cddfSDavid du Colombier if(strcmp(nt->attr, "dhcp") == 0){ 1397dd7cddfSDavid du Colombier if(iip->dhcpgroup[0] == 0) 1407dd7cddfSDavid du Colombier strcpy(iip->dhcpgroup, nt->val); 1417dd7cddfSDavid du Colombier } 1427dd7cddfSDavid du Colombier else 1437dd7cddfSDavid du Colombier if(strcmp(nt->attr, "bootf") == 0){ 1447dd7cddfSDavid du Colombier if(iip->bootf[0] == 0) 1457dd7cddfSDavid du Colombier strcpy(iip->bootf, nt->val); 1467dd7cddfSDavid du Colombier } 1477dd7cddfSDavid du Colombier else 1489a747e4fSDavid du Colombier if(strcmp(nt->attr, "bootf2") == 0){ 1499a747e4fSDavid du Colombier if(iip->bootf2[0] == 0) 1509a747e4fSDavid du Colombier strcpy(iip->bootf2, nt->val); 1519a747e4fSDavid du Colombier } 1529a747e4fSDavid du Colombier else 1537dd7cddfSDavid du Colombier if(strcmp(nt->attr, "vendor") == 0){ 1547dd7cddfSDavid du Colombier if(iip->vendor[0] == 0) 1557dd7cddfSDavid du Colombier strcpy(iip->vendor, nt->val); 1567dd7cddfSDavid du Colombier } 1577dd7cddfSDavid du Colombier else 1587dd7cddfSDavid du Colombier if(strcmp(nt->attr, "dom") == 0){ 1597dd7cddfSDavid du Colombier if(iip->domain[0] == 0) 1607dd7cddfSDavid du Colombier strcpy(iip->domain, nt->val); 1617dd7cddfSDavid du Colombier } 1629a747e4fSDavid du Colombier else 1639a747e4fSDavid du Colombier if(strcmp(nt->attr, "rootpath") == 0){ 1649a747e4fSDavid du Colombier if(iip->rootpath[0] == 0) 1659a747e4fSDavid du Colombier strcpy(iip->rootpath, nt->val); 1669a747e4fSDavid du Colombier } 1677dd7cddfSDavid du Colombier } 1687dd7cddfSDavid du Colombier ndbfree(t); 1697dd7cddfSDavid du Colombier maskip(iip->ipaddr, iip->ipmask, iip->ipnet); 1707dd7cddfSDavid du Colombier return 0; 1717dd7cddfSDavid du Colombier } 1727dd7cddfSDavid du Colombier 1737dd7cddfSDavid du Colombier static uchar zeroes[6]; 1747dd7cddfSDavid du Colombier 1757dd7cddfSDavid du Colombier /* 1767dd7cddfSDavid du Colombier * lookup info about a client in the database. Find an address on the 1777dd7cddfSDavid du Colombier * same net as riip. 1787dd7cddfSDavid du Colombier */ 1797dd7cddfSDavid du Colombier int 1807dd7cddfSDavid du Colombier lookup(Bootp *bp, Info *iip, Info *riip) 1817dd7cddfSDavid du Colombier { 1827dd7cddfSDavid du Colombier Ndbtuple *t, *nt; 1837dd7cddfSDavid du Colombier Ndbs s; 1847dd7cddfSDavid du Colombier char *hwattr; 1857dd7cddfSDavid du Colombier char *hwval, hwbuf[33]; 1867dd7cddfSDavid du Colombier uchar ciaddr[IPaddrlen]; 1877dd7cddfSDavid du Colombier 1887dd7cddfSDavid du Colombier if(db == 0) 1897dd7cddfSDavid du Colombier db = ndbopen(ndbfile); 1907dd7cddfSDavid du Colombier if(db == 0){ 1918c6ab946SDavid du Colombier warning(1, "can't open db"); 1927dd7cddfSDavid du Colombier return -1; 1937dd7cddfSDavid du Colombier } 1947dd7cddfSDavid du Colombier 1957dd7cddfSDavid du Colombier memset(iip, 0, sizeof(*iip)); 1967dd7cddfSDavid du Colombier 1977dd7cddfSDavid du Colombier /* client knows its address? */ 1987dd7cddfSDavid du Colombier v4tov6(ciaddr, bp->ciaddr); 1997dd7cddfSDavid du Colombier if(validip(ciaddr)){ 200*0a84db5eSDavid du Colombier if(lookupip(ciaddr, iip, 0) < 0) { 201*0a84db5eSDavid du Colombier if (debug) 202*0a84db5eSDavid du Colombier warning(0, "don't know %I", ciaddr); 2037dd7cddfSDavid du Colombier return -1; /* don't know anything about it */ 204*0a84db5eSDavid du Colombier } 2057dd7cddfSDavid du Colombier if(!samenet(riip->ipaddr, iip)){ 2067dd7cddfSDavid du Colombier warning(0, "%I not on %I", ciaddr, riip->ipnet); 2077dd7cddfSDavid du Colombier return -1; 2087dd7cddfSDavid du Colombier } 2097dd7cddfSDavid du Colombier 2107dd7cddfSDavid du Colombier /* 2117dd7cddfSDavid du Colombier * see if this is a masquerade, i.e., if the ether 2127dd7cddfSDavid du Colombier * address doesn't match what we expected it to be. 2137dd7cddfSDavid du Colombier */ 2147dd7cddfSDavid du Colombier if(memcmp(iip->etheraddr, zeroes, 6) != 0) 2157dd7cddfSDavid du Colombier if(memcmp(bp->chaddr, iip->etheraddr, 6) != 0) 2167dd7cddfSDavid du Colombier warning(0, "ciaddr %I rcvd from %E instead of %E", 2177dd7cddfSDavid du Colombier ciaddr, bp->chaddr, iip->etheraddr); 2187dd7cddfSDavid du Colombier 2197dd7cddfSDavid du Colombier return 0; 2207dd7cddfSDavid du Colombier } 2217dd7cddfSDavid du Colombier 2227dd7cddfSDavid du Colombier if(bp->hlen > Maxhwlen) 2237dd7cddfSDavid du Colombier return -1; 2247dd7cddfSDavid du Colombier switch(bp->htype){ 2257dd7cddfSDavid du Colombier case 1: 2267dd7cddfSDavid du Colombier hwattr = "ether"; 2277dd7cddfSDavid du Colombier hwval = hwbuf; 2287dd7cddfSDavid du Colombier snprint(hwbuf, sizeof(hwbuf), "%E", bp->chaddr); 2297dd7cddfSDavid du Colombier break; 2307dd7cddfSDavid du Colombier default: 2317dd7cddfSDavid du Colombier syslog(0, blog, "not ethernet %E, htype %d, hlen %d", 2327dd7cddfSDavid du Colombier bp->chaddr, bp->htype, bp->hlen); 2337dd7cddfSDavid du Colombier return -1; 2347dd7cddfSDavid du Colombier } 2357dd7cddfSDavid du Colombier 2367dd7cddfSDavid du Colombier /* 2377dd7cddfSDavid du Colombier * use hardware address to find an ip address on 2387dd7cddfSDavid du Colombier * same net as riip 2397dd7cddfSDavid du Colombier */ 2407dd7cddfSDavid du Colombier t = ndbsearch(db, &s, hwattr, hwval); 2417dd7cddfSDavid du Colombier while(t){ 2427dd7cddfSDavid du Colombier for(nt = t; nt; nt = nt->entry){ 2437dd7cddfSDavid du Colombier if(strcmp(nt->attr, "ip") != 0) 2447dd7cddfSDavid du Colombier continue; 2457dd7cddfSDavid du Colombier parseip(ciaddr, nt->val); 2463ff48bf5SDavid du Colombier if(lookupip(ciaddr, iip, 0) < 0) 2477dd7cddfSDavid du Colombier continue; 2487dd7cddfSDavid du Colombier if(samenet(riip->ipaddr, iip)){ 2497dd7cddfSDavid du Colombier ndbfree(t); 2507dd7cddfSDavid du Colombier return 0; 2517dd7cddfSDavid du Colombier } 2527dd7cddfSDavid du Colombier } 2537dd7cddfSDavid du Colombier ndbfree(t); 2547dd7cddfSDavid du Colombier t = ndbsnext(&s, hwattr, hwval); 2557dd7cddfSDavid du Colombier } 2567dd7cddfSDavid du Colombier return -1; 2577dd7cddfSDavid du Colombier } 2587dd7cddfSDavid du Colombier 2597dd7cddfSDavid du Colombier /* 2603ff48bf5SDavid du Colombier * interface to ndbipinfo 2613ff48bf5SDavid du Colombier */ 2623ff48bf5SDavid du Colombier Ndbtuple* 2633ff48bf5SDavid du Colombier lookupinfo(uchar *ipaddr, char **attr, int n) 2643ff48bf5SDavid du Colombier { 2653ff48bf5SDavid du Colombier char ip[32]; 2663ff48bf5SDavid du Colombier 2673ff48bf5SDavid du Colombier sprint(ip, "%I", ipaddr); 2683ff48bf5SDavid du Colombier return ndbipinfo(db, "ip", ip, attr, n); 2693ff48bf5SDavid du Colombier } 2703ff48bf5SDavid du Colombier 2713ff48bf5SDavid du Colombier /* 2727dd7cddfSDavid du Colombier * return the ip addresses for a type of server for system ip 2737dd7cddfSDavid du Colombier */ 2747dd7cddfSDavid du Colombier int 2753ff48bf5SDavid du Colombier lookupserver(char *attr, uchar **ipaddrs, Ndbtuple *t) 2767dd7cddfSDavid du Colombier { 2773ff48bf5SDavid du Colombier Ndbtuple *nt; 2787dd7cddfSDavid du Colombier int rv = 0; 2797dd7cddfSDavid du Colombier 2807dd7cddfSDavid du Colombier for(nt = t; rv < 2 && nt != nil; nt = nt->entry) 2817dd7cddfSDavid du Colombier if(strcmp(nt->attr, attr) == 0){ 2827dd7cddfSDavid du Colombier parseip(ipaddrs[rv], nt->val); 2837dd7cddfSDavid du Colombier rv++; 2847dd7cddfSDavid du Colombier } 2857dd7cddfSDavid du Colombier return rv; 2867dd7cddfSDavid du Colombier } 2877dd7cddfSDavid du Colombier 2887dd7cddfSDavid du Colombier /* 2897dd7cddfSDavid du Colombier * just lookup the name 2907dd7cddfSDavid du Colombier */ 2917dd7cddfSDavid du Colombier void 2923ff48bf5SDavid du Colombier lookupname(char *val, Ndbtuple *t) 2937dd7cddfSDavid du Colombier { 2943ff48bf5SDavid du Colombier Ndbtuple *nt; 2957dd7cddfSDavid du Colombier 2967dd7cddfSDavid du Colombier for(nt = t; nt != nil; nt = nt->entry) 2977dd7cddfSDavid du Colombier if(strcmp(nt->attr, "dom") == 0){ 2987dd7cddfSDavid du Colombier strcpy(val, nt->val); 2997dd7cddfSDavid du Colombier break; 3007dd7cddfSDavid du Colombier } 3013ff48bf5SDavid du Colombier } 302