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