嵌入式 指定网卡名称的信息以及网络连通状态以及重连机制代码示例

#include <fcntl.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <signal.h>
#include <dirent.h>
#include <pthread.h>

#include <asm/types.h>
#include <arpa/inet.h>

#include <sys/vfs.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/utsname.h>

#include <netdb.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/route.h>
#include <net/if_arp.h>
 
#include <linux/sockios.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ether.h>
#include <netinet/ip_icmp.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_TIME 6000
#define JSOEPH_NET_RMSG_BUFSIZE 8192

typedef struct Joseph_Ethtool_Value {
 unsigned int cmd;
 unsigned int data;
}JOSEPH_ETHTOOL_VALUE;

typedef struct route_info{
 struct in_addr dstAddr;
 struct in_addr srcAddr;
 struct in_addr gateWay;
 char ifName[IF_NAMESIZE];
}JOSEPH_ROUTE_INFO;

#ifdef JOSEPH_CAT_ENUM
/* Routing message attributes */
enum rtattr_type_t {
 RTA_UNSPEC,
 RTA_DST,
 RTA_SRC,
 RTA_IIF,
 RTA_OIF,
 RTA_GATEWAY,
 RTA_PRIORITY,
 RTA_PREFSRC,
 RTA_METRICS,
 RTA_MULTIPATH,
 RTA_PROTOINFO, /* no longer used */
 RTA_FLOW,
 RTA_CACHEINFO,
 RTA_SESSION, /* no longer used */
 RTA_MP_ALGO, /* no longer used */
 RTA_TABLE,
 RTA_MARK,
 __RTA_MAX
};
#endif

typedef struct Joseph_Net_Interface_Info
{
 int net_device_type;// 0 ~ eth0 ; 1 ~ wlan ;3 ~ ppp0
 int net_device_priority;// 0 ~ eth0 ; 1 ~ wlan ;3 ~ ppp0
 int net_device_status;//0 ~ down; 1 ~ up
 int net_device_link_status;//0 ~ no ;1 ~ yes
 char net_device_name[8];
 char net_device_ip[16];
 char net_device_lan_dst[16];//dstaddr in route table
 char net_device_internet_dst[16];//dstaddr in route table
 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;


/*joseph check net link status*/
enum Joseph_Net_Device_Type
{
 JOSEPH_ETH = 0,
 JOSEPH_WIFI = 1,
 JOSEPH_3G = 2,
}JOSEPH_NET_DEVICE_TYPE;

#include "joseph_av_common.h"

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;
}

/*
Author : kj
Timer: 2014-08-14
Function :
 0 ~ allow ping int area of Lan and Internet
 1 ~ forbit ping int area of Lan and Internet
*/
int Joseph_Net_Icmp_Control(char *value)
{
 int Qy_Ret = JOSEPH_RET_OK;
 int Joseph_Icmp_Value = 0;
 
 if(strlen(value) != 1)
 {
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }

 Joseph_Icmp_Value = atoi(value);
 switch(Joseph_Icmp_Value)
 {
  case 0:
   {
    system("echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all");
    break;
   }
  case 1:
   {
    system("echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all");
    break;
   }
  default:
   {
    Qy_Ret = JOSEPH_RET_ERR1;
    break;
   }

 }
 
 return Qy_Ret;
}

int Joseph_Ping( char *ips,char *srcip , int timeout)
{

 int n;

 pid_t pid;
 int maxfds = 0;
 fd_set readfds;

 struct ip *iph;
 struct ifreq ifr;
 struct icmp *icmp;
 struct timeval *tval;
 struct timeval timeo;
 struct sockaddr_in addr;
 struct sockaddr_in from;

 int Qy_Ret = JOSEPH_RET_OK;
 
 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)
 {
   joseph_personal_eth_print("%s:[%d] Socket Create Error ,The Src Ip is %s !\n",\
    __FUNCTION__,__LINE__,ips);
   
   Qy_Ret = JOSEPH_RET_ERR1;
   return Qy_Ret;
 }


 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));
#else

 strcpy(ifr.ifr_name, srcip);
 if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
 {
  joseph_personal_eth_print("%s:[%d] Can't Bind To Interface %s !\n",\
   __FUNCTION__,__LINE__,ifr.ifr_name);
 
  close(sockfd);
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }
 
