📄 sys-svr4.c
字号:
int unit, mtu; u_int32_t asyncmap; int pcomp, accomp;{ int cf[2]; struct ifreq ifr;#if defined(INET6) && defined(SOL2) struct lifreq lifr; int fd;#endif /* defined(INET6) && defined(SOL2) */ 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 (fdmuxid >= 0) { /* can't set these if we don't have a stream attached below /dev/ppp */ 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 the 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(ipfd, SIOCSIFMTU, &ifr) < 0) { error("Couldn't set IP MTU: %m"); }#if defined(INET6) && defined(SOL2) fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) error("Couldn't open IPv6 socket: %m"); memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); lifr.lifr_mtu = link_mtu; if (ioctl(fd, SIOCSLIFMTU, &lifr) < 0) { close(fd); error("Couldn't set IPv6 MTU: %m"); } close(fd);#endif /* defined(INET6) && defined(SOL2) */}/* * ppp_set_xaccm - set the extended transmit ACCM for the interface. */voidppp_set_xaccm(unit, accm) int unit; ext_accm accm;{ if (fdmuxid >= 0 && 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 (fdmuxid >= 0) { /* can't set these if we don't have a stream attached below /dev/ppp */ 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;}#if 0/* * 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 (strioctl(pppfd, PPPIO_PASSFILT, pass, sizeof(struct bpf_program), 0) < 0) { error("Couldn't set pass-filter in kernel: %m"); ret = 0; } } if (active->bf_len > 0) { if (strioctl(pppfd, PPPIO_ACTIVEFILT, active, sizeof(struct bpf_program), 0) < 0) { error("Couldn't set active-filter in kernel: %m"); ret = 0; } } return ret;}#endif/* * 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(ipfd, SIOCGIFFLAGS, &ifr) < 0) { error("Couldn't mark interface up (get): %m"); return 0; } ifr.ifr_flags |= IFF_UP; if (ioctl(ipfd, 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; if (ipmuxid < 0) return 1; strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) { error("Couldn't mark interface down (get): %m"); return 0; } ifr.ifr_flags &= ~IFF_UP; if (ioctl(ipfd, 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;}#if defined(SOL2) && defined(INET6)/* * sif6up - Config the IPv6 interface up and enable IPv6 packets to pass. */intsif6up(u) int u;{ struct lifreq lifr; int fd; fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) { return 0; } memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) { close(fd); return 0; } lifr.lifr_flags |= IFF_UP; strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); if (ioctl(fd, SIOCSLIFFLAGS, &lifr) < 0) { close(fd); return 0; } if6_is_up = 1; close(fd); return 1;}/* * sifdown - Config the IPv6 interface down and disable IPv6. */intsif6down(u) int u;{ struct lifreq lifr; int fd; fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) return 0; memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) { close(fd); return 0; } lifr.lifr_flags &= ~IFF_UP; strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) { close(fd); return 0; } if6_is_up = 0; close(fd); return 1;}/* * sif6addr - Config the interface with an IPv6 link-local address */intsif6addr(u, o, h) int u; eui64_t o, h;{ struct lifreq lifr; struct sockaddr_storage laddr; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&laddr; int fd; fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) return 0; memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); /* * Do this because /dev/ppp responds to DL_PHYS_ADDR_REQ with * zero values, hence the interface token came to be zero too, * and without this, in.ndpd will complain */ IN6_LLTOKEN_FROM_EUI64(lifr, sin6, o); if (ioctl(fd, SIOCSLIFTOKEN, &lifr) < 0) { close(fd); return 0; } /* * Set the interface address and destination address */ IN6_LLADDR_FROM_EUI64(lifr, sin6, o); if (ioctl(fd, SIOCSLIFADDR, &lifr) < 0) { close(fd); return 0; } memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); IN6_LLADDR_FROM_EUI64(lifr, sin6, h); if (ioctl(fd, SIOCSLIFDSTADDR, &lifr) < 0) { close(fd); return 0; } return 1;}/* * cif6addr - Remove the IPv6 address from interface */intcif6addr(u, o, h) int u; eui64_t o, h;{ return 1;}#endif /* defined(SOL2) && defined(INET6) */#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; int ret = 1; 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(ipfd, SIOCSIFNETMASK, &ifr) < 0) { error("Couldn't set IP netmask: %m"); ret = 0; } ifr.ifr_addr.sa_family = AF_INET; INET_ADDR(ifr.ifr_addr) = o; if (ioctl(ipfd, SIOCSIFADDR, &ifr) < 0) { error("Couldn't set local IP address: %m"); ret = 0; } /* * On some systems, we have to explicitly set the point-to-point * flag bit before we can set a destination address. */ if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) >= 0 && (ifr.ifr_flags & IFF_POINTOPOINT) == 0) { ifr.ifr_flags |= IFF_POINTOPOINT; if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) { error("Couldn't mark interface pt-to-pt: %m"); ret = 0; } } ifr.ifr_dstaddr.sa_family = AF_INET; INET_ADDR(ifr.ifr_dstaddr) = h; if (ioctl(ipfd, SIOCSIFDSTADDR, &ifr) < 0) { error("Couldn't set remote IP address: %m"); ret = 0; }#if 0 /* now done in ppp_send_config */ ifr.ifr_metric = link_mtu; if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) { error("Couldn't set IP MTU: %m"); }#endif remote_addr = h; return ret;}/* * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. */intcifaddr(u, o, h) int u; u_int32_t o, h;{#if defined(__USLC__) /* was: #if 0 */ cifroute(unit, ouraddr, hisaddr); if (ipmuxid >= 0) { notice("Removing ppp interface unit"); if (ioctl(ipfd, I_UNLINK, ipmuxid) < 0) { error("Can't remove ppp interface unit: %m"); return 0; } ipmuxid = -1; }#endif remote_addr = 0; return 1;}/* * sifdefaultroute - assign a default route through the address given. */intsifdefaultroute(u, l, g) int u; u_int32_t l, g;{ struct rtentry rt;#if defined(__USLC__) g = l; /* use the local address as gateway */#endif memset(&rt, 0, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; INET_ADDR(rt.rt_dst) = 0; rt.rt_gateway.sa_family = AF_INET; INET_ADDR(rt.rt_gateway) = g; rt.rt_flags = RTF_GATEWAY; if (ioctl(ipfd, SIOCADDRT, &rt) < 0) { error("Can't add default route: %m"); return 0; } default_route_gateway = g; return 1;}/* * cifdefaultroute - delete a default route through the address given. */intcifdefaultroute(u, l, g) int u; u_int32_t l, g;{ struct rtentry rt;#if defined(__USLC__) g = l; /* use the local address as gateway */#endif memset(&rt, 0, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; INET_ADDR(rt.rt_dst) = 0; rt.rt_gateway.sa_family = AF_INET; INET_ADDR(rt.rt_gateway) = g; rt.rt_flags = RTF_GATEWAY; if (ioctl(ipfd, SIOCDELRT, &rt) < 0) { error("Can't delete default route: %m"); return 0; } default_route_gateway = 0; return 1;}/* * sifproxyarp - Make a proxy ARP entry for the peer. */intsifproxyarp(unit, hisaddr) int unit; u_int32_t hisaddr;{ struct arpreq arpreq; memset(&arpreq, 0, sizeof(arpreq)); if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) return 0; arpreq.arp_pa.sa_family = AF_INET; INET_ADDR(arpreq.arp_pa) = hisaddr; arpreq.arp_flags = ATF_PERM | ATF_PUBL; if (ioctl(ipfd, SIOCSARP, (caddr_t) &arpreq) < 0) { error("Couldn't set proxy ARP entry: %m"); return 0; } proxy_arp_addr = hisaddr; return 1;}/* * cifproxyarp - Delete the proxy ARP entry for the peer. */intcifproxyarp(unit, hisaddr) int unit; u_int32_t hisaddr;{ struct arpreq arpreq; memset(&arpreq, 0, sizeof(arpreq)); arpreq.arp_pa.sa_family = AF_INET; INET_ADDR(arpreq.arp_pa) = hisaddr; if (ioctl(ipfd, SIOCDARP, (caddr_t)&arpreq) < 0) { error("Couldn't delete proxy ARP entry: %m"); return 0; } proxy_arp_addr = 0; return 1;}/* * get_ether_addr - get the hardware address of an interface on the * the same subnet as ipaddr. */#define MAX_IFS 32static intget_ether_addr(ipaddr, hwaddr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -