struct table_port_mac *obx_mc_mac_tbl = NULL;/*定義多播MAC轉發表對象爲空指針,将在main函數中(zhōng)初始地址*/
/*爲多手播MAC轉發表分(fēn)配内存,并初始數據爲0*/
obx_mc_mac_tbl = (struct table_port_mac *)malloc(sizeof(struct table_port_mac));
memset(obx_mc_mac_tbl,0,sizeof(struct table_port_mac));
#include
#include
#include
if(pkt->data[0]&0x1)//MC MAC
{
u64 igmpv3_dmac = 0x1600005E0001;
if(!ether_addr_equal(pkt->data,(u8 *)&igmpv3_dmac)) //IGMP
{
struct ethhdr *eth = (struct ethhdr *)pkt->data;
struct iphdr *ip = (struct iphdr *)(eth+1);
int oft = 0;
if(eth->h_proto = htons(0x0800) && ip->protocol == IPPROTO_IGMP)
{
oft = sizeof(*eth) + ip->ihl * sizeof(int);
igmpv3_report(pkt->um.inport,pkt->data+oft);
}
}
}
void igmpv3_report(u8 inport,u8 *igmp)
{
struct igmpv3_report *g3r = (struct igmpv3_report *)igmp;
if(g3r->type == IGMPV3_HOST_MEMBERSHIP_REPORT)/*IGMPv3_REPORT*/
{
u8 mc_mac[MAC_LEN] = {0x01,00,0x5E};
u8 *mcip = NULL;
int k = 0;
for(;k
{
mcip = (u8 *)&g3r->grec[k].grec_mca;
memcpy(&mc_mac[3],&mcip[1],3);/*僅複制後3字節數據*/
mc_mac[3] &= 0x7F;/*将第23bit置0*/
join_leave_mc_mac(inport,mc_mac,g3r->grec[k].grec_type);
}
}
}
if(type == IGMPV3_CHANGE_TO_EXCLUDE)/*入組*/
{
obx_mc_mac_tbl->row[i].port |= 1<<>
}
else/*退組*/
{
obx_mc_mac_tbl->row[i].port &= ~ (1<<>
}
void output(u8 outtype,int outport,struct fast_packet *pkt)
{
if(outtype == UC)
{
pkt->um.outport = outport;
pkt_send_normal(pkt,pkt->um.len);
}
else
{
int i = 0;
for(;i<>
{
if(pkt->um.inport != i && (outport & (1< 0)
{
pkt->um.outport = i;
pkt_send_normal(pkt,pkt->um.len);
}
}
}
}