📄 intf.c
字号:
entry->intf_type = INTF_TYPE_ETH; else if ((entry->intf_flags & INTF_FLAG_POINTOPOINT) != 0) entry->intf_type = INTF_TYPE_TUN; else if ((entry->intf_flags & INTF_FLAG_LOOPBACK) != 0) entry->intf_type = INTF_TYPE_LOOPBACK; else entry->intf_type = INTF_TYPE_OTHER;}static int_intf_get_noalias(intf_t *intf, struct intf_entry *entry){ struct ifreq ifr; strlcpy(ifr.ifr_name, entry->intf_name, sizeof(ifr.ifr_name)); /* Get interface flags. */ if (ioctl(intf->fd, SIOCGIFFLAGS, &ifr) < 0) return (-1); entry->intf_flags = intf_iff_to_flags(ifr.ifr_flags); _intf_set_type(entry); /* Get interface MTU. */#ifdef SIOCGIFMTU if (ioctl(intf->fd, SIOCGIFMTU, &ifr) < 0)#endif return (-1); entry->intf_mtu = ifr.ifr_mtu; entry->intf_addr.addr_type = entry->intf_dst_addr.addr_type = entry->intf_link_addr.addr_type = ADDR_TYPE_NONE; /* Get primary interface address. */ if (ioctl(intf->fd, SIOCGIFADDR, &ifr) == 0) { addr_ston(&ifr.ifr_addr, &entry->intf_addr); if (ioctl(intf->fd, SIOCGIFNETMASK, &ifr) < 0) return (-1); addr_stob(&ifr.ifr_addr, &entry->intf_addr.addr_bits); } /* Get other addresses. */ if (entry->intf_type == INTF_TYPE_TUN) { if (ioctl(intf->fd, SIOCGIFDSTADDR, &ifr) == 0) { if (addr_ston(&ifr.ifr_addr, &entry->intf_dst_addr) < 0) return (-1); } } else if (entry->intf_type == INTF_TYPE_ETH) {#if defined(SIOCGIFHWADDR) if (ioctl(intf->fd, SIOCGIFHWADDR, &ifr) < 0) return (-1); if (addr_ston(&ifr.ifr_addr, &entry->intf_link_addr) < 0) return (-1);#elif defined(SIOCRPHYSADDR) /* Tru64 */ struct ifdevea *ifd = (struct ifdevea *)𝔦 /* XXX */ if (ioctl(intf->fd, SIOCRPHYSADDR, ifd) < 0) return (-1); addr_pack(&entry->intf_link_addr, ADDR_TYPE_ETH, ETH_ADDR_BITS, ifd->current_pa, ETH_ADDR_LEN);#else eth_t *eth; if ((eth = eth_open(entry->intf_name)) != NULL) { if (!eth_get(eth, &entry->intf_link_addr.addr_eth)) { entry->intf_link_addr.addr_type = ADDR_TYPE_ETH; entry->intf_link_addr.addr_bits = ETH_ADDR_BITS; } eth_close(eth); }#endif } return (0);}#ifdef SIOCLIFADDR/* XXX - aliases on IRIX don't show up in SIOCGIFCONF */static int_intf_get_aliases(intf_t *intf, struct intf_entry *entry){ struct dnet_ifaliasreq ifra; struct addr *ap, *lap; strlcpy(ifra.ifra_name, entry->intf_name, sizeof(ifra.ifra_name)); addr_ntos(&entry->intf_addr, &ifra.ifra_addr); addr_btos(entry->intf_addr.addr_bits, &ifra.ifra_mask); memset(&ifra.ifra_brdaddr, 0, sizeof(ifra.ifra_brdaddr)); ifra.ifra_cookie = 1; ap = entry->intf_alias_addrs; lap = (struct addr *)((u_char *)entry + entry->intf_len); while (ioctl(intf->fd, SIOCLIFADDR, &ifra) == 0 && ifra.ifra_cookie > 0 && (ap + 1) < lap) { if (addr_ston(&ifra.ifra_addr, ap) < 0) break; ap++, entry->intf_alias_num++; } entry->intf_len = (u_char *)ap - (u_char *)entry; return (0);}#elsestatic int_intf_get_aliases(intf_t *intf, struct intf_entry *entry){ struct ifreq *ifr, *lifr; struct ifreq tmpifr; struct addr *ap, *lap; char *p; if (intf->ifc.ifc_len < (int)sizeof(*ifr)) { errno = EINVAL; return (-1); } entry->intf_alias_num = 0; ap = entry->intf_alias_addrs; lifr = (struct ifreq *)intf->ifc.ifc_buf + (intf->ifc.ifc_len / sizeof(*lifr)); lap = (struct addr *)((u_char *)entry + entry->intf_len); /* Get addresses for this interface. */ for (ifr = intf->ifc.ifc_req; ifr < lifr && (ap + 1) < lap; ifr = NEXTIFR(ifr)) { /* XXX - Linux, Solaris ifaliases */ if ((p = strchr(ifr->ifr_name, ':')) != NULL) *p = '\0'; if (strcmp(ifr->ifr_name, entry->intf_name) != 0) { if (p) *p = ':'; continue; } if (p) *p = ':'; /* Fix the name back up */ if (addr_ston(&ifr->ifr_addr, ap) < 0) continue; /* XXX */ if (ap->addr_type == ADDR_TYPE_ETH) { memcpy(&entry->intf_link_addr, ap, sizeof(*ap)); continue; } else if (ap->addr_type == ADDR_TYPE_IP) { if (ap->addr_ip == entry->intf_addr.addr_ip || ap->addr_ip == entry->intf_dst_addr.addr_ip) continue; strlcpy(tmpifr.ifr_name, ifr->ifr_name, sizeof(tmpifr.ifr_name)); if (ioctl(intf->fd, SIOCGIFNETMASK, &tmpifr) == 0) addr_stob(&tmpifr.ifr_addr, &ap->addr_bits); }#ifdef SIOCGIFNETMASK_IN6 else if (ap->addr_type == ADDR_TYPE_IP6 && intf->fd6 != -1) { struct in6_ifreq ifr6; /* XXX - sizeof(ifr) < sizeof(ifr6) */ memcpy(&ifr6, ifr, sizeof(ifr6)); if (ioctl(intf->fd6, SIOCGIFNETMASK_IN6, &ifr6) == 0) { addr_stob((struct sockaddr *)&ifr6.ifr_addr, &ap->addr_bits); } else perror("SIOCGIFNETMASK_IN6"); }#endif ap++, entry->intf_alias_num++; } entry->intf_len = (u_char *)ap - (u_char *)entry; return (0);}#endif /* SIOCLIFADDR */intintf_get(intf_t *intf, struct intf_entry *entry){ if (_intf_get_noalias(intf, entry) < 0) return (-1);#ifndef SIOCLIFADDR intf->ifc.ifc_buf = (caddr_t)intf->ifcbuf; intf->ifc.ifc_len = sizeof(intf->ifcbuf); if (ioctl(intf->fd, SIOCGIFCONF, &intf->ifc) < 0) return (-1);#endif return (_intf_get_aliases(intf, entry));}static int_match_intf_src(const struct intf_entry *entry, void *arg){ int matched = 0; int cnt; struct intf_entry *save = (struct intf_entry *)arg; if (entry->intf_addr.addr_type == ADDR_TYPE_IP && entry->intf_addr.addr_ip == save->intf_addr.addr_ip) matched = 1; for (cnt = 0; !matched && cnt < (int) entry->intf_alias_num; cnt++) { if (entry->intf_alias_addrs[cnt].addr_type != ADDR_TYPE_IP) continue; if (entry->intf_alias_addrs[cnt].addr_ip == save->intf_addr.addr_ip) matched = 1; } if (matched) { /* XXX - truncated result if entry is too small. */ if (save->intf_len < entry->intf_len) memcpy(save, entry, save->intf_len); else memcpy(save, entry, entry->intf_len); return (1); } return (0);}intintf_get_src(intf_t *intf, struct intf_entry *entry, struct addr *src){ memcpy(&entry->intf_addr, src, sizeof(*src)); if (intf_loop(intf, _match_intf_src, entry) != 1) { errno = ENXIO; return (-1); } return (0);}intintf_get_dst(intf_t *intf, struct intf_entry *entry, struct addr *dst){ struct sockaddr_in sin; int n; if (dst->addr_type != ADDR_TYPE_IP) { errno = EINVAL; return (-1); } addr_ntos(dst, (struct sockaddr *)&sin); sin.sin_port = htons(666); if (connect(intf->fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) return (-1); n = sizeof(sin); if (getsockname(intf->fd, (struct sockaddr *)&sin, &n) < 0) return (-1); addr_ston((struct sockaddr *)&sin, &entry->intf_addr); if (intf_loop(intf, _match_intf_src, entry) != 1) return (-1); return (0);}#ifdef HAVE_LINUX_PROCFS#define PROC_DEV_FILE "/proc/net/dev"intintf_loop(intf_t *intf, intf_handler callback, void *arg){ FILE *fp; struct intf_entry *entry; char *p, buf[BUFSIZ], ebuf[BUFSIZ]; int ret; entry = (struct intf_entry *)ebuf; if ((fp = fopen(PROC_DEV_FILE, "r")) == NULL) return (-1); intf->ifc.ifc_buf = (caddr_t)intf->ifcbuf; intf->ifc.ifc_len = sizeof(intf->ifcbuf); if (ioctl(intf->fd, SIOCGIFCONF, &intf->ifc) < 0) return (-1); ret = 0; while (fgets(buf, sizeof(buf), fp) != NULL) { if ((p = strchr(buf, ':')) == NULL) continue; *p = '\0'; for (p = buf; *p == ' '; p++) ; memset(ebuf, 0, sizeof(ebuf)); strlcpy(entry->intf_name, p, sizeof(entry->intf_name)); entry->intf_len = sizeof(ebuf); if (_intf_get_noalias(intf, entry) < 0) { ret = -1; break; } if (_intf_get_aliases(intf, entry) < 0) { ret = -1; break; } if ((ret = (*callback)(entry, arg)) != 0) break; } if (ferror(fp)) ret = -1; fclose(fp); return (ret);}#elseintintf_loop(intf_t *intf, intf_handler callback, void *arg){ struct intf_entry *entry; struct ifreq *ifr, *lifr, *pifr; char *p, ebuf[BUFSIZ]; int ret; entry = (struct intf_entry *)ebuf; intf->ifc.ifc_buf = (caddr_t)intf->ifcbuf; intf->ifc.ifc_len = sizeof(intf->ifcbuf); if (ioctl(intf->fd, SIOCGIFCONF, &intf->ifc) < 0) return (-1); pifr = NULL; lifr = (struct ifreq *)&intf->ifc.ifc_buf[intf->ifc.ifc_len]; for (ifr = intf->ifc.ifc_req; ifr < lifr; ifr = NEXTIFR(ifr)) { /* XXX - Linux, Solaris ifaliases */ if ((p = strchr(ifr->ifr_name, ':')) != NULL) *p = '\0'; if (pifr != NULL && strcmp(ifr->ifr_name, pifr->ifr_name) == 0) { if (p) *p = ':'; continue; } memset(ebuf, 0, sizeof(ebuf)); strlcpy(entry->intf_name, ifr->ifr_name, sizeof(entry->intf_name)); entry->intf_len = sizeof(ebuf); /* Repair the alias name back up. */ if (p) *p = ':'; if (_intf_get_noalias(intf, entry) < 0) return (-1); if (_intf_get_aliases(intf, entry) < 0) return (-1); if ((ret = (*callback)(entry, arg)) != 0) return (ret); pifr = ifr; } return (0);}#endif /* !HAVE_LINUX_PROCFS */intf_t *intf_close(intf_t *intf){ if (intf != NULL) { if (intf->fd >= 0) close(intf->fd); if (intf->fd6 >= 0) close(intf->fd6); free(intf); } return (NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -