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