def get_live_sessions(ip_address, curr_timestamp, ip_dict, ip_to_ip_dict, ip_port_dict): """ Get all live TCP sessions for an IP address :param ip_address: IP as int :return: list(tuples) """ # Iterate over all IPs res = [] for other_ip in ip_dict[ip_address]: # Iterate over all sessions between the IPs for (source_port, destination_port, protocol) in ip_to_ip_dict[Util.ip_to_ip_make_key( ip_address, other_ip)]: # Generate dictionary key key = Util.ip_port_make_key(ip_address, other_ip, source_port, destination_port) # Check if session was a TCP session and if it was established if protocol == IPPROTO_TCP and key in ip_port_dict: # Retrieve session data prev_timestamp, is_active = ip_port_dict[key] # Check if session wasn't terminated or timed out if is_active and curr_timestamp - prev_timestamp < TCP_SESSION_TIMEOUT: res += [(ip_address, other_ip, source_port, destination_port)] return res
def get_live_sessions(ip_address, curr_timestamp, ip_dict, ip_to_ip_dict, ip_port_dict): """ Get all live TCP sessions for an IP address :param ip_address: IP as int :return: list(tuples) """ # Iterate over all IPs res = [] for other_ip in ip_dict[ip_address]: # Iterate over all sessions between the IPs for (source_port, destination_port, protocol) in ip_to_ip_dict[Util.ip_to_ip_make_key(ip_address, other_ip)]: # Generate dictionary key key = Util.ip_port_make_key(ip_address, other_ip, source_port, destination_port) # Check if session was a TCP session and if it was established if protocol == IPPROTO_TCP and key in ip_port_dict: # Retrieve session data prev_timestamp, is_active = ip_port_dict[key] # Check if session wasn't terminated or timed out if is_active and curr_timestamp - prev_timestamp < TCP_SESSION_TIMEOUT: res += [(ip_address, other_ip, source_port, destination_port)] return res
def update_tcp_session(source_ip, destination_ip, source_port, destination_port, ip_port_dict, timestamp, tcp_flags): # Create dictionary keys key = Util.ip_port_make_key(source_ip, destination_ip, source_port, destination_port) # Parse TCP flags ack = tcp_flags & 0b00001000 syn = tcp_flags & 0b01000000 rst = tcp_flags & 0b00100000 fin = tcp_flags & 0b10000000 if fin or rst: # Connection was terminated ip_port_dict[key] = (timestamp, False) elif key in ip_port_dict: # Session recorded in memory # Get the last state of this session prev_timestamp, is_active = ip_port_dict[key] if not is_active: # Session was active and was terminated. # Check if session was established again with same IPs and ports after termination. Note that if we missed # Syn/Ack response (on "revive") from the server, the session will be counted as inactive. if syn and ack and timestamp > prev_timestamp: # Session "revived" ip_port_dict[key] = (timestamp, True) # Update last timestamp, connection still active else: timestamp = max(prev_timestamp, timestamp) ip_port_dict[key] = (timestamp, True) else: # Session not in memory. Check if session was established if ack or not syn: # Connection established (SYN & ACK) or already exists (not SYN) ip_port_dict[key] = (timestamp, True)
def load_packet(packet_length, data, timestamp, ip_dict, port_dict, ip_to_ip_dict, ip_port_dict): e_len = 14 # Length of ethernet header # Parse addresses from IP header source_ip = Util.ip_bytes_to_int(data[e_len + 12: e_len + 16]) destination_ip = Util.ip_bytes_to_int(data[e_len + 16: e_len + 20]) # Insert IPs to IP dict ip_dict[source_ip].add(destination_ip) ip_dict[destination_ip].add(source_ip) # Create dictionary keys ip_key1 = Util.ip_to_ip_make_key(source_ip, destination_ip) ip_key2 = Util.ip_to_ip_make_key(destination_ip, source_ip) # Parse other info header_len = ord(data[e_len]) & 0x0f tcp_offset = 4 * header_len + e_len source_port = Util.port_bytes_to_int(data[tcp_offset: tcp_offset + 2]) destination_port = Util.port_bytes_to_int(data[tcp_offset + 2: tcp_offset + 4]) protocol = ord(data[e_len + 9]) # insert ports into port_dict port_dict[source_ip].add((source_port, protocol)) port_dict[destination_ip].add((destination_port, protocol)) # Insert ports used into ip_to_ip_dict ip_to_ip_dict[ip_key1].add((source_port, destination_port, protocol)) ip_to_ip_dict[ip_key2].add((destination_port, source_port, protocol)) # Check if tcp if protocol == IPPROTO_TCP: tcp_flags = ord(data[tcp_offset + 13]) update_tcp_session(source_ip, destination_ip, source_port, destination_port, ip_port_dict, timestamp, tcp_flags)
def communicated_with_ip_on_port(source_ip, destination_ip, port, ip_to_ip_dict): """ :param source_ip: First IP as int :param destination_ip: Second IP as int :param port: (Port, protocol) both as int :return: Boolean """ # Get all ports used for communication between 2 IPs # TODO: Optimize with new dict that maps 2 IPs -> set(port)? ports = ip_to_ip_dict[Util.ip_to_ip_make_key(source_ip, destination_ip)] port_num, curr_protocol = port return any(port_num == source_port and curr_protocol == protocol for source_port, destination_port, protocol in ports)
def load_packet(packet_length, data, timestamp, ip_dict, port_dict, ip_to_ip_dict, ip_port_dict): e_len = 14 # Length of ethernet header # Parse addresses from IP header source_ip = Util.ip_bytes_to_int(data[e_len + 12:e_len + 16]) destination_ip = Util.ip_bytes_to_int(data[e_len + 16:e_len + 20]) # Insert IPs to IP dict ip_dict[source_ip].add(destination_ip) ip_dict[destination_ip].add(source_ip) # Create dictionary keys ip_key1 = Util.ip_to_ip_make_key(source_ip, destination_ip) ip_key2 = Util.ip_to_ip_make_key(destination_ip, source_ip) # Parse other info header_len = ord(data[e_len]) & 0x0f tcp_offset = 4 * header_len + e_len source_port = Util.port_bytes_to_int(data[tcp_offset:tcp_offset + 2]) destination_port = Util.port_bytes_to_int(data[tcp_offset + 2:tcp_offset + 4]) protocol = ord(data[e_len + 9]) # insert ports into port_dict port_dict[source_ip].add((source_port, protocol)) port_dict[destination_ip].add((destination_port, protocol)) # Insert ports used into ip_to_ip_dict ip_to_ip_dict[ip_key1].add((source_port, destination_port, protocol)) ip_to_ip_dict[ip_key2].add((destination_port, source_port, protocol)) # Check if tcp if protocol == IPPROTO_TCP: tcp_flags = ord(data[tcp_offset + 13]) update_tcp_session(source_ip, destination_ip, source_port, destination_port, ip_port_dict, timestamp, tcp_flags)
def list_live(ip, ip_dict, ip_to_ip_dict, ip_port_dict): for session in PcapUtils.get_live_sessions(ip, time.time(), ip_dict, ip_to_ip_dict, ip_port_dict): print(Util.tcp_session_tuple_to_str(session))