您的位置:首页 > 理论基础 > 计算机网络

向本地网络中广播特定的控制帧,设备端检测到控制帧时,发送自己的网络配置信息,如IP,Mask,Mac地址

2017-09-26 15:45 106 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/idream68/article/details/78096865

        当一台嵌入式设备连接到PC或多个设备通过交换机与PC相连时,由于设备的IP地址可能未知,那么就需要通过工具进行设备探测,来获取设备的IP地址和网络掩码,获取到的参数可以由PC来参考设备本地的网络参数和PC程序中用来打开设备的参数。

 注意事项:

(1)广播的目的mac地址为FF:FF:FF:FF:FF:FF

(2)发送数据需要先绑定网卡

struct sockaddr_ll saddr_ll;

struct ifreq ifr;

bzero(&saddr_ll, sizeof(struct sockaddr_ll));
bzero(&ifr, sizeof(struct ifreq));
/* 网卡接口名 */
memcpy(ifr.ifr_name, Network_Name, strlen(Network_Name));

/* 获取网卡接口索引 */
if (ioctl(skfd, SIOCGIFINDEX, &ifr) == -1)
perror("ioctl() get ifindex");
saddr_ll.sll_ifindex = ifr.ifr_ifindex;
saddr_ll.sll_family = PF_PACKET;

(3)需要构建原始套接字raw_socket;

  socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL))

(4)ioctl函数的应用获取IP,Mask,Mac地址;

实现广播程序如下:

#include "api.h"

int send_broadcast(const char* Network_Name/*in*/)
{
int skfd,n;
char buf[BUFLEN]={0};
char r_buf[BUFLEN]={0};
struct ethhdr *eth0;
struct ether_header *eth;
Tbroadcast *broadcast;

Tack *iph;
struct sockaddr_ll saddr_ll;

struct ifreq ifr;
struct sockaddr_in *sin;

char ip[16] ;
char netmask[16];
char mac[16];

//struct sockaddr_in  clientaddr;
//bzero(&clientaddr, sizeof(clientaddr));
//clientaddr.sin_family = AF_INET;
//inet_pton(AF_INET, BROADCAST_IP, &clientaddr.sin_addr.s_addr);
//clientaddr.sin_port = htons(CLIENT_PORT);

unsigned char src_mac[ETH_ALEN]={0};
unsigned char dst_mac[ETH_ALEN]={0xff,0xff,0xff,0xff,0xff,0xff}; //全网广播

bzero(&saddr_ll, sizeof(struct sockaddr_ll));
bzero(&ifr, sizeof(struct ifreq));
/* 网卡接口名 */
memcpy(ifr.ifr_name, Network_Name, strlen(Network_Name));

if(0>(skfd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL))))
{
perror("Create Error");
exit(1);
}

/* 获取网卡接口索引 */
if (ioctl(skfd, SIOCGIFINDEX, &ifr) == -1)
perror("ioctl() get ifindex");
saddr_ll.sll_ifindex = ifr.ifr_ifindex;
saddr_ll.sll_family = PF_PACKET;

int flag = 1;
setsockopt(skfd, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag));

//获取接口IP地址

//strcpy(ifr.ifr_name,argv[1]);
memset(&sin, 0, sizeof(sin));

if(ioctl(skfd, SIOCGIFADDR, &ifr) != -1)
{
sin = (struct sockaddr_in *)&ifr.ifr_addr;
strcpy(ip, inet_ntoa(sin->sin_addr));
printf("IP address is %s\n", ip);
}

//获取接口的子网掩码
if(ioctl(skfd, SIOCGIFNETMASK, &ifr) != -1)
{
sin = (struct sockaddr_in *)&ifr.ifr_netmask;
strcpy(netmask, inet_ntoa(sin->sin_addr));
printf("Net-mask is %s\n", netmask);
}

//获取接口的MAC地址
if(ioctl(skfd, SIOCGIFHWADDR, &ifr) != -1)
{
sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned char)ifr.ifr_hwaddr.sa_data[0],
(unsigned char)ifr.ifr_hwaddr.sa_data[1],
(unsigned char)ifr.ifr_hwaddr.sa_data[2],
(unsigned char)ifr.ifr_hwaddr.sa_data[3],
(unsigned char)ifr.ifr_hwaddr.sa_data[4],
(unsigned char)ifr.ifr_hwaddr.sa_data[5]);
printf("Mac address is %s\n", mac);
}
memcpy(src_mac,ifr.ifr_hwaddr.sa_data,ETH_ALEN);

//开始填充,构造以太头部
eth=(struct ether_header*)buf;
memcpy(eth->ether_dhost,dst_mac,ETH_ALEN);
memcpy(eth->ether_shost,src_mac,ETH_ALEN);
eth->ether_type = htons(BROADCAST);

//手动开始广播帧结构
broadcast=(struct _Tbroadcast*)(buf+sizeof(struct ether_header));
broadcast->header=0xdeadbeef; 	                           //帧头(帧头固定为0xdeadbeef)
broadcast->length=sizeof(struct _Tbroadcast); 	           //广播帧长度
broadcast->version=0x00;	                               //广播帧版本
broadcast->contNum=1;	                                   //控制字

if(ioctl(skfd, SIOCGIFADDR, &ifr) != -1)
memcpy(&broadcast->dev_ip,&(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr),4);   	        //网络参数 设备IP地址
else
perror("broadcast->dev_ip error");

if(ioctl(skfd, SIOCGIFNETMASK, &ifr) != -1)
memcpy(&broadcast->dev_mask,&(((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr),4);       //网络参数 设备子网掩码
else
perror("broadcast->dev_mask error");

if(ioctl(skfd, SIOCGIFHWADDR, &ifr)!= -1 )
memcpy(&broadcast->dev_mac,ifr.ifr_hwaddr.sa_data,6);                                       //网络参数 设备MAC地址
else
perror("broadcast->dev_mac error");

//发送广播数据
while(1)
{
if(n=sendto(skfd,buf,BUFLEN,0, (struct sockaddr *)&saddr_ll, sizeof(struct sockaddr_ll))<0)
{
perror("Send error:");
continue;
}
else
{
n=recvfrom(skfd,r_buf,BUFLEN,0,NULL,0);
if(n <=0)
{
perror("Receive error:");
continue;
}
else
{

iph=(struct _Tack*)(r_buf+sizeof(struct ether_header));
if(iph->header == 0xdeadbeef)
{
printf("\n %d Bytes Receive\n",n);
char strIP[16];
char strMask[16];
printf("Client   IP:%s\n",inet_ntop(AF_INET,&iph->dev_ip,strIP,sizeof(strIP)));
printf("Client Mask:%s\n",inet_ntop(AF_INET,&iph->dev_mask,strMask,sizeof(strMask)));

sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned char)iph->dev_mac[0],
(unsigned char)iph->dev_mac[1],
(unsigned char)iph->dev_mac[2],
(unsigned char)iph->dev_mac[3],
(unsigned char)iph->dev_mac[4],
(unsigned char)iph->dev_mac[5]);

printf("Mac address is %s\n", mac);

return 0;
}

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