Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <ctype.h>
4 #include <ip.h>
6 static Ipifc**
7 _readoldipifc(char *buf, Ipifc **l, int index)
8 {
9 char *f[200];
10 int i, n;
11 Ipifc *ifc;
12 Iplifc *lifc, **ll;
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;
21 n = tokenize(buf, f, nelem(f));
22 if(n < 2)
23 return l;
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);
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;
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 }
46 static char*
47 findfield(char *name, char **f, int n)
48 {
49 int i;
51 for(i = 0; i < n-1; i++)
52 if(strcmp(f[i], name) == 0)
53 return f[i+1];
54 return "";
55 }
57 static Ipifc**
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;
65 Iplifc *lifc, **ll;
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);
77 if(strncmp(buf, "device", 6) != 0)
78 return _readoldipifc(buf, l, index);
80 /* allocate new interface */
81 *l = ifc = mallocz(sizeof(Ipifc), 1);
82 if(ifc == nil)
83 return l;
84 l = &ifc->next;
85 ifc->index = index;
87 lines = getfields(buf, line, nelem(line), 1, "\n");
89 /* pick off device specific info(first line) */
90 n = tokenize(line[0], f, nelem(f));
91 strncpy(ifc->dev, findfield("device", f, n), sizeof(ifc->dev));
92 ifc->dev[sizeof(ifc->dev)-1] = 0;
93 if(ifc->dev[0] == 0){
94 free(ifc);
95 return l;
96 }
97 ifc->mtu = strtoul(findfield("maxmtu", f, n), nil, 10);
98 ifc->sendra6 = atoi(findfield("sendra", f, n));
99 ifc->recvra6 = atoi(findfield("recvra", f, n));
100 ifc->rp.mflag = atoi(findfield("mflag", f, n));
101 ifc->rp.oflag = atoi(findfield("oflag", f, n));
102 ifc->rp.maxraint = atoi(findfield("maxraint", f, n));
103 ifc->rp.minraint = atoi(findfield("minraint", f, n));
104 ifc->rp.linkmtu = atoi(findfield("linkmtu", f, n));
105 ifc->rp.reachtime = atoi(findfield("reachtime", f, n));
106 ifc->rp.rxmitra = atoi(findfield("rxmitra", f, n));
107 ifc->rp.ttl = atoi(findfield("ttl", f, n));
108 ifc->rp.routerlt = atoi(findfield("routerlt", f, n));
109 ifc->pktin = strtoul(findfield("pktin", f, n), nil, 10);
110 ifc->pktout = strtoul(findfield("pktout", f, n), nil, 10);
111 ifc->errin = strtoul(findfield("errin", f, n), nil, 10);
112 ifc->errout = strtoul(findfield("errout", f, n), nil, 10);
114 /* now read the addresses */
115 ll = &ifc->lifc;
116 for(i = 1; i < lines; i++){
117 n = tokenize(line[i], f, nelem(f));
118 if(n < 5)
119 break;
121 /* allocate new local address */
122 *ll = lifc = mallocz(sizeof(Iplifc), 1);
123 ll = &lifc->next;
125 parseip(lifc->ip, f[0]);
126 parseipmask(lifc->mask, f[1]);
127 parseip(lifc->net, f[2]);
129 lifc->validlt = strtoul(f[3], nil, 10);
130 lifc->preflt = strtoul(f[4], nil, 10);
133 return l;
136 static void
137 _freeifc(Ipifc *ifc)
139 Ipifc *next;
140 Iplifc *lnext, *lifc;
142 if(ifc == nil)
143 return;
144 for(; ifc; ifc = next){
145 next = ifc->next;
146 for(lifc = ifc->lifc; lifc; lifc = lnext){
147 lnext = lifc->next;
148 free(lifc);
150 free(ifc);
154 Ipifc*
155 readipifc(char *net, Ipifc *ifc, int index)
157 int fd, i, n;
158 Dir *dir;
159 char directory[128];
160 char buf[128];
161 Ipifc **l;
163 _freeifc(ifc);
165 l = &ifc;
166 ifc = nil;
168 if(net == 0)
169 net = "/net";
170 snprint(directory, sizeof(directory), "%s/ipifc", net);
172 if(index >= 0){
173 snprint(buf, sizeof(buf), "%s/%d/status", directory, index);
174 _readipifc(buf, l, index);
175 } else {
176 fd = open(directory, OREAD);
177 if(fd < 0)
178 return nil;
179 n = dirreadall(fd, &dir);
180 close(fd);
182 for(i = 0; i < n; i++){
183 if(strcmp(dir[i].name, "clone") == 0)
184 continue;
185 if(strcmp(dir[i].name, "stats") == 0)
186 continue;
187 snprint(buf, sizeof(buf), "%s/%s/status", directory, dir[i].name);
188 l = _readipifc(buf, l, atoi(dir[i].name));
190 free(dir);
193 return ifc;