Exemple #1
0
    def __get_pkt_port_info(self, mbuf):
        mbuf.offset = 48
        sport = utils.bytes2number(mbuf.get_part(2))
        mbuf.offset = 50
        dport = utils.bytes2number(mbuf.get_part(2))

        return (sport, dport,)
Exemple #2
0
    def __get_ipv4_dgram_pkt_addr_info(self):
        """获取数据包的地址信息
        :param mbuf:
        :return:
        """
        mbuf = self.__mbuf

        hdrlen = self.__get_ip4_hdrlen()

        mbuf.offset = hdrlen + 2
        dport = utils.bytes2number(mbuf.get_part(2))
        mbuf.offset = hdrlen
        sport = utils.bytes2number(mbuf.get_part(2))

        mbuf.offset = 16
        daddr = mbuf.get_part(4)
        mbuf.offset = 12
        saddr = mbuf.get_part(4)

        return (
            socket.inet_ntoa(saddr),
            socket.inet_ntoa(daddr),
            sport,
            dport,
        )
Exemple #3
0
    def __handle_ipv6_data_from_tunnel(self):
        self.__mbuf.offset = 4
        payload_length = utils.bytes2number(self.__mbuf.get_part(2))
        if payload_length + 40 != self.__mbuf.payload_size: return

        self.__mbuf.offset = 6
        nexthdr = self.__mbuf.get_part(1)

        if nexthdr not in self.__support_protocols: return

        self.__mbuf.offset = 24
        byte_dst_addr = self.__mbuf.get_part(16)
        self.__mbuf.offset = 42
        byte_dst_port = self.__mbuf.get_part(2)
        dst_port = utils.bytes2number(byte_dst_port)

        rule = self.__port_mapv6.find_rule_for_in(byte_dst_addr, nexthdr,
                                                  dst_port)
        if not rule: return

        self.__mbuf.offset = 8
        byte_src_addr = self.__mbuf.get_part(16)
        src_addr = socket.inet_ntop(socket.AF_INET6, byte_src_addr)
        k = "%s/132" % src_addr

        if k not in self.__routes:
            self.set_route(src_addr, prefix=132, is_ipv6=True)
        # 此处重写IP地址
        byte_rewrite, extra_data = rule
        ippkts.modify_ip6address(byte_rewrite, self.__mbuf, flags=1)
        self.__mbuf.offset = 0
        byte_data = self.__mbuf.get_data()
        self.get_handler(self.__tundev_fileno).msg_from_tunnel(byte_data)
Exemple #4
0
    def __get_pkt_addr_info(self, mbuf):
        """获取数据包的地址信息
        :param mbuf:
        :return:
        """
        mbuf.offset = 0
        n = mbuf.get_part(1)
        hdrlen = (n & 0x0f) * 4

        mbuf.offset = hdrlen + 2
        dport = utils.bytes2number(mbuf.get_part(2))
        mbuf.offset = hdrlen
        sport = utils.bytes2number(mbuf.get_part(2))

        mbuf.offset = 16
        daddr = mbuf.get_part(4)
        mbuf.offset = 12
        saddr = mbuf.get_part(4)

        return (
            socket.inet_ntoa(saddr),
            socket.inet_ntoa(daddr),
            sport,
            dport,
        )
Exemple #5
0
def modify_port(port, mbuf, flags=0):
    """修改TCP/SCTP/UDP/UDPLite端口
    :param port:
    :param mbuf:
    :param flags: 0表示修改源端口,1表示修改目的端口
    :return:
    """
    protocols = (
        6,
        17,
        132,
        136,
    )
    ip_ver = mbuf.ip_version()
    p = __get_protocol(mbuf)

    if p not in protocols:
        raise ValueError("unsupport IP protocol for modify port")

    if ip_ver == 4:
        hdrlen = __get_ip4_hdrlen(mbuf)
    else:
        hdrlen = 40

    if flags == 0:
        port_off = hdrlen
    else:
        port_off = hdrlen + 2

    mbuf.offset = port_off
    # SCTP特别处理
    if p == 132:
        mbuf.replace(utils.number2bytes(port, 2))
        return

    old_port = utils.bytes2number(mbuf.get_part(2))

    if p in (
            6,
            136,
    ):
        csum_offset = hdrlen + 6
    else:
        csum_offset = hdrlen + 16

    mbuf.offset = csum_offset
    csum = utils.bytes2number(mbuf.get_part(2))

    mbuf.offset = port_off
    mbuf.replace(utils.number2bytes(port, 2))

    # 如果旧的校检和为0,说明不需要进行校检和计算
    if csum == 0: return

    mbuf.offset = csum_offset
    csum = fn_utils.calc_incre_csum(csum, old_port, port)
    mbuf.replace(utils.number2bytes(csum, 2))
Exemple #6
0
    def __get_pkt_port_info(self, mbuf):
        mbuf.offset = 48
        sport = utils.bytes2number(mbuf.get_part(2))
        mbuf.offset = 50
        dport = utils.bytes2number(mbuf.get_part(2))

        return (
            sport,
            dport,
        )
