main.c revision 1.5
1/*	$OpenBSD: main.c,v 1.5 1996/03/25 15:55:49 niklas Exp $	*/
2
3/*
4 * main.c - Point-to-Point Protocol main module
5 *
6 * Copyright (c) 1989 Carnegie Mellon University.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms are permitted
10 * provided that the above copyright notice and this paragraph are
11 * duplicated in all such forms and that any documentation,
12 * advertising materials, and other materials related to such
13 * distribution and use acknowledge that the software was developed
14 * by Carnegie Mellon University.  The name of the
15 * University may not be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
19 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
22#ifndef lint
23static char rcsid[] = "$OpenBSD: main.c,v 1.5 1996/03/25 15:55:49 niklas Exp $";
24#endif
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <unistd.h>
30#include <signal.h>
31#include <errno.h>
32#include <fcntl.h>
33#include <syslog.h>
34#include <netdb.h>
35#include <utmp.h>
36#include <pwd.h>
37#include <sys/param.h>
38#include <sys/types.h>
39#include <sys/wait.h>
40#include <sys/time.h>
41#include <sys/resource.h>
42#include <sys/stat.h>
43#include <sys/socket.h>
44#include <net/if.h>
45
46#include "pppd.h"
47#include "magic.h"
48#include "fsm.h"
49#include "lcp.h"
50#include "ipcp.h"
51#include "upap.h"
52#include "chap.h"
53#include "ccp.h"
54#include "pathnames.h"
55#include "patchlevel.h"
56
57#ifdef IPX_CHANGE
58#include "ipxcp.h"
59#endif /* IPX_CHANGE */
60
61/*
62 * If REQ_SYSOPTIONS is defined to 1, pppd will not run unless
63 * /etc/ppp/options exists.
64 */
65#ifndef	REQ_SYSOPTIONS
66#define REQ_SYSOPTIONS	1
67#endif
68
69/* interface vars */
70char ifname[IFNAMSIZ];		/* Interface name */
71int ifunit;			/* Interface unit number */
72
73char *progname;			/* Name of this program */
74char hostname[MAXNAMELEN];	/* Our hostname */
75static char pidfilename[MAXPATHLEN];	/* name of pid file */
76static char default_devnam[MAXPATHLEN];	/* name of default device */
77static pid_t pid;		/* Our pid */
78static uid_t uid;		/* Our real user-id */
79
80int ttyfd = -1;			/* Serial port file descriptor */
81
82int phase;			/* where the link is at */
83int kill_link;
84int open_ccp_flag;
85
86u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */
87u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */
88
89int hungup;			/* terminal has been hung up */
90static int n_children;		/* # child processes still running */
91
92int baud_rate;			/* Actual bits/second for serial device */
93
94static int locked;		/* lock() has succeeded */
95
96char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n";
97
98/* Prototypes for procedures local to this file. */
99
100static void cleanup __P((void));
101static void close_tty __P((void));
102static void get_input __P((void));
103static void connect_time_expired __P((caddr_t));
104static void calltimeout __P((void));
105static struct timeval *timeleft __P((struct timeval *));
106static void hup __P((int));
107static void term __P((int));
108static void chld __P((int));
109static void toggle_debug __P((int));
110static void open_ccp __P((int));
111static void bad_signal __P((int));
112static void holdoff_end __P((void *));
113static int device_script __P((char *, int, int));
114static void reap_kids __P((void));
115static void pr_log __P((void *, char *, ...));
116
117extern	char	*ttyname __P((int));
118extern	char	*getlogin __P((void));
119
120#ifdef ultrix
121#undef	O_NONBLOCK
122#define	O_NONBLOCK	O_NDELAY
123#endif
124
125/*
126 * PPP Data Link Layer "protocol" table.
127 * One entry per supported protocol.
128 * The last entry must be NULL.
129 */
130struct protent *protocols[] = {
131    &lcp_protent,
132    &pap_protent,
133    &chap_protent,
134    &ipcp_protent,
135    &ccp_protent,
136#ifdef IPX_CHANGE
137    &ipxcp_protent,
138#endif
139    NULL
140};
141
142void
143main(argc, argv)
144    int argc;
145    char *argv[];
146{
147    int i, nonblock, fdflags;
148    struct sigaction sa;
149    FILE *pidfile;
150    char *p;
151    struct passwd *pw;
152    struct timeval timo;
153    sigset_t mask;
154    struct protent *protp;
155
156    p = ttyname(0);
157    if (p)
158	strcpy(devnam, p);
159    strcpy(default_devnam, devnam);
160
161    if (gethostname(hostname, MAXNAMELEN) < 0 ) {
162	perror("couldn't get hostname");
163	die(1);
164    }
165    hostname[MAXNAMELEN-1] = 0;
166
167    uid = getuid();
168
169    /*
170     * Initialize to the standard option set, then parse, in order,
171     * the system options file, the user's options file, and the command
172     * line arguments.
173     */
174    for (i = 0; (protp = protocols[i]) != NULL; ++i)
175        (*protp->init)(0);
176
177    progname = *argv;
178
179    if (!options_from_file(_PATH_SYSOPTIONS, REQ_SYSOPTIONS, 0) ||
180	!options_for_tty() ||
181	!options_from_user() ||
182	!parse_args(argc-1, argv+1))
183	exit(1);
184
185    if (!ppp_available()) {
186	fprintf(stderr, no_ppp_msg);
187	exit(1);
188    }
189
190    /*
191     * Check that the options given are valid and consistent.
192     */
193    sys_check_options();
194    auth_check_options();
195    for (i = 0; (protp = protocols[i]) != NULL; ++i)
196	if (protp->check_options != NULL)
197	    (*protp->check_options)();
198    if (demand && connector == 0) {
199	fprintf(stderr, "%s: connect script required for demand-dialling\n",
200		progname);
201	exit(1);
202    }
203
204    /*
205     * If the user has specified the default device name explicitly,
206     * pretend they hadn't.
207     */
208    if (!default_device && strcmp(devnam, default_devnam) == 0)
209	default_device = 1;
210
211    /*
212     * Initialize system-dependent stuff and magic number package.
213     */
214    sys_init();
215    magic_init();
216
217    /*
218     * Detach ourselves from the terminal, if required,
219     * and identify who is running us.
220     */
221    if (!default_device && !nodetach && daemon(0, 0) < 0) {
222	perror("Couldn't detach from controlling terminal");
223	exit(1);
224    }
225    pid = getpid();
226    p = getlogin();
227    if (p == NULL) {
228	pw = getpwuid(uid);
229	if (pw != NULL && pw->pw_name != NULL)
230	    p = pw->pw_name;
231	else
232	    p = "(unknown)";
233    }
234    syslog(LOG_NOTICE, "pppd %s.%d started by %s, uid %d",
235	   VERSION, PATCHLEVEL, p, uid);
236
237    /*
238     * Compute mask of all interesting signals and install signal handlers
239     * for each.  Only one signal handler may be active at a time.  Therefore,
240     * all other signals should be masked when any handler is executing.
241     */
242    sigemptyset(&mask);
243    sigaddset(&mask, SIGHUP);
244    sigaddset(&mask, SIGINT);
245    sigaddset(&mask, SIGTERM);
246    sigaddset(&mask, SIGCHLD);
247
248#define SIGNAL(s, handler)	{ \
249	sa.sa_handler = handler; \
250	if (sigaction(s, &sa, NULL) < 0) { \
251	    syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \
252	    die(1); \
253	} \
254    }
255
256    sa.sa_mask = mask;
257    sa.sa_flags = 0;
258    SIGNAL(SIGHUP, hup);		/* Hangup */
259    SIGNAL(SIGINT, term);		/* Interrupt */
260    SIGNAL(SIGTERM, term);		/* Terminate */
261    SIGNAL(SIGCHLD, chld);
262
263    SIGNAL(SIGUSR1, toggle_debug);	/* Toggle debug flag */
264    SIGNAL(SIGUSR2, open_ccp);		/* Reopen CCP */
265
266    /*
267     * Install a handler for other signals which would otherwise
268     * cause pppd to exit without cleaning up.
269     */
270    SIGNAL(SIGABRT, bad_signal);
271    SIGNAL(SIGALRM, bad_signal);
272    SIGNAL(SIGFPE, bad_signal);
273    SIGNAL(SIGILL, bad_signal);
274    SIGNAL(SIGPIPE, bad_signal);
275    SIGNAL(SIGQUIT, bad_signal);
276    SIGNAL(SIGSEGV, bad_signal);
277#ifdef SIGBUS
278    SIGNAL(SIGBUS, bad_signal);
279#endif
280#ifdef SIGEMT
281    SIGNAL(SIGEMT, bad_signal);
282#endif
283#ifdef SIGPOLL
284    SIGNAL(SIGPOLL, bad_signal);
285#endif
286#ifdef SIGPROF
287    SIGNAL(SIGPROF, bad_signal);
288#endif
289#ifdef SIGSYS
290    SIGNAL(SIGSYS, bad_signal);
291#endif
292#ifdef SIGTRAP
293    SIGNAL(SIGTRAP, bad_signal);
294#endif
295#ifdef SIGVTALRM
296    SIGNAL(SIGVTALRM, bad_signal);
297#endif
298#ifdef SIGXCPU
299    SIGNAL(SIGXCPU, bad_signal);
300#endif
301#ifdef SIGXFSZ
302    SIGNAL(SIGXFSZ, bad_signal);
303#endif
304
305    /*
306     * If we're doing dial-on-demand, set up the interface now.
307     */
308    if (demand) {
309	/*
310	 * Open the loopback channel and set it up to be the ppp interface.
311	 */
312	open_ppp_loopback();
313
314	syslog(LOG_INFO, "Using interface ppp%d", ifunit);
315	(void) sprintf(ifname, "ppp%d", ifunit);
316
317	/* write pid to file */
318	(void) sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname);
319	if ((pidfile = fopen(pidfilename, "w")) != NULL) {
320	    fprintf(pidfile, "%d\n", pid);
321	    (void) fclose(pidfile);
322	} else {
323	    syslog(LOG_ERR, "Failed to create pid file %s: %m", pidfilename);
324	    pidfilename[0] = 0;
325	}
326
327	/*
328	 * Configure the interface and mark it up, etc.
329	 */
330	demand_conf();
331    }
332
333    for (;;) {
334
335	if (demand) {
336	    /*
337	     * Don't do anything until we see some activity.
338	     */
339	    phase = PHASE_DORMANT;
340	    kill_link = 0;
341	    demand_unblock();
342	    for (;;) {
343		wait_loop_output(timeleft(&timo));
344		calltimeout();
345		if (kill_link) {
346		    if (!persist)
347			die(0);
348		    kill_link = 0;
349		}
350		if (get_loop_output())
351		    break;
352		reap_kids();
353	    }
354
355	    /*
356	     * Now we want to bring up the link.
357	     */
358	    demand_block();
359	    syslog(LOG_INFO, "Starting link");
360	}
361
362	/*
363	 * Lock the device if we've been asked to.
364	 */
365	if (lockflag && !default_device) {
366	    if (lock(devnam) < 0)
367		goto fail;
368	    locked = 1;
369	}
370
371	/*
372	 * Open the serial device and set it up to be the ppp interface.
373	 * If we're dialling out, or we don't want to use the modem lines,
374	 * we open it in non-blocking mode, but then we need to clear
375	 * the non-blocking I/O bit.
376	 */
377	nonblock = (connector || !modem)? O_NONBLOCK: 0;
378	if ((ttyfd = open(devnam, nonblock | O_RDWR, 0)) < 0) {
379	    syslog(LOG_ERR, "Failed to open %s: %m", devnam);
380	    goto fail;
381	}
382	if (nonblock) {
383	    if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1
384		|| fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)
385		syslog(LOG_WARNING,
386		       "Couldn't reset non-blocking mode on device: %m");
387	}
388	hungup = 0;
389	kill_link = 0;
390
391	/* run connection script */
392	if (connector && connector[0]) {
393	    MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector));
394
395	    /* set line speed, flow control, etc.; set CLOCAL for now */
396	    set_up_tty(ttyfd, 1);
397
398	    /* drop dtr to hang up in case modem is off hook */
399	    if (!default_device && modem) {
400		setdtr(ttyfd, FALSE);
401		sleep(1);
402		setdtr(ttyfd, TRUE);
403	    }
404
405	    if (device_script(connector, ttyfd, ttyfd) < 0) {
406		syslog(LOG_ERR, "Connect script failed");
407		setdtr(ttyfd, FALSE);
408		goto fail;
409	    }
410
411	    syslog(LOG_INFO, "Serial connection established.");
412	    sleep(1);		/* give it time to set up its terminal */
413	}
414
415	/* set line speed, flow control, etc.; clear CLOCAL if modem option */
416	set_up_tty(ttyfd, 0);
417
418	/* run welcome script, if any */
419	if (welcomer && welcomer[0]) {
420	    if (device_script(welcomer, ttyfd, ttyfd) < 0)
421		syslog(LOG_WARNING, "Welcome script failed");
422	}
423
424	/* set up the serial device as a ppp interface */
425	establish_ppp(ttyfd);
426
427	if (!demand) {
428
429	    syslog(LOG_INFO, "Using interface ppp%d", ifunit);
430	    (void) sprintf(ifname, "ppp%d", ifunit);
431
432	    /* write pid to file */
433	    (void) sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname);
434	    if ((pidfile = fopen(pidfilename, "w")) != NULL) {
435		fprintf(pidfile, "%d\n", pid);
436		(void) fclose(pidfile);
437	    } else {
438		syslog(LOG_ERR, "Failed to create pid file %s: %m",
439		       pidfilename);
440		pidfilename[0] = 0;
441	    }
442	}
443
444	/*
445	 * Set a timeout to close the connection once the maximum
446	 * connect time has expired.
447	 */
448	if (maxconnect > 0)
449	    TIMEOUT(connect_time_expired, 0, maxconnect);
450
451	/*
452	 * Start opening the connection and wait for
453	 * incoming events (reply, timeout, etc.).
454	 */
455	syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam);
456	lcp_lowerup(0);
457	lcp_open(0);		/* Start protocol */
458	for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) {
459	    wait_input(timeleft(&timo));
460	    calltimeout();
461	    get_input();
462	    if (kill_link) {
463		lcp_close(0, "User request");
464		phase = PHASE_TERMINATE;
465		kill_link = 0;
466	    }
467	    if (open_ccp_flag) {
468		if (phase == PHASE_NETWORK) {
469		    ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */
470		    ccp_open(0);
471		}
472		open_ccp_flag = 0;
473	    }
474	    reap_kids();	/* Don't leave dead kids lying around */
475	}
476
477	/*
478	 * If we may want to bring the link up again, transfer
479	 * the ppp unit back to the loopback.  Set the
480	 * real serial device back to its normal mode of operation.
481	 */
482	clean_check();
483	if (demand)
484	    restore_loop();
485	disestablish_ppp(ttyfd);
486
487	/*
488	 * Run disconnector script, if requested.
489	 * XXX we may not be able to do this if the line has hung up!
490	 */
491	if (disconnector && !hungup) {
492	    set_up_tty(ttyfd, 1);
493	    if (device_script(disconnector, ttyfd, ttyfd) < 0) {
494		syslog(LOG_WARNING, "disconnect script failed");
495	    } else {
496		syslog(LOG_INFO, "Serial link disconnected.");
497	    }
498	}
499
500    fail:
501	close_tty();
502	if (locked) {
503	    unlock();
504	    locked = 0;
505	}
506
507	if (!demand) {
508	    if (unlink(pidfilename) < 0 && errno != ENOENT)
509		syslog(LOG_WARNING, "unable to delete pid file: %m");
510	    pidfilename[0] = 0;
511	}
512
513	if (!persist)
514	    break;
515
516	if (demand)
517	    demand_discard();
518	if (holdoff > 0) {
519	    phase = PHASE_HOLDOFF;
520	    TIMEOUT(holdoff_end, NULL, holdoff);
521	    do {
522		wait_time(timeleft(&timo));
523		calltimeout();
524		if (kill_link) {
525		    if (!persist)
526			die(0);
527		    kill_link = 0;
528		    phase = PHASE_DORMANT; /* allow signal to end holdoff */
529		}
530		reap_kids();
531	    } while (phase == PHASE_HOLDOFF);
532	}
533    }
534
535    die(0);
536}
537
538/*
539 * holdoff_end - called via a timeout when the holdoff period ends.
540 */
541static void
542holdoff_end(arg)
543    void *arg;
544{
545    phase = PHASE_DORMANT;
546}
547
548/*
549 * get_input - called when incoming data is available.
550 */
551static void
552get_input()
553{
554    int len, i;
555    u_char *p;
556    u_short protocol;
557    struct protent *protp;
558
559    p = inpacket_buf;	/* point to beginning of packet buffer */
560
561    len = read_packet(inpacket_buf);
562    if (len < 0)
563	return;
564
565    if (len == 0) {
566	syslog(LOG_NOTICE, "Modem hangup");
567	hungup = 1;
568	lcp_lowerdown(0);	/* serial link is no longer available */
569	link_terminated(0);
570	return;
571    }
572
573    if (debug /*&& (debugflags & DBG_INPACKET)*/)
574	log_packet(p, len, "rcvd ");
575
576    if (len < PPP_HDRLEN) {
577	MAINDEBUG((LOG_INFO, "io(): Received short packet."));
578	return;
579    }
580
581    p += 2;				/* Skip address and control */
582    GETSHORT(protocol, p);
583    len -= PPP_HDRLEN;
584
585    /*
586     * Toss all non-LCP packets unless LCP is OPEN.
587     */
588    if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) {
589	MAINDEBUG((LOG_INFO,
590		   "io(): Received non-LCP packet when LCP not open."));
591	return;
592    }
593
594    /*
595     * Upcall the proper protocol input routine.
596     */
597    for (i = 0; (protp = protocols[i]) != NULL; ++i) {
598	if (protp->protocol == protocol && protp->enabled_flag) {
599	    (*protp->input)(0, p, len);
600	    return;
601	}
602        if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag
603	    && protp->datainput != NULL) {
604	    (*protp->datainput)(0, p, len);
605	    return;
606	}
607    }
608
609    if (debug)
610    	syslog(LOG_WARNING, "Unsupported protocol (0x%x) received", protocol);
611    lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN);
612}
613
614
615/*
616 * quit - Clean up state and exit (with an error indication).
617 */
618void
619quit()
620{
621    die(1);
622}
623
624/*
625 * die - like quit, except we can specify an exit status.
626 */
627void
628die(status)
629    int status;
630{
631    cleanup();
632    syslog(LOG_INFO, "Exit.");
633    exit(status);
634}
635
636/*
637 * connect_time_expired - log a message and close the connection.
638 */
639static void
640connect_time_expired(arg)
641    caddr_t arg;
642{
643    syslog(LOG_INFO, "Connect time expired");
644
645    phase = PHASE_TERMINATE;
646    lcp_close(0, "Connect time expired");	/* Close connection */
647}
648
649/*
650 * cleanup - restore anything which needs to be restored before we exit
651 */
652/* ARGSUSED */
653static void
654cleanup()
655{
656    sys_cleanup();
657
658    if (ttyfd >= 0)
659	close_tty();
660
661    if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT)
662	syslog(LOG_WARNING, "unable to delete pid file: %m");
663    pidfilename[0] = 0;
664
665    if (locked)
666	unlock();
667}
668
669/*
670 * close_tty - restore the terminal device and close it.
671 */
672static void
673close_tty()
674{
675    disestablish_ppp(ttyfd);
676
677    /* drop dtr to hang up */
678    if (modem) {
679	setdtr(ttyfd, FALSE);
680	/*
681	 * This sleep is in case the serial port has CLOCAL set by default,
682	 * and consequently will reassert DTR when we close the device.
683	 */
684	sleep(1);
685    }
686
687    restore_tty(ttyfd);
688
689    close(ttyfd);
690    ttyfd = -1;
691}
692
693
694struct	callout {
695    struct timeval	c_time;		/* time at which to call routine */
696    caddr_t		c_arg;		/* argument to routine */
697    void		(*c_func)();	/* routine */
698    struct		callout *c_next;
699};
700
701static struct callout *callout = NULL;	/* Callout list */
702static struct timeval timenow;		/* Current time */
703
704/*
705 * timeout - Schedule a timeout.
706 *
707 * Note that this timeout takes the number of seconds, NOT hz (as in
708 * the kernel).
709 */
710void
711timeout(func, arg, time)
712    void (*func)();
713    caddr_t arg;
714    int time;
715{
716    struct callout *newp, *p, **pp;
717
718    MAINDEBUG((LOG_DEBUG, "Timeout %lx:%lx in %d seconds.",
719	       (long) func, (long) arg, time));
720
721    /*
722     * Allocate timeout.
723     */
724    if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) {
725	syslog(LOG_ERR, "Out of memory in timeout()!");
726	die(1);
727    }
728    newp->c_arg = arg;
729    newp->c_func = func;
730    gettimeofday(&timenow, NULL);
731    newp->c_time.tv_sec = timenow.tv_sec + time;
732    newp->c_time.tv_usec = timenow.tv_usec;
733
734    /*
735     * Find correct place and link it in.
736     */
737    for (pp = &callout; (p = *pp); pp = &p->c_next)
738	if (newp->c_time.tv_sec < p->c_time.tv_sec
739	    || (newp->c_time.tv_sec == p->c_time.tv_sec
740		&& newp->c_time.tv_usec < p->c_time.tv_sec))
741	    break;
742    newp->c_next = p;
743    *pp = newp;
744}
745
746
747/*
748 * untimeout - Unschedule a timeout.
749 */
750void
751untimeout(func, arg)
752    void (*func)();
753    caddr_t arg;
754{
755    struct callout **copp, *freep;
756
757    MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg));
758
759    /*
760     * Find first matching timeout and remove it from the list.
761     */
762    for (copp = &callout; (freep = *copp); copp = &freep->c_next)
763	if (freep->c_func == func && freep->c_arg == arg) {
764	    *copp = freep->c_next;
765	    (void) free((char *) freep);
766	    break;
767	}
768}
769
770
771/*
772 * calltimeout - Call any timeout routines which are now due.
773 */
774static void
775calltimeout()
776{
777    struct callout *p;
778
779    while (callout != NULL) {
780	p = callout;
781
782	if (gettimeofday(&timenow, NULL) < 0) {
783	    syslog(LOG_ERR, "Failed to get time of day: %m");
784	    die(1);
785	}
786	if (!(p->c_time.tv_sec < timenow.tv_sec
787	      || (p->c_time.tv_sec == timenow.tv_sec
788		  && p->c_time.tv_usec <= timenow.tv_usec)))
789	    break;		/* no, it's not time yet */
790
791	callout = p->c_next;
792	(*p->c_func)(p->c_arg);
793
794	free((char *) p);
795    }
796}
797
798
799/*
800 * timeleft - return the length of time until the next timeout is due.
801 */
802static struct timeval *
803timeleft(tvp)
804    struct timeval *tvp;
805{
806    if (callout == NULL)
807	return NULL;
808
809    gettimeofday(&timenow, NULL);
810    tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec;
811    tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec;
812    if (tvp->tv_usec < 0) {
813	tvp->tv_usec += 1000000;
814	tvp->tv_sec -= 1;
815    }
816    if (tvp->tv_sec < 0)
817	tvp->tv_sec = tvp->tv_usec = 0;
818
819    return tvp;
820}
821
822
823/*
824 * hup - Catch SIGHUP signal.
825 *
826 * Indicates that the physical layer has been disconnected.
827 * We don't rely on this indication; if the user has sent this
828 * signal, we just take the link down.
829 */
830static void
831hup(sig)
832    int sig;
833{
834    syslog(LOG_INFO, "Hangup (SIGHUP)");
835    kill_link = 1;
836}
837
838
839/*
840 * term - Catch SIGTERM signal and SIGINT signal (^C/del).
841 *
842 * Indicates that we should initiate a graceful disconnect and exit.
843 */
844/*ARGSUSED*/
845static void
846term(sig)
847    int sig;
848{
849    syslog(LOG_INFO, "Terminating on signal %d.", sig);
850    persist = 0;		/* don't try to restart */
851    kill_link = 1;
852}
853
854
855/*
856 * chld - Catch SIGCHLD signal.
857 * Calls reap_kids to get status for any dead kids.
858 */
859static void
860chld(sig)
861    int sig;
862{
863    reap_kids();
864}
865
866
867/*
868 * toggle_debug - Catch SIGUSR1 signal.
869 *
870 * Toggle debug flag.
871 */
872/*ARGSUSED*/
873static void
874toggle_debug(sig)
875    int sig;
876{
877    debug = !debug;
878    note_debug_level();
879}
880
881
882/*
883 * open_ccp - Catch SIGUSR2 signal.
884 *
885 * Try to (re)negotiate compression.
886 */
887/*ARGSUSED*/
888static void
889open_ccp(sig)
890    int sig;
891{
892    open_ccp_flag = 1;
893}
894
895
896/*
897 * bad_signal - We've caught a fatal signal.  Clean up state and exit.
898 */
899static void
900bad_signal(sig)
901    int sig;
902{
903    syslog(LOG_ERR, "Fatal signal %d", sig);
904    die(1);
905}
906
907
908/*
909 * device_script - run a program to connect or disconnect the
910 * serial device.
911 */
912static int
913device_script(program, in, out)
914    char *program;
915    int in, out;
916{
917    int pid;
918    int status;
919    int errfd;
920
921    pid = fork();
922
923    if (pid < 0) {
924	syslog(LOG_ERR, "Failed to create child process: %m");
925	die(1);
926    }
927
928    if (pid == 0) {
929	sys_close();
930	dup2(in, 0);
931	dup2(out, 1);
932	errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644);
933	if (errfd >= 0)
934	    dup2(errfd, 2);
935	setuid(getuid());
936	setgid(getgid());
937	execl("/bin/sh", "sh", "-c", program, (char *)0);
938	syslog(LOG_ERR, "could not exec /bin/sh: %m");
939	_exit(99);
940	/* NOTREACHED */
941    }
942
943    while (waitpid(pid, &status, 0) < 0) {
944	if (errno == EINTR)
945	    continue;
946	syslog(LOG_ERR, "error waiting for (dis)connection process: %m");
947	die(1);
948    }
949
950    return (status == 0 ? 0 : -1);
951}
952
953
954/*
955 * run-program - execute a program with given arguments,
956 * but don't wait for it.
957 * If the program can't be executed, logs an error unless
958 * must_exist is 0 and the program file doesn't exist.
959 */
960int
961run_program(prog, args, must_exist)
962    char *prog;
963    char **args;
964    int must_exist;
965{
966    int pid;
967
968    pid = fork();
969    if (pid == -1) {
970	syslog(LOG_ERR, "Failed to create child process for %s: %m", prog);
971	return -1;
972    }
973    if (pid == 0) {
974	int new_fd;
975
976	/* Leave the current location */
977	(void) setsid();    /* No controlling tty. */
978	(void) umask (S_IRWXG|S_IRWXO);
979	(void) chdir ("/"); /* no current directory. */
980	setuid(geteuid());
981	setgid(getegid());
982
983	/* Ensure that nothing of our device environment is inherited. */
984	sys_close();
985	close (0);
986	close (1);
987	close (2);
988	close (ttyfd);  /* tty interface to the ppp device */
989
990        /* Don't pass handles to the PPP device, even by accident. */
991	new_fd = open (_PATH_DEVNULL, O_RDWR);
992	if (new_fd >= 0) {
993	    if (new_fd != 0) {
994	        dup2  (new_fd, 0); /* stdin <- /dev/null */
995		close (new_fd);
996	    }
997	    dup2 (0, 1); /* stdout -> /dev/null */
998	    dup2 (0, 2); /* stderr -> /dev/null */
999	}
1000
1001#ifdef BSD
1002	/* Force the priority back to zero if pppd is running higher. */
1003	if (setpriority (PRIO_PROCESS, 0, 0) < 0)
1004	    syslog (LOG_WARNING, "can't reset priority to 0: %m");
1005#endif
1006
1007	/* SysV recommends a second fork at this point. */
1008
1009	execve(prog, args);
1010	if (must_exist || errno != ENOENT)
1011	    syslog(LOG_WARNING, "Can't execute %s: %m", prog);
1012	_exit(-1);
1013    }
1014    MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %d", prog, pid));
1015    ++n_children;
1016    return 0;
1017}
1018
1019
1020/*
1021 * reap_kids - get status from any dead child processes,
1022 * and log a message for abnormal terminations.
1023 */
1024static void
1025reap_kids()
1026{
1027    int pid, status;
1028
1029    if (n_children == 0)
1030	return;
1031    if ((pid = waitpid(-1, &status, WNOHANG)) == -1) {
1032	if (errno != ECHILD)
1033	    syslog(LOG_ERR, "Error waiting for child process: %m");
1034	return;
1035    }
1036    if (pid > 0) {
1037	--n_children;
1038	if (WIFSIGNALED(status)) {
1039	    syslog(LOG_WARNING, "Child process %d terminated with signal %d",
1040		   pid, WTERMSIG(status));
1041	}
1042    }
1043}
1044
1045
1046/*
1047 * log_packet - format a packet and log it.
1048 */
1049
1050char line[256];			/* line to be logged accumulated here */
1051char *linep;
1052
1053void
1054log_packet(p, len, prefix)
1055    u_char *p;
1056    int len;
1057    char *prefix;
1058{
1059    strcpy(line, prefix);
1060    linep = line + strlen(line);
1061    format_packet(p, len, pr_log, NULL);
1062    if (linep != line)
1063	syslog(LOG_DEBUG, "%s", line);
1064}
1065
1066/*
1067 * format_packet - make a readable representation of a packet,
1068 * calling `printer(arg, format, ...)' to output it.
1069 */
1070void
1071format_packet(p, len, printer, arg)
1072    u_char *p;
1073    int len;
1074    void (*printer) __P((void *, char *, ...));
1075    void *arg;
1076{
1077    int i, n;
1078    u_short proto;
1079    u_char x;
1080    struct protent *protp;
1081
1082    if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {
1083	p += 2;
1084	GETSHORT(proto, p);
1085	len -= PPP_HDRLEN;
1086	for (i = 0; (protp = protocols[i]) != NULL; ++i)
1087	    if (proto == protp->protocol)
1088		break;
1089	if (protp != NULL) {
1090	    printer(arg, "[%s", protp->name);
1091	    n = (*protp->printpkt)(p, len, printer, arg);
1092	    printer(arg, "]");
1093	    p += n;
1094	    len -= n;
1095	} else {
1096	    printer(arg, "[proto=0x%x]", proto);
1097	}
1098    }
1099
1100    for (; len > 0; --len) {
1101	GETCHAR(x, p);
1102	printer(arg, " %.2x", x);
1103    }
1104}
1105
1106#ifdef __STDC__
1107#include <stdarg.h>
1108
1109static void
1110pr_log(void *arg, char *fmt, ...)
1111{
1112    int n;
1113    va_list pvar;
1114    char buf[256];
1115
1116    va_start(pvar, fmt);
1117    vsprintf(buf, fmt, pvar);
1118    va_end(pvar);
1119
1120    n = strlen(buf);
1121    if (linep + n + 1 > line + sizeof(line)) {
1122	syslog(LOG_DEBUG, "%s", line);
1123	linep = line;
1124    }
1125    strcpy(linep, buf);
1126    linep += n;
1127}
1128
1129#else /* __STDC__ */
1130#include <varargs.h>
1131
1132static void
1133pr_log(arg, fmt, va_alist)
1134void *arg;
1135char *fmt;
1136va_dcl
1137{
1138    int n;
1139    va_list pvar;
1140    char buf[256];
1141
1142    va_start(pvar);
1143    vsprintf(buf, fmt, pvar);
1144    va_end(pvar);
1145
1146    n = strlen(buf);
1147    if (linep + n + 1 > line + sizeof(line)) {
1148	syslog(LOG_DEBUG, "%s", line);
1149	linep = line;
1150    }
1151    strcpy(linep, buf);
1152    linep += n;
1153}
1154#endif
1155
1156/*
1157 * print_string - print a readable representation of a string using
1158 * printer.
1159 */
1160void
1161print_string(p, len, printer, arg)
1162    char *p;
1163    int len;
1164    void (*printer) __P((void *, char *, ...));
1165    void *arg;
1166{
1167    int c;
1168
1169    printer(arg, "\"");
1170    for (; len > 0; --len) {
1171	c = *p++;
1172	if (' ' <= c && c <= '~')
1173	    printer(arg, "%c", c);
1174	else
1175	    printer(arg, "\\%.3o", c);
1176    }
1177    printer(arg, "\"");
1178}
1179
1180/*
1181 * novm - log an error message saying we ran out of memory, and die.
1182 */
1183void
1184novm(msg)
1185    char *msg;
1186{
1187    syslog(LOG_ERR, "Virtual memory exhausted allocating %s\n", msg);
1188    die(1);
1189}
1190