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 a string value from the KERN sysctl subtree. 64122394Sharti */ 65122394Shartistatic char * 66122394Shartiact_getkernstring(int id) 67122394Sharti{ 68122394Sharti int mib[2]; 69122394Sharti size_t len; 70122394Sharti char *string; 71122394Sharti 72122394Sharti mib[0] = CTL_KERN; 73122394Sharti mib[1] = id; 74122394Sharti if (sysctl(mib, 2, NULL, &len, NULL, 0) != 0) 75122394Sharti return (NULL); 76122394Sharti if ((string = malloc(len)) == NULL) 77122394Sharti return (NULL); 78122394Sharti if (sysctl(mib, 2, string, &len, NULL, 0) != 0) { 79122394Sharti free(string); 80122394Sharti return (NULL); 81122394Sharti } 82122394Sharti return (string); 83122394Sharti} 84122394Sharti 85122394Sharti/* 86122394Sharti * Get an integer value from the KERN sysctl subtree. 87122394Sharti */ 88122394Shartistatic char * 89122394Shartiact_getkernint(int id) 90122394Sharti{ 91122394Sharti int mib[2]; 92122394Sharti size_t len; 93122394Sharti u_long value; 94122394Sharti char *string; 95122394Sharti 96122394Sharti mib[0] = CTL_KERN; 97122394Sharti mib[1] = id; 98122394Sharti len = sizeof(value); 99122394Sharti if (sysctl(mib, 2, &value, &len, NULL, 0) != 0) 100122394Sharti return (NULL); 101122394Sharti 102122394Sharti if ((string = malloc(20)) == NULL) 103122394Sharti return (NULL); 104122394Sharti sprintf(string, "%lu", value); 105122394Sharti return (string); 106122394Sharti} 107122394Sharti 108122394Sharti/* 109122394Sharti * Initialize global variables of the system group. 110122394Sharti */ 111122394Shartiint 112122394Shartiinit_actvals(void) 113122394Sharti{ 114163820Sharti struct utsname uts; 115163820Sharti char *hostid; 116122394Sharti size_t len; 117163820Sharti#ifdef __FreeBSD__ 118163820Sharti char *rel, *p, *end; 119163820Sharti u_long num; 120163820Sharti#endif 121122394Sharti 122163820Sharti if (uname(&uts) == -1) 123122394Sharti return (-1); 124122394Sharti 125163820Sharti if ((systemg.name = strdup(uts.nodename)) == NULL) 126163820Sharti return (-1); 127122394Sharti 128163820Sharti if ((hostid = act_getkernint(KERN_HOSTID)) == NULL) 129163820Sharti return (-1); 130122394Sharti 131163820Sharti len = strlen(uts.nodename) + 1; 132163820Sharti len += strlen(hostid) + 1; 133163820Sharti len += strlen(uts.sysname) + 1; 134163820Sharti len += strlen(uts.release) + 1; 135122394Sharti 136163820Sharti if ((systemg.descr = malloc(len)) == NULL) { 137163820Sharti free(hostid); 138163820Sharti return (-1); 139163820Sharti } 140163820Sharti sprintf(systemg.descr, "%s %s %s %s", uts.nodename, hostid, uts.sysname, 141163820Sharti uts.release); 142122394Sharti 143163820Sharti#ifdef __FreeBSD__ 144163820Sharti /* 145163820Sharti * Construct a FreeBSD oid 146163820Sharti */ 147163820Sharti systemg.object_id = oid_freeBSDVersion; 148163820Sharti rel = uts.release; 149163820Sharti while ((p = strsep(&rel, ".")) != NULL && 150163820Sharti systemg.object_id.len < ASN_MAXOIDLEN) { 151163820Sharti systemg.object_id.subs[systemg.object_id.len] = 0; 152163820Sharti if (*p != '\0') { 153163820Sharti num = strtoul(p, &end, 10); 154163820Sharti if (end == p) 155163820Sharti break; 156163820Sharti systemg.object_id.subs[systemg.object_id.len] = num; 157163820Sharti } 158163820Sharti systemg.object_id.len++; 159163820Sharti } 160163820Sharti#endif 161163820Sharti 162163820Sharti free(hostid); 163163820Sharti 164122394Sharti return (0); 165122394Sharti} 166122394Sharti 167216294Ssyrinx/* 168216294Ssyrinx * Initialize global variables of the snmpEngine group. 169216294Ssyrinx */ 170216294Ssyrinxint 171216294Ssyrinxinit_snmpd_engine(void) 172216294Ssyrinx{ 173216294Ssyrinx char *hostid; 174122394Sharti 175216294Ssyrinx snmpd_engine.engine_boots = 1; 176216294Ssyrinx snmpd_engine.engine_time = 1; 177216294Ssyrinx snmpd_engine.max_msg_size = 1500; /* XXX */ 178122394Sharti 179216294Ssyrinx snmpd_engine.engine_id[0] = ((OID_freeBSD & 0xff000000) >> 24) | 0x80; 180216294Ssyrinx snmpd_engine.engine_id[1] = (OID_freeBSD & 0xff0000) >> 16; 181216294Ssyrinx snmpd_engine.engine_id[2] = (OID_freeBSD & 0xff00) >> 8; 182216294Ssyrinx snmpd_engine.engine_id[3] = OID_freeBSD & 0xff; 183216294Ssyrinx snmpd_engine.engine_id[4] = 128; 184216294Ssyrinx snmpd_engine.engine_len = 5; 185216294Ssyrinx 186216294Ssyrinx if ((hostid = act_getkernint(KERN_HOSTID)) == NULL) 187216294Ssyrinx return (-1); 188216294Ssyrinx 189216294Ssyrinx if (strlen(hostid) > SNMP_ENGINE_ID_SIZ - snmpd_engine.engine_len) { 190216294Ssyrinx memcpy(snmpd_engine.engine_id + snmpd_engine.engine_len, 191216294Ssyrinx hostid, SNMP_ENGINE_ID_SIZ - snmpd_engine.engine_len); 192216294Ssyrinx snmpd_engine.engine_len = SNMP_ENGINE_ID_SIZ; 193216294Ssyrinx } else { 194216294Ssyrinx memcpy(snmpd_engine.engine_id + snmpd_engine.engine_len, 195216294Ssyrinx hostid, strlen(hostid)); 196216294Ssyrinx snmpd_engine.engine_len += strlen(hostid); 197216294Ssyrinx } 198216294Ssyrinx 199216294Ssyrinx free(hostid); 200216294Ssyrinx 201216294Ssyrinx return (0); 202216294Ssyrinx} 203216294Ssyrinx 204216294Ssyrinxint 205216294Ssyrinxset_snmpd_engine(void) 206216294Ssyrinx{ 207216294Ssyrinx FILE *fp; 208216294Ssyrinx uint32_t i; 209216294Ssyrinx uint8_t *cptr, engine[2 * SNMP_ENGINE_ID_SIZ + 2]; 210216294Ssyrinx uint8_t myengine[2 * SNMP_ENGINE_ID_SIZ + 2]; 211216294Ssyrinx 212216294Ssyrinx if (engine_file[0] == '\0') 213216294Ssyrinx return (-1); 214216294Ssyrinx 215216294Ssyrinx cptr = myengine; 216216294Ssyrinx for (i = 0; i < snmpd_engine.engine_len; i++) 217216294Ssyrinx cptr += sprintf(cptr, "%.2x", snmpd_engine.engine_id[i]); 218216294Ssyrinx *cptr++ = '\n'; 219216294Ssyrinx *cptr++ = '\0'; 220216294Ssyrinx 221216294Ssyrinx if ((fp = fopen(engine_file, "r+")) != NULL) { 222216294Ssyrinx if (fgets(engine, sizeof(engine) - 1, fp) == NULL || 223216294Ssyrinx fscanf(fp, "%u", &snmpd_engine.engine_boots) <= 0) { 224216294Ssyrinx fclose(fp); 225216294Ssyrinx goto save_boots; 226216294Ssyrinx } 227216294Ssyrinx 228216294Ssyrinx fclose(fp); 229216294Ssyrinx if (strcmp(myengine, engine) != 0) 230216294Ssyrinx snmpd_engine.engine_boots = 1; 231216294Ssyrinx else 232216294Ssyrinx snmpd_engine.engine_boots++; 233216294Ssyrinx } else if (errno != ENOENT) 234216294Ssyrinx return (-1); 235216294Ssyrinx 236216294Ssyrinxsave_boots: 237216294Ssyrinx if ((fp = fopen(engine_file, "w+")) == NULL) 238216294Ssyrinx return (-1); 239216294Ssyrinx fprintf(fp, "%s%u\n", myengine, snmpd_engine.engine_boots); 240216294Ssyrinx fclose(fp); 241216294Ssyrinx 242216294Ssyrinx return (0); 243216294Ssyrinx} 244216294Ssyrinx 245122394Sharti/************************************************************* 246122394Sharti * 247122394Sharti * System group 248122394Sharti */ 249122394Shartiint 250122394Shartiop_system_group(struct snmp_context *ctx, struct snmp_value *value, 251122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 252122394Sharti{ 253122394Sharti asn_subid_t which = value->var.subs[sub - 1]; 254122394Sharti 255122394Sharti switch (op) { 256122394Sharti 257122394Sharti case SNMP_OP_GETNEXT: 258122394Sharti abort(); 259122394Sharti 260122394Sharti case SNMP_OP_GET: 261122394Sharti break; 262122394Sharti 263122394Sharti case SNMP_OP_SET: 264122394Sharti switch (which) { 265122394Sharti 266122394Sharti case LEAF_sysDescr: 267122394Sharti if (community != COMM_INITIALIZE) 268122394Sharti return (SNMP_ERR_NOT_WRITEABLE); 269122394Sharti return (string_save(value, ctx, -1, &systemg.descr)); 270122394Sharti 271122394Sharti case LEAF_sysObjectId: 272122394Sharti if (community != COMM_INITIALIZE) 273122394Sharti return (SNMP_ERR_NOT_WRITEABLE); 274122394Sharti return (oid_save(value, ctx, &systemg.object_id)); 275122394Sharti 276122394Sharti case LEAF_sysContact: 277122394Sharti return (string_save(value, ctx, -1, &systemg.contact)); 278122394Sharti 279122394Sharti case LEAF_sysName: 280122394Sharti return (string_save(value, ctx, -1, &systemg.name)); 281122394Sharti 282122394Sharti case LEAF_sysLocation: 283122394Sharti return (string_save(value, ctx, -1, &systemg.location)); 284122394Sharti } 285122394Sharti return (SNMP_ERR_NO_CREATION); 286122394Sharti 287122394Sharti case SNMP_OP_ROLLBACK: 288122394Sharti switch (which) { 289122394Sharti 290122394Sharti case LEAF_sysDescr: 291122394Sharti string_rollback(ctx, &systemg.descr); 292122394Sharti return (SNMP_ERR_NOERROR); 293122394Sharti case LEAF_sysObjectId: 294122394Sharti oid_rollback(ctx, &systemg.object_id); 295122394Sharti return (SNMP_ERR_NOERROR); 296122394Sharti case LEAF_sysContact: 297122394Sharti string_rollback(ctx, &systemg.contact); 298122394Sharti return (SNMP_ERR_NOERROR); 299122394Sharti case LEAF_sysName: 300122394Sharti string_rollback(ctx, &systemg.name); 301122394Sharti return (SNMP_ERR_NOERROR); 302122394Sharti case LEAF_sysLocation: 303122394Sharti string_rollback(ctx, &systemg.location); 304122394Sharti return (SNMP_ERR_NOERROR); 305122394Sharti } 306122394Sharti abort(); 307122394Sharti 308122394Sharti case SNMP_OP_COMMIT: 309122394Sharti switch (which) { 310122394Sharti 311122394Sharti case LEAF_sysDescr: 312122394Sharti string_commit(ctx); 313122394Sharti return (SNMP_ERR_NOERROR); 314122394Sharti case LEAF_sysObjectId: 315122394Sharti oid_commit(ctx); 316122394Sharti return (SNMP_ERR_NOERROR); 317122394Sharti case LEAF_sysContact: 318122394Sharti string_commit(ctx); 319122394Sharti return (SNMP_ERR_NOERROR); 320122394Sharti case LEAF_sysName: 321122394Sharti string_commit(ctx); 322122394Sharti return (SNMP_ERR_NOERROR); 323122394Sharti case LEAF_sysLocation: 324122394Sharti string_commit(ctx); 325122394Sharti return (SNMP_ERR_NOERROR); 326122394Sharti } 327122394Sharti abort(); 328122394Sharti } 329122394Sharti 330122394Sharti /* 331122394Sharti * Come here for GET. 332122394Sharti */ 333122394Sharti switch (which) { 334122394Sharti 335122394Sharti case LEAF_sysDescr: 336122394Sharti return (string_get(value, systemg.descr, -1)); 337122394Sharti case LEAF_sysObjectId: 338122394Sharti return (oid_get(value, &systemg.object_id)); 339122394Sharti case LEAF_sysUpTime: 340122394Sharti value->v.uint32 = get_ticks() - start_tick; 341122394Sharti break; 342122394Sharti case LEAF_sysContact: 343122394Sharti return (string_get(value, systemg.contact, -1)); 344122394Sharti case LEAF_sysName: 345122394Sharti return (string_get(value, systemg.name, -1)); 346122394Sharti case LEAF_sysLocation: 347122394Sharti return (string_get(value, systemg.location, -1)); 348122394Sharti case LEAF_sysServices: 349122394Sharti value->v.integer = systemg.services; 350122394Sharti break; 351122394Sharti case LEAF_sysORLastChange: 352122394Sharti value->v.uint32 = systemg.or_last_change; 353122394Sharti break; 354122394Sharti } 355122394Sharti return (SNMP_ERR_NOERROR); 356122394Sharti} 357122394Sharti 358122394Sharti/************************************************************* 359122394Sharti * 360122394Sharti * Debug group 361122394Sharti */ 362122394Shartiint 363122394Shartiop_debug(struct snmp_context *ctx, struct snmp_value *value, u_int sub, 364122394Sharti u_int iidx __unused, enum snmp_op op) 365122394Sharti{ 366122394Sharti asn_subid_t which = value->var.subs[sub - 1]; 367122394Sharti 368122394Sharti switch (op) { 369122394Sharti 370122394Sharti case SNMP_OP_GETNEXT: 371122394Sharti abort(); 372122394Sharti 373122394Sharti case SNMP_OP_GET: 374122394Sharti switch (which) { 375122394Sharti 376122394Sharti case LEAF_begemotSnmpdDebugDumpPdus: 377122394Sharti value->v.integer = TRUTH_MK(debug.dump_pdus); 378122394Sharti break; 379122394Sharti 380122394Sharti case LEAF_begemotSnmpdDebugSnmpTrace: 381122394Sharti value->v.uint32 = snmp_trace; 382122394Sharti break; 383122394Sharti 384122394Sharti case LEAF_begemotSnmpdDebugSyslogPri: 385122394Sharti value->v.integer = debug.logpri; 386122394Sharti break; 387122394Sharti } 388122394Sharti return (SNMP_ERR_NOERROR); 389122394Sharti 390122394Sharti case SNMP_OP_SET: 391122394Sharti switch (which) { 392122394Sharti 393122394Sharti case LEAF_begemotSnmpdDebugDumpPdus: 394122394Sharti if (!TRUTH_OK(value->v.integer)) 395122394Sharti return (SNMP_ERR_WRONG_VALUE); 396122394Sharti ctx->scratch->int1 = debug.dump_pdus; 397122394Sharti debug.dump_pdus = TRUTH_GET(value->v.integer); 398122394Sharti return (SNMP_ERR_NOERROR); 399122394Sharti 400122394Sharti case LEAF_begemotSnmpdDebugSnmpTrace: 401122394Sharti ctx->scratch->int1 = snmp_trace; 402122394Sharti snmp_trace = value->v.uint32; 403122394Sharti return (SNMP_ERR_NOERROR); 404122394Sharti 405122394Sharti case LEAF_begemotSnmpdDebugSyslogPri: 406122394Sharti if (value->v.integer < 0 || value->v.integer > 8) 407122394Sharti return (SNMP_ERR_WRONG_VALUE); 408122394Sharti ctx->scratch->int1 = debug.logpri; 409122394Sharti debug.logpri = (u_int)value->v.integer; 410122394Sharti return (SNMP_ERR_NOERROR); 411122394Sharti } 412122394Sharti return (SNMP_ERR_NO_CREATION); 413122394Sharti 414122394Sharti case SNMP_OP_ROLLBACK: 415122394Sharti switch (which) { 416122394Sharti 417122394Sharti case LEAF_begemotSnmpdDebugDumpPdus: 418122394Sharti debug.dump_pdus = ctx->scratch->int1; 419122394Sharti return (SNMP_ERR_NOERROR); 420122394Sharti 421122394Sharti case LEAF_begemotSnmpdDebugSnmpTrace: 422122394Sharti snmp_trace = ctx->scratch->int1; 423122394Sharti return (SNMP_ERR_NOERROR); 424122394Sharti 425122394Sharti case LEAF_begemotSnmpdDebugSyslogPri: 426122394Sharti debug.logpri = ctx->scratch->int1; 427122394Sharti return (SNMP_ERR_NOERROR); 428122394Sharti } 429122394Sharti abort(); 430122394Sharti 431122394Sharti case SNMP_OP_COMMIT: 432122394Sharti switch (which) { 433122394Sharti 434122394Sharti case LEAF_begemotSnmpdDebugDumpPdus: 435122394Sharti case LEAF_begemotSnmpdDebugSnmpTrace: 436122394Sharti return (SNMP_ERR_NOERROR); 437122394Sharti 438122394Sharti case LEAF_begemotSnmpdDebugSyslogPri: 439122394Sharti if (debug.logpri == 0) 440122394Sharti setlogmask(0); 441122394Sharti else 442122394Sharti setlogmask(LOG_UPTO(debug.logpri - 1)); 443122394Sharti return (SNMP_ERR_NOERROR); 444122394Sharti } 445122394Sharti abort(); 446122394Sharti } 447122394Sharti abort(); 448122394Sharti} 449122394Sharti 450122394Sharti/************************************************************* 451122394Sharti * 452122394Sharti * OR Table 453122394Sharti */ 454122394Shartiint 455122394Shartiop_or_table(struct snmp_context *ctx __unused, struct snmp_value *value, 456122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 457122394Sharti{ 458122394Sharti struct objres *objres; 459122394Sharti 460122394Sharti switch (op) { 461122394Sharti 462122394Sharti case SNMP_OP_GETNEXT: 463122394Sharti if ((objres = NEXT_OBJECT_INT(&objres_list, &value->var, sub)) 464122394Sharti == NULL) 465122394Sharti return (SNMP_ERR_NOSUCHNAME); 466122394Sharti value->var.subs[sub] = objres->index; 467122394Sharti value->var.len = sub + 1; 468122394Sharti break; 469122394Sharti 470122394Sharti case SNMP_OP_GET: 471122394Sharti if ((objres = FIND_OBJECT_INT(&objres_list, &value->var, sub)) 472122394Sharti == NULL) 473122394Sharti return (SNMP_ERR_NOSUCHNAME); 474122394Sharti break; 475122394Sharti 476122394Sharti case SNMP_OP_SET: 477122394Sharti if ((objres = FIND_OBJECT_INT(&objres_list, &value->var, sub)) 478122394Sharti == NULL) 479122394Sharti return (SNMP_ERR_NO_CREATION); 480122394Sharti return (SNMP_ERR_NOT_WRITEABLE); 481122394Sharti 482122394Sharti case SNMP_OP_ROLLBACK: 483122394Sharti case SNMP_OP_COMMIT: 484122394Sharti default: 485122394Sharti abort(); 486122394Sharti } 487122394Sharti 488122394Sharti /* 489122394Sharti * Come here for GET, GETNEXT. 490122394Sharti */ 491122394Sharti switch (value->var.subs[sub - 1]) { 492122394Sharti 493122394Sharti case LEAF_sysORID: 494122394Sharti value->v.oid = objres->oid; 495122394Sharti break; 496122394Sharti 497122394Sharti case LEAF_sysORDescr: 498122394Sharti return (string_get(value, objres->descr, -1)); 499122394Sharti 500122394Sharti case LEAF_sysORUpTime: 501122394Sharti value->v.uint32 = objres->uptime; 502122394Sharti break; 503122394Sharti } 504122394Sharti return (SNMP_ERR_NOERROR); 505122394Sharti} 506122394Sharti 507122394Sharti/************************************************************* 508122394Sharti * 509122394Sharti * mib-2 snmp 510122394Sharti */ 511122394Shartiint 512122394Shartiop_snmp(struct snmp_context *ctx, struct snmp_value *value, 513122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 514122394Sharti{ 515122394Sharti switch (op) { 516122394Sharti 517122394Sharti case SNMP_OP_GETNEXT: 518122394Sharti abort(); 519122394Sharti 520122394Sharti case SNMP_OP_GET: 521122394Sharti switch (value->var.subs[sub - 1]) { 522122394Sharti 523122394Sharti case LEAF_snmpInPkts: 524122394Sharti value->v.uint32 = snmpd_stats.inPkts; 525122394Sharti break; 526122394Sharti 527122394Sharti case LEAF_snmpInBadVersions: 528122394Sharti value->v.uint32 = snmpd_stats.inBadVersions; 529122394Sharti break; 530122394Sharti 531122394Sharti case LEAF_snmpInBadCommunityNames: 532122394Sharti value->v.uint32 = snmpd_stats.inBadCommunityNames; 533122394Sharti break; 534122394Sharti 535122394Sharti case LEAF_snmpInBadCommunityUses: 536122394Sharti value->v.uint32 = snmpd_stats.inBadCommunityUses; 537122394Sharti break; 538122394Sharti 539122394Sharti case LEAF_snmpInASNParseErrs: 540122394Sharti value->v.uint32 = snmpd_stats.inASNParseErrs; 541122394Sharti break; 542122394Sharti 543122394Sharti case LEAF_snmpEnableAuthenTraps: 544122394Sharti value->v.integer = TRUTH_MK(snmpd.auth_traps); 545122394Sharti break; 546122394Sharti 547122394Sharti case LEAF_snmpSilentDrops: 548122394Sharti value->v.uint32 = snmpd_stats.silentDrops; 549122394Sharti break; 550122394Sharti 551122394Sharti case LEAF_snmpProxyDrops: 552122394Sharti value->v.uint32 = snmpd_stats.proxyDrops; 553122394Sharti break; 554122394Sharti 555122394Sharti default: 556122394Sharti return (SNMP_ERR_NOSUCHNAME); 557122394Sharti 558122394Sharti } 559122394Sharti return (SNMP_ERR_NOERROR); 560122394Sharti 561122394Sharti case SNMP_OP_SET: 562122394Sharti switch (value->var.subs[sub - 1]) { 563122394Sharti case LEAF_snmpEnableAuthenTraps: 564122394Sharti if (!TRUTH_OK(value->v.integer)) 565122394Sharti return (SNMP_ERR_WRONG_VALUE); 566122394Sharti ctx->scratch->int1 = value->v.integer; 567122394Sharti snmpd.auth_traps = TRUTH_GET(value->v.integer); 568122394Sharti return (SNMP_ERR_NOERROR); 569122394Sharti } 570122394Sharti abort(); 571122394Sharti 572122394Sharti case SNMP_OP_ROLLBACK: 573122394Sharti switch (value->var.subs[sub - 1]) { 574122394Sharti case LEAF_snmpEnableAuthenTraps: 575122394Sharti snmpd.auth_traps = ctx->scratch->int1; 576122394Sharti return (SNMP_ERR_NOERROR); 577122394Sharti } 578122394Sharti abort(); 579122394Sharti 580122394Sharti case SNMP_OP_COMMIT: 581122394Sharti switch (value->var.subs[sub - 1]) { 582122394Sharti case LEAF_snmpEnableAuthenTraps: 583122394Sharti return (SNMP_ERR_NOERROR); 584122394Sharti } 585122394Sharti abort(); 586122394Sharti } 587122394Sharti abort(); 588122394Sharti} 589122394Sharti 590122394Sharti/************************************************************* 591122394Sharti * 592122394Sharti * SNMPd statistics group 593122394Sharti */ 594122394Shartiint 595122394Shartiop_snmpd_stats(struct snmp_context *ctx __unused, struct snmp_value *value, 596122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 597122394Sharti{ 598122394Sharti switch (op) { 599122394Sharti 600122394Sharti case SNMP_OP_GET: 601122394Sharti switch (value->var.subs[sub - 1]) { 602122394Sharti 603122394Sharti case LEAF_begemotSnmpdStatsNoRxBufs: 604122394Sharti value->v.uint32 = snmpd_stats.noRxbuf; 605122394Sharti break; 606122394Sharti 607122394Sharti case LEAF_begemotSnmpdStatsNoTxBufs: 608122394Sharti value->v.uint32 = snmpd_stats.noTxbuf; 609122394Sharti break; 610122394Sharti 611122394Sharti case LEAF_begemotSnmpdStatsInTooLongPkts: 612122394Sharti value->v.uint32 = snmpd_stats.inTooLong; 613122394Sharti break; 614122394Sharti 615122394Sharti case LEAF_begemotSnmpdStatsInBadPduTypes: 616122394Sharti value->v.uint32 = snmpd_stats.inBadPduTypes; 617122394Sharti break; 618122394Sharti 619122394Sharti default: 620122394Sharti return (SNMP_ERR_NOSUCHNAME); 621122394Sharti } 622122394Sharti return (SNMP_ERR_NOERROR); 623122394Sharti 624122394Sharti case SNMP_OP_SET: 625122394Sharti case SNMP_OP_ROLLBACK: 626122394Sharti case SNMP_OP_COMMIT: 627122394Sharti case SNMP_OP_GETNEXT: 628122394Sharti abort(); 629122394Sharti } 630122394Sharti abort(); 631122394Sharti} 632122394Sharti 633122394Sharti/* 634122394Sharti * SNMPd configuration scalars 635122394Sharti */ 636122394Shartiint 637122394Shartiop_snmpd_config(struct snmp_context *ctx, struct snmp_value *value, 638122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 639122394Sharti{ 640122394Sharti asn_subid_t which = value->var.subs[sub - 1]; 641122394Sharti 642122394Sharti switch (op) { 643122394Sharti 644122394Sharti case SNMP_OP_GETNEXT: 645122394Sharti abort(); 646122394Sharti 647122394Sharti case SNMP_OP_GET: 648122394Sharti switch (which) { 649122394Sharti 650122394Sharti case LEAF_begemotSnmpdTransmitBuffer: 651122394Sharti value->v.integer = snmpd.txbuf; 652122394Sharti break; 653122394Sharti case LEAF_begemotSnmpdReceiveBuffer: 654122394Sharti value->v.integer = snmpd.rxbuf; 655122394Sharti break; 656122394Sharti case LEAF_begemotSnmpdCommunityDisable: 657122394Sharti value->v.integer = TRUTH_MK(snmpd.comm_dis); 658122394Sharti break; 659122394Sharti case LEAF_begemotSnmpdTrap1Addr: 660122394Sharti return (ip_get(value, snmpd.trap1addr)); 661124861Sharti case LEAF_begemotSnmpdVersionEnable: 662124861Sharti value->v.uint32 = snmpd.version_enable; 663124861Sharti break; 664122394Sharti default: 665122394Sharti return (SNMP_ERR_NOSUCHNAME); 666122394Sharti } 667122394Sharti return (SNMP_ERR_NOERROR); 668122394Sharti 669122394Sharti case SNMP_OP_SET: 670122394Sharti switch (which) { 671122394Sharti 672122394Sharti case LEAF_begemotSnmpdTransmitBuffer: 673122394Sharti ctx->scratch->int1 = snmpd.txbuf; 674122394Sharti if (value->v.integer < 484 || 675122394Sharti value->v.integer > 65535) 676122394Sharti return (SNMP_ERR_WRONG_VALUE); 677122394Sharti snmpd.txbuf = value->v.integer; 678122394Sharti return (SNMP_ERR_NOERROR); 679122394Sharti 680122394Sharti case LEAF_begemotSnmpdReceiveBuffer: 681122394Sharti ctx->scratch->int1 = snmpd.rxbuf; 682122394Sharti if (value->v.integer < 484 || 683122394Sharti value->v.integer > 65535) 684122394Sharti return (SNMP_ERR_WRONG_VALUE); 685122394Sharti snmpd.rxbuf = value->v.integer; 686122394Sharti return (SNMP_ERR_NOERROR); 687122394Sharti 688122394Sharti case LEAF_begemotSnmpdCommunityDisable: 689122394Sharti ctx->scratch->int1 = snmpd.comm_dis; 690122394Sharti if (!TRUTH_OK(value->v.integer)) 691122394Sharti return (SNMP_ERR_WRONG_VALUE); 692122394Sharti if (TRUTH_GET(value->v.integer)) { 693122394Sharti snmpd.comm_dis = 1; 694122394Sharti } else { 695122394Sharti if (snmpd.comm_dis) 696122394Sharti return (SNMP_ERR_WRONG_VALUE); 697122394Sharti } 698122394Sharti return (SNMP_ERR_NOERROR); 699122394Sharti 700122394Sharti case LEAF_begemotSnmpdTrap1Addr: 701122394Sharti return (ip_save(value, ctx, snmpd.trap1addr)); 702124861Sharti 703124861Sharti case LEAF_begemotSnmpdVersionEnable: 704124861Sharti if (community != COMM_INITIALIZE) 705124861Sharti return (SNMP_ERR_NOT_WRITEABLE); 706124861Sharti ctx->scratch->int1 = snmpd.version_enable; 707124861Sharti if (value->v.uint32 == 0 || 708124861Sharti (value->v.uint32 & ~VERS_ENABLE_ALL)) 709124861Sharti return (SNMP_ERR_WRONG_VALUE); 710124861Sharti snmpd.version_enable = value->v.uint32; 711124861Sharti return (SNMP_ERR_NOERROR); 712122394Sharti } 713122394Sharti abort(); 714122394Sharti 715122394Sharti case SNMP_OP_ROLLBACK: 716122394Sharti switch (which) { 717122394Sharti 718122394Sharti case LEAF_begemotSnmpdTransmitBuffer: 719122394Sharti snmpd.rxbuf = ctx->scratch->int1; 720122394Sharti return (SNMP_ERR_NOERROR); 721122394Sharti case LEAF_begemotSnmpdReceiveBuffer: 722122394Sharti snmpd.txbuf = ctx->scratch->int1; 723122394Sharti return (SNMP_ERR_NOERROR); 724122394Sharti case LEAF_begemotSnmpdCommunityDisable: 725122394Sharti snmpd.comm_dis = ctx->scratch->int1; 726122394Sharti return (SNMP_ERR_NOERROR); 727122394Sharti case LEAF_begemotSnmpdTrap1Addr: 728122394Sharti ip_rollback(ctx, snmpd.trap1addr); 729122394Sharti return (SNMP_ERR_NOERROR); 730124861Sharti case LEAF_begemotSnmpdVersionEnable: 731124861Sharti snmpd.version_enable = ctx->scratch->int1; 732124861Sharti return (SNMP_ERR_NOERROR); 733122394Sharti } 734122394Sharti abort(); 735122394Sharti 736122394Sharti case SNMP_OP_COMMIT: 737122394Sharti switch (which) { 738122394Sharti 739122394Sharti case LEAF_begemotSnmpdTransmitBuffer: 740122394Sharti case LEAF_begemotSnmpdReceiveBuffer: 741122394Sharti case LEAF_begemotSnmpdCommunityDisable: 742122394Sharti return (SNMP_ERR_NOERROR); 743122394Sharti case LEAF_begemotSnmpdTrap1Addr: 744122394Sharti ip_commit(ctx); 745122394Sharti return (SNMP_ERR_NOERROR); 746124861Sharti case LEAF_begemotSnmpdVersionEnable: 747124861Sharti return (SNMP_ERR_NOERROR); 748122394Sharti } 749122394Sharti abort(); 750122394Sharti } 751122394Sharti abort(); 752122394Sharti} 753122394Sharti 754122394Sharti/* 755122394Sharti * The community table 756122394Sharti */ 757122394Shartiint 758122394Shartiop_community(struct snmp_context *ctx, struct snmp_value *value, 759122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 760122394Sharti{ 761122394Sharti asn_subid_t which = value->var.subs[sub - 1]; 762122394Sharti struct community *c; 763122394Sharti 764122394Sharti switch (op) { 765122394Sharti 766122394Sharti case SNMP_OP_GETNEXT: 767122394Sharti if ((community != COMM_INITIALIZE && snmpd.comm_dis) || 768122394Sharti (c = NEXT_OBJECT_OID(&community_list, &value->var, sub)) == NULL) 769122394Sharti return (SNMP_ERR_NOSUCHNAME); 770122394Sharti index_append(&value->var, sub, &c->index); 771122394Sharti break; 772122394Sharti 773122394Sharti case SNMP_OP_GET: 774122394Sharti if ((community != COMM_INITIALIZE && snmpd.comm_dis) || 775122394Sharti (c = FIND_OBJECT_OID(&community_list, &value->var, sub)) == NULL) 776122394Sharti return (SNMP_ERR_NOSUCHNAME); 777122394Sharti break; 778122394Sharti 779122394Sharti case SNMP_OP_SET: 780122394Sharti if ((community != COMM_INITIALIZE && snmpd.comm_dis) || 781122394Sharti (c = FIND_OBJECT_OID(&community_list, &value->var, sub)) == NULL) 782122394Sharti return (SNMP_ERR_NO_CREATION); 783122394Sharti if (which != LEAF_begemotSnmpdCommunityString) 784122394Sharti return (SNMP_ERR_NOT_WRITEABLE); 785122394Sharti return (string_save(value, ctx, -1, &c->string)); 786122394Sharti 787122394Sharti case SNMP_OP_ROLLBACK: 788122394Sharti if (which == LEAF_begemotSnmpdCommunityString) { 789122394Sharti if ((c = FIND_OBJECT_OID(&community_list, &value->var, 790122394Sharti sub)) == NULL) 791122394Sharti string_free(ctx); 792122394Sharti else 793122394Sharti string_rollback(ctx, &c->string); 794122394Sharti return (SNMP_ERR_NOERROR); 795122394Sharti } 796122394Sharti abort(); 797122394Sharti 798122394Sharti case SNMP_OP_COMMIT: 799122394Sharti if (which == LEAF_begemotSnmpdCommunityString) { 800122394Sharti if ((c = FIND_OBJECT_OID(&community_list, &value->var, 801122394Sharti sub)) == NULL) 802122394Sharti string_free(ctx); 803122394Sharti else 804122394Sharti string_commit(ctx); 805122394Sharti return (SNMP_ERR_NOERROR); 806122394Sharti } 807122394Sharti abort(); 808122394Sharti 809122394Sharti default: 810122394Sharti abort(); 811122394Sharti } 812122394Sharti 813122394Sharti switch (which) { 814122394Sharti 815122394Sharti case LEAF_begemotSnmpdCommunityString: 816122394Sharti return (string_get(value, c->string, -1)); 817122394Sharti 818122394Sharti case LEAF_begemotSnmpdCommunityDescr: 819122394Sharti return (string_get(value, c->descr, -1)); 820122394Sharti } 821122394Sharti abort(); 822122394Sharti} 823122394Sharti 824122394Sharti/* 825122394Sharti * Module table. 826122394Sharti */ 827122394Shartistruct module_dep { 828122394Sharti struct snmp_dependency dep; 829122394Sharti u_char section[LM_SECTION_MAX + 1]; 830122394Sharti u_char *path; 831122394Sharti struct lmodule *m; 832122394Sharti}; 833122394Sharti 834122394Shartistatic int 835122394Shartidep_modules(struct snmp_context *ctx, struct snmp_dependency *dep, 836122394Sharti enum snmp_depop op) 837122394Sharti{ 838122394Sharti struct module_dep *mdep = (struct module_dep *)(void *)dep; 839122394Sharti 840122394Sharti switch (op) { 841122394Sharti 842122394Sharti case SNMP_DEPOP_COMMIT: 843122394Sharti if (mdep->path == NULL) { 844122394Sharti /* unload - find the module */ 845122394Sharti TAILQ_FOREACH(mdep->m, &lmodules, link) 846128237Sharti if (strcmp(mdep->m->section, 847128237Sharti mdep->section) == 0) 848122394Sharti break; 849122394Sharti if (mdep->m == NULL) 850128237Sharti /* no such module - that's ok */ 851122394Sharti return (SNMP_ERR_NOERROR); 852128237Sharti 853128237Sharti /* handle unloading in the finalizer */ 854122394Sharti return (SNMP_ERR_NOERROR); 855122394Sharti } 856122394Sharti /* load */ 857128237Sharti if ((mdep->m = lm_load(mdep->path, mdep->section)) == NULL) { 858128237Sharti /* could not load */ 859122394Sharti return (SNMP_ERR_RES_UNAVAIL); 860122394Sharti } 861128237Sharti /* start in finalizer */ 862122394Sharti return (SNMP_ERR_NOERROR); 863122394Sharti 864122394Sharti case SNMP_DEPOP_ROLLBACK: 865122394Sharti if (mdep->path == NULL) { 866128237Sharti /* rollback unload - the finalizer takes care */ 867122394Sharti return (SNMP_ERR_NOERROR); 868122394Sharti } 869122394Sharti /* rollback load */ 870122394Sharti lm_unload(mdep->m); 871122394Sharti return (SNMP_ERR_NOERROR); 872128237Sharti 873128237Sharti case SNMP_DEPOP_FINISH: 874128237Sharti if (mdep->path == NULL) { 875128237Sharti if (mdep->m != NULL && ctx->code == SNMP_RET_OK) 876128237Sharti lm_unload(mdep->m); 877128237Sharti } else { 878128237Sharti if (mdep->m != NULL && ctx->code == SNMP_RET_OK && 879128237Sharti community != COMM_INITIALIZE) 880128237Sharti lm_start(mdep->m); 881128237Sharti free(mdep->path); 882128237Sharti } 883128237Sharti return (SNMP_ERR_NOERROR); 884122394Sharti } 885122394Sharti abort(); 886122394Sharti} 887122394Sharti 888122394Shartiint 889122394Shartiop_modules(struct snmp_context *ctx, struct snmp_value *value, 890122394Sharti u_int sub, u_int iidx, enum snmp_op op) 891122394Sharti{ 892122394Sharti asn_subid_t which = value->var.subs[sub - 1]; 893122394Sharti struct lmodule *m; 894122394Sharti u_char *section, *ptr; 895122394Sharti size_t seclen; 896122394Sharti struct module_dep *mdep; 897122394Sharti struct asn_oid idx; 898122394Sharti 899122394Sharti switch (op) { 900122394Sharti 901122394Sharti case SNMP_OP_GETNEXT: 902122394Sharti if ((m = NEXT_OBJECT_OID(&lmodules, &value->var, sub)) == NULL) 903122394Sharti return (SNMP_ERR_NOSUCHNAME); 904122394Sharti index_append(&value->var, sub, &m->index); 905122394Sharti break; 906122394Sharti 907122394Sharti case SNMP_OP_GET: 908122394Sharti if ((m = FIND_OBJECT_OID(&lmodules, &value->var, sub)) == NULL) 909122394Sharti return (SNMP_ERR_NOSUCHNAME); 910122394Sharti break; 911122394Sharti 912122394Sharti case SNMP_OP_SET: 913122394Sharti m = FIND_OBJECT_OID(&lmodules, &value->var, sub); 914122394Sharti if (which != LEAF_begemotSnmpdModulePath) { 915122394Sharti if (m == NULL) 916122394Sharti return (SNMP_ERR_NO_CREATION); 917122394Sharti return (SNMP_ERR_NOT_WRITEABLE); 918122394Sharti } 919122394Sharti 920122394Sharti /* the errors in the next few statements can only happen when 921122394Sharti * m is NULL, hence the NO_CREATION error. */ 922122394Sharti if (index_decode(&value->var, sub, iidx, 923122394Sharti §ion, &seclen)) 924122394Sharti return (SNMP_ERR_NO_CREATION); 925122394Sharti 926122394Sharti /* check the section name */ 927122394Sharti if (seclen > LM_SECTION_MAX || seclen == 0) { 928122394Sharti free(section); 929122394Sharti return (SNMP_ERR_NO_CREATION); 930122394Sharti } 931122394Sharti for (ptr = section; ptr < section + seclen; ptr++) 932122394Sharti if (!isascii(*ptr) || !isalnum(*ptr)) { 933122394Sharti free(section); 934122394Sharti return (SNMP_ERR_NO_CREATION); 935122394Sharti } 936122394Sharti if (!isalpha(section[0])) { 937122394Sharti free(section); 938122394Sharti return (SNMP_ERR_NO_CREATION); 939122394Sharti } 940122394Sharti 941122394Sharti /* check the path */ 942122394Sharti for (ptr = value->v.octetstring.octets; 943122394Sharti ptr < value->v.octetstring.octets + value->v.octetstring.len; 944122394Sharti ptr++) { 945122394Sharti if (*ptr == '\0') { 946122394Sharti free(section); 947122394Sharti return (SNMP_ERR_WRONG_VALUE); 948122394Sharti } 949122394Sharti } 950122394Sharti 951122394Sharti if (m == NULL) { 952122394Sharti if (value->v.octetstring.len == 0) { 953122394Sharti free(section); 954122394Sharti return (SNMP_ERR_INCONS_VALUE); 955122394Sharti } 956122394Sharti } else { 957122394Sharti if (value->v.octetstring.len != 0) { 958122394Sharti free(section); 959122394Sharti return (SNMP_ERR_INCONS_VALUE); 960122394Sharti } 961122394Sharti } 962122394Sharti 963122394Sharti asn_slice_oid(&idx, &value->var, sub, value->var.len); 964122394Sharti 965122394Sharti /* so far, so good */ 966122394Sharti mdep = (struct module_dep *)(void *)snmp_dep_lookup(ctx, 967122394Sharti &oid_begemotSnmpdModuleTable, &idx, 968122394Sharti sizeof(*mdep), dep_modules); 969122394Sharti if (mdep == NULL) { 970122394Sharti free(section); 971122394Sharti return (SNMP_ERR_RES_UNAVAIL); 972122394Sharti } 973122394Sharti 974122394Sharti if (mdep->section[0] != '\0') { 975122394Sharti /* two writes to the same entry - bad */ 976122394Sharti free(section); 977122394Sharti return (SNMP_ERR_INCONS_VALUE); 978122394Sharti } 979122394Sharti 980122394Sharti strncpy(mdep->section, section, seclen); 981122394Sharti mdep->section[seclen] = '\0'; 982122394Sharti free(section); 983122394Sharti 984122394Sharti if (value->v.octetstring.len == 0) 985122394Sharti mdep->path = NULL; 986122394Sharti else { 987122394Sharti if ((mdep->path = malloc(value->v.octetstring.len + 1)) == NULL) 988122394Sharti return (SNMP_ERR_RES_UNAVAIL); 989122394Sharti strncpy(mdep->path, value->v.octetstring.octets, 990122394Sharti value->v.octetstring.len); 991122394Sharti mdep->path[value->v.octetstring.len] = '\0'; 992122394Sharti } 993122394Sharti ctx->scratch->ptr1 = mdep; 994122394Sharti return (SNMP_ERR_NOERROR); 995122394Sharti 996122394Sharti case SNMP_OP_ROLLBACK: 997122394Sharti case SNMP_OP_COMMIT: 998122394Sharti return (SNMP_ERR_NOERROR); 999122394Sharti 1000122394Sharti default: 1001122394Sharti abort(); 1002122394Sharti } 1003122394Sharti 1004122394Sharti switch (which) { 1005122394Sharti 1006122394Sharti case LEAF_begemotSnmpdModulePath: 1007122394Sharti return (string_get(value, m->path, -1)); 1008122394Sharti 1009122394Sharti case LEAF_begemotSnmpdModuleComment: 1010122394Sharti return (string_get(value, m->config->comment, -1)); 1011122394Sharti } 1012122394Sharti abort(); 1013122394Sharti} 1014122394Sharti 1015122394Shartiint 1016122394Shartiop_snmp_set(struct snmp_context *ctx __unused, struct snmp_value *value, 1017122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 1018122394Sharti{ 1019122394Sharti switch (op) { 1020122394Sharti 1021122394Sharti case SNMP_OP_GETNEXT: 1022122394Sharti abort(); 1023122394Sharti 1024122394Sharti case SNMP_OP_GET: 1025122394Sharti switch (value->var.subs[sub - 1]) { 1026122394Sharti 1027122394Sharti case LEAF_snmpSetSerialNo: 1028122394Sharti value->v.integer = snmp_serial_no; 1029122394Sharti break; 1030122394Sharti 1031122394Sharti default: 1032122394Sharti abort(); 1033122394Sharti } 1034122394Sharti return (SNMP_ERR_NOERROR); 1035122394Sharti 1036122394Sharti case SNMP_OP_SET: 1037122394Sharti switch (value->var.subs[sub - 1]) { 1038122394Sharti 1039122394Sharti case LEAF_snmpSetSerialNo: 1040122394Sharti if (value->v.integer != snmp_serial_no) 1041122394Sharti return (SNMP_ERR_INCONS_VALUE); 1042122394Sharti break; 1043122394Sharti 1044122394Sharti default: 1045122394Sharti abort(); 1046122394Sharti } 1047122394Sharti return (SNMP_ERR_NOERROR); 1048122394Sharti 1049122394Sharti case SNMP_OP_ROLLBACK: 1050122394Sharti return (SNMP_ERR_NOERROR); 1051122394Sharti 1052122394Sharti case SNMP_OP_COMMIT: 1053122394Sharti if (snmp_serial_no++ == 2147483647) 1054122394Sharti snmp_serial_no = 0; 1055122394Sharti return (SNMP_ERR_NOERROR); 1056122394Sharti } 1057122394Sharti abort(); 1058122394Sharti} 1059124861Sharti 1060124861Sharti/* 1061216294Ssyrinx * SNMP Engine 1062216294Ssyrinx */ 1063216294Ssyrinxint 1064216294Ssyrinxop_snmp_engine(struct snmp_context *ctx __unused, struct snmp_value *value, 1065216294Ssyrinx u_int sub, u_int iidx __unused, enum snmp_op op) 1066216294Ssyrinx{ 1067216294Ssyrinx asn_subid_t which = value->var.subs[sub - 1]; 1068216294Ssyrinx 1069216294Ssyrinx switch (op) { 1070216294Ssyrinx case SNMP_OP_GETNEXT: 1071216294Ssyrinx abort(); 1072216294Ssyrinx 1073216294Ssyrinx case SNMP_OP_GET: 1074216294Ssyrinx break; 1075216294Ssyrinx 1076216294Ssyrinx case SNMP_OP_SET: 1077216294Ssyrinx if (community != COMM_INITIALIZE) 1078216294Ssyrinx return (SNMP_ERR_NOT_WRITEABLE); 1079216294Ssyrinx switch (which) { 1080216294Ssyrinx case LEAF_snmpEngineID: 1081216294Ssyrinx if (value->v.octetstring.len > SNMP_ENGINE_ID_SIZ) 1082216294Ssyrinx return (SNMP_ERR_WRONG_VALUE); 1083216294Ssyrinx ctx->scratch->ptr1 = malloc(snmpd_engine.engine_len); 1084216294Ssyrinx if (ctx->scratch->ptr1 == NULL) 1085216294Ssyrinx return (SNMP_ERR_GENERR); 1086216294Ssyrinx memcpy(ctx->scratch->ptr1, snmpd_engine.engine_id, 1087216294Ssyrinx snmpd_engine.engine_len); 1088216294Ssyrinx ctx->scratch->int1 = snmpd_engine.engine_len; 1089216294Ssyrinx snmpd_engine.engine_len = value->v.octetstring.len; 1090216294Ssyrinx memcpy(snmpd_engine.engine_id, 1091216294Ssyrinx value->v.octetstring.octets, 1092216294Ssyrinx value->v.octetstring.len); 1093216294Ssyrinx break; 1094216294Ssyrinx 1095216294Ssyrinx case LEAF_snmpEngineMaxMessageSize: 1096216294Ssyrinx ctx->scratch->int1 = snmpd_engine.max_msg_size; 1097216294Ssyrinx snmpd_engine.max_msg_size = value->v.integer; 1098216294Ssyrinx break; 1099216294Ssyrinx 1100216294Ssyrinx default: 1101216294Ssyrinx return (SNMP_ERR_NOT_WRITEABLE); 1102216294Ssyrinx } 1103216294Ssyrinx return (SNMP_ERR_NOERROR); 1104216294Ssyrinx 1105216294Ssyrinx case SNMP_OP_ROLLBACK: 1106216294Ssyrinx switch (which) { 1107216294Ssyrinx case LEAF_snmpEngineID: 1108216294Ssyrinx snmpd_engine.engine_len = ctx->scratch->int1; 1109216294Ssyrinx memcpy(snmpd_engine.engine_id, ctx->scratch->ptr1, 1110216294Ssyrinx snmpd_engine.engine_len); 1111216294Ssyrinx free(ctx->scratch->ptr1); 1112216294Ssyrinx break; 1113216294Ssyrinx 1114216294Ssyrinx case LEAF_snmpEngineMaxMessageSize: 1115216294Ssyrinx snmpd_engine.max_msg_size = ctx->scratch->int1; 1116216294Ssyrinx break; 1117216294Ssyrinx 1118216294Ssyrinx default: 1119216294Ssyrinx abort(); 1120216294Ssyrinx } 1121216294Ssyrinx return (SNMP_ERR_NOERROR); 1122216294Ssyrinx 1123216294Ssyrinx case SNMP_OP_COMMIT: 1124216294Ssyrinx if (which == LEAF_snmpEngineID) { 1125216294Ssyrinx if (set_snmpd_engine() < 0) { 1126216294Ssyrinx snmpd_engine.engine_len = ctx->scratch->int1; 1127216294Ssyrinx memcpy(snmpd_engine.engine_id, 1128216294Ssyrinx ctx->scratch->ptr1, ctx->scratch->int1); 1129216294Ssyrinx } 1130216294Ssyrinx free(ctx->scratch->ptr1); 1131216294Ssyrinx } 1132216294Ssyrinx return (SNMP_ERR_NOERROR); 1133216294Ssyrinx } 1134216294Ssyrinx 1135216294Ssyrinx 1136216294Ssyrinx switch (which) { 1137216294Ssyrinx case LEAF_snmpEngineID: 1138216294Ssyrinx return (string_get(value, snmpd_engine.engine_id, 1139216294Ssyrinx snmpd_engine.engine_len)); 1140216294Ssyrinx case LEAF_snmpEngineBoots: 1141216294Ssyrinx value->v.integer = snmpd_engine.engine_boots; 1142216294Ssyrinx break; 1143216294Ssyrinx case LEAF_snmpEngineTime: 1144216294Ssyrinx snmpd_engine.engine_time = (get_ticks() - start_tick) / 100ULL; 1145216294Ssyrinx value->v.integer = snmpd_engine.engine_time; 1146216294Ssyrinx break; 1147216294Ssyrinx case LEAF_snmpEngineMaxMessageSize: 1148216294Ssyrinx value->v.integer = snmpd_engine.max_msg_size; 1149216294Ssyrinx break; 1150216294Ssyrinx default: 1151216294Ssyrinx return (SNMP_ERR_NOSUCHNAME); 1152216294Ssyrinx } 1153216294Ssyrinx 1154216294Ssyrinx return (SNMP_ERR_NOERROR); 1155216294Ssyrinx} 1156216294Ssyrinx 1157216294Ssyrinx/* 1158124861Sharti * Transport table 1159124861Sharti */ 1160124861Shartiint 1161124861Shartiop_transport_table(struct snmp_context *ctx __unused, struct snmp_value *value, 1162124861Sharti u_int sub, u_int iidx, enum snmp_op op) 1163124861Sharti{ 1164124861Sharti asn_subid_t which = value->var.subs[sub - 1]; 1165124861Sharti struct transport *t; 1166124861Sharti u_char *tname, *ptr; 1167124861Sharti size_t tnamelen; 1168124861Sharti 1169124861Sharti switch (op) { 1170124861Sharti 1171124861Sharti case SNMP_OP_GETNEXT: 1172124861Sharti if ((t = NEXT_OBJECT_OID(&transport_list, &value->var, sub)) 1173124861Sharti == NULL) 1174124861Sharti return (SNMP_ERR_NOSUCHNAME); 1175124861Sharti index_append(&value->var, sub, &t->index); 1176124861Sharti break; 1177124861Sharti 1178124861Sharti case SNMP_OP_GET: 1179124861Sharti if ((t = FIND_OBJECT_OID(&transport_list, &value->var, sub)) 1180124861Sharti == NULL) 1181124861Sharti return (SNMP_ERR_NOSUCHNAME); 1182124861Sharti break; 1183124861Sharti 1184124861Sharti case SNMP_OP_SET: 1185124861Sharti t = FIND_OBJECT_OID(&transport_list, &value->var, sub); 1186124861Sharti if (which != LEAF_begemotSnmpdTransportStatus) { 1187124861Sharti if (t == NULL) 1188124861Sharti return (SNMP_ERR_NO_CREATION); 1189124861Sharti return (SNMP_ERR_NOT_WRITEABLE); 1190124861Sharti } 1191124861Sharti 1192124861Sharti /* the errors in the next few statements can only happen when 1193124861Sharti * t is NULL, hence the NO_CREATION error. */ 1194124861Sharti if (index_decode(&value->var, sub, iidx, 1195124861Sharti &tname, &tnamelen)) 1196124861Sharti return (SNMP_ERR_NO_CREATION); 1197124861Sharti 1198124861Sharti /* check the section name */ 1199124861Sharti if (tnamelen >= TRANS_NAMELEN || tnamelen == 0) { 1200124861Sharti free(tname); 1201124861Sharti return (SNMP_ERR_NO_CREATION); 1202124861Sharti } 1203124861Sharti for (ptr = tname; ptr < tname + tnamelen; ptr++) { 1204124861Sharti if (!isascii(*ptr) || !isalnum(*ptr)) { 1205124861Sharti free(tname); 1206124861Sharti return (SNMP_ERR_NO_CREATION); 1207124861Sharti } 1208124861Sharti } 1209124861Sharti 1210124861Sharti /* for now */ 1211124861Sharti return (SNMP_ERR_NOT_WRITEABLE); 1212124861Sharti 1213124861Sharti case SNMP_OP_ROLLBACK: 1214124861Sharti case SNMP_OP_COMMIT: 1215124861Sharti return (SNMP_ERR_NOERROR); 1216124861Sharti default: 1217124861Sharti abort(); 1218124861Sharti } 1219124861Sharti 1220124861Sharti switch (which) { 1221124861Sharti 1222124861Sharti case LEAF_begemotSnmpdTransportStatus: 1223124861Sharti value->v.integer = 1; 1224124861Sharti break; 1225124861Sharti 1226124861Sharti case LEAF_begemotSnmpdTransportOid: 1227124861Sharti memcpy(&value->v.oid, &t->vtab->id, sizeof(t->vtab->id)); 1228124861Sharti break; 1229124861Sharti } 1230124861Sharti return (SNMP_ERR_NOERROR); 1231124861Sharti} 1232