From 81391595dca425ae58e2294898f09f11d9a32dbc Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Tue, 22 Sep 2015 12:49:09 -0700 Subject: bringing src to commit tag 65d551b50e782b0c1ea76c1a9ed1c5a801a5a7e4 Change-Id: Ib2da78962eaef856f418636c31b0f5c84286244f --- framework/src/onos/utils/jdvue/bin/jdvue | 2 +- framework/src/onos/utils/jdvue/pom.xml | 26 +- .../src/main/java/org/onlab/jdvue/Catalog.java | 15 ++ .../src/main/java/org/onlab/jdvue/Dependency.java | 15 ++ .../main/java/org/onlab/jdvue/DependencyCycle.java | 15 ++ .../java/org/onlab/jdvue/DependencyViewer.java | 15 ++ .../src/main/java/org/onlab/jdvue/JavaEntity.java | 15 ++ .../src/main/java/org/onlab/jdvue/JavaPackage.java | 15 ++ .../src/main/java/org/onlab/jdvue/JavaSource.java | 15 ++ .../src/test/java/org/onlab/jdvue/CatalogTest.java | 15 ++ .../java/org/onlab/jdvue/DependencyCycleTest.java | 15 ++ .../test/java/org/onlab/jdvue/DependencyTest.java | 15 ++ .../java/org/onlab/jdvue/DependencyViewerTest.java | 15 ++ framework/src/onos/utils/jnc/pom.xml | 2 +- framework/src/onos/utils/junit/pom.xml | 2 +- framework/src/onos/utils/misc/pom.xml | 2 +- .../src/main/java/org/onlab/graph/GAOrganism.java | 15 ++ .../main/java/org/onlab/graph/GAPopulation.java | 15 ++ .../misc/src/main/java/org/onlab/packet/IPv4.java | 2 + .../misc/src/main/java/org/onlab/packet/MPLS.java | 15 ++ .../misc/src/main/java/org/onlab/packet/PIM.java | 296 +++++++++++++++++++++ .../java/org/onlab/packet/pim/PIMAddrGroup.java | 257 ++++++++++++++++++ .../java/org/onlab/packet/pim/PIMAddrSource.java | 281 +++++++++++++++++++ .../java/org/onlab/packet/pim/PIMAddrUnicast.java | 182 +++++++++++++ .../main/java/org/onlab/packet/pim/PIMHello.java | 118 ++++++++ .../java/org/onlab/packet/pim/PIMHelloOption.java | 147 ++++++++++ .../java/org/onlab/packet/pim/PIMJoinPrune.java | 271 +++++++++++++++++++ .../java/org/onlab/packet/pim/package-info.java | 21 ++ .../src/test/java/org/onlab/packet/PIMTest.java | 132 +++++++++ .../test/java/org/onlab/util/HexStringTest.java | 4 +- framework/src/onos/utils/netty/pom.xml | 2 +- framework/src/onos/utils/nio/pom.xml | 2 +- framework/src/onos/utils/osgi/pom.xml | 2 +- framework/src/onos/utils/pom.xml | 2 +- framework/src/onos/utils/rest/pom.xml | 2 +- framework/src/onos/utils/stc/bin/stc | 2 +- framework/src/onos/utils/stc/pom.xml | 2 +- .../src/main/java/org/onlab/stc/Coordinator.java | 9 + .../stc/src/main/java/org/onlab/stc/Main.java | 24 +- .../src/main/java/org/onlab/stc/ScenarioStore.java | 25 ++ framework/src/onos/utils/thirdparty/pom.xml | 2 +- 41 files changed, 2007 insertions(+), 22 deletions(-) create mode 100755 framework/src/onos/utils/misc/src/main/java/org/onlab/packet/PIM.java create mode 100644 framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrGroup.java create mode 100644 framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java create mode 100644 framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrUnicast.java create mode 100644 framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHello.java create mode 100644 framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHelloOption.java create mode 100644 framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMJoinPrune.java create mode 100755 framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/package-info.java create mode 100644 framework/src/onos/utils/misc/src/test/java/org/onlab/packet/PIMTest.java (limited to 'framework/src/onos/utils') diff --git a/framework/src/onos/utils/jdvue/bin/jdvue b/framework/src/onos/utils/jdvue/bin/jdvue index 86adfb4f..3dda5969 100755 --- a/framework/src/onos/utils/jdvue/bin/jdvue +++ b/framework/src/onos/utils/jdvue/bin/jdvue @@ -8,7 +8,7 @@ JDVUE_ROOT=${JDVUE_ROOT:-$(dirname $0)/..} cd $JDVUE_ROOT -VER=1.3.0-SNAPSHOT +VER=1.4.0-SNAPSHOT JAR=$PWD/target/jdvue-${VER}.jar # start with the dev jar first cd - >/dev/null diff --git a/framework/src/onos/utils/jdvue/pom.xml b/framework/src/onos/utils/jdvue/pom.xml index 3399a8ab..d1501027 100644 --- a/framework/src/onos/utils/jdvue/pom.xml +++ b/framework/src/onos/utils/jdvue/pom.xml @@ -1,5 +1,21 @@ - + 4.0.0 @@ -9,7 +25,7 @@ org.onosproject onlab-utils - 1.3.0-SNAPSHOT + 1.4.0-SNAPSHOT ../pom.xml @@ -70,8 +86,10 @@ 2.3 - - org.onlab.jdvue.DependencyViewer + + org.onlab.jdvue.DependencyViewer + diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Catalog.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Catalog.java index 8f611c52..40cb99a3 100644 --- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Catalog.java +++ b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Catalog.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.jdvue; diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Dependency.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Dependency.java index 7fc3409a..21fae479 100644 --- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Dependency.java +++ b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Dependency.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.jdvue; import java.util.Objects; diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java index 65e3cfbc..444995bf 100644 --- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java +++ b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.jdvue; import java.util.ArrayList; diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyViewer.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyViewer.java index a210d717..32e9ef1c 100644 --- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyViewer.java +++ b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyViewer.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.jdvue; import com.fasterxml.jackson.databind.JsonNode; diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaEntity.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaEntity.java index 31959307..e74bdc60 100644 --- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaEntity.java +++ b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaEntity.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.jdvue; import java.util.Objects; diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaPackage.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaPackage.java index 7bf4be16..a15cb4d3 100644 --- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaPackage.java +++ b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaPackage.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.jdvue; import java.util.Collections; diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaSource.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaSource.java index 8919a13e..1376cfee 100644 --- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaSource.java +++ b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaSource.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.jdvue; import java.util.*; diff --git a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/CatalogTest.java b/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/CatalogTest.java index 99d22087..b792abcc 100644 --- a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/CatalogTest.java +++ b/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/CatalogTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.jdvue; import org.junit.Test; diff --git a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyCycleTest.java b/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyCycleTest.java index a0a7c7cb..895c713f 100644 --- a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyCycleTest.java +++ b/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyCycleTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.jdvue; import org.junit.Test; diff --git a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyTest.java b/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyTest.java index 4dfe9615..94740dae 100644 --- a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyTest.java +++ b/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.jdvue; import com.google.common.testing.EqualsTester; diff --git a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyViewerTest.java b/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyViewerTest.java index cdac0c24..0937c068 100644 --- a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyViewerTest.java +++ b/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyViewerTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.jdvue; import org.junit.Test; diff --git a/framework/src/onos/utils/jnc/pom.xml b/framework/src/onos/utils/jnc/pom.xml index a70bfbe7..6d0f8343 100644 --- a/framework/src/onos/utils/jnc/pom.xml +++ b/framework/src/onos/utils/jnc/pom.xml @@ -22,7 +22,7 @@ org.onosproject onlab-utils - 1.3.0-SNAPSHOT + 1.4.0-SNAPSHOT ../pom.xml diff --git a/framework/src/onos/utils/junit/pom.xml b/framework/src/onos/utils/junit/pom.xml index 90178346..c9787a41 100644 --- a/framework/src/onos/utils/junit/pom.xml +++ b/framework/src/onos/utils/junit/pom.xml @@ -22,7 +22,7 @@ org.onosproject onlab-utils - 1.3.0-SNAPSHOT + 1.4.0-SNAPSHOT ../pom.xml diff --git a/framework/src/onos/utils/misc/pom.xml b/framework/src/onos/utils/misc/pom.xml index 17951215..2e721135 100644 --- a/framework/src/onos/utils/misc/pom.xml +++ b/framework/src/onos/utils/misc/pom.xml @@ -22,7 +22,7 @@ org.onosproject onlab-utils - 1.3.0-SNAPSHOT + 1.4.0-SNAPSHOT ../pom.xml diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAOrganism.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAOrganism.java index 230609f8..a0e0570d 100644 --- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAOrganism.java +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAOrganism.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.graph; /** diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAPopulation.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAPopulation.java index ae7f182e..c5fa9b45 100644 --- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAPopulation.java +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAPopulation.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.graph; import java.util.ArrayList; diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPv4.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPv4.java index d75b50a2..a5c5f4f1 100644 --- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPv4.java +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPv4.java @@ -35,6 +35,7 @@ public class IPv4 extends BasePacket { public static final byte PROTOCOL_IGMP = 0x2; public static final byte PROTOCOL_TCP = 0x6; public static final byte PROTOCOL_UDP = 0x11; + public static final byte PROTOCOL_PIM = 0x67; public static final Map> PROTOCOL_DESERIALIZER_MAP = new HashMap<>(); @@ -43,6 +44,7 @@ public class IPv4 extends BasePacket { IPv4.PROTOCOL_DESERIALIZER_MAP.put(IPv4.PROTOCOL_IGMP, IGMP.deserializer()); IPv4.PROTOCOL_DESERIALIZER_MAP.put(IPv4.PROTOCOL_TCP, TCP.deserializer()); IPv4.PROTOCOL_DESERIALIZER_MAP.put(IPv4.PROTOCOL_UDP, UDP.deserializer()); + IPv4.PROTOCOL_DESERIALIZER_MAP.put(IPv4.PROTOCOL_PIM, PIM.deserializer()); } private static final byte DSCP_MASK = 0x3f; diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MPLS.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MPLS.java index 47dbeed2..71c5803e 100644 --- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MPLS.java +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MPLS.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.onlab.packet; import java.nio.ByteBuffer; diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/PIM.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/PIM.java new file mode 100755 index 00000000..d9a5e83f --- /dev/null +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/PIM.java @@ -0,0 +1,296 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onlab.packet; + +import org.onlab.packet.pim.PIMHello; +import org.onlab.packet.pim.PIMJoinPrune; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import static org.onlab.packet.PacketUtils.checkInput; + +/** + * Implements PIM control packet format. + */ +public class PIM extends BasePacket { + + public static final IpAddress PIM_ADDRESS = IpAddress.valueOf("224.0.0.13"); + + public static final byte TYPE_HELLO = 0x00; + public static final byte TYPE_REGISTER = 0x01; + public static final byte TYPE_REGISTER_STOP = 0x02; + public static final byte TYPE_JOIN_PRUNE_REQUEST = 0x03; + public static final byte TYPE_BOOTSTRAP = 0x04; + public static final byte TYPE_ASSERT = 0x05; + public static final byte TYPE_GRAFT = 0x06; + public static final byte TYPE_GRAFT_ACK = 0x07; + public static final byte TYPE_CANDIDATE_RP_ADV = 0x08; + + public static final int PIM_HEADER_LEN = 4; + + public static final Map> PROTOCOL_DESERIALIZER_MAP = + new HashMap<>(); + + static { + PIM.PROTOCOL_DESERIALIZER_MAP.put(PIM.TYPE_HELLO, PIMHello.deserializer()); + PIM.PROTOCOL_DESERIALIZER_MAP.put(PIM.TYPE_JOIN_PRUNE_REQUEST, PIMJoinPrune.deserializer()); + } + + /* + * PIM Header fields + */ + protected byte version; + protected byte type; + protected byte reserved; + protected short checksum; + + /** + * Default constructor. + */ + public PIM() { + super(); + this.version = 2; + this.reserved = 0; + } + + /** + * Return the PIM message type. + * + * @return the pimMsgType + */ + public byte getPimMsgType() { + return this.type; + } + + /** + * Set the PIM message type. Currently PIMJoinPrune and PIMHello are + * supported. + * + * @param type PIM message type + * @return PIM Header + */ + public PIM setPIMType(final byte type) { + this.type = type; + return this; + } + + /** + * Get the version of PIM. + * + * @return the PIM version. Must be 2. + */ + public byte getVersion() { + return version; + } + + /** + * Set the PIM version type. Should not change from 2. + * + * @param version PIM version + */ + public void setVersion(byte version) { + this.version = version; + } + + /** + * Get the reserved field. + * + * @return the reserved field. Must be ignored. + */ + public byte getReserved() { + return reserved; + } + + /** + * Set the reserved field. + * + * @param reserved should be 0 + */ + public void setReserved(byte reserved) { + this.reserved = reserved; + } + + /** + * Get the checksum of this packet. + * + * @return the checksum + */ + public short getChecksum() { + return checksum; + } + + /** + * Set the checksum. + * + * @param checksum the checksum + */ + public void setChecksum(short checksum) { + this.checksum = checksum; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 5807; + int result = super.hashCode(); + result = prime * result + this.type; + result = prime * result + this.version; + result = prime * result + this.checksum; + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof PIM)) { + return false; + } + final PIM other = (PIM) obj; + if (this.type != other.type) { + return false; + } + if (this.version != other.version) { + return false; + } + if (this.checksum != other.checksum) { + return false; + } + return true; + } + + /** + * Serializes the packet. Will compute and set the following fields if they + * are set to specific values at the time serialize is called: -checksum : 0 + * -length : 0 + * + * @return will return the serialized packet + */ + @Override + public byte[] serialize() { + int length = 4; + byte[] payloadData = null; + if (this.payload != null) { + this.payload.setParent(this); + payloadData = this.payload.serialize(); + length += payloadData.length; + } + + final byte[] data = new byte[length]; + final ByteBuffer bb = ByteBuffer.wrap(data); + + bb.put((byte) ((this.version & 0xf) << 4 | this.type & 0xf)); + bb.put(this.reserved); + bb.putShort(this.checksum); + if (payloadData != null) { + bb.put(payloadData); + } + + if (this.parent != null && this.parent instanceof PIM) { + ((PIM) this.parent).setPIMType(TYPE_JOIN_PRUNE_REQUEST); + } + + // compute checksum if needed + if (this.checksum == 0) { + bb.rewind(); + int accumulation = 0; + + for (int i = 0; i < length / 2; ++i) { + accumulation += 0xffff & bb.getShort(); + } + // pad to an even number of shorts + if (length % 2 > 0) { + accumulation += (bb.get() & 0xff) << 8; + } + + accumulation = (accumulation >> 16 & 0xffff) + + (accumulation & 0xffff); + this.checksum = (short) (~accumulation & 0xffff); + bb.putShort(2, this.checksum); + } + return data; + } + + /** + * Deserialize the PIM packet. + * + * @param data bytes to deserialize. + * @param offset offset to start deserializing from + * @param length length of the data to deserialize + * + * @return the deserialized PIM packet. + */ + @Override + public IPacket deserialize(final byte[] data, final int offset, + final int length) { + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); + this.type = bb.get(); + this.version = bb.get(); + this.checksum = bb.getShort(); + + //this.payload = new Data(); + this.payload = this.payload.deserialize(data, bb.position(), bb.limit() - bb.position()); + this.payload.setParent(this); + return this; + } + /** + * Deserializer function for IPv4 packets. + * + * @return deserializer function + */ + public static Deserializer deserializer() { + return (data, offset, length) -> { + checkInput(data, offset, length, PIM_HEADER_LEN); + + PIM pim = new PIM(); + + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); + + byte versionByte = bb.get(); + pim.version = (byte) (versionByte >> 4 & 0xf); + pim.setPIMType((byte) (versionByte & 0xf)); + pim.reserved = bb.get(); + pim.checksum = bb.getShort(); + + Deserializer deserializer; + if (PIM.PROTOCOL_DESERIALIZER_MAP.containsKey(pim.getPimMsgType())) { + deserializer = PIM.PROTOCOL_DESERIALIZER_MAP.get(pim.getPimMsgType()); + } else { + deserializer = Data.deserializer(); + } + + pim.payload = deserializer.deserialize(data, bb.position(), bb.limit() - bb.position()); + pim.payload.setParent(pim); + + return pim; + }; + } +} diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrGroup.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrGroup.java new file mode 100644 index 00000000..891a0193 --- /dev/null +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrGroup.java @@ -0,0 +1,257 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onlab.packet.pim; + +import org.onlab.packet.DeserializationException; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpPrefix; +import org.onlab.packet.Ip6Address; + +import java.nio.ByteBuffer; + +import static org.onlab.packet.PacketUtils.checkInput; + +public class PIMAddrGroup { + private byte family; + private byte encType; + private byte reserved; + private boolean bBit; + private boolean zBit; + private byte masklen; + IpAddress addr; + + public static final int ENC_GROUP_IPV4_BYTE_LENGTH = 4 + Ip4Address.BYTE_LENGTH; + public static final int ENC_GROUP_IPV6_BYTE_LENGTH = 4 + Ip6Address.BYTE_LENGTH; + + /** + * PIM Encoded Group Address. + */ + public PIMAddrGroup() { + this.family = 4; + this.encType = 0; + this.reserved = 0; + this.bBit = false; + this.zBit = false; + } + + /** + * PIM Encoded Source Address. + * + * @param addr IPv4 or IPv6 + */ + public PIMAddrGroup(String addr) { + this.setAddr(addr); + } + + /** + * PIM Encoded Group Address. + * + * @param gpfx PIM encoded group address. + */ + public PIMAddrGroup(IpPrefix gpfx) { + this.setAddr(gpfx); + } + + /** + * PIM encoded source address. + * + * @param addr IPv4 or IPv6 + */ + public void setAddr(String addr) { + setAddr(IpPrefix.valueOf(addr)); + } + + /** + * Set the encoded source address. + * + * @param pfx address prefix + */ + public void setAddr(IpPrefix pfx) { + this.addr = pfx.address(); + this.masklen = (byte) pfx.prefixLength(); + this.family = (byte) ((this.addr.isIp4()) ? 4 : 6); + } + + /** + * Get the IP family of this address: 4 or 6. + * + * @return the IP address family + */ + public int getFamily() { + return this.family; + } + + /** + * Get the address of this encoded address. + * + * @return source address + */ + public IpAddress getAddr() { + return this.addr; + } + + /** + * Get the masklen of the group address. + * + * @return the masklen + */ + public int getMasklen() { + return this.masklen; + } + + /** + * Return the z bit for admin scoping. Only used for the Bootstrap router. + * + * @return true or false + */ + public boolean getZBit() { + return this.zBit; + } + + /** + * Return the bBit. Used to indicate this is a bidir + * + * @return return true or false. + */ + public boolean getBBit() { + return this.bBit; + } + + /** + * The size in bytes of a serialized address. + * + * @return the number of bytes when serialized + */ + public int getByteSize() { + int size = 4; + size += addr.isIp4() ? 4 : 16; + return size; + } + + /** + * Serialize this group address. + * + * @return the serialized address in a buffer + */ + public byte[] serialize() { + int len = getByteSize(); + + final byte[] data = new byte[len]; + final ByteBuffer bb = ByteBuffer.wrap(data); + + bb.put(this.family); + bb.put(this.encType); + + // Todo: technically we should be setting the B and Z bits, but we'll never use them. + bb.put(reserved); + + bb.put(this.masklen); + bb.put(this.addr.toOctets()); + return data; + } + + /** + * Deserialze from a ByteBuffer. + * + * @param bb the ByteBuffer + * @return an encoded PIM group address + * @throws DeserializationException if unable to deserialize the packet data + */ + public PIMAddrGroup deserialize(ByteBuffer bb) throws DeserializationException { + + /* + * We need to verify that we have enough buffer space. First we'll assume that + * we are decoding an IPv4 address. After we read the first by (address family), + * we'll determine if we actually need more buffer space for an IPv6 address. + */ + checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_GROUP_IPV4_BYTE_LENGTH); + + this.family = bb.get(); + if (family != 4 && family != 6) { + throw new DeserializationException("Illegal IP version number: " + family + "\n"); + } else if (family == 6) { + + // Check for one less by since we have already read the first byte of the packet. + checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_GROUP_IPV6_BYTE_LENGTH - 1); + } + + this.encType = bb.get(); + this.reserved = bb.get(); + if ((this.reserved & 0x80) != 0) { + this.bBit = true; + } + if ((this.reserved & 0x01) != 0) { + this.zBit = true; + } + // Remove the z and b bits from reserved + this.reserved |= 0x7d; + + this.masklen = bb.get(); + if (this.family == 4) { + this.addr = IpAddress.valueOf(bb.getInt()); + } else if (this.family == 6) { + this.addr = Ip6Address.valueOf(bb.array(), 2); + } + return this; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 2521; + int result = super.hashCode(); + result = prime * result + this.family; + result = prime * result + this.encType; + result = prime * result + this.reserved; + result = prime * result + this.masklen; + result = prime * result + this.addr.hashCode(); + return result; + } + + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals() + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof PIMAddrGroup)) { + return false; + } + final PIMAddrGroup other = (PIMAddrGroup) obj; + if (this.family != this.family) { + return false; + } + + if (this.encType != other.encType) { + return false; + } + + if (!this.addr.equals(other.addr)) { + return false; + } + return true; + } +} diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java new file mode 100644 index 00000000..2d4a7816 --- /dev/null +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java @@ -0,0 +1,281 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onlab.packet.pim; + +import org.onlab.packet.DeserializationException; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpPrefix; +import org.onlab.packet.Ip6Address; + +import java.nio.ByteBuffer; + +import static org.onlab.packet.PacketUtils.checkInput; + +public class PIMAddrSource { + private byte family; + private byte encType; + private byte reserved; + private boolean sBit; + private boolean wBit; + private boolean rBit; + private byte masklen; + IpAddress addr; + + public static final int ENC_SOURCE_IPV4_BYTE_LENGTH = 4 + Ip4Address.BYTE_LENGTH; + public static final int ENC_SOURCE_IPV6_BYTE_LENGTH = 4 + Ip6Address.BYTE_LENGTH; + + /** + * PIM Encoded Source Address. + * + * @param addr IPv4 or IPv6 + */ + public PIMAddrSource(String addr) { + this.init(); + this.setAddr(addr); + } + + /** + * PIM Encoded Source Address. + * + * @param spfx IPv4 or IPv6 + */ + public PIMAddrSource(IpPrefix spfx) { + this.init(); + this.setAddr(spfx); + } + + /** + * PIM Encoded Group Address. + */ + public PIMAddrSource() { + this.init(); + } + + private void init() { + this.family = 4; + this.encType = 0; + this.reserved = 0; + this.sBit = true; + this.wBit = false; + this.rBit = false; + } + + /** + * PIM Encoded Source Address. + * + * @param addr IPv4 or IPv6 + */ + public void setAddr(String addr) { + IpPrefix spfx = IpPrefix.valueOf(addr); + setAddr(spfx); + } + + /** + * PIM Encoded Source Address. + * + * @param spfx IPv4 or IPv6 address prefix + */ + public void setAddr(IpPrefix spfx) { + this.addr = spfx.address(); + this.masklen = (byte) spfx.prefixLength(); + this.family = (byte) ((this.addr.isIp4()) ? 4 : 6); + } + + /** + * Get the IP family of this address: 4 or 6. + * + * @return the IP address family + */ + public byte getFamily() { + return this.family; + } + + /** + * Get the address of this encoded address. + * + * @return source address + */ + public IpAddress getAddr() { + return this.addr; + } + + /** + * Get the masklen of the group address. + * + * @return the masklen + */ + public int getMasklen() { + return this.masklen; + } + + /** + * Return the sparse bit. + * + * @return true or false + */ + public boolean getSBit() { + return this.sBit; + } + + /** + * Return the wBit, used in Join/Prune messages. + * + * @return return true or false. + */ + public boolean getWBit() { + return this.wBit; + } + + /** + * Return the rBit. Used by Rendezvous Point. + * + * @return the rBit. + */ + public boolean getRBit() { + return this.rBit; + } + + /** + * The size in bytes of a serialized address. + * + * @return the number of bytes when serialized + */ + public int getByteSize() { + int size = 4; + size += addr.isIp4() ? 4 : 16; + return size; + } + + public byte[] serialize() { + int len = addr.isIp4() ? ENC_SOURCE_IPV4_BYTE_LENGTH : ENC_SOURCE_IPV6_BYTE_LENGTH; + + final byte[] data = new byte[len]; + final ByteBuffer bb = ByteBuffer.wrap(data); + + bb.put(this.family); + bb.put(this.encType); + + // Todo: technically we should be setting the B and Z bits, but we'll never use them. + byte mask = 0x0; + if (this.sBit) { + this.reserved |= 0x4; + } + if (this.wBit) { + this.reserved |= 0x2; + } + if (this.rBit) { + this.reserved |= 0x1; + } + bb.put(reserved); + + bb.put(this.masklen); + bb.put(this.addr.toOctets()); + return data; + } + + public PIMAddrSource deserialize(byte[] data, int offset, int length) throws DeserializationException { + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); + return deserialize(bb); + } + + public PIMAddrSource deserialize(ByteBuffer bb) throws DeserializationException { + + /* + * We need to verify that we have enough buffer space. First we'll assume that + * we are decoding an IPv4 address. After we read the first by (address family), + * we'll determine if we actually need more buffer space for an IPv6 address. + */ + checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_SOURCE_IPV4_BYTE_LENGTH); + + this.family = bb.get(); + if (family != 4 && family != 6) { + throw new DeserializationException("Illegal IP version number: " + family + "\n"); + } else if (family == 6) { + + // Check for one less by since we have already read the first byte of the packet. + checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_SOURCE_IPV6_BYTE_LENGTH - 1); + } + + this.encType = bb.get(); + this.reserved = bb.get(); + if ((this.reserved & 0x01) != 0) { + this.rBit = true; + } + if ((this.reserved & 0x02) != 0) { + this.wBit = true; + } + if ((this.reserved & 0x4) != 0) { + this.sBit = true; + } + + // Remove the s, reserved + this.reserved &= 0xf8; + + this.masklen = bb.get(); + if (this.family == 4) { + this.addr = IpAddress.valueOf(bb.getInt()); + } else if (this.family == 6) { + this.addr = Ip6Address.valueOf(bb.array(), 2); + } + return this; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 2521; + int result = super.hashCode(); + result = prime * result + this.family; + result = prime * result + this.encType; + result = prime * result + this.reserved; + result = prime * result + this.masklen; + result = prime * result + this.addr.hashCode(); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof PIMAddrSource)) { + return false; + } + final PIMAddrSource other = (PIMAddrSource) obj; + if (this.family != this.family) { + return false; + } + + if (this.encType != other.encType) { + return false; + } + + if (!this.addr.equals(other.addr)) { + return false; + } + return true; + } +} diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrUnicast.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrUnicast.java new file mode 100644 index 00000000..0c2d676b --- /dev/null +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrUnicast.java @@ -0,0 +1,182 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onlab.packet.pim; + +import org.onlab.packet.DeserializationException; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.Ip6Address; + +import java.nio.ByteBuffer; + +import static org.onlab.packet.PacketUtils.checkInput; + +public class PIMAddrUnicast { + private byte family; + private byte encType; + IpAddress addr; + + public static final int ENC_UNICAST_IPV4_BYTE_LENGTH = 2 + Ip4Address.BYTE_LENGTH; + public static final int ENC_UNICAST_IPV6_BYTE_LENGTH = 2 + Ip6Address.BYTE_LENGTH; + + /** + * PIM Encoded Source Address. + */ + public PIMAddrUnicast() { + this.family = 4; + this.encType = 0; + } + + /** + * PIM Encoded Source Address. + * + * @param addr IPv4 or IPv6 + */ + public PIMAddrUnicast(String addr) { + this.addr = IpAddress.valueOf(addr); + if (this.addr.isIp4()) { + this.family = 4; + } else { + this.family = 6; + } + this.encType = 0; + } + + /** + * PIM Encoded Source Address. + * + * @param addr IPv4 or IPv6 + */ + public void setAddr(IpAddress addr) { + this.addr = addr; + if (this.addr.isIp4()) { + this.family = 4; + } else { + this.family = 6; + } + } + + /** + * Get the address of this encoded address. + * + * @return source address + */ + public IpAddress getAddr() { + return this.addr; + } + + /** + * Get the IP family of this address: 4 or 6. + * + * @return the IP address family + */ + public int getFamily() { + return this.family; + } + + /** + * The size in bytes of a serialized address. + * + * @return the number of bytes when serialized + */ + public int getByteSize() { + int size = 2; + if (addr != null) { + size += addr.isIp4() ? 4 : 16; + } else { + size += 4; + } + return size; + } + + public byte[] serialize() { + int len = getByteSize(); + + final byte[] data = new byte[len]; + final ByteBuffer bb = ByteBuffer.wrap(data); + + bb.put(family); + bb.put(encType); + bb.put(addr.toOctets()); + return data; + } + + public PIMAddrUnicast deserialize(ByteBuffer bb) throws DeserializationException { + + // Assume IPv4 for check length until we read the encoded family. + checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_UNICAST_IPV4_BYTE_LENGTH); + this.family = bb.get(); + + // If we have IPv6 we need to ensure we have adequate buffer space. + if (this.family != 4 && this.family != 6) { + throw new DeserializationException("Invalid address family: " + this.family); + } else if (this.family == 6) { + // Subtract -1 from ENC_UNICAST_IPv6 BYTE_LENGTH because we read one byte for family previously. + checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_UNICAST_IPV6_BYTE_LENGTH - 1); + } + + this.encType = bb.get(); + if (this.family == 4) { + this.addr = IpAddress.valueOf(bb.getInt()); + } else if (this.family == 6) { + this.addr = Ip6Address.valueOf(bb.array(), 2); + } + return this; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 2521; + int result = super.hashCode(); + result = prime * result + this.family; + result = prime * result + this.encType; + result = prime * result + this.addr.hashCode(); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof PIMAddrUnicast)) { + return false; + } + final PIMAddrUnicast other = (PIMAddrUnicast) obj; + if (this.family != this.family) { + return false; + } + + if (this.encType != other.encType) { + return false; + } + + if (!this.addr.equals(other.addr)) { + return false; + } + return true; + } +} diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHello.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHello.java new file mode 100644 index 00000000..9ad3fdbd --- /dev/null +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHello.java @@ -0,0 +1,118 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onlab.packet.pim; + +import org.onlab.packet.BasePacket; +import org.onlab.packet.Deserializer; +import org.onlab.packet.IPacket; +import org.onlab.packet.IpAddress; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import static org.onlab.packet.PacketUtils.checkInput; + +public class PIMHello extends BasePacket { + + private IpAddress nbrIpAddress; + private boolean priorityPresent = false; + + private Map options = new HashMap<>(); + + /** + * Create a PIM Hello packet with the most common hello options and default + * values. The values of any options can be easily changed by modifying the value of + * the option with the desired change. + */ + public void createDefaultOptions() { + options.put(PIMHelloOption.OPT_HOLDTIME, new PIMHelloOption(PIMHelloOption.OPT_HOLDTIME)); + options.put(PIMHelloOption.OPT_PRIORITY, new PIMHelloOption(PIMHelloOption.OPT_PRIORITY)); + options.put(PIMHelloOption.OPT_GENID, new PIMHelloOption(PIMHelloOption.OPT_GENID)); + } + + /** + * Add a PIM Hello option to this hello message. Note + * + * @param opt the PIM Hello option we are adding + */ + public void addOption(PIMHelloOption opt) { + this.options.put(opt.getOptType(), opt); + } + + public Map getOptions() { + return this.options; + } + + /** + * Sets all payloads parent packet if applicable, then serializes this + * packet and all payloads. + * + * @return a byte[] containing this packet and payloads + */ + @Override + public byte[] serialize() { + int totalLen = 0; + + + // Since we are likely to only have 3-4 options, go head and walk the + // hashmap twice, once to calculate the space needed to allocate a + // buffer, the second time serialize the options into the buffer. This + // saves us from allocating an over sized buffer the re-allocating and + // copying. + for (Short optType : options.keySet()) { + PIMHelloOption opt = options.get(optType); + totalLen += PIMHelloOption.MINIMUM_OPTION_LEN_BYTES + opt.getOptLength(); + } + + byte[] data = new byte[totalLen]; + ByteBuffer bb = ByteBuffer.wrap(data); + + // Now serialize the data. + for (Short optType : options.keySet()) { + PIMHelloOption opt = options.get(optType); + bb.put(opt.serialize()); + } + return data; + } + + /** + * XXX: This is deprecated, DO NOT USE, use the deserializer() function instead. + */ + public IPacket deserialize(final byte[] data, final int offset, + final int length) { + // TODO: throw an expection? + return null; + } + + /** + * Deserialize this hello message. + * + * @return a deserialized hello message + */ + public static Deserializer deserializer() { + return (data, offset, length) -> { + checkInput(data, offset, length, PIMHelloOption.MINIMUM_OPTION_LEN_BYTES); + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); + + PIMHello hello = new PIMHello(); + while (bb.hasRemaining()) { + PIMHelloOption opt = PIMHelloOption.deserialize(bb); + hello.addOption(opt); + } + return hello; + }; + } +} diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHelloOption.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHelloOption.java new file mode 100644 index 00000000..bf021fbd --- /dev/null +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHelloOption.java @@ -0,0 +1,147 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onlab.packet.pim; + +import org.onlab.packet.DeserializationException; + +import java.nio.ByteBuffer; +import java.text.MessageFormat; + +import static org.onlab.packet.PacketUtils.checkBufferLength; +import static org.onlab.packet.PacketUtils.checkInput; + +public class PIMHelloOption { + + /** + * PIM Option types. + */ + public static final short OPT_HOLDTIME = 1; + public static final short OPT_PRUNEDELAY = 2; + public static final short OPT_PRIORITY = 19; + public static final short OPT_GENID = 20; + public static final short OPT_ADDRLIST = 24; + + public static final short DEFAULT_HOLDTIME = 105; + public static final int DEFAULT_PRUNEDELAY = 2000; // 2,000 ms + public static final int DEFAULT_PRIORITY = 1; + public static final int DEFAULT_GENID = 0; + + public static final int MINIMUM_OPTION_LEN_BYTES = 4; + + // Values for this particular hello option. + private short optType; + private short optLength; + private byte[] optValue; + + public PIMHelloOption() { + } + + /** + * Set a PIM Hello option by type. The length and default value of the + * type will be auto filled in by default. + * + * @param type hello option type + */ + public PIMHelloOption(short type) { + this.optType = type; + switch (type) { + case OPT_HOLDTIME: + this.optLength = 2; + this.optValue = new byte[optLength]; + ByteBuffer.wrap(this.optValue).putShort(PIMHelloOption.DEFAULT_HOLDTIME); + break; + + case OPT_PRUNEDELAY: + this.optLength = 4; + this.optValue = new byte[this.optLength]; + ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_PRUNEDELAY); + break; + + case OPT_PRIORITY: + this.optLength = 4; + this.optValue = new byte[this.optLength]; + ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_PRIORITY); + break; + + case OPT_GENID: + this.optLength = 4; + this.optValue = new byte[this.optLength]; + ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_GENID); + break; + + case OPT_ADDRLIST: + this.optLength = 0; // We don't know what the length will be yet. + this.optValue = null; + + default: + //log.error("Unkown option type: " + type + "\n" ); + return; + } + } + + public void setOptType(short type) { + this.optType = type; + } + + public short getOptType() { + return this.optType; + } + + public void setOptLength(short len) { + this.optLength = len; + } + + public short getOptLength() { + return this.optLength; + } + + public void setValue(ByteBuffer bb) throws DeserializationException { + this.optValue = new byte[this.optLength]; + bb.get(this.optValue, 0, this.optLength); + } + + public byte[] getValue() { + return this.optValue; + } + + public static PIMHelloOption deserialize(ByteBuffer bb) throws DeserializationException { + checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), 4); + + PIMHelloOption opt = new PIMHelloOption(); + opt.setOptType(bb.getShort()); + opt.setOptLength(bb.getShort()); + + checkBufferLength(bb.limit(), bb.position(), opt.getOptLength()); + opt.setValue(bb); + + return opt; + } + + public byte [] serialize() { + int len = 4 + this.optLength; + ByteBuffer bb = ByteBuffer.allocate(len); + bb.putShort(this.optType); + bb.putShort(this.optLength); + bb.put(this.optValue); + return bb.array(); + } + + public String toString() { + return MessageFormat.format("Type: {0}, len: {1} value: {2}", this.optType, this.optLength, + (this.optValue == null) ? "null" : this.optValue.toString()); + } + +} diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMJoinPrune.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMJoinPrune.java new file mode 100644 index 00000000..9653115b --- /dev/null +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMJoinPrune.java @@ -0,0 +1,271 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onlab.packet.pim; + +import org.onlab.packet.BasePacket; +import org.onlab.packet.Deserializer; +import org.onlab.packet.IPacket; +import org.onlab.packet.IpPrefix; + +import java.nio.ByteBuffer; +import java.util.HashMap; + +import static org.onlab.packet.PacketUtils.checkInput; + +public class PIMJoinPrune extends BasePacket { + + private PIMAddrUnicast upstreamAddr = new PIMAddrUnicast(); + private short holdTime = (short) 0xffff; + + private class JoinPruneGroup { + protected IpPrefix group; + protected HashMap joins = new HashMap<>(); + protected HashMap prunes = new HashMap<>(); + + public JoinPruneGroup(IpPrefix grp) { + group = grp; + } + } + private HashMap joinPrunes = new HashMap<>(); + + /** + * Get the J/P hold time. + * + * @return specified in seconds. + */ + public short getHoldTime() { + return holdTime; + } + + /** + * Set the J/P holdtime in seconds. + * + * @param holdTime return the holdtime. + */ + public void setHoldTime(short holdTime) { + this.holdTime = holdTime; + } + + /** + * Get the upstreamAddr for this J/P request. + * + * @return the upstream address. + */ + public PIMAddrUnicast getUpstreamAddr() { + return upstreamAddr; + } + + /** + * Set the upstream address of this PIM J/P request. + * + * @param upstr the PIM Upstream unicast address + */ + public void setUpstreamAddr(PIMAddrUnicast upstr) { + this.upstreamAddr = upstr; + } + + /** + * Add the specified s,g to join field. + * + * @param saddr the source address of the route + * @param gaddr the group address of the route + * @param join true for a join, false for a prune. + */ + public void addJoinPrune(String saddr, String gaddr, boolean join) { + IpPrefix gpfx = IpPrefix.valueOf(gaddr); + IpPrefix spfx = IpPrefix.valueOf(saddr); + addJoinPrune(spfx, gpfx, join); + } + + /** + * Add the specified S, G to the join field. + * + * @param spfx the source prefix of the route + * @param gpfx the group prefix of the route + * @param join true for join, false for prune + */ + public void addJoinPrune(IpPrefix spfx, IpPrefix gpfx, boolean join) { + JoinPruneGroup jpg = joinPrunes.get(gpfx); + if (jpg == null) { + jpg = new JoinPruneGroup(gpfx); + joinPrunes.put(gpfx, jpg); + } + + HashMap members = (join) ? jpg.joins : jpg.prunes; + if (members.get(spfx) == null) { + members.put(spfx, spfx); + } + } + + /** + * Add a join given strings represending the source and group addresses. + * + * @param saddr source address + * @param gaddr group address + */ + public void addJoin(String saddr, String gaddr) { + this.addJoinPrune(saddr, gaddr, true); + } + + /** + * Add a prune given strings represending the source and group addresses. + * + * @param saddr source address + * @param gaddr group address + */ + public void addPrune(String saddr, String gaddr) { + this.addJoinPrune(saddr, gaddr, false); + } + + /** + * Sets all payloads parent packet if applicable, then serializes this + * packet and all payloads. + * + * @return a byte[] containing this packet and payloads + */ + @Override + public byte[] serialize() { + + byte[] data = new byte[8096]; // Come up with something better + ByteBuffer bb = ByteBuffer.wrap(data); + + bb.put(upstreamAddr.serialize()); + bb.put((byte) 0); // reserved + + int ngrps = joinPrunes.size(); + bb.put((byte) ngrps); + bb.putShort(this.holdTime); + + // Walk the group list and input all groups + for (JoinPruneGroup jpg : joinPrunes.values()) { + PIMAddrGroup grp = new PIMAddrGroup(jpg.group); + bb.put(grp.serialize()); + + // put the number of joins and prunes + bb.putShort((short) jpg.joins.size()); + bb.putShort((short) jpg.prunes.size()); + + // Set all of the joins + for (IpPrefix spfx : jpg.joins.values()) { + PIMAddrSource src = new PIMAddrSource(spfx); + bb.put(src.serialize()); + } + + // Set all of the prunes + for (IpPrefix spfx : jpg.prunes.values()) { + PIMAddrSource src = new PIMAddrSource(spfx); + bb.put(src.serialize()); + } + } + + int len = bb.position(); + byte[] data2 = new byte[len]; + bb = ByteBuffer.wrap(data2, 0, len); + bb.put(data, 0, len); + return data2; + } + + // TODO: I suppose I really need to implement this? + @Override + public IPacket deserialize(final byte[] data, final int offset, + final int length) { + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); + return this; + } + + /** + * Return the J/P deserializer function. + * + * @return a function that will deserialize a J/P message. + */ + public static Deserializer deserializer() { + return (data, offset, length) -> { + + /* + * Delay buffer checks until we read enough of the packet to know how + * much data we will require. Each encoded address deserializer function + * will ensure there is enough data for that address. + */ + PIMJoinPrune jp = new PIMJoinPrune(); + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); + + // We must get a PIM encoded unicast address + PIMAddrUnicast upstream = new PIMAddrUnicast(); + upstream.deserialize(bb); + jp.setUpstreamAddr(upstream); + + // Use this boolean to determine the buffer space we need according to address sizes + boolean ipv4 = upstream.getAddr().isIp4(); + + // We need at minimum 4 bytes for reserved(1), ngroups(1) & holdtime(2) + checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), 4); + + // get and skip the reserved byte + bb.get(); + + // Get the number of groups. + int ngroups = bb.get(); + + // Save the holdtime. + jp.setHoldTime(bb.getShort()); + + + for (int i = 0; i < ngroups; i++) { + PIMAddrGroup grp = new PIMAddrGroup(); + + /* + * grp.deserialize will ensure the buffer has enough data to read the group address. + */ + grp.deserialize(bb); + + checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), 4); + int njoins = bb.getShort(); + int nprunes = bb.getShort(); + + /* + * Now we'll verify we have enough buffer to read the next + * group of join and prune addresses for this group. + */ + int required = (njoins + nprunes) * + (ipv4 ? PIMAddrSource.ENC_SOURCE_IPV4_BYTE_LENGTH : PIMAddrSource.ENC_SOURCE_IPV6_BYTE_LENGTH); + checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), required); + + // Now iterate through the joins for this group + for (; njoins > 0; njoins--) { + + PIMAddrSource src = new PIMAddrSource(); + src.deserialize(bb); + + jp.addJoinPrune( + src.getAddr().toIpPrefix(), + grp.getAddr().toIpPrefix(), true); + } + + // Now iterate through the prunes for this group + for (; nprunes > 0; nprunes--) { + + PIMAddrSource src = new PIMAddrSource(); + src.deserialize(bb); + jp.addJoinPrune( + src.getAddr().toIpPrefix(), + grp.getAddr().toIpPrefix(), false); + } + } + + return jp; + }; + } +} diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/package-info.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/package-info.java new file mode 100755 index 00000000..88a1ad5d --- /dev/null +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Utilities for managing PIM packets. + */ +package org.onlab.packet.pim; + diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/PIMTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/PIMTest.java new file mode 100644 index 00000000..7fba3cd7 --- /dev/null +++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/PIMTest.java @@ -0,0 +1,132 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onlab.packet; + +import org.junit.Before; +import org.junit.Test; +import org.onlab.packet.pim.PIMAddrUnicast; +import org.onlab.packet.pim.PIMHello; +import org.onlab.packet.pim.PIMJoinPrune; + +import static junit.framework.Assert.assertTrue; + +public final class PIMTest { + + public static final String SADDR = "10.2.1.2"; + public static final String PIMADDR = "224.0.0.13"; + public static final String PIMUADDR = "10.23.3.5"; + + public static final String SADDR1 = "10.1.1.1/32"; + public static final String SADDR2 = "10.1.2.1/32"; + public static final String GADDR1 = "232.1.1.1/32"; + public static final String GADDR2 = "232.1.2.1/32"; + + public static final String CPSTR1 = "of:deadbeefball/8"; + public static final String CPSTR2 = "of:deadbeefcafe/3"; + public static final String CPSTR3 = "of:2badcafef00d/3"; + + private Deserializer deserializer; + + private PIM pimHello; + private PIMHello hello; + + private PIM pimJoinPrune; + private PIMJoinPrune joinPrune; + + /** + * Create PIM Hello and Join/Prune packets to be used in testing. + * + * @throws Exception if packet creation fails + */ + @Before + public void setUp() throws Exception { + + // Create a PIM Hello + pimHello = new PIM(); + pimHello.setVersion((byte) 2); + pimHello.setPIMType((byte) PIM.TYPE_HELLO); + pimHello.setChecksum((short) 0); + + hello = new PIMHello(); + hello.createDefaultOptions(); + pimHello.setPayload(hello); + hello.setParent(pimHello); + + // Create PIM Join Prune + pimJoinPrune = new PIM(); + pimJoinPrune.setVersion((byte) 2); + pimJoinPrune.setPIMType((byte) PIM.TYPE_JOIN_PRUNE_REQUEST); + pimJoinPrune.setChecksum((short) 0); + + joinPrune = new PIMJoinPrune(); + joinPrune.setUpstreamAddr(new PIMAddrUnicast(SADDR)); + joinPrune.addJoin(GADDR1, SADDR1); + joinPrune.addJoin(GADDR2, SADDR2); + joinPrune.addPrune(GADDR1, SADDR2); + joinPrune.addPrune(GADDR2, SADDR1); + + pimJoinPrune.setPayload(joinPrune); + joinPrune.setParent(pimJoinPrune); + + deserializer = PIM.deserializer(); + } + + /** + * Make sure our deserializer throws an exception if we recieve bad input. + * + * @throws Exception if we are given bad input. + */ + @Test + public void testDeserializeBadInput() throws Exception { + PacketTestUtils.testDeserializeBadInput(deserializer); + } + + /** + * Verify we throw an exception if we receive a truncated Join/Prune message. + * + * @throws Exception if we receive a truncated Join/Prune message. + */ + @Test + public void testDeserializeTruncated() throws Exception { + byte [] bits = pimJoinPrune.serialize(); + PacketTestUtils.testDeserializeTruncated(deserializer, bits); + } + + /** + * Verify that we correctly deserialize hello messages. + * + * @throws Exception if our input is bad or truncated. + */ + @Test + public void testDeserializeHello() throws Exception { + byte [] data = pimHello.serialize(); + PIM pim = deserializer.deserialize(data, 0, data.length); + assertTrue(pim.equals(pimHello)); + } + + /** + * Verify that we correctly deserialize Join/Prune messages. + * + * @throws Exception if our input is bad or truncated. + */ + @Test + public void testDeserializeJoinPrune() throws Exception { + byte [] data = pimJoinPrune.serialize(); + PIM pim = deserializer.deserialize(data, 0, data.length); + assertTrue(pim.equals(pimJoinPrune)); + } + +} \ No newline at end of file diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/HexStringTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/HexStringTest.java index 27652123..e04e29a2 100644 --- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/HexStringTest.java +++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/HexStringTest.java @@ -21,12 +21,14 @@ import com.esotericsoftware.minlog.Log; import junit.framework.TestCase; +import static org.junit.Assert.fail; + /** * Test of the Hexstring. * */ -public class HexStringTest extends TestCase { +public class HexStringTest { @Test public void testMarshalling() throws Exception { diff --git a/framework/src/onos/utils/netty/pom.xml b/framework/src/onos/utils/netty/pom.xml index fa320d52..5ce4838b 100644 --- a/framework/src/onos/utils/netty/pom.xml +++ b/framework/src/onos/utils/netty/pom.xml @@ -22,7 +22,7 @@ org.onosproject onlab-utils - 1.3.0-SNAPSHOT + 1.4.0-SNAPSHOT ../pom.xml diff --git a/framework/src/onos/utils/nio/pom.xml b/framework/src/onos/utils/nio/pom.xml index b9e4d447..83957669 100644 --- a/framework/src/onos/utils/nio/pom.xml +++ b/framework/src/onos/utils/nio/pom.xml @@ -22,7 +22,7 @@ org.onosproject onlab-utils - 1.3.0-SNAPSHOT + 1.4.0-SNAPSHOT ../pom.xml diff --git a/framework/src/onos/utils/osgi/pom.xml b/framework/src/onos/utils/osgi/pom.xml index 7be6c69d..cf79312d 100644 --- a/framework/src/onos/utils/osgi/pom.xml +++ b/framework/src/onos/utils/osgi/pom.xml @@ -22,7 +22,7 @@ org.onosproject onlab-utils - 1.3.0-SNAPSHOT + 1.4.0-SNAPSHOT ../pom.xml diff --git a/framework/src/onos/utils/pom.xml b/framework/src/onos/utils/pom.xml index 2adbba70..c2fa5dc6 100644 --- a/framework/src/onos/utils/pom.xml +++ b/framework/src/onos/utils/pom.xml @@ -22,7 +22,7 @@ org.onosproject onos - 1.3.0-SNAPSHOT + 1.4.0-SNAPSHOT ../pom.xml diff --git a/framework/src/onos/utils/rest/pom.xml b/framework/src/onos/utils/rest/pom.xml index ce2bd845..c9a7df75 100644 --- a/framework/src/onos/utils/rest/pom.xml +++ b/framework/src/onos/utils/rest/pom.xml @@ -22,7 +22,7 @@ org.onosproject onlab-utils - 1.3.0-SNAPSHOT + 1.4.0-SNAPSHOT ../pom.xml diff --git a/framework/src/onos/utils/stc/bin/stc b/framework/src/onos/utils/stc/bin/stc index 23affc4a..241822c5 100755 --- a/framework/src/onos/utils/stc/bin/stc +++ b/framework/src/onos/utils/stc/bin/stc @@ -5,7 +5,7 @@ STC_ROOT=${STC_ROOT:-$(dirname $0)/..} cd $STC_ROOT -VER=1.3.0-SNAPSHOT +VER=1.4.0-SNAPSHOT PATH=$PWD/bin:$PATH diff --git a/framework/src/onos/utils/stc/pom.xml b/framework/src/onos/utils/stc/pom.xml index a3f96430..a71dcfe3 100644 --- a/framework/src/onos/utils/stc/pom.xml +++ b/framework/src/onos/utils/stc/pom.xml @@ -22,7 +22,7 @@ org.onosproject onlab-utils - 1.3.0-SNAPSHOT + 1.4.0-SNAPSHOT ../pom.xml diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Coordinator.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Coordinator.java index 8e3aad5b..ef1c31f3 100644 --- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Coordinator.java +++ b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Coordinator.java @@ -108,6 +108,15 @@ public class Coordinator { // FIXME: implement this } + /** + * Returns number of milliseconds it took to execute. + * + * @return number of millis elapsed during the run + */ + public long duration() { + return store.endTime() - store.startTime(); + } + /** * Returns a list of steps that match the specified list of patterns. * diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Main.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Main.java index 09b89456..bc10ec7a 100644 --- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Main.java +++ b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Main.java @@ -44,11 +44,12 @@ public final class Main { private static final String GREEN = "\u001B[32;1m"; private static final String BLUE = "\u001B[36m"; - private static final String SUCCESS_SUMMARY = "%sPassed! %d steps succeeded%s"; + private static final String SUCCESS_SUMMARY = + "%s %sPassed! %d steps succeeded%s"; private static final String MIXED_SUMMARY = "%s%d steps succeeded; %s%d steps failed; %s%d steps skipped%s"; - private static final String FAILURE_SUMMARY = "%sFailed! " + MIXED_SUMMARY; - private static final String ABORTED_SUMMARY = "%sAborted! " + MIXED_SUMMARY; + private static final String FAILURE_SUMMARY = "%s %sFailed! " + MIXED_SUMMARY; + private static final String ABORTED_SUMMARY = "%s %sAborted! " + MIXED_SUMMARY; private boolean isReported = false; @@ -180,6 +181,7 @@ public final class Main { private void processList() { coordinator.getRecords() .forEach(event -> logStatus(event.time(), event.name(), event.status(), event.command())); + printSummary(0, false); System.exit(0); } @@ -201,14 +203,15 @@ public final class Main { if (!isReported) { isReported = true; Set steps = coordinator.getSteps(); + String duration = formatDuration((int) (coordinator.duration() / 1_000)); int count = steps.size(); if (exitCode == 0) { - print(SUCCESS_SUMMARY, color(SUCCEEDED), count, color(null)); + print(SUCCESS_SUMMARY, duration, color(SUCCEEDED), count, color(null)); } else { long success = steps.stream().filter(s -> coordinator.getStatus(s) == SUCCEEDED).count(); long failed = steps.stream().filter(s -> coordinator.getStatus(s) == FAILED).count(); long skipped = steps.stream().filter(s -> coordinator.getStatus(s) == SKIPPED).count(); - print(isAborted ? ABORTED_SUMMARY : FAILURE_SUMMARY, + print(isAborted ? ABORTED_SUMMARY : FAILURE_SUMMARY, duration, color(FAILED), color(SUCCEEDED), success, color(FAILED), failed, color(SKIPPED), skipped, color(null)); } @@ -281,6 +284,17 @@ public final class Main { } } + // Formats time duration + private static String formatDuration(int totalSeconds) { + int seconds = totalSeconds % 60; + int totalMinutes = totalSeconds / 60; + int minutes = totalMinutes % 60; + int hours = totalMinutes / 60; + return hours > 0 ? + String.format("%d:%02d:%02d", hours, minutes, seconds) : + String.format("%d:%02d", minutes, seconds); + } + // Shutdown hook to report status even when aborted. private class ShutdownHook extends Thread { @Override diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/ScenarioStore.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/ScenarioStore.java index d37222b1..7313462e 100644 --- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/ScenarioStore.java +++ b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/ScenarioStore.java @@ -43,6 +43,9 @@ class ScenarioStore { private final List events = Lists.newArrayList(); private final Map statusMap = Maps.newConcurrentMap(); + private long startTime = Long.MAX_VALUE; + private long endTime = Long.MIN_VALUE; + /** * Creates a new scenario store for the specified process flow. * @@ -69,6 +72,8 @@ class ScenarioStore { PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile); cfg.clear(); cfg.save(); + startTime = Long.MAX_VALUE; + endTime = Long.MIN_VALUE; } catch (ConfigurationException e) { print("Unable to store file %s", storeFile); } @@ -156,6 +161,8 @@ class ScenarioStore { private synchronized void add(StepEvent event) { events.add(event); statusMap.put(event.name(), event.status()); + startTime = Math.min(startTime, event.time()); + endTime = Math.max(endTime, event.time()); } /** @@ -198,4 +205,22 @@ class ScenarioStore { } } + /** + * Returns the scenario run start time. + * + * @return start time in mills since start of epoch + */ + public long startTime() { + return startTime; + } + + /** + * Returns the scenario run end time or current time if the scenario + * is still running. + * + * @return end time (or current time) in mills since start of epoch + */ + public long endTime() { + return endTime > 0 ? endTime : System.currentTimeMillis(); + } } diff --git a/framework/src/onos/utils/thirdparty/pom.xml b/framework/src/onos/utils/thirdparty/pom.xml index f5c81677..bb5e3e06 100644 --- a/framework/src/onos/utils/thirdparty/pom.xml +++ b/framework/src/onos/utils/thirdparty/pom.xml @@ -22,7 +22,7 @@ org.onosproject onlab-utils - 1.3.0-SNAPSHOT + 1.4.0-SNAPSHOT ../pom.xml -- cgit 1.2.3-korg