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

📄 sys-sunos4.c

📁 经典的ppp程序
💻 C
📖 第 1 页 / 共 3 页
字号:
{    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");	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 SunOS, 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) {	if (errno != EAGAIN)	    fatal("poll: %m");	/* we can get EAGAIN on a heavily loaded system,	 * just wait a short time and try again. */	usleep(50000);    }}/* * 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[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.  Huh?	 */	if (debug)	    dbglog("got ctrl msg len=%d", 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)    int unit, mtu;    u_int32_t asyncmap;    int pcomp, accomp;{    int cf[2];    struct ifreq ifr;    link_mtu = mtu;    if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) {	if (hungup && errno == ENXIO)	    return;	error("Couldn't set MTU: %m");    }    if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {	error("Couldn't set transmit ACCM: %m");    }    cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0);    cf[1] = COMP_PROT | COMP_AC;    if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {	error("Couldn't set prot/AC compression: %m");    }    /* set mtu for ip as well */    memset(&ifr, 0, sizeof(ifr));    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));    ifr.ifr_metric = link_mtu;    if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) {	error("Couldn't set IP MTU: %m");    }}/* * ppp_set_xaccm - set the extended transmit ACCM for the interface. */voidppp_set_xaccm(unit, accm)    int unit;    ext_accm accm;{    if (strioctl(pppfd, PPPIO_XACCM, accm, sizeof(ext_accm), 0) < 0) {	if (!hungup || errno != ENXIO)	    warn("Couldn't set extended ACCM: %m");    }}/* * ppp_recv_config - configure the receive-side characteristics of * the ppp interface. */voidppp_recv_config(unit, mru, asyncmap, pcomp, accomp)    int unit, mru;    u_int32_t asyncmap;    int pcomp, accomp;{    int cf[2];    link_mru = mru;    if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) {	if (hungup && errno == ENXIO)	    return;	error("Couldn't set MRU: %m");    }    if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {	error("Couldn't set receive ACCM: %m");    }    cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0);    cf[1] = DECOMP_PROT | DECOMP_AC;    if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {	error("Couldn't set prot/AC decompression: %m");    }}/* * ccp_test - ask kernel whether a given compression method * is acceptable for use. */intccp_test(unit, opt_ptr, opt_len, for_transmit)    int unit, opt_len, for_transmit;    u_char *opt_ptr;{    if (strioctl(pppfd, (for_transmit? PPPIO_XCOMP: PPPIO_RCOMP),		 opt_ptr, opt_len, 0) >= 0)	return 1;    return (errno == ENOSR)? 0: -1;}/* * ccp_flags_set - inform kernel about the current state of CCP. */voidccp_flags_set(unit, isopen, isup)    int unit, isopen, isup;{    int cf[2];    cf[0] = (isopen? CCP_ISOPEN: 0) + (isup? CCP_ISUP: 0);    cf[1] = CCP_ISOPEN | CCP_ISUP | CCP_ERROR | CCP_FATALERROR;    if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {	if (!hungup || errno != ENXIO)	    error("Couldn't set kernel CCP state: %m");    }}/* * get_idle_time - return how long the link has been idle. */intget_idle_time(u, ip)    int u;    struct ppp_idle *ip;{    return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0;}/* * get_ppp_stats - return statistics for the link. */intget_ppp_stats(u, stats)    int u;    struct pppd_stats *stats;{    struct ppp_stats s;    if (strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) {	error("Couldn't get link statistics: %m");	return 0;    }    stats->bytes_in = s.p.ppp_ibytes;    stats->bytes_out = s.p.ppp_obytes;    return 1;}/* * ccp_fatal_error - returns 1 if decompression was disabled as a * result of an error detected after decompression of a packet, * 0 otherwise.  This is necessary because of patent nonsense. */intccp_fatal_error(unit)    int unit;{    int cf[2];    cf[0] = cf[1] = 0;    if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {	if (errno != ENXIO && errno != EINVAL)	    error("Couldn't get compression flags: %m");	return 0;    }    return cf[0] & CCP_FATALERROR;}/* * sifvjcomp - config tcp header compression */intsifvjcomp(u, vjcomp, xcidcomp, xmaxcid)    int u, vjcomp, xcidcomp, xmaxcid;{    int cf[2];    char maxcid[2];    if (vjcomp) {	maxcid[0] = xcidcomp;	maxcid[1] = 15;		/* XXX should be rmaxcid */	if (strioctl(pppfd, PPPIO_VJINIT, maxcid, sizeof(maxcid), 0) < 0) {	    error("Couldn't initialize VJ compression: %m");	}    }    cf[0] = (vjcomp? COMP_VJC + DECOMP_VJC: 0)	/* XXX this is wrong */	+ (xcidcomp? COMP_VJCCID + DECOMP_VJCCID: 0);    cf[1] = COMP_VJC + DECOMP_VJC + COMP_VJCCID + DECOMP_VJCCID;    if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {	if (vjcomp)	    error("Couldn't enable VJ compression: %m");    }    return 1;}/* * sifup - Config the interface up and enable IP packets to pass. */intsifup(u)    int u;{    struct ifreq ifr;    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));    if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {	error("Couldn't mark interface up (get): %m");	return 0;    }    ifr.ifr_flags |= IFF_UP;    if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {	error("Couldn't mark interface up (set): %m");	return 0;    }    if_is_up = 1;    return 1;}/* * sifdown - Config the interface down and disable IP. */intsifdown(u)    int u;{    struct ifreq ifr;    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));    if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {	error("Couldn't mark interface down (get): %m");	return 0;    }    if ((ifr.ifr_flags & IFF_UP) != 0) {	ifr.ifr_flags &= ~IFF_UP;	if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {	    error("Couldn't mark interface down (set): %m");	    return 0;	}    }    if_is_up = 0;    return 1;}/* * sifnpmode - Set the mode for handling packets for a given NP. */intsifnpmode(u, proto, mode)    int u;    int proto;    enum NPmode mode;{    int npi[2];    npi[0] = proto;    npi[1] = (int) mode;    if (strioctl(pppfd, PPPIO_NPMODE, npi, 2 * sizeof(int), 0) < 0) {	error("ioctl(set NP %d mode to %d): %m", proto, mode);	return 0;    }    return 1;}#define INET_ADDR(x)	(((struct sockaddr_in *) &(x))->sin_addr.s_addr)/* * sifaddr - Config the interface IP addresses and netmask. */intsifaddr(u, o, h, m)    int u;    u_int32_t o, h, m;{    struct ifreq ifr;    memset(&ifr, 0, sizeof(ifr));    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));    ifr.ifr_addr.sa_family = AF_INET;    INET_ADDR(ifr.ifr_addr) = m;    if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) {	error("Couldn't set IP netmask: %m");    }    ifr.ifr_addr.sa_family = AF_INET;    INET_ADDR(ifr.ifr_addr) = o;    if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {	error("Couldn't set local IP address: %m");    }    ifr.ifr_dstaddr.sa_family = AF_INET;    INET_ADDR(ifr.ifr_dstaddr) = h;    if (ioctl(sockfd, SIOCSIFDSTADDR, &ifr) < 0) {	error("Couldn't set remote IP address: %m");    }#if 0	/* now done in ppp_send_config */    ifr.ifr_metric = link_mtu;    if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) {	error("Couldn't set IP MTU: %m");    }#endif    ifaddrs[0] = o;    ifaddrs[1] = h;    return 1;}/* * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. */

⌨️ 快捷键说明

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