Implement SNMP v3 security support, remove traps support
This commit is contained in:
parent
0045f00613
commit
e52ac96c62
@ -19,6 +19,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.thingsboard.server.common.data.DeviceTransportType;
|
||||
import org.thingsboard.server.common.data.transport.snmp.AuthenticationProtocol;
|
||||
import org.thingsboard.server.common.data.transport.snmp.PrivacyProtocol;
|
||||
import org.thingsboard.server.common.data.transport.snmp.SnmpProtocolVersion;
|
||||
|
||||
@Data
|
||||
@ -26,9 +28,23 @@ public class SnmpDeviceTransportConfiguration implements DeviceTransportConfigur
|
||||
private String address;
|
||||
private int port;
|
||||
private SnmpProtocolVersion protocolVersion;
|
||||
|
||||
/*
|
||||
* For SNMP v1 and v2c
|
||||
* */
|
||||
private String community;
|
||||
|
||||
/*
|
||||
* For SNMP v3 with User Based Security Model
|
||||
* */
|
||||
private String username;
|
||||
private String securityName;
|
||||
private String authenticationPassphrase; // for SNMP v3
|
||||
private String privacyPassphrase; // for SNMP v3
|
||||
private String contextName;
|
||||
private AuthenticationProtocol authenticationProtocol;
|
||||
private String authenticationPassphrase;
|
||||
private PrivacyProtocol privacyProtocol;
|
||||
private String privacyPassphrase;
|
||||
private String engineId;
|
||||
|
||||
@Override
|
||||
public DeviceTransportType getType() {
|
||||
@ -44,7 +60,6 @@ public class SnmpDeviceTransportConfiguration implements DeviceTransportConfigur
|
||||
|
||||
@JsonIgnore
|
||||
private boolean isValid() {
|
||||
return StringUtils.isNotBlank(address) && port > 0 &&
|
||||
StringUtils.isNotBlank(securityName) && protocolVersion != null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright © 2016-2021 The Thingsboard Authors
|
||||
*
|
||||
* 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.thingsboard.server.common.data.transport.snmp;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
public enum AuthenticationProtocol {
|
||||
SHA_1("1.3.6.1.6.3.10.1.1.3"),
|
||||
SHA_224("1.3.6.1.6.3.10.1.1.4"),
|
||||
SHA_256("1.3.6.1.6.3.10.1.1.5"),
|
||||
SHA_384("1.3.6.1.6.3.10.1.1.6"),
|
||||
SHA_512("1.3.6.1.6.3.10.1.1.7"),
|
||||
MD5("1.3.6.1.6.3.10.1.1.2");
|
||||
|
||||
// oids taken from org.snmp4j.security.SecurityProtocol implementations
|
||||
private final String oid;
|
||||
|
||||
AuthenticationProtocol(String oid) {
|
||||
this.oid = oid;
|
||||
}
|
||||
|
||||
public String getOid() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
public static Optional<AuthenticationProtocol> forName(String name) {
|
||||
return Arrays.stream(values())
|
||||
.filter(protocol -> protocol.name().equalsIgnoreCase(name))
|
||||
.findFirst();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright © 2016-2021 The Thingsboard Authors
|
||||
*
|
||||
* 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.thingsboard.server.common.data.transport.snmp;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
public enum PrivacyProtocol {
|
||||
DES("1.3.6.1.6.3.10.1.2.2"),
|
||||
AES_128("1.3.6.1.6.3.10.1.2.4"),
|
||||
AES_192("1.3.6.1.4.1.4976.2.2.1.1.1"),
|
||||
AES_256("1.3.6.1.4.1.4976.2.2.1.1.2");
|
||||
|
||||
// oids taken from org.snmp4j.security.SecurityProtocol implementations
|
||||
private final String oid;
|
||||
|
||||
PrivacyProtocol(String oid) {
|
||||
this.oid = oid;
|
||||
}
|
||||
|
||||
public String getOid() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
public static Optional<PrivacyProtocol> forName(String name) {
|
||||
return Arrays.stream(values())
|
||||
.filter(protocol -> protocol.name().equalsIgnoreCase(name))
|
||||
.findFirst();
|
||||
}
|
||||
}
|
||||
@ -19,10 +19,7 @@ public enum SnmpCommunicationSpec {
|
||||
TELEMETRY_QUERYING(true),
|
||||
CLIENT_ATTRIBUTES_QUERYING(true),
|
||||
|
||||
SHARED_ATTRIBUTES_SETTING,
|
||||
|
||||
TELEMETRY_TRAPS_RECEIVING,
|
||||
CLIENT_ATTRIBUTES_TRAPS_RECEIVING;
|
||||
SHARED_ATTRIBUTES_SETTING;
|
||||
|
||||
private final boolean isRepeatingQuerying;
|
||||
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Copyright © 2016-2021 The Thingsboard Authors
|
||||
*
|
||||
* 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.thingsboard.server.common.data.transport.snmp.configs;
|
||||
|
||||
import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec;
|
||||
|
||||
public class ClientAttributesTrapsReceivingSnmpCommunicationConfig extends SnmpCommunicationConfig {
|
||||
@Override
|
||||
public SnmpCommunicationSpec getSpec() {
|
||||
return SnmpCommunicationSpec.CLIENT_ATTRIBUTES_TRAPS_RECEIVING;
|
||||
}
|
||||
}
|
||||
@ -31,9 +31,7 @@ import java.util.List;
|
||||
@JsonSubTypes({
|
||||
@Type(value = TelemetryQueryingSnmpCommunicationConfig.class, name = "TELEMETRY_QUERYING"),
|
||||
@Type(value = ClientAttributesQueryingSnmpCommunicationConfig.class, name = "CLIENT_ATTRIBUTES_QUERYING"),
|
||||
@Type(value = SharedAttributesSettingSnmpCommunicationConfig.class, name = "SHARED_ATTRIBUTES_SETTING"),
|
||||
@Type(value = TelemetryTrapsReceivingSnmpCommunicationConfig.class, name = "TELEMETRY_TRAPS_RECEIVING"),
|
||||
@Type(value = ClientAttributesTrapsReceivingSnmpCommunicationConfig.class, name = "CLIENT_ATTRIBUTES_TRAPS_RECEIVING")
|
||||
@Type(value = SharedAttributesSettingSnmpCommunicationConfig.class, name = "SHARED_ATTRIBUTES_SETTING")
|
||||
})
|
||||
public abstract class SnmpCommunicationConfig {
|
||||
protected List<SnmpMapping> mappings;
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
/**
|
||||
* Copyright © 2016-2021 The Thingsboard Authors
|
||||
*
|
||||
* 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.thingsboard.server.common.data.transport.snmp.configs;
|
||||
|
||||
import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec;
|
||||
|
||||
public class TelemetryTrapsReceivingSnmpCommunicationConfig extends SnmpCommunicationConfig {
|
||||
@Override
|
||||
public SnmpCommunicationSpec getSpec() {
|
||||
return SnmpCommunicationSpec.TELEMETRY_TRAPS_RECEIVING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,118 @@
|
||||
/**
|
||||
* Copyright © 2016-2021 The Thingsboard Authors
|
||||
*
|
||||
* 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.thingsboard.server.transport.snmp;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.snmp4j.AbstractTarget;
|
||||
import org.snmp4j.CommunityTarget;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.UserTarget;
|
||||
import org.snmp4j.security.SecurityLevel;
|
||||
import org.snmp4j.security.SecurityModel;
|
||||
import org.snmp4j.security.SecurityProtocols;
|
||||
import org.snmp4j.security.USM;
|
||||
import org.snmp4j.security.UsmUser;
|
||||
import org.snmp4j.smi.GenericAddress;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.transport.snmp.SnmpProtocolVersion;
|
||||
import org.thingsboard.server.queue.util.TbSnmpTransportComponent;
|
||||
import org.thingsboard.server.transport.snmp.service.SnmpTransportService;
|
||||
import org.thingsboard.server.transport.snmp.session.DeviceSessionContext;
|
||||
|
||||
@Service
|
||||
@TbSnmpTransportComponent
|
||||
@RequiredArgsConstructor
|
||||
public class SnmpAuthService {
|
||||
private final SnmpTransportService snmpTransportService;
|
||||
|
||||
@Value("${transport.snmp.underlying_protocol}")
|
||||
private String snmpUnderlyingProtocol;
|
||||
|
||||
public Target setUpSnmpTarget(SnmpDeviceProfileTransportConfiguration profileTransportConfig, SnmpDeviceTransportConfiguration deviceTransportConfig) {
|
||||
AbstractTarget target;
|
||||
|
||||
SnmpProtocolVersion protocolVersion = deviceTransportConfig.getProtocolVersion();
|
||||
switch (protocolVersion) {
|
||||
case V1:
|
||||
CommunityTarget communityTargetV1 = new CommunityTarget();
|
||||
communityTargetV1.setSecurityModel(SecurityModel.SECURITY_MODEL_SNMPv1);
|
||||
communityTargetV1.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV);
|
||||
communityTargetV1.setCommunity(new OctetString(deviceTransportConfig.getCommunity()));
|
||||
target = communityTargetV1;
|
||||
break;
|
||||
case V2C:
|
||||
CommunityTarget communityTargetV2 = new CommunityTarget();
|
||||
communityTargetV2.setSecurityModel(SecurityModel.SECURITY_MODEL_SNMPv2c);
|
||||
communityTargetV2.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV);
|
||||
communityTargetV2.setCommunity(new OctetString(deviceTransportConfig.getCommunity()));
|
||||
target = communityTargetV2;
|
||||
break;
|
||||
case V3:
|
||||
OctetString username = new OctetString(deviceTransportConfig.getUsername());
|
||||
OctetString securityName = new OctetString(deviceTransportConfig.getSecurityName());
|
||||
OctetString engineId = new OctetString(deviceTransportConfig.getEngineId());
|
||||
|
||||
OID authenticationProtocol = new OID(deviceTransportConfig.getAuthenticationProtocol().getOid());
|
||||
OID privacyProtocol = new OID(deviceTransportConfig.getPrivacyProtocol().getOid());
|
||||
OctetString authenticationPassphrase = new OctetString(deviceTransportConfig.getAuthenticationPassphrase());
|
||||
authenticationPassphrase = new OctetString(SecurityProtocols.getInstance().passwordToKey(authenticationProtocol, authenticationPassphrase, engineId.getValue()));
|
||||
OctetString privacyPassphrase = new OctetString(deviceTransportConfig.getPrivacyPassphrase());
|
||||
privacyPassphrase = new OctetString(SecurityProtocols.getInstance().passwordToKey(privacyProtocol, authenticationProtocol, privacyPassphrase, engineId.getValue()));
|
||||
|
||||
USM usm = snmpTransportService.getSnmp().getUSM();
|
||||
if (usm.hasUser(engineId, securityName)) {
|
||||
usm.removeAllUsers(username, engineId);
|
||||
}
|
||||
usm.addLocalizedUser(
|
||||
engineId.getValue(), username,
|
||||
authenticationProtocol, authenticationPassphrase.getValue(),
|
||||
privacyProtocol, privacyPassphrase.getValue()
|
||||
);
|
||||
|
||||
UserTarget userTarget = new UserTarget();
|
||||
userTarget.setSecurityName(securityName);
|
||||
userTarget.setAuthoritativeEngineID(engineId.getValue());
|
||||
userTarget.setSecurityModel(SecurityModel.SECURITY_MODEL_USM);
|
||||
userTarget.setSecurityLevel(SecurityLevel.AUTH_PRIV);
|
||||
target = userTarget;
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("SNMP protocol version " + protocolVersion + " is not supported");
|
||||
}
|
||||
|
||||
target.setAddress(GenericAddress.parse(snmpUnderlyingProtocol + ":" + deviceTransportConfig.getAddress() + "/" + deviceTransportConfig.getPort()));
|
||||
target.setTimeout(profileTransportConfig.getTimeoutMs());
|
||||
target.setRetries(profileTransportConfig.getRetries());
|
||||
target.setVersion(protocolVersion.getCode());
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
public void cleanUpSnmpAuthInfo(DeviceSessionContext sessionContext) {
|
||||
SnmpDeviceTransportConfiguration deviceTransportConfiguration = sessionContext.getDeviceTransportConfiguration();
|
||||
if (deviceTransportConfiguration.getProtocolVersion() == SnmpProtocolVersion.V3) {
|
||||
OctetString username = new OctetString(deviceTransportConfiguration.getUsername());
|
||||
OctetString engineId = new OctetString(deviceTransportConfiguration.getEngineId());
|
||||
snmpTransportService.getSnmp().getUSM().removeAllUsers(username, engineId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,9 +15,9 @@
|
||||
*/
|
||||
package org.thingsboard.server.transport.snmp;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
@ -61,18 +61,18 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class SnmpTransportContext extends TransportContext {
|
||||
@Getter
|
||||
private final SnmpTransportService snmpTransportService;
|
||||
private final TransportDeviceProfileCache deviceProfileCache;
|
||||
private final TransportService transportService;
|
||||
private final ProtoTransportEntityService protoEntityService;
|
||||
private final SnmpTransportBalancingService balancingService;
|
||||
@Getter
|
||||
private final SnmpAuthService snmpAuthService;
|
||||
|
||||
private final Map<DeviceId, DeviceSessionContext> sessions = new ConcurrentHashMap<>();
|
||||
private Collection<DeviceId> allSnmpDevicesIds = new ConcurrentLinkedDeque<>();
|
||||
|
||||
@Value("${transport.snmp.underlying_protocol}")
|
||||
private String snmpUnderlyingProtocol;
|
||||
|
||||
@AfterStartUp(order = 2)
|
||||
public void initDevicesSessions() {
|
||||
log.info("Initializing SNMP devices sessions");
|
||||
@ -116,8 +116,7 @@ public class SnmpTransportContext extends TransportContext {
|
||||
|
||||
DeviceSessionContext deviceSessionContext = new DeviceSessionContext(
|
||||
device, deviceProfile, credentials.getCredentialsId(),
|
||||
profileTransportConfiguration, deviceTransportConfiguration,
|
||||
this, snmpTransportService, snmpUnderlyingProtocol
|
||||
profileTransportConfiguration, deviceTransportConfiguration, this
|
||||
);
|
||||
registerSessionMsgListener(deviceSessionContext);
|
||||
sessions.put(device.getId(), deviceSessionContext);
|
||||
@ -155,6 +154,7 @@ public class SnmpTransportContext extends TransportContext {
|
||||
if (sessionContext == null) return;
|
||||
log.info("Destroying SNMP device session for device {}", sessionContext.getDevice().getId());
|
||||
sessionContext.close();
|
||||
snmpAuthService.cleanUpSnmpAuthInfo(sessionContext);
|
||||
transportService.deregisterSession(sessionContext.getSessionInfo());
|
||||
sessions.remove(sessionContext.getDeviceId());
|
||||
snmpTransportService.cancelQueryingTasks(sessionContext);
|
||||
|
||||
@ -19,29 +19,31 @@ import com.google.gson.JsonObject;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.snmp4j.CommandResponder;
|
||||
import org.snmp4j.CommandResponderEvent;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.ScopedPDU;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.TransportMapping;
|
||||
import org.snmp4j.event.ResponseEvent;
|
||||
import org.snmp4j.mp.MPv3;
|
||||
import org.snmp4j.security.SecurityModels;
|
||||
import org.snmp4j.security.SecurityProtocols;
|
||||
import org.snmp4j.security.USM;
|
||||
import org.snmp4j.smi.Null;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
import org.snmp4j.smi.TcpAddress;
|
||||
import org.snmp4j.smi.UdpAddress;
|
||||
import org.snmp4j.smi.VariableBinding;
|
||||
import org.snmp4j.transport.DefaultTcpTransportMapping;
|
||||
import org.snmp4j.transport.DefaultUdpTransportMapping;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.common.util.ThingsBoardThreadFactory;
|
||||
import org.thingsboard.server.common.data.TbTransportService;
|
||||
import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||
import org.thingsboard.server.common.data.kv.DataType;
|
||||
import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec;
|
||||
import org.thingsboard.server.common.data.transport.snmp.SnmpMapping;
|
||||
import org.thingsboard.server.common.data.transport.snmp.SnmpProtocolVersion;
|
||||
import org.thingsboard.server.common.data.transport.snmp.configs.RepeatingQueryingSnmpCommunicationConfig;
|
||||
import org.thingsboard.server.common.data.transport.snmp.configs.SnmpCommunicationConfig;
|
||||
import org.thingsboard.server.common.transport.TransportService;
|
||||
@ -49,12 +51,12 @@ import org.thingsboard.server.common.transport.TransportServiceCallback;
|
||||
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||
import org.thingsboard.server.queue.util.TbSnmpTransportComponent;
|
||||
import org.thingsboard.server.transport.snmp.SnmpTransportContext;
|
||||
import org.thingsboard.server.transport.snmp.session.DeviceSessionContext;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -67,13 +69,11 @@ import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@TbSnmpTransportComponent
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SnmpTransportService implements TbTransportService, CommandResponder {
|
||||
private final SnmpTransportContext snmpTransportContext;
|
||||
public class SnmpTransportService implements TbTransportService {
|
||||
private final TransportService transportService;
|
||||
|
||||
@Getter
|
||||
@ -88,9 +88,7 @@ public class SnmpTransportService implements TbTransportService, CommandResponde
|
||||
@Value("${transport.snmp.underlying_protocol}")
|
||||
private String snmpUnderlyingProtocol;
|
||||
|
||||
public SnmpTransportService(@Lazy SnmpTransportContext snmpTransportContext,
|
||||
TransportService transportService) {
|
||||
this.snmpTransportContext = snmpTransportContext;
|
||||
public SnmpTransportService(TransportService transportService) {
|
||||
this.transportService = transportService;
|
||||
}
|
||||
|
||||
@ -102,7 +100,6 @@ public class SnmpTransportService implements TbTransportService, CommandResponde
|
||||
responseProcessingExecutor = Executors.newWorkStealingPool(responseProcessingParallelismLevel);
|
||||
|
||||
initializeSnmp();
|
||||
initializeTrapsListener();
|
||||
configureResponseProcessors();
|
||||
|
||||
log.info("SNMP transport service initialized");
|
||||
@ -122,29 +119,9 @@ public class SnmpTransportService implements TbTransportService, CommandResponde
|
||||
}
|
||||
snmp = new Snmp(transportMapping);
|
||||
snmp.listen();
|
||||
}
|
||||
|
||||
private void initializeTrapsListener() throws IOException {
|
||||
int trapsListeningPort = 1062;
|
||||
String bindingAddress = "0.0.0.0/" + trapsListeningPort;
|
||||
|
||||
TransportMapping<?> transportMapping;
|
||||
switch (snmpUnderlyingProtocol) {
|
||||
case "udp":
|
||||
transportMapping = new DefaultUdpTransportMapping(new UdpAddress(bindingAddress));
|
||||
break;
|
||||
case "tcp":
|
||||
transportMapping = new DefaultTcpTransportMapping(new TcpAddress(bindingAddress));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Underlying protocol " + snmpUnderlyingProtocol + " for SNMP is not supported");
|
||||
}
|
||||
|
||||
|
||||
Snmp trapsSnmp = new Snmp(transportMapping);
|
||||
trapsSnmp.addCommandResponder(this);
|
||||
|
||||
transportMapping.listen();
|
||||
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
|
||||
SecurityModels.getInstance().addSecurityModel(usm);
|
||||
}
|
||||
|
||||
public void createQueryingTasks(DeviceSessionContext sessionContext) {
|
||||
@ -177,12 +154,11 @@ public class SnmpTransportService implements TbTransportService, CommandResponde
|
||||
}
|
||||
|
||||
public void sendRequest(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig) throws IOException {
|
||||
PDU request = createPdu(communicationConfig);
|
||||
executeRequest(sessionContext, request);
|
||||
sendRequest(sessionContext, communicationConfig, Collections.emptyMap());
|
||||
}
|
||||
|
||||
public void sendRequest(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig, Map<String, String> values) throws IOException {
|
||||
PDU request = createPduWithValues(communicationConfig, values);
|
||||
PDU request = createPdu(sessionContext, communicationConfig, values);
|
||||
executeRequest(sessionContext, request);
|
||||
}
|
||||
|
||||
@ -193,45 +169,36 @@ public class SnmpTransportService implements TbTransportService, CommandResponde
|
||||
}
|
||||
}
|
||||
|
||||
private PDU createPdu(SnmpCommunicationConfig communicationConfig) {
|
||||
PDU pdu = new PDU();
|
||||
private PDU createPdu(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig, Map<String, String> values) {
|
||||
PDU pdu;
|
||||
SnmpDeviceTransportConfiguration deviceTransportConfiguration = sessionContext.getDeviceTransportConfiguration();
|
||||
SnmpProtocolVersion snmpVersion = deviceTransportConfiguration.getProtocolVersion();
|
||||
switch (snmpVersion) {
|
||||
case V1:
|
||||
case V2C:
|
||||
pdu = new PDU();
|
||||
break;
|
||||
case V3:
|
||||
ScopedPDU scopedPdu = new ScopedPDU();
|
||||
scopedPdu.setContextName(new OctetString(deviceTransportConfiguration.getContextName()));
|
||||
scopedPdu.setContextEngineID(new OctetString(deviceTransportConfiguration.getEngineId()));
|
||||
pdu = scopedPdu;
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("SNMP version " + snmpVersion + " is not supported");
|
||||
}
|
||||
|
||||
pdu.setType(communicationConfig.getMethod().getCode());
|
||||
pdu.addAll(communicationConfig.getMappings().stream()
|
||||
.map(mapping -> new VariableBinding(new OID(mapping.getOid())))
|
||||
.filter(mapping -> values.isEmpty() || values.containsKey(mapping.getKey()))
|
||||
.map(mapping -> Optional.ofNullable(values.get(mapping.getKey()))
|
||||
.map(value -> new VariableBinding(new OID(mapping.getOid()), new OctetString(values.get(mapping.getKey()))))
|
||||
.orElseGet(() -> new VariableBinding(new OID(mapping.getOid()))))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
return pdu;
|
||||
}
|
||||
|
||||
private PDU createPduWithValues(SnmpCommunicationConfig communicationConfig, Map<String, String> values) {
|
||||
PDU pdu = new PDU();
|
||||
pdu.setType(communicationConfig.getMethod().getCode());
|
||||
pdu.addAll(communicationConfig.getMappings().stream()
|
||||
.filter(mapping -> values.containsKey(mapping.getKey()))
|
||||
.map(mapping -> {
|
||||
String value = values.get(mapping.getKey());
|
||||
return new VariableBinding(new OID(mapping.getOid()), new OctetString(value));
|
||||
})
|
||||
.collect(Collectors.toList()));
|
||||
return pdu;
|
||||
}
|
||||
|
||||
|
||||
private void processTrap(CommandResponderEvent event) {
|
||||
if (event.getPDU().getType() != PDU.TRAP) return;
|
||||
|
||||
snmpTransportContext.getSessions().stream()
|
||||
.filter(sessionContext -> {
|
||||
// TODO: SNMP v3 support
|
||||
return sessionContext.getTarget().getSecurityName().equals(OctetString.fromByteArray(event.getSecurityName())) &&
|
||||
sessionContext.getTarget().getAddress().equals(event.getPeerAddress());
|
||||
})
|
||||
.findFirst()
|
||||
.ifPresentOrElse(sessionContext -> {
|
||||
responseProcessingExecutor.execute(() -> processResponse(sessionContext, event.getPDU()));
|
||||
}, () -> {
|
||||
log.debug("SNMP event is from unknown source: {}", event);
|
||||
});
|
||||
}
|
||||
|
||||
public void processResponseEvent(DeviceSessionContext sessionContext, ResponseEvent event) {
|
||||
((Snmp) event.getSource()).cancel(event.getRequest(), sessionContext);
|
||||
@ -243,7 +210,7 @@ public class SnmpTransportService implements TbTransportService, CommandResponde
|
||||
|
||||
PDU response = event.getResponse();
|
||||
if (response == null) {
|
||||
log.warn("No response from SNMP device {}, requestId: {}", sessionContext.getDeviceId(), event.getRequest().getRequestID());
|
||||
log.debug("No response from SNMP device {}, requestId: {}", sessionContext.getDeviceId(), event.getRequest().getRequestID());
|
||||
return;
|
||||
}
|
||||
DeviceProfileId deviceProfileId = (DeviceProfileId) event.getUserObject();
|
||||
@ -308,23 +275,17 @@ public class SnmpTransportService implements TbTransportService, CommandResponde
|
||||
}
|
||||
|
||||
private void configureResponseProcessors() {
|
||||
Stream.of(SnmpCommunicationSpec.TELEMETRY_QUERYING, SnmpCommunicationSpec.TELEMETRY_TRAPS_RECEIVING)
|
||||
.forEach(telemetrySpec -> {
|
||||
responseProcessors.put(telemetrySpec, (response, sessionContext) -> {
|
||||
TransportProtos.PostTelemetryMsg postTelemetryMsg = JsonConverter.convertToTelemetryProto(response);
|
||||
transportService.process(sessionContext.getSessionInfo(), postTelemetryMsg, TransportServiceCallback.EMPTY);
|
||||
log.debug("Posted telemetry for device {}: {}", sessionContext.getDeviceId(), response);
|
||||
});
|
||||
});
|
||||
responseProcessors.put(SnmpCommunicationSpec.TELEMETRY_QUERYING, (response, sessionContext) -> {
|
||||
TransportProtos.PostTelemetryMsg postTelemetryMsg = JsonConverter.convertToTelemetryProto(response);
|
||||
transportService.process(sessionContext.getSessionInfo(), postTelemetryMsg, TransportServiceCallback.EMPTY);
|
||||
log.debug("Posted telemetry for device {}: {}", sessionContext.getDeviceId(), response);
|
||||
});
|
||||
|
||||
Stream.of(SnmpCommunicationSpec.CLIENT_ATTRIBUTES_QUERYING, SnmpCommunicationSpec.CLIENT_ATTRIBUTES_TRAPS_RECEIVING)
|
||||
.forEach(clientAttributesSpec -> {
|
||||
responseProcessors.put(clientAttributesSpec, (response, sessionContext) -> {
|
||||
TransportProtos.PostAttributeMsg postAttributesMsg = JsonConverter.convertToAttributesProto(response);
|
||||
transportService.process(sessionContext.getSessionInfo(), postAttributesMsg, TransportServiceCallback.EMPTY);
|
||||
log.debug("Posted attributes for device {}: {}", sessionContext.getDeviceId(), response);
|
||||
});
|
||||
});
|
||||
responseProcessors.put(SnmpCommunicationSpec.CLIENT_ATTRIBUTES_QUERYING, (response, sessionContext) -> {
|
||||
TransportProtos.PostAttributeMsg postAttributesMsg = JsonConverter.convertToAttributesProto(response);
|
||||
transportService.process(sessionContext.getSessionInfo(), postAttributesMsg, TransportServiceCallback.EMPTY);
|
||||
log.debug("Posted attributes for device {}: {}", sessionContext.getDeviceId(), response);
|
||||
});
|
||||
}
|
||||
|
||||
private void reportActivity(TransportProtos.SessionInfoProto sessionInfo) {
|
||||
@ -353,11 +314,6 @@ public class SnmpTransportService implements TbTransportService, CommandResponde
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPdu(CommandResponderEvent event) {
|
||||
processTrap(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SNMP";
|
||||
|
||||
@ -18,29 +18,15 @@ package org.thingsboard.server.transport.snmp.session;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.snmp4j.AbstractTarget;
|
||||
import org.snmp4j.CommunityTarget;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.UserTarget;
|
||||
import org.snmp4j.event.ResponseEvent;
|
||||
import org.snmp4j.event.ResponseListener;
|
||||
import org.snmp4j.security.AuthSHA;
|
||||
import org.snmp4j.security.PrivDES;
|
||||
import org.snmp4j.security.SecurityLevel;
|
||||
import org.snmp4j.security.SecurityModel;
|
||||
import org.snmp4j.security.SecurityModels;
|
||||
import org.snmp4j.security.USM;
|
||||
import org.snmp4j.security.UsmUser;
|
||||
import org.snmp4j.smi.GenericAddress;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.id.DeviceId;
|
||||
import org.thingsboard.server.common.data.transport.snmp.SnmpCommunicationSpec;
|
||||
import org.thingsboard.server.common.data.transport.snmp.SnmpProtocolVersion;
|
||||
import org.thingsboard.server.common.transport.SessionMsgListener;
|
||||
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
|
||||
import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext;
|
||||
@ -50,6 +36,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponse
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotificationProto;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg;
|
||||
import org.thingsboard.server.transport.snmp.SnmpAuthService;
|
||||
import org.thingsboard.server.transport.snmp.SnmpTransportContext;
|
||||
import org.thingsboard.server.transport.snmp.service.SnmpTransportService;
|
||||
|
||||
@ -77,6 +64,7 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S
|
||||
|
||||
private final SnmpTransportContext snmpTransportContext;
|
||||
private final SnmpTransportService snmpTransportService;
|
||||
private final SnmpAuthService snmpAuthService;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ -84,7 +72,6 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S
|
||||
private final AtomicInteger msgIdSeq = new AtomicInteger(0);
|
||||
@Getter
|
||||
private boolean isActive = true;
|
||||
private final String snmpUnderlyingProtocol;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ -93,8 +80,7 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S
|
||||
public DeviceSessionContext(Device device, DeviceProfile deviceProfile, String token,
|
||||
SnmpDeviceProfileTransportConfiguration profileTransportConfiguration,
|
||||
SnmpDeviceTransportConfiguration deviceTransportConfiguration,
|
||||
SnmpTransportContext snmpTransportContext, SnmpTransportService snmpTransportService,
|
||||
String snmpUnderlyingProtocol) {
|
||||
SnmpTransportContext snmpTransportContext) {
|
||||
super(UUID.randomUUID());
|
||||
super.setDeviceId(device.getId());
|
||||
super.setDeviceProfile(deviceProfile);
|
||||
@ -102,12 +88,12 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S
|
||||
|
||||
this.token = token;
|
||||
this.snmpTransportContext = snmpTransportContext;
|
||||
this.snmpTransportService = snmpTransportService;
|
||||
this.snmpTransportService = snmpTransportContext.getSnmpTransportService();
|
||||
this.snmpAuthService = snmpTransportContext.getSnmpAuthService();
|
||||
|
||||
this.profileTransportConfiguration = profileTransportConfiguration;
|
||||
this.deviceTransportConfiguration = deviceTransportConfiguration;
|
||||
|
||||
this.snmpUnderlyingProtocol = snmpUnderlyingProtocol;
|
||||
initializeTarget(profileTransportConfiguration, deviceTransportConfiguration);
|
||||
}
|
||||
|
||||
@ -133,55 +119,7 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S
|
||||
|
||||
public void initializeTarget(SnmpDeviceProfileTransportConfiguration profileTransportConfig, SnmpDeviceTransportConfiguration deviceTransportConfig) {
|
||||
log.trace("Initializing target for SNMP session of device {}", device);
|
||||
|
||||
AbstractTarget target;
|
||||
|
||||
SnmpProtocolVersion protocolVersion = deviceTransportConfig.getProtocolVersion();
|
||||
switch (protocolVersion) {
|
||||
case V1:
|
||||
CommunityTarget communityTargetV1 = new CommunityTarget();
|
||||
communityTargetV1.setSecurityModel(SecurityModel.SECURITY_MODEL_SNMPv1);
|
||||
communityTargetV1.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV);
|
||||
communityTargetV1.setCommunity(new OctetString(deviceTransportConfig.getSecurityName()));
|
||||
target = communityTargetV1;
|
||||
break;
|
||||
case V2C:
|
||||
CommunityTarget communityTargetV2 = new CommunityTarget();
|
||||
communityTargetV2.setSecurityModel(SecurityModel.SECURITY_MODEL_SNMPv2c);
|
||||
communityTargetV2.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV);
|
||||
communityTargetV2.setCommunity(new OctetString(deviceTransportConfig.getSecurityName()));
|
||||
target = communityTargetV2;
|
||||
break;
|
||||
case V3:
|
||||
USM usm = new USM();
|
||||
SecurityModels.getInstance().addSecurityModel(usm);
|
||||
|
||||
OctetString securityName = new OctetString(deviceTransportConfig.getSecurityName());
|
||||
OctetString authenticationPassphrase = new OctetString(deviceTransportConfig.getAuthenticationPassphrase());
|
||||
OctetString privacyPassphrase = new OctetString(deviceTransportConfig.getPrivacyPassphrase());
|
||||
|
||||
OID authenticationProtocol = AuthSHA.ID;
|
||||
OID privacyProtocol = PrivDES.ID; // FIXME: to config
|
||||
|
||||
UsmUser user = new UsmUser(securityName, authenticationProtocol, authenticationPassphrase, privacyProtocol, privacyPassphrase);
|
||||
snmpTransportService.getSnmp().getUSM().addUser(user);
|
||||
|
||||
UserTarget userTarget = new UserTarget();
|
||||
userTarget.setSecurityName(securityName);
|
||||
userTarget.setSecurityLevel(SecurityLevel.AUTH_PRIV);
|
||||
|
||||
target = userTarget;
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("SNMP protocol version " + protocolVersion + " is not supported");
|
||||
}
|
||||
|
||||
target.setAddress(GenericAddress.parse(snmpUnderlyingProtocol + ":" + deviceTransportConfig.getAddress() + "/" + deviceTransportConfig.getPort()));
|
||||
target.setTimeout(profileTransportConfig.getTimeoutMs());
|
||||
target.setRetries(profileTransportConfig.getRetries());
|
||||
target.setVersion(protocolVersion.getCode());
|
||||
|
||||
this.target = target;
|
||||
this.target = snmpAuthService.setUpSnmpTarget(profileTransportConfig, deviceTransportConfig);
|
||||
log.info("SNMP target initialized: {}", target);
|
||||
}
|
||||
|
||||
|
||||
@ -73,32 +73,6 @@ public class SnmpDeviceSimulatorV2 extends BaseAgent {
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
SnmpDeviceSimulatorV2 device = new SnmpDeviceSimulatorV2(1610, "public");
|
||||
|
||||
device.start();
|
||||
device.setUpMappings(Map.of(
|
||||
".1.3.6.1.2.1.1.1.50", "12",
|
||||
".1.3.6.1.2.1.2.1.52", "56",
|
||||
".1.3.6.1.2.1.3.1.54", "yes",
|
||||
".1.3.6.1.2.1.7.1.58", ""
|
||||
));
|
||||
|
||||
|
||||
// while (true) {
|
||||
// new Scanner(System.in).nextLine();
|
||||
// device.sendTrap("127.0.0.1", 1062, Map.of(".1.3.6.1.2.87.1.56", "12"));
|
||||
// System.out.println("sent");
|
||||
// }
|
||||
|
||||
// Snmp snmp = new Snmp(device.transportMappings[0]);
|
||||
// device.snmp.addCommandResponder(event -> {
|
||||
// System.out.println(event);
|
||||
// });
|
||||
|
||||
new Scanner(System.in).nextLine();
|
||||
}
|
||||
|
||||
|
||||
private final Target target;
|
||||
private final Address address;
|
||||
|
||||
@ -15,38 +15,731 @@
|
||||
*/
|
||||
package org.thingsboard.server.transport.snmp;
|
||||
|
||||
import org.snmp4j.UserTarget;
|
||||
import org.snmp4j.MessageDispatcherImpl;
|
||||
import org.snmp4j.TransportMapping;
|
||||
import org.snmp4j.agent.BaseAgent;
|
||||
import org.snmp4j.agent.CommandProcessor;
|
||||
import org.snmp4j.agent.DuplicateRegistrationException;
|
||||
import org.snmp4j.agent.MOGroup;
|
||||
import org.snmp4j.agent.ManagedObject;
|
||||
import org.snmp4j.agent.mo.DefaultMOMutableRow2PC;
|
||||
import org.snmp4j.agent.mo.DefaultMOTable;
|
||||
import org.snmp4j.agent.mo.MOAccessImpl;
|
||||
import org.snmp4j.agent.mo.MOColumn;
|
||||
import org.snmp4j.agent.mo.MOMutableColumn;
|
||||
import org.snmp4j.agent.mo.MOMutableTableModel;
|
||||
import org.snmp4j.agent.mo.MOScalar;
|
||||
import org.snmp4j.agent.mo.MOTableIndex;
|
||||
import org.snmp4j.agent.mo.MOTableRow;
|
||||
import org.snmp4j.agent.mo.MOTableSubIndex;
|
||||
import org.snmp4j.agent.mo.ext.AgentppSimulationMib;
|
||||
import org.snmp4j.agent.mo.snmp.RowStatus;
|
||||
import org.snmp4j.agent.mo.snmp.SnmpCommunityMIB;
|
||||
import org.snmp4j.agent.mo.snmp.SnmpNotificationMIB;
|
||||
import org.snmp4j.agent.mo.snmp.SnmpTargetMIB;
|
||||
import org.snmp4j.agent.mo.snmp.StorageType;
|
||||
import org.snmp4j.agent.mo.snmp.TransportDomains;
|
||||
import org.snmp4j.agent.mo.snmp.VacmMIB;
|
||||
import org.snmp4j.agent.mo.snmp4j.example.Snmp4jHeartbeatMib;
|
||||
import org.snmp4j.agent.security.MutableVACM;
|
||||
import org.snmp4j.mp.MPv1;
|
||||
import org.snmp4j.mp.MPv2c;
|
||||
import org.snmp4j.mp.MPv3;
|
||||
import org.snmp4j.mp.MessageProcessingModel;
|
||||
import org.snmp4j.security.AuthHMAC192SHA256;
|
||||
import org.snmp4j.security.AuthMD5;
|
||||
import org.snmp4j.security.AuthSHA;
|
||||
import org.snmp4j.security.PrivAES128;
|
||||
import org.snmp4j.security.PrivAES192;
|
||||
import org.snmp4j.security.PrivAES256;
|
||||
import org.snmp4j.security.PrivDES;
|
||||
import org.snmp4j.security.SecurityLevel;
|
||||
import org.snmp4j.security.SecurityModel;
|
||||
import org.snmp4j.security.SecurityModels;
|
||||
import org.snmp4j.security.SecurityProtocols;
|
||||
import org.snmp4j.security.USM;
|
||||
import org.snmp4j.security.UsmUser;
|
||||
import org.snmp4j.smi.Address;
|
||||
import org.snmp4j.smi.Gauge32;
|
||||
import org.snmp4j.smi.GenericAddress;
|
||||
import org.snmp4j.smi.Integer32;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
import org.snmp4j.smi.SMIConstants;
|
||||
import org.snmp4j.smi.TcpAddress;
|
||||
import org.snmp4j.smi.TimeTicks;
|
||||
import org.snmp4j.smi.UdpAddress;
|
||||
import org.snmp4j.smi.Variable;
|
||||
import org.snmp4j.transport.DefaultTcpTransportMapping;
|
||||
import org.snmp4j.transport.TransportMappings;
|
||||
import org.snmp4j.util.ThreadPool;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
public class SnmpDeviceSimulatorV3 extends SnmpDeviceSimulatorV2 {
|
||||
public SnmpDeviceSimulatorV3(int port, String securityName, String authenticationPassphrase, String privacyPassphrase) throws IOException {
|
||||
super(12, null);
|
||||
// super(new File("conf.agent"), new File("bootCounter.agent"));
|
||||
/**
|
||||
* The TestAgent is a sample SNMP agent implementation of all
|
||||
* features (MIB implementations) provided by the SNMP4J-Agent framework.
|
||||
*
|
||||
* Note, for snmp4s, this code is mostly a copy from snmp4j.
|
||||
* And don't remove snmp users
|
||||
*
|
||||
*/
|
||||
public class SnmpDeviceSimulatorV3 extends BaseAgent {
|
||||
protected String address;
|
||||
private Snmp4jHeartbeatMib heartbeatMIB;
|
||||
private AgentppSimulationMib agentppSimulationMIB;
|
||||
|
||||
USM usm = new USM();
|
||||
SecurityModels.getInstance().addSecurityModel(usm);
|
||||
public SnmpDeviceSimulatorV3(CommandProcessor processor) throws IOException {
|
||||
super(new File("SNMP4JTestAgentBC.cfg"), new File("SNMP4JTestAgentConfig.cfg"),
|
||||
processor);
|
||||
agent.setWorkerPool(ThreadPool.create("RequestPool", 4));
|
||||
}
|
||||
|
||||
public void setUpMappings(Map<String, String> oidToResponseMappings) {
|
||||
unregisterManagedObject(getSnmpv2MIB());
|
||||
oidToResponseMappings.forEach((oid, response) -> {
|
||||
registerManagedObject(new MOScalar<>(new OID(oid), MOAccessImpl.ACCESS_READ_WRITE, new OctetString(response)));
|
||||
});
|
||||
}
|
||||
protected void registerManagedObject(ManagedObject mo) {
|
||||
try {
|
||||
server.register(mo, null);
|
||||
} catch (DuplicateRegistrationException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected void unregisterManagedObject(MOGroup moGroup) {
|
||||
moGroup.unregisterMOs(server, getContext(moGroup));
|
||||
}
|
||||
|
||||
protected void registerManagedObjects() {
|
||||
try {
|
||||
server.register(createStaticIfTable(), null);
|
||||
server.register(createStaticIfXTable(), null);
|
||||
agentppSimulationMIB.registerMOs(server, null);
|
||||
heartbeatMIB.registerMOs(server, null);
|
||||
} catch (DuplicateRegistrationException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected void addNotificationTargets(SnmpTargetMIB targetMIB,
|
||||
SnmpNotificationMIB notificationMIB) {
|
||||
targetMIB.addDefaultTDomains();
|
||||
|
||||
targetMIB.addTargetAddress(new OctetString("notificationV2c"),
|
||||
TransportDomains.transportDomainUdpIpv4,
|
||||
new OctetString(new UdpAddress("127.0.0.1/162").getValue()),
|
||||
200, 1,
|
||||
new OctetString("notify"),
|
||||
new OctetString("v2c"),
|
||||
StorageType.permanent);
|
||||
targetMIB.addTargetAddress(new OctetString("notificationV3"),
|
||||
TransportDomains.transportDomainUdpIpv4,
|
||||
new OctetString(new UdpAddress("127.0.0.1/1162").getValue()),
|
||||
200, 1,
|
||||
new OctetString("notify"),
|
||||
new OctetString("v3notify"),
|
||||
StorageType.permanent);
|
||||
targetMIB.addTargetParams(new OctetString("v2c"),
|
||||
MessageProcessingModel.MPv2c,
|
||||
SecurityModel.SECURITY_MODEL_SNMPv2c,
|
||||
new OctetString("cpublic"),
|
||||
SecurityLevel.AUTH_PRIV,
|
||||
StorageType.permanent);
|
||||
targetMIB.addTargetParams(new OctetString("v3notify"),
|
||||
MessageProcessingModel.MPv3,
|
||||
SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("v3notify"),
|
||||
SecurityLevel.NOAUTH_NOPRIV,
|
||||
StorageType.permanent);
|
||||
notificationMIB.addNotifyEntry(new OctetString("default"),
|
||||
new OctetString("notify"),
|
||||
SnmpNotificationMIB.SnmpNotifyTypeEnum.inform,
|
||||
StorageType.permanent);
|
||||
}
|
||||
protected void addViews(VacmMIB vacm) {
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_SNMPv1,
|
||||
new OctetString("cpublic"),
|
||||
new OctetString("v1v2group"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_SNMPv2c,
|
||||
new OctetString("cpublic"),
|
||||
new OctetString("v1v2group"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("SHADES"),
|
||||
new OctetString("v3group"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("MD5DES"),
|
||||
new OctetString("v3group"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("TEST"),
|
||||
new OctetString("v3test"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("SHA"),
|
||||
new OctetString("v3restricted"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("SHAAES128"),
|
||||
new OctetString("v3group"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("SHAAES192"),
|
||||
new OctetString("v3group"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("SHAAES256"),
|
||||
new OctetString("v3group"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("MD5AES128"),
|
||||
new OctetString("v3group"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("MD5AES192"),
|
||||
new OctetString("v3group"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("MD5AES256"),
|
||||
new OctetString("v3group"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("aboba"),
|
||||
new OctetString("v3group"),
|
||||
StorageType.nonVolatile);
|
||||
//============================================//
|
||||
// agent5-auth-priv
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("agent5"),
|
||||
new OctetString("v3group"),
|
||||
StorageType.nonVolatile);
|
||||
//===========================================//
|
||||
// agent002
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("agent002"),
|
||||
new OctetString("v3group"),
|
||||
StorageType.nonVolatile);
|
||||
//===========================================//
|
||||
// user001-auth-no-priv
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("user001"),
|
||||
new OctetString("group001"),
|
||||
StorageType.nonVolatile);
|
||||
//===========================================//
|
||||
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("v3notify"),
|
||||
new OctetString("v3group"),
|
||||
StorageType.nonVolatile);
|
||||
|
||||
//===========================================//
|
||||
// group auth no priv
|
||||
vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
|
||||
new OctetString("v3notify-auth"),
|
||||
new OctetString("group001"),
|
||||
StorageType.nonVolatile);
|
||||
//===========================================//
|
||||
|
||||
|
||||
|
||||
// my conf
|
||||
vacm.addAccess(new OctetString("group001"), new OctetString("public"),
|
||||
SecurityModel.SECURITY_MODEL_USM,
|
||||
SecurityLevel.AUTH_NOPRIV,
|
||||
MutableVACM.VACM_MATCH_EXACT,
|
||||
new OctetString("fullReadView"),
|
||||
new OctetString("fullWriteView"),
|
||||
new OctetString("fullNotifyView"),
|
||||
StorageType.nonVolatile);
|
||||
|
||||
vacm.addAccess(new OctetString("v1v2group"), new OctetString("public"),
|
||||
SecurityModel.SECURITY_MODEL_ANY,
|
||||
SecurityLevel.NOAUTH_NOPRIV,
|
||||
MutableVACM.VACM_MATCH_EXACT,
|
||||
new OctetString("fullReadView"),
|
||||
new OctetString("fullWriteView"),
|
||||
new OctetString("fullNotifyView"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addAccess(new OctetString("v3group"), new OctetString(),
|
||||
SecurityModel.SECURITY_MODEL_USM,
|
||||
SecurityLevel.AUTH_PRIV,
|
||||
MutableVACM.VACM_MATCH_EXACT,
|
||||
new OctetString("fullReadView"),
|
||||
new OctetString("fullWriteView"),
|
||||
new OctetString("fullNotifyView"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addAccess(new OctetString("v3restricted"), new OctetString(),
|
||||
SecurityModel.SECURITY_MODEL_USM,
|
||||
SecurityLevel.NOAUTH_NOPRIV,
|
||||
MutableVACM.VACM_MATCH_EXACT,
|
||||
new OctetString("restrictedReadView"),
|
||||
new OctetString("restrictedWriteView"),
|
||||
new OctetString("restrictedNotifyView"),
|
||||
StorageType.nonVolatile);
|
||||
vacm.addAccess(new OctetString("v3test"), new OctetString(),
|
||||
SecurityModel.SECURITY_MODEL_USM,
|
||||
SecurityLevel.AUTH_PRIV,
|
||||
MutableVACM.VACM_MATCH_EXACT,
|
||||
new OctetString("testReadView"),
|
||||
new OctetString("testWriteView"),
|
||||
new OctetString("testNotifyView"),
|
||||
StorageType.nonVolatile);
|
||||
|
||||
vacm.addViewTreeFamily(new OctetString("fullReadView"), new OID("1.3"),
|
||||
new OctetString(), VacmMIB.vacmViewIncluded,
|
||||
StorageType.nonVolatile);
|
||||
vacm.addViewTreeFamily(new OctetString("fullWriteView"), new OID("1.3"),
|
||||
new OctetString(), VacmMIB.vacmViewIncluded,
|
||||
StorageType.nonVolatile);
|
||||
vacm.addViewTreeFamily(new OctetString("fullNotifyView"), new OID("1.3"),
|
||||
new OctetString(), VacmMIB.vacmViewIncluded,
|
||||
StorageType.nonVolatile);
|
||||
|
||||
vacm.addViewTreeFamily(new OctetString("restrictedReadView"),
|
||||
new OID("1.3.6.1.2"),
|
||||
new OctetString(), VacmMIB.vacmViewIncluded,
|
||||
StorageType.nonVolatile);
|
||||
vacm.addViewTreeFamily(new OctetString("restrictedWriteView"),
|
||||
new OID("1.3.6.1.2.1"),
|
||||
new OctetString(),
|
||||
VacmMIB.vacmViewIncluded,
|
||||
StorageType.nonVolatile);
|
||||
vacm.addViewTreeFamily(new OctetString("restrictedNotifyView"),
|
||||
new OID("1.3.6.1.2"),
|
||||
new OctetString(), VacmMIB.vacmViewIncluded,
|
||||
StorageType.nonVolatile);
|
||||
vacm.addViewTreeFamily(new OctetString("restrictedNotifyView"),
|
||||
new OID("1.3.6.1.6.3.1"),
|
||||
new OctetString(), VacmMIB.vacmViewIncluded,
|
||||
StorageType.nonVolatile);
|
||||
|
||||
vacm.addViewTreeFamily(new OctetString("testReadView"),
|
||||
new OID("1.3.6.1.2"),
|
||||
new OctetString(), VacmMIB.vacmViewIncluded,
|
||||
StorageType.nonVolatile);
|
||||
vacm.addViewTreeFamily(new OctetString("testReadView"),
|
||||
new OID("1.3.6.1.2.1.1"),
|
||||
new OctetString(), VacmMIB.vacmViewExcluded,
|
||||
StorageType.nonVolatile);
|
||||
vacm.addViewTreeFamily(new OctetString("testWriteView"),
|
||||
new OID("1.3.6.1.2.1"),
|
||||
new OctetString(),
|
||||
VacmMIB.vacmViewIncluded,
|
||||
StorageType.nonVolatile);
|
||||
vacm.addViewTreeFamily(new OctetString("testNotifyView"),
|
||||
new OID("1.3.6.1.2"),
|
||||
new OctetString(), VacmMIB.vacmViewIncluded,
|
||||
StorageType.nonVolatile);
|
||||
|
||||
}
|
||||
|
||||
protected void addUsmUser(USM usm) {
|
||||
UsmUser user = new UsmUser(new OctetString("SHADES"),
|
||||
AuthSHA.ID,
|
||||
new OctetString("SHADESAuthPassword"),
|
||||
PrivDES.ID,
|
||||
new OctetString("SHADESPrivPassword"));
|
||||
// usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
usm.addUser(user.getSecurityName(), null, user);
|
||||
user = new UsmUser(new OctetString("TEST"),
|
||||
AuthSHA.ID,
|
||||
new OctetString("maplesyrup"),
|
||||
PrivDES.ID,
|
||||
new OctetString("maplesyrup"));
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
user = new UsmUser(new OctetString("SHA"),
|
||||
AuthSHA.ID,
|
||||
new OctetString("SHAAuthPassword"),
|
||||
null,
|
||||
null);
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
user = new UsmUser(new OctetString("SHADES"),
|
||||
AuthSHA.ID,
|
||||
new OctetString("SHADESAuthPassword"),
|
||||
PrivDES.ID,
|
||||
new OctetString("SHADESPrivPassword"));
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
user = new UsmUser(new OctetString("MD5DES"),
|
||||
AuthMD5.ID,
|
||||
new OctetString("MD5DESAuthPassword"),
|
||||
PrivDES.ID,
|
||||
new OctetString("MD5DESPrivPassword"));
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
user = new UsmUser(new OctetString("SHAAES128"),
|
||||
AuthSHA.ID,
|
||||
new OctetString("SHAAES128AuthPassword"),
|
||||
PrivAES128.ID,
|
||||
new OctetString("SHAAES128PrivPassword"));
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
user = new UsmUser(new OctetString("SHAAES192"),
|
||||
AuthSHA.ID,
|
||||
new OctetString("SHAAES192AuthPassword"),
|
||||
PrivAES192.ID,
|
||||
new OctetString("SHAAES192PrivPassword"));
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
user = new UsmUser(new OctetString("SHAAES256"),
|
||||
AuthSHA.ID,
|
||||
new OctetString("SHAAES256AuthPassword"),
|
||||
PrivAES256.ID,
|
||||
new OctetString("SHAAES256PrivPassword"));
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
|
||||
user = new UsmUser(new OctetString("MD5AES128"),
|
||||
AuthMD5.ID,
|
||||
new OctetString("MD5AES128AuthPassword"),
|
||||
PrivAES128.ID,
|
||||
new OctetString("MD5AES128PrivPassword"));
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
user = new UsmUser(new OctetString("MD5AES192"),
|
||||
AuthHMAC192SHA256.ID,
|
||||
new OctetString("MD5AES192AuthPassword"),
|
||||
PrivAES192.ID,
|
||||
new OctetString("MD5AES192PrivPassword"));
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
//==============================================================
|
||||
user = new UsmUser(new OctetString("MD5AES256"),
|
||||
AuthMD5.ID,
|
||||
new OctetString("MD5AES256AuthPassword"),
|
||||
PrivAES256.ID,
|
||||
new OctetString("MD5AES256PrivPassword"));
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
user = new UsmUser(new OctetString("MD5AES256"),
|
||||
AuthMD5.ID,
|
||||
new OctetString("MD5AES256AuthPassword"),
|
||||
PrivAES256.ID,
|
||||
new OctetString("MD5AES256PrivPassword"));
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
|
||||
OctetString securityName = new OctetString("aboba");
|
||||
OctetString authenticationPassphrase = new OctetString("abobaaboba");
|
||||
OctetString privacyPassphrase = new OctetString("abobaaboba");
|
||||
OID authenticationProtocol = AuthSHA.ID;
|
||||
OID privacyProtocol = PrivDES.ID;
|
||||
OID privacyProtocol = PrivDES.ID; // FIXME: to config
|
||||
user = new UsmUser(securityName, authenticationProtocol, authenticationPassphrase, privacyProtocol, privacyPassphrase);
|
||||
usm.addUser(user);
|
||||
|
||||
UsmUser user = new UsmUser(new OctetString(securityName), authenticationProtocol, new OctetString(authenticationPassphrase), privacyProtocol, new OctetString(privacyPassphrase));
|
||||
//===============================================================//
|
||||
user = new UsmUser(new OctetString("agent5"),
|
||||
AuthSHA.ID,
|
||||
new OctetString("authpass"),
|
||||
PrivDES.ID,
|
||||
new OctetString("privpass"));
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
//===============================================================//
|
||||
// user001
|
||||
user = new UsmUser(new OctetString("user001"),
|
||||
AuthSHA.ID,
|
||||
new OctetString("authpass"),
|
||||
null, null);
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
//===============================================================//
|
||||
// user002
|
||||
user = new UsmUser(new OctetString("user001"),
|
||||
null,
|
||||
null,
|
||||
null, null);
|
||||
usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
|
||||
//===============================================================//
|
||||
|
||||
user = new UsmUser(new OctetString("v3notify"),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
usm.addUser(user.getSecurityName(), null, user);
|
||||
|
||||
this.usm = usm;
|
||||
}
|
||||
|
||||
public void initV3(UsmUser user, String securityName) {
|
||||
// snmp.getUSM().addUser(user);
|
||||
private static DefaultMOTable createStaticIfXTable() {
|
||||
MOTableSubIndex[] subIndexes =
|
||||
new MOTableSubIndex[] { new MOTableSubIndex(SMIConstants.SYNTAX_INTEGER) };
|
||||
MOTableIndex indexDef = new MOTableIndex(subIndexes, false);
|
||||
MOColumn[] columns = new MOColumn[19];
|
||||
int c = 0;
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_OCTET_STRING,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifName
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_COUNTER32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifInMulticastPkts
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_COUNTER32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifInBroadcastPkts
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_COUNTER32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifOutMulticastPkts
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_COUNTER32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifOutBroadcastPkts
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_COUNTER32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifHCInOctets
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_COUNTER32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifHCInUcastPkts
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_COUNTER32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifHCInMulticastPkts
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_COUNTER32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifHCInBroadcastPkts
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_COUNTER32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifHCOutOctets
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_COUNTER32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifHCOutUcastPkts
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_COUNTER32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifHCOutMulticastPkts
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_COUNTER32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifHCOutBroadcastPkts
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_INTEGER,
|
||||
MOAccessImpl.ACCESS_READ_WRITE); // ifLinkUpDownTrapEnable
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_GAUGE32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifHighSpeed
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_INTEGER,
|
||||
MOAccessImpl.ACCESS_READ_WRITE); // ifPromiscuousMode
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_INTEGER,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifConnectorPresent
|
||||
columns[c++] =
|
||||
new MOMutableColumn(c, SMIConstants.SYNTAX_OCTET_STRING, // ifAlias
|
||||
MOAccessImpl.ACCESS_READ_WRITE, null);
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_TIMETICKS,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifCounterDiscontinuityTime
|
||||
|
||||
UserTarget userTarget = new UserTarget();
|
||||
userTarget.setSecurityName(new OctetString(securityName));
|
||||
userTarget.setSecurityLevel(SecurityLevel.AUTH_PRIV);
|
||||
DefaultMOTable ifXTable =
|
||||
new DefaultMOTable(new OID("1.3.6.1.2.1.31.1.1.1"), indexDef, columns);
|
||||
MOMutableTableModel model = (MOMutableTableModel) ifXTable.getModel();
|
||||
Variable[] rowValues1 = new Variable[] {
|
||||
new OctetString("Ethernet-0"),
|
||||
new Integer32(1),
|
||||
new Integer32(2),
|
||||
new Integer32(3),
|
||||
new Integer32(4),
|
||||
new Integer32(5),
|
||||
new Integer32(6),
|
||||
new Integer32(7),
|
||||
new Integer32(8),
|
||||
new Integer32(9),
|
||||
new Integer32(10),
|
||||
new Integer32(11),
|
||||
new Integer32(12),
|
||||
new Integer32(13),
|
||||
new Integer32(14),
|
||||
new Integer32(15),
|
||||
new Integer32(16),
|
||||
new OctetString("My eth"),
|
||||
new TimeTicks(1000)
|
||||
};
|
||||
Variable[] rowValues2 = new Variable[] {
|
||||
new OctetString("Loopback"),
|
||||
new Integer32(21),
|
||||
new Integer32(22),
|
||||
new Integer32(23),
|
||||
new Integer32(24),
|
||||
new Integer32(25),
|
||||
new Integer32(26),
|
||||
new Integer32(27),
|
||||
new Integer32(28),
|
||||
new Integer32(29),
|
||||
new Integer32(30),
|
||||
new Integer32(31),
|
||||
new Integer32(32),
|
||||
new Integer32(33),
|
||||
new Integer32(34),
|
||||
new Integer32(35),
|
||||
new Integer32(36),
|
||||
new OctetString("My loop"),
|
||||
new TimeTicks(2000)
|
||||
};
|
||||
model.addRow(new DefaultMOMutableRow2PC(new OID("1"), rowValues1));
|
||||
model.addRow(new DefaultMOMutableRow2PC(new OID("2"), rowValues2));
|
||||
ifXTable.setVolatile(true);
|
||||
return ifXTable;
|
||||
}
|
||||
|
||||
}
|
||||
private static DefaultMOTable createStaticIfTable() {
|
||||
MOTableSubIndex[] subIndexes =
|
||||
new MOTableSubIndex[] { new MOTableSubIndex(SMIConstants.SYNTAX_INTEGER) };
|
||||
MOTableIndex indexDef = new MOTableIndex(subIndexes, false);
|
||||
MOColumn[] columns = new MOColumn[8];
|
||||
int c = 0;
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_INTEGER,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifIndex
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_OCTET_STRING,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifDescr
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_INTEGER,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifType
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_INTEGER,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifMtu
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_GAUGE32,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifSpeed
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_OCTET_STRING,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifPhysAddress
|
||||
columns[c++] =
|
||||
new MOMutableColumn(c, SMIConstants.SYNTAX_INTEGER, // ifAdminStatus
|
||||
MOAccessImpl.ACCESS_READ_WRITE, null);
|
||||
columns[c++] =
|
||||
new MOColumn(c, SMIConstants.SYNTAX_INTEGER,
|
||||
MOAccessImpl.ACCESS_READ_ONLY); // ifOperStatus
|
||||
|
||||
DefaultMOTable ifTable =
|
||||
new DefaultMOTable(new OID("1.3.6.1.2.1.2.2.1"), indexDef, columns);
|
||||
MOMutableTableModel model = (MOMutableTableModel) ifTable.getModel();
|
||||
Variable[] rowValues1 = new Variable[] {
|
||||
new Integer32(1),
|
||||
new OctetString("eth0"),
|
||||
new Integer32(6),
|
||||
new Integer32(1500),
|
||||
new Gauge32(100000000),
|
||||
new OctetString("00:00:00:00:01"),
|
||||
new Integer32(1),
|
||||
new Integer32(1)
|
||||
};
|
||||
Variable[] rowValues2 = new Variable[] {
|
||||
new Integer32(2),
|
||||
new OctetString("loopback"),
|
||||
new Integer32(24),
|
||||
new Integer32(1500),
|
||||
new Gauge32(10000000),
|
||||
new OctetString("00:00:00:00:02"),
|
||||
new Integer32(1),
|
||||
new Integer32(1)
|
||||
};
|
||||
model.addRow(new DefaultMOMutableRow2PC(new OID("1"), rowValues1));
|
||||
model.addRow(new DefaultMOMutableRow2PC(new OID("2"), rowValues2));
|
||||
ifTable.setVolatile(true);
|
||||
return ifTable;
|
||||
}
|
||||
|
||||
private static DefaultMOTable createStaticSnmp4sTable() {
|
||||
MOTableSubIndex[] subIndexes =
|
||||
new MOTableSubIndex[] { new MOTableSubIndex(SMIConstants.SYNTAX_INTEGER) };
|
||||
MOTableIndex indexDef = new MOTableIndex(subIndexes, false);
|
||||
MOColumn[] columns = new MOColumn[8];
|
||||
int c = 0;
|
||||
columns[c++] = new MOColumn(c, SMIConstants.SYNTAX_NULL, MOAccessImpl.ACCESS_READ_ONLY); // testNull
|
||||
columns[c++] = new MOColumn(c, SMIConstants.SYNTAX_INTEGER, MOAccessImpl.ACCESS_READ_ONLY); // testBoolean
|
||||
columns[c++] = new MOColumn(c, SMIConstants.SYNTAX_INTEGER, MOAccessImpl.ACCESS_READ_ONLY); // ifType
|
||||
columns[c++] = new MOColumn(c, SMIConstants.SYNTAX_INTEGER, MOAccessImpl.ACCESS_READ_ONLY); // ifMtu
|
||||
columns[c++] = new MOColumn(c, SMIConstants.SYNTAX_GAUGE32, MOAccessImpl.ACCESS_READ_ONLY); // ifSpeed
|
||||
columns[c++] = new MOColumn(c, SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY); //ifPhysAddress
|
||||
columns[c++] = new MOMutableColumn(c, SMIConstants.SYNTAX_INTEGER, MOAccessImpl.ACCESS_READ_WRITE,
|
||||
null);
|
||||
// ifAdminStatus
|
||||
columns[c++] = new MOColumn(c, SMIConstants.SYNTAX_INTEGER, MOAccessImpl.ACCESS_READ_ONLY);
|
||||
// ifOperStatus
|
||||
|
||||
DefaultMOTable ifTable =
|
||||
new DefaultMOTable(new OID("1.3.6.1.4.1.50000.1.1"), indexDef, columns);
|
||||
MOMutableTableModel model = (MOMutableTableModel) ifTable.getModel();
|
||||
Variable[] rowValues1 = new Variable[] {
|
||||
new Integer32(1),
|
||||
new OctetString("eth0"),
|
||||
new Integer32(6),
|
||||
new Integer32(1500),
|
||||
new Gauge32(100000000),
|
||||
new OctetString("00:00:00:00:01"),
|
||||
new Integer32(1),
|
||||
new Integer32(1)
|
||||
};
|
||||
Variable[] rowValues2 = new Variable[] {
|
||||
new Integer32(2),
|
||||
new OctetString("loopback"),
|
||||
new Integer32(24),
|
||||
new Integer32(1500),
|
||||
new Gauge32(10000000),
|
||||
new OctetString("00:00:00:00:02"),
|
||||
new Integer32(1),
|
||||
new Integer32(1)
|
||||
};
|
||||
model.addRow(new DefaultMOMutableRow2PC(new OID("1"), rowValues1));
|
||||
model.addRow(new DefaultMOMutableRow2PC(new OID("2"), rowValues2));
|
||||
ifTable.setVolatile(true);
|
||||
return ifTable;
|
||||
}
|
||||
|
||||
protected void initTransportMappings() throws IOException {
|
||||
transportMappings = new TransportMapping[2];
|
||||
Address addr = GenericAddress.parse(address);
|
||||
TransportMapping tm =
|
||||
TransportMappings.getInstance().createTransportMapping(addr);
|
||||
transportMappings[0] = tm;
|
||||
transportMappings[1] = new DefaultTcpTransportMapping(new TcpAddress(address));
|
||||
}
|
||||
|
||||
public void start(String ip, String port) throws IOException {
|
||||
address = ip + "/" + port;
|
||||
//BasicConfigurator.configure();
|
||||
init();
|
||||
addShutdownHook();
|
||||
// loadConfig(ImportModes.REPLACE_CREATE);
|
||||
getServer().addContext(new OctetString("public"));
|
||||
finishInit();
|
||||
run();
|
||||
sendColdStartNotification();
|
||||
}
|
||||
|
||||
protected void unregisterManagedObjects() {
|
||||
// here we should unregister those objects previously registered...
|
||||
}
|
||||
|
||||
protected void addCommunities(SnmpCommunityMIB communityMIB) {
|
||||
Variable[] com2sec = new Variable[] {
|
||||
new OctetString("public"), // community name
|
||||
new OctetString("cpublic"), // security name
|
||||
getAgent().getContextEngineID(), // local engine ID
|
||||
new OctetString("public"), // default context name
|
||||
new OctetString(), // transport tag
|
||||
new Integer32(StorageType.nonVolatile), // storage type
|
||||
new Integer32(RowStatus.active) // row status
|
||||
};
|
||||
MOTableRow row =
|
||||
communityMIB.getSnmpCommunityEntry().createRow(
|
||||
new OctetString("public2public").toSubIndex(true), com2sec);
|
||||
communityMIB.getSnmpCommunityEntry().addRow((SnmpCommunityMIB.SnmpCommunityEntryRow) row);
|
||||
// snmpCommunityMIB.setSourceAddressFiltering(true);
|
||||
}
|
||||
|
||||
protected void registerSnmpMIBs() {
|
||||
heartbeatMIB = new Snmp4jHeartbeatMib(super.getNotificationOriginator(),
|
||||
new OctetString(),
|
||||
super.snmpv2MIB.getSysUpTime());
|
||||
agentppSimulationMIB = new AgentppSimulationMib();
|
||||
super.registerSnmpMIBs();
|
||||
}
|
||||
|
||||
protected void initMessageDispatcher() {
|
||||
this.dispatcher = new MessageDispatcherImpl();
|
||||
this.mpv3 = new MPv3(this.agent.getContextEngineID().getValue());
|
||||
this.usm = new USM(SecurityProtocols.getInstance(), this.agent.getContextEngineID(), this.updateEngineBoots());
|
||||
SecurityModels.getInstance().addSecurityModel(this.usm);
|
||||
SecurityProtocols.getInstance().addDefaultProtocols();
|
||||
this.dispatcher.addMessageProcessingModel(new MPv1());
|
||||
this.dispatcher.addMessageProcessingModel(new MPv2c());
|
||||
this.dispatcher.addMessageProcessingModel(this.mpv3);
|
||||
this.initSnmpSession();
|
||||
}
|
||||
|
||||
}
|
||||
@ -19,7 +19,7 @@ import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class SnmpTest {
|
||||
public class SnmpTestV2 {
|
||||
public static void main(String[] args) throws IOException {
|
||||
SnmpDeviceSimulatorV2 device = new SnmpDeviceSimulatorV2(1610, "public");
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright © 2016-2021 The Thingsboard Authors
|
||||
*
|
||||
* 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.thingsboard.server.transport.snmp;
|
||||
|
||||
import org.snmp4j.CommandResponderEvent;
|
||||
import org.snmp4j.agent.CommandProcessor;
|
||||
import org.snmp4j.mp.MPv3;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class SnmpTestV3 {
|
||||
public static void main(String[] args) throws IOException {
|
||||
SnmpDeviceSimulatorV3 device = new SnmpDeviceSimulatorV3(new CommandProcessor(new OctetString(MPv3.createLocalEngineID())) {
|
||||
@Override
|
||||
public void processPdu(CommandResponderEvent event) {
|
||||
System.out.println("event: " + event);
|
||||
}
|
||||
});
|
||||
device.start("0.0.0.0", "1610");
|
||||
|
||||
device.setUpMappings(Map.of(
|
||||
".1.3.6.1.2.1.1.1.50", "12",
|
||||
".1.3.6.1.2.1.2.1.52", "56",
|
||||
".1.3.6.1.2.1.3.1.54", "yes",
|
||||
".1.3.6.1.2.1.7.1.58", ""
|
||||
));
|
||||
|
||||
new Scanner(System.in).nextLine();
|
||||
}
|
||||
}
|
||||
@ -38,16 +38,6 @@
|
||||
"dataType": "STRING"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"spec": "TELEMETRY_TRAPS_RECEIVING",
|
||||
"mappings": [
|
||||
{
|
||||
"oid": ".1.3.6.1.2.8.7.1.56",
|
||||
"key": "temperature_trap",
|
||||
"dataType": "LONG"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
{
|
||||
"address": "192.168.3.23",
|
||||
"port": 1610,
|
||||
"protocolVersion": "V3",
|
||||
|
||||
"username": "tb-user",
|
||||
"engineId": "qwertyuioa",
|
||||
"securityName": "tb-user",
|
||||
"authenticationProtocol": "SHA_512",
|
||||
"authenticationPassphrase": "sdfghjkloifgh",
|
||||
"privacyProtocol": "DES",
|
||||
"privacyPassphrase": "rtytguijokod"
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"port": 1610,
|
||||
"password": "public",
|
||||
"community": "public",
|
||||
"protocolVersion": "V2C"
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user