Exemple #7
0
    def __is_dns_request(self):
        mbuf = self.__mbuf
        ip_ver = mbuf.ip_version()

        if ip_ver == 4:
            mbuf.offset = 0
            n = mbuf.get_part(1)
            hdrlen = (n & 0x0f) * 4

            mbuf.offset = 9
            nexthdr = mbuf.get_part(1)

            mbuf.offset = 12
            saddr = mbuf.get_part(4)
            mbuf.offset = 16
            daddr = mbuf.get_part(4)
        else:
            mbuf.offset = 6
            nexthdr = mbuf.get_part(1)
            hdrlen = 40
            mbuf.offset = 8
            saddr = mbuf.get_part(16)
            mbuf.offset = 24
            daddr = mbuf.get_part(16)

        if (nexthdr != 17): return (False, None, None, None, None)

        mbuf.offset = hdrlen
        sport = utils.bytes2number(mbuf.get_part(2))

        mbuf.offset = hdrlen + 2
        dport = utils.bytes2number(mbuf.get_part(2))
        if dport != 53: return (
                False,
                None,
                None,
                None,
                None,
        )

        mbuf.offset = hdrlen + 8

        return (
            True,
            saddr,
            daddr,
            sport,
            mbuf.get_data(),
        )
Exemple #8
0
    def __handle_ipv4data_from_tunnel(self, session_id):
        self.__mbuf.offset = 9
        protocol = self.__mbuf.get_part(1)

        hdrlen = self.__get_ip4_hdrlen()
        if hdrlen + 8 < 28: return False

        # 检查IP数据报长度是否合法
        self.__mbuf.offset = 2
        payload_length = utils.bytes2number(self.__mbuf.get_part(2))
        if payload_length != self.__mbuf.payload_size: return False

        if protocol not in self.__support_ip4_protocols: return False

        # 对UDP和UDPLite进行特殊处理,以支持内网穿透
        if protocol == 17 or protocol == 136:
            is_udplite = False
            if protocol == 136: is_udplite = True
            self.__handle_ipv4_dgram_from_tunnel(session_id, is_udplite=is_udplite)
            return True
        self.__mbuf.offset = 0

        rs = self.__nat4.get_ippkt2sLan_from_cLan(session_id, self.__mbuf)
        if not rs: return
        self.__mbuf.offset = 0
        self.get_handler(self.__tundev_fileno).handle_msg_from_tunnel(self.__mbuf.get_data())
        return True
Exemple #9
0
    def __handle_ipv6data_from_tunnel(self, session_id):
        # 如果NAT66没开启那么丢弃IPV6数据包
        if not self.__enable_nat6: return False

        if self.__mbuf.payload_size < 48: return False

        # 检查IPV6数据包长度是否合法
        self.__mbuf.offset = 4
        payload_length = utils.bytes2number(self.__mbuf.get_part(2))
        if payload_length + 40 != self.__mbuf.payload_size: return False

        self.__mbuf.offset = 6
        nexthdr = self.__mbuf.get_part(1)

        if nexthdr not in self.__support_ip6_protocols: return False

        self.__mbuf.offset = 40
        nexthdr = self.__mbuf.get_part(1)

        if nexthdr in (17, 136,) and self.__ip6_udp_cone_nat:
            is_udplite = False
            if nexthdr == 136: is_udplite = True
            self.__handle_ipv6_dgram_from_tunnel(session_id, is_udplite=is_udplite)
            return True

        b = self.__nat6.get_ippkt2sLan_from_cLan(session_id, self.__mbuf)
        if not b: return False

        self.__mbuf.offset = 24
        self.__mbuf.offset = 0
        self.get_handler(self.__tundev_fileno).handle_msg_from_tunnel(self.__mbuf.get_data())

        return True
Exemple #10
0
    def __handle_ipv4data_from_tunnel(self, session_id):
        self.__mbuf.offset = 9
        protocol = self.__mbuf.get_part(1)

        hdrlen = self.__get_ip4_hdrlen()
        if hdrlen + 8 < 28: return False

        # 检查IP数据报长度是否合法
        self.__mbuf.offset = 2
        payload_length = utils.bytes2number(self.__mbuf.get_part(2))
        if payload_length != self.__mbuf.payload_size: return False

        if protocol not in self.__support_ip4_protocols: return False

        # 对UDP和UDPLite进行特殊处理,以支持内网穿透
        if protocol == 17 or protocol == 136:
            is_udplite = False
            if protocol == 136: is_udplite = True
            self.__handle_ipv4_dgram_from_tunnel(session_id, is_udplite=is_udplite)
            return True
        self.__mbuf.offset = 0

        rs = self.__nat4.get_ippkt2sLan_from_cLan(session_id, self.__mbuf)
        if not rs: return
        self.__mbuf.offset = 0
        self.get_handler(self.__tundev_fileno).handle_msg_from_tunnel(self.__mbuf.get_data())
        return True
