18#include "OSPF_Neighbor.h"
19#include "OSPF_Interface.h"
21#define OSPF_HELLO_GET_DR_FROM_IF(i) (i->designaterRouter?i->designaterRouter:NullID)
22#define OSPF_HELLO_GET_BDR_FROM_IF(i) (i->backupDesignaterRouter?i->backupDesignaterRouter:NullID)
24void OSPF_HELLO_MSG_NEW(ptrOSPFPACKETHDR hdr)
26 ptrOSPFHELLO hello = calloc(1,
sizeof* hello);
33ptrOSPFHELLO OSPF_HELLO_MSG_COPY(ptrOSPFHELLO hello)
35 ptrOSPFHELLO h = calloc(1,
sizeof* hello);
36 memcpy(h, hello,
sizeof* hello);
38 if (hello->neighCount)
39 h->Neighbor = calloc(hello->neighCount,
sizeof* h->Neighbor);
40 for (i = 0; i < hello->neighCount; i++)
41 h->Neighbor[i] = IP_COPY(hello->Neighbor[i]);
45void OSPF_HELLO_MSG_FREE(ptrOSPFHELLO hello)
50void start_interval_hello_timer()
52 double delay = NETSIM_RAND_01()*OSPF_BROADCAST_JITTER;
54 NetSim_EVENTDETAILS pevent;
55 memset(&pevent, 0,
sizeof pevent);
56 pevent.dEventTime = pstruEventDetails->dEventTime + delay;
57 pevent.nDeviceId = pstruEventDetails->nDeviceId;
58 pevent.nDeviceType = DEVICE_TYPE(pevent.nDeviceId);
59 pevent.nEventType = TIMER_EVENT;
60 pevent.nInterfaceId = pstruEventDetails->nInterfaceId;
61 pevent.nProtocolId = APP_PROTOCOL_OSPF;
62 pevent.nSubEventType = OSPF_HELLO_TIMER;
65 print_ospf_log(OSPF_HELLO_LOG,
"Starting interval hello timer for router %d-%d at time %lf",
66 pstruEventDetails->nDeviceId,
67 pstruEventDetails->nInterfaceId,
68 pstruEventDetails->dEventTime);
71static void add_next_hello_timer()
73 ptrOSPF_IF ospfIf = OSPF_IF_CURRENT();
74 double delay = NETSIM_RAND_01()*OSPF_BROADCAST_JITTER;
75 NetSim_EVENTDETAILS pevent;
76 memset(&pevent, 0,
sizeof pevent);
77 pevent.dEventTime = pstruEventDetails->dEventTime +
78 ospfIf->helloInterval*SECOND + delay;
79 pevent.nDeviceId = pstruEventDetails->nDeviceId;
80 pevent.nDeviceType = DEVICE_TYPE(pevent.nDeviceId);
81 pevent.nEventType = TIMER_EVENT;
82 pevent.nInterfaceId = pstruEventDetails->nInterfaceId;
83 pevent.nProtocolId = APP_PROTOCOL_OSPF;
84 pevent.nSubEventType = OSPF_HELLO_TIMER;
87 print_ospf_log(OSPF_HELLO_LOG,
"Scheduling next interval hello timer for router %d-%d at time %lf",
88 pstruEventDetails->nDeviceId,
89 pstruEventDetails->nInterfaceId,
90 pstruEventDetails->dEventTime);
93static UINT16 add_neighborToHello(ptrOSPFHELLO hello, ptrOSPF_IF ospf)
97 print_ospf_log(OSPF_HELLO_LOG,
"Adding neighbor to hello message");
98 for (i = 0; i < ospf->neighborRouterCount; i++)
100 if (ospf->neighborRouterList[i]->state >= OSPFNEIGHSTATE_Init)
103 hello->Neighbor = realloc(hello->Neighbor, (c + 1) *
sizeof* hello->Neighbor);
105 hello->Neighbor = calloc(1,
sizeof* hello->Neighbor);
106 hello->Neighbor[c] = ospf->neighborRouterList[i]->neighborId;
107 print_ospf_log(OSPF_HELLO_LOG,
"%s neighbor is added",
108 ospf->neighborRouterList[i]->neighborId->str_ip);
113 print_ospf_log(OSPF_HELLO_LOG,
"%d neighbor is added out of %d", c, ospf->neighborRouterCount);
117static void set_hello_param(NetSim_PACKET* packet, ptrOSPFPACKETHDR hdr)
119 ptrOSPFHELLO hello = OSPF_HDR_GET_MSG(hdr);
120 ptrOSPF_IF thisInterface = OSPF_IF_CURRENT();
121 hello->NetworkMask = DEVICE_CURR_MASK;
122 hello->HelloInterval = OSPFTIME_TO_UINT16(thisInterface->helloInterval);
123 hello->RtrPri = thisInterface->RouterPriority;
124 hello->RouterDeadInterval = OSPFTIME_TO_UINT16(thisInterface->routerDeadInterval);
125 hello->DesignatedRouter = OSPF_HELLO_GET_DR_FROM_IF(thisInterface);
126 hello->BackupDesignatedRouter = OSPF_HELLO_GET_BDR_FROM_IF(thisInterface);
127 UINT16 count = add_neighborToHello(hello, thisInterface);
128 OSPF_HDR_INCREASE_LEN(packet, count * 4);
131static void ospf_hello_update_dst(NetSim_PACKET* packet)
133 add_dest_to_packet(packet, 0);
134 packet->pstruNetworkData->szDestIP = AllSPFRouters;
135 packet->pstruNetworkData->szNextHopIp = AllSPFRouters;
136 packet->pstruNetworkData->nTTL = 2;
139static void send_hello()
141 OSPFMSG type = OSPFMSG_HELLO;
142 NetSim_PACKET* packet = OSPF_PACKET_NEW(pstruEventDetails->dEventTime,
144 pstruEventDetails->nDeviceId,
145 pstruEventDetails->nInterfaceId);
147 ospf_hello_update_dst(packet);
148 ptrOSPFPACKETHDR hdr = OSPF_PACKET_GET_HDR(packet);
150 set_hello_param(packet, hdr);
152 OSPF_SEND_PACKET(packet);
155void ospf_handle_helloTimer_event()
157 ptrOSPF_IF thisInterface = OSPF_IF_CURRENT();
158 if (thisInterface->State == OSPFIFSTATE_DOWN)
161 add_next_hello_timer();
163 print_ospf_log(OSPF_HELLO_LOG,
"Time %0.4lf, Router %d, interface %d (%s) is sending hello msg",
164 pstruEventDetails->dEventTime / MILLISECOND,
165 pstruEventDetails->nDeviceId,
166 pstruEventDetails->nInterfaceId,
167 DEVICE_MYIP()->str_ip);
169 print_ospf_log(OSPF_HELLO_LOG,
"\n");
172static bool validate_hello_msg()
174 NetSim_PACKET* packet = pstruEventDetails->pPacket;
175 ptrOSPFPACKETHDR hdr = OSPF_PACKET_GET_HDR(packet);
176 ptrOSPFHELLO hello = OSPF_HDR_GET_MSG(hdr);
177 ptrOSPF_IF thisInterface = OSPF_IF_CURRENT();
179 if (thisInterface->Type != OSPFIFTYPE_P2P &&
180 thisInterface->Type != OSPFIFTYPE_VIRTUALLINK)
182 if (IP_COMPARE(thisInterface->IPIfMask, hello->NetworkMask))
184 fnNetSimError(
"Router %d-%d received hello packet with different net mask than configured\n",
185 pstruEventDetails->nDeviceId,
186 pstruEventDetails->nInterfaceId);
191 if (thisInterface->helloInterval != hello->HelloInterval)
193 fnNetSimError(
"Router %d-%d received hello packet with different hello interval than configured\n",
194 pstruEventDetails->nDeviceId,
195 pstruEventDetails->nInterfaceId);
199 if (thisInterface->routerDeadInterval != hello->RouterDeadInterval)
201 fnNetSimError(
"Router %d-%d received hello packet with different router dead interval than configured\n",
202 pstruEventDetails->nDeviceId,
203 pstruEventDetails->nInterfaceId);
209static bool is_ip_present_in_hello(ptrOSPFHELLO hello, NETSIM_IPAddress ip)
212 for (i = 0; i < hello->neighCount; i++)
214 if (!IP_COMPARE(hello->Neighbor[i], ip))
220static bool ospf_hello_findNeighbor(ptrOSPF_IF thisInterface,
221 NETSIM_IPAddress srcAddr,
223 ptrOSPF_NEIGHBOR* neighbor)
226 for (i = 0; i < thisInterface->neighborRouterCount; i++)
228 ptrOSPF_NEIGHBOR neigh = thisInterface->neighborRouterList[i];
229 if (thisInterface->Type == OSPFIFTYPE_BROADCAST ||
230 thisInterface->Type == OSPFIFTYPE_P2MP)
232 if (!IP_COMPARE(neigh->neighborIPAddr, srcAddr))
240 if (!OSPFID_COMPARE(neigh->neighborId, rid))
242 if (IP_COMPARE(neigh->neighborIPAddr, srcAddr))
256void ospf_process_hello()
258 NETSIM_ID d = pstruEventDetails->nDeviceId;
259 NETSIM_ID in = pstruEventDetails->nInterfaceId;
260 NetSim_PACKET* packet = pstruEventDetails->pPacket;
261 NETSIM_IPAddress src = packet->pstruNetworkData->szSourceIP;
262 ptrOSPFPACKETHDR hdr = OSPF_PACKET_GET_HDR(packet);
263 NETSIM_IPAddress rid = hdr->RouterId;
264 ptrOSPFHELLO hello = OSPF_HDR_GET_MSG(hdr);
265 ptrOSPF_PDS ospf = OSPF_PDS_CURRENT();
266 ptrOSPF_IF thisIntf = OSPF_IF_CURRENT();
267 ptrOSPFAREA_DS thisArea = OSPF_AREA_GET_ID(ospf, thisIntf->areaId);
269 ptrOSPF_NEIGHBOR tempNeighborInfo = NULL;
270 BOOL neighborFound =
false;
272 print_ospf_log(OSPF_HELLO_LOG,
"Time %0.4lf ms, Router %d interface %d (%s) received hello msg from neighbor %s",
273 pstruEventDetails->dEventTime / MILLISECOND,
276 DEVICE_NWADDRESS(d, in)->str_ip,
277 hdr->RouterId->str_ip);
279 if (!validate_hello_msg())
281 print_ospf_log(OSPF_HELLO_LOG,
"Hello msg is not validated. Deleting hello msg...");
282 goto TERMINATE_PROCESSING_HELLO;
285 NETSIM_IPAddress nbrPrevDR = NULL;
286 NETSIM_IPAddress nbrPrevBDR = NULL;
287 UINT8 nbrPrevPriority = 0;
288 bool routerIdInHelloPktBody =
false;
290 numNeighbor = hello->neighCount;
291 print_ospf_log(OSPF_HELLO_LOG,
"%d neighbor is present in hello message", numNeighbor);
293 if (!ospf_hello_findNeighbor(thisIntf, src, rid, &tempNeighborInfo))
294 goto TERMINATE_PROCESSING_HELLO;
296 if (tempNeighborInfo)
297 neighborFound =
true;
301 print_ospf_log(OSPF_HELLO_LOG,
"Neighbor is not found in neighbor list");
302 print_ospf_log(OSPF_HELLO_LOG,
"Adding new neighbor of RID %s, IP addr %s",
303 rid->str_ip, src->str_ip);
304 tempNeighborInfo = ospf_neighbor_new(src, rid);
305 ospf_neighbor_add(thisIntf, tempNeighborInfo);
306 tempNeighborInfo->neighborDesignateRouter = hello->DesignatedRouter;
307 tempNeighborInfo->neighborDesignateBackupRouter = hello->BackupDesignatedRouter;
309 nbrPrevDR = tempNeighborInfo->neighborDesignateRouter;
310 nbrPrevBDR = tempNeighborInfo->neighborDesignateBackupRouter;
312 if (thisIntf->Type == OSPFIFTYPE_BROADCAST ||
313 thisIntf->Type == OSPFIFTYPE_P2MP)
315 nbrPrevPriority = tempNeighborInfo->neighborPriority;
316 tempNeighborInfo->neighborDesignateRouter = hello->DesignatedRouter;
317 tempNeighborInfo->neighborDesignateBackupRouter = hello->BackupDesignatedRouter;
318 tempNeighborInfo->neighborPriority = hello->RtrPri;
320 else if (thisIntf->Type == OSPFIFTYPE_P2P)
322 nbrPrevPriority = tempNeighborInfo->neighborPriority;
323 tempNeighborInfo->neighborIPAddr = src;
324 tempNeighborInfo->neighborPriority = hello->RtrPri;
328 nbrPrevPriority = tempNeighborInfo->neighborPriority;
329 tempNeighborInfo->neighborPriority = hello->RtrPri;
333 ospf_event_set_and_call(OSPF_HelloReceived,
338 if (is_ip_present_in_hello(hello, ospf->routerId))
340 print_ospf_log(OSPF_HELLO_LOG,
"My ip is present in neighbor list. Setting 2-way received event");
341 ospf_event_set_and_call(OSPF_2WayReceived, tempNeighborInfo);
342 routerIdInHelloPktBody =
true;
346 print_ospf_log(OSPF_HELLO_LOG,
"My ip is not present in neighbor list. Set 1-way event & terminating further processing");
347 ospf_event_set_and_call(OSPF_1Way, tempNeighborInfo);
348 goto TERMINATE_PROCESSING_HELLO;
354 if (nbrPrevPriority != tempNeighborInfo->neighborPriority)
356 print_ospf_log(OSPF_HELLO_LOG,
"Neighbor priority is changed. Adding neighbor change event");
357 ospf_event_add(pstruEventDetails->dEventTime,
373 if (!IP_COMPARE(hello->DesignatedRouter, tempNeighborInfo->neighborIPAddr) &&
374 !hello->BackupDesignatedRouter->int_ip[0] &&
375 thisIntf->State == OSPFIFSTATE_WAITING)
377 print_ospf_log(OSPF_HELLO_LOG,
"Neighbor is declaring itself as DR and BDR is NULL");
378 ospf_event_add(pstruEventDetails->dEventTime,
385 else if ((!IP_COMPARE(hello->DesignatedRouter, tempNeighborInfo->neighborIPAddr) &&
386 IP_COMPARE(nbrPrevDR, tempNeighborInfo->neighborIPAddr)) ||
387 (IP_COMPARE(hello->DesignatedRouter, tempNeighborInfo->neighborIPAddr) &&
388 !IP_COMPARE(nbrPrevDR, tempNeighborInfo->neighborIPAddr)))
390 ospf_event_add(pstruEventDetails->dEventTime,
406 if (hello->BackupDesignatedRouter->int_ip[0] ==
407 tempNeighborInfo->neighborIPAddr->int_ip[0] &&
408 thisIntf->State == OSPFIFSTATE_WAITING)
410 ospf_event_add(pstruEventDetails->dEventTime,
417 else if ((hello->BackupDesignatedRouter->int_ip[0] == tempNeighborInfo->neighborIPAddr->int_ip[0] &&
418 nbrPrevBDR->int_ip[0] != tempNeighborInfo->neighborIPAddr->int_ip[0]) ||
419 (hello->BackupDesignatedRouter->int_ip[0] != tempNeighborInfo->neighborIPAddr->int_ip[0] &&
420 nbrPrevBDR->int_ip[0] == tempNeighborInfo->neighborIPAddr->int_ip[0]))
422 ospf_event_add(pstruEventDetails->dEventTime,
430TERMINATE_PROCESSING_HELLO:
431 fn_NetSim_Packet_FreePacket(packet);
432 pstruEventDetails->pPacket = NULL;
433 print_ospf_log(OSPF_HELLO_LOG,
"\n\n");