예제 #1
0
/**
 * Populates nio with the counters accumulated for all of the non-virtual
 * adaptors, first ensuring that the accumulated counters are current.
 * Returns TRUE if there are adaptors for which their are counters 0,
 * FALSE otherwise.
 */
BOOL readNioCounters(HSP *sp, SFLHost_nio_counters *nio) {
	// may need to schedule intermediate calls to updateNioCounters()
	// too (to avoid undetected wraps), but at the very least we need to do
	// it here to make sure the data is up to the second.
	updateNioCounters(sp);
	BOOL gotData = FALSE;
	// just add up all the counters for the non-virtual adaptors
	for (uint32_t i = 0; i < sp->adaptorList->num_adaptors; i++) {
		SFLAdaptor *ad = sp->adaptorList->adaptors[i];
		if (ad != NULL) {
			HSPAdaptorNIO *ctrs = (HSPAdaptorNIO *)ad->userData;
			if (ctrs != NULL && !ctrs->isVirtual) {
				gotData = TRUE;
				myLog(LOG_INFO, "readNioCounters: accumulating: pkts_in=%lu (device=%S virtual=%d)",
					  ctrs->nio.pkts_in, ctrs->countersInstance, ctrs->isVirtual);
				nio->bytes_in += ctrs->nio.bytes_in;
				nio->pkts_in += ctrs->nio.pkts_in;
				nio->errs_in += ctrs->nio.errs_in;
				nio->drops_in += ctrs->nio.drops_in;
				nio->bytes_out += ctrs->nio.bytes_out;
				nio->pkts_out += ctrs->nio.pkts_out;
				nio->errs_out += ctrs->nio.errs_out;
				nio->drops_out += ctrs->nio.drops_out;
			}
		}
	}
	myLog(LOG_INFO,"readNioCounters: %lu adaptors\n\trbytes:\t%llu\n\trpkts:\t%lu\n\trdrops:\t%lu\n\trerrs:\t%lu\n\ttbytes:\t%llu\n\ttpkts:\t%lu\n\ttdrops:\t%lu\n\tterrs:\t%lu\n",
		  sp->adaptorList->num_adaptors,nio->bytes_in,nio->pkts_in,nio->drops_in,nio->errs_in,nio->bytes_out,nio->pkts_out,nio->drops_out,nio->errs_out);
	return gotData;
}
예제 #2
0
  static void openXenHandles(HSP *sp)
  {
    // need to do this while we still have root privileges
    if(sp->xc_handle == 0) {
      sp->xc_handle = xc_interface_open();
      if(sp->xc_handle <= 0) {
        myLog(LOG_ERR, "xc_interface_open() failed : %s", strerror(errno));
      }
      else {
        sp->xs_handle = xs_daemon_open_readonly();
        if(sp->xs_handle == NULL) {
          myLog(LOG_ERR, "xs_daemon_open_readonly() failed : %s", strerror(errno));
        }
        // get the page size [ref xenstat.c]
#if defined(PAGESIZE)
        sp->page_size = PAGESIZE;
#elif defined(PAGE_SIZE)
        sp->page_size = PAGE_SIZE;
#else
        sp->page_size = sysconf(_SC_PAGE_SIZE);
        if(pgsiz < 0) {
          myLog(LOG_ERR, "Failed to retrieve page size : %s", strerror(errno));
          abort();
        }
#endif
      }
    }
  }
예제 #3
0
  int readMemoryCounters(SFLHost_mem_counters *mem) {
    int gotData = NO;
	MEMORYSTATUSEX memStat;

	memStat.dwLength = sizeof(memStat);
	if(GlobalMemoryStatusEx(&memStat) == 0){

		myLog(LOG_ERR,"GlobalMemoryStatusEx failed: %d\n",GetLastError());
		return NO;
	}

	mem->mem_total = memStat.ullTotalPhys;
	mem->mem_free = memStat.ullAvailPhys;
	mem->swap_total = memStat.ullTotalPageFile;
	mem->swap_free = memStat.ullAvailPageFile;
	mem->mem_cached = readSingleCounter("\\Memory\\Cache Bytes");
	mem->swap_in = (uint32_t)readSingleCounter("\\Memory\\Pages Input/sec");
	mem->swap_out = (uint32_t)readSingleCounter("\\Memory\\Pages Output/sec");

	//There are no obvious Windows equivalents
	mem->mem_buffers = UNKNOWN_COUNTER_64;
    mem->mem_shared = UNKNOWN_COUNTER_64;
	mem->page_in = UNKNOWN_COUNTER;
	mem->page_out = UNKNOWN_COUNTER;

	gotData = YES;

	myLog(LOG_INFO,"readMemoryCounters:\n\ttotal: %I64d\n\tfree: %I64d\n\tcached: %I64d\n\tswap_in: %d\n\tswap_out: %d\n",
			mem->mem_total,mem->mem_free,mem->mem_cached,mem->swap_in,mem->swap_out);

    return gotData;
  }
예제 #4
0
파일: dnsSD.c 프로젝트: wuhongyang/iass-web
/**
 * Runs the DNS-SD sequence to discover the sFlow server settings,
 * collector addresses and ports and sampling rates and polling interval
 * settings.
 * The DNS query is scoped to query for entries in the domain (zone)
 * configured as the domain override in the registry (if set), or the
 * primary domain name configured on the system if there is no domain
 * override.
 * Note that the DNS query could fail or return no results if we are
 * unable to discover the primary domain of the system.
 * HSP *sp used to update the min TTL for DNS entries so that the
 * next DNS request can be scheduled.
 * HSPSFlowSettings *settings in which sFlow collector addresses and ports
 * and sampling and polling settings will be populated.
 * Returns the number of sFlow collectors discovered or -1 on failure.
 */