Exemple #11
0
    def __handle_ipv6data_from_tunnel(self, session_id):
        # 如果NAT66没开启那么丢弃IPV6数据包
        if not self.__enable_nat6: return False

        if self.__mbuf.payload_size < 48: return False

        # 检查IPV6数据包长度是否合法
        self.__mbuf.offset = 4
        payload_length = utils.bytes2number(self.__mbuf.get_part(2))
        if payload_length + 40 != self.__mbuf.payload_size: return False

        self.__mbuf.offset = 6
        nexthdr = self.__mbuf.get_part(1)

        if nexthdr not in self.__support_ip6_protocols: return False

        self.__mbuf.offset = 40
        nexthdr = self.__mbuf.get_part(1)

        if nexthdr in (17, 136,) and self.__ip6_udp_cone_nat:
            is_udplite = False
            if nexthdr == 136: is_udplite = True
            self.__handle_ipv6_dgram_from_tunnel(session_id, is_udplite=is_udplite)
            return True

        b = self.__nat6.get_ippkt2sLan_from_cLan(session_id, self.__mbuf)
        if not b: return False

        self.__mbuf.offset = 24
        self.__mbuf.offset = 0
        self.get_handler(self.__tundev_fileno).handle_msg_from_tunnel(self.__mbuf.get_data())

        return True
Exemple #12
0
    def __handle_ipv6_msg_from_tundev(self):
        self.__mbuf.offset = 6
        nexthdr = self.__mbuf.get_part(1)
        self.__mbuf.offset = 8
        byte_saddr = self.__mbuf.get_part(16)

        if nexthdr not in self.__support_protocols: return

        self.__mbuf.offset = 40

        byte_sport = self.__mbuf.get_part(2)
        src_port = utils.bytes2number(byte_sport)

        rules = self.__port_mapv6.find_rule_for_out(byte_saddr, nexthdr,
                                                    src_port)
        if not rules: return

        in_key, byte_src_ip, p, port = rules
        ippkts.modify_ip6address(byte_saddr, self.__mbuf, flags=0)
        ippkts.modify_port(port, self.__mbuf, flags=0)

        self.__mbuf.offset = 0
        message = self.__mbuf.get_data()

        self.send_msg_to_tunnel(proto_utils.ACT_IPDATA, message)
Exemple #13
0
    def __handle_ipv4_msg_from_tundev(self):
        self.__mbuf.offset = 9
        protocol = self.__mbuf.get_part(1)
        self.__mbuf.offset = 12
        byte_saddr = self.__mbuf.get_part(4)

        if protocol not in self.__support_protocols: return

        hdrlen = self.__get_ip4_hdrlen()
        if hdrlen < 28: return

        self.__mbuf.offset = hdrlen
        byte_sport = self.__mbuf.get_part(2)
        src_port = utils.bytes2number(byte_sport)

        rules = self.__port_mapv4.find_rule_for_out(byte_saddr, protocol,
                                                    src_port)
        if not rules: return

        in_key, byte_src_ip, p, port = rules
        ippkts.modify_ip4address(byte_saddr, self.__mbuf, flags=0)
        ippkts.modify_port(port, self.__mbuf, flags=0)

        self.__mbuf.offset = 0
        message = self.__mbuf.get_data()

        self.send_msg_to_tunnel(proto_utils.ACT_IPDATA, message)
Exemple #14
0
    def put_addr(self, byte_ip):
        n = utils.bytes2number(byte_ip)

        if n == self.__cur_max_ipaddr_num:
            self.__cur_max_ipaddr_num -= 1
            return
        self.__no_use_iplist_num.append(n)
Exemple #15
0
    def __handle_ipv4data_from_tunnel(self, session_id):
        self.__mbuf.offset = 9
        protocol = self.__mbuf.get_part(1)

        hdrlen = self.__get_ip4_hdrlen()
        if hdrlen + 8 < 28: return False

        # 检查IP数据报长度是否合法
        self.__mbuf.offset = 2
        payload_length = utils.bytes2number(self.__mbuf.get_part(2))
        if payload_length != self.__mbuf.payload_size: return False

        if protocol not in self.__support_ip4_protocols: return False

        # 对没有启用NAT内核模块UDP和UDPLite进行特殊处理,以支持内网穿透
        if (protocol == 17
                or protocol == 136) and not self.__enable_nat_module:
            is_udplite = False
            if protocol == 136: is_udplite = True
            self.__handle_ipv4_dgram_from_tunnel(session_id,
                                                 is_udplite=is_udplite)
            return True
        self.__mbuf.offset = 0

        rs = self.__nat4.get_ippkt2sLan_from_cLan(session_id, self.__mbuf)
        if not rs:
            logging.print_error(
                "cannot modify source address from client packet for ipv4")
            return
        self.__mbuf.offset = 0
        self.get_handler(self.__tundev_fileno).handle_msg_from_tunnel(
            self.__mbuf.get_data())
        return True
