JNIEXPORT void JNICALL Java_ow_ipmulticast_Native_leaveGroup(JNIEnv *env, jclass clazz, jint group, jint ifLocalAddr, jint ifIndex) { struct uvif u; u.uv_ifindex = (int)ifIndex; u.uv_lcl_addr = (uint32_t)htonl(ifLocalAddr); k_leave(sock_dgram_send, (uint32_t)htonl(group), &u); }
void stop_vif(mifi_t vifi) { struct uvif *v; struct listaddr *a; register pim_nbr_entry_t *n; register pim_nbr_entry_t *next; struct vif_acl *acl; /* * TODO: make sure that the kernel viftable is * consistent with the daemon table */ v = &uvifs[vifi]; if (!(v->uv_flags & MIFF_REGISTER)) { k_leave(pim6_socket, &allpim6routers_group.sin6_addr, v->uv_ifindex); k_leave(mld6_socket, &allrouters_group.sin6_addr, v->uv_ifindex); /* * Discard all group addresses. (No need to tell kernel; * the k_del_vif() call will clean up kernel state.) */ while (v->uv_groups != NULL) { a = v->uv_groups; v->uv_groups = a->al_next; /* reset all the timers */ if (a->al_query) { timer_clearTimer(a->al_query); } if (a->al_comp) { timer_clearTimer(a->al_comp); } if (a->al_timerid) { timer_clearTimer(a->al_timerid); } /* frees all the related sources */ while (a->sources != NULL) { struct listaddr *curr = a->sources; a->sources = a->sources->al_next; free((char *)curr); } a->sources = NULL; /* discard the group */ free((char *)a); } v->uv_groups = NULL; } /* * TODO: inform (eventually) the neighbors I am going down by sending * PIM_HELLO with holdtime=0 so someone else should become a DR. */ /* TODO: dummy! Implement it!! Any problems if don't use it? */ delete_vif_from_mrt(vifi); /* * Delete the interface from the kernel's vif structure. */ k_del_vif(mld6_socket, vifi); v->uv_flags = (v->uv_flags & ~VIFF_QUERIER & ~VIFF_NONBRS) | VIFF_DOWN; if (!(v->uv_flags & MIFF_REGISTER)) { RESET_TIMER(v->uv_pim_hello_timer); RESET_TIMER(v->uv_jp_timer); RESET_TIMER(v->uv_gq_timer); for (n = v->uv_pim_neighbors; n != NULL; n = next) { /* Free the space for each neighbour */ next = n->next; delete_pim6_nbr(n); } v->uv_pim_neighbors = NULL; } if (v->uv_querier != NULL) { free(v->uv_querier); v->uv_querier = NULL; } /* I/F address list */ { struct phaddr *pa, *pa_next; for (pa = v->uv_addrs; pa; pa = pa_next) { pa_next = pa->pa_next; free(pa); } } v->uv_addrs = NULL; v->uv_linklocal = NULL; /* uv_linklocal must be in uv_addrs */ /* TODO: currently not used */ /* The Access Control List (list with the scoped addresses) */ while (v->uv_acl != NULL) { acl = v->uv_acl; v->uv_acl = acl->acl_next; free((char *)acl); } vifs_down = TRUE; IF_DEBUG(DEBUG_IF) log_msg(LOG_DEBUG, 0, "%s goes down, vif #%u out of service", v->uv_name, vifi); }