+/*
+ * transfer_ppp - make the device on fd `fd' take over the PPP interface
+ * unit that we are using.
+ */
+void
+transfer_ppp(fd)
+ int fd;
+{
+ if (fd == ppp_fd)
+ return; /* we can't get here */
+
+ if (fd != loop_slave) {
+ /* go through and save the name of all the modules, then pop em */
+ str_module_count = 0;
+ for (;;) {
+ if (ioctl(fd, I_LOOK, str_modules[str_module_count].modname) < 0 ||
+ ioctl(fd, I_POP, 0) < 0)
+ break;
+ MAINDEBUG((LOG_DEBUG, "popped stream module : %s",
+ str_modules[str_module_count].modname));
+ str_module_count++;
+ }
+ }
+
+ /* now push the async/fcs module */
+ if (ioctl(fd, I_PUSH, "pppasync") < 0) {
+ syslog(LOG_ERR, "ioctl(I_PUSH, ppp_async): %m");
+ die(1);
+ }
+ /* push the compress module */
+ if (ioctl(fd, I_PUSH, "pppcomp") < 0) {
+ syslog(LOG_WARNING, "ioctl(I_PUSH, ppp_comp): %m");
+ }
+ /* finally, push the ppp_if module that actually handles the */
+ /* network interface */
+ if (ioctl(fd, I_PUSH, "pppif") < 0) {
+ syslog(LOG_ERR, "ioctl(I_PUSH, ppp_if): %m");
+ die(1);
+ }
+ pushed_ppp = 1;
+
+ /* read mode, message non-discard mode */
+ if (ioctl(fd, I_SRDOPT, RMSGN) < 0) {
+ syslog(LOG_ERR, "ioctl(I_SRDOPT, RMSGN): %m");
+ die(1);
+ }
+ /*
+ * Connect to the interface unit we want.
+ * (ppp_if handles this ioctl)
+ */
+ if (ioctl(fd, SIOCSETU, &ifunit) < 0) {
+ syslog(LOG_ERR, "ioctl(SIOCSETU): %m");
+ die(1);
+ }
+
+ /* Set debug flags in driver */
+ if (ioctl(fd, SIOCSIFDEBUG, &kdebugflag) < 0) {
+ syslog(LOG_ERR, "ioctl(SIOCSIFDEBUG): %m");
+ }
+
+ /*
+ * Pop the modules off the old ppp stream, and restore
+ * the modules that were there, if this is the real serial port.
+ */
+ while (ioctl(ppp_fd, I_POP, 0) == 0) /* pop any we pushed */
+ ;
+ if (fd == loop_slave) {
+ for (; str_module_count > 0; str_module_count--) {
+ if (ioctl(ppp_fd, I_PUSH, str_modules[str_module_count-1].modname)) {
+ if (errno != ENXIO)
+ syslog(LOG_WARNING,
+ "Couldn't restore STREAMS module %s: %m",
+ str_modules[str_module_count-1].modname);
+ }
+ }
+ }
+ ppp_fd = fd;
+}
+