xref: /plan9/sys/src/9/boot/bootip.c (revision a23bc242239d04784669e65edcfd537bcc267e00)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <ip.h>
47dd7cddfSDavid du Colombier 
57dd7cddfSDavid du Colombier #include "boot.h"
67dd7cddfSDavid du Colombier 
77dd7cddfSDavid du Colombier static	uchar	fsip[IPaddrlen];
89a747e4fSDavid du Colombier 	uchar	auip[IPaddrlen];
97dd7cddfSDavid du Colombier static	char	mpoint[32];
107dd7cddfSDavid du Colombier 
117dd7cddfSDavid du Colombier static int isvalidip(uchar*);
127dd7cddfSDavid du Colombier static void netndb(char*, uchar*);
1380ee5cbfSDavid du Colombier static void netenv(char*, uchar*);
147dd7cddfSDavid du Colombier 
1567031067SDavid du Colombier 
167dd7cddfSDavid du Colombier void
1767031067SDavid du Colombier configip(int bargc, char **bargv, int needfs)
187dd7cddfSDavid du Colombier {
199a747e4fSDavid du Colombier 	Waitmsg *w;
20*a23bc242SDavid du Colombier 	int argc, pid;
21*a23bc242SDavid du Colombier 	char **arg, **argv, buf[32], *p;
227dd7cddfSDavid du Colombier 
239a747e4fSDavid du Colombier 	fmtinstall('I', eipfmt);
249a747e4fSDavid du Colombier 	fmtinstall('M', eipfmt);
259a747e4fSDavid du Colombier 	fmtinstall('E', eipfmt);
267dd7cddfSDavid du Colombier 
277dd7cddfSDavid du Colombier 	arg = malloc((bargc+1) * sizeof(char*));
287dd7cddfSDavid du Colombier 	if(arg == nil)
29*a23bc242SDavid du Colombier 		fatal("%r");
30a3b78ba5SDavid du Colombier 	memmove(arg, bargv, bargc * sizeof(char*));
31a3b78ba5SDavid du Colombier 	arg[bargc] = 0;
327dd7cddfSDavid du Colombier 
337dd7cddfSDavid du Colombier 	argc = bargc;
347dd7cddfSDavid du Colombier 	argv = arg;
357dd7cddfSDavid du Colombier 	strcpy(mpoint, "/net");
367dd7cddfSDavid du Colombier 	ARGBEGIN {
377dd7cddfSDavid du Colombier 	case 'x':
387dd7cddfSDavid du Colombier 		p = ARGF();
397dd7cddfSDavid du Colombier 		if(p != nil)
407dd7cddfSDavid du Colombier 			snprint(mpoint, sizeof(mpoint), "/net%s", p);
417dd7cddfSDavid du Colombier 		break;
427dd7cddfSDavid du Colombier 	case 'g':
437dd7cddfSDavid du Colombier 	case 'b':
447dd7cddfSDavid du Colombier 	case 'h':
457dd7cddfSDavid du Colombier 	case 'm':
467dd7cddfSDavid du Colombier 		p = ARGF();
477dd7cddfSDavid du Colombier 		USED(p);
487dd7cddfSDavid du Colombier 		break;
497dd7cddfSDavid du Colombier 	} ARGEND;
507dd7cddfSDavid du Colombier 
517dd7cddfSDavid du Colombier 	/* bind in an ip interface */
52*a23bc242SDavid du Colombier 	if(bind("#I", mpoint, MAFTER) < 0)
53*a23bc242SDavid du Colombier 		fatal("bind #I: %r\n");
54*a23bc242SDavid du Colombier 	if(access("#l0", 0) == 0 && bind("#l0", mpoint, MAFTER) < 0)
55*a23bc242SDavid du Colombier 		print("bind #l0: %r\n");
56*a23bc242SDavid du Colombier 	if(access("#l1", 0) == 0 && bind("#l1", mpoint, MAFTER) < 0)
57*a23bc242SDavid du Colombier 		print("bind #l1: %r\n");
58*a23bc242SDavid du Colombier 	if(access("#l2", 0) == 0 && bind("#l2", mpoint, MAFTER) < 0)
59*a23bc242SDavid du Colombier 		print("bind #l2: %r\n");
60*a23bc242SDavid du Colombier 	if(access("#l3", 0) == 0 && bind("#l3", mpoint, MAFTER) < 0)
61*a23bc242SDavid du Colombier 		print("bind #l3: %r\n");
62e5fc48fbSDavid du Colombier 	werrstr("");
637dd7cddfSDavid du Colombier 
647dd7cddfSDavid du Colombier 	/* let ipconfig configure the ip interface */
657dd7cddfSDavid du Colombier 	switch(pid = fork()){
667dd7cddfSDavid du Colombier 	case -1:
67*a23bc242SDavid du Colombier 		fatal("configuring ip: %r");
687dd7cddfSDavid du Colombier 	case 0:
696a9fc400SDavid du Colombier 		exec("/boot/ipconfig", arg);
707dd7cddfSDavid du Colombier 		fatal("execing /ipconfig");
717dd7cddfSDavid du Colombier 	default:
727dd7cddfSDavid du Colombier 		break;
737dd7cddfSDavid du Colombier 	}
747dd7cddfSDavid du Colombier 
757dd7cddfSDavid du Colombier 	/* wait for ipconfig to finish */
767dd7cddfSDavid du Colombier 	for(;;){
779a747e4fSDavid du Colombier 		w = wait();
789a747e4fSDavid du Colombier 		if(w != nil && w->pid == pid){
799a747e4fSDavid du Colombier 			if(w->msg[0] != 0)
809a747e4fSDavid du Colombier 				fatal(w->msg);
819a747e4fSDavid du Colombier 			free(w);
827dd7cddfSDavid du Colombier 			break;
839a747e4fSDavid du Colombier 		} else if(w == nil)
847dd7cddfSDavid du Colombier 			fatal("configuring ip");
859a747e4fSDavid du Colombier 		free(w);
867dd7cddfSDavid du Colombier 	}
877dd7cddfSDavid du Colombier 
8867031067SDavid du Colombier 	if(!needfs)
8967031067SDavid du Colombier 		return;
9067031067SDavid du Colombier 
917dd7cddfSDavid du Colombier 	/* if we didn't get a file and auth server, query user */
927dd7cddfSDavid du Colombier 	netndb("fs", fsip);
9380ee5cbfSDavid du Colombier 	if(!isvalidip(fsip))
9480ee5cbfSDavid du Colombier 		netenv("fs", fsip);
9580ee5cbfSDavid du Colombier 	while(!isvalidip(fsip)){
967dd7cddfSDavid du Colombier 		buf[0] = 0;
977dd7cddfSDavid du Colombier 		outin("filesystem IP address", buf, sizeof(buf));
9883030dd5SDavid du Colombier 		if (parseip(fsip, buf) == -1)
9983030dd5SDavid du Colombier 			fprint(2, "configip: can't parse fs ip %s\n", buf);
1007dd7cddfSDavid du Colombier 	}
10180ee5cbfSDavid du Colombier 
10280ee5cbfSDavid du Colombier 	netndb("auth", auip);
10380ee5cbfSDavid du Colombier 	if(!isvalidip(auip))
10480ee5cbfSDavid du Colombier 		netenv("auth", auip);
10580ee5cbfSDavid du Colombier 	while(!isvalidip(auip)){
1067dd7cddfSDavid du Colombier 		buf[0] = 0;
1077dd7cddfSDavid du Colombier 		outin("authentication server IP address", buf, sizeof(buf));
10883030dd5SDavid du Colombier 		if (parseip(auip, buf) == -1)
10983030dd5SDavid du Colombier 			fprint(2, "configip: can't parse auth ip %s\n", buf);
1107dd7cddfSDavid du Colombier 	}
1117dd7cddfSDavid du Colombier }
1127dd7cddfSDavid du Colombier 
1139a747e4fSDavid du Colombier static void
1149a747e4fSDavid du Colombier setauthaddr(char *proto, int port)
1157dd7cddfSDavid du Colombier {
1169a747e4fSDavid du Colombier 	char buf[128];
1177dd7cddfSDavid du Colombier 
1189a747e4fSDavid du Colombier 	snprint(buf, sizeof buf, "%s!%I!%d", proto, auip, port);
1199a747e4fSDavid du Colombier 	authaddr = strdup(buf);
1207dd7cddfSDavid du Colombier }
1217dd7cddfSDavid du Colombier 
12280ee5cbfSDavid du Colombier void
12380ee5cbfSDavid du Colombier configtcp(Method*)
12480ee5cbfSDavid du Colombier {
12567031067SDavid du Colombier 	configip(bargc, bargv, 1);
1269a747e4fSDavid du Colombier 	setauthaddr("tcp", 567);
12780ee5cbfSDavid du Colombier }
12880ee5cbfSDavid du Colombier 
12980ee5cbfSDavid du Colombier int
13080ee5cbfSDavid du Colombier connecttcp(void)
13180ee5cbfSDavid du Colombier {
13283030dd5SDavid du Colombier 	int fd;
1339a747e4fSDavid du Colombier 	char buf[64];
13480ee5cbfSDavid du Colombier 
1359a747e4fSDavid du Colombier 	snprint(buf, sizeof buf, "tcp!%I!564", fsip);
13683030dd5SDavid du Colombier 	fd = dial(buf, 0, 0, 0);
13783030dd5SDavid du Colombier 	if (fd < 0)
13883030dd5SDavid du Colombier 		werrstr("dial %s: %r", buf);
13983030dd5SDavid du Colombier 	return fd;
1409a747e4fSDavid du Colombier }
1419a747e4fSDavid du Colombier 
1427dd7cddfSDavid du Colombier static int
1437dd7cddfSDavid du Colombier isvalidip(uchar *ip)
1447dd7cddfSDavid du Colombier {
1457dd7cddfSDavid du Colombier 	if(ipcmp(ip, IPnoaddr) == 0)
1467dd7cddfSDavid du Colombier 		return 0;
1477dd7cddfSDavid du Colombier 	if(ipcmp(ip, v4prefix) == 0)
1487dd7cddfSDavid du Colombier 		return 0;
1497dd7cddfSDavid du Colombier 	return 1;
1507dd7cddfSDavid du Colombier }
1517dd7cddfSDavid du Colombier 
1527dd7cddfSDavid du Colombier static void
15380ee5cbfSDavid du Colombier netenv(char *attr, uchar *ip)
15480ee5cbfSDavid du Colombier {
15580ee5cbfSDavid du Colombier 	int fd, n;
15680ee5cbfSDavid du Colombier 	char buf[128];
15780ee5cbfSDavid du Colombier 
15880ee5cbfSDavid du Colombier 	ipmove(ip, IPnoaddr);
15980ee5cbfSDavid du Colombier 	snprint(buf, sizeof(buf), "#e/%s", attr);
16080ee5cbfSDavid du Colombier 	fd = open(buf, OREAD);
16180ee5cbfSDavid du Colombier 	if(fd < 0)
16280ee5cbfSDavid du Colombier 		return;
16380ee5cbfSDavid du Colombier 
16480ee5cbfSDavid du Colombier 	n = read(fd, buf, sizeof(buf)-1);
16580ee5cbfSDavid du Colombier 	if(n <= 0)
16680ee5cbfSDavid du Colombier 		return;
16780ee5cbfSDavid du Colombier 	buf[n] = 0;
16883030dd5SDavid du Colombier 	if (parseip(ip, buf) == -1)
16983030dd5SDavid du Colombier 		fprint(2, "netenv: can't parse ip %s\n", buf);
17080ee5cbfSDavid du Colombier }
17180ee5cbfSDavid du Colombier 
17280ee5cbfSDavid du Colombier static void
1737dd7cddfSDavid du Colombier netndb(char *attr, uchar *ip)
1747dd7cddfSDavid du Colombier {
1757dd7cddfSDavid du Colombier 	int fd, n, c;
1767dd7cddfSDavid du Colombier 	char buf[1024];
1777dd7cddfSDavid du Colombier 	char *p;
1787dd7cddfSDavid du Colombier 
1797dd7cddfSDavid du Colombier 	ipmove(ip, IPnoaddr);
1807dd7cddfSDavid du Colombier 	snprint(buf, sizeof(buf), "%s/ndb", mpoint);
1817dd7cddfSDavid du Colombier 	fd = open(buf, OREAD);
1827dd7cddfSDavid du Colombier 	if(fd < 0)
1837dd7cddfSDavid du Colombier 		return;
1847dd7cddfSDavid du Colombier 	n = read(fd, buf, sizeof(buf)-1);
1857dd7cddfSDavid du Colombier 	close(fd);
1867dd7cddfSDavid du Colombier 	if(n <= 0)
1877dd7cddfSDavid du Colombier 		return;
1887dd7cddfSDavid du Colombier 	buf[n] = 0;
1897dd7cddfSDavid du Colombier 	n = strlen(attr);
19083030dd5SDavid du Colombier 	for(p = buf; ; p++){
1917dd7cddfSDavid du Colombier 		p = strstr(p, attr);
1927dd7cddfSDavid du Colombier 		if(p == nil)
1937dd7cddfSDavid du Colombier 			break;
1947dd7cddfSDavid du Colombier 		c = *(p-1);
1957dd7cddfSDavid du Colombier 		if(*(p + n) == '=' && (p == buf || c == '\n' || c == ' ' || c == '\t')){
1967dd7cddfSDavid du Colombier 			p += n+1;
19783030dd5SDavid du Colombier 			if (parseip(ip, p) == -1)
19883030dd5SDavid du Colombier 				fprint(2, "netndb: can't parse ip %s\n", p);
19980ee5cbfSDavid du Colombier 			return;
2007dd7cddfSDavid du Colombier 		}
2017dd7cddfSDavid du Colombier 	}
20280ee5cbfSDavid du Colombier 	return;
2037dd7cddfSDavid du Colombier }
204