双网卡同网段, 监测网卡连接
IFF_UP 和 IFF_RUNNING 的差別在哪?就實際功用而言,兩者都代表了網路裝置是否正常啟用,但是更仔細觀察可以發現拔除網路線時會造成 IFF_RUNNING 的改變,至於 IFF_UP 不會因插拔網路線而有任何變化
#include <stdio.h>   
#include <stdlib.h>    
#include <sys/types.h>    
#include <sys/stat.h>    
#include <unistd.h>    
#include <sys/ioctl.h>    
#include <sys/socket.h>    
#include <netinet/in.h>    
#include <arpa/inet.h>    
#include <string.h>    
#include <fcntl.h>    
#include <errno.h>    
#include <sys/types.h>    
#include <linux/if.h>    
#include <linux/sockios.h>    
#include <linux/ethtool.h> 
#define SLEEP_TIME (1000*1000)
typedef struct nic_t   
{    
    char if_name[5];    
    int status;    
    int old_status;    
}nic;    
void init_daemon(void);    
int get_netlink_status(const char *if_name);    
void auto_up_down_eth(nic* pnic); 
void auto_route_eth(nic* pnic);
void init_nic(nic* pnic, const char* if_name)   
{    
    memset(pnic, 0, sizeof(nic));    
    strcpy(pnic->if_name, if_name);    
} 
int main(int argc, char* argv[])   
{    
    init_daemon();    
    if(getuid() != 0)    
    {    
        fprintf(stderr, "Netlink Status Check Need Root Power.\n");    
        return 1;    
    } 
    nic eth[2];   
    init_nic(ð[0], "eth0");    
    init_nic(ð[1], "eth1"); 
    while(1)   
    {    
        auto_up_down_eth(eth);    
        auto_up_down_eth(eth+1);    
        //auto_route_eth(eth);    
        //auto_route_eth(eth+1);    
        //get_netlink_status("eth1");    
        usleep(SLEEP_TIME);    
    } 
    return 0;   
} 
#define IFCONFIG_CMD "ifconfig %s %s"   
void ifconfig_cmd(const char* if_name, int up_down)    
{    
    char cmd[48];    
    sprintf(cmd, IFCONFIG_CMD, if_name, up_down==1?"up":"down");    
    system(cmd);    
} 
#define LINK_UP "up"   
#define LINK_DOWN "down"    
void auto_up_down_eth(nic* pnic)    
{    
    pnic->status = get_netlink_status(pnic->if_name);    
    if(pnic->status!=pnic->old_status)    
    {    
        printf("%s Net link status: %s\n", pnic->if_name, pnic->status==1?"up":"down");    
        ifconfig_cmd(pnic->if_name, pnic->status);    
        pnic->old_status = pnic->status;    
    }    
} 
#define ROUTE_DEL_CMD "route del -net %s netmask %s dev %s"   
//route del -net 192.168.3.0 netmask 255.255.255.0 dev eth1 
void route_del_cmd(const char* if_name, int up_down)   
{    
    char cmd[48];    
    sprintf(cmd, "./delroute.sh %s", if_name);    
    if(up_down!=1)    
    {    
        system(cmd);    
    }    
} 
void auto_route_eth(nic* pnic)   
{    
    pnic->status = get_netlink_status(pnic->if_name);    
    if(pnic->status!=pnic->old_status)    
    {    
        printf("%s Net link status: %s\n", pnic->if_name, pnic->status==1?"up":"down");    
        route_del_cmd(pnic->if_name, pnic->status);    
        pnic->old_status = pnic->status;    
    }    
} 
// if_name like "ath0", "eth0". Notice: call this function   
// need root privilege.    
// return value:    
// -1 -- error , details can check errno    
// 1 -- interface link up    
// 0 -- interface link down.    
#if 1    
int get_netlink_status(const char *if_name)    
{    
    int skfd;    
    struct ifreq ifr;    
    struct 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;    
}    
#else    
int get_netlink_status(const char *if_name)    
{    
    struct ifreq ifr;    
    int sockfd;    
    int ret = 0; 
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);   
    bzero(&ifr, sizeof(ifr));    
    strcpy(ifr.ifr_name, if_name); 
    ioctl(sockfd, SIOCGIFFLAGS, &ifr);   
    /*    
     ifr_flags 的各項旗標和說明:    
         IFF_UP              裝置正在運作    
         IFF_BROADCAST       有效的廣播位址    
         IFF_DEBUG           Debug 標誌    
         IFF_LOOPBACK        這是 Loopback 裝置    
         IFF_POINTOPOINT     這是點到點的網路裝置介面    
         IFF_RUNNING         資源已分配    
         IFF_NOARP           無arp協議,沒有設置第二層目的地址    
         IFF_PROMISC         介面為雜湊(promiscuous)模式    
         IFF_NOTRAILERS      避免使用 trailer    
         IFF_ALLMULTI        接收所有群組廣播(multicast)封包資料    
         IFF_MASTER          主負載平衡群(bundle)    
         IFF_SLAVE           從負載平衡群(bundle)    
         IFF_MULTICAST       支持群組廣播(multicast)    
         IFF_PORTSEL         可以通過 ifmap 選擇 media 類型    
         IFF_AUTOMEDIA       自動選擇 media    
         IFF_DYNAMIC         裝置介面關閉時丟棄地址    
    */    
    if (ifr.ifr_flags & IFF_UP)     
    {    
        printf("%s is IFF_UP!\n", if_name);    
        ret = 1;    
    }    
    else    
    {    
        printf("%s is !IFF_UP!\n", if_name);    
        ret = 0;    
    } 
    if (ifr.ifr_flags & IFF_RUNNING)    
    {    
        printf("%s is IFF_RUNNING!\n", if_name);    
    }    
    else    
    {    
        printf("%s is !IFF_RUNNING!\n", if_name);    
    } 
    close(sockfd);   
    return ret;    
} 
#endif
#include <unistd.h>   
#include <signal.h>    
#include <sys/param.h>    
#include <sys/types.h>    
#include <sys/stat.h> 
void init_daemon(void)   
{    
int pid;    
int i; 
if(pid=fork())   
exit(0);//是父进程,结束父进程    
else if(pid< 0)    
exit(1);//fork失败,退出    
//是第一子进程,后台继续执行 
setsid();//第一子进程成为新的会话组长和进程组长   
//并与控制终端分离    
if(pid=fork())    
exit(0);//是第一子进程,结束第一子进程    
else if(pid< 0)    
exit(1);//fork失败,退出    
//是第二子进程,继续    
//第二子进程不再是会话组长 
for(i=0;i< NOFILE;++i)//关闭打开的文件描述符   
close(i);    
//linzhming add:这个我们不需要    
chdir("/tmp");//改变工作目录到/tmp    
umask(0);//重设文件创建掩模    
return;    
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号