User libraries depend on their dependencies .a's
[akaros.git] / user / iplib / readipifc.c
1 /* 
2  * This file is part of the UCB release of Plan 9. It is subject to the license
3  * terms in the LICENSE file found in the top-level directory of this
4  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
5  * part of the UCB release of Plan 9, including this file, may be copied,
6  * modified, propagated, or distributed except according to the terms contained
7  * in the LICENSE file.
8  */
9 #include <stdlib.h>
10
11 #include <stdio.h>
12 #include <parlib.h>
13 #include <unistd.h>
14 #include <signal.h>
15 #include <iplib.h>
16
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <dirent.h>
21
22 #define NFIELD 200
23 #define nelem(x) (sizeof(x)/sizeof(x[0]))
24 static struct ipifc**
25 _readoldipifc(char *buf, struct ipifc **l, int index)
26 {
27         char *f[NFIELD];
28         int i, n;
29         struct ipifc *ifc;
30         struct iplifc *lifc, **ll;
31
32         /* allocate new interface */
33         *l = ifc = calloc(sizeof(struct ipifc), 1);
34         if(ifc == NULL)
35                 return l;
36         l = &ifc->next;
37         ifc->index = index;
38
39         n = tokenize(buf, f, NFIELD);
40         if(n < 2)
41                 return l;
42
43         strncpy(ifc->dev, f[0], sizeof ifc->dev);
44         ifc->dev[sizeof(ifc->dev) - 1] = 0;
45         ifc->mtu = strtoul(f[1], NULL, 10);
46
47         ll = &ifc->lifc;
48         for(i = 2; n-i >= 7; i += 7){
49                 /* allocate new local address */
50                 *ll = lifc = calloc(sizeof(struct iplifc), 1);
51                 ll = &lifc->next;
52
53                 parseip(lifc->ip, f[i]);
54                 parseipmask(lifc->mask, f[i+1]);
55                 parseip(lifc->net, f[i+2]);
56                 ifc->pktin = strtoul(f[i+3], NULL, 10);
57                 ifc->pktout = strtoul(f[i+4], NULL, 10);
58                 ifc->errin = strtoul(f[i+5], NULL, 10);
59                 ifc->errout = strtoul(f[i+6], NULL, 10);
60         }
61         return l;
62 }
63
64 static char*
65 findfield(char *name, char **f, int n)
66 {
67         int i;
68
69         for(i = 0; i < n-1; i++)
70                 if(strcmp(f[i], name) == 0)
71                         return f[i+1];
72         return "";
73 }
74
75 static struct ipifc**
76 _readipifc(char *file, struct ipifc **l, int index)
77 {
78         int i, n, fd, lines;
79         char buf[4*1024];
80         char *line[32];
81         char *f[64];
82         struct ipifc *ifc, **l0;
83         struct iplifc *lifc, **ll;
84
85         /* read the file */
86         fd = open(file, O_RDONLY);
87         if(fd < 0)
88                 return l;
89         n = 0;
90         while((i = read(fd, buf+n, sizeof(buf)-1-n)) > 0 && n < sizeof(buf) - 1)
91                 n += i;
92         buf[n] = 0;
93         close(fd);
94
95         if(strncmp(buf, "device", 6) != 0)
96                 return _readoldipifc(buf, l, index);
97         /* ignore ifcs with no associated device */
98         if(strncmp(buf+6, "  ", 2) == 0)
99                 return l;
100         /* allocate new interface */
101         *l = ifc = calloc(sizeof(struct ipifc), 1);
102         if(ifc == NULL)
103                 return l;
104         l0 = l;
105         l = &ifc->next;
106         ifc->index = index;
107
108         lines = getfields(buf, line, nelem(line), 1, "\n");
109
110         /* pick off device specific info(first line) */
111         n = tokenize(line[0], f, nelem(f));
112         if(n%2 != 0)
113                 goto lose;
114         strncpy(ifc->dev, findfield("device", f, n), sizeof(ifc->dev));
115         ifc->dev[sizeof(ifc->dev)-1] = 0;
116         if(ifc->dev[0] == 0){
117 lose:
118                 free(ifc);
119                 *l0 = NULL;
120                 return l;
121         }
122         ifc->mtu = strtoul(findfield("maxtu", f, n), NULL, 10);
123         ifc->sendra6 = atoi(findfield("sendra", f, n));
124         ifc->recvra6 = atoi(findfield("recvra", f, n));
125         ifc->rp.mflag = atoi(findfield("mflag", f, n));
126         ifc->rp.oflag = atoi(findfield("oflag", f, n));
127         ifc->rp.maxraint = atoi(findfield("maxraint", f, n));
128         ifc->rp.minraint = atoi(findfield("minraint", f, n));
129         ifc->rp.linkmtu = atoi(findfield("linkmtu", f, n));
130         ifc->rp.reachtime = atoi(findfield("reachtime", f, n));
131         ifc->rp.rxmitra = atoi(findfield("rxmitra", f, n));
132         ifc->rp.ttl = atoi(findfield("ttl", f, n));
133         ifc->rp.routerlt = atoi(findfield("routerlt", f, n));
134         ifc->pktin = strtoul(findfield("pktin", f, n), NULL, 10);
135         ifc->pktout = strtoul(findfield("pktout", f, n), NULL, 10);
136         ifc->errin = strtoul(findfield("errin", f, n), NULL, 10);
137         ifc->errout = strtoul(findfield("errout", f, n), NULL, 10);
138
139         /* now read the addresses */
140         ll = &ifc->lifc;
141         for(i = 1; i < lines; i++){
142                 n = tokenize(line[i], f, nelem(f));
143                 if(n < 5)
144                         break;
145
146                 /* allocate new local address */
147                 *ll = lifc = calloc(sizeof(struct iplifc), 1);
148                 ll = &lifc->next;
149
150                 parseip(lifc->ip, f[0]);
151                 parseipmask(lifc->mask, f[1]);
152                 parseip(lifc->net, f[2]);
153
154                 lifc->validlt = strtoul(f[3], NULL, 10);
155                 lifc->preflt = strtoul(f[4], NULL, 10);
156         }
157
158         return l;
159 }
160
161 static void
162 _freeifc(struct ipifc *ifc)
163 {
164         struct ipifc *next;
165         struct iplifc *lnext, *lifc;
166
167         if(ifc == NULL)
168                 return;
169         for(; ifc; ifc = next){
170                 next = ifc->next;
171                 for(lifc = ifc->lifc; lifc; lifc = lnext){
172                         lnext = lifc->next;
173                         free(lifc);
174                 }
175                 free(ifc);
176         }
177 }
178
179 struct ipifc*
180 readipifc(char *net, struct ipifc *ifc, int index)
181 {
182         int fd, i, n;
183         struct dir *dir;
184         char directory[128];
185         char buf[128];
186         struct ipifc **l;
187
188         _freeifc(ifc);
189
190         l = &ifc;
191         ifc = NULL;
192
193         if(net == 0)
194                 net = "/net";
195         snprintf(directory, sizeof(directory), "%s/ipifc", net);
196
197         if(index >= 0){
198                 snprintf(buf, sizeof(buf), "%s/%d/status", directory, index);
199                 _readipifc(buf, l, index);
200         } else {
201                 DIR *d;
202                 struct dirent *de;
203                 d = opendir(directory);
204                 if(! d)
205                         return NULL;
206                 
207                 while (de = readdir(d)){
208                         if(strcmp(de->d_name, "clone") == 0)
209                                 continue;
210                         if(strcmp(de->d_name, "stats") == 0)
211                                 continue;
212                         snprintf(buf, sizeof(buf), "%s/%s/status", directory, de->d_name);
213                         l = _readipifc(buf, l, atoi(de->d_name));
214                 }
215                 closedir(d);
216         }
217         
218         return ifc;
219 }