diff options
author | 2015-09-22 12:49:09 -0700 | |
---|---|---|
committer | 2015-09-22 12:49:09 -0700 | |
commit | 81391595dca425ae58e2294898f09f11d9a32dbc (patch) | |
tree | f5d65c39a732150b2b29daa8de98a35d1236d3fb /framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java | |
parent | 0aa37e73dcb3a55b8d889b0c32ff74055551b1f3 (diff) |
bringing src to commit tag 65d551b50e782b0c1ea76c1a9ed1c5a801a5a7e4
Change-Id: Ib2da78962eaef856f418636c31b0f5c84286244f
Diffstat (limited to 'framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java')
-rw-r--r-- | framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java new file mode 100644 index 00000000..2d4a7816 --- /dev/null +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java @@ -0,0 +1,281 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * 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 + * + * 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 org.onlab.packet.pim; + +import org.onlab.packet.DeserializationException; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpPrefix; +import org.onlab.packet.Ip6Address; + +import java.nio.ByteBuffer; + +import static org.onlab.packet.PacketUtils.checkInput; + +public class PIMAddrSource { + private byte family; + private byte encType; + private byte reserved; + private boolean sBit; + private boolean wBit; + private boolean rBit; + private byte masklen; + IpAddress addr; + + public static final int ENC_SOURCE_IPV4_BYTE_LENGTH = 4 + Ip4Address.BYTE_LENGTH; + public static final int ENC_SOURCE_IPV6_BYTE_LENGTH = 4 + Ip6Address.BYTE_LENGTH; + + /** + * PIM Encoded Source Address. + * + * @param addr IPv4 or IPv6 + */ + public PIMAddrSource(String addr) { + this.init(); + this.setAddr(addr); + } + + /** + * PIM Encoded Source Address. + * + * @param spfx IPv4 or IPv6 + */ + public PIMAddrSource(IpPrefix spfx) { + this.init(); + this.setAddr(spfx); + } + + /** + * PIM Encoded Group Address. + */ + public PIMAddrSource() { + this.init(); + } + + private void init() { + this.family = 4; + this.encType = 0; + this.reserved = 0; + this.sBit = true; + this.wBit = false; + this.rBit = false; + } + + /** + * PIM Encoded Source Address. + * + * @param addr IPv4 or IPv6 + */ + public void setAddr(String addr) { + IpPrefix spfx = IpPrefix.valueOf(addr); + setAddr(spfx); + } + + /** + * PIM Encoded Source Address. + * + * @param spfx IPv4 or IPv6 address prefix + */ + public void setAddr(IpPrefix spfx) { + this.addr = spfx.address(); + this.masklen = (byte) spfx.prefixLength(); + this.family = (byte) ((this.addr.isIp4()) ? 4 : 6); + } + + /** + * Get the IP family of this address: 4 or 6. + * + * @return the IP address family + */ + public byte getFamily() { + return this.family; + } + + /** + * Get the address of this encoded address. + * + * @return source address + */ + public IpAddress getAddr() { + return this.addr; + } + + /** + * Get the masklen of the group address. + * + * @return the masklen + */ + public int getMasklen() { + return this.masklen; + } + + /** + * Return the sparse bit. + * + * @return true or false + */ + public boolean getSBit() { + return this.sBit; + } + + /** + * Return the wBit, used in Join/Prune messages. + * + * @return return true or false. + */ + public boolean getWBit() { + return this.wBit; + } + + /** + * Return the rBit. Used by Rendezvous Point. + * + * @return the rBit. + */ + public boolean getRBit() { + return this.rBit; + } + + /** + * The size in bytes of a serialized address. + * + * @return the number of bytes when serialized + */ + public int getByteSize() { + int size = 4; + size += addr.isIp4() ? 4 : 16; + return size; + } + + public byte[] serialize() { + int len = addr.isIp4() ? ENC_SOURCE_IPV4_BYTE_LENGTH : ENC_SOURCE_IPV6_BYTE_LENGTH; + + final byte[] data = new byte[len]; + final ByteBuffer bb = ByteBuffer.wrap(data); + + bb.put(this.family); + bb.put(this.encType); + + // Todo: technically we should be setting the B and Z bits, but we'll never use them. + byte mask = 0x0; + if (this.sBit) { + this.reserved |= 0x4; + } + if (this.wBit) { + this.reserved |= 0x2; + } + if (this.rBit) { + this.reserved |= 0x1; + } + bb.put(reserved); + + bb.put(this.masklen); + bb.put(this.addr.toOctets()); + return data; + } + + public PIMAddrSource deserialize(byte[] data, int offset, int length) throws DeserializationException { + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); + return deserialize(bb); + } + + public PIMAddrSource deserialize(ByteBuffer bb) throws DeserializationException { + + /* + * We need to verify that we have enough buffer space. First we'll assume that + * we are decoding an IPv4 address. After we read the first by (address family), + * we'll determine if we actually need more buffer space for an IPv6 address. + */ + checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_SOURCE_IPV4_BYTE_LENGTH); + + this.family = bb.get(); + if (family != 4 && family != 6) { + throw new DeserializationException("Illegal IP version number: " + family + "\n"); + } else if (family == 6) { + + // Check for one less by since we have already read the first byte of the packet. + checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_SOURCE_IPV6_BYTE_LENGTH - 1); + } + + this.encType = bb.get(); + this.reserved = bb.get(); + if ((this.reserved & 0x01) != 0) { + this.rBit = true; + } + if ((this.reserved & 0x02) != 0) { + this.wBit = true; + } + if ((this.reserved & 0x4) != 0) { + this.sBit = true; + } + + // Remove the s, reserved + this.reserved &= 0xf8; + + this.masklen = bb.get(); + if (this.family == 4) { + this.addr = IpAddress.valueOf(bb.getInt()); + } else if (this.family == 6) { + this.addr = Ip6Address.valueOf(bb.array(), 2); + } + return this; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 2521; + int result = super.hashCode(); + result = prime * result + this.family; + result = prime * result + this.encType; + result = prime * result + this.reserved; + result = prime * result + this.masklen; + result = prime * result + this.addr.hashCode(); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof PIMAddrSource)) { + return false; + } + final PIMAddrSource other = (PIMAddrSource) obj; + if (this.family != this.family) { + return false; + } + + if (this.encType != other.encType) { + return false; + } + + if (!this.addr.equals(other.addr)) { + return false; + } + return true; + } +} |