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,)
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, )
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)
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, )
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))
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, )
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(), )
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
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
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
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
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)
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)
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)
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
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]
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 __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,)
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
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]
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)
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(),)
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))
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 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]
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())
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 __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())
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())
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())
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 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 __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())