xref: /plan9-contrib/sys/src/9k/boot/bootip.c (revision 45a1df244aa549faca6f420494127e03a325d1ac)
19ef1f84bSDavid du Colombier #include <u.h>
29ef1f84bSDavid du Colombier #include <libc.h>
39ef1f84bSDavid du Colombier #include <ip.h>
49ef1f84bSDavid du Colombier 
59ef1f84bSDavid du Colombier #include "boot.h"
69ef1f84bSDavid du Colombier 
79ef1f84bSDavid du Colombier static	uchar	fsip[IPaddrlen];
8532111f7SDavid du Colombier static	uchar	auip[IPaddrlen];
99ef1f84bSDavid du Colombier static	char	mpoint[32];
109ef1f84bSDavid du Colombier 
119ef1f84bSDavid du Colombier static int isvalidip(uchar*);
12532111f7SDavid du Colombier static void getndbvar(char *name, uchar *var, char *prompt);
139ef1f84bSDavid du Colombier 
149ef1f84bSDavid du Colombier void
configip(int bargc,char ** bargv,int needfs)159ef1f84bSDavid du Colombier configip(int bargc, char **bargv, int needfs)
169ef1f84bSDavid du Colombier {
179ef1f84bSDavid du Colombier 	Waitmsg *w;
189ef1f84bSDavid du Colombier 	int argc, pid;
19532111f7SDavid du Colombier 	char **arg, **argv, *p;
209ef1f84bSDavid du Colombier 
219ef1f84bSDavid du Colombier 	fmtinstall('I', eipfmt);
229ef1f84bSDavid du Colombier 	fmtinstall('M', eipfmt);
239ef1f84bSDavid du Colombier 	fmtinstall('E', eipfmt);
249ef1f84bSDavid du Colombier 
259ef1f84bSDavid du Colombier 	arg = malloc((bargc+1) * sizeof(char*));
269ef1f84bSDavid du Colombier 	if(arg == nil)
279ef1f84bSDavid du Colombier 		fatal("malloc");
289ef1f84bSDavid du Colombier 	memmove(arg, bargv, bargc * sizeof(char*));
299ef1f84bSDavid du Colombier 	arg[bargc] = 0;
309ef1f84bSDavid du Colombier 
319ef1f84bSDavid du Colombier 	argc = bargc;
329ef1f84bSDavid du Colombier 	argv = arg;
331928e073SDavid du Colombier 	strncpy(mpoint, "/net", sizeof mpoint);
349ef1f84bSDavid du Colombier 	ARGBEGIN {
359ef1f84bSDavid du Colombier 	case 'x':
369ef1f84bSDavid du Colombier 		p = ARGF();
379ef1f84bSDavid du Colombier 		if(p != nil)
389ef1f84bSDavid du Colombier 			snprint(mpoint, sizeof(mpoint), "/net%s", p);
399ef1f84bSDavid du Colombier 		break;
409ef1f84bSDavid du Colombier 	case 'g':
419ef1f84bSDavid du Colombier 	case 'b':
429ef1f84bSDavid du Colombier 	case 'h':
439ef1f84bSDavid du Colombier 	case 'm':
449ef1f84bSDavid du Colombier 		p = ARGF();
459ef1f84bSDavid du Colombier 		USED(p);
469ef1f84bSDavid du Colombier 		break;
479ef1f84bSDavid du Colombier 	} ARGEND;
489ef1f84bSDavid du Colombier 
49532111f7SDavid du Colombier 	/* bind in an ip interface or two */
50532111f7SDavid du Colombier 	dprint("bind #I...");
519ef1f84bSDavid du Colombier 	if(bind("#I", mpoint, MAFTER) < 0)
52532111f7SDavid du Colombier 		fatal("bind #I");
53532111f7SDavid du Colombier 	dprint("bind #l0...");
54*45a1df24SDavid du Colombier 	if(access("#l0", AEXIST) == 0 && bind("#l0", mpoint, MAFTER) < 0)
55532111f7SDavid du Colombier 		warning("bind #l0");
56532111f7SDavid du Colombier 	dprint("bind #l1...");
57*45a1df24SDavid du Colombier 	if(access("#l1", AEXIST) == 0 && bind("#l1", mpoint, MAFTER) < 0)
58532111f7SDavid du Colombier 		warning("bind #l1");
59532111f7SDavid du Colombier 	dprint("bind #l2...");
60*45a1df24SDavid du Colombier 	if(access("#l2", AEXIST) == 0 && bind("#l2", mpoint, MAFTER) < 0)
61532111f7SDavid du Colombier 		warning("bind #l2");
62532111f7SDavid du Colombier 	dprint("bind #l3...");
63*45a1df24SDavid du Colombier 	if(access("#l3", AEXIST) == 0 && bind("#l3", mpoint, MAFTER) < 0)
64532111f7SDavid du Colombier 		warning("bind #l3");
659ef1f84bSDavid du Colombier 	werrstr("");
669ef1f84bSDavid du Colombier 
67532111f7SDavid du Colombier 	/* let ipconfig configure the first ip interface */
689ef1f84bSDavid du Colombier 	switch(pid = fork()){
699ef1f84bSDavid du Colombier 	case -1:
70532111f7SDavid du Colombier 		fatal("fork configuring ip: %r");
719ef1f84bSDavid du Colombier 	case 0:
72532111f7SDavid du Colombier 		dprint("starting ipconfig...");
739ef1f84bSDavid du Colombier 		exec("/boot/ipconfig", arg);
74532111f7SDavid du Colombier 		fatal("execing /boot/ipconfig: %r");
759ef1f84bSDavid du Colombier 	default:
769ef1f84bSDavid du Colombier 		break;
779ef1f84bSDavid du Colombier 	}
789ef1f84bSDavid du Colombier 
799ef1f84bSDavid du Colombier 	/* wait for ipconfig to finish */
80532111f7SDavid du Colombier 	dprint("waiting for dhcp...");
819ef1f84bSDavid du Colombier 	for(;;){
829ef1f84bSDavid du Colombier 		w = wait();
839ef1f84bSDavid du Colombier 		if(w != nil && w->pid == pid){
849ef1f84bSDavid du Colombier 			if(w->msg[0] != 0)
859ef1f84bSDavid du Colombier 				fatal(w->msg);
869ef1f84bSDavid du Colombier 			free(w);
879ef1f84bSDavid du Colombier 			break;
889ef1f84bSDavid du Colombier 		} else if(w == nil)
899ef1f84bSDavid du Colombier 			fatal("configuring ip");
909ef1f84bSDavid du Colombier 		free(w);
919ef1f84bSDavid du Colombier 	}
92532111f7SDavid du Colombier 	dprint("\n");
939ef1f84bSDavid du Colombier 
94532111f7SDavid du Colombier 	if(needfs) {  /* if we didn't get a file and auth server, query user */
95532111f7SDavid du Colombier 		getndbvar("fs", fsip, "filesystem IP address");
96532111f7SDavid du Colombier 		getndbvar("auth", auip, "authentication server IP address");
979ef1f84bSDavid du Colombier 	}
989ef1f84bSDavid du Colombier }
999ef1f84bSDavid du Colombier 
1009ef1f84bSDavid du Colombier static void
setauthaddr(char * proto,int port)1019ef1f84bSDavid du Colombier setauthaddr(char *proto, int port)
1029ef1f84bSDavid du Colombier {
1039ef1f84bSDavid du Colombier 	char buf[128];
1049ef1f84bSDavid du Colombier 
1059ef1f84bSDavid du Colombier 	snprint(buf, sizeof buf, "%s!%I!%d", proto, auip, port);
1069ef1f84bSDavid du Colombier 	authaddr = strdup(buf);
1079ef1f84bSDavid du Colombier }
1089ef1f84bSDavid du Colombier 
1099ef1f84bSDavid du Colombier void
configtcp(Method *)1109ef1f84bSDavid du Colombier configtcp(Method*)
1119ef1f84bSDavid du Colombier {
112532111f7SDavid du Colombier 	dprint("configip...");
1139ef1f84bSDavid du Colombier 	configip(bargc, bargv, 1);
114532111f7SDavid du Colombier 	dprint("setauthaddr...");
1159ef1f84bSDavid du Colombier 	setauthaddr("tcp", 567);
1169ef1f84bSDavid du Colombier }
1179ef1f84bSDavid du Colombier 
1189ef1f84bSDavid du Colombier int
connecttcp(void)1199ef1f84bSDavid du Colombier connecttcp(void)
1209ef1f84bSDavid du Colombier {
1219ef1f84bSDavid du Colombier 	int fd;
1229ef1f84bSDavid du Colombier 	char buf[64];
1239ef1f84bSDavid du Colombier 
1249ef1f84bSDavid du Colombier 	snprint(buf, sizeof buf, "tcp!%I!564", fsip);
125532111f7SDavid du Colombier 	dprint("dial %s...", buf);
1269ef1f84bSDavid du Colombier 	fd = dial(buf, 0, 0, 0);
1279ef1f84bSDavid du Colombier 	if (fd < 0)
1289ef1f84bSDavid du Colombier 		werrstr("dial %s: %r", buf);
1299ef1f84bSDavid du Colombier 	return fd;
1309ef1f84bSDavid du Colombier }
1319ef1f84bSDavid du Colombier 
1329ef1f84bSDavid du Colombier static int
isvalidip(uchar * ip)1339ef1f84bSDavid du Colombier isvalidip(uchar *ip)
1349ef1f84bSDavid du Colombier {
1359ef1f84bSDavid du Colombier 	if(ipcmp(ip, IPnoaddr) == 0)
1369ef1f84bSDavid du Colombier 		return 0;
1379ef1f84bSDavid du Colombier 	if(ipcmp(ip, v4prefix) == 0)
1389ef1f84bSDavid du Colombier 		return 0;
1399ef1f84bSDavid du Colombier 	return 1;
1409ef1f84bSDavid du Colombier }
1419ef1f84bSDavid du Colombier 
1429ef1f84bSDavid du Colombier static void
netenv(char * attr,uchar * ip)1439ef1f84bSDavid du Colombier netenv(char *attr, uchar *ip)
1449ef1f84bSDavid du Colombier {
1459ef1f84bSDavid du Colombier 	int fd, n;
1469ef1f84bSDavid du Colombier 	char buf[128];
1479ef1f84bSDavid du Colombier 
1489ef1f84bSDavid du Colombier 	ipmove(ip, IPnoaddr);
1499ef1f84bSDavid du Colombier 	snprint(buf, sizeof(buf), "#e/%s", attr);
1509ef1f84bSDavid du Colombier 	fd = open(buf, OREAD);
1519ef1f84bSDavid du Colombier 	if(fd < 0)
1529ef1f84bSDavid du Colombier 		return;
1539ef1f84bSDavid du Colombier 
1549ef1f84bSDavid du Colombier 	n = read(fd, buf, sizeof(buf)-1);
155532111f7SDavid du Colombier 	close(fd);
1569ef1f84bSDavid du Colombier 	if(n <= 0)
1579ef1f84bSDavid du Colombier 		return;
1589ef1f84bSDavid du Colombier 	buf[n] = 0;
1599ef1f84bSDavid du Colombier 	if (parseip(ip, buf) == -1)
1609ef1f84bSDavid du Colombier 		fprint(2, "netenv: can't parse ip %s\n", buf);
1619ef1f84bSDavid du Colombier }
1629ef1f84bSDavid du Colombier 
1639ef1f84bSDavid du Colombier static void
netndb(char * attr,uchar * ip)1649ef1f84bSDavid du Colombier netndb(char *attr, uchar *ip)
1659ef1f84bSDavid du Colombier {
1669ef1f84bSDavid du Colombier 	int fd, n, c;
1679ef1f84bSDavid du Colombier 	char buf[1024];
1689ef1f84bSDavid du Colombier 	char *p;
1699ef1f84bSDavid du Colombier 
1709ef1f84bSDavid du Colombier 	ipmove(ip, IPnoaddr);
1719ef1f84bSDavid du Colombier 	snprint(buf, sizeof(buf), "%s/ndb", mpoint);
1729ef1f84bSDavid du Colombier 	fd = open(buf, OREAD);
1739ef1f84bSDavid du Colombier 	if(fd < 0)
1749ef1f84bSDavid du Colombier 		return;
1759ef1f84bSDavid du Colombier 	n = read(fd, buf, sizeof(buf)-1);
1769ef1f84bSDavid du Colombier 	close(fd);
1779ef1f84bSDavid du Colombier 	if(n <= 0)
1789ef1f84bSDavid du Colombier 		return;
1799ef1f84bSDavid du Colombier 	buf[n] = 0;
1809ef1f84bSDavid du Colombier 	n = strlen(attr);
1819ef1f84bSDavid du Colombier 	for(p = buf; ; p++){
1829ef1f84bSDavid du Colombier 		p = strstr(p, attr);
1839ef1f84bSDavid du Colombier 		if(p == nil)
1849ef1f84bSDavid du Colombier 			break;
1859ef1f84bSDavid du Colombier 		c = *(p-1);
1869ef1f84bSDavid du Colombier 		if(*(p + n) == '=' && (p == buf || c == '\n' || c == ' ' || c == '\t')){
1879ef1f84bSDavid du Colombier 			p += n+1;
1889ef1f84bSDavid du Colombier 			if (parseip(ip, p) == -1)
1899ef1f84bSDavid du Colombier 				fprint(2, "netndb: can't parse ip %s\n", p);
1909ef1f84bSDavid du Colombier 			return;
1919ef1f84bSDavid du Colombier 		}
1929ef1f84bSDavid du Colombier 	}
193532111f7SDavid du Colombier }
194532111f7SDavid du Colombier 
195532111f7SDavid du Colombier static void
getndbvar(char * name,uchar * var,char * prompt)196532111f7SDavid du Colombier getndbvar(char *name, uchar *var, char *prompt)
197532111f7SDavid du Colombier {
198532111f7SDavid du Colombier 	char buf[64];
199532111f7SDavid du Colombier 
200532111f7SDavid du Colombier 	netndb(name, var);
201532111f7SDavid du Colombier 	if(!isvalidip(var))
202532111f7SDavid du Colombier 		netenv(name, var);
203532111f7SDavid du Colombier 	while(!isvalidip(var)){
204532111f7SDavid du Colombier 		buf[0] = 0;
205532111f7SDavid du Colombier 		outin(prompt, buf, sizeof buf);
206532111f7SDavid du Colombier 		if (parseip(var, buf) == -1)
207532111f7SDavid du Colombier 			fprint(2, "configip: can't parse %s ip %s\n", name, buf);
208532111f7SDavid du Colombier 	}
2099ef1f84bSDavid du Colombier }
210