void GetInterfaceInfo(void) { int fd, len, i, j; struct ifreq ifbuf[512], ifr, *ifp; struct ifconf list; struct sockaddr_in *sin; struct hostent *hp; char *sp; char ip[CF_MAXVARSIZE]; char name[CF_MAXVARSIZE]; Debug("GetInterfaceInfo()\n"); if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { CfLog(cferror, "Couldn't open socket", "socket"); exit(1); } list.ifc_len = sizeof(ifbuf); list.ifc_req = ifbuf; #ifdef SIOCGIFCONF if (ioctl(fd, SIOCGIFCONF, &list) == -1 || (list.ifc_len < (sizeof(struct ifreq)))) #else if (ioctl(fd, OSIOCGIFCONF, &list) == -1 || (list.ifc_len < (sizeof(struct ifreq)))) #endif { CfLog(cferror, "Couldn't get interfaces", "ioctl"); exit(1); } for (j = 0, len = 0, ifp = list.ifc_req; len < list.ifc_len; len+=SIZEOF_IFREQ(*ifp), j++, ifp=&ifbuf[j]) { if (ifp->ifr_addr.sa_family == 0) { continue; } Verbose("Interface %d: %s\n", j+1, ifp->ifr_name); if(g_underscore_classes) { snprintf(g_vbuff, CF_BUFSIZE, "_net_iface_%s", CanonifyName(ifp->ifr_name)); } else { snprintf(g_vbuff, CF_BUFSIZE, "net_iface_%s", CanonifyName(ifp->ifr_name)); } AddClassToHeap(g_vbuff); if (ifp->ifr_addr.sa_family == AF_INET) { strncpy(ifr.ifr_name, ifp->ifr_name, sizeof(ifp->ifr_name)); if (ioctl(fd,SIOCGIFFLAGS,&ifr) == -1) { CfLog(cferror, "No such network device", "ioctl"); close(fd); return; } /* * Used to check if interface was "up" if ((ifr.ifr_flags & * IFF_UP) && !(ifr.ifr_flags & IFF_LOOPBACK)) Now check * whether it is configured ... */ if ((ifr.ifr_flags & IFF_BROADCAST) && !(ifr.ifr_flags & IFF_LOOPBACK)) { sin=(struct sockaddr_in *)&ifp->ifr_addr; snprintf(name, CF_MAXVARSIZE-1, "ipv4[%s]", CanonifyName(ifp->ifr_name)); AddMacroValue(g_contextid, name, inet_ntoa(sin->sin_addr)); if ((hp = gethostbyaddr((char *)&(sin->sin_addr.s_addr), sizeof(sin->sin_addr.s_addr), AF_INET)) == NULL) { Debug("Host information for %s not found\n", inet_ntoa(sin->sin_addr)); } else { if (hp->h_name != NULL) { Debug("Adding hostip %s..\n", inet_ntoa(sin->sin_addr)); AddClassToHeap(CanonifyName(inet_ntoa(sin->sin_addr))); Debug("Adding hostname %s..\n", hp->h_name); AddClassToHeap(CanonifyName(hp->h_name)); for (i=0; hp->h_aliases[i] != NULL; i++) { Debug("Adding alias %s..\n", hp->h_aliases[i]); AddClassToHeap(CanonifyName(hp->h_aliases[i])); } /* Old style compat */ strcpy(ip,inet_ntoa(sin->sin_addr)); AppendItem(&g_ipaddresses, ip, ""); for (sp = ip+strlen(ip)-1; *sp != '.'; sp--) { } *sp = '\0'; AddClassToHeap(CanonifyName(ip)); /* New style */ strcpy(ip, "ipv4_"); strcat(ip, inet_ntoa(sin->sin_addr)); AddClassToHeap(CanonifyName(ip)); for (sp = ip+strlen(ip)-1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; AddClassToHeap(CanonifyName(ip)); } } } } } } ifp = (struct ifreq *)((char *)ifp + SIZEOF_IFREQ(*ifp)); } close(fd); }
void GetInterfacesInfo(AgentType ag) { int fd, len, i, j, first_address = false, ipdefault = false; struct ifreq ifbuf[CF_IFREQ], ifr, *ifp; struct ifconf list; struct sockaddr_in *sin; struct hostent *hp; char *sp, workbuf[CF_BUFSIZE]; char ip[CF_MAXVARSIZE]; char name[CF_MAXVARSIZE]; char last_name[CF_BUFSIZE]; Rlist *interfaces = NULL, *hardware = NULL, *ips = NULL; CfDebug("GetInterfacesInfo()\n"); // Long-running processes may call this many times DeleteItemList(IPADDRESSES); IPADDRESSES = NULL; memset(ifbuf, 0, sizeof(ifbuf)); InitIgnoreInterfaces(); last_name[0] = '\0'; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { CfOut(OUTPUT_LEVEL_ERROR, "socket", "Couldn't open socket"); exit(1); } list.ifc_len = sizeof(ifbuf); list.ifc_req = ifbuf; # ifdef SIOCGIFCONF if (ioctl(fd, SIOCGIFCONF, &list) == -1 || (list.ifc_len < (sizeof(struct ifreq)))) # else if ((ioctl(fd, OSIOCGIFCONF, &list) == -1) || (list.ifc_len < (sizeof(struct ifreq)))) # endif { CfOut(OUTPUT_LEVEL_ERROR, "ioctl", "Couldn't get interfaces - old kernel? Try setting CF_IFREQ to 1024"); exit(1); } last_name[0] = '\0'; for (j = 0, len = 0, ifp = list.ifc_req; len < list.ifc_len; len += SIZEOF_IFREQ(*ifp), j++, ifp = (struct ifreq *) ((char *) ifp + SIZEOF_IFREQ(*ifp))) { if (ifp->ifr_addr.sa_family == 0) { continue; } if ((ifp->ifr_name == NULL) || (strlen(ifp->ifr_name) == 0)) { continue; } /* Skip virtual network interfaces for Linux, which seems to be a problem */ if (IgnoreInterface(ifp->ifr_name)) { continue; } if (strstr(ifp->ifr_name, ":")) { #ifdef __linux__ CfOut(OUTPUT_LEVEL_VERBOSE, "", "Skipping apparent virtual interface %d: %s\n", j + 1, ifp->ifr_name); continue; #endif } else { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Interface %d: %s\n", j + 1, ifp->ifr_name); } // Ignore the loopback if (strcmp(ifp->ifr_name, "lo") == 0) { continue; } if (strncmp(last_name, ifp->ifr_name, sizeof(ifp->ifr_name)) == 0) { first_address = false; } else { strncpy(last_name, ifp->ifr_name, sizeof(ifp->ifr_name)); if (!first_address) { NewScalar("sys", "interface", last_name, DATA_TYPE_STRING); first_address = true; } } snprintf(workbuf, CF_BUFSIZE, "net_iface_%s", CanonifyName(ifp->ifr_name)); HardClass(workbuf); if (ifp->ifr_addr.sa_family == AF_INET) { strncpy(ifr.ifr_name, ifp->ifr_name, sizeof(ifp->ifr_name)); if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) { CfOut(OUTPUT_LEVEL_ERROR, "ioctl", "No such network device"); continue; } if ((ifr.ifr_flags & IFF_UP) && (!(ifr.ifr_flags & IFF_LOOPBACK))) { sin = (struct sockaddr_in *) &ifp->ifr_addr; if (IgnoreJailInterface(j + 1, sin)) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Ignoring interface %d", j + 1); continue; } CfDebug("Adding hostip %s..\n", inet_ntoa(sin->sin_addr)); HardClass(inet_ntoa(sin->sin_addr)); if ((hp = gethostbyaddr((char *) &(sin->sin_addr.s_addr), sizeof(sin->sin_addr.s_addr), AF_INET)) == NULL) { CfDebug("No hostinformation for %s found\n", inet_ntoa(sin->sin_addr)); } else { if (hp->h_name != NULL) { CfDebug("Adding hostname %s..\n", hp->h_name); HardClass(hp->h_name); if (hp->h_aliases != NULL) { for (i = 0; hp->h_aliases[i] != NULL; i++) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Adding alias %s..\n", hp->h_aliases[i]); HardClass(hp->h_aliases[i]); } } } } if (strcmp(inet_ntoa(sin->sin_addr), "0.0.0.0") == 0) { // Maybe we need to do something windows specific here? CfOut(OUTPUT_LEVEL_VERBOSE, "", " !! Cannot discover hardware IP, using DNS value"); strcpy(ip, "ipv4_"); strcat(ip, VIPADDRESS); AppendItem(&IPADDRESSES, VIPADDRESS, ""); RlistAppend(&ips, VIPADDRESS, RVAL_TYPE_SCALAR); for (sp = ip + strlen(ip) - 1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; HardClass(ip); } } strcpy(ip, VIPADDRESS); i = 3; for (sp = ip + strlen(ip) - 1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; snprintf(name, CF_MAXVARSIZE - 1, "ipv4_%d[%s]", i--, CanonifyName(VIPADDRESS)); NewScalar("sys", name, ip, DATA_TYPE_STRING); } } continue; } strncpy(ip, "ipv4_", CF_MAXVARSIZE); strncat(ip, inet_ntoa(sin->sin_addr), CF_MAXVARSIZE - 6); HardClass(ip); if (!ipdefault) { ipdefault = true; NewScalar("sys", "ipv4", inet_ntoa(sin->sin_addr), DATA_TYPE_STRING); strcpy(VIPADDRESS, inet_ntoa(sin->sin_addr)); } AppendItem(&IPADDRESSES, inet_ntoa(sin->sin_addr), ""); RlistAppend(&ips, inet_ntoa(sin->sin_addr), RVAL_TYPE_SCALAR); for (sp = ip + strlen(ip) - 1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; HardClass(ip); } } // Set the IPv4 on interface array strcpy(ip, inet_ntoa(sin->sin_addr)); if ((ag != AGENT_TYPE_KNOW) && (ag != AGENT_TYPE_GENDOC)) { snprintf(name, CF_MAXVARSIZE - 1, "ipv4[%s]", CanonifyName(ifp->ifr_name)); } else { snprintf(name, CF_MAXVARSIZE - 1, "ipv4[interface_name]"); } NewScalar("sys", name, ip, DATA_TYPE_STRING); i = 3; for (sp = ip + strlen(ip) - 1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; if ((ag != AGENT_TYPE_KNOW) && (ag != AGENT_TYPE_GENDOC)) { snprintf(name, CF_MAXVARSIZE - 1, "ipv4_%d[%s]", i--, CanonifyName(ifp->ifr_name)); } else { snprintf(name, CF_MAXVARSIZE - 1, "ipv4_%d[interface_name]", i--); } NewScalar("sys", name, ip, DATA_TYPE_STRING); } } } // Set the hardware/mac address array GetMacAddress(ag, fd, &ifr, ifp, &interfaces, &hardware); } } close(fd); NewList("sys", "interfaces", interfaces, DATA_TYPE_STRING_LIST); NewList("sys", "hardware_addresses", hardware, DATA_TYPE_STRING_LIST); NewList("sys", "ip_addresses", ips, DATA_TYPE_STRING_LIST); RlistDestroy(interfaces); RlistDestroy(hardware); RlistDestroy(ips); FindV6InterfacesInfo(); }