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