NetSim Source Code Help
Loading...
Searching...
No Matches
OSPF_Hello.c
Go to the documentation of this file.
1/************************************************************************************
2* Copyright (C) 2020 *
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#include "main.h"
15#include "OSPF.h"
16#include "OSPF_enum.h"
17#include "OSPF_Msg.h"
18#include "OSPF_Neighbor.h"
19#include "OSPF_Interface.h"
20
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)
23
25{
26 ptrOSPFHELLO hello = calloc(1, sizeof* hello);
29 hello,
31}
32
34{
35 ptrOSPFHELLO h = calloc(1, sizeof* hello);
36 memcpy(h, hello, sizeof* hello);
37 UINT i;
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]);
42 return h;
43}
44
46{
47 free(hello);
48}
49
51{
53
55 memset(&pevent, 0, sizeof pevent);
56 pevent.dEventTime = pstruEventDetails->dEventTime + delay;
58 pevent.nDeviceType = DEVICE_TYPE(pevent.nDeviceId);
59 pevent.nEventType = TIMER_EVENT;
62 pevent.nSubEventType = OSPF_HELLO_TIMER;
63 fnpAddEvent(&pevent);
64
66 print_ospf_log(OSPF_HELLO_LOG, "Starting interval hello timer for router %d-%d at time %lf",
70}
71
73{
74 ptrOSPF_IF ospfIf = OSPF_IF_CURRENT();
77 memset(&pevent, 0, sizeof pevent);
79 ospfIf->helloInterval*SECOND + delay;
81 pevent.nDeviceType = DEVICE_TYPE(pevent.nDeviceId);
82 pevent.nEventType = TIMER_EVENT;
85 pevent.nSubEventType = OSPF_HELLO_TIMER;
86 fnpAddEvent(&pevent);
87
89 print_ospf_log(OSPF_HELLO_LOG, "Scheduling next interval hello timer for router %d-%d at time %lf",
93}
94
96{
97 UINT16 c = 0;
98 UINT i;
99 print_ospf_log(OSPF_HELLO_LOG, "Adding neighbor to hello message");
100 for (i = 0; i < ospf->neighborRouterCount; i++)
101 {
103 {
104 if (hello->Neighbor)
105 hello->Neighbor = realloc(hello->Neighbor, (c + 1) * sizeof* hello->Neighbor);
106 else
107 hello->Neighbor = calloc(1, sizeof* hello->Neighbor);
108 hello->Neighbor[c] = ospf->neighborRouterList[i]->neighborId;
109 print_ospf_log(OSPF_HELLO_LOG, "%s neighbor is added",
111 hello->neighCount++;
112 c++;
113 }
114 }
115 print_ospf_log(OSPF_HELLO_LOG, "%d neighbor is added out of %d", c, ospf->neighborRouterCount);
116 return c;
117}
118
120{
121 ptrOSPFHELLO hello = OSPF_HDR_GET_MSG(hdr);
122 ptrOSPF_IF thisInterface = OSPF_IF_CURRENT();
124 hello->HelloInterval = OSPFTIME_TO_UINT16(thisInterface->helloInterval);
125 hello->RtrPri = thisInterface->RouterPriority;
127 hello->DesignatedRouter = OSPF_HELLO_GET_DR_FROM_IF(thisInterface);
129 UINT16 count = add_neighborToHello(hello, thisInterface);
130 OSPF_HDR_INCREASE_LEN(packet, count * 4);
131}
132
134{
135 add_dest_to_packet(packet, 0);
138 packet->pstruNetworkData->nTTL = 2;
139}
140
141static void send_hello()
142{
143 OSPFMSG type = OSPFMSG_HELLO;
145 type,
148
149 ospf_hello_update_dst(packet);
151
152 set_hello_param(packet, hdr);
153
154 OSPF_SEND_PACKET(packet);
155}
156
158{
159 ptrOSPF_IF thisInterface = OSPF_IF_CURRENT();
160 if (thisInterface->State == OSPFIFSTATE_DOWN)
161 return; // No hello is send if interface state is down.
162
164
165 print_ospf_log(OSPF_HELLO_LOG, "Time %0.4lf, Router %d, interface %d (%s) is sending hello msg",
169 DEVICE_MYIP()->str_ip);
170 send_hello();
172}
173
175{
178 ptrOSPFHELLO hello = OSPF_HDR_GET_MSG(hdr);
179 ptrOSPF_IF thisInterface = OSPF_IF_CURRENT();
180
181 if (thisInterface->Type != OSPFIFTYPE_P2P &&
182 thisInterface->Type != OSPFIFTYPE_VIRTUALLINK)
183 {
184 if (IP_COMPARE(thisInterface->IPIfMask, hello->NetworkMask))
185 {
186 fnNetSimError("Router %d-%d received hello packet with different net mask than configured\n",
189 return false;
190 }
191 }
192
193 if (thisInterface->helloInterval != hello->HelloInterval)
194 {
195 fnNetSimError("Router %d-%d received hello packet with different hello interval than configured\n",
198 return false;
199 }
200
201 if (thisInterface->routerDeadInterval != hello->RouterDeadInterval)
202 {
203 fnNetSimError("Router %d-%d received hello packet with different router dead interval than configured\n",
206 return false;
207 }
208 return true;
209}
210
212{
213 UINT i;
214 for (i = 0; i < hello->neighCount; i++)
215 {
216 if (!IP_COMPARE(hello->Neighbor[i], ip))
217 return true;
218 }
219 return false;
220}
221
222static bool ospf_hello_findNeighbor(ptrOSPF_IF thisInterface,
223 NETSIM_IPAddress srcAddr,
224 OSPFID rid,
225 ptrOSPF_NEIGHBOR* neighbor)
226{
227 UINT i;
228 for (i = 0; i < thisInterface->neighborRouterCount; i++)
229 {
230 ptrOSPF_NEIGHBOR neigh = thisInterface->neighborRouterList[i];
231 if (thisInterface->Type == OSPFIFTYPE_BROADCAST ||
232 thisInterface->Type == OSPFIFTYPE_P2MP)
233 {
234 if (!IP_COMPARE(neigh->neighborIPAddr, srcAddr))
235 {
236 *neighbor = neigh;
237 return true;
238 }
239 }
240 else
241 {
242 if (!OSPFID_COMPARE(neigh->neighborId, rid))
243 {
244 if (IP_COMPARE(neigh->neighborIPAddr, srcAddr))
245 {
246 *neighbor = NULL;
247 return false;
248 }
249 *neighbor = neigh;
250 return true;
251 }
252 }
253 }
254 *neighbor = NULL;
255 return true;
256}
257
259{
265 NETSIM_IPAddress rid = hdr->RouterId;
266 ptrOSPFHELLO hello = OSPF_HDR_GET_MSG(hdr);
268 ptrOSPF_IF thisIntf = OSPF_IF_CURRENT();
269 ptrOSPFAREA_DS thisArea = OSPF_AREA_GET_ID(ospf, thisIntf->areaId);
270 ptrOSPF_NEIGHBOR tempNeighborInfo = NULL;
271 BOOL neighborFound = false;
272 UINT numNeighbor;
273 print_ospf_log(OSPF_HELLO_LOG, "Time %0.4lf ms, Router %d interface %d (%s) received hello msg from neighbor %s",
275 d,
276 in,
277 DEVICE_NWADDRESS(d, in)->str_ip,
278 hdr->RouterId->str_ip);
279
280 if (!validate_hello_msg())
281 {
282 print_ospf_log(OSPF_HELLO_LOG, "Hello msg is not validated. Deleting hello msg...");
283 goto TERMINATE_PROCESSING_HELLO;
284 }
285
286 NETSIM_IPAddress nbrPrevDR = NULL;
287 NETSIM_IPAddress nbrPrevBDR = NULL;
288 UINT8 nbrPrevPriority = 0;
289 bool routerIdInHelloPktBody = false;
290
291 numNeighbor = hello->neighCount;
292 print_ospf_log(OSPF_HELLO_LOG, "%d neighbor is present in hello message", numNeighbor);
293
294 if (!ospf_hello_findNeighbor(thisIntf, src, rid, &tempNeighborInfo))
295 goto TERMINATE_PROCESSING_HELLO;
296
297 if (tempNeighborInfo)
298 neighborFound = true;
299
300 if (!neighborFound)
301 {
302 print_ospf_log(OSPF_HELLO_LOG, "Neighbor is not found in neighbor list");
303 print_ospf_log(OSPF_HELLO_LOG, "Adding new neighbor of RID %s, IP addr %s",
304 rid->str_ip, src->str_ip);
305 tempNeighborInfo = ospf_neighbor_new(src, rid);
306 ospf_neighbor_add(thisIntf, tempNeighborInfo);
307 tempNeighborInfo->neighborDesignateRouter = hello->DesignatedRouter;
308 tempNeighborInfo->neighborDesignateBackupRouter = hello->BackupDesignatedRouter;
309 }
310 nbrPrevDR = tempNeighborInfo->neighborDesignateRouter;
311 nbrPrevBDR = tempNeighborInfo->neighborDesignateBackupRouter;
312
313 if (thisIntf->Type == OSPFIFTYPE_BROADCAST ||
314 thisIntf->Type == OSPFIFTYPE_P2MP)
315 {
316 nbrPrevPriority = tempNeighborInfo->neighborPriority;
317 tempNeighborInfo->neighborDesignateRouter = hello->DesignatedRouter;
318 tempNeighborInfo->neighborDesignateBackupRouter = hello->BackupDesignatedRouter;
319 tempNeighborInfo->neighborPriority = hello->RtrPri;
320 }
321 else if (thisIntf->Type == OSPFIFTYPE_P2P)
322 {
323 nbrPrevPriority = tempNeighborInfo->neighborPriority;
324 tempNeighborInfo->neighborIPAddr = src;
325 tempNeighborInfo->neighborPriority = hello->RtrPri;
326 }
327 else
328 {
329 nbrPrevPriority = tempNeighborInfo->neighborPriority;
330 tempNeighborInfo->neighborPriority = hello->RtrPri;
331 }
332
333 // Handle neighbor event
334 ospf_event_set_and_call(OSPF_HelloReceived,
335 tempNeighborInfo);
336
337 // Check whether this router itself appear in the
338 // list of neighbor contained in Hello packet.
339 if (is_ip_present_in_hello(hello, ospf->routerId))
340 {
341 print_ospf_log(OSPF_HELLO_LOG, "My ip is present in neighbor list. Setting 2-way received event");
342 ospf_event_set_and_call(OSPF_2WayReceived, tempNeighborInfo);
343 routerIdInHelloPktBody = true;
344 }
345 else
346 {
347 print_ospf_log(OSPF_HELLO_LOG, "My ip is not present in neighbor list. Set 1-way event & terminating further processing");
348 ospf_event_set_and_call(OSPF_1Way, tempNeighborInfo);
349 goto TERMINATE_PROCESSING_HELLO;
350 }
351
352 // If a change in the neighbor's Router Priority field was noted,
353 // the receiving interface's state machine is scheduled with
354 // the event NeighborChange.
355 if (nbrPrevPriority != tempNeighborInfo->neighborPriority)
356 {
357 print_ospf_log(OSPF_HELLO_LOG, "Neighbor priority is changed. Adding neighbor change event");
359 d,
360 in,
361 OSPF_NEIGHBORCHANGE,
362 NULL,
363 tempNeighborInfo);
364 }
365
366 // If the neighbor is both declaring itself to be Designated Router and
367 // the Backup Designated Router field in the packet is equal to 0.0.0.0
368 // and the receiving interface is in state Waiting, the receiving
369 // interface's state machine is scheduled with the event BackupSeen.
370 // Otherwise, if the neighbor is declaring itself to be Designated Router
371 // and it had not previously, or the neighbor is not declaring itself
372 // Designated Router where it had previously, the receiving interface's
373 // state machine is scheduled with the event NeighborChange.
374 if (!IP_COMPARE(hello->DesignatedRouter, tempNeighborInfo->neighborIPAddr) &&
375 !hello->BackupDesignatedRouter->int_ip[0] &&
376 thisIntf->State == OSPFIFSTATE_WAITING)
377 {
378 print_ospf_log(OSPF_HELLO_LOG, "Neighbor is declaring itself as DR and BDR is NULL");
380 d,
381 in,
382 OSPF_BACKUPSEEN,
383 NULL,
384 tempNeighborInfo);
385 }
386 else if ((!IP_COMPARE(hello->DesignatedRouter, tempNeighborInfo->neighborIPAddr) &&
387 IP_COMPARE(nbrPrevDR, tempNeighborInfo->neighborIPAddr)) ||
388 (IP_COMPARE(hello->DesignatedRouter, tempNeighborInfo->neighborIPAddr) &&
389 !IP_COMPARE(nbrPrevDR, tempNeighborInfo->neighborIPAddr)))
390 {
392 d,
393 in,
394 OSPF_NEIGHBORCHANGE,
395 NULL,
396 tempNeighborInfo);
397 }
398
399
400 // If the neighbor is declaring itself to be Backup Designated Router and
401 // the receiving interface is in state Waiting, the receiving interface's
402 // state machine is scheduled with the event BackupSeen. Otherwise, if
403 // neighbor is declaring itself to be Backup Designated Router and it had
404 // not previously, or the neighbor is not declaring itself Backup
405 // Designated Router where it had previously, the receiving interface's
406 // state machine is scheduled with the event NeighborChange.
407 if (hello->BackupDesignatedRouter->int_ip[0] ==
408 tempNeighborInfo->neighborIPAddr->int_ip[0] &&
409 thisIntf->State == OSPFIFSTATE_WAITING)
410 {
412 d,
413 in,
414 OSPF_BACKUPSEEN,
415 NULL,
416 tempNeighborInfo);
417 }
418 else if ((hello->BackupDesignatedRouter->int_ip[0] == tempNeighborInfo->neighborIPAddr->int_ip[0] &&
419 nbrPrevBDR->int_ip[0] != tempNeighborInfo->neighborIPAddr->int_ip[0]) ||
420 (hello->BackupDesignatedRouter->int_ip[0] != tempNeighborInfo->neighborIPAddr->int_ip[0] &&
421 nbrPrevBDR->int_ip[0] == tempNeighborInfo->neighborIPAddr->int_ip[0]))
422 {
424 d,
425 in,
426 OSPF_NEIGHBORCHANGE,
427 NULL,
428 tempNeighborInfo);
429 }
430
431TERMINATE_PROCESSING_HELLO:
435}
436
unsigned int NETSIM_ID
Definition: Animation.h:45
NETSIM_IPAddress IP_COPY(NETSIM_IPAddress ip)
#define IP_COMPARE(ip1, ip2)
Definition: IP_Addressing.h:67
#define c
BOOL
Definition: Linux.h:62
#define UINT
Definition: Linux.h:38
#define fnNetSimError(x,...)
Definition: Linux.h:56
#define UINT16
Definition: Linux.h:33
#define UINT8
Definition: Linux.h:31
#define realloc(p, s)
Definition: Memory.h:32
#define free(p)
Definition: Memory.h:31
#define calloc(c, s)
Definition: Memory.h:29
#define OSPF_BROADCAST_JITTER
Definition: OSPF.h:56
void ospf_event_set_and_call(int subevent, void *otherDetails)
#define OSPF_PDS_CURRENT()
Definition: OSPF.h:151
void ospf_neighbor_add(ptrOSPF_IF ospf, ptrOSPF_NEIGHBOR neigh)
#define OSPF_IF_CURRENT()
Definition: OSPF.h:179
#define DEVICE_CURR_MASK
Definition: OSPF.h:38
ptrOSPF_NEIGHBOR ospf_neighbor_new(NETSIM_IPAddress ip, OSPFID rid)
void print_ospf_log(OSPFLOGFLAG logFlag, char *format,...)
#define OSPF_AREA_GET_ID(ospf, id)
Definition: OSPF.h:106
@ OSPF_HELLO_LOG
Definition: OSPF.h:32
NETSIM_IPAddress AllSPFRouters
Definition: OSPF.h:48
#define ospf_event_add(time, d, in, subevent, packet, eventdata)
Definition: OSPF.h:400
static bool isOSPFHelloDebug
Definition: OSPF.h:27
static void add_next_hello_timer()
Definition: OSPF_Hello.c:72
void start_interval_hello_timer()
Definition: OSPF_Hello.c:50
static bool ospf_hello_findNeighbor(ptrOSPF_IF thisInterface, NETSIM_IPAddress srcAddr, OSPFID rid, ptrOSPF_NEIGHBOR *neighbor)
Definition: OSPF_Hello.c:222
void ospf_process_hello()
Definition: OSPF_Hello.c:258
static void send_hello()
Definition: OSPF_Hello.c:141
static bool is_ip_present_in_hello(ptrOSPFHELLO hello, NETSIM_IPAddress ip)
Definition: OSPF_Hello.c:211
void OSPF_HELLO_MSG_NEW(ptrOSPFPACKETHDR hdr)
Definition: OSPF_Hello.c:24
#define OSPF_HELLO_GET_BDR_FROM_IF(i)
Definition: OSPF_Hello.c:22
static UINT16 add_neighborToHello(ptrOSPFHELLO hello, ptrOSPF_IF ospf)
Definition: OSPF_Hello.c:95
void ospf_handle_helloTimer_event()
Definition: OSPF_Hello.c:157
static bool validate_hello_msg()
Definition: OSPF_Hello.c:174
static void set_hello_param(NetSim_PACKET *packet, ptrOSPFPACKETHDR hdr)
Definition: OSPF_Hello.c:119
ptrOSPFHELLO OSPF_HELLO_MSG_COPY(ptrOSPFHELLO hello)
Definition: OSPF_Hello.c:33
#define OSPF_HELLO_GET_DR_FROM_IF(i)
Definition: OSPF_Hello.c:21
static void ospf_hello_update_dst(NetSim_PACKET *packet)
Definition: OSPF_Hello.c:133
void OSPF_HELLO_MSG_FREE(ptrOSPFHELLO hello)
Definition: OSPF_Hello.c:45
@ OSPFIFTYPE_P2MP
@ OSPFIFTYPE_P2P
@ OSPFIFTYPE_BROADCAST
@ OSPFIFTYPE_VIRTUALLINK
@ OSPFIFSTATE_WAITING
@ OSPFIFSTATE_DOWN
void OSPF_SEND_PACKET(NetSim_PACKET *packet)
Definition: OSPF_Msg.c:136
void OSPF_HDR_INCREASE_LEN(NetSim_PACKET *packet, UINT16 len)
Definition: OSPF_Msg.c:80
void OSPF_HDR_SET_MSG(ptrOSPFPACKETHDR hdr, OSPFMSG type, void *msg, UINT16 len)
Definition: OSPF_Msg.c:70
NetSim_PACKET * OSPF_PACKET_NEW(double time, OSPFMSG type, NETSIM_ID d, NETSIM_ID in)
Definition: OSPF_Msg.c:106
@ OSPFMSG_HELLO
Definition: OSPF_Msg.h:33
#define OSPF_HDR_GET_MSG(hdr)
Definition: OSPF_Msg.h:93
#define OSPFHELLO_LEN_FIXED
Definition: OSPF_Msg.h:166
#define OSPF_PACKET_GET_HDR(packet)
Definition: OSPF_Msg.h:91
@ OSPFNEIGHSTATE_Init
Definition: OSPF_Neighbor.h:25
#define OSPFID_COMPARE
Definition: OSPF_Typedef.h:42
#define OSPFTIME_TO_UINT16(time)
Definition: OSPF_Typedef.h:47
enum enum_ospf_msg OSPFMSG
Definition: OSPF_Typedef.h:38
void add_dest_to_packet(NetSim_PACKET *packet, NETSIM_ID dest)
#define DEVICE_TYPE(DeviceId)
Definition: Stack.h:773
#define DEVICE_NWADDRESS(DeviceId, InterfaceId)
Definition: Stack.h:805
@ APP_PROTOCOL_OSPF
Definition: Stack.h:155
#define MILLISECOND
Definition: Stack.h:59
#define SECOND
Definition: Stack.h:60
@ TIMER_EVENT
Definition: Stack.h:114
#define DEVICE_MYIP()
Definition: Stack.h:806
EXPORTED struct stru_NetSim_EventDetails * pstruEventDetails
Definition: Stack.h:837
#define NETSIM_RAND_01()
Definition: Stack.h:860
#define fn_NetSim_Packet_FreePacket(pstruPacket)
Definition: main.h:177
#define fnpAddEvent(pstruEvent)
Definition: main.h:191
EVENT_TYPE nEventType
Definition: Stack.h:747
NETSIM_ID nProtocolId
Definition: Stack.h:748
struct stru_NetSim_Packet * pPacket
Definition: Stack.h:754
NETSIM_ID nSubEventType
Definition: Stack.h:757
NETSIM_ID nDeviceId
Definition: Stack.h:750
netsimDEVICE_TYPE nDeviceType
Definition: Stack.h:749
NETSIM_ID nInterfaceId
Definition: Stack.h:751
NETSIM_IPAddress szDestIP
Definition: Packet.h:199
NETSIM_IPAddress szNextHopIp
Definition: Packet.h:201
NETSIM_IPAddress szSourceIP
Definition: Packet.h:198
struct stru_NetSim_Packet_NetworkLayer * pstruNetworkData
Definition: Packet.h:275
char str_ip[_NETSIM_IP_LEN]
Definition: IP_Addressing.h:54
unsigned int int_ip[4]
Definition: IP_Addressing.h:51
NETSIM_IPAddress NetworkMask
Definition: OSPF_Msg.h:155
UINT RouterDeadInterval
Definition: OSPF_Msg.h:159
UINT16 HelloInterval
Definition: OSPF_Msg.h:156
NETSIM_IPAddress DesignatedRouter
Definition: OSPF_Msg.h:160
NETSIM_IPAddress * Neighbor
Definition: OSPF_Msg.h:162
NETSIM_IPAddress BackupDesignatedRouter
Definition: OSPF_Msg.h:161
OSPFTIME routerDeadInterval
ptrOSPF_NEIGHBOR * neighborRouterList
OSPFIFTYPE Type
NETSIM_IPAddress IPIfMask
OSPFTIME helloInterval
UINT8 RouterPriority
OSPFIFSTATE State
UINT neighborRouterCount
OSPFID neighborDesignateBackupRouter
Definition: OSPF_Neighbor.h:62
OSPFNEIGHSTATE state
Definition: OSPF_Neighbor.h:47
OSPFID neighborDesignateRouter
Definition: OSPF_Neighbor.h:61
NETSIM_IPAddress neighborIPAddr
Definition: OSPF_Neighbor.h:58
OSPFID routerId
Definition: OSPF.h:114