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