Blob


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"
11 static void check72(Info *iip);
13 Ndb *db;
14 char *ndbfile;
16 Iplifc*
17 findlifc(uchar *ip)
18 {
19 uchar x[IPaddrlen];
20 Ipifc *ifc;
21 Iplifc *lifc;
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 }
35 int
36 forme(uchar *ip)
37 {
38 Ipifc *ifc;
39 Iplifc *lifc;
41 extern uchar xmyipaddr[IPaddrlen];
43 if(memcmp(ip, xmyipaddr, IPaddrlen) == 0)
44 return 1;
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 }
54 uchar noetheraddr[6];
56 static void
57 setipaddr(uchar *addr, char *ip)
58 {
59 if(ipcmp(addr, IPnoaddr) == 0)
60 parseip(addr, ip);
61 }
63 static void
64 setipmask(uchar *mask, char *ip)
65 {
66 if(ipcmp(mask, IPnoaddr) == 0)
67 parseipmask(mask, ip);
68 }
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;
80 if(db == 0)
81 db = ndbopen(ndbfile);
82 if(db == 0){
83 fprint(2, "can't open db\n");
84 return -1;
85 }
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";
104 *p = 0;
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;
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;
139 else
140 if(strcmp(nt->attr, "dhcp") == 0){
141 if(iip->dhcpgroup[0] == 0)
142 strcpy(iip->dhcpgroup, nt->val);
144 else
145 if(strcmp(nt->attr, "bootf") == 0){
146 if(iip->bootf[0] == 0)
147 strcpy(iip->bootf, nt->val);
149 else
150 if(strcmp(nt->attr, "bootf2") == 0){
151 if(iip->bootf2[0] == 0)
152 strcpy(iip->bootf2, nt->val);
154 else
155 if(strcmp(nt->attr, "vendor") == 0){
156 if(iip->vendor[0] == 0)
157 strcpy(iip->vendor, nt->val);
159 else
160 if(strcmp(nt->attr, "dom") == 0){
161 if(iip->domain[0] == 0)
162 strcpy(iip->domain, nt->val);
164 else
165 if(strcmp(nt->attr, "rootpath") == 0){
166 if(iip->rootpath[0] == 0)
167 strcpy(iip->rootpath, nt->val);
170 ndbfree(t);
171 maskip(iip->ipaddr, iip->ipmask, iip->ipnet);
172 return 0;
175 static uchar zeroes[6];
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)
184 Ndbtuple *t, *nt;
185 Ndbs s;
186 char *hwattr;
187 char *hwval, hwbuf[33];
188 uchar ciaddr[IPaddrlen];
190 if(db == 0)
191 db = ndbopen(ndbfile);
192 if(db == 0){
193 fprint(2, "can't open db\n");
194 return -1;
197 memset(iip, 0, sizeof(*iip));
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 */
205 check72(iip);
207 if(!samenet(riip->ipaddr, iip)){
208 warning(0, "%I not on %I", ciaddr, riip->ipnet);
209 return -1;
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);
221 return 0;
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;
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;
255 ndbfree(t);
256 t = ndbsnext(&s, hwattr, hwval);
258 return -1;
261 /*
262 * interface to ndbipinfo
263 */
264 Ndbtuple*
265 lookupinfo(uchar *ipaddr, char **attr, int n)
267 char ip[32];
269 sprint(ip, "%I", ipaddr);
270 return ndbipinfo(db, "ip", ip, attr, n);
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)
279 Ndbtuple *nt;
280 int rv = 0;
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++;
287 return rv;
290 /*
291 * just lookup the name
292 */
293 void
294 lookupname(char *val, Ndbtuple *t)
296 Ndbtuple *nt;
298 for(nt = t; nt != nil; nt = nt->entry)
299 if(strcmp(nt->attr, "dom") == 0){
300 strcpy(val, nt->val);
301 break;
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 };
310 static void
311 check72(Info *iip)
313 uchar net[IPaddrlen];
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);