如何从 getifaddr 读取子网掩码
How do I read the subnet mask from getifaddr
使用getifaddrs()
函数,我想提取网络IP和掩码 CIDR格式(即24而不是255.255.255.0(,与其他问题不同。 但是我在面具部分遇到了困难。
例如:
192.168.0.114/24
这就是我到目前为止一直在搞砸的东西。 但我一定是错误地读取了网络掩码。 这是完全错误的。
#include <stdio.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
unsigned int cidrMask(unsigned int n) {
unsigned int count = 0;
while (n) {
count += n & 1;
n >>= 1;
}
return 32-count;
}
int main (int argc, const char * argv[]) {
struct ifaddrs * ifAddrStruct=NULL;
struct ifaddrs * ifa=NULL;
void * tmpAddrPtr=NULL;
unsigned int tmpMask;
getifaddrs(&ifAddrStruct);
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
if (!ifa->ifa_addr) {
continue;
}
if (ifa->ifa_addr->sa_family == AF_INET) { // check it is IP4
// is a valid IP4 Address
tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
memcpy(&tmpMask, &(*(struct sockaddr_in *)&ifa->ifa_netmask).sin_addr, 4);
char addressBuffer[INET_ADDRSTRLEN];
inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
printf("%s IP Address %s, mask=%u, %un", ifa->ifa_name, addressBuffer, ifa->ifa_netmask, cidrMask(tmpMask));
printf("tmpmask=%dn", tmpMask);
}
}
if (ifAddrStruct!=NULL) freeifaddrs(ifAddrStruct);
return 0;
}
因此,网络掩码的输出是完全错误的。
lo IP Address 127.0.0.1, mask=3106544572, 22
tmpmask=21982
enp0s25 IP Address 192.168.0.114, mask=3106544756, 22
tmpmask=21982
docker0 IP Address 172.17.0.1, mask=3106544940, 22
tmpmask=21982
如何读取网络掩码并产生正确的输出?
你对tmpMask
的赋值是错误的,因为你的类型转换ifa_netmask
错误的,所以你通过无效的指针访问其sin_addr
成员。
您正在获取ifa_netmask
的地址并将其类型转换为sockaddr_in*
,但您需要将其值类型转换为,就像您对ifa_addr
所做的那样:
memcpy(&tmpMask, &(((struct sockaddr_in *)(ifa->ifa_netmask))->sin_addr.s_addr), 4);
可以通过删除memcpy()
来简化:
tmpMask = ((struct sockaddr_in *)(ifa->ifa_netmask))->sin_addr.s_addr;
当您打印出ifa_netmask
时,您正在打印出其原始指针值(使用%u
,这是指针的未定义行为(。您应该像格式化ifa_addr
一样将ifa_netmask
格式化为人类可读的字符串,因为它们都是指向sockaddr_in
结构的指针:
char addressBuffer[INET_ADDRSTRLEN];
char maskBuffer[INET_ADDRSTRLEN];
tmpAddrPtr = &((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr;
inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
tmpAddrPtr = &((struct sockaddr_in *)(ifa->ifa_netmask))->sin_addr;
inet_ntop(AF_INET, tmpAddrPtr, maskBuffer, INET_ADDRSTRLEN);
tmpMask = ((struct sockaddr_in *)(ifa->ifa_netmask))->sin_addr.s_addr;
printf("%s IP Address %s, Mask %s, %un", ifa->ifa_name, addressBuffer, maskBuffer, cidrMask(tmpMask));
printf("tmpmask=%un", tmpMask);
相关文章:
- 位移操作和位掩码未检测到重复字符
- OpenCV - 带有掩码的absdiff
- 生成前缀位掩码
- 如何从__m64值的 lsb 创建 8 位掩码?
- 如何对无符号长 int 进行位掩码?
- 删除K的背景掩码-意味着Python或C++中的集群/
- 如何在C++中优雅地处理位掩码
- 用FFMPEG读取每帧时间码
- 用rapidjson读取子对象向量
- 将uint64_t位掩码转换为 std::布尔数组
- 使输入二进制掩码适应 ITK 网格生成器
- 如何从 getifaddr 读取子网掩码
- 优化从子位掩码生成父位掩码
- 基于模式创建位掩码作为 constexpr
- 使用二进制掩码 C++ ITK 获取感兴趣区域
- C++中的运行时位复制(位掩码)
- 根据 IP 和掩码C++打印所有 IP
- 使用DHCP获取IP地址,网关,掩码和广播信息
- 正在验证IPv6子网掩码前缀
- 如何知道从子网掩码中搜索哪些IP地址