我正在使用pcap_findalldevs获取计算机中的设备列表。我成功了,设备的名称和描述,但我不知道为什么,我得到Netmask 0.0.0.0和IP地址也0.0.0.0。 这是我生成列表的代码:
/* get the devices list */
if (pcap_findalldevs(&devList, errbuf) == -1)
{
fprintf(stderr, "There is a problem with pcap_findalldevs: %s\n", errbuf);
return -1;
}
/* scan the list for a suitable device to capture from */
for (dev = devList; dev != NULL; dev = dev->next)
{
pcap_addr_t *dev_addr; //interface address that used by pcap_findalldevs()
/* check if the device captureble*/
if ((dev_addr = dev->addresses) != NULL && dev_addr->addr->sa_family == AF_INET && dev_addr->addr && dev_addr->netmask) {
printf("Found a device %s on address %s with netmask %s\n", dev->name, iptos(((struct sockaddr_in *)dev_addr->addr)->sin_addr.s_addr), iptos(((struct sockaddr_in *)dev_addr->netmask)->sin_addr.s_addr));
break;
}
}
答案 0 :(得分:5)
这是应该做的事情:
/* get the devices list */
if (pcap_findalldevs(&devList, errbuf) == -1)
{
fprintf(stderr, "There is a problem with pcap_findalldevs: %s\n", errbuf);
return -1;
}
/* scan the list for a suitable device to capture from */
for (dev = devList; dev != NULL; dev = dev->next)
{
pcap_addr_t *dev_addr; //interface address that used by pcap_findalldevs()
/* check if the device captureble*/
for (dev_addr = dev->addresses; dev_addr != NULL; dev_addr = dev_addr->next) {
if (dev_addr->addr->sa_family == AF_INET && dev_addr->addr && dev_addr->netmask) {
printf("Found a device %s on address %s with netmask %s\n", dev->name, iptos(((struct sockaddr_in *)dev_addr->addr)->sin_addr.s_addr), iptos(((struct sockaddr_in *)dev_addr->netmask)->sin_addr.s_addr));
goto found;
}
}
}
found:
这样,您可以检查整个地址列表,而不仅仅是列表中的第一个地址。如果,当您到达found
时,dev
为非空,则它指向至少有一个IPv4地址的设备,dev_addr
指向该地址。如果dev
为空,则表示没有具有IPv4地址的设备。
答案 1 :(得分:1)
Anrew Medico的post让我想到了这个解决方案:
起初我使用const auto进行初始化。这是一个常见问题*。我还得到了ip-address的子网掩码。由于iptos()对我不起作用,我将deklaration更改为const string。
const string interface_ip = inet_ntoa(reinterpret_cast<struct sockaddr_in*>(address->addr)->sin_addr);
const string interface_netmask = inet_ntoa(reinterpret_cast<struct sockaddr_in*>(address->netmask)->sin_addr);
希望这有助于其他人,因为它帮助了我。
答案 2 :(得分:0)
在您找到的第一个接口之后退出循环,这可能是环回接口。
这是我过去使用的代码(我跳过了地址为0.0.0.0的环回):
for(pcap_if_t* pInterface(m_pAllDevices); pInterface != 0; pInterface = pInterface->next)
{
if((pInterface->flags & PCAP_IF_LOOPBACK) != 0) // Skip loopback interfaces
{
continue;
}
std::string address;
if(pInterface->addresses != 0)
{
#if defined(WIN32)
static char tempChar[1] = {0};
DWORD stringSize(0);
if(pInterface->addresses != 0 && WSAAddressToStringA(pInterface->addresses->addr, sizeof(*(pInterface->addresses->addr)), 0, tempChar, &stringSize) == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT)
{
address.resize((size_t)stringSize);
WSAAddressToStringA(pInterface->addresses->addr, sizeof(*(pInterface->addresses->addr)), 0, &(address[0]), &stringSize);
}
#else
char tempBuffer[INET_ADDRSTRLEN];
inet_ntop(AF_INET, pInterface->addresses->addr, tempBuffer, sizeof(tempBuffer));
address = tempBuffer;
#endif
}
}
答案 3 :(得分:0)
iptos
example from WinPcap使用单个静态缓冲区来生成结果。这意味着当你调用它两次时,第二次调用的结果会覆盖第一次调用的结果。
因此你的代码:
printf("Found a device %s on address %s with netmask %s\n",
dev->name, iptos(<addr-expr>), iptos(<mask-expr>));
将始终在地址和网络掩码位置中打印相同的值(地址或网络掩码,具体取决于编译器的参数评估顺序)。
要更正此问题,您可以复制结果字符串并将其保存到单独的变量中,如下所示:
char* addr = strdup(iptos(<addr-expr>));
char* mask = stdrup(iptos(<mask-expr>));
printf("Found a device %s on address %s with netmask %s\n",
dev->name, addr, mask>);
free(addr);
free(mask);
答案 4 :(得分:-1)
这对我有用.. 打开网络连接设置。右键单击您的连接并选择属性。现在取消选中Internet协议版本6(TCP / IPV6)。 现在运行您的应用程序,您将获得正确的IP地址。