def __build_ipv6_fragment_hdr(nexthdr, frag_off, m_flag, frag_id): frag_off = (frag_off << 3) | m_flag byte_seq = [ utils.number2bytes(nexthdr, 1), b"\0", utils.number2bytes(frag_off, 2), utils.number2bytes(frag_id, 4), ] return b"".join(byte_seq)
def __calc_udp_csum(saddr, daddr, udp_data, is_ipv6=False): size = len(udp_data) seq = [ saddr, daddr, b'\x00\x11', utils.number2bytes(size, 2), udp_data, ] if is_ipv6: size += 24 else: size += 12 if 0 != size % 2: seq.append(b"\0") size += 1 data = b"".join(seq) csum = socket.htons(fn_utils.calc_csum(data, size)) # csum = __calc_checksum(data, size) # import socket # print(csum,socket.htons(csum_t)) if csum == 0: return 0xffff return csum
def __build_ipv6_hdr(flow_label, payload_length, nexthdr, hop_limit, saddr, daddr): """构建IPV6通用头 :param flow_label: :param payload_length: :param nexthdr: :param hop_limit: :param saddr: :param daddr: :return: """ # flow_label = random.randint(1, 0x0fffff) byte_seq = [ utils.number2bytes(6 << 4, 1), utils.number2bytes(flow_label & 0x0fffff, 3), utils.number2bytes(payload_length, 2), utils.number2bytes(nexthdr, 1), utils.number2bytes(hop_limit, 1), saddr, daddr ] return b"".join(byte_seq)
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))
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)
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))
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)
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())
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())