How can I programmatically find the IP address/netmask/gateway configured for a specific network device in Linux?

后端 未结 3 658
傲寒
傲寒 2020-12-23 13:11

I would like to write a piece of code which checks, for each network device (e.g. eth0, lo, master devices) some statistics and configuration data about that device.
I c

3条回答
  •  离开以前
    2020-12-23 13:29

    There sure is using a struct of ifreq and ioctl() calls you can grab all interface information:

    Man page is here Ifreq manpage

    /* local interface info */
        typedef struct{
            char *iface;
            struct ether_addr hwa;
            struct in_addr ipa;
            struct in_addr bcast;
            struct in_addr nmask;
            u_short mtu;
        } ifcfg_t; 
        /*
         * Grabs local network interface information and stores in a ifcfg_t 
         * defined in network.h, returns 0 on success -1 on failure
        */
        int get_local_info(int rsock, ifcfg_t *ifcfg)
        {
            struct ifreq ifr;
    
            memset(&ifr, 0, sizeof(ifr));
            strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
            if((ioctl(rsock, SIOCGIFHWADDR, &ifr)) == -1){
                perror("ioctl():");
                return -1;
            }
            memcpy(&(ifcfg->hwa), &ifr.ifr_hwaddr.sa_data, 6);
    
            memset(&ifr, 0, sizeof(ifr));
            strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
            if((ioctl(rsock, SIOCGIFADDR, &ifr)) == -1){
                perror("ioctl():");
                return -1;
            }
            memcpy(&ifcfg->ipa, &(*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr, 4);
    
            memset(&ifr, 0, sizeof(ifr));
            strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
            if((ioctl(rsock, SIOCGIFBRDADDR, &ifr)) == -1){
                perror("ioctl():");
                return -1;
            }
            memcpy(&ifcfg->bcast, &(*(struct sockaddr_in *)&ifr.ifr_broadaddr).sin_addr, 4);
    
            memset(&ifr, 0, sizeof(ifr));
            strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
            if((ioctl(rsock, SIOCGIFNETMASK, &ifr)) == -1){
                perror("ioctl():");
                return -1;
            }
            memcpy(&ifcfg->nmask.s_addr, &(*(struct sockaddr_in *)&ifr.ifr_netmask).sin_addr, 4);
    
            memset(&ifr, 0, sizeof(ifr));
            strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
            if((ioctl(rsock, SIOCGIFMTU, &ifr)) == -1){
                perror("ioctl():");
                return -1;
            }
            ifcfg->mtu = ifr.ifr_mtu;
    
            return 0;
        }
    

    Quick edit, this function requires that the interface has been assigned before it is called, like so:

    strcpy(if_cfg->iface, iface)
    

    Ensuring you have allocated the memory first, then call like so

    if((get_local_info(sock, if_cfg)) != 0){
        printf("Unable to get network device info\n");
        return -1;
    }
    

提交回复
热议问题