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

📄 sys-bsd.c

📁 unix and linux net driver
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (tcgetattr(loop_slave, &tios) == 0) {	tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);	tios.c_cflag |= CS8 | CREAD;	tios.c_iflag = IGNPAR;	tios.c_oflag = 0;	tios.c_lflag = 0;	if (tcsetattr(loop_slave, TCSAFLUSH, &tios) < 0)	    warn("couldn't set attributes on loopback: %m");    }    if ((flags = fcntl(loop_master, F_GETFL)) != -1) 	if (fcntl(loop_master, F_SETFL, flags | O_NONBLOCK) == -1)	    warn("couldn't set loopback to nonblock: %m");    ppp_fd = loop_slave;    if (ioctl(ppp_fd, TIOCSETD, &pppdisc) < 0)	fatal("ioctl(TIOCSETD): %m");    /*     * Find out which interface we were given.     */    if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)	fatal("ioctl(PPPIOCGUNIT): %m");    /*     * Enable debug in the driver if requested.     */    if (kdebugflag) {	if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &flags) < 0) {	    warn("ioctl (PPPIOCGFLAGS): %m");	} else {	    flags |= (kdebugflag & 0xFF) * SC_DEBUG;	    if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0)		warn("ioctl(PPPIOCSFLAGS): %m");	}    }    return loop_master;}/* * output - Output PPP packet. */voidoutput(unit, p, len)    int unit;    u_char *p;    int len;{    if (debug)	dbglog("sent %P", p, len);    if (write(ttyfd, p, len) < 0) {	if (errno != EIO)	    error("write: %m");    }}/* * 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;{    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");}/* * add_fd - add an fd to the set that wait_input waits for. */void add_fd(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(fd)    int fd;{    FD_CLR(fd, &in_fds);}#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;{    fd_set ready;    int n;    FD_ZERO(&ready);    FD_SET(loop_master, &ready);    n = select(loop_master + 1, &ready, NULL, &ready, timo);    if (n < 0 && errno != EINTR)	fatal("select: %m");}/* * 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;{    int len;    if ((len = read(ttyfd, buf, PPP_MTU + PPP_HDRLEN)) < 0) {	if (errno == EWOULDBLOCK || errno == EINTR)	    return -1;	fatal("read: %m");    }    return len;}/* * get_loop_output - read characters from the loopback, form them * into frames, 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 rv = 0;    int n;    while ((n = read(loop_master, 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");    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;{    u_int x;    struct ifreq ifr;    strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));    ifr.ifr_mtu = mtu;    if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0)	fatal("ioctl(SIOCSIFMTU): %m");    if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0)	fatal("ioctl(PPPIOCSASYNCMAP): %m");    if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0)	fatal("ioctl (PPPIOCGFLAGS): %m");    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;    if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)	fatal("ioctl(PPPIOCSFLAGS): %m");}/* * ppp_set_xaccm - set the extended transmit ACCM for the interface. */voidppp_set_xaccm(unit, accm)    int unit;    ext_accm accm;{    if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY)	warn("ioctl(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 x;    if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)	fatal("ioctl(PPPIOCSMRU): %m");    if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0)	fatal("ioctl(PPPIOCSRASYNCMAP): %m");    if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0)	fatal("ioctl (PPPIOCGFLAGS): %m");    x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC;    if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)	fatal("ioctl(PPPIOCSFLAGS): %m");}/* * ccp_test - ask kernel whether a given compression method * is acceptable for use.  Returns 1 if the method and parameters * are OK, 0 if the method is known but the parameters are not OK * (e.g. code size should be reduced), or -1 if the method is unknown. */intccp_test(unit, opt_ptr, opt_len, for_transmit)    int unit, opt_len, for_transmit;    u_char *opt_ptr;{    struct ppp_option_data data;    data.ptr = opt_ptr;    data.length = opt_len;    data.transmit = for_transmit;    if (ioctl(ttyfd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)	return 1;    return (errno == ENOBUFS)? 0: -1;}/* * ccp_flags_set - inform kernel about the current state of CCP. */voidccp_flags_set(unit, isopen, isup)    int unit, isopen, isup;{    int x;    if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {	error("ioctl (PPPIOCGFLAGS): %m");	return;    }    x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN;    x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP;    if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)	error("ioctl(PPPIOCSFLAGS): %m");}/* * 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 x;    if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {	error("ioctl(PPPIOCGFLAGS): %m");	return 0;    }    return x & SC_DC_FERROR;}/* * get_idle_time - return how long the link has been idle. */intget_idle_time(u, ip)    int u;    struct ppp_idle *ip;{    return ioctl(ppp_fd, PPPIOCGIDLE, ip) >= 0;}/* * get_ppp_stats - return statistics for the link. */intget_ppp_stats(u, stats)    int u;    struct pppd_stats *stats;{    struct ifpppstatsreq req;    memset (&req, 0, sizeof (req));    strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name));    if (ioctl(sockfd, SIOCGPPPSTATS, &req) < 0) {	error("Couldn't get PPP statistics: %m");	return 0;    }    stats->bytes_in = req.stats.p.ppp_ibytes;    stats->bytes_out = req.stats.p.ppp_obytes;    return 1;}#ifdef PPP_FILTER/* * set_filters - transfer the pass and active filters to the kernel. */intset_filters(pass, active)    struct bpf_program *pass, *active;{    int ret = 1;    if (pass->bf_len > 0) {	if (ioctl(ppp_fd, PPPIOCSPASS, pass) < 0) {	    error("Couldn't set pass-filter in kernel: %m");	    ret = 0;	}    }    if (active->bf_len > 0) {	if (ioctl(ppp_fd, PPPIOCSACTIVE, active) < 0) {	    error("Couldn't set active-filter in kernel: %m");	    ret = 0;	}    }    return ret;}#endif/* * sifvjcomp - config tcp header compression */intsifvjcomp(u, vjcomp, cidcomp, maxcid)    int u, vjcomp, cidcomp, maxcid;{    u_int x;    if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {	error("ioctl (PPPIOCGFLAGS): %m");	return 0;    }    x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP;    x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID;    if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {	error("ioctl(PPPIOCSFLAGS): %m");	return 0;    }    if (vjcomp && ioctl(ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {	error("ioctl(PPPIOCSFLAGS): %m");	return 0;    }    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, (caddr_t) &ifr) < 0) {	error("ioctl (SIOCGIFFLAGS): %m");	return 0;    }    ifr.ifr_flags |= IFF_UP;    if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {	error("ioctl(SIOCSIFFLAGS): %m");	return 0;    }    if_is_up = 1;    return 1;}/* * sifnpmode - Set the mode for handling packets for a given NP. */intsifnpmode(u, proto, mode)    int u;    int proto;    enum NPmode mode;{    struct npioctl npi;    npi.protocol = proto;    npi.mode = mode;    if (ioctl(ppp_fd, PPPIOCSNPMODE, &npi) < 0) {	error("ioctl(set NP %d mode to %d): %m", proto, mode);	return 0;    }    return 1;}/* * sifdown - Config the interface down and disable IP. */intsifdown(u)    int u;{    struct ifreq ifr;    int rv;    struct npioctl npi;    rv = 1;    npi.protocol = PPP_IP;    npi.mode = NPMODE_ERROR;    ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi);    /* ignore errors, because ppp_fd might have been closed by now. */    strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));    if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {	error("ioctl (SIOCGIFFLAGS): %m");	rv = 0;    } else {	ifr.ifr_flags &= ~IFF_UP;	if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {	    error("ioctl(SIOCSIFFLAGS): %m");	    rv = 0;	} else	    if_is_up = 0;    }    return rv;}/* * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, * if it exists. */#define SET_SA_FAMILY(addr, family)		\    BZERO((char *) &(addr), sizeof(addr));	\    addr.sa_family = (family); 			\    addr.sa_len = sizeof(addr);/* * sifaddr - Config the interface IP addresses and netmask. */intsifaddr(u, o, h, m)    int u;    u_int32_t o, h, m;{    struct ifaliasreq ifra;    struct ifreq ifr;    strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));    SET_SA_FAMILY(ifra.ifra_addr, AF_INET);    ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o;    SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);    ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h;    if (m != 0) {	SET_SA_FAMILY(ifra.ifra_mask, AF_INET);	((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m;    } else	BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));    BZERO(&ifr, sizeof(ifr));    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));    if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifr) < 0) {	if (errno != EADDRNOTAVAIL)	    warn("Couldn't remove interface address: %m");    }    if (ioctl(sockfd, SIOCAIFADDR, (caddr_t) &ifra) < 0) {	if (errno != EEXIST) {	    error("Couldn't set interface address: %m");	    return 0;	}	warn("Couldn't set interface address: Address %I already exists", o);    }    ifaddrs[0] = o;    ifaddrs[1] = h;

⌨️ 快捷键说明

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