NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
RouteRequest.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#include "main.h"
15#include "List.h"
16#include "DSR.h"
17int fn_NetSim_DSR_DeleteRREQTable(NETSIM_IPAddress targetAddress,NETSIM_ID nDeviceId);
18double getRREQBackoff(DSR_RREQ_TABLE* table);
19bool fn_NetSim_DSR_CheckIPinIPList(NETSIM_IPAddress* ipList,int length,NETSIM_IPAddress ip);
20bool fn_NetSim_DSR_CheckEntryInRREQTable(DSR_RREQ_OPTION* rreq,DSR_RREQ_TABLE* table);
21/**
22This function initiates a route request to the target.
23*/
24NetSim_PACKET* fn_NetSim_DSR_InitRouteRequest(NETSIM_IPAddress target,DSR_RREQ_TABLE** rreqTable,
25 NETSIM_ID nDeviceId,
26 double dTime,
27 NetSim_EVENTDETAILS* pstruEventDetails)
28{
29 NetSim_EVENTDETAILS pevent;
30 NetSim_PACKET* rreq = fn_NetSim_DSR_GenerateCtrlPacket(nDeviceId,
31 0,0,/*BROADCAST*/
32 dTime,
33 ctrlPacket_ROUTE_REQUEST);
34 DSR_OPTION_HEADER* option=(DSR_OPTION_HEADER*)calloc(1,sizeof* option);
35 DSR_RREQ_OPTION* rreqOption=(DSR_RREQ_OPTION*)calloc(1,sizeof* rreqOption);
36 DSR_RREQ_TABLE* table;
37 rreq->pstruNetworkData->dPacketSize=DSR_RREQ_SIZE_FIXED+DSR_OPTION_HEADER_SIZE;
38 rreq->pstruNetworkData->dOverhead=DSR_RREQ_SIZE_FIXED+DSR_OPTION_HEADER_SIZE;
39 rreq->pstruNetworkData->dPayload=0;
40
41 rreq->pstruNetworkData->Packet_RoutingProtocol = option;
42 option->nFlowState=0;
43 option->nNextHeader=NO_NEXT_HEADER;
44 option->nReserved = 0;
45 option->nPayloadLength=DSR_RREQ_SIZE_FIXED;
46 option->optType = optType_RouteRequest;
47
48 option->options = rreqOption;
49 rreqOption->nOptionType = optType_RouteRequest;
50 rreqOption->nOptDataLen = DSR_RREQ_OPT_LEN;
51 rreqOption->nIdentification = ++DSR_DEV_VAR(pstruEventDetails->nDeviceId)->nRREQIdentification;
52 rreqOption->targetAddress = target;
53 rreq->pstruNetworkData->nTTL = 1; //Initially hop limit = 1
54
55 table=(DSR_RREQ_TABLE*)RREQTABLE_ALLOC();
56 table->target = IP_COPY(rreqOption->targetAddress);
57 table->lastRequestTime = dTime;
58 table->nCount = 1;
59 table->nTTL = 1;
60 table->nIdentification = rreqOption->nIdentification;
61 LIST_ADD_LAST(rreqTable,table);
62
63 //Time out event
64 memcpy(&pevent,pstruEventDetails,sizeof* pstruEventDetails);
65 pevent.dEventTime += NonpropRequestTimeout;
66 pevent.nInterfaceId = 1;
67 pevent.dPacketSize = 0;
68 pevent.nApplicationId = 0;
69 pevent.nEventType = TIMER_EVENT;
70 pevent.nPacketId = 0;
71 pevent.nProtocolId = NW_PROTOCOL_DSR;
72 pevent.nSubEventType = subevent_RREQ_TIMEOUT;
73 pevent.pPacket = NULL;
74 pevent.szOtherDetails = IP_COPY(rreqOption->targetAddress);
75 table->nEventId = fnpAddEvent(&pevent);
76
77 //Update the metrics
78 DSR_DEV_VAR(nDeviceId)->dsrMetrics.rreqSent++;
79 return rreq;
80}
81/**
82This function checks if a route is present in the route cache. If not, then it retransmits
83the route request packet if the route request count is less than the DSR Max Retransmit limit.
84If the RREQ count is > Max Retransmit Limit, it Empties the Send Buffer and deletes the RREQ
85entry from the RREQ table.
86*/
87int fn_NetSim_DSR_RREQTimeout(NetSim_EVENTDETAILS* pstruEventDetails)
88{
89 DSR_ROUTE_CACHE* cache;
90 NETSIM_IPAddress nextHop;
91 NETSIM_IPAddress targetAddress=(NETSIM_IPAddress)pstruEventDetails->szOtherDetails;
92 //check for route exits or not
93 if(!DSR_CHECK_ROUTE_FOUND(targetAddress,DSR_DEV_VAR(pstruEventDetails->nDeviceId),&nextHop,pstruEventDetails->dEventTime,&cache))
94 {
95 //No route reply received
96 DSR_RREQ_TABLE* table = getRREQTable(targetAddress,DSR_DEV_VAR(pstruEventDetails->nDeviceId)->pstruRREQTable);
97 if(table->nCount < DSR_MAX_REQUEST_REXMT)
98 {
99 //Retry sending route request
100 pstruEventDetails->nEventType = NETWORK_OUT_EVENT;
101 pstruEventDetails->pPacket = DSR_RETRY_RREQ(targetAddress,
102 pstruEventDetails->nDeviceId,pstruEventDetails->dEventTime);
103 pstruEventDetails->nSubEventType = 0;
104 IP_FREE(pstruEventDetails->szOtherDetails);
105 pstruEventDetails->szOtherDetails = NULL;
106 fnpAddEvent(pstruEventDetails);
107 return 0;
108 }
109 else
110 {
111 DSR_EMPTY_SEND_BUFFER(targetAddress,pstruEventDetails->nDeviceId);
112 fn_NetSim_DSR_DeleteRREQTable(targetAddress,pstruEventDetails->nDeviceId);
113 }
114 }
115 else
116 {
117 //Route reply already received. Ignore the event
118 }
119 IP_FREE(pstruEventDetails->szOtherDetails);
120 pstruEventDetails->szOtherDetails = NULL;
121 return 0;
122}
123/**
124This function retransmits the RREQ packet.
125*/
126NetSim_PACKET* fn_NetSim_DSR_RetryRREQ(NETSIM_IPAddress targetAddress,
127 NETSIM_ID nDeviceId,
128 double dTime,
129 NetSim_EVENTDETAILS* pstruEventDetails)
130{
131 NetSim_EVENTDETAILS pevent;
132 DSR_RREQ_TABLE* rreqTable = DSR_DEV_VAR(nDeviceId)->pstruRREQTable;
133 NetSim_PACKET* rreq = fn_NetSim_DSR_GenerateCtrlPacket(nDeviceId,
134 0,0,/*BROADCAST*/
135 dTime,
136 ctrlPacket_ROUTE_REQUEST);
137 DSR_OPTION_HEADER* option=(DSR_OPTION_HEADER*)calloc(1,sizeof* option);
138 DSR_RREQ_OPTION* rreqOption=(DSR_RREQ_OPTION*)calloc(1,sizeof* rreqOption);
139 DSR_RREQ_TABLE* table;
140 rreq->pstruNetworkData->dPacketSize=DSR_RREQ_SIZE_FIXED+DSR_OPTION_HEADER_SIZE;
141 rreq->pstruNetworkData->dOverhead=DSR_RREQ_SIZE_FIXED+DSR_OPTION_HEADER_SIZE;
142 rreq->pstruNetworkData->dPayload=0;
143
144 rreq->pstruNetworkData->Packet_RoutingProtocol = option;
145 option->nFlowState=0;
146 option->nNextHeader=NO_NEXT_HEADER;
147 option->nReserved = 0;
148 option->nPayloadLength=DSR_RREQ_SIZE_FIXED;
149 option->optType = optType_RouteRequest;
150
151 option->options = rreqOption;
152 rreqOption->nOptionType = optType_RouteRequest;
153 rreqOption->nOptDataLen = DSR_RREQ_OPT_LEN;
154 rreqOption->nIdentification = ++DSR_DEV_VAR(nDeviceId)->nRREQIdentification;
155 rreqOption->targetAddress = IP_COPY(targetAddress);
156 rreq->pstruNetworkData->nTTL = DSR_DISCOVERY_HOP_LIMIT;
157
158 table=getRREQTable(targetAddress,rreqTable);
159 table->lastRequestTime = dTime;
160 table->nCount++;
161 table->nIdentification = rreqOption->nIdentification;
162 table->nTTL = DSR_DISCOVERY_HOP_LIMIT;
163
164 //Time out event
165 memcpy(&pevent,pstruEventDetails,sizeof* pstruEventDetails);
166 pevent.dEventTime += getRREQBackoff(table);
167 pevent.dPacketSize = 0;
168 pevent.nApplicationId = 0;
169 pevent.nEventType = TIMER_EVENT;
170 pevent.nPacketId = 0;
171 pevent.nProtocolId = NW_PROTOCOL_DSR;
172 pevent.nSubEventType = subevent_RREQ_TIMEOUT;
173 pevent.pPacket = NULL;
174 pevent.szOtherDetails = IP_COPY(rreqOption->targetAddress);
175 table->nEventId = fnpAddEvent(&pevent);
176 //Update the metrics
177 DSR_DEV_VAR(nDeviceId)->dsrMetrics.rreqSent++;
178 return rreq;
179}
180/**
181If a RREQ to a target is before hand generated, this entry is made in the RREQ Table.
182This function gets the RREQ table of the target IP if the RREQ was beforehand sent.
183*/
184DSR_RREQ_TABLE* getRREQTable(NETSIM_IPAddress target,DSR_RREQ_TABLE* table)
185{
186 while(table)
187 {
188
189 if(!IP_COMPARE(table->target,target) && table->flag==false)
190 return table;
191 table = LIST_NEXT(table);
192 }
193 return NULL;
194}
195/**
196This gets the Backoff time of the RREQ table. The backoff time is time until when if the RREQ
197is not received, it retransmits the RREQ.
198*/
199double getRREQBackoff(DSR_RREQ_TABLE* table)
200{
201 if(!table->dBackoff)
202 {
203 table->dBackoff = DSR_REQUEST_PERIOD;
204 return DSR_REQUEST_PERIOD;
205 }
206 table->dBackoff *= 2;
207 if(table->dBackoff > DSR_MAX_REQUEST_PERIOD)
208 table->dBackoff = DSR_MAX_REQUEST_PERIOD;
209 return table->dBackoff;
210}
211/**
212This function deletes the entry from the Route Request table
213*/
214int fn_NetSim_DSR_DeleteRREQTable(NETSIM_IPAddress targetAddress,NETSIM_ID nDeviceId)
215{
216 DSR_RREQ_TABLE* table = DSR_DEV_VAR(nDeviceId)->pstruRREQTable;
217 while(table)
218 {
219
220 if(!IP_COMPARE(table->target,targetAddress))
221 {
222 LIST_FREE(&DSR_DEV_VAR(nDeviceId)->pstruRREQTable,table);
223 break;
224 }
225 table = LIST_NEXT(table);
226 }
227 return 0;
228}
229/**
230This function process the RREQ that a device gets.
231If the target address is the device, it generates a RREP.
232If the RREQ packet contains the device IP in its address list, it drops the packet.
233If the Device cache contains the route to the target, then the device replies via the route
234cache.
235If no route is present, then the device forwards the RREQ.
236*/
237int fn_NetSim_DSR_ProcessRREQ(NetSim_EVENTDETAILS* pstruEventDetails)
238{
239 DSR_ROUTE_CACHE* cache;
240 NetSim_PACKET* packet = pstruEventDetails->pPacket;
241 DSR_OPTION_HEADER* option = (DSR_OPTION_HEADER*)packet->pstruNetworkData->Packet_RoutingProtocol;
242 DSR_RREQ_OPTION* rreq = (DSR_RREQ_OPTION*)option->options;
243 if (fn_NetSim_DSR_CheckEntryInRREQTable(rreq, DSR_DEV_VAR(pstruEventDetails->nDeviceId)->pstruRREQTable))
244 {
245 //Drop the route request packet
246 fn_NetSim_Packet_FreePacket(packet);
247 pstruEventDetails->pPacket = NULL;
248 return 0;
249 }
250 else
251 {
252 DSR_RREQ_TABLE* table;
253 table = (DSR_RREQ_TABLE*)RREQTABLE_ALLOC();
254 table->target = IP_COPY(rreq->targetAddress);
255 table->lastRequestTime = pstruEventDetails->dEventTime;
256 table->nCount = 1;
257 table->nTTL = 1;
258 table->nIdentification = rreq->nIdentification;
259 LIST_ADD_LAST(&DSR_DEV_VAR(pstruEventDetails->nDeviceId)->pstruRREQTable, table);
260 }
261
262 if(!IP_COMPARE(rreq->targetAddress,dsr_get_curr_ip()))
263 {
264 DSR_GENERATE_RREP(packet);
265 //Free route request packet
266 fn_NetSim_Packet_FreePacket(packet);
267 }
268 else
269 {
270 int length = DSR_RREQ_LEN(rreq);
271 //Check for own ip address in address list
272 if(fn_NetSim_DSR_CheckIPinIPList(rreq->address,length,dsr_get_curr_ip()))
273 {
274 //Drop the route request packet
275 fn_NetSim_Packet_FreePacket(packet);
276 pstruEventDetails->pPacket = NULL;
277 return 0;
278 }
279 else
280 {
281
282 NETSIM_IPAddress nexthop;
283 //Add entry to route request table
284 DSR_RREQ_TABLE* table = RREQTABLE_ALLOC();
285 table->nIdentification = rreq->nIdentification;
286 table->target = IP_COPY(rreq->targetAddress);
287 LIST_ADD_LAST((void**)&DSR_DEV_VAR(pstruEventDetails->nDeviceId)->pstruRREQTable, table);
288 if (fn_NetSim_DSR_CheckRouteFound(rreq->targetAddress,
289 DSR_DEV_VAR(pstruEventDetails->nDeviceId),
290 &nexthop,
291 pstruEventDetails->dEventTime,
292 &cache))
293 {
294 //Route already present. reply using route cache
295 fn_NetSim_DSR_GenerateRREPUsingRouteCache(DSR_DEV_VAR(pstruEventDetails->nDeviceId),
296 pstruEventDetails->pPacket,
297 pstruEventDetails->dEventTime,
298 pstruEventDetails);
299 }
300 else
301 {
302 //No route present forward the route request
303 rreq->address = (NETSIM_IPAddress*)realloc(rreq->address, (sizeof *rreq->address)*(DSR_RREQ_LEN(rreq) + 1));
304 rreq->address[DSR_RREQ_LEN(rreq)] = dsr_get_curr_ip();
305 rreq->nOptDataLen += 4;
306 pstruEventDetails->pPacket->pstruNetworkData->dOverhead += 4.0;
307 pstruEventDetails->pPacket->pstruNetworkData->dPacketSize += 4.0;
308 pstruEventDetails->pPacket->nTransmitterId = pstruEventDetails->nDeviceId;
309 pstruEventDetails->pPacket->nReceiverId = 0;
310 //Generate network out event
311 pstruEventDetails->dEventTime += fn_NetSim_DSR_GetBroadCastJitter();
312 pstruEventDetails->nEventType = NETWORK_OUT_EVENT;
313 fnpAddEvent(pstruEventDetails);
314 //Update the metrics
315 DSR_DEV_VAR(pstruEventDetails->nDeviceId)->dsrMetrics.rreqForwarded++;
316 }
317 }
318 }
319 return 1;
320}
321/**
322This functions checks if the IP is in the IP_List. It returns true if IP is there or else
323it returns false.
324*/
325bool fn_NetSim_DSR_CheckIPinIPList(NETSIM_IPAddress* ipList,int length,NETSIM_IPAddress ip)
326{
327 while(length--)
328 {
329
330 if(!IP_COMPARE(ipList[length],ip))
331 return true;
332 }
333 return false;
334}
335/**
336This function checks if the RREQ table has an entry of the target IP address. This indicates
337that the particular device has already initiated a RREQ to the target.
338*/
339bool fn_NetSim_DSR_CheckEntryInRREQTable(DSR_RREQ_OPTION* rreq,DSR_RREQ_TABLE* table)
340{
341 while(table)
342 {
343
344 if(table->nIdentification == rreq->nIdentification && !IP_COMPARE(table->target,rreq->targetAddress))
345 return true;
346 table = LIST_NEXT(table);
347 }
348 return false;
349}
350
unsigned int nReserved
Definition DSR.h:548
unsigned int nNextHeader
Definition DSR.h:536
unsigned int nFlowState
Definition DSR.h:543
DSR_OPTION_TYPE optType
Definition DSR.h:558
unsigned int nTTL
nTTL - Time to Live
Definition DSR.h:602
unsigned int nIdentification
Identification value.
Definition DSR.h:613
DSR_OPTION_TYPE nOptionType
Definition DSR.h:218
unsigned int nOptDataLen
Definition DSR.h:224
unsigned int nIdentification
Definition DSR.h:231