21static ptrIGMP_MSG get_IGMP_MSG(NetSim_PACKET* packet)
23 return (ptrIGMP_MSG)(packet->pstruNetworkData->Packet_NetworkProtocol);
26static void set_IGMP_MSG(NetSim_PACKET* packet, ptrIGMP_MSG msg)
28 packet->pstruNetworkData->Packet_NetworkProtocol = msg;
31static int get_ctrlpackettype_basedon_igmptype(IGMPMSG_TYPE type,
char* stype)
35 case IGMPMSG_LeaveGroup:
36 strcpy(stype,
"IGMP_LEAVE_GROUP");
37 return PACKET_IGMP_LEAVE;
39 case IGMPMSG_V2MembershipReport:
40 strcpy(stype,
"IGMP_V2_Membership_Report");
41 return PACKET_IGMP_REPORT;
43 case IGMPMSG_MembershipQuery:
44 strcpy(stype,
"IGMP_Membership_Query");
45 return PACKET_IGMP_QUERY;
48 fnNetSimError(
"Unknown igmp msg type %d\n", type);
53static ptrIGMP_MSG create_igmp_hdr(IGMPMSG_TYPE type,
55 NETSIM_IPAddress group)
57 ptrIGMP_MSG msg = (ptrIGMP_MSG)calloc(1,
sizeof* msg);
58 msg->GroupAddress = IP_COPY(group);
60 msg->MaxRespTime = maxRespTime;
65static void free_igmp_hdr(ptrIGMP_MSG msg)
70static ptrIGMP_MSG copy_igmp_hdr(ptrIGMP_MSG msg)
72 ptrIGMP_MSG ret = (ptrIGMP_MSG)calloc(1,
sizeof* msg);
73 memcpy(ret, msg,
sizeof* ret);
77void copy_igmp_packet(NetSim_PACKET* d, NetSim_PACKET* s)
79 set_IGMP_MSG(d, copy_igmp_hdr(get_IGMP_MSG(s)));
81void IGMP_FreePacket(NetSim_PACKET* packet)
83 free_igmp_hdr(packet->pstruNetworkData->Packet_NetworkProtocol);
84 packet->pstruNetworkData->Packet_NetworkProtocol = NULL;
85 packet->pstruNetworkData->IPProtocol = 0;
88static UINT8 make_resp_time(UINT T)
93static NetSim_PACKET* create_igmp_packet(NETSIM_ID src,
97 NETSIM_IPAddress group,
101 UINT8 RespTime = make_resp_time(maxRespTime);
102 ptrIGMP_MSG msg = create_igmp_hdr(type,
106 NetSim_PACKET* packet = fn_NetSim_Packet_CreatePacket(NETWORK_LAYER);
108 set_IGMP_MSG(packet, msg);
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;
128 packet->pstruNetworkData->szSourceIP = DEVICE_NWADDRESS(src, ifId);
129 packet->pstruNetworkData->szDestIP = IP_COPY(group);
130 packet->pstruNetworkData->IPProtocol = IPPROTOCOL_IGMP;
135static void send_igmp_packet(NETSIM_ID d,
137 NetSim_PACKET* packet)
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);
152void send_membership_report(NETSIM_ID d, NETSIM_IPAddress group)
154 NetSim_PACKET* packet = create_igmp_packet(d,
157 IGMPMSG_V2MembershipReport,
162 send_igmp_packet(d, pstruEventDetails->dEventTime, packet);
165static bool igmp_process_report(NetSim_PACKET* packet,
171 return host_process_report(packet, msg, d);
174 else if (isRouter(d))
176 return router_process_report(packet, msg, d);
181bool igmp_process_query(NetSim_PACKET* packet,
186 return router_process_query(packet, msg, d);
187 else if (isIPHOST(d))
188 return host_process_query(packet, msg, d);
190 fnNetSimError(
"Device %d is neither host nor router", d);
195void process_igmp_packet()
197 bool isContinue =
true;
198 NETSIM_ID d = pstruEventDetails->nDeviceId;
199 NetSim_PACKET* packet = pstruEventDetails->pPacket;
200 ptrIGMP_MSG msg = get_IGMP_MSG(packet);
202 ptrIGMP_VAR igmp = GET_IGMP_VAR(d);
206 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
207 pstruEventDetails->pPacket = NULL;
213 case IGMPMSG_MembershipQuery:
214 isContinue = igmp_process_query(packet, msg, d);
216 case IGMPMSG_V2MembershipReport:
217 isContinue = igmp_process_report(packet, msg, d);
220 fnNetSimError(
"Unknown IGMP packet %d in %s.\n",
228 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
229 pstruEventDetails->pPacket = NULL;
233void send_query_msg(NETSIM_ID d, NETSIM_IPAddress group,
double time)
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,
241 if (db->sentCount >= var->RobustnessVar)
244 if (db->state == RouterState_NonQuerier)
248 for (i = 0; i < DEVICE(d)->nNumOfInterface; i++)
250 if (!isBroadcastInterface(d, i + 1))
252 NetSim_PACKET* packet = create_igmp_packet(d,
255 IGMPMSG_MembershipQuery,
257 var->QueryResponseInterval,
259 send_igmp_packet(d, time, packet);
265 isStartup ? EVENT_IGMP_SendStartupQuery : EVENT_IGMP_SendQuery,