network.c revision 39868
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 * $Id: network.c,v 1.31 1998/07/12 17:11:53 brian Exp $
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 <sys/fcntl.h>
43#include <sys/ioctl.h>
44#include <sys/stat.h>
45
46static Boolean	networkInitialized;
47static pid_t	startPPP(Device *devp);
48
49static pid_t	pppPID;
50
51Boolean
52mediaInitNetwork(Device *dev)
53{
54    int i;
55    char *rp;
56    char *cp, ifconfig[255];
57
58    if (!RunningAsInit || networkInitialized)
59	return TRUE;
60
61    msgDebug("Init routine called for network device %s.\n", dev->name);
62    if (!file_readable("/etc/resolv.conf"))
63	configResolv();
64
65    /* Old PPP process lying around? */
66    if (pppPID) {
67	msgNotify("Killing previous PPP process %d.", pppPID);
68	kill(pppPID, SIGTERM);
69	pppPID = 0;
70    }
71    if (!strncmp("ppp", dev->name, 3)) {	/* PPP? */
72	if (!(pppPID = startPPP(dev))) {
73	    msgConfirm("Unable to start PPP!  This installation method cannot be used.");
74	    return FALSE;
75	}
76	networkInitialized = TRUE;
77	return TRUE;
78    }
79    else if (!strncmp("sl", dev->name, 2)) {	/* SLIP? */
80	char *val;
81	char attach[256];
82
83	dialog_clear_norefresh();
84	/* Cheesy slip attach */
85	snprintf(attach, 256, "slattach -a -h -l -s 9600 %s", dev->devname);
86	val = msgGetInput(attach,
87			  "Warning:  SLIP is rather poorly supported in this revision\n"
88			  "of the installation due to the lack of a dialing utility.\n"
89			  "If you can use PPP for this instead then you're much better\n"
90			  "off doing so, otherwise SLIP works fairly well for *hardwired*\n"
91			  "links.  Please edit the following slattach command for\n"
92			  "correctness (default here is: VJ compression, Hardware flow-\n"
93			  "control, ignore carrier and 9600 baud data rate).  When you're\n"
94			  "ready, press [ENTER] to execute it.");
95	if (!val) {
96	    msgConfirm("slattach command was empty.  Try again!");
97	    return FALSE;
98	}
99	else
100	    SAFE_STRCPY(attach, val);
101	/*
102	 * Doing this with vsystem() is actually bogus since we should be storing the pid of slattach
103	 * for later killing.  It's just too convenient to call vsystem(), however, rather than
104	 * constructing a proper argument for exec() so we punt on doing slip right for now.
105	 */
106	if (vsystem(attach)) {
107	    msgConfirm("slattach returned a bad status!  Please verify that\n"
108		       "the command is correct and try this operation again.");
109	    return FALSE;
110	}
111    }
112
113    snprintf(ifconfig, 255, "%s%s", VAR_IFCONFIG, dev->name);
114    cp = variable_get(ifconfig);
115    if (!cp) {
116	msgConfirm("The %s device is not configured.  You will need to do so\n"
117		   "in the Networking configuration menu before proceeding.", dev->name);
118	return FALSE;
119    }
120    msgNotify("ifconfig %s %s", dev->name, cp);
121    i = vsystem("ifconfig %s %s", dev->name, cp);
122    if (i) {
123	msgConfirm("Unable to configure the %s interface!\n"
124		   "This installation method cannot be used.", dev->name);
125	return FALSE;
126    }
127
128    rp = variable_get(VAR_GATEWAY);
129    if (!rp || *rp == '0') {
130	msgConfirm("No gateway has been set. You may be unable to access hosts\n"
131		   "not on your local network");
132    }
133    else {
134	msgNotify("Adding default route to %s.", rp);
135	vsystem("route -n add default %s", rp);
136    }
137    if (isDebug())
138	msgDebug("Network initialized successfully.\n");
139    networkInitialized = TRUE;
140    return TRUE;
141}
142
143void
144mediaShutdownNetwork(Device *dev)
145{
146    char *cp;
147
148    if (!RunningAsInit || !networkInitialized)
149	return;
150
151    msgDebug("Shutdown called for network device %s\n", dev->name);
152    /* Not a serial device? */
153    if (strncmp("sl", dev->name, 2) && strncmp("ppp", dev->name, 3)) {
154	int i;
155	char ifconfig[255];
156
157	snprintf(ifconfig, 255, "%s%s", VAR_IFCONFIG, dev->name);
158	cp = variable_get(ifconfig);
159	if (!cp)
160	    return;
161	msgNotify("ifconfig %s down", dev->name);
162	i = vsystem("ifconfig %s down", dev->name);
163	if (i)
164	    msgConfirm("Warning: Unable to down the %s interface properly", dev->name);
165	cp = variable_get(VAR_GATEWAY);
166	if (cp) {
167	    msgNotify("Deleting default route.");
168	    vsystem("route -n delete default");
169	}
170    }
171    else if (pppPID) {
172	msgNotify("Killing previous PPP process %d.", pppPID);
173	kill(pppPID, SIGTERM);
174	pppPID = 0;
175    }
176    networkInitialized = FALSE;
177}
178
179/* Start PPP on the 3rd screen */
180static pid_t
181startPPP(Device *devp)
182{
183    int fd2;
184    FILE *fp;
185    char *val;
186    pid_t pid = 0;
187    char myaddr[16], provider[16], speed[16];
188
189    /* These are needed to make ppp work */
190    Mkdir("/var/log");
191    Mkdir("/var/run");
192    Mkdir("/var/spool/lock");
193    Mkdir("/etc/ppp");
194
195    dialog_clear_norefresh();
196    if (!variable_get(VAR_SERIAL_SPEED))
197	variable_set2(VAR_SERIAL_SPEED, "115200");
198    /* Get any important user values */
199    val = variable_get_value(VAR_SERIAL_SPEED,
200		      "Enter the baud rate for your modem - this can be higher than the actual\n"
201		      "maximum data rate since most modems can talk at one speed to the\n"
202		      "computer and at another speed to the remote end.\n\n"
203		      "If you're not sure what to put here, just select the default.");
204    SAFE_STRCPY(speed, (val && *val) ? val : "115200");
205
206    val = variable_get(VAR_GATEWAY);
207    SAFE_STRCPY(provider, (val && *val) ? val : "0");
208
209    dialog_clear_norefresh();
210    val = msgGetInput(provider, "Enter the IP address of your service provider or 0 if you\n"
211		      "don't know it and would prefer to negotiate it dynamically.");
212    SAFE_STRCPY(provider, (val && *val) ? val : "0");
213
214    if (devp->private && ((DevInfo *)devp->private)->ipaddr[0])
215	SAFE_STRCPY(myaddr, ((DevInfo *)devp->private)->ipaddr);
216    else
217	strcpy(myaddr, "0");
218
219    if (!Fake)
220	fp = fopen("/etc/ppp/ppp.linkup", "w");
221    else
222	fp = fopen("/dev/stderr", "w");
223    if (fp != NULL) {
224	fprintf(fp, "MYADDR:\n");
225	fprintf(fp, " delete ALL\n");
226        fprintf(fp, " add 0 0 HISADDR\n");
227	fchmod(fileno(fp), 0755);
228	fclose(fp);
229    }
230    if (!Fake)
231	fd2 = open("/etc/ppp/ppp.secret", O_CREAT);
232    else
233	fd2 = -1;
234    if (fd2 != -1) {
235	fchmod(fd2, 0700);
236	close(fd2);
237    }
238    if (!Fake)
239	fp = fopen("/etc/ppp/ppp.conf", "w");
240    else
241	fp = fopen("/dev/stderr", "w");
242    if (!fp) {
243	msgConfirm("Couldn't open /etc/ppp/ppp.conf file!  This isn't going to work");
244	return 0;
245    }
246    fprintf(fp, "default:\n");
247    fprintf(fp, " set speed %s\n", speed);
248    fprintf(fp, " set device %s\n", devp->devname);
249    fprintf(fp, " set ifaddr %s %s\n", myaddr, provider);
250    fprintf(fp, " set timeout 0\n");
251    fprintf(fp, " enable dns\n");
252    fprintf(fp, " set log local phase\n");
253    fclose(fp);
254
255    if (!Fake && !file_readable("/dev/tun0") && mknod("/dev/tun0", 0600 | S_IFCHR, makedev(52, 0))) {
256	msgConfirm("Warning:  No /dev/tun0 device.  PPP will not work!");
257	return 0;
258    }
259
260    if (isDebug())
261	msgDebug("About to start PPP on device %s @ %s baud.  Provider = %s\n", devp->devname, speed, provider);
262
263    if (!Fake && !(pid = fork())) {
264	int i, fd;
265	struct termios foo;
266	extern int login_tty(int);
267
268	for (i = getdtablesize(); i >= 0; i--)
269	    close(i);
270
271	/* We're going over to VTY2 */
272	fd = open("/dev/ttyv2", O_RDWR);
273	ioctl(0, TIOCSCTTY, &fd);
274	dup2(0, 1);
275	dup2(0, 2);
276	DebugFD = 2;
277	if (login_tty(fd) == -1)
278	    msgDebug("ppp: Can't set the controlling terminal.\n");
279	signal(SIGTTOU, SIG_IGN);
280	if (tcgetattr(fd, &foo) != -1) {
281	    foo.c_cc[VERASE] = '\010';
282	    if (tcsetattr(fd, TCSANOW, &foo) == -1)
283		msgDebug("ppp: Unable to set the erase character.\n");
284	}
285	else
286	    msgDebug("ppp: Unable to get the terminal attributes!\n");
287	execlp("ppp", "ppp", (char *)NULL);
288	msgDebug("PPP process failed to exec!\n");
289	exit(1);
290    }
291    else {
292	dialog_clear_norefresh();
293	msgConfirm("NOTICE: The PPP command is now started on VTY3 (type ALT-F3 to\n"
294		   "interact with it, ALT-F1 to switch back here). The only command\n"
295		   "you'll probably want or need to use is the \"term\" command\n"
296		   "which starts a terminal emulator you can use to talk to your\n"
297		   "modem and dial the service provider.  Once you're connected,\n"
298		   "come back to this screen and press return.\n\n"
299		   "DO NOT PRESS [ENTER] HERE UNTIL THE CONNECTION IS FULLY\n"
300		   "ESTABLISHED!");
301    }
302    return pid;
303}
304