📄 sys-solaris.c
字号:
/* * get_ppp_stats - return statistics for the link. */intget_ppp_stats(u, stats) int u; struct pppd_stats *stats;{ struct ppp_stats s; if (!sync_serial && 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; stats->pkts_in = s.p.ppp_ipackets; stats->pkts_out = s.p.ppp_opackets; 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; } 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) u_int32_t ipaddr; struct sockaddr *hwaddr;{ struct ifreq *ifr, *ifend, ifreq; int nif; struct ifconf ifc; u_int32_t ina, mask; /* * Scan through the system's network interfaces. */#ifdef SIOCGIFNUM if (ioctl(ipfd, SIOCGIFNUM, &nif) < 0)#endif nif = MAX_IFS; ifc.ifc_len = nif * sizeof(struct ifreq); ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len); if (ifc.ifc_buf == 0) return 0; if (ioctl(ipfd, SIOCGIFCONF, &ifc) < 0) { warn("Couldn't get system interface list: %m"); free(ifc.ifc_buf); return 0; } ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); for (ifr = ifc.ifc_req; ifr < ifend; ++ifr) { if (ifr->ifr_addr.sa_family != AF_INET) continue; /* * Check that the interface is up, and not point-to-point or loopback. */ strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); if (ioctl(ipfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) != (IFF_UP|IFF_BROADCAST)) continue; /* * Get its netmask and check that it's on the right subnet. */ if (ioctl(ipfd, SIOCGIFNETMASK, &ifreq) < 0) continue; ina = INET_ADDR(ifr->ifr_addr); mask = INET_ADDR(ifreq.ifr_addr); if ((ipaddr & mask) == (ina & mask)) break; } if (ifr >= ifend) { warn("No suitable interface found for proxy ARP"); free(ifc.ifc_buf); return 0; } info("found interface %s for proxy ARP", ifr->ifr_name); if (!get_hw_addr(ifr->ifr_name, ina, hwaddr)) { error("Couldn't get hardware address for %s", ifr->ifr_name); free(ifc.ifc_buf); return 0; } free(ifc.ifc_buf); return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -