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