⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sys-linux.c

📁 unix and linux net driver
💻 C
📖 第 1 页 / 共 5 页
字号:
 * * 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 + -