def add_network(self, addr): if addr is "": return block = addr.split('/') addr_family = is_ip(block[0]) addr_len = IPNetwork.ADDRLENGTH[addr_family] if addr_family is socket.AF_INET: ip, = struct.unpack("!I", socket.inet_aton(block[0])) elif addr_family is socket.AF_INET6: hi, lo = struct.unpack("!QQ", inet_pton(addr_family, block[0])) ip = (hi << 64) | lo else: raise Exception("Not a valid CIDR notation: %s" % addr) if len(block) is 1: prefix_size = 0 while (ip & 1) == 0 and ip is not 0: ip >>= 1 prefix_size += 1 logging.warn("You did't specify CIDR routing prefix size for %s, " "implicit treated as %s/%d" % (addr, addr, addr_len)) elif block[1].isdigit() and int(block[1]) <= addr_len: prefix_size = addr_len - int(block[1]) ip >>= prefix_size else: raise Exception("Not a valid CIDR notation: %s" % addr) if addr_family is socket.AF_INET: self._network_list_v4.append((ip, prefix_size)) else: self._network_list_v6.append((ip, prefix_size))
def parse_header(data): addrtype = ord(data[0]) dest_addr = None dest_port = None header_length = 0 connecttype = (addrtype & 0x8) and 1 or 0 addrtype &= ~0x8 if addrtype == ADDRTYPE_IPV4: if len(data) >= 7: dest_addr = socket.inet_ntoa(data[1:5]) dest_port = struct.unpack('>H', data[5:7])[0] header_length = 7 else: logging.warn('header is too short') elif addrtype == ADDRTYPE_HOST: if len(data) > 2: addrlen = ord(data[1]) if len(data) >= 4 + addrlen: dest_addr = data[2:2 + addrlen] dest_port = struct.unpack('>H', data[2 + addrlen:4 + addrlen])[0] header_length = 4 + addrlen else: logging.warn('header is too short') else: logging.warn('header is too short') elif addrtype == ADDRTYPE_IPV6: if len(data) >= 19: dest_addr = socket.inet_ntop(socket.AF_INET6, data[1:17]) dest_port = struct.unpack('>H', data[17:19])[0] header_length = 19 else: logging.warn('header is too short') else: logging.warn('unsupported addrtype %d, maybe wrong password or ' 'encryption method' % addrtype) if dest_addr is None: return None return connecttype, addrtype, to_bytes(dest_addr), dest_port, header_length
def pre_parse_header(data): if not data: return None datatype = ord(data[0]) if datatype == 0x80: if len(data) <= 2: return None rand_data_size = ord(data[1]) if rand_data_size + 2 >= len(data): logging.warn('header too short, maybe wrong password or ' 'encryption method') return None data = data[rand_data_size + 2:] elif datatype == 0x81: data = data[1:] elif datatype == 0x82: if len(data) <= 3: return None rand_data_size = struct.unpack('>H', data[1:3])[0] if rand_data_size + 3 >= len(data): logging.warn('header too short, maybe wrong password or ' 'encryption method') return None data = data[rand_data_size + 3:] elif datatype == 0x88 or (~datatype & 0xff) == 0x88: if len(data) <= 7 + 7: return None data_size = struct.unpack('>H', data[1:3])[0] ogn_data = data data = data[:data_size] crc = binascii.crc32(data) & 0xffffffff if crc != 0xffffffff: logging.warn('uncorrect CRC32, maybe wrong password or ' 'encryption method') return None start_pos = 3 + ord(data[3]) data = data[start_pos:-4] if data_size < len(ogn_data): data += ogn_data[data_size:] return data