?? sys-linux.c
字號:
* * clean_check - Fetch the flags for the device and generate * appropriate error messages. */void clean_check(void){ int x; char *s; if (still_ppp()) { if (ioctl(ppp_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: s = "all had bit 7 set to 1"; break; case SC_RCV_B7_1: 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) { warn("Receive serial link is not 8-bit clean:"); warn("Problem: %s", s); } } }} /* * List of valid speeds. */struct speed { int speed_int, speed_val;} speeds[] = {#ifdef B50 { 50, B50 },#endif#ifdef B75 { 75, B75 },#endif#ifdef B110 { 110, B110 },#endif#ifdef B134 { 134, B134 },#endif#ifdef B150 { 150, B150 },#endif#ifdef B200 { 200, B200 },#endif#ifdef B300 { 300, B300 },#endif#ifdef B600 { 600, B600 },#endif#ifdef B1200 { 1200, B1200 },#endif#ifdef B1800 { 1800, B1800 },#endif#ifdef B2000 { 2000, B2000 },#endif#ifdef B2400 { 2400, B2400 },#endif#ifdef B3600 { 3600, B3600 },#endif#ifdef B4800 { 4800, B4800 },#endif#ifdef B7200 { 7200, B7200 },#endif#ifdef B9600 { 9600, B9600 },#endif#ifdef B19200 { 19200, B19200 },#endif#ifdef B38400 { 38400, B38400 },#endif#ifdef B57600 { 57600, B57600 },#endif#ifdef B115200 { 115200, B115200 },#endif#ifdef EXTA { 19200, EXTA },#endif#ifdef EXTB { 38400, EXTB },#endif#ifdef B230400 { 230400, B230400 },#endif#ifdef B460800 { 460800, B460800 },#endif { 0, 0 }};/******************************************************************** * * Translate from bits/second to a speed_t. */static int translate_speed (int bps){ struct speed *speedp; if (bps != 0) { for (speedp = speeds; speedp->speed_int; speedp++) { if (bps == speedp->speed_int) return speedp->speed_val; } warn("speed %d not supported", bps); } return 0;}/******************************************************************** * * Translate from a speed_t to bits/second. */static int baud_rate_of (int speed){ struct speed *speedp; if (speed != 0) { for (speedp = speeds; speedp->speed_int; speedp++) { if (speed == speedp->speed_val) return speedp->speed_int; } } return 0;}/******************************************************************** * * 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. */void set_up_tty(int tty_fd, int local){ int speed; struct termios tios; setdtr(tty_fd, 1); if (tcgetattr(tty_fd, &tios) < 0) { if (!ok_error(errno)) fatal("tcgetattr: %m(%d)", errno); return; } if (!restore_term) inittermios = tios; tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); tios.c_cflag |= CS8 | CREAD | HUPCL; tios.c_iflag = IGNBRK | IGNPAR; tios.c_oflag = 0; tios.c_lflag = 0; tios.c_cc[VMIN] = 1; tios.c_cc[VTIME] = 0; if (local || !modem) tios.c_cflag ^= (CLOCAL | HUPCL); switch (crtscts) { case 1: tios.c_cflag |= CRTSCTS; break; case -2: tios.c_iflag |= IXON | IXOFF; tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ break; case -1: tios.c_cflag &= ~CRTSCTS; break; default: break; } speed = translate_speed(inspeed); if (speed) { cfsetospeed (&tios, speed); cfsetispeed (&tios, speed); }/* * We can't proceed if the serial port speed is B0, * since that implies that the serial port is disabled. */ else { speed = cfgetospeed(&tios); if (speed == B0) fatal("Baud rate for %s is 0; need explicit baud rate", devnam); } if (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0) if (!ok_error(errno)) fatal("tcsetattr: %m"); baud_rate = baud_rate_of(speed); restore_term = 1;}/******************************************************************** * * setdtr - control the DTR line on the serial port. * This is called from die(), so it shouldn't call die(). */void setdtr (int tty_fd, int on){ int modembits = TIOCM_DTR; ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);}/******************************************************************** * * restore_tty - restore the terminal to the saved settings. */void restore_tty (int tty_fd){ if (restore_term) { restore_term = 0;/* * Turn off echoing, because otherwise we can get into * a loop with the tty and the modem echoing to each other. * We presume we are the sole user of this tty device, so * when we close it, it will revert to its defaults anyway. */ if (!default_device) inittermios.c_lflag &= ~(ECHO | ECHONL); if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) { if (! ok_error (errno)) warn("tcsetattr: %m"); } }}/******************************************************************** * * output - Output PPP packet. */void output (int unit, unsigned char *p, int len){ if (debug) dbglog("sent %P", p, len); if (len < PPP_HDRLEN) return; if (new_style_driver) { p += 2; len -= 2; } if (write(ppp_dev_fd, p, len) < 0) { if (errno == EWOULDBLOCK || errno == ENOBUFS || errno == ENXIO || errno == EIO || errno == EINTR) warn("write: warning: %m (%d)", errno); else error("write: %m (%d)", errno); }}/******************************************************************** * * wait_input - wait until there is data available, * for the length of time specified by *timo (indefinite * if timo is NULL). */void wait_input(struct timeval *timo){ fd_set ready; int n; ready = in_fds; n = select(max_in_fd + 1, &ready, NULL, &ready, timo); if (n < 0 && errno != EINTR) fatal("select: %m(%d)", errno);}/* * add_fd - add an fd to the set that wait_input waits for. */void add_fd(int fd){ FD_SET(fd, &in_fds); if (fd > max_in_fd) max_in_fd = fd;}/* * remove_fd - remove an fd from the set that wait_input waits for. */void remove_fd(int fd){ FD_CLR(fd, &in_fds);}/******************************************************************** * * read_packet - get a PPP packet from the serial device. */int read_packet (unsigned char *buf){ int len, nr; len = PPP_MRU + PPP_HDRLEN; if (new_style_driver) { *buf++ = PPP_ALLSTATIONS; *buf++ = PPP_UI; len -= 2; } nr = read(ppp_fd, buf, len); if (new_style_driver && nr < 0 && (errno == EWOULDBLOCK || errno == EIO)) nr = read(ppp_dev_fd, buf, len); if (nr < 0) { if (errno == EWOULDBLOCK || errno == EIO) return -1; fatal("read: %m(%d)", errno); } return (new_style_driver && nr > 0)? nr+2: nr;}/******************************************************************** * * get_loop_output - get outgoing packets from the ppp device, * and detect when we want to bring the real link up. * Return value is 1 if we need to bring up the link, 0 otherwise. */intget_loop_output(void){ int rv = 0; int n; if (new_style_driver) { while ((n = read_packet(inpacket_buf)) > 0) if (loop_frame(inpacket_buf, n)) rv = 1; return rv; } while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0) if (loop_chars(inbuf, n)) rv = 1; if (n == 0) fatal("eof on loopback"); if (errno != EWOULDBLOCK) fatal("read from loopback: %m(%d)", errno); return rv;}/******************************************************************** * * ppp_send_config - configure the transmit characteristics of * the ppp interface. */void ppp_send_config (int unit,int mtu,u_int32_t asyncmap,int pcomp,int accomp){ u_int x; struct ifreq ifr; SYSDEBUG ((LOG_DEBUG, "send_config: mtu = %d\n", mtu));/* * Set the MTU and other parameters for the ppp device */ memset (&ifr, '\0', sizeof (ifr)); strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); ifr.ifr_mtu = mtu; if (ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0) fatal("ioctl(SIOCSIFMTU): %m(%d)", errno); if (!still_ppp()) return; SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap)); if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) { if (!ok_error(errno)) fatal("ioctl(PPPIOCSASYNCMAP): %m(%d)", errno); return; } x = get_flags(ppp_fd); x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT; x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC; x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC; set_flags(ppp_fd, x);}/******************************************************************** * * ppp_set_xaccm - set the extended transmit ACCM for the interface. */void ppp_set_xaccm (int unit, ext_accm accm){ SYSDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n", accm[0], accm[1], accm[2], accm[3])); if (!still_ppp()) return; if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) { if ( ! ok_error (errno)) warn("ioctl(set extended ACCM): %m(%d)", errno); }}/******************************************************************** * * ppp_recv_config - configure the receive-side characteristics of * the ppp interface. */void ppp_recv_config (int unit,int mru,u_int32_t asyncmap,int pcomp,int accomp){ SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru));/* * If we were called because the link has gone down then there is nothing * which may be done. Just return without incident. */ if (!still_ppp()) return;/* * Set the receiver parameters */ if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { if ( ! ok_error (errno)) error("ioctl(PPPIOCSMRU): %m(%d)", errno); } if (new_style_driver && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) error("Couldn't set MRU in generic PPP layer: %m"); SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap)); if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) { if (!ok_error(errno)) error("ioctl(PPPIOCSRASYNCMAP): %m(%d)", errno); }}/******************************************************************** * * ccp_test - ask kernel whether a given compression method * is acceptable for use. */int ccp_test (int unit, u_char *opt_ptr, int opt_len, int for_transmit){ struct ppp_option_data data; memset (&data, '\0', sizeof (data)); data.ptr = opt_ptr; data.length = opt_len; data.transmit = for_transmit; if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0) return 1; return (errno == ENOBUFS)? 0: -1;}/******************************************************************** * * ccp_flags_set - inform kernel about the current state of CCP.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -