linux 组播请求发送

4 篇文章 0 订阅

组播文章:http://www.docin.com/p-271100049.html

http://blog.csdn.net/luohai859/article/details/37819113

#include <net/if_arp.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <strings.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>




#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>


#if 0
# include <linux/in.h>
#endif
#include <netinet/in.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <linux/sockios.h>
#include <netinet/in.h>
#include <netinet/ip.h>


#ifdef linux
# define NEWSOCKET() socket(AF_INET, SOCK_PACKET, htons(ETH_P_RARP))
#else
# define NEWSOCKET() socket(SOL_SOCKET, SOCK_RAW, ETHERTYPE_REVARP)
#endif


#define MAC_ADDR_LEN 6
#define IP_ADDR_LEN 4
#define ARP_FRAME_TYPE 0x0806
#define IP_FRAME_TYPE 0x0800
#define ETHER_HW_TYPE 1
#define IP_PROTO_TYPE 0x0800
#define OP_ARP_REQUEST 1
#define OP_ARP_REPLY 2




char usage[]={"Usage: send_arp <ifname>\n\tExample:\tsend_arp eth0\n\t\t\tsend_arp eth1:1"};
typedef struct igmphdr{
unsigned char type;
unsigned char code;
unsigned short csum;
struct in_addr group;
}igmphdr;
struct arp_packet {
        u_char targ_hw_addr[MAC_ADDR_LEN];
        u_char src_hw_addr[MAC_ADDR_LEN];
        //u_short vlan; //always 0x8100
//u_short vlan_id; //0x43
        u_short frame_type;
        u_char padding[32];
};
void die(const char *);
void get_ip_addr(struct in_addr*,char*);
void get_hw_addr(u_char*,char*);


int ioctl_sock;


int opt_d = 0;


#define IGMP_MINLEN                    8
#define FOLD_U32T(u)          (((u) >> 16) + ((u) & 0x0000ffffUL))
#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8)
char igmpbuf[8];
static unsigned short
lwip_standard_chksum(void *dataptr, int lenarg)
{
  
  int len = lenarg;
  unsigned char  *pb = (unsigned char *)dataptr;
  unsigned short *ps, t = 0;
  unsigned int  *pl;
  unsigned int sum = 0, tmp;
  /* starts at odd byte address? */
  int odd = ((unsigned int )pb & 1);


 printf(" odd %d %d  %d\n",odd,sizeof(ps),len);
  if (odd && len > 0) {
    ((unsigned char *)&t)[1] = *pb++;
    len--;
  }


 printf(" odd %d %d  %d\n",odd,sizeof(ps),len);
  ps = (unsigned short *)pb;
 printf("  if   %d\n" , ((unsigned int )ps &3));


  if (((unsigned int )ps & 3) && len > 1) {
    sum += *ps++;
    len -= 2;
  }


 printf(" ps:%d sum:%d len%d\n",ps,sum,len);
  pl = (unsigned int *)ps;


  while (len > 7)  {
    tmp = sum + *pl++;          /* ping */
    if (tmp < sum) {
      tmp++;                    /* add back carry */
    }
printf(" %d %d %d\n" , len , tmp, sum);
    sum = tmp + *pl++;          /* pong */
printf(" %d %d %d\n" , len , tmp, sum);
    if (sum < tmp) {
      sum++;                    /* add back carry */
    }


printf(" %d %d %d\n" , len , tmp, sum);
    len -= 8;
  }


 printf(" sum0 %d\n",sum);
  /* make room in upper bits */
  sum = FOLD_U32T(sum);
 printf(" sum1 %d\n",sum);
   ps = (unsigned short *)pl;


  /* 16-bit aligned word remaining? */
  while (len > 1) {
    sum += *ps++;
    len -= 2;
  }


 printf(" sum2 %d\n",sum);
  /* dangling tail byte remaining? */
  if (len > 0) {                /* include odd byte */
    ((unsigned char *)&t)[0] = *(unsigned char *)ps;
  }


  sum += t;                     /* add end bytes */


 printf(" sum2 %d\n",sum);
  /* Fold 32-bit sum to 16 bits
     calling this twice is propably faster than if statements... */
  sum = FOLD_U32T(sum);
  sum = FOLD_U32T(sum);
 printf(" sum2 %d\n",sum);


  if (odd) {
    sum = SWAP_BYTES_IN_WORD(sum);
  }


  return (unsigned short)sum;
}


