package org.freertr.addr; /** * represents one prefix (address/netmask) * * @param class of address * @author matecsaba */ public class addrPrefix implements Comparable> { /** * network address */ public T network; /** * the netmask */ public T mask; /** * wildcard mask */ public T wildcard; /** * broadcast address */ public T broadcast; /** * netmask length */ public int maskLen; private addrPrefix() { } /** * create new prefix * * @param adr address in the prefix * @param msk netmask size in bits */ @SuppressWarnings("unchecked") public addrPrefix(T adr, int msk) { maskLen = rangeCheckMask(adr, msk); network = (T) adr.copyBytes(); mask = (T) adr.copyBytes(); wildcard = (T) adr.copyBytes(); broadcast = (T) adr.copyBytes(); update(); } /** * clone this prefix * * @return new instance containing same data */ @SuppressWarnings("unchecked") public addrPrefix copyBytes() { addrPrefix n = new addrPrefix(); n.network = (T) network.copyBytes(); n.mask = (T) mask.copyBytes(); n.wildcard = (T) wildcard.copyBytes(); n.broadcast = (T) broadcast.copyBytes(); n.maskLen = maskLen; return n; } public int compareTo(addrPrefix o) { int i = network.compareTo(o.network); if (i != 0) { return i; } return broadcast.compareTo(o.broadcast); } /** * convert to string * * @return string */ public String toString() { return network + "/" + maskLen; } private int rangeCheckMask(T adr, int msk) { if (msk > adr.maxBits()) { msk = adr.maxBits(); } if (msk < 0) { msk = 0; } return msk; } private void update() { mask.fromNetmask(maskLen); network.setAnd(network, mask); wildcard.setNot(mask); broadcast.setOr(network, wildcard); } /** * change just mask * * @param msk netmask size */ public void setMask(int msk) { maskLen = rangeCheckMask(network, msk); update(); } /** * convert string to address * * @param s string to convert * @return true if error happened */ public boolean fromString(String s) { s = s.trim(); int i = s.indexOf("/"); if (i < 0) { return true; } if (network.fromString(s.substring(0, i).trim())) { return true; } try { maskLen = Integer.parseInt(s.substring(i + 1, s.length()).trim()); } catch (Exception e) { return true; } maskLen = rangeCheckMask(network, maskLen); update(); return false; } /** * test if this prefix contains an address * * @param adr address to test * @return true if matches, false if not matches */ public boolean matches(T adr) { if (adr.compareTo(network) < 0) { return false; } if (adr.compareTo(broadcast) > 0) { return false; } return true; } /** * test if this prefix's network is address * * @param adr address to test * @return true if this is the network address */ public boolean isNetwork(T adr) { return adr.compareTo(network) == 0; } /** * test if this prefix's broadcast is address * * @param adr address to test * @return true if this is the broadcast address */ public boolean isBroadcast(T adr) { return adr.compareTo(broadcast) == 0; } /** * test if this prefix contains this unicast address * * @param adr address to test * @return true if this is the broadcast address */ public boolean isUnicast(T adr) { boolean b = matches(adr); b &= !isNetwork(adr); b &= !isBroadcast(adr); return b; } /** * test if this prefix contains an other * * @param other other to test * @param equals set true to allow equals to contain * @return true if other is subnet of this, false otherwise */ public boolean supernet(addrPrefix other, boolean equals) { if (!matches(other.network)) { return false; } if (!matches(other.broadcast)) { return false; } if (equals) { return true; } if (network.compareTo(other.network) != 0) { return true; } if (broadcast.compareTo(other.broadcast) != 0) { return true; } return false; } /** * convert ipv4 prefix to ip * * @param old old prefix * @return new prefix */ public static addrPrefix ip4toIP(addrPrefix old) { addrIPv4 a4 = addrIPv4.getBroadcast(); a4.fromNetmask(old.maskLen); addrIP a1 = new addrIP(); addrIP a2 = new addrIP(); a1.fromIPv4mask(a4); a2.fromIPv4addr(old.network); return new addrPrefix(a2, a1.toNetmask()); } /** * convert ipv6 prefix to ip * * @param old old prefix * @return new prefix */ public static addrPrefix ip6toIP(addrPrefix old) { addrIPv6 a6 = addrIPv6.getAllNodes(); a6.fromNetmask(old.maskLen); addrIP a1 = new addrIP(); addrIP a2 = new addrIP(); a1.fromIPv6mask(a6); a2.fromIPv6addr(old.network); return new addrPrefix(a2, a1.toNetmask()); } /** * convert prefix to ipv4 * * @param old old prefix * @return new prefix */ public static addrPrefix ip2ip4(addrPrefix old) { addrIPv4 a1 = old.network.toIPv4(); addrIPv4 a2 = old.mask.toIPv4(); return new addrPrefix(a1, a2.toNetmask()); } /** * convert prefix to ipv6 * * @param old old prefix * @return new prefix */ public static addrPrefix ip2ip6(addrPrefix old) { addrIPv6 a1 = old.network.toIPv6(); addrIPv6 a2 = old.mask.toIPv6(); return new addrPrefix(a1, a2.toNetmask()); } /** * convert string to ip prefix * * @param s string to convert * @return null if failed, prefix if succeeded */ public static addrPrefix str2ip(String s) { addrPrefix p4 = new addrPrefix(addrIPv4.getBroadcast(), 0); if (!p4.fromString(s)) { return ip4toIP(p4); } addrPrefix p6 = new addrPrefix(addrIPv6.getAllNodes(), 0); if (!p6.fromString(s)) { return ip6toIP(p6); } int i = s.indexOf("#"); if (i < 0) { return null; } addrPrefix p = new addrPrefix(new addrIP(), addrIP.size * 128); if (p.network.fromString(s.substring(0, i))) { return null; } if (p.broadcast.fromString(s.substring(i + 1, s.length()))) { return null; } return p; } /** * convert prefix to string * * @param old prefix to convert * @return string representation */ public static String ip2str(addrPrefix old) { if (old.network.isIPv4()) { return "" + ip2ip4(old); } else { return "" + ip2ip6(old); } } /** * convert prefix to string * * @param old prefix to convert * @return string representation */ public static String ip2evpn(addrPrefix old) { return old.network + "#" + old.broadcast; } /** * get default route * * @return default route */ public static addrPrefix defaultRoute4() { return new addrPrefix(new addrIPv4(), 0); } /** * get default route * * @return default route */ public static addrPrefix defaultRoute6() { return new addrPrefix(new addrIPv6(), 0); } /** * get default route * * @param ver version number * @return default route */ public static addrPrefix defaultRoute(int ver) { if (ver == 4) { return ip4toIP(defaultRoute4()); } else { return ip6toIP(defaultRoute6()); } } /** * substract on displaying * * @param old prefix to test * @return substract value */ public static int dispSub(addrPrefix old) { int i; if (old.network.isIPv4()) { i = addrIPv4.size; } else { i = addrIPv6.size; } return (addrIP.size - i) * 8; } }