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