Exemplo n.º 1
0
void CDiscoveryApp::SetDefaulRoute(in_addr_t gw)
{
	in_addr_t def_dest=inet_addr("0.0.0.0");
	in_addr_t def_mask=inet_addr("0.0.0.0");
	in_addr addr={0};
	char szDevice [64];
	
	
	switch( get_default_gateway( &addr.s_addr, szDevice, sizeof(szDevice) ) )
	{
		case DEFAULT_ETH_INTERF:
			LOG("REPLACING DefaultGW [%s] on %s", inet_ntoa(addr), m_szEthInterf);
			del_route(addr.s_addr);
			set_route(def_dest, gw, def_mask);
		break;

		case DEFAULT_NOT_ETH_INTERF:
			LOG("NOT REPLACING DefaultGW GW [%s] on %s", inet_ntoa(addr), szDevice );
		break;
			
		case DEFAULT_NOT_SET:
			LOG("SETTING DefaultGW [%s] on %s", inet_ntoa(addr), m_szEthInterf);
			set_route(def_dest, gw, def_mask);
		break;
	}
}
Exemplo n.º 2
0
/* 
 * Delete/retain addresses to list and handle the route entries.
 */
void
install_address(struct preflist **plist, struct interface *ifp)
{
	struct preflist *pl, **ppl, *temp;

	/* DELETE FIRST */
	for (pl = *plist, ppl = plist; pl;) {
		temp = pl;
		pl = pl->pl_next;
		if (temp->pl_flag != PL_DELADDR) {
			ppl = &(temp->pl_next);
			continue;
		} else {
			*ppl = pl;
			del_route(temp, ifp);
			free(temp);
		}
	}

	/* AND THEN ADD */
	for (pl = *plist, ppl = plist; pl;) {
		temp = pl;
		pl = pl->pl_next;
		if (temp->pl_flag == PL_NEWADDR) {
			if (ifp->if_flag & IFF_UP && ifp->if_lladdr != NULL)
				add_route(temp, ifp);
		}
		ppl = &(temp->pl_next);
	}

	return;
}
Exemplo n.º 3
0
int del_tun_default_route_v6()
{

    /*
     * Assign route to ::/1 and 8000::/1 via tun interface
     */

    lisp_addr_t dest;
    lisp_addr_t *src = NULL;
    lisp_addr_t gw;
    uint32_t prefix_len = 0;
    uint32_t metric = 0;

    prefix_len = 1;
    metric = 512;

    get_lisp_addr_from_char("::",&gw);

    get_lisp_addr_from_char("::",&dest);

    if (del_route(AF_INET6,
            tun_ifindex,
            &dest,
            src,
            NULL,
            prefix_len,
            metric,
            RT_TABLE_MAIN) != GOOD){
        return (BAD);
    }

    get_lisp_addr_from_char("8000::",&dest);

    if (del_route(AF_INET6,
            tun_ifindex,
            &dest,
            src,
            NULL,
            prefix_len,
            metric,
            RT_TABLE_MAIN) != GOOD){
        return (BAD);
    }

    return(GOOD);
}
Exemplo n.º 4
0
int
ni_set_state(NET ifp, int opcode)
{
   int   err = 0;

   if ((opcode != NI_DOWN) &&
       (opcode != NI_UP))
   {
      return ENP_PARAM;
   }

   LOCK_NET_RESOURCE(NET_RESID);

   if (opcode == NI_DOWN)  /* clean up system tables */
   {
#ifdef INCLUDE_TCP
      if_killsocks(ifp);      /* kill this iface's sockets */
#endif   /* INCLUDE_TCP */
      del_route(0, 0, if_netnumber(ifp));    /* delete any IP routes */
      clear_arp_entries(NULLIP, ifp);        /* delete any ARP entries */
   }

   /* force if-mib AdminStatus flag to correct setting. This will
    * keep devices without n_setstate() calls from receiving any
    * packet to send from ip2mac().
    */
   if (opcode == NI_UP)
      ifp->n_mib->ifAdminStatus = NI_UP;
   else
      ifp->n_mib->ifAdminStatus = NI_DOWN;

   ifp->n_mib->ifLastChange = cticks * (100/TPS);
   if (ifp->n_setstate) /* call state routine if any */
      err = ifp->n_setstate(ifp, opcode);
   else
      err = 0; /* no routine == no error */

   if(!err)
   {
      /* Get here if setstate was OK - set ifOperStatus */
      if (opcode == NI_UP)
         ifp->n_mib->ifOperStatus = NI_UP;
      else
         ifp->n_mib->ifOperStatus = NI_DOWN;
   }

   UNLOCK_NET_RESOURCE(NET_RESID);

   return err;
}
/*
 * Remove all the created rules to the source routing tables
 */
void remove_created_rules()
{
    lispd_iface_list_elt    *interface_list = NULL;
    lispd_iface_elt         *iface          = NULL;

    interface_list = head_interface_list;
    while (interface_list != NULL){
        iface = interface_list->iface;

        if (iface->ipv4_address->afi != AF_UNSPEC){
            if (iface->ipv4_gateway != NULL){
                del_route(AF_INET,iface->iface_index,NULL,NULL,iface->ipv4_gateway,0,0,iface->iface_index);
            }
            del_rule(AF_INET,0,iface->iface_index,iface->iface_index,RTN_UNICAST,iface->ipv4_address,32,NULL,0,0);
        }
        if (iface->ipv6_address->afi != AF_UNSPEC){
            if (iface->ipv6_gateway != NULL){
                del_route(AF_INET6,iface->iface_index,NULL,NULL,iface->ipv6_gateway,0,0,iface->iface_index);
            }
            del_rule(AF_INET6,0,iface->iface_index,iface->iface_index,RTN_UNICAST,iface->ipv6_address,128,NULL,0,0);
        }
        interface_list = interface_list->next;
    }
}
Exemplo n.º 6
0
/* FUNCTION: netmain_route_del()
 *
 * Delete IP route table entry
 *
 * PARAM1: CLI_CTX            CLI context
 *
 * RETURNS: int               0 or error code
 */
