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

📄 sys-linux.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 5 页
字号:
	set_kdebugflag (kdebugflag);    looped = 0;    return ppp_fd; err_close:    close(fd); err:    return -1;}/******************************************************************** * * tty_disestablish_ppp - Restore the serial port to normal operation. * This shouldn't call die() because it's called from die(). */void tty_disestablish_ppp(int tty_fd){    if (!hungup) {/* * Flush the tty output buffer so that the TIOCSETD doesn't hang. */	if (tcflush(tty_fd, TCIOFLUSH) < 0)	{	    warn("tcflush failed: %m");	    goto flushfailed;	}/* * Restore the previous line discipline */	if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {	    if ( ! ok_error (errno))		error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);	}	if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {	    if ( ! ok_error (errno))		warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);	}	/* Reset non-blocking mode on fd. */	if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {	    if ( ! ok_error (errno))		warn("Couldn't restore device fd flags: %m");	}    }flushfailed:    initfdflags = -1;    generic_disestablish_ppp(tty_fd);}/******************************************************************** * * generic_disestablish_ppp - Restore device components to normal * operation, and reconnect the ppp unit to the loopback if in demand * mode.  This shouldn't call die() because it's called from die(). */void generic_disestablish_ppp(int dev_fd){    if (new_style_driver) {	close(ppp_fd);	ppp_fd = -1;	if (demand) {	    modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);	    looped = 1;	} else if (!doing_multilink && ppp_dev_fd >= 0) {	    close(ppp_dev_fd);	    remove_fd(ppp_dev_fd);	    ppp_dev_fd = -1;	}    } else {	/* old-style driver */	if (demand)	    set_ppp_fd(slave_fd);	else	    ppp_dev_fd = -1;    }}/* * make_ppp_unit - make a new ppp unit for ppp_dev_fd. * Assumes new_style_driver. */static int make_ppp_unit(){	int x, flags;	if (ppp_dev_fd >= 0) {		dbglog("in make_ppp_unit, already had /dev/ppp open?");		close(ppp_dev_fd);	}	ppp_dev_fd = open("/dev/ppp", O_RDWR);	if (ppp_dev_fd < 0)		fatal("Couldn't open /dev/ppp: %m");	flags = fcntl(ppp_dev_fd, F_GETFL);	if (flags == -1	    || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)		warn("Couldn't set /dev/ppp to nonblock: %m");	ifunit = req_unit;	x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);	if (x < 0 && req_unit >= 0 && errno == EEXIST) {		warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);		ifunit = -1;		x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);	}	if (x < 0)		error("Couldn't create new ppp unit: %m");	return x;}/* * cfg_bundle - configure the existing bundle. * Used in demand mode. */void cfg_bundle(int mrru, int mtru, int rssn, int tssn){	if (!new_style_driver)		return;	/* set the mrru, mtu and flags */	if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)		error("Couldn't set MRRU: %m");	modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,		     ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)		      | (mrru? SC_MULTILINK: 0)));	/* connect up the channel */	if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)		fatal("Couldn't attach to PPP unit %d: %m", ifunit);	add_fd(ppp_dev_fd);}/* * make_new_bundle - create a new PPP unit (i.e. a bundle) * and connect our channel to it.  This should only get called * if `multilink' was set at the time establish_ppp was called. * In demand mode this uses our existing bundle instead of making * a new one. */void make_new_bundle(int mrru, int mtru, int rssn, int tssn){	if (!new_style_driver)		return;	/* make us a ppp unit */	if (make_ppp_unit() < 0)		die(1);	/* set the mrru and flags */	cfg_bundle(mrru, mtru, rssn, tssn);}/* * bundle_attach - attach our link to a given PPP unit. * We assume the unit is controlled by another pppd. */int bundle_attach(int ifnum){	int master_fd;	if (!new_style_driver)		return -1;	master_fd = open("/dev/ppp", O_RDWR);	if (master_fd < 0)		fatal("Couldn't open /dev/ppp: %m");	if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {		if (errno == ENXIO) {			close(master_fd);			return 0;	/* doesn't still exist */		}		fatal("Couldn't attach to interface unit %d: %m\n", ifnum);	}	if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)		fatal("Couldn't connect to interface unit %d: %m", ifnum);	modify_flags(master_fd, 0, SC_MULTILINK);	close(master_fd);	ifunit = ifnum;	return 1;}/* * destroy_bundle - tell the driver to destroy our bundle. */void destroy_bundle(void){	if (ppp_dev_fd >= 0) {		close(ppp_dev_fd);		remove_fd(ppp_dev_fd);		ppp_dev_fd = -1;	}}/******************************************************************** * * 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 B76800    { 76800, B76800 },#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#ifdef B921600    { 921600, B921600 },#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 (line %d)", __LINE__);	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);    }    while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))	if (errno != EINTR)	    fatal("tcsetattr: %m (line %d)", __LINE__);    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 (line %d)", __LINE__);	}    }}/******************************************************************** * * output - Output PPP packet. */void output (int unit, unsigned char *p, int len){    int fd = ppp_fd;    int proto;    dump_packet("sent", p, len);    if (snoop_send_hook) snoop_send_hook(p, len);    if (len < PPP_HDRLEN)	return;    if (new_style_driver) {	p += 2;	len -= 2;	proto = (p[0] << 8) + p[1];	if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))	    fd = ppp_dev_fd;    }    if (write(fd, p, len) < 0) {	if (errno == EWOULDBLOCK || errno == EAGAIN || 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, exc;    int n;    ready = in_fds;    exc = in_fds;    n = select(max_in_fd + 1, &ready, NULL, &exc, timo);    if (n < 0 && errno != EINTR)	fatal("select: %m");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -