Beispiel #1
0
/*
 * 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;
}
Beispiel #3
0
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);
}