/**
 * Parses addrString into an IPv4 or IPv6 address, then determines
 * whether the priority of the address is higher than the existing
 * adaptor IP address (according to EnumIPSelectionPriority).
 * If it is, then the new address is assigned as the adaptor IP address
 * and used to populate adapter->userData->ipAddr.
 * If two addresses have the same highest priority, then the first one seen 
 * is chosen.
 */
static void stringToAdaptorIp(PCWSTR addrString, SFLAdaptor *adaptor)
{
	HSPAdaptorNIO *nioState = (HSPAdaptorNIO *)adaptor->userData;
	IN_ADDR in_addr = {0};
	LPCWSTR terminator;
	LONG result = RtlIpv4StringToAddressW(addrString, TRUE, &terminator, &in_addr);
	if (NO_ERROR == result) {
		SFLAddress addrv4;
		addrv4.type = SFLADDRESSTYPE_IP_V4;
		addrv4.address.ip_v4.addr =  in_addr.S_un.S_addr;
		EnumIPSelectionPriority ipPriority = agentAddressPriority(&addrv4);
		if (ipPriority > nioState->ipPriority) {
			nioState->ipPriority = ipPriority;
			nioState->ipAddr = addrv4;
		}
	} else {
		IN6_ADDR in6_addr = {0};
		result = RtlIpv6StringToAddressW(addrString, &terminator, &in6_addr);
		if (NO_ERROR == result) {
			SFLAddress addrv6;
			addrv6.type = SFLADDRESSTYPE_IP_V6;
			memcpy(addrv6.address.ip_v6.addr, in_addr6.u.Byte, sizeof(in6_addr.u.Byte));
			EnumIPSelectionPriority ipPriority = agentAddressPriority(&addrv6);
			if (ipPriority > nioState->ipPriority) {
				nioState->ipPriority = ipPriority;
				nioState->ipAddr = addrv6;
			}
		}
	}
}
Beispiel #2
0
/*________________---------------------------__________________
  ________________  setAddressPriorities     __________________
  ----------------___________________________------------------
  Ideally we would do this as we go along,  but since the vlan
  info is spliced in separately we have to wait for that and
  then set the priorities for the whole list.
*/
  void setAddressPriorities(HSP *sp)
  {
    for(uint32_t i = 0; i < sp->adaptorList->num_adaptors; i++) {
      SFLAdaptor *adaptor = sp->adaptorList->adaptors[i];
      if(adaptor && adaptor->userData) {
	HSPAdaptorNIO *adaptorNIO = (HSPAdaptorNIO *)adaptor->userData;
	adaptorNIO->ipPriority = agentAddressPriority(&adaptorNIO->ipAddr,
						      adaptorNIO->vlan,
						      adaptorNIO->loopback);
      }
    }
  }
  void readIPv6Addresses(HSP *sp)
  {
    FILE *procFile = fopen("/proc/net/if_inet6", "r");
    if(procFile) {
      char line[MAX_PROC_LINE_CHARS];
      int lineNo = 0;
      while(fgets(line, MAX_PROC_LINE_CHARS, procFile)) {
	// expect lines of the form "<address> <netlink_no> <prefix_len(HEX)> <scope(HEX)> <flags(HEX)> <deviceName>
	// (with a header line on the first row)
	char devName[MAX_PROC_LINE_CHARS];
	u_char addr[MAX_PROC_LINE_CHARS];
	u_int devNo, maskBits, scope, flags;
	++lineNo;
	if(sscanf(line, "%s %x %x %x %x %s",
		  addr,
		  &devNo,
		  &maskBits,
		  &scope,
		  &flags,
		  devName) == 6) {
	  if(debug) {
	    myLog(LOG_INFO, "adaptor %s has v6 address %s with scope 0x%x",
		  devName,
		  addr,
		  scope);
	  }
	  SFLAdaptor *adaptor = adaptorListGet(sp->adaptorList, trimWhitespace(devName));
	  if(adaptor && adaptor->userData) {
	    HSPAdaptorNIO *niostate = (HSPAdaptorNIO *)adaptor->userData;
	    SFLAddress v6addr;
	    v6addr.type = SFLADDRESSTYPE_IP_V6;
	    if(hexToBinary(addr, v6addr.address.ip_v6.addr, 16) == 16) {
	      // we interpret the scope from the address now
	      // scope = remap_proc_net_if_inet6_scope(scope);
	      EnumIPSelectionPriority ipPriority = agentAddressPriority(sp,
									&v6addr,
									niostate->vlan,
									niostate->loopback);
	      if(ipPriority > niostate->ipPriority) {
		// write this in as the preferred sflow-agent-address for this adaptor
		niostate->ipAddr = v6addr;
		niostate->ipPriority = ipPriority;
	      }
	    }
	  }
	}
      }
      fclose(procFile);
    }
  }
