]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/sysinstall/network.c
Mount devfs with nmount(2) instead of mount(2). This error was masked
[FreeBSD/FreeBSD.git] / usr.sbin / sysinstall / network.c
1 /*
2  * The new sysinstall program.
3  *
4  * This is probably the last attempt in the `sysinstall' line, the next
5  * generation being slated to essentially a complete rewrite.
6  *
7  * $FreeBSD$
8  *
9  * Copyright (c) 1995
10  *      Jordan Hubbard.  All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer,
17  *    verbatim and that no modifications are made prior to this
18  *    point in the file.
19  *
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  */
37
38 /* These routines deal with getting things off of network media */
39
40 #include "sysinstall.h"
41 #include <signal.h>
42 #include <termios.h>
43 #include <sys/fcntl.h>
44 #include <sys/ioctl.h>
45 #include <sys/stat.h>
46
47 static Boolean  networkInitialized;
48 static pid_t    startPPP(Device *devp);
49
50 static pid_t    pppPID;
51
52 Boolean
53 mediaInitNetwork(Device *dev)
54 {
55     int i;
56     char *rp;
57     char *cp, ifconfig[255];
58     WINDOW *w;
59     
60     if (!RunningAsInit || networkInitialized)
61         return TRUE;
62
63     if (isDebug())
64         msgDebug("Init routine called for network device %s.\n", dev->name);
65
66     if (!file_readable("/etc/resolv.conf")) {
67         if (DITEM_STATUS(configResolv(NULL)) == DITEM_FAILURE) {
68             msgConfirm("Can't seem to write out /etc/resolv.conf.  Net cannot be used.");
69             return FALSE;
70         }
71     }
72
73     w = savescr();
74     dialog_clear_norefresh();
75
76     /* Old PPP process lying around? */
77     if (pppPID) {
78         msgConfirm("Killing previous PPP process %d.", pppPID);
79         kill(pppPID, SIGTERM);
80         pppPID = 0;
81     }
82     if (!strncmp("ppp", dev->name, 3)) {        /* PPP? */
83         if (!(pppPID = startPPP(dev))) {
84             msgConfirm("Unable to start PPP!  This installation method cannot be used.");
85             return FALSE;
86         }
87         networkInitialized = TRUE;
88         return TRUE;
89     }
90     else if (!strncmp("sl", dev->name, 2)) {    /* SLIP? */
91         char *val;
92         char attach[256];
93
94         /* Cheesy slip attach */
95         snprintf(attach, 256, "slattach -a -h -l -s 9600 %s", dev->devname);
96         val = msgGetInput(attach,
97                           "Warning:  SLIP is rather poorly supported in this revision\n"
98                           "of the installation due to the lack of a dialing utility.\n"
99                           "If you can use PPP for this instead then you're much better\n"
100                           "off doing so, otherwise SLIP works fairly well for *hardwired*\n"
101                           "links.  Please edit the following slattach command for\n"
102                           "correctness (default here is: VJ compression, Hardware flow-\n"
103                           "control, ignore carrier and 9600 baud data rate).  When you're\n"
104                           "ready, press [ENTER] to execute it.");
105         if (!val) {
106             msgConfirm("slattach command was empty.  Try again!");
107             restorescr(w);
108             return FALSE;
109         }
110         else
111             SAFE_STRCPY(attach, val);
112         /*
113          * Doing this with vsystem() is actually bogus since we should be storing the pid of slattach
114          * for later killing.  It's just too convenient to call vsystem(), however, rather than
115          * constructing a proper argument for exec() so we punt on doing slip right for now.
116          */
117         if (vsystem("%s", attach)) {
118             msgConfirm("slattach returned a bad status!  Please verify that\n"
119                        "the command is correct and try this operation again.");
120             restorescr(w);
121             return FALSE;
122         }
123         restorescr(w);
124     }
125
126     snprintf(ifconfig, 255, "%s%s", VAR_IFCONFIG, dev->name);
127     cp = variable_get(ifconfig);
128     if (cp) {
129         if (strcmp(cp, "DHCP")) {
130             msgDebug("ifconfig %s %s\n", dev->name, cp);
131             i = vsystem("ifconfig %s %s", dev->name, cp);
132             if (i) {
133                 msgConfirm("Unable to configure the %s interface!\n"
134                            "This installation method cannot be used.",
135                            dev->name);
136                 return FALSE;
137             }
138             rp = variable_get(VAR_GATEWAY);
139             if (!rp || *rp == '0') {
140                 msgConfirm("No gateway has been set. You may be unable to access hosts\n"
141                            "not on your local network");
142             }
143             else {
144                 msgDebug("Adding default route to %s.\n", rp);
145                 vsystem("route -n add default %s", rp);
146             }
147         }
148     } else if ((cp = variable_get(VAR_IPV6ADDR)) == NULL || *cp == '\0') {
149         msgConfirm("The %s device is not configured.  You will need to do so\n"
150                    "in the Networking configuration menu before proceeding.", dev->name);
151         return FALSE;
152     }
153
154     if (isDebug())
155         msgDebug("Network initialized successfully.\n");
156     networkInitialized = TRUE;
157     return TRUE;
158 }
159
160 void
161 mediaShutdownNetwork(Device *dev)
162 {
163     char *cp;
164
165     if (!RunningAsInit || !networkInitialized)
166         return;
167
168     msgDebug("Shutdown called for network device %s\n", dev->name);
169     /* Not a serial device? */
170     if (strncmp("sl", dev->name, 2) && strncmp("ppp", dev->name, 3)) {
171         int i;
172         char ifconfig[255];
173
174         snprintf(ifconfig, 255, "%s%s", VAR_IFCONFIG, dev->name);
175         cp = variable_get(ifconfig);
176         if (!cp)
177             return;
178         msgDebug("ifconfig %s down\n", dev->name);
179         i = vsystem("ifconfig %s down", dev->name);
180         if (i)
181             msgConfirm("Warning: Unable to down the %s interface properly", dev->name);
182         cp = variable_get(VAR_GATEWAY);
183         if (cp) {
184             msgDebug("Deleting default route.\n");
185             vsystem("route -n delete default");
186         }
187     }
188     else if (pppPID) {
189         msgConfirm("Killing previous PPP process %d.", pppPID);
190         kill(pppPID, SIGTERM);
191         pppPID = 0;
192     }
193     networkInitialized = FALSE;
194 }
195
196 /* Start PPP on the 3rd screen */
197 static pid_t
198 startPPP(Device *devp)
199 {
200     int fd2, pulse;
201     FILE *fp;
202     char *val;
203     pid_t pid = 0;
204     char myaddr[16], provider[16], speed[16], authname[32], authkey[16];
205     char phone[16];
206     WINDOW *w = savescr();
207     
208     /* These are needed to make ppp work */
209     Mkdir("/var/log");
210     Mkdir("/var/run");
211     Mkdir("/var/spool/lock");
212     Mkdir("/etc/ppp");
213
214     dialog_clear_norefresh();
215     if (!variable_get(VAR_SERIAL_SPEED))
216         variable_set2(VAR_SERIAL_SPEED, "115200", 0);
217     /* Get any important user values */
218     val = variable_get_value(VAR_SERIAL_SPEED,
219                       "Enter the baud rate for your modem - this can be higher than the actual\n"
220                       "maximum data rate since most modems can talk at one speed to the\n"
221                       "computer and at another speed to the remote end.\n\n"
222                       "If you're not sure what to put here, just select the default.", 0);
223     SAFE_STRCPY(speed, (val && *val) ? val : "115200");
224
225     val = variable_get(VAR_GATEWAY);
226     SAFE_STRCPY(provider, (val && *val) ? val : "0");
227
228     dialog_clear_norefresh();
229     val = msgGetInput(provider, "Enter the IP address of your service provider or 0 if you\n"
230                       "don't know it and would prefer to negotiate it dynamically.");
231     SAFE_STRCPY(provider, (val && *val) ? val : "0");
232
233     if (devp->private && ((DevInfo *)devp->private)->ipaddr[0])
234         SAFE_STRCPY(myaddr, ((DevInfo *)devp->private)->ipaddr);
235     else
236         strcpy(myaddr, "0");
237
238     if (!Fake)
239         fp = fopen("/etc/ppp/ppp.linkup", "w");
240     else
241         fp = fopen("/dev/stderr", "w");
242     if (fp != NULL) {
243         fprintf(fp, "MYADDR:\n");
244         fprintf(fp, " delete ALL\n");
245         fprintf(fp, " add 0 0 HISADDR\n");
246         fchmod(fileno(fp), 0755);
247         fclose(fp);
248     }
249     if (!Fake)
250         fd2 = open("/etc/ppp/ppp.secret", O_CREAT);
251     else
252         fd2 = -1;
253     if (fd2 != -1) {
254         fchmod(fd2, 0700);
255         close(fd2);
256     }
257     if (!Fake)
258         fp = fopen("/etc/ppp/ppp.conf", "a");
259     else
260         fp = fopen("/dev/stderr", "w");
261     if (!fp) {
262         msgConfirm("Couldn't open /etc/ppp/ppp.conf file!  This isn't going to work");
263         restorescr(w);
264         return 0;
265     }
266     authname[0] = '\0';
267     pulse = 0;
268     dialog_clear_norefresh();
269     if (!dialog_yesno("", "Does your ISP support PAP or CHAP ppp logins?", -1, -1)) {
270         val = msgGetInput(NULL, "Enter the name you use to login to your provider.");
271         SAFE_STRCPY(authname, val);
272         dialog_clear_norefresh();
273         val = msgGetInput(NULL, "Enter the password you use to login to your provider.");
274         SAFE_STRCPY(authkey, val);
275         dialog_clear_norefresh();
276         val = msgGetInput(NULL, "Enter the your provider's login phone number.");
277         SAFE_STRCPY(phone, val);
278         dialog_clear_norefresh();
279         pulse = dialog_yesno("", "Does your telephone line support tone dialing?", -1, -1);
280     }
281     fprintf(fp, "\ninstall:\n");
282     fprintf(fp, " set speed %s\n", speed);
283     fprintf(fp, " set device %s\n", devp->devname);
284     fprintf(fp, " set ifaddr %s %s 255.255.255.0 0.0.0.0\n", myaddr, provider);
285     fprintf(fp, " add! default HISADDR\n");
286     fprintf(fp, " set timeout 0\n");
287     fprintf(fp, " enable dns\n");
288     fprintf(fp, " set log local phase\n");
289     if(authname[0] != '\0'){
290         fprintf(fp, " set dial \"ABORT BUSY ABORT NO\\\\sCARRIER TIMEOUT 5 \\\"\\\" AT OK-AT-OK ATE1Q0 OK \\\\dATD%c\\\\T TIMEOUT 40 CONNECT\"\n", pulse ? 'P' : 'T');
291         fprintf(fp, " set login\n");
292         fprintf(fp, " set authname %s\n", authname);
293         fprintf(fp, " set authkey %s\n", authkey);
294         fprintf(fp, " set phone %s\n", phone);
295     }
296     if (fchmod(fileno(fp), 0600) != 0)
297         msgConfirm("Warning: Failed to fix permissions on /etc/ppp/ppp.conf !");
298     fclose(fp);
299
300     /* Make the ppp config persistent */
301     variable_set2(VAR_PPP_ENABLE, "YES", 0);
302     variable_set2(VAR_PPP_PROFILE, "install", 0);
303
304     if (!Fake && !file_readable("/dev/tun0") && mknod("/dev/tun0", 0600 | S_IFCHR, makedev(52, 0))) {
305         msgConfirm("Warning:  No /dev/tun0 device.  PPP will not work!");
306         restorescr(w);
307         return 0;
308     }
309
310     if (isDebug())
311         msgDebug("About to start PPP on device %s @ %s baud.  Provider = %s\n", devp->devname, speed, provider);
312
313     if (!Fake && !(pid = fork())) {
314         int i, fd;
315         struct termios foo;
316         extern int login_tty(int);
317
318         for (i = getdtablesize(); i >= 0; i--)
319             close(i);
320
321         /* We're going over to VTY2 */
322         fd = open("/dev/ttyv2", O_RDWR);
323         ioctl(0, TIOCSCTTY, &fd);
324         dup2(0, 1);
325         dup2(0, 2);
326         DebugFD = 2;
327         if (login_tty(fd) == -1)
328             msgDebug("ppp: Can't set the controlling terminal.\n");
329         signal(SIGTTOU, SIG_IGN);
330         if (tcgetattr(fd, &foo) != -1) {
331             foo.c_cc[VERASE] = '\010';
332             if (tcsetattr(fd, TCSANOW, &foo) == -1)
333                 msgDebug("ppp: Unable to set the erase character.\n");
334         }
335         else
336             msgDebug("ppp: Unable to get the terminal attributes!\n");
337         execlp("ppp", "ppp", "install", (char *)NULL);
338         msgDebug("PPP process failed to exec!\n");
339         exit(1);
340     }
341     else {
342         dialog_clear_norefresh();
343         msgConfirm("NOTICE: The PPP command is now started on VTY3 (type ALT-F3 to\n"
344            "interact with it, ALT-F1 to switch back here). If you are using\n"
345            "a PAP or CHAP login simply enter \"dial\", otherwise you'll need\n"
346            "to use the \"term\" command which starts a terminal emulator\n"
347            "which you can use to talk to your modem and dial the service\n"
348            "provider.  Once you're connected, come back to this screen and\n"
349            "press return.\n\n"
350            "DO NOT PRESS [ENTER] HERE UNTIL THE CONNECTION IS FULLY\n"
351            "ESTABLISHED!");
352     }
353     restorescr(w);
354     return pid;
355 }