Beispiel #1
0
static inline void ProcessTCPFlow(FlowSource_t	*fs, struct FlowNode *NewNode ) {
struct FlowNode *Node;

	assert(NewNode->memflag == NODE_IN_USE);
	Node = Insert_Node(NewNode);
	// Return existing Node if flow exists already, otherwise insert es new
	if ( Node == NULL ) {
		// Insert as new
		dbg_printf("New TCP flow: Packets: %u, Bytes: %u\n", NewNode->packets, NewNode->bytes);

		// in case it's a FIN/RST only packet - immediately flush it
		if ( NewNode->fin == FIN_NODE  ) {
			// flush node
			if ( StorePcapFlow(fs, NewNode) ) {
				Remove_Node(NewNode);
			} 
		}

		if ( !CacheCheck() ) {
			uint32_t NumFlows;
			LogError("Node cache exhausted! - Immediate flush - increase flow cache!!");	
			NumFlows  = Flush_FlowTree(fs);
			LogError("Flushed flows: %u", NumFlows);	
		}

		if ( Link_RevNode(NewNode)) {
			// if we could link this new node, it is the server answer
			// -> calculate server latency
			SetServer_latency(NewNode);
		}
		return;
	}

	assert(Node->memflag == NODE_IN_USE);

	// check for first client ACK for client latency
	if ( Node->latency.flag == 1 ) {
		SetClient_latency(Node, &(NewNode->t_first));
	} else if ( Node->latency.flag == 2 ) {
		SetApplication_latency(Node, &(NewNode->t_first));
	}
	// update existing flow
	Node->flags |= NewNode->flags;
	Node->packets++;
	Node->bytes += NewNode->bytes; 
	Node->t_last = NewNode->t_last; 
	dbg_printf("Existing TCP flow: Packets: %u, Bytes: %u\n", Node->packets, Node->bytes);

	if ( NewNode->fin == FIN_NODE) {
		// flush node
		Node->fin = FIN_NODE;
		if ( StorePcapFlow(fs, Node) ) {
			Remove_Node(Node);
		} 
	} else {
		Free_Node(NewNode);
	}
 

} // End of ProcessTCPFlow
Beispiel #2
0
static inline void ProcessTCPFlow (FlowSource_t *fs, struct FlowNode *NewNode)
{
	struct FlowNode *Node;

	assert (NewNode->memflag == NODE_IN_USE);
	Node = Insert_Node (NewNode);
	// if insert fails, the existing node is returned -> flow exists already
	if (Node == NULL) {
		dbg_printf ("New TCP flow: Packets: %u, Bytes: %u\n", NewNode->packets, NewNode->bytes);

		// in case it's a FIN/RST only packet - immediately flush it
		if (NewNode->fin == FIN_NODE) {
			// flush node
			if (StorePcapFlow (fs, NewNode)) {
				Remove_Node (NewNode);
			}
		}

		if (!CacheCheck()) {
			uint32_t NumFlows;
			LogError ("Node cache exhausted! - Immediate flush - increase flow cache!!");
			NumFlows = Flush_FlowTree (fs);
			LogError ("Flushed flows: %u", NumFlows);
		}
		return;
	}

	assert (Node->memflag == NODE_IN_USE);

	// update existing flow
	Node->flags |= NewNode->flags;
	Node->packets++;
	Node->bytes += NewNode->bytes;
	Node->t_last = NewNode->t_last;
	dbg_printf ("Existing TCP flow: Packets: %u, Bytes: %u\n", Node->packets, Node->bytes);

	if (NewNode->fin == FIN_NODE) {
		// flush node
		Node->fin = FIN_NODE;
		if (StorePcapFlow (fs, Node)) {
			Remove_Node (Node);
		}
	} else {
		Free_Node (NewNode);
	}


} // End of ProcessTCPFlow
Beispiel #3
0
static inline void ProcessUDPFlow(FlowSource_t	*fs, struct FlowNode *NewNode ) {
struct FlowNode *Node;

	assert(NewNode->memflag == NODE_IN_USE);
	// Flush DNS queries directly 
	if ( NewNode->src_port == 53 || NewNode->dst_port == 53 ) {
		StorePcapFlow(fs, NewNode);
		Free_Node(NewNode);
		return;
	}

	// insert other UDP traffic
	Node = Insert_Node(NewNode);
	// if insert fails, the existing node is returned -> flow exists already
	if ( Node == NULL ) {
		dbg_printf("New UDP flow: Packets: %u, Bytes: %u\n", NewNode->packets, NewNode->bytes);
		return;
	} 
	assert(Node->memflag == NODE_IN_USE);

	// update existing flow
	Node->packets++;
	Node->bytes += NewNode->bytes; 
	Node->t_last = NewNode->t_last; 

	dbg_printf("Existing UDP flow: Packets: %u, Bytes: %u\n", Node->packets, Node->bytes);

	Free_Node(NewNode);

} // End of ProcessUDPFlow
Beispiel #4
0
uint32_t Flush_FlowTree(FlowSource_t *fs) {
struct FlowNode *node, *nxt;
uint32_t n = NumFlows;

	// Dump all incomplete flows to the file
	for (node = RB_MIN(FlowTree, FlowTree); node != NULL; node = nxt) {
		StorePcapFlow(fs, node);
		nxt = RB_NEXT(FlowTree, FlowTree, node);
#ifdef DEVEL
if ( node->left || node->right ) {
	assert(node->proto == 17);
	 node->left = node->right = NULL;
}
#endif
		Remove_Node(node);
	}

#ifdef DEVEL
	if ( NumFlows != 0 )
		LogError("### Flush_FlowTree() remaining flows: %u\n", NumFlows);
#endif

	UDP_list.list	= NULL;
	UDP_list.tail	= NULL;
	UDP_list.size	= 0;

	return n;

} // End of Flush_FlowTree
Beispiel #5
0
static inline void ProcessICMPFlow(FlowSource_t	*fs, struct FlowNode *NewNode ) {

	// Flush ICMP directly 
	StorePcapFlow(fs, NewNode);
	dbg_printf("Flush ICMP flow: Packets: %u, Bytes: %u\n", NewNode->packets, NewNode->bytes);

	Free_Node(NewNode);

} // End of ProcessICMPFlow
Beispiel #6
0
static inline void ProcessOtherFlow(FlowSource_t *fs, struct FlowNode *NewNode ) {

	// Flush Other packets directly
	StorePcapFlow(fs, NewNode);
	dbg_printf("Flush Other flow: Proto: %u, Packets: %u, Bytes: %u\n", NewNode->proto, NewNode->packets, NewNode->bytes);

	Free_Node(NewNode);


} // End of ProcessOtherFlow
Beispiel #7
0
void UDPexpire(FlowSource_t *fs, time_t t_expire) {
struct FlowNode  *node;
uint32_t num = 0;

	node = UDP_list.list;
	while ( node && (node->t_last.tv_sec < t_expire) ) {
		struct FlowNode  *n = node;
		node = node->right;
		DisconnectFlowNode(&UDP_list, n);
		StorePcapFlow(fs, n);
		Remove_Node(n);
		num++;
	}
	dbg_printf("UDP expired %u flows - left %u\n", num, UDP_list.size);

} // End of UDPexpire