#include <stdio.h>
#include <stdlib.h>
#include <net/if.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <net/route.h>
#include <string.h>
#include <net/if_arp.h>
#include <time.h>
#define ALIGN __attribute__((packed))
struct ifreq buf[16];
int interfaceNum = 0;
unsigned int devnum=0;
//报文结束标志
typedef struct ALIGN tag_EndFlag{
/*
tag_EndFlag(){
flag[0] = 'O';
flag[1] = 'K';
}
*/
char flag[2];
}EndFlag;
//pc机设置网络参数
typedef struct ALIGN tag_NetworkParamSingle{
/*
tag_NetworkParamSingle(){
sep1 = ',';
sep2 = ',';
sep3 = ',';
sep4 = ',';
sep5 = ',';
}
*/
char sep1;
char ethName[8];//网卡名字,ascii 码表示,不足八个字符补数字0
char sep2;
uint32_t ipAddr;//IP参数
char sep3;
uint32_t netmask;//MASK参数
char sep4;
uint32_t gateway;//GATEWAY参数
char sep5;
char macAddr[6];//MAC地址
}NetworkParamSingle;
//pc机查询网络参数
typedef struct ALIGN tag_NetworkParamReq{
/*
tag_NetworkParamReq(){
flags[0] = '$';
flags[1] = 'C';
flags[2] = 'G';
flags[3] = 'B';
flags[4] = 'C';
flags[5] = 'X';
}
*/
char flags[6]; //客户端标志,广播查询,ascii 码表示 $CGBCX
}NetworkParamReq;
typedef struct ALIGN tag_NetworkParamSet{
/*
tag_NetworkParamSet(){
flags[0] = '$';
flags[1] = 'C';
flags[2] = 'G';
flags[3] = 'B';
flags[4] = 'S';
flags[5] = 'E';
flags[6] = 'T';
sep1 = ',';
}
*/
char flags[7]; //客户端标志,广播设置,ascii 码表示 $CGBSET
char sep1;//分隔符
char devnum[10]; //设备编号,ascii 码表示 $CGBSET
char sep2;//分隔符
char MacCount[2];//网卡数量,ascii 码表示
//NetworkParamSingle n个
//EndFlag
}NetworkParamSet;
//arm回复网络参数查询命令
typedef struct ALIGN tag_NetworkParamRes{
/*
tag_NetworkParamRes(){
flags[0] = '$';
flags[1] = 'S';
flags[2] = 'G';
flags[3] = 'B';
flags[4] = 'C';
flags[5] = 'X';
flags[6] = 'A';
flags[7] = 'C';
flags[8] = 'K';
sep1 = ',';
}
*/
char flags[9]; //服务端标志,广播回复查询,ascii 码表示 $SGBCXACK
char sep1;//分隔符
char MacCount[2];//网卡数量,ascii 码表示
//NetworkParamSingle n个
//EndFlag
}NetworkParamRes;
int get_interface(char *sendbuf)
{
/************************************************************************/
struct sockaddr_in *sin;
struct in_addr longaddr;
struct ifreq ifr;
struct ifconf ifc;
FILE *dns;
FILE *gw;
char buffer[128] = {'\0'};
char NetTemp[128] = {'\0'};
char query_cmd[128]= {'\0'};
char name[9] = {0};
char ip[32] = {0};
char subnetMask[32] = {0};
char mac[16] = {0};
char broadAddr[32] = {0};
int socket_fd;
FILE *query_fd;
int ibuffer=0;
if((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket");
}
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = (caddr_t)buf;
if (!ioctl(socket_fd, SIOCGIFCONF, (char *)&ifc))
{
interfaceNum = ifc.ifc_len / sizeof(struct ifreq);
int if_i=0;
int ifface_total=interfaceNum;
for(if_i=0;if_i<interfaceNum;if_i++)
{
if(!strncmp(buf[if_i].ifr_name,"lo",strlen("lo")))
{
ifface_total--;
}
}
/*ethif number*/
*sendbuf++ = ifface_total/10 + '0';
*sendbuf++ = ifface_total%10 + '0';
*sendbuf++ = ',';
for(if_i=0;if_i<(ifc.ifc_len / sizeof(struct ifreq));if_i++)
{
int i=0;
/*name*/
strncpy(name,buf[if_i].ifr_name,strlen(buf[if_i].ifr_name));
if(!strncmp(buf[if_i].ifr_name,"lo",strlen("lo")))
{
continue;
}
printf("name=%s,\n",name,buf[if_i].ifr_name);
for(i=0;i<8;i++)
{
*sendbuf++ = name[i];
}
memset(name,0,sizeof(name));
*sendbuf++ = ',';
//get the IP of this interface
if (!ioctl(socket_fd, SIOCGIFADDR, (char *)&buf[if_i]))
{
memset(ip,0,sizeof(ip));
snprintf(ip, sizeof(ip), "%s",(char *)inet_ntoa(((struct sockaddr_in *)&(buf[if_i].ifr_addr))->sin_addr));
memset(NetTemp,0,sizeof(NetTemp));
for(ibuffer=0;ibuffer<sizeof(ip);ibuffer++)
{
if((ip[ibuffer]!='\n')&&(ip[ibuffer]!='\0'))
{
NetTemp[ibuffer] = ip[ibuffer];
}
else
{
break;
}
}
if(!ibuffer)
{
printf("init ip: %s\n");
NetTemp[0]='0';
NetTemp[1]='.';
NetTemp[2]='0';
NetTemp[3]='.';
NetTemp[4]='0';
NetTemp[5]='.';
NetTemp[6]='0';
NetTemp[7]='\0';
}
longaddr.s_addr = inet_addr(NetTemp);
*sendbuf++ = (longaddr.s_addr&0xff);
*sendbuf++ = ((longaddr.s_addr>>8)&0xff);
*sendbuf++ = ((longaddr.s_addr>>16)&0xff);
*sendbuf++ = ((longaddr.s_addr>>24)&0xff);
*sendbuf++ = ',';
}
//get the subnet mask of this interface
if (!ioctl(socket_fd,SIOCGIFNETMASK, &buf[if_i]))
{
memset(subnetMask,0,sizeof(subnetMask));
snprintf(subnetMask, sizeof(subnetMask), "%s",(char *)inet_ntoa(((struct sockaddr_in *)&(buf[if_i].ifr_netmask))->sin_addr));
memset(NetTemp,0,sizeof(NetTemp));
for(ibuffer=0;ibuffer<sizeof(subnetMask);ibuffer++)
{
if((subnetMask[ibuffer]!='\n')&&(subnetMask[ibuffer]!='\0'))
{
NetTemp[ibuffer] = subnetMask[ibuffer];
}
else
{
break;
}
}
if(!ibuffer)
{
NetTemp[0]='0';
NetTemp[1]='.';
NetTemp[2]='0';
NetTemp[3]='.';
NetTemp[4]='0';
NetTemp[5]='.';
NetTemp[6]='0';
NetTemp[7]='\0';
}
longaddr.s_addr = inet_addr(NetTemp);
*sendbuf++ = (longaddr.s_addr&0xff);
*sendbuf++ = ((longaddr.s_addr>>8)&0xff);
*sendbuf++ = ((longaddr.s_addr>>16)&0xff);
*sendbuf++ = ((longaddr.s_addr>>24)&0xff);
*sendbuf++ = ',';
}
//get the gateway of this interface
memset(query_cmd,0,sizeof(query_cmd));
sprintf(query_cmd,"route | grep %s | tail -1 | awk {'print $1'} > ./gateway",buf[if_i].ifr_name);
system(query_cmd);
query_fd = fopen("./gateway", "r+");
if(!query_fd)
{
printf("open %s fail !!!\n","./gateway");
exit(0);
}
while(!feof(query_fd))
{
fread(buffer, sizeof(buffer),1,query_fd);
}
fclose(query_fd);
memset(NetTemp,0,sizeof(NetTemp));
for(ibuffer=0;ibuffer<sizeof(buffer);ibuffer++)
{
if((buffer[ibuffer]!='\n')&&(buffer[ibuffer]!='\0'))
{
NetTemp[ibuffer] = buffer[ibuffer];
}
else
{
break;
}
}
if(!ibuffer)
{
NetTemp[0]='0';
NetTemp[1]='.';
NetTemp[2]='0';
NetTemp[3]='.';
NetTemp[4]='0';
NetTemp[5]='.';
NetTemp[6]='0';
NetTemp[7]='\0';
}
longaddr.s_addr = inet_addr(NetTemp);
*sendbuf++ = (longaddr.s_addr&0xff);
*sendbuf++ = ((longaddr.s_addr>>8)&0xff);
*sendbuf++ = ((longaddr.s_addr>>16)&0xff);
*sendbuf++ = ((longaddr.s_addr>>24)&0xff);
*sendbuf++ = ',';
//get the mac of this interface
if (!ioctl(socket_fd, SIOCGIFHWADDR, (char *)(&buf[if_i])))
{
memset(mac, 0, sizeof(mac));
snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x",
(unsigned char)buf[if_i].ifr_hwaddr.sa_data[0],
(unsigned char)buf[if_i].ifr_hwaddr.sa_data[1],
(unsigned char)buf[if_i].ifr_hwaddr.sa_data[2],
(unsigned char)buf[if_i].ifr_hwaddr.sa_data[3],
(unsigned char)buf[if_i].ifr_hwaddr.sa_data[4],
(unsigned char)buf[if_i].ifr_hwaddr.sa_data[5]);
}
*sendbuf++ = (unsigned char)buf[if_i].ifr_hwaddr.sa_data[0];
*sendbuf++ = (unsigned char)buf[if_i].ifr_hwaddr.sa_data[1];
*sendbuf++ = (unsigned char)buf[if_i].ifr_hwaddr.sa_data[2];
*sendbuf++ = (unsigned char)buf[if_i].ifr_hwaddr.sa_data[3];
*sendbuf++ = (unsigned char)buf[if_i].ifr_hwaddr.sa_data[4];
*sendbuf++ = (unsigned char)buf[if_i].ifr_hwaddr.sa_data[5];
*sendbuf++ = ',';
//get the broad address of this interface
if (!ioctl(socket_fd,SIOCGIFBRDADDR, &buf[if_i]))
{
snprintf(broadAddr, sizeof(broadAddr), "%s",(char *)inet_ntoa(((struct sockaddr_in *)&(buf[if_i].ifr_broadaddr))->sin_addr));
}
}
*sendbuf++ = 'O';
*sendbuf++ = 'K';
*sendbuf++ = '\0';
}
close(socket_fd);
}
int SetIp(const char *szIpaddr, char * netif_name)
{
int sock_set_ip=0;
char query_cmd[128]= {'\0'};
struct sockaddr_in sin_set_ip;
struct ifreq ifr_set_ip;
bzero( &ifr_set_ip,sizeof(ifr_set_ip));
if( szIpaddr == NULL )
{
printf("socket ipaddr...SetLocalIp!\n");
}
if((sock_set_ip = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("socket create failse...SetLocalIp!\n");
}
printf("get ip:%s\n",szIpaddr);
memset( &sin_set_ip, 0, sizeof(sin_set_ip));
strncpy(ifr_set_ip.ifr_name, netif_name, strlen(netif_name));
sin_set_ip.sin_family = AF_INET;
sin_set_ip.sin_addr.s_addr = inet_addr(szIpaddr);
memcpy( &ifr_set_ip.ifr_addr, &sin_set_ip, sizeof(sin_set_ip));
if( ioctl( sock_set_ip, SIOCSIFADDR, &ifr_set_ip) < 0 )
{
printf( "SetIp SIOCSIFADDR error\n");
}
//设置激活标志
ifr_set_ip.ifr_flags |= IFF_UP |IFF_RUNNING;
//get the status of the device
if( ioctl( sock_set_ip, SIOCSIFFLAGS, &ifr_set_ip ) < 0 )
{
printf("SetIp SIOCSIFFLAGS error\n");
}
else
{
sprintf(query_cmd,"sed -i '/ip:%s/'d /usrinit/netset.sh",netif_name);
system(query_cmd);
sprintf(query_cmd,"echo ip:\"%s %s\" >> /usrinit/netset.sh",netif_name,szIpaddr);
system(query_cmd);
}
close(sock_set_ip);
return 0;
}
int SetNetMask(const char *szNetMask,char * netif_name)
{
int sock_set_mask=0;
char query_cmd[128]= {'\0'};
struct sockaddr_in sin_set_mask;
struct ifreq ifr_set_mask;
bzero( &ifr_set_mask,sizeof(ifr_set_mask));
if( szNetMask == NULL )
{
printf("socket szNetMask...SetNetMask!\n");
}
if((sock_set_mask = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("socket create failse...SetNetMask!\n");
}
printf("get mask:%s\n",szNetMask);
memset( &sin_set_mask, 0, sizeof(sin_set_mask));
strncpy(ifr_set_mask.ifr_name, netif_name, strlen(netif_name));
sin_set_mask.sin_family = AF_INET;
sin_set_mask.sin_addr.s_addr = inet_addr(szNetMask);
memcpy( &ifr_set_mask.ifr_addr, &sin_set_mask, sizeof(sin_set_mask));
if( ioctl( sock_set_mask, SIOCSIFNETMASK, &ifr_set_mask) < 0 )
{
printf( "SetNetMask ioctl error\n");
}
else
{
sprintf(query_cmd,"sed -i '/mask:%s/'d /usrinit/netset.sh",netif_name);
system(query_cmd);
sprintf(query_cmd,"echo mask:\"%s %s\" >> /usrinit/netset.sh",netif_name,szNetMask);
system(query_cmd);
}
close(sock_set_mask);
return 0;
}
int SetGateWay(const char *szGateWay,char * netif_name)
{
int sock_gateway=0;
struct sockaddr_in sin_net_gateway;
struct rtentry rt;
sock_gateway = socket( AF_INET, SOCK_DGRAM, 0 );
if( sock_gateway == -1)
{
printf("Not create network socket connect\n");
}
printf("get gateWay:%s\n",szGateWay);
memset(&rt, 0, sizeof(struct rtentry));
memset(&sin_net_gateway, 0, sizeof(struct sockaddr_in));
sin_net_gateway.sin_family = AF_INET;
sin_net_gateway.sin_port = 0;
sin_net_gateway.sin_addr.s_addr = inet_addr(szGateWay);
memcpy ( &rt.rt_gateway, &sin_net_gateway, sizeof(struct sockaddr_in));
((struct sockaddr_in *)&rt.rt_dst)->sin_family=AF_INET;
((struct sockaddr_in *)&rt.rt_genmask)->sin_family=AF_INET;
rt.rt_flags |= RTF_GATEWAY;
rt.rt_dev = netif_name;
if(ioctl(sock_gateway, SIOCADDRT, &rt ) < 0)
{
printf("SetGateWay ioctl error\n");
}
close(sock_gateway);
return 0;
}
void udp_serrecv(int sock)
{
char* pSave = NULL;
char *pChar = ",";
char cCharNum = 0;
char temp_buf[255];
char recvbuf[255];
char sendbuf[1024];
int n;
char netif_i = 0;
char ethif_cnt = 0;
char ethif_name[8] = {'\0'};
char query_cmd[128]= {'\0'};
struct sockaddr_in peeraddr;
struct sockaddr_in cliaddr;
socklen_t peerlen;
socklen_t clilen;
memset(&cliaddr,0,sizeof(cliaddr));
cliaddr.sin_family = AF_INET;
cliaddr.sin_port = htons(8000);
cliaddr.sin_addr.s_addr =inet_addr("255.255.255.255");
clilen = sizeof(cliaddr);
/***************************************************************************/
while(1)
{
peerlen = sizeof(peeraddr);
memset(recvbuf,0,sizeof(recvbuf));
printf("wait:udp\n");
n = recvfrom(sock,recvbuf,sizeof(recvbuf),0,(struct sockaddr*)&peeraddr,&peerlen);
if(n == -1)
{
if(errno == EINTR)
{
continue;
}
printf("recvfrom error\n");
}
else if(n > 0)
{
int ret = 0;
printf("recvfrom:%s\n",recvbuf);
if(!strncmp(recvbuf,"$CGBCX",strlen("$CGBCX")))
{
memset(sendbuf,0,sizeof(sendbuf));
sendbuf[0]='$';
sendbuf[1]='S';
sendbuf[2]='G';
sendbuf[3]='B';
sendbuf[4]='C';
sendbuf[5]='X';
sendbuf[6]='A';
sendbuf[7]='C';
sendbuf[8]='K';
sendbuf[9]=',';
memset(temp_buf,0,sizeof(temp_buf));
sprintf(temp_buf,"%d",devnum);
strncpy(&sendbuf[10],temp_buf,strlen(temp_buf));
sendbuf[20]=',';
//eth* cnt
get_interface(&sendbuf[21]);
int buf_i = 0;
int str_len = 0;
for(buf_i=0;buf_i<1024;buf_i++)
{
str_len++;
if((sendbuf[buf_i]=='O')&&(sendbuf[buf_i+1]=='K'))
{
str_len++;
break;
}
}
int net_i=0;
for(net_i=0;net_i<interfaceNum;net_i++)
{
memset(query_cmd,0,sizeof(query_cmd));
/*add route*/
sprintf(query_cmd,"route add -host 255.255.255.255 dev %s",buf[net_i].ifr_name);
system(query_cmd);
/*udp send*/
ret = sendto(sock,sendbuf,str_len,0,(struct sockaddr*)&cliaddr,clilen);
if(ret < 0)
{
printf("sendto err,lsh\n");
}
/*del route*/
sprintf(query_cmd,"route del -host 255.255.255.255 dev %s",buf[net_i].ifr_name);
system(query_cmd);
}
}
else if(!strncmp(recvbuf,"$CGBSET",strlen("$CGBSET")))
{
NetworkParamSet * p_NetSetHead = NULL;
NetworkParamSingle * p_NetSetParam = NULL;
char * p_recvbuf = &recvbuf[0];
memcpy(temp_buf,p_recvbuf,sizeof(NetworkParamSet));
p_recvbuf += sizeof(NetworkParamSet);
p_NetSetHead = (NetworkParamSet *)(temp_buf);
struct sockaddr_in sin_new;
int netif_cnt=0;
netif_cnt = (atoi(p_NetSetHead->MacCount));
int devnum_tmp=0;
devnum_tmp = (atoi(p_NetSetHead->devnum));
if(devnum_tmp != devnum)
{
continue;
}
char setif_i = 0;
unsigned int net_value = 0;
for(setif_i=0;setif_i<netif_cnt;setif_i++)
{
memcpy(temp_buf,p_recvbuf,sizeof(NetworkParamSingle));
p_recvbuf += sizeof(NetworkParamSingle);
p_NetSetParam = (NetworkParamSingle *)(temp_buf);
//set ip/
memset(&sin_new, 0, sizeof(sin_new));
net_value = 0;
net_value |= ((ntohl((uint32_t)p_NetSetParam->ipAddr))&0xff)<<24;
net_value |= (((ntohl((uint32_t)p_NetSetParam->ipAddr))>>8)&0xff)<<16;
net_value |= (((ntohl((uint32_t)p_NetSetParam->ipAddr))>>16)&0xff)<<8;
net_value |= (((ntohl((uint32_t)p_NetSetParam->ipAddr))>>24)&0xff)<<0;
sin_new.sin_addr.s_addr = net_value;
SetIp(inet_ntoa(sin_new.sin_addr),p_NetSetParam->ethName);
//set mask//
memset(&sin_new, 0, sizeof(sin_new));
net_value = 0;
net_value |= ((ntohl((uint32_t)p_NetSetParam->netmask))&0xff)<<24;
net_value |= (((ntohl((uint32_t)p_NetSetParam->netmask))>>8)&0xff)<<16;
net_value |= (((ntohl((uint32_t)p_NetSetParam->netmask))>>16)&0xff)<<8;
net_value |= (((ntohl((uint32_t)p_NetSetParam->netmask))>>24)&0xff)<<0;
sin_new.sin_addr.s_addr = net_value;
SetNetMask(inet_ntoa(sin_new.sin_addr),p_NetSetParam->ethName);
//set gateway/
memset(&sin_new, 0, sizeof(sin_new));
net_value = 0;
net_value |= ((ntohl((uint32_t)p_NetSetParam->gateway))&0xff)<<24;
net_value |= (((ntohl((uint32_t)p_NetSetParam->gateway))>>8)&0xff)<<16;
net_value |= (((ntohl((uint32_t)p_NetSetParam->gateway))>>16)&0xff)<<8;
net_value |= (((ntohl((uint32_t)p_NetSetParam->gateway))>>24)&0xff)<<0;
sin_new.sin_addr.s_addr = net_value;
SetGateWay(inet_ntoa(sin_new.sin_addr),p_NetSetParam->ethName);
}
}
}
}
}
int main(void)
{
char query_cmd[128]= {'\0'};
char buffer[35] = {'\0'}; ;
int sock;
int i, skfd, ret;
const int opt = 1;
int socket_fd;
FILE *query_fd;
if((sock = socket(AF_INET,SOCK_DGRAM,0)) < 0)
{
printf("socket error \n");
}
struct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8000);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sock,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
{
printf("socket error \n");
}
ret = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&opt, sizeof(opt));
if (ret == -1)
{
printf("setsockopt error\n");
}
sprintf(query_cmd,"mkdir /usrinit");
//get the gateway of this interface
memset(query_cmd,0,sizeof(query_cmd));
sprintf(query_cmd,"cat /usrinit/netset.sh | grep devnum |head -1 | tail -1 | sed 's/devnum=//g' > ./devnum.log");
system(query_cmd);
query_fd = fopen("./devnum.log", "r+");
if(!query_fd)
{
printf("open %s fail !!!\n","./devnum.log");
exit(0);
}
while(!feof(query_fd))
{
fread(buffer, sizeof(buffer),1,query_fd);
}
fclose(query_fd);
if(strlen(buffer)<5)
{
srand((unsigned)time( NULL ));
devnum = (unsigned int)rand();
if(devnum==0)
{
printf("srand error \n");
}
sprintf(query_cmd,"echo devnum=\"%d\" > /usrinit/netset.sh",devnum);
system(query_cmd);
}
else
{
devnum = atoi(buffer);
}
printf("devnum:%d\n",devnum);
udp_serrecv(sock);
return 0;
}