21static ptrPIM_JOINPRUNE_MSG alloc_pim_joinprune()
23 ptrPIM_JOINPRUNE_MSG jp = (ptrPIM_JOINPRUNE_MSG)calloc(1,
sizeof* jp);
24 set_pim_hdr(&jp->hdr, PIMMSG_JoinPrune);
29static NetSim_PACKET* create_pim_joinprune(NETSIM_ID dev,
33 ptrPIM_JOINPRUNE_MSG jp = alloc_pim_joinprune();
34 NetSim_PACKET* packet = create_pim_packet(PIMMSG_JoinPrune,
38 DEVICE_NWADDRESS(dev, 1),
46static ptrPIM_JOINMSG_GROUP pim_join_add_group_member(NETSIM_ID d,
47 NETSIM_IPAddress groupAddr,
48 ptrPIM_JOINPRUNE_MSG jp,
52 ptrPIM_JOINMSG_GROUP msg = jp->groups[c];
55 msg = calloc(1,
sizeof* msg);
57 msg->numJoinedSource = 1;
58 msg->joinedSourceAddr = calloc(1,
sizeof* msg->joinedSourceAddr);
60 msg->multicastAddr = encode_group_addr(groupAddr);
64 msg->joinedSourceAddr = realloc(msg->joinedSourceAddr,
65 (msg->numJoinedSource + 1) *
sizeof* msg->joinedSourceAddr);
66 i = msg->numJoinedSource;
67 msg->numJoinedSource++;
69 msg->joinedSourceAddr[i] = encode_source_addr(DEVICE_NWADDRESS(d, 1),
70 DEVICE_INTERFACE(d, 1)->szSubnetMask);
74static ptrPIM_JOINMSG_GROUP jP_find_groups(ptrPIM_JOINPRUNE_MSG jp, NETSIM_IPAddress m, UINT* in)
77 for (i = 0; i < jp->numGroups; i++)
79 if (!IP_COMPARE(jp->groups[i]->multicastAddr->GroupMulticastAddr, m))
88static void pim_join_add_group(NETSIM_ID d,
89 NetSim_PACKET* packet,
91 ptrPIM_NEIGHBOR neighbor)
93 ptrPIM_JOINPRUNE_MSG jp = get_PIM_MSG(packet);
97 jp->holdTime = (UINT16)(3.5*(GET_PIM_VAR(d)->t_periodic / SECOND));
98 jp->unicastAddr = encode_unicast_addr(neighbor->neighborAddr);
99 jp->groups = calloc(jp->numGroups,
sizeof* jp->groups);
100 jp->groups[0] = pim_join_add_group_member(d, group->groupAddress, jp, 0);
105 jp->holdTime = (UINT16)(3.5*(GET_PIM_VAR(d)->t_periodic / SECOND));
106 jp->unicastAddr = encode_unicast_addr(neighbor->neighborAddr);
107 ptrPIM_JOINMSG_GROUP g = jP_find_groups(jp, group->groupAddress,&i);
111 jp->groups = realloc(jp->groups, (jp->numGroups + 1) *
sizeof* jp->groups);
113 jp->groups = calloc(1,
sizeof* jp->groups);
114 g = jp->groups[jp->numGroups];
116 i = jp->numGroups - 1;
118 jp->groups[i] = pim_join_add_group_member(d, group->groupAddress, jp, i);
122static ptrPIM_NEIGHBOR pimjoin_find_neighbor(NETSIM_ID d, NETSIM_IPAddress rp)
124 NETSIM_IPAddress nexthop = pimroute_find_nexthop(d, rp);
125 return find_neighbor(d, nexthop);
128void pim_send_joinprune(NETSIM_ID d,
double time,ptrPIM_GROUP group)
130 ptrPIM_VAR var = GET_PIM_VAR(d);
131 NetSim_PACKET* packet = create_pim_joinprune(d, time, group);
133 ptrPIM_NEIGHBOR neighbor = pimjoin_find_neighbor(d, group->RP);
137 pim_join_add_group(d, packet, group, neighbor);
139 send_pim_msg(d, time, packet);
140 print_pim_sm_log(
"sending PIM_Join msg.");
141 print_pim_sm_log(
"Adding JT timer event at %0.3lf", time + var->t_periodic);
142 pim_add_timeout_event(d, time + var->t_periodic, EVENT_PIM_JT, group->groupAddress);
143 print_pim_sm_log(
"\n");
146static bool validate_RP(NETSIM_ID d, NETSIM_IPAddress rp, NETSIM_IPAddress gaddr)
148 ptrPIM_GROUP g = pim_find_group(d, gaddr);
149 if (!IP_COMPARE(g->RP, rp))
155static ptrPIM_JP_STATE get_Pim_jp_state(NETSIM_ID d, NETSIM_ID i, ptrPIM_GROUP gr)
158 gr->jpState_G = (ptrPIM_JP_STATE*)calloc(DEVICE(d)->nNumOfInterface,
sizeof* gr->jpState_G);
160 if (!gr->jpState_G[i - 1])
161 gr->jpState_G[i - 1] = (ptrPIM_JP_STATE)calloc(1,
sizeof* gr->jpState_G[i]);
163 return gr->jpState_G[i - 1];
166static bool amIRP(NETSIM_ID d, ptrPIM_GROUP g)
171void pim_forward_join()
173 NETSIM_ID d = pstruEventDetails->nDeviceId;
174 NetSim_PACKET* packet = pstruEventDetails->pPacket;
175 double time = pstruEventDetails->dEventTime;
176 ptrPIM_VAR var = GET_PIM_VAR(d);
177 ptrPIM_JOINPRUNE_MSG msg = get_PIM_MSG(packet);
178 NETSIM_IPAddress maddr = msg->groups[0]->multicastAddr->GroupMulticastAddr;
179 ptrPIM_GROUP g = pim_find_group(d, maddr);
181 ptrPIM_NEIGHBOR neighbor = pimjoin_find_neighbor(d, g->RP);
182 pim_join_add_group(d, packet, g, neighbor);
184 packet->pstruNetworkData->szGatewayIP = NULL;
185 packet->pstruNetworkData->szNextHopIp = NULL;
186 send_pim_msg(d, time, packet);
187 print_pim_sm_log(
"sending PIM_Join msg.");
188 print_pim_sm_log(
"Adding JT timer event at %0.3lf", time + var->t_periodic);
189 pim_add_timeout_event(d, time + var->t_periodic, EVENT_PIM_JT, g->groupAddress);
190 print_pim_sm_log(
"\n");
193bool pim_process_join()
195 NETSIM_ID d = pstruEventDetails->nDeviceId;
196 NetSim_PACKET* packet = pstruEventDetails->pPacket;
197 double time = pstruEventDetails->dEventTime;
198 ptrPIM_VAR var = GET_PIM_VAR(d);
199 ptrPIM_JOINPRUNE_MSG msg = get_PIM_MSG(packet);
200 NETSIM_IPAddress maddr = msg->groups[0]->multicastAddr->GroupMulticastAddr;
202 print_pim_sm_log(
"Received PIM_JOIN msg from %s for group address %s",
203 packet->pstruNetworkData->szGatewayIP->str_ip,
206 NETSIM_IPAddress msgRP = packet->pstruNetworkData->szDestIP;
208 if (!validate_RP(d, msgRP, maddr))
210 print_pim_sm_log(
"RP is not matched for group");
213 ptrPIM_GROUP g = pim_find_group(d, maddr);
215 ptrPIM_JP_STATE state = get_Pim_jp_state(d,
216 pstruEventDetails->nInterfaceId,
219 if (state->state == JPS_NI)
221 state->state = JPS_J;
222 state->ET = time + msg->holdTime*SECOND;
223 print_pim_sm_log(
"Adding JT timer event at %0.3lf", state->ET/1000);
224 pim_add_timeout_event(d, state->ET, EVENT_PIM_ET, g->groupAddress);
228 state->ET = time + msg->holdTime*SECOND;
229 print_pim_sm_log(
"ET timer is updated to %0.3lf", state->ET / 1000);
232 pim_add_interface_to_group(d, pstruEventDetails->nInterfaceId, g);
239 print_RPT_Tree(d, g);