Я попробовал решение Дейва Уэбба, но столкнулся с некоторыми проблемами:
Самое главное - соответствие должно быть проверено путем ИД IP-адреса с маской, а затем проверки результата, точно совпадающего с Сетевым адресом. НЕ ИЛИ IP-адрес с Сетевым адресом, как было сделано.
Я также заметил, что просто игнорируя поведение Endian, предполагая, что согласованность спасет вас, вы будете работать только для масок на границах октетов (/ 24, / 16). Для того, чтобы другие маски (/ 23, / 21) работали правильно, я добавил «больше чем» в команды struct и изменил код для создания двоичной маски, чтобы он начинался со всех «1» и сдвигался влево на (32-mask ).
Наконец, я добавил простую проверку, что сетевой адрес действителен для маски, и просто напечатал предупреждение, если это не так.
Вот результат:
def addressInNetwork(ip,net):
"Is an address in a network"
ipaddr = struct.unpack('>L',socket.inet_aton(ip))[0]
netaddr,bits = net.split('/')
netmask = struct.unpack('>L',socket.inet_aton(netaddr))[0]
ipaddr_masked = ipaddr & (4294967295<<(32-int(bits))) # Logical AND of IP address and mask will equal the network address if it matches
if netmask == netmask & (4294967295<<(32-int(bits))): # Validate network address is valid for mask
return ipaddr_masked == netmask
else:
print "***WARNING*** Network",netaddr,"not valid with mask /"+bits
return ipaddr_masked == netmask