📄 igmp_cli.c
字号:
#include "igmpcon.h"
#define OK 0
/*
#define MAXPortNum2 32
#ifdef _AN2200_06_
#define usMaxPort 12
#define UPLINKSLOT 5
#else
#define usMaxPort 24
#define UPLINKSLOT 29
#endif
*/
extern BOOL igmpageflag;
void free_grouplist(void)
{
GroupEntity *ptemp;
SearchNode *ps;
semTake(semIgmpDelete, 10);
if (NULL == pGroupEntityList)
{
semGive(semIgmpDelete);
return;
}
while (pGroupEntityList)
{
ptemp = pGroupEntityList;
ps = ptemp->pNode;
DelGroup(ptemp->unGroupAddress);
pGroupEntityList = pGroupEntityList->pNext;
while (ptemp->pNode)
{
ps = ptemp->pNode;
ptemp->pNode = ptemp->pNode->pNext;
free (ps);
ps = NULL;
ps->pNext = NULL;
}
free (ptemp);
ptemp = NULL;
}
semGive(semIgmpDelete);
usCurrentGroup = 0;
return;
}
extern SEM_ID semIgmpTimeOut;
void stop_igmp(void)
{
/*StopGeneralQueryTimer();
StopStartupQueryTimer();
StopOtherQuerierPresentTimer(); */
StopV1RouterPresentTimer();
StopIgmpMembershipTimer();
taskDelete(nIGMPTaskId);
nIGMPTaskId = 0;
msgQDelete(IGMPMsgQId);
semTake(semIgmpDelete,WAIT_FOREVER);
/*free_authlist();
free_previewlist();*/
free_grouplist();
semGive(semIgmpDelete);
semDelete(semIgmpDelete);
semDelete(semIgmpReceive);
semDelete(semIgmpTimeOut);
semDelete (semPreJoin);
/*关闭igmp snooping */
driver_igmpdisable ();
#ifdef _AN5116_06A_
driver_dtag_igmpdisable();
#endif
/* IS_Stop ();*/
return;
}
PreJoinNode *IfPreJoinNodeExist (UINT unGroupAddress)
{
PreJoinNode *PreJoinNodeTemp;
UINT unReturnCode = 0;
if (pPreJoinList == NULL)
return NULL;
PreJoinNodeTemp = pPreJoinList;
while (PreJoinNodeTemp)
{
if (PreJoinNodeTemp->unGroupAddress == unGroupAddress)
return PreJoinNodeTemp;
else
PreJoinNodeTemp = PreJoinNodeTemp->pNext;
}
return NULL;
}
int AddPreJoinNode (UINT unGroupAddress)
{
PreJoinNode *PreJoinNodeTemp;
semTake (semPreJoin, WAIT_FOREVER);
if ((IfPreJoinNodeExist (unGroupAddress) == NULL)
&& (usCurrentPreJoinNode < usMaxPreJoin))
{
PreJoinNodeTemp = (PreJoinNode *) malloc (sizeof (PreJoinNode));
if (PreJoinNodeTemp == NULL)
{
semGive (semPreJoin);
return ERROR;
}
PreJoinNodeTemp->unGroupAddress = unGroupAddress;
PreJoinNodeTemp->usCount = 0;
PreJoinNodeTemp->pNext = pPreJoinList;
pPreJoinList = PreJoinNodeTemp;
usCurrentPreJoinNode++;
SpecificGroupSendV2Report (unGroupAddress);
}
else
{
printf("Group already exist or reach the maximum prejoin groups.\r\n");
semGive (semPreJoin);
return ERROR;
}
semGive (semPreJoin);
return OK;
}
void DelPreJoinNode (UINT unGroupAddress)
{
PreJoinNode *PreJoinNodeTemp1;
PreJoinNode *PreJoinNodeTemp2;
if (IfPreJoinNodeExist (unGroupAddress) == NULL)
return;
semTake (semPreJoin, WAIT_FOREVER);
PreJoinNodeTemp1 = pPreJoinList;
if (PreJoinNodeTemp1->unGroupAddress == unGroupAddress)
{
pPreJoinList = PreJoinNodeTemp1->pNext;
PreJoinNodeTemp1->unGroupAddress = 0;
PreJoinNodeTemp1->usCount = 0;
PreJoinNodeTemp1->pNext = NULL;
free ((void *) PreJoinNodeTemp1);
usCurrentPreJoinNode--;
semGive (semPreJoin);
return;
}
PreJoinNodeTemp2 = PreJoinNodeTemp1->pNext;
while (PreJoinNodeTemp2)
{
if (PreJoinNodeTemp2->unGroupAddress == unGroupAddress)
{
PreJoinNodeTemp1->pNext = PreJoinNodeTemp2->pNext;
PreJoinNodeTemp2->unGroupAddress = 0;
PreJoinNodeTemp2->usCount = 0;
PreJoinNodeTemp2->pNext = NULL;
free ((void *) PreJoinNodeTemp2);
usCurrentPreJoinNode--;
semGive (semPreJoin);
return;
}
else
{
PreJoinNodeTemp1 = PreJoinNodeTemp2;
PreJoinNodeTemp2 = PreJoinNodeTemp2->pNext;
}
}
semGive (semPreJoin);
}
void DelAllPreJoinNode (void)
{
PreJoinNode *PreJoinNodeTemp;
PreJoinNode *PreJoinNodeTemp1;
if (pPreJoinList == NULL)
{
return;
}
semTake (semPreJoin, WAIT_FOREVER);
PreJoinNodeTemp = pPreJoinList->pNext;
pPreJoinList->unGroupAddress = 0;
pPreJoinList->usCount = 0;
pPreJoinList->pNext = NULL;
free ((void *) pPreJoinList);
usCurrentPreJoinNode--;
while (PreJoinNodeTemp)
{
PreJoinNodeTemp1 = PreJoinNodeTemp->pNext;
PreJoinNodeTemp->unGroupAddress = 0;
PreJoinNodeTemp->usCount = 0;
PreJoinNodeTemp->pNext = NULL;
free ((void *) PreJoinNodeTemp);
usCurrentPreJoinNode--;
PreJoinNodeTemp = PreJoinNodeTemp1;
}
pPreJoinList = NULL;
semGive (semPreJoin);
}
int get_all_prejoin (char *buf, USHORT *len)
{
char *p;
PreJoinNode *ptmp;
int count;
semTake (semPreJoin, WAIT_FOREVER);
ptmp = pPreJoinList;
p = buf;
*(int *)p = 1;
p += 4;
*p = get_prejoin_count();
count = *p;
p++;
*len = count*4 + 1;
while (ptmp)
{
*(UINT *)p = ptmp->unGroupAddress;
p+= 4;
ptmp = ptmp->pNext;
}
*len = p-buf;
semGive (semPreJoin);
return OK;
}
int get_prejoin_count (void)
{
PreJoinNode *ptmp;
int count;
ptmp = pPreJoinList;
count = 0;
while (ptmp)
{
count++;
ptmp = ptmp->pNext;
}
return count;
}
int get_prejoin_group (UINT * group)
{
UINT gip[256];
PreJoinNode *ptmp;
int i;
memset (gip, 0, 1024);
i = 0;
ptmp = pPreJoinList;
while (ptmp)
{
gip[i] = ptmp->unGroupAddress;
i++;
ptmp = ptmp->pNext;
}
bcopy ((char *) gip, (char *) group, 1024);
return OK;
}
int start_igmp_proxy (char *act, struct vty *vty)
{
if(strcmp(act, "enable") == 0)
{
if (nIGMPTaskId )
{
return OK;
}
IgmpInit();
}
else
{
if (nIGMPTaskId == 0)
{
return OK;
}
stop_igmp();
return OK;
}
}
int show_igmp_stat (struct vty *vty)
{
char on[] = "ON";
char echo[] = "OFF";
if (!tIgmpMembershipTimer)
{
vty_out (vty, "IGMP is OFF\r\n");
return OK;
}
vty_out (vty, "IGMP Proxy is Running!\r\n");
return OK;
}
int showgroupusernew (unsigned int groupaddress, struct vty *vty)
{
GroupEntity *ptemp;
int i, j, k;
int sum;
struct in_addr gip;
ptemp = pGroupEntityList;
sum = 0;
/*显示所有组信息*/
if (groupaddress == 0)
{
vty_out (vty, "Total Group: %d\r\n", usCurrentGroup);
while (ptemp)
{
sum = 0;
gip.s_addr = ptemp->unGroupAddress;
vty_out (vty, "==========Group==========\r\n");
vty_out (vty, "group(%s): \r\n", inet_ntoa (gip));
vty_out (vty, "slot: ");
for (i = 1; i <= MAX_UPLINK_PORT; i++)
{
if (ptemp->eGroupPortStatus[i])
{
vty_out (vty, "%d, ", i);
sum++;
}
}
vty_out (vty, "\r\nTotal Group member: %d\r\n", ptemp->usGroupUserNumber);
vty_out (vty, "====================\r\n");
ptemp = ptemp->pNext;
}
return OK;
}
/*显示单个组信息*/
while (ptemp)
{
if (ptemp->unGroupAddress == groupaddress)
{
sum = 0;
gip.s_addr = ptemp->unGroupAddress;
vty_out (vty, "==========Group==========\r\n");
vty_out (vty, "group(%s): \r\n", inet_ntoa (gip));
vty_out (vty, "slot: ");
for (i = 1; i <= MAX_UPLINK_PORT; i++)
{
if (ptemp->eGroupPortStatus[i])
{
vty_out (vty, "%d, ", i);
sum++;
}
}
vty_out (vty, "\r\nTotal Group member: %d\r\n", sum);
vty_out (vty, "====================\r\n");
return OK;
}
ptemp = ptemp->pNext;
}
return OK;
}
void ShowGroupUplink(struct vty *vty)
{
GroupEntity *ptemp;
int i, j, k;
int sum;
struct in_addr gip;
char portlist[20];
char ip[20];
char uplink[10];
vty_out (vty, "IGMP uplink ports :");
for (i = MIN_UPLINK_PORT; i <= MAX_UPLINK_PORT; i ++)
{
if (slot_module[i] == HOST_MODULE_PORT)
{
translate_uplinkport_out (i, uplink);
vty_out(vty, "%s, ", uplink);
}
}
vty_out (vty, "\r\n");
vty_out (vty, "IGMP cascade ports :");
for (i = MIN_UPLINK_PORT; i <= MAX_UPLINK_PORT; i ++)
{
if (slot_module[i] == ROUTER_MODULE_PORT)
{
translate_uplinkport_out (i, uplink);
vty_out(vty, "%s, ", uplink);
}
}
vty_out (vty, "\r\n");
memset (portlist, 0, sizeof (portlist));
ptemp = pGroupEntityList;
while (ptemp)
{
sum = 0;
gip.s_addr = ptemp->unGroupAddress;
k = GetUplinkPortlist(portlist, ptemp->unGroupAddress );
if (k)
{
inet_ntoa_b(gip, ip);
vty_out (vty, "Group(%s) : %s\r\n", ip, portlist);
memset (portlist, 0, sizeof (portlist));
}
ptemp = ptemp->pNext;
}
return;
}
int show_igmp_ip (struct vty *vty)
{
struct in_addr gip;
char ip[20];
gip.s_addr = gEtherInfo.ipAddr;
inet_ntoa_b(gip,ip);
vty_out (vty, "IGMP proxy's IP : %s\r\n", ip);
return OK;
}
int set_igmpproxy_ip (unsigned int groupaddress)
{
gEtherInfo.ipAddr = groupaddress;
return OK;
}
void erase_proxy_config (void)
{
PreJoinNode *ptmp;
if (pPreJoinList != NULL)
{
semTake (semPreJoin, WAIT_FOREVER);
while (pPreJoinList)
{
ptmp = pPreJoinList;
pPreJoinList = pPreJoinList->pNext;
free(ptmp);
ptmp = NULL;
}
semGive (semPreJoin);
usCurrentPreJoinNode = 0;
}
gEtherInfo.ipAddr = 0x0a190e39;
return;
}
/***************************************************
函数名称:SendIgmpPktbyCmd
函数功能:发送IGMP包函数,根据需要组IGMP包,并发送。
输入参数:ucIgmpType IGMP包类型
unGroupAddress 组播组地址
usPort 数据包发送的目的端口
ucMaxRespTime 最大响应时间(查询包)
usSessionId PPPoE用户SessionId
返回值: 无
备注 : 修改了最终的发送函数aibin 2005-01-14
现暂时把所有包都设置成untaged aibin 2005-4-1
***************************************************/
void SendIgmpPktbyCmd ( int ucIgmpType, UINT unGroupAddress, unsigned long sourceip, USHORT usPort,
UCHAR user)
{
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;
unsigned char smac[6];
char *userchar, *p;
char temp[100];
/*struct in_addr IpAddress; */
UCHAR DestinationMacAddress[6];
ipheader IpHeader;
ipheaderwithoption IpHeaderWithOption;
igmpheader IgmpHeader;
vlantag VlanTag;
GroupEntity *IgmpGroup;
int vid;
OutVlanTag = 0; /*aibin*/
smac[0] = '5';
smac[1] = '4';
smac[2] = '3';
smac[3] = '2';
smac[4] = '1';
smac[5] = '0';
if(IgmpPkt == NULL)
{
printf("SendIgmpPkt:Malloc Fail\n");
return;
}
memset (IgmpPkt, 0, unPktLength);
/*if (OutVlanTag > 4094) /*VLAN tag非法4095保留 */
/*{ */
/* OutVlanTag = 0; */
/*} */
switch (ucIgmpType)
{
case IGMPMembershipQuery:
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 (sourceip);
IpHeader.daddr = ntohl (DestinationIpAddress);
CaculateChecksum ((UCHAR *) & IpHeader, sizeof (ipheader), 10);
IgmpHeader.ucType = ucIgmpType;
IgmpHeader.ucMaxRespTime = 10 * 10;
IgmpHeader.usChecksum = 0;
IgmpHeader.unGroupAddress = 0; /*通用查询组地址为零 */
CaculateChecksum ((UCHAR *) & IgmpHeader, sizeof (igmpheader), 2); /*计算校验和 */
if (OutVlanTag == 0) /*没有VLAN */
{
if (1) /*无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));
}
}
}
break;
case IGMPV1MembershipReport:
case IGMPV2MembershipReport:
/*路由器口的vid ,mod by aibin*/
DestinationIpAddress = unGroupAddress;
IgmpEtherMapIpMulticast (ntohl (DestinationIpAddress),
DestinationMacAddress);
memcpy (IgmpPkt, DestinationMacAddress, 6); /*目的Mac */
memcpy (IgmpPkt + 6, smac, 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 (sourceip);
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;aibin*/
if (1)
{
*(USHORT *) (IgmpPkt + 12) = ntohs (0x0800);
memcpy (IgmpPkt + 14, &IpHeaderWithOption,
sizeof (IpHeaderWithOption));
memcpy (IgmpPkt + 14 + sizeof (IpHeaderWithOption), &IgmpHeader,
sizeof (igmpheader));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -