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

inet.ipaddr.ipv4.IPv4Address Maven / Gradle / Ivy

There is a newer version: 5.5.1
Show newest version
/*
 * Copyright 2016-2018 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.ipv4;

import java.net.Inet4Address;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import inet.ipaddr.Address;
import inet.ipaddr.AddressConversionException;
import inet.ipaddr.AddressNetwork.PrefixConfiguration;
import inet.ipaddr.AddressValueException;
import inet.ipaddr.IPAddress;
import inet.ipaddr.IPAddressConverter;
import inet.ipaddr.IPAddressSection.IPStringBuilderOptions;
import inet.ipaddr.IPAddressSegmentSeries;
import inet.ipaddr.IPAddressStringParameters;
import inet.ipaddr.IncompatibleAddressException;
import inet.ipaddr.PrefixLenException;
import inet.ipaddr.format.string.IPAddressStringDivisionSeries;
import inet.ipaddr.format.util.AddressComponentSpliterator;
import inet.ipaddr.format.util.AddressComponentRangeSpliterator;
import inet.ipaddr.format.util.IPAddressPartStringCollection;
import inet.ipaddr.ipv4.IPv4AddressNetwork.IPv4AddressCreator;
import inet.ipaddr.ipv4.IPv4AddressSection.IPv4AddressCache;
import inet.ipaddr.ipv4.IPv4AddressSection.IPv4StringBuilderOptions;
import inet.ipaddr.ipv4.IPv4AddressSection.IPv4StringCollection;
import inet.ipaddr.ipv6.IPv6Address;
import inet.ipaddr.ipv6.IPv6Address.IPv6AddressConverter;
import inet.ipaddr.ipv6.IPv6AddressNetwork;
import inet.ipaddr.ipv6.IPv6AddressNetwork.IPv6AddressCreator;
import inet.ipaddr.ipv6.IPv6AddressSection;
import inet.ipaddr.ipv6.IPv6AddressSegment;


/**
 * An IPv4 address, or a subnet of multiple IPv4 addresses.  Each segment can represent a single value or a range of values.
 * 

* You can construct an IPv4 address from a byte array, from an int, from a {@link inet.ipaddr.Address.SegmentValueProvider}, * from Inet4Address, from an {@link IPv4AddressSection} of 4 segments, or from an array of 4 {@link IPv4AddressSegment} objects. *

* To construct one from a {@link java.lang.String} use * {@link inet.ipaddr.IPAddressString#toAddress()} or {@link inet.ipaddr.IPAddressString#getAddress()}, {@link inet.ipaddr.IPAddressString#toHostAddress()} or {@link inet.ipaddr.IPAddressString#getHostAddress()} * * * @custom.core * @author sfoley * */ public class IPv4Address extends IPAddress implements Iterable { private static final long serialVersionUID = 4L; public static final char SEGMENT_SEPARATOR = '.'; public static final int BITS_PER_SEGMENT = 8; public static final int BYTES_PER_SEGMENT = 1; public static final int SEGMENT_COUNT = 4; public static final int BYTE_COUNT = 4; public static final int BIT_COUNT = 32; public static final int DEFAULT_TEXTUAL_RADIX = 10; public static final int MAX_VALUE_PER_SEGMENT = 0xff; public static final int MAX_VALUE = 0xffffffff; public static final String REVERSE_DNS_SUFFIX = ".in-addr.arpa"; transient IPv4AddressCache addressCache; /** * Constructs an IPv4 address or subnet. * @param segments the address segments * @throws AddressValueException if segments is not length 4 */ public IPv4Address(IPv4AddressSegment[] segments) throws AddressValueException { this(segments, null); } /** * Constructs an IPv4 address or subnet. *

* When networkPrefixLength is non-null, depending on the prefix configuration (see {@link inet.ipaddr.AddressNetwork#getPrefixConfiguration()}, * this object may represent either a single address with that network prefix length, or the prefix subnet block containing all addresses with the same network prefix. *

* @param segments the address segments * @param networkPrefixLength * @throws AddressValueException if segments is not length 4 */ public IPv4Address(IPv4AddressSegment[] segments, Integer networkPrefixLength) throws AddressValueException { super(thisAddress -> ((IPv4Address) thisAddress).getAddressCreator().createSection(segments, networkPrefixLength)); if(getSegmentCount() != SEGMENT_COUNT) { throw new AddressValueException("ipaddress.error.ipv4.invalid.segment.count", getSegmentCount()); } } /** * Constructs an IPv4 address or subnet. * @param section the address segments * @throws AddressValueException if section does not have 4 segments */ public IPv4Address(IPv4AddressSection section) throws AddressValueException { super(section); if(section.getSegmentCount() != SEGMENT_COUNT) { throw new AddressValueException("ipaddress.error.ipv4.invalid.segment.count", section.getSegmentCount()); } } /** * Constructs an IPv4 address. * * @param address the 4 byte IPv4 address */ public IPv4Address(int address) { this(address, null); } /** * Constructs an IPv4 address or subnet. *

* When networkPrefixLength is non-null, depending on the prefix configuration (see {@link inet.ipaddr.AddressNetwork#getPrefixConfiguration()}, * this object may represent either a single address with that network prefix length, or the prefix subnet block containing all addresses with the same network prefix. *

* * @param address the 4 byte IPv4 address * @param networkPrefixLength the CIDR network prefix length, which can be null for no prefix */ public IPv4Address(int address, Integer networkPrefixLength) throws AddressValueException { super(thisAddress -> ((IPv4Address) thisAddress).getAddressCreator().createSectionInternal(address, networkPrefixLength)); } /** * Constructs an IPv4 address. * * @param inet4Address the java.net address object */ public IPv4Address(Inet4Address inet4Address, Integer networkPrefixLength) { this(inet4Address, inet4Address.getAddress(), networkPrefixLength); } /** * Constructs an IPv4 address. * * @param inet4Address the java.net address object */ public IPv4Address(Inet4Address inet4Address) { this(inet4Address, inet4Address.getAddress(), null); } private IPv4Address(Inet4Address inet4Address, byte[] bytes, Integer networkPrefixLength) throws AddressValueException { super(thisAddress -> ((IPv4Address) thisAddress).getAddressCreator().createSection(bytes, 0, bytes.length, IPv4Address.SEGMENT_COUNT, networkPrefixLength)); getSection().setInetAddress(inet4Address); } /** * Constructs an IPv4 address. * * @param bytes the 4 byte IPv4 address in network byte order - if longer than 4 bytes the additional bytes must be zero, if shorter than 4 bytes then then the bytes are sign-extended to 4 bytes. * @throws AddressValueException if bytes not equivalent to a 4 byte address */ public IPv4Address(byte[] bytes) throws AddressValueException { this(bytes, null); } /** * Constructs an IPv4 address or subnet. *

* Similar to {@link #IPv4Address(byte[])} except that you can specify the start and end of the address in the given byte array. * * @param bytes * @throws AddressValueException */ public IPv4Address(byte[] bytes, int byteStartIndex, int byteEndIndex) throws AddressValueException { this(bytes, byteStartIndex, byteEndIndex, null); } /** * Constructs an IPv4 address or subnet. *

* When networkPrefixLength is non-null, depending on the prefix configuration (see {@link inet.ipaddr.AddressNetwork#getPrefixConfiguration()}, * this object may represent either a single address with that network prefix length, or the prefix subnet block containing all addresses with the same network prefix. *

* * @param bytes the 4 byte IPv4 address in network byte order - if longer than 4 bytes the additional bytes must be zero, if shorter than 4 bytes then the bytes are sign-extended to 4 bytes. * @param networkPrefixLength the CIDR network prefix length, which can be null for no prefix * @throws AddressValueException if bytes not equivalent to a 4 byte address */ public IPv4Address(byte[] bytes, Integer networkPrefixLength) throws AddressValueException { this(bytes, 0, bytes.length, networkPrefixLength); } /** * Constructs an IPv4 address or subnet. *

* Similar to {@link #IPv4Address(byte[],Integer)} except that you can specify the start and end of the address in the given byte array. *

* When networkPrefixLength is non-null, depending on the prefix configuration (see {@link inet.ipaddr.AddressNetwork#getPrefixConfiguration()}, * this object may represent either a single address with that network prefix length, or the prefix subnet block containing all addresses with the same network prefix. *

* * @param bytes the 4 byte IPv4 address - if longer than 4 bytes the additional bytes must be zero, if shorter than 4 bytes then the bytes are sign-extended to 4 bytes. * @param networkPrefixLength the CIDR network prefix length, which can be null for no prefix * @throws AddressValueException if bytes not equivalent to a 4 byte address */ public IPv4Address(byte[] bytes, int byteStartIndex, int byteEndIndex, Integer networkPrefixLength) throws AddressValueException { super(thisAddress -> ((IPv4Address) thisAddress).getAddressCreator().createSection(bytes, byteStartIndex, byteEndIndex, IPv4Address.SEGMENT_COUNT, networkPrefixLength)); } /** * Constructs an IPv4 address or subnet. *

* When networkPrefixLength is non-null, depending on the prefix configuration (see {@link inet.ipaddr.AddressNetwork#getPrefixConfiguration()}, * this object may represent either a single address with that network prefix length, or the prefix subnet block containing all addresses with the same network prefix. *

* * @param lowerValueProvider supplies the 1 byte lower values for each segment * @param upperValueProvider supplies the 1 byte upper values for each segment * @param networkPrefixLength the CIDR network prefix length, which can be null for no prefix */ public IPv4Address(SegmentValueProvider lowerValueProvider, SegmentValueProvider upperValueProvider, Integer networkPrefixLength) throws AddressValueException { super(thisAddress -> ((IPv4Address) thisAddress).getAddressCreator().createFullSectionInternal(lowerValueProvider, upperValueProvider, networkPrefixLength)); } /** * Constructs an IPv4 address or subnet. * * @param lowerValueProvider supplies the 1 byte lower values for each segment * @param upperValueProvider supplies the 1 byte upper values for each segment */ public IPv4Address(SegmentValueProvider lowerValueProvider, SegmentValueProvider upperValueProvider) { this(lowerValueProvider, upperValueProvider, null); } /** * Constructs an IPv4 address. *

* When networkPrefixLength is non-null, depending on the prefix configuration (see {@link inet.ipaddr.AddressNetwork#getPrefixConfiguration()}, * this object may represent either a single address with that network prefix length, or the prefix subnet block containing all addresses with the same network prefix. *

* * @param valueProvider supplies the 1 byte value for each segment * @param networkPrefixLength the CIDR network prefix length, which can be null for no prefix */ public IPv4Address(SegmentValueProvider valueProvider, Integer networkPrefixLength) throws AddressValueException { this(valueProvider, valueProvider, networkPrefixLength); } /** * Constructs an IPv4 address. * * @param valueProvider supplies the 1 byte value for each segment */ public IPv4Address(SegmentValueProvider valueProvider) { this(valueProvider, (Integer) null); } @Override public IPv4AddressSection getSection() { return (IPv4AddressSection) super.getSection(); } @Override public IPv4AddressSection getSection(int index) { return getSection().getSection(index); } @Override public IPv4AddressSection getSection(int index, int endIndex) { return getSection().getSection(index, endIndex); } @Override public IPv4AddressSegment getDivision(int index) { return getSegment(index); } @Override public IPv4AddressSegment getSegment(int index) { return getSection().getSegment(index); } @Override public IPv4AddressSegment[] getSegments() { return getSection().getSegments(); } @Override public IPAddressStringDivisionSeries[] getParts(IPStringBuilderOptions options) { return getParts(IPv4StringBuilderOptions.from(options)); } public IPAddressStringDivisionSeries[] getParts(IPv4StringBuilderOptions options) { IPAddressStringDivisionSeries parts[] = getSection().getParts(options); IPv6Address ipv6Addr = getConverted(options); if(ipv6Addr != null) { IPAddressStringDivisionSeries ipv6Parts[] = ipv6Addr.getParts(options.ipv6ConverterOptions); IPAddressStringDivisionSeries tmp[] = parts; parts = new IPAddressStringDivisionSeries[tmp.length + ipv6Parts.length]; System.arraycopy(tmp, 0, parts, 0, tmp.length); System.arraycopy(ipv6Parts, 0, parts, tmp.length, ipv6Parts.length); } return parts; } @Override public int getSegmentCount() { return SEGMENT_COUNT; } @Override public int getByteCount() { return BYTE_COUNT; } @Override public int getBitCount() { return BIT_COUNT; } @Override public boolean isIPv4() { return true; } @Override public IPv4Address toIPv4() { return this; } @Override public boolean isIPv4Convertible() { return true; } /** * Create an IPv6 mixed address using the given ipv6 segments and using this address for the embedded IPv4 segments * * @param segs * @return */ public IPv6Address getIPv6Address(IPv6AddressSegment segs[]) { IPv6AddressCreator creator = getIPv6Network().getAddressCreator(); return creator.createAddress(IPv6AddressSection.createSection(creator, segs, this)); /* address creation */ } public IPv6Address getIPv4MappedAddress() { IPv6AddressCreator creator = getIPv6Network().getAddressCreator(); IPv6AddressSegment zero = creator.createSegment(0); IPv6AddressSegment segs[] = creator.createSegmentArray(IPv6Address.MIXED_ORIGINAL_SEGMENT_COUNT); segs[0] = segs[1] = segs[2] = segs[3] = segs[4] = zero; segs[5] = creator.createSegment(IPv6Address.MAX_VALUE_PER_SEGMENT); return getIPv6Address(segs); } /** * Override this method to convert in your own way. * The default behaviour uses IPv4-mapped conversion. * * You should also override {@link #toIPv6()} to match the conversion. * * @see IPv4Address#toIPv6() */ @Override public boolean isIPv6Convertible() { IPAddressConverter conv = DEFAULT_ADDRESS_CONVERTER; return conv.isIPv6Convertible(this); } /** * Returns this address converted to IPv6. *

* You can also use {@link #isIPv6Convertible()} to determine convertibility. Both use an instance of {@link IPAddressConverter.DefaultAddressConverter} which uses IPv4-mapped address mappings from rfc 4038. *

* Override this method and {@link IPv6Address#isIPv6Convertible()} if you wish to map IPv4 to IPv6 according to the mappings defined by * in {@link IPv6Address#isIPv4Compatible()}, {@link IPv6Address#isIPv4Mapped()}, {@link IPv6Address#is6To4()} or some other mapping. *

* If you override this method, you should also override the {@link IPv4Address#isIPv6Convertible()} method to match this behaviour, * and potentially also override the reverse conversion {@link IPv6Address#toIPv4()} in your {@link IPv6Address} subclass. */ @Override public IPv6Address toIPv6() { IPAddressConverter conv = DEFAULT_ADDRESS_CONVERTER; return conv.toIPv6(this); } /** * The broadcast address has the same prefix but a host that is all 1 bits. * If this address or subnet is not prefixed, this returns the address of all 1 bits, the "max" address. * * @return */ public IPv4Address toBroadcastAddress() { return toMaxHost(); } /** * The network address has the same prefix but a zero host. * If this address or subnet is not prefixed, this returns the zero "any" address. * * @return */ public IPv4Address toNetworkAddress() { return toZeroHost(); } void cache(IPv4Address lower, IPv4Address upper) { getSection().cache(this, lower, upper); } @Override public IPv4Address getLowerNonZeroHost() { return getSection().getLowestOrHighest(this, true, true); } @Override public IPv4Address getLower() { return getSection().getLowestOrHighest(this, true, false); } @Override public IPv4Address getUpper() { return getSection().getLowestOrHighest(this, false, false); } /** * Returns the address (or lowest value of the address if a subnet) as a signed integer * @return the signed integer lower address value */ public int intValue() { return getSection().intValue(); } /** * Returns the address (or highest value of the address if a subnet) as a signed integer * @return the signed integer upper address value */ public int upperIntValue() { return getSection().upperIntValue(); } /** * Returns the address (or lowest value of the address if a subnet) as a positive integer * @return the positive integer lower address value */ public long longValue() { return getSection().longValue(); } /** * Returns the address (or highest value of the address if a subnet) as a positive integer * @return the positive integer upper address value */ public long upperLongValue() { return getSection().upperLongValue(); } /** * Replaces segments starting from startIndex and ending before endIndex with the same number of segments starting at replacementStartIndex from the replacement section * * @param startIndex * @param endIndex * @param replacement * @param replacementIndex * @throws IndexOutOfBoundsException * @return */ public IPv4Address replace(int startIndex, int endIndex, IPv4Address replacement, int replacementIndex) { return checkIdentity(getSection().replace(startIndex, endIndex, replacement.getSection(), replacementIndex, replacementIndex + (endIndex - startIndex))); } @Override public IPv4Address reverseBits(boolean perByte) { return checkIdentity(getSection().reverseBits(perByte)); } @Override public IPv4Address reverseBytes() { return checkIdentity(getSection().reverseBytes()); } @Override public IPv4Address reverseBytesPerSegment() { return this; } @Override public IPv4Address reverseSegments() { return checkIdentity(getSection().reverseSegments()); } private IPv4Address checkIdentity(IPv4AddressSection newSection) { IPv4AddressSection section = getSection(); if(newSection == section) { return this; } return getAddressCreator().createAddress(newSection); } @Override public IPv4Address adjustPrefixBySegment(boolean nextSegment) { return checkIdentity(getSection().adjustPrefixBySegment(nextSegment)); } @Override public IPv4Address adjustPrefixBySegment(boolean nextSegment, boolean zeroed) { return checkIdentity(getSection().adjustPrefixBySegment(nextSegment, zeroed)); } @Override public IPv4Address adjustPrefixLength(int adjustment) { return checkIdentity(getSection().adjustPrefixLength(adjustment)); } @Override public IPv4Address adjustPrefixLength(int adjustment, boolean zeroed) { return checkIdentity(getSection().adjustPrefixLength(adjustment, zeroed)); } @Override public IPv4Address setPrefixLength(int prefixLength) { return setPrefixLength(prefixLength, true); } @Override public IPv4Address setPrefixLength(int prefixLength, boolean zeroed) { return checkIdentity(getSection().setPrefixLength(prefixLength, zeroed)); } @Override public IPv4Address setPrefixLength(int prefixLength, boolean zeroed, boolean zeroHostIsBlock) throws PrefixLenException { return checkIdentity(getSection().setPrefixLength(prefixLength, zeroed, zeroHostIsBlock)); } @Deprecated @Override public IPv4Address applyPrefixLength(int networkPrefixLength) throws PrefixLenException { return checkIdentity(getSection().applyPrefixLength(networkPrefixLength)); } @Override @Deprecated public IPv4Address removePrefixLength(boolean zeroed) { return checkIdentity(getSection().removePrefixLength(zeroed)); } @Override public IPv4Address withoutPrefixLength() { return removePrefixLength(false); } @Override @Deprecated public IPv4Address removePrefixLength() { return removePrefixLength(true); } @Override public Iterator segmentsNonZeroHostIterator() { return getSection().segmentsNonZeroHostIterator(); } @Override public Iterator segmentsIterator() { return getSection().segmentsIterator(); } @Override public AddressComponentRangeSpliterator segmentsSpliterator() { return getSection().segmentsSpliterator(this, getAddressCreator()); } @Override public Stream segmentsStream() { return StreamSupport.stream(segmentsSpliterator(), false); } @Override public Iterator iterator() { return getSection().iterator(this, getAddressCreator(), null); } @Override public AddressComponentSpliterator spliterator() { return getSection().spliterator(this, getAddressCreator(), false); } @Override public Stream stream() { return StreamSupport.stream(spliterator(), false); } @Override public Iterator nonZeroHostIterator() { Predicate excludeFunc = null; if(includesZeroHost()) { int prefLength = getNetworkPrefixLength(); excludeFunc = s -> getSection().isZeroHost(s, prefLength); } return getSection().iterator(this, getAddressCreator(), excludeFunc); } @Override public Iterator prefixBlockIterator() { return getSection().prefixIterator(this, getAddressCreator(), true); } @Override public AddressComponentSpliterator prefixBlockSpliterator() { return getSection().prefixSpliterator(this, getAddressCreator(), true); } @Override public Stream prefixBlockStream() { return StreamSupport.stream(prefixBlockSpliterator(), false); } @Override public Iterator prefixBlockIterator(int prefixLength) { return getSection().prefixIterator(this, getAddressCreator(), true, prefixLength); } @Override public AddressComponentSpliterator prefixBlockSpliterator(int prefixLength) { return getSection().prefixSpliterator(this, getAddressCreator(), true, prefixLength); } @Override public Stream prefixBlockStream(int prefixLength) { return StreamSupport.stream(prefixBlockSpliterator(prefixLength), false); } @Override public Iterator prefixIterator() { return getSection().prefixIterator(this, getAddressCreator(), false); } @Override public AddressComponentSpliterator prefixSpliterator() { return getSection().prefixSpliterator(this, getAddressCreator(), false); } @Override public Stream prefixStream() { return StreamSupport.stream(prefixSpliterator(), false); } @Override public Iterator prefixIterator(int prefixLength) { return getSection().prefixIterator(this, getAddressCreator(), false, prefixLength); } @Override public AddressComponentSpliterator prefixSpliterator(int prefixLength) { return getSection().prefixSpliterator(this, getAddressCreator(), false, prefixLength); } @Override public Stream prefixStream(int prefixLength) { return StreamSupport.stream(prefixSpliterator(prefixLength), false); } @Override public Iterator blockIterator(int segmentCount) { return getSection().blockIterator(this, getAddressCreator(), segmentCount); } @Override public AddressComponentSpliterator blockSpliterator(int segmentCount) { return getSection().blockSpliterator(this, getAddressCreator(), segmentCount); } @Override public Stream blockStream(int segmentCount) { return StreamSupport.stream(blockSpliterator(segmentCount), false); } @SuppressWarnings("unchecked") @Override public Iterator sequentialBlockIterator() { return (Iterator) super.sequentialBlockIterator(); } @SuppressWarnings("unchecked") @Override public AddressComponentSpliterator sequentialBlockSpliterator() { return (AddressComponentSpliterator) super.sequentialBlockSpliterator(); } @SuppressWarnings("unchecked") @Override public Stream sequentialBlockStream() { return (Stream) super.sequentialBlockStream(); } @Override public Iterable getIterable() { return this; } @Override public IPv4Address increment(long increment) { return checkIdentity(getSection().increment(increment)); } @Override public IPv4Address incrementBoundary(long increment) { return checkIdentity(getSection().incrementBoundary(increment)); } IPv4AddressCreator getAddressCreator() { return getNetwork().getAddressCreator(); } @Override public IPv4AddressNetwork getNetwork() { return defaultIpv4Network(); } /** * Returns the IPv6 network used by {@link #getIPv4MappedAddress()} and {@link #getIPv6Address(IPv6AddressSegment[])} * * @return */ public IPv6AddressNetwork getIPv6Network() { return defaultIpv6Network(); } @Override protected IPv4Address convertArg(IPAddress arg) throws AddressConversionException { IPv4Address converted = arg.toIPv4(); if(converted == null) { throw new AddressConversionException(this, arg); } return converted; } @Override public IPv4Address intersect(IPAddress other) throws AddressConversionException { IPv4AddressSection thisSection = getSection(); IPv4AddressSection section = thisSection.intersect(convertArg(other).getSection()); if(section == null) { return null; } IPv4AddressCreator creator = getAddressCreator(); IPv4Address result = creator.createAddress(section); /* address creation */ return result; } @Override public IPv4Address[] subtract(IPAddress other) throws AddressConversionException { IPv4AddressSection thisSection = getSection(); IPv4AddressSection sections[] = thisSection.subtract(convertArg(other).getSection()); if(sections == null) { return null; } IPv4AddressCreator creator = getAddressCreator(); IPv4Address result[] = new IPv4Address[sections.length]; for(int i = 0; i < result.length; i++) { result[i] = creator.createAddress(sections[i]); /* address creation */ } return result; } @Override public IPv4Address toZeroHost() { return toZeroHost(false); } @Override protected IPv4Address toZeroHost(boolean boundariesOnly) { if(!isPrefixed()) { IPv4AddressNetwork network = getNetwork(); PrefixConfiguration config = network.getPrefixConfiguration(); IPv4Address addr = network.getNetworkMask(0, !config.allPrefixedAddressesAreSubnets()); if(config.zeroHostsAreSubnets()) { addr = addr.getLower(); } return addr; } if(includesZeroHost() && isSingleNetwork()) { return getLower();//cached } return checkIdentity(getSection().createZeroHost(boundariesOnly)); } @Override public IPv4Address toZeroHost(int prefixLength) { if(isPrefixed() && prefixLength == getNetworkPrefixLength()) { return toZeroHost(); } return checkIdentity(getSection().toZeroHost(prefixLength)); } @Override public IPv4Address toZeroNetwork() { if(!isPrefixed()) { return getNetwork().getHostMask(getBitCount()); } return checkIdentity(getSection().createZeroNetwork()); } @Override public IPv4Address toMaxHost() { if(!isPrefixed()) { IPv4Address resultNoPrefix = getNetwork().getHostMask(0); if(getNetwork().getPrefixConfiguration().allPrefixedAddressesAreSubnets()) { return resultNoPrefix; } return resultNoPrefix.setPrefixLength(0); } if(includesMaxHost() && isSingleNetwork()) { return getUpper();//cached } return checkIdentity(getSection().createMaxHost()); } @Override public IPv4Address toMaxHost(int prefixLength) { if(isPrefixed() && prefixLength == getNetworkPrefixLength()) { return toMaxHost(); } return checkIdentity(getSection().toMaxHost(prefixLength)); } @Override public IPv4Address mask(IPAddress mask, boolean retainPrefix) throws IncompatibleAddressException, AddressConversionException { return checkIdentity(getSection().mask(convertArg(mask).getSection(), retainPrefix)); } @Override public IPv4Address mask(IPAddress mask) throws IncompatibleAddressException, AddressConversionException { return mask(mask, false); } @Override public IPv4Address maskNetwork(IPAddress mask, int networkPrefixLength) throws IncompatibleAddressException, PrefixLenException, AddressConversionException { return checkIdentity(getSection().maskNetwork(convertArg(mask).getSection(), networkPrefixLength)); } @Override public IPv4Address bitwiseOr(IPAddress mask, boolean retainPrefix) throws IncompatibleAddressException, AddressConversionException { return checkIdentity(getSection().bitwiseOr(convertArg(mask).getSection(), retainPrefix)); } @Override public IPv4Address bitwiseOr(IPAddress mask) throws IncompatibleAddressException, AddressConversionException { return bitwiseOr(mask, false); } @Override public IPv4Address bitwiseOrNetwork(IPAddress mask, int networkPrefixLength) throws IncompatibleAddressException, PrefixLenException, AddressConversionException { return checkIdentity(getSection().bitwiseOrNetwork(convertArg(mask).getSection(), networkPrefixLength)); } @Override public IPv4Address getHostMask() { return (IPv4Address) super.getHostMask(); } @Override public IPv4Address getNetworkMask() { return (IPv4Address) super.getNetworkMask(); } @Override public IPv4AddressSection getNetworkSection() { return getSection().getNetworkSection(); } @Override public IPv4AddressSection getNetworkSection(int networkPrefixLength) throws PrefixLenException { return getSection().getNetworkSection(networkPrefixLength); } @Override public IPv4AddressSection getNetworkSection(int networkPrefixLength, boolean withPrefixLength) throws PrefixLenException { return getSection().getNetworkSection(networkPrefixLength, withPrefixLength); } @Override public IPv4AddressSection getHostSection() { return getSection().getHostSection(); } @Override public IPv4AddressSection getHostSection(int networkPrefixLength) throws PrefixLenException { return getSection().getHostSection(networkPrefixLength); } @Override public IPv4Address toPrefixBlock() { Integer prefixLength = getNetworkPrefixLength(); if(prefixLength == null || getNetwork().getPrefixConfiguration().allPrefixedAddressesAreSubnets()) { return this; } return toPrefixBlock(prefixLength); } @Override public IPv4Address toPrefixBlock(int networkPrefixLength) throws PrefixLenException { return checkIdentity(getSection().toPrefixBlock(networkPrefixLength)); } @Override public IPv4Address assignPrefixForSingleBlock() { return (IPv4Address) super.assignPrefixForSingleBlock(); } @Override public IPv4Address assignMinPrefixForBlock() { return (IPv4Address) super.assignMinPrefixForBlock(); } @Override public IPv4Address coverWithPrefixBlock() { return (IPv4Address) IPv4AddressSection.coverWithPrefixBlock(this, getLower(), getUpper()); } @Override public IPv4Address coverWithPrefixBlock(IPAddress other) throws AddressConversionException { return IPv4AddressSection.coverWithPrefixBlock( this, convertArg(other), IPv4Address::getLower, IPv4Address::getUpper, Address.ADDRESS_LOW_VALUE_COMPARATOR::compare); } /** * Produces an array of prefix blocks that cover the same set of addresses as this. *

* Unlike {@link #spanWithPrefixBlocks(IPAddress)} this method only includes addresses that are a part of this subnet. */ @Override public IPv4Address[] spanWithPrefixBlocks() { if(isSequential()) { if(isSinglePrefixBlock()) { return new IPv4Address[] {this}; } return spanWithPrefixBlocks(this); } @SuppressWarnings("unchecked") ArrayList list = (ArrayList) spanWithBlocks(true); return list.toArray(new IPv4Address[list.size()]); } @Override public IPv4Address[] spanWithPrefixBlocks(IPAddress other) throws AddressConversionException { return IPAddress.getSpanningPrefixBlocks( this, convertArg(other), IPv4Address::getLower, IPv4Address::getUpper, Address.ADDRESS_LOW_VALUE_COMPARATOR::compare, IPv4Address::assignPrefixForSingleBlock, IPv4Address::withoutPrefixLength, getAddressCreator()::createAddressArray); } /** * Produces an array of blocks that are sequential that cover the same set of addresses as this. *

* This array can be shorter than that produced by {@link #spanWithPrefixBlocks()} and is never longer. *

* Unlike {@link #spanWithSequentialBlocks(IPAddress)} this method only includes addresses that are a part of this subnet. */ @Override public IPv4Address[] spanWithSequentialBlocks() throws AddressConversionException { if(isSequential()) { return new IPv4Address[] { withoutPrefixLength() }; } @SuppressWarnings("unchecked") ArrayList list = (ArrayList) spanWithBlocks(false); return list.toArray(new IPv4Address[list.size()]); } @Override public IPv4Address[] spanWithSequentialBlocks(IPAddress other) throws AddressConversionException { return IPAddress.getSpanningSequentialBlocks( this, convertArg(other), IPv4Address::getLower, IPv4Address::getUpper, Address.ADDRESS_LOW_VALUE_COMPARATOR::compare, IPv4Address::withoutPrefixLength, getAddressCreator()); } @Override public IPv4AddressSeqRange spanWithRange(IPAddress other) throws AddressConversionException { return toSequentialRange(other); } @Override public IPv4Address[] mergeToPrefixBlocks(IPAddress ...addresses) throws AddressConversionException { if(addresses.length == 0) { if(isSinglePrefixBlock()) { return new IPv4Address[] {this}; } } IPAddress[] converted = getConverted(addresses); List blocks = getMergedPrefixBlocks(converted); return blocks.toArray(new IPv4Address[blocks.size()]); } private IPAddress[] getConverted(IPAddress... addresses) { IPAddress converted[] = new IPAddress[addresses.length + 1]; for(int i = 0, j = 1; i < addresses.length; i = j++) { converted[j] = convertArg(addresses[i]); } converted[0] = this; return converted; } @Override public IPv4Address[] mergeToSequentialBlocks(IPAddress ...addresses) throws AddressConversionException { if(addresses.length == 0) { if(isSequential()) { return new IPv4Address[] {this}; } } IPAddress[] converted = getConverted(addresses); List blocks = getMergedSequentialBlocks(converted, getAddressCreator()); return blocks.toArray(new IPv4Address[blocks.size()]); } @Override public Inet4Address toUpperInetAddress() { return (Inet4Address) super.toUpperInetAddress(); } @Override public Inet4Address toInetAddress() { return (Inet4Address) super.toInetAddress(); } @Override @Deprecated public IPv4AddressSeqRange toSequentialRange(IPAddress other) { return new IPv4AddressSeqRange(this, convertArg(other)); } @Override public IPv4AddressSeqRange toSequentialRange() { IPv4Address thiz = withoutPrefixLength(); return new IPv4AddressSeqRange(thiz.getLower(), thiz.getUpper(), true); } @Override public boolean isLocal() { if(isMulticast()) { //1110... IPv4AddressSegment seg0 = getSegment(0); //http://www.tcpipguide.com/free/t_IPMulticastAddressing.htm //rfc4607 and https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml //239.0.0.0-239.255.255.255 organization local if(seg0.matches(239)) { return true; } IPv4AddressSegment seg1 = getSegment(1), seg2 = getSegment(2); return // 224.0.0.0 to 224.0.0.255 local // includes link local multicast name resolution https://tools.ietf.org/html/rfc4795 224.0.0.252 (seg0.matches(224) && seg1.isZero() && seg2.isZero()) //232.0.0.1 - 232.0.0.255 Reserved for IANA allocation [RFC4607] //232.0.1.0 - 232.255.255.255 Reserved for local host allocation [RFC4607] || (seg0.matches(232) && !(seg1.isZero() && seg2.isZero())); } return isLinkLocal() || isPrivate() || isAnyLocal(); } /** * @see java.net.InetAddress#isLinkLocalAddress() */ @Override public boolean isLinkLocal() { if(isMulticast()) { //224.0.0.252 Link-local Multicast Name Resolution [RFC4795] return getSegment(0).matches(224) && getSegment(1).isZero() && getSegment(2).isZero() && getSegment(3).matches(252); } return getSegment(0).matches(169) && getSegment(1).matches(254); } /** * Unicast addresses allocated for private use * * @see java.net.InetAddress#isSiteLocalAddress() */ public boolean isPrivate() { // refer to RFC 1918 // 10/8 prefix // 172.16/12 prefix (172.16.0.0 – 172.31.255.255) // 192.168/16 prefix IPv4AddressSegment seg0 = getSegment(0); IPv4AddressSegment seg1 = getSegment(1); return seg0.matches(10) || (seg0.matches(172) && seg1.matchesWithPrefixMask(16, 4)) || (seg0.matches(192) && seg1.matches(168)); } @Override public boolean isMulticast() { // 1110... //224.0.0.0/4 return getSegment(0).matchesWithPrefixMask(0xe0, 4); } /** * @see java.net.InetAddress#isLoopbackAddress() */ @Override public boolean isLoopback() { return getSegment(0).matches(127); } /** * @custom.core * @author sfoley * */ public interface IPv4AddressConverter { /** * If the given address is IPv4, or can be converted to IPv4, returns that {@link IPv4Address}. Otherwise, returns null. */ IPv4Address toIPv4(IPAddress address); } ////////////////string creation below /////////////////////////////////////////////////////////////////////////////////////////// @Override protected IPAddressStringParameters createFromStringParams() { return new IPAddressStringParameters.Builder(). getIPv4AddressParametersBuilder().setNetwork(getNetwork()).getParentBuilder(). getIPv6AddressParametersBuilder().setNetwork(getIPv6Network()).getParentBuilder().toParams(); } /** * Creates the normalized string for an address without having to create the address objects first. * * @param lowerValueProvider * @param upperValueProvider * @param prefixLength * @param network use {@link #defaultIpv4Network()} if there is no custom network in use * @return */ public static String toNormalizedString(IPv4AddressNetwork network, SegmentValueProvider lowerValueProvider, SegmentValueProvider upperValueProvider, Integer prefixLength) { return toNormalizedString(network.getPrefixConfiguration(), lowerValueProvider, upperValueProvider, prefixLength, SEGMENT_COUNT, BYTES_PER_SEGMENT, BITS_PER_SEGMENT, MAX_VALUE_PER_SEGMENT, SEGMENT_SEPARATOR, DEFAULT_TEXTUAL_RADIX, null); } /** * @author sfoley * */ public static enum inet_aton_radix { OCTAL, HEX, DECIMAL; int getRadix() { if(this == OCTAL) { return 8; } else if(this == HEX) { return 16; } return 10; } String getSegmentStrPrefix() { if(this == OCTAL) { return "0"; } else if(this == HEX) { return "0x"; } return null; } @Override public String toString() { if(this == OCTAL) { return "octal"; } else if(this == HEX) { return "hexadecimal"; } return "decimal"; } } /** * Returns a string like the inet_aton style string * @return */ public String toInetAtonString(IPv4Address.inet_aton_radix radix) { return getSection().toInetAtonString(radix); } public String toInetAtonString(IPv4Address.inet_aton_radix radix, int joinedCount) throws IncompatibleAddressException { return getSection().toInetAtonString(radix, joinedCount); } @Override public String toSegmentedBinaryString() { return getSection().toSegmentedBinaryString(); } @Override public String toUNCHostName() { return super.toCanonicalString(); } @Override public IPAddressPartStringCollection toStandardStringCollection() { return toStringCollection(IPv4StringBuilderOptions.STANDARD_OPTS); } @Override public IPAddressPartStringCollection toAllStringCollection() { return toStringCollection(IPv4StringBuilderOptions.ALL_OPTS); } @Override public IPAddressPartStringCollection toStringCollection(IPStringBuilderOptions opts) { return toStringCollection(IPv4StringBuilderOptions.from(opts)); } private IPv6Address getConverted(IPv4StringBuilderOptions opts) { if(opts.includes(IPv4StringBuilderOptions.IPV6_CONVERSIONS)) { IPv6AddressConverter converter = opts.converter; return converter.toIPv6(this); } return null; } public IPAddressPartStringCollection toStringCollection(IPv4StringBuilderOptions opts) { IPv4StringCollection coll = new IPv4StringCollection(); IPAddressPartStringCollection sectionColl = getSection().toStringCollection(opts); coll.addAll(sectionColl); IPv6Address ipv6Addr = getConverted(opts); if(ipv6Addr != null) { IPAddressPartStringCollection ipv6StringCollection = ipv6Addr.toStringCollection(opts.ipv6ConverterOptions); coll.addAll(ipv6StringCollection); } return coll; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy