123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- /*
- * 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;
- 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++ = "vendor";
- *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);
- }
|