首页 > 解决方案 > 无法获取具有两个 IP 地址的接口的辅助网络掩码和广播地址

问题描述

我有一个带有以下网络接口的 vagrant 容器:

vagrant@vagrant-ubuntu-trusty-64:~/nettool$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:5f:bb:e6 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 192.168.56.202/24 brd 192.168.56.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe5f:bbe6/64 scope link 
       valid_lft forever preferred_lft forever

eth0请注意具有辅助 IP 地址的接口。我想获取eth0接口的两个 IP 的广播地址。我有以下c++代码可以做到这一点,但是当我尝试获取辅助 IP 地址的网络信息时,会返回主地址的netmaskbroadcast address。不知道为什么,我犯了错误的任何想法?

这是我写的代码:

#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/if.h>
#include <net/if_arp.h>
#include <unistd.h>
#include <linux/sockios.h>
#include <linux/ethtool.h>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <fstream>
#include <iostream>

std::string ipAddressToString(uint32_t ipAddress)
{
    char buffer[INET_ADDRSTRLEN] = {0};
    uint32_t addr = htonl(ipAddress);
    return std::string(inet_ntop(AF_INET, &addr, buffer, sizeof(buffer)));
}

int main(int argc, char *argv[]) {

    int fd = socket(AF_INET, SOCK_DGRAM, 0); 
    assert(fd > 0); 

    struct ifconf ifc;
    struct ifreq *pifr;

    ifc.ifc_len = sizeof(struct ifreq) * 10; 
    ifc.ifc_buf = (char*) malloc(ifc.ifc_len);

    int err = ioctl(fd, SIOCGIFCONF, &ifc);
    assert(err >= 0); 

    int ifc_num = ifc.ifc_len / sizeof(struct ifreq);
    printf("Interfaces: %d\r\n", ifc_num);

    assert(ifc.ifc_buf != NULL);
    pifr = ifc.ifc_req;
    
    // Iterate trought all ifreq and save interface type, ip and netmask
    for (int i = 0;  i < ifc_num; ++i)
    {       
        err = ioctl(fd, SIOCGIFADDR, &pifr[i]);
        assert(err == 0); 
        uint32_t ipAddress = ntohl(reinterpret_cast<struct sockaddr_in*>(&(pifr[i].ifr_addr))->sin_addr.s_addr);

        err = ioctl(fd, SIOCGIFNETMASK, &pifr[i]);
        assert(err == 0); 
        uint32_t netmaskAddress = ntohl(reinterpret_cast<struct sockaddr_in*>(&(pifr[i].ifr_netmask))->sin_addr.s_addr);

        err = ioctl(fd, SIOCGIFBRDADDR, &pifr[i]);
        assert(err == 0); 
        uint32_t broadcastAddress = ntohl(reinterpret_cast<struct sockaddr_in*>(&(pifr[i].ifr_broadaddr))->sin_addr.s_addr);

        printf("Network Interface: %s, IP=%s, Netmask=%s, Broadcast=%s\r\n", 
               pifr[i].ifr_name, 
               ipAddressToString(ipAddress).c_str(), 
               ipAddressToString(netmaskAddress).c_str(), 
               ipAddressToString(broadcastAddress).c_str());
    }   
}

这就是它打印的内容:

vagrant@vagrant-ubuntu-trusty-64:~/nettool$ g++ main.cpp -o nettool && sudo ./nettool
Interfaces: 3
Network Interface: lo, IP=127.0.0.1, Netmask=255.0.0.0, Broadcast=0.0.0.0
Network Interface: eth0, IP=10.0.2.15, Netmask=255.255.255.0, Broadcast=10.0.2.255
Network Interface: eth0, IP=192.168.56.202, Netmask=255.255.255.0, Broadcast=10.0.2.255

标签: c++linuxnetworkingnetwork-programming

解决方案


推荐阅读