ttestlook.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
ttestlook.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 li… | |
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)) ==… | |
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, cha… | |
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, … | |
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] && au… | |
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 fig… | |
186 * out from the client record. | |
187 */ | |
188 recursesubnet(db, classmask[CLASS(iip->ipaddr)], iip, fsname, gw… | |
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 } |