int dnsSD(HSP *sp, HSPSFlowSettings *settings)
{
    char request[HSP_MAX_DNS_LEN];
	if (sp->DNSSD_domain) {
		sprintf_s(request, HSP_MAX_DNS_LEN, "%s%s", SFLOW_DNS_SD, sp->DNSSD_domain);
	} else {
		char domain[MAX_HOSTNAME_LEN];
		memset(domain, 0, MAX_HOSTNAME_LEN);
		DWORD len = MAX_HOSTNAME_LEN;
		char *dot = "";
		if (GetComputerNameEx(ComputerNameDnsDomain, domain, &len) == 0) {
			DWORD err = GetLastError();
			logErr(LOG_ERR, err, "dnsSD: cannot determined DNS domain for this computer error=%u", err);
		} else if (len == 0) {
			myLog(LOG_ERR, "dnsSD: DNS domain for this computer not set");
		} else {
			dot = ".";
		}
		sprintf_s(request, HSP_MAX_DNS_LEN, "%s%s%s", SFLOW_DNS_SD, dot, domain);
	}
	myLog(LOG_INFO, "dnsSD: request=%s", request);
    int num_servers = dnsSD_Request(sp, settings, request, DNS_TYPE_SRV);
    dnsSD_Request(sp, settings, request, DNS_TYPE_TEXT);
    // it's ok even if only the SRV request succeeded
    return num_servers; //  -1 on error
}
예제 #5
0
/* Use this function for debugging purpose */
void printAdjList(AdjList *pstAdjList)
{
	int i;
	AdjList *pstTmpList = NULL_PTR, *pstTmpList2 = NULL_PTR;

	if (NULL_PTR == pstAdjList)
	{
		myLog(ERROR, "Invalid Input!");
		return;
	}
	
	myLog(DEBUG, "Printing Adjacency List:");
	pstTmpList = pstAdjList;

	for (i = 0; i < gNoOfVertex; i++)
	{
		pstTmpList2 = pstTmpList;

		while (pstTmpList2)
		{
			printf("(%d, %d) = %d\n",
				pstTmpList->vertexNum, pstTmpList2->vertexNum, pstTmpList2->distance);
			pstTmpList2 = pstTmpList2->next;
		}

		pstTmpList++;
	}
}
예제 #6
0
/**
 * Initialises the sFlow filter device for receiving packet samples.
 */
void openFilter(HSP *sp)
{
	sp->filter.dev = INVALID_HANDLE_VALUE;
	// Open the device
    sp->filter.dev = CreateFileW(SFLOW_FILTER_DEVICE, GENERIC_READ, FILE_SHARE_READ, 
		                         NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	if (sp->filter.dev == INVALID_HANDLE_VALUE) {
		DWORD error = GetLastError();
		if (error == ERROR_FILE_NOT_FOUND) {
			 myLog(LOG_ERR, "openFilter: sFlow Hyper-V switch extension not found (Windows Server 2012 Hyper-V not running or sFlow extension not installed). Monitoring host performance only");
		} else {
			myLog(LOG_ERR, "openFilter: could not open device file %S: %ld. Monitoring host performance only.", 
				  SFLOW_FILTER_DEVICE, error);
		}
	} else {
		myLog(debug, "openFilter: attached to sFlow Hyper-V Switch extension");
		//Create the ioctl overlaps for communication with the device
		sp->filter.ioctlOverlap.Internal = 0;
		sp->filter.ioctlOverlap.InternalHigh = 0;
		sp->filter.ioctlOverlap.Pointer = NULL;
		sp->filter.ioctlOverlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

		createOverlaps(sp);
		if (queueReads(sp) != 0) {
			CloseHandle(sp->filter.dev);
			sp->filter.dev = INVALID_HANDLE_VALUE;
			myLog(LOG_ERR, "openFilter: could not queue initial read requests");
		} else {
			setFilterSamplingParams(sp);
		}
	}
}
예제 #7
0
/*________________---------------------------__________________
  ________________      readVLAN             __________________
  ----------------___________________________------------------

Rejected this way of looking up the VLAN because is was not
portable back to Linux 2.4 kernels,  and because the /proc/net/vlan
approach seemed more stable and portable.
*/
  int32_t readVLAN(char *devName, int fd)
  {
    // check in case it is just a sub-interface with a VLAN tag
    // that we should ignore to avoid double-counting.  We'll still
    // allow it through in case we are doing ULOG sampling and we
    // want to record flows/counters against this interface.
    int32_t vlan = HSP_VLAN_ALL;
    // for some reason if_vlan.h has only 24 characters set aside
    // for the device name, and no #define to capture that (like
    // IFNAMSIZ above)
#define HSP_VLAN_IFNAMSIZ 24
    if(my_strlen(devName) < HSP_VLAN_IFNAMSIZ) {
      struct vlan_ioctl_args vlargs;
      vlargs.cmd = GET_VLAN_VID_CMD;
      strcpy(vlargs.device1, devName);
      if(ioctl(fd, SIOCGIFVLAN, &vlargs) != 0) {
	if(debug) {
	  myLog(LOG_ERR, "device %s Get SIOCGIFVLAN failed : %s",
		devName,
		strerror(errno));
	}
      }
      else {
	vlan = vlargs.u.VID;
	if(debug) {
	  myLog(LOG_INFO, "device %s is vlan interface for vlan %u",
		devName,
		vlan);
	}
      }
    }
    return vlan;
  }
예제 #8
0
 int readMacAddress(char *devName, u_char *buf, int bufLen) {
   // we can only call dlpi_open() with root privileges.  So only try to get
   // the MAC address if we are still root.  We could cache the dlpi handle
   // for each interface as another field in the adaptorNIO structure, but in
   // practice it seems unlikely that the MAC address will change without
   // a reboot of the host,  so it's OK to only read it at the start.  If a
   // new interface somehow appears then it will just be instantiated without
   // a MAC.
   if(getuid() != 0) {
     return NO;
   }
   
   int macaddrlen = DLPI_PHYSADDR_MAX;
   int copied = 0;
   char macaddr[DLPI_PHYSADDR_MAX];
   dlpi_handle_t dh;
   if (DLPI_SUCCESS != dlpi_open(devName, &dh, 0)) {
     myLog(LOG_ERR, "device %s dlpi_open failed : %s", devName, strerror(errno));
     return 0;
   }
   // opened OK
   if (DLPI_SUCCESS != dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, macaddr, &macaddrlen)) {
     myLog(LOG_ERR, "device %s dlpi_get_physaddr failed :%s", devName, strerror(errno));
   }
   if(macaddrlen <= bufLen) {
     memcpy(buf, macaddr, macaddrlen);
     copied = macaddrlen;
   }
   dlpi_close(dh);
   return copied;
 }
