Viewing file: _inet.py (4.55 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function
import socket import struct
from ._errors import unwrap from ._types import byte_cls, bytes_to_list, str_cls, type_name
def inet_ntop(address_family, packed_ip): """ Windows compatibility shim for socket.inet_ntop().
:param address_family: socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6
:param packed_ip: A byte string of the network form of an IP address
:return: A unicode string of the IP address """
if address_family not in set([socket.AF_INET, socket.AF_INET6]): raise ValueError(unwrap( ''' address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s), not %s ''', repr(socket.AF_INET), repr(socket.AF_INET6), repr(address_family) ))
if not isinstance(packed_ip, byte_cls): raise TypeError(unwrap( ''' packed_ip must be a byte string, not %s ''', type_name(packed_ip) ))
required_len = 4 if address_family == socket.AF_INET else 16 if len(packed_ip) != required_len: raise ValueError(unwrap( ''' packed_ip must be %d bytes long - is %d ''', required_len, len(packed_ip) ))
if address_family == socket.AF_INET: return '%d.%d.%d.%d' % tuple(bytes_to_list(packed_ip))
octets = struct.unpack(b'!HHHHHHHH', packed_ip)
runs_of_zero = {} longest_run = 0 zero_index = None for i, octet in enumerate(octets + (-1,)): if octet != 0: if zero_index is not None: length = i - zero_index if length not in runs_of_zero: runs_of_zero[length] = zero_index longest_run = max(longest_run, length) zero_index = None elif zero_index is None: zero_index = i
hexed = [hex(o)[2:] for o in octets]
if longest_run < 2: return ':'.join(hexed)
zero_start = runs_of_zero[longest_run] zero_end = zero_start + longest_run
return ':'.join(hexed[:zero_start]) + '::' + ':'.join(hexed[zero_end:])
def inet_pton(address_family, ip_string): """ Windows compatibility shim for socket.inet_ntop().
:param address_family: socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6
:param ip_string: A unicode string of an IP address
:return: A byte string of the network form of the IP address """
if address_family not in set([socket.AF_INET, socket.AF_INET6]): raise ValueError(unwrap( ''' address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s), not %s ''', repr(socket.AF_INET), repr(socket.AF_INET6), repr(address_family) ))
if not isinstance(ip_string, str_cls): raise TypeError(unwrap( ''' ip_string must be a unicode string, not %s ''', type_name(ip_string) ))
if address_family == socket.AF_INET: octets = ip_string.split('.') error = len(octets) != 4 if not error: ints = [] for o in octets: o = int(o) if o > 255 or o < 0: error = True break ints.append(o)
if error: raise ValueError(unwrap( ''' ip_string must be a dotted string with four integers in the range of 0 to 255, got %s ''', repr(ip_string) ))
return struct.pack(b'!BBBB', *ints)
error = False omitted = ip_string.count('::') if omitted > 1: error = True elif omitted == 0: octets = ip_string.split(':') error = len(octets) != 8 else: begin, end = ip_string.split('::') begin_octets = begin.split(':') end_octets = end.split(':') missing = 8 - len(begin_octets) - len(end_octets) octets = begin_octets + (['0'] * missing) + end_octets
if not error: ints = [] for o in octets: o = int(o, 16) if o > 65535 or o < 0: error = True break ints.append(o)
return struct.pack(b'!HHHHHHHH', *ints)
raise ValueError(unwrap( ''' ip_string must be a valid ipv6 string, got %s ''', repr(ip_string) ))
|