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); } }
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(); }
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; }
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; } }
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); }
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; }
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); }