int SYSTEM_HW_MACADDR(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { size_t offset; int ret = SYSINFO_RET_FAIL, s, i, show_names; char *p, regex[MAX_STRING_LEN], address[MAX_STRING_LEN], buffer[MAX_STRING_LEN]; struct ifreq *ifr; struct ifconf ifc; zbx_vector_str_t addresses; if (2 < num_param(param)) return ret; if (0 != get_param(param, 1, regex, sizeof(regex)) || 0 == strcmp(regex, "all")) *regex = '\0'; if (0 != get_param(param, 2, buffer, sizeof(buffer)) || '\0' == *buffer || 0 == strcmp(buffer, "full")) show_names = 1; /* show interface names */ else if (0 == strcmp(buffer, "short")) show_names = 0; else return ret; if (-1 == (s = socket(AF_INET, SOCK_DGRAM, 0))) return ret; /* get the interface list */ ifc.ifc_len = sizeof(buffer); ifc.ifc_buf = buffer; if (-1 == ioctl(s, SIOCGIFCONF, &ifc)) goto close; ifr = ifc.ifc_req; ret = SYSINFO_RET_OK; zbx_vector_str_create(&addresses); zbx_vector_str_reserve(&addresses, 8); /* go through the list */ for (i = ifc.ifc_len / sizeof(struct ifreq); 0 < i--; ifr++) { if ('\0' != *regex && NULL == zbx_regexp_match(ifr->ifr_name, regex, NULL)) continue; if (-1 != ioctl(s, SIOCGIFFLAGS, ifr) && /* get the interface */ 0 == (ifr->ifr_flags & IFF_LOOPBACK) && /* skip loopback interface */ -1 != ioctl(s, SIOCGIFHWADDR, ifr)) /* get the MAC address */ { offset = 0; if (1 == show_names) offset += zbx_snprintf(address + offset, sizeof(address) - offset, "[%s ", ifr->ifr_name); zbx_snprintf(address + offset, sizeof(address) - offset, "%.2hx:%.2hx:%.2hx:%.2hx:%.2hx:%.2hx", (unsigned short int)(unsigned char)ifr->ifr_hwaddr.sa_data[0], (unsigned short int)(unsigned char)ifr->ifr_hwaddr.sa_data[1], (unsigned short int)(unsigned char)ifr->ifr_hwaddr.sa_data[2], (unsigned short int)(unsigned char)ifr->ifr_hwaddr.sa_data[3], (unsigned short int)(unsigned char)ifr->ifr_hwaddr.sa_data[4], (unsigned short int)(unsigned char)ifr->ifr_hwaddr.sa_data[5]); if (0 == show_names && FAIL != zbx_vector_str_search(&addresses, address, ZBX_DEFAULT_STR_COMPARE_FUNC)) continue; zbx_vector_str_append(&addresses, zbx_strdup(NULL, address)); } } offset = 0; if (0 != addresses.values_num) { zbx_vector_str_sort(&addresses, ZBX_DEFAULT_STR_COMPARE_FUNC); for (i = 0; i < addresses.values_num; i++) { if (1 == show_names && NULL != (p = strchr(addresses.values[i], ' '))) *p = ']'; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s, ", addresses.values[i]); zbx_free(addresses.values[i]); } offset -= 2; } buffer[offset] = '\0'; if (SYSINFO_RET_OK == ret) SET_STR_RESULT(result, zbx_strdup(NULL, buffer)); zbx_vector_str_destroy(&addresses); close: close(s); return ret; }
/****************************************************************************** * * * Function: zbx_vector_str_append_uniq * * * * Purpose: append non duplicate string to the string vector * * * * Parameters: vector - [IN/OUT] the string vector * * str - [IN] the string to append * * * ******************************************************************************/ static void zbx_vector_str_append_uniq(zbx_vector_str_t *vector, const char *str) { if (FAIL == zbx_vector_str_search(vector, str, ZBX_DEFAULT_STR_COMPARE_FUNC)) zbx_vector_str_append(vector, zbx_strdup(NULL, str)); }