#endif

 if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo)) == -1)
 {
  joseph_personal_eth_print("%s:[%d] Setsockopt Error ,Ip is %s !\n",\
   __FUNCTION__,__LINE__,ips);
 
  close(sockfd);
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }
 else
 {
  ;
 }

 char sendpacket[JSOEPH_NET_CHECK_PACKET_SIZE];
 char recvpacket[JSOEPH_NET_CHECK_PACKET_SIZE];

 memset(sendpacket, 0, sizeof(sendpacket));

#if 1

 pid = getpid();
#else

 pthread_t pthread_self();
#endif
 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)
 {
  joseph_personal_eth_print("%s:[%d] Sendto Error ,Ip is %s !\n",\
   __FUNCTION__,__LINE__,ips);
 
  close(sockfd);
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }
   
 while(1)
 {
   FD_ZERO(&readfds);
   FD_SET(sockfd, &readfds);
   maxfds = sockfd + 1;
   n = select(maxfds, &readfds, NULL, NULL, &timeo);
   if (n <= 0)
   {
    joseph_personal_eth_print("%s:[%d] Time Out Error ,Ip is %s !\n",\
     __FUNCTION__,__LINE__,ips);
   
    close(sockfd);
    Qy_Ret = JOSEPH_RET_ERR1;
    return Qy_Ret;
   }
 
   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)
   {
    close(sockfd);
    Qy_Ret = JOSEPH_RET_ERR1;
    return Qy_Ret;
   }
   
   char *from_ip = (char *)inet_ntoa(from.sin_addr);
   if (strcmp(from_ip,ips) != 0)
   {
    joseph_personal_eth_print("%s:[%d] Now Pingip: %s Fromip: %s ,That is not same to Fromip,So Wrong !\n",\
     __FUNCTION__,__LINE__,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)
   {
    close(sockfd);
  Qy_Ret = JOSEPH_RET_OK;
  return Qy_Ret;
   }
   else
    continue;
 }

 close(sockfd);

 return Qy_Ret;
}
 
int Joseph_Check_Net_Status(char *if_name)
{
 int Qy_Ret = JOSEPH_RET_OK;
 if(strlen(if_name) <= 0)
 {
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }

#if 0
 char aPing[16]="202.108.22.5"; /* Joseph_Ping form ip */
#else
 char aPing[16]="114.114.114.114"; /* Joseph_Ping form ip */
#endif
 if(Joseph_Ping(aPing,if_name,JOSEPH_NET_CHECK_TIME) == 0)
 {
  joseph_personal_eth_print("%s:[%d] Network is Ok!\n",__FUNCTION__,__LINE__);
  Qy_Ret = JOSEPH_RET_OK;
 }
 else
 {
  joseph_personal_eth_print("%s:[%d] Network is Bad!\n",__FUNCTION__,__LINE__);
  Qy_Ret = JOSEPH_RET_ERR1;
 }

 return Qy_Ret;
}


