Exemple #1
0
static int home_or_pro(const OSVERSIONINFOEX osinfo, char **name)
{
    int r;

    if (osinfo.wSuiteMask & VER_SUITE_PERSONAL) {
        r = sg_concat_string(name, " Home Edition");
    } else {
        r = sg_concat_string(name, " Professional");
    }
    return r;
}
sg_network_io_stats *sg_get_network_io_stats(int *entries){
	int interfaces;
	sg_network_io_stats *network_stat_ptr;

#ifdef SOLARIS
	kstat_ctl_t *kc;
	kstat_t *ksp;
	kstat_named_t *knp;
#endif

#ifdef LINUX
	FILE *f;
	/* Horrible big enough, but it should be easily big enough */
	char line[8096];
	regex_t regex;
	regmatch_t line_match[9];
#endif
#ifdef ALLBSD
	struct ifaddrs *net, *net_ptr;
	struct if_data *net_data;
#endif
#ifdef WIN32
	PMIB_IFTABLE if_table;
	MIB_IFROW if_row;
	int i, no, j;

	/* used for duplicate interface names. 5 for space, hash, up to two
	 * numbers and terminating slash */
	char buf[5];
#endif

#ifdef ALLBSD
	if(getifaddrs(&net) != 0){
		sg_set_error_with_errno(SG_ERROR_GETIFADDRS, NULL);
		return NULL;
	}

	interfaces=0;
	
	for(net_ptr=net;net_ptr!=NULL;net_ptr=net_ptr->ifa_next){
		if(net_ptr->ifa_addr->sa_family != AF_LINK) continue;

		if (VECTOR_RESIZE(network_stats, interfaces + 1) < 0) {
			return NULL;
		}
		network_stat_ptr=network_stats+interfaces;
		
		if (sg_update_string(&network_stat_ptr->interface_name,
				     net_ptr->ifa_name) < 0) {
			return NULL;
		}
		net_data=(struct if_data *)net_ptr->ifa_data;
		network_stat_ptr->rx=net_data->ifi_ibytes;
		network_stat_ptr->tx=net_data->ifi_obytes;
		network_stat_ptr->ipackets=net_data->ifi_ipackets;
		network_stat_ptr->opackets=net_data->ifi_opackets;
		network_stat_ptr->ierrors=net_data->ifi_ierrors;
		network_stat_ptr->oerrors=net_data->ifi_oerrors;
		network_stat_ptr->collisions=net_data->ifi_collisions;
		network_stat_ptr->systime=time(NULL);
		interfaces++;
	}
	freeifaddrs(net);	
#endif

#ifdef SOLARIS
	if ((kc = kstat_open()) == NULL) {
		sg_set_error(SG_ERROR_KSTAT_OPEN, NULL);
		return NULL;
	}

	interfaces=0;

	for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
		if (strcmp(ksp->ks_class, "net") == 0) {
			kstat_read(kc, ksp, NULL);

#ifdef SOL7
#define LRX "rbytes"
#define LTX "obytes"
#define LIPACKETS "ipackets"
#define LOPACKETS "opackets"
#define VALTYPE value.ui32
#else
#define LRX "rbytes64"
#define LTX "obytes64"
#define LIPACKETS "ipackets64"
#define LOPACKETS "opackets64"
#define VALTYPE value.ui64
#endif

			/* Read rx */
			if((knp=kstat_data_lookup(ksp, LRX))==NULL){
				/* This is a network interface, but it doesn't
				 * have the rbytes/obytes values; for instance,
				 * the loopback devices have this behaviour
				 * (although they do track packets in/out). */
				/* FIXME: Show packet counts when byte counts
				 * not available. */
				continue;
			}

			/* Create new network_stats */
			if (VECTOR_RESIZE(network_stats, interfaces + 1) < 0) {
				return NULL;
			}
			network_stat_ptr=network_stats+interfaces;

			/* Finish reading rx */
			network_stat_ptr->rx=knp->VALTYPE;

			/* Read tx */
			if((knp=kstat_data_lookup(ksp, LTX))==NULL){
				continue;
			}
			network_stat_ptr->tx=knp->VALTYPE;

			/* Read ipackets */
			if((knp=kstat_data_lookup(ksp, LIPACKETS))==NULL){
				continue;
			}
			network_stat_ptr->ipackets=knp->VALTYPE;

			/* Read opackets */
			if((knp=kstat_data_lookup(ksp, LOPACKETS))==NULL){
				continue;
			}
			network_stat_ptr->opackets=knp->VALTYPE;

			/* Read ierrors */
			if((knp=kstat_data_lookup(ksp, "ierrors"))==NULL){
				continue;
			}
			network_stat_ptr->ierrors=knp->value.ui32;

			/* Read oerrors */
			if((knp=kstat_data_lookup(ksp, "oerrors"))==NULL){
				continue;
			}
			network_stat_ptr->oerrors=knp->value.ui32;

			/* Read collisions */
			if((knp=kstat_data_lookup(ksp, "collisions"))==NULL){
				continue;
			}
			network_stat_ptr->collisions=knp->value.ui32;

			/* Read interface name */
			if (sg_update_string(&network_stat_ptr->interface_name,
					     ksp->ks_name) < 0) {
				return NULL;
			}

			/* Store systime */
			network_stat_ptr->systime=time(NULL);

			interfaces++;
		}
	}
		
	kstat_close(kc);	
