]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - usr.sbin/sysinstall/network.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.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         /*
130          * If this interface isn't a DHCP one, bring it up.
131          * If it is, then it's already up.
132          */
133         if (strstr(cp, "DHCP") == NULL) {
134             msgDebug("Not a DHCP interface.\n");
135             i = vsystem("ifconfig %s %s", dev->name, cp);
136             if (i) {
137                 msgConfirm("Unable to configure the %s interface!\n"
138                            "This installation method cannot be used.",
139                            dev->name);
140                 return FALSE;
141             }
142             rp = variable_get(VAR_GATEWAY);
143             if (!rp || *rp == '0') {
144                 msgConfirm("No gateway has been set. You will be unable to access hosts\n"
145                            "not on your local network");
146             }
147             else {
148                 /* 
149                  * Explicitly flush all routes to get back to a known sane
150                  * state. We don't need to check this exit code because if
151                  * anything fails it will show up in the route add below.
152                  */
153                 system("route -n flush");
154                 msgDebug("Adding default route to %s.\n", rp);
155                 if (vsystem("route -n add default %s", rp) != 0) {
156                     msgConfirm("Failed to add a default route; please check "
157                                "your network configuration");
158                     return FALSE;
159                 }
160             }
161         } else {
162             msgDebug("A DHCP interface.  Should already be up.\n");
163         }
164     } else if ((cp = variable_get(VAR_IPV6ADDR)) == NULL || *cp == '\0') {
165         msgConfirm("The %s device is not configured.  You will need to do so\n"
166                    "in the Networking configuration menu before proceeding.", dev->name);
167         return FALSE;
168     }
169
170     if (isDebug())
171         msgDebug("Network initialized successfully.\n");
172     networkInitialized = TRUE;
173     return TRUE;
174 }
175
176 void
177 mediaShutdownNetwork(Device *dev)
178 {
179     char *cp;
180
181     if (!RunningAsInit || !networkInitialized)
182         return;
183
184     msgDebug("Shutdown called for network device %s\n", dev->name);
185     /* Not a serial device? */
186     if (strncmp("sl", dev->name, 2) && strncmp("ppp", dev->name, 3)) {
187         int i;
188         char ifconfig[255];
189
190         snprintf(ifconfig, 255, "%s%s", VAR_IFCONFIG, dev->name);
191         cp = variable_get(ifconfig);
192         if (!cp)
193             return;
194         msgDebug("ifconfig %s down\n", dev->name);
195         i = vsystem("ifconfig %s down", dev->name);
196         if (i)
197             msgConfirm("Warning: Unable to down the %s interface properly", dev->name);
198         cp = variable_get(VAR_GATEWAY);
199         if (cp) {
200             msgDebug("Deleting default route.\n");
201             vsystem("route -n delete default");
202         }
203     }
204     else if (pppPID) {
205         msgConfirm("Killing previous PPP process %d.", pppPID);
206         kill(pppPID, SIGTERM);
207         pppPID = 0;
208     }
209     networkInitialized = FALSE;
210 }
211
212 /* Start PPP on the 3rd screen */
213 static pid_t
214 startPPP(Device *devp)
215 {
216     int fd2, pulse;
217     FILE *fp;
218     char *val;
219     pid_t pid = 0;
220     char myaddr[16], provider[16], speed[16], authname[32], authkey[16];
221     char phone[16];
222     WINDOW *w = savescr();
223     
224     /* These are needed to make ppp work */
225     Mkdir("/var/log");
226     Mkdir("/var/run");
227     Mkdir("/var/spool/lock");
228     Mkdir("/etc/ppp");
229
230     dialog_clear_norefresh();
231     if (!variable_get(VAR_SERIAL_SPEED))
232         variable_set2(VAR_SERIAL_SPEED, "115200", 0);
233     /* Get any important user values */
234     val = variable_get_value(VAR_SERIAL_SPEED,
235                       "Enter the baud rate for your modem - this can be higher than the actual\n"
236                       "maximum data rate since most modems can talk at one speed to the\n"
237                       "computer and at another speed to the remote end.\n\n"
238                       "If you're not sure what to put here, just select the default.", 0);
239     SAFE_STRCPY(speed, (val && *val) ? val : "115200");
240
241     val = variable_get(VAR_GATEWAY);
242     SAFE_STRCPY(provider, (val && *val) ? val : "0");
243
244     dialog_clear_norefresh();
245     val = msgGetInput(provider, "Enter the IP address of your service provider or 0 if you\n"
246                       "don't know it and would prefer to negotiate it dynamically.");
247     SAFE_STRCPY(provider, (val && *val) ? val : "0");
248
249     if (devp->private && ((DevInfo *)devp->private)->ipaddr[0])
250         SAFE_STRCPY(myaddr, ((DevInfo *)devp->private)->ipaddr);
251     else
252         strcpy(myaddr, "0");
253
254     if (!Fake)
255         fp = fopen("/etc/ppp/ppp.linkup", "w");
256     else
257         fp = fopen("/dev/stderr", "w");
258     if (fp != NULL) {
259         fprintf(fp, "MYADDR:\n");
260         fprintf(fp, " delete ALL\n");
261         fprintf(fp, " add 0 0 HISADDR\n");
262         fchmod(fileno(fp), 0755);
263         fclose(fp);
264     }
265     if (!Fake)
266         fd2 = open("/etc/ppp/ppp.secret", O_CREAT);
267     else
268         fd2 = -1;
269     if (fd2 != -1) {
270         fchmod(fd2, 0700);
271         close(fd2);
272     }
273     if (!Fake)
274         fp = fopen("/etc/ppp/ppp.conf", "a");
275     else
276         fp = fopen("/dev/stderr", "w");
277     if (!fp) {
278         msgConfirm("Couldn't open /etc/ppp/ppp.conf file!  This isn't going to work");
279         restorescr(w);
280         return 0;
281     }
282     authname[0] = '\0';
283     pulse = 0;
284     dialog_clear_norefresh();
285     if (!dialog_yesno("", "Does your ISP support PAP or CHAP ppp logins?", -1, -1)) {
286         val = msgGetInput(NULL, "Enter the name you use to login to your provider.");
287         SAFE_STRCPY(authname, val);
288         dialog_clear_norefresh();
289         val = msgGetInput(NULL, "Enter the password you use to login to your provider.");
290         SAFE_STRCPY(authkey, val);
291         dialog_clear_norefresh();
292         val = msgGetInput(NULL, "Enter the your provider's login phone number.");
293         SAFE_STRCPY(phone, val);
294         dialog_clear_norefresh();
295         pulse = dialog_yesno("", "Does your telephone line support tone dialing?", -1, -1);
296     }
297     fprintf(fp, "\ninstall:\n");
298     fprintf(fp, " set speed %s\n", speed);
299     fprintf(fp, " set device %s\n", devp->devname);
300     fprintf(fp, " set ifaddr %s %s 255.255.255.0 0.0.0.0\n", myaddr, provider);
301     fprintf(fp, " add! default HISADDR\n");
302     fprintf(fp, " set timeout 0\n");
303     fprintf(fp, " enable dns\n");
304     fprintf(fp, " set log local phase\n");
305     if(authname[0] != '\0'){
306         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');
307         fprintf(fp, " set login\n");
308         fprintf(fp, " set authname %s\n", authname);
309         fprintf(fp, " set authkey %s\n", authkey);
310         fprintf(fp, " set phone %s\n", phone);
311     }
312     if (fchmod(fileno(fp), 0600) != 0)
313         msgConfirm("Warning: Failed to fix permissions on /etc/ppp/ppp.conf !");
314     fclose(fp);
315
316     /* Make the ppp config persistent */
317     variable_set2(VAR_PPP_ENABLE, "YES", 0);
318     variable_set2(VAR_PPP_PROFILE, "install", 0);
319
320     if (!Fake && !file_readable("/dev/tun0")) {
321         msgConfirm("Warning:  No /dev/tun0 device.  PPP will not work!");
322         restorescr(w);
323         return 0;
324     }
325
326     if (isDebug())
327         msgDebug("About to start PPP on device %s @ %s baud.  Provider = %s\n", devp->devname, speed, provider);
328
329     if (!Fake && !(pid = fork())) {
330         int i, fd;
331         struct termios foo;
332         extern int login_tty(int);
333
334         for (i = getdtablesize(); i >= 0; i--)
335             close(i);
336
337         /* We're going over to VTY2 */
338         fd = open("/dev/ttyv2", O_RDWR);
339         ioctl(0, TIOCSCTTY, &fd);
340         dup2(0, 1);
341         dup2(0, 2);
342         DebugFD = 2;
343         if (login_tty(fd) == -1)
344             msgDebug("ppp: Can't set the controlling terminal.\n");
345         signal(SIGTTOU, SIG_IGN);
346         if (tcgetattr(fd, &foo) != -1) {
347             foo.c_cc[VERASE] = '\010';
348             if (tcsetattr(fd, TCSANOW, &foo) == -1)
349                 msgDebug("ppp: Unable to set the erase character.\n");
350         }
351         else
352             msgDebug("ppp: Unable to get the terminal attributes!\n");
353         execlp("ppp", "ppp", "install", (char *)NULL);
354         msgDebug("PPP process failed to exec!\n");
355         exit(1);
356     }
357     else {
358         dialog_clear_norefresh();
359         msgConfirm("NOTICE: The PPP command is now started on VTY3 (type ALT-F3 to\n"
360            "interact with it, ALT-F1 to switch back here). If you are using\n"
361            "a PAP or CHAP login simply enter \"dial\", otherwise you'll need\n"
362            "to use the \"term\" command which starts a terminal emulator\n"
363            "which you can use to talk to your modem and dial the service\n"
364            "provider.  Once you're connected, come back to this screen and\n"
365            "press return.\n\n"
366            "DO NOT PRESS [ENTER] HERE UNTIL THE CONNECTION IS FULLY\n"
367            "ESTABLISHED!");
368     }
369     restorescr(w);
370     return pid;
371 }