X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fsal%2Fapi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fpacket%2FICMP.java;h=987394402d7157f44a011c3d16ab77308855d8a6;hb=4aac6809c89d1a58d1d7ab9aa4af528cc9d8bb3e;hp=d1f81c5775f5d9952d9ef1a2fcde2f22248de11f;hpb=42210c03b0a4c54706320ba9f55794c0abd4d201;p=controller.git diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/ICMP.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/ICMP.java index d1f81c5775..987394402d 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/ICMP.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/ICMP.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2013-2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, @@ -13,34 +13,29 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; +import org.opendaylight.controller.sal.utils.NetUtils; /** * Class that represents the ICMP packet objects - * - * */ public class ICMP extends Packet { - private static final String TYPECODE = "TypeCode"; + private static final String TYPE = "Type"; private static final String CODE = "Code"; - private static final String HEADERCHECKSUM = "HeaderChecksum"; + private static final String CHECKSUM = "Checksum"; private static final String IDENTIFIER = "Identifier"; private static final String SEQNUMBER = "SequenceNumber"; private static Map> fieldCoordinates = new LinkedHashMap>() { private static final long serialVersionUID = 1L; - { - put(TYPECODE, new ImmutablePair(0, 8)); + put(TYPE, new ImmutablePair(0, 8)); put(CODE, new ImmutablePair(8, 8)); - put(HEADERCHECKSUM, new ImmutablePair(16, 16)); + put(CHECKSUM, new ImmutablePair(16, 16)); put(IDENTIFIER, new ImmutablePair(32, 16)); put(SEQNUMBER, new ImmutablePair(48, 16)); - } }; @@ -64,7 +59,7 @@ public class ICMP extends Packet { hdrFieldsMap = fieldValues; } - private Map fieldValues; + private final Map fieldValues; @Override public void setHeaderField(String headerField, byte[] readValue) { @@ -72,16 +67,49 @@ public class ICMP extends Packet { } /** - * Sets the TypeCode of ICMP for the current ICMP object instance - * @param short - typeCode - * @return ICMP + * Sets the type for the current ICMP message + * + * @param type + * The ICMP message type + * @return This ICMP object + */ + public ICMP setType(byte type) { + byte[] icmpType = BitBufferHelper.toByteArray(type); + fieldValues.put(TYPE, icmpType); + return this; + } + + /** + * Returns the type field of the current ICMP packet + * + * @return The type code of the current ICMP packet + */ + public byte getType() { + return BitBufferHelper.getByte(fieldValues.get(TYPE)); + } + + /** + * Sets the ICMP code (type subtype) for the current ICMP object instance + * + * @param code + * The ICMP message type subtype + * @return This ICMP object */ - public ICMP setTypeCode(short typeCode) { - byte[] icmpTypeCode = BitBufferHelper.toByteArray(typeCode); - fieldValues.put(TYPECODE, icmpTypeCode); + public ICMP setCode(byte code) { + byte[] icmpCode = BitBufferHelper.toByteArray(code); + fieldValues.put(CODE, icmpCode); return this; } + /** + * Gets the ICMP code (type subtype) for the current ICMP object instance + * + * @return The ICMP message type subtype + */ + public byte getCode() { + return BitBufferHelper.getByte(fieldValues.get(CODE)); + } + /** * Sets the ICMP checksum for the current ICMP object instance * @param short - checksum @@ -89,12 +117,12 @@ public class ICMP extends Packet { */ public ICMP setChecksum(short checksum) { byte[] icmpChecksum = BitBufferHelper.toByteArray(checksum); - fieldValues.put(HEADERCHECKSUM, icmpChecksum); + fieldValues.put(CHECKSUM, icmpChecksum); return this; } /** - * Sets the ICMP identifier for the current ICMP object instance + * Sets the ICMP identifier for the current ICMP object instance * @param short - identifier * @return ICMP */ @@ -104,6 +132,16 @@ public class ICMP extends Packet { return this; } + /** + * Gets the ICMP identifier of the current ICMP object instance + * + * @return short - identifier + */ + + public short getIdentifier() { + return BitBufferHelper.getShort(fieldValues.get(IDENTIFIER)); + } + /** * Sets the ICMP sequence number for the current ICMP object instance * @param short - seqNumber @@ -115,13 +153,92 @@ public class ICMP extends Packet { return this; } + /** + * Gets the ICMP sequence number of the current ICMP object instance + * + * @return short - seqNumber + */ + + public short getSequenceNumber() { + return BitBufferHelper.getShort(fieldValues.get(SEQNUMBER)); + } + + /** + * Gets the header size in bits + * @return The ICMP header size in bits + */ + @Override + public int getHeaderSize() { + return 64; + } + + /** + * Computes the ICMP checksum on the serialized ICMP message + * + * @param serialized + * The data stream + * @param start + * The byte index on the data stream from which the ICMP packet + * starts + * @return The checksum + */ + short computeChecksum(byte[] data, int start) { + int sum = 0, carry = 0, finalSum = 0; + int wordData; + int end = start + this.getHeaderSize() / NetUtils.NumBitsInAByte; + if (rawPayload != null) { + end += rawPayload.length; + } + int checksumStartByte = start + getfieldOffset(CHECKSUM) / NetUtils.NumBitsInAByte; + int even = end & ~1; + + for (int i = start; i < even; i = i + 2) { + // Skip, if the current bytes are checkSum bytes + if (i == checksumStartByte) { + continue; + } + wordData = ((data[i] << 8) & 0xFF00) + (data[i + 1] & 0xFF); + sum = sum + wordData; + } + if (even < end) { + // Add the last octet with zero padding. + wordData = (data[even] << 8) & 0xFF00; + sum = sum + wordData; + } + + carry = sum >>> 16; + finalSum = (sum & 0xFFFF) + carry; + return (short) ~((short) finalSum & 0xFFFF); + } + @Override - public int hashCode() { - return HashCodeBuilder.reflectionHashCode(this); + protected void postSerializeCustomOperation(byte[] serializedBytes) + throws PacketException { + byte[] checkSum = BitBufferHelper + .toByteArray(computeChecksum(serializedBytes, 0)); + try { + BitBufferHelper.setBytes(serializedBytes, checkSum, + getfieldOffset(CHECKSUM), getfieldnumBits(CHECKSUM)); + } catch (BufferException e) { + throw new PacketException(e.getMessage()); + } } @Override - public boolean equals(Object obj) { - return EqualsBuilder.reflectionEquals(this, obj); + protected void postDeserializeCustomOperation(byte[] data, int endBitOffset) { + short computedChecksum = computeChecksum(data, endBitOffset / NetUtils.NumBitsInAByte); + short actualChecksum = BitBufferHelper.getShort(fieldValues.get(CHECKSUM)); + + if (computedChecksum != actualChecksum) { + corrupted = true; + } + } + + /** + * Gets the checksum value stored + * @return the checksum + */ + public short getChecksum() { + return (BitBufferHelper.getShort(fieldValues.get(CHECKSUM))); } }