1/*
2 * sys-linux.c - System-dependent procedures for setting up
3 * PPP interfaces on Linux systems
4 *
5 * Copyright (c) 1994-2004 Paul Mackerras. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 *
14 * 2. The name(s) of the authors of this software must not be used to
15 *    endorse or promote products derived from this software without
16 *    prior written permission.
17 *
18 * 3. Redistributions of any form whatsoever must retain the following
19 *    acknowledgment:
20 *    "This product includes software developed by Paul Mackerras
21 *     <paulus@samba.org>".
22 *
23 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
24 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
25 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
26 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
27 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
28 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
29 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30 *
31 * Derived from main.c and pppd.h, which are:
32 *
33 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 *
39 * 1. Redistributions of source code must retain the above copyright
40 *    notice, this list of conditions and the following disclaimer.
41 *
42 * 2. Redistributions in binary form must reproduce the above copyright
43 *    notice, this list of conditions and the following disclaimer in
44 *    the documentation and/or other materials provided with the
45 *    distribution.
46 *
47 * 3. The name "Carnegie Mellon University" must not be used to
48 *    endorse or promote products derived from this software without
49 *    prior written permission. For permission or any legal
50 *    details, please contact
51 *      Office of Technology Transfer
52 *      Carnegie Mellon University
53 *      5000 Forbes Avenue
54 *      Pittsburgh, PA  15213-3890
55 *      (412) 268-4387, fax: (412) 268-7395
56 *      tech-transfer@andrew.cmu.edu
57 *
58 * 4. Redistributions of any form whatsoever must retain the following
59 *    acknowledgment:
60 *    "This product includes software developed by Computing Services
61 *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
62 *
63 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
64 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
65 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
66 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
67 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
68 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
69 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
70 */
71
72#include <sys/ioctl.h>
73#include <sys/types.h>
74#include <sys/socket.h>
75#include <sys/time.h>
76#include <sys/errno.h>
77#include <sys/file.h>
78#include <sys/stat.h>
79#include <sys/utsname.h>
80#include <sys/sysmacros.h>
81
82#include <stdio.h>
83#include <stdlib.h>
84#include <syslog.h>
85#include <string.h>
86#include <time.h>
87#include <memory.h>
88#include <utmp.h>
89#include <mntent.h>
90#include <signal.h>
91#include <fcntl.h>
92#include <ctype.h>
93#include <termios.h>
94#include <unistd.h>
95#include <paths.h>
96
97/* This is in netdevice.h. However, this compile will fail miserably if
98   you attempt to include netdevice.h because it has so many references
99   to __memcpy functions which it should not attempt to do. So, since I
100   really don't use it, but it must be defined, define it now. */
101
102#ifndef MAX_ADDR_LEN
103#define xxMAX_ADDR_LEN 7
104#endif
105
106#if __GLIBC__ >= 2
107#include <asm/types.h>		/* glibc 2 conflicts with linux/types.h */
108#include <net/if.h>
109#include <net/if_arp.h>
110#include <net/route.h>
111#include <netinet/if_ether.h>
112#else
113#include <linux/types.h>
114#include <linux/if.h>
115#include <linux/if_arp.h>
116#include <linux/route.h>
117#include <linux/if_ether.h>
118#endif
119#include <linux/sockios.h>
120#include <netinet/in.h>
121#include <arpa/inet.h>
122
123#include <linux/ppp_defs.h>
124#include <linux/if_ppp.h>
125
126#include "pppd.h"
127#include "fsm.h"
128#include "ipcp.h"
129
130#ifdef IPX_CHANGE
131#include "ipxcp.h"
132#if __GLIBC__ >= 2 && \
133    !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
134#include <netipx/ipx.h>
135#else
136#include <linux/ipx.h>
137#endif
138#endif /* IPX_CHANGE */
139
140#ifdef PPP_FILTER
141#include <pcap-bpf.h>
142#include <linux/filter.h>
143#endif /* PPP_FILTER */
144
145#ifdef LOCKLIB
146#include <sys/locks.h>
147#endif
148
149#ifdef INET6
150#ifndef _LINUX_IN6_H
151/*
152 *    This is in linux/include/net/ipv6.h.
153 */
154
155struct in6_ifreq {
156    struct in6_addr ifr6_addr;
157    __u32 ifr6_prefixlen;
158    unsigned int ifr6_ifindex;
159};
160#endif
161
162#define IN6_LLADDR_FROM_EUI64(sin6, eui64) do {			\
163	memset(&sin6.s6_addr, 0, sizeof(struct in6_addr));	\
164	sin6.s6_addr16[0] = htons(0xfe80);			\
165	eui64_copy(eui64, sin6.s6_addr32[2]);			\
166	} while (0)
167
168#endif /* INET6 */
169
170/* We can get an EIO error on an ioctl if the modem has hung up */
171#define ok_error(num) ((num)==EIO)
172
173static int tty_disc = N_TTY;	/* The TTY discipline */
174static int ppp_disc = N_PPP;	/* The PPP discpline */
175static int initfdflags = -1;	/* Initial file descriptor flags for fd */
176static int ppp_fd = -1;		/* fd which is set to PPP discipline */
177static int sock_fd = -1;	/* socket for doing interface ioctls */
178static int slave_fd = -1;	/* pty for old-style demand mode, slave */
179static int master_fd = -1;	/* pty for old-style demand mode, master */
180#ifdef INET6
181static int sock6_fd = -1;
182#endif /* INET6 */
183
184/*
185 * For the old-style kernel driver, this is the same as ppp_fd.
186 * For the new-style driver, it is the fd of an instance of /dev/ppp
187 * which is attached to the ppp unit and is used for controlling it.
188 */
189int ppp_dev_fd = -1;		/* fd for /dev/ppp (new style driver) */
190
191static int chindex;		/* channel index (new style driver) */
192
193static fd_set in_fds;		/* set of fds that wait_input waits for */
194static int max_in_fd;		/* highest fd set in in_fds */
195
196static int has_proxy_arp       = 0;
197static int driver_version      = 0;
198static int driver_modification = 0;
199static int driver_patch        = 0;
200static int driver_is_old       = 0;
201static int restore_term        = 0;	/* 1 => we've munged the terminal */
202static struct termios inittermios;	/* Initial TTY termios */
203
204int new_style_driver = 0;
205
206static char loop_name[20];
207static unsigned char inbuf[512]; /* buffer for chars read from loopback */
208
209static int	if_is_up;	/* Interface has been marked up */
210static u_int32_t default_route_gateway;	/* Gateway for default route added */
211static u_int32_t proxy_arp_addr;	/* Addr for proxy arp entry added */
212static char proxy_arp_dev[16];		/* Device for proxy arp entry */
213static u_int32_t our_old_addr;		/* for detecting address changes */
214static int	dynaddr_set;		/* 1 if ip_dynaddr set */
215static int	looped;			/* 1 if using loop */
216static int	link_mtu;		/* mtu for the link (not bundle) */
217
218static struct utsname utsname;	/* for the kernel version */
219static int kernel_version;
220#define KVERSION(j,n,p)	((j)*1000000 + (n)*1000 + (p))
221
222#define MAX_IFS		100
223
224#define FLAGS_GOOD (IFF_UP          | IFF_BROADCAST)
225#define FLAGS_MASK (IFF_UP          | IFF_BROADCAST | \
226		    IFF_POINTOPOINT | IFF_LOOPBACK  | IFF_NOARP)
227
228#define SIN_ADDR(x)	(((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
229
230/* Prototypes for procedures local to this file. */
231static int modify_flags(int fd, int clear_bits, int set_bits);
232static int translate_speed (int bps);
233static int baud_rate_of (int speed);
234static void close_route_table (void);
235static int open_route_table (void);
236static int read_route_table (struct rtentry *rt);
237static int defaultroute_exists (struct rtentry *rt);
238static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
239			   char *name, int namelen);
240static void decode_version (char *buf, int *version, int *mod, int *patch);
241static int set_kdebugflag(int level);
242static int ppp_registered(void);
243static int make_ppp_unit(void);
244
245extern u_char	inpacket_buf[];	/* borrowed from main.c */
246
247/*
248 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
249 * if it exists.
250 */
251
252#define SET_SA_FAMILY(addr, family)			\
253    memset ((char *) &(addr), '\0', sizeof(addr));	\
254    addr.sa_family = (family);
255
256/*
257 * Determine if the PPP connection should still be present.
258 */
259
260extern int hungup;
261
262/* new_fd is the fd of a tty */
263static void set_ppp_fd (int new_fd)
264{
265	ppp_fd = new_fd;
266	if (!new_style_driver)
267		ppp_dev_fd = new_fd;
268}
269
270static int still_ppp(void)
271{
272	if (new_style_driver)
273		return !hungup && ppp_fd >= 0;
274	if (!hungup || ppp_fd == slave_fd)
275		return 1;
276	if (slave_fd >= 0) {
277		set_ppp_fd(slave_fd);
278		return 1;
279	}
280	return 0;
281}
282
283/*
284 * modify_flags - set and clear flag bits controlling the kernel
285 * PPP driver.
286 */
287static int modify_flags(int fd, int clear_bits, int set_bits)
288{
289	int flags;
290
291	if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
292		goto err;
293	flags = (flags & ~clear_bits) | set_bits;
294	if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
295		goto err;
296
297	return 0;
298
299 err:
300	if (errno != EIO)
301		error("Failed to set PPP kernel option flags: %m");
302	return -1;
303}
304
305/********************************************************************
306 *
307 * sys_init - System-dependent initialization.
308 */
309
310void sys_init(void)
311{
312    /* Get an internet socket for doing socket ioctls. */
313    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
314    if (sock_fd < 0)
315	fatal("Couldn't create IP socket: %m(%d)", errno);
316
317#ifdef INET6
318    sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
319    if (sock6_fd < 0)
320	sock6_fd = -errno;	/* save errno for later */
321#endif
322
323    FD_ZERO(&in_fds);
324    max_in_fd = 0;
325}
326
327/********************************************************************
328 *
329 * sys_cleanup - restore any system state we modified before exiting:
330 * mark the interface down, delete default route and/or proxy arp entry.
331 * This shouldn't call die() because it's called from die().
332 */
333
334void sys_cleanup(void)
335{
336/*
337 * Take down the device
338 */
339    if (if_is_up) {
340	if_is_up = 0;
341	sifdown(0);
342    }
343/*
344 * Delete any routes through the device.
345 */
346    if (default_route_gateway != 0)
347	cifdefaultroute(0, 0, default_route_gateway);
348
349    if (has_proxy_arp)
350	cifproxyarp(0, proxy_arp_addr);
351}
352
353/********************************************************************
354 *
355 * sys_close - Clean up in a child process before execing.
356 */
357void
358sys_close(void)
359{
360    if (new_style_driver && ppp_dev_fd >= 0)
361	close(ppp_dev_fd);
362    if (sock_fd >= 0)
363	close(sock_fd);
364#ifdef INET6
365    if (sock6_fd >= 0)
366	close(sock6_fd);
367#endif
368    if (slave_fd >= 0)
369	close(slave_fd);
370    if (master_fd >= 0)
371	close(master_fd);
372}
373
374/********************************************************************
375 *
376 * set_kdebugflag - Define the debugging level for the kernel
377 */
378
379static int set_kdebugflag (int requested_level)
380{
381    if (ppp_dev_fd < 0)
382	return 1;
383    if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
384	if ( ! ok_error (errno) )
385	    error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
386	return (0);
387    }
388    return (1);
389}
390
391/********************************************************************
392 *
393 * tty_establish_ppp - Turn the serial port into a ppp interface.
394 */
395
396int tty_establish_ppp (int tty_fd)
397{
398    int ret_fd;
399
400/*
401 * Ensure that the tty device is in exclusive mode.
402 */
403    if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
404	if ( ! ok_error ( errno ))
405	    warn("Couldn't make tty exclusive: %m");
406    }
407/*
408 * Demand mode - prime the old ppp device to relinquish the unit.
409 */
410    if (!new_style_driver && looped
411	&& ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
412	error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
413	return -1;
414    }
415/*
416 * Set the current tty to the PPP discpline
417 */
418
419#ifndef N_SYNC_PPP
420#define N_SYNC_PPP 14
421#endif
422    ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
423    if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
424	if ( ! ok_error (errno) ) {
425	    error("Couldn't set tty to PPP discipline: %m");
426	    return -1;
427	}
428    }
429
430    ret_fd = generic_establish_ppp(tty_fd);
431
432#define SC_RCVB	(SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
433#define SC_LOGB	(SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
434		 | SC_LOG_FLUSH)
435
436    if (ret_fd >= 0) {
437	modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
438		     (kdebugflag * SC_DEBUG) & SC_LOGB);
439    } else {
440	if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
441	    warn("Couldn't reset tty to normal line discipline: %m");
442    }
443
444    return ret_fd;
445}
446
447/********************************************************************
448 *
449 * generic_establish_ppp - Turn the fd into a ppp interface.
450 */
451int generic_establish_ppp (int fd)
452{
453    int x;
454
455    if (new_style_driver) {
456	int flags;
457
458	/* Open an instance of /dev/ppp and connect the channel to it */
459	if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
460	    error("Couldn't get channel number: %m");
461	    goto err;
462	}
463	dbglog("using channel %d", chindex);
464	fd = open("/dev/ppp", O_RDWR);
465	if (fd < 0) {
466	    error("Couldn't reopen /dev/ppp: %m");
467	    goto err;
468	}
469	(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
470	if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
471	    error("Couldn't attach to channel %d: %m", chindex);
472	    goto err_close;
473	}
474	flags = fcntl(fd, F_GETFL);
475	if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
476	    warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
477	set_ppp_fd(fd);
478
479	if (!looped)
480	    ifunit = -1;
481	if (!looped && !multilink) {
482	    /*
483	     * Create a new PPP unit.
484	     */
485	    if (make_ppp_unit() < 0)
486		goto err_close;
487	}
488
489	if (looped)
490	    modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
491
492	if (!multilink) {
493	    add_fd(ppp_dev_fd);
494	    if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
495		error("Couldn't attach to PPP unit %d: %m", ifunit);
496		goto err_close;
497	    }
498	}
499
500    } else {
501	/*
502	 * Old-style driver: find out which interface we were given.
503	 */
504	set_ppp_fd (fd);
505	if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
506	    if (ok_error (errno))
507		goto err;
508	    fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
509	}
510	/* Check that we got the same unit again. */
511	if (looped && x != ifunit)
512	    fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
513	ifunit = x;
514
515	/*
516	 * Fetch the initial file flags and reset blocking mode on the file.
517	 */
518	initfdflags = fcntl(fd, F_GETFL);
519	if (initfdflags == -1 ||
520	    fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
521	    if ( ! ok_error (errno))
522		warn("Couldn't set device to non-blocking mode: %m");
523	}
524    }
525
526    /*
527     * Enable debug in the driver if requested.
528     */
529    if (!looped)
530	set_kdebugflag (kdebugflag);
531
532    looped = 0;
533
534    return ppp_fd;
535
536 err_close:
537    close(fd);
538 err:
539    return -1;
540}
541
542/********************************************************************
543 *
544 * tty_disestablish_ppp - Restore the serial port to normal operation.
545 * This shouldn't call die() because it's called from die().
546 */
547
548void tty_disestablish_ppp(int tty_fd)
549{
550    if (!hungup) {
551/*
552 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
553 */
554	if (tcflush(tty_fd, TCIOFLUSH) < 0)
555	{
556	    warn("tcflush failed: %m");
557	    goto flushfailed;
558	}
559/*
560 * Restore the previous line discipline
561 */
562	if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
563	    if ( ! ok_error (errno))
564		error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
565	}
566
567	if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
568	    if ( ! ok_error (errno))
569		warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
570	}
571
572	/* Reset non-blocking mode on fd. */
573	if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
574	    if ( ! ok_error (errno))
575		warn("Couldn't restore device fd flags: %m");
576	}
577    }
578flushfailed:
579    initfdflags = -1;
580
581    generic_disestablish_ppp(tty_fd);
582}
583
584/********************************************************************
585 *
586 * generic_disestablish_ppp - Restore device components to normal
587 * operation, and reconnect the ppp unit to the loopback if in demand
588 * mode.  This shouldn't call die() because it's called from die().
589 */
590void generic_disestablish_ppp(int dev_fd)
591{
592    if (new_style_driver) {
593	close(ppp_fd);
594	ppp_fd = -1;
595	if (demand) {
596	    modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
597	    looped = 1;
598	} else if (!doing_multilink && ppp_dev_fd >= 0) {
599	    close(ppp_dev_fd);
600	    remove_fd(ppp_dev_fd);
601	    ppp_dev_fd = -1;
602	}
603    } else {
604	/* old-style driver */
605	if (demand)
606	    set_ppp_fd(slave_fd);
607	else
608	    ppp_dev_fd = -1;
609    }
610}
611
612/*
613 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
614 * Assumes new_style_driver.
615 */
616static int make_ppp_unit()
617{
618	int x, flags;
619
620	if (ppp_dev_fd >= 0) {
621		dbglog("in make_ppp_unit, already had /dev/ppp open?");
622		close(ppp_dev_fd);
623	}
624	ppp_dev_fd = open("/dev/ppp", O_RDWR);
625	if (ppp_dev_fd < 0)
626		fatal("Couldn't open /dev/ppp: %m");
627	flags = fcntl(ppp_dev_fd, F_GETFL);
628	if (flags == -1
629	    || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
630		warn("Couldn't set /dev/ppp to nonblock: %m");
631
632	ifunit = req_unit;
633	x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
634	if (x < 0 && req_unit >= 0 && errno == EEXIST) {
635		warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
636		ifunit = -1;
637		x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
638	}
639	if (x < 0)
640		error("Couldn't create new ppp unit: %m");
641	return x;
642}
643
644/*
645 * cfg_bundle - configure the existing bundle.
646 * Used in demand mode.
647 */
648void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
649{
650	if (!new_style_driver)
651		return;
652
653	/* set the mrru, mtu and flags */
654	if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
655		error("Couldn't set MRRU: %m");
656
657	modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
658		     ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
659		      | (mrru? SC_MULTILINK: 0)));
660
661	/* connect up the channel */
662	if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
663		fatal("Couldn't attach to PPP unit %d: %m", ifunit);
664	add_fd(ppp_dev_fd);
665}
666
667/*
668 * make_new_bundle - create a new PPP unit (i.e. a bundle)
669 * and connect our channel to it.  This should only get called
670 * if `multilink' was set at the time establish_ppp was called.
671 * In demand mode this uses our existing bundle instead of making
672 * a new one.
673 */
674void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
675{
676	if (!new_style_driver)
677		return;
678
679	/* make us a ppp unit */
680	if (make_ppp_unit() < 0)
681		die(1);
682
683	/* set the mrru and flags */
684	cfg_bundle(mrru, mtru, rssn, tssn);
685}
686
687/*
688 * bundle_attach - attach our link to a given PPP unit.
689 * We assume the unit is controlled by another pppd.
690 */
691int bundle_attach(int ifnum)
692{
693	int master_fd;
694
695	if (!new_style_driver)
696		return -1;
697
698	master_fd = open("/dev/ppp", O_RDWR);
699	if (master_fd < 0)
700		fatal("Couldn't open /dev/ppp: %m");
701	if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
702		if (errno == ENXIO) {
703			close(master_fd);
704			return 0;	/* doesn't still exist */
705		}
706		fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
707	}
708	if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
709		fatal("Couldn't connect to interface unit %d: %m", ifnum);
710	modify_flags(master_fd, 0, SC_MULTILINK);
711	close(master_fd);
712
713	ifunit = ifnum;
714	return 1;
715}
716
717/*
718 * destroy_bundle - tell the driver to destroy our bundle.
719 */
720void destroy_bundle(void)
721{
722	if (ppp_dev_fd >= 0) {
723		close(ppp_dev_fd);
724		remove_fd(ppp_dev_fd);
725		ppp_dev_fd = -1;
726	}
727}
728
729/********************************************************************
730 *
731 * clean_check - Fetch the flags for the device and generate
732 * appropriate error messages.
733 */
734void clean_check(void)
735{
736    int x;
737    char *s;
738
739    if (still_ppp()) {
740	if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
741	    s = NULL;
742	    switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
743	    case SC_RCV_B7_0:
744		s = "all had bit 7 set to 1";
745		break;
746
747	    case SC_RCV_B7_1:
748		s = "all had bit 7 set to 0";
749		break;
750
751	    case SC_RCV_EVNP:
752		s = "all had odd parity";
753		break;
754
755	    case SC_RCV_ODDP:
756		s = "all had even parity";
757		break;
758	    }
759
760	    if (s != NULL) {
761		warn("Receive serial link is not 8-bit clean:");
762		warn("Problem: %s", s);
763	    }
764	}
765    }
766}
767
768
769/*
770 * List of valid speeds.
771 */
772
773struct speed {
774    int speed_int, speed_val;
775} speeds[] = {
776#ifdef B50
777    { 50, B50 },
778#endif
779#ifdef B75
780    { 75, B75 },
781#endif
782#ifdef B110
783    { 110, B110 },
784#endif
785#ifdef B134
786    { 134, B134 },
787#endif
788#ifdef B150
789    { 150, B150 },
790#endif
791#ifdef B200
792    { 200, B200 },
793#endif
794#ifdef B300
795    { 300, B300 },
796#endif
797#ifdef B600
798    { 600, B600 },
799#endif
800#ifdef B1200
801    { 1200, B1200 },
802#endif
803#ifdef B1800
804    { 1800, B1800 },
805#endif
806#ifdef B2000
807    { 2000, B2000 },
808#endif
809#ifdef B2400
810    { 2400, B2400 },
811#endif
812#ifdef B3600
813    { 3600, B3600 },
814#endif
815#ifdef B4800
816    { 4800, B4800 },
817#endif
818#ifdef B7200
819    { 7200, B7200 },
820#endif
821#ifdef B9600
822    { 9600, B9600 },
823#endif
824#ifdef B19200
825    { 19200, B19200 },
826#endif
827#ifdef B38400
828    { 38400, B38400 },
829#endif
830#ifdef B57600
831    { 57600, B57600 },
832#endif
833#ifdef B76800
834    { 76800, B76800 },
835#endif
836#ifdef B115200
837    { 115200, B115200 },
838#endif
839#ifdef EXTA
840    { 19200, EXTA },
841#endif
842#ifdef EXTB
843    { 38400, EXTB },
844#endif
845#ifdef B230400
846    { 230400, B230400 },
847#endif
848#ifdef B460800
849    { 460800, B460800 },
850#endif
851#ifdef B921600
852    { 921600, B921600 },
853#endif
854    { 0, 0 }
855};
856
857/********************************************************************
858 *
859 * Translate from bits/second to a speed_t.
860 */
861
862static int translate_speed (int bps)
863{
864    struct speed *speedp;
865
866    if (bps != 0) {
867	for (speedp = speeds; speedp->speed_int; speedp++) {
868	    if (bps == speedp->speed_int)
869		return speedp->speed_val;
870	}
871	warn("speed %d not supported", bps);
872    }
873    return 0;
874}
875
876/********************************************************************
877 *
878 * Translate from a speed_t to bits/second.
879 */
880
881static int baud_rate_of (int speed)
882{
883    struct speed *speedp;
884
885    if (speed != 0) {
886	for (speedp = speeds; speedp->speed_int; speedp++) {
887	    if (speed == speedp->speed_val)
888		return speedp->speed_int;
889	}
890    }
891    return 0;
892}
893
894/********************************************************************
895 *
896 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
897 * at the requested speed, etc.  If `local' is true, set CLOCAL
898 * regardless of whether the modem option was specified.
899 */
900
901void set_up_tty(int tty_fd, int local)
902{
903    int speed;
904    struct termios tios;
905
906    setdtr(tty_fd, 1);
907    if (tcgetattr(tty_fd, &tios) < 0) {
908	if (!ok_error(errno))
909	    fatal("tcgetattr: %m (line %d)", __LINE__);
910	return;
911    }
912
913    if (!restore_term)
914	inittermios = tios;
915
916    tios.c_cflag     &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
917    tios.c_cflag     |= CS8 | CREAD | HUPCL;
918
919    tios.c_iflag      = IGNBRK | IGNPAR;
920    tios.c_oflag      = 0;
921    tios.c_lflag      = 0;
922    tios.c_cc[VMIN]   = 1;
923    tios.c_cc[VTIME]  = 0;
924
925    if (local || !modem)
926	tios.c_cflag ^= (CLOCAL | HUPCL);
927
928    switch (crtscts) {
929    case 1:
930	tios.c_cflag |= CRTSCTS;
931	break;
932
933    case -2:
934	tios.c_iflag     |= IXON | IXOFF;
935	tios.c_cc[VSTOP]  = 0x13;	/* DC3 = XOFF = ^S */
936	tios.c_cc[VSTART] = 0x11;	/* DC1 = XON  = ^Q */
937	break;
938
939    case -1:
940	tios.c_cflag &= ~CRTSCTS;
941	break;
942
943    default:
944	break;
945    }
946
947    speed = translate_speed(inspeed);
948    if (speed) {
949	cfsetospeed (&tios, speed);
950	cfsetispeed (&tios, speed);
951    }
952/*
953 * We can't proceed if the serial port speed is B0,
954 * since that implies that the serial port is disabled.
955 */
956    else {
957	speed = cfgetospeed(&tios);
958	if (speed == B0)
959	    fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
960    }
961
962    while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
963	if (errno != EINTR)
964	    fatal("tcsetattr: %m (line %d)", __LINE__);
965
966    baud_rate    = baud_rate_of(speed);
967    restore_term = 1;
968}
969
970/********************************************************************
971 *
972 * setdtr - control the DTR line on the serial port.
973 * This is called from die(), so it shouldn't call die().
974 */
975
976void setdtr (int tty_fd, int on)
977{
978    int modembits = TIOCM_DTR;
979
980    ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
981}
982
983/********************************************************************
984 *
985 * restore_tty - restore the terminal to the saved settings.
986 */
987
988void restore_tty (int tty_fd)
989{
990    if (restore_term) {
991	restore_term = 0;
992/*
993 * Turn off echoing, because otherwise we can get into
994 * a loop with the tty and the modem echoing to each other.
995 * We presume we are the sole user of this tty device, so
996 * when we close it, it will revert to its defaults anyway.
997 */
998	if (!default_device)
999	    inittermios.c_lflag &= ~(ECHO | ECHONL);
1000
1001	if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1002	    if (! ok_error (errno))
1003		warn("tcsetattr: %m (line %d)", __LINE__);
1004	}
1005    }
1006}
1007
1008/********************************************************************
1009 *
1010 * output - Output PPP packet.
1011 */
1012
1013void output (int unit, unsigned char *p, int len)
1014{
1015    int fd = ppp_fd;
1016    int proto;
1017
1018    dump_packet("sent", p, len);
1019    if (snoop_send_hook) snoop_send_hook(p, len);
1020
1021    if (len < PPP_HDRLEN)
1022	return;
1023    if (new_style_driver) {
1024	p += 2;
1025	len -= 2;
1026	proto = (p[0] << 8) + p[1];
1027	if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1028	    fd = ppp_dev_fd;
1029    }
1030    if (write(fd, p, len) < 0) {
1031	if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1032	    || errno == ENXIO || errno == EIO || errno == EINTR)
1033	    warn("write: warning: %m (%d)", errno);
1034	else
1035	    error("write: %m (%d)", errno);
1036    }
1037}
1038
1039/********************************************************************
1040 *
1041 * wait_input - wait until there is data available,
1042 * for the length of time specified by *timo (indefinite
1043 * if timo is NULL).
1044 */
1045
1046void wait_input(struct timeval *timo)
1047{
1048    fd_set ready, exc;
1049    int n;
1050
1051    ready = in_fds;
1052    exc = in_fds;
1053    n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1054    if (n < 0 && errno != EINTR)
1055	fatal("select: %m");
1056}
1057
1058/*
1059 * add_fd - add an fd to the set that wait_input waits for.
1060 */
1061void add_fd(int fd)
1062{
1063    if (fd >= FD_SETSIZE)
1064	fatal("internal error: file descriptor too large (%d)", fd);
1065    FD_SET(fd, &in_fds);
1066    if (fd > max_in_fd)
1067	max_in_fd = fd;
1068}
1069
1070/*
1071 * remove_fd - remove an fd from the set that wait_input waits for.
1072 */
1073void remove_fd(int fd)
1074{
1075    FD_CLR(fd, &in_fds);
1076}
1077
1078
1079/********************************************************************
1080 *
1081 * read_packet - get a PPP packet from the serial device.
1082 */
1083
1084int read_packet (unsigned char *buf)
1085{
1086    int len, nr;
1087
1088    len = PPP_MRU + PPP_HDRLEN;
1089    if (new_style_driver) {
1090	*buf++ = PPP_ALLSTATIONS;
1091	*buf++ = PPP_UI;
1092	len -= 2;
1093    }
1094    nr = -1;
1095
1096    if (ppp_fd >= 0) {
1097	nr = read(ppp_fd, buf, len);
1098	if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1099	    && errno != EIO && errno != EINTR)
1100	    error("read: %m");
1101	if (nr < 0 && errno == ENXIO)
1102	    return 0;
1103    }
1104    if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1105	/* N.B. we read ppp_fd first since LCP packets come in there. */
1106	nr = read(ppp_dev_fd, buf, len);
1107	if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1108	    && errno != EIO && errno != EINTR)
1109	    error("read /dev/ppp: %m");
1110	if (nr < 0 && errno == ENXIO)
1111	    nr = 0;
1112	if (nr == 0 && doing_multilink) {
1113	    remove_fd(ppp_dev_fd);
1114	    bundle_eof = 1;
1115	}
1116    }
1117    if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1118	nr = 0;
1119    return (new_style_driver && nr > 0)? nr+2: nr;
1120}
1121
1122/********************************************************************
1123 *
1124 * get_loop_output - get outgoing packets from the ppp device,
1125 * and detect when we want to bring the real link up.
1126 * Return value is 1 if we need to bring up the link, 0 otherwise.
1127 */
1128int
1129get_loop_output(void)
1130{
1131    int rv = 0;
1132    int n;
1133
1134    if (new_style_driver) {
1135	while ((n = read_packet(inpacket_buf)) > 0)
1136	    if (loop_frame(inpacket_buf, n))
1137		rv = 1;
1138	return rv;
1139    }
1140
1141    while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1142	if (loop_chars(inbuf, n))
1143	    rv = 1;
1144
1145    if (n == 0)
1146	fatal("eof on loopback");
1147
1148    if (errno != EWOULDBLOCK && errno != EAGAIN)
1149	fatal("read from loopback: %m(%d)", errno);
1150
1151    return rv;
1152}
1153
1154/*
1155 * netif_set_mtu - set the MTU on the PPP network interface.
1156 */
1157void
1158netif_set_mtu(int unit, int mtu)
1159{
1160    struct ifreq ifr;
1161
1162    memset (&ifr, '\0', sizeof (ifr));
1163    strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1164    ifr.ifr_mtu = mtu;
1165
1166    if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1167	error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1168}
1169
1170/*
1171 * netif_get_mtu - get the MTU on the PPP network interface.
1172 */
1173int
1174netif_get_mtu(int unit)
1175{
1176    struct ifreq ifr;
1177
1178    memset (&ifr, '\0', sizeof (ifr));
1179    strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1180
1181    if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1182	error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1183	return 0;
1184    }
1185    return ifr.ifr_mtu;
1186}
1187
1188/********************************************************************
1189 *
1190 * tty_send_config - configure the transmit characteristics of
1191 * the ppp interface.
1192 */
1193
1194void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1195{
1196	int x;
1197
1198	if (!still_ppp())
1199		return;
1200	link_mtu = mtu;
1201	if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1202		if (errno != EIO && errno != ENOTTY)
1203			error("Couldn't set transmit async character map: %m");
1204		++error_count;
1205		return;
1206	}
1207
1208	x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1209	    | (sync_serial? SC_SYNC: 0);
1210	modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1211}
1212
1213/********************************************************************
1214 *
1215 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1216 */
1217
1218void tty_set_xaccm (ext_accm accm)
1219{
1220    if (!still_ppp())
1221	return;
1222    if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1223	if ( ! ok_error (errno))
1224	    warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1225    }
1226}
1227
1228/********************************************************************
1229 *
1230 * tty_recv_config - configure the receive-side characteristics of
1231 * the ppp interface.
1232 */
1233
1234void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1235{
1236/*
1237 * If we were called because the link has gone down then there is nothing
1238 * which may be done. Just return without incident.
1239 */
1240	if (!still_ppp())
1241		return;
1242/*
1243 * Set the receiver parameters
1244 */
1245	if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1246		if (errno != EIO && errno != ENOTTY)
1247			error("Couldn't set channel receive MRU: %m");
1248	}
1249	if (new_style_driver && ppp_dev_fd >= 0
1250	    && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1251		error("Couldn't set MRU in generic PPP layer: %m");
1252
1253	if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1254		if (errno != EIO && errno != ENOTTY)
1255			error("Couldn't set channel receive asyncmap: %m");
1256	}
1257}
1258
1259/********************************************************************
1260 *
1261 * ccp_test - ask kernel whether a given compression method
1262 * is acceptable for use.
1263 */
1264
1265int
1266ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1267{
1268    struct ppp_option_data data;
1269
1270    memset (&data, '\0', sizeof (data));
1271    data.ptr      = opt_ptr;
1272    data.length   = opt_len;
1273    data.transmit = for_transmit;
1274
1275    if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1276	return 1;
1277
1278    return (errno == ENOBUFS)? 0: -1;
1279}
1280
1281/********************************************************************
1282 *
1283 * ccp_flags_set - inform kernel about the current state of CCP.
1284 */
1285
1286void ccp_flags_set (int unit, int isopen, int isup)
1287{
1288	int x;
1289
1290	x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1291	if (still_ppp() && ppp_dev_fd >= 0)
1292		modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1293}
1294
1295#ifdef PPP_FILTER
1296/*
1297 * set_filters - set the active and pass filters in the kernel driver.
1298 */
1299int set_filters(struct bpf_program *pass, struct bpf_program *active)
1300{
1301	struct sock_fprog fp;
1302
1303	fp.len = pass->bf_len;
1304	fp.filter = (struct sock_filter *) pass->bf_insns;
1305	if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1306		if (errno == ENOTTY)
1307			warn("kernel does not support PPP filtering");
1308		else
1309			error("Couldn't set pass-filter in kernel: %m");
1310		return 0;
1311	}
1312	fp.len = active->bf_len;
1313	fp.filter = (struct sock_filter *) active->bf_insns;
1314	if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1315		error("Couldn't set active-filter in kernel: %m");
1316		return 0;
1317	}
1318	return 1;
1319}
1320#endif /* PPP_FILTER */
1321
1322/********************************************************************
1323 *
1324 * get_idle_time - return how long the link has been idle.
1325 */
1326int
1327get_idle_time(u, ip)
1328    int u;
1329    struct ppp_idle *ip;
1330{
1331    return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1332}
1333
1334/********************************************************************
1335 *
1336 * get_ppp_stats - return statistics for the link.
1337 */
1338int
1339get_ppp_stats(u, stats)
1340    int u;
1341    struct pppd_stats *stats;
1342{
1343    struct ifpppstatsreq req;
1344
1345    memset (&req, 0, sizeof (req));
1346
1347    req.stats_ptr = (caddr_t) &req.stats;
1348    strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1349    if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1350	error("Couldn't get PPP statistics: %m");
1351	return 0;
1352    }
1353    stats->bytes_in = req.stats.p.ppp_ibytes;
1354    stats->bytes_out = req.stats.p.ppp_obytes;
1355    stats->pkts_in = req.stats.p.ppp_ipackets;
1356    stats->pkts_out = req.stats.p.ppp_opackets;
1357    return 1;
1358}
1359
1360/********************************************************************
1361 *
1362 * ccp_fatal_error - returns 1 if decompression was disabled as a
1363 * result of an error detected after decompression of a packet,
1364 * 0 otherwise.  This is necessary because of patent nonsense.
1365 */
1366
1367int ccp_fatal_error (int unit)
1368{
1369	int flags;
1370
1371	if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1372		error("Couldn't read compression error flags: %m");
1373		flags = 0;
1374	}
1375	return flags & SC_DC_FERROR;
1376}
1377
1378/********************************************************************
1379 *
1380 * path_to_procfs - find the path to the proc file system mount point
1381 */
1382static char proc_path[MAXPATHLEN];
1383static int proc_path_len;
1384
1385static char *path_to_procfs(const char *tail)
1386{
1387    struct mntent *mntent;
1388    FILE *fp;
1389
1390    if (proc_path_len == 0) {
1391	/* Default the mount location of /proc */
1392	strlcpy (proc_path, "/proc", sizeof(proc_path));
1393	proc_path_len = 5;
1394	fp = fopen(_PATH_MOUNTED, "r");
1395	if (fp != NULL) {
1396	    while ((mntent = getmntent(fp)) != NULL) {
1397		if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1398		    continue;
1399		if (strcmp(mntent->mnt_type, "proc") == 0) {
1400		    strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1401		    proc_path_len = strlen(proc_path);
1402		    break;
1403		}
1404	    }
1405	    fclose (fp);
1406	}
1407    }
1408
1409    strlcpy(proc_path + proc_path_len, tail,
1410	    sizeof(proc_path) - proc_path_len);
1411    return proc_path;
1412}
1413
1414/*
1415 * /proc/net/route parsing stuff.
1416 */
1417#define ROUTE_MAX_COLS	12
1418FILE *route_fd = (FILE *) 0;
1419static char route_buffer[512];
1420static int route_dev_col, route_dest_col, route_gw_col;
1421static int route_flags_col, route_mask_col;
1422static int route_num_cols;
1423
1424static int open_route_table (void);
1425static void close_route_table (void);
1426static int read_route_table (struct rtentry *rt);
1427
1428/********************************************************************
1429 *
1430 * close_route_table - close the interface to the route table
1431 */
1432
1433static void close_route_table (void)
1434{
1435    if (route_fd != (FILE *) 0) {
1436	fclose (route_fd);
1437	route_fd = (FILE *) 0;
1438    }
1439}
1440
1441/********************************************************************
1442 *
1443 * open_route_table - open the interface to the route table
1444 */
1445static char route_delims[] = " \t\n";
1446
1447static int open_route_table (void)
1448{
1449    char *path;
1450
1451    close_route_table();
1452
1453    path = path_to_procfs("/net/route");
1454    route_fd = fopen (path, "r");
1455    if (route_fd == NULL) {
1456	error("can't open routing table %s: %m", path);
1457	return 0;
1458    }
1459
1460    route_dev_col = 0;		/* default to usual columns */
1461    route_dest_col = 1;
1462    route_gw_col = 2;
1463    route_flags_col = 3;
1464    route_mask_col = 7;
1465    route_num_cols = 8;
1466
1467    /* parse header line */
1468    if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1469	char *p = route_buffer, *q;
1470	int col;
1471	for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1472	    int used = 1;
1473	    if ((q = strtok(p, route_delims)) == 0)
1474		break;
1475	    if (strcasecmp(q, "iface") == 0)
1476		route_dev_col = col;
1477	    else if (strcasecmp(q, "destination") == 0)
1478		route_dest_col = col;
1479	    else if (strcasecmp(q, "gateway") == 0)
1480		route_gw_col = col;
1481	    else if (strcasecmp(q, "flags") == 0)
1482		route_flags_col = col;
1483	    else if (strcasecmp(q, "mask") == 0)
1484		route_mask_col = col;
1485	    else
1486		used = 0;
1487	    if (used && col >= route_num_cols)
1488		route_num_cols = col + 1;
1489	    p = NULL;
1490	}
1491    }
1492
1493    return 1;
1494}
1495
1496/********************************************************************
1497 *
1498 * read_route_table - read the next entry from the route table
1499 */
1500
1501static int read_route_table(struct rtentry *rt)
1502{
1503    char *cols[ROUTE_MAX_COLS], *p;
1504    int col;
1505
1506    memset (rt, '\0', sizeof (struct rtentry));
1507
1508    if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1509	return 0;
1510
1511    p = route_buffer;
1512    for (col = 0; col < route_num_cols; ++col) {
1513	cols[col] = strtok(p, route_delims);
1514	if (cols[col] == NULL)
1515	    return 0;		/* didn't get enough columns */
1516	p = NULL;
1517    }
1518
1519    SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1520    SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1521    SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1522
1523    rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1524    rt->rt_dev   = cols[route_dev_col];
1525
1526    return 1;
1527}
1528
1529/********************************************************************
1530 *
1531 * defaultroute_exists - determine if there is a default route
1532 */
1533
1534static int defaultroute_exists (struct rtentry *rt)
1535{
1536    int result = 0;
1537
1538    if (!open_route_table())
1539	return 0;
1540
1541    while (read_route_table(rt) != 0) {
1542	if ((rt->rt_flags & RTF_UP) == 0)
1543	    continue;
1544
1545	if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1546	    continue;
1547	if (SIN_ADDR(rt->rt_dst) == 0L) {
1548	    result = 1;
1549	    break;
1550	}
1551    }
1552
1553    close_route_table();
1554    return result;
1555}
1556
1557/*
1558 * have_route_to - determine if the system has any route to
1559 * a given IP address.  `addr' is in network byte order.
1560 * Return value is 1 if yes, 0 if no, -1 if don't know.
1561 * For demand mode to work properly, we have to ignore routes
1562 * through our own interface.
1563 */
1564int have_route_to(u_int32_t addr)
1565{
1566    struct rtentry rt;
1567    int result = 0;
1568
1569    if (!open_route_table())
1570	return -1;		/* don't know */
1571
1572    while (read_route_table(&rt)) {
1573	if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1574	    continue;
1575	if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1576	    result = 1;
1577	    break;
1578	}
1579    }
1580
1581    close_route_table();
1582    return result;
1583}
1584
1585/********************************************************************
1586 *
1587 * sifdefaultroute - assign a default route through the address given.
1588 */
1589
1590int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1591{
1592    struct rtentry rt;
1593
1594    if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1595	u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway);
1596
1597	if (old_gateway != gateway)
1598	    error("not replacing existing default route to %s [%I]",
1599		  rt.rt_dev, old_gateway);
1600	return 0;
1601    }
1602
1603    memset (&rt, '\0', sizeof (rt));
1604    SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1605    SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1606
1607    rt.rt_dev = ifname;
1608
1609    if (kernel_version > KVERSION(2,1,0)) {
1610	SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1611	SIN_ADDR(rt.rt_genmask) = 0L;
1612    }
1613
1614    SIN_ADDR(rt.rt_gateway) = gateway;
1615
1616    rt.rt_flags = RTF_UP | RTF_GATEWAY;
1617    if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1618	if ( ! ok_error ( errno ))
1619	    error("default route ioctl(SIOCADDRT): %m");
1620	return 0;
1621    }
1622
1623    default_route_gateway = gateway;
1624    return 1;
1625}
1626
1627/********************************************************************
1628 *
1629 * cifdefaultroute - delete a default route through the address given.
1630 */
1631
1632int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1633{
1634    struct rtentry rt;
1635
1636    default_route_gateway = 0;
1637
1638    memset (&rt, '\0', sizeof (rt));
1639    SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1640    SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1641
1642    if (kernel_version > KVERSION(2,1,0)) {
1643	SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1644	SIN_ADDR(rt.rt_genmask) = 0L;
1645    }
1646
1647    SIN_ADDR(rt.rt_gateway) = gateway;
1648
1649    rt.rt_flags = RTF_UP | RTF_GATEWAY;
1650    if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1651	if (still_ppp()) {
1652	    if ( ! ok_error ( errno ))
1653		error("default route ioctl(SIOCDELRT): %m");
1654	    return 0;
1655	}
1656    }
1657
1658    return 1;
1659}
1660
1661/********************************************************************
1662 *
1663 * sifproxyarp - Make a proxy ARP entry for the peer.
1664 */
1665
1666int sifproxyarp (int unit, u_int32_t his_adr)
1667{
1668    struct arpreq arpreq;
1669    char *forw_path;
1670
1671    if (has_proxy_arp == 0) {
1672	memset (&arpreq, '\0', sizeof(arpreq));
1673
1674	SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1675	SIN_ADDR(arpreq.arp_pa) = his_adr;
1676	arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1677/*
1678 * Get the hardware address of an interface on the same subnet
1679 * as our local address.
1680 */
1681	if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1682			    sizeof(proxy_arp_dev))) {
1683	    error("Cannot determine ethernet address for proxy ARP");
1684	    return 0;
1685	}
1686	strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1687
1688	if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1689	    if ( ! ok_error ( errno ))
1690		error("ioctl(SIOCSARP): %m");
1691	    return 0;
1692	}
1693	proxy_arp_addr = his_adr;
1694	has_proxy_arp = 1;
1695
1696	if (tune_kernel) {
1697	    forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1698	    if (forw_path != 0) {
1699		int fd = open(forw_path, O_WRONLY);
1700		if (fd >= 0) {
1701		    if (write(fd, "1", 1) != 1)
1702			error("Couldn't enable IP forwarding: %m");
1703		    close(fd);
1704		}
1705	    }
1706	}
1707    }
1708
1709    return 1;
1710}
1711
1712/********************************************************************
1713 *
1714 * cifproxyarp - Delete the proxy ARP entry for the peer.
1715 */
1716
1717int cifproxyarp (int unit, u_int32_t his_adr)
1718{
1719    struct arpreq arpreq;
1720
1721    if (has_proxy_arp) {
1722	has_proxy_arp = 0;
1723	memset (&arpreq, '\0', sizeof(arpreq));
1724	SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1725	SIN_ADDR(arpreq.arp_pa) = his_adr;
1726	arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1727	strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1728
1729	if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1730	    if ( ! ok_error ( errno ))
1731		warn("ioctl(SIOCDARP): %m");
1732	    return 0;
1733	}
1734    }
1735    return 1;
1736}
1737
1738/********************************************************************
1739 *
1740 * get_ether_addr - get the hardware address of an interface on the
1741 * the same subnet as ipaddr.
1742 */
1743
1744static int get_ether_addr (u_int32_t ipaddr,
1745			   struct sockaddr *hwaddr,
1746			   char *name, int namelen)
1747{
1748    struct ifreq *ifr, *ifend;
1749    u_int32_t ina, mask;
1750    char *aliasp;
1751    struct ifreq ifreq, bestifreq;
1752    struct ifconf ifc;
1753    struct ifreq ifs[MAX_IFS];
1754
1755    u_int32_t bestmask=0;
1756    int found_interface = 0;
1757
1758    ifc.ifc_len = sizeof(ifs);
1759    ifc.ifc_req = ifs;
1760    if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1761	if ( ! ok_error ( errno ))
1762	    error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1763	return 0;
1764    }
1765
1766/*
1767 * Scan through looking for an interface with an Internet
1768 * address on the same subnet as `ipaddr'.
1769 */
1770    ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1771    for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1772	if (ifr->ifr_addr.sa_family == AF_INET) {
1773	    ina = SIN_ADDR(ifr->ifr_addr);
1774	    strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1775/*
1776 * Check that the interface is up, and not point-to-point
1777 * nor loopback.
1778 */
1779	    if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1780		continue;
1781
1782	    if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1783		continue;
1784/*
1785 * Get its netmask and check that it's on the right subnet.
1786 */
1787	    if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1788		continue;
1789
1790	    mask = SIN_ADDR(ifreq.ifr_addr);
1791
1792	    if (((ipaddr ^ ina) & mask) != 0)
1793		continue; /* no match */
1794	    /* matched */
1795	    if (mask >= bestmask) {
1796		/* Compare using >= instead of > -- it is possible for
1797		   an interface to have a netmask of 0.0.0.0 */
1798		found_interface = 1;
1799		bestifreq = ifreq;
1800		bestmask = mask;
1801	    }
1802	}
1803    }
1804
1805    if (!found_interface) return 0;
1806
1807    strlcpy(name, bestifreq.ifr_name, namelen);
1808
1809    /* trim off the :1 in eth0:1 */
1810    aliasp = strchr(name, ':');
1811    if (aliasp != 0)
1812	*aliasp = 0;
1813
1814    info("found interface %s for proxy arp", name);
1815/*
1816 * Now get the hardware address.
1817 */
1818    memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1819    if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
1820	error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
1821	return 0;
1822    }
1823
1824    memcpy (hwaddr,
1825	    &bestifreq.ifr_hwaddr,
1826	    sizeof (struct sockaddr));
1827
1828    return 1;
1829}
1830
1831/*
1832 * get_if_hwaddr - get the hardware address for the specified
1833 * network interface device.
1834 */
1835int
1836get_if_hwaddr(u_char *addr, char *name)
1837{
1838	struct ifreq ifreq;
1839	int ret, sock_fd;
1840
1841	sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1842	if (sock_fd < 0)
1843		return 0;
1844	memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1845	strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1846	ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1847	close(sock_fd);
1848	if (ret >= 0)
1849		memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1850	return ret;
1851}
1852
1853/*
1854 * get_first_ethernet - return the name of the first ethernet-style
1855 * interface on this system.
1856 */
1857char *
1858get_first_ethernet()
1859{
1860	return "eth0";
1861}
1862
1863/********************************************************************
1864 *
1865 * Return user specified netmask, modified by any mask we might determine
1866 * for address `addr' (in network byte order).
1867 * Here we scan through the system's list of interfaces, looking for
1868 * any non-point-to-point interfaces which might appear to be on the same
1869 * network as `addr'.  If we find any, we OR in their netmask to the
1870 * user-specified netmask.
1871 */
1872
1873u_int32_t GetMask (u_int32_t addr)
1874{
1875    u_int32_t mask, nmask, ina;
1876    struct ifreq *ifr, *ifend, ifreq;
1877    struct ifconf ifc;
1878    struct ifreq ifs[MAX_IFS];
1879
1880    addr = ntohl(addr);
1881
1882    if (IN_CLASSA(addr))	/* determine network mask for address class */
1883	nmask = IN_CLASSA_NET;
1884    else if (IN_CLASSB(addr))
1885	    nmask = IN_CLASSB_NET;
1886    else
1887	    nmask = IN_CLASSC_NET;
1888
1889    /* class D nets are disallowed by bad_ip_adrs */
1890    mask = netmask | htonl(nmask);
1891/*
1892 * Scan through the system's network interfaces.
1893 */
1894    ifc.ifc_len = sizeof(ifs);
1895    ifc.ifc_req = ifs;
1896    if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1897	if ( ! ok_error ( errno ))
1898	    warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1899	return mask;
1900    }
1901
1902    ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1903    for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1904/*
1905 * Check the interface's internet address.
1906 */
1907	if (ifr->ifr_addr.sa_family != AF_INET)
1908	    continue;
1909	ina = SIN_ADDR(ifr->ifr_addr);
1910	if (((ntohl(ina) ^ addr) & nmask) != 0)
1911	    continue;
1912/*
1913 * Check that the interface is up, and not point-to-point nor loopback.
1914 */
1915	strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1916	if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1917	    continue;
1918
1919	if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1920	    continue;
1921/*
1922 * Get its netmask and OR it into our mask.
1923 */
1924	if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1925	    continue;
1926	mask |= SIN_ADDR(ifreq.ifr_addr);
1927	break;
1928    }
1929    return mask;
1930}
1931
1932/********************************************************************
1933 *
1934 * Internal routine to decode the version.modification.patch level
1935 */
1936
1937static void decode_version (char *buf, int *version,
1938			    int *modification, int *patch)
1939{
1940    char *endp;
1941
1942    *version      = (int) strtoul (buf, &endp, 10);
1943    *modification = 0;
1944    *patch        = 0;
1945
1946    if (endp != buf && *endp == '.') {
1947	buf = endp + 1;
1948	*modification = (int) strtoul (buf, &endp, 10);
1949	if (endp != buf && *endp == '.') {
1950	    buf = endp + 1;
1951	    *patch = (int) strtoul (buf, &buf, 10);
1952	}
1953    }
1954}
1955
1956/********************************************************************
1957 *
1958 * Procedure to determine if the PPP line discipline is registered.
1959 */
1960
1961static int
1962ppp_registered(void)
1963{
1964    int local_fd;
1965    int mfd = -1;
1966    int ret = 0;
1967    char slave[16];
1968
1969    /*
1970     * We used to open the serial device and set it to the ppp line
1971     * discipline here, in order to create a ppp unit.  But that is
1972     * not a good idea - the user might have specified a device that
1973     * they can't open (permission, or maybe it doesn't really exist).
1974     * So we grab a pty master/slave pair and use that.
1975     */
1976    if (!get_pty(&mfd, &local_fd, slave, 0)) {
1977	no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
1978	return 0;
1979    }
1980
1981    /*
1982     * Try to put the device into the PPP discipline.
1983     */
1984    if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
1985	error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
1986    } else
1987	ret = 1;
1988
1989    close(local_fd);
1990    close(mfd);
1991    return ret;
1992}
1993
1994/********************************************************************
1995 *
1996 * ppp_available - check whether the system has any ppp interfaces
1997 * (in fact we check whether we can do an ioctl on ppp0).
1998 */
1999
2000int ppp_available(void)
2001{
2002    int s, ok, fd;
2003    struct ifreq ifr;
2004    int    size;
2005    int    my_version, my_modification, my_patch;
2006    int osmaj, osmin, ospatch;
2007
2008    no_ppp_msg =
2009	"This system lacks kernel support for PPP.  This could be because\n"
2010	"the PPP kernel module could not be loaded, or because PPP was not\n"
2011	"included in the kernel configuration.  If PPP was included as a\n"
2012	"module, try `/sbin/modprobe -v ppp'.  If that fails, check that\n"
2013	"ppp.o exists in /lib/modules/`uname -r`/net.\n"
2014	"See README.linux file in the ppp distribution for more details.\n";
2015
2016    /* get the kernel version now, since we are called before sys_init */
2017    uname(&utsname);
2018    osmaj = osmin = ospatch = 0;
2019    sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2020    kernel_version = KVERSION(osmaj, osmin, ospatch);
2021
2022    fd = open("/dev/ppp", O_RDWR);
2023#if 0
2024    if (fd < 0 && errno == ENOENT) {
2025	/* try making it and see if that helps. */
2026	if (mknod("/dev/ppp", S_IFCHR | S_IRUSR | S_IWUSR,
2027		  makedev(108, 0)) >= 0) {
2028	    fd = open("/dev/ppp", O_RDWR);
2029	    if (fd >= 0)
2030		info("Created /dev/ppp device node");
2031	    else
2032		unlink("/dev/ppp");	/* didn't work, undo the mknod */
2033	} else if (errno == EEXIST) {
2034	    fd = open("/dev/ppp", O_RDWR);
2035	}
2036    }
2037#endif /* 0 */
2038    if (fd >= 0) {
2039	new_style_driver = 1;
2040
2041	/* XXX should get from driver */
2042	driver_version = 2;
2043	driver_modification = 4;
2044	driver_patch = 0;
2045	close(fd);
2046	return 1;
2047    }
2048    if (kernel_version >= KVERSION(2,3,13)) {
2049	if (errno == ENOENT)
2050	    no_ppp_msg =
2051		"pppd is unable to open the /dev/ppp device.\n"
2052		"You need to create the /dev/ppp device node by\n"
2053		"executing the following command as root:\n"
2054		"	mknod /dev/ppp c 108 0\n";
2055	return 0;
2056    }
2057
2058/*
2059 * Open a socket for doing the ioctl operations.
2060 */
2061    s = socket(AF_INET, SOCK_DGRAM, 0);
2062    if (s < 0)
2063	return 0;
2064
2065    strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2066    ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2067/*
2068 * If the device did not exist then attempt to create one by putting the
2069 * current tty into the PPP discipline. If this works then obtain the
2070 * flags for the device again.
2071 */
2072    if (!ok) {
2073	if (ppp_registered()) {
2074	    strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2075	    ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2076	}
2077    }
2078/*
2079 * Ensure that the hardware address is for PPP and not something else
2080 */
2081    if (ok)
2082	ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2083
2084    if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2085	ok = 0;
2086
2087/*
2088 *  This is the PPP device. Validate the version of the driver at this
2089 *  point to ensure that this program will work with the driver.
2090 */
2091    if (ok) {
2092	char   abBuffer [1024];
2093
2094	ifr.ifr_data = abBuffer;
2095	size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2096	if (size < 0) {
2097	    error("Couldn't read driver version: %m");
2098	    ok = 0;
2099	    no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2100
2101	} else {
2102	    decode_version(abBuffer,
2103			   &driver_version,
2104			   &driver_modification,
2105			   &driver_patch);
2106/*
2107 * Validate the version of the driver against the version that we used.
2108 */
2109	    decode_version(VERSION,
2110			   &my_version,
2111			   &my_modification,
2112			   &my_patch);
2113
2114	    /* The version numbers must match */
2115	    if (driver_version != my_version)
2116		ok = 0;
2117
2118	    /* The modification levels must be legal */
2119	    if (driver_modification < 3) {
2120		if (driver_modification >= 2) {
2121		    /* we can cope with 2.2.0 and above */
2122		    driver_is_old = 1;
2123		} else {
2124		    ok = 0;
2125		}
2126	    }
2127
2128	    close (s);
2129	    if (!ok) {
2130		slprintf(route_buffer, sizeof(route_buffer),
2131			 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2132			 driver_version, driver_modification, driver_patch);
2133
2134		no_ppp_msg = route_buffer;
2135	    }
2136	}
2137    }
2138    return ok;
2139}
2140
2141/********************************************************************
2142 *
2143 * Update the wtmp file with the appropriate user name and tty device.
2144 */
2145
2146void logwtmp (const char *line, const char *name, const char *host)
2147{
2148    struct utmp ut, *utp;
2149    pid_t  mypid = getpid();
2150#if __GLIBC__ < 2
2151    int    wtmp;
2152#endif
2153
2154/*
2155 * Update the signon database for users.
2156 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2157 */
2158    utmpname(_PATH_UTMP);
2159    setutent();
2160    while ((utp = getutent()) && (utp->ut_pid != mypid))
2161	/* nothing */;
2162
2163    if (utp)
2164	memcpy(&ut, utp, sizeof(ut));
2165    else
2166	/* some gettys/telnetds don't initialize utmp... */
2167	memset(&ut, 0, sizeof(ut));
2168
2169    if (ut.ut_id[0] == 0)
2170	strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2171
2172    strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2173    strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2174
2175    time(&ut.ut_time);
2176
2177    ut.ut_type = USER_PROCESS;
2178    ut.ut_pid  = mypid;
2179
2180    /* Insert the host name if one is supplied */
2181    if (*host)
2182	strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2183
2184    /* Insert the IP address of the remote system if IP is enabled */
2185    if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2186	memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2187		 sizeof(ut.ut_addr));
2188
2189    /* CL: Makes sure that the logout works */
2190    if (*host == 0 && *name==0)
2191	ut.ut_host[0]=0;
2192
2193    pututline(&ut);
2194    endutent();
2195/*
2196 * Update the wtmp file.
2197 */
2198#if __GLIBC__ >= 2
2199    updwtmp(_PATH_WTMP, &ut);
2200#else
2201    wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2202    if (wtmp >= 0) {
2203	flock(wtmp, LOCK_EX);
2204
2205	if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2206	    warn("error writing %s: %m", _PATH_WTMP);
2207
2208	flock(wtmp, LOCK_UN);
2209
2210	close (wtmp);
2211    }
2212#endif
2213}
2214
2215
2216/********************************************************************
2217 *
2218 * sifvjcomp - config tcp header compression
2219 */
2220
2221int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2222{
2223	u_int x;
2224
2225	if (vjcomp) {
2226		if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0)
2227			error("Couldn't set up TCP header compression: %m");
2228		vjcomp = 0;
2229	}
2230
2231	x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2232	modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2233
2234	return 1;
2235}
2236
2237/********************************************************************
2238 *
2239 * sifup - Config the interface up and enable IP packets to pass.
2240 */
2241
2242int sifup(int u)
2243{
2244    struct ifreq ifr;
2245
2246    memset (&ifr, '\0', sizeof (ifr));
2247    strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2248    if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2249	if (! ok_error (errno))
2250	    error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2251	return 0;
2252    }
2253
2254    ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2255    if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2256	if (! ok_error (errno))
2257	    error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2258	return 0;
2259    }
2260    if_is_up++;
2261
2262    return 1;
2263}
2264
2265/********************************************************************
2266 *
2267 * sifdown - Disable the indicated protocol and config the interface
2268 *	     down if there are no remaining protocols.
2269 */
2270
2271int sifdown (int u)
2272{
2273    struct ifreq ifr;
2274
2275    if (if_is_up && --if_is_up > 0)
2276	return 1;
2277
2278    memset (&ifr, '\0', sizeof (ifr));
2279    strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2280    if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2281	if (! ok_error (errno))
2282	    error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2283	return 0;
2284    }
2285
2286    ifr.ifr_flags &= ~IFF_UP;
2287    ifr.ifr_flags |= IFF_POINTOPOINT;
2288    if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2289	if (! ok_error (errno))
2290	    error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2291	return 0;
2292    }
2293    return 1;
2294}
2295
2296/********************************************************************
2297 *
2298 * sifaddr - Config the interface IP addresses and netmask.
2299 */
2300
2301int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2302	     u_int32_t net_mask)
2303{
2304    struct ifreq   ifr;
2305    struct rtentry rt;
2306
2307    memset (&ifr, '\0', sizeof (ifr));
2308    memset (&rt,  '\0', sizeof (rt));
2309
2310    SET_SA_FAMILY (ifr.ifr_addr,    AF_INET);
2311    SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2312    SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2313
2314    strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2315/*
2316 *  Set our IP address
2317 */
2318    SIN_ADDR(ifr.ifr_addr) = our_adr;
2319    if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2320	if (errno != EEXIST) {
2321	    if (! ok_error (errno))
2322		error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2323	}
2324	else {
2325	    warn("ioctl(SIOCSIFADDR): Address already exists");
2326	}
2327	return (0);
2328    }
2329/*
2330 *  Set the gateway address
2331 */
2332    SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2333    if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2334	if (! ok_error (errno))
2335	    error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2336	return (0);
2337    }
2338/*
2339 *  Set the netmask.
2340 *  For recent kernels, force the netmask to 255.255.255.255.
2341 */
2342    if (kernel_version >= KVERSION(2,1,16))
2343	net_mask = ~0L;
2344    if (net_mask != 0) {
2345	SIN_ADDR(ifr.ifr_netmask) = net_mask;
2346	if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2347	    if (! ok_error (errno))
2348		error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2349	    return (0);
2350	}
2351    }
2352/*
2353 *  Add the device route
2354 */
2355    if (kernel_version < KVERSION(2,1,16)) {
2356	SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2357	SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2358	rt.rt_dev = ifname;
2359
2360	SIN_ADDR(rt.rt_gateway) = 0L;
2361	SIN_ADDR(rt.rt_dst)     = his_adr;
2362	rt.rt_flags = RTF_UP | RTF_HOST;
2363
2364	if (kernel_version > KVERSION(2,1,0)) {
2365	    SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2366	    SIN_ADDR(rt.rt_genmask) = -1L;
2367	}
2368
2369	if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2370	    if (! ok_error (errno))
2371		error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2372	    return (0);
2373	}
2374    }
2375
2376    /* set ip_dynaddr in demand mode if address changes */
2377    if (demand && tune_kernel && !dynaddr_set
2378	&& our_old_addr && our_old_addr != our_adr) {
2379	/* set ip_dynaddr if possible */
2380	char *path;
2381	int fd;
2382
2383	path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2384	if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2385	    if (write(fd, "1", 1) != 1)
2386		error("Couldn't enable dynamic IP addressing: %m");
2387	    close(fd);
2388	}
2389	dynaddr_set = 1;	/* only 1 attempt */
2390    }
2391    our_old_addr = 0;
2392
2393    return 1;
2394}
2395
2396/********************************************************************
2397 *
2398 * cifaddr - Clear the interface IP addresses, and delete routes
2399 * through the interface if possible.
2400 */
2401
2402int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2403{
2404    struct ifreq ifr;
2405
2406    if (kernel_version < KVERSION(2,1,16)) {
2407/*
2408 *  Delete the route through the device
2409 */
2410	struct rtentry rt;
2411	memset (&rt, '\0', sizeof (rt));
2412
2413	SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2414	SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2415	rt.rt_dev = ifname;
2416
2417	SIN_ADDR(rt.rt_gateway) = 0;
2418	SIN_ADDR(rt.rt_dst)     = his_adr;
2419	rt.rt_flags = RTF_UP | RTF_HOST;
2420
2421	if (kernel_version > KVERSION(2,1,0)) {
2422	    SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2423	    SIN_ADDR(rt.rt_genmask) = -1L;
2424	}
2425
2426	if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2427	    if (still_ppp() && ! ok_error (errno))
2428		error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2429	    return (0);
2430	}
2431    }
2432
2433    /* This way it is possible to have an IPX-only or IPv6-only interface */
2434    memset(&ifr, 0, sizeof(ifr));
2435    SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2436    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2437
2438    if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2439	if (! ok_error (errno)) {
2440	    error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2441	    return 0;
2442	}
2443    }
2444
2445    our_old_addr = our_adr;
2446
2447    return 1;
2448}
2449
2450#ifdef INET6
2451/********************************************************************
2452 *
2453 * sif6addr - Config the interface with an IPv6 link-local address
2454 */
2455int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2456{
2457    struct in6_ifreq ifr6;
2458    struct ifreq ifr;
2459    struct in6_rtmsg rt6;
2460
2461    if (sock6_fd < 0) {
2462	errno = -sock6_fd;
2463	error("IPv6 socket creation failed: %m");
2464	return 0;
2465    }
2466    memset(&ifr, 0, sizeof (ifr));
2467    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2468    if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2469	error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2470	return 0;
2471    }
2472
2473    /* Local interface */
2474    memset(&ifr6, 0, sizeof(ifr6));
2475    IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2476    ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2477    ifr6.ifr6_prefixlen = 10;
2478
2479    if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2480	error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2481	return 0;
2482    }
2483
2484    /* Route to remote host */
2485    memset(&rt6, 0, sizeof(rt6));
2486    IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2487    rt6.rtmsg_flags = RTF_UP;
2488    rt6.rtmsg_dst_len = 10;
2489    rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2490    rt6.rtmsg_metric = 1;
2491
2492    if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2493	error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2494	return 0;
2495    }
2496
2497    return 1;
2498}
2499
2500
2501/********************************************************************
2502 *
2503 * cif6addr - Remove IPv6 address from interface
2504 */
2505int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2506{
2507    struct ifreq ifr;
2508    struct in6_ifreq ifr6;
2509
2510    if (sock6_fd < 0) {
2511	errno = -sock6_fd;
2512	error("IPv6 socket creation failed: %m");
2513	return 0;
2514    }
2515    memset(&ifr, 0, sizeof(ifr));
2516    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2517    if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2518	error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2519	return 0;
2520    }
2521
2522    memset(&ifr6, 0, sizeof(ifr6));
2523    IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2524    ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2525    ifr6.ifr6_prefixlen = 10;
2526
2527    if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2528	if (errno != EADDRNOTAVAIL) {
2529	    if (! ok_error (errno))
2530		error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2531	}
2532	else {
2533	    warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2534	}
2535	return (0);
2536    }
2537    return 1;
2538}
2539#endif /* INET6 */
2540
2541/*
2542 * get_pty - get a pty master/slave pair and chown the slave side
2543 * to the uid given.  Assumes slave_name points to >= 16 bytes of space.
2544 */
2545int
2546get_pty(master_fdp, slave_fdp, slave_name, uid)
2547    int *master_fdp;
2548    int *slave_fdp;
2549    char *slave_name;
2550    int uid;
2551{
2552    int i, mfd, sfd = -1;
2553    char pty_name[16];
2554    struct termios tios;
2555
2556#ifdef TIOCGPTN
2557    /*
2558     * Try the unix98 way first.
2559     */
2560    mfd = open("/dev/ptmx", O_RDWR);
2561    if (mfd >= 0) {
2562	int ptn;
2563	if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2564	    slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2565	    chmod(pty_name, S_IRUSR | S_IWUSR);
2566#ifdef TIOCSPTLCK
2567	    ptn = 0;
2568	    if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2569		warn("Couldn't unlock pty slave %s: %m", pty_name);
2570#endif
2571	    if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2572		warn("Couldn't open pty slave %s: %m", pty_name);
2573	}
2574    }
2575#endif /* TIOCGPTN */
2576
2577    if (sfd < 0) {
2578	/* the old way - scan through the pty name space */
2579	for (i = 0; i < 64; ++i) {
2580	    slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2581		     'p' + i / 16, i % 16);
2582	    mfd = open(pty_name, O_RDWR, 0);
2583	    if (mfd >= 0) {
2584		pty_name[5] = 't';
2585		sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2586		if (sfd >= 0) {
2587		    fchown(sfd, uid, -1);
2588		    fchmod(sfd, S_IRUSR | S_IWUSR);
2589		    break;
2590		}
2591		close(mfd);
2592	    }
2593	}
2594    }
2595
2596    if (sfd < 0)
2597	return 0;
2598
2599    strlcpy(slave_name, pty_name, 16);
2600    *master_fdp = mfd;
2601    *slave_fdp = sfd;
2602    if (tcgetattr(sfd, &tios) == 0) {
2603	tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2604	tios.c_cflag |= CS8 | CREAD | CLOCAL;
2605	tios.c_iflag  = IGNPAR;
2606	tios.c_oflag  = 0;
2607	tios.c_lflag  = 0;
2608	if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2609	    warn("couldn't set attributes on pty: %m");
2610    } else
2611	warn("couldn't get attributes on pty: %m");
2612
2613    return 1;
2614}
2615
2616/********************************************************************
2617 *
2618 * open_loopback - open the device we use for getting packets
2619 * in demand mode.  Under Linux, we use a pty master/slave pair.
2620 */
2621int
2622open_ppp_loopback(void)
2623{
2624    int flags;
2625
2626    looped = 1;
2627    if (new_style_driver) {
2628	/* allocate ourselves a ppp unit */
2629	if (make_ppp_unit() < 0)
2630	    die(1);
2631	modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
2632	set_kdebugflag(kdebugflag);
2633	ppp_fd = -1;
2634	return ppp_dev_fd;
2635    }
2636
2637    if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2638	fatal("No free pty for loopback");
2639
2640    set_ppp_fd(slave_fd);
2641
2642    flags = fcntl(master_fd, F_GETFL);
2643    if (flags == -1 ||
2644	fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2645	warn("couldn't set master loopback to nonblock: %m");
2646
2647    flags = fcntl(ppp_fd, F_GETFL);
2648    if (flags == -1 ||
2649	fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2650	warn("couldn't set slave loopback to nonblock: %m");
2651
2652    if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2653	fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2654/*
2655 * Find out which interface we were given.
2656 */
2657    if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2658	fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2659/*
2660 * Enable debug in the driver if requested.
2661 */
2662    set_kdebugflag (kdebugflag);
2663
2664    return master_fd;
2665}
2666
2667/********************************************************************
2668 *
2669 * sifnpmode - Set the mode for handling packets for a given NP.
2670 */
2671
2672int
2673sifnpmode(u, proto, mode)
2674    int u;
2675    int proto;
2676    enum NPmode mode;
2677{
2678    struct npioctl npi;
2679
2680    npi.protocol = proto;
2681    npi.mode     = mode;
2682    if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2683	if (! ok_error (errno))
2684	    error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2685	return 0;
2686    }
2687    return 1;
2688}
2689
2690
2691/********************************************************************
2692 *
2693 * sipxfaddr - Config the interface IPX networknumber
2694 */
2695
2696int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2697{
2698    int    result = 1;
2699
2700#ifdef IPX_CHANGE
2701    int    skfd;
2702    struct ifreq         ifr;
2703    struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2704
2705    skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2706    if (skfd < 0) {
2707	if (! ok_error (errno))
2708	    dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2709	result = 0;
2710    }
2711    else {
2712	memset (&ifr, '\0', sizeof (ifr));
2713	strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2714
2715	memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2716	sipx->sipx_family  = AF_IPX;
2717	sipx->sipx_port    = 0;
2718	sipx->sipx_network = htonl (network);
2719	sipx->sipx_type    = IPX_FRAME_ETHERII;
2720	sipx->sipx_action  = IPX_CRTITF;
2721/*
2722 *  Set the IPX device
2723 */
2724	if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2725	    result = 0;
2726	    if (errno != EEXIST) {
2727		if (! ok_error (errno))
2728		    dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
2729	    }
2730	    else {
2731		warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2732	    }
2733	}
2734	close (skfd);
2735    }
2736#endif
2737    return result;
2738}
2739
2740/********************************************************************
2741 *
2742 * cipxfaddr - Clear the information for the IPX network. The IPX routes
2743 *	       are removed and the device is no longer able to pass IPX
2744 *	       frames.
2745 */
2746
2747int cipxfaddr (int unit)
2748{
2749    int    result = 1;
2750
2751#ifdef IPX_CHANGE
2752    int    skfd;
2753    struct ifreq         ifr;
2754    struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2755
2756    skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2757    if (skfd < 0) {
2758	if (! ok_error (errno))
2759	    dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2760	result = 0;
2761    }
2762    else {
2763	memset (&ifr, '\0', sizeof (ifr));
2764	strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2765
2766	sipx->sipx_type    = IPX_FRAME_ETHERII;
2767	sipx->sipx_action  = IPX_DLTITF;
2768	sipx->sipx_family  = AF_IPX;
2769/*
2770 *  Set the IPX device
2771 */
2772	if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2773	    if (! ok_error (errno))
2774		info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
2775	    result = 0;
2776	}
2777	close (skfd);
2778    }
2779#endif
2780    return result;
2781}
2782
2783/*
2784 * Use the hostname as part of the random number seed.
2785 */
2786int
2787get_host_seed()
2788{
2789    int h;
2790    char *p = hostname;
2791
2792    h = 407;
2793    for (p = hostname; *p != 0; ++p)
2794	h = h * 37 + *p;
2795    return h;
2796}
2797
2798/********************************************************************
2799 *
2800 * sys_check_options - check the options that the user specified
2801 */
2802
2803int
2804sys_check_options(void)
2805{
2806#ifdef IPX_CHANGE
2807/*
2808 * Disable the IPX protocol if the support is not present in the kernel.
2809 */
2810    char *path;
2811
2812    if (ipxcp_protent.enabled_flag) {
2813	struct stat stat_buf;
2814	if ((path = path_to_procfs("/net/ipx/interface")) == 0
2815	    || (path = path_to_procfs("/net/ipx_interface")) == 0
2816	    || lstat(path, &stat_buf) < 0) {
2817	    error("IPX support is not present in the kernel\n");
2818	    ipxcp_protent.enabled_flag = 0;
2819	}
2820    }
2821#endif
2822    if (demand && driver_is_old) {
2823	option_error("demand dialling is not supported by kernel driver "
2824		     "version %d.%d.%d", driver_version, driver_modification,
2825		     driver_patch);
2826	return 0;
2827    }
2828    if (multilink && !new_style_driver) {
2829	warn("Warning: multilink is not supported by the kernel driver");
2830	multilink = 0;
2831    }
2832    return 1;
2833}
2834
2835#ifdef INET6
2836/*
2837 * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
2838 *
2839 * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
2840 * that the system has a properly configured Ethernet interface for this
2841 * function to return non-zero.
2842 */
2843int
2844ether_to_eui64(eui64_t *p_eui64)
2845{
2846    struct ifreq ifr;
2847    int skfd;
2848    const unsigned char *ptr;
2849
2850    skfd = socket(PF_INET6, SOCK_DGRAM, 0);
2851    if(skfd == -1)
2852    {
2853        warn("could not open IPv6 socket");
2854        return 0;
2855    }
2856
2857    strcpy(ifr.ifr_name, "eth0");
2858    if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
2859    {
2860        close(skfd);
2861        warn("could not obtain hardware address for eth0");
2862        return 0;
2863    }
2864    close(skfd);
2865
2866    /*
2867     * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
2868     */
2869    ptr = ifr.ifr_hwaddr.sa_data;
2870    p_eui64->e8[0] = ptr[0] | 0x02;
2871    p_eui64->e8[1] = ptr[1];
2872    p_eui64->e8[2] = ptr[2];
2873    p_eui64->e8[3] = 0xFF;
2874    p_eui64->e8[4] = 0xFE;
2875    p_eui64->e8[5] = ptr[3];
2876    p_eui64->e8[6] = ptr[4];
2877    p_eui64->e8[7] = ptr[5];
2878
2879    return 1;
2880}
2881#endif
2882