Exemple #16
0
    def add_frag(self, mbuf):
        mbuf.offset = 4
        byte_uniq_id = mbuf.get_part(2)

        mbuf.offset = 6
        frag_off = utils.bytes2number(mbuf.get_part(2))
        df = 0x4000 >> 14
        mf = 0x2000 >> 13
        offset = frag_off & 0x1fff

        mbuf.offset = 12
        saddr = mbuf.get_part(4)

        # 处理部分包只有一个分包的情况
        if df or (df == 0 and offset == 0 and mf == 0):
            saddr, daddr, sport, dport = self.__get_pkt_addr_info(mbuf)
            if dport == 0: return
            content = self.__get_transfer_content(mbuf)
            self.__ok_packets.append((
                saddr,
                daddr,
                sport,
                dport,
                content,
            ))
            return

        # 限制分包数目
        if offset > 2048: return

        _id = b"".join([saddr, byte_uniq_id])
        if offset == 0:
            saddr, daddr, sport, dport = self.__get_pkt_addr_info(mbuf)
            if dport == 0: return
            content = self.__get_transfer_content(mbuf)

            self.__frag_data[_id] = (saddr, daddr, sport, dport, [
                content,
            ])
            self.__timer.set_timeout(_id, self.__TIMEOUT)

            return
        elif _id not in self.__frag_data:
            return

        else:
            content = self.__get_transfer_content(mbuf, is_off=True)
            _, _, frag_pkts = self.__frag_data[_id]
            frag_pkts.append(content)

        if mf != 0: return

        saddr, daddr, sport, dport, frag_pkts = self.__frag_data[_id]

        self.__ok_packets.append(saddr, daddr, sport, dport,
                                 b"".join(frag_pkts))
        self.__timer.drop(_id)

        del self.__frag_data[_id]
Exemple #17
0
def modify_ip4address(ip_packet, mbuf, flags=0):
    """
    :param ip_packet:
    :param mbuf:
    :param flags: 0表示修改源地址,1表示修改目的地址
    :return:
    """

    mbuf.offset = 9
    protocol = mbuf.get_part(1)

    if flags == 0:
        mbuf.offset = 12
    else:
        mbuf.offset = 16
    old_ip_packet = mbuf.get_part(4)
    mbuf.offset = 10
    csum = utils.bytes2number(mbuf.get_part(2))
    csum = calc_checksum_for_ip_change(old_ip_packet, ip_packet, csum)
    mbuf.replace(utils.number2bytes(csum, 2))

    mbuf.offset = 6
    offset = utils.bytes2number(mbuf.get_part(2)) & 0x1fff
    # 修改第一个数据包
    if protocol in (
            6,
            17,
            132,
            136,
    ) and offset == 0:
        if protocol == 6:
            p = 1
        else:
            p = 0
        modify_tcpudp_for_change(ip_packet, mbuf, p, flags=flags)

    mbuf.offset = 10

    if flags == 0:
        mbuf.offset = 12
    else:
        mbuf.offset = 16

    mbuf.replace(ip_packet)
Exemple #18
0
    def __get_ipv4_dgram_pkt_addr_info(self):
        """获取数据包的地址信息
        :param mbuf:
        :return:
        """
        mbuf = self.__mbuf

        hdrlen = self.__get_ip4_hdrlen()

        mbuf.offset = hdrlen + 2
        dport = utils.bytes2number(mbuf.get_part(2))
        mbuf.offset = hdrlen
        sport = utils.bytes2number(mbuf.get_part(2))

        mbuf.offset = 16
        daddr = mbuf.get_part(4)
        mbuf.offset = 12
        saddr = mbuf.get_part(4)

        return (socket.inet_ntoa(saddr), socket.inet_ntoa(daddr), sport, dport,)
Exemple #19
0
    def __init__(self, subnet, prefix, is_ipv6=False):

        self.__no_use_iplist_num = []
        self.__subnet = subnet
        self.__prefix = prefix
        self.__is_ipv6 = is_ipv6

        if not is_ipv6:
            self.__fa = socket.AF_INET
            self.__cur_max_ipaddr_num = utils.bytes2number(
                socket.inet_pton(socket.AF_INET, subnet))
            self.__prefix_num = utils.calc_net_prefix_num(prefix)
        else:
            self.__fa = socket.AF_INET6
            self.__cur_max_ipaddr_num = utils.bytes2number(
                socket.inet_pton(socket.AF_INET6, subnet))
            self.__prefix_num = utils.calc_net_prefix_num(prefix, is_ipv6=True)

        self.__subnet_num = self.__cur_max_ipaddr_num
        return
