NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
PIM_SM.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 FILE* pim_sm_log = NULL;
22static void init_pim_sm_log()
23{
24 if (!pim_sm_log)
25 {
26 char str[BUFSIZ];
27 sprintf(str, "%s/%s", pszIOPath, "pim_sm_log.txt");
28 pim_sm_log = fopen(str, "w");
29 }
30}
31
32static void close_pim_sm_log()
33{
34 if(pim_sm_log)
35 fclose(pim_sm_log);
36}
37
38void print_pim_sm_log(char* format, ...)
39{
40 if (pim_sm_log)
41 {
42 va_list l;
43 va_start(l, format);
44 vfprintf(pim_sm_log, format, l);
45 fprintf(pim_sm_log, "\n");
46 fflush(pim_sm_log);
47 }
48}
49
50void pim_add_timeout_event(NETSIM_ID d,
51 double time,
52 IP_SUBEVENT eve,
53 NETSIM_IPAddress group)
54{
55 NetSim_EVENTDETAILS pevent;
56 memset(&pevent, 0, sizeof pevent);
57 pevent.dEventTime = time;
58 pevent.nDeviceId = d;
59 pevent.nDeviceType = DEVICE_TYPE(d);
60 pevent.nEventType = TIMER_EVENT;
61 pevent.nProtocolId = NW_PROTOCOL_IPV4;
62 pevent.nSubEventType = eve;
63 pevent.szOtherDetails = group;
64 fnpAddEvent(&pevent);
65}
66
67void Router_PIM_Init(NETSIM_ID d)
68{
69 static bool isFirst = true;
70 if (isFirst)
71 {
72 init_pim_sm_log();
73 configure_PIM();
74 isFirst = false;
75 }
76 DEVICE_NWLAYER(d)->routerFunction = pim_route_msg;
77 ptrPIM_VAR var = GET_PIM_VAR(d);
78 ALL_PIM_ROUTERS_ADDRESS = STR_TO_IP4("224.0.0.13");
79 pim_route_add(d, 0, 330, ALL_PIM_ROUTERS_ADDRESS);
80
81 print_pim_sm_log("Router %d, Time 0.0: Starting PIM", d);
82
83 var->DR = calloc(DEVICE(d)->nNumOfInterface, sizeof* var->DR);
84
85 var->genId = (UINT)rand();
86 print_pim_sm_log("Generation Id = %d", var->genId);
87
88 print_pim_sm_log("Adding %s to IP routing table.\n",
89 "224.0.0.13");
90
91 double time = NETSIM_RAND_01()*var->triggeredHelloDelay;
92 print_pim_sm_log("Router %d, Time %0.3lf: Sending hello packet", d, time / 1000);
93 send_hello_msg(d, time);
94}
95
96static bool isPIMReqd(NETSIM_ID d)
97{
98 NETSIM_ID i;
99 for (i = 0; i < DEVICE(d)->nNumOfInterface; i++)
100 {
101 if (DEVICE_INTERFACE(d, i + 1)->nInterfaceType == INTERFACE_WAN_ROUTER)
102 return true;
103 }
104 return false;
105}
106
107void pim_configure(NETSIM_ID d, void* xmlNetSimNode)
108{
109 ptrPIM_VAR var = GET_PIM_VAR(d);
110 if (!isPIMReqd(d))
111 {
112 fnNetSimError("PIM is configure for router %d without any WAN port\n", d);
113 GET_IP_DEVVAR(d)->isPIMConfigured = false;
114 return;
115 }
116
117 if (!var)
118 {
119 var = (ptrPIM_VAR)calloc(1, sizeof* var);
120 SET_PIM_VAR(d, var);
121 }
122
123 getXmlVar(&var->helloPeriod, HELLO_PERIOD, xmlNetSimNode, 1, _DOUBLE, PIM);
124 var->helloPeriod *= SECOND;
125
126 getXmlVar(&var->triggeredHelloDelay, TRIGGERED_HELLO_DELAY, xmlNetSimNode, 1, _DOUBLE, PIM);
127 var->triggeredHelloDelay *= SECOND;
128
129 getXmlVar(&var->DRPriority, DR_PRIORITY, xmlNetSimNode, 1, _UINT, PIM);
130
131 getXmlVar(&var->propagationDelay, PROPAGATION_DELAY, xmlNetSimNode, 1, _UINT16, PIM);
132
133 getXmlVar(&var->overrideInterval, OVERRIDE_INTERVAL, xmlNetSimNode, 1, _UINT16, PIM);
134
135 getXmlVar(&var->t_periodic, T_PERIODIC, xmlNetSimNode, 1, _DOUBLE, PIM);
136 var->t_periodic *= SECOND;
137}
138
139IP_PROTOCOL_ACTION pim_decide_action(NetSim_PACKET* packet, NETSIM_ID d)
140{
141 if (packet->nControlDataType == PACKET_PIM_JOINPRUNE)
142 return ACTION_MOVEUP;
143 else if (packet->nControlDataType == PACKET_PIM_HELLO)
144 return ACTION_MOVEUP;
145 else
146 return ACTION_MOVEUP;
147}
148
149void process_pim_packet()
150{
151 bool isFree = false;
152
153 if (!GET_IP_DEVVAR(pstruEventDetails->nDeviceId)->isPIMConfigured)
154 goto FREE_PACKET; // PIM is not configured for this device
155
156 NetSim_PACKET* packet = pstruEventDetails->pPacket;
157
158 print_pim_sm_log("Router %d, Time %0.3lf: %s packet is received on %d interface",
159 pstruEventDetails->nDeviceId,
160 pstruEventDetails->dEventTime / 1000,
161 packet->szPacketType,
162 pstruEventDetails->nInterfaceId);
163
164 switch (packet->nControlDataType)
165 {
166 case PACKET_PIM_HELLO:
167 isFree = process_pim_hello_packet();
168 break;
169 case PACKET_PIM_JOINPRUNE:
170 isFree = pim_process_join();
171 break;
172 default:
173 fnNetSimError("Unknown packet %s in %s\n",
174 packet->szPacketType,
175 __FUNCTION__);
176 break;
177 }
178 print_pim_sm_log("\n");
179 if (isFree)
180 {
181 FREE_PACKET:
182 fn_NetSim_Packet_FreePacket(packet);
183 pstruEventDetails->pPacket = NULL;
184 }
185}
186
187void pim_handle_timer_event()
188{
189 NETSIM_ID d = pstruEventDetails->nDeviceId;
190 double time = pstruEventDetails->dEventTime;
191 NETSIM_IPAddress gAddr = pstruEventDetails->szOtherDetails;
192 ptrPIM_VAR var = GET_PIM_VAR(d);
193
194 switch (pstruEventDetails->nSubEventType)
195 {
196 case EVENT_PIM_SEND_HELLO:
197 {
198 double t = time + var->helloPeriod;
199 print_pim_sm_log("Router %d, Time %0.3lf: Sending hello packet", d, t / 1000);
200 send_hello_msg(d, t);
201 }
202 break;
203 case EVENT_PIM_JT:
204 ptrPIM_GROUP group = pim_find_group(d, gAddr);
205 pim_send_joinprune(d, time, group);
206 break;
207 case EVENT_PIM_ET:
208 //Needs to implemented after node or link failure.
209 break;
210 case EVENT_PIM_NEIGHBOR_TIMEOUT:
211 //Needs to implemented after node or link failure.
212 break;
213 default:
214 fnNetSimError("Unknown subevent %d for PIM.", pstruEventDetails->nSubEventType);
215 break;
216 }
217}
218
219static bool isReservedGroup(NETSIM_IPAddress addr)
220{
221 if (!IP_COMPARE(addr, STR_TO_IP4("224.0.0.0")) ||
222 !IP_COMPARE(addr, STR_TO_IP4("224.0.0.1")))
223 return true;
224 return false;
225}
226
227//Called from IGMP
228void pim_join_group(NETSIM_ID d, NETSIM_IPAddress group)
229{
230 if (!GET_IP_DEVVAR(d)->isPIMConfigured)
231 return; //PIM is not configured
232
233 if (isReservedGroup(group))
234 return; //Reserved address
235
236 ptrPIM_GROUP gr = pim_find_group(d, group);
237 if (!gr)
238 {
239 fnNetSimError("PIM Configuration is wrong. RP is not configured for group address %s\n",
240 group->str_ip);
241 return;
242 }
243
244 if (d == gr->RPId)
245 {
246 fnNetSimError("PIM Configuration is wrong. %s can't be RP of group %s.\n",
247 gr->RP->str_ip,
248 group->str_ip);
249 return;
250 }
251
252 print_pim_sm_log("Router %d, Time %0.3lf: Joining %s group",
253 d,
254 pstruEventDetails->dEventTime / 1000,
255 group->str_ip);
256
257 //Call join function to send join msg to RP
258 pim_send_joinprune(d, pstruEventDetails->dEventTime, gr);
259}