예제 #9
0
  static int xenstat_dsk(HSP *sp, uint32_t dom_id, SFLHost_vrt_dsk_counters *dsk)
  {
    // [ref xenstat_linux.c]
#define SYSFS_VBD_PATH "/sys/devices/xen-backend/"
    DIR *sysfsvbd = opendir(SYSFS_VBD_PATH);
    if(sysfsvbd == NULL) {
      myLog(LOG_ERR, "opendir %s failed : %s", SYSFS_VBD_PATH, strerror(errno));
      return NO;
    }

    char scratch[sizeof(struct dirent) + _POSIX_PATH_MAX];
    struct dirent *dp = NULL;
    for(;;) {
      readdir_r(sysfsvbd, (struct dirent *)scratch, &dp);
      if(dp == NULL) break;
      uint32_t vbd_dom_id;
      uint32_t vbd_dev;
      char vbd_type[256];
      if(sscanf(dp->d_name, "%3s-%u-%u", vbd_type, &vbd_dom_id, &vbd_dev) == 3) {
	if(vbd_dom_id == dom_id) {
	  //dsk->capacity $$$
	  //dsk->allocation $$$
	  //dsk->available $$$
	  if(debug > 1) myLog(LOG_INFO, "reading VBD %s for dom_id %u", dp->d_name, dom_id); 
	  dsk->rd_req += xen_vbd_counter(vbd_type, dom_id, vbd_dev, "rd_req");
	  dsk->rd_bytes += (xen_vbd_counter(vbd_type, dom_id, vbd_dev, "rd_sect") * HSP_SECTOR_BYTES);
	  dsk->wr_req += xen_vbd_counter(vbd_type, dom_id, vbd_dev, "wr_req");
	  dsk->wr_bytes += (xen_vbd_counter(vbd_type, dom_id, vbd_dev, "wr_sect") * HSP_SECTOR_BYTES);
	  dsk->errs += xen_vbd_counter(vbd_type, dom_id, vbd_dev, "oo_req");
	}
      }
    }
    closedir(sysfsvbd);
    return YES;
  }
예제 #10
0
파일: dnsSD.c 프로젝트: wuhongyang/iass-web
/**
 * Issues the DNS request to discover the sFlow service settings
 * (collector addresses and ports, sampling rates and polling intervals).
 * The DNS request is configured to bypass the DNS cache and go straight
 * to the wire to avoid using stale entries.
 * If the request succeeds, updates the min TTL in HSP *sp, parses the response,
 * and returns the number of records returned, populating HSPSFlowSettings *settings
 * with the parsed result.
 * If the request fails, returns -1.
 * char *dname contains the DNS query (fully qualified)
 * WORD dtype the DNS query type (SRV for collectors or TEXT for sampling rates
 * and polling intervals)
 * Note that we are using the DnsQuery function to make the DNS request.
 * This function does not take into account the system DNS search path, so the
 * DNS query must be fully qualified (ie include the domain to search).
 */
static int dnsSD_Request(HSP *sp, HSPSFlowSettings *settings,
						 char *dname, WORD rtype)
{
	PDNS_RECORD pDnsRecord;
	DNS_FREE_TYPE dnsFreeType;
	dnsFreeType = DnsFreeRecordListDeep;
	DNS_STATUS status = DnsQuery(dname, rtype, DNS_QUERY_WIRE_ONLY, NULL, &pDnsRecord, NULL);
	if (status) {
		//fail
		logErr(LOG_ERR, status, "dnsSD_Request: DNSQuery(%s, %u) failed error=%u", dname, rtype, status);
		return -1;
	} else {
		 //process results and free
		int answerCount = 0;
		PDNS_RECORD nextRecord = pDnsRecord;
		while (nextRecord != NULL) {
			//update the minimum ttl
			DWORD ttl = nextRecord->dwTtl;
			if (sp->DNSSD_ttl == 0 || ttl < sp->DNSSD_ttl) {
				sp->DNSSD_ttl = ttl;
			}
			switch(rtype) {
			case DNS_TYPE_TEXT:
				if (nextRecord->wType == DNS_TYPE_TEXT) {
					answerCount++;
					DWORD stringCount = nextRecord->Data.TXT.dwStringCount;
					for (DWORD i = 0; i < stringCount; i++) {
						if (LOG_INFO <= debug) {
							myLog(LOG_INFO, "dnsDS_Request: DNS_TYPE_TEXT %s",
								nextRecord->Data.TXT.pStringArray[i]);
						}
						dnsSD_parseTxt(settings,
									   nextRecord->Data.TXT.pStringArray[i]);
					}
				}
				break;
			case DNS_TYPE_SRV:
				if (nextRecord->wType == DNS_TYPE_SRV) {
					answerCount++;
					if (LOG_INFO <= debug) {
						myLog(LOG_INFO, "dnsDS_Request: DNS_TYPE_SRV %s %u",
							nextRecord->Data.SRV.pNameTarget, nextRecord->Data.SRV.wPort);
					}
					insertCollector(settings, nextRecord->Data.SRV.pNameTarget, 
						nextRecord->Data.SRV.wPort);
				}
				break;
			default:
				DnsRecordListFree(pDnsRecord, dnsFreeType);
				myLog(LOG_ERR, "dnsDS_Request: unsupported query type %u", rtype);
				return -1;
			}
			nextRecord = nextRecord->pNext;
		}
		DnsRecordListFree(pDnsRecord, dnsFreeType);
		return answerCount;
	}
}
예제 #11
0
파일: util.c 프로젝트: cordellia/host-sflow
 void *my_os_realloc(void *ptr, size_t bytes)
 {
   myLog(LOG_INFO, "my_os_realloc(%u)", bytes);
   void *mem = SYS_REALLOC(ptr, bytes);
   if(mem == NULL) {
     myLog(LOG_ERR, "realloc() failed : %s", strerror(errno));
     exit(EXIT_FAILURE);
   }
   return mem;
 }
