xref: /plan9/sys/src/libip/readipifc.c (revision ac84fd08a8c8d942164771116b1cd72c58cf8dc5)
1 #include <u.h>
2 #include <libc.h>
3 #include <ctype.h>
4 #include <ip.h>
5 
6 static Ipifc**
_readoldipifc(char * buf,Ipifc ** l,int index)7 _readoldipifc(char *buf, Ipifc **l, int index)
8 {
9 	char *f[200];
10 	int i, n;
11 	Ipifc *ifc;
12 	Iplifc *lifc, **ll;
13 
14 	/* allocate new interface */
15 	*l = ifc = mallocz(sizeof(Ipifc), 1);
16 	if(ifc == nil)
17 		return l;
18 	l = &ifc->next;
19 	ifc->index = index;
20 
21 	n = tokenize(buf, f, nelem(f));
22 	if(n < 2)
23 		return l;
24 
25 	strncpy(ifc->dev, f[0], sizeof ifc->dev);
26 	ifc->dev[sizeof(ifc->dev) - 1] = 0;
27 	ifc->mtu = strtoul(f[1], nil, 10);
28 
29 	ll = &ifc->lifc;
30 	for(i = 2; n-i >= 7; i += 7){
31 		/* allocate new local address */
32 		*ll = lifc = mallocz(sizeof(Iplifc), 1);
33 		ll = &lifc->next;
34 
35 		parseip(lifc->ip, f[i]);
36 		parseipmask(lifc->mask, f[i+1]);
37 		parseip(lifc->net, f[i+2]);
38 		ifc->pktin = strtoul(f[i+3], nil, 10);
39 		ifc->pktout = strtoul(f[i+4], nil, 10);
40 		ifc->errin = strtoul(f[i+5], nil, 10);
41 		ifc->errout = strtoul(f[i+6], nil, 10);
42 	}
43 	return l;
44 }
45 
46 static char*
findfield(char * name,char ** f,int n)47 findfield(char *name, char **f, int n)
48 {
49 	int i;
50 
51 	for(i = 0; i < n-1; i++)
52 		if(strcmp(f[i], name) == 0)
53 			return f[i+1];
54 	return "";
55 }
56 
57 static Ipifc**
_readipifc(char * file,Ipifc ** l,int index)58 _readipifc(char *file, Ipifc **l, int index)
59 {
60 	int i, n, fd, lines;
61 	char buf[4*1024];
62 	char *line[32];
63 	char *f[64];
64 	Ipifc *ifc, **l0;
65 	Iplifc *lifc, **ll;
66 
67 	/* read the file */
68 	fd = open(file, OREAD);
69 	if(fd < 0)
70 		return l;
71 	n = 0;
72 	while((i = read(fd, buf+n, sizeof(buf)-1-n)) > 0 && n < sizeof(buf) - 1)
73 		n += i;
74 	buf[n] = 0;
75 	close(fd);
76 
77 	if(strncmp(buf, "device", 6) != 0)
78 		return _readoldipifc(buf, l, index);
79 	/* ignore ifcs with no associated device */
80 	if(strncmp(buf+6, "  ", 2) == 0)
81 		return l;
82 	/* allocate new interface */
83 	*l = ifc = mallocz(sizeof(Ipifc), 1);
84 	if(ifc == nil)
85 		return l;
86 	l0 = l;
87 	l = &ifc->next;
88 	ifc->index = index;
89 
90 	lines = getfields(buf, line, nelem(line), 1, "\n");
91 
92 	/* pick off device specific info(first line) */
93 	n = tokenize(line[0], f, nelem(f));
94 	if(n%2 != 0)
95 		goto lose;
96 	strncpy(ifc->dev, findfield("device", f, n), sizeof(ifc->dev));
97 	ifc->dev[sizeof(ifc->dev)-1] = 0;
98 	if(ifc->dev[0] == 0){
99 lose:
100 		free(ifc);
101 		*l0 = nil;
102 		return l;
103 	}
104 	ifc->mtu = strtoul(findfield("maxtu", f, n), nil, 10);
105 	ifc->sendra6 = atoi(findfield("sendra", f, n));
106 	ifc->recvra6 = atoi(findfield("recvra", f, n));
107 	ifc->rp.mflag = atoi(findfield("mflag", f, n));
108 	ifc->rp.oflag = atoi(findfield("oflag", f, n));
109 	ifc->rp.maxraint = atoi(findfield("maxraint", f, n));
110 	ifc->rp.minraint = atoi(findfield("minraint", f, n));
111 	ifc->rp.linkmtu = atoi(findfield("linkmtu", f, n));
112 	ifc->rp.reachtime = atoi(findfield("reachtime", f, n));
113 	ifc->rp.rxmitra = atoi(findfield("rxmitra", f, n));
114 	ifc->rp.ttl = atoi(findfield("ttl", f, n));
115 	ifc->rp.routerlt = atoi(findfield("routerlt", f, n));
116 	ifc->pktin = strtoul(findfield("pktin", f, n), nil, 10);
117 	ifc->pktout = strtoul(findfield("pktout", f, n), nil, 10);
118 	ifc->errin = strtoul(findfield("errin", f, n), nil, 10);
119 	ifc->errout = strtoul(findfield("errout", f, n), nil, 10);
120 
121 	/* now read the addresses */
122 	ll = &ifc->lifc;
123 	for(i = 1; i < lines; i++){
124 		n = tokenize(line[i], f, nelem(f));
125 		if(n < 5)
126 			break;
127 
128 		/* allocate new local address */
129 		*ll = lifc = mallocz(sizeof(Iplifc), 1);
130 		ll = &lifc->next;
131 
132 		parseip(lifc->ip, f[0]);
133 		parseipmask(lifc->mask, f[1]);
134 		parseip(lifc->net, f[2]);
135 
136 		lifc->validlt = strtoul(f[3], nil, 10);
137 		lifc->preflt = strtoul(f[4], nil, 10);
138 	}
139 
140 	return l;
141 }
142 
143 static void
_freeifc(Ipifc * ifc)144 _freeifc(Ipifc *ifc)
145 {
146 	Ipifc *next;
147 	Iplifc *lnext, *lifc;
148 
149 	if(ifc == nil)
150 		return;
151 	for(; ifc; ifc = next){
152 		next = ifc->next;
153 		for(lifc = ifc->lifc; lifc; lifc = lnext){
154 			lnext = lifc->next;
155 			free(lifc);
156 		}
157 		free(ifc);
158 	}
159 }
160 
161 Ipifc*
readipifc(char * net,Ipifc * ifc,int index)162 readipifc(char *net, Ipifc *ifc, int index)
163 {
164 	int fd, i, n;
165 	Dir *dir;
166 	char directory[128];
167 	char buf[128];
168 	Ipifc **l;
169 
170 	_freeifc(ifc);
171 
172 	l = &ifc;
173 	ifc = nil;
174 
175 	if(net == 0)
176 		net = "/net";
177 	snprint(directory, sizeof(directory), "%s/ipifc", net);
178 
179 	if(index >= 0){
180 		snprint(buf, sizeof(buf), "%s/%d/status", directory, index);
181 		_readipifc(buf, l, index);
182 	} else {
183 		fd = open(directory, OREAD);
184 		if(fd < 0)
185 			return nil;
186 		n = dirreadall(fd, &dir);
187 		close(fd);
188 
189 		for(i = 0; i < n; i++){
190 			if(strcmp(dir[i].name, "clone") == 0)
191 				continue;
192 			if(strcmp(dir[i].name, "stats") == 0)
193 				continue;
194 			snprint(buf, sizeof(buf), "%s/%s/status", directory, dir[i].name);
195 			l = _readipifc(buf, l, atoi(dir[i].name));
196 		}
197 		free(dir);
198 	}
199 
200 	return ifc;
201 }
202