package org.batfish.datamodel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
public class Header6Space implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private static boolean rangesContain(Collection<SubRange> ranges, int num) {
for (SubRange range : ranges) {
if (range.getStart() <= num && num <= range.getEnd()) {
return true;
}
}
return false;
}
private static boolean wildcardsContain(Collection<Ip6Wildcard> wildcards,
Ip6 ip) {
for (Ip6Wildcard wildcard : wildcards) {
if (wildcard.contains(ip)) {
return true;
}
}
return false;
}
private SortedSet<Integer> _dscps;
private SortedSet<Ip6Wildcard> _dstIps;
private SortedSet<SubRange> _dstPorts;
private SortedSet<Integer> _ecns;
private SortedSet<SubRange> _fragmentOffsets;
private SortedSet<SubRange> _icmpCodes;
private SortedSet<SubRange> _icmpTypes;
private Set<IpProtocol> _ipProtocols;
private boolean _negate;
private SortedSet<Integer> _notDscps;
private SortedSet<Ip6Wildcard> _notDstIps;
private SortedSet<SubRange> _notDstPorts;
private SortedSet<Integer> _notEcns;
private SortedSet<SubRange> _notFragmentOffsets;
private SortedSet<SubRange> _notIcmpCodes;
private SortedSet<SubRange> _notIcmpTypes;
private Set<IpProtocol> _notIpProtocols;
private SortedSet<Ip6Wildcard> _notSrcIps;
private SortedSet<SubRange> _notSrcPorts;
private SortedSet<Ip6Wildcard> _srcIps;
private SortedSet<Ip6Wildcard> _srcOrDstIps;
private SortedSet<SubRange> _srcOrDstPorts;
private SortedSet<SubRange> _srcPorts;
private Set<State> _states;
private List<TcpFlags> _tcpFlags;
public Header6Space() {
_dscps = new TreeSet<>();
_dstIps = new TreeSet<>();
_dstPorts = new TreeSet<>();
_ecns = new TreeSet<>();
_fragmentOffsets = new TreeSet<>();
_ipProtocols = EnumSet.noneOf(IpProtocol.class);
_srcIps = new TreeSet<>();
_srcOrDstIps = new TreeSet<>();
_srcOrDstPorts = new TreeSet<>();
_srcPorts = new TreeSet<>();
_icmpTypes = new TreeSet<>();
_icmpCodes = new TreeSet<>();
_states = EnumSet.noneOf(State.class);
_tcpFlags = new ArrayList<>();
_notDscps = new TreeSet<>();
_notDstIps = new TreeSet<>();
_notDstPorts = new TreeSet<>();
_notEcns = new TreeSet<>();
_notFragmentOffsets = new TreeSet<>();
_notIcmpCodes = new TreeSet<>();
_notIcmpTypes = new TreeSet<>();
_notIpProtocols = EnumSet.noneOf(IpProtocol.class);
_notSrcIps = new TreeSet<>();
_notSrcPorts = new TreeSet<>();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
Header6Space other = (Header6Space) obj;
if (!_dscps.equals(other._dscps)) {
return false;
}
if (!_dstIps.equals(other._dstIps)) {
return false;
}
if (!_dstPorts.equals(other._dstPorts)) {
return false;
}
if (!_ecns.equals(other._ecns)) {
return false;
}
if (!_fragmentOffsets.equals(other._fragmentOffsets)) {
return false;
}
if (!_icmpCodes.equals(other._icmpCodes)) {
return false;
}
if (!_icmpTypes.equals(other._icmpTypes)) {
return false;
}
if (!_ipProtocols.equals(other._ipProtocols)) {
return false;
}
if (_negate != other._negate) {
return false;
}
if (!_notDscps.equals(other._notDscps)) {
return false;
}
if (!_notDstIps.equals(other._notDstIps)) {
return false;
}
if (!_notDstPorts.equals(other._notDstPorts)) {
return false;
}
if (!_notEcns.equals(other._notEcns)) {
return false;
}
if (!_notFragmentOffsets.equals(other._notFragmentOffsets)) {
return false;
}
if (!_notIcmpCodes.equals(other._notIcmpCodes)) {
return false;
}
if (!_notIcmpTypes.equals(other._notIcmpTypes)) {
return false;
}
if (!_notIpProtocols.equals(other._notIpProtocols)) {
return false;
}
if (!_notSrcIps.equals(other._notSrcIps)) {
return false;
}
if (!_notSrcPorts.equals(other._notSrcPorts)) {
return false;
}
if (!_srcIps.equals(other._srcIps)) {
return false;
}
if (!_srcOrDstIps.equals(other._srcOrDstIps)) {
return false;
}
if (!_srcOrDstPorts.equals(other._srcOrDstPorts)) {
return false;
}
if (!_srcPorts.equals(other._srcPorts)) {
return false;
}
if (!_states.equals(other._states)) {
return false;
}
if (!_tcpFlags.equals(other._tcpFlags)) {
return false;
}
return true;
}
public SortedSet<Integer> getDscps() {
return _dscps;
}
public SortedSet<Ip6Wildcard> getDstIps() {
return _dstIps;
}
public SortedSet<SubRange> getDstPorts() {
return _dstPorts;
}
public SortedSet<Integer> getEcns() {
return _ecns;
}
public SortedSet<SubRange> getFragmentOffsets() {
return _fragmentOffsets;
}
public SortedSet<SubRange> getIcmpCodes() {
return _icmpCodes;
}
public SortedSet<SubRange> getIcmpTypes() {
return _icmpTypes;
}
public Set<IpProtocol> getIpProtocols() {
return _ipProtocols;
}
public boolean getNegate() {
return _negate;
}
public SortedSet<Integer> getNotDscps() {
return _notDscps;
}
public SortedSet<Ip6Wildcard> getNotDstIps() {
return _notDstIps;
}
public SortedSet<SubRange> getNotDstPorts() {
return _notDstPorts;
}
public SortedSet<Integer> getNotEcns() {
return _notEcns;
}
public SortedSet<SubRange> getNotFragmentOffsets() {
return _notFragmentOffsets;
}
public SortedSet<SubRange> getNotIcmpCodes() {
return _notIcmpCodes;
}
public SortedSet<SubRange> getNotIcmpTypes() {
return _notIcmpTypes;
}
public Set<IpProtocol> getNotIpProtocols() {
return _notIpProtocols;
}
public SortedSet<Ip6Wildcard> getNotSrcIps() {
return _notSrcIps;
}
public SortedSet<SubRange> getNotSrcPorts() {
return _notSrcPorts;
}
public SortedSet<Ip6Wildcard> getSrcIps() {
return _srcIps;
}
public SortedSet<Ip6Wildcard> getSrcOrDstIps() {
return _srcOrDstIps;
}
public SortedSet<SubRange> getSrcOrDstPorts() {
return _srcOrDstPorts;
}
public SortedSet<SubRange> getSrcPorts() {
return _srcPorts;
}
public Set<State> getStates() {
return _states;
}
public List<TcpFlags> getTcpFlags() {
return _tcpFlags;
}
@Override
public int hashCode() {
// TODO: implement better hashcode
return 0;
}
public boolean matches(Flow6 flow) {
if (!_dscps.isEmpty() && !_dscps.contains(flow.getDscp())) {
return false;
}
if (!_notDscps.isEmpty() && _notDscps.contains(flow.getDscp())) {
return false;
}
if (!_dstIps.isEmpty() && !wildcardsContain(_dstIps, flow.getDstIp())) {
return false;
}
if (!_notDstIps.isEmpty()
&& wildcardsContain(_notDstIps, flow.getDstIp())) {
return false;
}
if (!_dstPorts.isEmpty()
&& !rangesContain(_dstPorts, flow.getDstPort())) {
return false;
}
if (!_notDstPorts.isEmpty()
&& rangesContain(_notDstPorts, flow.getDstPort())) {
return false;
}
if (!_fragmentOffsets.isEmpty()
&& !rangesContain(_fragmentOffsets, flow.getFragmentOffset())) {
return false;
}
if (!_notFragmentOffsets.isEmpty()
&& rangesContain(_notFragmentOffsets, flow.getFragmentOffset())) {
return false;
}
if (!_icmpCodes.isEmpty()
&& !rangesContain(_icmpCodes, flow.getIcmpCode())) {
return false;
}
if (!_notIcmpCodes.isEmpty()
&& rangesContain(_notIcmpCodes, flow.getFragmentOffset())) {
return false;
}
if (!_icmpTypes.isEmpty()
&& !rangesContain(_icmpTypes, flow.getIcmpType())) {
return false;
}
if (!_notIcmpTypes.isEmpty()
&& rangesContain(_notIcmpTypes, flow.getFragmentOffset())) {
return false;
}
if (!_ipProtocols.isEmpty()
&& !_ipProtocols.contains(flow.getIpProtocol())) {
return false;
}
if (!_notIpProtocols.isEmpty()
&& _notIpProtocols.contains(flow.getIpProtocol())) {
return false;
}
if (!_srcOrDstIps.isEmpty()
&& !(wildcardsContain(_srcOrDstIps, flow.getSrcIp())
|| wildcardsContain(_srcOrDstIps, flow.getDstIp()))) {
return false;
}
if (!_srcOrDstPorts.isEmpty()
&& !(rangesContain(_srcOrDstPorts, flow.getSrcPort())
|| rangesContain(_srcOrDstPorts, flow.getDstPort()))) {
return false;
}
if (!_srcIps.isEmpty() && !wildcardsContain(_srcIps, flow.getSrcIp())) {
return false;
}
if (!_notSrcIps.isEmpty()
&& wildcardsContain(_notSrcIps, flow.getSrcIp())) {
return false;
}
if (!_srcPorts.isEmpty()
&& !rangesContain(_srcPorts, flow.getSrcPort())) {
return false;
}
if (!_notSrcPorts.isEmpty()
&& rangesContain(_notSrcPorts, flow.getSrcPort())) {
return false;
}
if (!_states.isEmpty() && !_states.contains(flow.getState())) {
return false;
}
if (!_tcpFlags.isEmpty()) {
boolean matchTcpFlags = false;
for (TcpFlags tcpFlags : _tcpFlags) {
if (tcpFlags.getUseAck()
&& tcpFlags.getAck() ^ (flow.getTcpFlagsAck() == 0)) {
continue;
}
if (tcpFlags.getUseCwr()
&& tcpFlags.getCwr() ^ (flow.getTcpFlagsCwr() == 0)) {
continue;
}
if (tcpFlags.getUseEce()
&& tcpFlags.getEce() ^ (flow.getTcpFlagsEce() == 0)) {
continue;
}
if (tcpFlags.getUseFin()
&& tcpFlags.getFin() ^ (flow.getTcpFlagsFin() == 0)) {
continue;
}
if (tcpFlags.getUsePsh()
&& tcpFlags.getPsh() ^ (flow.getTcpFlagsPsh() == 0)) {
continue;
}
if (tcpFlags.getUseRst()
&& tcpFlags.getRst() ^ (flow.getTcpFlagsRst() == 0)) {
continue;
}
if (tcpFlags.getUseSyn()
&& tcpFlags.getSyn() ^ (flow.getTcpFlagsSyn() == 0)) {
continue;
}
if (tcpFlags.getUseUrg()
&& tcpFlags.getUrg() ^ (flow.getTcpFlagsUrg() == 0)) {
continue;
}
matchTcpFlags = true;
break;
}
if (!matchTcpFlags) {
return false;
}
}
return true;
}
public void setDscps(SortedSet<Integer> dscps) {
_dscps = dscps;
}
public void setDstIps(SortedSet<Ip6Wildcard> dstIps) {
_dstIps = dstIps;
}
public void setDstPorts(SortedSet<SubRange> dstPorts) {
_dstPorts = dstPorts;
}
public void setEcns(SortedSet<Integer> ecns) {
_ecns = ecns;
}
public void setFragmentOffsets(SortedSet<SubRange> fragmentOffsets) {
_fragmentOffsets = fragmentOffsets;
}
public void setIcmpCodes(SortedSet<SubRange> icmpCodes) {
_icmpCodes = icmpCodes;
}
public void setIcmpTypes(SortedSet<SubRange> icmpTypes) {
_icmpTypes = icmpTypes;
}
public void setIpProtocols(Set<IpProtocol> ipProtocols) {
_ipProtocols.clear();
_ipProtocols.addAll(ipProtocols);
}
public void setNegate(boolean negate) {
_negate = negate;
}
public void setNotDscps(SortedSet<Integer> notDscps) {
_notDscps = notDscps;
}
public void setNotDstIps(SortedSet<Ip6Wildcard> notDstIps) {
_notDstIps = notDstIps;
}
public void setNotDstPorts(SortedSet<SubRange> notDstPorts) {
_notDstPorts = notDstPorts;
}
public void setNotEcns(SortedSet<Integer> notEcns) {
_notEcns = notEcns;
}
public void setNotFragmentOffsets(SortedSet<SubRange> notFragmentOffsets) {
_notFragmentOffsets = notFragmentOffsets;
}
public void setNotIcmpCodes(SortedSet<SubRange> notIcmpCodes) {
_notIcmpCodes = notIcmpCodes;
}
public void setNotIcmpTypes(SortedSet<SubRange> notIcmpTypes) {
_notIcmpTypes = notIcmpTypes;
}
public void setNotIpProtocols(Set<IpProtocol> notIpProtocols) {
_notIpProtocols.clear();
_notIpProtocols.addAll(notIpProtocols);
}
public void setNotSrcIps(SortedSet<Ip6Wildcard> notSrcIps) {
_notSrcIps = notSrcIps;
}
public void setNotSrcPorts(SortedSet<SubRange> notSrcPorts) {
_notSrcPorts = notSrcPorts;
}
public void setSrcIps(SortedSet<Ip6Wildcard> srcIps) {
_srcIps = srcIps;
}
public void setSrcOrDstIps(SortedSet<Ip6Wildcard> srcOrDstIps) {
_srcOrDstIps = srcOrDstIps;
}
public void setSrcOrDstPorts(SortedSet<SubRange> srcOrDstPorts) {
_srcOrDstPorts = srcOrDstPorts;
}
public void setSrcPorts(SortedSet<SubRange> srcPorts) {
_srcPorts = srcPorts;
}
public void setStates(Set<State> states) {
_states = states;
}
public void setTcpFlags(List<TcpFlags> tcpFlags) {
_tcpFlags = tcpFlags;
}
@Override
public String toString() {
return "[Protocols:" + _ipProtocols.toString() + ", SrcIps:" + _srcIps
+ ", NotSrcIps:" + _notSrcIps + ", DstIps:" + _dstIps
+ ", NotDstIps:" + _notDstIps + ", SrcOrDstIps:" + _srcOrDstIps
+ ", SrcPorts:" + _srcPorts + ", NotSrcPorts:" + _notSrcPorts
+ ", DstPorts:" + _dstPorts + ", NotDstPorts:" + _notDstPorts
+ ", SrcOrDstPorts:" + _srcOrDstPorts + ", Dscps: "
+ _dscps.toString() + ", NotDscps: " + _notDscps.toString()
+ ", Ecns: " + _ecns.toString() + ", NotEcns: "
+ _notEcns.toString() + ", FragmentOffsets: "
+ _fragmentOffsets.toString() + ", NotFragmentOffsets: "
+ _notFragmentOffsets.toString() + ", IcmpType:" + _icmpTypes
+ ", NotIcmpType:" + _notIcmpTypes + ", IcmpCode:" + _icmpCodes
+ ", NotIcmpCode:" + _notIcmpCodes + ", States:"
+ _states.toString() + ", TcpFlags:" + _tcpFlags.toString() + "]";
}
public final boolean unrestricted() {
boolean ret = _dscps.isEmpty() && _notDscps.isEmpty() && _dstIps.isEmpty()
&& _notDstIps.isEmpty() && _dstPorts.isEmpty()
&& _notDstPorts.isEmpty() && _ecns.isEmpty() && _notEcns.isEmpty()
&& _fragmentOffsets.isEmpty() && _notFragmentOffsets.isEmpty()
&& _icmpCodes.isEmpty() && _notIcmpCodes.isEmpty()
&& _icmpTypes.isEmpty() && _notIcmpTypes.isEmpty()
&& _ipProtocols.isEmpty() && _notIpProtocols.isEmpty()
&& _srcIps.isEmpty() && _notSrcIps.isEmpty()
&& _srcOrDstIps.isEmpty() && _srcOrDstPorts.isEmpty()
&& _srcPorts.isEmpty() && _notSrcPorts.isEmpty()
&& _states.isEmpty() && _tcpFlags.isEmpty();
return ret;
}
}