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