1 /**
2 * @brief SNMP Error Notification class.
3 *
4 * This file is part of phosphor-snmp project.
5 *
6 * Copyright (c) 2018 IBM Corporation
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 * Note: In near future this file will be autogenerated by the custom parser.
21 *
22 */
23
24 #pragma once
25
26 // net-snmp requires a very specific header include order.
27 // disable clang-format around this block
28 // clang-format off
29 #include <net-snmp/net-snmp-config.h>
30 #include <net-snmp/net-snmp-includes.h>
31 #include <net-snmp/agent/net-snmp-agent-includes.h>
32 // clang-format on
33
34 #include <sdbusplus/server.hpp>
35
36 #include <sstream>
37 #include <string>
38 #include <vector>
39
40 namespace phosphor
41 {
42 namespace network
43 {
44 namespace snmp
45 {
46
47 using OID = std::array<oid, MAX_OID_LEN>;
48 using OID_LEN = size_t;
49 using Type = u_char;
50
51 using Value = std::variant<uint32_t, uint64_t, int32_t, std::string>;
52 // Generic snmp trap ID
53 oid SNMPTrapOID[] = {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0};
54 oid sysuptimeOID[] = {1, 3, 6, 1, 2, 1, 1, 3, 0};
55
56 struct Object
57 {
58 OID oid;
59 OID_LEN oid_len;
60 Type type;
61 Value value;
62 };
63
64 /** @brief Get the ASN object type from the given templatized type.
65 * Specialize this template for handling a specific type.
66 * @tparam T - type of object from ASN type would be decided.
67 * @returns the ASN object type.
68 */
69 template <typename T>
70 u_char getASNType() = delete;
71
72 template <>
getASNType()73 u_char getASNType<uint32_t>()
74 {
75 return ASN_UNSIGNED;
76 }
77
78 template <>
getASNType()79 u_char getASNType<uint64_t>()
80 {
81 return ASN_OPAQUE_U64;
82 }
83
84 template <>
getASNType()85 u_char getASNType<int32_t>()
86 {
87 return ASN_INTEGER;
88 }
89
90 template <>
getASNType()91 u_char getASNType<std::string>()
92 {
93 return ASN_OCTET_STR;
94 }
95
96 /** @class Notification
97 * @brief Notification interface.
98 *
99 * This class implements the sendTrap function which
100 * send the list of objects defined by the specific notification
101 * to the configured SNMP manager.
102 */
103
104 class Notification
105 {
106 public:
107 Notification() = default;
108 Notification(const Notification&) = delete;
109 Notification(Notification&&) = default;
110 Notification& operator=(const Notification&) = delete;
111 Notification& operator=(Notification&&) = default;
112 virtual ~Notification() = default;
113
114 /** @brief Send the snmp trap to the configured
115 * manager.
116 */
117 void sendTrap();
118
119 protected:
120 /** @brief Add the variable in the snmp pdu object.
121 * @param[in] pdu - SNMP pdu object.
122 * @param[in] objID - SNMP object identifier.
123 * @param[in] objIDLen - Object identifier length.
124 * @param[in] type - ASN type of object.
125 * @param[in] val - Value of the object.
126 * @returns true on success otherwise false.
127 */
128 bool addPDUVar(netsnmp_pdu& pdu, const OID& objID, size_t objIDLen,
129 u_char type, Value val);
130
131 /** @brief get the SNMP notification type in the mib
132 * defined format.
133 * This is pure virtual function all the subclasses
134 * need to provide its own defined type.
135 * @returns the notification type string.
136 */
137 virtual std::pair<OID, OID_LEN> getTrapOID() = 0;
138
139 /** @brief get all the objects meta data defined under
140 * this notification.
141 */
142 virtual std::vector<Object> getFieldOIDList() = 0;
143 };
144
145 class TestErrorNotification;
146
147 /** @class ErrorNotification
148 * @brief subclass of Notification
149 *
150 * A Error Notification represents the objects needed by the
151 * Error Object.
152 */
153 class OBMCErrorNotification : public Notification
154 {
155 private:
156 uint32_t OBMCErrorID = 0;
157 uint64_t OBMCErrorTimestamp = 0;
158 int32_t OBMCErrorSeverity = 0;
159 std::string OBMCErrorMessage;
160
161 public:
162 OBMCErrorNotification() = delete;
163 OBMCErrorNotification(const OBMCErrorNotification&) = delete;
164 OBMCErrorNotification(OBMCErrorNotification&&) = default;
165 OBMCErrorNotification& operator=(const OBMCErrorNotification&) = delete;
166 OBMCErrorNotification& operator=(OBMCErrorNotification&&) = default;
167 ~OBMCErrorNotification() = default;
168
169 /** @brief Constructor
170 * @param[in] id - The error entry id.
171 * @param[in] ts - The commit timestamp.
172 * @param[in] sev - The severity of the error.
173 * @param[in] msg - The message of the error.
174 */
OBMCErrorNotification(uint32_t id,uint64_t ts,int32_t sev,std::string msg)175 OBMCErrorNotification(uint32_t id, uint64_t ts, int32_t sev,
176 std::string msg) :
177 OBMCErrorID(id), OBMCErrorTimestamp(ts), OBMCErrorSeverity(sev),
178 OBMCErrorMessage(msg)
179 {}
180
181 protected:
getTrapOID()182 std::pair<OID, OID_LEN> getTrapOID() override
183 {
184 // notification sub types
185 OID id = {1, 3, 6, 1, 4, 1, 49871, 1, 0, 0, 1};
186 OID_LEN idLen = 11;
187 return std::make_pair<OID, OID_LEN>(std::move(id), std::move(idLen));
188 }
189
getFieldOIDList()190 std::vector<Object> getFieldOIDList() override
191 {
192 std::vector<Object> objectList;
193 objectList.reserve(4);
194 {
195 OID_LEN idLen = 11;
196 OID id = {1, 3, 6, 1, 4, 1, 49871, 1, 0, 1, 1};
197 u_char type = getASNType<decltype(OBMCErrorID)>();
198
199 objectList.emplace_back(id, idLen, type, OBMCErrorID);
200 }
201 {
202 OID_LEN idLen = 11;
203 OID id = {1, 3, 6, 1, 4, 1, 49871, 1, 0, 1, 2};
204 u_char type = getASNType<decltype(OBMCErrorTimestamp)>();
205
206 objectList.emplace_back(id, idLen, type, OBMCErrorTimestamp);
207 }
208 {
209 OID_LEN idLen = 11;
210 OID id = {1, 3, 6, 1, 4, 1, 49871, 1, 0, 1, 3};
211 u_char type = getASNType<decltype(OBMCErrorSeverity)>();
212
213 objectList.emplace_back(id, idLen, type, OBMCErrorSeverity);
214 }
215 {
216 OID_LEN idLen = 11;
217 OID id = {1, 3, 6, 1, 4, 1, 49871, 1, 0, 1, 4};
218 u_char type = getASNType<decltype(OBMCErrorMessage)>();
219
220 objectList.emplace_back(id, idLen, type, OBMCErrorMessage);
221 }
222 return objectList;
223 }
224
225 friend class TestErrorNotification;
226 };
227
228 } // namespace snmp
229 } // namespace network
230 } // namespace phosphor
231