xref: /plan9/sys/src/9/boot/bootip.c (revision 217e9e83c7f9cc6fb27d97dda90c8339b6f98728)
1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 
5 #include "boot.h"
6 
7 static	uchar	fsip[IPaddrlen];
8 static	uchar	auip[IPaddrlen];
9 static	char	mpoint[32];
10 
11 static int isvalidip(uchar*);
12 static void getndbvar(char *name, uchar *var, char *prompt);
13 
14 void
configip(int bargc,char ** bargv,int needfs)15 configip(int bargc, char **bargv, int needfs)
16 {
17 	Waitmsg *w;
18 	int argc, pid;
19 	char **arg, **argv, *p;
20 
21 	fmtinstall('I', eipfmt);
22 	fmtinstall('M', eipfmt);
23 	fmtinstall('E', eipfmt);
24 
25 	arg = malloc((bargc+1) * sizeof(char*));
26 	if(arg == nil)
27 		fatal("malloc");
28 	memmove(arg, bargv, bargc * sizeof(char*));
29 	arg[bargc] = 0;
30 
31 	argc = bargc;
32 	argv = arg;
33 	strcpy(mpoint, "/net");
34 	ARGBEGIN {
35 	case 'x':
36 		p = ARGF();
37 		if(p != nil)
38 			snprint(mpoint, sizeof(mpoint), "/net%s", p);
39 		break;
40 	case 'g':
41 	case 'b':
42 	case 'h':
43 	case 'm':
44 		p = ARGF();
45 		USED(p);
46 		break;
47 	} ARGEND;
48 
49 	/* bind in an ip interface or two */
50 	dprint("bind #I...");
51 	if(bind("#I", mpoint, MAFTER) < 0)
52 		fatal("bind #I");
53 	dprint("bind #l0...");
54 	if(access("#l0", 0) == 0 && bind("#l0", mpoint, MAFTER) < 0)
55 		warning("bind #l0");
56 	dprint("bind #l1...");
57 	if(access("#l1", 0) == 0 && bind("#l1", mpoint, MAFTER) < 0)
58 		warning("bind #l1");
59 	dprint("bind #l2...");
60 	if(access("#l2", 0) == 0 && bind("#l2", mpoint, MAFTER) < 0)
61 		warning("bind #l2");
62 	dprint("bind #l3...");
63 	if(access("#l3", 0) == 0 && bind("#l3", mpoint, MAFTER) < 0)
64 		warning("bind #l3");
65 	werrstr("");
66 
67 	/* let ipconfig configure the first ip interface */
68 	switch(pid = fork()){
69 	case -1:
70 		fatal("fork configuring ip: %r");
71 	case 0:
72 		dprint("starting ipconfig...");
73 		exec("/boot/ipconfig", arg);
74 		fatal("execing /boot/ipconfig: %r");
75 	default:
76 		break;
77 	}
78 
79 	/* wait for ipconfig to finish */
80 	dprint("waiting for dhcp...");
81 	for(;;){
82 		w = wait();
83 		if(w != nil && w->pid == pid){
84 			if(w->msg[0] != 0)
85 				fatal(w->msg);
86 			free(w);
87 			break;
88 		} else if(w == nil)
89 			fatal("configuring ip");
90 		free(w);
91 	}
92 	dprint("\n");
93 
94 	if(needfs) {  /* if we didn't get a file and auth server, query user */
95 		getndbvar("fs", fsip, "filesystem IP address");
96 		getndbvar("auth", auip, "authentication server IP address");
97 	}
98 }
99 
100 static void
setauthaddr(char * proto,int port)101 setauthaddr(char *proto, int port)
102 {
103 	char buf[128];
104 
105 	snprint(buf, sizeof buf, "%s!%I!%d", proto, auip, port);
106 	authaddr = strdup(buf);
107 }
108 
109 void
configtcp(Method *)110 configtcp(Method*)
111 {
112 	dprint("configip...");
113 	configip(bargc, bargv, 1);
114 	dprint("setauthaddr...");
115 	setauthaddr("tcp", 567);
116 }
117 
118 int
connecttcp(void)119 connecttcp(void)
120 {
121 	int fd;
122 	char buf[64];
123 
124 	snprint(buf, sizeof buf, "tcp!%I!564", fsip);
125 	dprint("dial %s...", buf);
126 	fd = dial(buf, 0, 0, 0);
127 	if (fd < 0)
128 		werrstr("dial %s: %r", buf);
129 	return fd;
130 }
131 
132 static int
isvalidip(uchar * ip)133 isvalidip(uchar *ip)
134 {
135 	if(ipcmp(ip, IPnoaddr) == 0)
136 		return 0;
137 	if(ipcmp(ip, v4prefix) == 0)
138 		return 0;
139 	return 1;
140 }
141 
142 static void
netenv(char * attr,uchar * ip)143 netenv(char *attr, uchar *ip)
144 {
145 	int fd, n;
146 	char buf[128];
147 
148 	ipmove(ip, IPnoaddr);
149 	snprint(buf, sizeof(buf), "#e/%s", attr);
150 	fd = open(buf, OREAD);
151 	if(fd < 0)
152 		return;
153 
154 	n = read(fd, buf, sizeof(buf)-1);
155 	close(fd);
156 	if(n <= 0)
157 		return;
158 	buf[n] = 0;
159 	if (parseip(ip, buf) == -1)
160 		fprint(2, "netenv: can't parse ip %s\n", buf);
161 }
162 
163 static void
netndb(char * attr,uchar * ip)164 netndb(char *attr, uchar *ip)
165 {
166 	int fd, n, c;
167 	char buf[1024];
168 	char *p;
169 
170 	ipmove(ip, IPnoaddr);
171 	snprint(buf, sizeof(buf), "%s/ndb", mpoint);
172 	fd = open(buf, OREAD);
173 	if(fd < 0)
174 		return;
175 	n = read(fd, buf, sizeof(buf)-1);
176 	close(fd);
177 	if(n <= 0)
178 		return;
179 	buf[n] = 0;
180 	n = strlen(attr);
181 	for(p = buf; ; p++){
182 		p = strstr(p, attr);
183 		if(p == nil)
184 			break;
185 		c = *(p-1);
186 		if(*(p + n) == '=' && (p == buf || c == '\n' || c == ' ' || c == '\t')){
187 			p += n+1;
188 			if (parseip(ip, p) == -1)
189 				fprint(2, "netndb: can't parse ip %s\n", p);
190 			return;
191 		}
192 	}
193 }
194 
195 static void
getndbvar(char * name,uchar * var,char * prompt)196 getndbvar(char *name, uchar *var, char *prompt)
197 {
198 	char buf[64];
199 
200 	netndb(name, var);
201 	if(!isvalidip(var))
202 		netenv(name, var);
203 	while(!isvalidip(var)){
204 		buf[0] = 0;
205 		outin(prompt, buf, sizeof buf);
206 		if (parseip(var, buf) == -1)
207 			fprint(2, "configip: can't parse %s ip %s\n", name, buf);
208 	}
209 }
210