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