bdi-network-resilience

Changes

Details

diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/AnomalyDetectionCapability.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/AnomalyDetectionCapability.java
index 74fad7d..9c22acf 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/AnomalyDetectionCapability.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/AnomalyDetectionCapability.java
@@ -28,6 +28,7 @@ import bdi4jade.belief.PropositionalBelief;
 import bdi4jade.core.GoalUpdateSet;
 import bdi4jade.reasoning.AbstractReasoningStrategy;
 import bdi4jade.reasoning.OptionGenerationFunction;
+import br.ufrgs.inf.bdinetr.domain.AnomalyDetection;
 import br.ufrgs.inf.bdinetr.domain.logic.IpPreposition.Anomalous;
 import br.ufrgs.inf.bdinetr.domain.logic.IpPreposition.Benign;
 import br.ufrgs.inf.bdinetr.domain.logic.IpPreposition.Restricted;
@@ -70,7 +71,11 @@ public class AnomalyDetectionCapability extends RouterAgentCapability {
 
 	private static final long serialVersionUID = -1705728861020677126L;
 
-	public AnomalyDetectionCapability() {
+	@bdi4jade.annotation.TransientBelief
+	private final AnomalyDetection role;
+
+	public AnomalyDetectionCapability(AnomalyDetection anomalyDetection) {
+		this.role = anomalyDetection;
 		ReasoningStrategy strategy = new ReasoningStrategy();
 		setOptionGenerationFunction(strategy);
 	}
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/ClassifierCapability.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/ClassifierCapability.java
index b0694c0..5087f32 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/ClassifierCapability.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/ClassifierCapability.java
@@ -28,6 +28,7 @@ import bdi4jade.belief.PropositionalBelief;
 import bdi4jade.core.GoalUpdateSet;
 import bdi4jade.reasoning.AbstractReasoningStrategy;
 import bdi4jade.reasoning.OptionGenerationFunction;
+import br.ufrgs.inf.bdinetr.domain.Classifier;
 import br.ufrgs.inf.bdinetr.domain.logic.FlowPreposition.Threat;
 import br.ufrgs.inf.bdinetr.domain.logic.FlowPreposition.ThreatResponded;
 
@@ -53,7 +54,11 @@ public class ClassifierCapability extends RouterAgentCapability {
 
 	private static final long serialVersionUID = -1705728861020677126L;
 
-	public ClassifierCapability() {
+	@bdi4jade.annotation.TransientBelief
+	private final Classifier role;
+
+	public ClassifierCapability(Classifier classifier) {
+		this.role = classifier;
 		ReasoningStrategy strategy = new ReasoningStrategy();
 		setOptionGenerationFunction(strategy);
 	}
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/LinkMonitorCapability.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/LinkMonitorCapability.java
index ed2427c..f8181f6 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/LinkMonitorCapability.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/LinkMonitorCapability.java
@@ -21,6 +21,7 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.agent;
 
+import java.util.HashSet;
 import java.util.Set;
 
 import bdi4jade.belief.Belief;
@@ -33,7 +34,6 @@ import bdi4jade.reasoning.OptionGenerationFunction;
 import br.ufrgs.inf.bdinetr.domain.Link;
 import br.ufrgs.inf.bdinetr.domain.LinkMonitor;
 import br.ufrgs.inf.bdinetr.domain.Observer;
-import br.ufrgs.inf.bdinetr.domain.PReSETRole.RoleType;
 import br.ufrgs.inf.bdinetr.domain.logic.LinkProposition.AttackPrevented;
 import br.ufrgs.inf.bdinetr.domain.logic.LinkProposition.OverUsage;
 import br.ufrgs.inf.bdinetr.domain.logic.LinkProposition.RegularUsage;
@@ -68,22 +68,24 @@ public class LinkMonitorCapability extends RouterAgentCapability implements
 
 		@Override
 		public void reviewBeliefs() {
-			LinkMonitor lm = (LinkMonitor) getPReSETRole(RoleType.LINK_MONITOR);
+			synchronized (linkEvents) {
+				for (Link link : linkEvents) {
+					OverUsage overUsage = new OverUsage(link);
+					boolean isOverUsage = role.isOverUsage(link);
 
-			for (Link link : lm.getLinks()) {
-				OverUsage overUsage = new OverUsage(link);
-				boolean isOverUsage = lm.isOverUsage(link);
-
-				if (isOverUsage) {
-					PropositionalBelief<OverUsage> overUsageBelief = (PropositionalBelief<OverUsage>) getBeliefBase()
-							.getBelief(overUsage);
-					if (overUsageBelief == null || !overUsageBelief.getValue()) {
-						belief(overUsage, true);
-						belief(new RegularUsage(link), null);
+					if (isOverUsage) {
+						PropositionalBelief<OverUsage> overUsageBelief = (PropositionalBelief<OverUsage>) getBeliefBase()
+								.getBelief(overUsage);
+						if (overUsageBelief == null
+								|| !overUsageBelief.getValue()) {
+							belief(overUsage, true);
+							belief(new RegularUsage(link), null);
+						}
+					} else {
+						belief(overUsage, null);
 					}
-				} else {
-					belief(overUsage, null);
 				}
+				linkEvents.clear();
 			}
 		}
 	}
@@ -92,21 +94,31 @@ public class LinkMonitorCapability extends RouterAgentCapability implements
 
 	private static final long serialVersionUID = -1705728861020677126L;
 
+	@bdi4jade.annotation.TransientBeliefSet
+	private final Set<Link> linkEvents;
+
 	@bdi4jade.annotation.Belief
 	private Belief<String, Double> overUsageThreshold = new TransientBelief<>(
 			"threshold", OVER_USAGE_THRESHOLD);
 
-	public LinkMonitorCapability() {
+	@bdi4jade.annotation.TransientBelief
+	private LinkMonitor role;
+
+	public LinkMonitorCapability(LinkMonitor linkMonitor) {
+		this.role = linkMonitor;
+		linkMonitor.attachObserver(this);
+		this.linkEvents = new HashSet<>();
+
 		ReasoningStrategy strategy = new ReasoningStrategy();
 		setBeliefRevisionStrategy(strategy);
 		setOptionGenerationFunction(strategy);
-
-		LinkMonitor lm = (LinkMonitor) getPReSETRole(RoleType.LINK_MONITOR);
-		lm.attachObserver(this);
 	}
 
 	@Override
 	public void update(Object o, Object arg) {
+		synchronized (linkEvents) {
+			this.linkEvents.add((Link) arg);
+		}
 		getMyAgent().restart();
 	}
 
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RateLimiterCapability.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RateLimiterCapability.java
index 77124b1..0d1a8ac 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RateLimiterCapability.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RateLimiterCapability.java
@@ -21,6 +21,8 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.agent;
 
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Set;
 
 import bdi4jade.annotation.Parameter;
@@ -37,13 +39,17 @@ import bdi4jade.plan.planbody.BeliefGoalPlanBody;
 import bdi4jade.reasoning.AbstractReasoningStrategy;
 import bdi4jade.reasoning.OptionGenerationFunction;
 import br.ufrgs.inf.bdinetr.agent.RouterAgent.RootCapability;
-import br.ufrgs.inf.bdinetr.domain.IpAddress;
+import br.ufrgs.inf.bdinetr.domain.Flow;
+import br.ufrgs.inf.bdinetr.domain.Ip;
 import br.ufrgs.inf.bdinetr.domain.Link;
-import br.ufrgs.inf.bdinetr.domain.PReSETRole.RoleType;
 import br.ufrgs.inf.bdinetr.domain.PReSETRouter;
 import br.ufrgs.inf.bdinetr.domain.RateLimiter;
+import br.ufrgs.inf.bdinetr.domain.logic.FlowPreposition.FlowRateLimited;
+import br.ufrgs.inf.bdinetr.domain.logic.FlowPreposition.Threat;
+import br.ufrgs.inf.bdinetr.domain.logic.FlowPreposition.ThreatResponded;
 import br.ufrgs.inf.bdinetr.domain.logic.IpPreposition.Anomalous;
 import br.ufrgs.inf.bdinetr.domain.logic.IpPreposition.Benign;
+import br.ufrgs.inf.bdinetr.domain.logic.IpPreposition.OverUsageCause;
 import br.ufrgs.inf.bdinetr.domain.logic.IpPreposition.RateLimited;
 import br.ufrgs.inf.bdinetr.domain.logic.IpPreposition.Restricted;
 import br.ufrgs.inf.bdinetr.domain.logic.LinkProposition.AttackPrevented;
@@ -56,38 +62,86 @@ import br.ufrgs.inf.bdinetr.domain.logic.LinkProposition.RegularUsage;
  */
 public class RateLimiterCapability extends RouterAgentCapability {
 
+	public class LimitFlowRatePlan extends BeliefGoalPlanBody {
+		private static final long serialVersionUID = -3493377510830902961L;
+
+		private Flow flow;
+
+		@Override
+		public void execute() {
+			role.limitFlow(flow, FLOW_LIMIT_RATE);
+			belief(new FlowRateLimited(flow), true);
+			belief(new ThreatResponded(flow), true);
+			belief(new Threat(flow), null);
+
+			boolean exists = false;
+			Set<Belief<?, ?>> threatBeliefs = getBeliefBase().getBeliefsByType(
+					Threat.class);
+			for (Belief<?, ?> belief : threatBeliefs) {
+				PropositionalBelief<Threat> threat = (PropositionalBelief<Threat>) belief;
+				assert threat.getValue();
+				if (flow.getDstIp().equals(
+						threat.getName().getFlow().getDstIp())) {
+					exists = true;
+					break;
+				}
+			}
+			if (!exists) {
+				belief(new Benign(flow.getDstIp()), true);
+			}
+
+			log.info(getGoal());
+		}
+
+		@Parameter(direction = Direction.IN)
+		public void setBeliefName(ThreatResponded threatResponded) {
+			this.flow = threatResponded.getFlow();
+		}
+	}
+
 	public class LimitIPRatePlan extends BeliefGoalPlanBody {
 		private static final long serialVersionUID = -3493377510830902961L;
 
 		@bdi4jade.annotation.Belief(name = RootCapability.ROUTER_BELIEF)
 		private Belief<String, PReSETRouter> device;
-		private IpAddress ip;
+		private Ip ip;
 
 		@Override
 		public void execute() {
-			((RateLimiter) getPReSETRole(RoleType.RATE_LIMITER)).limitIp(ip,
-					IP_LIMIT_RATE);
+			role.limitIp(ip, IP_LIMIT_RATE);
 			belief(new RateLimited(ip), true);
 			belief(new Restricted(ip), true);
 
-			boolean exists = false;
-			Set<Belief<?, ?>> anomalousBeliefs = getBeliefBase()
-					.getBeliefsByType(Anomalous.class);
-			for (Belief<?, ?> belief : anomalousBeliefs) {
-				PropositionalBelief<Anomalous> anomalous = (PropositionalBelief<Anomalous>) belief;
-				if (anomalous.getValue()) {
-					PropositionalBelief<Restricted> restricted = (PropositionalBelief<Restricted>) getBeliefBase()
-							.getBelief(
-									new Restricted(anomalous.getName().getIp()));
-					if (restricted == null || !restricted.getValue()) {
+			Set<Belief<?, ?>> overUsageCauseBeliefs = getBeliefBase()
+					.getBeliefsByType(OverUsageCause.class);
+			Set<OverUsageCause> causedByIp = new HashSet<>();
+			Iterator<Belief<?, ?>> it = overUsageCauseBeliefs.iterator();
+			while (it.hasNext()) {
+				PropositionalBelief<OverUsageCause> overUsageCause = (PropositionalBelief<OverUsageCause>) it
+						.next();
+				if (ip.equals(overUsageCause.getName().getIp())) {
+					assert overUsageCause.getValue();
+					causedByIp.add(overUsageCause.getName());
+				}
+				it.remove();
+				belief(overUsageCause.getName(), null);
+			}
+
+			for (OverUsageCause overUsageCause : causedByIp) {
+				boolean exists = false;
+				for (Belief<?, ?> belief : overUsageCauseBeliefs) {
+					PropositionalBelief<OverUsageCause> otherOverUsageCause = (PropositionalBelief<OverUsageCause>) belief;
+					if (overUsageCause.getLink().equals(
+							otherOverUsageCause.getName().getLink())) {
+						assert !overUsageCause.getIp().equals(
+								otherOverUsageCause.getName().getIp());
 						exists = true;
+						break;
 					}
-
 				}
-			}
-			if (!exists) {
-				// FIXME
-				belief(new RegularUsage(new Link("")), true);
+				if (!exists) {
+					belief(new RegularUsage(overUsageCause.getLink()), true);
+				}
 			}
 
 			log.info(getGoal());
@@ -106,8 +160,7 @@ public class RateLimiterCapability extends RouterAgentCapability {
 
 		@Override
 		public void execute() {
-			((RateLimiter) getPReSETRole(RoleType.RATE_LIMITER)).limitLink(
-					link, LINK_LIMIT_RATE);
+			role.limitLink(link, LINK_LIMIT_RATE);
 			belief(new FullyOperational(link), false);
 			belief(new AttackPrevented(link), true);
 			log.info(getGoal());
@@ -147,11 +200,11 @@ public class RateLimiterCapability extends RouterAgentCapability {
 
 		@bdi4jade.annotation.Belief(name = RootCapability.ROUTER_BELIEF)
 		private Belief<String, PReSETRouter> device;
-		private IpAddress ip;
+		private Ip ip;
 
 		@Override
 		public void execute() {
-			((RateLimiter) getPReSETRole(RoleType.RATE_LIMITER)).unlimitIp(ip);
+			role.unlimitIp(ip);
 			belief(new RateLimited(ip), false);
 			belief(new Restricted(ip), false);
 			belief(new Anomalous(ip), null);
@@ -171,8 +224,7 @@ public class RateLimiterCapability extends RouterAgentCapability {
 
 		@Override
 		public void execute() {
-			((RateLimiter) getPReSETRole(RoleType.RATE_LIMITER))
-					.unlimitLink(link);
+			role.unlimitLink(link);
 			belief(new FullyOperational(link), true);
 			belief(new AttackPrevented(link), null);
 			log.info(getGoal());
@@ -184,12 +236,25 @@ public class RateLimiterCapability extends RouterAgentCapability {
 		}
 	}
 
+	public static final double FLOW_LIMIT_RATE = 0.5;
 	public static final double IP_LIMIT_RATE = 0.5;
 	public static final double LINK_LIMIT_RATE = 0.5;
 
 	private static final long serialVersionUID = -1705728861020677126L;
 
 	@bdi4jade.annotation.Plan
+	private Plan limitFlowRate = new DefaultPlan(
+			GoalTemplateFactory.hasValueForBeliefOfType(ThreatResponded.class,
+					Boolean.TRUE), LimitFlowRatePlan.class) {
+		public boolean isContextApplicable(Goal goal) {
+			BeliefGoal<ThreatResponded> bg = (BeliefGoal<ThreatResponded>) goal;
+			PropositionalBelief<Threat> threat = (PropositionalBelief<Threat>) getBeliefBase()
+					.getBelief(new Threat(bg.getBeliefName().getFlow()));
+			return (threat != null && threat.getValue());
+		};
+	};
+
+	@bdi4jade.annotation.Plan
 	private Plan limitIpRate = new DefaultPlan(
 			GoalTemplateFactory.hasValueForBeliefOfType(Restricted.class,
 					Boolean.TRUE), LimitIPRatePlan.class) {
@@ -240,7 +305,12 @@ public class RateLimiterCapability extends RouterAgentCapability {
 		};
 	};
 
-	public RateLimiterCapability() {
+	@bdi4jade.annotation.TransientBelief
+	private final RateLimiter role;
+
+	public RateLimiterCapability(RateLimiter rateLimiter) {
+		this.role = rateLimiter;
+
 		ReasoningStrategy strategy = new ReasoningStrategy();
 		setOptionGenerationFunction(strategy);
 	}
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RouterAgent.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RouterAgent.java
index 7c60f68..42ce3d5 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RouterAgent.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RouterAgent.java
@@ -25,8 +25,12 @@ import bdi4jade.belief.Belief;
 import bdi4jade.belief.TransientBelief;
 import bdi4jade.core.Capability;
 import bdi4jade.core.SingleCapabilityAgent;
+import br.ufrgs.inf.bdinetr.domain.AnomalyDetection;
+import br.ufrgs.inf.bdinetr.domain.Classifier;
+import br.ufrgs.inf.bdinetr.domain.LinkMonitor;
 import br.ufrgs.inf.bdinetr.domain.PReSETRole.RoleType;
 import br.ufrgs.inf.bdinetr.domain.PReSETRouter;
+import br.ufrgs.inf.bdinetr.domain.RateLimiter;
 
 /**
  * @author Ingrid Nunes
@@ -54,14 +58,21 @@ public class RouterAgent extends SingleCapabilityAgent {
 	public RouterAgent(PReSETRouter router) {
 		super(new RootCapability(router));
 		if (router.hasRole(RoleType.LINK_MONITOR)) {
-			this.getCapability().addPartCapability(new LinkMonitorCapability());
+			this.getCapability().addPartCapability(
+					new LinkMonitorCapability((LinkMonitor) router
+							.getRole(RoleType.LINK_MONITOR)));
 		} else if (router.hasRole(RoleType.ANOMALY_DETECTION)) {
 			this.getCapability().addPartCapability(
-					new AnomalyDetectionCapability());
+					new AnomalyDetectionCapability((AnomalyDetection) router
+							.getRole(RoleType.ANOMALY_DETECTION)));
 		} else if (router.hasRole(RoleType.RATE_LIMITER)) {
-			this.getCapability().addPartCapability(new RateLimiterCapability());
+			this.getCapability().addPartCapability(
+					new RateLimiterCapability((RateLimiter) router
+							.getRole(RoleType.RATE_LIMITER)));
 		} else if (router.hasRole(RoleType.CLASSIFIER)) {
-			this.getCapability().addPartCapability(new ClassifierCapability());
+			this.getCapability().addPartCapability(
+					new ClassifierCapability((Classifier) router
+							.getRole(RoleType.CLASSIFIER)));
 		}
 	}
 
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RouterAgentCapability.java b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RouterAgentCapability.java
index 01aaac3..1e98cc1 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RouterAgentCapability.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/agent/RouterAgentCapability.java
@@ -21,21 +21,18 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.agent;
 
-import bdi4jade.belief.Belief;
 import bdi4jade.belief.TransientPropositionalBelief;
 import bdi4jade.core.Capability;
 import bdi4jade.goal.BeliefPresentGoal;
 import bdi4jade.goal.PropositionalBeliefValueGoal;
-import br.ufrgs.inf.bdinetr.agent.RouterAgent.RootCapability;
-import br.ufrgs.inf.bdinetr.domain.PReSETRole;
-import br.ufrgs.inf.bdinetr.domain.PReSETRole.RoleType;
-import br.ufrgs.inf.bdinetr.domain.PReSETRouter;
 
 /**
  * @author Ingrid Nunes
  */
 public class RouterAgentCapability extends Capability {
 
+	public static final String ROLE_BELIEF = "role";
+
 	private static final long serialVersionUID = -3491170777812144486L;
 
 	protected void belief(Object proposition, Boolean value) {
@@ -49,15 +46,6 @@ public class RouterAgentCapability extends Capability {
 		}
 	}
 
-	protected PReSETRole getPReSETRole(RoleType roleType) {
-		return getRouter().getRole(roleType);
-	}
-
-	protected PReSETRouter getRouter() {
-		return ((Belief<String, PReSETRouter>) getBeliefBase().getBelief(
-				RootCapability.ROUTER_BELIEF)).getValue();
-	}
-
 	protected void goal(Object proposition) {
 		getMyAgent().addGoal(this, new BeliefPresentGoal(proposition));
 		log.debug("goal(?" + proposition + "))");
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/BDINetRApp.java b/network-resilience/src/br/ufrgs/inf/bdinetr/BDINetRApp.java
index 97aac4d..45eb143 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/BDINetRApp.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/BDINetRApp.java
@@ -38,7 +38,7 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.log4j.PropertyConfigurator;
 
 import br.ufrgs.inf.bdinetr.agent.RouterAgent;
-import br.ufrgs.inf.bdinetr.domain.IpAddress;
+import br.ufrgs.inf.bdinetr.domain.Ip;
 import br.ufrgs.inf.bdinetr.domain.PReSETRouter;
 
 /**
@@ -46,7 +46,7 @@ import br.ufrgs.inf.bdinetr.domain.PReSETRouter;
  */
 public class BDINetRApp {
 
-	private static final Map<IpAddress, Agent> AGENTS;
+	private static final Map<Ip, Agent> AGENTS;
 
 	static {
 		PropertyConfigurator.configure(BDINetRApp.class
@@ -82,7 +82,7 @@ public class BDINetRApp {
 		PlatformController controller = runtime
 				.createMainContainer(bootProfile);
 
-		for (IpAddress agentName : AGENTS.keySet()) {
+		for (Ip agentName : AGENTS.keySet()) {
 			try {
 				AgentController ac = ((AgentContainer) controller)
 						.acceptNewAgent(agentName.toString(),
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/AnomalyDetection.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/AnomalyDetection.java
index 0fe161a..0bf40c1 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/AnomalyDetection.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/AnomalyDetection.java
@@ -41,9 +41,13 @@ public class AnomalyDetection extends PReSETRole {
 		super(router);
 	}
 
-	public Set<IpAddress> detectIntrusion(Link link) {
-		// FIXME
-		return new HashSet<>();
+	public Set<Ip> detectIntrusion(Link link) {
+		Set<Ip> intrusions = new HashSet<>();
+		if (link.getId().equals("AFFECTED_LINK")) {
+			intrusions.add(new Ip("victim1"));
+			intrusions.add(new Ip("victim2"));
+		}
+		return intrusions;
 	}
 
 }
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/Classifier.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/Classifier.java
index dfcd40b..ca7b727 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/Classifier.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/Classifier.java
@@ -40,9 +40,18 @@ public class Classifier extends PReSETRole {
 		super(router);
 	}
 
-	public Set<Flow> classifyFlows(IpAddress ip) {
-		// FIXME
-		return new HashSet<>();
+	public Set<Flow> classifyFlows(Ip ip) {
+		Set<Flow> flows = new HashSet<>();
+		if (ip.getAddress().equals("victim1")) {
+			flows.add(new Flow(new Ip("DDoS1"), 80, new Ip("victim1"), 80,
+					"http"));
+			flows.add(new Flow(new Ip("DDoS2"), 80, new Ip("victim1"), 80,
+					"http"));
+		} else if (ip.getAddress().equals("victim2")) {
+			flows.add(new Flow(new Ip("DDoS3"), 80, new Ip("victim2"), 80,
+					"http"));
+		}
+		return flows;
 	}
 
 	public void turnFlowExporterOn() {
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/Flow.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/Flow.java
index f1fa114..eb84ee0 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/Flow.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/Flow.java
@@ -26,14 +26,13 @@ package br.ufrgs.inf.bdinetr.domain;
  */
 public class Flow {
 
-	private IpAddress dstIp;
+	private Ip dstIp;
 	private int dstPort;
 	private String protocol;
-	private IpAddress srcIp;
+	private Ip srcIp;
 	private int srcPort;
 
-	public Flow(IpAddress srcIp, int srcPort, IpAddress dstIp, int dstPort,
-			String protocol) {
+	public Flow(Ip srcIp, int srcPort, Ip dstIp, int dstPort, String protocol) {
 		this.srcIp = srcIp;
 		this.srcPort = srcPort;
 		this.dstIp = dstIp;
@@ -72,7 +71,7 @@ public class Flow {
 		return true;
 	}
 
-	public IpAddress getDstIp() {
+	public Ip getDstIp() {
 		return dstIp;
 	}
 
@@ -84,7 +83,7 @@ public class Flow {
 		return protocol;
 	}
 
-	public IpAddress getSrcIp() {
+	public Ip getSrcIp() {
 		return srcIp;
 	}
 
@@ -105,7 +104,7 @@ public class Flow {
 		return result;
 	}
 
-	public void setDstIp(IpAddress dstIp) {
+	public void setDstIp(Ip dstIp) {
 		this.dstIp = dstIp;
 	}
 
@@ -117,7 +116,7 @@ public class Flow {
 		this.protocol = protocol;
 	}
 
-	public void setSrcIp(IpAddress srcIp) {
+	public void setSrcIp(Ip srcIp) {
 		this.srcIp = srcIp;
 	}
 
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/Link.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/Link.java
index 9f35abe..d693858 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/Link.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/Link.java
@@ -41,6 +41,10 @@ public class Link {
 		return false;
 	}
 
+	public String getId() {
+		return id;
+	}
+
 	@Override
 	public int hashCode() {
 		return id == null ? 0 : id.hashCode();
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/LinkMonitor.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/LinkMonitor.java
index 8332e45..c28c4b8 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/LinkMonitor.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/LinkMonitor.java
@@ -22,7 +22,6 @@
 package br.ufrgs.inf.bdinetr.domain;
 
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -37,17 +36,11 @@ import java.util.Set;
  */
 public class LinkMonitor extends PReSETRole {
 
-	private final Set<Observer> observers;
 	private final Map<Link, Boolean> overUsageLinks;
 
 	public LinkMonitor(PReSETRouter router) {
 		super(router);
 		this.overUsageLinks = new HashMap<>();
-		this.observers = new HashSet<>();
-	}
-
-	public void attachObserver(Observer observer) {
-		this.observers.add(observer);
 	}
 
 	public Set<Link> getLinks() {
@@ -61,12 +54,6 @@ public class LinkMonitor extends PReSETRole {
 		return overUsage;
 	}
 
-	private void notifyObservers(Object arg) {
-		for (Observer observer : observers) {
-			observer.update(this, arg);
-		}
-	}
-
 	public void setOverUsage(Link link, boolean overUsage) {
 		this.overUsageLinks.put(link, overUsage);
 		notifyObservers(link);
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/logic/FlowPreposition.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/logic/FlowPreposition.java
index 9d89b58..af315b7 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/logic/FlowPreposition.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/logic/FlowPreposition.java
@@ -27,19 +27,19 @@ import br.ufrgs.inf.bdinetr.domain.Flow;
  * @author Ingrid Nunes
  */
 public class FlowPreposition {
-	
+
 	public static class FlowRateLimited extends FlowPreposition {
 		public FlowRateLimited(Flow flow) {
 			super(flow);
 		}
 	}
-	
+
 	public static class Threat extends FlowPreposition {
 		public Threat(Flow flow) {
 			super(flow);
 		}
 	}
-	
+
 	public static class ThreatResponded extends FlowPreposition {
 		public ThreatResponded(Flow flow) {
 			super(flow);
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/logic/IpPreposition.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/logic/IpPreposition.java
index 8d1d835..28b5de2 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/logic/IpPreposition.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/logic/IpPreposition.java
@@ -21,7 +21,8 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain.logic;
 
-import br.ufrgs.inf.bdinetr.domain.IpAddress;
+import br.ufrgs.inf.bdinetr.domain.Ip;
+import br.ufrgs.inf.bdinetr.domain.Link;
 
 /**
  * @author Ingrid Nunes
@@ -29,38 +30,65 @@ import br.ufrgs.inf.bdinetr.domain.IpAddress;
 public class IpPreposition {
 
 	public static class Anomalous extends IpPreposition {
-		public Anomalous(IpAddress ip) {
+		public Anomalous(Ip ip) {
 			super(ip);
 		}
 	}
 
 	public static class Benign extends IpPreposition {
-		public Benign(IpAddress ip) {
+		public Benign(Ip ip) {
 			super(ip);
 		}
 	}
 
-	public static class FlowRecord extends IpPreposition {
-		public FlowRecord(IpAddress ip) {
+	public static class OverUsageCause extends IpPreposition {
+		private Link link;
+
+		public OverUsageCause(Ip ip, Link link) {
 			super(ip);
+			this.link = link;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if (!super.equals(obj))
+				return false;
+			if (obj != null && this.getClass().equals(obj.getClass())) {
+				OverUsageCause lp = (OverUsageCause) obj;
+				return this.link.equals(lp.link);
+			}
+			return false;
+		}
+
+		public Link getLink() {
+			return link;
+		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = super.hashCode();
+			result = prime * result + ((link == null) ? 0 : link.hashCode());
+			return result;
 		}
+
 	}
 
 	public static class RateLimited extends IpPreposition {
-		public RateLimited(IpAddress ip) {
+		public RateLimited(Ip ip) {
 			super(ip);
 		}
 	}
 
 	public static class Restricted extends IpPreposition {
-		public Restricted(IpAddress ip) {
+		public Restricted(Ip ip) {
 			super(ip);
 		}
 	}
 
-	protected IpAddress ip;
+	protected Ip ip;
 
-	public IpPreposition(IpAddress ip) {
+	public IpPreposition(Ip ip) {
 		this.ip = ip;
 	}
 
@@ -73,7 +101,7 @@ public class IpPreposition {
 		return false;
 	}
 
-	public IpAddress getIp() {
+	public Ip getIp() {
 		return ip;
 	}
 
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/logic/LinkProposition.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/logic/LinkProposition.java
index ee93021..aa1ee53 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/logic/LinkProposition.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/logic/LinkProposition.java
@@ -52,12 +52,6 @@ public class LinkProposition {
 		}
 	}
 
-	public static class Usage extends LinkProposition {
-		public Usage(Link link) {
-			super(link);
-		}
-	}
-
 	protected Link link;
 
 	public LinkProposition(Link link) {
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/PReSETRole.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/PReSETRole.java
index 6839503..2ce637d 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/PReSETRole.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/PReSETRole.java
@@ -21,6 +21,9 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr.domain;
 
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * @author Ingrid Nunes
  */
@@ -47,9 +50,21 @@ public abstract class PReSETRole {
 	}
 
 	protected final PReSETRouter router;
+	private final Set<Observer> observers;
 
 	public PReSETRole(PReSETRouter router) {
 		this.router = router;
+		this.observers = new HashSet<>();
+	}
+
+	public void attachObserver(Observer observer) {
+		this.observers.add(observer);
+	}
+
+	protected void notifyObservers(Object arg) {
+		for (Observer observer : observers) {
+			observer.update(this, arg);
+		}
 	}
 
 }
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/PReSETRouter.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/PReSETRouter.java
index 0ee6a16..80d2ffe 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/PReSETRouter.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/PReSETRouter.java
@@ -31,10 +31,10 @@ import br.ufrgs.inf.bdinetr.domain.PReSETRole.RoleType;
  */
 public class PReSETRouter {
 
-	private final IpAddress ip;
+	private final Ip ip;
 	private final Map<RoleType, PReSETRole> roles;
 
-	public PReSETRouter(final IpAddress id, int roles) {
+	public PReSETRouter(final Ip id, int roles) {
 		this.ip = id;
 		this.roles = new HashMap<>();
 		if (RoleType.LINK_MONITOR.isPresent(roles)) {
@@ -58,7 +58,7 @@ public class PReSETRouter {
 		return false;
 	}
 
-	public IpAddress getIp() {
+	public Ip getIp() {
 		return ip;
 	}
 
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/RateLimiter.java b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/RateLimiter.java
index 3a989f6..a53d39a 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/domain/RateLimiter.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/domain/RateLimiter.java
@@ -38,8 +38,20 @@ import java.util.Map;
  */
 public class RateLimiter extends PReSETRole {
 
+	public class LimitLinkEvent {
+		private Link link;
+
+		public LimitLinkEvent(Link link) {
+			this.link = link;
+		}
+
+		public Link getLink() {
+			return link;
+		}
+	}
+
 	private final Map<Flow, Double> rateLimitedflows;
-	private final Map<IpAddress, Double> rateLimitedIps;
+	private final Map<Ip, Double> rateLimitedIps;
 	private final Map<Link, Double> rateLimitedLinks;
 
 	public RateLimiter(PReSETRouter router) {
@@ -53,19 +65,20 @@ public class RateLimiter extends PReSETRole {
 		this.rateLimitedflows.put(flow, rate);
 	}
 
-	public void limitIp(IpAddress ip, double rate) {
+	public void limitIp(Ip ip, double rate) {
 		this.rateLimitedIps.put(ip, rate);
 	}
 
 	public void limitLink(Link link, double rate) {
 		this.rateLimitedLinks.put(link, rate);
+		notifyObservers(new LimitLinkEvent(link));
 	}
 
 	public void unlimitFlow(Flow flow) {
 		this.rateLimitedflows.remove(flow);
 	}
 
-	public void unlimitIp(IpAddress ip) {
+	public void unlimitIp(Ip ip) {
 		this.rateLimitedIps.remove(ip);
 	}
 
diff --git a/network-resilience/src/br/ufrgs/inf/bdinetr/Network.java b/network-resilience/src/br/ufrgs/inf/bdinetr/Network.java
index 8a1862f..32dbbe2 100644
--- a/network-resilience/src/br/ufrgs/inf/bdinetr/Network.java
+++ b/network-resilience/src/br/ufrgs/inf/bdinetr/Network.java
@@ -21,67 +21,41 @@
 //----------------------------------------------------------------------------
 package br.ufrgs.inf.bdinetr;
 
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
-import java.util.Random;
 import java.util.Set;
 import java.util.Timer;
-import java.util.TimerTask;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import bdi4jade.examples.BDI4JADEExamplesPanel;
-import br.ufrgs.inf.bdinetr.domain.IpAddress;
+import br.ufrgs.inf.bdinetr.domain.Ip;
 import br.ufrgs.inf.bdinetr.domain.Link;
 import br.ufrgs.inf.bdinetr.domain.LinkMonitor;
+import br.ufrgs.inf.bdinetr.domain.Observer;
 import br.ufrgs.inf.bdinetr.domain.PReSETRole.RoleType;
 import br.ufrgs.inf.bdinetr.domain.PReSETRouter;
+import br.ufrgs.inf.bdinetr.domain.RateLimiter;
+import br.ufrgs.inf.bdinetr.domain.RateLimiter.LimitLinkEvent;
 
 /**
  * @author Ingrid Nunes
  */
-public class Network {
-
-	class LinkUsageUpdater extends TimerTask {
-		private static final double OVER_USAGE_PROBABILITY = 0.3;
-
-		@Override
-		public void run() {
-			Map<Link, Boolean> overUsage = new HashMap<>();
-			Random random = new Random(System.currentTimeMillis());
-			for (Link link : NETWORK.getLinks()) {
-				double d = random.nextDouble();
-				overUsage.put(link, d < OVER_USAGE_PROBABILITY);
-			}
-			log.info("Updating link usage");
-			for (PReSETRouter router : NETWORK.getRouters()) {
-				if (router.hasRole(RoleType.LINK_MONITOR)) {
-					LinkMonitor lm = (LinkMonitor) router
-							.getRole(RoleType.LINK_MONITOR);
-					for (Link link : overUsage.keySet()) {
-						lm.setOverUsage(link, overUsage.get(link));
-					}
-				}
-			}
-		}
-	}
+public class Network implements Observer {
 
+	public static final Link AFFECTED_LINK;
 	public static final Network NETWORK;
 
 	static {
 		NETWORK = new Network();
-		PReSETRouter firewall = new PReSETRouter(new IpAddress("Firewall"),
-				RoleType.RATE_LIMITER.getId());
-		NETWORK.addRouter(firewall);
-		PReSETRouter linkMonitor = new PReSETRouter(new IpAddress(
-				"Rate Limiter"), RoleType.LINK_MONITOR.getId());
-		NETWORK.addRouter(linkMonitor);
+		NETWORK.addRouter(new PReSETRouter(new Ip("Router"),
+				RoleType.RATE_LIMITER.getId() | RoleType.CLASSIFIER.getId()
+						| RoleType.ANOMALY_DETECTION.getId()
+						| RoleType.LINK_MONITOR.getId()));
 
+		AFFECTED_LINK = new Link("AFFECTED_LINK");
+		NETWORK.addLink(AFFECTED_LINK);
 		NETWORK.addLink(new Link("LINK_01"));
 		NETWORK.addLink(new Link("LINK_02"));
-		NETWORK.addLink(new Link("LINK_03"));
 	}
 
 	private final Set<Link> links;
@@ -94,6 +68,13 @@ public class Network {
 		this.router = new HashSet<>();
 		this.links = new HashSet<>();
 		this.timer = new Timer();
+
+		for (PReSETRouter router : NETWORK.getRouters()) {
+			if (router.hasRole(RoleType.RATE_LIMITER)) {
+				((RateLimiter) router.getRole(RoleType.RATE_LIMITER))
+						.attachObserver(this);
+			}
+		}
 	}
 
 	public void addLink(Link link) {
@@ -117,8 +98,30 @@ public class Network {
 	 * {@link BDI4JADEExamplesPanel}.
 	 */
 	public void run() {
-		int interval = 10 * 1000;
-		this.timer.schedule(new LinkUsageUpdater(), interval, interval);
+		log.info("Updating link usage");
+		for (PReSETRouter router : NETWORK.getRouters()) {
+			if (router.hasRole(RoleType.LINK_MONITOR)) {
+				LinkMonitor lm = (LinkMonitor) router
+						.getRole(RoleType.LINK_MONITOR);
+				lm.setOverUsage(AFFECTED_LINK, true);
+			}
+		}
+	}
+
+	@Override
+	public void update(Object o, Object arg) {
+		if (arg instanceof LimitLinkEvent) {
+			LimitLinkEvent event = (LimitLinkEvent) arg;
+			for (PReSETRouter router : NETWORK.getRouters()) {
+				if (router.hasRole(RoleType.LINK_MONITOR)) {
+					LinkMonitor lm = (LinkMonitor) router
+							.getRole(RoleType.LINK_MONITOR);
+					if (lm.isOverUsage(event.getLink())) {
+						lm.setOverUsage(event.getLink(), false);
+					}
+				}
+			}
+		}
 	}
 
 }