#endif
#ifdef LINUX
	f=fopen("/proc/net/dev", "r");
	if(f==NULL){
		sg_set_error_with_errno(SG_ERROR_OPEN, "/proc/net/dev");
		return NULL;
	}
	/* read the 2 lines.. Its the title, so we dont care :) */
	fgets(line, sizeof(line), f);
	fgets(line, sizeof(line), f);


	if((regcomp(&regex, "^ *([^:]+): *([0-9]+) +([0-9]+) +([0-9]+) +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +([0-9]+) +([0-9]+) +([0-9]+) +[0-9]+ +[0-9]+ +([0-9]+)", REG_EXTENDED))!=0){
		sg_set_error(SG_ERROR_PARSE, NULL);
		return NULL;
	}

	interfaces=0;

	while((fgets(line, sizeof(line), f)) != NULL){
		if((regexec(&regex, line, 9, line_match, 0))!=0){
			continue;
		}

		if (VECTOR_RESIZE(network_stats, interfaces + 1) < 0) {
			return NULL;
		}
		network_stat_ptr=network_stats+interfaces;

		if(network_stat_ptr->interface_name!=NULL){
			free(network_stat_ptr->interface_name);
		}

		network_stat_ptr->interface_name=sg_get_string_match(line, &line_match[1]);
		network_stat_ptr->rx=sg_get_ll_match(line, &line_match[2]);
		network_stat_ptr->tx=sg_get_ll_match(line, &line_match[5]);
		network_stat_ptr->ipackets=sg_get_ll_match(line, &line_match[3]);
		network_stat_ptr->opackets=sg_get_ll_match(line, &line_match[6]);
		network_stat_ptr->ierrors=sg_get_ll_match(line, &line_match[4]);
		network_stat_ptr->oerrors=sg_get_ll_match(line, &line_match[7]);
		network_stat_ptr->collisions=sg_get_ll_match(line, &line_match[8]);
		network_stat_ptr->systime=time(NULL);

		interfaces++;
	}
	fclose(f);
	regfree(&regex);

#endif

#ifdef CYGWIN
	sg_set_error(SG_ERROR_UNSUPPORTED, "Cygwin");
	return NULL;
#endif
#ifdef HPUX
	sg_set_error(SG_ERROR_UNSUPPORTED, "HP-UX");
	return NULL;
#endif

