Beispiel #1
0
static void
copy_hw_info(char *buf, size_t len) {
  int i;

  buf[0] = '\0';
  for (i = 0; i < sizeof(dmidecode_param) / sizeof(dmidecode_param[0]); i++) {
    strncat(buf, get_dmi_string(dmidecode_param[i]), len);
    buf[strlen(buf) - 1] = ' ';
  }
  buf[strlen(buf) - 1] = '\0';
}
Beispiel #2
0
static int	get_dmi_info(char *buf, int bufsize, int flags)
{
	int		ret = SYSINFO_RET_FAIL, fd, offset = 0;
	unsigned char	membuf[SMBIOS_ENTRY_POINT_SIZE], *smbuf = NULL, *data;
	size_t		len, fp;
	void		*mmp = NULL;
	static long	pagesize = 0;
	static int	smbios_status = SMBIOS_STATUS_UNKNOWN;
	static size_t	smbios_len, smbios;	/* length and address of SMBIOS table (if found) */

	if (-1 == (fd = open(DEV_MEM, O_RDONLY)))
		return ret;

	if (SMBIOS_STATUS_UNKNOWN == smbios_status)	/* look for SMBIOS table only once */
	{
		pagesize = sysconf(_SC_PAGESIZE);

		/* find smbios entry point - located between 0xF0000 and 0xFFFFF (according to the specs) */
		for (fp = 0xf0000; 0xfffff > fp; fp += 16)
		{
			memset(membuf, 0, sizeof(membuf));

			len = fp % pagesize;	/* mmp needs to be a multiple of pagesize for munmap */
			if (MAP_FAILED == (mmp = mmap(0, len + SMBIOS_ENTRY_POINT_SIZE, PROT_READ, MAP_SHARED, fd, fp - len)))
				goto close;

			memcpy(membuf, mmp + len, sizeof(membuf));
			munmap(mmp, len + SMBIOS_ENTRY_POINT_SIZE);

			if (0 == strncmp((char *)membuf, "_DMI_", 5))	/* entry point found */
			{
				smbios_len = membuf[7] << 8 | membuf[6];
				smbios = (size_t)membuf[11] << 24 | (size_t)membuf[10] << 16 | (size_t)membuf[9] << 8 | membuf[8];
				smbios_status = SMBIOS_STATUS_OK;
				break;
			}
		}
	}

	if (SMBIOS_STATUS_OK != smbios_status)
	{
		smbios_status = SMBIOS_STATUS_ERROR;
		goto close;
	}

	smbuf = zbx_malloc(smbuf, smbios_len);

	len = smbios % pagesize;	/* mmp needs to be a multiple of pagesize for munmap */
	if (MAP_FAILED == (mmp = mmap(0, len + smbios_len, PROT_READ, MAP_SHARED, fd, smbios - len)))
		goto clean;

	memcpy(smbuf, mmp + len, smbios_len);
	munmap(mmp, len + smbios_len);

	data = smbuf;
	while (data + DMI_HEADER_SIZE <= smbuf + smbios_len)
	{
		if (1 == data[0])	/* system information */
		{
			if (0 != (flags & DMI_GET_VENDOR))
			{
				offset += get_dmi_string(buf + offset, bufsize - offset, data, data[4]);
				flags &= ~DMI_GET_VENDOR;
			}

			if (0 != (flags & DMI_GET_MODEL))
			{
				offset += get_dmi_string(buf + offset, bufsize - offset, data, data[5]);
				flags &= ~DMI_GET_MODEL;
			}

			if (0 != (flags & DMI_GET_SERIAL))
			{
				offset += get_dmi_string(buf + offset, bufsize - offset, data, data[7]);
				flags &= ~DMI_GET_SERIAL;
			}
		}
		else if (3 == data[0] && 0 != (flags & DMI_GET_TYPE))	/* chassis */
		{
			offset += get_chassis_type(buf + offset, bufsize - offset, data[5]);
			flags &= ~DMI_GET_TYPE;
		}

		if (0 == flags)
			break;

		data += data[1];			/* skip the main data */
		while (0 != data[0] || 0 != data[1])	/* string data ends with two nulls */
		{
			data++;
		}
		data += 2;
	}

	if (0 < offset)
		ret = SYSINFO_RET_OK;
clean:
	zbx_free(smbuf);
close:
	close(fd);

	return ret;
}