From 340a93f17c03395391339a82b3a036afd374f569 Mon Sep 17 00:00:00 2001 From: Alessandro Boch Date: Wed, 24 Apr 2013 18:09:09 -0700 Subject: [PATCH] Revisit Exception handling in BitBufferHelper and Packet - Added BufferException and PacketException - Revisit exception handling in BitBufferhelper - Other minor code style changes Change-Id: I2b97560708fb1adb557852a524e2a8d3da6a5d73 Signed-off-by: Alessandro Boch --- .../openflow/internal/DiscoveryService.java | 4 +- .../internal/FlowProgrammerService.java | 1 + .../sal/packet/BitBufferHelper.java | 242 +++++++++------- .../sal/packet/BufferException.java | 19 ++ .../controller/sal/packet/Ethernet.java | 2 +- .../controller/sal/packet/IPv4.java | 22 +- .../controller/sal/packet/LLDP.java | 273 ++++++++++-------- .../controller/sal/packet/LLDPTLV.java | 5 +- .../controller/sal/packet/Packet.java | 127 ++++---- .../sal/packet/PacketException.java | 22 ++ .../controller/sal/packet/IPv4Test.java | 2 +- .../internal/DataPacketService.java | 3 +- 12 files changed, 416 insertions(+), 306 deletions(-) create mode 100644 opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/BufferException.java create mode 100644 opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/PacketException.java diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java index 5775895664..d8fe7a4cae 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java @@ -256,8 +256,8 @@ public class DiscoveryService implements IInventoryShimExternalListener, try { ethPkt.deserialize(data, 0, data.length * NetUtils.NumBitsInAByte); } catch (Exception e) { - logger.warn("Failed to decode LLDP packet from " - + inPkt.getIncomingNodeConnector() + ": " + e); + logger.warn("Failed to decode LLDP packet from {}: {}", + inPkt.getIncomingNodeConnector(), e); return PacketResult.IGNORED; } if (ethPkt.getPayload() instanceof LLDP) { diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java index 230376555e..c8ae922902 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java @@ -72,6 +72,7 @@ public class FlowProgrammerService implements IPluginInFlowProgrammerService, public FlowProgrammerService() { controller = null; flowProgrammerNotifiers = new ConcurrentHashMap(); + containerToNc = new HashMap>(); xid2rid = new ConcurrentHashMap>(); } diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/BitBufferHelper.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/BitBufferHelper.java index cd9a904a60..5c81a1830b 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/BitBufferHelper.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/BitBufferHelper.java @@ -1,4 +1,3 @@ - /* * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * @@ -24,14 +23,12 @@ import org.slf4j.LoggerFactory; * - convert bits to primitive data type - like short, int, long * - store bits in specified location in stream of bits * - convert primitive data types to stream of bits - * - * */ public abstract class BitBufferHelper { protected static final Logger logger = LoggerFactory .getLogger(BitBufferHelper.class); - public static long ByteMask = 0xFF; + public static final long ByteMask = 0xFF; // Getters // data: array where data are stored @@ -47,10 +44,10 @@ public abstract class BitBufferHelper { public static byte getByte(byte[] data) { if ((data.length * NetUtils.NumBitsInAByte) > Byte.SIZE) { try { - throw new Exception( + throw new BufferException( "Container is too small for the number of requested bits"); - } catch (Exception e) { - logger.error("",e); + } catch (BufferException e) { + logger.error("", e); } } return (data[0]); @@ -65,10 +62,10 @@ public abstract class BitBufferHelper { public static short getShort(byte[] data) { if (data.length > Short.SIZE) { try { - throw new Exception( + throw new BufferException( "Container is too small for the number of requested bits"); - } catch (Exception e) { - logger.error("",e); + } catch (BufferException e) { + logger.error("", e); } } return (short) toNumber(data); @@ -83,10 +80,10 @@ public abstract class BitBufferHelper { public static int getInt(byte[] data) { if (data.length > Integer.SIZE) { try { - throw new Exception( + throw new BufferException( "Container is too small for the number of requested bits"); - } catch (Exception e) { - logger.error("",e); + } catch (BufferException e) { + logger.error("", e); } } return (int) toNumber(data); @@ -101,10 +98,10 @@ public abstract class BitBufferHelper { public static long getLong(byte[] data) { if (data.length > Long.SIZE) { try { - throw new Exception( + throw new BufferException( "Container is too small for the number of requested bits"); } catch (Exception e) { - logger.error("",e); + logger.error("", e); } } return (long) toNumber(data); @@ -116,20 +113,24 @@ public abstract class BitBufferHelper { * @param byte[] data * @param int - numBits * @return short - the short value of byte array - * @throws Exception */ - public static short getShort(byte[] data, int numBits) throws Exception { + public static short getShort(byte[] data, int numBits) { if (numBits > Short.SIZE) { try { - throw new Exception( + throw new BufferException( "Container is too small for the number of requested bits"); - } catch (Exception e) { - logger.error("",e); + } catch (BufferException e) { + logger.error("", e); } } int startOffset = data.length * NetUtils.NumBitsInAByte - numBits; - return (short) toNumber(BitBufferHelper.getBits(data, startOffset, - numBits), numBits); + byte[] bits = null; + try { + bits = BitBufferHelper.getBits(data, startOffset, numBits); + } catch (BufferException e) { + logger.error("", e); + } + return (short) toNumber(bits, numBits); } /** @@ -138,20 +139,24 @@ public abstract class BitBufferHelper { * @param byte[] data * @param int - numBits * @return int - the integer value of byte array - * @throws Exception */ - public static int getInt(byte[] data, int numBits) throws Exception { + public static int getInt(byte[] data, int numBits) { if (numBits > Integer.SIZE) { try { - throw new Exception( - "Container is too small for the number of requiested bits"); - } catch (Exception e) { - logger.error("",e); + throw new BufferException( + "Container is too small for the number of requested bits"); + } catch (BufferException e) { + logger.error("", e); } } int startOffset = data.length * NetUtils.NumBitsInAByte - numBits; - return (int) toNumber(BitBufferHelper.getBits(data, startOffset, - numBits), numBits); + byte[] bits = null; + try { + bits = BitBufferHelper.getBits(data, startOffset, numBits); + } catch (BufferException e) { + logger.error("", e); + } + return (int) toNumber(bits, numBits); } /** @@ -160,29 +165,32 @@ public abstract class BitBufferHelper { * @param byte[] data * @param int - numBits * @return long - the integer value of byte array - * @throws Exception */ - - public static long getLong(byte[] data, int numBits) throws Exception { + public static long getLong(byte[] data, int numBits) { if (numBits > Long.SIZE) { try { - throw new Exception( + throw new BufferException( "Container is too small for the number of requested bits"); - } catch (Exception e) { - logger.error("",e); + } catch (BufferException e) { + logger.error("", e); } } if (numBits > data.length * NetUtils.NumBitsInAByte) { try { - throw new Exception( + throw new BufferException( "Trying to read more bits than contained in the data buffer"); - } catch (Exception e) { - logger.error("",e); + } catch (BufferException e) { + logger.error("", e); } } int startOffset = data.length * NetUtils.NumBitsInAByte - numBits; - return toNumber(BitBufferHelper.getBits(data, startOffset, numBits), - numBits); + byte[] bits = null; + try { + bits = BitBufferHelper.getBits(data, startOffset, numBits); + } catch (BufferException e) { + logger.error("", e); + } + return (long) toNumber(bits, numBits); } /** @@ -202,10 +210,13 @@ public abstract class BitBufferHelper { * @param int startOffset - offset to start fetching bits from data from * @param int numBits - number of bits to be fetched from data * @return byte [] - LSB aligned bits - * @throws Exception + * + * @throws BufferException + * when the startOffset and numBits parameters are not congruent + * with the data buffer size */ public static byte[] getBits(byte[] data, int startOffset, int numBits) - throws Exception { + throws BufferException { int startByteOffset = 0; int valfromcurr, valfromnext; @@ -216,8 +227,9 @@ public abstract class BitBufferHelper { byte[] shiftedBytes = new byte[numBytes]; startByteOffset = startOffset / NetUtils.NumBitsInAByte; byte[] bytes = new byte[numBytes]; - if (numBits == 0) + if (numBits == 0) { return bytes; + } checkExceptions(data, startOffset, numBits); @@ -233,7 +245,7 @@ public abstract class BitBufferHelper { } else { int i; for (i = 0; i < numBits / NetUtils.NumBitsInAByte; i++) { - // Reading Numbytes starting from offset + // Reading numBytes starting from offset valfromcurr = (data[startByteOffset + i]) & getLSBMask(NetUtils.NumBitsInAByte - extraOffsetBits); valfromnext = (data[startByteOffset + i + 1]) @@ -279,11 +291,13 @@ public abstract class BitBufferHelper { * @param byte - input byte to be inserted * @param startOffset - offset of data[] to start inserting byte from * @param numBits - number of bits of input to be inserted into data[] - * @return void - * @throws Exception + * + * @throws BufferException + * when the input, startOffset and numBits are not congruent + * with the data buffer size */ public static void setByte(byte[] data, byte input, int startOffset, - int numBits) throws Exception { + int numBits) throws BufferException { byte[] inputByteArray = new byte[1]; Arrays.fill(inputByteArray, 0, 1, input); setBytes(data, inputByteArray, startOffset, numBits); @@ -296,16 +310,19 @@ public abstract class BitBufferHelper { * @param startOffset - offset of data[] to start inserting byte from * @param numBits - number of bits of input to be inserted into data[] * @return void - * @throws Exception + * @throws BufferException + * when the startOffset and numBits parameters are not congruent + * with data and input buffers' size */ public static void setBytes(byte[] data, byte[] input, int startOffset, - int numBits) throws Exception { + int numBits) throws BufferException { checkExceptions(data, startOffset, numBits); insertBits(data, input, startOffset, numBits); } /** * Returns numBits 1's in the MSB position + * * @param numBits * @return */ @@ -319,6 +336,7 @@ public abstract class BitBufferHelper { /** * Returns numBits 1's in the LSB position + * * @param numBits * @return */ @@ -332,6 +350,7 @@ public abstract class BitBufferHelper { /** * Returns the numerical value of the byte array passed + * * @param byte[] - array * @return long - numerical value of byte array passed */ @@ -350,8 +369,9 @@ public abstract class BitBufferHelper { } /** - * Returns the numerical value of the last numBits (LSB bits) - * of the byte array passed + * Returns the numerical value of the last numBits (LSB bits) of the byte + * array passed + * * @param byte[] - array * @param int - numBits * @return long - numerical value of byte array passed @@ -381,57 +401,59 @@ public abstract class BitBufferHelper { } /** - * Accepts a number as input and returns its value in byte form - * in LSB aligned form - * example: input = 5000 [1001110001000] - * bytes = 19, -120 [00010011] [10001000] + * Accepts a number as input and returns its value in byte form in LSB + * aligned form example: input = 5000 [1001110001000] bytes = 19, -120 + * [00010011] [10001000] + * * @param Number * @return byte[] - * + * */ public static byte[] toByteArray(Number input) { Class dataType = input.getClass(); short size = 0; - long Lvalue = input.longValue(); + long longValue = input.longValue(); - if (dataType == Byte.class || dataType == byte.class) + if (dataType == Byte.class || dataType == byte.class) { size = Byte.SIZE; - else if (dataType == Short.class || dataType == short.class) + } else if (dataType == Short.class || dataType == short.class) { size = Short.SIZE; - else if (dataType == Integer.class || dataType == int.class) + } else if (dataType == Integer.class || dataType == int.class) { size = Integer.SIZE; - else if (dataType == Long.class || dataType == long.class) + } else if (dataType == Long.class || dataType == long.class) { size = Long.SIZE; - else + } else { throw new IllegalArgumentException( "Parameter must one of the following: Short/Int/Long\n"); + } int length = size / NetUtils.NumBitsInAByte; byte bytes[] = new byte[length]; - /*Getting the bytes from input value*/ + // Getting the bytes from input value for (int i = 0; i < length; i++) { - bytes[i] = (byte) ((Lvalue >> (NetUtils.NumBitsInAByte * (length + bytes[i] = (byte) ((longValue >> (NetUtils.NumBitsInAByte * (length - i - 1))) & ByteMask); } return bytes; } /** - * Accepts a number as input and returns its value in byte form - * in MSB aligned form - * example: input = 5000 [1001110001000] - * bytes = -114, 64 [10011100] [01000000] - * @param Number input + * Accepts a number as input and returns its value in byte form in MSB + * aligned form example: input = 5000 [1001110001000] bytes = -114, 64 + * [10011100] [01000000] + * + * @param Number + * input * @param int numBits - the number of bits to be returned * @return byte[] - * + * */ public static byte[] toByteArray(Number input, int numBits) { Class dataType = input.getClass(); short size = 0; - long Lvalue = input.longValue(); + long longValue = input.longValue(); if (dataType == Short.class) { size = Short.SIZE; @@ -449,9 +471,9 @@ public abstract class BitBufferHelper { byte[] inputbytes = new byte[length]; byte shiftedBytes[]; - //Getting the bytes from input value + // Getting the bytes from input value for (int i = 0; i < length; i++) { - bytes[i] = (byte) ((Lvalue >> (NetUtils.NumBitsInAByte * (length + bytes[i] = (byte) ((longValue >> (NetUtils.NumBitsInAByte * (length - i - 1))) & ByteMask); } @@ -476,20 +498,20 @@ public abstract class BitBufferHelper { } /** - * Takes an LSB aligned byte array and returned the LSB numBits in a MSB aligned byte array - * + * Takes an LSB aligned byte array and returned the LSB numBits in a MSB + * aligned byte array + * * @param inputbytes * @param numBits * @return */ /** - * It aligns the last numBits bits to the head of the byte array - * following them with numBits % 8 zero bits. - * - * Example: - * For inputbytes = [00000111][01110001] and numBits = 12 it returns: - * shiftedBytes = [01110111][00010000] - * + * It aligns the last numBits bits to the head of the byte array following + * them with numBits % 8 zero bits. + * + * Example: For inputbytes = [00000111][01110001] and numBits = 12 it + * returns: shiftedBytes = [01110111][00010000] + * * @param byte[] inputBytes * @param int numBits - number of bits to be left aligned * @return byte[] @@ -507,20 +529,24 @@ public abstract class BitBufferHelper { } } - if (numBits % NetUtils.NumBitsInAByte == 0) + if (numBits % NetUtils.NumBitsInAByte == 0) { numBitstoShiftBy = 0; - else + } else { numBitstoShiftBy = ((NetUtils.NumBitsInAByte - (numBits % NetUtils.NumBitsInAByte)) < leadZeroesMSB) ? (NetUtils.NumBitsInAByte - (numBits % NetUtils.NumBitsInAByte)) : leadZeroesMSB; - - if (numBitstoShiftBy == 0) + } + if (numBitstoShiftBy == 0) { return inputBytes; + } - if (numBits < NetUtils.NumBitsInAByte) { //inputbytes.length = 1 OR Read less than a byte + if (numBits < NetUtils.NumBitsInAByte) { + // inputbytes.length = 1 OR read less than a byte shiftedBytes[0] = (byte) ((inputBytes[0] & getLSBMask(numBits)) << numBitstoShiftBy); } else { + // # of bits to read from last byte numEndRestBits = NetUtils.NumBitsInAByte - - (inputBytes.length * NetUtils.NumBitsInAByte - numBits - numBitstoShiftBy); //# of bits to read from last byte + - (inputBytes.length * NetUtils.NumBitsInAByte - numBits - numBitstoShiftBy); + for (i = 0; i < (size - 1); i++) { if ((i + 1) == (size - 1)) { if (numEndRestBits > numBitstoShiftBy) { @@ -540,11 +566,10 @@ public abstract class BitBufferHelper { /** * It aligns the first numBits bits to the right end of the byte array * preceding them with numBits % 8 zero bits. - * - * Example: - * For inputbytes = [01110111][00010000] and numBits = 12 it returns: - * shiftedBytes = [00000111][01110001] - * + * + * Example: For inputbytes = [01110111][00010000] and numBits = 12 it + * returns: shiftedBytes = [00000111][01110001] + * * @param byte[] inputBytes * @param int numBits - number of bits to be right aligned * @return byte[] @@ -555,8 +580,9 @@ public abstract class BitBufferHelper { byte[] shiftedBytes = new byte[numBytes]; int inputLsb = 0, inputMsb = 0; - if (numBitstoShift == 0) + if (numBitstoShift == 0) { return inputBytes; + } for (int i = 1; i < numBytes; i++) { inputLsb = inputBytes[i - 1] @@ -575,18 +601,20 @@ public abstract class BitBufferHelper { /** * Insert in the data buffer at position dictated by the offset the number - * of bits specified from the input data byte array. - * The input byte array has the bits stored starting from the LSB - * + * of bits specified from the input data byte array. The input byte array + * has the bits stored starting from the LSB + * * @param byte[] data * @param byte[] inputdata * @param int startOffset * @param int numBits - * @return void */ public static void insertBits(byte[] data, byte[] inputdataLSB, int startOffset, int numBits) { - byte[] inputdata = shiftBitsToMSB(inputdataLSB, numBits); // Align to MSB the passed byte array + byte[] inputdata = shiftBitsToMSB(inputdataLSB, numBits); // Align to + // MSB the + // passed byte + // array int numBytes = numBits / NetUtils.NumBitsInAByte; int startByteOffset = startOffset / NetUtils.NumBitsInAByte; int extraOffsetBits = startOffset % NetUtils.NumBitsInAByte; @@ -595,8 +623,9 @@ public abstract class BitBufferHelper { int InputMSBbits = 0, InputLSBbits = 0; int i; - if (numBits == 0) - return; + if (numBits == 0) { + return; + } if (extraOffsetBits == 0) { if (extranumBits == 0) { @@ -659,10 +688,11 @@ public abstract class BitBufferHelper { * @param data * @param startOffset * @param numBits - * @throws Exception + * @throws PacketException when the startOffset and numBits parameters + * are not congruent with the data buffer's size */ public static void checkExceptions(byte[] data, int startOffset, int numBits) - throws Exception { + throws BufferException { int endOffsetByte; int startByteOffset; endOffsetByte = startOffset @@ -674,13 +704,13 @@ public abstract class BitBufferHelper { startByteOffset = startOffset / NetUtils.NumBitsInAByte; if (data == null) { - throw new Exception("data[] is null\n"); + throw new BufferException("data[] is null\n"); } if ((startOffset < 0) || (startByteOffset >= data.length) || (endOffsetByte > data.length) || (numBits < 0) || (numBits > NetUtils.NumBitsInAByte * data.length)) { - throw new Exception( + throw new BufferException( "Illegal arguement/out of bound exception - data.length = " + data.length + " startOffset = " + startOffset + " numBits " + numBits); diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/BufferException.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/BufferException.java new file mode 100644 index 0000000000..655147d747 --- /dev/null +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/BufferException.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 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, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.packet; + +/** + * Describes an exception that is raised during BitBufferHelper operations. + */ +public class BufferException extends Exception { + private static final long serialVersionUID = 1L; + + public BufferException(String message) { + super(message); + } +} diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Ethernet.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Ethernet.java index 0d866d644e..0f1a7f54f3 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Ethernet.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Ethernet.java @@ -31,7 +31,7 @@ public class Ethernet extends Packet { // TODO: This has to be outside and it should be possible for osgi // to add new coming packet classes - public static Map> etherTypeClassMap; + public static final Map> etherTypeClassMap; static { etherTypeClassMap = new HashMap>(); etherTypeClassMap.put(EtherTypes.ARP.shortValue(), ARP.class); diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java index e55873d693..d547e2c905 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java @@ -51,7 +51,7 @@ public class IPv4 extends Packet { private static final String DIP = "DestinationIPAddress"; private static final String OPTIONS = "Options"; - public static Map> protocolClassMap; + public static final Map> protocolClassMap; static { protocolClassMap = new HashMap>(); protocolClassMap.put(IPProtocols.ICMP.byteValue(), ICMP.class); @@ -505,17 +505,20 @@ public class IPv4 extends Packet { * Method to perform post serialization - like computation of checksum of serialized header * @param serializedBytes * @return void - * @Exception throws exception + * @Exception throws PacketException */ protected void postSerializeCustomOperation(byte[] serializedBytes) - throws Exception { + throws PacketException { int startOffset = this.getfieldOffset(CHECKSUM); int numBits = this.getfieldnumBits(CHECKSUM); byte[] checkSum = BitBufferHelper.toByteArray(computeChecksum( serializedBytes, serializedBytes.length)); - BitBufferHelper.setBytes(serializedBytes, checkSum, startOffset, - numBits); - return; + try { + BitBufferHelper.setBytes(serializedBytes, checkSum, startOffset, + numBits); + } catch (BufferException e) { + throw new PacketException(e.getMessage()); + } } @Override @@ -534,8 +537,8 @@ public class IPv4 extends Packet { int payloadLength = 0; try { payloadLength = payload.serialize().length; - } catch (Exception e) { - logger.error("",e); + } catch (PacketException e) { + logger.error("", e); } this.setTotalLength((short) (this.getHeaderLen() + payloadLength)); } @@ -549,7 +552,8 @@ public class IPv4 extends Packet { int endByteOffset = endBitOffset / NetUtils.NumBitsInAByte; int computedChecksum = computeChecksum(data, endByteOffset); int actualChecksum = BitBufferHelper.getInt(fieldValues.get(CHECKSUM)); - if (computedChecksum != actualChecksum) + if (computedChecksum != actualChecksum) { corrupted = true; + } } } diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDP.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDP.java index 420614ffbd..1a0033ee96 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDP.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDP.java @@ -1,4 +1,3 @@ - /* * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * @@ -20,92 +19,101 @@ import org.opendaylight.controller.sal.utils.NetUtils; */ public class LLDP extends Packet { - private static final String CHASSISID = "ChassisId"; - private static final String PORTID = "PortId"; - private static final String TTL = "TTL"; - private static final int LLDPDefaultTlvs = 3; - private static LLDPTLV emptyTLV = new LLDPTLV().setLength((short)0).setType((byte)0); - public static final byte[] LLDPMulticastMac = {1,(byte)0x80,(byte)0xc2, 0, 0,(byte)0xe}; - private Map tlvList; - - /** - * Default constructor that creates the tlvList LinkedHashMap - */ - public LLDP() { - super(); - tlvList = new LinkedHashMap(LLDPDefaultTlvs); - } - - /** - * Constructor that creates the tlvList LinkedHashMap and sets - * the write access for the same - */ - public LLDP (boolean writeAccess) { - super(writeAccess); - tlvList = new LinkedHashMap(LLDPDefaultTlvs); // Mandatory TLVs - } - - /** - * @param String - description of the type of TLV - * @return byte - type of TLV - */ - private byte getType(String typeDesc) { - if (typeDesc.equals(CHASSISID)) { - return LLDPTLV.TLVType.ChassisID.getValue(); - } else if (typeDesc.equals(PORTID)) { - return LLDPTLV.TLVType.PortID.getValue(); - } else if (typeDesc.equals(TTL)) { - return LLDPTLV.TLVType.TTL.getValue(); - } else { - return LLDPTLV.TLVType.Unknown.getValue(); - } - } - - /** - * @param String - description of the type of TLV - * @return LLDPTLV - full TLV - */ + private static final String CHASSISID = "ChassisId"; + private static final String PORTID = "PortId"; + private static final String TTL = "TTL"; + private static final int LLDPDefaultTlvs = 3; + private static LLDPTLV emptyTLV = new LLDPTLV().setLength((short) 0) + .setType((byte) 0); + public static final byte[] LLDPMulticastMac = { 1, (byte) 0x80, + (byte) 0xc2, 0, 0, (byte) 0xe }; + private Map tlvList; + + /** + * Default constructor that creates the tlvList LinkedHashMap + */ + public LLDP() { + super(); + tlvList = new LinkedHashMap(LLDPDefaultTlvs); + } + + /** + * Constructor that creates the tlvList LinkedHashMap and sets the write + * access for the same + */ + public LLDP(boolean writeAccess) { + super(writeAccess); + tlvList = new LinkedHashMap(LLDPDefaultTlvs); // Mandatory + // TLVs + } + + /** + * @param String + * - description of the type of TLV + * @return byte - type of TLV + */ + private byte getType(String typeDesc) { + if (typeDesc.equals(CHASSISID)) { + return LLDPTLV.TLVType.ChassisID.getValue(); + } else if (typeDesc.equals(PORTID)) { + return LLDPTLV.TLVType.PortID.getValue(); + } else if (typeDesc.equals(TTL)) { + return LLDPTLV.TLVType.TTL.getValue(); + } else { + return LLDPTLV.TLVType.Unknown.getValue(); + } + } + + /** + * @param String + * - description of the type of TLV + * @return LLDPTLV - full TLV + */ public LLDPTLV getTLV(String type) { - return tlvList.get(getType(type)); + return tlvList.get(getType(type)); } - /** - * @param String - description of the type of TLV - * @param LLDPTLV - tlv to set - * @return void - */ + /** + * @param String + * - description of the type of TLV + * @param LLDPTLV + * - tlv to set + * @return void + */ public void setTLV(String type, LLDPTLV tlv) { - tlvList.put(getType(type), tlv); + tlvList.put(getType(type), tlv); } /** * @return the chassisId TLV */ public LLDPTLV getChassisId() { - return getTLV(CHASSISID); + return getTLV(CHASSISID); } /** - * @param LLDPTLV - the chassisId to set + * @param LLDPTLV + * - the chassisId to set */ public LLDP setChassisId(LLDPTLV chassisId) { - tlvList.put(getType(CHASSISID), chassisId); + tlvList.put(getType(CHASSISID), chassisId); return this; } - + /** * @return LLDPTLV - the portId TLV */ public LLDPTLV getPortId() { - return tlvList.get(getType(PORTID)); + return tlvList.get(getType(PORTID)); } /** - * @param LLDPTLV - the portId to set + * @param LLDPTLV + * - the portId to set * @return LLDP */ public LLDP setPortId(LLDPTLV portId) { - tlvList.put(getType(PORTID), portId); + tlvList.put(getType(PORTID), portId); return this; } @@ -113,15 +121,16 @@ public class LLDP extends Packet { * @return LLDPTLV - the ttl TLV */ public LLDPTLV getTtl() { - return tlvList.get(getType(TTL)); + return tlvList.get(getType(TTL)); } /** - * @param LLDPTLV - the ttl to set + * @param LLDPTLV + * - the ttl to set * @return LLDP */ public LLDP setTtl(LLDPTLV ttl) { - tlvList.put(getType(TTL), ttl); + tlvList.put(getType(TTL), ttl); return this; } @@ -129,83 +138,95 @@ public class LLDP extends Packet { * @return the optionalTLVList */ public List getOptionalTLVList() { - List list = new ArrayList(); - for (Map.Entry entry : tlvList.entrySet()) { - byte type = entry.getKey(); - if ((type == LLDPTLV.TLVType.ChassisID.getValue()) || - (type == LLDPTLV.TLVType.PortID.getValue()) || - (type == LLDPTLV.TLVType.TTL.getValue())) { - continue; - } else { - list.add(entry.getValue()); - } - } + List list = new ArrayList(); + for (Map.Entry entry : tlvList.entrySet()) { + byte type = entry.getKey(); + if ((type == LLDPTLV.TLVType.ChassisID.getValue()) + || (type == LLDPTLV.TLVType.PortID.getValue()) + || (type == LLDPTLV.TLVType.TTL.getValue())) { + continue; + } else { + list.add(entry.getValue()); + } + } return list; } /** - * @param optionalTLVList the optionalTLVList to set + * @param optionalTLVList + * the optionalTLVList to set * @return LLDP */ - public LLDP setOptionalTLVList(List optionalTLVList) - { - for (LLDPTLV tlv : optionalTLVList) { - tlvList.put(tlv.getType(), tlv); - } + public LLDP setOptionalTLVList(List optionalTLVList) { + for (LLDPTLV tlv : optionalTLVList) { + tlvList.put(tlv.getType(), tlv); + } return this; } @Override - public Packet deserialize (byte[] data, int bitOffset, int size) throws Exception { - int lldpOffset = bitOffset; // LLDP start - int lldpSize = size; // LLDP size - - /* - * Deserialize the TLVs until we reach the end of the packet - */ - - while (lldpSize > 0) { - LLDPTLV tlv = new LLDPTLV(); - tlv.deserialize(data, lldpOffset, lldpSize); - lldpOffset += tlv.getTLVSize(); //Size of current TLV in bits - lldpSize -= tlv.getTLVSize(); - this.tlvList.put(tlv.getType(), tlv); - } - return this; - } - + public Packet deserialize(byte[] data, int bitOffset, int size) + throws PacketException { + int lldpOffset = bitOffset; // LLDP start + int lldpSize = size; // LLDP size + + /* + * Deserialize the TLVs until we reach the end of the packet + */ + while (lldpSize > 0) { + LLDPTLV tlv = new LLDPTLV(); + tlv.deserialize(data, lldpOffset, lldpSize); + int tlvSize = tlv.getTLVSize(); // Size of current TLV in bits + lldpOffset += tlvSize; + lldpSize -= tlvSize; + this.tlvList.put(tlv.getType(), tlv); + } + return this; + } + @Override - public byte[] serialize() throws Exception { - int startOffset = 0; - byte[] serializedBytes = new byte[getLLDPPacketLength()]; - - for (Map.Entry entry : tlvList.entrySet()) { - LLDPTLV tlv = entry.getValue(); - int numBits = tlv.getTLVSize(); - BitBufferHelper.setBytes(serializedBytes, tlv.serialize(), startOffset, numBits); - startOffset += numBits; - } - // Now add the empty LLDPTLV at the end - BitBufferHelper.setBytes(serializedBytes, LLDP.emptyTLV.serialize(), startOffset, LLDP.emptyTLV.getTLVSize()); - - return serializedBytes; - } - + public byte[] serialize() throws PacketException { + int startOffset = 0; + byte[] serializedBytes = new byte[getLLDPPacketLength()]; + + for (Map.Entry entry : tlvList.entrySet()) { + LLDPTLV tlv = entry.getValue(); + int numBits = tlv.getTLVSize(); + try { + BitBufferHelper.setBytes(serializedBytes, tlv.serialize(), + startOffset, numBits); + } catch (BufferException e) { + throw new PacketException(e.getMessage()); + } + startOffset += numBits; + } + // Now add the empty LLDPTLV at the end + try { + BitBufferHelper.setBytes(serializedBytes, + LLDP.emptyTLV.serialize(), startOffset, + LLDP.emptyTLV.getTLVSize()); + } catch (BufferException e) { + throw new PacketException(e.getMessage()); + } + + return serializedBytes; + } + /** * Returns the size of LLDP packet in bytes + * * @return int - LLDP Packet size in bytes - * @throws Exception */ - private int getLLDPPacketLength() throws Exception { - int len = 0; - LLDPTLV tlv; - - for (Map.Entry entry : this.tlvList.entrySet()) { - tlv = entry.getValue(); - len += tlv.getTLVSize(); - } - len += LLDP.emptyTLV.getTLVSize(); - - return len/NetUtils.NumBitsInAByte; + private int getLLDPPacketLength() { + int len = 0; + LLDPTLV tlv; + + for (Map.Entry entry : this.tlvList.entrySet()) { + tlv = entry.getValue(); + len += tlv.getTLVSize(); + } + len += LLDP.emptyTLV.getTLVSize(); + + return len / NetUtils.NumBitsInAByte; } } diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDPTLV.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDPTLV.java index 45706fc77c..3847e59a13 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDPTLV.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/LLDPTLV.java @@ -152,7 +152,7 @@ public class LLDPTLV extends Packet { } @Override - public int getfieldnumBits(String fieldName) throws Exception { + public int getfieldnumBits(String fieldName) { if (fieldName.equals(VALUE)) { return (NetUtils.NumBitsInAByte * (int) BitBufferHelper.getShort( fieldValues.get(LENGTH), fieldCoordinates.get(LENGTH) @@ -165,9 +165,8 @@ public class LLDPTLV extends Packet { * Returns the size in bits of the whole TLV * * @return int - size in bits of full TLV - * @throws Exception */ - public int getTLVSize() throws Exception { + public int getTLVSize() { return (LLDPTLV.fieldCoordinates.get(TYPE).getRight() + // static LLDPTLV.fieldCoordinates.get(LENGTH).getRight() + // static getfieldnumBits(VALUE)); // variable diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Packet.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Packet.java index bbe85ec66a..cdf15322e3 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Packet.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/Packet.java @@ -1,4 +1,3 @@ - /* * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * @@ -21,16 +20,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Abstract class which represents the generic network packet object - * It provides the basic methods which are common for all the packets, - * like serialize and deserialize - * - * + * Abstract class which represents the generic network packet object It provides + * the basic methods which are common for all the packets, like serialize and + * deserialize + * + * */ public abstract class Packet { protected static final Logger logger = LoggerFactory - .getLogger(Packet.class); + .getLogger(Packet.class); // Access level granted to this packet protected boolean writeAccess; // When deserialized from wire, packet could result corrupted @@ -77,17 +76,19 @@ public abstract class Packet { } /** - * This method deserializes the data bits obtained from the wire - * into the respective header and payload which are of type Packet + * This method deserializes the data bits obtained from the wire into the + * respective header and payload which are of type Packet + * * @param byte[] data - data from wire to deserialize - * @param int bitOffset bit position where packet header starts in data array + * @param int bitOffset bit position where packet header starts in data + * array * @param int size of packet in bits * @return Packet - * @throws Exception + * @throws PacketException */ public Packet deserialize(byte[] data, int bitOffset, int size) - throws Exception { + throws PacketException { String hdrField; Integer startOffset = 0, numBits = 0; byte[] hdrFieldBytes; @@ -98,10 +99,15 @@ public abstract class Packet { startOffset = bitOffset + this.getfieldOffset(hdrField); numBits = this.getfieldnumBits(hdrField); - hdrFieldBytes = BitBufferHelper.getBits(data, startOffset, numBits); + try { + hdrFieldBytes = BitBufferHelper.getBits(data, startOffset, + numBits); + } catch (BufferException e) { + throw new PacketException(e.getMessage()); + } /* - * Store the raw read value, checks the payload type and - * set the payloadClass accordingly + * Store the raw read value, checks the payload type and set the + * payloadClass accordingly */ this.setHeaderField(hdrField, hdrFieldBytes); } @@ -109,7 +115,7 @@ public abstract class Packet { postDeserializeCustomOperation(data, startOffset); int payloadStart = startOffset + numBits; - //int payloadSize = size - payloadStart; + // int payloadSize = size - payloadStart; int payloadSize = data.length * NetUtils.NumBitsInAByte - payloadStart; if (payloadClass != null) { @@ -128,14 +134,14 @@ public abstract class Packet { } /** - * This method serializes the header and payload bytes from - * the respective packet class, into a single stream of bytes - * to be sent on the wire + * This method serializes the header and payload bytes from the respective + * packet class, into a single stream of bytes to be sent on the wire + * * @return byte[] - serialized bytes - * @throws Exception + * @throws PacketException */ - public byte[] serialize() throws Exception { + public byte[] serialize() throws PacketException { byte[] payloadBytes = null; int payloadSize = 0; int headerSize = this.getHeaderSize(); @@ -168,8 +174,12 @@ public abstract class Packet { if (fieldBytes != null) { startOffset = this.getfieldOffset(field); numBits = this.getfieldnumBits(field); - BitBufferHelper.setBytes(headerBytes, fieldBytes, startOffset, - numBits); + try { + BitBufferHelper.setBytes(headerBytes, fieldBytes, + startOffset, numBits); + } catch (BufferException e) { + throw new PacketException(e.getMessage()); + } } } postSerializeCustomOperation(headerBytes); @@ -178,45 +188,47 @@ public abstract class Packet { } /** - * This method gets called at the end of the serialization process - * It is intended for the child packets to insert some custom data - * into the output byte stream which cannot be done or cannot be done - * efficiently during the normal Packet.serialize() path. - * An example is the checksum computation for IPv4 + * This method gets called at the end of the serialization process It is + * intended for the child packets to insert some custom data into the output + * byte stream which cannot be done or cannot be done efficiently during the + * normal Packet.serialize() path. An example is the checksum computation + * for IPv4 + * * @param byte[] - serialized bytes + * @throws PacketException */ protected void postSerializeCustomOperation(byte[] myBytes) - throws Exception { + throws PacketException { // no op } /** - * This method re-computes the checksum of the bits received on the - * wire and validates it with the checksum in the bits received - * Since the computation of checksum varies based on the protocol, - * this method is overridden - * Currently only IPv4 does checksum computation and validation - * TCP and UDP need to implement these if required + * This method re-computes the checksum of the bits received on the wire and + * validates it with the checksum in the bits received Since the computation + * of checksum varies based on the protocol, this method is overridden + * Currently only IPv4 does checksum computation and validation TCP and UDP + * need to implement these if required + * * @param byte[] data * @param int endBitOffset - * @return void + * @throws PacketException */ protected void postDeserializeCustomOperation(byte[] data, int endBitOffset) - throws Exception { - // no op + throws PacketException { + // no op } /** * Gets the header length in bits - * @return int - * @throws Exception + * + * @return int the header length in bits */ - public int getHeaderSize() throws Exception { + public int getHeaderSize() { int size = 0; /* - * We need to iterate over the fields that were read in the frame (hdrFieldsMap) - * not all the possible ones described in hdrFieldCoordMap. - * For ex, 802.1Q may or may not be there + * We need to iterate over the fields that were read in the frame + * (hdrFieldsMap) not all the possible ones described in + * hdrFieldCoordMap. For ex, 802.1Q may or may not be there */ for (Map.Entry fieldEntry : hdrFieldsMap.entrySet()) { if (fieldEntry.getValue() != null) { @@ -229,9 +241,11 @@ public abstract class Packet { /** * This method fetches the start bit offset for header field specified by - * 'fieldname'. The offset is present in the hdrFieldCoordMap of the respective - * packet class - * @param String fieldName + * 'fieldname'. The offset is present in the hdrFieldCoordMap of the + * respective packet class + * + * @param String + * fieldName * @return Integer - startOffset of the requested field */ public int getfieldOffset(String fieldName) { @@ -241,12 +255,14 @@ public abstract class Packet { /** * This method fetches the number of bits for header field specified by - * 'fieldname'. The numBits are present in the hdrFieldCoordMap of the respective - * packet class - * @param String fieldName + * 'fieldname'. The numBits are present in the hdrFieldCoordMap of the + * respective packet class + * + * @param String + * fieldName * @return Integer - number of bits of the requested field */ - public int getfieldnumBits(String fieldName) throws Exception { + public int getfieldnumBits(String fieldName) { return (((Pair) hdrFieldCoordMap.get(fieldName)) .getRight()); } @@ -261,15 +277,13 @@ public abstract class Packet { } else if (entry.getValue().length == 4) { try { ret.append(InetAddress.getByAddress(entry.getValue()) - .getHostAddress() - + " "); + .getHostAddress() + " "); } catch (UnknownHostException e) { - logger.error("",e); + logger.error("", e); } } else { ret.append(((Long) BitBufferHelper.getLong(entry.getValue())) - .toString() - + " "); + .toString() + " "); } } return ret.toString(); @@ -277,6 +291,7 @@ public abstract class Packet { /** * Returns true if the packet is corrupted + * * @return boolean */ protected boolean isPacketCorrupted() { diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/PacketException.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/PacketException.java new file mode 100644 index 0000000000..ee50273359 --- /dev/null +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/PacketException.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2013 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, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.packet; + +/** + * Describes an exception that is raised when the process of serializing or + * deserializing a network packet/stream fails. This generally happens when the + * packet/stream is malformed. + * + */ +public class PacketException extends Exception { + private static final long serialVersionUID = 1L; + + public PacketException(String message) { + super(message); + } +} diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/IPv4Test.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/IPv4Test.java index beeb7d13c0..43118ec0dd 100644 --- a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/IPv4Test.java +++ b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/IPv4Test.java @@ -90,7 +90,7 @@ public class IPv4Test { byte protocol = ip.getProtocol(); Assert.assertTrue(protocol == 1); - Class clazz = ip.protocolClassMap.get(protocol); + Class clazz = IPv4.protocolClassMap.get(protocol); System.out.printf("clazz = %s\n", clazz.getName()); Assert.assertTrue(clazz == ICMP.class); } diff --git a/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/DataPacketService.java b/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/DataPacketService.java index 3f36beaa27..7741945e73 100644 --- a/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/DataPacketService.java +++ b/opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/DataPacketService.java @@ -31,7 +31,6 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.opendaylight.controller.sal.core.ConstructionException; -import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.match.Match; import org.opendaylight.controller.sal.packet.Ethernet; @@ -516,7 +515,7 @@ public class DataPacketService implements IPluginOutDataPacketService, try { res.deserialize(data, 0, data.length * NetUtils.NumBitsInAByte); } catch (Exception e) { - logger.warn("", e); + logger.warn("Failed to decode packet: {}", e.getMessage()); } return res; } -- 2.36.6