File: [local] / src / usr.sbin / snmpd / snmpd.h (download)
Revision 1.119, Tue Feb 6 15:36:11 2024 UTC (3 months, 3 weeks ago) by martijn
Branch: MAIN
CVS Tags: OPENBSD_7_5_BASE, OPENBSD_7_5 Changes since 1.118: +3 -3 lines
Let the config parser make use of the mib_string2oid().
If a descriptor is not found in the loaded MIB files it falls back to
the old smi_oid2string(), which then throws a deprecation warning. This
won't trigger for most cases in the default install, but the
UCD-DISKIO-MIB and dependencies aren't included (yet?) (which can be
fixed by manually including them via "mib directory") and there's a
couple of misspellings (e.g. mib_2 vs mib-2, and
usmStatsNotInTimeWindow vs usmStatsNotInTimeWindows).
Feedback and OK tb@
|
/* $OpenBSD: snmpd.h,v 1.119 2024/02/06 15:36:11 martijn Exp $ */
/*
* Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef SNMPD_H
#define SNMPD_H
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/tree.h>
#include <sys/types.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <ber.h>
#include <event.h>
#include <limits.h>
#include <imsg.h>
#include <stddef.h>
#include <stdint.h>
#include "mib.h"
#include "snmp.h"
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
/*
* common definitions for snmpd
*/
#define CONF_FILE "/etc/snmpd.conf"
#define SNMPD_BACKEND "/usr/libexec/snmpd"
#define SNMPD_USER "_snmpd"
#define SNMP_PORT "161"
#define SNMPTRAP_PORT "162"
#define AGENTX_MASTER_PATH "/var/agentx/master"
#define AGENTX_GROUP "_agentx"
#define SNMPD_MAXSTRLEN 484
#define SNMPD_MAXCOMMUNITYLEN SNMPD_MAXSTRLEN
#define SNMPD_MAXVARBIND 0x7fffffff
#define SNMPD_MAXVARBINDLEN 1210
#define SNMPD_MAXENGINEIDLEN 32
#define SNMPD_MAXUSERNAMELEN 32
#define SNMPD_MAXCONTEXNAMELEN 32
#define SNMP_USM_MAXDIGESTLEN 48
#define SNMP_USM_SALTLEN 8
#define SNMP_USM_KEYLEN 64
#define SNMP_CIPHER_KEYLEN 16
#define SMALL_READ_BUF_SIZE 1024
#define READ_BUF_SIZE 65535
#define RT_BUF_SIZE 16384
#define MAX_RTSOCK_BUF (2 * 1024 * 1024)
#define SNMP_ENGINEID_OLD 0x00
#define SNMP_ENGINEID_NEW 0x80 /* RFC3411 */
#define SNMP_ENGINEID_FMT_IPv4 1
#define SNMP_ENGINEID_FMT_IPv6 2
#define SNMP_ENGINEID_FMT_MAC 3
#define SNMP_ENGINEID_FMT_TEXT 4
#define SNMP_ENGINEID_FMT_OCT 5
#define SNMP_ENGINEID_FMT_HH 129
#define PEN_OPENBSD 30155
enum imsg_type {
IMSG_NONE,
IMSG_CTL_VERBOSE,
IMSG_CTL_PROCFD,
IMSG_TRAP_EXEC,
IMSG_AX_FD
};
struct imsgev {
struct imsgbuf ibuf;
void (*handler)(int, short, void *);
struct event ev;
struct privsep_proc *proc;
void *data;
short events;
const char *name;
};
#define IMSG_SIZE_CHECK(imsg, p) do { \
if (IMSG_DATA_SIZE(imsg) < sizeof(*p)) \
fatalx("bad length imsg received"); \
} while (0)
#define IMSG_DATA_SIZE(imsg) ((imsg)->hdr.len - IMSG_HEADER_SIZE)
enum privsep_procid {
PROC_PARENT, /* Parent process and application interface */
PROC_SNMPE, /* SNMP engine */
PROC_MAX
};
extern enum privsep_procid privsep_process;
struct privsep_pipes {
int *pp_pipes[PROC_MAX];
};
struct privsep {
struct privsep_pipes *ps_pipes[PROC_MAX];
struct privsep_pipes *ps_pp;
struct imsgev *ps_ievs[PROC_MAX];
const char *ps_title[PROC_MAX];
pid_t ps_pid[PROC_MAX];
struct passwd *ps_pw;
u_int ps_instances[PROC_MAX];
u_int ps_instance;
int ps_noaction;
/* Event and signal handlers */
struct event ps_evsigint;
struct event ps_evsigterm;
struct event ps_evsigchld;
struct event ps_evsighup;
struct event ps_evsigpipe;
struct event ps_evsigusr1;
void *ps_env;
};
struct privsep_proc {
const char *p_title;
enum privsep_procid p_id;
int (*p_cb)(int, struct privsep_proc *,
struct imsg *);
void (*p_init)(struct privsep *,
struct privsep_proc *);
void (*p_shutdown)(void);
const char *p_chroot;
struct privsep *p_ps;
struct passwd *p_pw;
};
struct privsep_fd {
enum privsep_procid pf_procid;
unsigned int pf_instance;
};
#define PROC_PARENT_SOCK_FILENO 3
#define PROC_MAX_INSTANCES 32
#if DEBUG
#define DPRINTF log_debug
#else
#define DPRINTF(x...) do {} while(0)
#endif
#define OID(...) (struct ber_oid){ { __VA_ARGS__ }, \
(sizeof((uint32_t []) { __VA_ARGS__ }) / sizeof(uint32_t)) }
/*
* daemon structures
*/
#define MSG_HAS_AUTH(m) (((m)->sm_flags & SNMP_MSGFLAG_AUTH) != 0)
#define MSG_HAS_PRIV(m) (((m)->sm_flags & SNMP_MSGFLAG_PRIV) != 0)
#define MSG_SECLEVEL(m) ((m)->sm_flags & SNMP_MSGFLAG_SECMASK)
#define MSG_REPORT(m) (((m)->sm_flags & SNMP_MSGFLAG_REPORT) != 0)
struct snmp_message {
int sm_sock;
struct sockaddr_storage sm_ss;
socklen_t sm_slen;
int sm_sock_tcp;
int sm_aflags;
enum snmp_pdutype sm_pdutype;
struct event sm_sockev;
char sm_host[HOST_NAME_MAX+1];
in_port_t sm_port;
struct sockaddr_storage sm_local_ss;
socklen_t sm_local_slen;
struct ber sm_ber;
struct ber_element *sm_req;
struct ber_element *sm_resp;
u_int8_t sm_data[READ_BUF_SIZE];
size_t sm_datalen;
uint32_t sm_transactionid;
u_int sm_version;
/* V1, V2c */
char sm_community[SNMPD_MAXCOMMUNITYLEN];
/* V3 */
long long sm_msgid;
long long sm_max_msg_size;
u_int8_t sm_flags;
long long sm_secmodel;
u_int32_t sm_engine_boots;
u_int32_t sm_engine_time;
uint8_t sm_ctxengineid[SNMPD_MAXENGINEIDLEN];
size_t sm_ctxengineid_len;
char sm_ctxname[SNMPD_MAXCONTEXNAMELEN+1];
/* USM */
char sm_username[SNMPD_MAXUSERNAMELEN+1];
struct usmuser *sm_user;
size_t sm_digest_offs;
char sm_salt[SNMP_USM_SALTLEN];
int sm_usmerr;
long long sm_request;
const char *sm_errstr;
long long sm_error;
#define sm_nonrepeaters sm_error
long long sm_errorindex;
#define sm_maxrepetitions sm_errorindex
struct ber_element *sm_pdu;
struct ber_element *sm_pduend;
struct ber_element *sm_varbind;
struct ber_element *sm_varbindresp;
RB_ENTRY(snmp_message) sm_entry;
};
RB_HEAD(snmp_messages, snmp_message);
extern struct snmp_messages snmp_messages;
/* Defined in SNMPv2-MIB.txt (RFC 3418) */
struct snmp_stats {
u_int32_t snmp_inpkts;
u_int32_t snmp_outpkts;
u_int32_t snmp_inbadversions;
u_int32_t snmp_inbadcommunitynames;
u_int32_t snmp_inbadcommunityuses;
u_int32_t snmp_inasnparseerrs;
u_int32_t snmp_intoobigs;
u_int32_t snmp_innosuchnames;
u_int32_t snmp_inbadvalues;
u_int32_t snmp_inreadonlys;
u_int32_t snmp_ingenerrs;
u_int32_t snmp_intotalreqvars;
u_int32_t snmp_intotalsetvars;
u_int32_t snmp_ingetrequests;
u_int32_t snmp_ingetnexts;
u_int32_t snmp_insetrequests;
u_int32_t snmp_ingetresponses;
u_int32_t snmp_intraps;
u_int32_t snmp_outtoobigs;
u_int32_t snmp_outnosuchnames;
u_int32_t snmp_outbadvalues;
u_int32_t snmp_outgenerrs;
u_int32_t snmp_outgetrequests;
u_int32_t snmp_outgetnexts;
u_int32_t snmp_outsetrequests;
u_int32_t snmp_outgetresponses;
u_int32_t snmp_outtraps;
int snmp_enableauthentraps;
u_int32_t snmp_silentdrops;
u_int32_t snmp_proxydrops;
/* USM stats (RFC 3414) */
u_int32_t snmp_usmbadseclevel;
u_int32_t snmp_usmtimewindow;
u_int32_t snmp_usmnosuchuser;
u_int32_t snmp_usmnosuchengine;
u_int32_t snmp_usmwrongdigest;
u_int32_t snmp_usmdecrypterr;
};
struct address {
struct sockaddr_storage ss;
in_port_t port;
int type;
int flags;
int fd;
struct event ev;
struct event evt;
TAILQ_ENTRY(address) entry;
};
TAILQ_HEAD(addresslist, address);
struct agentx_master {
int axm_fd;
struct sockaddr_un axm_sun;
uid_t axm_owner;
gid_t axm_group;
mode_t axm_mode;
struct event axm_ev;
TAILQ_ENTRY(agentx_master) axm_entry;
};
TAILQ_HEAD(axmasterlist, agentx_master);
#define ADDRESS_FLAG_READ 0x01
#define ADDRESS_FLAG_WRITE 0x02
#define ADDRESS_FLAG_NOTIFY 0x04
#define ADDRESS_FLAG_PERM \
(ADDRESS_FLAG_READ | ADDRESS_FLAG_WRITE | ADDRESS_FLAG_NOTIFY)
#define ADDRESS_FLAG_SNMPV1 0x10
#define ADDRESS_FLAG_SNMPV2 0x20
#define ADDRESS_FLAG_SNMPV3 0x40
#define ADDRESS_FLAG_MPS \
(ADDRESS_FLAG_SNMPV1 | ADDRESS_FLAG_SNMPV2 | ADDRESS_FLAG_SNMPV3)
struct trap_address {
struct sockaddr_storage ta_ss;
struct sockaddr_storage ta_sslocal;
int ta_version;
union {
char ta_community[SNMPD_MAXCOMMUNITYLEN];
struct {
char *ta_usmusername;
struct usmuser *ta_usmuser;
int ta_seclevel;
};
};
struct ber_oid ta_oid;
TAILQ_ENTRY(trap_address) entry;
};
TAILQ_HEAD(trap_addresslist, trap_address);
enum usmauth {
AUTH_NONE = 0,
AUTH_MD5, /* HMAC-MD5-96, RFC3414 */
AUTH_SHA1, /* HMAC-SHA-96, RFC3414 */
AUTH_SHA224, /* usmHMAC128SHA224AuthProtocol. RFC7860 */
AUTH_SHA256, /* usmHMAC192SHA256AuthProtocol. RFC7860 */
AUTH_SHA384, /* usmHMAC256SHA384AuthProtocol. RFC7860 */
AUTH_SHA512 /* usmHMAC384SHA512AuthProtocol. RFC7860 */
};
#define AUTH_DEFAULT AUTH_SHA1 /* Default digest */
enum usmpriv {
PRIV_NONE = 0,
PRIV_DES, /* CBC-DES, RFC3414 */
PRIV_AES /* CFB128-AES-128, RFC3826 */
};
#define PRIV_DEFAULT PRIV_AES /* Default cipher */
struct usmuser {
char *uu_name;
int uu_seclevel;
enum usmauth uu_auth;
char *uu_authkey;
unsigned uu_authkeylen;
enum usmpriv uu_priv;
char *uu_privkey;
unsigned long long uu_salt;
SLIST_ENTRY(usmuser) uu_next;
};
struct snmp_system {
char sys_descr[256];
struct ber_oid sys_oid;
char sys_contact[256];
char sys_name[256];
char sys_location[256];
int8_t sys_services;
};
struct snmpd {
u_int8_t sc_flags;
#define SNMPD_F_VERBOSE 0x01
#define SNMPD_F_DEBUG 0x02
#define SNMPD_F_NONAMES 0x04
enum mib_oidfmt sc_oidfmt;
const char *sc_confpath;
struct addresslist sc_addresses;
struct axmasterlist sc_agentx_masters;
struct timeval sc_starttime;
u_int32_t sc_engine_boots;
char sc_rdcommunity[SNMPD_MAXCOMMUNITYLEN];
char sc_rwcommunity[SNMPD_MAXCOMMUNITYLEN];
char sc_trcommunity[SNMPD_MAXCOMMUNITYLEN];
uint8_t sc_engineid[SNMPD_MAXENGINEIDLEN];
size_t sc_engineid_len;
struct snmp_stats sc_stats;
struct snmp_system sc_system;
struct trap_addresslist sc_trapreceivers;
struct ber_oid *sc_blocklist;
size_t sc_nblocklist;
int sc_rtfilter;
int sc_min_seclevel;
int sc_traphandler;
struct privsep sc_ps;
};
struct trapcmd {
struct ber_oid cmd_oid;
/* sideways return for intermediate lookups */
struct trapcmd *cmd_maybe;
int cmd_argc;
char **cmd_argv;
RB_ENTRY(trapcmd) cmd_entry;
};
RB_HEAD(trapcmd_tree, trapcmd);
extern struct trapcmd_tree trapcmd_tree;
extern struct snmpd *snmpd_env;
/* parse.y */
struct snmpd *parse_config(const char *, u_int);
int cmdline_symset(char *);
/* snmpe.c */
void snmpe(struct privsep *, struct privsep_proc *);
void snmpe_shutdown(void);
void snmpe_dispatchmsg(struct snmp_message *);
void snmpe_response(struct snmp_message *);
int snmp_messagecmp(struct snmp_message *, struct snmp_message *);
RB_PROTOTYPE(snmp_messages, snmp_message, sm_entry, snmp_messagecmp)
/* trap.c */
void trap_init(void);
int trap_imsg(struct imsgev *, pid_t);
int trap_send(struct ber_oid *, struct ber_element *);
/* smi.c */
int smi_init(void);
int smi_string2oid(const char *, struct ber_oid *);
const char *smi_insert(struct ber_oid *, const char *);
unsigned int smi_application(struct ber_element *);
void smi_debug_elements(struct ber_element *);
/* snmpd.c */
int snmpd_socket_af(struct sockaddr_storage *, int);
u_long snmpd_engine_time(void);
/* usm.c */
void usm_generate_keys(void);
struct usmuser *usm_newuser(char *name, const char **);
struct usmuser *usm_finduser(char *name);
int usm_checkuser(struct usmuser *, const char **);
struct ber_element *usm_decode(struct snmp_message *, struct ber_element *,
const char **);
struct ber_element *usm_encode(struct snmp_message *, struct ber_element *);
struct ber_element *usm_encrypt(struct snmp_message *, struct ber_element *);
void usm_finalize_digest(struct snmp_message *, char *, ssize_t);
void usm_make_report(struct snmp_message *);
const struct usmuser *usm_check_mincred(int, const char **);
/* proc.c */
enum privsep_procid
proc_getid(struct privsep_proc *, unsigned int, const char *);
void proc_init(struct privsep *, struct privsep_proc *, unsigned int, int,
int, char **, enum privsep_procid);
void proc_kill(struct privsep *);
void proc_connect(struct privsep *);
void proc_dispatch(int, short event, void *);
void proc_run(struct privsep *, struct privsep_proc *,
struct privsep_proc *, u_int,
void (*)(struct privsep *, struct privsep_proc *, void *), void *);
void imsg_event_add(struct imsgev *);
int imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t,
pid_t, int, void *, u_int16_t);
int imsg_composev_event(struct imsgev *, u_int16_t, u_int32_t,
pid_t, int, const struct iovec *, int);
void proc_range(struct privsep *, enum privsep_procid, int *, int *);
int proc_compose_imsg(struct privsep *, enum privsep_procid, int,
u_int16_t, u_int32_t, int, void *, u_int16_t);
int proc_compose(struct privsep *, enum privsep_procid,
uint16_t, void *, uint16_t);
int proc_composev_imsg(struct privsep *, enum privsep_procid, int,
u_int16_t, u_int32_t, int, const struct iovec *, int);
int proc_composev(struct privsep *, enum privsep_procid,
uint16_t, const struct iovec *, int);
struct imsgbuf *
proc_ibuf(struct privsep *, enum privsep_procid, int);
struct imsgev *
proc_iev(struct privsep *, enum privsep_procid, int);
int proc_flush_imsg(struct privsep *, enum privsep_procid, int);
/* traphandler.c */
int traphandler_parse(struct snmp_message *);
int traphandler_priv_recvmsg(struct privsep_proc *, struct imsg *);
void trapcmd_free(struct trapcmd *);
int trapcmd_add(struct trapcmd *);
struct trapcmd *
trapcmd_lookup(struct ber_oid *);
/* util.c */
ssize_t sendtofrom(int, void *, size_t, int, struct sockaddr *,
socklen_t, struct sockaddr *, socklen_t);
ssize_t recvfromto(int, void *, size_t, int, struct sockaddr *,
socklen_t *, struct sockaddr *, socklen_t *);
const char *print_host(struct sockaddr_storage *, char *, size_t);
char *tohexstr(u_int8_t *, int);
uint8_t *fromhexstr(uint8_t *, const char *, size_t);
#endif /* SNMPD_H */