NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
IGMP_Host.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 ptrIGMP_HOST_DB find_or_alloc_multicast_db_host(NETSIM_ID d, NETSIM_IPAddress group)
21{
22 ptrIGMP_HOST_DB r = GET_IGMP_HOST(d)->database;
23
24 while (r)
25 {
26 if (!IP_COMPARE(r->group, group))
27 return r;
28 r = LIST_NEXT(r);
29 }
30
31 r = (ptrIGMP_HOST_DB)IGMP_HOST_DB_ALLOC();
32 r->group = IP_COPY(group);
33 r->state = HostState_IdleMember;
34
35 IGMP_HOST_DB_ADD(d, r);
36
37 return r;
38}
39
40static void host_join_multicast_group(NETSIM_ID d, NETSIM_IPAddress group)
41{
42 find_or_alloc_multicast_db_host(d, group);
43}
44
45ptrIGMP_HOST_DB host_get_multicast_db(NETSIM_ID d, NETSIM_IPAddress addr)
46{
47 ptrIGMP_HOST_DB r = GET_IGMP_HOST(d)->database;
48
49 while (r)
50 {
51 if (!IP_COMPARE(r->group, addr))
52 return r;
53 r = LIST_NEXT(r);
54 }
55 return NULL;
56}
57
58void igmp_host_init(NETSIM_ID d)
59{
60 ptrIGMP_HOST host = GET_IGMP_HOST(d);
61
62 print_igmp_log("\nHost %d, Time 0: joining multicast group %s.",
63 d,
64 "224.0.0.1");
65
66 host_join_multicast_group(d, STR_TO_IP4("224.0.0.1"));
67}
68
69IP_PROTOCOL_ACTION host_is_ip_present_in_db(NETSIM_ID d, NETSIM_IPAddress ip, NetSim_PACKET* packet)
70{
71 IP_DEVVAR* dip = GET_IP_DEVVAR(d);
72 ptrIGMP_HOST_DB db = dip->isIGMPConfigured ? GET_IGMP_HOST(d)->database : NULL;
73 while (db)
74 {
75 if (!IP_COMPARE(db->group, ip))
76 return ACTION_MOVEUP;
77 db = LIST_NEXT(db);
78 }
79 return ACTION_DROP;
80}
81
82bool host_process_query(NetSim_PACKET* packet,
83 ptrIGMP_MSG msg,
84 NETSIM_ID d)
85{
86 bool isTimerReqd = false;
87 ptrIGMP_HOST_DB db = host_get_multicast_db(d, msg->GroupAddress);
88
89 print_igmp_log("\nHost %d, Time %0.0lf: Query received for group address %s.",
90 d,
91 pstruEventDetails->dEventTime,
92 msg->GroupAddress->str_ip);
93
94 if (!db->isReportreqd ||
95 pstruEventDetails->dEventTime -
96 db->queryRecvTime -
97 db->delayTime >=
98 msg->MaxRespTime*0.1*SECOND)
99 isTimerReqd = true;
100
101 db->maxResponseTime = msg->MaxRespTime;
102 db->queryRecvTime = pstruEventDetails->dEventTime;
103
104 if (isTimerReqd)
105 {
106 print_igmp_log("Starting Delay timer.");
107 igmp_start_timer(d,
108 EVENT_IGMP_DelayTimer,
109 msg->GroupAddress,
110 pstruEventDetails->dEventTime);
111 db->isReportreqd = true;
112 print_igmp_log("Changing host state to delaying member");
113 db->state = HostState_DelayingMember;
114 }
115
116 return false;
117}
118
119void host_send_report()
120{
121 NETSIM_IPAddress g = pstruEventDetails->szOtherDetails;
122 ptrIGMP_HOST_DB db = host_get_multicast_db(pstruEventDetails->nDeviceId,
123 g);
124
125 if (db->isReportreqd)
126 {
127 print_igmp_log("\nHost %d, Time %0.0lf: Sending report for group address %s.",
128 pstruEventDetails->nDeviceId,
129 pstruEventDetails->dEventTime,
130 g->str_ip);
131
132 send_membership_report(pstruEventDetails->nDeviceId,
133 g);
134 db->isReportreqd = false;
135 print_igmp_log("Changing host state to idle member");
136 db->state = HostState_IdleMember;
137 }
138}
139
140bool host_process_report(NetSim_PACKET* packet,
141 ptrIGMP_MSG msg,
142 NETSIM_ID d)
143{
144 ptrIGMP_HOST_DB db = host_get_multicast_db(d, msg->GroupAddress);
145 if (db)
146 {
147 print_igmp_log("\nHost %d, Time %0.0lf: report received for group address %s.",
148 d,
149 pstruEventDetails->dEventTime,
150 msg->GroupAddress->str_ip);
151 print_igmp_log("Report is not required.");
152 db->isReportreqd = false;
153 print_igmp_log("Changing host state to Idle member");
154 db->state = HostState_IdleMember;
155 }
156 return false;
157}
158
159void igmp_host_join_group(NETSIM_ID d, NETSIM_IPAddress group)
160{
161 if (!isHost(d))
162 fnNetSimError("%s is called for Non-Host device %d.\n", __FUNCTION__, d);
163
164 print_igmp_log("\nHost %d, Time %0.0lf: Joining multicast group %s.",
165 d,
166 pstruEventDetails->dEventTime,
167 group->str_ip);
168 print_igmp_log("Sending membership report.");
169
170 ptrIGMP_HOST_DB db = find_or_alloc_multicast_db_host(d, group);
171
172 send_membership_report(d, group);
173 db->reportSentCount++;
174 print_igmp_log("Changing host state to delaying member");
175 db->state = HostState_DelayingMember;
176 print_igmp_log("Starting Unsolicited report timer");
177 igmp_start_timer(d,
178 EVENT_IGMP_Unsolicited_report,
179 group,
180 pstruEventDetails->dEventTime);
181}
182
183void host_handle_unsolicited_report_timer()
184{
185 NETSIM_ID d = pstruEventDetails->nDeviceId;
186 NETSIM_IPAddress group = pstruEventDetails->szOtherDetails;
187
188 ptrIGMP_HOST_DB db = find_or_alloc_multicast_db_host(d, group);
189
190 if (db->reportSentCount < 2 && db->isReportreqd)
191 {
192 print_igmp_log("\nHost %d, Time %0.0lf: Unsolicited report timer triggered. Sending membership report.");
193 send_membership_report(d, group);
194 db->reportSentCount++;
195 print_igmp_log("Changing host state to delaying member");
196 db->state = HostState_DelayingMember;
197 print_igmp_log("Starting Unsolicited report timer");
198 igmp_start_timer(d,
199 EVENT_IGMP_Unsolicited_report,
200 group,
201 pstruEventDetails->dEventTime);
202 }
203}
204
205void host_free(NETSIM_ID d)
206{
207 ptrIGMP_HOST h = GET_IGMP_HOST(d);
208 ptrIGMP_HOST_DB db = h->database;
209 while (db)
210 {
211 LIST_FREE(&db, db);
212 }
213 free(h);
214 SET_IGMP_HOST(d, NULL);
215}