예제 #12
0
  static int parseOrResolveAddress(char *name, struct sockaddr *sa, SFLAddress *addr, int family, int numeric)
  {
    struct addrinfo *info = NULL;
    struct addrinfo hints = { 0 };
    hints.ai_socktype = SOCK_DGRAM; // constrain this so we don't get lots of answers
    hints.ai_family = family; // PF_INET, PF_INET6 or 0
    if(numeric) {
      hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
    }
    int err = getaddrinfo(name, NULL, &hints, &info);
    if(err) {
      if(debug) myLog(LOG_INFO, "getaddrinfo() failed: %s", gai_strerror(err));
      switch(err) {
      case EAI_NONAME: break;
      case EAI_NODATA: break;
      case EAI_AGAIN: break; // loop and try again?
      default: myLog(LOG_ERR, "getaddrinfo() error: %s", gai_strerror(err)); break;
      }
      return NO;
    }
  
    if(info == NULL) return NO;
  
    if(info->ai_addr) {
      // answer is now in info - a linked list of answers with sockaddr values.
      // extract the address we want from the first one. $$$ should perhaps
      // traverse the list and look for an IPv4 address since that is more
      // likely to work?
      switch(info->ai_family) {
      case PF_INET:
	{
	  struct sockaddr_in *ipsoc = (struct sockaddr_in *)info->ai_addr;
	  addr->type = SFLADDRESSTYPE_IP_V4;
	  addr->address.ip_v4.addr = ipsoc->sin_addr.s_addr;
	  if(sa) memcpy(sa, info->ai_addr, info->ai_addrlen);
	}
	break;
      case PF_INET6:
	{
	  struct sockaddr_in6 *ip6soc = (struct sockaddr_in6 *)info->ai_addr;
	  addr->type = SFLADDRESSTYPE_IP_V6;
	  memcpy(&addr->address.ip_v6, &ip6soc->sin6_addr, 16);
	  if(sa) memcpy(sa, info->ai_addr, info->ai_addrlen);
	}
	break;
      default:
	myLog(LOG_ERR, "get addrinfo: unexpected address family: %d", info->ai_family);
	return NO;
	break;
      }
    }
    // free the dynamically allocated data before returning
    freeaddrinfo(info);
    return YES;
  }
