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

📄 sys-svr4.c

📁 unix and linux net driver
💻 C
📖 第 1 页 / 共 4 页
字号:
{    close(ipfd);#if defined(INET6) && defined(SOL2)    close(ip6fd);#endif /* defined(INET6) && defined(SOL2) */    if (pppfd >= 0)	close(pppfd);}/* * sys_check_options - check the options that the user specified */intsys_check_options(){    return 1;}#if 0/* * daemon - Detach us from controlling terminal session. */intdaemon(nochdir, noclose)    int nochdir, noclose;{    int pid;    if ((pid = fork()) < 0)	return -1;    if (pid != 0)	exit(0);		/* parent dies */    setsid();    if (!nochdir)	chdir("/");    if (!noclose) {	fclose(stdin);		/* don't need stdin, stdout, stderr */	fclose(stdout);	fclose(stderr);    }    return 0;}#endif/* * ppp_available - check whether the system has any ppp interfaces */intppp_available(){    struct stat buf;    return stat(PPP_DEV_NAME, &buf) >= 0;}/* * establish_ppp - Turn the serial port into a ppp interface. */intestablish_ppp(fd)    int fd;{    int i;    /* Pop any existing modules off the tty stream. */    for (i = 0;; ++i)	if (ioctl(fd, I_LOOK, tty_modules[i]) < 0	    || strcmp(tty_modules[i], "ptem") == 0	    || ioctl(fd, I_POP, 0) < 0)	    break;    tty_nmodules = i;    /* Push the async hdlc module and the compressor module. */    tty_npushed = 0;    if(!sync_serial) {        if (ioctl(fd, I_PUSH, AHDLC_MOD_NAME) < 0) {            error("Couldn't push PPP Async HDLC module: %m");	    return -1;        }        ++tty_npushed;    }    if (kdebugflag & 4) {	i = PPPDBG_LOG + PPPDBG_AHDLC;	strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0);    }    if (ioctl(fd, I_PUSH, COMP_MOD_NAME) < 0)	error("Couldn't push PPP compression module: %m");    else	++tty_npushed;    if (kdebugflag & 2) {	i = PPPDBG_LOG + PPPDBG_COMP;	strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0);    }    /* Link the serial port under the PPP multiplexor. */    if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0) {	error("Can't link tty to PPP mux: %m");	return -1;    }    return pppfd;}/* * restore_loop - reattach the ppp unit to the loopback. * This doesn't need to do anything because disestablish_ppp does it. */voidrestore_loop(){}/* * disestablish_ppp - Restore the serial port to normal operation. * It attempts to reconstruct the stream with the previously popped * modules.  This shouldn't call die() because it's called from die(). */voiddisestablish_ppp(fd)    int fd;{    int i;    if (fdmuxid >= 0) {	if (ioctl(pppfd, I_UNLINK, fdmuxid) < 0) {	    if (!hungup)		error("Can't unlink tty from PPP mux: %m");	}	fdmuxid = -1;	if (!hungup) {	    while (tty_npushed > 0 && ioctl(fd, I_POP, 0) >= 0)		--tty_npushed;	    for (i = tty_nmodules - 1; i >= 0; --i)		if (ioctl(fd, I_PUSH, tty_modules[i]) < 0)		    error("Couldn't restore tty module %s: %m",			   tty_modules[i]);	}	if (hungup && default_device && tty_sid > 0) {	    /*	     * If we have received a hangup, we need to send a SIGHUP	     * to the terminal's controlling process.  The reason is	     * that the original stream head for the terminal hasn't	     * seen the M_HANGUP message (it went up through the ppp	     * driver to the stream head for our fd to /dev/ppp).	     */	    kill(tty_sid, SIGHUP);	}    }}/* * Check whether the link seems not to be 8-bit clean. */voidclean_check(){    int x;    char *s;    if (strioctl(pppfd, PPPIO_GCLEAN, &x, 0, sizeof(x)) < 0)	return;    s = NULL;    switch (~x) {    case RCV_B7_0:	s = "bit 7 set to 1";	break;    case RCV_B7_1:	s = "bit 7 set to 0";	break;    case RCV_EVNP:	s = "odd parity";	break;    case RCV_ODDP:	s = "even parity";	break;    }    if (s != NULL) {	warn("Serial link is not 8-bit clean:");	warn("All received characters had %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 EXTA    { 19200, EXTA },#endif#ifdef EXTB    { 38400, EXTB },#endif#ifdef B57600    { 57600, B57600 },#endif#ifdef B76800    { 76800, B76800 },#endif#ifdef B115200    { 115200, B115200 },#endif#ifdef B153600    { 153600, B153600 },#endif#ifdef B230400    { 230400, B230400 },#endif#ifdef B307200    { 307200, B307200 },#endif#ifdef B460800    { 460800, B460800 },#endif    { 0, 0 }};/* * Translate from bits/second to a speed_t. */static inttranslate_speed(bps)    int bps;{    struct speed *speedp;    if (bps == 0)	return 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 intbaud_rate_of(speed)    int speed;{    struct speed *speedp;    if (speed == 0)	return 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. */voidset_up_tty(fd, local)    int fd, local;{    int speed;    struct termios tios;#if !defined (CRTSCTS)    struct termiox tiox;#endif    if (!sync_serial && tcgetattr(fd, &tios) < 0)	fatal("tcgetattr: %m");#ifndef CRTSCTS    termiox_ok = 1;    if (ioctl (fd, TCGETX, &tiox) < 0) {	termiox_ok = 0;	if (errno != ENOTTY)	    error("TCGETX: %m");    }#endif    if (!restore_term) {	inittermios = tios;#ifndef CRTSCTS	inittermiox = tiox;#endif	ioctl(fd, TIOCGWINSZ, &wsinfo);    }    tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);#ifdef CRTSCTS    if (crtscts > 0)	tios.c_cflag |= CRTSCTS;    else if (crtscts < 0)	tios.c_cflag &= ~CRTSCTS;#else    if (crtscts != 0 && !termiox_ok) {	error("Can't set RTS/CTS flow control");    } else if (crtscts > 0) {	tiox.x_hflag |= RTSXOFF|CTSXON;    } else if (crtscts < 0) {	tiox.x_hflag &= ~(RTSXOFF|CTSXON);    }#endif    tios.c_cflag |= CS8 | CREAD | HUPCL;    if (local || !modem)	tios.c_cflag |= CLOCAL;    tios.c_iflag = IGNBRK | IGNPAR;    tios.c_oflag = 0;    tios.c_lflag = 0;    tios.c_cc[VMIN] = 1;    tios.c_cc[VTIME] = 0;    if (crtscts == -2) {	tios.c_iflag |= IXON | IXOFF;	tios.c_cc[VSTOP] = 0x13;	/* DC3 = XOFF = ^S */	tios.c_cc[VSTART] = 0x11;	/* DC1 = XON  = ^Q */    }    speed = translate_speed(inspeed);    if (speed) {	cfsetospeed(&tios, speed);	cfsetispeed(&tios, speed);    } else {	speed = cfgetospeed(&tios);	/*	 * We can't proceed if the serial port speed is 0,	 * since that implies that the serial port is disabled.	 */	if (speed == B0)	    fatal("Baud rate for %s is 0; need explicit baud rate", devnam);    }    if (!sync_serial && tcsetattr(fd, TCSAFLUSH, &tios) < 0)	fatal("tcsetattr: %m");#ifndef CRTSCTS    if (termiox_ok && ioctl (fd, TCSETXF, &tiox) < 0){	error("TCSETXF: %m");    }#endif    baud_rate = inspeed = baud_rate_of(speed);    restore_term = 1;}/* * restore_tty - restore the terminal to the saved settings. */voidrestore_tty(fd)    int fd;{    if (restore_term) {	if (!default_device) {	    /*	     * 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.	     */	    inittermios.c_lflag &= ~(ECHO | ECHONL);	}	if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)	    if (!hungup && errno != ENXIO)		warn("tcsetattr: %m");#ifndef CRTSCTS	if (ioctl (fd, TCSETXF, &inittermiox) < 0){	    if (!hungup && errno != ENXIO)		error("TCSETXF: %m");	}#endif	ioctl(fd, TIOCSWINSZ, &wsinfo);	restore_term = 0;    }}/* * setdtr - control the DTR line on the serial port. * This is called from die(), so it shouldn't call die(). */voidsetdtr(fd, on)int fd, on;{    int modembits = TIOCM_DTR;    ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);}/* * open_loopback - open the device we use for getting packets * in demand mode.  Under Solaris 2, we use our existing fd * to the ppp driver. */intopen_ppp_loopback(){    return pppfd;}/* * output - Output PPP packet. */voidoutput(unit, p, len)    int unit;    u_char *p;    int len;{    struct strbuf data;    int retries;    struct pollfd pfd;    if (debug)	dbglog("sent %P", p, len);    data.len = len;    data.buf = (caddr_t) p;    retries = 4;    while (putmsg(pppfd, NULL, &data, 0) < 0) {	if (--retries < 0 || (errno != EWOULDBLOCK && errno != EAGAIN)) {	    if (errno != ENXIO)		error("Couldn't send packet: %m");	    break;	}	pfd.fd = pppfd;	pfd.events = POLLOUT;	poll(&pfd, 1, 250);	/* wait for up to 0.25 seconds */    }}/* * wait_input - wait until there is data available, * for the length of time specified by *timo (indefinite * if timo is NULL). */voidwait_input(timo)    struct timeval *timo;{    int t;    t = timo == NULL? -1: timo->tv_sec * 1000 + timo->tv_usec / 1000;    if (poll(pollfds, n_pollfds, t) < 0 && errno != EINTR)	fatal("poll: %m");}/* * add_fd - add an fd to the set that wait_input waits for. */void add_fd(fd)    int fd;{    int n;    for (n = 0; n < n_pollfds; ++n)	if (pollfds[n].fd == fd)	    return;    if (n_pollfds < MAX_POLLFDS) {	pollfds[n_pollfds].fd = fd;	pollfds[n_pollfds].events = POLLIN | POLLPRI | POLLHUP;	++n_pollfds;    } else	error("Too many inputs!");}/* * remove_fd - remove an fd from the set that wait_input waits for. */void remove_fd(fd)    int fd;{    int n;    for (n = 0; n < n_pollfds; ++n) {	if (pollfds[n].fd == fd) {	    while (++n < n_pollfds)		pollfds[n-1] = pollfds[n];	    --n_pollfds;	    break;	}    }}#if 0/* * wait_loop_output - wait until there is data available on the * loopback, for the length of time specified by *timo (indefinite * if timo is NULL). */voidwait_loop_output(timo)    struct timeval *timo;{    wait_input(timo);}/* * wait_time - wait for a given length of time or until a * signal is received. */voidwait_time(timo)    struct timeval *timo;{    int n;    n = select(0, NULL, NULL, NULL, timo);    if (n < 0 && errno != EINTR)	fatal("select: %m");}#endif/* * read_packet - get a PPP packet from the serial device. */intread_packet(buf)    u_char *buf;{    struct strbuf ctrl, data;    int flags, len;    unsigned char ctrlbuf[sizeof(union DL_primitives) + 64];    for (;;) {	data.maxlen = PPP_MRU + PPP_HDRLEN;	data.buf = (caddr_t) buf;	ctrl.maxlen = sizeof(ctrlbuf);	ctrl.buf = (caddr_t) ctrlbuf;	flags = 0;	len = getmsg(pppfd, &ctrl, &data, &flags);	if (len < 0) {	    if (errno == EAGAIN || errno == EINTR)		return -1;	    fatal("Error reading packet: %m");	}	if (ctrl.len <= 0)	    return data.len;	/*	 * Got a M_PROTO or M_PCPROTO message.  Interpret it	 * as a DLPI primitive??	 */	if (debug)	    dbglog("got dlpi prim 0x%x, len=%d",		   ((union DL_primitives *)ctrlbuf)->dl_primitive, ctrl.len);    }}/* * 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(){    int len;    int rv = 0;    while ((len = read_packet(inpacket_buf)) > 0) {	if (loop_frame(inpacket_buf, len))	    rv = 1;    }    return rv;}/* * ppp_send_config - configure the transmit characteristics of * the ppp interface. */voidppp_send_config(unit, mtu, asyncmap, pcomp, accomp)

⌨️ 快捷键说明

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