NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
IP.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* This source code is licensed per the NetSim license agreement. *
12* *
13* No portion of this source code may be used as the basis for a derivative work, *
14* or used, for any purpose other than its intended use per the NetSim license *
15* agreement. *
16* *
17* This source code and the algorithms contained within it are confidential trade *
18* secrets of TETCOS and may not be used as the basis for any other software, *
19* hardware, product or service. *
20* *
21* Author: Shashi Kant Suman *
22* *
23* ----------------------------------------------------------------------------------*/
24#include "main.h"
25#include "List.h"
26#include "IP.h"
27#include "Protocol.h"
28#include "NetSim_utility.h"
29#include "../Firewall/Firewall.h"
30#include "Animation.h"
31#include "../SupportFunction/Scheduling.h"
32#include "AdvancedPlots.h"
33#pragma comment(lib,"AdvancedPlots.lib")
34
35_declspec(dllexport) int fn_NetSim_IP_VPN_Init();
36NETWORK_LAYER_PROTOCOL fnGetLocalNetworkProtocol(NetSim_EVENTDETAILS* pstruEventDetails);
37int freeVPN(void* vpn);
38int freeDNS(void* dns);
39int freeVPNPacket(void* vpnPacket);
40void* copyVPNPacket(void* vpnPacket);
41static void add_default_ip_table_entry(NETSIM_ID d);
42void set_public_ip(NETSIM_ID d);
43void configure_static_ip_route(NETSIM_ID d, char* file);
44static void init_ip_anim();
45
46
47//ICMP function
48_declspec(dllexport) int fn_NetSim_IP_ICMP_GenerateDstUnreachableMsg();
49_declspec(dllexport) int fn_NetSim_IP_ICMP_EchoRequest();
50_declspec(dllexport) int fn_NetSim_IP_ICMP_EchoReply();
51_declspec(dllexport) int fn_NetSim_IP_ICMP_ProcessRouterAdvertisement();
52_declspec(dllexport) int fn_NetSim_IP_ICMP_ProcessDestUnreachableMsg();
53_declspec(dllexport) int fn_NetSim_IP_ICMP_Init();
54_declspec(dllexport) int fn_NetSim_IP_ICMP_POLL();
55_declspec(dllexport) int fn_NetSim_IP_ICMP_AdvertiseRouter();
56
57int fn_NetSim_IP_ConfigStaticIPTable(char* szVal);
58
59static IP_PROTOCOL_ACTION decide_action_for_packet(NetSim_PACKET* packet, NETSIM_ID dev)
60{
61 NETSIM_IPAddress dest = packet->pstruNetworkData->szDestIP;
62 NETSIM_IPAddress recv = packet->pstruNetworkData->szNextHopIp;
63
64 if (isBroadcastIP(dest))
65 {
66 if (isHost(dev))
67 return ACTION_MOVEUP;
68 else
69 return ACTION_DROP;
70 }
71
72 if (isMulticastIP(dest))
73 {
74 return check_ip_in_multicastgroup(dest, dev, packet);
75 }
76 switch (packet->pstruNetworkData->IPProtocol)
77 {
78 case IPPROTOCOL_PIM:
79 return pim_decide_action(packet, dev);
80 break;
81 }
82
83 if (isDestFoundinPacket(packet, dev))
84 return ACTION_MOVEUP;
85 else
86 return ACTION_REROUTE;
87}
88
89/**
90This function initializes the IP parameters.
91*/
92_declspec(dllexport) int fn_NetSim_IP_Init(struct stru_NetSim_Network *NETWORK_Formal,
93 NetSim_EVENTDETAILS *pstruEventDetails_Formal,
94 char *pszAppPath_Formal,
95 char *pszWritePath_Formal,
96 int nVersion_Type,
97 void **fnPointer)
98{
99 fnNetSim_buffer_log_init();
100
101 NETSIM_ID loop;
102 if (nVersion_Type / 10 != VERSION)
103 {
104 printf("IP---Version number mismatch\nDll Version=%d\nNetSim Version=%d\nFileName=%s\nLine=%d\n", VERSION, nVersion_Type / 10, __FILE__, __LINE__);
105 exit(0);
106 }
107 pstruEventDetails->dEventTime = 0;
108 //init_ip_anim();
109 fnDNS = dns_query;
110 ipMetrics = calloc(NETWORK->nDeviceCount, sizeof* ipMetrics);
111 for (loop = 0; loop < NETWORK->nDeviceCount; loop++)
112 {
113 if (!DEVICE_NWLAYER(loop + 1))
114 continue;
115
116 NETSIM_ID nInterface;
117 unsigned int i;
118
119 set_public_ip(loop + 1);
120
121 add_default_ip_table_entry(loop + 1);
122
123 IP_DEVVAR* devVar = NETWORK->ppstruDeviceList[loop]->pstruNetworkLayer->ipVar;
124
125 if (devVar->staticIPTableFile && *devVar->staticIPTableFile)
126 configure_static_ip_route(loop + 1, devVar->staticIPTableFile);
127
128 if (devVar->nGatewayCount)
129 devVar->nGatewayId = calloc(devVar->nGatewayCount, sizeof* devVar->nGatewayId);
130 for (i = 0; i < devVar->nGatewayCount; i++)
131 devVar->nGatewayId[i] = fn_NetSim_Stack_GetDeviceId_asIP(devVar->GatewayIPAddress[i], &nInterface);
132 if (devVar && devVar->isFirewallConfigured)
133 {
134 //read the firewall info
135 fn_NetSim_FirewallConfig(loop + 1);
136 }
137 ipMetrics[loop] = calloc(1, sizeof* ipMetrics[loop]);
138 ipMetrics[loop]->nDeviceId = fn_NetSim_Stack_GetConfigIdOfDeviceById(loop + 1);
139
140 //Init the IGMP
141 if (devVar->isIGMPConfigured)
142 igmp_init(loop + 1);
143
144 //Init the PIM
145 if (devVar->isPIMConfigured)
146 Router_PIM_Init(loop + 1);
147 }
148
149 //Initialize the ICMP
150 fn_NetSim_IP_ICMP_Init();
151
152 //Initialize the VPN
153 fn_NetSim_IP_VPN_Init();
154
155 return 1;
156}
157
158static ptrIP_FORWARD_ROUTE build_route(NetSim_PACKET* packet)
159{
160 NETSIM_ID d = pstruEventDetails->nDeviceId;
161 NETSIM_ID in = pstruEventDetails->nInterfaceId;
162
163 if (!packet)
164 return NULL;
165 if (!packet->pstruNetworkData->szNextHopIp)
166 return NULL;
167
168 ptrIP_FORWARD_ROUTE route = calloc(1, sizeof* route);
169 route->count = 1;
170
171 route->nextHop = calloc(1, sizeof* route->nextHop);
172 route->nextHop[0] = packet->pstruNetworkData->szNextHopIp;
173
174 route->gateway = calloc(1, sizeof* route->gateway);
175 route->gateway[0] = DEVICE_NWADDRESS(d, in);
176
177 route->interfaceId = calloc(1, sizeof* route->interfaceId);
178 route->interfaceId[0] = in;
179
180 route->nextHopId = calloc(1, sizeof* route->nextHopId);
181 route->nextHopId[0] = fn_NetSim_Stack_GetDeviceId_asIP(route->nextHop[0], &in);
182
183 return route;
184}
185
186static void ip_handle_processing_delay()
187{
188 NETSIM_ID d = pstruEventDetails->nDeviceId;
189 NETSIM_ID in = pstruEventDetails->nInterfaceId;
190 NetSim_EVENTDETAILS pevent;
191
192 if (DEVICE_INTERFACE(d, in)->nLocalNetworkProtocol)
193 {
194 memcpy(&pevent, pstruEventDetails, sizeof pevent);
195 pstruEventDetails->nEventType = NETWORK_OUT_EVENT;
196 pstruEventDetails->nProtocolId = DEVICE_INTERFACE(d, in)->nLocalNetworkProtocol;
197 pstruEventDetails->nSubEventType = 0;
198 pstruEventDetails->szOtherDetails = NULL;
199 //Call the local network protocol
200 fnCallProtocol(DEVICE_INTERFACE(d, in)->nLocalNetworkProtocol);
201 memcpy(pstruEventDetails, &pevent, sizeof * pstruEventDetails);
202 }
203 else
204 {
205 NetSim_BUFFER* buffer = DEVICE_INTERFACE(d, in)->pstruAccessInterface->pstruAccessBuffer;
206 NetSim_PACKET* packet = pstruEventDetails->pPacket;
207
208 if (!fn_NetSim_GetBufferStatus(buffer))
209 {
210 memcpy(&pevent, pstruEventDetails, sizeof pevent);
211
212 //Add the MAC out event
213 pevent.nEventType = MAC_OUT_EVENT;
214 pevent.nProtocolId = fn_NetSim_Stack_GetMacProtocol(d, in);
215 pevent.pPacket = NULL;
216 pevent.nSubEventType = 0;
217 fnpAddEvent(&pevent);
218 }
219 fn_NetSim_Packet_AddPacketToList(buffer, packet, 0);
220 }
221}
222
223/**
224This function is called by NetworkStack.dll, whenever the event gets triggered
225inside the NetworkStack.dll for IP.It includes NETWORK_OUT,NETWORK_IN and TIMER_EVENT.
226*/
227_declspec(dllexport) int fn_NetSim_IP_Run()
228{
229 switch (pstruEventDetails->nEventType)
230 {
231 case NETWORK_OUT_EVENT:
232 {
233 ptrIP_FORWARD_ROUTE route = NULL;
234 NetSim_PACKET* packet = pstruEventDetails->pPacket;
235 NETWORK_LAYER_PROTOCOL nLocalNetworkProtcol;
236 nLocalNetworkProtcol = fnGetLocalNetworkProtocol(pstruEventDetails);
237 if (nLocalNetworkProtcol)
238 {
239 fnCallProtocol(nLocalNetworkProtcol);
240 return 0;
241 }
242 if (packet->pstruNetworkData->nTTL == 0)
243 {
244 //TTL expire drop the packet
245 packet->nPacketStatus = PacketStatus_TTL_Expired;
246 packet->nTransmitterId = pstruEventDetails->nDeviceId;
247 packet->nReceiverId = pstruEventDetails->nDeviceId;
248 fn_NetSim_WritePacketTrace(packet);
249 fn_NetSim_Packet_FreePacket(packet);
250 pstruEventDetails->pPacket = NULL;
251 ipMetrics[pstruEventDetails->nDeviceId - 1]->nTTLDrop++;
252 return 0;
253 }
254 //set the time
255 packet->pstruNetworkData->dStartTime = pstruEventDetails->dEventTime;
256 packet->pstruNetworkData->dArrivalTime = pstruEventDetails->dEventTime;
257 //Set the payload
258 if (packet->pstruTransportData)
259 packet->pstruNetworkData->dPayload = packet->pstruTransportData->dPacketSize;
260
261 //Already got routed
262 if (packet->pstruNetworkData->szNextHopIp)
263 {
264 route = build_route(packet);
265 goto PACKET_ROUTED;
266 }
267
268 if (packet->pstruNetworkData->szNextHopIp == NULL)
269 {
270 //First route via static ip route table
271 route = fn_NetSim_IP_RoutePacketViaStaticEntry(packet,
272 pstruEventDetails->nDeviceId);
273 }
274
275 packet = pstruEventDetails->pPacket;
276
277 if (!packet)
278 return -1; //Routing fails
279
280 if (route && route->count)
281 goto PACKET_ROUTED;
282
283 //Call NAT
284 fn_NetSim_NAT_NetworkOut(pstruEventDetails->nDeviceId, packet);
285
286 // Recall static route
287 if (packet->pstruNetworkData->szNextHopIp == NULL)
288 {
289 //First route via static ip route table
290 route = fn_NetSim_IP_RoutePacketViaStaticEntry(packet,
291 pstruEventDetails->nDeviceId);
292 }
293
294 packet = pstruEventDetails->pPacket;
295
296 if (!packet)
297 return -1; //Routing fails
298
299 if (route && route->count)
300 goto PACKET_ROUTED;
301
302 //routing function
303 //First route via routing function
304 if (DEVICE_NWLAYER(pstruEventDetails->nDeviceId)->routerFunction)
305 DEVICE_NWLAYER(pstruEventDetails->nDeviceId)->routerFunction();
306
307 packet = pstruEventDetails->pPacket;
308 if (!packet)
309 return -1; //Routing fails
310
311 if (packet->pstruNetworkData->szNextHopIp)
312 {
313 route = build_route(packet);
314 goto PACKET_ROUTED;
315 }
316
317 //Route via routing protocol
318 if (DEVICE_NWLAYER(pstruEventDetails->nDeviceId)->nRoutingProtocolId)
319 {
320 fnCallProtocol(DEVICE_NWLAYER(pstruEventDetails->nDeviceId)->nRoutingProtocolId);
321 }
322
323 packet = pstruEventDetails->pPacket;
324 if (!packet)
325 return -1; //Routing fails
326
327 if (packet->pstruNetworkData->szNextHopIp)
328 {
329 route = build_route(packet);
330 goto PACKET_ROUTED;
331 }
332
333 //IP Routing
334 packet = pstruEventDetails->pPacket;
335 route = fn_NetSim_IP_RoutePacket(packet,
336 pstruEventDetails->nDeviceId);
337
338 if (!route || !route->count)
339 goto ROUTING_FAILS;
340 else
341 goto PACKET_ROUTED;
342
343 ROUTING_FAILS:
344 {
345 ipMetrics[pstruEventDetails->nDeviceId - 1]->nPacketDiscarded++;
346 //Generate ICMP dst unreachable message
347 IP_DEVVAR* var = GET_IP_DEVVAR(pstruEventDetails->nDeviceId);
348 if (var && var->isICMP)
349 fn_NetSim_IP_ICMP_GenerateDstUnreachableMsg();
350 packet = NULL;
351 free_ip_route(route);
352 return -2;
353 }
354
355 PACKET_ROUTED:
356 if (route)
357 {
358 NetSim_PACKET* p;
359 UINT i;
360 //Packet is routed via ip table
361 for (i = 0; i < route->count; i++)
362 {
363 if (i != route->count - 1)
364 p = fn_NetSim_Packet_CopyPacket(packet);
365 else
366 p = packet;
367
368 p->pstruNetworkData->szNextHopIp = route->nextHop[i];
369 pass_to_lower_layer(p, route, i);
370 }
371 }
372 else
373 {
374 //Packet is routed via other protocol
375 pass_to_lower_layer(packet, NULL, 0);
376 }
377 free_ip_route(route);
378 }
379 break;
380 case NETWORK_IN_EVENT:
381 {
382 NetSim_PACKET* packet = pstruEventDetails->pPacket;
383 if (pstruEventDetails->nInterfaceId && NETWORK->ppstruDeviceList[pstruEventDetails->nDeviceId - 1]->ppstruInterfaceList[pstruEventDetails->nInterfaceId - 1]->nLocalNetworkProtocol)
384 {
385 //Call the local network protocol
386 fnCallProtocol(NETWORK->ppstruDeviceList[pstruEventDetails->nDeviceId - 1]->ppstruInterfaceList[pstruEventDetails->nInterfaceId - 1]->nLocalNetworkProtocol);
387 }
388 if (pstruEventDetails->pPacket == NULL)
389 return 0;
390 packet = pstruEventDetails->pPacket;
391
392 NETSIM_IPAddress gateway = packet->pstruNetworkData->szGatewayIP;
393 NETSIM_IPAddress my = DEVICE_NWADDRESS(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId);
394 NETSIM_IPAddress sub = DEVICE_INTERFACE(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId)->szSubnetMask;
395 UINT prefix = DEVICE_INTERFACE(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId)->prefix_len;
396 if (!IP_IS_IN_SAME_NETWORK(gateway, my, sub, prefix))
397 {
398 fn_NetSim_Packet_FreePacket(packet);
399 return 0;
400 }
401
402 if (wireshark_trace.convert_sim_to_real_packet &&
403 !DEVICE_MACLAYER(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId)->isWiresharkWriter)
404 {
405 wireshark_trace.convert_sim_to_real_packet(packet,
406 wireshark_trace.pcapWriterlist[pstruEventDetails->nDeviceId - 1][pstruEventDetails->nInterfaceId - 1],
407 pstruEventDetails->dEventTime);
408 }
409
410 //Decrease the TTL
411 packet->pstruNetworkData->nTTL--;
412
413 //Reduce the IP overhead
414 packet->pstruNetworkData->dOverhead -= IPV4_HEADER_SIZE;
415 packet->pstruNetworkData->dPacketSize -= IPV4_HEADER_SIZE;
416 if ((((IP_DEVVAR*)DEVICE_NWLAYER(pstruEventDetails->nDeviceId)->ipVar)->nVPNStatus == VPN_SERVER ||
417 ((IP_DEVVAR*)DEVICE_NWLAYER(pstruEventDetails->nDeviceId)->ipVar)->nVPNStatus == VPN_CLIENT) &&
418 packet->pstruNetworkData->nPacketFlag == PACKET_VPN)
419 fn_NetSim_IP_VPN_Run();
420 packet = pstruEventDetails->pPacket;
421 if (!packet)
422 return 0;
423
424 //check for firewall
425 if (fn_NetSim_NETWORK_Firewall(pstruEventDetails->nDeviceId,
426 pstruEventDetails->nInterfaceId,
427 pstruEventDetails->pPacket,
428 ACLTYPE_INBOUND) == ACLACTION_DENY)
429 {
430 ipMetrics[pstruEventDetails->nDeviceId - 1]->nFirewallBlocked++;
431 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
432 pstruEventDetails->pPacket = NULL;
433 return 0;
434 }
435
436 //call routing protocol
437 if (DEVICE_NWLAYER(pstruEventDetails->nDeviceId)->nRoutingProtocolId)
438 fnCallProtocol(DEVICE_NWLAYER(pstruEventDetails->nDeviceId)->nRoutingProtocolId);
439 packet = pstruEventDetails->pPacket;
440 if (!packet)
441 return 0;
442
443 //Call NAT
444 fn_NetSim_NAT_NetworkIn(pstruEventDetails->nDeviceId, packet);
445
446 IP_PROTOCOL_ACTION action = decide_action_for_packet(packet, pstruEventDetails->nDeviceId);
447
448 if (action == ACTION_DROP)
449 {
450 //Drop packet
451 fn_NetSim_Packet_FreePacket(packet);
452 pstruEventDetails->pPacket = NULL;
453 return 0;
454 }
455
456 if (action == ACTION_MOVEUP)
457 {
458 TRANSPORT_LAYER_PROTOCOL txProtocol = TX_PROTOCOL_NULL;
459 IP_PROTOCOL_NUMBER num = packet->pstruNetworkData->IPProtocol;
460 switch (num)
461 {
462 case IPPROTOCOL_ICMP:
463 process_icmp_packet();
464 break;
465 case IPPROTOCOL_IGMP:
466 process_igmp_packet();
467 break;
468 case IPPROTOCOL_PIM:
469 process_pim_packet();
470 break;
471 case IPPROTOCOL_DSR:
472 //Already processed by routing protocol call.
473 break;
474 case IPPROTOCOL_TCP:
475 if (txProtocol == TX_PROTOCOL_NULL)
476 txProtocol = TX_PROTOCOL_TCP;
477 case IPPROTOCOL_UDP:
478 if(txProtocol == TX_PROTOCOL_NULL)
479 txProtocol = TX_PROTOCOL_UDP;
480 default:
481 //For legacy code
482
483 //Add transport in event
484 pstruEventDetails->dPacketSize = packet->pstruNetworkData->dPacketSize;
485 pstruEventDetails->nEventType = TRANSPORT_IN_EVENT;
486 pstruEventDetails->nProtocolId = txProtocol;
487 pstruEventDetails->nSubEventType = 0;
488 pstruEventDetails->szOtherDetails = NULL;
489 fnpAddEvent(pstruEventDetails);
490
491 //Increment the received count
492 ipMetrics[pstruEventDetails->nDeviceId - 1]->nPacketReceived++;
493 break;
494 }
495 }
496 else if (action == ACTION_REROUTE)
497 {
498 //Add network out event to reroute the packet
499 packet->pstruNetworkData->szNextHopIp = NULL;
500 packet->pstruNetworkData->szGatewayIP = NULL;
501
502 pstruEventDetails->dPacketSize = packet->pstruNetworkData->dPacketSize;
503 pstruEventDetails->nEventType = NETWORK_OUT_EVENT;
504 pstruEventDetails->nProtocolId = DEVICE_INTERFACE(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId)->nProtocolId;
505 pstruEventDetails->nSubEventType = 0;
506 pstruEventDetails->szOtherDetails = NULL;
507 fnpAddEvent(pstruEventDetails);
508
509 //Increment the forwarded count
510 ipMetrics[pstruEventDetails->nDeviceId - 1]->nPacketForwarded++;
511 }
512 }
513 break;
514 case TIMER_EVENT:
515 {
516 switch (pstruEventDetails->nSubEventType)
517 {
518 case EVENT_ICMP_POLL:
519 fn_NetSim_IP_ICMP_POLL();
520 break;
521 case EVENT_ADVERTISE_ROUTER:
522 fn_NetSim_IP_ICMP_AdvertiseRouter();
523 break;
524 case SUBEVENT_JOIN_MULTICAST_GROUP:
525 multicast_join_group();
526 break;
527 case EVENT_IGMP_SendStartupQuery:
528 case EVENT_IGMP_SendQuery:
529 send_query_msg(pstruEventDetails->nDeviceId,
530 pstruEventDetails->szOtherDetails,
531 pstruEventDetails->dEventTime);
532 break;
533 case EVENT_IGMP_OtherQuerierPresentTimer:
534 igmp_router_processOtherQuerierPresentTime();
535 break;
536 case EVENT_IGMP_DelayTimer:
537 host_send_report();
538 break;
539 case EVENT_IGMP_GroupMembershipTimer:
540 igmp_router_ProcessGroupMembershipTimer();
541 break;
542 case EVENT_IGMP_Unsolicited_report:
543 host_handle_unsolicited_report_timer();
544 break;
545 case EVENT_PIM_SEND_HELLO:
546 case EVENT_PIM_NEIGHBOR_TIMEOUT:
547 case EVENT_PIM_ET:
548 case EVENT_PIM_JT:
549 pim_handle_timer_event();
550 break;
551 case EVENT_IP_INIT_TABLE:
552 iptable_add(IP_WRAPPER_GET(pstruEventDetails->nDeviceId),
553 NULL, NULL, 0, NULL, 0, NULL, NULL, 0, NULL);
554 break;
555 case EVENT_ICMP_SEND_ECHO:
556 icmp_send_echo_request();
557 break;
558 case EVENT_IP_PROCESSING_DELAY:
559 ip_handle_processing_delay();
560 break;
561 default:
562 {
563 char error[BUFSIZ];
564 sprintf(error, "Unknown sub event %d for IP", pstruEventDetails->nSubEventType);
565 fnNetSimError(error);
566 }
567 break;
568 }
569 }
570 break;
571 default:
572 {
573 char error[BUFSIZ];
574 sprintf(error, "Unknown event %d for IP", pstruEventDetails->nEventType);
575 fnNetSimError(error);
576 }
577 break;
578 }
579 return 0;
580}
581
582/**
583This function is called by NetworkStack.dll, once simulation end to free the
584allocated memory for the network.
585*/
586_declspec(dllexport) int fn_NetSim_IP_Finish()
587{
588 fn_NetSim_buffer_log_close();
589
590 NETSIM_ID i;
591 for (i = 0; i < NETWORK->nDeviceCount; i++)
592 {
593 if (DEVICE_NWLAYER(i + 1))
594 {
595 ptrIP_ROUTINGTABLE table = IP_TABLE_GET(i+1);
596 IP_DEVVAR* devVar = NETWORK->ppstruDeviceList[i]->pstruNetworkLayer->ipVar;
597 if (devVar)
598 {
599 fn_NetSim_Firewall_Free(i + 1);
600 free(devVar->firewallConfig);
601 free(devVar->GatewayIPAddress);
602 free(devVar->nGatewayId);
603 free(devVar->nGatewayState);
604 free(devVar->nInterfaceId);
605 freeVPN(devVar->vpn);
606 freeDNS(devVar->dnsList);
607 igmp_free(i + 1);
608 free(devVar);
609 }
610 while (table)
611 {
612 LIST_FREE(&table, table);
613 }
614 }
615 free(ipMetrics[i]);
616 }
617 free(ipMetrics);
618 return 1;
619}
620
621/**
622This function is called by NetworkStack.dll, while writing the event trace
623to get the sub event as a string.
624*/
625_declspec(dllexport) char* fn_NetSim_IP_Trace(NETSIM_ID nSubeventid)
626{
627 switch (nSubeventid)
628 {
629 case EVENT_ICMP_POLL:
630 return "ICMP_POLL";
631 case EVENT_ADVERTISE_ROUTER:
632 return "ICMP_Advertise_Router";
633 case EVENT_IGMP_DelayTimer:
634 return "IGMP_DelayTimer";
635 case EVENT_IGMP_GroupMembershipTimer:
636 return "IGMP_GroupMembershipTimer";
637 case EVENT_IGMP_OtherQuerierPresentTimer:
638 return "IGMP_OtherQueierPresentTimer";
639 case EVENT_IGMP_SendQuery:
640 return "IGMP_SendQuery";
641 case EVENT_IGMP_SendStartupQuery:
642 return "IGMP_SendStartupQuery";
643 case EVENT_IGMP_Unsolicited_report:
644 return "IGMP_UnsolicitedReportTimer";
645 case EVENT_IP_INIT_TABLE:
646 return "IP_INIT_TABLE";
647 case EVENT_PIM_SEND_HELLO:
648 return "PIM_SEND_HELLO";
649 case EVENT_PIM_NEIGHBOR_TIMEOUT:
650 return "PIM_NEIGHBOR_TIMEOUT";
651 case EVENT_PIM_JT:
652 return "PIM_JT";
653 case EVENT_PIM_ET:
654 return "PIM_ET";
655 case EVENT_ICMP_SEND_ECHO:
656 return "ICMP_SEND_ECHO";
657 case EVENT_IP_PROCESSING_DELAY:
658 return "IP_PROCESSING_DELAY";
659 default:
660 return "IP_UNKNOWN_SUBEVENT";
661 }
662}
663
664#pragma region SCHEDULER_CONFIG
665#define QUEUING_MAX_TH_MB_DEFAULT 7.0
666#define QUEUING_MIN_TH_MB_DEFAULT 4.0
667
668#define QUEUING_MAX_P_DEFAULT 0.05
669#define QUEUING_WQ_DEFAULT 0.0002
670
671#define QUEUING_LOW_MAX_TH_MB_DEFAULT 7.0
672#define QUEUING_NORMAL_MAX_TH_MB_DEFAULT 7.0
673#define QUEUING_MEDIUM_MAX_TH_MB_DEFAULT 7.0
674#define QUEUING_HIGH_MAX_TH_MB_DEFAULT 7.0
675#define QUEUING_LOW_MIN_TH_MB_DEFAULT 4.0
676#define QUEUING_NORMAL_MIN_TH_MB_DEFAULT 4.5
677#define QUEUING_MEDIUM_MIN_TH_MB_DEFAULT 5.0
678#define QUEUING_HIGH_MIN_TH_MB_DEFAULT 5.5
679
680#define QUEUING_LOW_MAX_P_DEFAULT 0.05
681#define QUEUING_NORMAL_MAX_P_DEFAULT 0.05
682#define QUEUING_MEDIUM_MAX_P_DEFAULT 0.05
683#define QUEUING_HIGH_MAX_P_DEFAULT 0.05
684
685#define SCHEDULING_MAX_LATENCY_UGS_MS_DEFAULT 100
686#define SCHEDULING_MAX_LATENCY_rtPS_MS_DEFAULT 150
687#define SCHEDULING_MAX_LATENCY_ertPS_MS_DEFAULT 300
688#define SCHEDULING_MAX_LATENCY_nrtPS_MS_DEFAULT 300
689#define SCHEDULING_MAX_LATENCY_BE_MS_DEFAULT 100000
690
691static void ip_queuing_read_config(NETSIM_ID d, NETSIM_ID in, void* xmlNetSimNode)
692{
693 char* szVal;
694 NetSim_BUFFER* pstruBuffer = DEVICE_ACCESSBUFFER(d, in);
695
696 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "QUEUING_TYPE", 0);
697 if (szVal)
698 {
699 if (_stricmp(szVal, "DROP_TAIL") == 0)
700 pstruBuffer->queuingTechnique = QUEUING_DROPTAIL;
701 else if (_stricmp(szVal, "RED") == 0)
702 {
703 pstruBuffer->queuingTechnique = QUEUING_RED;
704
705 ptrQUEUING_RED_VAR queuing_var = calloc(1, sizeof * queuing_var);
706 queuing_var->max_th = fn_NetSim_Config_read_dataLen(xmlNetSimNode, "MAX_TH", QUEUING_MAX_TH_MB_DEFAULT, "MB");
707 queuing_var->min_th = fn_NetSim_Config_read_dataLen(xmlNetSimNode, "MIN_TH", QUEUING_MIN_TH_MB_DEFAULT, "MB");
708 getXmlVar(&queuing_var->max_p, MAX_P, xmlNetSimNode, 1, _DOUBLE, QUEUING);
709 getXmlVar(&queuing_var->wq, WQ, xmlNetSimNode, 1, _DOUBLE, QUEUING);
710
711 queuing_var->avg_queue_size = 0;
712 queuing_var->count = -1;
713 queuing_var->random_value = NETSIM_RAND_01();
714 queuing_var->q_time = 0;
715 pstruBuffer->queuingParam = queuing_var;
716 }
717 else if (_stricmp(szVal, "WRED") == 0)
718 {
719 pstruBuffer->queuingTechnique = QUEUING_WRED;
720 ptrQUEUING_WRED_VAR queuing_var = calloc(1, sizeof * queuing_var);
721 double* min_th_values = calloc(4, sizeof * min_th_values);
722 double* max_th_values = calloc(4, sizeof * max_th_values);
723 double* max_p_values = calloc(4, sizeof * max_p_values);
724 int* count_values = calloc(4, sizeof * count_values);
725 double* random_values = calloc(4, sizeof * random_values);
726 min_th_values[0] = fn_NetSim_Config_read_dataLen(xmlNetSimNode, "LOW_MIN_TH", QUEUING_LOW_MIN_TH_MB_DEFAULT, "MB");
727 min_th_values[1] = fn_NetSim_Config_read_dataLen(xmlNetSimNode, "NORMAL_MIN_TH", QUEUING_NORMAL_MIN_TH_MB_DEFAULT, "MB");
728 min_th_values[2] = fn_NetSim_Config_read_dataLen(xmlNetSimNode, "MEDIUM_MIN_TH", QUEUING_MEDIUM_MIN_TH_MB_DEFAULT, "MB");
729 min_th_values[3] = fn_NetSim_Config_read_dataLen(xmlNetSimNode, "HIGH_MIN_TH", QUEUING_HIGH_MIN_TH_MB_DEFAULT, "MB");
730 max_th_values[0] = fn_NetSim_Config_read_dataLen(xmlNetSimNode, "LOW_MAX_TH", QUEUING_LOW_MAX_TH_MB_DEFAULT, "MB");
731 max_th_values[1] = fn_NetSim_Config_read_dataLen(xmlNetSimNode, "NORMAL_MAX_TH", QUEUING_NORMAL_MAX_TH_MB_DEFAULT, "MB");
732 max_th_values[2] = fn_NetSim_Config_read_dataLen(xmlNetSimNode, "MEDIUM_MAX_TH", QUEUING_MEDIUM_MAX_TH_MB_DEFAULT, "MB");
733 max_th_values[3] = fn_NetSim_Config_read_dataLen(xmlNetSimNode, "HIGH_MAX_TH", QUEUING_HIGH_MAX_TH_MB_DEFAULT, "MB");
734 getXmlVar(&max_p_values[0], LOW_MAX_P, xmlNetSimNode, 1, _DOUBLE, QUEUING);
735 getXmlVar(&max_p_values[1], NORMAL_MAX_P, xmlNetSimNode, 1, _DOUBLE, QUEUING);
736 getXmlVar(&max_p_values[2], MEDIUM_MAX_P, xmlNetSimNode, 1, _DOUBLE, QUEUING);
737 getXmlVar(&max_p_values[3], HIGH_MAX_P, xmlNetSimNode, 1, _DOUBLE, QUEUING);
738 getXmlVar(&queuing_var->wq, WQ, xmlNetSimNode, 1, _DOUBLE, QUEUING);
739
740
741 count_values[0] = -1;
742 count_values[1] = -1;
743 count_values[2] = -1;
744 count_values[3] = -1;
745 random_values[0] = NETSIM_RAND_01();
746 random_values[1] = NETSIM_RAND_01();
747 random_values[2] = NETSIM_RAND_01();
748 random_values[3] = NETSIM_RAND_01();
749
750 queuing_var->max_th = max_th_values;
751 queuing_var->min_th = min_th_values;
752 queuing_var->max_p = max_p_values;
753 queuing_var->avg_queue_size = 0;
754 queuing_var->count = count_values;
755 queuing_var->random_value = random_values;
756 pstruBuffer->queuingParam = queuing_var;
757 }
758 else
759 {
760 fnNetSimError("Unknwon queuing technique %s for router %d-%d.\n",
761 szVal, d, in);
762 pstruBuffer->queuingTechnique = QUEUING_NULL;
763 }
764 }
765 else
766 pstruBuffer->queuingTechnique = QUEUING_NULL;
767 free(szVal);
768}
769
770static void ip_scheduling_read_config(NETSIM_ID d, NETSIM_ID in, void* xmlNetSimNode)
771{
772 NetSim_BUFFER* pstruBuffer = DEVICE_ACCESSBUFFER(d, in);
773 char* szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "SCHEDULING_TYPE", 0);
774 if (szVal)
775 {
776 _strupr(szVal);
777 if (strcmp(szVal, "FIFO") == 0)
778 pstruBuffer->nSchedulingType = SCHEDULING_FIFO;
779 else if (strcmp(szVal, "PRIORITY") == 0)
780 pstruBuffer->nSchedulingType = SCHEDULING_PRIORITY;
781 else if (strcmp(szVal, "ROUND_ROBIN") == 0)
782 pstruBuffer->nSchedulingType = SCHEDULING_ROUNDROBIN;
783 else if (strcmp(szVal, "WFQ") == 0)
784 pstruBuffer->nSchedulingType = SCHEDULING_WFQ;
785 else if (strcmp(szVal, "EDF") == 0)
786 {
787 pstruBuffer->nSchedulingType = SCHEDULING_EDF;
788 ptrSCHEDULING_EDF_VAR scheduling_var = calloc(1, sizeof * scheduling_var);
789 double* max_latency_values = calloc(5, sizeof * max_latency_values);
790
791 max_latency_values[0] = fn_NetSim_Config_read_time(xmlNetSimNode, "MAX_LATENCY_UGS", SCHEDULING_MAX_LATENCY_UGS_MS_DEFAULT, "ms");
792 max_latency_values[1] = fn_NetSim_Config_read_time(xmlNetSimNode, "MAX_LATENCY_rtPS", SCHEDULING_MAX_LATENCY_rtPS_MS_DEFAULT, "ms");
793 max_latency_values[2] = fn_NetSim_Config_read_time(xmlNetSimNode, "MAX_LATENCY_ertPS", SCHEDULING_MAX_LATENCY_ertPS_MS_DEFAULT, "ms");
794 max_latency_values[3] = fn_NetSim_Config_read_time(xmlNetSimNode, "MAX_LATENCY_nrtPS", SCHEDULING_MAX_LATENCY_nrtPS_MS_DEFAULT, "ms");
795 max_latency_values[4] = fn_NetSim_Config_read_time(xmlNetSimNode, "MAX_LATENCY_BE", SCHEDULING_MAX_LATENCY_BE_MS_DEFAULT, "ms");
796
797 scheduling_var->max_latency = max_latency_values;
798 pstruBuffer->schedulingParam = scheduling_var;
799 }
800 else
801 {
802 fnNetSimError("Unknown scheduling technique %s for router %d-%d.\n",
803 szVal, d, in);
804 pstruBuffer->nSchedulingType = SCHEDULING_NONE;
805 }
806 }
807 else
808 pstruBuffer->nSchedulingType = SCHEDULING_NONE;
809 free(szVal);
810}
811#pragma endregion
812
813/**
814This function is called by NetworkStack.dll, while configuring the device
815NETWORK layer for IP protocol.
816*/
817_declspec(dllexport) int fn_NetSim_IP_Configure(void** var)
818{
819 FILE* fpConfigLog;
820 void* xmlNetSimNode;
821 NETSIM_ID nDeviceId = 0;
822 NETSIM_ID nInterfaceId = 0;
823 LAYER_TYPE nLayerType = 0;
824 char* szVal;
825 IP_DEVVAR* devVar;
826 fpConfigLog = var[0];
827 xmlNetSimNode = var[2];
828 if (var[3])
829 nDeviceId = *((NETSIM_ID*)var[3]);
830 if (var[4])
831 nInterfaceId = *((NETSIM_ID*)var[4]);
832 if (var[5])
833 nLayerType = *((LAYER_TYPE*)var[5]);
834 if (nDeviceId)
835 {
836 devVar = NETWORK->ppstruDeviceList[nDeviceId - 1]->pstruNetworkLayer->ipVar;
837 if (devVar == NULL)
838 {
839 devVar = calloc(1, sizeof* devVar);
840 NETWORK->ppstruDeviceList[nDeviceId - 1]->pstruNetworkLayer->ipVar = devVar;
841 }
842 }
843
844 if (nDeviceId && nInterfaceId)
845 {
846 int iptype = 0;
847 NetSim_BUFFER* pstruBuffer;
848 int nDeviceType;
849 nDeviceType = DEVICE_TYPE(nDeviceId);
850
851 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "BUFFER_SIZE", 0);
852 if (szVal)
853 {
854 pstruBuffer = DEVICE_ACCESSBUFFER(nDeviceId, nInterfaceId);
855
856 pstruBuffer->deviceId = nDeviceId;
857 pstruBuffer->interfaceId = nInterfaceId;
858
859 pstruBuffer->dMaxBufferSize = atof(szVal);
860 free(szVal);
861
862 //Configure the Queuing
863 ip_queuing_read_config(nDeviceId, nInterfaceId, xmlNetSimNode);
864
865 //Configure the Scheduling
866 ip_scheduling_read_config(nDeviceId, nInterfaceId, xmlNetSimNode);
867 }
868
869 if (NETWORK->ppstruDeviceList[nDeviceId - 1]->ppstruInterfaceList[nInterfaceId - 1]->nProtocolId == NW_PROTOCOL_IPV4)
870 iptype = 4;
871 else if (NETWORK->ppstruDeviceList[nDeviceId - 1]->ppstruInterfaceList[nInterfaceId - 1]->nProtocolId == NW_PROTOCOL_IPV6)
872 iptype = 6;
873 //Configure the IP address
874 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "IP_ADDRESS", 1);
875 NETWORK->ppstruDeviceList[nDeviceId - 1]->ppstruInterfaceList[nInterfaceId - 1]->szAddress = STR_TO_IP(szVal, iptype);
876 free(szVal);
877
878 if (iptype == 4)
879 {
880 //Configure the subnet mask
881 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "SUBNET_MASK", 1);
882 NETWORK->ppstruDeviceList[nDeviceId - 1]->ppstruInterfaceList[nInterfaceId - 1]->szSubnetMask = STR_TO_IP4(szVal);
883 free(szVal);
884 }
885 else if (iptype == 6)
886 {
887 //Configure the subnet mask
888 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "PREFIX_LENGTH", 1);
889 NETWORK->ppstruDeviceList[nDeviceId - 1]->ppstruInterfaceList[nInterfaceId - 1]->prefix_len = atoi(szVal);
890 free(szVal);
891 }
892 else
893 return -1;
894
895 //Configure the default gateway
896 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "DEFAULT_GATEWAY", 0);
897 if (szVal)
898 NETWORK->ppstruDeviceList[nDeviceId - 1]->ppstruInterfaceList[nInterfaceId - 1]->szDefaultGateWay = STR_TO_IP(szVal, iptype);
899 free(szVal);
900 }
901 else if (nDeviceId)
902 {
903 devVar->processingDelay = fn_NetSim_Config_read_time(xmlNetSimNode, "PROCESSING_DELAY", IP_PROCESSING_DELAY_DEFAULT, "us");
904
905 getXmlVar(&devVar->isIGMPConfigured, IGMP_STATUS, xmlNetSimNode, 0, _BOOL, IP);
906
907 getXmlVar(&devVar->staticIPTableFile, STATIC_IP_ROUTE, xmlNetSimNode, 0, _STRING, IP);
908
909 if (devVar->isIGMPConfigured)
910 igmp_configure(nDeviceId, xmlNetSimNode);
911
912 getXmlVar(&devVar->isPIMConfigured, PIM_STATUS, xmlNetSimNode, 0, _BOOL, IP);
913 if (devVar->isPIMConfigured)
914 pim_configure(nDeviceId, xmlNetSimNode);
915
916 //Configure the firewall status
917 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "ACL_STATUS", 0);
918 if (szVal && _strupr(szVal) && !strcmp(szVal, "ENABLE"))
919 {
920 devVar->isFirewallConfigured = true;
921 free(szVal);
922 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "ACL_CONFIG_FILE", 1);
923 if (szVal)
924 devVar->firewallConfig = szVal;
925 else
926 devVar->isFirewallConfigured = false;
927 }
928 else
929 free(szVal);
930
931 getXmlVar(&devVar->isICMP, ICMP_STATUS, xmlNetSimNode, 0, _BOOL, IP);
932
933 if (devVar->isICMP)
934 {
935 //Configure the ICMP property
936 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "ICMP_CONTINUOUS_POLLING_TIME", 0);
937 if (szVal)
938 {
939 devVar->nICMPPollingTime = atoi(szVal);
940 free(szVal);
941 }
942 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "ROUTER_ADVERTISEMENT", 0);
943 if (szVal)
944 {
945 _strupr(szVal);
946 if (!strcmp(szVal, "TRUE"))
947 devVar->nRouterAdvertisementFlag = 1;
948 free(szVal);
949 }
950 if (devVar->nRouterAdvertisementFlag)
951 {
952 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "ROUTER_ADVERTISEMENT_MIN_INTERVAL", 0);
953 if (szVal)
954 {
955 devVar->nRouterAdverMinInterval = atoi(szVal);
956 free(szVal);
957 }
958 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "ROUTER_ADVERTISEMENT_MAX_INTERVAL", 0);
959 if (szVal)
960 {
961 devVar->nRouterAdverMaxInterval = atoi(szVal);
962 free(szVal);
963 }
964 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "ROUTER_ADVERTISEMENT_LIFE_TIME", 0);
965 if (szVal)
966 {
967 devVar->nRouterAdverLifeTime = atoi(szVal);
968 free(szVal);
969 }
970 }
971 }
972
973 //Configure the VPN
974 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "VPN_STATUS", 0);
975 if (szVal)
976 {
977 _strupr(szVal);
978 if (!strcmp(szVal, "SERVER"))
979 {
980 devVar->nVPNStatus = VPN_SERVER;
981 free(szVal);
982 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "IP_POOL_START", 1);
983 if (szVal)
984 {
985 devVar->ipPoolStart = STR_TO_IP4(szVal);
986 }
987 else
988 devVar->nVPNStatus = VPN_DISABLE;
989 free(szVal);
990 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "IP_POOL_END", 1);
991 if (szVal)
992 {
993 devVar->ipPoolEnd = STR_TO_IP4(szVal);
994 }
995 else
996 devVar->nVPNStatus = VPN_DISABLE;
997 free(szVal);
998 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "IP_POOL_MASK", 1);
999 if (szVal)
1000 {
1001 devVar->ipPoolMask = STR_TO_IP4(szVal);
1002 }
1003 else
1004 devVar->nVPNStatus = VPN_DISABLE;
1005 free(szVal);
1006 }
1007 else if (!strcmp(szVal, "CLIENT"))
1008 {
1009 devVar->nVPNStatus = VPN_CLIENT;
1010 free(szVal);
1011 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "SERVER_IP", 1);
1012 if (szVal)
1013 {
1014 devVar->serverIP = STR_TO_IP4(szVal);
1015 }
1016 else
1017 devVar->nVPNStatus = VPN_DISABLE;
1018 free(szVal);
1019 }
1020 else
1021 free(szVal);
1022 }
1023 }
1024 return 1;
1025}
1026
1027/**
1028This function is to free the memory allocated for packets of this protocol.
1029*/
1030_declspec(dllexport) int fn_NetSim_IP_FreePacket(NetSim_PACKET* pstruPacket)
1031{
1032 if (pstruPacket->pstruNetworkData->nPacketFlag == PACKET_VPN)
1033 {
1034 freeVPNPacket(pstruPacket->pstruNetworkData->Packet_NetworkProtocol);
1035 }
1036 switch (pstruPacket->pstruNetworkData->IPProtocol)
1037 {
1038 case IPPROTOCOL_IGMP:
1039 IGMP_FreePacket(pstruPacket);
1040 break;
1041 }
1042 return 1;
1043}
1044/**
1045This function is to copy the IP information from source to the destination.
1046*/
1047_declspec(dllexport) int fn_NetSim_IP_CopyPacket(NetSim_PACKET* pstruDestPacket, NetSim_PACKET* pstruSrcPacket)
1048{
1049 if (pstruSrcPacket->pstruNetworkData->nPacketFlag == PACKET_VPN)
1050 pstruDestPacket->pstruNetworkData->Packet_NetworkProtocol = copyVPNPacket(pstruSrcPacket->pstruNetworkData->Packet_NetworkProtocol);
1051 switch (pstruSrcPacket->pstruNetworkData->IPProtocol)
1052 {
1053 case IPPROTOCOL_ICMP:
1054 ICMP_copyPacket(pstruDestPacket, pstruSrcPacket);
1055 break;
1056 case IPPROTOCOL_IGMP:
1057 copy_igmp_packet(pstruDestPacket, pstruSrcPacket);
1058 break;
1059 }
1060 return 1;
1061}
1062/**
1063This function write the Metrics in Metrics.txt
1064*/
1065_declspec(dllexport) int fn_NetSim_IP_Metrics(PMETRICSWRITER metricsWriter)
1066{
1067 NETSIM_ID loop;
1068 PMETRICSNODE menu = init_metrics_node(MetricsNode_Menu, "IP_Metrics", NULL);
1069 PMETRICSNODE table = init_metrics_node(MetricsNode_Table, "IP_Metrics", NULL);
1070 add_node_to_menu(menu, table);
1071
1072 add_table_heading(table, "Device Id", true, 0);
1073 add_table_heading(table, "Packet sent", true, 0);
1074 add_table_heading(table, "Packet forwarded", true, 0);
1075 add_table_heading(table, "Packet received", true, 0);
1076 add_table_heading(table, "Packet discarded", false, 0);
1077 add_table_heading(table, "TTL expired", false, 0);
1078 add_table_heading(table, "Firewall blocked", false, 0);
1079
1080 for (loop = 0; loop < NETWORK->nDeviceCount; loop++)
1081 {
1082 if (ipMetrics[loop])
1083 {
1084 add_table_row_formatted(false, table, "%d,%d,%d,%d,%d,%d,%d,",
1085 ipMetrics[loop]->nDeviceId,
1086 ipMetrics[loop]->nPacketSent,
1087 ipMetrics[loop]->nPacketForwarded,
1088 ipMetrics[loop]->nPacketReceived,
1089 ipMetrics[loop]->nPacketDiscarded,
1090 ipMetrics[loop]->nTTLDrop,
1091 ipMetrics[loop]->nFirewallBlocked);
1092 }
1093 }
1094 write_metrics_node(metricsWriter, WriterPosition_Current, NULL, menu);
1095 delete_metrics_node(menu);
1096
1097 menu = init_metrics_node(MetricsNode_Menu, "IP_Forwarding_Table", NULL);
1098 for (loop = 0; loop < NETWORK->nDeviceCount; loop++)
1099 {
1100 if (NETWORK->ppstruDeviceList[loop]->pstruNetworkLayer &&
1101 IP_TABLE_GET(loop+1))
1102 {
1103 ptrIP_ROUTINGTABLE routeTable = IP_TABLE_GET(loop + 1);
1104
1105 PMETRICSNODE submenu = init_metrics_node(MetricsNode_Menu, NETWORK->ppstruDeviceList[loop]->szDeviceName, NULL);
1106 add_node_to_menu(menu, submenu);
1107 table = init_metrics_node(MetricsNode_Table, NETWORK->ppstruDeviceList[loop]->szDeviceName, NULL);
1108 add_node_to_menu(submenu, table);
1109
1110 add_table_heading(table, "Network Destination", true, 0);
1111 add_table_heading(table, "Netmask/Prefix len", true, 0);
1112 add_table_heading(table, "Gateway", true, 0);
1113 add_table_heading(table, "Interface", true, 0);
1114 add_table_heading(table, "Metrics", false, 0);
1115 add_table_heading(table, "Type", false, 0);
1116
1117 while (routeTable)
1118 {
1119 char ipStr[_NETSIM_IP_LEN];
1120 IP_TO_STR(routeTable->networkDestination, ipStr);
1121 add_table_row_formatted(false, table, "%s,", ipStr);
1122 if (routeTable->networkDestination && routeTable->networkDestination->type == 4)
1123 {
1124 IP_TO_STR(routeTable->netMask, ipStr);
1125 add_table_row_formatted(true, table, "%s,", ipStr);
1126 }
1127 else if (routeTable->networkDestination && routeTable->networkDestination->type == 6)
1128 {
1129 add_table_row_formatted(true, table, "%d,", routeTable->prefix_len);
1130 }
1131 if (routeTable->gateway)
1132 {
1133 IP_TO_STR(routeTable->gateway, ipStr);
1134 add_table_row_formatted(true, table, "%s,", ipStr);
1135 }
1136 else
1137 add_table_row_formatted(true, table, "on-link,");
1138
1139 UINT i;
1140 char str[BUFSIZ] = "";
1141 for (i = 0; i < routeTable->interfaceCount; i++)
1142 {
1143 strcat(str, routeTable->Interface[i]->str_ip);
1144 strcat(str, " ");
1145 }
1146 add_table_row_formatted(true, table, "%s,", str);
1147
1148 add_table_row_formatted(true, table, "%d,", routeTable->Metric);
1149
1150 if (routeTable->szType && *routeTable->szType)
1151 {
1152 add_table_row_formatted(true, table, "%s,", routeTable->szType);
1153 }
1154 else
1155 {
1156 switch (routeTable->type)
1157 {
1158 case RoutingType_DEFAULT:
1159 add_table_row_formatted(true, table, "Default,");
1160 break;
1161 case RoutingType_STATIC:
1162 add_table_row_formatted(true, table, "Static,");
1163 break;
1164 default:
1165 add_table_row_formatted(true, table, "-,");
1166 break;
1167 }
1168 }
1169 routeTable = LIST_NEXT(routeTable);
1170 }
1171 }
1172 }
1173 write_metrics_node(metricsWriter, WriterPosition_Current, NULL, menu);
1174 delete_metrics_node(menu);
1175 return 1;
1176}
1177int IP_packetTraceFiledFlag[4] = { 0,0,0,0 };
1178char pszTrace[BUFSIZ];
1179/**
1180This function will return the string to write packet trace heading.
1181*/
1182_declspec(dllexport) char* fn_NetSim_IP_ConfigPacketTrace(const void* xmlNetSimNode)
1183{
1184 char* szStatus;
1185 *pszTrace = 0;
1186 szStatus = fn_NetSim_xmlConfigPacketTraceField(xmlNetSimNode, "SOURCE_IP");
1187 _strupr(szStatus);
1188 if (!strcmp(szStatus, "ENABLE"))
1189 {
1190 IP_packetTraceFiledFlag[0] = 1;
1191 strcat(pszTrace, "SOURCE_IP,");
1192 }
1193 else
1194 IP_packetTraceFiledFlag[0] = 0;
1195 free(szStatus);
1196 szStatus = fn_NetSim_xmlConfigPacketTraceField(xmlNetSimNode, "DESTINATION_IP");
1197 _strupr(szStatus);
1198 if (!strcmp(szStatus, "ENABLE"))
1199 {
1200 IP_packetTraceFiledFlag[1] = 1;
1201 strcat(pszTrace, "DESTINATION_IP,");
1202 }
1203 else
1204 IP_packetTraceFiledFlag[1] = 0;
1205 free(szStatus);
1206 szStatus = fn_NetSim_xmlConfigPacketTraceField(xmlNetSimNode, "GATEWAY_IP");
1207 _strupr(szStatus);
1208 if (!strcmp(szStatus, "ENABLE"))
1209 {
1210 IP_packetTraceFiledFlag[2] = 1;
1211 strcat(pszTrace, "GATEWAY_IP,");
1212 }
1213 else
1214 IP_packetTraceFiledFlag[2] = 0;
1215 free(szStatus);
1216 szStatus = fn_NetSim_xmlConfigPacketTraceField(xmlNetSimNode, "NEXT_HOP_IP");
1217 _strupr(szStatus);
1218 if (!strcmp(szStatus, "ENABLE"))
1219 {
1220 IP_packetTraceFiledFlag[3] = 1;
1221 strcat(pszTrace, "NEXT_HOP_IP,");
1222 }
1223 else
1224 IP_packetTraceFiledFlag[3] = 0;
1225 free(szStatus);
1226 return pszTrace;
1227}
1228/**
1229This function will return the string to write packet trace.
1230*/
1231_declspec(dllexport) int fn_NetSim_IP_WritePacketTrace(NetSim_PACKET* pstruPacket, char** ppszTrace)
1232{
1233 int i = 0;
1234 char ip[_NETSIM_IP_LEN];
1235 *pszTrace = 0;
1236 *ppszTrace = calloc(BUFSIZ, sizeof(char));
1237 if (pstruPacket->pstruNetworkData == NULL)
1238 {
1239 sprintf(*ppszTrace, "-,-,-,-,");
1240 return 0;
1241 }
1242
1243
1244 if (IP_packetTraceFiledFlag[i++] == 1)
1245 {
1246 if (pstruPacket->pstruNetworkData->szSourceIP)
1247 IP_TO_STR(pstruPacket->pstruNetworkData->szSourceIP, ip);
1248 else
1249 strcpy(ip, "-");
1250 sprintf(pszTrace, "%s%s,", pszTrace, ip);
1251 }
1252 if (IP_packetTraceFiledFlag[i++] == 1)
1253 {
1254 if (pstruPacket->pstruNetworkData->szDestIP)
1255 IP_TO_STR(pstruPacket->pstruNetworkData->szDestIP, ip);
1256 else
1257 strcpy(ip, "-");
1258 sprintf(pszTrace, "%s%s,", pszTrace, ip);
1259 }
1260 if (IP_packetTraceFiledFlag[i++] == 1)
1261 {
1262 if (pstruPacket->pstruNetworkData->szGatewayIP)
1263 IP_TO_STR(pstruPacket->pstruNetworkData->szGatewayIP, ip);
1264 else
1265 strcpy(ip, "-");
1266 sprintf(pszTrace, "%s%s,", pszTrace, ip);
1267 }
1268 if (IP_packetTraceFiledFlag[i++] == 1)
1269 {
1270 if (pstruPacket->pstruNetworkData->szNextHopIp)
1271 IP_TO_STR(pstruPacket->pstruNetworkData->szNextHopIp, ip);
1272 else
1273 strcpy(ip, "-");
1274 sprintf(pszTrace, "%s%s,", pszTrace, ip);
1275 }
1276 strcpy(*ppszTrace, pszTrace);
1277 return 1;
1278}
1279
1280
1281/** This function is to get the local network protocol */
1282NETWORK_LAYER_PROTOCOL fnGetLocalNetworkProtocol(NetSim_EVENTDETAILS* pstruEventDetails)
1283{
1284 switch (pstruEventDetails->nSubEventType / 100)
1285 {
1286 case NW_PROTOCOL_ARP:
1287 return NW_PROTOCOL_ARP;
1288 }
1289 switch (pstruEventDetails->pPacket->nControlDataType / 100)
1290 {
1291 case NW_PROTOCOL_ARP:
1292 return NW_PROTOCOL_ARP;
1293 }
1294 return 0;
1295}
1296
1297static bool isSameIPForOtherInterface(NETSIM_ID d, NETSIM_ID in)
1298{
1299 NETSIM_ID i;
1300 bool isDefault = false;
1301 bool isFound = false;
1302
1303 if (DEVICE_NWADDRESS(d, in) == NULL) return false;
1304
1305 if (DEVICE_INTERFACE(d, in)->szDefaultGateWay)
1306 isDefault = true;
1307
1308 for (i = 0; i < DEVICE(d)->nNumOfInterface; i++)
1309 {
1310 if (DEVICE_NWADDRESS(d, i + 1) == NULL) continue;
1311
1312 if (!IP_COMPARE(DEVICE_NWADDRESS(d, i + 1), DEVICE_NWADDRESS(d, in)))
1313 {
1314 if (in > i + 1)
1315 isFound = true;
1316
1317 if (DEVICE_INTERFACE(d, i + 1)->szDefaultGateWay)
1318 {
1319 if (!isDefault)
1320 return true;
1321 else if (in <= i + 1)
1322 return false;
1323 else
1324 return true;
1325 }
1326 }
1327 }
1328 return isFound;
1329}
1330
1331static void add_default_ip_table_entry(NETSIM_ID d)
1332{
1333 NETSIM_ID i;
1334
1335 if (!DEVICE_NWLAYER(d))
1336 return; //Why i am called.
1337
1338 for (i = 1; i <= DEVICE(d)->nNumOfInterface; i++)
1339 {
1340 NETSIM_IPAddress dest = NULL;
1341 NETSIM_IPAddress mask = NULL;
1342 NETSIM_IPAddress gate;
1343 UINT pre = 0;
1344
1345 IP_DEVVAR* devVar = DEVICE_NWLAYER(d)->ipVar;
1346 NETSIM_IPAddress ip = DEVICE_NWADDRESS(d, i);
1347 NETSIM_IPAddress subnet = DEVICE_INTERFACE(d, i)->szSubnetMask;
1348 NETSIM_IPAddress gateway = DEVICE_INTERFACE(d, i)->szDefaultGateWay;
1349 UINT prefix = DEVICE_INTERFACE(d, i)->prefix_len;
1350
1351 if (!ip) continue; //Not an IP interface
1352
1353 if (isSameIPForOtherInterface(d, i))
1354 continue;
1355
1356 iptable_add(IP_WRAPPER_GET(d),
1357 IP_NETWORK_ADDRESS(ip, subnet, prefix),
1358 subnet,
1359 prefix,
1360 on_link,
1361 1,
1362 &ip,
1363 &i,
1364 ONLINK_METRIC,
1365 "LOCAL");
1366
1367 if (gateway && IP_COMPARE(ip, gateway))
1368 {
1369 if (ip->type == 4)
1370 {
1371 mask = STR_TO_IP4("0.0.0.0");
1372 dest = STR_TO_IP4("0.0.0.0");
1373 }
1374 else if (ip->type == 6)
1375 {
1376 pre = 0;
1377 dest = STR_TO_IP6("0:0:0:0:0:0:0:0");
1378 }
1379 iptable_add(IP_WRAPPER_GET(d),
1380 dest,
1381 mask,
1382 pre,
1383 gateway,
1384 1,
1385 &ip,
1386 &i,
1387 DEFAULT_METRIC,
1388 "DEFAULT");
1389 devVar->nGatewayCount++;
1390 devVar->GatewayIPAddress = realloc(devVar->GatewayIPAddress, devVar->nGatewayCount*(sizeof* devVar->GatewayIPAddress));
1391 devVar->GatewayIPAddress[devVar->nGatewayCount - 1] = gateway;
1392 devVar->nGatewayState = realloc(devVar->nGatewayState, devVar->nGatewayCount*(sizeof* devVar->nGatewayState));
1393 devVar->nGatewayState[devVar->nGatewayCount - 1] = GATEWAYSTATE_UP;
1394 devVar->nInterfaceId = realloc(devVar->nInterfaceId, devVar->nGatewayCount*(sizeof* devVar->nInterfaceId));
1395 devVar->nInterfaceId[devVar->nGatewayCount - 1] = i;
1396 }
1397 if (DEVICE_INTERFACE(d, i)->nInterfaceType != INTERFACE_WAN_ROUTER)
1398 {
1399 if (ip->type == 4)
1400 {
1401 mask = STR_TO_IP4("255.255.255.255");
1402 dest = STR_TO_IP4("255.255.255.255");
1403 pre = 0;
1404 }
1405 else if (ip->type == 6)
1406 {
1407 dest = STR_TO_IP6("FF00:0:0:0:0:0:0:0");
1408 mask = NULL;
1409 pre = 8;
1410 }
1411 gate = on_link;
1412 iptable_add(IP_WRAPPER_GET(d),
1413 dest,
1414 mask,
1415 pre,
1416 gate,
1417 1,
1418 &ip,
1419 &i,
1420 DEFAULT_METRIC,
1421 "BROADCAST");
1422 }
1423
1424 //Add entry for Multicast
1425 if (ip->type == 4)
1426 {
1427 mask = STR_TO_IP4("240.0.0.0");
1428 dest = STR_TO_IP4("224.0.0.0");
1429 pre = 0;
1430 }
1431 else if (ip->type == 6)
1432 {
1433 dest = STR_TO_IP6("FFX2:0:0:0:0:0:0:0");
1434 mask = NULL;
1435 pre = 16;
1436 }
1437 gate = on_link;
1438 iptable_add(IP_WRAPPER_GET(d),
1439 dest,
1440 mask,
1441 pre,
1442 gate,
1443 1,
1444 &ip,
1445 &i,
1446 MULTICAST_METRIC,
1447 "MULTICAST");
1448
1449 if (ip->type == 4)
1450 {
1451 mask = STR_TO_IP4("255.255.255.255");
1452 dest = STR_TO_IP4("224.0.0.1");
1453 pre = 0;
1454 }
1455 else if (ip->type == 6)
1456 {
1457 dest = STR_TO_IP6("FFX2:0:0:0:0:0:0:1");
1458 mask = NULL;
1459 pre = 128;
1460 }
1461 gate = on_link;
1462 iptable_add(IP_WRAPPER_GET(d),
1463 dest,
1464 mask,
1465 pre,
1466 gate,
1467 1,
1468 &ip,
1469 &i,
1470 MULTICAST_METRIC,
1471 "MULTICAST");
1472 }
1473}
1474
1475void ip_write_to_pcap(NetSim_PACKET* packet,
1476 NETSIM_ID d,
1477 NETSIM_ID i,
1478 double time)
1479{
1480 if (!wireshark_trace.convert_sim_to_real_packet)
1481 return; //PCAP writer is not available
1482
1483 if (DEVICE_MACLAYER(d, i)->isWiresharkWriter)
1484 return; //PCAP writer is handled by mac layer
1485
1486 wireshark_trace.convert_sim_to_real_packet(packet,
1487 wireshark_trace.pcapWriterlist[d - 1][i - 1],
1488 time);
1489}
1490
1491static void init_event_to_write(NETSIM_ID d)
1492{
1493 NetSim_EVENTDETAILS pe;
1494
1495 memset(&pe, 0, sizeof pe);
1496 pe.nDeviceId = d;
1497 pe.nDeviceType = DEVICE_TYPE(d);
1498 pe.nEventType = TIMER_EVENT;
1499 pe.nSubEventType = EVENT_IP_INIT_TABLE;
1500 pe.nProtocolId = NW_PROTOCOL_IPV4;
1501 fnpAddEvent(&pe);
1502}
1503
1504static void init_ip_anim()
1505{
1506 ANIM_HANDLE handle;
1507 ANIM_HANDLE chandle;
1508 handle = anim_add_new_menu(NULL, "IP Table", false, false, false, 0, ANIMFILETYPE_TABLE);
1509 NETSIM_ID i;
1510 for (i = 0; i < NETWORK->nDeviceCount; i++)
1511 {
1512 if (DEVICE_NWLAYER(i + 1))
1513 {
1514 chandle = anim_add_new_menu(handle,
1515 DEVICE_NAME(i + 1),
1516 false,
1517 true,
1518 true,
1519 0,
1520 ANIMFILETYPE_TABLE);
1521 DEVICE_NWLAYER(i + 1)->ipWrapper->handle = chandle;
1522 init_event_to_write(i + 1);
1523 }
1524 }
1525}