Exemple #20
0
    def add_frag(self, mbuf):
        mbuf.offset = 8
        saddr = mbuf.get_part(16)
        mbuf.offset = 24
        daddr = mbuf.get_part(16)
        mbuf.offset = 42

        frag_off = utils.bytes2number(mbuf.get_part(2))
        m_flag = frag_off & 1
        frag_off = frag_off >> 3

        mbuf.offset = 44
        frag_id = mbuf.get_part(4)

        if frag_off == 0 and m_flag == 0:
            sport, dport = self.__get_pkt_port_info(mbuf)
            mbuf.offset = 56
            self.__ok_packets.append((
                saddr,
                daddr,
                sport,
                dport,
                mbuf.get_data(),
            ))
            return

        uniq_id = b"".join([
            saddr,
            frag_id,
        ])

        if frag_off == 0 and m_flag == 1:
            sport, dport = self.__get_pkt_port_info(mbuf)
            mbuf.offset = 56

            self.__fragdata[uniq_id] = (saddr, daddr, sport, dport,
                                        [mbuf.get_data()])
            self.__timer.set_timeout(uniq_id, self.__TIMEOUT)
            return

        if uniq_id not in self.__fragdata: return
        mbuf.offset = 48
        content = mbuf.get_data()

        saddr, daddr, sport, dport, data_list = self.__fragdata[uniq_id]
        data_list.append(content)

        if m_flag != 0: return

        self.__ok_packets.append(
            (saddr, daddr, sport, dport, b"".join(data_list)))

        self.__timer.drop(uniq_id)
        del self.__fragdata[uniq_id]
Exemple #21
0
    def __handle_ipv4_data_from_tunnel(self):
        self.__mbuf.offset = 12
        byte_src_addr = self.__mbuf.get_part(4)
        self.__mbuf.offset = 16
        byte_dst_addr = self.__mbuf.get_part(4)
        self.__mbuf.offset = 9
        protocol = self.__mbuf.get_part(1)

        hdrlen = self.__get_ip4_hdrlen()
        if hdrlen + 8 < 28: return False

        # 检查IP数据报长度是否合法
        self.__mbuf.offset = 2
        payload_length = utils.bytes2number(self.__mbuf.get_part(2))

        if payload_length != self.__mbuf.payload_size: return
        if protocol not in self.__support_protocols: return

        self.__mbuf.offset = hdrlen + 2
        byte_dst_port = self.__mbuf.get_part(2)
        dst_port = utils.bytes2number(byte_dst_port)

        rule = self.__port_mapv4.find_rule_for_in(byte_dst_addr, protocol,
                                                  dst_port)
        if not rule: return

        src_addr = socket.inet_ntop(socket.AF_INET, byte_src_addr)
        k = "%s/32" % src_addr
        if k not in self.__routes:
            self.set_route(src_addr, prefix=32, is_ipv6=False)

        _, rewrite_dest_ip, p, rewrite_dest_port = rule
        # 此处重写IP地址
        ippkts.modify_ip4address(rewrite_dest_ip, self.__mbuf, flags=1)
        ippkts.modify_port(rewrite_dest_port, self.__mbuf, flags=1)
        self.__mbuf.offset = 0
        byte_data = self.__mbuf.get_data()
        self.get_handler(self.__tundev_fileno).msg_from_tunnel(byte_data)
Exemple #22
0
    def __is_dns_request(self):
        mbuf = self.__mbuf
        ip_ver = mbuf.ip_version()

        if ip_ver == 4:
            mbuf.offset = 0
            n = mbuf.get_part(1)
            hdrlen = (n & 0x0f) * 4

            mbuf.offset = 9
            nexthdr = mbuf.get_part(1)

            mbuf.offset = 12
            saddr = mbuf.get_part(4)
            mbuf.offset = 16
            daddr = mbuf.get_part(4)
        else:
            mbuf.offset = 6
            nexthdr = mbuf.get_part(1)
            hdrlen = 40
            mbuf.offset = 8
            saddr = mbuf.get_part(16)
            mbuf.offset = 24
            daddr = mbuf.get_part(16)

        if (nexthdr != 17): return (False, None, None, None, None)

        mbuf.offset = hdrlen
        sport = utils.bytes2number(mbuf.get_part(2))

        mbuf.offset = hdrlen + 2
        dport = utils.bytes2number(mbuf.get_part(2))
        if dport != 53: return (False, None, None, None, None,)

        mbuf.offset = hdrlen + 8

        return (True, saddr, daddr, sport, mbuf.get_data(),)
