X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=opendaylight%2Fsal%2Fapi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fpacket%2FIPv4.java;h=559acd633ab7e56b6cb22042f7d3974a1e217212;hb=92d65efa7b1f42cc0f24546c3b33c28159197176;hp=7a7a5a757fb4ab4ff7184da84a25662f42729e07;hpb=8398f3adb544427642694be13abe9c3bc1a4e192;p=controller.git 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 7a7a5a757f..559acd633a 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 @@ -47,6 +47,10 @@ public class IPv4 extends Packet { private static final String DIP = "DestinationIPAddress"; private static final String OPTIONS = "Options"; + private static final int UNIT_SIZE_SHIFT = 2; + private static final int UNIT_SIZE = (1 << UNIT_SIZE_SHIFT); + private static final int MIN_HEADER_SIZE = 20; + public static final Map> protocolClassMap; static { protocolClassMap = new HashMap>(); @@ -145,12 +149,7 @@ public class IPv4 extends Packet { public int getHeaderSize() { int headerLen = this.getHeaderLen(); if (headerLen == 0) { - headerLen = 20; - } - - byte[] options = hdrFieldsMap.get(OPTIONS); - if (options != null) { - headerLen += options.length; + headerLen = MIN_HEADER_SIZE; } return headerLen * NetUtils.NumBitsInAByte; @@ -260,6 +259,10 @@ public class IPv4 extends Packet { public void setHeaderField(String headerField, byte[] readValue) { if (headerField.equals(PROTOCOL)) { payloadClass = protocolClassMap.get(readValue[0]); + } else if (headerField.equals(OPTIONS) && + (readValue == null || readValue.length == 0)) { + hdrFieldsMap.remove(headerField); + return; } hdrFieldsMap.put(headerField, readValue); } @@ -276,7 +279,7 @@ public class IPv4 extends Packet { } /** - * Stores the length of IP header in words (2 bytes) + * Stores the length of IP header in words (4 bytes) * @param headerLength the headerLength to set * @return IPv4 */ @@ -434,8 +437,23 @@ public class IPv4 extends Packet { * @return IPv4 */ public IPv4 setOptions(byte[] options) { - fieldValues.put(OPTIONS, options); - byte newIHL = (byte) (5 + options.length); + byte newIHL = (byte)(MIN_HEADER_SIZE >>> UNIT_SIZE_SHIFT); + if (options == null || options.length == 0) { + fieldValues.remove(OPTIONS); + } else { + int len = options.length; + int rlen = (len + (UNIT_SIZE - 1)) & ~(UNIT_SIZE - 1); + if (rlen > len) { + // Padding is required. + byte[] newopt = new byte[rlen]; + System.arraycopy(options, 0, newopt, 0, len); + options = newopt; + len = rlen; + } + fieldValues.put(OPTIONS, options); + newIHL += (len >>> UNIT_SIZE_SHIFT); + } + setHeaderLength(newIHL); return this; @@ -455,7 +473,7 @@ public class IPv4 extends Packet { int end = start + getHeaderLen(); short checkSum = (short) 0; int sum = 0, carry = 0, finalSum = 0; - int parsedHex = 0; + int wordData; int checksumStart = start + (getfieldOffset(CHECKSUM) / NetUtils.NumBitsInAByte); @@ -464,14 +482,8 @@ public class IPv4 extends Packet { if (i == checksumStart) { continue; } - StringBuffer sbuffer = new StringBuffer(); - sbuffer.append(String.format("%02X", data[i])); - if (i < (data.length - 1)) { - sbuffer.append(String.format("%02X", data[i + 1])); - } - - parsedHex = Integer.valueOf(sbuffer.toString(), 16); - sum += parsedHex; + wordData = ((data[i] << 8) & 0xFF00) + (data[i + 1] & 0xFF); + sum = sum + wordData; } carry = (sum >> 16) & 0xFF; finalSum = (sum & 0xFFFF) + carry; @@ -483,15 +495,13 @@ public class IPv4 extends Packet { @Override /** * Gets the number of bits for the fieldname specified - * If the fieldname has variable length like "Options", then this value is computed using the - * options length and the header length + * If the fieldname has variable length like "Options", then this value is computed using the header length * @param fieldname - String * @return number of bits for fieldname - int */ public int getfieldnumBits(String fieldName) { if (fieldName.equals(OPTIONS)) { - byte[] options = getOptions(); - return ((options == null) ? 0 : (options.length - getHeaderLen())); + return (getHeaderLen() - MIN_HEADER_SIZE) * NetUtils.NumBitsInAByte; } return hdrFieldCoordMap.get(fieldName).getRight(); }