1122394Sharti/* 2122394Sharti * Copyright (c) 2001-2003 3122394Sharti * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4122394Sharti * All rights reserved. 5163820Sharti * Copyright (c) 2004-2006 6163820Sharti * Hartmut Brandt. 7163820Sharti * All rights reserved. 8122394Sharti * 9122394Sharti * Author: Harti Brandt <harti@freebsd.org> 10133211Sharti * 11133211Sharti * Redistribution and use in source and binary forms, with or without 12133211Sharti * modification, are permitted provided that the following conditions 13133211Sharti * are met: 14133211Sharti * 1. Redistributions of source code must retain the above copyright 15133211Sharti * notice, this list of conditions and the following disclaimer. 16122394Sharti * 2. Redistributions in binary form must reproduce the above copyright 17122394Sharti * notice, this list of conditions and the following disclaimer in the 18122394Sharti * documentation and/or other materials provided with the distribution. 19133211Sharti * 20133211Sharti * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21133211Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22133211Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23133211Sharti * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 24133211Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25133211Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26133211Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27133211Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28133211Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29133211Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30133211Sharti * SUCH DAMAGE. 31122394Sharti * 32163820Sharti * $Begemot: action.c 517 2006-10-31 08:52:04Z brandt_h $ 33122394Sharti * 34122394Sharti * Variable access for SNMPd 35122394Sharti */ 36122394Sharti#include <sys/types.h> 37216294Ssyrinx#include <sys/queue.h> 38122394Sharti#include <sys/sysctl.h> 39122394Sharti#include <sys/un.h> 40163820Sharti#include <sys/utsname.h> 41122394Sharti#include <stdio.h> 42122394Sharti#include <stdlib.h> 43122394Sharti#include <stdarg.h> 44122394Sharti#include <string.h> 45122394Sharti#include <ctype.h> 46216294Ssyrinx#include <errno.h> 47122394Sharti#include <syslog.h> 48122394Sharti 49122394Sharti#include "snmpmod.h" 50122394Sharti#include "snmpd.h" 51122394Sharti#include "tree.h" 52122394Sharti#include "oid.h" 53122394Sharti 54122394Shartistatic const struct asn_oid 55122394Sharti oid_begemotSnmpdModuleTable = OIDX_begemotSnmpdModuleTable; 56122394Sharti 57163820Sharti#ifdef __FreeBSD__ 58163820Shartistatic const struct asn_oid 59163820Sharti oid_freeBSDVersion = OIDX_freeBSDVersion; 60163820Sharti#endif 61163820Sharti 62122394Sharti/* 63122394Sharti * Get an integer value from the KERN sysctl subtree. 64122394Sharti */ 65122394Shartistatic char * 66122394Shartiact_getkernint(int id) 67122394Sharti{ 68122394Sharti int mib[2]; 69122394Sharti size_t len; 70122394Sharti u_long value; 71122394Sharti char *string; 72122394Sharti 73122394Sharti mib[0] = CTL_KERN; 74122394Sharti mib[1] = id; 75122394Sharti len = sizeof(value); 76122394Sharti if (sysctl(mib, 2, &value, &len, NULL, 0) != 0) 77122394Sharti return (NULL); 78122394Sharti 79122394Sharti if ((string = malloc(20)) == NULL) 80122394Sharti return (NULL); 81122394Sharti sprintf(string, "%lu", value); 82122394Sharti return (string); 83122394Sharti} 84122394Sharti 85122394Sharti/* 86122394Sharti * Initialize global variables of the system group. 87122394Sharti */ 88122394Shartiint 89122394Shartiinit_actvals(void) 90122394Sharti{ 91163820Sharti struct utsname uts; 92163820Sharti char *hostid; 93122394Sharti size_t len; 94163820Sharti#ifdef __FreeBSD__ 95163820Sharti char *rel, *p, *end; 96163820Sharti u_long num; 97163820Sharti#endif 98122394Sharti 99163820Sharti if (uname(&uts) == -1) 100122394Sharti return (-1); 101122394Sharti 102163820Sharti if ((systemg.name = strdup(uts.nodename)) == NULL) 103163820Sharti return (-1); 104122394Sharti 105163820Sharti if ((hostid = act_getkernint(KERN_HOSTID)) == NULL) 106163820Sharti return (-1); 107122394Sharti 108163820Sharti len = strlen(uts.nodename) + 1; 109163820Sharti len += strlen(hostid) + 1; 110163820Sharti len += strlen(uts.sysname) + 1; 111163820Sharti len += strlen(uts.release) + 1; 112122394Sharti 113163820Sharti if ((systemg.descr = malloc(len)) == NULL) { 114163820Sharti free(hostid); 115163820Sharti return (-1); 116163820Sharti } 117163820Sharti sprintf(systemg.descr, "%s %s %s %s", uts.nodename, hostid, uts.sysname, 118163820Sharti uts.release); 119122394Sharti 120163820Sharti#ifdef __FreeBSD__ 121163820Sharti /* 122163820Sharti * Construct a FreeBSD oid 123163820Sharti */ 124163820Sharti systemg.object_id = oid_freeBSDVersion; 125163820Sharti rel = uts.release; 126163820Sharti while ((p = strsep(&rel, ".")) != NULL && 127163820Sharti systemg.object_id.len < ASN_MAXOIDLEN) { 128163820Sharti systemg.object_id.subs[systemg.object_id.len] = 0; 129163820Sharti if (*p != '\0') { 130163820Sharti num = strtoul(p, &end, 10); 131163820Sharti if (end == p) 132163820Sharti break; 133163820Sharti systemg.object_id.subs[systemg.object_id.len] = num; 134163820Sharti } 135163820Sharti systemg.object_id.len++; 136163820Sharti } 137163820Sharti#endif 138163820Sharti 139163820Sharti free(hostid); 140163820Sharti 141122394Sharti return (0); 142122394Sharti} 143122394Sharti 144216294Ssyrinx/* 145216294Ssyrinx * Initialize global variables of the snmpEngine group. 146216294Ssyrinx */ 147216294Ssyrinxint 148216294Ssyrinxinit_snmpd_engine(void) 149216294Ssyrinx{ 150216294Ssyrinx char *hostid; 151122394Sharti 152216294Ssyrinx snmpd_engine.engine_boots = 1; 153216294Ssyrinx snmpd_engine.engine_time = 1; 154216294Ssyrinx snmpd_engine.max_msg_size = 1500; /* XXX */ 155122394Sharti 156216294Ssyrinx snmpd_engine.engine_id[0] = ((OID_freeBSD & 0xff000000) >> 24) | 0x80; 157216294Ssyrinx snmpd_engine.engine_id[1] = (OID_freeBSD & 0xff0000) >> 16; 158216294Ssyrinx snmpd_engine.engine_id[2] = (OID_freeBSD & 0xff00) >> 8; 159216294Ssyrinx snmpd_engine.engine_id[3] = OID_freeBSD & 0xff; 160216294Ssyrinx snmpd_engine.engine_id[4] = 128; 161216294Ssyrinx snmpd_engine.engine_len = 5; 162216294Ssyrinx 163216294Ssyrinx if ((hostid = act_getkernint(KERN_HOSTID)) == NULL) 164216294Ssyrinx return (-1); 165216294Ssyrinx 166216294Ssyrinx if (strlen(hostid) > SNMP_ENGINE_ID_SIZ - snmpd_engine.engine_len) { 167216294Ssyrinx memcpy(snmpd_engine.engine_id + snmpd_engine.engine_len, 168216294Ssyrinx hostid, SNMP_ENGINE_ID_SIZ - snmpd_engine.engine_len); 169216294Ssyrinx snmpd_engine.engine_len = SNMP_ENGINE_ID_SIZ; 170216294Ssyrinx } else { 171216294Ssyrinx memcpy(snmpd_engine.engine_id + snmpd_engine.engine_len, 172216294Ssyrinx hostid, strlen(hostid)); 173216294Ssyrinx snmpd_engine.engine_len += strlen(hostid); 174216294Ssyrinx } 175216294Ssyrinx 176216294Ssyrinx free(hostid); 177216294Ssyrinx 178216294Ssyrinx return (0); 179216294Ssyrinx} 180216294Ssyrinx 181216294Ssyrinxint 182216294Ssyrinxset_snmpd_engine(void) 183216294Ssyrinx{ 184216294Ssyrinx FILE *fp; 185216294Ssyrinx uint32_t i; 186216294Ssyrinx uint8_t *cptr, engine[2 * SNMP_ENGINE_ID_SIZ + 2]; 187216294Ssyrinx uint8_t myengine[2 * SNMP_ENGINE_ID_SIZ + 2]; 188216294Ssyrinx 189216294Ssyrinx if (engine_file[0] == '\0') 190216294Ssyrinx return (-1); 191216294Ssyrinx 192216294Ssyrinx cptr = myengine; 193216294Ssyrinx for (i = 0; i < snmpd_engine.engine_len; i++) 194216294Ssyrinx cptr += sprintf(cptr, "%.2x", snmpd_engine.engine_id[i]); 195216294Ssyrinx *cptr++ = '\n'; 196216294Ssyrinx *cptr++ = '\0'; 197216294Ssyrinx 198216294Ssyrinx if ((fp = fopen(engine_file, "r+")) != NULL) { 199216294Ssyrinx if (fgets(engine, sizeof(engine) - 1, fp) == NULL || 200216294Ssyrinx fscanf(fp, "%u", &snmpd_engine.engine_boots) <= 0) { 201216294Ssyrinx fclose(fp); 202216294Ssyrinx goto save_boots; 203216294Ssyrinx } 204216294Ssyrinx 205216294Ssyrinx fclose(fp); 206216294Ssyrinx if (strcmp(myengine, engine) != 0) 207216294Ssyrinx snmpd_engine.engine_boots = 1; 208216294Ssyrinx else 209216294Ssyrinx snmpd_engine.engine_boots++; 210216294Ssyrinx } else if (errno != ENOENT) 211216294Ssyrinx return (-1); 212216294Ssyrinx 213216294Ssyrinxsave_boots: 214216294Ssyrinx if ((fp = fopen(engine_file, "w+")) == NULL) 215216294Ssyrinx return (-1); 216216294Ssyrinx fprintf(fp, "%s%u\n", myengine, snmpd_engine.engine_boots); 217216294Ssyrinx fclose(fp); 218216294Ssyrinx 219216294Ssyrinx return (0); 220216294Ssyrinx} 221216294Ssyrinx 222122394Sharti/************************************************************* 223122394Sharti * 224122394Sharti * System group 225122394Sharti */ 226122394Shartiint 227122394Shartiop_system_group(struct snmp_context *ctx, struct snmp_value *value, 228122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 229122394Sharti{ 230122394Sharti asn_subid_t which = value->var.subs[sub - 1]; 231122394Sharti 232122394Sharti switch (op) { 233122394Sharti 234122394Sharti case SNMP_OP_GETNEXT: 235122394Sharti abort(); 236122394Sharti 237122394Sharti case SNMP_OP_GET: 238122394Sharti break; 239122394Sharti 240122394Sharti case SNMP_OP_SET: 241122394Sharti switch (which) { 242122394Sharti 243122394Sharti case LEAF_sysDescr: 244122394Sharti if (community != COMM_INITIALIZE) 245122394Sharti return (SNMP_ERR_NOT_WRITEABLE); 246122394Sharti return (string_save(value, ctx, -1, &systemg.descr)); 247122394Sharti 248122394Sharti case LEAF_sysObjectId: 249122394Sharti if (community != COMM_INITIALIZE) 250122394Sharti return (SNMP_ERR_NOT_WRITEABLE); 251122394Sharti return (oid_save(value, ctx, &systemg.object_id)); 252122394Sharti 253122394Sharti case LEAF_sysContact: 254122394Sharti return (string_save(value, ctx, -1, &systemg.contact)); 255122394Sharti 256122394Sharti case LEAF_sysName: 257122394Sharti return (string_save(value, ctx, -1, &systemg.name)); 258122394Sharti 259122394Sharti case LEAF_sysLocation: 260122394Sharti return (string_save(value, ctx, -1, &systemg.location)); 261122394Sharti } 262122394Sharti return (SNMP_ERR_NO_CREATION); 263122394Sharti 264122394Sharti case SNMP_OP_ROLLBACK: 265122394Sharti switch (which) { 266122394Sharti 267122394Sharti case LEAF_sysDescr: 268122394Sharti string_rollback(ctx, &systemg.descr); 269122394Sharti return (SNMP_ERR_NOERROR); 270122394Sharti case LEAF_sysObjectId: 271122394Sharti oid_rollback(ctx, &systemg.object_id); 272122394Sharti return (SNMP_ERR_NOERROR); 273122394Sharti case LEAF_sysContact: 274122394Sharti string_rollback(ctx, &systemg.contact); 275122394Sharti return (SNMP_ERR_NOERROR); 276122394Sharti case LEAF_sysName: 277122394Sharti string_rollback(ctx, &systemg.name); 278122394Sharti return (SNMP_ERR_NOERROR); 279122394Sharti case LEAF_sysLocation: 280122394Sharti string_rollback(ctx, &systemg.location); 281122394Sharti return (SNMP_ERR_NOERROR); 282122394Sharti } 283122394Sharti abort(); 284122394Sharti 285122394Sharti case SNMP_OP_COMMIT: 286122394Sharti switch (which) { 287122394Sharti 288122394Sharti case LEAF_sysDescr: 289122394Sharti string_commit(ctx); 290122394Sharti return (SNMP_ERR_NOERROR); 291122394Sharti case LEAF_sysObjectId: 292122394Sharti oid_commit(ctx); 293122394Sharti return (SNMP_ERR_NOERROR); 294122394Sharti case LEAF_sysContact: 295122394Sharti string_commit(ctx); 296122394Sharti return (SNMP_ERR_NOERROR); 297122394Sharti case LEAF_sysName: 298122394Sharti string_commit(ctx); 299122394Sharti return (SNMP_ERR_NOERROR); 300122394Sharti case LEAF_sysLocation: 301122394Sharti string_commit(ctx); 302122394Sharti return (SNMP_ERR_NOERROR); 303122394Sharti } 304122394Sharti abort(); 305122394Sharti } 306122394Sharti 307122394Sharti /* 308122394Sharti * Come here for GET. 309122394Sharti */ 310122394Sharti switch (which) { 311122394Sharti 312122394Sharti case LEAF_sysDescr: 313122394Sharti return (string_get(value, systemg.descr, -1)); 314122394Sharti case LEAF_sysObjectId: 315122394Sharti return (oid_get(value, &systemg.object_id)); 316122394Sharti case LEAF_sysUpTime: 317122394Sharti value->v.uint32 = get_ticks() - start_tick; 318122394Sharti break; 319122394Sharti case LEAF_sysContact: 320122394Sharti return (string_get(value, systemg.contact, -1)); 321122394Sharti case LEAF_sysName: 322122394Sharti return (string_get(value, systemg.name, -1)); 323122394Sharti case LEAF_sysLocation: 324122394Sharti return (string_get(value, systemg.location, -1)); 325122394Sharti case LEAF_sysServices: 326122394Sharti value->v.integer = systemg.services; 327122394Sharti break; 328122394Sharti case LEAF_sysORLastChange: 329122394Sharti value->v.uint32 = systemg.or_last_change; 330122394Sharti break; 331122394Sharti } 332122394Sharti return (SNMP_ERR_NOERROR); 333122394Sharti} 334122394Sharti 335122394Sharti/************************************************************* 336122394Sharti * 337122394Sharti * Debug group 338122394Sharti */ 339122394Shartiint 340122394Shartiop_debug(struct snmp_context *ctx, struct snmp_value *value, u_int sub, 341122394Sharti u_int iidx __unused, enum snmp_op op) 342122394Sharti{ 343122394Sharti asn_subid_t which = value->var.subs[sub - 1]; 344122394Sharti 345122394Sharti switch (op) { 346122394Sharti 347122394Sharti case SNMP_OP_GETNEXT: 348122394Sharti abort(); 349122394Sharti 350122394Sharti case SNMP_OP_GET: 351122394Sharti switch (which) { 352122394Sharti 353122394Sharti case LEAF_begemotSnmpdDebugDumpPdus: 354122394Sharti value->v.integer = TRUTH_MK(debug.dump_pdus); 355122394Sharti break; 356122394Sharti 357122394Sharti case LEAF_begemotSnmpdDebugSnmpTrace: 358122394Sharti value->v.uint32 = snmp_trace; 359122394Sharti break; 360122394Sharti 361122394Sharti case LEAF_begemotSnmpdDebugSyslogPri: 362122394Sharti value->v.integer = debug.logpri; 363122394Sharti break; 364122394Sharti } 365122394Sharti return (SNMP_ERR_NOERROR); 366122394Sharti 367122394Sharti case SNMP_OP_SET: 368122394Sharti switch (which) { 369122394Sharti 370122394Sharti case LEAF_begemotSnmpdDebugDumpPdus: 371122394Sharti if (!TRUTH_OK(value->v.integer)) 372122394Sharti return (SNMP_ERR_WRONG_VALUE); 373122394Sharti ctx->scratch->int1 = debug.dump_pdus; 374122394Sharti debug.dump_pdus = TRUTH_GET(value->v.integer); 375122394Sharti return (SNMP_ERR_NOERROR); 376122394Sharti 377122394Sharti case LEAF_begemotSnmpdDebugSnmpTrace: 378122394Sharti ctx->scratch->int1 = snmp_trace; 379122394Sharti snmp_trace = value->v.uint32; 380122394Sharti return (SNMP_ERR_NOERROR); 381122394Sharti 382122394Sharti case LEAF_begemotSnmpdDebugSyslogPri: 383122394Sharti if (value->v.integer < 0 || value->v.integer > 8) 384122394Sharti return (SNMP_ERR_WRONG_VALUE); 385122394Sharti ctx->scratch->int1 = debug.logpri; 386122394Sharti debug.logpri = (u_int)value->v.integer; 387122394Sharti return (SNMP_ERR_NOERROR); 388122394Sharti } 389122394Sharti return (SNMP_ERR_NO_CREATION); 390122394Sharti 391122394Sharti case SNMP_OP_ROLLBACK: 392122394Sharti switch (which) { 393122394Sharti 394122394Sharti case LEAF_begemotSnmpdDebugDumpPdus: 395122394Sharti debug.dump_pdus = ctx->scratch->int1; 396122394Sharti return (SNMP_ERR_NOERROR); 397122394Sharti 398122394Sharti case LEAF_begemotSnmpdDebugSnmpTrace: 399122394Sharti snmp_trace = ctx->scratch->int1; 400122394Sharti return (SNMP_ERR_NOERROR); 401122394Sharti 402122394Sharti case LEAF_begemotSnmpdDebugSyslogPri: 403122394Sharti debug.logpri = ctx->scratch->int1; 404122394Sharti return (SNMP_ERR_NOERROR); 405122394Sharti } 406122394Sharti abort(); 407122394Sharti 408122394Sharti case SNMP_OP_COMMIT: 409122394Sharti switch (which) { 410122394Sharti 411122394Sharti case LEAF_begemotSnmpdDebugDumpPdus: 412122394Sharti case LEAF_begemotSnmpdDebugSnmpTrace: 413122394Sharti return (SNMP_ERR_NOERROR); 414122394Sharti 415122394Sharti case LEAF_begemotSnmpdDebugSyslogPri: 416122394Sharti if (debug.logpri == 0) 417122394Sharti setlogmask(0); 418122394Sharti else 419122394Sharti setlogmask(LOG_UPTO(debug.logpri - 1)); 420122394Sharti return (SNMP_ERR_NOERROR); 421122394Sharti } 422122394Sharti abort(); 423122394Sharti } 424122394Sharti abort(); 425122394Sharti} 426122394Sharti 427122394Sharti/************************************************************* 428122394Sharti * 429122394Sharti * OR Table 430122394Sharti */ 431122394Shartiint 432122394Shartiop_or_table(struct snmp_context *ctx __unused, struct snmp_value *value, 433122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 434122394Sharti{ 435122394Sharti struct objres *objres; 436122394Sharti 437122394Sharti switch (op) { 438122394Sharti 439122394Sharti case SNMP_OP_GETNEXT: 440122394Sharti if ((objres = NEXT_OBJECT_INT(&objres_list, &value->var, sub)) 441122394Sharti == NULL) 442122394Sharti return (SNMP_ERR_NOSUCHNAME); 443122394Sharti value->var.subs[sub] = objres->index; 444122394Sharti value->var.len = sub + 1; 445122394Sharti break; 446122394Sharti 447122394Sharti case SNMP_OP_GET: 448122394Sharti if ((objres = FIND_OBJECT_INT(&objres_list, &value->var, sub)) 449122394Sharti == NULL) 450122394Sharti return (SNMP_ERR_NOSUCHNAME); 451122394Sharti break; 452122394Sharti 453122394Sharti case SNMP_OP_SET: 454122394Sharti if ((objres = FIND_OBJECT_INT(&objres_list, &value->var, sub)) 455122394Sharti == NULL) 456122394Sharti return (SNMP_ERR_NO_CREATION); 457122394Sharti return (SNMP_ERR_NOT_WRITEABLE); 458122394Sharti 459122394Sharti case SNMP_OP_ROLLBACK: 460122394Sharti case SNMP_OP_COMMIT: 461122394Sharti default: 462122394Sharti abort(); 463122394Sharti } 464122394Sharti 465122394Sharti /* 466122394Sharti * Come here for GET, GETNEXT. 467122394Sharti */ 468122394Sharti switch (value->var.subs[sub - 1]) { 469122394Sharti 470122394Sharti case LEAF_sysORID: 471122394Sharti value->v.oid = objres->oid; 472122394Sharti break; 473122394Sharti 474122394Sharti case LEAF_sysORDescr: 475122394Sharti return (string_get(value, objres->descr, -1)); 476122394Sharti 477122394Sharti case LEAF_sysORUpTime: 478122394Sharti value->v.uint32 = objres->uptime; 479122394Sharti break; 480122394Sharti } 481122394Sharti return (SNMP_ERR_NOERROR); 482122394Sharti} 483122394Sharti 484122394Sharti/************************************************************* 485122394Sharti * 486122394Sharti * mib-2 snmp 487122394Sharti */ 488122394Shartiint 489122394Shartiop_snmp(struct snmp_context *ctx, struct snmp_value *value, 490122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 491122394Sharti{ 492122394Sharti switch (op) { 493122394Sharti 494122394Sharti case SNMP_OP_GETNEXT: 495122394Sharti abort(); 496122394Sharti 497122394Sharti case SNMP_OP_GET: 498122394Sharti switch (value->var.subs[sub - 1]) { 499122394Sharti 500122394Sharti case LEAF_snmpInPkts: 501122394Sharti value->v.uint32 = snmpd_stats.inPkts; 502122394Sharti break; 503122394Sharti 504122394Sharti case LEAF_snmpInBadVersions: 505122394Sharti value->v.uint32 = snmpd_stats.inBadVersions; 506122394Sharti break; 507122394Sharti 508122394Sharti case LEAF_snmpInBadCommunityNames: 509122394Sharti value->v.uint32 = snmpd_stats.inBadCommunityNames; 510122394Sharti break; 511122394Sharti 512122394Sharti case LEAF_snmpInBadCommunityUses: 513122394Sharti value->v.uint32 = snmpd_stats.inBadCommunityUses; 514122394Sharti break; 515122394Sharti 516122394Sharti case LEAF_snmpInASNParseErrs: 517122394Sharti value->v.uint32 = snmpd_stats.inASNParseErrs; 518122394Sharti break; 519122394Sharti 520122394Sharti case LEAF_snmpEnableAuthenTraps: 521122394Sharti value->v.integer = TRUTH_MK(snmpd.auth_traps); 522122394Sharti break; 523122394Sharti 524122394Sharti case LEAF_snmpSilentDrops: 525122394Sharti value->v.uint32 = snmpd_stats.silentDrops; 526122394Sharti break; 527122394Sharti 528122394Sharti case LEAF_snmpProxyDrops: 529122394Sharti value->v.uint32 = snmpd_stats.proxyDrops; 530122394Sharti break; 531122394Sharti 532122394Sharti default: 533122394Sharti return (SNMP_ERR_NOSUCHNAME); 534122394Sharti 535122394Sharti } 536122394Sharti return (SNMP_ERR_NOERROR); 537122394Sharti 538122394Sharti case SNMP_OP_SET: 539122394Sharti switch (value->var.subs[sub - 1]) { 540122394Sharti case LEAF_snmpEnableAuthenTraps: 541122394Sharti if (!TRUTH_OK(value->v.integer)) 542122394Sharti return (SNMP_ERR_WRONG_VALUE); 543122394Sharti ctx->scratch->int1 = value->v.integer; 544122394Sharti snmpd.auth_traps = TRUTH_GET(value->v.integer); 545122394Sharti return (SNMP_ERR_NOERROR); 546122394Sharti } 547122394Sharti abort(); 548122394Sharti 549122394Sharti case SNMP_OP_ROLLBACK: 550122394Sharti switch (value->var.subs[sub - 1]) { 551122394Sharti case LEAF_snmpEnableAuthenTraps: 552122394Sharti snmpd.auth_traps = ctx->scratch->int1; 553122394Sharti return (SNMP_ERR_NOERROR); 554122394Sharti } 555122394Sharti abort(); 556122394Sharti 557122394Sharti case SNMP_OP_COMMIT: 558122394Sharti switch (value->var.subs[sub - 1]) { 559122394Sharti case LEAF_snmpEnableAuthenTraps: 560122394Sharti return (SNMP_ERR_NOERROR); 561122394Sharti } 562122394Sharti abort(); 563122394Sharti } 564122394Sharti abort(); 565122394Sharti} 566122394Sharti 567122394Sharti/************************************************************* 568122394Sharti * 569122394Sharti * SNMPd statistics group 570122394Sharti */ 571122394Shartiint 572122394Shartiop_snmpd_stats(struct snmp_context *ctx __unused, struct snmp_value *value, 573122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 574122394Sharti{ 575122394Sharti switch (op) { 576122394Sharti 577122394Sharti case SNMP_OP_GET: 578122394Sharti switch (value->var.subs[sub - 1]) { 579122394Sharti 580122394Sharti case LEAF_begemotSnmpdStatsNoRxBufs: 581122394Sharti value->v.uint32 = snmpd_stats.noRxbuf; 582122394Sharti break; 583122394Sharti 584122394Sharti case LEAF_begemotSnmpdStatsNoTxBufs: 585122394Sharti value->v.uint32 = snmpd_stats.noTxbuf; 586122394Sharti break; 587122394Sharti 588122394Sharti case LEAF_begemotSnmpdStatsInTooLongPkts: 589122394Sharti value->v.uint32 = snmpd_stats.inTooLong; 590122394Sharti break; 591122394Sharti 592122394Sharti case LEAF_begemotSnmpdStatsInBadPduTypes: 593122394Sharti value->v.uint32 = snmpd_stats.inBadPduTypes; 594122394Sharti break; 595122394Sharti 596122394Sharti default: 597122394Sharti return (SNMP_ERR_NOSUCHNAME); 598122394Sharti } 599122394Sharti return (SNMP_ERR_NOERROR); 600122394Sharti 601122394Sharti case SNMP_OP_SET: 602122394Sharti case SNMP_OP_ROLLBACK: 603122394Sharti case SNMP_OP_COMMIT: 604122394Sharti case SNMP_OP_GETNEXT: 605122394Sharti abort(); 606122394Sharti } 607122394Sharti abort(); 608122394Sharti} 609122394Sharti 610122394Sharti/* 611122394Sharti * SNMPd configuration scalars 612122394Sharti */ 613122394Shartiint 614122394Shartiop_snmpd_config(struct snmp_context *ctx, struct snmp_value *value, 615122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 616122394Sharti{ 617122394Sharti asn_subid_t which = value->var.subs[sub - 1]; 618122394Sharti 619122394Sharti switch (op) { 620122394Sharti 621122394Sharti case SNMP_OP_GETNEXT: 622122394Sharti abort(); 623122394Sharti 624122394Sharti case SNMP_OP_GET: 625122394Sharti switch (which) { 626122394Sharti 627122394Sharti case LEAF_begemotSnmpdTransmitBuffer: 628122394Sharti value->v.integer = snmpd.txbuf; 629122394Sharti break; 630122394Sharti case LEAF_begemotSnmpdReceiveBuffer: 631122394Sharti value->v.integer = snmpd.rxbuf; 632122394Sharti break; 633122394Sharti case LEAF_begemotSnmpdCommunityDisable: 634122394Sharti value->v.integer = TRUTH_MK(snmpd.comm_dis); 635122394Sharti break; 636122394Sharti case LEAF_begemotSnmpdTrap1Addr: 637122394Sharti return (ip_get(value, snmpd.trap1addr)); 638124861Sharti case LEAF_begemotSnmpdVersionEnable: 639124861Sharti value->v.uint32 = snmpd.version_enable; 640124861Sharti break; 641122394Sharti default: 642122394Sharti return (SNMP_ERR_NOSUCHNAME); 643122394Sharti } 644122394Sharti return (SNMP_ERR_NOERROR); 645122394Sharti 646122394Sharti case SNMP_OP_SET: 647122394Sharti switch (which) { 648122394Sharti 649122394Sharti case LEAF_begemotSnmpdTransmitBuffer: 650122394Sharti ctx->scratch->int1 = snmpd.txbuf; 651122394Sharti if (value->v.integer < 484 || 652122394Sharti value->v.integer > 65535) 653122394Sharti return (SNMP_ERR_WRONG_VALUE); 654122394Sharti snmpd.txbuf = value->v.integer; 655122394Sharti return (SNMP_ERR_NOERROR); 656122394Sharti 657122394Sharti case LEAF_begemotSnmpdReceiveBuffer: 658122394Sharti ctx->scratch->int1 = snmpd.rxbuf; 659122394Sharti if (value->v.integer < 484 || 660122394Sharti value->v.integer > 65535) 661122394Sharti return (SNMP_ERR_WRONG_VALUE); 662122394Sharti snmpd.rxbuf = value->v.integer; 663122394Sharti return (SNMP_ERR_NOERROR); 664122394Sharti 665122394Sharti case LEAF_begemotSnmpdCommunityDisable: 666122394Sharti ctx->scratch->int1 = snmpd.comm_dis; 667122394Sharti if (!TRUTH_OK(value->v.integer)) 668122394Sharti return (SNMP_ERR_WRONG_VALUE); 669122394Sharti if (TRUTH_GET(value->v.integer)) { 670122394Sharti snmpd.comm_dis = 1; 671122394Sharti } else { 672122394Sharti if (snmpd.comm_dis) 673122394Sharti return (SNMP_ERR_WRONG_VALUE); 674122394Sharti } 675122394Sharti return (SNMP_ERR_NOERROR); 676122394Sharti 677122394Sharti case LEAF_begemotSnmpdTrap1Addr: 678122394Sharti return (ip_save(value, ctx, snmpd.trap1addr)); 679124861Sharti 680124861Sharti case LEAF_begemotSnmpdVersionEnable: 681124861Sharti if (community != COMM_INITIALIZE) 682124861Sharti return (SNMP_ERR_NOT_WRITEABLE); 683124861Sharti ctx->scratch->int1 = snmpd.version_enable; 684124861Sharti if (value->v.uint32 == 0 || 685124861Sharti (value->v.uint32 & ~VERS_ENABLE_ALL)) 686124861Sharti return (SNMP_ERR_WRONG_VALUE); 687124861Sharti snmpd.version_enable = value->v.uint32; 688124861Sharti return (SNMP_ERR_NOERROR); 689122394Sharti } 690122394Sharti abort(); 691122394Sharti 692122394Sharti case SNMP_OP_ROLLBACK: 693122394Sharti switch (which) { 694122394Sharti 695122394Sharti case LEAF_begemotSnmpdTransmitBuffer: 696122394Sharti snmpd.rxbuf = ctx->scratch->int1; 697122394Sharti return (SNMP_ERR_NOERROR); 698122394Sharti case LEAF_begemotSnmpdReceiveBuffer: 699122394Sharti snmpd.txbuf = ctx->scratch->int1; 700122394Sharti return (SNMP_ERR_NOERROR); 701122394Sharti case LEAF_begemotSnmpdCommunityDisable: 702122394Sharti snmpd.comm_dis = ctx->scratch->int1; 703122394Sharti return (SNMP_ERR_NOERROR); 704122394Sharti case LEAF_begemotSnmpdTrap1Addr: 705122394Sharti ip_rollback(ctx, snmpd.trap1addr); 706122394Sharti return (SNMP_ERR_NOERROR); 707124861Sharti case LEAF_begemotSnmpdVersionEnable: 708124861Sharti snmpd.version_enable = ctx->scratch->int1; 709124861Sharti return (SNMP_ERR_NOERROR); 710122394Sharti } 711122394Sharti abort(); 712122394Sharti 713122394Sharti case SNMP_OP_COMMIT: 714122394Sharti switch (which) { 715122394Sharti 716122394Sharti case LEAF_begemotSnmpdTransmitBuffer: 717122394Sharti case LEAF_begemotSnmpdReceiveBuffer: 718122394Sharti case LEAF_begemotSnmpdCommunityDisable: 719122394Sharti return (SNMP_ERR_NOERROR); 720122394Sharti case LEAF_begemotSnmpdTrap1Addr: 721122394Sharti ip_commit(ctx); 722122394Sharti return (SNMP_ERR_NOERROR); 723124861Sharti case LEAF_begemotSnmpdVersionEnable: 724124861Sharti return (SNMP_ERR_NOERROR); 725122394Sharti } 726122394Sharti abort(); 727122394Sharti } 728122394Sharti abort(); 729122394Sharti} 730122394Sharti 731122394Sharti/* 732122394Sharti * The community table 733122394Sharti */ 734122394Shartiint 735122394Shartiop_community(struct snmp_context *ctx, struct snmp_value *value, 736122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 737122394Sharti{ 738122394Sharti asn_subid_t which = value->var.subs[sub - 1]; 739122394Sharti struct community *c; 740122394Sharti 741122394Sharti switch (op) { 742122394Sharti 743122394Sharti case SNMP_OP_GETNEXT: 744122394Sharti if ((community != COMM_INITIALIZE && snmpd.comm_dis) || 745122394Sharti (c = NEXT_OBJECT_OID(&community_list, &value->var, sub)) == NULL) 746122394Sharti return (SNMP_ERR_NOSUCHNAME); 747122394Sharti index_append(&value->var, sub, &c->index); 748122394Sharti break; 749122394Sharti 750122394Sharti case SNMP_OP_GET: 751122394Sharti if ((community != COMM_INITIALIZE && snmpd.comm_dis) || 752122394Sharti (c = FIND_OBJECT_OID(&community_list, &value->var, sub)) == NULL) 753122394Sharti return (SNMP_ERR_NOSUCHNAME); 754122394Sharti break; 755122394Sharti 756122394Sharti case SNMP_OP_SET: 757122394Sharti if ((community != COMM_INITIALIZE && snmpd.comm_dis) || 758122394Sharti (c = FIND_OBJECT_OID(&community_list, &value->var, sub)) == NULL) 759122394Sharti return (SNMP_ERR_NO_CREATION); 760122394Sharti if (which != LEAF_begemotSnmpdCommunityString) 761122394Sharti return (SNMP_ERR_NOT_WRITEABLE); 762122394Sharti return (string_save(value, ctx, -1, &c->string)); 763122394Sharti 764122394Sharti case SNMP_OP_ROLLBACK: 765122394Sharti if (which == LEAF_begemotSnmpdCommunityString) { 766122394Sharti if ((c = FIND_OBJECT_OID(&community_list, &value->var, 767122394Sharti sub)) == NULL) 768122394Sharti string_free(ctx); 769122394Sharti else 770122394Sharti string_rollback(ctx, &c->string); 771122394Sharti return (SNMP_ERR_NOERROR); 772122394Sharti } 773122394Sharti abort(); 774122394Sharti 775122394Sharti case SNMP_OP_COMMIT: 776122394Sharti if (which == LEAF_begemotSnmpdCommunityString) { 777122394Sharti if ((c = FIND_OBJECT_OID(&community_list, &value->var, 778122394Sharti sub)) == NULL) 779122394Sharti string_free(ctx); 780122394Sharti else 781122394Sharti string_commit(ctx); 782122394Sharti return (SNMP_ERR_NOERROR); 783122394Sharti } 784122394Sharti abort(); 785122394Sharti 786122394Sharti default: 787122394Sharti abort(); 788122394Sharti } 789122394Sharti 790122394Sharti switch (which) { 791122394Sharti 792122394Sharti case LEAF_begemotSnmpdCommunityString: 793122394Sharti return (string_get(value, c->string, -1)); 794122394Sharti 795122394Sharti case LEAF_begemotSnmpdCommunityDescr: 796122394Sharti return (string_get(value, c->descr, -1)); 797122394Sharti } 798122394Sharti abort(); 799122394Sharti} 800122394Sharti 801122394Sharti/* 802122394Sharti * Module table. 803122394Sharti */ 804122394Shartistruct module_dep { 805122394Sharti struct snmp_dependency dep; 806122394Sharti u_char section[LM_SECTION_MAX + 1]; 807122394Sharti u_char *path; 808122394Sharti struct lmodule *m; 809122394Sharti}; 810122394Sharti 811122394Shartistatic int 812122394Shartidep_modules(struct snmp_context *ctx, struct snmp_dependency *dep, 813122394Sharti enum snmp_depop op) 814122394Sharti{ 815122394Sharti struct module_dep *mdep = (struct module_dep *)(void *)dep; 816122394Sharti 817122394Sharti switch (op) { 818122394Sharti 819122394Sharti case SNMP_DEPOP_COMMIT: 820122394Sharti if (mdep->path == NULL) { 821122394Sharti /* unload - find the module */ 822122394Sharti TAILQ_FOREACH(mdep->m, &lmodules, link) 823128237Sharti if (strcmp(mdep->m->section, 824128237Sharti mdep->section) == 0) 825122394Sharti break; 826122394Sharti if (mdep->m == NULL) 827128237Sharti /* no such module - that's ok */ 828122394Sharti return (SNMP_ERR_NOERROR); 829128237Sharti 830128237Sharti /* handle unloading in the finalizer */ 831122394Sharti return (SNMP_ERR_NOERROR); 832122394Sharti } 833122394Sharti /* load */ 834128237Sharti if ((mdep->m = lm_load(mdep->path, mdep->section)) == NULL) { 835128237Sharti /* could not load */ 836122394Sharti return (SNMP_ERR_RES_UNAVAIL); 837122394Sharti } 838128237Sharti /* start in finalizer */ 839122394Sharti return (SNMP_ERR_NOERROR); 840122394Sharti 841122394Sharti case SNMP_DEPOP_ROLLBACK: 842122394Sharti if (mdep->path == NULL) { 843128237Sharti /* rollback unload - the finalizer takes care */ 844122394Sharti return (SNMP_ERR_NOERROR); 845122394Sharti } 846122394Sharti /* rollback load */ 847122394Sharti lm_unload(mdep->m); 848122394Sharti return (SNMP_ERR_NOERROR); 849128237Sharti 850128237Sharti case SNMP_DEPOP_FINISH: 851128237Sharti if (mdep->path == NULL) { 852128237Sharti if (mdep->m != NULL && ctx->code == SNMP_RET_OK) 853128237Sharti lm_unload(mdep->m); 854128237Sharti } else { 855128237Sharti if (mdep->m != NULL && ctx->code == SNMP_RET_OK && 856128237Sharti community != COMM_INITIALIZE) 857128237Sharti lm_start(mdep->m); 858128237Sharti free(mdep->path); 859128237Sharti } 860128237Sharti return (SNMP_ERR_NOERROR); 861122394Sharti } 862122394Sharti abort(); 863122394Sharti} 864122394Sharti 865122394Shartiint 866122394Shartiop_modules(struct snmp_context *ctx, struct snmp_value *value, 867122394Sharti u_int sub, u_int iidx, enum snmp_op op) 868122394Sharti{ 869122394Sharti asn_subid_t which = value->var.subs[sub - 1]; 870122394Sharti struct lmodule *m; 871122394Sharti u_char *section, *ptr; 872122394Sharti size_t seclen; 873122394Sharti struct module_dep *mdep; 874122394Sharti struct asn_oid idx; 875122394Sharti 876122394Sharti switch (op) { 877122394Sharti 878122394Sharti case SNMP_OP_GETNEXT: 879122394Sharti if ((m = NEXT_OBJECT_OID(&lmodules, &value->var, sub)) == NULL) 880122394Sharti return (SNMP_ERR_NOSUCHNAME); 881122394Sharti index_append(&value->var, sub, &m->index); 882122394Sharti break; 883122394Sharti 884122394Sharti case SNMP_OP_GET: 885122394Sharti if ((m = FIND_OBJECT_OID(&lmodules, &value->var, sub)) == NULL) 886122394Sharti return (SNMP_ERR_NOSUCHNAME); 887122394Sharti break; 888122394Sharti 889122394Sharti case SNMP_OP_SET: 890122394Sharti m = FIND_OBJECT_OID(&lmodules, &value->var, sub); 891122394Sharti if (which != LEAF_begemotSnmpdModulePath) { 892122394Sharti if (m == NULL) 893122394Sharti return (SNMP_ERR_NO_CREATION); 894122394Sharti return (SNMP_ERR_NOT_WRITEABLE); 895122394Sharti } 896122394Sharti 897122394Sharti /* the errors in the next few statements can only happen when 898122394Sharti * m is NULL, hence the NO_CREATION error. */ 899122394Sharti if (index_decode(&value->var, sub, iidx, 900122394Sharti §ion, &seclen)) 901122394Sharti return (SNMP_ERR_NO_CREATION); 902122394Sharti 903122394Sharti /* check the section name */ 904122394Sharti if (seclen > LM_SECTION_MAX || seclen == 0) { 905122394Sharti free(section); 906122394Sharti return (SNMP_ERR_NO_CREATION); 907122394Sharti } 908122394Sharti for (ptr = section; ptr < section + seclen; ptr++) 909122394Sharti if (!isascii(*ptr) || !isalnum(*ptr)) { 910122394Sharti free(section); 911122394Sharti return (SNMP_ERR_NO_CREATION); 912122394Sharti } 913122394Sharti if (!isalpha(section[0])) { 914122394Sharti free(section); 915122394Sharti return (SNMP_ERR_NO_CREATION); 916122394Sharti } 917122394Sharti 918122394Sharti /* check the path */ 919122394Sharti for (ptr = value->v.octetstring.octets; 920122394Sharti ptr < value->v.octetstring.octets + value->v.octetstring.len; 921122394Sharti ptr++) { 922122394Sharti if (*ptr == '\0') { 923122394Sharti free(section); 924122394Sharti return (SNMP_ERR_WRONG_VALUE); 925122394Sharti } 926122394Sharti } 927122394Sharti 928122394Sharti if (m == NULL) { 929122394Sharti if (value->v.octetstring.len == 0) { 930122394Sharti free(section); 931122394Sharti return (SNMP_ERR_INCONS_VALUE); 932122394Sharti } 933122394Sharti } else { 934122394Sharti if (value->v.octetstring.len != 0) { 935122394Sharti free(section); 936122394Sharti return (SNMP_ERR_INCONS_VALUE); 937122394Sharti } 938122394Sharti } 939122394Sharti 940122394Sharti asn_slice_oid(&idx, &value->var, sub, value->var.len); 941122394Sharti 942122394Sharti /* so far, so good */ 943122394Sharti mdep = (struct module_dep *)(void *)snmp_dep_lookup(ctx, 944122394Sharti &oid_begemotSnmpdModuleTable, &idx, 945122394Sharti sizeof(*mdep), dep_modules); 946122394Sharti if (mdep == NULL) { 947122394Sharti free(section); 948122394Sharti return (SNMP_ERR_RES_UNAVAIL); 949122394Sharti } 950122394Sharti 951122394Sharti if (mdep->section[0] != '\0') { 952122394Sharti /* two writes to the same entry - bad */ 953122394Sharti free(section); 954122394Sharti return (SNMP_ERR_INCONS_VALUE); 955122394Sharti } 956122394Sharti 957122394Sharti strncpy(mdep->section, section, seclen); 958122394Sharti mdep->section[seclen] = '\0'; 959122394Sharti free(section); 960122394Sharti 961122394Sharti if (value->v.octetstring.len == 0) 962122394Sharti mdep->path = NULL; 963122394Sharti else { 964122394Sharti if ((mdep->path = malloc(value->v.octetstring.len + 1)) == NULL) 965122394Sharti return (SNMP_ERR_RES_UNAVAIL); 966122394Sharti strncpy(mdep->path, value->v.octetstring.octets, 967122394Sharti value->v.octetstring.len); 968122394Sharti mdep->path[value->v.octetstring.len] = '\0'; 969122394Sharti } 970122394Sharti ctx->scratch->ptr1 = mdep; 971122394Sharti return (SNMP_ERR_NOERROR); 972122394Sharti 973122394Sharti case SNMP_OP_ROLLBACK: 974122394Sharti case SNMP_OP_COMMIT: 975122394Sharti return (SNMP_ERR_NOERROR); 976122394Sharti 977122394Sharti default: 978122394Sharti abort(); 979122394Sharti } 980122394Sharti 981122394Sharti switch (which) { 982122394Sharti 983122394Sharti case LEAF_begemotSnmpdModulePath: 984122394Sharti return (string_get(value, m->path, -1)); 985122394Sharti 986122394Sharti case LEAF_begemotSnmpdModuleComment: 987122394Sharti return (string_get(value, m->config->comment, -1)); 988122394Sharti } 989122394Sharti abort(); 990122394Sharti} 991122394Sharti 992122394Shartiint 993122394Shartiop_snmp_set(struct snmp_context *ctx __unused, struct snmp_value *value, 994122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 995122394Sharti{ 996122394Sharti switch (op) { 997122394Sharti 998122394Sharti case SNMP_OP_GETNEXT: 999122394Sharti abort(); 1000122394Sharti 1001122394Sharti case SNMP_OP_GET: 1002122394Sharti switch (value->var.subs[sub - 1]) { 1003122394Sharti 1004122394Sharti case LEAF_snmpSetSerialNo: 1005122394Sharti value->v.integer = snmp_serial_no; 1006122394Sharti break; 1007122394Sharti 1008122394Sharti default: 1009122394Sharti abort(); 1010122394Sharti } 1011122394Sharti return (SNMP_ERR_NOERROR); 1012122394Sharti 1013122394Sharti case SNMP_OP_SET: 1014122394Sharti switch (value->var.subs[sub - 1]) { 1015122394Sharti 1016122394Sharti case LEAF_snmpSetSerialNo: 1017122394Sharti if (value->v.integer != snmp_serial_no) 1018122394Sharti return (SNMP_ERR_INCONS_VALUE); 1019122394Sharti break; 1020122394Sharti 1021122394Sharti default: 1022122394Sharti abort(); 1023122394Sharti } 1024122394Sharti return (SNMP_ERR_NOERROR); 1025122394Sharti 1026122394Sharti case SNMP_OP_ROLLBACK: 1027122394Sharti return (SNMP_ERR_NOERROR); 1028122394Sharti 1029122394Sharti case SNMP_OP_COMMIT: 1030122394Sharti if (snmp_serial_no++ == 2147483647) 1031122394Sharti snmp_serial_no = 0; 1032122394Sharti return (SNMP_ERR_NOERROR); 1033122394Sharti } 1034122394Sharti abort(); 1035122394Sharti} 1036124861Sharti 1037124861Sharti/* 1038216294Ssyrinx * SNMP Engine 1039216294Ssyrinx */ 1040216294Ssyrinxint 1041216294Ssyrinxop_snmp_engine(struct snmp_context *ctx __unused, struct snmp_value *value, 1042216294Ssyrinx u_int sub, u_int iidx __unused, enum snmp_op op) 1043216294Ssyrinx{ 1044216294Ssyrinx asn_subid_t which = value->var.subs[sub - 1]; 1045216294Ssyrinx 1046216294Ssyrinx switch (op) { 1047216294Ssyrinx case SNMP_OP_GETNEXT: 1048216294Ssyrinx abort(); 1049216294Ssyrinx 1050216294Ssyrinx case SNMP_OP_GET: 1051216294Ssyrinx break; 1052216294Ssyrinx 1053216294Ssyrinx case SNMP_OP_SET: 1054216294Ssyrinx if (community != COMM_INITIALIZE) 1055216294Ssyrinx return (SNMP_ERR_NOT_WRITEABLE); 1056216294Ssyrinx switch (which) { 1057216294Ssyrinx case LEAF_snmpEngineID: 1058216294Ssyrinx if (value->v.octetstring.len > SNMP_ENGINE_ID_SIZ) 1059216294Ssyrinx return (SNMP_ERR_WRONG_VALUE); 1060216294Ssyrinx ctx->scratch->ptr1 = malloc(snmpd_engine.engine_len); 1061216294Ssyrinx if (ctx->scratch->ptr1 == NULL) 1062216294Ssyrinx return (SNMP_ERR_GENERR); 1063216294Ssyrinx memcpy(ctx->scratch->ptr1, snmpd_engine.engine_id, 1064216294Ssyrinx snmpd_engine.engine_len); 1065216294Ssyrinx ctx->scratch->int1 = snmpd_engine.engine_len; 1066216294Ssyrinx snmpd_engine.engine_len = value->v.octetstring.len; 1067216294Ssyrinx memcpy(snmpd_engine.engine_id, 1068216294Ssyrinx value->v.octetstring.octets, 1069216294Ssyrinx value->v.octetstring.len); 1070216294Ssyrinx break; 1071216294Ssyrinx 1072216294Ssyrinx case LEAF_snmpEngineMaxMessageSize: 1073216294Ssyrinx ctx->scratch->int1 = snmpd_engine.max_msg_size; 1074216294Ssyrinx snmpd_engine.max_msg_size = value->v.integer; 1075216294Ssyrinx break; 1076216294Ssyrinx 1077216294Ssyrinx default: 1078216294Ssyrinx return (SNMP_ERR_NOT_WRITEABLE); 1079216294Ssyrinx } 1080216294Ssyrinx return (SNMP_ERR_NOERROR); 1081216294Ssyrinx 1082216294Ssyrinx case SNMP_OP_ROLLBACK: 1083216294Ssyrinx switch (which) { 1084216294Ssyrinx case LEAF_snmpEngineID: 1085216294Ssyrinx snmpd_engine.engine_len = ctx->scratch->int1; 1086216294Ssyrinx memcpy(snmpd_engine.engine_id, ctx->scratch->ptr1, 1087216294Ssyrinx snmpd_engine.engine_len); 1088216294Ssyrinx free(ctx->scratch->ptr1); 1089216294Ssyrinx break; 1090216294Ssyrinx 1091216294Ssyrinx case LEAF_snmpEngineMaxMessageSize: 1092216294Ssyrinx snmpd_engine.max_msg_size = ctx->scratch->int1; 1093216294Ssyrinx break; 1094216294Ssyrinx 1095216294Ssyrinx default: 1096216294Ssyrinx abort(); 1097216294Ssyrinx } 1098216294Ssyrinx return (SNMP_ERR_NOERROR); 1099216294Ssyrinx 1100216294Ssyrinx case SNMP_OP_COMMIT: 1101216294Ssyrinx if (which == LEAF_snmpEngineID) { 1102216294Ssyrinx if (set_snmpd_engine() < 0) { 1103216294Ssyrinx snmpd_engine.engine_len = ctx->scratch->int1; 1104216294Ssyrinx memcpy(snmpd_engine.engine_id, 1105216294Ssyrinx ctx->scratch->ptr1, ctx->scratch->int1); 1106216294Ssyrinx } 1107216294Ssyrinx free(ctx->scratch->ptr1); 1108216294Ssyrinx } 1109216294Ssyrinx return (SNMP_ERR_NOERROR); 1110216294Ssyrinx } 1111216294Ssyrinx 1112216294Ssyrinx 1113216294Ssyrinx switch (which) { 1114216294Ssyrinx case LEAF_snmpEngineID: 1115216294Ssyrinx return (string_get(value, snmpd_engine.engine_id, 1116216294Ssyrinx snmpd_engine.engine_len)); 1117216294Ssyrinx case LEAF_snmpEngineBoots: 1118216294Ssyrinx value->v.integer = snmpd_engine.engine_boots; 1119216294Ssyrinx break; 1120216294Ssyrinx case LEAF_snmpEngineTime: 1121216294Ssyrinx snmpd_engine.engine_time = (get_ticks() - start_tick) / 100ULL; 1122216294Ssyrinx value->v.integer = snmpd_engine.engine_time; 1123216294Ssyrinx break; 1124216294Ssyrinx case LEAF_snmpEngineMaxMessageSize: 1125216294Ssyrinx value->v.integer = snmpd_engine.max_msg_size; 1126216294Ssyrinx break; 1127216294Ssyrinx default: 1128216294Ssyrinx return (SNMP_ERR_NOSUCHNAME); 1129216294Ssyrinx } 1130216294Ssyrinx 1131216294Ssyrinx return (SNMP_ERR_NOERROR); 1132216294Ssyrinx} 1133216294Ssyrinx 1134216294Ssyrinx/* 1135124861Sharti * Transport table 1136124861Sharti */ 1137124861Shartiint 1138124861Shartiop_transport_table(struct snmp_context *ctx __unused, struct snmp_value *value, 1139124861Sharti u_int sub, u_int iidx, enum snmp_op op) 1140124861Sharti{ 1141124861Sharti asn_subid_t which = value->var.subs[sub - 1]; 1142124861Sharti struct transport *t; 1143124861Sharti u_char *tname, *ptr; 1144124861Sharti size_t tnamelen; 1145124861Sharti 1146124861Sharti switch (op) { 1147124861Sharti 1148124861Sharti case SNMP_OP_GETNEXT: 1149124861Sharti if ((t = NEXT_OBJECT_OID(&transport_list, &value->var, sub)) 1150124861Sharti == NULL) 1151124861Sharti return (SNMP_ERR_NOSUCHNAME); 1152124861Sharti index_append(&value->var, sub, &t->index); 1153124861Sharti break; 1154124861Sharti 1155124861Sharti case SNMP_OP_GET: 1156124861Sharti if ((t = FIND_OBJECT_OID(&transport_list, &value->var, sub)) 1157124861Sharti == NULL) 1158124861Sharti return (SNMP_ERR_NOSUCHNAME); 1159124861Sharti break; 1160124861Sharti 1161124861Sharti case SNMP_OP_SET: 1162124861Sharti t = FIND_OBJECT_OID(&transport_list, &value->var, sub); 1163124861Sharti if (which != LEAF_begemotSnmpdTransportStatus) { 1164124861Sharti if (t == NULL) 1165124861Sharti return (SNMP_ERR_NO_CREATION); 1166124861Sharti return (SNMP_ERR_NOT_WRITEABLE); 1167124861Sharti } 1168124861Sharti 1169124861Sharti /* the errors in the next few statements can only happen when 1170124861Sharti * t is NULL, hence the NO_CREATION error. */ 1171124861Sharti if (index_decode(&value->var, sub, iidx, 1172124861Sharti &tname, &tnamelen)) 1173124861Sharti return (SNMP_ERR_NO_CREATION); 1174124861Sharti 1175124861Sharti /* check the section name */ 1176124861Sharti if (tnamelen >= TRANS_NAMELEN || tnamelen == 0) { 1177124861Sharti free(tname); 1178124861Sharti return (SNMP_ERR_NO_CREATION); 1179124861Sharti } 1180124861Sharti for (ptr = tname; ptr < tname + tnamelen; ptr++) { 1181124861Sharti if (!isascii(*ptr) || !isalnum(*ptr)) { 1182124861Sharti free(tname); 1183124861Sharti return (SNMP_ERR_NO_CREATION); 1184124861Sharti } 1185124861Sharti } 1186124861Sharti 1187124861Sharti /* for now */ 1188124861Sharti return (SNMP_ERR_NOT_WRITEABLE); 1189124861Sharti 1190124861Sharti case SNMP_OP_ROLLBACK: 1191124861Sharti case SNMP_OP_COMMIT: 1192124861Sharti return (SNMP_ERR_NOERROR); 1193124861Sharti default: 1194124861Sharti abort(); 1195124861Sharti } 1196124861Sharti 1197124861Sharti switch (which) { 1198124861Sharti 1199124861Sharti case LEAF_begemotSnmpdTransportStatus: 1200124861Sharti value->v.integer = 1; 1201124861Sharti break; 1202124861Sharti 1203124861Sharti case LEAF_begemotSnmpdTransportOid: 1204124861Sharti memcpy(&value->v.oid, &t->vtab->id, sizeof(t->vtab->id)); 1205124861Sharti break; 1206124861Sharti } 1207124861Sharti return (SNMP_ERR_NOERROR); 1208124861Sharti} 1209