NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
IGMP.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
15#include "main.h"
16#include "List.h"
17#include "IP.h"
18#include "IGMP.h"
19
20static FILE* igmp_log = NULL;
21static void init_igmp_log()
22{
23 char str[BUFSIZ];
24 sprintf(str, "%s/%s", pszIOPath, "igmp_log.txt");
25 igmp_log = fopen(str, "w");
26}
27
28static void close_igmp_log()
29{
30 fclose(igmp_log);
31}
32
33void print_igmp_log(char* format, ...)
34{
35 va_list l;
36 va_start(l, format);
37 vfprintf(igmp_log, format, l);
38 fprintf(igmp_log, "\n");
39 fflush(igmp_log);
40}
41
42//IGMP Device
43void igmp_configure(NETSIM_ID d, void* xmlNode)
44{
45 ptrIGMP_VAR var = GET_IGMP_VAR(d);
46 ptrIGMP_HOST host;
47 ptrIGMP_ROUTER router;
48 if (!var)
49 {
50 var = calloc(1, sizeof* var);
51 SET_IGMP_VAR(d, var);
52 }
53
54 if (isHost(d))
55 {
56 var->devType = IP_HOST;
57 host = GET_IGMP_HOST(d);
58 if (!host)
59 {
60 host = (ptrIGMP_HOST)calloc(1, sizeof* host);
61 SET_IGMP_HOST(d, host);
62 }
63 }
64 else if (isRouter(d))
65 {
66 var->devType = IP_ROUTER;
67 router = GET_IGMP_ROUTER(d);
68 if (!router)
69 {
70 router = (ptrIGMP_ROUTER)calloc(1, sizeof* router);
71 SET_IGMP_ROUTER(d, router);
72 }
73 }
74 else
75 fnNetSimError("IGMP is only for either host or router");
76
77 getXmlVar(&var->RobustnessVar, ROBUSTNESS_VARIABLE, xmlNode, 1, _UINT, IGMP);
78 getXmlVar(&var->QueryInterval, QUERY_INTERVAL, xmlNode, 1, _UINT, IGMP);
79 getXmlVar(&var->lastMemQueryInterval, LAST_MEMBER_QUERY_INTERVAL, xmlNode, 1, _DOUBLE, IGMP);
80
81 if (isIPHOST(d))
82 {
83 getXmlVar(&var->UnsolicitedReportInterval, UNSOLICITED_REPORT_INTERVAL, xmlNode, 1, _DOUBLE, IGMP);
84 var->UnsolicitedReportInterval *= SECOND;
85 }
86
87 if (isIPRouter(d))
88 {
89 getXmlVar(&var->QueryResponseInterval, QUERY_RESPONSE_INTERVAL, xmlNode, 1, _UINT, IGMP);
90 }
91}
92
93static double get_subevent_delay(NETSIM_ID d,
94 IP_SUBEVENT sev,
95 NETSIM_IPAddress group)
96{
97 ptrIGMP_VAR igmp = GET_IGMP_VAR(d);
98 switch (sev)
99 {
100 case EVENT_IGMP_SendStartupQuery:
101 return igmp->StartupQueryInterval*0.1*SECOND;
102 case EVENT_IGMP_SendQuery:
103 return igmp->QueryInterval*0.1*SECOND;
104 case EVENT_IGMP_Unsolicited_report:
105 return igmp->UnsolicitedReportInterval*NETSIM_RAND_01();
106 case EVENT_IGMP_OtherQuerierPresentTimer:
107 return igmp->QueryPresentInterval*0.1*SECOND;
108 case EVENT_IGMP_DelayTimer:
109 {
110 ptrIGMP_HOST_DB db = host_get_multicast_db(d, group);
111 double t = db->maxResponseTime*0.1*SECOND*NETSIM_RAND_01();
112 db->delayTime = t;
113 return t;
114 }
115 case EVENT_IGMP_GroupMembershipTimer:
116 return igmp->GroupMembershipInterval*0.1*SECOND;
117 default:
118 fnNetSimError("Unknown subevnet %d\n", sev);
119 return 0;
120 }
121}
122
123void igmp_start_timer(NETSIM_ID d,
124 IP_SUBEVENT sev,
125 NETSIM_IPAddress addr,
126 double time)
127{
128 NetSim_EVENTDETAILS pevent;
129 memset(&pevent, 0, sizeof pevent);
130
131 pevent.dEventTime = time + get_subevent_delay(d, sev, addr);
132 pevent.nDeviceId = d;
133 pevent.nDeviceType = DEVICE_TYPE(d);
134 pevent.nEventType = TIMER_EVENT;
135 pevent.nProtocolId = NW_PROTOCOL_IPV4;
136 pevent.nSubEventType = sev;
137 pevent.szOtherDetails = addr;
138 fnpAddEvent(&pevent);
139}
140
141void igmp_init(NETSIM_ID d)
142{
143 if(!igmp_log)
144 init_igmp_log();
145
146 if (isIPRouter(d))
147 igmp_router_init(d);
148 else if (isIPHOST(d))
149 igmp_host_init(d);
150 else
151 fnNetSimError("Device %d is neither host nor router\n", d);
152
153 ptrIGMP_VAR var = GET_IGMP_VAR(d);
154
155 var->GroupMembershipInterval = var->RobustnessVar*
156 var->QueryInterval + var->QueryResponseInterval;
157
158 var->QueryPresentInterval = var->RobustnessVar*
159 var->QueryInterval + var->QueryResponseInterval / 2;
160
161 var->lastMemQueryCount = var->RobustnessVar;
162}
163
164void igmp_free(NETSIM_ID d)
165{
166 ptrIGMP_VAR v = GET_IGMP_VAR(d);
167 if (!v)
168 return; //IGMP is not configured
169
170 if (isIPHOST(d))
171 host_free(d);
172 else if (isIPRouter(d))
173 router_free(d);
174
175 free(v);
176 SET_IGMP_VAR(d, NULL);
177}