📄 igmp_polltest.c
字号:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/igmp.h>
#include <strings.h>
#include <unistd.h>
#define IPVERSION 4
#define BUFFSIZE (sizeof(struct igmp) + sizeof(struct iphdr))
unsigned short in_cksum(unsigned short *addr,int len)
{
register int sum = 0;
u_short answer = 0;
register u_short *w = addr;
register int nleft = len;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return(answer);
}
int Send_IGMP_messege(char *addr,short type)
{
struct igmp *igmphdr;
struct iphdr *iphdr;
int sockd;
int dummy,on;
int tmp;
struct sockaddr_in mysocket;
unsigned char buff[BUFFSIZE];
if((sockd = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) < 0) {
perror("socket");
return -1;
}
iphdr = (struct iphdr *)buff;
bzero((char *)iphdr,sizeof(struct iphdr));
iphdr->ihl = 5;
iphdr->version = IPVERSION;
iphdr->tot_len = htons(sizeof(struct iphdr) + sizeof(struct igmp));
iphdr->id = htons(getpid());
iphdr->ttl = 1;
iphdr->protocol = 2;
iphdr->saddr = inet_addr("192.168.2.138"); /*本地地址*/
if(type == 0x11)
iphdr->daddr = inet_addr("224.0.0.1");
else
iphdr->daddr = inet_addr(addr);
iphdr->check = in_cksum((unsigned short *)iphdr,sizeof(struct iphdr));
igmphdr = (struct igmp*)(buff +sizeof(struct iphdr));
bzero((char *)igmphdr,sizeof(struct igmp));
igmphdr->igmp_type = type;
igmphdr->igmp_code = 0;
if(type == 0x11)
inet_pton(AF_INET,"0.0.0.0",&igmphdr->igmp_group);
else
inet_pton(AF_INET,addr,&igmphdr->igmp_group);
igmphdr->igmp_cksum = in_cksum((unsigned short *)igmphdr, sizeof(struct igmp));
bzero((char *)&mysocket,sizeof(mysocket));
mysocket.sin_family = AF_INET;
if(type == 0x11)
mysocket.sin_addr.s_addr = inet_addr("224.0.0.1");
else
mysocket.sin_addr.s_addr = inet_addr(addr);
if((tmp = sendto(sockd,(char *)buff,sizeof(buff),0x0,
(struct sockaddr *)&mysocket,sizeof(mysocket))) < 0) {
perror("sendto");
return -1;
}
printf("tmp : %d \n",tmp);
close(sockd);
return 0;
}
/**************************************************/
/* 参数:希望加入的IPV4 组播组地址
/* 返回:正确返回0
/* 网络错误返回-1
/**************************************************/
int Send_IGMP_Join(char * addr)
{
return Send_IGMP_messege(addr,0x16);
}
/***************************************************/
/* 参数:希望退出的IPv4组播组地址
/* 返回:正确返回0
/* 错误返回-1
/***************************************************/
int Send_IGMP_Leave(char * addr)
{
return Send_IGMP_messege(addr,0x17);
}
int Send_IGMP_Poll(char * addr)
{
return Send_IGMP_messege(addr,0x11);
}
/***************************************************/
/* 监听轮询信息,并作出应答。
/* 参数:监听来自哪个组播地址的轮询
/***************************************************/
void IGMP_Listen(char * addr)
{
struct igmp *igmphdr;
struct iphdr *iphdr;
int sockd,nready;
fd_set rset,allset;
char buf[64];
if((sockd = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) < 0) {
perror("socket");
return ;
}
while(1)
{
FD_ZERO(&allset);
FD_SET(sockd,&allset);
nready=select(sockd+1,&rset,NULL,NULL,NULL);
if(FD_ISSET(sockd,&rset))
{
if(recvfrom(sockd,buf,sizeof(buf),0,NULL,NULL) < 0){
perror("sendto");
return ;
}
}
usleep(10);
}
}
int main()
{
//Send_IGMP_Join("224.0.0.4");
//Send_IGMP_Leave("224.0.0.4");
Send_IGMP_Poll("224.0.0.4");
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -