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 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* 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** 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; 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 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; 86 87 lines = getfields(buf, line, nelem(line), 1, "\n"); 88 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); 113 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; 120 121 /* allocate new local address */ 122 *ll = lifc = mallocz(sizeof(Iplifc), 1); 123 ll = &lifc->next; 124 125 parseip(lifc->ip, f[0]); 126 parseipmask(lifc->mask, f[1]); 127 parseip(lifc->net, f[2]); 128 129 lifc->validlt = strtoul(f[3], nil, 10); 130 lifc->preflt = strtoul(f[4], nil, 10); 131 } 132 133 return l; 134 } 135 136 static void 137 _freeifc(Ipifc *ifc) 138 { 139 Ipifc *next; 140 Iplifc *lnext, *lifc; 141 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); 149 } 150 free(ifc); 151 } 152 } 153 154 Ipifc* 155 readipifc(char *net, Ipifc *ifc, int index) 156 { 157 int fd, i, n; 158 Dir *dir; 159 char directory[128]; 160 char buf[128]; 161 Ipifc **l; 162 163 _freeifc(ifc); 164 165 l = &ifc; 166 ifc = nil; 167 168 if(net == 0) 169 net = "/net"; 170 snprint(directory, sizeof(directory), "%s/ipifc", net); 171 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); 181 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)); 189 } 190 free(dir); 191 } 192 193 return ifc; 194 } 195