Exemple #23
0
def modify_tcpudp_for_change(ip_packet, mbuf, proto, flags=0, is_ipv6=False):
    """ 修改传输层(SCTP,TCP,UDP,UDPLite,)内容
    :param ip_packet:
    :param ip_packet_list:
    :param proto: 0表示计算的UDP以及UDPLITE,1表示计算的TCP
    :param flags: 0 表示修改时的源地址,1表示修改的是目的地址
    :param is_ipv6:表示是否是否是IPV6
    :return:
    """
    if proto not in [0, 1]: return

    if is_ipv6:
        hdr_len = 40
    else:
        mbuf.offset = 0
        hdr_len = (mbuf.get_part(1) & 0x0f) * 4

    if flags:
        if is_ipv6:
            mbuf.offset = 24
        else:
            mbuf.offset = 16
        ''''''
    else:
        if is_ipv6:
            mbuf.offset = 8
        else:
            mbuf.offset = 12
        ''''''
    if is_ipv6:
        old_ip_packet = mbuf.get_part(16)
    else:
        old_ip_packet = mbuf.get_part(4)

    if proto == 0:
        n = hdr_len + 6
    else:
        n = hdr_len + 16

    mbuf.offset = n
    csum = utils.bytes2number(mbuf.get_part(2))
    # 如果旧的校检和为0,说明不需要进行校检和计算
    if csum == 0: return

    csum = calc_checksum_for_ip_change(old_ip_packet,
                                       ip_packet,
                                       csum,
                                       is_ipv6=is_ipv6)
    mbuf.replace(utils.number2bytes(csum, 2))
Exemple #24
0
def modify_tcpudp_for_change(ip_packet, mbuf, proto, flags=0, is_ipv6=False):
    """ 修改传输层(SCTP,TCP,UDP,UDPLite,)内容
    :param ip_packet:
    :param ip_packet_list:
    :param proto: 0表示计算的UDP,SCTP以及UDPLITE,1表示计算的TCP
    :param flags: 0 表示修改时的源地址,1表示修改的是目的地址
    :param is_ipv6:表示是否是否是IPV6
    :return:
    """
    if proto not in [0, 1]: return

    if is_ipv6:
        hdr_len = 40
    else:
        mbuf.offset = 0
        hdr_len = (mbuf.get_part(1) & 0x0f) * 4

    if flags:
        if is_ipv6:
            mbuf.offset = 24
        else:
            mbuf.offset = 16
        ''''''
    else:
        if is_ipv6:
            mbuf.offset = 8
        else:
            mbuf.offset = 12
        ''''''
    if is_ipv6:
        old_ip_packet = mbuf.get_part(16)
    else:
        old_ip_packet = mbuf.get_part(4)

    if proto == 0:
        n = hdr_len + 6
    else:
        n = hdr_len + 16

    mbuf.offset = n
    csum = utils.bytes2number(mbuf.get_part(2))
    # 如果旧的校检和为0,说明不需要进行校检和计算
    if csum == 0: return

    csum = calc_checksum_for_ip_change(old_ip_packet, ip_packet, csum, is_ipv6=is_ipv6)
    mbuf.replace(utils.number2bytes(csum, 2))
Exemple #25
0
    def add_frag(self, mbuf):
        mbuf.offset = 8
        saddr = mbuf.get_part(16)
        mbuf.offset = 24
        daddr = mbuf.get_part(16)
        mbuf.offset = 42

        frag_off = utils.bytes2number(mbuf.get_part(2))
        m_flag = frag_off & 1
        frag_off = frag_off >> 3

        mbuf.offset = 44
        frag_id = mbuf.get_part(4)

        if frag_off == 0 and m_flag == 0:
            sport, dport = self.__get_pkt_port_info(mbuf)
            mbuf.offset = 56
            self.__ok_packets.append((saddr, daddr, sport, dport, mbuf.get_data(),))
            return

        uniq_id = b"".join([saddr, frag_id, ])

        if frag_off == 0 and m_flag == 1:
            sport, dport = self.__get_pkt_port_info(mbuf)
            mbuf.offset = 56

            self.__fragdata[uniq_id] = (saddr, daddr, sport, dport, [mbuf.get_data()])
            self.__timer.set_timeout(uniq_id, self.__TIMEOUT)
            return

        if uniq_id not in self.__fragdata: return
        mbuf.offset = 48
        content = mbuf.get_data()

        saddr, daddr, sport, dport, data_list = self.__fragdata[uniq_id]
        data_list.append(content)

        if m_flag != 0: return

        self.__ok_packets.append(
            (saddr, daddr, sport, dport, b"".join(data_list))
        )

        self.__timer.drop(uniq_id)
        del self.__fragdata[uniq_id]
Exemple #26
0
    def __handle_msg_from_tun_for_ipv4(self, data_size):
        self.__mbuf.offset = 9
        protocol = self.__mbuf.get_part(1)
        self.__mbuf.offset = 16
        byte_daddr = self.__mbuf.get_part(4)
        if protocol not in self.__support_protocols: return

        hdrlen = self.__get_ip4_hdrlen()
        self.__mbuf.offset = hdrlen
        byte_dport = self.__mbuf.get_part(2)
        dst_port = utils.bytes2number(byte_dport)

        rs = self.__access.get_map_rule(byte_daddr, protocol, dst_port)
        if not rs: return
        _id, key = rs
        if not self.__access.handle_packet_for_send(key, data_size): return

        self.__mbuf.offset = 0
        self.__send_msg_to_tunnel(_id, key, self.__mbuf.get_data())
