xref: /plan9/sys/src/9/boot/bootip.c (revision 217e9e83c7f9cc6fb27d97dda90c8339b6f98728)
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];
8*217e9e83SDavid du Colombier static	uchar	auip[IPaddrlen];
97dd7cddfSDavid du Colombier static	char	mpoint[32];
107dd7cddfSDavid du Colombier 
117dd7cddfSDavid du Colombier static int isvalidip(uchar*);
12*217e9e83SDavid du Colombier static void getndbvar(char *name, uchar *var, char *prompt);
1367031067SDavid du Colombier 
147dd7cddfSDavid du Colombier void
configip(int bargc,char ** bargv,int needfs)1567031067SDavid du Colombier configip(int bargc, char **bargv, int needfs)
167dd7cddfSDavid du Colombier {
179a747e4fSDavid du Colombier 	Waitmsg *w;
18a23bc242SDavid du Colombier 	int argc, pid;
19*217e9e83SDavid du Colombier 	char **arg, **argv, *p;
207dd7cddfSDavid du Colombier 
219a747e4fSDavid du Colombier 	fmtinstall('I', eipfmt);
229a747e4fSDavid du Colombier 	fmtinstall('M', eipfmt);
239a747e4fSDavid du Colombier 	fmtinstall('E', eipfmt);
247dd7cddfSDavid du Colombier 
257dd7cddfSDavid du Colombier 	arg = malloc((bargc+1) * sizeof(char*));
267dd7cddfSDavid du Colombier 	if(arg == nil)
278c055935SDavid du Colombier 		fatal("malloc");
28a3b78ba5SDavid du Colombier 	memmove(arg, bargv, bargc * sizeof(char*));
29a3b78ba5SDavid du Colombier 	arg[bargc] = 0;
307dd7cddfSDavid du Colombier 
317dd7cddfSDavid du Colombier 	argc = bargc;
327dd7cddfSDavid du Colombier 	argv = arg;
337dd7cddfSDavid du Colombier 	strcpy(mpoint, "/net");
347dd7cddfSDavid du Colombier 	ARGBEGIN {
357dd7cddfSDavid du Colombier 	case 'x':
367dd7cddfSDavid du Colombier 		p = ARGF();
377dd7cddfSDavid du Colombier 		if(p != nil)
387dd7cddfSDavid du Colombier 			snprint(mpoint, sizeof(mpoint), "/net%s", p);
397dd7cddfSDavid du Colombier 		break;
407dd7cddfSDavid du Colombier 	case 'g':
417dd7cddfSDavid du Colombier 	case 'b':
427dd7cddfSDavid du Colombier 	case 'h':
437dd7cddfSDavid du Colombier 	case 'm':
447dd7cddfSDavid du Colombier 		p = ARGF();
457dd7cddfSDavid du Colombier 		USED(p);
467dd7cddfSDavid du Colombier 		break;
477dd7cddfSDavid du Colombier 	} ARGEND;
487dd7cddfSDavid du Colombier 
49*217e9e83SDavid du Colombier 	/* bind in an ip interface or two */
50*217e9e83SDavid du Colombier 	dprint("bind #I...");
51a23bc242SDavid du Colombier 	if(bind("#I", mpoint, MAFTER) < 0)
528c055935SDavid du Colombier 		fatal("bind #I");
53*217e9e83SDavid du Colombier 	dprint("bind #l0...");
54a23bc242SDavid du Colombier 	if(access("#l0", 0) == 0 && bind("#l0", mpoint, MAFTER) < 0)
558c055935SDavid du Colombier 		warning("bind #l0");
56*217e9e83SDavid du Colombier 	dprint("bind #l1...");
57a23bc242SDavid du Colombier 	if(access("#l1", 0) == 0 && bind("#l1", mpoint, MAFTER) < 0)
588c055935SDavid du Colombier 		warning("bind #l1");
59*217e9e83SDavid du Colombier 	dprint("bind #l2...");
60a23bc242SDavid du Colombier 	if(access("#l2", 0) == 0 && bind("#l2", mpoint, MAFTER) < 0)
618c055935SDavid du Colombier 		warning("bind #l2");
62*217e9e83SDavid du Colombier 	dprint("bind #l3...");
63a23bc242SDavid du Colombier 	if(access("#l3", 0) == 0 && bind("#l3", mpoint, MAFTER) < 0)
648c055935SDavid du Colombier 		warning("bind #l3");
65e5fc48fbSDavid du Colombier 	werrstr("");
667dd7cddfSDavid du Colombier 
67*217e9e83SDavid du Colombier 	/* let ipconfig configure the first ip interface */
687dd7cddfSDavid du Colombier 	switch(pid = fork()){
697dd7cddfSDavid du Colombier 	case -1:
7038ebe949SDavid du Colombier 		fatal("fork configuring ip: %r");
717dd7cddfSDavid du Colombier 	case 0:
72*217e9e83SDavid du Colombier 		dprint("starting ipconfig...");
736a9fc400SDavid du Colombier 		exec("/boot/ipconfig", arg);
7438ebe949SDavid du Colombier 		fatal("execing /boot/ipconfig: %r");
757dd7cddfSDavid du Colombier 	default:
767dd7cddfSDavid du Colombier 		break;
777dd7cddfSDavid du Colombier 	}
787dd7cddfSDavid du Colombier 
797dd7cddfSDavid du Colombier 	/* wait for ipconfig to finish */
80*217e9e83SDavid du Colombier 	dprint("waiting for dhcp...");
817dd7cddfSDavid du Colombier 	for(;;){
829a747e4fSDavid du Colombier 		w = wait();
839a747e4fSDavid du Colombier 		if(w != nil && w->pid == pid){
849a747e4fSDavid du Colombier 			if(w->msg[0] != 0)
859a747e4fSDavid du Colombier 				fatal(w->msg);
869a747e4fSDavid du Colombier 			free(w);
877dd7cddfSDavid du Colombier 			break;
889a747e4fSDavid du Colombier 		} else if(w == nil)
897dd7cddfSDavid du Colombier 			fatal("configuring ip");
909a747e4fSDavid du Colombier 		free(w);
917dd7cddfSDavid du Colombier 	}
92*217e9e83SDavid du Colombier 	dprint("\n");
937dd7cddfSDavid du Colombier 
94*217e9e83SDavid du Colombier 	if(needfs) {  /* if we didn't get a file and auth server, query user */
95*217e9e83SDavid du Colombier 		getndbvar("fs", fsip, "filesystem IP address");
96*217e9e83SDavid du Colombier 		getndbvar("auth", auip, "authentication server IP address");
977dd7cddfSDavid du Colombier 	}
987dd7cddfSDavid du Colombier }
997dd7cddfSDavid du Colombier 
1009a747e4fSDavid du Colombier static void
setauthaddr(char * proto,int port)1019a747e4fSDavid du Colombier setauthaddr(char *proto, int port)
1027dd7cddfSDavid du Colombier {
1039a747e4fSDavid du Colombier 	char buf[128];
1047dd7cddfSDavid du Colombier 
1059a747e4fSDavid du Colombier 	snprint(buf, sizeof buf, "%s!%I!%d", proto, auip, port);
1069a747e4fSDavid du Colombier 	authaddr = strdup(buf);
1077dd7cddfSDavid du Colombier }
1087dd7cddfSDavid du Colombier 
10980ee5cbfSDavid du Colombier void
configtcp(Method *)11080ee5cbfSDavid du Colombier configtcp(Method*)
11180ee5cbfSDavid du Colombier {
112*217e9e83SDavid du Colombier 	dprint("configip...");
11367031067SDavid du Colombier 	configip(bargc, bargv, 1);
114*217e9e83SDavid du Colombier 	dprint("setauthaddr...");
1159a747e4fSDavid du Colombier 	setauthaddr("tcp", 567);
11680ee5cbfSDavid du Colombier }
11780ee5cbfSDavid du Colombier 
11880ee5cbfSDavid du Colombier int
connecttcp(void)11980ee5cbfSDavid du Colombier connecttcp(void)
12080ee5cbfSDavid du Colombier {
12183030dd5SDavid du Colombier 	int fd;
1229a747e4fSDavid du Colombier 	char buf[64];
12380ee5cbfSDavid du Colombier 
1249a747e4fSDavid du Colombier 	snprint(buf, sizeof buf, "tcp!%I!564", fsip);
125*217e9e83SDavid du Colombier 	dprint("dial %s...", buf);
12683030dd5SDavid du Colombier 	fd = dial(buf, 0, 0, 0);
12783030dd5SDavid du Colombier 	if (fd < 0)
12883030dd5SDavid du Colombier 		werrstr("dial %s: %r", buf);
12983030dd5SDavid du Colombier 	return fd;
1309a747e4fSDavid du Colombier }
1319a747e4fSDavid du Colombier 
1327dd7cddfSDavid du Colombier static int
isvalidip(uchar * ip)1337dd7cddfSDavid du Colombier isvalidip(uchar *ip)
1347dd7cddfSDavid du Colombier {
1357dd7cddfSDavid du Colombier 	if(ipcmp(ip, IPnoaddr) == 0)
1367dd7cddfSDavid du Colombier 		return 0;
1377dd7cddfSDavid du Colombier 	if(ipcmp(ip, v4prefix) == 0)
1387dd7cddfSDavid du Colombier 		return 0;
1397dd7cddfSDavid du Colombier 	return 1;
1407dd7cddfSDavid du Colombier }
1417dd7cddfSDavid du Colombier 
1427dd7cddfSDavid du Colombier static void
netenv(char * attr,uchar * ip)14380ee5cbfSDavid du Colombier netenv(char *attr, uchar *ip)
14480ee5cbfSDavid du Colombier {
14580ee5cbfSDavid du Colombier 	int fd, n;
14680ee5cbfSDavid du Colombier 	char buf[128];
14780ee5cbfSDavid du Colombier 
14880ee5cbfSDavid du Colombier 	ipmove(ip, IPnoaddr);
14980ee5cbfSDavid du Colombier 	snprint(buf, sizeof(buf), "#e/%s", attr);
15080ee5cbfSDavid du Colombier 	fd = open(buf, OREAD);
15180ee5cbfSDavid du Colombier 	if(fd < 0)
15280ee5cbfSDavid du Colombier 		return;
15380ee5cbfSDavid du Colombier 
15480ee5cbfSDavid du Colombier 	n = read(fd, buf, sizeof(buf)-1);
155*217e9e83SDavid du Colombier 	close(fd);
15680ee5cbfSDavid du Colombier 	if(n <= 0)
15780ee5cbfSDavid du Colombier 		return;
15880ee5cbfSDavid du Colombier 	buf[n] = 0;
15983030dd5SDavid du Colombier 	if (parseip(ip, buf) == -1)
16083030dd5SDavid du Colombier 		fprint(2, "netenv: can't parse ip %s\n", buf);
16180ee5cbfSDavid du Colombier }
16280ee5cbfSDavid du Colombier 
16380ee5cbfSDavid du Colombier static void
netndb(char * attr,uchar * ip)1647dd7cddfSDavid du Colombier netndb(char *attr, uchar *ip)
1657dd7cddfSDavid du Colombier {
1667dd7cddfSDavid du Colombier 	int fd, n, c;
1677dd7cddfSDavid du Colombier 	char buf[1024];
1687dd7cddfSDavid du Colombier 	char *p;
1697dd7cddfSDavid du Colombier 
1707dd7cddfSDavid du Colombier 	ipmove(ip, IPnoaddr);
1717dd7cddfSDavid du Colombier 	snprint(buf, sizeof(buf), "%s/ndb", mpoint);
1727dd7cddfSDavid du Colombier 	fd = open(buf, OREAD);
1737dd7cddfSDavid du Colombier 	if(fd < 0)
1747dd7cddfSDavid du Colombier 		return;
1757dd7cddfSDavid du Colombier 	n = read(fd, buf, sizeof(buf)-1);
1767dd7cddfSDavid du Colombier 	close(fd);
1777dd7cddfSDavid du Colombier 	if(n <= 0)
1787dd7cddfSDavid du Colombier 		return;
1797dd7cddfSDavid du Colombier 	buf[n] = 0;
1807dd7cddfSDavid du Colombier 	n = strlen(attr);
18183030dd5SDavid du Colombier 	for(p = buf; ; p++){
1827dd7cddfSDavid du Colombier 		p = strstr(p, attr);
1837dd7cddfSDavid du Colombier 		if(p == nil)
1847dd7cddfSDavid du Colombier 			break;
1857dd7cddfSDavid du Colombier 		c = *(p-1);
1867dd7cddfSDavid du Colombier 		if(*(p + n) == '=' && (p == buf || c == '\n' || c == ' ' || c == '\t')){
1877dd7cddfSDavid du Colombier 			p += n+1;
18883030dd5SDavid du Colombier 			if (parseip(ip, p) == -1)
18983030dd5SDavid du Colombier 				fprint(2, "netndb: can't parse ip %s\n", p);
19080ee5cbfSDavid du Colombier 			return;
1917dd7cddfSDavid du Colombier 		}
1927dd7cddfSDavid du Colombier 	}
193*217e9e83SDavid du Colombier }
194*217e9e83SDavid du Colombier 
195*217e9e83SDavid du Colombier static void
getndbvar(char * name,uchar * var,char * prompt)196*217e9e83SDavid du Colombier getndbvar(char *name, uchar *var, char *prompt)
197*217e9e83SDavid du Colombier {
198*217e9e83SDavid du Colombier 	char buf[64];
199*217e9e83SDavid du Colombier 
200*217e9e83SDavid du Colombier 	netndb(name, var);
201*217e9e83SDavid du Colombier 	if(!isvalidip(var))
202*217e9e83SDavid du Colombier 		netenv(name, var);
203*217e9e83SDavid du Colombier 	while(!isvalidip(var)){
204*217e9e83SDavid du Colombier 		buf[0] = 0;
205*217e9e83SDavid du Colombier 		outin(prompt, buf, sizeof buf);
206*217e9e83SDavid du Colombier 		if (parseip(var, buf) == -1)
207*217e9e83SDavid du Colombier 			fprint(2, "configip: can't parse %s ip %s\n", name, buf);
208*217e9e83SDavid du Colombier 	}
2097dd7cddfSDavid du Colombier }
210