/**
* 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
* @author Konstantin Pozdeev
* @version 0.1
*/
package org.opendaylight.defense4all.core;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.opendaylight.defense4all.framework.core.ExceptionControlApp;
import org.opendaylight.defense4all.framework.core.FMHolder;
import org.opendaylight.defense4all.framework.core.HealthTracker;
import org.opendaylight.defense4all.framework.core.PropertiesSerializer;
import org.opendaylight.defense4all.framework.core.RepoCD;
import org.opendaylight.defense4all.core.ProtocolPort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import me.prettyprint.cassandra.serializers.BooleanSerializer;
import me.prettyprint.cassandra.serializers.IntegerSerializer;
import me.prettyprint.cassandra.serializers.StringSerializer;
public class Mitigation {
public enum Status {
INVALID,
ACTIVE,
NO_RESOURCES,
ENDED
}
/* MitigationRepo column names */
public static final String KEY = "key";
public static final String ATTACK_KEY = "attack_key";
public static final String PNKEY = "pnkey";
public static final String MONITORED_TRAFFIC_KEY = "monitored_traffic_key";
public static final String DST_ADDR = "dest_addr";
public static final String DST_ADDR_PREFIX_LEN = "dest_addr_prefix_len";
public static final String PROTOCOL_PORT = "protocol_port";
public static final String STATUS = "status";
public static final String COLLECT_STATS = "collect_stats";
public static final String MITIGATION_DRIVER = "mitigation_driver";
public static final String TRAFFIC_FLOOR_KEY_PREFIX = "traffic_floor_key_";
public static final String DVSN_INFO_KEY_PREFIX = "dvsn_info_key_";
public static final String MITIGATION_EXECUTION_PROPS = "mitigation_execution_props";
static Logger log = LoggerFactory.getLogger(Mitigation.class);
public String key;
public String attackKey;
public String pnKey;
public String monitoredTrafficKey;
public InetAddress dstAddr;
public int dstAddrPrefixLen;
public ProtocolPort protocolPort;
public Status status;
public Boolean collectStats;
public String mitigationDriverLabel;
public List<String> trafficFloorKeys; // used to indicate traffic floors created for mitigation
public List<String> dvsnInfoKeys;
public Properties mitigationExecutionProps;
public static String generateKey(String s) {return s + "_" + System.currentTimeMillis() / 1000;}
protected static ArrayList<RepoCD> mitigationRepoCDs = null;
/** ### Description ###
* @param param_name
*/
public Mitigation() {
key = attackKey = pnKey = monitoredTrafficKey = null; dstAddr = null; dstAddrPrefixLen = 0;
status = Status.INVALID; collectStats = false; mitigationDriverLabel = "";
trafficFloorKeys = new ArrayList<String>();
protocolPort = new ProtocolPort();
dvsnInfoKeys = new ArrayList<String>();
mitigationExecutionProps = new Properties();
}
/** ### Description ###
* @param param_name
* @throws
*/
public Mitigation(String key, String attackKey, String pnKey, String monitoredTrafficKey, InetAddress dstAddr,
int dstAddrPrefixLen, ProtocolPort protocolPort, Status status, Boolean collectStats,
String mitigationDriverLabel, List<String> dvsnInfoKeys) {
this.key = key; this.attackKey = attackKey; this.pnKey = pnKey; this.monitoredTrafficKey = monitoredTrafficKey;
this.dstAddr = dstAddr; this.dstAddrPrefixLen = dstAddrPrefixLen; this.protocolPort = protocolPort;
this.status = status; this.collectStats= collectStats; this.mitigationDriverLabel = mitigationDriverLabel;
this.trafficFloorKeys = new ArrayList<String>();
this.dvsnInfoKeys = dvsnInfoKeys == null ? new ArrayList<String>() : dvsnInfoKeys;
this.mitigationExecutionProps = new Properties();
}
/** ### Description ###
* @param param_name
*/
public Mitigation(Mitigation other) {
this.key = other.key; this.attackKey = other.attackKey; this.pnKey = other.pnKey;
this.monitoredTrafficKey = other.monitoredTrafficKey; this.dstAddr = other.dstAddr;
this.dstAddrPrefixLen = other.dstAddrPrefixLen; this.protocolPort = other.protocolPort;
this.status = other.status; this.collectStats= other.collectStats;
this.mitigationDriverLabel = other.mitigationDriverLabel;
this.trafficFloorKeys = other.trafficFloorKeys;
this.dvsnInfoKeys = other.dvsnInfoKeys;
this.mitigationExecutionProps = other.mitigationExecutionProps;
}
public Mitigation(Hashtable<String, Object> mitigationRow) throws UnknownHostException, ExceptionControlApp {
this();
key = (String) mitigationRow.get(KEY);
attackKey = (String) mitigationRow.get(ATTACK_KEY);
pnKey = (String) mitigationRow.get(PNKEY);
monitoredTrafficKey = (String) mitigationRow.get(MONITORED_TRAFFIC_KEY);
try {
dstAddr = InetAddress.getByName((String) mitigationRow.get(DST_ADDR));
} catch (Exception e) {
log.error("Failed to construct Mitigation - bad destination address " + dstAddr + ". " + e.getLocalizedMessage());
FMHolder.get().getHealthTracker().reportHealthIssue(HealthTracker.MODERATE_HEALTH_ISSUE);
throw new ExceptionControlApp("Failed to construct Mitigation. + ", e);
}
dstAddrPrefixLen = (Integer) mitigationRow.get(DST_ADDR_PREFIX_LEN);
protocolPort = new ProtocolPort((String) mitigationRow.get(PROTOCOL_PORT));
status = Status.valueOf((String) mitigationRow.get(STATUS));
collectStats= (Boolean) mitigationRow.get(COLLECT_STATS);
mitigationDriverLabel = (String) mitigationRow.get(MITIGATION_DRIVER);
mitigationExecutionProps = (Properties) mitigationRow.get(MITIGATION_EXECUTION_PROPS);
Iterator<Map.Entry<String,Object>> iter = mitigationRow.entrySet().iterator();
Map.Entry<String,Object> entry; String key;
while(iter.hasNext()) {
entry = iter.next();
key = entry.getKey();
if(key.startsWith(DVSN_INFO_KEY_PREFIX))
dvsnInfoKeys.add((String) entry.getValue());
else if(key.startsWith(TRAFFIC_FLOOR_KEY_PREFIX))
trafficFloorKeys.add((String) entry.getValue());
}
}
public Hashtable<String, Object> toRow() {
/* Change any null value to empty, otherwise Hashtable.put() will throw an exception */
if(key == null) key = "";
if(attackKey == null) attackKey = "";
if(pnKey == null) pnKey = "";
if(monitoredTrafficKey == null) monitoredTrafficKey = "";
if(mitigationDriverLabel == null) mitigationDriverLabel = "";
if(protocolPort == null) protocolPort = new ProtocolPort();
Hashtable<String, Object> row = new Hashtable<String, Object>();
row.put(KEY, key);
row.put(ATTACK_KEY, attackKey);
row.put(PNKEY, pnKey);
row.put(MONITORED_TRAFFIC_KEY, monitoredTrafficKey);
row.put(DST_ADDR, dstAddr.getHostAddress());
row.put(DST_ADDR_PREFIX_LEN, dstAddrPrefixLen);
row.put(PROTOCOL_PORT, protocolPort.toString());
row.put(STATUS, status.name());
row.put(COLLECT_STATS, collectStats);
row.put(MITIGATION_DRIVER, mitigationDriverLabel);
row.put(MITIGATION_EXECUTION_PROPS, mitigationExecutionProps);
for(String dvsnInfoKey : dvsnInfoKeys)
row.put(DVSN_INFO_KEY_PREFIX + dvsnInfoKey, dvsnInfoKey);
for(String trafficFloorKey : trafficFloorKeys)
row.put(trafficFloorKey, trafficFloorKey);
return row;
}
public String getKey() {return key;}
public void setKey(String key) {this.key = key;}
public String getAttackKey() {return attackKey;}
public void setAttackKey(String attackKey) {this.attackKey = attackKey;}
public String getMonitoredTraffickey() {return monitoredTrafficKey;}
public void setMonitoredTraffickey(String monitoredTrafficKey) {this.monitoredTrafficKey = monitoredTrafficKey;}
public String getPnkey() {return pnKey;}
public void setPnkey(String pnKey) {this.pnKey = pnKey;}
public InetAddress getDstAddr() {return dstAddr;}
public void setDstAddr(InetAddress dstAddr) {this.dstAddr = dstAddr;}
public int getDstAddrPrefixLen() {return dstAddrPrefixLen;}
public void setDstAddrPrefixLen(int dstAddrPrefixLen) {this.dstAddrPrefixLen = dstAddrPrefixLen;}
public ProtocolPort getProtocolPort() {return protocolPort;}
public void setProtocolPort(ProtocolPort protocolPort) {this.protocolPort = protocolPort;}
public Status getStatus() {return status;}
public void setStatus(Status status) {this.status = status;}
public Boolean getCollectStats() {return collectStats;}
public void setCollectStats(Boolean collectStats) {this.collectStats = collectStats;}
public String getMitigationDriverLabel() {return mitigationDriverLabel;}
public void setMitigationDriverLabel(String label) {this.mitigationDriverLabel = label;}
public List<String> getTrafficFlowKeys() {return trafficFloorKeys;}
public void setTrafficFlowKeys(List<String> trafficFloorKeys) {this.trafficFloorKeys = trafficFloorKeys;}
public List<String> getDvsnInfoKeys() {return dvsnInfoKeys;}
public void setDvsnInfoKeys(List<String> dvsnInfoKeys) {this.dvsnInfoKeys = dvsnInfoKeys;}
public Properties getMitigationExecutionProps() {return mitigationExecutionProps;}
public void setMitigationExecutionProps(Properties props) {this.mitigationExecutionProps = props;}
public static List<RepoCD> getMitigationRCDs() {
if(mitigationRepoCDs == null) {
RepoCD rcd;
mitigationRepoCDs = new ArrayList<RepoCD>();
rcd = new RepoCD(KEY, StringSerializer.get(), null); mitigationRepoCDs.add(rcd);
rcd = new RepoCD(ATTACK_KEY, StringSerializer.get(), null); mitigationRepoCDs.add(rcd);
rcd = new RepoCD(PNKEY, StringSerializer.get(), null); mitigationRepoCDs.add(rcd);
rcd = new RepoCD(MONITORED_TRAFFIC_KEY, StringSerializer.get(), null); mitigationRepoCDs.add(rcd);
rcd = new RepoCD(DST_ADDR, StringSerializer.get(), null); mitigationRepoCDs.add(rcd);
rcd = new RepoCD(DST_ADDR_PREFIX_LEN, IntegerSerializer.get(), null); mitigationRepoCDs.add(rcd);
rcd = new RepoCD(PROTOCOL_PORT, StringSerializer.get(), null); mitigationRepoCDs.add(rcd);
rcd = new RepoCD(STATUS, StringSerializer.get(), null); mitigationRepoCDs.add(rcd);
rcd = new RepoCD(COLLECT_STATS, BooleanSerializer.get(), null); mitigationRepoCDs.add(rcd);
rcd = new RepoCD(MITIGATION_DRIVER, StringSerializer.get(), null); mitigationRepoCDs.add(rcd);
rcd = new RepoCD(MITIGATION_EXECUTION_PROPS, PropertiesSerializer.get(), null); mitigationRepoCDs.add(rcd);
}
return mitigationRepoCDs;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Mitigation[key="); sb.append(key); sb.append(", ");
sb.append("attackKey="); sb.append(attackKey); sb.append(", ");
sb.append("pnKey="); sb.append(pnKey); sb.append(", ");
sb.append("monitoredTrafficKey="); sb.append(monitoredTrafficKey); sb.append(", ");
sb.append("protocolPort="); sb.append(protocolPort.toString()); sb.append(", ");
sb.append("status="); sb.append(status.name()); sb.append(", ");
sb.append("dvsnInfoKeys="); sb.append(dvsnInfoKeys);
sb.append("]");
return sb.toString();
}
public static boolean hasActiveDvsns(String mitigationKey) {
Mitigation mitigation = getMitigation(mitigationKey);
boolean active;
DFAppRoot dfAppRoot = DFHolder.get();
for(String dvsnInfoKey : mitigation.dvsnInfoKeys) {
try {
active = (Boolean) dfAppRoot.dvsnInfosRepo.getCellValue(dvsnInfoKey, DvsnInfo.TRAFFIC_DIVERTED);
if(active) return true;
} catch (Throwable e) {
log.error("Failed to retrieve dvsnInfo status from repo for " + dvsnInfoKey);
FMHolder.get().getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE);
}
}
return false;
}
public static Mitigation getMitigation(String mitigationKey) {
try {
Hashtable<String, Object> mitigationRow = DFHolder.get().mitigationsRepo.getRow(mitigationKey);
if(mitigationRow == null) {
log.error("Got null mitigationRow for key " + mitigationKey);
return null;
}
Mitigation mitigation = new Mitigation(mitigationRow);
return mitigation;
} catch (Throwable e) {
log.error("Failed to get Mitigation : "+mitigationKey, e);
FMHolder.get().getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE);
return null;
}
}
public static String getPrintableMitigationTarget(String mitigationKey) {
Mitigation mitigation = getMitigation(mitigationKey);
if ( mitigation == null ) return "";
return mitigation.getPrintableMitigationTarget();
}
public String getPrintableMitigationTarget() {
StringBuilder sb = new StringBuilder();
if (protocolPort != null )
sb.append( protocolPort.toPrintableString());
sb.append(" traffic for PO " );
sb.append(PN.getPrintableKey(pnKey));
return sb.toString();
}
}