예제 #1
0
 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))
예제 #2
0
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
예제 #3
0
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