1 /* $OpenBSD: application_internal.c,v 1.12 2024/02/06 12:44:27 martijn Exp $ */ 2 3 /* 4 * Copyright (c) 2023 Martijn van Duren <martijn@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/tree.h> 20 #include <sys/types.h> 21 22 #include <stddef.h> 23 24 #include <ber.h> 25 #include <errno.h> 26 #include <stdint.h> 27 #include <stdlib.h> 28 #include <string.h> 29 30 #include "application.h" 31 #include "log.h" 32 #include "mib.h" 33 #include "smi.h" 34 #include "snmp.h" 35 #include "snmpd.h" 36 37 struct appl_internal_object { 38 struct ber_oid oid; 39 struct ber_element * (*get)(struct ber_oid *); 40 /* No getnext means the object is scalar */ 41 struct ber_element * (*getnext)(int8_t, struct ber_oid *); 42 43 int32_t intval; 44 char *stringval; 45 46 RB_ENTRY(appl_internal_object) entry; 47 }; 48 49 void appl_internal_region(struct ber_oid *); 50 void appl_internal_object(struct ber_oid *, 51 struct ber_element *(*)(struct ber_oid *), 52 struct ber_element *(*)(int8_t, struct ber_oid *)); 53 void appl_internal_get(struct appl_backend *, int32_t, int32_t, const char *, 54 struct appl_varbind *); 55 void appl_internal_getnext(struct appl_backend *, int32_t, int32_t, 56 const char *, struct appl_varbind *); 57 struct ber_element *appl_internal_snmp(struct ber_oid *); 58 struct ber_element *appl_internal_engine(struct ber_oid *); 59 struct ber_element *appl_internal_usmstats(struct ber_oid *); 60 struct ber_element *appl_internal_system(struct ber_oid *); 61 struct ber_element *appl_internal_get_int(struct ber_oid *); 62 struct ber_element *appl_internal_get_string(struct ber_oid *); 63 struct appl_internal_object *appl_internal_object_parent(struct ber_oid *); 64 int appl_internal_object_cmp(struct appl_internal_object *, 65 struct appl_internal_object *); 66 67 struct appl_backend_functions appl_internal_functions = { 68 .ab_get = appl_internal_get, 69 .ab_getnext = appl_internal_getnext, 70 .ab_getbulk = NULL, /* getbulk is too complex */ 71 }; 72 73 struct appl_backend appl_internal = { 74 .ab_name = "internal", 75 .ab_cookie = NULL, 76 .ab_retries = 0, 77 .ab_range = 1, 78 .ab_fn = &appl_internal_functions 79 }; 80 81 struct appl_backend appl_config = { 82 .ab_name = "config", 83 .ab_cookie = NULL, 84 .ab_retries = 0, 85 .ab_range = 1, 86 .ab_fn = &appl_internal_functions 87 }; 88 89 static RB_HEAD(appl_internal_objects, appl_internal_object) 90 appl_internal_objects = RB_INITIALIZER(&appl_internal_objects), 91 appl_internal_objects_conf = RB_INITIALIZER(&appl_internal_objects_conf); 92 RB_PROTOTYPE_STATIC(appl_internal_objects, appl_internal_object, entry, 93 appl_internal_object_cmp); 94 95 void 96 appl_internal_init(void) 97 { 98 struct appl_internal_object *obj; 99 struct ber_oid oid; 100 101 appl_internal_region(&OID(MIB_system)); 102 appl_internal_object(&OID(MIB_sysDescr), appl_internal_system, NULL); 103 appl_internal_object(&OID(MIB_sysOID), appl_internal_system, NULL); 104 appl_internal_object(&OID(MIB_sysUpTime), appl_internal_system, NULL); 105 appl_internal_object(&OID(MIB_sysContact), appl_internal_system, NULL); 106 appl_internal_object(&OID(MIB_sysName), appl_internal_system, NULL); 107 appl_internal_object(&OID(MIB_sysLocation), appl_internal_system, NULL); 108 appl_internal_object(&OID(MIB_sysServices), appl_internal_system, NULL); 109 appl_internal_object(&OID(MIB_sysORLastChange), appl_sysorlastchange, 110 NULL); 111 112 appl_internal_object(&OID(MIB_sysORID), appl_sysortable, 113 appl_sysortable_getnext); 114 appl_internal_object(&OID(MIB_sysORDescr), appl_sysortable, 115 appl_sysortable_getnext); 116 appl_internal_object(&OID(MIB_sysORUpTime), appl_sysortable, 117 appl_sysortable_getnext); 118 119 appl_internal_region(&OID(MIB_snmp)); 120 appl_internal_object(&OID(MIB_snmpInPkts), appl_internal_snmp, NULL); 121 appl_internal_object(&OID(MIB_snmpOutPkts), appl_internal_snmp, NULL); 122 appl_internal_object(&OID(MIB_snmpInBadVersions), appl_internal_snmp, 123 NULL); 124 appl_internal_object(&OID(MIB_snmpInBadCommunityNames), 125 appl_internal_snmp, NULL); 126 appl_internal_object(&OID(MIB_snmpInBadCommunityUses), 127 appl_internal_snmp, NULL); 128 appl_internal_object(&OID(MIB_snmpInASNParseErrs), appl_internal_snmp, 129 NULL); 130 appl_internal_object(&OID(MIB_snmpInTooBigs), appl_internal_snmp, NULL); 131 appl_internal_object(&OID(MIB_snmpInNoSuchNames), appl_internal_snmp, 132 NULL); 133 appl_internal_object(&OID(MIB_snmpInBadValues), appl_internal_snmp, 134 NULL); 135 appl_internal_object(&OID(MIB_snmpInReadOnlys), appl_internal_snmp, 136 NULL); 137 appl_internal_object(&OID(MIB_snmpInGenErrs), appl_internal_snmp, NULL); 138 appl_internal_object(&OID(MIB_snmpInTotalReqVars), appl_internal_snmp, 139 NULL); 140 appl_internal_object(&OID(MIB_snmpInTotalSetVars), appl_internal_snmp, 141 NULL); 142 appl_internal_object(&OID(MIB_snmpInGetRequests), appl_internal_snmp, 143 NULL); 144 appl_internal_object(&OID(MIB_snmpInGetNexts), appl_internal_snmp, 145 NULL); 146 appl_internal_object(&OID(MIB_snmpInSetRequests), appl_internal_snmp, 147 NULL); 148 appl_internal_object(&OID(MIB_snmpInGetResponses), appl_internal_snmp, 149 NULL); 150 appl_internal_object(&OID(MIB_snmpInTraps), appl_internal_snmp, NULL); 151 appl_internal_object(&OID(MIB_snmpOutTooBigs), appl_internal_snmp, 152 NULL); 153 appl_internal_object(&OID(MIB_snmpOutNoSuchNames), appl_internal_snmp, 154 NULL); 155 appl_internal_object(&OID(MIB_snmpOutBadValues), appl_internal_snmp, 156 NULL); 157 appl_internal_object(&OID(MIB_snmpOutGenErrs), appl_internal_snmp, 158 NULL); 159 appl_internal_object(&OID(MIB_snmpOutGetRequests), appl_internal_snmp, 160 NULL); 161 appl_internal_object(&OID(MIB_snmpOutGetNexts), appl_internal_snmp, 162 NULL); 163 appl_internal_object(&OID(MIB_snmpOutSetRequests), appl_internal_snmp, 164 NULL); 165 appl_internal_object(&OID(MIB_snmpOutGetResponses), appl_internal_snmp, 166 NULL); 167 appl_internal_object(&OID(MIB_snmpOutTraps), appl_internal_snmp, NULL); 168 appl_internal_object(&OID(MIB_snmpEnableAuthenTraps), 169 appl_internal_snmp, NULL); 170 appl_internal_object(&OID(MIB_snmpSilentDrops), appl_internal_snmp, 171 NULL); 172 appl_internal_object(&OID(MIB_snmpProxyDrops), appl_internal_snmp, 173 NULL); 174 175 appl_internal_region(&OID(MIB_snmpV2)); 176 appl_internal_object(&OID(MIB_snmpEngineID), appl_internal_engine, 177 NULL); 178 appl_internal_object(&OID(MIB_snmpEngineBoots), appl_internal_engine, 179 NULL); 180 appl_internal_object(&OID(MIB_snmpEngineTime), appl_internal_engine, 181 NULL); 182 appl_internal_object(&OID(MIB_snmpEngineMaxMsgSize), 183 appl_internal_engine, NULL); 184 185 appl_internal_object(&OID(MIB_snmpUnavailableContexts), 186 appl_targetmib, NULL); 187 appl_internal_object(&OID(MIB_snmpUnknownContexts), 188 appl_targetmib, NULL); 189 190 appl_internal_object(&OID(MIB_usmStatsUnsupportedSecLevels), 191 appl_internal_usmstats, NULL); 192 appl_internal_object(&OID(MIB_usmStatsNotInTimeWindow), 193 appl_internal_usmstats, NULL); 194 appl_internal_object(&OID(MIB_usmStatsUnknownUserNames), 195 appl_internal_usmstats, NULL); 196 appl_internal_object(&OID(MIB_usmStatsUnknownEngineId), 197 appl_internal_usmstats, NULL); 198 appl_internal_object(&OID(MIB_usmStatsWrongDigests), 199 appl_internal_usmstats, NULL); 200 appl_internal_object(&OID(MIB_usmStatsDecryptionErrors), 201 appl_internal_usmstats, NULL); 202 203 while ((obj = RB_MIN(appl_internal_objects, 204 &appl_internal_objects_conf)) != NULL) { 205 RB_REMOVE(appl_internal_objects, 206 &appl_internal_objects_conf, obj); 207 oid = obj->oid; 208 oid.bo_id[oid.bo_n++] = 0; 209 if (appl_register(NULL, 150, 1, &oid, 210 1, 1, 0, 0, &appl_config) != APPL_ERROR_NOERROR) { 211 free(obj->stringval); 212 free(obj); 213 } else 214 RB_INSERT(appl_internal_objects, &appl_internal_objects, 215 obj); 216 } 217 } 218 219 void 220 appl_internal_shutdown(void) 221 { 222 struct appl_internal_object *object; 223 224 while ((object = RB_ROOT(&appl_internal_objects)) != NULL) { 225 RB_REMOVE(appl_internal_objects, &appl_internal_objects, 226 object); 227 free(object->stringval); 228 free(object); 229 } 230 231 appl_close(&appl_internal); 232 appl_close(&appl_config); 233 } 234 235 void 236 appl_internal_region(struct ber_oid *oid) 237 { 238 enum appl_error error; 239 char oidbuf[1024]; 240 241 error = appl_register(NULL, 150, 1, oid, 0, 1, 0, 0, &appl_internal); 242 /* 243 * Ignore requestDenied, duplicateRegistration, and unsupportedContext 244 */ 245 if (error == APPL_ERROR_PROCESSINGERROR || 246 error == APPL_ERROR_PARSEERROR) 247 fatalx("internal: Failed to register %s", mib_oid2string(oid, 248 oidbuf, sizeof(oidbuf), snmpd_env->sc_oidfmt)); 249 } 250 251 void 252 appl_internal_object(struct ber_oid *oid, 253 struct ber_element *(*get)(struct ber_oid *), 254 struct ber_element *(*getnext)(int8_t, struct ber_oid *)) 255 { 256 struct appl_internal_object *obj; 257 char buf[1024]; 258 259 if ((obj = calloc(1, sizeof(*obj))) == NULL) 260 fatal(NULL); 261 obj->oid = *oid; 262 obj->get = get; 263 obj->getnext = getnext; 264 obj->stringval = NULL; 265 266 if (RB_INSERT(appl_internal_objects, 267 &appl_internal_objects, obj) != NULL) 268 fatalx("%s: %s already registered", __func__, 269 mib_oid2string(oid, buf, sizeof(buf), 270 snmpd_env->sc_oidfmt)); 271 } 272 273 const char * 274 appl_internal_object_int(struct ber_oid *oid, int32_t val) 275 { 276 struct appl_internal_object *obj; 277 278 if ((obj = calloc(1, sizeof(*obj))) == NULL) 279 return strerror(errno); 280 obj->oid = *oid; 281 obj->get = appl_internal_get_int; 282 obj->getnext = NULL; 283 obj->intval = val; 284 obj->stringval = NULL; 285 286 if (RB_INSERT(appl_internal_objects, 287 &appl_internal_objects_conf, obj) != NULL) { 288 free(obj); 289 return "OID already defined"; 290 } 291 return NULL; 292 } 293 294 const char * 295 appl_internal_object_string(struct ber_oid *oid, char *val) 296 { 297 struct appl_internal_object *obj; 298 299 if ((obj = calloc(1, sizeof(*obj))) == NULL) 300 return strerror(errno); 301 obj->oid = *oid; 302 obj->get = appl_internal_get_string; 303 obj->getnext = NULL; 304 obj->stringval = val; 305 306 if (RB_INSERT(appl_internal_objects, 307 &appl_internal_objects_conf, obj) != NULL) { 308 free(obj); 309 return "OID already defined"; 310 } 311 return NULL; 312 } 313 314 void 315 appl_internal_get(struct appl_backend *backend, __unused int32_t transactionid, 316 int32_t requestid, __unused const char *ctx, struct appl_varbind *vblist) 317 { 318 struct ber_oid oid; 319 struct appl_internal_object *object; 320 struct appl_varbind *vb, *resp; 321 size_t i; 322 int r; 323 324 for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next, i++) 325 continue; 326 327 if ((resp = calloc(i, sizeof(*resp))) == NULL) { 328 log_warn("%s", backend->ab_name); 329 appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist); 330 return; 331 } 332 333 for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next, i++) { 334 resp[i].av_oid = vb->av_oid; 335 if ((object = appl_internal_object_parent(&vb->av_oid)) == NULL) 336 resp[i].av_value = 337 appl_exception(APPL_EXC_NOSUCHOBJECT); 338 else { 339 oid = object->oid; 340 /* Add 0 element for scalar */ 341 if (object->getnext == NULL) 342 oid.bo_id[oid.bo_n++] = 0; 343 r = ober_oid_cmp(&vb->av_oid, &oid); 344 if ((r == 0 && object->getnext == NULL) || 345 (r == 2 && object->getnext != NULL)) 346 resp[i].av_value = object->get(&resp[i].av_oid); 347 else 348 resp[i].av_value = 349 appl_exception(APPL_EXC_NOSUCHINSTANCE); 350 } 351 if (resp[i].av_value == NULL) { 352 log_warnx("%s: Failed to get value", backend->ab_name); 353 goto fail; 354 } 355 resp[i].av_next = &resp[i + 1]; 356 } 357 resp[i - 1].av_next = NULL; 358 359 appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, resp); 360 361 free(resp); 362 return; 363 364 fail: 365 for (vb = resp; vb != NULL; vb = vb->av_next) 366 ober_free_elements(vb->av_value); 367 free(resp); 368 appl_response(backend, requestid, APPL_ERROR_GENERR, i + 1, vblist); 369 } 370 371 void 372 appl_internal_getnext(struct appl_backend *backend, 373 __unused int32_t transactionid, int32_t requestid, __unused const char *ctx, 374 struct appl_varbind *vblist) 375 { 376 struct ber_oid oid; 377 struct appl_internal_object *object, search; 378 struct appl_varbind *vb, *resp; 379 size_t i; 380 int r; 381 int8_t include; 382 383 for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next, i++) 384 continue; 385 386 if ((resp = calloc(i, sizeof(*resp))) == NULL) { 387 log_warn("%s", backend->ab_name); 388 appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist); 389 return; 390 } 391 392 for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next, i++) { 393 resp[i].av_oid = vb->av_oid; 394 object = appl_internal_object_parent(&vb->av_oid); 395 if (object == NULL) { 396 search.oid = vb->av_oid; 397 object = RB_NFIND(appl_internal_objects, 398 &appl_internal_objects, &search); 399 } 400 401 include = vb->av_include; 402 for (; object != NULL; object = RB_NEXT(appl_internal_objects, 403 &appl_internal_objects, object), include = 1) { 404 if (object->getnext == NULL) { 405 oid = object->oid; 406 oid.bo_id[oid.bo_n++] = 0; 407 r = ober_oid_cmp(&resp[i].av_oid, &oid); 408 if (r > 0 || (r == 0 && !include)) 409 continue; 410 resp[i].av_oid = oid; 411 resp[i].av_value = object->get(&oid); 412 break; 413 } 414 /* non-scalar */ 415 if (ober_oid_cmp(&object->oid, &resp[i].av_oid) > 0) { 416 include = 1; 417 resp[i].av_oid = object->oid; 418 } 419 420 resp[i].av_value = 421 object->getnext(include, &resp[i].av_oid); 422 if (resp[i].av_value == NULL || 423 resp[i].av_value->be_class != BER_CLASS_CONTEXT) 424 break; 425 /* endOfMibView */ 426 ober_free_elements(resp[i].av_value); 427 resp[i].av_value = NULL; 428 } 429 if (ober_oid_cmp(&resp[i].av_oid, &vb->av_oid_end) >= 0 || 430 object == NULL) { 431 resp[i].av_oid = vb->av_oid; 432 ober_free_elements(resp[i].av_value); 433 resp[i].av_value = 434 appl_exception(APPL_EXC_ENDOFMIBVIEW); 435 } 436 if (resp[i].av_value == NULL) { 437 log_warnx("%s: Failed to get value", backend->ab_name); 438 goto fail; 439 } 440 resp[i].av_next = &resp[i + 1]; 441 } 442 resp[i - 1].av_next = NULL; 443 444 appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, resp); 445 446 free(resp); 447 return; 448 449 fail: 450 for (vb = resp; vb != NULL; vb = vb->av_next) 451 ober_free_elements(vb->av_value); 452 free(resp); 453 appl_response(backend, requestid, APPL_ERROR_GENERR, i + 1, vblist); 454 } 455 456 struct ber_element * 457 appl_internal_snmp(struct ber_oid *oid) 458 { 459 struct snmp_stats *stats = &snmpd_env->sc_stats; 460 struct ber_element *value = NULL; 461 462 if (ober_oid_cmp(oid, &OID(MIB_snmpEnableAuthenTraps, 0)) == 0) 463 return ober_add_integer(NULL, 464 stats->snmp_enableauthentraps ? 1 : 2); 465 if (ober_oid_cmp(&OID(MIB_snmpInPkts, 0), oid) == 0) 466 value = ober_add_integer(NULL, stats->snmp_inpkts); 467 else if (ober_oid_cmp(&OID(MIB_snmpOutPkts, 0), oid) == 0) 468 value = ober_add_integer(NULL, stats->snmp_outpkts); 469 else if (ober_oid_cmp(&OID(MIB_snmpInBadVersions, 0), oid) == 0) 470 value = ober_add_integer(NULL, stats->snmp_inbadversions); 471 else if (ober_oid_cmp(&OID(MIB_snmpInBadCommunityNames, 0), oid) == 0) 472 value = ober_add_integer(NULL, stats->snmp_inbadcommunitynames); 473 else if (ober_oid_cmp(&OID(MIB_snmpInBadCommunityUses, 0), oid) == 0) 474 value = ober_add_integer(NULL, stats->snmp_inbadcommunityuses); 475 else if (ober_oid_cmp(&OID(MIB_snmpInASNParseErrs, 0), oid) == 0) 476 value = ober_add_integer(NULL, stats->snmp_inasnparseerrs); 477 else if (ober_oid_cmp(&OID(MIB_snmpInTooBigs, 0), oid) == 0) 478 value = ober_add_integer(NULL, stats->snmp_intoobigs); 479 else if (ober_oid_cmp(&OID(MIB_snmpInNoSuchNames, 0), oid) == 0) 480 value = ober_add_integer(NULL, stats->snmp_innosuchnames); 481 else if (ober_oid_cmp(&OID(MIB_snmpInBadValues, 0), oid) == 0) 482 value = ober_add_integer(NULL, stats->snmp_inbadvalues); 483 else if (ober_oid_cmp(&OID(MIB_snmpInReadOnlys, 0), oid) == 0) 484 value = ober_add_integer(NULL, stats->snmp_inreadonlys); 485 else if (ober_oid_cmp(&OID(MIB_snmpInGenErrs, 0), oid) == 0) 486 value = ober_add_integer(NULL, stats->snmp_ingenerrs); 487 else if (ober_oid_cmp(&OID(MIB_snmpInTotalReqVars, 0), oid) == 0) 488 value = ober_add_integer(NULL, stats->snmp_intotalreqvars); 489 else if (ober_oid_cmp(&OID(MIB_snmpInTotalSetVars, 0), oid) == 0) 490 value = ober_add_integer(NULL, stats->snmp_intotalsetvars); 491 else if (ober_oid_cmp(&OID(MIB_snmpInGetRequests, 0), oid) == 0) 492 value = ober_add_integer(NULL, stats->snmp_ingetrequests); 493 else if (ober_oid_cmp(&OID(MIB_snmpInGetNexts, 0), oid) == 0) 494 value = ober_add_integer(NULL, stats->snmp_ingetnexts); 495 else if (ober_oid_cmp(&OID(MIB_snmpInSetRequests, 0), oid) == 0) 496 value = ober_add_integer(NULL, stats->snmp_insetrequests); 497 else if (ober_oid_cmp(&OID(MIB_snmpInGetResponses, 0), oid) == 0) 498 value = ober_add_integer(NULL, stats->snmp_ingetresponses); 499 else if (ober_oid_cmp(&OID(MIB_snmpInTraps, 0), oid) == 0) 500 value = ober_add_integer(NULL, stats->snmp_intraps); 501 else if (ober_oid_cmp(&OID(MIB_snmpOutTooBigs, 0), oid) == 0) 502 value = ober_add_integer(NULL, stats->snmp_outtoobigs); 503 else if (ober_oid_cmp(&OID(MIB_snmpOutNoSuchNames, 0), oid) == 0) 504 value = ober_add_integer(NULL, stats->snmp_outnosuchnames); 505 else if (ober_oid_cmp(&OID(MIB_snmpOutBadValues, 0), oid) == 0) 506 value = ober_add_integer(NULL, stats->snmp_outbadvalues); 507 else if (ober_oid_cmp(&OID(MIB_snmpOutGenErrs, 0), oid) == 0) 508 value = ober_add_integer(NULL, stats->snmp_outgenerrs); 509 else if (ober_oid_cmp(&OID(MIB_snmpOutGetRequests, 0), oid) == 0) 510 value = ober_add_integer(NULL, stats->snmp_outgetrequests); 511 else if (ober_oid_cmp(&OID(MIB_snmpOutGetNexts, 0), oid) == 0) 512 value = ober_add_integer(NULL, stats->snmp_outgetnexts); 513 else if (ober_oid_cmp(&OID(MIB_snmpOutSetRequests, 0), oid) == 0) 514 value = ober_add_integer(NULL, stats->snmp_outsetrequests); 515 else if (ober_oid_cmp(&OID(MIB_snmpOutGetResponses, 0), oid) == 0) 516 value = ober_add_integer(NULL, stats->snmp_outgetresponses); 517 else if (ober_oid_cmp(&OID(MIB_snmpOutTraps, 0), oid) == 0) 518 value = ober_add_integer(NULL, stats->snmp_outtraps); 519 else if (ober_oid_cmp(&OID(MIB_snmpSilentDrops, 0), oid) == 0) 520 value = ober_add_integer(NULL, stats->snmp_silentdrops); 521 else if (ober_oid_cmp(&OID(MIB_snmpProxyDrops, 0), oid) == 0) 522 value = ober_add_integer(NULL, stats->snmp_proxydrops); 523 524 if (value != NULL) 525 ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_COUNTER32); 526 return value; 527 } 528 529 struct ber_element * 530 appl_internal_engine(struct ber_oid *oid) 531 { 532 if (ober_oid_cmp(&OID(MIB_snmpEngineID, 0), oid) == 0) 533 return ober_add_nstring(NULL, snmpd_env->sc_engineid, 534 snmpd_env->sc_engineid_len); 535 else if (ober_oid_cmp(&OID(MIB_snmpEngineBoots, 0), oid) == 0) 536 return ober_add_integer(NULL, snmpd_env->sc_engine_boots); 537 else if (ober_oid_cmp(&OID(MIB_snmpEngineTime, 0), oid) == 0) 538 return ober_add_integer(NULL, snmpd_engine_time()); 539 else if (ober_oid_cmp(&OID(MIB_snmpEngineMaxMsgSize, 0), oid) == 0) 540 return ober_add_integer(NULL, READ_BUF_SIZE); 541 return NULL; 542 } 543 544 struct ber_element * 545 appl_internal_usmstats(struct ber_oid *oid) 546 { 547 struct snmp_stats *stats = &snmpd_env->sc_stats; 548 struct ber_element *value = NULL; 549 550 if (ober_oid_cmp(&OID(MIB_usmStatsUnsupportedSecLevels, 0), oid) == 0) 551 value = ober_add_integer(NULL, stats->snmp_usmbadseclevel); 552 else if (ober_oid_cmp(&OID(MIB_usmStatsNotInTimeWindow, 0), oid) == 0) 553 value = ober_add_integer(NULL, stats->snmp_usmtimewindow); 554 else if (ober_oid_cmp(&OID(MIB_usmStatsUnknownUserNames, 0), oid) == 0) 555 value = ober_add_integer(NULL, stats->snmp_usmnosuchuser); 556 else if (ober_oid_cmp(&OID(MIB_usmStatsUnknownEngineId, 0), oid) == 0) 557 value = ober_add_integer(NULL, stats->snmp_usmnosuchengine); 558 else if (ober_oid_cmp(&OID(MIB_usmStatsWrongDigests, 0), oid) == 0) 559 value = ober_add_integer(NULL, stats->snmp_usmwrongdigest); 560 else if (ober_oid_cmp(&OID(MIB_usmStatsDecryptionErrors, 0), oid) == 0) 561 value = ober_add_integer(NULL, stats->snmp_usmdecrypterr); 562 563 if (value != NULL) 564 ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_COUNTER32); 565 566 return value; 567 } 568 569 struct ber_element * 570 appl_internal_system(struct ber_oid *oid) 571 { 572 struct snmp_system *s = &snmpd_env->sc_system; 573 struct ber_element *value = NULL; 574 575 if (ober_oid_cmp(&OID(MIB_sysDescr, 0), oid) == 0) 576 return ober_add_string(NULL, s->sys_descr); 577 else if (ober_oid_cmp(&OID(MIB_sysOID, 0), oid) == 0) 578 return ober_add_oid(NULL, &s->sys_oid); 579 else if (ober_oid_cmp(&OID(MIB_sysUpTime, 0), oid) == 0) { 580 value = ober_add_integer(NULL, smi_getticks()); 581 ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS); 582 } else if (ober_oid_cmp(&OID(MIB_sysContact, 0), oid) == 0) 583 return ober_add_string(NULL, s->sys_contact); 584 else if (ober_oid_cmp(&OID(MIB_sysName, 0), oid) == 0) 585 return ober_add_string(NULL, s->sys_name); 586 else if (ober_oid_cmp(&OID(MIB_sysLocation, 0), oid) == 0) 587 return ober_add_string(NULL, s->sys_location); 588 else if (ober_oid_cmp(&OID(MIB_sysServices, 0), oid) == 0) 589 return ober_add_integer(NULL, s->sys_services); 590 return value; 591 } 592 593 struct ber_element * 594 appl_internal_get_int(struct ber_oid *oid) 595 { 596 struct appl_internal_object *obj; 597 598 obj = appl_internal_object_parent(oid); 599 return ober_add_integer(NULL, obj->intval); 600 } 601 602 struct ber_element * 603 appl_internal_get_string(struct ber_oid *oid) 604 { 605 struct appl_internal_object *obj; 606 607 obj = appl_internal_object_parent(oid); 608 return ober_add_string(NULL, obj->stringval); 609 } 610 611 struct appl_internal_object * 612 appl_internal_object_parent(struct ber_oid *oid) 613 { 614 struct appl_internal_object *object, search; 615 616 search.oid = *oid; 617 do { 618 if ((object = RB_FIND(appl_internal_objects, 619 &appl_internal_objects, &search)) != NULL) 620 return object; 621 } while (--search.oid.bo_n > 0); 622 623 return NULL; 624 } 625 626 int 627 appl_internal_object_cmp(struct appl_internal_object *o1, 628 struct appl_internal_object *o2) 629 { 630 return ober_oid_cmp(&o1->oid, &o2->oid); 631 } 632 633 RB_GENERATE_STATIC(appl_internal_objects, appl_internal_object, entry, 634 appl_internal_object_cmp); 635