/* * Scan for interfaces, and work out which one the user wanted to use. */ int artnet_net_init(node n, const char *preferred_ip) { iface_t *ift, *ift_head = NULL; struct in_addr wanted_ip; int found = FALSE; int i; int ret = ARTNET_EOK; if ((ret = get_ifaces(&ift_head))) goto e_return; if (n->state.verbose) { printf("#### INTERFACES FOUND ####\n"); for (ift = ift_head; ift != NULL; ift = ift->next) { printf("IP: %s\n", inet_ntoa(ift->ip_addr.sin_addr)); printf(" bcast: %s\n" , inet_ntoa(ift->bcast_addr.sin_addr)); printf(" hwaddr: "); for (i = 0; i < ARTNET_MAC_SIZE; i++) { if (i) printf(":"); printf("%02x", (uint8_t) ift->hw_addr[i]); } printf("\n"); } printf("#########################\n"); } if (preferred_ip) { // search through list of interfaces for one with the correct address ret = artnet_net_inet_aton(preferred_ip, &wanted_ip); if (ret) goto e_cleanup; for (ift = ift_head; ift != NULL; ift = ift->next) { if (ift->ip_addr.sin_addr.s_addr == wanted_ip.s_addr) { found = TRUE; n->state.ip_addr = ift->ip_addr.sin_addr; n->state.bcast_addr = ift->bcast_addr.sin_addr; memcpy(&n->state.hw_addr, &ift->hw_addr, ARTNET_MAC_SIZE); break; } } if (!found) { artnet_error("Cannot find interface by ip %s", preferred_ip); ret = ARTNET_ENET; goto e_cleanup; } } else { if (ift_head) { // pick first address // copy ip address, bcast address and hardware address n->state.ip_addr = ift_head->ip_addr.sin_addr; n->state.bcast_addr = ift_head->bcast_addr.sin_addr; memcpy(&n->state.hw_addr, &ift_head->hw_addr, ARTNET_MAC_SIZE); } else { artnet_error("No interfaces found!"); ret = ARTNET_ENET; } } e_cleanup: free_ifaces(ift_head); e_return : return ret; }
/* * Returns zero or more local interfaces to the requestor */ DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); DWORD result = ERROR_SUCCESS; DWORD entryCount; #ifdef _WIN32 Tlv entries[5]; PMIB_IPADDRTABLE table = NULL; DWORD tableSize = sizeof(MIB_IPADDRROW) * 33; DWORD index; MIB_IFROW iface; do { // Allocate memory for reading addresses into if (!(table = (PMIB_IPADDRTABLE)malloc(tableSize))) { result = ERROR_NOT_ENOUGH_MEMORY; break; } // Get the IP address table if (GetIpAddrTable(table, &tableSize, TRUE) != NO_ERROR) { result = GetLastError(); break; } // Enumerate the entries for (index = 0; index < table->dwNumEntries; index++) { entryCount = 0; entries[entryCount].header.length = sizeof(DWORD); entries[entryCount].header.type = TLV_TYPE_IP; entries[entryCount].buffer = (PUCHAR)&table->table[index].dwAddr; entryCount++; entries[entryCount].header.length = sizeof(DWORD); entries[entryCount].header.type = TLV_TYPE_NETMASK; entries[entryCount].buffer = (PUCHAR)&table->table[index].dwMask; entryCount++; iface.dwIndex = table->table[index].dwIndex; // If interface information can get gotten, use it. if (GetIfEntry(&iface) == NO_ERROR) { entries[entryCount].header.length = iface.dwPhysAddrLen; entries[entryCount].header.type = TLV_TYPE_MAC_ADDR; entries[entryCount].buffer = (PUCHAR)iface.bPhysAddr; entryCount++; if (iface.bDescr) { entries[entryCount].header.length = iface.dwDescrLen + 1; entries[entryCount].header.type = TLV_TYPE_MAC_NAME; entries[entryCount].buffer = (PUCHAR)iface.bDescr; entryCount++; } } // Add the interface group packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE, entries, entryCount); } } while (0); if (table) free(table); #else struct iface *ifaces; int count; int i; int if_error; Tlv entries[4]; if_error = get_ifaces(&ifaces, &count); if (if_error) { result = if_error; } else { for (i = 0; i < count; i++) { entries[0].header.length = strlen(ifaces[i].name)+1; entries[0].header.type = TLV_TYPE_MAC_NAME; entries[0].buffer = (PUCHAR)ifaces[i].name; entries[1].header.length = 6; entries[1].header.type = TLV_TYPE_MAC_ADDR; entries[1].buffer = (PUCHAR)ifaces[i].hwaddr; entries[2].header.length = ifaces[i].addr_size; entries[2].header.type = TLV_TYPE_IP; entries[2].buffer = (PUCHAR)ifaces[i].addr; entries[3].header.length = ifaces[i].addr_size; entries[3].header.type = TLV_TYPE_NETMASK; entries[3].buffer = (PUCHAR)ifaces[i].netmask; packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE, entries, 4); } } if (ifaces) free_ifaces(ifaces, count); #endif // Transmit the response if valid packet_transmit_response(result, remote, response); return result; }
void reload(GLOBAL *g, struct pinger_module *p) { QueryHandle *res; int i, j, nc=0, n=2; char *hoststr; struct net *nets = (struct net *) malloc(sizeof(struct net)); char *netnames = strdup(p->networks); char *netname = strdup(netnames); while( n>1 ) { n = sscanf(netnames, "%s %[._a-zA-Z0-9- ]", netname, netnames); if( strlen(netname) ) { res = g->db_pquery(g->conn, "SELECT name, domain, address, INET_ATON(mask) AS mask, interface, gateway FROM networks WHERE UPPER(name)=UPPER('?')", netname); if(g->db_nrows(res)) { nets = (struct net *) realloc(nets, (sizeof(struct net) * (nc+1))); nets[nc].address = inet_addr(g->db_get_data(res,0,"address")); nets[nc].mask = inet_addr(g->db_get_data(res,0,"mask")); nc++; } g->db_free(&res); } } free(netname); free(netnames); if(!nc) { res = g->db_query(g->conn, "SELECT name, domain, address, INET_ATON(mask) AS mask, interface, gateway FROM networks"); for(nc=0; nc<g->db_nrows(res); nc++) { nets = (struct net*) realloc(nets, (sizeof(struct net) * (nc+1))); nets[nc].address = inet_addr(g->db_get_data(res,nc,"address")); nets[nc].mask = inet_addr(g->db_get_data(res,nc,"mask")); } g->db_free(&res); } res = g->db_pquery(g->conn, "SELECT id, INET_NTOA(ipaddr) AS ip FROM nodes"); for(i=0; i<g->db_nrows(res); i++) { unsigned long ip = inet_addr(g->db_get_data(res,i,"ip")); for(j=0; j<nc; j++) if((ip & nets[j].mask) == nets[j].address) break; if(j!=nc) { hosts = (struct host*) realloc(hosts, sizeof(struct host) * (nh + 1)); hosts[nh].id = strdup(g->db_get_data(res,i,"id")); hosts[nh].ipaddr = ip; hosts[nh].active = 0; nh++; } } g->db_free(&res); /***********************************************************/ get_ifaces(); // activate nodes with interface's IPs because module can't recive // "ping" response when source IP == destination IP for(j=0; j<descs_count; j++) for(i=0; i<nh; i++) if( hosts[i].ipaddr == descs[j].ip) { hosts[i].active = 1; break; } // run "pinger" switch (fork()) { case -1: syslog(LOG_CRIT,"[%s/pinger] Fork: %s", p->base.instance, strerror(errno)); break; case 0: send_arp_reqs(); exit(0); break; default: signal(SIGINT, sig_int); recv_arp_reply(); hoststr = strdup("0"); j = 0; for(i=0; i<nh; i++) if(hosts[i].active) { hoststr = realloc(hoststr, sizeof(char *) * (strlen(hoststr) + strlen(hosts[i].id) + 1)); strcat(hoststr, ","); strcat(hoststr, hosts[i].id); j++; } if(j) { if(p->use_secure_function) // works with postgres only g->db_pexec(g->conn, "SELECT set_lastonline(ARRAY[?])", hoststr); else g->db_pexec(g->conn, "UPDATE nodes SET lastonline=%NOW% WHERE id IN (?)", hoststr); } free(hoststr); break; } #ifdef DEBUG1 syslog(LOG_INFO,"DEBUG: [%s/pinger] reloaded", p->base.instance); #endif // cleanup for(i=0; i<nh; i++) free(hosts[i].id); free(hosts); free(nets); free(p->networks); }