STATIC int
netmain_route_del(CLI_CTX ctx)
{
   struct cli_addr *cap;
   ip_addr dst;
   ip_addr mask;
   int ifindex;
   int rc;

   /* extract the destination IP address */
   cap = (struct cli_addr *)CLI_VALUE(ctx, 'd');
   if (cap->type == CLI_IPV4)
   {
      dst = *((ip_addr *)&cap->addr[0]);
   }
   else
   {
      /* failed to parse destination IP address */
      return (CLI_ERR_PARAM);
   }

   /* extract the address mask */
   cap = (struct cli_addr *)CLI_VALUE(ctx, 'm');
   if (cap->type == CLI_IPV4)
   {
      mask = *((ip_addr *)&cap->addr[0]);
   }
   else
   {
      /* failed to parse address mask */
      return (CLI_ERR_PARAM);
   }

   /* extract the interface identifier (zero-based) */
   ifindex = (int)CLI_VALUE(ctx, 'i') - 1;
   if ((ifindex < 0) || (ifindex >= MAXNETS) ||
       (if_getbynum(ifindex) == (NET)NULL))
   {
      /* bad interface index */
      return (CLI_ERR_PARAM);
   }

   /* del_route() returns the number of routes deleted */
   rc = del_route(dst, mask, ifindex);

   return ((rc > 0) ? 0 : CLI_ERR_EXECUTE);
}
Exemplo n.º 7
0
void proxy_instance::refresh_all_traffic(int if_index, const addr_storage& g_addr){
    HC_LOG_TRACE("");

    upstream_src_state_map::iterator iter_uss;
    src_state_map::iterator iter_src;
    state_table_map::iterator iter_table;
    g_state_map::iterator iter_state;
    src_group_state_pair* sgs_pair = 0;

    if(if_index == m_upstream){
        HC_LOG_ERROR("the if_index:" << if_index << " mussnt be the upstream, upstream have no joined groups");
    }

    //process upstream
    iter_uss = m_upstream_state.find(g_addr);
    if(iter_uss != m_upstream_state.end()){ //g_addr found
        for(iter_src = iter_uss->second.begin(); iter_src != iter_uss->second.end(); iter_src++){
            if(!split_traffic(m_upstream, g_addr, iter_src->first)){
                //have to check old upstream source because the have no default stream so they dont refresh themselve like downstreams
                iter_src->second.flag = src_state::UNUSED_SRC;
                del_route(if_index,g_addr,iter_src->first);
            }
        }
    }

    //process downstream
    for(iter_table = m_state_table.begin(); iter_table != m_state_table.end(); iter_table++){
        if(if_index != iter_table->first){

            iter_state = iter_table->second.find(g_addr);

            if(iter_state != iter_table->second.end()){
                sgs_pair = &iter_state->second;

                for(iter_src = sgs_pair->first.begin(); iter_src != sgs_pair->first.end(); iter_src++){
                    split_traffic(iter_table->first, g_addr, iter_src->first);
                }
            }

        }
    }
}
Exemplo n.º 8
0
int main( int argc, char **argv )
{
	uint8 anAddress[4];
	uint8 anMask[4];
	uint8 anGateway[4] = { 0, 0, 0, 0 };
	const char *pzGateway = NULL, *pzProgram;
	const char *pzCommand, *pzNetAddr, *pzNetMask;
	struct rtentry sRoute;
	bool bLong = false;
	bool bNetSet = false, bMaskSet = false, bGwSet = false;
	int c;
	
	if ( (pzProgram = strrchr( *argv, '/' )) != NULL )
		++pzProgram;
	else
		pzProgram = *argv;

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

	sRoute.rt_metric = 0;
	sRoute.rt_flags = RTF_UP | RTF_STATIC; /* Not necessary */

	while ( ( c = getopt_long( argc, argv, "hlqvi:g:", long_opts, ( int * )0 ) ) != EOF )
	{
		switch ( c )
		{
		case 0:
			break;
		case 'l':
			bLong = true;
			break;
		case 'v':
			g_nShowVersion = true;
			break;
		case 'h':
			g_nShowHelp = true;
			break;
		default:
			usage( pzProgram, 0 );
			return ( EXIT_FAILURE );
		}
	}

	argc -= optind;
	argv += optind;
	
	if ( (pzCommand = *argv++) == NULL )
	{
		usage( pzProgram, 0 );
	
		return ( EXIT_FAILURE );
	}
	
	/* Check command is valid */
	if ( strcmp( pzCommand, "list" ) == 0 )
	{
		list_routes( bLong );
		
		return ( EXIT_SUCCESS );
	}
	else if ( strcmp( pzCommand, "add" ) != 0 && strcmp( pzCommand, "del" ) != 0 )
	{
		usage( pzProgram, 0 );

		return ( EXIT_FAILURE );
	}
	
	
	/* Add or delete a route */
	/* Look for address parameter */
	while ( *argv )
	{
		const char *pzInstruction = *argv++;
    char *pzArg = *argv++;
		
		if ( pzArg == NULL )
		{
			/* No argument */
			usage( pzProgram, 0 );

			return ( EXIT_FAILURE );
		}

		if ( strcmp( pzInstruction, "net" ) == 0 )
		{
			char *pzStr;
			
			if( bNetSet == true )
			{
				usage( pzProgram, 0 );

				return ( EXIT_FAILURE );
			}
			
			if( strcmp( pzArg, "default" ) == 0 )
			{
				bNetSet = true;
				bMaskSet = true;
			}
			else
			{
				if( (pzStr = strchr( pzArg, '/' )) != NULL )
				{
					/* CIDR notation in address parameter */
					int nBits;
					uint32 nIpAddr = 0xFFFFFFFF;
					
					*pzStr++ = 0;
					
					if( (nBits = atoi( pzStr )) < 32 )
						nIpAddr <<= (32 - nBits);

					*((uint32 *)&((struct sockaddr_in *)&sRoute.rt_genmask)->sin_addr) = htonl( nIpAddr );
					bMaskSet = true;
				}
				
				/* Interpret as IP address */
				parse_ipaddress( (uint8*)&((struct sockaddr_in *)&sRoute.rt_dst)->sin_addr, pzArg );
				bNetSet = true;
			}
		}
		else if ( strcmp( pzInstruction, "mask" ) == 0 )
		{
			if( bMaskSet == true )
			{
				usage( pzProgram, 0 );

				return ( EXIT_FAILURE );
			}
			
			parse_ipaddress( (uint8*)&((struct sockaddr_in *)&sRoute.rt_genmask)->sin_addr, pzArg );
			bMaskSet = true;
		}
		else if ( strcmp( pzInstruction, "gw" ) == 0 )
		{
			if( bGwSet == true )
			{
				usage( pzProgram, 0 );

				return ( EXIT_FAILURE );
			}
			
			parse_ipaddress( (uint8*)&((struct sockaddr_in *)&sRoute.rt_gateway)->sin_addr, pzArg );
			sRoute.rt_flags |= RTF_GATEWAY;
			bGwSet = true;
		}
		else
		{
			usage( pzProgram, 0 );

			return ( EXIT_FAILURE );
		}
	}
	
	/* Check for required arguments */
	if( !bNetSet || !bMaskSet )
	{
		usage( pzProgram, 0 );

		return ( EXIT_FAILURE );
	}
	
	/* Perform action */
	if ( strcmp( pzCommand, "add" ) == 0 )
	{
		add_route( &sRoute );
	}
	else if ( strcmp( pzCommand, "del" ) == 0 )
	{
		del_route( &sRoute );
	}
	
	return ( EXIT_SUCCESS );
}
Exemplo n.º 9
0
void proxy_instance::handle_config(struct config_msg* c){
    HC_LOG_TRACE("");

    switch(c->type){
    case config_msg::ADD_DOWNSTREAM: {

        //if interface exist
        if(m_state_table.find(c->if_index) != m_state_table.end()){
            HC_LOG_ERROR("failed to add downstream, interface " << c->if_index << " allready exist");
        }

        m_state_table.insert(state_tabel_pair(c->if_index,g_state_map()));
        m_vif_map.insert(vif_pair(c->if_index,c->vif));
        registrate_if(c->if_index);
        break;
    }
    case config_msg::DEL_DOWNSTREAM: {
        //if interface exist
        if(m_state_table.find(c->if_index) == m_state_table.end()){
            HC_LOG_ERROR("failed to del downstream, interface " << c->if_index << " not exist");
        }

        unregistrate_if(c->if_index);

        state_table_map::iterator iter_table;
        g_state_map::iterator iter_state;
        src_group_state_pair* sgs_pair = NULL;
        src_state_map::iterator iter_src;

        iter_table =m_state_table.find(c->if_index);
        if(iter_table == m_state_table.end()) {
            HC_LOG_ERROR("faild to del downstream: cant find if_index: " << c->if_index);
            return;
        }

        vector<addr_storage> tmp_erase_group_vector;
        for(iter_state= iter_table->second.begin(); iter_state != iter_table->second.end(); iter_state++){
            sgs_pair = &iter_state->second;

            //remove all own sources (routes)
            for(iter_src = sgs_pair->first.begin(); iter_src != sgs_pair->first.end(); iter_src++){
                if(iter_src->second.flag == src_state::CACHED_SRC){
                    del_route(iter_table->first, iter_state->first, iter_src->first);
                }
            }

            //save all groups for remove
            tmp_erase_group_vector.push_back(iter_state->first);

            //refresh upstream
            if(!is_group_joined(c->if_index,iter_state->first)){
                if(!m_sender->send_leave(m_upstream, iter_state->first)){
                    HC_LOG_ERROR("failed to leave on upstream group: " << iter_state->first);
                }
            }
        }

        //erase all groups
        for(unsigned int i=0; i< tmp_erase_group_vector.size(); i++){
            if((iter_state = iter_table->second.find(tmp_erase_group_vector[i]))!= iter_table->second.end()){
                iter_table->second.erase(iter_state);

                //calculate the joined group roles
                refresh_all_traffic(c->if_index, tmp_erase_group_vector[i]);
            }else{
                HC_LOG_ERROR("cant find downstream group: " << tmp_erase_group_vector[i]);}

        }

        //clean state table
        m_state_table.erase(iter_table);

        //clean vif map
        vif_map::iterator it_vif_map = m_vif_map.find(c->if_index);
        if(it_vif_map == m_vif_map.end()) {
            HC_LOG_ERROR("faild to del downstream: cant find vif to if_index: " << c->if_index);
            return;
        }
        m_vif_map.erase(it_vif_map);

        //HC_LOG_ERROR("del downstream not implementeted");
        break;
    }
    case config_msg::SET_UPSTREAM: {

        //remove current upstream
        unregistrate_if(c->if_index);

        vif_map::iterator it_vif_map = m_vif_map.find(c->if_index);
        if(it_vif_map == m_vif_map.end()) {
            HC_LOG_ERROR("faild to del downstream: cant find if_index: " << c->if_index);
            return;
        }
        m_vif_map.erase(it_vif_map);

        //ToDo
        //refresh routes?????????????????????????????????
        HC_LOG_ERROR("set upstream not implementeted");


        //set new upstream
        m_upstream = c->if_index;
        m_vif_map.insert(vif_pair(c->if_index,c->vif));
        registrate_if(c->if_index);

        break;
    }
    default: HC_LOG_ERROR("unknown config message format");
    }
}
Exemplo n.º 10
0
void proxy_instance::handle_clock(struct clock_msg* c){
    HC_LOG_TRACE("");

    proxy_msg msg;
    state_table_map::iterator iter_table;
    g_state_map::iterator iter_state;
    src_state_map::iterator iter_src;
    src_group_state_pair* sgs_pair = NULL;


    switch(c->type){
    case clock_msg::SEND_GQ_TO_ALL: {
        //send GQ
        send_gq_to_all();

        m_check_source.check(); //reloade routing table

        //##-- dekrement all counter of all groups on all downstream interfaces in RUNNING state --##
        //##-- and dekrement all counter of all groups source addresses --##
        vector<addr_storage> tmp_erase_group_vector; //if group not joined and all sources are deleted
        for(iter_table= m_state_table.begin(); iter_table != m_state_table.end(); iter_table++){

            for(iter_state= iter_table->second.begin(); iter_state != iter_table->second.end(); iter_state++){
                sgs_pair = &iter_state->second;

                //-- process groups in RUNNING state --
                if( sgs_pair->second.flag == src_state::RUNNING){
                    //if counter == 0 delete this group after query response
                    if(--sgs_pair->second.robustness_counter == 0){
                        sgs_pair->second.flag= src_state::WAIT_FOR_DEL;
                        sgs_pair->second.robustness_counter = PROXY_INSTANCE_DEL_IMMEDIATELY;

                        msg.type = proxy_msg::CLOCK_MSG;
                        msg.msg = new struct clock_msg(clock_msg::DEL_GROUP, iter_table->first, iter_state->first);
                        m_timing->add_time(MC_TV_QUERY_RESPONSE_INTERVAL*1000 /*msec*/,this,msg);
                    }
                }


                //-- process sources in FOREIGN_SRC state -downstream- --
                vector<addr_storage> tmp_erase_source_vector;
                for(iter_src = sgs_pair->first.begin(); iter_src != sgs_pair->first.end(); iter_src++){
                    if(iter_src->second.flag == src_state::UNUSED_SRC || iter_src->second.flag == src_state::CACHED_SRC){
                        //del unused sources
                        vif_map::iterator it_vif_map;
                        if((it_vif_map = m_vif_map.find(iter_table->first)) == m_vif_map.end()){
                            HC_LOG_ERROR("cant find vif to if_index:" << iter_table->first);
                        }

                        if(m_check_source.is_src_unused(it_vif_map->second, iter_src->first, iter_state->first)){
                            iter_src->second.robustness_counter--;
                        }else{
                            iter_src->second.robustness_counter=MC_TV_ROBUSTNESS_VARIABLE;
                        }

                        if(iter_src->second.robustness_counter == 0){
                            //save invalid sources
                            tmp_erase_source_vector.push_back(iter_src->first);

                            //refresh routing
                            if(iter_src->second.flag == src_state::CACHED_SRC){
                                del_route(iter_table->first, iter_state->first, iter_src->first);
                            }

                        }
                    }else{
                        HC_LOG_ERROR("downstream source is in unknown state: " << iter_src->second.state_type_to_string());
                    }
                }
                //erase invalid sources
                for(unsigned int i=0; i< tmp_erase_source_vector.size(); i++){
                    if((iter_src = sgs_pair->first.find(tmp_erase_source_vector[i]))!= sgs_pair->first.end()){
                        sgs_pair->first.erase(iter_src);
                    }else{
                        HC_LOG_ERROR("cant find invalid downstream soruce: " << tmp_erase_source_vector[i]);
                    }
                }

                //if group has no sources and is not joined (flag=INIT) remove the group
                if(sgs_pair->first.size()  == 0){
                    if(sgs_pair->second.flag == src_state::INIT){
                        tmp_erase_group_vector.push_back(iter_state->first);
                    }
                }


            }
            //erase unused groups
            for(unsigned int i=0; i< tmp_erase_group_vector.size(); i++){
                if((iter_state = iter_table->second.find(tmp_erase_group_vector[i]))!= iter_table->second.end()){
                    iter_table->second.erase(iter_state);

                }else{
                    HC_LOG_ERROR("cant find unused groups: " << tmp_erase_group_vector[i]);
                }
            }
            tmp_erase_group_vector.clear();

        }



        //-- process sources in FOREIGN_SRC state -upstream- --
        upstream_src_state_map::iterator tmp_it_up_ss_map;
        src_state_map* tmp_ss_map;
        tmp_erase_group_vector.clear(); //unused groups
        for(tmp_it_up_ss_map = m_upstream_state.begin(); tmp_it_up_ss_map != m_upstream_state.end(); tmp_it_up_ss_map++){

            tmp_ss_map = &tmp_it_up_ss_map->second;
            vector<addr_storage> tmp_erase_source_vector;
            for(iter_src = tmp_ss_map->begin(); iter_src != tmp_ss_map->end(); iter_src++){
                //                if(iter_src->second.flag == src_state::UNUSED_SRC || iter_src->second.flag == src_state::CACHED_SRC){

                //                    //del old sources
                //                    if(--iter_src->second.robustness_counter == 0){
                //                        //save invalid sources
                //                        tmp_erase_source_vector.push_back(iter_src->first);

                //                        //refresh routing
                //                        if(iter_src->second.flag == src_state::CACHED_SRC){
                //                            del_route(m_upstream, tmp_it_up_ss_map->first, iter_src->first);
                //                        }

                //                    }
                //                }else{
                //                    HC_LOG_ERROR("upstream source is in unknown state: " << iter_src->second.state_type_to_string());
                //                }

                if(iter_src->second.flag == src_state::UNUSED_SRC){

                    //del old sources
                    if(--iter_src->second.robustness_counter == 0){
                        //save invalid sources
                        tmp_erase_source_vector.push_back(iter_src->first);
                    }
                }else if(iter_src->second.flag == src_state::CACHED_SRC){

                    if(m_check_source.is_src_unused(m_upstream, iter_src->first, tmp_it_up_ss_map->first)){
                        if(--iter_src->second.robustness_counter == 0){
                            //save invalid sources
                            tmp_erase_source_vector.push_back(iter_src->first);

                            del_route(m_upstream, tmp_it_up_ss_map->first, iter_src->first);
                        }

                    }else{
                        iter_src->second.robustness_counter=MC_TV_ROBUSTNESS_VARIABLE;
                    }


                }else{
                    HC_LOG_ERROR("upstream source is in unknown state: " << iter_src->second.state_type_to_string());
                }


            }
            //erase invalid sources
            for(unsigned int i=0; i< tmp_erase_source_vector.size(); i++){
                if((iter_src = tmp_ss_map->find(tmp_erase_source_vector[i])) != tmp_ss_map->end()){
                    tmp_ss_map->erase(iter_src);
                }else{
                    HC_LOG_ERROR("cant find invalid upstream soruce: " << tmp_erase_source_vector[i]);
                }
            }

            //if group has no sources remove the group
            if(tmp_it_up_ss_map->second.size() == 0){
                tmp_erase_group_vector.push_back(tmp_it_up_ss_map->first);
            }

        }
        //erase unused groups
        for(unsigned int i=0; i < tmp_erase_group_vector.size(); i++){
            tmp_it_up_ss_map = m_upstream_state.find(tmp_erase_group_vector[i]);
            if(tmp_it_up_ss_map != m_upstream_state.end()){
                m_upstream_state.erase(tmp_it_up_ss_map);
            }else{
                HC_LOG_ERROR("cant find unused groups: " << tmp_erase_group_vector[i]);
            }
        }

        //initiate new GQ
        msg.type = proxy_msg::CLOCK_MSG;
        msg.msg = new struct clock_msg(clock_msg::SEND_GQ_TO_ALL);
        m_timing->add_time(MC_TV_QUERY_INTERVAL*1000 /*msec*/,this,msg);
        break;
    }
    case clock_msg::SEND_GSQ: {
        iter_table =m_state_table.find(c->if_index);
        if(iter_table == m_state_table.end()) return;

        iter_state = iter_table->second.find(c->g_addr);
        if(iter_state == iter_table->second.end()) return;

        sgs_pair = &iter_state->second;
        if(sgs_pair->second.flag == src_state::RESPONSE_STATE){
            m_sender->send_group_specific_query(c->if_index,c->g_addr);

            if(--sgs_pair->second.robustness_counter == PROXY_INSTANCE_DEL_IMMEDIATELY){
                sgs_pair->second.flag = src_state::WAIT_FOR_DEL;

                msg.type = proxy_msg::CLOCK_MSG;
                msg.msg = new struct clock_msg(clock_msg::DEL_GROUP, iter_table->first, iter_state->first);
                if(m_addr_family == AF_INET){
                    m_timing->add_time(MC_TV_LAST_MEMBER_QUERY_INTEVAL*1000 /*msec*/,this,msg);
                }else if(m_addr_family == AF_INET6){
                    m_timing->add_time(MC_TV_LAST_LISTENER_QUERY_INTERVAL*1000 /*msec*/,this,msg);
                }else{
                    HC_LOG_ERROR("wrong addr_family: " << m_addr_family);
                    return;
                }
            }else{
                msg.type = proxy_msg::CLOCK_MSG;
                msg.msg = new struct clock_msg(clock_msg::SEND_GSQ, iter_table->first, iter_state->first);

                if(m_addr_family == AF_INET){
                    m_timing->add_time(MC_TV_LAST_MEMBER_QUERY_INTEVAL*1000 /*msec*/,this,msg);
                }else if(m_addr_family== AF_INET6){
                    m_timing->add_time(MC_TV_LAST_LISTENER_QUERY_INTERVAL*1000 /*msec*/,this,msg);
                }else{
                    HC_LOG_ERROR("wrong addr_family: " << m_addr_family);
                    return;
                }
            }
        }
        break;
    }
    case clock_msg::DEL_GROUP:{
        iter_table =m_state_table.find(c->if_index);
        if(iter_table == m_state_table.end()) return;

        iter_state = iter_table->second.find(c->g_addr);
        if(iter_state == iter_table->second.end()) return;

        sgs_pair = &iter_state->second;
        if(sgs_pair->second.flag == src_state::WAIT_FOR_DEL){
            HC_LOG_DEBUG("DEL_GROUP if_index: " << c->if_index << " group: " << c->g_addr);

            //refresh upstream
            if(!is_group_joined(c->if_index,c->g_addr)){
                if(!m_sender->send_leave(m_upstream, c->g_addr)){
                    HC_LOG_ERROR("failed to leave on upstream group: " << c->g_addr);
                }
            }

            //del only if no FOREIGN_SRC available
            if(sgs_pair->first.size() == 0){
                iter_table->second.erase(iter_state);
            }else{ //set groupstate to INIT
                sgs_pair->second.flag = src_state::INIT;
            }

            //refresh routing
            //cout << "in del group: refresh_all_traffic()..." << endl;
            refresh_all_traffic(c->if_index, c->g_addr);
        }

        break;
    }
    case clock_msg::SEND_GQ: break; //start up Query Interval vor new interfaces
    default: HC_LOG_ERROR("unknown clock message foramt");
    }
}
Exemplo n.º 11
0
int configure (const options_t *options, interface_t *iface,
	       const dhcp_t *dhcp)
{
  route_t *route = NULL;
  route_t *new_route = NULL;
  route_t *old_route = NULL;
  struct hostent *he = NULL;
  char newhostname[HOSTNAME_MAX_LEN] = {0};
  char curhostname[HOSTNAME_MAX_LEN] = {0};
  char *dname = NULL;
  int dnamel = 0;

  if (! options || ! iface || ! dhcp)
    return -1;

  /* Remove old routes
     Always do this as the interface may have >1 address not added by us
     so the routes we added may still exist */
  if (iface->previous_routes)
    {
      for (route = iface->previous_routes; route; route = route->next)
	if (route->destination.s_addr || options->dogateway)
	  {
	    int have = 0;
	    if (dhcp->address.s_addr != 0)
	      for (new_route = dhcp->routes; new_route; new_route = new_route->next)
		if (new_route->destination.s_addr == route->destination.s_addr
		    && new_route->netmask.s_addr == route->netmask.s_addr
		    && new_route->gateway.s_addr == route->gateway.s_addr)
		  {
		    have = 1;
		    break;
		  }
	    if (! have)
	      del_route (iface->name, route->destination, route->netmask,
			 route->gateway, options->metric);
	  }
    }

  /* If we don't have an address, then return */
  if (dhcp->address.s_addr == 0)
    {
      if (iface->previous_routes)
	{
	  free_route (iface->previous_routes);
	  iface->previous_routes = NULL;
	}

      /* Only reset things if we had set them before */
      if (iface->previous_address.s_addr != 0)
	{
	  del_address (iface->name, iface->previous_address,
		       iface->previous_netmask);
	  memset (&iface->previous_address, 0, sizeof (struct in_addr));
	  memset (&iface->previous_netmask, 0, sizeof (struct in_addr));

	  restore_resolv (iface->name);

	  /* we currently don't have a resolvconf style programs for ntp/nis */
	  exec_script (options->script, iface->infofile, "down");
	}
      return 0;
    }

  if (add_address (iface->name, dhcp->address, dhcp->netmask,
		   dhcp->broadcast) < 0 && errno != EEXIST)
    return -1;

  /* Now delete the old address if different */
  if (iface->previous_address.s_addr != dhcp->address.s_addr
      && iface->previous_address.s_addr != 0)
    del_address (iface->name, iface->previous_address, iface->previous_netmask);

#ifdef __linux__
  /* On linux, we need to change the subnet route to have our metric. */
  if (iface->previous_address.s_addr != dhcp->address.s_addr
      && options->metric > 0 && dhcp->netmask.s_addr != INADDR_BROADCAST)
    {
      struct in_addr td;
      struct in_addr tg;
      memset (&td, 0, sizeof (td));
      memset (&tg, 0, sizeof (tg));
      td.s_addr = dhcp->address.s_addr & dhcp->netmask.s_addr;
      add_route (iface->name, td, dhcp->netmask, tg, options->metric);
      del_route (iface->name, td, dhcp->netmask, tg, 0);
    }
#endif

  /* Remember added routes */
  if (dhcp->routes)
    {
      route_t *new_routes = NULL;
      int remember;

      for (route = dhcp->routes; route; route = route->next)
	{
	  /* Don't set default routes if not asked to */
	  if (route->destination.s_addr == 0 && route->netmask.s_addr == 0
	      && ! options->dogateway)
	    continue;

	  remember = add_route (iface->name, route->destination,
				route->netmask,  route->gateway,
				options->metric);
	  /* If we failed to add the route, we may have already added it
	     ourselves. If so, remember it again. */
	  if (remember < 0)
	    for (old_route = iface->previous_routes; old_route;
		 old_route = old_route->next)
	      if (old_route->destination.s_addr == route->destination.s_addr
		  && old_route->netmask.s_addr == route->netmask.s_addr
		  && old_route->gateway.s_addr == route->gateway.s_addr)
		{
		  remember = 1;
		  break;
		}

	  if (remember >= 0)
	    {
	      if (! new_routes)
		{
		  new_routes = xmalloc (sizeof (route_t));
		  memset (new_routes, 0, sizeof (route_t));
		  new_route = new_routes;
		}
	      else
		{
		  new_route->next = xmalloc (sizeof (route_t));
		  new_route = new_route->next;
		}
	      memcpy (new_route, route, sizeof (route_t));
	      new_route -> next = NULL;
	    }
	}

      if (iface->previous_routes)
	free_route (iface->previous_routes);

      iface->previous_routes = new_routes;
    }

  if (options->dodns && dhcp->dnsservers)
    make_resolv(iface->name, dhcp);
  else
    logger (LOG_DEBUG, "no dns information to write");

  if (options->dontp && dhcp->ntpservers)
    make_ntp(iface->name, dhcp);

  if (options->donis && (dhcp->nisservers || dhcp->nisdomain))
    make_nis(iface->name, dhcp);

  /* Now we have made a resolv.conf we can obtain a hostname if we need one */
  if (options->dohostname && ! dhcp->hostname)
    {
      he = gethostbyaddr (inet_ntoa (dhcp->address),
			  sizeof (struct in_addr), AF_INET);
      if (he)
	{
	  dname = he->h_name;
	  while (*dname > 32)
	    dname++;
	  dnamel = dname - he->h_name;
	  memcpy (newhostname, he->h_name, dnamel);
	  newhostname[dnamel] = 0;
	}
    }

  gethostname (curhostname, sizeof (curhostname));

  if (options->dohostname
      || strlen (curhostname) == 0
      || strcmp (curhostname, "(none)") == 0
      || strcmp (curhostname, "localhost") == 0)
    {
      if (dhcp->hostname)
	strcpy (newhostname, dhcp->hostname); 

      if (*newhostname)
	{
	  logger (LOG_INFO, "setting hostname to `%s'", newhostname);
	  sethostname (newhostname, strlen (newhostname));
	}
    }

  write_info (iface, dhcp, options);

  if (iface->previous_address.s_addr != dhcp->address.s_addr ||
      iface->previous_netmask.s_addr != dhcp->netmask.s_addr)
    {
      memcpy (&iface->previous_address,
	      &dhcp->address, sizeof (struct in_addr));
      memcpy (&iface->previous_netmask,
	      &dhcp->netmask, sizeof (struct in_addr));
      exec_script (options->script, iface->infofile, "new");
    }
  else
    exec_script (options->script, iface->infofile, "up");

  return 0;
}
Exemplo n.º 12
0
int Handle_Update(unsigned short bgp_len) {
	//unsigned char *buf;
	unsigned char buf[1000];
	u_int16_t *wr_len_p;
	u_int16_t wr_len;
	u_int16_t *pa_len_p;
	u_int16_t pa_len;
	u_int16_t nlri_len;
	u_int8_t *prefix_bits;
	unsigned int prefix_bytes;
	unsigned int pb;
	u_int32_t prefix;
	unsigned char *prefix_start;
	int shift;
	int n;
	unsigned int i;

	// make sure the length we were sent isn't outrageous long
	if (bgp_len > 1000) {
//		if (debug) fprintf(stderr,"Outrageous update length: %d\n", bgp_len);
		bgp_send_notification(BGP_NOTIFY_MAJOR_MSG, BGP_NOTIFY_MINOR_MSG_LEN);
		return(-1);
	}

	// but, make sure the length is long enough to contain the minimum update data
	// bgp header plus 2 bytes for the withdrawn routes length field and 2 bytes for the path attribute length field
	if (bgp_len < BGP_UPDATE_MIN_SIZE) {
//		if (debug) fprintf(stderr,"Too small update length: %d\n", bgp_len);
		bgp_send_notification(BGP_NOTIFY_MAJOR_MSG, BGP_NOTIFY_MINOR_MSG_LEN);
		return(-1);
	}
		
	// alloc memory to hold the bgp update message
//	if ((buf = (unsigned char *)calloc(1, bgp_len-BGP_SIZE)) == NULL) {
//		// not good...
//		if (debug) fprintf(stderr, "Shit...calloc failed\n");
//		bgp_send_notification(BGP_NOTIFY_MAJOR_CEASE, BGP_NOTIFY_MINOR_CEASE_ADDOWN);
//	}

	// read in the rest of the bgp update message
	if ((n = read(STDIN_FILENO, buf, bgp_len-BGP_SIZE)) != bgp_len-BGP_SIZE) {
		// invalid size
//		if (debug) fprintf(stderr,"Update read failed: %d of %d\n", n, bgp_len);
		bgp_send_notification(BGP_NOTIFY_MAJOR_MSG, BGP_NOTIFY_MINOR_MSG_LEN);
		return(-1);
	}

	//
	// start parsing the update message
	//

	// first get the withdrawn routes length
	wr_len_p = (u_int16_t *)buf;
	wr_len = ntohs(*wr_len_p);

	// make sure the indicated length matches up with the packet length we've received
	if (bgp_len < BGP_UPDATE_MIN_SIZE + wr_len) {
		// invalid size
//		if (debug) fprintf(stderr,"Withdrawn routes length not valid: %d\n", wr_len);
		bgp_send_notification(BGP_NOTIFY_MAJOR_MSG, BGP_NOTIFY_MINOR_MSG_LEN);
		return(-1);
	}

	// next, get the total path attribute length
	//pa_len_p = (u_int16_t *)(buf+2+*wr_len_p);
	pa_len_p = (u_int16_t *)(buf+2+wr_len);
	pa_len = ntohs(*pa_len_p);

	// make sure the indicated length matches up with the packet length we've received
	if (bgp_len < BGP_UPDATE_MIN_SIZE + wr_len + pa_len) {
		// invalid size
//		if (debug) fprintf(stderr,"bgp_len (%d) != 2 + wr_len (%d) + pa_len (%d)\n", bgp_len, wr_len, pa_len);
		bgp_send_notification(BGP_NOTIFY_MAJOR_MSG, BGP_NOTIFY_MINOR_MSG_LEN);
		return(-1);
	}
	
	// finally, figure out the NLRI length
	nlri_len = bgp_len - BGP_UPDATE_MIN_SIZE - wr_len - pa_len;
//	if (debug) fprintf(stderr,"nlri_len %d\n", nlri_len);

	// at this point, we know the lengths of the various update message sections
	// so, start parsing each section

	//
	// first, parse the withdrawn routes
	//
	i = 0;
	while (i < wr_len) {
		// get the length of the prefix in bits
		// offset from beginning of buf = length of withdrawn routes length field + i
		// new check that sizeof works like we want here
		prefix_bits = (u_int8_t *)(buf + sizeof(wr_len_p) + i);

		// make sure prefix_bits are valid
		if (*prefix_bits > 32) {
			bgp_send_notification(BGP_NOTIFY_MAJOR_UPDATE, BGP_NOTIFY_MINOR_UPDATE_BADATTR);
			return(-1);
		}

		// round up to the octet boundry
		if (*prefix_bits % 8 == 0) {
			prefix_bytes = (int)(*prefix_bits/8);
		} else {
			prefix_bytes = (int)((*prefix_bits/8)+1);
		}

		// make sure the prefix length we're told isn't more than the 
		// remaining size of the withdrawn routes field
		// i + prefix length byte + prefix length
		if (i+sizeof(prefix_bits)+prefix_bytes > wr_len) {
			bgp_send_notification(BGP_NOTIFY_MAJOR_MSG, BGP_NOTIFY_MINOR_MSG_LEN);
			return(-1);
		}

		// looks ok, so parse the prefix
		prefix = 0;
		shift = 24;
		prefix_start = (unsigned char *)(buf + sizeof(wr_len_p) + i + sizeof(prefix_bits));
		pb = prefix_bytes;
		while (pb--) {
			prefix = prefix | ((*prefix_start)<<shift);
			shift -= 8;
			prefix_start += 1;
		}

		// remove this prefix from our routing table for this client
//		if (debug) fprintf(stderr,"Removing prefix %08x from routing table\n", prefix);
		del_route(ntohl(prefix), *prefix_bits);

		// move on to the next prefix
		//i += sizeof(prefix_bits)+prefix_bytes;
		i += 1+prefix_bytes;

	}
//	if (debug) fprintf(stderr,"Done parsing withdrawn routes\n");

	//
	// next, parse the path attributes
	//
	if (pa_len == 0) {
		// nothing to do...only withdrawn routes are listed in this update
		return(0);
	}

	return(Parse_Path_Attributes(buf+sizeof(wr_len)+wr_len+sizeof(pa_len), pa_len, nlri_len));
	
}