#ifdef WIN32
	interfaces = 0;

	if((if_table = win32_get_devices()) == NULL) {
		sg_set_error(SG_ERROR_DEVICES, "network");
		return NULL;
	}

	if(VECTOR_RESIZE(network_stats, if_table->dwNumEntries) < 0) {
		free(if_table);
		return NULL;
	}

	for (i=0; i<if_table->dwNumEntries; i++) {
		network_stat_ptr=network_stats+i;
		if_row = if_table->table[i];

		if(sg_update_string(&network_stat_ptr->interface_name,
					if_row.bDescr) < 0) {
			free(if_table);
			return NULL;
		}
		network_stat_ptr->tx = if_row.dwOutOctets;
		network_stat_ptr->rx = if_row.dwInOctets;
		network_stat_ptr->ipackets = if_row.dwInUcastPkts + if_row.dwInNUcastPkts;
		network_stat_ptr->opackets = if_row.dwOutUcastPkts + if_row.dwOutNUcastPkts;
		network_stat_ptr->ierrors = if_row.dwInErrors;
		network_stat_ptr->oerrors = if_row.dwOutErrors;
		network_stat_ptr->collisions = 0; /* can't do that */
		network_stat_ptr->systime = time(NULL);

		interfaces++;
	}
	free(if_table);

	/* Please say there's a nicer way to do this...  If windows has two (or
	 * more) identical network cards, GetIfTable returns them with the same
	 * name, not like in Device Manager where the other has a #2 etc after
	 * it. So, add the #number here. Should we be doing this? Or should the
	 * end programs be dealing with duplicate names? Currently breaks
	 * watch.pl in rrdgraphing. But Unix does not have the issue of
	 * duplicate net device names.
	 */
	for (i=0; i<interfaces; i++) {
		no = 2;
		for(j=i+1; j<interfaces; j++) {
			network_stat_ptr=network_stats+j;
			if(strcmp(network_stats[i].interface_name, 
					network_stat_ptr->interface_name) == 0) {
				if(snprintf(buf, sizeof(buf), " #%d", no) < 0) {
					break;
				}
				if(sg_concat_string(&network_stat_ptr->interface_name, buf) != 0) {
					return NULL;
				}

				no++;
			}
		}
	}
