xref: /plan9/sys/src/cmd/ip/dhcpd/testlookup.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
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 	Ndb *db;
9 
10 static void
recursesubnet(Ndb * db,uchar * addr,uchar * mask,char * attr,char * name,char * name1)11 recursesubnet(Ndb *db, uchar *addr, uchar *mask, char *attr, char *name, char *name1)
12 {
13 	Ndbs s;
14 	Ndbtuple *t, *nt;
15 	uchar submask[IPaddrlen], net[IPaddrlen];
16 	char ip[Ndbvlen];
17 	int found;
18 
19 	maskip(addr, mask, net);
20 	sprint(ip, "%I", net);
21 	t = ndbsearch(db, &s, "ip", ip);
22 	if(t == 0)
23 		return;
24 
25 	for(nt = t; nt; nt = nt->entry){
26 		if(strcmp(nt->attr, "ipmask") == 0){
27 			parseip(submask, nt->val);
28 			if(memcmp(submask, mask, IPaddrlen) != 0)
29 				recursesubnet(db, addr, submask, attr, name, name1);
30 			break;
31 		}
32 	}
33 
34 	if(name[0] == 0){
35 		found = 0;
36 		for(nt = t; nt; nt = nt->entry){
37 			if(strcmp(nt->attr, attr) == 0){
38 				if(found){
39 					strcpy(name, nt->val);
40 					name1[0] = 0;
41 					found = 1;
42 				} else {
43 					strcpy(name1, nt->val);
44 					break;
45 				}
46 			}
47 		}
48 	}
49 
50 	ndbfree(t);
51 }
52 
53 /*
54  *  lookup an ip address
55  */
56 static int
getipaddr(Ndb * db,char * name,uchar * to,Ipinfo * iip)57 getipaddr(Ndb *db, char *name, uchar *to, Ipinfo *iip)
58 {
59 	Ndbtuple *t, *nt;
60 	char buf[Ndbvlen];
61 	uchar subnet[IPaddrlen];
62 	Ndbs s;
63 	char *attr;
64 
65 	attr = ipattr(name);
66 	if(strcmp(attr, "ip") == 0){
67 		parseip(to, name);
68 		return 1;
69 	}
70 
71 	t = ndbgetval(db, &s, attr, name, "ip", buf);
72 	if(t){
73 		/* first look for match on same subnet */
74 		for(nt = t; nt; nt = nt->entry){
75 			if(strcmp(nt->attr, "ip") != 0)
76 				continue;
77 			parseip(to, nt->val);
78 			maskip(to, iip->ipmask, subnet);
79 			if(memcmp(subnet, iip->ipnet, sizeof(subnet)) == 0)
80 				return 1;
81 		}
82 
83 		/* otherwise, just take what we have */
84 		ndbfree(t);
85 		parseip(to, buf);
86 		return 1;
87 	}
88 	return 0;
89 }
90 
91 /*
92  *  return the ip addresses for a type of server for system ip
93  */
94 int
lookupserver(char * attr,uchar ipaddrs[2][IPaddrlen],Ipinfo * iip)95 lookupserver(char *attr, uchar ipaddrs[2][IPaddrlen], Ipinfo *iip)
96 {
97 	Ndbtuple *t, *nt;
98 	Ndbs s;
99 	char ip[32];
100 	char name[Ndbvlen];
101 	char name1[Ndbvlen];
102 	int i;
103 
104 	name[0] = name1[0] = 0;
105 
106 	snprint(ip, sizeof(ip), "%I", iip->ipaddr);
107 	t = ndbsearch(db, &s, "ip", ip);
108 	while(t){
109 		for(nt = t; nt; nt = nt->entry){
110 			if(strcmp(attr, nt->attr) == 0){
111 				if(*name == 0)
112 					strcpy(name, nt->val);
113 				else {
114 					strcpy(name1, nt->val);
115 					break;
116 				}
117 			}
118 		}
119 		if(name[0])
120 			break;
121 		t = ndbsnext(&s, "ip", ip);
122 	}
123 
124 	if(name[0] == 0)
125 		recursesubnet(db, iip->ipaddr, classmask[CLASS(iip->ipaddr)], attr, name, name1);
126 
127 	i = 0;
128 	if(name[0] && getipaddr(db, name, *ipaddrs, iip) == 1){
129 		ipaddrs++;
130 		i++;
131 	}
132 	if(name1[0] && getipaddr(db, name1, *ipaddrs, iip) == 1)
133 		i++;
134 	return i;
135 }
136 
137 void
main(int argc,char ** argv)138 main(int argc, char **argv)
139 {
140 	Ipinfo ii;
141 	uchar addrs[2][IPaddrlen];
142 	int i, j;
143 
144 	db = ndbopen(0);
145 
146 	fmtinstall('E', eipconv);
147 	fmtinstall('I', eipconv);
148 	if(argc < 2)
149 		exits(0);
150 	if(strchr(argv[1], '.')){
151 		if(ipinfo(db, 0, argv[1], 0, &ii) < 0)
152 			exits(0);
153 	} else {
154 		if(ipinfo(db, argv[1], 0, 0, &ii) < 0)
155 			exits(0);
156 	}
157 	print("a %I m %I n %I f %s e %E a %I\n", ii.ipaddr,
158 		ii.ipmask, ii.ipnet, ii.bootf, ii.etheraddr, ii.auip);
159 
160 	i = lookupserver("auth", addrs, &ii);
161 	print("lookupserver returns %d\n", i);
162 	for(j = 0; j < i; j++)
163 		print("%I\n", addrs[j]);
164 	i = lookupserver("dns", addrs, &ii);
165 	print("lookupserver returns %d\n", i);
166 	for(j = 0; j < i; j++)
167 		print("%I\n", addrs[j]);
168 }
169