]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ip/dhcpd/testlook.c
socksd: setnetmtpt
[plan9front.git] / sys / src / cmd / ip / dhcpd / testlook.c
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 }