1 /* $OpenBSD: application_internal.c,v 1.7 2023/11/08 19:46:28 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 21 #include <event.h> 22 #include <stdlib.h> 23 #include <unistd.h> 24 25 #include "application.h" 26 #include "log.h" 27 #include "mib.h" 28 #include "smi.h" 29 #include "snmpd.h" 30 31 struct appl_internal_object { 32 struct ber_oid oid; 33 struct ber_element * (*get)(struct ber_oid *); 34 /* No getnext means the object is scalar */ 35 struct ber_element * (*getnext)(int8_t, struct ber_oid *); 36 37 RB_ENTRY(appl_internal_object) entry; 38 }; 39 40 void appl_internal_region(struct ber_oid *); 41 void appl_internal_object(struct ber_oid *, 42 struct ber_element *(*)(struct ber_oid *), 43 struct ber_element *(*)(int8_t, struct ber_oid *)); 44 void appl_internal_get(struct appl_backend *, int32_t, int32_t, const char *, 45 struct appl_varbind *); 46 void appl_internal_getnext(struct appl_backend *, int32_t, int32_t, 47 const char *, struct appl_varbind *); 48 struct ber_element *appl_internal_snmp(struct ber_oid *); 49 struct ber_element *appl_internal_engine(struct ber_oid *); 50 struct ber_element *appl_internal_usmstats(struct ber_oid *); 51 struct ber_element *appl_internal_system(struct ber_oid *); 52 struct appl_internal_object *appl_internal_object_parent(struct ber_oid *); 53 int appl_internal_object_cmp(struct appl_internal_object *, 54 struct appl_internal_object *); 55 56 struct appl_backend_functions appl_internal_functions = { 57 .ab_get = appl_internal_get, 58 .ab_getnext = appl_internal_getnext, 59 .ab_getbulk = NULL, /* getbulk is too complex */ 60 }; 61 62 struct appl_backend appl_internal = { 63 .ab_name = "internal", 64 .ab_cookie = NULL, 65 .ab_retries = 0, 66 .ab_range = 1, 67 .ab_fn = &appl_internal_functions 68 }; 69 70 static RB_HEAD(appl_internal_objects, appl_internal_object) 71 appl_internal_objects = RB_INITIALIZER(&appl_internal_objects); 72 RB_PROTOTYPE_STATIC(appl_internal_objects, appl_internal_object, entry, 73 appl_internal_object_cmp); 74 75 void 76 appl_internal_init(void) 77 { 78 appl_internal_region(&OID(MIB_system)); 79 appl_internal_object(&OID(MIB_sysDescr), appl_internal_system, NULL); 80 appl_internal_object(&OID(MIB_sysOID), appl_internal_system, NULL); 81 appl_internal_object(&OID(MIB_sysUpTime), appl_internal_system, NULL); 82 appl_internal_object(&OID(MIB_sysContact), appl_internal_system, NULL); 83 appl_internal_object(&OID(MIB_sysName), appl_internal_system, NULL); 84 appl_internal_object(&OID(MIB_sysLocation), appl_internal_system, NULL); 85 appl_internal_object(&OID(MIB_sysServices), appl_internal_system, NULL); 86 appl_internal_object(&OID(MIB_sysORLastChange), appl_sysorlastchange, 87 NULL); 88 89 appl_internal_object(&OID(MIB_sysORID), appl_sysortable, 90 appl_sysortable_getnext); 91 appl_internal_object(&OID(MIB_sysORDescr), appl_sysortable, 92 appl_sysortable_getnext); 93 appl_internal_object(&OID(MIB_sysORUpTime), appl_sysortable, 94 appl_sysortable_getnext); 95 96 appl_internal_region(&OID(MIB_snmp)); 97 appl_internal_object(&OID(MIB_snmpInPkts), appl_internal_snmp, NULL); 98 appl_internal_object(&OID(MIB_snmpOutPkts), appl_internal_snmp, NULL); 99 appl_internal_object(&OID(MIB_snmpInBadVersions), appl_internal_snmp, 100 NULL); 101 appl_internal_object(&OID(MIB_snmpInBadCommunityNames), 102 appl_internal_snmp, NULL); 103 appl_internal_object(&OID(MIB_snmpInBadCommunityUses), 104 appl_internal_snmp, NULL); 105 appl_internal_object(&OID(MIB_snmpInASNParseErrs), appl_internal_snmp, 106 NULL); 107 appl_internal_object(&OID(MIB_snmpInTooBigs), appl_internal_snmp, NULL); 108 appl_internal_object(&OID(MIB_snmpInNoSuchNames), appl_internal_snmp, 109 NULL); 110 appl_internal_object(&OID(MIB_snmpInBadValues), appl_internal_snmp, 111 NULL); 112 appl_internal_object(&OID(MIB_snmpInReadOnlys), appl_internal_snmp, 113 NULL); 114 appl_internal_object(&OID(MIB_snmpInReadOnlys), appl_internal_snmp, 115 NULL); 116 appl_internal_object(&OID(MIB_snmpInGenErrs), appl_internal_snmp, NULL); 117 appl_internal_object(&OID(MIB_snmpInTotalReqVars), appl_internal_snmp, 118 NULL); 119 appl_internal_object(&OID(MIB_snmpInTotalSetVars), appl_internal_snmp, 120 NULL); 121 appl_internal_object(&OID(MIB_snmpInGetRequests), appl_internal_snmp, 122 NULL); 123 appl_internal_object(&OID(MIB_snmpInGetNexts), appl_internal_snmp, 124 NULL); 125 appl_internal_object(&OID(MIB_snmpInSetRequests), appl_internal_snmp, 126 NULL); 127 appl_internal_object(&OID(MIB_snmpInGetResponses), appl_internal_snmp, 128 NULL); 129 appl_internal_object(&OID(MIB_snmpInTraps), appl_internal_snmp, NULL); 130 appl_internal_object(&OID(MIB_snmpOutTooBigs), appl_internal_snmp, 131 NULL); 132 appl_internal_object(&OID(MIB_snmpOutNoSuchNames), appl_internal_snmp, 133 NULL); 134 appl_internal_object(&OID(MIB_snmpOutBadValues), appl_internal_snmp, 135 NULL); 136 appl_internal_object(&OID(MIB_snmpOutGenErrs), appl_internal_snmp, 137 NULL); 138 appl_internal_object(&OID(MIB_snmpOutGetRequests), appl_internal_snmp, 139 NULL); 140 appl_internal_object(&OID(MIB_snmpOutGetNexts), appl_internal_snmp, 141 NULL); 142 appl_internal_object(&OID(MIB_snmpOutSetRequests), appl_internal_snmp, 143 NULL); 144 appl_internal_object(&OID(MIB_snmpOutGetResponses), appl_internal_snmp, 145 NULL); 146 appl_internal_object(&OID(MIB_snmpOutTraps), appl_internal_snmp, NULL); 147 appl_internal_object(&OID(MIB_snmpEnableAuthenTraps), 148 appl_internal_snmp, NULL); 149 appl_internal_object(&OID(MIB_snmpSilentDrops), appl_internal_snmp, 150 NULL); 151 appl_internal_object(&OID(MIB_snmpProxyDrops), appl_internal_snmp, 152 NULL); 153 154 appl_internal_region(&OID(MIB_snmpV2)); 155 appl_internal_object(&OID(MIB_snmpEngineID), appl_internal_engine, 156 NULL); 157 appl_internal_object(&OID(MIB_snmpEngineBoots), appl_internal_engine, 158 NULL); 159 appl_internal_object(&OID(MIB_snmpEngineTime), appl_internal_engine, 160 NULL); 161 appl_internal_object(&OID(MIB_snmpEngineMaxMsgSize), 162 appl_internal_engine, NULL); 163 164 appl_internal_object(&OID(MIB_snmpUnavailableContexts), 165 appl_targetmib, NULL); 166 appl_internal_object(&OID(MIB_snmpUnknownContexts), 167 appl_targetmib, NULL); 168 169 appl_internal_object(&OID(MIB_usmStatsUnsupportedSecLevels), 170 appl_internal_usmstats, NULL); 171 appl_internal_object(&OID(MIB_usmStatsNotInTimeWindow), 172 appl_internal_usmstats, NULL); 173 appl_internal_object(&OID(MIB_usmStatsUnknownUserNames), 174 appl_internal_usmstats, NULL); 175 appl_internal_object(&OID(MIB_usmStatsUnknownEngineId), 176 appl_internal_usmstats, NULL); 177 appl_internal_object(&OID(MIB_usmStatsWrongDigests), 178 appl_internal_usmstats, NULL); 179 appl_internal_object(&OID(MIB_usmStatsDecryptionErrors), 180 appl_internal_usmstats, NULL); 181 } 182 183 void 184 appl_internal_shutdown(void) 185 { 186 struct appl_internal_object *object; 187 188 while ((object = RB_ROOT(&appl_internal_objects)) != NULL) { 189 RB_REMOVE(appl_internal_objects, &appl_internal_objects, 190 object); 191 free(object); 192 } 193 194 appl_close(&appl_internal); 195 } 196 197 void 198 appl_internal_region(struct ber_oid *oid) 199 { 200 enum appl_error error; 201 char oidbuf[1024]; 202 203 error = appl_register(NULL, 150, 1, oid, 0, 1, 0, 0, &appl_internal); 204 /* 205 * Ignore requestDenied, duplicateRegistration, and unsupportedContext 206 */ 207 if (error == APPL_ERROR_PROCESSINGERROR || 208 error == APPL_ERROR_PARSEERROR) { 209 smi_oid2string(oid, oidbuf, sizeof(oidbuf), 0); 210 fatalx("internal: Failed to register %s", oidbuf); 211 } 212 } 213 214 void 215 appl_internal_object(struct ber_oid *oid, 216 struct ber_element *(*get)(struct ber_oid *), 217 struct ber_element *(*getnext)(int8_t, struct ber_oid *)) 218 { 219 struct appl_internal_object *obj; 220 221 if ((obj = calloc(1, sizeof(*obj))) == NULL) 222 fatal(NULL); 223 obj->oid = *oid; 224 obj->get = get; 225 obj->getnext = getnext; 226 227 RB_INSERT(appl_internal_objects, &appl_internal_objects, obj); 228 } 229 230 void 231 appl_internal_get(struct appl_backend *backend, __unused int32_t transactionid, 232 int32_t requestid, __unused const char *ctx, struct appl_varbind *vblist) 233 { 234 struct ber_oid oid; 235 struct appl_internal_object *object; 236 struct appl_varbind *vb, *resp; 237 size_t i; 238 int r; 239 240 for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next, i++) 241 continue; 242 243 if ((resp = calloc(i, sizeof(*resp))) == NULL) { 244 log_warn("%s", backend->ab_name); 245 appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist); 246 return; 247 } 248 249 for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next, i++) { 250 resp[i].av_oid = vb->av_oid; 251 if ((object = appl_internal_object_parent(&vb->av_oid)) == NULL) 252 resp[i].av_value = 253 appl_exception(APPL_EXC_NOSUCHOBJECT); 254 else { 255 oid = object->oid; 256 /* Add 0 element for scalar */ 257 if (object->getnext == NULL) 258 oid.bo_id[oid.bo_n++] = 0; 259 r = ober_oid_cmp(&vb->av_oid, &oid); 260 if ((r == 0 && object->getnext == NULL) || 261 (r == 2 && object->getnext != NULL)) 262 resp[i].av_value = object->get(&resp[i].av_oid); 263 else 264 resp[i].av_value = 265 appl_exception(APPL_EXC_NOSUCHINSTANCE); 266 } 267 if (resp[i].av_value == NULL) { 268 log_warnx("%s: Failed to get value", backend->ab_name); 269 goto fail; 270 } 271 resp[i].av_next = &resp[i + 1]; 272 } 273 resp[i - 1].av_next = NULL; 274 275 appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, resp); 276 return; 277 278 fail: 279 for (vb = resp; vb != NULL; vb = vb->av_next) 280 ober_free_elements(vb->av_value); 281 free(resp); 282 appl_response(backend, requestid, APPL_ERROR_GENERR, i + 1, vblist); 283 } 284 285 void 286 appl_internal_getnext(struct appl_backend *backend, 287 __unused int32_t transactionid, int32_t requestid, __unused const char *ctx, 288 struct appl_varbind *vblist) 289 { 290 struct ber_oid oid; 291 struct appl_internal_object *object, search; 292 struct appl_varbind *vb, *resp; 293 size_t i; 294 int r; 295 int8_t include; 296 297 for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next, i++) 298 continue; 299 300 if ((resp = calloc(i, sizeof(*resp))) == NULL) { 301 log_warn("%s", backend->ab_name); 302 appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist); 303 return; 304 } 305 306 for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next, i++) { 307 resp[i].av_oid = vb->av_oid; 308 object = appl_internal_object_parent(&vb->av_oid); 309 if (object == NULL) { 310 search.oid = vb->av_oid; 311 object = RB_NFIND(appl_internal_objects, 312 &appl_internal_objects, &search); 313 } 314 315 include = vb->av_include; 316 for (; object != NULL; object = RB_NEXT(appl_internal_objects, 317 &appl_internal_objects, object), include = 1) { 318 if (object->getnext == NULL) { 319 oid = object->oid; 320 oid.bo_id[oid.bo_n++] = 0; 321 r = ober_oid_cmp(&resp[i].av_oid, &oid); 322 if (r > 0 || (r == 0 && !include)) 323 continue; 324 resp[i].av_oid = oid; 325 resp[i].av_value = object->get(&oid); 326 break; 327 } 328 /* non-scalar */ 329 if (ober_oid_cmp(&object->oid, &resp[i].av_oid) > 0) { 330 include = 1; 331 resp[i].av_oid = object->oid; 332 } 333 334 resp[i].av_value = 335 object->getnext(include, &resp[i].av_oid); 336 if (resp[i].av_value == NULL || 337 resp[i].av_value->be_class != BER_CLASS_CONTEXT) 338 break; 339 /* endOfMibView */ 340 ober_free_elements(resp[i].av_value); 341 resp[i].av_value = NULL; 342 } 343 if (ober_oid_cmp(&resp[i].av_oid, &vb->av_oid_end) >= 0 || 344 object == NULL) { 345 resp[i].av_oid = vb->av_oid; 346 ober_free_elements(resp[i].av_value); 347 resp[i].av_value = 348 appl_exception(APPL_EXC_ENDOFMIBVIEW); 349 } 350 if (resp[i].av_value == NULL) { 351 log_warnx("%s: Failed to get value", backend->ab_name); 352 goto fail; 353 } 354 resp[i].av_next = &resp[i + 1]; 355 } 356 resp[i - 1].av_next = NULL; 357 358 appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, resp); 359 return; 360 361 fail: 362 for (vb = resp; vb != NULL; vb = vb->av_next) 363 ober_free_elements(vb->av_value); 364 free(resp); 365 appl_response(backend, requestid, APPL_ERROR_GENERR, i + 1, vblist); 366 } 367 368 struct ber_element * 369 appl_internal_snmp(struct ber_oid *oid) 370 { 371 struct snmp_stats *stats = &snmpd_env->sc_stats; 372 struct ber_element *value = NULL; 373 374 if (ober_oid_cmp(oid, &OID(MIB_snmpEnableAuthenTraps, 0)) == 0) 375 return ober_add_integer(NULL, 376 stats->snmp_enableauthentraps ? 1 : 2); 377 if (ober_oid_cmp(&OID(MIB_snmpInPkts, 0), oid) == 0) 378 value = ober_add_integer(NULL, stats->snmp_inpkts); 379 else if (ober_oid_cmp(&OID(MIB_snmpOutPkts, 0), oid) == 0) 380 value = ober_add_integer(NULL, stats->snmp_outpkts); 381 else if (ober_oid_cmp(&OID(MIB_snmpInBadVersions, 0), oid) == 0) 382 value = ober_add_integer(NULL, stats->snmp_inbadversions); 383 else if (ober_oid_cmp(&OID(MIB_snmpInBadCommunityNames, 0), oid) == 0) 384 value = ober_add_integer(NULL, stats->snmp_inbadcommunitynames); 385 else if (ober_oid_cmp(&OID(MIB_snmpInBadCommunityUses, 0), oid) == 0) 386 value = ober_add_integer(NULL, stats->snmp_inbadcommunityuses); 387 else if (ober_oid_cmp(&OID(MIB_snmpInASNParseErrs, 0), oid) == 0) 388 value = ober_add_integer(NULL, stats->snmp_inasnparseerrs); 389 else if (ober_oid_cmp(&OID(MIB_snmpInTooBigs, 0), oid) == 0) 390 value = ober_add_integer(NULL, stats->snmp_intoobigs); 391 else if (ober_oid_cmp(&OID(MIB_snmpInNoSuchNames, 0), oid) == 0) 392 value = ober_add_integer(NULL, stats->snmp_innosuchnames); 393 else if (ober_oid_cmp(&OID(MIB_snmpInBadValues, 0), oid) == 0) 394 value = ober_add_integer(NULL, stats->snmp_inbadvalues); 395 else if (ober_oid_cmp(&OID(MIB_snmpInReadOnlys, 0), oid) == 0) 396 value = ober_add_integer(NULL, stats->snmp_inreadonlys); 397 else if (ober_oid_cmp(&OID(MIB_snmpInGenErrs, 0), oid) == 0) 398 value = ober_add_integer(NULL, stats->snmp_ingenerrs); 399 else if (ober_oid_cmp(&OID(MIB_snmpInTotalReqVars, 0), oid) == 0) 400 value = ober_add_integer(NULL, stats->snmp_intotalreqvars); 401 else if (ober_oid_cmp(&OID(MIB_snmpInTotalSetVars, 0), oid) == 0) 402 value = ober_add_integer(NULL, stats->snmp_intotalsetvars); 403 else if (ober_oid_cmp(&OID(MIB_snmpInGetRequests, 0), oid) == 0) 404 value = ober_add_integer(NULL, stats->snmp_ingetrequests); 405 else if (ober_oid_cmp(&OID(MIB_snmpInGetNexts, 0), oid) == 0) 406 value = ober_add_integer(NULL, stats->snmp_ingetnexts); 407 else if (ober_oid_cmp(&OID(MIB_snmpInSetRequests, 0), oid) == 0) 408 value = ober_add_integer(NULL, stats->snmp_insetrequests); 409 else if (ober_oid_cmp(&OID(MIB_snmpInGetResponses, 0), oid) == 0) 410 value = ober_add_integer(NULL, stats->snmp_ingetresponses); 411 else if (ober_oid_cmp(&OID(MIB_snmpInTraps, 0), oid) == 0) 412 value = ober_add_integer(NULL, stats->snmp_intraps); 413 else if (ober_oid_cmp(&OID(MIB_snmpOutTooBigs, 0), oid) == 0) 414 value = ober_add_integer(NULL, stats->snmp_outtoobigs); 415 else if (ober_oid_cmp(&OID(MIB_snmpOutNoSuchNames, 0), oid) == 0) 416 value = ober_add_integer(NULL, stats->snmp_outnosuchnames); 417 else if (ober_oid_cmp(&OID(MIB_snmpOutBadValues, 0), oid) == 0) 418 value = ober_add_integer(NULL, stats->snmp_outbadvalues); 419 else if (ober_oid_cmp(&OID(MIB_snmpOutGenErrs, 0), oid) == 0) 420 value = ober_add_integer(NULL, stats->snmp_outgenerrs); 421 else if (ober_oid_cmp(&OID(MIB_snmpOutGetRequests, 0), oid) == 0) 422 value = ober_add_integer(NULL, stats->snmp_outgetrequests); 423 else if (ober_oid_cmp(&OID(MIB_snmpOutGetNexts, 0), oid) == 0) 424 value = ober_add_integer(NULL, stats->snmp_outgetnexts); 425 else if (ober_oid_cmp(&OID(MIB_snmpOutSetRequests, 0), oid) == 0) 426 value = ober_add_integer(NULL, stats->snmp_outsetrequests); 427 else if (ober_oid_cmp(&OID(MIB_snmpOutGetResponses, 0), oid) == 0) 428 value = ober_add_integer(NULL, stats->snmp_outgetresponses); 429 else if (ober_oid_cmp(&OID(MIB_snmpOutTraps, 0), oid) == 0) 430 value = ober_add_integer(NULL, stats->snmp_outtraps); 431 else if (ober_oid_cmp(&OID(MIB_snmpSilentDrops, 0), oid) == 0) 432 value = ober_add_integer(NULL, stats->snmp_silentdrops); 433 else if (ober_oid_cmp(&OID(MIB_snmpProxyDrops, 0), oid) == 0) 434 value = ober_add_integer(NULL, stats->snmp_proxydrops); 435 436 if (value != NULL) 437 ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_COUNTER32); 438 return value; 439 } 440 441 struct ber_element * 442 appl_internal_engine(struct ber_oid *oid) 443 { 444 if (ober_oid_cmp(&OID(MIB_snmpEngineID, 0), oid) == 0) 445 return ober_add_nstring(NULL, snmpd_env->sc_engineid, 446 snmpd_env->sc_engineid_len); 447 else if (ober_oid_cmp(&OID(MIB_snmpEngineBoots, 0), oid) == 0) 448 return ober_add_integer(NULL, snmpd_env->sc_engine_boots); 449 else if (ober_oid_cmp(&OID(MIB_snmpEngineTime, 0), oid) == 0) 450 return ober_add_integer(NULL, snmpd_engine_time()); 451 else if (ober_oid_cmp(&OID(MIB_snmpEngineMaxMsgSize, 0), oid) == 0) 452 return ober_add_integer(NULL, READ_BUF_SIZE); 453 return NULL; 454 } 455 456 struct ber_element * 457 appl_internal_usmstats(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(MIB_usmStatsUnsupportedSecLevels, 0), oid) == 0) 463 value = ober_add_integer(NULL, stats->snmp_usmbadseclevel); 464 else if (ober_oid_cmp(&OID(MIB_usmStatsNotInTimeWindow, 0), oid) == 0) 465 value = ober_add_integer(NULL, stats->snmp_usmtimewindow); 466 else if (ober_oid_cmp(&OID(MIB_usmStatsUnknownUserNames, 0), oid) == 0) 467 value = ober_add_integer(NULL, stats->snmp_usmnosuchuser); 468 else if (ober_oid_cmp(&OID(MIB_usmStatsUnknownEngineId, 0), oid) == 0) 469 value = ober_add_integer(NULL, stats->snmp_usmnosuchengine); 470 else if (ober_oid_cmp(&OID(MIB_usmStatsWrongDigests, 0), oid) == 0) 471 value = ober_add_integer(NULL, stats->snmp_usmwrongdigest); 472 else if (ober_oid_cmp(&OID(MIB_usmStatsDecryptionErrors, 0), oid) == 0) 473 value = ober_add_integer(NULL, stats->snmp_usmdecrypterr); 474 475 if (value != NULL) 476 ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_COUNTER32); 477 478 return value; 479 } 480 481 struct ber_element * 482 appl_internal_system(struct ber_oid *oid) 483 { 484 struct snmp_system *s = &snmpd_env->sc_system; 485 struct ber_element *value = NULL; 486 487 if (ober_oid_cmp(&OID(MIB_sysDescr, 0), oid) == 0) 488 return ober_add_string(NULL, s->sys_descr); 489 else if (ober_oid_cmp(&OID(MIB_sysOID, 0), oid) == 0) 490 return ober_add_oid(NULL, &s->sys_oid); 491 else if (ober_oid_cmp(&OID(MIB_sysUpTime, 0), oid) == 0) { 492 value = ober_add_integer(NULL, smi_getticks()); 493 ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS); 494 } else if (ober_oid_cmp(&OID(MIB_sysContact, 0), oid) == 0) 495 return ober_add_string(NULL, s->sys_contact); 496 else if (ober_oid_cmp(&OID(MIB_sysName, 0), oid) == 0) 497 return ober_add_string(NULL, s->sys_name); 498 else if (ober_oid_cmp(&OID(MIB_sysLocation, 0), oid) == 0) 499 return ober_add_string(NULL, s->sys_location); 500 else if (ober_oid_cmp(&OID(MIB_sysServices, 0), oid) == 0) 501 return ober_add_integer(NULL, s->sys_services); 502 return value; 503 } 504 505 struct appl_internal_object * 506 appl_internal_object_parent(struct ber_oid *oid) 507 { 508 struct appl_internal_object *object, search; 509 510 search.oid = *oid; 511 do { 512 if ((object = RB_FIND(appl_internal_objects, 513 &appl_internal_objects, &search)) != NULL) 514 return object; 515 } while (--search.oid.bo_n > 0); 516 517 return NULL; 518 } 519 520 int 521 appl_internal_object_cmp(struct appl_internal_object *o1, 522 struct appl_internal_object *o2) 523 { 524 return ober_oid_cmp(&o1->oid, &o2->oid); 525 } 526 527 RB_GENERATE_STATIC(appl_internal_objects, appl_internal_object, entry, 528 appl_internal_object_cmp); 529