summaryrefslogtreecommitdiffstats
path: root/verigraph/service
diff options
context:
space:
mode:
Diffstat (limited to 'verigraph/service')
-rw-r--r--verigraph/service/src/mcnet/components/Checker.java363
-rw-r--r--verigraph/service/src/mcnet/components/Core.java44
-rw-r--r--verigraph/service/src/mcnet/components/DataIsolationResult.java41
-rw-r--r--verigraph/service/src/mcnet/components/IsolationResult.java42
-rw-r--r--verigraph/service/src/mcnet/components/NetContext.java340
-rw-r--r--verigraph/service/src/mcnet/components/Network.java296
-rw-r--r--verigraph/service/src/mcnet/components/NetworkObject.java57
-rw-r--r--verigraph/service/src/mcnet/components/Result.java43
-rw-r--r--verigraph/service/src/mcnet/components/Tuple.java35
-rw-r--r--verigraph/service/src/mcnet/netobjs/AclFirewall.java123
-rw-r--r--verigraph/service/src/mcnet/netobjs/DumbNode.java42
-rw-r--r--verigraph/service/src/mcnet/netobjs/EndHost.java100
-rw-r--r--verigraph/service/src/mcnet/netobjs/PacketModel.java70
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoAntispam.java124
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoCache.java177
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoEndHost.java100
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoErrFunction.java96
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoFieldModifier.java91
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoIDS.java140
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoMailClient.java106
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoMailServer.java117
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoNF.java101
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoNat.java176
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoVpnAccess.java142
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoVpnExit.java142
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoWebClient.java107
-rw-r--r--verigraph/service/src/mcnet/netobjs/PolitoWebServer.java114
-rw-r--r--verigraph/service/src/tests/j-verigraph-generator/README.rst54
-rw-r--r--verigraph/service/src/tests/j-verigraph-generator/__init__.py8
-rw-r--r--verigraph/service/src/tests/j-verigraph-generator/batch_generator.py186
-rw-r--r--verigraph/service/src/tests/j-verigraph-generator/code_generator.py59
-rw-r--r--verigraph/service/src/tests/j-verigraph-generator/config.py88
-rw-r--r--verigraph/service/src/tests/j-verigraph-generator/json_generator.py261
-rw-r--r--verigraph/service/src/tests/j-verigraph-generator/routing_generator.py80
-rw-r--r--verigraph/service/src/tests/j-verigraph-generator/test_class_generator.py399
-rw-r--r--verigraph/service/src/tests/j-verigraph-generator/test_generator.py160
-rw-r--r--verigraph/service/src/tests/j-verigraph-generator/utility.py257
37 files changed, 4881 insertions, 0 deletions
diff --git a/verigraph/service/src/mcnet/components/Checker.java b/verigraph/service/src/mcnet/components/Checker.java
new file mode 100644
index 0000000..3c13d28
--- /dev/null
+++ b/verigraph/service/src/mcnet/components/Checker.java
@@ -0,0 +1,363 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Model;
+import com.microsoft.z3.Solver;
+import com.microsoft.z3.Status;
+
+/**Various checks for specific properties in the network.
+ *
+ */
+public class Checker {
+
+ Context ctx;
+ Network net;
+ NetContext nctx;
+ Solver solver;
+ ArrayList<BoolExpr> constraints;
+ public BoolExpr [] assertions;
+ public Status result;
+ public Model model;
+
+
+ public Checker(Context context,NetContext nctx,Network network){
+ this.ctx = context;
+ this.net = network;
+ this.nctx = nctx;
+ this.solver = ctx.mkSolver();
+ this.constraints = new ArrayList<BoolExpr>();
+ }
+
+ /**Resets the constraints
+ *
+ */
+ public void clearState (){
+ this.solver.reset();
+ this.constraints = new ArrayList<BoolExpr>();
+ }
+
+ /**Checks whether the source provided can reach the destination
+ *
+ * @param src
+ * @param dest
+ * @return
+ */
+ public IsolationResult checkIsolationProperty (NetworkObject src, NetworkObject dest){
+ assert(net.elements.contains(src));
+ assert(net.elements.contains(dest));
+ solver.push ();
+ addConstraints();
+
+ Expr p0 = ctx.mkConst("check_isolation_p0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+ Expr p1 = ctx.mkConst("check_isolation_p1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+ Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+ Expr n_1 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+ IntExpr t_0 = ctx.mkIntConst("check_isolation_t0_"+src.getZ3Node()+"_"+dest.getZ3Node());
+ IntExpr t_1 = ctx.mkIntConst("check_isolation_t1_"+src.getZ3Node()+"_"+dest.getZ3Node());
+
+ // Constraint1 recv(n_0,destNode,p0,t_0)
+ this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p0, t_0));
+
+ // Constraint2 send(srcNode,n_1,p1,t_1)
+ this.solver.add((BoolExpr)nctx.send.apply(src.getZ3Node(), n_1, p1, t_1));
+
+ // Constraint3 nodeHasAddr(srcNode,p1.srcAddr)
+ this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(src.getZ3Node(), nctx.pf.get("src").apply(p1)));
+
+ // Constraint4 p1.origin == srcNode
+ this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p1), src.getZ3Node()));
+
+ // Constraint5 nodeHasAddr(destNode,p1.destAddr)
+ this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(dest.getZ3Node(), nctx.pf.get("dest").apply(p1)));
+
+ //NON sembrano necessari
+ // this.solver.add(z3.Or(this.ctx.nodeHasAddr(src.getZ3Node(), this.ctx.packet.src(p0)),\
+ // this.ctx.nodeHasAddr(n_0, this.ctx.packet.src(p0)),\
+ // this.ctx.nodeHasAddr(n_1, this.ctx.packet.src(p0))))
+ //this.solver.add(this.ctx.packet.dest(p1) == this.ctx.packet.dest(p0))
+
+ // Constraint6 p1.origin == p0.origin
+ this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p1),nctx.pf.get("origin").apply(p0)));
+
+ // Constraint7 nodeHasAddr(destNode, p0.destAddr)
+ this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(dest.getZ3Node(), nctx.pf.get("dest").apply(p0)));
+
+ result = this.solver.check();
+ model = null;
+ assertions = this.solver.getAssertions();
+ if (result == Status.SATISFIABLE){
+ model = this.solver.getModel();
+ }
+ this.solver.pop();
+ return new IsolationResult(ctx,result, p0, n_0, t_1, t_0, nctx, assertions, model);
+ }
+
+
+
+ public IsolationResult CheckIsolationFlowProperty (NetworkObject src, NetworkObject dest){
+ assert(net.elements.contains(src));
+ assert(net.elements.contains(dest));
+ solver.push ();
+ addConstraints();
+
+ Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+ Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+ Expr n_1 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+ Expr n_2 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+
+ IntExpr t_0 = ctx.mkIntConst("check_isolation_t0_"+src.getZ3Node()+"_"+dest.getZ3Node());
+ IntExpr t_1 = ctx.mkIntConst("check_isolation_t1_"+src.getZ3Node()+"_"+dest.getZ3Node());
+ IntExpr t_2 = ctx.mkIntConst("check_isolation_t2_"+src.getZ3Node()+"_"+dest.getZ3Node());
+
+ // Constraint1 recv(n_0,destNode,p,t_0)
+ this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t_0));
+
+ // Constraint2 send(srcNode,n_1,p1,t_1)
+ this.solver.add((BoolExpr)nctx.send.apply(src.getZ3Node(), n_1, p, t_1));
+
+ // Constraint3 nodeHasAddr(srcNode,p.srcAddr)
+ this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(src.getZ3Node(), nctx.pf.get("src").apply(p)));
+
+ // Constraint4 p.origin == srcNode
+ this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node()));
+
+
+ Expr p_2 = ctx.mkConst("check_isolation_p_flow_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+
+ // Constraint5 there does not exist p_2, n_2, t_2 :
+ // send(destNode,n_2,p_2,t_2) &&
+ // p_2.srcAddr == p. destAddr &&
+ // p_2.srcPort == p.destPort &&
+ // p_2.destPort == p.srcPort &&
+ // p_2.destt == p.src &&
+ // t_2 < t_0
+ this.solver.add(ctx.mkNot(ctx.mkExists(new Expr[]{p_2,n_2,t_2},
+ ctx.mkAnd(
+ (BoolExpr)nctx.send.apply(dest.getZ3Node(), n_2, p_2, t_2),
+ ctx.mkEq(nctx.pf.get("src").apply(p_2), nctx.pf.get("dest").apply(p)),
+ ctx.mkEq(nctx.pf.get("src_port").apply(p_2), nctx.pf.get("dest_port").apply(p)),
+ ctx.mkEq(nctx.pf.get("dest_port").apply(p_2), nctx.pf.get("src_port").apply(p)),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_2), nctx.pf.get("src").apply(p)),
+ ctx.mkLt(t_2,t_0)),1,null,null,null,null)));
+
+
+ result = this.solver.check();
+ model = null;
+ assertions = this.solver.getAssertions();
+ if (result == Status.SATISFIABLE){
+ model = this.solver.getModel();
+ }
+ this.solver.pop();
+ return new IsolationResult(ctx,result, p, n_0, t_1, t_0, nctx, assertions, model);
+ }
+
+
+
+ public IsolationResult CheckNodeTraversalProperty (NetworkObject src, NetworkObject dest, NetworkObject node){
+ assert(net.elements.contains(src));
+ assert(net.elements.contains(dest));
+ solver.push ();
+ addConstraints();
+
+ Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+
+ Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+ Expr n_1 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+ Expr n_2 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+
+ IntExpr t_0 = ctx.mkIntConst("check_isolation_t0_"+src.getZ3Node()+"_"+dest.getZ3Node());
+ IntExpr t_1 = ctx.mkIntConst("check_isolation_t1_"+src.getZ3Node()+"_"+dest.getZ3Node());
+ IntExpr t_2 = ctx.mkIntConst("check_isolation_t2_"+src.getZ3Node()+"_"+dest.getZ3Node());
+
+ // Constraint1 recv(n_0,destNode,p,t_0)
+ this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t_0));
+
+ // Constraint2 send(srcNode,n_1,p1,t_1)
+ this.solver.add((BoolExpr)nctx.send.apply(src.getZ3Node(), n_1, p, t_1));
+
+ // Constraint3 nodeHasAddr(srcNode,p.srcAddr)
+ this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(src.getZ3Node(), nctx.pf.get("src").apply(p)));
+
+ // Constraint4 p.origin == srcNode
+ this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node()));
+
+
+ // Constraint5 there does not exist n_2, t_2 : recv(n_2,node,p,t_2) && t_2 < t_0
+ this.solver.add(ctx.mkNot(ctx.mkExists(new Expr[]{n_2,t_2},
+ ctx.mkAnd(
+ (BoolExpr)nctx.recv.apply(n_2, node.getZ3Node(), p, t_2),
+ ctx.mkLt(t_2,t_0)),1,null,null,null,null)));
+
+ // Constraint 6 there does not exist n_2, t_2 : send(node,n_2,p,t_2) && t_2 < t_0
+ this.solver.add(ctx.mkNot(ctx.mkExists(new Expr[]{n_2,t_2},
+ ctx.mkAnd(
+ (BoolExpr)nctx.send.apply(node.getZ3Node(), n_2, p, t_2),
+ ctx.mkLt(t_2,t_0)),1,null,null,null,null)));
+
+
+ result = this.solver.check();
+ model = null;
+ assertions = this.solver.getAssertions();
+ if (result == Status.SATISFIABLE){
+ model = this.solver.getModel();
+ }
+ this.solver.pop();
+ return new IsolationResult(ctx,result, p, n_0, t_1, t_0, nctx, assertions, model);
+
+ }
+
+ public IsolationResult CheckLinkTraversalProperty (NetworkObject src, NetworkObject dest, NetworkObject le0, NetworkObject le1){
+ assert(net.elements.contains(src));
+ assert(net.elements.contains(dest));
+ solver.push ();
+ addConstraints();
+
+ Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+
+ Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+ Expr n_1 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+
+ IntExpr t_0 = ctx.mkIntConst("check_isolation_t0_"+src.getZ3Node()+"_"+dest.getZ3Node());
+ IntExpr t_1 = ctx.mkIntConst("check_isolation_t1_"+src.getZ3Node()+"_"+dest.getZ3Node());
+ IntExpr t_2 = ctx.mkIntConst("check_isolation_t2_"+src.getZ3Node()+"_"+dest.getZ3Node());
+
+ // Constraint1 recv(n_0,destNode,p,t_0)
+ this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t_0));
+
+ // Constraint2 send(srcNode,n_1,p1,t_1)
+ this.solver.add((BoolExpr)nctx.send.apply(src.getZ3Node(), n_1, p, t_1));
+
+ // Constraint3 nodeHasAddr(srcNode,p.srcAddr)
+ this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(src.getZ3Node(), nctx.pf.get("src").apply(p)));
+
+ // Constraint4 p.origin == srcNode
+ this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node()));
+
+ // Constraint5 ∃ t_1, t_2 :
+ // send(linkNode0,linkNode1,p,t_1) &&
+ // recv(linkNode0,linkNode1,p,t_2) &&
+ // t_1 < t_0 &&
+ // t_2 < t_0
+ this.solver.add(ctx.mkExists(new Expr[]{t_1,t_2},
+ ctx.mkAnd(
+ (BoolExpr)nctx.send.apply(le0.getZ3Node(), le1.getZ3Node(), p, t_1),
+ (BoolExpr)nctx.recv.apply(le0.getZ3Node(), le1.getZ3Node(), p, t_2),
+ ctx.mkLt(t_1,t_0),
+ ctx.mkLt(t_2,t_0)),1,null,null,null,null));
+
+
+ result = this.solver.check();
+ model = null;
+ assertions = this.solver.getAssertions();
+ if (result == Status.SATISFIABLE){
+ model = this.solver.getModel();
+ }
+ this.solver.pop();
+ return new IsolationResult(ctx,result, p, n_0, t_1, t_0, nctx, assertions, model);
+
+ }
+
+ public Result CheckDataIsolationPropertyCore (NetworkObject src, NetworkObject dest){
+ assert(net.elements.contains(src));
+ assert(net.elements.contains(dest));
+ List<BoolExpr> constr = this.getConstraints();
+ Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+
+ Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+ IntExpr t = ctx.mkIntConst("check_isolation_t_"+src.getZ3Node()+"_"+dest.getZ3Node());
+
+ // Constraint1 recv(n_0,destNode,p,t)
+ constr.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t));
+
+ // Constraint2 p.origin == srcNode
+ this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node()));
+
+ this.solver.push();
+
+ // Constraint3 for each constraint( n -> constraint)
+ ArrayList<BoolExpr> names =new ArrayList<BoolExpr>();
+ for(BoolExpr con : constr){
+ BoolExpr n = ctx.mkBoolConst(""+con);
+ names.add(n);
+ this.solver.add(ctx.mkImplies(n, con));
+ }
+
+ BoolExpr[] nam = new BoolExpr[names.size()];
+ result = this.solver.check(names.toArray(nam));
+ Result ret =null;
+
+ if (result == Status.SATISFIABLE){
+ System.out.println("SAT");
+ ret = new Result(ctx,this.solver.getModel());
+ }else if(result == Status.UNSATISFIABLE){
+ System.out.println("unsat");
+ ret = new Result(ctx,this.solver.getUnsatCore());
+ }
+ this.solver.pop();
+ return ret;
+ }
+
+ public DataIsolationResult CheckDataIsolationProperty(NetworkObject src, NetworkObject dest){
+ assert(net.elements.contains(src));
+ assert(net.elements.contains(dest));
+ solver.push ();
+ addConstraints();
+
+ Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet);
+
+ Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node);
+ IntExpr t = ctx.mkIntConst("check_isolation_t_"+src.getZ3Node()+"_"+dest.getZ3Node());
+
+ // Constraint1 recv(n_0,destNode,p,t)
+ this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t));
+
+ // Constraint2 p.origin == srcNode
+ this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node()));
+
+ result = this.solver.check();
+ model = null;
+ assertions = this.solver.getAssertions();
+ if (result == Status.SATISFIABLE){
+ model = this.solver.getModel();
+ }
+ this.solver.pop();
+ return new DataIsolationResult(ctx,result, p, n_0, t, nctx, assertions, model);
+ }
+
+
+
+
+ public void addConstraints(){
+ nctx.addConstraints(solver);
+ net.addConstraints(solver);
+ for (NetworkObject el : net.elements)
+ el.addConstraints(solver);
+ }
+
+
+ public List<BoolExpr> getConstraints(){
+ Solver l = ctx.mkSolver();
+ nctx.addConstraints(l);
+ net.addConstraints(l);
+ for (NetworkObject el : net.elements)
+ el.addConstraints(l);
+ return Arrays.asList(l.getAssertions());
+ }
+}
diff --git a/verigraph/service/src/mcnet/components/Core.java b/verigraph/service/src/mcnet/components/Core.java
new file mode 100644
index 0000000..c72b9e3
--- /dev/null
+++ b/verigraph/service/src/mcnet/components/Core.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.Solver;
+
+/**Core component for everything that matters
+ *
+ */
+public abstract class Core{
+
+ final int MAX_PORT = 512;
+
+ /**
+ * Base class for all objects in the modeling framework
+ * @param ctx
+ * @param args
+ */
+ public Core(Context ctx, Object[]... args){ // Object[]... -> The nearest way to implement variable length argument lists
+ //in Java, in the most generic way.
+ init(ctx,args);
+ }
+ /**
+ * Override _init for any constructor initialization. Avoids having to explicitly call super.__init__ every Time.class
+ * @param ctx
+ * @param args
+ */
+ abstract protected void init(Context ctx,Object[]... args);
+
+ /**
+ * Add constraints to solver
+ * @param solver
+ */
+ abstract protected void addConstraints(Solver solver);
+}
+
+
diff --git a/verigraph/service/src/mcnet/components/DataIsolationResult.java b/verigraph/service/src/mcnet/components/DataIsolationResult.java
new file mode 100644
index 0000000..b90a47f
--- /dev/null
+++ b/verigraph/service/src/mcnet/components/DataIsolationResult.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.Model;
+import com.microsoft.z3.Status;
+
+
+/**Data structure for the response to a check request for data isolation property
+ *
+ */
+public class DataIsolationResult {
+
+ Context ctx;
+ public NetContext nctx;
+ public Status result;
+ public Model model;
+ public Expr violating_packet,last_hop,last_time,t_1;
+ public BoolExpr [] assertions;
+
+ public DataIsolationResult(Context ctx,Status result, Expr violating_packet, Expr last_hop, Expr last_time, NetContext nctx, BoolExpr[] assertions, Model model){
+ this.ctx = ctx;
+ this.result = result;
+ this.violating_packet = violating_packet;
+ this.last_hop = last_hop;
+ this.model = model;
+ this.last_time = last_time;
+ this.assertions = assertions;
+ }
+}
+
diff --git a/verigraph/service/src/mcnet/components/IsolationResult.java b/verigraph/service/src/mcnet/components/IsolationResult.java
new file mode 100644
index 0000000..1ecaccc
--- /dev/null
+++ b/verigraph/service/src/mcnet/components/IsolationResult.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.Model;
+import com.microsoft.z3.Status;
+
+/**
+ * Data structure for the response to check requests for isolation properties
+ *
+ */
+public class IsolationResult {
+
+ Context ctx;
+ public NetContext nctx;
+ public Status result;
+ public Model model;
+ public Expr violating_packet,last_hop,last_send_time,last_recv_time,t_1;
+ public BoolExpr [] assertions;
+
+ public IsolationResult(Context ctx,Status result, Expr violating_packet, Expr last_hop, Expr last_send_time, Expr last_recv_time,NetContext nctx, BoolExpr[] assertions, Model model){
+ this.ctx = ctx;
+ this.result = result;
+ this.violating_packet = violating_packet;
+ this.last_hop = last_hop;
+ this.model = model;
+ this.last_send_time = last_send_time;
+ this.last_recv_time = last_recv_time;
+ this.assertions = assertions;
+ }
+}
+
diff --git a/verigraph/service/src/mcnet/components/NetContext.java b/verigraph/service/src/mcnet/components/NetContext.java
new file mode 100644
index 0000000..ece31c5
--- /dev/null
+++ b/verigraph/service/src/mcnet/components/NetContext.java
@@ -0,0 +1,340 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Constructor;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.DatatypeSort;
+import com.microsoft.z3.EnumSort;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+import com.microsoft.z3.Sort;
+
+import mcnet.netobjs.DumbNode;
+
+/**
+ * Basic fields and other things required for model checking.
+ *
+ */
+public class NetContext extends Core{
+
+
+ List<BoolExpr> constraints;
+ List<Core> policies;
+
+ public HashMap<String,NetworkObject> nm; //list of nodes, callable by node name
+ public HashMap<String,DatatypeExpr> am; // list of addresses, callable by address name
+ public HashMap<String,FuncDecl> pf;
+ Context ctx;
+ public EnumSort node,address;
+ public FuncDecl src_port,dest_port,nodeHasAddr,addrToNode,send,recv;
+ public DatatypeSort packet;
+
+ /* Constants definition
+ - used in the packet proto field */
+ public final int HTTP_REQUEST = 1;
+ public final int HTTP_RESPONSE = 2;
+ public final int POP3_REQUEST = 3;
+ public final int POP3_RESPONSE = 4;
+
+ /**
+ * Context for all of the rest that follows. Every network needs one of these
+ * @param ctx
+ * @param args
+ */
+ public NetContext(Context ctx,Object[]... args ){
+ super(ctx,args);
+
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ nm = new HashMap<String,NetworkObject>(); //list of nodes, callable by node name
+ am = new HashMap<String,DatatypeExpr>(); // list of addresses, callable by address name
+ pf= new HashMap<String,FuncDecl>() ;
+
+ mkTypes((String[])args[0],(String[])args[1]);
+
+ constraints = new ArrayList<BoolExpr>();
+ policies = new ArrayList<Core>();
+
+ baseCondition();
+ }
+
+ /**
+ * A policy is a collection of shared algorithms or functions used by multiple components
+ * (for instance compression or DPI policies etc).
+ * @param policy
+ */
+ public void AddPolicy (NetworkObject policy){
+ policies.add(policy);
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ for (Core policy : policies){
+ policy.addConstraints(solver);
+ }
+ }
+
+ private void mkTypes (String[] nodes, String[] addresses){
+ //Nodes in a network
+ node = ctx.mkEnumSort("Node", nodes);
+ for(int i=0;i<node.getConsts().length;i++){
+ DatatypeExpr fd = (DatatypeExpr)node.getConst(i);
+ DumbNode dn =new DumbNode(ctx,new Object[]{fd});
+ nm.put(fd.toString(),dn);
+ }
+
+ //Addresses for this network
+ String[] new_addr = new String[addresses.length+1];
+ for(int k=0;k<addresses.length;k++)
+ new_addr[k] = addresses[k];
+
+ new_addr[new_addr.length-1] = "null";
+ address = ctx.mkEnumSort("Address", new_addr);
+ for(int i=0;i<address.getConsts().length;i++){
+ DatatypeExpr fd = (DatatypeExpr)address.getConst(i);
+ am.put(fd.toString(),fd);
+ }
+
+ // Type for packets, contains (some of these are currently represented as relations):
+ // - src: Source address
+ // - dest: Destination address
+ // - origin: Node where the data originated. (Node)
+ // - body: Packet contents. (Integer)
+ // - seq: Sequence number for packets. (Integer)
+ // - options: A representation for IP options. (Integer)
+
+ String[] fieldNames = new String[]{
+ "src","dest","inner_src","inner_dest","origin","orig_body","body","seq","proto","emailFrom","url","options","encrypted"};
+ Sort[] srt = new Sort[]{
+ address,address,address,address,node,ctx.mkIntSort(),ctx.mkIntSort(),ctx.mkIntSort(),
+ ctx.mkIntSort(),ctx.mkIntSort(),ctx.mkIntSort(),ctx.mkIntSort(),ctx.mkBoolSort()};
+ Constructor packetcon = ctx.mkConstructor("packet", "is_packet", fieldNames, srt, null);
+ packet = ctx.mkDatatypeSort("packet", new Constructor[] {packetcon});
+
+ for(int i=0;i<fieldNames.length;i++){
+ pf.put(fieldNames[i], packet.getAccessors()[0][i]); // pf to get packet's function declarations by name
+ }
+
+ src_port = ctx.mkFuncDecl("sport", packet, ctx.mkIntSort());
+ dest_port = ctx.mkFuncDecl("dport", packet, ctx.mkIntSort());
+
+ // Some commonly used relations
+
+ // nodeHasAddr: node -> address -> boolean
+ nodeHasAddr = ctx.mkFuncDecl("nodeHasAddr", new Sort[]{node, address},ctx.mkBoolSort());
+
+ // addrToNode: address -> node
+ addrToNode = ctx.mkFuncDecl("addrToNode", address, node);
+
+ // Send and receive both have the form:
+ // source-> destination -> packet-> int-> bool
+
+ // send: node -> node -> packet-> int-> bool
+ send = ctx.mkFuncDecl("send", new Sort[]{ node, node, packet, ctx.mkIntSort()},ctx.mkBoolSort());
+
+ // recv: node -> node -> packet-> int-> bool
+ recv = ctx.mkFuncDecl("recv", new Sort[]{ node, node, packet, ctx.mkIntSort()},ctx.mkBoolSort());
+
+ }
+
+ /**
+ * Set up base conditions for the network
+ */
+ private void baseCondition(){
+ // Basic constraints for the overall model
+ Expr n_0 = ctx.mkConst("ctx_base_n_0", node);
+ Expr n_1 = ctx.mkConst("ctx_base_n_1", node);
+ Expr n_2 = ctx.mkConst("ctx_base_n_2", node);
+ Expr p_0 = ctx.mkConst("ctx_base_p_0", packet);
+ Expr p_1 = ctx.mkConst("ctx_base_p_1", packet);
+ IntExpr t_0 = ctx.mkIntConst("ctx_base_t_0");
+ IntExpr t_1 = ctx.mkIntConst("ctx_base_t_1");
+
+ // Constraint1 send(n_0, n_1, p_0, t_0) -> n_0 != n_1
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies((BoolExpr)send.apply(n_0, n_1, p_0, t_0),ctx.mkNot(ctx.mkEq( n_0, n_1))),1,null,null,null,null));
+
+ // Constraint2 recv(n_0, n_1, p_0, t_0) -> n_0 != n_1
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),ctx.mkNot(ctx.mkEq( n_0, n_1))),1,null,null,null,null));
+
+ // Constraint3 send(n_0, n_1, p_0, t_0) -> p_0.src != p_0.dest
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies((BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+ ctx.mkNot(ctx.mkEq( pf.get("src").apply(p_0), pf.get("dest").apply(p_0)))),1,null,null,null,null));
+
+ // Constraint4 recv(n_0, n_1, p_0, t_0) -> p_0.src != p_0.dest
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+ ctx.mkNot(ctx.mkEq(pf.get("src").apply(p_0),pf.get("dest").apply(p_0)))),1,null,null,null,null));
+
+ // Constraint5 recv(n_0, n_1, p, t_0) -> send(n_0, n_1, p, t_1) && t_1 < t_0
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+ ctx.mkExists(new Expr[]{t_1},
+ ctx.mkAnd((BoolExpr)send.apply(n_0, n_1, p_0, t_1),
+ ctx.mkLt(t_1, t_0)),1,null,null,null,null)),1,null,null,null,null));
+
+ // Constraint6 send(n_0, n_1, p, t_0) -> p.src_port > 0 && p.dest_port < MAX_PORT
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies((BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+ ctx.mkAnd( ctx.mkGe((IntExpr)src_port.apply(p_0),(IntExpr)ctx.mkInt(0)),
+ ctx.mkLt((IntExpr)src_port.apply(p_0),(IntExpr) ctx.mkInt(MAX_PORT)))),1,null,null,null,null));
+
+ // Constraint7 recv(n_0, n_1, p, t_0) -> p.src_port > 0 && p.dest_port < MAX_PORT
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+ ctx.mkAnd( ctx.mkGe((IntExpr)dest_port.apply(p_0),(IntExpr)ctx.mkInt(0)),
+ ctx.mkLt((IntExpr)dest_port.apply(p_0),(IntExpr) ctx.mkInt(MAX_PORT)))),1,null,null,null,null));
+
+ // Constraint8 recv(n_0, n_1, p_0, t_0) -> t_0 > 0
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+ ctx.mkGt(t_0,ctx.mkInt(0))),1,null,null,null,null));
+
+ // Constraint9 send(n_0, n_1, p_0, t_0) -> t_0 > 0
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies((BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+ ctx.mkGt(t_0,ctx.mkInt(0))),1,null,null,null,null));
+
+ // Extra constriants for supporting the VPN gateway
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies(
+ ctx.mkAnd((BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+ ctx.mkNot(ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.am.get("null")))),
+ ctx.mkNot(ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0)))),1,null,null,null,null));
+
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies(
+ ctx.mkAnd((BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+ ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.am.get("null"))),
+ ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0))),1,null,null,null,null));
+
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies(
+ ctx.mkAnd((BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+ ctx.mkEq(this.pf.get("inner_dest").apply(p_0), this.am.get("null"))),
+ ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0))),1,null,null,null,null));
+
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies(
+ ctx.mkAnd((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+ ctx.mkNot(ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.am.get("null")))),
+ ctx.mkNot(ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0)))),1,null,null,null,null));
+
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies(
+ ctx.mkAnd((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+ ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.am.get("null"))),
+ ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0))),1,null,null,null,null));
+
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0},
+ ctx.mkImplies(
+ ctx.mkAnd((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),
+ ctx.mkEq(this.pf.get("inner_dest").apply(p_0), this.am.get("null"))),
+ ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0))),1,null,null,null,null));
+
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0, n_2, p_1, t_1},
+ ctx.mkImplies(
+ ctx.mkAnd(
+ ctx.mkLt(t_1, t_0),
+ (BoolExpr)send.apply(n_0, n_1, p_0, t_0),
+ (BoolExpr)this.pf.get("encrypted").apply(p_1),
+ (BoolExpr)recv.apply(n_2, n_0, p_1, t_1),
+ (BoolExpr)this.pf.get("encrypted").apply(p_0)),
+ ctx.mkAnd(
+ ctx.mkEq(this.pf.get("inner_src").apply(p_1), this.pf.get("inner_src").apply(p_0)),
+ ctx.mkEq(this.pf.get("inner_dest").apply(p_1), this.pf.get("inner_dest").apply(p_0)),
+ ctx.mkEq(this.pf.get("origin").apply(p_1), this.pf.get("origin").apply(p_0)),
+ ctx.mkEq(this.pf.get("orig_body").apply(p_1), this.pf.get("orig_body").apply(p_0)),
+ ctx.mkEq(this.pf.get("body").apply(p_1), this.pf.get("body").apply(p_0)),
+ ctx.mkEq(this.pf.get("seq").apply(p_1), this.pf.get("seq").apply(p_0)),
+ ctx.mkEq(this.pf.get("proto").apply(p_1), this.pf.get("proto").apply(p_0)),
+ ctx.mkEq(this.pf.get("emailFrom").apply(p_1), this.pf.get("emailFrom").apply(p_0)),
+ ctx.mkEq(this.pf.get("url").apply(p_1), this.pf.get("url").apply(p_0)),
+ ctx.mkEq(this.pf.get("options").apply(p_1), this.pf.get("options").apply(p_0)))),1,null,null,null,null)
+ );
+ }
+
+ /**
+ * Two packets have equal headers
+ * @param p1
+ * @param p2
+ * @return
+ */
+ public BoolExpr PacketsHeadersEqual(Expr p1, Expr p2){
+ return ctx.mkAnd(new BoolExpr[]{
+ ctx.mkEq(pf.get("src").apply(p1), pf.get("src").apply(p2)),
+ ctx.mkEq(pf.get("dest").apply(p1), pf.get("dest").apply(p2)),
+ ctx.mkEq(pf.get("origin").apply(p1), pf.get("origin").apply(p2)),
+ ctx.mkEq(pf.get("seq").apply(p1), pf.get("seq").apply(p2)),
+ ctx.mkEq(src_port.apply(p1), src_port.apply(p2)),
+ ctx.mkEq(dest_port.apply(p1), dest_port.apply(p2)),
+ ctx.mkEq(pf.get("options").apply(p1), pf.get("options").apply(p2))});
+ }
+
+ /**
+ * Two packets have equal bodies
+ * @param p1
+ * @param p2
+ * @return
+ */
+ public BoolExpr PacketContentEqual(Expr p1, Expr p2){
+ return ctx.mkEq(pf.get("body").apply(p1), pf.get("body").apply(p2));
+ }
+
+
+ /* seems to be useless
+ *
+ public Function failurePredicate (NetContext context)
+ {
+ return (NetworkObject node) -> ctx.mkNot(context.failed (node.z3Node));
+
+ }*/
+
+ public BoolExpr destAddrPredicate (Expr p, DatatypeExpr address){
+ return ctx.mkEq(pf.get("dest").apply(p),address);
+ }
+
+ public BoolExpr srcAddrPredicate (Expr p, DatatypeExpr address){
+ return ctx.mkEq(pf.get("src").apply(p),address);
+ }
+
+} \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/components/Network.java b/verigraph/service/src/mcnet/components/Network.java
new file mode 100644
index 0000000..c04f771
--- /dev/null
+++ b/verigraph/service/src/mcnet/components/Network.java
@@ -0,0 +1,296 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+import com.microsoft.z3.Z3Exception;
+
+/**Model for a network, encompasses routing and wiring
+ *
+ */
+public class Network extends Core{
+
+ Context ctx;
+ NetContext nctx;
+ List<BoolExpr> constraints;
+ List<NetworkObject> elements;
+
+
+
+ public Network(Context ctx,Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ this.nctx = (NetContext) args[0][0];
+ constraints = new ArrayList<BoolExpr>();
+ elements = new ArrayList<NetworkObject>();
+
+ }
+
+ /**Composes the network linking the configured network objects
+ *
+ * @param elements
+ */
+ public void attach (NetworkObject ... elements){
+ for(NetworkObject el : elements)
+ this.elements.add(el);
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ try {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ } catch (Z3Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Specify host to address mapping.
+ * Handles the case in which we have more than one address for a node
+ * @param addrmap
+ */
+ public void setAddressMappings(ArrayList<Tuple<NetworkObject,ArrayList<DatatypeExpr>>> addrmap){
+ // Set address mapping for nodes.
+ for (Tuple<NetworkObject,ArrayList<DatatypeExpr>> entry : addrmap) {
+ NetworkObject node=entry._1;
+ List<DatatypeExpr> addr=entry._2;
+ Expr a_0 = ctx.mkConst(node+"_address_mapping_a_0",nctx.address);
+ ArrayList<BoolExpr> or_clause = new ArrayList<BoolExpr>();
+
+ // Constraint 1 addrToNode(foreach ad in addr) = node
+ for (DatatypeExpr ad : addr){
+ constraints.add(ctx.mkEq(nctx.addrToNode.apply(ad), node.getZ3Node()));
+ or_clause.add(ctx.mkEq(a_0,ad));
+ }
+ BoolExpr[] orClause = new BoolExpr[or_clause.size()];
+
+ // Constraint 2 nodeHasAddr(node, a_0) == Or(foreach ad in addr (a_0 == ad))
+ // Note we need the iff here to make sure that we set nodeHasAddr to false
+ // for other addresses.
+ constraints.add(ctx.mkForall(new Expr[]{a_0},
+ ctx.mkEq(ctx.mkOr(or_clause.toArray(orClause)), nctx.nodeHasAddr.apply(node.getZ3Node(), a_0)),1,null,null,null,null));
+ }
+ }
+
+
+
+ /**
+ * Don't forward packets addressed to node
+ * @param node
+ */
+ public void saneSend(NetworkObject node){
+ Expr n_0 = ctx.mkConst(node+"_saneSend_n_0", nctx.node);
+ Expr p_0 = ctx.mkConst(node+"_saneSend_p_0", nctx.packet);
+ IntExpr t_0 = ctx.mkIntConst(node+"_saneSend_t_0");
+ // Constant: node
+ //Constraint send(node, n_0, p, t_0) -> !nodeHasAddr(node, p.dest)
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(node.getZ3Node(),n_0, p_0, t_0),
+ ctx.mkNot((BoolExpr)nctx.nodeHasAddr.apply( node.getZ3Node(),
+ nctx.pf.get("dest").apply(p_0)))),1,null,null,null,null));
+ }
+
+ /**
+ * Node sends all traffic through gateway
+ * @param node
+ * @param gateway
+ */
+ public void setGateway (NetworkObject node, NetworkObject gateway){
+ // SetGateway(self, node, gateway): All packets from node are sent through gateway
+ Expr n_0 = ctx.mkConst(node+"_gateway_n_0", nctx.node);
+ Expr p_0 = ctx.mkConst(node+"_gateway_p_0", nctx.packet);
+ IntExpr t_0 = ctx.mkIntConst(node+"_gateway_t_0");
+
+ //Constraint send(node, n_0, p_0, t_0) -> n_0 = gateway
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies(
+ (BoolExpr)nctx.send.apply(node.getZ3Node(), n_0, p_0, t_0),
+ ctx.mkEq(n_0,gateway.getZ3Node())),1,null,null,null,null));
+
+// constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+// ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0, node.getZ3Node(), p_0, t_0),
+// ctx.mkEq(n_0,gateway.getZ3Node())),1,null,null,null,null));
+ }
+
+ /**
+ * Assigns a specific routing table to a network object. Routing entries in the form: address -> node
+ * @param node
+ * @param routing_table
+ */
+ public void routingTable (NetworkObject node,ArrayList<Tuple<DatatypeExpr,NetworkObject>> routing_table){
+ compositionPolicy(node,routing_table);
+ }
+
+ /**
+ * Composition policies steer packets between middleboxes.
+ * @param node
+ * @param policy
+ */
+ public void compositionPolicy (NetworkObject node,ArrayList<Tuple<DatatypeExpr,NetworkObject>> policy){
+ //Policy is of the form predicate -> node
+ Expr p_0 = ctx.mkConst(node+"_composition_p_0", nctx.packet);
+ Expr n_0 = ctx.mkConst(node+"_composition_n_0", nctx.node);
+ Expr t_0 = ctx.mkIntConst(node+"_composition_t_0");
+
+ HashMap<String,ArrayList<BoolExpr>> collected = new HashMap<String,ArrayList<BoolExpr>>();
+ HashMap<String,NetworkObject> node_dict = new HashMap<String,NetworkObject>();
+ BoolExpr predicates;
+ for(int y=0;y<policy.size();y++){
+ Tuple<DatatypeExpr,NetworkObject> tp = policy.get(y);
+ if(collected.containsKey(""+tp._2)) collected.get(""+tp._2).add(nctx.destAddrPredicate(p_0,tp._1));
+ else{
+ ArrayList<BoolExpr> alb = new ArrayList<BoolExpr>();
+ alb.add(nctx.destAddrPredicate(p_0,tp._1));
+ collected.put(""+tp._2,alb);
+ }
+ node_dict.put(""+tp._2, tp._2);
+ }
+
+ //Constraint foreach rtAddr,rtNode in rt( send(node, n_0, p_0, t_0) &&
+ // Or(foreach rtAddr in rt destAddrPredicate(p_0,rtAddr)) -> n_0 == rtNode )
+ for (Map.Entry<String,ArrayList<BoolExpr>> entry : collected.entrySet()) {
+ BoolExpr[] pred = new BoolExpr[entry.getValue().size()];
+ predicates = ctx.mkOr(entry.getValue().toArray(pred));
+
+ constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(node.getZ3Node(), n_0, p_0, t_0), predicates),
+ ctx.mkEq(n_0, node_dict.get(entry.getKey()).getZ3Node())),1,null,null,null,null));
+ }
+ }
+
+ /**
+ * Routing entries are in the form: address -> node. Also allows packet to be sent to another box for further processing
+ * @param node
+ * @param routing_table
+ * @param shunt_node
+ */
+ public void routingTableShunt (NetworkObject node,ArrayList<Tuple<DatatypeExpr,NetworkObject>> routing_table,NetworkObject shunt_node){
+ compositionPolicyShunt(node,routing_table,shunt_node);
+ }
+
+ /**
+ * Composition policies steer packets between middleboxes.Policy is in the form: predicate -> node
+ * @param node
+ * @param routing_table
+ * @param shunt_node
+ */
+ public void compositionPolicyShunt (NetworkObject node,ArrayList<Tuple<DatatypeExpr,NetworkObject>> routing_table,NetworkObject shunt_node){
+ Expr p_0 = ctx.mkConst(node+"_composition_p_0", nctx.packet);
+ Expr n_0 = ctx.mkConst(node+"_composition_n_0", nctx.node);
+ Expr t_0 = ctx.mkIntConst(node+"_composition_t_0");
+
+ HashMap<String,ArrayList<BoolExpr>> collected = new HashMap<String,ArrayList<BoolExpr>>();
+ HashMap<String,NetworkObject> node_dict = new HashMap<String,NetworkObject>();
+ BoolExpr predicates;
+ for(int y=0;y<routing_table.size();y++){
+ Tuple<DatatypeExpr,NetworkObject> tp = routing_table.get(y);
+ if(collected.containsKey(""+tp._2)) collected.get(""+tp._2).add(nctx.destAddrPredicate(p_0,tp._1));
+ else{
+ ArrayList<BoolExpr> alb = new ArrayList<BoolExpr>();
+ alb.add(nctx.destAddrPredicate(p_0,tp._1));
+ collected.put(""+tp._2,alb);
+ }
+ node_dict.put(""+tp._2, tp._2);
+ }
+
+ //Constraint foreach rtAddr,rtNode in rt( send(node, n_0, p_0, t_0) &&
+ // Or(foreach rtAddr in rt destAddrPredicate(p_0,rtAddr)) -> n_0 == rtNode )
+ for (Map.Entry<String,ArrayList<BoolExpr>> entry : collected.entrySet()) {
+ BoolExpr[] pred = new BoolExpr[entry.getValue().size()];
+ predicates = ctx.mkOr(entry.getValue().toArray(pred));
+
+ constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(node.getZ3Node(), n_0, p_0, t_0), predicates),
+ ctx.mkOr(ctx.mkEq(n_0, node_dict.get(entry.getKey()).getZ3Node()),ctx.mkEq(n_0, shunt_node.getZ3Node()))),1,null,null,null,null));
+ }
+
+ }
+
+// public void SimpleIsolation (NetworkObject node, ArrayList<DatatypeExpr> addresses){
+// Expr p = ctx.mkConst(node+"_s_p", nctx.packet);
+// Expr n = ctx.mkConst(node+"_s_n", nctx.node);
+// IntExpr t = ctx.mkInt(node+"_s_t");
+//
+// BoolExpr[] a_pred= new BoolExpr[addresses.size()];
+// for(int y=0;y<addresses.size();y++){
+// DatatypeExpr de = addresses.get(y);
+// a_pred[y] = ctx.mkOr(ctx.mkEq(nctx.pf.get("src").apply(p), de),ctx.mkEq(nctx.pf.get("dest").apply(p), de));
+// }
+//
+// constraints.add(
+// ctx.mkForall(new Expr[]{p, n, t},
+// ctx.mkImplies((BoolExpr)nctx.recv.apply(n, node.getZ3Node(), p, t),
+// ctx.mkOr(a_pred)),1,null,null,null,null));
+// constraints.add(
+// ctx.mkForall(new Expr[]{p, n, t},
+// ctx.mkImplies((BoolExpr)nctx.send.apply(node.getZ3Node(), n, p, t),
+// ctx.mkOr(a_pred)),1,null,null,null,null));
+// }
+
+
+ /**
+ * Set isolation constraints on a node.
+ * Doesn't need to be set but useful when interfering policies are in play.
+ * @param node
+ * @param adjacencies
+ *
+ */
+ public void SetIsolationConstraint ( NetworkObject node, ArrayList<NetworkObject> adjacencies){
+
+ Expr n_0 = ctx.mkConst(node+"_isolation_n_0", nctx.node);
+ Expr p_0 = ctx.mkConst(node+"_isolation_p_0", nctx.packet);
+ IntExpr t_0 = ctx.mkInt(node+"_isolation_t_0");
+
+ BoolExpr[] adj = new BoolExpr[adjacencies.size()];
+ for(int y=0;y<adjacencies.size();y++){
+ NetworkObject no = adjacencies.get(y);
+ adj[y] = ctx.mkEq(n_0,no.getZ3Node());
+ }
+ BoolExpr clause = ctx.mkOr(adj);
+
+ constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(node.getZ3Node(), n_0, p_0, t_0),
+ clause),1,null,null,null,null));
+ constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0, node.getZ3Node(), p_0, t_0),
+ clause),1,null,null,null,null));
+ }
+
+ /**
+ * Return all currently attached endhosts
+ * @return NetworkObject
+ */
+ public List<String> EndHosts(){
+ List<String> att_nos = new ArrayList<String>();
+ for(NetworkObject el :elements){
+ if(el.isEndHost){
+ System.out.println("el: "+el);
+ att_nos.add(el.getZ3Node().toString());
+ }
+ }
+ return att_nos;
+ }
+}
diff --git a/verigraph/service/src/mcnet/components/NetworkObject.java b/verigraph/service/src/mcnet/components/NetworkObject.java
new file mode 100644
index 0000000..0de3937
--- /dev/null
+++ b/verigraph/service/src/mcnet/components/NetworkObject.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+
+/** Represents a generic network object.
+ *
+ */
+public abstract class NetworkObject extends Core{
+
+ public NetworkObject(Context ctx,Object[]... args) {
+ super(ctx,args);
+ }
+
+ protected DatatypeExpr z3Node;
+ protected boolean isEndHost;
+ /**
+ * Get a reference to the z3 node this class wraps around
+ * @return
+ */
+ abstract public DatatypeExpr getZ3Node();
+
+ public String toString(){
+ return z3Node.toString();
+ }
+
+ //There is probably an error: z3Node.hashCode = 0 because AST.hashCode() has always hash=0
+ /*public int hashCode(){
+ return z3Node.hashCode();
+ }*/
+
+ /**
+ * A simple way to determine the set of endhosts
+ * @return
+ */
+ public boolean isEndHost(){
+ return isEndHost;
+ }
+
+ /**
+ * Wrap methods to set policy
+ * @param policy
+ * @throws UnsupportedOperationException
+ */
+ void setPolicy (Object policy) throws UnsupportedOperationException{
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/verigraph/service/src/mcnet/components/Result.java b/verigraph/service/src/mcnet/components/Result.java
new file mode 100644
index 0000000..acb23f1
--- /dev/null
+++ b/verigraph/service/src/mcnet/components/Result.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.Model;
+
+/**Data structure for the core of the response to a check request for data isolation property
+ *
+ */
+public class Result {
+ Context ctx;
+ public Model model;
+ public BoolExpr[] unsat_core;
+
+/**
+ *
+ * @param ctx
+ * @param model
+ */
+ public Result(Context ctx, Model model){
+ this.ctx = ctx;
+ this.model = model;
+ }
+
+/**
+ *
+ * @param ctx
+ * @param unsat_core
+ */
+ public Result(Context ctx, BoolExpr[] unsat_core){
+ this.ctx = ctx;
+ this.unsat_core = unsat_core;
+}
+}
diff --git a/verigraph/service/src/mcnet/components/Tuple.java b/verigraph/service/src/mcnet/components/Tuple.java
new file mode 100644
index 0000000..849d607
--- /dev/null
+++ b/verigraph/service/src/mcnet/components/Tuple.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.components;
+
+/** A data structure which is an utility to make a generic couple of objects with different types in Java
+ *
+ */
+public class Tuple<T, U> {
+ public final T _1;
+ public final U _2;
+
+
+ public Tuple(T arg1,U arg2) {
+ super();
+ this._1 = arg1;
+ this._2 = arg2;
+ }
+
+ public Tuple(){
+ this._1 = null;
+ this._2 = null;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("(%s, %s)", _1, _2);
+ }
+ } \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/AclFirewall.java b/verigraph/service/src/mcnet/netobjs/AclFirewall.java
new file mode 100644
index 0000000..4ae3421
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/AclFirewall.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+import com.microsoft.z3.Sort;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+import mcnet.components.Tuple;
+
+/** Represents a Firewall with the associated Access Control List
+ *
+ */
+public class AclFirewall extends NetworkObject{
+
+ List<BoolExpr> constraints;
+ Context ctx;
+ DatatypeExpr fw;
+ ArrayList<Tuple<DatatypeExpr,DatatypeExpr>> acls;
+ Network net;
+ NetContext nctx;
+ FuncDecl acl_func;
+
+ public AclFirewall(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ isEndHost=false;
+ constraints = new ArrayList<BoolExpr>();
+ acls = new ArrayList<Tuple<DatatypeExpr,DatatypeExpr>>();
+ z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ fw = z3Node;
+ net = (Network)args[0][1];
+ nctx = (NetContext)args[0][2];
+ net.saneSend(this);
+ firewallSendRules();
+ }
+
+ /**
+ * Wrap add acls
+ * @param policy
+ */
+ public void setPolicy(ArrayList<Tuple<DatatypeExpr, DatatypeExpr>> policy){
+ addAcls(policy);
+ }
+
+ public void addAcls(ArrayList<Tuple<DatatypeExpr,DatatypeExpr>> acls){
+ this.acls.addAll(acls);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return fw;
+ }
+
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ aclConstraints(solver);
+ }
+
+ private void firewallSendRules (){
+ Expr p_0 = ctx.mkConst(fw+"_firewall_send_p_0", nctx.packet);
+ Expr n_0 = ctx.mkConst(fw+"_firewall_send_n_0", nctx.node);
+ Expr n_1 = ctx.mkConst(fw+"_firewall_send_n_1", nctx.node);
+ IntExpr t_0 = ctx.mkIntConst(fw+"_firewall_send_t_0");
+ IntExpr t_1 = ctx.mkIntConst(fw+"_firewall_send_t_1");
+ acl_func = ctx.mkFuncDecl(fw+"_acl_func", new Sort[]{nctx.address, nctx.address},ctx.mkBoolSort());
+
+ //Constraint1 send(fw, n_0, p, t_0) -> (exist n_1,t_1 : (recv(n_1, fw, p, t_1) &&
+ // t_1 < t_0 && !acl_func(p.src,p.dest))
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies(
+ (BoolExpr)nctx.send.apply(new Expr[]{ fw, n_0, p_0, t_0}),
+ ctx.mkExists(new Expr[]{t_1},
+ ctx.mkAnd(ctx.mkLt(t_1,t_0),
+ ctx.mkExists(new Expr[]{n_1},
+ nctx.recv.apply(n_1, fw, p_0, t_1),1,null,null,null,null),
+ ctx.mkNot((BoolExpr)acl_func.apply(nctx.pf.get("src").apply(p_0), nctx.pf.get("dest").apply(p_0)))),1,null,null,null,null)),1,null,null,null,null));
+
+ }
+
+ private void aclConstraints(Solver solver){
+ if (acls.size() == 0)
+ return;
+ Expr a_0 = ctx.mkConst(fw+"_firewall_acl_a_0", nctx.address);
+ Expr a_1 = ctx.mkConst(fw+"_firewall_acl_a_1", nctx.address);
+ BoolExpr[] acl_map = new BoolExpr[acls.size()];
+ for(int y=0;y<acls.size();y++){
+ Tuple<DatatypeExpr,DatatypeExpr> tp = acls.get(y);
+ acl_map[y] = ctx.mkOr(ctx.mkAnd(ctx.mkEq(a_0,tp._1),ctx.mkEq(a_1,tp._2)), ctx.mkAnd(ctx.mkEq(a_0,tp._2),ctx.mkEq(a_1,tp._1)));
+ }
+ //Constraint2 acl_func(a_0,a_1) == or(foreach ip1,ip2 in acl_map ((a_0 == ip1 && a_1 == ip2)||(a_0 == ip2 && a_1 == ip1)))
+ solver.add(ctx.mkForall(new Expr[]{a_0, a_1},
+ ctx.mkEq(
+ acl_func.apply(a_0, a_1),
+ ctx.mkOr(acl_map)),1,null,null,null,null));
+ }
+} \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/DumbNode.java b/verigraph/service/src/mcnet/netobjs/DumbNode.java
new file mode 100644
index 0000000..012ff40
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/DumbNode.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetworkObject;
+
+/**
+ * This is just a wrapper around z3 instances. The idea is that by using this we perhaps need to have
+ * fewer (or no) ifs to deal with the case where we don't instantiate an object for a node
+ *
+ */
+public class DumbNode extends NetworkObject {
+ public DumbNode(Context ctx, Object[]... args){
+ super(ctx,args);
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ return;
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ isEndHost=true;
+ this.z3Node = (DatatypeExpr)args[0][0];
+ }
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return z3Node;
+ }
+}
diff --git a/verigraph/service/src/mcnet/netobjs/EndHost.java b/verigraph/service/src/mcnet/netobjs/EndHost.java
new file mode 100644
index 0000000..99cf732
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/EndHost.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/**
+ * End host network objects
+ *
+ */
+public class EndHost extends NetworkObject{
+
+ List<BoolExpr> constraints;
+ Context ctx;
+ DatatypeExpr node;
+ Network net;
+ NetContext nctx;
+
+ public EndHost(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ isEndHost=true;
+ constraints = new ArrayList<BoolExpr>();
+ z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ node = z3Node;
+ net = (Network)args[0][1];
+ nctx = (NetContext)args[0][2];
+ endHostRules();
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return node;
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ public void endHostRules (){
+ Expr n_0 = ctx.mkConst("eh_"+node+"_n_0", nctx.node);
+ IntExpr t_0 = ctx.mkIntConst("eh_"+node+"_t_0");
+ Expr p_0 = ctx.mkConst("eh_"+node+"_p_0", nctx.packet);
+
+ //Constraint1 send(node, n_0, p, t_0) -> nodeHasAddr(node,p.src)
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies(
+ (BoolExpr)nctx.send.apply( new Expr[]{ node, n_0, p_0, t_0}),
+ (BoolExpr)nctx.nodeHasAddr.apply(new Expr[]{node, nctx.pf.get("src").apply(p_0)})),1,null,null,null,null));
+ //Constraint2 send(node, n_0, p, t_0) -> p.origin == node
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies(
+ (BoolExpr)nctx.send.apply( new Expr[]{ node, n_0, p_0, t_0}),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_0),node)),1,null,null,null,null));
+ //Constraint3 send(node, n_0, p, t_0) -> p.orig_body == p.body
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies(
+ (BoolExpr)nctx.send.apply(new Expr[]{ node, n_0, p_0, t_0}),
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null));
+ //Constraint4 recv(n_0, node, p, t_0) -> nodeHasAddr(node,p.dest)
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies(
+ (BoolExpr)nctx.recv.apply( new Expr[]{ n_0, node, p_0, t_0}),
+ (BoolExpr)nctx.nodeHasAddr.apply(new Expr[]{node, nctx.pf.get("dest").apply(p_0)})),1,null,null,null,null));
+
+// Just a try: here we state that an endhost is not able to issue a HTTP response traffic
+// See PolitoCache.py model for constants definition (2 means HTTP_RESPONSE, 1 means HTTP_REQUEST)
+// constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+// ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0),
+// ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(1))),1,null,null,null,null));
+ }
+} \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PacketModel.java b/verigraph/service/src/mcnet/netobjs/PacketModel.java
new file mode 100644
index 0000000..5761861
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PacketModel.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import com.microsoft.z3.DatatypeExpr;
+
+/*
+ * Fields that can be configured -> "dest","body","seq","proto","emailFrom","url","options"
+ */
+public class PacketModel {
+
+ private DatatypeExpr ip_dest;
+ private Integer body;
+ private Integer seq;
+ private Integer proto;
+ private Integer emailFrom;
+ private Integer url;
+ private Integer options;
+
+ public DatatypeExpr getIp_dest() {
+ return ip_dest;
+ }
+ public void setIp_dest(DatatypeExpr ip_dest) {
+ this.ip_dest = ip_dest;
+ }
+ public Integer getBody() {
+ return body;
+ }
+ public void setBody(Integer body) {
+ this.body = body;
+ }
+ public Integer getSeq() {
+ return seq;
+ }
+ public void setSeq(Integer seq) {
+ this.seq = seq;
+ }
+ public Integer getProto() {
+ return proto;
+ }
+ public void setProto(Integer proto) {
+ this.proto = proto;
+ }
+ public Integer getEmailFrom() {
+ return emailFrom;
+ }
+ public void setEmailFrom(Integer emailFrom) {
+ this.emailFrom = emailFrom;
+ }
+ public Integer getUrl() {
+ return url;
+ }
+ public void setUrl(Integer url) {
+ this.url = url;
+ }
+ public Integer getOptions() {
+ return options;
+ }
+ public void setOptions(Integer options) {
+ this.options = options;
+ }
+
+}
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoAntispam.java b/verigraph/service/src/mcnet/netobjs/PolitoAntispam.java
new file mode 100644
index 0000000..abb4615
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoAntispam.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+/**
+ * Model of an anti-spam node
+ *
+ */
+public class PolitoAntispam extends NetworkObject{
+
+ List<BoolExpr> constraints;
+ Context ctx;
+ DatatypeExpr politoAntispam;
+ Network net;
+ NetContext nctx;
+ FuncDecl isInBlacklist;
+
+ public PolitoAntispam(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ isEndHost=false;
+ constraints = new ArrayList<BoolExpr>();
+ z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ politoAntispam = z3Node;
+ net = (Network)args[0][1];
+ nctx = (NetContext)args[0][2];
+ //net.saneSend(this);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return politoAntispam;
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ public void installAntispam (int[] blackList){
+ Expr n_0 = ctx.mkConst(politoAntispam+"_n_0", nctx.node);
+ Expr n_1 = ctx.mkConst(politoAntispam+"_n_1", nctx.node);
+ Expr p_0 = ctx.mkConst(politoAntispam+"_p_0", nctx.packet);
+ IntExpr t_0 = ctx.mkIntConst(politoAntispam+"_t_0");
+ IntExpr t_1 = ctx.mkIntConst(politoAntispam+"_t_1");
+ IntExpr ef_0 = ctx.mkIntConst(politoAntispam+"_ef_0");
+
+ isInBlacklist = ctx.mkFuncDecl(politoAntispam+"_isInBlacklist", ctx.mkIntSort(), ctx.mkBoolSort());
+ BoolExpr[] blConstraint = new BoolExpr[blackList.length];
+ if(blackList.length != 0){
+ for (int i=0;i<blackList.length;i++)
+ blConstraint[i]=(ctx.mkEq(ef_0,ctx.mkInt(blackList[i])));
+ //Constraint1a if(isInBlackList(ef_0) == or(for bl in blacklist (ef_0==bl)) ? true : false
+ constraints.add(ctx.mkForall(new Expr[]{ef_0}, ctx.mkIff((BoolExpr)isInBlacklist.apply(ef_0),ctx.mkOr(blConstraint)),1,null,null,null,null));
+ }else{
+ //Constraint1b isInblackList(ef_0) == false
+ constraints.add(ctx.mkForall(new Expr[]{ef_0}, ctx.mkEq((BoolExpr)isInBlacklist.apply(ef_0), ctx.mkBool(false)),1,null,null,null,null));
+ }
+
+ //Constraint2 send(politoAntispam, n_0, p, t_0) && p.proto(POP3_RESP) ->
+ // (exist n_1,t_1 : (recv(n_1, politoAntispam, p, t_1) && t_1 < t_0)) && !isInBlackList(p.emailFrom)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(politoAntispam, n_0, p_0, t_0), ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_RESPONSE))),
+ ctx.mkAnd( ctx.mkExists(new Expr[]{n_1, t_1},
+ ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1, politoAntispam, p_0, t_1), ctx.mkLt(t_1 , t_0)),1,null,null,null,null),
+ ctx.mkNot((BoolExpr)isInBlacklist.apply(nctx.pf.get("emailFrom").apply(p_0))))),1,null,null,null,null));
+
+ //Constraint3 send(politoAntispam, n_0, p, t_0) && p.proto(POP3_REQ) ->
+ // (exist n_1,t_1 : (recv(n_1, politoAntispam, p, t_1) && t_1 < t_0))
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(politoAntispam, n_0, p_0, t_0), ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_REQUEST))),
+ ctx.mkAnd(ctx.mkExists(new Expr[]{n_1, t_1},
+ ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1, politoAntispam, p_0, t_1),
+ ctx.mkLt(t_1 , t_0)),1,null,null,null,null))),1,null,null,null,null));
+
+ //Constraint4 send(politoAntispam, politoErrFunction, p, t_0) ->
+ // (exist n_1,t_1 : (recv(n_1, politoAntispam, p, t_1) && t_1 < t_0 && p.emailFrom ==1))
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoAntispam, nctx.nm.get("politoErrFunction").getZ3Node(), p_0, t_0),
+ ctx.mkAnd(ctx.mkExists(new Expr[]{n_1, t_1},
+ ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1, politoAntispam, p_0, t_1),
+ ctx.mkLt(t_1 , t_0),
+ ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0),ctx.mkInt(1))),1,null,null,null,null))),1,null,null,null,null));
+
+ //Constraint5 send(politoAntispam, n_0, p, t_0) -> p.proto == POP_REQ || p.protpo == POP_RESP
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoAntispam, n_0, p_0, t_0),
+ ctx.mkOr( ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_REQUEST)),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_RESPONSE)))),1,null,null,null,null));
+
+ //Constraint6 send(politoAntispam, n_0, p, t_0) -> nodeHasAddr(politoAntispam,p.src)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoAntispam, n_0, p_0, t_0),
+ ctx.mkNot((BoolExpr)nctx.nodeHasAddr.apply(politoAntispam,nctx.pf.get("src").apply(p_0)))),1,null,null,null,null));
+ }
+ } \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoCache.java b/verigraph/service/src/mcnet/netobjs/PolitoCache.java
new file mode 100644
index 0000000..948915c
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoCache.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+import com.microsoft.z3.Sort;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/**Cache Model
+ *
+ */
+public class PolitoCache extends NetworkObject{
+
+ List<BoolExpr> constraints;
+ Context ctx;
+ DatatypeExpr politoCache;
+ Network net;
+ NetContext nctx;
+ FuncDecl isInBlacklist;
+
+ public PolitoCache(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ isEndHost=false;
+ constraints = new ArrayList<BoolExpr>();
+ z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ politoCache = z3Node;
+ net = (Network)args[0][1];
+ nctx = (NetContext)args[0][2];
+ //net.saneSend(this);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return politoCache;
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ public void installCache (NetworkObject[] internalNodes){
+ Expr n_0 = ctx.mkConst("politoCache_"+politoCache+"_n_0", nctx.node);
+ Expr n_1 = ctx.mkConst("politoCache_"+politoCache+"_n_1", nctx.node);
+ Expr n_2 = ctx.mkConst("politoCache_"+politoCache+"_n_2", nctx.node);
+ Expr p_0 = ctx.mkConst("politoCache_"+politoCache+"_p_0", nctx.packet);
+ Expr p_1 = ctx.mkConst("politoCache_"+politoCache+"_p_1", nctx.packet);
+ Expr p_2 = ctx.mkConst("politoCache_"+politoCache+"_p_2", nctx.packet);
+
+ IntExpr t_0 = ctx.mkIntConst("politoCache_"+politoCache+"_t_0");
+ IntExpr t_1 = ctx.mkIntConst("politoCache_"+politoCache+"_t_1");
+ IntExpr t_2 = ctx.mkIntConst("politoCache_"+politoCache+"_t_2");
+
+ Expr a_0 = ctx.mkConst(politoCache+"politoCache_a_0", nctx.node);
+ IntExpr u_0 = ctx.mkIntConst("politoCache_"+politoCache+"_u_0");
+
+ FuncDecl isInternalNode = ctx.mkFuncDecl(politoCache+"_isInternalNode", nctx.node, ctx.mkBoolSort());
+ FuncDecl isInCache = ctx.mkFuncDecl(politoCache+"_isInCache", new Sort[]{ctx.mkIntSort(),ctx.mkIntSort()}, ctx.mkBoolSort());
+
+ assert(internalNodes.length!=0); //No internal nodes => Should never happen
+
+ //Modeling the behavior of the isInternalNode() and isInCache() functions
+ BoolExpr[] internalNodesConstraint = new BoolExpr[internalNodes.length];
+ for(int w=0;w<internalNodesConstraint.length;w++)
+ internalNodesConstraint[w]= (ctx.mkEq(a_0,internalNodes[w].getZ3Node()));
+
+ //Constraint1 if(isInternalNode(a_0) == or(listadeinodiinterni) ? True : false
+ constraints.add(
+ ctx.mkForall(new Expr[]{a_0},
+ ctx.mkIff((BoolExpr)isInternalNode.apply(a_0), ctx.mkOr(internalNodesConstraint)),1,null,null,null,null));
+
+// constraints.add(ctx.mkForall(new Expr[]{a_0}, ctx.mkEq(isInternalNode.apply(a_0),ctx.mkOr(internalNodesConstraint)),1,null,null,null,null));
+
+// constraints.add(ctx.mkForall(new Expr[]{u_0, t_0},
+// ctx.mkITE(ctx.mkExists(new Expr[]{t_1, t_2, p_1, p_2, n_1, n_2},
+// ctx.mkAnd(ctx.mkLt(t_1, t_2),
+// ctx.mkLt(t_1, t_0),
+// ctx.mkLt(t_2, t_0),
+// (BoolExpr)nctx.recv.apply(n_1, politoCache, p_1, t_1),
+// (BoolExpr)nctx.recv.apply(n_2, politoCache, p_2, t_2),
+// ctx.mkEq(nctx.pf.get("proto").apply(p_1),ctx.mkInt(nctx.HTTP_REQUEST)),
+// ctx.mkEq(nctx.pf.get("proto").apply(p_2),ctx.mkInt(nctx.HTTP_RESPONSE)),
+// (BoolExpr)isInternalNode.apply(n_1),
+// ctx.mkNot((BoolExpr)isInternalNode.apply(n_2)),
+// ctx.mkEq(nctx.pf.get("url").apply(p_1),u_0),
+// ctx.mkEq(nctx.pf.get("url").apply(p_2),u_0)),1,null,null,null,null),
+// ctx.mkEq(isInCache.apply(u_0,t_0),ctx.mkBool(true)),ctx.mkEq(isInCache.apply(u_0,t_0),ctx.mkBool(false))),1,null,null,null,null));
+//
+
+ //Constraint2 isInCache(u_0,t_0), exist t_1, t_2, p_1, p_2, n_1, n_2 :
+ // ( t_1< t_2 < t_0 && recv(n_1, politoCache, p_1, t_1) && recv(n_2, politoCache, p_2, t_2))) &&
+ // p_1.proto == HTTP_REQ && p_2.proto == HTTP_RESP &&
+ // isInternalNode(n_1) && !isInternalNode(n_2) &&
+ // p_1.url == u_0 && p_2.url == u_0 )
+ constraints.add(
+ ctx.mkForall(new Expr[]{u_0, t_0},
+ ctx.mkImplies((BoolExpr)isInCache.apply(u_0, t_0),
+ ctx.mkExists(new Expr[]{t_1,t_2,p_1,p_2,n_1, n_2},
+ ctx.mkAnd(
+ ctx.mkLt(t_1, t_2),
+ ctx.mkLt(t_1, t_0),
+ ctx.mkLt(t_2, t_0),
+ (BoolExpr)nctx.recv.apply(n_1, politoCache, p_1, t_1),
+ (BoolExpr)nctx.recv.apply(n_2, politoCache, p_2, t_2),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_1), ctx.mkInt(nctx.HTTP_REQUEST)),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_2), ctx.mkInt(nctx.HTTP_RESPONSE)),
+ (BoolExpr)isInternalNode.apply(n_1),
+ ctx.mkNot((BoolExpr)isInternalNode.apply(n_2)),
+ ctx.mkEq(nctx.pf.get("url").apply(p_1), u_0),
+ ctx.mkEq(nctx.pf.get("url").apply(p_2), u_0)),1,null,null,null,null)),1,null,null,null,null));
+// //Always in cache
+// constraints.add(ctx.mkForall(new Expr[]{u_0, t_0},ctx.mkEq(isInCache.apply(u_0,t_0),ctx.mkBool(true)),1,null,null,null,null));
+
+ //Constraint3 Modeling the behavior of the cache
+ // send(politoCache, n_0, p, t_0) && !isInternalNode(n_0) ->
+ // (exist t_1,n_1 :
+ // (t_1 < t_0 && recv(n_1, politoCache, p, t_1) &&
+ // p.proto == HTTP_REQ && !isInCache(p.url,t_0))
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0,p_0, t_0},
+ ctx.mkImplies(
+ ctx.mkAnd((BoolExpr)nctx.send.apply(politoCache,n_0,p_0,t_0),ctx.mkNot((BoolExpr)isInternalNode.apply(n_0))),
+ ctx.mkAnd(ctx.mkExists(new Expr[]{t_1, n_1},
+ ctx.mkAnd(
+ ctx.mkLt(t_1, t_0),
+ (BoolExpr)isInternalNode.apply(n_1),
+ (BoolExpr)nctx.recv.apply(n_1, politoCache, p_0, t_1)),1,null,null,null,null),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST)),
+ ctx.mkNot((BoolExpr)isInCache.apply(nctx.pf.get("url").apply(p_0), t_0)))),1,null,null,null,null));
+
+ //Constraint4 send(politoCache, n_0, p, t_0) && isInternalNode(n_0) ->
+ // (exist p_1,t_1 :
+ // (t_1 < t_0 && recv(n_0, politoCache, p_1, t_1) &&
+ // p_1.proto == HTTP_REQ && p.proto == HTTP_RESP &&
+ // p_1.url == p.url && p.src == p_1.dest && p.dest==p_1.src
+ // && isInCache(p.url,t_0))
+ constraints.add(
+ ctx.mkForall(new Expr[]{n_0,p_0, t_0},
+ ctx.mkImplies(
+ ctx.mkAnd((BoolExpr)nctx.send.apply(politoCache,n_0,p_0,t_0),(BoolExpr)isInternalNode.apply(n_0)),
+ ctx.mkAnd(ctx.mkExists(new Expr[]{p_1, t_1},
+ ctx.mkAnd(
+ ctx.mkLt(t_1, t_0),
+ (BoolExpr)nctx.recv.apply(n_0, politoCache, p_1, t_1),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_1), ctx.mkInt(nctx.HTTP_REQUEST)),
+ ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0))),1,null,null,null,null),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_RESPONSE)),
+ ctx.mkEq(nctx.pf.get("src").apply(p_0), nctx.pf.get("dest").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_0), nctx.pf.get("src").apply(p_1)),
+ (BoolExpr)isInCache.apply(nctx.pf.get("url").apply(p_0), t_0))),1,null,null,null,null));
+ }
+} \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoEndHost.java b/verigraph/service/src/mcnet/netobjs/PolitoEndHost.java
new file mode 100644
index 0000000..e12579f
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoEndHost.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+public class PolitoEndHost extends NetworkObject {
+
+ List<BoolExpr> constraints = new ArrayList<BoolExpr>();
+ Context ctx;
+ DatatypeExpr politoEndHost;
+ Network net;
+ NetContext nctx;
+
+ public PolitoEndHost(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return politoEndHost;
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ this.isEndHost = true;
+ this.politoEndHost = this.z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ this.net = (Network)args[0][1];
+ this.nctx = (NetContext)args[0][2];
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ /*
+ * Fields that can be configured -> "dest","body","seq","proto","emailFrom","url","options"
+ */
+ public void installEndHost (PacketModel packet){
+ System.out.println("Installing PolitoEndHost...");
+ Expr n_0 = ctx.mkConst("PolitoEndHost_"+politoEndHost+"_n_0", nctx.node);
+ Expr p_0 = ctx.mkConst("PolitoEndHost_"+politoEndHost+"_p_0", nctx.packet);
+ IntExpr t_0 = ctx.mkIntConst("PolitoEndHost_"+politoEndHost+"_t_0");
+ BoolExpr predicatesOnPktFields = ctx.mkTrue();
+
+ if(packet.getIp_dest() != null)
+ predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("dest").apply(p_0), packet.getIp_dest()));
+ if(packet.getBody() != null)
+ predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("body").apply(p_0), ctx.mkInt(packet.getBody())));
+ if(packet.getEmailFrom() != null)
+ predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0), ctx.mkInt(packet.getEmailFrom())));
+ if(packet.getOptions() != null)
+ predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("options").apply(p_0), ctx.mkInt(packet.getOptions())));
+ if(packet.getProto() != null)
+ predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(packet.getProto())));
+ if(packet.getSeq() != null)
+ predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("seq").apply(p_0), ctx.mkInt(packet.getSeq())));
+ if(packet.getUrl() != null)
+ predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("url").apply(p_0), ctx.mkInt(packet.getUrl())));
+
+ //Constraint1 send(politoWebClient, n_0, p, t_0) -> p.origin == politoWebClient && p.orig_body == p.body && nodeHasAddr(politoWebClient,p.src)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoEndHost, n_0, p_0, t_0),
+ ctx.mkAnd(predicatesOnPktFields,
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_0),politoEndHost),
+ (BoolExpr)nctx.nodeHasAddr.apply(politoEndHost,nctx.pf.get("src").apply(p_0)))),1,null,null,null,null));
+
+ //Constraint2 recv(n_0, politoWebClient, p, t_0) -> nodeHasAddr(politoWebClient,p.dest)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,politoEndHost, p_0, t_0),
+ (BoolExpr)nctx.nodeHasAddr.apply(politoEndHost,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null));
+
+ System.out.println("Done.");
+ return;
+ }
+
+}
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoErrFunction.java b/verigraph/service/src/mcnet/netobjs/PolitoErrFunction.java
new file mode 100644
index 0000000..5f84b9f
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoErrFunction.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/**Error Function objects
+ *
+ */
+public class PolitoErrFunction extends NetworkObject{
+
+ List<BoolExpr> constraints;
+ Context ctx;
+ DatatypeExpr politoErrFunction;
+ Network net;
+ NetContext nctx;
+ FuncDecl isInBlacklist;
+
+ public PolitoErrFunction(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ isEndHost=true;
+ constraints = new ArrayList<BoolExpr>();
+ z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ politoErrFunction = z3Node;
+ net = (Network)args[0][1];
+ nctx = (NetContext)args[0][2];
+ errFunctionRules();
+ //net.saneSend(this);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return politoErrFunction;
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+// System.out.println("[ERR FUNC] Installing rules.");
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ private void errFunctionRules (){
+ Expr n_0 = ctx.mkConst("PolitoErrFunction_"+politoErrFunction+"_n_0", nctx.node);
+ Expr p_0 = ctx.mkConst("PolitoErrFunction_"+politoErrFunction+"_p_0", nctx.packet);
+ IntExpr t_0 = ctx.mkIntConst("PolitoErrFunction_"+politoErrFunction+"_t_0");
+
+// constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+// ctx.mkImplies((BoolExpr)nctx.send.apply(politoErrFunction, n_0, p_0, t_0),
+// (BoolExpr)nctx.nodeHasAddr.apply(politoErrFunction, nctx.pf.get("src").apply(p_0))),1,null,null,null,null));
+// constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+// ctx.mkImplies((BoolExpr)nctx.send.apply(politoErrFunction, n_0, p_0, t_0),
+// ctx.mkEq(nctx.pf.get("origin").apply(p_0), politoErrFunction)),1,null,null,null,null));
+//
+// constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+// ctx.mkImplies((BoolExpr)nctx.send.apply(politoErrFunction, n_0, p_0, t_0),
+// ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null));
+
+
+// Constraint1 We want the ErrFunction not to send out any packet
+// send(politoErrFunction, n_0, p, t_0) -> 1 == 2
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoErrFunction, n_0, p_0, t_0),
+ ctx.mkEq(ctx.mkInt(1),ctx.mkInt(2))),1,null,null,null,null));
+
+// constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+// ctx.mkImplies( (BoolExpr)nctx.send.apply(n_0, politoErrFunction, p_0, t_0),
+// (BoolExpr)nctx.nodeHasAddr.apply(politoErrFunction, nctx.pf.get("dest").apply(p_0))),1,null,null,null,null));
+
+ }
+ } \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoFieldModifier.java b/verigraph/service/src/mcnet/netobjs/PolitoFieldModifier.java
new file mode 100644
index 0000000..6d8d8fe
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoFieldModifier.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+public class PolitoFieldModifier extends NetworkObject {
+
+ List<BoolExpr> constraints;
+ Context ctx;
+ DatatypeExpr politoFieldModifier;
+ Network net;
+ NetContext nctx;
+
+ public PolitoFieldModifier(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return politoFieldModifier;
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ isEndHost=false;
+ constraints = new ArrayList<BoolExpr>();
+ z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ politoFieldModifier = z3Node;
+ net = (Network)args[0][1];
+ nctx = (NetContext)args[0][2];
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ public void installFieldModifier (){
+ Expr x = ctx.mkConst("politoFieldModifier_"+politoFieldModifier+"_x", nctx.node);
+ Expr y = ctx.mkConst("politoFieldModifier_"+politoFieldModifier+"_y", nctx.node);
+ Expr p_0 = ctx.mkConst("politoFieldModifier_"+politoFieldModifier+"_p_0", nctx.packet);
+ Expr p_1 = ctx.mkConst("politoFieldModifier_"+politoFieldModifier+"_p_1", nctx.packet);
+
+ IntExpr t_0 = ctx.mkIntConst("politoFieldModifier_"+politoFieldModifier+"_t_0");
+ IntExpr t_1 = ctx.mkIntConst("politoFieldModifier_"+politoFieldModifier+"_t_1");
+
+ constraints.add(
+ ctx.mkForall(new Expr[]{t_0, p_0, x},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoFieldModifier,x,p_0,t_0),
+ ctx.mkExists(new Expr[]{y, p_1, t_1},
+ ctx.mkAnd(ctx.mkLt(t_1, t_0),
+ (BoolExpr)nctx.recv.apply(y, politoFieldModifier, p_1, t_1),
+ ctx.mkEq(nctx.pf.get("encrypted").apply(p_0), nctx.pf.get("encrypted").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("src").apply(p_0), nctx.pf.get("src").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_0), nctx.pf.get("dest").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.pf.get("inner_src").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("inner_dest").apply(p_0), nctx.pf.get("inner_dest").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_0), nctx.pf.get("origin").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_0), nctx.pf.get("orig_body").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("body").apply(p_0), nctx.pf.get("body").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("seq").apply(p_0), nctx.pf.get("seq").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_0), nctx.pf.get("proto").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0), nctx.pf.get("emailFrom").apply(p_1)),
+ ctx.mkNot(ctx.mkEq(nctx.pf.get("url").apply(p_0), nctx.pf.get("url").apply(p_1))),
+ ctx.mkEq(nctx.pf.get("options").apply(p_0), nctx.pf.get("options").apply(p_1))),1,null,null,null,null)),
+ 1,null,null,null,null));
+ }
+
+} \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoIDS.java b/verigraph/service/src/mcnet/netobjs/PolitoIDS.java
new file mode 100644
index 0000000..6f2cddf
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoIDS.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+public class PolitoIDS extends NetworkObject {
+
+ public static final int DROGA = 1; //no go
+ public static final int GATTINI = 2; //go
+
+ Context ctx;
+ List<BoolExpr> constraints = new ArrayList<BoolExpr>();
+ DatatypeExpr politoIDS;
+ Network net;
+ NetContext nctx;
+ FuncDecl isInBlacklist;
+
+
+ public PolitoIDS(Context ctx, Object[]...args){
+ super(ctx, args);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return politoIDS;
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+
+ this.ctx = ctx;
+ this.isEndHost = false;
+ this.politoIDS = this.z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ this.net = (Network)args[0][1];
+ this.nctx = (NetContext)args[0][2];
+
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+
+ }
+
+ public void installIDS(int[] blackList){
+ Expr n_0 = ctx.mkConst(politoIDS + "_n_0", nctx.node);
+ Expr n_1 = ctx.mkConst(politoIDS + "_n_1", nctx.node);
+ Expr p_0 = ctx.mkConst(politoIDS + "_p_0", nctx.packet);
+ IntExpr t_0 = ctx.mkIntConst(politoIDS + "_t_0");
+ IntExpr t_1 = ctx.mkIntConst(politoIDS + "_t_1");
+ Expr b_0 = ctx.mkIntConst(politoIDS + "_b_0");
+
+ isInBlacklist = ctx.mkFuncDecl(politoIDS + "_isInBlacklist", ctx.mkIntSort(), ctx.mkBoolSort());
+
+
+ BoolExpr[] blConstraints = new BoolExpr[blackList.length];
+ if(blackList.length != 0){
+
+ for(int i = 0; i<blackList.length; i++)
+ blConstraints[i] = ctx.mkEq(b_0, ctx.mkInt(blackList[i]));
+
+ this.constraints.add(ctx.mkForall(new Expr[]{b_0},
+ ctx.mkIff((BoolExpr)isInBlacklist.apply(b_0), ctx.mkOr(blConstraints)),
+ 1,
+ null, null, null, null));
+ }else{
+ this.constraints.add(ctx.mkForall(new Expr[]{b_0},
+ ctx.mkEq(isInBlacklist.apply(b_0), ctx.mkBool(false)),
+ 1,
+ null, null, null, null));
+ }
+
+ //Constraint2 send(politoIDS, n_0, p, t_0) && (p.proto(HTTP_RESPONSE) || p.proto(HTTP_REQUEST)) ->
+ // (exist n_1,t_1 : (recv(n_1, politoIDS, p, t_1) && t_1 < t_0)) && !isInBlackList(p.body)
+
+ this.constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(politoIDS, n_0, p_0, t_0), ctx.mkOr(ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_RESPONSE)), ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST)))),
+ ctx.mkAnd(ctx.mkExists(new Expr[]{n_1,t_1},
+ ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1,politoIDS,p_0,t_1),ctx.mkLt(t_1, t_0)),
+ 1,
+ null, null, null, null),
+ ctx.mkNot((BoolExpr)isInBlacklist.apply(nctx.pf.get("body").apply(p_0))))),
+ 1,
+ null, null, null, null));
+
+ //Constraint3 send(politoIDS, n_0, p, t_0) && p.proto(HTTP_REQUEST) ->
+ // (exist n_1,t_1 : (recv(n_1, politoIDS, p, t_1) && t_1 < t_0)) Constraint not needed anymore (included in contr. 2)
+ /*
+ this.constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(politoIDS, n_0, p_0, t_0), ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST))),
+ ctx.mkAnd(ctx.mkExists(new Expr[]{n_1,t_1},
+ ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1,politoIDS,p_0,t_1),ctx.mkLt(t_1, t_0)),
+ 1,
+ null, null, null, null))),
+ 1,
+ null, null, null, null));
+ */
+
+ //Constraint5 send(politoIDS, n_0, p, t_0) -> p.proto == HTTP_REQ || p.protpo == HTTP_RESP
+
+ this.constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoIDS, n_0, p_0, t_0),
+ ctx.mkOr(ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST)),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_RESPONSE)))),
+ 1,
+ null,null,null,null));
+
+ //Constraint6 send(politoIDS, n_0, p, t_0) -> nodeHasAddr(politoIDS,p.src)
+
+ this.constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoIDS, n_0, p_0, t_0),
+ ctx.mkNot((BoolExpr)nctx.nodeHasAddr.apply(politoIDS,nctx.pf.get("src").apply(p_0)))),
+ 1,
+ null,null,null,null));
+
+ }
+
+}
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoMailClient.java b/verigraph/service/src/mcnet/netobjs/PolitoMailClient.java
new file mode 100644
index 0000000..6925258
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoMailClient.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/**
+ * MailClient objects
+ *
+ */
+public class PolitoMailClient extends NetworkObject{
+
+ List<BoolExpr> constraints;
+ Context ctx;
+ DatatypeExpr politoMailClient;
+ Network net;
+ NetContext nctx;
+ FuncDecl isInBlacklist;
+
+ public PolitoMailClient(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ isEndHost=true;
+ constraints = new ArrayList<BoolExpr>();
+ z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ politoMailClient = z3Node;
+ net = (Network)args[0][1];
+ nctx = (NetContext)args[0][2];
+ DatatypeExpr ipServer = (DatatypeExpr) args[0][3];
+ mailClientRules(ipServer);
+ //net.saneSend(this);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return politoMailClient;
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+// System.out.println("[MailClient] Installing rules.");
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ private void mailClientRules (DatatypeExpr ipServer){
+ Expr n_0 = ctx.mkConst("PolitoMailClient_"+politoMailClient+"_n_0", nctx.node);
+ Expr p_0 = ctx.mkConst("PolitoMailClient_"+politoMailClient+"_p_0", nctx.packet);
+ IntExpr t_0 = ctx.mkIntConst("PolitoMailClient_"+politoMailClient+"_t_0");
+
+// Constraint1 send(politoMailClient, n_0, p, t_0) -> nodeHasAddr(politoMailClient,p.src)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0),
+ (BoolExpr)nctx.nodeHasAddr.apply(politoMailClient,nctx.pf.get("src").apply(p_0))),1,null,null,null,null));
+
+// Constraint2 send(politoMailClient, n_0, p, t_0) -> p.origin == politoMailClient
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_0),politoMailClient)),1,null,null,null,null));
+
+// Constraint3 send(politoMailClient, n_0, p, t_0) -> p.orig_body == p.body
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null));
+
+// Constraint4 recv(n_0, politoMailClient, p, t_0) -> nodeHasAddr(politoMailClient,p.dest)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,politoMailClient, p_0, t_0),
+ (BoolExpr)nctx.nodeHasAddr.apply(politoMailClient,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null));
+
+// Constraint5 This client is only able to produce POP3 requests
+// send(politoMailClient, n_0, p, t_0) -> p.proto == POP3_REQ
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_REQUEST))),1,null,null,null,null));
+
+// Constraint6 send(politoMailClient, n_0, p, t_0) -> p.dest == ip_mailServer
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_0), ipServer)),1,null,null,null,null));
+ }
+}
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoMailServer.java b/verigraph/service/src/mcnet/netobjs/PolitoMailServer.java
new file mode 100644
index 0000000..c464195
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoMailServer.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/** Mail server objects
+ *
+ */
+public class PolitoMailServer extends NetworkObject{
+
+ List<BoolExpr> constraints;
+ Context ctx;
+ DatatypeExpr politoMailServer;
+ Network net;
+ NetContext nctx;
+ FuncDecl isInBlacklist;
+
+ public PolitoMailServer(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ isEndHost=false;
+ constraints = new ArrayList<BoolExpr>();
+ z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ politoMailServer = z3Node;
+ net = (Network)args[0][1];
+ nctx = (NetContext)args[0][2];
+ mailServerRules();
+ net.saneSend(this);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return politoMailServer;
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ private void mailServerRules (){
+ Expr n_0 = ctx.mkConst(politoMailServer+"_n_0", nctx.node);
+ Expr p_0 = ctx.mkConst(politoMailServer+"_p_0", nctx.packet);
+ Expr p_1 = ctx.mkConst(politoMailServer+"_p_1", nctx.packet);
+ IntExpr t_0 = ctx.mkIntConst(politoMailServer+"_t_0");
+ IntExpr t_1 = ctx.mkIntConst(politoMailServer+"_t_1");
+
+// Constraint1 send(politoMailServer, n_0, p, t_0) -> nodeHasAddr(politoMailServer,p.src)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0),
+ (BoolExpr)nctx.nodeHasAddr.apply(politoMailServer,nctx.pf.get("src").apply(p_0))),1,null,null,null,null));
+
+// Constraint2 send(politoMailServer, n_0, p, t_0) -> p.origin == politoMailServer
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_0),politoMailServer)),1,null,null,null,null));
+
+// Constraint3 send(politoMailServer, n_0, p, t_0) -> p.orig_body == p.body
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null));
+
+// Constraint4 recv(n_0, politoMailServer, p, t_0) -> nodeHasAddr(politoMailServer,p.dest)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,politoMailServer, p_0, t_0),
+ (BoolExpr)nctx.nodeHasAddr.apply(politoMailServer,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null));
+
+// Constraint5 send(politoMailServer, n_0, p, t_0) -> p.proto == POP3_RESP && p.emailFrom == 1
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0),
+ ctx.mkAnd( ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_RESPONSE)),
+ ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0), ctx.mkInt(1)))),1,null,null,null,null));
+
+// Constraint6 send(politoMailServer, n_0, p, t_0) ->
+// (exist p_1, t_1 : (t_1 < t_0 && recv(n_0, politoMailServer, p_1, t_1) &&
+// p_0.proto == POP3_RESP && p_1.proto == POP3_REQ && p_0.dest == p_1.src )
+
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0),
+ ctx.mkExists(new Expr[]{p_1, t_1},
+ ctx.mkAnd(ctx.mkLt(t_1, t_0),
+ (BoolExpr)nctx.recv.apply(n_0, politoMailServer, p_1, t_1),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_RESPONSE)),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_1), ctx.mkInt(nctx.POP3_REQUEST)),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_0), nctx.pf.get("src").apply(p_1))),1,null,null,null,null)),1,null,null,null,null));
+
+// constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+// ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0),
+// ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0),ctx.mkInt(2))),1,null,null,null,null));
+ }
+} \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoNF.java b/verigraph/service/src/mcnet/netobjs/PolitoNF.java
new file mode 100644
index 0000000..53cae28
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoNF.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+import com.microsoft.z3.Sort;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+/** First example of custom network function: a simple filter
+ *
+ */
+public class PolitoNF extends NetworkObject{
+
+ List<BoolExpr> constraints;
+ Context ctx;
+ DatatypeExpr politoNF;
+ Network net;
+ NetContext nctx;
+ FuncDecl isInBlacklist;
+
+
+ public PolitoNF(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ isEndHost=false;
+ constraints = new ArrayList<BoolExpr>();
+ z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ politoNF = z3Node;
+ net = (Network)args[0][1];
+ nctx = (NetContext)args[0][2];
+ //net.saneSend(this);
+ }
+
+ public void politoNFRules (DatatypeExpr ipA,DatatypeExpr ipB){
+// System.out.println("[PolitoNf] Installing rules");
+ Expr n_0 = ctx.mkConst("politoNF_"+politoNF+"_n_0", nctx.node);
+ Expr n_1 = ctx.mkConst("politoNF_"+politoNF+"_n_1", nctx.node);
+ Expr p_0 = ctx.mkConst("politoNF_"+politoNF+"_p_0", nctx.packet);
+ IntExpr t_0 = ctx.mkIntConst("politoNF_"+politoNF+"_t_0");
+ IntExpr t_1 = ctx.mkIntConst("politoNF_"+politoNF+"_t_1");
+ Expr a_0 = ctx.mkConst(politoNF+"_politoNF_a_0", nctx.address);
+ Expr a_1 = ctx.mkConst(politoNF+"_politoNF_a_1", nctx.address);
+
+ FuncDecl myFunction = ctx.mkFuncDecl(politoNF+"_myFunction", new Sort[]{nctx.address,nctx.address}, ctx.mkBoolSort());
+
+ BoolExpr myConstraint = ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoNF, n_0, p_0, t_0),
+ ctx.mkExists(new Expr[]{n_1, t_1},
+ ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1, politoNF, p_0, t_1),
+ ctx.mkLt(t_1 , t_0),
+ (BoolExpr)myFunction.apply(nctx.pf.get("src").apply(p_0), nctx.pf.get("dest").apply(p_0))),1,null,null,null,null)),1,null,null,null,null);
+
+ BoolExpr funcConstraint = ctx.mkOr(ctx.mkAnd(ctx.mkEq(a_0, ipA), ctx.mkEq(a_1, ipB)), ctx.mkAnd(ctx.mkEq(a_0,ipB), ctx.mkEq(a_1,ipA)));
+
+ // Constraint1 myFunction(a_0,a_1) == ((a_0 == ipA && a_1 == ipB) || (a_0 == ipB && a_1 == ipA))
+ constraints.add(
+ ctx.mkForall(new Expr[]{a_0,a_1},
+ ctx.mkEq(myFunction.apply(a_0, a_1), funcConstraint),1,null,null,null,null));
+
+ //Constraint2 send(politoNF, n_0, p, t_0) ->
+ // (exist n_1,t_1 : (t_1 < t_0 && recv(n_1, politoNF, p, t_1) && myFunction(p.src,p.dest))
+ constraints.add(myConstraint);
+
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return politoNF;
+ }
+
+ } \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoNat.java b/verigraph/service/src/mcnet/netobjs/PolitoNat.java
new file mode 100644
index 0000000..6d8a36d
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoNat.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/**
+ * NAT Model object
+ *
+ */
+public class PolitoNat extends NetworkObject{
+ List<BoolExpr> constraints;
+ Context ctx;
+ DatatypeExpr nat;
+ List<DatatypeExpr> private_addresses;
+ List<NetworkObject> private_node;
+ Network net;
+ NetContext nctx;
+ FuncDecl private_addr_func ;
+
+ public PolitoNat(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ isEndHost=false;
+ constraints = new ArrayList<BoolExpr>();
+ z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ nat = z3Node;
+ net = (Network)args[0][1];
+ nctx = (NetContext)args[0][2];
+ private_addresses = new ArrayList<DatatypeExpr>();
+ private_node = new ArrayList<NetworkObject>();
+ net.saneSend(this);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return nat;
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ /*
+ private void addPrivateAdd(List<DatatypeExpr> address){
+ private_addresses.addAll(address);
+ }
+ */
+
+ public List<DatatypeExpr> getPrivateAddress(){
+ return private_addresses;
+ }
+
+ public void natModel(DatatypeExpr natIp){
+ Expr x = ctx.mkConst("x", nctx.node);
+ Expr y = ctx.mkConst("y", nctx.node);
+ Expr z = ctx.mkConst("z", nctx.node);
+
+ Expr p_0 = ctx.mkConst("p_0", nctx.packet);
+ Expr p_1 = ctx.mkConst("p_1", nctx.packet);
+ Expr p_2 = ctx.mkConst("p_2", nctx.packet);
+
+ IntExpr t_0 = ctx.mkIntConst("t_0");
+ IntExpr t_1 = ctx.mkIntConst("t_1");
+ IntExpr t_2 = ctx.mkIntConst("t_2");
+
+// private_addr_func = ctx.mkFuncDecl("private_addr_func", nctx.address, ctx.mkBoolSort());
+ private_addr_func = ctx.mkFuncDecl(nat + "_nat_func", nctx.address, ctx.mkBoolSort());
+
+ //Constraint1
+// "send(nat, x, p_0, t_0) && !private_addr_func(p_0.dest) ->
+// p_0.src == ip_politoNat &&
+// (exist y, p_1,t_1 :
+// (recv(y, nat, p_1, t_1) && t_1 < t_0 &&
+// private_addr_func(p1.src) &&
+// p_1.origin == p_0.origin &&
+// same for p_1.<dest,orig_body,body,seq,proto,emailFrom,url,options> == p_0.<...>) "
+ constraints.add( ctx.mkForall(new Expr[]{t_0, p_0, x},
+ ctx.mkImplies(
+ ctx.mkAnd((BoolExpr)nctx.send.apply(nat, x, p_0, t_0),
+ ctx.mkNot((BoolExpr)private_addr_func.apply(nctx.pf.get("dest").apply(p_0)))),
+ ctx.mkAnd(
+ ctx.mkEq(nctx.pf.get("src").apply(p_0),natIp),
+ ctx.mkExists(new Expr[]{y, p_1, t_1},
+ ctx.mkAnd(
+ (BoolExpr)nctx.recv.apply(y, nat, p_1, t_1),
+ ctx.mkLt(t_1 , t_0),
+ (BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_1),nctx.pf.get("origin").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_1),nctx.pf.get("dest").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_1),nctx.pf.get("orig_body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("body").apply(p_1),nctx.pf.get("body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("seq").apply(p_1),nctx.pf.get("seq").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_1),nctx.pf.get("proto").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1),nctx.pf.get("emailFrom").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("url").apply(p_1),nctx.pf.get("url").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("options").apply(p_1),nctx.pf.get("options").apply(p_0))),1,null,null,null,null))),1,null,null,null,null));
+
+ //Constraint2
+// send(nat, x, p_0, t_0) && private_addr_func(p_0.dest) ->
+// !private_addr_func(p_0.src) &&
+// (exist y, p_1,t_1 :
+// (recv(y, nat, p_1, t_1) && t_1 < t_0 &&
+// !private_addr_func(p1.src) &&
+// p_1.dest == ip_politoNat &&
+// p_1.origin == p_0.origin &&
+// same for p_1.<src,orig_body,body,seq,proto,emailFrom,url,options> == p_0.<...>)
+ constraints.add( ctx.mkForall(new Expr[]{x, p_0, t_0},
+ ctx.mkImplies(
+ ctx.mkAnd((BoolExpr)nctx.send.apply(nat, x, p_0, t_0),
+ (BoolExpr)private_addr_func.apply(nctx.pf.get("dest").apply(p_0))),
+ ctx.mkAnd(
+ ctx.mkNot((BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_0))),
+ ctx.mkExists(new Expr[]{y, p_1, t_1},
+ ctx.mkAnd(
+ ctx.mkLt(t_1 , t_0),
+ (BoolExpr)nctx.recv.apply(y, nat, p_1, t_1),
+ ctx.mkNot((BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_1))),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_1),natIp),
+ ctx.mkEq(nctx.pf.get("src").apply(p_1),nctx.pf.get("src").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_0),nctx.pf.get("origin").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_1),nctx.pf.get("orig_body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("body").apply(p_1),nctx.pf.get("body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("seq").apply(p_1),nctx.pf.get("seq").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_1),nctx.pf.get("proto").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1),nctx.pf.get("emailFrom").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("url").apply(p_1),nctx.pf.get("url").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("options").apply(p_1),nctx.pf.get("options").apply(p_0)),
+ ctx.mkExists(new Expr[]{z, p_2, t_2},
+ ctx.mkAnd(
+ ctx.mkLt(t_2 , t_1),
+ (BoolExpr)nctx.recv.apply(z, nat, p_2, t_2),
+ (BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_2)),
+ ctx.mkEq(nctx.pf.get("src").apply(p_1),nctx.pf.get("dest").apply(p_2)),
+ ctx.mkEq(nctx.pf.get("src").apply(p_0),nctx.pf.get("dest").apply(p_2)),
+ ctx.mkEq(nctx.pf.get("src").apply(p_2),nctx.pf.get("dest").apply(p_0))),1,null,null,null,null)),1,null,null,null,null))),1,null,null,null,null));
+ }
+
+ public void setInternalAddress(ArrayList<DatatypeExpr> internalAddress){
+ List<BoolExpr> constr = new ArrayList<BoolExpr>();
+ Expr n_0 = ctx.mkConst("nat_node", nctx.address);
+
+ for(DatatypeExpr n : internalAddress){
+ constr.add(ctx.mkEq(n_0,n));
+ }
+ BoolExpr[] constrs = new BoolExpr[constr.size()];
+ //Constraint private_addr_func(n_0) == or(n_0==n foreach internal address)
+ constraints.add(ctx.mkForall(new Expr[]{n_0}, ctx.mkEq(private_addr_func.apply(n_0),ctx.mkOr(constr.toArray(constrs))),1,null,null,null,null));
+ }
+} \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoVpnAccess.java b/verigraph/service/src/mcnet/netobjs/PolitoVpnAccess.java
new file mode 100644
index 0000000..e6fc5fe
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoVpnAccess.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+public class PolitoVpnAccess extends NetworkObject {
+
+ List<BoolExpr> constraints = new ArrayList<BoolExpr>();
+ DatatypeExpr politoVpnAccess;
+ FuncDecl private_addr_func;
+ NetContext nctx;
+ Context ctx;
+ Network net;
+
+ public PolitoVpnAccess(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return politoVpnAccess;
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ this.isEndHost = false;
+ this.politoVpnAccess = this.z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ this.net = (Network)args[0][1];
+ this.nctx = (NetContext)args[0][2];
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ public void vpnAccessModel(DatatypeExpr vpnAccessIp, DatatypeExpr vpnExitIp) {
+ Expr x = ctx.mkConst("vpn_x", nctx.node);
+ Expr y = ctx.mkConst("vpn_y", nctx.node);
+
+ Expr p_0 = ctx.mkConst("vpn_p_0", nctx.packet);
+ Expr p_1 = ctx.mkConst("vpn_p_1", nctx.packet);
+
+ IntExpr t_0 = ctx.mkIntConst("vpn_t_0");
+ IntExpr t_1 = ctx.mkIntConst("vpn_t_1");
+
+ private_addr_func = ctx.mkFuncDecl("vpn_private_addr_func", nctx.address, ctx.mkBoolSort());
+
+ BoolExpr constraint1 = ctx.mkForall(new Expr[]{t_0, p_0, x},
+ ctx.mkImplies(ctx.mkAnd(
+ (BoolExpr)nctx.send.apply(politoVpnAccess, x, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.am.get("null"))),
+ ctx.mkAnd(
+ (BoolExpr)private_addr_func.apply(nctx.pf.get("dest").apply(p_0)),
+ ctx.mkNot((BoolExpr)nctx.pf.get("encrypted").apply(p_0)),
+ ctx.mkExists(new Expr[]{y, p_1, t_1},
+ ctx.mkAnd((BoolExpr)nctx.recv.apply(y, politoVpnAccess, p_1, t_1),
+ ctx.mkLt(t_1, t_0),
+ (BoolExpr)nctx.pf.get("encrypted").apply(p_1),
+ ctx.mkEq(nctx.pf.get("src").apply(p_1), vpnExitIp),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_1), vpnAccessIp),
+ ctx.mkEq(nctx.pf.get("inner_src").apply(p_1), nctx.pf.get("src").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), nctx.pf.get("dest").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_1), nctx.pf.get("origin").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_1), nctx.pf.get("orig_body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("body").apply(p_1), nctx.pf.get("body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("seq").apply(p_1), nctx.pf.get("seq").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_1), nctx.pf.get("proto").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1), nctx.pf.get("emailFrom").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("options").apply(p_1), nctx.pf.get("options").apply(p_0))), 1, null, null, null, null))),
+ 1,null,null,null,null);
+
+ constraints.add(constraint1);
+
+ BoolExpr constraint2 = ctx.mkForall(new Expr[]{t_0, p_0, x},
+ ctx.mkImplies(ctx.mkAnd(
+ (BoolExpr)nctx.send.apply(politoVpnAccess, x, p_0, t_0),
+ ctx.mkNot(ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.am.get("null")))),
+ ctx.mkAnd(
+ ctx.mkEq(nctx.pf.get("src").apply(p_0), vpnAccessIp),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_0), vpnExitIp),
+ (BoolExpr)private_addr_func.apply(nctx.pf.get("inner_src").apply(p_0)),
+ ctx.mkNot(ctx.mkEq(nctx.pf.get("inner_dest").apply(p_0), vpnAccessIp)),
+ (BoolExpr)nctx.pf.get("encrypted").apply(p_0),
+ ctx.mkExists(new Expr[]{y, p_1, t_1},
+ ctx.mkAnd((BoolExpr)nctx.recv.apply(y, politoVpnAccess, p_1, t_1),
+ ctx.mkLt(t_1, t_0),
+ ctx.mkNot((BoolExpr)nctx.pf.get("encrypted").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("src").apply(p_1), nctx.pf.get("inner_src").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_1), nctx.pf.get("inner_dest").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("inner_src").apply(p_1), nctx.am.get("null")),
+ ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), nctx.am.get("null")),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_1), nctx.pf.get("origin").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_1), nctx.pf.get("orig_body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("body").apply(p_1), nctx.pf.get("body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("seq").apply(p_1), nctx.pf.get("seq").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_1), nctx.pf.get("proto").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1), nctx.pf.get("emailFrom").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("options").apply(p_1), nctx.pf.get("options").apply(p_0))), 1, null, null, null, null))),
+ 1,null,null,null,null);
+
+ constraints.add(constraint2);
+ }
+
+ public void setInternalAddress(ArrayList<DatatypeExpr> internalAddress){
+ List<BoolExpr> constr = new ArrayList<BoolExpr>();
+ Expr n_0 = ctx.mkConst("vpn_node", nctx.address);
+
+ for(DatatypeExpr n : internalAddress){
+ constr.add(ctx.mkEq(n_0,n));
+ }
+ BoolExpr[] constrs = new BoolExpr[constr.size()];
+ //Constraint private_addr_func(n_0) == or(n_0==n foreach internal address)
+ constraints.add(ctx.mkForall(new Expr[]{n_0}, ctx.mkEq(private_addr_func.apply(n_0),ctx.mkOr(constr.toArray(constrs))),1,null,null,null,null));
+ }
+
+} \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoVpnExit.java b/verigraph/service/src/mcnet/netobjs/PolitoVpnExit.java
new file mode 100644
index 0000000..fb2341f
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoVpnExit.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+public class PolitoVpnExit extends NetworkObject {
+
+ List<BoolExpr> constraints = new ArrayList<BoolExpr>();
+ DatatypeExpr politoVpnExit;
+ FuncDecl private_addr_func;
+ NetContext nctx;
+ Context ctx;
+ Network net;
+
+ public PolitoVpnExit(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return politoVpnExit;
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ this.isEndHost = false;
+ this.politoVpnExit = this.z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ this.net = (Network)args[0][1];
+ this.nctx = (NetContext)args[0][2];
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ public void vpnAccessModel(DatatypeExpr vpnAccessIp, DatatypeExpr vpnExitIp) {
+ Expr x = ctx.mkConst("vpn_x", nctx.node);
+ Expr y = ctx.mkConst("vpn_y", nctx.node);
+
+ Expr p_0 = ctx.mkConst("vpn_p_0", nctx.packet);
+ Expr p_1 = ctx.mkConst("vpn_p_1", nctx.packet);
+
+ IntExpr t_0 = ctx.mkIntConst("vpn_t_0");
+ IntExpr t_1 = ctx.mkIntConst("vpn_t_1");
+
+ private_addr_func = ctx.mkFuncDecl("vpn_private_addr_func", nctx.address, ctx.mkBoolSort());
+
+ BoolExpr constraint1 = ctx.mkForall(new Expr[]{t_0, p_0, x},
+ ctx.mkImplies(ctx.mkAnd(
+ (BoolExpr)nctx.send.apply(politoVpnExit, x, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.am.get("null"))),
+ ctx.mkAnd(
+ (BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_0)),
+ ctx.mkNot((BoolExpr)nctx.pf.get("encrypted").apply(p_0)),
+ ctx.mkExists(new Expr[]{y, p_1, t_1},
+ ctx.mkAnd((BoolExpr)nctx.recv.apply(y, politoVpnExit, p_1, t_1),
+ ctx.mkLt(t_1, t_0),
+ (BoolExpr)nctx.pf.get("encrypted").apply(p_1),
+ ctx.mkEq(nctx.pf.get("src").apply(p_1), vpnAccessIp),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_1), vpnExitIp),
+ ctx.mkEq(nctx.pf.get("inner_src").apply(p_1), nctx.pf.get("src").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), nctx.pf.get("dest").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_1), nctx.pf.get("origin").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_1), nctx.pf.get("orig_body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("body").apply(p_1), nctx.pf.get("body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("seq").apply(p_1), nctx.pf.get("seq").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_1), nctx.pf.get("proto").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1), nctx.pf.get("emailFrom").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("options").apply(p_1), nctx.pf.get("options").apply(p_0))), 1, null, null, null, null))),
+ 1,null,null,null,null);
+
+ constraints.add(constraint1);
+
+ BoolExpr constraint2 = ctx.mkForall(new Expr[]{t_0, p_0, x},
+ ctx.mkImplies(ctx.mkAnd(
+ (BoolExpr)nctx.send.apply(politoVpnExit, x, p_0, t_0),
+ ctx.mkNot(ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.am.get("null")))),
+ ctx.mkAnd(
+ ctx.mkEq(nctx.pf.get("src").apply(p_0), vpnExitIp),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_0), vpnAccessIp),
+ (BoolExpr)private_addr_func.apply(nctx.pf.get("dest").apply(p_0)),
+ ctx.mkNot(ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), vpnExitIp)),
+ (BoolExpr)nctx.pf.get("encrypted").apply(p_0),
+ ctx.mkExists(new Expr[]{y, p_1, t_1},
+ ctx.mkAnd((BoolExpr)nctx.recv.apply(y, politoVpnExit, p_1, t_1),
+ ctx.mkLt(t_1, t_0),
+ ctx.mkNot((BoolExpr)nctx.pf.get("encrypted").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("src").apply(p_1), nctx.pf.get("inner_src").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_1), nctx.pf.get("inner_dest").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("inner_src").apply(p_1), nctx.am.get("null")),
+ ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), nctx.am.get("null")),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_1), nctx.pf.get("origin").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_1), nctx.pf.get("orig_body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("body").apply(p_1), nctx.pf.get("body").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("seq").apply(p_1), nctx.pf.get("seq").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_1), nctx.pf.get("proto").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1), nctx.pf.get("emailFrom").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0)),
+ ctx.mkEq(nctx.pf.get("options").apply(p_1), nctx.pf.get("options").apply(p_0))), 1, null, null, null, null))),
+ 1,null,null,null,null);
+
+ constraints.add(constraint2);
+ }
+
+ public void setInternalAddress(ArrayList<DatatypeExpr> internalAddress){
+ List<BoolExpr> constr = new ArrayList<BoolExpr>();
+ Expr n_0 = ctx.mkConst("vpn_node", nctx.address);
+
+ for(DatatypeExpr n : internalAddress){
+ constr.add(ctx.mkEq(n_0,n));
+ }
+ BoolExpr[] constrs = new BoolExpr[constr.size()];
+ //Constraint private_addr_func(n_0) == or(n_0==n foreach internal address)
+ constraints.add(ctx.mkForall(new Expr[]{n_0}, ctx.mkEq(private_addr_func.apply(n_0),ctx.mkOr(constr.toArray(constrs))),1,null,null,null,null));
+ }
+
+} \ No newline at end of file
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoWebClient.java b/verigraph/service/src/mcnet/netobjs/PolitoWebClient.java
new file mode 100644
index 0000000..28e2cf2
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoWebClient.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+
+/**
+ * WebClient
+ */
+public class PolitoWebClient extends NetworkObject{
+
+ List<BoolExpr> constraints;
+ Context ctx;
+ DatatypeExpr politoWebClient;
+ Network net;
+ NetContext nctx;
+ FuncDecl isInBlacklist;
+
+ public PolitoWebClient(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ isEndHost=true;
+ constraints = new ArrayList<BoolExpr>();
+ z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ politoWebClient = z3Node;
+ net = (Network)args[0][1];
+ nctx = (NetContext)args[0][2];
+ DatatypeExpr ipServer = (DatatypeExpr) args[0][3];
+ webClientRules(ipServer);
+ //net.saneSend(this);
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return politoWebClient;
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+// System.out.println("[MailClient] Installing rules.");
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ private void webClientRules (DatatypeExpr ipServer){
+ Expr n_0 = ctx.mkConst("PolitoWebClient_"+politoWebClient+"_n_0", nctx.node);
+ Expr p_0 = ctx.mkConst("PolitoWebClient_"+politoWebClient+"_p_0", nctx.packet);
+ IntExpr t_0 = ctx.mkIntConst("PolitoWebClient_"+politoWebClient+"_t_0");
+
+ //Constraint1 send(politoWebClient, n_0, p, t_0) -> nodeHasAddr(politoWebClient,p.src)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0),
+ (BoolExpr)nctx.nodeHasAddr.apply(politoWebClient,nctx.pf.get("src").apply(p_0))),1,null,null,null,null));
+
+ //Constraint2 send(politoWebClient, n_0, p, t_0) -> p.origin == politoWebClient
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_0),politoWebClient)),1,null,null,null,null));
+
+ //Constraint3 send(politoWebClient, n_0, p, t_0) -> p.orig_body == p.body
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null));
+
+ //Constraint4 recv(n_0, politoWebClient, p, t_0) -> nodeHasAddr(politoWebClient,p.dest)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,politoWebClient, p_0, t_0),
+ (BoolExpr)nctx.nodeHasAddr.apply(politoWebClient,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null));
+
+
+ //Constraint5 This client is only able to produce HTTP requests
+ // send(politoWebClient, n_0, p, t_0) -> p.proto == HTTP_REQ
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST))),1,null,null,null,null));
+
+ //Constraint6 send(politoWebClient, n_0, p, t_0) -> p.dest == ipServer
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_0), ipServer)),1,null,null,null,null));
+ }
+ }
diff --git a/verigraph/service/src/mcnet/netobjs/PolitoWebServer.java b/verigraph/service/src/mcnet/netobjs/PolitoWebServer.java
new file mode 100644
index 0000000..54710d9
--- /dev/null
+++ b/verigraph/service/src/mcnet/netobjs/PolitoWebServer.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package mcnet.netobjs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.microsoft.z3.BoolExpr;
+import com.microsoft.z3.Context;
+import com.microsoft.z3.DatatypeExpr;
+import com.microsoft.z3.Expr;
+import com.microsoft.z3.FuncDecl;
+import com.microsoft.z3.IntExpr;
+import com.microsoft.z3.Solver;
+
+import mcnet.components.NetContext;
+import mcnet.components.Network;
+import mcnet.components.NetworkObject;
+/**
+ * WebServer object
+ *
+ */
+public class PolitoWebServer extends NetworkObject{
+
+ List<BoolExpr> constraints;
+ Context ctx;
+ DatatypeExpr node;
+ Network net;
+ NetContext nctx;
+ FuncDecl isInBlacklist;
+
+ public PolitoWebServer(Context ctx, Object[]... args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void init(Context ctx, Object[]... args) {
+ this.ctx = ctx;
+ isEndHost=true;
+ constraints = new ArrayList<BoolExpr>();
+ z3Node = ((NetworkObject)args[0][0]).getZ3Node();
+ node = z3Node;
+ net = (Network)args[0][1];
+ nctx = (NetContext)args[0][2];
+ webServerRules();
+ }
+
+ @Override
+ public DatatypeExpr getZ3Node() {
+ return node;
+ }
+
+ @Override
+ protected void addConstraints(Solver solver) {
+ BoolExpr[] constr = new BoolExpr[constraints.size()];
+ solver.add(constraints.toArray(constr));
+ }
+
+ private void webServerRules (){
+ Expr n_0 = ctx.mkConst("webserver_"+node+"_n_0", nctx.node);
+ Expr p_0 = ctx.mkConst("webserver_"+node+"_p_0", nctx.packet);
+ Expr p_1 = ctx.mkConst("webserver_"+node+"_p_1", nctx.packet);
+ IntExpr t_0 = ctx.mkIntConst("webserver_"+node+"_t_0");
+ IntExpr t_1 = ctx.mkIntConst("webserver_"+node+"_t_1");
+
+ //Constraint1 send(politoWebServer, n_0, p, t_0) -> nodeHasAddr(politoWebServer,p.src)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0),
+ (BoolExpr)nctx.nodeHasAddr.apply(node,nctx.pf.get("src").apply(p_0))),1,null,null,null,null));
+
+ //Constraint2 send(politoWebServer, n_0, p, t_0) -> p.origin == politoWebServer
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("origin").apply(p_0),node)),1,null,null,null,null));
+
+ //Constraint3 send(politoWebServer, n_0, p, t_0) -> p.orig_body == p.body
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0),
+ ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),
+ 1,null,null,null,null));
+
+ //Constraint4 recv(n_0, politoWebServer, p, t_0) -> nodeHasAddr(politoWebServer,p.dest)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,node, p_0, t_0),
+ (BoolExpr)nctx.nodeHasAddr.apply(node,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null));
+
+ //Constraint5
+ // send(politoWebServer, n_0, p, t_0) ->
+ // (exist p_1,t_1 :
+ // (t_1 < t_0 && recv(n_0, politoWebServer, p_1, t_1) &&
+ // p_0.proto == HTTP_RESP && p_1.proto == HTTP_REQ &&
+ // p_0.dest == p_1.src && p_0.src == p_1.dest && p_0.url == p_1.url)
+ constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0},
+ ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0),
+ ctx.mkExists(new Expr[]{p_1, t_1},
+ ctx.mkAnd(
+ ctx.mkLt(t_1, t_0),
+ ctx.mkEq(nctx.pf.get("url").apply(p_0), nctx.pf.get("url").apply(p_1)),
+ (BoolExpr)nctx.recv.apply(n_0, node, p_1, t_1),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_RESPONSE)),
+ ctx.mkEq(nctx.pf.get("proto").apply(p_1), ctx.mkInt(nctx.HTTP_REQUEST)),
+ ctx.mkEq(nctx.pf.get("dest").apply(p_0), nctx.pf.get("src").apply(p_1)),
+ ctx.mkEq(nctx.pf.get("src").apply(p_0), nctx.pf.get("dest").apply(p_1))),
+ 1,null,null,null,null)),1,null,null,null,null));
+ }
+}
diff --git a/verigraph/service/src/tests/j-verigraph-generator/README.rst b/verigraph/service/src/tests/j-verigraph-generator/README.rst
new file mode 100644
index 0000000..c796af7
--- /dev/null
+++ b/verigraph/service/src/tests/j-verigraph-generator/README.rst
@@ -0,0 +1,54 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+CODE\_GENERATOR Java serializer and formatter
+
+UTILITY Contains utility methods used by other modules
+
+JSON\_GENERATOR Interactive module to generate the configuration files
+(default names are "chains.json" and "config.json") "chains.json"
+describes all the chains of nodes belonging to a certain scenario
+
+TEST\_CLASS\_GENERATOR Generates one or multiple test scenarios given
+the two configuration files above (default names are "chains.json" and
+"config.json") All the test scenarios have to be placed in the examples
+folder (i. e. under "j-verigraph/service/src/tests/examples"). Here is
+the script help:
+
+test\_class\_generator.py -c -f -o
+
+Supposing the module gets executed from the project root directory (i.e.
+"j-verigraph"), a sample command is the following:
+
+service/src/tests/j-verigraph-generator/test\_class\_generator.py -c
+"service/src/tests/j-verigraph-generator/examples/budapest/chains.json"
+-f
+"service/src/tests/j-verigraph-generator/examples/budapest/config.json"
+-o "service/src/tests/examples/Scenario"
+
+Keep in mind that in the previous command "Scenario" represents a prefix
+which will be followed by an underscore and an incremental number
+starting from 1, which represents the n-th scenario starting from the
+previously mentioned "chains.json" file (this file can indeed contain
+multiple chains).
+
+TEST\_GENERATOR Generates a file which performs the verification test
+through Z3 (theorem prover from Microsoft Research) given a certain
+scenario generated with the above snippet. All the test modules have to
+be placed under the "tests" directory (i.e. under
+"j-verigraph/service/src/tests"). Here is the module help:
+
+test\_generator.py -i -o -s -d
+
+Supposing the module gets executed from the project root directory (i.e.
+"j-verigraph") a sample command given the previously generated scenario
+is the following:
+
+service/src/tests/j-verigraph-generator/test\_generator.py -i
+service/src/tests/examples/Scenario\_1.java -o
+service/src/tests/Test.java -s user1 -d webserver
+
+The aforementioned "Test.java" file can be compiled and executed
+normally. Its output will be either "SAT" or "UNSAT". For possible
+statistics the test is repeated 10 times and the average execution time
+in seconds is printed to the console.
diff --git a/verigraph/service/src/tests/j-verigraph-generator/__init__.py b/verigraph/service/src/tests/j-verigraph-generator/__init__.py
new file mode 100644
index 0000000..d8a620f
--- /dev/null
+++ b/verigraph/service/src/tests/j-verigraph-generator/__init__.py
@@ -0,0 +1,8 @@
+##############################################################################
+# Copyright (c) 2017 Politecnico di Torino and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
diff --git a/verigraph/service/src/tests/j-verigraph-generator/batch_generator.py b/verigraph/service/src/tests/j-verigraph-generator/batch_generator.py
new file mode 100644
index 0000000..517bdf7
--- /dev/null
+++ b/verigraph/service/src/tests/j-verigraph-generator/batch_generator.py
@@ -0,0 +1,186 @@
+#!/usr/bin/python
+
+##############################################################################
+# Copyright (c) 2017 Politecnico di Torino and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import json
+from pprint import pprint
+import sys, getopt
+import commands
+import os
+from config import *
+from utility import *
+import subprocess
+
+#global variables
+chains = {}
+chains["chains"] = []
+routing = {}
+routing["routing_table"] = []
+configuration = {}
+configuration["nodes"] = []
+#end of global variables
+
+
+#generates json file describing the chains (default chains.json)
+def generate_chains(curr_dir, multiplier, flowspace):
+ filename = "chains.json"
+
+ multiplier = int(multiplier)
+ number_of_chains = multiplier*multiplier
+ for i in range(0, int(number_of_chains)):
+ chains["chains"].insert(i, {})
+ chains["chains"][i]["id"] = i+1
+ chains["chains"][i]["flowspace"] = flowspace
+ chain_nodes = multiplier
+ chains["chains"][i]["nodes"] = []
+ #set attributes for nth client
+ chains["chains"][i]["nodes"].insert(0, {})
+ node_name = "client_" + str((i%multiplier)+1)
+ chains["chains"][i]["nodes"][0]["name"] = node_name
+ node_type = "web_client"
+ chains["chains"][i]["nodes"][0]["functional_type"] = node_type
+ node_address = "ip_web_client_" + str((i%multiplier)+1)
+ chains["chains"][i]["nodes"][0]["address"] = node_address
+ #set attributes for chain of firewalls
+ for j in range(1, chain_nodes+1):
+ chains["chains"][i]["nodes"].insert(j, {})
+ node_name = "firewall_" + str(j)
+ chains["chains"][i]["nodes"][j]["name"] = node_name
+ node_type = "firewall"
+ chains["chains"][i]["nodes"][j]["functional_type"] = node_type
+ node_address = "ip_firewall_" + str(j)
+ chains["chains"][i]["nodes"][j]["address"] = node_address
+ #set attributes for nth web server
+ chains["chains"][i]["nodes"].insert(chain_nodes+1, {})
+ node_name = "server_" + str((i%multiplier)+1)
+ chains["chains"][i]["nodes"][chain_nodes+1]["name"] = node_name
+ node_type = "web_server"
+ chains["chains"][i]["nodes"][chain_nodes+1]["functional_type"] = node_type
+ node_address = "ip_web_server_" + str((i%multiplier)+1)
+ chains["chains"][i]["nodes"][chain_nodes+1]["address"] = node_address
+ #pprint(chains)
+ with smart_open(curr_dir + "/" + filename) as f:
+ print >>f, json.dumps(chains)
+ return filename
+
+#generates json file describing the node configurations (default config.json)
+def generate_config(curr_dir):
+ chains_file = "chains.json"
+
+ chains = parse_chains(curr_dir + "/" + chains_file)
+
+ print "Chains read from file:"
+ pprint(chains)
+ chains_id = []
+
+ for chain_id, chain in chains.items():
+ chains_id.append(chain_id)
+ print "Chain #" + str(chain_id) + " has " + str(len(chain)) + " elements"
+ for node_name in chain.keys():
+ print node_name + " ",
+ print ""
+
+
+ filename = "config.json"
+
+ config_names = []
+
+ i = -1
+
+ for number_of_chain in chains_id:
+ number_of_nodes = len(chains[number_of_chain].keys())
+
+ # for i in range(0, number_of_nodes):
+
+ for node_name, node_map in chains[number_of_chain].items():
+ if node_name in config_names:
+ continue
+ config_names.append(node_name)
+ i += 1
+ configuration["nodes"].insert(i, {})
+ # node_id = raw_input("Node #" + str(i+1) + " id? -->")
+ # configuration["nodes"][i]["id"] = node_id
+ configuration["nodes"][i]["id"] = node_name
+
+ name_split = node_name.split("_")
+
+ #init = raw_input("Any parameter for inizialization of node " + node_name + "? (N/Y)-->")
+ init_list = devices_initialization[node_map["functional_type"]]
+ if init_list != []:
+ for init_item in init_list:
+ init_param = "ip_" + init_item + "_" + name_split[1]
+ configuration["nodes"][i][init_item] = init_param
+
+ node_description = name_split[0] + " denies any traffic from web_client #" + name_split[1] + " to web_server #" + name_split[1]
+ configuration["nodes"][i]["description"] = node_description
+ while(True):
+ #node_configuration_type = raw_input("Node " + node_id +"'s configuration type (list, maps)? (L/M) -->")
+ #n = search_node_in_chains(node_id)
+
+ node_configuration_type = devices_configuration_methods[node_map["functional_type"]]
+ if node_configuration_type == "list":
+ #list
+ configuration["nodes"][i]["configuration"] = []
+
+ break
+ if node_configuration_type == "maps":
+ #maps
+ configuration["nodes"][i]["configuration"] = []
+ n_entries = 1
+
+ for m in range(0, n_entries):
+ configuration["nodes"][i]["configuration"].insert(m, {})
+
+ map_elements = 1
+
+ for n in range(0, map_elements):
+ key = "ip_web_server_" + name_split[1]
+ value = "ip_web_client_" + name_split[1]
+ configuration["nodes"][i]["configuration"][m][key] = value
+ break
+ else:
+ print "Invalid config, please edit the config file"
+ #pprint(configuration)
+ with smart_open(curr_dir + "/" + filename) as f:
+ print >>f, json.dumps(configuration)
+ return filename
+
+def main(argv):
+ #exit if any command line argument is missing
+ if len(argv) < 4:
+ print 'batch_generator.py -m <multiplier> -o <output_directory>'
+ sys.exit(2)
+ #initialize json file names
+ chains_file = ''
+ configuration_file = ''
+ output_dir = ''
+ multiplier = ''
+ #parse command line arguments and exit if there is an error
+ try:
+ opts, args = getopt.getopt(argv,"hm:o:",["mutliplier=","help","odir="])
+ except getopt.GetoptError as err:
+ print str(err)
+ print 'batch_generator.py -m <multiplier> -o <output_directory>'
+ sys.exit(2)
+ for opt, arg in opts:
+ if opt in ("-h", "--help"):
+ print 'batch_generator.py -m <multiplier> -o <output_directory>'
+ sys.exit()
+ elif opt in ("-o", "--output"):
+ output_dir = arg
+ elif opt in ("-m", "--multiplier"):
+ multiplier = arg
+
+ generate_chains(output_dir, multiplier, "tcp=80")
+ generate_config(output_dir)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/verigraph/service/src/tests/j-verigraph-generator/code_generator.py b/verigraph/service/src/tests/j-verigraph-generator/code_generator.py
new file mode 100644
index 0000000..5b9834f
--- /dev/null
+++ b/verigraph/service/src/tests/j-verigraph-generator/code_generator.py
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+
+##############################################################################
+# Copyright (c) 2017 Politecnico di Torino and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import sys, string
+
+class CodeGeneratorBackend:
+
+ def begin(self, tab="\t"):
+ self.code = []
+ self.tab = tab
+ self.level = 0
+
+ def end(self):
+ return string.join(self.code, "")
+
+ def write(self, string):
+ self.code.append(self.tab * self.level + string)
+
+ def writeln(self, string):
+ self.code.append(self.tab * self.level + string + "\n")
+
+ def append(self, string):
+ self.code.append(string)
+
+ def indent(self):
+ self.level = self.level + 1
+
+ def dedent(self):
+ if self.level == 0:
+ raise SyntaxError, "internal error in code generator"
+ self.level = self.level - 1
+
+ def write_list(self, data, delimiter=True, wrapper="'"):
+ if delimiter == True:
+ self.code.append("{")
+ first = True
+ for element in data:
+ if (first == False):
+ self.code.append(", ")
+ else:
+ first = False
+ if wrapper == "'":
+ self.code.append("'" + str(element) + "'")
+ elif wrapper == "\"":
+ self.code.append("\"" + str(element) + "\"")
+ elif wrapper == "b":
+ self.code.append("(" + str(element) + ")")
+ else:
+ self.code.append(str(element))
+ if delimiter == True:
+ self.code.append("}")
diff --git a/verigraph/service/src/tests/j-verigraph-generator/config.py b/verigraph/service/src/tests/j-verigraph-generator/config.py
new file mode 100644
index 0000000..3fe5d6c
--- /dev/null
+++ b/verigraph/service/src/tests/j-verigraph-generator/config.py
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+
+##############################################################################
+# Copyright (c) 2017 Politecnico di Torino and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+devices_to_classes = { "webclient" : "PolitoWebClient",
+ "webserver" : "PolitoWebServer",
+ "cache" : "PolitoCache",
+ "nat" : "PolitoNat",
+ "firewall" : "AclFirewall",
+ "mailclient" : "PolitoMailClient",
+ "mailserver" : "PolitoMailServer",
+ "antispam" : "PolitoAntispam",
+ "endpoint": "EndHost",
+ "dpi": "PolitoIDS",
+ "endhost": "PolitoEndHost",
+ "vpnaccess":"PolitoVpnAccess",
+ "vpnexit":"PolitoVpnExit",
+ "fieldmodifier":"PolitoFieldModifier"
+ }
+devices_to_configuration_methods = {"webclient" : "",
+ "webserver" : "",
+ "cache" : "installCache",
+ "nat" : "setInternalAddress",
+ "firewall" : "addAcls",
+ "mailclient" : "",
+ "mailserver" : "",
+ "antispam" : "",
+ "endpoint": "",
+ "dpi": "installIDS",
+ "endhost": "installEndHost",
+ "vpnaccess":"vpnAccessModel",
+ "vpnexit":"vpnAccessModel",
+ "fieldmodifier":"installFieldModifier"
+ }
+devices_initialization = { "webclient" : ["webserver"],
+ "webserver" : [],
+ "cache" : [],
+ "nat" : [],
+ "firewall" : [],
+ "mailclient" : ["mailserver"],
+ "mailserver" : [],
+ "antispam" : [],
+ "endpoint": [],
+ "dpi":[] ,
+ "endhost":[],
+ "vpnaccess":[],
+ "vpnexit":[],
+ "fieldmodifier":[]
+ }
+
+convert_configuration_property_to_ip = { "webclient" : ["value"],
+ "webserver" : [],
+ "cache" : ["value"],
+ "nat" : ["value"],
+ "firewall" : ["key", "value"],
+ "mailclient" : ["value"],
+ "mailserver" : [],
+ "antispam" : [],
+ "endpoint": [],
+ "dpi": [],
+ "endhost": [],
+ "vpnaccess": ["value"],
+ "vpnexit": ["value"],
+ "fieldmodifier": []
+ }
+
+devices_configuration_fields = { "webclient" : "",
+ "webserver" : "",
+ "cache" : "cached address",
+ "nat" : "natted address",
+ "firewall" : "acl entry",
+ "mailclient" : "",
+ "mailserver" : "",
+ "antispam" : "",
+ "endpoint": "",
+ "dpi":"words blacklist",
+ "endhost":"",
+ "vpnaccess":"vpn access",
+ "vpnexit":"vpn exit",
+ "fieldmodifier":"field modifier"
+ }
diff --git a/verigraph/service/src/tests/j-verigraph-generator/json_generator.py b/verigraph/service/src/tests/j-verigraph-generator/json_generator.py
new file mode 100644
index 0000000..d65ea43
--- /dev/null
+++ b/verigraph/service/src/tests/j-verigraph-generator/json_generator.py
@@ -0,0 +1,261 @@
+#!/usr/bin/python
+
+##############################################################################
+# Copyright (c) 2017 Politecnico di Torino and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import json
+from pprint import pprint
+import sys
+import commands
+import os
+from config import *
+from utility import *
+import batch_generator
+import subprocess
+
+#global variables
+chains = {}
+chains["chains"] = []
+routing = {}
+routing["routing_table"] = []
+configuration = {}
+configuration["nodes"] = []
+#end of global variables
+
+
+
+#generates json file describing the chains (default chains.json)
+def generate_chains(curr_dir):
+ filename = "chains.json"
+ fn = raw_input("Please enter a file name for the json file describing the nodes chains (default \"chains.json\") -->")
+ if fn != "":
+ filename = fn
+
+ number_of_chains = check_input_is_int("Please enter the number of chains you wish to simulate: -->")
+ for i in range(0, int(number_of_chains)):
+ chains["chains"].insert(i, {})
+ #decomment the following 2 lines to make chain id an arbitrary integer
+ #chain_id = check_input_is_int("Chain #" + str(i+1) + " id? -->")
+ #chains["chains"][i]["id"] = chain_id
+ chains["chains"][i]["id"] = i+1
+ flowspace = raw_input("Chain #" + str(i+1) + " flowspace? -->")
+ chains["chains"][i]["flowspace"] = flowspace
+ chain_nodes = check_input_is_int("How many nodes does the chain #" + str(i+1) + " have? -->")
+ chains["chains"][i]["nodes"] = []
+ for j in range(0, chain_nodes):
+ chains["chains"][i]["nodes"].insert(j, {})
+ node_name = raw_input("Node #" + str(j+1) + " name? -->")
+ chains["chains"][i]["nodes"][j]["name"] = node_name
+ print "Available functional types are:"
+ for device in devices_to_classes.keys():
+ print device + " ",
+ while True:
+ node_type = raw_input("Node #" + str(j+1) + " functional_type (see valid options above)? -->")
+ if node_type in devices_to_classes.keys():
+ break
+ chains["chains"][i]["nodes"][j]["functional_type"] = node_type
+ node_address = raw_input("Node #" + str(j+1) + " address? -->")
+ chains["chains"][i]["nodes"][j]["address"] = node_address
+ #pprint(chains)
+ with smart_open(curr_dir + "/" + filename) as f:
+ print >>f, json.dumps(chains)
+ return filename
+
+#generates json file describing the node configurations (default config.json)
+def generate_config(curr_dir):
+ chains_file = "chains.json"
+ while True:
+ list_files(curr_dir)
+ fn = raw_input("Please enter the file name of the json file containing the chains (default \"chains.json\") -->")
+ if fn != "":
+ chains_file = fn
+ try:
+ chains = parse_chains(curr_dir + "/" + chains_file)
+ except:
+ print "Chains file is not valid"
+ continue
+ break
+ print "Chains read from file:"
+ pprint(chains)
+ chains_id = []
+
+ for chain_id, chain in chains.items():
+ chains_id.append(chain_id)
+ print "Chain #" + str(chain_id) + " has " + str(len(chain)) + " elements"
+ for node_name in chain.keys():
+ print node_name + " ",
+ print ""
+
+ while True:
+ number_of_chain = check_input_is_int("Please enter the number of the chain you wish to configure: -->")
+ if number_of_chain in chains_id:
+ break
+ else:
+ print "Please enter a valid chain id (see options above)"
+
+ filename = "config.json"
+ fn = raw_input("Please enter a file name for the json file describing the nodes configuration (default \"config.json\") -->")
+ if fn != "":
+ filename = fn
+
+ number_of_nodes = len(chains[number_of_chain].keys())
+
+# for i in range(0, number_of_nodes):
+ i = -1
+ for node_name, node_map in chains[number_of_chain].items():
+ i += 1
+ configuration["nodes"].insert(i, {})
+# node_id = raw_input("Node #" + str(i+1) + " id? -->")
+# configuration["nodes"][i]["id"] = node_id
+ configuration["nodes"][i]["id"] = node_name
+ #init = raw_input("Any parameter for inizialization of node " + node_name + "? (N/Y)-->")
+ init_list = devices_initialization[node_map["functional_type"]]
+ if init_list != []:
+ for init_item in init_list:
+ init_param = raw_input("Please enter the IP address of parameter \"" + init_item + "\" for node " + node_name + ": -->")
+ configuration["nodes"][i][init_item] = init_param
+
+ node_description = raw_input("Node " + node_name +"'s configuration description? -->")
+ configuration["nodes"][i]["description"] = node_description
+ while(True):
+ #node_configuration_type = raw_input("Node " + node_id +"'s configuration type (list, maps)? (L/M) -->")
+ #n = search_node_in_chains(node_id)
+
+ node_configuration_type = devices_configuration_methods[node_map["functional_type"]]
+ if node_configuration_type == "list":
+ #list
+ configuration["nodes"][i]["configuration"] = []
+ config_elements = check_input_is_int("How many configuration elements for node " + node_name + "? (type 0 to skip configuration) -->")
+ for e in range(0, config_elements):
+ element = raw_input("\tPlease enter " + devices_configuration_fields[node_map["functional_type"]] + "#" + str(e+1) + " -->")
+ configuration["nodes"][i]["configuration"].append(element)
+ break
+ elif node_configuration_type == "maps":
+ #maps
+ configuration["nodes"][i]["configuration"] = []
+ n_entries = check_input_is_int("How many maps for the configuration of node " + node_name + "? (type 0 to skip configuration) -->")
+
+ for m in range(0, n_entries):
+ configuration["nodes"][i]["configuration"].insert(m, {})
+
+ map_elements = check_input_is_int("How many elements for map #" + str(m+1) + "? -->")
+
+ for n in range(0, map_elements):
+ key = raw_input("\tKey for " + devices_configuration_fields[node_map["functional_type"]] + "#" + str(n+1) + ": -->")
+ value = raw_input("\tValue for " + devices_configuration_fields[node_map["functional_type"]] + "#" + str(n+1) + ": -->")
+ configuration["nodes"][i]["configuration"][m][key] = value
+ break
+ else:
+ print "Invalid config, please edit the config file"
+ #pprint(configuration)
+ with smart_open(curr_dir + "/" + filename) as f:
+ print >>f, json.dumps(configuration)
+ return filename
+
+
+def main():
+
+ chains_file = ""
+ configuration_file = ""
+ routing_file = ""
+ curr_dir = os.getcwd()
+ current_path = curr_dir
+
+ set_dir = raw_input("Change working directory? (" + curr_dir + ") (N/Y) -->")
+ if set_dir == "Y" or set_dir == "y":
+ print "List of subdirectories:"
+ print list_directories(curr_dir)
+ while True:
+ curr_dir = os.path.abspath(raw_input("Enter working path (relative or absolute path are supported) -->"))
+ if os.path.exists(curr_dir):
+ current_path = curr_dir
+ break
+ else:
+ print "Please enter a valid path!"
+
+ directory = raw_input("Do you want to create a new test directory? (N/Y) -->")
+ if directory == "Y" or directory =="y":
+ directory_name = raw_input("Directory name? -->")
+ print commands.getoutput("mkdir -v " + curr_dir + "/" + directory_name)
+ current_path = curr_dir + "/" + directory_name
+
+ print "Files will be created at " + current_path
+
+ firewall_chain = False
+
+ while True:
+ choice = raw_input("""CHAINS?\n
+ Choose one of the following options:\n
+ 1) Automatic generation of chains.json and config.json for an N-firewall chain
+ 2) Generate step-by-step
+ 3) Verify the integrity of an existing json file
+ 4) Skip step\n-->""")
+ try:
+ if int(choice) == 1:
+ multiplier = check_input_is_int("Please enter N -->")
+ arguments = ["-m", str(multiplier), "-o", current_path]
+ batch_generator.main(arguments)
+ firewall_chain = True
+ break
+ elif int(choice) == 2:
+ chains_file = generate_chains(current_path)
+ break
+ elif int(choice) == 3:
+ chains_file = raw_input("Input file for CHAINS? -->")
+ if(check_chains_integrity(current_path + "/" + chains_file)) == True:
+ break
+ else:
+ print "Input json file for CHAINS not well formed, please try again!"
+ elif int(choice) == 4:
+ break
+ else:
+ print "Invalid choice, please try again!"
+ except ValueError, e:
+ print "Invalid choice, please try again!"
+ continue
+
+ while True:
+
+ if firewall_chain == True:
+ chains_file = "chains.json"
+ configuration_file = "config.json"
+ routing_file = ""
+ break
+
+ choice = raw_input("""CONFIGURATION?\n
+ Choose one of the following options:\n
+ 1) Generate step-by-step
+ 2) Verify the integrity of an existing json file
+ 3) Skip step\n-->""")
+ try:
+ if int(choice) == 1:
+ configuration_file = generate_config(current_path)
+ break
+ elif int(choice) == 2:
+ configuration_file = raw_input("Input file for CONFIGURATION? -->")
+ if(check_config_integrity(current_path + "/" + configuration_file)) == True:
+ break
+ else:
+ print "Input json file for CONFIGURATION not well formed, please try again!"
+ elif int(choice) == 3:
+ break
+ else:
+ print "Invalid choice, please try again!"
+ except ValueError, e:
+ print "Invalid choice, please try again!"
+ continue
+
+ print "All done, you are ready to launch the test generator like so:"
+ print "test_class_generator.py -c " + chains_file + " -f " + configuration_file + " -o <output_file>"
+
+ return chains_file, configuration_file, routing_file, current_path
+
+
+if __name__ == "__main__":
+ main()
diff --git a/verigraph/service/src/tests/j-verigraph-generator/routing_generator.py b/verigraph/service/src/tests/j-verigraph-generator/routing_generator.py
new file mode 100644
index 0000000..c8956f2
--- /dev/null
+++ b/verigraph/service/src/tests/j-verigraph-generator/routing_generator.py
@@ -0,0 +1,80 @@
+#!/usr/bin/python
+
+##############################################################################
+# Copyright (c) 2017 Politecnico di Torino and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from pprint import pprint
+import sys, getopt
+import os
+from utility import *
+
+# used by test_class_generator
+def generate_routing_from_chain(chain):
+ routing = {}
+ routing["routing_table"] = {}
+
+ chain = chain["nodes"]
+ for i in range(0, len(chain)):
+ routing["routing_table"][chain[i]["name"]] = {}
+ for j in range(i-1, -1, -1):
+ routing["routing_table"][chain[i]["name"]][chain[j]["address"]] = chain[i-1]["name"]
+ for k in range (i+1, len(chain)):
+ routing["routing_table"][chain[i]["name"]][chain[k]["address"]] = chain[i+1]["name"]
+ pprint(routing)
+ return routing
+
+def generate_routing_from_chains_file(chains_file, chain_number):
+ routing = {}
+ routing["routing_table"] = {}
+
+ chains = convert_unicode_to_ascii(parse_json_file(chains_file))
+ chain = None
+ for chn in chains["chains"]:
+ if chn["id"] == chain_number:
+ chain = chn["nodes"]
+ break
+ if chain == None:
+ return routing
+
+ for i in range(0, len(chain)):
+ routing["routing_table"][chain[i]["name"]] = {}
+ for j in range(i-1, -1, -1):
+ routing["routing_table"][chain[i]["name"]][chain[j]["address"]] = chain[i-1]["name"]
+ for k in range (i+1, len(chain)):
+ routing["routing_table"][chain[i]["name"]][chain[k]["address"]] = chain[i+1]["name"]
+ pprint(routing)
+ return routing
+
+def main(argv):
+ if len(argv) < 4:
+ print 'routing_generator.py -c <chains_file> -n <chain_number>'
+ sys.exit(2)
+ chains_file = ""
+ chain_number = ""
+ try:
+ opts, args = getopt.getopt(argv,"hc:n:",["chains=","id="])
+ except getopt.GetoptError:
+ print 'routing_generator.py -c <chains_file> -n <chain_number>'
+ sys.exit(2)
+ for opt, arg in opts:
+ if opt == '-h':
+ print 'routing_generator.py -c <chains_file> -n <chain_number>'
+ sys.exit()
+ elif opt in ("-c", "--chains"):
+ chains_file = arg
+ elif opt in ("-n", "--id"):
+ chain_number = arg
+
+ print "Chains file is " + chains_file
+ print "Chain id is " + chain_number
+
+ return generate_routing_from_chains_file(chains_file, chain_number)
+
+if __name__ == '__main__':
+ main(sys.argv[1:]) \ No newline at end of file
diff --git a/verigraph/service/src/tests/j-verigraph-generator/test_class_generator.py b/verigraph/service/src/tests/j-verigraph-generator/test_class_generator.py
new file mode 100644
index 0000000..7bf446c
--- /dev/null
+++ b/verigraph/service/src/tests/j-verigraph-generator/test_class_generator.py
@@ -0,0 +1,399 @@
+#!/usr/bin/python
+
+##############################################################################
+# Copyright (c) 2017 Politecnico di Torino and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from pprint import pprint
+from pprint import pformat
+import sys, getopt
+from code_generator import CodeGeneratorBackend
+import os, errno
+from config import *
+from utility import *
+from routing_generator import *
+import logging
+from pip._vendor.pkg_resources import null_ns_handler
+
+#generates a custom test file
+def generate_test_file(chain, number, configuration, output_file="test_class"):
+
+ route = {}
+ config = {}
+ chn = {}
+
+ #initiatlize the config dictionary for each node
+ for node in chain["nodes"]:
+ config[node["name"]] = {}
+
+ #initiatlize the route dictionary for each node
+ for node in chain["nodes"]:
+ route[node["name"]] = {}
+
+ #initiatlize the chn dictionary for each node
+ for node in chain["nodes"]:
+ chn[node["name"]] = {}
+
+ #set chn values: chn[name][key] = value
+ for node in chain["nodes"]:
+ for key, value in node.items():
+ try:
+ #name key is redundant in map
+ if key != "name":
+ chn[node["name"]][key] = value
+ except KeyError, e:
+ logging.debug("Field " + str(key) + " not found for node " + str(node["name"]))
+ logging.debug("Cotinuing...")
+ continue
+
+ #debug print of chn
+ logging.debug(pformat((chn)))
+
+ routing = generate_routing_from_chain(chain)
+
+ for node_name, node_rt in routing["routing_table"].items():
+ route[node_name] = node_rt
+
+ #debug print of route
+ logging.debug(pformat((route)))
+
+ #set config: config[node_name][key] = value
+ for node in configuration["nodes"]:
+ for key, value in node.items():
+ #id field is redundant
+ if key != "id":
+ try:
+ if key == "configuration":
+ #init config[node_name][key] with an empty array
+ config[node["id"]][key] = []
+
+ for value_item in value:
+ change_key = "key" in convert_configuration_property_to_ip[chn[node["id"]]["functional_type"]]
+ change_value = "value" in convert_configuration_property_to_ip[chn[node["id"]]["functional_type"]]
+ if (change_key==False and change_value==False):
+ config[node["id"]][key].append(value_item)
+ continue
+ # config[node_name][configuration] is a dictionary
+ if isinstance(value_item, dict):
+ for config_item_key, config_item_value in value_item.items():
+ new_key = config_item_key
+ changed_key = False
+ changed_value = False
+ if change_key and config_item_key in chn.keys():
+ changed_key = True
+ new_key = "ip_" + str(config_item_key)
+ value_item[new_key] = str(config_item_value)
+ del value_item[config_item_key]
+ if change_value and config_item_value in chn.keys():
+ changed_value = True
+ new_value = "ip_" + str(config_item_value)
+ value_item[new_key] = new_value
+ if(change_key==changed_key) and (change_value==changed_value):
+ config[node["id"]][key].append(value_item)
+ else:
+ if change_value:
+ if value_item in chn.keys():
+ new_value = "ip_" + str(value_item)
+ config[node["id"]][key].append(new_value)
+ else:
+ config[node["id"]][key].append(str(value_item))
+ else:
+ config[node["id"]][key] = value
+ except KeyError, e:
+ #node not found in current chain
+ logging.debug("Field '" + key + "' not found for node '" + str(node["id"]) + "'")
+ logging.debug(key + " probably doesn't belong to the current chain, thus it will be skipped")
+ #sys.exit(1)
+ continue
+
+ # debug print of config
+ logging.debug(pformat((config)))
+
+ #prepare a few more helpful data structures
+ nodes_names = []
+ nodes_types = []
+ nodes_addresses = []
+ nodes_ip_mappings = []
+ nodes_rt = {}
+
+ #initialize vectors for node names and routing tables
+ for name in chn.keys():
+ nodes_names.append(name)
+ nodes_rt[name] = []
+
+ #add functional types, addresses and ip mapping to vectors
+ for node, field in chn.items():
+ nodes_types.append(field["functional_type"])
+ nodes_addresses.append(field["address"])
+ nodes_ip_mappings.append(field["address"])
+
+ for node, rt in route.items():
+ for dest, next_hop in rt.items():
+ row = "nctx.am.get(\"" + dest + "\"), " + next_hop
+ try:
+ nodes_rt[node].append(row)
+ except KeyError, e:
+ #node not found, notify and exit
+ logging.debug("Node " + node + " not found!")
+ sys.exit(1)
+
+ #begin file generation
+ logging.debug("* instantiating chain #" + str(number))
+ dirname = os.path.dirname(output_file)
+ basename = os.path.basename(output_file)
+ basename = os.path.splitext(basename)[0]
+ basename = basename[0].upper() + basename[1:]
+ with smart_open(dirname + "/" + basename + "_" + str(number) + ".java") as f:
+ c = CodeGeneratorBackend()
+ c.begin(tab=" ")
+
+ c.writeln("package tests.scenarios;")
+
+ #imports here
+ c.writeln("import java.util.ArrayList;")
+ c.writeln("import com.microsoft.z3.Context;")
+ c.writeln("import com.microsoft.z3.DatatypeExpr;")
+
+ c.writeln("import mcnet.components.Checker;")
+ c.writeln("import mcnet.components.NetContext;")
+ c.writeln("import mcnet.components.Network;")
+ c.writeln("import mcnet.components.NetworkObject;")
+ c.writeln("import mcnet.components.Tuple;")
+ c.writeln("import mcnet.netobjs.PacketModel;")
+
+ #import components
+ #for i in range(0, len(nodes_names)):
+ # c.writeln("import mcnet.netobjs." + devices_to_classes[str(nodes_types[i])] + ";")
+
+ for key, value in devices_to_classes.items():
+ c.writeln("import mcnet.netobjs." + value + ";")
+
+ c.writeln("public class " + basename + "_" + str(number) + "{")
+
+ c.indent()
+ c.writeln("public Checker check;")
+ # declare components
+ for i in range(0, len(nodes_names)):
+ c.writeln("public " + devices_to_classes[str(nodes_types[i])] + " " + str(nodes_names[i]) + ";")
+
+ # method setDevices
+ c.writeln("private void setDevices(Context ctx, NetContext nctx, Network net){")
+ c.indent()
+ for i in range(0, len(nodes_names)):
+ c.write(str(nodes_names[i]) + " = new " + devices_to_classes[str(nodes_types[i])] + "(ctx, new Object[]{nctx.nm.get(\"" + nodes_names[i] + "\"), net, nctx")
+ if devices_initialization[nodes_types[i]] != [] :
+ for param in devices_initialization[nodes_types[i]]:
+ print "configuring node " + nodes_names[i]
+ for config_param in config[nodes_names[i]]["configuration"]:
+ if param in config_param:
+ c.append(", nctx.am.get(\"" + config_param[param] + "\")")
+ c.append("});\n")
+ c.dedent()
+ c.writeln("}")
+ # end method setDevices
+
+ # method doMappings
+ c.writeln("private void doMappings(NetContext nctx, ArrayList<Tuple<NetworkObject,ArrayList<DatatypeExpr>>> adm){")
+ c.indent()
+ for i in range(0, len(nodes_names)):
+ c.writeln("ArrayList<DatatypeExpr> al" + str(i) + " = new ArrayList<DatatypeExpr>();")
+ c.writeln("al" + str(i) + ".add(nctx.am.get(\"" + nodes_ip_mappings[i] + "\"));")
+ c.writeln("adm.add(new Tuple<>((NetworkObject)" + nodes_names[i] + ", al" + str(i) + "));")
+ c.dedent()
+ c.writeln("}")
+ # end method doMappings
+
+ # for each node methods setRouting and configureDevice
+ for i in range(0, len(nodes_names)):
+ # method setRouting
+ c.writeln("private void setRouting" + nodes_names[i] + "(NetContext nctx, Network net, ArrayList<Tuple<DatatypeExpr,NetworkObject>> rt_" + nodes_names[i] + "){")
+ c.indent()
+ for row in nodes_rt[nodes_names[i]]:
+ c.writeln("rt_" + nodes_names[i] + ".add(new Tuple<DatatypeExpr,NetworkObject>(" + row + "));")
+ c.writeln("net.routingTable(" + nodes_names[i] + ", rt_" + nodes_names[i] + ");")
+ c.dedent()
+ c.writeln("}")
+ # end method setRouting
+ # method configureDevice
+ c.writeln("private void configureDevice" + nodes_names[i] + "(NetContext nctx) {")
+ c.indent()
+ #configure middle-box only if its configuration is not empty
+ if config[nodes_names[i]]["configuration"] != [] :
+ if nodes_types[i] == "cache":
+ c.write(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(new NetworkObject[]")
+ cache_ips = config[nodes_names[i]]["configuration"]
+ cache_hosts = []
+ for cache_ip in cache_ips:
+ i = -1
+ for host in nodes_addresses:
+ i += 1
+ if host == cache_ip:
+ cache_hosts.append(nodes_names[i])
+ c.write_list(formatted_list_from_list_of_maps(cache_hosts), wrapper="")
+ c.append(");\n")
+ elif nodes_types[i] == "nat":
+ c.writeln("ArrayList<DatatypeExpr> ia" + str(i) +" = new ArrayList<DatatypeExpr>();")
+ config_elements = []
+ config_elements = formatted_list_from_list_of_maps(config[nodes_names[i]]["configuration"])
+ for address in config_elements:
+ c.writeln("ia" + str(i) + ".add(nctx.am.get(\"" + address + "\"));")
+ c.writeln(nodes_names[i] + ".natModel(nctx.am.get(\"ip_" + nodes_names[i] + "\"));")
+ c.writeln(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(ia" + str(i) +");")
+ elif nodes_types[i] == "firewall":
+ c.writeln("ArrayList<Tuple<DatatypeExpr,DatatypeExpr>> acl" + str(i) + " = new ArrayList<Tuple<DatatypeExpr,DatatypeExpr>>();")
+ for config_element in config[nodes_names[i]]["configuration"]:
+ if isinstance(config_element,dict):
+ for key, value in config_element.items():
+ if key in nodes_addresses and value in nodes_addresses:
+ c.writeln("acl" + str(i) + ".add(new Tuple<DatatypeExpr,DatatypeExpr>(nctx.am.get(\"" + key + "\"),nctx.am.get(\"" + value + "\")));")
+ c.writeln(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(acl" + str(i) + ");")
+ elif nodes_types[i] == "antispam":
+ c.write(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(new int[]")
+ c.write_list(formatted_list_from_list_of_maps(config[nodes_names[i]]["configuration"]))
+ c.append(");\n")
+ elif nodes_types[i] == "dpi":
+ for index in range(0, len(config[nodes_names[i]]["configuration"])):
+ config[nodes_names[i]]["configuration"][index] = "String.valueOf(\"" + str(config[nodes_names[i]]["configuration"][index]) + "\").hashCode()"
+ c.write(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(new int[]")
+ c.write_list(formatted_list_from_list_of_maps(config[nodes_names[i]]["configuration"]), wrapper="")
+ c.append(");\n")
+ elif nodes_types[i] == "endhost":
+ c.writeln("PacketModel pModel" + str(i) + " = new PacketModel();")
+ if "body" in config[nodes_names[i]]["configuration"][0]:
+ c.writeln("pModel" + str(i) + ".setBody(String.valueOf(\"" + config[nodes_names[i]]["configuration"][0]["body"] + "\").hashCode());")
+ if "sequence" in config[nodes_names[i]]["configuration"][0]:
+ c.writeln("pModel" + str(i) + ".setSeq(" + config[nodes_names[i]]["configuration"][0]["sequence"] + ");")
+ if "protocol" in config[nodes_names[i]]["configuration"][0]:
+ c.writeln("pModel" + str(i) + ".setProto(nctx." + config[nodes_names[i]]["configuration"][0]["protocol"] + ");")
+ if "email_from" in config[nodes_names[i]]["configuration"][0]:
+ c.writeln("pModel" + str(i) + ".setEmailFrom(String.valueOf(\"" + config[nodes_names[i]]["configuration"][0]["email_from"] + "\").hashCode());")
+ if "url" in config[nodes_names[i]]["configuration"][0]:
+ c.writeln("pModel" + str(i) + ".setUrl(String.valueOf(\"" + config[nodes_names[i]]["configuration"][0]["url"] + "\").hashCode());")
+ if "options" in config[nodes_names[i]]["configuration"][0]:
+ c.writeln("pModel" + str(i) + ".setOptions(String.valueOf(\"" + config[nodes_names[i]]["configuration"][0]["options"] + "\").hashCode());")
+ if "destination" in config[nodes_names[i]]["configuration"][0]:
+ c.writeln("pModel" + str(i) + ".setIp_dest(nctx.am.get(\"" + config[nodes_names[i]]["configuration"][0]["destination"] + "\"));")
+
+ c.writeln(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(pModel" + str(i) + ");")
+ elif nodes_types[i] == "vpnaccess":
+ c.writeln(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(nctx.am.get(\"" + nodes_addresses[i] + "\"), nctx.am.get(\"" + config[nodes_names[i]]["configuration"][0]["vpnexit"] + "\"));")
+ elif nodes_types[i] == "vpnexit":
+ c.writeln(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "(nctx.am.get(\"" + config[nodes_names[i]]["configuration"][0]["vpnaccess"] + "\"), nctx.am.get(\"" + nodes_addresses[i] + "\"));")
+
+ # config is empty but configure device anyway
+ elif nodes_types[i] == "fieldmodifier":
+ c.writeln(nodes_names[i] + "." + devices_to_configuration_methods[nodes_types[i]] + "();")
+ c.dedent()
+ c.writeln("}")
+ # end method configureDevice
+
+
+ c.writeln("public " + basename + "_" + str(number) + "(Context ctx){")
+ c.indent()
+ c.write("NetContext nctx = new NetContext (ctx,new String[]")
+ c.write_list(nodes_names, wrapper="\"")
+ c.append(", new String[]")
+ c.write_list(nodes_addresses, wrapper="\"")
+ c.append(");\n")
+ c.writeln("Network net = new Network (ctx,new Object[]{nctx});")
+ # call method setDevices
+ c.writeln("setDevices(ctx, nctx, net);")
+
+ #SET ADDRESS MAPPINGS
+ c.writeln("ArrayList<Tuple<NetworkObject,ArrayList<DatatypeExpr>>> adm = new ArrayList<Tuple<NetworkObject,ArrayList<DatatypeExpr>>>();")
+ # call doMappings
+ c.writeln("doMappings(nctx, adm);")
+ c.writeln("net.setAddressMappings(adm);")
+
+ #CONFIGURE ROUTING TABLE
+ for i in range(0, len(nodes_names)):
+ c.writeln("ArrayList<Tuple<DatatypeExpr,NetworkObject>> rt_" + nodes_names[i] + " = new ArrayList<Tuple<DatatypeExpr,NetworkObject>>(); ")
+ c.writeln("setRouting" + nodes_names[i] + "(nctx, net, rt_" + nodes_names[i] + ");")
+
+ #ATTACH DEVICES
+ c.write("net.attach(")
+ c.write_list(nodes_names, delimiter = False, wrapper="")
+ c.append(");\n")
+
+ #CONFIGURE MIDDLE-BOXES
+ for i in range(0, len(nodes_names)):
+ c.writeln("configureDevice" + nodes_names[i] + "(nctx);")
+
+ c.writeln("check = new Checker(ctx,nctx,net);")
+
+ c.dedent()
+ c.writeln("}")
+
+ c.dedent()
+ c.writeln("}")
+
+ #write c object to file
+ print >>f, c.end()
+
+ logging.debug("wrote test file " + os.path.abspath(dirname + "/" + basename + "_" + str(number)) + ".java" + " successfully!")
+
+
+def main(argv):
+ #exit if any command line argument is missing
+ if len(argv) < 6:
+ print 'test_class_generator.py -c <chain_file> -f <conf_file> -o <output_name>'
+ sys.exit(1)
+
+ #initialize json file names
+ chains_file = ''
+ configuration_file = ''
+ output_file = ''
+
+ #parse command line arguments and exit in case of any error
+ try:
+ opts, args = getopt.getopt(argv,"hc:f:r:o:",["help","chain=","config=","route=","ofile="])
+ except getopt.GetoptError as err:
+ print str(err)
+ print 'test_class_generator.py -c <chain_file> -f <conf_file> -o <output_name>'
+ sys.exit(2)
+ for opt, arg in opts:
+ if opt in ("-h", "--help"):
+ print 'test_class_generator.py -c <chain_file> -f <conf_file> -o <output_name'
+ sys.exit()
+ elif opt in ("-c", "--chain"):
+ chains_file = arg
+ elif opt in ("-f", "--config"):
+ configuration_file = arg
+ elif opt in ("-o", "--ofile"):
+ output_file = arg
+
+ #set logging
+ logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
+
+ #parse chains file
+ chains = convert_unicode_to_ascii(parse_json_file(chains_file))
+
+ #parse configuration file
+ configuration = convert_unicode_to_ascii(parse_json_file(configuration_file))
+
+ logging.debug(pformat((chains)))
+ logging.debug(pformat((configuration)))
+
+ #custom formatted prints
+ print_chains(chains)
+ print_configuration(configuration)
+
+ #counter for the number of chains
+ number_of_chains = 0
+
+ #generate test classes
+ for chain in chains["chains"]:
+ #increment the number of chains
+ number_of_chains += 1;
+ #generate test files
+ generate_test_file(chain, number_of_chains, configuration, output_file)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
+
diff --git a/verigraph/service/src/tests/j-verigraph-generator/test_generator.py b/verigraph/service/src/tests/j-verigraph-generator/test_generator.py
new file mode 100644
index 0000000..f4629bb
--- /dev/null
+++ b/verigraph/service/src/tests/j-verigraph-generator/test_generator.py
@@ -0,0 +1,160 @@
+#!/usr/bin/python
+
+##############################################################################
+# Copyright (c) 2017 Politecnico di Torino and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from pprint import pprint
+from code_generator import CodeGeneratorBackend
+import sys, getopt
+import contextlib
+import os
+from utility import *
+import logging
+
+def main(argv):
+ if len(argv) < 8:
+ print 'test_generator.py -i <inputfile> -o <outputfile> -s <source> -d <destination>'
+ sys.exit(2)
+ #initialize command line arguments values
+ inputfile = ''
+ outputfile = ''
+ source = ''
+ destination = ''
+ #parse command line arguments and exit if there is an error
+ try:
+ opts, args = getopt.getopt(argv,"hi:o:s:d:",["ifile=","ofile=","source=","destination="])
+ except getopt.GetoptError:
+ print 'test_generator.py -i <inputfile> -o <outputfile> -s <source> -d <destination>'
+ sys.exit(2)
+ for opt, arg in opts:
+ if opt == '-h':
+ print 'test_generator.py -i <inputfile> -o <outputfile> -s <source> -d <destination>'
+ sys.exit()
+ elif opt in ("-i", "--ifile"):
+ inputfile = arg
+ elif opt in ("-o", "--ofile"):
+ outputfile = arg
+ elif opt in ("-s", "--source"):
+ source = arg
+ elif opt in ("-d", "--destination"):
+ destination = arg
+ #set logging
+ logging.basicConfig(stream=sys.stderr, level=logging.INFO)
+ #capitalize ouput filename
+ dirname = os.path.dirname(outputfile)
+ basename = os.path.basename(outputfile)
+ basename = os.path.splitext(basename)[0]
+ basename = basename[0].upper() + basename[1:]
+
+ #print arguments
+ logging.debug('Input file is', inputfile)
+ logging.debug('Output file is', dirname + "/" + basename)
+ logging.debug('Source node is', source)
+ logging.debug('Destination node is', destination)
+
+ #begin file generation
+ with smart_open(dirname + "/" + basename + ".java") as f:
+ c = CodeGeneratorBackend()
+ c.begin(tab=" ")
+ c.writeln("package tests;")
+ c.writeln("import java.util.Calendar;")
+ c.writeln("import java.util.Date;")
+ c.writeln("import java.util.HashMap;")
+
+ c.writeln("import com.microsoft.z3.Context;")
+ c.writeln("import com.microsoft.z3.FuncDecl;")
+ c.writeln("import com.microsoft.z3.Model;")
+ c.writeln("import com.microsoft.z3.Status;")
+ c.writeln("import com.microsoft.z3.Z3Exception;")
+ c.writeln("import mcnet.components.IsolationResult;")
+
+
+ inputfile = os.path.basename(inputfile)
+ c.writeln("import tests.scenarios." + os.path.splitext(inputfile)[0] + ";")
+ c.writeln("public class " + basename + "{")
+
+ c.indent()
+ c.writeln("Context ctx;")
+
+ c.write("public void resetZ3() throws Z3Exception{\n\
+ HashMap<String, String> cfg = new HashMap<String, String>();\n\
+ cfg.put(\"model\", \"true\");\n\
+ ctx = new Context(cfg);\n\
+ \r\t}\n")
+
+ c.write("public void printVector (Object[] array){\n\
+ int i=0;\n\
+ System.out.println( \"*** Printing vector ***\");\n\
+ for (Object a : array){\n\
+ i+=1;\n\
+ System.out.println( \"#\"+i);\n\
+ System.out.println(a);\n\
+ System.out.println( \"*** \"+ i+ \" elements printed! ***\");\n\
+ }\n\
+ \r\t}\n")
+
+ c.write("public void printModel (Model model) throws Z3Exception{\n\
+ for (FuncDecl d : model.getFuncDecls()){\n\
+ System.out.println(d.getName() +\" = \"+ d.toString());\n\
+ System.out.println(\"\");\n\
+ }\n\
+ \r\t}\n")
+
+ c.writeln("public int run() throws Z3Exception{")
+ c.indent()
+
+ c.writeln(basename + " p = new " + basename + "();")
+
+ #adding time estimation
+ #c.writeln("int k = 0;")
+ #c.writeln("long t = 0;")
+
+ #c.writeln("for(;k<1;k++){")
+ #c.indent()
+
+ c.writeln("p.resetZ3();")
+
+ c.write(os.path.splitext(inputfile)[0] + " model = new " + os.path.splitext(inputfile)[0] + "(p.ctx);\n")
+
+ #c.writeln("Calendar cal = Calendar.getInstance();")
+ #c.writeln("Date start_time = cal.getTime();")
+
+ c.write("IsolationResult ret =model.check.checkIsolationProperty(model.")
+ c.append(source + ", model." + destination + ");\n")
+ #c.writeln("Calendar cal2 = Calendar.getInstance();")
+ #c.writeln("t = t+(cal2.getTime().getTime() - start_time.getTime());")
+
+ c.writeln("if (ret.result == Status.UNSATISFIABLE){\n\
+ System.out.println(\"UNSAT\");\n\
+ return -1;\n\
+ }else if (ret.result == Status.SATISFIABLE){\n\
+ System.out.println(\"SAT\");\n\
+ return 0;\n\
+ }else{\n\
+ System.out.println(\"UNKNOWN\");\n\
+ return -2;\n\
+ \r\t\t}")
+
+ #c.dedent()
+ #c.writeln("}")
+
+ #c.writeln("")
+ #c.writeln("System.out.printf(\"Mean execution time " + source + " -> " + destination + ": %.16f\", ((float) t/(float)1000)/k);")
+
+ c.dedent()
+ c.writeln("}")
+
+ c.dedent()
+ c.writeln("}")
+
+ print >>f, c.end()
+ logging.debug("File " + os.path.abspath(dirname + "/" + basename + ".java") + " has been successfully generated!!")
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/verigraph/service/src/tests/j-verigraph-generator/utility.py b/verigraph/service/src/tests/j-verigraph-generator/utility.py
new file mode 100644
index 0000000..47d0180
--- /dev/null
+++ b/verigraph/service/src/tests/j-verigraph-generator/utility.py
@@ -0,0 +1,257 @@
+#!/usr/bin/python
+
+##############################################################################
+# Copyright (c) 2017 Politecnico di Torino and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import json
+import contextlib
+import sys
+import os
+import subprocess
+from pprint import pprint
+
+#manages output easily (can either write to file or to stdout)
+@contextlib.contextmanager
+def smart_open(filename=None):
+ if filename and filename != '-':
+ fh = open(filename, 'w')
+ else:
+ fh = sys.stdout
+ try:
+ yield fh
+ finally:
+ if fh is not sys.stdout:
+ fh.close()
+
+def check_input_is_int(text):
+ while True:
+ data = raw_input(text)
+ try:
+ int_value = int(data)
+ except ValueError:
+ print "Please enter a valid number!"
+ continue
+ return int_value
+
+#parses a json file into a unicode dictionary
+def parse_json_file(filename):
+ with open(filename) as json_file:
+ return json.load(json_file)
+
+#returns an ascii dictionary from a unicode one
+def convert_unicode_to_ascii(input):
+ if isinstance(input, dict):
+ return {convert_unicode_to_ascii(key): convert_unicode_to_ascii(value) for key, value in input.iteritems()}
+ elif isinstance(input, list):
+ return [convert_unicode_to_ascii(element) for element in input]
+ elif isinstance(input, unicode):
+ return input.encode('utf-8')
+ else:
+ return input
+
+#parses a chains file
+def parse_chains(chains_file):
+ chains_json = convert_unicode_to_ascii(parse_json_file(chains_file))
+
+ chains = {}
+
+ for chn in chains_json["chains"]:
+ try:
+ chains[chn["id"]] = {}
+ #initiatlize the config dictionary for each node
+ for node in chn["nodes"]:
+ chains[chn["id"]][node["name"]] = {}
+ except:
+ raise KeyError("Chains file is not valid!")
+
+ for chn in chains_json["chains"]:
+ try:
+ #set chn values ---> chn(name, (field, value))
+ for node in chn["nodes"]:
+ for key, value in node.items():
+ #name key is redundant in map
+ if key != "name":
+ chains[chn["id"]][node["name"]][key] = value
+ except:
+ raise KeyError("Chains file is not valid!")
+ return chains
+
+def check_chains_integrity(filename):
+ print "Checking input file..."
+ try:
+ chains = convert_unicode_to_ascii(parse_json_file(filename))
+ print "File correctly parsed"
+ if isinstance(chains["chains"], list) == False:
+ print "Child of chains is not a list!"
+ return False
+ for chain in chains["chains"]:
+ print "Chain found, checking its fields..."
+ print "Checking chain id field... "
+ chain["id"]
+ print "OK!"
+ print "Checking chain flowspace field... "
+ chain["flowspace"]
+ print "OK!"
+ if isinstance(chain["nodes"], list) == False:
+ print "Chain #" + chain["id"] + " does not have a list of nodes!"
+ return False
+ for node in chain["nodes"]:
+ print "Node found, checking its fields..."
+ print "Checking node name... "
+ node["name"]
+ print "OK!"
+ print "Checking node functional_type field... "
+ node["functional_type"]
+ print "OK!"
+ print "Checking node address field... "
+ node["address"]
+ print "OK!"
+ except (KeyboardInterrupt, SystemExit):
+ raise
+ except:
+ print "One or more required fields are missing!"
+ return False
+ print filename + " validated successfully!"
+ return True
+
+def check_config_integrity(filename):
+ print "Checking input file..."
+ try:
+ config = convert_unicode_to_ascii(parse_json_file(filename))
+ pprint(config)
+ print "File correctly parsed"
+ if isinstance(config["nodes"], list) == False:
+ print "Child of nodes is not a list!"
+ return False
+ for node in config["nodes"]:
+ print "Node found, checking its fields..."
+ print "Checking id field... "
+ node["id"]
+ print "OK!"
+ print "Checking description field... "
+ node["description"]
+ print "OK!"
+ print "Checking configuration field... "
+ node["configuration"]
+ print "OK!"
+ if isinstance(node["configuration"], list) == False:
+ print "Checking if node configuration is a list..."
+ print "Node with id " + node["id"] + " does not have a configuration list!"
+ return False
+ for c in node["configuration"]:
+ print "Checking if node configuration element is a string or a dictionary..."
+ if (isinstance(c, str) == False and isinstance(c, dict) == False):
+ print "At least one element of node with id " + node["id"] + " has an invalid configuration (it is neither a string or a map)"
+ return False
+ except (KeyboardInterrupt, SystemExit):
+ raise
+ except:
+ print "One or more required fields are missing!"
+ return False
+ print filename + " validated successfully!"
+ return True
+
+def check_routing_integrity(filename):
+ print "Checking input file..."
+ try:
+ routing = convert_unicode_to_ascii(parse_json_file(filename))
+ print "File correctly parsed"
+ if isinstance(routing["routing_table"], list) == False:
+ print "Child of routing_table is not a list!"
+ return False
+ for node in routing["routing_table"]:
+ if isinstance(node, dict) == False:
+ print "Child of routing_table is not a map!"
+ return False
+ for n, rt in node.items():
+ if isinstance(rt, list) == False:
+ print "Routing table of element " + n + " is not a list!"
+ return False
+ for entry in rt:
+ if isinstance(entry, dict) == False:
+ print "Invalid entry for node " + n + " (not a map)!"
+ return False
+ except (KeyboardInterrupt, SystemExit):
+ raise
+ except:
+ print "One or more required fields are missing!"
+ return False
+ return True
+
+#prints every node for each input chain
+def print_chains(chains):
+ for chain in chains["chains"]:
+ print "CHAIN #" + str(chain["id"])
+ for node in chain["nodes"]:
+ print "Name: " + str(node["name"])
+ print "Functional type: " + str(node["functional_type"])
+ print "Address: " + str(node["address"])
+ print "-----------------------------------"
+ print ""
+
+#prints every node's configuration
+def print_configuration(configuration):
+ print "NODES CONFIGURATION"
+ for node in configuration["nodes"]:
+ print "Name: " + str(node["id"])
+ print "Description: " + str(node["description"])
+ print "Configuration: "
+ pprint(node["configuration"])
+ print "-----------------------------------"
+ print ""
+
+#print every node's routing table
+def print_routing_table(routing):
+ print "ROUTING"
+ for table in routing["routing_table"]:
+ for node,rt in table.items():
+ print "Name: " + str(node)
+ pprint(rt)
+ print "-----------------------------------"
+ print ""
+
+#returns a list of tuple [(k1, v1), (k2, v2)] from a list of maps like [{k1 : v1},{k2 : v2}]
+def formatted_list_from_list_of_maps(maps):
+ l = []
+ for map in maps:
+ if isinstance(map, dict):
+ for k, v in map.items():
+ #l.append("(ctx." + str(k) + ", ctx." + str(v) + ")")
+ l.append(str(k))
+ l.append(str(v))
+ else:
+ #l.append("ctx." + map)
+ l.append(map)
+ return l
+
+def list_directories(dir):
+ #output = subprocess.call(["ls", "-d", "*/"])
+ output = subprocess.call(["find", dir, "-type", "d"])
+
+ #TREE VERSION
+ #find = subprocess.Popen(["find", ".", "-type", "d"], stdout=subprocess.PIPE)
+ #output = subprocess.check_output(["sed", "-e", "s/[^-][^\/]*\// |/g", "-e", "s/|\([^ ]\)/|-\1/"], stdin=find.stdout)
+ #find.wait()
+
+# ps = subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)
+# output = subprocess.check_output(('grep', 'process_name'), stdin=ps.stdout)
+# ps.wait()
+ return output
+
+def list_files(dir):
+ output = subprocess.call(["find", dir, "-type", "f"])
+ return output
+
+def search_node_in_chains(n):
+ found = []
+ for chain in chains["chains"]:
+ for node in chain["nodes"]:
+ if node["name"] == n:
+ found.append(node)
+ return found \ No newline at end of file