tndb.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tndb.c (6152B) | |
--- | |
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" | |
10 | |
11 static void check72(Info *iip); | |
12 | |
13 Ndb *db; | |
14 char *ndbfile; | |
15 | |
16 Iplifc* | |
17 findlifc(uchar *ip) | |
18 { | |
19 uchar x[IPaddrlen]; | |
20 Ipifc *ifc; | |
21 Iplifc *lifc; | |
22 | |
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 } | |
34 | |
35 int | |
36 forme(uchar *ip) | |
37 { | |
38 Ipifc *ifc; | |
39 Iplifc *lifc; | |
40 | |
41 extern uchar xmyipaddr[IPaddrlen]; | |
42 | |
43 if(memcmp(ip, xmyipaddr, IPaddrlen) == 0) | |
44 return 1; | |
45 | |
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 } | |
53 | |
54 uchar noetheraddr[6]; | |
55 | |
56 static void | |
57 setipaddr(uchar *addr, char *ip) | |
58 { | |
59 if(ipcmp(addr, IPnoaddr) == 0) | |
60 parseip(addr, ip); | |
61 } | |
62 | |
63 static void | |
64 setipmask(uchar *mask, char *ip) | |
65 { | |
66 if(ipcmp(mask, IPnoaddr) == 0) | |
67 parseipmask(mask, ip); | |
68 } | |
69 | |
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; | |
79 | |
80 if(db == 0) | |
81 db = ndbopen(ndbfile); | |
82 if(db == 0){ | |
83 fprint(2, "can't open db\n"); | |
84 return -1; | |
85 } | |
86 | |
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"; | |
103 } | |
104 *p = 0; | |
105 | |
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; | |
111 | |
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; | |
138 } | |
139 else | |
140 if(strcmp(nt->attr, "dhcp") == 0){ | |
141 if(iip->dhcpgroup[0] == 0) | |
142 strcpy(iip->dhcpgroup, nt->val); | |
143 } | |
144 else | |
145 if(strcmp(nt->attr, "bootf") == 0){ | |
146 if(iip->bootf[0] == 0) | |
147 strcpy(iip->bootf, nt->val); | |
148 } | |
149 else | |
150 if(strcmp(nt->attr, "bootf2") == 0){ | |
151 if(iip->bootf2[0] == 0) | |
152 strcpy(iip->bootf2, nt->val); | |
153 } | |
154 else | |
155 if(strcmp(nt->attr, "vendor") == 0){ | |
156 if(iip->vendor[0] == 0) | |
157 strcpy(iip->vendor, nt->val); | |
158 } | |
159 else | |
160 if(strcmp(nt->attr, "dom") == 0){ | |
161 if(iip->domain[0] == 0) | |
162 strcpy(iip->domain, nt->val); | |
163 } | |
164 else | |
165 if(strcmp(nt->attr, "rootpath") == 0){ | |
166 if(iip->rootpath[0] == 0) | |
167 strcpy(iip->rootpath, nt->val); | |
168 } | |
169 } | |
170 ndbfree(t); | |
171 maskip(iip->ipaddr, iip->ipmask, iip->ipnet); | |
172 return 0; | |
173 } | |
174 | |
175 static uchar zeroes[6]; | |
176 | |
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) | |
183 { | |
184 Ndbtuple *t, *nt; | |
185 Ndbs s; | |
186 char *hwattr; | |
187 char *hwval, hwbuf[33]; | |
188 uchar ciaddr[IPaddrlen]; | |
189 | |
190 if(db == 0) | |
191 db = ndbopen(ndbfile); | |
192 if(db == 0){ | |
193 fprint(2, "can't open db\n"); | |
194 return -1; | |
195 } | |
196 | |
197 memset(iip, 0, sizeof(*iip)); | |
198 | |
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 i… | |
204 | |
205 check72(iip); | |
206 | |
207 if(!samenet(riip->ipaddr, iip)){ | |
208 warning(0, "%I not on %I", ciaddr, riip->ipnet); | |
209 return -1; | |
210 } | |
211 | |
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); | |
220 | |
221 return 0; | |
222 } | |
223 | |
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; | |
236 } | |
237 | |
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; | |
253 } | |
254 } | |
255 ndbfree(t); | |
256 t = ndbsnext(&s, hwattr, hwval); | |
257 } | |
258 return -1; | |
259 } | |
260 | |
261 /* | |
262 * interface to ndbipinfo | |
263 */ | |
264 Ndbtuple* | |
265 lookupinfo(uchar *ipaddr, char **attr, int n) | |
266 { | |
267 char ip[32]; | |
268 | |
269 sprint(ip, "%I", ipaddr); | |
270 return ndbipinfo(db, "ip", ip, attr, n); | |
271 } | |
272 | |
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) | |
278 { | |
279 Ndbtuple *nt; | |
280 int rv = 0; | |
281 | |
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++; | |
286 } | |
287 return rv; | |
288 } | |
289 | |
290 /* | |
291 * just lookup the name | |
292 */ | |
293 void | |
294 lookupname(char *val, Ndbtuple *t) | |
295 { | |
296 Ndbtuple *nt; | |
297 | |
298 for(nt = t; nt != nil; nt = nt->entry) | |
299 if(strcmp(nt->attr, "dom") == 0){ | |
300 strcpy(val, nt->val); | |
301 break; | |
302 } | |
303 } | |
304 | |
305 uchar slash120[IPaddrlen] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, … | |
306 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff… | |
307 uchar net72[IPaddrlen] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
308 0x0, 0x0, 0xff, 0xff, 135, 104, 72, 0 }; | |
309 | |
310 static void | |
311 check72(Info *iip) | |
312 { | |
313 uchar net[IPaddrlen]; | |
314 | |
315 maskip(iip->ipaddr, slash120, net); | |
316 if(ipcmp(net, net72) == 0) | |
317 syslog(0, blog, "check72 %I %M gw %I", iip->ipaddr, iip-… | |
318 } |