All Downloads are FREE. Search and download functionalities are using the official Maven repository.

inet.ipaddr.Address Maven / Gradle / Ivy

/*
 * Copyright 2017 Sean C Foley
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     or at
 *     https://github.com/seancfoley/IPAddress/blob/master/LICENSE
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package inet.ipaddr;

import java.math.BigInteger;
import java.util.Iterator;
import java.util.function.Function;

import inet.ipaddr.AddressComparator.CountComparator;
import inet.ipaddr.format.AddressDivisionSeries;
import inet.ipaddr.ipv4.IPv4AddressNetwork;
import inet.ipaddr.ipv6.IPv6AddressNetwork;
import inet.ipaddr.mac.MACAddressNetwork;

/**
 * @custom.core
 * @author sfoley
 *
 */
public abstract class Address implements AddressSegmentSeries, Comparable
{ private static final long serialVersionUID = 4L; /** * @custom.core * @author sfoley * */ public static interface AddressProvider { int getSegmentCount(); SegmentValueProvider getValues(); SegmentValueProvider getUpperValues(); Integer getPrefixLength(); String getZone(); } /** * @custom.core * @author sfoley * */ public static interface SegmentValueProvider { int getValue(int segmentIndex); } public static final String HEX_PREFIX = "0x"; public static final String OCTAL_PREFIX = "0"; public static final char RANGE_SEPARATOR = '-'; public static final String RANGE_SEPARATOR_STR = String.valueOf(RANGE_SEPARATOR); public static final char ALTERNATIVE_RANGE_SEPARATOR = '»'; public static final String ALTERNATIVE_RANGE_SEPARATOR_STR = String.valueOf(ALTERNATIVE_RANGE_SEPARATOR); public static final char SEGMENT_WILDCARD = '*'; public static final String SEGMENT_WILDCARD_STR = String.valueOf(SEGMENT_WILDCARD); public static final String ALTERNATIVE_SEGMENT_WILDCARD_STR = "¿"; public static final char SEGMENT_SQL_WILDCARD = '%'; public static final String SEGMENT_SQL_WILDCARD_STR = String.valueOf(SEGMENT_SQL_WILDCARD); public static final char SEGMENT_SQL_SINGLE_WILDCARD = '_'; public static final String SEGMENT_SQL_SINGLE_WILDCARD_STR = String.valueOf(SEGMENT_SQL_SINGLE_WILDCARD); public static final AddressComparator DEFAULT_ADDRESS_COMPARATOR = new CountComparator(); private static MACAddressNetwork macNetwork; private static IPv6AddressNetwork ipv6Network; private static IPv4AddressNetwork ipv4Network; /* the segments. For IPv4, each element is actually just 1 byte and the array has 4 elements, * while for IPv6, each element is 2 bytes and the array has 8 elements. */ final AddressSection addressSection; /* an object encapsulating a string representing the address, which is the one used to construct the address if the address was constructed from a string */ protected HostIdentifierString fromString; /** * Constructs an address. * @param section the address segments */ protected Address(AddressSection section) { addressSection = section; if(!getNetwork().equals(addressSection.getNetwork())) { throw new NetworkMismatchException(addressSection); } } protected Address(Function supplier) { addressSection = supplier.apply(this); if(!getNetwork().equals(addressSection.getNetwork())) { throw new NetworkMismatchException(addressSection); } } public static IPv6AddressNetwork defaultIpv6Network() { if(ipv6Network == null) { synchronized(Address.class) { if(ipv6Network == null) { ipv6Network = new IPv6AddressNetwork(); } } } return ipv6Network; } public static IPv4AddressNetwork defaultIpv4Network() { if(ipv4Network == null) { synchronized(Address.class) { if(ipv4Network == null) { ipv4Network = new IPv4AddressNetwork(); } } } return ipv4Network; } public static MACAddressNetwork defaultMACNetwork() { if(macNetwork == null) { synchronized(Address.class) { if(macNetwork == null) { macNetwork = new MACAddressNetwork(); } } } return macNetwork; } protected static String getMessage(String key) { return HostIdentifierException.getMessage(key); } @Override public int getSegmentCount() { return getSection().getSegmentCount(); } @Override public int getDivisionCount() { return getSection().getDivisionCount(); } @Override public int getBitCount() { return getSection().getBitCount(); } @Override public int getByteCount() { return getSection().getByteCount(); } @Override public AddressSection getSection() { return addressSection; } @Override public void getSegments(AddressSegment segs[]) { getSection().getSegments(segs); } @Override public void getSegments(int start, int end, AddressSegment segs[], int index) { getSection().getSegments(start, end, segs, index); } /** * @return the maximum possible segment value for this type of address. * Note this is not the maximum value of the segments in this specific address. */ public abstract int getMaxSegmentValue(); @Override public abstract Iterable getIterable(); @Override public abstract Iterator iterator(); @Override public abstract Iterator prefixBlockIterator(); @Override public abstract Address increment(long increment); @Override public abstract Address incrementBoundary(long increment); @Override public abstract Address getLower(); @Override public abstract Address getUpper(); /** * @return whether this address represents more than one address. * Such addresses include CIDR/IP addresses (eg 1.2.3.4/11) or wildcard addresses (eg 1.2.*.4) or range addresses (eg 1.2.3-4.5) */ @Override public boolean isMultiple() { return getSection().isMultiple(); } /** * @return whether this address has an associated prefix length */ @Override public boolean isPrefixed() { return getSection().isPrefixed(); } /** * the largest number of high bits for which this address represents all addresses with the same set of high bits */ @Override public Integer getPrefixLength() { return getSection().getPrefixLength(); } /** * Returns the smallest prefix length possible such that this includes the block of addresses for that prefix. *

* If the entire range can be dictated this way, then this method returns the same value as {@link #getPrefixLengthForSingleBlock()}. * Otherwise, this method will return the minimal possible prefix that can be paired with this address, while {@link #getPrefixLengthForSingleBlock()} will return null. *

* In cases where the final bit in this address division series is constant, this returns the bit length of this address division series. * * @return the prefix length */ @Override public int getMinPrefixLengthForBlock() { return getSection().getMinPrefixLengthForBlock(); } /** * Returns a prefix length for which the range of this address subnet matches the the block of addresses for that prefix. *

* If the range can be dictated this way, then this method returns the same value as {@link #getMinPrefixLengthForBlock()}. *

* If no such prefix exists, returns null. *

* If this segment grouping represents a single value, returns the bit length of this address division series. *

* IP address examples: * 1.2.3.4 returns 32 * 1.2.*.* returns 16 * 1.2.*.0/24 returns 16 in the case of PrefixConfiguration == ALL_PREFIXES_ARE_SUBNETS, 32 otherwise * 1.2.*.4 returns null * 1.2.252-255.* returns 22 * 1.2.3.4/x returns x in the case of PrefixConfiguration == ALL_PREFIXES_ARE_SUBNETS, 32 otherwise * 1.2.0.0/16 returns 16 in the case of PrefixConfiguration == ALL_PREFIXES_ARE_SUBNETS or PREFIXED_ZERO_HOSTS_ARE_SUBNETS, 32 otherwise * * @return the prefix length or null if it does not exist */ @Override public Integer getPrefixLengthForSingleBlock() { return getSection().getPrefixLengthForSingleBlock(); } /** * Whether the MAC address or IP address or other form of address is multicast. * * @see java.net.InetAddress#isMulticastAddress() */ public abstract boolean isMulticast(); /** * Gets the count of addresses that this address may represent. * * If this address is not a subnet block of multiple addresses or has no range of values, then there is only one such address. * * @return */ @Override public BigInteger getCount() { return getSection().getCount(); } /** * If this has a prefix length, the count of the range of values in the prefix. * * If this has no prefix, returns the same value as {@link #getCount()} * * @return */ @Override public BigInteger getPrefixCount() { return getSection().getPrefixCount(); } @Override public int isMore(AddressDivisionSeries other) { return getSection().isMore(other); } @Override public byte[] getBytes() { return getSection().getBytes(); } @Override public byte[] getBytes(byte bytes[]) { return getSection().getBytes(bytes); } @Override public byte[] getBytes(byte bytes[], int index) { return getSection().getBytes(bytes, index); } /** * Gets the bytes for the highest address in the range of addresses represented by this address instance. * * @return */ @Override public byte[] getUpperBytes() { return getSection().getUpperBytes(); } @Override public byte[] getUpperBytes(byte bytes[]) { return getSection().getUpperBytes(bytes); } @Override public byte[] getUpperBytes(byte bytes[], int index) { return getSection().getUpperBytes(bytes, index); } @Override public BigInteger getValue() { return getSection().getValue(); } @Override public BigInteger getUpperValue() { return getSection().getUpperValue(); } @Override public boolean isZero() { return getSection().isZero(); } @Override public boolean includesZero() { return getSection().includesZero(); } @Override public boolean isMax() { return getSection().isMax(); } @Override public boolean includesMax() { return getSection().includesMax(); } @Override public boolean isFullRange() { return getSection().isFullRange(); } /** * Whether the address can be considered a local address (as opposed to a global one) * @return */ public abstract boolean isLocal(); @Override public int hashCode() { return getSection().hashCode(); } @Override public int compareTo(Address other) { if(this == other) { return 0; } return DEFAULT_ADDRESS_COMPARATOR.compare(this, other); } protected abstract boolean isFromSameString(HostIdentifierString otherString); public boolean isSameAddress(Address other) { return other == this || getSection().equals(other.getSection()); } /** * Two Address objects are equal if they represent the same set of addresses. */ @Override public boolean equals(Object o) { if(o == this) { return true; } if(o instanceof Address) { Address other = (Address) o; if(isFromSameString(other.fromString)) { return true; } return isSameAddress(other); } return false; } public abstract boolean contains(Address other); /** * Returns a host identifier string representation for this address, * which will be already validated. * * @return */ public HostIdentifierString toAddressString() { return fromString; } /** * Writes this address as a single hexadecimal value with always the exact same number of characters, with or without a preceding 0x prefix. * * If this section represents a range of values outside of the network prefix length, then this is printed as a range of two hex values. */ @Override public String toHexString(boolean with0xPrefix) { return getSection().toHexString(with0xPrefix); } /** * The normalized string returned by this method is a common and consistent representation of the address. * * The string returned by this method is unique for each address. */ @Override public String toNormalizedString() { return getSection().toNormalizedString(); } /** * This produces a canonical string. * * RFC 5952 describes canonical representations for Ipv6 * http://en.wikipedia.org/wiki/IPv6_address#Recommended_representation_as_text * http://tools.ietf.org/html/rfc5952 * * Each address has a unique canonical string, not counting the prefix, which can give two equal addresses different strings. */ @Override public String toCanonicalString() { return getSection().toCanonicalString(); } /** * Produce short strings for the address in the usual address format. * * Each address has a unique compressed string. * */ @Override public String toCompressedString() { return getSection().toCompressedString(); } @Override public String toString() { return toCanonicalString(); } @Override public String[] getDivisionStrings() { return getSection().getDivisionStrings(); } @Override public String[] getSegmentStrings() { return getSection().getSegmentStrings(); } @Override public abstract Address reverseSegments(); @Override public abstract Address reverseBits(boolean perByte); @Override public abstract Address reverseBytes(); @Override public abstract Address reverseBytesPerSegment(); /** * Returns whether the address range has a prefix length and includes the block of values for its prefix length. */ @Override public boolean isPrefixBlock() { return getSection().isPrefixBlock(); } @Override public boolean containsPrefixBlock(int prefixLength) { return getSection().containsPrefixBlock(prefixLength); } /** * Returns whether the address range the block of values for a single prefix identified by its prefix length. * This is similar to {@link #isPrefixBlock()} except that it returns false when * the subnet has multiple prefixes. * * For instance, 1.*.*.* /16 return false for this method and returns true for {@link #isPrefixBlock()} */ @Override public boolean isSinglePrefixBlock() { return getSection().isSinglePrefixBlock(); } @Override public boolean containsSinglePrefixBlock(int prefixLength) { return getSection().containsSinglePrefixBlock(prefixLength); } @Override public abstract Address toPrefixBlock(); @Override public abstract Address removePrefixLength(); @Override public abstract Address removePrefixLength(boolean zeroed); @Override public abstract Address adjustPrefixBySegment(boolean nextSegment); @Override public abstract Address adjustPrefixBySegment(boolean nextSegment, boolean zeroed); @Override public abstract Address adjustPrefixLength(int adjustment); @Override public abstract Address adjustPrefixLength(int adjustment, boolean zeroed); @Override public abstract Address setPrefixLength(int prefixLength); @Override public abstract Address setPrefixLength(int prefixLength, boolean zeroed); @Override public abstract Address applyPrefixLength(int networkPrefixLength); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy