21static FILE* pim_sm_log = NULL;
22static void init_pim_sm_log()
27 sprintf(str,
"%s/%s", pszIOPath,
"pim_sm_log.txt");
28 pim_sm_log = fopen(str,
"w");
32static void close_pim_sm_log()
38void print_pim_sm_log(
char* format, ...)
44 vfprintf(pim_sm_log, format, l);
45 fprintf(pim_sm_log,
"\n");
50void pim_add_timeout_event(NETSIM_ID d,
53 NETSIM_IPAddress group)
55 NetSim_EVENTDETAILS pevent;
56 memset(&pevent, 0,
sizeof pevent);
57 pevent.dEventTime = time;
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;
67void Router_PIM_Init(NETSIM_ID d)
69 static bool isFirst =
true;
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);
81 print_pim_sm_log(
"Router %d, Time 0.0: Starting PIM", d);
83 var->DR = calloc(DEVICE(d)->nNumOfInterface,
sizeof* var->DR);
85 var->genId = (UINT)rand();
86 print_pim_sm_log(
"Generation Id = %d", var->genId);
88 print_pim_sm_log(
"Adding %s to IP routing table.\n",
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);
96static bool isPIMReqd(NETSIM_ID d)
99 for (i = 0; i < DEVICE(d)->nNumOfInterface; i++)
101 if (DEVICE_INTERFACE(d, i + 1)->nInterfaceType == INTERFACE_WAN_ROUTER)
107void pim_configure(NETSIM_ID d,
void* xmlNetSimNode)
109 ptrPIM_VAR var = GET_PIM_VAR(d);
112 fnNetSimError(
"PIM is configure for router %d without any WAN port\n", d);
113 GET_IP_DEVVAR(d)->isPIMConfigured =
false;
119 var = (ptrPIM_VAR)calloc(1,
sizeof* var);
123 getXmlVar(&var->helloPeriod, HELLO_PERIOD, xmlNetSimNode, 1, _DOUBLE, PIM);
124 var->helloPeriod *= SECOND;
126 getXmlVar(&var->triggeredHelloDelay, TRIGGERED_HELLO_DELAY, xmlNetSimNode, 1, _DOUBLE, PIM);
127 var->triggeredHelloDelay *= SECOND;
129 getXmlVar(&var->DRPriority, DR_PRIORITY, xmlNetSimNode, 1, _UINT, PIM);
131 getXmlVar(&var->propagationDelay, PROPAGATION_DELAY, xmlNetSimNode, 1, _UINT16, PIM);
133 getXmlVar(&var->overrideInterval, OVERRIDE_INTERVAL, xmlNetSimNode, 1, _UINT16, PIM);
135 getXmlVar(&var->t_periodic, T_PERIODIC, xmlNetSimNode, 1, _DOUBLE, PIM);
136 var->t_periodic *= SECOND;
139IP_PROTOCOL_ACTION pim_decide_action(NetSim_PACKET* packet, NETSIM_ID d)
141 if (packet->nControlDataType == PACKET_PIM_JOINPRUNE)
142 return ACTION_MOVEUP;
143 else if (packet->nControlDataType == PACKET_PIM_HELLO)
144 return ACTION_MOVEUP;
146 return ACTION_MOVEUP;
149void process_pim_packet()
153 if (!GET_IP_DEVVAR(pstruEventDetails->nDeviceId)->isPIMConfigured)
156 NetSim_PACKET* packet = pstruEventDetails->pPacket;
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);
164 switch (packet->nControlDataType)
166 case PACKET_PIM_HELLO:
167 isFree = process_pim_hello_packet();
169 case PACKET_PIM_JOINPRUNE:
170 isFree = pim_process_join();
173 fnNetSimError(
"Unknown packet %s in %s\n",
174 packet->szPacketType,
178 print_pim_sm_log(
"\n");
182 fn_NetSim_Packet_FreePacket(packet);
183 pstruEventDetails->pPacket = NULL;
187void pim_handle_timer_event()
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);
194 switch (pstruEventDetails->nSubEventType)
196 case EVENT_PIM_SEND_HELLO:
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);
204 ptrPIM_GROUP group = pim_find_group(d, gAddr);
205 pim_send_joinprune(d, time, group);
210 case EVENT_PIM_NEIGHBOR_TIMEOUT:
214 fnNetSimError(
"Unknown subevent %d for PIM.", pstruEventDetails->nSubEventType);
219static bool isReservedGroup(NETSIM_IPAddress addr)
221 if (!IP_COMPARE(addr, STR_TO_IP4(
"224.0.0.0")) ||
222 !IP_COMPARE(addr, STR_TO_IP4(
"224.0.0.1")))
228void pim_join_group(NETSIM_ID d, NETSIM_IPAddress group)
230 if (!GET_IP_DEVVAR(d)->isPIMConfigured)
233 if (isReservedGroup(group))
236 ptrPIM_GROUP gr = pim_find_group(d, group);
239 fnNetSimError(
"PIM Configuration is wrong. RP is not configured for group address %s\n",
246 fnNetSimError(
"PIM Configuration is wrong. %s can't be RP of group %s.\n",
252 print_pim_sm_log(
"Router %d, Time %0.3lf: Joining %s group",
254 pstruEventDetails->dEventTime / 1000,
258 pim_send_joinprune(d, pstruEventDetails->dEventTime, gr);