void establish_ppp (void) { int pppdisc = N_PPP; int sig = SIGIO; if (ioctl(fd, TIOCEXCL, 0) < 0) { syslog (LOG_WARNING, "ioctl(TIOCEXCL): %m"); } if (ioctl(fd, TIOCGETD, &initdisc) < 0) { syslog(LOG_ERR, "ioctl(TIOCGETD): %m"); die (1); } if (ioctl(fd, TIOCSETD, &pppdisc) < 0) { syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); die (1); } if (ioctl(fd, PPPIOCGUNIT, &ifunit) < 0) { syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m"); die (1); } set_kdebugflag (kdebugflag); set_flags (get_flags() & ~(SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)); MAINDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver", driver_version, driver_modification, driver_patch)); }
/******************************************************************** * * generic_establish_ppp - Turn the fd into a ppp interface. */ int generic_establish_ppp (int fd) { int x; /* * Demand mode - prime the old ppp device to relinquish the unit. */ if (!new_style_driver && looped && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) { error("ioctl(transfer ppp unit): %m"); return -1; } if (new_style_driver) { /* Open another instance of /dev/ppp and connect the channel to it */ int flags; if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) { error("Couldn't get channel number: %m"); goto err; } dbglog("using channel %d", chindex); fd = open("/dev/ppp", O_RDWR); if (fd < 0) { error("Couldn't reopen /dev/ppp: %m"); goto err; } if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) { error("Couldn't attach to channel %d: %m", chindex); goto err_close; } flags = fcntl(fd, F_GETFL); if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) warn("Couldn't set /dev/ppp (channel) to nonblock: %m"); set_ppp_fd(fd); if (!looped) ifunit = -1; if (!looped && !multilink) { /* * Create a new PPP unit. */ if (make_ppp_unit() < 0) goto err_close; } if (looped) set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) & ~SC_LOOP_TRAFFIC); if (!multilink) { add_fd(ppp_dev_fd); if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) { error("Couldn't attach to PPP unit %d: %m", ifunit); goto err_close; } } } else { /* * Old-style driver: find out which interface we were given. */ set_ppp_fd (fd); if (ioctl(fd, PPPIOCGUNIT, &x) < 0) { if (ok_error (errno)) goto err; fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno); } /* Check that we got the same unit again. */ if (looped && x != ifunit) fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x); ifunit = x; /* * Fetch the initial file flags and reset blocking mode on the file. */ initfdflags = fcntl(fd, F_GETFL); if (initfdflags == -1 || fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { if ( ! ok_error (errno)) warn("Couldn't set device to non-blocking mode: %m"); } } /* * Enable debug in the driver if requested. */ if (!looped) set_kdebugflag (kdebugflag); SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver", driver_version, driver_modification, driver_patch)); return ppp_fd; err_close: close(fd); err: if (ioctl(fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno)) warn("Couldn't reset tty to normal line discipline: %m"); return -1; }
void disestablish_ppp(void) { int x; char *s; /* * Fetch the flags for the device and generate appropriate error * messages. */ if (still_ppp() && initdisc >= 0) { if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) { s = NULL; switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) { case SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP: s = "nothing was received"; break; case SC_RCV_B7_0: case SC_RCV_B7_0 | SC_RCV_EVNP: case SC_RCV_B7_0 | SC_RCV_ODDP: case SC_RCV_B7_0 | SC_RCV_ODDP | SC_RCV_EVNP: s = "all had bit 7 set to 1"; break; case SC_RCV_B7_1: case SC_RCV_B7_1 | SC_RCV_EVNP: case SC_RCV_B7_1 | SC_RCV_ODDP: case SC_RCV_B7_1 | SC_RCV_ODDP | SC_RCV_EVNP: s = "all had bit 7 set to 0"; break; case SC_RCV_EVNP: s = "all had odd parity"; break; case SC_RCV_ODDP: s = "all had even parity"; break; } if (s != NULL) { syslog(LOG_WARNING, "Receive serial link is not" " 8-bit clean:"); syslog(LOG_WARNING, "Problem: %s", s); } } set_kdebugflag (prev_kdebugflag); if (ioctl(fd, TIOCSETD, &initdisc) < 0) { syslog(LOG_WARNING, "ioctl(TIOCSETD): %m"); } if (ioctl(fd, TIOCNXCL, 0) < 0) { syslog (LOG_WARNING, "ioctl(TIOCNXCL): %m"); } } initdisc = -1; }