/*
Author : kj
Time : 2014-08-09
Function :
 get ip gw mac broadcast
*/
int Joseph_Get_Net_Device_Info(JOSEPH_NET_INTERFACE_INFO *Joseph_Net_Interface_Info_In)
{
 int Qy_Ret = JOSEPH_RET_OK;
 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(STRLEN(Joseph_Net_Interface_Info_In->net_device_name) == 0)
 {
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }
 
 Joseph_Net_Interface_Sfd = socket(AF_INET,SOCK_DGRAM,0);
 if(Joseph_Net_Interface_Sfd < 0){
  joseph_personal_eth_print("%s:[%d] Socket Create Error !\n",__FUNCTION__,__LINE__);
  return JOSEPH_RET_ERR1;
 }
 
 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)
   {
    joseph_personal_eth_print("%s:[%d] The %dst net device is : %s !\n",\
     __FUNCTION__,__LINE__,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)
     {
      joseph_personal_eth_print("%s:[%d] The Interface Status Is UP !\n",\
       __FUNCTION__,__LINE__);
     
     }
     else
     {
      joseph_personal_eth_print("%s:[%d] The Interface Status Is DOWN !\n",\
       __FUNCTION__,__LINE__);
     }
    }
    break;
   }
  }

 }
 if(Joseph_Net_Interface_exist == 0)
 {
  joseph_personal_eth_print("%s:[%d] No Such Device of %s !\n",\
   __FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_name);
 
  close(Joseph_Net_Interface_Sfd);
  return -1;
 }


 /*get net device mac addr*/
 Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFHWADDR,&Joseph_Net_Ifr);
 if(!Qy_Ret)
 {
  MEMSET(Joseph_Net_Interface_Info_In->net_device_mac_info,32);
  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]);
 
  joseph_personal_eth_print("%s:[%d] Mac address is : %02x:%02x:%02x:%02x:%02x:%02x\n",\
   __FUNCTION__,__LINE__,\
   (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
 {
  joseph_personal_eth_print("%s:[%d] Mac address is : NULL !\n",__FUNCTION__,__LINE__);
 }

 /*get net device ip */
 Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFADDR,&Joseph_Net_Ifr);
 if(!Qy_Ret)
 {
  MEMSET(Joseph_Net_Interface_Info_In->net_device_ip,16);
  inet_ntop(AF_INET,&sin->sin_addr.s_addr,Joseph_Net_Interface_Info_In->net_device_ip,16);
  joseph_personal_eth_print("%s:[%d] IP address is : %s !\n",\
   __FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_ip);
 
 }else
 {
  joseph_personal_eth_print("%s:[%d] IP address is : NULL !\n",\
   __FUNCTION__,__LINE__);
 }

 /*get broadcast addr*/
 Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFBRDADDR,&Joseph_Net_Ifr);
 if(!Qy_Ret)
 {
  MEMSET(Joseph_Net_Interface_Info_In->net_device_broadcast_info,16);
  inet_ntop(AF_INET,&broadcast->sin_addr.s_addr,Joseph_Net_Interface_Info_In->net_device_broadcast_info,16);
  joseph_personal_eth_print("%s:[%d] BROADCAST IP is : %s !\n",\
   __FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_broadcast_info);
 }else
 {
  joseph_personal_eth_print("%s:[%d] BROADCAST IP is : NULL !\n",\
   __FUNCTION__,__LINE__);
 }

 /*get mask info*/
 Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFNETMASK,&Joseph_Net_Ifr);
 if (!Qy_Ret)
 {
  MEMSET(Joseph_Net_Interface_Info_In->net_device_mask_info,16);
  inet_ntop(AF_INET,&sin->sin_addr.s_addr,Joseph_Net_Interface_Info_In->net_device_mask_info,16);
  joseph_personal_eth_print("%s:[%d} NetMask is : %s !\n",\
   __FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_mask_info);
 }

 close(Joseph_Net_Interface_Sfd);
 return Qy_Ret;
}


