Пример #1
0
def build_ip_packet(pkt_len, protocol, saddr, daddr, message, pkt_id=1, flags_df=0, flags_mf=0, offset=0):
    """创建IP数据包
    :param pkt_len:包长度
    :param saddr: bytes类型的源地址
    :param daddr: bytes类型的目的地址
    :param message:消息内容
    :param pkt_id: 包ID
    :param flags_df: 分段df位
    :param flags_mf:分段mf位
    :param offset:包偏移
    :return ip_pkt:
    """
    if pkt_len < __IP_HDR_SIZE: raise ValueError("the value of pkt_len must be less than 20")
    if protocol < 0 or protocol > 255: raise ValueError("the value of protocol is wrong")

    tpl = b'E\x00\x00\x14\x00\x01\x00\x00@\x00z\xea\x00\x00\x00\x00\x00\x00\x00\x00'

    L = list(tpl)

    # 修改地址
    csum = (L[10] << 8) | L[11]
    csum = checksum.calc_checksum_for_ip_change(tpl[12:16], saddr, csum)
    csum = checksum.calc_checksum_for_ip_change(tpl[16:20], daddr, csum)
    L[12:16] = saddr
    L[16:20] = daddr

    # 修改包长度
    old_v = (L[2] << 8) | L[3]
    new_v = pkt_len
    csum = fn_utils.calc_incre_csum(csum, old_v, new_v)
    L[2:4] = ((pkt_len & 0xff00) >> 8, pkt_len & 0x00ff,)

    # 修改包ID
    old_v = (L[4] << 8) | L[5]
    new_v = pkt_id
    csum = fn_utils.calc_incre_csum(csum, old_v, new_v)
    L[4:6] = ((pkt_id & 0xff00) >> 8, pkt_id & 0x00ff,)

    # 修改flags以及offset
    old_v = (L[6] << 8) | L[7]
    new_v = (flags_df << 14) | (flags_mf << 13) | offset
    csum = fn_utils.calc_incre_csum(csum, old_v, new_v)
    L[6:8] = ((new_v & 0xff00) >> 8, new_v & 0x00ff,)

    # 修改协议
    old_v = L[9]
    new_v = protocol
    csum = fn_utils.calc_incre_csum(csum, old_v, new_v)
    L[9] = protocol

    # 修改校检和
    # L[10:12] = (0, 0,)
    # csum = fn_utils.calc_csum(bytes(L), 20)
    L[10:12] = ((csum & 0xff00) >> 8, csum & 0x00ff,)

    return b"".join((bytes(L), message,))
Пример #2
0
def calc_checksum_for_ip_change(old_ip_packet,
                                new_ip_packet,
                                old_checksum,
                                is_ipv6=False):
    """ ip地址改变之后重新获取校检码
    :param old_ip_packet:
    :param new_ip_packet:
    :param old_checksum:
    :param is_ipv6:是否是ipv6
    :return:
    """
    final_checksum = old_checksum
    a = 0
    b = 1
    # tmpcsum = old_checksum

    if is_ipv6:
        n = 8
    else:
        n = 2

    i = 0
    while i < n:
        old_field = (old_ip_packet[a] << 8) | old_ip_packet[b]
        new_field = (new_ip_packet[a] << 8) | new_ip_packet[b]
        # final_checksum = checksum.calc_incre_checksum(final_checksum, old_field, new_field)
        final_checksum = fn_utils.calc_incre_csum(final_checksum, old_field,
                                                  new_field)
        a = a + 2
        b = b + 2
        i += 1

    return final_checksum
Пример #3
0
def calc_checksum_for_ip_change(old_ip_packet, new_ip_packet, old_checksum, is_ipv6=False):
    """ ip地址改变之后重新获取校检码
    :param old_ip_packet:
    :param new_ip_packet:
    :param old_checksum:
    :param is_ipv6:是否是ipv6
    :return:
    """
    final_checksum = old_checksum
    a = 0
    b = 1
    # tmpcsum = old_checksum

    if is_ipv6:
        n = 8
    else:
        n = 2

    i = 0
    while i < n:
        old_field = (old_ip_packet[a] << 8) | old_ip_packet[b]
        new_field = (new_ip_packet[a] << 8) | new_ip_packet[b]
        # final_checksum = checksum.calc_incre_checksum(final_checksum, old_field, new_field)
        final_checksum = fn_utils.calc_incre_csum(final_checksum, old_field, new_field)
        a = a + 2
        b = b + 2
        i += 1

    return final_checksum
