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