📄 ppplib.c
字号:
die(unit, 1); } syslog(LOG_INFO, "Connected..."); } MAINDEBUG((LOG_INFO, "Using interface ppp%d", unit)); (void) sprintf(ppp_if[unit]->ifname, "ppp%d", unit); /* * Block all signals, start opening the connection, and wait for * incoming signals (reply, timeout, etc.). */ syslog (LOG_NOTICE, "Connect: %s <--> %s", ppp_if[unit]->ifname, ppp_if[unit]->devname); sigprocmask(SIG_BLOCK, &mask, NULL); /* Block signals now */ lcp_lowerup(unit); /* XXX Well, sort of... */ lcp_open(unit); /* Start protocol */ sigemptyset(&mask); for (ppp_if[unit]->phase = PHASE_ESTABLISH, errno = 0; ppp_if[unit]->phase != PHASE_DEAD;) { sigsuspend(&mask); /* Wait for next signal */ if (errno != EINTR) { syslog(LOG_ERR, "ppp_task: sigsuspend error!"); break; } errno = 0; /* reset errno */ } /* run disconnection hook routine */ if ((pppHookRtns[unit] != NULL) && (pppHookRtns[unit]->disconnectHook != NULL)) { if (((*pppHookRtns[unit]->disconnectHook) (unit, ppp_if[unit]->fd)) == ERROR) { syslog(LOG_WARNING, "disconnect hook failed"); die(unit, 1); } syslog(LOG_INFO, "Disconnected..."); } die(unit, 1);} /********************************************************************************* pppDelete - delete a PPP network interface** This routine deletes the Point-to-Point Protocol (PPP) network interface* specified by the unit number <unit>.** A Link Control Protocol (LCP) terminate request packet is sent to notify* the peer of the impending PPP link shut-down. The associated serial* interface (<tty>) is then detached from the PPP driver, and the PPP interface* is deleted from the list of network interfaces. Finally, all resources* associated with the PPP link are returned to the VxWorks system.** RETURNS: N/A*/void pppDelete ( int unit /* PPP interface unit number to delete */ ) { if (ppp_if[unit] != NULL) netJobAdd ((FUNCPTR)kill, ppp_if[unit]->task_id, SIGTERM, 0, 0, 0); }/* * Translate from bits/second to a speed_t. */static inttranslate_speed(bps) int bps;{ return bps;}/* * translate from a speed_t to bits/second. */static intbaud_rate_of(speed) int speed;{ return speed;}/* * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity, * at the requested speed, etc. If `local' is true, set CLOCAL * regardless of whether the modem option was specified. */static intset_up_tty(fd) int fd;{ int speed; int state; /* * Put the tty in raw mode */ if ((state = ioctl(fd, FIOGETOPTIONS, NULL)) == ERROR) { syslog(LOG_ERR, "ioctl(FIOGETOPTIONS) error"); die(ppp_unit, 1); } if (!ppp_if[ppp_unit]->restore_term) ppp_if[ppp_unit]->ttystate = state; speed = translate_speed(ppp_if[ppp_unit]->inspeed); if (ioctl(fd, FIOOPTIONS, OPT_RAW) < 0) { syslog(LOG_ERR, "ioctl(FIOOPTIONS) error"); die(ppp_unit, 1); } if (speed && ioctl(fd, FIOBAUDRATE, speed) == ERROR) { syslog(LOG_ERR, "ioctl(FIOBAUDRATE) error"); die(ppp_unit, 1); } ppp_if[ppp_unit]->baud_rate = baud_rate_of(speed); ppp_if[ppp_unit]->restore_term = TRUE; return 0;} /* * die - like quit, except we can specify an exit status. */voiddie(unit, status) int unit; int status;{ fsm *f = &ppp_if[unit]->lcp_fsm; lcp_close(unit); /* Close connection */ if (f->flags & (OPT_PASSIVE | OPT_SILENT)) return; MAINDEBUG((LOG_INFO, " Exitting.")); cleanup(unit, status, NULL); if (status) exit(status);}/* * cleanup - restore anything which needs to be restored before we exit */static voidcleanup(unit, status, arg) int unit; int status; caddr_t arg;{ if (unit < 0 || unit > NPPP) return; { disestablish_ppp(); if (ppp_if[unit]->restore_term) { if (ioctl(ppp_if[unit]->fd, FIOSETOPTIONS, ppp_if[unit]->ttystate) == ERROR) syslog(LOG_ERR, "ioctl(FIOSETOPTIONS) error"); } pppclose(unit); ppp_if[unit]->fd = ERROR; } if (ppp_if[unit]->s != ERROR) close(ppp_if[unit]->s); if (!status) if (ppp_if[unit]->task_id) taskDelete(ppp_if[unit]->task_id); timer_delete(ppp_if[unit]->timer_id); free(ppp_parms[unit]->task_name); if (ppp_parms[unit]->devname) free(ppp_parms[unit]->devname); if (ppp_parms[unit]->local_addr) free(ppp_parms[unit]->local_addr); if (ppp_parms[unit]->remote_addr) free(ppp_parms[unit]->remote_addr); if (ppp_parms[unit]->filename) free(ppp_parms[unit]->filename); free((char *)ppp_parms[unit]); if (ppp_if[unit]->options->pap_file) free(ppp_if[unit]->options->pap_file); if (ppp_if[unit]->options->chap_file) free(ppp_if[unit]->options->chap_file); if ((char *)ppp_if[unit]) free((char *)ppp_if[unit]); ppp_if[unit] = NULL;} /* * ppp_timeout - Schedule a timeout. * * Note that this timeout takes the number of seconds, NOT hz (as in * the kernel). */voidppp_timeout(func, arg, seconds) void (*func)(); caddr_t arg; int seconds;{ struct itimerspec itv; struct callout *newp, **oldpp; MAINDEBUG((LOG_DEBUG, "Timeout %x:%x in %d seconds.", (int) func, (int) arg, seconds)); /* * Allocate timeout. */ if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) { syslog(LOG_ERR, "Out of memory in timeout()!"); die(ppp_unit, 1); } newp->c_arg = arg; newp->c_func = func; /* * Find correct place to link it in and decrement its time by the * amount of time used by preceding timeouts. */ for (oldpp = &(ppp_if[ppp_unit]->callout); *oldpp && (*oldpp)->c_time <= seconds; oldpp = &(*oldpp)->c_next) seconds -= (*oldpp)->c_time; newp->c_time = seconds; newp->c_next = *oldpp; if (*oldpp) (*oldpp)->c_time -= seconds; *oldpp = newp; /* * If this is now the first callout then we have to set a new * itimer. */ if (ppp_if[ppp_unit]->callout == newp) { itv.it_interval.tv_sec = itv.it_interval.tv_nsec = itv.it_value.tv_nsec = 0; itv.it_value.tv_sec = ppp_if[ppp_unit]->callout->c_time; MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in timeout.", itv.it_value.tv_sec)); if (timer_settime(ppp_if[ppp_unit]->timer_id, CLOCK_REALTIME, &itv, NULL) < 0) { syslog(LOG_ERR, "setitimer(ITIMER_REAL): error"); die(ppp_unit, 1); } if (time(&(ppp_if[ppp_unit]->schedtime)) == ERROR) { syslog(LOG_ERR, "gettimeofday: error"); die(ppp_unit, 1); } }} /* * ppp_untimeout - Unschedule a timeout. */voidppp_untimeout(func, arg) void (*func)(); caddr_t arg;{ struct itimerspec itv; struct callout **copp, *freep; int reschedule = 0; MAINDEBUG((LOG_DEBUG, "Untimeout %x:%x.", (int) func, (int) arg)); /* * If the first callout is unscheduled then we have to set a new * itimer. */ if (ppp_if[ppp_unit]->callout && ppp_if[ppp_unit]->callout->c_func == func && ppp_if[ppp_unit]->callout->c_arg == arg) reschedule = 1; /* * Find first matching timeout. Add its time to the next timeouts * time. */ for (copp = &(ppp_if[ppp_unit]->callout); *copp; copp = &(*copp)->c_next) if ((*copp)->c_func == func && (*copp)->c_arg == arg) { freep = *copp; *copp = freep->c_next; if (*copp) (*copp)->c_time += freep->c_time; (void) free((char *) freep); break; } if (reschedule) { itv.it_interval.tv_sec = itv.it_interval.tv_nsec = itv.it_value.tv_nsec = 0; itv.it_value.tv_sec = ppp_if[ppp_unit]->callout ? ppp_if[ppp_unit]->callout->c_time : 0; MAINDEBUG((LOG_DEBUG, "untimeout: Setting itimer for %d seconds in untimeout.", itv.it_value.tv_sec)); if (timer_settime(ppp_if[ppp_unit]->timer_id, CLOCK_REALTIME, &itv, NULL) < 0) { syslog(LOG_ERR, "setitimer(ITIMER_REAL): error"); die(ppp_unit, 1); } if (time(&(ppp_if[ppp_unit]->schedtime)) == ERROR) { syslog(LOG_ERR, "gettimeofday: error"); die(ppp_unit, 1); } }}/* * adjtimeout - Decrement the first timeout by the amount of time since * it was scheduled. */voidadjtimeout(){ time_t tv; int timediff; if (ppp_if[ppp_unit]->callout == NULL) return; /* * Make sure that the clock hasn't been warped dramatically. * Account for recently expired, but blocked timer by adding * small fudge factor. */ if (time(&tv) == ERROR) { syslog(LOG_ERR, "gettimeofday: error"); die(ppp_unit, 1); } timediff = tv - ppp_if[ppp_unit]->schedtime; if (timediff < 0 || timediff >= ppp_if[ppp_unit]->callout->c_time) return; ppp_if[ppp_unit]->callout->c_time -= timediff; /* OK, Adjust time */} /* * hup - Catch SIGHUP signal. * * Indicates that the physical layer has been disconnected. */static voidhup(sig) int sig;{ MAINDEBUG((LOG_INFO, "Hangup (SIGHUP)")); ppp_if[ppp_unit]->hungup = 1; /* they hung up on us! */ adjtimeout(); /* Adjust timeouts */ die(ppp_unit, 1); /* Close connection */}/* * term - Catch SIGTERM signal. * * Indicates that we should initiate a graceful disconnect and exit. */static voidterm(sig) int sig;{ fsm *f = &ppp_if[ppp_unit]->lcp_fsm; /* even if OPT_SILENT | OPT_PASSIVE, force die(..) to delete */ f->flags = 0; MAINDEBUG((LOG_INFO, "Terminating link.")); adjtimeout(); /* Adjust timeouts */ die(ppp_unit, 1); /* Close connection */}/* * intr - Catch SIGINT signal (DEL/^C). * * Indicates that we should initiate a graceful disconnect and exit. */static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -