📄 sys-bsd.c
字号:
return 1;}/* * 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;{ struct ifaliasreq ifra; ifaddrs[0] = 0; 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; BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifra) < 0) { if (errno != EADDRNOTAVAIL) warn("Couldn't delete interface address: %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. */static intdodefaultroute(g, cmd) u_int32_t g; int cmd;{ int routes; struct { struct rt_msghdr hdr; struct sockaddr_in dst; struct sockaddr_in gway; struct sockaddr_in mask; } rtmsg; if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { error("Couldn't %s default route: socket: %m", cmd=='s'? "add": "delete"); return 0; } memset(&rtmsg, 0, sizeof(rtmsg)); rtmsg.hdr.rtm_type = cmd == 's'? RTM_ADD: RTM_DELETE; rtmsg.hdr.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; rtmsg.hdr.rtm_version = RTM_VERSION; rtmsg.hdr.rtm_seq = ++rtm_seq; rtmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; rtmsg.dst.sin_len = sizeof(rtmsg.dst); rtmsg.dst.sin_family = AF_INET; rtmsg.gway.sin_len = sizeof(rtmsg.gway); rtmsg.gway.sin_family = AF_INET; rtmsg.gway.sin_addr.s_addr = g; rtmsg.mask.sin_len = sizeof(rtmsg.dst); rtmsg.mask.sin_family = AF_INET; rtmsg.hdr.rtm_msglen = sizeof(rtmsg); if (write(routes, &rtmsg, sizeof(rtmsg)) < 0) { error("Couldn't %s default route: %m", cmd=='s'? "add": "delete"); close(routes); return 0; } close(routes); default_route_gateway = (cmd == 's')? g: 0; return 1;}#if RTM_VERSION >= 3/* * sifproxyarp - Make a proxy ARP entry for the peer. */static struct { struct rt_msghdr hdr; struct sockaddr_inarp dst; struct sockaddr_dl hwa; char extra[128];} arpmsg;static int arpmsg_valid;intsifproxyarp(unit, hisaddr) int unit; u_int32_t hisaddr;{ int routes; /* * Get the hardware address of an interface on the same subnet * as our local address. */ memset(&arpmsg, 0, sizeof(arpmsg)); if (!get_ether_addr(hisaddr, &arpmsg.hwa)) { error("Cannot determine ethernet address for proxy ARP"); return 0; } if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { error("Couldn't add proxy arp entry: socket: %m"); return 0; } arpmsg.hdr.rtm_type = RTM_ADD; arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC; arpmsg.hdr.rtm_version = RTM_VERSION; arpmsg.hdr.rtm_seq = ++rtm_seq; arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY; arpmsg.hdr.rtm_inits = RTV_EXPIRE; arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp); arpmsg.dst.sin_family = AF_INET; arpmsg.dst.sin_addr.s_addr = hisaddr; arpmsg.dst.sin_other = SIN_PROXY; arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg + arpmsg.hwa.sdl_len; if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) { error("Couldn't add proxy arp entry: %m"); close(routes); return 0; } close(routes); arpmsg_valid = 1; proxy_arp_addr = hisaddr; return 1;}/* * cifproxyarp - Delete the proxy ARP entry for the peer. */intcifproxyarp(unit, hisaddr) int unit; u_int32_t hisaddr;{ int routes; if (!arpmsg_valid) return 0; arpmsg_valid = 0; arpmsg.hdr.rtm_type = RTM_DELETE; arpmsg.hdr.rtm_seq = ++rtm_seq; if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { error("Couldn't delete proxy arp entry: socket: %m"); return 0; } if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) { error("Couldn't delete proxy arp entry: %m"); close(routes); return 0; } close(routes); proxy_arp_addr = 0; return 1;}#else /* RTM_VERSION *//* * sifproxyarp - Make a proxy ARP entry for the peer. */intsifproxyarp(unit, hisaddr) int unit; u_int32_t hisaddr;{ struct arpreq arpreq; struct { struct sockaddr_dl sdl; char space[128]; } dls; BZERO(&arpreq, sizeof(arpreq)); /* * Get the hardware address of an interface on the same subnet * as our local address. */ if (!get_ether_addr(hisaddr, &dls.sdl)) { error("Cannot determine ethernet address for proxy ARP"); return 0; } arpreq.arp_ha.sa_len = sizeof(struct sockaddr); arpreq.arp_ha.sa_family = AF_UNSPEC; BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen); 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("Couldn't add 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; 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("Couldn't delete proxy arp entry: %m"); return 0; } proxy_arp_addr = 0; return 1;}#endif /* RTM_VERSION *//* * 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_dl *hwaddr;{ struct ifreq *ifr, *ifend, *ifp; u_int32_t ina, mask; struct sockaddr_dl *dla; struct ifreq ifreq; struct ifconf ifc; struct ifreq ifs[MAX_IFS]; 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 + ifr->ifr_addr.sa_len)) { 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); /* * Now scan through again looking for a link-level address * for this interface. */ ifp = ifr; for (ifr = ifc.ifc_req; ifr < ifend; ) { if (strcmp(ifp->ifr_name, ifr->ifr_name) == 0 && ifr->ifr_addr.sa_family == AF_LINK) { /* * Found the link-level address - copy it out */ dla = (struct sockaddr_dl *) &ifr->ifr_addr; BCOPY(dla, hwaddr, dla->sdl_len); return 1; } ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len); } 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); /* * Scan through the system's network interfaces. */ ifc.ifc_len = sizeof(ifs); ifc.ifc_req = ifs; if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { warn("ioctl(SIOCGIFCONF): %m"); return mask; } ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) { /* * Check the interface's internet address. */ if (ifr->ifr_addr.sa_family != AF_INET) continue; ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; if ((ntohl(ina) & nmask) != (addr & nmask)) 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(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) != IFF_UP) continue; /* * Get its netmask and OR it into our mask. */ if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0) continue; mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr; } return mask;}/* * have_route_to - determine if the system has any route to * a given IP address. * For demand mode to work properly, we have to ignore routes * through our own interface. */int have_route_to(u_int32_t addr){ return -1;}/* * Use the hostid as part of the random number seed. */intget_host_seed(){ return gethostid();}#if 0/* * lock - create a lock file for the named lock device */#define LOCK_PREFIX "/var/spool/lock/LCK.."static char *lock_file; /* name of lock file created */intlock(dev) char *dev;{ char hdb_lock_buffer[12]; int fd, pid, n; char *p; size_t l; if ((p = strrchr(dev, '/')) != NULL) dev = p + 1; l = strlen(LOCK_PREFIX) + strlen(dev) + 1; lock_file = malloc(l); if (lock_file == NULL) novm("lock file name"); slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev); while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { if (errno == EEXIST && (fd = open(lock_file, O_RDONLY, 0)) >= 0) { /* Read the lock file to find out who has the device locked */ n = read(fd, hdb_lock_buffer, 11); if (n <= 0) { error("Can't read pid from lock file %s", lock_file); close(fd); } else { hdb_lock_buffer[n] = 0; pid = atoi(hdb_lock_buffer); if (kill(pid, 0) == -1 && errno == ESRCH) { /* pid no longer exists - remove the lock file */ if (unlink(lock_file) == 0) { close(fd); notice("Removed stale lock on %s (pid %d)", dev, pid); continue; } else warn("Couldn't remove stale lock on %s", dev); } else notice("Device %s is locked by pid %d", dev, pid); } close(fd); } else error("Can't create lock file %s: %m", lock_file); free(lock_file); lock_file = NULL; return -1; } slprintf(hdb_lock_buffer, sizeof(hdb_lock_buffer), "%10d\n", getpid()); write(fd, hdb_lock_buffer, 11); close(fd); return 0;}/* * unlock - remove our lockfile */voidunlock(){ if (lock_file) { unlink(lock_file); free(lock_file); lock_file = NULL; }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -