1 /*
2 Generated by LwipMibCompiler
3 */
4
5 #include "lwip/apps/snmp_opts.h"
6 #if LWIP_SNMP && LWIP_SNMP_V3
7
8 #include "lwip/apps/snmp_snmpv2_usm.h"
9 #include "lwip/apps/snmp.h"
10 #include "lwip/apps/snmp_core.h"
11 #include "lwip/apps/snmp_scalar.h"
12 #include "lwip/apps/snmp_table.h"
13 #include "lwip/apps/snmpv3.h"
14 #include "snmpv3_priv.h"
15
16 #include "lwip/apps/snmp_snmpv2_framework.h"
17
18 #include <string.h>
19
20 /* --- usmUser 1.3.6.1.6.3.15.1.2 ----------------------------------------------------- */
21
22 static const struct snmp_oid_range usmUserTable_oid_ranges[] = {
23 { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
24 { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
25 { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
26 { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
27 { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
28 { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
29 { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff },
30 { 0, 0xff }, { 0, 0xff }, { 0, 0xff }, { 0, 0xff }
31 };
32
snmp_engineid_to_oid(const char * engineid,u32_t * oid,u32_t len)33 static void snmp_engineid_to_oid(const char *engineid, u32_t *oid, u32_t len)
34 {
35 u8_t i;
36
37 for (i = 0; i < len; i++) {
38 oid[i] = engineid[i];
39 }
40 }
41
snmp_oid_to_name(char * name,const u32_t * oid,size_t len)42 static void snmp_oid_to_name(char *name, const u32_t *oid, size_t len)
43 {
44 u8_t i;
45
46 for (i = 0; i < len; i++) {
47 name[i] = (char)oid[i];
48 }
49 }
50
snmp_name_to_oid(const char * name,u32_t * oid,size_t len)51 static void snmp_name_to_oid(const char *name, u32_t *oid, size_t len)
52 {
53 u8_t i;
54
55 for (i = 0; i < len; i++) {
56 oid[i] = name[i];
57 }
58 }
59
snmp_auth_algo_to_oid(snmpv3_auth_algo_t algo)60 static const struct snmp_obj_id *snmp_auth_algo_to_oid(snmpv3_auth_algo_t algo)
61 {
62 if (algo == SNMP_V3_AUTH_ALGO_MD5) {
63 return &usmHMACMD5AuthProtocol;
64 } else if (algo == SNMP_V3_AUTH_ALGO_SHA) {
65 return &usmHMACMD5AuthProtocol;
66 }
67
68 return &usmNoAuthProtocol;
69 }
70
snmp_priv_algo_to_oid(snmpv3_priv_algo_t algo)71 static const struct snmp_obj_id *snmp_priv_algo_to_oid(snmpv3_priv_algo_t algo)
72 {
73 if (algo == SNMP_V3_PRIV_ALGO_DES) {
74 return &usmDESPrivProtocol;
75 } else if (algo == SNMP_V3_PRIV_ALGO_AES) {
76 return &usmAESPrivProtocol;
77 }
78
79 return &usmNoPrivProtocol;
80 }
81
82 char username[32];
83
usmusertable_get_instance(const u32_t * column,const u32_t * row_oid,u8_t row_oid_len,struct snmp_node_instance * cell_instance)84 static snmp_err_t usmusertable_get_instance(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, struct snmp_node_instance *cell_instance)
85 {
86 const char *engineid;
87 u8_t eid_len;
88
89 u32_t engineid_oid[SNMP_V3_MAX_ENGINE_ID_LENGTH];
90
91 u8_t name_len;
92 u8_t engineid_len;
93
94 u8_t name_start;
95 u8_t engineid_start;
96
97 LWIP_UNUSED_ARG(column);
98
99 snmpv3_get_engine_id(&engineid, &eid_len);
100
101 engineid_len = (u8_t)row_oid[0];
102 engineid_start = 1;
103
104 if (engineid_len != eid_len) {
105 /* EngineID length does not match! */
106 return SNMP_ERR_NOSUCHINSTANCE;
107 }
108
109 if (engineid_len > row_oid_len) {
110 /* row OID doesn't contain enough data according to engineid_len.*/
111 return SNMP_ERR_NOSUCHINSTANCE;
112 }
113
114 /* check if incoming OID length and if values are in plausible range */
115 if (!snmp_oid_in_range(&row_oid[engineid_start], engineid_len, usmUserTable_oid_ranges, engineid_len)) {
116 return SNMP_ERR_NOSUCHINSTANCE;
117 }
118
119 snmp_engineid_to_oid(engineid, engineid_oid, engineid_len);
120
121 /* Verify EngineID */
122 if (snmp_oid_equal(&row_oid[engineid_start], engineid_len, engineid_oid, engineid_len)) {
123 return SNMP_ERR_NOSUCHINSTANCE;
124 }
125
126 name_len = (u8_t)row_oid[engineid_start + engineid_len];
127 name_start = engineid_start + engineid_len + 1;
128
129 if (name_len > SNMP_V3_MAX_USER_LENGTH) {
130 /* specified name is too long */
131 return SNMP_ERR_NOSUCHINSTANCE;
132 }
133
134 if (1 + engineid_len + 1 + name_len != row_oid_len) {
135 /* Length of EngineID and name does not match row oid length. (+2 for length fields)*/
136 return SNMP_ERR_NOSUCHINSTANCE;
137 }
138
139 /* check if incoming OID length and if values are in plausible range */
140 if (!snmp_oid_in_range(&row_oid[name_start], name_len, usmUserTable_oid_ranges, name_len)) {
141 return SNMP_ERR_NOSUCHINSTANCE;
142 }
143
144 /* Verify if user exists */
145 memset(username, 0, sizeof(username));
146 snmp_oid_to_name(username, &row_oid[name_start], name_len);
147 if (snmpv3_get_user(username, NULL, NULL, NULL, NULL) != ERR_OK) {
148 return SNMP_ERR_NOSUCHINSTANCE;
149 }
150
151 /* Save name in reference pointer to make it easier to handle later on */
152 cell_instance->reference.ptr = username;
153 cell_instance->reference_len = name_len;
154
155 /* user was found */
156 return SNMP_ERR_NOERROR;
157 }
158
159 /*
160 * valid oid options
161 * <oid>
162 * <oid>.<EngineID length>
163 * <oid>.<EngineID length>.<partial EngineID>
164 * <oid>.<EngineID length>.<EngineID>
165 * <oid>.<EngineID length>.<EngineID>.<UserName length>
166 * <oid>.<EngineID length>.<EngineID>.<UserName length>.<partial UserName>
167 * <oid>.<EngineID length>.<EngineID>.<UserName length>.<UserName>
168 *
169 */
usmusertable_get_next_instance(const u32_t * column,struct snmp_obj_id * row_oid,struct snmp_node_instance * cell_instance)170 static snmp_err_t usmusertable_get_next_instance(const u32_t *column, struct snmp_obj_id *row_oid, struct snmp_node_instance *cell_instance)
171 {
172 const char *engineid;
173 u8_t eid_len;
174
175 u32_t engineid_oid[SNMP_V3_MAX_ENGINE_ID_LENGTH];
176
177 u8_t name_len;
178 u8_t engineid_len;
179
180 u8_t name_start;
181 u8_t engineid_start = 1;
182 u8_t i;
183
184 struct snmp_next_oid_state state;
185
186 u32_t result_temp[LWIP_ARRAYSIZE(usmUserTable_oid_ranges)];
187
188 LWIP_UNUSED_ARG(column);
189
190 snmpv3_get_engine_id(&engineid, &eid_len);
191
192 /* If EngineID might be given */
193 if (row_oid->len > 0) {
194 engineid_len = (u8_t)row_oid->id[0];
195 engineid_start = 1;
196
197 if (engineid_len != eid_len) {
198 /* EngineID length does not match! */
199 return SNMP_ERR_NOSUCHINSTANCE;
200 }
201
202 if (engineid_len > row_oid->len) {
203 /* Verify partial EngineID */
204 snmp_engineid_to_oid(engineid, engineid_oid, row_oid->len - 1);
205 if (!snmp_oid_equal(&row_oid->id[engineid_start], row_oid->len - 1, engineid_oid, row_oid->len - 1)) {
206 return SNMP_ERR_NOSUCHINSTANCE;
207 }
208 } else {
209 /* Verify complete EngineID */
210 snmp_engineid_to_oid(engineid, engineid_oid, engineid_len);
211 if (!snmp_oid_equal(&row_oid->id[engineid_start], engineid_len, engineid_oid, engineid_len)) {
212 return SNMP_ERR_NOSUCHINSTANCE;
213 }
214 }
215
216 /* At this point, the given EngineID (partially) matches the local EngineID.*/
217
218 /* If name might also be given */
219 if (row_oid->len > engineid_start + engineid_len) {
220 name_len = (u8_t)row_oid->id[engineid_start + engineid_len];
221 name_start = engineid_start + engineid_len + 1;
222
223 if (name_len > SNMP_V3_MAX_USER_LENGTH) {
224 /* specified name is too long, max length is 32 according to mib file.*/
225 return SNMP_ERR_NOSUCHINSTANCE;
226 }
227
228 if (row_oid->len < engineid_len + name_len + 2) {
229 /* Partial name given according to oid.*/
230 u8_t tmplen = row_oid->len - engineid_len - 2;
231 if (!snmp_oid_in_range(&row_oid->id[name_start], tmplen, usmUserTable_oid_ranges, tmplen)) {
232 return SNMP_ERR_NOSUCHINSTANCE;
233 }
234 } else {
235 /* Full name given according to oid. Also test for too much data.*/
236 u8_t tmplen = row_oid->len - engineid_len - 2;
237 if (!snmp_oid_in_range(&row_oid->id[name_start], name_len, usmUserTable_oid_ranges, tmplen)) {
238 return SNMP_ERR_NOSUCHINSTANCE;
239 }
240 }
241
242 /* At this point the EngineID and (partial) UserName match the local EngineID and UserName.*/
243 }
244 }
245
246 /* init struct to search next oid */
247 snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(usmUserTable_oid_ranges));
248
249 for (i = 0; i < snmpv3_get_amount_of_users(); i++) {
250 u32_t test_oid[LWIP_ARRAYSIZE(usmUserTable_oid_ranges)];
251
252 test_oid[0] = eid_len;
253 snmp_engineid_to_oid(engineid, &test_oid[1], eid_len);
254
255 snmpv3_get_username(username, i);
256
257 test_oid[1 + eid_len] = strlen(username);
258 snmp_name_to_oid(username, &test_oid[2 + eid_len], strlen(username));
259
260 /* check generated OID: is it a candidate for the next one? */
261 snmp_next_oid_check(&state, test_oid, (u8_t)(1 + eid_len + 1 + strlen(username)), LWIP_PTR_NUMERIC_CAST(void *, i));
262 }
263
264 /* did we find a next one? */
265 if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
266 snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
267 /* store username for subsequent operations (get/test/set) */
268 memset(username, 0, sizeof(username));
269 snmpv3_get_username(username, LWIP_PTR_NUMERIC_CAST(u8_t, state.reference));
270 cell_instance->reference.ptr = username;
271 cell_instance->reference_len = strlen(username);
272 return SNMP_ERR_NOERROR;
273 }
274
275 /* not found */
276 return SNMP_ERR_NOSUCHINSTANCE;
277 }
278
usmusertable_get_value(struct snmp_node_instance * cell_instance,void * value)279 static s16_t usmusertable_get_value(struct snmp_node_instance *cell_instance, void *value)
280 {
281 snmpv3_user_storagetype_t storage_type;
282
283 switch (SNMP_TABLE_GET_COLUMN_FROM_OID(cell_instance->instance_oid.id)) {
284 case 3: /* usmUserSecurityName */
285 MEMCPY(value, cell_instance->reference.ptr, cell_instance->reference_len);
286 return (s16_t)cell_instance->reference_len;
287 case 4: /* usmUserCloneFrom */
288 MEMCPY(value, snmp_zero_dot_zero.id, snmp_zero_dot_zero.len * sizeof(u32_t));
289 return snmp_zero_dot_zero.len * sizeof(u32_t);
290 case 5: { /* usmUserAuthProtocol */
291 const struct snmp_obj_id *auth_algo;
292 snmpv3_auth_algo_t auth_algo_val;
293 snmpv3_get_user((const char *)cell_instance->reference.ptr, &auth_algo_val, NULL, NULL, NULL);
294 auth_algo = snmp_auth_algo_to_oid(auth_algo_val);
295 MEMCPY(value, auth_algo->id, auth_algo->len * sizeof(u32_t));
296 return auth_algo->len * sizeof(u32_t);
297 }
298 case 6: /* usmUserAuthKeyChange */
299 return 0;
300 case 7: /* usmUserOwnAuthKeyChange */
301 return 0;
302 case 8: { /* usmUserPrivProtocol */
303 const struct snmp_obj_id *priv_algo;
304 snmpv3_priv_algo_t priv_algo_val;
305 snmpv3_get_user((const char *)cell_instance->reference.ptr, NULL, NULL, &priv_algo_val, NULL);
306 priv_algo = snmp_priv_algo_to_oid(priv_algo_val);
307 MEMCPY(value, priv_algo->id, priv_algo->len * sizeof(u32_t));
308 return priv_algo->len * sizeof(u32_t);
309 }
310 case 9: /* usmUserPrivKeyChange */
311 return 0;
312 case 10: /* usmUserOwnPrivKeyChange */
313 return 0;
314 case 11: /* usmUserPublic */
315 /* TODO: Implement usmUserPublic */
316 return 0;
317 case 12: /* usmUserStorageType */
318 snmpv3_get_user_storagetype((const char *)cell_instance->reference.ptr, &storage_type);
319 *(s32_t *)value = storage_type;
320 return sizeof(s32_t);
321 case 13: /* usmUserStatus */
322 *(s32_t *)value = 1; /* active */
323 return sizeof(s32_t);
324 default:
325 LWIP_DEBUGF(SNMP_MIB_DEBUG, ("usmusertable_get_value(): unknown id: %"S32_F"\n", SNMP_TABLE_GET_COLUMN_FROM_OID(cell_instance->instance_oid.id)));
326 return 0;
327 }
328 }
329
330 /* --- usmMIBObjects 1.3.6.1.6.3.15.1 ----------------------------------------------------- */
usmstats_scalars_get_value(const struct snmp_scalar_array_node_def * node,void * value)331 static s16_t usmstats_scalars_get_value(const struct snmp_scalar_array_node_def *node, void *value)
332 {
333 u32_t *uint_ptr = (u32_t *)value;
334 switch (node->oid) {
335 case 1: /* usmStatsUnsupportedSecLevels */
336 *uint_ptr = snmp_stats.unsupportedseclevels;
337 break;
338 case 2: /* usmStatsNotInTimeWindows */
339 *uint_ptr = snmp_stats.notintimewindows;
340 break;
341 case 3: /* usmStatsUnknownUserNames */
342 *uint_ptr = snmp_stats.unknownusernames;
343 break;
344 case 4: /* usmStatsUnknownEngineIDs */
345 *uint_ptr = snmp_stats.unknownengineids;
346 break;
347 case 5: /* usmStatsWrongDigests */
348 *uint_ptr = snmp_stats.wrongdigests;
349 break;
350 case 6: /* usmStatsDecryptionErrors */
351 *uint_ptr = snmp_stats.decryptionerrors;
352 break;
353 default:
354 LWIP_DEBUGF(SNMP_MIB_DEBUG, ("usmstats_scalars_get_value(): unknown id: %"S32_F"\n", node->oid));
355 return 0;
356 }
357
358 return sizeof(*uint_ptr);
359 }
360
361 /* --- snmpUsmMIB ----------------------------------------------------- */
362
363 /* --- usmUser 1.3.6.1.6.3.15.1.2 ----------------------------------------------------- */
364
365 static const struct snmp_table_col_def usmusertable_columns[] = {
366 {3, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserSecurityName */
367 {4, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserCloneFrom */
368 {5, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserAuthProtocol */
369 {6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserAuthKeyChange */
370 {7, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserOwnAuthKeyChange */
371 {8, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserPrivProtocol */
372 {9, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserPrivKeyChange */
373 {10, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserOwnPrivKeyChange */
374 {11, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserPublic */
375 {12, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserStorageType */
376 {13, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmUserStatus */
377 };
378 static const struct snmp_table_node usmusertable = SNMP_TABLE_CREATE(2, usmusertable_columns, usmusertable_get_instance, usmusertable_get_next_instance, usmusertable_get_value, NULL, NULL);
379
380 static const struct snmp_node *const usmuser_subnodes[] = {
381 &usmusertable.node.node
382 };
383 static const struct snmp_tree_node usmuser_treenode = SNMP_CREATE_TREE_NODE(2, usmuser_subnodes);
384
385 /* --- usmMIBObjects 1.3.6.1.6.3.15.1 ----------------------------------------------------- */
386 static const struct snmp_scalar_array_node_def usmstats_scalars_nodes[] = {
387 {1, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsUnsupportedSecLevels */
388 {2, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsNotInTimeWindows */
389 {3, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsUnknownUserNames */
390 {4, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsUnknownEngineIDs */
391 {5, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsWrongDigests */
392 {6, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* usmStatsDecryptionErrors */
393 };
394 static const struct snmp_scalar_array_node usmstats_scalars = SNMP_SCALAR_CREATE_ARRAY_NODE(1, usmstats_scalars_nodes, usmstats_scalars_get_value, NULL, NULL);
395
396 static const struct snmp_node *const usmmibobjects_subnodes[] = {
397 &usmstats_scalars.node.node,
398 &usmuser_treenode.node
399 };
400 static const struct snmp_tree_node usmmibobjects_treenode = SNMP_CREATE_TREE_NODE(1, usmmibobjects_subnodes);
401
402 /* --- snmpUsmMIB ----------------------------------------------------- */
403 static const struct snmp_node *const snmpusmmib_subnodes[] = {
404 &usmmibobjects_treenode.node
405 };
406 static const struct snmp_tree_node snmpusmmib_root = SNMP_CREATE_TREE_NODE(15, snmpusmmib_subnodes);
407 static const u32_t snmpusmmib_base_oid[] = {1, 3, 6, 1, 6, 3, 15};
408 const struct snmp_mib snmpusmmib = {snmpusmmib_base_oid, LWIP_ARRAYSIZE(snmpusmmib_base_oid), &snmpusmmib_root.node};
409
410 #endif /* LWIP_SNMP */
411