package org.opendaylight.defense4all.cli;
/**
* Copyright (c) <2013> <Radware Ltd.> and others. All rights reserved.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License
* v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
* @author Gera Goft
* @version 0.1
*/
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.codehaus.jackson.type.TypeReference;
import org.opendaylight.defense4all.core.PN;
import org.opendaylight.defense4all.core.PO.IpVersion;
import org.opendaylight.defense4all.core.PN.MitigationScope;
import org.opendaylight.defense4all.core.PN.OperationalStatus;
import org.opendaylight.defense4all.core.ProtectionSLA;
import org.opendaylight.defense4all.framework.core.Utils;
public class CliPn {
//TODO complete....
public static final String explanation = "PN – Protected Network, "
+ "is a specified network traffic that is protected against DDoS attacks. "
+ "Protected traffic is defined by a range of target IP addresses, "
+ "specified by either CIDR or subnet-mask notations. "
+ "Attacks against TCP, UDP, ICMP protocols or attacks against "
+ "all of remaining traffic are mitigated separately. "
+ "This can mean that only traffic of an attacked protocol of a PN is diverted to AMS "
+ "(Attack Mitigation Systems). "
+ "This can also mean that attacked traffic of different protocols, "
+ "even of the same PN may be diverted to different AMSs. "
+ "Each PN can have its unique protection properties.";
/**
* #### method description ####
* @param param_name param description
* @return return description
* @throws exception_type circumstances description
*/
protected static void displayUsageGetPn() {
StringBuilder sb = new StringBuilder();
sb.append("Usage: controlapps getpn pn_label\n");
sb.append(" Description - returns the pn corresponding to specified pn_label.\n");
System.out.println(sb.toString());
}
/**
* #### method description ####
* @param param_name param description
* @return return description
* @throws exception_type circumstances description
*/
protected static void displayUsageGetPns() {
StringBuilder sb = new StringBuilder();
sb.append("Usage: controlapps getpns\n");
sb.append(" Description - returns the PNs known to DF.\n");
System.out.println(sb.toString());
}
/**
* #### method description ####
* @param param_name param description
* @return return description
* @throws exception_type circumstances description
*/
protected static void displayUsageGetPnsCount() {
StringBuilder sb = new StringBuilder();
sb.append("Usage: controlapps getpnscount\n");
sb.append(" Description - returns the number of PNs known to DF.\n");
System.out.println(sb.toString());
}
/**
* #### method description ####
* @param param_name param description
* @return return description
* @throws exception_type circumstances description
*/
protected static void displayUsageRemovePn() {
StringBuilder sb = new StringBuilder();
sb.append("Usage: controlapps removepn pn_label\n");
sb.append(" Description - removes the PN corresponding to the pn_label.");
System.out.println(sb.toString());
}
/**
* #### method description ####
* @param param_name param description
* @return return description
* @throws exception_type circumstances description
*/
protected static void displayUsageAddPn() {
String displayUsage = "Usage: controlapps addpn param1 param2 ... \n"
+" Description - adds the pn described through the params.\n"
+" A params is formed -- field_name=field_value.\n"
+" A composite field is formed -- composite_field::sub_composite_field=sub_composite_field_value.\n"
+" A field in composite list element -- list_name::list_element_label::composite_field::sub_composite_field=value.\n"
+" The params are\n"
+" label - [mandatory] user provided unique textual name (starts with a letter) to this pn.\n"
+" ipVersion - [mandatory] ip version (IPV4, IPV6).\n"
+" dstAddr - [mandatory] traffic destination adderess.\n"
+" dstAddrPrefixLen - traffic destination adderess prefix len.(default=0)\n"
+" protectionSLA - protection SLA.\n"
+" mitigationConfirmation - is mitigation confirmation(true/false default=false).\n"
+" ofBasedDetection - is rate based detection (true/false default=false).\n"
+" anomalyThresholdPercentage - anomaly threshold percentage.\n"
+" mitigationScope - [mandatory] mitigation scop. (ATTACKED, ALL)\n"
+" detectorLabel - [mandatory] label of relevant detector\n"
+" symmetricDvsn - is attack diversion symmetric. (true/false default=true)\n"
+" amsConfigProps - {}.\n"
+" netNodeLabel - [list] of relevant NetNodes\n"
+" virtualNetid - virtual network Id\n"
+" props - {}.\n"
+"Example: controlapps addpn label=pn1 ipVersion=IPV4 dstAddr=100.1.1.10 dstAddrPrefixLen=32 "
+ "mitigationScope=ATTACKED detectorLabel=of_rate_based_detector mitigationConfirmation=false ofBasedDetection=true "
+ "anomalyThresholdPercentage=80 virtualNetid=1 symmetricDvsn=true netNodeLabel=ovs\n";
System.out.println(displayUsage);
}
/**
* #### method description ####
* @param param_name param description
* @return return description
* @throws exception_type circumstances description
*/
protected static void handleGetPns() {
List<PN> pns;
try {
Defense4allConnector connector = new Defense4allConnector(Cli.user, Cli.password);
TypeReference<?> typeRef = new TypeReference<List<PN>>(){};
pns = connector.getFromControlApps("pns", typeRef);
} catch (Exception e) {
System.out.println("Could not get pns because " + e.getMessage());
return;
}
if(pns == null || pns.isEmpty()) {
System.out.println("DF has no pns configured.");
return;
}
System.out.println("pns:\n");
for(PN pn : pns) {
if ( pn.operationalStatus == OperationalStatus.CANCELED )
continue;
System.out.println(pn.toString());
System.out.println("=================================");
}
}
/**
* #### method description ####
* @param param_name param description
* @return return description
* @throws exception_type circumstances description
*/
protected static void handleGetPns(ArrayList<String> params) {
if(params == null || params.isEmpty()) {
displayUsageGetPn();
return;
}
String label = params.get(0);
if(label == null || label.isEmpty()) {
displayUsageGetPn();
return;
}
PN pn;
try {
Defense4allConnector connector = new Defense4allConnector(Cli.user, Cli.password);
TypeReference<?> typeRef = new TypeReference<PN>(){};
pn = connector.getFromControlApps("pns/" + label, typeRef);
String printOut = (pn == null) ? "No pn " + label + " is known to DF.\n" : pn.toString();
System.out.println(printOut);
} catch (Exception e) {
System.out.println("Could not get pn " + label + " because " + e.getMessage());
return;
}
}
/**
* #### method description ####
* @param param_name param description
* @return return description
* @throws exception_type circumstances description
*/
protected static void handleAddPn(ArrayList<String> params) {
if(params == null) {
displayUsageAddPn();
return;
}
PN pn = new PN();
pn.props = new Properties();
pn.amsConfigProps = new Properties();
pn.protectionSLA = new ProtectionSLA("");
try {
for(String param : params) {
if(param.startsWith("label"))
addLabel(pn, param);
else if(param.startsWith("ipVersion"))
addIpVersion(pn, param);
else if(param.startsWith("dstAddr") && ! param.startsWith("dstAddrPrefixLen") )
addDstAddr(pn, param);
else if(param.startsWith("dstAddrPrefixLen"))
addDstAddrPrefixLen(pn, param);
else if(param.startsWith("protectionSLA"))
addProtectionSLA(pn, param);
else if(param.startsWith("mitigationConfirmation"))
addMitigationConfirmation(pn, param);
else if(param.startsWith("ofBasedDetection"))
addOfBasedDetection(pn, param);
else if(param.startsWith("anomalyThresholdPercentage"))
addAnomalyThresholdPercentage(pn, param);
else if(param.startsWith("mitigationScope"))
addMitigationScope(pn, param);
else if(param.startsWith("detectorLabel"))
addDetectorLabel(pn, param);
else if(param.startsWith("virtualNetid"))
addVirtualNetid(pn, param);
else if(param.startsWith("symmetricDvsn"))
addSymmetricDvsn(pn, param);
else if(param.startsWith("amsConfigProps"))
addAmsConfigProps(pn, param);
else if(param.startsWith("netNodeLabel"))
addNetNodeLabels(pn, param);
else if(param.startsWith("props"))
addProp(pn, param);
}
pn.toJacksonFriendly(); // Jackson does not handle lists with complex items. Let it inflate strings
// of those serialized lists, and inflate lists in "set" methods.
pn.validate();
} catch (Throwable e1) {
System.out.println(e1.getMessage());
displayUsageAddPn();
return;
}
try {
Defense4allConnector connector = new Defense4allConnector(Cli.user, Cli.password);
System.out.println("Adding pn " + pn.label);
connector.postToControlApps("pns", pn);
} catch (Exception e) {
System.out.println("Could not add pn because " + e.getMessage());
}
}
protected static void addLabel(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.label = split[1]; // Split "label=l1"
}
protected static boolean addIpVersion(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.ipVersion = IpVersion.valueOf(split[1]); // Split "id=00:00:00:50:56:a3:1b:80"
return true;
}
protected static void addDstAddr(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.dstAddr = InetAddress.getByName(split[1]);
}
protected static void addDstAddrPrefixLen(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.dstAddrPrefixLen = new Integer(split[1]);
}
protected static void addAnomalyThresholdPercentage(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.anomalyThresholdPercentage = new Integer(split[1]);
}
protected static void addProtectionSLA(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.protectionSLA = new ProtectionSLA(split[1]);
}
protected static void addMitigationConfirmation(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.mitigationConfirmation = new Boolean(split[1]);
}
protected static void addMitigationScope(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.mitigationScope = MitigationScope.valueOf(split[1]);
}
protected static void addOfBasedDetection(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.ofBasedDetection = new Boolean(split[1]);
}
protected static void addProp(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "::"); // Split "props::example_prop=example_prop_value"
split = split[1].split("="); // Can be [example_prop] or [example_prop, example_prop_value]
if(split[0].isEmpty())
throw new Exception("Invalid property format - " + param);
String value = (split.length < 2) ? "" : split[1];
pn.props.setProperty(split[0], value);
}
protected static void addAmsConfigProps(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "::"); // Split "props::example_prop=example_prop_value"
split = split[1].split("="); // Can be [example_prop] or [example_prop, example_prop_value]
if(split[0].isEmpty())
throw new Exception("Invalid property format - " + param);
String value = (split.length < 2) ? "" : split[1];
pn.amsConfigProps.setProperty(split[0], value);
}
protected static void addDetectorLabel(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.detectorLabel = split[1]; // Split "label=l1"
}
protected static void addVirtualNetid(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.virtualNetid = split[1]; // Split "label=l1"
}
protected static void addSymmetricDvsn(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.symmetricDvsn = new Boolean(split[1]);
}
protected static void addNetNodeLabels(PN pn, String param) throws Exception {
String[] split = Cli.splitAndAssertSize(param, "=");
pn.netNodeLabels.add(split[1]);
}
/**
* #### method description ####
* @param param_name param description
* @return return description
* @throws exception_type circumstances description
*/
protected static void handleRemovePn(ArrayList<String> params) {
if(params == null || params.isEmpty()) {
displayUsageRemovePn();
return;
}
String label = params.get(0);
if(label == null || label.isEmpty()) {
displayUsageRemovePn();
return;
}
String msg = "Are you sure you want to remove pn " + label + "? Please confirm with [yes, Yes or Y].";
boolean confirmed = Utils.confirmYesByUser(msg);
if(!confirmed) return;
try {
Defense4allConnector connector = new Defense4allConnector(Cli.user, Cli.password);
connector.delFromControlApps("pns/" + label);
} catch (Exception e) {
System.out.println("Could not remove pn " + label + " because " + e.getMessage());
}
System.out.println("Initiating removal of pn " + label);
}
public static void handleGetPnsCount() {
Integer count = 0;
try {
Defense4allConnector connector = new Defense4allConnector(Cli.user, Cli.password);
TypeReference<?> typeRef = new TypeReference<Integer>(){};
count = connector.getFromControlApps("pns/count", typeRef);
} catch (Exception e) {
System.out.println("Could not get pns because " + e.getMessage());
return;
}
System.out.println("There are " + count + " PNs known to DF.\n");
}
}