#if 0
static unsigned short
lwip_standard_chksum(void *dataptr, int len)
{
  unsigned char  *pb = (unsigned char *)dataptr;
  unsigned short *ps, t = 0;
  unsigned int  *pl;
  unsigned int sum = 0, tmp;
  /* starts at odd byte address? */
  int odd = ((unsigned int )pb & 1);


  if (odd && len > 0) {
    ((unsigned char *)&t)[1] = *pb++;
    len--;
  }


  ps = (unsigned short *)pb;


  if (((unsigned int )ps & 3) && len > 1) {
    sum += *ps++;
    len -= 2;
  }


  pl = (unsigned int *)ps;


  while (len > 7)  {
    tmp = sum + *pl++;          /* ping */
    if (tmp < sum) {
      tmp++;                    /* add back carry */
    }


    sum = tmp + *pl++;          /* pong */
    if (sum < tmp) {
      sum++;                    /* add back carry */
    }


    len -= 8;
  }


  /* make room in upper bits */
  sum = FOLD_U32T(sum);


   ps = (unsigned short *)pl;


  /* 16-bit aligned word remaining? */
  while (len > 1) {
    sum += *ps++;
    len -= 2;
  }


  /* dangling tail byte remaining? */
  if (len > 0) {                /* include odd byte */
    ((unsigned char *)&t)[0] = *(unsigned char *)ps;
  }


  sum += t;                     /* add end bytes */


  /* Fold 32-bit sum to 16 bits
     calling this twice is propably faster than if statements... */
  sum = FOLD_U32T(sum);
  sum = FOLD_U32T(sum);


  if (odd) {
    sum = SWAP_BYTES_IN_WORD(sum);
  }


  return (unsigned short)sum;
}
#endif
unsigned short checksum(unsigned short *buf, int nword)
{
unsigned long sum;


for(sum = 0; nword > 0; nword--)
sum += (*buf++);


sum = (sum>>16) + (sum&0xffff);
sum += (sum>>16);


return ~sum;
}


void
igmpjoinreport (char *interface, char* destip)
{


struct in_addr my_in_addr;
struct arp_packet pkt;
struct sockaddr sa;
int optypes [] = {OP_ARP_REQUEST, OP_ARP_REPLY, 0};
int sock;
u_char hwaddr[MAC_ADDR_LEN];
int j, i;
char *ifname, *ifsend, *cindex;
char ch;








struct sockaddr_in target,host;


bzero(&target , sizeof(struct sockaddr_in ) );
target.sin_family = AF_INET;
target.sin_port= htons(8888);
if(!inet_aton((const char*)destip ,&target.sin_addr))
printf("inet_aton error\n");
printf("%s %p\n",destip, &target.sin_addr);


sock=NEWSOCKET();
ioctl_sock = NEWSOCKET();


if ((sock < 0) || (ioctl_sock < 0)) {
perror("Unable to create socket");
exit(1);
   }






if (!(ifname = strdup(interface)) || !(ifsend = strdup(interface)))
die("Cannot duplicate interface name\n");




if (cindex = strchr(ifsend, ':'))
*cindex = '\0';


if (opt_d) {
printf("Interface: %s\n", ifname);
}


get_hw_addr(hwaddr, interface);
get_ip_addr(&my_in_addr, ifname);


memset(&pkt, '0', sizeof(pkt));
pkt.frame_type = htons(IP_FRAME_TYPE);


pkt.targ_hw_addr[0]=0x01;
pkt.targ_hw_addr[1]=0x00;
pkt.targ_hw_addr[2]=0x5e;
unsigned int addr = (unsigned int)target.sin_addr.s_addr;
printf("mac is %x\n", addr);
unsigned char temp = (addr&0x00007F00)>>8  ;
pkt.targ_hw_addr[3]=temp;
printf("mac is %x\n", temp);
temp = (addr&0x00FF0000)>>16  ;
printf("mac is %x", temp);
pkt.targ_hw_addr[4]=temp;
temp = (addr&0xFF000000)>>24  ;
printf("mac is %x", temp);
pkt.targ_hw_addr[5]=temp;


       //pkt.vlan= 0x8100;
//pkt.vlan_id=0x43;



for (i = 0; i < MAC_ADDR_LEN; i++)
pkt.src_hw_addr[i] = hwaddr[i];


memset(pkt.padding,0, 18);


strcpy(sa.sa_data, ifsend);
printf ("**********%d\n",sizeof(struct ip ));
struct ip *ip;
struct igmphdr *igmp , *igmp2;
unsigned short ip_len;
ip_len = sizeof(struct ip ) + sizeof(struct igmphdr)+4;
ip=(struct ip*)pkt.padding;
ip->ip_v= IPVERSION;
ip->ip_hl = (sizeof(struct ip ) +4)>>2;
ip->ip_tos = 0xc0;
ip->ip_len = htons(ip_len);
ip->ip_id=0x00;


ip->ip_off= 0x0040;
ip->ip_ttl = 1;
ip->ip_p= IPPROTO_IGMP;


ip->ip_dst = target.sin_addr;
ip->ip_src = my_in_addr ;/* host.sin_addr;*/


char * option = ((void*)(pkt.padding)+ sizeof(struct ip ));
option[0]=0x94;
option [1]= 0x04;
option [2]= 0x00;
option [3]= 0x00;
ip->ip_sum=checksum( ip , (sizeof(struct ip  ) +4)/2 );
igmp =(struct igmphdr*)((void*)(pkt.padding)+ sizeof(struct ip )+4);
igmp->type=0x16;
igmp->code=0;
igmp->group=target.sin_addr;

        igmp2=(struct igmphdr*)igmpbuf;
igmp2->type=0x16;
igmp2->code=0;
igmp2->group=target.sin_addr;


igmp->csum=~lwip_standard_chksum(igmp2,IGMP_MINLEN );
printf ("**********%p %p igmpchecksum %x\n",ip , igmp, igmp->csum);
int tmp =1;
const int *val = &tmp;
setsockopt (sock, IPPROTO_IP, IP_HDRINCL, val, sizeof(tmp));




if (sendto(sock, (const void *)&pkt, sizeof(pkt), 0,&sa,sizeof(sa)) < 0) {
perror("Unable to send");
exit(1);
}
close(sock);
close(ioctl_sock);


if(ifname != NULL)
free(ifname);


if(ifsend != NULL)
free(ifsend);
}