Beispiel #4
0
  int readInterfaces_getifaddrs(HSP *sp)
  {
    struct ifaddrs *ifap = NULL;
    int interfaces_found = 0;
    
    if(getifaddrs(&ifap) != 0) {
      myLog(LOG_ERR, "getifaddrs() failed : %s", strerror(errno));
      return 0;
    }
    for(struct ifaddrs *ifa = ifap; ifa; ifa = ifa->ifa_next) {
      int up = (ifa->ifa_flags & IFF_UP) ? 1 : 0;
      int loopback = (ifa->ifa_flags & IFF_LOOPBACK) ? 1: 0;
      int promisc = (ifa->ifa_flags & IFF_PROMISC) ? 1 : 0;
      int bond_master = 0; // (ifa->ifa_flags & IFF_MASTER) ? 1 : 0;
	
      if(debug) myLog(LOG_INFO, "ifa_name=%s up=%d loopback=%d", ifa->ifa_name, up, loopback);
	
      if(up == 0) continue;
      interfaces_found++;

      // try to get the MAC
      u_char *macptr = NULL;
      u_char macAddr[6];
      if(readMacAddress(ifa->ifa_name, macAddr, 6)) {
	macptr = macAddr;
      }

      // find or create the "adaptor" entry for this dev
      SFLAdaptor *adaptor = adaptorListAdd(sp->adaptorList, ifa->ifa_name, macptr, sizeof(HSPAdaptorNIO));
			
      // this flag might belong in the adaptorNIO struct
      adaptor->promiscuous = promisc;
			
      // remember some useful flags in the userData structure
      HSPAdaptorNIO *adaptorNIO = (HSPAdaptorNIO *)adaptor->userData;
      adaptorNIO->loopback = loopback;
      adaptorNIO->bond_master = bond_master;
      adaptorNIO->vlan = HSP_VLAN_ALL; // may be modified below

      // we don't expect to read counters from this device - it's
      // really just there to learn the IP address/MAC addresses
      adaptorNIO->forCounters = NO;

      SFLAddress addr = { 0 };

      if (AF_INET == ifa->ifa_addr->sa_family) {
	struct sockaddr_in *s = (struct sockaddr_in *)ifa->ifa_addr;
	addr.type = SFLADDRESSTYPE_IP_V4;
	addr.address.ip_v4.addr = s->sin_addr.s_addr;
      }
      else if(AF_INET6 == ifa->ifa_addr->sa_family) {
	struct sockaddr_in6 *s = (struct sockaddr_in6 *)ifa->ifa_addr;
	addr.type = SFLADDRESSTYPE_IP_V6;
	memcpy(&addr.address.ip_v6.addr, &s->sin6_addr, 16);
      }
      EnumIPSelectionPriority ipPriority = agentAddressPriority(sp,
								&addr,
								adaptorNIO->vlan,
								adaptorNIO->loopback);
      if(adaptor->marked ||
	 ipPriority > adaptorNIO->ipPriority) {
	adaptorNIO->ipAddr = addr;
	adaptorNIO->ipPriority = ipPriority;

	if(debug) {
	  char buf[51];
	  myLog(LOG_INFO, "interface: %s family: %d IP: %s priority: %d",
		ifa->ifa_name,
		ifa->ifa_addr->sa_family,
		inet_ntop(ifa->ifa_addr->sa_family, &adaptorNIO->ipAddr.address, buf, 50),
		ipPriority);
	}
      }
	
      // clear the mark so we don't free it below
      adaptor->marked = NO; 
    }

    // clean up
    freeifaddrs(ifap);

    if(debug) myLog(LOG_INFO, "found (and unmarked) %d interfaces via getifaddrs", interfaces_found);

    return interfaces_found;
  }
Beispiel #5
0
/**
 * Finds the associated Win32_NetworkAdapterConfiguration for Win32_NetworkAdapter adapterObj.
 * Iterates through the IP addresses associated with the adapter and chooses the highest
 * priority IP address (according to EnumIPSelectionPriority) as the adapter address
 * which is used to populate adapter->userData->ipAddr.
 * If two addresses have the same highest priority, then the first one seen is chosen.
 */
void readIpAddresses(IWbemServices *pNamespace, IWbemClassObject *adapterObj, SFLAdaptor *adaptor)
{
	IEnumWbemClassObject *configEnum;
	HRESULT hr = associatorsOf(pNamespace, adapterObj,
							   L"Win32_NetworkAdapterSetting",
							   L"Win32_NetworkAdapterConfiguration",
							   L"Setting", &configEnum);
	if (SUCCEEDED(hr)) {
		IWbemClassObject *configObj;
		ULONG configCount;
		hr = configEnum->Next(WBEM_INFINITE, 1, &configObj, &configCount);
		if (SUCCEEDED(hr) && configCount == 1) {
			VARIANT addresses;
			hr = configObj->Get(L"IPAddress", 0, &addresses, 0, 0);
			if (WBEM_S_NO_ERROR == hr && addresses.vt == (VT_ARRAY |VT_BSTR))  {
				SAFEARRAY *sa = V_ARRAY(&addresses);
				LONG lstart, lend;
				hr = SafeArrayGetLBound(sa, 1, &lstart);
				hr = SafeArrayGetUBound(sa, 1, &lend);
				BSTR *pbstr;
				hr = SafeArrayAccessData(sa, (void HUGEP **)&pbstr);
				if (SUCCEEDED(hr)) {
					HSPAdaptorNIO *nioState = (HSPAdaptorNIO *)adaptor->userData;
					for (LONG idx=lstart; idx <= lend; idx++) {		
						PCWSTR addrStr = pbstr[idx];
						IN_ADDR in_addr = {0};
						LPCWSTR terminator;
						LONG result = RtlIpv4StringToAddressW(addrStr, TRUE, &terminator, &in_addr);
						if (NO_ERROR == result) {
							SFLAddress addrv4;
							addrv4.type = SFLADDRESSTYPE_IP_V4;
							addrv4.address.ip_v4.addr =  in_addr.S_un.S_addr;
							EnumIPSelectionPriority ipPriority = agentAddressPriority(&addrv4);
							if (ipPriority > nioState->ipPriority) {
								nioState->ipPriority = ipPriority;
								nioState->ipAddr = addrv4;
							}
						} else {
							IN6_ADDR in6_addr = {0};
							result = RtlIpv6StringToAddressW(addrStr, &terminator, &in6_addr);
							if (NO_ERROR == result) {
								SFLAddress addrv6;
								addrv6.type = SFLADDRESSTYPE_IP_V6;
								memcpy(addrv6.address.ip_v6.addr, in_addr6.u.Byte, sizeof(in6_addr.u.Byte));
								EnumIPSelectionPriority ipPriority = agentAddressPriority(&addrv6);
								if (ipPriority > nioState->ipPriority) {
									nioState->ipPriority = ipPriority;
									nioState->ipAddr = addrv6;
								}
							}
						}
					}
					SafeArrayUnaccessData(sa);
				}
			}
			VariantClear(&addresses);
			configObj->Release();
		}
		configEnum->Release();
	}
}