testlook.c (4639B)
1 #include <u.h> 2 #include <libc.h> 3 #include <ip.h> 4 #include <bio.h> 5 #include <ndb.h> 6 7 static uchar noether[6]; 8 9 /* 10 * Look for a pair with the given attribute. look first on the same line, 11 * then in the whole entry. 12 */ 13 static Ndbtuple* 14 lookval(Ndbtuple *entry, Ndbtuple *line, char *attr, char *to) 15 { 16 Ndbtuple *nt; 17 18 /* first look on same line (closer binding) */ 19 for(nt = line;;){ 20 if(strcmp(attr, nt->attr) == 0){ 21 strncpy(to, nt->val, Ndbvlen); 22 return nt; 23 } 24 nt = nt->line; 25 if(nt == line) 26 break; 27 } 28 /* search whole tuple */ 29 for(nt = entry; nt; nt = nt->entry) 30 if(strcmp(attr, nt->attr) == 0){ 31 strncpy(to, nt->val, Ndbvlen); 32 return nt; 33 } 34 return 0; 35 } 36 37 /* 38 * lookup an ip address 39 */ 40 static uchar* 41 lookupip(Ndb *db, char *name, uchar *to, Ipinfo *iip) 42 { 43 Ndbtuple *t, *nt; 44 char buf[Ndbvlen]; 45 uchar subnet[IPaddrlen]; 46 Ndbs s; 47 char *attr; 48 49 attr = ipattr(name); 50 if(strcmp(attr, "ip") == 0){ 51 parseip(to, name); 52 return to; 53 } 54 55 t = ndbgetval(db, &s, attr, name, "ip", buf); 56 if(t){ 57 /* first look for match on same subnet */ 58 for(nt = t; nt; nt = nt->entry){ 59 if(strcmp(nt->attr, "ip") != 0) 60 continue; 61 parseip(to, nt->val); 62 maskip(to, iip->ipmask, subnet); 63 if(memcmp(subnet, iip->ipnet, sizeof(subnet)) == 0) 64 return to; 65 } 66 67 /* otherwise, just take what we have */ 68 ndbfree(t); 69 parseip(to, buf); 70 return to; 71 } 72 return 0; 73 } 74 75 /* 76 * lookup a subnet and fill in anything we can 77 */ 78 static void 79 recursesubnet(Ndb *db, uchar *mask, Ipinfo *iip, char *fs, char *gw, char *au) 80 { 81 Ndbs s; 82 Ndbtuple *t; 83 uchar submask[IPaddrlen]; 84 char ip[Ndbvlen]; 85 86 memmove(iip->ipmask, mask, 4); 87 maskip(iip->ipaddr, iip->ipmask, iip->ipnet); 88 sprint(ip, "%I", iip->ipnet); 89 t = ndbsearch(db, &s, "ip", ip); 90 print("%s->", ip); 91 if(t){ 92 /* look for a further subnet */ 93 if(lookval(t, s.t, "ipmask", ip)){ 94 parseip(submask, ip); 95 96 /* recurse only if it has changed */ 97 if(!equivip(submask, mask)) 98 recursesubnet(db, submask, iip, fs, gw, au); 99 100 } 101 102 /* fill in what we don't have */ 103 if(gw[0] == 0) 104 lookval(t, s.t, "ipgw", gw); 105 if(fs[0] == 0) 106 lookval(t, s.t, "fs", fs); 107 if(au[0] == 0) 108 lookval(t, s.t, "auth", au); 109 110 ndbfree(t); 111 } 112 } 113 #ifdef foo 114 /* 115 * find out everything we can about a system from what has been 116 * specified. 117 */ 118 int 119 ipinfo(Ndb *db, char *etherin, char *ipin, char *name, Ipinfo *iip) 120 { 121 Ndbtuple *t; 122 Ndbs s; 123 char ether[Ndbvlen]; 124 char ip[Ndbvlen]; 125 char fsname[Ndbvlen]; 126 char gwname[Ndbvlen]; 127 char auname[Ndbvlen]; 128 129 memset(iip, 0, sizeof(Ipinfo)); 130 fsname[0] = 0; 131 gwname[0] = 0; 132 auname[0] = 0; 133 134 /* 135 * look for a matching entry 136 */ 137 t = 0; 138 if(etherin) 139 t = ndbgetval(db, &s, "ether", etherin, "ip", ip); 140 if(t == 0 && ipin) 141 t = ndbsearch(db, &s, "ip", ipin); 142 if(t == 0 && name) 143 t = ndbgetval(db, &s, ipattr(name), name, "ip", ip); 144 if(t){ 145 /* 146 * copy in addresses and name 147 */ 148 if(lookval(t, s.t, "ip", ip)) 149 parseip(iip->ipaddr, ip); 150 if(lookval(t, s.t, "ether", ether)) 151 parseether(iip->etheraddr, ether); 152 lookval(t, s.t, "dom", iip->domain); 153 154 /* 155 * Look for bootfile, fs, and gateway. 156 * If necessary, search through all entries for 157 * this ip address. 158 */ 159 while(t){ 160 if(iip->bootf[0] == 0) 161 lookval(t, s.t, "bootf", iip->bootf); 162 if(fsname[0] == 0) 163 lookval(t, s.t, "fs", fsname); 164 if(gwname[0] == 0) 165 lookval(t, s.t, "ipgw", gwname); 166 if(auname[0] == 0) 167 lookval(t, s.t, "auth", auname); 168 ndbfree(t); 169 if(iip->bootf[0] && fsname[0] && gwname[0] && auname[0]) 170 break; 171 t = ndbsnext(&s, "ether", ether); 172 } 173 } else if(ipin) { 174 /* 175 * copy in addresses (all we know) 176 */ 177 parseip(iip->ipaddr, ipin); 178 if(etherin) 179 parseether(iip->etheraddr, etherin); 180 } else 181 return -1; 182 183 /* 184 * Look up the client's network and find a subnet mask for it. 185 * Fill in from the subnet (or net) entry anything we can't figure 186 * out from the client record. 187 */ 188 recursesubnet(db, classmask[CLASS(iip->ipaddr)], iip, fsname, gwname, auname); 189 190 /* lookup fs's and gw's ip addresses */ 191 192 if(fsname[0]) 193 lookupip(db, fsname, iip->fsip, iip); 194 if(gwname[0]) 195 lookupip(db, gwname, iip->gwip, iip); 196 if(auname[0]) 197 lookupip(db, auname, iip->auip, iip); 198 return 0; 199 } 200 #endif 201 void 202 main(int argc, char **argv) 203 { 204 Ipinfo ii; 205 Ndb *db; 206 207 db = ndbopen(0); 208 209 fmtinstall('E', eipconv); 210 fmtinstall('I', eipconv); 211 if(argc < 2) 212 exits(0); 213 if(strchr(argv[1], '.')){ 214 if(ipinfo(db, 0, argv[1], 0, &ii) < 0) 215 exits(0); 216 } else { 217 if(ipinfo(db, argv[1], 0, 0, &ii) < 0) 218 exits(0); 219 } 220 fprint(2, "a %I m %I n %I f %s e %E\n", ii.ipaddr, 221 ii.ipmask, ii.ipnet, ii.bootf, ii.etheraddr); 222 }