X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fsal%2Fapi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Futils%2FIPProtocols.java;h=d3d3142cdfbcf7f06dc81d5cd49d95f0038ee971;hb=65ab4ccadb216b12d773ec4113ae241be30d3eb7;hp=cdb4463c02acb2636a0991053f9e64951e3f3ba5;hpb=541d0a36997f292bb037a2199463431eee538358;p=controller.git diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/IPProtocols.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/IPProtocols.java index cdb4463c02..d3d3142cdf 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/IPProtocols.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/IPProtocols.java @@ -13,24 +13,25 @@ import java.util.ArrayList; import java.util.List; /** - * It represents the most common IP protocols numbers - * It provides the binding between IP protocol names and numbers - * and provides APIs to read and parse them in either of the two forms - * + * Enum represents the most common IP protocols numbers It provides the binding + * between IP protocol names and numbers and provides APIs to read and parse + * them in either of the two forms * + * NOTE: Openflow 1.0 supports the IP Proto match only for ICMP, TCP and UDP * + * references: + * http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml */ -// Openflow 1.0 supports the IP Proto match only for ICMP, TCP and UDP public enum IPProtocols { - ANY("any", 0), - /* HOPOPT("HOPOPT",0), - */ICMP("ICMP", 1), - /* IGMP("IGMP",2), + ANY("any", -1), + HOPOPT("HOPOPT",0), + ICMP("ICMP", 1), + IGMP("IGMP",2), GGP("GGP",3), IPV4("IPv4",4), ST("ST",5), - */TCP("TCP", 6), - /* CBT("CBT",7), + TCP("TCP", 6), + CBT("CBT",7), EGP("EGP",8), IGP("IGP",9), BBNRCCMON("BBN-RCC-MON",10), @@ -40,8 +41,8 @@ public enum IPProtocols { EMCON("EMCON",14), XNET("XNET",15), CHAOS("CHAOS",16), - */UDP("UDP", 17), - /* MUX("MUX",18), + UDP("UDP", 17), + MUX("MUX",18), DCNMEAS("DCN-MEAS",19), HMP("HMP",20), PRM("PRM",21), @@ -81,8 +82,8 @@ public enum IPProtocols { MOBILE("MOBILE",55), TLSP("TLSP",56), SKIP("SKIP",57), - */IPV6ICMP("IPv6-ICMP", 58); - /* IPV6NoNxt("IPv6-NoNxt",59), + IPV6ICMP("IPv6-ICMP", 58), + IPV6NoNxt("IPv6-NoNxt",59), IPV6Opts("IPv6-Opts",60), ANYHOST("ANY-HOST",61), CFTP("CFTP",62), @@ -166,9 +167,15 @@ public enum IPProtocols { HIP("HIP",139), SHIM6("Shim6",140), WESP("WESP",141), - ROHC("ROHC",142); - */ - private static final String regexNumberString = "^[0-9]+$"; + ROHC("ROHC",142), + /*143-252 Unassigned by IANA*/ + + //Experimebtal protocol numbers (http://tools.ietf.org/html/rfc3692) + EXP1("Experimental1", 253), + EXP2("Experimental2", 254), + + RESERVED("RESERVED",255); + private String protocolName; private int protocolNumber; @@ -189,6 +196,7 @@ public enum IPProtocols { return ((Integer) protocolNumber).byteValue(); } + @Override public String toString() { return protocolName; } @@ -198,11 +206,11 @@ public enum IPProtocols { } public static String getProtocolName(short number) { - return getProtocolNameInternal((int) number & 0xffff); + return getProtocolNameInternal(number & 0xffff); } public static String getProtocolName(byte number) { - return getProtocolNameInternal((int) number & 0xff); + return getProtocolNameInternal(number & 0xff); } private static String getProtocolNameInternal(int number) { @@ -211,43 +219,35 @@ public enum IPProtocols { return proto.toString(); } } + //TODO: this is for backwards compatibility return "0x" + Integer.toHexString(number); } public static short getProtocolNumberShort(String name) { - if (name.matches(regexNumberString)) { - return Short.valueOf(name); - } - for (IPProtocols proto : IPProtocols.values()) { - if (proto.protocolName.equalsIgnoreCase(name)) { - return proto.shortValue(); - } + IPProtocols p = fromString(name); + if (p != null) { + return p.shortValue(); } - return 0; + //This method should be called after validation only + throw new IllegalArgumentException("Illegal IP protocol value: " + name); } public static int getProtocolNumberInt(String name) { - if (name.matches(regexNumberString)) { - return Integer.valueOf(name); - } - for (IPProtocols proto : IPProtocols.values()) { - if (proto.protocolName.equalsIgnoreCase(name)) { - return proto.intValue(); - } + IPProtocols p = fromString(name); + if (p != null) { + return p.intValue(); } - return 0; + //This method should be called after validation only + throw new IllegalArgumentException("Illegal IP protocol value: " + name); } public static byte getProtocolNumberByte(String name) { - if (name.matches(regexNumberString)) { - return Integer.valueOf(name).byteValue(); + IPProtocols p = fromString(name); + if (p != null) { + return p.byteValue(); } - for (IPProtocols proto : IPProtocols.values()) { - if (proto.protocolName.equalsIgnoreCase(name)) { - return proto.byteValue(); - } - } - return 0; + //This method should be called after validation only + throw new IllegalArgumentException("Illegal IP protocol value: " + name); } public static List getProtocolNameList() { @@ -257,4 +257,47 @@ public enum IPProtocols { } return protoList; } + + /** + * Method to parse an IPProtocol from a numeric string + * (see: {@link Java.Lang.Integer.decode(java.lang.String)} for parsable strings), + * or this enum's name string. + * + * @param s + * The IP protocol string to be parsed + * @return The IP protocol Enum, or null if invalid protocol string is passed + */ + public static IPProtocols fromString(String s) { + // null/empty/any/* evaluates to ANY + if (s == null || s.isEmpty() || s.equalsIgnoreCase("any") || s.equals("*")) { + return IPProtocols.ANY; + } + + // Try parsing numeric and find the related ENUM + try { + int protoNum = Integer.decode(s); + for (IPProtocols protoEnum : IPProtocols.values()) { + if (protoEnum.protocolNumber == protoNum) { + return protoEnum; + } + } + // At this point it's an invalid number (i.e. out of range or not a valid proto num) + return null; + } catch (NumberFormatException nfe) { + // numeric failed try by NAME + try { + return valueOf(s); + } catch(IllegalArgumentException e) { + // Neither numeric nor enum NAME, attempt human readable name + for (IPProtocols protoEnum : IPProtocols.values()) { + if (protoEnum.toString().equalsIgnoreCase(s)) { + return protoEnum; + } + } + //couldn't parse, signifies an invalid proto field! + return null; + } + + } + } }