我正在使用以下函数来解析CIDR表示法并最终返回所有IP地址的数组。
我在这一行遇到了问题:network_addr = last_addr = addr.s_addr;
我需要3个变量来保存网络地址,最后地址和原始地址,因此我可以对它们应用位移运算符。但是,目前它似乎是在addr.s_addr
的参考。
如何按值复制?
int parse_ipv4_cidr(char *ip_cidr)
{
struct in_addr addr;
int cidr;
char *token;
uint32_t netmask, network_addr, last_addr;
token = strtok(ip_cidr, "/");
/*
* Validate IPV4 CIDR address
*/
if(!inet_aton(token, &addr) ||
!(token = strtok(NULL, "/")) ||
(atoi(token) < 0 || atoi(token) > 32))
{
printf("Invalid CIDR notation. Example format: 192.0.0.1/21\n");
return 1;
}
cidr = atoi(token);
network_addr = last_addr = addr.s_addr;
/*
* Create the netmask
*/
netmask = 0xFFFFFFFF;
netmask <<= 32 - cidr;
netmask = ntohl(netmask);
/*
* Calculate network address
*/
network_addr = network_addr & netmask;
/*
* Calculate last address
*/
last_addr = (last_addr & netmask) + ~netmask;
...
}
答案 0 :(得分:2)
我认为您的问题不在于引用/按值复制(您已经按值复制)。在我看来,你似乎搞砸了网络/主机字节顺序。
sa_addr
的{{1}}字段按网络字节顺序排列;当您将其复制到struct in_addr
和network_addr
时,您应该将其转换为主机字节顺序,因为您将进行转换和其他操作。
此外,由于某种原因,代码假定last_addr
处于网络字节顺序,而实际上它是以主机字节顺序。事情并没有加起来。
坚持主机字节顺序,一切都应该有效。
更改此行:
netmask
要:
network_addr = last_addr = addr.s_addr;
并删除此行:
network_addr = last_addr = ntohl(addr.s_addr);
您可能希望最后添加netmask = ntohl(netmask);
,并可能将返回类型更改为return network_addr;
。
答案 1 :(得分:0)
您可能需要malloc
新变量,然后将memcpy
旧变量添加到新变量中。