diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/IpmiCollectImpl.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/IpmiCollectImpl.java new file mode 100644 index 00000000000..e98bfaf58f6 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/IpmiCollectImpl.java @@ -0,0 +1,114 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2; + +import lombok.extern.slf4j.Slf4j; +import org.apache.hertzbeat.collector.collect.AbstractCollect; +import org.apache.hertzbeat.collector.collect.common.cache.CacheIdentifier; +import org.apache.hertzbeat.collector.collect.common.cache.ConnectionCommonCache; +import org.apache.hertzbeat.collector.collect.ipmi2.cache.IpmiConnect; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiClient; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiConnection; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiHandlerManager; +import org.apache.hertzbeat.collector.dispatch.DispatchConstants; +import org.apache.hertzbeat.common.entity.job.Metrics; +import org.apache.hertzbeat.common.entity.job.protocol.IpmiProtocol; +import org.apache.hertzbeat.common.entity.message.CollectRep; +import org.springframework.util.Assert; + +import java.io.IOException; +import java.util.Optional; + +/** + * Ipmi collect implementation + */ +@Slf4j +public class IpmiCollectImpl extends AbstractCollect { + + private final ConnectionCommonCache connectionCommonCache; + + private final IpmiHandlerManager ipmiHandlerManager; + + public IpmiCollectImpl() { + connectionCommonCache = new ConnectionCommonCache<>(); + ipmiHandlerManager = new IpmiHandlerManager(); + } + + + @Override + public void preCheck(Metrics metrics) throws IllegalArgumentException { + if (metrics == null || metrics.getIpmi() == null) { + throw new IllegalArgumentException("Ipmi collect must has ipmi params"); + } + IpmiProtocol ipmiProtocol = metrics.getIpmi(); + Assert.hasText(ipmiProtocol.getHost(), "Ipmi Protocol host is required."); + Assert.hasText(ipmiProtocol.getPort(), "Ipmi Protocol port is required."); + Assert.hasText(ipmiProtocol.getUsername(), "Ipmi Protocol username is required."); + Assert.hasText(ipmiProtocol.getPassword(), "Ipmi Protocol password is required."); + } + + @Override + public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) { + IpmiConnection connection = null; + try { + connection = getIpmiConnection(metrics.getIpmi()); + } catch (Exception e) { + log.error("Ipmi session create error: {}", e.getMessage()); + builder.setCode(CollectRep.Code.FAIL); + builder.setMsg(e.getMessage()); + return; + } + try { + connection.getResource(builder, metrics); + } catch (IOException e) { + log.error("Get Ipmi {} detail resource error: {}", metrics.getName(), e.getMessage()); + } + } + + @Override + public String supportProtocol() { + return DispatchConstants.PROTOCOL_IPMI; + } + + + private IpmiConnection getIpmiConnection(IpmiProtocol ipmiProtocol) throws Exception { + CacheIdentifier identifier = CacheIdentifier.builder() + .ip(ipmiProtocol.getHost()) + .port(ipmiProtocol.getPort()) + .username(ipmiProtocol.getUsername()) + .password(ipmiProtocol.getPassword()) + .build(); + IpmiConnection connection = null; + Optional cacheOption = connectionCommonCache.getCache(identifier, true); + if (cacheOption.isPresent()) { + IpmiConnect ipmiConnect = cacheOption.get(); + connection = ipmiConnect.getConnection(); + if (connection == null || !connection.isActive()) { + connection = null; + connectionCommonCache.removeCache(identifier); + } + } + if (connection != null) { + return connection; + } + IpmiClient ipmiClient = IpmiClient.create(ipmiProtocol); + connection = ipmiClient.connect(); + connectionCommonCache.addCache(identifier, new IpmiConnect(connection)); + return connection; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/cache/IpmiConnect.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/cache/IpmiConnect.java new file mode 100644 index 00000000000..deba8dde9a4 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/cache/IpmiConnect.java @@ -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 org.apache.hertzbeat.collector.collect.ipmi2.cache; + + +import org.apache.hertzbeat.collector.collect.common.cache.AbstractConnection; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiConnection; + +/** + * ipmi connect session + */ +public class IpmiConnect extends AbstractConnection { + + private final IpmiConnection ipmiConnection; + + public IpmiConnect(IpmiConnection ipmiConnection) { + this.ipmiConnection = ipmiConnection; + } + + @Override + public IpmiConnection getConnection() { + return ipmiConnection; + } + + @Override + public void closeConnection() throws Exception { + if (ipmiConnection != null) { + ipmiConnection.close(); + } + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiClient.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiClient.java new file mode 100644 index 00000000000..2a9ac26c12d --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiClient.java @@ -0,0 +1,84 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.client; + +import java.io.IOException; +import java.security.SecureRandom; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage1; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage2; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage3; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage4; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RmcpPlusOpenSessionRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RmcpPlusOpenSessionResponse; +import org.apache.hertzbeat.common.entity.job.protocol.IpmiProtocol; + +/** + * IpmiClient used to connect to a remote Ipmi server + */ +public class IpmiClient { + + UdpConnection connection; + private final String host; + private final Integer port; + private final String username; + private final String password; + + public IpmiClient(String host, Integer port, String username, String password) throws IOException { + this.host = host; + this.port = port; + this.username = username; + this.password = password; + connection = new UdpConnection(host, port); + } + + public static IpmiClient create(IpmiProtocol ipmiProtocol) throws IOException { + return new IpmiClient(ipmiProtocol.getHost(), Integer.parseInt(ipmiProtocol.getPort()), + ipmiProtocol.getUsername(), ipmiProtocol.getPassword()); + } + + public IpmiConnection connect() throws IOException { + IpmiSession session = newSession(username, password); + + RmcpPlusOpenSessionResponse rmcpPlusOpenSessionResponse = connection.get(session, new RmcpPlusOpenSessionRequest(), RmcpPlusOpenSessionResponse.class); + session.setSystemSessionId(rmcpPlusOpenSessionResponse.systemSessionId); + + session.generateConsoleRandomNumber(); + RakpMessage2 rakpMessage2 = connection.get(session, new RakpMessage1(), RakpMessage2.class); + session.setSystemRandomNumber(rakpMessage2.systemRandom); + session.setSystemGuid(rakpMessage2.systemGuid); + + + session.generateSik(); + session.setK1(session.generateK(1)); + session.setK2(session.generateK(2)); + connection.get(session, new RakpMessage3(), RakpMessage4.class); + + session.setConnected(true); + return new IpmiConnection(session, connection); + } + + public IpmiSession newSession(String username, String password) { + SecureRandom random = new SecureRandom(); + IpmiSession session = new IpmiSession(random.nextInt()); + session.setUserName(username); + session.setPassword(password); + return session; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiConnection.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiConnection.java new file mode 100644 index 00000000000..a366d6341ea --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiConnection.java @@ -0,0 +1,65 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.client; + +import java.io.IOException; +import org.apache.hertzbeat.collector.collect.ipmi2.client.handler.IpmiHandler; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.messaging.CloseSessionRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.messaging.CloseSessionResponse; +import org.apache.hertzbeat.common.entity.job.Metrics; +import org.apache.hertzbeat.common.entity.message.CollectRep; + +/** + * IpmiConnection used for sending ipmi request + */ +public class IpmiConnection implements AutoCloseable { + + IpmiSession session; + + UdpConnection udpConnection; + + IpmiHandlerManager handlerManager = new IpmiHandlerManager(); + + private volatile boolean active = true; + + IpmiConnection(IpmiSession session, UdpConnection udpConnection) { + this.session = session; + this.udpConnection = udpConnection; + } + + public void getResource(CollectRep.MetricsData.Builder builder, Metrics metrics) throws IOException { + IpmiHandler handler = handlerManager.getHandler(metrics.getName()); + if (handler == null) { + throw new RuntimeException("no handler for " + metrics.getIpmi().getType()); + } + handler.handler(session, udpConnection, builder, metrics); + } + + + @Override + public void close() throws IOException { + udpConnection.get(session, new CloseSessionRequest(session.getSystemSessionId()), CloseSessionResponse.class); + udpConnection.close(); + session = null; + active = false; + } + + public boolean isActive() { + return this.active; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiEncoderDecoder.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiEncoderDecoder.java new file mode 100644 index 00000000000..f0d52d4919b --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiEncoderDecoder.java @@ -0,0 +1,41 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.client; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.rmcp.RmcpPacket; + +/** + * IPMI encoder and decoder + */ +public class IpmiEncoderDecoder { + + public static ByteBuffer encode(IpmiPacketContext context, RmcpPacket rmcpPacket) { + int length = rmcpPacket.getWireLength(context.getIpmiSession()); + ByteBuffer buffer = ByteBuffer.allocate(length); + rmcpPacket.toWire(context, buffer); + buffer.flip(); + return buffer; + } + + public static RmcpPacket decode(IpmiPacketContext context, ByteBuffer buffer) { + RmcpPacket rmcpPacket = new RmcpPacket(); + rmcpPacket.fromWire(context, buffer); + return rmcpPacket; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiHandlerManager.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiHandlerManager.java new file mode 100644 index 00000000000..7e683710153 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiHandlerManager.java @@ -0,0 +1,50 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.client; + + +import java.util.HashMap; +import java.util.Map; +import org.apache.hertzbeat.collector.collect.ipmi2.client.handler.ChassisHandler; +import org.apache.hertzbeat.collector.collect.ipmi2.client.handler.IpmiHandler; +import org.apache.hertzbeat.collector.collect.ipmi2.client.handler.SensorHandler; + +/** + * Manger for IpmiHandler + */ +public class IpmiHandlerManager { + + Map handlerMap = new HashMap<>(); + + public IpmiHandlerManager() { + registerHandler("Chassis", new ChassisHandler()); + registerHandler("Sensor", new SensorHandler()); + } + + public void registerHandler(String metricName, IpmiHandler handler) { + handlerMap.put(metricName, handler); + } + + public IpmiHandler getHandler(String metricName) { + if (!handlerMap.containsKey(metricName)) { + return null; + } + return handlerMap.get(metricName); + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiPacketContext.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiPacketContext.java new file mode 100644 index 00000000000..6f3e262c943 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiPacketContext.java @@ -0,0 +1,25 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.client; + +/** + * Ipmi packet context + */ +public interface IpmiPacketContext { + IpmiSession getIpmiSession(); +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiSession.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiSession.java new file mode 100644 index 00000000000..f62ef00d271 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/IpmiSession.java @@ -0,0 +1,133 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.client; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.concurrent.atomic.AtomicInteger; +import lombok.Data; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.AbstractWireable; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.AbstractSessionIpmiPayload; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiAuthenticationCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiConfidentialityCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiIntegrityCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication.IpmiAuthentication; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteOrderUtils; + + +/** + * Ipmi session + */ +@Data +public class IpmiSession implements IpmiPacketContext { + + private final int consoleSessionId; + + private int systemSessionId; + + private byte[] consoleRandomNumber; + + private byte[] systemRandomNumber; + + private byte[] systemGuid; + + private byte[] sik; + + private byte[] k1; + + private byte[] k2; + + private String userName; + + private String password; + + private boolean isConnected = false; + + private AtomicInteger authenticatedSequenceNumber = new AtomicInteger(1); + + private AtomicInteger unauthenticatedSequenceNumber = new AtomicInteger(1); + + private IpmiAuthenticationCode authenticationAlgorithm = IpmiAuthenticationCode.RAKP_HMAC_SHA1; + private IpmiConfidentialityCode confidentialityAlgorithm = IpmiConfidentialityCode.AES_CBC_128; + private IpmiIntegrityCode integrityAlgorithm = IpmiIntegrityCode.HMAC_SHA1_96; + + private AbstractSessionIpmiPayload.MaximumPrivilegeLevel maximumPrivilegeLevel = AbstractSessionIpmiPayload.MaximumPrivilegeLevel.ADMINISTRATOR; + + public IpmiSession(int consoleSessionId) { + this.consoleSessionId = consoleSessionId; + } + + public void generateSik() { + int length = 34 + ((userName == null) ? 0 : userName.length()); + ByteBuffer buffer = ByteBuffer.allocate(length); + ByteOrderUtils.writeBytes(buffer, consoleRandomNumber); + ByteOrderUtils.writeBytes(buffer, systemRandomNumber); + byte t = AbstractWireable.setBits((byte) 0, 4, 0x1, 1); + AbstractSessionIpmiPayload.MaximumPrivilegeLevel maximumPrivilegeLevel = this.getMaximumPrivilegeLevel(); + t = AbstractWireable.setBits(t, 0, AbstractSessionIpmiPayload.MaximumPrivilegeLevel.MASK, maximumPrivilegeLevel.getCode()); + buffer.put(t); + if (userName != null) { + byte[] usernameBytes = userName.getBytes(StandardCharsets.US_ASCII); + buffer.put((byte) usernameBytes.length); + buffer.put(usernameBytes); + } else { + buffer.put((byte) 0); + } + IpmiAuthenticationCode authenticationCode = authenticationAlgorithm; + IpmiAuthentication authentication = authenticationCode.newIpmiAuthentication(); + if (authentication == null) { + throw new UnsupportedOperationException("Unsupported authentication code: " + authenticationCode); + } + try { + authentication.setKey(password.getBytes(StandardCharsets.US_ASCII)); + authentication.setData(buffer.array()); + sik = authentication.getHash(); + } catch (InvalidKeyException e) { + throw new RuntimeException(e); + } + } + + public byte[] generateK(int n) { + byte[] data = new byte[20]; + Arrays.fill(data, (byte) n); + IpmiAuthentication authentication = authenticationAlgorithm.newIpmiAuthentication(); + if (authentication == null) { + throw new UnsupportedOperationException("Unsupported authentication code: " + authenticationAlgorithm); + } + try { + authentication.setKey(sik); + authentication.setData(data); + return authentication.getHash(); + } catch (InvalidKeyException e) { + throw new RuntimeException(e); + } + } + + public void generateConsoleRandomNumber() { + SecureRandom random = new SecureRandom(); + consoleRandomNumber = random.generateSeed(16); + } + + @Override + public IpmiSession getIpmiSession() { + return this; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/UdpConnection.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/UdpConnection.java new file mode 100644 index 00000000000..27c6b9f4263 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/UdpConnection.java @@ -0,0 +1,81 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.client; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.DatagramChannel; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.Ipmi20Ipv4SessionWrapper; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.IpmiPayload; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.rmcp.RmcpPacket; + +/** + * Udp connection for ipmi + */ +public class UdpConnection { + final String host; + final int port; + + final SocketAddress address; + + DatagramChannel channel; + + ByteBuffer receiveBuffer = ByteBuffer.allocate(1024); + + + public UdpConnection(String host, int port) throws IOException { + this.host = host; + this.port = port; + this.address = new InetSocketAddress(host, port); + channel = DatagramChannel.open(); + } + + private int send(IpmiPacketContext context, IpmiPayload payload) throws IOException { + Ipmi20Ipv4SessionWrapper wrapper = new Ipmi20Ipv4SessionWrapper(); + wrapper.setIpmiPayload(payload); + if (context.getIpmiSession().isConnected()) { + wrapper.setIpmiSessionId(context.getIpmiSession().getSystemSessionId()); + wrapper.setIpmiSessionSequenceNumber(context.getIpmiSession().getAuthenticatedSequenceNumber().getAndIncrement()); + } + RmcpPacket rmcpPacket = new RmcpPacket(); + rmcpPacket.withData(wrapper); + ByteBuffer sendBuffer = IpmiEncoderDecoder.encode(context, rmcpPacket); + return channel.send(sendBuffer, address); + } + + private T receive(IpmiPacketContext context, Class clazz) throws IOException { + receiveBuffer.clear(); + channel.receive(receiveBuffer); + receiveBuffer.flip(); + RmcpPacket rmcpPacket = IpmiEncoderDecoder.decode(context, receiveBuffer); + return rmcpPacket.getEncapsulated(clazz); + } + + public T get(IpmiPacketContext context, IpmiPayload payload, Class clazz) throws IOException { + send(context, payload); + return receive(context, clazz); + } + + public void close() throws IOException { + channel.close(); + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/handler/ChassisHandler.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/handler/ChassisHandler.java new file mode 100644 index 00000000000..2aaf6ac9cd1 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/handler/ChassisHandler.java @@ -0,0 +1,66 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.client.handler; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; +import org.apache.hertzbeat.collector.collect.ipmi2.client.UdpConnection; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.chassis.GetChassisStatusRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.chassis.GetChassisStatusResponse; +import org.apache.hertzbeat.common.constants.CommonConstants; +import org.apache.hertzbeat.common.entity.job.Metrics; +import org.apache.hertzbeat.common.entity.message.CollectRep; + +/** + * ChassisHandler + */ +public class ChassisHandler implements IpmiHandler { + + Map parseValue = new HashMap<>(); + + @Override + public void handler(IpmiSession session, UdpConnection connection, CollectRep.MetricsData.Builder builder, Metrics metrics) throws IOException { + GetChassisStatusResponse getChassisStatusResponse = connection.get(session, new GetChassisStatusRequest(), GetChassisStatusResponse.class); + parseFieldToMap(getChassisStatusResponse); + CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder(); + for (Metrics.Field field : metrics.getFields()) { + if (!parseValue.containsKey(field.getField())) { + valueRowBuilder.addColumns(CommonConstants.NULL_VALUE); + continue; + } + valueRowBuilder.addColumns(parseValue.get(field.getField())); + } + builder.addValues(valueRowBuilder.build()); + } + + public void parseFieldToMap(GetChassisStatusResponse getChassisStatusResponse) { + parseValue.put("system_power", getChassisStatusResponse.isPowerOn ? "on" : "off"); + parseValue.put("power_overload", getChassisStatusResponse.isPowerOverload ? "true" : "false"); + parseValue.put("power_interlock", getChassisStatusResponse.isPowerInterlock ? "true" : "false"); + parseValue.put("power_fault", getChassisStatusResponse.isPowerFault ? "true" : "false"); + parseValue.put("power_control_fault", getChassisStatusResponse.isPowerControlFault ? "true" : "false"); + parseValue.put("power_restore_policy", getChassisStatusResponse.powerRestorePolicy); + parseValue.put("last_power_event", getChassisStatusResponse.lastPowerEvent); + parseValue.put("fan_fault", getChassisStatusResponse.isFanFault ? "true" : "false"); + parseValue.put("drive_fault", getChassisStatusResponse.isDriveFault ? "true" : "false"); + parseValue.put("front_panel_lockout_active", getChassisStatusResponse.isFrontPanelLockoutActive ? "true" : "false"); + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/handler/IpmiHandler.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/handler/IpmiHandler.java new file mode 100644 index 00000000000..6620d155a4a --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/handler/IpmiHandler.java @@ -0,0 +1,32 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.client.handler; + +import java.io.IOException; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; +import org.apache.hertzbeat.collector.collect.ipmi2.client.UdpConnection; +import org.apache.hertzbeat.common.entity.job.Metrics; +import org.apache.hertzbeat.common.entity.message.CollectRep; + +/** + * IpmiHandler interface + */ +public interface IpmiHandler { + void handler(IpmiSession session, UdpConnection connection, CollectRep.MetricsData.Builder builder, Metrics metrics) throws IOException; + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/handler/SensorHandler.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/handler/SensorHandler.java new file mode 100644 index 00000000000..1ea2ac69489 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/client/handler/SensorHandler.java @@ -0,0 +1,136 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.client.handler; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; +import org.apache.hertzbeat.collector.collect.ipmi2.client.UdpConnection; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.GetSdrRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.GetSdrResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.GetSensorReadingRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.GetSensorReadingResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.ReserveSdrRepositoryRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.ReserveSdrRepositoryResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.code.IpmiReadingTypeCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; +import org.apache.hertzbeat.common.constants.CommonConstants; +import org.apache.hertzbeat.common.entity.job.Metrics; +import org.apache.hertzbeat.common.entity.message.CollectRep; + +/** + * SensorHandler + */ +@Slf4j +public class SensorHandler implements IpmiHandler { + + @Override + public void handler(IpmiSession session, UdpConnection connection, CollectRep.MetricsData.Builder builder, Metrics metrics) throws IOException { + ReserveSdrRepositoryResponse response = connection.get(session, new ReserveSdrRepositoryRequest(), ReserveSdrRepositoryResponse.class); + int reserveId = response.reserveId; + int recordId = GetSdrRequest.RECORD_ID_START; + while (true) { + if (recordId == 0xFFFF) { + break; + } + GetSdrRequest headRequest = new GetSdrRequest(reserveId, recordId, (byte) 0, GetSdrRequest.HEADER_LENGTH); + GetSdrResponse getSdrHeadResponse = connection.get(session, headRequest, GetSdrResponse.class); + if (getSdrHeadResponse.recordType != 0x01) { + recordId = getSdrHeadResponse.nextRecordId; + continue; + } + Map parseValue = new HashMap<>(); + GetSdrRequest request = new GetSdrRequest(reserveId, recordId, (byte) 0, (byte) (getSdrHeadResponse.recordLength + 5)); + recordId = getSdrHeadResponse.nextRecordId; + GetSdrResponse getSdrBodyResponse = connection.get(session, request, GetSdrResponse.class); + if (isReadable(getSdrBodyResponse)) { + byte sensorNum = getSdrBodyResponse.sensorNumber; + GetSensorReadingRequest readingRequest = new GetSensorReadingRequest(sensorNum); + readingRequest.setRqLun(getSdrBodyResponse.sensorOwnerLun); + try { + GetSensorReadingResponse getSensorReadingResponse = connection.get(session, readingRequest, GetSensorReadingResponse.class); + double sensorReading = calcSensorValue(getSdrBodyResponse, getSensorReadingResponse.sensorReading); + parseValue.put("sensor_reading", String.format("%.3f", sensorReading) + " " + getSdrBodyResponse.unitTypeCode.getDescription()); + } catch (Exception e) { + log.error("get sensor reading error", e); + } + } + parseValue.put("sensor_id", getSdrBodyResponse.sensorIdString); + parseValue.put("entity_id", getSdrBodyResponse.entityIdCode.getDescription()); + parseValue.put("sensor_type", getSdrBodyResponse.sensorTypeCode.getDescription()); + CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder(); + for (Metrics.Field field : metrics.getFields()) { + if (!parseValue.containsKey(field.getField())) { + valueRowBuilder.addColumns(CommonConstants.NULL_VALUE); + continue; + } + valueRowBuilder.addColumns(parseValue.get(field.getField())); + } + builder.addValues(valueRowBuilder.build()); + } + } + + public boolean isReadable(GetSdrResponse response) { + if (response.recordType != 0x01) { + return false; + } + if (response.readingTypeCode != IpmiReadingTypeCode.Threshold) { + return false; + } + if (response.analogDataFormat == 0x03) { + return false; + } + return true; + } + + public double calcSensorValue(GetSdrResponse response, int raw) { + switch (response.analogDataFormat) { + case 0x00 -> raw = raw & 0xFF; + case 0x01 -> { + int signbit = raw & 0x80; + if (signbit != 0) { + raw = ~raw & 0x7F; + raw = -raw; + } + } + case 0x02 -> raw = ByteConvertUtils.getBitsAsSigned(raw, 8); + default -> { + return 0.0; + } + } + double value = (response.m * raw + response.b * Math.pow(10, response.k1)) * Math.pow(10, response.k2); + switch (response.linear) { + case 0x01 -> value = Math.log(value); + case 0x02 -> value = Math.log10(value); + case 0x03 -> value = Math.log(value) / Math.log(2); + case 0x04 -> value = Math.exp(value); + case 0x05 -> value = Math.pow(10, value); + case 0x06 -> value = Math.pow(2, value); + case 0x07 -> value = Math.pow(value, -1.0); + case 0x08 -> value = Math.pow(value, 2.0); + case 0x09 -> value = Math.pow(value, 3.0); + case 0x0A -> value = Math.sqrt(value); + case 0x0B -> value = Math.cbrt(value); + default -> { + } + } + return value; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/common/AbstractWireable.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/common/AbstractWireable.java new file mode 100644 index 00000000000..2504dd0ae92 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/common/AbstractWireable.java @@ -0,0 +1,59 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.common; + +import java.nio.ByteBuffer; + +/** + * Abstract wireable + */ +public abstract class AbstractWireable implements Wireable { + + public static byte setBits(byte b, int byteIndex, int byteMask, int byteValue) { + byteMask <<= byteIndex; + return (byte) ((b & ~byteMask) | ((byteValue << byteIndex) & byteMask)); + } + + public static byte setBits(byte b, int byteMask, int byteValue) { + return setBits(b, 0, byteMask, byteValue); + } + + public static byte setBits(byte b, int byteValue) { + return setBits(b, 0, 0xff, byteValue); + } + + public static byte getBits(byte b, int byteIndex, int byteMask) { + return (byte) ((b >> byteIndex) & byteMask); + } + + public static byte getBits(byte b, int byteMask) { + return getBits(b, 0, byteMask); + } + + public static void ignoreBytes(ByteBuffer buffer, int length) { + for (int i = 0; i < length; i++) { + buffer.get(); + } + } + + public static void reservedBytes(ByteBuffer buffer, int length) { + for (int i = 0; i < length; i++) { + buffer.put((byte) 0); + } + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/common/IpmiCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/common/IpmiCode.java new file mode 100644 index 00000000000..1f6625f49a4 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/common/IpmiCode.java @@ -0,0 +1,59 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.common; + +import java.nio.ByteBuffer; +import com.google.common.primitives.UnsignedBytes; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * IPMI code + */ +public class IpmiCode { + + /** + * IPMI code + */ + public interface Code { + byte getCode(); + + default String getDescription() { + return "No description"; + } + } + + public static & IpmiCode.Code> T fromByte(Class type, byte code) { + for (T value : type.getEnumConstants()) + if (value.getCode() == code) + return value; + throw new IllegalArgumentException("Unknown " + type.getSimpleName() + " code 0x" + UnsignedBytes.toString(code, 16)); + } + + public static & IpmiCode.Code> T fromInt(Class type, int code) { + return fromByte(type, ByteConvertUtils.checkCastByte(code)); + } + + public static & IpmiCode.Code> T fromBuffer(Class type, ByteBuffer buffer) { + return fromByte(type, buffer.get()); + } + + public static & IpmiCode.Code> T fromBufferWithMask(Class type, ByteBuffer buffer, int mask) { + return fromByte(type, (byte) (buffer.get() & mask)); + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/common/IpmiEncapsulation.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/common/IpmiEncapsulation.java new file mode 100644 index 00000000000..4eb74842e50 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/common/IpmiEncapsulation.java @@ -0,0 +1,40 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.common; + +/** + * Ipmi encapsulation used to get encapsulated object + */ +public class IpmiEncapsulation { + + /** + * Encapsulation interface + */ + public interface Encapsulation { + T getEncapsulated(Class type); + } + + public static T getEncapsulated(Class type, Object value) { + if (type.isInstance(value)) + return type.cast(value); + if (value instanceof Encapsulation) + return ((Encapsulation) value).getEncapsulated(type); + return null; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/common/Wireable.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/common/Wireable.java new file mode 100644 index 00000000000..d775ee735f7 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/common/Wireable.java @@ -0,0 +1,36 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.common; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; + + +/** + * Wireable interface to serialize and deserialize + */ +public interface Wireable { + + int getWireLength(IpmiPacketContext context); + + void toWire(IpmiPacketContext context, ByteBuffer buffer); + + void fromWire(IpmiPacketContext context, ByteBuffer buffer); + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/AbstractIpmiSessionWrapper.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/AbstractIpmiSessionWrapper.java new file mode 100644 index 00000000000..9bf2ed9ae08 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/AbstractIpmiSessionWrapper.java @@ -0,0 +1,111 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.AbstractWireable; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiEncapsulation; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.IpmiPayload; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.IpmiPayloadType; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage1; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage2; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage3; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage4; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RmcpPlusOpenSessionRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RmcpPlusOpenSessionResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.rmcp.RmcpMessageClass; + +/** + * Abstract Ipmi Session Wrapper + */ +public abstract class AbstractIpmiSessionWrapper extends AbstractWireable implements IpmiSessionWrapper { + private int sessionId = 0; + private int sessionSequenceNumber = 0; + private IpmiPayload payload; + + @Override + public int getIpmiSessionId() { + return sessionId; + } + + @Override + public void setIpmiSessionId(int ipmiSessionId) { + this.sessionId = ipmiSessionId; + } + + @Override + public int getIpmiSessionSequenceNumber() { + return sessionSequenceNumber; + } + + @Override + public void setIpmiSessionSequenceNumber(int ipmiSessionSequenceNumber) { + this.sessionSequenceNumber = ipmiSessionSequenceNumber; + } + + @Override + public IpmiPayload getIpmiPayload() { + return payload; + } + + @Override + public void setIpmiPayload(IpmiPayload ipmiPayload) { + this.payload = ipmiPayload; + } + + @Override + public T getEncapsulated(Class type) { + if (type.isInstance(this)) + return type.cast(this); + return IpmiEncapsulation.getEncapsulated(type, getIpmiPayload()); + } + + @Override + public RmcpMessageClass getMessageClass() { + return RmcpMessageClass.IPMI; + } + + public static IpmiPayload newIpmiPayload(ByteBuffer buffer, IpmiPayloadType type) { + switch (type) { + case IPMI: { + int position = buffer.position(); + byte netFn = AbstractWireable.getBits(buffer.get(position + 1), 2, IpmiNetworkFunctionCode.MASK); + IpmiNetworkFunctionCode networkFunctionCode = IpmiCode.fromByte(IpmiNetworkFunctionCode.class, (byte) (netFn & ~1)); + byte commandNameByte = buffer.get(position + 5); + IpmiCommandName commandName = IpmiCommandName.fromNetFunctionAndCode(networkFunctionCode, commandNameByte); + boolean isResponse = (netFn & 1) != 0; + return isResponse ? commandName.newIpmiResponse() : commandName.newIpmiRequest(); + } + case RMCPOpenSessionRequest: + return new RmcpPlusOpenSessionRequest(); + case RMCPOpenSessionResponse: + return new RmcpPlusOpenSessionResponse(); + case RAKPMessage1: + return new RakpMessage1(); + case RAKPMessage2: + return new RakpMessage2(); + case RAKPMessage3: + return new RakpMessage3(); + case RAKPMessage4: + return new RakpMessage4(); + default: + throw new UnsupportedOperationException("Unsupported IPMI payload type: " + type); + } + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/Ipmi20Ipv4SessionWrapper.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/Ipmi20Ipv4SessionWrapper.java new file mode 100644 index 00000000000..e447303d4c5 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/Ipmi20Ipv4SessionWrapper.java @@ -0,0 +1,219 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.IpmiPayload; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.IpmiPayloadType; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiAuthenticationCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiConfidentialityCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiIntegrityCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality.IpmiConfidentiality; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity.IpmiIntegrity; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteOrderUtils; + +/** + * See IPMIv2 Section 13.6 + */ +public class Ipmi20Ipv4SessionWrapper extends AbstractIpmiSessionWrapper{ + + private static final IpmiSessionAuthenticationType AUTH_TYPE = IpmiSessionAuthenticationType.RMCPP; + + @Override + public int getWireLength(IpmiPacketContext context) { + IpmiPayload payload = getIpmiPayload(); + int rawDataLength = payload.getWireLength(context); + int encryptDataLength = rawDataLength; + IpmiConfidentialityCode confidentialityCode = getConfidentialityCode(context.getIpmiSession()); + if (!IpmiConfidentialityCode.NONE.equals(confidentialityCode)) { + IpmiConfidentiality confidentiality = confidentialityCode.newIpmiConfidentiality(); + if (confidentiality == null) { + throw new UnsupportedOperationException("Such confidentiality algorithm not support"); + } + encryptDataLength = confidentiality.getEncryptedLength(rawDataLength); + } + int integrityDataLength = 0; + IpmiIntegrityCode integrityCode = getIntegrityCode(context.getIpmiSession()); + if (!IpmiIntegrityCode.NONE.equals(integrityCode)) { + int padLength = 4 - (12 + encryptDataLength + 1 + 1) % 4; + IpmiIntegrity ipmiIntegrity = integrityCode.newIpmiIntegrity(); + if (ipmiIntegrity == null) { + throw new UnsupportedOperationException("Such integrity algorithm not support"); + } + integrityDataLength = padLength + 1 + 1 + ipmiIntegrity.getHashLength(); + } + return 12 + encryptDataLength + integrityDataLength; + } + + public IpmiConfidentialityCode getConfidentialityCode(IpmiSession session) { + if (getIpmiSessionId() == 0) { + return IpmiConfidentialityCode.NONE; + } + return session.getConfidentialityAlgorithm(); + } + + public IpmiAuthenticationCode getAuthenticationCode(IpmiSession session) { + if (getIpmiSessionId() == 0) { + return IpmiAuthenticationCode.RAKP_NOME; + } + return session.getAuthenticationAlgorithm(); + } + + public IpmiIntegrityCode getIntegrityCode(IpmiSession session) { + if (getIpmiSessionId() == 0) { + return IpmiIntegrityCode.NONE; + } + return session.getIntegrityAlgorithm(); + } + + @Override + public void toWire(IpmiPacketContext context, ByteBuffer buffer) { + IpmiSession session = context.getIpmiSession(); + + IpmiConfidentialityCode confidentialityCode = getConfidentialityCode(session); + IpmiIntegrityCode integrityCode = getIntegrityCode(session); + + IpmiPayload payload = getIpmiPayload(); + + ByteBuffer integrityInput = buffer.duplicate(); + + buffer.put(AUTH_TYPE.getCode()); + + boolean encrypted = !IpmiConfidentialityCode.NONE.equals(confidentialityCode); + boolean authenticated = !IpmiIntegrityCode.NONE.equals(integrityCode); + byte tmp = setBits((byte) 0, payload.getPayloadType().getCode(), IpmiPayloadType.MASK); + tmp = setBits(tmp, 6, 0x1, authenticated ? 1 : 0); + tmp = setBits(tmp, 7, 0x1, encrypted ? 1 : 0); + buffer.put(tmp); + + if (IpmiPayloadType.OEM_EXPLICIT.equals(payload.getPayloadType())) { + throw new UnsupportedOperationException("OEM explicit payload not supported"); + } + + ByteOrderUtils.writeLeInt(buffer, getIpmiSessionId()); + ByteOrderUtils.writeLeInt(buffer, getIpmiSessionSequenceNumber()); + + IpmiConfidentiality confidentiality = confidentialityCode.newIpmiConfidentiality(); + int rawDataLength = payload.getWireLength(context); + if (confidentiality == null) { + throw new UnsupportedOperationException("Such confidentiality algorithm not support"); + } + int encryptDataLength = confidentiality.getEncryptedLength(rawDataLength); + ByteOrderUtils.writeLeChar(buffer, (char) encryptDataLength); + + try { + if (encrypted) { + ByteBuffer raw = ByteBuffer.allocate(rawDataLength); + payload.toWire(context, raw); + raw.flip(); + confidentiality.encrypt(session, raw, buffer); + } else { + payload.toWire(context, buffer); + } + + if (authenticated) { + int padLength = 4 - (12 + encryptDataLength + 1 + 1) % 4; + byte[] pad = new byte[padLength]; + for (int i = 0; i < padLength; i++) { + pad[i] = (byte) 0xFF; + } + buffer.put(pad); + buffer.put((byte) padLength); + buffer.put((byte) 0x07); + integrityInput.limit(buffer.position()); + IpmiIntegrity ipmiIntegrity = integrityCode.newIpmiIntegrity(); + if (ipmiIntegrity == null) { + throw new UnsupportedOperationException("Such integrity algorithm not support"); + } + ipmiIntegrity.setKey(session.getK1()); + ipmiIntegrity.setData(ByteOrderUtils.readBytes(integrityInput, integrityInput.limit() - integrityInput.position())); + byte[] integrityData = ipmiIntegrity.getHash(); + buffer.put(integrityData); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void fromWire(IpmiPacketContext context, ByteBuffer buffer) { + IpmiSession session = context.getIpmiSession(); + ByteBuffer integrityInput = buffer.duplicate(); + + IpmiSessionAuthenticationType type = IpmiCode.fromByte(IpmiSessionAuthenticationType.class, buffer.get()); + if (!IpmiSessionAuthenticationType.RMCPP.equals(type)) { + throw new UnsupportedOperationException("Unsupported authentication type: " + type); + } + + byte tmp = buffer.get(); + boolean encrypted = getBits(tmp, 7, 0x01) == 1; + boolean authenticated = getBits(tmp, 6, 0x01) == 1; + IpmiPayloadType payloadType = IpmiCode.fromByte(IpmiPayloadType.class, getBits(tmp, IpmiPayloadType.MASK)); + + setIpmiSessionId(ByteOrderUtils.readLeInt(buffer)); + setIpmiSessionSequenceNumber(ByteOrderUtils.readLeInt(buffer)); + + int payloadLength = ByteOrderUtils.readLeChar(buffer); + + ByteBuffer encryptedBuffer = buffer.duplicate(); + encryptedBuffer.limit(encryptedBuffer.position() + payloadLength); + buffer.position(encryptedBuffer.position() + payloadLength); + + try { + ByteBuffer decryptedBuffer; + if (encrypted) { + IpmiConfidentialityCode confidentialityCode = getConfidentialityCode(session); + IpmiConfidentiality confidentiality = confidentialityCode.newIpmiConfidentiality(); + if (confidentiality == null) { + throw new UnsupportedOperationException("Such confidentiality algorithm not support"); + } + decryptedBuffer = confidentiality.decrypt(session, encryptedBuffer); + } else { + decryptedBuffer = encryptedBuffer; + } + IpmiPayload payload = newIpmiPayload(decryptedBuffer, payloadType); + payload.fromWire(context, decryptedBuffer); + setIpmiPayload(payload); + + + if (authenticated) { + int padLength = 4 - (12 + payloadLength + 1 + 1) % 4; + ignoreBytes(buffer, padLength + 2); + integrityInput.limit(buffer.position()); + IpmiIntegrityCode ipmiIntegrityCode = session.getIntegrityAlgorithm(); + IpmiIntegrity ipmiIntegrity = ipmiIntegrityCode.newIpmiIntegrity(); + if (ipmiIntegrity == null) { + throw new UnsupportedOperationException("Such integrity algorithm not support"); + } + ipmiIntegrity.setKey(session.getK1()); + ipmiIntegrity.setData(ByteOrderUtils.readBytes(integrityInput, integrityInput.limit() - integrityInput.position())); + byte[] expectIntegrityData = ipmiIntegrity.getHash(); + byte[] actualIntegrityData = ByteOrderUtils.readBytes(buffer, ipmiIntegrity.getHashLength()); + if (!Arrays.equals(expectIntegrityData, actualIntegrityData)) { + throw new RuntimeException("Integrity check failed"); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiChannelMediumCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiChannelMediumCode.java new file mode 100644 index 00000000000..c24955f5ac4 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiChannelMediumCode.java @@ -0,0 +1,52 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 6.5 + */ +public enum IpmiChannelMediumCode implements IpmiCode.Code { + IPMB_I2C(0x1), + ICMB_v1_0(0x2), + ICMB_v0_9(0x3), + LAN_802_3(0x4), + Serial_Modem(0x5), + LAN_Other(0x6), + PCI_SMBus(0x7), + SMBus_v1(0x8), + SMBus_v2(0x9), + USB_v1(0xA), + USB_v2(0xB), + System_Interface(0xC); + private final byte code; + + public static final int MASK = 0x7F; + + private IpmiChannelMediumCode(int code) { + this.code = ByteConvertUtils.checkCastByte(code); + } + + @Override + public byte getCode() { + return code; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiChannelNumberCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiChannelNumberCode.java new file mode 100644 index 00000000000..f9bf3aedc97 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiChannelNumberCode.java @@ -0,0 +1,55 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 6.3 + */ +public enum IpmiChannelNumberCode implements IpmiCode.Code { + Primary_IPMB(0x0), + C1(0x1), + C2(0x2), + C3(0x3), + C4(0x4), + C5(0x5), + C6(0x6), + C7(0x7), + C8(0x8), + C9(0x9), + C10(0xA), + C11(0xB), + PRESENT(0xE), + System_Interface(0xF); + + private final byte code; + + public static final int MASK = 0xF; + + private IpmiChannelNumberCode(int code) { + this.code = ByteConvertUtils.checkCastByte(code); + } + + @Override + public byte getCode() { + return code; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiChannelPrivilegeLevel.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiChannelPrivilegeLevel.java new file mode 100644 index 00000000000..fffbc49e2de --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiChannelPrivilegeLevel.java @@ -0,0 +1,46 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 6.8 + */ +public enum IpmiChannelPrivilegeLevel implements IpmiCode.Code { + Unprotected(0x00), + Callback(0x01), + User(0x02), + Operator(0x03), + Administrator(0x04), + OEM(0x05); + private final byte code; + + public static final byte MASK = 0x07; + + private IpmiChannelPrivilegeLevel(int code) { + this.code = ByteConvertUtils.checkCastByte(code); + } + + @Override + public byte getCode() { + return code; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiChannelProtocolCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiChannelProtocolCode.java new file mode 100644 index 00000000000..52db7156213 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiChannelProtocolCode.java @@ -0,0 +1,53 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 6.4 + */ +public enum IpmiChannelProtocolCode implements IpmiCode.Code { + IPMB_v1_0(0x01), + ICMB_v1_0(0x02), + IPMI_SMBus(0x04), + KCS(0x05), + SMIC(0x06), + BT_10(0x07), + BT_15(0x08), + TMode(0x09), + OEM1(0x1C), + OEM2(0x1D), + OEM3(0x1E), + OEM4(0x1F); + + + private final byte code; + public static final int MASK = 0xFF; + + private IpmiChannelProtocolCode(int code) { + this.code = ByteConvertUtils.checkCastByte(code); + } + + @Override + public byte getCode() { + return code; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiCommandName.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiCommandName.java new file mode 100644 index 00000000000..0f244d61870 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiCommandName.java @@ -0,0 +1,118 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.IpmiRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.IpmiResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.chassis.GetChassisStatusRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.chassis.GetChassisStatusResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.messaging.CloseSessionRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.messaging.CloseSessionResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.messaging.GetChannelAuthenticationCapabilitiesRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.messaging.GetChannelAuthenticationCapabilitiesResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.GetSdrRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.GetSdrResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.GetSensorReadingRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.GetSensorReadingResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.ReserveSdrRepositoryRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.ReserveSdrRepositoryResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Appendix G + */ +public enum IpmiCommandName implements IpmiCode.Code { + + GetChassisStatus("Get Chassis Status", IpmiNetworkFunctionCode.Chassis, 0x01, + IpmiChannelPrivilegeLevel.User, GetChassisStatusRequest.class, GetChassisStatusResponse.class), + GetChannelAuthenticationCapabilities("Get Channel Authentication Capabilities", IpmiNetworkFunctionCode.App, + 0x38, IpmiChannelPrivilegeLevel.User, GetChannelAuthenticationCapabilitiesRequest.class, GetChannelAuthenticationCapabilitiesResponse.class), + CloseSession("Close Session", IpmiNetworkFunctionCode.App, 0x3C, IpmiChannelPrivilegeLevel.Callback, + CloseSessionRequest.class, CloseSessionResponse.class), + ReserveSdrRepository("Reserve SDR Repository", IpmiNetworkFunctionCode.Storage, 0x22, IpmiChannelPrivilegeLevel.User, + ReserveSdrRepositoryRequest.class, ReserveSdrRepositoryResponse.class), + GetSdr("Get SDR", IpmiNetworkFunctionCode.Storage, 0x23, IpmiChannelPrivilegeLevel.User, GetSdrRequest.class, GetSdrResponse.class), + GetSensorReading("Get Sensor Reading", IpmiNetworkFunctionCode.Sensor_Event, 0x2D, IpmiChannelPrivilegeLevel.User, GetSensorReadingRequest.class, GetSensorReadingResponse.class); + + private final String name; + private final IpmiNetworkFunctionCode networkFunction; + private final byte code; + private final IpmiChannelPrivilegeLevel privilegeLevel; + private final Class requestType; + private final Class responseType; + + private IpmiCommandName(String name, IpmiNetworkFunctionCode networkFunction, int code, IpmiChannelPrivilegeLevel privilegeLevel, + Class requestType, Class responseType) { + this.name = name; + this.networkFunction = networkFunction; + this.code = ByteConvertUtils.checkCastByte(code); + this.privilegeLevel = privilegeLevel; + this.requestType = requestType; + this.responseType = responseType; + } + + @Override + public byte getCode() { + return code; + } + + public IpmiNetworkFunctionCode getNetworkFunction() { + return networkFunction; + } + + public static IpmiCommandName fromNetFunctionAndCode(IpmiNetworkFunctionCode networkFunction, byte code) { + for (IpmiCommandName command : values()) { + if (command.networkFunction == networkFunction && command.code == code) { + return command; + } + } + throw new UnsupportedOperationException("Unsupported command: " + networkFunction + " " + ByteConvertUtils.byteToInt(code)); + } + + public static IpmiResponse getResponseByRequest(Class request) { + for (IpmiCommandName command : values()) { + if (command.requestType.isInstance(request)) { + IpmiResponse response = command.newIpmiResponse(); + if (command.responseType.isInstance(response)) { + return response; + } + } + } + throw new UnsupportedOperationException("Unsupported request: " + request); + } + + public IpmiResponse newIpmiResponse() { + try { + return responseType.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public IpmiRequest newIpmiRequest() { + try { + return requestType.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiCompletionCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiCompletionCode.java new file mode 100644 index 00000000000..9054ee5c454 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiCompletionCode.java @@ -0,0 +1,75 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 5.2 + */ +public enum IpmiCompletionCode implements IpmiCode.Code { + CompletedNormally(0x00, "Command Completed Normally."), + NodeBusy(0xC0, "Node Busy. Command could not be processed because command processing resources are temporarily unavailable."), + InvalidCommand(0xC1, "Invalid Command. Used to indicate an unrecognized or unsupported command."), + InvalidForGivenLUN(0xC2, "Command invalid for given LUN."), + Timeout(0xC3, "Timeout while processing command. Response unavailable."), + OutOfSpace(0xC4, "Out of space. Command could not be completed because of a lack of storage space required to execute the given command operation."), + ReservationCanceled(0xC5, "Reservation Canceled or Invalid Reservation ID."), + RequestDataTruncated(0xC6, "Request data truncated."), + RequestDataLengthInvalid(0xC7, "Request data length invalid."), + RequestDataFieldLengthExceed(0xC8, "Request data field length limit exceeded."), + ParameterOutOfRange(0xC9, "Parameter out of range. "), + CannotReturnRequestedData(0xCA, "Cannot return number of requested data bytes."), + RequestDataNotPresent(0xCB, "Requested Sensor, data, or record not present"), + InvalidDataFieldRequest(0xCC, "Invalid data field in Request"), + CommandIllegalForSDR(0xCD, "Command illegal for specified sensor or record type."), + CommandResponseNotProvided(0xCE, "Command response could not be provided."), + DuplicateRequest(0xCF, "Cannot execute duplicated request. "), + SDRRepositoryInUpdateMode(0xD0, "Command response could not be provided. SDR Repository in update mode"), + FirmwareUpdateMode(0xD1, "Command response could not be provided. Device in firmware update mode."), + BMCInitialization(0xD2, "Command response could not be provided. BMC initialization or initialization agent in progress."), + DestinationUnavailable(0xD3, "Destination unavailable. Cannot deliver request to selected destination."), + InsufficientPrivilege(0xD4, "Cannot execute command due to insufficient privilege level or other security-based restriction (e.g. disabled for 'firmware firewall)"), + NotSupportedCommand(0xD5, "Cannot execute command. Command, or request parameter(s), not supported in present state."), + ParameterIllegal(0xD6, "Cannot execute command. Parameter is illegal because command sub-function has been disabled or is unavailable (e.g. disabled for 'firmware firewall')."), + UnspecifiedError(0xFF, "Unspecified error.") + ; + + + private final byte code; + private final String description; + + public static final int MASK = 0xFF; + + private IpmiCompletionCode(int code, String description) { + this.code = ByteConvertUtils.checkCastByte(code); + this.description = description; + } + + @Override + public byte getCode() { + return code; + } + + @Override + public String getDescription() { + return description; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiLun.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiLun.java new file mode 100644 index 00000000000..be8d20c304a --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiLun.java @@ -0,0 +1,44 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 13.8 + */ +public enum IpmiLun implements IpmiCode.Code { + L0(0), L1(1), L2(2), L3(3); + public static final int MASK = 0x03; + private final byte code; + + private IpmiLun(int value) { + this.code = ByteConvertUtils.checkCastByte(value); + } + + @Override + public byte getCode() { + return code; + } + + public int getValue() { + return getCode() & MASK; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiNetworkFunctionCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiNetworkFunctionCode.java new file mode 100644 index 00000000000..84b2e225f81 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiNetworkFunctionCode.java @@ -0,0 +1,59 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.IpmiCommand; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.IpmiResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 5.1 + */ +public enum IpmiNetworkFunctionCode implements IpmiCode.Code { + + Chassis(0x00), + Bridge(0x02), + Sensor_Event(0x04), + App(0x06), + Firmware(0x08), + Storage(0x0A), + Transport(0x0C), + GroupExtension(0x2C), + OEM_Group(0x2E); + + private final byte code; + + public static final int MASK = 0x3F; + + private IpmiNetworkFunctionCode(int code) { + this.code = ByteConvertUtils.checkCastByte(code); + } + + @Override + public byte getCode() { + return code; + } + + public int getCode(IpmiCommand command) { + if (command instanceof IpmiResponse) { + return (code | 0x1); + } + return code; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiSessionAuthenticationType.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiSessionAuthenticationType.java new file mode 100644 index 00000000000..a1c19d6865f --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiSessionAuthenticationType.java @@ -0,0 +1,43 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 13.6 + */ +public enum IpmiSessionAuthenticationType implements IpmiCode.Code { + NONE(0), + MD2(1), + MD5(2), + PASSWORD(4), + OEM_PROPRIETARY(5), + RMCPP(6); + private final byte code; + + private IpmiSessionAuthenticationType(int code) { + this.code = ByteConvertUtils.checkCastByte(code); + } + + @Override + public byte getCode() { + return code; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiSessionWrapper.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiSessionWrapper.java new file mode 100644 index 00000000000..5215c0d25cd --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/IpmiSessionWrapper.java @@ -0,0 +1,41 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiEncapsulation; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.IpmiPayload; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.rmcp.RmcpData; + +/** + * Ipmi Session Wrapper Interface + */ +public interface IpmiSessionWrapper extends RmcpData, IpmiEncapsulation.Encapsulation { + + int getIpmiSessionId(); + + void setIpmiSessionId(int ipmiSessionId); + + int getIpmiSessionSequenceNumber(); + + void setIpmiSessionSequenceNumber(int ipmiSessionSequenceNumber); + + IpmiPayload getIpmiPayload(); + + void setIpmiPayload(IpmiPayload ipmiPayload); + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/AbstractIpmiCommand.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/AbstractIpmiCommand.java new file mode 100644 index 00000000000..e56e6d98c67 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/AbstractIpmiCommand.java @@ -0,0 +1,126 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiLun; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.AbstractIpmiPayload; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.IpmiPayloadType; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity.IntegrityUtils; + +/** + * Abstract IPMI command. See IPMIv2 Section 13.8 + */ +public abstract class AbstractIpmiCommand extends AbstractIpmiPayload implements IpmiCommand { + private static final int SEQUENCE_NUMBER_MASK = 0x3F; + private byte rsAddress = 0x20; + private IpmiLun rsLun = IpmiLun.L0; + private byte rqAddress = (byte) 0x81; + private IpmiLun rqLun = IpmiLun.L0; + private byte sequenceNumber; + + @Override + public IpmiPayloadType getPayloadType() { + return IpmiPayloadType.IPMI; + } + + @Override + public byte getRsAddress() { + return rsAddress; + } + + @Override + public IpmiLun getRsLun() { + return rsLun; + } + + @Override + public byte getRqAddress() { + return rqAddress; + } + + @Override + public IpmiLun getRqLun() { + return rqLun; + } + + public void setRqLun(IpmiLun rqLun) { + this.rqLun = rqLun; + } + + @Override + public byte getSequenceNumber() { + return sequenceNumber; + } + + @Override + public void setSequenceNumber(byte sequenceNumber) { + this.sequenceNumber = (byte) (sequenceNumber & SEQUENCE_NUMBER_MASK); + } + + @Override + public int getWireLength(IpmiPacketContext context) { + return 7 + getDataWireLength(context); + } + + public abstract int getDataWireLength(IpmiPacketContext context); + + public abstract void toWireData(IpmiPacketContext context, ByteBuffer buffer); + + @Override + public void toWire(IpmiPacketContext context, ByteBuffer buffer) { + int c1 = buffer.position(); + buffer.put(getRsAddress()); + int netFn = getCommandName().getNetworkFunction().getCode(this); + buffer.put((byte) (netFn << 2 | getRsLun().getValue())); + byte c1sum = IntegrityUtils.calculateChecksum(buffer, c1); + buffer.put(c1sum); + int c2 = buffer.position(); + buffer.put(getRqAddress()); + byte seq = (byte) (getSequenceNumber() & SEQUENCE_NUMBER_MASK); + buffer.put((byte) (seq << 2 | getRqLun().getValue())); + buffer.put(getCommandName().getCode()); + toWireData(context, buffer); + byte c2sum = IntegrityUtils.calculateChecksum(buffer, c2); + buffer.put(c2sum); + } + + public abstract void fromWireData(IpmiPacketContext context, ByteBuffer buffer); + + @Override + public void fromWire(IpmiPacketContext context, ByteBuffer buffer) { + int c1 = buffer.position(); + rqAddress = buffer.get(); + int tmp = buffer.get(); + rqLun = IpmiCode.fromInt(IpmiLun.class, tmp & IpmiLun.MASK); + IntegrityUtils.validChecksum(buffer, c1); + int c2 = buffer.position(); + rsAddress = buffer.get(); + tmp = buffer.get(); + sequenceNumber = (byte) (tmp >>> 2 & SEQUENCE_NUMBER_MASK); + rsLun = IpmiCode.fromInt(IpmiLun.class, tmp & IpmiLun.MASK); + buffer.get(); + buffer.limit(buffer.limit() - 1); + fromWireData(context, buffer); + buffer.limit(buffer.limit() + 1); + IntegrityUtils.validChecksum(buffer, c2); + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/AbstractIpmiRequest.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/AbstractIpmiRequest.java new file mode 100644 index 00000000000..f7b98645255 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/AbstractIpmiRequest.java @@ -0,0 +1,31 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; + +/** + * Abstract class for IPMI command request + */ +public abstract class AbstractIpmiRequest extends AbstractIpmiCommand implements IpmiRequest { + @Override + public void fromWireData(IpmiPacketContext context, ByteBuffer buffer) { + throw new UnsupportedOperationException("Not implemented"); + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/AbstractIpmiResponse.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/AbstractIpmiResponse.java new file mode 100644 index 00000000000..0dff106b8dc --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/AbstractIpmiResponse.java @@ -0,0 +1,50 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCompletionCode; + +/** + * Abstract class for IPMI command response + */ +public abstract class AbstractIpmiResponse extends AbstractIpmiCommand implements IpmiResponse { + + public IpmiCompletionCode completionCode; + + @Override + public void toWireData(IpmiPacketContext context, ByteBuffer buffer) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public void fromWireData(IpmiPacketContext context, ByteBuffer buffer) { + completionCode = IpmiCode.fromByte(IpmiCompletionCode.class, buffer.get()); + fromResponseData(context, buffer); + } + + @Override + public int getDataWireLength(IpmiPacketContext context) { + return 0; + } + + public abstract void fromResponseData(IpmiPacketContext context, ByteBuffer buffer); + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/IpmiCommand.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/IpmiCommand.java new file mode 100644 index 00000000000..ae40681e20c --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/IpmiCommand.java @@ -0,0 +1,45 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiLun; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.IpmiPayload; + +/** + * IPMI Command interface + */ +public interface IpmiCommand extends IpmiPayload { + + byte getRsAddress(); + + IpmiLun getRsLun(); + + byte getRqAddress(); + + IpmiLun getRqLun(); + + void setRqLun(IpmiLun lun); + + byte getSequenceNumber(); + + void setSequenceNumber(byte sequenceNumber); + + IpmiCommandName getCommandName(); + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/IpmiRequest.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/IpmiRequest.java new file mode 100644 index 00000000000..a9c34e15135 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/IpmiRequest.java @@ -0,0 +1,24 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command; + +/** + * Ipmi request interface + */ +public interface IpmiRequest extends IpmiCommand { +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/IpmiResponse.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/IpmiResponse.java new file mode 100644 index 00000000000..c3d66f6dc87 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/IpmiResponse.java @@ -0,0 +1,24 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command; + +/** + * Ipmi response interface + */ +public interface IpmiResponse extends IpmiCommand{ +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/chassis/GetChassisStatusRequest.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/chassis/GetChassisStatusRequest.java new file mode 100644 index 00000000000..3a027e4517e --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/chassis/GetChassisStatusRequest.java @@ -0,0 +1,49 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.chassis; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.AbstractIpmiRequest; + +/** + * See IPMIv2 Section 28.2 + */ +public class GetChassisStatusRequest extends AbstractIpmiRequest { + + @Override + public int getDataWireLength(IpmiPacketContext context) { + return 0; + } + + @Override + public void toWireData(IpmiPacketContext context, ByteBuffer buffer) { + + } + + @Override + public void fromWireData(IpmiPacketContext context, ByteBuffer buffer) { + + } + + @Override + public IpmiCommandName getCommandName() { + return IpmiCommandName.GetChassisStatus; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/chassis/GetChassisStatusResponse.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/chassis/GetChassisStatusResponse.java new file mode 100644 index 00000000000..aa40759848a --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/chassis/GetChassisStatusResponse.java @@ -0,0 +1,116 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.chassis; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.AbstractIpmiResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + + +/** + * See IPMIv2 Section 28.2 + */ +public class GetChassisStatusResponse extends AbstractIpmiResponse { + + public boolean isPowerOn; + public boolean isPowerOverload; + public boolean isPowerInterlock; + public boolean isPowerFault; + public boolean isPowerControlFault; + public String powerRestorePolicy; + public String lastPowerEvent; + public boolean isFanFault; + public boolean isDriveFault; + public boolean isFrontPanelLockoutActive; + + enum PowerRestorePolicy implements IpmiCode.Code { + alwaysOff(0, "Always Off"), + previous(1, "Previous"), + alwaysOn(2, "Always On"), + unknown(3, "Unknown"); + + private final byte code; + private final String description; + + PowerRestorePolicy(int code, String description) { + this.code = ByteConvertUtils.checkCastByte(code); + this.description = description; + } + + @Override + public byte getCode() { + return code; + } + + @Override + public String getDescription() { + return description; + } + } + + enum LastPowerEvent implements IpmiCode.Code { + none(0, "None"), + unknown(1, "Unknown"), + lastPowerOff(2, "Last Power Off"), + lastPowerOn(3, "Last Power On"); + + private final byte code; + private final String description; + + LastPowerEvent(int code, String description) { + this.code = ByteConvertUtils.checkCastByte(code); + this.description = description; + } + + @Override + public byte getCode() { + return code; + } + + @Override + public String getDescription() { + return description; + } + } + + @Override + public IpmiCommandName getCommandName() { + return IpmiCommandName.GetChassisStatus; + } + + @Override + public void fromResponseData(IpmiPacketContext context, ByteBuffer buffer) { + byte t = buffer.get(); + isPowerOn = getBits(t, 0, 0x1) == 1; + isPowerOverload = getBits(t, 1, 0x1) == 1; + isPowerInterlock = getBits(t, 2, 0x1) == 1; + isPowerFault = getBits(t, 3, 0x1) == 1; + isPowerControlFault = getBits(t, 4, 0x1) == 1; + powerRestorePolicy = IpmiCode.fromByte(PowerRestorePolicy.class, getBits(t, 5, 0x3)).getDescription(); + t = buffer.get(); + lastPowerEvent = IpmiCode.fromByte(LastPowerEvent.class, getBits(t, 0, 0x1F)).getDescription(); + t = buffer.get(); + isFrontPanelLockoutActive = getBits(t, 1, 0x1) == 1; + isDriveFault = getBits(t, 2, 0x1) == 1; + isFanFault = getBits(t, 3, 0x1) == 1; + ignoreBytes(buffer, 1); + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/messaging/CloseSessionRequest.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/messaging/CloseSessionRequest.java new file mode 100644 index 00000000000..5a39b8d5fe6 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/messaging/CloseSessionRequest.java @@ -0,0 +1,55 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.messaging; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.AbstractIpmiRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteOrderUtils; + + +/** + * See IPMIv2 Section 22.19 + */ +public class CloseSessionRequest extends AbstractIpmiRequest { + + public final int systemSessionId; + + public CloseSessionRequest(int systemSessionId) { + this.systemSessionId = systemSessionId; + } + + @Override + public int getDataWireLength(IpmiPacketContext context) { + return (systemSessionId == 0) ? 5 : 4; + } + + @Override + public void toWireData(IpmiPacketContext context, ByteBuffer buffer) { + ByteOrderUtils.writeLeInt(buffer, systemSessionId); + if (systemSessionId == 0) { + buffer.put((byte) 0); + } + } + + @Override + public IpmiCommandName getCommandName() { + return IpmiCommandName.CloseSession; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/messaging/CloseSessionResponse.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/messaging/CloseSessionResponse.java new file mode 100644 index 00000000000..f61807a68dd --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/messaging/CloseSessionResponse.java @@ -0,0 +1,53 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.messaging; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCompletionCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.AbstractIpmiResponse; + +/** + * See IPMIv2 Section 22.19 + */ +public class CloseSessionResponse extends AbstractIpmiResponse { + + @Override + public void fromWireData(IpmiPacketContext context, ByteBuffer buffer) { + byte code = buffer.get(); + if (code == (byte) 0x87) { + throw new RuntimeException("invalid Session ID in request"); + } else if (code == (byte) 0x88) { + throw new RuntimeException("invalid Session Handle in request"); + } else { + completionCode = IpmiCode.fromByte(IpmiCompletionCode.class, code); + } + fromResponseData(context, buffer); + } + + @Override + public void fromResponseData(IpmiPacketContext context, ByteBuffer buffer) { + } + + @Override + public IpmiCommandName getCommandName() { + return IpmiCommandName.CloseSession; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/messaging/GetChannelAuthenticationCapabilitiesRequest.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/messaging/GetChannelAuthenticationCapabilitiesRequest.java new file mode 100644 index 00000000000..bf1028baa9d --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/messaging/GetChannelAuthenticationCapabilitiesRequest.java @@ -0,0 +1,54 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.messaging; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiChannelNumberCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiChannelPrivilegeLevel; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.AbstractIpmiRequest; + +/** + * See IPMIv2 Section 22.13 + */ +public class GetChannelAuthenticationCapabilitiesRequest extends AbstractIpmiRequest { + + public IpmiChannelNumberCode channelNumberCode = IpmiChannelNumberCode.PRESENT; + public IpmiChannelPrivilegeLevel channelPrivilegeLevel = IpmiChannelPrivilegeLevel.Administrator; + public int isIpmi20 = 0x1; + + @Override + public int getDataWireLength(IpmiPacketContext context) { + return 2; + } + + @Override + public void toWireData(IpmiPacketContext context, ByteBuffer buffer) { + byte b = 0; + b = setBits(b, 7, 0x1, isIpmi20); + b = setBits(b, 0, IpmiChannelNumberCode.MASK, channelNumberCode.getCode()); + buffer.put(b); + buffer.put(channelPrivilegeLevel.getCode()); + } + + @Override + public IpmiCommandName getCommandName() { + return IpmiCommandName.GetChannelAuthenticationCapabilities; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/messaging/GetChannelAuthenticationCapabilitiesResponse.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/messaging/GetChannelAuthenticationCapabilitiesResponse.java new file mode 100644 index 00000000000..8bddeb64066 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/messaging/GetChannelAuthenticationCapabilitiesResponse.java @@ -0,0 +1,56 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.messaging; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiChannelNumberCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.AbstractIpmiResponse; + +/** + * See IPMIv2 Section 22.13 + */ +public class GetChannelAuthenticationCapabilitiesResponse extends AbstractIpmiResponse { + + public IpmiChannelNumberCode channelNumberCode; + public boolean hasExtendedCapabilities; + public byte kgStatus; + public boolean isSupportIpmi20; + public boolean isSupportIpmi15; + + @Override + public void fromResponseData(IpmiPacketContext context, ByteBuffer buffer) { + channelNumberCode = IpmiCode.fromByte(IpmiChannelNumberCode.class, buffer.get()); + byte tmp = buffer.get(); + hasExtendedCapabilities = getBits(tmp, 7, 0x1) == 0x1; + tmp = buffer.get(); + kgStatus = getBits(tmp, 5, 0x1); + tmp = buffer.get(); + isSupportIpmi20 = getBits(tmp, 1, 0x1) == 0x1; + isSupportIpmi15 = getBits(tmp, 0, 0x1) == 0x1; + ignoreBytes(buffer, 4); + } + + @Override + public IpmiCommandName getCommandName() { + return IpmiCommandName.GetChannelAuthenticationCapabilities; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/GetSdrRequest.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/GetSdrRequest.java new file mode 100644 index 00000000000..2cd2d5f0325 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/GetSdrRequest.java @@ -0,0 +1,72 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr; + +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.AbstractIpmiRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +import java.nio.ByteBuffer; + +/** + * See IPMIv2 Section 33.12 + */ +public class GetSdrRequest extends AbstractIpmiRequest { + + public static byte HEADER_LENGTH = 5; + + public static int RECORD_ID_START = 0x01; + + final int reservationId; + + final int recordId; + + final byte offset; + + final byte byteToRead; + + public GetSdrRequest(int reservationId, int recordId, byte offset, byte byteToRead) { + this.reservationId = reservationId; + this.recordId = recordId; + this.offset = offset; + this.byteToRead = byteToRead; + } + + @Override + public int getDataWireLength(IpmiPacketContext context) { + return 6; + } + + @Override + public void toWireData(IpmiPacketContext context, ByteBuffer buffer) { + byte[] reservationIdBytes = ByteConvertUtils.intToLsMsByte(reservationId); + buffer.put(reservationIdBytes[0]); + buffer.put(reservationIdBytes[1]); + byte[] recordIdBytes = ByteConvertUtils.intToLsMsByte(recordId); + buffer.put(recordIdBytes[0]); + buffer.put(recordIdBytes[1]); + buffer.put(offset); + buffer.put(byteToRead); + } + + @Override + public IpmiCommandName getCommandName() { + return IpmiCommandName.GetSdr; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/GetSdrResponse.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/GetSdrResponse.java new file mode 100644 index 00000000000..cf1ebb7427c --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/GetSdrResponse.java @@ -0,0 +1,131 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.AbstractWireable; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiChannelNumberCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiLun; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.AbstractIpmiResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.code.IpmiEntityIdCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.code.IpmiReadingTypeCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.code.IpmiSensorTypeCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.code.IpmiSensorUnitTypeCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteOrderUtils; + +/** + * See IPMIv2 Section 33.12 + */ +public class GetSdrResponse extends AbstractIpmiResponse { + + public int nextRecordId; + public int recordId; + public byte recordType; + public byte recordLength; + public byte sensorOwnerId; + public IpmiLun sensorOwnerLun; + public IpmiChannelNumberCode sensorOwnerChannelNumber; + public byte sensorNumber; + public IpmiEntityIdCode entityIdCode; + public IpmiSensorTypeCode sensorTypeCode; + public IpmiReadingTypeCode readingTypeCode; + public byte analogDataFormat; + public IpmiSensorUnitTypeCode unitTypeCode; + public byte linear; + public int m; + public int b; + public int k1; + public int k2; + public String sensorIdString; + + + @Override + public void fromResponseData(IpmiPacketContext context, ByteBuffer buffer) { + byte[] recordIdBytes = ByteOrderUtils.readBytes(buffer, 2); + nextRecordId = ByteConvertUtils.lsMsByteToInt(recordIdBytes[0], recordIdBytes[1]); + fromSensorRecordHeader(context, buffer); + int remainingLength = buffer.remaining(); + if (remainingLength == 0) { + return; + } + if (recordType != 0x01) { + buffer.position(buffer.limit()); + return; + } + fromRecordKeyBytes(context, buffer); + fromFullSensorRecord(context, buffer); + } + + @Override + public IpmiCommandName getCommandName() { + return IpmiCommandName.GetSdr; + } + + + public void fromSensorRecordHeader(IpmiPacketContext context, ByteBuffer buffer) { + recordId = ByteOrderUtils.readLeChar(buffer); + ignoreBytes(buffer, 1); + recordType = buffer.get(); + recordLength = buffer.get(); + } + + public void fromRecordKeyBytes(IpmiPacketContext context, ByteBuffer buffer) { + sensorOwnerId = buffer.get(); + byte t = buffer.get(); + sensorOwnerLun = IpmiCode.fromByte(IpmiLun.class, AbstractWireable.getBits(t, IpmiLun.MASK)); + sensorOwnerChannelNumber = IpmiCode.fromByte(IpmiChannelNumberCode.class, AbstractWireable.getBits(t, 4, IpmiChannelNumberCode.MASK)); + sensorNumber = buffer.get(); + } + + public void fromFullSensorRecord(IpmiPacketContext context, ByteBuffer buffer) { + entityIdCode = IpmiCode.fromBuffer(IpmiEntityIdCode.class, buffer); + ignoreBytes(buffer, 3); + sensorTypeCode = IpmiCode.fromBuffer(IpmiSensorTypeCode.class, buffer); + readingTypeCode = IpmiCode.fromBuffer(IpmiReadingTypeCode.class, buffer); + ignoreBytes(buffer, 6); + byte t = buffer.get(); + analogDataFormat = AbstractWireable.getBits(t, 6, 0x3); + unitTypeCode = IpmiCode.fromBuffer(IpmiSensorUnitTypeCode.class, buffer); + ignoreBytes(buffer, 1); + linear = buffer.get(); + short mt = buffer.getShort(); + m = ((mt & 0xFF00) >> 8 | (mt & 0xC0) << 2); + m = ByteConvertUtils.getBitsAsSigned(m, 10); + short ba = buffer.getShort(); + b = ((ba & 0xFF00) >> 8 | (ba & 0xC0) << 2); + b = ByteConvertUtils.getBitsAsSigned(b, 10); + ignoreBytes(buffer, 1); + byte rb = buffer.get(); + k1 = AbstractWireable.getBits(rb, 0, 0xF); + k1 = ByteConvertUtils.getBitsAsSigned(k1, 4); + k2 = AbstractWireable.getBits(rb, 4, 0xF); + k2 = ByteConvertUtils.getBitsAsSigned(k2, 4); + ignoreBytes(buffer, 17); + int length = buffer.get() & 0x1F; + if (buffer.remaining() < length) { + length = buffer.remaining(); + } + byte[] sensorIdBytes = ByteOrderUtils.readBytes(buffer, length); + sensorIdString = new String(sensorIdBytes, StandardCharsets.US_ASCII); + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/GetSensorReadingRequest.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/GetSensorReadingRequest.java new file mode 100644 index 00000000000..fddccfe7d1e --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/GetSensorReadingRequest.java @@ -0,0 +1,50 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.AbstractIpmiRequest; + +/** + * See IPMIv2 Section 35.14 + */ +public class GetSensorReadingRequest extends AbstractIpmiRequest { + + final byte sensorNumber; + + public GetSensorReadingRequest(byte sensorNumber) { + this.sensorNumber = sensorNumber; + } + + @Override + public int getDataWireLength(IpmiPacketContext context) { + return 1; + } + + @Override + public void toWireData(IpmiPacketContext context, ByteBuffer buffer) { + buffer.put(sensorNumber); + } + + @Override + public IpmiCommandName getCommandName() { + return IpmiCommandName.GetSensorReading; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/GetSensorReadingResponse.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/GetSensorReadingResponse.java new file mode 100644 index 00000000000..a38b6618953 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/GetSensorReadingResponse.java @@ -0,0 +1,42 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.AbstractIpmiResponse; + +/** + * See IPMIv2 Section 33.12 + */ +public class GetSensorReadingResponse extends AbstractIpmiResponse { + + public int sensorReading; + + @Override + public void fromResponseData(IpmiPacketContext context, ByteBuffer buffer) { + sensorReading = buffer.get(); + buffer.position(buffer.limit()); + } + + @Override + public IpmiCommandName getCommandName() { + return IpmiCommandName.GetSensorReading; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/ReserveSdrRepositoryRequest.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/ReserveSdrRepositoryRequest.java new file mode 100644 index 00000000000..e38bf620d7f --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/ReserveSdrRepositoryRequest.java @@ -0,0 +1,44 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.AbstractIpmiRequest; + +/** + * See IPMIv2 Section 33.11 + */ +public class ReserveSdrRepositoryRequest extends AbstractIpmiRequest { + + @Override + public int getDataWireLength(IpmiPacketContext context) { + return 0; + } + + @Override + public void toWireData(IpmiPacketContext context, ByteBuffer buffer) { + + } + + @Override + public IpmiCommandName getCommandName() { + return IpmiCommandName.ReserveSdrRepository; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/ReserveSdrRepositoryResponse.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/ReserveSdrRepositoryResponse.java new file mode 100644 index 00000000000..26a0329ec6f --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/ReserveSdrRepositoryResponse.java @@ -0,0 +1,44 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiCommandName; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.AbstractIpmiResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 33.11 + */ +public class ReserveSdrRepositoryResponse extends AbstractIpmiResponse { + + public int reserveId; + + @Override + public void fromResponseData(IpmiPacketContext context, ByteBuffer buffer) { + byte lsReserveId = buffer.get(); + byte msReserveId = buffer.get(); + this.reserveId = ByteConvertUtils.lsMsByteToInt(lsReserveId, msReserveId); + } + + @Override + public IpmiCommandName getCommandName() { + return IpmiCommandName.ReserveSdrRepository; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/code/IpmiEntityIdCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/code/IpmiEntityIdCode.java new file mode 100644 index 00000000000..1867f915bfd --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/code/IpmiEntityIdCode.java @@ -0,0 +1,106 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.code; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 43.14 + */ +public enum IpmiEntityIdCode implements IpmiCode.Code { + + Unspecified(0x00, "unspecified"), + Other(0x01, "other"), + Unknown(0x02, "unknown"), + Processor(0x03, "processor"), + Disk_or_DiskBay(0x04, "disk or disk bay"), + Peripheral_Bay(0x05, "peripheral bay"), + System_Management_Module(0x06, "system management module"), + System_Board(0x07, "system board"), + Memory_Module(0x08, "memory module"), + Processor_Module(0x09, "processor module"), + Power_Supply(0x0A, "power supply"), + Add_in_Card(0x0B, "add-in card"), + Front_Panel_Board(0x0C, "front panel board"), + Back_Panel_Board(0x0D, "back panel board"), + Power_System_Board(0x0E, "power system board"), + Drive_Backplane(0x0F, "drive backplane"), + System_Internal_Expansion_Board(0x10, "system internal expansion board"), + Other_System_Board(0x11, "other system board"), + Processor_Board(0x12, "processor board"), + Power_Unit(0x13, "power unit / power domain"), + Power_Module(0x14, "power module / DC-to-DC converter"), + Power_Management(0x15, "power management / power distribution board"), + Chassis_Back_Panel_Board(0x16, "chassis back panel board"), + System_Chassis(0x17, "system chassis"), + Sub_Chassis(0x18, "sub-chassis"), + Other_Chassis_Board(0x19, "other chassis board"), + Disk_Drive(0x1A, "disk drive"), + Peripheral_Bay_2(0x1B, "Peripheral Bay"), + Device_Bay(0x1C, "device bay"), + Fan(0x1D, "fan / cooling device"), + Cooling_Unit(0x1E, "cooling unit / cooling domain"), + Cable_or_Interconnect(0x1F, "cable / interconnect"), + Memory_Device(0x20, "memory device"), + System_Management_Software(0x21, "system management software"), + System_Firmware(0x22, "system firmware (e.g. BIOS / EFI)"), + Operating_System(0x23, "operating system"), + System_Bus(0x24, "system bus"), + Group(0x25, "group"), + Remote_Management_Communication_Device(0x26, "remote management communication device"), + External_Environment(0x27, "external environment"), + Battery(0x28, "battery"), + Processing_Blade(0x29, "processing blade"), + Connectivity_Switch(0x2A, "connectivity switch"), + Processor_Memory_Module(0x2B, "processor memory module"), + IO_Module(0x2C, "I/O module"), + Processor_IO_Module(0x2D, "processor I/O module"), + Management_Controller(0x2E, "management controller"), + Ipmi_Channel(0x2F, "IPMI channel"), + PCI_Bus(0x30, "PCI bus"), + PCI_Express_Bus(0x31, "PCI Express bus"), + SCSI_Bus_Parallel(0x32, "SCSI bus (parallel)"), + SATA_SAS_Bus(0x33, "SATA / SAS bus"), + Processor_Front_Side_Bus(0x34, "processor front-side bus"), + Real_Time_Clock(0x35, "real-time clock"), + Air_Inlet(0x37, "air inlet"), + Air_Inlet_2(0x40, "air inlet"), + Processor_2(0x41, "processor"), + System_Board_2(0x042, "system board"), + ; + + private byte code; + + private String description; + + IpmiEntityIdCode(int code, String description) { + this.code = ByteConvertUtils.checkCastByte(code); + this.description = description; + } + + @Override + public byte getCode() { + return this.code; + } + + @Override + public String getDescription() { + return this.description; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/code/IpmiReadingTypeCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/code/IpmiReadingTypeCode.java new file mode 100644 index 00000000000..5af43c35dd9 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/code/IpmiReadingTypeCode.java @@ -0,0 +1,52 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.code; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 42.1 + */ +public enum IpmiReadingTypeCode implements IpmiCode.Code{ + Unspecified(0x00), + Threshold(0x01), + Discrete_1(0x02), + Discrete_2(0x03), + Discrete_3(0x04), + Discrete_4(0x05), + Discrete_5(0x06), + Discrete_6(0x07), + Discrete_7(0x08), + Discrete_8(0x09), + Discrete_9(0x0A), + Discrete_10(0x0B), + Discrete_11(0x0C), + Sensor_Specific(0x6F); + + private byte code; + + IpmiReadingTypeCode(int code) { + this.code = ByteConvertUtils.checkCastByte(code); + } + + @Override + public byte getCode() { + return this.code; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/code/IpmiSensorTypeCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/code/IpmiSensorTypeCode.java new file mode 100644 index 00000000000..854eca77687 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/code/IpmiSensorTypeCode.java @@ -0,0 +1,93 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.code; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 42.2 + */ +public enum IpmiSensorTypeCode implements IpmiCode.Code { + Reserved(0x00, "Reserved"), + Temperature(0x01, "Temperature"), + Voltage(0x02, "Voltage"), + Current(0x03, "Current"), + Fan(0x04, "Fan"), + Physical_Security(0x05, "Physical Security"), + Platform_Security(0x06, "Platform Security Violation Attempt"), + Processor(0x07, "Processor"), + Power_Supply(0x08, "Power Supply"), + Power_Unit(0x09, "Power Unit"), + Cooling_Device(0x0A, "Cooling Device"), + Other(0x0B, "Other Units-based Sensor"), + Memory(0x0C, "Memory"), + Drive_Slot_Bay(0x0D, "Drive Slot"), + POST_Memory_Resize(0x0E, "POST Memory Resize"), + System_Firmwares(0x0F, "System Firmwares Progress"), + Event_Logging_Disabled(0x10, "Event Logging Disabled"), + Watchdog1(0x11, "Watchdog 1"), + System_Event(0x12, "System Event"), + Critical_Interrupt(0x13, "Critical Interrupt"), + Button(0x14, "Button / Switch"), + Module_Board(0x15, "Module / Board"), + Microcontroller(0x16, "Microcontroller / Coprocessor"), + Add_in_Card(0x17, "Add-in Card"), + Chassis(0x18, "Chassis"), + Chip_Set(0x19, "Chip Set"), + Other_FRU(0x1A, "Other FRU"), + Cable_Interconnect(0x1B, "Cable / Interconnect"), + Terminator(0x1C, "Terminator"), + System_Boot_Initiated(0x1D, "System Boot / Restart Initiated"), + Boot_Error(0x1E, "Boot Error"), + OS_Boot(0x1F, "Base OS Boot / Installation Status"), + OS_Critical_Stop(0x20, "OS Stop / Shutdown"), + Slot_Connector(0x21, "Slot / Connector"), + System_ACPI_Power_State(0x22, "System ACPI Power State"), + Watchdog2(0x23, "Watchdog 2"), + Platform_Alert(0x24, "Platform Alert"), + Entity_Presence(0x25, "Entity Presence"), + Monitor_ASIC(0x26, "Monitor ASIC / IC"), + LAN(0x27, "LAN"), + Management_Subsystem_Health(0x28, "Management Subsystem Health"), + Battery(0x29, "Battery"), + Session_Audit(0x2A, "Session Audit"), + Version_Change(0x2B, "Version Change"), + FRU_State(0x2C, "FRU State"); + + private byte code; + + private String description; + + IpmiSensorTypeCode(int code, String description) { + this.code = ByteConvertUtils.checkCastByte(code); + this.description = description; + } + + @Override + public byte getCode() { + return code; + } + + @Override + public String getDescription() { + return description; + } + + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/code/IpmiSensorUnitTypeCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/code/IpmiSensorUnitTypeCode.java new file mode 100644 index 00000000000..a666a55ae6a --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/command/sdr/code/IpmiSensorUnitTypeCode.java @@ -0,0 +1,139 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.sdr.code; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 43.17 + */ +public enum IpmiSensorUnitTypeCode implements IpmiCode.Code { + Unspecified(0x00, "Unspecified"), + Degrees_Celsius(0x01, "Degrees C"), + Degrees_Fahrenheit(0x02, "Degrees F"), + Degrees_Kelvin(0x03, "Degrees K"), + Volts(0x04, "Volts"), + Amps(0x05, "Amps"), + Watts(0x06, "Watts"), + Joules(0x07, "Joules"), + Coulombs(0x08, "Coulombs"), + VA(0x09, "VA"), + Nits(0x0A, "Nits"), + Lumen(0x0B, "Lumen"), + Lux(0x0C, "Lux"), + Candela(0x0D, "Candela"), + kPa(0x0E, "kPa"), + PSI(0x0F, "PSI"), + Newton(0x10, "Newton"), + CFM(0x11, "CFM"), + RPM(0x12, "RPM"), + Hz(0x13, "Hz"), + Microsecond(0x14, "Microsecond"), + Millisecond(0x15, "Millisecond"), + Second(0x16, "Second"), + Minute(0x17, "Minute"), + Hour(0x18, "Hour"), + Day(0x19, "Day"), + Week(0x1A, "Week"), + Mil(0x1B, "Mil"), + Inches(0x1C, "Inches"), + Feet(0x1D, "Feet"), + Cu_Inch(0x1E, "Cu in"), + Cu_Feet(0x1F, "Cu feet"), + Mm(0x20, "mm"), + Cm(0x21, "cm"), + Meter(0x22, "m"), + Cu_Cm(0x23, "Cu cm"), + Cu_Meter(0x24, "Cu m"), + Liters(0x25, "Liters"), + Fluid_Ounce(0x26, "Fluid ounce"), + Radians(0x27, "Radians"), + Steradians(0x28, "Steradians"), + Revolutions(0x29, "Revolutions"), + Cycles(0x2A, "Cycles"), + Gravities(0x2B, "Gravities"), + Ounce(0x2C, "Ounce"), + Pound(0x2D, "Pound"), + Ft_Lb(0x2E, "Ft-lb"), + Oz_Inch(0x2F, "Oz-in"), + Gauss(0x30, "Gauss"), + Gilberts(0x31, "Gilberts"), + Henry(0x32, "Henry"), + Millihenry(0x33, "Millihenry"), + Farad(0x34, "Farad"), + Microfarad(0x35, "Microfarad"), + Ohms(0x36, "Ohms"), + Siemens(0x37, "Siemens"), + Mole(0x38, "Mole"), + Becquerel(0x39, "Becquerel"), + PPM(0x3A, "PPM"), + Reserved(0x3B, "Reserved"), + Decibels(0x3C, "Decibels"), + DbA(0x3D, "DbA"), + DbC(0x3E, "DbC"), + Gray(0x3F, "Gray"), + Sievert(0x40, "Sievert"), + Color_Temp_Deg_K(0x41, "Color temp deg K"), + Bit(0x42, "Bit"), + Kilobit(0x43, "Kilobit"), + Megabit(0x44, "Megabit"), + Gigabit(0x45, "Gigabit"), + Byte(0x46, "Byte"), + Kilobyte(0x47, "Kilobyte"), + Megabyte(0x48, "Megabyte"), + Gigabyte(0x49, "Gigabyte"), + Word(0x4A, "Word"), + Dword(0x4B, "Dword"), + Qword(0x4C, "Qword"), + Line(0x4D, "Line"), + Hit(0x4E, "Hit"), + Miss(0x4F, "Miss"), + Retry(0x50, "Retry"), + Reset(0x51, "Reset"), + Overflow(0x52, "Overflow"), + Underrun(0x53, "Underrun"), + Collision(0x54, "Collision"), + Packets(0x55, "Packets"), + Messages(0x56, "Messages"), + Characters(0x57, "Characters"), + Error(0x58, "Error"), + Correctable_Error(0x59, "Correctable error"), + Uncorrectable_Error(0x5A, "Uncorrectable error"), + Fatal_Error(0x5B, "Fatal error"), + Grams(0x5C, "Grams"); + + private byte code; + + private String description; + + IpmiSensorUnitTypeCode(int code, String description) { + this.code = ByteConvertUtils.checkCastByte(code); + this.description = description; + } + + @Override + public byte getCode() { + return code; + } + + @Override + public String getDescription() { + return description; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/AbstractIpmiPayload.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/AbstractIpmiPayload.java new file mode 100644 index 00000000000..601b78843c2 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/AbstractIpmiPayload.java @@ -0,0 +1,26 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.AbstractWireable; + +/** + * Abstract ipmi payload + */ +public abstract class AbstractIpmiPayload extends AbstractWireable implements IpmiPayload { +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/AbstractSessionIpmiPayload.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/AbstractSessionIpmiPayload.java new file mode 100644 index 00000000000..f4a988d9bea --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/AbstractSessionIpmiPayload.java @@ -0,0 +1,63 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * Abstract ipmi session payload + */ +public abstract class AbstractSessionIpmiPayload extends AbstractIpmiPayload { + + /** + * See IPMIv2 Section 13.20 + */ + public enum MaximumPrivilegeLevel implements IpmiCode.Code { + UNSPECIFIED(0), + CALLBACK(1), + USER(2), + OPERATOR(3), + ADMINISTRATOR(4), + OEM(5); + + private byte code; + + public static final int MASK = 0xF; + + MaximumPrivilegeLevel(int code){ + this.code = ByteConvertUtils.checkCastByte(code); + } + + @Override + public byte getCode() { + return code; + } + } + + public byte messageTag; + + public byte getMessageTag() { + return messageTag; + } + + public void setMessageTag(byte messageTag) { + this.messageTag = messageTag; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/IpmiPayload.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/IpmiPayload.java new file mode 100644 index 00000000000..2f38ea35c69 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/IpmiPayload.java @@ -0,0 +1,27 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.Wireable; + +/** + * Ipmi payload interface + */ +public interface IpmiPayload extends Wireable { + IpmiPayloadType getPayloadType(); +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/IpmiPayloadType.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/IpmiPayloadType.java new file mode 100644 index 00000000000..ebdfa114d20 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/IpmiPayloadType.java @@ -0,0 +1,61 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 13.27.3 + */ +public enum IpmiPayloadType implements IpmiCode.Code { + IPMI(0x00, 1, 0), + SOL(0x01, 1, 0), + OEM_EXPLICIT(0x02, -1, -1), + RMCPOpenSessionRequest(0x10, 1, 0), + RMCPOpenSessionResponse(0x11, 1, 0), + RAKPMessage1(0x12, 1, 0), + RAKPMessage2(0x13, 1, 0), + RAKPMessage3(0x14, 1, 0), + RAKPMessage4(0x15, 1, 0), + OEM0(0x20, -1, -1), + OEM1(0x21, -1, -1), + OEM2(0x22, -1, -1), + OEM3(0x23, -1, -1), + OEM4(0x24, -1, -1), + OEM5(0x25, -1, -1), + OEM6(0x26, -1, -1), + OEM7(0x27, -1, -1); + // 6 bits only. + private final byte code; + private final int majorFormat; + private final int minorFormat; + + public static final byte MASK = 0x3f; + + private IpmiPayloadType(int code, int majorFormat, int minorFormat) { + this.code = ByteConvertUtils.checkCastByte(code); + this.majorFormat = majorFormat; + this.minorFormat = minorFormat; + } + + @Override + public byte getCode() { + return code; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/MessageStatusCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/MessageStatusCode.java new file mode 100644 index 00000000000..fb2dcde549b --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/MessageStatusCode.java @@ -0,0 +1,65 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 13.24 + */ +public enum MessageStatusCode implements IpmiCode.Code { + NO_ERRORS(0x00, "No errors"), + INSUFFICIENT_RESOURCE(0x01, "Insufficient resources to create a session"), + INVALID_SESSION_ID(0x02, "Invalid session ID"), + INVALID_PAYLOAD_TYPE(0x03, "Invalid payload type"), + INVALID_AUTHENTICATION_ALGORITHM(0x04, "Invalid authentication algorithm"), + INVALID_INTEGRITY_ALGORITHM(0x05, "Invalid integrity algorithm"), + NO_MATCHING_AUTHENTICATION(0x06, "No matching authentication payload"), + NO_MATCHING_INTEGRITY(0x07, "No matching integrity payload"), + INACTIVE_SESSION(0x08, "Inactive session ID"), + INVALID_ROLE(0x09, "Invalid role"), + UNAUTHORIZED_ROLE(0x0A, "No matching authentication payload"), + INSUFFICIENT_RESOURCE_FOR_ROLE(0x0B, "Insufficient resources to create asession at the requested role"), + INVALID_NAME(0x0C, "Invalid name length"), + UNAUTHORIZED_NAME(0x0D, "Unauthorized name"), + UNAUTHORIZED_GUID(0x0E, "Unauthorized GUID. (GUID that BMCsubmitted in RAKP Message 2 was notaccepted by remote console)"), + INVALID_INTEGRITY_CHECK_VALUE(0x0F, "Invalid integrity check value"), + INVALID_CONFIDENTIALITY_ALGORITHM(0x10, "Invalid confidentiality algorithm"), + NO_CIPHER_SUITE_MATCH(0x11, "No Cipher Suite match with proposed security algorithms"), + ILLEGAL_PARAMETER(0x12, "Illegal or unrecognized parameter"); + + public static final int MASK = 0xff; + private final byte code; + private final String description; + + MessageStatusCode(int code, String description) { + this.code = ByteConvertUtils.checkCastByte(code); + this.description = description; + } + + @Override + public byte getCode() { + return code; + } + + @Override + public String getDescription() { + return description; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RakpMessage1.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RakpMessage1.java new file mode 100644 index 00000000000..e98f62ba6d9 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RakpMessage1.java @@ -0,0 +1,76 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteOrderUtils; + +/** + * See IPMIv2 Section 13.20 + */ +public class RakpMessage1 extends AbstractSessionIpmiPayload { + + public int systemSessionId; + + public byte[] consoleRandomNumber; + + public int nameLookup = 0x1; + + public MaximumPrivilegeLevel maximumPrivilegeLevel; + + @Override + public int getWireLength(IpmiPacketContext context) { + String userName = context.getIpmiSession().getUserName(); + return 28 + ((userName == null) ? 0 : userName.length()); + } + + @Override + public void toWire(IpmiPacketContext context, ByteBuffer buffer) { + buffer.put(messageTag); + reservedBytes(buffer, 3); + systemSessionId = context.getIpmiSession().getSystemSessionId(); + ByteOrderUtils.writeLeInt(buffer, systemSessionId); + consoleRandomNumber = context.getIpmiSession().getConsoleRandomNumber(); + buffer.put(consoleRandomNumber); + byte t = setBits((byte) 0, 4, 0x1, nameLookup); + maximumPrivilegeLevel = context.getIpmiSession().getMaximumPrivilegeLevel(); + t = setBits(t, 0, MaximumPrivilegeLevel.MASK, maximumPrivilegeLevel.getCode()); + buffer.put(t); + reservedBytes(buffer, 2); + String userName = context.getIpmiSession().getUserName(); + if (userName != null) { + byte[] usernameBytes = userName.getBytes(StandardCharsets.US_ASCII); + buffer.put((byte) usernameBytes.length); + buffer.put(usernameBytes); + } else { + buffer.put((byte) 0); + } + } + + @Override + public void fromWire(IpmiPacketContext context, ByteBuffer buffer) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public IpmiPayloadType getPayloadType() { + return IpmiPayloadType.RAKPMessage1; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RakpMessage2.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RakpMessage2.java new file mode 100644 index 00000000000..064facb9a2f --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RakpMessage2.java @@ -0,0 +1,107 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.util.Arrays; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiAuthenticationCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication.IpmiAuthentication; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteOrderUtils; + +/** + * See IPMIv2 Section 13.21 + */ +public class RakpMessage2 extends AbstractSessionIpmiPayload { + + public MessageStatusCode messageStatusCode; + + public int consoleSessionId; + public byte[] systemRandom; + public byte[] systemGuid; + public byte[] keyExchangeAuthenticationCode; + + @Override + public int getWireLength(IpmiPacketContext context) { + return 40 + keyExchangeAuthenticationCode.length; + } + + @Override + public void toWire(IpmiPacketContext context, ByteBuffer buffer) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public void fromWire(IpmiPacketContext context, ByteBuffer buffer) { + messageTag = buffer.get(); + messageStatusCode = IpmiCode.fromBuffer(MessageStatusCode.class, buffer); + ignoreBytes(buffer, 2); + consoleSessionId = ByteOrderUtils.readLeInt(buffer); + systemRandom = ByteOrderUtils.readBytes(buffer, 16); + systemGuid = ByteOrderUtils.readBytes(buffer, 16); + keyExchangeAuthenticationCode = ByteOrderUtils.readBytes(buffer, buffer.remaining()); + byte[] hash = verifyKeyExchangeAuthenticationCode(context.getIpmiSession()); + if (!Arrays.equals(hash, keyExchangeAuthenticationCode)) { + throw new RuntimeException("Key exchange authentication code mismatch"); + } + } + + @Override + public IpmiPayloadType getPayloadType() { + return IpmiPayloadType.RAKPMessage2; + } + + + public byte[] verifyKeyExchangeAuthenticationCode(IpmiSession session) { + String userName = session.getUserName(); + int length = 58 + ((userName == null) ? 0 : userName.length()); + ByteBuffer buffer = ByteBuffer.allocate(length); + ByteOrderUtils.writeLeInt(buffer, session.getConsoleSessionId()); + ByteOrderUtils.writeLeInt(buffer, session.getSystemSessionId()); + ByteOrderUtils.writeBytes(buffer, session.getConsoleRandomNumber()); + ByteOrderUtils.writeBytes(buffer, systemRandom); + ByteOrderUtils.writeBytes(buffer, systemGuid); + byte t = setBits((byte) 0, 4, 0x1, 1); + MaximumPrivilegeLevel maximumPrivilegeLevel = session.getMaximumPrivilegeLevel(); + t = setBits(t, 0, MaximumPrivilegeLevel.MASK, maximumPrivilegeLevel.getCode()); + buffer.put(t); + if (userName != null) { + byte[] usernameBytes = userName.getBytes(StandardCharsets.US_ASCII); + buffer.put((byte) usernameBytes.length); + buffer.put(usernameBytes); + } else { + buffer.put((byte) 0); + } + IpmiAuthenticationCode authenticationCode = session.getAuthenticationAlgorithm(); + IpmiAuthentication authentication = authenticationCode.newIpmiAuthentication(); + if (authentication == null) { + throw new UnsupportedOperationException("Unsupported authentication code: " + authenticationCode); + } + try { + authentication.setKey(session.getPassword().getBytes(StandardCharsets.US_ASCII)); + authentication.setData(buffer.array()); + return authentication.getHash(); + } catch (InvalidKeyException e) { + throw new RuntimeException(e); + } + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RakpMessage3.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RakpMessage3.java new file mode 100644 index 00000000000..8025ecc8345 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RakpMessage3.java @@ -0,0 +1,100 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiAuthenticationCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication.IpmiAuthentication; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteOrderUtils; + +/** + * See IPMIv2 Section 13.22 + */ +public class RakpMessage3 extends AbstractSessionIpmiPayload{ + + private int systemSessionId; + + private MessageStatusCode messageStatusCode = MessageStatusCode.NO_ERRORS; + private byte[] keyExchangeAuthenticationCode; + + @Override + public int getWireLength(IpmiPacketContext context) { + IpmiSession session = context.getIpmiSession(); + IpmiAuthentication authentication = session.getAuthenticationAlgorithm().newIpmiAuthentication(); + if (authentication == null) { + throw new UnsupportedOperationException("Unsupported authentication code: " + session.getAuthenticationAlgorithm()); + } + return 8 + authentication.getHashLength(); + } + + @Override + public void toWire(IpmiPacketContext context, ByteBuffer buffer) { + buffer.put(messageTag); + buffer.put(messageStatusCode.getCode()); + reservedBytes(buffer, 2); + systemSessionId = context.getIpmiSession().getSystemSessionId(); + ByteOrderUtils.writeLeInt(buffer, systemSessionId); + keyExchangeAuthenticationCode = generateKeyExchangeAuthenticationCode(context.getIpmiSession()); + ByteOrderUtils.writeBytes(buffer, keyExchangeAuthenticationCode); + } + + @Override + public void fromWire(IpmiPacketContext context, ByteBuffer buffer) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public IpmiPayloadType getPayloadType() { + return IpmiPayloadType.RAKPMessage3; + } + + private byte[] generateKeyExchangeAuthenticationCode(IpmiSession session) { + String userName = session.getUserName(); + int length = 22 + ((userName == null) ? 0 : userName.length()); + ByteBuffer buffer = ByteBuffer.allocate(length); + ByteOrderUtils.writeBytes(buffer, session.getSystemRandomNumber()); + ByteOrderUtils.writeLeInt(buffer, session.getConsoleSessionId()); + byte t = setBits((byte) 0, 4, 0x1, 1); + MaximumPrivilegeLevel maximumPrivilegeLevel = session.getMaximumPrivilegeLevel(); + t = setBits(t, 0, MaximumPrivilegeLevel.MASK, maximumPrivilegeLevel.getCode()); + buffer.put(t); + if (userName != null) { + byte[] usernameBytes = userName.getBytes(StandardCharsets.US_ASCII); + buffer.put((byte) usernameBytes.length); + buffer.put(usernameBytes); + } else { + buffer.put((byte) 0); + } + IpmiAuthenticationCode authenticationCode = session.getAuthenticationAlgorithm(); + IpmiAuthentication authentication = authenticationCode.newIpmiAuthentication(); + if (authentication == null) { + throw new UnsupportedOperationException("Unsupported authentication code: " + authenticationCode); + } + try { + authentication.setKey(session.getPassword().getBytes(StandardCharsets.US_ASCII)); + authentication.setData(buffer.array()); + return authentication.getHash(); + } catch (InvalidKeyException e) { + throw new RuntimeException(e); + } + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RakpMessage4.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RakpMessage4.java new file mode 100644 index 00000000000..6b7cf8753db --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RakpMessage4.java @@ -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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload; + +import java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.util.Arrays; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiIntegrityCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity.IpmiIntegrity; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteOrderUtils; + +/** + * See IPMIv2 Section 13.23 + */ +public class RakpMessage4 extends AbstractSessionIpmiPayload { + + private MessageStatusCode messageStatusCode; + + public int consoleSessionId; + + public byte[] integrityCheckValue; + + @Override + public int getWireLength(IpmiPacketContext context) { + return 0; + } + + @Override + public void toWire(IpmiPacketContext context, ByteBuffer buffer) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public void fromWire(IpmiPacketContext context, ByteBuffer buffer) { + messageTag = buffer.get(); + messageStatusCode = IpmiCode.fromBuffer(MessageStatusCode.class, buffer); + ignoreBytes(buffer, 2); + consoleSessionId = ByteOrderUtils.readLeInt(buffer); + integrityCheckValue = ByteOrderUtils.readBytes(buffer, buffer.remaining()); + byte[] hash = verifyIntegrityCheckValue(context.getIpmiSession()); + if (!Arrays.equals(hash, integrityCheckValue)) { + throw new RuntimeException("integrity check value mismatch"); + } + } + + @Override + public IpmiPayloadType getPayloadType() { + return IpmiPayloadType.RAKPMessage4; + } + + + public byte[] verifyIntegrityCheckValue(IpmiSession session) { + int length = 36; + ByteBuffer buffer = ByteBuffer.allocate(length); + ByteOrderUtils.writeBytes(buffer, session.getConsoleRandomNumber()); + ByteOrderUtils.writeLeInt(buffer, session.getSystemSessionId()); + ByteOrderUtils.writeBytes(buffer, session.getSystemGuid()); + IpmiIntegrityCode ipmiIntegrityCode = session.getIntegrityAlgorithm(); + IpmiIntegrity ipmiIntegrity = ipmiIntegrityCode.newIpmiIntegrity(); + if (ipmiIntegrity == null) { + throw new UnsupportedOperationException("Unsupported authentication code: " + ipmiIntegrityCode); + } + try { + ipmiIntegrity.setKey(session.getSik()); + ipmiIntegrity.setData(buffer.array()); + return ipmiIntegrity.getHash(); + } catch (InvalidKeyException e) { + throw new RuntimeException(e); + } + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RmcpPlusOpenSessionRequest.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RmcpPlusOpenSessionRequest.java new file mode 100644 index 00000000000..bbd8cfad83b --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RmcpPlusOpenSessionRequest.java @@ -0,0 +1,79 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiAuthenticationCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiConfidentialityCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiIntegrityCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication.IpmiAuthenticationAlgorithmWrapper; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality.IpmiConfidentialityAlgorithmWrapper; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity.IpmiIntegrityAlgorithmWrapper; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteOrderUtils; + +/** + * See IPMIv2 Section 13.17 + */ +public class RmcpPlusOpenSessionRequest extends AbstractSessionIpmiPayload { + + public AbstractSessionIpmiPayload.MaximumPrivilegeLevel maximumPrivilegeLevel = MaximumPrivilegeLevel.UNSPECIFIED; + + public int consoleSessionId; + + public IpmiAuthenticationCode authenticationCode; + + public IpmiIntegrityCode integrityCode; + + public IpmiConfidentialityCode confidentialityCode; + + @Override + public int getWireLength(IpmiPacketContext context) { + return 32; + } + + @Override + public void toWire(IpmiPacketContext context, ByteBuffer buffer) { + buffer.put(messageTag); + buffer.put(maximumPrivilegeLevel.getCode()); + reservedBytes(buffer, 2); + IpmiSession ipmiSession = context.getIpmiSession(); + consoleSessionId = ipmiSession.getConsoleSessionId(); + authenticationCode = ipmiSession.getAuthenticationAlgorithm(); + integrityCode = ipmiSession.getIntegrityAlgorithm(); + confidentialityCode = ipmiSession.getConfidentialityAlgorithm(); + ByteOrderUtils.writeLeInt(buffer, consoleSessionId); + IpmiAuthenticationAlgorithmWrapper authenticationAlgorithmWrapper = new IpmiAuthenticationAlgorithmWrapper(authenticationCode); + authenticationAlgorithmWrapper.toWire(context, buffer); + IpmiIntegrityAlgorithmWrapper integrityAlgorithmWrapper = new IpmiIntegrityAlgorithmWrapper(integrityCode); + integrityAlgorithmWrapper.toWire(context, buffer); + IpmiConfidentialityAlgorithmWrapper confidentialityAlgorithmWrapper = new IpmiConfidentialityAlgorithmWrapper(confidentialityCode); + confidentialityAlgorithmWrapper.toWire(context, buffer); + } + + @Override + public void fromWire(IpmiPacketContext context, ByteBuffer buffer) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public IpmiPayloadType getPayloadType() { + return IpmiPayloadType.RMCPOpenSessionRequest; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RmcpPlusOpenSessionResponse.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RmcpPlusOpenSessionResponse.java new file mode 100644 index 00000000000..08255ac781a --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/payload/RmcpPlusOpenSessionResponse.java @@ -0,0 +1,79 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiAuthenticationCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiConfidentialityCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiIntegrityCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteOrderUtils; + +/** + * See IPMIv2 Section 13.18 + */ +public class RmcpPlusOpenSessionResponse extends AbstractSessionIpmiPayload { + + public MessageStatusCode messageStatusCode; + public AbstractSessionIpmiPayload.MaximumPrivilegeLevel maximumPrivilegeLevel; + + public IpmiAuthenticationCode authenticationCode; + + public IpmiConfidentialityCode confidentialityCode; + + public IpmiIntegrityCode integrityCode; + + public int consoleSessionId; + + public int systemSessionId; + + @Override + public int getWireLength(IpmiPacketContext context) { + return 0; + } + + @Override + public void toWire(IpmiPacketContext context, ByteBuffer buffer) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public void fromWire(IpmiPacketContext context, ByteBuffer buffer) { + messageTag = buffer.get(); + messageStatusCode = IpmiCode.fromBuffer(MessageStatusCode.class, buffer); + maximumPrivilegeLevel = IpmiCode.fromBufferWithMask(AbstractSessionIpmiPayload.MaximumPrivilegeLevel.class, buffer, MaximumPrivilegeLevel.MASK); + ignoreBytes(buffer, 1); + consoleSessionId = ByteOrderUtils.readLeInt(buffer); + systemSessionId = ByteOrderUtils.readLeInt(buffer); + ignoreBytes(buffer, 4); + authenticationCode = IpmiCode.fromBuffer(IpmiAuthenticationCode.class, buffer); + ignoreBytes(buffer, 3); + ignoreBytes(buffer, 4); + integrityCode = IpmiCode.fromBuffer(IpmiIntegrityCode.class, buffer); + ignoreBytes(buffer, 3); + ignoreBytes(buffer, 4); + confidentialityCode = IpmiCode.fromBuffer(IpmiConfidentialityCode.class, buffer); + ignoreBytes(buffer, 3); + } + + @Override + public IpmiPayloadType getPayloadType() { + return IpmiPayloadType.RMCPOpenSessionResponse; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/AbstractIpmiAlgorithmWrapper.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/AbstractIpmiAlgorithmWrapper.java new file mode 100644 index 00000000000..ff3e08da37f --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/AbstractIpmiAlgorithmWrapper.java @@ -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 org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.AbstractWireable; + +/** + * See IPMIv2 Section 13.19 + */ +public abstract class AbstractIpmiAlgorithmWrapper extends AbstractWireable implements IpmiAlgorithm { + @Override + public int getWireLength(IpmiPacketContext context) { + return 8; + } + + @Override + public void toWire(IpmiPacketContext context, ByteBuffer buffer) { + buffer.put(getPayloadType()); + buffer.putShort((short) 0); + buffer.put((byte) 8); + buffer.put(getCode()); + buffer.put((byte) 0); + buffer.putShort((short) 0); + } + + @Override + public void fromWire(IpmiPacketContext context, ByteBuffer buffer) { + buffer.get(); + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/IpmiAlgorithm.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/IpmiAlgorithm.java new file mode 100644 index 00000000000..946fea51057 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/IpmiAlgorithm.java @@ -0,0 +1,28 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; + +/** + * Ipmi Algorithm interface + */ +public interface IpmiAlgorithm extends IpmiCode.Code { + byte getPayloadType(); + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/IpmiAuthenticationCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/IpmiAuthenticationCode.java new file mode 100644 index 00000000000..537f7de2b2b --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/IpmiAuthenticationCode.java @@ -0,0 +1,62 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication.IpmiAuthentication; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication.None; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication.RakpHmacMd5; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication.RakpHmacSha1; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication.RakpHmacSha256; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 13.28 + */ +public enum IpmiAuthenticationCode implements IpmiCode.Code{ + RAKP_NOME(0x00, None.class), + RAKP_HMAC_SHA1(0x01, RakpHmacSha1.class), + RAKP_HMAC_MD5(0x02, RakpHmacMd5.class), + RAKP_HMAC_SHA256(0x03, RakpHmacSha256.class); + + private final byte code; + + private final Class authentication; + + + IpmiAuthenticationCode(int code, Class authentication) { + this.code = ByteConvertUtils.checkCastByte(code); + this.authentication = authentication; + } + + @Override + public byte getCode() { + return code; + } + + public IpmiAuthentication newIpmiAuthentication() { + if (authentication == null) { + return null; + } + try { + return authentication.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/IpmiConfidentialityCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/IpmiConfidentialityCode.java new file mode 100644 index 00000000000..9d121776326 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/IpmiConfidentialityCode.java @@ -0,0 +1,61 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality.AesCbc128; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality.IpmiConfidentiality; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality.None; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality.Xrc440; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality.Xrc4128; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 13.28.5 + */ +public enum IpmiConfidentialityCode implements IpmiCode.Code { + NONE(0x00, None.class), + AES_CBC_128(0x01, AesCbc128.class), + xRC4_128(0x02, Xrc4128.class), + xRC4_40(0x03, Xrc440.class); + + private final byte code; + + private final Class confidentiality; + + IpmiConfidentialityCode(int code, Class confidentiality) { + this.code = ByteConvertUtils.checkCastByte(code); + this.confidentiality = confidentiality; + } + + @Override + public byte getCode() { + return code; + } + + public IpmiConfidentiality newIpmiConfidentiality() { + if (confidentiality == null) { + return null; + } + try { + return confidentiality.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/IpmiIntegrityCode.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/IpmiIntegrityCode.java new file mode 100644 index 00000000000..4cebf8c5b79 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/IpmiIntegrityCode.java @@ -0,0 +1,63 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity.HmacMd5128; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity.HmacSha196; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity.HmacSha256128; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity.Md5128; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity.IpmiIntegrity; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity.None; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See IPMIv2 Section 13.28.4 + */ +public enum IpmiIntegrityCode implements IpmiCode.Code{ + NONE(0x00, None.class), + HMAC_SHA1_96(0x01, HmacSha196.class), + HMAC_MD5_128(0x02, HmacMd5128.class), + MD5_128(0x03, Md5128.class), + HMAC_SHA256_128(0x04, HmacSha256128.class); + + private final byte code; + + private final Class integrity; + + IpmiIntegrityCode(int code, Class integrity) { + this.code = ByteConvertUtils.checkCastByte(code); + this.integrity = integrity; + } + + @Override + public byte getCode() { + return code; + } + + public IpmiIntegrity newIpmiIntegrity() { + if (integrity == null) { + return null; + } + try { + return integrity.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/AbstractIpmiAuthentication.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/AbstractIpmiAuthentication.java new file mode 100644 index 00000000000..82c58f2692a --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/AbstractIpmiAuthentication.java @@ -0,0 +1,59 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication; + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +/** + * Abstract class for IPMI authentication algorithms. + */ +public abstract class AbstractIpmiAuthentication implements IpmiAuthentication { + + private final Mac mac; + + public AbstractIpmiAuthentication(String algorithm) throws NoSuchAlgorithmException { + this.mac = Mac.getInstance(algorithm); + } + + @Override + public void setKey(byte[] key) throws InvalidKeyException { + SecretKey secretKey = new SecretKeySpec(key, mac.getAlgorithm()); + mac.init(secretKey); + } + + @Override + public void setData(byte[] data) { + mac.update(data); + } + + @Override + public byte[] getHash() { + byte[] hash = mac.doFinal(); + int cutLength = getHashLength(); + if (hash.length > cutLength) { + hash = Arrays.copyOf(hash, cutLength); + } + return hash; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/IpmiAuthentication.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/IpmiAuthentication.java new file mode 100644 index 00000000000..e43f0e375ab --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/IpmiAuthentication.java @@ -0,0 +1,33 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication; + +import java.security.InvalidKeyException; + +/** + * Ipmi authentication interface + */ +public interface IpmiAuthentication { + void setKey(byte[] key) throws InvalidKeyException; + + void setData(byte[] data); + + byte[] getHash(); + + int getHashLength(); +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/IpmiAuthenticationAlgorithmWrapper.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/IpmiAuthenticationAlgorithmWrapper.java new file mode 100644 index 00000000000..8179cb5c6fa --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/IpmiAuthenticationAlgorithmWrapper.java @@ -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 org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.AbstractIpmiAlgorithmWrapper; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiAuthenticationCode; + +/** + * See IPMIv2 Section 13.19 + */ +public class IpmiAuthenticationAlgorithmWrapper extends AbstractIpmiAlgorithmWrapper { + + private final IpmiAuthenticationCode code; + + private final IpmiAuthentication authentication; + + public IpmiAuthenticationAlgorithmWrapper(IpmiAuthenticationCode code) { + this.code = code; + authentication = code.newIpmiAuthentication(); + } + + @Override + public byte getCode() { + return code.getCode(); + } + + @Override + public byte getPayloadType() { + return 0; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/None.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/None.java new file mode 100644 index 00000000000..73b7b681a11 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/None.java @@ -0,0 +1,45 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication; + +import java.security.InvalidKeyException; + +/** + * See IPMIv2 Section 13.28.2 + */ +public class None implements IpmiAuthentication { + + @Override + public void setKey(byte[] key) throws InvalidKeyException { + } + + @Override + public void setData(byte[] data) { + } + + @Override + public byte[] getHash() { + return new byte[0]; + } + + @Override + public int getHashLength() { + return 0; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/RakpHmacMd5.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/RakpHmacMd5.java new file mode 100644 index 00000000000..d5aa6089bd3 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/RakpHmacMd5.java @@ -0,0 +1,34 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication; + +import java.security.NoSuchAlgorithmException; + +/** + * See IPMIv2 Section 13.28.3 + */ +public class RakpHmacMd5 extends AbstractIpmiAuthentication { + public RakpHmacMd5() throws NoSuchAlgorithmException { + super("HmacMD5"); + } + + @Override + public int getHashLength() { + return 16; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/RakpHmacSha1.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/RakpHmacSha1.java new file mode 100644 index 00000000000..c579242b3eb --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/RakpHmacSha1.java @@ -0,0 +1,35 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication; + +import java.security.NoSuchAlgorithmException; + +/** + * See IPMIv2 Section 13.28.1 + */ +public class RakpHmacSha1 extends AbstractIpmiAuthentication { + public RakpHmacSha1() throws NoSuchAlgorithmException { + super("HmacSHA1"); + } + + @Override + public int getHashLength() { + return 20; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/RakpHmacSha256.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/RakpHmacSha256.java new file mode 100644 index 00000000000..fd591efdd2d --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/authentication/RakpHmacSha256.java @@ -0,0 +1,35 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.authentication; + +import java.security.NoSuchAlgorithmException; + +/** + * See IPMIv2 Section 13.28.1b + */ +public class RakpHmacSha256 extends AbstractIpmiAuthentication { + public RakpHmacSha256() throws NoSuchAlgorithmException { + super("HmacSHA256"); + } + + @Override + public int getHashLength() { + return 32; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/AbstractIpmiConfidentiality.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/AbstractIpmiConfidentiality.java new file mode 100644 index 00000000000..59bad4db3e9 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/AbstractIpmiConfidentiality.java @@ -0,0 +1,53 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality; + +import java.nio.ByteBuffer; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * Abstract class for IPMI confidentiality algorithms. + */ +public abstract class AbstractIpmiConfidentiality implements IpmiConfidentiality { + + public final Cipher cipher; + + public AbstractIpmiConfidentiality(String algorithm) throws NoSuchPaddingException, NoSuchAlgorithmException { + this.cipher = Cipher.getInstance(algorithm); + } + + @Override + public int getBlockSize() { + return cipher.getBlockSize(); + } + + public void init(int mode, SecretKeySpec key, IvParameterSpec iv) throws InvalidAlgorithmParameterException, InvalidKeyException { + cipher.init(mode, key, iv); + } + + public void update(ByteBuffer input, ByteBuffer output) throws ShortBufferException { + cipher.update(input, output); + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/AesCbc128.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/AesCbc128.java new file mode 100644 index 00000000000..da4bc25849b --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/AesCbc128.java @@ -0,0 +1,102 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality; + +import java.nio.ByteBuffer; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteOrderUtils; + +/** + * See IPMIv2 Section 13.29 + */ +public class AesCbc128 extends AbstractIpmiConfidentiality{ + public AesCbc128() throws NoSuchPaddingException, NoSuchAlgorithmException { + super("AES/CBC/NoPadding"); + } + + @Override + public void init(int mode, byte[] key, byte[] iv) throws InvalidAlgorithmParameterException, InvalidKeyException { + if (key.length > 16) { + key = Arrays.copyOf(key, 16); + } + super.init(mode, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv)); + } + + @Override + public void encrypt(IpmiSession session, ByteBuffer in, ByteBuffer out) throws InvalidAlgorithmParameterException, InvalidKeyException, ShortBufferException { + byte[] iv = IpmiConfidentialityAlgorithmWrapper.generateIv(); + byte[] secretKey = session.getK2(); + out.put(iv); + this.init(Cipher.ENCRYPT_MODE, secretKey, iv); + int padLength = pad(in.remaining() + 1); + this.update(in, out); + if (padLength > 0) { + ByteBuffer pad = ByteBuffer.allocate(padLength + 1); + for (int i = 1; i <= padLength; i++) { + pad.put(ByteConvertUtils.checkCastByte(i)); + } + pad.put(ByteConvertUtils.checkCastByte(padLength)); + pad.flip(); + this.update(pad, out); + } + } + + @Override + public ByteBuffer decrypt(IpmiSession session, ByteBuffer in) throws InvalidAlgorithmParameterException, InvalidKeyException, ShortBufferException { + + ByteBuffer buffer = ByteBuffer.allocate(in.remaining()); + byte[] iv = ByteOrderUtils.readBytes(in, 16); + byte[] secretKey = session.getK2(); + this.init(Cipher.DECRYPT_MODE, secretKey, iv); + this.update(in, buffer); + int padLength = ByteConvertUtils.byteToInt(buffer.get(buffer.position() - 1)); + for (int i = 1; i <= padLength; i++) + if (ByteConvertUtils.byteToInt(buffer.get(buffer.position() - i - 1)) != padLength - i + 1) + throw new IllegalArgumentException("Bad pad byte " + i); + buffer.limit(buffer.position() - padLength - 1); + buffer.flip(); + return buffer; + } + + @Override + public int pad(int length) { + int t = length % 16; + if (t == 0) + return 0; + return 16 - t; + } + + @Override + public int getEncryptedLength(int length) { + return 16 + length + pad(length); + } + + public void update(ByteBuffer input, ByteBuffer output) throws ShortBufferException { + super.update(input, output); + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/IpmiConfidentiality.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/IpmiConfidentiality.java new file mode 100644 index 00000000000..72a1aae0bef --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/IpmiConfidentiality.java @@ -0,0 +1,41 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality; + +import java.nio.ByteBuffer; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; + +/** + * Confidentiality algorithm interface + */ +public interface IpmiConfidentiality { + + int getBlockSize(); + + void init(int mode, byte[] key, byte[] iv) throws InvalidAlgorithmParameterException, InvalidKeyException; + + void encrypt(IpmiSession session, ByteBuffer in, ByteBuffer out) throws Exception; + + ByteBuffer decrypt(IpmiSession session, ByteBuffer in) throws Exception; + + int pad(int length); + + int getEncryptedLength(int length); +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/IpmiConfidentialityAlgorithmWrapper.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/IpmiConfidentialityAlgorithmWrapper.java new file mode 100644 index 00000000000..2c8191126d2 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/IpmiConfidentialityAlgorithmWrapper.java @@ -0,0 +1,56 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality; + +import java.security.SecureRandom; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.AbstractIpmiAlgorithmWrapper; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiConfidentialityCode; + +/** + * See IPMIv2 Section 13.19 + */ +public class IpmiConfidentialityAlgorithmWrapper extends AbstractIpmiAlgorithmWrapper { + private static final byte PAYLOAD_TYPE = 2; + + private final IpmiConfidentialityCode code; + + private final IpmiConfidentiality ipmiConfidentiality; + + public IpmiConfidentialityAlgorithmWrapper(IpmiConfidentialityCode code) { + this.code = code; + ipmiConfidentiality = code.newIpmiConfidentiality(); + } + + @Override + public byte getCode() { + return code.getCode(); + } + + @Override + public byte getPayloadType() { + return PAYLOAD_TYPE; + } + + public static byte[] generateIv() { + byte[] iv = new byte[16]; + new SecureRandom().nextBytes(iv); + return iv; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/None.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/None.java new file mode 100644 index 00000000000..f5bfcd3dc38 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/None.java @@ -0,0 +1,58 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality; + +import java.nio.ByteBuffer; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; + +/** + * See IPMIv2 Section 13.28.5 + */ +public class None implements IpmiConfidentiality { + + @Override + public int getBlockSize() { + return 1; + } + + @Override + public void init(int mode, byte[] key, byte[] iv) throws InvalidAlgorithmParameterException, InvalidKeyException { + } + + @Override + public void encrypt(IpmiSession session, ByteBuffer in, ByteBuffer out) { + out.put(in); + } + + @Override + public ByteBuffer decrypt(IpmiSession session, ByteBuffer in) { + return in; + } + + @Override + public int pad(int length) { + return 0; + } + + @Override + public int getEncryptedLength(int length) { + return length; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/Xrc4128.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/Xrc4128.java new file mode 100644 index 00000000000..866c8764e8a --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/Xrc4128.java @@ -0,0 +1,59 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality; + +import java.nio.ByteBuffer; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; + +/** + * See IPMIv2 Section 13.30. Not implement now. + */ +public class Xrc4128 implements IpmiConfidentiality{ + @Override + public int getBlockSize() { + return 0; + } + + @Override + public void init(int mode, byte[] key, byte[] iv) throws InvalidAlgorithmParameterException, InvalidKeyException { + + } + + @Override + public void encrypt(IpmiSession session, ByteBuffer in, ByteBuffer out) { + return; + } + + @Override + public ByteBuffer decrypt(IpmiSession session, ByteBuffer in) { + return null; + } + + + @Override + public int pad(int length) { + return 0; + } + + @Override + public int getEncryptedLength(int length) { + return 0; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/Xrc440.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/Xrc440.java new file mode 100644 index 00000000000..26804bf2d14 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/confidentiality/Xrc440.java @@ -0,0 +1,59 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality; + +import java.nio.ByteBuffer; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; + +/** + * See IPMIv2 Section 13.30. Not implement now. + */ +public class Xrc440 implements IpmiConfidentiality{ + @Override + public int getBlockSize() { + return 0; + } + + @Override + public void init(int mode, byte[] key, byte[] iv) throws InvalidAlgorithmParameterException, InvalidKeyException { + + } + + @Override + public void encrypt(IpmiSession session, ByteBuffer in, ByteBuffer out) { + return; + } + + @Override + public ByteBuffer decrypt(IpmiSession session, ByteBuffer in) { + return null; + } + + + @Override + public int pad(int length) { + return 0; + } + + @Override + public int getEncryptedLength(int length) { + return 0; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/AbstractIpmiIntegrity.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/AbstractIpmiIntegrity.java new file mode 100644 index 00000000000..26d1451452f --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/AbstractIpmiIntegrity.java @@ -0,0 +1,59 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity; + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +/** + * Abstract class for IPMI integrity algorithms. + */ +public abstract class AbstractIpmiIntegrity implements IpmiIntegrity { + + private final Mac mac; + + public AbstractIpmiIntegrity(String algorithm) throws NoSuchAlgorithmException { + this.mac = Mac.getInstance(algorithm); + } + + @Override + public void setKey(byte[] key) throws InvalidKeyException { + SecretKey secretKey = new SecretKeySpec(key, mac.getAlgorithm()); + mac.init(secretKey); + } + + @Override + public void setData(byte[] data) { + mac.update(data); + } + + @Override + public byte[] getHash() { + byte[] hash = mac.doFinal(); + int cutLength = getHashLength(); + if (hash.length > cutLength) { + hash = Arrays.copyOf(hash, cutLength); + } + return hash; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/HmacMd5128.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/HmacMd5128.java new file mode 100644 index 00000000000..935865f9c0b --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/HmacMd5128.java @@ -0,0 +1,34 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity; + +import java.security.NoSuchAlgorithmException; + +/** + * See IPMIv2 Section 13.28.4 + */ +public class HmacMd5128 extends AbstractIpmiIntegrity { + public HmacMd5128() throws NoSuchAlgorithmException { + super("HmacMD5"); + } + + @Override + public int getHashLength() { + return 16; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/HmacSha196.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/HmacSha196.java new file mode 100644 index 00000000000..8c4247beee9 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/HmacSha196.java @@ -0,0 +1,34 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity; + +import java.security.NoSuchAlgorithmException; + +/** + * See IPMIv2 Section 13.28.4 + */ +public class HmacSha196 extends AbstractIpmiIntegrity{ + public HmacSha196() throws NoSuchAlgorithmException { + super("HmacSHA1"); + } + + @Override + public int getHashLength() { + return 12; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/HmacSha256128.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/HmacSha256128.java new file mode 100644 index 00000000000..a16618104bc --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/HmacSha256128.java @@ -0,0 +1,35 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity; + +import java.security.NoSuchAlgorithmException; + +/** + * See IPMIv2 Section 13.28.4 + */ +public class HmacSha256128 extends AbstractIpmiIntegrity { + public HmacSha256128() throws NoSuchAlgorithmException { + super("HmacSHA256"); + } + + @Override + public int getHashLength() { + return 16; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/IntegrityUtils.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/IntegrityUtils.java new file mode 100644 index 00000000000..385c6ab04cb --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/IntegrityUtils.java @@ -0,0 +1,42 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity; + +import java.nio.ByteBuffer; + +/** + * IntegrityUtils for verify checksum + */ +public class IntegrityUtils { + public static byte calculateChecksum(ByteBuffer buffer, int start) { + int checksum = 0; + for (int i = start; i < buffer.position(); i++) { + checksum += buffer.get(i); + } + return (byte) -checksum; + } + + public static void validChecksum(ByteBuffer buffer, int start) { + byte exceptChecksum = calculateChecksum(buffer, start); + byte actualChecksum = buffer.get(); + if (exceptChecksum != actualChecksum) { + throw new IllegalArgumentException("Checksum error, except: " + exceptChecksum + ", actual: " + actualChecksum); + } + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/IpmiIntegrity.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/IpmiIntegrity.java new file mode 100644 index 00000000000..fe9fc7c635a --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/IpmiIntegrity.java @@ -0,0 +1,35 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity; + +import java.security.InvalidKeyException; + +/** + * Ipmi Integrity interface + */ +public interface IpmiIntegrity { + + void setKey(byte[] key) throws InvalidKeyException; + + void setData(byte[] data); + + byte[] getHash(); + + int getHashLength(); + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/IpmiIntegrityAlgorithmWrapper.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/IpmiIntegrityAlgorithmWrapper.java new file mode 100644 index 00000000000..aedb4d50ae8 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/IpmiIntegrityAlgorithmWrapper.java @@ -0,0 +1,50 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.AbstractIpmiAlgorithmWrapper; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiIntegrityCode; + +/** + * See IPMIv2 Section 13.19 + */ +public class IpmiIntegrityAlgorithmWrapper extends AbstractIpmiAlgorithmWrapper { + + private static final byte PAYLOAD_TYPE = 1; + + private final IpmiIntegrityCode code; + + private final IpmiIntegrity integrity; + + public IpmiIntegrityAlgorithmWrapper(IpmiIntegrityCode code) { + + this.code = code; + this.integrity = code.newIpmiIntegrity(); + } + + @Override + public byte getCode() { + return code.getCode(); + } + + @Override + public byte getPayloadType() { + return PAYLOAD_TYPE; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/Md5128.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/Md5128.java new file mode 100644 index 00000000000..c00d97c0fa4 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/Md5128.java @@ -0,0 +1,61 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity; + +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; + +/** + * See IPMIv2 Section 13.28.4. Not implement now. + */ +public class Md5128 implements IpmiIntegrity { + + private final MessageDigest digest; + + + public Md5128() throws NoSuchAlgorithmException { + digest = MessageDigest.getInstance("MD5"); + } + + @Override + public void setKey(byte[] key) throws InvalidKeyException { + return; + } + + @Override + public void setData(byte[] data) { + digest.update(data); + } + + @Override + public byte[] getHash() { + byte[] hash = digest.digest(); + int cutLength = getHashLength(); + if (hash.length > cutLength) { + hash = Arrays.copyOf(hash, cutLength); + } + return hash; + } + + @Override + public int getHashLength() { + return 16; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/None.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/None.java new file mode 100644 index 00000000000..cb4e4d9f7bf --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/ipmi/security/integrity/None.java @@ -0,0 +1,44 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.integrity; + +import java.security.InvalidKeyException; + +/** + * See IPMIv2 Section 13.28.4 + */ +public class None implements IpmiIntegrity { + + @Override + public void setKey(byte[] key) throws InvalidKeyException { + } + + @Override + public void setData(byte[] data) { + } + + @Override + public byte[] getHash() { + return new byte[0]; + } + + @Override + public int getHashLength() { + return 0; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/Packet.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/Packet.java new file mode 100644 index 00000000000..25da1e374d4 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/Packet.java @@ -0,0 +1,34 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.rmcp; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiEncapsulation; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.Wireable; + +/** + * RMCP Packet interface + */ +public interface Packet extends Wireable, IpmiEncapsulation.Encapsulation { + + RmcpData getData(); + + T getData(Class type); + + Packet withData(RmcpData data); + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpData.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpData.java new file mode 100644 index 00000000000..aa2a734522d --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpData.java @@ -0,0 +1,28 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.rmcp; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.Wireable; + +/** + * RMCP Data interface + */ +public interface RmcpData extends Wireable { + RmcpMessageClass getMessageClass(); + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpMessageClass.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpMessageClass.java new file mode 100644 index 00000000000..292e5f9eb0a --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpMessageClass.java @@ -0,0 +1,42 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.rmcp; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See ASF 3.2.2.2 RMCP Header + */ +public enum RmcpMessageClass implements IpmiCode.Code { + + ASF(0x06), IPMI(0x07), OEM(0x08); + private final byte code; + + public static final byte MASK = 0x0F; + + private RmcpMessageClass(int code) { + this.code = ByteConvertUtils.checkCastByte(code); + } + + + @Override + public byte getCode() { + return code; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpMessageStatus.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpMessageStatus.java new file mode 100644 index 00000000000..4e53b6882fd --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpMessageStatus.java @@ -0,0 +1,39 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.rmcp; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See ASF 3.2.2.1 RMCP Acknowledge + */ +public enum RmcpMessageStatus implements IpmiCode.Code { + + REQ(0), ACK(1); + private final byte code; + + private RmcpMessageStatus(int code) { + this.code = ByteConvertUtils.checkCastByte(code); + } + + @Override + public byte getCode() { + return code; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpPacket.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpPacket.java new file mode 100644 index 00000000000..f879979a5d7 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpPacket.java @@ -0,0 +1,125 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.rmcp; + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiPacketContext; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.AbstractWireable; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiEncapsulation; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.Ipmi20Ipv4SessionWrapper; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.IpmiSessionAuthenticationType; + +/** + * RMCP Packet See ASF 3.2 Remote Management and Control Protocol (RMCP) + */ +public class RmcpPacket extends AbstractWireable implements Packet{ + + protected static final int RMCP_HEADER_LENGTH = 4; + private final RmcpVersion version = RmcpVersion.ASF_RMCP_1_0; + private byte sequenceNumber = (byte) 0xFF; + private RmcpMessageClass messageClass; + private RmcpMessageStatus messageRole = RmcpMessageStatus.REQ; + private RmcpData data; + + + public RmcpVersion getVersion() { + return version; + } + + public byte getSequenceNumber() { + return sequenceNumber; + } + + public RmcpMessageClass getMessageClass() { + return messageClass; + } + + public RmcpPacket withMessageClass(RmcpMessageClass messageClass) { + this.messageClass = messageClass; + return this; + } + + public RmcpMessageStatus getMessageRole() { + return messageRole; + } + + @Override + public RmcpData getData() { + return data; + } + + @Override + public T getData(Class type) { + return type.cast(getData()); + } + + @Override + public Packet withData(RmcpData data) { + withMessageClass(data.getMessageClass()); + this.data = data; + return this; + } + + @Override + public T getEncapsulated(Class type) { + if (type.isInstance(this)) + return type.cast(this); + return IpmiEncapsulation.getEncapsulated(type, getData()); + } + + + private void toWireHeader(ByteBuffer buffer) { + buffer.put(getVersion().getCode()); + buffer.put((byte) 0x00); + buffer.put(getSequenceNumber()); + byte messageClassByte = getMessageClass().getCode(); + messageClassByte = AbstractWireable.setBits(messageClassByte, 7, 0x01, getMessageRole().getCode()); + buffer.put(messageClassByte); + } + + @Override + public int getWireLength(IpmiPacketContext context) { + return RMCP_HEADER_LENGTH + getData().getWireLength(context); + } + + @Override + public void toWire(IpmiPacketContext context, ByteBuffer buffer) { + toWireHeader(buffer); + getData().toWire(context, buffer); + } + + @Override + public void fromWire(IpmiPacketContext context, ByteBuffer buffer) { + AbstractWireable.ignoreBytes(buffer, 3); + messageClass = IpmiCode.fromBufferWithMask(RmcpMessageClass.class, buffer, RmcpMessageClass.MASK); + int position = buffer.position(); + if (messageClass != RmcpMessageClass.IPMI) { + throw new UnsupportedOperationException("Unsupported RMCP message class " + messageClass); + } + IpmiSessionAuthenticationType type = IpmiCode.fromByte(IpmiSessionAuthenticationType.class, buffer.get(position)); + if (type == IpmiSessionAuthenticationType.RMCPP) { + data = new Ipmi20Ipv4SessionWrapper(); + } else { + throw new UnsupportedOperationException("Unsupported IPMI 1.5 version"); + } + buffer.position(position); + withData(data); + data.fromWire(context, buffer); + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpVersion.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpVersion.java new file mode 100644 index 00000000000..b10bcd6a458 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/protocol/rmcp/RmcpVersion.java @@ -0,0 +1,45 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.protocol.rmcp; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.IpmiCode; +import org.apache.hertzbeat.collector.collect.ipmi2.utils.ByteConvertUtils; + +/** + * See ASF 3.2.2.2 RMCP Header + */ +public enum RmcpVersion implements IpmiCode.Code { + + LEGACY0(0), + LEGACY1(1), + LEGACY2(2), + LEGACY3(3), + LEGACY4(4), + LEGACY5(5), + ASF_RMCP_1_0(6); + final byte code; + + private RmcpVersion(int code) { + this.code = ByteConvertUtils.checkCastByte(code); + } + + @Override + public byte getCode() { + return code; + } +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/utils/ByteCheckUtils.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/utils/ByteCheckUtils.java new file mode 100644 index 00000000000..7c7a9b50413 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/utils/ByteCheckUtils.java @@ -0,0 +1,41 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.utils; + +import java.nio.ByteBuffer; + +/** + * Byte check utils + */ +public class ByteCheckUtils { + + public static void assertBytesInt(ByteBuffer buffer, int exceptInt) { + int actualInt = buffer.getInt() & 0xFF; + if (actualInt != exceptInt) { + throw new IllegalArgumentException("Expected " + exceptInt + ", but got " + actualInt); + } + } + + public static void assertBytesByte(ByteBuffer buffer, byte exceptByte) { + byte actualByte = buffer.get(); + if (actualByte != exceptByte) { + throw new IllegalArgumentException("Expected " + exceptByte + ", but got " + actualByte); + } + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/utils/ByteConvertUtils.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/utils/ByteConvertUtils.java new file mode 100644 index 00000000000..097402a3997 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/utils/ByteConvertUtils.java @@ -0,0 +1,59 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.utils; + +import com.google.common.primitives.UnsignedBytes; + +/** + * Byte convert utils + */ +public class ByteConvertUtils { + + public static int byteToInt(byte b) { + return UnsignedBytes.toInt(b); + } + + public static byte checkCastByte(int i) { + return UnsignedBytes.checkedCast(i); + } + + public static int lsMsByteToInt(byte lsByte, byte msByte) { + return (byteToInt(msByte) << 8) + byteToInt(lsByte); + } + + public static byte[] intToLsMsByte(int i) { + if (i < 0 || i > 0xFFFF) { + throw new IllegalArgumentException("Invalid int value: " + i); + } + byte[] bytes = new byte[2]; + bytes[0] = checkCastByte(i & 0xFF); + bytes[1] = checkCastByte((i >> 8) & 0xFF); + return bytes; + } + + public static int getBitsAsSigned(int value, int n) { + int mask = (1 << n) - 1; + int lowerBits = value & mask; + int signBit = 1 << (n - 1); + if ((lowerBits & signBit) != 0) { + lowerBits |= ~mask; + } + return lowerBits; + } + +} diff --git a/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/utils/ByteOrderUtils.java b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/utils/ByteOrderUtils.java new file mode 100644 index 00000000000..f00ba90ef48 --- /dev/null +++ b/collector/collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/ipmi2/utils/ByteOrderUtils.java @@ -0,0 +1,78 @@ +/* + * 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.hertzbeat.collector.collect.ipmi2.utils; + +import java.nio.ByteBuffer; + +/** + * Byte order read and write utils + */ +public class ByteOrderUtils { + public static long readLeLong(ByteBuffer buffer) { + long value = 0; + for (int i = 0; i < Long.BYTES; i++) { + value |= ((long) buffer.get()) << (i * 8); + } + return value; + } + + public static void writeLeLong(ByteBuffer buffer, long value) { + for (int i = 0; i < Long.BYTES; i++) { + buffer.put((byte) (value >> (i * 8))); + } + } + + public static int readLeInt(ByteBuffer buffer) { + int value = 0; + for (int i = 0; i < Integer.BYTES; i++) { + value |= (buffer.get() & 0xFF) << (i * 8); + } + return value; + } + + public static void writeLeInt(ByteBuffer buffer, int value) { + for (int i = 0; i < Integer.BYTES; i++) { + buffer.put((byte) (value >> (i * 8))); + } + } + + public static char readLeChar(ByteBuffer buffer) { + char value = 0; + for (int i = 0; i < Character.BYTES; i++) { + value |= ((char) buffer.get()) << (i * 8); + } + return value; + } + + public static void writeLeChar(ByteBuffer buffer, char value) { + for (int i = 0; i < Character.BYTES; i++) { + buffer.put((byte) (value >> (i * 8))); + } + } + + public static byte[] readBytes(ByteBuffer buffer, int size) { + byte[] bytes = new byte[size]; + buffer.get(bytes); + return bytes; + } + + public static void writeBytes(ByteBuffer buffer, byte[] bytes) { + buffer.put(bytes); + } + +} diff --git a/collector/collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/ipmi/IpmiSessionWrapperTest.java b/collector/collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/ipmi/IpmiSessionWrapperTest.java new file mode 100644 index 00000000000..1c4c47354db --- /dev/null +++ b/collector/collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/ipmi/IpmiSessionWrapperTest.java @@ -0,0 +1,233 @@ +/* + * 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.hertzbeat.collector.collect.ipmi; + + +import java.nio.ByteBuffer; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.Ipmi20Ipv4SessionWrapper; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.chassis.GetChassisStatusResponse; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage1; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage2; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage3; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage4; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RmcpPlusOpenSessionRequest; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.rmcp.RmcpPacket; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Test case for {@link Ipmi20Ipv4SessionWrapper} + */ +public class IpmiSessionWrapperTest { + + IpmiSession ipmiSession; + + @BeforeEach + void setUp() { + ipmiSession = new IpmiSession(0xA0A2A3A4); + ipmiSession.setUserName("root"); + ipmiSession.setPassword("calvin"); + } + + @Test + void testRmcpPlusOpenSessionRequest() { + RmcpPlusOpenSessionRequest request = new RmcpPlusOpenSessionRequest(); + Ipmi20Ipv4SessionWrapper wrapper = new Ipmi20Ipv4SessionWrapper(); + wrapper.setIpmiPayload(request); + RmcpPacket packet = new RmcpPacket(); + packet.withData(wrapper); + int length = packet.getWireLength(ipmiSession); + ByteBuffer buffer = ByteBuffer.allocate(length); + packet.toWire(ipmiSession, buffer); + buffer.flip(); + byte[] targetBytes = new byte[] { + 0x06, 0x00, (byte) 0xFF, 0x07, 0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, (byte) 0xA4, (byte) 0xA3, (byte) 0xA2, (byte) 0xA0, 0x00, 0x00, 0x00, + 0x08, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, + 0x01, 0x00, 0x00, 0x00 + }; + for (byte targetByte : targetBytes) { + assert targetByte == buffer.get(); + } + } + + @Test + void testRakp1() { + ipmiSession.generateConsoleRandomNumber(); + ipmiSession.setSystemSessionId(0x02000300); + ipmiSession.setConsoleRandomNumber(new byte[]{0x04, 0x79, (byte) 0xfe, (byte) 0xe3, (byte) 0xe0, (byte) 0xa2, 0x67, 0x0a, 0x11, (byte) 0xd3, 0x3f, 0x0e, 0x48, (byte) 0xbe, 0x62, (byte) 0xb8}); + RakpMessage1 request = new RakpMessage1(); + Ipmi20Ipv4SessionWrapper wrapper = new Ipmi20Ipv4SessionWrapper(); + wrapper.setIpmiPayload(request); + RmcpPacket packet = new RmcpPacket(); + packet.withData(wrapper); + int length = packet.getWireLength(ipmiSession); + ByteBuffer buffer = ByteBuffer.allocate(length); + packet.toWire(ipmiSession, buffer); + buffer.flip(); + byte[] targetBytes = new byte[] { + 0x06, 0x00, (byte) 0xFF, 0x07, 0x06, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x04, 0x79, (byte) 0xFE, (byte) 0xE3, (byte) 0xE0, + (byte) 0xA2, 0x67, 0x0A, 0x11, (byte) 0xD3, 0x3F, 0x0E, 0x48, (byte) 0xBE, 0x62, (byte) 0xB8, 0x14, + 0x00, 0x00, 0x04, 0x72, 0x6F, 0x6F, 0x74 + }; + for (byte targetByte : targetBytes) { + assert targetByte == buffer.get(); + } + } + + @Test + void testRakp2() { + byte[] rakp2 = new byte[] { + 0x06, 0x00, (byte) 0xFF, 0x07, 0x06, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, (byte) 0xA4, (byte) 0xA3, (byte) 0xA2, (byte) 0xA0, (byte) 0xA0, (byte) 0xEB, (byte) 0x3B, (byte) 0xBB, + (byte) 0xA9, 0x62, (byte) 0xDB, 0x2A, 0x27, 0x5F, 0x64, 0x6B, (byte) 0xFF, (byte) 0x8A, (byte) 0xC6, + (byte) 0xCF, 0x44, 0x45, 0x4C, 0x4C, 0x39, 0x00, 0x10, 0x38, (byte) 0x80, 0x38, (byte) 0xC4, (byte) 0xC0, 0x4F, + (byte) 0x35, 0x58, 0x31, (byte) 0xE4, (byte) 0xF8, 0x46, 0x42, 0x33, (byte) 0x8B, 0x67, (byte) 0xA8, + 0x3F, 0x4E, (byte) 0xCF, 0x3B, 0x44, (byte) 0xCC, 0x0D, 0x70, (byte) 0xEF, 0x2B, (byte) 0xBD, (byte) 0x92 + }; + ipmiSession.setSystemSessionId(0x02000300); + byte[] consoleRandom = new byte[]{ + 0x04, 0x79, (byte) 0xfe, (byte) 0xe3, (byte) 0xe0, (byte) 0xa2, 0x67, 0x0a, 0x11, (byte) 0xd3, 0x3f, + 0x0e, 0x48, (byte) 0xbe, 0x62, (byte) 0xb8 + }; + ipmiSession.setConsoleRandomNumber(consoleRandom); + RmcpPacket packet = new RmcpPacket(); + packet.fromWire(ipmiSession, ByteBuffer.wrap(rakp2)); + RakpMessage2 rakpMessage2 = packet.getEncapsulated(RakpMessage2.class); + byte[] systemRandomNumber = new byte[] { + (byte) 0xA0, (byte) 0xEB, 0x3B, (byte) 0xBB, (byte) 0xA9, 0x62, + (byte) 0xDB, 0x2A, 0x27, 0x5F, 0x64, 0x6B, (byte) 0xFF, (byte) 0x8A, (byte) 0xC6, (byte) 0xCF + }; + byte[] guid = new byte[] { + 0x44, 0x45, 0x4C, 0x4C, 0x39, 0x00, 0x10, 0x38, (byte) 0x80, 0x38, (byte) 0xC4, + (byte) 0xC0, 0x4F, (byte) 0x35, 0x58, 0x31 + }; + for (int i = 0; i < systemRandomNumber.length; i++) { + assert systemRandomNumber[i] == rakpMessage2.systemRandom[i]; + } + for (int i = 0; i < guid.length; i++) { + assert guid[i] == rakpMessage2.systemGuid[i]; + } + assert rakpMessage2.consoleSessionId == ipmiSession.getConsoleSessionId(); + } + + @Test + void testRakp3() { + byte[] systemRandomNumber = new byte[] { + (byte) 0xA0, (byte) 0xEB, 0x3B, (byte) 0xBB, (byte) 0xA9, 0x62, + (byte) 0xDB, 0x2A, 0x27, 0x5F, 0x64, 0x6B, (byte) 0xFF, (byte) 0x8A, (byte) 0xC6, (byte) 0xCF + }; + byte[] guid = new byte[] { + 0x44, 0x45, 0x4C, 0x4C, 0x39, 0x00, 0x10, 0x38, (byte) 0x80, 0x38, (byte) 0xC4, + (byte) 0xC0, 0x4F, (byte) 0x35, 0x58, 0x31 + }; + ipmiSession.setSystemRandomNumber(systemRandomNumber); + ipmiSession.setSystemGuid(guid); + ipmiSession.setSystemSessionId(0x02000300); + RakpMessage3 request = new RakpMessage3(); + Ipmi20Ipv4SessionWrapper wrapper = new Ipmi20Ipv4SessionWrapper(); + wrapper.setIpmiPayload(request); + RmcpPacket packet = new RmcpPacket(); + packet.withData(wrapper); + int length = packet.getWireLength(ipmiSession); + ByteBuffer buffer = ByteBuffer.allocate(length); + packet.toWire(ipmiSession, buffer); + buffer.flip(); + byte[] targetBytes = new byte[] { + 0x06, 0x00, (byte) 0xFF, 0x07, 0x06, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x6D, (byte) 0x86, (byte) 0xE3, 0x11, (byte) 0xEB, + (byte) 0xB5, (byte) 0xBE, 0x51, (byte) 0x80, 0x16, (byte) 0xFD, 0x14, 0x35, 0x73, 0x3E, (byte) 0xAD, + (byte) 0xBC, (byte) 0xB1, (byte) 0xC4, 0x66 + + }; + for (byte targetByte : targetBytes) { + assert targetByte == buffer.get(); + } + } + + @Test + void testRakp4() { + byte[] rakp4 = new byte[] { + 0x06, 0x00, (byte) 0xFF, 0x07, 0x06, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, (byte) 0xA4, (byte) 0xA3, (byte) 0xA2, (byte) 0xA0, (byte) 0x9C, 0x7C, (byte) 0xEB, + 0x17, (byte) 0xC7, (byte) 0xCA, 0x43, 0x3B, (byte) 0xB0, 0x61, (byte) 0xBA, 0x6D + }; + byte[] consoleRandom = new byte[]{ + 0x04, 0x79, (byte) 0xfe, (byte) 0xe3, (byte) 0xe0, (byte) 0xa2, 0x67, 0x0a, 0x11, (byte) 0xd3, 0x3f, + 0x0e, 0x48, (byte) 0xbe, 0x62, (byte) 0xb8 + }; + ipmiSession.setConsoleRandomNumber(consoleRandom); + byte[] systemRandomNumber = new byte[] { + (byte) 0xA0, (byte) 0xEB, 0x3B, (byte) 0xBB, (byte) 0xA9, 0x62, + (byte) 0xDB, 0x2A, 0x27, 0x5F, 0x64, 0x6B, (byte) 0xFF, (byte) 0x8A, (byte) 0xC6, (byte) 0xCF + }; + ipmiSession.setSystemRandomNumber(systemRandomNumber); + ipmiSession.setSystemSessionId(0x02000300); + byte[] guid = new byte[] { + 0x44, 0x45, 0x4C, 0x4C, 0x39, 0x00, 0x10, 0x38, (byte) 0x80, 0x38, (byte) 0xC4, + (byte) 0xC0, 0x4F, (byte) 0x35, 0x58, 0x31 + }; + ipmiSession.setSystemGuid(guid); + ipmiSession.generateSik(); + RmcpPacket packet = new RmcpPacket(); + packet.fromWire(ipmiSession, ByteBuffer.wrap(rakp4)); + RakpMessage4 rakpMessage4 = packet.getEncapsulated(RakpMessage4.class); + assert rakpMessage4.consoleSessionId == ipmiSession.getConsoleSessionId(); + } + + @Test + void testIpmiMessage() { + byte[] consoleRandom = new byte[]{ + 0x04, 0x79, (byte) 0xfe, (byte) 0xe3, (byte) 0xe0, (byte) 0xa2, 0x67, 0x0a, 0x11, (byte) 0xd3, 0x3f, + 0x0e, 0x48, (byte) 0xbe, 0x62, (byte) 0xb8 + }; + ipmiSession.setConsoleRandomNumber(consoleRandom); + byte[] systemRandomNumber = new byte[] { + (byte) 0xA0, (byte) 0xEB, 0x3B, (byte) 0xBB, (byte) 0xA9, 0x62, + (byte) 0xDB, 0x2A, 0x27, 0x5F, 0x64, 0x6B, (byte) 0xFF, (byte) 0x8A, (byte) 0xC6, (byte) 0xCF + }; + ipmiSession.setSystemRandomNumber(systemRandomNumber); + ipmiSession.setSystemSessionId(0x02000300); + byte[] guid = new byte[] { + 0x44, 0x45, 0x4C, 0x4C, 0x39, 0x00, 0x10, 0x38, (byte) 0x80, 0x38, (byte) 0xC4, + (byte) 0xC0, 0x4F, (byte) 0x35, 0x58, 0x31 + }; + ipmiSession.setSystemGuid(guid); + ipmiSession.generateSik(); + ipmiSession.setK1(ipmiSession.generateK(1)); + ipmiSession.setK2(ipmiSession.generateK(2)); + + byte[] message = { + (byte) 0x06, (byte) 0x00, (byte) 0xff, (byte) 0x07, (byte) 0x06, (byte) 0xc0, (byte) 0xa4, (byte) 0xa3, + (byte) 0xa2, (byte) 0xa0, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x20, (byte) 0x00, + (byte) 0xa0, (byte) 0xeb, (byte) 0x3b, (byte) 0xbb, (byte) 0xa9, (byte) 0x62, (byte) 0xdb, (byte) 0x2a, + (byte) 0x27, (byte) 0x5f, (byte) 0x64, (byte) 0x6b, (byte) 0xff, (byte) 0x8a, (byte) 0xc6, (byte) 0xcf, + (byte) 0x4e, (byte) 0x4e, (byte) 0xe1, (byte) 0xab, (byte) 0xcc, (byte) 0xf7, (byte) 0x72, (byte) 0x09, + (byte) 0x23, (byte) 0x63, (byte) 0xd3, (byte) 0xec, (byte) 0xb6, (byte) 0xdb, (byte) 0xf1, (byte) 0xb7, + (byte) 0xff, (byte) 0xff, (byte) 0x02, (byte) 0x07, (byte) 0x68, (byte) 0x3b, (byte) 0x0e, (byte) 0x61, + (byte) 0x8e, (byte) 0xd6, (byte) 0x6b, (byte) 0x3d, (byte) 0x32, (byte) 0x58, (byte) 0xf1, (byte) 0x1d + }; + + RmcpPacket packet = new RmcpPacket(); + packet.fromWire(ipmiSession, ByteBuffer.wrap(message)); + GetChassisStatusResponse response = packet.getEncapsulated(GetChassisStatusResponse.class); + + } +} diff --git a/collector/collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/ipmi/common/AbstractWireableTest.java b/collector/collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/ipmi/common/AbstractWireableTest.java new file mode 100644 index 00000000000..acf0c4d4cd2 --- /dev/null +++ b/collector/collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/ipmi/common/AbstractWireableTest.java @@ -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 org.apache.hertzbeat.collector.collect.ipmi.common; + +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.common.AbstractWireable; +import org.junit.jupiter.api.Test; + +/** + * Test case for {@link AbstractWireable} + */ +public class AbstractWireableTest { + + public static final byte b = 0b01010101; + + @Test + void testSetBits() { + byte result = AbstractWireable.setBits(b, 0, 0x03, 0x02); + assert result == 0b01010110; + + result = AbstractWireable.setBits(b, 0x03, 0x02); + assert result == 0b01010110; + + result = AbstractWireable.setBits(b, 0x02); + assert result == 0b00000010; + + result = AbstractWireable.setBits(b, 2, 0x03, 0x02); + assert result == 0b01011001; + + result = AbstractWireable.setBits(b, 2, 0x03, 0x04); + assert result == 0b01010001; + } +} diff --git a/collector/collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/ipmi/security/IpmiConfidentialityTest.java b/collector/collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/ipmi/security/IpmiConfidentialityTest.java new file mode 100644 index 00000000000..7e1f4873894 --- /dev/null +++ b/collector/collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/ipmi/security/IpmiConfidentialityTest.java @@ -0,0 +1,65 @@ +/* + * 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.hertzbeat.collector.collect.ipmi.security; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiSession; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.IpmiConfidentialityCode; +import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.security.confidentiality.IpmiConfidentiality; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Test case for {@link IpmiConfidentiality} + */ +public class IpmiConfidentialityTest { + + IpmiSession session; + + @BeforeEach + public void setUp() { + session = new IpmiSession(1); + session.setK2(new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10}); + + } + + @Test + public void testAesCbc128() throws Exception { + String message = "Hello World!"; + IpmiConfidentialityCode code = IpmiConfidentialityCode.AES_CBC_128; + IpmiConfidentiality confidentiality = code.newIpmiConfidentiality(); + ByteBuffer in = ByteBuffer.allocate(1024); + ByteBuffer out = ByteBuffer.allocate(1024); + in.put(message.getBytes(StandardCharsets.UTF_8)); + in.flip(); + assert confidentiality != null; + confidentiality.encrypt(session, in, out); + out.flip(); + ByteBuffer decrypt = confidentiality.decrypt(session, out); + assert message.equals(asString(decrypt)); + } + + private static String asString(final ByteBuffer buffer) { + final ByteBuffer copy = buffer.duplicate(); + final byte[] bytes = new byte[copy.remaining()]; + copy.get(bytes); + return new String(bytes, StandardCharsets.UTF_8); + } +} diff --git a/collector/collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/DispatchConstants.java b/collector/collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/DispatchConstants.java index c94016f0e8d..27b82c54bc0 100644 --- a/collector/collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/DispatchConstants.java +++ b/collector/collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/DispatchConstants.java @@ -142,6 +142,11 @@ public interface DispatchConstants { */ String PROTOCOL_MQTT = "mqtt"; + /** + * protocol ipmi + */ + String PROTOCOL_IPMI = "ipmi"; + // Protocol type related - end // http protocol related - start should reuse HttpHeaders as much as possible diff --git a/collector/collector/src/main/resources/META-INF/services/org.apache.hertzbeat.collector.collect.AbstractCollect b/collector/collector/src/main/resources/META-INF/services/org.apache.hertzbeat.collector.collect.AbstractCollect index 1ece33cf384..086c33afb24 100644 --- a/collector/collector/src/main/resources/META-INF/services/org.apache.hertzbeat.collector.collect.AbstractCollect +++ b/collector/collector/src/main/resources/META-INF/services/org.apache.hertzbeat.collector.collect.AbstractCollect @@ -26,4 +26,5 @@ org.apache.hertzbeat.collector.collect.nebulagraph.NgqlCollectImpl org.apache.hertzbeat.collector.collect.imap.ImapCollectImpl org.apache.hertzbeat.collector.collect.script.ScriptCollectImpl org.apache.hertzbeat.collector.collect.mqtt.MqttCollectImpl +org.apache.hertzbeat.collector.collect.ipmi2.IpmiCollectImpl org.apache.hertzbeat.collector.collect.kafka.KafkaCollectImpl diff --git a/common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java b/common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java index 086c366a4be..d39e9165c1e 100644 --- a/common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java +++ b/common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java @@ -35,6 +35,7 @@ import org.apache.hertzbeat.common.entity.job.protocol.HttpsdProtocol; import org.apache.hertzbeat.common.entity.job.protocol.IcmpProtocol; import org.apache.hertzbeat.common.entity.job.protocol.ImapProtocol; +import org.apache.hertzbeat.common.entity.job.protocol.IpmiProtocol; import org.apache.hertzbeat.common.entity.job.protocol.JdbcProtocol; import org.apache.hertzbeat.common.entity.job.protocol.JmxProtocol; import org.apache.hertzbeat.common.entity.job.protocol.KafkaProtocol; @@ -232,7 +233,10 @@ public class Metrics { * Monitoring configuration information using the public mqtt protocol */ private MqttProtocol mqtt; - + /** + * Monitoring configuration information using the public ipmi protocol + */ + private IpmiProtocol ipmi; /** * Monitoring configuration information using the public kafka protocol */ diff --git a/common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/IpmiProtocol.java b/common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/IpmiProtocol.java new file mode 100644 index 00000000000..8ad76628297 --- /dev/null +++ b/common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/IpmiProtocol.java @@ -0,0 +1,72 @@ +/* + * 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.hertzbeat.common.entity.job.protocol; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * IPMI2 Protocol + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class IpmiProtocol { + /** + * IP ADDRESS OR DOMAIN NAME OF THE PEER HOST + */ + private String host; + + /** + * Peer host port + */ + private String port; + + /** + * UserName + */ + private String username; + + /** + * Password + */ + private String password; + + /** + * command type: Chassis | Sensor | Raw + */ + private String type; + + /** + * (Optional) only used for the specific id search + */ + private String id; + + /** + * (Optional) only used when type is Raw + */ + private Field field; + + + static class Field { + + } +} diff --git a/home/docs/help/ipmi.md b/home/docs/help/ipmi.md new file mode 100644 index 00000000000..65a18528e70 --- /dev/null +++ b/home/docs/help/ipmi.md @@ -0,0 +1,53 @@ +--- +id: ipmi +title: IPMI2 Monitoring +sidebar_label: Server Monitor +keywords: [open source monitoring tool, open source server Monitoring, IPMI Monitoring] +--- + +> Collect and monitor the general performance Metrics of Server using IPMI2. + +**Protocol: IPMI** + +## Pre-monitoring steps + +1. The target server supports the **IPMI2 protocol**. +2. The **BMC** (Baseboard Management Controller) has been configured with a network interface, allowing access to the **IPMI port**. +3. **User accounts** have been configured, and appropriate **permissions** have been assigned to the accounts. + +These are basic checks you can follow, and for further details on enabling and configuring IPMI over LAN, you can consult the specific user manual of the server manufacturer. + +## Configuration Parameters + +| Parameter Name | Parameter Description | +| -------------- |----------------------------------------------------------------------------------------------------------------| +| Target Host | The IPv4, IPv6, or domain name of the monitored peer. Note: without protocol header (e.g., https://, http://). | +| Port | The port number of the server IPMI over LAN, default is 623. | +| Username | IPMI user name | +| Password | IPMI password | + +### Collected Metrics + +#### Metric Set: Chassis + +| Metric Name | Unit | Metric Description | +| -------------------- | ---- | ------------------------------------------------------------ | +| System Power | none | Current Power State. Power is on. | +| Power Overload | none | Power overload. System shutdown because of power overload condition. | +| Power Interlock | none | Power Interlock. | +| Main Power Fault | none | Power fault. Fault detected in main power subsystem. | +| Power Control Fault | none | Power control fault. Controller attempted to turn system power on or off, but systemdid not enter desired state. | +| Power Restore Policy | none | Power restore policy. | +| Last Power Event | none | Last Power Event. | +| Cooling/Fan Fault | none | Cooling/fan fault detected. | +| Drive Fault | none | Drive Fault. | +| Front-Panel Lockout | none | Front Panel Lockout active (power off and reset via chassispush-buttons disabled.) | + +#### Metric Set: Sensor + +| Metric Name | Unit | Metric Description | +| -------------- | ---- | ------------------------------------------------------------ | +| Sensor ID | none | Sensor ID. | +| Entity ID | none | Indicates the physical entity that the sensor is monitoring or is otherwiseassociated with the sensor. | +| Sensor Type | none | Sensor Type. | +| Sensor Reading | none | Current Sensor Reading. | diff --git a/home/i18n/en/docusaurus-plugin-content-docs/current.json b/home/i18n/en/docusaurus-plugin-content-docs/current.json index 1a67acd062c..cba9a0fb8fe 100644 --- a/home/i18n/en/docusaurus-plugin-content-docs/current.json +++ b/home/i18n/en/docusaurus-plugin-content-docs/current.json @@ -43,6 +43,10 @@ "message": "OS Monitor", "description": "The label for category os in sidebar docs" }, + "sidebar.docs.category.server": { + "message": "Server Monitor", + "description": "The label for category Server in sidebar docs" + }, "sidebar.docs.category.threshold": { "message": "Threshold Alarm Setting", "description": "The label for category threshold in sidebar docs" diff --git a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current.json b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current.json index 678cf071cd2..cf4e59a0470 100644 --- a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current.json +++ b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current.json @@ -43,6 +43,10 @@ "message": "操作系统监控", "description": "The label for category os in sidebar docs" }, + "sidebar.docs.category.server": { + "message": "服务器监控", + "description": "The label for category Server in sidebar docs" + }, "sidebar.docs.category.mid": { "message": "中间件监控", "description": "The label for category mid in sidebar docs" diff --git a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/help/ipmi.md b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/help/ipmi.md new file mode 100644 index 00000000000..4b7e34523ed --- /dev/null +++ b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/help/ipmi.md @@ -0,0 +1,55 @@ +--- + +id: ipmi +title: IPMI2 监控 +sidebar_label: Server Monitor +keywords: [开源监控工具, 开源服务器监控, IPMI 监控] + +--- + +> 使用 IPMI2 协议收集并监控服务器的一般性能指标。 + +**协议: IPMI** + +## 监控前操作 + +1. 目标服务器支持 **IPMI2 协议**。 +2. **BMC**(主板管理控制器)已配置了网络接口,允许访问 **IPMI 端口**。 +3. **用户账户**已配置,并为账户分配了适当的**权限**。 + +这些是基本检查项,关于启用和配置 IPMI over LAN 的详细信息,可以参考服务器制造商的具体使用手册。 + +## 配置参数 + +| 参数名称 | 参数描述 | +| -------------- | ------------------------------------------------------------------------------------------------- | +| 目标主机 | 被监控服务器的 IPv4、IPv6 地址或域名。注意:无需添加协议头(例如,https://, http://)。 | +| 端口 | 服务器 IPMI over LAN 的端口号,默认为 623。 | +| 用户名 | IPMI 用户名 | +| 密码 | IPMI 密码 | + +### 采集指标 + +#### 指标集合:Chassis + +| 指标名称 | 单位 | 指标描述 | +| ------------------ | ---- | ------------------------------------------------------------------------ | +| System Power | 无 | 当前电源状态,电源开启。 | +| Power Overload | 无 | 电源过载。系统因电源过载状况而关闭。 | +| Power Interlock | 无 | 电源联锁。 | +| Main Power Fault | 无 | 电源故障。在主电源子系统中检测到故障。 | +| Power Control Fault | 无 | 电源控制故障。控制器试图打开或关闭系统电源,但系统未进入所需状态。 | +| Power Restore Policy | 无 | 电源恢复策略。 | +| Last Power Event | 无 | 最后电源事件。 | +| Cooling/Fan Fault | 无 | 检测到冷却/风扇故障。 | +| Drive Fault | 无 | 硬盘故障。 | +| Front-Panel Lockout | 无 | 前面板锁定已激活(通过机箱按钮禁用电源关闭和重置功能)。 | + +#### 指标集合:Sensor + +| Metric Name | Unit | Metric Description | +| -------------- | ---- | -------------------------------------------- | +| Sensor ID | 无 | 传感器标识。 | +| Entity ID | 无 | 指示传感器正在监控或与传感器关联的物理实体。 | +| Sensor Type | 无 | 传感器类型。 | +| Sensor Reading | 无 | 传感器当前读数。 | diff --git a/manager/src/main/resources/define/app-ipmi.yml b/manager/src/main/resources/define/app-ipmi.yml new file mode 100644 index 00000000000..66a6a148477 --- /dev/null +++ b/manager/src/main/resources/define/app-ipmi.yml @@ -0,0 +1,232 @@ +# 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. + +# The monitoring type category:service-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring +# 监控类型所属类别:service-应用服务 program-应用程序 db-数据库 custom-自定义 os-操作系统 bigdata-大数据 mid-中间件 webserver-web服务器 cache-缓存 cn-云原生 network-网络监控等等 +category: server +# The monitoring type eg: linux windows tomcat mysql aws... +# 监控类型 eg: linux windows tomcat mysql aws... +app: ipmi +# The monitoring i18n name +# 监控类型国际化名称 +name: + zh-CN: IPMI + en-US: IPMI +# The description and help of this monitoring type +# 监控类型的帮助描述信息 +help: + zh-CN: Hertzbeat 对支持 IPMI 服务的服务器进行测量监控。
您可以点击 “新建 IPMI” 并进行配置,或者选择“更多操作”,导入已有配置。 + en-US: Hertzbeat monitoring servers supporting IPMI services. You could click the "New IPMI" button and proceed with the configuration or import an existing setup through the "More Actions" menu. + zh-TW: Hertzbeat 對支援 IPMI 服務的伺服器進行測量監控。
您可以點擊“IPMI”並進行配寘,或者選擇“更多操作”,導入已有配寘。 +helpLink: + zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/ipmi + en-US: https://hertzbeat.apache.org/docs/help/ipmi +# 监控所需输入参数定义(根据定义渲染页面UI) +# Input params define for monitoring(render web ui by the definition) +params: + # field-param field key + # field-变量字段标识符 + - field: host + # name-param field display i18n name + # name-参数字段显示名称 + name: + zh-CN: 目标Host + en-US: Target Host + # type-param field type(most mapping the html input type) + # type-字段类型,样式(大部分映射input标签type属性) + type: host + # required-true or false + # required-是否是必输项 true-必填 false-可选 + required: true + # field-param field key + # field-变量字段标识符 + - field: port + # name-param field display i18n name + # name-参数字段显示名称 + name: + zh-CN: 端口 + en-US: Port + # type-param field type(most mapping the html input type) + # type-字段类型,样式(大部分映射input标签type属性) + type: number + # when type is number, range is required + # 当type为number时,用range表示范围 + range: '[0,65535]' + # required-true or false + # required-是否是必输项 true-必填 false-可选 + required: true + # default value + # 默认值 + defaultValue: 623 + # field-param field key + # field-变量字段标识符 + - field: username + # name-param field display i18n name + # name-参数字段显示名称 + name: + zh-CN: 用户名 + en-US: Username + # type-param field type(most mapping the html input type) + # type-字段类型,样式(大部分映射input标签type属性) + type: text + # when type is text, use limit to limit string length + # 当type为text时,用limit表示字符串限制大小 + limit: 50 + # required-true or false + # required-是否是必输项 true-必填 false-可选 + required: false + # field-param field key + # field-变量字段标识符 + - field: password + # name-param field display i18n name + # name-参数字段显示名称 + name: + zh-CN: 密码 + en-US: Password + # type-param field type(most mapping the html input tag) + # type-字段类型,样式(大部分映射input标签type属性) + type: password + # required-true or false + # required-是否是必输项 true-必填 false-可选 + required: false +# collect metrics config list +# 采集指标配置列表 +metrics: + # metrics - cpu + # 监控指标 - cpu + - name: Chassis + # metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel + # priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue + # 指标采集调度优先级(0->127)->(优先级高->低) 优先级低的指标会等优先级高的指标采集完成后才会被调度, 相同优先级的指标会并行调度采集 + # 优先级为0的指标为可用性指标,即它会被首先调度,采集成功才会继续调度其它指标,采集失败则中断调度 + priority: 0 + # collect metrics content + # 具体监控指标列表 + fields: + # field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field + # field-指标名称, type-指标类型(0-number数字,1-string字符串), unit-指标单位('%','ms','MB'), label-是否是指标标签字段 + - field: system_power + type: 1 + i18n: + zh-CN: 系统电源状态 + en-US: System Power + - field: power_overload + type: 1 + i18n: + zh-CN: 电源过载 + en-US: Power Overload + - field: power_interlock + type: 1 + i18n: + zh-CN: 电源互锁 + en-US: Power Interlock + - field: power_fault + type: 1 + i18n: + zh-CN: 主电源故障 + en-US: Main Power Fault + - field: power_control_fault + type: 1 + i18n: + zh-CN: 电源控制故障 + en-US: Power Control Fault + - field: power_restore_policy + type: 1 + i18n: + zh-CN: 电源恢复策略 + en-US: Power Restore Policy + - field: last_power_event + type: 1 + i18n: + zh-CN: 最后一次电源事件 + en-US: Last Power Event + - field: fan_fault + type: 1 + i18n: + zh-CN: 风扇故障 + en-US: Cooling/Fan Fault + - field: drive_fault + type: 1 + i18n: + zh-CN: 硬盘故障 + en-US: Drive Fault + - field: front_panel_lockout_active + type: 1 + i18n: + zh-CN: 前面板锁定 + en-US: Front-Panel Lockout + # (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field + # (可选)监控指标别名, 做为中间字段与采集数据字段和指标字段映射转换 + # the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk + protocol: ipmi + # the config content when protocol is ipmi + ipmi: + # ipmi host: ipv4 ipv6 domain + host: ^_^host^_^ + # ipmi port + port: ^_^port^_^ + # ipmi username + username: ^_^username^_^ + # ipmi password + password: ^_^password^_^ + # ipmi command type: Chassis | Sensor + type: Chassis + - name: Sensor + # metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel + # priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue + # 指标采集调度优先级(0->127)->(优先级高->低) 优先级低的指标会等优先级高的指标采集完成后才会被调度, 相同优先级的指标会并行调度采集 + # 优先级为0的指标为可用性指标,即它会被首先调度,采集成功才会继续调度其它指标,采集失败则中断调度 + priority: 1 + # collect metrics content + # 具体监控指标列表 + fields: + # field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field + # field-指标名称, type-指标类型(0-number数字,1-string字符串), unit-指标单位('%','ms','MB'), label-是否是指标标签字段 + - field: sensor_id + type: 1 + i18n: + zh-CN: 传感器标识 + en-US: Sensor ID + - field: entity_id + type: 1 + i18n: + zh-CN: 实体标识 + en-US: Entity ID + - field: sensor_type + type: 1 + i18n: + zh-CN: 传感器类型 + en-US: Sensor Type + - field: sensor_reading + type: 1 + i18n: + zh-CN: 传感器读数 + en-US: Sensor Reading + # (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field + # (可选)监控指标别名, 做为中间字段与采集数据字段和指标字段映射转换 + # the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk + protocol: ipmi + # the config content when protocol is ipmi + ipmi: + # ipmi host: ipv4 ipv6 domain + host: ^_^host^_^ + # ipmi port + port: ^_^port^_^ + # ipmi username + username: ^_^username^_^ + # ipmi password + password: ^_^password^_^ + # ipmi command type: Chassis | Sensor + type: Sensor