Exemple #1
0
static inline
void ipcs_table_refresh_wireless(struct nc_ipcs_table *tbl, int fd)
{
    struct nc_ipcs_table_item *ipc = NULL;
    char iface_name[32];
    uint8_t hwaddr[ETH_ALEN] = {0};
    uint32_t src_ip = 0;
    int ret = -1;
    int i;

    if (tbl->wireless_enable == 0)
    {
        return ;
    }

    sprintf(iface_name, "%s.%d", tbl->iface_name, NC_WIRELESS_VID);

    ret = get_iface_addr(iface_name, hwaddr, ETH_ALEN, &src_ip);
    if (ret < 0)
    {
        return ;
    }

    if (tbl->wireless_enable)
    {
        for (i = 0; i < NC_WIRELESS_SZ; ++i)
        {
            ipc = &tbl->wireless_ipcs[i];

            if (ipc->alive_sec < 0)
            {
                continue;
            }

            if (ipc->alive_sec == 0)
            {
                send_ipc_info(tbl, -1, ipc->mac, ipc->ip, 1);
            }
            else
            {
                if ((ipc->alive_sec & 0x1) == 0x1)
                {
                    st_dbg("send to \n");
                    send_arp_req(fd, hwaddr, src_ip, ipc->ip, NULL, 0);
                }
            }
        }
    }
}
Exemple #2
0
int send_arp_reqs() 
{
	int sock, i;

	if ((sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP))) == -1) {
		printf("send_arp_reqs: socket: %s\n", strerror(errno));
		return 1;
	}

	for (i = 0; i < nh; i++)
		send_arp_req(sock, hosts[i].ipaddr);

	close(sock);
	return 0;
}
Exemple #3
0
static int recv_onvif_probematch(
    struct nc_ipcs_table *tbl,
    int arp_fd,
    int port_idx,
    char *probematch,
    int pm_len,
    struct sockaddr_in *addr
)
{
    char iface_name[32];
    uint8_t hwaddr[ETH_ALEN] = {0};
    uint32_t src_ip = 0;
    uint32_t tgt_ip = addr->sin_addr.s_addr;
    struct sockaddr_ll hw_sa;
    int ret = -1;

    if (port_idx < 0)
    {
        sprintf(iface_name, "%s.%d", tbl->iface_name, NC_WIRELESS_VID);
    }
    else
    {
        sprintf(iface_name, "%s.%d", tbl->iface_name, NC_WIRE_VID_START + port_idx);
    }

    ret = get_iface_addr(iface_name, hwaddr, ETH_ALEN, &src_ip);
    if (ret < 0)
    {
        return -1;
    }

    memset(&hw_sa, 0, sizeof(hw_sa));

    hw_sa.sll_family = AF_PACKET;
    hw_sa.sll_protocol = htons(ETH_P_ARP);
    hw_sa.sll_ifindex = if_nametoindex(iface_name);
    hw_sa.sll_halen = ETH_ALEN;
    memcpy(hw_sa.sll_addr, hwaddr, ETH_ALEN);

    return send_arp_req(arp_fd, hwaddr, src_ip, tgt_ip, &hw_sa, sizeof(hw_sa));
}
Exemple #4
0
static inline
void ipcs_table_refresh_wire(struct nc_ipcs_table *tbl, int *fds)
{
    struct nc_ipcs_table_item *ipc = NULL;
    int i;

    for (i = 0; i < tbl->wire_cnt; ++i)
    {
        ipc = &tbl->wire_ipcs[i];

        if (ipc->alive_sec < 0)
        {
            continue;
        }

        if (ipc->alive_sec == 0)
        {
            send_ipc_info(tbl, i, ipc->mac, ipc->ip, 1);
        }
        else
        {
            char iface_name[32];
            uint8_t hwaddr[ETH_ALEN] = {0};
            uint32_t src_ip = 0;
            int ret = -1;

            sprintf(iface_name, "%s.%d", tbl->iface_name, NC_WIRE_VID_START + i);
            ret = get_iface_addr(iface_name, hwaddr, ETH_ALEN, &src_ip);
            if (ret < 0)
            {
                continue;
            }

            send_arp_req(fds[i], hwaddr, src_ip, ipc->ip, NULL, 0);
        }
    }
}
Exemple #5
0
int handle_rtm_newroute(const struct nlmsghdr *nl){
	const struct rtmsg *rt = NLMSG_DATA(nl);
	struct rtattr *ra;
	void *as,*ad,*ag;
	int rlen,oif;
	route *r,**prev;
	size_t flen;

	oif = -1;
	if((r = create_route()) == NULL){
		return -1;
	}
	switch( (r->family = rt->rtm_family) ){
	case AF_INET:{
		flen = sizeof(uint32_t);
		as = &((struct sockaddr_in *)&r->sss)->sin_addr;
		ad = &((struct sockaddr_in *)&r->ssd)->sin_addr;
		ag = &((struct sockaddr_in *)&r->ssg)->sin_addr;
	break;}case AF_INET6:{
		flen = sizeof(uint32_t) * 4;
		as = &((struct sockaddr_in6 *)&r->sss)->sin6_addr;
		ad = &((struct sockaddr_in6 *)&r->ssd)->sin6_addr;
		ag = &((struct sockaddr_in6 *)&r->ssg)->sin6_addr;
	break;}case AF_BRIDGE:{
		// FIXME wtf is a bridge route
		diagnostic("got a bridge route hrmmm FIXME");
		return -1; // FIXME
	break;}default:{
		flen = 0;
	break;} }
	r->maskbits = rt->rtm_dst_len;
	if(flen == 0 || flen > sizeof(r->sss.__ss_padding)){
		diagnostic("Unknown route family %u",rt->rtm_family);
		return -1;
	}
	rlen = nl->nlmsg_len - NLMSG_LENGTH(sizeof(*rt));
	ra = (struct rtattr *)((char *)(NLMSG_DATA(nl)) + sizeof(*rt));
	memset(&r->ssg,0,sizeof(r->ssg));
	memset(&r->ssd,0,sizeof(r->ssd));
	memset(&r->sss,0,sizeof(r->sss));
	while(RTA_OK(ra,rlen)){
		switch(ra->rta_type){
		case RTA_DST:{
			if(RTA_PAYLOAD(ra) != flen){
				diagnostic("Expected %zu dst bytes, got %zu",
						flen,RTA_PAYLOAD(ra));
				break;
			}
			if(r->ssd.ss_family){
				diagnostic("Got two destinations for route");
				break;
			}
			memcpy(ad,RTA_DATA(ra),flen);
			r->ssd.ss_family = r->family;
		break;}case RTA_PREFSRC: case RTA_SRC:{
			// FIXME do we not want to prefer PREFSRC?
			if(RTA_PAYLOAD(ra) != flen){
				diagnostic("Expected %zu src bytes, got %zu",
						flen,RTA_PAYLOAD(ra));
				break;
			}
			if(r->sss.ss_family){
				diagnostic("Got two sources for route");
				break;
			}
			memcpy(as,RTA_DATA(ra),flen);
			r->sss.ss_family = r->family;
		break;}case RTA_IIF:{
			if(RTA_PAYLOAD(ra) != sizeof(int)){
				diagnostic("Expected %zu iiface bytes, got %zu",
						sizeof(int),RTA_PAYLOAD(ra));
				break;
			}
			// we don't use RTA_OIF: iif = *(int *)RTA_DATA(ra);
		break;}case RTA_OIF:{
			if(RTA_PAYLOAD(ra) != sizeof(int)){
				diagnostic("Expected %zu oiface bytes, got %zu",
						sizeof(int),RTA_PAYLOAD(ra));
				break;
			}
			oif = *(int *)RTA_DATA(ra);
		break;}case RTA_GATEWAY:{
			if(RTA_PAYLOAD(ra) != flen){
				diagnostic("Expected %zu gw bytes, got %zu",
						flen,RTA_PAYLOAD(ra));
				break;
			}
			if(r->ssg.ss_family){
				diagnostic("Got two gateways for route");
				break;
			}
			// We get 0.0.0.0 as the gateway when there's no 'via'
			if(memcmp(ag,RTA_DATA(ra),flen)){
				memcpy(ag,RTA_DATA(ra),flen);
				r->ssg.ss_family = r->family;
			}
		break;}case RTA_PRIORITY:{
		break;}case RTA_METRICS:{
		break;}case RTA_MULTIPATH:{
		// break;}case RTA_PROTOINFO:{ // unused
		break;}case RTA_FLOW:{
		break;}case RTA_CACHEINFO:{
		// break;}case RTA_SESSION:{ // unused
		// break;}case RTA_MP_ALGO:{ // unused
		break;}case RTA_TABLE:{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
		break;}case RTA_MARK:{
#endif
		break;}case RTA_MFC_STATS:{
		break;}case RTA_VIA:{
		break;}case RTA_NEWDST:{
		break;}case RTA_PREF:{
		break;}case RTA_ENCAP_TYPE:{
		break;}case RTA_ENCAP:{
		break;}case RTA_EXPIRES:{
		break;}case RTA_PAD:{
		break;}default:{
			diagnostic("Unknown rtatype %u",ra->rta_type);
		break;}}
		ra = RTA_NEXT(ra,rlen);
	}
	if(rlen){
		diagnostic("%d excess bytes on newlink message",rlen);
	}
	if((r->iface = iface_by_idx(oif)) == NULL){
		diagnostic("Unknown output interface %d on %s",oif,r->iface->name);
		goto err;
	}
	{
		char str[INET6_ADDRSTRLEN],via[INET6_ADDRSTRLEN];
		inet_ntop(rt->rtm_family,ad,str,sizeof(str));
		inet_ntop(rt->rtm_family,ag,via,sizeof(via));
		diagnostic("[%s] new route to %s/%u %ls%ls%s",
			r->iface->name,str,r->maskbits,
			rt->rtm_type == RTN_LOCAL ? L"(local)" :
			rt->rtm_type == RTN_BROADCAST ? L"(broadcast)" :
			rt->rtm_type == RTN_UNREACHABLE ? L"(unreachable)" :
			rt->rtm_type == RTN_ANYCAST ? L"(anycast)" :
			rt->rtm_type == RTN_UNICAST ? L"(unicast)" :
			rt->rtm_type == RTN_MULTICAST ? L"(multicast)" :
			rt->rtm_type == RTN_BLACKHOLE ? L"(blackhole)" :
			rt->rtm_type == RTN_MULTICAST ? L"(multicast)" : L"",
			r->ssg.ss_family ? L" via " : L"",
			r->ssg.ss_family ? via : "");
	}
	// We're not interest in blackholes, unreachables, prohibits, NATs yet
	if(rt->rtm_type != RTN_UNICAST && rt->rtm_type != RTN_LOCAL
			&& rt->rtm_type != RTN_BROADCAST
			&& rt->rtm_type != RTN_ANYCAST
			&& rt->rtm_type != RTN_MULTICAST){
		free_route(r);
		return 0;
	}
	assert(r->iface);
	if(!r->sss.ss_family){
		struct routepath rp;

		if(get_router(r->sss.ss_family,ad,&rp) == 0){
			if(r->sss.ss_family == AF_INET){
				memcpy(as,rp.src,4);
			}else if(r->sss.ss_family == AF_INET6){
				memcpy(as,rp.src,16);
			}else{
				assert(0);
			}
		}else{ // FIXME vicious hackery!
			if(r->family == AF_INET6){
				memcpy(as,r->iface->ip6defsrc,flen);
				r->sss.ss_family = AF_INET6;
			}
		}
	}
	if(r->family == AF_INET){
		lock_interface(r->iface);
		if(add_route4(r->iface,ad,r->ssg.ss_family ? ag : NULL,
					r->sss.ss_family ? as : NULL,
					r->maskbits)){
			unlock_interface(r->iface);
			diagnostic("Couldn't add route to %s",r->iface->name);
			goto err;
		}
		if(r->ssg.ss_family){
			send_arp_req(r->iface,r->iface->bcast,ag,as);
		}
		unlock_interface(r->iface);
		pthread_mutex_lock(&route_lock);
			prev = &ip_table4;
			// Order most-specific (largest maskbits) to least-specific (0 maskbits)
			while(*prev){
				if(r->maskbits > (*prev)->maskbits){
					break;
				}
				prev = &(*prev)->next;
			}
			r->next = *prev;
			*prev = r;
			if(r->sss.ss_family){
				while( *(prev = &(*prev)->next) ){
					assert((*prev)->maskbits < r->maskbits);
					if(!((*prev)->sss.ss_family)){
						memcpy(&(*prev)->sss,&r->sss,sizeof(r->sss));
					}
				}
			}
		pthread_mutex_unlock(&route_lock);
	}else if(r->family == AF_INET6){
		lock_interface(r->iface);
		if(add_route6(r->iface,ad,r->ssg.ss_family ? ag : NULL,r->sss.ss_family ? as : NULL,r->maskbits)){
			unlock_interface(r->iface);
			diagnostic("Couldn't add route to %s",r->iface->name);
			goto err;
		}
		unlock_interface(r->iface);
		pthread_mutex_lock(&route_lock);
			prev = &ip_table6;
			// Order most-specific (largest maskbits) to least-specific (0 maskbits)
			while(*prev){
				if(r->maskbits > (*prev)->maskbits){
					break;
				}
				prev = &(*prev)->next;
			}
			r->next = *prev;
			*prev = r;
			// FIXME set less-specific sources
		pthread_mutex_unlock(&route_lock);
	}
	return 0;

err:
	free_route(r);
	return -1;
}