1/*
2Generated 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
22static 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
33static 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
42static 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
51static 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
60static 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
71static 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
82char username[32];
83
84static 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 */
170static 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
279static 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 ----------------------------------------------------- */
331static 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
365static 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};
378static 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
380static const struct snmp_node *const usmuser_subnodes[] = {
381  &usmusertable.node.node
382};
383static 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 ----------------------------------------------------- */
386static 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};
394static const struct snmp_scalar_array_node usmstats_scalars = SNMP_SCALAR_CREATE_ARRAY_NODE(1, usmstats_scalars_nodes, usmstats_scalars_get_value, NULL, NULL);
395
396static const struct snmp_node *const usmmibobjects_subnodes[] = {
397  &usmstats_scalars.node.node,
398  &usmuser_treenode.node
399};
400static const struct snmp_tree_node usmmibobjects_treenode = SNMP_CREATE_TREE_NODE(1, usmmibobjects_subnodes);
401
402/* --- snmpUsmMIB  ----------------------------------------------------- */
403static const struct snmp_node *const snmpusmmib_subnodes[] = {
404  &usmmibobjects_treenode.node
405};
406static const struct snmp_tree_node snmpusmmib_root = SNMP_CREATE_TREE_NODE(15, snmpusmmib_subnodes);
407static const u32_t snmpusmmib_base_oid[] = {1, 3, 6, 1, 6, 3, 15};
408const struct snmp_mib snmpusmmib = {snmpusmmib_base_oid, LWIP_ARRAYSIZE(snmpusmmib_base_oid), &snmpusmmib_root.node};
409
410#endif /* LWIP_SNMP */
411