📄 igmp_main.cpp
字号:
usCurrentMsgQLength = 0;
usRealMaxMsgQLength = 0;
usCurrentUser = 0; /*当前组播用户数 */
usCurrentGroup = 0; /*当前频道数 */
usCurrentTimer = 0; /*当前定时器数 */
unGeneralQueryTimerCount = 0;
ucCurrentStartupQueryCount = 0;
ulCustomMemoryUsed = 0; /*当前内存块数 */
bEnableInstantLeave = TRUE;
bIgmpDebug = FALSE;
pGroupEntityList = NULL;
pPreJoinList = NULL;
usCurrentPreJoinNode = 0;
/*printf("%d Bytes per igmp group.\n",sizeof (GroupEntity)); */
/*if (CreateMemory ((void *) IgmpGroupEntity, sizeof (GroupEntity),(usMaxGroup+1)) == NULL)
{
printf ("IGMP Create Group Memory FAIL!\n");
return FALSE;
}
else
{
printf("%d IgmpGroups Use %d KBytes Memory.\n",usMaxGroup,sizeof (GroupEntity)*(usMaxGroup+1)/(1024));
}
if (CreateMemory ((void *) IgmpTimerEntity, sizeof (TimerEntity),
usMaxTimer) == FALSE)
{
printf ("IGMP Create Timer Memory FAIL!\n");
return FALSE;
}
else
{
printf("%d IgmpTimers Use %d Bytes Memory.\n",usMaxTimer,sizeof (TimerEntity)*usMaxTimer);
} */
tIgmpMembershipTimer = 0;
StartIgmpMembershipTimer ();
if (tIgmpMembershipTimer != 0)
{
/*printf("IGMP Memership Timer OK!\n"); */
}
if (bQuerierFlag)
{
RouterSendGenernalQueryToAllPort ();
StartStartupQueryTimer ();
}
return TRUE;
}
/***************************************************
函数名称:ProcessReceiveIgmpPkt
函数功能:将接收到的数据包进行分类,交给其他模块处理。
输入参数:ReceiveIgmpMsg 接收到的数据包
返回值: 无
***************************************************/
void ProcessReceiveIgmpPkt (IGMPMsg ReceiveIgmpMsg)
{
if (slot_module[ReceiveIgmpMsg.usPort] == HOST_MODULE_PORT) /*来自上联口侧 */
{
ulEtherReceiveIgmpPkt++;
if (!bEnableHostModule) /*Host功能被关闭 */
{
return;
}
switch (ReceiveIgmpMsg.ucIGMPType)
{
case IGMPMembershipQuery:
if (ReceiveIgmpMsg.ucMaxResponseTime == 0)
{
ulEtherReceiveIgmpV1Query++;
if (!bHostEnableIGMPV1) /*不兼容V1 */
{
return;
}
HostProcessIgmpV1Query (ReceiveIgmpMsg);
}
else
{
ulEtherReceiveIgmpV2Query++;
HostProcessIgmpV2Query (ReceiveIgmpMsg);
}
break;
case IGMPV1MembershipReport:
ulEtherReceiveIgmpV1MembershipReport++;
if (!bHostEnableIGMPV1) /*不兼容V1 */
{
return;
}
HostProcessIgmpReport (ReceiveIgmpMsg);
break;
case IGMPV2MembershipReport:
ulEtherReceiveIgmpV2MembershipReport++;
HostProcessIgmpReport (ReceiveIgmpMsg);
break;
case IGMPV3MembershipReport:
ulEtherReceiveIgmpV3MembershipReport++;
HostProcessIgmpReport (ReceiveIgmpMsg);
break;
case IGMPLeaveGroup:
ulEtherReceiveIgmpLeaveGroup++;
break;
default:
ulEtherReceiveIgmpUnknown++;
break;
}
}
else /*来自router模块测 */
{
if (contest == TRUE)
{
if (ReceiveIgmpMsg.ucIGMPType == IGMPV2MembershipReport)
processtest (ReceiveIgmpMsg.usPort, 1, 1, 1, 0,
ReceiveIgmpMsg.unGroupAddress);
else if (ReceiveIgmpMsg.ucIGMPType == IGMPLeaveGroup)
processtest (ReceiveIgmpMsg.usPort, 1, 1, 0, 0,
ReceiveIgmpMsg.unGroupAddress);
}
ulATMReceiveIgmpPkt++;
if (!bEnableRouterModule) /*Router功能关闭 */
{
ulATMReceiveIgmpBad++;
if (bIgmpDebug)
{
printf ("Router is disable!Drop\n");
}
return;
}
if (!bEnablePortIGMP[ReceiveIgmpMsg.usPort]) /*该端口禁止组播功能 */
{
ulATMReceiveIgmpBad++;
if (bIgmpDebug)
{
printf ("Port %d igmp is disable igmp!Drop\n",
ReceiveIgmpMsg.usPort);
}
return;
}
usPortMapSessionId[ReceiveIgmpMsg.usPort] = ReceiveIgmpMsg.usSessionId; /*保存SessionId */
switch (ReceiveIgmpMsg.ucIGMPType)
{
case IGMPV2MembershipReport:
ulATMReceiveIgmpV2MembershipReport++;
semTake (semIgmpDelete, WAIT_FOREVER);
RouterProcessIgmpV2Report (ReceiveIgmpMsg);
semGive (semIgmpDelete);
break;
case IGMPV3MembershipReport:
ulATMReceiveIgmpV3MembershipReport++;
semTake (semIgmpDelete, WAIT_FOREVER);
RouterProcessIgmpV2Report (ReceiveIgmpMsg);
semGive (semIgmpDelete);
break;
case IGMPLeaveGroup:
ulATMReceiveIgmpLeaveGroup++;
semTake (semIgmpDelete, WAIT_FOREVER);
RouterProcessIgmpLeave (ReceiveIgmpMsg);
semGive (semIgmpDelete);
break;
case IGMPMembershipQuery:
if (ReceiveIgmpMsg.ucMaxResponseTime == 0)
{
ulATMReceiveIgmpV1Query++;
if (!bRouterEnableIGMPV1) /*不兼容V1 */
{
return;
}
RouterProcessIgmpV1Query (ReceiveIgmpMsg);
}
else
{
ulATMReceiveIgmpV2Query++;
RouterProcessIgmpV2Query (ReceiveIgmpMsg);
}
break;
case IGMPV1MembershipReport:
ulATMReceiveIgmpV1MembershipReport++;
if (!bRouterEnableIGMPV1) /*不兼容V1 */
{
return;
}
semTake (semIgmpDelete, WAIT_FOREVER);
RouterProcessIgmpV1Report (ReceiveIgmpMsg);
semGive (semIgmpDelete);
break;
default:
ulATMReceiveIgmpUnknown++;
break;
}
}
}
#ifdef __cplusplus
extern "C"
{
#endif
int send_igmp_packet_snooping (short srcPort, char *IgmpPkt, short usLength,
short vlanid)
{
char origin[70];
char *p, *sendPkt;
char type, iph_len;
int i;
short pvid = 0;
/*get igmp type */
iph_len = (*(IgmpPkt + 14)) & 0xf;
type = *(IgmpPkt + 14 + 4 * iph_len);
/*rebuild origin packet, if vlanid=4088, we think it's a untag packet, but there should be a bug hiding here: when
the origin packet with tag 4088, it can transmitte to cpu, we can't know whether it has tag and so on */
memset (origin, 0, sizeof (origin));
pvid = driver_get_pvid (srcPort);
if (vlanid != pvid)
{
memcpy (origin, IgmpPkt, 12);
*(short *) (origin + 12) = htonl (0x8100);
*(short *) (origin + 14) = htonl (vlanid);
memcpy (origin + 16, IgmpPkt + 12, usLength - 12);
sendPkt = origin;
}
else
{
sendPkt = IgmpPkt;
}
if (type == IGMPMembershipQuery)
{
/*错误的接收端口 */
if (slot_module[srcPort] == ROUTER_MODULE_PORT)
return -1;
/*发往下行方向 */
for (i = 1; i <= MAX_UPLINK_PORT; i++)
{
if (slot_module[i] == ROUTER_MODULE_PORT)
{
br_send_MSC (i, (u_char *) sendPkt, 70, 1);
}
}
}
/*往上联口发送的报文,加入 */
else if (type == IGMPV2MembershipReport || type == IGMPLeaveGroup ||
type == IGMPV1MembershipReport || type == IGMPV3MembershipReport)
{
/*错误的接收端口 */
if (slot_module[srcPort] == HOST_MODULE_PORT)
return -1;
for (i = MIN_UPLINK_PORT; i <= MAX_UPLINK_PORT; i++)
{
if (slot_module[i] == HOST_MODULE_PORT)
{
br_send_MSC (i, (u_char *) sendPkt, 70, 1);
}
}
}
else
{
return -1;
}
if (bIgmpDebug)
{
printf ("\n\rsend IGMP packet type:%d ", type);
typePkt (sendPkt, 68);
}
return 0;
}
int debug_igmp = 0;
/***************************************************
函数名称:IgmpReceive_new
函数功能:IGMP Proxy对外接口函数,负责将IGMP包送入消息队列
输入参数:usPort 接收数据包的源端口号
IgmpPkt 指向数据包的指针
usLength 数据包的长度
返回值: 0 表示成功
-1 表示失败
备注: 将输入参数unPVC改为unPort ,这样可以去掉与pvc的转换过程 aibin 2005-01-14
***************************************************/
int IgmpReceive (USHORT usPort, char *IgmpRecPkt, USHORT usLength,
short vlanid)
{
IGMPMsg ReceiveIgmpMsg;
ipheader *IpHeaderInPkt;
igmpheader *IgmpHeaderInPkt;
USHORT IpHeaderLength;
UINT groupaddress;
/*UINT DestinationAddressInPkt; */
UCHAR IpProtocolInPkt;
UINT MsgNum;
int nReturnValue;
UCHAR *user; /*线卡上的用户端口aibin 2005-3-24 */
USHORT usSessionId;
char *p;
char *p1;
int *pp;
int i;
USHORT PPPoEFlag = 0;
USHORT IGMPV3Flag = 0;
/*USHORT usPort = TransformPVCToPort (unPVC); modified by aibin 2005-01-14 */
char IgmpPkt[200];
/*edit by aibin 20080723 */
memset (IgmpPkt, 0, sizeof (IgmpPkt));
memcpy (IgmpPkt, IgmpRecPkt, usLength);
if (debug_igmp)
return 0;
if (bIgmpDebug)
{
printf ("\n\rreceive IGMP from Slot %d, vlan %d", usPort, vlanid);
typePkt (IgmpPkt, usLength);
}
/*协议报文来自自己发出的,丢弃 */
if (memcmp (IgmpPkt + 6, (char *) gEtherInfo.etherMac, 6) == 0)
{
if (bIgmpDebug)
{
printf ("Error! Igmp Packet comes from myself!\r\n");
}
/*free ((void *) IgmpPkt);
/*device_driver_free ((void *) IgmpPkt);
IgmpPkt = NULL; */
return ERROR;
}
if (gIGMPMODE == MODE_SNOOPING)
{
send_igmp_packet_snooping (usPort, IgmpPkt, usLength, vlanid);
}
/*
if (htonl (*((ULONG *) (IgmpPkt + 26))) == gEtherInfo.ipAddr)
{
return ERROR;
}
*/
timetick1 = tickGet ();
if (*(IgmpPkt + 38) == 0x16)
{
timeget[groupid].tick1 = tickGet ();
}
ulIGMPReceivePktAll++;
/***********************************************************************************/
#if 1
if (turbo)
{
groupaddress = htonl (*((ULONG *) (IgmpPkt + 42)));
if (*(IgmpPkt + 38) == 0x16)
{
ulATMReceiveIgmpV2MembershipReport++;
for (i = 0; i < MaxGroup; i++)
{
if (add[i].groupaddress == groupaddress)
{
if (add[i].slot[usPort])
{
return OK;
}
else
{
add[i].slot[usPort] = 1;
add[i].count++;
AddPortToGroup (groupaddress, usPort);
timeget[groupid].tick4 = tickGet ();
groupid++;
return OK;
}
}
}
//printf("Rx Join\n");
if (usCurrentGroup >= MaxGroup)
return ERROR;
usCurrentGroup++;
AddGroup (groupaddress);
timeget[groupid].tick2 = tickGet ();
AddPortToGroup (groupaddress, usPort);
SendIgmpPkt (IGMPV2MembershipReport, groupaddress, 0, 0);
/*uESend((UINT *) IgmpPkt, usLength, 0, 0); */
timeget[groupid].tick3 = tickGet ();
timeget[groupid].groupaddress = groupaddress;
i = 0;
while (i < MaxGroup)
{
if (!add[i].groupaddress)
{
add[i].groupaddress = groupaddress;
add[i].count++;
add[i].slot[usPort] = 1;
timeget[groupid].tick4 = tickGet ();
groupid++;
return OK;
}
i++;
}
}
else if (*(IgmpPkt + 38) == 0x17)
{
ulATMReceiveIgmpLeaveGroup++;
for (i = 0; i < MaxGroup; i++)
{
if (add[i].groupaddress == groupaddress)
{
if (add[i].slot[usPort])
{
DelPortFromGroup1 (groupaddress, usPort);
add[i].slot[usPort] = 0;
add[i].count--;
if (!add[i].count)
{
DelGroup (groupaddress);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -