mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
api/utils/ui: List protocol numbers and icmp types (#8293)
This PR contains the following changes * adds a new API to list network procotols and details/types/codes, etc * get network protocols on UI and add dropdowns for procotol numbers and icmp types/codes * validate icmp types/codes when add network ACL
This commit is contained in:
parent
7dffbc6e47
commit
af8a582055
@ -321,6 +321,7 @@ public class ApiConstants {
|
||||
public static final String IS_DEFAULT_USE = "defaultuse";
|
||||
public static final String OLD_FORMAT = "oldformat";
|
||||
public static final String OP = "op";
|
||||
public static final String OPTION = "option";
|
||||
public static final String OPTIONS = "options";
|
||||
public static final String OS_CATEGORY_ID = "oscategoryid";
|
||||
public static final String OS_CATEGORY_NAME = "oscategoryname";
|
||||
|
||||
@ -0,0 +1,109 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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.apache.cloudstack.api.command.user.network;
|
||||
|
||||
import com.cloud.utils.net.NetworkProtocols;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkProtocolResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = "listNetworkProtocols", description = "Lists details of network protocols", responseObject = NetworkProtocolResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
authorized = { RoleType.Admin, RoleType.DomainAdmin, RoleType.ResourceAdmin, RoleType.User}, since = "4.19.0")
|
||||
public class ListNetworkProtocolsCmd extends BaseCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(ListNetworkProtocolsCmd.class.getName());
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.OPTION, type = CommandType.STRING, required = true,
|
||||
description = "The option of network protocols. Supported values are: protocolnumber, icmptype.")
|
||||
private String option;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public String getOption() {
|
||||
return option;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ListResponse<NetworkProtocolResponse> response = new ListResponse<>();
|
||||
List<NetworkProtocolResponse> networkProtocolResponses = new ArrayList<>();
|
||||
|
||||
NetworkProtocols.Option option = NetworkProtocols.Option.getOption(getOption());
|
||||
switch (option) {
|
||||
case ProtocolNumber:
|
||||
updateResponseWithProtocolNumbers(networkProtocolResponses);
|
||||
break;
|
||||
case IcmpType:
|
||||
updateResponseWithIcmpTypes(networkProtocolResponses);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
response.setResponses(networkProtocolResponses);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
private void updateResponseWithProtocolNumbers(List<NetworkProtocolResponse> responses) {
|
||||
for (NetworkProtocols.ProtocolNumber protocolNumber : NetworkProtocols.ProtocolNumbers) {
|
||||
NetworkProtocolResponse networkProtocolResponse = new NetworkProtocolResponse(protocolNumber.getNumber(),
|
||||
protocolNumber.getKeyword(), protocolNumber.getProtocol());
|
||||
networkProtocolResponse.setObjectName("networkprotocol");
|
||||
responses.add(networkProtocolResponse);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateResponseWithIcmpTypes(List<NetworkProtocolResponse> responses) {
|
||||
for (NetworkProtocols.IcmpType icmpType : NetworkProtocols.IcmpTypes) {
|
||||
NetworkProtocolResponse networkProtocolResponse = new NetworkProtocolResponse(icmpType.getType(),
|
||||
null, icmpType.getDescription());
|
||||
for (NetworkProtocols.IcmpCode code : icmpType.getIcmpCodes()) {
|
||||
networkProtocolResponse.addDetail(String.valueOf(code.getCode()), code.getDescription());
|
||||
}
|
||||
networkProtocolResponse.setObjectName("networkprotocol");
|
||||
responses.add(networkProtocolResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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.apache.cloudstack.api.response;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class NetworkProtocolResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.INDEX)
|
||||
@Param(description = "the index (ID, Value, Code, Type, Option, etc) of the protocol parameter")
|
||||
private Integer index;
|
||||
|
||||
@SerializedName(ApiConstants.NAME)
|
||||
@Param(description = "the name of the protocol parameter")
|
||||
private String name;
|
||||
|
||||
@SerializedName(ApiConstants.DESCRIPTION)
|
||||
@Param(description = "the description of the protocol parameter")
|
||||
private String description;
|
||||
|
||||
@SerializedName(ApiConstants.DETAILS)
|
||||
@Param(description = "the details of the protocol parameter")
|
||||
private Map details;
|
||||
|
||||
public NetworkProtocolResponse(Integer index, String name, String description) {
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(Integer index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Map getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
public void setDetails(Map details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public void addDetail(String key, String value) {
|
||||
if (this.details == null) {
|
||||
this.details = new LinkedHashMap();
|
||||
}
|
||||
this.details.put(key, value);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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.apache.cloudstack.api.command.user.network;
|
||||
|
||||
import com.cloud.utils.net.NetworkProtocols;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkProtocolResponse;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ListNetworkProtocolsCmdTest {
|
||||
|
||||
@Test
|
||||
public void testListNetworkProtocolNumbers() {
|
||||
ListNetworkProtocolsCmd cmd = new ListNetworkProtocolsCmd();
|
||||
String option = NetworkProtocols.Option.ProtocolNumber.toString();
|
||||
ReflectionTestUtils.setField(cmd, "option", option);
|
||||
Assert.assertEquals(cmd.getOption(), option);
|
||||
|
||||
try {
|
||||
cmd.execute();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Object response = cmd.getResponseObject();
|
||||
Assert.assertTrue(response instanceof ListResponse);
|
||||
ListResponse listResponse = (ListResponse) response;
|
||||
Assert.assertEquals(BaseCmd.getResponseNameByClass(cmd.getClass()), listResponse.getResponseName());
|
||||
Assert.assertNotNull(listResponse.getResponses());
|
||||
Assert.assertNotEquals(0, listResponse.getResponses().size());
|
||||
Object firstResponse = listResponse.getResponses().get(0);
|
||||
Assert.assertTrue(firstResponse instanceof NetworkProtocolResponse);
|
||||
Assert.assertEquals("networkprotocol", ((NetworkProtocolResponse) firstResponse).getObjectName());
|
||||
Assert.assertEquals(Integer.valueOf(0), ((NetworkProtocolResponse) firstResponse).getIndex());
|
||||
Assert.assertEquals("HOPOPT", ((NetworkProtocolResponse) firstResponse).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListIcmpTypes() {
|
||||
ListNetworkProtocolsCmd cmd = new ListNetworkProtocolsCmd();
|
||||
String option = NetworkProtocols.Option.IcmpType.toString();
|
||||
ReflectionTestUtils.setField(cmd, "option", option);
|
||||
Assert.assertEquals(cmd.getOption(), option);
|
||||
|
||||
try {
|
||||
cmd.execute();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Object response = cmd.getResponseObject();
|
||||
Assert.assertTrue(response instanceof ListResponse);
|
||||
ListResponse listResponse = (ListResponse) response;
|
||||
Assert.assertEquals(BaseCmd.getResponseNameByClass(cmd.getClass()), listResponse.getResponseName());
|
||||
Assert.assertNotNull(listResponse.getResponses());
|
||||
Assert.assertNotEquals(0, listResponse.getResponses().size());
|
||||
Object firstResponse = listResponse.getResponses().get(0);
|
||||
Assert.assertTrue(firstResponse instanceof NetworkProtocolResponse);
|
||||
Assert.assertEquals("networkprotocol", ((NetworkProtocolResponse) firstResponse).getObjectName());
|
||||
Assert.assertEquals(Integer.valueOf(0), ((NetworkProtocolResponse) firstResponse).getIndex());
|
||||
Assert.assertNotNull(((NetworkProtocolResponse) firstResponse).getDetails());
|
||||
System.out.println(((NetworkProtocolResponse) firstResponse).getDetails());
|
||||
Assert.assertEquals("Echo reply", ((NetworkProtocolResponse) firstResponse).getDetails().get("0"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testListInvalidOption() {
|
||||
ListNetworkProtocolsCmd cmd = new ListNetworkProtocolsCmd();
|
||||
String option = "invalid-option";
|
||||
ReflectionTestUtils.setField(cmd, "option", option);
|
||||
Assert.assertEquals(cmd.getOption(), option);
|
||||
|
||||
cmd.execute();
|
||||
}
|
||||
}
|
||||
@ -658,10 +658,14 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro
|
||||
if(StringUtils.isNumeric(protocol)){
|
||||
int protoNumber = Integer.parseInt(protocol);
|
||||
// Deal with ICMP(protocol number 1) specially because it need to be paired with icmp type and code
|
||||
if (protoNumber == 1) {
|
||||
protocol = "icmp";
|
||||
icmpCode = -1;
|
||||
icmpType = -1;
|
||||
if (protoNumber == NetUtils.ICMP_PROTO_NUMBER) {
|
||||
protocol = NetUtils.ICMP_PROTO;
|
||||
if (icmpCode == null) {
|
||||
icmpCode = -1;
|
||||
}
|
||||
if (icmpType == null) {
|
||||
icmpType = -1;
|
||||
}
|
||||
} else if(protoNumber < 0 || protoNumber > 255){
|
||||
throw new InvalidParameterValueException("Invalid protocol number: " + protoNumber);
|
||||
}
|
||||
@ -673,18 +677,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro
|
||||
}
|
||||
}
|
||||
if (protocol.equals(NetUtils.ICMP_PROTO)) {
|
||||
if ((icmpType == null) || (icmpCode == null)) {
|
||||
throw new InvalidParameterValueException("Invalid ICMP type/code specified, icmpType = " + icmpType + ", icmpCode = " + icmpCode);
|
||||
}
|
||||
if (icmpType == -1 && icmpCode != -1) {
|
||||
throw new InvalidParameterValueException("Invalid icmp code");
|
||||
}
|
||||
if (icmpType != -1 && icmpCode == -1) {
|
||||
throw new InvalidParameterValueException("Invalid icmp code: need non-negative icmp code ");
|
||||
}
|
||||
if (icmpCode > 255 || icmpType > 255 || icmpCode < -1 || icmpType < -1) {
|
||||
throw new InvalidParameterValueException("Invalid icmp type/code ");
|
||||
}
|
||||
NetUtils.validateIcmpTypeAndCode(icmpType, icmpCode);
|
||||
startPortOrType = icmpType;
|
||||
endPortOrCode = icmpCode;
|
||||
} else if (protocol.equals(NetUtils.ALL_PROTO)) {
|
||||
@ -785,6 +778,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro
|
||||
SecurityGroupRuleVO securityGroupRule = _securityGroupRuleDao.findByProtoPortsAndAllowedGroupId(securityGroup.getId(), protocolFinal, startPortOrTypeFinal,
|
||||
endPortOrCodeFinal, ngVO.getId());
|
||||
if ((securityGroupRule != null) && (securityGroupRule.getRuleType() == ruleType)) {
|
||||
s_logger.warn("The rule already exists. id= " + securityGroupRule.getUuid());
|
||||
continue; // rule already exists.
|
||||
}
|
||||
securityGroupRule = new SecurityGroupRuleVO(ruleType, securityGroup.getId(), startPortOrTypeFinal, endPortOrCodeFinal, protocolFinal, ngVO.getId());
|
||||
|
||||
@ -583,7 +583,7 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
Integer icmpCode = networkACLItemVO.getIcmpCode();
|
||||
Integer icmpType = networkACLItemVO.getIcmpType();
|
||||
// icmp code and icmp type can't be passed in for any other protocol rather than icmp
|
||||
boolean isIcmpProtocol = protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO);
|
||||
boolean isIcmpProtocol = protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) || protocol.equalsIgnoreCase(String.valueOf(NetUtils.ICMP_PROTO_NUMBER));
|
||||
if (!isIcmpProtocol && (icmpCode != null || icmpType != null)) {
|
||||
throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only");
|
||||
}
|
||||
|
||||
@ -446,6 +446,7 @@ import org.apache.cloudstack.api.command.user.network.ListNetworkACLListsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworkProtocolsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.MoveNetworkAclItemCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RemoveNetworkPermissionsCmd;
|
||||
@ -3621,6 +3622,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
cmdList.add(DeleteNetworkCmd.class);
|
||||
cmdList.add(ListNetworkACLsCmd.class);
|
||||
cmdList.add(ListNetworkOfferingsCmd.class);
|
||||
cmdList.add(ListNetworkProtocolsCmd.class);
|
||||
cmdList.add(ListNetworksCmd.class);
|
||||
cmdList.add(RestartNetworkCmd.class);
|
||||
cmdList.add(UpdateNetworkCmd.class);
|
||||
|
||||
@ -622,8 +622,8 @@ public class NetworkACLServiceImplTest {
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void validateProtocolTestProtocolNotIcmpWithIcmpConfigurations() {
|
||||
Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(1);
|
||||
Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(1);
|
||||
Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(2);
|
||||
Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(3);
|
||||
|
||||
Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("tcp");
|
||||
networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
|
||||
@ -647,8 +647,8 @@ public class NetworkACLServiceImplTest {
|
||||
|
||||
@Test
|
||||
public void validateProtocolTestProtocolIcmpWithIcmpConfigurations() {
|
||||
Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(1);
|
||||
Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(1);
|
||||
Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(2);
|
||||
Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(3);
|
||||
|
||||
Mockito.when(networkAclItemVoMock.getSourcePortStart()).thenReturn(null);
|
||||
Mockito.when(networkAclItemVoMock.getSourcePortEnd()).thenReturn(null);
|
||||
|
||||
@ -64,19 +64,19 @@
|
||||
<div class="list__label">{{ $t('label.protocol') }}</div>
|
||||
<div>{{ element.protocol }}</div>
|
||||
</div>
|
||||
<div class="list__col" v-if="element.startport">
|
||||
<div class="list__col" v-if="element.startport !== undefined">
|
||||
<div class="list__label">{{ $t('label.startport') }}</div>
|
||||
<div>{{ element.startport }}</div>
|
||||
</div>
|
||||
<div class="list__col" v-if="element.endport">
|
||||
<div class="list__col" v-if="element.endport !== undefined">
|
||||
<div class="list__label">{{ $t('label.endport') }}</div>
|
||||
<div>{{ element.endport }}</div>
|
||||
</div>
|
||||
<div class="list__col" v-if="element.icmpcode">
|
||||
<div class="list__col" v-if="element.icmpcode !== undefined">
|
||||
<div class="list__label">{{ $t('label.icmpcode') }}</div>
|
||||
<div>{{ element.icmpcode }}</div>
|
||||
</div>
|
||||
<div class="list__col" v-if="element.icmptype">
|
||||
<div class="list__col" v-if="element.icmptype !== undefined">
|
||||
<div class="list__label">{{ $t('label.icmptype') }}</div>
|
||||
<div>{{ element.icmptype }}</div>
|
||||
</div>
|
||||
@ -208,19 +208,50 @@
|
||||
:label="$t('label.protocolnumber')"
|
||||
ref="protocolnumber"
|
||||
name="protocolnumber">
|
||||
<a-input v-model:value="form.protocolnumber" />
|
||||
<a-select
|
||||
v-model:value="form.protocolnumber"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt, optIndex) in protocolNumbers" :key="optIndex" :label="opt.name">
|
||||
{{ opt.index + ' - ' + opt.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<div v-if="form.protocol === 'icmp'">
|
||||
<div v-if="form.protocol === 'icmp' || (form.protocol === 'protocolnumber' && form.protocolnumber === 1)">
|
||||
<a-form-item :label="$t('label.icmptype')" ref="icmptype" name="icmptype">
|
||||
<a-input v-model:value="form.icmptype" :placeholder="$t('icmp.type.desc')" />
|
||||
<a-select
|
||||
v-model:value="form.icmptype"
|
||||
@change="val => { updateIcmpCodes(val) }"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt) in icmpTypes" :key="opt.index" :label="opt.description">
|
||||
{{ opt.index + ' - ' + opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.icmpcode')" ref="icmpcode" name="icmpcode">
|
||||
<a-input v-model:value="form.icmpcode" :placeholder="$t('icmp.code.desc')" />
|
||||
<a-select
|
||||
v-model:value="form.icmpcode"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt) in icmpCodes" :key="opt.code" :label="opt.description">
|
||||
{{ opt.code + ' - ' + opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</div>
|
||||
|
||||
<div v-show="['tcp', 'udp', 'protocolnumber'].includes(form.protocol)">
|
||||
<div v-show="['tcp', 'udp', 'protocolnumber'].includes(form.protocol) && !(form.protocol === 'protocolnumber' && form.protocolnumber === 1)">
|
||||
<a-form-item :label="$t('label.startport')" ref="startport" name="startport">
|
||||
<a-input-number style="width: 100%" v-model:value="form.startport" />
|
||||
</a-form-item>
|
||||
@ -285,6 +316,9 @@ export default {
|
||||
return {
|
||||
acls: [],
|
||||
fetchLoading: false,
|
||||
protocolNumbers: [],
|
||||
icmpTypes: [],
|
||||
icmpCodes: [],
|
||||
tags: [],
|
||||
selectedAcl: null,
|
||||
tagsModalVisible: false,
|
||||
@ -296,6 +330,7 @@ export default {
|
||||
},
|
||||
created () {
|
||||
this.initForm()
|
||||
this.fetchNetworkProtocols()
|
||||
this.fetchData()
|
||||
},
|
||||
watch: {
|
||||
@ -310,6 +345,8 @@ export default {
|
||||
this.formRef = ref()
|
||||
this.form = reactive({})
|
||||
this.rules = reactive({})
|
||||
this.form.icmptype = -1
|
||||
this.form.icmpcode = -1
|
||||
},
|
||||
csv ({ data = null, columnDelimiter = ',', lineDelimiter = '\n' }) {
|
||||
let result = null
|
||||
@ -351,6 +388,35 @@ export default {
|
||||
|
||||
return result
|
||||
},
|
||||
fetchNetworkProtocols () {
|
||||
api('listNetworkProtocols', {
|
||||
option: 'protocolnumber'
|
||||
}).then(json => {
|
||||
this.protocolNumbers = json.listnetworkprotocolsresponse?.networkprotocol || []
|
||||
})
|
||||
api('listNetworkProtocols', {
|
||||
option: 'icmptype'
|
||||
}).then(json => {
|
||||
this.icmpTypes.push({ index: -1, description: this.$t('label.all') })
|
||||
const results = json.listnetworkprotocolsresponse?.networkprotocol || []
|
||||
for (const result of results) {
|
||||
this.icmpTypes.push(result)
|
||||
}
|
||||
})
|
||||
this.icmpCodes.push({ code: -1, description: this.$t('label.all') })
|
||||
},
|
||||
updateIcmpCodes (val) {
|
||||
this.form.icmpcode = -1
|
||||
this.icmpCodes = []
|
||||
this.icmpCodes.push({ code: -1, description: this.$t('label.all') })
|
||||
const icmpType = this.icmpTypes.find(icmpType => icmpType.index === val)
|
||||
if (icmpType && icmpType.details) {
|
||||
const icmpTypeDetails = icmpType.details
|
||||
for (const k of Object.keys(icmpTypeDetails)) {
|
||||
this.icmpCodes.push({ code: parseInt(k), description: icmpTypeDetails[k] })
|
||||
}
|
||||
}
|
||||
},
|
||||
fetchData () {
|
||||
this.fetchLoading = true
|
||||
api('listNetworkACLs', { aclid: this.resource.id }).then(json => {
|
||||
@ -476,8 +542,15 @@ export default {
|
||||
self.form.cidrlist = acl.cidrlist
|
||||
self.form.action = acl.action
|
||||
self.form.protocol = acl.protocol
|
||||
if (!['tcp', 'udp', 'icmp', 'all'].includes(acl.protocol)) {
|
||||
self.form.protocol = 'protocolnumber'
|
||||
self.form.protocolnumber = parseInt(acl.protocol)
|
||||
}
|
||||
self.form.startport = acl.startport
|
||||
self.form.endport = acl.endport
|
||||
self.form.icmptype = parseInt(acl.icmptype)
|
||||
this.updateIcmpCodes(self.form.icmptype)
|
||||
self.form.icmpcode = acl.icmpcode
|
||||
self.form.traffictype = acl.traffictype
|
||||
self.form.reason = acl.reason
|
||||
}, 200)
|
||||
@ -497,9 +570,9 @@ export default {
|
||||
data.endport = values.endport || ''
|
||||
}
|
||||
|
||||
if (values.protocol === 'icmp') {
|
||||
data.icmptype = values.icmptype || -1
|
||||
data.icmpcode = values.icmpcode || -1
|
||||
if (values.protocol === 'icmp' || (values.protocol === 'protocolnumber' && values.protocolnumber === 1)) {
|
||||
data.icmptype = values.icmptype
|
||||
data.icmpcode = values.icmpcode
|
||||
}
|
||||
|
||||
if (values.protocol === 'protocolnumber') {
|
||||
|
||||
@ -63,11 +63,32 @@
|
||||
</div>
|
||||
<div v-show="newRule.protocol === 'icmp'" class="form__item">
|
||||
<div class="form__label">{{ $t('label.icmptype') }}</div>
|
||||
<a-input v-model:value="newRule.icmptype"></a-input>
|
||||
<a-select
|
||||
v-model:value="newRule.icmptype"
|
||||
@change="val => { updateIcmpCodes(val) }"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt) in icmpTypes" :key="opt.index" :label="opt.description">
|
||||
{{ opt.index + ' - ' + opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div v-show="newRule.protocol === 'icmp'" class="form__item">
|
||||
<div class="form__label">{{ $t('label.icmpcode') }}</div>
|
||||
<a-input v-model:value="newRule.icmpcode"></a-input>
|
||||
<a-select
|
||||
v-model:value="newRule.icmpcode"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt) in icmpCodes" :key="opt.code" :label="opt.description">
|
||||
{{ opt.code + ' - ' + opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div class="form__item">
|
||||
<a-button ref="submit" :disabled="!('createEgressFirewallRule' in $store.getters.apis)" type="primary" @click="addRule">
|
||||
@ -102,10 +123,10 @@
|
||||
{{ getCapitalise(record.protocol) }}
|
||||
</template>
|
||||
<template v-if="column.key === 'startport'">
|
||||
{{ record.icmptype || record.startport >= 0 ? record.icmptype || record.startport : 'All' }}
|
||||
{{ record.icmptype >= 0 ? String(record.icmptype): record.startport >= 0 ? String(record.startport): 'All' }}
|
||||
</template>
|
||||
<template v-if="column.key === 'endport'">
|
||||
{{ record.icmpcode || record.endport >= 0 ? record.icmpcode || record.endport : 'All' }}
|
||||
{{ record.icmpcode >= 0 ? String(record.icmpcode): record.endport >= 0 ? String(record.endport): 'All' }}
|
||||
</template>
|
||||
<template v-if="column.key === 'actions'">
|
||||
<tooltip-button
|
||||
@ -196,6 +217,9 @@ export default {
|
||||
startport: null,
|
||||
endport: null
|
||||
},
|
||||
protocolNumbers: [],
|
||||
icmpTypes: [],
|
||||
icmpCodes: [],
|
||||
totalCount: 0,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
@ -233,6 +257,7 @@ export default {
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.fetchNetworkProtocols()
|
||||
this.fetchData()
|
||||
},
|
||||
watch: {
|
||||
@ -248,6 +273,34 @@ export default {
|
||||
},
|
||||
inject: ['parentFetchData'],
|
||||
methods: {
|
||||
fetchNetworkProtocols () {
|
||||
api('listNetworkProtocols', {
|
||||
option: 'protocolnumber'
|
||||
}).then(json => {
|
||||
this.protocolNumbers = json.listnetworkprotocolsresponse?.networkprotocol || []
|
||||
})
|
||||
api('listNetworkProtocols', {
|
||||
option: 'icmptype'
|
||||
}).then(json => {
|
||||
this.icmpTypes.push({ index: -1, description: this.$t('label.all') })
|
||||
const results = json.listnetworkprotocolsresponse?.networkprotocol || []
|
||||
for (const result of results) {
|
||||
this.icmpTypes.push(result)
|
||||
}
|
||||
})
|
||||
},
|
||||
updateIcmpCodes (val) {
|
||||
this.newRule.icmpcode = -1
|
||||
this.icmpCodes = []
|
||||
this.icmpCodes.push({ code: -1, description: this.$t('label.all') })
|
||||
const icmpType = this.icmpTypes.find(icmpType => icmpType.index === val)
|
||||
if (icmpType && icmpType.details) {
|
||||
const icmpTypeDetails = icmpType.details
|
||||
for (const k of Object.keys(icmpTypeDetails)) {
|
||||
this.icmpCodes.push({ code: parseInt(k), description: icmpTypeDetails[k] })
|
||||
}
|
||||
}
|
||||
},
|
||||
fetchData () {
|
||||
this.loading = true
|
||||
api('listEgressFirewallRules', {
|
||||
|
||||
@ -49,11 +49,32 @@
|
||||
</div>
|
||||
<div v-show="newRule.protocol === 'icmp'" class="form__item">
|
||||
<div class="form__label">{{ $t('label.icmptype') }}</div>
|
||||
<a-input v-model:value="newRule.icmptype"></a-input>
|
||||
<a-select
|
||||
v-model:value="newRule.icmptype"
|
||||
@change="val => { updateIcmpCodes(val) }"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt) in icmpTypes" :key="opt.index" :label="opt.description">
|
||||
{{ opt.index + ' - ' + opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div v-show="newRule.protocol === 'icmp'" class="form__item">
|
||||
<div class="form__label">{{ $t('label.icmpcode') }}</div>
|
||||
<a-input v-model:value="newRule.icmpcode"></a-input>
|
||||
<a-select
|
||||
v-model:value="newRule.icmpcode"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt) in icmpCodes" :key="opt.code" :label="opt.description">
|
||||
{{ opt.code + ' - ' + opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div class="form__item" style="margin-left: auto;">
|
||||
<a-button :disabled="!('createFirewallRule' in $store.getters.apis)" type="primary" ref="submit" @click="addRule">{{ $t('label.add') }}</a-button>
|
||||
@ -85,10 +106,10 @@
|
||||
{{ getCapitalise(record.protocol) }}
|
||||
</template>
|
||||
<template v-if="column.key === 'startport'">
|
||||
{{ record.icmptype || record.startport >= 0 ? record.icmptype || record.startport : $t('label.all') }}
|
||||
{{ record.icmptype >= 0 ? String(record.icmptype): record.startport >= 0 ? String(record.startport): 'All' }}
|
||||
</template>
|
||||
<template v-if="column.key === 'endport'">
|
||||
{{ record.icmpcode || record.endport >= 0 ? record.icmpcode || record.endport : $t('label.all') }}
|
||||
{{ record.icmpcode >= 0 ? String(record.icmpcode): record.endport >= 0 ? String(record.endport): 'All' }}
|
||||
</template>
|
||||
<template v-if="column.key === 'actions'">
|
||||
<div class="actions">
|
||||
@ -238,6 +259,9 @@ export default {
|
||||
startport: null,
|
||||
endport: null
|
||||
},
|
||||
protocolNumbers: [],
|
||||
icmpTypes: [],
|
||||
icmpCodes: [],
|
||||
tagsModalVisible: false,
|
||||
selectedRule: null,
|
||||
tags: [],
|
||||
@ -279,6 +303,7 @@ export default {
|
||||
},
|
||||
created () {
|
||||
this.initForm()
|
||||
this.fetchNetworkProtocols()
|
||||
this.fetchData()
|
||||
},
|
||||
watch: {
|
||||
@ -301,6 +326,34 @@ export default {
|
||||
value: [{ required: true, message: this.$t('message.specify.tag.value') }]
|
||||
})
|
||||
},
|
||||
fetchNetworkProtocols () {
|
||||
api('listNetworkProtocols', {
|
||||
option: 'protocolnumber'
|
||||
}).then(json => {
|
||||
this.protocolNumbers = json.listnetworkprotocolsresponse?.networkprotocol || []
|
||||
})
|
||||
api('listNetworkProtocols', {
|
||||
option: 'icmptype'
|
||||
}).then(json => {
|
||||
this.icmpTypes.push({ index: -1, description: this.$t('label.all') })
|
||||
const results = json.listnetworkprotocolsresponse?.networkprotocol || []
|
||||
for (const result of results) {
|
||||
this.icmpTypes.push(result)
|
||||
}
|
||||
})
|
||||
},
|
||||
updateIcmpCodes (val) {
|
||||
this.newRule.icmpcode = -1
|
||||
this.icmpCodes = []
|
||||
this.icmpCodes.push({ code: -1, description: this.$t('label.all') })
|
||||
const icmpType = this.icmpTypes.find(icmpType => icmpType.index === val)
|
||||
if (icmpType && icmpType.details) {
|
||||
const icmpTypeDetails = icmpType.details
|
||||
for (const k of Object.keys(icmpTypeDetails)) {
|
||||
this.icmpCodes.push({ code: parseInt(k), description: icmpTypeDetails[k] })
|
||||
}
|
||||
}
|
||||
},
|
||||
fetchData () {
|
||||
this.loading = true
|
||||
api('listFirewallRules', {
|
||||
@ -620,7 +673,7 @@ export default {
|
||||
&__item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/*flex: 1;*/
|
||||
flex: 1;
|
||||
padding-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
|
||||
@ -47,25 +47,56 @@
|
||||
<a-select-option value="protocolnumber" :label="$t('label.protocol.number')">{{ capitalise($t('label.protocol.number')) }}</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div v-show="newRule.protocol === 'tcp' || newRule.protocol === 'udp'" class="form__item">
|
||||
<div v-show="newRule.protocol === 'protocolnumber'" class="form__item">
|
||||
<div class="form__label">{{ $t('label.protocol.number') }}</div>
|
||||
<a-select
|
||||
v-model:value="newRule.protocolnumber"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt, optIndex) in protocolNumbers" :key="optIndex" :label="opt.name">
|
||||
{{ opt.index + ' - ' + opt.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div v-show="['tcp', 'udp', 'protocolnumber'].includes(newRule.protocol) && !(newRule.protocol === 'protocolnumber' && newRule.protocolnumber === 1)" class="form__item">
|
||||
<div class="form__label">{{ $t('label.startport') }}</div>
|
||||
<a-input v-model:value="newRule.startport"></a-input>
|
||||
</div>
|
||||
<div v-show="newRule.protocol === 'tcp' || newRule.protocol === 'udp'" class="form__item">
|
||||
<div v-show="['tcp', 'udp', 'protocolnumber'].includes(newRule.protocol) && !(newRule.protocol === 'protocolnumber' && newRule.protocolnumber === 1)" class="form__item">
|
||||
<div class="form__label">{{ $t('label.endport') }}</div>
|
||||
<a-input v-model:value="newRule.endport"></a-input>
|
||||
</div>
|
||||
<div v-show="newRule.protocol === 'protocolnumber'" class="form__item">
|
||||
<div class="form__label">{{ $t('label.protocol.number') }}</div>
|
||||
<a-input v-model:value="newRule.protocolnumber"></a-input>
|
||||
</div>
|
||||
<div v-show="newRule.protocol === 'icmp'" class="form__item">
|
||||
<div v-show="newRule.protocol === 'icmp' || (newRule.protocol === 'protocolnumber' && newRule.protocolnumber === 1)" class="form__item">
|
||||
<div class="form__label">{{ $t('label.icmptype') }}</div>
|
||||
<a-input v-model:value="newRule.icmptype"></a-input>
|
||||
<a-select
|
||||
v-model:value="newRule.icmptype"
|
||||
@change="val => { updateIcmpCodes(val) }"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt) in icmpTypes" :key="opt.index" :label="opt.description">
|
||||
{{ opt.index + ' - ' + opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div v-show="newRule.protocol === 'icmp'" class="form__item">
|
||||
<div v-show="newRule.protocol === 'icmp' || (newRule.protocol === 'protocolnumber' && newRule.protocolnumber === 1)" class="form__item">
|
||||
<div class="form__label">{{ $t('label.icmpcode') }}</div>
|
||||
<a-input v-model:value="newRule.icmpcode"></a-input>
|
||||
<a-select
|
||||
v-model:value="newRule.icmpcode"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt) in icmpCodes" :key="opt.code" :label="opt.description">
|
||||
{{ opt.code + ' - ' + opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div class="form__item" v-if="addType === 'cidr'">
|
||||
<div class="form__label">{{ $t('label.cidr') }}</div>
|
||||
@ -211,6 +242,9 @@ export default {
|
||||
group: null
|
||||
}
|
||||
},
|
||||
protocolNumbers: [],
|
||||
icmpTypes: [],
|
||||
icmpCodes: [],
|
||||
tagsModalVisible: false,
|
||||
tags: [],
|
||||
newTag: {
|
||||
@ -275,6 +309,7 @@ export default {
|
||||
},
|
||||
created () {
|
||||
this.initForm()
|
||||
this.fetchNetworkProtocols()
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
@ -286,6 +321,34 @@ export default {
|
||||
value: [{ required: true, message: this.$t('message.specify.tag.value') }]
|
||||
})
|
||||
},
|
||||
fetchNetworkProtocols () {
|
||||
api('listNetworkProtocols', {
|
||||
option: 'protocolnumber'
|
||||
}).then(json => {
|
||||
this.protocolNumbers = json.listnetworkprotocolsresponse?.networkprotocol || []
|
||||
})
|
||||
api('listNetworkProtocols', {
|
||||
option: 'icmptype'
|
||||
}).then(json => {
|
||||
this.icmpTypes.push({ index: -1, description: this.$t('label.all') })
|
||||
const results = json.listnetworkprotocolsresponse?.networkprotocol || []
|
||||
for (const result of results) {
|
||||
this.icmpTypes.push(result)
|
||||
}
|
||||
})
|
||||
},
|
||||
updateIcmpCodes (val) {
|
||||
this.newRule.icmpcode = -1
|
||||
this.icmpCodes = []
|
||||
this.icmpCodes.push({ code: -1, description: this.$t('label.all') })
|
||||
const icmpType = this.icmpTypes.find(icmpType => icmpType.index === val)
|
||||
if (icmpType && icmpType.details) {
|
||||
const icmpTypeDetails = icmpType.details
|
||||
for (const k of Object.keys(icmpTypeDetails)) {
|
||||
this.icmpCodes.push({ code: parseInt(k), description: icmpTypeDetails[k] })
|
||||
}
|
||||
}
|
||||
},
|
||||
fetchData () {
|
||||
this.tabType = this.$route.query.tab === 'ingress.rule' ? 'ingress' : 'egress'
|
||||
this.rules = this.tabType === 'ingress' ? this.resource.ingressrule : this.resource.egressrule
|
||||
|
||||
@ -78,6 +78,7 @@ public class NetUtils {
|
||||
public final static String ANY_PROTO = "any";
|
||||
public final static String ICMP_PROTO = "icmp";
|
||||
public static final String ICMP6_PROTO = "icmp6";
|
||||
public final static int ICMP_PROTO_NUMBER = 1;
|
||||
public final static String ALL_PROTO = "all";
|
||||
public final static String HTTP_PROTO = "http";
|
||||
public final static String HTTPS_PROTO = "https";
|
||||
@ -1771,4 +1772,18 @@ public class NetUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateIcmpTypeAndCode(Integer icmpType, Integer icmpCode) {
|
||||
if ((icmpType == null) || (icmpCode == null)) {
|
||||
throw new CloudRuntimeException("Invalid ICMP type/code specified, icmpType = " + icmpType + ", icmpCode = " + icmpCode);
|
||||
}
|
||||
if (icmpType == -1 && icmpCode != -1) {
|
||||
throw new CloudRuntimeException("Invalid icmp code");
|
||||
}
|
||||
if (icmpType != -1 && icmpCode == -1) {
|
||||
throw new CloudRuntimeException("Invalid icmp code: need non-negative icmp code ");
|
||||
}
|
||||
if (icmpCode > 255 || icmpType > 255 || icmpCode < -1 || icmpType < -1) {
|
||||
throw new CloudRuntimeException("Invalid icmp type/code ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
362
utils/src/main/java/com/cloud/utils/net/NetworkProtocols.java
Normal file
362
utils/src/main/java/com/cloud/utils/net/NetworkProtocols.java
Normal file
@ -0,0 +1,362 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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 com.cloud.utils.net;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Network protocols and parameters.
|
||||
* see <a href="https://www.iana.org/protocols">Protocol Registries</a>
|
||||
*
|
||||
*/
|
||||
public class NetworkProtocols {
|
||||
|
||||
public enum Option {
|
||||
ProtocolNumber, IcmpType;
|
||||
|
||||
public static Option getOption(String value) {
|
||||
return Arrays.stream(Option.values())
|
||||
.filter(option -> option.name().equalsIgnoreCase(value))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format("Option " + value + " is not supported. Supported values are %s", Arrays.toString(Option.values()))));
|
||||
}
|
||||
}
|
||||
|
||||
// Refer to https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
|
||||
public static List<ProtocolNumber> ProtocolNumbers = new ArrayList<>();
|
||||
static {
|
||||
ProtocolNumbers.add(new ProtocolNumber(0, "HOPOPT", "IPv6 Hop-by-Hop Option"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(1, "ICMP", "Internet Control Message"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(2, "IGMP", "Internet Group Management"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(3, "GGP", "Gateway-to-Gateway"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(4, "IPv4", "IPv4 encapsulation"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(5, "ST", "Stream"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(6, "TCP", "Transmission Control"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(7, "CBT", "CBT"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(8, "EGP", "Exterior Gateway Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(9, "IGP", "any private interior gateway"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(10, "BBN-RCC-MON", "BBN RCC Monitoring"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(11, "NVP-II", "Network Voice Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(12, "PUP", "PUP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(13, "ARGUS (deprecated)", "ARGUS"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(14, "EMCON", "EMCON"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(15, "XNET", "Cross Net Debugger"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(16, "CHAOS", "Chaos"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(17, "UDP", "User Datagram"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(18, "MUX", "Multiplexing"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(19, "DCN-MEAS", "DCN Measurement Subsystems"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(20, "HMP", "Host Monitoring"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(21, "PRM", "Packet Radio Measurement"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(22, "XNS-IDP", "XEROX NS IDP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(23, "TRUNK-1", "Trunk-1"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(24, "TRUNK-2", "Trunk-2"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(25, "LEAF-1", "Leaf-1"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(26, "LEAF-2", "Leaf-2"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(27, "RDP", "Reliable Data Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(28, "IRTP", "Internet Reliable Transaction"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(29, "ISO-TP4", "ISO Transport Protocol Class 4"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(30, "NETBLT", "Bulk Data Transfer Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(31, "MFE-NSP", "MFE Network Services Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(32, "MERIT-INP", "MERIT Internodal Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(33, "DCCP", "Datagram Congestion Control Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(34, "3PC", "Third Party Connect Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(35, "IDPR", "Inter-Domain Policy Routing Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(36, "XTP", "XTP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(37, "DDP", "Datagram Delivery Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(38, "IDPR-CMTP", "IDPR Control Message Transport Proto"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(39, "TP++", "TP++ Transport Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(40, "IL", "IL Transport Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(41, "IPv6", "IPv6 encapsulation"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(42, "SDRP", "Source Demand Routing Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(43, "IPv6-Route", "Routing Header for IPv6"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(44, "IPv6-Frag", "Fragment Header for IPv6"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(45, "IDRP", "Inter-Domain Routing Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(46, "RSVP", "Reservation Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(47, "GRE", "Generic Routing Encapsulation"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(48, "DSR", "Dynamic Source Routing Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(49, "BNA", "BNA"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(50, "ESP", "Encap Security Payload"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(51, "AH", "Authentication Header"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(52, "I-NLSP", "Integrated Net Layer Security TUBA"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(53, "SWIPE (deprecated)", "IP with Encryption"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(54, "NARP", "NBMA Address Resolution Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(55, "MOBILE", "Minimal IPv4 Encapsulation"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(56, "TLSP", "Transport Layer Security Protocol using Kryptonet key management"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(57, "SKIP", "SKIP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(58, "IPv6-ICMP", "ICMP for IPv6"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(59, "IPv6-NoNxt", "No Next Header for IPv6"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(60, "IPv6-Opts", "Destination Options for IPv6"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(61, "Any host internal protocol", "Any host internal protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(62, "CFTP", "CFTP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(63, "Any local network", "Any local network"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(64, "SAT-EXPAK", "SATNET and Backroom EXPAK"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(65, "KRYPTOLAN", "Kryptolan"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(66, "RVD", "MIT Remote Virtual Disk Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(67, "IPPC", "Internet Pluribus Packet Core"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(68, "Any distributed file system", "Any distributed file system"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(69, "SAT-MON", "SATNET Monitoring"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(70, "VISA", "VISA Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(71, "IPCV", "Internet Packet Core Utility"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(72, "CPNX", "Computer Protocol Network Executive"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(73, "CPHB", "Computer Protocol Heart Beat"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(74, "WSN", "Wang Span Network"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(75, "PVP", "Packet Video Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(76, "BR-SAT-MON", "Backroom SATNET Monitoring"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(77, "SUN-ND", "SUN ND PROTOCOL-Temporary"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(78, "WB-MON", "WIDEBAND Monitoring"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(79, "WB-EXPAK", "WIDEBAND EXPAK"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(80, "ISO-IP", "ISO Internet Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(81, "VMTP", "VMTP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(82, "SECURE-VMTP", "SECURE-VMTP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(83, "VINES", "VINES"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(84, "TTP or IPTM", "Internet Protocol Traffic Manager"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(85, "NSFNET-IGP", "NSFNET-IGP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(86, "DGP", "Dissimilar Gateway Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(87, "TCF", "TCF"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(88, "EIGRP", "EIGRP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(89, "OSPFIGP", "OSPFIGP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(90, "Sprite-RPC", "Sprite RPC Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(91, "LARP", "Locus Address Resolution Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(92, "MTP", "Multicast Transport Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(93, "AX.25", "AX.25 Frames"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(94, "IPIP", "IP-within-IP Encapsulation Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(95, "MICP (deprecated)", "Mobile Internetworking Control Pro."));
|
||||
ProtocolNumbers.add(new ProtocolNumber(96, "SCC-SP", "Semaphore Communications Sec. Pro."));
|
||||
ProtocolNumbers.add(new ProtocolNumber(97, "ETHERIP", "Ethernet-within-IP Encapsulation"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(98, "ENCAP", "Encapsulation Header"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(99, "Any private encryption scheme", "Any private encryption scheme"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(100, "GMTP", "GMTP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(101, "IFMP", "Ipsilon Flow Management Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(102, "PNNI", "PNNI over IP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(103, "PIM", "Protocol Independent Multicast"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(104, "ARIS", "ARIS"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(105, "SCPS", "SCPS"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(106, "QNX", "QNX"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(107, "A/N", "Active Networks"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(108, "IPComp", "IP Payload Compression Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(109, "SNP", "Sitara Networks Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(110, "Compaq-Peer", "Compaq Peer Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(111, "IPX-in-IP", "IPX in IP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(112, "VRRP", "Virtual Router Redundancy Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(113, "PGM", "PGM Reliable Transport Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(114, "Any 0-hop protocol", "Any 0-hop protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(115, "L2TP", "Layer Two Tunneling Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(116, "DDX", "D-II Data Exchange (DDX)"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(117, "IATP", "Interactive Agent Transfer Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(118, "STP", "Schedule Transfer Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(119, "SRP", "SpectraLink Radio Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(120, "UTI", "UTI"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(121, "SMP", "Simple Message Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(122, "SM (deprecated)", "Simple Multicast Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(123, "PTP", "Performance Transparency Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(124, "ISIS over IPv4", ""));
|
||||
ProtocolNumbers.add(new ProtocolNumber(125, "FIRE", ""));
|
||||
ProtocolNumbers.add(new ProtocolNumber(126, "CRTP", "Combat Radio Transport Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(127, "CRUDP", "Combat Radio User Datagram"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(128, "SSCOPMCE", ""));
|
||||
ProtocolNumbers.add(new ProtocolNumber(129, "IPLT", ""));
|
||||
ProtocolNumbers.add(new ProtocolNumber(130, "SPS", "Secure Packet Shield"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(131, "PIPE", "Private IP Encapsulation within IP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(132, "SCTP", "Stream Control Transmission Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(133, "FC", "Fibre Channel"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(134, "RSVP-E2E-IGNORE", ""));
|
||||
ProtocolNumbers.add(new ProtocolNumber(135, "Mobility Header", ""));
|
||||
ProtocolNumbers.add(new ProtocolNumber(136, "UDPLite", ""));
|
||||
ProtocolNumbers.add(new ProtocolNumber(137, "MPLS-in-IP", ""));
|
||||
ProtocolNumbers.add(new ProtocolNumber(138, "manet", "MANET Protocols"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(139, "HIP", "Host Identity Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(140, "Shim6", "Shim6 Protocol"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(141, "WESP", "Wrapped Encapsulating Security Payload"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(142, "ROHC", "Robust Header Compression"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(143, "Ethernet", "Ethernet"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(144, "AGGFRAG", "AGGFRAG encapsulation payload for ESP"));
|
||||
ProtocolNumbers.add(new ProtocolNumber(145, "NSH", "Network Service Header"));
|
||||
}
|
||||
/**
|
||||
* Different Internet Protocol Numbers.
|
||||
*/
|
||||
public static class ProtocolNumber {
|
||||
|
||||
private final Integer number;
|
||||
|
||||
private final String keyword;
|
||||
|
||||
private final String protocol;
|
||||
|
||||
public ProtocolNumber(Integer number, String keyword, String protocol) {
|
||||
this.number = number;
|
||||
this.keyword = keyword;
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public Integer getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public String getKeyword() {
|
||||
return keyword;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
}
|
||||
|
||||
// Refer to https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
|
||||
public static List<IcmpType> IcmpTypes = new ArrayList<>();
|
||||
static {
|
||||
IcmpTypes.add(new IcmpType(0, "Echo Reply"));
|
||||
IcmpTypes.add(new IcmpType(3, "Destination Unreachable"));
|
||||
IcmpTypes.add(new IcmpType(5, "Redirect"));
|
||||
IcmpTypes.add(new IcmpType(8, "Echo"));
|
||||
IcmpTypes.add(new IcmpType(9, "Router Advertisement"));
|
||||
IcmpTypes.add(new IcmpType(10, "Router Solicitation"));
|
||||
IcmpTypes.add(new IcmpType(11, "Time Exceeded"));
|
||||
IcmpTypes.add(new IcmpType(12, "Parameter Problem"));
|
||||
IcmpTypes.add(new IcmpType(13, "Timestamp"));
|
||||
IcmpTypes.add(new IcmpType(14, "Timestamp Reply"));
|
||||
IcmpTypes.add(new IcmpType(40, "Photuris"));
|
||||
IcmpTypes.add(new IcmpType(42, "Extended Echo Request"));
|
||||
IcmpTypes.add(new IcmpType(43, "Extended Echo Reply"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Different types of ICMP (Internet Control Message Protocol).
|
||||
*/
|
||||
public static class IcmpType {
|
||||
|
||||
private final Integer type;
|
||||
|
||||
private final String description;
|
||||
|
||||
private final List<IcmpCode> icmpCodes = new ArrayList<>();
|
||||
|
||||
public IcmpType(Integer type, String description) {
|
||||
this.type = type;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public List<IcmpCode> getIcmpCodes() {
|
||||
return icmpCodes;
|
||||
}
|
||||
|
||||
public void addIcmpCodes(IcmpCode code) {
|
||||
this.icmpCodes.add(code);
|
||||
}
|
||||
}
|
||||
|
||||
static void addIcmpCode(IcmpCode code) {
|
||||
IcmpType type = IcmpTypes.stream().filter(icmpType -> icmpType.getType().equals(code.getType())).findFirst().get();
|
||||
type.addIcmpCodes(code);
|
||||
}
|
||||
|
||||
public static boolean validateIcmpTypeAndCode(Integer type, Integer code) {
|
||||
if (type != null && type != -1) {
|
||||
Optional<IcmpType> icmpTypeOptional = IcmpTypes.stream().filter(t -> t.getType().equals(type)).findFirst();
|
||||
if (icmpTypeOptional == null || icmpTypeOptional.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
IcmpType icmpType = icmpTypeOptional.get();
|
||||
if (code != null && code != -1) {
|
||||
Optional<IcmpCode> icmpCodeOptional = icmpType.getIcmpCodes().stream().filter(c -> c.getCode().equals(code)).findFirst();
|
||||
if (icmpCodeOptional == null || icmpCodeOptional.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static {
|
||||
addIcmpCode(new IcmpCode(0, 0, "Echo reply"));
|
||||
addIcmpCode(new IcmpCode(3, 0, "Net unreachable"));
|
||||
addIcmpCode(new IcmpCode(3, 1, "Host unreachable"));
|
||||
addIcmpCode(new IcmpCode(3, 2, "Protocol unreachable"));
|
||||
addIcmpCode(new IcmpCode(3, 3, "Port unreachable"));
|
||||
addIcmpCode(new IcmpCode(3, 4, "Fragmentation needed and DF set"));
|
||||
addIcmpCode(new IcmpCode(3, 5, "Source route failed"));
|
||||
addIcmpCode(new IcmpCode(3, 6, "Destination network unknown"));
|
||||
addIcmpCode(new IcmpCode(3, 7, "Destination host unknown"));
|
||||
addIcmpCode(new IcmpCode(3, 9, "Network administratively prohibited"));
|
||||
addIcmpCode(new IcmpCode(3, 10, "Host administratively prohibited"));
|
||||
addIcmpCode(new IcmpCode(3, 11, "Network unreachable for ToS"));
|
||||
addIcmpCode(new IcmpCode(3, 12, "Host unreachable for ToS"));
|
||||
addIcmpCode(new IcmpCode(3, 13, "Communication administratively prohibited"));
|
||||
addIcmpCode(new IcmpCode(3, 14, "Host Precedence Violation"));
|
||||
addIcmpCode(new IcmpCode(3, 15, "Precedence cutoff in effect"));
|
||||
addIcmpCode(new IcmpCode(5, 0, "Redirect Datagram for the Network"));
|
||||
addIcmpCode(new IcmpCode(5, 1, "Redirect Datagram for the Host"));
|
||||
addIcmpCode(new IcmpCode(5, 2, "Redirect Datagram for the ToS & network"));
|
||||
addIcmpCode(new IcmpCode(5, 3, "Redirect Datagram for the ToS & host"));
|
||||
addIcmpCode(new IcmpCode(8, 0, "Echo request"));
|
||||
addIcmpCode(new IcmpCode(9, 0, "Router advertisement"));
|
||||
addIcmpCode(new IcmpCode(9, 16, "Does not route common traffic"));
|
||||
addIcmpCode(new IcmpCode(10, 0, "Router solicitation"));
|
||||
addIcmpCode(new IcmpCode(11, 0, "TTL expired in transit"));
|
||||
addIcmpCode(new IcmpCode(11, 1, "Fragment reassembly time exceeded"));
|
||||
addIcmpCode(new IcmpCode(12, 0, "Parameter problem: Pointer indicates the error"));
|
||||
addIcmpCode(new IcmpCode(12, 1, "Parameter problem: Missing a required option"));
|
||||
addIcmpCode(new IcmpCode(12, 2, "Parameter problem: Bad length"));
|
||||
addIcmpCode(new IcmpCode(13, 0, "Timestamp"));
|
||||
addIcmpCode(new IcmpCode(14, 0, "Timestamp reply"));
|
||||
addIcmpCode(new IcmpCode(40, 0, "Photuris: Security failures"));
|
||||
addIcmpCode(new IcmpCode(40, 1, "Photuris: Authentication failed"));
|
||||
addIcmpCode(new IcmpCode(40, 2, "Photuris: Decompression failed"));
|
||||
addIcmpCode(new IcmpCode(40, 3, "Photuris: Decryption failed"));
|
||||
addIcmpCode(new IcmpCode(40, 4, "Photuris: Need authentication"));
|
||||
addIcmpCode(new IcmpCode(40, 5, "Photuris: Need authorization"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Code field of ICMP types.
|
||||
*/
|
||||
public static class IcmpCode {
|
||||
|
||||
private final Integer type;
|
||||
private final Integer code;
|
||||
private final String description;
|
||||
|
||||
public IcmpCode(Integer type, Integer code, String description) {
|
||||
this.type = type;
|
||||
this.code = code;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -843,4 +843,50 @@ public class NetUtilsTest {
|
||||
Assert.assertEquals(expected, result);
|
||||
networkInterfaceMocked.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateIcmpTypeAndCodesGood1() {
|
||||
NetUtils.validateIcmpTypeAndCode(-1, -1);
|
||||
}
|
||||
@Test
|
||||
public void validateIcmpTypeAndCodesGood2() {
|
||||
NetUtils.validateIcmpTypeAndCode(3, 2);
|
||||
}
|
||||
|
||||
@Test(expected=CloudRuntimeException.class)
|
||||
public void validateIcmpTypeAndCodesThrowsException1() {
|
||||
NetUtils.validateIcmpTypeAndCode(null, null);
|
||||
}
|
||||
@Test(expected=CloudRuntimeException.class)
|
||||
public void validateIcmpTypeAndCodesThrowsException2() {
|
||||
NetUtils.validateIcmpTypeAndCode(null, -1);
|
||||
}
|
||||
@Test(expected=CloudRuntimeException.class)
|
||||
public void validateIcmpTypeAndCodesThrowsException3() {
|
||||
NetUtils.validateIcmpTypeAndCode(-1, null);
|
||||
}
|
||||
@Test(expected=CloudRuntimeException.class)
|
||||
public void validateIcmpTypeAndCodesThrowsException4() {
|
||||
NetUtils.validateIcmpTypeAndCode(-1, 2);
|
||||
}
|
||||
@Test(expected=CloudRuntimeException.class)
|
||||
public void validateIcmpTypeAndCodesThrowsException5() {
|
||||
NetUtils.validateIcmpTypeAndCode(3, -1);
|
||||
}
|
||||
@Test(expected=CloudRuntimeException.class)
|
||||
public void validateIcmpTypeAndCodesThrowsException6() {
|
||||
NetUtils.validateIcmpTypeAndCode(-2, 2);
|
||||
}
|
||||
@Test(expected=CloudRuntimeException.class)
|
||||
public void validateIcmpTypeAndCodesThrowsException7() {
|
||||
NetUtils.validateIcmpTypeAndCode(257, 2);
|
||||
}
|
||||
@Test(expected=CloudRuntimeException.class)
|
||||
public void validateIcmpTypeAndCodesThrowsException8() {
|
||||
NetUtils.validateIcmpTypeAndCode(3, -2);
|
||||
}
|
||||
@Test(expected=CloudRuntimeException.class)
|
||||
public void validateIcmpTypeAndCodesThrowsException9() {
|
||||
NetUtils.validateIcmpTypeAndCode(3, -257);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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 com.cloud.utils.net;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class NetworkProtocolsTest {
|
||||
|
||||
@Test
|
||||
public void validateIcmpTypeAndCode() {
|
||||
validateIcmpTypeAndCodeInternal(null, null, true);
|
||||
validateIcmpTypeAndCodeInternal(null, -1, true);
|
||||
validateIcmpTypeAndCodeInternal(-1, -1, true);
|
||||
validateIcmpTypeAndCodeInternal(3, -1, true);
|
||||
validateIcmpTypeAndCodeInternal(3, 15, true);
|
||||
validateIcmpTypeAndCodeInternal(4, -1, false);
|
||||
validateIcmpTypeAndCodeInternal(5, 10, false);
|
||||
}
|
||||
|
||||
private void validateIcmpTypeAndCodeInternal(Integer type, Integer code, boolean expected) {
|
||||
boolean actual = NetworkProtocols.validateIcmpTypeAndCode(type, code);
|
||||
Assert.assertEquals(expected, actual);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user