xref: /plan9/sys/src/libip/readipifc.c (revision ac84fd08a8c8d942164771116b1cd72c58cf8dc5)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <ctype.h>
47dd7cddfSDavid du Colombier #include <ip.h>
57dd7cddfSDavid du Colombier 
67dd7cddfSDavid du Colombier static Ipifc**
_readoldipifc(char * buf,Ipifc ** l,int index)75d459b5aSDavid du Colombier _readoldipifc(char *buf, Ipifc **l, int index)
85d459b5aSDavid du Colombier {
95d459b5aSDavid du Colombier 	char *f[200];
105d459b5aSDavid du Colombier 	int i, n;
115d459b5aSDavid du Colombier 	Ipifc *ifc;
125d459b5aSDavid du Colombier 	Iplifc *lifc, **ll;
135d459b5aSDavid du Colombier 
145d459b5aSDavid du Colombier 	/* allocate new interface */
155d459b5aSDavid du Colombier 	*l = ifc = mallocz(sizeof(Ipifc), 1);
165d459b5aSDavid du Colombier 	if(ifc == nil)
175d459b5aSDavid du Colombier 		return l;
185d459b5aSDavid du Colombier 	l = &ifc->next;
195d459b5aSDavid du Colombier 	ifc->index = index;
205d459b5aSDavid du Colombier 
215d459b5aSDavid du Colombier 	n = tokenize(buf, f, nelem(f));
225d459b5aSDavid du Colombier 	if(n < 2)
235d459b5aSDavid du Colombier 		return l;
245d459b5aSDavid du Colombier 
255d459b5aSDavid du Colombier 	strncpy(ifc->dev, f[0], sizeof ifc->dev);
265d459b5aSDavid du Colombier 	ifc->dev[sizeof(ifc->dev) - 1] = 0;
275d459b5aSDavid du Colombier 	ifc->mtu = strtoul(f[1], nil, 10);
285d459b5aSDavid du Colombier 
295d459b5aSDavid du Colombier 	ll = &ifc->lifc;
305d459b5aSDavid du Colombier 	for(i = 2; n-i >= 7; i += 7){
315d459b5aSDavid du Colombier 		/* allocate new local address */
325d459b5aSDavid du Colombier 		*ll = lifc = mallocz(sizeof(Iplifc), 1);
335d459b5aSDavid du Colombier 		ll = &lifc->next;
345d459b5aSDavid du Colombier 
355d459b5aSDavid du Colombier 		parseip(lifc->ip, f[i]);
365d459b5aSDavid du Colombier 		parseipmask(lifc->mask, f[i+1]);
375d459b5aSDavid du Colombier 		parseip(lifc->net, f[i+2]);
385d459b5aSDavid du Colombier 		ifc->pktin = strtoul(f[i+3], nil, 10);
395d459b5aSDavid du Colombier 		ifc->pktout = strtoul(f[i+4], nil, 10);
405d459b5aSDavid du Colombier 		ifc->errin = strtoul(f[i+5], nil, 10);
415d459b5aSDavid du Colombier 		ifc->errout = strtoul(f[i+6], nil, 10);
425d459b5aSDavid du Colombier 	}
435d459b5aSDavid du Colombier 	return l;
445d459b5aSDavid du Colombier }
455d459b5aSDavid du Colombier 
463ff48bf5SDavid du Colombier static char*
findfield(char * name,char ** f,int n)475d459b5aSDavid du Colombier findfield(char *name, char **f, int n)
485d459b5aSDavid du Colombier {
495d459b5aSDavid du Colombier 	int i;
505d459b5aSDavid du Colombier 
515d459b5aSDavid du Colombier 	for(i = 0; i < n-1; i++)
525d459b5aSDavid du Colombier 		if(strcmp(f[i], name) == 0)
535d459b5aSDavid du Colombier 			return f[i+1];
545d459b5aSDavid du Colombier 	return "";
555d459b5aSDavid du Colombier }
565d459b5aSDavid du Colombier 
575d459b5aSDavid du Colombier static Ipifc**
_readipifc(char * file,Ipifc ** l,int index)587dd7cddfSDavid du Colombier _readipifc(char *file, Ipifc **l, int index)
597dd7cddfSDavid du Colombier {
605d459b5aSDavid du Colombier 	int i, n, fd, lines;
617dd7cddfSDavid du Colombier 	char buf[4*1024];
625d459b5aSDavid du Colombier 	char *line[32];
635d459b5aSDavid du Colombier 	char *f[64];
64*ac84fd08SDavid du Colombier 	Ipifc *ifc, **l0;
659a747e4fSDavid du Colombier 	Iplifc *lifc, **ll;
667dd7cddfSDavid du Colombier 
677dd7cddfSDavid du Colombier 	/* read the file */
687dd7cddfSDavid du Colombier 	fd = open(file, OREAD);
697dd7cddfSDavid du Colombier 	if(fd < 0)
707dd7cddfSDavid du Colombier 		return l;
717dd7cddfSDavid du Colombier 	n = 0;
727dd7cddfSDavid du Colombier 	while((i = read(fd, buf+n, sizeof(buf)-1-n)) > 0 && n < sizeof(buf) - 1)
737dd7cddfSDavid du Colombier 		n += i;
747dd7cddfSDavid du Colombier 	buf[n] = 0;
757dd7cddfSDavid du Colombier 	close(fd);
765d459b5aSDavid du Colombier 
775d459b5aSDavid du Colombier 	if(strncmp(buf, "device", 6) != 0)
785d459b5aSDavid du Colombier 		return _readoldipifc(buf, l, index);
79*ac84fd08SDavid du Colombier 	/* ignore ifcs with no associated device */
80*ac84fd08SDavid du Colombier 	if(strncmp(buf+6, "  ", 2) == 0)
81*ac84fd08SDavid du Colombier 		return l;
829a747e4fSDavid du Colombier 	/* allocate new interface */
839a747e4fSDavid du Colombier 	*l = ifc = mallocz(sizeof(Ipifc), 1);
849a747e4fSDavid du Colombier 	if(ifc == nil)
857dd7cddfSDavid du Colombier 		return l;
86*ac84fd08SDavid du Colombier 	l0 = l;
879a747e4fSDavid du Colombier 	l = &ifc->next;
889a747e4fSDavid du Colombier 	ifc->index = index;
897dd7cddfSDavid du Colombier 
905d459b5aSDavid du Colombier 	lines = getfields(buf, line, nelem(line), 1, "\n");
915d459b5aSDavid du Colombier 
925d459b5aSDavid du Colombier 	/* pick off device specific info(first line) */
935d459b5aSDavid du Colombier 	n = tokenize(line[0], f, nelem(f));
94*ac84fd08SDavid du Colombier 	if(n%2 != 0)
95*ac84fd08SDavid du Colombier 		goto lose;
965d459b5aSDavid du Colombier 	strncpy(ifc->dev, findfield("device", f, n), sizeof(ifc->dev));
979a747e4fSDavid du Colombier 	ifc->dev[sizeof(ifc->dev)-1] = 0;
985d459b5aSDavid du Colombier 	if(ifc->dev[0] == 0){
99*ac84fd08SDavid du Colombier lose:
1005d459b5aSDavid du Colombier 		free(ifc);
101*ac84fd08SDavid du Colombier 		*l0 = nil;
1025d459b5aSDavid du Colombier 		return l;
1035d459b5aSDavid du Colombier 	}
104de8abbc9SDavid du Colombier 	ifc->mtu = strtoul(findfield("maxtu", f, n), nil, 10);
1055d459b5aSDavid du Colombier 	ifc->sendra6 = atoi(findfield("sendra", f, n));
1065d459b5aSDavid du Colombier 	ifc->recvra6 = atoi(findfield("recvra", f, n));
1075d459b5aSDavid du Colombier 	ifc->rp.mflag = atoi(findfield("mflag", f, n));
1085d459b5aSDavid du Colombier 	ifc->rp.oflag = atoi(findfield("oflag", f, n));
1095d459b5aSDavid du Colombier 	ifc->rp.maxraint = atoi(findfield("maxraint", f, n));
1105d459b5aSDavid du Colombier 	ifc->rp.minraint = atoi(findfield("minraint", f, n));
1115d459b5aSDavid du Colombier 	ifc->rp.linkmtu = atoi(findfield("linkmtu", f, n));
1125d459b5aSDavid du Colombier 	ifc->rp.reachtime = atoi(findfield("reachtime", f, n));
1135d459b5aSDavid du Colombier 	ifc->rp.rxmitra = atoi(findfield("rxmitra", f, n));
1145d459b5aSDavid du Colombier 	ifc->rp.ttl = atoi(findfield("ttl", f, n));
1155d459b5aSDavid du Colombier 	ifc->rp.routerlt = atoi(findfield("routerlt", f, n));
1165d459b5aSDavid du Colombier 	ifc->pktin = strtoul(findfield("pktin", f, n), nil, 10);
1175d459b5aSDavid du Colombier 	ifc->pktout = strtoul(findfield("pktout", f, n), nil, 10);
1185d459b5aSDavid du Colombier 	ifc->errin = strtoul(findfield("errin", f, n), nil, 10);
1195d459b5aSDavid du Colombier 	ifc->errout = strtoul(findfield("errout", f, n), nil, 10);
1207dd7cddfSDavid du Colombier 
1215d459b5aSDavid du Colombier 	/* now read the addresses */
1229a747e4fSDavid du Colombier 	ll = &ifc->lifc;
1235d459b5aSDavid du Colombier 	for(i = 1; i < lines; i++){
1245d459b5aSDavid du Colombier 		n = tokenize(line[i], f, nelem(f));
1255d459b5aSDavid du Colombier 		if(n < 5)
1265d459b5aSDavid du Colombier 			break;
1275d459b5aSDavid du Colombier 
1289a747e4fSDavid du Colombier 		/* allocate new local address */
1299a747e4fSDavid du Colombier 		*ll = lifc = mallocz(sizeof(Iplifc), 1);
1309a747e4fSDavid du Colombier 		ll = &lifc->next;
1317dd7cddfSDavid du Colombier 
1325d459b5aSDavid du Colombier 		parseip(lifc->ip, f[0]);
1335d459b5aSDavid du Colombier 		parseipmask(lifc->mask, f[1]);
1345d459b5aSDavid du Colombier 		parseip(lifc->net, f[2]);
1359a747e4fSDavid du Colombier 
1365d459b5aSDavid du Colombier 		lifc->validlt = strtoul(f[3], nil, 10);
1375d459b5aSDavid du Colombier 		lifc->preflt = strtoul(f[4], nil, 10);
1387dd7cddfSDavid du Colombier 	}
1397dd7cddfSDavid du Colombier 
1407dd7cddfSDavid du Colombier 	return l;
1417dd7cddfSDavid du Colombier }
1427dd7cddfSDavid du Colombier 
1439a747e4fSDavid du Colombier static void
_freeifc(Ipifc * ifc)1449a747e4fSDavid du Colombier _freeifc(Ipifc *ifc)
1459a747e4fSDavid du Colombier {
1469a747e4fSDavid du Colombier 	Ipifc *next;
1479a747e4fSDavid du Colombier 	Iplifc *lnext, *lifc;
1489a747e4fSDavid du Colombier 
1499a747e4fSDavid du Colombier 	if(ifc == nil)
1509a747e4fSDavid du Colombier 		return;
1519a747e4fSDavid du Colombier 	for(; ifc; ifc = next){
1529a747e4fSDavid du Colombier 		next = ifc->next;
1539a747e4fSDavid du Colombier 		for(lifc = ifc->lifc; lifc; lifc = lnext){
1549a747e4fSDavid du Colombier 			lnext = lifc->next;
1559a747e4fSDavid du Colombier 			free(lifc);
1569a747e4fSDavid du Colombier 		}
1579a747e4fSDavid du Colombier 		free(ifc);
1589a747e4fSDavid du Colombier 	}
1599a747e4fSDavid du Colombier }
1609a747e4fSDavid du Colombier 
1617dd7cddfSDavid du Colombier Ipifc*
readipifc(char * net,Ipifc * ifc,int index)1629a747e4fSDavid du Colombier readipifc(char *net, Ipifc *ifc, int index)
1637dd7cddfSDavid du Colombier {
1647dd7cddfSDavid du Colombier 	int fd, i, n;
1659a747e4fSDavid du Colombier 	Dir *dir;
1667dd7cddfSDavid du Colombier 	char directory[128];
1677dd7cddfSDavid du Colombier 	char buf[128];
1689a747e4fSDavid du Colombier 	Ipifc **l;
1699a747e4fSDavid du Colombier 
1709a747e4fSDavid du Colombier 	_freeifc(ifc);
1717dd7cddfSDavid du Colombier 
1727dd7cddfSDavid du Colombier 	l = &ifc;
1739a747e4fSDavid du Colombier 	ifc = nil;
1747dd7cddfSDavid du Colombier 
1757dd7cddfSDavid du Colombier 	if(net == 0)
1767dd7cddfSDavid du Colombier 		net = "/net";
1777dd7cddfSDavid du Colombier 	snprint(directory, sizeof(directory), "%s/ipifc", net);
1789a747e4fSDavid du Colombier 
1799a747e4fSDavid du Colombier 	if(index >= 0){
1809a747e4fSDavid du Colombier 		snprint(buf, sizeof(buf), "%s/%d/status", directory, index);
1819a747e4fSDavid du Colombier 		_readipifc(buf, l, index);
1829a747e4fSDavid du Colombier 	} else {
1837dd7cddfSDavid du Colombier 		fd = open(directory, OREAD);
1847dd7cddfSDavid du Colombier 		if(fd < 0)
1859a747e4fSDavid du Colombier 			return nil;
1869a747e4fSDavid du Colombier 		n = dirreadall(fd, &dir);
1879a747e4fSDavid du Colombier 		close(fd);
1887dd7cddfSDavid du Colombier 
1897dd7cddfSDavid du Colombier 		for(i = 0; i < n; i++){
1907dd7cddfSDavid du Colombier 			if(strcmp(dir[i].name, "clone") == 0)
1917dd7cddfSDavid du Colombier 				continue;
1929a747e4fSDavid du Colombier 			if(strcmp(dir[i].name, "stats") == 0)
1939a747e4fSDavid du Colombier 				continue;
1947dd7cddfSDavid du Colombier 			snprint(buf, sizeof(buf), "%s/%s/status", directory, dir[i].name);
1957dd7cddfSDavid du Colombier 			l = _readipifc(buf, l, atoi(dir[i].name));
1967dd7cddfSDavid du Colombier 		}
1979a747e4fSDavid du Colombier 		free(dir);
1987dd7cddfSDavid du Colombier 	}
1997dd7cddfSDavid du Colombier 
2007dd7cddfSDavid du Colombier 	return ifc;
2017dd7cddfSDavid du Colombier }
202