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