📄 sys-next.c
字号:
{ int len; if ((len = read(ttyfd, buf, PPP_MTU + PPP_HDRLEN)) < 0) { if (errno == EWOULDBLOCK || errno == EINTR) { SYSDEBUG(("read: %m")); return -1; } fatal("read: %m"); } return len;}/* * 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(ttyfd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) fatal("ioctl(PPPIOCSASYNCMAP): %m"); if (ioctl(ttyfd, 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; if (ioctl(ttyfd, 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(ttyfd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) warn("ioctl(PPPIOCSXASYNCMAP): %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(ttyfd, PPPIOCSMRU, (caddr_t) &mru) < 0) fatal("ioctl(PPPIOCSMRU): %m"); if (ioctl(ttyfd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) fatal("ioctl(PPPIOCSRASYNCMAP): %m"); if (ioctl(ttyfd, PPPIOCGFLAGS, (caddr_t) &x) < 0) fatal("ioctl(PPPIOCGFLAGS): %m"); x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC; if (ioctl(ttyfd, PPPIOCSFLAGS, (caddr_t) &x) < 0) fatal("ioctl(PPPIOCSFLAGS): %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;{ 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(ttyfd, 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(ttyfd, 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(ttyfd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { error("ioctl(PPPIOCGFLAGS): %m"); return 0; } return x & SC_DC_FERROR;}/* * sifvjcomp - config tcp header compression */intsifvjcomp(u, vjcomp, cidcomp, maxcid) int u, vjcomp, cidcomp, maxcid;{ u_int x; if (ioctl(ttyfd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { error("ioctl(PPIOCGFLAGS): %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(ttyfd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { error("ioctl(PPPIOCSFLAGS): %m"); return 0; } if (ioctl(ttyfd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { error("ioctl(PPPIOCSFLAGS): %m"); return 0; } return 1;}/* * sifup - Config the interface up and enable IP packets to pass. */#ifndef SC_ENABLE_IP#define SC_ENABLE_IP 0x100 /* compat for old versions of kernel code */#endifintsifup(u) int u;{ struct ifreq ifr; u_int x; struct npioctl npi; 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; npi.protocol = PPP_IP; npi.mode = NPMODE_PASS; if (ioctl(ttyfd, PPPIOCSNPMODE, &npi) < 0) { if (errno != ENOTTY) { error("ioctl(PPPIOCSNPMODE): %m"); return 0; } /* for backwards compatibility */ if (ioctl(ttyfd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { error("ioctl (PPPIOCGFLAGS): %m"); return 0; } x |= SC_ENABLE_IP; if (ioctl(ttyfd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { error("ioctl(PPPIOCSFLAGS): %m"); return 0; } } return 1;}/* * sifdown - Config the interface down and disable IP. */intsifdown(u) int u;{ struct ifreq ifr; u_int x; int rv; struct npioctl npi; rv = 1; npi.protocol = PPP_IP; npi.mode = NPMODE_ERROR; ioctl(ttyfd, PPPIOCSNPMODE, (caddr_t) &npi); /* ignore errors, because ttyfd 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); /* * sifaddr - Config the interface IP addresses and netmask. */intsifaddr(u, o, h, m) int u; u_int32_t o, h, m;{ int ret; struct ifreq ifr; ret = 1; strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o; if (ioctl(sockfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { error("ioctl(SIOCAIFADDR): %m"); ret = 0; } ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = h; if (ioctl(sockfd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { error("ioctl(SIOCSIFDSTADDR): %m"); ret = 0; } if (m != 0) { ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = m; info("Setting interface mask to %s\n", ip_ntoa(m)); if (ioctl(sockfd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { error("ioctl(SIOCSIFNETMASK): %m"); ret = 0; } } return ret;}/* * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. * * N.B.: under NextStep, you can't *delete* an address on an interface, * so we change it to 0.0.0.0... A real hack. But it simplifies * reconnection on the server side. */intcifaddr(u, o, h) int u; u_int32_t o, h;{ struct rtentry rt;#if 1 h = o = 0L; (void) sifaddr(u, o, h, 0L);#endif SET_SA_FAMILY(rt.rt_dst, AF_INET); ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = h; SET_SA_FAMILY(rt.rt_gateway, AF_INET); ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = o; rt.rt_flags = RTF_HOST; if (ioctl(sockfd, SIOCDELRT, (caddr_t) &rt) < 0) { error("ioctl(SIOCDELRT): %m"); return 0; } return 1;}/* * sifdefaultroute - assign a default route through the address given. */intsifdefaultroute(u, l, g) int u; u_int32_t l, g;{ return dodefaultroute(g, 's');}/* * cifdefaultroute - delete a default route through the address given. */intcifdefaultroute(u, l, g) int u; u_int32_t l, g;{ return dodefaultroute(g, 'c');}/* * dodefaultroute - talk to a routing socket to add/delete a default route. */intdodefaultroute(g, cmd) u_int32_t g; int cmd;{ struct rtentry rt; SET_SA_FAMILY(rt.rt_dst, AF_INET); ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = 0L; SET_SA_FAMILY(rt.rt_gateway, AF_INET); ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g; rt.rt_flags = RTF_GATEWAY; if (ioctl(sockfd, (cmd == 's') ? SIOCADDRT : SIOCDELRT, &rt) < 0) { error("%cifdefaultroute: ioctl(%s): %m", cmd, (cmd == 's') ? "SIOCADDRT" : "SIOCDELRT"); return 0; } default_route_gateway = (cmd == 's')? g: 0; return 1;}/* * sifproxyarp - Make a proxy ARP entry for the peer. */intsifproxyarp(unit, hisaddr) int unit; u_int32_t hisaddr;{ struct arpreq arpreq; BZERO(&arpreq, sizeof(arpreq)); /* * Get the hardware address of an interface on the same subnet * as our local address. */ if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) { error("Cannot determine ethernet address for proxy ARP"); return 0; } SET_SA_FAMILY(arpreq.arp_pa, AF_INET); ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; arpreq.arp_flags = ATF_PERM | ATF_PUBL; if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) { error("ioctl(SIOCSARP): %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; BZERO(&arpreq, sizeof(arpreq)); SET_SA_FAMILY(arpreq.arp_pa, AF_INET); ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) { warn("ioctl(SIOCDARP): %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 32intget_ether_addr(ipaddr, hwaddr) u_int32_t ipaddr; struct sockaddr *hwaddr;{ struct ifreq *ifr, *ifend, *ifp; u_int32_t ina, mask; struct ether_addr dla; struct ifreq ifreq; struct ifconf ifc; struct ifreq ifs[MAX_IFS]; struct hostent *hostent; ifc.ifc_len = sizeof(ifs); ifc.ifc_req = ifs; if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { error("ioctl(SIOCGIFCONF): %m"); return 0; } /* * Scan through looking for an interface with an Internet * address on the same subnet as `ipaddr'. */ ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + sizeof(struct sockaddr))) { if (ifr->ifr_addr.sa_family == AF_INET) { ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); /* * Check that the interface is up, and not point-to-point * or loopback. */ if (ioctl(sockfd, 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(sockfd, SIOCGIFNETMASK, &ifreq) < 0) continue; mask = ((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr.s_addr; if ((ipaddr & mask) != (ina & mask)) continue; break; } } if (ifr >= ifend) return 0; info("found interface %s for proxy arp", ifr->ifr_name); /* * Get the hostname and look for an entry using the ethers database. * Under NeXTStep this is the best we can do for now. */ if ((hostent = gethostbyaddr((char*)&ina, sizeof(ina), AF_INET)) == NULL) return 0; if (ether_by_host(hostent->h_name, &dla)) { info("Add entry for %s in /etc/ethers", hostent->h_name); return 0; /* it's not there */ } hwaddr->sa_family = AF_UNSPEC; BCOPY(&dla, hwaddr->sa_data, sizeof(dla)); return 1;}static intether_by_host(hostname, etherptr) char *hostname; struct ether_addr *etherptr;{ struct ether_addr *thisptr; void *conn; ni_id root; ni_namelist val; char path[256]; if (!ether_hostton(hostname, etherptr)) return 0; /* * We shall now try and * find the address in the * top domain of netinfo. */ slprintf(path, sizeof(path), "/machines/%s", hostname); if (ni_open((void *)0, "/", &conn) || ni_root(conn, &root) || ni_pathsearch(conn, &root, path) || ni_lookupprop(conn, &root, "en_address", &val)) return 1; /* * Now we can convert the returned string into an ethernet address. */ strlcpy(path, val.ni_namelist_val[0], sizeof(path)); ni_free(conn); if ((thisptr = (struct ether_addr*)ether_aton(path)) == NULL) return 1; BCOPY(thisptr, etherptr, sizeof(struct ether_addr)); return 0;}/* * Return user specified netmask, modified by any mask we might determine * for address `addr' (in network byte order). * Here we scan through the system's list of interfaces, looking for * any non-point-to-point interfaces which might appear to be on the same * network as `addr'. If we find any, we OR in their netmask to the * user-specified netmask. */u_int32_tGetMask(addr) u_int32_t addr;{ u_int32_t mask, nmask, ina; struct ifreq *ifr, *ifend, ifreq; struct ifconf ifc; struct ifreq ifs[MAX_IFS]; addr = ntohl(addr); if (IN_CLASSA(addr)) /* determine network mask for address class */ nmask = IN_CLASSA_NET; else if (IN_CLASSB(addr)) nmask = IN_CLASSB_NET; else nmask = IN_CLASSC_NET; /* class D nets are disallowed by bad_ip_adrs */ mask = netmask | htonl(nmask); /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -