给定一个 IP 地址(比如 192.168.0.1),我如何在 Python 中检查它是否在网络中(比如 192.168.0.0/24)?
Python中有用于IP地址操作的通用工具吗?诸如主机查找,int 的 ip 地址,带有网络掩码的网络地址到 int 等的东西?希望在 2.5 的标准 Python 库中。
给定一个 IP 地址(比如 192.168.0.1),我如何在 Python 中检查它是否在网络中(比如 192.168.0.0/24)?
Python中有用于IP地址操作的通用工具吗?诸如主机查找,int 的 ip 地址,带有网络掩码的网络地址到 int 等的东西?希望在 2.5 的标准 Python 库中。
使用ipaddress(自 3.3 起在 stdlib 中,在 PyPi 中为 2.6/2.7):
>>> import ipaddress
>>> ipaddress.ip_address('192.168.0.1') in ipaddress.ip_network('192.168.0.0/24')
True
如果您想以这种方式评估大量IP 地址,您可能需要预先计算网络掩码,例如
n = ipaddress.ip_network('192.0.0.0/16')
netw = int(n.network_address)
mask = int(n.netmask)
然后,对于每个地址,使用以下之一计算二进制表示
a = int(ipaddress.ip_address('192.0.43.10'))
a = struct.unpack('!I', socket.inet_pton(socket.AF_INET, '192.0.43.10'))[0]
a = struct.unpack('!I', socket.inet_aton('192.0.43.10'))[0] # IPv4 only
最后,您可以简单地检查:
in_network = (a & mask) == netw
我喜欢为此使用netaddr:
from netaddr import CIDR, IP
if IP("192.168.0.1") in CIDR("192.168.0.0/24"):
print "Yay!"
正如 arno_v 在评论中指出的那样,新版本的 netaddr 是这样的:
from netaddr import IPNetwork, IPAddress
if IPAddress("192.168.0.1") in IPNetwork("192.168.0.0/24"):
print "Yay!"
对于python3
import ipaddress
ipaddress.IPv4Address('192.168.1.1') in ipaddress.IPv4Network('192.168.0.0/24')
ipaddress.IPv4Address('192.168.1.1') in ipaddress.IPv4Network('192.168.0.0/16')
输出 :
False
True
这篇文章展示了你可以用socket
和struct
模块做到这一点,而不需要太多额外的努力。我在文章中添加了一点如下:
import socket,struct
def makeMask(n):
"return a mask of n bits as a long integer"
return (2L<<n-1) - 1
def dottedQuadToNum(ip):
"convert decimal dotted quad string to long integer"
return struct.unpack('L',socket.inet_aton(ip))[0]
def networkMask(ip,bits):
"Convert a network address to a long integer"
return dottedQuadToNum(ip) & makeMask(bits)
def addressInNetwork(ip,net):
"Is an address in a network"
return ip & net == net
address = dottedQuadToNum("192.168.1.1")
networka = networkMask("10.0.0.0",24)
networkb = networkMask("192.168.0.0",24)
print (address,networka,networkb)
print addressInNetwork(address,networka)
print addressInNetwork(address,networkb)
这输出:
False
True
如果你只想要一个接受字符串的函数,它看起来像这样:
import socket,struct
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] & ((2L<<int(bits)-1) - 1)
return ipaddr & netmask == netmask
使用 Python >= 3.7 ipaddress:
import ipaddress
address = ipaddress.ip_address("192.168.0.1")
network = ipaddress.ip_network("192.168.0.0/16")
print(network.supernet_of(ipaddress.ip_network(f"{address}/{address.max_prefixlen}")))
您可以将IP 地址视为具有最大可能网络掩码的网络(对于/32
IPv4,/128
对于 IPv6)
检查是否192.168.0.1
是在192.168.0.0/16
本质上与检查是否192.168.0.1/32
是一个子网相同192.168.0.0/16
这段代码在 Linux x86 上为我工作。我并没有真正考虑过字节序问题,但我已经使用超过 200K IP 地址针对 8 个不同的网络字符串测试了“ipaddr”模块,并且 ipaddr 的结果与此代码相同。
def addressInNetwork(ip, net):
import socket,struct
ipaddr = int(''.join([ '%02x' % int(x) for x in ip.split('.') ]), 16)
netstr, bits = net.split('/')
netaddr = int(''.join([ '%02x' % int(x) for x in netstr.split('.') ]), 16)
mask = (0xffffffff << (32 - int(bits))) & 0xffffffff
return (ipaddr & mask) == (netaddr & mask)
例子:
>>> print addressInNetwork('10.9.8.7', '10.9.1.0/16')
True
>>> print addressInNetwork('10.9.8.7', '10.9.1.0/24')
False
我会尽可能推荐内置的ipaddress模块。虽然它只在 Python 3 中可用,但它非常易于使用,并且支持 IPv6。为什么你还不使用 Python 3,对吧?
接受的答案不起作用......这让我很生气。掩码是向后的,不适用于任何不是简单的 8 位块(例如 /24)的位。我调整了答案,效果很好。
import socket,struct
def addressInNetwork(ip, net_n_bits):
ipaddr = struct.unpack('!L', socket.inet_aton(ip))[0]
net, bits = net_n_bits.split('/')
netaddr = struct.unpack('!L', socket.inet_aton(net))[0]
netmask = (0xFFFFFFFF >> int(bits)) ^ 0xFFFFFFFF
return ipaddr & netmask == netaddr
这是一个函数,它返回一个带点的二进制字符串,以帮助可视化屏蔽..有点像ipcalc
输出。
def bb(i):
def s = '{:032b}'.format(i)
def return s[0:8]+"."+s[8:16]+"."+s[16:24]+"."+s[24:32]
例如:
我不喜欢在不需要时使用模块。这项工作只需要简单的数学运算,所以这是我完成这项工作的简单函数:
def ipToInt(ip):
o = map(int, ip.split('.'))
res = (16777216 * o[0]) + (65536 * o[1]) + (256 * o[2]) + o[3]
return res
def isIpInSubnet(ip, ipNetwork, maskLength):
ipInt = ipToInt(ip)#my test ip, in int form
maskLengthFromRight = 32 - maskLength
ipNetworkInt = ipToInt(ipNetwork) #convert the ip network into integer form
binString = "{0:b}".format(ipNetworkInt) #convert that into into binary (string format)
chopAmount = 0 #find out how much of that int I need to cut off
for i in range(maskLengthFromRight):
if i < len(binString):
chopAmount += int(binString[len(binString)-1-i]) * 2**i
minVal = ipNetworkInt-chopAmount
maxVal = minVal+2**maskLengthFromRight -1
return minVal <= ipInt and ipInt <= maxVal
然后使用它:
>>> print isIpInSubnet('66.151.97.0', '66.151.97.192',24)
True
>>> print isIpInSubnet('66.151.97.193', '66.151.97.192',29)
True
>>> print isIpInSubnet('66.151.96.0', '66.151.97.192',24)
False
>>> print isIpInSubnet('66.151.97.0', '66.151.97.192',29)
就是这样,这比上面包含模块的解决方案要快得多。
我尝试了 Dave Webb 的解决方案,但遇到了一些问题:
最基本的 - 应该通过将 IP 地址与掩码进行与运算来检查匹配,然后检查结果是否与网络地址完全匹配。不像之前那样将 IP 地址与网络地址进行与运算。
我还注意到,假设一致性将节省您的时间,而忽略 Endian 行为,只会适用于八位字节边界(/24、/16)上的掩码。为了让其他掩码(/23、/21)正常工作,我在结构命令中添加了一个“大于”,并将创建二进制掩码的代码更改为以全“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
不在 2.5 的标准库中,但 ipaddr 使这很容易。我相信它是在 3.3 中,名称为 ipaddress。
import ipaddr
a = ipaddr.IPAddress('192.168.0.1')
n = ipaddr.IPNetwork('192.168.0.0/24')
#This will return True
n.Contains(a)
Marc 的代码几乎是正确的。代码的完整版本是 -
def addressInNetwork3(ip,net):
'''This function allows you to check if on IP belogs to a Network'''
ipaddr = struct.unpack('=L',socket.inet_aton(ip))[0]
netaddr,bits = net.split('/')
netmask = struct.unpack('=L',socket.inet_aton(calcDottedNetmask(int(bits))))[0]
network = struct.unpack('=L',socket.inet_aton(netaddr))[0] & netmask
return (ipaddr & netmask) == (network & netmask)
def calcDottedNetmask(mask):
bits = 0
for i in xrange(32-mask,32):
bits |= (1 << i)
return "%d.%d.%d.%d" % ((bits & 0xff000000) >> 24, (bits & 0xff0000) >> 16, (bits & 0xff00) >> 8 , (bits & 0xff))
显然来自与上述相同的来源......
一个非常重要的注意事项是第一个代码有一个小故障 - IP 地址 255.255.255.255 也显示为任何子网的有效 IP。我花了很多时间让这段代码运行起来,感谢 Marc 的正确答案。
依赖“struct”模块可能会导致字节序和类型大小出现问题,而这并不是必需的。socket.inet_aton() 也不是。Python 非常适用于点分四组 IP 地址:
def ip_to_u32(ip):
return int(''.join('%02x' % int(d) for d in ip.split('.')), 16)
我需要针对一整套允许的源网络对每个套接字 accept() 调用进行 IP 匹配,因此我将掩码和网络预先计算为整数:
SNS_SOURCES = [
# US-EAST-1
'207.171.167.101',
'207.171.167.25',
'207.171.167.26',
'207.171.172.6',
'54.239.98.0/24',
'54.240.217.16/29',
'54.240.217.8/29',
'54.240.217.64/28',
'54.240.217.80/29',
'72.21.196.64/29',
'72.21.198.64/29',
'72.21.198.72',
'72.21.217.0/24',
]
def build_masks():
masks = [ ]
for cidr in SNS_SOURCES:
if '/' in cidr:
netstr, bits = cidr.split('/')
mask = (0xffffffff << (32 - int(bits))) & 0xffffffff
net = ip_to_u32(netstr) & mask
else:
mask = 0xffffffff
net = ip_to_u32(cidr)
masks.append((mask, net))
return masks
然后我可以快速查看给定 IP 是否在这些网络之一中:
ip = ip_to_u32(ipstr)
for mask, net in cached_masks:
if ip & mask == net:
# matched!
break
else:
raise BadClientIP(ipstr)
不需要模块导入,并且代码匹配速度非常快。
选择的答案有一个错误。
以下是正确的代码:
def addressInNetwork(ip, net_n_bits):
ipaddr = struct.unpack('<L', socket.inet_aton(ip))[0]
net, bits = net_n_bits.split('/')
netaddr = struct.unpack('<L', socket.inet_aton(net))[0]
netmask = ((1L << int(bits)) - 1)
return ipaddr & netmask == netaddr & netmask
注意:ipaddr & netmask == netaddr & netmask
而不是ipaddr & netmask == netmask
.
我也替换((2L<<int(bits)-1) - 1)
为((1L << int(bits)) - 1)
,因为后者似乎更容易理解。
>>> from netaddr import all_matching_cidrs
>>> all_matching_cidrs("212.11.70.34", ["192.168.0.0/24","212.11.64.0/19"] )
[IPNetwork('212.11.64.0/19')]
这是此方法的用法:
>>> help(all_matching_cidrs)
Help on function all_matching_cidrs in module netaddr.ip:
all_matching_cidrs(ip, cidrs)
Matches an IP address or subnet against a given sequence of IP addresses and subnets.
@param ip: a single IP address or subnet.
@param cidrs: a sequence of IP addresses and/or subnets.
@return: all matching IPAddress and/or IPNetwork objects from the provided
sequence, an empty list if there was no match.
基本上,您提供一个 IP 地址作为第一个参数,并提供一个 cidr 列表作为第二个参数。返回命中列表。
#这可以正常工作,没有奇怪的逐字节处理 def addressInNetwork(ip,net): '''是网络中的地址''' # 将地址转换为主机顺序,因此移位实际上是有意义的 ip = struct.unpack('>L',socket.inet_aton(ip))[0] netaddr,bits = net.split('/') netaddr = struct.unpack('>L',socket.inet_aton(netaddr))[0] # 必须左移一个全为值,/32 = 零移,/0 = 32 左移 网络掩码 = (0xffffffff << (32-int(位))) & 0xffffffff # 不需要屏蔽网络地址,只要是正确的网络地址 返回(IP 和网络掩码)== netaddr
这是我为最长前缀匹配编写的一个类:
#!/usr/bin/env python
class Node:
def __init__(self):
self.left_child = None
self.right_child = None
self.data = "-"
def setData(self, data): self.data = data
def setLeft(self, pointer): self.left_child = pointer
def setRight(self, pointer): self.right_child = pointer
def getData(self): return self.data
def getLeft(self): return self.left_child
def getRight(self): return self.right_child
def __str__(self):
return "LC: %s RC: %s data: %s" % (self.left_child, self.right_child, self.data)
class LPMTrie:
def __init__(self):
self.nodes = [Node()]
self.curr_node_ind = 0
def addPrefix(self, prefix):
self.curr_node_ind = 0
prefix_bits = ''.join([bin(int(x)+256)[3:] for x in prefix.split('/')[0].split('.')])
prefix_length = int(prefix.split('/')[1])
for i in xrange(0, prefix_length):
if (prefix_bits[i] == '1'):
if (self.nodes[self.curr_node_ind].getRight()):
self.curr_node_ind = self.nodes[self.curr_node_ind].getRight()
else:
tmp = Node()
self.nodes[self.curr_node_ind].setRight(len(self.nodes))
tmp.setData(self.nodes[self.curr_node_ind].getData());
self.curr_node_ind = len(self.nodes)
self.nodes.append(tmp)
else:
if (self.nodes[self.curr_node_ind].getLeft()):
self.curr_node_ind = self.nodes[self.curr_node_ind].getLeft()
else:
tmp = Node()
self.nodes[self.curr_node_ind].setLeft(len(self.nodes))
tmp.setData(self.nodes[self.curr_node_ind].getData());
self.curr_node_ind = len(self.nodes)
self.nodes.append(tmp)
if i == prefix_length - 1 :
self.nodes[self.curr_node_ind].setData(prefix)
def searchPrefix(self, ip):
self.curr_node_ind = 0
ip_bits = ''.join([bin(int(x)+256)[3:] for x in ip.split('.')])
for i in xrange(0, 32):
if (ip_bits[i] == '1'):
if (self.nodes[self.curr_node_ind].getRight()):
self.curr_node_ind = self.nodes[self.curr_node_ind].getRight()
else:
return self.nodes[self.curr_node_ind].getData()
else:
if (self.nodes[self.curr_node_ind].getLeft()):
self.curr_node_ind = self.nodes[self.curr_node_ind].getLeft()
else:
return self.nodes[self.curr_node_ind].getData()
return None
def triePrint(self):
n = 1
for i in self.nodes:
print n, ':'
print i
n += 1
这是一个测试程序:
n=LPMTrie()
n.addPrefix('10.25.63.0/24')
n.addPrefix('10.25.63.0/16')
n.addPrefix('100.25.63.2/8')
n.addPrefix('100.25.0.3/16')
print n.searchPrefix('10.25.63.152')
print n.searchPrefix('100.25.63.200')
#10.25.63.0/24
#100.25.0.3/16
以前的解决方案在 ip & net == net 中有一个错误。正确的 ip 查找是 ip & netmask = net
错误修正的代码:
import socket
import struct
def makeMask(n):
"return a mask of n bits as a long integer"
return (2L<<n-1) - 1
def dottedQuadToNum(ip):
"convert decimal dotted quad string to long integer"
return struct.unpack('L',socket.inet_aton(ip))[0]
def addressInNetwork(ip,net,netmask):
"Is an address in a network"
print "IP "+str(ip) + " NET "+str(net) + " MASK "+str(netmask)+" AND "+str(ip & netmask)
return ip & netmask == net
def humannetcheck(ip,net):
address=dottedQuadToNum(ip)
netaddr=dottedQuadToNum(net.split("/")[0])
netmask=makeMask(long(net.split("/")[1]))
return addressInNetwork(address,netaddr,netmask)
print humannetcheck("192.168.0.1","192.168.0.0/24");
print humannetcheck("192.169.0.1","192.168.0.0/24");
从 Python 3.7 开始,您可以使用subnet_of
和supernet_of
辅助方法,它们是标准库的一部分:
要仅针对单个 IP 进行测试,您可以使用/32
表示“仅此 IP 地址”的子网掩码作为子网,或者您可以将 IP 地址传递给IPv4Nework
构造IPv6Nework
函数,它们将为您返回子网值。
所以对于你的例子:
from ipaddress import IPv4Network, IPv4Address
# Store IP Address as variable
>>> myip = IPv4Address('192.168.0.1')
>>> myip
IPv4Address('192.168.0.1')
# This treats the IP as a subnet
>>> myip_subnet = IPv4Network(myip)
>>> myip_subnet
IPv4Network('192.168.0.1/32')
# The other subnet to test membership against
>>> other_subnet = IPv4Network('192.168.0.0/24')
>>> other_subnet
IPv4Network('192.168.0.0/24')
# Now we can test
>>> myip_subnet.subnet_of(other_subnet)
True
Python中有用于IP地址操作的通用工具吗?诸如主机查找,int 的 ip 地址,带有网络掩码的网络地址到 int 等的东西?希望在 2.5 的标准 Python 库中。
在 Python 3 中,有ipaddress
一个具有 IPv4 和 IPv6 操作工具的模块。您可以通过强制转换将它们转换为 int,即int(IPv4Address('192.168.0.1'))
. ipaddress
主机模块中的许多其他有用功能等。
我不知道标准库中的任何内容,但PySubnetTree是一个 Python 库,可以进行子网匹配。
谢谢你的剧本!
我已经做了很长时间的工作以使一切正常......所以我在这里分享它
makeMask 功能不起作用!仅适用于 /8,/16,/24
例如:
位=“21”;socket.inet_ntoa(struct.pack('=L',(2L << int(bits)-1) - 1))
'255.255.31.0' 而它应该是 255.255.248.0
所以我使用了来自 http://code.activestate.com/recipes/576483-convert-subnetmask-from-cidr-notation-to-dotdecima/
的另一个函数 calcDottedNetmask(mask)
例如:
#!/usr/bin/python
>>> calcDottedNetmask(21)
>>> '255.255.248.0'
#!/usr/bin/python
>>> addressInNetwork('188.104.8.64','172.16.0.0/12')
>>>True which is completely WRONG!!
所以我的新 addressInNetwork 函数看起来像:
#!/usr/bin/python
import socket,struct
def addressInNetwork(ip,net):
'''This function allows you to check if on IP belogs to a Network'''
ipaddr = struct.unpack('=L',socket.inet_aton(ip))[0]
netaddr,bits = net.split('/')
netmask = struct.unpack('=L',socket.inet_aton(calcDottedNetmask(bits)))[0]
network = struct.unpack('=L',socket.inet_aton(netaddr))[0] & netmask
return (ipaddr & netmask) == (network & netmask)
def calcDottedNetmask(mask):
bits = 0
for i in xrange(32-int(mask),32):
bits |= (1 > 24, (bits & 0xff0000) >> 16, (bits & 0xff00) >> 8 , (bits & 0xff))
而现在,答案是对的!!
#!/usr/bin/python
>>> addressInNetwork('188.104.8.64','172.16.0.0/12')
False
我希望它会帮助其他人,为他们节省时间!
关于上述所有内容,我认为 socket.inet_aton() 按网络顺序返回字节,因此解压它们的正确方法可能是
struct.unpack('!L', ... )
import socket,struct
def addressInNetwork(ip,net):
"Is an address in a network"
ipaddr = struct.unpack('!L',socket.inet_aton(ip))[0]
netaddr,bits = net.split('/')
netaddr = struct.unpack('!L',socket.inet_aton(netaddr))[0]
netmask = ((1<<(32-int(bits))) - 1)^0xffffffff
return ipaddr & netmask == netaddr & netmask
print addressInNetwork('10.10.10.110','10.10.10.128/25')
print addressInNetwork('10.10.10.110','10.10.10.0/25')
print addressInNetwork('10.10.10.110','10.20.10.128/25')
$ python check-subnet.py
假
真
假
从上面的各种来源以及我自己的研究来看,这就是我如何让子网和地址计算工作的方式。这些作品足以解决问题和其他相关问题。
class iptools:
@staticmethod
def dottedQuadToNum(ip):
"convert decimal dotted quad string to long integer"
return struct.unpack('>L', socket.inet_aton(ip))[0]
@staticmethod
def numToDottedQuad(n):
"convert long int to dotted quad string"
return socket.inet_ntoa(struct.pack('>L', n))
@staticmethod
def makeNetmask(mask):
bits = 0
for i in xrange(32-int(mask), 32):
bits |= (1 << i)
return bits
@staticmethod
def ipToNetAndHost(ip, maskbits):
"returns tuple (network, host) dotted-quad addresses given"
" IP and mask size"
# (by Greg Jorgensen)
n = iptools.dottedQuadToNum(ip)
m = iptools.makeMask(maskbits)
net = n & m
host = n - mask
return iptools.numToDottedQuad(net), iptools.numToDottedQuad(host)
在 python 中有一个称为 SubnetTree 的 API 可以很好地完成这项工作。这是一个简单的例子:
import SubnetTree
t = SubnetTree.SubnetTree()
t.insert("10.0.1.3/32")
print("10.0.1.3" in t)
这是我的代码
# -*- coding: utf-8 -*-
import socket
class SubnetTest(object):
def __init__(self, network):
self.network, self.netmask = network.split('/')
self._network_int = int(socket.inet_aton(self.network).encode('hex'), 16)
self._mask = ((1L << int(self.netmask)) - 1) << (32 - int(self.netmask))
self._net_prefix = self._network_int & self._mask
def match(self, ip):
'''
判断传入的 IP 是不是本 Network 内的 IP
'''
ip_int = int(socket.inet_aton(ip).encode('hex'), 16)
return (ip_int & self._mask) == self._net_prefix
st = SubnetTest('100.98.21.0/24')
print st.match('100.98.23.32')
如果您不想导入其他模块,可以使用:
def ip_matches_network(self, network, ip):
"""
'{:08b}'.format(254): Converts 254 in a string of its binary representation
ip_bits[:net_mask] == net_ip_bits[:net_mask]: compare the ip bit streams
:param network: string like '192.168.33.0/24'
:param ip: string like '192.168.33.1'
:return: if ip matches network
"""
net_ip, net_mask = network.split('/')
net_mask = int(net_mask)
ip_bits = ''.join('{:08b}'.format(int(x)) for x in ip.split('.'))
net_ip_bits = ''.join('{:08b}'.format(int(x)) for x in net_ip.split('.'))
# example: net_mask=24 -> compare strings at position 0 to 23
return ip_bits[:net_mask] == net_ip_bits[:net_mask]
我在这些答案中尝试了提议的解决方案的一个子集。没有成功,我最终调整并修复了提议的代码并编写了我的固定函数。
我对其进行了测试,并且至少可以在小端架构上工作——egx86——如果有人喜欢尝试大端架构,请给我反馈。
IP2Int
代码来自这篇文章,另一种方法是完全(对于我的测试用例)对这个问题中先前提案的工作修复。
编码:
def IP2Int(ip):
o = map(int, ip.split('.'))
res = (16777216 * o[0]) + (65536 * o[1]) + (256 * o[2]) + o[3]
return res
def addressInNetwork(ip, net_n_bits):
ipaddr = IP2Int(ip)
net, bits = net_n_bits.split('/')
netaddr = IP2Int(net)
bits_num = int(bits)
netmask = ((1L << bits_num) - 1) << (32 - bits_num)
return ipaddr & netmask == netaddr & netmask
希望有用,
这是使用 netaddr 包的解决方案
from netaddr import IPNetwork, IPAddress
def network_has_ip(network, ip):
if not isinstance(network, IPNetwork):
raise Exception("network parameter must be {0} instance".format(IPNetwork.__name__))
if not isinstance(ip, IPAddress):
raise Exception("ip parameter must be {0} instance".format(IPAddress.__name__))
return (network.cidr.ip.value & network.netmask.value) == (ip.value & network.netmask.value)