예제 #13
0
  int readNioCounters(SFLHost_nio_counters *nio, char *devFilter) {
    int interface_count = 0;

    int mib[]={ CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
    size_t needed=0;
    if(sysctl(mib, 6, NULL, &needed, NULL, 0) != 0) {
      myLog(LOG_ERR, "sysctl(<NioCounters>) probe failed : %s", strerror(errno));
      return NO;
    }
    char *buf = (char*)my_calloc(needed);
    if (sysctl(mib, 6, buf, &needed, NULL, 0) != 0) {
      myLog(LOG_ERR, "sysctl(<NioCounters>) read failed : %s", strerror(errno));
      return NO;
    }
    char *end = buf + needed;
    for(char *p = buf; p < end; ) {
      struct if_msghdr *ifm = (struct if_msghdr *)p;
      if(ifm->ifm_type != RTM_IFINFO) {
	myLog(LOG_ERR, "sysctl(<NioCounters>) walk failed (offset=%d of %d)", p - buf, needed);
	return NO;
      }
      p += ifm->ifm_msglen;

      // consume the RTM_NEWADDR msgs that follow
      while(p < end) {
	struct if_msghdr *nextifm = (struct if_msghdr *)p;
	if(nextifm->ifm_type != RTM_NEWADDR) break;
	p += nextifm->ifm_msglen;
      }

      // ignore loopback interfaces and interfaces that are currently down
      if(ifm->ifm_flags & IFF_LOOPBACK) continue;
      if(!(ifm->ifm_flags & IFF_UP)) continue;

      // $$$ test the device filter - is the device name known here?
      // may need to get the ifindex with ifm->ifm_index and then look up
      // the name from there - or go the other way and make the filter be
      // a filter on ifindex.

      interface_count++;
      // report the sum over all devices
      nio->bytes_in += ifm->ifm_data.ifi_ibytes;
      nio->pkts_in += ifm->ifm_data.ifi_ipackets;
      nio->errs_in += ifm->ifm_data.ifi_ierrors;
      nio->drops_in += ifm->ifm_data.ifi_iqdrops;
      nio->bytes_out += ifm->ifm_data.ifi_obytes;
      nio->pkts_out += ifm->ifm_data.ifi_opackets;
      nio->errs_out += ifm->ifm_data.ifi_oerrors;
      // nio->drops_out += ifm->ifm_data.ifi_oqdrops;
      
    }
    free(buf);
    return interface_count;
  }
예제 #14
0
 void *my_os_calloc(size_t bytes)
 {
   if(debug) myLog(LOG_INFO, "my_os_calloc(%u)", bytes);
   void *mem = SYS_CALLOC(1, bytes);
   if(mem == NULL) {
     myLog(LOG_ERR, "calloc() failed : %s", strerror(errno));
     //if(debug) malloc_stats();
     exit(EXIT_FAILURE);
   }
   return mem;
 }
예제 #15
0
static void logSFlowSettings(HSPSFlow *sFlow)
{
	HSPSFlowSettings *settings = sFlow->sFlowSettings;
	char agentAddr[255];
	addrToStr(&sFlow->agentIP, agentAddr, 255);
	myLog(debug, "sFlow configuration agent=%s serialNumber=%u: pollingInterval=%u, samplingRate=%u", 
		  agentAddr, settings->serialNumber, settings->pollingInterval, settings->samplingRate);
	for (HSPCollector *collector= settings->collectors;
		collector; collector = collector->nxt) {
		myLog(debug, "collector=%s:%u", collector->name, collector->udpPort);
	}
}
예제 #16
0
int truncateOpenFile(FILE *fptr)
{
    int fd = fileno(fptr);
    if(fd == -1) {
        myLog(LOG_ERR, "truncateOpenFile(): fileno() failed : %s", strerror(errno));
        return NO;
    }
    if(ftruncate(fd, lseek(fd, 0, SEEK_CUR)) != 0) {
        myLog(LOG_ERR, "truncateOpenFile(): ftruncate() failed : %s", strerror(errno));
        return NO;
    }
    return YES;
}
예제 #17
0
  static  uint32_t  getRunningProcesses( void )
  {
    struct kinfo_proc *kp;
    int i;
    int state;
    int nentries;
    kvm_t *kd = NULL;
    int what = KERN_PROC_ALL;
    
    uint32_t val32;
    
    val32 = 0;
    
    // it looks like we don't need to be root to call kvm_open
    // just to read the process table (in the way that the ps(1) command does).
    kd=kvm_open("/dev/null", "/dev/null", "/dev/null", O_RDONLY, "kvm_open");
    if (kd == NULL) {
      myLog(LOG_ERR, "kvm_open() failed");
    }
    else {
      
#ifdef KERN_PROC_NOTHREADS
      what |= KERN_PROC_NOTHREADS;
#endif
      
      if ((kp = kvm_getprocs(kd, what, 0, &nentries)) == 0 || nentries < 0) {
	myLog(LOG_ERR, "kvm_getprocs() failed");
      }
      else {
	if(debug) myLog(LOG_INFO,"kvm_getprocs found %u entries", nentries);
	
	for (i = 0; i < nentries; kp++, i++) {
#ifdef KINFO_PROC_SIZE
	  state = kp->ki_stat;
#else
	  state = kp->kp_proc.p_stat;
#endif
	  switch(state) {
	  case SRUN:
	  case SIDL:
	    val32++;
	    break;
	  }
	}
      }
      kvm_close(kd);
    }
    
    if (val32 > 0) val32--; // subtract one for me
    return val32;
  }
예제 #18
0
/**
 * Test to see whether we are running on a system with Hyper-V enabled.
 * We consider Hyper-V to be running (and can export per vm stats) if
 * the Hyper-V related services (nvspwmi, vmm, vhdsvc) are running and
 * we can access the WMI namespace root\virtualization (ie v1 for Win 2008).
 * We do not check for the v2 namespace, since this is not required for 
 * per vm stats.
 * The ability connect to the sFlow filter for export of packet samples 
 * and counter samples for the virtual switch is made separately.
 */
BOOL testForHyperv()
{
	BSTR path = SysAllocString(WMI_CIMV2_NS);
	HRESULT hr = S_FALSE;
	IWbemServices *pNamespace = NULL;

	hr = connectToWMI(path, &pNamespace);
	SysFreeString(path);
	if (WBEM_S_NO_ERROR != hr) {
		myLog(LOG_ERR,"testForHyperv: connectToWMI failed for namespace %S", path);
		return false;
	}
	//Test for Hyper-V services
	BOOL gotHyperV = false;
	BSTR queryLang = SysAllocString(L"WQL");
	BSTR query = SysAllocString(L"SELECT * FROM Win32_Service WHERE Name=\"nvspwmi\" OR Name=\"vmms\" OR Name=\"vhdsvc\"");
	IEnumWbemClassObject *serviceEnum = NULL;
	hr = pNamespace->ExecQuery(queryLang, query, WBEM_FLAG_FORWARD_ONLY, NULL, &serviceEnum);
	SysFreeString(query);
	SysFreeString(queryLang);
	if (WBEM_S_NO_ERROR != hr) {
		myLog(LOG_ERR, "testForHyperv: ExecQuery() failed for %S error=0x%x", query, hr);
	} else {
		IWbemClassObject *serviceObj = NULL;
		ULONG uReturned = 0;
		BOOL gotHyperVSvc = false;
		hr = serviceEnum->Next(WBEM_INFINITE, 1, &serviceObj, &uReturned);
		if (SUCCEEDED(hr)) {
			if (uReturned == 1) {
				gotHyperVSvc = true;
				serviceObj->Release();
			}
		}
		serviceEnum->Release();
		pNamespace->Release();
		if (gotHyperVSvc) { //now check that we have the v1 virtualization namespace
			CoUninitialize();
			path = SysAllocString(WMI_VIRTUALIZATION_NS_V1);
			hr = connectToWMI(path, &pNamespace);
			SysFreeString(path);
			if (WBEM_NO_ERROR == hr) {
				gotHyperV = true;
				pNamespace->Release();
			}
		}
	}
	CoUninitialize();
	myLog(LOG_INFO, "testForHyperv: HyperV=%u", gotHyperV);
	return gotHyperV;
}
예제 #19
0
  int lookupAddress(char *name, struct sockaddr *sa, SFLAddress *addr, int family)
  {
    struct addrinfo *info = NULL;
    struct addrinfo hints = { 0 };
    hints.ai_socktype = SOCK_DGRAM; // constrain this so we don't get lots of answers
    hints.ai_family = family; // PF_INET, PF_INET6 or 0
    int err = getaddrinfo(name, NULL, &hints, &info);
    if(err) {
      switch(err) {
      case EAI_NONAME: break;
      case EAI_NODATA: break;
      case EAI_AGAIN: break; // loop and try again?
      default: myLog(LOG_ERR, "getaddrinfo() error: %s", gai_strerror(err)); break;
      }
      return NO;
    }
  
    if(info == NULL) return NO;
  
    if(info->ai_addr) {
      // answer is now in info - a linked list of answers with sockaddr values.
      // extract the address we want from the first one.
      switch(info->ai_family) {
      case PF_INET:
	{
	  struct sockaddr_in *ipsoc = (struct sockaddr_in *)info->ai_addr;
	  addr->type = SFLADDRESSTYPE_IP_V4;
	  addr->address.ip_v4.addr = ipsoc->sin_addr.s_addr;
	  if(sa) memcpy(sa, info->ai_addr, info->ai_addrlen);
	}
	break;
      case PF_INET6:
	{
	  struct sockaddr_in6 *ip6soc = (struct sockaddr_in6 *)info->ai_addr;
	  addr->type = SFLADDRESSTYPE_IP_V6;
	  memcpy(&addr->address.ip_v6, &ip6soc->sin6_addr, 16);
	  if(sa) memcpy(sa, info->ai_addr, info->ai_addrlen);
	}
	break;
      default:
	myLog(LOG_ERR, "get addrinfo: unexpected address family: %d", info->ai_family);
	return NO;
	break;
      }
    }
    // free the dynamically allocated data before returning
    freeaddrinfo(info);
    return YES;
  }
예제 #20
0
/**
 * Populates the host_memory structure using data retrieved using
 * GlobalMemoryStatusEx function and the Memory performance counter
 * object.
 * Returns FALSE if call to GlobalMemoryStatusEx produces an error, TRUE otherwise.
 * Note that the Windows use of memory and classification of use does
 * not map cleanly to Linux terms.
 * Windows Resource Monitor reports cached as Standby+Modified this is not the
 * equivalent of Linux file system cache, however it could be viewed as
 * analagous memory usage, and it makes sense to retain some consistency with
 * Windows tools.
 * Windows Resource Monitor reports free memory as free and zero page list bytes,
 * this is used for free memory. There are no obvious equivalents for shared
 * and buffers so these counters are reported as unknown.
 * Windows also does not seem to report swapping (all memory associated with a process
 * swapped in/out of memory). Memory\\Pages Input/sec and Memory\\Pages Output/sec
 * are used for page_in and page_out.
 */
BOOL readMemoryCounters(SFLHost_mem_counters *mem) 
{
	MEMORYSTATUSEX memStat;
	memStat.dwLength = sizeof(memStat);
	if (GlobalMemoryStatusEx(&memStat) == 0){
		myLog(LOG_ERR,"GlobalMemoryStatusEx failed: %d\n",GetLastError());
		return FALSE;
	}
	mem->mem_total = memStat.ullTotalPhys;
	mem->swap_total = memStat.ullTotalPageFile;
	mem->swap_free = memStat.ullAvailPageFile;
	PDH_HQUERY query;
	if (PdhOpenQuery(NULL, 0, &query) == ERROR_SUCCESS) {
		PDH_HCOUNTER free, standbyCore, standbyNormal, standbyReserve, modified, pageIn, pageOut;
		if (addCounterToQuery(MEM_COUNTER_OBJECT, NULL, MEM_COUNTER_FREE, &query, &free) == ERROR_SUCCESS &&
			addCounterToQuery(MEM_COUNTER_OBJECT, NULL, MEM_COUNTER_STANDBY_CORE, &query, &standbyCore) == ERROR_SUCCESS &&
			addCounterToQuery(MEM_COUNTER_OBJECT, NULL, MEM_COUNTER_STANDBY_NORMAL, &query, &standbyNormal) == ERROR_SUCCESS &&
			addCounterToQuery(MEM_COUNTER_OBJECT, NULL, MEM_COUNTER_STANDBY_RESERVE, &query, &standbyReserve) == ERROR_SUCCESS &&
			addCounterToQuery(MEM_COUNTER_OBJECT, NULL, MEM_COUNTER_MODIFIED, &query, &modified) == ERROR_SUCCESS &&
			addCounterToQuery(MEM_COUNTER_OBJECT, NULL, MEM_COUNTER_PAGE_IN, &query, &pageIn) == ERROR_SUCCESS &&
			addCounterToQuery(MEM_COUNTER_OBJECT, NULL, MEM_COUNTER_PAGE_OUT, &query, &pageOut) == ERROR_SUCCESS &&
			PdhCollectQueryData(query) == ERROR_SUCCESS) {
			mem->mem_free = getRawCounterValue(&free);
			mem->mem_cached = getRawCounterValue(&standbyCore) +
				getRawCounterValue(&standbyNormal) +
				getRawCounterValue(&standbyReserve) +
				getRawCounterValue(&modified);
			mem->page_in = (uint32_t)getRawCounterValue(&pageIn);
			mem->page_out = (uint32_t)getRawCounterValue(&pageOut);
		}
		PdhCloseQuery(query);
	}

	//There are no obvious Windows equivalents
    mem->mem_shared = UNKNOWN_GAUGE_64;
	mem->mem_buffers = UNKNOWN_GAUGE_64;
	//using the definition that swapping is when all the memory associated with a
	//process is moved in/out of RAM
	mem->swap_in = UNKNOWN_COUNTER;
	mem->swap_out = UNKNOWN_COUNTER;
	myLog(LOG_INFO,
		"readMemoryCounters:\n\ttotal: \t\t%I64d\n\tfree: \t\t%I64d\n"
		"\tcached: \t%I64d\n\tpage_in: \t%d\n\tpage_out: \t%d\n"
		"\tswap_total: \t%I64d\n\tswap_free: \t%I64d\n",
		mem->mem_total, mem->mem_free,
		mem->mem_cached, mem->page_in, mem->page_out,
		mem->swap_total, mem->swap_free);
	return TRUE;
}
예제 #21
0
  int selectAgentAddress(HSP *sp) {

    if(debug) myLog(LOG_INFO, "selectAgentAddress");

    if(sp->sFlow->explicitAgentIP && sp->sFlow->agentIP.type) {
      // it was hard-coded in the config file
      if(debug) myLog(LOG_INFO, "selectAgentAddress hard-coded in config file");
      return YES;
    }
    
    // it may have been defined as agent=<device>
    if(sp->sFlow->explicitAgentDevice && sp->sFlow->agentDevice) {
      SFLAdaptor *ad = adaptorListGet(sp->adaptorList, sp->sFlow->agentDevice);
      if(ad && ad->userData) {
	HSPAdaptorNIO *adaptorNIO = (HSPAdaptorNIO *)ad->userData;
	sp->sFlow->agentIP = adaptorNIO->ipAddr;
	if(debug) myLog(LOG_INFO, "selectAgentAddress pegged to device in config file");
	return YES;
      }
    }

    // try to automatically choose an IP (or IPv6) address,  based on the priority ranking.
    // We already used this ranking to prioritize L3 addresses per adaptor (in the case where
    // there are more than one) so now we are applying the same ranking globally to pick
    // the best candidate to represent the whole agent:
    SFLAdaptor *selectedAdaptor = NULL;
    EnumIPSelectionPriority ipPriority = IPSP_NONE;

    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;
	if(adaptorNIO->ipPriority > ipPriority) {
	  selectedAdaptor = adaptor;
	  ipPriority = adaptorNIO->ipPriority;
	}
      }	    
    }
    if(selectedAdaptor && selectedAdaptor->userData) {
      // crown the winner
      HSPAdaptorNIO *adaptorNIO = (HSPAdaptorNIO *)selectedAdaptor->userData;
      sp->sFlow->agentIP = adaptorNIO->ipAddr;
      sp->sFlow->agentDevice = my_strdup(selectedAdaptor->deviceName);
      if(debug) myLog(LOG_INFO, "selectAgentAddress selected agentIP with highest priority");
      return YES;
    }
    
    return NO;
  }
예제 #22
0
  static void agentCB_sendPkt(void *magic, SFLAgent *agent, SFLReceiver *receiver, u_char *pkt, uint32_t pktLen)
  {
    HSP *sp = (HSP *)magic;
    size_t socklen = 0;
    int fd = 0;

    for(HSPCollector *coll = sp->sFlow->sFlowSettings->collectors; coll; coll=coll->nxt) {

      switch(coll->ipAddr.type) {
      case SFLADDRESSTYPE_UNDEFINED:
	// skip over it if the forward lookup failed
	break;
      case SFLADDRESSTYPE_IP_V4:
	{
	  struct sockaddr_in *sa = (struct sockaddr_in *)&(coll->sendSocketAddr);
	  socklen = sizeof(struct sockaddr_in);
	  sa->sin_family = AF_INET;
	  sa->sin_port = htons(coll->udpPort);
	  fd = sp->socket4;
	}
	break;
      case SFLADDRESSTYPE_IP_V6:
	{
	  struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&(coll->sendSocketAddr);
	  socklen = sizeof(struct sockaddr_in6);
	  sa6->sin6_family = AF_INET6;
	  sa6->sin6_port = htons(coll->udpPort);
	  fd = sp->socket6;
	}
	break;
      }

      if(socklen && fd > 0) {
	int result = sendto(fd,
			    pkt,
			    pktLen,
			    0,
			    (struct sockaddr *)&coll->sendSocketAddr,
			    socklen);
	if(result == -1 && errno != EINTR) {
	  myLog(LOG_ERR, "socket sendto error: %s", strerror(errno));
	}
	if(result == 0) {
	  myLog(LOG_ERR, "socket sendto returned 0: %s", strerror(errno));
	}
      }
    }
  }
