xref: /openbsd-src/usr.sbin/snmpd/application_blocklist.c (revision 25c4e8bd056e974b28f4a0ffd39d76c190a56013)
1 /*	$OpenBSD: application_blocklist.c,v 1.1 2022/06/30 11:28:36 martijn Exp $	*/
2 
3 /*
4  * Copyright (c) 2022 Martijn van Duren <martijn@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <event.h>
20 #include <stdlib.h>
21 
22 #include "application.h"
23 #include "snmpd.h"
24 
25 struct appl_varbind *appl_blocklist_response(size_t);
26 void appl_blocklist_get(struct appl_backend *, int32_t, int32_t, const char *,
27     struct appl_varbind *);
28 void appl_blocklist_getnext(struct appl_backend *, int32_t, int32_t,
29     const char *, struct appl_varbind *);
30 
31 struct appl_backend_functions appl_blocklist_functions = {
32 	.ab_get = appl_blocklist_get,
33 	.ab_getnext = appl_blocklist_getnext,
34 	.ab_getbulk = NULL,
35 };
36 
37 struct appl_backend appl_blocklist = {
38 	.ab_name = "blocklist",
39 	.ab_cookie = NULL,
40 	.ab_retries = 0,
41 	.ab_fn = &appl_blocklist_functions
42 };
43 
44 static struct appl_varbind *response = NULL;
45 static size_t responsesz = 0;
46 
47 struct appl_varbind *
48 appl_blocklist_response(size_t nvarbind)
49 {
50 	struct appl_varbind *tmp;
51 	size_t i;
52 
53 	if (responsesz < nvarbind) {
54 		if ((tmp = recallocarray(response, responsesz, nvarbind,
55 		    sizeof(*response))) == NULL) {
56 			log_warn(NULL);
57 			return NULL;
58 		}
59 		responsesz = nvarbind;
60 		response = tmp;
61 	}
62 	for (i = 0; i < nvarbind; i++)
63 		response[i].av_next = i + 1 == nvarbind ?
64 		    NULL : &(response[i + 1]);
65 	return response;
66 }
67 
68 void
69 appl_blocklist_init(void)
70 {
71 	extern struct snmpd *snmpd_env;
72 	size_t i;
73 
74 	for (i = 0; i < snmpd_env->sc_nblocklist; i++)
75 		appl_register(NULL, 150, 1, &(snmpd_env->sc_blocklist[i]),
76 		    0, 1, 0, 0, &appl_blocklist);
77 }
78 
79 void
80 appl_blocklist_shutdown(void)
81 {
82 	appl_close(&appl_blocklist);
83 	free(response);
84 }
85 
86 void
87 appl_blocklist_get(struct appl_backend *backend, __unused int32_t transactionid,
88     int32_t requestid, __unused const char *ctx, struct appl_varbind *vblist)
89 {
90 	struct appl_varbind *vb, *rvb, *rvblist;
91 	size_t i;
92 
93 	for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next)
94 		i++;
95 	if ((rvblist = appl_blocklist_response(i)) == NULL)
96 		goto fail;
97 	rvb = rvblist;
98 	for (vb = vblist; vb != NULL; vb = vb->av_next, rvb = rvb->av_next) {
99 		rvb->av_oid = vb->av_oid;
100 		rvb->av_value = appl_exception(APPL_EXC_NOSUCHOBJECT);
101 		if (rvb->av_value == NULL)
102 			goto fail;
103 	}
104 
105 	appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, rvblist);
106 	return;
107  fail:
108 	for (rvb = rvblist; rvb != NULL && rvb->av_value != NULL;
109 	    rvb = rvb->av_next)
110 		ober_free_elements(rvb->av_value);
111 	appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vb);
112 }
113 
114 void
115 appl_blocklist_getnext(struct appl_backend *backend,
116     __unused int32_t transactionid, int32_t requestid, __unused const char *ctx,
117     struct appl_varbind *vblist)
118 {
119 	struct appl_varbind *vb, *rvb, *rvblist;
120 	size_t i;
121 
122 	for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next)
123 		i++;
124 	if ((rvblist = appl_blocklist_response(i)) == NULL)
125 		goto fail;
126 	rvb = rvblist;
127 	for (vb = vblist; vb != NULL; vb = vb->av_next, rvb = rvb->av_next) {
128 		rvb->av_oid = vb->av_oid;
129 		rvb->av_value = appl_exception(APPL_EXC_ENDOFMIBVIEW);
130 		if (rvb->av_value == NULL)
131 			goto fail;
132 	}
133 
134 	appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, rvblist);
135 	return;
136  fail:
137 	for (rvb = rvblist; rvb != NULL && rvb->av_value != NULL;
138 	    rvb = rvb->av_next)
139 		ober_free_elements(rvb->av_value);
140 	appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vb);
141 }
142