1/* 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 * open_loopback - open the device we use for getting packets 1039 * in demand mode. Under Linux, we use a pty master/slave pair. 1040 */ 1041int 1042open_ppp_loopback(void) 1043{ 1044 int flags; 1045 1046 looped = 1; 1047 if (new_style_driver) { 1048 /* allocate ourselves a ppp unit */ 1049 if (make_ppp_unit() < 0) 1050 die(1); 1051 set_flags(ppp_dev_fd, SC_LOOP_TRAFFIC); 1052 set_kdebugflag(kdebugflag); 1053 ppp_fd = -1; 1054 return ppp_dev_fd; 1055 } 1056 1057 if (!get_pty(&master_fd, &slave_fd, loop_name, 0)) 1058 fatal("No free pty for loopback"); 1059 SYSDEBUG(("using %s for loopback", loop_name)); 1060 1061 set_ppp_fd(slave_fd); 1062 1063 flags = fcntl(master_fd, F_GETFL); 1064 if (flags == -1 || 1065 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1) 1066 warn("couldn't set master loopback to nonblock: %m(%d)", errno); 1067 1068 flags = fcntl(ppp_fd, F_GETFL); 1069 if (flags == -1 || 1070 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1) 1071 warn("couldn't set slave loopback to nonblock: %m(%d)", errno); 1072 1073 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0) 1074 fatal("ioctl(TIOCSETD): %m(%d)", errno); 1075/* 1076 * Find out which interface we were given. 1077 */ 1078 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0) 1079 fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno); 1080/* 1081 * Enable debug in the driver if requested. 1082 */ 1083 set_kdebugflag (kdebugflag); 1084 1085 return master_fd; 1086} 1087 1088/******************************************************************** 1089 * 1090 * restore_loop - reattach the ppp unit to the loopback. 1091 * 1092 * The kernel ppp driver automatically reattaches the ppp unit to 1093 * the loopback if the serial port is set to a line discipline other 1094 * than ppp, or if it detects a modem hangup. The former will happen 1095 * in disestablish_ppp if the latter hasn't already happened, so we 1096 * shouldn't need to do anything. 1097 * 1098 * Just to be sure, set the real serial port to the normal discipline. 1099 */ 1100 1101void 1102restore_loop(void) 1103{ 1104 looped = 1; 1105 if (new_style_driver) { 1106 set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC); 1107 return; 1108 } 1109 if (ppp_fd != slave_fd) { 1110 (void) ioctl(ppp_fd, TIOCSETD, &tty_disc); 1111 set_ppp_fd(slave_fd); 1112 } 1113} 1114 1115/******************************************************************** 1116 * 1117 * sifnpmode - Set the mode for handling packets for a given NP. 1118 */ 1119 1120int 1121sifnpmode(u, proto, mode) 1122 int u; 1123 int proto; 1124 enum NPmode mode; 1125{ 1126 struct npioctl npi; 1127 1128 npi.protocol = proto; 1129 npi.mode = mode; 1130 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) { 1131 if (! ok_error (errno)) 1132 error("ioctl(PPPIOCSNPMODE, %d, %d): %m (%d)", 1133 proto, mode, errno); 1134 return 0; 1135 } 1136 return 1; 1137} 1138 1139/* 1140 * Use the hostname as part of the random number seed. 1141 */ 1142int 1143get_host_seed() 1144{ 1145 int h; 1146 char *p = hostname; 1147 1148 h = 407; 1149 for (p = hostname; *p != 0; ++p) 1150 h = h * 37 + *p; 1151 return h; 1152} 1153