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)
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)
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)
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), )
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)
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)
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)
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)