嵌入式 hi3518平台以太网网络模块设计包括重连机制和网线检测机制

来源:互联网 发布:杭州瀚诚网络 编辑:程序博客网 时间:2024/05/16 12:53
<span style="font-family:Courier New;">#include <sys/types.h>  #include <string.h>  #include <stdlib.h>  #include <sys/ioctl.h>  #include <sys/stat.h>  #include <stdio.h>  #include <string.h>  #include <errno.h>  #include <net/if.h>  #include <sys/utsname.h>  #include <limits.h>  #include <ctype.h>     #include <sys/socket.h>  #include <arpa/inet.h>     #include <linux/sockios.h>  #include <sys/socket.h>   #include <netinet/ip.h>   #include <netinet/ip_icmp.h>   #include <netdb.h>  #include <netinet/in.h>#define JOSEPH_LOOP_INTERFACE "lo"#define JOSEPH_ETH_INTERFACE "eth0"#define JOSEPH_WIRLESS_INTERFACE "wlan0"#define ETHTOOL_GLINK   0x0000000a   /* Get link status (ethtool_value) */  #define JSOEPH_NET_CHECK_PACKET_SIZE    4096   #define JOSEPH_NET_CHECK_TIME3000typedef struct Joseph_Net_Interface_Info{int net_device_type;// 0 ~ eth0 ; 1 ~ wlan ;3 ~ ppp0int net_device_priority;// 0 ~ eth0 ; 1 ~ wlan ;3 ~ ppp0intnet_device_status;//0 ~ down; 1 ~ upint net_device_link_status;//0 ~ no ;1 ~ yeschar net_device_name[8];char net_device_ip[16];char net_device_mac_info[32];char net_device_gw_info[16];char net_device_mask_info[16];char net_device_broadcast_info[16];}JOSEPH_NET_INTERFACE_INFO;typedef struct Joseph_Ethtool_Value {  unsigned int   cmd;  unsigned int   data;   }JOSEPH_ETHTOOL_VALUE;enum Joseph_Net_Device_Type{JOSEPH_ETH = 0,JOSEPH_WIFI = 1,JOSEPH_3G = 2,}JOSEPH_NET_DEVICE_TYPE;unsigned short Joseph_Cal_Chksum(unsigned short *addr, int len){  int nleft=len;  int sum=0;  unsigned short *w=addr;  unsigned short answer=0;while(nleft > 1){    sum += *w++;  nleft -= 2;  }  if( nleft == 1)  {   *(unsigned char *)(&answer) = *(unsigned char *)w;    sum += answer;  }  sum = (sum >> 16) + (sum & 0xffff);  sum += (sum >> 16);  answer = ~sum;  return answer;  }  int Joseph_Ping( char *ips,char *srcip , int timeout){    int n;pid_t pid;int maxfds = 0; fd_set readfds; struct ip *iph; struct icmp *icmp;struct timeval *tval;  struct sockaddr_in addr;  struct sockaddr_in from;struct ifreq ifr;bzero(&addr,sizeof(addr));addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr(ips);int sockfd; sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (sockfd < 0) {      printf("ip:%s,socket error\n",ips);   return -1;    }    struct timeval timeo;timeo.tv_sec = timeout / 1000;timeo.tv_usec = timeout % 1000; #if 0/*set src ip*/bzero(&from,sizeof(from));/* 设定Ip信息 */from.sin_family = AF_INET;from.sin_addr.s_addr = inet_addr(srcip);if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF,(struct sockaddr *)&from, sizeof(from)) == -1)    {      printf("ip:%s,setsockopt error \n",srcip);   return ERROR;}  bind(sockfd,(struct sockaddr *)&addr, sizeof(addr));#elsestrcpy(ifr.ifr_name, srcip);if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1){printf("can't bind to interface %s\n",ifr.ifr_name);}#endifif (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo)) == -1)    {    printf("ip:%s,setsockopt error\n",ips); return -1;    }else{;}char sendpacket[JSOEPH_NET_CHECK_PACKET_SIZE];    char recvpacket[JSOEPH_NET_CHECK_PACKET_SIZE];    memset(sendpacket, 0, sizeof(sendpacket)); pid = getpid();   icmp=(struct icmp*)sendpacket; icmp->icmp_type = ICMP_ECHO;icmp->icmp_code = 0;icmp->icmp_cksum = 0; icmp->icmp_seq = 0;    icmp->icmp_id = pid;   tval = (struct timeval *)icmp->icmp_data;  gettimeofday(tval,NULL);  icmp->icmp_cksum=Joseph_Cal_Chksum((unsigned short *)icmp,sizeof(struct icmp));n = sendto(sockfd, (char *)&sendpacket, sizeof(struct icmp), 0, (struct sockaddr *)&addr, sizeof(addr));  if (n < 1){    printf("ip:%s,sendto error\n",ips); return -1;    }     while(1) {      FD_ZERO(&readfds);  FD_SET(sockfd, &readfds);      maxfds = sockfd + 1;    n = select(maxfds, &readfds, NULL, NULL, &timeo);      if (n <= 0)   {      printf("ip:%s,Time out error\n",ips);      close(sockfd);  return -1;      }      memset(recvpacket, 0, sizeof(recvpacket));  int fromlen = sizeof(from);  n = recvfrom(sockfd, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)&from, (socklen_t *)&fromlen);      if (n < 1)  {    return -1;  }      char *from_ip = (char *)inet_ntoa(from.sin_addr);    if (strcmp(from_ip,ips) != 0)   {      printf("NowPingip:%s Fromip:%s\nNowPingip is not same to Fromip,so Joseph_Ping wrong!\n",ips,from_ip);   continue;    }      iph = (struct ip *)recvpacket;  icmp = (struct icmp *)(recvpacket + (iph->ip_hl << 2));  if (icmp->icmp_type == ICMP_ECHOREPLY && icmp->icmp_id == pid)  return 0;  else   continue; } return 0;}  int Joseph_Check_Net_Status(char *if_name)  {  int Qy_Ret = 0;if(strlen(if_name) <= 0){Qy_Ret = -1;return Qy_Ret;}char aPing[16]="202.108.22.5";/* Joseph_Ping form ip  */if(Joseph_Ping(aPing,if_name,JOSEPH_NET_CHECK_TIME) == 0)  {  printf("Network is Ok!\n"); Qy_Ret = 0;}  else{  printf("Network is Bad!\n");Qy_Ret = -1;}return Qy_Ret;}/*Author : kjTime : 2014-08-09Function :get ip gw mac broadcast*/int Joseph_Get_Net_Device_Info(JOSEPH_NET_INTERFACE_INFO *Joseph_Net_Interface_Info_In){int Qy_Ret = 0;int device_itertion = 0;int Joseph_Net_Interface_Sfd = 0;int Joseph_Net_Interface_exist = 0;struct ifreq Joseph_Net_Ifr;struct ifconf Joseph_Ifc;struct sockaddr_in *sin = (struct sockaddr_in*)&Joseph_Net_Ifr.ifr_addr;struct sockaddr_in *broadcast = (struct sockaddr_in*)&Joseph_Net_Ifr.ifr_broadaddr;if(Joseph_Net_Interface_Info_In == NULL){Qy_Ret = -1;return Qy_Ret;}Joseph_Net_Interface_Sfd = socket(AF_INET,SOCK_DGRAM,0);if(Joseph_Net_Interface_Sfd < 0){perror("socket error");return -1;}memset(&Joseph_Net_Ifr,0,sizeof(Joseph_Net_Ifr));Joseph_Ifc.ifc_len = sizeof(Joseph_Net_Ifr);Joseph_Ifc.ifc_buf = (caddr_t)&Joseph_Net_Ifr;for(device_itertion = 1;device_itertion < 5;device_itertion++){Joseph_Net_Ifr.ifr_ifindex = device_itertion;Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFNAME,&Joseph_Net_Ifr);if(Qy_Ret){Joseph_Net_Interface_exist = 0;}else{if(strcmp(Joseph_Net_Ifr.ifr_name,Joseph_Net_Interface_Info_In->net_device_name) == 0){printf("The %dst net device is : %s\n",Joseph_Net_Ifr.ifr_ifindex,Joseph_Net_Ifr.ifr_name);Joseph_Net_Interface_exist = 1;/*Judge card type of net device*/Qy_Ret = ioctl (Joseph_Net_Interface_Sfd, SIOCGIFFLAGS,&Joseph_Net_Ifr);if(!Qy_Ret){/*judge the status of net device*/if (Joseph_Net_Ifr.ifr_flags & IFF_UP){puts("the interface status is UP");}else{puts("the interface status is DOWN");}}break;}}}if(Joseph_Net_Interface_exist == 0){printf("%s:[%d] No Such Device of %s !\n",__FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_name);return -1;}/*get net device mac addr*/Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFHWADDR,&Joseph_Net_Ifr);if(!Qy_Ret){sprintf(Joseph_Net_Interface_Info_In->net_device_mac_info,"%02x:%02x:%02x:%02x:%02x:%02x",\(unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[0],\(unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[1],\(unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[2],\(unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[3],\(unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[4],\(unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[5]);printf("Mac address is : %02x:%02x:%02x:%02x:%02x:%02x\n",\(unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[0],\(unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[1],\(unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[2],\(unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[3],\(unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[4],\(unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[5]);}else{printf("Mac address is : 00:00:00:00:00:00\n");}/*get net device ip */memset(Joseph_Net_Interface_Info_In->net_device_ip,0,16);Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFADDR,&Joseph_Net_Ifr);if(!Qy_Ret){inet_ntop(AF_INET,&sin->sin_addr.s_addr,Joseph_Net_Interface_Info_In->net_device_ip,16);printf("IP address is : %s\n",Joseph_Net_Interface_Info_In->net_device_ip);}else{printf("IP address is : 0.0.0.0\n");}/*get broadcast addr*/memset(Joseph_Net_Interface_Info_In->net_device_broadcast_info,0,16);Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFBRDADDR,&Joseph_Net_Ifr);if(!Qy_Ret){inet_ntop(AF_INET,&broadcast->sin_addr.s_addr,Joseph_Net_Interface_Info_In->net_device_broadcast_info,16);printf("BROADCAST IP is : %s\n",Joseph_Net_Interface_Info_In->net_device_broadcast_info);}else{printf("BROADCAST IP is : 0.0.0.0\n");}/*get mask info*/Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFNETMASK,&Joseph_Net_Ifr);if (!Qy_Ret){  inet_ntop(AF_INET,&sin->sin_addr.s_addr,Joseph_Net_Interface_Info_In->net_device_mask_info,16);printf("NetMask is : %s\n",Joseph_Net_Interface_Info_In->net_device_mask_info); }  return Qy_Ret;}/****************************************************************    return value:     -1 -- error , details can check errno     1  -- interface link up     0  -- interface link down.  ****************************************************************/int Joseph_Get_Netlink_Status(const char *if_name)  {      int skfd;      struct ifreq ifr;      JOSEPH_ETHTOOL_VALUE edata;      edata.cmd = ETHTOOL_GLINK;      edata.data = 0;      memset(&ifr, 0, sizeof(ifr));      strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name) - 1);      ifr.ifr_data = (char *)&edata;      if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) == 0)          return -1;      if (ioctl(skfd, SIOCETHTOOL, &ifr) == -1)      {         close(skfd);              return -1;      }      close(skfd);      return edata.data;  }  int main(int argc,char *argv[]){int Qy_Ret = 0;JOSEPH_NET_INTERFACE_INFO Joseph_Net_Interface_Info;memset(&Joseph_Net_Interface_Info,0,sizeof(JOSEPH_NET_INTERFACE_INFO));if(argc < 2){Qy_Ret = -1;return Qy_Ret;}system("ifconfig eth0 up");sleep(3);strcpy(Joseph_Net_Interface_Info.net_device_name,argv[1]);Qy_Ret = Joseph_Get_Netlink_Status(argv[1]);if(Qy_Ret == 1){printf("%s:[%d] The netlink is up !\n",__FUNCTION__,__LINE__);}else{printf("%s:[%d] The netlink is down , Begin go to wifi !\n",__FUNCTION__,__LINE__);return -1;}NET_INIT:/*after 5s , if no ip ,then killall udhcpc ,then go to wifi*/system("killall -9 udhcpc");system("udhcpc -i eth0");Qy_Ret = Joseph_Check_Net_Status(argv[1]);if(Qy_Ret == 0){Joseph_Get_Net_Device_Info(&Joseph_Net_Interface_Info);}NET_RUN:while(1){Qy_Ret = Joseph_Get_Netlink_Status(argv[1]);if(Qy_Ret == 1){printf("Net link status: %s\n", Qy_Ret == 1 ? "up" : "down");Qy_Ret = Joseph_Check_Net_Status(argv[1]);if(Qy_Ret < 0){break;//do nothing}}else{printf("%s:[%d] The netlink is down !\n",__FUNCTION__,__LINE__);}sleep(1);}goto NET_INIT;return Qy_Ret;}</span>

0 0
原创粉丝点击