예제 #23
0
  void readVLANs(HSP *sp)
  {
    // mark interfaces that are specific to a VLAN
    FILE *procFile = fopen("/proc/net/vlan/config", "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 "<device> VID: <vlan> ..."
	// (with a header line on the first row)
	char devName[MAX_PROC_LINE_CHARS];
	int vlan;
	++lineNo;
	if(lineNo > 1 && sscanf(line, "%s | %d", devName, &vlan) == 2) {
	  SFLAdaptor *adaptor = adaptorListGet(sp->adaptorList, trimWhitespace(devName));
	  if(adaptor && adaptor->userData &&
	     vlan >= 0 && vlan < 4096) {
	    HSPAdaptorNIO *niostate = (HSPAdaptorNIO *)adaptor->userData;
	    niostate->vlan = vlan;
	    if(debug) myLog(LOG_INFO, "adaptor %s has 802.1Q vlan %d", devName, vlan);
	  }
	}
      }
      fclose(procFile);
    }
  }
예제 #24
0
/* Returns a pointer to an array which is the starting of adjList */
AdjList* initAdjList()
{
	AdjList *pstAdjList = NULL_PTR;
	int i, size;

	size = gNoOfVertex;

	/*Allocate the size of the array. Each array index will maintain a list
		If 2 is connected to 5 with edge weight 10,
		at piAdjList[1], next will point to a node whose vertextNum
		is 5 and distance is 10. */
	pstAdjList = (AdjList *) malloc(sizeof(AdjList)*size);

	/* If memory was allocted */
	if (NULL_PTR == pstAdjList)
	{
		myLog(ERROR, "malloc failed!");
		return NULL_PTR;
	}
	
	/* Initialize */
	for (i = 0; i < size; i++)
	{
		pstAdjList[i].vertexNum = i;
		pstAdjList[i].distance  = 0;
		pstAdjList[i].next = NULL_PTR;
	}

	return pstAdjList;
}
예제 #25
0
ULONG_PTR setFilterSamplingParams(HSP *sp)
{
	BOOLEAN ioctlSuccess;
	uint32_t tries = 0;
	ULONG_PTR error = ERROR_SUCCESS;
	SFlowConfiguration sFlowConfig; 
	sFlowConfig.sampleRate = sp->sFlow->sFlowSettings->samplingRate;
	sFlowConfig.sampleHeaderLength = sp->sFlow->sFlowSettings->headerBytes;
	do {
		ioctlSuccess = DeviceIoControl(sp->filter.dev, 
									   IOCTL_SFLOW_CONFIGURE,
                                       &sFlowConfig, sizeof(SFlowConfiguration), 
									   NULL, 0,
                                       NULL, &sp->filter.ioctlOverlap);
        if (!ioctlSuccess) {
			error = GetLastError();
			if (error == ERROR_IO_PENDING) {
				// I/O pending, wait for completion
				if (WaitForSingleObject(sp->filter.ioctlOverlap.hEvent, INFINITE) == WAIT_OBJECT_0) {
					error = sp->filter.ioctlOverlap.Internal;
				}
			}
        }
		tries++;
	} while (tries < 10 && error == ERROR_GEN_FAILURE);
	if (tries >= 10 || error == ERROR_GEN_FAILURE) {
		myLog(LOG_ERR, "SetFilterSamplerSettings: failed");
	}
	return error;
}
예제 #26
0
/* Deallocates memory used by the adj list */
void destroyAdjList(AdjList *pstAdjList)
{
	int i, j;
	AdjList *pstTraverser = NULL_PTR, *pstTmp = NULL_PTR;
	
	if (NULL_PTR == pstAdjList)
	{
		myLog(ERROR, "Invalid Input!");
		return;
	}
	
	for (i = 0; i < gNoOfVertex; i++)
	{
		pstTraverser = &(pstAdjList[i]);
		
		/* Delete the horizontal lists */
		while (NULL_PTR != pstTraverser->next)
		{
			pstTmp = pstTraverser->next;
			pstTraverser->next = pstTmp->next;
			
			free(pstTmp);
			pstTmp = NULL_PTR;
		}
	}

	/* Delete the vertical list */
	free(pstAdjList);
	pstAdjList = NULL_PTR;
}
예제 #27
0
  static HSPToken *readTokens(HSP *sp)
  {
    FILE *cfg = NULL;
    if((cfg = fopen(sp->configFile, "r")) == NULL) {
      myLog(LOG_ERR,"cannot open config file %s : %s", sp->configFile, strerror(errno));
      return NULL;
    }

    // collect the tokens in a (reversed) list
    HSPToken *tokens = newToken("start", 5);
    char line[HSP_MAX_LINELEN];
    uint32_t lineNo = 0;
    while(fgets(line, HSP_MAX_LINELEN, cfg)) {
      lineNo++;
      char *p = line;
      // comments start with '#'
      p[strcspn(p, "#")] = '\0';
      HSPToken *tok;
      while((tok = nextToken(p, &p)) != NULL) {
	tok->lineNo = lineNo;
	ADD_TO_LIST(tokens, tok);
      }
    }
    fclose(cfg);

    // get them in the right order
    tokens = reverseTokens(tokens);

    return tokens;
  }
