📄 sys-bsd.c
字号:
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 + -