/* 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);
}
Exemple #3
0
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);
}