📄 igmp_main.cpp
字号:
timetick1 = tickGet ();
/*printf("Receive IGMP PKT!device_driver_free!\n"); */
free ((void *) IgmpPkt);
/*device_driver_free ((void *) IgmpPkt); */
IgmpPkt = NULL;
/*发送到消息队列 */
timetick2 = tickGet ();
ReceiveIgmpMsg.tick = tickGet ();
nReturnValue =
msgQSend (IGMPMsgQId, (char *) &ReceiveIgmpMsg, sizeof (IGMPMsg),
NO_WAIT, MSG_PRI_NORMAL);
if (nReturnValue == OK)
{
ulIGMPSendToQueueAll++;
}
semGive (semIgmpReceive);
timetick3 = tickGet ();
return (nReturnValue);
}
#ifdef __cplusplus
}
#endif
/***************************************************
函数名称:SendIgmpPkt
函数功能:发送IGMP包函数,根据需要组IGMP包,并发送。
输入参数:ucIgmpType IGMP包类型
unGroupAddress 组播组地址
usPort 数据包发送的目的端口
ucMaxRespTime 最大响应时间(查询包)
usSessionId PPPoE用户SessionId
返回值: 无
备注 : 修改了最终的发送函数aibin 2005-01-14
现暂时把所有包都设置成untaged aibin 2005-4-1
***************************************************/
void SendIgmpPkt (UCHAR ucIgmpType, UINT unGroupAddress, USHORT usPort,
UCHAR ucMaxRespTime)
{
UCHAR *IgmpPkt = (UCHAR *) malloc (68); /*aibin */
/*UCHAR *IgmpPkt = (UCHAR *) device_driver_malloc (); */
UINT unPktLength = 68; /*与3400上的兼容, 原为64。modied by aibin ; */
UINT unOutPVC;
USHORT OutVlanTag; /* = GetPortVlanTag (usPort) */
UINT DestinationIpAddress;
char gz_add_id = 255;
/*struct in_addr IpAddress; */
UCHAR DestinationMacAddress[6];
ipheader IpHeader;
ipheaderwithoption IpHeaderWithOption;
igmpheader IgmpHeader;
vlantag VlanTag;
GroupEntity *IgmpGroup;
int vid;
int i;
OutVlanTag = 0; /*所有包都设置成untag版本的包aibin */
char name[20];
char tag = 0;
if (IgmpPkt == NULL)
{
printf ("SendIgmpPkt:Malloc Fail\n");
return;
}
/*in snooping mode, no need send igmp packet by gsw, aibin 20080505 */
if (gIGMPMODE == MODE_SNOOPING)
{
free (IgmpPkt);
return;
}
memset (IgmpPkt, 0, unPktLength);
/*if (OutVlanTag > 4094) /*VLAN tag非法4095保留 */
/*{ */
/* OutVlanTag = 0; */
/*} */
switch (ucIgmpType)
{
case IGMPMembershipQuery:
if (usPort == 0) /*查询包不能发往Ethernet */
{
printf ("SendIgmpPkt ERROR!device_driver_free!\n");
free ((void *) IgmpPkt);
/*device_driver_free ((void *) IgmpPkt); */
IgmpPkt = NULL;
return;
}
if (!bEnableRouterModule)
{
printf ("IGMP Router Module is disable,do not send Query!\n");
free ((void *) IgmpPkt);
/*device_driver_free ((void *) IgmpPkt); */
IgmpPkt = NULL;
return;
}
if (!bQuerierFlag)
{
printf ("I am not a querier, do not send Query!\n");
free ((void *) IgmpPkt);
/*device_driver_free ((void *) IgmpPkt); */
IgmpPkt = NULL;
return;
}
if (unGroupAddress == 0) /*通用查询 */
{
DestinationIpAddress = 0xe0000001;
IgmpEtherMapIpMulticast (ntohl (DestinationIpAddress),
DestinationMacAddress);
memcpy (IgmpPkt, DestinationMacAddress, 6); /*目的Mac */
memcpy (IgmpPkt + 6, gEtherInfo.etherMac, 6); /*源Mac */
IpHeader.version = 4;
IpHeader.headerlength = 5;
IpHeader.tos = 0;
IpHeader.total_len = htons (0x001c);
srand (tickGet ());
IpHeader.id = (USHORT) rand ();
IpHeader.frag_off = 0;
IpHeader.ttl = 1;
IpHeader.protocol = 2;
IpHeader.checksum = 0;
IpHeader.saddr = htonl (gEtherInfo.ipAddr);
IpHeader.daddr = ntohl (DestinationIpAddress);
CaculateChecksum ((UCHAR *) & IpHeader, sizeof (ipheader), 10);
IgmpHeader.ucType = ucIgmpType;
IgmpHeader.ucMaxRespTime = usQueryResponseInterval * 10;
IgmpHeader.usChecksum = 0;
IgmpHeader.unGroupAddress = 0; /*通用查询组地址为零 */
CaculateChecksum ((UCHAR *) & IgmpHeader, sizeof (igmpheader), 2); /*计算校验和 */
OutVlanTag = global_vlan;
if (OutVlanTag == 0) /*没有VLAN */
{
if (usPortMapSessionId[usPort] == 0) /*无PPPoE封装 */
{
*(USHORT *) (IgmpPkt + 12) = ntohs (0x0800);
memcpy (IgmpPkt + 14, &IpHeader, sizeof (ipheader));
memcpy (IgmpPkt + 14 + sizeof (ipheader), &IgmpHeader,
sizeof (igmpheader));
}
else /*有PPPoE封装 */
{
*(USHORT *) (IgmpPkt + 12) = ntohs (0x8864);
*(USHORT *) (IgmpPkt + 14) = ntohs (0x1100);
*(USHORT *) (IgmpPkt + 16) =
ntohs (usPortMapSessionId[usPort]);
*(USHORT *) (IgmpPkt + 18) = ntohs (0x001e);
*(USHORT *) (IgmpPkt + 20) = ntohs (0x0021);
memcpy (IgmpPkt + 22, &IpHeader, sizeof (ipheader));
memcpy (IgmpPkt + 22 + sizeof (ipheader), &IgmpHeader,
sizeof (igmpheader));
}
}
else /*有VLAN */
{
if (usPortMapSessionId[usPort] == 0) /*无PPPoE封装 */
{
VlanTag.TagProtocolType = htons (0x8100);
VlanTag.VlanID = htons (OutVlanTag);
memcpy (IgmpPkt + 12, &VlanTag, sizeof (vlantag));
*(USHORT *) (IgmpPkt + 16) = ntohs (0x0800);
memcpy (IgmpPkt + 18, &IpHeader, sizeof (ipheader));
memcpy (IgmpPkt + 18 + sizeof (ipheader), &IgmpHeader,
sizeof (igmpheader));
}
else /*有PPPoE封装 */
{
VlanTag.TagProtocolType = htons (0x8100);
VlanTag.VlanID = htons (OutVlanTag);
memcpy (IgmpPkt + 12, &VlanTag, sizeof (vlantag));
*(USHORT *) (IgmpPkt + 16) = ntohs (0x8864);
*(USHORT *) (IgmpPkt + 18) = ntohs (0x1100);
*(USHORT *) (IgmpPkt + 20) =
ntohs (usPortMapSessionId[usPort]);
*(USHORT *) (IgmpPkt + 22) = ntohs (0x001e);
*(USHORT *) (IgmpPkt + 24) = ntohs (0x0021);
memcpy (IgmpPkt + 26, &IpHeader, sizeof (ipheader));
memcpy (IgmpPkt + 26 + sizeof (ipheader), &IgmpHeader,
sizeof (igmpheader));
}
}
}
else /*特定组查询 */
{
DestinationIpAddress = unGroupAddress;
IgmpEtherMapIpMulticast (ntohl (DestinationIpAddress),
DestinationMacAddress);
memcpy (IgmpPkt, DestinationMacAddress, 6); /*目的Mac */
memcpy (IgmpPkt + 6, gEtherInfo.etherMac, 6); /*源Mac */
IpHeader.version = 4;
IpHeader.headerlength = 5;
IpHeader.tos = 0;
IpHeader.total_len = htons (0x001c);
srand (tickGet ());
IpHeader.id = (USHORT) rand ();
IpHeader.frag_off = 0;
IpHeader.ttl = 1;
IpHeader.protocol = 2;
IpHeader.checksum = 0;
IpHeader.saddr = htonl (gEtherInfo.ipAddr);
IpHeader.daddr = ntohl (DestinationIpAddress);
CaculateChecksum ((UCHAR *) & IpHeader, sizeof (ipheader), 10); /*计算校验和 */
IgmpHeader.ucType = ucIgmpType;
IgmpHeader.ucMaxRespTime = usLastMemberQueryInterval * 10;
IgmpHeader.usChecksum = 0;
IgmpHeader.unGroupAddress = ntohl (DestinationIpAddress);
CaculateChecksum ((UCHAR *) & IgmpHeader, sizeof (igmpheader), 2); /*计算校验和 */
OutVlanTag = GetGroupVlan (unGroupAddress);
if (OutVlanTag == 0) /*没有VLAN */
{
if (usPortMapSessionId[usPort] == 0) /*无PPPoE封装 */
{
*(USHORT *) (IgmpPkt + 12) = ntohs (0x0800);
memcpy (IgmpPkt + 14, &IpHeader, sizeof (ipheader));
memcpy (IgmpPkt + 14 + sizeof (ipheader), &IgmpHeader,
sizeof (igmpheader));
}
else /*有PPPoE封装 */
{
*(USHORT *) (IgmpPkt + 12) = ntohs (0x8864);
*(USHORT *) (IgmpPkt + 14) = ntohs (0x1100);
*(USHORT *) (IgmpPkt + 16) =
ntohs (usPortMapSessionId[usPort]);
*(USHORT *) (IgmpPkt + 18) = ntohs (0x001e);
*(USHORT *) (IgmpPkt + 20) = ntohs (0x0021);
memcpy (IgmpPkt + 22, &IpHeader, sizeof (ipheader));
memcpy (IgmpPkt + 22 + sizeof (ipheader), &IgmpHeader,
sizeof (igmpheader));
}
}
else /*有VLAN */
{
if (usPortMapSessionId[usPort] == 0) /*无PPPoE封装 */
{
VlanTag.TagProtocolType = htons (0x8100);
VlanTag.VlanID = htons (OutVlanTag);
memcpy (IgmpPkt + 12, &VlanTag, sizeof (vlantag));
*(USHORT *) (IgmpPkt + 16) = ntohs (0x0800);
memcpy (IgmpPkt + 18, &IpHeader, sizeof (ipheader));
memcpy (IgmpPkt + 18 + sizeof (ipheader), &IgmpHeader,
sizeof (igmpheader));
}
else /*有PPPoE封装 */
{
VlanTag.TagProtocolType = htons (0x8100);
VlanTag.VlanID = htons (OutVlanTag);
memcpy (IgmpPkt + 12, &VlanTag, sizeof (vlantag));
*(USHORT *) (IgmpPkt + 16) = ntohs (0x8864);
*(USHORT *) (IgmpPkt + 18) = ntohs (0x1100);
*(USHORT *) (IgmpPkt + 20) =
ntohs (usPortMapSessionId[usPort]);
*(USHORT *) (IgmpPkt + 22) = ntohs (0x001e);
*(USHORT *) (IgmpPkt + 24) = ntohs (0x0021);
memcpy (IgmpPkt + 26, &IpHeader, sizeof (ipheader));
memcpy (IgmpPkt + 26 + sizeof (ipheader), &IgmpHeader,
sizeof (igmpheader));
}
}
}
break;
case IGMPV1MembershipReport:
case IGMPV2MembershipReport:
if (!bEnableHostModule)
{
printf ("SendIgmpPkt ERROR!device_driver_free!\n");
free ((void *) IgmpPkt);
/*device_driver_free ((void *) IgmpPkt); */
IgmpPkt = NULL;
return;
}
vid = router_vid; /*路由器口的vid ,mod by aibin */
DestinationIpAddress = unGroupAddress;
IgmpEtherMapIpMulticast (ntohl (DestinationIpAddress),
DestinationMacAddress);
memcpy (IgmpPkt, DestinationMacAddress, 6); /*目的Mac */
memcpy (IgmpPkt + 6, gEtherInfo.etherMac, 6); /*源Mac */
IpHeaderWithOption.version = 4;
IpHeaderWithOption.headerlength = 6;
IpHeaderWithOption.tos = 0;
IpHeaderWithOption.total_len = htons (0x0020);
srand (tickGet ());
IpHeaderWithOption.id = (USHORT) rand ();
IpHeaderWithOption.frag_off = 0;
IpHeaderWithOption.ttl = 1;
IpHeaderWithOption.protocol = 2;
IpHeaderWithOption.checksum = 0;
IpHeaderWithOption.saddr = htonl (gEtherInfo.ipAddr);
IpHeaderWithOption.daddr = ntohl (DestinationIpAddress);
IpHeaderWithOption.option = htonl (0x94040000);
CaculateChecksum ((UCHAR *) & IpHeaderWithOption,
sizeof (IpHeaderWithOption), 10);
IgmpHeader.ucType = ucIgmpType;
IgmpHeader.ucMaxRespTime = 0;
IgmpHeader.usChecksum = 0;
IgmpHeader.unGroupAddress = htonl (unGroupAddress);
CaculateChecksum ((UCHAR *) & IgmpHeader, sizeof (igmpheader), 2);
IgmpGroup = FindIgmpGroupByAddress (unGroupAddress);
OutVlanTag = IgmpGroup->OutVlanTag; /*20050803aibin */
OutVlanTag = GetGroupVlan (unGroupAddress); /*20061031 aibin */
if (uplink_vlan_enable)
OutVlanTag = GetGroupUplinkVlan (unGroupAddress); /*aibin 20080610 */
if (gz_ctc_test) /*在ctc测试某模式中,上行协议报文需要打指定vlan aibin 20080119 */
{
for (i = 0; i < 10; i++)
{
if (GZ_add[i].groupaddress == unGroupAddress)
{
OutVlanTag = GZ_add[i].outvlan;
gz_add_id = i;
break;
}
}
}
if (OutVlanTag == 0)
{
*(USHORT *) (IgmpPkt + 12) = ntohs (0x0800);
memcpy (IgmpPkt + 14, &IpHeaderWithOption,
sizeof (IpHeaderWithOption));
memcpy (IgmpPkt + 14 + sizeof (IpHeaderWithOption), &IgmpHeader,
sizeof (igmpheader));
}
else
{
VlanTag.TagProtocolType = htons (0x8100);
VlanTag.VlanID = htons (OutVlanTag);
memcpy (IgmpPkt + 12, &VlanTag, sizeof (vlantag));
*(USHORT *) (IgmpPkt + 16) = ntohs (0x0800);
memcpy (IgmpPkt + 18, &IpHeaderWithOption,
sizeof (IpHeaderWithOption));
memcpy (IgmpPkt + 18 + sizeof (IpHeaderWithOption), &IgmpHeader,
sizeof (igmpheader));
if (unGroupAddress == 0xed010203)
{
VlanTag.TagProtocolType = htons (0x8100);
VlanTag.VlanID = htons (OutVlanTag);
memcpy (IgmpPkt + 12, &VlanTag, sizeof (vlantag));
memcpy (IgmpPkt + 16, &VlanTag, sizeof (vlantag));
*(USHORT *) (IgmpPkt + 20) = ntohs (0x0800);
memcpy (IgmpPkt + 22, &IpHeaderWithOption,
sizeof (IpHeaderWithOption));
memcpy (IgmpPkt + 22 + sizeof (IpHeaderWithOption),
&IgmpHeader, sizeof (igmpheader));
}
}
break;
case IGMPLeaveGroup:
if (!bEnableHostModule)
{
printf ("SendIgmpPkt ERROR!device_driver_free!\n");
free ((void *) IgmpPkt);
/*device_driver_free ((void *) IgmpPkt); */
IgmpPkt = NULL;
return;
}
DestinationIpAddress = 0xe0000002;
/*IpAddress.s_addr = ntohl (DestinationIpAddress); */
IgmpEtherMapIpMulticast (ntohl (DestinationIpAddress),
DestinationMacAddress);
memcpy (IgmpPkt, DestinationMacAddress, 6); /*目的Mac */
memcpy (IgmpPkt + 6, gEtherInfo.etherMac, 6); /*源Mac */
IpHeaderWithOption.version = 4;
IpHeaderWithOption.headerlength = 6;
IpHeaderWithOption.tos = 0;
IpHeaderWithOption.total_len = htons (0x0020);
srand (tickGet ());
IpHeaderWithOption.id = (USHORT) rand ();
IpHeaderWithOption.frag_off = 0;
IpHeaderWithOption.ttl = 1;
IpHeaderWithOption.protocol = 2;
IpHeaderWithOption.checksum = 0;
IpHeaderWithOption.saddr = htonl (gEtherInfo.ipAddr);
IpHeaderWithOption.daddr = ntohl (DestinationIpAddress);
IpHeaderWithOption.option = htonl (0x94040000);
CaculateChecksum ((UCHAR *) & IpHeaderWithOption,
sizeof (IpHeaderWithOption), 10);
IgmpHeader.ucType = ucIgmpType;
IgmpHeader.ucMaxRespTime = 0;
IgmpHeader.usChecksum = 0;
IgmpHeader.unGroupAddress = htonl (unGroupAddress);
CaculateChecksum ((UCHAR *) & IgmpHeader, sizeof (igmpheader), 2);
/*IgmpHeader.usChecksum = nos_in_cksum ((UCHAR *) & IgmpHeader, 8); */
IgmpGroup = FindIgmpGroupByAddress (unGroupAddress);
OutVlanTag = IgmpGroup->OutVlanTag; /*20050803aibin */
OutVlanTag = GetGroupVlan (unGroupAddress); /*20061031 aibin */
if (uplink_vlan_enable)
OutVlanTag = GetGroupUplinkVlan (unGroupAddress);; /*aibin 20080610 */
if (gz_ctc_test) /*在ctc测试某模式中,上行协议报文需要打指定vlan aibin 20080119 */
{
for (i = 0; i < 10; i++)
{
if (GZ_add[i].groupaddress == unGroupAddress)
{
OutVlanTag = GZ_add[i].outvlan;
gz_add_id = i;
break;
}
}
}
if (OutVlanTag == 0)
{
*(USHORT *) (IgmpPkt + 12) = ntohs (0x0800);
memcpy (IgmpPkt + 14, &IpHeaderWithOption,
sizeof (IpHeaderWithOption));
memcpy (IgmpPkt + 14 + sizeof (IpHeaderWithOption), &IgmpHeader,
sizeof (igmpheader));
}
else
{
VlanTag.TagProtocolType = htons (0x8100);
VlanTag.VlanID = htons (OutVlanTag);
memcpy (IgmpPkt + 12, &VlanTag, sizeof (vlantag));
*(USHORT *) (IgmpPkt + 16) = ntohs (0x0800);
memcpy (IgmpPkt + 18, &IpHeaderWithOption,
sizeof (IpHeaderWithOption));
memcpy (IgmpPkt + 18 + sizeof (IpHeaderWithOption), &IgmpHeader,
sizeof (igmpheader));
if (unGroupAddress == 0xed010203)
{
VlanTag.TagProtocolType = htons (0x8100);
VlanTag.VlanID = htons (OutVlanTag);
memcpy (IgmpPkt + 12, &VlanTag, sizeof (vlantag));
memcpy (IgmpPkt + 16, &VlanTag, sizeof (vlantag));
*(USHORT *) (IgmpPkt + 20) = ntohs (0x0800);
memcpy (IgmpPkt + 22, &IpHeaderWithOption,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -