/********************* Monitors packets and updates statistics ***************/
-----------------
function monitor
-----------------
for (each captured packet)
{
   if (packet is outgoing)
   {
	/* Find flow */
	find index i of flow in flow hash
	if (i == NOT_FOUND)
		insert flow in flow hash and store index in i
        /* Find connection */
	find index j of connection in connection hash
	if (j == NOT_FOUND)
	{
		insert connection in connection hash and store index in j
		/* Update number of connections in the flow */
		switch (packet.protocol)
		{
			TCP:  	increment flow[i].TCP_conn
			UDP:  	increment flow[i].UDP_conn
			ICMP:  	increment flow[i].ICMP_conn
			OTHER:  increment flow[i].OTHER_conn
		} /* end switch */
	} /* end if not found */
	if (flow[i].rate_limit exists)
	{
		if (connection[j].classification != GOOD)
		{
			/* This packet will be subjected to rate-limiting */
			if (fs.rate_limit  >= fs.sent_bytes + packet.length and
			    fs.rate_limit - fs.good_bytes_old  >=
			    fs.sent_bytes - fs.good_bytes + packet.length)
			    {	
				forward packet
				goto UPDATE
			    }
			else
			   {
				drop packet
				fs.dropped_bytes += packet.length
				return
			   }
		}
		else
		{
			/* Always pass packets from good connections */
			forward packet
			goto UPDATE
		}
	} /*endif flow is rate-limited */
	else
	{
		/* Always pass packets from not limited flows */
		forward packet
		goto UPDATE
	}	
UPDATE:	
	increment flow[i].sent_to 
	flow[i].sent_bytes += packet.length
	/* Based on packet protocol update protocol statistics */
	switch (packet.protocol) 
	{
		TCP: 	increment flow[i].TCP_sent_to 
			flow[i].TCP_sent_bytes += packet.length
		UDP: 	increment flow[i].UDP_sent_to 
			flow[i].UDP_sent_bytes += packet.length
		ICMP: 	increment flow[i].ICMP_sent_to 
			flow[i].ICMP_sent_bytes += packet.length
		default:increment flow[i].OTHER_sent_to 
			flow[i].OTHER_sent_bytes += packet.length	
	} /* end switch */
	increment connection[j].sent_to 
	connection[j].sent_bytes += packet.length
	/* Update portion of the flow consisting of good connections */
	if (connection[j].classification == GOOD)
		flow[i].good_bytes += packet.length
   } /* end if outgoing packet */
   else /* Packet is incoming */
   {
	/* Always forward incoming packets */
	foward packet
	/* Update flow statistics */
	find index i of flow in flow hash
	if (i == NOT_FOUND)
		insert flow in flow hash and store index in i
	increment flow[i].received_from 
	flow[i].received_bytes += packet.length
	/* Based on packet protocol update protocol statistics */
	switch (packet.protocol) 
	{
		TCP: 	increment flow[i].TCP_received_from 
			flow[i].TCP_received_bytes += packet.length
		UDP: 	increment flow[i].UDP_received_from 
			flow[i].UDP_received_bytes += packet.length
		ICMP: 	increment flow[i].ICMP_received_from 
			flow[i].ICMP_received_bytes += packet.length
		default:increment flow[i].OTHER_received_from 
			flow[i].OTHER_received_bytes += packet.length	
	} /* end switch */
	/* Update connection statistics */
	find index j of connection in connection hash
	if (j == NOT_FOUND)
	{
		insert connection in connection hash and store index in j
		/* Update number of connections in the flow */
		switch (packet.protocol)
		{
			TCP:  	increment flow[i].TCP_conn
			UDP:  	increment flow[i].UDP_conn
			ICMP:  	increment flow[i].ICMP_conn
			OTHER:  increment flow[i].OTHER_conn
		} /* end switch */
	} /* end if not found */
	increment connection[j].received_from 
	connection[j].received_bytes += packet.length
   } /* end if incoming packet */
}


