Exemple #27
0
def modify_icmp6_echo_for_change(byte_ip, mbuf, flags=0):
    """修改ICMPv6报文
    :param byte_ip:
    :param new_icmpid:
    :param flags:0表示修改请求报文,1表示表示修改响应报文
    :return:
    """
    mbuf.offset = 42
    csum = utils.bytes2number(mbuf.get_part(2))

    if flags == 0:
        mbuf.offset = 8
    else:
        mbuf.offset = 24

    old_byte_ip = mbuf.get_part(16)

    csum = calc_checksum_for_ip_change(old_byte_ip, byte_ip, csum, is_ipv6=True)

    mbuf.offset = 42
    mbuf.replace(utils.number2bytes(csum, 2))
Exemple #28
0
    def __handle_msg_from_tun_for_ipv6(self, data_size):
        self.__mbuf.offset = 6
        nexthdr = self.__mbuf.get_part(1)
        self.__mbuf.offset = 24
        byte_daddr = self.__mbuf.get_part(16)

        if nexthdr not in self.__support_protocols: return

        self.__mbuf.offset = 40

        byte_dport = self.__mbuf.get_part(2)
        dst_port = utils.bytes2number(byte_dport)

        rs = self.__access.get_map_rule(byte_daddr, nexthdr, dst_port)
        if not rs: return
        _id, key = rs

        if not self.__access.handle_packet_for_send(key, data_size): return

        self.__mbuf.offset = 0
        self.__send_msg_to_tunnel(_id, key, self.__mbuf.get_data())
Exemple #29
0
    def __handle_ipv6_msg_from_tunnel(self, session_id, data_size):
        self.__mbuf.offset = 6
        nexthdr = self.__mbuf.get_part(1)
        self.__mbuf.offset = 8
        byte_saddr = self.__mbuf.get_part(16)

        if nexthdr not in self.__support_protocols: return

        self.__mbuf.offset = 40

        byte_sport = self.__mbuf.get_part(2)
        src_port = utils.bytes2number(byte_sport)

        rs = self.__access.get_map_rule(byte_saddr, nexthdr, src_port)
        if not rs: return
        _id, key = rs
        if _id != session_id: return
        if not self.__access.handle_packet_from_recv(key, data_size): return

        self.__mbuf.offset = 0
        self.get_handler(self.__tundev_fileno).handle_msg_from_tunnel(
            self.__mbuf.get_data())
Exemple #30
0
    def __handle_ipv4_msg_from_tunnel(self, session_id, data_size):
        self.__mbuf.offset = 9
        protocol = self.__mbuf.get_part(1)
        self.__mbuf.offset = 12
        byte_saddr = self.__mbuf.get_part(4)
        if protocol not in self.__support_protocols: return

        hdrlen = self.__get_ip4_hdrlen()
        self.__mbuf.offset = hdrlen
        byte_sport = self.__mbuf.get_part(2)
        src_port = utils.bytes2number(byte_sport)

        rs = self.__access.get_map_rule(byte_saddr, protocol, src_port)
        if not rs: return
        _id, key = rs
        # 会话ID不一致就丢弃数据包
        if session_id != _id: return

        if not self.__access.handle_packet_from_recv(key, data_size): return

        self.__mbuf.offset = 0
        self.get_handler(self.__tundev_fileno).handle_msg_from_tunnel(
            self.__mbuf.get_data())
Exemple #31
0
def modify_ip4address(ip_packet, mbuf, flags=0):
    """
    :param ip_packet:
    :param mbuf:
    :param flags: 0表示修改源地址和端口,1表示修改目的地址和端口
    :return:
    """

    mbuf.offset = 9
    protocol = mbuf.get_part(1)

    if flags == 0:
        mbuf.offset = 12
    else:
        mbuf.offset = 16
    old_ip_packet = mbuf.get_part(4)
    mbuf.offset = 10
    csum = utils.bytes2number(mbuf.get_part(2))
    csum = calc_checksum_for_ip_change(old_ip_packet, ip_packet, csum)
    mbuf.replace(utils.number2bytes(csum, 2))

    if protocol in (6, 17, 132, 136,):
        if protocol == 6:
            p = 1
        else:
            p = 0
        modify_tcpudp_for_change(ip_packet, mbuf, p, flags=flags)

    mbuf.offset = 10

    if flags == 0:
        mbuf.offset = 12
    else:
        mbuf.offset = 16

    mbuf.replace(ip_packet)
Exemple #32
0
def modify_icmp6_echo_for_change(byte_ip, mbuf, flags=0):
    """修改ICMPv6报文
    :param byte_ip:
    :param new_icmpid:
    :param flags:0表示修改请求报文,1表示表示修改响应报文
    :return:
    """
    mbuf.offset = 42
    csum = utils.bytes2number(mbuf.get_part(2))

    if flags == 0:
        mbuf.offset = 8
    else:
        mbuf.offset = 24

    old_byte_ip = mbuf.get_part(16)

    csum = calc_checksum_for_ip_change(old_byte_ip,
                                       byte_ip,
                                       csum,
                                       is_ipv6=True)

    mbuf.offset = 42
    mbuf.replace(utils.number2bytes(csum, 2))
