X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fsal%2Fapi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fpacket%2FIPv4.java;h=3363f423d695f1b2f090e6c5274715f47d765e3c;hp=44318aab8c5c1626eb787b960acfaa3ede7bea29;hb=bd165724c2279b280cb6ff20543f899f68e551c7;hpb=59cc8f34c24d81a8890a94c11dedd4b21caa0adf 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 44318aab8c..3363f423d6 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 @@ -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, @@ -20,6 +20,8 @@ import java.util.Random; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; +import org.opendaylight.controller.sal.match.Match; +import org.opendaylight.controller.sal.match.MatchType; import org.opendaylight.controller.sal.utils.IPProtocols; import org.opendaylight.controller.sal.utils.NetUtils; import org.slf4j.Logger; @@ -47,6 +49,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 +151,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 +261,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 +281,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 */ @@ -378,9 +383,9 @@ public class IPv4 extends Packet { * @param checksum the checksum to set */ /*public IPv4 setChecksum() { - short ipChecksum = computeChecksum(); + short ipChecksum = computeChecksum(); byte[] checksum = BitBufferHelper.toByteArray(ipChecksum); - fieldValues.put(CHECKSUM, checksum); + fieldValues.put(CHECKSUM, checksum); return this; }*/ @@ -434,8 +439,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; @@ -444,7 +464,7 @@ public class IPv4 extends Packet { /** * Computes the IPv4 header checksum on the passed stream of bytes * representing the packet - * + * * @param data * The byte stream * @param offset @@ -455,7 +475,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 +484,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 +497,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(); } @@ -567,4 +579,12 @@ public class IPv4 extends Packet { corrupted = true; } } + + @Override + public void populateMatch(Match match) { + match.setField(MatchType.NW_SRC, NetUtils.getInetAddress(this.getSourceAddress())); + match.setField(MatchType.NW_DST, NetUtils.getInetAddress(this.getDestinationAddress())); + match.setField(MatchType.NW_PROTO, this.getProtocol()); + match.setField(MatchType.NW_TOS, this.getDiffServ()); + } }