package org.batfish.datamodel; import org.batfish.common.BatfishException; import org.batfish.common.Pair; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; public class IpWildcard extends Pair<Ip, Ip> { public static final IpWildcard ANY = new IpWildcard(Ip.ZERO, Ip.MAX); /** * */ private static final long serialVersionUID = 1L; private static Ip parseAddress(String str) { if (str.contains(":")) { String[] parts = str.split(":"); if (parts.length != 2) { throw new BatfishException( "Invalid IpWildcard string: '" + str + "'"); } else { return new Ip(parts[0]); } } else if (str.contains("/")) { String[] parts = str.split("/"); if (parts.length != 2) { throw new BatfishException( "Invalid IpWildcard string: '" + str + "'"); } else { return new Ip(parts[0]); } } else { return new Ip(str); } } private static Ip parseMask(String str) { if (str.contains(":")) { String[] parts = str.split(":"); if (parts.length != 2) { throw new BatfishException( "Invalid IpWildcard string: '" + str + "'"); } else { return new Ip(parts[1]); } } else if (str.contains("/")) { String[] parts = str.split("/"); if (parts.length != 2) { throw new BatfishException( "Invalid IpWildcard string: '" + str + "'"); } else { int prefixLength = Integer.parseInt(parts[1]); return Ip.numSubnetBitsToSubnetMask(prefixLength).inverted(); } } else { return Ip.ZERO; } } public IpWildcard(Ip ip) { this(new Prefix(ip, Prefix.MAX_PREFIX_LENGTH)); } public IpWildcard(Ip address, Ip wildcardMask) { super(address, wildcardMask); if (!wildcardMask.valid()) { throw new BatfishException( "Invalid wildcard: " + wildcardMask.toString()); } } public IpWildcard(Prefix prefix) { this(prefix.getAddress(), prefix.getPrefixWildcard()); } @JsonCreator public IpWildcard(String str) { super(parseAddress(str), parseMask(str)); } public boolean contains(Ip ip) { long wildcardIpAsLong = getIp().asLong(); long wildcardMask = getWildcard().asLong(); long ipAsLong = ip.asLong(); long maskedIpAsLong = ipAsLong | wildcardMask; long maskedWildcard = wildcardIpAsLong | wildcardMask; return maskedIpAsLong == maskedWildcard; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } IpWildcard other = (IpWildcard) obj; if (other.getFirst().equals(this.getFirst()) && other.getSecond().equals(this.getSecond())) { return true; } else { return false; } } public Ip getIp() { return _first; } public Ip getWildcard() { return _second; } public boolean isPrefix() { long w = _second.asLong(); long wp = w + 1l; int numTrailingZeros = Long.numberOfTrailingZeros(wp); long check = 1l << numTrailingZeros; return wp == check; } public Prefix toPrefix() { if (isPrefix()) { return new Prefix(_first, _second.inverted()); } else { throw new BatfishException( "Invalid wildcard format for conversion to prefix: " + _second); } } @JsonValue @Override public String toString() { if (_second.equals(Ip.ZERO)) { return _first.toString(); } else if (isPrefix()) { return toPrefix().toString(); } else { return _first.toString() + ":" + _second.toString(); } } }