78 """ |
78 """ |
79 Group an iterable of hexadecimal nibbles into hextets. |
79 Group an iterable of hexadecimal nibbles into hextets. |
80 """ |
80 """ |
81 |
81 |
82 for i in xrange(0, len(parts), 4) : |
82 for i in xrange(0, len(parts), 4) : |
83 yield ''.join(parts[i:i+4]) |
83 yield u''.join(parts[i:i+4]) |
84 |
84 |
85 # suffix :: |
85 # suffix :: |
86 if len(parts) < 32 : |
86 if len(parts) < 32 : |
87 yield '' |
87 yield u'' |
88 yield '' |
88 yield u'' |
89 |
89 |
90 def parse_prefix (prefix) : |
90 def parse_prefix (prefix) : |
91 """ |
91 """ |
92 Return an ipaddr.IPNetwork from given filesystem-compatbile IPv4/IPv6 prefix-ish variant. |
92 Return an ipaddress.IPNetwork from given filesystem-compatbile IPv4/IPv6 prefix-ish variant. |
93 |
93 |
94 Supports partial IPv4 prefixes on octet boundaries. |
94 Supports partial IPv4 prefixes on octet boundaries. |
95 Supports partial IPv6 prefixes on nibble boundaries. |
95 Supports partial IPv6 prefixes on nibble boundaries. |
96 Supports IPv4 prefxies using "-" as the prefix separator in place of "/". |
96 Supports IPv4 prefxies using "-" as the prefix separator in place of "/". |
97 |
97 |
98 >>> parse_prefix('127.0.0.0/8') |
98 >>> print parse_prefix('127.0.0.0/8') |
99 IPv4Network('127.0.0.0/8') |
99 127.0.0.0/8 |
100 >>> parse_prefix('192.0.2.128/26') |
100 >>> print parse_prefix('192.0.2.128/26') |
101 IPv4Network('192.0.2.128/26') |
101 192.0.2.128/26 |
102 >>> parse_prefix('192.0.2.128-26') |
102 >>> print parse_prefix('192.0.2.128-26') |
103 IPv4Network('192.0.2.128/26') |
103 192.0.2.128/26 |
104 >>> parse_prefix('127.') |
104 >>> print parse_prefix('127.') |
105 IPv4Network('127.0.0.0/8') |
105 127.0.0.0/8 |
106 >>> parse_prefix('10') |
106 >>> print parse_prefix('10') |
107 IPv4Network('10.0.0.0/8') |
107 10.0.0.0/8 |
108 >>> parse_prefix('192.168') |
108 >>> print parse_prefix('192.168') |
109 IPv4Network('192.168.0.0/16') |
109 192.168.0.0/16 |
110 >>> parse_prefix('fe80::') |
110 >>> print parse_prefix('fe80::') |
111 IPv6Network('fe80::/16') |
111 fe80::/16 |
112 >>> parse_prefix('2001:db8::') |
112 >>> print parse_prefix('2001:db8::') |
113 IPv6Network('2001:db8::/32') |
113 2001:db8::/32 |
114 >>> parse_prefix('2001:db8:1:2') |
114 >>> print parse_prefix('2001:db8:1:2') |
115 IPv6Network('2001:db8:1:2::/64') |
115 2001:db8:1:2::/64 |
116 """ |
116 """ |
117 |
117 |
|
118 prefix = unicode(prefix) |
|
119 |
118 if '/' in prefix : |
120 if '/' in prefix : |
119 return ipaddr.IPNetwork(prefix) |
121 return ipaddress.ip_network(prefix) |
120 |
122 |
121 elif '-' in prefix : |
123 elif '-' in prefix : |
122 return ipaddr.IPNetwork(prefix.replace('-', '/')) |
124 return ipaddress.ip_network(prefix.replace('-', '/')) |
123 |
125 |
124 elif '.' in prefix or prefix.isdigit() : |
126 elif '.' in prefix or prefix.isdigit() : |
125 parts = prefix.rstrip('.').split('.') |
127 parts = prefix.rstrip('.').split('.') |
126 prefixlen = len(parts) * 8 |
128 prefixlen = len(parts) * 8 |
127 |
129 |
128 return ipaddr.IPv4Network('{prefix}/{prefixlen}'.format( |
130 return ipaddress.IPv4Network(u'{prefix}/{prefixlen}'.format( |
129 prefix = '.'.join(parts + ['0' for i in xrange(4 - len(parts))]), |
131 prefix = u'.'.join(parts + [u'0' for i in xrange(4 - len(parts))]), |
130 prefixlen = prefixlen, |
132 prefixlen = prefixlen, |
131 )) |
133 )) |
132 |
134 |
133 elif ':' in prefix : |
135 elif ':' in prefix : |
134 parts = list(_split_ipv6_parts(prefix)) |
136 parts = list(_split_ipv6_parts(prefix)) |
135 prefixlen = len(parts) * 4 |
137 prefixlen = len(parts) * 4 |
136 |
138 |
137 return ipaddr.IPv6Network('{prefix}/{prefixlen}'.format( |
139 return ipaddress.IPv6Network(u'{prefix}/{prefixlen}'.format( |
138 prefix = ':'.join(_build_ipv6_parts(parts)), |
140 prefix = u':'.join(_build_ipv6_parts(parts)), |
139 prefixlen = prefixlen, |
141 prefixlen = prefixlen, |
140 )) |
142 )) |
141 |
143 |
142 else : |
144 else : |
143 raise ValueError("Unrecognized IP prefix string: %s" % (prefix, )) |
145 raise ValueError("Unrecognized IP prefix string: %s" % (prefix, )) |