您的位置:首页 > 其它

使用SOCK_RAW构建全网广播包

2015-08-29 23:01 423 查看
使用SOCK_DGRAM在Linux上发送全网广播包:

#include<stdio.h>

#include<stdlib.h>

#include<errno.h>

#include<string.h>

#include<sys/types.h>

#include<netinet/in.h>

#include<sys/socket.h>

#include<sys/wait.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<unistd.h>

#include<arpa/inet.h>

#include<netdb.h>

#define PORT 7773

#define MAXDATASIZE 256

int main(int argc,char *argv[])

{

int ret,socket_fd;

struct sockaddr_in my_addr;

char buf[MAXDATASIZE];

int so_broadcast=1;

socklen_t size;

char my_ip[12];

my_addr.sin_family=AF_INET;

my_addr.sin_port=htons(PORT);

my_addr.sin_addr.s_addr=inet_addr("255.255.255.255");

bzero(&(my_addr.sin_zero),8);

if((socket_fd=(socket(AF_INET,SOCK_DGRAM,0)))==-1) {

perror("socket");

exit(1);

}

setsockopt(socket_fd,SOL_SOCKET,SO_BROADCAST,&so_broadcast,sizeof(so_broadcast));

strcpy(buf,"Hello,I'm on line!");

while(1) {

ret=sendto(socket_fd,buf,strlen(buf),0,(struct sockaddr *)&my_addr,sizeof(my_addr));

sleep(1);

printf("next:%d\n",ret);

}

return 0;

}

还必须运行此命令,不然即使sendto不报错,实质上也发不出去,对方抓包都抓不到。有些系统会提示:No Route to host.

route add -host 255.255.255.255 dev eth0

由于系统差异,有些系统的UDP协议不支持发送全网广播包,只能发送子网广播包,因此只能使用SOCK_RAW构建UDP包,这样就能实现全网广播包:

#include<stdio.h>

#include<stdlib.h>

#include<errno.h>

#include<string.h>

#include<sys/types.h>

#include<netinet/in.h>

#include<sys/socket.h>

#include<sys/wait.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<unistd.h>

#include<arpa/inet.h>

#include<netdb.h>

#define UDP_HEADER_SIZE 8

#define IP_HEADER_SIZE 20

typedef struct udp_hdr{

unsigned short s_port;

unsigned short d_port;

unsigned short length;

unsigned short cksum;

char data[0];

}udp_hdr;

int

send_bcast(char *send_data,char *src_ip, uint16_t src_port, uint16_t dest_port)

{

int sd;

udp_hdr *udp;

int count = -1; /* # of expected bcasts,

* default infinite */

int send_cnt = 0; /* # of bcasts sent */

int recv_cnt = 0; /* # of bcasts received on

* current send */

int udplen; /* Total length of packets sent */

struct sockaddr_in laddr; /* Local address */

socklen_t laddr_len; /* Local address */

struct sockaddr_in faddr; /* Foreign address */

int datalen = strlen(send_data);
/* data length. */

/* Parameters (command line options) */

char *host;

unsigned int ipaddr;

char *data;

unsigned char ttl = 64; /* IP_MULTICAST_TTL default 1, must change to 64 */

/* Set 'ipaddr' from first non-option argument. */

host = "255.255.255.255";

ipaddr = inet_addr("255.255.255.255");

if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) == -1)

{

perror("socket");

goto fail;

}

if(setsockopt(sd, IPPROTO_IP, IP_MULTICAST_TTL,(char *)&ttl, sizeof(unsigned char)) == -1)

{

perror("setsockopt(IP_MULTICAST_TTL)");

}

int on=1;

setsockopt(sd,SOL_SOCKET,SO_REUSEADDR | SO_BROADCAST,&on,sizeof(on));

/* Our local address */

memset(&laddr, 0, sizeof(laddr));

laddr.sin_family = AF_INET;

laddr.sin_addr.s_addr = inet_addr(src_ip);

/* Foreign adddress (for connect/sendto) */

memset(&faddr, 0, sizeof(faddr));

faddr.sin_family = AF_INET;

faddr.sin_addr.s_addr = ipaddr;

/*

* Initialize the send buffer with an request.

*/

udplen = datalen + UDP_HEADER_SIZE;

udp = malloc(udplen);

data = udp->data;

memcpy(data,send_data,datalen);

udp->s_port = htons(src_port);

udp->d_port = htons(dest_port);

udp->length = udplen;

udp->cksum = 0;

//udp->cksum = chksum((U16 *)udp, udplen);

laddr_len = sizeof(laddr);

getsockname(sd, (struct sockaddr *)&laddr, &laddr_len);

printf("bcast %s (%s) ", host, inet_ntoa(*((struct in_addr *)&ipaddr)));

if (laddr.sin_addr.s_addr != 0)

{

printf("from %s: ", inet_ntoa(laddr.sin_addr));

}

printf("%d(%d) bytes of data.\n", datalen, udplen+IP_HEADER_SIZE);

/*

* Send one echo request

*/

int retval = sendto(sd, udp, udplen, 0,

(struct sockaddr *)&faddr, sizeof(faddr));

if (retval == -1)

{

perror("sendto");

}

fail:

/* Cleanup and exit. */

if (udp) free(udp);

if (sd != -1) close(sd);

usage:

return 0;

}

int main(int argc, char *argv[])

{

int c;

int enable_double=0;

int cycles=0;

char *data;

while ((c = getopt(argc, argv, "r:d:")) != -1)

{

switch (c)

{

case 'r':

cycles = (uint32_t)strtol(optarg,NULL,10);

break;

case 'd':

data = optarg;

break;

}

}

if(cycles)

{

if(data==NULL)

{

data="hello";

}

while(cycles--)

{

send_bcast(data,"10.69.2.214",13334,8080);

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: