#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <linux/if.h>
#include <string.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
//由於嵌入式linux貌似沒有對ethtool_value這個結*構體的定義,但在非嵌入式的版本里是有的,所以直接抄過來= =...
struct ethtool_value {
int cmd;
int data;
};
//以下兩個宏和ioctl有關,從網卡里獲取網線的狀態的關鍵就在這裏
#define ETHTOOL_GLINK 0x0000000a
#define SIOCETHTOOL 0x8946
#define UNCONNECT 0
#define CONNECT 1
int main(int argc, char **argv)
{
int i, fd, fd2, fdtablesize, sock, last, ret;
pid_t pid;
struct sigaction sa;
struct ifreq ifr;
struct ethtool_value edata;
edata.cmd = ETHTOOL_GLINK;
edata.data = 0;
//以下是產生一個守*護進程的方法,具體註解就不再贅述,之前的博文裏有詳解
umask(0);
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
//shutdown some signal
if(sigaction(SIGTTOU, &sa, NULL) < 0)
{
printf("can't ignore SIGTTOU\n");
return -1;
}
if(sigaction(SIGTTIN, &sa, NULL) < 0)
{
printf("can't ignore SIGTTIN\n");
return -1;
}
if(sigaction(SIGTSTP, &sa, NULL) < 0)
{
printf("can't ignore SIGTSTP\n");
return -1;
}
if(sigaction(SIGHUP, &sa, NULL) < 0)
{
printf("can't ignore SIGHUP\n");
return -1;
}
//terminate the father thread first
if(fork() != 0)
{
exit(1);
}
if(setsid() < 0)
{
exit(1);
}
//terminate the father thread second
if(fork() != 0)
{
exit(1);
}
//change work dir to root
if(chdir("/") == -1)
{
exit(1);
}
//shutdown some fds
for(fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++)
{
close(fd);
}
if(sigaction(SIGCHLD, &sa, NULL))
{
printf("can't ignore SIGCHLD\n");
return -1;
}
//access a socket
sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock == -1)
{
return -1;
}
//這裏是將要查詢的端口名拷貝到指定位置
strcpy(ifr.ifr_name, "eth0");
ifr.ifr_data = (char *)&edata;
//獲取狀態
ioctl(sock, SIOCETHTOOL, &ifr);
last = edata.data;
//不斷的讀取網卡的狀態
while(1)
{
//偶爾也讓它休息一下^_^
sleep(1);
ioctl(sock, SIOCETHTOOL, &ifr);
//如果狀態沒有改變,就跳過,直接執行下一次查詢
if(edata.data == last)
{
continue;
}
else
{
if(last == UNCONNECT) //如果網線被插上了
{
//打開一個子進程,在裏面調用一個腳本
if(fork() == 0)
{
// pid = getpid();
ret = execl("/data/work/ma_to_mt.sh", "master", NULL);
if(ret < 0)
{
exit(1);
}
// return 0; //這裏沒有必要使用return 因爲execl執行了就不會返回了
}
last = CONNECT; //把狀態改爲已連接
}
else if(last == CONNECT) //如果斷開了網線
{
if(fork() == 0) //開一個子進程,運行另一個腳本
{
// pid = getpid();
ret = execl("/data/work/mt_to_ma.sh", "managed", NULL);
if(ret < 0)
{
exit(1);
}
}
last = UNCONNECT; //狀態改爲已斷開
}
}
waitpid(-1, NULL ,0); //這個回收子進程的動作貌似也是沒必要的= =....
}
return 0;
}
- #include <linux/sockios.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <linux/if.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #define ETHTOOL_GLINK 0x0000000a /* Get link status (ethtool_value) */
- typedef enum { IFSTATUS_UP, IFSTATUS_DOWN, IFSTATUS_ERR } interface_status_t;
- typedef signed int u32;
- /* for passing single values */
- struct ethtool_value
- {
- u32 cmd;
- u32 data;
- };
- interface_status_t interface_detect_beat_ethtool(int fd, char *iface)
- {
- struct ifreq ifr;
- struct ethtool_value edata;
- memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)-1);
- edata.cmd = ETHTOOL_GLINK;
- ifr.ifr_data = (caddr_t) &edata;
- if (ioctl(fd, SIOCETHTOOL, &ifr) == -1)
- {
- perror("ETHTOOL_GLINK failed ");
- return IFSTATUS_ERR;
- }
- return edata.data ? IFSTATUS_UP : IFSTATUS_DOWN;
- }
- int main (int argc, char *argv[])
- {
- FILE *fp;
- interface_status_t status;
- char buf[512] = {'\0'};
- char hw_name[10] = {'\0'};
- char *token = NULL;
- /* 獲取網卡名稱 */
- if ((fp = fopen("/proc/net/dev", "r")) != NULL)
- {
- while (fgets(buf, sizeof(buf), fp) != NULL)
- {
- if(strstr(buf, "eth") != NULL)
- {
- token = strtok(buf, ":");
- while (*token == ' ') ++token;
- strncpy(hw_name, token, strlen(token));
- }
- }
- }
- fclose(fp);
- //方法一:查看一個文件文件,相對來說比較簡單
- #if 1
- char carrier_path[512] = {'\0'};
- memset(buf, 0, sizeof(buf));
- snprintf(carrier_path, sizeof(carrier_path), "/sys/class/net/%s/carrier", hw_name);
- if ((fp = fopen(carrier_path, "r")) != NULL)
- {
- while (fgets(buf, sizeof(buf), fp) != NULL)
- {
- if (buf[0] == '0')
- {
- status = IFSTATUS_DOWN;
- }
- else
- {
- status = IFSTATUS_UP;
- }
- }
- }
- else
- {
- perror("Open carrier ");
- }
- fclose(fp);
- #endif
- //方法二:用函數吧!有點複雜,但是也是一種有效的辦法
- #if 1
- int fd;
- if((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- perror("socket ");
- exit(0);
- }
- status = interface_detect_beat_ethtool(fd, hw_name);
- close(fd);
- #endif
- switch (status)
- {
- case IFSTATUS_UP:
- printf("%s : link up\n", hw_name);
- break;
- case IFSTATUS_DOWN:
- printf("%s : link down\n", hw_name);
- break;
- default:
- printf("Detect Error\n");
- break;
- }
- return 0;
- }
注:第一種方法適用於2.6內核以後的版本,第二中方法適用於2.4及以前的版本,2.4及之前的版本沒有/sys/class/net/%s/carrier這個目錄
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- int GetNetStat( )
- {
- char buffer[BUFSIZ];
- FILE *read_fp;
- int chars_read;
- int ret;
- memset( buffer, 0, BUFSIZ );
- read_fp = popen("ifconfig eth0 | grep RUNNING", "r");
- if ( read_fp != NULL )
- {
- chars_read = fread(buffer, sizeof(char), BUFSIZ-1, read_fp);
- if (chars_read > 0)
- {
- ret = 1;
- }
- else
- {
- ret = -1;
- }
- pclose(read_fp);
- }
- else
- {
- ret = -1;
- }
- return ret;
- }
- int main()
- {
- int i=0;
- i = GetNetStat();
- printf( "\nNetStat = %d\n", i );
- return 0;
- }