예제 #28
0
파일: mod_ovs.c 프로젝트: sflow/host-sflow
  static bool readConfig(EVMod *mod)  {
    HSP_mod_OVS *mdata = (HSP_mod_OVS *)mod->data;
    HSP *sp = (HSP *)EVROOTDATA(mod);

    resetConfig(&mdata->config);

    if(sp->sFlowSettings == NULL)
      return NO;

    mdata->config.sampling_n = sp->sFlowSettings->samplingRate;
    mdata->config.polling_secs = sp->actualPollingInterval;
    mdata->config.header_bytes = sp->sFlowSettings->headerBytes;
    char ipbuf[51];
    SFLAddress_print(&sp->agentIP, ipbuf, 50);
    setStr(&mdata->config.agent_ip, ipbuf);
    setStr(&mdata->config.agent_dev, sp->agentDevice);
    for(HSPCollector *coll = sp->sFlowSettings->collectors; coll; coll = coll->nxt) {
      if(mdata->config.num_collectors == SFVS_MAX_COLLECTORS) {
	myLog(LOG_ERR, "OVS: MAX collectors exceeded");
      }
      else {
	uint32_t i = mdata->config.num_collectors++;
	SFLAddress_print(&coll->ipAddr, ipbuf, 50);
	setStr(&mdata->config.collectors[i].ip, ipbuf);
	mdata->config.collectors[i].port = coll->udpPort;
	mdata->config.collectors[i].priority = 0;
      }
    }
    // turn the collectors list into the targets string
    formatTargets(mod);
    return YES;
  }
예제 #29
0
/**
 * Enumerates MSFT_NetIpAddress whose interface index is the same as the
 * adaptor's. Calls stringToAdaptorIP() for each object so that the
 * highest priority IP address is associated with the adaptor.
 */
static void readIpAddressesMsft(IWbemServices *pNamespace, SFLAdaptor *adaptor)
{
	BSTR queryLang = SysAllocString(L"WQL");
	wchar_t *query = L"SELECT * FROM MSFT_NetIpAddress WHERE InterfaceIndex=%u";
	wchar_t ipQuery[70];
	swprintf_s(ipQuery, 70, query, adaptor->ifIndex);
	IEnumWbemClassObject *ipEnum = NULL;
	HRESULT hr = pNamespace->ExecQuery(queryLang, ipQuery, WBEM_FLAG_FORWARD_ONLY, NULL, &ipEnum);
	SysFreeString(queryLang);
	if (!SUCCEEDED(hr)) {
		myLog(LOG_ERR,"readIpAddressesMsft: ExecQuery() failed for query %S error=0x%x", ipQuery, hr);
		return;
	}
	IWbemClassObject *ipObj;
	hr = WBEM_S_NO_ERROR;
	while (WBEM_S_NO_ERROR == hr) {
		ULONG ipCount = 0;
		hr = ipEnum->Next(WBEM_INFINITE, 1, &ipObj, &ipCount);
		if (ipCount == 0) {
			break;
		}
		VARIANT address;
		hr = ipObj->Get(L"IPAddress", 0, &address, 0, 0);
		if (WBEM_S_NO_ERROR == hr && V_VT(&address) == VT_BSTR)  {
			stringToAdaptorIp(address.bstrVal, adaptor);
		}
		VariantClear(&address);
		ipObj->Release();
	}
	ipEnum->Release();
}
예제 #30
0
void adaptorListFreeMarked(SFLAdaptorList *adList)
{
    uint32_t removed = 0;
    for(uint32_t i = 0; i < adList->num_adaptors; i++) {
        SFLAdaptor *ad = adList->adaptors[i];
        if(ad && ad->marked) {
            adaptorFree(ad);
            adList->adaptors[i] = NULL;
            removed++;
        }
    }
    if(removed > 0) {
        uint32_t found = 0;
        // now pack the array and update the num_adaptors count
        for(uint32_t i = 0; i < adList->num_adaptors; i++) {
            SFLAdaptor *ad = adList->adaptors[i];
            if(ad) adList->adaptors[found++] = ad;
        }
        // cross-check
        if((found + removed) != adList->num_adaptors) {
            myLog(LOG_ERR, "adaptorListFreeMarked: found(%u) + removed(%u) != num_adaptors(%u)",
                  found,
                  removed,
                  adList->num_adaptors);
        }
        adList->num_adaptors = found;
    }
}