Пример #4
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))
Пример #5
0
def calc_checksum_for_ip_change(old_ip_packet, new_ip_packet, old_checksum):
    """ ip地址改变之后重新获取校检码
    :param old_ip_packet:
    :param new_ip_packet:
    :param old_checksum:
    :return:
    """
    final_checksum = old_checksum
    a = 0
    b = 1
    # tmpcsum = old_checksum

    for i in range(2):
        old_field = (old_ip_packet[a] << 8) | old_ip_packet[b]
        new_field = (new_ip_packet[a] << 8) | new_ip_packet[b]
        # final_checksum = checksum.calc_incre_checksum(final_checksum, old_field, new_field)
        final_checksum = fn_utils.calc_incre_csum(final_checksum, old_field, new_field)
        a = a + 2
        b = b + 2

    return final_checksum
Пример #6
0
def calc_checksum_for_ip_change(old_ip_packet, new_ip_packet, old_checksum):
    """ ip地址改变之后重新获取校检码
    :param old_ip_packet:
    :param new_ip_packet:
    :param old_checksum:
    :return:
    """
    final_checksum = old_checksum
    a = 0
    b = 1
    # tmpcsum = old_checksum

    for i in range(2):
        old_field = (old_ip_packet[a] << 8) | old_ip_packet[b]
        new_field = (new_ip_packet[a] << 8) | new_ip_packet[b]
        # final_checksum = checksum.calc_incre_checksum(final_checksum, old_field, new_field)
        final_checksum = fn_utils.calc_incre_csum(final_checksum, old_field,
                                                  new_field)
        a = a + 2
        b = b + 2

    return final_checksum
Пример #7
0
def build_ip_packet(pkt_len,
                    protocol,
                    saddr,
                    daddr,
                    message,
                    pkt_id=1,
                    flags_df=0,
                    flags_mf=0,
                    offset=0):
    """创建IP数据包
    :param pkt_len:包长度
    :param saddr: bytes类型的源地址
    :param daddr: bytes类型的目的地址
    :param message:消息内容
    :param pkt_id: 包ID
    :param flags_df: 分段df位
    :param flags_mf:分段mf位
    :param offset:包偏移
    :return ip_pkt:
    """
    if pkt_len < __IP_HDR_SIZE:
        raise ValueError("the value of pkt_len must be less than 20")
    if protocol < 0 or protocol > 255:
        raise ValueError("the value of protocol is wrong")

    tpl = b'E\x00\x00\x14\x00\x01\x00\x00@\x00z\xea\x00\x00\x00\x00\x00\x00\x00\x00'

    L = list(tpl)

    # 修改地址
    csum = (L[10] << 8) | L[11]
    csum = checksum.calc_checksum_for_ip_change(tpl[12:16], saddr, csum)
    csum = checksum.calc_checksum_for_ip_change(tpl[16:20], daddr, csum)
    L[12:16] = saddr
    L[16:20] = daddr

    # 修改包长度
    old_v = (L[2] << 8) | L[3]
    new_v = pkt_len
    csum = fn_utils.calc_incre_csum(csum, old_v, new_v)
    L[2:4] = (
        (pkt_len & 0xff00) >> 8,
        pkt_len & 0x00ff,
    )

    # 修改包ID
    old_v = (L[4] << 8) | L[5]
    new_v = pkt_id
    csum = fn_utils.calc_incre_csum(csum, old_v, new_v)
    L[4:6] = (
        (pkt_id & 0xff00) >> 8,
        pkt_id & 0x00ff,
    )

    # 修改flags以及offset
    old_v = (L[6] << 8) | L[7]
    new_v = (flags_df << 14) | (flags_mf << 13) | offset
    csum = fn_utils.calc_incre_csum(csum, old_v, new_v)
    L[6:8] = (
        (new_v & 0xff00) >> 8,
        new_v & 0x00ff,
    )

    # 修改协议
    old_v = L[9]
    new_v = protocol
    csum = fn_utils.calc_incre_csum(csum, old_v, new_v)
    L[9] = protocol

    # 修改校检和
    # L[10:12] = (0, 0,)
    # csum = fn_utils.calc_csum(bytes(L), 20)
    L[10:12] = (
        (csum & 0xff00) >> 8,
        csum & 0x00ff,
    )

    return b"".join((
        bytes(L),
        message,
    ))
Пример #8
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())
Пример #9
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())