blob: b18db0f17ebcb21c3a9383eb648e58be8865ebd5 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*
2 * sys-linux.c - System-dependent procedures for setting up
3 * PPP interfaces on Linux systems
4 *
5 * Copyright (c) 1989 Carnegie Mellon University.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by Carnegie Mellon University. The name of the
14 * University may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 */
20
21#include <sys/ioctl.h>
22#include <sys/types.h>
23#include <sys/socket.h>
24#include <sys/time.h>
25#include <sys/errno.h>
26#include <sys/file.h>
27#include <sys/stat.h>
28#include <sys/utsname.h>
29#include <sys/sysmacros.h>
30
31#include <stdio.h>
32#include <stdlib.h>
33#include <syslog.h>
34#include <string.h>
35#include <time.h>
36#include <memory.h>
37#include <utmp.h>
38#include <mntent.h>
39#include <signal.h>
40#include <fcntl.h>
41#include <ctype.h>
42#include <termios.h>
43#include <unistd.h>
44
45/* This is in netdevice.h. However, this compile will fail miserably if
46 you attempt to include netdevice.h because it has so many references
47 to __memcpy functions which it should not attempt to do. So, since I
48 really don't use it, but it must be defined, define it now. */
49
50#ifndef MAX_ADDR_LEN
51#define MAX_ADDR_LEN 7
52#endif
53
54#if __GLIBC__ >= 2
55#include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
56#include <net/if.h>
57#include <net/if_arp.h>
58#include <net/route.h>
59#include <netinet/if_ether.h>
60#else
61#include <linux/types.h>
62#include <linux/if.h>
63#include <linux/if_arp.h>
64#include <linux/route.h>
65#include <linux/if_ether.h>
66#endif
67#include <netinet/in.h>
68#include <arpa/inet.h>
69
70#include <linux/ppp_defs.h>
71#include <linux/if_ppp.h>
72
73#include "pppd.h"
74#include "fsm.h"
75#include "ipcp.h"
76
77/* We can get an EIO error on an ioctl if the modem has hung up */
78#define ok_error(num) ((num)==EIO)
79
80static int tty_disc = N_TTY; /* The TTY discipline */
81static int ppp_disc = N_PPP; /* The PPP discpline */
82static int initfdflags = -1; /* Initial file descriptor flags for fd */
83static int ppp_fd = -1; /* fd which is set to PPP discipline */
84static int sock_fd = -1; /* socket for doing interface ioctls */
85static int slave_fd = -1;
86static int master_fd = -1;
87static int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
88static int chindex; /* channel index (new style driver) */
89
90static fd_set in_fds; /* set of fds that wait_input waits for */
91static int max_in_fd; /* highest fd set in in_fds */
92
93static int driver_version = 0;
94static int driver_modification = 0;
95static int driver_patch = 0;
96
97static char loop_name[20];
98static unsigned char inbuf[512]; /* buffer for chars read from loopback */
99
100static int if_is_up; /* Interface has been marked up */
101static u_int32_t our_old_addr; /* for detecting address changes */
102static int dynaddr_set; /* 1 if ip_dynaddr set */
103static int looped; /* 1 if using loop */
104
105static int kernel_version;
106#define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
107
108#define MAX_IFS 100
109
110#define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
111#define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
112 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
113
114#define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
115
116/* Prototypes for procedures local to this file. */
117static int get_flags (int fd);
118static void set_flags (int fd, int flags);
119static int make_ppp_unit(void);
120static void restore_loop(void); /* Transfer ppp unit back to loopback */
121
122extern u_char inpacket_buf[]; /* borrowed from main.c */
123
124/*
125 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
126 * if it exists.
127 */
128
129#define SET_SA_FAMILY(addr, family) \
130 memset ((char *) &(addr), '\0', sizeof(addr)); \
131 addr.sa_family = (family);
132
133/*
134 * Determine if the PPP connection should still be present.
135 */
136
137extern int hungup;
138
139/* new_fd is the fd of a tty */
140static void set_ppp_fd (int new_fd)
141{
142 SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", new_fd));
143 ppp_fd = new_fd;
144 if (!new_style_driver)
145 ppp_dev_fd = new_fd;
146}
147
148static int still_ppp(void)
149{
150 if (new_style_driver)
151 return !hungup && ppp_fd >= 0;
152 if (!hungup || ppp_fd == slave_fd)
153 return 1;
154 if (slave_fd >= 0) {
155 set_ppp_fd(slave_fd);
156 return 1;
157 }
158 return 0;
159}
160
161/********************************************************************
162 *
163 * Functions to read and set the flags value in the device driver
164 */
165
166static int get_flags (int fd)
167{
168 int flags;
169
170 if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &flags) < 0) {
171 if ( ok_error (errno) )
172 flags = 0;
173 else
174 fatal("ioctl(PPPIOCGFLAGS): %m");
175 }
176
177 SYSDEBUG ((LOG_DEBUG, "get flags = %x\n", flags));
178 return flags;
179}
180
181/********************************************************************/
182
183static void set_flags (int fd, int flags)
184{
185 SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags));
186
187 if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) {
188 if (! ok_error (errno) )
189 fatal("ioctl(PPPIOCSFLAGS, %x): %m", flags, errno);
190 }
191}
192
193/********************************************************************
194 *
195 * sys_init - System-dependent initialization.
196 */
197
198void sys_init(void)
199{
200 int flags;
201
202 if (new_style_driver) {
203 ppp_dev_fd = open("/dev/ppp", O_RDWR);
204 if (ppp_dev_fd < 0)
205 fatal("Couldn't open /dev/ppp: %m");
206 flags = fcntl(ppp_dev_fd, F_GETFL);
207 if (flags == -1
208 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
209 warn("Couldn't set /dev/ppp to nonblock: %m");
210 }
211
212 /* Get an internet socket for doing socket ioctls. */
213 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
214 if (sock_fd < 0)
215 fatal("Couldn't create IP socket: %m(%d)", errno);
216
217 FD_ZERO(&in_fds);
218 max_in_fd = 0;
219}
220
221/********************************************************************
222 *
223 * sys_cleanup - restore any system state we modified before exiting:
224 * mark the interface down, delete default route and/or proxy arp entry.
225 * This shouldn't call die() because it's called from die().
226 */
227
228void sys_cleanup(void)
229{
230/*
231 * Take down the device
232 */
233 if (if_is_up) {
234 if_is_up = 0;
235 sifdown(0);
236 }
237}
238
239/********************************************************************
240 *
241 * sys_close - Clean up in a child process before execing.
242 */
243void
244sys_close(void)
245{
246 close(ppp_dev_fd);
247 if (sock_fd >= 0)
248 close(sock_fd);
249 if (slave_fd >= 0)
250 close(slave_fd);
251 if (master_fd >= 0)
252 close(master_fd);
253 closelog();
254}
255
256/********************************************************************
257 *
258 * set_kdebugflag - Define the debugging level for the kernel
259 */
260
261static int set_kdebugflag (int requested_level)
262{
263 if (new_style_driver && ifunit < 0)
264 return 1;
265 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
266 if ( ! ok_error (errno) )
267 error("ioctl(PPPIOCSDEBUG): %m");
268 return (0);
269 }
270 SYSDEBUG ((LOG_INFO, "set kernel debugging level to %d",
271 requested_level));
272 return (1);
273}
274
275
276/********************************************************************
277 *
278 * generic_establish_ppp - Turn the fd into a ppp interface.
279 */
280int generic_establish_ppp (int fd)
281{
282 int x;
283/*
284 * Demand mode - prime the old ppp device to relinquish the unit.
285 */
286 if (!new_style_driver && looped
287 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
288 error("ioctl(transfer ppp unit): %m");
289 return -1;
290 }
291
292
293 if (new_style_driver) {
294 /* Open another instance of /dev/ppp and connect the channel to it */
295 int flags;
296
297 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
298 error("Couldn't get channel number: %m");
299 goto err;
300 }
301 dbglog("using channel %d", chindex);
302 fd = open("/dev/ppp", O_RDWR);
303 if (fd < 0) {
304 error("Couldn't reopen /dev/ppp: %m");
305 goto err;
306 }
307 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
308 error("Couldn't attach to channel %d: %m", chindex);
309 goto err_close;
310 }
311 flags = fcntl(fd, F_GETFL);
312 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
313 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
314 set_ppp_fd(fd);
315
316 if (!looped)
317 ifunit = -1;
318 if (!looped && !multilink) {
319 /*
320 * Create a new PPP unit.
321 */
322 if (make_ppp_unit() < 0)
323 goto err_close;
324 }
325
326 if (looped)
327 set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) & ~SC_LOOP_TRAFFIC);
328
329 if (!multilink) {
330 add_fd(ppp_dev_fd);
331 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
332 error("Couldn't attach to PPP unit %d: %m", ifunit);
333 goto err_close;
334 }
335 }
336
337 } else {
338
339 /*
340 * Old-style driver: find out which interface we were given.
341 */
342 set_ppp_fd (fd);
343 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
344 if (ok_error (errno))
345 goto err;
346 fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
347 }
348 /* Check that we got the same unit again. */
349 if (looped && x != ifunit)
350 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
351 ifunit = x;
352
353 /*
354 * Fetch the initial file flags and reset blocking mode on the file.
355 */
356 initfdflags = fcntl(fd, F_GETFL);
357 if (initfdflags == -1 ||
358 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
359 if ( ! ok_error (errno))
360 warn("Couldn't set device to non-blocking mode: %m");
361 }
362 }
363
364
365 /*
366 * Enable debug in the driver if requested.
367 */
368 if (!looped)
369 set_kdebugflag (kdebugflag);
370
371 SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver",
372 driver_version, driver_modification, driver_patch));
373
374 return ppp_fd;
375
376 err_close:
377 close(fd);
378 err:
379 if (ioctl(fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
380 warn("Couldn't reset tty to normal line discipline: %m");
381 return -1;
382}
383
384/********************************************************************
385 *
386 * generic_disestablish_ppp - Restore device components to normal
387 * operation, and reconnect the ppp unit to the loopback if in demand
388 * mode. This shouldn't call die() because it's called from die().
389*/
390void generic_disestablish_ppp(int dev_fd){
391 /* Restore loop if needed */
392 if(demand)
393 restore_loop();
394
395 /* Finally detach the device */
396 initfdflags = -1;
397
398 if (new_style_driver) {
399 close(ppp_fd);
400 ppp_fd = -1;
401 if (!looped && ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0)
402 error("Couldn't release PPP unit: %m");
403 if (!multilink)
404 remove_fd(ppp_dev_fd);
405 }
406}
407
408/*
409 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
410 * Assumes new_style_driver.
411 */
412static int make_ppp_unit()
413{
414 int x;
415
416 ifunit = req_unit;
417 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
418 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
419 warn("Couldn't allocate PPP unit %d as it is already in use");
420 ifunit = -1;
421 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
422 }
423 if (x < 0)
424 error("Couldn't create new ppp unit: %m");
425 return x;
426}
427
428/********************************************************************
429 *
430 * clean_check - Fetch the flags for the device and generate
431 * appropriate error messages.
432 */
433void clean_check(void)
434{
435 int x;
436 char *s;
437
438 if (still_ppp()) {
439 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
440 s = NULL;
441 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
442 case SC_RCV_B7_0:
443 s = "all had bit 7 set to 1";
444 break;
445
446 case SC_RCV_B7_1:
447 s = "all had bit 7 set to 0";
448 break;
449
450 case SC_RCV_EVNP:
451 s = "all had odd parity";
452 break;
453
454 case SC_RCV_ODDP:
455 s = "all had even parity";
456 break;
457 }
458
459 if (s != NULL) {
460 warn("Receive serial link is not 8-bit clean:");
461 warn("Problem: %s", s);
462 }
463 }
464 }
465}
466
467/********************************************************************
468 *
469 * output - Output PPP packet.
470 */
471
472void output (int unit, unsigned char *p, int len)
473{
474 int fd = ppp_fd;
475 int proto;
476
477 if (debug)
478 dbglog("sent %P", p, len);
479
480 if (len < PPP_HDRLEN)
481 return;
482 if (new_style_driver) {
483 p += 2;
484 len -= 2;
485 proto = (p[0] << 8) + p[1];
486 if (ifunit >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
487 fd = ppp_dev_fd;
488 }
489 if (write(fd, p, len) < 0) {
490 if (errno == EWOULDBLOCK || errno == ENOBUFS
491 || errno == ENXIO || errno == EIO || errno == EINTR)
492 warn("write: warning: %m (%d)", errno);
493 else
494 error("write: %m (%d)", errno);
495 }
496}
497
498/********************************************************************
499 *
500 * wait_input - wait until there is data available,
501 * for the length of time specified by *timo (indefinite
502 * if timo is NULL).
503 */
504
505void wait_input(struct timeval *timo)
506{
507 fd_set ready, exc;
508 int n;
509
510 ready = in_fds;
511 exc = in_fds;
512 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
513 if (n < 0 && errno != EINTR)
514 fatal("select: %m(%d)", errno);
515}
516
517/*
518 * add_fd - add an fd to the set that wait_input waits for.
519 */
520void add_fd(int fd)
521{
522 FD_SET(fd, &in_fds);
523 if (fd > max_in_fd)
524 max_in_fd = fd;
525}
526
527/*
528 * remove_fd - remove an fd from the set that wait_input waits for.
529 */
530void remove_fd(int fd)
531{
532 FD_CLR(fd, &in_fds);
533}
534
535
536/********************************************************************
537 *
538 * read_packet - get a PPP packet from the serial device.
539 */
540
541int read_packet (unsigned char *buf)
542{
543 int len, nr;
544
545 len = PPP_MRU + PPP_HDRLEN;
546 if (new_style_driver) {
547 *buf++ = PPP_ALLSTATIONS;
548 *buf++ = PPP_UI;
549 len -= 2;
550 }
551 nr = -1;
552 if (ppp_fd >= 0) {
553 nr = read(ppp_fd, buf, len);
554 if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR)
555 error("read: %m");
556 if (nr < 0 && errno == ENXIO)
557 return 0;
558 }
559 if (nr < 0 && new_style_driver && ifunit >= 0) {
560 /* N.B. we read ppp_fd first since LCP packets come in there. */
561 nr = read(ppp_dev_fd, buf, len);
562 if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR)
563 error("read /dev/ppp: %m");
564 if (nr < 0 && errno == ENXIO)
565 return 0;
566 }
567 return (new_style_driver && nr > 0)? nr+2: nr;
568}
569
570/********************************************************************
571 *
572 * get_loop_output - get outgoing packets from the ppp device,
573 * and detect when we want to bring the real link up.
574 * Return value is 1 if we need to bring up the link, 0 otherwise.
575 */
576int
577get_loop_output(void)
578{
579 int rv = 0;
580 int n;
581
582 if (new_style_driver) {
583 while ((n = read_packet(inpacket_buf)) > 0)
584 if (loop_frame(inpacket_buf, n))
585 rv = 1;
586 return rv;
587 }
588
589 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
590 if (loop_chars(inbuf, n))
591 rv = 1;
592
593 if (n == 0)
594 fatal("eof on loopback");
595
596 if (errno != EWOULDBLOCK)
597 fatal("read from loopback: %m(%d)", errno);
598
599 return rv;
600}
601
602/*
603 * netif_set_mtu - set the MTU on the PPP network interface.
604 */
605void
606netif_set_mtu(int unit, int mtu)
607{
608 struct ifreq ifr;
609
610 SYSDEBUG ((LOG_DEBUG, "netif_set_mtu: mtu = %d\n", mtu));
611
612 memset (&ifr, '\0', sizeof (ifr));
613 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
614 ifr.ifr_mtu = mtu;
615
616 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
617 fatal("ioctl(SIOCSIFMTU): %m");
618}
619
620/********************************************************************
621 *
622 * ccp_test - ask kernel whether a given compression method
623 * is acceptable for use.
624 */
625
626int ccp_test (int unit, u_char *opt_ptr, int opt_len, int for_transmit)
627{
628 struct ppp_option_data data;
629
630 memset (&data, '\0', sizeof (data));
631 data.ptr = opt_ptr;
632 data.length = opt_len;
633 data.transmit = for_transmit;
634
635 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
636 return 1;
637
638 return (errno == ENOBUFS)? 0: -1;
639}
640
641/********************************************************************
642 *
643 * ccp_flags_set - inform kernel about the current state of CCP.
644 */
645
646void ccp_flags_set (int unit, int isopen, int isup)
647{
648 if (still_ppp()) {
649 int x = get_flags(ppp_dev_fd);
650 x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN;
651 x = isup? x | SC_CCP_UP : x &~ SC_CCP_UP;
652 set_flags (ppp_dev_fd, x);
653 }
654}
655
656/********************************************************************
657 *
658 * get_idle_time - return how long the link has been idle.
659 */
660int
661get_idle_time(u, ip)
662 int u;
663 struct ppp_idle *ip;
664{
665 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
666}
667
668/********************************************************************
669 *
670 * get_ppp_stats - return statistics for the link.
671 */
672int
673get_ppp_stats(u, stats)
674 int u;
675 struct pppd_stats *stats;
676{
677 struct ifpppstatsreq req;
678
679 memset (&req, 0, sizeof (req));
680
681 req.stats_ptr = (caddr_t) &req.stats;
682 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
683 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
684 error("Couldn't get PPP statistics: %m");
685 return 0;
686 }
687 stats->bytes_in = req.stats.p.ppp_ibytes;
688 stats->bytes_out = req.stats.p.ppp_obytes;
689 return 1;
690}
691
692/********************************************************************
693 *
694 * ccp_fatal_error - returns 1 if decompression was disabled as a
695 * result of an error detected after decompression of a packet,
696 * 0 otherwise. This is necessary because of patent nonsense.
697 */
698
699int ccp_fatal_error (int unit)
700{
701 int x = get_flags(ppp_dev_fd);
702
703 return x & SC_DC_FERROR;
704}
705
706/********************************************************************
707 *
708 * Return user specified netmask, modified by any mask we might determine
709 * for address `addr' (in network byte order).
710 * Here we scan through the system's list of interfaces, looking for
711 * any non-point-to-point interfaces which might appear to be on the same
712 * network as `addr'. If we find any, we OR in their netmask to the
713 * user-specified netmask.
714 */
715
716u_int32_t GetMask (u_int32_t addr)
717{
718 u_int32_t mask, nmask, ina;
719 struct ifreq *ifr, *ifend, ifreq;
720 struct ifconf ifc;
721 struct ifreq ifs[MAX_IFS];
722
723 addr = ntohl(addr);
724
725 if (IN_CLASSA(addr)) /* determine network mask for address class */
726 nmask = IN_CLASSA_NET;
727 else if (IN_CLASSB(addr))
728 nmask = IN_CLASSB_NET;
729 else
730 nmask = IN_CLASSC_NET;
731
732 /* class D nets are disallowed by bad_ip_adrs */
733 mask = netmask | htonl(nmask);
734/*
735 * Scan through the system's network interfaces.
736 */
737 ifc.ifc_len = sizeof(ifs);
738 ifc.ifc_req = ifs;
739 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
740 if ( ! ok_error ( errno ))
741 warn("ioctl(SIOCGIFCONF): %m(%d)", errno);
742 return mask;
743 }
744
745 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
746 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
747/*
748 * Check the interface's internet address.
749 */
750 if (ifr->ifr_addr.sa_family != AF_INET)
751 continue;
752 ina = SIN_ADDR(ifr->ifr_addr);
753 if (((ntohl(ina) ^ addr) & nmask) != 0)
754 continue;
755/*
756 * Check that the interface is up, and not point-to-point nor loopback.
757 */
758 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
759 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
760 continue;
761
762 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
763 continue;
764/*
765 * Get its netmask and OR it into our mask.
766 */
767 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
768 continue;
769 mask |= SIN_ADDR(ifreq.ifr_addr);
770 break;
771 }
772 return mask;
773}
774
775/********************************************************************
776 *
777 * ppp_available - check whether the system has any ppp interfaces
778 * (in fact we check whether we can do an ioctl on ppp0).
779 */
780
781int ppp_available(void)
782{
783 struct utsname utsname; /* for the kernel version */
784 int osmaj, osmin, ospatch;
785
786 /* get the kernel version now, since we are called before sys_init */
787 uname(&utsname);
788 osmaj = osmin = ospatch = 0;
789 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
790 kernel_version = KVERSION(osmaj, osmin, ospatch);
791
792 driver_version = 2;
793 driver_modification = 4;
794 driver_patch = 0;
795
796 return 1;
797}
798
799/********************************************************************
800 *
801 * sifvjcomp - config tcp header compression
802 */
803
804int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
805{
806 u_int x = get_flags(ppp_dev_fd);
807
808 if (vjcomp) {
809 if (ioctl (ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
810 if (! ok_error (errno))
811 error("ioctl(PPPIOCSMAXCID): %m(%d)", errno);
812 vjcomp = 0;
813 }
814 }
815
816 x = vjcomp ? x | SC_COMP_TCP : x &~ SC_COMP_TCP;
817 x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;
818 set_flags (ppp_dev_fd, x);
819
820 return 1;
821}
822
823/********************************************************************
824 *
825 * sifup - Config the interface up and enable IP packets to pass.
826 */
827
828int sifup(int u)
829{
830 struct ifreq ifr;
831
832 memset (&ifr, '\0', sizeof (ifr));
833 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
834 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
835 if (! ok_error (errno))
836 error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
837 return 0;
838 }
839
840 ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
841 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
842 if (! ok_error (errno))
843 error("ioctl(SIOCSIFFLAGS): %m(%d)", errno);
844 return 0;
845 }
846 if_is_up++;
847
848 return 1;
849}
850
851/********************************************************************
852 *
853 * sifdown - Disable the indicated protocol and config the interface
854 * down if there are no remaining protocols.
855 */
856
857int sifdown (int u)
858{
859 struct ifreq ifr;
860
861 if (if_is_up && --if_is_up > 0)
862 return 1;
863
864 memset (&ifr, '\0', sizeof (ifr));
865 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
866 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
867 if (! ok_error (errno))
868 error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
869 return 0;
870 }
871
872 ifr.ifr_flags &= ~IFF_UP;
873 ifr.ifr_flags |= IFF_POINTOPOINT;
874 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
875 if (! ok_error (errno))
876 error("ioctl(SIOCSIFFLAGS): %m(%d)", errno);
877 return 0;
878 }
879 return 1;
880}
881
882/********************************************************************
883 *
884 * sifaddr - Config the interface IP addresses and netmask.
885 */
886
887int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
888 u_int32_t net_mask)
889{
890 struct ifreq ifr;
891 struct rtentry rt;
892
893 memset (&ifr, '\0', sizeof (ifr));
894 memset (&rt, '\0', sizeof (rt));
895
896 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
897 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
898 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
899
900 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
901/*
902 * Set our IP address
903 */
904 SIN_ADDR(ifr.ifr_addr) = our_adr;
905 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
906 if (errno != EEXIST) {
907 if (! ok_error (errno))
908 error("ioctl(SIOCSIFADDR): %m(%d)", errno);
909 }
910 else {
911 warn("ioctl(SIOCSIFADDR): Address already exists");
912 }
913 return (0);
914 }
915/*
916 * Set the gateway address
917 */
918 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
919 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
920 if (! ok_error (errno))
921 error("ioctl(SIOCSIFDSTADDR): %m(%d)", errno);
922 return (0);
923 }
924/*
925 * Set the netmask.
926 * For recent kernels, force the netmask to 255.255.255.255.
927 */
928 if (kernel_version >= KVERSION(2,1,16))
929 net_mask = ~0L;
930 if (net_mask != 0) {
931 SIN_ADDR(ifr.ifr_netmask) = net_mask;
932 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
933 if (! ok_error (errno))
934 error("ioctl(SIOCSIFNETMASK): %m(%d)", errno);
935 return (0);
936 }
937 }
938/*
939 * Add the device route
940 */
941 if (kernel_version < KVERSION(2,1,16)) {
942 SET_SA_FAMILY (rt.rt_dst, AF_INET);
943 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
944 rt.rt_dev = ifname;
945
946 SIN_ADDR(rt.rt_gateway) = 0L;
947 SIN_ADDR(rt.rt_dst) = his_adr;
948 rt.rt_flags = RTF_UP | RTF_HOST;
949
950 if (kernel_version > KVERSION(2,1,0)) {
951 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
952 SIN_ADDR(rt.rt_genmask) = -1L;
953 }
954
955 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
956 if (! ok_error (errno))
957 error("ioctl(SIOCADDRT) device route: %m(%d)", errno);
958 return (0);
959 }
960 }
961
962 /* set ip_dynaddr in demand mode if address changes */
963 if (demand && tune_kernel && !dynaddr_set
964 && our_old_addr && our_old_addr != our_adr) {
965 /* set ip_dynaddr if possible */
966 char *path;
967 int fd;
968
969 path = "/proc/sys/net/ipv4/ip_dynaddr";
970 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
971 if (write(fd, "1", 1) != 1)
972 error("Couldn't enable dynamic IP addressing: %m");
973 close(fd);
974 }
975 dynaddr_set = 1; /* only 1 attempt */
976 }
977 our_old_addr = 0;
978
979 return 1;
980}
981
982/********************************************************************
983 *
984 * cifaddr - Clear the interface IP addresses, and delete routes
985 * through the interface if possible.
986 */
987
988int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
989{
990 struct ifreq ifr;
991
992 if (kernel_version < KVERSION(2,1,16)) {
993/*
994 * Delete the route through the device
995 */
996 struct rtentry rt;
997 memset (&rt, '\0', sizeof (rt));
998
999 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1000 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1001 rt.rt_dev = ifname;
1002
1003 SIN_ADDR(rt.rt_gateway) = 0;
1004 SIN_ADDR(rt.rt_dst) = his_adr;
1005 rt.rt_flags = RTF_UP | RTF_HOST;
1006
1007 if (kernel_version > KVERSION(2,1,0)) {
1008 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1009 SIN_ADDR(rt.rt_genmask) = -1L;
1010 }
1011
1012 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1013 if (still_ppp() && ! ok_error (errno))
1014 error("ioctl(SIOCDELRT) device route: %m(%d)", errno);
1015 return (0);
1016 }
1017 }
1018
1019 /* This way it is possible to have an IPX-only or IPv6-only interface */
1020 memset(&ifr, 0, sizeof(ifr));
1021 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
1022 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1023
1024 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
1025 if (! ok_error (errno)) {
1026 error("ioctl(SIOCSIFADDR): %m(%d)", errno);
1027 return 0;
1028 }
1029 }
1030
1031 our_old_addr = our_adr;
1032
1033 return 1;
1034}
1035
1036//===================================================================
1037
1038#if 1
1039/*
1040 * /proc/net/route parsing stuff.
1041 */
1042
1043#define ROUTE_MAX_COLS 12
1044FILE *route_fd = (FILE *) 0;
1045static char route_buffer[512];
1046static int route_dev_col, route_dest_col, route_gw_col;
1047static int route_flags_col, route_mask_col;
1048static int route_num_cols;
1049
1050static int open_route_table (void);
1051static void close_route_table (void);
1052static int read_route_table (struct rtentry *rt);
1053static char route_delims[] = " \t\n";
1054
1055/********************************************************************
1056 *
1057 * close_route_table - close the interface to the route table
1058 */
1059// copy from pppd/sys-linux.c by tallest
1060static void close_route_table (void)
1061{
1062 if (route_fd != (FILE *) 0) {
1063 fclose (route_fd);
1064 route_fd = (FILE *) 0;
1065 }
1066}
1067
1068/********************************************************************
1069 *
1070 * read_route_table - read the next entry from the route table
1071 */
1072// copy from pppd/sys-linux.c by tallest
1073static int read_route_table(struct rtentry *rt)
1074{
1075 char *cols[ROUTE_MAX_COLS], *p;
1076 int col;
1077
1078 memset (rt, '\0', sizeof (struct rtentry));
1079
1080 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1081 return 0;
1082
1083 p = route_buffer;
1084 for (col = 0; col < route_num_cols; ++col) {
1085 cols[col] = strtok(p, route_delims);
1086 if (cols[col] == NULL)
1087 return 0; /* didn't get enough columns */
1088 p = NULL;
1089 }
1090
1091 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1092 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1093 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1094
1095 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1096 rt->rt_dev = cols[route_dev_col];
1097
1098 return 1;
1099}
1100
1101/********************************************************************
1102 *
1103 * open_route_table - open the interface to the route table
1104 */
1105// copy from pppd/sys-linux.c by tallest
1106
1107static int open_route_table (void)
1108{
1109 char *path;
1110
1111 close_route_table();
1112
1113 //path = path_to_procfs("/net/route");
1114 //route_fd = fopen (path, "r");
1115 route_fd = fopen ("proc/net/route", "r");
1116 if (route_fd == NULL) {
1117 error("can't open routing table");
1118 return 0;
1119 }
1120
1121 route_dev_col = 0; /* default to usual columns */
1122 route_dest_col = 1;
1123 route_gw_col = 2;
1124 route_flags_col = 3;
1125 route_mask_col = 7;
1126 route_num_cols = 8;
1127
1128 /* parse header line */
1129 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1130 char *p = route_buffer, *q;
1131 int col;
1132 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1133 int used = 1;
1134 if ((q = strtok(p, route_delims)) == 0)
1135 break;
1136 if (strcasecmp(q, "iface") == 0)
1137 route_dev_col = col;
1138 else if (strcasecmp(q, "destination") == 0)
1139 route_dest_col = col;
1140 else if (strcasecmp(q, "gateway") == 0)
1141 route_gw_col = col;
1142 else if (strcasecmp(q, "flags") == 0)
1143 route_mask_col = col;
1144 else
1145 used = 0;
1146 if (used && col >= route_num_cols)
1147 route_num_cols = col + 1;
1148 p = NULL;
1149 }
1150 }
1151
1152 return 1;
1153}
1154
1155/********************************************************************
1156 *
1157 * defaultroute_exists - determine if there is a default route
1158 */
1159// copy from pppd/sys-linux.c by tallest
1160static int defaultroute_exists (struct rtentry *rt)
1161{
1162 int result = 0;
1163
1164 if (!open_route_table())
1165 return 0;
1166
1167 while (read_route_table(rt) != 0) {
1168 if ((rt->rt_flags & RTF_UP) == 0)
1169 continue;
1170
1171 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1172 continue;
1173 if (SIN_ADDR(rt->rt_dst) == 0L) {
1174 result = 1;
1175 break;
1176 }
1177 }
1178
1179 close_route_table();
1180 return result;
1181}
1182
1183/********************************************************************
1184 *
1185 * sifdefaultroute - assign a default route through the address given.
1186 */
1187// copy from pppd/sys_linux.c by tallest
1188int
1189sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1190{
1191 struct rtentry rt;
1192
1193 if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1194 u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway);
1195
1196 if (old_gateway != gateway)
1197 error("not replacing existing default route to %s [%I]",
1198 rt.rt_dev, old_gateway);
1199 return 0;
1200 }
1201
1202 memset (&rt, '\0', sizeof (rt));
1203 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1204 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1205
1206 if (kernel_version > KVERSION(2,1,0)) {
1207 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1208 SIN_ADDR(rt.rt_genmask) = 0L;
1209 }
1210
1211 SIN_ADDR(rt.rt_gateway) = gateway;
1212
1213 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1214 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1215 if ( ! ok_error ( errno ))
1216 error("default route ioctl(SIOCADDRT): %m(%d)", errno);
1217 return 0;
1218 }
1219
1220 //default_route_gateway = gateway;
1221 return 1;
1222}
1223#endif
1224//===================================================================
1225
1226
1227/********************************************************************
1228 *
1229 * open_loopback - open the device we use for getting packets
1230 * in demand mode. Under Linux, we use a pty master/slave pair.
1231 */
1232int
1233open_ppp_loopback(void)
1234{
1235 int flags;
1236
1237 looped = 1;
1238 if (new_style_driver) {
1239 /* allocate ourselves a ppp unit */
1240 if (make_ppp_unit() < 0)
1241 die(1);
1242 set_flags(ppp_dev_fd, SC_LOOP_TRAFFIC);
1243 set_kdebugflag(kdebugflag);
1244 ppp_fd = -1;
1245 return ppp_dev_fd;
1246 }
1247
1248 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
1249 fatal("No free pty for loopback");
1250 SYSDEBUG(("using %s for loopback", loop_name));
1251
1252 set_ppp_fd(slave_fd);
1253
1254 flags = fcntl(master_fd, F_GETFL);
1255 if (flags == -1 ||
1256 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
1257 warn("couldn't set master loopback to nonblock: %m(%d)", errno);
1258
1259 flags = fcntl(ppp_fd, F_GETFL);
1260 if (flags == -1 ||
1261 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
1262 warn("couldn't set slave loopback to nonblock: %m(%d)", errno);
1263
1264 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
1265 fatal("ioctl(TIOCSETD): %m(%d)", errno);
1266/*
1267 * Find out which interface we were given.
1268 */
1269 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
1270 fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
1271/*
1272 * Enable debug in the driver if requested.
1273 */
1274 set_kdebugflag (kdebugflag);
1275
1276 return master_fd;
1277}
1278
1279/********************************************************************
1280 *
1281 * restore_loop - reattach the ppp unit to the loopback.
1282 *
1283 * The kernel ppp driver automatically reattaches the ppp unit to
1284 * the loopback if the serial port is set to a line discipline other
1285 * than ppp, or if it detects a modem hangup. The former will happen
1286 * in disestablish_ppp if the latter hasn't already happened, so we
1287 * shouldn't need to do anything.
1288 *
1289 * Just to be sure, set the real serial port to the normal discipline.
1290 */
1291
1292void
1293restore_loop(void)
1294{
1295 looped = 1;
1296 if (new_style_driver) {
1297 set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC);
1298 return;
1299 }
1300 if (ppp_fd != slave_fd) {
1301 (void) ioctl(ppp_fd, TIOCSETD, &tty_disc);
1302 set_ppp_fd(slave_fd);
1303 }
1304}
1305
1306/********************************************************************
1307 *
1308 * sifnpmode - Set the mode for handling packets for a given NP.
1309 */
1310
1311int
1312sifnpmode(u, proto, mode)
1313 int u;
1314 int proto;
1315 enum NPmode mode;
1316{
1317 struct npioctl npi;
1318
1319 npi.protocol = proto;
1320 npi.mode = mode;
1321 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
1322 if (! ok_error (errno))
1323 error("ioctl(PPPIOCSNPMODE, %d, %d): %m (%d)",
1324 proto, mode, errno);
1325 return 0;
1326 }
1327 return 1;
1328}
1329
1330/*
1331 * Use the hostname as part of the random number seed.
1332 */
1333int
1334get_host_seed()
1335{
1336 int h;
1337 char *p = hostname;
1338
1339 h = 407;
1340 for (p = hostname; *p != 0; ++p)
1341 h = h * 37 + *p;
1342 return h;
1343}