NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
PIM_Join.c
1/************************************************************************************
2* Copyright (C) 2023 *
3* TETCOS, Bangalore. India *
4* *
5* Tetcos owns the intellectual property rights in the Product and its content. *
6* The copying, redistribution, reselling or publication of any or all of the *
7* Product or its content without express prior written consent of Tetcos is *
8* prohibited. Ownership and / or any other right relating to the software and all *
9* intellectual property rights therein shall remain at all times with Tetcos. *
10* *
11* Author: Shashi Kant Suman *
12* *
13* ---------------------------------------------------------------------------------*/
14
15#include "main.h"
16#include "List.h"
17#include "IP.h"
18#include "PIM_SM.h"
19#include "PIM_Msg.h"
20
21static ptrPIM_JOINPRUNE_MSG alloc_pim_joinprune()
22{
23 ptrPIM_JOINPRUNE_MSG jp = (ptrPIM_JOINPRUNE_MSG)calloc(1, sizeof* jp);
24 set_pim_hdr(&jp->hdr, PIMMSG_JoinPrune);
25
26 return jp;
27}
28
29static NetSim_PACKET* create_pim_joinprune(NETSIM_ID dev,
30 double time,
31 ptrPIM_GROUP group)
32{
33 ptrPIM_JOINPRUNE_MSG jp = alloc_pim_joinprune();
34 NetSim_PACKET* packet = create_pim_packet(PIMMSG_JoinPrune,
35 jp,
36 time,
37 dev,
38 DEVICE_NWADDRESS(dev, 1),
39 1,
40 &group->RPId,
41 group->RP,
42 MAX_TTL);
43 return packet;
44}
45
46static ptrPIM_JOINMSG_GROUP pim_join_add_group_member(NETSIM_ID d,
47 NETSIM_IPAddress groupAddr,
48 ptrPIM_JOINPRUNE_MSG jp,
49 UINT c)
50{
51 UINT i;
52 ptrPIM_JOINMSG_GROUP msg = jp->groups[c];
53 if (!msg)
54 {
55 msg = calloc(1, sizeof* msg);
56 jp->groups[c] = msg;
57 msg->numJoinedSource = 1;
58 msg->joinedSourceAddr = calloc(1, sizeof* msg->joinedSourceAddr);
59 i = 0;
60 msg->multicastAddr = encode_group_addr(groupAddr);
61 }
62 else
63 {
64 msg->joinedSourceAddr = realloc(msg->joinedSourceAddr,
65 (msg->numJoinedSource + 1) * sizeof* msg->joinedSourceAddr);
66 i = msg->numJoinedSource;
67 msg->numJoinedSource++;
68 }
69 msg->joinedSourceAddr[i] = encode_source_addr(DEVICE_NWADDRESS(d, 1),
70 DEVICE_INTERFACE(d, 1)->szSubnetMask);
71 return msg;
72}
73
74static ptrPIM_JOINMSG_GROUP jP_find_groups(ptrPIM_JOINPRUNE_MSG jp, NETSIM_IPAddress m, UINT* in)
75{
76 UINT i;
77 for (i = 0; i < jp->numGroups; i++)
78 {
79 if (!IP_COMPARE(jp->groups[i]->multicastAddr->GroupMulticastAddr, m))
80 {
81 *in = i;
82 return jp->groups[i];
83 }
84 }
85 return NULL;
86}
87
88static void pim_join_add_group(NETSIM_ID d,
89 NetSim_PACKET* packet,
90 ptrPIM_GROUP group,
91 ptrPIM_NEIGHBOR neighbor)
92{
93 ptrPIM_JOINPRUNE_MSG jp = get_PIM_MSG(packet);
94 if (!jp)
95 {
96 jp->numGroups = 1;
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);
101 }
102 else
103 {
104 UINT i;
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);
108 if (!g)
109 {
110 if (jp->groups)
111 jp->groups = realloc(jp->groups, (jp->numGroups + 1) * sizeof* jp->groups);
112 else
113 jp->groups = calloc(1, sizeof* jp->groups);
114 g = jp->groups[jp->numGroups];
115 jp->numGroups++;
116 i = jp->numGroups - 1;
117 }
118 jp->groups[i] = pim_join_add_group_member(d, group->groupAddress, jp, i);
119 }
120}
121
122static ptrPIM_NEIGHBOR pimjoin_find_neighbor(NETSIM_ID d, NETSIM_IPAddress rp)
123{
124 NETSIM_IPAddress nexthop = pimroute_find_nexthop(d, rp);
125 return find_neighbor(d, nexthop);
126}
127
128void pim_send_joinprune(NETSIM_ID d, double time,ptrPIM_GROUP group)
129{
130 ptrPIM_VAR var = GET_PIM_VAR(d);
131 NetSim_PACKET* packet = create_pim_joinprune(d, time, group);
132
133 ptrPIM_NEIGHBOR neighbor = pimjoin_find_neighbor(d, group->RP);
134
135 assert(neighbor);
136
137 pim_join_add_group(d, packet, group, neighbor);
138
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");
144}
145
146static bool validate_RP(NETSIM_ID d, NETSIM_IPAddress rp, NETSIM_IPAddress gaddr)
147{
148 ptrPIM_GROUP g = pim_find_group(d, gaddr);
149 if (!IP_COMPARE(g->RP, rp))
150 return true;
151 else
152 return false;
153}
154
155static ptrPIM_JP_STATE get_Pim_jp_state(NETSIM_ID d, NETSIM_ID i, ptrPIM_GROUP gr)
156{
157 if (!gr->jpState_G)
158 gr->jpState_G = (ptrPIM_JP_STATE*)calloc(DEVICE(d)->nNumOfInterface, sizeof* gr->jpState_G);
159
160 if (!gr->jpState_G[i - 1])
161 gr->jpState_G[i - 1] = (ptrPIM_JP_STATE)calloc(1, sizeof* gr->jpState_G[i]);
162
163 return gr->jpState_G[i - 1];
164}
165
166static bool amIRP(NETSIM_ID d, ptrPIM_GROUP g)
167{
168 return g->RPId == d;
169}
170
171void pim_forward_join()
172{
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);
180
181 ptrPIM_NEIGHBOR neighbor = pimjoin_find_neighbor(d, g->RP);
182 pim_join_add_group(d, packet, g, neighbor);
183
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");
191}
192
193bool pim_process_join()
194{
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;
201
202 print_pim_sm_log("Received PIM_JOIN msg from %s for group address %s",
203 packet->pstruNetworkData->szGatewayIP->str_ip,
204 maddr->str_ip);
205
206 NETSIM_IPAddress msgRP = packet->pstruNetworkData->szDestIP;
207
208 if (!validate_RP(d, msgRP, maddr))
209 {
210 print_pim_sm_log("RP is not matched for group");
211 return true; // RP is not matched for group
212 }
213 ptrPIM_GROUP g = pim_find_group(d, maddr);
214
215 ptrPIM_JP_STATE state = get_Pim_jp_state(d,
216 pstruEventDetails->nInterfaceId,
217 g);
218
219 if (state->state == JPS_NI)
220 {
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);
225 }
226 else
227 {
228 state->ET = time + msg->holdTime*SECOND;
229 print_pim_sm_log("ET timer is updated to %0.3lf", state->ET / 1000);
230 }
231
232 pim_add_interface_to_group(d, pstruEventDetails->nInterfaceId, g);
233
234 //pim_route_add(d, pstruEventDetails->nInterfaceId, 330, g->groupAddress);
235
236 if (amIRP(d, g))
237 {
238#ifdef PRINT_RPT_TREE
239 print_RPT_Tree(d, g);
240#endif
241 return true;
242 }
243 else
244 {
245 pim_forward_join();
246 return false;
247 }
248}