Example #1
0
    def __udp_local_proxy_for_send(self, byte_data):
        """当地UDP代理,该代理不经过加密隧道"""
        ihl = (byte_data[0] & 0x0f) * 4
        offset = ((byte_data[6] & 0x1f) << 5) | byte_data[7]

        # 说明不是第一个数据分包,那么就直接发送给raw socket
        if offset:
            L = list(byte_data)
            checksum.modify_address(b"\0\0\0\0", L, checksum.FLAG_MODIFY_SRC_IP)
            self.send_message_to_handler(self.fileno, self.__traffic_send_fd, bytes(L))
            return

        b, e = (ihl, ihl + 1,)
        sport = (byte_data[b] << 8) | byte_data[e]
        saddr = socket.inet_ntoa(byte_data[12:16])
        uniq_id = self.__get_id((saddr, sport,))

        fileno = 0
        if uniq_id not in self.__udp_natp_to_fd:
            fileno = self.create_handler(self.fileno, traffic_pass.udp_proxy,
                                         self.__traffic_send_fd, (saddr, sport,),
                                         uniq_id)
            self.__udp_natp_to_fd[uniq_id] = fileno
        else:
            fileno = self.__udp_natp_to_fd[uniq_id]
        self.send_message_to_handler(self.fileno, fileno, byte_data)
Example #2
0
    def get_new_packet_for_lan(self, pkt):
        """获取要发送给局域网机器的包
        :param pkt:收到的要发给局域网机器的包
        """
        dst_addr = pkt[16:20]
        # 如果没在nat表中,那么不执行转换
        if dst_addr not in self.__dst_nat_table: return None

        dst_lan = self.__dst_nat_table[dst_addr]
        self.__timer.set_timeout(dst_addr, self.__IP_TIMEOUT)
        pkt_list = list(pkt)
        checksum.modify_address(dst_lan, pkt_list, checksum.FLAG_MODIFY_DST_IP)

        return bytes(pkt_list)
Example #3
0
    def get_ippkt2sLan_from_cLan(self, session_id, ippkt):
        clan_saddr = ippkt[12:16]
        slan_saddr = self.find_sLanAddr_by_cLanAddr(session_id, clan_saddr)

        if not slan_saddr:
            slan_saddr = self.__ip_alloc.get_addr()
            self.add2Lan(session_id, clan_saddr, slan_saddr)

        data_list = list(ippkt)
        checksum.modify_address(slan_saddr, data_list,
                                checksum.FLAG_MODIFY_SRC_IP)
        self.__timer.set_timeout(slan_saddr, self.__VALID_TIME)

        return bytes(data_list)
Example #4
0
    def get_ippkt2cLan_from_sLan(self, ippkt):
        slan_daddr = ippkt[16:20]
        rs = self.find_cLanAddr_by_sLanAddr(slan_daddr)

        if not rs: return None

        data_list = list(ippkt)
        checksum.modify_address(rs["clan_addr"], data_list,
                                checksum.FLAG_MODIFY_DST_IP)
        self.__timer.set_timeout(slan_daddr, self.__VALID_TIME)

        return (
            rs["session_id"],
            bytes(data_list),
        )
Example #5
0
    def get_new_packet_to_tunnel(self, pkt):
        """获取要发送到tunnel的IP包
        :param pkt:从局域网机器读取过来的包
        """
        src_addr = pkt[12:16]
        vir_ip = self.__src_nat_table.get(src_addr, None)

        if not vir_ip and not self.__virtual_ips: return None
        if not vir_ip: vir_ip = self.__virtual_ips.pop(0)

        pkt_list = list(pkt)
        checksum.modify_address(vir_ip, pkt_list, checksum.FLAG_MODIFY_SRC_IP)

        self.__timer.set_timeout(vir_ip, self.__IP_TIMEOUT)

        if vir_ip not in self.__dst_nat_table: self.__dst_nat_table[vir_ip] = src_addr
        if src_addr not in self.__src_nat_table: self.__src_nat_table[src_addr] = vir_ip

        return bytes(pkt_list)
