1 """IP address set manipulation, built on top of ipaddr.py"""
3 # This file is Free Software. It was originally written for secnet.
5 # Copyright 2014 Ian Jackson
7 # You may redistribute secnet as a whole and/or modify it under the
8 # terms of the GNU General Public License as published by the Free
9 # Software Foundation; either version 3, or (at your option) any
12 # You may redistribute this file and/or modify it under the terms of
13 # the GNU General Public License as published by the Free Software
14 # Foundation; either version 2, or (at your option) any later version.
15 # Note however that this version of ipaddrset.py uses the Python
16 # ipaddr library from Google, which is licenced only under the Apache
17 # Licence, version 2.0, which is only compatible with the GNU GPL v3
18 # (or perhaps later versions), and not with the GNU GPL v2.
20 # This software is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 # GNU General Public License for more details.
25 # You should have received a copy of the GNU General Public License
26 # along with this software; if not, see
27 # https://www.gnu.org/licenses/gpl.html.
34 "A set of IP addresses"
37 def __init__(self
,l
=[]):
38 "New set contains each ipaddr.IPNetwork in the sequence l"
44 # housekeeping and representation
47 self
._v
[v
] = ipaddr
.collapse_address_list(self
._v
[v
])
49 return "IPAddressSet(%s)" % self
.networks()
50 def str(self
,comma
=",",none
="-"):
51 "Human-readable string with controllable delimiters"
53 return comma
.join(map(str, self
.networks()))
61 "Appends each ipaddr.IPNetwork in the sequence l to self"
66 "Appends each ipaddr.IPNetwork in the sequence l to self"
68 self
._v
[a
.version
].append(a
)
70 # enquirers including standard comparisons
71 def __nonzero__(self
):
77 def __eq__(self
,other
):
79 if self
._v
[v
] != other
._v
[v
]:
82 def __ne__(self
,other
): return not self
.__eq__(other
)
83 def __ge__(self
,other
):
84 """True iff self completely contains IPAddressSet other"""
86 if not self
._contains_net(o
):
89 def __le__(self
,other
): return other
.__ge__(self
)
90 def __gt__(self
,other
): return self
!=other
and other
.__ge__(self
)
91 def __lt__(self
,other
): return other
.__gt__(self
)
93 def __cmp__(self
,other
):
94 if self
==other
: return 0
95 if self
>=other
: return +1
96 if self
<=other
: return -1
100 "Iterates over minimal list of distinct IPNetworks in this set"
106 "Returns miminal list of distinct IPNetworks in this set"
107 return [i
for i
in self
]
110 def intersection(self
,other
):
111 "Returns the intersection; does not modify self"
115 for j
in other
._v
[v
]:
117 if i
.prefixlen
> j
.prefixlen
:
122 def union(self
,other
):
123 "Returns the union; does not modify self"
125 r
._append(self
.networks())
126 r
._append(other
.networks())
130 def _contains_net(self
,n
):
131 """True iff self completely contains IPNetwork n"""
133 if i
.overlaps(n
) and n
.prefixlen
>= i
.prefixlen
:
137 def contains(self
,thing
):
138 """Returns True iff self completely contains thing.
139 thing may be an IPNetwork or an IPAddressSet"""
145 return self
._contains_net(ipaddr
.IPNetwork(thing
))
147 return self
.__ge__(thing
)
150 "Returns a set containing all addresses"
153 a
=ipaddr
.IPAddress(0,v
)
154 n
=ipaddr
.IPNetwork("%s/0" % a
)