int Joseph_ReadNlSock(int sockFd, char *bufPtr, int seqNum, int pId)
{
 struct nlmsghdr *nlHdr;
 int readLen = 0, msgLen = 0;

 do
 {
  /* Recieve response from the kernel */
  if((readLen = recv(sockFd, bufPtr, JSOEPH_NET_RMSG_BUFSIZE - msgLen, 0)) < 0){
   printf("SOCK READ Error !\n");
   return -1;
  }

  nlHdr = (struct nlmsghdr *)bufPtr;

  /* Check if the header is valid */
  if((NLMSG_OK(nlHdr, readLen) == 0) || (nlHdr->nlmsg_type == NLMSG_ERROR))
  {
   printf("Error in recieved packet !\n");
   return -1;
  }

  /* Check if the its the last message */
  if(nlHdr->nlmsg_type == NLMSG_DONE)
  {
   break;
  }
  else
  {
   /* Else move the pointer to buffer appropriately */
   bufPtr += readLen;
   msgLen += readLen;
  }

  /* Check if its a multi part message */
  if((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0)
  {
   /* return if its not */
   break;
  }
 } while((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId));
 
 return msgLen;
}


/* For printing the routes. */
void Joseph_PrintRoute(struct route_info *rtInfo,JOSEPH_NET_INTERFACE_INFO *Joseph_Net_Interface_Info_In)
{
 char Joseph_Zero_Addr[8] = "0.0.0.0";
 
 if(strcmp(rtInfo->ifName,Joseph_Net_Interface_Info_In->net_device_name) == 0)
 {
  /* Print Destination address */
  if(rtInfo->dstAddr.s_addr != 0)
  {
   MEMSET(Joseph_Net_Interface_Info_In->net_device_lan_dst,16);
   sprintf(Joseph_Net_Interface_Info_In->net_device_lan_dst,"%s",(char *)inet_ntoa(rtInfo->dstAddr));
  }
  else
  {
   MEMSET(Joseph_Net_Interface_Info_In->net_device_internet_dst,16);
   sprintf(Joseph_Net_Interface_Info_In->net_device_internet_dst,"%s",Joseph_Zero_Addr);
  }

  /* Print Gateway address */
  if(rtInfo->gateWay.s_addr != 0)
  {
   MEMSET(Joseph_Net_Interface_Info_In->net_device_gw_info,16);
   sprintf(Joseph_Net_Interface_Info_In->net_device_gw_info,"%s",(char *)inet_ntoa(rtInfo->gateWay));
  }

 }

}

/* For parsing the route info returned */
int Joseph_ParseRoutes(struct nlmsghdr *nlHdr,struct route_info *rtInfo,JOSEPH_NET_INTERFACE_INFO *Joseph_Net_Interface_Info_In)
{
 int Qy_Ret = JOSEPH_RET_OK;
 struct rtmsg *rtMsg;
 struct rtattr *rtAttr;
 int rtLen;
 char *tempBuf = NULL;

 tempBuf = (char *)malloc(100);
 rtMsg = (struct rtmsg *)NLMSG_DATA(nlHdr);

 /* If the route is not for AF_INET or does not belong to main routing table then return. */
 if((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN))
 {
  free(tempBuf);
  tempBuf = NULL;
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }


 /* get the rtattr field */
 rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
 rtLen = RTM_PAYLOAD(nlHdr);
 
 for(;RTA_OK(rtAttr,rtLen);rtAttr = RTA_NEXT(rtAttr,rtLen))
 {
  switch(rtAttr->rta_type)
  {
   case RTA_OIF:
    if_indextoname(*(int *)RTA_DATA(rtAttr), rtInfo->ifName);
    break;
   case RTA_GATEWAY:
    rtInfo->gateWay.s_addr = *(u_int *)RTA_DATA(rtAttr);
    break;
   case RTA_PREFSRC:
    rtInfo->srcAddr.s_addr = *(u_int *)RTA_DATA(rtAttr);
    break;
   case RTA_DST:
    rtInfo->dstAddr.s_addr = *(u_int *)RTA_DATA(rtAttr);
    break;
  }
 }

#if 0

 printf("%s\n", (char *)inet_ntoa(rtInfo->dstAddr));
 //ADDED BY BOB - ALSO COMMENTED Joseph_PrintRoute

 if (strstr((char *)inet_ntoa(rtInfo->dstAddr), "0.0.0.0"))
 {
  sprintf(gateway,"%s",(char *)inet_ntoa(rtInfo->gateWay));
 }
#endif

 Joseph_PrintRoute(rtInfo,Joseph_Net_Interface_Info_In);

 free(tempBuf);
 tempBuf = NULL;

 return Qy_Ret;
}

int Joseph_Get_Gateway(JOSEPH_NET_INTERFACE_INFO *Joseph_Net_Interface_Info_In)
{
 int Qy_Ret = JOSEPH_RET_OK;
 struct nlmsghdr *nlMsg;
 struct rtmsg *rtMsg;
 struct route_info *rtInfo;
 char msgBuf[JSOEPH_NET_RMSG_BUFSIZE];

 int sock, len, msgSeq = 0;

 if(strlen(Joseph_Net_Interface_Info_In->net_device_name) == 0 )
 {
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }
 
 /* Create Socket */
 if((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
 {
  joseph_personal_eth_print("%s:[%d] Socket Creation Error !\n",\
   __FUNCTION__,__LINE__);
 
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }
 
 /* Initialize the buffer */
 memset(msgBuf, 0, JSOEPH_NET_RMSG_BUFSIZE);

 /* point the header and the msg structure pointers into the buffer */
 nlMsg = (struct nlmsghdr *)msgBuf;
 rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);

 /* Fill in the nlmsg header*/
 nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
 nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
 nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump.
 nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet.
 nlMsg->nlmsg_pid = getpid(); // PID of process sending the request.

 /* Send the request */
 if(send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0)
 {
  joseph_personal_eth_print("%s:[%d] Write To Socket Failed ...\n",\
   __FUNCTION__,__LINE__);
 
  close(sock);
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }

 /* Read the response */
 if((len = Joseph_ReadNlSock(sock, msgBuf, msgSeq, getpid())) < 0)
 {
  joseph_personal_eth_print("%s:[%d] Read From Socket Failed ...\n",\
   __FUNCTION__,__LINE__);
 
  close(sock);
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }
 
 /* Parse and print the response */
 rtInfo = (struct route_info *)malloc(sizeof(struct route_info));
 
 /* THIS IS THE NETTSTAT -RL code I commented out the printing here and in parse routes */
 //fprintf(stdout, "Destination\tGateway\tInterface\tSource\n");

 for( ; NLMSG_OK(nlMsg,len); nlMsg = NLMSG_NEXT(nlMsg,len))
 {
  memset(rtInfo, 0, sizeof(struct route_info));
  Joseph_ParseRoutes(nlMsg,rtInfo,Joseph_Net_Interface_Info_In);
 }
 
 free(rtInfo);
 rtInfo = NULL;
 close(sock);

 return Qy_Ret;
}

/*
Author : kj
Timer : 2014-08-15
Function:
 del rt info of appoint net interface
Instruction:
 The net is exist ,before call the function interface
*/
int Joseph_Net_Del_Rt(char *if_name)
{
 int Qy_Ret = JOSEPH_RET_OK;
 char Cmd_Buf[BUF_LENGTH_512B] = {0};
 
 if(STRLEN(if_name) == 0)
 {
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }
 
 if(STRCMP(if_name,JOSEPH_ETH_INTERFACE) == 0)
 {
  /*get ip broadcast mask mac info*/
  Joseph_Get_Net_Device_Info(&Joseph_Net_Eth_Info);

  /*get gw landst internetdst info*/
  Joseph_Get_Gateway(&Joseph_Net_Eth_Info);

  /*route del ... dev eth0 rt */
  sprintf(Cmd_Buf,"route del -net %s gw %s dev %s;route del -net %s netmask %s dev %s",\
   Joseph_Net_Eth_Info.net_device_internet_dst,\
   Joseph_Net_Eth_Info.net_device_gw_info,\
   Joseph_Net_Eth_Info.net_device_name,\
   Joseph_Net_Eth_Info.net_device_lan_dst,\
   Joseph_Net_Eth_Info.net_device_mask_info,\
   Joseph_Net_Eth_Info.net_device_name);

  joseph_personal_eth_print("%s\n",Cmd_Buf);
  system(Cmd_Buf);
 }
 else if(STRCMP(if_name,JOSEPH_WIRLESS_INTERFACE) == 0)
 {
  /*get ip broadcast mask mac info*/
  Joseph_Get_Net_Device_Info(&Joseph_Net_Wlan_Info);

  /*get gw landst internetdst info*/
  Joseph_Get_Gateway(&Joseph_Net_Wlan_Info);
 
  /*route del ... dev wlan0 rt */
  sprintf(Cmd_Buf,"route del -net %s gw %s dev %s;route del -net %s netmask %s dev %s",\
   Joseph_Net_Wlan_Info.net_device_internet_dst,\
   Joseph_Net_Wlan_Info.net_device_gw_info,\
   Joseph_Net_Wlan_Info.net_device_name,\
   Joseph_Net_Wlan_Info.net_device_lan_dst,\
   Joseph_Net_Wlan_Info.net_device_mask_info,\
   Joseph_Net_Wlan_Info.net_device_name);

  joseph_personal_eth_print("%s\n",Cmd_Buf);
  system(Cmd_Buf);
 }
 
 return Qy_Ret;
}

int Joseph_Net_Interface_Info_Print(JOSEPH_NET_INTERFACE_INFO *Joseph_Net_Interface_Info_In)
{
 int Qy_Ret = JOSEPH_RET_OK;

 if(STRLEN(Joseph_Net_Interface_Info_In->net_device_name) == 0)
 {
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }

 joseph_personal_eth_print("%s:[%d] net_device_name is %s \n",\
  __FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_name);
 joseph_personal_eth_print("%s:[%d] net_device_ip is %s \n",\
  __FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_ip);
 joseph_personal_eth_print("%s:[%d] net_device_lan_dst is %s \n",\
  __FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_lan_dst);
 joseph_personal_eth_print("%s:[%d] net_device_internet_dst is %s \n",\
  __FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_internet_dst);
 joseph_personal_eth_print("%s:[%d] net_device_mask_info is %s \n",\
  __FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_mask_info);
 joseph_personal_eth_print("%s:[%d] net_device_mac_info is %s \n",\
  __FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_mac_info);
 joseph_personal_eth_print("%s:[%d] net_device_gw_info is %s \n",\
  __FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_gw_info);
 joseph_personal_eth_print("%s:[%d] net_device_broadcast_info is %s \n",\
  __FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_broadcast_info);


 return Qy_Ret;
}
int Joseph_Net_Get_Interface_Rt(JOSEPH_NET_INTERFACE_INFO *Joseph_Net_Interface_Info_In)
{
 int Qy_Ret = JOSEPH_RET_OK;

 if(STRLEN(Joseph_Net_Interface_Info_In->net_device_name) == 0)
 {
   Qy_Ret = JOSEPH_RET_ERR1;
   return Qy_Ret;
 }
   /*get ip broadcast mask mac info*/
 Qy_Ret = Joseph_Get_Net_Device_Info(Joseph_Net_Interface_Info_In);
 if(Qy_Ret <0)
 {
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }
 
 Qy_Ret = Joseph_Get_Gateway(Joseph_Net_Interface_Info_In);
 if(Qy_Ret <0)
 {
  Qy_Ret = JOSEPH_RET_ERR1;
  return Qy_Ret;
 }

 Joseph_Net_Interface_Info_Print(Joseph_Net_Interface_Info_In);

 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;
}

/*
Author : kj
Timer : 2014-08-14 20:08
Function:
 check eth0 link status

 0 ~ link
 1 ~ no link
*/
int Joseph_Net_Check_Eth_Link_Status(void)
{
 int Qy_Ret = JOSEPH_RET_OK;
 
 system("ifconfig eth0 up");
 sleep(3);

 Qy_Ret = Joseph_Get_Netlink_Status(JOSEPH_ETH_INTERFACE);
 if(Qy_Ret == 1)
 {
  Qy_Ret = JOSEPH_RET_OK;
 }
 else
 {
  Qy_Ret = JOSEPH_RET_ERR1;
 }

 return Qy_Ret;
}

int Joseph_EthNet_Udhcpc_Time(void)
{
 int Qy_Ret = 0;
 
 while(1)
 {
 
  if(joseph_ipnc_param.joseph_ipnc_network_attr.joseph_ipnc_eth_net_status == 0)
  {
   sleep(15);
   if(joseph_ipnc_param.joseph_ipnc_network_attr.joseph_ipnc_eth_udhcpc_kill == 1)
   {
    system("killall -9 udhcpc");
   }
  }
  else
  {
   sleep(1);
  }
 }
 
 return Qy_Ret;
}

int Joseph_EthNet_Udhcpc_Time_Pthread(void)
{
 int Qy_Ret = 0;

 char *param = NULL;
 run_pthread(&Joseph_EthNet_Udhcpc_Time,param);
 return Qy_Ret;
}

int Joseph_EthNet_Interface_Init(char *interface_name)
{
 int Qy_Ret = 0;

 JOSEPH_NET_INTERFACE_INFO Joseph_Net_Interface_Info;
 memset(&Joseph_Net_Interface_Info,0,sizeof(JOSEPH_NET_INTERFACE_INFO));

#if 0
 system("ifconfig eth0 up");
 sleep(3);
#endif

 if(strlen(interface_name) == 0)
 {
  Qy_Ret = -1;
  return Qy_Ret;
 }
 
 strcpy(Joseph_Net_Interface_Info.net_device_name,interface_name);

#if 1
 Qy_Ret = Joseph_Get_Netlink_Status(interface_name);
 if(Qy_Ret == 1)
 {
  joseph_personal_eth_print("%s:[%d] The netlink is up !\n",__FUNCTION__,__LINE__);
 }
 else
 {
  joseph_personal_eth_print("%s:[%d] The netlink is down , Begin go to wifi !\n",__FUNCTION__,__LINE__);
  return -1;
 }
#endif

 /*after 5s , if no ip ,then killall udhcpc ,then go to wifi*/
 Joseph_EthNet_Udhcpc_Time_Pthread();

NET_INIT:

 MEMSET(&Joseph_Net_Interface_Info,SIZEOF(JOSEPH_NET_INTERFACE_INFO));
 strcpy(Joseph_Net_Interface_Info.net_device_name,"eth0");
 system("killall -9 udhcpc");
 joseph_ipnc_param.joseph_ipnc_network_attr.joseph_ipnc_eth_net_status = 0;
 joseph_ipnc_param.joseph_ipnc_network_attr.joseph_ipnc_eth_udhcpc_kill = 1;
 system("udhcpc -i eth0");

 Qy_Ret = Joseph_Get_Net_Device_Info(&Joseph_Net_Interface_Info);
 if(STRLEN(Joseph_Net_Interface_Info.net_device_ip) > 0)
 {
  joseph_ipnc_param.joseph_ipnc_network_attr.joseph_ipnc_eth_udhcpc_kill = 0;
  MEMSET(joseph_ipnc_param.joseph_ipnc_server_attr.joseph_ipnc_network_attr.joseph_ipnc_ip_info,\
   JOSEPH_IPNC_SERVER_IP_MAX);
  sprintf(joseph_ipnc_param.joseph_ipnc_server_attr.joseph_ipnc_network_attr.joseph_ipnc_ip_info, \
   "%s",Joseph_Net_Interface_Info.net_device_ip);
 
  joseph_fill_broadcas_pack(NET_ETHERNET_NAME);
 }
 else if((Joseph_Get_Netlink_Status(interface_name)) == 1)
  goto NET_INIT;

 Qy_Ret = Joseph_Check_Net_Status(interface_name);
 if(Qy_Ret < 0)
 {
  ;//do nothing
 }
 else
 {
  joseph_ipnc_param.joseph_ipnc_network_attr.joseph_sys_connect_network = 1;
 }

 while(1)
 {
  Qy_Ret = Joseph_Get_Netlink_Status(interface_name);
  if(Qy_Ret == 1)
  {
   joseph_personal_eth_print("%s:[%d] Net link status: %s\n",\
    __FUNCTION__,__LINE__,Qy_Ret == 1 ? "up" : "down");
   
   Qy_Ret = Joseph_Check_Net_Status(interface_name);
   if(Qy_Ret < 0)
   {
    if(joseph_ipnc_param.joseph_ipnc_network_attr.joseph_ipnc_eth_net_status != 0)
    {
     /*try to connect network*/
     joseph_set_led_status_run(JOSEPH_LED_RED_BLUE_SLOW_GLITTER_INT);
    }
   
    break;//do nothing
   }
   else
   {
    if(joseph_ipnc_param.joseph_ipnc_network_attr.joseph_ipnc_eth_net_status != 1)
    {
     joseph_set_led_status_run(JOSEPH_LED_BLUE_SLOW_GLITTER_INT);
    }
   
    joseph_ipnc_param.joseph_ipnc_network_attr.joseph_sys_connect_network = 1;
    joseph_ipnc_param.joseph_ipnc_network_attr.joseph_ipnc_eth_net_status = 1;
   }
  }
  else
  {
   if(joseph_ipnc_param.joseph_ipnc_network_attr.joseph_ipnc_eth_net_status != -1)
   {
    /*try to connect network*/
    joseph_set_led_status_run(JOSEPH_LED_RED_BLUE_SLOW_GLITTER_INT);
   }
       
   joseph_ipnc_param.joseph_ipnc_network_attr.joseph_ipnc_eth_net_status = -1;
   joseph_personal_eth_print("%s:[%d] The netlink is down !\n",__FUNCTION__,__LINE__);
  }
  sleep(5);
 }
 
 goto NET_INIT;

 return Qy_Ret;
}

int Joseph_EthNet_Interface_Init_Pthread(char *if_name)
{
 int Qy_Ret = 0;

 char *param = if_name;
 run_pthread(&Joseph_EthNet_Interface_Init,param);

 /*try to connect network*/
 joseph_set_led_status_run(JOSEPH_LED_RED_BLUE_SLOW_GLITTER_INT);
 
 return Qy_Ret;
}

你可能感兴趣的:(嵌入式 指定网卡名称的信息以及网络连通状态以及重连机制代码示例)