Exemple #33
0
    def __handle_ipv4_dgram_from_tunnel(self, session_id, is_udplite=False):
        mbuf = self.__mbuf
        mbuf.offset = 4

        mbuf.offset = 6
        frag_off = utils.bytes2number(mbuf.get_part(2))

        df = (frag_off & 0x4000) >> 14
        mf = (frag_off & 0x2000) >> 13
        offset = frag_off & 0x1fff

        if offset == 0:
            sts_saddr, sts_daddr, sport, dport = self.__get_ipv4_dgram_pkt_addr_info()
            if dport == 0: return False

        # 把源地址和checksum设置为0
        mbuf.offset = 12
        mbuf.replace(b"\0\0\0\0")

        mbuf.offset = 10
        mbuf.replace(b"\0\0")
        ##

        if offset != 0:
            mbuf.offset = 0
            self.send_message_to_handler(-1, self.__raw_fileno, mbuf.get_data())
            return

        _id = "%s-%s" % (sts_saddr, sport,)

        fileno = -1
        if session_id in self.__dgram_proxy:
            pydict = self.__dgram_proxy[session_id]
            if _id in pydict: fileno = pydict[_id]

        if fileno < 0:
            fileno = self.create_handler(-1, traffic_pass.p2p_proxy, session_id, (sts_saddr, sport,),
                                         mtu=self.__ip4_mtu, is_udplite=is_udplite, is_ipv6=False)
            if fileno < 0: return

        self.get_handler(fileno).add_permit((sts_daddr, dport,))
        _, new_sport = self.get_handler(fileno).getsockname()

        hdrlen = self.__get_ip4_hdrlen()
        # 替换源端口
        mbuf.offset = hdrlen
        mbuf.replace(utils.number2bytes(new_sport, 2))

        mbuf.offset = hdrlen + 6

        if not is_udplite:
            mbuf.replace(b"\0\0")
        else:
            csum = utils.bytes2number(mbuf.get_part(2))
            csum = fn_utils.calc_incre_csum(csum, sport, new_sport)
            mbuf.replace(utils.number2bytes(csum, 2))

        if session_id not in self.__dgram_proxy:
            self.__dgram_proxy[session_id] = {}

        pydict = self.__dgram_proxy[session_id]
        pydict[_id] = fileno

        mbuf.offset = 0
        self.send_message_to_handler(-1, self.__raw_fileno, mbuf.get_data())
Exemple #34
0
    def __handle_ipv4_dgram_from_tunnel(self, session_id, is_udplite=False):
        mbuf = self.__mbuf
        mbuf.offset = 4

        mbuf.offset = 6
        frag_off = utils.bytes2number(mbuf.get_part(2))

        df = (frag_off & 0x4000) >> 14
        mf = (frag_off & 0x2000) >> 13
        offset = frag_off & 0x1fff

        if offset == 0:
            sts_saddr, sts_daddr, sport, dport = self.__get_ipv4_dgram_pkt_addr_info(
            )
            if dport == 0: return False

        # 把源地址和checksum设置为0
        mbuf.offset = 12
        mbuf.replace(b"\0\0\0\0")

        mbuf.offset = 10
        mbuf.replace(b"\0\0")
        ##

        if offset != 0:
            mbuf.offset = 0
            self.send_message_to_handler(-1, self.__raw_fileno,
                                         mbuf.get_data())
            return

        _id = "%s-%s" % (
            sts_saddr,
            sport,
        )

        fileno = -1
        if session_id in self.__dgram_proxy:
            pydict = self.__dgram_proxy[session_id]
            if _id in pydict: fileno = pydict[_id]

        if fileno < 0:
            fileno = self.create_handler(-1,
                                         traffic_pass.p2p_proxy,
                                         session_id, (
                                             sts_saddr,
                                             sport,
                                         ),
                                         mtu=self.__ip4_mtu,
                                         is_udplite=is_udplite,
                                         is_ipv6=False)
            if fileno < 0: return

        self.get_handler(fileno).add_permit((
            sts_daddr,
            dport,
        ))
        _, new_sport = self.get_handler(fileno).getsockname()

        hdrlen = self.__get_ip4_hdrlen()
        # 替换源端口
        mbuf.offset = hdrlen
        mbuf.replace(utils.number2bytes(new_sport, 2))

        mbuf.offset = hdrlen + 6

        if not is_udplite:
            mbuf.replace(b"\0\0")
        else:
            csum = utils.bytes2number(mbuf.get_part(2))
            csum = fn_utils.calc_incre_csum(csum, sport, new_sport)
            mbuf.replace(utils.number2bytes(csum, 2))

        if session_id not in self.__dgram_proxy:
            self.__dgram_proxy[session_id] = {}

        pydict = self.__dgram_proxy[session_id]
        pydict[_id] = fileno

        mbuf.offset = 0
        self.send_message_to_handler(-1, self.__raw_fileno, mbuf.get_data())