#endif

	*entries=interfaces;

	return network_stats;	
}
Exemple #3
0
static char *get_os_name(const OSVERSIONINFOEX osinfo)
{
    char *name;
    char tmp[10];
    int r = 0;

    /* we only compile on 2k or newer, which is version 5
     * Covers 2000, XP and 2003 */
    if (osinfo.dwMajorVersion != 5) {
        return "Unknown";
    }
    switch(osinfo.dwMinorVersion) {
    case 0: /* Windows 2000 */
        name = strdup(WINDOWS2000);
        if(name == NULL) {
            goto out;
        }
        if (osinfo.wProductType == VER_NT_WORKSTATION) {
            r = home_or_pro(osinfo, &name);
        } else if (osinfo.wSuiteMask & VER_SUITE_DATACENTER) {
            r = sg_concat_string(&name, " Datacenter Server");
        } else if (osinfo.wSuiteMask & VER_SUITE_ENTERPRISE) {
            r = sg_concat_string(&name, " Advanced Server");
        } else {
            r = sg_concat_string(&name, " Server");
        }
        break;
    case 1: /* Windows XP */
        name = strdup(WINDOWSXP);
        if(name == NULL) {
            goto out;
        }
        r = home_or_pro(osinfo, &name);
        break;
    case 2: /* Windows 2003 */
        name = strdup(WINDOWS2003);
        if(name == NULL) {
            goto out;
        }
        if (osinfo.wSuiteMask & VER_SUITE_DATACENTER) {
            r = sg_concat_string(&name, " Datacenter Edition");
        } else if (osinfo.wSuiteMask & VER_SUITE_ENTERPRISE) {
            r = sg_concat_string(&name, " Enterprise Edition");
        } else if (osinfo.wSuiteMask & VER_SUITE_BLADE) {
            r = sg_concat_string(&name, " Web Edition");
        } else {
            r = sg_concat_string(&name, " Standard Edition");
        }
        break;
    default:
        name = strdup("Windows 2000 based");
        break;
    }
    if(r != 0) {
        free (name);
        return NULL;
    }
    /* Add on service pack version */
    if (osinfo.wServicePackMajor != 0) {
        if(osinfo.wServicePackMinor == 0) {
            if(snprintf(tmp, sizeof(tmp), " SP%d", osinfo.wServicePackMajor) != -1) {
                r = sg_concat_string(&name, tmp);
            }
        } else {
            if(snprintf(tmp, sizeof(tmp), " SP%d.%d", osinfo.wServicePackMajor,
                        osinfo.wServicePackMinor) != -1) {
                r = sg_concat_string(&name, tmp);
            }
        }
        if(r) {
            free(name);
            return NULL;
        }
    }
    return name;

out:
    /* strdup failed */
    sg_set_error_with_errno(SG_ERROR_MALLOC, NULL);
    return NULL;
}
static char *
get_os_name(const OSVERSIONINFOEX osinfo, SYSTEM_INFO sysinfo)
{
	char *name;
	char tmp[10];
	int r = 0;

	/* we only compile on 2k or newer, which is version 5
	 * Covers 2000, XP and 2003 */
	if (osinfo.dwMajorVersion != 5) {
		return "Unknown";
	}
	switch(osinfo.dwMinorVersion) {
		case 0: /* Windows 2000 */
			name = strdup(WINDOWS2000);
			if(name == NULL) {
				goto out;
			}
			if (osinfo.wProductType == VER_NT_WORKSTATION) {
				r = home_or_pro(osinfo, &name);
			} else if (osinfo.wSuiteMask & VER_SUITE_DATACENTER) {
				r = sg_concat_string(&name, " Datacenter Server");
			} else if (osinfo.wSuiteMask & VER_SUITE_ENTERPRISE) {
				r = sg_concat_string(&name, " Advanced Server");
			} else {
				r = sg_concat_string(&name, " Server");
			}
			break;
		case 1: /* Windows XP */
			name = strdup(WINDOWSXP);
			if(name == NULL) {
				goto out;
			}
			r = home_or_pro(osinfo, &name);
			break;
		case 2: /* Windows 2003 */
			/* XXX complete detection using http://msdn.microsoft.com/en-us/library/ms724833%28VS.85%29.aspx */
			if( (osinfo.wProductType == VER_NT_WORKSTATION) &&
			    (sysinfo.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) ) {
				name = strdup(WINDOWSXP);
				r = home_or_pro(osinfo, &name);
				r = sg_concat_string(&name, " x64 Edition");
			}
			else {
				name = strdup(WINDOWS2003);
			}

			if(name == NULL) {
				goto out;
			}
			if (osinfo.wSuiteMask & VER_SUITE_DATACENTER) {
				r = sg_concat_string(&name, " Datacenter Edition");
			} else if (osinfo.wSuiteMask & VER_SUITE_ENTERPRISE) {
				r = sg_concat_string(&name, " Enterprise Edition");
			} else if (osinfo.wSuiteMask & VER_SUITE_BLADE) {
				r = sg_concat_string(&name, " Web Edition");
			} else {
				r = sg_concat_string(&name, " Standard Edition");
			}
			break;
		default:
			name = strdup("Windows 2000 based");
			break;
	}
	if(r != 0) {
		free (name);
		return NULL;
	}
	/* Add on service pack version */
	if (osinfo.wServicePackMajor != 0) {
		if(osinfo.wServicePackMinor == 0) {
			if(snprintf(tmp, sizeof(tmp), " SP%d", osinfo.wServicePackMajor) != -1) {
				r = sg_concat_string(&name, tmp);
			}
		} else {
			if(snprintf(tmp, sizeof(tmp), " SP%d.%d", osinfo.wServicePackMajor,
					osinfo.wServicePackMinor) != -1) {
				r = sg_concat_string(&name, tmp);
			}
		}
		if(r) {
			free(name);
			return NULL;
		}
	}
	return name;

out:
	/* strdup failed */
	SET_ERROR_WITH_ERRNO("os", SG_ERROR_MALLOC, "get_os_name: strdup() failed");
	return NULL;
}