• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
153 struct 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 
175 static int tty_disc = N_TTY;	/* The TTY discipline */
176 static int ppp_disc = N_PPP;	/* The PPP discpline */
177 static int initfdflags = -1;	/* Initial file descriptor flags for fd */
178 static int ppp_fd = -1;		/* fd which is set to PPP discipline */
179 static int sock_fd = -1;	/* socket for doing interface ioctls */
180 static int slave_fd = -1;	/* pty for old-style demand mode, slave */
181 static int master_fd = -1;	/* pty for old-style demand mode, master */
182 #ifdef INET6
183 static 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  */
191 int ppp_dev_fd = -1;		/* fd for /dev/ppp (new style driver) */
192 
193 static int chindex;		/* channel index (new style driver) */
194 
195 static fd_set in_fds;		/* set of fds that wait_input waits for */
196 static int max_in_fd;		/* highest fd set in in_fds */
197 
198 static int has_proxy_arp       = 0;
199 static int driver_version      = 0;
200 static int driver_modification = 0;
201 static int driver_patch        = 0;
202 static int driver_is_old       = 0;
203 static int restore_term        = 0;	/* 1 => we've munged the terminal */
204 static struct termios inittermios;	/* Initial TTY termios */
205 
206 int new_style_driver = 0;
207 
208 static char loop_name[20];
209 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
210 
211 static int	if_is_up;	/* Interface has been marked up */
212 static int	if6_is_up;	/* Interface has been marked up for IPv6, to help differentiate */
213 static int	have_default_route;	/* Gateway for default route added */
214 static u_int32_t proxy_arp_addr;	/* Addr for proxy arp entry added */
215 static char proxy_arp_dev[16];		/* Device for proxy arp entry */
216 static u_int32_t our_old_addr;		/* for detecting address changes */
217 static int	dynaddr_set;		/* 1 if ip_dynaddr set */
218 static int	looped;			/* 1 if using loop */
219 static int	link_mtu;		/* mtu for the link (not bundle) */
220 
221 static struct utsname utsname;	/* for the kernel version */
222 static 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. */
234 static int modify_flags(int fd, int clear_bits, int set_bits);
235 static int translate_speed (int bps);
236 static int baud_rate_of (int speed);
237 static void close_route_table (void);
238 static int open_route_table (void);
239 static int read_route_table (struct rtentry *rt);
240 static int defaultroute_exists (struct rtentry *rt);
241 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
242 			   char *name, int namelen);
243 static void decode_version (char *buf, int *version, int *mod, int *patch);
244 static int set_kdebugflag(int level);
245 static int ppp_registered(void);
246 static int make_ppp_unit(void);
247 static int setifstate (int u, int state);
248 
249 extern 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 
264 extern int hungup;
265 
266 /* new_fd is the fd of a tty */
set_ppp_fd(int new_fd)267 static 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 
still_ppp(void)274 static 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  */
modify_flags(int fd,int clear_bits,int set_bits)291 static 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 
sys_init(void)314 void 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 
sys_cleanup(void)338 void 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  */
364 void
sys_close(void)365 sys_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 
set_kdebugflag(int requested_level)386 static 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 
tty_establish_ppp(int tty_fd)403 int 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  */
generic_establish_ppp(int fd)458 int 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 
tty_disestablish_ppp(int tty_fd)555 void 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     }
585 flushfailed:
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  */
generic_disestablish_ppp(int dev_fd)597 void 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  */
make_ppp_unit()623 static 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  */
cfg_bundle(int mrru,int mtru,int rssn,int tssn)655 void 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  */
make_new_bundle(int mrru,int mtru,int rssn,int tssn)681 void 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  */
bundle_attach(int ifnum)698 int 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  */
destroy_bundle(void)727 void 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  */
clean_check(void)741 void 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 
780 struct 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 
translate_speed(int bps)893 static 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 
baud_rate_of(int speed)912 static 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 
set_up_tty(int tty_fd,int local)932 void 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 
setdtr(int tty_fd,int on)1010 void 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 
restore_tty(int tty_fd)1022 void 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 
output(int unit,unsigned char * p,int len)1047 void 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 
wait_input(struct timeval * timo)1080 void 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  */
add_fd(int fd)1095 void 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  */
remove_fd(int fd)1107 void 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 
read_packet(unsigned char * buf)1118 int 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  */
1162 int
get_loop_output(void)1163 get_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  */
1191 void
netif_set_mtu(int unit,int mtu)1192 netif_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  */
1207 int
netif_get_mtu(int unit)1208 netif_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 
tty_send_config(int mtu,u_int32_t asyncmap,int pcomp,int accomp)1228 void 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 
tty_set_xaccm(ext_accm accm)1252 void 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 
tty_recv_config(int mru,u_int32_t asyncmap,int pcomp,int accomp)1268 void 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 
1299 int
ccp_test(int unit,u_char * opt_ptr,int opt_len,int for_transmit)1300 ccp_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 
ccp_flags_set(int unit,int isopen,int isup)1320 void 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  */
set_filters(struct bpf_program * pass,struct bpf_program * active)1333 int 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  */
1360 int
get_idle_time(u,ip)1361 get_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  */
1372 int
get_ppp_stats(u,stats)1373 get_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 
ccp_fatal_error(int unit)1401 int 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  */
1416 static char proc_path[MAXPATHLEN];
1417 static int proc_path_len;
1418 
path_to_procfs(const char * tail)1419 static 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
1452 FILE *route_fd = (FILE *) 0;
1453 static char route_buffer[512];
1454 static int route_dev_col, route_dest_col, route_gw_col;
1455 static int route_flags_col, route_mask_col;
1456 static int route_num_cols;
1457 
1458 static int open_route_table (void);
1459 static void close_route_table (void);
1460 static int read_route_table (struct rtentry *rt);
1461 
1462 /********************************************************************
1463  *
1464  * close_route_table - close the interface to the route table
1465  */
1466 
close_route_table(void)1467 static 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  */
1479 static char route_delims[] = " \t\n";
1480 
open_route_table(void)1481 static 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 
read_route_table(struct rtentry * rt)1535 static 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 
defaultroute_exists(struct rtentry * rt)1568 static 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  */
have_route_to(u_int32_t addr)1598 int 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 
sifdefaultroute(int unit,u_int32_t ouraddr,u_int32_t gateway)1624 int 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 
cifdefaultroute(int unit,u_int32_t ouraddr,u_int32_t gateway)1664 int 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 
sifproxyarp(int unit,u_int32_t his_adr)1698 int 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 
cifproxyarp(int unit,u_int32_t his_adr)1749 int 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 
get_ether_addr(u_int32_t ipaddr,struct sockaddr * hwaddr,char * name,int namelen)1776 static 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  */
1867 int
get_if_hwaddr(u_char * addr,char * name)1868 get_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  */
1889 char *
get_first_ethernet()1890 get_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 
GetMask(u_int32_t addr)1905 u_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 
decode_version(char * buf,int * version,int * modification,int * patch)1969 static 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 
1993 static int
ppp_registered(void)1994 ppp_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 
ppp_available(void)2032 int 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__)
logwtmp(const char * line,const char * name,const char * host)2164 void 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 
logwtmp(const char * line,const char * name,const char * host)2171 void 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 
sifvjcomp(int u,int vjcomp,int cidcomp,int maxcid)2246 int 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 
sifup(int u)2268 int 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 
sifdown(int u)2284 int 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 
sif6up(int u)2303 int 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 
sif6down(int u)2319 int 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 
setifstate(int u,int state)2335 static 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 
sifaddr(int unit,u_int32_t our_adr,u_int32_t his_adr,u_int32_t net_mask)2365 int 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 
cifaddr(int unit,u_int32_t our_adr,u_int32_t his_adr)2468 int 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  */
sif6addr(int unit,eui64_t our_eui64,eui64_t his_eui64)2521 int 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  */
cif6addr(int unit,eui64_t our_eui64,eui64_t his_eui64)2571 int 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  */
2611 int
get_pty(master_fdp,slave_fdp,slave_name,uid)2612 get_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  */
2687 int
open_ppp_loopback(void)2688 open_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 
2738 int
sifnpmode(u,proto,mode)2739 sifnpmode(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 
sipxfaddr(int unit,unsigned long int network,unsigned char * node)2762 int 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 
cipxfaddr(int unit)2813 int 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  */
2852 int
get_host_seed()2853 get_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 
2869 int
sys_check_options(void)2870 sys_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  */
2909 int
ether_to_eui64(eui64_t * p_eui64)2910 ether_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