package org.freertr.addr; import org.freertr.util.bits; /** * one address * * @author matecsaba */ public abstract class addrType implements Comparable { /** * bytes representing this address */ protected byte[] addr; /** * get size of this address in bytes * * @return bytes in the address */ public abstract int getSize(); /** * clone this address * * @return new instance with the same content */ public abstract addrType copyBytes(); /** * text representation of this address * * @return text representing of this address */ public abstract String toString(); /** * convert string to address * * @param s string to convert * @return true if error happened */ public abstract boolean fromString(String s); /** * convert any address to string * * @param at address to convert * @return converted */ public final static String any2str(addrType at) { try { addrIP ai = (addrIP) at; return "" + ai; } catch (Exception e) { return "" + at; } } /** * get size of this address in bits * * @return bits in the address */ public int maxBits() { return addr.length * 8; } /** * set address from other address * * @param src source */ public void setAddr(addrType src) { bits.byteCopy(src.addr, 0, addr, 0, addr.length); } /** * exchange two addresses * * @param other other to exchange */ public void exchangeAddr(addrType other) { byte[] ob = other.addr; other.addr = addr; addr = ob; } /** * convert prefix length to address * * @param len number of 1 bits */ public void fromNetmask(int len) { if (len > addr.length * 8) { len = addr.length * 8; } if (len < 0) { len = 0; } int ofs = len / 8; len &= 7; bits.byteFill(addr, 0, ofs, 0xff); bits.byteFill(addr, ofs, addr.length - ofs, 0); if (len < 1) { return; } addr[ofs] = maskVals[len]; } private final static byte[] maskVals = { (byte) 0x00, (byte) 0x80, (byte) 0xc0, (byte) 0xe0, (byte) 0xf0, (byte) 0xf8, (byte) 0xfc, (byte) 0xfe, (byte) 0xff }; /** * convert address to prefix length * * @return number of 1 bits */ public int toNetmask() { int len; for (len = 0; len < addr.length; len++) { if ((addr[len] & 0xff) != 0xff) { break; } } if (len >= addr.length) { return addr.length * 8; } int val = addr[len] & 0xff; int ofs; for (ofs = 7; ofs >= 0; ofs--) { if ((bits.bitVals[ofs] & val) == 0) { break; } } return len * 8 + 7 - ofs; } /** * bit values in u32 */ public final static int[] bitVals = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 }; /** * set one bit * * @param num bit number */ public void bitSet(int num) { addr[num / 8] |= (byte) bitVals[num & 0x7]; } /** * set one bit * * @param num bit number */ public void bitClear(int num) { addr[num / 8] &= (byte) (-bitVals[num & 0x7] - 1); } /** * set one bit * * @param num bit number * @return bit value */ public boolean bitValue(int num) { return (addr[num / 8] & (byte) bitVals[num & 0x7]) != 0; } /** * create empty address */ public addrType() { addr = new byte[getSize()]; } /** * get bytes of address * * @return bytes represents the address */ public byte[] getBytes() { return addr; } /** * set address bytes from buffer * * @param buf source buffer * @param ofs offset in buffer */ public void fromBuf(byte[] buf, int ofs) { bits.byteCopy(buf, ofs, addr, 0, addr.length); } /** * copy address bytes to buffer * * @param buf target buffer * @param ofs offset in buffer */ public void toBuffer(byte[] buf, int ofs) { bits.byteCopy(addr, 0, buf, ofs, addr.length); } /** * test if address matches to a network/mask * * @param net network to test for * @param msk mask to test for * @return true if matches, false if not matches */ public boolean isMatches(addrType net, addrType msk) { for (int i = 0; i < addr.length; i++) { if ((addr[i] & msk.addr[i]) != (net.addr[i] & msk.addr[i])) { return false; } } return true; } /** * test if address filled with a value * * @param val value to check for * @return true if filled, false if not */ public boolean isFilled(int val) { for (int i = 0; i < addr.length; i++) { if (addr[i] != (byte) val) { return false; } } return true; } /** * fill up buffer with value * * @param val value to set */ public void fillBytes(int val) { for (int i = 0; i < addr.length; i++) { addr[i] = (byte) val; } } /** * fill up buffer with random */ public void fillRandom() { for (int i = 0; i < addr.length; i++) { addr[i] = (byte) bits.randomB(); } } /** * set from a1 and a2 * * @param a1 address 1 * @param a2 address 2 */ public void setAnd(addrType a1, addrType a2) { for (int i = 0; i < addr.length; i++) { addr[i] = (byte) ((a1.addr[i] & 0xff) & (a2.addr[i] & 0xff)); } } /** * set from a1 or a2 * * @param a1 address 1 * @param a2 address 2 */ public void setOr(addrType a1, addrType a2) { for (int i = 0; i < addr.length; i++) { addr[i] = (byte) ((a1.addr[i] & 0xff) | (a2.addr[i] & 0xff)); } } /** * set from a1 xor a2 * * @param a1 address 1 * @param a2 address 2 */ public void setXor(addrType a1, addrType a2) { for (int i = 0; i < addr.length; i++) { addr[i] = (byte) ((a1.addr[i] & 0xff) ^ (a2.addr[i] & 0xff)); } } /** * set from not a1 * * @param a1 address */ public void setNot(addrType a1) { for (int i = 0; i < addr.length; i++) { addr[i] = (byte) (255 - (a1.addr[i] & 0xff)); } } /** * set from shifted a1 * * @param a1 address * @param shf shift */ public void setShl(addrType a1, int shf) { int shb = shf / 8; shf &= 7; for (int i = 0; i < (addr.length - shb); i++) { int p = (a1.addr[i + shb] & 0xff) << shf; if ((i + shb + 1) < addr.length) { p |= (a1.addr[i + shb + 1] & 0xff) >>> (8 - shf); } addr[i] = (byte) p; } for (int i = 0; i < (shb - 1); i++) { addr[addr.length - i - 1] = 0; } } /** * set from a1 + a2 * * @param a1 address 1 * @param a2 address 2 */ public void setAdd(addrType a1, addrType a2) { int o = 0; for (int i = addr.length - 1; i >= 0; i--) { o = (a1.addr[i] & 0xff) + (a2.addr[i] & 0xff) + o; addr[i] = (byte) o; if (o > 0xff) { o = 1; } else { o = 0; } } } /** * set from a1 - a2 * * @param a1 address 1 * @param a2 address 2 */ public void setSub(addrType a1, addrType a2) { int o = 0; for (int i = addr.length - 1; i >= 0; i--) { o = (a1.addr[i] & 0xff) - (a2.addr[i] & 0xff) + o; addr[i] = (byte) o; if (o < 0) { o = -1; } else { o = 0; } } } public int compareTo(addrType o) { return bits.byteComp(addr, 0, o.addr, 0, addr.length); } /** * get address hash * * @return xor value */ public int getHashB() { int o = 0; for (int i = 0; i < addr.length; i++) { o ^= addr[i] & 0xff; } return o; } /** * get address hash * * @return xor value */ public int getHashW() { int o = 0; for (int i = 0; i < addr.length; i += 2) { o ^= addr[i + 0] & 0xff; o ^= (addr[i + 1] & 0xff) << 8; } return o; } }