Exemple #1
0
void imp_input_report_mldv2(imp_interface *p_if, struct mld_hdr *p_mldh, int buf_len)
{
    int i = 0, num = 0, cur_len = 0;
    pi_addr pig;

    num =  ntohs(p_mldh->mld_num_multi);
    cur_len += sizeof(struct icmp6_hdr);

    for (; i < num; i++) {

        struct imp_multi_rec* p_rec = (struct imp_multi_rec*)((char*)p_mldh + cur_len);
         pa_list *p_src_list = NULL;
         int k;

        imp_build_piaddr(AF_INET6, &p_rec->multi_addr, &pig);
        IMP_LOG_DEBUG("group is = %s\n", imp_pi_ntoa(&pig));

        if (imp_verify_multicast_addr(&pig) < 0)
            continue;

        cur_len += (ntohl(p_rec->src_num)*sizeof(struct in6_addr) +
                        sizeof(struct imp_multi_rec));

        if (cur_len > buf_len) {

            IMP_LOG_ERROR("exceed buffer\n");
            return;
        }

        for (k = 0; k < p_rec->src_num; k++) {

            pi_addr pa;
            imp_build_piaddr(AF_INET6, &p_rec->src_list[k], &pa);
            p_src_list = pa_list_add(p_src_list, &pa);
        }

        switch (p_rec->rec_type) {

            case MLD_MODE_IS_INCLUDE:
                IMP_LOG_INFO("MLD_MODE_IS_INCLUDE\n");
                mcast_is_in_handler(p_if, &pig, p_src_list, IM_IGMPv3_MLDv2);
                break;
            case MLD_MODE_IS_EXCLUDE:
                IMP_LOG_INFO("MLD_MODE_IS_EXCLUDE\n");
                mcast_is_ex_hander(p_if, &pig, p_src_list, IM_IGMPv3_MLDv2);
                break;
            case MLD_CHANGE_TO_INCLUDE:
                /*leave */
                IMP_LOG_INFO("MLD_CHANGE_TO_INCLUDE\n");
                mcast_to_in_handler(p_if, &pig, p_src_list, IM_IGMPv3_MLDv2);
                break;
            case MLD_CHANGE_TO_EXCLUDE:
                /*join*/
                IMP_LOG_INFO("MLD_CHANGE_TO_EXCLUDE\n");
                mcast_to_ex_hander(p_if, &pig, p_src_list, IM_IGMPv3_MLDv2);
                break;
            case MLD_ALLOW_NEW_SOURCES:
                IMP_LOG_INFO("MLD_ALLOW_NEW_SOURCES\n");
                mcast_allow_handler(p_if, &pig, p_src_list, IM_IGMPv3_MLDv2);
                break;
            case MLD_BLOCK_OLD_SOURCES:
                IMP_LOG_INFO("MLD_BLOCK_OLD_SOURCES\n");
                mcast_block_handler(p_if, &pig, p_src_list, IM_IGMPv3_MLDv2);
                break;
            default:
                IMP_LOG_ERROR("error group type\n");
                pa_list_cleanup(&p_src_list);
                return;
        }
        imp_membership_db_update(&pig);
        pa_list_cleanup(&p_src_list);

    }
}
Exemple #2
0
static void test3_base_test()
{
	int ret;
	SUDevID devid;

	ret = SU_Base_GetDevID(&devid);
	if (ret < 0) {
		IMP_LOG_ERR(TAG, "SU_Base_GetDevID() error\n");
		CU_FAIL();
		return;
	}

	IMP_LOG_INFO(TAG, "Device ID: %s\n", &devid.chr);

	SUTime now_save;
	ret = SU_Base_GetTime(&now_save);
	if (ret < 0) {
		IMP_LOG_ERR(TAG, "SU_Base_GetTime() error\n");
		CU_FAIL();
		return;
	}

	IMP_LOG_INFO(TAG, "Now: %d.%d.%d %d:%d:%d\n",
				 now_save.year, now_save.mon, now_save.mday,
				 now_save.hour , now_save.min, now_save.sec);

	SUTime time_to_set, now;
#define TEST_SET_GET_TIME(Y, MON, D, H, MIN, S)			\
	time_to_set.year = Y;								\
	time_to_set.mon = MON;								\
	time_to_set.mday = D;								\
	time_to_set.hour = H;								\
	time_to_set.min = MIN;								\
	time_to_set.sec = S;								\
														\
	ret = SU_Base_SetTime(&time_to_set);				\
	if (ret < 0) {										\
		IMP_LOG_ERR(TAG, "SU_Base_SetTime() error\n");	\
		CU_FAIL();										\
		return;											\
	}													\
														\
	ret = SU_Base_GetTime(&now);						\
	if (ret < 0) {										\
		IMP_LOG_ERR(TAG, "SU_Base_GetTime() error\n");	\
		CU_FAIL();										\
		return;											\
	}													\
	IMP_LOG_DBG(TAG, "After set: %d.%d.%d %d:%d:%d\n",	\
				now.year, now.mon, now.mday,			\
				now.hour , now.min, now.sec);			\
	if ((now.year = time_to_set.year)					\
		&& (now.mon == time_to_set.mon)					\
			&& (now.mday == time_to_set.mday)			\
			&& (now.hour == time_to_set.hour)			\
		&& (now.min == time_to_set.min)					\
		&& (now.sec >= time_to_set.sec)) {				\
		;												\
	} else {											\
		CU_FAIL();										\
		return;											\
	}

	TEST_SET_GET_TIME(2015, 1, 26, 21, 13, 20);
	TEST_SET_GET_TIME(2010, 12, 14, 9, 1, 2);

	ret = SU_Base_SetTime(&now_save);
	if (ret < 0) {
		IMP_LOG_ERR(TAG, "SU_Base_SetTime() error\n");
		CU_FAIL();
		return;
	}

	ret = SU_Base_GetTime(&now);
	if (ret < 0) {
		IMP_LOG_ERR(TAG, "SU_Base_SetTime() error\n");
		CU_FAIL();
		return;
	}

	IMP_LOG_INFO(TAG, "Restore: %d.%d.%d %d:%d:%d\n",
				 now.year, now.mon, now.mday,
				 now.hour , now.min, now.sec);

	CU_PASS();
}
Exemple #3
0
static int imp_verify_multicast_addr(pi_addr *p_pia)
{

    if(p_pia->ss.ss_family == AF_INET6) {

        if (!IN6_IS_ADDR_MULTICAST(p_pia->v6.sin6_addr.s6_addr)) {

            IMP_LOG_ERROR("Address %s isn't multicast address\n",
                           imp_pi_ntoa(p_pia));
            return -1;
        }
        /* Interface-Local scope spans only a single interface on a node
         * and is useful only for loopback transmission of multicast.
         *
         * Link-Local multicast scope spans the same topological region as
         * the corresponding unicast scope.
         * [RFC 4291 section 2.7]
         */

        if (IN6_IS_ADDR_MC_LINKLOCAL(p_pia->v6.sin6_addr.s6_addr) ||
            IN6_IS_ADDR_MC_NODELOCAL(p_pia->v6.sin6_addr.s6_addr)) {

            IMP_LOG_WARNING("Group address %s is link-local multicast address\n",
                           imp_pi_ntoa(p_pia));
            return -1;
        }
        /*
         * Nodes must not originate a packet to a multicast address whose scop
         * field contains the reserved value 0; if such a packet is received, it
         * must be silently dropped.  Nodes should not originate a packet to a
         * multicast address whose scop field contains the reserved value F; if
         * such a packet is sent or received, it must be treated the same as
         * packets destined to a global (scop E) multicast address.
         * [RFC 4291 section 2.7]
         */
         if ((p_pia->v6.sin6_addr.s6_addr[1] & 0x0f) == 0) {

            IMP_LOG_WARNING("group address %s's scope is 0, Ignore it.\n",
                             imp_pi_ntoa(p_pia));
            return -1;
        }
    } else if(p_pia->ss.ss_family == AF_INET) {

        if (!IN_MULTICAST(p_pia->v4.sin_addr.s_addr)) {

            IMP_LOG_ERROR("group address %s isn't multicast adddress\n",
                          imp_pi_ntoa(p_pia));
            return -1;
        }

        /*
         *    Address Range                 Size       Designation
         *    -------------                 ----       -----------
         *    224.0.0.0 - 224.0.0.255       (/24)      Local Network Control Block
         *
         *    Addresses in the Local Network Control Block are used for protocol
         *    control traffic that is not forwarded off link.
         *    [RFC 5771 section 4]
         */
        if (IN_LOCAL_CONTROL_BLOCK(p_pia->v4.sin_addr.s_addr)) {

            IMP_LOG_INFO("Group address %s is Local Network Control Block\n",
                          imp_pi_ntoa(p_pia));
            return -1;
        }

	/* 239.255.0.0/16 is defined to be the IPv4 Local Scope.
	 * [RFC 2365 section 6.1]
	 */

        if (IN_LOCAL_SCOPE_BLOCK(p_pia->v4.sin_addr.s_addr)) {

            IMP_LOG_INFO("Group address %s belongs to IPv4 Local Scope.\n",
                          imp_pi_ntoa(p_pia));
            return -1;
        }


    }else
        return -1;

    return 0;
}
Exemple #4
0
void mcast_block_handler(imp_interface *p_if, pi_addr *p_ga,
     pa_list* p_src_list, im_version version)
{
    imp_group   *p_gp = NULL;
    pa_list     *p_node = NULL;;

    p_gp = imp_group_find(p_if, p_ga);

    if (p_gp != NULL) {

        imp_source  *p_is = NULL, *p_is_next = NULL;
        int enable_sch = 0;
        struct timeval lmqt;

        imp_time_val(TIMER_LMQT, &lmqt);

        if (p_gp->version < version && version == IM_IGMPv3_MLDv2) {

            IMP_LOG_INFO("Group %s Group Compatibility Mode" \
                "is lesser than IGMPV3\n", imp_pi_ntoa(&p_gp->group_addr));
            return;
        }

        /*update version timer*/
        imp_group_version_timer_update(p_gp, version);

        if(p_gp->type == GROUP_INCLUDE) {

            /*INCLUDE (A)    BLOCK (B)    INCLUDE (A)             Send Q(G, A*B)*/
             for(p_is = LIST_FIRST(&p_gp->src_list); p_is;
                p_is = p_is_next) {

                if (pa_list_find(p_src_list, &p_is->src_addr) != NULL &&
                    TIMEVAL_LT(lmqt, p_is->timer->tm)) {

                    imp_set_timer(TIMER_LMQT, p_is->timer);
                    p_is->times = DEFAULT_RV;
                    enable_sch = 1;
                }
            }

        } else {
            /*EXCLUDE (X, Y)  BLOCK (A)    EXCLUDE (X+(A-Y), Y)     (A-X-Y)=Group Timer
                                                                    Send Q(G, A-Y)*/

            for (p_node = p_src_list ;p_node; p_node = p_node->next ){


                if (imp_source_find(p_gp, &p_node->addr, BLOCKING) == NULL) {

                    p_is = imp_source_find(p_gp, &p_node->addr, FORWARDING);

                    if (p_is == NULL) {

                        p_is = imp_source_create(p_gp, &p_node->addr, FORWARDING);

                        /*(A-X-Y)=Group Timer*/
                        memcpy(&p_is->timer->tm, &p_gp->timer->tm, sizeof(struct timeval));
                    }

                    /*Send Q(G, A-Y)*/
                    if(TIMEVAL_LT(lmqt, p_is->timer->tm)) {

                        p_is->times = DEFAULT_RV;
                        enable_sch = 1;
                        imp_set_timer(TIMER_LMQT, p_is->timer);

                    }

                }
            }

         }

        if(enable_sch && p_gp->sch_timer == NULL ) {

            p_gp->sch_timer = imp_add_timer(group_source_specific_timer_handler, p_gp);
            imp_set_timer(0, p_gp->sch_timer);
        }

        return;
    }

}
Exemple #5
0
void mcast_allow_handler(imp_interface *p_if, pi_addr *p_ga,
     pa_list* p_src_list, im_version version)
{
    imp_group *p_gp = NULL;
    pa_list   *p_node = NULL;;

    p_gp = imp_group_find(p_if, p_ga);
    if (p_gp != NULL) {

        imp_source  *p_is = NULL, *p_is_next = NULL;

        if (p_gp->version < version && version == IM_IGMPv3_MLDv2) {

            IMP_LOG_INFO("Group %s Group Compatibility Mode" \
                "is lesser than IGMPV3\n", imp_pi_ntoa(&p_gp->group_addr));
            return;
        }

        /*update version timer*/
        imp_group_version_timer_update(p_gp, version);

        if(p_gp->type == GROUP_INCLUDE) {

            /*INCLUDE (A)    ALLOW (B)      INCLUDE (A+B)           (B)=GMI*/

            for (p_node = p_src_list ;p_node; p_node = p_node->next ){

                p_is = imp_source_find(p_gp, &p_node->addr, FORWARDING);
                if (p_is == NULL) {

                    imp_source_create(p_gp, &p_node->addr, FORWARDING);
                } else {

                    imp_set_timer(TIMER_GMI, p_is->timer);
                }
            }

        } else {
            /*EXCLUDE (X, Y)  ALLOW (A)    EXCLUDE (X+A, Y-A)       (A)=GMI*/

            for (p_node = p_src_list ;p_node; p_node = p_node->next ){

                p_is = imp_source_find(p_gp, &p_node->addr, FORWARDING);
                if (p_is == NULL) {

                    imp_source_create(p_gp, &p_node->addr, FORWARDING);
                } else {

                    imp_set_timer(TIMER_GMI, p_is->timer);
                }
            }

             for(p_is = LIST_FIRST(&p_gp->src_list); p_is;
                p_is = p_is_next) {

                p_is_next = LIST_NEXT(p_is, link);
                if (!TIMEVAL_ISZERO(p_is->timer->tm))
                    continue;

                if( pa_list_find(p_src_list, &p_is->src_addr) != NULL)
                    imp_source_cleanup(p_is);
            }


         }
        return;
    }

    imp_group_print(p_if);
}
Exemple #6
0
void mcast_is_ex_hander(imp_interface *p_if, pi_addr *p_ga,
    pa_list* p_src_list, im_version version)
{
    imp_group *p_gp = NULL;
    pa_list *p_node = NULL;;


    p_gp = imp_group_find(p_if, p_ga);
    if (p_gp != NULL) {

        if (p_gp->version < version && version == IM_IGMPv3_MLDv2) {

            IMP_LOG_INFO("Group %s Group Compatibility Mode" \
                "is lesser than IGMPV3\n", imp_pi_ntoa(&p_gp->group_addr));
            return;
        }

        /*update version timer*/
        imp_group_version_timer_update(p_gp, version);

        if(p_gp->type == GROUP_INCLUDE) {
            /* Router State   Report Rec'd  New Router State     Actions
             * ------------   ------------  ----------------     -------
             *  INCLUDE (A)    IS_EX (B)     EXCLUDE (A*B, B-A)   (B-A)=0
             *                                                    Delete (A-B)
             *                                                    Group Timer=GMI
             */

            imp_source  *p_is = NULL, *p_is_next = NULL;

            for (p_is = LIST_FIRST(&p_gp->src_list); p_is ;
                    p_is = p_is_next) {

                p_is_next = LIST_NEXT(p_is, link);
                if(pa_list_find(p_src_list, &p_is->src_addr) == NULL) {
                    /*Delete (A-B)*/
                    imp_source_cleanup(p_is);
                }
            }

            for(p_node = p_src_list; p_node; p_node = p_node->next) {

                if (imp_source_find(p_gp, &p_node->addr, FORWARDING) == NULL){
                    /*(B-A)=0*/
                    imp_source_create(p_gp, &p_node->addr, BLOCKING);/*forward or not*/
                }
            }

            p_gp->type = GROUP_EXCLUDE;


            p_gp->timer = imp_add_timer(group_timer_handler, p_gp);
            /*Group Timer=GMI*/
            imp_set_timer(TIMER_GMI, p_gp->timer);

        } else {

            /*  Router State   Report Rec'd  New Router State   Actions
                *  ------------   ------------  ----------------   -------
             *  EXCLUDE (X, Y)  IS_EX (A)     EXCLUDE (A-Y, Y*A)    (A-X-Y)=GMI
             *                                                    Delete (X-A)
             *                                                    Delete (Y-A)
             *                                                    Group Timer=GMI
             */
            imp_source  *p_is = NULL, *p_is_next = NULL;

            for (p_is = LIST_FIRST(&p_gp->src_list); p_is ;
                    p_is = p_is_next) {

                p_is_next = LIST_NEXT(p_is, link);

                if(TIMEVAL_ISZERO(p_is->timer->tm))
                    continue;
                /*Delete (X-A)*/
                if(pa_list_find(p_src_list, &p_is->src_addr) == NULL) {
                    imp_source_cleanup(p_is);
                }
            }


            for (p_is = LIST_FIRST(&p_gp->src_list); p_is ;
                    p_is = p_is_next) {

                p_is_next = LIST_NEXT(p_is, link);

                if(!TIMEVAL_ISZERO(p_is->timer->tm))
                    continue;

                /*Delete (Y-A)*/
                if(pa_list_find(p_src_list, &p_is->src_addr) == NULL) {
                    imp_source_cleanup(p_is);
                }
            }

            for(p_node = p_src_list; p_node; p_node = p_node->next) {

                if (imp_source_find(p_gp, &p_node->addr, BLOCKING) == NULL
                    && imp_source_find(p_gp, &p_node->addr, FORWARDING) == NULL){
                    /*(A-X-Y)=GMI*/
                    imp_source_create(p_gp, &p_node->addr, FORWARDING);/*forward or not*/
                }
            }

            /*Group Timer=GMI*/
            imp_set_timer(TIMER_GMI, p_gp->timer);

        }

        return;
    }

    p_gp = imp_group_create(p_if, p_ga, p_src_list, GROUP_EXCLUDE, version);

    if (p_gp == NULL) {
        IMP_LOG_ERROR("imp_group_create failed");
        return;
    }


    imp_group_print(p_if);
    return;

}
Exemple #7
0
void mcast_to_ex_hander(imp_interface *p_if, pi_addr *p_ga,
     pa_list* p_src_list, im_version version)
{
    imp_group *p_gp = NULL;
    pa_list *p_node = NULL;;

    p_gp = imp_group_find(p_if, p_ga);
    if (p_gp != NULL) {

        imp_source     *p_is = NULL, *p_is_next = NULL;
        int             enable_sch = 0;
        struct timeval  lmqt;

        imp_time_val(TIMER_LMQT, &lmqt);

        if (p_gp->version < version && version == IM_IGMPv3_MLDv2) {

            IMP_LOG_INFO("Group %s Group Compatibility Mode" \
                "is lesser than IGMPV3\n", imp_pi_ntoa(&p_gp->group_addr));
            return;
        }

        /*update version timer*/
        imp_group_version_timer_update(p_gp, version);


        if(p_gp->type == GROUP_INCLUDE) {
            /* Router State   Report Rec'd  New Router State     Actions
             * ------------   ------------  ----------------     -------
             *  INCLUDE (A)    TO_EX (B)    EXCLUDE (A*B, B-A)   (B-A)=0
             *                                                    Send Q(G, A*B)
             *                                                    Delete (A-B)
             *                                                    Group Timer=GMI
             */


            for (p_is = LIST_FIRST(&p_gp->src_list); p_is ;
                    p_is = p_is_next) {

                p_is_next = LIST_NEXT(p_is, link);
                if(pa_list_find(p_src_list, &p_is->src_addr) == NULL) {

                    /*Delete (A-B)*/
                    imp_source_cleanup(p_is);
                } else if(TIMEVAL_LT(lmqt, p_is->timer->tm)) {

                    /*Send Q(G, A*B)*/
                    imp_set_timer(TIMER_LMQT, p_is->timer);
                    p_is->times = DEFAULT_RV;
                    enable_sch = 1;
                }
            }

            for(p_node = p_src_list; p_node; p_node = p_node->next) {

                if (imp_source_find(p_gp, &p_node->addr, FORWARDING) == NULL){

                    /*(B-A)=0*/
                    imp_source_create(p_gp, &p_node->addr, BLOCKING);/*forward or not*/
                }
            }

            p_gp->type = GROUP_EXCLUDE;

            p_gp->timer = imp_add_timer(group_timer_handler, p_gp);
            /*Group Timer=GMI*/
            imp_set_timer(TIMER_GMI, p_gp->timer);

        } else {

            /*  Router State   Report Rec'd  New Router State   Actions
                *  ------------   ------------  ----------------   -------
             *  EXCLUDE (X, Y)  TO_EX (A)     EXCLUDE (A-Y, Y*A)    (A-X-Y)=Group Timer
             *                                                    Delete (X-A)
             *                                                    Delete (Y-A)
             *                                                    Send Q(G, A-Y)
             *                                                    Group Timer=GMI
             */

            for (p_is = LIST_FIRST(&p_gp->src_list); p_is ;
                    p_is = p_is_next) {

                p_is_next = LIST_NEXT(p_is, link);

                if(TIMEVAL_ISZERO(p_is->timer->tm))
                    continue;
                if(pa_list_find(p_src_list, &p_is->src_addr) == NULL) {

                    /*Delete (X-A)*/
                    imp_source_cleanup(p_is);
                } else if(TIMEVAL_LT(lmqt, p_is->timer->tm)) {

                    /*Send Q(G, A-Y)*/
                    imp_set_timer(TIMER_LMQT, p_is->timer);
                    p_is->times = DEFAULT_RV;
                    enable_sch = 1;
                }
            }


            for (p_is = LIST_FIRST(&p_gp->src_list); p_is ;
                    p_is = p_is_next) {

                p_is_next = LIST_NEXT(p_is, link);
                if(!TIMEVAL_ISZERO(p_is->timer->tm))
                    continue;
                /*Delete (Y-A)*/
                if(pa_list_find(p_src_list, &p_is->src_addr) == NULL) {
                    imp_source_cleanup(p_is);
                }
            }

            for(p_node = p_src_list; p_node; p_node = p_node->next) {

                if (imp_source_find(p_gp, &p_node->addr, BLOCKING) == NULL
                    && imp_source_find(p_gp, &p_node->addr, FORWARDING) == NULL){
                    /*(A-X-Y)=Group Timer*/
                    p_is = imp_source_create(p_gp, &p_node->addr, FORWARDING);/*forward or not*/
                    memcpy(&p_is->timer->tm, &p_gp->timer->tm, sizeof(struct timeval));

                    if(TIMEVAL_LT(lmqt, p_is->timer->tm)) {

                        imp_set_timer(TIMER_LMQT, p_is->timer);
                        p_is->times = DEFAULT_RV;
                        enable_sch = 1;
                    }
                }
            }

            /*Group Timer=GMI*/
            imp_set_timer(TIMER_GMI, p_gp->timer);

        }

        if(enable_sch && p_gp->sch_timer == NULL) {

            p_gp->sch_timer = imp_add_timer(group_source_specific_timer_handler, p_gp);
            imp_set_timer(0, p_gp->sch_timer);
        }

        imp_membership_db_update(p_ga);

        return;
    }

    p_gp = imp_group_create(p_if, p_ga, p_src_list, GROUP_EXCLUDE, version);

    if (p_gp == NULL) {
        IMP_LOG_ERROR("imp_group_create failed");
        return;
    }

    imp_membership_db_update(p_ga);
    imp_group_print(p_if);

}