Example #6
0
    def __send_ipv4_msg_to_udp_proxy(self, session_id, message):
        # 检查长度是否合法
        msg_len = len(message)
        if msg_len < 21: return

        ihl = (message[0] & 0x0f) * 4
        pkt_len = (message[2] << 8) | message[3]
        b = ihl + 4
        e = b + 1
        udp_len = (message[b] << 8) | message[e]
        offset = ((message[6] & 0x1f) << 5) | message[7]
        flags = ((message[6]) & 0xe0) >> 5
        df = (flags & 0x2) >> 1
        mf = flags & 0x1

        if df and udp_len >= pkt_len: return
        if udp_len == 0 and offset == 0: return
        if df == 0 and mf == 1 and offset == 0 and udp_len < 512: return

        offset = ((message[6] & 0x1f) << 5) | message[7]

        # 说明不是第一个数据分包,那么就直接发送给raw socket
        if offset:
            L = list(message)
            checksum.modify_address(b"\0\0\0\0", L,
                                    checksum.FLAG_MODIFY_SRC_IP)
            self.send_message_to_handler(-1, self.__raw_socket_fd, bytes(L))
            return
        # 丢弃长度不合法的数据包
        if not offset and msg_len < 28: return

        b, e = (
            ihl,
            ihl + 1,
        )
        sport = (message[b] << 8) | message[e]
        saddr = socket.inet_ntoa(message[12:16])

        if not self.__udp_proxy_exists(session_id, saddr, sport):
            self.__create_udp_proxy(session_id, saddr, sport)
        fileno = self.__get_udp_proxy(session_id, saddr, sport)

        self.send_message_to_handler(-1, fileno, message)
Example #7
0
    def __handle_udp_data(self, byte_data, address):
        """对UDP协议进行特别处理,以实现CONE NAT模型
        """
        # flags = (byte_data[6] & 0xe0) >> 5
        # flag_df = (flags & 0x2) >> 1
        # flags_mf = flags & 0x1
        offset = ((byte_data[6] & 0x1f) << 5) | byte_data[7]

        # 说明不是第一个数据分包,那么就直接发送给raw socket
        if offset:
            L = list(byte_data)
            checksum.modify_address(b"\0\0\0\0", L,
                                    checksum.FLAG_MODIFY_SRC_IP)
            self.send_message_to_handler(self.fileno, self.__raw_socket_fd,
                                         bytes(L))
            return

        ihl = (byte_data[0] & 0x0f) * 4
        saddr = socket.inet_ntoa(byte_data[12:16])
        b = ihl
        e = ihl + 1
        sport = (byte_data[b] << 8) | byte_data[e]

        uniq_id = "%s-%s" % address
        session_cls = self.__sessions[uniq_id]

        udp_nat_map = session_cls.udp_nat_map

        uniq_nat_id = "%s-%s" % (saddr, sport)

        if uniq_nat_id not in udp_nat_map:
            fileno = self.create_handler(self.fileno, traffic_pass.udp_proxy,
                                         self.__raw_socket_fd, (
                                             saddr,
                                             sport,
                                         ), uniq_id)
            udp_nat_map[uniq_nat_id] = fileno
        else:
            fileno = udp_nat_map[uniq_nat_id]

        self.send_message_to_handler(self.fileno, fileno, byte_data)
Example #8
0
    def __handle_udp_data(self, byte_data, address):
        """对UDP协议进行特别处理,以实现CONE NAT模型
        """
        # flags = (byte_data[6] & 0xe0) >> 5
        # flag_df = (flags & 0x2) >> 1
        # flags_mf = flags & 0x1
        offset = ((byte_data[6] & 0x1f) << 5) | byte_data[7]

        # 说明不是第一个数据分包,那么就直接发送给raw socket
        if offset:
            L = list(byte_data)
            checksum.modify_address(b"\0\0\0\0", L, checksum.FLAG_MODIFY_SRC_IP)
            self.send_message_to_handler(self.fileno, self.__raw_socket_fd, bytes(L))
            return

        ihl = (byte_data[0] & 0x0f) * 4
        saddr = socket.inet_ntoa(byte_data[12:16])
        b = ihl
        e = ihl + 1
        sport = (byte_data[b] << 8) | byte_data[e]

        uniq_id = "%s-%s" % address
        session_cls = self.__sessions[uniq_id]

        udp_nat_map = session_cls.udp_nat_map

        uniq_nat_id = "%s-%s" % (saddr, sport)

        if uniq_nat_id not in udp_nat_map:
            fileno = self.create_handler(self.fileno, traffic_pass.udp_proxy,
                                         self.__raw_socket_fd,
                                         (saddr, sport,),
                                         uniq_id)
            udp_nat_map[uniq_nat_id] = fileno
        else:
            fileno = udp_nat_map[uniq_nat_id]

        self.send_message_to_handler(self.fileno, fileno, byte_data)