我正在研究下面的函数来解析CIDR表示法,并最终返回所有IP地址的数组。
不过,我在这一行遇到了一个问题:network_addr = last_addr = addr.s_addr;
我需要三个变量,保存网络地址,最后地址,和原始地址,以便我可以应用位移位运算符。但是,就目前而言,它似乎是在借鉴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;
...
}发布于 2015-08-24 11:41:09
我认为您的问题不是引用/按值复制(您已经在按值复制)。在我看来,你好像搞砸了网络/主机字节顺序。
sa_addr字段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;,并可能将返回类型更改为uint32_t。
发布于 2015-08-24 12:04:55
您可能需要malloc您的新变量,然后memcpy旧变量到您的新变量。
https://stackoverflow.com/questions/32181183
复制相似问题