zoukankan      html  css  js  c++  java
  • 双网卡同网段, 监测网卡连接

    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(&eth[0], "eth0");
        init_nic(&eth[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;
    }

  • 相关阅读:
    造出最好的 CMS 轮子
    搭建开发框架Express,实现Web网站登录验证
    QueryOver<T>
    NVelocity
    .NET 相依性注入
    Unity 3.5
    java socket 的参数选项解读(转)
    换种方式去分页(转)
    上海市居住证办理材料及流程
    java动态代理
  • 原文地址:https://www.cnblogs.com/cute/p/2090894.html
Copyright © 2011-2022 走看看