NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
IGMP_Msg.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
20
21static ptrIGMP_MSG get_IGMP_MSG(NetSim_PACKET* packet)
22{
23 return (ptrIGMP_MSG)(packet->pstruNetworkData->Packet_NetworkProtocol);
24}
25
26static void set_IGMP_MSG(NetSim_PACKET* packet, ptrIGMP_MSG msg)
27{
28 packet->pstruNetworkData->Packet_NetworkProtocol = msg;
29}
30
31static int get_ctrlpackettype_basedon_igmptype(IGMPMSG_TYPE type, char* stype)
32{
33 switch (type)
34 {
35 case IGMPMSG_LeaveGroup:
36 strcpy(stype, "IGMP_LEAVE_GROUP");
37 return PACKET_IGMP_LEAVE;
38
39 case IGMPMSG_V2MembershipReport:
40 strcpy(stype, "IGMP_V2_Membership_Report");
41 return PACKET_IGMP_REPORT;
42
43 case IGMPMSG_MembershipQuery:
44 strcpy(stype, "IGMP_Membership_Query");
45 return PACKET_IGMP_QUERY;
46
47 default:
48 fnNetSimError("Unknown igmp msg type %d\n", type);
49 return 0;
50 }
51}
52
53static ptrIGMP_MSG create_igmp_hdr(IGMPMSG_TYPE type,
54 UINT8 maxRespTime,
55 NETSIM_IPAddress group)
56{
57 ptrIGMP_MSG msg = (ptrIGMP_MSG)calloc(1, sizeof* msg);
58 msg->GroupAddress = IP_COPY(group);
59 msg->Type = type;
60 msg->MaxRespTime = maxRespTime;
61
62 return msg;
63}
64
65static void free_igmp_hdr(ptrIGMP_MSG msg)
66{
67 free(msg);
68}
69
70static ptrIGMP_MSG copy_igmp_hdr(ptrIGMP_MSG msg)
71{
72 ptrIGMP_MSG ret = (ptrIGMP_MSG)calloc(1, sizeof* msg);
73 memcpy(ret, msg, sizeof* ret);
74 return ret;
75}
76
77void copy_igmp_packet(NetSim_PACKET* d, NetSim_PACKET* s)
78{
79 set_IGMP_MSG(d, copy_igmp_hdr(get_IGMP_MSG(s)));
80}
81void IGMP_FreePacket(NetSim_PACKET* packet)
82{
83 free_igmp_hdr(packet->pstruNetworkData->Packet_NetworkProtocol);
84 packet->pstruNetworkData->Packet_NetworkProtocol = NULL;
85 packet->pstruNetworkData->IPProtocol = 0;
86}
87
88static UINT8 make_resp_time(UINT T)
89{
90 return (UINT8)(T);
91}
92
93static NetSim_PACKET* create_igmp_packet(NETSIM_ID src,
94 NETSIM_ID ifId,
95 NETSIM_ID dest,
96 IGMPMSG_TYPE type,
97 NETSIM_IPAddress group,
98 UINT maxRespTime,
99 UINT8 ttl)
100{
101 UINT8 RespTime = make_resp_time(maxRespTime);
102 ptrIGMP_MSG msg = create_igmp_hdr(type,
103 RespTime,
104 group);
105
106 NetSim_PACKET* packet = fn_NetSim_Packet_CreatePacket(NETWORK_LAYER);
107
108 set_IGMP_MSG(packet, msg);
109
110 packet->dEventTime = pstruEventDetails->dEventTime;
111 packet->nControlDataType = get_ctrlpackettype_basedon_igmptype(type, packet->szPacketType);
112 packet->nPacketPriority = Priority_Low;
113 packet->nPacketType = PacketType_Control;
114 packet->nQOS = QOS_BE;
115 packet->nReceiverId = 0;
116 packet->nSourceId = src;
117 packet->nTransmitterId = src;
118 add_dest_to_packet(packet, dest);
119 packet->pstruNetworkData->nTTL = ttl;
120 packet->pstruNetworkData->nNetworkProtocol = NW_PROTOCOL_IPV4;
121 packet->pstruNetworkData->dArrivalTime = pstruEventDetails->dEventTime;
122 packet->pstruNetworkData->dStartTime = pstruEventDetails->dEventTime;
123 packet->pstruNetworkData->dEndTime = pstruEventDetails->dEventTime;
124 packet->pstruNetworkData->dOverhead = IGMP_HDR_SIZE;
125 packet->pstruNetworkData->dPacketSize = packet->pstruNetworkData->dPayload +
126 packet->pstruNetworkData->dOverhead;
127
128 packet->pstruNetworkData->szSourceIP = DEVICE_NWADDRESS(src, ifId);
129 packet->pstruNetworkData->szDestIP = IP_COPY(group);
130 packet->pstruNetworkData->IPProtocol = IPPROTOCOL_IGMP;
131
132 return packet;
133}
134
135static void send_igmp_packet(NETSIM_ID d,
136 double time,
137 NetSim_PACKET* packet)
138{
139 NetSim_EVENTDETAILS pevent;
140 memset(&pevent, 0, sizeof pevent);
141 pevent.dEventTime = time;
142 pevent.dPacketSize = packet->pstruNetworkData->dPacketSize;
143 pevent.nDeviceId = d;
144 pevent.nDeviceType = DEVICE_TYPE(d);
145 pevent.nEventType = NETWORK_OUT_EVENT;
146 pevent.nPacketId = packet->nPacketId;
147 pevent.nProtocolId = NW_PROTOCOL_IPV4;
148 pevent.pPacket = packet;
149 fnpAddEvent(&pevent);
150}
151
152void send_membership_report(NETSIM_ID d, NETSIM_IPAddress group)
153{
154 NetSim_PACKET* packet = create_igmp_packet(d,
155 1,
156 0,
157 IGMPMSG_V2MembershipReport,
158 group,
159 0,
160 1);
161
162 send_igmp_packet(d, pstruEventDetails->dEventTime, packet);
163}
164
165static bool igmp_process_report(NetSim_PACKET* packet,
166 ptrIGMP_MSG msg,
167 NETSIM_ID d)
168{
169 if (isHost(d))
170 {
171 return host_process_report(packet, msg, d);
172 }
173
174 else if (isRouter(d))
175 {
176 return router_process_report(packet, msg, d);
177 }
178 return false;
179}
180
181bool igmp_process_query(NetSim_PACKET* packet,
182 ptrIGMP_MSG msg,
183 NETSIM_ID d)
184{
185 if (isIPRouter(d))
186 return router_process_query(packet, msg, d);
187 else if (isIPHOST(d))
188 return host_process_query(packet, msg, d);
189 else
190 fnNetSimError("Device %d is neither host nor router", d);
191
192 return true;
193}
194
195void process_igmp_packet()
196{
197 bool isContinue = true;
198 NETSIM_ID d = pstruEventDetails->nDeviceId;
199 NetSim_PACKET* packet = pstruEventDetails->pPacket;
200 ptrIGMP_MSG msg = get_IGMP_MSG(packet);
201
202 ptrIGMP_VAR igmp = GET_IGMP_VAR(d);
203 if (!igmp)
204 {
205 //IGMP is not configured
206 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
207 pstruEventDetails->pPacket = NULL;
208 return;
209 }
210
211 switch (msg->Type)
212 {
213 case IGMPMSG_MembershipQuery:
214 isContinue = igmp_process_query(packet, msg, d);
215 break;
216 case IGMPMSG_V2MembershipReport:
217 isContinue = igmp_process_report(packet, msg, d);
218 break;
219 default:
220 fnNetSimError("Unknown IGMP packet %d in %s.\n",
221 msg->Type,
222 __FUNCTION__);
223 break;
224 }
225
226 if (!isContinue)
227 {
228 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
229 pstruEventDetails->pPacket = NULL;
230 }
231}
232
233void send_query_msg(NETSIM_ID d, NETSIM_IPAddress group, double time)
234{
235 bool isStartup = true;
236 ptrIGMP_VAR var = GET_IGMP_VAR(d);
237 ptrIGMP_ROUTER router = GET_IGMP_ROUTER(d);
238 ptrIGMP_ROUTER_DB db = router_get_multicast_db(d,
239 group);
240
241 if (db->sentCount >= var->RobustnessVar)
242 isStartup = false;
243
244 if (db->state == RouterState_NonQuerier)
245 return;
246
247 NETSIM_ID i;
248 for (i = 0; i < DEVICE(d)->nNumOfInterface; i++)
249 {
250 if (!isBroadcastInterface(d, i + 1))
251 continue;
252 NetSim_PACKET* packet = create_igmp_packet(d,
253 i+1,
254 0,
255 IGMPMSG_MembershipQuery,
256 group,
257 var->QueryResponseInterval,
258 1);
259 send_igmp_packet(d, time, packet);
260 }
261
262 db->sentCount++;
263
264 igmp_start_timer(d,
265 isStartup ? EVENT_IGMP_SendStartupQuery : EVENT_IGMP_SendQuery,
266 group,
267 time);
268}