<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_TIME 3000 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_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)); #else strcpy(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); } #endif if (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 : 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 = 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>