标准/安全的方法来检查IP地址是否在范围/子网中

时间:2015-06-25 02:27:16

标签: c sockets ip-address subnet netmask

我有一小段代码将32位无符号整数(即:uint32_t)转换为一组四个8位字段,将其视为IP地址,然后向客户端报告如果它属于预定的IP地址范围。

我已经already found C中的一些different examples代码向我展示了如何从包含它的struct sockaddr_in获取客户端的IP地址,{{} 3}}。但是,我想进一步细分地址,保持纯C,想要了解一些简单的事情:

  1. 内部表示在系统之间是否一致,或者我是否需要在s_addr字段上进行Endian-ness检查/更正?
  2. 是否有CLASS_C_NETMASKCLASS_B_NETMASK等行的标准宏,比使用手动生成的掩码更合适(即:0xFF0000000x00FF0000,等)。
  3. 套接字库中是否有任何现有功能可以检查IP地址是否在IP地址范围内或与子网掩码匹配?
  4. 感谢。

1 个答案:

答案 0 :(得分:10)

  

内部表示在系统之间是否一致,或者我是否需要在s_addr字段上进行Endian-ness检查/更正?

s_addr在所有平台上始终处于网络(大端)字节顺序。

  

是否有符合CLASS_C_NETMASK,CLASS_B_NETMASK等标准的宏,这比使用手动生成的掩码(即:0xFF000000,0x00FF0000等)更合适。

不,使用这样的宏也没有意义,因为子网掩码不是从一个网络固定到另一个网络。您需要为代码提供实际的网络IP及其子网掩码(提示用户,查询操作系统等)。然后,您可以计算子网的起始IP和结束IP,以与目标IP进行比较:

uint32_t ip = ...; // value to check
uint32_t netip = ...; // network ip to compare with
uint32_t netmask = ...; // network ip subnet mask
uint32_t netstart = (netip & netmask); // first ip in subnet
uint32_t netend = (netstart | ~netmask); // last ip in subnet
if ((ip >= netstart) && (ip <= netend))
    // is in subnet range...
else
    // not in subnet range...

或者更简单,使用子网掩码屏蔽网络IP和目标IP,并查看结果值是否相同(即,它们是同一子网):

uint32_t ip = ...; // value to check
uint32_t netip = ...; // network ip to compare with
uint32_t netmask = ...; // network ip subnet mask
if ((netip & netmask) == (ip & netmask))
    // is on same subnet...
else
    // not on same subnet...
  

如果IP地址在IP地址范围内或与子网掩码匹配,套接字库中是否有现有功能可以检查?

没有。但是手动实现是微不足道的,它只需要几行代码,如上所示。