xref: /openbsd/usr.sbin/snmpd/snmpd.h (revision 3c554fea)
1 /*	$OpenBSD: snmpd.h,v 1.109 2023/11/12 16:07:34 martijn Exp $	*/
2 
3 /*
4  * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
5  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #ifndef SNMPD_H
21 #define SNMPD_H
22 
23 #include <sys/tree.h>
24 #include <sys/un.h>
25 
26 #include <net/if.h>
27 #include <net/if_dl.h>
28 #include <netinet/in.h>
29 #include <netinet/if_ether.h>
30 #include <netinet/ip.h>
31 #include <arpa/inet.h>
32 #include <net/pfvar.h>
33 #include <net/route.h>
34 
35 #include <ber.h>
36 #include <stdio.h>
37 #include <imsg.h>
38 
39 #include "log.h"
40 #include "smi.h"
41 #include "snmp.h"
42 
43 #ifndef nitems
44 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
45 #endif
46 
47 /*
48  * common definitions for snmpd
49  */
50 
51 #define CONF_FILE		"/etc/snmpd.conf"
52 #define SNMPD_BACKEND		"/usr/libexec/snmpd"
53 #define SNMPD_USER		"_snmpd"
54 #define SNMP_PORT		"161"
55 #define SNMPTRAP_PORT		"162"
56 
57 #define AGENTX_MASTER_PATH	"/var/agentx/master"
58 #define AGENTX_GROUP		"_agentx"
59 
60 #define SNMPD_MAXSTRLEN		484
61 #define SNMPD_MAXCOMMUNITYLEN	SNMPD_MAXSTRLEN
62 #define SNMPD_MAXVARBIND	0x7fffffff
63 #define SNMPD_MAXVARBINDLEN	1210
64 #define SNMPD_MAXENGINEIDLEN	32
65 #define SNMPD_MAXUSERNAMELEN	32
66 #define SNMPD_MAXCONTEXNAMELEN	32
67 
68 #define SNMP_USM_MAXDIGESTLEN	48
69 #define SNMP_USM_SALTLEN	8
70 #define SNMP_USM_KEYLEN		64
71 #define SNMP_CIPHER_KEYLEN	16
72 
73 #define SMALL_READ_BUF_SIZE	1024
74 #define READ_BUF_SIZE		65535
75 #define	RT_BUF_SIZE		16384
76 #define	MAX_RTSOCK_BUF		(2 * 1024 * 1024)
77 
78 #define SNMP_ENGINEID_OLD	0x00
79 #define SNMP_ENGINEID_NEW	0x80	/* RFC3411 */
80 
81 #define SNMP_ENGINEID_FMT_IPv4	1
82 #define SNMP_ENGINEID_FMT_IPv6	2
83 #define SNMP_ENGINEID_FMT_MAC	3
84 #define SNMP_ENGINEID_FMT_TEXT	4
85 #define SNMP_ENGINEID_FMT_OCT	5
86 #define SNMP_ENGINEID_FMT_HH	129
87 
88 #define PEN_OPENBSD		30155
89 
90 enum imsg_type {
91 	IMSG_NONE,
92 	IMSG_CTL_VERBOSE,
93 	IMSG_CTL_PROCFD,
94 	IMSG_TRAP_EXEC,
95 	IMSG_AX_FD
96 };
97 
98 struct imsgev {
99 	struct imsgbuf		 ibuf;
100 	void			(*handler)(int, short, void *);
101 	struct event		 ev;
102 	struct privsep_proc	*proc;
103 	void			*data;
104 	short			 events;
105 	const char		*name;
106 };
107 
108 #define IMSG_SIZE_CHECK(imsg, p) do {				\
109 	if (IMSG_DATA_SIZE(imsg) < sizeof(*p))			\
110 		fatalx("bad length imsg received");		\
111 } while (0)
112 #define IMSG_DATA_SIZE(imsg)	((imsg)->hdr.len - IMSG_HEADER_SIZE)
113 
114 enum privsep_procid {
115 	PROC_PARENT,	/* Parent process and application interface */
116 	PROC_SNMPE,	/* SNMP engine */
117 	PROC_MAX
118 };
119 
120 extern enum privsep_procid privsep_process;
121 
122 struct privsep_pipes {
123 	int			*pp_pipes[PROC_MAX];
124 };
125 
126 struct privsep {
127 	struct privsep_pipes	*ps_pipes[PROC_MAX];
128 	struct privsep_pipes	*ps_pp;
129 
130 	struct imsgev		*ps_ievs[PROC_MAX];
131 	const char		*ps_title[PROC_MAX];
132 	pid_t			 ps_pid[PROC_MAX];
133 	struct passwd		*ps_pw;
134 
135 	u_int			 ps_instances[PROC_MAX];
136 	u_int			 ps_instance;
137 	int			 ps_noaction;
138 
139 	/* Event and signal handlers */
140 	struct event		 ps_evsigint;
141 	struct event		 ps_evsigterm;
142 	struct event		 ps_evsigchld;
143 	struct event		 ps_evsighup;
144 	struct event		 ps_evsigpipe;
145 	struct event		 ps_evsigusr1;
146 
147 	void			*ps_env;
148 };
149 
150 struct privsep_proc {
151 	const char		*p_title;
152 	enum privsep_procid	 p_id;
153 	int			(*p_cb)(int, struct privsep_proc *,
154 				    struct imsg *);
155 	void			(*p_init)(struct privsep *,
156 				    struct privsep_proc *);
157 	void			(*p_shutdown)(void);
158 	const char		*p_chroot;
159 	struct privsep		*p_ps;
160 	struct passwd		*p_pw;
161 };
162 
163 struct privsep_fd {
164 	enum privsep_procid		 pf_procid;
165 	unsigned int			 pf_instance;
166 };
167 
168 #define PROC_PARENT_SOCK_FILENO	3
169 #define PROC_MAX_INSTANCES	32
170 
171 #if DEBUG
172 #define DPRINTF		log_debug
173 #else
174 #define DPRINTF(x...)	do {} while(0)
175 #endif
176 
177 /*
178  * Message Processing Subsystem (mps)
179  */
180 
181 struct oid {
182 	struct ber_oid		 o_id;
183 #define o_oid			 o_id.bo_id
184 #define o_oidlen		 o_id.bo_n
185 
186 	char			*o_name;
187 
188 	u_int			 o_flags;
189 
190 	int			 (*o_get)(struct oid *, struct ber_oid *,
191 				    struct ber_element **);
192 	struct ber_oid		*(*o_table)(struct oid *, struct ber_oid *,
193 				    struct ber_oid *);
194 
195 	long long		 o_val;
196 	void			*o_data;
197 
198 	RB_ENTRY(oid)		 o_element;
199 	RB_ENTRY(oid)		 o_keyword;
200 };
201 
202 #define OID_RD			0x01
203 #define OID_WR			0x02
204 #define OID_IFSET		0x04	/* only if user-specified value */
205 #define OID_DYNAMIC		0x08	/* free allocated data */
206 #define OID_TABLE		0x10	/* dynamic sub-elements */
207 #define OID_MIB			0x20	/* root-OID of a supported MIB */
208 #define OID_KEY			0x40	/* lookup tables */
209 
210 #define OID_RS			(OID_RD|OID_IFSET)
211 
212 #define OID_TRD			(OID_RD|OID_TABLE)
213 
214 #define OID_NOTSET(_oid)						\
215 	(((_oid)->o_flags & OID_IFSET) &&				\
216 	((_oid)->o_data == NULL) && ((_oid)->o_val == 0))
217 
218 #define OID(...)		(struct ber_oid){ { __VA_ARGS__ },	\
219     (sizeof((uint32_t []) { __VA_ARGS__ }) / sizeof(uint32_t)) }
220 #define MIBDECL(...)		{ { MIB_##__VA_ARGS__ } }, #__VA_ARGS__
221 #define MIB(...)		{ { MIB_##__VA_ARGS__ } }, NULL
222 #define MIBEND			{ { 0 } }, NULL
223 
224 /*
225  * daemon structures
226  */
227 
228 #define MSG_HAS_AUTH(m)		(((m)->sm_flags & SNMP_MSGFLAG_AUTH) != 0)
229 #define MSG_HAS_PRIV(m)		(((m)->sm_flags & SNMP_MSGFLAG_PRIV) != 0)
230 #define MSG_SECLEVEL(m)		((m)->sm_flags & SNMP_MSGFLAG_SECMASK)
231 #define MSG_REPORT(m)		(((m)->sm_flags & SNMP_MSGFLAG_REPORT) != 0)
232 
233 struct snmp_message {
234 	int			 sm_sock;
235 	struct sockaddr_storage	 sm_ss;
236 	socklen_t		 sm_slen;
237 	int			 sm_sock_tcp;
238 	int			 sm_aflags;
239 	enum snmp_pdutype	 sm_pdutype;
240 	struct event		 sm_sockev;
241 	char			 sm_host[HOST_NAME_MAX+1];
242 	in_port_t		 sm_port;
243 
244 	struct sockaddr_storage	 sm_local_ss;
245 	socklen_t		 sm_local_slen;
246 
247 	struct ber		 sm_ber;
248 	struct ber_element	*sm_req;
249 	struct ber_element	*sm_resp;
250 
251 	u_int8_t		 sm_data[READ_BUF_SIZE];
252 	size_t			 sm_datalen;
253 
254 	uint32_t		 sm_transactionid;
255 
256 	u_int			 sm_version;
257 
258 	/* V1, V2c */
259 	char			 sm_community[SNMPD_MAXCOMMUNITYLEN];
260 
261 	/* V3 */
262 	long long		 sm_msgid;
263 	long long		 sm_max_msg_size;
264 	u_int8_t		 sm_flags;
265 	long long		 sm_secmodel;
266 	u_int32_t		 sm_engine_boots;
267 	u_int32_t		 sm_engine_time;
268 	uint8_t			 sm_ctxengineid[SNMPD_MAXENGINEIDLEN];
269 	size_t			 sm_ctxengineid_len;
270 	char			 sm_ctxname[SNMPD_MAXCONTEXNAMELEN+1];
271 
272 	/* USM */
273 	char			 sm_username[SNMPD_MAXUSERNAMELEN+1];
274 	struct usmuser		*sm_user;
275 	size_t			 sm_digest_offs;
276 	char			 sm_salt[SNMP_USM_SALTLEN];
277 	int			 sm_usmerr;
278 
279 	long long		 sm_request;
280 
281 	const char		*sm_errstr;
282 	long long		 sm_error;
283 #define sm_nonrepeaters		 sm_error
284 	long long		 sm_errorindex;
285 #define sm_maxrepetitions	 sm_errorindex
286 
287 	struct ber_element	*sm_pdu;
288 	struct ber_element	*sm_pduend;
289 
290 	struct ber_element	*sm_varbind;
291 	struct ber_element	*sm_varbindresp;
292 
293 	RB_ENTRY(snmp_message)	 sm_entry;
294 };
295 RB_HEAD(snmp_messages, snmp_message);
296 extern struct snmp_messages snmp_messages;
297 
298 /* Defined in SNMPv2-MIB.txt (RFC 3418) */
299 struct snmp_stats {
300 	u_int32_t		snmp_inpkts;
301 	u_int32_t		snmp_outpkts;
302 	u_int32_t		snmp_inbadversions;
303 	u_int32_t		snmp_inbadcommunitynames;
304 	u_int32_t		snmp_inbadcommunityuses;
305 	u_int32_t		snmp_inasnparseerrs;
306 	u_int32_t		snmp_intoobigs;
307 	u_int32_t		snmp_innosuchnames;
308 	u_int32_t		snmp_inbadvalues;
309 	u_int32_t		snmp_inreadonlys;
310 	u_int32_t		snmp_ingenerrs;
311 	u_int32_t		snmp_intotalreqvars;
312 	u_int32_t		snmp_intotalsetvars;
313 	u_int32_t		snmp_ingetrequests;
314 	u_int32_t		snmp_ingetnexts;
315 	u_int32_t		snmp_insetrequests;
316 	u_int32_t		snmp_ingetresponses;
317 	u_int32_t		snmp_intraps;
318 	u_int32_t		snmp_outtoobigs;
319 	u_int32_t		snmp_outnosuchnames;
320 	u_int32_t		snmp_outbadvalues;
321 	u_int32_t		snmp_outgenerrs;
322 	u_int32_t		snmp_outgetrequests;
323 	u_int32_t		snmp_outgetnexts;
324 	u_int32_t		snmp_outsetrequests;
325 	u_int32_t		snmp_outgetresponses;
326 	u_int32_t		snmp_outtraps;
327 	int			snmp_enableauthentraps;
328 	u_int32_t		snmp_silentdrops;
329 	u_int32_t		snmp_proxydrops;
330 
331 	/* USM stats (RFC 3414) */
332 	u_int32_t		snmp_usmbadseclevel;
333 	u_int32_t		snmp_usmtimewindow;
334 	u_int32_t		snmp_usmnosuchuser;
335 	u_int32_t		snmp_usmnosuchengine;
336 	u_int32_t		snmp_usmwrongdigest;
337 	u_int32_t		snmp_usmdecrypterr;
338 };
339 
340 struct address {
341 	struct sockaddr_storage	 ss;
342 	in_port_t		 port;
343 	int			 type;
344 	int			 flags;
345 	int			 fd;
346 	struct event		 ev;
347 	struct event		 evt;
348 
349 	TAILQ_ENTRY(address)	 entry;
350 };
351 TAILQ_HEAD(addresslist, address);
352 
353 struct agentx_master {
354 	int			axm_fd;
355 	struct sockaddr_un	axm_sun;
356 	uid_t			axm_owner;
357 	gid_t			axm_group;
358 	mode_t			axm_mode;
359 
360 	struct event		axm_ev;
361 
362 	TAILQ_ENTRY(agentx_master) axm_entry;
363 };
364 TAILQ_HEAD(axmasterlist, agentx_master);
365 
366 #define ADDRESS_FLAG_READ	0x01
367 #define ADDRESS_FLAG_WRITE	0x02
368 #define ADDRESS_FLAG_NOTIFY	0x04
369 #define ADDRESS_FLAG_PERM	\
370     (ADDRESS_FLAG_READ | ADDRESS_FLAG_WRITE | ADDRESS_FLAG_NOTIFY)
371 #define ADDRESS_FLAG_SNMPV1	0x10
372 #define ADDRESS_FLAG_SNMPV2	0x20
373 #define ADDRESS_FLAG_SNMPV3	0x40
374 #define ADDRESS_FLAG_MPS	\
375     (ADDRESS_FLAG_SNMPV1 | ADDRESS_FLAG_SNMPV2 | ADDRESS_FLAG_SNMPV3)
376 
377 struct trap_address {
378 	struct sockaddr_storage	 ta_ss;
379 	struct sockaddr_storage	 ta_sslocal;
380 	int			 ta_version;
381 	union {
382 		char		 ta_community[SNMPD_MAXCOMMUNITYLEN];
383 		struct {
384 			char		*ta_usmusername;
385 			struct usmuser	*ta_usmuser;
386 			int		 ta_seclevel;
387 		};
388 	};
389 	struct ber_oid		*ta_oid;
390 
391 	TAILQ_ENTRY(trap_address) entry;
392 };
393 TAILQ_HEAD(trap_addresslist, trap_address);
394 
395 enum usmauth {
396 	AUTH_NONE = 0,
397 	AUTH_MD5,	/* HMAC-MD5-96, RFC3414 */
398 	AUTH_SHA1,	/* HMAC-SHA-96, RFC3414 */
399 	AUTH_SHA224,	/* usmHMAC128SHA224AuthProtocol. RFC7860 */
400 	AUTH_SHA256,	/* usmHMAC192SHA256AuthProtocol. RFC7860 */
401 	AUTH_SHA384,	/* usmHMAC256SHA384AuthProtocol. RFC7860 */
402 	AUTH_SHA512	/* usmHMAC384SHA512AuthProtocol. RFC7860 */
403 };
404 
405 #define AUTH_DEFAULT	AUTH_SHA1	/* Default digest */
406 
407 enum usmpriv {
408 	PRIV_NONE = 0,
409 	PRIV_DES,	/* CBC-DES, RFC3414 */
410 	PRIV_AES	/* CFB128-AES-128, RFC3826 */
411 };
412 
413 #define PRIV_DEFAULT	PRIV_AES	/* Default cipher */
414 
415 struct usmuser {
416 	char			*uu_name;
417 	int			 uu_seclevel;
418 
419 	enum usmauth		 uu_auth;
420 	char			*uu_authkey;
421 	unsigned		 uu_authkeylen;
422 
423 
424 	enum usmpriv		 uu_priv;
425 	char			*uu_privkey;
426 	unsigned long long	 uu_salt;
427 
428 	SLIST_ENTRY(usmuser)	 uu_next;
429 };
430 
431 struct snmp_system {
432 	char			 sys_descr[256];
433 	struct ber_oid		 sys_oid;
434 	char			 sys_contact[256];
435 	char			 sys_name[256];
436 	char			 sys_location[256];
437 	int8_t			 sys_services;
438 };
439 
440 struct snmpd {
441 	u_int8_t		 sc_flags;
442 #define SNMPD_F_VERBOSE		 0x01
443 #define SNMPD_F_DEBUG		 0x02
444 #define SNMPD_F_NONAMES		 0x04
445 
446 	const char		*sc_confpath;
447 	struct addresslist	 sc_addresses;
448 	struct axmasterlist	 sc_agentx_masters;
449 	struct timeval		 sc_starttime;
450 	u_int32_t		 sc_engine_boots;
451 
452 	char			 sc_rdcommunity[SNMPD_MAXCOMMUNITYLEN];
453 	char			 sc_rwcommunity[SNMPD_MAXCOMMUNITYLEN];
454 	char			 sc_trcommunity[SNMPD_MAXCOMMUNITYLEN];
455 
456 	uint8_t			 sc_engineid[SNMPD_MAXENGINEIDLEN];
457 	size_t			 sc_engineid_len;
458 
459 	struct snmp_stats	 sc_stats;
460 	struct snmp_system	 sc_system;
461 
462 	struct trap_addresslist	 sc_trapreceivers;
463 
464 	struct ber_oid		*sc_blocklist;
465 	size_t			 sc_nblocklist;
466 	int			 sc_rtfilter;
467 
468 	int			 sc_min_seclevel;
469 	int			 sc_traphandler;
470 
471 	struct privsep		 sc_ps;
472 };
473 
474 struct trapcmd {
475 	struct ber_oid		*cmd_oid;
476 		/* sideways return for intermediate lookups */
477 	struct trapcmd		*cmd_maybe;
478 
479 	int			 cmd_argc;
480 	char			**cmd_argv;
481 
482 	RB_ENTRY(trapcmd)	 cmd_entry;
483 };
484 RB_HEAD(trapcmd_tree, trapcmd);
485 extern	struct trapcmd_tree trapcmd_tree;
486 
487 extern struct snmpd *snmpd_env;
488 
489 /* parse.y */
490 struct snmpd	*parse_config(const char *, u_int);
491 int		 cmdline_symset(char *);
492 
493 /* snmpe.c */
494 void		 snmpe(struct privsep *, struct privsep_proc *);
495 void		 snmpe_shutdown(void);
496 void		 snmpe_dispatchmsg(struct snmp_message *);
497 void		 snmpe_response(struct snmp_message *);
498 int		 snmp_messagecmp(struct snmp_message *, struct snmp_message *);
499 RB_PROTOTYPE(snmp_messages, snmp_message, sm_entry, snmp_messagecmp)
500 
501 /* trap.c */
502 void		 trap_init(void);
503 int		 trap_imsg(struct imsgev *, pid_t);
504 int		 trap_send(struct ber_oid *, struct ber_element *);
505 
506 /* smi.c */
507 int		 smi_init(void);
508 void		 smi_mibtree(struct oid *);
509 struct oid	*smi_find(struct oid *);
510 struct oid	*smi_nfind(struct oid *);
511 struct oid	*smi_findkey(char *);
512 struct oid	*smi_next(struct oid *);
513 struct oid	*smi_foreach(struct oid *, u_int);
514 void		 smi_oidlen(struct ber_oid *);
515 void		 smi_scalar_oidlen(struct ber_oid *);
516 int		 smi_string2oid(const char *, struct ber_oid *);
517 void		 smi_delete(struct oid *);
518 int		 smi_insert(struct oid *);
519 int		 smi_oid_cmp(struct oid *, struct oid *);
520 int		 smi_key_cmp(struct oid *, struct oid *);
521 unsigned int	 smi_application(struct ber_element *);
522 void		 smi_debug_elements(struct ber_element *);
523 
524 /* snmpd.c */
525 int		 snmpd_socket_af(struct sockaddr_storage *, int);
526 u_long		 snmpd_engine_time(void);
527 
528 /* usm.c */
529 void		 usm_generate_keys(void);
530 struct usmuser	*usm_newuser(char *name, const char **);
531 struct usmuser	*usm_finduser(char *name);
532 int		 usm_checkuser(struct usmuser *, const char **);
533 struct ber_element *usm_decode(struct snmp_message *, struct ber_element *,
534 		    const char **);
535 struct ber_element *usm_encode(struct snmp_message *, struct ber_element *);
536 struct ber_element *usm_encrypt(struct snmp_message *, struct ber_element *);
537 void		 usm_finalize_digest(struct snmp_message *, char *, ssize_t);
538 void		 usm_make_report(struct snmp_message *);
539 const struct usmuser *usm_check_mincred(int, const char **);
540 
541 /* proc.c */
542 enum privsep_procid
543 	    proc_getid(struct privsep_proc *, unsigned int, const char *);
544 void	 proc_init(struct privsep *, struct privsep_proc *, unsigned int, int,
545 	    int, char **, enum privsep_procid);
546 void	 proc_kill(struct privsep *);
547 void	 proc_connect(struct privsep *);
548 void	 proc_dispatch(int, short event, void *);
549 void	 proc_run(struct privsep *, struct privsep_proc *,
550 	    struct privsep_proc *, u_int,
551 	    void (*)(struct privsep *, struct privsep_proc *, void *), void *);
552 void	 imsg_event_add(struct imsgev *);
553 int	 imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t,
554 	    pid_t, int, void *, u_int16_t);
555 int	 imsg_composev_event(struct imsgev *, u_int16_t, u_int32_t,
556 	    pid_t, int, const struct iovec *, int);
557 void	 proc_range(struct privsep *, enum privsep_procid, int *, int *);
558 int	 proc_compose_imsg(struct privsep *, enum privsep_procid, int,
559 	    u_int16_t, u_int32_t, int, void *, u_int16_t);
560 int	 proc_compose(struct privsep *, enum privsep_procid,
561 	    uint16_t, void *, uint16_t);
562 int	 proc_composev_imsg(struct privsep *, enum privsep_procid, int,
563 	    u_int16_t, u_int32_t, int, const struct iovec *, int);
564 int	 proc_composev(struct privsep *, enum privsep_procid,
565 	    uint16_t, const struct iovec *, int);
566 int	 proc_forward_imsg(struct privsep *, struct imsg *,
567 	    enum privsep_procid, int);
568 struct imsgbuf *
569 	 proc_ibuf(struct privsep *, enum privsep_procid, int);
570 struct imsgev *
571 	 proc_iev(struct privsep *, enum privsep_procid, int);
572 int	 proc_flush_imsg(struct privsep *, enum privsep_procid, int);
573 
574 /* traphandler.c */
575 int	 traphandler_parse(struct snmp_message *);
576 int	 traphandler_priv_recvmsg(struct privsep_proc *, struct imsg *);
577 void	 trapcmd_free(struct trapcmd *);
578 int	 trapcmd_add(struct trapcmd *);
579 struct trapcmd *
580 	 trapcmd_lookup(struct ber_oid *);
581 
582 /* util.c */
583 ssize_t	 sendtofrom(int, void *, size_t, int, struct sockaddr *,
584 	    socklen_t, struct sockaddr *, socklen_t);
585 ssize_t	 recvfromto(int, void *, size_t, int, struct sockaddr *,
586 	    socklen_t *, struct sockaddr *, socklen_t *);
587 const char *print_host(struct sockaddr_storage *, char *, size_t);
588 char	*tohexstr(u_int8_t *, int);
589 uint8_t *fromhexstr(uint8_t *, const char *, size_t);
590 
591 #endif /* SNMPD_H */
592