/* Map an MIB interface type into an internal interface type. The internal types are never exposed to users of this library; they exist only for the sake of ordering interface types within an intf_handle, which has an array of ifcombo structures ordered by type. Entries in an intf_handle must not be stored or accessed by a raw MIB type number because they will not be able to be found by a device name such as "net0" if the device name does not map exactly to the type. */ static int _if_type_canonicalize(int type) { return _ifcombo_type(_ifcombo_name(type)); }
static void _adapter_address_to_entry(intf_t *intf, IP_ADAPTER_ADDRESSES *a, struct intf_entry *entry) { struct addr *ap, *lap; int i; int type; IP_ADAPTER_UNICAST_ADDRESS *addr; /* The total length of the entry may be passed inside entry. Remember it and clear the entry. */ u_int intf_len = entry->intf_len; memset(entry, 0, sizeof(*entry)); entry->intf_len = intf_len; type = _if_type_canonicalize(a->IfType); for (i = 0; i < intf->ifcombo[type].cnt; i++) { if (intf->ifcombo[type].idx[i].ipv4 == a->IfIndex && intf->ifcombo[type].idx[i].ipv6 == a->Ipv6IfIndex) { break; } } /* XXX - type matches MIB-II ifType. */ snprintf(entry->intf_name, sizeof(entry->intf_name), "%s%lu", _ifcombo_name(a->IfType), i); entry->intf_type = (uint16_t)type; /* Get interface flags. */ entry->intf_flags = 0; if (a->OperStatus == IfOperStatusUp) entry->intf_flags |= INTF_FLAG_UP; if (a->IfType == IF_TYPE_SOFTWARE_LOOPBACK) entry->intf_flags |= INTF_FLAG_LOOPBACK; else entry->intf_flags |= INTF_FLAG_MULTICAST; /* Get interface MTU. */ entry->intf_mtu = a->Mtu; /* Get hardware address. */ if (a->PhysicalAddressLength == ETH_ADDR_LEN) { entry->intf_link_addr.addr_type = ADDR_TYPE_ETH; entry->intf_link_addr.addr_bits = ETH_ADDR_BITS; memcpy(&entry->intf_link_addr.addr_eth, a->PhysicalAddress, ETH_ADDR_LEN); } /* Get addresses. */ ap = entry->intf_alias_addrs; lap = ap + ((entry->intf_len - sizeof(*entry)) / sizeof(entry->intf_alias_addrs[0])); for (addr = a->FirstUnicastAddress; addr != NULL; addr = addr->Next) { IP_ADAPTER_PREFIX *prefix; unsigned short bits; /* Find the netmask length. This is stored in a parallel list. We just take the first one with a matching address family, but that may not be right. Windows Vista and later has an OnLinkPrefixLength member that is stored right with the unicast address. */ bits = 0; for (prefix = a->FirstPrefix; prefix != NULL; prefix = prefix->Next) { if (prefix->Address.lpSockaddr->sa_family == addr->Address.lpSockaddr->sa_family) { bits = (unsigned short) prefix->PrefixLength; break; } } if (entry->intf_addr.addr_type == ADDR_TYPE_NONE) { /* Set primary address if unset. */ addr_ston(addr->Address.lpSockaddr, &entry->intf_addr); entry->intf_addr.addr_bits = bits; } else if (ap < lap) { /* Set aliases. */ addr_ston(addr->Address.lpSockaddr, ap); ap->addr_bits = bits; ap++; entry->intf_alias_num++; } } entry->intf_len = (u_int) ((u_char *)ap - (u_char *)entry); }
static void _ifrow_to_entry(intf_t *intf, MIB_IFROW *ifrow, struct intf_entry *entry) { struct addr *ap, *lap; int i; memset(entry, 0, sizeof(*entry)); for (i = 0; i < intf->ifcombo[ifrow->dwType].cnt; i++) { if (intf->ifcombo[ifrow->dwType].idx[i] == ifrow->dwIndex) break; } /* XXX - dwType matches MIB-II ifType. */ snprintf(entry->intf_name, sizeof(entry->intf_name), "%s%lu", _ifcombo_name(ifrow->dwType), i); entry->intf_type = (uint16_t)ifrow->dwType; /* Get interface flags. */ entry->intf_flags = 0; if (ifrow->dwAdminStatus == MIB_IF_ADMIN_STATUS_UP && (ifrow->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL || ifrow->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED)) entry->intf_flags |= INTF_FLAG_UP; if (ifrow->dwType == MIB_IF_TYPE_LOOPBACK) entry->intf_flags |= INTF_FLAG_LOOPBACK; else entry->intf_flags |= INTF_FLAG_MULTICAST; /* Get interface MTU. */ entry->intf_mtu = ifrow->dwMtu; /* Get hardware address. */ if (ifrow->dwPhysAddrLen == ETH_ADDR_LEN) { entry->intf_link_addr.addr_type = ADDR_TYPE_ETH; entry->intf_link_addr.addr_bits = ETH_ADDR_BITS; memcpy(&entry->intf_link_addr.addr_eth, ifrow->bPhysAddr, ETH_ADDR_LEN); } /* Get addresses. */ ap = entry->intf_alias_addrs; lap = ap + ((entry->intf_len - sizeof(*entry)) / sizeof(entry->intf_alias_addrs[0])); for (i = 0; i < (int)intf->iptable->dwNumEntries; i++) { if (intf->iptable->table[i].dwIndex == ifrow->dwIndex && intf->iptable->table[i].dwAddr != 0) { if (entry->intf_addr.addr_type == ADDR_TYPE_NONE) { /* Set primary address if unset. */ entry->intf_addr.addr_type = ADDR_TYPE_IP; entry->intf_addr.addr_ip = intf->iptable->table[i].dwAddr; addr_mtob(&intf->iptable->table[i].dwMask, IP_ADDR_LEN, &entry->intf_addr.addr_bits); } else if (ap < lap) { /* Set aliases. */ ap->addr_type = ADDR_TYPE_IP; ap->addr_ip = intf->iptable->table[i].dwAddr; addr_mtob(&intf->iptable->table[i].dwMask, IP_ADDR_LEN, &ap->addr_bits); ap++, entry->intf_alias_num++; } } } entry->intf_len = (unsigned int) ((u_char *)ap - (u_char *)entry); }