void die(const char* str)
{
fprintf(stderr,"Error: %s\n",str);
exit(1);
}




void get_ip_addr(struct in_addr* in_addr,char* str)
{
struct ifreq ifr;
struct sockaddr_in sin;


strcpy(ifr.ifr_name, str);
   ifr.ifr_addr.sa_family = AF_INET;
   if (ioctl(ioctl_sock, SIOCGIFADDR, &ifr))
 {  //   die("Failed to get IP address for the interface");
printf(" failed to get ipt addre ");
}
memcpy(&sin, &ifr.ifr_addr, sizeof(struct sockaddr_in));
in_addr->s_addr = sin.sin_addr.s_addr;
if (opt_d)
printf("IP address: %s\n", inet_ntoa(*in_addr));
}


void get_hw_addr(u_char* buf,char* str)
{


int i;
struct ifreq ifr;
char c,val = 0;


strcpy(ifr.ifr_name, str);
  if (ioctl(ioctl_sock, SIOCGIFHWADDR, &ifr))
    { } // die("Failed to get MAC address for the interface");


memcpy(buf, ifr.ifr_hwaddr.sa_data, 8);
if (opt_d)
printf("MAC address: %2X:%2X:%2X:%2X:%2X:%2X\n", *(buf), *(buf+1), *(buf+2), *(buf+3),*(buf+4), *(buf+5));
}


#define LINENUM 256


int
getMajor(char *path, char *node)
{
FILE *file = fopen(path, "r");
char buf[LINENUM];
int index = -1;


if(file == NULL)
{
perror ("File  open error!\n");
return -1;
}



while ((fgets (buf, LINENUM, file)) != NULL)
{
if(strstr(buf, node) != NULL)
{
char *p = strchr(buf, 0x20);
*p = '\0';
return atoi(buf);
}
  memset(buf, 0, LINENUM);
}


return -1;



}




int
main(int argc, char **argv)
{
if (argc < 3) {
die(usage);
}
igmpjoinreport(argv[1], argv[2]);

int res = 0;
time_t currenttime;
int fd = open("/dev/iptvdev", O_RDWR|O_NONBLOCK);
if(fd < 0)
{
int major = getMajor("/proc/devices", "iptvdev");
if(major < 0)
{
perror ("get major failed pls check /proc/devices!\n");
goto startloop;

}


dev_t dev = makedev(major, 1);
int res = mknod("/dev/iptvdev", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH|S_IFCHR, dev);
if(res != 0)
{
perror ("mknod failed pls check major or minjor!\n");
goto startloop;
}


fd = open("/dev/iptvdev", O_RDWR|O_NONBLOCK);
if(fd < 0)
{
perror ("fd create failed!\n");
goto startloop;
}
}



startloop:
if(fd < 0)
{
fd = 2;
struct timeval tv;
while(1)
{
tv.tv_sec = 120;
tv.tv_usec = 0;
if( (res = select(fd, NULL, NULL, NULL, &tv) ) == 0)
{
currenttime = time(NULL);

fprintf(stderr, "time out %s\n", ctime(&currenttime));
igmpjoinreport(argv[1], argv[2]);
}
}
}
else
{
int val= fcntl(fd,   F_GETFL,   0);
char buf[32];


fcntl(fd,   F_SETFL,   val | O_NONBLOCK);
fd_set rset;
fd_set wset;
fd_set eset;



while(1)
{
FD_ZERO(&rset);
FD_CLR(fd,&rset);
FD_SET(fd, &rset);
res = 0;
fprintf(stderr, "\n===================================== \n");
// here add timeout
struct timeval tv;
tv.tv_sec = 120;
tv.tv_usec = 0;
if( ( res = select(fd + 1, &rset, NULL, NULL, &tv) ) <= 0)
{
printf("select error\n");
continue;
}



res = FD_ISSET(fd, &rset);


read(fd, buf, 32);
if(res > 0)
igmpjoinreport(argv[1], argv[2]);
fprintf(stderr, "===================================== \n");
}
close(fd);
}
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值